New API call iso_write_opts_set_joliet_long_names()

This commit is contained in:
Thomas Schmitt 2011-03-26 15:38:08 +01:00
parent d8a56f60ef
commit 559e9b564d
8 changed files with 84 additions and 28 deletions

View File

@ -1650,6 +1650,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
target->allow_full_ascii = opts->allow_full_ascii;
target->relaxed_vol_atts = opts->relaxed_vol_atts;
target->joliet_longer_paths = opts->joliet_longer_paths;
target->joliet_long_names = opts->joliet_long_names;
target->rrip_version_1_10 = opts->rrip_version_1_10;
target->rrip_1_10_px_ino = opts->rrip_1_10_px_ino;
target->aaip_susp_1_10 = opts->aaip_susp_1_10;
@ -2641,6 +2642,15 @@ int iso_write_opts_set_joliet_longer_paths(IsoWriteOpts *opts, int allow)
return ISO_SUCCESS;
}
int iso_write_opts_set_joliet_long_names(IsoWriteOpts *opts, int allow)
{
if (opts == NULL) {
return ISO_NULL_POINTER;
}
opts->joliet_long_names = allow ? 1 : 0;
return ISO_SUCCESS;
}
int iso_write_opts_set_rrip_version_1_10(IsoWriteOpts *opts, int oldvers)
{
if (opts == NULL) {

View File

@ -161,6 +161,11 @@ struct iso_write_opts {
*/
unsigned int joliet_longer_paths :1;
/**
* Allow Joliet names up to 103 characters rather than 64.
*/
unsigned int joliet_long_names :1;
/**
* Write Rock Ridge info as of specification RRIP-1.10 rather than
* RRIP-1.12: signature "RRIP_1991A" rather than "IEEE_1282",
@ -459,6 +464,9 @@ struct ecma119_image
/** Allow paths on Joliet tree to be larger than 240 bytes */
unsigned int joliet_longer_paths :1;
/** Allow Joliet names up to 103 characters rather than 64 */
unsigned int joliet_long_names :1;
/** Write old fashioned RRIP-1.10 rather than RRIP-1.12 */
unsigned int rrip_version_1_10 :1;

View File

@ -19,6 +19,7 @@
#include "filesrc.h"
#include "eltorito.h"
#include "libisofs.h"
#include "util.h"
#include <stdlib.h>
@ -42,12 +43,11 @@ int get_joliet_name(Ecma119Image *t, IsoNode *iso, uint16_t **name)
iso_msg_debug(t->image->id, "Can't convert %s", iso->name);
return ret;
}
/* TODO #00022 : support relaxed constraints in joliet filenames */
if (iso->type == LIBISO_DIR) {
jname = iso_j_dir_id(ucs_name);
jname = iso_j_dir_id(ucs_name, t->joliet_long_names << 1);
} else {
jname = iso_j_file_id(ucs_name, !!(t->no_force_dots & 2));
jname = iso_j_file_id(ucs_name,
(t->joliet_long_names << 1) | !!(t->no_force_dots & 2));
}
free(ucs_name);
if (jname != NULL) {
@ -303,8 +303,15 @@ int joliet_create_mangled_name(uint16_t *dest, uint16_t *src, int digits,
int ret, pos;
uint16_t *ucsnumber;
char fmt[16];
char nstr[72]; /* The only caller of this function allocates dest with 66
elements and limits digits to < 8 */
char nstr[72];
/* was: The only caller of this function allocates dest
with 66 elements and limits digits to < 8
But this does not match the usage of nstr which has to take
the decimal representation of an int.
*/
if (digits >= 8)
return ISO_ASSERT_FAILURE;
sprintf(fmt, "%%0%dd", digits);
sprintf(nstr, fmt, number);
@ -337,7 +344,7 @@ static
int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
{
int ret;
int i, nchildren;
int i, nchildren, maxchar = 64;
JolietNode **children;
IsoHTable *table;
int need_sort = 0;
@ -345,6 +352,9 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
nchildren = dir->info.dir->nchildren;
children = dir->info.dir->children;
if (t->joliet_long_names)
maxchar = 103;
/* a hash table will temporary hold the names, for fast searching */
ret = iso_htable_create((nchildren * 100) / 80, iso_str_hash,
(compare_function_t)ucscmp, &table);
@ -361,7 +371,7 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
for (i = 0; i < nchildren; ++i) {
uint16_t *name, *ext;
uint16_t full_name[66];
uint16_t full_name[LIBISO_JOLIET_NAME_MAX];
int max; /* computed max len for name, without extension */
int j = i;
int digits = 1; /* characters to change per name */
@ -380,7 +390,7 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
* A max of 7 characters is good enought, it allows handling up to
* 9,999,999 files with same name.
*/
/* Important: joliet_create_mangled_name() relies on digits < 72 */
/* Important: joliet_create_mangled_name() relies on digits < 8 */
while (digits < 8) {
int ok, k;
@ -403,7 +413,7 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
ext = dot + 1;
extlen = ucslen(ext);
max = 65 - extlen - 1 - digits;
max = maxchar + 1 - extlen - 1 - digits;
if (max <= 0) {
/* this can happen if extension is too long */
if (extlen + max > 3) {
@ -413,7 +423,7 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
*/
extlen = extlen + max - 1;
ext[extlen] = 0;
max = 66 - extlen - 1 - digits;
max = maxchar + 2 - extlen - 1 - digits;
} else {
/*
* error, we don't support extensions < 3
@ -430,10 +440,10 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
} else {
/* Directory, or file without extension */
if (children[i]->type == JOLIET_DIR) {
max = 65 - digits;
max = maxchar + 1 - digits;
dot = NULL; /* dots have no meaning in dirs */
} else {
max = 65 - digits;
max = maxchar + 1 - digits;
}
name = full_name;
if (max < ucslen(name)) {
@ -446,7 +456,7 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
ok = 1;
/* change name of each file */
for (k = i; k <= j; ++k) {
uint16_t tmp[66];
uint16_t tmp[LIBISO_JOLIET_NAME_MAX];
while (1) {
ret = joliet_create_mangled_name(tmp, name, digits,
change, ext);

View File

@ -18,6 +18,10 @@
#include "libisofs.h"
#include "ecma119.h"
/* was formerly 66 = 64 + 2. Now 105 = 103 + 2.
*/
#define LIBISO_JOLIET_NAME_MAX 105
enum joliet_node_type {
JOLIET_FILE,
JOLIET_DIR

View File

@ -1585,6 +1585,15 @@ int iso_write_opts_set_relaxed_vol_atts(IsoWriteOpts *opts, int allow);
*/
int iso_write_opts_set_joliet_longer_paths(IsoWriteOpts *opts, int allow);
/**
* Allow leaf names in the Joliet tree to have up to 103 characters.
* Normal limit is 64.
* This breaks Joliet specification. Use with caution.
*
* @since 1.0.6
*/
int iso_write_opts_set_joliet_long_names(IsoWriteOpts *opts, int allow);
/**
* Write Rock Ridge info as of specification RRIP-1.10 rather than RRIP-1.12:
* signature "RRIP_1991A" rather than "IEEE_1282", field PX without file

View File

@ -282,6 +282,7 @@ iso_write_opts_set_hardlinks;
iso_write_opts_set_iso1999;
iso_write_opts_set_iso_level;
iso_write_opts_set_joliet;
iso_write_opts_set_joliet_long_names;
iso_write_opts_set_joliet_longer_paths;
iso_write_opts_set_max_37_char_filenames;
iso_write_opts_set_ms_block;

View File

@ -16,6 +16,7 @@
#include "util.h"
#include "libisofs.h"
#include "messages.h"
#include "joliet.h"
#include "../version.h"
#include <stdlib.h>
@ -916,16 +917,20 @@ ex:;
/*
bit0= no_force_dots
bit1= allow 103 characters rather than 64
*/
uint16_t *iso_j_file_id(const uint16_t *src, int flag)
{
uint16_t *dot;
size_t lname, lext, lnname, lnext, pos, i;
uint16_t dest[66]; /* 66 = 64 (name + ext) + 1 (.) + 1 (\0) */
size_t lname, lext, lnname, lnext, pos, i, maxchar = 64;
uint16_t dest[LIBISO_JOLIET_NAME_MAX];
/* was: 66 = 64 (name + ext) + 1 (.) + 1 (\0) */
if (src == NULL) {
return NULL;
}
if (flag & 2)
maxchar = 103;
dot = ucsrchr(src, '.');
@ -937,14 +942,15 @@ uint16_t *iso_j_file_id(const uint16_t *src, int flag)
*/
if (dot == NULL || cmp_ucsbe(dot + 1, '\0') == 0) {
lname = ucslen(src);
lnname = (lname > 64) ? 64 : lname;
lnname = (lname > maxchar) ? maxchar : lname;
lext = lnext = 0;
} else {
lext = ucslen(dot + 1);
lname = ucslen(src) - lext - 1;
lnext = (ucslen(src) > 65 && lext > 3) ? (lname < 61 ? 64 - lname : 3)
lnext = (ucslen(src) > maxchar + 1 && lext > 3)
? (lname < maxchar - 3 ? maxchar - lname : 3)
: lext;
lnname = (ucslen(src) > 65) ? 64 - lnext : lname;
lnname = (ucslen(src) > maxchar + 1) ? maxchar - lnext : lname;
}
if (lnname == 0 && lnext == 0) {
@ -986,18 +992,22 @@ is_done:;
return ucsdup(dest);
}
uint16_t *iso_j_dir_id(const uint16_t *src)
/* @param flag bit1= allow 103 characters rather than 64
*/
uint16_t *iso_j_dir_id(const uint16_t *src, int flag)
{
size_t len, i;
uint16_t dest[65]; /* 65 = 64 + 1 (\0) */
size_t len, i, maxchar = 64;
uint16_t dest[LIBISO_JOLIET_NAME_MAX]; /* was: 65 = 64 + 1 (\0) */
if (src == NULL) {
return NULL;
}
if (flag & 2)
maxchar = 103;
len = ucslen(src);
if (len > 64) {
len = 64;
if (len > maxchar) {
len = maxchar;
}
for (i = 0; i < len; i++) {
uint16_t c = src[i];

View File

@ -153,13 +153,15 @@ char *iso_r_fileid(const char *src, size_t len, int relaxed, int forcedot);
/**
* Create a Joliet file identifier that consists of name and extension. The
* combined name and extension length will not exceed 128 bytes, and the
* name and extension will be separated (.). All characters consist of
* 2 bytes and the resulting string is NULL-terminated by a 2-byte NULL.
* combined name and extension length will normally not exceed 64 characters
* (= 128 bytes). The name and the extension will be separated (.).
* All characters consist of 2 bytes and the resulting string is
* NULL-terminated by a 2-byte NULL.
*
* Note that version number and (;1) is not appended.
* @param flag
* bit0= no_force_dots
* bit1= allow 103 characters rather than 64
* @return
* NULL if the original name and extension both are of length 0.
*/
@ -171,10 +173,12 @@ uint16_t *iso_j_file_id(const uint16_t *src, int flag);
* and the name and extension will be separated (.). All characters consist of
* 2 bytes and the resulting string is NULL-terminated by a 2-byte NULL.
*
* @param flag
* bit1= allow 103 characters rather than 64
* @return
* NULL if the original name and extension both are of length 0.
*/
uint16_t *iso_j_dir_id(const uint16_t *src);
uint16_t *iso_j_dir_id(const uint16_t *src, int flag);
/**
* Like strlen, but for Joliet strings.