/*
 *  GRUB  --  GRand Unified Bootloader
 *  Copyright (C) 2001   Free Software Foundation, Inc.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 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.
 */

#ifdef FSYS_VSTAFS

#include "shared.h"
#include "filesys.h"
#include "vstafs.h"


static void get_file_info (int sector);
static struct dir_entry *vstafs_readdir (long sector);
static struct dir_entry *vstafs_nextdir (void);


#define FIRST_SECTOR	((struct first_sector *) FSYS_BUF)
#define FILE_INFO	((struct fs_file *) (int) FIRST_SECTOR + 8192)
#define DIRECTORY_BUF	((struct dir_entry *) (int) FILE_INFO + 512)

#define ROOT_SECTOR	1

/*
 * In f_sector we store the sector number in which the information about
 * the found file is.
 */
extern int filepos;
static int f_sector;

int 
vstafs_mount (void)
{
  int retval = 1;
  
  if( (((current_drive & 0x80) || (current_slice != 0))
       && current_slice != PC_SLICE_TYPE_VSTAFS)
      ||  ! devread (0, 0, BLOCK_SIZE, (char *) FSYS_BUF)
      ||  FIRST_SECTOR->fs_magic != 0xDEADFACE)
    retval = 0;
  
  return retval;
}

static void 
get_file_info (int sector)
{
  devread (sector, 0, BLOCK_SIZE, (char *) FILE_INFO);
}

static int curr_ext, current_direntry, current_blockpos;
static struct alloc *a;

static struct dir_entry *
vstafs_readdir (long sector)
{
  /*
   * Get some information from the current directory
   */
  get_file_info (sector);
  if (FILE_INFO->type != 2)
    {
      errnum = ERR_FILE_NOT_FOUND;
      return 0;
    }
  
  a = FILE_INFO->blocks;
  curr_ext = 0;
  devread (a[curr_ext].a_start, 0, 512, (char *) DIRECTORY_BUF);
  current_direntry = 11;
  current_blockpos = 0;
  
  return &DIRECTORY_BUF[10];
}

static struct dir_entry *
vstafs_nextdir (void)
{
  if (current_direntry > 15)
    {
      current_direntry = 0;
      if (++current_blockpos > (a[curr_ext].a_len - 1))
	{
	  current_blockpos = 0;
	  curr_ext++;
	}
      
      if (curr_ext < FILE_INFO->extents)
	{
	  devread (a[curr_ext].a_start + current_blockpos, 0,
		   512, (char *) DIRECTORY_BUF);
	}
      else
	{
	  /* errnum =ERR_FILE_NOT_FOUND; */
	  return 0;
	}
    }
  
  return &DIRECTORY_BUF[current_direntry++];
}

int 
vstafs_dir (char *dirname)
{
  char *fn, ch;
  struct dir_entry *d;
  /* int l, i, s; */
  
  /*
   * Read in the entries of the current directory.
   */
  f_sector = ROOT_SECTOR;
  do
    {
      if (! (d = vstafs_readdir (f_sector)))
	{
	  return 0;
	}
      
      /*
       * Find the file in the path
       */
      while (*dirname == '/') dirname++;
      fn = dirname;
      while ((ch = *fn) && ch != '/' && ! isspace (ch)) fn++;
      *fn = 0;
      
      do
	{
	  if (d->name[0] == 0 || d->name[0] & 0x80)
	    continue;
	  
#ifndef STAGE1_5
	  if (print_possibilities && ch != '/'
	      && (! *dirname || strcmp (dirname, d->name) <= 0))
	    {
	      if (print_possibilities > 0)
		print_possibilities = -print_possibilities;
	      
	      printf ("  %s", d->name);
	    }
#endif
	  if (! grub_strcmp (dirname, d->name))
	    {
	      f_sector = d->start;
	      get_file_info (f_sector);
	      filemax = FILE_INFO->len; 
	      break;
	    }
	}
      while ((d =vstafs_nextdir ()));
      
      *(dirname = fn) = ch;
      if (! d)
	{
	  if (print_possibilities < 0)
	    {
	      putchar ('\n');
	      return 1;
	    }
	  
	  errnum = ERR_FILE_NOT_FOUND;
	  return 0;
	}
    }
  while (*dirname && ! isspace (ch));
  
  return 1;
}

int 
vstafs_read (char *addr, int len)
{
  struct alloc *a;
  int size, ret = 0, offset, curr_len = 0;
  int curr_ext;
  char extent;
  int ext_size;
  char *curr_pos;
  
  get_file_info (f_sector);
  size = FILE_INFO->len-VSTAFS_START_DATA;
  a = FILE_INFO->blocks;
  
  if (filepos > 0)
    {
      if (filepos < a[0].a_len * 512 - VSTAFS_START_DATA)
	{
	  offset = filepos + VSTAFS_START_DATA;
	  extent = 0;
	  curr_len = a[0].a_len * 512 - offset - filepos; 
	}
      else
	{
	  ext_size = a[0].a_len * 512 - VSTAFS_START_DATA;
	  offset = filepos - ext_size;
	  extent = 1;
	  do
	    {
	      curr_len -= ext_size;
	      offset -= ext_size;
	      ext_size = a[extent+1].a_len * 512;
	    }
	  while (extent < FILE_INFO->extents && offset>ext_size);
	}
    }
  else
    {
      offset = VSTAFS_START_DATA;
      extent = 0;
      curr_len = a[0].a_len * 512 - offset;
    }
  
  curr_pos = addr;
  if (curr_len > len)
    curr_len = len;
  
  for (curr_ext=extent;
       curr_ext < FILE_INFO->extents; 
       curr_len = a[curr_ext].a_len * 512, curr_pos += curr_len, curr_ext++)
    {
      ret += curr_len;
      size -= curr_len;
      if (size < 0)
	{
	  ret += size;
	  curr_len += size;
	}
      
      devread (a[curr_ext].a_start,offset, curr_len, curr_pos);
      offset = 0;
    }
  
  return ret;
}

#endif /* FSYS_VSTAFS */
