diff --git a/libisofs/ecma119.c b/libisofs/ecma119.c index 6c08a78..e49ad8c 100644 --- a/libisofs/ecma119.c +++ b/libisofs/ecma119.c @@ -291,6 +291,27 @@ void write_one_dir_record(Ecma119Image *t, Ecma119Node *node, int file_id, } } +static +char *get_relaxed_vol_id(Ecma119Image *t, const char *name) +{ + int ret; + if (name == NULL) { + return NULL; + } + if (strcmp(t->input_charset, t->output_charset)) { + /* charset conversion needed */ + char *str; + ret = strconv(name, t->input_charset, t->output_charset, &str); + if (ret == ISO_SUCCESS) { + return str; + } + iso_msg_submit(t->image->id, ISO_FILENAME_WRONG_CHARSET, ret, + "Charset conversion error. Can't convert %s from %s to %s", + name, t->input_charset, t->output_charset); + } + return strdup(name); +} + /** * Write the Primary Volume Descriptor (ECMA-119, 8.4) */ @@ -316,11 +337,15 @@ int ecma119_writer_write_vol_desc(IsoImageWriter *writer) memset(&vol, 0, sizeof(struct ecma119_pri_vol_desc)); - str2d_char(t->input_charset, image->volume_id, &vol_id); + if (t->relaxed_vol_atts) { + vol_id = get_relaxed_vol_id(t, image->volume_id); + volset_id = get_relaxed_vol_id(t, image->volset_id); + } else { + str2d_char(t->input_charset, image->volume_id, &vol_id); + str2d_char(t->input_charset, image->volset_id, &volset_id); + } str2a_char(t->input_charset, image->publisher_id, &pub_id); str2a_char(t->input_charset, image->data_preparer_id, &data_id); - str2d_char(t->input_charset, image->volset_id, &volset_id); - str2a_char(t->input_charset, image->system_id, &system_id); str2a_char(t->input_charset, image->application_id, &application_id); str2d_char(t->input_charset, image->copyright_file_id, ©right_file_id); @@ -838,6 +863,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img) target->no_force_dots = opts->no_force_dots; target->allow_lowercase = opts->allow_lowercase; 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->sort_files = opts->sort_files; @@ -1386,6 +1412,15 @@ int iso_write_opts_set_allow_full_ascii(IsoWriteOpts *opts, int allow) return ISO_SUCCESS; } +int iso_write_opts_set_relaxed_vol_atts(IsoWriteOpts *opts, int allow) +{ + if (opts == NULL) { + return ISO_NULL_POINTER; + } + opts->relaxed_vol_atts = allow ? 1 : 0; + return ISO_SUCCESS; +} + int iso_write_opts_set_joliet_longer_paths(IsoWriteOpts *opts, int allow) { if (opts == NULL) { diff --git a/libisofs/ecma119.h b/libisofs/ecma119.h index 7aa2bb2..ffb1611 100644 --- a/libisofs/ecma119.h +++ b/libisofs/ecma119.h @@ -81,6 +81,13 @@ struct iso_write_opts { */ unsigned int allow_full_ascii :1; + /** + * Allow all characters to be part of Volume and Volset identifiers on + * the Primary Volume Descriptor. This breaks ISO-9660 contraints, but + * should work on modern systems. + */ + unsigned int relaxed_vol_atts :1; + /** * Allow paths in the Joliet tree to have more than 240 characters. */ @@ -222,6 +229,8 @@ struct ecma119_image unsigned int allow_lowercase :1; unsigned int allow_full_ascii :1; + unsigned int relaxed_vol_atts : 1; + /** Allow paths on Joliet tree to be larger than 240 bytes */ unsigned int joliet_longer_paths :1; diff --git a/libisofs/fs_image.c b/libisofs/fs_image.c index 415f838..72cff22 100644 --- a/libisofs/fs_image.c +++ b/libisofs/fs_image.c @@ -1638,6 +1638,7 @@ int read_pvm(_ImageFsData *data, uint32_t block) /* ok, it is a valid PVD */ /* fill volume attributes */ + /* TODO take care of input charset */ data->volset_id = strcopy((char*)pvm->vol_set_id, 128); data->volume_id = strcopy((char*)pvm->volume_id, 32); data->publisher_id = strcopy((char*)pvm->publisher_id, 128); diff --git a/libisofs/libisofs.h b/libisofs/libisofs.h index f94d4d4..a871d26 100644 --- a/libisofs/libisofs.h +++ b/libisofs/libisofs.h @@ -919,6 +919,15 @@ int iso_write_opts_set_allow_lowercase(IsoWriteOpts *opts, int allow); */ int iso_write_opts_set_allow_full_ascii(IsoWriteOpts *opts, int allow); +/** + * Allow all characters to be part of Volume and Volset identifiers on + * the Primary Volume Descriptor. This breaks ISO-9660 contraints, but + * should work on modern systems. + * + * @since 0.6.2 + */ +int iso_write_opts_set_relaxed_vol_atts(IsoWriteOpts *opts, int allow); + /** * Allow paths in the Joliet tree to have more than 240 characters. * This breaks Joliet specification. Use with caution.