/* sfs.c - Amiga Smart FileSystem.  */
/*
 *  GRUB  --  GRand Unified Bootloader
 *  Copyright (C) 2005,2006,2007,2008,2009  Free Software Foundation, Inc.
 *
 *  GRUB 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.
 *
 *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <grub/err.h>
#include <grub/file.h>
#include <grub/mm.h>
#include <grub/misc.h>
#include <grub/disk.h>
#include <grub/dl.h>
#include <grub/types.h>
#include <grub/fshelp.h>
#include <grub/charset.h>

GRUB_MOD_LICENSE ("GPLv3+");

/* The common header for a block.  */
struct grub_sfs_bheader
{
  grub_uint8_t magic[4];
  grub_uint32_t chksum;
  grub_uint32_t ipointtomyself;
} GRUB_PACKED;

/* The sfs rootblock.  */
struct grub_sfs_rblock
{
  struct grub_sfs_bheader header;
  grub_uint32_t version;
  grub_uint32_t createtime;
  grub_uint8_t flags;
  grub_uint8_t unused1[31];
  grub_uint32_t blocksize;
  grub_uint8_t unused2[40];
  grub_uint8_t unused3[8];
  grub_uint32_t rootobject;
  grub_uint32_t btree;
} GRUB_PACKED;

enum
  {
    FLAGS_CASE_SENSITIVE = 0x80
  };

/* A SFS object container.  */
struct grub_sfs_obj
{
  grub_uint8_t unused1[4];
  grub_uint32_t nodeid;
  grub_uint8_t unused2[4];
  union
  {
    struct
    {
      grub_uint32_t first_block;
      grub_uint32_t size;
    } GRUB_PACKED file;
    struct
    {
      grub_uint32_t hashtable;
      grub_uint32_t dir_objc;
    } GRUB_PACKED dir;
  } file_dir;
  grub_uint32_t mtime;
  grub_uint8_t type;
  grub_uint8_t filename[1];
  grub_uint8_t comment[1];
} GRUB_PACKED;

#define	GRUB_SFS_TYPE_DELETED	32
#define	GRUB_SFS_TYPE_SYMLINK	64
#define	GRUB_SFS_TYPE_DIR	128

/* A SFS object container.  */
struct grub_sfs_objc
{
  struct grub_sfs_bheader header;
  grub_uint32_t parent;
  grub_uint32_t next;
  grub_uint32_t prev;
  /* The amount of objects depends on the blocksize.  */
  struct grub_sfs_obj objects[1];
} GRUB_PACKED;

struct grub_sfs_btree_node
{
  grub_uint32_t key;
  grub_uint32_t data;
} GRUB_PACKED;

struct grub_sfs_btree_extent
{
  grub_uint32_t key;
  grub_uint32_t next;
  grub_uint32_t prev;
  grub_uint16_t size;
} GRUB_PACKED;

struct grub_sfs_btree
{
  struct grub_sfs_bheader header;
  grub_uint16_t nodes;
  grub_uint8_t leaf;
  grub_uint8_t nodesize;
  /* Normally this can be kind of node, but just extents are
     supported.  */
  struct grub_sfs_btree_node node[1];
} GRUB_PACKED;



struct cache_entry
{
  grub_uint32_t off;
  grub_uint32_t block;
};

struct grub_fshelp_node
{
  struct grub_sfs_data *data;
  grub_uint32_t block;
  grub_uint32_t size;
  grub_uint32_t mtime;
  grub_uint32_t cache_off;
  grub_uint32_t next_extent;
  grub_size_t cache_allocated;
  grub_size_t cache_size;
  struct cache_entry *cache;
};

/* Information about a "mounted" sfs filesystem.  */
struct grub_sfs_data
{
  struct grub_sfs_rblock rblock;
  struct grub_fshelp_node diropen;
  grub_disk_t disk;

  /* Log of blocksize in sectors.  */
  int log_blocksize;

  int fshelp_flags;

  /* Label of the filesystem.  */
  char *label;
};

static grub_dl_t my_mod;


/* Lookup the extent starting with BLOCK in the filesystem described
   by DATA.  Return the extent size in SIZE and the following extent
   in NEXTEXT.  */
static grub_err_t
grub_sfs_read_extent (struct grub_sfs_data *data, unsigned int block,
		      grub_uint32_t *size, grub_uint32_t *nextext)
{
  char *treeblock;
  struct grub_sfs_btree *tree;
  int i;
  grub_uint32_t next;
  grub_size_t blocksize = GRUB_DISK_SECTOR_SIZE << data->log_blocksize;

  treeblock = grub_malloc (blocksize);
  if (!treeblock)
    return grub_errno;

  next = grub_be_to_cpu32 (data->rblock.btree);
  tree = (struct grub_sfs_btree *) treeblock;

  /* Handle this level in the btree.  */
  do
    {
      grub_uint16_t nnodes;
      grub_disk_read (data->disk,
		      ((grub_disk_addr_t) next) << data->log_blocksize,
		      0, blocksize, treeblock);
      if (grub_errno)
	{
	  grub_free (treeblock);
	  return grub_errno;
	}

      nnodes = grub_be_to_cpu16 (tree->nodes);
      if (nnodes * (grub_uint32_t) (tree)->nodesize > blocksize)
	break;

      for (i = (int) nnodes - 1; i >= 0; i--)
	{

#define EXTNODE(tree, index)						\
	((struct grub_sfs_btree_node *) (((char *) &(tree)->node[0])	\
					 + (index) * (tree)->nodesize))

	  /* Follow the tree down to the leaf level.  */
	  if ((grub_be_to_cpu32 (EXTNODE(tree, i)->key) <= block)
	      && !tree->leaf)
	    {
	      next = grub_be_to_cpu32 (EXTNODE (tree, i)->data);
	      break;
	    }

	  /* If the leaf level is reached, just find the correct extent.  */
	  if (grub_be_to_cpu32 (EXTNODE (tree, i)->key) == block && tree->leaf)
	    {
	      struct grub_sfs_btree_extent *extent;
	      extent = (struct grub_sfs_btree_extent *) EXTNODE (tree, i);

	      /* We found a correct leaf.  */
	      *size = grub_be_to_cpu16 (extent->size);
	      *nextext = grub_be_to_cpu32 (extent->next);

	      grub_free (treeblock);
	      return 0;
	    }

#undef EXTNODE

	}
    } while (!tree->leaf);

  grub_free (treeblock);

  return grub_error (GRUB_ERR_FILE_READ_ERROR, "SFS extent not found");
}

static grub_disk_addr_t
grub_sfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
{
  grub_uint32_t blk;
  grub_uint32_t size = 0;
  grub_uint32_t next = 0;
  grub_disk_addr_t off;
  struct grub_sfs_data *data = node->data;

  /* In case of the first block we don't have to lookup the
     extent, the minimum size is always 1.  */
  if (fileblock == 0)
    return node->block;

  if (!node->cache)
    {
      grub_size_t cache_size;
      /* Assume half-max extents (32768 sectors).  */
      cache_size = ((node->size >> (data->log_blocksize + GRUB_DISK_SECTOR_BITS
				    + 15))
		    + 3);
      if (cache_size < 8)
	cache_size = 8;

      node->cache_off = 0;
      node->next_extent = node->block;
      node->cache_size = 0;

      node->cache = grub_malloc (sizeof (node->cache[0]) * cache_size);
      if (!node->cache)
	{
	  grub_errno = 0;
	  node->cache_allocated = 0;
	}
      else
	{
	  node->cache_allocated = cache_size;
	  node->cache[0].off = 0;
	  node->cache[0].block = node->block;
	}
    }

  if (fileblock < node->cache_off)
    {
      unsigned int i = 0;
      int j, lg;
      for (lg = 0; node->cache_size >> lg; lg++);

      for (j = lg - 1; j >= 0; j--)
	if ((i | (1 << j)) < node->cache_size
	    && node->cache[(i | (1 << j))].off <= fileblock)
	  i |= (1 << j);
      return node->cache[i].block + fileblock - node->cache[i].off;
    }

  off = node->cache_off;
  blk = node->next_extent;

  while (blk)
    {
      grub_err_t err;

      err = grub_sfs_read_extent (node->data, blk, &size, &next);
      if (err)
	return 0;

      if (node->cache && node->cache_size >= node->cache_allocated)
	{
	  struct cache_entry *e = node->cache;
	  e = grub_realloc (node->cache,node->cache_allocated * 2
			    * sizeof (e[0]));
	  if (!e)
	    {
	      grub_errno = 0;
	      grub_free (node->cache);
	      node->cache = 0;
	    }
	  else
	    {
	      node->cache_allocated *= 2;
	      node->cache = e;
	    }
	}

      if (node->cache)
	{
	  node->cache_off = off + size;
	  node->next_extent = next;
	  node->cache[node->cache_size].off = off;
	  node->cache[node->cache_size].block = blk;
	  node->cache_size++;
	}

      if (fileblock - off < size)
	return fileblock - off + blk;

      off += size;

      blk = next;
    }

  grub_error (GRUB_ERR_FILE_READ_ERROR,
	      "reading a SFS block outside the extent");

  return 0;
}


/* Read LEN bytes from the file described by DATA starting with byte
   POS.  Return the amount of read bytes in READ.  */
static grub_ssize_t
grub_sfs_read_file (grub_fshelp_node_t node,
		    grub_disk_read_hook_t read_hook, void *read_hook_data,
		    grub_off_t pos, grub_size_t len, char *buf)
{
  return grub_fshelp_read_file (node->data->disk, node,
				read_hook, read_hook_data,
				pos, len, buf, grub_sfs_read_block,
				node->size, node->data->log_blocksize, 0);
}


static struct grub_sfs_data *
grub_sfs_mount (grub_disk_t disk)
{
  struct grub_sfs_data *data;
  struct grub_sfs_objc *rootobjc;
  char *rootobjc_data = 0;
  grub_uint32_t blk;

  data = grub_malloc (sizeof (*data));
  if (!data)
    return 0;

  /* Read the rootblock.  */
  grub_disk_read (disk, 0, 0, sizeof (struct grub_sfs_rblock),
		  &data->rblock);
  if (grub_errno)
    goto fail;

  /* Make sure this is a sfs filesystem.  */
  if (grub_strncmp ((char *) (data->rblock.header.magic), "SFS", 4)
      || data->rblock.blocksize == 0
      || (data->rblock.blocksize & (data->rblock.blocksize - 1)) != 0
      || (data->rblock.blocksize & grub_cpu_to_be32_compile_time (0xf00001ff)))
    {
      grub_error (GRUB_ERR_BAD_FS, "not a SFS filesystem");
      goto fail;
    }

  for (data->log_blocksize = 9;
       (1U << data->log_blocksize) < grub_be_to_cpu32 (data->rblock.blocksize);
       data->log_blocksize++);
  data->log_blocksize -= GRUB_DISK_SECTOR_BITS;
  if (data->rblock.flags & FLAGS_CASE_SENSITIVE)
    data->fshelp_flags = 0;
  else
    data->fshelp_flags = GRUB_FSHELP_CASE_INSENSITIVE;
  rootobjc_data = grub_malloc (GRUB_DISK_SECTOR_SIZE << data->log_blocksize);
  if (! rootobjc_data)
    goto fail;

  /* Read the root object container.  */
  grub_disk_read (disk, ((grub_disk_addr_t) grub_be_to_cpu32 (data->rblock.rootobject))
		  << data->log_blocksize, 0,
		  GRUB_DISK_SECTOR_SIZE << data->log_blocksize, rootobjc_data);
  if (grub_errno)
    goto fail;

  rootobjc = (struct grub_sfs_objc *) rootobjc_data;

  blk = grub_be_to_cpu32 (rootobjc->objects[0].file_dir.dir.dir_objc);
  data->diropen.size = 0;
  data->diropen.block = blk;
  data->diropen.data = data;
  data->diropen.cache = 0;
  data->disk = disk;
  data->label = grub_strdup ((char *) (rootobjc->objects[0].filename));

  grub_free (rootobjc_data);
  return data;

 fail:
  if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
    grub_error (GRUB_ERR_BAD_FS, "not an SFS filesystem");

  grub_free (data);
  grub_free (rootobjc_data);
  return 0;
}


static char *
grub_sfs_read_symlink (grub_fshelp_node_t node)
{
  struct grub_sfs_data *data = node->data;
  char *symlink;
  char *block;

  block = grub_malloc (GRUB_DISK_SECTOR_SIZE << data->log_blocksize);
  if (!block)
    return 0;

  grub_disk_read (data->disk, ((grub_disk_addr_t) node->block)
		  << data->log_blocksize,
		  0, GRUB_DISK_SECTOR_SIZE << data->log_blocksize, block);
  if (grub_errno)
    {
      grub_free (block);
      return 0;
    }

  /* This is just a wild guess, but it always worked for me.  How the
     SLNK block looks like is not documented in the SFS docs.  */
  symlink = grub_malloc (((GRUB_DISK_SECTOR_SIZE << data->log_blocksize)
			  - 24) * GRUB_MAX_UTF8_PER_LATIN1 + 1);
  if (!symlink)
    {
      grub_free (block);
      return 0;
    }
  *grub_latin1_to_utf8 ((grub_uint8_t *) symlink, (grub_uint8_t *) &block[24],
			(GRUB_DISK_SECTOR_SIZE << data->log_blocksize) - 24) = '\0';
  grub_free (block);
  return symlink;
}

/* Helper for grub_sfs_iterate_dir.  */
static int
grub_sfs_create_node (struct grub_fshelp_node **node,
		      struct grub_sfs_data *data,
		      const char *name,
		      grub_uint32_t block, grub_uint32_t size, int type,
		      grub_uint32_t mtime,
		      grub_fshelp_iterate_dir_hook_t hook, void *hook_data)
{
  grub_size_t len = grub_strlen (name);
  grub_uint8_t *name_u8;
  int ret;
  *node = grub_malloc (sizeof (**node));
  if (!*node)
    return 1;
  name_u8 = grub_malloc (len * GRUB_MAX_UTF8_PER_LATIN1 + 1);
  if (!name_u8)
    {
      grub_free (*node);
      return 1;
    }

  (*node)->data = data;
  (*node)->size = size;
  (*node)->block = block;
  (*node)->mtime = mtime;
  (*node)->cache = 0;
  (*node)->cache_off = 0;
  (*node)->next_extent = block;
  (*node)->cache_size = 0;
  (*node)->cache_allocated = 0;

  *grub_latin1_to_utf8 (name_u8, (const grub_uint8_t *) name, len) = '\0';

  ret = hook ((char *) name_u8, type | data->fshelp_flags, *node, hook_data);
  grub_free (name_u8);
  return ret;
}

static int
grub_sfs_iterate_dir (grub_fshelp_node_t dir,
		      grub_fshelp_iterate_dir_hook_t hook, void *hook_data)
{
  struct grub_fshelp_node *node = 0;
  struct grub_sfs_data *data = dir->data;
  char *objc_data;
  struct grub_sfs_objc *objc;
  unsigned int next = dir->block;
  grub_uint32_t pos;

  objc_data = grub_malloc (GRUB_DISK_SECTOR_SIZE << data->log_blocksize);
  if (!objc_data)
    goto fail;

  /* The Object container can consist of multiple blocks, iterate over
     every block.  */
  while (next)
    {
      grub_disk_read (data->disk, ((grub_disk_addr_t) next)
		      << data->log_blocksize, 0,
		      GRUB_DISK_SECTOR_SIZE << data->log_blocksize, objc_data);
      if (grub_errno)
	goto fail;

      objc = (struct grub_sfs_objc *) objc_data;

      pos = (char *) &objc->objects[0] - (char *) objc;

      /* Iterate over all entries in this block.  */
      while (pos + sizeof (struct grub_sfs_obj)
	     < (1U << (GRUB_DISK_SECTOR_BITS + data->log_blocksize)))
	{
	  struct grub_sfs_obj *obj;
	  obj = (struct grub_sfs_obj *) ((char *) objc + pos);
	  const char *filename = (const char *) obj->filename;
	  grub_size_t len;
	  enum grub_fshelp_filetype type;
	  grub_uint32_t block;

	  /* The filename and comment dynamically increase the size of
	     the object.  */
	  len = grub_strlen (filename);
	  len += grub_strlen (filename + len + 1);

	  pos += sizeof (*obj) + len;
	  /* Round up to a multiple of two bytes.  */
	  pos = ((pos + 1) >> 1) << 1;

	  if (filename[0] == 0)
	    continue;

	  /* First check if the file was not deleted.  */
	  if (obj->type & GRUB_SFS_TYPE_DELETED)
	    continue;
	  else if (obj->type & GRUB_SFS_TYPE_SYMLINK)
	    type = GRUB_FSHELP_SYMLINK;
	  else if (obj->type & GRUB_SFS_TYPE_DIR)
	    type = GRUB_FSHELP_DIR;
	  else
	    type = GRUB_FSHELP_REG;

	  if (type == GRUB_FSHELP_DIR)
	    block = grub_be_to_cpu32 (obj->file_dir.dir.dir_objc);
	  else
	    block = grub_be_to_cpu32 (obj->file_dir.file.first_block);

	  if (grub_sfs_create_node (&node, data, filename, block,
				    grub_be_to_cpu32 (obj->file_dir.file.size),
				    type, grub_be_to_cpu32 (obj->mtime),
				    hook, hook_data))
	    {
	      grub_free (objc_data);
	      return 1;
	    }
	}

      next = grub_be_to_cpu32 (objc->next);
    }

 fail:
  grub_free (objc_data);
  return 0;
}


/* Open a file named NAME and initialize FILE.  */
static grub_err_t
grub_sfs_open (struct grub_file *file, const char *name)
{
  struct grub_sfs_data *data;
  struct grub_fshelp_node *fdiro = 0;

  grub_dl_ref (my_mod);

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

  grub_fshelp_find_file (name, &data->diropen, &fdiro, grub_sfs_iterate_dir,
			 grub_sfs_read_symlink, GRUB_FSHELP_REG);
  if (grub_errno)
    goto fail;

  file->size = fdiro->size;
  data->diropen = *fdiro;
  grub_free (fdiro);

  file->data = data;
  file->offset = 0;

  return 0;

 fail:
  if (data && fdiro != &data->diropen)
    grub_free (fdiro);
  if (data)
    grub_free (data->label);
  grub_free (data);

  grub_dl_unref (my_mod);

  return grub_errno;
}


static grub_err_t
grub_sfs_close (grub_file_t file)
{
  struct grub_sfs_data *data = (struct grub_sfs_data *) file->data;

  grub_free (data->diropen.cache);
  grub_free (data->label);
  grub_free (data);

  grub_dl_unref (my_mod);

  return GRUB_ERR_NONE;
}


/* Read LEN bytes data from FILE into BUF.  */
static grub_ssize_t
grub_sfs_read (grub_file_t file, char *buf, grub_size_t len)
{
  struct grub_sfs_data *data = (struct grub_sfs_data *) file->data;

  return grub_sfs_read_file (&data->diropen,
			     file->read_hook, file->read_hook_data,
			     file->offset, len, buf);
}


/* Context for grub_sfs_dir.  */
struct grub_sfs_dir_ctx
{
  grub_fs_dir_hook_t hook;
  void *hook_data;
};

/* Helper for grub_sfs_dir.  */
static int
grub_sfs_dir_iter (const char *filename, enum grub_fshelp_filetype filetype,
		   grub_fshelp_node_t node, void *data)
{
  struct grub_sfs_dir_ctx *ctx = data;
  struct grub_dirhook_info info;

  grub_memset (&info, 0, sizeof (info));
  info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
  info.mtime = node->mtime + 8 * 365 * 86400 + 86400 * 2;
  info.mtimeset = 1;
  grub_free (node->cache);
  grub_free (node);
  return ctx->hook (filename, &info, ctx->hook_data);
}

static grub_err_t
grub_sfs_dir (grub_device_t device, const char *path,
	      grub_fs_dir_hook_t hook, void *hook_data)
{
  struct grub_sfs_dir_ctx ctx = { hook, hook_data };
  struct grub_sfs_data *data = 0;
  struct grub_fshelp_node *fdiro = 0;

  grub_dl_ref (my_mod);

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

  grub_fshelp_find_file (path, &data->diropen, &fdiro, grub_sfs_iterate_dir,
			grub_sfs_read_symlink, GRUB_FSHELP_DIR);
  if (grub_errno)
    goto fail;

  grub_sfs_iterate_dir (fdiro, grub_sfs_dir_iter, &ctx);

 fail:
  if (data && fdiro != &data->diropen)
    grub_free (fdiro);
  if (data)
    grub_free (data->label);
  grub_free (data);

  grub_dl_unref (my_mod);

  return grub_errno;
}


static grub_err_t
grub_sfs_label (grub_device_t device, char **label)
{
  struct grub_sfs_data *data;
  grub_disk_t disk = device->disk;

  data = grub_sfs_mount (disk);
  if (data)
    {
      grub_size_t len = grub_strlen (data->label);
      *label = grub_malloc (len * GRUB_MAX_UTF8_PER_LATIN1 + 1);
      if (*label)
	*grub_latin1_to_utf8 ((grub_uint8_t *) *label,
			      (const grub_uint8_t *) data->label,
			      len) = '\0';
      grub_free (data->label);
    }
  grub_free (data);

  return grub_errno;
}


static struct grub_fs grub_sfs_fs =
  {
    .name = "sfs",
    .dir = grub_sfs_dir,
    .open = grub_sfs_open,
    .read = grub_sfs_read,
    .close = grub_sfs_close,
    .label = grub_sfs_label,
#ifdef GRUB_UTIL
    .reserved_first_sector = 0,
    .blocklist_install = 1,
#endif
    .next = 0
  };

GRUB_MOD_INIT(sfs)
{
  grub_fs_register (&grub_sfs_fs);
  my_mod = mod;
}

GRUB_MOD_FINI(sfs)
{
  grub_fs_unregister (&grub_sfs_fs);
}
