Switched from AAIP-1.0 with field "AA" to AAIP-2.0 with field "AL"

because ancient Apple ISO 9660 already used "AA".
Old AAIP-1.0 enhanced images can still be read and luckily their AAIP fields
can be distinguished from eventual Apple AA fields.
This commit is contained in:
2009-03-31 11:40:58 +02:00
parent d28351c5a4
commit 21de3e2087
11 changed files with 313 additions and 154 deletions

View File

@ -1,7 +1,7 @@
/*
Arbitrary Attribute Interchange Protocol , AAIP versions 0.2 and 1.0.
Arbitrary Attribute Interchange Protocol , AAIP versions 0.2 , 1.0 , 2.0.
Implementation of encoding and decoding xattr and ACL.
See test/aaip_0_2.h
@ -21,6 +21,8 @@
#include <grp.h>
#include <sys/stat.h>
#include "libisofs.h"
/* <<<
*/
#define Aaip_encode_debuG 1
@ -80,7 +82,7 @@ static int aaip_encode_pair(char *name, size_t attr_length, char *attr,
This is malloc() memory which needs to be freed when
no longer needed
@param flag Bitfield for control purposes
bit0= set CONTINUE bit of last AA field to 1
bit0= set CONTINUE bit of last AAIP field to 1
@return >0 is the number of SUSP fields generated,
0 means error
*/
@ -126,7 +128,13 @@ size_t aaip_encode(size_t num_attrs, char **names,
/* write the field headers */
for(i= 0; i < number_of_fields; i++) {
(*result)[i * 255 + 0]= 'A';
#ifdef Libisofs_aaip_2_0
(*result)[i * 255 + 1]= 'L';
#else /* Libisofs_aaip_2_0 */
(*result)[i * 255 + 1]= 'A';
#endif /* ! Libisofs_aaip_2_0 */
if(i < number_of_fields - 1 || (mem_size % 255) == 0)
(*result)[i * 255 + 2]= 255;
else
@ -200,7 +208,7 @@ static int aaip_encode_comp(unsigned char *result, size_t *result_fill,
/* Write the component records for name and attr. Skip the positions of
AA field headers.
AAIP field headers.
@param flag bit0= only count but do not produce result
*/
static int aaip_encode_pair(char *name, size_t attr_length, char *attr,
@ -818,11 +826,11 @@ int aaip_add_acl_st_mode(char *acl_text, mode_t st_mode, int flag)
struct aaip_state {
/* AA field status */
int aa_head_missing; /* number of bytes needed to complete AA field header */
int aa_missing; /* number of bytes needed to complete current AA field */
int aa_ends; /* 0= still AA fields expected, 1= last AA being processed,
2= all AA fields processed, 3= all is delivered */
/* AAIP field status */
int aa_head_missing; /* number of bytes needed to complete field header */
int aa_missing; /* number of bytes needed to complete current field */
int aa_ends; /* 0= still fields expected, 1= last field being processed,
2= all fields processed, 3= all is delivered */
/* Buffer for component records */
int recs_invalid; /* number of components to skip */
@ -1178,11 +1186,19 @@ static int aaip_consume_aa_head(struct aaip_state *aaip,
aaip->aa_head_missing-= todo;
if(aaip->aa_head_missing == 0) {
aaip_read_from_recs(aaip, aaip->recs_fill - 5, aa_head, 5, 0);
#ifdef Libisofs_aaip_2_0
if(aa_head[0] != 'A' || (aa_head[1] != 'L' && aa_head[1] != 'A') ||
aa_head[3] != 1)
return(-1);
#else /* Libisofs_aaip_2_0 */
if(aa_head[0] != 'A' || aa_head[1] != 'A' || aa_head[3] != 1)
return(-1);
#endif /* ! Libisofs_aaip_2_0 */
aaip->aa_missing= aa_head[2];
aaip->aa_ends= !(aa_head[4] & 1);
aaip->recs_fill-= 5; /* AA heads do not get delivered */
aaip->recs_fill-= 5; /* AAIP field heads do not get delivered */
if(aaip->aa_missing >= 5)
aaip->aa_missing-= 5;
else
@ -1262,7 +1278,7 @@ static int aaip_consume_aa_data(struct aaip_state *aaip,
0 inquires the buffer status avoiding replies <= 0
@param ready_bytes Number of decoded bytes ready for delivery
@param flag Bitfield for control purposes
@return -1= non-AA field detected
@return -1= non-AAIP field detected
*ready_bytes gives number of consumed bytes in data
0= cannot accept data because buffer full
1= no component record complete, submit more data
@ -1506,7 +1522,7 @@ retry:;
@return <0 error
-3 buffer full (program error)
-2 insufficient result_size (only with flag bit0)
-1 non-AA field detected
-1 non-AAIP field detected
0 data not accepted, first fetch pending pairs with num_data == 0
1 name and value are not valid yet, submit more data
2 name and value are valid, submit more data
@ -1521,7 +1537,7 @@ int aaip_decode_pair(struct aaip_state *aaip,
int flag)
{
int ret;
size_t ready_bytes;
size_t ready_bytes= 0;
#ifdef Aaip_with_short_namespaceS
char prefix[Aaip_max_name_expansioN + 1];
@ -1552,7 +1568,7 @@ int aaip_decode_pair(struct aaip_state *aaip,
else if(aaip->num_recs)
ret= 2;
}
if(ret < 0) { /* non-AA field detected */
if(ret < 0) { /* non-AAIP field detected */
*consumed= ready_bytes;
{ret= -1; goto ex;}
} else if(ret == 0) { /* buffer overflow */;
@ -1673,8 +1689,9 @@ static int aaip_enlarge_buf(struct aaip_state *aaip, size_t memory_limit,
bit15= end decoding :
Free handle and its intermediate list memory.
@return <=0 error
-4 interpretation stalled, no valid result
-3 program error, unexpected reply from lower layers
-2 non-AA-field detected, arrays are complete,
-2 non-AAIP-field detected, arrays are complete,
call aaip_get_decoded_attrs()
-1 out of memory
1 not complete yet, submit more data
@ -1776,8 +1793,10 @@ int aaip_decode_attrs(struct aaip_state **handle,
if(ret != 1)
return(ret);
} else if(ret == -1) { /* non-AA field detected */
} else if(ret == -1) { /* non-AAIP field detected */
was_non_aa= 1;
if(pair_consumed <= 0)
return(-4); /* interpretation did not advance */
} else if(ret < 0) { /* other error */
return(-3);

View File

@ -29,7 +29,7 @@
This is malloc() memory which needs to be freed when
no longer needed
@param flag Bitfield for control purposes
bit0= set CONTINUE bit of last AA field to 1
bit0= set CONTINUE bit of last AAIP field to 1
@return >0 is the number of SUSP fields generated,
0 means error
*/
@ -207,15 +207,16 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
attribute lists but may also be used as alternative to Pair Level.
*/
/* Operations on complete AA field strings which need no decoder context.
These function expect to get submitted a complete chain of AA fields.
/* Operations on complete AAIP field strings which need no decoder context.
These function expect to get submitted a complete chain of AAIP fields.
*/
/* Determine the size of the AA string by interpreting the SUSP structure.
/* Determine the size of the AAIP string by interpreting the SUSP structure.
@param data An arbitrary number of bytes beginning with the
complete chain of AA fields. Trailing trash is ignored.
complete chain of AAIP fields. Trailing trash is
ignored.
@param flag Unused yet. Submit 0.
@return The number of bytes of the AA field chain.
@return The number of bytes of the AAIP field chain.
*/
size_t aaip_count_bytes(unsigned char *data, int flag);
@ -231,7 +232,7 @@ size_t aaip_sizeof_aaip_state(void);
/* Initialize a AAIP decoder context.
This has to be done before the first AA field of a node is processed.
This has to be done before the first AAIP field of a node is processed.
The caller has to provide the storage of the struct aaip_state.
@param aaip The AAIP decoder context to be initialized
@param flag Bitfield for control purposes
@ -259,7 +260,7 @@ int aaip_init_aaip_state(struct aaip_state *aaip, int flag);
0 inquires the buffer status avoiding replies <= 0
@param ready_bytes Number of decoded bytes ready for delivery
@param flag Bitfield for control purposes
@return -1= non-AA field detected
@return -1= non-AAIP field detected
*ready_bytes gives number of consumed bytes in data
0= cannot accept data because buffer full
1= no component record complete, submit more data

View File

@ -197,7 +197,7 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
1 << 15); /* free ACL texts */
}
/* Obtain ownership of eventual AA string */
/* Obtain ownership of eventual AAIP string */
ret = iso_file_source_get_aa_string(src, &aa_string,
1 | (image->builder_ignore_acl << 1) |
(image->builder_ignore_ea << 2 ));

View File

@ -306,7 +306,7 @@ struct image_fs_data
} data;
/**
* malloc() storage for the string of AA fields which represent
* malloc() storage for the string of AAIP fields which represent
* ACLs and XFS-style Extended Attributes. (Not to be confused with
* ECMA-119 Extended Attributes.)
*/
@ -1350,8 +1350,8 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
}
continue;
/* Need to read AA in any case so it is available for S_IRWXG
mapping in case that fsdata->aaip_load != 1
/* Need to read AA resp. AL in any case so it is available for
S_IRWXG mapping in case that fsdata->aaip_load != 1
*/
} else if (SUSP_SIG(sue, 'A', 'A')) {
@ -1364,10 +1364,17 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
continue;
}
/* >>> AAIP-2 :
SUSP_SIG(sue, 'A', 'L')
read_aaip_AL() like read_aaip_AA()
*/
} else if (SUSP_SIG(sue, 'A', 'L')) {
ret = read_aaip_AL(sue, &aa_string, &aa_size, &aa_len,
&prev_field, &aa_done, 0);
if (ret < 0) {
/* notify and continue */
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR_WARN, ret,
"Invalid AL entry");
continue;
}
/* This message is inflationary */
/*
@ -2024,13 +2031,15 @@ int read_root_susp_entries(_ImageFsData *data, uint32_t block)
} else if (sue->data.ER.len_id[0] == 9 &&
(strncmp((char*)sue->data.ER.ext_id, "AAIP_0002", 9) == 0 ||
strncmp((char*)sue->data.ER.ext_id, "AAIP_0100", 9) == 0)) {
strncmp((char*)sue->data.ER.ext_id, "AAIP_0100", 9) == 0 ||
strncmp((char*)sue->data.ER.ext_id, "AAIP_0200", 9) == 0)) {
/* Tolerate AAIP ER even if not supported */
iso_msg_debug(data->msgid,
"Suitable AAIP ER found.");
iso_msg_debug(data->msgid, "Suitable AAIP ER found.");
if (((char*)sue->data.ER.ext_id)[6] == '1')
if (strncmp((char*)sue->data.ER.ext_id, "AAIP_0200", 9) == 0)
data->aaip_version = 200;
else if (((char*)sue->data.ER.ext_id)[6] == '1')
data->aaip_version = 100;
else
data->aaip_version = 2;
@ -2424,7 +2433,7 @@ int src_aa_to_node(IsoFileSource *src, IsoNode *node, int flag)
data = (ImageFileSourceData*)src->data;
fsdata = data->fs->data;
/* Obtain ownership of eventual AA string */
/* Obtain ownership of eventual AAIP string */
ret = iso_file_source_get_aa_string(src, &aa_string, 1);
if (ret != 1 || aa_string == NULL)
return 1;

View File

@ -685,7 +685,7 @@ struct IsoFileSource_Iface
/**
* Valid only if .version is > 0. See above.
* Get the AA string with encoded ACL and xattr.
* Get the AAIP string with encoded ACL and xattr.
* (Not to be confused with ECMA-119 Extended Attributes).
*
* bit1 and bit2 of flag should be implemented so that freshly fetched
@ -694,14 +694,14 @@ struct IsoFileSource_Iface
* delivered.
*
* @param flag Bitfield for control purposes
* bit0= Transfer ownership of AA string data.
* bit0= Transfer ownership of AAIP string data.
* src will free the eventual cached data and might
* not be able to produce it again.
* bit1= No need to get ACL (no guarantee of exclusion)
* bit2= No need to get xattr (no guarantee of exclusion)
* @param aa_string Returns a pointer to the AA string data. If no AA
* @param aa_string Returns a pointer to the AAIP string data. If no AAIP
* string is available, *aa_string becomes NULL.
* (See doc/susp_aaip_0_2.txt for the meaning of AA and
* (See doc/susp_aaip_*_*.txt for the meaning of AAIP and
* libisofs/aaip_0_2.h for encoding and decoding.)
* The caller is responsible for finally calling free()
* on non-NULL results.
@ -1286,7 +1286,7 @@ int iso_write_opts_set_rrip_version_1_10(IsoWriteOpts *opts, int oldvers);
/**
* Write AAIP as extension according to SUSP 1.10 rather than SUSP 1.12.
* I.e. without announcing it by an ER field and thus without the need
* to preceed the RRIP fields and the AA field by ES fields.
* to preceed the RRIP fields and the AAIP field by ES fields.
* This saves 5 to 10 bytes per file and might avoid problems with readers
* which dislike ER fields other than the ones for RRIP.
* On the other hand, SUSP 1.12 frowns on such unannounced extensions
@ -3824,17 +3824,17 @@ int iso_file_source_readlink(IsoFileSource *src, char *buf, size_t bufsiz);
/**
* Get the AA string with encoded ACL and xattr.
* Get the AAIP string with encoded ACL and xattr.
* (Not to be confused with ECMA-119 Extended Attributes).
* @param src The file source object to be inquired.
* @param aa_string Returns a pointer to the AA string data. If no AA
* @param aa_string Returns a pointer to the AAIP string data. If no AAIP
* string is available, *aa_string becomes NULL.
* (See doc/susp_aaip_0_2.txt for the meaning of AA and
* (See doc/susp_aaip_0_2.txt for the meaning of AAIP and
* libisofs/aaip_0_2.h for encoding and decoding.)
* The caller is responsible for finally calling free()
* on non-NULL results.
* @param flag Bitfield for control purposes
* bit0= Transfer ownership of AA string data.
* bit0= Transfer ownership of AAIP string data.
* src will free the eventual cached data and might
* not be able to produce it again.
* bit1= No need to get ACL (but no guarantee of exclusion)
@ -4330,15 +4330,16 @@ IsoStream *iso_stream_get_input_stream(IsoStream *stream, int flag);
/* --------------------------------- AAIP --------------------------------- */
/**
* Function to identify and manage AA strings as xinfo of IsoNode.
* Function to identify and manage AAIP strings as xinfo of IsoNode.
*
* An AA string contains the Attribute List with the xattr and ACL of a node
* An AAIP string contains the Attribute List with the xattr and ACL of a node
* in the image tree. It is formatted according to libisofs specification
* AAIP-1.0 and ready to be written into the System Use Area resp. Continuation
* Area of a directory entry in an ISO image.
*
* Applications are not supposed to manipulate AA strings directly. They should
* rather make use of the appropriate iso_node_get_* and iso_node_set_* calls.
* Applications are not supposed to manipulate AAIP strings directly.
* They should rather make use of the appropriate iso_node_get_* and
* iso_node_set_* calls.
*
* AAIP represents ACLs as xattr with empty name and AAIP-specific binary
* content. Local filesystems may represent ACLs as xattr with names like
@ -4977,6 +4978,9 @@ struct burn_source {
#define Libisofs_avoid_using_allocA yes
/* ---------------------------- Improvements --------------------------- */
/* Cleanup : make call setlocale() at init time resp. never
*/
#define Libisofs_setlocale_in_iniT yes
@ -4988,6 +4992,11 @@ struct burn_source {
#define Libisofs_file_src_cmp_sizE yes
/* Disambiguation : change to AAIP-2.0 with field signature "AL"
*/
#define Libisofs_aaip_2_0 yes
/* ---------------------------- Experiments ---------------------------- */

View File

@ -1372,7 +1372,7 @@ int attrs_cleanout_name(char *del_name, size_t *num_attrs, char **names,
/**
* Backend of iso_node_get_attrs() with parameter node replaced by the
* AA string from where to get the attribute list.
* AAIP 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,

View File

@ -350,7 +350,7 @@ int iso_aa_get_acl_text(unsigned char *aa_string, mode_t st_mode,
/**
* Backend of iso_node_get_attrs() with parameter node replaced by the
* AA string from where to get the attribute list.
* AAIP 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,

View File

@ -15,6 +15,7 @@
#include "messages.h"
#include "image.h"
#include "aaip_0_2.h"
#include "libisofs.h"
#include <string.h>
@ -505,7 +506,7 @@ int rrip_add_SL(Ecma119Image *t, struct susp_info *susp, uint8_t **comp,
parameters susp and data may be NULL in this case
*/
static
int aaip_add_AA(Ecma119Image *t, struct susp_info *susp,
int aaip_add_AL(Ecma119Image *t, struct susp_info *susp,
uint8_t **data, size_t num_data,
size_t *sua_free, size_t *ce_len, int flag)
{
@ -647,45 +648,46 @@ int rrip_add_ER(Ecma119Image *t, struct susp_info *susp)
static
int aaip_add_ER(Ecma119Image *t, struct susp_info *susp, int flag)
{
unsigned char *AA;
unsigned char *ER;
AA = malloc(160);
if (AA == NULL) {
ER = malloc(160);
if (ER == NULL) {
return ISO_OUT_OF_MEM;
}
AA[0] = 'E';
AA[1] = 'R';
AA[2] = 160;
AA[3] = 1;
AA[4] = 9;
AA[5] = 81;
AA[6] = 62;
AA[7] = 1;
ER[0] = 'E';
ER[1] = 'R';
ER[2] = 160;
ER[3] = 1;
ER[4] = 9;
ER[5] = 81;
ER[6] = 62;
ER[7] = 1;
#define Libisofs_aaip_1_0 yes
#ifdef Libisofs_aaip_1_0
#ifdef Libisofs_aaip_2_0
memcpy(AA + 8, "AAIP_0100", 9);
memcpy(AA + 17,
"AA PROVIDES VIA AAIP 1.0 SUPPORT FOR ARBITRARY FILE ATTRIBUTES"
memcpy(ER + 8, "AAIP_0200", 9);
memcpy(ER + 17,
"AL PROVIDES VIA AAIP 2.0 SUPPORT FOR ARBITRARY FILE ATTRIBUTES"
" IN ISO 9660 IMAGES", 81);
#else /* Libisofs_aaip_1_0 */
memcpy(AA + 8, "AAIP_0002", 9);
memcpy(AA + 17,
"AA PROVIDES VIA AAIP 0.2 SUPPORT FOR ARBITRARY FILE ATTRIBUTES"
" IN ISO 9660 IMAGES", 81);
#endif /* ! Libisofs_aaip_1_0 */
memcpy(AA + 98,
memcpy(ER + 98,
"PLEASE CONTACT THE LIBBURNIA PROJECT VIA LIBBURNIA-PROJECT.ORG",
62);
#else /* Libisofs_aaip_2_0 */
memcpy(ER + 8, "AAIP_0100", 9);
memcpy(ER + 17,
"AA PROVIDES VIA AAIP 1.0 SUPPORT FOR ARBITRARY FILE ATTRIBUTES"
" IN ISO 9660 IMAGES", 81);
memcpy(ER + 98,
"PLEASE CONTACT THE LIBBURNIA PROJECT VIA LIBBURNIA-PROJECT.ORG",
62);
#endif /* ! Libisofs_aaip_2_0 */
/** This always goes to continuation area */
return susp_append_ce(t, susp, AA);
return susp_append_ce(t, susp, ER);
}
@ -775,8 +777,8 @@ int aaip_xinfo_func(void *data, int flag)
/**
* Compute SUA lentgth and eventual Continuation Area length of field NM and
* eventually fields SL and AA. Because CA usage makes necessary the use of
* Compute SUA length and eventual Continuation Area length of field NM and
* eventually fields SL and AL. Because CA usage makes necessary the use of
* a CE entry of 28 bytes in SUA, this computation fails if not the 28 bytes
* are taken into account at start. In this case the caller should retry with
* bit0 set.
@ -789,7 +791,7 @@ int aaip_xinfo_func(void *data, int flag)
* -1= not enough SUA space for 28 bytes of CE entry
*/
static
int susp_calc_nm_sl_aa(Ecma119Image *t, Ecma119Node *n, size_t space,
int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
size_t *su_size, size_t *ce, int flag)
{
char *name;
@ -942,7 +944,7 @@ int susp_calc_nm_sl_aa(Ecma119Image *t, Ecma119Node *n, size_t space,
/* let the expert decide where to add num_aapt */
if (num_aapt > 0) {
sua_free = space - *su_size;
aaip_add_AA(t, NULL, NULL, num_aapt, &sua_free, ce, 1);
aaip_add_AL(t, NULL, NULL, num_aapt, &sua_free, ce, 1);
*su_size = space - sua_free;
if (*ce > 0 && !(flag & 1))
goto unannounced_ca;
@ -991,7 +993,7 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t space,
su_size += 5;
#ifdef Libisofs_with_rrip_rR
/* obsolete RR field (once in AAIP-1.09) */
/* obsolete RR field (once in RRIP-1.09) */
su_size += 5;
#endif
@ -1026,9 +1028,9 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t space,
if (type == 0) {
/* Try without CE */
ret = susp_calc_nm_sl_aa(t, n, space, &su_size, ce, 0);
ret = susp_calc_nm_sl_al(t, n, space, &su_size, ce, 0);
if (ret == 0) /* Retry with CE */
susp_calc_nm_sl_aa(t, n, space, &su_size, ce, 1);
susp_calc_nm_sl_al(t, n, space, &su_size, ce, 1);
} else {
@ -1110,7 +1112,7 @@ int add_aa_string(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
if (aapt == NULL)
return ISO_OUT_OF_MEM;
memcpy(aapt, xipt, num_aapt);
ret = aaip_add_AA(t, info, &aapt, num_aapt, sua_free, ce_len,
ret = aaip_add_AL(t, info, &aapt, num_aapt, sua_free, ce_len,
flag & 1);
if (ret < 0)
return ret;
@ -1264,12 +1266,12 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
sua_free = space - info->suf_len;
/* Try whether NM, SL, AA will fit into SUA */
/* Try whether NM, SL, AL will fit into SUA */
su_size_pd = info->suf_len;
ce_len_pd = ce_len;
ret = susp_calc_nm_sl_aa(t, n, space, &su_size_pd, &ce_len_pd, 0);
ret = susp_calc_nm_sl_al(t, n, space, &su_size_pd, &ce_len_pd, 0);
if (ret == 0) { /* Have to use CA. 28 bytes of CE are necessary */
susp_calc_nm_sl_aa(t, n, space, &su_size_pd, &ce_len_pd, 1);
susp_calc_nm_sl_al(t, n, space, &su_size_pd, &ce_len_pd, 1);
sua_free -= 28;
ce_is_predicted = 1;
}
@ -1493,7 +1495,7 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
}
}
/* Obtain AA field string from node
/* Obtain AAIP field string from node
and write it to directory entry or CE area.
*/
ret = ISO_SUCCESS;

View File

@ -118,14 +118,19 @@ struct rr_SL {
};
/** Arbitrary Attribute (AAIP, see doc/susp_aaip_1_0.txt) */
struct rr_AA {
/** Outdated Arbitrary Attribute (AAIP, see doc/susp_aaip_1_0.txt)
* It collided with pre-SUSP Apple AA field.
*/
struct aaip_AA {
uint8_t flags[1];
uint8_t comps[1];
};
/* >>> AAIP-2 : struct rr_AL like struct rr_AA */
/** Arbitrary Attribute (AAIP, see doc/susp_aaip_2_0.txt) */
struct aaip_AL {
uint8_t flags[1];
uint8_t comps[1];
};
/**
@ -146,10 +151,8 @@ struct susp_sys_user_entry
struct rr_NM NM;
struct rr_CL CL;
struct rr_SL SL;
struct rr_AA AA;
/* >>> AAIP-2 : struct rr_AL */
struct aaip_AA AA;
struct aaip_AL AL;
} data; /* 5 to 4+len_sue */
};
@ -283,8 +286,8 @@ int read_rr_PN(struct susp_sys_user_entry *pn, struct stat *st);
/**
* Collects the AA field string from single AA fields.
* (see doc/susp_aaip_0_2.txt)
* Collects the AAIP field string from single AAIP fields.
* (see doc/susp_aaip_1_0.txt)
* @param aa_string Storage location of the emerging string.
* Begin with *aa_string == NULL, or own malloc() storage.
* @param aa_size Current allocated size of aa_string.
@ -293,14 +296,24 @@ int read_rr_PN(struct susp_sys_user_entry *pn, struct stat *st);
* Begin with *aa_len == 0
* @param prev_field Returns the index of start of the previous field
* in the string.
* @param is_done The current completion state of the AA field string.
* @param is_done The current completion state of the AAIP field string.
* Fields will be ignored as soon as it is 1.
* Begin with *is_done == 0
* @param flag Unused yet. Submit 0.
* @return
* 1 on success, < 0 on error
*/
int read_aaip_AA(struct susp_sys_user_entry *sue,
unsigned char **aa_string, size_t *aa_size, size_t *aa_len,
size_t *prev_field, int *is_done, int flag);
/**
* Collects the AAIP field string from single AL fields.
* (see doc/susp_aaip_2_0.txt)
*/
int read_aaip_AL(struct susp_sys_user_entry *sue,
unsigned char **aa_string, size_t *aa_size, size_t *aa_len,
size_t *prev_field, int *is_done, int flag);
#endif /* LIBISO_ROCKRIDGE_H */

View File

@ -435,6 +435,8 @@ int read_rr_PN(struct susp_sys_user_entry *pn, struct stat *st)
}
/* AA is the field signature of AAIP versions < 2.0
*/
int read_aaip_AA(struct susp_sys_user_entry *sue,
unsigned char **aa_string, size_t *aa_size, size_t *aa_len,
size_t *prev_field, int *is_done, int flag)
@ -443,8 +445,7 @@ int read_aaip_AA(struct susp_sys_user_entry *sue,
if (*is_done) {
/* AAIP-2
To coexist with Apple ISO :
/* To coexist with Apple ISO :
Gracefully react on eventually trailing Apple AA
*/
if (sue->version[0] != 1 || sue->len_sue[0] == 7)
@ -457,8 +458,7 @@ int read_aaip_AA(struct susp_sys_user_entry *sue,
/* Eventually create or grow storage */
if (*aa_size == 0 || *aa_string == NULL) {
/* AAIP-2
Gracefully react on eventually leading Apple AA
/* Gracefully react on eventually leading Apple AA
*/
if (sue->version[0] != 1 || sue->len_sue[0] < 9) {
return ISO_SUCCESS;
@ -470,8 +470,7 @@ int read_aaip_AA(struct susp_sys_user_entry *sue,
} else if (*aa_len + sue->len_sue[0] > *aa_size) {
if (sue->version[0] != 1) {
/* AAIP-2
Apple ISO within the AAIP field group is not AAIP compliant
/* Apple ISO within the AAIP field group is not AAIP compliant
*/
return ISO_WRONG_RR;
}
@ -492,25 +491,92 @@ int read_aaip_AA(struct susp_sys_user_entry *sue,
/* Compose new SUSP header with signature aa[], cont == 0 */
aapt = *aa_string + *aa_len;
/* >>> AAIP-2
Change to new signature (AL ?)
*/
aapt[0] = 'A';
#ifdef Libisofs_aaip_2_0
aapt[1] = 'L';
#else /* Libisofs_aaip_2_0 */
aapt[1] = 'A';
#endif /* ! Libisofs_aaip_2_0 */
aapt[2] = sue->len_sue[0];
aapt[3] = 1;
aapt[4] = 0;
/* Append sue payload */
#ifdef Libisofs_aaip_2_0
memcpy(aapt + 5, sue->data.AL.comps, sue->len_sue[0] - 5);
*is_done = !(sue->data.AL.flags[0] & 1);
#else /* Libisofs_aaip_2_0 */
memcpy(aapt + 5, sue->data.AA.comps, sue->len_sue[0] - 5);
*is_done = !(sue->data.AA.flags[0] & 1);
#endif /* ! Libisofs_aaip_2_0 */
*aa_len += sue->len_sue[0];
return ISO_SUCCESS;
}
/* AL is the obsolete field signature of AAIP versions >= 2.0
*/
int read_aaip_AL(struct susp_sys_user_entry *sue,
unsigned char **aa_string, size_t *aa_size, size_t *aa_len,
size_t *prev_field, int *is_done, int flag)
{
unsigned char *aapt;
if (*is_done)
return ISO_WRONG_RR;
if (sue->version[0] != 1)
return ISO_WRONG_RR;
/* Eventually create or grow storage */
if (*aa_size == 0 || *aa_string == NULL) {
*aa_size = *aa_len + sue->len_sue[0];
*aa_string = calloc(*aa_size, 1);
*aa_len = 0;
} else if (*aa_len + sue->len_sue[0] > *aa_size) {
*aa_size += *aa_len + sue->len_sue[0];
*aa_string = realloc(*aa_string, *aa_size);
}
if (*aa_string == NULL)
return ISO_OUT_OF_MEM;
if (*aa_len > 0) {
/* Mark prev_field as being continued */
(*aa_string)[*prev_field + 4] = 1;
}
*prev_field = *aa_len;
/* Compose new SUSP header with signature aa[], cont == 0 */
aapt = *aa_string + *aa_len;
aapt[0] = 'A';
#ifdef Libisofs_aaip_2_0
aapt[1] = 'L';
#else /* Libisofs_aaip_2_0 */
aapt[1] = 'A';
#endif /* ! Libisofs_aaip_2_0 */
aapt[2] = sue->len_sue[0];
aapt[3] = 1;
aapt[4] = 0;
/* Append sue payload */
#ifdef Libisofs_aaip_2_0
memcpy(aapt + 5, sue->data.AL.comps, sue->len_sue[0] - 5);
*is_done = !(sue->data.AL.flags[0] & 1);
#else /* Libisofs_aaip_2_0 */
memcpy(aapt + 5, sue->data.AA.comps, sue->len_sue[0] - 5);
*is_done = !(sue->data.AA.flags[0] & 1);
#endif /* ! Libisofs_aaip_2_0 */
*aa_len += sue->len_sue[0];
*is_done = !(sue->data.AA.flags[0] & 1);
return ISO_SUCCESS;
}
/* >>> AAIP-2
read_aaip_AL() like read_aaip_AA()
*/