1 /* Copyright 1986-1992 Emmet P. Gray.
2 * Copyright 1994,1996-2009 Alain Knaff.
3 * This file is part of mtools.
5 * Mtools is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * Mtools is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with Mtools. If not, see <http://www.gnu.org/licenses/>.
21 #define DONT_NEED_WAIT
23 #include "sysincludes.h"
30 #include "floppyd_io.h"
31 #include "nameclash.h"
39 #include "partition.h"
40 #include "file_name.h"
43 #define abs(x) ((x)>0?(x):-(x))
47 #include "linux/hdreg.h"
49 #define _LINUX_STRING_H_
52 #undef _LINUX_STRING_H_
57 static int init_geometry_boot(union bootsector *boot, struct device *dev,
58 int sectors0, int rate_0, int rate_any,
59 unsigned long *tot_sectors, int keepBoot)
68 set_word(boot->boot.nsect, dev->sectors);
69 set_word(boot->boot.nheads, dev->heads);
71 *tot_sectors = dev->heads * dev->sectors * dev->tracks - DWORD(nhs);
73 if (*tot_sectors < 0x10000){
74 set_word(boot->boot.psect, *tot_sectors);
75 set_dword(boot->boot.bigsect, 0);
77 set_word(boot->boot.psect, 0);
78 set_dword(boot->boot.bigsect, *tot_sectors);
81 if (dev->use_2m & 0x7f){
83 strncpy(boot->boot.banner, "2M-STV04", 8);
84 boot->boot.ext.old.res_2m = 0;
85 boot->boot.ext.old.fmt_2mf = 6;
86 if ( dev->sectors % ( ((1 << dev->ssize) + 3) >> 2 ))
87 boot->boot.ext.old.wt = 1;
89 boot->boot.ext.old.wt = 0;
90 boot->boot.ext.old.rate_0= rate_0;
91 boot->boot.ext.old.rate_any= rate_any;
92 if (boot->boot.ext.old.rate_any== 2 )
93 boot->boot.ext.old.rate_any= 1;
97 set_word(boot->boot.ext.old.Infp0, i);
98 boot->bytes[i++] = sectors0;
99 boot->bytes[i++] = 108;
100 for(j=1; j<= sectors0; j++)
101 boot->bytes[i++] = j;
103 set_word(boot->boot.ext.old.InfpX, i);
105 boot->bytes[i++] = 64;
106 boot->bytes[i++] = 3;
108 sector2 = dev->sectors;
112 while ( sector2 < (1 << size2) >> 2 )
114 boot->bytes[i++] = 128 + j;
115 boot->bytes[i++] = j++;
116 boot->bytes[i++] = size2;
117 sector2 -= (1 << size2) >> 2;
119 boot->bytes[nb_renum] = ( i - nb_renum - 1 ) / 3;
121 set_word(boot->boot.ext.old.InfTm, i);
123 sector2 = dev->sectors;
126 while ( sector2 < 1 << ( size2 - 2) )
128 boot->bytes[i++] = size2;
129 sector2 -= 1 << (size2 - 2 );
132 set_word(boot->boot.ext.old.BootP,i);
136 for (sum=0, j=64; j<i; j++)
137 sum += boot->bytes[j];/* checksum */
138 boot->boot.ext.old.CheckSum=-sum;
142 boot->boot.jump[0] = 0xeb;
143 boot->boot.jump[1] = 0;
144 boot->boot.jump[2] = 0x90;
145 strncpy(boot->boot.banner, mformat_banner, 8);
146 /* It looks like some versions of DOS are
147 * rather picky about this, and assume default
148 * parameters without this, ignoring any
149 * indication about cluster size et al. */
156 static int comp_fat_bits(Fs_t *Fs, int estimate,
157 unsigned long tot_sectors, int fat32)
161 needed_fat_bits = 12;
163 #define MAX_DISK_SIZE(bits,clusters) \
164 TOTAL_DISK_SIZE((bits), Fs->sector_size, (clusters), \
165 Fs->num_fat, MAX_BYTES_PER_CLUSTER/Fs->sector_size)
167 if(tot_sectors > MAX_DISK_SIZE(12, FAT12-1))
168 needed_fat_bits = 16;
169 if(fat32 || tot_sectors > MAX_DISK_SIZE(16, FAT16-1))
170 needed_fat_bits = 32;
174 if(abs(estimate) && abs(estimate) < needed_fat_bits) {
177 "Contradiction between FAT size on command line and FAT size in conf file\n");
181 "Device too big for a %d bit FAT\n",
187 unsigned int min_fat16_size;
189 if(needed_fat_bits > 12)
190 return needed_fat_bits;
191 min_fat16_size = DISK_SIZE(16, Fs->sector_size, FAT12,
193 if(tot_sectors < min_fat16_size)
195 else if(tot_sectors >= 2* min_fat16_size)
196 return 16; /* heuristics */
204 * According to Microsoft "Hardware White Paper", "Microsoft
205 * Extensible Formware Initiative", "FAT32 File System Specification",
206 * Version 1.03, December 6, 2000:
207 * If (CountofClusters < 4085) {
209 * } else if (CountofClusters < 65525) {
215 * This document can be found at the following URL
216 * http://www.microsoft.com/hwdev/download/hardware/fatgen103.pdf
217 * The relevant passus is on page 15.
219 * Actually, experimentations with Windows NT 4 show that the
220 * cutoff is 4087 rather than 4085... This is Microsoft after all.
221 * Not sure what the other Microsoft OS'es do though...
223 static void calc_fat_bits2(Fs_t *Fs, unsigned long tot_sectors, int fat_bits,
224 int may_change_cluster_size,
225 int may_change_root_size)
227 unsigned long rem_sect;
230 * the "remaining sectors" after directory and boot
231 * hasve been accounted for.
233 rem_sect = tot_sectors - Fs->dir_len - Fs->fat_start;
234 switch(abs(fat_bits)) {
237 #define MY_DISK_SIZE(bits,clusters) \
238 DISK_SIZE( (bits), Fs->sector_size, (clusters), \
239 Fs->num_fat, Fs->cluster_size)
241 if(rem_sect >= MY_DISK_SIZE(16, FAT12+2))
242 /* big enough for FAT16
243 * We take a margin of 2, because NT4
244 * misbehaves, and starts considering a disk
245 * as FAT16 only if it is larger than 4086
246 * sectors, rather than 4084 as it should
249 else if(rem_sect <= MY_DISK_SIZE(12, FAT12-1))
250 /* small enough for FAT12 */
253 /* "between two chairs",
254 * augment cluster size, and
256 if(may_change_cluster_size &&
257 Fs->cluster_size * Fs->sector_size * 2
258 <= MAX_BYTES_PER_CLUSTER)
259 Fs->cluster_size <<= 1;
260 else if(may_change_root_size) {
262 rem_sect - MY_DISK_SIZE(12, FAT12-1);
281 static __inline__ void format_root(Fs_t *Fs, char *label, union bootsector *boot)
286 struct ClashHandling_t ch;
289 init_clash_handling(&ch);
290 ch.name_converter = label_name;
291 ch.ignore_entry = -2;
293 buf = safe_malloc(Fs->sector_size);
294 RootDir = OpenRoot((Stream_t *)Fs);
296 fprintf(stderr,"Could not open root directory\n");
300 memset(buf, '\0', Fs->sector_size);
302 if(Fs->fat_bits == 32) {
303 /* on a FAT32 system, we only write one sector,
304 * as the directory can be extended at will...*/
305 dirlen = Fs->cluster_size;
306 fatAllocate(Fs, Fs->rootCluster, Fs->end_fat);
308 dirlen = Fs->dir_len;
309 for (i = 0; i < dirlen; i++)
310 WRITES(RootDir, buf, sectorsToBytes((Stream_t*)Fs, i),
315 mwrite_one(RootDir,label, 0, labelit, NULL,&ch);
318 if(Fs->fat_bits == 32)
319 set_word(boot->boot.dirents, 0);
321 set_word(boot->boot.dirents, Fs->dir_len * (Fs->sector_size / 32));
326 static void xdf_calc_fat_size(Fs_t *Fs, unsigned long tot_sectors,
329 unsigned int rem_sect;
331 rem_sect = tot_sectors - Fs->dir_len - Fs->fat_start - 2 * Fs->fat_len;
334 /* an XDF disk, we know the fat_size and have to find
335 * out the rest. We start with a cluster size of 1 and
336 * keep doubling until everything fits into the
337 * FAT. This will occur eventually, as our FAT has a
338 * minimal size of 1 */
339 for(Fs->cluster_size = 1; 1 ; Fs->cluster_size <<= 1) {
340 Fs->num_clus = rem_sect / Fs->cluster_size;
341 if(abs(fat_bits) == 16 || Fs->num_clus >= FAT12)
345 if (Fs->fat_len >= NEEDED_FAT_SIZE(Fs))
349 fprintf(stderr,"Internal error while calculating Xdf fat size\n");
354 static void calc_fat_size(Fs_t *Fs, unsigned long tot_sectors)
356 unsigned long rem_sect;
357 unsigned long real_rem_sect;
358 unsigned long numerator;
359 unsigned long denominator;
362 int printGrowMsg=1; /* Should we print "growing FAT" messages ?*/
365 fprintf(stderr, "Fat start=%d\n", Fs->fat_start);
366 fprintf(stderr, "tot_sectors=%lu\n", tot_sectors);
367 fprintf(stderr, "dir_len=%d\n", Fs->dir_len);
369 real_rem_sect = rem_sect = tot_sectors - Fs->dir_len - Fs->fat_start;
371 /* Cheat a little bit to address the _really_ common case of
372 odd number of remaining sectors while both nfat and cluster size
374 if(rem_sect %2 == 1 &&
375 Fs->num_fat %2 == 0 &&
376 Fs->cluster_size %2 == 0)
380 fprintf(stderr, "Rem sect=%lu\n", rem_sect);
383 if(Fs->fat_bits == 0) {
384 fprintf(stderr, "Weird, fat bits = 0\n");
389 /* See fat_size_calculation.tex or
390 (http://ftp.gnu.org/software/mtools/manual/fat_size_calculation.pdf)
391 for an explantation about why the stuff below works...
394 fat_nybbles = Fs->fat_bits / 4;
395 numerator = rem_sect+2*Fs->cluster_size;
397 Fs->cluster_size * Fs->sector_size * 2 +
398 Fs->num_fat * fat_nybbles;
401 numerator *= fat_nybbles;
403 /* Avoid numerical overflows, divide the denominator
404 * rather than multiplying the numerator */
405 denominator = denominator / fat_nybbles;
408 fprintf(stderr, "Numerator=%lu denominator=%lu\n",
409 numerator, denominator);
412 Fs->fat_len = (numerator-1)/denominator+1;
413 Fs->num_clus = (rem_sect-(Fs->fat_len*Fs->num_fat))/Fs->cluster_size;
415 /* Apply upper bounds for FAT bits */
416 if(Fs->fat_bits == 16 && Fs->num_clus >= FAT16)
417 Fs->num_clus = FAT16-1;
418 if(Fs->fat_bits == 12 && Fs->num_clus >= FAT12)
419 Fs->num_clus = FAT12-1;
421 /* A safety, if above math is correct, this should not be happen...*/
422 if(Fs->num_clus > (Fs->fat_len * Fs->sector_size * 2 /
425 "Fat size miscalculation, shrinking num_clus from %d ",
427 Fs->num_clus = (Fs->fat_len * Fs->sector_size * 2 /
429 fprintf(stderr, " to %d\n", Fs->num_clus);
432 fprintf(stderr, "Num_clus=%d fat_len=%d nybbles=%d\n",
433 Fs->num_clus, Fs->fat_len, fat_nybbles);
436 if ( Fs->num_clus < FAT16 && Fs->fat_bits > 16 ){
437 fprintf(stderr,"Too few clusters for this fat size."
438 " Please choose a 16-bit fat in your /etc/mtools.conf"
439 " or .mtoolsrc file\n");
443 /* As the number of clusters is specified nowhere in the boot sector,
444 * it will be calculated by removing everything else from total number
445 * of sectors. This means that if we reduced the number of clusters
446 * above, we will have to grow the FAT in order to take up any excess
449 assert(rem_sect >= Fs->num_clus * Fs->cluster_size +
450 Fs->fat_len * Fs->num_fat);
453 Fs->num_clus * Fs->cluster_size -
454 Fs->fat_len * Fs->num_fat;
455 if(slack >= Fs->cluster_size) {
456 /* This can happen under two circumstances:
457 1. We had to reduce num_clus because we reached maximum
458 number of cluster for FAT12 or FAT16
461 fprintf(stderr, "Slack=%d\n", slack);
462 fprintf(stderr, "Growing fat size from %d",
466 (slack - Fs->cluster_size) / Fs->num_fat + 1;
469 " to %d in order to take up excess cluster area\n",
472 Fs->num_clus = (rem_sect-(Fs->fat_len*Fs->num_fat))/
478 /* Fat must be big enough for all clusters */
479 assert( ((Fs->num_clus+2) * fat_nybbles) <=
480 (Fs->fat_len*Fs->sector_size*2));
482 /* num_clus must be big enough to cover rest of disk, or else further
483 * users of the filesystem will assume a bigger num_clus, which might
484 * be too big for fat_len */
485 assert(Fs->num_clus ==
486 (real_rem_sect - Fs->num_fat * Fs->fat_len) / Fs->cluster_size);
491 static unsigned char bootprog[]=
492 {0xfa, 0x31, 0xc0, 0x8e, 0xd8, 0x8e, 0xc0, 0xfc, 0xb9, 0x00, 0x01,
493 0xbe, 0x00, 0x7c, 0xbf, 0x00, 0x80, 0xf3, 0xa5, 0xea, 0x00, 0x00,
494 0x00, 0x08, 0xb8, 0x01, 0x02, 0xbb, 0x00, 0x7c, 0xba, 0x80, 0x00,
495 0xb9, 0x01, 0x00, 0xcd, 0x13, 0x72, 0x05, 0xea, 0x00, 0x7c, 0x00,
498 static __inline__ void inst_boot_prg(union bootsector *boot, int offset)
500 memcpy((char *) boot->boot.jump + offset,
501 (char *) bootprog, sizeof(bootprog) /sizeof(bootprog[0]));
502 if(offset - 2 < 0x80) {
504 boot->boot.jump[0] = 0xeb;
505 boot->boot.jump[1] = offset -2;
506 boot->boot.jump[2] = 0x90;
508 /* long jump, if offset is too large */
509 boot->boot.jump[0] = 0xe9;
510 boot->boot.jump[1] = offset -3;
511 boot->boot.jump[2] = 0x00;
513 set_word(boot->boot.jump + offset + 20, offset + 24);
516 static void calc_cluster_size(struct Fs_t *Fs, unsigned long tot_sectors,
520 unsigned int max_clusters; /* maximal possible number of sectors for
521 * this FAT entry length (12/16/32) */
522 unsigned int max_fat_size; /* maximal size of the FAT for this FAT
523 * entry length (12/16/32) */
524 unsigned int rem_sect; /* remaining sectors after we accounted for
525 * the root directory and boot sector(s) */
527 switch(abs(fat_bits)) {
529 max_clusters = FAT12-1;
530 max_fat_size = Fs->num_fat *
531 FAT_SIZE(12, Fs->sector_size, max_clusters);
534 case 0: /* still hesititating between 12 and 16 */
535 max_clusters = FAT16-1;
536 max_fat_size = Fs->num_fat *
537 FAT_SIZE(16, Fs->sector_size, max_clusters);
540 Fs->cluster_size = 8;
542 * http://support.microsoft.com/support/kb/articles/q154/9/97.asp
543 * Micro$oft does not support FAT32 with less than 4K
547 fprintf(stderr,"Bad fat size\n");
551 rem_sect = tot_sectors - Fs->dir_len - Fs->fat_start;
553 /* double the cluster size until we can fill up the disk with
554 * the maximal number of sectors of this size */
555 while(Fs->cluster_size * max_clusters + max_fat_size < rem_sect) {
556 if(Fs->cluster_size > 64) {
557 /* bigger than 64. Should fit */
559 "Internal error while calculating cluster size\n");
562 Fs->cluster_size <<= 1;
567 struct OldDos_t old_dos[]={
568 { 40, 9, 1, 4, 1, 2, 0xfc },
569 { 40, 9, 2, 7, 2, 2, 0xfd },
570 { 40, 8, 1, 4, 1, 1, 0xfe },
571 { 40, 8, 2, 7, 2, 1, 0xff },
572 { 80, 9, 2, 7, 2, 3, 0xf9 },
573 { 80, 15, 2,14, 1, 7, 0xf9 },
574 { 80, 18, 2,14, 1, 9, 0xf0 },
575 { 80, 36, 2,15, 2, 9, 0xf0 },
576 { 1, 8, 1, 1, 1, 1, 0xf0 },
579 static int old_dos_size_to_geom(size_t size, int *cyls, int *heads, int *sects)
583 for(i=0; i < sizeof(old_dos) / sizeof(old_dos[0]); i++){
584 if (old_dos[i].sectors *
586 old_dos[i].heads == size) {
587 *cyls = old_dos[i].tracks;
588 *heads = old_dos[i].heads;
589 *sects = old_dos[i].sectors;
597 static void calc_fs_parameters(struct device *dev, unsigned long tot_sectors,
598 struct Fs_t *Fs, union bootsector *boot)
602 for(i=0; i < sizeof(old_dos) / sizeof(old_dos[0]); i++){
603 if (dev->sectors == old_dos[i].sectors &&
604 dev->tracks == old_dos[i].tracks &&
605 dev->heads == old_dos[i].heads &&
606 (dev->fat_bits == 0 || abs(dev->fat_bits) == 12) &&
607 (Fs->dir_len == 0 || Fs->dir_len == old_dos[i].dir_len) &&
608 (Fs->cluster_size == 0 ||
609 Fs->cluster_size == old_dos[i].cluster_size)) {
610 boot->boot.descr = old_dos[i].media;
611 Fs->cluster_size = old_dos[i].cluster_size;
612 Fs->dir_len = old_dos[i].dir_len;
613 Fs->fat_len = old_dos[i].fat_len;
618 if (i == sizeof(old_dos) / sizeof(old_dos[0]) ){
619 int may_change_cluster_size = (Fs->cluster_size == 0);
620 int may_change_root_size = (Fs->dir_len == 0);
622 /* a non-standard format */
624 boot->boot.descr = 0xf8;
626 boot->boot.descr = 0xf0;
629 if(!Fs->cluster_size) {
631 Fs->cluster_size = 1;
633 Fs->cluster_size = (tot_sectors > 2000 ) ? 1:2;
634 if (dev->use_2m & 0x7f)
635 Fs->cluster_size = 1;
643 Fs->dir_len = (tot_sectors > 2000) ? 32 : 7;
646 calc_cluster_size(Fs, tot_sectors, dev->fat_bits);
648 xdf_calc_fat_size(Fs, tot_sectors, dev->fat_bits);
650 calc_fat_bits2(Fs, tot_sectors, dev->fat_bits,
651 may_change_cluster_size,
652 may_change_root_size);
653 calc_fat_size(Fs, tot_sectors);
657 set_word(boot->boot.fatlen, Fs->fat_len);
662 static void calc_fs_parameters_32(unsigned long tot_sectors,
663 struct Fs_t *Fs, union bootsector *boot)
666 boot->boot.descr = 0xf8;
668 boot->boot.descr = 0xf0;
669 if(!Fs->cluster_size)
671 * http://www.microsoft.com/kb/articles/q154/9/97.htm,
672 * Micro$oft does not support FAT32 with less than 4K
674 Fs->cluster_size = 8;
677 Fs->num_clus = tot_sectors / Fs->cluster_size;
679 calc_fat_size(Fs, tot_sectors);
680 set_word(boot->boot.fatlen, 0);
681 set_dword(boot->boot.ext.fat32.bigFat, Fs->fat_len);
687 static void usage(int ret)
690 "Mtools version %s, dated %s\n", mversion, mdate);
692 "Usage: %s [-V] [-t tracks] [-h heads] [-n sectors] "
693 "[-v label] [-1] [-4] [-8] [-f size] "
695 "[-k] [-B bootsector] [-r root_dir_len] [-L fat_len] "
696 "[-F] [-I fsVersion] [-C] [-c cluster_size] "
697 "[-H hidden_sectors] "
701 "[-S hardsectorsize] [-M softsectorsize] [-3] "
702 "[-2 track0sectors] [-0 rate0] [-A rateany] [-a]"
703 "device\n", progname);
708 static int get_block_geom(int fd, struct MT_STAT *buf, struct device *dev,
710 struct hd_geometry geom;
712 int heads=dev->heads;
713 int sectors=dev->sectors;
716 if (ioctl(fd, HDIO_GETGEO, &geom) < 0) {
717 sprintf(errmsg, "Could not get geometry of device (%s)",
722 if (ioctl(fd, BLKGETSIZE, &size) < 0) {
723 sprintf(errmsg, "Could not get size of device (%s)",
731 sectors = geom.sectors;
733 sect_per_track = heads * sectors;
736 hidden = geom.start % sect_per_track;
737 if(hidden && hidden != sectors) {
739 "Hidden (%d) does not match sectors (%d)\n",
743 dev->hidden = hidden;
746 dev->sectors = sectors;
748 dev->tracks = (size + dev->hidden) / sect_per_track;
749 size = dev->tracks * dev->heads * dev->sectors + dev->hidden;
754 void mformat(int argc, char **argv, int dummy)
756 int r; /* generic return value */
760 int sectors0=18; /* number of sectors on track 0 */
762 int rate_0, rate_any;
764 int argssize=0; /* sector size */
767 struct label_blk_t *labelBlock;
773 struct xdf_info info;
775 union bootsector boot;
779 struct device used_dev;
780 int argtracks, argheads, argsectors;
781 unsigned long tot_sectors;
784 char drive, name[EXPAND_BUF];
786 char label[VBUFSIZE];
788 dos_name_t shortlabel;
792 unsigned long serial;
799 int Atari = 0; /* should we add an Atari-style serial number ? */
815 if(getenv("MTOOLS_DIR_LEN")) {
816 Fs.dir_len = atoi(getenv("MTOOLS_DIR_LEN"));
822 if(getenv("MTOOLS_NFATS")) {
823 Fs.num_fat = atoi(getenv("MTOOLS_NFATS"));
828 rate_0 = mtools_rate_0;
829 rate_any = mtools_rate_any;
831 /* get command line options */
832 if(helpFlag(argc, argv))
834 while ((c = getopt(argc,argv,
836 "kB:r:L:I:FCc:Xh:s:l:N:H:M:S:2:30:Aad:m:"))!= EOF) {
839 set_cmd_line_image(optarg, 0);
842 /* standard DOS flags */
855 r=old_dos_size_to_geom(atoi(optarg),
856 &argtracks, &argheads,
860 "Bad size %s\n", optarg);
865 argtracks = atoi(optarg);
868 case 'n': /*non-standard*/
870 argsectors = atoi(optarg);
873 case 'l': /* non-standard */
875 strncpy(label, optarg, VBUFSIZE-1);
876 label[VBUFSIZE-1] = '\0';
879 /* flags supported by Dos but not mtools */
883 /*case 's': leave this for compatibility */
885 "Flag %c not supported by mtools\n",c);
890 /* flags added by mtools */
897 argssize = atoi(optarg) | 0x80;
900 if(argssize >= 0x87) {
901 fprintf(stderr, "argssize must be less than 6\n");
914 sectors0 = atoi(optarg);
920 case '0': /* rate on track 0 */
921 rate_0 = atoi(optarg);
923 case 'A': /* rate on other tracks */
924 rate_any = atoi(optarg);
928 msize = atoi(optarg);
933 fprintf(stderr, "Only sector sizes of 512, 1024, 2048 or 4096 bytes are allowed\n");
939 serial = strtoul(optarg,0,16);
942 case 'a': /* Atari style serial number */
947 create = O_CREAT | O_TRUNC;
956 fsVersion = strtoul(optarg,0,0);
960 Fs.cluster_size = atoi(optarg);
964 Fs.dir_len = strtoul(optarg,0,0);
967 Fs.fat_len = strtoul(optarg,0,0);
978 argheads = atoi(optarg);
981 Fs.num_fat = atoi(optarg);
984 mediaDesc = strtoul(optarg,0,0);
991 if (argc - optind != 1 ||
992 !argv[optind][0] || argv[optind][1] != ':')
996 if(create && format_xdf) {
997 fprintf(stderr,"Create and XDF can't be used together\n");
1002 drive = toupper(argv[argc -1][0]);
1004 /* check out a drive whose letter and parameters match */
1005 sprintf(errmsg, "Drive '%c:' not supported", drive);
1008 for(dev=devices;dev->drive;dev++) {
1011 if (dev->drive != drive)
1015 SET_INT(used_dev.tracks, argtracks);
1016 SET_INT(used_dev.heads, argheads);
1017 SET_INT(used_dev.sectors, argsectors);
1018 SET_INT(used_dev.use_2m, arguse_2m);
1019 SET_INT(used_dev.ssize, argssize);
1021 used_dev.hidden = hs;
1023 expand(dev->name, name);
1024 #ifdef USING_NEW_VOLD
1025 strcpy(name, getVoldName(dev, name));
1033 Fs.Direct = FloppydOpen(&used_dev, dev, name,
1037 maxSize = max_off_t_31;
1041 Fs.Direct = SimpleFileOpen(&used_dev, dev, name,
1048 used_dev.misc_flags |= USE_XDF_FLAG;
1049 Fs.Direct = XdfOpen(&used_dev, name, O_RDWR,
1051 if(Fs.Direct && !Fs.fat_len)
1052 Fs.fat_len = info.FatSize;
1053 if(Fs.Direct && !Fs.dir_len)
1054 Fs.dir_len = info.RootDirSize;
1062 if ((!used_dev.tracks || !used_dev.heads || !used_dev.sectors) &&
1064 int fd= get_fd(Fs.Direct);
1065 struct MT_STAT stbuf;
1067 if (MT_FSTAT(fd, &stbuf) < 0) {
1068 sprintf(errmsg, "Could not stat file (%s)", strerror(errno));
1072 if (S_ISBLK(stbuf.st_mode) &&
1073 get_block_geom(fd, &stbuf, &used_dev, errmsg) < 0)
1078 /* no way to find out geometry */
1079 if (!used_dev.tracks || !used_dev.heads || !used_dev.sectors){
1082 "(You must tell the complete geometry "
1083 "of the disk, \neither in /etc/mtools.conf or "
1084 "on the command line) ");
1089 /* set parameters, if needed */
1090 if(SET_GEOM(Fs.Direct, &used_dev, 0xf0, boot)){
1091 sprintf(errmsg,"Can't set disk parameters: %s",
1096 Fs.sector_size = 512;
1097 if( !(used_dev.use_2m & 0x7f)) {
1098 Fs.sector_size = 128 << (used_dev.ssize & 0x7f);
1101 SET_INT(Fs.sector_size, msize);
1104 for(j = 0; j < 31; j++) {
1105 if (Fs.sector_size == (unsigned int) (1 << j)) {
1110 Fs.sectorMask = Fs.sector_size - 1;
1113 if(!used_dev.blocksize || used_dev.blocksize < Fs.sector_size)
1114 blocksize = Fs.sector_size;
1116 blocksize = used_dev.blocksize;
1118 if(blocksize > MAX_SECTOR)
1119 blocksize = MAX_SECTOR;
1121 /* do a "test" read */
1123 READS(Fs.Direct, &boot.characters, 0, Fs.sector_size) !=
1124 (signed int) Fs.sector_size) {
1126 "Error reading from '%s', wrong parameters?",
1134 /* print error msg if needed */
1135 if ( dev->drive == 0 ){
1137 fprintf(stderr,"%s: %s\n", argv[0],errmsg);
1141 /* calculate the total number of sectors */
1142 tot_sectors = used_dev.tracks*used_dev.heads*used_dev.sectors - used_dev.hidden;
1144 /* create the image file if needed */
1146 WRITES(Fs.Direct, &boot.characters,
1147 sectorsToBytes((Stream_t*)&Fs, tot_sectors-1),
1151 /* the boot sector */
1155 fd = open(bootSector, O_RDONLY | O_BINARY | O_LARGEFILE);
1157 perror("open boot sector");
1160 if(read(fd, &boot.bytes, blocksize) < blocksize) {
1161 perror("short read on boot sector");
1166 if(!keepBoot && !(used_dev.use_2m & 0x7f)) {
1167 memset(boot.characters, '\0', Fs.sector_size);
1168 if(Fs.sector_size == 512 && !used_dev.partition) {
1169 /* install fake partition table pointing to itself */
1170 struct partition *partTable=(struct partition *)
1171 (&boot.bytes[0x1ae]);
1172 setBeginEnd(&partTable[1], 0,
1173 used_dev.heads * used_dev.sectors * used_dev.tracks,
1174 used_dev.heads, used_dev.sectors, 1, 0);
1177 set_dword(boot.boot.nhs, used_dev.hidden);
1179 Fs.Next = buf_init(Fs.Direct,
1180 blocksize * used_dev.heads * used_dev.sectors,
1181 blocksize * used_dev.heads * used_dev.sectors,
1185 boot.boot.nfat = Fs.num_fat;
1187 set_word(&boot.bytes[510], 0xaa55);
1189 /* Initialize the remaining parameters */
1190 set_word(boot.boot.nsect, used_dev.sectors);
1191 set_word(boot.boot.nheads, used_dev.heads);
1193 used_dev.fat_bits = comp_fat_bits(&Fs,used_dev.fat_bits, tot_sectors, fat32);
1195 if(used_dev.fat_bits == 32) {
1197 Fs.writeAllFats = 1;
1199 calc_fs_parameters_32(tot_sectors, &Fs, &boot);
1201 Fs.clus_start = Fs.num_fat * Fs.fat_len + Fs.fat_start;
1203 /* extension flags: mirror fats, and use #0 as primary */
1204 set_word(boot.boot.ext.fat32.extFlags,0);
1206 /* fs version. What should go here? */
1207 set_word(boot.boot.ext.fat32.fsVersion,fsVersion);
1209 /* root directory */
1210 set_dword(boot.boot.ext.fat32.rootCluster, Fs.rootCluster = 2);
1213 set_word(boot.boot.ext.fat32.infoSector, Fs.infoSectorLoc = 1);
1214 Fs.infoSectorLoc = 1;
1216 /* no backup boot sector */
1217 set_word(boot.boot.ext.fat32.backupBoot, 6);
1219 labelBlock = & boot.boot.ext.fat32.labelBlock;
1221 Fs.infoSectorLoc = 0;
1223 calc_fs_parameters(&used_dev, tot_sectors, &Fs, &boot);
1224 Fs.dir_start = Fs.num_fat * Fs.fat_len + Fs.fat_start;
1225 Fs.clus_start = Fs.dir_start + Fs.dir_len;
1226 labelBlock = & boot.boot.ext.old.labelBlock;
1230 /* Set the codepage */
1231 Fs.cp = cp_open(used_dev.codepage);
1236 /* only zero out physdrive if we don't have a template
1238 labelBlock->physdrive = 0x00;
1239 labelBlock->reserved = 0;
1240 labelBlock->dos4 = 0x29;
1242 if (!serial_set || Atari)
1243 srandom((long)time (0));
1246 set_dword(labelBlock->serial, serial);
1247 label_name(GET_DOSCONVERT((Stream_t *)&Fs),
1248 label[0] ? label : "NO NAME ", 0, &mangled, &shortlabel);
1249 strncpy(labelBlock->label, shortlabel.base, 11);
1250 sprintf(labelBlock->fat_type, "FAT%2.2d ", Fs.fat_bits);
1251 labelBlock->fat_type[7] = ' ';
1253 set_word(boot.boot.secsiz, Fs.sector_size);
1254 boot.boot.clsiz = (unsigned char) Fs.cluster_size;
1255 set_word(boot.boot.nrsvsect, Fs.fat_start);
1257 bootOffset = init_geometry_boot(&boot, &used_dev, sectors0,
1259 &tot_sectors, keepBoot);
1261 bootOffset = ((unsigned char *) labelBlock) - boot.bytes +
1262 sizeof(struct label_blk_t);
1265 boot.boot.banner[4] = 0;
1266 boot.boot.banner[5] = random();
1267 boot.boot.banner[6] = random();
1268 boot.boot.banner[7] = random();
1272 inst_boot_prg(&boot, bootOffset);
1273 /* Mimic 3.8 behavior, else 2m disk do not work (???)
1274 * luferbu@fluidsignal.com (Luis Bustamante), Fri, 14 Jun 2002
1276 if(used_dev.use_2m & 0x7f) {
1277 boot.boot.jump[0] = 0xeb;
1278 boot.boot.jump[1] = 0x80;
1279 boot.boot.jump[2] = 0x90;
1281 if(used_dev.use_2m & 0x7f)
1284 boot.boot.descr=mediaDesc;
1285 Fs.lastFatSectorNr = 0;
1286 Fs.lastFatSectorData = 0;
1287 zero_fat(&Fs, boot.boot.descr);
1288 Fs.freeSpace = Fs.num_clus;
1294 i < (info.BadSectors+Fs.cluster_size-1)/Fs.cluster_size;
1296 fatEncode(&Fs, i+2, 0xfff7);
1299 format_root(&Fs, label, &boot);
1300 WRITES((Stream_t *)&Fs, boot.characters,
1301 (mt_off_t) 0, Fs.sector_size);
1302 if(Fs.fat_bits == 32 && WORD_S(ext.fat32.backupBoot) != MAX16) {
1303 WRITES((Stream_t *)&Fs, boot.characters,
1304 sectorsToBytes((Stream_t*)&Fs,
1305 WORD_S(ext.fat32.backupBoot)),
1308 FLUSH((Stream_t *)&Fs); /* flushes Fs.
1309 * This triggers the writing of the FAT */
1311 Fs.Class->freeFunc((Stream_t *)&Fs);
1313 if(format_xdf && isatty(0) && !getenv("MTOOLS_USE_XDF"))
1316 "Remember to set the \"MTOOLS_USE_XDF\" environmental\n"
1317 "variable before accessing this disk\n\n"
1318 "Bourne shell syntax (sh, ash, bash, ksh, zsh etc):\n"
1319 " export MTOOLS_USE_XDF=1\n\n"
1320 "C shell syntax (csh and tcsh):\n"
1321 " setenv MTOOLS_USE_XDF 1\n" );