Subversion Repositories SvarDOS

Rev

Rev 989 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 989 Rev 1043
1
/* This file is part of the SvarCOM project and is published under the terms
1
/* This file is part of the SvarCOM project and is published under the terms
2
 * of the MIT license.
2
 * of the MIT license.
3
 *
3
 *
4
 * Copyright (C) 2021-2022 Mateusz Viste
4
 * Copyright (C) 2021-2022 Mateusz Viste
5
 *
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a
6
 * Permission is hereby granted, free of charge, to any person obtaining a
7
 * copy of this software and associated documentation files (the "Software"),
7
 * copy of this software and associated documentation files (the "Software"),
8
 * to deal in the Software without restriction, including without limitation
8
 * to deal in the Software without restriction, including without limitation
9
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
 * and/or sell copies of the Software, and to permit persons to whom the
10
 * and/or sell copies of the Software, and to permit persons to whom the
11
 * Software is furnished to do so, subject to the following conditions:
11
 * Software is furnished to do so, subject to the following conditions:
12
 *
12
 *
13
 * The above copyright notice and this permission notice shall be included in
13
 * The above copyright notice and this permission notice shall be included in
14
 * all copies or substantial portions of the Software.
14
 * all copies or substantial portions of the Software.
15
 *
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22
 * DEALINGS IN THE SOFTWARE.
22
 * DEALINGS IN THE SOFTWARE.
23
 */
23
 */
24
 
24
 
25
/*
25
/*
26
 * ln add linkname linkdir
26
 * ln add linkname linkdir
27
 * ln del linkname
27
 * ln del linkname
28
 * ln list [pattern]
28
 * ln list [pattern]
29
 */
29
 */
30
 
30
 
31
static enum cmd_result cmd_lnadd(char *BUFFER, const char *linkname, const char *targetdir, unsigned short env_seg) {
31
static enum cmd_result cmd_lnadd(char *BUFFER, const char *linkname, const char *targetdir, unsigned short env_seg) {
32
  const char *ext;
32
  const char *ext;
33
  char *realdirname = BUFFER;
33
  char *realdirname = BUFFER;
34
  unsigned short realdirnamelen;
34
  unsigned short realdirnamelen;
35
  char *buff = BUFFER + 256;
35
  char *buff = BUFFER + 256;
36
  unsigned short doserr;
36
  unsigned short doserr;
37
 
37
 
38
  /* convert dirname to realpath */
38
  /* convert dirname to realpath */
39
  doserr = file_truename(targetdir, realdirname);
39
  doserr = file_truename(targetdir, realdirname);
40
  if (doserr != 0) {
40
  if (doserr != 0) {
41
    nls_outputnl_doserr(doserr);
41
    nls_outputnl_doserr(doserr);
42
    return(CMD_FAIL);
42
    return(CMD_FAIL);
43
  }
43
  }
44
 
44
 
45
  /* does EXENAME in DIRECTORY exist? */
45
  /* does EXENAME in DIRECTORY exist? */
46
  if (lookup_cmd(buff, linkname, realdirname, &ext) != 0) {
46
  if (lookup_cmd(buff, linkname, realdirname, &ext) != 0) {
47
    nls_outputnl(29,4); /* "No matching executable found in given path." */
47
    nls_outputnl(29,4); /* "No matching executable found in given path." */
48
    return(CMD_FAIL);
48
    return(CMD_FAIL);
49
  }
49
  }
50
 
50
 
51
  /* open DOSDIR\CFG\LINKS.DB and write realdirname to */
51
  /* compute the filename of the link file */
52
  if (link_computefname(buff, linkname, env_seg) != 0) return(CMD_FAIL);
52
  if (link_computefname(buff, linkname, env_seg) != 0) return(CMD_FAIL);
53
 
53
 
54
  realdirnamelen = strlen(realdirname);
54
  realdirnamelen = strlen(realdirname);
55
 
55
 
56
  /* open file *only if it does not exist yet* and write realdirname to it */
56
  /* open file *only if it does not exist yet* and write realdirname to it */
57
  _asm {
57
  _asm {
58
    push ax
58
    push ax
59
    push bx
59
    push bx
60
    push cx
60
    push cx
61
    push dx
61
    push dx
62
 
62
 
63
    mov ax, 0x6c00  /* extended OPEN */
63
    mov ax, 0x6c00  /* extended OPEN */
64
    mov bx, 1       /* open for WRITE */
64
    mov bx, 1       /* open for WRITE */
65
    xor cx, cx      /* create the file with no attributes */
65
    xor cx, cx      /* create the file with no attributes */
66
    mov dx, 0x0010  /* create file if it does not exists, otherwise fail */
66
    mov dx, 0x0010  /* create file if it does not exists, otherwise fail */
67
    mov si, buff    /* file name */
67
    mov si, buff    /* file name */
68
    int 0x21
68
    int 0x21
69
    jnc WRITE
69
    jnc WRITE
70
    mov doserr, ax
70
    mov doserr, ax
71
    jmp DONE
71
    jmp DONE
72
 
72
 
73
    WRITE:
73
    WRITE:
74
    mov bx, ax      /* file handle */
74
    mov bx, ax      /* file handle */
75
    mov ah, 0x40    /* write to file */
75
    mov ah, 0x40    /* write to file */
76
    mov cx, realdirnamelen
76
    mov cx, realdirnamelen
77
    mov dx, realdirname
77
    mov dx, realdirname
78
    int 0x21
78
    int 0x21
79
 
79
 
80
    mov ah, 0x3e    /* close file in BX */
80
    mov ah, 0x3e    /* close file in BX */
81
    int 0x21
81
    int 0x21
82
 
82
 
83
    DONE:
83
    DONE:
84
 
84
 
85
    pop dx
85
    pop dx
86
    pop cx
86
    pop cx
87
    pop bx
87
    pop bx
88
    pop ax
88
    pop ax
89
  }
89
  }
90
 
90
 
91
  if (doserr != 0) {
91
  if (doserr != 0) {
92
    nls_outputnl_doserr(doserr);
92
    nls_outputnl_doserr(doserr);
93
    return(CMD_FAIL);
93
    return(CMD_FAIL);
94
  }
94
  }
95
 
95
 
96
  return(CMD_OK);
96
  return(CMD_OK);
97
}
97
}
98
 
98
 
99
 
99
 
100
static enum cmd_result cmd_lndel(char *buff, const char *linkname, unsigned short env_seg) {
100
static enum cmd_result cmd_lndel(char *buff, const char *linkname, unsigned short env_seg) {
101
  unsigned short i;
101
  unsigned short i;
102
 
102
 
103
  /* is the argument valid? (must not contain any dot nor backslash) */
103
  /* is the argument valid? (must not contain any dot nor backslash) */
104
  for (i = 0; linkname[i] != 0; i++) {
104
  for (i = 0; linkname[i] != 0; i++) {
105
    if ((linkname[i] == '.') || (linkname[i] == '/') || (linkname[i] == '\\')) {
105
    if ((linkname[i] == '.') || (linkname[i] == '/') || (linkname[i] == '\\')) {
106
      nls_outputnl(0,3); /* "Invalid parameter format" */
106
      nls_outputnl(0,3); /* "Invalid parameter format" */
107
      return(CMD_OK);
107
      return(CMD_OK);
108
    }
108
    }
109
  }
109
  }
110
 
110
 
111
  /* prep link filename to look at */
111
  /* prep link filename to look at */
112
  if (link_computefname(buff, linkname, env_seg) != 0) return(CMD_FAIL);
112
  if (link_computefname(buff, linkname, env_seg) != 0) return(CMD_FAIL);
113
 
113
 
114
  /* try removing it */
114
  /* try removing it */
115
  i = 0;
115
  i = 0;
116
  _asm {
116
  _asm {
117
    push ax
117
    push ax
118
    push bx
118
    push bx
119
    push cx
119
    push cx
120
    push dx
120
    push dx
121
 
121
 
122
    mov ah, 0x41
122
    mov ah, 0x41
123
    mov dx, buff
123
    mov dx, buff
124
    int 0x21
124
    int 0x21
125
    jnc SUCCESS
125
    jnc SUCCESS
126
    mov i, ax
126
    mov i, ax
127
    SUCCESS:
127
    SUCCESS:
128
 
128
 
129
    pop dx
129
    pop dx
130
    pop cx
130
    pop cx
131
    pop bx
131
    pop bx
132
    pop ax
132
    pop ax
133
  }
133
  }
134
 
134
 
135
  if (i != 0) nls_outputnl_doserr(i);
135
  if (i != 0) nls_outputnl_doserr(i);
136
 
136
 
137
  return(CMD_OK);
137
  return(CMD_OK);
138
}
138
}
139
 
139
 
140
 
140
 
141
static enum cmd_result cmd_lnlist(char *buff, const char *linkname, unsigned short env_seg) {
141
static enum cmd_result cmd_lnlist(char *buff, const char *linkname, unsigned short env_seg) {
142
  unsigned short i, pathlen;
142
  unsigned short i, pathlen;
143
  struct DTA *dta = (void *)0x80;
143
  struct DTA *dta = (void *)0x80;
144
  char *buff128 = buff + 256;
144
  char *buff128 = buff + 256;
145
  char *buff16 = buff128 + 128;
145
  char *buff16 = buff128 + 128;
146
 
146
 
147
  if (linkname != NULL) {
147
  if (linkname != NULL) {
148
    /* make sure link pattern is valid (must not contain '.' or '\\' or '/') */
148
    /* make sure link pattern is valid (must not contain '.' or '\\' or '/') */
149
    for (i = 0; linkname[i] != 0; i++) {
149
    for (i = 0; linkname[i] != 0; i++) {
150
      switch (linkname[i]) {
150
      switch (linkname[i]) {
151
        case '.':
151
        case '.':
152
        case '/':
152
        case '/':
153
        case '\\':
153
        case '\\':
154
          nls_outputnl(0,3); /* "Invalid parameter format" */
154
          nls_outputnl(0,3); /* "Invalid parameter format" */
155
          return(CMD_FAIL);
155
          return(CMD_FAIL);
156
      }
156
      }
157
    }
157
    }
158
  } else {
158
  } else {
159
    linkname = "*";
159
    linkname = "*";
160
  }
160
  }
161
 
161
 
162
  /* fetch %DOSDIR% */
-
 
163
  pathlen = env_lookup_valcopy(buff, 128, env_seg, "DOSDIR");
-
 
164
  if (pathlen == 0) {
-
 
165
    nls_outputnl(29,5); /* "%DOSDIR% not defined" */
-
 
166
    return(CMD_FAIL);
-
 
167
  }
-
 
168
 
-
 
169
  /* prep DOSDIR\LINKS\pattern */
162
  /* prep DOSDIR\LINKS\pattern */
170
  if (buff[pathlen - 1] == '\\') pathlen--;
163
  if (link_computefname(buff, linkname, env_seg) != 0) return(CMD_FAIL);
-
 
164
 
171
  pathlen += sprintf(buff + pathlen, "\\LINKS\\");
165
  /* set pathlen to end of path (char after last backslash) */
-
 
166
  pathlen = 0;
172
  sprintf(buff + pathlen, "%s.LNK", linkname);
167
  for (i = 0; buff[i] != 0; i++) if (buff[i] == '\\') pathlen = i + 1;
173
 
168
 
174
  if (findfirst(dta, buff, DOS_ATTR_RO | DOS_ATTR_ARC) != 0) return(CMD_OK);
169
  if (findfirst(dta, buff, DOS_ATTR_RO | DOS_ATTR_ARC) != 0) return(CMD_OK);
175
 
170
 
176
  do {
171
  do {
177
    /* print link file name (but trim ".lnk") */
172
    /* print link file name (but trim ".lnk") */
178
    for (i = 0; (dta->fname[i] != 0) && (dta->fname[i] != '.'); i++) buff16[i] = dta->fname[i];
173
    for (i = 0; (dta->fname[i] != 0) && (dta->fname[i] != '.'); i++) buff16[i] = dta->fname[i];
179
    if (i < 8) buff16[i++] = '\t';
174
    if (i < 8) buff16[i++] = '\t';
180
    buff16[i] = 0;
175
    buff16[i] = 0;
181
    output(buff16);
176
    output(buff16);
182
    output(" @ ");
177
    output(" @ ");
183
    /* prep full link filename */
178
    /* prep full link filename */
184
    strcpy(buff + pathlen, dta->fname);
179
    strcpy(buff + pathlen, dta->fname);
185
    /* read up to 128 bytes from link file to buff and display it */
180
    /* read up to 128 bytes from link file to buff and display it */
186
    i = 0;
181
    i = 0;
187
    _asm {
182
    _asm {
188
      push ax
183
      push ax
189
      push bx
184
      push bx
190
      push cx
185
      push cx
191
      push dx
186
      push dx
192
 
187
 
193
      /* open file */
188
      /* open file */
194
      mov ax, 0x3d00
189
      mov ax, 0x3d00
195
      mov dx, buff   /* filename */
190
      mov dx, buff   /* filename */
196
      int 0x21
191
      int 0x21
197
      jc FAIL_FOPEN
192
      jc FAIL_FOPEN
198
      /* read from file */
193
      /* read from file */
199
      mov bx, ax
194
      mov bx, ax
200
      mov ah, 0x3f
195
      mov ah, 0x3f
201
      mov cx, 128
196
      mov cx, 128
202
      mov dx, buff128
197
      mov dx, buff128
203
      int 0x21
198
      int 0x21
204
      jc FAIL_FREAD
199
      jc FAIL_FREAD
205
      mov i, ax
200
      mov i, ax
206
      /* close file */
201
      /* close file */
207
      FAIL_FREAD:
202
      FAIL_FREAD:
208
      mov ah, 0x3e
203
      mov ah, 0x3e
209
      int 0x21
204
      int 0x21
210
      FAIL_FOPEN:
205
      FAIL_FOPEN:
211
 
206
 
212
      pop dx
207
      pop dx
213
      pop cx
208
      pop cx
214
      pop bx
209
      pop bx
215
      pop ax
210
      pop ax
216
    }
211
    }
217
    buff128[i] = 0;
212
    buff128[i] = 0;
218
    /* make sure no cr or lf is present */
213
    /* make sure no cr or lf is present */
219
    for (i = 0; buff128[i] != 0; i++) {
214
    for (i = 0; buff128[i] != 0; i++) {
220
      if ((buff128[i] == '\r') || (buff128[i] == '\n')) {
215
      if ((buff128[i] == '\r') || (buff128[i] == '\n')) {
221
        buff128[i] = 0;
216
        buff128[i] = 0;
222
        break;
217
        break;
223
      }
218
      }
224
    }
219
    }
225
    outputnl(buff128);
220
    outputnl(buff128);
226
  } while (findnext(dta) == 0);
221
  } while (findnext(dta) == 0);
227
 
222
 
228
  return(CMD_OK);
223
  return(CMD_OK);
229
}
224
}
230
 
225
 
231
 
226
 
232
static enum cmd_result cmd_ln(struct cmd_funcparam *p) {
227
static enum cmd_result cmd_ln(struct cmd_funcparam *p) {
233
  if (cmd_ishlp(p)) {
228
  if (cmd_ishlp(p)) {
234
    nls_outputnl(29,0); /* "Adds, deletes or displays executable links." */
229
    nls_outputnl(29,0); /* "Adds, deletes or displays executable links." */
235
    outputnl("");
230
    outputnl("");
236
    nls_outputnl(29,1); /* "LN ADD linkname targetdir" */
231
    nls_outputnl(29,1); /* "LN ADD linkname targetdir" */
237
    nls_outputnl(29,2); /* "LN DEL linkname" */
232
    nls_outputnl(29,2); /* "LN DEL linkname" */
238
    nls_outputnl(29,3); /* "LN LIST [pattern]" */
233
    nls_outputnl(29,3); /* "LN LIST [pattern]" */
239
    return(CMD_OK);
234
    return(CMD_OK);
240
  }
235
  }
241
 
236
 
242
  if (p->argc == 0) {
237
  if (p->argc == 0) {
243
    nls_outputnl(0,7); /* "Required parameter missing */
238
    nls_outputnl(0,7); /* "Required parameter missing */
244
    return(CMD_OK);
239
    return(CMD_OK);
245
  }
240
  }
246
 
241
 
247
  /* detect what subfunction the user wants */
242
  /* detect what subfunction the user wants */
248
  if ((imatch(p->argv[0], "add")) && (p->argc == 3)) return(cmd_lnadd(p->BUFFER, p->argv[1], p->argv[2], p->env_seg));
243
  if ((imatch(p->argv[0], "add")) && (p->argc == 3)) return(cmd_lnadd(p->BUFFER, p->argv[1], p->argv[2], p->env_seg));
249
  if ((imatch(p->argv[0], "del")) && (p->argc == 2)) return(cmd_lndel(p->BUFFER, p->argv[1], p->env_seg));
244
  if ((imatch(p->argv[0], "del")) && (p->argc == 2)) return(cmd_lndel(p->BUFFER, p->argv[1], p->env_seg));
250
  if (imatch(p->argv[0], "list")) {
245
  if (imatch(p->argv[0], "list")) {
251
    if (p->argc == 1) return(cmd_lnlist(p->BUFFER, NULL, p->env_seg));
246
    if (p->argc == 1) return(cmd_lnlist(p->BUFFER, NULL, p->env_seg));
252
    if (p->argc == 2) return(cmd_lnlist(p->BUFFER, p->argv[1], p->env_seg));
247
    if (p->argc == 2) return(cmd_lnlist(p->BUFFER, p->argv[1], p->env_seg));
253
  }
248
  }
254
 
249
 
255
  nls_outputnl(0,6); /* "Invalid parameter" */
250
  nls_outputnl(0,6); /* "Invalid parameter" */
256
  return(CMD_FAIL);
251
  return(CMD_FAIL);
257
}
252
}
258
 
253