/* hfs.c - HFS.  */
/*
 *  GRUB  --  GRand Unified Bootloader
 *  Copyright (C) 2004,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/>.
 */

/* HFS is documented at
   http://developer.apple.com/documentation/mac/Files/Files-2.html */

#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/hfs.h>
#include <grub/i18n.h>
#include <grub/fshelp.h>

GRUB_MOD_LICENSE ("GPLv3+");

#define	GRUB_HFS_SBLOCK		2
#define GRUB_HFS_EMBED_HFSPLUS_SIG 0x482B

#define GRUB_HFS_BLKS		(data->blksz >> 9)

#define GRUB_HFS_NODE_LEAF	0xFF

/* The two supported filesystems a record can have.  */
enum
  {
    GRUB_HFS_FILETYPE_DIR = 1,
    GRUB_HFS_FILETYPE_FILE = 2
  };

/* Catalog node ID (CNID).  */
enum grub_hfs_cnid_type
  {
    GRUB_HFS_CNID_ROOT_PARENT = 1,
    GRUB_HFS_CNID_ROOT = 2,
    GRUB_HFS_CNID_EXT = 3,
    GRUB_HFS_CNID_CAT = 4,
    GRUB_HFS_CNID_BAD = 5
  };

/* A node descriptor.  This is the header of every node.  */
struct grub_hfs_node
{
  grub_uint32_t next;
  grub_uint32_t prev;
  grub_uint8_t type;
  grub_uint8_t level;
  grub_uint16_t reccnt;
  grub_uint16_t unused;
} GRUB_PACKED;

/* The head of the B*-Tree.  */
struct grub_hfs_treeheader
{
  grub_uint16_t tree_depth;
  /* The number of the first node.  */
  grub_uint32_t root_node;
  grub_uint32_t leaves;
  grub_uint32_t first_leaf;
  grub_uint32_t last_leaf;
  grub_uint16_t node_size;
  grub_uint16_t key_size;
  grub_uint32_t nodes;
  grub_uint32_t free_nodes;
  grub_uint8_t unused[76];
} GRUB_PACKED;

/* The state of a mounted HFS filesystem.  */
struct grub_hfs_data
{
  struct grub_hfs_sblock sblock;
  grub_disk_t disk;
  grub_hfs_datarecord_t extents;
  int fileid;
  int size;
  int ext_root;
  int ext_size;
  int cat_root;
  int cat_size;
  int blksz;
  int log2_blksz;
  int rootdir;
};

/* The key as used on disk in a catalog tree.  This is used to lookup
   file/directory nodes by parent directory ID and filename.  */
struct grub_hfs_catalog_key
{
  grub_uint8_t unused;
  grub_uint32_t parent_dir;

  /* Filename length.  */
  grub_uint8_t strlen;

  /* Filename.  */
  grub_uint8_t str[31];
} GRUB_PACKED;

/* The key as used on disk in a extent overflow tree.  Using this key
   the extents can be looked up using a fileid and logical start block
   as index.  */
struct grub_hfs_extent_key
{
  /* The kind of fork.  This is used to store meta information like
     icons, attributes, etc.  We will only use the datafork, which is
     0.  */
  grub_uint8_t forktype;
  grub_uint32_t fileid;
  grub_uint16_t first_block;
} GRUB_PACKED;

/* A directory record.  This is used to find out the directory ID.  */
struct grub_hfs_dirrec
{
  /* For a directory, type == 1.  */
  grub_uint8_t type;
  grub_uint8_t unused[5];
  grub_uint32_t dirid;
  grub_uint32_t ctime;
  grub_uint32_t mtime;
} GRUB_PACKED;

/* Information about a file.  */
struct grub_hfs_filerec
{
  /* For a file, type == 2.  */
  grub_uint8_t type;
  grub_uint8_t unused[19];
  grub_uint32_t fileid;
  grub_uint8_t unused2[2];
  grub_uint32_t size;
  grub_uint8_t unused3[18];
  grub_uint32_t mtime;
  grub_uint8_t unused4[22];

  /* The first 3 extents of the file.  The other extents can be found
     in the extent overflow file.  */
  grub_hfs_datarecord_t extents;
} GRUB_PACKED;

/* A record descriptor, both key and data, used to pass to call back
   functions.  */
struct grub_hfs_record
{
  void *key;
  grub_size_t keylen;
  void *data;
  grub_size_t datalen;
};

static grub_dl_t my_mod;

static int grub_hfs_find_node (struct grub_hfs_data *, char *,
			       grub_uint32_t, int, char *, grub_size_t);

/* Find block BLOCK of the file FILE in the mounted UFS filesystem
   DATA.  The first 3 extents are described by DAT.  If cache is set,
   using caching to improve non-random reads.  */
static unsigned int
grub_hfs_block (struct grub_hfs_data *data, grub_hfs_datarecord_t dat,
		int file, int block, int cache)
{
  grub_hfs_datarecord_t dr;
  int pos = 0;
  struct grub_hfs_extent_key key;

  int tree = 0;
  static int cache_file = 0;
  static int cache_pos = 0;
  static grub_hfs_datarecord_t cache_dr;

  grub_memcpy (dr, dat, sizeof (dr));

  key.forktype = 0;
  key.fileid = grub_cpu_to_be32 (file);

  if (cache && cache_file == file  && block > cache_pos)
    {
      pos = cache_pos;
      key.first_block = grub_cpu_to_be16 (pos);
      grub_memcpy (dr, cache_dr, sizeof (cache_dr));
    }

  for (;;)
    {
      int i;

      /* Try all 3 extents.  */
      for (i = 0; i < 3; i++)
	{
	  /* Check if the block is stored in this extent.  */
	  if (grub_be_to_cpu16 (dr[i].count) + pos > block)
	    {
	      int first = grub_be_to_cpu16 (dr[i].first_block);

	      /* If the cache is enabled, store the current position
		 in the tree.  */
	      if (tree && cache)
		{
		  cache_file = file;
		  cache_pos = pos;
		  grub_memcpy (cache_dr, dr, sizeof (cache_dr));
		}

	      return (grub_be_to_cpu16 (data->sblock.first_block)
		      + (first + block - pos) * GRUB_HFS_BLKS);
	    }

	  /* Try the next extent.  */
	  pos += grub_be_to_cpu16 (dr[i].count);
	}

      /* Lookup the block in the extent overflow file.  */
      key.first_block = grub_cpu_to_be16 (pos);
      tree = 1;
      grub_hfs_find_node (data, (char *) &key, data->ext_root,
			  1, (char *) &dr, sizeof (dr));
      if (grub_errno)
	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_hfs_read_file (struct grub_hfs_data *data,
		    grub_disk_read_hook_t read_hook, void *read_hook_data,
		    grub_uint32_t pos, grub_size_t len, char *buf)
{
  grub_off_t i;
  grub_off_t blockcnt;

  /* Files are at most 2G/4G - 1 bytes on hfs. Avoid 64-bit division.
     Moreover len > 0 as checked in upper layer.  */
  blockcnt = (len + pos - 1) / data->blksz + 1;

  for (i = pos / data->blksz; i < blockcnt; i++)
    {
      grub_disk_addr_t blknr;
      grub_off_t blockoff;
      grub_off_t blockend = data->blksz;

      int skipfirst = 0;

      blockoff = pos % data->blksz;

      blknr = grub_hfs_block (data, data->extents, data->fileid, i, 1);
      if (grub_errno)
	return -1;

      /* Last block.  */
      if (i == blockcnt - 1)
	{
	  blockend = (len + pos) % data->blksz;

	  /* The last portion is exactly EXT2_BLOCK_SIZE (data).  */
	  if (! blockend)
	    blockend = data->blksz;
	}

      /* First block.  */
      if (i == pos / data->blksz)
	{
	  skipfirst = blockoff;
	  blockend -= skipfirst;
	}

      /* If the block number is 0 this block is not stored on disk but
	 is zero filled instead.  */
      if (blknr)
	{
	  data->disk->read_hook = read_hook;
	  data->disk->read_hook_data = read_hook_data;
	  grub_disk_read (data->disk, blknr, skipfirst,
			  blockend, buf);
	  data->disk->read_hook = 0;
	  if (grub_errno)
	    return -1;
	}

      buf += data->blksz - skipfirst;
    }

  return len;
}


/* Mount the filesystem on the disk DISK.  */
static struct grub_hfs_data *
grub_hfs_mount (grub_disk_t disk)
{
  struct grub_hfs_data *data;
  struct grub_hfs_catalog_key key;
  struct grub_hfs_dirrec dir;
  int first_block;

  struct
  {
    struct grub_hfs_node node;
    struct grub_hfs_treeheader head;
  } treehead;

  data = grub_malloc (sizeof (struct grub_hfs_data));
  if (!data)
    return 0;

  /* Read the superblock.  */
  if (grub_disk_read (disk, GRUB_HFS_SBLOCK, 0,
		      sizeof (struct grub_hfs_sblock), &data->sblock))
    goto fail;

  /* Check if this is a HFS filesystem.  */
  if (grub_be_to_cpu16 (data->sblock.magic) != GRUB_HFS_MAGIC
      || data->sblock.blksz == 0
      || (data->sblock.blksz & grub_cpu_to_be32_compile_time (0xc00001ff)))
    {
      grub_error (GRUB_ERR_BAD_FS, "not an HFS filesystem");
      goto fail;
    }

  /* Check if this is an embedded HFS+ filesystem.  */
  if (grub_be_to_cpu16 (data->sblock.embed_sig) == GRUB_HFS_EMBED_HFSPLUS_SIG)
    {
      grub_error (GRUB_ERR_BAD_FS, "embedded HFS+ filesystem");
      goto fail;
    }

  data->blksz = grub_be_to_cpu32 (data->sblock.blksz);
  data->disk = disk;

  /* Lookup the root node of the extent overflow tree.  */
  first_block = ((grub_be_to_cpu16 (data->sblock.extent_recs[0].first_block)
		  * GRUB_HFS_BLKS)
		 + grub_be_to_cpu16 (data->sblock.first_block));

  if (grub_disk_read (data->disk, first_block, 0,
		      sizeof (treehead), &treehead))
    goto fail;
  data->ext_root = grub_be_to_cpu32 (treehead.head.root_node);
  data->ext_size = grub_be_to_cpu16 (treehead.head.node_size);

  /* Lookup the root node of the catalog tree.  */
  first_block = ((grub_be_to_cpu16 (data->sblock.catalog_recs[0].first_block)
		  * GRUB_HFS_BLKS)
		 + grub_be_to_cpu16 (data->sblock.first_block));
  if (grub_disk_read (data->disk, first_block, 0,
		      sizeof (treehead), &treehead))
    goto fail;
  data->cat_root = grub_be_to_cpu32 (treehead.head.root_node);
  data->cat_size = grub_be_to_cpu16 (treehead.head.node_size);

  if (data->cat_size == 0
      || data->blksz < data->cat_size
      || data->blksz < data->ext_size)
    goto fail;

  /* Lookup the root directory node in the catalog tree using the
     volume name.  */
  key.parent_dir = grub_cpu_to_be32_compile_time (1);
  key.strlen = data->sblock.volname[0];
  grub_strcpy ((char *) key.str, (char *) (data->sblock.volname + 1));

  if (grub_hfs_find_node (data, (char *) &key, data->cat_root,
			  0, (char *) &dir, sizeof (dir)) == 0)
    {
      grub_error (GRUB_ERR_BAD_FS, "cannot find the HFS root directory");
      goto fail;
    }

  if (grub_errno)
    goto fail;

  data->rootdir = grub_be_to_cpu32 (dir.dirid);

  return data;
 fail:
  grub_free (data);

  if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
    grub_error (GRUB_ERR_BAD_FS, "not a HFS filesystem");

  return 0;
}

/* Compare the K1 and K2 catalog file keys using HFS character ordering.  */
static int
grub_hfs_cmp_catkeys (const struct grub_hfs_catalog_key *k1,
		      const struct grub_hfs_catalog_key *k2)
{
  /* Taken from hfsutils 3.2.6 and converted to a readable form */
  static const unsigned char hfs_charorder[256] = {
    [0x00] = 0,
    [0x01] = 1,
    [0x02] = 2,
    [0x03] = 3,
    [0x04] = 4,
    [0x05] = 5,
    [0x06] = 6,
    [0x07] = 7,
    [0x08] = 8,
    [0x09] = 9,
    [0x0A] = 10,
    [0x0B] = 11,
    [0x0C] = 12,
    [0x0D] = 13,
    [0x0E] = 14,
    [0x0F] = 15,
    [0x10] = 16,
    [0x11] = 17,
    [0x12] = 18,
    [0x13] = 19,
    [0x14] = 20,
    [0x15] = 21,
    [0x16] = 22,
    [0x17] = 23,
    [0x18] = 24,
    [0x19] = 25,
    [0x1A] = 26,
    [0x1B] = 27,
    [0x1C] = 28,
    [0x1D] = 29,
    [0x1E] = 30,
    [0x1F] = 31,
    [' '] = 32,		[0xCA] = 32,
    ['!'] = 33,
    ['"'] = 34,
    [0xD2] = 35,
    [0xD3] = 36,
    [0xC7] = 37,
    [0xC8] = 38,
    ['#'] = 39,
    ['$'] = 40,
    ['%'] = 41,
    ['&'] = 42,
    ['\''] = 43,
    [0xD4] = 44,
    [0xD5] = 45,
    ['('] = 46,
    [')'] = 47,
    ['*'] = 48,
    ['+'] = 49,
    [','] = 50,
    ['-'] = 51,
    ['.'] = 52,
    ['/'] = 53,
    ['0'] = 54,
    ['1'] = 55,
    ['2'] = 56,
    ['3'] = 57,
    ['4'] = 58,
    ['5'] = 59,
    ['6'] = 60,
    ['7'] = 61,
    ['8'] = 62,
    ['9'] = 63,
    [':'] = 64,
    [';'] = 65,
    ['<'] = 66,
    ['='] = 67,
    ['>'] = 68,
    ['?'] = 69,
    ['@'] = 70,
    ['A'] = 71,		['a'] = 71,
    [0x88] = 72,	[0xCB] = 72,
    [0x80] = 73,	[0x8A] = 73,
    [0x8B] = 74,	[0xCC] = 74,
    [0x81] = 75,	[0x8C] = 75,
    [0xAE] = 76,	[0xBE] = 76,
    ['`'] = 77,
    [0x87] = 78,
    [0x89] = 79,
    [0xBB] = 80,
    ['B'] = 81,		['b'] = 81,
    ['C'] = 82,		['c'] = 82,
    [0x82] = 83,	[0x8D] = 83,
    ['D'] = 84,		['d'] = 84,
    ['E'] = 85,		['e'] = 85,
    [0x83] = 86,	[0x8E] = 86,
    [0x8F] = 87,
    [0x90] = 88,
    [0x91] = 89,
    ['F'] = 90,		['f'] = 90,
    ['G'] = 91,		['g'] = 91,
    ['H'] = 92,		['h'] = 92,
    ['I'] = 93,		['i'] = 93,
    [0x92] = 94,
    [0x93] = 95,
    [0x94] = 96,
    [0x95] = 97,
    ['J'] = 98,		['j'] = 98,
    ['K'] = 99,		['k'] = 99,
    ['L'] = 100,	['l'] = 100,
    ['M'] = 101,	['m'] = 101,
    ['N'] = 102,	['n'] = 102,
    [0x84] = 103,	[0x96] = 103,
    ['O'] = 104,	['o'] = 104,
    [0x85] = 105,	[0x9A] = 105,
    [0x9B] = 106,	[0xCD] = 106,
    [0xAF] = 107,	[0xBF] = 107,
    [0xCE] = 108,	[0xCF] = 108,
    [0x97] = 109,
    [0x98] = 110,
    [0x99] = 111,
    [0xBC] = 112,
    ['P'] = 113,	['p'] = 113,
    ['Q'] = 114,	['q'] = 114,
    ['R'] = 115,	['r'] = 115,
    ['S'] = 116,	['s'] = 116,
    [0xA7] = 117,
    ['T'] = 118,	['t'] = 118,
    ['U'] = 119,	['u'] = 119,
    [0x86] = 120,	[0x9F] = 120,
    [0x9C] = 121,
    [0x9D] = 122,
    [0x9E] = 123,
    ['V'] = 124,	['v'] = 124,
    ['W'] = 125,	['w'] = 125,
    ['X'] = 126,	['x'] = 126,
    ['Y'] = 127,	['y'] = 127,
    [0xD8] = 128,
    ['Z'] = 129,	['z'] = 129,
    ['['] = 130,
    ['\\'] = 131,
    [']'] = 132,
    ['^'] = 133,
    ['_'] = 134,
    ['{'] = 135,
    ['|'] = 136,
    ['}'] = 137,
    ['~'] = 138,
    [0x7F] = 139,
    [0xA0] = 140,
    [0xA1] = 141,
    [0xA2] = 142,
    [0xA3] = 143,
    [0xA4] = 144,
    [0xA5] = 145,
    [0xA6] = 146,
    [0xA8] = 147,
    [0xA9] = 148,
    [0xAA] = 149,
    [0xAB] = 150,
    [0xAC] = 151,
    [0xAD] = 152,
    [0xB0] = 153,
    [0xB1] = 154,
    [0xB2] = 155,
    [0xB3] = 156,
    [0xB4] = 157,
    [0xB5] = 158,
    [0xB6] = 159,
    [0xB7] = 160,
    [0xB8] = 161,
    [0xB9] = 162,
    [0xBA] = 163,
    [0xBD] = 164,
    [0xC0] = 165,
    [0xC1] = 166,
    [0xC2] = 167,
    [0xC3] = 168,
    [0xC4] = 169,
    [0xC5] = 170,
    [0xC6] = 171,
    [0xC9] = 172,
    [0xD0] = 173,
    [0xD1] = 174,
    [0xD6] = 175,
    [0xD7] = 176,
    [0xD9] = 177,
    [0xDA] = 178,
    [0xDB] = 179,
    [0xDC] = 180,
    [0xDD] = 181,
    [0xDE] = 182,
    [0xDF] = 183,
    [0xE0] = 184,
    [0xE1] = 185,
    [0xE2] = 186,
    [0xE3] = 187,
    [0xE4] = 188,
    [0xE5] = 189,
    [0xE6] = 190,
    [0xE7] = 191,
    [0xE8] = 192,
    [0xE9] = 193,
    [0xEA] = 194,
    [0xEB] = 195,
    [0xEC] = 196,
    [0xED] = 197,
    [0xEE] = 198,
    [0xEF] = 199,
    [0xF0] = 200,
    [0xF1] = 201,
    [0xF2] = 202,
    [0xF3] = 203,
    [0xF4] = 204,
    [0xF5] = 205,
    [0xF6] = 206,
    [0xF7] = 207,
    [0xF8] = 208,
    [0xF9] = 209,
    [0xFA] = 210,
    [0xFB] = 211,
    [0xFC] = 212,
    [0xFD] = 213,
    [0xFE] = 214,
    [0xFF] = 215,
  };
  int i;
  int cmp;
  int minlen = (k1->strlen < k2->strlen) ? k1->strlen : k2->strlen;

  cmp = (grub_be_to_cpu32 (k1->parent_dir) - grub_be_to_cpu32 (k2->parent_dir));
  if (cmp != 0)
    return cmp;

  for (i = 0; i < minlen; i++)
    {
      cmp = (hfs_charorder[k1->str[i]] - hfs_charorder[k2->str[i]]);
      if (cmp != 0)
	return cmp;
    }

  /* Shorter strings precede long ones.  */
  return (k1->strlen - k2->strlen);
}


/* Compare the K1 and K2 extent overflow file keys.  */
static int
grub_hfs_cmp_extkeys (const struct grub_hfs_extent_key *k1,
		      const struct grub_hfs_extent_key *k2)
{
  int cmp = k1->forktype - k2->forktype;
  if (cmp == 0)
    cmp = grub_be_to_cpu32 (k1->fileid) - grub_be_to_cpu32 (k2->fileid);
  if (cmp == 0)
    cmp = (grub_be_to_cpu16 (k1->first_block)
	   - grub_be_to_cpu16 (k2->first_block));
  return cmp;
}


/* Iterate the records in the node with index IDX in the mounted HFS
   filesystem DATA.  This node holds data of the type TYPE (0 =
   catalog node, 1 = extent overflow node).  If this is set, continue
   iterating to the next node.  For every records, call NODE_HOOK.  */
static grub_err_t
grub_hfs_iterate_records (struct grub_hfs_data *data, int type, int idx,
			  int this, int (*node_hook) (struct grub_hfs_node *hnd,
						      struct grub_hfs_record *,
						      void *hook_arg),
			  void *hook_arg)
{
  grub_size_t nodesize = type == 0 ? data->cat_size : data->ext_size;

  union node_union
  {
    struct grub_hfs_node node;
    char rawnode[0];
    grub_uint16_t offsets[0];
  } *node;

  if (nodesize < sizeof (struct grub_hfs_node))
    nodesize = sizeof (struct grub_hfs_node);

  node = grub_malloc (nodesize);
  if (!node)
    return grub_errno;

  do
    {
      int i;
      struct grub_hfs_extent *dat;
      int blk;
      grub_uint16_t reccnt;

      dat = (struct grub_hfs_extent *) (type == 0
					? (&data->sblock.catalog_recs)
					: (&data->sblock.extent_recs));

      /* Read the node into memory.  */
      blk = grub_hfs_block (data, dat,
                            (type == 0) ? GRUB_HFS_CNID_CAT : GRUB_HFS_CNID_EXT,
			    idx / (data->blksz / nodesize), 0);
      blk += (idx % (data->blksz / nodesize));

      if (grub_errno || grub_disk_read (data->disk, blk, 0,
					nodesize, node))
	{
	  grub_free (node);
	  return grub_errno;
	}

      reccnt = grub_be_to_cpu16 (node->node.reccnt);
      if (reccnt > (nodesize >> 1))
	reccnt = (nodesize >> 1);

      /* Iterate over all records in this node.  */
      for (i = 0; i < reccnt; i++)
	{
	  int pos = (nodesize >> 1) - 1 - i;
 	  struct pointer
	  {
	    grub_uint8_t keylen;
	    grub_uint8_t key;
	  } GRUB_PACKED *pnt;
	  grub_uint16_t off = grub_be_to_cpu16 (node->offsets[pos]);
	  if (off > nodesize - sizeof(*pnt))
	    continue;
	  pnt = (struct pointer *) (off + node->rawnode);
	  if (nodesize < (grub_size_t) off + pnt->keylen + 1)
	    continue;

	  struct grub_hfs_record rec =
	    {
	      &pnt->key,
	      pnt->keylen,
	      &pnt->key + pnt->keylen +(pnt->keylen + 1) % 2,
	      nodesize - off - pnt->keylen - 1
	    };

	  if (node_hook (&node->node, &rec, hook_arg))
	    {
	      grub_free (node);
	      return 0;
	    }
	}

      idx = grub_be_to_cpu32 (node->node.next);
    } while (idx && this);
  grub_free (node);
  return 0;
}

struct grub_hfs_find_node_node_found_ctx
{
  int found;
  int isleaf;
  int done;
  int type;
  const char *key;
  char *datar;
  grub_size_t datalen;
};

static int
grub_hfs_find_node_node_found (struct grub_hfs_node *hnd, struct grub_hfs_record *rec,
			       void *hook_arg)
{
  struct grub_hfs_find_node_node_found_ctx *ctx = hook_arg;
  int cmp = 1;

  if (ctx->type == 0)
    cmp = grub_hfs_cmp_catkeys (rec->key, (const void *) ctx->key);
  else
    cmp = grub_hfs_cmp_extkeys (rec->key, (const void *) ctx->key);

  /* If the key is smaller or equal to the current node, mark the
     entry.  In case of a non-leaf mode it will be used to lookup
     the rest of the tree.  */
  if (cmp <= 0)
    ctx->found = grub_be_to_cpu32 (grub_get_unaligned32 (rec->data));
  else /* The key can not be found in the tree. */
    return 1;

  /* Check if this node is a leaf node.  */
  if (hnd->type == GRUB_HFS_NODE_LEAF)
    {
      ctx->isleaf = 1;

      /* Found it!!!!  */
      if (cmp == 0)
	{
	  ctx->done = 1;

	  grub_memcpy (ctx->datar, rec->data,
		       rec->datalen < ctx->datalen ? rec->datalen : ctx->datalen);
	  return 1;
	}
    }

  return 0;
}


/* Lookup a record in the mounted filesystem DATA using the key KEY.
   The index of the node on top of the tree is IDX.  The tree is of
   the type TYPE (0 = catalog node, 1 = extent overflow node).  Return
   the data in DATAR with a maximum length of DATALEN.  */
static int
grub_hfs_find_node (struct grub_hfs_data *data, char *key,
		    grub_uint32_t idx, int type, char *datar, grub_size_t datalen)
{
  struct grub_hfs_find_node_node_found_ctx ctx =
    {
      .found = -1,
      .isleaf = 0,
      .done = 0,
      .type = type,
      .key = key,
      .datar = datar,
      .datalen = datalen
    };

  do
    {
      ctx.found = -1;

      if (grub_hfs_iterate_records (data, type, idx, 0, grub_hfs_find_node_node_found, &ctx))
        return 0;

      if (ctx.found == -1)
        return 0;

      idx = ctx.found;
    } while (! ctx.isleaf);

  return ctx.done;
}

struct grub_hfs_iterate_dir_node_found_ctx
{
  grub_uint32_t dir_be;
  int found;
  int isleaf;
  grub_uint32_t next;
  int (*hook) (struct grub_hfs_record *, void *hook_arg);
  void *hook_arg;
};

static int
grub_hfs_iterate_dir_node_found (struct grub_hfs_node *hnd, struct grub_hfs_record *rec,
				 void *hook_arg)
{
  struct grub_hfs_iterate_dir_node_found_ctx *ctx = hook_arg;
  struct grub_hfs_catalog_key *ckey = rec->key;

  /* The lowest key possible with DIR as root directory.  */
  const struct grub_hfs_catalog_key key = {0, ctx->dir_be, 0, ""};

  if (grub_hfs_cmp_catkeys (rec->key, &key) <= 0)
    ctx->found = grub_be_to_cpu32 (grub_get_unaligned32 (rec->data));

  if (hnd->type == 0xFF && ckey->strlen > 0)
    {
      ctx->isleaf = 1;
      ctx->next = grub_be_to_cpu32 (hnd->next);

      /* An entry was found.  */
      if (ckey->parent_dir == ctx->dir_be)
	return ctx->hook (rec, ctx->hook_arg);
    }

  return 0;
}

static int
grub_hfs_iterate_dir_it_dir (struct grub_hfs_node *hnd __attribute ((unused)),
			     struct grub_hfs_record *rec,
			     void *hook_arg)
{
  struct grub_hfs_catalog_key *ckey = rec->key;
  struct grub_hfs_iterate_dir_node_found_ctx *ctx = hook_arg;
  
  /* Stop when the entries do not match anymore.  */
  if (ckey->parent_dir != ctx->dir_be)
    return 1;

  return ctx->hook (rec, ctx->hook_arg);
}


/* Iterate over the directory with the id DIR.  The tree is searched
   starting with the node ROOT_IDX.  For every entry in this directory
   call HOOK.  */
static grub_err_t
grub_hfs_iterate_dir (struct grub_hfs_data *data, grub_uint32_t root_idx,
		      grub_uint32_t dir, int (*hook) (struct grub_hfs_record *, void *hook_arg),
		      void *hook_arg)
{
  struct grub_hfs_iterate_dir_node_found_ctx ctx =
  {
    .dir_be = grub_cpu_to_be32 (dir),
    .found = -1,
    .isleaf = 0,
    .next = 0,
    .hook = hook,
    .hook_arg = hook_arg
  };

  do
    {
      ctx.found = -1;

      if (grub_hfs_iterate_records (data, 0, root_idx, 0, grub_hfs_iterate_dir_node_found, &ctx))
        return grub_errno;

      if (ctx.found == -1)
        return 0;

      root_idx = ctx.found;
    } while (! ctx.isleaf);

  /* If there was a matching record in this leaf node, continue the
     iteration until the last record was found.  */
  grub_hfs_iterate_records (data, 0, ctx.next, 1, grub_hfs_iterate_dir_it_dir, &ctx);
  return grub_errno;
}

#define MAX_UTF8_PER_MAC_ROMAN 3

static const char macroman[0x80][MAX_UTF8_PER_MAC_ROMAN + 1] =
  {
    /* 80 */ "\xc3\x84",
    /* 81 */ "\xc3\x85",
    /* 82 */ "\xc3\x87",
    /* 83 */ "\xc3\x89",
    /* 84 */ "\xc3\x91",
    /* 85 */ "\xc3\x96",
    /* 86 */ "\xc3\x9c",
    /* 87 */ "\xc3\xa1",
    /* 88 */ "\xc3\xa0",
    /* 89 */ "\xc3\xa2",
    /* 8A */ "\xc3\xa4",
    /* 8B */ "\xc3\xa3",
    /* 8C */ "\xc3\xa5",
    /* 8D */ "\xc3\xa7",
    /* 8E */ "\xc3\xa9",
    /* 8F */ "\xc3\xa8",
    /* 90 */ "\xc3\xaa",
    /* 91 */ "\xc3\xab",
    /* 92 */ "\xc3\xad",
    /* 93 */ "\xc3\xac",
    /* 94 */ "\xc3\xae",
    /* 95 */ "\xc3\xaf",
    /* 96 */ "\xc3\xb1",
    /* 97 */ "\xc3\xb3",
    /* 98 */ "\xc3\xb2",
    /* 99 */ "\xc3\xb4",
    /* 9A */ "\xc3\xb6",
    /* 9B */ "\xc3\xb5",
    /* 9C */ "\xc3\xba",
    /* 9D */ "\xc3\xb9",
    /* 9E */ "\xc3\xbb",
    /* 9F */ "\xc3\xbc",
    /* A0 */ "\xe2\x80\xa0",
    /* A1 */ "\xc2\xb0",
    /* A2 */ "\xc2\xa2",
    /* A3 */ "\xc2\xa3",
    /* A4 */ "\xc2\xa7",
    /* A5 */ "\xe2\x80\xa2",
    /* A6 */ "\xc2\xb6",
    /* A7 */ "\xc3\x9f",
    /* A8 */ "\xc2\xae",
    /* A9 */ "\xc2\xa9",
    /* AA */ "\xe2\x84\xa2",
    /* AB */ "\xc2\xb4",
    /* AC */ "\xc2\xa8",
    /* AD */ "\xe2\x89\xa0",
    /* AE */ "\xc3\x86",
    /* AF */ "\xc3\x98",
    /* B0 */ "\xe2\x88\x9e",
    /* B1 */ "\xc2\xb1",
    /* B2 */ "\xe2\x89\xa4",
    /* B3 */ "\xe2\x89\xa5",
    /* B4 */ "\xc2\xa5",
    /* B5 */ "\xc2\xb5",
    /* B6 */ "\xe2\x88\x82",
    /* B7 */ "\xe2\x88\x91",
    /* B8 */ "\xe2\x88\x8f",
    /* B9 */ "\xcf\x80",
    /* BA */ "\xe2\x88\xab",
    /* BB */ "\xc2\xaa",
    /* BC */ "\xc2\xba",
    /* BD */ "\xce\xa9",
    /* BE */ "\xc3\xa6",
    /* BF */ "\xc3\xb8",
    /* C0 */ "\xc2\xbf",
    /* C1 */ "\xc2\xa1",
    /* C2 */ "\xc2\xac",
    /* C3 */ "\xe2\x88\x9a",
    /* C4 */ "\xc6\x92",
    /* C5 */ "\xe2\x89\x88",
    /* C6 */ "\xe2\x88\x86",
    /* C7 */ "\xc2\xab",
    /* C8 */ "\xc2\xbb",
    /* C9 */ "\xe2\x80\xa6",
    /* CA */ "\xc2\xa0",
    /* CB */ "\xc3\x80",
    /* CC */ "\xc3\x83",
    /* CD */ "\xc3\x95",
    /* CE */ "\xc5\x92",
    /* CF */ "\xc5\x93",
    /* D0 */ "\xe2\x80\x93",
    /* D1 */ "\xe2\x80\x94",
    /* D2 */ "\xe2\x80\x9c",
    /* D3 */ "\xe2\x80\x9d",
    /* D4 */ "\xe2\x80\x98",
    /* D5 */ "\xe2\x80\x99",
    /* D6 */ "\xc3\xb7",
    /* D7 */ "\xe2\x97\x8a",
    /* D8 */ "\xc3\xbf",
    /* D9 */ "\xc5\xb8",
    /* DA */ "\xe2\x81\x84",
    /* DB */ "\xe2\x82\xac",
    /* DC */ "\xe2\x80\xb9",
    /* DD */ "\xe2\x80\xba",
    /* DE */ "\xef\xac\x81",
    /* DF */ "\xef\xac\x82",
    /* E0 */ "\xe2\x80\xa1",
    /* E1 */ "\xc2\xb7",
    /* E2 */ "\xe2\x80\x9a",
    /* E3 */ "\xe2\x80\x9e",
    /* E4 */ "\xe2\x80\xb0",
    /* E5 */ "\xc3\x82",
    /* E6 */ "\xc3\x8a",
    /* E7 */ "\xc3\x81",
    /* E8 */ "\xc3\x8b",
    /* E9 */ "\xc3\x88",
    /* EA */ "\xc3\x8d",
    /* EB */ "\xc3\x8e",
    /* EC */ "\xc3\x8f",
    /* ED */ "\xc3\x8c",
    /* EE */ "\xc3\x93",
    /* EF */ "\xc3\x94",
    /* F0 */ "\xef\xa3\xbf",
    /* F1 */ "\xc3\x92",
    /* F2 */ "\xc3\x9a",
    /* F3 */ "\xc3\x9b",
    /* F4 */ "\xc3\x99",
    /* F5 */ "\xc4\xb1",
    /* F6 */ "\xcb\x86",
    /* F7 */ "\xcb\x9c",
    /* F8 */ "\xc2\xaf",
    /* F9 */ "\xcb\x98",
    /* FA */ "\xcb\x99",
    /* FB */ "\xcb\x9a",
    /* FC */ "\xc2\xb8",
    /* FD */ "\xcb\x9d",
    /* FE */ "\xcb\x9b",
    /* FF */ "\xcb\x87",
  };

static void
macroman_to_utf8 (char *to, const grub_uint8_t *from, grub_size_t len,
		  int translate_slash)
{
  char *optr = to;
  const grub_uint8_t *iptr;

  for (iptr = from; iptr < from + len && *iptr; iptr++)
    {
      /* Translate '/' to ':' as per HFS spec.  */
      if (*iptr == '/' && translate_slash)
	{
	  *optr++ = ':';
	  continue;
	}	
      if (!(*iptr & 0x80))
	{
	  *optr++ = *iptr;
	  continue;
	}
      optr = grub_stpcpy (optr, macroman[*iptr & 0x7f]);
    }
  *optr = 0;
}

static grub_ssize_t
utf8_to_macroman (grub_uint8_t *to, const char *from)
{
  grub_uint8_t *end = to + 31;
  grub_uint8_t *optr = to;
  const char *iptr = from;
  
  while (*iptr && optr < end)
    {
      int i, clen;
      /* Translate ':' to '/' as per HFS spec.  */
      if (*iptr == ':')
	{
	  *optr++ = '/';
	  iptr++;
	  continue;
	}	
      if (!(*iptr & 0x80))
	{
	  *optr++ = *iptr++;
	  continue;
	}
      clen = 2;
      if ((*iptr & 0xf0) == 0xe0)
	clen++;
      for (i = 0; i < 0x80; i++)
	if (grub_memcmp (macroman[i], iptr, clen) == 0)
	  break;
      if (i == 0x80)
	break;
      *optr++ = i | 0x80;
      iptr += clen;
    }
  /* Too long or not encodable.  */
  if (*iptr)
    return -1;
  return optr - to;
}

union grub_hfs_anyrec {
  struct grub_hfs_filerec frec;
  struct grub_hfs_dirrec dir;
};

struct grub_fshelp_node
{
  struct grub_hfs_data *data;
  union grub_hfs_anyrec fdrec;
  grub_uint32_t inode;
};

static grub_err_t
lookup_file (grub_fshelp_node_t dir,
	     const char *name,
	     grub_fshelp_node_t *foundnode,
	     enum grub_fshelp_filetype *foundtype)
{
  struct grub_hfs_catalog_key key;
  grub_ssize_t slen;
  union grub_hfs_anyrec fdrec;

  key.parent_dir = grub_cpu_to_be32 (dir->inode);
  slen = utf8_to_macroman (key.str, name);
  if (slen < 0)
    /* Not found */
    return GRUB_ERR_NONE;
  key.strlen = slen;

  /* Lookup this node.  */
  if (! grub_hfs_find_node (dir->data, (char *) &key, dir->data->cat_root,
			    0, (char *) &fdrec.frec, sizeof (fdrec.frec)))
    /* Not found */
    return GRUB_ERR_NONE;

  *foundnode = grub_malloc (sizeof (struct grub_fshelp_node));
  if (!*foundnode)
    return grub_errno;
  
  (*foundnode)->inode = grub_be_to_cpu32 (fdrec.dir.dirid);
  (*foundnode)->fdrec = fdrec;
  (*foundnode)->data = dir->data;
  *foundtype = (fdrec.frec.type == GRUB_HFS_FILETYPE_DIR) ? GRUB_FSHELP_DIR : GRUB_FSHELP_REG;
  return GRUB_ERR_NONE;
}

/* Find a file or directory with the pathname PATH in the filesystem
   DATA.  Return the file record in RETDATA when it is non-zero.
   Return the directory number in RETINODE when it is non-zero.  */
static grub_err_t
grub_hfs_find_dir (struct grub_hfs_data *data, const char *path,
		   grub_fshelp_node_t *found,
		   enum grub_fshelp_filetype exptype)
{
  struct grub_fshelp_node root = {
    .data = data,
    .inode = data->rootdir,
    .fdrec = {
      .frec = {
	.type = GRUB_HFS_FILETYPE_DIR
      }
    }
  };
  grub_err_t err;

  err = grub_fshelp_find_file_lookup (path, &root, found, lookup_file, NULL, exptype);

  if (&root == *found)
    {
      *found = grub_malloc (sizeof (root));
      if (!*found)
	return grub_errno;
      grub_memcpy (*found, &root, sizeof (root));
    }
  return err;
}

struct grub_hfs_dir_hook_ctx
{
  grub_fs_dir_hook_t hook;
  void *hook_data;
};

static int
grub_hfs_dir_hook (struct grub_hfs_record *rec, void *hook_arg)
{
  struct grub_hfs_dir_hook_ctx *ctx = hook_arg;
  struct grub_hfs_dirrec *drec = rec->data;
  struct grub_hfs_filerec *frec = rec->data;
  struct grub_hfs_catalog_key *ckey = rec->key;
  char fname[sizeof (ckey->str) * MAX_UTF8_PER_MAC_ROMAN + 1];
  struct grub_dirhook_info info;
  grub_size_t len;

  grub_memset (fname, 0, sizeof (fname));

  grub_memset (&info, 0, sizeof (info));

  len = ckey->strlen;
  if (len > sizeof (ckey->str))
    len = sizeof (ckey->str);
  macroman_to_utf8 (fname, ckey->str, len, 1);

  info.case_insensitive = 1;

  if (drec->type == GRUB_HFS_FILETYPE_DIR)
    {
      info.dir = 1;
      info.mtimeset = 1;
      info.inodeset = 1;
      info.mtime = grub_be_to_cpu32 (drec->mtime) - 2082844800;
      info.inode = grub_be_to_cpu32 (drec->dirid);
      return ctx->hook (fname, &info, ctx->hook_data);
    }
  if (frec->type == GRUB_HFS_FILETYPE_FILE)
    {
      info.dir = 0;
      info.mtimeset = 1;
      info.inodeset = 1;
      info.mtime = grub_be_to_cpu32 (frec->mtime) - 2082844800;
      info.inode = grub_be_to_cpu32 (frec->fileid);
      return ctx->hook (fname, &info, ctx->hook_data);
    }

  return 0;
}


static grub_err_t
grub_hfs_dir (grub_device_t device, const char *path, grub_fs_dir_hook_t hook,
	      void *hook_data)
{
  struct grub_hfs_data *data;
  struct grub_hfs_dir_hook_ctx ctx =
    {
      .hook = hook,
      .hook_data = hook_data
    };
  grub_fshelp_node_t found = NULL;
  
  grub_dl_ref (my_mod);

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

  /* First the directory ID for the directory.  */
  if (grub_hfs_find_dir (data, path, &found, GRUB_FSHELP_DIR))
    goto fail;

  grub_hfs_iterate_dir (data, data->cat_root, found->inode, grub_hfs_dir_hook, &ctx);

 fail:
  grub_free (found);
  grub_free (data);

  grub_dl_unref (my_mod);

  return grub_errno;
}


/* Open a file named NAME and initialize FILE.  */
static grub_err_t
grub_hfs_open (struct grub_file *file, const char *name)
{
  struct grub_hfs_data *data;
  grub_fshelp_node_t found = NULL;
  
  grub_dl_ref (my_mod);

  data = grub_hfs_mount (file->device->disk);

  if (!data)
    {
      grub_dl_unref (my_mod);
      return grub_errno;
    }

  if (grub_hfs_find_dir (data, name, &found, GRUB_FSHELP_REG))
    {
      grub_free (data);
      grub_free (found);
      grub_dl_unref (my_mod);
      return grub_errno;
    }

  grub_memcpy (data->extents, found->fdrec.frec.extents, sizeof (grub_hfs_datarecord_t));
  file->size = grub_be_to_cpu32 (found->fdrec.frec.size);
  data->size = grub_be_to_cpu32 (found->fdrec.frec.size);
  data->fileid = grub_be_to_cpu32 (found->fdrec.frec.fileid);
  file->offset = 0;

  file->data = data;

  grub_free (found);

  return 0;
}

static grub_ssize_t
grub_hfs_read (grub_file_t file, char *buf, grub_size_t len)
{
  struct grub_hfs_data *data =
    (struct grub_hfs_data *) file->data;

  return grub_hfs_read_file (data, file->read_hook, file->read_hook_data,
			     file->offset, len, buf);
}


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

  grub_dl_unref (my_mod);

  return 0;
}


static grub_err_t
grub_hfs_label (grub_device_t device, char **label)
{
  struct grub_hfs_data *data;

  data = grub_hfs_mount (device->disk);

  if (data)
    {
      grub_size_t len = data->sblock.volname[0];
      if (len > sizeof (data->sblock.volname) - 1)
	len = sizeof (data->sblock.volname) - 1;
      *label = grub_malloc (len * MAX_UTF8_PER_MAC_ROMAN + 1);
      if (*label)
	macroman_to_utf8 (*label, data->sblock.volname + 1,
			  len + 1, 0);
    }
  else
    *label = 0;

  grub_free (data);
  return grub_errno;
}

static grub_err_t
grub_hfs_mtime (grub_device_t device, grub_int32_t *tm)
{
  struct grub_hfs_data *data;

  data = grub_hfs_mount (device->disk);

  if (data)
    *tm = grub_be_to_cpu32 (data->sblock.mtime) - 2082844800;
  else
    *tm = 0;

  grub_free (data);
  return grub_errno;
}

static grub_err_t
grub_hfs_uuid (grub_device_t device, char **uuid)
{
  struct grub_hfs_data *data;

  grub_dl_ref (my_mod);

  data = grub_hfs_mount (device->disk);
  if (data && data->sblock.num_serial != 0)
    {
      *uuid = grub_xasprintf ("%016llx",
			     (unsigned long long)
			     grub_be_to_cpu64 (data->sblock.num_serial));
    }
  else
    *uuid = NULL;

  grub_dl_unref (my_mod);

  grub_free (data);

  return grub_errno;
}



static struct grub_fs grub_hfs_fs =
  {
    .name = "hfs",
    .dir = grub_hfs_dir,
    .open = grub_hfs_open,
    .read = grub_hfs_read,
    .close = grub_hfs_close,
    .label = grub_hfs_label,
    .uuid = grub_hfs_uuid,
    .mtime = grub_hfs_mtime,
#ifdef GRUB_UTIL
    .reserved_first_sector = 1,
    .blocklist_install = 1,
#endif
    .next = 0
  };

GRUB_MOD_INIT(hfs)
{
  grub_fs_register (&grub_hfs_fs);
  my_mod = mod;
}

GRUB_MOD_FINI(hfs)
{
  grub_fs_unregister (&grub_hfs_fs);
}
