Subversion Repositories SvarDOS

Rev

Rev 518 | Rev 538 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
421 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 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
 
392 mateuszvis 25
/*
26
 * del/erase
27
 */
28
 
533 mateuszvis 29
static enum cmd_result cmd_del(struct cmd_funcparam *p) {
392 mateuszvis 30
  const char *delspec = NULL;
31
  unsigned short err = 0;
32
  unsigned short confirmflag = 0;
33
  unsigned short i;
34
  unsigned short pathlimit = 0;
35
  char *buff = p->BUFFER;
36
 
37
  struct DTA *dta = (void *)0x80; /* use the default DTA at location 80h in PSP */
38
  char *fname = dta->fname;
39
 
40
  if (cmd_ishlp(p)) {
41
    outputnl("Deletes one or more files.");
42
    outputnl("");
43
    outputnl("DEL [drive:][path]filename [/P]");
44
    outputnl("ERASE [drive:][path]filename [/P]");
45
    outputnl("");
46
    outputnl("[drive:][path]filename  Specifies the file(s) to delete.");
47
    outputnl("/P  Prompts for confirmation before deleting each file.");
533 mateuszvis 48
    return(CMD_OK);
392 mateuszvis 49
  }
50
 
51
  if (p->argc == 0) {
52
    outputnl("Required parameter missing");
533 mateuszvis 53
    return(CMD_FAIL);
392 mateuszvis 54
  }
55
 
56
  /* scan argv for delspec and possible /p or /v */
57
  for (i = 0; i < p->argc; i++) {
58
    /* delspec? */
59
    if (p->argv[i][0] == '/') {
60
      if (imatch(p->argv[i], "/p")) {
61
        confirmflag = 1;
62
      } else {
63
        output("Invalid switch:");
64
        output(" ");
65
        outputnl(p->argv[i]);
533 mateuszvis 66
        return(CMD_FAIL);
392 mateuszvis 67
      }
68
    } else if (delspec != NULL) { /* otherwise its a delspec */
69
      outputnl("Too many parameters");
533 mateuszvis 70
      return(CMD_FAIL);
392 mateuszvis 71
    } else {
72
      delspec = p->argv[i];
73
    }
74
  }
75
 
76
  /* convert path to canonical form */
77
  file_truename(delspec, buff);
78
 
79
  /* is delspec pointing at a directory? if so, add a \*.* */
518 mateuszvis 80
  i = path_appendbkslash_if_dir(buff);
81
  if (buff[i - 1] == '\\') strcat(buff, "????????.???");
392 mateuszvis 82
 
83
  /* parse delspec in buff and remember where last backslash or slash is */
84
  for (i = 0; buff[i] != 0; i++) if (buff[i] == '\\') pathlimit = i + 1;
85
 
86
  /* is this about deleting all content inside a directory? if no per-file
87
   * confirmation set, ask for a global confirmation */
88
  if ((confirmflag == 0) && (imatch(buff + pathlimit, "????????.???"))) {
89
    outputnl("All files in directory will be deleted!");
533 mateuszvis 90
    if (askchoice("Are you sure (Y/N)?", "YN") != 0) return(CMD_FAIL);
392 mateuszvis 91
  }
92
 
93
  for (i = 0;; i = 1) {
94
 
95
    /* exec FindFirst or FindNext */
96
    if (i == 0) {
97
      err = findfirst(dta, buff, DOS_ATTR_RO | DOS_ATTR_SYS | DOS_ATTR_HID);
518 mateuszvis 98
      if (err != 0) { /* report the error only if query had no wildcards */
99
        for (i = 0; buff[i] != 0; i++) if (buff[i] == '?') break;
100
        if (buff[i] == 0) outputnl(doserr(err));
101
        break;
102
      }
392 mateuszvis 103
    } else {
518 mateuszvis 104
      if (findnext(dta) != 0) break; /* do not report errors on findnext() */
392 mateuszvis 105
    }
106
 
518 mateuszvis 107
    /* prep the full path/name of the file in buff */
108
    /* NOTE: buff contained the search pattern but it is no longer needed so I
109
     * can reuse it now */
110
    strcpy(buff + pathlimit, fname);
392 mateuszvis 111
 
112
    /* ask if confirmation required: PLIK.TXT  Delete (Y/N)? */
113
    if (confirmflag) {
114
      output(buff);
115
      output(" \t");
116
      if (askchoice("Delete (Y/N)?", "YN") != 0) continue;
117
    }
118
 
119
    /* del found file */
120
    _asm {
518 mateuszvis 121
      push ax
122
      push dx
392 mateuszvis 123
      mov ah, 0x41      /* delete a file, DS:DX points to an ASCIIZ filespec (no wildcards allowed) */
518 mateuszvis 124
      mov dx, buff
392 mateuszvis 125
      int 0x21
126
      jnc DONE
127
      mov [err], ax
128
      DONE:
518 mateuszvis 129
      pop dx
130
      pop ax
392 mateuszvis 131
    }
132
 
133
    if (err != 0) {
134
      output(fname);
135
      output(": ");
136
      outputnl(doserr(err));
137
      break;
138
    }
139
  }
518 mateuszvis 140
 
533 mateuszvis 141
  if (err == 0) return(CMD_OK);
142
  return(CMD_FAIL);
392 mateuszvis 143
}