diff --git a/include/cdio/iso9660.h b/include/cdio/iso9660.h index e93bc188..bb300bb9 100644 --- a/include/cdio/iso9660.h +++ b/include/cdio/iso9660.h @@ -1,5 +1,5 @@ /* - $Id: iso9660.h,v 1.66 2005/02/14 02:18:58 rocky Exp $ + $Id: iso9660.h,v 1.67 2005/02/14 07:49:46 rocky Exp $ Copyright (C) 2000 Herbert Valerio Riedel Copyright (C) 2003, 2004, 2005 Rocky Bernstein @@ -526,7 +526,7 @@ typedef uint32_t posix_gid_t; @see iso9660_dir */ struct iso9660_stat_s { /* big endian!! */ - bool b_rock; /**< has Rock Ridge extension. + bool_3way_t b_rock; /**< has Rock Ridge extension. If not true then the next 9 fields aren't used. */ diff --git a/lib/iso9660/iso9660_fs.c b/lib/iso9660/iso9660_fs.c index 5741940a..78d5c325 100644 --- a/lib/iso9660/iso9660_fs.c +++ b/lib/iso9660/iso9660_fs.c @@ -1,5 +1,5 @@ /* - $Id: iso9660_fs.c,v 1.13 2005/02/13 22:03:00 rocky Exp $ + $Id: iso9660_fs.c,v 1.14 2005/02/14 07:49:46 rocky Exp $ Copyright (C) 2001 Herbert Valerio Riedel Copyright (C) 2003, 2004, 2005 Rocky Bernstein @@ -52,7 +52,7 @@ #include -static const char _rcsid[] = "$Id: iso9660_fs.c,v 1.13 2005/02/13 22:03:00 rocky Exp $"; +static const char _rcsid[] = "$Id: iso9660_fs.c,v 1.14 2005/02/14 07:49:46 rocky Exp $"; /* Implementation of iso9660_t type */ struct _iso9660_s { @@ -833,7 +833,7 @@ _iso9660_dir_to_statbuf (iso9660_dir_t *p_iso9660_dir, bool b_mode2, uint8_t dir_len= iso9660_get_dir_len(p_iso9660_dir); unsigned int filename_len; unsigned int stat_len; - iso9660_stat_t *stat; + iso9660_stat_t *p_stat; if (!dir_len) return NULL; @@ -842,37 +842,45 @@ _iso9660_dir_to_statbuf (iso9660_dir_t *p_iso9660_dir, bool b_mode2, /* .. string in statbuf is one longer than in p_iso9660_dir's listing '\1' */ stat_len = sizeof(iso9660_stat_t)+filename_len+2; - stat = calloc(1, stat_len); - stat->type = (p_iso9660_dir->file_flags & ISO_DIRECTORY) + p_stat = calloc(1, stat_len); + p_stat->type = (p_iso9660_dir->file_flags & ISO_DIRECTORY) ? _STAT_DIR : _STAT_FILE; - stat->lsn = from_733 (p_iso9660_dir->extent); - stat->size = from_733 (p_iso9660_dir->size); - stat->secsize = _cdio_len2blocks (stat->size, ISO_BLOCKSIZE); + p_stat->lsn = from_733 (p_iso9660_dir->extent); + p_stat->size = from_733 (p_iso9660_dir->size); + p_stat->secsize = _cdio_len2blocks (p_stat->size, ISO_BLOCKSIZE); + p_stat->b_rock = dunno; /*FIXME should do based on mask */ if ('\0' == p_iso9660_dir->filename[0] && 1 == filename_len) - strcpy (stat->filename, "."); + strcpy (p_stat->filename, "."); else if ('\1' == p_iso9660_dir->filename[0] && 1 == filename_len) - strcpy (stat->filename, ".."); + strcpy (p_stat->filename, ".."); else { + char rr_fname[256]; + int i_rr_fname_len = + get_rock_ridge_filename(p_iso9660_dir, rr_fname, p_stat); + if (i_rr_fname_len > 0) { + strncpy(p_stat->filename, rr_fname, i_rr_fname_len+1); + } else { #ifdef HAVE_JOLIET - if (i_joliet_level) { - int i_inlen = filename_len; - int i_outlen = (i_inlen / 2); - char *p_psz_out = NULL; - ucs2be_to_locale(p_iso9660_dir->filename, i_inlen, - &p_psz_out, i_outlen); - strncpy(stat->filename, p_psz_out, filename_len); - free(p_psz_out); - } else + if (i_joliet_level && i_rr_fname_len > 0) { + int i_inlen = filename_len; + int i_outlen = (i_inlen / 2); + char *p_psz_out = NULL; + ucs2be_to_locale(p_iso9660_dir->filename, i_inlen, + &p_psz_out, i_outlen); + strncpy(p_stat->filename, p_psz_out, filename_len); + free(p_psz_out); + } else #endif /*HAVE_JOLIET*/ - strncpy (stat->filename, p_iso9660_dir->filename, filename_len); + strncpy (p_stat->filename, p_iso9660_dir->filename, filename_len); + } } - iso9660_get_dtime(&(p_iso9660_dir->recording_time), true, &(stat->tm)); + iso9660_get_dtime(&(p_iso9660_dir->recording_time), true, &(p_stat->tm)); if (dir_len < sizeof (iso9660_dir_t)) { - free(stat); + free(p_stat); return NULL; } @@ -886,10 +894,10 @@ _iso9660_dir_to_statbuf (iso9660_dir_t *p_iso9660_dir, bool b_mode2, su_length--; if (su_length < 0 || su_length < sizeof (iso9660_xa_t)) - return stat; + return p_stat; if (nope == b_xa) { - return stat; + return p_stat; } else { iso9660_xa_t *xa_data = (void *) (((char *) p_iso9660_dir) @@ -909,12 +917,12 @@ _iso9660_dir_to_statbuf (iso9660_dir_t *p_iso9660_dir, bool b_mode2, su_length, xa_data->signature[0], xa_data->signature[1], xa_data->signature[0], xa_data->signature[1]); - return stat; + return p_stat; } - stat->xa = *xa_data; + p_stat->xa = *xa_data; } } - return stat; + return p_stat; } diff --git a/lib/iso9660/rock.c b/lib/iso9660/rock.c index 9fa97772..8c3c59f8 100644 --- a/lib/iso9660/rock.c +++ b/lib/iso9660/rock.c @@ -1,5 +1,5 @@ /* - $Id: rock.c,v 1.2 2005/02/14 02:18:58 rocky Exp $ + $Id: rock.c,v 1.3 2005/02/14 07:49:46 rocky Exp $ Copyright (C) 2005 Rocky Bernstein Adapted from GNU/Linux fs/isofs/rock.c (C) 1992, 1993 Eric Youngdale @@ -80,18 +80,22 @@ } \ } -/*! return length of name field; 0: not found, -1: to be ignored */ +/*! + Get + @return length of name field; 0: not found, -1: to be ignored +*/ int -get_rock_ridge_filename(iso9660_dir_t * de, /*out*/ char * retname, - /*out*/ iso9660_stat_t *p_stat) +get_rock_ridge_filename(iso9660_dir_t * de, /*out*/ char * psz_name, + iso9660_stat_t *p_stat) { int len; unsigned char *chr; CONTINUE_DECLS; - int retnamlen = 0, truncate=0; + int retnamlen = 0; + int truncate=0; - if (!p_stat || !p_stat->b_rock) return 0; - *retname = 0; + if (!p_stat || nope == p_stat->b_rock) return 0; + *psz_name = 0; SETUP_ROCK_RIDGE(de, chr, len); /* repeat:*/ @@ -102,7 +106,7 @@ get_rock_ridge_filename(iso9660_dir_t * de, /*out*/ char * retname, while (len > 1){ /* There may be one byte for padding somewhere */ rr = (iso_extension_record_t *) chr; if (rr->len == 0) goto out; /* Something got screwed up here */ - sig = from_721(*chr); + sig = *chr+(*(chr+1) << 8); chr += rr->len; len -= rr->len; @@ -114,6 +118,7 @@ get_rock_ridge_filename(iso9660_dir_t * de, /*out*/ char * retname, CHECK_CE; break; case SIG('N','M'): + p_stat->b_rock = yep; if (truncate) break; /* * If the flags are 2 or 4, this indicates '.' or '..'. @@ -130,16 +135,51 @@ get_rock_ridge_filename(iso9660_dir_t * de, /*out*/ char * retname, cdio_info("Unsupported NM flag settings (%d)",rr->u.NM.flags); break; } - if((strlen(retname) + rr->len - 5) >= 254) { + if((strlen(psz_name) + rr->len - 5) >= 254) { truncate = 1; break; } - strncat(retname, rr->u.NM.name, rr->len - 5); + strncat(psz_name, rr->u.NM.name, rr->len - 5); retnamlen += rr->len - 5; break; + case SIG('P','X'): + p_stat->st_mode = from_733(rr->u.PX.st_mode); + p_stat->st_nlinks = from_733(rr->u.PX.st_nlinks); + p_stat->st_uid = from_733(rr->u.PX.st_uid); + p_stat->st_gid = from_733(rr->u.PX.st_gid); + p_stat->b_rock = yep; + break; case SIG('R','E'): free(buffer); return -1; + case SIG('T','F'): + { +#ifdef TIME_FIXED + int cnt = 0; /* Rock ridge never appears on a High Sierra disk */ + /* Some RRIP writers incorrectly place ctime in the + ISO_ROCK_TF_CREATE field. Try to handle this correctly for + either case. */ + /*** FIXME: + Test on long format or not and use + iso9660_get_dtime or iso9660_get_ltime - which needs to be + written. + */ + if (rr->u.TF.flags & ISO_ROCK_TF_CREATE) { + p_stat->st_ctime = rr->u.TF.times[cnt++].time; + } + if(rr->u.TF.flags & ISO_ROCK_TF_MODIFY) { + p_stat->st_mtime = rr->u.TF.times[cnt++].time; + } + if(rr->u.TF.flags & ISO_ROCK_TF_ACCESS) { + p_stat->st_atime = rr->u.TF.times[cnt++].time; + } + if(rr->u.TF.flags & ISO_ROCK_TF_ATTRIBUTES) { + p_stat->st_ctime = rr->u.TF.times[cnt++].time; + } +#endif + p_stat->b_rock = yep; + break; + } default: break; } @@ -161,7 +201,7 @@ parse_rock_ridge_stat_internal(iso9660_dir_t *de, int symlink_len = 0; CONTINUE_DECLS; - if (!p_stat->b_rock) return 0; + if (nope == p_stat->b_rock) return 0; SETUP_ROCK_RIDGE(de, chr, len); if (regard_xa) @@ -192,7 +232,7 @@ parse_rock_ridge_stat_internal(iso9660_dir_t *de, CHECK_CE; break; case SIG('E','R'): - p_stat->b_rock = 1; + p_stat->b_rock = yep; cdio_debug("ISO 9660 Extensions: "); { int p; for(p=0;pu.ER.len_id;p++) cdio_debug("%c",rr->u.ER.data[p]); @@ -341,7 +381,7 @@ parse_rock_ridge_stat(iso9660_dir_t *de, /*out*/ iso9660_stat_t *p_stat) result = parse_rock_ridge_stat_internal(de, p_stat, 0); /* if Rock-Ridge flag was reset and we didn't look for attributes * behind eventual XA attributes, have a look there */ - if (0xFF == p_stat->s_rock_offset && p_stat->b_rock) { + if (0xFF == p_stat->s_rock_offset && nope != p_stat->b_rock) { result = parse_rock_ridge_stat_internal(de, p_stat, 14); } return result; diff --git a/src/iso-info.c b/src/iso-info.c index 4a93e9e2..0cf005c7 100644 --- a/src/iso-info.c +++ b/src/iso-info.c @@ -1,5 +1,5 @@ /* - $Id: iso-info.c,v 1.20 2005/01/22 22:21:36 rocky Exp $ + $Id: iso-info.c,v 1.21 2005/02/14 07:49:46 rocky Exp $ Copyright (C) 2004, 2005 Rocky Bernstein @@ -185,21 +185,22 @@ print_iso9660_recurse (iso9660_t *p_iso, const char pathname[]) _CDIO_LIST_FOREACH (entnode, entlist) { - iso9660_stat_t *statbuf = _cdio_list_node_data (entnode); - char *iso_name = statbuf->filename; + iso9660_stat_t *p_statbuf = _cdio_list_node_data (entnode); + char *iso_name = p_statbuf->filename; char _fullname[4096] = { 0, }; char translated_name[MAX_ISONAME+1]; #define DATESTR_SIZE 30 char date_str[DATESTR_SIZE]; - iso9660_name_translate_ext(iso_name, translated_name, i_joliet_level); + if (yep != p_statbuf->b_rock) + iso9660_name_translate_ext(iso_name, translated_name, i_joliet_level); snprintf (_fullname, sizeof (_fullname), "%s%s", pathname, iso_name); strncat (_fullname, "/", sizeof (_fullname)); - if (statbuf->type == _STAT_DIR + if (p_statbuf->type == _STAT_DIR && strcmp (iso_name, ".") && strcmp (iso_name, "..")) _cdio_list_append (dirlist, strdup (_fullname)); @@ -207,26 +208,28 @@ print_iso9660_recurse (iso9660_t *p_iso, const char pathname[]) if (opts.print_iso9660) { if (iso9660_ifs_is_xa(p_iso)) { printf ( " %c %s %d %d [fn %.2d] [LSN %6lu] ", - (statbuf->type == _STAT_DIR) ? 'd' : '-', - iso9660_get_xa_attr_str (statbuf->xa.attributes), - uint16_from_be (statbuf->xa.user_id), - uint16_from_be (statbuf->xa.group_id), - statbuf->xa.filenum, - (long unsigned int) statbuf->lsn); + (p_statbuf->type == _STAT_DIR) ? 'd' : '-', + iso9660_get_xa_attr_str (p_statbuf->xa.attributes), + uint16_from_be (p_statbuf->xa.user_id), + uint16_from_be (p_statbuf->xa.group_id), + p_statbuf->xa.filenum, + (long unsigned int) p_statbuf->lsn); - if (uint16_from_be(statbuf->xa.attributes) & XA_ATTR_MODE2FORM2) { + if (uint16_from_be(p_statbuf->xa.attributes) & XA_ATTR_MODE2FORM2) { printf ("%9u (%9u)", - (unsigned int) statbuf->secsize * M2F2_SECTOR_SIZE, - (unsigned int) statbuf->size); + (unsigned int) p_statbuf->secsize * M2F2_SECTOR_SIZE, + (unsigned int) p_statbuf->size); } else { - printf ("%9u", (unsigned int) statbuf->size); + printf ("%9u", (unsigned int) p_statbuf->size); } } - strftime(date_str, DATESTR_SIZE, "%b %d %Y %H:%M ", &statbuf->tm); - printf (" %s %s\n", date_str, translated_name); + strftime(date_str, DATESTR_SIZE, "%b %d %Y %H:%M ", &p_statbuf->tm); + printf (" %s %s\n", date_str, + yep == p_statbuf->b_rock ? iso_name : translated_name); } else if ( strcmp (iso_name, ".") && strcmp (iso_name, "..")) - printf("%s%s\n", pathname, translated_name); + printf("%s%s\n", pathname, + yep == p_statbuf->b_rock ? iso_name : translated_name); } _cdio_list_free (entlist, true); diff --git a/test/isofs-m1.right b/test/isofs-m1.right index 5fb9c802..baecc6c6 100644 --- a/test/isofs-m1.right +++ b/test/isofs-m1.right @@ -25,7 +25,7 @@ ISO9660 filesystem Jul 29 2002 08:39 copying Apr 20 2003 12:18 doc -/DOC/: +/doc/: Apr 20 2003 12:18 . Apr 20 2003 07:26 .. Apr 20 2003 12:18 readme.txt