1: /*
   2:  * Display an MSDOS directory
   3:  *
   4:  * Emmet P. Gray			US Army, HQ III Corps & Fort Hood
   5:  * ...!uunet!uiucuxc!fthood!egray	Attn: AFZF-DE-ENV
   6:  * fthood!egray@uxc.cso.uiuc.edu	Directorate of Engineering & Housing
   7:  * 					Environmental Management Office
   8:  * 					Fort Hood, TX 76544-5057
   9:  */
  10: 
  11: #include <stdio.h>
  12: #include "msdos.h"
  13: #include "patchlevel.h"
  14: 
  15: int fd = -1;                /* the file descriptor for the device */
  16: int dir_start;              /* starting sector for directory */
  17: int dir_len;                /* length of directory (in sectors) */
  18: int dir_entries;            /* number of directory entries */
  19: int clus_size;              /* cluster size (in sectors) */
  20: char *mcwd;             /* the Current Working Directory */
  21: int fat_error;              /* FAT error detected? */
  22: 
  23: static long getfree();
  24: static char *conv_date(), *conv_time();
  25: 
  26: main(argc, argv)
  27: int argc;
  28: char *argv[];
  29: {
  30:     int i, entry, files, fargn, wide, faked;
  31:     long size, blocks;
  32:     char *date, *time, last_drive, *fix_mcwd();
  33:     char *strncpy(), newpath[MAX_PATH], *get_name(), *get_path(), *pathname;
  34:     char *newfile, *filename, *unix_name(), volume[12], drive, *strpbrk();
  35:     char *strcpy(), *strcat(), newname[13], *strncat(), get_drive();
  36:     void exit();
  37:     struct directory *dir, *dir_read();
  38: 
  39:     fargn = 1;
  40:     wide = 0;
  41:     files = 0;
  42:                     /* first argument */
  43:     if (argc > 1) {
  44:         if (!strcmp(argv[1], "-w")) {
  45:             wide = 1;
  46:             fargn = 2;
  47:         }
  48:         if (argv[1][0] == '-' && !wide) {
  49:             fprintf(stderr, "%s: illegal option -- %c\n", argv[0], argv[1][1]);
  50:             fprintf(stderr, "Mtools version %s, dated %s\n", VERSION, DATE);
  51:             fprintf(stderr, "Usage: %s: [-w] msdosdirectory\n", argv[0]);
  52:             fprintf(stderr, "       %s: [-w] msdosfile [msdosfiles...]\n", argv[0]);
  53:             exit(1);
  54:         }
  55:     }
  56:                     /* fake an argument */
  57:     faked = 0;
  58:     if (argc == fargn) {
  59:         faked++;
  60:         argc++;
  61:     }
  62:     last_drive = 'x';
  63:     mcwd = fix_mcwd();
  64: 
  65:     for (i = fargn; i < argc; i++) {
  66:         if (faked) {
  67:             drive = get_drive("");
  68:             filename = get_name("");
  69:             pathname = get_path("");
  70:         }
  71:         else {
  72:             drive = get_drive(argv[i]);
  73:             filename = get_name(argv[i]);
  74:             pathname = get_path(argv[i]);
  75:         }
  76:                     /* is this a new device? */
  77:         if (drive != last_drive) {
  78:             if (last_drive != 'x') {
  79:                 blocks = getfree() * MSECTOR_SIZE;
  80:                 if (!files)
  81:                     printf("File \"%s\" not found\n\n", newname);
  82:                 else
  83:                     printf("     %3d File(s)     %6ld bytes free\n\n", files, blocks);
  84:             }
  85:             if (init(drive, 0)) {
  86:                 fprintf(stderr, "%s: Cannot initialize '%c:'\n", argv[0], drive);
  87:                 continue;
  88:             }
  89:             last_drive = drive;
  90:             files = 0;
  91:                     /* find the volume label */
  92:             volume[0] = '\0';
  93:             for (entry = 0; entry < dir_entries; entry++) {
  94:                 dir = dir_read(entry);
  95: 
  96:                     /* if empty */
  97:                 if (dir->name[0] == 0x0)
  98:                     break;
  99: 
 100:                     /* if erased */
 101:                 if (dir->name[0] == 0xe5)
 102:                     continue;
 103: 
 104:                     /* if not volume label */
 105:                 if (!(dir->attr & 0x08))
 106:                     continue;
 107: 
 108:                 strncpy(volume, (char *) dir->name, 8);
 109:                 volume[8] = '\0';
 110:                 strncat(volume, (char *) dir->ext, 3);
 111:                 volume[11] = '\0';
 112:                 break;
 113:             }
 114:             if (volume[0] == '\0')
 115:                 printf(" Volume in drive %c has no label\n", drive);
 116:             else
 117:                 printf(" Volume in drive %c is %s\n", drive, volume);
 118:         }
 119: 
 120:         /*
 121: 		 * Move to "first guess" subdirectory, so that is_dir() can
 122: 		 * search to see if filename is also a directory.
 123: 		 */
 124:         if (subdir(drive, pathname))
 125:             continue;
 126: 
 127:         /*
 128: 		 * Under MSDOS, wildcards that match directories don't
 129: 		 * display the contents of that directory.  So I guess I'll
 130: 		 * do that too.
 131: 		 */
 132:         if ((strpbrk(filename, "*[?") == NULL) && is_dir(filename)) {
 133:             strcpy(newpath, pathname);
 134:             if (newpath[strlen(newpath) -1] != '/')
 135:                 strcat(newpath, "/");
 136:             strcat(newpath, filename);
 137: 
 138:                     /* move to real subdirectory */
 139:             if (subdir(drive, newpath))
 140:                 continue;
 141: 
 142:             strcpy(newname, "*");
 143:         }
 144:         else {
 145:             strcpy(newpath, pathname);
 146:             strcpy(newname, filename);
 147:         }
 148:                     /* if no files, assume '*' */
 149:         if (*filename == '\0')
 150:             strcpy(newname, "*");
 151: 
 152:         printf(" Directory for %c:%s\n\n", drive, newpath);
 153: 
 154:         for (entry = 0; entry < dir_entries; entry++) {
 155:             dir = dir_read(entry);
 156:                     /* if empty */
 157:             if (dir->name[0] == 0x0)
 158:                 break;
 159:                     /* if erased */
 160:             if (dir->name[0] == 0xe5)
 161:                 continue;
 162:                     /* if a volume label */
 163:             if (dir->attr & 0x08)
 164:                 continue;
 165: 
 166:             newfile = unix_name(dir->name, dir->ext);
 167:             if (!match(newfile, newname))
 168:                 continue;
 169: 
 170:             files++;
 171:             if (wide && files != 1) {
 172:                 if (!((files - 1) % 5))
 173:                     putchar('\n');
 174:             }
 175:             date = conv_date(dir->date[1], dir->date[0]);
 176:             time = conv_time(dir->time[1], dir->time[0]);
 177:             size = dir->size[3] * 0x1000000L + dir->size[2] * 0x10000L + dir->size[1] * 0x100 + dir->size[0];
 178:                     /* is a subdirectory */
 179:             if (dir->attr & 0x10) {
 180:                 if (wide)
 181:                     printf("%-8.8s %-3.3s   ", dir->name, dir->ext);
 182:                 else
 183:                     printf("%-8.8s %-3.3s     <DIR>     %s  %s\n", dir->name, dir->ext, date, time);
 184:                 continue;
 185:             }
 186:             if (wide)
 187:                 printf("%-8.8s %-3.3s   ", dir->name, dir->ext);
 188:             else
 189:                 printf("%-8.8s %-3.3s    %8ld   %s  %s\n", dir->name, dir->ext, size, date, time);
 190:         }
 191:         if (argc > 2)
 192:             putchar('\n');
 193:     }
 194:     if (fd < 0)
 195:         exit(1);
 196: 
 197:     blocks = getfree() * MSECTOR_SIZE;
 198:     if (!files)
 199:         printf("File \"%s\" not found\n", newname);
 200:     else
 201:         printf("     %3d File(s)     %6ld bytes free\n", files, blocks);
 202:     close(fd);
 203:     exit(0);
 204: }
 205: 
 206: /*
 207:  * Get the amount of free space on the diskette
 208:  */
 209: 
 210: static long
 211: getfree()
 212: {
 213:     register unsigned int i;
 214:     long total;
 215:     extern unsigned int num_clus;
 216:     unsigned int fat_decode();
 217: 
 218:     total = 0L;
 219:     for (i = 2; i < num_clus + 2; i++) {
 220:                     /* if fat_decode returns zero */
 221:         if (!fat_decode(i))
 222:             total += clus_size;
 223:     }
 224:     return(total);
 225: }
 226: 
 227: /*
 228:  * Convert an MSDOS directory date stamp to ASCII
 229:  */
 230: 
 231: static char *
 232: conv_date(date_high, date_low)
 233: unsigned date_high, date_low;
 234: {
 235: /*
 236:  *	    hi byte     |    low byte
 237:  *	|7|6|5|4|3|2|1|0|7|6|5|4|3|2|1|0|
 238:  *      | | | | | | | | | | | | | | | | |
 239:  *      \   7 bits    /\4 bits/\ 5 bits /
 240:  *         year +80      month     day
 241:  */
 242:     static char ans[9];
 243:     unsigned char year, month_hi, month_low, day;
 244: 
 245:     year = (date_high >> 1) + 80;
 246:     month_hi = (date_high & 0x1) << 3;
 247:     month_low = date_low >> 5;
 248:     day = date_low & 0x1f;
 249:     sprintf(ans, "%2d-%02d-%02d", month_hi + month_low, day, year);
 250:     return(ans);
 251: }
 252: 
 253: /*
 254:  * Convert an MSDOS directory time stamp to ASCII.
 255:  */
 256: 
 257: static char *
 258: conv_time(time_high, time_low)
 259: unsigned time_high, time_low;
 260: {
 261: /*
 262:  *	    hi byte     |    low byte
 263:  *	|7|6|5|4|3|2|1|0|7|6|5|4|3|2|1|0|
 264:  *      | | | | | | | | | | | | | | | | |
 265:  *      \  5 bits /\  6 bits  /\ 5 bits /
 266:  *         hour      minutes     sec*2
 267:  */
 268:     static char ans[7];
 269:     char am_pm;
 270:     unsigned char hour, min_hi, min_low;
 271: 
 272:     hour = time_high >> 3;
 273:     am_pm = (hour >= 12) ? 'p' : 'a';
 274:     if (hour > 12)
 275:         hour = hour - 12;
 276:     if (hour == 0)
 277:         hour = 12;
 278:     min_hi = (time_high & 0x7) << 3;
 279:     min_low = time_low >> 5;
 280:     sprintf(ans, "%2d:%02d%c", hour, min_hi + min_low, am_pm);
 281:     return(ans);
 282: }
 283: 
 284: /*
 285:  * stubs for read-only programs
 286:  */
 287: 
 288: void
 289: disk_flush()
 290: {
 291:     extern int disk_dirty;
 292: 
 293:     disk_dirty = 0;
 294:     return;
 295: }
 296: 
 297: void
 298: dir_flush()
 299: {
 300:     extern int dir_dirty;
 301: 
 302:     dir_dirty = 0;
 303:     return;
 304: }

Defined functions

conv_date defined in line 231; used 2 times
conv_time defined in line 257; used 2 times
dir_flush defined in line 297; never used
disk_flush defined in line 288; never used
getfree defined in line 210; used 3 times
main defined in line 26; never used

Defined variables

clus_size defined in line 19; used 1 times
dir_entries defined in line 18; used 2 times
dir_len defined in line 17; never used
dir_start defined in line 16; never used
fat_error defined in line 21; never used
fd defined in line 15; used 2 times
mcwd defined in line 20; used 1 times
  • in line 63
Last modified: 1992-06-24
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2527
Valid CSS Valid XHTML 1.0 Strict