📄 mkdosfs.c
字号:
for (x = 1; x <= nr_fats; x++)
#ifdef _WIN32
/*
* WIN32 appearently has problems writing very large chunks directly
* to disk devices. To not produce errors because of resource shortages
* split up the write in sector size chunks.
*/
for (blk = 0; blk < fat_length; blk++)
writebuf(fat+blk*sector_size, sector_size, "FAT");
#else
writebuf( fat, fat_length * sector_size, "FAT" );
#endif
/* Write the root directory directly after the last FAT. This is the root
* dir area on FAT12/16, and the first cluster on FAT32. */
writebuf( (char *) root_dir, size_root_dir, "root directory" );
if (info_sector) free( info_sector );
free (root_dir); /* Free up the root directory space from setup_tables */
free (fat); /* Free up the fat table space reserved during setup_tables */
}
/* Report the command usage and return a failure error code */
void
usage (void)
{
fatal_error("\
Usage: mkdosfs [-A] [-c] [-C] [-v] [-I] [-l bad-block-file] [-b backup-boot-sector]\n\
[-m boot-msg-file] [-n volume-name] [-i volume-id]\n\
[-s sectors-per-cluster] [-S logical-sector-size] [-f number-of-FATs]\n\
[-F fat-size] [-r root-dir-entries] [-R reserved-sectors]\n\
/dev/name [blocks]\n");
}
/*
* ++roman: On m68k, check if this is an Atari; if yes, turn on Atari variant
* of MS-DOS filesystem by default.
*/
static void check_atari( void )
{
#ifdef __mc68000__
FILE *f;
char line[128], *p;
if (!(f = fopen( "/proc/hardware", "r" ))) {
perror( "/proc/hardware" );
return;
}
while( fgets( line, sizeof(line), f ) ) {
if (strncmp( line, "Model:", 6 ) == 0) {
p = line + 6;
p += strspn( p, " \t" );
if (strncmp( p, "Atari ", 6 ) == 0)
atari_format = 1;
break;
}
}
fclose( f );
#endif
}
/* The "main" entry point into the utility - we pick up the options and attempt to process them in some sort of sensible
way. In the event that some/all of the options are invalid we need to tell the user so that something can be done! */
int
main (int argc, char **argv)
{
int c;
char *tmp;
char *listfile = NULL;
FILE *msgfile;
#ifdef _WIN32
static char dev_buf[] = "\\\\.\\X:";
#else
struct stat statbuf;
#endif
int i = 0, pos, ch;
int create = 0;
if (argc && *argv) { /* What's the program name? */
char *p;
program_name = *argv;
#ifdef _WIN32
if ((p = strrchr( program_name, '\\' )))
#else
if ((p = strrchr( program_name, '/' )))
#endif
program_name = p+1;
}
time(&create_time);
volume_id = (long)create_time; /* Default volume ID = creation time */
check_atari();
printf ("%s " VERSION " (" VERSION_DATE ")\n"
#ifdef _WIN32
"Win32 port by Jens-Uwe Mager <jum@anubis.han.de>\n"
#endif
, program_name);
while ((c = getopt (argc, argv, "AcCf:F:Ii:l:m:n:r:R:s:S:v")) != EOF)
/* Scan the command line for options */
switch (c)
{
case 'A': /* toggle Atari format */
atari_format = !atari_format;
break;
case 'b': /* b : location of backup boot sector */
backup_boot = (int) strtol (optarg, &tmp, 0);
if (*tmp || backup_boot < 2 || backup_boot > 0xffff)
{
printf ("Bad location for backup boot sector : %s\n", optarg);
usage ();
}
break;
case 'c': /* c : Check FS as we build it */
check = TRUE;
break;
case 'C': /* C : Create a new file */
create = TRUE;
break;
case 'f': /* f : Choose number of FATs */
nr_fats = (int) strtol (optarg, &tmp, 0);
if (*tmp || nr_fats < 1 || nr_fats > 4)
{
printf ("Bad number of FATs : %s\n", optarg);
usage ();
}
break;
case 'F': /* F : Choose FAT size */
size_fat = (int) strtol (optarg, &tmp, 0);
if (*tmp || (size_fat != 12 && size_fat != 16 && size_fat != 32))
{
printf ("Bad FAT type : %s\n", optarg);
usage ();
}
size_fat_by_user = 1;
break;
case 'I':
ignore_full_disk = 1;
break;
case 'i': /* i : specify volume ID */
volume_id = strtol(optarg, &tmp, 16);
if ( *tmp )
{
printf("Volume ID must be a hexadecimal number\n");
usage();
}
break;
case 'l': /* l : Bad block filename */
listfile = optarg;
break;
case 'm': /* m : Set boot message */
if ( strcmp(optarg, "-") )
{
msgfile = fopen(optarg, "r");
if ( !msgfile )
perror(optarg);
}
else
msgfile = stdin;
if ( msgfile )
{
/* The boot code ends at offset 448 and needs a null terminator */
i = MESSAGE_OFFSET;
pos = 0; /* We are at beginning of line */
do
{
ch = getc(msgfile);
switch (ch)
{
case '\r': /* Ignore CRs */
case '\0': /* and nulls */
break;
case '\n': /* LF -> CR+LF if necessary */
if ( pos ) /* If not at beginning of line */
{
dummy_boot_code[i++] = '\r';
pos = 0;
}
dummy_boot_code[i++] = '\n';
break;
case '\t': /* Expand tabs */
do
{
dummy_boot_code[i++] = ' ';
pos++;
}
while ( pos % 8 && i < BOOTCODE_SIZE-1 );
break;
case EOF:
dummy_boot_code[i++] = '\0'; /* Null terminator */
break;
default:
dummy_boot_code[i++] = ch; /* Store character */
pos++; /* Advance position */
break;
}
}
while ( ch != EOF && i < BOOTCODE_SIZE-1 );
/* Fill up with zeros */
while( i < BOOTCODE_SIZE-1 )
dummy_boot_code[i++] = '\0';
dummy_boot_code[BOOTCODE_SIZE-1] = '\0'; /* Just in case */
if ( ch != EOF )
printf ("Warning: message too long; truncated\n");
if ( msgfile != stdin )
fclose(msgfile);
}
break;
case 'n': /* n : Volume name */
sprintf(volume_name, "%-11.11s", optarg);
break;
case 'r': /* r : Root directory entries */
root_dir_entries = (int) strtol (optarg, &tmp, 0);
if (*tmp || root_dir_entries < 16 || root_dir_entries > 32768)
{
printf ("Bad number of root directory entries : %s\n", optarg);
usage ();
}
break;
case 'R': /* R : number of reserved sectors */
reserved_sectors = (int) strtol (optarg, &tmp, 0);
if (*tmp || reserved_sectors < 1 || reserved_sectors > 0xffff)
{
printf ("Bad number of reserved sectors : %s\n", optarg);
usage ();
}
break;
case 's': /* s : Sectors per cluster */
sectors_per_cluster = (int) strtol (optarg, &tmp, 0);
if (*tmp || (sectors_per_cluster != 1 && sectors_per_cluster != 2
&& sectors_per_cluster != 4 && sectors_per_cluster != 8
&& sectors_per_cluster != 16 && sectors_per_cluster != 32
&& sectors_per_cluster != 64 && sectors_per_cluster != 128))
{
printf ("Bad number of sectors per cluster : %s\n", optarg);
usage ();
}
break;
case 'S': /* S : Sector size */
sector_size = (int) strtol (optarg, &tmp, 0);
if (*tmp || (sector_size != 512 && sector_size != 1024 &&
sector_size != 2048 && sector_size != 4096 &&
sector_size != 8192 && sector_size != 16384 &&
sector_size != 32768))
{
printf ("Bad logical sector size : %s\n", optarg);
usage ();
}
sector_size_set = 1;
break;
case 'v': /* v : Verbose execution */
++verbose;
break;
default:
printf( "Unknown option: %c\n", c );
usage ();
}
if (optind >= argc)
usage();
device_name = argv[optind]; /* Determine the number of blocks in the FS */
#ifdef _WIN32
if (device_name[1] == ':' && device_name[2] == '\0') {
dev_buf[4] = device_name[0];
device_name = dev_buf;
is_device = 1;
}
#endif
if (!create)
i = count_blocks (device_name); /* Have a look and see! */
if (optind == argc - 2) /* Either check the user specified number */
{
blocks = (int) strtol (argv[optind + 1], &tmp, 0);
if (!create && blocks != i)
{
fprintf (stderr, "Warning: block count mismatch: ");
fprintf (stderr, "found %d but assuming %d.\n",i,blocks);
}
}
else if (optind == argc - 1) /* Or use value found */
{
if (create)
die( "Need intended size with -C." );
blocks = i;
tmp = "";
}
else
usage ();
if (*tmp)
{
printf ("Bad block count : %s\n", argv[optind + 1]);
usage ();
}
if (check && listfile) /* Auto and specified bad block handling are mutually */
die ("-c and -l are incompatible"); /* exclusive of each other! */
if (!create) {
check_mount (device_name); /* Is the device already mounted? */
dev = open (device_name, O_RDWR|O_SHARED); /* Is it a suitable device to build the FS on? */
if (dev < 0)
die ("unable to open %s");
#ifdef _WIN32
if (is_device) {
if (fsctl(dev, FSCTL_LOCK_VOLUME) == -1)
die("unable to lock %s");
}
#endif
}
else {
loff_t offset = blocks*BLOCK_SIZE - 1;
char null = 0;
/* create the file */
dev = open( device_name, O_RDWR|O_CREAT|O_TRUNC, 0775 );
if (dev < 0)
die("unable to create %s");
/* seek to the intended end-1, and write one byte. this creates a
* sparse-as-possible file of appropriate size. */
if (llseek( dev, offset, SEEK_SET ) != offset)
die( "seek failed" );
if (write( dev, &null, 1 ) < 0)
die( "write failed" );
if (llseek( dev, 0, SEEK_SET ) != 0)
die( "seek failed" );
}
#ifdef _WIN32
if (!is_device)
check = 0;
establish_params();
#else
if (fstat (dev, &statbuf) < 0)
die ("unable to stat %s");
if (!S_ISBLK (statbuf.st_mode)) {
statbuf.st_rdev = 0;
check = 0;
}
else
/*
* Ignore any 'full' fixed disk devices, if -I is not given.
* On a MO-disk one doesn't need partitions. The filesytem can go
* directly to the whole disk. Under other OSes this is known as
* the 'superfloppy' format. As I don't know how to find out if
* this is a MO disk I introduce a -I (ignore) switch. -Joey
*/
if (!ignore_full_disk && (
(statbuf.st_rdev & 0xff3f) == 0x0300 || /* hda, hdb */
(statbuf.st_rdev & 0xff0f) == 0x0800 || /* sd */
(statbuf.st_rdev & 0xff3f) == 0x0d00 || /* xd */
(statbuf.st_rdev & 0xff3f) == 0x1600 ) /* hdc, hdd */
)
die ("Will not try to make filesystem on '%s'");
establish_params (statbuf.st_rdev,statbuf.st_size);
/* Establish the media parameters */
#endif
setup_tables (); /* Establish the file system tables */
if (check) /* Determine any bad block locations and mark them */
check_blocks ();
else if (listfile)
get_list_blocks (listfile);
write_tables (); /* Write the file system tables away! */
#ifdef _WIN32
if (is_device) {
if (fsctl(dev, FSCTL_DISMOUNT_VOLUME) == -1)
die("unable to dismount %s");
if (fsctl(dev, FSCTL_UNLOCK_VOLUME) == -1)
die("unable to unlock %s");
}
#endif
exit (0); /* Terminate with no errors! */
}
/* That's All Folks */
/* Local Variables: */
/* tab-width: 8 */
/* End: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -