/* -*-C-*- */

/*  const.c  */


/*
 * Author: Nikita Danilov <NikitaDanilov@yahoo.COM>
 * Keywords: dafs, vfs, open by inode, open by key
 *
 * Copyright (C) 2000 Namesys (Hans Reiser)
 *
 * This file is part of dafs.
 *
 * Dafs 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, or (at your option)
 * any later version.
 *
 * This software 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 software; see the file COPYING.  If not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 */

#include "da.h"

/* $Id$ */
static char cvsid[] = "@(#)$Id$";
static char debugFileId[] = __FILE__;

/* externs */

/* forward declarations */

extern ssize_t const_read( struct file *file, char *buffer, size_t len, 
						   loff_t *offset );

/* global data definitions */

struct file_operations const_file_ops = {
  read: &const_read,
};

struct inode_operations	const_inode_ops = {
#if defined( LINUX_2_2 )
  default_file_ops: &const_file_ops,
#endif
  lookup: lookup,
};

/* definitions */

static inline long min( long a, long b )
{
  return( ( a < b ) ? a : b );
}


ssize_t const_read( struct file *file, char *buffer, size_t len, 
					loff_t *offset )
{
  int size;
  char **start;
  char **scan;
  char *message;
  struct da_entry *entry;

  ssize_t to_copy;

  static unsigned long seed = 0;

  entry = HENTRY( file -> f_dentry -> d_inode -> u.generic_ip );
  TRACE;
  if( *offset == 0 )
	{
	  for( scan = ( char ** ) entry -> specific ; *scan ; --scan )
		{}
	  ++scan;
	  HDEBUG( "scan: `%s'", *scan );
	  size = 0;
	  for( start = scan ; *scan ; ++scan, ++size )
		{}
  
	  HASSERT( size > 0 );
	  HDEBUG( "size: %i", size );

	  HDEBUG( "seed %% size = %li", seed % size );
	  entry -> specific = start + ( seed % size );

	  ++seed;
	}
  message = * ( char ** ) entry -> specific;

  to_copy = min( strlen( message ) - *offset, len );
  copy_to_user( buffer, message + *offset, to_copy );
  *offset += to_copy;
  return to_copy;
}

struct da_entry *new_const_entry( struct da_entry *parent, 
								  char *name, umode_t mode,
								  char **contents )
{
  struct da_entry *result;
  
  HASSERT( ! S_ISDIR( mode ) );
  HASSERT( contents != NULL );
  
  result = new_entry( parent, name, mode, &const_inode_ops, &const_file_ops );
  result -> specific = contents;
  return result;
}

/*
 * $Log$
 */

