1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200
|
/*
* DEL.C - del command.
*
* Comments:
*
* 06/29/98 (Rob Lake rlake@cs.mun.ca)
* rewrote del to support wildcards
* added my name to the contributors
*
* 07/13/98 (Rob Lake)
* - fixed bug that caused del not to delete file with out attribute.
* - moved set, del, ren, and ver to there own files
*
* 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
* - added config.h include
*
* 09-Aug-1998 (Rob Lake <rlake@cs.mun.ca>)
* - changed check for ^C
* - alloced mem for char **arg
*
* 10-Aug-1998 ska
* - fixed allocation of char **arg incl. out-of-memory check
*
* 1998/12/04 ska
* - chg: vcgetchar() displays a space rather beep()s for no-printable
* characters. the caller can beep()
* - chg: moved vcgetchar() to misc.c as it is multiply used now
* - chg: use vcgetcstr() instead of vcgetchar() loop
*
* 1999/04/27 ska
* chg: uniform command line parser
* add: allow multiple patterns on command line
* add: delete count
*
* 1999/07/02 ska
* chg: replaced stat() by dfnstat() [reduces size of image]
*/
#include "../config.h"
//#define NODEL
#include <assert.h>
#include <ctype.h>
#include <dir.h>
#include <dos.h>
#include <io.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dfn.h>
#include "../include/cmdline.h"
#include "../include/command.h"
#include "../err_fcts.h"
#include "../strings.h"
static int optP, verbose;
#pragma argsused
optScanFct(opt_del)
{
switch(ch) {
case 'P': return optScanBool(optP);
case 'V': return optScanBool(verbose);
}
optErr();
return E_Useage;
}
int cmd_del(char *param)
{
int ec = E_None; /* exit code */
int i;
unsigned count = 0;
struct ffblk f;
/* Make fullname somewhat larger to ensure that appending
a matched name, one backslash and one hope. */
char fullname[MAXPATH + sizeof(f.ff_name) + 2],
*p, *q;
int len;
char **arg;
int argc, optc;
/* initialize options */
verbose = optP = 0;
if((arg = scanCmdline(param, opt_del, 0, &argc, &optc)) == 0)
return E_Other;
if(!argc) {
error_req_param_missing();
ec = E_Useage;
} else {
i = 0;
do {
assert(arg[i]);
/* Get the pattern fully-qualified */
/* Note: An absolute path always contains:
A:\\
--> It's always three bytes long at minimum
and always contains a backslash */
p = dfnexpand(arg[i], 0);
if(!p) {
error_out_of_memory();
return E_NoMem;
}
assert(strlen(p) >= 3);
if((len = strlen(p)) >= MAXPATH) {
error_filename_too_long(p);
free(p);
ec = E_Other;
goto errRet;
}
strcpy(fullname, p); /* Operating over a local buffer simplifies
the process; rather than keep the pattern
within dynamic memory */
free(p);
p = fullname + len;
/* check if it is a directory */
if(dfnstat(fullname) & DFN_DIRECTORY) {
if (p[-1] != '\\')
*p++ = '\\';
}
if(p[-1] == '\\') /* delete a whole directory */
p = stpcpy(p, "*.*");
/* p := address to copy the filename to to form the fully-qualified
filename */
/* There is at least one backslash within fullname,
because of dfnexpand() */
while(*--p != '\\') ;
++p;
/* make sure user is sure if all files are to be
* deleted */
if(!optP && *p == '*'
&& ((q = strchr(p, '.')) == 0 || q[1] == '*')) {
if(userprompt(PROMPT_DELETE_ALL, p) != 1) {
ec = E_Other;
goto errRet;
}
}
if (FINDFIRST(fullname, &f, FA_ARCH)) {
error_sfile_not_found(fullname);
} else do {
strcpy(p, f.ff_name); /* Make the full path */
if(optP) {
switch(userprompt(PROMPT_DELETE_FILE, fullname)) {
case 4: /* Quit/^Break pressed */
ec = E_CBreak;
goto errRet;
case 3: /* all */
optP = 0;
case 1:
break; /* yes, delete */
default:
case 2:
continue; /* no, don't delete */
}
}
else if(cbreak) { /* is also probed for in vcgetstr() */
ec = E_CBreak;
goto errRet;
}
#ifdef NODEL
/* define NODEL if you want to debug */
puts(fullname);
#else
if(verbose && !optP)
displayString(TEXT_DELETE_FILE, fullname);
if(unlink(fullname) != 0) {
perror(fullname); /* notify the user */
} else
++count;
#endif
} while (FINDNEXT(&f) == 0);
} while(++i < argc);
}
errRet:
if(echo)
dispCount(count, TEXT_MSG_DEL_CNT_FILES);
freep(arg);
return ec;
}
|