Ejemplo n.º 1
0
static grub_err_t
grub_cpio_dir (grub_device_t device, const char *path_in,
	       grub_fs_dir_hook_t hook, void *hook_data)
{
  struct grub_archelp_data *data;
  grub_err_t err;

  data = grub_cpio_mount (device->disk);
  if (!data)
    return grub_errno;

  err = grub_archelp_dir (data, &arcops,
			  path_in, hook, hook_data);

  grub_free (data);

  return err;
}
Ejemplo n.º 2
0
static grub_err_t
grub_cpio_open (grub_file_t file, const char *name_in)
{
  struct grub_archelp_data *data;
  grub_err_t err;

  data = grub_cpio_mount (file->device->disk);
  if (!data)
    return grub_errno;

  err = grub_archelp_open (data, &arcops, name_in);
  if (err)
    {
      grub_free (data);
    }
  else
    {
      file->data = data;
      file->size = data->size;
    }
  return err;
}
Ejemplo n.º 3
0
static grub_err_t
grub_cpio_open (grub_file_t file, const char *name)
{
  struct grub_cpio_data *data;
  grub_uint32_t ofs;
  char *fn;
  int i, j;

  grub_dl_ref (my_mod);

  data = grub_cpio_mount (file->device->disk);
  if (!data)
    goto fail;

  data->hofs = 0;
  while (1)
    {
      if (grub_cpio_find_file (data, &fn, &ofs))
	goto fail;

      if (!ofs)
	{
	  grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
	  break;
	}

      /* Compare NAME and FN by hand in order to cope with duplicate
	 slashes.  */
      i = 0;
      j = 0;
      while (name[i] == '/')
	i++;
      while (1)
	{
	  if (name[i] != fn[j])
	    goto no_match;

	  if (name[i] == '\0')
	    break;

	  while (name[i] == '/' && name[i+1] == '/')
	    i++;

	  i++;
	  j++;
	}

      if (name[i] != fn[j])
	goto no_match;

      file->data = data;
      file->size = data->size;
      grub_free (fn);

      return GRUB_ERR_NONE;

    no_match:

      grub_free (fn);
      data->hofs = ofs;
    }

fail:

  if (data)
    grub_free (data);

  grub_dl_unref (my_mod);

  return grub_errno;
}
Ejemplo n.º 4
0
static grub_err_t
grub_cpio_dir (grub_device_t device, const char *path,
	       int (*hook) (const char *filename,
			    const struct grub_dirhook_info *info))
{
  struct grub_cpio_data *data;
  grub_uint32_t ofs;
  char *prev, *name;
  const char *np;
  int len;

  grub_dl_ref (my_mod);

  prev = 0;

  data = grub_cpio_mount (device->disk);
  if (!data)
    goto fail;

  np = path + 1;
  len = grub_strlen (path) - 1;

  data->hofs = 0;
  while (1)
    {
      if (grub_cpio_find_file (data, &name, &ofs))
	goto fail;

      if (!ofs)
	break;

      if (grub_memcmp (np, name, len) == 0)
	{
	  char *p, *n;

	  n = name + len;
	  if (*n == '/')
	    n++;

	  p = grub_strchr (name + len, '/');
	  if (p)
	    *p = 0;

	  if ((!prev) || (grub_strcmp (prev, name) != 0))
	    {
	      struct grub_dirhook_info info;
	      grub_memset (&info, 0, sizeof (info));
	      info.dir = (p != NULL);

	      hook (name + len, &info);
	      if (prev)
		grub_free (prev);
	      prev = name;
	    }
	  else
	    grub_free (name);
	}
      data->hofs = ofs;
    }

fail:

  if (prev)
    grub_free (prev);

  if (data)
    grub_free (data);

  grub_dl_unref (my_mod);

  return grub_errno;
}
Ejemplo n.º 5
0
static grub_err_t
grub_cpio_open (grub_file_t file, const char *name_in)
{
  struct grub_cpio_data *data;
  grub_disk_addr_t ofs;
  char *fn;
  char *name = grub_strdup (name_in + 1);
  int symlinknest = 0;

  if (!name)
    return grub_errno;

  canonicalize (name);

  grub_dl_ref (my_mod);

  data = grub_cpio_mount (file->device->disk);
  if (!data)
    {
      grub_free (name);
      return grub_errno;
    }

  data->hofs = 0;
  while (1)
    {
      grub_uint32_t mode;
      int restart;
      
      if (grub_cpio_find_file (data, &fn, NULL, &ofs, &mode))
	goto fail;

      if (!ofs)
	{
	  grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), name_in);
	  break;
	}

      if (handle_symlink (data, fn, &name, mode, &restart))
	{
	  grub_free (fn);
	  goto fail;
	}

      if (restart)
	{
	  ofs = 0;
	  if (++symlinknest == 8)
	    {
	      grub_error (GRUB_ERR_SYMLINK_LOOP,
			  N_("too deep nesting of symlinks"));
	      goto fail;
	    }
	  goto no_match;
	}

      if (grub_strcmp (name, fn) != 0)
	goto no_match;

      file->data = data;
      file->size = data->size;
      grub_free (fn);
      grub_free (name);

      return GRUB_ERR_NONE;

    no_match:

      grub_free (fn);
      data->hofs = ofs;
    }

fail:
#ifdef MODE_USTAR
  grub_free (data->linkname);
#endif
  grub_free (data);
  grub_free (name);

  grub_dl_unref (my_mod);

  return grub_errno;
}
Ejemplo n.º 6
0
static grub_err_t
grub_cpio_dir (grub_device_t device, const char *path_in,
	       int (*hook) (const char *filename,
			    const struct grub_dirhook_info *info))
{
  struct grub_cpio_data *data;
  grub_disk_addr_t ofs;
  char *prev, *name, *path, *ptr;
  grub_size_t len;
  int symlinknest = 0;

  path = grub_strdup (path_in + 1);
  if (!path)
    return grub_errno;
  canonicalize (path);
  for (ptr = path + grub_strlen (path) - 1; ptr >= path && *ptr == '/'; ptr--)
    *ptr = 0;

  grub_dl_ref (my_mod);

  prev = 0;

  data = grub_cpio_mount (device->disk);
  if (!data)
    {
      grub_free (path);
      return grub_errno;
    }

  len = grub_strlen (path);
  data->hofs = 0;
  while (1)
    {
      grub_int32_t mtime;
      grub_uint32_t mode;
      grub_err_t err;

      if (grub_cpio_find_file (data, &name, &mtime, &ofs, &mode))
	goto fail;

      if (!ofs)
	break;

      if (grub_memcmp (path, name, len) == 0
	  && (name[len] == 0 || name[len] == '/' || len == 0))
	{
	  char *p, *n;

	  n = name + len;
	  while (*n == '/')
	    n++;

	  p = grub_strchr (n, '/');
	  if (p)
	    *p = 0;

	  if (((!prev) || (grub_strcmp (prev, name) != 0)) && *n != 0)
	    {
	      struct grub_dirhook_info info;
	      grub_memset (&info, 0, sizeof (info));
	      info.dir = (p != NULL) || ((mode & ATTR_TYPE) == ATTR_DIR);
	      info.mtime = mtime;
	      info.mtimeset = 1;

	      if (hook (n, &info))
		{
		  grub_free (name);
		  goto fail;
		}
	      grub_free (prev);
	      prev = name;
	    }
	  else
	    {
	      int restart = 0;
	      err = handle_symlink (data, name, &path, mode, &restart);
	      grub_free (name);
	      if (err)
		goto fail;
	      if (restart)
		{
		  len = grub_strlen (path);
		  if (++symlinknest == 8)
		    {
		      grub_error (GRUB_ERR_SYMLINK_LOOP,
				  N_("too deep nesting of symlinks"));
		      goto fail;
		    }
		  ofs = 0;
		}
	    }
	}
      else
	grub_free (name);
      data->hofs = ofs;
    }

fail:

  grub_free (path);
  grub_free (prev);
#ifdef MODE_USTAR
  grub_free (data->linkname);
#endif
  grub_free (data);

  grub_dl_unref (my_mod);

  return grub_errno;
}