Subversion Repositories SvarDOS

Rev

Rev 1043 | Details | Compare with Previous | Last modification | View Log | RSS feed

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