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