⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mkdosfs.c

📁 mkdosfs - Make DOS file system utilty. I wrote this, partially to complement the dosfsck utilit
💻 C
📖 第 1 页 / 共 4 页
字号:
/* Write the new filesystem's data tables to wherever they're going to end up! */#define error(str)				\  do {						\    free (fat);					\    if (info_sector) free (info_sector);	\    free (root_dir);				\    die (str);					\  } while(0)#define seekto(pos,errstr)						\  do {									\    loff_t __pos = (pos);						\    if (llseek (dev, __pos, SEEK_SET) != __pos)				\	error ("seek to " errstr " failed whilst writing tables");	\  } while(0)#define writebuf(buf,size,errstr)			\  do {							\    int __size = (size);				\    if (write (dev, buf, __size) != __size)		\	error ("failed whilst writing " errstr);	\  } while(0)static voidwrite_tables (void){  int x;  int fat_length;  fat_length = (size_fat == 32) ?	       CF_LE_L(bs.fat32.fat32_length) : CF_LE_W(bs.fat_length);  seekto( 0, "start of device" );  /* clear all reserved sectors */  for( x = 0; x < reserved_sectors; ++x )    writebuf( blank_sector, sector_size, "reserved sector" );  /* seek back to sector 0 and write the boot sector */  seekto( 0, "boot sector" );  writebuf( (char *) &bs, sizeof (struct msdos_boot_sector), "boot sector" );  /* on FAT32, write the info sector and backup boot sector */  if (size_fat == 32)    {      seekto( CF_LE_W(bs.fat32.info_sector)*sector_size, "info sector" );      writebuf( info_sector, 512, "info sector" );      if (backup_boot != 0)	{	  seekto( backup_boot*sector_size, "backup boot sector" );	  writebuf( (char *) &bs, sizeof (struct msdos_boot_sector),		    "backup boot sector" );	}    }  /* seek to start of FATS and write them all */  seekto( reserved_sectors*sector_size, "first FAT" );  for (x = 1; x <= nr_fats; x++)    writebuf( fat, fat_length * sector_size, "FAT" );  /* 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 (blank_sector) free( blank_sector );  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 */voidusage (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\       [-h hidden-sectors] [-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! */intmain (int argc, char **argv){  int c;  char *tmp;  char *listfile = NULL;  FILE *msgfile;  struct stat statbuf;  int i = 0, pos, ch;  int create = 0;  unsigned long long cblocks;    if (argc && *argv) {		/* What's the program name? */    char *p;    program_name = *argv;    if ((p = strrchr( program_name, '/' )))	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",	   program_name);  while ((c = getopt (argc, argv, "AbcCf:F:Ii:l:m:n:r:R:s:S:h: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 'h':        /* h : number of hidden sectors */	hidden_sectors = (int) strtol (optarg, &tmp, 0);	if ( *tmp || hidden_sectors < 0 )	  {	    printf("Bad number of hidden sectors : %s\n", optarg);	    usage ();	  }	break;      case 'I':	ignore_full_disk = 1;	break;      case 'i':		/* i : specify volume ID */	volume_id = strtoul(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)    {      device_name = argv[optind];  /* Determine the number of blocks in the FS */      if (!create)         cblocks = count_blocks (device_name); /*  Have a look and see! */    }  if (optind == argc - 2)	/*  Either check the user specified number */    {      blocks = strtoull (argv[optind + 1], &tmp, 0);      if (!create && blocks != cblocks)	{	  fprintf (stderr, "Warning: block count mismatch: ");	  fprintf (stderr, "found %llu but assuming %llu.\n",cblocks,blocks);	}    }  else if (optind == argc - 1)	/*  Or use value found */    {      if (create)	die( "Need intended size with -C." );      blocks = cblocks;      tmp = "";    }  else    {      fprintf (stderr, "No device specified!\n");      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);	/* Is it a suitable device to build the FS on? */    if (dev < 0)      die ("unable to open %s");  }  else {      off_t offset = blocks*BLOCK_SIZE - 1;      char null = 0;      /* create the file */      dev = open( device_name, O_RDWR|O_CREAT|O_TRUNC, 0666 );      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" );  }    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 full-disk device '%s' (use -I if wanted)");  establish_params (statbuf.st_rdev,statbuf.st_size);	                                /* Establish the media parameters */  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! */  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 + -