Subversion Repositories SvarDOS

Rev

Rev 403 | Rev 420 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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