/*
 *  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>
#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;
}
