/*
 *  Copyright 2000-2002 by Hans Reiser, licensing governed by reiserfs/README
 *
 *  GRUB  --  GRand Unified Bootloader
 *  Copyright (C) 2000, 2001  Free Software Foundation, Inc.
 *
 *  (C) Copyright 2003 - 2004
 *  Sysgo AG, <www.elinos.com>, Pavel Bartusek <pba@sysgo.com>
 *
 *
 *  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 2 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, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

/* An implementation for the ReiserFS filesystem ported from GRUB.
 * Some parts of this code (mainly the structures and defines) are
 * from the original reiser fs code, as found in the linux kernel.
 */

#include <common.h>
#if defined(CONFIG_CMD_REISER)

#include <malloc.h>
#include <linux/ctype.h>
#include <linux/time.h>
#include <asm/byteorder.h>
#include <reiserfs.h>

#include "reiserfs_private.h"

#undef REISERDEBUG

/* Some parts of this code (mainly the structures and defines) are
 * from the original reiser fs code, as found in the linux kernel.
 */

static char fsys_buf[FSYS_BUFLEN];
static reiserfs_error_t errnum = ERR_NONE;
static int print_possibilities;
static unsigned int filepos, filemax;

static int
substring (const char *s1, const char *s2)
{
  while (*s1 == *s2)
    {
      /* The strings match exactly. */
      if (! *(s1++))
	return 0;
      s2 ++;
    }

  /* S1 is a substring of S2. */
  if (*s1 == 0)
    return -1;

  /* S1 isn't a substring. */
  return 1;
}

static void sd_print_item (struct item_head * ih, char * item)
{
    char filetime[30];
    time_t ttime;

    if (stat_data_v1 (ih)) {
	struct stat_data_v1 * sd = (struct stat_data_v1 *)item;
	ttime = sd_v1_mtime(sd);
	ctime_r(&ttime, filetime);
	printf ("%-10s %4hd %6d %6d %9d %24.24s",
		 bb_mode_string(sd_v1_mode(sd)), sd_v1_nlink(sd),sd_v1_uid(sd), sd_v1_gid(sd),
		 sd_v1_size(sd), filetime);
    } else {
	struct stat_data * sd = (struct stat_data *)item;
	ttime = sd_v2_mtime(sd);
	ctime_r(&ttime, filetime);
	printf ("%-10s %4d %6d %6d %9d %24.24s",
		 bb_mode_string(sd_v2_mode(sd)), sd_v2_nlink(sd),sd_v2_uid(sd),sd_v2_gid(sd),
		 (__u32) sd_v2_size(sd), filetime);
    }
}

static int
journal_read (int block, int len, char *buffer)
{
  return reiserfs_devread ((INFO->journal_block + block) << INFO->blocksize_shift,
			   0, len, buffer);
}

/* Read a block from ReiserFS file system, taking the journal into
 * account.  If the block nr is in the journal, the block from the
 * journal taken.
 */
static int
block_read (unsigned int blockNr, int start, int len, char *buffer)
{
  int transactions = INFO->journal_transactions;
  int desc_block = INFO->journal_first_desc;
  int journal_mask = INFO->journal_block_count - 1;
  int translatedNr = blockNr;
  __u32 *journal_table = JOURNAL_START;
  while (transactions-- > 0)
    {
      int i = 0;
      int j_len;
      if (__le32_to_cpu(*journal_table) != 0xffffffff)
	{
	  /* Search for the blockNr in cached journal */
	  j_len = __le32_to_cpu(*journal_table++);
	  while (i++ < j_len)
	    {
	      if (__le32_to_cpu(*journal_table++) == blockNr)
		{
		  journal_table += j_len - i;
		  goto found;
		}
	    }
	}
      else
	{
	  /* This is the end of cached journal marker.  The remaining
	   * transactions are still on disk.
	   */
	  struct reiserfs_journal_desc   desc;
	  struct reiserfs_journal_commit commit;

	  if (! journal_read (desc_block, sizeof (desc), (char *) &desc))
	    return 0;

	  j_len = __le32_to_cpu(desc.j_len);
	  while (i < j_len && i < JOURNAL_TRANS_HALF)
	    if (__le32_to_cpu(desc.j_realblock[i++]) == blockNr)
	      goto found;

	  if (j_len >= JOURNAL_TRANS_HALF)
	    {
	      int commit_block = (desc_block + 1 + j_len) & journal_mask;
	      if (! journal_read (commit_block,
				  sizeof (commit), (char *) &commit))
		return 0;
	      while (i < j_len)
		if (__le32_to_cpu(commit.j_realblock[i++ - JOURNAL_TRANS_HALF]) == blockNr)
		  goto found;
	    }
	}
      goto not_found;

    found:
      translatedNr = INFO->journal_block + ((desc_block + i) & journal_mask);
#ifdef REISERDEBUG
      printf ("block_read: block %d is mapped to journal block %d.\n",
	      blockNr, translatedNr - INFO->journal_block);
#endif
      /* We must continue the search, as this block may be overwritten
       * in later transactions.
       */
    not_found:
      desc_block = (desc_block + 2 + j_len) & journal_mask;
    }
  return reiserfs_devread (translatedNr << INFO->blocksize_shift, start, len, buffer);
}

/* Init the journal data structure.  We try to cache as much as
 * possible in the JOURNAL_START-JOURNAL_END space, but if it is full
 * we can still read the rest from the disk on demand.
 *
 * The first number of valid transactions and the descriptor block of the
 * first valid transaction are held in INFO.  The transactions are all
 * adjacent, but we must take care of the journal wrap around.
 */
static int
journal_init (void)
{
  unsigned int block_count = INFO->journal_block_count;
  unsigned int desc_block;
  unsigned int commit_block;
  unsigned int next_trans_id;
  struct reiserfs_journal_header header;
  struct reiserfs_journal_desc   desc;
  struct reiserfs_journal_commit commit;
  __u32 *journal_table = JOURNAL_START;

  journal_read (block_count, sizeof (header), (char *) &header);
  desc_block = __le32_to_cpu(header.j_first_unflushed_offset);
  if (desc_block >= block_count)
    return 0;

  INFO->journal_first_desc = desc_block;
  next_trans_id = __le32_to_cpu(header.j_last_flush_trans_id) + 1;

#ifdef REISERDEBUG
  printf ("journal_init: last flushed %d\n",
	  __le32_to_cpu(header.j_last_flush_trans_id));
#endif

  while (1)
    {
      journal_read (desc_block, sizeof (desc), (char *) &desc);
      if (substring (JOURNAL_DESC_MAGIC, desc.j_magic) > 0
	  || __le32_to_cpu(desc.j_trans_id) != next_trans_id
	  || __le32_to_cpu(desc.j_mount_id) != __le32_to_cpu(header.j_mount_id))
	/* no more valid transactions */
	break;

      commit_block = (desc_block + __le32_to_cpu(desc.j_len) + 1) & (block_count - 1);
      journal_read (commit_block, sizeof (commit), (char *) &commit);
      if (__le32_to_cpu(desc.j_trans_id) != commit.j_trans_id
	  || __le32_to_cpu(desc.j_len) != __le32_to_cpu(commit.j_len))
	/* no more valid transactions */
	break;

#ifdef REISERDEBUG
      printf ("Found valid transaction %d/%d at %d.\n",
	      __le32_to_cpu(desc.j_trans_id), __le32_to_cpu(desc.j_mount_id), desc_block);
#endif

      next_trans_id++;
      if (journal_table < JOURNAL_END)
	{
	  if ((journal_table + 1 + __le32_to_cpu(desc.j_len)) >= JOURNAL_END)
	    {
	      /* The table is almost full; mark the end of the cached
	       * journal.*/
	      *journal_table = __cpu_to_le32(0xffffffff);
	      journal_table = JOURNAL_END;
	    }
	  else
	    {
	      unsigned int i;
	      /* Cache the length and the realblock numbers in the table.
	       * The block number of descriptor can easily be computed.
	       * and need not to be stored here.
	       */

	      /* both are in the little endian format */
	      *journal_table++ = desc.j_len;
	      for (i = 0; i < __le32_to_cpu(desc.j_len) && i < JOURNAL_TRANS_HALF; i++)
		{
		  /* both are in the little endian format */
		  *journal_table++ = desc.j_realblock[i];
#ifdef REISERDEBUG
		  printf ("block %d is in journal %d.\n",
			  __le32_to_cpu(desc.j_realblock[i]), desc_block);
#endif
		}
	      for (     ; i < __le32_to_cpu(desc.j_len); i++)
		{
		  /* both are in the little endian format */
		  *journal_table++ = commit.j_realblock[i-JOURNAL_TRANS_HALF];
#ifdef REISERDEBUG
		  printf ("block %d is in journal %d.\n",
			  __le32_to_cpu(commit.j_realblock[i-JOURNAL_TRANS_HALF]),
			  desc_block);
#endif
		}
	    }
	}
      desc_block = (commit_block + 1) & (block_count - 1);
    }
#ifdef REISERDEBUG
  printf ("Transaction %d/%d at %d isn't valid.\n",
	  __le32_to_cpu(desc.j_trans_id), __le32_to_cpu(desc.j_mount_id), desc_block);
#endif

  INFO->journal_transactions
    = next_trans_id - __le32_to_cpu(header.j_last_flush_trans_id) - 1;
  return errnum == 0;
}

/* check filesystem types and read superblock into memory buffer */
int
reiserfs_mount (unsigned part_length)
{
  struct reiserfs_super_block super;
  int superblock = REISERFS_DISK_OFFSET_IN_BYTES >> SECTOR_BITS;

  if (part_length < superblock + (sizeof (super) >> SECTOR_BITS)
      || ! reiserfs_devread (superblock, 0, sizeof (struct reiserfs_super_block),
			     (char *) &super)
      || (substring (REISER3FS_SUPER_MAGIC_STRING, super.s_magic) > 0
	  && substring (REISER2FS_SUPER_MAGIC_STRING, super.s_magic) > 0
	  && substring (REISERFS_SUPER_MAGIC_STRING, super.s_magic) > 0)
      || (/* check that this is not a copy inside the journal log */
	  sb_journal_block(&super) * sb_blocksize(&super)
	  <= REISERFS_DISK_OFFSET_IN_BYTES))
    {
      /* Try old super block position */
      superblock = REISERFS_OLD_DISK_OFFSET_IN_BYTES >> SECTOR_BITS;
      if (part_length < superblock + (sizeof (super) >> SECTOR_BITS)
	  || ! reiserfs_devread (superblock, 0, sizeof (struct reiserfs_super_block),
				 (char *) &super))
	return 0;

      if (substring (REISER2FS_SUPER_MAGIC_STRING, super.s_magic) > 0
	  && substring (REISERFS_SUPER_MAGIC_STRING, super.s_magic) > 0)
	{
	  /* pre journaling super block ? */
	  if (substring (REISERFS_SUPER_MAGIC_STRING,
			 (char*) ((int) &super + 20)) > 0)
	    return 0;

	  set_sb_blocksize(&super, REISERFS_OLD_BLOCKSIZE);
	  set_sb_journal_block(&super, 0);
	  set_sb_version(&super, 0);
	}
    }

  /* check the version number.  */
  if (sb_version(&super) > REISERFS_MAX_SUPPORTED_VERSION)
    return 0;

  INFO->version = sb_version(&super);
  INFO->blocksize = sb_blocksize(&super);
  INFO->fullblocksize_shift = log2 (sb_blocksize(&super));
  INFO->blocksize_shift = INFO->fullblocksize_shift - SECTOR_BITS;
  INFO->cached_slots =
    (FSYSREISER_CACHE_SIZE >> INFO->fullblocksize_shift) - 1;

#ifdef REISERDEBUG
  printf ("reiserfs_mount: version=%d, blocksize=%d\n",
	  INFO->version, INFO->blocksize);
#endif /* REISERDEBUG */

  /* Clear node cache. */
  memset (INFO->blocks, 0, sizeof (INFO->blocks));

  if (sb_blocksize(&super) < FSYSREISER_MIN_BLOCKSIZE
      || sb_blocksize(&super) > FSYSREISER_MAX_BLOCKSIZE
      || (SECTOR_SIZE << INFO->blocksize_shift) != sb_blocksize(&super))
    return 0;

  /* Initialize journal code.  If something fails we end with zero
   * journal_transactions, so we don't access the journal at all.
   */
  INFO->journal_transactions = 0;
  if (sb_journal_block(&super) != 0 && super.s_journal_dev == 0)
    {
      INFO->journal_block = sb_journal_block(&super);
      INFO->journal_block_count = sb_journal_size(&super);
      if (is_power_of_two (INFO->journal_block_count))
	journal_init ();

      /* Read in super block again, maybe it is in the journal */
      block_read (superblock >> INFO->blocksize_shift,
		  0, sizeof (struct reiserfs_super_block), (char *) &super);
    }

  if (! block_read (sb_root_block(&super), 0, INFO->blocksize, (char*) ROOT))
    return 0;

  INFO->tree_depth = __le16_to_cpu(BLOCKHEAD (ROOT)->blk_level);

#ifdef REISERDEBUG
  printf ("root read_in: block=%d, depth=%d\n",
	  sb_root_block(&super), INFO->tree_depth);
#endif /* REISERDEBUG */

  if (INFO->tree_depth >= MAX_HEIGHT)
    return 0;
  if (INFO->tree_depth == DISK_LEAF_NODE_LEVEL)
    {
      /* There is only one node in the whole filesystem,
       * which is simultanously leaf and root */
      memcpy (LEAF, ROOT, INFO->blocksize);
    }
  return 1;
}

/***************** TREE ACCESSING METHODS *****************************/

/* I assume you are familiar with the ReiserFS tree, if not go to
 * http://www.namesys.com/content_table.html
 *
 * My tree node cache is organized as following
 *   0   ROOT node
 *   1   LEAF node  (if the ROOT is also a LEAF it is copied here
 *   2-n other nodes on current path from bottom to top.
 *       if there is not enough space in the cache, the top most are
 *       omitted.
 *
 * I have only two methods to find a key in the tree:
 *   search_stat(dir_id, objectid) searches for the stat entry (always
 *       the first entry) of an object.
 *   next_key() gets the next key in tree order.
 *
 * This means, that I can only sequential reads of files are
 * efficient, but this really doesn't hurt for grub.
 */

/* Read in the node at the current path and depth into the node cache.
 * You must set INFO->blocks[depth] before.
 */
static char *
read_tree_node (unsigned int blockNr, int depth)
{
  char* cache = CACHE(depth);
  int num_cached = INFO->cached_slots;
  if (depth < num_cached)
    {
      /* This is the cached part of the path.  Check if same block is
       * needed.
       */
      if (blockNr == INFO->blocks[depth])
	return cache;
    }
  else
    cache = CACHE(num_cached);

#ifdef REISERDEBUG
  printf ("  next read_in: block=%d (depth=%d)\n",
	  blockNr, depth);
#endif /* REISERDEBUG */
  if (! block_read (blockNr, 0, INFO->blocksize, cache))
    return 0;
  /* Make sure it has the right node level */
  if (__le16_to_cpu(BLOCKHEAD (cache)->blk_level) != depth)
    {
      errnum = ERR_FSYS_CORRUPT;
      return 0;
    }

  INFO->blocks[depth] = blockNr;
  return cache;
}

/* Get the next key, i.e. the key following the last retrieved key in
 * tree order.  INFO->current_ih and
 * INFO->current_info are adapted accordingly.  */
static int
next_key (void)
{
  int depth;
  struct item_head *ih = INFO->current_ih + 1;
  char *cache;

#ifdef REISERDEBUG
  printf ("next_key:\n  old ih: key %d:%d:%d:%d version:%d\n",
	  __le32_to_cpu(INFO->current_ih->ih_key.k_dir_id),
	  __le32_to_cpu(INFO->current_ih->ih_key.k_objectid),
	  __le32_to_cpu(INFO->current_ih->ih_key.u.v1.k_offset),
	  __le32_to_cpu(INFO->current_ih->ih_key.u.v1.k_uniqueness),
	  __le16_to_cpu(INFO->current_ih->ih_version));
#endif /* REISERDEBUG */

  if (ih == &ITEMHEAD[__le16_to_cpu(BLOCKHEAD (LEAF)->blk_nr_item)])
    {
      depth = DISK_LEAF_NODE_LEVEL;
      /* The last item, was the last in the leaf node.
       * Read in the next block
       */
      do
	{
	  if (depth == INFO->tree_depth)
	    {
	      /* There are no more keys at all.
	       * Return a dummy item with MAX_KEY */
	      ih = (struct item_head *) &BLOCKHEAD (LEAF)->blk_right_delim_key;
	      goto found;
	    }
	  depth++;
#ifdef REISERDEBUG
	  printf ("  depth=%d, i=%d\n", depth, INFO->next_key_nr[depth]);
#endif /* REISERDEBUG */
	}
      while (INFO->next_key_nr[depth] == 0);

      if (depth == INFO->tree_depth)
	cache = ROOT;
      else if (depth <= INFO->cached_slots)
	cache = CACHE (depth);
      else
	{
	  cache = read_tree_node (INFO->blocks[depth], depth);
	  if (! cache)
	    return 0;
	}

      do
	{
	  int nr_item = __le16_to_cpu(BLOCKHEAD (cache)->blk_nr_item);
	  int key_nr = INFO->next_key_nr[depth]++;
#ifdef REISERDEBUG
	  printf ("  depth=%d, i=%d/%d\n", depth, key_nr, nr_item);
#endif /* REISERDEBUG */
	  if (key_nr == nr_item)
	    /* This is the last item in this block, set the next_key_nr to 0 */
	    INFO->next_key_nr[depth] = 0;

	  cache = read_tree_node (dc_block_number(&(DC (cache)[key_nr])), --depth);
	  if (! cache)
	    return 0;
	}
      while (depth > DISK_LEAF_NODE_LEVEL);

      ih = ITEMHEAD;
    }
 found:
  INFO->current_ih   = ih;
  INFO->current_item = &LEAF[__le16_to_cpu(ih->ih_item_location)];
#ifdef REISERDEBUG
  printf ("  new ih: key %d:%d:%d:%d version:%d\n",
	  __le32_to_cpu(INFO->current_ih->ih_key.k_dir_id),
	  __le32_to_cpu(INFO->current_ih->ih_key.k_objectid),
	  __le32_to_cpu(INFO->current_ih->ih_key.u.v1.k_offset),
	  __le32_to_cpu(INFO->current_ih->ih_key.u.v1.k_uniqueness),
	  __le16_to_cpu(INFO->current_ih->ih_version));
#endif /* REISERDEBUG */
  return 1;
}

/* preconditions: reiserfs_mount already executed, therefore
 *   INFO block is valid
 * returns: 0 if error (errnum is set),
 *   nonzero iff we were able to find the key successfully.
 * postconditions: on a nonzero return, the current_ih and
 *   current_item fields describe the key that equals the
 *   searched key.  INFO->next_key contains the next key after
 *   the searched key.
 * side effects: messes around with the cache.
 */
static int
search_stat (__u32 dir_id, __u32 objectid)
{
  char *cache;
  int depth;
  int nr_item;
  int i;
  struct item_head *ih;
#ifdef REISERDEBUG
  printf ("search_stat:\n  key %d:%d:0:0\n", dir_id, objectid);
#endif /* REISERDEBUG */

  depth = INFO->tree_depth;
  cache = ROOT;

  while (depth > DISK_LEAF_NODE_LEVEL)
    {
      struct key *key;
      nr_item = __le16_to_cpu(BLOCKHEAD (cache)->blk_nr_item);

      key = KEY (cache);

      for (i = 0; i < nr_item; i++)
	{
	  if (__le32_to_cpu(key->k_dir_id) > dir_id
	      || (__le32_to_cpu(key->k_dir_id) == dir_id
		  && (__le32_to_cpu(key->k_objectid) > objectid
		      || (__le32_to_cpu(key->k_objectid) == objectid
			  && (__le32_to_cpu(key->u.v1.k_offset)
			      | __le32_to_cpu(key->u.v1.k_uniqueness)) > 0))))
	    break;
	  key++;
	}

#ifdef REISERDEBUG
      printf ("  depth=%d, i=%d/%d\n", depth, i, nr_item);
#endif /* REISERDEBUG */
      INFO->next_key_nr[depth] = (i == nr_item) ? 0 : i+1;
      cache = read_tree_node (dc_block_number(&(DC (cache)[i])), --depth);
      if (! cache)
	return 0;
    }

  /* cache == LEAF */
  nr_item = __le16_to_cpu(BLOCKHEAD (LEAF)->blk_nr_item);
  ih = ITEMHEAD;
  for (i = 0; i < nr_item; i++)
    {
      if (__le32_to_cpu(ih->ih_key.k_dir_id) == dir_id
	  && __le32_to_cpu(ih->ih_key.k_objectid) == objectid
	  && __le32_to_cpu(ih->ih_key.u.v1.k_offset) == 0
	  && __le32_to_cpu(ih->ih_key.u.v1.k_uniqueness) == 0)
	{
#ifdef REISERDEBUG
	  printf ("  depth=%d, i=%d/%d\n", depth, i, nr_item);
#endif /* REISERDEBUG */
	  INFO->current_ih   = ih;
	  INFO->current_item = &LEAF[__le16_to_cpu(ih->ih_item_location)];
	  return 1;
	}
      ih++;
    }
  errnum = ERR_FSYS_CORRUPT;
  return 0;
}

int
reiserfs_read (char *buf, unsigned len)
{
  unsigned int blocksize;
  unsigned int offset;
  unsigned int to_read;
  char *prev_buf = buf;

#ifdef REISERDEBUG
  printf ("reiserfs_read: filepos=%d len=%d, offset=%Lx\n",
	  filepos, len, (__u64) IH_KEY_OFFSET (INFO->current_ih) - 1);
#endif /* REISERDEBUG */

  if (__le32_to_cpu(INFO->current_ih->ih_key.k_objectid) != INFO->fileinfo.k_objectid
      || IH_KEY_OFFSET (INFO->current_ih) > filepos + 1)
    {
      search_stat (INFO->fileinfo.k_dir_id, INFO->fileinfo.k_objectid);
      goto get_next_key;
    }

  while (! errnum)
    {
      if (__le32_to_cpu(INFO->current_ih->ih_key.k_objectid) != INFO->fileinfo.k_objectid) {
	break;
      }

      offset = filepos - IH_KEY_OFFSET (INFO->current_ih) + 1;
      blocksize = __le16_to_cpu(INFO->current_ih->ih_item_len);

#ifdef REISERDEBUG
      printf ("  loop: filepos=%d len=%d, offset=%d blocksize=%d\n",
	      filepos, len, offset, blocksize);
#endif /* REISERDEBUG */

      if (IH_KEY_ISTYPE(INFO->current_ih, TYPE_DIRECT)
	  && offset < blocksize)
	{
#ifdef REISERDEBUG
	  printf ("direct_read: offset=%d, blocksize=%d\n",
		  offset, blocksize);
#endif /* REISERDEBUG */
	  to_read = blocksize - offset;
	  if (to_read > len)
	    to_read = len;

	  memcpy (buf, INFO->current_item + offset, to_read);
	  goto update_buf_len;
	}
      else if (IH_KEY_ISTYPE(INFO->current_ih, TYPE_INDIRECT))
	{
	  blocksize = (blocksize >> 2) << INFO->fullblocksize_shift;
#ifdef REISERDEBUG
	  printf ("indirect_read: offset=%d, blocksize=%d\n",
		  offset, blocksize);
#endif /* REISERDEBUG */

	  while (offset < blocksize)
	    {
	      __u32 blocknr = __le32_to_cpu(((__u32 *) INFO->current_item)
		[offset >> INFO->fullblocksize_shift]);
	      int blk_offset = offset & (INFO->blocksize-1);
	      to_read = INFO->blocksize - blk_offset;
	      if (to_read > len)
		to_read = len;

	      /* Journal is only for meta data.  Data blocks can be read
	       * directly without using block_read
	       */
	      reiserfs_devread (blocknr << INFO->blocksize_shift,
				blk_offset, to_read, buf);
	    update_buf_len:
	      len -= to_read;
	      buf += to_read;
	      offset += to_read;
	      filepos += to_read;
	      if (len == 0)
		goto done;
	    }
	}
    get_next_key:
      next_key ();
    }
 done:
  return errnum ? 0 : buf - prev_buf;
}


/* preconditions: reiserfs_mount already executed, therefore
 *   INFO block is valid
 * returns: 0 if error, nonzero iff we were able to find the file successfully
 * postconditions: on a nonzero return, INFO->fileinfo contains the info
 *   of the file we were trying to look up, filepos is 0 and filemax is
 *   the size of the file.
 */
static int
reiserfs_dir (char *dirname)
{
  struct reiserfs_de_head *de_head;
  char *rest, ch;
  __u32 dir_id, objectid, parent_dir_id = 0, parent_objectid = 0;
#ifndef STAGE1_5
  int do_possibilities = 0;
#endif /* ! STAGE1_5 */
  char linkbuf[PATH_MAX];	/* buffer for following symbolic links */
  int link_count = 0;
  int mode;

  dir_id = REISERFS_ROOT_PARENT_OBJECTID;
  objectid = REISERFS_ROOT_OBJECTID;

  while (1)
    {
#ifdef REISERDEBUG
      printf ("dirname=%s\n", dirname);
#endif /* REISERDEBUG */

      /* Search for the stat info first. */
      if (! search_stat (dir_id, objectid))
	return 0;

#ifdef REISERDEBUG
       printf ("sd_mode=%x sd_size=%d\n",
	       stat_data_v1(INFO->current_ih) ? sd_v1_mode((struct stat_data_v1 *) INFO->current_item) :
						sd_v2_mode((struct stat_data *) (INFO->current_item)),
	       stat_data_v1(INFO->current_ih) ? sd_v1_size((struct stat_data_v1 *) INFO->current_item) :
						sd_v2_size((struct stat_data *) INFO->current_item)
	      );

#endif /* REISERDEBUG */
      mode = stat_data_v1(INFO->current_ih) ?
	       sd_v1_mode((struct stat_data_v1 *) INFO->current_item) :
	       sd_v2_mode((struct stat_data *) INFO->current_item);

      /* If we've got a symbolic link, then chase it. */
      if (S_ISLNK (mode))
	{
	  unsigned int len;
	  if (++link_count > MAX_LINK_COUNT)
	    {
	      errnum = ERR_SYMLINK_LOOP;
	      return 0;
	    }

	  /* Get the symlink size. */
	  filemax = stat_data_v1(INFO->current_ih) ?
		     sd_v1_size((struct stat_data_v1 *) INFO->current_item) :
		     sd_v2_size((struct stat_data *) INFO->current_item);

	  /* Find out how long our remaining name is. */
	  len = 0;
	  while (dirname[len] && !isspace (dirname[len]))
	    len++;

	  if (filemax + len > sizeof (linkbuf) - 1)
	    {
	      errnum = ERR_FILELENGTH;
	      return 0;
	    }

	  /* Copy the remaining name to the end of the symlink data.
	     Note that DIRNAME and LINKBUF may overlap! */
	  memmove (linkbuf + filemax, dirname, len+1);

	  INFO->fileinfo.k_dir_id = dir_id;
	  INFO->fileinfo.k_objectid = objectid;
	  filepos = 0;
	  if (! next_key ()
	      || reiserfs_read (linkbuf, filemax) != filemax)
	    {
	      if (! errnum)
		errnum = ERR_FSYS_CORRUPT;
	      return 0;
	    }

#ifdef REISERDEBUG
	  printf ("symlink=%s\n", linkbuf);
#endif /* REISERDEBUG */

	  dirname = linkbuf;
	  if (*dirname == '/')
	    {
	      /* It's an absolute link, so look it up in root. */
	      dir_id = REISERFS_ROOT_PARENT_OBJECTID;
	      objectid = REISERFS_ROOT_OBJECTID;
	    }
	  else
	    {
	      /* Relative, so look it up in our parent directory. */
	      dir_id   = parent_dir_id;
	      objectid = parent_objectid;
	    }

	  /* Now lookup the new name. */
	  continue;
	}

      /* 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 (! S_ISREG (mode))
	    {
	      errnum = ERR_BAD_FILETYPE;
	      return 0;
	    }

	  filepos = 0;
	  filemax = stat_data_v1(INFO->current_ih) ?
		      sd_v1_size((struct stat_data_v1 *) INFO->current_item) :
		      sd_v2_size((struct stat_data *) INFO->current_item);
#if 0
	  /* If this is a new stat data and size is > 4GB set filemax to
	   * maximum
	   */
	  if (__le16_to_cpu(INFO->current_ih->ih_version) == ITEM_VERSION_2
	      && sd_size_hi((struct stat_data *) INFO->current_item) > 0)
	    filemax = 0xffffffff;
#endif
	  INFO->fileinfo.k_dir_id = dir_id;
	  INFO->fileinfo.k_objectid = objectid;
	  return next_key ();
	}

      /* continue with the file/directory name interpretation */
      while (*dirname == '/')
	dirname++;
      if (! S_ISDIR (mode))
	{
	  errnum = ERR_BAD_FILETYPE;
	  return 0;
	}
      for (rest = dirname; (ch = *rest) && ! isspace (ch) && ch != '/'; rest++);
      *rest = 0;

# ifndef STAGE1_5
      if (print_possibilities && ch != '/')
	do_possibilities = 1;
# endif /* ! STAGE1_5 */

      while (1)
	{
	  char *name_end;
	  int num_entries;

	  if (! next_key ())
	    return 0;
#ifdef REISERDEBUG
	  printf ("ih: key %d:%d:%d:%d version:%d\n",
		  __le32_to_cpu(INFO->current_ih->ih_key.k_dir_id),
		  __le32_to_cpu(INFO->current_ih->ih_key.k_objectid),
		  __le32_to_cpu(INFO->current_ih->ih_key.u.v1.k_offset),
		  __le32_to_cpu(INFO->current_ih->ih_key.u.v1.k_uniqueness),
		  __le16_to_cpu(INFO->current_ih->ih_version));
#endif /* REISERDEBUG */

	  if (__le32_to_cpu(INFO->current_ih->ih_key.k_objectid) != objectid)
	    break;

	  name_end = INFO->current_item + __le16_to_cpu(INFO->current_ih->ih_item_len);
	  de_head = (struct reiserfs_de_head *) INFO->current_item;
	  num_entries = __le16_to_cpu(INFO->current_ih->u.ih_entry_count);
	  while (num_entries > 0)
	    {
	      char *filename = INFO->current_item + deh_location(de_head);
	      char  tmp = *name_end;
	      if ((deh_state(de_head) & DEH_Visible))
		{
		  int cmp;
		  /* Directory names in ReiserFS are not null
		   * terminated.  We write a temporary 0 behind it.
		   * NOTE: that this may overwrite the first block in
		   * the tree cache.  That doesn't hurt as long as we
		   * don't call next_key () in between.
		   */
		  *name_end = 0;
		  cmp = substring (dirname, filename);
		  *name_end = tmp;
# ifndef STAGE1_5
		  if (do_possibilities)
		    {
		      if (cmp <= 0)
			{
			  char fn[PATH_MAX];
			  struct fsys_reiser_info info_save;

			  if (print_possibilities > 0)
			    print_possibilities = -print_possibilities;
			  *name_end = 0;
			  strcpy(fn, filename);
			  *name_end = tmp;

			  /* If NAME is "." or "..", do not count it.  */
			  if (strcmp (fn, ".") != 0 && strcmp (fn, "..") != 0) {
			    memcpy(&info_save, INFO, sizeof(struct fsys_reiser_info));
			    search_stat (deh_dir_id(de_head), deh_objectid(de_head));
			    sd_print_item(INFO->current_ih, INFO->current_item);
			    printf(" %s\n", fn);
			    search_stat (dir_id, objectid);
			    memcpy(INFO, &info_save, sizeof(struct fsys_reiser_info));
			  }
			}
		    }
		  else
# endif /* ! STAGE1_5 */
		    if (cmp == 0)
		      goto found;
		}
	      /* The beginning of this name marks the end of the next name.
	       */
	      name_end = filename;
	      de_head++;
	      num_entries--;
	    }
	}

# ifndef STAGE1_5
      if (print_possibilities < 0)
	return 1;
# endif /* ! STAGE1_5 */

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

    found:
      *rest = ch;
      dirname = rest;

      parent_dir_id = dir_id;
      parent_objectid = objectid;
      dir_id = deh_dir_id(de_head);
      objectid = deh_objectid(de_head);
    }
}

/*
 * U-Boot interface functions
 */

/*
 * List given directory
 *
 * RETURN: 0 - OK, else grub_error_t errnum
 */
int
reiserfs_ls (char *dirname)
{
	char *dir_slash;
	int res;

	errnum = 0;
	dir_slash = malloc(strlen(dirname) + 1);
	if (dir_slash == NULL) {
		return ERR_NUMBER_OVERFLOW;
	}
	strcpy(dir_slash, dirname);
	/* add "/" to the directory name */
	strcat(dir_slash, "/");

	print_possibilities = 1;
	res = reiserfs_dir (dir_slash);
	free(dir_slash);
	if (!res || errnum) {
		return errnum;
	}

	return 0;
}

/*
 * Open file for reading
 *
 * RETURN: >0 - OK, size of opened file
 *         <0 - ERROR  -grub_error_t errnum
 */
int
reiserfs_open (char *filename)
{
	/* open the file */
	errnum = 0;
	print_possibilities = 0;
	if (!reiserfs_dir (filename) || errnum) {
		return -errnum;
	}
	return filemax;
}

#endif
