368 |
mateuszvis |
1 |
/*
|
|
|
2 |
* dir
|
|
|
3 |
*
|
|
|
4 |
* Displays a list of files and subdirectories in a directory.
|
|
|
5 |
*
|
|
|
6 |
* DIR [drive:][path][filename] [/P] [/W] [/A[:]attributes] [/O[[:]sortorder]] [/S] [/B] [/L]
|
|
|
7 |
*
|
|
|
8 |
* /P Pauses after each screenful of information.
|
|
|
9 |
* /W Uses wide list format.
|
|
|
10 |
*
|
|
|
11 |
* /A Displays file with specified attributes:
|
|
|
12 |
* D Directories R Read-only files H Hidden files
|
|
|
13 |
* A Ready for archiving S System files - prefix meaning "not"
|
|
|
14 |
*
|
|
|
15 |
* /O List files in sorted order:
|
|
|
16 |
* N by name S by size E by extension
|
|
|
17 |
* D by date G group dirs first - prefix to reverse order
|
|
|
18 |
*
|
|
|
19 |
* /S Displays files in specified directory and all subdirectories.
|
|
|
20 |
* /B Uses bare format (no heading information or summary)
|
|
|
21 |
* /L Uses lowercases
|
|
|
22 |
*/
|
|
|
23 |
|
396 |
mateuszvis |
24 |
/* NOTE: /A attributes are matched in an exclusive way, ie. only files with
|
|
|
25 |
* the specified attributes are matched. This is different from how DOS
|
|
|
26 |
* itself matches attributes hence DIR cannot rely on the attributes
|
|
|
27 |
* filter within FindFirst.
|
|
|
28 |
*
|
|
|
29 |
* NOTE: Multiple /A are not supported - only the last one is significant.
|
|
|
30 |
*/
|
|
|
31 |
|
372 |
mateuszvis |
32 |
static int cmd_dir(struct cmd_funcparam *p) {
|
393 |
mateuszvis |
33 |
const char *filespecptr = NULL;
|
388 |
mateuszvis |
34 |
struct DTA *dta = (void *)0x80; /* set DTA to its default location at 80h in PSP */
|
393 |
mateuszvis |
35 |
int i;
|
396 |
mateuszvis |
36 |
unsigned short availrows; /* counter of available rows on display (used for /P) */
|
|
|
37 |
#define DIR_FLAG_PAUSE 1
|
|
|
38 |
#define DIR_FLAG_WIDE 2
|
|
|
39 |
#define DIR_FLAG_RECUR 4
|
|
|
40 |
#define DIR_FLAG_BARE 8
|
|
|
41 |
#define DIR_FLAG_LCASE 16
|
|
|
42 |
unsigned char flags = 0;
|
|
|
43 |
// unsigned char attribs_show = 0; /* show only files with ALL these attribs */
|
|
|
44 |
// unsigned char attribs_hide = 0; /* hide files with ANY of these attribs */
|
368 |
mateuszvis |
45 |
|
390 |
mateuszvis |
46 |
if (cmd_ishlp(p)) {
|
396 |
mateuszvis |
47 |
outputnl("Displays a list of files and subdirectories in a directory");
|
|
|
48 |
outputnl("");
|
|
|
49 |
outputnl("DIR [drive:][path][filename] [/P] [/W] [/A[:]attributes] [/O[[:]sortorder]] [/S] [/B] [/L]");
|
|
|
50 |
outputnl("");
|
|
|
51 |
outputnl("/P Pauses after each screenful of information");
|
|
|
52 |
outputnl("/W Uses wide list format");
|
|
|
53 |
outputnl("");
|
|
|
54 |
outputnl("/A Displays files with specified attributes:");
|
|
|
55 |
outputnl(" D Directories R Read-only files H Hidden files");
|
|
|
56 |
outputnl(" A Ready for archiving S System files - prefix meaning \"not\"");
|
|
|
57 |
outputnl("");
|
|
|
58 |
outputnl("/O List files in sorted order:");
|
|
|
59 |
outputnl(" N by name S by size E by extension");
|
|
|
60 |
outputnl(" D by date G group dirs first - prefix to reverse order");
|
|
|
61 |
outputnl("");
|
|
|
62 |
outputnl("/S Displays files in specified directory and all subdirectories");
|
|
|
63 |
outputnl("/B Uses bare format (no heading information or summary)");
|
|
|
64 |
outputnl("/L Uses lowercases");
|
|
|
65 |
|
|
|
66 |
/* TODO FIXME REMOVE THIS ONCE ALL IMPLEMENTED */
|
|
|
67 |
outputnl("\r\n*** THIS COMMAND IS NOT FULLY IMPLEMENTED YET ***");
|
|
|
68 |
|
390 |
mateuszvis |
69 |
return(-1);
|
|
|
70 |
}
|
|
|
71 |
|
393 |
mateuszvis |
72 |
/* parse command line */
|
|
|
73 |
for (i = 0; i < p->argc; i++) {
|
|
|
74 |
if (p->argv[i][0] == '/') {
|
396 |
mateuszvis |
75 |
char arg;
|
|
|
76 |
char neg = 0;
|
|
|
77 |
/* detect negations and get actual argument */
|
|
|
78 |
if (p->argv[i][1] == '-') neg = 1;
|
|
|
79 |
arg = p->argv[i][1 + neg];
|
|
|
80 |
/* */
|
|
|
81 |
switch (arg) {
|
|
|
82 |
case 'a':
|
|
|
83 |
case 'A':
|
|
|
84 |
/* TODO */
|
|
|
85 |
outputnl("/A NOT IMPLEMENTED YET");
|
|
|
86 |
return(-1);
|
|
|
87 |
break;
|
|
|
88 |
case 'p':
|
|
|
89 |
case 'P':
|
|
|
90 |
flags |= DIR_FLAG_PAUSE;
|
|
|
91 |
if (neg) flags &= (0xff ^ DIR_FLAG_PAUSE);
|
|
|
92 |
break;
|
393 |
mateuszvis |
93 |
default:
|
|
|
94 |
outputnl("Invalid switch");
|
|
|
95 |
return(-1);
|
|
|
96 |
}
|
|
|
97 |
} else { /* filespec */
|
|
|
98 |
if (filespecptr != NULL) {
|
|
|
99 |
outputnl("Too many parameters");
|
|
|
100 |
return(-1);
|
|
|
101 |
}
|
|
|
102 |
filespecptr = p->argv[i];
|
|
|
103 |
}
|
|
|
104 |
}
|
368 |
mateuszvis |
105 |
|
393 |
mateuszvis |
106 |
if (filespecptr == NULL) filespecptr = ".";
|
|
|
107 |
|
|
|
108 |
file_truename(filespecptr, p->BUFFER);
|
|
|
109 |
|
|
|
110 |
/* if dir then append \????????.??? */
|
|
|
111 |
i = file_getattr(p->BUFFER);
|
|
|
112 |
if ((i > 0) && (i & DOS_ATTR_DIR)) strcat(p->BUFFER, "\\????????.???");
|
|
|
113 |
|
|
|
114 |
if (findfirst(dta, p->BUFFER, DOS_ATTR_RO | DOS_ATTR_HID | DOS_ATTR_SYS | DOS_ATTR_DIR | DOS_ATTR_ARC) != 0) return(-1);
|
|
|
115 |
|
396 |
mateuszvis |
116 |
availrows = screen_getheight();
|
|
|
117 |
|
369 |
mateuszvis |
118 |
outputnl(dta->fname);
|
396 |
mateuszvis |
119 |
availrows--;
|
368 |
mateuszvis |
120 |
|
396 |
mateuszvis |
121 |
while (findnext(dta) == 0) {
|
|
|
122 |
outputnl(dta->fname);
|
|
|
123 |
if (flags & DIR_FLAG_PAUSE) {
|
|
|
124 |
availrows--;
|
|
|
125 |
if (availrows < 2) {
|
|
|
126 |
press_any_key();
|
|
|
127 |
availrows = screen_getheight();
|
|
|
128 |
}
|
|
|
129 |
}
|
|
|
130 |
}
|
368 |
mateuszvis |
131 |
|
|
|
132 |
return(-1);
|
|
|
133 |
}
|