home *** CD-ROM | disk | FTP | other *** search
- /*
- * Display an MSDOS directory
- *
- * Emmet P. Gray US Army, HQ III Corps & Fort Hood
- * ...!uunet!uiucuxc!fthood!egray Attn: AFZF-DE-ENV
- * fthood!egray@uxc.cso.uiuc.edu Directorate of Engineering & Housing
- * Environmental Management Office
- * Fort Hood, TX 76544-5057
- */
-
- #include <stdio.h>
- #include "msdos.h"
- #include "patchlevel.h"
-
- int fd = -1; /* the file descriptor for the device */
- int dir_start; /* starting sector for directory */
- int dir_len; /* length of directory (in sectors) */
- int dir_entries; /* number of directory entries */
- int clus_size; /* cluster size (in sectors) */
- char *mcwd; /* the Current Working Directory */
- int fat_error; /* FAT error detected? */
-
- static long getfree();
- static char *conv_date(), *conv_time();
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- int i, entry, files, fargn, wide, faked;
- long size, blocks;
- char *date, *time, last_drive, *fix_mcwd();
- char *strncpy(), newpath[MAX_PATH], *get_name(), *get_path(), *pathname;
- char *newfile, *filename, *unix_name(), volume[12], drive, *strpbrk();
- char *strcpy(), *strcat(), newname[13], *strncat(), get_drive();
- void exit();
- struct directory *dir, *dir_read();
-
- fargn = 1;
- wide = 0;
- files = 0;
- /* first argument */
- if (argc > 1) {
- if (!strcmp(argv[1], "-w")) {
- wide = 1;
- fargn = 2;
- }
- if (argv[1][0] == '-' && !wide) {
- fprintf(stderr, "%s: illegal option -- %c\n", argv[0], argv[1][1]);
- fprintf(stderr, "Mtools version %s, dated %s\n", VERSION, DATE);
- fprintf(stderr, "Usage: %s: [-w] msdosdirectory\n", argv[0]);
- fprintf(stderr, " %s: [-w] msdosfile [msdosfiles...]\n", argv[0]);
- exit(1);
- }
- }
- /* fake an argument */
- faked = 0;
- if (argc == fargn) {
- faked++;
- argc++;
- }
- last_drive = 'x';
- mcwd = fix_mcwd();
-
- for (i = fargn; i < argc; i++) {
- if (faked) {
- drive = get_drive("");
- filename = get_name("");
- pathname = get_path("");
- }
- else {
- drive = get_drive(argv[i]);
- filename = get_name(argv[i]);
- pathname = get_path(argv[i]);
- }
- /* is this a new device? */
- if (drive != last_drive) {
- if (last_drive != 'x') {
- blocks = getfree() * MSECTOR_SIZE;
- if (!files)
- printf("File \"%s\" not found\n\n", newname);
- else
- printf(" %3d File(s) %6ld bytes free\n\n", files, blocks);
- }
- if (init(drive, 0)) {
- fprintf(stderr, "%s: Cannot initialize '%c:'\n", argv[0], drive);
- continue;
- }
- last_drive = drive;
- files = 0;
- /* find the volume label */
- volume[0] = '\0';
- for (entry = 0; entry < dir_entries; entry++) {
- dir = dir_read(entry);
-
- /* if empty */
- if (dir->name[0] == 0x0)
- break;
-
- /* if erased */
- if (dir->name[0] == 0xe5)
- continue;
-
- /* if not volume label */
- if (!(dir->attr & 0x08))
- continue;
-
- strncpy(volume, (char *) dir->name, 8);
- volume[8] = '\0';
- strncat(volume, (char *) dir->ext, 3);
- volume[11] = '\0';
- break;
- }
- if (volume[0] == '\0')
- printf(" Volume in drive %c has no label\n", drive);
- else
- printf(" Volume in drive %c is %s\n", drive, volume);
- }
-
- /*
- * Move to "first guess" subdirectory, so that is_dir() can
- * search to see if filename is also a directory.
- */
- if (subdir(drive, pathname))
- continue;
-
- /*
- * Under MSDOS, wildcards that match directories don't
- * display the contents of that directory. So I guess I'll
- * do that too.
- */
- if ((strpbrk(filename, "*[?") == NULL) && is_dir(filename)) {
- strcpy(newpath, pathname);
- if (newpath[strlen(newpath) -1] != '/')
- strcat(newpath, "/");
- strcat(newpath, filename);
-
- /* move to real subdirectory */
- if (subdir(drive, newpath))
- continue;
-
- strcpy(newname, "*");
- }
- else {
- strcpy(newpath, pathname);
- strcpy(newname, filename);
- }
- /* if no files, assume '*' */
- if (*filename == '\0')
- strcpy(newname, "*");
-
- printf(" Directory for %c:%s\n\n", drive, newpath);
-
- for (entry = 0; entry < dir_entries; entry++) {
- dir = dir_read(entry);
- /* if empty */
- if (dir->name[0] == 0x0)
- break;
- /* if erased */
- if (dir->name[0] == 0xe5)
- continue;
- /* if a volume label */
- if (dir->attr & 0x08)
- continue;
-
- newfile = unix_name(dir->name, dir->ext);
- if (!match(newfile, newname))
- continue;
-
- files++;
- if (wide && files != 1) {
- if (!((files - 1) % 5))
- putchar('\n');
- }
- date = conv_date(dir->date[1], dir->date[0]);
- time = conv_time(dir->time[1], dir->time[0]);
- size = dir->size[3] * 0x1000000L + dir->size[2] * 0x10000L + dir->size[1] * 0x100 + dir->size[0];
- /* is a subdirectory */
- if (dir->attr & 0x10) {
- if (wide)
- printf("%-8.8s %-3.3s ", dir->name, dir->ext);
- else
- printf("%-8.8s %-3.3s <DIR> %s %s\n", dir->name, dir->ext, date, time);
- continue;
- }
- if (wide)
- printf("%-8.8s %-3.3s ", dir->name, dir->ext);
- else
- printf("%-8.8s %-3.3s %8ld %s %s\n", dir->name, dir->ext, size, date, time);
- }
- if (argc > 2)
- putchar('\n');
- }
- if (fd < 0)
- exit(1);
-
- blocks = getfree() * MSECTOR_SIZE;
- if (!files)
- printf("File \"%s\" not found\n", newname);
- else
- printf(" %3d File(s) %6ld bytes free\n", files, blocks);
- close(fd);
- exit(0);
- }
-
- /*
- * Get the amount of free space on the diskette
- */
-
- static long
- getfree()
- {
- register unsigned int i;
- long total;
- extern unsigned int num_clus;
- unsigned int fat_decode();
-
- total = 0L;
- for (i = 2; i < num_clus + 2; i++) {
- /* if fat_decode returns zero */
- if (!fat_decode(i))
- total += clus_size;
- }
- return(total);
- }
-
- /*
- * Convert an MSDOS directory date stamp to ASCII
- */
-
- static char *
- conv_date(date_high, date_low)
- unsigned date_high, date_low;
- {
- /*
- * hi byte | low byte
- * |7|6|5|4|3|2|1|0|7|6|5|4|3|2|1|0|
- * | | | | | | | | | | | | | | | | |
- * \ 7 bits /\4 bits/\ 5 bits /
- * year +80 month day
- */
- static char ans[9];
- unsigned char year, month_hi, month_low, day;
-
- year = (date_high >> 1) + 80;
- month_hi = (date_high & 0x1) << 3;
- month_low = date_low >> 5;
- day = date_low & 0x1f;
- sprintf(ans, "%2d-%02d-%02d", month_hi + month_low, day, year);
- return(ans);
- }
-
- /*
- * Convert an MSDOS directory time stamp to ASCII.
- */
-
- static char *
- conv_time(time_high, time_low)
- unsigned time_high, time_low;
- {
- /*
- * hi byte | low byte
- * |7|6|5|4|3|2|1|0|7|6|5|4|3|2|1|0|
- * | | | | | | | | | | | | | | | | |
- * \ 5 bits /\ 6 bits /\ 5 bits /
- * hour minutes sec*2
- */
- static char ans[7];
- char am_pm;
- unsigned char hour, min_hi, min_low;
-
- hour = time_high >> 3;
- am_pm = (hour >= 12) ? 'p' : 'a';
- if (hour > 12)
- hour = hour - 12;
- if (hour == 0)
- hour = 12;
- min_hi = (time_high & 0x7) << 3;
- min_low = time_low >> 5;
- sprintf(ans, "%2d:%02d%c", hour, min_hi + min_low, am_pm);
- return(ans);
- }
-
- /*
- * stubs for read-only programs
- */
-
- void
- disk_flush()
- {
- extern int disk_dirty;
-
- disk_dirty = 0;
- return;
- }
-
- void
- dir_flush()
- {
- extern int dir_dirty;
-
- dir_dirty = 0;
- return;
- }
-