Joliet improvements
* support discs with more than one secondary volume descriptors * add Joliet support for extract sample * add fallback to non-Joliet if non-Joliet may be longer
This commit is contained in:
@@ -19,16 +19,20 @@
|
||||
/* iso9660 filesystem-based routines */
|
||||
|
||||
#if defined(HAVE_CONFIG_H) && !defined(__CDIO_CONFIG_H__)
|
||||
# include "config.h"
|
||||
# define __CDIO_CONFIG_H__ 1
|
||||
#include "config.h"
|
||||
#define __CDIO_CONFIG_H__ 1
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDIO_H
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ERRNO_H
|
||||
# include <errno.h>
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LANGINFO_CODESET
|
||||
@@ -46,8 +50,6 @@
|
||||
#include "_cdio_stdio.h"
|
||||
#include "cdio_private.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static const char _rcsid[] = "$Id: iso9660_fs.c,v 1.47 2008/04/18 16:02:09 karl Exp $";
|
||||
|
||||
/* Implementation of iso9660_t type */
|
||||
@@ -272,6 +274,72 @@ check_pvd (const iso9660_pvd_t *p_pvd, cdio_log_level_t log_level)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Core procedure for the iso9660_ifs_get_###_id() calls.
|
||||
pvd_member/svd_member is a pointer to an achar_t or dchar_t
|
||||
ID string which we can superset as char.
|
||||
If the Joliet converted string is the same as the achar_t/dchar_t
|
||||
one, we fall back to using the latter, as it may be longer.
|
||||
*/
|
||||
static inline bool
|
||||
get_member_id(iso9660_t *p_iso, cdio_utf8_t **p_psz_member_id,
|
||||
char* pvd_member, char* svd_member, size_t max_size)
|
||||
{
|
||||
int j;
|
||||
bool strip;
|
||||
|
||||
if (!p_iso) {
|
||||
*p_psz_member_id = NULL;
|
||||
return false;
|
||||
}
|
||||
#ifdef HAVE_JOLIET
|
||||
if (p_iso->i_joliet_level) {
|
||||
/* Translate USC-2 string from Secondary Volume Descriptor */
|
||||
if (cdio_charset_to_utf8(svd_member, max_size,
|
||||
p_psz_member_id, "UCS-2BE")) {
|
||||
/* NB: *p_psz_member_id is never NULL on success. */
|
||||
if (strncmp(*p_psz_member_id, pvd_member,
|
||||
strlen(*p_psz_member_id)) != 0) {
|
||||
/* Strip trailing spaces */
|
||||
for (j = strlen(*p_psz_member_id)-1; j >= 0; j--) {
|
||||
if ((*p_psz_member_id)[j] != ' ')
|
||||
break;
|
||||
(*p_psz_member_id)[j] = '\0';
|
||||
}
|
||||
if ((*p_psz_member_id)[0] != 0) {
|
||||
/* Joliet string is not empty and differs from
|
||||
non Joliet one => use it */
|
||||
return true;
|
||||
}
|
||||
}
|
||||
/* Joliet string was either empty or same */
|
||||
free(*p_psz_member_id);
|
||||
}
|
||||
}
|
||||
#endif /*HAVE_JOLIET*/
|
||||
*p_psz_member_id = calloc(max_size+1, sizeof(cdio_utf8_t));
|
||||
if (!*p_psz_member_id) {
|
||||
cdio_warn("Memory allocation error");
|
||||
return false;
|
||||
}
|
||||
/* Copy string while removing trailing spaces */
|
||||
(*p_psz_member_id)[max_size] = 0;
|
||||
for (strip=true, j=max_size-1; j>=0; j--) {
|
||||
if (strip && (pvd_member[j] == ' '))
|
||||
continue;
|
||||
strip = false;
|
||||
(*p_psz_member_id)[j] = pvd_member[j];
|
||||
}
|
||||
if (strlen(*p_psz_member_id) == 0) {
|
||||
free(*p_psz_member_id);
|
||||
*p_psz_member_id = NULL;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Return the application ID. NULL is returned in psz_app_id if there
|
||||
is some problem in getting this.
|
||||
@@ -280,30 +348,14 @@ bool
|
||||
iso9660_ifs_get_application_id(iso9660_t *p_iso,
|
||||
/*out*/ cdio_utf8_t **p_psz_app_id)
|
||||
{
|
||||
if (!p_iso) {
|
||||
*p_psz_app_id = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef HAVE_JOLIET
|
||||
if (p_iso->i_joliet_level) {
|
||||
/* TODO: check that we haven't reached the maximum size.
|
||||
If we have, perhaps we've truncated and if we can get
|
||||
longer results *and* have the same character using
|
||||
the PVD, do that.
|
||||
*/
|
||||
if ( cdio_charset_to_utf8(p_iso->svd.application_id,
|
||||
ISO_MAX_APPLICATION_ID,
|
||||
p_psz_app_id, "UCS-2BE"))
|
||||
return true;
|
||||
}
|
||||
#endif /*HAVE_JOLIET*/
|
||||
*p_psz_app_id = iso9660_get_application_id( &(p_iso->pvd) );
|
||||
return *p_psz_app_id != NULL && strlen(*p_psz_app_id);
|
||||
return get_member_id(p_iso, p_psz_app_id,
|
||||
(char*)p_iso->pvd.application_id,
|
||||
(char*)p_iso->svd.application_id,
|
||||
ISO_MAX_APPLICATION_ID);
|
||||
}
|
||||
|
||||
/*!
|
||||
Return the Joliet level recognaized for p_iso.
|
||||
Return the Joliet level recognized for p_iso.
|
||||
*/
|
||||
uint8_t iso9660_ifs_get_joliet_level(iso9660_t *p_iso)
|
||||
{
|
||||
@@ -319,25 +371,10 @@ bool
|
||||
iso9660_ifs_get_preparer_id(iso9660_t *p_iso,
|
||||
/*out*/ cdio_utf8_t **p_psz_preparer_id)
|
||||
{
|
||||
if (!p_iso) {
|
||||
*p_psz_preparer_id = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef HAVE_JOLIET
|
||||
if (p_iso->i_joliet_level) {
|
||||
/* TODO: check that we haven't reached the maximum size.
|
||||
If we have, perhaps we've truncated and if we can get
|
||||
longer results *and* have the same character using
|
||||
the PVD, do that.
|
||||
*/
|
||||
if ( cdio_charset_to_utf8(p_iso->svd.preparer_id, ISO_MAX_PREPARER_ID,
|
||||
p_psz_preparer_id, "UCS-2BE") )
|
||||
return true;
|
||||
}
|
||||
#endif /*HAVE_JOLIET*/
|
||||
*p_psz_preparer_id = iso9660_get_preparer_id( &(p_iso->pvd) );
|
||||
return *p_psz_preparer_id != NULL && strlen(*p_psz_preparer_id);
|
||||
return get_member_id(p_iso, p_psz_preparer_id,
|
||||
(char*)p_iso->pvd.preparer_id,
|
||||
(char*)p_iso->svd.preparer_id,
|
||||
ISO_MAX_PREPARER_ID);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -347,28 +384,12 @@ iso9660_ifs_get_preparer_id(iso9660_t *p_iso,
|
||||
bool iso9660_ifs_get_publisher_id(iso9660_t *p_iso,
|
||||
/*out*/ cdio_utf8_t **p_psz_publisher_id)
|
||||
{
|
||||
if (!p_iso) {
|
||||
*p_psz_publisher_id = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef HAVE_JOLIET
|
||||
if (p_iso->i_joliet_level) {
|
||||
/* TODO: check that we haven't reached the maximum size.
|
||||
If we have, perhaps we've truncated and if we can get
|
||||
longer results *and* have the same character using
|
||||
the PVD, do that.
|
||||
*/
|
||||
if( cdio_charset_to_utf8(p_iso->svd.publisher_id, ISO_MAX_PUBLISHER_ID,
|
||||
p_psz_publisher_id, "UCS-2BE") )
|
||||
return true;
|
||||
}
|
||||
#endif /*HAVE_JOLIET*/
|
||||
*p_psz_publisher_id = iso9660_get_publisher_id( &(p_iso->pvd) );
|
||||
return *p_psz_publisher_id != NULL && strlen(*p_psz_publisher_id);
|
||||
return get_member_id(p_iso, p_psz_publisher_id,
|
||||
(char*)p_iso->pvd.publisher_id,
|
||||
(char*)p_iso->svd.publisher_id,
|
||||
ISO_MAX_PUBLISHER_ID);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Return a string containing the PVD's publisher id with trailing
|
||||
blanks removed.
|
||||
@@ -376,28 +397,12 @@ bool iso9660_ifs_get_publisher_id(iso9660_t *p_iso,
|
||||
bool iso9660_ifs_get_system_id(iso9660_t *p_iso,
|
||||
/*out*/ cdio_utf8_t **p_psz_system_id)
|
||||
{
|
||||
if (!p_iso) {
|
||||
*p_psz_system_id = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef HAVE_JOLIET
|
||||
if (p_iso->i_joliet_level) {
|
||||
/* TODO: check that we haven't reached the maximum size.
|
||||
If we have, perhaps we've truncated and if we can get
|
||||
longer results *and* have the same character using
|
||||
the PVD, do that.
|
||||
*/
|
||||
if ( cdio_charset_to_utf8(p_iso->svd.system_id, ISO_MAX_SYSTEM_ID,
|
||||
p_psz_system_id, "UCS-2BE") )
|
||||
return true;
|
||||
}
|
||||
#endif /*HAVE_JOLIET*/
|
||||
*p_psz_system_id = iso9660_get_system_id( &(p_iso->pvd) );
|
||||
return *p_psz_system_id != NULL && strlen(*p_psz_system_id);
|
||||
return get_member_id(p_iso, p_psz_system_id,
|
||||
(char*)p_iso->pvd.system_id,
|
||||
(char*)p_iso->svd.system_id,
|
||||
ISO_MAX_SYSTEM_ID);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Return a string containing the PVD's publisher id with trailing
|
||||
blanks removed.
|
||||
@@ -405,28 +410,12 @@ bool iso9660_ifs_get_system_id(iso9660_t *p_iso,
|
||||
bool iso9660_ifs_get_volume_id(iso9660_t *p_iso,
|
||||
/*out*/ cdio_utf8_t **p_psz_volume_id)
|
||||
{
|
||||
if (!p_iso) {
|
||||
*p_psz_volume_id = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef HAVE_JOLIET
|
||||
if (p_iso->i_joliet_level) {
|
||||
/* TODO: check that we haven't reached the maximum size.
|
||||
If we have, perhaps we've truncated and if we can get
|
||||
longer results *and* have the same character using
|
||||
the PVD, do that.
|
||||
*/
|
||||
if ( cdio_charset_to_utf8(p_iso->svd.volume_id, ISO_MAX_VOLUME_ID,
|
||||
p_psz_volume_id, "UCS-2BE") )
|
||||
return true;
|
||||
}
|
||||
#endif /* HAVE_JOLIET */
|
||||
*p_psz_volume_id = iso9660_get_volume_id( &(p_iso->pvd) );
|
||||
return *p_psz_volume_id != NULL && strlen(*p_psz_volume_id);
|
||||
return get_member_id(p_iso, p_psz_volume_id,
|
||||
(char*)p_iso->pvd.volume_id,
|
||||
(char*)p_iso->svd.volume_id,
|
||||
ISO_MAX_VOLUME_ID);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Return a string containing the PVD's publisher id with trailing
|
||||
blanks removed.
|
||||
@@ -434,27 +423,10 @@ bool iso9660_ifs_get_volume_id(iso9660_t *p_iso,
|
||||
bool iso9660_ifs_get_volumeset_id(iso9660_t *p_iso,
|
||||
/*out*/ cdio_utf8_t **p_psz_volumeset_id)
|
||||
{
|
||||
if (!p_iso) {
|
||||
*p_psz_volumeset_id = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef HAVE_JOLIET
|
||||
if (p_iso->i_joliet_level) {
|
||||
/* TODO: check that we haven't reached the maximum size.
|
||||
If we have, perhaps we've truncated and if we can get
|
||||
longer results *and* have the same character using
|
||||
the PVD, do that.
|
||||
*/
|
||||
if ( cdio_charset_to_utf8(p_iso->svd.volume_set_id,
|
||||
ISO_MAX_VOLUMESET_ID,
|
||||
p_psz_volumeset_id,
|
||||
"UCS-2BE") )
|
||||
return true;
|
||||
}
|
||||
#endif /*HAVE_JOLIET*/
|
||||
*p_psz_volumeset_id = iso9660_get_volumeset_id( &(p_iso->pvd) );
|
||||
return *p_psz_volumeset_id != NULL && strlen(*p_psz_volumeset_id);
|
||||
return get_member_id(p_iso, p_psz_volumeset_id,
|
||||
(char*)p_iso->pvd.volume_set_id,
|
||||
(char*)p_iso->svd.volume_set_id,
|
||||
ISO_MAX_VOLUMESET_ID);
|
||||
}
|
||||
|
||||
|
||||
@@ -494,19 +466,25 @@ bool
|
||||
iso9660_ifs_read_superblock (iso9660_t *p_iso,
|
||||
iso_extension_mask_t iso_extension_mask)
|
||||
{
|
||||
iso9660_svd_t *p_svd; /* Secondary volume descriptor. */
|
||||
|
||||
iso9660_svd_t p_svd; /* Secondary volume descriptor. */
|
||||
int i;
|
||||
|
||||
if (!p_iso || !iso9660_ifs_read_pvd(p_iso, &(p_iso->pvd)))
|
||||
return false;
|
||||
|
||||
p_svd = &(p_iso->svd);
|
||||
p_iso->i_joliet_level = 0;
|
||||
|
||||
if (0 != iso9660_iso_seek_read (p_iso, p_svd, ISO_PVD_SECTOR+1, 1)) {
|
||||
if ( ISO_VD_SUPPLEMENTARY == from_711(p_svd->type) ) {
|
||||
if (p_svd->escape_sequences[0] == 0x25
|
||||
&& p_svd->escape_sequences[1] == 0x2f) {
|
||||
switch (p_svd->escape_sequences[2]) {
|
||||
/* There may be multiple Secondary Volume Descriptors (eg. El Torito + Joliet) */
|
||||
for (i=1; (0 != iso9660_iso_seek_read (p_iso, &p_svd, ISO_PVD_SECTOR+i, 1)); i++) {
|
||||
if (ISO_VD_END == from_711(p_svd.type) ) /* Last SVD */
|
||||
break;
|
||||
if ( ISO_VD_SUPPLEMENTARY == from_711(p_svd.type) ) {
|
||||
/* We're only interested in Joliet => make sure the SVD isn't overwritten */
|
||||
if (p_iso->i_joliet_level == 0)
|
||||
memcpy(&(p_iso->svd), &p_svd, sizeof(iso9660_svd_t));
|
||||
if (p_svd.escape_sequences[0] == 0x25
|
||||
&& p_svd.escape_sequences[1] == 0x2f) {
|
||||
switch (p_svd.escape_sequences[2]) {
|
||||
case 0x40:
|
||||
if (iso_extension_mask & ISO_EXTENSION_JOLIET_LEVEL1)
|
||||
p_iso->i_joliet_level = 1;
|
||||
|
||||
Reference in New Issue
Block a user