Subversion Repositories SvarDOS

Rev

Rev 571 | Go to most recent revision | 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
 
51
  /* open DOSDIR\CFG\LINKS.DB and write realdirname to */
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
  /* fetch %DOSDIR% */
163
  pathlen = env_lookup_valcopy(buff, 128, env_seg, "DOSDIR");
164
  if (pathlen == 0) {
989 mateusz.vi 165
    nls_outputnl(29,5); /* "%DOSDIR% not defined" */
571 mateuszvis 166
    return(CMD_FAIL);
167
  }
168
 
169
  /* prep DOSDIR\LINKS\pattern */
170
  if (buff[pathlen - 1] == '\\') pathlen--;
171
  pathlen += sprintf(buff + pathlen, "\\LINKS\\");
172
  sprintf(buff + pathlen, "%s.LNK", linkname);
173
 
174
  if (findfirst(dta, buff, DOS_ATTR_RO | DOS_ATTR_ARC) != 0) return(CMD_OK);
175
 
176
  do {
177
    /* print link file name (but trim ".lnk") */
178
    for (i = 0; (dta->fname[i] != 0) && (dta->fname[i] != '.'); i++) buff16[i] = dta->fname[i];
179
    if (i < 8) buff16[i++] = '\t';
180
    buff16[i] = 0;
181
    output(buff16);
182
    output(" @ ");
183
    /* prep full link filename */
184
    strcpy(buff + pathlen, dta->fname);
185
    /* read up to 128 bytes from link file to buff and display it */
186
    i = 0;
187
    _asm {
188
      push ax
189
      push bx
190
      push cx
191
      push dx
192
 
193
      /* open file */
194
      mov ax, 0x3d00
195
      mov dx, buff   /* filename */
196
      int 0x21
197
      jc FAIL_FOPEN
198
      /* read from file */
199
      mov bx, ax
200
      mov ah, 0x3f
201
      mov cx, 128
202
      mov dx, buff128
203
      int 0x21
204
      jc FAIL_FREAD
205
      mov i, ax
206
      /* close file */
207
      FAIL_FREAD:
208
      mov ah, 0x3e
209
      int 0x21
210
      FAIL_FOPEN:
211
 
212
      pop dx
213
      pop cx
214
      pop bx
215
      pop ax
216
    }
217
    buff128[i] = 0;
218
    /* make sure no cr or lf is present */
219
    for (i = 0; buff128[i] != 0; i++) {
220
      if ((buff128[i] == '\r') || (buff128[i] == '\n')) {
221
        buff128[i] = 0;
222
        break;
223
      }
224
    }
225
    outputnl(buff128);
226
  } while (findnext(dta) == 0);
227
 
228
  return(CMD_OK);
229
}
230
 
231
 
232
static enum cmd_result cmd_ln(struct cmd_funcparam *p) {
233
  if (cmd_ishlp(p)) {
989 mateusz.vi 234
    nls_outputnl(29,0); /* "Adds, deletes or displays executable links." */
571 mateuszvis 235
    outputnl("");
989 mateusz.vi 236
    nls_outputnl(29,1); /* "LN ADD linkname targetdir" */
237
    nls_outputnl(29,2); /* "LN DEL linkname" */
238
    nls_outputnl(29,3); /* "LN LIST [pattern]" */
571 mateuszvis 239
    return(CMD_OK);
240
  }
241
 
242
  if (p->argc == 0) {
989 mateusz.vi 243
    nls_outputnl(0,7); /* "Required parameter missing */
571 mateuszvis 244
    return(CMD_OK);
245
  }
246
 
247
  /* 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));
249
  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")) {
251
    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));
253
  }
254
 
989 mateusz.vi 255
  nls_outputnl(0,6); /* "Invalid parameter" */
571 mateuszvis 256
  return(CMD_FAIL);
257
}