/* iso9660.h: */

#ifndef _ISO9660_H_
#define _ISO9660_H_

typedef struct directory_record {
  unsigned char         length;
  unsigned char         ext_attr_length;
  unsigned long         extent_loc_i;
  unsigned long         extent_loc_m;
  unsigned long		data_length_i;
  unsigned long		data_length_m;
  unsigned char		year;
  unsigned char		month;
  unsigned char		day;
  unsigned char		hour;
  unsigned char		minute;
  unsigned char		second;  
  char			tz;
  unsigned char		flags;
  unsigned char		file_unit_size;
  unsigned char		gap_size;
  unsigned short	sequence_i;
  unsigned short	sequence_m;
  unsigned char		file_id_length;
  char			file_id[1];
} directory_record;

typedef struct path_table_record {
  unsigned char         id_length;
  unsigned char         ext_attr_length;
  unsigned long		location;
  unsigned short        parent;
  char                  id[1];
} path_table_record;

typedef char time_and_date[17];

typedef struct prim_vol_desc {
  unsigned char		type;
  char			id[5];
  unsigned char		version;
  char			pad1;
  char			system_id[32];
  char			volume_id[32];
  char			pad2[8];
  unsigned long		space_size_i;
  unsigned long		space_size_m;
  char			pad3[32];
  unsigned short	set_size_i;
  unsigned short	set_size_m;
  unsigned short	sequence_i;
  unsigned short	sequence_m;
  unsigned short	block_size_i;
  unsigned short	block_size_m;
  unsigned long		path_size_i;
  unsigned long		path_size_m;
  unsigned long         l_table;
  unsigned long         opt_l_table;
  unsigned long         m_table;
  unsigned long         opt_m_table;
  directory_record      root;
  char			volume_set_id[128];
  char			publisher_id[128];
  char			data_preparer[128];
  char			application_id[128];
  char			copyright[37];
  char			abstract_file_id[37];
  char			bibliographic_id[37];
  time_and_date		vol_creation;
  time_and_date		vol_modification;
  time_and_date		vol_expiration;
  time_and_date		vol_effective;
  unsigned char		file_structure_version;
  char			pad4;
  char			application_use[512];
  char			reserved[653];
} prim_vol_desc;

typedef struct VOLUME {
  CDROM		*cd;
  prim_vol_desc pvd;
  short		use_rock_ridge;
  /* for use by the Rock Ridge protocol: */
  int		skip;
  /* for use by the device handler: */
  short		valid;
  int		locks;
} VOLUME;

typedef struct CDROM_OBJ {
  short			directory_f;	/* TRUE iff object is a directory     */
  VOLUME		*volume;	/* Pointer to volume node	      */
  unsigned long 	path_table_pos;	/* (ISO only:) index to path table    */
  unsigned long 	parent;		/* ISO: index of parent in path table */
  					/* RR: location of parent directory   */
  unsigned long		pos;		/* Current position (for read & seek) */
  directory_record	*dir_record;    /* Pointer to directory record        */
} CDROM_OBJ;

typedef struct CDROM_INFO {
  directory_record	dir_record;
  char			pad[222];	/* rest of directory record	*/
  int			name_length;	/* length of file name		*/
  char			name[256];	/* file name			*/
} CDROM_INFO;

#define ISOERR_NO_MEMORY	1	/* out of memory		*/
#define ISOERR_SCSI_ERROR	2	/* scsi command return with err */
#define ISOERR_NO_PVD		3	/* prim volume descr not found	*/
#define ISOERR_ILLEGAL_NAME	4	/* illegal path name		*/
#define ISOERR_NO_SUCH_RECORD	5	/* no such record in path table */
#define ISOERR_NOT_FOUND	6	/* file not found		*/
#define ISOERR_OFF_BOUNDS	7	/* bad seek operation		*/
#define ISOERR_BAD_ARGUMENTS	8	/* bad arguments		*/

#define SEEK_FROM_START		-1	/* values for			*/
#define SEEK_FROM_CURRENT_POS	0	/* the 'Seek_Position'		*/
#define SEEK_FROM_END		1	/* function			*/

extern int iso_errno;

VOLUME *Open_Volume (CDROM *p_cdrom, int p_use_rock_ridge);
void Close_Volume (VOLUME *p_volume);

CDROM_OBJ *Open_Top_Level_Directory (VOLUME *p_volume);
CDROM_OBJ *Open_Object (CDROM_OBJ *p_current_dir, char *p_name);
void Close_Object (CDROM_OBJ *p_object);

int Read_From_File (CDROM_OBJ *p_file, char *p_buffer, int p_buffer_length);

int CDROM_Info (CDROM_OBJ *p_obj, CDROM_INFO *p_info);
int Examine_Next (CDROM_OBJ *p_dir, CDROM_INFO *p_info, unsigned long *p_offset);

CDROM_OBJ *Clone_Object (CDROM_OBJ *p_object);
CDROM_OBJ *Find_Parent (CDROM_OBJ *p_object);

int Is_Top_Level_Object (CDROM_OBJ *p_object);

int Seek_Position (CDROM_OBJ *p_object, long p_offset, int p_mode);

directory_record *Get_Directory_Record (VOLUME *p_volume,
					unsigned long p_location,
					unsigned long p_offset);
directory_record *Find_Directory_Entry (VOLUME *p_volume, unsigned long p_location,
			                char *p_name);


#endif /* _ISO9660_H_ */
