home *** CD-ROM | disk | FTP | other *** search
- /* iso9660.c:
- *
- * Support for the ISO-9660 filing system.
- *
- * ----------------------------------------------------------------------
- * This code is (C) Copyright 1993,1994 by Frank Munkert.
- * All rights reserved.
- * This software may be freely distributed and redistributed for
- * non-commercial purposes, provided this notice is included.
- * ----------------------------------------------------------------------
- * History:
- *
- * 17-May-94 fmu New option MAYBELOWERCASE (=ML).
- * 25-Apr-94 fmu The extented attribute record length has to be
- * considered when reading file sections.
- * 17-Feb-94 fmu Volume ID must not be longer than 30 characters.
- * 05-Feb-94 fmu Added support for relocated directories.
- * 07-Jan-94 fmu Support for drives which don't support the SCSI-2
- * READ TOC command.
- * 01-Jan-94 fmu Added multisession support.
- * 11-Dec-93 fmu Fixed bug in Iso_Find_Parent().
- * 02-Dec-93 fmu Bugfix: a logical block of a file extent must not
- * necessarily start at a logical sector border.
- * 29-Nov-93 fmu - New function Iso_Block_Size().
- * - Support for variable logical block sizes.
- * 15-Nov-93 fmu Uses_High_Sierra_Protocol added.
- * 13-Nov-93 fmu Bad iso_errno return value in Iso_Open_Obj_In_Directory
- * corrected.
- * 12-Oct-93 fmu Adapted to new VOLUME and CDROM_OBJ structures.
- * 24-Sep-93 fmu Two further bugs in Seek_Position fixed.
- * 16-Sep-93 fmu Fixed bug in Seek_Position.
- * 16-Sep-93 fmu Bugfix: Top level object recognition in CDROM_Info
- * had to be changed for Rock Ridge disks.
- */
-
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
-
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <clib/exec_protos.h>
- #include <clib/utility_protos.h>
- #ifdef AZTEC_C
- #include <pragmas/exec_lib.h>
- #include <pragmas/utility_lib.h>
- #endif
- #ifdef LATTICE
- #include <pragmas/exec_pragmas.h>
- #include <pragmas/utility_pragmas.h>
- #endif
- #if defined(_DCC) && defined(REGISTERED)
- #include <pragmas/exec_pragmas.h>
- #include <pragmas/utility_pragmas.h>
- extern struct Library *SysBase;
- #endif
-
- #include "cdrom.h"
- #include "iso9660.h"
- #include "rock.h"
-
- extern struct Library *UtilityBase;
-
- t_bool Iso_Is_Top_Level_Object (CDROM_OBJ *);
-
- int iso_errno;
-
- #define VOL(vol,tag) (((t_iso_vol_info *)(vol->vol_info))->tag)
- #define OBJ(obj,tag) (((t_iso_obj_info *)(obj->obj_info))->tag)
-
- /* Check whether the given volume uses the ISO 9660 Protocol.
- * The protocol is identified by the sequence
- * 'C' 'D' '0' '0' '1'
- * in the 2nd..6th byte of sector 16 of a track.
- *
- * All data tracks on the disk are examined.
- *
- * Returns TRUE iff the ISO protocol is used; FALSE otherwise.
- */
-
- t_bool Uses_Iso_Protocol (CDROM *p_cdrom, t_ulong *p_offset)
- {
- int i, len;
- t_ulong *buf;
-
- /* If Data_Tracks() returns -1, then the drive probably doesn't support
- * the SCSI-2 READ TOC command.
- */
- if (p_cdrom->use_trackdisk ||
- (len = Data_Tracks (p_cdrom, &buf)) < 0) {
- *p_offset = 0;
- if (!Read_Sector (p_cdrom, 16))
- return FALSE;
- return strncmp ((char *) p_cdrom->buffer + 1, "CD001", 5) == 0;
- }
-
- if (len == 0)
- return FALSE;
-
- for (i=len-1; i>=0; i--) {
- *p_offset = buf[i];
- if (!Read_Sector (p_cdrom, 16 + *p_offset))
- continue;
- if (strncmp ((char *) p_cdrom->buffer + 1, "CD001", 5) == 0) {
- FreeVec (buf);
- return TRUE;
- }
- }
-
- FreeVec (buf);
- return FALSE;
- }
-
- /* Check whether the given volume uses the High Sierra Protocol.
- * The protocol is identified by the sequence
- * 'C' 'D' 'R' 'O' 'M'
- * in the 10th..14th byte of sector 16.
- *
- * Returns TRUE iff the High Sierra protocol is used; FALSE otherwise.
- */
-
- t_bool Uses_High_Sierra_Protocol (CDROM *p_cdrom)
- {
- if (!Read_Sector (p_cdrom, 16))
- return FALSE;
-
- return strncmp ((char *) p_cdrom->buffer + 9, "CDROM", 5) == 0;
- }
-
- t_bool Iso_Init_Vol_Info (VOLUME *p_volume, int p_skip, t_ulong p_offset)
- {
- long loc = 16 + p_offset;
- extern t_handler g_iso_handler, g_rr_handler;
-
- if (p_volume->protocol == PRO_ISO)
- p_volume->handler = &g_iso_handler;
- else
- p_volume->handler = &g_rr_handler;
-
- p_volume->vol_info = AllocMem (sizeof (t_iso_vol_info), MEMF_PUBLIC);
- if (!p_volume->vol_info) {
- iso_errno = ISOERR_NO_MEMORY;
- return FALSE;
- }
-
- for (;;) {
- if (!Read_Sector (p_volume->cd, loc)) {
- iso_errno = ISOERR_SCSI_ERROR;
- FreeMem (p_volume->vol_info, sizeof (t_iso_vol_info));
- return FALSE;
- }
-
- if (p_volume->cd->buffer[0] == 1) {
- memcpy (&VOL(p_volume,pvd), p_volume->cd->buffer, sizeof (prim_vol_desc));
- break;
- }
-
- if (p_volume->cd->buffer[0] == 255 || loc > 1000) {
- iso_errno = ISOERR_NO_PVD;
- FreeMem (p_volume->vol_info, sizeof (t_iso_vol_info));
- return FALSE;
- }
-
- loc++;
- }
-
- VOL(p_volume,skip) = p_skip;
-
- switch (VOL(p_volume,pvd).block_size_m) {
- case 512:
- VOL(p_volume,blockshift) = 2;
- break;
- case 1024:
- VOL(p_volume,blockshift) = 1;
- break;
- case 2048:
- default:
- VOL(p_volume,blockshift) = 0;
- break;
- }
-
- /* Look at the system ID to find out if the CD is supposed
- * to feature proper file names. These are CDs made for use
- * with the CDTV and the CD³² (both share the "CDTV" system ID)
- * and the "Fresh Fish", "Frozen Fish" and "Gold Fish" CDs
- * created by Mkisofs. If any of these IDs is found the
- * file name to lower case conversion is temporarily
- * disabled if the "ML=MAYBELOWERCASE" option has been selected.
- */
-
- if (p_volume->protocol == PRO_ROCK ||
- !strncmp(VOL(p_volume,pvd).system_id,"CDTV",4) ||
- !strncmp(VOL(p_volume,pvd).system_id,"AMIGA",5))
- p_volume->mixed_char_filenames = TRUE;
- else
- p_volume->mixed_char_filenames = FALSE;
-
- return TRUE;
- }
-
- void Iso_Close_Vol_Info (VOLUME *p_volume)
- {
- FreeMem (p_volume->vol_info, sizeof (t_iso_vol_info));
- }
-
- CDROM_OBJ *Iso_Alloc_Obj (int p_length_of_dir_record)
- {
- CDROM_OBJ *obj;
-
- obj = AllocMem (sizeof (CDROM_OBJ), MEMF_PUBLIC | MEMF_CLEAR);
- if (!obj) {
- iso_errno = ISOERR_NO_MEMORY;
- return NULL;
- }
-
- obj->obj_info = AllocMem (sizeof (t_iso_obj_info), MEMF_PUBLIC);
- if (!obj->obj_info) {
- FreeMem (obj, sizeof (CDROM_OBJ));
- return NULL;
- }
-
- OBJ(obj,dir) = AllocMem (p_length_of_dir_record, MEMF_PUBLIC);
- if (!OBJ(obj,dir)) {
- iso_errno = ISOERR_NO_MEMORY;
- FreeMem (obj->obj_info, sizeof (t_iso_obj_info));
- FreeMem (obj, sizeof (CDROM_OBJ));
- return NULL;
- }
-
- return obj;
- }
-
- /* Get the "CDROM object" for the root directory of the volume.
- */
-
- CDROM_OBJ *Iso_Open_Top_Level_Directory (VOLUME *p_volume)
- {
- CDROM_OBJ *obj;
-
- obj = Iso_Alloc_Obj (VOL(p_volume,pvd).root.length);
- if (!obj)
- return NULL;
-
- obj->directory_f = TRUE;
- obj->volume = p_volume;
- obj->pos = 0;
- memcpy (OBJ(obj,dir), &VOL(p_volume,pvd).root, VOL(p_volume,pvd).root.length);
-
- return obj;
- }
-
- /* Test on equality of directory names (ignoring case).
- */
-
- int Directory_Names_Equal (char *p_iso_name, int p_length, char *p_name)
- {
- return Strncasecmp (p_iso_name, p_name, p_length) == 0 &&
- p_name[p_length] == 0;
- }
-
- /* Compare the name of the directory entry p_iso_name (with length p_length)
- * with the C string p_name, and return 1 iff both strings are equal.
- * NOTE: p_iso_name may be a file name (with version number) or a directory
- * name (without version number).
- */
-
- int Names_Equal (char *p_iso_name, int p_length, char *p_name)
- {
- int pos;
-
- if (Strncasecmp (p_iso_name, p_name, p_length) == 0 &&
- p_name[p_length] == 0)
- return TRUE;
-
- /* compare without version number: */
-
- for (pos=p_length-1; pos>=0; pos--)
- if (p_iso_name[pos] == ';')
- break;
-
- if (pos>=0)
- return (Strncasecmp (p_iso_name, p_name, pos) == 0 &&
- p_name[pos] == 0);
- else
- return FALSE;
- }
-
- /* Get a record from a directory.
- * p_location is a LOGICAL BLOCK number.
- */
-
- directory_record *Get_Directory_Record (VOLUME *p_volume,
- unsigned long p_location,
- unsigned long p_offset)
- {
- static unsigned char result[256];
- int len;
- int loc;
-
- loc = (p_location >> VOL(p_volume,blockshift)) + (p_offset >> 11);
- if (!Read_Sector (p_volume->cd, loc)) {
- iso_errno = ISOERR_SCSI_ERROR;
- return NULL;
- }
-
- len = p_volume->cd->buffer[p_offset & 2047];
- if (len)
- memcpy (result, p_volume->cd->buffer + (p_offset & 2047), len);
- else
- result[0] = 0; /* mark as last record */
-
- return (directory_record *) result;
- }
-
- /* Create a "CDROM object" for the directory which is located
- * at sector p_location.
- */
-
- CDROM_OBJ *Iso_Create_Directory_Obj (VOLUME *p_volume, unsigned long p_location)
- {
- directory_record *dir;
- unsigned long loc;
- int offset = 0;
- CDROM_OBJ *obj;
- unsigned long len;
-
- if (p_location == VOL(p_volume,pvd).root.extent_loc_m)
- return Iso_Open_Top_Level_Directory (p_volume);
-
- dir = Get_Directory_Record (p_volume, p_location, 0);
- if (!dir)
- return NULL;
-
- dir = Get_Directory_Record (p_volume, p_location, dir->length);
- if (!dir)
- return NULL;
-
- loc = dir->extent_loc_m;
- len = dir->data_length_m;
- for (;;) {
- if (offset >= len)
- return NULL;
- dir = Get_Directory_Record (p_volume, loc, offset);
- if (!dir)
- return NULL;
- if (!dir->length) {
- /* go to next logical sector: */
- offset = (offset & 0xfffff800) + 2048;
- continue;
- }
- if (dir->extent_loc_m == p_location)
- break;
- offset += dir->length;
- }
-
- obj = Iso_Alloc_Obj (dir->length);
- if (!obj)
- return NULL;
-
- obj->directory_f = TRUE;
- obj->volume = p_volume;
- obj->pos = 0;
- memcpy (OBJ(obj,dir), dir, dir->length);
-
- return obj;
- }
-
-
- /* Open the object with name p_name in the directory p_dir.
- * p_name must not contain '/' or ':' characters.
- */
-
- CDROM_OBJ *Iso_Open_Obj_In_Directory (CDROM_OBJ *p_dir, char *p_name)
- {
- unsigned long loc = OBJ(p_dir,dir)->extent_loc_m + OBJ(p_dir,dir)->ext_attr_length;
- unsigned long len = OBJ(p_dir,dir)->data_length_m;
- directory_record *dir;
- int offset;
- CDROM_OBJ *obj;
- long cl;
-
- /* skip first two entries: */
-
- dir = Get_Directory_Record (p_dir->volume, loc, 0);
- if (!dir)
- return NULL;
-
- offset = dir->length;
- dir = Get_Directory_Record (p_dir->volume, loc, offset);
- if (!dir)
- return NULL;
-
- offset += dir->length;
- for (;;) {
- if (offset >= len) {
- iso_errno = ISOERR_NOT_FOUND;
- return NULL;
- }
- dir = Get_Directory_Record (p_dir->volume, loc, offset);
- if (!dir)
- return NULL;
- if (!dir->length) {
- /* go to next logical sector: */
- offset = (offset & 0xfffff800) + 2048;
- continue;
- }
- if (p_dir->volume->protocol == PRO_ROCK) {
- char buf[256];
- int len;
-
- if ((len = Get_RR_File_Name (p_dir->volume, dir, buf, sizeof (buf))) > 0 &&
- Strncasecmp (buf, p_name, len) == 0 &&
- p_name[len] == 0)
- break;
- }
-
- if (Names_Equal (dir->file_id, dir->file_id_length, p_name))
- break;
- offset += dir->length;
- }
-
- if (p_dir->volume->protocol == PRO_ROCK &&
- (cl = RR_Child_Link (p_dir->volume, dir)) >= 0)
- return Iso_Create_Directory_Obj (p_dir->volume, cl);
-
- obj = Iso_Alloc_Obj (dir->length);
- if (!obj)
- return NULL;
-
- obj->directory_f = (dir->flags & 2);
- if (p_dir->volume->protocol == PRO_ROCK &&
- Is_A_Symbolic_Link (p_dir->volume, dir)) {
- obj->symlink_f = 1;
- obj->directory_f = 0;
- }
- memcpy (OBJ(obj,dir), dir, dir->length);
- obj->volume = p_dir->volume;
- obj->pos = 0;
- if (!obj->directory_f)
- OBJ(obj,parent_loc) = loc;
-
- return obj;
- }
-
- /* Close a "CDROM object" and deallocate all associated resources.
- */
-
- void Iso_Close_Obj (CDROM_OBJ *p_object)
- {
- FreeMem (OBJ(p_object,dir), OBJ(p_object,dir)->length);
- FreeMem (p_object->obj_info, sizeof (t_iso_obj_info));
- FreeMem (p_object, sizeof (CDROM_OBJ));
- }
-
- /* Read bytes from a file.
- */
-
- int Iso_Read_From_File (CDROM_OBJ *p_file, char *p_buffer, int p_buffer_length)
- {
- unsigned long loc;
- int remain_block, remain_file, remain;
- int len;
- VOLUME *vol = p_file->volume;
- CDROM *cd = vol->cd;
- int buf_pos = 0;
- int todo;
- unsigned long last_loc, ext_loc;
- short blockshift;
- int offset;
- unsigned long firstblock;
-
- if (p_file->pos == OBJ(p_file,dir)->data_length_m)
- /* at end of file: */
- return 0;
-
- blockshift = VOL(vol,blockshift);
- /* 'firstblock' is the first logical block of the file section: */
- firstblock = OBJ(p_file,dir)->extent_loc_m + OBJ(p_file,dir)->ext_attr_length;
- /*
- * 'offset' is the offset of the first logical block of the file
- * extent from the first logical (2048-byte-)sector.
- */
- if (blockshift)
- offset = ((firstblock & ((1<<blockshift)-1))
- << (11-blockshift));
- else
- offset = 0;
- /*
- * 'ext_loc' is the first logical sector of the file extent.
- * 'loc' is the first logical sector to be read.
- * 'last_loc' is the last logical sector of the file extent.
- */
- ext_loc = firstblock >> blockshift;
- loc = ext_loc + ((p_file->pos + offset) >> 11);
- last_loc = ext_loc + ((OBJ(p_file,dir)->data_length_m + offset - 1) >> 11);
- todo = p_buffer_length;
-
- offset += p_file->pos;
- offset &= 2047;
- remain_block = 2048 - offset;
-
- while (todo) {
- if (!Read_Contiguous_Sectors (cd, loc, last_loc)) {
- iso_errno = ISOERR_SCSI_ERROR;
- return -1;
- }
-
- remain_file = OBJ(p_file,dir)->data_length_m - p_file->pos;
- /*
- * 'todo' is the number of bytes in p_buffer which haven't been filled yet.
- * 'remain' is remaining number of bytes in cd->buffer.
- */
- remain = (remain_block < remain_file) ? remain_block : remain_file;
- len = (todo < remain) ? todo : remain;
- CopyMem ((APTR) (cd->buffer + offset), (APTR) (p_buffer + buf_pos), len);
- buf_pos += len;
- p_file->pos += len;
- todo -= len;
-
- if (p_file->pos >= OBJ(p_file,dir)->data_length_m)
- break;
-
- remain_block = 2048;
- offset = 0;
-
- loc++;
- }
-
- return buf_pos;
- }
-
- t_ulong Extract_Date (directory_record *p_dir_record)
- {
- struct ClockData ClockData;
-
- ClockData.sec = p_dir_record->second;
- ClockData.min = p_dir_record->minute;
- ClockData.hour = p_dir_record->hour;
- ClockData.mday = p_dir_record->day;
- ClockData.wday = 0; /* is ignored by CheckDate() and Date2Amiga() */
- ClockData.month = p_dir_record->month;
- ClockData.year = p_dir_record->year + 1900;
-
- if (CheckDate (&ClockData))
- return Date2Amiga (&ClockData);
- else
- return 0;
- }
-
- /* Return information on a "CDROM object."
- */
-
- int Iso_CDROM_Info (CDROM_OBJ *p_obj, CDROM_INFO *p_info)
- {
- int len;
-
- if (Iso_Is_Top_Level_Object (p_obj)) {
- p_info->name_length = 1;
- p_info->name[0] = ':';
- p_info->directory_f = TRUE;
- p_info->file_length = 0;
- p_info->date = Volume_Creation_Date (p_obj->volume);
- } else {
- if (p_obj->volume->protocol == PRO_ROCK &&
- (len = Get_RR_File_Name (p_obj->volume, OBJ(p_obj,dir),
- p_info->name, sizeof (p_info->name))) > 0) {
- p_info->name_length = len;
- } else {
- p_info->name_length = OBJ(p_obj,dir)->file_id_length;
- memcpy (p_info->name, OBJ(p_obj,dir)->file_id, p_info->name_length);
- }
- p_info->directory_f = p_obj->directory_f;
- p_info->symlink_f = p_obj->symlink_f;
- p_info->file_length = OBJ(p_obj,dir)->data_length_m;
- p_info->date = Extract_Date (OBJ(p_obj,dir));
- }
-
- return 1;
- }
-
- /* Browse all entries in a directory.
- */
-
- int Iso_Examine_Next (CDROM_OBJ *p_dir, CDROM_INFO *p_info,
- unsigned long *p_offset)
- {
- unsigned long offset;
- directory_record *rec;
- int len;
-
- if (!p_dir->directory_f || p_dir->symlink_f) {
- iso_errno = ISOERR_BAD_ARGUMENTS;
- return 0;
- }
-
- if (*p_offset == 0) {
- /* skip first two directory entries: */
-
- rec = Get_Directory_Record
- (p_dir->volume,
- OBJ(p_dir,dir)->extent_loc_m + OBJ(p_dir,dir)->ext_attr_length,
- 0);
- if (!rec)
- return 0;
-
- offset = rec->length;
-
- rec = Get_Directory_Record
- (p_dir->volume,
- OBJ(p_dir,dir)->extent_loc_m + OBJ(p_dir,dir)->ext_attr_length,
- offset);
- if (!rec)
- return 0;
-
- *p_offset = offset + rec->length;
- }
-
- for (;;) {
- if (OBJ(p_dir,dir)->data_length_m <= *p_offset)
- return 0;
-
- rec = Get_Directory_Record
- (p_dir->volume,
- OBJ(p_dir,dir)->extent_loc_m + OBJ(p_dir,dir)->ext_attr_length,
- *p_offset);
- if (!rec)
- return 0;
-
- if (rec->length == 0)
- /* go to next logical sector: */
- *p_offset = (*p_offset & 0xfffff800) + 2048;
- else
- break;
- }
-
- *p_offset += rec->length;
-
- if (p_dir->volume->protocol == PRO_ROCK &&
- (len = Get_RR_File_Name (p_dir->volume, rec,
- p_info->name, sizeof (p_info->name))) > 0) {
- p_info->name_length = len;
- } else {
- p_info->name_length = rec->file_id_length;
- memcpy (p_info->name, rec->file_id, rec->file_id_length);
- }
- if (p_dir->volume->protocol == PRO_ROCK &&
- Is_A_Symbolic_Link (p_dir->volume, rec)) {
- p_info->symlink_f = 1;
- p_info->directory_f = 0;
- } else if (p_dir->volume->protocol == PRO_ROCK &&
- Has_System_Use_Field (p_dir->volume, rec, "CL")) {
- p_info->symlink_f = 0;
- p_info->directory_f = 1;
- } else {
- p_info->symlink_f = 0;
- p_info->directory_f = rec->flags & 2;
- }
- p_info->file_length = rec->data_length_m;
- p_info->date = Extract_Date (rec);
- p_info->suppl_info = rec;
-
- return 1;
- }
-
- /* Clone a "CDROM object info."
- */
-
- void *Iso_Clone_Obj_Info (void *p_info)
- {
- t_iso_obj_info *info = (t_iso_obj_info *) p_info;
- t_iso_obj_info *new;
-
- new = AllocMem (sizeof (t_iso_obj_info), MEMF_PUBLIC);
- if (!new)
- return NULL;
-
- memcpy (new, info, sizeof (t_iso_obj_info));
-
- new->dir = AllocMem (info->dir->length, MEMF_PUBLIC);
- if (!new->dir) {
- FreeMem (new, sizeof (t_iso_obj_info));
- return NULL;
- }
- memcpy (new->dir, info->dir, info->dir->length);
-
- return new;
- }
-
- /* Find parent directory.
- */
-
- CDROM_OBJ *Iso_Find_Parent (CDROM_OBJ *p_object)
- {
- directory_record *dir;
- unsigned long dir_loc;
- long pl;
-
- if (p_object->directory_f)
- dir_loc = OBJ(p_object,dir)->extent_loc_m + OBJ(p_object,dir)->ext_attr_length;
- else
- dir_loc = OBJ(p_object,parent_loc);
-
- dir = Get_Directory_Record (p_object->volume, dir_loc, 0);
- if (!dir)
- return NULL;
-
- if (p_object->directory_f) {
- dir = Get_Directory_Record (p_object->volume, dir_loc, dir->length);
- if (!dir)
- return NULL;
- if (p_object->volume->protocol == PRO_ROCK &&
- (pl = RR_Parent_Link (p_object->volume, dir)) >= 0)
- return Iso_Create_Directory_Obj (p_object->volume, pl);
- }
-
- return Iso_Create_Directory_Obj (p_object->volume, dir->extent_loc_m);
- }
-
- /* Test if p_object is the root directory.
- */
-
- t_bool Iso_Is_Top_Level_Object (CDROM_OBJ *p_object)
- {
- return p_object->directory_f &&
- OBJ(p_object,dir)->extent_loc_m ==
- VOL(p_object->volume,pvd).root.extent_loc_m;
- }
-
- /* Test if two objects are equal.
- */
-
- t_bool Iso_Same_Objects (CDROM_OBJ *p_obj1, CDROM_OBJ *p_obj2)
- {
- return (OBJ(p_obj1,dir)->extent_loc_m ==
- OBJ(p_obj2,dir)->extent_loc_m);
- }
-
- /*
- * Convert p_num digits into an integer value:
- */
-
- int Digs_To_Int (char *p_digits, int p_num)
- {
- int result = 0;
- int i;
-
- for (i=0; i<p_num; i++)
- result = result * 10 + p_digits[i] - '0';
-
- return result;
- }
-
- /*
- * Return volume creation date as number of seconds since 1-Jan-1978:
- */
-
- t_ulong Iso_Creation_Date (VOLUME *p_volume)
- {
- struct ClockData ClockData;
- char *dt = VOL(p_volume,pvd).vol_creation;
-
- ClockData.sec = Digs_To_Int (dt+12, 2);
- ClockData.min = Digs_To_Int (dt+10, 2);
- ClockData.hour = Digs_To_Int (dt+8, 2);
- ClockData.mday = Digs_To_Int (dt+6, 2);
- ClockData.wday = 0; /* is ignored by CheckDate() and Date2Amiga() */
- ClockData.month = Digs_To_Int (dt+4, 2);
- ClockData.year = Digs_To_Int (dt, 4);
-
- if (CheckDate (&ClockData))
- return Date2Amiga (&ClockData);
- else
- return 0;
- }
-
- t_ulong Iso_Volume_Size (VOLUME *p_volume)
- {
- return VOL(p_volume,pvd).space_size_m;
- }
-
- t_ulong Iso_Block_Size (VOLUME *p_volume)
- {
- return VOL(p_volume,pvd).block_size_m;
- }
-
- void Iso_Volume_ID (VOLUME *p_volume, char *p_buffer, int p_buf_length)
- {
- char *iso_name = VOL(p_volume,pvd).volume_id;
- int iso_len;
- int len;
-
- for (iso_len = 30; iso_len; iso_len--) {
- if (iso_name[iso_len-1] != ' ')
- break;
- }
-
- len = (iso_len > p_buf_length-1) ? p_buf_length-1 : iso_len;
- if (len > 0)
- memcpy (p_buffer, iso_name, len);
- p_buffer[len] = 0;
- }
-
- t_ulong Iso_Location (CDROM_OBJ *p_object)
- {
- return OBJ(p_object,dir)->extent_loc_m;
- }
-
- t_ulong Iso_File_Length (CDROM_OBJ *p_obj)
- {
- return OBJ(p_obj,dir)->data_length_m;
- }
-
- t_handler g_iso_handler = {
- Iso_Close_Vol_Info,
- Iso_Open_Top_Level_Directory,
- Iso_Open_Obj_In_Directory,
- Iso_Find_Parent,
- Iso_Close_Obj,
- Iso_Read_From_File,
- Iso_CDROM_Info,
- Iso_Examine_Next,
- Iso_Clone_Obj_Info,
- Iso_Is_Top_Level_Object,
- Iso_Same_Objects,
- Iso_Creation_Date,
- Iso_Volume_Size,
- Iso_Volume_ID,
- Iso_Location,
- Iso_File_Length,
- Iso_Block_Size
- };
-
- t_handler g_rr_handler = {
- Iso_Close_Vol_Info,
- Iso_Open_Top_Level_Directory,
- Iso_Open_Obj_In_Directory,
- Iso_Find_Parent,
- Iso_Close_Obj,
- Iso_Read_From_File,
- Iso_CDROM_Info,
- Iso_Examine_Next,
- Iso_Clone_Obj_Info,
- Iso_Is_Top_Level_Object,
- Iso_Same_Objects,
- Iso_Creation_Date,
- Iso_Volume_Size,
- Iso_Volume_ID,
- Iso_Location,
- Iso_File_Length,
- Iso_Block_Size
- };
-
-