Subversion Repositories SvarDOS

Rev

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

Rev 1043 Rev 1101
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
  /* compute the filename of the link file */
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
  /* prep DOSDIR\LINKS\pattern */
162
  /* prep DOSDIR\LINKS\pattern */
163
  if (link_computefname(buff, linkname, env_seg) != 0) return(CMD_FAIL);
163
  if (link_computefname(buff, linkname, env_seg) != 0) return(CMD_FAIL);
164
 
164
 
165
  /* set pathlen to end of path (char after last backslash) */
165
  /* set pathlen to end of path (char after last backslash) */
166
  pathlen = 0;
166
  pathlen = 0;
167
  for (i = 0; buff[i] != 0; i++) if (buff[i] == '\\') pathlen = i + 1;
167
  for (i = 0; buff[i] != 0; i++) if (buff[i] == '\\') pathlen = i + 1;
168
 
168
 
169
  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);
170
 
170
 
171
  do {
171
  do {
172
    /* print link file name (but trim ".lnk") */
172
    /* print link file name (but trim ".lnk") */
173
    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];
174
    if (i < 8) buff16[i++] = '\t';
174
    if (i < 8) buff16[i++] = '\t';
175
    buff16[i] = 0;
175
    buff16[i] = 0;
176
    output(buff16);
176
    output(buff16);
177
    output(" @ ");
177
    output(" @ ");
178
    /* prep full link filename */
178
    /* prep full link filename */
179
    strcpy(buff + pathlen, dta->fname);
179
    strcpy(buff + pathlen, dta->fname);
180
    /* 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 */
181
    i = 0;
181
    i = 0;
182
    _asm {
182
    _asm {
183
      push ax
183
      push ax
184
      push bx
184
      push bx
185
      push cx
185
      push cx
186
      push dx
186
      push dx
187
 
187
 
188
      /* open file */
188
      /* open file */
189
      mov ax, 0x3d00
189
      mov ax, 0x3d00
190
      mov dx, buff   /* filename */
190
      mov dx, buff   /* filename */
191
      int 0x21
191
      int 0x21
192
      jc FAIL_FOPEN
192
      jc FAIL_FOPEN
193
      /* read from file */
193
      /* read from file */
194
      mov bx, ax
194
      mov bx, ax
195
      mov ah, 0x3f
195
      mov ah, 0x3f
196
      mov cx, 128
196
      mov cx, 128
197
      mov dx, buff128
197
      mov dx, buff128
198
      int 0x21
198
      int 0x21
199
      jc FAIL_FREAD
199
      jc FAIL_FREAD
200
      mov i, ax
200
      mov i, ax
201
      /* close file */
201
      /* close file */
202
      FAIL_FREAD:
202
      FAIL_FREAD:
203
      mov ah, 0x3e
203
      mov ah, 0x3e
204
      int 0x21
204
      int 0x21
205
      FAIL_FOPEN:
205
      FAIL_FOPEN:
206
 
206
 
207
      pop dx
207
      pop dx
208
      pop cx
208
      pop cx
209
      pop bx
209
      pop bx
210
      pop ax
210
      pop ax
211
    }
211
    }
212
    buff128[i] = 0;
212
    buff128[i] = 0;
213
    /* make sure no cr or lf is present */
213
    /* make sure no cr or lf is present */
214
    for (i = 0; buff128[i] != 0; i++) {
214
    for (i = 0; buff128[i] != 0; i++) {
215
      if ((buff128[i] == '\r') || (buff128[i] == '\n')) {
215
      if ((buff128[i] == '\r') || (buff128[i] == '\n')) {
216
        buff128[i] = 0;
216
        buff128[i] = 0;
217
        break;
217
        break;
218
      }
218
      }
219
    }
219
    }
220
    outputnl(buff128);
220
    outputnl(buff128);
221
  } while (findnext(dta) == 0);
221
  } while (findnext(dta) == 0);
222
 
222
 
223
  return(CMD_OK);
223
  return(CMD_OK);
224
}
224
}
225
 
225
 
226
 
226
 
227
static enum cmd_result cmd_ln(struct cmd_funcparam *p) {
227
static enum cmd_result cmd_ln(struct cmd_funcparam *p) {
228
  if (cmd_ishlp(p)) {
228
  if (cmd_ishlp(p)) {
229
    nls_outputnl(29,0); /* "Adds, deletes or displays executable links." */
229
    nls_outputnl(29,0); /* "Adds, deletes or displays executable links." */
230
    outputnl("");
230
    outputnl("");
231
    nls_outputnl(29,1); /* "LN ADD linkname targetdir" */
231
    nls_outputnl(29,1); /* "LN ADD linkname targetdir" */
232
    nls_outputnl(29,2); /* "LN DEL linkname" */
232
    nls_outputnl(29,2); /* "LN DEL linkname" */
233
    nls_outputnl(29,3); /* "LN LIST [pattern]" */
233
    nls_outputnl(29,3); /* "LN LIST [pattern]" */
234
    return(CMD_OK);
234
    return(CMD_OK);
235
  }
235
  }
236
 
236
 
237
  if (p->argc == 0) {
237
  if (p->argc == 0) {
238
    nls_outputnl(0,7); /* "Required parameter missing */
238
    nls_outputnl(0,7); /* "Required parameter missing */
239
    return(CMD_OK);
239
    return(CMD_OK);
240
  }
240
  }
241
 
241
 
242
  /* detect what subfunction the user wants */
242
  /* detect what subfunction the user wants */
243
  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));
244
  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));
245
  if (imatch(p->argv[0], "list")) {
245
  if (imatch(p->argv[0], "list")) {
246
    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));
247
    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));
248
  }
248
  }
249
 
249
 
250
  nls_outputnl(0,6); /* "Invalid parameter" */
250
  nls_outputnl(0,6); /* "Invalid parameter" */
251
  return(CMD_FAIL);
251
  return(CMD_FAIL);
252
}
252
}
253
 
253