1: /*
   2:  * Make an MSDOS subdirectory
   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 <signal.h>
  13: #include "msdos.h"
  14: #include "patchlevel.h"
  15: 
  16: int fd = -1;                /* the file descriptor for the device */
  17: int dir_start;              /* starting sector for directory */
  18: int dir_len;                /* length of directory (in sectors) */
  19: int dir_entries;            /* number of directory entries */
  20: int clus_size;              /* cluster size (in sectors) */
  21: char *mcwd;             /* the Current Working Directory */
  22: int fat_error;              /* FAT error detected? */
  23: 
  24: static int got_signal();
  25: static void empty_dir();
  26: 
  27: main(argc, argv)
  28: int argc;
  29: char *argv[];
  30: {
  31:     int i, entry, slot, fargn, verbose, oops;
  32:     extern unsigned int end_fat;
  33:     unsigned int fat, dot, next_fat();
  34:     char filename[13], *newfile, drive, get_drive(), *get_path();
  35:     char *strcpy(), *fix_mcwd(), *pathname, *unix_name(), last_drive;
  36:     unsigned char *fixed, *dos_name();
  37:     void exit(), fat_write(), dir_write(), disk_flush(), dir_flush();
  38:     struct directory *dir, *dir_read(), *mk_entry();
  39:     long time(), now;
  40:                     /* catch signals */
  41:     signal(SIGINT, (SIG_TYPE(*) ()) got_signal);
  42:     signal(SIGTERM, (SIG_TYPE(*) ()) got_signal);
  43:     signal(SIGQUIT, (SIG_TYPE(*) ()) got_signal);
  44: 
  45:     fargn = 1;
  46:     verbose = 0;
  47:     oops = 0;
  48:     if (argc > 1) {
  49:         if (!strcmp(argv[1], "-v")) {
  50:             fargn = 2;
  51:             verbose = 1;
  52:         }
  53:         if (argv[1][0] == '-' && !verbose)
  54:             oops++;
  55:     }
  56:     if (argc == 1 || oops) {
  57:         fprintf(stderr, "Mtools version %s, dated %s\n", VERSION, DATE);
  58:         fprintf(stderr, "Usage: %s [-v] msdosdirectory [msdosdirectories...]\n", argv[0]);
  59:         exit(1);
  60:     }
  61:     last_drive = 'x';
  62:     mcwd = fix_mcwd();
  63: 
  64:     for (i = fargn; i < argc; i++) {
  65:         drive = get_drive(argv[i]);
  66:         if (drive != last_drive) {
  67:             if (last_drive != 'x') {
  68:                 fat_write();
  69:                 dir_flush();
  70:                 disk_flush();
  71:             }
  72: 
  73:             if (init(drive, 2)) {
  74:                 fprintf(stderr, "%s: Cannot initialize '%c:'\n", argv[0], drive);
  75:                 continue;
  76:             }
  77:             last_drive = drive;
  78:         }
  79:                     /* serves the get_name() function too */
  80:         fixed = dos_name(argv[i], verbose);
  81: 
  82:         strcpy(filename, unix_name(fixed, fixed + 8));
  83:         pathname = get_path(argv[i]);
  84: 
  85:         if (subdir(drive, pathname))
  86:             continue;
  87:                     /* see if exists and get slot */
  88:         slot = -1;
  89:         dot = 0;
  90:         oops = 0;
  91:         for (entry = 0; entry < dir_entries; entry++) {
  92:             dir = dir_read(entry);
  93: 
  94:                     /* if empty */
  95:             if (dir->name[0] == 0x0) {
  96:                 if (slot < 0)
  97:                     slot = entry;
  98:                 break;
  99:             }
 100:                     /* if erased */
 101:             if (dir->name[0] == 0xe5) {
 102:                 if (slot < 0)
 103:                     slot = entry;
 104:                 continue;
 105:             }
 106:                     /* if not a directory */
 107:             if (!(dir->attr & 0x10))
 108:                 continue;
 109: 
 110:             newfile = unix_name(dir->name, dir->ext);
 111:                     /* save the 'dot' directory info */
 112:             if (!strcmp(".", newfile))
 113:                 dot = dir->start[1] * 0x100 + dir->start[0];
 114: 
 115:             if (!strcmp(filename, newfile)) {
 116:                 fprintf(stderr, "%s: Directory \"%s\" already exists\n", argv[0], filename);
 117:                 oops++;
 118:                 break;
 119:             }
 120:         }
 121:         if (oops)
 122:             continue;
 123:                     /* no '.' entry means root directory */
 124:         if (dot == 0 && slot < 0) {
 125:             fprintf(stderr, "%s: No directory slots\n", argv[0]);
 126:             continue;
 127:         }
 128:                     /* make the directory grow */
 129:         if (dot && slot < 0) {
 130:             if (dir_grow(dot)) {
 131:                 fprintf(stderr, "%s: Disk full\n", argv[0]);
 132:                 continue;
 133:             }
 134:                     /* first slot in the new part */
 135:             slot = entry;
 136:         }
 137:                     /* grab a starting cluster */
 138:         if ((fat = next_fat(0)) == 1) {
 139:             fprintf(stderr, "%s: Disk full\n", argv[0]);
 140:             continue;
 141:         }
 142:                     /* make directory entry */
 143:         time(&now);
 144:         dir = mk_entry(fixed, 0x10, fat, 0L, now);
 145:         dir_write(slot, dir);
 146:                     /* write the cluster */
 147:         empty_dir(fat, dot);
 148:         fat_encode(fat, end_fat);
 149:     }
 150:                     /* write the FAT, flush the buffers */
 151:     fat_write();
 152:     dir_flush();
 153:     disk_flush();
 154:     close(fd);
 155:     exit(0);
 156: }
 157: 
 158: /*
 159:  * Write an empty directory 'template' to the cluster starting at 'dot'.
 160:  */
 161: 
 162: static void
 163: empty_dir(dot, dot_dot)
 164: unsigned int dot, dot_dot;
 165: {
 166:     int buflen;
 167:     long start;
 168:     char buf[MAX_CLUSTER], *memcpy(), *memset();
 169:     struct directory *dir, *mk_entry();
 170:     void disk_write();
 171:     long time(), now;
 172: 
 173:     start = (long) (dot - 2) * clus_size + dir_start + dir_len;
 174: 
 175:     buflen = clus_size * MSECTOR_SIZE;
 176:     time(&now);
 177:                     /* make the '.' and '..' entries */
 178:     dir = mk_entry((unsigned char *) ".          ", 0x10, dot, 0L, now);
 179:     memcpy(&buf[0], (char *) dir, MDIR_SIZE);
 180:     dir = mk_entry((unsigned char *) "..         ", 0x10, dot_dot, 0L, now);
 181:     memcpy(&buf[MDIR_SIZE], (char *) dir, MDIR_SIZE);
 182: 
 183:                     /* zero the remainder */
 184:     memset(&buf[2 * MDIR_SIZE], '\0', buflen - (2 * MDIR_SIZE));
 185: 
 186:                     /* write the cluster */
 187:     disk_write(start, (unsigned char *) buf, buflen);
 188:     return;
 189: }
 190: 
 191: /*
 192:  * Do a graceful exit if the program is interrupted.  This will reduce
 193:  * (but not eliminate) the risk of generating a corrupted disk on
 194:  * a user abort.
 195:  */
 196: 
 197: static int
 198: got_signal()
 199: {
 200:     void exit(), disk_flush(), fat_write(), dir_flush();
 201: 
 202:     if (fd < 0)
 203:         exit(1);
 204:     fat_write();
 205:     dir_flush();
 206:     disk_flush();
 207:     close(fd);
 208:     exit(1);
 209: }

Defined functions

empty_dir defined in line 162; used 2 times
got_signal defined in line 197; used 4 times
main defined in line 27; never used

Defined variables

fd defined in line 16; used 35 times
mcwd defined in line 21; used 4 times
Last modified: 1992-06-24
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2691
Valid CSS Valid XHTML 1.0 Strict