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

📄 mkdosfs.c

📁 mkdosfs - Make DOS file system utilty. I wrote this, partially to complement the dosfsck utilit
💻 C
📖 第 1 页 / 共 4 页
字号:
{  if (currently_testing >= blocks)    return;  signal (SIGALRM, alarm_intr);  alarm (5);  if (!currently_testing)    return;  printf ("%lld... ", (unsigned long long)currently_testing);  fflush (stdout);}static voidcheck_blocks (void){  int try, got;  int i;  static char blkbuf[BLOCK_SIZE * TEST_BUFFER_BLOCKS];  if (verbose)    {      printf ("Searching for bad blocks ");      fflush (stdout);    }  currently_testing = 0;  if (verbose)    {      signal (SIGALRM, alarm_intr);      alarm (5);    }  try = TEST_BUFFER_BLOCKS;  while (currently_testing < blocks)    {      if (currently_testing + try > blocks)	try = blocks - currently_testing;      got = do_check (blkbuf, try, currently_testing);      currently_testing += got;      if (got == try)	{	  try = TEST_BUFFER_BLOCKS;	  continue;	}      else	try = 1;      if (currently_testing < start_data_block)	die ("bad blocks before data-area: cannot make fs");      for (i = 0; i < SECTORS_PER_BLOCK; i++)	/* Mark all of the sectors in the block as bad */	mark_sector_bad (currently_testing * SECTORS_PER_BLOCK + i);      badblocks++;      currently_testing++;    }  if (verbose)    printf ("\n");  if (badblocks)    printf ("%d bad block%s\n", badblocks,	    (badblocks > 1) ? "s" : "");}static voidget_list_blocks (char *filename){  int i;  FILE *listfile;  unsigned long blockno;  listfile = fopen (filename, "r");  if (listfile == (FILE *) NULL)    die ("Can't open file of bad blocks");  while (!feof (listfile))    {      fscanf (listfile, "%ld\n", &blockno);      for (i = 0; i < SECTORS_PER_BLOCK; i++)	/* Mark all of the sectors in the block as bad */	mark_sector_bad (blockno * SECTORS_PER_BLOCK + i);      badblocks++;    }  fclose (listfile);  if (badblocks)    printf ("%d bad block%s\n", badblocks,	    (badblocks > 1) ? "s" : "");}/* Given a file descriptor and an offset, check whether the offset is a valid offset for the file - return FALSE if it   isn't valid or TRUE if it is */static intvalid_offset (int fd, loff_t offset){  char ch;  if (llseek (fd, offset, SEEK_SET) < 0)    return FALSE;  if (read (fd, &ch, 1) < 1)    return FALSE;  return TRUE;}/* Given a filename, look to see how many blocks of BLOCK_SIZE are present, returning the answer */static unsigned long longcount_blocks (char *filename){  off_t high, low;  int fd;  if ((fd = open (filename, O_RDONLY)) < 0)    {      perror (filename);      exit (1);    }  /* first try SEEK_END, which should work on most devices nowadays */  if ((low = llseek(fd, 0, SEEK_END)) <= 0) {      low = 0;      for (high = 1; valid_offset (fd, high); high *= 2)	  low = high;      while (low < high - 1) {	  const loff_t mid = (low + high) / 2;	  if (valid_offset (fd, mid))	      low = mid;	  else	      high = mid;      }      ++low;  }  close (fd);  return low / BLOCK_SIZE;}/* Check to see if the specified device is currently mounted - abort if it is */static voidcheck_mount (char *device_name){  FILE *f;  struct mntent *mnt;  if ((f = setmntent (MOUNTED, "r")) == NULL)    return;  while ((mnt = getmntent (f)) != NULL)    if (strcmp (device_name, mnt->mnt_fsname) == 0)      die ("%s contains a mounted file system.");  endmntent (f);}/* Establish the geometry and media parameters for the device */static voidestablish_params (int device_num,int size){  long loop_size;  struct hd_geometry geometry;  struct floppy_struct param;  if ((0 == device_num) || ((device_num & 0xff00) == 0x0200))    /* file image or floppy disk */    {      if (0 == device_num)	{	  param.size = size/512;	  switch(param.size)	    {	    case 720:	      param.sect = 9 ;	      param.head = 2;	      break; 	    case 1440:	      param.sect = 9;	      param.head = 2;	      break;	    case 2400:	      param.sect = 15;	      param.head = 2;	      break;	    case 2880:	      param.sect = 18;	      param.head = 2;	      break;	    case 5760:	      param.sect = 36;	      param.head = 2;	      break;	    default:	      /* fake values */	      param.sect = 32;	      param.head = 64;	      break;	    }	  	}      else 	/* is a floppy diskette */	{	  if (ioctl (dev, FDGETPRM, &param))	/*  Can we get the diskette geometry? */	    die ("unable to get diskette geometry for '%s'");	}      bs.secs_track = CT_LE_W(param.sect);	/*  Set up the geometry information */      bs.heads = CT_LE_W(param.head);      switch (param.size)	/*  Set up the media descriptor byte */	{	case 720:		/* 5.25", 2, 9, 40 - 360K */	  bs.media = (char) 0xfd;	  bs.cluster_size = (char) 2;	  bs.dir_entries[0] = (char) 112;	  bs.dir_entries[1] = (char) 0;	  break;	case 1440:		/* 3.5", 2, 9, 80 - 720K */	  bs.media = (char) 0xf9;	  bs.cluster_size = (char) 2;	  bs.dir_entries[0] = (char) 112;	  bs.dir_entries[1] = (char) 0;	  break;	case 2400:		/* 5.25", 2, 15, 80 - 1200K */	  bs.media = (char) 0xf9;	  bs.cluster_size = (char)(atari_format ? 2 : 1);	  bs.dir_entries[0] = (char) 224;	  bs.dir_entries[1] = (char) 0;	  break;	  	case 5760:		/* 3.5", 2, 36, 80 - 2880K */	  bs.media = (char) 0xf0;	  bs.cluster_size = (char) 2;	  bs.dir_entries[0] = (char) 224;	  bs.dir_entries[1] = (char) 0;	  break;	case 2880:		/* 3.5", 2, 18, 80 - 1440K */	floppy_default:	  bs.media = (char) 0xf0;	  bs.cluster_size = (char)(atari_format ? 2 : 1);	  bs.dir_entries[0] = (char) 224;	  bs.dir_entries[1] = (char) 0;	  break;	default:		/* Anything else */	  if (0 == device_num)	      goto def_hd_params;	  else	      goto floppy_default;	}    }  else if ((device_num & 0xff00) == 0x0700) /* This is a loop device */    {      if (ioctl (dev, BLKGETSIZE, &loop_size)) 	die ("unable to get loop device size");      switch (loop_size)  /* Assuming the loop device -> floppy later */	{	case 720:		/* 5.25", 2, 9, 40 - 360K */	  bs.secs_track = CF_LE_W(9);	  bs.heads = CF_LE_W(2);	  bs.media = (char) 0xfd;	  bs.cluster_size = (char) 2;	  bs.dir_entries[0] = (char) 112;	  bs.dir_entries[1] = (char) 0;	  break;	case 1440:		/* 3.5", 2, 9, 80 - 720K */	  bs.secs_track = CF_LE_W(9);	  bs.heads = CF_LE_W(2);	  bs.media = (char) 0xf9;	  bs.cluster_size = (char) 2;	  bs.dir_entries[0] = (char) 112;	  bs.dir_entries[1] = (char) 0;	  break;	case 2400:		/* 5.25", 2, 15, 80 - 1200K */	  bs.secs_track = CF_LE_W(15);	  bs.heads = CF_LE_W(2);	  bs.media = (char) 0xf9;	  bs.cluster_size = (char)(atari_format ? 2 : 1);	  bs.dir_entries[0] = (char) 224;	  bs.dir_entries[1] = (char) 0;	  break;	  	case 5760:		/* 3.5", 2, 36, 80 - 2880K */	  bs.secs_track = CF_LE_W(36);	  bs.heads = CF_LE_W(2);	  bs.media = (char) 0xf0;	  bs.cluster_size = (char) 2;	  bs.dir_entries[0] = (char) 224;	  bs.dir_entries[1] = (char) 0;	  break;	case 2880:		/* 3.5", 2, 18, 80 - 1440K */	  bs.secs_track = CF_LE_W(18);	  bs.heads = CF_LE_W(2);	  bs.media = (char) 0xf0;	  bs.cluster_size = (char)(atari_format ? 2 : 1);	  bs.dir_entries[0] = (char) 224;	  bs.dir_entries[1] = (char) 0;	  break;	default:		/* Anything else: default hd setup */	  printf("Loop device does not match a floppy size, using "		 "default hd params\n");	  bs.secs_track = CT_LE_W(32); /* these are fake values... */	  bs.heads = CT_LE_W(64);	  goto def_hd_params;	}    }  else    /* Must be a hard disk then! */    {      /* Can we get the drive geometry? (Note I'm not too sure about */      /* whether to use HDIO_GETGEO or HDIO_REQ) */      if (ioctl (dev, HDIO_GETGEO, &geometry)) {	printf ("unable to get drive geometry, using default 255/63");        bs.secs_track = CT_LE_W(63);        bs.heads = CT_LE_W(255);      }      else {        bs.secs_track = CT_LE_W(geometry.sectors);	/* Set up the geometry information */        bs.heads = CT_LE_W(geometry.heads);      }    def_hd_params:      bs.media = (char) 0xf8; /* Set up the media descriptor for a hard drive */      bs.dir_entries[0] = (char) 0;	/* Default to 512 entries */      bs.dir_entries[1] = (char) 2;      if (!size_fat && blocks*SECTORS_PER_BLOCK > 1064960) {	  if (verbose) printf("Auto-selecting FAT32 for large filesystem\n");	  size_fat = 32;      }      if (size_fat == 32) {	  /* For FAT32, try to do the same as M$'s format command:	   * fs size < 256M: 0.5k clusters	   * fs size <   8G: 4k clusters	   * fs size <  16G: 8k clusters	   * fs size >= 16G: 16k clusters	   */	  unsigned long sz_mb =	      (blocks+(1<<(20-BLOCK_SIZE_BITS))-1) >> (20-BLOCK_SIZE_BITS);	  bs.cluster_size = sz_mb >= 16*1024 ? 32 :			    sz_mb >=  8*1024 ? 16 :			    sz_mb >=     256 ?  8 :					        1;      }      else {	  /* FAT12 and FAT16: start at 4 sectors per cluster */	  bs.cluster_size = (char) 4;      }    }}/* Create the filesystem data tables */static voidsetup_tables (void){  unsigned num_sectors;  unsigned cluster_count = 0, fat_length;  unsigned fatdata;			/* Sectors for FATs + data area */  struct tm *ctime;  struct msdos_volume_info *vi = (size_fat == 32 ? &bs.fat32.vi : &bs.oldfat.vi);    if (atari_format)      /* On Atari, the first few bytes of the boot sector are assigned       * differently: The jump code is only 2 bytes (and m68k machine code       * :-), then 6 bytes filler (ignored), then 3 byte serial number. */    strncpy( bs.system_id-1, "mkdosf", 6 );  else    strcpy (bs.system_id, "mkdosfs");  if (sectors_per_cluster)    bs.cluster_size = (char) sectors_per_cluster;  if (size_fat == 32)    {      /* Under FAT32, the root dir is in a cluster chain, and this is       * signalled by bs.dir_entries being 0. */      bs.dir_entries[0] = bs.dir_entries[1] = (char) 0;      root_dir_entries = 0;    }  else if (root_dir_entries)    {      /* Override default from establish_params() */      bs.dir_entries[0] = (char) (root_dir_entries & 0x00ff);      bs.dir_entries[1] = (char) ((root_dir_entries & 0xff00) >> 8);    }  else    root_dir_entries = bs.dir_entries[0] + (bs.dir_entries[1] << 8);  if (atari_format) {    bs.system_id[5] = (unsigned char) (volume_id & 0x000000ff);    bs.system_id[6] = (unsigned char) ((volume_id & 0x0000ff00) >> 8);    bs.system_id[7] = (unsigned char) ((volume_id & 0x00ff0000) >> 16);  }  else {    vi->volume_id[0] = (unsigned char) (volume_id & 0x000000ff);    vi->volume_id[1] = (unsigned char) ((volume_id & 0x0000ff00) >> 8);    vi->volume_id[2] = (unsigned char) ((volume_id & 0x00ff0000) >> 16);    vi->volume_id[3] = (unsigned char) (volume_id >> 24);  }  if (!atari_format) {    memcpy(vi->volume_label, volume_name, 11);      memcpy(bs.boot_jump, dummy_boot_jump, 3);    /* Patch in the correct offset to the boot code */    bs.boot_jump[1] = ((size_fat == 32 ?			(char *)&bs.fat32.boot_code :			(char *)&bs.oldfat.boot_code) -		       (char *)&bs) - 2;    if (size_fat == 32) {	int offset = (char *)&bs.fat32.boot_code -		     (char *)&bs + MESSAGE_OFFSET + 0x7c00;	if (dummy_boot_code[BOOTCODE_FAT32_SIZE-1])	  printf ("Warning: message too long; truncated\n");	dummy_boot_code[BOOTCODE_FAT32_SIZE-1] = 0;	memcpy(bs.fat32.boot_code, dummy_boot_code, BOOTCODE_FAT32_SIZE);	bs.fat32.boot_code[MSG_OFFSET_OFFSET] = offset & 0xff;	bs.fat32.boot_code[MSG_OFFSET_OFFSET+1] = offset >> 8;    }    else {	memcpy(bs.oldfat.boot_code, dummy_boot_code, BOOTCODE_SIZE);    }    bs.boot_sign = CT_LE_W(BOOT_SIGN);  }  else {    memcpy(bs.boot_jump, dummy_boot_jump_m68k, 2);  }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -