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

📄 fsys_ext2fs.c

📁 grub4dos-0.4.4-2008- 08-src.zip
💻 C
📖 第 1 页 / 共 2 页
字号:
  if (mapblock1 != 3      && !ext2_rdfsb (INODE->i_block[EXT2_TIND_BLOCK], DATABLOCK1))    {      errnum = ERR_FSYS_CORRUPT;      return -1;    }    mapblock1 = 3;    if (!ext2_rdfsb (((__u32 *) DATABLOCK1)		   [logical_block >> (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK)				      * 2)],		   DATABLOCK2))    {      errnum = ERR_FSYS_CORRUPT;      return -1;    }    if (! ext2_rdfsb (((__u32 *) DATABLOCK2)		   [(logical_block >> EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK))		    & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)],		   DATABLOCK2))    {      errnum = ERR_FSYS_CORRUPT;      return -1;    }    return ((__u32 *) DATABLOCK2)[logical_block & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)];}/* preconditions: all preconds of ext2fs_block_map */unsigned longext2fs_read (char *buf, unsigned long len){  unsigned long logical_block;  unsigned long offset;  unsigned long ret = 0;  unsigned long size = 0;  int map;#ifdef E2DEBUG  static char hexdigit[] = "0123456789abcdef";  unsigned char *i;    for (i = (unsigned char *) INODE;       i < ((unsigned char *) INODE + sizeof (struct ext2_inode));       i++)    {      printf ("%c", hexdigit[*i >> 4]);      printf ("%c", hexdigit[*i % 16]);            if (! ((i + 1 - (unsigned char *) INODE) % 16))	{	  printf ("\n");	}      else	{	  printf (" ");	}    }#endif /* E2DEBUG */  while (len > 0)  {      /* find the (logical) block component of our location */      logical_block = filepos >> EXT2_BLOCK_SIZE_BITS (SUPERBLOCK);      offset = filepos & (EXT2_BLOCK_SIZE (SUPERBLOCK) - 1);      map = ext2fs_block_map (logical_block);#ifdef E2DEBUG      printf ("map=%d\n", map);#endif /* E2DEBUG */            if (map < 0)	  break;      size = EXT2_BLOCK_SIZE (SUPERBLOCK);      size -= offset;            if (size > len)	  size = len;      if (map == 0)      {          memset ((char *) buf, 0, size);      } else {          disk_read_func = disk_read_hook;          devread (map * (EXT2_BLOCK_SIZE (SUPERBLOCK) / DEV_BSIZE),		 offset, size, buf);          disk_read_func = NULL;      }      buf += size;      len -= size;	/* len always >= 0 */      filepos += size;      ret += size;  }  if (errnum)      ret = 0;  return ret;}/* Based on:   def_blk_fops points to   blkdev_open, which calls (I think):   sys_open()   do_open()   open_namei()   dir_namei() which accesses current->fs->root     fs->root was set during original mount:     (something)... which calls (I think):     ext2_read_super()     iget()     __iget()     read_inode()     ext2_read_inode()       uses desc_per_block_bits, which is set in ext2_read_super()       also uses group descriptors loaded during ext2_read_super()   lookup()   ext2_lookup()   ext2_find_entry()   ext2_getblk()*/static inlineint ext2_is_fast_symlink (void){  int ea_blocks;  ea_blocks = INODE->i_file_acl ? EXT2_BLOCK_SIZE (SUPERBLOCK) / DEV_BSIZE : 0;  return INODE->i_blocks == ea_blocks;}/* preconditions: ext2fs_mount already executed, therefore supblk in buffer *   known as SUPERBLOCK * returns: 0 if error, nonzero iff we were able to find the file successfully * postconditions: on a nonzero return, buffer known as INODE contains the *   inode of the file we were trying to look up * side effects: messes up GROUP_DESC buffer area */intext2fs_dir (char *dirname){  int current_ino = EXT2_ROOT_INO;	/* start at the root */  int updir_ino = current_ino;	/* the parent of the current directory */  int group_id;			/* which group the inode is in */  int group_desc;		/* fs pointer to that group */  int desc;			/* index within that group */  int ino_blk;			/* fs pointer of the inode's information */  int str_chk = 0;		/* used to hold the results of a string compare */  struct ext2_group_desc *gdp;  struct ext2_inode *raw_inode;	/* inode info corresponding to current_ino *///char linkbuf[PATH_MAX];	/* buffer for following symbolic links */  int link_count = 0;  char *rest;  char ch;			/* temp char holder */  int off;			/* offset within block of directory entry (off mod blocksize) */  int loc;			/* location within a directory */  int blk;			/* which data blk within dir entry (off div blocksize) */  long map;			/* fs pointer of a particular block from dir entry */  struct ext2_dir_entry *dp;	/* pointer to directory entry */#ifdef E2DEBUG  unsigned char *i;#endif	/* E2DEBUG */  /* loop invariants:     current_ino = inode to lookup     dirname = pointer to filename component we are cur looking up within     the directory known pointed to by current_ino (if any)   */  while (1)    {#ifdef E2DEBUG      printf ("inode %d\n", current_ino);      printf ("dirname=%s\n", dirname);#endif /* E2DEBUG */      /* look up an inode */      group_id = (current_ino - 1) / (SUPERBLOCK->s_inodes_per_group);      group_desc = group_id >> log2_tmp (EXT2_DESC_PER_BLOCK (SUPERBLOCK));      desc = group_id & (EXT2_DESC_PER_BLOCK (SUPERBLOCK) - 1);#ifdef E2DEBUG      printf ("ipg=%d, dpb=%d\n", SUPERBLOCK->s_inodes_per_group,	      EXT2_DESC_PER_BLOCK (SUPERBLOCK));      printf ("group_id=%d group_desc=%d desc=%d\n", group_id, group_desc, desc);#endif /* E2DEBUG */      if (!ext2_rdfsb (			(WHICH_SUPER + group_desc + SUPERBLOCK->s_first_data_block),			(int) GROUP_DESC))	{	  return 0;	}      gdp = GROUP_DESC;      ino_blk = gdp[desc].bg_inode_table +	(((current_ino - 1) % (SUPERBLOCK->s_inodes_per_group))	 >> log2_tmp (EXT2_INODES_PER_BLOCK (SUPERBLOCK)));#ifdef E2DEBUG      printf ("inode table fsblock=%d\n", ino_blk);#endif /* E2DEBUG */      if (!ext2_rdfsb (ino_blk, (int) INODE))	{	  return 0;	}      /* reset indirect blocks! */      mapblock2 = mapblock1 = -1;      raw_inode = (struct ext2_inode *)((char *)INODE +	((current_ino - 1) & (EXT2_INODES_PER_BLOCK (SUPERBLOCK) - 1)) *	 EXT2_INODE_SIZE (SUPERBLOCK));#ifdef E2DEBUG      printf ("ipb=%d, sizeof(inode)=%d\n",	     EXT2_INODES_PER_BLOCK (SUPERBLOCK), EXT2_INODE_SIZE (SUPERBLOCK));      printf ("inode=%x, raw_inode=%x\n", INODE, raw_inode);      printf ("offset into inode table block=%d\n", (int) raw_inode - (int) INODE);      for (i = (unsigned char *) INODE; i <= (unsigned char *) raw_inode;	   i++)	{	  printf ("%c", "0123456789abcdef"[*i >> 4]);	  printf ("%c", "0123456789abcdef"[*i % 16]);	  if (!((i + 1 - (unsigned char *) INODE) % 16))	    {	      printf ("\n");	    }	  else	    {	      printf (" ");	    }	}      printf ("first word=%x\n", *((int *) raw_inode));#endif /* E2DEBUG */      /* copy inode to fixed location */      memmove ((void *) INODE, (void *) raw_inode, sizeof (struct ext2_inode));#ifdef E2DEBUG      printf ("first word=%x\n", *((int *) INODE));#endif /* E2DEBUG */      /* If we've got a symbolic link, then chase it. */      if (S_ISLNK (INODE->i_mode))	{	  int len;	  if (++link_count > MAX_LINK_COUNT)	    {	      errnum = ERR_SYMLINK_LOOP;	      return 0;	    }	  /* Find out how long our remaining name is. */	  //len = 0;	  //while (dirname[len] && !isspace (dirname[len]))	  //  len++;	  for (len = 0; (ch = dirname[len]) && !isspace (ch); len++)	  {		if (ch == '\\')		{			len++;			if (! (ch = dirname[len]))				break;		}	  }	  /* Get the symlink size. */	  filemax = (INODE->i_size);	  if (filemax + len > PATH_MAX - 2)	    {	      errnum = ERR_FILELENGTH;	      return 0;	    }	  if (len)	    {	      /* Copy the remaining name to the end of the symlink data.	         Note that DIRNAME and LINKBUF may overlap! */	      memmove (linkbuf + filemax, dirname, len);	    }	  linkbuf[filemax + len] = '\0';	  /* Read the symlink data. */	  if (! ext2_is_fast_symlink ())	    {	      /* Read the necessary blocks, and reset the file pointer. */	      len = grub_read (linkbuf, filemax);	      filepos = 0;	      if (!len)		return 0;	    }	  else	    {	      /* Copy the data directly from the inode. */	      len = filemax;	      memmove (linkbuf, (char *) INODE->i_block, len);	    }#ifdef E2DEBUG	  printf ("symlink=%s\n", linkbuf);#endif	  dirname = linkbuf;	  if (*dirname == '/')	    {	      /* It's an absolute link, so look it up in root. */	      current_ino = EXT2_ROOT_INO;	      updir_ino = current_ino;	    }	  else	    {	      /* Relative, so look it up in our parent directory. */	      current_ino = updir_ino;	    }	  /* Try again using the new name. */	  continue;	}      /* if end of filename, INODE points to the file's inode */      if (!*dirname || isspace (*dirname))	{	  if (!S_ISREG (INODE->i_mode))	    {	      errnum = ERR_BAD_FILETYPE;	      return 0;	    }	  filemax = (INODE->i_size);	  return 1;	}      /* else we have to traverse a directory */      updir_ino = current_ino;      /* skip over slashes */      while (*dirname == '/')	dirname++;      /* if this isn't a directory of sufficient size to hold our file, abort */      if (!(INODE->i_size) || !S_ISDIR (INODE->i_mode))	{	  errnum = ERR_BAD_FILETYPE;	  return 0;	}      /* skip to next slash or end of filename (space) *///      for (rest = dirname; (ch = *rest) && !isspace (ch) && ch != '/';//	   rest++);      for (rest = dirname; (ch = *rest) && !isspace (ch) && ch != '/'; rest++)      {	if (ch == '\\')	{		rest++;		if (! (ch = *rest))			break;	}      }      /* look through this directory and find the next filename component */      /* invariant: rest points to slash after the next filename component */      *rest = 0;      loc = 0;      do	{#ifdef E2DEBUG	  printf ("dirname=%s, rest=%s, loc=%d\n", dirname, rest, loc);#endif /* E2DEBUG */	  /* if our location/byte offset into the directory exceeds the size,	     give up */	  if (loc >= INODE->i_size)	    {# ifndef STAGE1_5	      if (print_possibilities < 0)		{# if 0		  putchar ('\n');# endif		  return 1;		}# endif /* STAGE1_5 */	      	      errnum = ERR_FILE_NOT_FOUND;	      *rest = ch;	      return 0;	    }	  /* else, find the (logical) block component of our location */	  blk = loc >> EXT2_BLOCK_SIZE_BITS (SUPERBLOCK);	  /* we know which logical block of the directory entry we are looking	     for, now we have to translate that to the physical (fs) block on	     the disk */	  map = ext2fs_block_map (blk);#ifdef E2DEBUG	  printf ("fs block=%d\n", map);#endif /* E2DEBUG */	  mapblock2 = -1;	  if ((map < 0) || !ext2_rdfsb (map, DATABLOCK2))	    {	      errnum = ERR_FSYS_CORRUPT;	      *rest = ch;	      return 0;	    }	  off = loc & (EXT2_BLOCK_SIZE (SUPERBLOCK) - 1);	  dp = (struct ext2_dir_entry *) (DATABLOCK2 + off);	  /* advance loc prematurely to next on-disk directory entry  */	  loc += dp->rec_len;	  /* NOTE: ext2fs filenames are NOT null-terminated */#ifdef E2DEBUG	  printf ("directory entry ino=%d\n", dp->inode);	  if (dp->inode)	    printf ("entry=%s\n", dp->name);#endif /* E2DEBUG */	  if (dp->inode)	    {	      //int saved_c = dp->name[dp->name_len];	      int j, k;	      char ch1;	      char *tmp_name= NAME_BUF;	/* EXT2_NAME_LEN is 255, so 512 byte buffer is needed. */	      /* copy dp->name to tmp_name, and quote the spaces with a '\\' */	      for (j = 0, k = 0; j < dp->name_len; j++)	      {		if (! (ch1 = dp->name[j]))			break;		if (ch1 == ' ')			tmp_name[k++] = '\\';		tmp_name[k++] = ch1;	      }	      tmp_name[k] = 0;	      //dp->name[dp->name_len] = 0;	      str_chk = substring (dirname, tmp_name, 0);# ifndef STAGE1_5	      if (print_possibilities && ch != '/'		  && (!*dirname || str_chk <= 0))		{		  if (print_possibilities > 0)		    print_possibilities = -print_possibilities;		  print_a_completion (tmp_name);		}# endif	      //dp->name[dp->name_len] = saved_c;	    }	}      while (!dp->inode || (str_chk || (print_possibilities && ch != '/')));      current_ino = dp->inode;      *(dirname = rest) = ch;    }  /* never get here */}#endif /* FSYS_EXT2_FS */

⌨️ 快捷键说明

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