1: /*
   2:  * Add an MSDOS filesystem to a low level formatted diskette.
   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 <ctype.h>
  13: #include "msdos.h"
  14: #include "patchlevel.h"
  15: 
  16: int fd, dir_dirty, dir_entries;
  17: long dir_chain[MAX_DIR_SECS];
  18: unsigned char *dir_buf;
  19: 
  20: main(argc, argv)
  21: int argc;
  22: char *argv[];
  23: {
  24:     extern int optind;
  25:     extern char *optarg;
  26:     extern struct device devices[];
  27:     struct bootsector boot;
  28:     int i, c, oops, tracks, heads, sectors, fat_len, dir_len, clus_size;
  29:     int tot_sectors, num_clus, fat_guess;
  30:     long time(), now, lseek();
  31:     char drive, *name, *expand();
  32:     char *strncpy(), *memset(), *memcpy();
  33:     unsigned char media, label[12], buf[MSECTOR_SIZE];
  34:     struct device *dev;
  35:     struct directory *dir, *mk_entry();
  36:     void exit(), perror();
  37: 
  38:     oops = 0;
  39:     tracks = 0;
  40:     heads = 0;
  41:     sectors = 0;
  42:     label[0] = '\0';
  43:                     /* get command line options */
  44:     while ((c = getopt(argc, argv, "t:h:s:l:")) != EOF) {
  45:         switch (c) {
  46:             case 't':
  47:                 tracks = atoi(optarg);
  48:                 break;
  49:             case 'h':
  50:                 heads = atoi(optarg);
  51:                 break;
  52:             case 's':
  53:                 sectors = atoi(optarg);
  54:                 break;
  55:             case 'l':
  56:                 sprintf((char *) label, "%-11.11s", optarg);
  57:                 break;
  58:             default:
  59:                 oops = 1;
  60:                 break;
  61:         }
  62:     }
  63: 
  64:     if (oops || (argc - optind) != 1) {
  65:         fprintf(stderr, "Mtools version %s, dated %s\n", VERSION, DATE);
  66:         fprintf(stderr, "Usage: %s [-t tracks] [-h heads] [-s sectors] [-l label] device\n", argv[0]);
  67:         exit(1);
  68:     }
  69: 
  70:     drive = argv[argc -1][0];
  71:     if (islower(drive))
  72:         drive = toupper(drive);
  73: 
  74:                     /* check out the drive letter */
  75:     dev = devices;
  76:     while (dev->drive) {
  77:         if (dev->drive == drive)
  78:             break;
  79:         dev++;
  80:     }
  81:     if (!dev->drive) {
  82:         fprintf(stderr, "Drive '%c:' not supported\n", drive);
  83:         exit(1);
  84:     }
  85:     if (dev->tracks == 0) {
  86:         fprintf(stderr, "Non-removable media is not supported\n");
  87:         exit(1);
  88:     }
  89:                     /* find the right one */
  90:     if (!dev->gioctl) {
  91:         while (dev->drive == drive) {
  92:             if ((!tracks || dev->tracks == tracks) && (!heads || dev->heads == heads) && (!sectors || dev->sectors == sectors))
  93:                 break;
  94:             dev++;
  95:         }
  96:     }
  97:     if (dev->drive != drive) {
  98:         fprintf(stderr, "%s: Paramaters not supported\n", argv[0]);
  99:         exit(1);
 100:     }
 101:                     /* open the device */
 102:     name = expand(dev->name);
 103:     if ((fd = open(name, 2 | dev->mode)) < 0) {
 104:         perror("init: open");
 105:         exit(1);
 106:     }
 107:                     /* fill in the blanks */
 108:     if (!tracks)
 109:         tracks = dev->tracks;
 110:     if (!heads)
 111:         heads = dev->heads;
 112:     if (!sectors)
 113:         sectors = dev->sectors;
 114: 
 115:                     /* set parameters, if needed */
 116:     if (dev->gioctl) {
 117:         if ((*(dev->gioctl)) (fd, tracks, heads, sectors))
 118:             exit(1);
 119:     }
 120:                     /* do a "test" read */
 121:     if (read(fd, (char *) buf, MSECTOR_SIZE) != MSECTOR_SIZE) {
 122:         fprintf(stderr, "%s: Error reading from '%s', wrong parameters?\n", argv[0], name);
 123:         exit(1);
 124:     }
 125:                     /* get the parameters */
 126:     tot_sectors = tracks * heads * sectors;
 127:     switch (tot_sectors) {
 128:         case 320:       /* 40t * 1h * 8s = 160k */
 129:             media = 0xfe;
 130:             clus_size = 1;
 131:             dir_len = 4;
 132:             fat_len = 1;
 133:             break;
 134:         case 360:       /* 40t * 1h * 9s = 180k */
 135:             media = 0xfc;
 136:             clus_size = 1;
 137:             dir_len = 4;
 138:             fat_len = 2;
 139:             break;
 140:         case 640:       /* 40t * 2h * 8s = 320k */
 141:             media = 0xff;
 142:             clus_size = 2;
 143:             dir_len = 7;
 144:             fat_len = 1;
 145:             break;
 146:         case 720:       /* 40t * 2h * 9s = 360k */
 147:             media = 0xfd;
 148:             clus_size = 2;
 149:             dir_len = 7;
 150:             fat_len = 2;
 151:             break;
 152:         case 1440:      /* 80t * 2h * 9s = 720k */
 153:             media = 0xf9;
 154:             clus_size = 2;
 155:             dir_len = 7;
 156:             fat_len = 3;
 157:             break;
 158:         case 2400:      /* 80t * 2h * 15s = 1.2m */
 159:             media = 0xf9;
 160:             clus_size = 1;
 161:             dir_len = 14;
 162:             fat_len = 7;
 163:             break;
 164:         case 2880:      /* 80t * 2h * 18s = 1.44m */
 165:             media = 0xf0;
 166:             clus_size = 1;
 167:             dir_len = 14;
 168:             fat_len = 9;
 169:             break;
 170:         default:        /* a non-standard format */
 171:             media = 0xf0;
 172:             if (heads == 1)
 173:                 clus_size = 1;
 174:             else
 175:                 clus_size = (tot_sectors > 2000) ? 1 : 2;
 176:             if (heads == 1)
 177:                 dir_len = 4;
 178:             else
 179:                 dir_len = (tot_sectors > 2000) ? 14 : 7;
 180:             /*
 181: 			 * Estimate the fat length, then figure it out.  The
 182: 			 * 341 is the number of 12 bit fat entries in a sector.
 183: 			 */
 184:             fat_guess = ((tot_sectors / clus_size) / 341.0) + 0.95;
 185:             num_clus = (tot_sectors -dir_len - (2 * fat_guess) -1) / clus_size;
 186:             fat_len = (num_clus / 341.0) + 1;
 187:             break;
 188:     }
 189:                     /* the boot sector */
 190:     memset((char *) &boot, '\0', MSECTOR_SIZE);
 191:     boot.jump[0] = 0xeb;
 192:     boot.jump[1] = 0x44;
 193:     boot.jump[2] = 0x90;
 194:     strncpy((char *) boot.banner, "Mtools  ", 8);
 195:     boot.secsiz[0] = 512 % 0x100;
 196:     boot.secsiz[1] = 512 / 0x100;
 197:     boot.clsiz = (unsigned char) clus_size;
 198:     boot.nrsvsect[0] = 1;
 199:     boot.nrsvsect[1] = 0;
 200:     boot.nfat = 2;
 201:     boot.dirents[0] = (dir_len * 16) % 0x100;
 202:     boot.dirents[1] = (dir_len * 16) / 0x100;
 203:     boot.psect[0] = tot_sectors % 0x100;
 204:     boot.psect[1] = tot_sectors / 0x100;
 205:     boot.descr = media;
 206:     boot.fatlen[0] = fat_len % 0x100;
 207:     boot.fatlen[1] = fat_len / 0x100;
 208:     boot.nsect[0] = sectors % 0x100;
 209:     boot.nsect[1] = sectors / 0x100;
 210:     boot.nheads[0] = heads % 0x100;
 211:     boot.nheads[1] = heads / 0x100;
 212: 
 213:                     /* write the boot */
 214:     lseek(fd, 0L, 0);
 215:     write(fd, (char *) &boot, MSECTOR_SIZE);
 216:                     /* first fat */
 217:     memset((char *) buf, '\0', MSECTOR_SIZE);
 218:     buf[0] = media;
 219:     buf[1] = 0xff;
 220:     buf[2] = 0xff;
 221:     write(fd, (char *) buf, MSECTOR_SIZE);
 222:     memset((char *) buf, '\0', MSECTOR_SIZE);
 223:     for (i = 1; i < fat_len; i++)
 224:         write(fd, (char *) buf, MSECTOR_SIZE);
 225:                     /* second fat */
 226:     buf[0] = media;
 227:     buf[1] = 0xff;
 228:     buf[2] = 0xff;
 229:     write(fd, (char *) buf, MSECTOR_SIZE);
 230:     memset((char *) buf, '\0', MSECTOR_SIZE);
 231:     for (i = 1; i < fat_len; i++)
 232:         write(fd, (char *) buf, MSECTOR_SIZE);
 233:                     /* the root directory */
 234:     if (label[0] != '\0') {
 235:         time(&now);
 236:         dir = mk_entry(label, 0x08, 0, 0L, now);
 237:         memcpy((char *) buf, (char *) dir, MDIR_SIZE);
 238:     }
 239:     write(fd, (char *) buf, MSECTOR_SIZE);
 240:     memset((char *) buf, '\0', MSECTOR_SIZE);
 241:     for (i = 1; i < dir_len; i++)
 242:         write(fd, (char *) buf, MSECTOR_SIZE);
 243:     close(fd);
 244:     exit(0);
 245: }
 246: 
 247: /* hooks for the missing parts */
 248: void disk_write() {}

Defined functions

main defined in line 20; never used

Defined variables

dir_buf defined in line 18; never used
dir_chain defined in line 17; never used
dir_dirty defined in line 16; never used
dir_entries defined in line 16; never used
fd defined in line 16; used 12 times
Last modified: 1992-06-24
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2593
Valid CSS Valid XHTML 1.0 Strict