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:
Thomas Schmitt 2009-03-20 17:48:42 +01:00
parent da2619c42a
commit 0402325ec2
6 changed files with 187 additions and 18 deletions

View File

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

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