From 016baf99843b3d38eef88e14fc8b76c82d63ea80 Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Tue, 13 Apr 2010 10:18:55 +0200 Subject: [PATCH] Implemented no_force_dots and separate omit_version_numbers for Joliet to allow producing the same Joliet names as mkisofs -J. --- libisofs/ecma119.c | 6 +++--- libisofs/ecma119.h | 12 ++++++++---- libisofs/ecma119_tree.c | 6 +++--- libisofs/joliet.c | 8 ++++---- libisofs/libisofs.h | 7 ++++++- libisofs/util.c | 11 ++++++++++- libisofs/util.h | 5 +++-- 7 files changed, 37 insertions(+), 18 deletions(-) diff --git a/libisofs/ecma119.c b/libisofs/ecma119.c index 2620fda..2e9c233 100644 --- a/libisofs/ecma119.c +++ b/libisofs/ecma119.c @@ -96,7 +96,7 @@ void ecma119_image_free(Ecma119Image *t) static int need_version_number(Ecma119Image *t, Ecma119Node *n) { - if (t->omit_version_numbers) { + if (t->omit_version_numbers & 1) { return 0; } if (n->type == ECMA119_DIR || n->type == ECMA119_PLACEHOLDER) { @@ -1821,7 +1821,7 @@ int iso_write_opts_set_omit_version_numbers(IsoWriteOpts *opts, int omit) if (opts == NULL) { return ISO_NULL_POINTER; } - opts->omit_version_numbers = omit ? 1 : 0; + opts->omit_version_numbers = omit & 3; return ISO_SUCCESS; } @@ -1857,7 +1857,7 @@ int iso_write_opts_set_no_force_dots(IsoWriteOpts *opts, int no) if (opts == NULL) { return ISO_NULL_POINTER; } - opts->no_force_dots = no ? 1 : 0; + opts->no_force_dots = no & 3; return ISO_SUCCESS; } diff --git a/libisofs/ecma119.h b/libisofs/ecma119.h index f5ff273..b679365 100644 --- a/libisofs/ecma119.h +++ b/libisofs/ecma119.h @@ -57,8 +57,10 @@ struct iso_write_opts { /** * Omit the version number (";1") at the end of the ISO-9660 identifiers. * Version numbers are usually not used. + * bit0= ECMA-119 and Joliet (for historical reasons) + * bit1= Joliet */ - unsigned int omit_version_numbers :1; + unsigned int omit_version_numbers :2; /** * Allow ISO-9660 directory hierarchy to be deeper than 8 levels. @@ -82,8 +84,10 @@ struct iso_write_opts { * ISO-9660 forces filenames to have a ".", that separates file name from * extension. libisofs adds it if original filename doesn't has one. Set * this to 1 to prevent this behavior + * bit0= ECMA-119 + * bit1= Joliet */ - unsigned int no_force_dots :1; + unsigned int no_force_dots :2; /** * Allow lowercase characters in ISO-9660 filenames. By default, only @@ -344,11 +348,11 @@ struct ecma119_image unsigned int always_gmt :1; /* relaxed constraints */ - unsigned int omit_version_numbers :1; + unsigned int omit_version_numbers :2; unsigned int allow_deep_paths :1; unsigned int allow_longer_paths :1; unsigned int max_37_char_filenames :1; - unsigned int no_force_dots :1; + unsigned int no_force_dots :2; unsigned int allow_lowercase :1; unsigned int allow_full_ascii :1; diff --git a/libisofs/ecma119_tree.c b/libisofs/ecma119_tree.c index a54d382..17f7006 100644 --- a/libisofs/ecma119_tree.c +++ b/libisofs/ecma119_tree.c @@ -64,18 +64,18 @@ int get_iso_name(Ecma119Image *img, IsoNode *iso, char **name) } else { if (img->max_37_char_filenames) { isoname = iso_r_fileid(ascii_name, 36, relaxed, - img->no_force_dots ? 0 : 1); + (img->no_force_dots & 1) ? 0 : 1); } else if (img->iso_level == 1) { if (relaxed) { isoname = iso_r_fileid(ascii_name, 11, relaxed, - img->no_force_dots ? 0 : 1); + (img->no_force_dots & 1) ? 0 : 1); } else { isoname = iso_1_fileid(ascii_name); } } else { if (relaxed) { isoname = iso_r_fileid(ascii_name, 30, relaxed, - img->no_force_dots ? 0 : 1); + (img->no_force_dots & 1) ? 0 : 1); } else { isoname = iso_2_fileid(ascii_name); } diff --git a/libisofs/joliet.c b/libisofs/joliet.c index 747ef89..160ad47 100644 --- a/libisofs/joliet.c +++ b/libisofs/joliet.c @@ -43,7 +43,7 @@ int get_joliet_name(Ecma119Image *t, IsoNode *iso, uint16_t **name) if (iso->type == LIBISO_DIR) { jname = iso_j_dir_id(ucs_name); } else { - jname = iso_j_file_id(ucs_name); + jname = iso_j_file_id(ucs_name, !!(t->no_force_dots & 2)); } free(ucs_name); if (jname != NULL) { @@ -574,7 +574,7 @@ size_t calc_dirent_len(Ecma119Image *t, JolietNode *n) { /* note than name len is always even, so we always need the pad byte */ int ret = n->name ? ucslen(n->name) * 2 + 34 : 34; - if (n->type == JOLIET_FILE && !t->omit_version_numbers) { + if (n->type == JOLIET_FILE && !(t->omit_version_numbers & 3)) { /* take into account version numbers */ ret += 4; } @@ -722,7 +722,7 @@ void write_one_dir_record(Ecma119Image *t, JolietNode *node, int file_id, memcpy(rec->file_id, name, len_fi); - if (node->type == JOLIET_FILE && !t->omit_version_numbers) { + if (node->type == JOLIET_FILE && !(t->omit_version_numbers & 3)) { len_dr += 4; rec->file_id[len_fi++] = 0; rec->file_id[len_fi++] = ';'; @@ -899,7 +899,7 @@ int write_one_dir(Ecma119Image *t, JolietNode *dir) /* compute len of directory entry */ fi_len = ucslen(child->name) * 2; len = fi_len + 34; - if (child->type == JOLIET_FILE && !t->omit_version_numbers) { + if (child->type == JOLIET_FILE && !(t->omit_version_numbers & 3)) { len += 4; } diff --git a/libisofs/libisofs.h b/libisofs/libisofs.h index 33ac9ef..ce0f3f1 100644 --- a/libisofs/libisofs.h +++ b/libisofs/libisofs.h @@ -1286,7 +1286,9 @@ int iso_write_opts_set_aaip(IsoWriteOpts *opts, int enable); * Omit the version number (";1") at the end of the ISO-9660 identifiers. * This breaks ECMA-119 specification, but version numbers are usually not * used, so it should work on most systems. Use with caution. - * + * @param omit + * bit0= omit version number with ECMA-119 and Joliet + * bit1= omit version number with Joliet alone (@since 0.6.30) * @since 0.6.2 */ int iso_write_opts_set_omit_version_numbers(IsoWriteOpts *opts, int omit); @@ -1324,6 +1326,9 @@ int iso_write_opts_set_max_37_char_filenames(IsoWriteOpts *opts, int allow); * extension. libisofs adds it if original filename doesn't has one. Set * this to 1 to prevent this behavior. * This breaks ECMA-119 specification. Use with caution. + * @param no + * bit0= no forced dot with ECMA-119 + * bit1= no forced dot with Joliet (@since 0.6.30) * * @since 0.6.2 */ diff --git a/libisofs/util.c b/libisofs/util.c index 823d5d1..6017a2e 100644 --- a/libisofs/util.c +++ b/libisofs/util.c @@ -908,7 +908,10 @@ ex:; return retval; } -uint16_t *iso_j_file_id(const uint16_t *src) +/* + bit0= no_force_dots +*/ +uint16_t *iso_j_file_id(const uint16_t *src, int flag) { uint16_t *dot; size_t lname, lext, lnname, lnext, pos, i; @@ -954,6 +957,10 @@ uint16_t *iso_j_file_id(const uint16_t *src) pos++; } } + + if ((flag & 1) && lnext <= 0) + goto is_done; + set_ucsbe(dest + pos, '.'); pos++; @@ -967,6 +974,8 @@ uint16_t *iso_j_file_id(const uint16_t *src) pos++; } } + +is_done:; set_ucsbe(dest + pos, '\0'); return ucsdup(dest); } diff --git a/libisofs/util.h b/libisofs/util.h index 4f28a1e..e8f3c45 100644 --- a/libisofs/util.h +++ b/libisofs/util.h @@ -151,11 +151,12 @@ char *iso_r_fileid(const char *src, size_t len, int relaxed, int forcedot); * 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 * @return * NULL if the original name and extension both are of length 0. */ -uint16_t *iso_j_file_id(const uint16_t *src); +uint16_t *iso_j_file_id(const uint16_t *src, int flag); /** * Create a Joliet directory identifier that consists of name and optionally