First semblance of being able to handle Rock Ridge names.

This commit is contained in:
rocky
2005-02-14 07:49:46 +00:00
parent 3f4397a6f5
commit b504a1a652
5 changed files with 112 additions and 61 deletions

View File

@@ -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 <hvr@gnu.org> Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org>
Copyright (C) 2003, 2004, 2005 Rocky Bernstein <rocky@panix.com> Copyright (C) 2003, 2004, 2005 Rocky Bernstein <rocky@panix.com>
@@ -526,7 +526,7 @@ typedef uint32_t posix_gid_t;
@see iso9660_dir @see iso9660_dir
*/ */
struct iso9660_stat_s { /* big endian!! */ 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 If not true then the next 9 fields
aren't used. aren't used.
*/ */

View File

@@ -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 <hvr@gnu.org> Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org>
Copyright (C) 2003, 2004, 2005 Rocky Bernstein <rocky@panix.com> Copyright (C) 2003, 2004, 2005 Rocky Bernstein <rocky@panix.com>
@@ -52,7 +52,7 @@
#include <stdio.h> #include <stdio.h>
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 */ /* Implementation of iso9660_t type */
struct _iso9660_s { 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); uint8_t dir_len= iso9660_get_dir_len(p_iso9660_dir);
unsigned int filename_len; unsigned int filename_len;
unsigned int stat_len; unsigned int stat_len;
iso9660_stat_t *stat; iso9660_stat_t *p_stat;
if (!dir_len) return NULL; 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' */ /* .. string in statbuf is one longer than in p_iso9660_dir's listing '\1' */
stat_len = sizeof(iso9660_stat_t)+filename_len+2; stat_len = sizeof(iso9660_stat_t)+filename_len+2;
stat = calloc(1, stat_len); p_stat = calloc(1, stat_len);
stat->type = (p_iso9660_dir->file_flags & ISO_DIRECTORY) p_stat->type = (p_iso9660_dir->file_flags & ISO_DIRECTORY)
? _STAT_DIR : _STAT_FILE; ? _STAT_DIR : _STAT_FILE;
stat->lsn = from_733 (p_iso9660_dir->extent); p_stat->lsn = from_733 (p_iso9660_dir->extent);
stat->size = from_733 (p_iso9660_dir->size); p_stat->size = from_733 (p_iso9660_dir->size);
stat->secsize = _cdio_len2blocks (stat->size, ISO_BLOCKSIZE); 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) 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) else if ('\1' == p_iso9660_dir->filename[0] && 1 == filename_len)
strcpy (stat->filename, ".."); strcpy (p_stat->filename, "..");
else { 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 #ifdef HAVE_JOLIET
if (i_joliet_level) { if (i_joliet_level && i_rr_fname_len > 0) {
int i_inlen = filename_len; int i_inlen = filename_len;
int i_outlen = (i_inlen / 2); int i_outlen = (i_inlen / 2);
char *p_psz_out = NULL; char *p_psz_out = NULL;
ucs2be_to_locale(p_iso9660_dir->filename, i_inlen, ucs2be_to_locale(p_iso9660_dir->filename, i_inlen,
&p_psz_out, i_outlen); &p_psz_out, i_outlen);
strncpy(stat->filename, p_psz_out, filename_len); strncpy(p_stat->filename, p_psz_out, filename_len);
free(p_psz_out); free(p_psz_out);
} else } else
#endif /*HAVE_JOLIET*/ #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)) { if (dir_len < sizeof (iso9660_dir_t)) {
free(stat); free(p_stat);
return NULL; return NULL;
} }
@@ -886,10 +894,10 @@ _iso9660_dir_to_statbuf (iso9660_dir_t *p_iso9660_dir, bool b_mode2,
su_length--; su_length--;
if (su_length < 0 || su_length < sizeof (iso9660_xa_t)) if (su_length < 0 || su_length < sizeof (iso9660_xa_t))
return stat; return p_stat;
if (nope == b_xa) { if (nope == b_xa) {
return stat; return p_stat;
} else { } else {
iso9660_xa_t *xa_data = iso9660_xa_t *xa_data =
(void *) (((char *) p_iso9660_dir) (void *) (((char *) p_iso9660_dir)
@@ -909,12 +917,12 @@ _iso9660_dir_to_statbuf (iso9660_dir_t *p_iso9660_dir, bool b_mode2,
su_length, su_length,
xa_data->signature[0], xa_data->signature[1], xa_data->signature[0], xa_data->signature[1],
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;
} }

View File

@@ -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 <rocky@panix.com> Copyright (C) 2005 Rocky Bernstein <rocky@panix.com>
Adapted from GNU/Linux fs/isofs/rock.c (C) 1992, 1993 Eric Youngdale 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 int
get_rock_ridge_filename(iso9660_dir_t * de, /*out*/ char * retname, get_rock_ridge_filename(iso9660_dir_t * de, /*out*/ char * psz_name,
/*out*/ iso9660_stat_t *p_stat) iso9660_stat_t *p_stat)
{ {
int len; int len;
unsigned char *chr; unsigned char *chr;
CONTINUE_DECLS; CONTINUE_DECLS;
int retnamlen = 0, truncate=0; int retnamlen = 0;
int truncate=0;
if (!p_stat || !p_stat->b_rock) return 0; if (!p_stat || nope == p_stat->b_rock) return 0;
*retname = 0; *psz_name = 0;
SETUP_ROCK_RIDGE(de, chr, len); SETUP_ROCK_RIDGE(de, chr, len);
/* repeat:*/ /* 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 */ while (len > 1){ /* There may be one byte for padding somewhere */
rr = (iso_extension_record_t *) chr; rr = (iso_extension_record_t *) chr;
if (rr->len == 0) goto out; /* Something got screwed up here */ if (rr->len == 0) goto out; /* Something got screwed up here */
sig = from_721(*chr); sig = *chr+(*(chr+1) << 8);
chr += rr->len; chr += rr->len;
len -= rr->len; len -= rr->len;
@@ -114,6 +118,7 @@ get_rock_ridge_filename(iso9660_dir_t * de, /*out*/ char * retname,
CHECK_CE; CHECK_CE;
break; break;
case SIG('N','M'): case SIG('N','M'):
p_stat->b_rock = yep;
if (truncate) break; if (truncate) break;
/* /*
* If the flags are 2 or 4, this indicates '.' or '..'. * 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); cdio_info("Unsupported NM flag settings (%d)",rr->u.NM.flags);
break; break;
} }
if((strlen(retname) + rr->len - 5) >= 254) { if((strlen(psz_name) + rr->len - 5) >= 254) {
truncate = 1; truncate = 1;
break; break;
} }
strncat(retname, rr->u.NM.name, rr->len - 5); strncat(psz_name, rr->u.NM.name, rr->len - 5);
retnamlen += rr->len - 5; retnamlen += rr->len - 5;
break; 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'): case SIG('R','E'):
free(buffer); free(buffer);
return -1; 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: default:
break; break;
} }
@@ -161,7 +201,7 @@ parse_rock_ridge_stat_internal(iso9660_dir_t *de,
int symlink_len = 0; int symlink_len = 0;
CONTINUE_DECLS; CONTINUE_DECLS;
if (!p_stat->b_rock) return 0; if (nope == p_stat->b_rock) return 0;
SETUP_ROCK_RIDGE(de, chr, len); SETUP_ROCK_RIDGE(de, chr, len);
if (regard_xa) if (regard_xa)
@@ -192,7 +232,7 @@ parse_rock_ridge_stat_internal(iso9660_dir_t *de,
CHECK_CE; CHECK_CE;
break; break;
case SIG('E','R'): case SIG('E','R'):
p_stat->b_rock = 1; p_stat->b_rock = yep;
cdio_debug("ISO 9660 Extensions: "); cdio_debug("ISO 9660 Extensions: ");
{ int p; { int p;
for(p=0;p<rr->u.ER.len_id;p++) cdio_debug("%c",rr->u.ER.data[p]); for(p=0;p<rr->u.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); result = parse_rock_ridge_stat_internal(de, p_stat, 0);
/* if Rock-Ridge flag was reset and we didn't look for attributes /* if Rock-Ridge flag was reset and we didn't look for attributes
* behind eventual XA attributes, have a look there */ * 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); result = parse_rock_ridge_stat_internal(de, p_stat, 14);
} }
return result; return result;

View File

@@ -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 <rocky@panix.com> Copyright (C) 2004, 2005 Rocky Bernstein <rocky@panix.com>
@@ -185,13 +185,14 @@ print_iso9660_recurse (iso9660_t *p_iso, const char pathname[])
_CDIO_LIST_FOREACH (entnode, entlist) _CDIO_LIST_FOREACH (entnode, entlist)
{ {
iso9660_stat_t *statbuf = _cdio_list_node_data (entnode); iso9660_stat_t *p_statbuf = _cdio_list_node_data (entnode);
char *iso_name = statbuf->filename; char *iso_name = p_statbuf->filename;
char _fullname[4096] = { 0, }; char _fullname[4096] = { 0, };
char translated_name[MAX_ISONAME+1]; char translated_name[MAX_ISONAME+1];
#define DATESTR_SIZE 30 #define DATESTR_SIZE 30
char date_str[DATESTR_SIZE]; char date_str[DATESTR_SIZE];
if (yep != p_statbuf->b_rock)
iso9660_name_translate_ext(iso_name, translated_name, i_joliet_level); iso9660_name_translate_ext(iso_name, translated_name, i_joliet_level);
snprintf (_fullname, sizeof (_fullname), "%s%s", pathname, snprintf (_fullname, sizeof (_fullname), "%s%s", pathname,
@@ -199,7 +200,7 @@ print_iso9660_recurse (iso9660_t *p_iso, const char pathname[])
strncat (_fullname, "/", sizeof (_fullname)); strncat (_fullname, "/", sizeof (_fullname));
if (statbuf->type == _STAT_DIR if (p_statbuf->type == _STAT_DIR
&& strcmp (iso_name, ".") && strcmp (iso_name, ".")
&& strcmp (iso_name, "..")) && strcmp (iso_name, ".."))
_cdio_list_append (dirlist, strdup (_fullname)); _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 (opts.print_iso9660) {
if (iso9660_ifs_is_xa(p_iso)) { if (iso9660_ifs_is_xa(p_iso)) {
printf ( " %c %s %d %d [fn %.2d] [LSN %6lu] ", printf ( " %c %s %d %d [fn %.2d] [LSN %6lu] ",
(statbuf->type == _STAT_DIR) ? 'd' : '-', (p_statbuf->type == _STAT_DIR) ? 'd' : '-',
iso9660_get_xa_attr_str (statbuf->xa.attributes), iso9660_get_xa_attr_str (p_statbuf->xa.attributes),
uint16_from_be (statbuf->xa.user_id), uint16_from_be (p_statbuf->xa.user_id),
uint16_from_be (statbuf->xa.group_id), uint16_from_be (p_statbuf->xa.group_id),
statbuf->xa.filenum, p_statbuf->xa.filenum,
(long unsigned int) statbuf->lsn); (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)", printf ("%9u (%9u)",
(unsigned int) statbuf->secsize * M2F2_SECTOR_SIZE, (unsigned int) p_statbuf->secsize * M2F2_SECTOR_SIZE,
(unsigned int) statbuf->size); (unsigned int) p_statbuf->size);
} else { } 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); strftime(date_str, DATESTR_SIZE, "%b %d %Y %H:%M ", &p_statbuf->tm);
printf (" %s %s\n", date_str, translated_name); printf (" %s %s\n", date_str,
yep == p_statbuf->b_rock ? iso_name : translated_name);
} else } else
if ( strcmp (iso_name, ".") && strcmp (iso_name, "..")) 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); _cdio_list_free (entlist, true);

View File

@@ -25,7 +25,7 @@ ISO9660 filesystem
Jul 29 2002 08:39 copying Jul 29 2002 08:39 copying
Apr 20 2003 12:18 doc Apr 20 2003 12:18 doc
/DOC/: /doc/:
Apr 20 2003 12:18 . Apr 20 2003 12:18 .
Apr 20 2003 07:26 .. Apr 20 2003 07:26 ..
Apr 20 2003 12:18 readme.txt Apr 20 2003 12:18 readme.txt