New API call iso_read_opts_auto_input_charset() allows to obtain

the image tree character set name from root xattr "isofs.cs".
This commit is contained in:
2009-03-20 17:48:42 +01:00
parent da2619c42a
commit 0402325ec2
6 changed files with 187 additions and 18 deletions

View File

@ -19,6 +19,7 @@
#include "image.h"
#include "tree.h"
#include "eltorito.h"
#include "node.h"
#include "aaip_0_2.h"
#include <stdlib.h>
@ -26,6 +27,7 @@
#include <locale.h>
#include <langinfo.h>
#include <limits.h>
#include <stdio.h>
/**
@ -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.
*/

View File

@ -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_*/

View File

@ -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;

View File

@ -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)
{

View File

@ -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_*/