/* cpio.c - cpio and tar filesystem.  */
/*
 *  GRUB  --  GRand Unified Bootloader
 *  Copyright (C) 2007,2008 Free Software Foundation, Inc.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <grub/file.h>
#include <grub/mm.h>
#include <grub/misc.h>
#include <grub/disk.h>
#include <grub/dl.h>

#ifndef MODE_USTAR
/* cpio support */
#define	MAGIC_BCPIO	070707
struct head
{
  grub_uint16_t magic;
  grub_uint16_t dev;
  grub_uint16_t ino;
  grub_uint16_t mode;
  grub_uint16_t uid;
  grub_uint16_t gid;
  grub_uint16_t nlink;
  grub_uint16_t rdev;
  grub_uint16_t mtime_1;
  grub_uint16_t mtime_2;
  grub_uint16_t namesize;
  grub_uint16_t filesize_1;
  grub_uint16_t filesize_2;
} __attribute__ ((packed));
#else
/* tar support */
#define MAGIC_USTAR	"ustar"
struct head
{
  char name[100];
  char mode[8];
  char uid[8];
  char gid[8];
  char size[12];
  char mtime[12];
  char chksum[8];
  char typeflag;
  char linkname[100];
  char magic[6];
  char version[2];
  char uname[32];
  char gname[32];
  char devmajor[8];
  char devminor[8];
  char prefix[155];
} __attribute__ ((packed));
#endif

struct grub_cpio_data
{
  grub_disk_t disk;
  grub_uint32_t hofs;
  grub_uint32_t dofs;
  grub_uint32_t size;
};

static grub_dl_t my_mod;

static grub_err_t
grub_cpio_find_file (struct grub_cpio_data *data, char **name,
		     grub_uint32_t * ofs)
{
#ifndef MODE_USTAR
      struct head hd;

      if (grub_disk_read
	  (data->disk, 0, data->hofs, sizeof (hd), &hd))
	return grub_errno;

      if (hd.magic != MAGIC_BCPIO)
	return grub_error (GRUB_ERR_BAD_FS, "Invalid cpio archive");

      data->size = (((grub_uint32_t) hd.filesize_1) << 16) + hd.filesize_2;

      if (hd.namesize & 1)
	hd.namesize++;

      if ((*name = grub_malloc (hd.namesize)) == NULL)
	return grub_errno;

      if (grub_disk_read (data->disk, 0, data->hofs + sizeof (hd),
			  hd.namesize, *name))
	{
	  grub_free (*name);
	  return grub_errno;
	}

      if (data->size == 0 && hd.mode == 0 && hd.namesize == 11 + 1
	  && ! grub_memcmp(*name, "TRAILER!!!", 11))
	{
	  *ofs = 0;
	  return GRUB_ERR_NONE;
	}

      data->dofs = data->hofs + sizeof (hd) + hd.namesize;
      *ofs = data->dofs + data->size;
      if (data->size & 1)
	(*ofs)++;
#else
      struct head hd;

      if (grub_disk_read
	  (data->disk, 0, data->hofs, sizeof (hd), &hd))
	return grub_errno;

      if (!hd.name[0])
	{
	  *ofs = 0;
	  return GRUB_ERR_NONE;
	}

      if (grub_memcmp (hd.magic, MAGIC_USTAR, sizeof (MAGIC_USTAR) - 1))
	return grub_error (GRUB_ERR_BAD_FS, "Invalid tar archive");

      if ((*name = grub_strdup (hd.name)) == NULL)
	return grub_errno;

      data->size = grub_strtoul (hd.size, NULL, 8);
      data->dofs = data->hofs + GRUB_DISK_SECTOR_SIZE;
      *ofs = data->dofs + ((data->size + GRUB_DISK_SECTOR_SIZE - 1) &
			   ~(GRUB_DISK_SECTOR_SIZE - 1));
#endif
  return GRUB_ERR_NONE;
}

static struct grub_cpio_data *
grub_cpio_mount (grub_disk_t disk)
{
  struct head hd;
  struct grub_cpio_data *data;

  if (grub_disk_read (disk, 0, 0, sizeof (hd), &hd))
    goto fail;

#ifndef MODE_USTAR
  if (hd.magic != MAGIC_BCPIO)
#else
  if (grub_memcmp (hd.magic, MAGIC_USTAR,
		   sizeof (MAGIC_USTAR) - 1))
#endif
    goto fail;

  data = (struct grub_cpio_data *) grub_malloc (sizeof (*data));
  if (!data)
    goto fail;

  data->disk = disk;

  return data;

fail:
  grub_error (GRUB_ERR_BAD_FS, "not a "
#ifdef MODE_USTAR
	      "tar"
#else
	      "cpio"
#endif
	      " filesystem");
  return 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;
}

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 = 1;
      j = 0;
      while (1)
	{
	  if (name[i] != fn[j])
	    goto no_match;

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

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

	  i++;
	  j++;
	}

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

static grub_ssize_t
grub_cpio_read (grub_file_t file, char *buf, grub_size_t len)
{
  struct grub_cpio_data *data;

  data = file->data;
  return (grub_disk_read (data->disk, 0, data->dofs + file->offset,
			  len, buf)) ? -1 : (grub_ssize_t) len;
}

static grub_err_t
grub_cpio_close (grub_file_t file)
{
  grub_free (file->data);

  grub_dl_unref (my_mod);

  return grub_errno;
}

static struct grub_fs grub_cpio_fs = {
#ifdef MODE_USTAR
  .name = "tarfs",
#else
  .name = "cpiofs",
#endif
  .dir = grub_cpio_dir,
  .open = grub_cpio_open,
  .read = grub_cpio_read,
  .close = grub_cpio_close,
};

#ifdef MODE_USTAR
GRUB_MOD_INIT (tar)
#else
GRUB_MOD_INIT (cpio)
#endif
{
  grub_fs_register (&grub_cpio_fs);
  my_mod = mod;
}

#ifdef MODE_USTAR
GRUB_MOD_FINI (tar)
#else
GRUB_MOD_FINI (cpio)
#endif
{
  grub_fs_unregister (&grub_cpio_fs);
}
