Imported Upstream version 4.0.18
[platform/upstream/mtools.git] / mformat.c
1 /*  Copyright 1986-1992 Emmet P. Gray.
2  *  Copyright 1994,1996-2009 Alain Knaff.
3  *  This file is part of mtools.
4  *
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.
9  *
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.
14  *
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/>.
17  *
18  * mformat.c
19  */
20
21 #define DONT_NEED_WAIT
22
23 #include "sysincludes.h"
24 #include "msdos.h"
25 #include "mtools.h"
26 #include "mainloop.h"
27 #include "fsP.h"
28 #include "file.h"
29 #include "plain_io.h"
30 #include "floppyd_io.h"
31 #include "nameclash.h"
32 #include "buffer.h"
33 #ifdef HAVE_ASSERT_H
34 #include <assert.h>
35 #endif
36 #ifdef USE_XDF
37 #include "xdf_io.h"
38 #endif
39 #include "partition.h"
40 #include "file_name.h"
41
42 #ifndef abs
43 #define abs(x) ((x)>0?(x):-(x))
44 #endif
45
46 #ifdef OS_linux
47 #include "linux/hdreg.h"
48
49 #define _LINUX_STRING_H_
50 #define kdev_t int
51 #include "linux/fs.h"
52 #undef _LINUX_STRING_H_
53
54 #endif
55
56
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)
60 {
61         int i;
62         int nb_renum;
63         int sector2;
64         int size2;
65         int j;
66         int sum;
67
68         set_word(boot->boot.nsect, dev->sectors);
69         set_word(boot->boot.nheads, dev->heads);
70
71 #ifdef HAVE_ASSERT_H
72         assert(*tot_sectors != 0);
73 #endif
74
75         if (*tot_sectors < 0x10000){
76                 set_word(boot->boot.psect, *tot_sectors);
77                 set_dword(boot->boot.bigsect, 0);
78         } else {
79                 set_word(boot->boot.psect, 0);
80                 set_dword(boot->boot.bigsect, *tot_sectors);
81         }
82
83         if (dev->use_2m & 0x7f){
84                 int bootOffset;
85                 strncpy(boot->boot.banner, "2M-STV04", 8);
86                 boot->boot.ext.old.res_2m = 0;
87                 boot->boot.ext.old.fmt_2mf = 6;
88                 if ( dev->sectors % ( ((1 << dev->ssize) + 3) >> 2 ))
89                         boot->boot.ext.old.wt = 1;
90                 else
91                         boot->boot.ext.old.wt = 0;
92                 boot->boot.ext.old.rate_0= rate_0;
93                 boot->boot.ext.old.rate_any= rate_any;
94                 if (boot->boot.ext.old.rate_any== 2 )
95                         boot->boot.ext.old.rate_any= 1;
96                 i=76;
97
98                 /* Infp0 */
99                 set_word(boot->boot.ext.old.Infp0, i);
100                 boot->bytes[i++] = sectors0;
101                 boot->bytes[i++] = 108;
102                 for(j=1; j<= sectors0; j++)
103                         boot->bytes[i++] = j;
104
105                 set_word(boot->boot.ext.old.InfpX, i);
106
107                 boot->bytes[i++] = 64;
108                 boot->bytes[i++] = 3;
109                 nb_renum = i++;
110                 sector2 = dev->sectors;
111                 size2 = dev->ssize;
112                 j=1;
113                 while( sector2 ){
114                         while ( sector2 < (1 << size2) >> 2 )
115                                 size2--;
116                         boot->bytes[i++] = 128 + j;
117                         boot->bytes[i++] = j++;
118                         boot->bytes[i++] = size2;
119                         sector2 -= (1 << size2) >> 2;
120                 }
121                 boot->bytes[nb_renum] = ( i - nb_renum - 1 ) / 3;
122
123                 set_word(boot->boot.ext.old.InfTm, i);
124
125                 sector2 = dev->sectors;
126                 size2= dev->ssize;
127                 while(sector2){
128                         while ( sector2 < 1 << ( size2 - 2) )
129                                 size2--;
130                         boot->bytes[i++] = size2;
131                         sector2 -= 1 << (size2 - 2 );
132                 }
133
134                 set_word(boot->boot.ext.old.BootP,i);
135                 bootOffset = i;
136
137                 /* checksum */
138                 for (sum=0, j=64; j<i; j++)
139                         sum += boot->bytes[j];/* checksum */
140                 boot->boot.ext.old.CheckSum=-sum;
141                 return bootOffset;
142         } else {
143                 if(!keepBoot) {
144                         boot->boot.jump[0] = 0xeb;
145                         boot->boot.jump[1] = 0;
146                         boot->boot.jump[2] = 0x90;
147                         strncpy(boot->boot.banner, mformat_banner, 8);
148                         /* It looks like some versions of DOS are
149                          * rather picky about this, and assume default
150                          * parameters without this, ignoring any
151                          * indication about cluster size et al. */
152                 }
153                 return 0;
154         }
155 }
156
157
158 static int comp_fat_bits(Fs_t *Fs, int estimate,
159                          unsigned long tot_sectors, int fat32)
160 {
161         int needed_fat_bits;
162
163         needed_fat_bits = 12;
164
165 #define MAX_DISK_SIZE(bits,clusters) \
166         TOTAL_DISK_SIZE((bits), Fs->sector_size, (clusters), \
167                         Fs->num_fat, MAX_BYTES_PER_CLUSTER/Fs->sector_size)
168
169         if(tot_sectors > MAX_DISK_SIZE(12, FAT12-1))
170                 needed_fat_bits = 16;
171         if(fat32 || tot_sectors > MAX_DISK_SIZE(16, FAT16-1))
172                 needed_fat_bits = 32;
173
174 #undef MAX_DISK_SIZE
175
176         if(abs(estimate) && abs(estimate) < needed_fat_bits) {
177                 if(fat32) {
178                         fprintf(stderr,
179                                 "Contradiction between FAT size on command line and FAT size in conf file\n");
180                         exit(1);
181                 }
182                 fprintf(stderr,
183                         "Device too big for a %d bit FAT\n",
184                         estimate);
185                 exit(1);
186         }
187
188         if(!estimate) {
189                 unsigned int min_fat16_size;
190
191                 if(needed_fat_bits > 12)
192                         return needed_fat_bits;
193                 min_fat16_size = DISK_SIZE(16, Fs->sector_size, FAT12,
194                                            Fs->num_fat, 1);
195                 if(tot_sectors < min_fat16_size)
196                         return 12;
197                 else if(Fs->cluster_size == 0 &&
198                         tot_sectors >= 2* min_fat16_size)
199                         return 16; /* heuristics */
200         }
201
202         return estimate;
203 }
204
205
206 /*
207  * According to Microsoft "Hardware White Paper", "Microsoft
208  * Extensible Formware Initiative", "FAT32 File System Specification",
209  * Version 1.03, December 6, 2000:
210  * If (CountofClusters < 4085) {
211  *  // Volume is FAT12
212  * } else if (CountofClusters < 65525) {
213  *  // Volume is FAT16
214  * } else {
215  *  //Volume is FAT32
216  * }
217  *
218  * This document can be found at the following URL
219  * http://www.microsoft.com/hwdev/download/hardware/fatgen103.pdf
220  * The relevant passus is on page 15.
221  *
222  * Actually, experimentations with Windows NT 4 show that the
223  * cutoff is 4087 rather than 4085... This is Microsoft after all.
224  * Not sure what the other Microsoft OS'es do though...
225  */
226 static void calc_fat_bits2(Fs_t *Fs, unsigned long tot_sectors, int fat_bits,
227                            int may_change_cluster_size,
228                            int may_change_root_size)
229 {
230         unsigned long rem_sect;
231
232         /*
233          * the "remaining sectors" after directory and boot
234          * hasve been accounted for.
235          */
236         rem_sect = tot_sectors - Fs->dir_len - Fs->fat_start;
237         switch(abs(fat_bits)) {
238                 case 0:
239
240 #define MY_DISK_SIZE(bits,clusters) \
241                         DISK_SIZE( (bits), Fs->sector_size, (clusters), \
242                                    Fs->num_fat, Fs->cluster_size)
243
244                         if(rem_sect >= MY_DISK_SIZE(16, FAT12+2))
245                                 /* big enough for FAT16
246                                  * We take a margin of 2, because NT4
247                                  * misbehaves, and starts considering a disk
248                                  * as FAT16 only if it is larger than 4086
249                                  * sectors, rather than 4084 as it should
250                                  */
251                                 set_fat16(Fs);
252                         else if(rem_sect <= MY_DISK_SIZE(12, FAT12-1))
253                                  /* small enough for FAT12 */
254                                  set_fat12(Fs);
255                         else {
256                                 /* "between two chairs",
257                                  * augment cluster size, and
258                                  * settle it */
259                                 if(may_change_cluster_size &&
260                                    Fs->cluster_size * Fs->sector_size * 2
261                                    <= MAX_BYTES_PER_CLUSTER)
262                                         Fs->cluster_size <<= 1;
263                                 else if(may_change_root_size) {
264                                         Fs->dir_len +=
265                                                 rem_sect - MY_DISK_SIZE(12, FAT12-1);
266                                 }
267                                 set_fat12(Fs);
268                         }
269                         break;
270 #undef MY_DISK_SIZE
271
272                 case 12:
273                         set_fat12(Fs);
274                         break;
275                 case 16:
276                         set_fat16(Fs);
277                         break;
278                 case 32:
279                         set_fat32(Fs);
280                         break;
281         }
282 }
283
284 static __inline__ void format_root(Fs_t *Fs, char *label, union bootsector *boot)
285 {
286         Stream_t *RootDir;
287         char *buf;
288         int i;
289         struct ClashHandling_t ch;
290         int dirlen;
291
292         init_clash_handling(&ch);
293         ch.name_converter = label_name_uc;
294         ch.ignore_entry = -2;
295
296         buf = safe_malloc(Fs->sector_size);
297         RootDir = OpenRoot((Stream_t *)Fs);
298         if(!RootDir){
299                 fprintf(stderr,"Could not open root directory\n");
300                 exit(1);
301         }
302
303         memset(buf, '\0', Fs->sector_size);
304
305         if(Fs->fat_bits == 32) {
306                 /* on a FAT32 system, we only write one sector,
307                  * as the directory can be extended at will...*/
308                 dirlen = Fs->cluster_size;
309                 fatAllocate(Fs, Fs->rootCluster, Fs->end_fat);
310         } else
311                 dirlen = Fs->dir_len;
312         for (i = 0; i < dirlen; i++)
313                 WRITES(RootDir, buf, sectorsToBytes((Stream_t*)Fs, i),
314                            Fs->sector_size);
315
316         ch.ignore_entry = 1;
317         if(label[0])
318                 mwrite_one(RootDir,label, 0, labelit, NULL,&ch);
319
320         FREE(&RootDir);
321         if(Fs->fat_bits == 32)
322                 set_word(boot->boot.dirents, 0);
323         else
324                 set_word(boot->boot.dirents, Fs->dir_len * (Fs->sector_size / 32));
325         free(buf);
326 }
327
328
329 #ifdef USE_XDF
330 static void xdf_calc_fat_size(Fs_t *Fs, unsigned long tot_sectors,
331                               int fat_bits)
332 {
333         unsigned int rem_sect;
334
335         rem_sect = tot_sectors - Fs->dir_len - Fs->fat_start - 2 * Fs->fat_len;
336
337         if(Fs->fat_len) {
338                 /* an XDF disk, we know the fat_size and have to find
339                  * out the rest. We start with a cluster size of 1 and
340                  * keep doubling until everything fits into the
341                  * FAT. This will occur eventually, as our FAT has a
342                  * minimal size of 1 */
343                 for(Fs->cluster_size = 1; 1 ; Fs->cluster_size <<= 1) {
344                         Fs->num_clus = rem_sect / Fs->cluster_size;
345                         if(abs(fat_bits) == 16 || Fs->num_clus >= FAT12)
346                                 set_fat16(Fs);
347                         else
348                                 set_fat12(Fs);
349                         if (Fs->fat_len >= NEEDED_FAT_SIZE(Fs))
350                                 return;
351                 }
352         }
353         fprintf(stderr,"Internal error while calculating Xdf fat size\n");
354         exit(1);
355 }
356 #endif
357
358 static void calc_fat_size(Fs_t *Fs, unsigned long tot_sectors)
359 {
360         unsigned long rem_sect;
361         unsigned long real_rem_sect;
362         unsigned long numerator;
363         unsigned long denominator;
364         int fat_nybbles;
365         unsigned int slack;
366         int printGrowMsg=1; /* Should we print "growing FAT" messages ?*/
367
368 #ifdef DEBUG
369         fprintf(stderr, "Fat start=%d\n", Fs->fat_start);
370         fprintf(stderr, "tot_sectors=%lu\n", tot_sectors);
371         fprintf(stderr, "dir_len=%d\n", Fs->dir_len);
372 #endif
373         real_rem_sect = rem_sect = tot_sectors - Fs->dir_len - Fs->fat_start;
374
375         /* Cheat a little bit to address the _really_ common case of
376            odd number of remaining sectors while both nfat and cluster size
377            are even... */
378         if(rem_sect         %2 == 1 &&
379            Fs->num_fat      %2 == 0 &&
380            Fs->cluster_size %2 == 0)
381                 rem_sect--;
382
383 #ifdef DEBUG
384         fprintf(stderr, "Rem sect=%lu\n", rem_sect);
385 #endif
386
387         if(Fs->fat_bits == 0) {
388                 fprintf(stderr, "Weird, fat bits = 0\n");
389                 exit(1);
390         }
391
392
393         /* See fat_size_calculation.tex or
394            (http://ftp.gnu.org/software/mtools/manual/fat_size_calculation.pdf)
395            for an explantation about why the stuff below works...
396         */
397
398         fat_nybbles = Fs->fat_bits / 4;
399         numerator   = rem_sect+2*Fs->cluster_size;
400         denominator =
401           Fs->cluster_size * Fs->sector_size * 2 +
402           Fs->num_fat * fat_nybbles;
403
404         if(fat_nybbles == 3)
405                 numerator *= fat_nybbles;
406         else
407                 /* Avoid numerical overflows, divide the denominator
408                  * rather than multiplying the numerator */
409                 denominator = denominator / fat_nybbles;
410
411 #ifdef DEBUG
412         fprintf(stderr, "Numerator=%lu denominator=%lu\n",
413                 numerator, denominator);
414 #endif
415
416         Fs->fat_len = (numerator-1)/denominator+1;
417         Fs->num_clus = (rem_sect-(Fs->fat_len*Fs->num_fat))/Fs->cluster_size;
418
419         /* Apply upper bounds for FAT bits */
420         if(Fs->fat_bits == 16 && Fs->num_clus >= FAT16)
421                 Fs->num_clus = FAT16-1;
422         if(Fs->fat_bits == 12 && Fs->num_clus >= FAT12)
423                 Fs->num_clus = FAT12-1;
424
425         /* A safety, if above math is correct, this should not be happen...*/
426         if(Fs->num_clus > (Fs->fat_len * Fs->sector_size * 2 /
427                            fat_nybbles - 2)) {
428                 fprintf(stderr,
429                         "Fat size miscalculation, shrinking num_clus from %d ",
430                         Fs->num_clus);
431                 Fs->num_clus = (Fs->fat_len * Fs->sector_size * 2 /
432                                 fat_nybbles - 2);
433                 fprintf(stderr, " to %d\n", Fs->num_clus);
434         }
435 #ifdef DEBUG
436         fprintf(stderr, "Num_clus=%d fat_len=%d nybbles=%d\n",
437                 Fs->num_clus, Fs->fat_len, fat_nybbles);
438 #endif
439
440         if ( Fs->num_clus < FAT16 && Fs->fat_bits > 16 ){
441                 fprintf(stderr,"Too few clusters for this fat size."
442                         " Please choose a 16-bit fat in your /etc/mtools.conf"
443                         " or .mtoolsrc file\n");
444                 exit(1);
445         }
446
447         /* As the number of clusters is specified nowhere in the boot sector,
448          * it will be calculated by removing everything else from total number
449          * of sectors. This means that if we reduced the number of clusters
450          * above, we will have to grow the FAT in order to take up any excess
451          * sectors... */
452 #ifdef HAVE_ASSERT_H
453         assert(rem_sect >= Fs->num_clus * Fs->cluster_size +
454                Fs->fat_len * Fs->num_fat);
455 #endif
456         slack = rem_sect -
457                 Fs->num_clus * Fs->cluster_size -
458                 Fs->fat_len * Fs->num_fat;
459         if(slack >= Fs->cluster_size) {
460                 /* This can happen under two circumstances:
461                    1. We had to reduce num_clus because we reached maximum
462                    number of cluster for FAT12 or FAT16
463                 */
464                 if(printGrowMsg) {
465                         fprintf(stderr, "Slack=%d\n", slack);
466                         fprintf(stderr, "Growing fat size from %d",
467                                 Fs->fat_len);
468                 }
469                 Fs->fat_len +=
470                         (slack - Fs->cluster_size) / Fs->num_fat + 1;
471                 if(printGrowMsg) {
472                         fprintf(stderr,
473                                 " to %d in order to take up excess cluster area\n",
474                                 Fs->fat_len);
475                 }
476                 Fs->num_clus = (rem_sect-(Fs->fat_len*Fs->num_fat))/
477                         Fs->cluster_size;
478
479         }
480
481 #ifdef HAVE_ASSERT_H
482         /* Fat must be big enough for all clusters */
483         assert( ((Fs->num_clus+2) * fat_nybbles) <=
484                 (Fs->fat_len*Fs->sector_size*2));
485
486         /* num_clus must be big enough to cover rest of disk, or else further
487          * users of the filesystem will assume a bigger num_clus, which might
488          * be too big for fat_len */
489         assert(Fs->num_clus ==
490                (real_rem_sect - Fs->num_fat * Fs->fat_len) / Fs->cluster_size);
491 #endif
492 }
493
494
495 static unsigned char bootprog[]=
496 {0xfa, 0x31, 0xc0, 0x8e, 0xd8, 0x8e, 0xc0, 0xfc, 0xb9, 0x00, 0x01,
497  0xbe, 0x00, 0x7c, 0xbf, 0x00, 0x80, 0xf3, 0xa5, 0xea, 0x00, 0x00,
498  0x00, 0x08, 0xb8, 0x01, 0x02, 0xbb, 0x00, 0x7c, 0xba, 0x80, 0x00,
499  0xb9, 0x01, 0x00, 0xcd, 0x13, 0x72, 0x05, 0xea, 0x00, 0x7c, 0x00,
500  0x00, 0xcd, 0x19};
501
502 static __inline__ void inst_boot_prg(union bootsector *boot, int offset)
503 {
504         memcpy((char *) boot->boot.jump + offset,
505                (char *) bootprog, sizeof(bootprog) /sizeof(bootprog[0]));
506         if(offset - 2 < 0x80) {
507           /* short jump */
508           boot->boot.jump[0] = 0xeb;
509           boot->boot.jump[1] = offset -2;
510           boot->boot.jump[2] = 0x90;
511         } else {
512           /* long jump, if offset is too large */
513           boot->boot.jump[0] = 0xe9;
514           boot->boot.jump[1] = offset -3;
515           boot->boot.jump[2] = 0x00;
516         }
517         set_word(boot->boot.jump + offset + 20, offset + 24);
518 }
519
520 static void calc_cluster_size(struct Fs_t *Fs, unsigned long tot_sectors,
521                               int fat_bits)
522
523 {
524         unsigned int max_clusters; /* maximal possible number of sectors for
525                                    * this FAT entry length (12/16/32) */
526         unsigned int max_fat_size; /* maximal size of the FAT for this FAT
527                                     * entry length (12/16/32) */
528         unsigned int rem_sect; /* remaining sectors after we accounted for
529                                 * the root directory and boot sector(s) */
530
531         switch(abs(fat_bits)) {
532                 case 12:
533                         max_clusters = FAT12-1;
534                         max_fat_size = Fs->num_fat *
535                                 FAT_SIZE(12, Fs->sector_size, max_clusters);
536                         break;
537                 case 16:
538                 case 0: /* still hesititating between 12 and 16 */
539                         max_clusters = FAT16-1;
540                         max_fat_size = Fs->num_fat *
541                                 FAT_SIZE(16, Fs->sector_size, max_clusters);
542                         break;
543                 case 32:
544                         Fs->cluster_size = 8;
545                         /* According to
546                          * http://support.microsoft.com/support/kb/articles/q154/9/97.asp
547                          * Micro$oft does not support FAT32 with less than 4K
548                          */
549                         return;
550                 default:
551                         fprintf(stderr,"Bad fat size\n");
552                         exit(1);
553         }
554
555         if(tot_sectors <= Fs->fat_start + Fs->num_fat + Fs->dir_len) {
556                 /* we need at least enough sectors to fit boot, fat and root
557                  * dir */
558                 fprintf(stderr, "Not enough sectors\n");
559                 exit(1);
560         }
561
562         rem_sect = tot_sectors - Fs->dir_len - Fs->fat_start;
563
564         /* double the cluster size until we can fill up the disk with
565          * the maximal number of sectors of this size */
566         while(Fs->cluster_size * max_clusters  + max_fat_size < rem_sect) {
567                 if(Fs->cluster_size > 64) {
568                         /* bigger than 64. Should fit */
569                         fprintf(stderr,
570                                 "Internal error while calculating cluster size\n");
571                         exit(1);
572                 }
573                 Fs->cluster_size <<= 1;
574         }
575 }
576
577
578 struct OldDos_t old_dos[]={
579 {   40,  9,  1, 4, 1, 2, 0xfc },
580 {   40,  9,  2, 7, 2, 2, 0xfd },
581 {   40,  8,  1, 4, 1, 1, 0xfe },
582 {   40,  8,  2, 7, 2, 1, 0xff },
583 {   80,  9,  2, 7, 2, 3, 0xf9 },
584 {   80, 15,  2,14, 1, 7, 0xf9 },
585 {   80, 18,  2,14, 1, 9, 0xf0 },
586 {   80, 36,  2,15, 2, 9, 0xf0 },
587 {    1,  8,  1, 1, 1, 1, 0xf0 },
588 };
589
590 static int old_dos_size_to_geom(size_t size, int *cyls, int *heads, int *sects)
591 {
592         unsigned int i;
593         size = size * 2;
594         for(i=0; i < sizeof(old_dos) / sizeof(old_dos[0]); i++){
595                 if (old_dos[i].sectors *
596                     old_dos[i].tracks *
597                     old_dos[i].heads == size) {
598                         *cyls = old_dos[i].tracks;
599                         *heads = old_dos[i].heads;
600                         *sects = old_dos[i].sectors;
601                         return 0;
602                 }
603         }
604         return 1;
605 }
606
607
608 static void calc_fs_parameters(struct device *dev, unsigned long tot_sectors,
609                                struct Fs_t *Fs, union bootsector *boot)
610 {
611         unsigned int i;
612
613         for(i=0; i < sizeof(old_dos) / sizeof(old_dos[0]); i++){
614                 if (dev->sectors == old_dos[i].sectors &&
615                     dev->tracks == old_dos[i].tracks &&
616                     dev->heads == old_dos[i].heads &&
617                     (dev->fat_bits == 0 || abs(dev->fat_bits) == 12) &&
618                     (Fs->dir_len == 0 || Fs->dir_len == old_dos[i].dir_len) &&
619                     (Fs->cluster_size == 0 ||
620                      Fs->cluster_size == old_dos[i].cluster_size)) {
621                         boot->boot.descr = old_dos[i].media;
622                         Fs->cluster_size = old_dos[i].cluster_size;
623                         Fs->dir_len = old_dos[i].dir_len;
624                         Fs->fat_len = old_dos[i].fat_len;
625                         Fs->fat_bits = 12;
626                         break;
627                 }
628         }
629         if (i == sizeof(old_dos) / sizeof(old_dos[0]) ){
630                 int may_change_cluster_size = (Fs->cluster_size == 0);
631                 int may_change_root_size = (Fs->dir_len == 0);
632
633                 /* a non-standard format */
634                 if(DWORD(nhs) || tot_sectors % (dev->sectors * dev->heads))
635                         boot->boot.descr = 0xf8;
636                   else
637                         boot->boot.descr = 0xf0;
638
639
640                 if(!Fs->cluster_size) {
641                         if (dev->heads == 1)
642                                 Fs->cluster_size = 1;
643                         else {
644                                 Fs->cluster_size = (tot_sectors > 2000 ) ? 1:2;
645                                 if (dev->use_2m & 0x7f)
646                                         Fs->cluster_size = 1;
647                         }
648                 }
649
650                 if(!Fs->dir_len) {
651                         if (dev->heads == 1)
652                                 Fs->dir_len = 4;
653                         else
654                                 Fs->dir_len = (tot_sectors > 2000) ? 32 : 7;
655                 }
656
657                 calc_cluster_size(Fs, tot_sectors, dev->fat_bits);
658 #ifdef USE_XDF
659                 if(Fs->fat_len)
660                         xdf_calc_fat_size(Fs, tot_sectors, dev->fat_bits);
661                 else
662 #endif
663                 {
664                         calc_fat_bits2(Fs, tot_sectors, dev->fat_bits,
665                                        may_change_cluster_size,
666                                        may_change_root_size);
667                         calc_fat_size(Fs, tot_sectors);
668                 }
669         }
670
671         set_word(boot->boot.fatlen, Fs->fat_len);
672 }
673
674
675
676 static void calc_fs_parameters_32(unsigned long tot_sectors,
677                                   struct Fs_t *Fs, union bootsector *boot)
678 {
679         if(DWORD(nhs))
680                 boot->boot.descr = 0xf8;
681         else
682                 boot->boot.descr = 0xf0;
683         if(!Fs->cluster_size)
684                 /* According to
685                  * http://www.microsoft.com/kb/articles/q154/9/97.htm,
686                  * Micro$oft does not support FAT32 with less than 4K
687                  */
688                 Fs->cluster_size = 8;
689
690         Fs->dir_len = 0;
691         Fs->num_clus = tot_sectors / Fs->cluster_size;
692         set_fat32(Fs);
693         calc_fat_size(Fs, tot_sectors);
694         set_word(boot->boot.fatlen, 0);
695         set_dword(boot->boot.ext.fat32.bigFat, Fs->fat_len);
696 }
697
698
699
700
701 static void usage(int ret)
702 {
703         fprintf(stderr,
704                 "Mtools version %s, dated %s\n", mversion, mdate);
705         fprintf(stderr,
706                 "Usage: %s [-V] [-t tracks] [-h heads] [-n sectors] "
707                 "[-v label] [-1] [-4] [-8] [-f size] "
708                 "[-N serialnumber] "
709                 "[-k] [-B bootsector] [-r root_dir_len] [-L fat_len] "
710                 "[-F] [-I fsVersion] [-C] [-c cluster_size] "
711                 "[-H hidden_sectors] "
712 #ifdef USE_XDF
713                 "[-X] "
714 #endif
715                 "[-S hardsectorsize] [-M softsectorsize] [-3] "
716                 "[-2 track0sectors] [-0 rate0] [-A rateany] [-a]"
717                 "device\n", progname);
718         exit(ret);
719 }
720
721 #ifdef OS_linux
722 static int get_block_geom(int fd, struct device *dev, char *errmsg) {
723         struct hd_geometry geom;
724         long size;
725         int heads=dev->heads;
726         int sectors=dev->sectors;
727         int sect_per_track;
728
729         if (ioctl(fd, HDIO_GETGEO, &geom) < 0) {
730                 sprintf(errmsg, "Could not get geometry of device (%s)",
731                         strerror(errno));
732                 return -1;
733         }
734
735         if (ioctl(fd, BLKGETSIZE, &size) < 0) {
736                 sprintf(errmsg, "Could not get size of device (%s)",
737                         strerror(errno));
738                 return -1;
739         }
740
741         if(!heads)
742                 heads = geom.heads;
743         if(!sectors)
744                 sectors = geom.sectors;
745
746         sect_per_track = heads * sectors;
747         if(!dev->hidden) {
748                 int hidden;
749                 hidden = geom.start % sect_per_track;
750                 if(hidden && hidden != sectors) {
751                         sprintf(errmsg,
752                                 "Hidden (%d) does not match sectors (%d)\n",
753                                 hidden, sectors);
754                         return -1;
755                 }
756                 dev->hidden = hidden;
757         }
758         dev->heads = heads;
759         dev->sectors = sectors;
760         if(!dev->tracks)
761                 dev->tracks = (size + dev->hidden % sect_per_track) / sect_per_track;
762         return 0;
763 }
764 #endif
765
766 void mformat(int argc, char **argv, int dummy)
767 {
768         int r; /* generic return value */
769         Fs_t Fs;
770         int hs, hs_set;
771         int arguse_2m = 0;
772         int sectors0=18; /* number of sectors on track 0 */
773         int create = 0;
774         int rate_0, rate_any;
775         int mangled;
776         int argssize=0; /* sector size */
777         int msize=0;
778         int fat32 = 0;
779         struct label_blk_t *labelBlock;
780         int bootOffset;
781
782 #ifdef USE_XDF
783         unsigned int i;
784         int format_xdf = 0;
785         struct xdf_info info;
786 #endif
787         union bootsector boot;
788         char *bootSector=0;
789         int c;
790         int keepBoot = 0;
791         struct device used_dev;
792         int argtracks, argheads, argsectors;
793         unsigned long tot_sectors=0;
794         int blocksize;
795
796         char drive, name[EXPAND_BUF];
797
798         char label[VBUFSIZE];
799
800         dos_name_t shortlabel;
801         struct device *dev;
802         char errmsg[200];
803
804         unsigned long serial;
805         int serial_set;
806         int fsVersion;
807         int mediaDesc=-1;
808
809         mt_size_t maxSize;
810
811         int Atari = 0; /* should we add an Atari-style serial number ? */
812
813         int backupBoot = 6;
814
815         char *endptr;
816
817         hs = hs_set = 0;
818         argtracks = 0;
819         argheads = 0;
820         argsectors = 0;
821         arguse_2m = 0;
822         argssize = 0x2;
823         label[0] = '\0';
824         serial_set = 0;
825         serial = 0;
826         fsVersion = 0;
827
828         Fs.cluster_size = 0;
829         Fs.refs = 1;
830         Fs.dir_len = 0;
831         if(getenv("MTOOLS_DIR_LEN")) {
832           Fs.dir_len = atoi(getenv("MTOOLS_DIR_LEN"));
833           if(Fs.dir_len <= 0)
834             Fs.dir_len=0;
835         }
836         Fs.fat_len = 0;
837         Fs.num_fat = 2;
838         if(getenv("MTOOLS_NFATS")) {
839           Fs.num_fat = atoi(getenv("MTOOLS_NFATS"));
840           if(Fs.num_fat <= 0)
841             Fs.num_fat=2;
842         }
843         Fs.Class = &FsClass;
844         rate_0 = mtools_rate_0;
845         rate_any = mtools_rate_any;
846
847         /* get command line options */
848         if(helpFlag(argc, argv))
849                 usage(0);
850         while ((c = getopt(argc,argv,
851                            "i:148f:t:n:v:qub"
852                            "kK:B:r:L:I:FCc:Xh:s:T:l:N:H:M:S:2:30:Aad:m:"))!= EOF) {
853                 endptr = NULL;
854                 switch (c) {
855                         case 'i':
856                                 set_cmd_line_image(optarg);
857                                 break;
858
859                         /* standard DOS flags */
860                         case '1':
861                                 argheads = 1;
862                                 break;
863                         case '4':
864                                 argsectors = 9;
865                                 argtracks = 40;
866                                 break;
867                         case '8':
868                                 argsectors = 8;
869                                 argtracks = 40;
870                                 break;
871                         case 'f':
872                                 r=old_dos_size_to_geom(atoi(optarg),
873                                                        &argtracks, &argheads,
874                                                        &argsectors);
875                                 if(r) {
876                                         fprintf(stderr,
877                                                 "Bad size %s\n", optarg);
878                                         exit(1);
879                                 }
880                                 break;
881                         case 't':
882                                 argtracks = atoi(optarg);
883                                 break;
884
885                         case 'T':
886                                 tot_sectors = atoi(optarg);
887                                 break;
888
889                         case 'n': /*non-standard*/
890                         case 's':
891                                 argsectors = atoi(optarg);
892                                 break;
893
894                         case 'l': /* non-standard */
895                         case 'v':
896                                 strncpy(label, optarg, VBUFSIZE-1);
897                                 label[VBUFSIZE-1] = '\0';
898                                 break;
899
900                         /* flags supported by Dos but not mtools */
901                         case 'q':
902                         case 'u':
903                         case 'b':
904                         /*case 's': leave this for compatibility */
905                                 fprintf(stderr,
906                                         "Flag %c not supported by mtools\n",c);
907                                 exit(1);
908
909
910
911                         /* flags added by mtools */
912                         case 'F':
913                                 fat32 = 1;
914                                 break;
915
916
917                         case 'S':
918                                 argssize = atoi(optarg) | 0x80;
919                                 if(argssize < 0x80)
920                                         usage(1);
921                                 if(argssize >= 0x87) {
922                                         fprintf(stderr, "argssize must be less than 6\n");
923                                         usage(1);
924                                 }
925                                 break;
926
927 #ifdef USE_XDF
928                         case 'X':
929                                 format_xdf = 1;
930                                 break;
931 #endif
932
933                         case '2':
934                                 arguse_2m = 0xff;
935                                 sectors0 = atoi(optarg);
936                                 break;
937                         case '3':
938                                 arguse_2m = 0x80;
939                                 break;
940
941                         case '0': /* rate on track 0 */
942                                 rate_0 = atoi(optarg);
943                                 break;
944                         case 'A': /* rate on other tracks */
945                                 rate_any = atoi(optarg);
946                                 break;
947
948                         case 'M':
949                                 msize = atoi(optarg);
950                                 if(msize != 512 &&
951                                    msize != 1024 &&
952                                    msize != 2048 &&
953                                    msize != 4096) {
954                                   fprintf(stderr, "Only sector sizes of 512, 1024, 2048 or 4096 bytes are allowed\n");
955                                   usage(1);
956                                 }
957                                 break;
958
959                         case 'N':
960                                 serial = strtoul(optarg,&endptr,16);
961                                 serial_set = 1;
962                                 break;
963                         case 'a': /* Atari style serial number */
964                                 Atari = 1;
965                                 break;
966
967                         case 'C':
968                                 create = O_CREAT | O_TRUNC;
969                                 break;
970
971                         case 'H':
972                                 hs = atoi(optarg);
973                                 hs_set = 1;
974                                 break;
975
976                         case 'I':
977                                 fsVersion = strtoul(optarg,&endptr,0);
978                                 break;
979
980                         case 'c':
981                                 Fs.cluster_size = atoi(optarg);
982                                 break;
983
984                         case 'r':
985                                 Fs.dir_len = strtoul(optarg,&endptr,0);
986                                 break;
987                         case 'L':
988                                 Fs.fat_len = strtoul(optarg,&endptr,0);
989                                 break;
990
991
992                         case 'B':
993                                 bootSector = optarg;
994                                 break;
995                         case 'k':
996                                 keepBoot = 1;
997                                 break;
998                         case 'K':
999                                 backupBoot = atoi(optarg);
1000                                 if(backupBoot < 2 || backupBoot >= 32) {
1001                                   fprintf(stderr, "Backupboot must be comprised between 2 and 32\n");
1002                                   exit(1);
1003                                 }
1004                                 break;
1005                         case 'h':
1006                                 argheads = atoi(optarg);
1007                                 break;
1008                         case 'd':
1009                                 Fs.num_fat = atoi(optarg);
1010                                 break;
1011                         case 'm':
1012                                 mediaDesc = strtoul(optarg,&endptr,0);
1013                                 if(*endptr)
1014                                         mediaDesc = strtoul(optarg,&endptr,16);
1015                                 break;
1016                         default:
1017                                 usage(1);
1018                 }
1019                 if(endptr && *endptr) {
1020                         fprintf(stderr, "Bad number %s\n", optarg);
1021                         exit(1);
1022                 }
1023         }
1024
1025         if (argc - optind > 1)
1026                 usage(1);
1027         if(argc - optind == 1) {
1028             if(!argv[optind][0] || argv[optind][1] != ':')
1029                 usage(1);
1030             drive = toupper(argv[argc -1][0]);
1031         } else {
1032             drive = get_default_drive();
1033             if(drive != ':') {
1034               /* Use default drive only if it is ":" (image file), as else
1035                  it would be too dangerous... */
1036               fprintf(stderr, "Drive letter missing\n");
1037               exit(1);
1038             }
1039         }
1040
1041         if(argtracks && tot_sectors) {
1042                 fprintf(stderr, "Only one of -t or -T may be specified\n");
1043                 usage(1);
1044         }
1045
1046 #ifdef USE_XDF
1047         if(create && format_xdf) {
1048                 fprintf(stderr,"Create and XDF can't be used together\n");
1049                 exit(1);
1050         }
1051 #endif
1052
1053         /* check out a drive whose letter and parameters match */
1054         sprintf(errmsg, "Drive '%c:' not supported", drive);
1055         Fs.Direct = NULL;
1056         blocksize = 0;
1057         for(dev=devices;dev->drive;dev++) {
1058                 FREE(&(Fs.Direct));
1059                 /* drive letter */
1060                 if (dev->drive != drive)
1061                         continue;
1062                 used_dev = *dev;
1063
1064                 SET_INT(used_dev.tracks, argtracks);
1065                 SET_INT(used_dev.heads, argheads);
1066                 SET_INT(used_dev.sectors, argsectors);
1067                 SET_INT(used_dev.use_2m, arguse_2m);
1068                 SET_INT(used_dev.ssize, argssize);
1069                 if(hs_set)
1070                         used_dev.hidden = hs;
1071
1072                 expand(dev->name, name);
1073 #ifdef USING_NEW_VOLD
1074                 strcpy(name, getVoldName(dev, name));
1075 #endif
1076
1077 #ifdef USE_XDF
1078                 if(!format_xdf) {
1079 #endif
1080                         Fs.Direct = 0;
1081 #ifdef USE_FLOPPYD
1082                         Fs.Direct = FloppydOpen(&used_dev, name,
1083                                                 O_RDWR | create,
1084                                                 errmsg, &maxSize);
1085 #endif
1086                         if(!Fs.Direct) {
1087                                 Fs.Direct = SimpleFileOpen(&used_dev, dev, name,
1088                                                            O_RDWR | create,
1089                                                            errmsg, 0, 1,
1090                                                            &maxSize);
1091                         }
1092 #ifdef USE_XDF
1093                 } else {
1094                         used_dev.misc_flags |= USE_XDF_FLAG;
1095                         Fs.Direct = XdfOpen(&used_dev, name, O_RDWR,
1096                                             errmsg, &info);
1097                         if(Fs.Direct && !Fs.fat_len)
1098                                 Fs.fat_len = info.FatSize;
1099                         if(Fs.Direct && !Fs.dir_len)
1100                                 Fs.dir_len = info.RootDirSize;
1101                 }
1102 #endif
1103
1104                 if (!Fs.Direct)
1105                         continue;
1106
1107 #ifdef OS_linux
1108                 if ((!used_dev.tracks || !used_dev.heads || !used_dev.sectors) &&
1109                         (!IS_SCSI(dev))) {
1110                         int fd= get_fd(Fs.Direct);
1111                         struct MT_STAT stbuf;
1112
1113                         if (MT_FSTAT(fd, &stbuf) < 0) {
1114                                 sprintf(errmsg, "Could not stat file (%s)", strerror(errno));
1115                                 continue;
1116                         }
1117
1118                         if (S_ISBLK(stbuf.st_mode) &&
1119                             get_block_geom(fd, &used_dev, errmsg) < 0)
1120                                 continue;
1121                 }
1122 #endif
1123
1124                 /* no way to find out geometry */
1125                 if ((!used_dev.tracks && !tot_sectors) ||
1126                      !used_dev.heads || !used_dev.sectors){
1127                         sprintf(errmsg,
1128                                 "Unknown geometry "
1129                                 "(You must tell the complete geometry "
1130                                 "of the disk, \neither in /etc/mtools.conf or "
1131                                 "on the command line) ");
1132                         continue;
1133                 }
1134
1135 #if 0
1136                 /* set parameters, if needed */
1137                 if(SET_GEOM(Fs.Direct, &used_dev, 0xf0, boot)){
1138                         sprintf(errmsg,"Can't set disk parameters: %s",
1139                                 strerror(errno));
1140                         continue;
1141                 }
1142 #endif
1143                 Fs.sector_size = 512;
1144                 if( !(used_dev.use_2m & 0x7f)) {
1145                         Fs.sector_size = 128 << (used_dev.ssize & 0x7f);
1146                 }
1147
1148                 SET_INT(Fs.sector_size, msize);
1149                 {
1150                     unsigned int j;
1151                     for(j = 0; j < 31; j++) {
1152                         if (Fs.sector_size == (unsigned int) (1 << j)) {
1153                             Fs.sectorShift = j;
1154                             break;
1155                         }
1156                     }
1157                     Fs.sectorMask = Fs.sector_size - 1;
1158                 }
1159
1160                 if(!used_dev.blocksize || used_dev.blocksize < Fs.sector_size)
1161                         blocksize = Fs.sector_size;
1162                 else
1163                         blocksize = used_dev.blocksize;
1164
1165                 if(blocksize > MAX_SECTOR)
1166                         blocksize = MAX_SECTOR;
1167
1168                 /* do a "test" read */
1169                 if (!create &&
1170                     READS(Fs.Direct, &boot.characters, 0, Fs.sector_size) !=
1171                     (signed int) Fs.sector_size) {
1172                         sprintf(errmsg,
1173                                 "Error reading from '%s', wrong parameters?",
1174                                 name);
1175                         continue;
1176                 }
1177                 break;
1178         }
1179
1180
1181         /* print error msg if needed */
1182         if ( dev->drive == 0 ){
1183                 FREE(&Fs.Direct);
1184                 fprintf(stderr,"%s: %s\n", argv[0],errmsg);
1185                 exit(1);
1186         }
1187
1188         /* calculate the total number of sectors */
1189         if(tot_sectors == 0) {
1190                 unsigned long sect_per_track = used_dev.heads*used_dev.sectors;
1191                 tot_sectors = used_dev.tracks*sect_per_track - used_dev.hidden%sect_per_track;
1192         }
1193
1194         /* create the image file if needed */
1195         if (create) {
1196                 WRITES(Fs.Direct, &boot.characters,
1197                        sectorsToBytes((Stream_t*)&Fs, tot_sectors-1),
1198                        Fs.sector_size);
1199         }
1200
1201         /* the boot sector */
1202         if(bootSector) {
1203                 int fd;
1204
1205                 fd = open(bootSector, O_RDONLY | O_BINARY | O_LARGEFILE);
1206                 if(fd < 0) {
1207                         perror("open boot sector");
1208                         exit(1);
1209                 }
1210                 if(read(fd, &boot.bytes, blocksize) < blocksize) {
1211                         perror("short read on boot sector");
1212                         exit(1);
1213                 }
1214                 keepBoot = 1;
1215                 close(fd);
1216         }
1217         if(!keepBoot && !(used_dev.use_2m & 0x7f)) {
1218                 memset(boot.characters, '\0', Fs.sector_size);
1219                 if(Fs.sector_size == 512 && !used_dev.partition) {
1220                         /* install fake partition table pointing to itself */
1221                         struct partition *partTable=(struct partition *)
1222                                 (&boot.bytes[0x1ae]);
1223                         setBeginEnd(&partTable[1], 0,
1224                                                 used_dev.heads * used_dev.sectors * used_dev.tracks,
1225                                                 used_dev.heads, used_dev.sectors, 1, 0);
1226                 }
1227         }
1228         set_dword(boot.boot.nhs, used_dev.hidden);
1229
1230         Fs.Next = buf_init(Fs.Direct,
1231                            blocksize * used_dev.heads * used_dev.sectors,
1232                            blocksize * used_dev.heads * used_dev.sectors,
1233                            blocksize);
1234         Fs.Buffer = 0;
1235
1236         boot.boot.nfat = Fs.num_fat;
1237         if(!keepBoot)
1238                 set_word(&boot.bytes[510], 0xaa55);
1239
1240         /* Initialize the remaining parameters */
1241         set_word(boot.boot.nsect, used_dev.sectors);
1242         set_word(boot.boot.nheads, used_dev.heads);
1243
1244         used_dev.fat_bits = comp_fat_bits(&Fs,used_dev.fat_bits, tot_sectors, fat32);
1245
1246         if(used_dev.fat_bits == 32) {
1247                 Fs.primaryFat = 0;
1248                 Fs.writeAllFats = 1;
1249                 Fs.fat_start = 32;
1250                 calc_fs_parameters_32(tot_sectors, &Fs, &boot);
1251
1252                 Fs.clus_start = Fs.num_fat * Fs.fat_len + Fs.fat_start;
1253
1254                 /* extension flags: mirror fats, and use #0 as primary */
1255                 set_word(boot.boot.ext.fat32.extFlags,0);
1256
1257                 /* fs version.  What should go here? */
1258                 set_word(boot.boot.ext.fat32.fsVersion,fsVersion);
1259
1260                 /* root directory */
1261                 set_dword(boot.boot.ext.fat32.rootCluster, Fs.rootCluster = 2);
1262
1263                 /* info sector */
1264                 set_word(boot.boot.ext.fat32.infoSector, Fs.infoSectorLoc = 1);
1265                 Fs.infoSectorLoc = 1;
1266
1267                 /* no backup boot sector */
1268                 set_word(boot.boot.ext.fat32.backupBoot, backupBoot);
1269
1270                 labelBlock = & boot.boot.ext.fat32.labelBlock;
1271         } else {
1272                 Fs.infoSectorLoc = 0;
1273                 Fs.fat_start = 1;
1274                 calc_fs_parameters(&used_dev, tot_sectors, &Fs, &boot);
1275                 Fs.dir_start = Fs.num_fat * Fs.fat_len + Fs.fat_start;
1276                 Fs.clus_start = Fs.dir_start + Fs.dir_len;
1277                 labelBlock = & boot.boot.ext.old.labelBlock;
1278
1279         }
1280
1281         /* Set the codepage */
1282         Fs.cp = cp_open(used_dev.codepage);
1283         if(Fs.cp == NULL)
1284                 exit(1);
1285
1286         if (!keepBoot)
1287                 /* only zero out physdrive if we don't have a template
1288                  * bootsector */
1289                 labelBlock->physdrive = 0x00;
1290         labelBlock->reserved = 0;
1291         labelBlock->dos4 = 0x29;
1292
1293         if (!serial_set || Atari)
1294                 srandom((long)time (0));
1295         if (!serial_set)
1296                 serial=random();
1297         set_dword(labelBlock->serial, serial);
1298         label_name_pc(GET_DOSCONVERT((Stream_t *)&Fs),
1299                       label[0] ? label : "NO NAME    ", 0,
1300                       &mangled, &shortlabel);
1301         strncpy(labelBlock->label, shortlabel.base, 11);
1302         sprintf(labelBlock->fat_type, "FAT%2.2d  ", Fs.fat_bits);
1303         labelBlock->fat_type[7] = ' ';
1304
1305         set_word(boot.boot.secsiz, Fs.sector_size);
1306         boot.boot.clsiz = (unsigned char) Fs.cluster_size;
1307         set_word(boot.boot.nrsvsect, Fs.fat_start);
1308
1309         bootOffset = init_geometry_boot(&boot, &used_dev, sectors0,
1310                                         rate_0, rate_any,
1311                                         &tot_sectors, keepBoot);
1312         if(!bootOffset) {
1313                 bootOffset = ((unsigned char *) labelBlock) - boot.bytes +
1314                         sizeof(struct label_blk_t);
1315         }
1316         if(Atari) {
1317                 boot.boot.banner[4] = 0;
1318                 boot.boot.banner[5] = random();
1319                 boot.boot.banner[6] = random();
1320                 boot.boot.banner[7] = random();
1321         }
1322
1323         if(!keepBoot)
1324                 inst_boot_prg(&boot, bootOffset);
1325         /* Mimic 3.8 behavior, else 2m disk do not work (???)
1326          * luferbu@fluidsignal.com (Luis Bustamante), Fri, 14 Jun 2002
1327          */
1328         if(used_dev.use_2m & 0x7f) {
1329           boot.boot.jump[0] = 0xeb;
1330           boot.boot.jump[1] = 0x80;
1331           boot.boot.jump[2] = 0x90;
1332         }
1333         if(used_dev.use_2m & 0x7f)
1334                 Fs.num_fat = 1;
1335         if(mediaDesc != -1)
1336                 boot.boot.descr=mediaDesc;
1337         Fs.lastFatSectorNr = 0;
1338         Fs.lastFatSectorData = 0;
1339         zero_fat(&Fs, boot.boot.descr);
1340         Fs.freeSpace = Fs.num_clus;
1341         Fs.last = 2;
1342
1343 #ifdef USE_XDF
1344         if(format_xdf)
1345                 for(i=0;
1346                     i < (info.BadSectors+Fs.cluster_size-1)/Fs.cluster_size;
1347                     i++)
1348                         fatEncode(&Fs, i+2, 0xfff7);
1349 #endif
1350
1351         format_root(&Fs, label, &boot);
1352         WRITES((Stream_t *)&Fs, boot.characters,
1353                (mt_off_t) 0, Fs.sector_size);
1354
1355         if(used_dev.fat_bits == 32) {
1356           WRITES((Stream_t *)&Fs, boot.characters,
1357                  (mt_off_t) backupBoot * Fs.sector_size, Fs.sector_size);
1358         }
1359
1360         if(Fs.fat_bits == 32 && WORD_S(ext.fat32.backupBoot) != MAX16) {
1361                 WRITES((Stream_t *)&Fs, boot.characters,
1362                        sectorsToBytes((Stream_t*)&Fs,
1363                                       WORD_S(ext.fat32.backupBoot)),
1364                        Fs.sector_size);
1365         }
1366         FLUSH((Stream_t *)&Fs); /* flushes Fs.
1367                                  * This triggers the writing of the FAT */
1368         FREE(&Fs.Next);
1369         Fs.Class->freeFunc((Stream_t *)&Fs);
1370 #ifdef USE_XDF
1371         if(format_xdf && isatty(0) && !getenv("MTOOLS_USE_XDF"))
1372                 fprintf(stderr,
1373                         "Note:\n"
1374                         "Remember to set the \"MTOOLS_USE_XDF\" environmental\n"
1375                         "variable before accessing this disk\n\n"
1376                         "Bourne shell syntax (sh, ash, bash, ksh, zsh etc):\n"
1377                         " export MTOOLS_USE_XDF=1\n\n"
1378                         "C shell syntax (csh and tcsh):\n"
1379                         " setenv MTOOLS_USE_XDF 1\n" );
1380 #endif
1381         exit(0);
1382 }