• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* mkdosfs.c - utility to create FAT/MS-DOS filesystems
2 
3    Copyright (C) 1991 Linus Torvalds <torvalds@klaava.helsinki.fi>
4    Copyright (C) 1992-1993 Remy Card <card@masi.ibp.fr>
5    Copyright (C) 1993-1994 David Hudson <dave@humbug.demon.co.uk>
6    Copyright (C) 1998 H. Peter Anvin <hpa@zytor.com>
7    Copyright (C) 1998-2005 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
8 
9    This program is free software: you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation, either version 3 of the License, or
12    (at your option) any later version.
13 
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17    GNU General Public License for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program. If not, see <http://www.gnu.org/licenses/>.
21 
22    On Debian systems, the complete text of the GNU General Public License
23    can be found in /usr/share/common-licenses/GPL-3 file.
24 */
25 
26 /* Description: Utility to allow an MS-DOS filesystem to be created
27    under Linux.  A lot of the basic structure of this program has been
28    borrowed from Remy Card's "mke2fs" code.
29 
30    As far as possible the aim here is to make the "mkdosfs" command
31    look almost identical to the other Linux filesystem make utilties,
32    eg bad blocks are still specified as blocks, not sectors, but when
33    it comes down to it, DOS is tied to the idea of a sector (512 bytes
34    as a rule), and not the block.  For example the boot block does not
35    occupy a full cluster.
36 
37    Fixes/additions May 1998 by Roman Hodek
38    <Roman.Hodek@informatik.uni-erlangen.de>:
39    - Atari format support
40    - New options -A, -S, -C
41    - Support for filesystems > 2GB
42    - FAT32 support */
43 
44 /* Include the header files */
45 
46 #include "version.h"
47 
48 #include <fcntl.h>
49 #include <linux/hdreg.h>
50 #include <sys/mount.h>
51 #include <linux/fd.h>
52 #include <endian.h>
53 #include <mntent.h>
54 #include <signal.h>
55 #include <string.h>
56 #include <stdio.h>
57 #include <stdlib.h>
58 #include <sys/ioctl.h>
59 #include <sys/stat.h>
60 #include <sys/time.h>
61 #include <sys/types.h>
62 #include <unistd.h>
63 #include <time.h>
64 #include <errno.h>
65 
66 # include <asm/types.h>
67 
68 #if __BYTE_ORDER == __BIG_ENDIAN
69 
70 #include <asm/byteorder.h>
71 #ifdef __le16_to_cpu
72 /* ++roman: 2.1 kernel headers define these function, they're probably more
73  * efficient then coding the swaps machine-independently. */
74 #define CF_LE_W	__le16_to_cpu
75 #define CF_LE_L	__le32_to_cpu
76 #define CT_LE_W	__cpu_to_le16
77 #define CT_LE_L	__cpu_to_le32
78 #else
79 #define CF_LE_W(v) ((((v) & 0xff) << 8) | (((v) >> 8) & 0xff))
80 #define CF_LE_L(v) (((unsigned)(v)>>24) | (((unsigned)(v)>>8)&0xff00) | \
81                (((unsigned)(v)<<8)&0xff0000) | ((unsigned)(v)<<24))
82 #define CT_LE_W(v) CF_LE_W(v)
83 #define CT_LE_L(v) CF_LE_L(v)
84 #endif /* defined(__le16_to_cpu) */
85 
86 #else
87 
88 #define CF_LE_W(v) (v)
89 #define CF_LE_L(v) (v)
90 #define CT_LE_W(v) (v)
91 #define CT_LE_L(v) (v)
92 
93 #endif /* __BIG_ENDIAN */
94 
95 /* In earlier versions, an own llseek() was used, but glibc lseek() is
96  * sufficient (or even better :) for 64 bit offsets in the meantime */
97 #define llseek lseek
98 
99 /* Constant definitions */
100 
101 #define TRUE 1			/* Boolean constants */
102 #define FALSE 0
103 
104 #define TEST_BUFFER_BLOCKS 16
105 #define HARD_SECTOR_SIZE   512
106 #define SECTORS_PER_BLOCK ( BLOCK_SIZE / HARD_SECTOR_SIZE )
107 
108 
109 /* Macro definitions */
110 
111 /* Report a failure message and return a failure error code */
112 
113 #define die( str ) fatal_error( "%s: " str "\n" )
114 
115 
116 /* Mark a cluster in the FAT as bad */
117 
118 #define mark_sector_bad( sector ) mark_FAT_sector( sector, FAT_BAD )
119 
120 /* Compute ceil(a/b) */
121 
122 inline int
cdiv(int a,int b)123 cdiv (int a, int b)
124 {
125   return (a + b - 1) / b;
126 }
127 
128 /* MS-DOS filesystem structures -- I included them here instead of
129    including linux/msdos_fs.h since that doesn't include some fields we
130    need */
131 
132 #define ATTR_RO      1		/* read-only */
133 #define ATTR_HIDDEN  2		/* hidden */
134 #define ATTR_SYS     4		/* system */
135 #define ATTR_VOLUME  8		/* volume label */
136 #define ATTR_DIR     16		/* directory */
137 #define ATTR_ARCH    32		/* archived */
138 
139 #define ATTR_NONE    0		/* no attribute bits */
140 #define ATTR_UNUSED  (ATTR_VOLUME | ATTR_ARCH | ATTR_SYS | ATTR_HIDDEN)
141 	/* attribute bits that are copied "as is" */
142 
143 /* FAT values */
144 #define FAT_EOF      (atari_format ? 0x0fffffff : 0x0ffffff8)
145 #define FAT_BAD      0x0ffffff7
146 
147 #define MSDOS_EXT_SIGN 0x29	/* extended boot sector signature */
148 #define MSDOS_FAT12_SIGN "FAT12   "	/* FAT12 filesystem signature */
149 #define MSDOS_FAT16_SIGN "FAT16   "	/* FAT16 filesystem signature */
150 #define MSDOS_FAT32_SIGN "FAT32   "	/* FAT32 filesystem signature */
151 
152 #define BOOT_SIGN 0xAA55	/* Boot sector magic number */
153 
154 #define MAX_CLUST_12	((1 << 12) - 16)
155 #define MAX_CLUST_16	((1 << 16) - 16)
156 #define MIN_CLUST_32    65529
157 /* M$ says the high 4 bits of a FAT32 FAT entry are reserved and don't belong
158  * to the cluster number. So the max. cluster# is based on 2^28 */
159 #define MAX_CLUST_32	((1 << 28) - 16)
160 
161 #define FAT12_THRESHOLD	4085
162 
163 #define OLDGEMDOS_MAX_SECTORS	32765
164 #define GEMDOS_MAX_SECTORS	65531
165 #define GEMDOS_MAX_SECTOR_SIZE	(16*1024)
166 
167 #define BOOTCODE_SIZE		448
168 #define BOOTCODE_FAT32_SIZE	420
169 
170 /* __attribute__ ((packed)) is used on all structures to make gcc ignore any
171  * alignments */
172 
173 struct msdos_volume_info {
174   __u8		drive_number;	/* BIOS drive number */
175   __u8		RESERVED;	/* Unused */
176   __u8		ext_boot_sign;	/* 0x29 if fields below exist (DOS 3.3+) */
177   __u8		volume_id[4];	/* Volume ID number */
178   __u8		volume_label[11];/* Volume label */
179   __u8		fs_type[8];	/* Typically FAT12 or FAT16 */
180 } __attribute__ ((packed));
181 
182 struct msdos_boot_sector
183 {
184   __u8	        boot_jump[3];	/* Boot strap short or near jump */
185   __u8          system_id[8];	/* Name - can be used to special case
186 				   partition manager volumes */
187   __u8          sector_size[2];	/* bytes per logical sector */
188   __u8          cluster_size;	/* sectors/cluster */
189   __u16         reserved;	/* reserved sectors */
190   __u8          fats;		/* number of FATs */
191   __u8          dir_entries[2];	/* root directory entries */
192   __u8          sectors[2];	/* number of sectors */
193   __u8          media;		/* media code (unused) */
194   __u16         fat_length;	/* sectors/FAT */
195   __u16         secs_track;	/* sectors per track */
196   __u16         heads;		/* number of heads */
197   __u32         hidden;		/* hidden sectors (unused) */
198   __u32         total_sect;	/* number of sectors (if sectors == 0) */
199   union {
200     struct {
201       struct msdos_volume_info vi;
202       __u8	boot_code[BOOTCODE_SIZE];
203     } __attribute__ ((packed)) _oldfat;
204     struct {
205       __u32	fat32_length;	/* sectors/FAT */
206       __u16	flags;		/* bit 8: fat mirroring, low 4: active fat */
207       __u8	version[2];	/* major, minor filesystem version */
208       __u32	root_cluster;	/* first cluster in root directory */
209       __u16	info_sector;	/* filesystem info sector */
210       __u16	backup_boot;	/* backup boot sector */
211       __u16	reserved2[6];	/* Unused */
212       struct msdos_volume_info vi;
213       __u8	boot_code[BOOTCODE_FAT32_SIZE];
214     } __attribute__ ((packed)) _fat32;
215   } __attribute__ ((packed)) fstype;
216   __u16		boot_sign;
217 } __attribute__ ((packed));
218 #define fat32	fstype._fat32
219 #define oldfat	fstype._oldfat
220 
221 struct fat32_fsinfo {
222   __u32		reserved1;	/* Nothing as far as I can tell */
223   __u32		signature;	/* 0x61417272L */
224   __u32		free_clusters;	/* Free cluster count.  -1 if unknown */
225   __u32		next_cluster;	/* Most recently allocated cluster.
226 				 * Unused under Linux. */
227   __u32		reserved2[4];
228 };
229 
230 struct msdos_dir_entry
231   {
232     char	name[8], ext[3];	/* name and extension */
233     __u8        attr;			/* attribute bits */
234     __u8	lcase;			/* Case for base and extension */
235     __u8	ctime_ms;		/* Creation time, milliseconds */
236     __u16	ctime;			/* Creation time */
237     __u16	cdate;			/* Creation date */
238     __u16	adate;			/* Last access date */
239     __u16	starthi;		/* high 16 bits of first cl. (FAT32) */
240     __u16	time, date, start;	/* time, date and first cluster */
241     __u32	size;			/* file size (in bytes) */
242   } __attribute__ ((packed));
243 
244 /* The "boot code" we put into the filesystem... it writes a message and
245    tells the user to try again */
246 
247 char dummy_boot_jump[3] = { 0xeb, 0x3c, 0x90 };
248 
249 char dummy_boot_jump_m68k[2] = { 0x60, 0x1c };
250 
251 #define MSG_OFFSET_OFFSET 3
252 char dummy_boot_code[BOOTCODE_SIZE] =
253   "\x0e"			/* push cs */
254   "\x1f"			/* pop ds */
255   "\xbe\x5b\x7c"		/* mov si, offset message_txt */
256 				/* write_msg: */
257   "\xac"			/* lodsb */
258   "\x22\xc0"			/* and al, al */
259   "\x74\x0b"			/* jz key_press */
260   "\x56"			/* push si */
261   "\xb4\x0e"			/* mov ah, 0eh */
262   "\xbb\x07\x00"		/* mov bx, 0007h */
263   "\xcd\x10"			/* int 10h */
264   "\x5e"			/* pop si */
265   "\xeb\xf0"			/* jmp write_msg */
266 				/* key_press: */
267   "\x32\xe4"			/* xor ah, ah */
268   "\xcd\x16"			/* int 16h */
269   "\xcd\x19"			/* int 19h */
270   "\xeb\xfe"			/* foo: jmp foo */
271 				/* message_txt: */
272 
273   "This is not a bootable disk.  Please insert a bootable floppy and\r\n"
274   "press any key to try again ... \r\n";
275 
276 #define MESSAGE_OFFSET 29	/* Offset of message in above code */
277 
278 /* Global variables - the root of all evil :-) - see these and weep! */
279 
280 static char *program_name = "mkdosfs";	/* Name of the program */
281 static char *device_name = NULL;	/* Name of the device on which to create the filesystem */
282 static int atari_format = 0;	/* Use Atari variation of MS-DOS FS format */
283 static int check = FALSE;	/* Default to no readablity checking */
284 static int verbose = 0;		/* Default to verbose mode off */
285 static long volume_id;		/* Volume ID number */
286 static time_t create_time;	/* Creation time */
287 static struct timeval create_timeval;	/* Creation time */
288 static char volume_name[] = "           "; /* Volume name */
289 static unsigned long long blocks;	/* Number of blocks in filesystem */
290 static int sector_size = 512;	/* Size of a logical sector */
291 static int sector_size_set = 0; /* User selected sector size */
292 static int backup_boot = 0;	/* Sector# of backup boot sector */
293 static int reserved_sectors = 0;/* Number of reserved sectors */
294 static int badblocks = 0;	/* Number of bad blocks in the filesystem */
295 static int nr_fats = 2;		/* Default number of FATs to produce */
296 static int size_fat = 0;	/* Size in bits of FAT entries */
297 static int size_fat_by_user = 0; /* 1 if FAT size user selected */
298 static int dev = -1;		/* FS block device file handle */
299 static int  ignore_full_disk = 0; /* Ignore warning about 'full' disk devices */
300 static off_t currently_testing = 0;	/* Block currently being tested (if autodetect bad blocks) */
301 static struct msdos_boot_sector bs;	/* Boot sector data */
302 static int start_data_sector;	/* Sector number for the start of the data area */
303 static int start_data_block;	/* Block number for the start of the data area */
304 static unsigned char *fat;	/* File allocation table */
305 static unsigned char *info_sector;	/* FAT32 info sector */
306 static struct msdos_dir_entry *root_dir;	/* Root directory */
307 static int size_root_dir;	/* Size of the root directory in bytes */
308 static int sectors_per_cluster = 0;	/* Number of sectors per disk cluster */
309 static int root_dir_entries = 0;	/* Number of root directory entries */
310 static char *blank_sector;		/* Blank sector - all zeros */
311 static int hidden_sectors = 0;		/* Number of hidden sectors */
312 
313 
314 /* Function prototype definitions */
315 
316 static void fatal_error (const char *fmt_string) __attribute__((noreturn));
317 static void mark_FAT_cluster (int cluster, unsigned int value);
318 static void mark_FAT_sector (int sector, unsigned int value);
319 static long do_check (char *buffer, int try, off_t current_block);
320 static void alarm_intr (int alnum);
321 static void check_blocks (void);
322 static void get_list_blocks (char *filename);
323 static int valid_offset (int fd, loff_t offset);
324 static unsigned long long count_blocks (char *filename);
325 static void check_mount (char *device_name);
326 static void establish_params (int device_num, int size);
327 static void setup_tables (void);
328 static void write_tables (void);
329 
330 
331 /* The function implementations */
332 
333 /* Handle the reporting of fatal errors.  Volatile to let gcc know that this doesn't return */
334 
335 static void
fatal_error(const char * fmt_string)336 fatal_error (const char *fmt_string)
337 {
338   fprintf (stderr, fmt_string, program_name, device_name);
339   exit (1);			/* The error exit code is 1! */
340 }
341 
342 
343 /* Mark the specified cluster as having a particular value */
344 
345 static void
mark_FAT_cluster(int cluster,unsigned int value)346 mark_FAT_cluster (int cluster, unsigned int value)
347 {
348   switch( size_fat ) {
349     case 12:
350       value &= 0x0fff;
351       if (((cluster * 3) & 0x1) == 0)
352 	{
353 	  fat[3 * cluster / 2] = (unsigned char) (value & 0x00ff);
354 	  fat[(3 * cluster / 2) + 1] = (unsigned char) ((fat[(3 * cluster / 2) + 1] & 0x00f0)
355 						 | ((value & 0x0f00) >> 8));
356 	}
357       else
358 	{
359 	  fat[3 * cluster / 2] = (unsigned char) ((fat[3 * cluster / 2] & 0x000f) | ((value & 0x000f) << 4));
360 	  fat[(3 * cluster / 2) + 1] = (unsigned char) ((value & 0x0ff0) >> 4);
361 	}
362       break;
363 
364     case 16:
365       value &= 0xffff;
366       fat[2 * cluster] = (unsigned char) (value & 0x00ff);
367       fat[(2 * cluster) + 1] = (unsigned char) (value >> 8);
368       break;
369 
370     case 32:
371       value &= 0xfffffff;
372       fat[4 * cluster] =       (unsigned char)  (value & 0x000000ff);
373       fat[(4 * cluster) + 1] = (unsigned char) ((value & 0x0000ff00) >> 8);
374       fat[(4 * cluster) + 2] = (unsigned char) ((value & 0x00ff0000) >> 16);
375       fat[(4 * cluster) + 3] = (unsigned char) ((value & 0xff000000) >> 24);
376       break;
377 
378     default:
379       die("Bad FAT size (not 12, 16, or 32)");
380   }
381 }
382 
383 
384 /* Mark a specified sector as having a particular value in it's FAT entry */
385 
386 static void
mark_FAT_sector(int sector,unsigned int value)387 mark_FAT_sector (int sector, unsigned int value)
388 {
389   int cluster;
390 
391   cluster = (sector - start_data_sector) / (int) (bs.cluster_size) /
392 	    (sector_size/HARD_SECTOR_SIZE);
393   if (cluster < 0)
394     die ("Invalid cluster number in mark_FAT_sector: probably bug!");
395 
396   mark_FAT_cluster (cluster, value);
397 }
398 
399 
400 /* Perform a test on a block.  Return the number of blocks that could be read successfully */
401 
402 static long
do_check(char * buffer,int try,off_t current_block)403 do_check (char *buffer, int try, off_t current_block)
404 {
405   long got;
406 
407   if (llseek (dev, current_block * BLOCK_SIZE, SEEK_SET) /* Seek to the correct location */
408       != current_block * BLOCK_SIZE)
409     die ("seek failed during testing for blocks");
410 
411   got = read (dev, buffer, try * BLOCK_SIZE);	/* Try reading! */
412   if (got < 0)
413     got = 0;
414 
415   if (got & (BLOCK_SIZE - 1))
416     printf ("Unexpected values in do_check: probably bugs\n");
417   got /= BLOCK_SIZE;
418 
419   return got;
420 }
421 
422 
423 /* Alarm clock handler - display the status of the quest for bad blocks!  Then retrigger the alarm for five senconds
424    later (so we can come here again) */
425 
426 static void
alarm_intr(int alnum)427 alarm_intr (int alnum)
428 {
429   if (currently_testing >= blocks)
430     return;
431 
432   signal (SIGALRM, alarm_intr);
433   alarm (5);
434   if (!currently_testing)
435     return;
436 
437   printf ("%lld... ", (unsigned long long)currently_testing);
438   fflush (stdout);
439 }
440 
441 
442 static void
check_blocks(void)443 check_blocks (void)
444 {
445   int try, got;
446   int i;
447   static char blkbuf[BLOCK_SIZE * TEST_BUFFER_BLOCKS];
448 
449   if (verbose)
450     {
451       printf ("Searching for bad blocks ");
452       fflush (stdout);
453     }
454   currently_testing = 0;
455   if (verbose)
456     {
457       signal (SIGALRM, alarm_intr);
458       alarm (5);
459     }
460   try = TEST_BUFFER_BLOCKS;
461   while (currently_testing < blocks)
462     {
463       if (currently_testing + try > blocks)
464 	try = blocks - currently_testing;
465       got = do_check (blkbuf, try, currently_testing);
466       currently_testing += got;
467       if (got == try)
468 	{
469 	  try = TEST_BUFFER_BLOCKS;
470 	  continue;
471 	}
472       else
473 	try = 1;
474       if (currently_testing < start_data_block)
475 	die ("bad blocks before data-area: cannot make fs");
476 
477       for (i = 0; i < SECTORS_PER_BLOCK; i++)	/* Mark all of the sectors in the block as bad */
478 	mark_sector_bad (currently_testing * SECTORS_PER_BLOCK + i);
479       badblocks++;
480       currently_testing++;
481     }
482 
483   if (verbose)
484     printf ("\n");
485 
486   if (badblocks)
487     printf ("%d bad block%s\n", badblocks,
488 	    (badblocks > 1) ? "s" : "");
489 }
490 
491 
492 static void
get_list_blocks(char * filename)493 get_list_blocks (char *filename)
494 {
495   int i;
496   FILE *listfile;
497   unsigned long blockno;
498 
499   listfile = fopen (filename, "r");
500   if (listfile == (FILE *) NULL)
501     die ("Can't open file of bad blocks");
502 
503   while (!feof (listfile))
504     {
505       fscanf (listfile, "%ld\n", &blockno);
506       for (i = 0; i < SECTORS_PER_BLOCK; i++)	/* Mark all of the sectors in the block as bad */
507 	mark_sector_bad (blockno * SECTORS_PER_BLOCK + i);
508       badblocks++;
509     }
510   fclose (listfile);
511 
512   if (badblocks)
513     printf ("%d bad block%s\n", badblocks,
514 	    (badblocks > 1) ? "s" : "");
515 }
516 
517 
518 /* Given a file descriptor and an offset, check whether the offset is a valid offset for the file - return FALSE if it
519    isn't valid or TRUE if it is */
520 
521 static int
valid_offset(int fd,loff_t offset)522 valid_offset (int fd, loff_t offset)
523 {
524   char ch;
525 
526   if (llseek (fd, offset, SEEK_SET) < 0)
527     return FALSE;
528   if (read (fd, &ch, 1) < 1)
529     return FALSE;
530   return TRUE;
531 }
532 
533 
534 /* Given a filename, look to see how many blocks of BLOCK_SIZE are present, returning the answer */
535 
536 static unsigned long long
count_blocks(char * filename)537 count_blocks (char *filename)
538 {
539   off_t high, low;
540   int fd;
541 
542   if ((fd = open (filename, O_RDONLY)) < 0)
543     {
544       perror (filename);
545       exit (1);
546     }
547 
548   /* first try SEEK_END, which should work on most devices nowadays */
549   if ((low = llseek(fd, 0, SEEK_END)) <= 0) {
550       low = 0;
551       for (high = 1; valid_offset (fd, high); high *= 2)
552 	  low = high;
553       while (low < high - 1) {
554 	  const loff_t mid = (low + high) / 2;
555 	  if (valid_offset (fd, mid))
556 	      low = mid;
557 	  else
558 	      high = mid;
559       }
560       ++low;
561   }
562 
563   close (fd);
564   return low / BLOCK_SIZE;
565 }
566 
567 
568 /* Check to see if the specified device is currently mounted - abort if it is */
569 
570 static void
check_mount(char * device_name)571 check_mount (char *device_name)
572 {
573   FILE *f;
574   struct mntent *mnt;
575 
576   if ((f = setmntent (MOUNTED, "r")) == NULL)
577     return;
578   while ((mnt = getmntent (f)) != NULL)
579     if (strcmp (device_name, mnt->mnt_fsname) == 0)
580       die ("%s contains a mounted file system.");
581   endmntent (f);
582 }
583 
584 
585 /* Establish the geometry and media parameters for the device */
586 
587 static void
establish_params(int device_num,int size)588 establish_params (int device_num,int size)
589 {
590   long loop_size;
591   struct hd_geometry geometry;
592   struct floppy_struct param;
593 
594   if ((0 == device_num) || ((device_num & 0xff00) == 0x0200))
595     /* file image or floppy disk */
596     {
597       if (0 == device_num)
598 	{
599 	  param.size = size/512;
600 	  switch(param.size)
601 	    {
602 	    case 720:
603 	      param.sect = 9 ;
604 	      param.head = 2;
605 	      break;
606 	    case 1440:
607 	      param.sect = 9;
608 	      param.head = 2;
609 	      break;
610 	    case 2400:
611 	      param.sect = 15;
612 	      param.head = 2;
613 	      break;
614 	    case 2880:
615 	      param.sect = 18;
616 	      param.head = 2;
617 	      break;
618 	    case 5760:
619 	      param.sect = 36;
620 	      param.head = 2;
621 	      break;
622 	    default:
623 	      /* fake values */
624 	      param.sect = 32;
625 	      param.head = 64;
626 	      break;
627 	    }
628 
629 	}
630       else 	/* is a floppy diskette */
631 	{
632 	  if (ioctl (dev, FDGETPRM, &param))	/*  Can we get the diskette geometry? */
633 	    die ("unable to get diskette geometry for '%s'");
634 	}
635       bs.secs_track = CT_LE_W(param.sect);	/*  Set up the geometry information */
636       bs.heads = CT_LE_W(param.head);
637       switch (param.size)	/*  Set up the media descriptor byte */
638 	{
639 	case 720:		/* 5.25", 2, 9, 40 - 360K */
640 	  bs.media = (char) 0xfd;
641 	  bs.cluster_size = (char) 2;
642 	  bs.dir_entries[0] = (char) 112;
643 	  bs.dir_entries[1] = (char) 0;
644 	  break;
645 
646 	case 1440:		/* 3.5", 2, 9, 80 - 720K */
647 	  bs.media = (char) 0xf9;
648 	  bs.cluster_size = (char) 2;
649 	  bs.dir_entries[0] = (char) 112;
650 	  bs.dir_entries[1] = (char) 0;
651 	  break;
652 
653 	case 2400:		/* 5.25", 2, 15, 80 - 1200K */
654 	  bs.media = (char) 0xf9;
655 	  bs.cluster_size = (char)(atari_format ? 2 : 1);
656 	  bs.dir_entries[0] = (char) 224;
657 	  bs.dir_entries[1] = (char) 0;
658 	  break;
659 
660 	case 5760:		/* 3.5", 2, 36, 80 - 2880K */
661 	  bs.media = (char) 0xf0;
662 	  bs.cluster_size = (char) 2;
663 	  bs.dir_entries[0] = (char) 224;
664 	  bs.dir_entries[1] = (char) 0;
665 	  break;
666 
667 	case 2880:		/* 3.5", 2, 18, 80 - 1440K */
668 	floppy_default:
669 	  bs.media = (char) 0xf0;
670 	  bs.cluster_size = (char)(atari_format ? 2 : 1);
671 	  bs.dir_entries[0] = (char) 224;
672 	  bs.dir_entries[1] = (char) 0;
673 	  break;
674 
675 	default:		/* Anything else */
676 	  if (0 == device_num)
677 	      goto def_hd_params;
678 	  else
679 	      goto floppy_default;
680 	}
681     }
682   else if ((device_num & 0xff00) == 0x0700) /* This is a loop device */
683     {
684       if (ioctl (dev, BLKGETSIZE, &loop_size))
685 	die ("unable to get loop device size");
686 
687       switch (loop_size)  /* Assuming the loop device -> floppy later */
688 	{
689 	case 720:		/* 5.25", 2, 9, 40 - 360K */
690 	  bs.secs_track = CF_LE_W(9);
691 	  bs.heads = CF_LE_W(2);
692 	  bs.media = (char) 0xfd;
693 	  bs.cluster_size = (char) 2;
694 	  bs.dir_entries[0] = (char) 112;
695 	  bs.dir_entries[1] = (char) 0;
696 	  break;
697 
698 	case 1440:		/* 3.5", 2, 9, 80 - 720K */
699 	  bs.secs_track = CF_LE_W(9);
700 	  bs.heads = CF_LE_W(2);
701 	  bs.media = (char) 0xf9;
702 	  bs.cluster_size = (char) 2;
703 	  bs.dir_entries[0] = (char) 112;
704 	  bs.dir_entries[1] = (char) 0;
705 	  break;
706 
707 	case 2400:		/* 5.25", 2, 15, 80 - 1200K */
708 	  bs.secs_track = CF_LE_W(15);
709 	  bs.heads = CF_LE_W(2);
710 	  bs.media = (char) 0xf9;
711 	  bs.cluster_size = (char)(atari_format ? 2 : 1);
712 	  bs.dir_entries[0] = (char) 224;
713 	  bs.dir_entries[1] = (char) 0;
714 	  break;
715 
716 	case 5760:		/* 3.5", 2, 36, 80 - 2880K */
717 	  bs.secs_track = CF_LE_W(36);
718 	  bs.heads = CF_LE_W(2);
719 	  bs.media = (char) 0xf0;
720 	  bs.cluster_size = (char) 2;
721 	  bs.dir_entries[0] = (char) 224;
722 	  bs.dir_entries[1] = (char) 0;
723 	  break;
724 
725 	case 2880:		/* 3.5", 2, 18, 80 - 1440K */
726 	  bs.secs_track = CF_LE_W(18);
727 	  bs.heads = CF_LE_W(2);
728 	  bs.media = (char) 0xf0;
729 	  bs.cluster_size = (char)(atari_format ? 2 : 1);
730 	  bs.dir_entries[0] = (char) 224;
731 	  bs.dir_entries[1] = (char) 0;
732 	  break;
733 
734 	default:		/* Anything else: default hd setup */
735 	  printf("Loop device does not match a floppy size, using "
736 		 "default hd params\n");
737 	  bs.secs_track = CT_LE_W(32); /* these are fake values... */
738 	  bs.heads = CT_LE_W(64);
739 	  goto def_hd_params;
740 	}
741     }
742   else
743     /* Must be a hard disk then! */
744     {
745       /* Can we get the drive geometry? (Note I'm not too sure about */
746       /* whether to use HDIO_GETGEO or HDIO_REQ) */
747       if (ioctl (dev, HDIO_GETGEO, &geometry) || geometry.sectors == 0 || geometry.heads == 0) {
748 	printf ("unable to get drive geometry, using default 255/63\n");
749         bs.secs_track = CT_LE_W(63);
750         bs.heads = CT_LE_W(255);
751       }
752       else {
753         bs.secs_track = CT_LE_W(geometry.sectors);	/* Set up the geometry information */
754         bs.heads = CT_LE_W(geometry.heads);
755       }
756     def_hd_params:
757       bs.media = (char) 0xf8; /* Set up the media descriptor for a hard drive */
758       bs.dir_entries[0] = (char) 0;	/* Default to 512 entries */
759       bs.dir_entries[1] = (char) 2;
760       if (!size_fat && blocks*SECTORS_PER_BLOCK > 1064960) {
761 	  if (verbose) printf("Auto-selecting FAT32 for large filesystem\n");
762 	  size_fat = 32;
763       }
764       if (size_fat == 32) {
765 	  /* For FAT32, try to do the same as M$'s format command
766 	   * (see http://www.win.tue.nl/~aeb/linux/fs/fat/fatgen103.pdf p. 20):
767 	   * fs size <= 260M: 0.5k clusters
768 	   * fs size <=   8G: 4k clusters
769 	   * fs size <=  16G: 8k clusters
770 	   * fs size >   16G: 16k clusters
771 	   */
772 	  unsigned long sz_mb =
773 	      (blocks+(1<<(20-BLOCK_SIZE_BITS))-1) >> (20-BLOCK_SIZE_BITS);
774 	  bs.cluster_size = sz_mb > 16*1024 ? 32 :
775 			    sz_mb >  8*1024 ? 16 :
776 			    sz_mb >     260 ?  8 :
777 					       1;
778       }
779       else {
780 	  /* FAT12 and FAT16: start at 4 sectors per cluster */
781 	  bs.cluster_size = (char) 4;
782       }
783     }
784 }
785 
786 
787 /* Create the filesystem data tables */
788 
789 static void
setup_tables(void)790 setup_tables (void)
791 {
792   unsigned num_sectors;
793   unsigned cluster_count = 0, fat_length;
794   unsigned fatdata;			/* Sectors for FATs + data area */
795   struct tm *ctime;
796   struct msdos_volume_info *vi = (size_fat == 32 ? &bs.fat32.vi : &bs.oldfat.vi);
797 
798   if (atari_format)
799       /* On Atari, the first few bytes of the boot sector are assigned
800        * differently: The jump code is only 2 bytes (and m68k machine code
801        * :-), then 6 bytes filler (ignored), then 3 byte serial number. */
802     memcpy( bs.system_id-1, "mkdosf", 6 );
803   else
804     strcpy (bs.system_id, "mkdosfs");
805   if (sectors_per_cluster)
806     bs.cluster_size = (char) sectors_per_cluster;
807   if (size_fat == 32)
808     {
809       /* Under FAT32, the root dir is in a cluster chain, and this is
810        * signalled by bs.dir_entries being 0. */
811       bs.dir_entries[0] = bs.dir_entries[1] = (char) 0;
812       root_dir_entries = 0;
813     }
814   else if (root_dir_entries)
815     {
816       /* Override default from establish_params() */
817       bs.dir_entries[0] = (char) (root_dir_entries & 0x00ff);
818       bs.dir_entries[1] = (char) ((root_dir_entries & 0xff00) >> 8);
819     }
820   else
821     root_dir_entries = bs.dir_entries[0] + (bs.dir_entries[1] << 8);
822 
823   if (atari_format) {
824     bs.system_id[5] = (unsigned char) (volume_id & 0x000000ff);
825     bs.system_id[6] = (unsigned char) ((volume_id & 0x0000ff00) >> 8);
826     bs.system_id[7] = (unsigned char) ((volume_id & 0x00ff0000) >> 16);
827   }
828   else {
829     vi->volume_id[0] = (unsigned char) (volume_id & 0x000000ff);
830     vi->volume_id[1] = (unsigned char) ((volume_id & 0x0000ff00) >> 8);
831     vi->volume_id[2] = (unsigned char) ((volume_id & 0x00ff0000) >> 16);
832     vi->volume_id[3] = (unsigned char) (volume_id >> 24);
833   }
834 
835   if (!atari_format) {
836     memcpy(vi->volume_label, volume_name, 11);
837 
838     memcpy(bs.boot_jump, dummy_boot_jump, 3);
839     /* Patch in the correct offset to the boot code */
840     bs.boot_jump[1] = ((size_fat == 32 ?
841 			(char *)&bs.fat32.boot_code :
842 			(char *)&bs.oldfat.boot_code) -
843 		       (char *)&bs) - 2;
844 
845     if (size_fat == 32) {
846 	int offset = (char *)&bs.fat32.boot_code -
847 		     (char *)&bs + MESSAGE_OFFSET + 0x7c00;
848 	if (dummy_boot_code[BOOTCODE_FAT32_SIZE-1])
849 	  printf ("Warning: message too long; truncated\n");
850 	dummy_boot_code[BOOTCODE_FAT32_SIZE-1] = 0;
851 	memcpy(bs.fat32.boot_code, dummy_boot_code, BOOTCODE_FAT32_SIZE);
852 	bs.fat32.boot_code[MSG_OFFSET_OFFSET] = offset & 0xff;
853 	bs.fat32.boot_code[MSG_OFFSET_OFFSET+1] = offset >> 8;
854     }
855     else {
856 	memcpy(bs.oldfat.boot_code, dummy_boot_code, BOOTCODE_SIZE);
857     }
858     bs.boot_sign = CT_LE_W(BOOT_SIGN);
859   }
860   else {
861     memcpy(bs.boot_jump, dummy_boot_jump_m68k, 2);
862   }
863   if (verbose >= 2)
864     printf( "Boot jump code is %02x %02x\n",
865 	    bs.boot_jump[0], bs.boot_jump[1] );
866 
867   if (!reserved_sectors)
868       reserved_sectors = (size_fat == 32) ? 32 : 1;
869   else {
870       if (size_fat == 32 && reserved_sectors < 2)
871 	  die("On FAT32 at least 2 reserved sectors are needed.");
872   }
873   bs.reserved = CT_LE_W(reserved_sectors);
874   if (verbose >= 2)
875     printf( "Using %d reserved sectors\n", reserved_sectors );
876   bs.fats = (char) nr_fats;
877   if (!atari_format || size_fat == 32)
878     bs.hidden = CT_LE_L(hidden_sectors);
879   else {
880     /* In Atari format, hidden is a 16 bit field */
881     __u16 hidden = CT_LE_W(hidden_sectors);
882     if (hidden_sectors & ~0xffff)
883       die("#hidden doesn't fit in 16bit field of Atari format\n");
884     memcpy( &bs.hidden, &hidden, 2 );
885   }
886 
887   num_sectors = (long long)blocks*BLOCK_SIZE/sector_size;
888   if (!atari_format) {
889     unsigned fatlength12, fatlength16, fatlength32;
890     unsigned maxclust12, maxclust16, maxclust32;
891     unsigned clust12, clust16, clust32;
892     int maxclustsize;
893 
894     fatdata = num_sectors - cdiv (root_dir_entries * 32, sector_size) -
895 	      reserved_sectors;
896 
897     if (sectors_per_cluster)
898       bs.cluster_size = maxclustsize = sectors_per_cluster;
899     else
900       /* An initial guess for bs.cluster_size should already be set */
901       maxclustsize = 128;
902 
903     if (verbose >= 2)
904       printf( "%d sectors for FAT+data, starting with %d sectors/cluster\n",
905 	      fatdata, bs.cluster_size );
906     do {
907       if (verbose >= 2)
908 	printf( "Trying with %d sectors/cluster:\n", bs.cluster_size );
909 
910       /* The factor 2 below avoids cut-off errors for nr_fats == 1.
911        * The "nr_fats*3" is for the reserved first two FAT entries */
912       clust12 = 2*((long long) fatdata *sector_size + nr_fats*3) /
913 	(2*(int) bs.cluster_size * sector_size + nr_fats*3);
914       fatlength12 = cdiv (((clust12+2) * 3 + 1) >> 1, sector_size);
915       /* Need to recalculate number of clusters, since the unused parts of the
916        * FATS and data area together could make up space for an additional,
917        * not really present cluster. */
918       clust12 = (fatdata - nr_fats*fatlength12)/bs.cluster_size;
919       maxclust12 = (fatlength12 * 2 * sector_size) / 3;
920       if (maxclust12 > MAX_CLUST_12)
921 	maxclust12 = MAX_CLUST_12;
922       if (verbose >= 2)
923 	printf( "FAT12: #clu=%u, fatlen=%u, maxclu=%u, limit=%u\n",
924 		clust12, fatlength12, maxclust12, MAX_CLUST_12 );
925       if (clust12 > maxclust12-2) {
926 	clust12 = 0;
927 	if (verbose >= 2)
928 	  printf( "FAT12: too much clusters\n" );
929       }
930 
931       clust16 = ((long long) fatdata *sector_size + nr_fats*4) /
932 	((int) bs.cluster_size * sector_size + nr_fats*2);
933       fatlength16 = cdiv ((clust16+2) * 2, sector_size);
934       /* Need to recalculate number of clusters, since the unused parts of the
935        * FATS and data area together could make up space for an additional,
936        * not really present cluster. */
937       clust16 = (fatdata - nr_fats*fatlength16)/bs.cluster_size;
938       maxclust16 = (fatlength16 * sector_size) / 2;
939       if (maxclust16 > MAX_CLUST_16)
940 	maxclust16 = MAX_CLUST_16;
941       if (verbose >= 2)
942 	printf( "FAT16: #clu=%u, fatlen=%u, maxclu=%u, limit=%u\n",
943 		clust16, fatlength16, maxclust16, MAX_CLUST_16 );
944       if (clust16 > maxclust16-2) {
945 	if (verbose >= 2)
946 	  printf( "FAT16: too much clusters\n" );
947 	clust16 = 0;
948       }
949       /* The < 4078 avoids that the filesystem will be misdetected as having a
950        * 12 bit FAT. */
951       if (clust16 < FAT12_THRESHOLD && !(size_fat_by_user && size_fat == 16)) {
952 	if (verbose >= 2)
953 	  printf( clust16 < FAT12_THRESHOLD ?
954 		  "FAT16: would be misdetected as FAT12\n" :
955 		  "FAT16: too much clusters\n" );
956 	clust16 = 0;
957       }
958 
959       clust32 = ((long long) fatdata *sector_size + nr_fats*8) /
960 	((int) bs.cluster_size * sector_size + nr_fats*4);
961       fatlength32 = cdiv ((clust32+2) * 4, sector_size);
962       /* Need to recalculate number of clusters, since the unused parts of the
963        * FATS and data area together could make up space for an additional,
964        * not really present cluster. */
965       clust32 = (fatdata - nr_fats*fatlength32)/bs.cluster_size;
966       maxclust32 = (fatlength32 * sector_size) / 4;
967       if (maxclust32 > MAX_CLUST_32)
968 	maxclust32 = MAX_CLUST_32;
969       if (clust32 && clust32 < MIN_CLUST_32 && !(size_fat_by_user && size_fat == 32)) {
970        clust32 = 0;
971        if (verbose >= 2)
972          printf( "FAT32: not enough clusters (%d)\n", MIN_CLUST_32);
973       }
974       if (verbose >= 2)
975 	printf( "FAT32: #clu=%u, fatlen=%u, maxclu=%u, limit=%u\n",
976 		clust32, fatlength32, maxclust32, MAX_CLUST_32 );
977       if (clust32 > maxclust32) {
978 	clust32 = 0;
979 	if (verbose >= 2)
980 	  printf( "FAT32: too much clusters\n" );
981       }
982 
983       if ((clust12 && (size_fat == 0 || size_fat == 12)) ||
984 	  (clust16 && (size_fat == 0 || size_fat == 16)) ||
985 	  (clust32 && size_fat == 32))
986 	break;
987 
988       bs.cluster_size <<= 1;
989     } while (bs.cluster_size && bs.cluster_size <= maxclustsize);
990 
991     /* Use the optimal FAT size if not specified;
992      * FAT32 is (not yet) choosen automatically */
993     if (!size_fat) {
994 	size_fat = (clust16 > clust12) ? 16 : 12;
995 	if (verbose >= 2)
996 	  printf( "Choosing %d bits for FAT\n", size_fat );
997     }
998 
999     switch (size_fat) {
1000       case 12:
1001 	cluster_count = clust12;
1002 	fat_length = fatlength12;
1003 	bs.fat_length = CT_LE_W(fatlength12);
1004 	memcpy(vi->fs_type, MSDOS_FAT12_SIGN, 8);
1005 	break;
1006 
1007       case 16:
1008 	if (clust16 < FAT12_THRESHOLD) {
1009 	    if (size_fat_by_user) {
1010 		fprintf( stderr, "WARNING: Not enough clusters for a "
1011 			 "16 bit FAT! The filesystem will be\n"
1012 			 "misinterpreted as having a 12 bit FAT without "
1013 			 "mount option \"fat=16\".\n" );
1014 	    }
1015 	    else {
1016 		fprintf( stderr, "This filesystem has an unfortunate size. "
1017 			 "A 12 bit FAT cannot provide\n"
1018 			 "enough clusters, but a 16 bit FAT takes up a little "
1019 			 "bit more space so that\n"
1020 			 "the total number of clusters becomes less than the "
1021 			 "threshold value for\n"
1022 			 "distinction between 12 and 16 bit FATs.\n" );
1023 		die( "Make the file system a bit smaller manually." );
1024 	    }
1025 	}
1026 	cluster_count = clust16;
1027 	fat_length = fatlength16;
1028 	bs.fat_length = CT_LE_W(fatlength16);
1029 	memcpy(vi->fs_type, MSDOS_FAT16_SIGN, 8);
1030 	break;
1031 
1032       case 32:
1033 	if (clust32 < MIN_CLUST_32)
1034 	  fprintf(stderr, "WARNING: Not enough clusters for a 32 bit FAT!\n");
1035 	cluster_count = clust32;
1036 	fat_length = fatlength32;
1037 	bs.fat_length = CT_LE_W(0);
1038 	bs.fat32.fat32_length = CT_LE_L(fatlength32);
1039 	memcpy(vi->fs_type, MSDOS_FAT32_SIGN, 8);
1040 	break;
1041 
1042       default:
1043 	die("FAT not 12, 16 or 32 bits");
1044     }
1045   }
1046   else {
1047     unsigned clusters, maxclust;
1048 
1049     /* GEMDOS always uses a 12 bit FAT on floppies, and always a 16 bit FAT on
1050      * hard disks. So use 12 bit if the size of the file system suggests that
1051      * this fs is for a floppy disk, if the user hasn't explicitly requested a
1052      * size.
1053      */
1054     if (!size_fat)
1055       size_fat = (num_sectors == 1440 || num_sectors == 2400 ||
1056 		  num_sectors == 2880 || num_sectors == 5760) ? 12 : 16;
1057     if (verbose >= 2)
1058       printf( "Choosing %d bits for FAT\n", size_fat );
1059 
1060     /* Atari format: cluster size should be 2, except explicitly requested by
1061      * the user, since GEMDOS doesn't like other cluster sizes very much.
1062      * Instead, tune the sector size for the FS to fit.
1063      */
1064     bs.cluster_size = sectors_per_cluster ? sectors_per_cluster : 2;
1065     if (!sector_size_set) {
1066       while( num_sectors > GEMDOS_MAX_SECTORS ) {
1067 	num_sectors >>= 1;
1068 	sector_size <<= 1;
1069       }
1070     }
1071     if (verbose >= 2)
1072       printf( "Sector size must be %d to have less than %d log. sectors\n",
1073 	      sector_size, GEMDOS_MAX_SECTORS );
1074 
1075     /* Check if there are enough FAT indices for how much clusters we have */
1076     do {
1077       fatdata = num_sectors - cdiv (root_dir_entries * 32, sector_size) -
1078 		reserved_sectors;
1079       /* The factor 2 below avoids cut-off errors for nr_fats == 1 and
1080        * size_fat == 12
1081        * The "2*nr_fats*size_fat/8" is for the reserved first two FAT entries
1082        */
1083       clusters = (2*((long long)fatdata*sector_size - 2*nr_fats*size_fat/8)) /
1084 		 (2*((int)bs.cluster_size*sector_size + nr_fats*size_fat/8));
1085       fat_length = cdiv( (clusters+2)*size_fat/8, sector_size );
1086       /* Need to recalculate number of clusters, since the unused parts of the
1087        * FATS and data area together could make up space for an additional,
1088        * not really present cluster. */
1089       clusters = (fatdata - nr_fats*fat_length)/bs.cluster_size;
1090       maxclust = (fat_length*sector_size*8)/size_fat;
1091       if (verbose >= 2)
1092 	printf( "ss=%d: #clu=%d, fat_len=%d, maxclu=%d\n",
1093 		sector_size, clusters, fat_length, maxclust );
1094 
1095       /* last 10 cluster numbers are special (except FAT32: 4 high bits rsvd);
1096        * first two numbers are reserved */
1097       if (maxclust <= (size_fat == 32 ? MAX_CLUST_32 : (1<<size_fat)-0x10) &&
1098 	  clusters <= maxclust-2)
1099 	break;
1100       if (verbose >= 2)
1101 	printf( clusters > maxclust-2 ?
1102 		"Too many clusters\n" : "FAT too big\n" );
1103 
1104       /* need to increment sector_size once more to  */
1105       if (sector_size_set)
1106 	  die( "With this sector size, the maximum number of FAT entries "
1107 	       "would be exceeded." );
1108       num_sectors >>= 1;
1109       sector_size <<= 1;
1110     } while( sector_size <= GEMDOS_MAX_SECTOR_SIZE );
1111 
1112     if (sector_size > GEMDOS_MAX_SECTOR_SIZE)
1113       die( "Would need a sector size > 16k, which GEMDOS can't work with");
1114 
1115     cluster_count = clusters;
1116     if (size_fat != 32)
1117 	bs.fat_length = CT_LE_W(fat_length);
1118     else {
1119 	bs.fat_length = 0;
1120 	bs.fat32.fat32_length = CT_LE_L(fat_length);
1121     }
1122   }
1123 
1124   bs.sector_size[0] = (char) (sector_size & 0x00ff);
1125   bs.sector_size[1] = (char) ((sector_size & 0xff00) >> 8);
1126 
1127   if (size_fat == 32)
1128     {
1129       /* set up additional FAT32 fields */
1130       bs.fat32.flags = CT_LE_W(0);
1131       bs.fat32.version[0] = 0;
1132       bs.fat32.version[1] = 0;
1133       bs.fat32.root_cluster = CT_LE_L(2);
1134       bs.fat32.info_sector = CT_LE_W(1);
1135       if (!backup_boot)
1136 	backup_boot = (reserved_sectors >= 7) ? 6 :
1137 		      (reserved_sectors >= 2) ? reserved_sectors-1 : 0;
1138       else
1139 	{
1140 	  if (backup_boot == 1)
1141 	    die("Backup boot sector must be after sector 1");
1142 	  else if (backup_boot >= reserved_sectors)
1143 	    die("Backup boot sector must be a reserved sector");
1144 	}
1145       if (verbose >= 2)
1146 	printf( "Using sector %d as backup boot sector (0 = none)\n",
1147 		backup_boot );
1148       bs.fat32.backup_boot = CT_LE_W(backup_boot);
1149       memset( &bs.fat32.reserved2, 0, sizeof(bs.fat32.reserved2) );
1150     }
1151 
1152   if (atari_format) {
1153       /* Just some consistency checks */
1154       if (num_sectors >= GEMDOS_MAX_SECTORS)
1155 	  die( "GEMDOS can't handle more than 65531 sectors" );
1156       else if (num_sectors >= OLDGEMDOS_MAX_SECTORS)
1157 	  printf( "Warning: More than 32765 sector need TOS 1.04 "
1158 		  "or higher.\n" );
1159   }
1160   if (num_sectors >= 65536)
1161     {
1162       bs.sectors[0] = (char) 0;
1163       bs.sectors[1] = (char) 0;
1164       bs.total_sect = CT_LE_L(num_sectors);
1165     }
1166   else
1167     {
1168       bs.sectors[0] = (char) (num_sectors & 0x00ff);
1169       bs.sectors[1] = (char) ((num_sectors & 0xff00) >> 8);
1170       if (!atari_format)
1171 	  bs.total_sect = CT_LE_L(0);
1172     }
1173 
1174   if (!atari_format)
1175     vi->ext_boot_sign = MSDOS_EXT_SIGN;
1176 
1177   if (!cluster_count)
1178     {
1179       if (sectors_per_cluster)	/* If yes, die if we'd spec'd sectors per cluster */
1180 	die ("Too many clusters for file system - try more sectors per cluster");
1181       else
1182 	die ("Attempting to create a too large file system");
1183     }
1184 
1185 
1186   /* The two following vars are in hard sectors, i.e. 512 byte sectors! */
1187   start_data_sector = (reserved_sectors + nr_fats * fat_length) *
1188 		      (sector_size/HARD_SECTOR_SIZE);
1189   start_data_block = (start_data_sector + SECTORS_PER_BLOCK - 1) /
1190 		     SECTORS_PER_BLOCK;
1191 
1192   if (blocks < start_data_block + 32)	/* Arbitrary undersize file system! */
1193     die ("Too few blocks for viable file system");
1194 
1195   if (verbose)
1196     {
1197       printf("%s has %d head%s and %d sector%s per track,\n",
1198 	     device_name, CF_LE_W(bs.heads), (CF_LE_W(bs.heads) != 1) ? "s" : "",
1199 	     CF_LE_W(bs.secs_track), (CF_LE_W(bs.secs_track) != 1) ? "s" : "");
1200       printf("logical sector size is %d,\n",sector_size);
1201       printf("using 0x%02x media descriptor, with %d sectors;\n",
1202 	     (int) (bs.media), num_sectors);
1203       printf("file system has %d %d-bit FAT%s and %d sector%s per cluster.\n",
1204 	     (int) (bs.fats), size_fat, (bs.fats != 1) ? "s" : "",
1205 	     (int) (bs.cluster_size), (bs.cluster_size != 1) ? "s" : "");
1206       printf ("FAT size is %d sector%s, and provides %d cluster%s.\n",
1207 	      fat_length, (fat_length != 1) ? "s" : "",
1208 	      cluster_count, (cluster_count != 1) ? "s" : "");
1209       if (size_fat != 32)
1210 	printf ("Root directory contains %d slots.\n",
1211 		(int) (bs.dir_entries[0]) + (int) (bs.dir_entries[1]) * 256);
1212       printf ("Volume ID is %08lx, ", volume_id &
1213 	      (atari_format ? 0x00ffffff : 0xffffffff));
1214       if ( strcmp(volume_name, "           ") )
1215 	printf("volume label %s.\n", volume_name);
1216       else
1217 	printf("no volume label.\n");
1218     }
1219 
1220   /* Make the file allocation tables! */
1221 
1222   if ((fat = (unsigned char *) malloc (fat_length * sector_size)) == NULL)
1223     die ("unable to allocate space for FAT image in memory");
1224 
1225   memset( fat, 0, fat_length * sector_size );
1226 
1227   mark_FAT_cluster (0, 0xffffffff);	/* Initial fat entries */
1228   mark_FAT_cluster (1, 0xffffffff);
1229   fat[0] = (unsigned char) bs.media;	/* Put media type in first byte! */
1230   if (size_fat == 32) {
1231     /* Mark cluster 2 as EOF (used for root dir) */
1232     mark_FAT_cluster (2, FAT_EOF);
1233   }
1234 
1235   /* Make the root directory entries */
1236 
1237   size_root_dir = (size_fat == 32) ?
1238 		  bs.cluster_size*sector_size :
1239 		  (((int)bs.dir_entries[1]*256+(int)bs.dir_entries[0]) *
1240 		   sizeof (struct msdos_dir_entry));
1241   if ((root_dir = (struct msdos_dir_entry *) malloc (size_root_dir)) == NULL)
1242     {
1243       free (fat);		/* Tidy up before we die! */
1244       die ("unable to allocate space for root directory in memory");
1245     }
1246 
1247   memset(root_dir, 0, size_root_dir);
1248   if ( memcmp(volume_name, "           ", 11) )
1249     {
1250       struct msdos_dir_entry *de = &root_dir[0];
1251       memcpy(de->name, volume_name, 11);
1252       de->attr = ATTR_VOLUME;
1253       ctime = localtime(&create_time);
1254       de->time = CT_LE_W((unsigned short)((ctime->tm_sec >> 1) +
1255 			  (ctime->tm_min << 5) + (ctime->tm_hour << 11)));
1256       de->date = CT_LE_W((unsigned short)(ctime->tm_mday +
1257 					  ((ctime->tm_mon+1) << 5) +
1258 					  ((ctime->tm_year-80) << 9)));
1259       de->ctime_ms = 0;
1260       de->ctime = de->time;
1261       de->cdate = de->date;
1262       de->adate = de->date;
1263       de->starthi = CT_LE_W(0);
1264       de->start = CT_LE_W(0);
1265       de->size = CT_LE_L(0);
1266     }
1267 
1268   if (size_fat == 32) {
1269     /* For FAT32, create an info sector */
1270     struct fat32_fsinfo *info;
1271 
1272     if (!(info_sector = malloc( sector_size )))
1273       die("Out of memory");
1274     memset(info_sector, 0, sector_size);
1275     /* fsinfo structure is at offset 0x1e0 in info sector by observation */
1276     info = (struct fat32_fsinfo *)(info_sector + 0x1e0);
1277 
1278     /* Info sector magic */
1279     info_sector[0] = 'R';
1280     info_sector[1] = 'R';
1281     info_sector[2] = 'a';
1282     info_sector[3] = 'A';
1283 
1284     /* Magic for fsinfo structure */
1285     info->signature = CT_LE_L(0x61417272);
1286     /* We've allocated cluster 2 for the root dir. */
1287     info->free_clusters = CT_LE_L(cluster_count - 1);
1288     info->next_cluster = CT_LE_L(2);
1289 
1290     /* Info sector also must have boot sign */
1291     *(__u16 *)(info_sector + 0x1fe) = CT_LE_W(BOOT_SIGN);
1292   }
1293 
1294   if (!(blank_sector = malloc( sector_size )))
1295       die( "Out of memory" );
1296   memset(blank_sector, 0, sector_size);
1297 }
1298 
1299 
1300 /* Write the new filesystem's data tables to wherever they're going to end up! */
1301 
1302 #define error(str)				\
1303   do {						\
1304     free (fat);					\
1305     if (info_sector) free (info_sector);	\
1306     free (root_dir);				\
1307     die (str);					\
1308   } while(0)
1309 
1310 #define seekto(pos,errstr)						\
1311   do {									\
1312     loff_t __pos = (pos);						\
1313     if (llseek (dev, __pos, SEEK_SET) != __pos)				\
1314 	error ("seek to " errstr " failed whilst writing tables");	\
1315   } while(0)
1316 
1317 #define writebuf(buf,size,errstr)			\
1318   do {							\
1319     int __size = (size);				\
1320     if (write (dev, buf, __size) != __size)		\
1321 	error ("failed whilst writing " errstr);	\
1322   } while(0)
1323 
1324 
1325 static void
write_tables(void)1326 write_tables (void)
1327 {
1328   int x;
1329   int fat_length;
1330 
1331   fat_length = (size_fat == 32) ?
1332 	       CF_LE_L(bs.fat32.fat32_length) : CF_LE_W(bs.fat_length);
1333 
1334   seekto( 0, "start of device" );
1335   /* clear all reserved sectors */
1336   for( x = 0; x < reserved_sectors; ++x )
1337     writebuf( blank_sector, sector_size, "reserved sector" );
1338   /* seek back to sector 0 and write the boot sector */
1339   seekto( 0, "boot sector" );
1340   writebuf( (char *) &bs, sizeof (struct msdos_boot_sector), "boot sector" );
1341   /* on FAT32, write the info sector and backup boot sector */
1342   if (size_fat == 32)
1343     {
1344       seekto( CF_LE_W(bs.fat32.info_sector)*sector_size, "info sector" );
1345       writebuf( info_sector, 512, "info sector" );
1346       if (backup_boot != 0)
1347 	{
1348 	  seekto( backup_boot*sector_size, "backup boot sector" );
1349 	  writebuf( (char *) &bs, sizeof (struct msdos_boot_sector),
1350 		    "backup boot sector" );
1351 	}
1352     }
1353   /* seek to start of FATS and write them all */
1354   seekto( reserved_sectors*sector_size, "first FAT" );
1355   for (x = 1; x <= nr_fats; x++)
1356     writebuf( fat, fat_length * sector_size, "FAT" );
1357   /* Write the root directory directly after the last FAT. This is the root
1358    * dir area on FAT12/16, and the first cluster on FAT32. */
1359   writebuf( (char *) root_dir, size_root_dir, "root directory" );
1360 
1361   if (blank_sector) free( blank_sector );
1362   if (info_sector) free( info_sector );
1363   free (root_dir);   /* Free up the root directory space from setup_tables */
1364   free (fat);  /* Free up the fat table space reserved during setup_tables */
1365 }
1366 
1367 
1368 /* Report the command usage and return a failure error code */
1369 
1370 void
usage(void)1371 usage (void)
1372 {
1373   fatal_error("\
1374 Usage: mkdosfs [-A] [-c] [-C] [-v] [-I] [-l bad-block-file] [-b backup-boot-sector]\n\
1375        [-m boot-msg-file] [-n volume-name] [-i volume-id]\n\
1376        [-s sectors-per-cluster] [-S logical-sector-size] [-f number-of-FATs]\n\
1377        [-h hidden-sectors] [-F fat-size] [-r root-dir-entries] [-R reserved-sectors]\n\
1378        /dev/name [blocks]\n");
1379 }
1380 
1381 /*
1382  * ++roman: On m68k, check if this is an Atari; if yes, turn on Atari variant
1383  * of MS-DOS filesystem by default.
1384  */
check_atari(void)1385 static void check_atari( void )
1386 {
1387 #ifdef __mc68000__
1388     FILE *f;
1389     char line[128], *p;
1390 
1391     if (!(f = fopen( "/proc/hardware", "r" ))) {
1392 	perror( "/proc/hardware" );
1393 	return;
1394     }
1395 
1396     while( fgets( line, sizeof(line), f ) ) {
1397 	if (strncmp( line, "Model:", 6 ) == 0) {
1398 	    p = line + 6;
1399 	    p += strspn( p, " \t" );
1400 	    if (strncmp( p, "Atari ", 6 ) == 0)
1401 		atari_format = 1;
1402 	    break;
1403 	}
1404     }
1405     fclose( f );
1406 #endif
1407 }
1408 
1409 /* The "main" entry point into the utility - we pick up the options and attempt to process them in some sort of sensible
1410    way.  In the event that some/all of the options are invalid we need to tell the user so that something can be done! */
1411 
1412 int
main(int argc,char ** argv)1413 main (int argc, char **argv)
1414 {
1415   int c;
1416   char *tmp;
1417   char *listfile = NULL;
1418   FILE *msgfile;
1419   struct stat statbuf;
1420   int i = 0, pos, ch;
1421   int create = 0;
1422   unsigned long long cblocks;
1423   int min_sector_size;
1424 
1425   if (argc && *argv) {		/* What's the program name? */
1426     char *p;
1427     program_name = *argv;
1428     if ((p = strrchr( program_name, '/' )))
1429 	program_name = p+1;
1430   }
1431 
1432   gettimeofday(&create_timeval, NULL);
1433   create_time = create_timeval.tv_sec;
1434   volume_id = (u_int32_t)( (create_timeval.tv_sec << 20) | create_timeval.tv_usec );	/* Default volume ID = creation time, fudged for more uniqueness */
1435   check_atari();
1436 
1437   printf ("%s " VERSION " (" VERSION_DATE ")\n",
1438 	   program_name);
1439 
1440   while ((c = getopt (argc, argv, "Ab:cCf:F:Ii:l:m:n:r:R:s:S:h:v")) != EOF)
1441     /* Scan the command line for options */
1442     switch (c)
1443       {
1444       case 'A':		/* toggle Atari format */
1445 	atari_format = !atari_format;
1446 	break;
1447 
1448       case 'b':		/* b : location of backup boot sector */
1449 	backup_boot = (int) strtol (optarg, &tmp, 0);
1450 	if (*tmp || backup_boot < 2 || backup_boot > 0xffff)
1451 	  {
1452 	    printf ("Bad location for backup boot sector : %s\n", optarg);
1453 	    usage ();
1454 	  }
1455 	break;
1456 
1457       case 'c':		/* c : Check FS as we build it */
1458 	check = TRUE;
1459 	break;
1460 
1461       case 'C':		/* C : Create a new file */
1462 	create = TRUE;
1463 	break;
1464 
1465       case 'f':		/* f : Choose number of FATs */
1466 	nr_fats = (int) strtol (optarg, &tmp, 0);
1467 	if (*tmp || nr_fats < 1 || nr_fats > 4)
1468 	  {
1469 	    printf ("Bad number of FATs : %s\n", optarg);
1470 	    usage ();
1471 	  }
1472 	break;
1473 
1474       case 'F':		/* F : Choose FAT size */
1475 	size_fat = (int) strtol (optarg, &tmp, 0);
1476 	if (*tmp || (size_fat != 12 && size_fat != 16 && size_fat != 32))
1477 	  {
1478 	    printf ("Bad FAT type : %s\n", optarg);
1479 	    usage ();
1480 	  }
1481 	size_fat_by_user = 1;
1482 	break;
1483 
1484       case 'h':        /* h : number of hidden sectors */
1485 	hidden_sectors = (int) strtol (optarg, &tmp, 0);
1486 	if ( *tmp || hidden_sectors < 0 )
1487 	  {
1488 	    printf("Bad number of hidden sectors : %s\n", optarg);
1489 	    usage ();
1490 	  }
1491 	break;
1492 
1493       case 'I':
1494 	ignore_full_disk = 1;
1495 	break;
1496 
1497       case 'i':		/* i : specify volume ID */
1498 	volume_id = strtoul(optarg, &tmp, 16);
1499 	if ( *tmp )
1500 	  {
1501 	    printf("Volume ID must be a hexadecimal number\n");
1502 	    usage();
1503 	  }
1504 	break;
1505 
1506       case 'l':		/* l : Bad block filename */
1507 	listfile = optarg;
1508 	break;
1509 
1510       case 'm':		/* m : Set boot message */
1511 	if ( strcmp(optarg, "-") )
1512 	  {
1513 	    msgfile = fopen(optarg, "r");
1514 	    if ( !msgfile )
1515 	      perror(optarg);
1516 	  }
1517 	else
1518 	  msgfile = stdin;
1519 
1520 	if ( msgfile )
1521 	  {
1522 	    /* The boot code ends at offset 448 and needs a null terminator */
1523 	    i = MESSAGE_OFFSET;
1524 	    pos = 0;		/* We are at beginning of line */
1525 	    do
1526 	      {
1527 		ch = getc(msgfile);
1528 		switch (ch)
1529 		  {
1530 		  case '\r':	/* Ignore CRs */
1531 		  case '\0':	/* and nulls */
1532 		    break;
1533 
1534 		  case '\n':	/* LF -> CR+LF if necessary */
1535 		    if ( pos )	/* If not at beginning of line */
1536 		      {
1537 			dummy_boot_code[i++] = '\r';
1538 			pos = 0;
1539 		      }
1540 		    dummy_boot_code[i++] = '\n';
1541 		    break;
1542 
1543 		  case '\t':	/* Expand tabs */
1544 		    do
1545 		      {
1546 			dummy_boot_code[i++] = ' ';
1547 			pos++;
1548 		      }
1549 		    while ( pos % 8 && i < BOOTCODE_SIZE-1 );
1550 		    break;
1551 
1552 		  case EOF:
1553 		    dummy_boot_code[i++] = '\0'; /* Null terminator */
1554 		    break;
1555 
1556 		  default:
1557 		    dummy_boot_code[i++] = ch; /* Store character */
1558 		    pos++;	/* Advance position */
1559 		    break;
1560 		  }
1561 	      }
1562 	    while ( ch != EOF && i < BOOTCODE_SIZE-1 );
1563 
1564 	    /* Fill up with zeros */
1565 	    while( i < BOOTCODE_SIZE-1 )
1566 		dummy_boot_code[i++] = '\0';
1567 	    dummy_boot_code[BOOTCODE_SIZE-1] = '\0'; /* Just in case */
1568 
1569 	    if ( ch != EOF )
1570 	      printf ("Warning: message too long; truncated\n");
1571 
1572 	    if ( msgfile != stdin )
1573 	      fclose(msgfile);
1574 	  }
1575 	break;
1576 
1577       case 'n':		/* n : Volume name */
1578 	sprintf(volume_name, "%-11.11s", optarg);
1579 	break;
1580 
1581       case 'r':		/* r : Root directory entries */
1582 	root_dir_entries = (int) strtol (optarg, &tmp, 0);
1583 	if (*tmp || root_dir_entries < 16 || root_dir_entries > 32768)
1584 	  {
1585 	    printf ("Bad number of root directory entries : %s\n", optarg);
1586 	    usage ();
1587 	  }
1588 	break;
1589 
1590       case 'R':		/* R : number of reserved sectors */
1591 	reserved_sectors = (int) strtol (optarg, &tmp, 0);
1592 	if (*tmp || reserved_sectors < 1 || reserved_sectors > 0xffff)
1593 	  {
1594 	    printf ("Bad number of reserved sectors : %s\n", optarg);
1595 	    usage ();
1596 	  }
1597 	break;
1598 
1599       case 's':		/* s : Sectors per cluster */
1600 	sectors_per_cluster = (int) strtol (optarg, &tmp, 0);
1601 	if (*tmp || (sectors_per_cluster != 1 && sectors_per_cluster != 2
1602 		     && sectors_per_cluster != 4 && sectors_per_cluster != 8
1603 		   && sectors_per_cluster != 16 && sectors_per_cluster != 32
1604 		&& sectors_per_cluster != 64 && sectors_per_cluster != 128))
1605 	  {
1606 	    printf ("Bad number of sectors per cluster : %s\n", optarg);
1607 	    usage ();
1608 	  }
1609 	break;
1610 
1611       case 'S':		/* S : Sector size */
1612 	sector_size = (int) strtol (optarg, &tmp, 0);
1613 	if (*tmp || (sector_size != 512 && sector_size != 1024 &&
1614 		     sector_size != 2048 && sector_size != 4096 &&
1615 		     sector_size != 8192 && sector_size != 16384 &&
1616 		     sector_size != 32768))
1617 	  {
1618 	    printf ("Bad logical sector size : %s\n", optarg);
1619 	    usage ();
1620 	  }
1621 	sector_size_set = 1;
1622 	break;
1623 
1624       case 'v':		/* v : Verbose execution */
1625 	++verbose;
1626 	break;
1627 
1628       default:
1629 	printf( "Unknown option: %c\n", c );
1630 	usage ();
1631       }
1632   if (optind < argc)
1633     {
1634       device_name = argv[optind];  /* Determine the number of blocks in the FS */
1635 
1636       if (!device_name) {
1637 	  printf("No device specified.\n");
1638 	  usage();
1639       }
1640 
1641       if (!create)
1642          cblocks = count_blocks (device_name); /*  Have a look and see! */
1643     }
1644   if (optind == argc - 2)	/*  Either check the user specified number */
1645     {
1646       blocks = strtoull (argv[optind + 1], &tmp, 0);
1647       if (!create && blocks != cblocks)
1648 	{
1649 	  fprintf (stderr, "Warning: block count mismatch: ");
1650 	  fprintf (stderr, "found %llu but assuming %llu.\n",cblocks,blocks);
1651 	}
1652     }
1653   else if (optind == argc - 1)	/*  Or use value found */
1654     {
1655       if (create)
1656 	die( "Need intended size with -C." );
1657       blocks = cblocks;
1658       tmp = "";
1659     }
1660   else
1661     {
1662       fprintf (stderr, "No device specified!\n");
1663       usage ();
1664     }
1665   if (*tmp)
1666     {
1667       printf ("Bad block count : %s\n", argv[optind + 1]);
1668       usage ();
1669     }
1670 
1671   if (check && listfile)	/* Auto and specified bad block handling are mutually */
1672     die ("-c and -l are incompatible");		/* exclusive of each other! */
1673 
1674   if (!create) {
1675     check_mount (device_name);	/* Is the device already mounted? */
1676     dev = open (device_name, O_EXCL|O_RDWR);	/* Is it a suitable device to build the FS on? */
1677     if (dev < 0)
1678       die ("unable to open %s");
1679   }
1680   else {
1681       off_t offset = blocks*BLOCK_SIZE - 1;
1682       char null = 0;
1683       /* create the file */
1684       dev = open( device_name, O_EXCL|O_RDWR|O_CREAT|O_TRUNC, 0666 );
1685       if (dev < 0)
1686 	die("unable to create %s");
1687       /* seek to the intended end-1, and write one byte. this creates a
1688        * sparse-as-possible file of appropriate size. */
1689       if (llseek( dev, offset, SEEK_SET ) != offset)
1690 	die( "seek failed" );
1691       if (write( dev, &null, 1 ) < 0)
1692 	die( "write failed" );
1693       if (llseek( dev, 0, SEEK_SET ) != 0)
1694 	die( "seek failed" );
1695   }
1696 
1697   if (fstat (dev, &statbuf) < 0)
1698     die ("unable to stat %s");
1699   if (!S_ISBLK (statbuf.st_mode)) {
1700     statbuf.st_rdev = 0;
1701     check = 0;
1702   }
1703   else
1704     /*
1705      * Ignore any 'full' fixed disk devices, if -I is not given.
1706      * On a MO-disk one doesn't need partitions.  The filesytem can go
1707      * directly to the whole disk.  Under other OSes this is known as
1708      * the 'superfloppy' format.  As I don't know how to find out if
1709      * this is a MO disk I introduce a -I (ignore) switch.  -Joey
1710      */
1711     if (!ignore_full_disk && (
1712 	(statbuf.st_rdev & 0xff3f) == 0x0300 || /* hda, hdb */
1713 	(statbuf.st_rdev & 0xff0f) == 0x0800 || /* sd */
1714 	(statbuf.st_rdev & 0xff3f) == 0x0d00 || /* xd */
1715 	(statbuf.st_rdev & 0xff3f) == 0x1600 )  /* hdc, hdd */
1716 	)
1717       die ("Device partition expected, not making filesystem on entire device '%s' (use -I to override)");
1718 
1719   if (sector_size_set)
1720     {
1721       if (ioctl(dev, BLKSSZGET, &min_sector_size) >= 0)
1722           if (sector_size < min_sector_size)
1723             {
1724 	      sector_size = min_sector_size;
1725               fprintf(stderr, "Warning: sector size was set to %d (minimal for this device)\n", sector_size);
1726             }
1727     }
1728   else
1729     {
1730       if (ioctl(dev, BLKSSZGET, &min_sector_size) >= 0)
1731         {
1732 	  sector_size = min_sector_size;
1733 	  sector_size_set = 1;
1734         }
1735     }
1736 
1737   if (sector_size > 4096)
1738     fprintf(stderr,
1739             "Warning: sector size is set to %d > 4096, such filesystem will not propably mount\n",
1740             sector_size);
1741 
1742   establish_params (statbuf.st_rdev,statbuf.st_size);
1743                                 /* Establish the media parameters */
1744 
1745   setup_tables ();		/* Establish the file system tables */
1746 
1747   if (check)			/* Determine any bad block locations and mark them */
1748     check_blocks ();
1749   else if (listfile)
1750     get_list_blocks (listfile);
1751 
1752   write_tables ();		/* Write the file system tables away! */
1753 
1754   exit (0);			/* Terminate with no errors! */
1755 }
1756 
1757 
1758 /* That's All Folks */
1759 /* Local Variables: */
1760 /* tab-width: 8     */
1761 /* End:             */
1762