[iso] Syslinux support improvements

* Allow the use of vanilla Syslinux by creating a /syslinux.cfg
  that references isolinux.cfg
* Fix #40 and #42
* Workaround for #44 by search and replace of ISO label in .cfg
* ISO9660 Joliet fixes
This commit is contained in:
Pete Batard 2012-02-21 00:08:31 +00:00
parent 3e51ed7160
commit f5939d18ab
6 changed files with 259 additions and 208 deletions

View file

@ -303,24 +303,26 @@ bool cdio_charset_to_utf8(char *src, size_t src_len, cdio_utf8_t **dst,
if (src == NULL || dst == NULL || src_charset == NULL || strcmp(src_charset, "UCS-2BE") != 0)
return false;
/* Compute UCS-2 src length */
if (src_len == (size_t)-1) {
for (src_len = 0; ((uint16_t*)src)[src_len] !=0; src_len++);
src_len <<=2;
} else {
src_len >>=1;
}
/* Eliminate empty strings */
if ((src_len < 2) || ((src[0] == 0) && (src[1] == 0))) {
if ((src_len < 1) || ((src[0] == 0) && (src[1] == 0))) {
*dst = NULL;
return false;
}
/* Perform byte reversal */
le_src = (wchar_t*)malloc(src_len+2);
for (i=0; i<src_len; i+=2) {
((char*)le_src)[i] = src[i+1];
((char*)le_src)[i+1] = src[i];
le_src = (wchar_t*)malloc(2*src_len+2);
for (i=0; i<src_len; i++) {
((char*)le_src)[2*i] = src[2*i+1];
((char*)le_src)[2*i+1] = src[2*i];
}
le_src[src_len/2] = 0;
le_src[src_len] = 0;
*dst = wchar_to_utf8(le_src);
free(le_src);

View file

@ -85,33 +85,6 @@ struct _iso9660_s {
*/
};
/*!
Change trailing blanks in null-terminated *str to nulls
If the end result is an empty string, *str is freed
*/
static void
strip_trail (char** str)
{
int j;
if (*str == NULL)
return;
for (j = strlen (*str) - 1; j >= 0; j--)
{
if ((*str)[j] != ' ')
break;
(*str)[j] = '\0';
}
if ((*str)[0] == 0)
{
free(*str);
*str = NULL;
}
}
static long int iso9660_seek_read_framesize (const iso9660_t *p_iso,
void *ptr, lsn_t start,
long int size,
@ -299,6 +272,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.
@ -307,32 +346,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")) {
strip_trail(p_psz_app_id);
return (*p_psz_app_id != NULL);
}
}
#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)
{
@ -348,27 +369,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") ) {
strip_trail(p_psz_preparer_id);
return (*p_psz_preparer_id != NULL);
}
}
#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);
}
/*!
@ -378,30 +382,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") ) {
strip_trail(p_psz_publisher_id);
return (*p_psz_publisher_id != NULL);
}
}
#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.
@ -409,30 +395,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") ) {
strip_trail(p_psz_system_id);
return (*p_psz_system_id != NULL);
}
}
#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.
@ -440,30 +408,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") ) {
strip_trail(p_psz_volume_id);
return (*p_psz_volume_id != NULL);
}
}
#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.
@ -471,29 +421,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") ) {
strip_trail(p_psz_volumeset_id);
return (*p_psz_volumeset_id != NULL);
}
}
#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);
}