Subversion Repositories SvarDOS

Compare Revisions

Ignore whitespace Rev 391 → Rev 392

/svarcom/cmd/del.c
0,0 → 1,107
/*
* del/erase
*/
 
static int cmd_del(struct cmd_funcparam *p) {
const char *delspec = NULL;
unsigned short err = 0;
unsigned short confirmflag = 0;
unsigned short i;
unsigned short pathlimit = 0;
char *buff = p->BUFFER;
 
struct DTA *dta = (void *)0x80; /* use the default DTA at location 80h in PSP */
char *fname = dta->fname;
 
if (cmd_ishlp(p)) {
outputnl("Deletes one or more files.");
outputnl("");
outputnl("DEL [drive:][path]filename [/P]");
outputnl("ERASE [drive:][path]filename [/P]");
outputnl("");
outputnl("[drive:][path]filename Specifies the file(s) to delete.");
outputnl("/P Prompts for confirmation before deleting each file.");
return(-1);
}
 
if (p->argc == 0) {
outputnl("Required parameter missing");
return(-1);
}
 
/* scan argv for delspec and possible /p or /v */
for (i = 0; i < p->argc; i++) {
/* delspec? */
if (p->argv[i][0] == '/') {
if (imatch(p->argv[i], "/p")) {
confirmflag = 1;
} else {
output("Invalid switch:");
output(" ");
outputnl(p->argv[i]);
return(-1);
}
} else if (delspec != NULL) { /* otherwise its a delspec */
outputnl("Too many parameters");
return(-1);
} else {
delspec = p->argv[i];
}
}
 
/* convert path to canonical form */
file_truename(delspec, buff);
 
/* is delspec pointing at a directory? if so, add a \*.* */
{ int attr = file_getattr(delspec);
if ((attr > 0) && (attr & DOS_ATTR_DIR)) strcat(buff, "\\????????.???");
}
 
/* parse delspec in buff and remember where last backslash or slash is */
for (i = 0; buff[i] != 0; i++) if (buff[i] == '\\') pathlimit = i + 1;
 
/* is this about deleting all content inside a directory? if no per-file
* confirmation set, ask for a global confirmation */
if ((confirmflag == 0) && (imatch(buff + pathlimit, "????????.???"))) {
outputnl("All files in directory will be deleted!");
if (askchoice("Are you sure (Y/N)?", "YN") != 0) return(-1);
}
 
for (i = 0;; i = 1) {
 
/* exec FindFirst or FindNext */
if (i == 0) {
err = findfirst(dta, buff, DOS_ATTR_RO | DOS_ATTR_SYS | DOS_ATTR_HID);
} else {
err = findnext(dta);
}
 
if (err != 0) break;
 
/* ask if confirmation required: PLIK.TXT Delete (Y/N)? */
if (confirmflag) {
strcpy(buff + pathlimit, fname); /* note: buff contained the search pattern but it no longer needed so I can reuse it now */
output(buff);
output(" \t");
if (askchoice("Delete (Y/N)?", "YN") != 0) continue;
}
 
/* del found file */
_asm {
mov ah, 0x41 /* delete a file, DS:DX points to an ASCIIZ filespec (no wildcards allowed) */
mov dx, fname
int 0x21
jnc DONE
mov [err], ax
DONE:
}
 
if (err != 0) {
output(fname);
output(": ");
outputnl(doserr(err));
break;
}
}
return(-1);
}
/svarcom/cmd.c
32,6 → 32,7
 
#include "cmd/_notimpl.c"
#include "cmd/cd.c"
#include "cmd/del.c"
#include "cmd/dir.c"
#include "cmd/exit.c"
#include "cmd/mkdir.c"
60,10 → 61,10
{"COPY", cmd_notimpl},
{"CTTY", cmd_notimpl},
{"DATE", cmd_notimpl},
{"DEL", cmd_notimpl},
{"DEL", cmd_del},
{"DIR", cmd_dir},
{"ECHO", cmd_notimpl},
{"ERASE", cmd_notimpl},
{"ERASE", cmd_del},
{"EXIT", cmd_exit},
{"LH", cmd_notimpl},
{"LOADHIGH",cmd_notimpl},
/svarcom/helpers.c
94,3 → 94,78
}
return(res);
}
 
 
/* print s string and wait for a single key press from stdin. accepts only
* key presses defined in the c ASCIIZ string. returns offset of pressed key
* in string. keys in c MUST BE UPPERCASE! */
unsigned short askchoice(const char *s, const char *c) {
unsigned short res;
char key = 0;
 
AGAIN:
output(s);
output(" ");
 
_asm {
push ax
push dx
 
mov ax, 0x0c01 /* clear input buffer and execute getchar (INT 21h,AH=1) */
int 0x21
/* if AL == 0 then this is an extended character */
test al, al
jnz GOTCHAR
mov ah, 0x08 /* read again to flush extended char from input buffer */
int 0x21
xor al, al /* all extended chars are ignored */
GOTCHAR: /* received key is in AL now */
mov [key], al /* save key */
 
/* print a cr/lf */
mov ah, 0x02
mov dl, 0x0D
int 0x21
mov dl, 0x0A
int 0x21
 
pop dx
pop ax
}
 
/* ucase() result */
if ((key >= 'a') && (key <= 'z')) key -= ('a' - 'A');
 
/* is there a match? */
for (res = 0; c[res] != 0; res++) if (c[res] == key) return(res);
 
goto AGAIN;
}
 
 
/* converts a path to its canonic representation */
void file_truename(const char *src, char *dst) {
_asm {
mov ah, 0x60 /* query truename, DS:SI=src, ES:DI=dst */
push ds
pop es
mov si, src
mov di, dst
int 0x21
}
}
 
 
/* returns DOS attributes of file, or -1 on error */
int file_getattr(const char *fname) {
int res = -1;
_asm {
mov ax, 0x4300 /* query file attributes, fname at DS:DX */
mov dx, fname
int 0x21 /* CX=attributes if CF=0, otherwise AX=errno */
jc DONE
mov [res], cx
DONE:
}
return(res);
}
/svarcom/helpers.h
46,4 → 46,15
/* find next matching, ie. continues an action intiated by findfirst() */
unsigned short findnext(struct DTA *dta);
 
/* print s string and wait for a single key press from stdin. accepts only
* key presses defined in the c ASCIIZ string. returns offset of pressed key
* in string. keys in c MUST BE UPPERCASE! */
unsigned short askchoice(const char *s, const char *c);
 
/* converts a path to its canonic representation */
void file_truename(const char *src, char *dst);
 
/* returns DOS attributes of file, or -1 on error */
int file_getattr(const char *fname);
 
#endif