int
ffs_dir (char *dirname)
{
  char *rest, ch;
  int block, off, loc, map, ino = ROOTINO;
  struct direct *dp;

/* main loop to find destination inode */
loop:

  /* load current inode (defaults to the root inode) */

	if (!devread (fsbtodb (SUPERBLOCK, itod (SUPERBLOCK, ino)),
								ino % (SUPERBLOCK->fs_inopb) * sizeof (struct dinode),
								sizeof (struct dinode), (char *) INODE))
			return 0;			/* XXX what return value? */

  /* if we have a real file (and we're not just printing possibilities),
     then this is where we want to exit */

  if (!*dirname || isspace (*dirname))
    {
      if ((INODE->i_mode & IFMT) != IFREG)
	{
	  errnum = ERR_BAD_FILETYPE;
	  return 0;
	}

      filemax = INODE->i_size;

      /* incomplete implementation requires this! */
      fsmax = (NDADDR + NINDIR (SUPERBLOCK)) * SUPERBLOCK->fs_bsize;
      return 1;
    }

  /* continue with file/directory name interpretation */

  while (*dirname == '/')
    dirname++;

  if (!(INODE->i_size) || ((INODE->i_mode & IFMT) != IFDIR))
    {
      errnum = ERR_BAD_FILETYPE;
      return 0;
    }

  for (rest = dirname; (ch = *rest) && !isspace (ch) && ch != '/'; rest++);

  *rest = 0;
  loc = 0;

  /* loop for reading a the entries in a directory */

  do
    {
      if (loc >= INODE->i_size)
	{
#if 0
	  putchar ('\n');
#endif

	  if (print_possibilities < 0)
	    return 1;

	  errnum = ERR_FILE_NOT_FOUND;
	  *rest = ch;
	  return 0;
	}

      if (!(off = blkoff (SUPERBLOCK, loc)))
	{
	  block = lblkno (SUPERBLOCK, loc);

	  if ((map = block_map (block)) < 0
	      || !devread (fsbtodb (SUPERBLOCK, map), 0,
			   blksize (SUPERBLOCK, INODE, block),
			   (char *) FSYS_BUF))
	    {
	      errnum = ERR_FSYS_CORRUPT;
	      *rest = ch;
	      return 0;
	    }
	}

      dp = (struct direct *) (FSYS_BUF + off);
      loc += dp->d_reclen;

#ifndef STAGE1_5
      if (dp->d_ino && print_possibilities && ch != '/'
	  && (!*dirname || substring (dirname, dp->d_name) <= 0))
	{
	  if (print_possibilities > 0)
	    print_possibilities = -print_possibilities;

	  print_a_completion (dp->d_name);
	}
#endif /* STAGE1_5 */
    }
  while (!dp->d_ino || (substring (dirname, dp->d_name) != 0
			|| (print_possibilities && ch != '/')));

  /* only get here if we have a matching directory entry */

  ino = dp->d_ino;
  *(dirname = rest) = ch;

  /* go back to main loop at top of function */
  goto loop;
}
Example #2
0
int
ufs2_dir (char *dirname)
{
  char *rest, ch;
  unsigned long block, off, loc, ino = ROOTINO;
  grub_int64_t map;
  struct direct *dp;
  int j, k;
  char ch1;
#ifdef GRUB_UTIL
  char tmp_name[512];
#else
  char *tmp_name = (char *)(NAME_BUF);	/* MAXNAMLEN is 255, so 512 byte buffer is needed. */
#endif

/* main loop to find destination inode */
loop:

  /* load current inode (defaults to the root inode) */

    if (!devread (fsbtodb (SUPERBLOCK, ino_to_fsba (SUPERBLOCK, ino)),
	    ino % (SUPERBLOCK->fs_inopb) * sizeof (struct ufs2_dinode),
	    sizeof (struct ufs2_dinode), (char *) INODE_UFS2, 0xedde0d90))
		    return 0;			/* XXX what return value? */

  /* if we have a real file (and we're not just printing possibilities),
     then this is where we want to exit */

  if (!*dirname || isspace (*dirname))
    {
      if ((INODE_UFS2->di_mode & IFMT) != IFREG)
	{
	  errnum = ERR_BAD_FILETYPE;
	  return 0;
	}

      filemax = INODE_UFS2->di_size;

      /* incomplete implementation requires this! */
      fsmax = (NDADDR + NINDIR (SUPERBLOCK)) * SUPERBLOCK->fs_bsize;
      return 1;
    }

  /* continue with file/directory name interpretation */

  while (*dirname == '/')
    dirname++;

  if (!(INODE_UFS2->di_size) || ((INODE_UFS2->di_mode & IFMT) != IFDIR))
    {
      errnum = ERR_BAD_FILETYPE;
      return 0;
    }

  //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;
	}
  }

  *rest = 0;
  loc = 0;

  /* loop for reading a the entries in a directory */

  do
    {
      if (loc >= INODE_UFS2->di_size)
	{
	  if (print_possibilities < 0)
	    return 1;

	  errnum = ERR_FILE_NOT_FOUND;
	  *rest = ch;
	  return 0;
	}

      if (!(off = blkoff (SUPERBLOCK, loc)))
	{
	  block = lblkno (SUPERBLOCK, loc);

	  if ((map = block_map (block)) < 0
	      || !devread (fsbtodb (SUPERBLOCK, map), 0,
			   blksize (SUPERBLOCK, INODE_UFS2, block),
			   (char *) FSYS_BUF, 0xedde0d90))
	    {
	      errnum = ERR_FSYS_CORRUPT;
	      *rest = ch;
	      return 0;
	    }
	}

      dp = (struct direct *) (FSYS_BUF + off);
      loc += dp->d_reclen;

	/* copy dp->name to tmp_name, and quote the spaces with a '\\' */
	for (j = 0, k = 0; j < dp->d_namlen; j++)
	{
		if (! (ch1 = dp->d_name[j]))
			break;
		if (ch1 == ' ')
			tmp_name[k++] = '\\';
		tmp_name[k++] = ch1;
	}
	tmp_name[k] = 0;

#ifndef STAGE1_5
      if (dp->d_ino && print_possibilities && ch != '/'
	  && (!*dirname || substring (dirname, tmp_name, 0) <= 0))
	{
	  if (print_possibilities > 0)
	    print_possibilities = -print_possibilities;

	  print_a_completion (tmp_name);
	}
#endif /* STAGE1_5 */
    }
  while (!dp->d_ino || (substring (dirname, dp->d_name, 0) != 0
			|| (print_possibilities && ch != '/')));

  /* only get here if we have a matching directory entry */

  ino = dp->d_ino;
  *(dirname = rest) = ch;

  /* go back to main loop at top of function */
  goto loop;
}
Example #3
0
int 
vstafs_dir (char *dirname)
{
  char *fn, ch;
  struct dir_entry *d;
  /* int l, i, s; */
  
  /*
   * Read in the entries of the current directory.
   */
  f_sector = ROOT_SECTOR;
  do
    {
      if (! (d = vstafs_readdir (f_sector)))
	{
	  return 0;
	}
      
      /*
       * Find the file in the path
       */
      while (*dirname == '/') dirname++;
      //fn = dirname;
      //while ((ch = *fn) && ch != '/' && ! isspace (ch)) fn++;
      for (fn = dirname; (ch = *fn) && ch != '/' && !isspace (ch); fn++)
      {
	if (ch == '\\')
	{
		fn++;
		if (! (ch = *fn))
			break;
	}
      }
      *fn = 0;
      
      do
	{
	  int j, k;
	  char ch1;
#ifdef GRUB_UTIL
	  char tmp_name[512];
#else
	  char *tmp_name = NAME_BUF;	/* MAXNAMLEN is 255, so 512 byte buffer is needed. */
#endif

	  if (d->name[0] == 0/* || d->name[0] & 0x80*/)
	    continue;
	  
	  /* copy d->name to tmp_name, and quote the spaces with a '\\' */
	  for (j = 0, k = 0; j < 28/*d->namlen*/; j++)
	  {
		if (! (ch1 = d->name[j]))
			break;
		if (ch1 == ' ')
			tmp_name[k++] = '\\';
		tmp_name[k++] = ch1;
	  }
	  tmp_name[k] = 0;

#ifndef STAGE1_5
	  if (print_possibilities && ch != '/'
	      && (! *dirname || strcmp (dirname, tmp_name) <= 0))
	    {
	      if (print_possibilities > 0)
		print_possibilities = -print_possibilities;
	      
	      //printf ("  %s", d->name);
	      print_a_completion (tmp_name);
	    }
#endif
	  if (! grub_strcmp (dirname, tmp_name))
	    {
	      f_sector = d->start;
	      get_file_info (f_sector);
	      filemax = FILE_INFO->len; 
	      break;
	    }
	}
      while ((d =vstafs_nextdir ()));
      
      *(dirname = fn) = ch;
      
      if (! d)
	{
	  if (print_possibilities < 0)
	    {
	      putchar ('\n');
	      return 1;
	    }
	  
	  errnum = ERR_FILE_NOT_FOUND;
	  return 0;
	}
    }
  while (*dirname && ! isspace (ch));
  
  return 1;
}