0,0 → 1,133 |
/* |
* dir |
* |
* Displays a list of files and subdirectories in a directory. |
* |
* DIR [drive:][path][filename] [/P] [/W] [/A[:]attributes] [/O[[:]sortorder]] [/S] [/B] [/L] |
* |
* /P Pauses after each screenful of information. |
* /W Uses wide list format. |
* |
* /A Displays file with specified attributes: |
* D Directories R Read-only files H Hidden files |
* A Ready for archiving S System files - prefix meaning "not" |
* |
* /O List files in sorted order: |
* N by name S by size E by extension |
* D by date G group dirs first - prefix to reverse order |
* |
* /S Displays files in specified directory and all subdirectories. |
* /B Uses bare format (no heading information or summary) |
* /L Uses lowercases |
*/ |
|
/* NOTE: /A attributes are matched in an exclusive way, ie. only files with |
* the specified attributes are matched. This is different from how DOS |
* itself matches attributes hence DIR cannot rely on the attributes |
* filter within FindFirst. |
* |
* NOTE: Multiple /A are not supported - only the last one is significant. |
*/ |
|
static int cmd_dir(struct cmd_funcparam *p) { |
const char *filespecptr = NULL; |
struct DTA *dta = (void *)0x80; /* set DTA to its default location at 80h in PSP */ |
int i; |
unsigned short availrows; /* counter of available rows on display (used for /P) */ |
#define DIR_FLAG_PAUSE 1 |
#define DIR_FLAG_WIDE 2 |
#define DIR_FLAG_RECUR 4 |
#define DIR_FLAG_BARE 8 |
#define DIR_FLAG_LCASE 16 |
unsigned char flags = 0; |
// unsigned char attribs_show = 0; /* show only files with ALL these attribs */ |
// unsigned char attribs_hide = 0; /* hide files with ANY of these attribs */ |
|
if (cmd_ishlp(p)) { |
outputnl("Displays a list of files and subdirectories in a directory"); |
outputnl(""); |
outputnl("DIR [drive:][path][filename] [/P] [/W] [/A[:]attributes] [/O[[:]sortorder]] [/S] [/B] [/L]"); |
outputnl(""); |
outputnl("/P Pauses after each screenful of information"); |
outputnl("/W Uses wide list format"); |
outputnl(""); |
outputnl("/A Displays files with specified attributes:"); |
outputnl(" D Directories R Read-only files H Hidden files"); |
outputnl(" A Ready for archiving S System files - prefix meaning \"not\""); |
outputnl(""); |
outputnl("/O List files in sorted order:"); |
outputnl(" N by name S by size E by extension"); |
outputnl(" D by date G group dirs first - prefix to reverse order"); |
outputnl(""); |
outputnl("/S Displays files in specified directory and all subdirectories"); |
outputnl("/B Uses bare format (no heading information or summary)"); |
outputnl("/L Uses lowercases"); |
|
/* TODO FIXME REMOVE THIS ONCE ALL IMPLEMENTED */ |
outputnl("\r\n*** THIS COMMAND IS NOT FULLY IMPLEMENTED YET ***"); |
|
return(-1); |
} |
|
/* parse command line */ |
for (i = 0; i < p->argc; i++) { |
if (p->argv[i][0] == '/') { |
char arg; |
char neg = 0; |
/* detect negations and get actual argument */ |
if (p->argv[i][1] == '-') neg = 1; |
arg = p->argv[i][1 + neg]; |
/* */ |
switch (arg) { |
case 'a': |
case 'A': |
/* TODO */ |
outputnl("/A NOT IMPLEMENTED YET"); |
return(-1); |
break; |
case 'p': |
case 'P': |
flags |= DIR_FLAG_PAUSE; |
if (neg) flags &= (0xff ^ DIR_FLAG_PAUSE); |
break; |
default: |
outputnl("Invalid switch"); |
return(-1); |
} |
} else { /* filespec */ |
if (filespecptr != NULL) { |
outputnl("Too many parameters"); |
return(-1); |
} |
filespecptr = p->argv[i]; |
} |
} |
|
if (filespecptr == NULL) filespecptr = "."; |
|
file_truename(filespecptr, p->BUFFER); |
|
/* if dir then append \????????.??? */ |
i = file_getattr(p->BUFFER); |
if ((i > 0) && (i & DOS_ATTR_DIR)) strcat(p->BUFFER, "\\????????.???"); |
|
if (findfirst(dta, p->BUFFER, DOS_ATTR_RO | DOS_ATTR_HID | DOS_ATTR_SYS | DOS_ATTR_DIR | DOS_ATTR_ARC) != 0) return(-1); |
|
availrows = screen_getheight(); |
|
outputnl(dta->fname); |
availrows--; |
|
while (findnext(dta) == 0) { |
outputnl(dta->fname); |
if (flags & DIR_FLAG_PAUSE) { |
availrows--; |
if (availrows < 2) { |
press_any_key(); |
availrows = screen_getheight(); |
} |
} |
} |
|
return(-1); |
} |