Subversion Repositories SvarDOS

Rev

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

Rev 421 Rev 424
1
/* This file is part of the SvarCOM project and is published under the terms
1
/* This file is part of the SvarCOM project and is published under the terms
2
 * of the MIT license.
2
 * of the MIT license.
3
 *
3
 *
4
 * Copyright (C) 2021 Mateusz Viste
4
 * Copyright (C) 2021 Mateusz Viste
5
 *
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a
6
 * Permission is hereby granted, free of charge, to any person obtaining a
7
 * copy of this software and associated documentation files (the "Software"),
7
 * copy of this software and associated documentation files (the "Software"),
8
 * to deal in the Software without restriction, including without limitation
8
 * to deal in the Software without restriction, including without limitation
9
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
 * and/or sell copies of the Software, and to permit persons to whom the
10
 * and/or sell copies of the Software, and to permit persons to whom the
11
 * Software is furnished to do so, subject to the following conditions:
11
 * Software is furnished to do so, subject to the following conditions:
12
 *
12
 *
13
 * The above copyright notice and this permission notice shall be included in
13
 * The above copyright notice and this permission notice shall be included in
14
 * all copies or substantial portions of the Software.
14
 * all copies or substantial portions of the Software.
15
 *
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22
 * DEALINGS IN THE SOFTWARE.
22
 * DEALINGS IN THE SOFTWARE.
23
 */
23
 */
24
 
24
 
25
/*
25
/*
26
 * dir
26
 * dir
27
 *
27
 *
28
 * Displays a list of files and subdirectories in a directory.
28
 * Displays a list of files and subdirectories in a directory.
29
 *
29
 *
30
 * DIR [drive:][path][filename] [/P] [/W] [/A[:]attributes] [/O[[:]sortorder]] [/S] [/B] [/L]
30
 * DIR [drive:][path][filename] [/P] [/W] [/A[:]attributes] [/O[[:]sortorder]] [/S] [/B] [/L]
31
 *
31
 *
32
 * /P Pauses after each screenful of information.
32
 * /P Pauses after each screenful of information.
33
 * /W Uses wide list format.
33
 * /W Uses wide list format.
34
 *
34
 *
35
 * /A Displays file with specified attributes:
35
 * /A Displays file with specified attributes:
36
 *     D Directories           R Read-only files     H Hidden files
36
 *     D Directories           R Read-only files     H Hidden files
37
 *     A Ready for archiving   S System files        - prefix meaning "not"
37
 *     A Ready for archiving   S System files        - prefix meaning "not"
38
 *
38
 *
39
 * /O List files in sorted order:
39
 * /O List files in sorted order:
40
 *     N by name            S by size              E by extension
40
 *     N by name            S by size              E by extension
41
 *     D by date            G group dirs first     - prefix to reverse order
41
 *     D by date            G group dirs first     - prefix to reverse order
42
 *
42
 *
43
 * /S Displays files in specified directory and all subdirectories.
43
 * /S Displays files in specified directory and all subdirectories.
44
 * /B Uses bare format (no heading information or summary)
44
 * /B Uses bare format (no heading information or summary)
45
 * /L Uses lowercases
45
 * /L Uses lowercases
46
 */
46
 */
47
 
47
 
48
/* NOTE: /A attributes are matched in an exclusive way, ie. only files with
48
/* NOTE: /A attributes are matched in an exclusive way, ie. only files with
49
 *       the specified attributes are matched. This is different from how DOS
49
 *       the specified attributes are matched. This is different from how DOS
50
 *       itself matches attributes hence DIR cannot rely on the attributes
50
 *       itself matches attributes hence DIR cannot rely on the attributes
51
 *       filter within FindFirst.
51
 *       filter within FindFirst.
52
 *
52
 *
53
 * NOTE: Multiple /A are not supported - only the last one is significant.
53
 * NOTE: Multiple /A are not supported - only the last one is significant.
54
 */
54
 */
55
 
55
 
56
#define WCOLWIDTH 15  /* width of a column in wide mode output */
56
#define WCOLWIDTH 15  /* width of a column in wide mode output */
57
 
57
 
-
 
58
 
-
 
59
/* fills freebytes with free bytes for drv (A=0, B=1, etc)
-
 
60
 * returns DOS ERR code on failure */
-
 
61
static unsigned short cmd_dir_df(unsigned long *freebytes, unsigned char drv) {
-
 
62
  unsigned short res = 0;
-
 
63
  unsigned short sects_per_clust = 0, avail_clusts = 0, bytes_per_sect = 0;
-
 
64
 
-
 
65
  _asm {
-
 
66
    push ax
-
 
67
    push bx
-
 
68
    push cx
-
 
69
    push dx
-
 
70
 
-
 
71
    mov ah, 0x36  /* DOS 2+ -- Get Disk Free Space */
-
 
72
    mov dl, [drv] /* A=1, B=2, etc (0 = DEFAULT DRIVE) */
-
 
73
    inc dl
-
 
74
    int 0x21      /* AX=sects_per_clust, BX=avail_clusts, CX=bytes_per_sect, DX=tot_clusters */
-
 
75
    cmp ax, 0xffff /* AX=0xffff on error (invalid drive) */
-
 
76
    jne COMPUTEDF
-
 
77
    mov [res], 0x0f /* fill res with DOS error code 15 ("invalid drive") */
-
 
78
    jmp DONE
-
 
79
 
-
 
80
    COMPUTEDF:
-
 
81
    /* freebytes = AX * BX * CX */
-
 
82
    mov [sects_per_clust], ax
-
 
83
    mov [avail_clusts], bx
-
 
84
    mov [bytes_per_sect], cx
-
 
85
 
-
 
86
    DONE:
-
 
87
    pop dx
-
 
88
    pop cx
-
 
89
    pop bx
-
 
90
    pop ax
-
 
91
  }
-
 
92
 
-
 
93
  /* multiple steps to avoid uint16 overflow */
-
 
94
  *freebytes = sects_per_clust;
-
 
95
  *freebytes *= avail_clusts;
-
 
96
  *freebytes *= bytes_per_sect;
-
 
97
 
-
 
98
  return(res);
-
 
99
}
-
 
100
 
-
 
101
 
58
static int cmd_dir(struct cmd_funcparam *p) {
102
static int cmd_dir(struct cmd_funcparam *p) {
59
  const char *filespecptr = NULL;
103
  const char *filespecptr = NULL;
60
  struct DTA *dta = (void *)0x80; /* set DTA to its default location at 80h in PSP */
104
  struct DTA *dta = (void *)0x80; /* set DTA to its default location at 80h in PSP */
61
  unsigned short i;
105
  unsigned short i;
62
  unsigned short availrows;  /* counter of available rows on display (used for /P) */
106
  unsigned short availrows;  /* counter of available rows on display (used for /P) */
63
  unsigned short wcols = screen_getwidth() / WCOLWIDTH; /* number of columns in wide mode */
107
  unsigned short wcols = screen_getwidth() / WCOLWIDTH; /* number of columns in wide mode */
64
  unsigned char wcolcount;
108
  unsigned char wcolcount;
65
  struct nls_patterns *nls = (void *)(p->BUFFER + (BUFFER_SIZE / 3));
109
  struct nls_patterns *nls = (void *)(p->BUFFER + (BUFFER_SIZE / 3));
66
  char *buff2 = p->BUFFER + (BUFFER_SIZE / 3 * 2);
110
  char *buff2 = p->BUFFER + (BUFFER_SIZE / 3 * 2);
-
 
111
  unsigned long summary_fcount = 0;
-
 
112
  unsigned long summary_totsz = 0;
-
 
113
  unsigned char drv = 0;
67
 
114
 
68
  #define DIR_FLAG_PAUSE  1
115
  #define DIR_FLAG_PAUSE  1
69
  #define DIR_FLAG_RECUR  4
116
  #define DIR_FLAG_RECUR  4
70
  #define DIR_FLAG_LCASE  8
117
  #define DIR_FLAG_LCASE  8
71
  unsigned char flags = 0;
118
  unsigned char flags = 0;
72
 
119
 
73
  #define DIR_OUTPUT_NORM 1
120
  #define DIR_OUTPUT_NORM 1
74
  #define DIR_OUTPUT_WIDE 2
121
  #define DIR_OUTPUT_WIDE 2
75
  #define DIR_OUTPUT_BARE 3
122
  #define DIR_OUTPUT_BARE 3
76
  unsigned char format = DIR_OUTPUT_NORM;
123
  unsigned char format = DIR_OUTPUT_NORM;
77
 
124
 
78
  if (cmd_ishlp(p)) {
125
  if (cmd_ishlp(p)) {
79
    outputnl("Displays a list of files and subdirectories in a directory");
126
    outputnl("Displays a list of files and subdirectories in a directory");
80
    outputnl("");
127
    outputnl("");
81
    outputnl("DIR [drive:][path][filename] [/P] [/W] [/A[:]attributes] [/O[[:]sortorder]] [/S] [/B] [/L]");
128
    outputnl("DIR [drive:][path][filename] [/P] [/W] [/A[:]attributes] [/O[[:]sortorder]] [/S] [/B] [/L]");
82
    outputnl("");
129
    outputnl("");
83
    outputnl("/P Pauses after each screenful of information");
130
    outputnl("/P Pauses after each screenful of information");
84
    outputnl("/W Uses wide list format");
131
    outputnl("/W Uses wide list format");
85
    outputnl("");
132
    outputnl("");
86
    outputnl("/A Displays files with specified attributes:");
133
    outputnl("/A Displays files with specified attributes:");
87
    outputnl("    D Directories            R Read-only files        H Hidden files");
134
    outputnl("    D Directories            R Read-only files        H Hidden files");
88
    outputnl("    A Ready for archiving    S System files           - prefix meaning \"not\"");
135
    outputnl("    A Ready for archiving    S System files           - prefix meaning \"not\"");
89
    outputnl("");
136
    outputnl("");
90
    outputnl("/O List files in sorted order:");
137
    outputnl("/O List files in sorted order:");
91
    outputnl("    N by name                S by size                E by extension");
138
    outputnl("    N by name                S by size                E by extension");
92
    outputnl("    D by date                G group dirs first       - prefix to reverse order");
139
    outputnl("    D by date                G group dirs first       - prefix to reverse order");
93
    outputnl("");
140
    outputnl("");
94
    outputnl("/S Displays files in specified directory and all subdirectories");
141
    outputnl("/S Displays files in specified directory and all subdirectories");
95
    outputnl("/B Uses bare format (no heading information or summary)");
142
    outputnl("/B Uses bare format (no heading information or summary)");
96
    outputnl("/L Uses lowercases");
143
    outputnl("/L Uses lowercases");
97
    return(-1);
144
    return(-1);
98
  }
145
  }
99
 
146
 
100
  i = nls_getpatterns(nls);
147
  i = nls_getpatterns(nls);
101
  if (i != 0) outputnl(doserr(i));
148
  if (i != 0) outputnl(doserr(i));
102
 
149
 
103
  /* parse command line */
150
  /* parse command line */
104
  for (i = 0; i < p->argc; i++) {
151
  for (i = 0; i < p->argc; i++) {
105
    if (p->argv[i][0] == '/') {
152
    if (p->argv[i][0] == '/') {
106
      char arg;
153
      char arg;
107
      char neg = 0;
154
      char neg = 0;
108
      /* detect negations and get actual argument */
155
      /* detect negations and get actual argument */
109
      if (p->argv[i][1] == '-') neg = 1;
156
      if (p->argv[i][1] == '-') neg = 1;
110
      arg = p->argv[i][1 + neg];
157
      arg = p->argv[i][1 + neg];
111
      /* */
158
      /* */
112
      switch (arg) {
159
      switch (arg) {
113
        case 'a':
160
        case 'a':
114
        case 'A':
161
        case 'A':
115
          /* TODO */
162
          /* TODO */
116
          outputnl("/A NOT IMPLEMENTED YET");
163
          outputnl("/A NOT IMPLEMENTED YET");
117
          return(-1);
164
          return(-1);
118
          break;
165
          break;
119
        case 'b':
166
        case 'b':
120
        case 'B':
167
        case 'B':
121
          format = DIR_OUTPUT_BARE;
168
          format = DIR_OUTPUT_BARE;
122
          break;
169
          break;
123
        case 'l':
170
        case 'l':
124
        case 'L':
171
        case 'L':
125
          flags |= DIR_FLAG_LCASE;
172
          flags |= DIR_FLAG_LCASE;
126
          break;
173
          break;
127
        case 'o':
174
        case 'o':
128
        case 'O':
175
        case 'O':
129
          /* TODO */
176
          /* TODO */
130
          outputnl("/O NOT IMPLEMENTED YET");
177
          outputnl("/O NOT IMPLEMENTED YET");
131
          return(-1);
178
          return(-1);
132
          break;
179
          break;
133
        case 'p':
180
        case 'p':
134
        case 'P':
181
        case 'P':
135
          flags |= DIR_FLAG_PAUSE;
182
          flags |= DIR_FLAG_PAUSE;
136
          if (neg) flags &= (0xff ^ DIR_FLAG_PAUSE);
183
          if (neg) flags &= (0xff ^ DIR_FLAG_PAUSE);
137
          break;
184
          break;
138
        case 's':
185
        case 's':
139
        case 'S':
186
        case 'S':
140
          /* TODO */
187
          /* TODO */
141
          outputnl("/S NOT IMPLEMENTED YET");
188
          outputnl("/S NOT IMPLEMENTED YET");
142
          return(-1);
189
          return(-1);
143
          break;
190
          break;
144
        case 'w':
191
        case 'w':
145
        case 'W':
192
        case 'W':
146
          format = DIR_OUTPUT_WIDE;
193
          format = DIR_OUTPUT_WIDE;
147
          break;
194
          break;
148
        default:
195
        default:
149
          outputnl("Invalid switch");
196
          outputnl("Invalid switch");
150
          return(-1);
197
          return(-1);
151
      }
198
      }
152
    } else {  /* filespec */
199
    } else {  /* filespec */
153
      if (filespecptr != NULL) {
200
      if (filespecptr != NULL) {
154
        outputnl("Too many parameters");
201
        outputnl("Too many parameters");
155
        return(-1);
202
        return(-1);
156
      }
203
      }
157
      filespecptr = p->argv[i];
204
      filespecptr = p->argv[i];
158
    }
205
    }
159
  }
206
  }
160
 
207
 
161
  if (filespecptr == NULL) filespecptr = ".";
208
  if (filespecptr == NULL) filespecptr = ".";
162
 
209
 
163
  /* special case: "DIR drive:" (truename() fails on "C:" under MS-DOS 6.0) */
210
  /* special case: "DIR drive:" (truename() fails on "C:" under MS-DOS 6.0) */
164
  if ((filespecptr[0] != 0) && (filespecptr[1] == ':') && (filespecptr[2] == 0)) {
211
  if ((filespecptr[0] != 0) && (filespecptr[1] == ':') && (filespecptr[2] == 0)) {
165
    if ((filespecptr[0] >= 'a') && (filespecptr[0] <= 'z')) {
212
    if ((filespecptr[0] >= 'a') && (filespecptr[0] <= 'z')) {
166
      p->BUFFER[0] = filespecptr[0] - ('a' - 1);
213
      p->BUFFER[0] = filespecptr[0] - ('a' - 1);
167
    } else {
214
    } else {
168
      p->BUFFER[0] = filespecptr[0] - ('A' - 1);
215
      p->BUFFER[0] = filespecptr[0] - ('A' - 1);
169
    }
216
    }
170
    i = curpathfordrv(p->BUFFER, p->BUFFER[0]);
217
    i = curpathfordrv(p->BUFFER, p->BUFFER[0]);
171
  } else {
218
  } else {
172
    i = file_truename(filespecptr, p->BUFFER);
219
    i = file_truename(filespecptr, p->BUFFER);
173
  }
220
  }
174
  if (i != 0) {
221
  if (i != 0) {
175
    outputnl(doserr(i));
222
    outputnl(doserr(i));
176
    return(-1);
223
    return(-1);
177
  }
224
  }
178
 
225
 
179
  if (format != DIR_OUTPUT_BARE) {
226
  if (format != DIR_OUTPUT_BARE) {
180
    unsigned char drv = p->BUFFER[0];
227
    drv = p->BUFFER[0];
181
    if (drv >= 'a') {
228
    if (drv >= 'a') {
182
      drv -= 'a';
229
      drv -= 'a';
183
    } else {
230
    } else {
184
      drv -= 'A';
231
      drv -= 'A';
185
    }
232
    }
186
    cmd_vol_internal(drv, buff2);
233
    cmd_vol_internal(drv, buff2);
187
    sprintf(buff2, "Directory of %s", p->BUFFER);
234
    sprintf(buff2, "Directory of %s", p->BUFFER);
188
    /* trim at first '?', if any */
235
    /* trim at first '?', if any */
189
    for (i = 0; buff2[i] != 0; i++) if (buff2[i] == '?') buff2[i] = 0;
236
    for (i = 0; buff2[i] != 0; i++) if (buff2[i] == '?') buff2[i] = 0;
190
    outputnl(buff2);
237
    outputnl(buff2);
191
    outputnl("");
238
    outputnl("");
192
  }
239
  }
193
 
240
 
194
  /* if dir: append a backslash (also get its len) */
241
  /* if dir: append a backslash (also get its len) */
195
  i = path_appendbkslash_if_dir(p->BUFFER);
242
  i = path_appendbkslash_if_dir(p->BUFFER);
196
 
243
 
197
  /* if ends with a \ then append ????????.??? */
244
  /* if ends with a \ then append ????????.??? */
198
  if (p->BUFFER[i - 1] == '\\') strcat(p->BUFFER, "????????.???");
245
  if (p->BUFFER[i - 1] == '\\') strcat(p->BUFFER, "????????.???");
199
 
246
 
200
  i = findfirst(dta, p->BUFFER, DOS_ATTR_RO | DOS_ATTR_HID | DOS_ATTR_SYS | DOS_ATTR_DIR | DOS_ATTR_ARC);
247
  i = findfirst(dta, p->BUFFER, DOS_ATTR_RO | DOS_ATTR_HID | DOS_ATTR_SYS | DOS_ATTR_DIR | DOS_ATTR_ARC);
201
  if (i != 0) {
248
  if (i != 0) {
202
    outputnl(doserr(i));
249
    outputnl(doserr(i));
203
    return(-1);
250
    return(-1);
204
  }
251
  }
205
 
252
 
206
  availrows = screen_getheight();
253
  availrows = screen_getheight();
207
  wcolcount = 0; /* may be used for columns counting with wide mode */
254
  wcolcount = 0; /* may be used for columns counting with wide mode */
208
 
255
 
209
  do {
256
  do {
210
    if (flags & DIR_FLAG_LCASE) _strlwr(dta->fname); /* OpenWatcom extension, probably does not care about NLS so results may be odd with non-A-Z characters... */
257
    if (flags & DIR_FLAG_LCASE) _strlwr(dta->fname); /* OpenWatcom extension, probably does not care about NLS so results may be odd with non-A-Z characters... */
211
 
258
 
-
 
259
    summary_fcount++;
-
 
260
    if ((dta->attr & DOS_ATTR_DIR) == 0) summary_totsz += dta->size;
-
 
261
 
212
    switch (format) {
262
    switch (format) {
213
      case DIR_OUTPUT_NORM:
263
      case DIR_OUTPUT_NORM:
214
        /* print fname-space-extension (unless it's "." or "..", then print as-is) */
264
        /* print fname-space-extension (unless it's "." or "..", then print as-is) */
215
        if (dta->fname[0] == '.') {
265
        if (dta->fname[0] == '.') {
216
          output(dta->fname);
266
          output(dta->fname);
217
          i = strlen(dta->fname);
267
          i = strlen(dta->fname);
218
          while (i++ < 12) output(" ");
268
          while (i++ < 12) output(" ");
219
        } else {
269
        } else {
220
          file_fname2fcb(buff2, dta->fname);
270
          file_fname2fcb(buff2, dta->fname);
221
          memmove(buff2 + 9, buff2 + 8, 4);
271
          memmove(buff2 + 9, buff2 + 8, 4);
222
          buff2[8] = ' ';
272
          buff2[8] = ' ';
223
          output(buff2);
273
          output(buff2);
224
        }
274
        }
225
        output(" ");
275
        output(" ");
226
        /* either <DIR> or right aligned 10-chars byte size */
276
        /* either <DIR> or right aligned 10-chars byte size */
227
        memset(buff2, ' ', 10);
277
        memset(buff2, ' ', 10);
228
        if (dta->attr & DOS_ATTR_DIR) {
278
        if (dta->attr & DOS_ATTR_DIR) {
229
          strcpy(buff2 + 10, "<DIR>");
279
          strcpy(buff2 + 10, "<DIR>");
230
        } else {
280
        } else {
231
          _ultoa(dta->size, buff2 + 10, 10); /* OpenWatcom extension */
281
          _ultoa(dta->size, buff2 + 10, 10); /* OpenWatcom extension */
232
        }
282
        }
233
        output(buff2 + strlen(buff2) - 10);
283
        output(buff2 + strlen(buff2) - 10);
234
        /* two spaces and NLS DATE */
284
        /* two spaces and NLS DATE */
235
        buff2[0] = ' ';
285
        buff2[0] = ' ';
236
        buff2[1] = ' ';
286
        buff2[1] = ' ';
237
        nls_format_date(buff2 + 2, dta->date_yr + 1980, dta->date_mo, dta->date_dy, nls);
287
        nls_format_date(buff2 + 2, dta->date_yr + 1980, dta->date_mo, dta->date_dy, nls);
238
        output(buff2);
288
        output(buff2);
239
 
289
 
240
        /* one space and NLS TIME */
290
        /* one space and NLS TIME */
241
        nls_format_time(buff2 + 1, dta->time_hour, dta->time_min, nls);
291
        nls_format_time(buff2 + 1, dta->time_hour, dta->time_min, nls);
242
        outputnl(buff2);
292
        outputnl(buff2);
243
        break;
293
        break;
244
 
294
 
245
      case DIR_OUTPUT_WIDE: /* display in columns of 12 chars per item */
295
      case DIR_OUTPUT_WIDE: /* display in columns of 12 chars per item */
246
        i = strlen(dta->fname);
296
        i = strlen(dta->fname);
247
        if (dta->attr & DOS_ATTR_DIR) {
297
        if (dta->attr & DOS_ATTR_DIR) {
248
          i += 2;
298
          i += 2;
249
          output("[");
299
          output("[");
250
          output(dta->fname);
300
          output(dta->fname);
251
          output("]");
301
          output("]");
252
        } else {
302
        } else {
253
          output(dta->fname);
303
          output(dta->fname);
254
        }
304
        }
255
        while (i++ < WCOLWIDTH) output(" ");
305
        while (i++ < WCOLWIDTH) output(" ");
256
        if (++wcolcount == wcols) {
306
        if (++wcolcount == wcols) {
257
          wcolcount = 0;
307
          wcolcount = 0;
258
          outputnl("");
308
          outputnl("");
259
        }
309
        }
260
        break;
310
        break;
261
 
311
 
262
      case DIR_OUTPUT_BARE:
312
      case DIR_OUTPUT_BARE:
263
        outputnl(dta->fname);
313
        outputnl(dta->fname);
264
        break;
314
        break;
265
    }
315
    }
266
 
316
 
267
    if ((flags & DIR_FLAG_PAUSE) && (--availrows < 2)) {
317
    if ((flags & DIR_FLAG_PAUSE) && (--availrows < 2)) {
268
      press_any_key();
318
      press_any_key();
269
      availrows = screen_getheight();
319
      availrows = screen_getheight();
270
    }
320
    }
271
 
321
 
272
  } while (findnext(dta) == 0);
322
  } while (findnext(dta) == 0);
273
 
323
 
-
 
324
  if (wcolcount != 0) outputnl(""); /* in wide mode make sure to end on a clear row */
-
 
325
 
-
 
326
  /* print out summary (unless bare output mode) */
-
 
327
  if (format != DIR_OUTPUT_BARE) {
-
 
328
    unsigned short alignpos;
-
 
329
    /* x file(s) */
-
 
330
    memset(buff2, ' ', 13); /* 13 is the max len of a 32 bit number with thousand separators (4'000'000'000) */
-
 
331
    i = nls_format_number(buff2 + 13, summary_fcount, nls);
-
 
332
    alignpos = sprintf(buff2 + 13 + i, " %s ", "file(s)");
-
 
333
    output(buff2 + i);
-
 
334
    /* xxxx bytes */
-
 
335
    i = nls_format_number(buff2 + 13, summary_totsz, nls);
-
 
336
    output(buff2 + i);
-
 
337
    output(" ");
-
 
338
    outputnl("bytes");
-
 
339
    /* xxxx bytes free */
-
 
340
    printf("totsz = %lu\r\n", summary_totsz);
-
 
341
    i = cmd_dir_df(&summary_totsz, drv);
274
  if (wcolcount != 0) outputnl("");
342
    if (i != 0) outputnl(doserr(i));
-
 
343
    alignpos += 13 + 13;
-
 
344
    memset(buff2, ' ', alignpos); /* align the freebytes value to same column as totbytes */
-
 
345
    i = nls_format_number(buff2 + alignpos, summary_totsz, nls);
-
 
346
    output(buff2 + i);
-
 
347
    output(" ");
-
 
348
    outputnl("bytes free");
-
 
349
  }
275
 
350
 
276
  return(-1);
351
  return(-1);
277
}
352
}
278
 
353