diff --git a/doc/susp_aaip_isofs_names.txt b/doc/susp_aaip_isofs_names.txt index 37e3cad..970bb14 100644 --- a/doc/susp_aaip_isofs_names.txt +++ b/doc/susp_aaip_isofs_names.txt @@ -8,7 +8,7 @@ The following names are defined for AAIP namespace "isofs." as mentioned in -specification AAIP 1.0 : +specification of AAIP : ------------------------------------------------------------------------------- @@ -34,3 +34,25 @@ Registered: ------------------------------------------------------------------------------- +Name: + isofs.cs + +Purpose: + Records the name of the character set that was used as output character + set when writing the RRIP name tree of the ISO 9660 image. It shall be + suitable as parameter for function iconv_open(3). + This attribute shall eventually be attached to the root directory entry + and be global for the whole image. + +Format of Value: + Shall hold the character set name without terminating 0-byte. + +Example: + { 'I', 'S', 'O', '-', '8', '8', '5', '9' , '-', '1' } + +Registered: + 18 Mar 2009 by Thomas Schmitt for libisofs. + +------------------------------------------------------------------------------- +------------------------------------------------------------------------------- + diff --git a/libisofs/fs_image.c b/libisofs/fs_image.c index e3e9b03..d486b7d 100644 --- a/libisofs/fs_image.c +++ b/libisofs/fs_image.c @@ -19,6 +19,7 @@ #include "image.h" #include "tree.h" #include "eltorito.h" +#include "node.h" #include "aaip_0_2.h" #include @@ -26,6 +27,7 @@ #include #include #include +#include /** @@ -77,6 +79,16 @@ struct iso_read_opts * Input charset for RR file names. NULL to use default locale charset. */ char *input_charset; + + /* ts A90319 */ + /** + * Enable or disable methods to automatically choose an input charset. + * This eventually overrides input_charset. + * + * bit0= allow to set the input character set automatically from + * attribute "isofs.cs" of root directory + */ + int auto_input_charset; }; /** @@ -112,7 +124,7 @@ static int ifs_fs_open(IsoImageFilesystem *fs); static int ifs_fs_close(IsoImageFilesystem *fs); static int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent, struct ecma119_dir_record *record, - IsoFileSource **src); + IsoFileSource **src, int falg); /** unique identifier for each image */ unsigned int fs_dev_id = 0; @@ -154,6 +166,16 @@ typedef struct char *input_charset; /**< Input charset for RR names */ char *local_charset; /**< For RR names, will be set to the locale one */ + /* ts A90319 */ + /** + * Enable or disable methods to automatically choose an input charset. + * This eventually overrides input_charset. + * + * bit0= allow to set the input character set automatically from + * attribute "isofs.cs" of root directory + */ + int auto_input_charset; + /** * Will be filled with the block lba of the extend for the root directory * of the hierarchy that will be read, either from the PVD (ISO, RR) or @@ -463,7 +485,7 @@ int read_dir(ImageFileSourceData *data) * We pass a NULL parent instead of dir, to prevent the circular * reference from child to parent. */ - ret = iso_file_source_new_ifs(fs, NULL, record, &child); + ret = iso_file_source_new_ifs(fs, NULL, record, &child, 0); if (ret < 0) { if (child) { /* @@ -1047,6 +1069,12 @@ ino_t fs_give_ino_number(IsoImageFilesystem *fs, int flag) * @param src * if not-NULL, it points to a multi-extent file returned by a previous * call to this function. + * + * ts A90320 + * @param flag + * bit0= this is the root node attribute load call + * (parameter parent is not reliable for this) + * * @return * 2 node is still incomplete (multi-extent) * 1 success, 0 record ignored (not an error, can be a relocated dir), @@ -1055,7 +1083,7 @@ ino_t fs_give_ino_number(IsoImageFilesystem *fs, int flag) static int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent, struct ecma119_dir_record *record, - IsoFileSource **src) + IsoFileSource **src, int flag) { int ret; struct stat atts; @@ -1077,6 +1105,10 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent, unsigned char *aa_string = NULL; size_t aa_size = 0, aa_len = 0, prev_field = 0; int aa_done = 0; + char *cs_value = NULL; + size_t cs_value_length = 0; + char msg[160]; + if (fs == NULL || fs->data == NULL || record == NULL || src == NULL) { return ISO_NULL_POINTER; @@ -1298,7 +1330,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent, * Ignore this, to prevent the hint message, if we are dealing * with root node (SP is only valid in "." of root node) */ - if (parent != NULL) { + if (!(flag & 1)) { /* notify and continue */ ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR, 0, "SP entry found in a directory entry other " @@ -1310,7 +1342,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent, * Ignore this, to prevent the hint message, if we are dealing * with root node (ER is only valid in "." of root node) */ - if (parent != NULL) { + if (!(flag & 1)) { /* notify and continue */ ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR, 0, "ER entry found in a directory entry other " @@ -1375,6 +1407,28 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent, return ret; } + /* ts A90319 */ + if ((flag & 1) && aa_string != NULL) { + ret = iso_aa_lookup_attr(aa_string, "isofs.cs", + &cs_value_length, &cs_value, 0); + if (ret == 1) { + if (fsdata->auto_input_charset & 1) { + if (fsdata->input_charset != NULL) + free(fsdata->input_charset); + fsdata->input_charset = cs_value; + sprintf(msg, + "Learned from ISO image: input character set '%.80s'", + cs_value); + } else { + sprintf(msg, + "Character set name recorded in ISO image: '%.80s'", + cs_value); + } + iso_msgs_submit(0, msg, 0, "NOTE", 0); + cs_value = NULL; + } + } + /* convert name to needed charset */ if (strcmp(fsdata->input_charset, fsdata->local_charset) && name) { /* we need to convert name charset */ @@ -1483,7 +1537,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent, } ret = iso_file_source_new_ifs(fs, parent, (struct ecma119_dir_record*) - buffer, src); + buffer, src, 0); if (ret <= 0) { return ret; } @@ -1666,7 +1720,7 @@ int ifs_get_root(IsoFilesystem *fs, IsoFileSource **root) /* get root attributes from "." entry */ *root = NULL; ret = iso_file_source_new_ifs((IsoImageFilesystem*)fs, NULL, - (struct ecma119_dir_record*) buffer, root); + (struct ecma119_dir_record*) buffer, root, 1); ifs_fs_close((IsoImageFilesystem*)fs); return ret; @@ -2339,6 +2393,8 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts, ret = ISO_OUT_OF_MEM; goto fs_cleanup; } + /* ts A90319 */ + data->auto_input_charset = opts->auto_input_charset; /* and finally return. Note that we keep the DataSource opened */ @@ -3078,6 +3134,15 @@ int iso_read_opts_set_input_charset(IsoReadOpts *opts, const char *charset) return ISO_SUCCESS; } +int iso_read_opts_auto_input_charset(IsoReadOpts *opts, int mode) +{ + if (opts == NULL) { + return ISO_NULL_POINTER; + } + opts->auto_input_charset = mode; + return ISO_SUCCESS; +} + /** * Destroy an IsoReadImageFeatures object obtained with iso_image_import. */ diff --git a/libisofs/libisofs.h b/libisofs/libisofs.h index 9958898..9b4dd0d 100644 --- a/libisofs/libisofs.h +++ b/libisofs/libisofs.h @@ -1162,8 +1162,8 @@ int iso_write_opts_set_iso1999(IsoWriteOpts *opts, int enable); * (e.g. the local POSIX filesystem) see iso_image_set_ignore_aclea(). * For loading of this information from images see iso_read_opts_set_no_aaip(). * - * @param enable 1 = do not read AAIP information - * 0 = read AAIP information if available + * @param enable 1 = write AAIP information from nodes into the image + * 0 = do not write AAIP information into the image * All other values are reserved. * @since 0.6.14 */ @@ -1677,6 +1677,29 @@ int iso_read_opts_set_default_permissions(IsoReadOpts *opts, mode_t file_perm, */ int iso_read_opts_set_input_charset(IsoReadOpts *opts, const char *charset); + +/* ts A90319 */ +#define Libisofs_has_auto_input_charseT yes +/** + * Enable or disable methods to automatically choose an input charset. + * This eventually overrides the name set via iso_read_opts_set_input_charset() + * + * @param mode + * Bitfield for control purposes: + * bit0= Allow to use the input character set name which is eventually + * stored in attribute "isofs.cs" of the root directory. + * Applications may attach this xattr by iso_node_set_attrs() to + * the root node, call iso_write_opts_set_output_charset() with the + * same name and enable iso_write_opts_set_aaip() when writing + * an image. + * Submit any other bits with value 0. + * + * @since 0.6.18 + * + */ +int iso_read_opts_auto_input_charset(IsoReadOpts *opts, int mode); + + /** * Import a previous session or image, for growing or modify. * @@ -4394,7 +4417,7 @@ mode_t iso_node_get_perms_wo_acl(const IsoNode *node); * @param value_lengths * Will return an arry with the lenghts of values * @param values - * Will return an array of pointers to 8-bit values + * Will return an array of pointers to strings of 8-bit bytes * @param flag * Bitfield for control purposes * bit0= obtain eventual ACLs as attribute with empty name @@ -4434,7 +4457,7 @@ int iso_node_get_attrs(IsoNode *node, size_t *num_attrs, * bit1= Do not clear the existing attribute list but merge it with * the list given by this call * bit2= Delete the attributes with the given names - * bit3= Allow non-user attributes. + * bit3= Allow to affect non-user attributes. * I.e. those with a non-empty name which does not begin by "user." * (The empty name is always allowed and governed by bit0.) This * deletes all previously existing attributes if not bit1 is set. @@ -4806,6 +4829,11 @@ struct burn_source { #define Libisofs_avoid_using_allocA yes +/* Cleanup : make call setlocale() at init time resp. never +*/ +#define Libisofs_setlocale_in_iniT yes + + /* ---------------------------- Experiments ---------------------------- */ @@ -4840,11 +4868,7 @@ struct burn_source { They can print errno messages and they can avoid iconv() if the identical mapping is desired. One could install own simple conversion capabilities. - #define Libisofs_with_iso_iconV yes */ - -/* Cleanup : make call setlocale() at init time resp. never -*/ -#define Libisofs_setlocale_in_iniT yes +#define Libisofs_with_iso_iconV yes #endif /*LIBISO_LIBISOFS_H_*/ diff --git a/libisofs/messages.c b/libisofs/messages.c index ef4c5bc..a1d4b3f 100644 --- a/libisofs/messages.c +++ b/libisofs/messages.c @@ -64,9 +64,13 @@ struct libiso_msgs *libiso_msgr = NULL; */ int iso_init_with_flag(int flag) { + +#ifdef Libisofs_setlocale_in_iniT if (! (flag & 1)) { iso_init_locale(0); } +#endif + if (libiso_msgr == NULL) { if (libiso_msgs_new(&libiso_msgr, 0) <= 0) return ISO_FATAL_ERROR; diff --git a/libisofs/node.c b/libisofs/node.c index 4f31335..ad3f141 100644 --- a/libisofs/node.c +++ b/libisofs/node.c @@ -1375,7 +1375,6 @@ int attrs_cleanout_name(char *del_name, size_t *num_attrs, char **names, * AA string from where to get the attribute list. * All other parameter specs apply. */ -static int iso_aa_get_attrs(unsigned char *aa_string, size_t *num_attrs, char ***names, size_t **value_lengths, char ***values, int flag) { @@ -1447,6 +1446,43 @@ ex:; } +/* ts A90319 */ +/** + * Search given name. Eventually calloc() and copy value. Add trailing 0 byte + * for caller convenience. + * + * @return 1= found , 0= not found , <0 error + */ +int iso_aa_lookup_attr(unsigned char *aa_string, char *name, + size_t *value_length, char **value, int flag) +{ + size_t num_attrs = 0, *value_lengths = NULL; + char **names = NULL, **values = NULL; + int i, ret = 0; + + ret = iso_aa_get_attrs(aa_string, &num_attrs, &names, + &value_lengths, &values, 0); + for (i = 0; i < num_attrs; i++) { + if (strcmp(names[i], name)) + continue; + *value_length = value_lengths[i]; + *value = calloc(*value_length + 1, 1); + if (*value == NULL) { + ret = ISO_OUT_OF_MEM; + break; + } + if (*value_length > 0) + memcpy(*value, values[i], *value_length); + (*value)[*value_length] = 0; + ret = 1; + break; + } + iso_aa_get_attrs(aa_string, &num_attrs, &names, + &value_lengths, &values, 1 << 15); + return ret; +} + + int iso_node_get_attrs(IsoNode *node, size_t *num_attrs, char ***names, size_t **value_lengths, char ***values, int flag) { diff --git a/libisofs/node.h b/libisofs/node.h index 503fb81..ef41274 100644 --- a/libisofs/node.h +++ b/libisofs/node.h @@ -348,4 +348,22 @@ int iso_node_set_perms_internal(IsoNode *node, mode_t mode, int flag); int iso_aa_get_acl_text(unsigned char *aa_string, mode_t st_mode, char **access_text, char **default_text, int flag); +/** + * Backend of iso_node_get_attrs() with parameter node replaced by the + * AA string from where to get the attribute list. + * All other parameter specs apply. + */ +int iso_aa_get_attrs(unsigned char *aa_string, size_t *num_attrs, + char ***names, size_t **value_lengths, char ***values, int flag); + +/** + * Search given name. Eventually calloc() and copy value. Add trailing 0 byte + * for caller convenience. + * + * @return 1= found , 0= not found , <0 error + */ +int iso_aa_lookup_attr(unsigned char *aa_string, char *name, + size_t *value_length, char **value, int flag); + + #endif /*LIBISO_NODE_H_*/