From 491777a66804c7a2ffbd5ec122c1084e18a5f0d2 Mon Sep 17 00:00:00 2001 From: rocky Date: Sun, 7 Sep 2003 18:15:26 +0000 Subject: [PATCH] add parameters to set times on directory entries, pvd's. --- include/cdio/iso9660.h | 33 ++++++++++++--- lib/iso9660.c | 96 ++++++++++++++++++++++++++---------------- lib/iso9660_fs.c | 79 +++++++++++++++++----------------- 3 files changed, 125 insertions(+), 83 deletions(-) diff --git a/include/cdio/iso9660.h b/include/cdio/iso9660.h index 45063cb9..28b1bf9a 100644 --- a/include/cdio/iso9660.h +++ b/include/cdio/iso9660.h @@ -1,5 +1,5 @@ /* - $Id: iso9660.h,v 1.18 2003/09/06 14:50:50 rocky Exp $ + $Id: iso9660.h,v 1.19 2003/09/07 18:15:26 rocky Exp $ Copyright (C) 2000 Herbert Valerio Riedel Copyright (C) 2003 Rocky Bernstein @@ -35,6 +35,8 @@ #include #include +#include + #define MIN_TRACK_SIZE 4*75 #define MIN_ISO_SIZE MIN_TRACK_SIZE @@ -127,6 +129,7 @@ struct iso9660_pvd { typedef struct iso9660_dir iso9660_dir_t; typedef struct iso9660_pvd iso9660_pvd_t; +typedef struct iso9660_stat iso9660_stat_t; #ifndef EMPTY_ARRAY_SIZE #define EMPTY_ARRAY_SIZE 0 @@ -156,13 +159,14 @@ struct iso9660_dir { char name[EMPTY_ARRAY_SIZE]; } GNUC_PACKED; -typedef struct iso9660_stat { /* big endian!! */ +struct iso9660_stat { /* big endian!! */ enum { _STAT_FILE = 1, _STAT_DIR = 2 } type; lsn_t lsn; /* start logical sector number */ uint32_t size; /* total size in bytes */ uint32_t secsize; /* number of sectors allocated */ iso9660_xa_t xa; /* XA attributes */ -} iso9660_stat_t; + struct tm tm; /* time on entry */ +} ; PRAGMA_END_PACKED @@ -208,6 +212,19 @@ int iso9660_name_translate(const char *old, char *new); char *iso9660_strncpy_pad(char dst[], const char src[], size_t len, enum strncpy_pad_check _check); +/*! + Set time in format used in ISO 9660 directory index record + from a Unix time structure. */ +void iso9660_set_time (const struct tm *tm, /*out*/ uint8_t idr_date[]); + + +/* Get time structure from structure in an ISO 9660 directory index + record. +*/ +/* FIXME? What do we do about the other fields.*/ +void iso9660_get_time (const uint8_t idr_date[], /*out*/ struct tm *tm); + + /*===================================================================== file/dirname's ======================================================================*/ @@ -251,18 +268,20 @@ bool iso9660_pathname_valid_p (const char pathname[]); void iso9660_dir_init_new (void *dir, uint32_t self, uint32_t ssize, - uint32_t parent, uint32_t psize); + uint32_t parent, uint32_t psize, + const time_t *dir_time); void iso9660_dir_init_new_su (void *dir, uint32_t self, uint32_t ssize, const void *ssu_data, unsigned int ssu_size, uint32_t parent, uint32_t psize, - const void *psu_data, unsigned int psu_size); + const void *psu_data, unsigned int psu_size, + const time_t *dir_time); void iso9660_dir_add_entry_su (void *dir, const char name[], uint32_t extent, uint32_t size, uint8_t flags, const void *su_data, - unsigned int su_size); + unsigned int su_size, const time_t *entry_time); unsigned int iso9660_dir_calc_record_size (unsigned int namelen, unsigned int su_len); @@ -338,7 +357,7 @@ iso9660_set_pvd (void *pd, const char volume_id[], const char application_id[], const char publisher_id[], const char preparer_id[], uint32_t iso_size, const void *root_dir, uint32_t path_table_l_extent, uint32_t path_table_m_extent, - uint32_t path_table_size); + uint32_t path_table_size, const time_t *pvd_time); void iso9660_set_evd (void *pd); diff --git a/lib/iso9660.c b/lib/iso9660.c index e30d42a1..4eef7e49 100644 --- a/lib/iso9660.c +++ b/lib/iso9660.c @@ -1,5 +1,5 @@ /* - $Id: iso9660.c,v 1.8 2003/09/06 14:50:50 rocky Exp $ + $Id: iso9660.c,v 1.9 2003/09/07 18:15:26 rocky Exp $ Copyright (C) 2000 Herbert Valerio Riedel Copyright (C) 2003 Rocky Bernstein @@ -37,7 +37,7 @@ #include #endif -static const char _rcsid[] = "$Id: iso9660.c,v 1.8 2003/09/06 14:50:50 rocky Exp $"; +static const char _rcsid[] = "$Id: iso9660.c,v 1.9 2003/09/07 18:15:26 rocky Exp $"; /* some parameters... */ #define SYSTEM_ID "CD-RTOS CD-BRIDGE" @@ -47,21 +47,42 @@ static void pathtable_get_size_and_entries(const void *pt, unsigned int *size, unsigned int *entries); -static void -_idr_set_time (uint8_t _idr_date[], const struct tm *_tm) +/* Get time structure from structure in an ISO 9660 directory index + record. +*/ +/* FIXME? What do we do about the other fields.*/ +void +iso9660_get_time (const uint8_t idr_date[], /*out*/ struct tm *tm) { - memset (_idr_date, 0, 7); + if (!idr_date) return; - if (!_tm) - return; + tm->tm_year = idr_date[0]; + tm->tm_mon = idr_date[1] - 1; + tm->tm_mday = idr_date[2]; + tm->tm_hour = idr_date[3]; + tm->tm_min = idr_date[4]; + tm->tm_sec = idr_date[5]; + /* Recompute tm_wday and tm_yday */ + mktime(tm); +} - _idr_date[0] = _tm->tm_year; - _idr_date[1] = _tm->tm_mon + 1; - _idr_date[2] = _tm->tm_mday; - _idr_date[3] = _tm->tm_hour; - _idr_date[4] = _tm->tm_min; - _idr_date[5] = _tm->tm_sec; - _idr_date[6] = 0x00; /* tz, GMT -48 +52 in 15min intervals */ +/*! + Set time in format used in ISO 9660 directory index record + from a Unix time structure. */ +void +iso9660_set_time (const struct tm *tm, /*out*/ uint8_t idr_date[]) +{ + memset (idr_date, 0, 7); + + if (!tm) return; + + idr_date[0] = tm->tm_year; + idr_date[1] = tm->tm_mon + 1; + idr_date[2] = tm->tm_mday; + idr_date[3] = tm->tm_hour; + idr_date[4] = tm->tm_min; + idr_date[5] = tm->tm_sec; + idr_date[6] = 0x00; /* tz, GMT -48 +52 in 15min intervals */ } static void @@ -248,21 +269,19 @@ iso9660_set_evd(void *pd) memcpy(pd, &ied, sizeof(ied)); } -/* important date to celebrate (for me at least =) - -- until user customization is implemented... */ -static const time_t _vcd_time = 269222400L; - void iso9660_set_pvd(void *pd, - const char volume_id[], - const char publisher_id[], - const char preparer_id[], - const char application_id[], - uint32_t iso_size, - const void *root_dir, - uint32_t path_table_l_extent, - uint32_t path_table_m_extent, - uint32_t path_table_size) + const char volume_id[], + const char publisher_id[], + const char preparer_id[], + const char application_id[], + uint32_t iso_size, + const void *root_dir, + uint32_t path_table_l_extent, + uint32_t path_table_m_extent, + uint32_t path_table_size, + const time_t *pvd_time + ) { iso9660_pvd_t ipd; @@ -308,8 +327,8 @@ iso9660_set_pvd(void *pd, iso9660_strncpy_pad (ipd.abstract_file_id , "", 37, ISO9660_DCHARS); iso9660_strncpy_pad (ipd.bibliographic_file_id, "", 37, ISO9660_DCHARS); - _pvd_set_time (ipd.creation_date, gmtime (&_vcd_time)); - _pvd_set_time (ipd.modification_date, gmtime (&_vcd_time)); + _pvd_set_time (ipd.creation_date, gmtime (pvd_time)); + _pvd_set_time (ipd.modification_date, gmtime (pvd_time)); _pvd_set_time (ipd.expiration_date, NULL); _pvd_set_time (ipd.effective_date, NULL); @@ -343,14 +362,14 @@ iso9660_dir_add_entry_su(void *dir, uint32_t size, uint8_t flags, const void *su_data, - unsigned int su_size) + unsigned int su_size, + const time_t *entry_time) { iso9660_dir_t *idr = dir; uint8_t *dir8 = dir; unsigned int offset = 0; uint32_t dsize = from_733(idr->size); int length, su_offset; - cdio_assert (sizeof(iso9660_dir_t) == 33); if (!dsize && !idr->length) @@ -407,7 +426,7 @@ iso9660_dir_add_entry_su(void *dir, idr->extent = to_733(extent); idr->size = to_733(size); - _idr_set_time (idr->date, gmtime (&_vcd_time)); + iso9660_set_time (gmtime(entry_time), idr->date); idr->flags = to_711(flags); @@ -424,9 +443,11 @@ iso9660_dir_init_new (void *dir, uint32_t self, uint32_t ssize, uint32_t parent, - uint32_t psize) + uint32_t psize, + const time_t *dir_time) { - iso9660_dir_init_new_su (dir, self, ssize, NULL, 0, parent, psize, NULL, 0); + iso9660_dir_init_new_su (dir, self, ssize, NULL, 0, parent, psize, NULL, + 0, dir_time); } void @@ -438,7 +459,8 @@ iso9660_dir_init_new_su (void *dir, uint32_t parent, uint32_t psize, const void *psu_data, - unsigned int psu_size) + unsigned int psu_size, + const time_t *dir_time) { cdio_assert (ssize > 0 && !(ssize % ISO_BLOCKSIZE)); cdio_assert (psize > 0 && !(psize % ISO_BLOCKSIZE)); @@ -448,10 +470,10 @@ iso9660_dir_init_new_su (void *dir, /* "\0" -- working hack due to padding */ iso9660_dir_add_entry_su (dir, "\0", self, ssize, ISO_DIRECTORY, ssu_data, - ssu_size); + ssu_size, dir_time); iso9660_dir_add_entry_su (dir, "\1", parent, psize, ISO_DIRECTORY, psu_data, - psu_size); + psu_size, dir_time); } void diff --git a/lib/iso9660_fs.c b/lib/iso9660_fs.c index 2cdc9e0a..936ecc54 100644 --- a/lib/iso9660_fs.c +++ b/lib/iso9660_fs.c @@ -1,5 +1,5 @@ /* - $Id: iso9660_fs.c,v 1.7 2003/09/06 14:50:50 rocky Exp $ + $Id: iso9660_fs.c,v 1.8 2003/09/07 18:15:26 rocky Exp $ Copyright (C) 2001 Herbert Valerio Riedel Copyright (C) 2003 Rocky Bernstein @@ -38,22 +38,24 @@ #include -static const char _rcsid[] = "$Id: iso9660_fs.c,v 1.7 2003/09/06 14:50:50 rocky Exp $"; +static const char _rcsid[] = "$Id: iso9660_fs.c,v 1.8 2003/09/07 18:15:26 rocky Exp $"; static void -_idr2statbuf (const iso9660_dir_t *idr, iso9660_stat_t *buf, bool is_mode2) +_idr2statbuf (const iso9660_dir_t *idr, iso9660_stat_t *stat, bool is_mode2) { iso9660_xa_t *xa_data = NULL; uint8_t dir_len= iso9660_get_dir_len(idr); - memset ((void *) buf, 0, sizeof (iso9660_stat_t)); + memset ((void *) stat, 0, sizeof (iso9660_stat_t)); if (!dir_len) return; - buf->type = (idr->flags & ISO_DIRECTORY) ? _STAT_DIR : _STAT_FILE; - buf->lsn = from_733 (idr->extent); - buf->size = from_733 (idr->size); - buf->secsize = _cdio_len2blocks (buf->size, ISO_BLOCKSIZE); + stat->type = (idr->flags & ISO_DIRECTORY) ? _STAT_DIR : _STAT_FILE; + stat->lsn = from_733 (idr->extent); + stat->size = from_733 (idr->size); + stat->secsize = _cdio_len2blocks (stat->size, ISO_BLOCKSIZE); + + iso9660_get_time(idr->date, &(stat->tm)); cdio_assert (dir_len >= sizeof (iso9660_dir_t)); @@ -81,7 +83,7 @@ _idr2statbuf (const iso9660_dir_t *idr, iso9660_stat_t *buf, bool is_mode2) xa_data->signature[0], xa_data->signature[1]); return; } - buf->xa = *xa_data; + stat->xa = *xa_data; } } @@ -110,7 +112,7 @@ _idr2name (const iso9660_dir_t *idr) static void -_fs_stat_root (const CdIo *cdio, iso9660_stat_t *buf, bool is_mode2) +_fs_stat_root (const CdIo *cdio, iso9660_stat_t *stat, bool is_mode2) { char block[ISO_BLOCKSIZE] = { 0, }; const iso9660_pvd_t *pvd = (void *) █ @@ -124,12 +126,13 @@ _fs_stat_root (const CdIo *cdio, iso9660_stat_t *buf, bool is_mode2) cdio_assert_not_reached (); } - _idr2statbuf (idr, buf, is_mode2); + _idr2statbuf (idr, stat, is_mode2); } static int _fs_stat_traverse (const CdIo *cdio, const iso9660_stat_t *_root, - char **splitpath, iso9660_stat_t *buf, bool is_mode2) + char **splitpath, /*out*/ iso9660_stat_t *buf, + bool is_mode2) { unsigned offset = 0; uint8_t *_dirbuf = NULL; @@ -165,11 +168,9 @@ _fs_stat_traverse (const CdIo *cdio, const iso9660_stat_t *_root, while (offset < (_root->secsize * ISO_BLOCKSIZE)) { - const iso9660_dir_t *idr - = (void *) &_dirbuf[offset]; - iso9660_stat_t _stat; - - char *_name; + const iso9660_dir_t *idr = (void *) &_dirbuf[offset]; + iso9660_stat_t stat; + char *name; if (!iso9660_get_dir_len(idr)) { @@ -177,19 +178,19 @@ _fs_stat_traverse (const CdIo *cdio, const iso9660_stat_t *_root, continue; } - _name = _idr2name (idr); - _idr2statbuf (idr, &_stat, is_mode2); + name = _idr2name (idr); + _idr2statbuf (idr, &stat, is_mode2); - if (!strcmp (splitpath[0], _name)) + if (!strcmp (splitpath[0], name)) { - int retval = _fs_stat_traverse (cdio, &_stat, &splitpath[1], buf, + int retval = _fs_stat_traverse (cdio, &stat, &splitpath[1], buf, is_mode2); - free (_name); + free (name); free (_dirbuf); return retval; } - free (_name); + free (name); offset += iso9660_get_dir_len(idr); } @@ -229,15 +230,15 @@ iso9660_fs_stat (const CdIo *cdio, const char pathname[], void * /* list of char* -- caller must free it */ iso9660_fs_readdir (const CdIo *cdio, const char pathname[], bool is_mode2) { - iso9660_stat_t _stat; + iso9660_stat_t stat; cdio_assert (cdio != NULL); cdio_assert (pathname != NULL); - if (iso9660_fs_stat (cdio, pathname, &_stat, is_mode2)) + if (iso9660_fs_stat (cdio, pathname, &stat, is_mode2)) return NULL; - if (_stat.type != _STAT_DIR) + if (stat.type != _STAT_DIR) return NULL; { @@ -245,25 +246,25 @@ iso9660_fs_readdir (const CdIo *cdio, const char pathname[], bool is_mode2) uint8_t *_dirbuf = NULL; CdioList *retval = _cdio_list_new (); - if (_stat.size != ISO_BLOCKSIZE * _stat.secsize) + if (stat.size != ISO_BLOCKSIZE * stat.secsize) { cdio_warn ("bad size for ISO9660 directory (%ud) should be (%d)!", - (unsigned) _stat.size, ISO_BLOCKSIZE * _stat.secsize); + (unsigned) stat.size, ISO_BLOCKSIZE * stat.secsize); } - _dirbuf = _cdio_malloc (_stat.secsize * ISO_BLOCKSIZE); + _dirbuf = _cdio_malloc (stat.secsize * ISO_BLOCKSIZE); if (is_mode2) { - if (cdio_read_mode2_sectors (cdio, _dirbuf, _stat.lsn, false, - _stat.secsize)) + if (cdio_read_mode2_sectors (cdio, _dirbuf, stat.lsn, false, + stat.secsize)) cdio_assert_not_reached (); } else { - if (cdio_read_mode1_sectors (cdio, _dirbuf, _stat.lsn, false, - _stat.secsize)) + if (cdio_read_mode1_sectors (cdio, _dirbuf, stat.lsn, false, + stat.secsize)) cdio_assert_not_reached (); } - while (offset < (_stat.secsize * ISO_BLOCKSIZE)) + while (offset < (stat.secsize * ISO_BLOCKSIZE)) { const iso9660_dir_t *idr = (void *) &_dirbuf[offset]; @@ -278,7 +279,7 @@ iso9660_fs_readdir (const CdIo *cdio, const char pathname[], bool is_mode2) offset += iso9660_get_dir_len(idr); } - cdio_assert (offset == (_stat.secsize * ISO_BLOCKSIZE)); + cdio_assert (offset == (stat.secsize * ISO_BLOCKSIZE)); free (_dirbuf); return retval; @@ -299,10 +300,10 @@ find_fs_lsn_recurse (const CdIo *cdio, const char pathname[], _CDIO_LIST_FOREACH (entnode, entlist) { - char *_name = _cdio_list_node_data (entnode); + char *name = _cdio_list_node_data (entnode); char _fullname[4096] = { 0, }; - snprintf (_fullname, sizeof (_fullname), "%s%s", pathname, _name); + snprintf (_fullname, sizeof (_fullname), "%s%s", pathname, name); if (iso9660_fs_stat (cdio, _fullname, statbuf, true)) cdio_assert_not_reached (); @@ -310,8 +311,8 @@ find_fs_lsn_recurse (const CdIo *cdio, const char pathname[], strncat (_fullname, "/", sizeof (_fullname)); if (statbuf->type == _STAT_DIR - && strcmp (_name, ".") - && strcmp (_name, "..")) + && strcmp (name, ".") + && strcmp (name, "..")) _cdio_list_append (dirlist, strdup (_fullname)); if (statbuf->lsn == lsn) {