From de99f93640151799630dcedd80dd59d1a075b4c6 Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Thu, 15 Jan 2009 17:43:58 +0100 Subject: [PATCH] Implemented reading of AA fields to struct image_fs_data.aa_string and defined IsoFileSource_Iface version 1 with access function .get_aa_string() --- doc/susp_aaip_0_2.txt | 2 +- libisofs/aaip_0_2.h | 2 +- libisofs/fs_image.c | 63 ++++++++++++++++++++++++++++++++++----- libisofs/libisofs.h | 34 +++++++++++++++++++-- libisofs/rockridge.c | 1 - libisofs/rockridge.h | 61 ++++++++++++++++++++++++++++++++----- libisofs/rockridge_read.c | 51 +++++++++++++++++++++++++++++++ 7 files changed, 195 insertions(+), 19 deletions(-) diff --git a/doc/susp_aaip_0_2.txt b/doc/susp_aaip_0_2.txt index ef2704f..b8a8b54 100644 --- a/doc/susp_aaip_0_2.txt +++ b/doc/susp_aaip_0_2.txt @@ -29,7 +29,7 @@ Since the size of a SUSP field is limited to 255, multiple fields may be needed to describe one component. The CE mechanism of SUSP shall be used to address enough storage if needed. -This SUSP field and the ER entry of AAIP shall only be present if the ER entry +The SUSP field and the ER entry of AAIP shall only be present if the ER entry of RRIP is present. ------------------------------------------------------------------------------- diff --git a/libisofs/aaip_0_2.h b/libisofs/aaip_0_2.h index f204332..a57f7ef 100644 --- a/libisofs/aaip_0_2.h +++ b/libisofs/aaip_0_2.h @@ -118,7 +118,7 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names, /* This function expects to get submitted a complete chain of AA fields and - determines its size by interpeting the SUSP structure.. + determines its size by interpeting the SUSP structure. @param aa_name The Signature Word (advised is "AA") to be looked for @param data An arbitrary number of bytes beginning with the complete chain of AA fields. Trailing trash is ignored. diff --git a/libisofs/fs_image.c b/libisofs/fs_image.c index 3274f84..f1e3f68 100644 --- a/libisofs/fs_image.c +++ b/libisofs/fs_image.c @@ -265,6 +265,20 @@ struct image_fs_data */ off_t offset; } data; + +#ifdef Libisofs_with_aaiP + /* ts A90114 */ + + /** + * malloc() storage for the string of AA fields which represent + * POSIX Extended Attributes and ACLs. (Not to be confused with + * ECMA-119 Extended Attributes.) + */ + unsigned char *aa_string; + +#endif /* Libisofs_with_aaiP */ + + }; struct child_list @@ -907,9 +921,28 @@ void ifs_free(IsoFileSource *src) free(data->sections); free(data->name); + +#ifdef Libisofs_with_aaiP + /* ts A90115 */ + + if (data->aa_string != NULL) + free(data->aa_string); + +#endif /* Libisofs_with_aaiP */ + free(data); } + +#ifdef Libisofs_with_aaiP + +/* >>> unsigned char *(*get_aa_string)(IsoFileSource *src, + unsigned char **aa_string, int flag); +*/ + +#endif /* Libisofs_with_aaiP */ + + IsoFileSourceIface ifs_class = { 0, /* version */ ifs_get_path, @@ -996,6 +1029,16 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent, uint32_t relocated_dir = 0; +#ifdef Libisofs_with_aaiP + + /* ts A90115 */ + unsigned char *aa_string = NULL; + size_t aa_size = 0, aa_len = 0, prev_field = 0; + int aa_done = 0; + +#endif /* Libisofs_with_aaiP */ + + if (fs == NULL || fs->data == NULL || record == NULL || src == NULL) { return ISO_NULL_POINTER; } @@ -1025,7 +1068,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent, if (record->len_xa[0]) { iso_msg_submit(fsdata->msgid, ISO_UNSUPPORTED_ECMA119, 0, "Unsupported image. This image has at least one file with " - "Extended Attributes, that are not supported"); + "ECMA-119 Extended Attributes, that are not supported"); return ISO_UNSUPPORTED_ECMA119; } @@ -1238,20 +1281,19 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent, #ifdef Libisofs_with_aaiP + /* ts A90115 */ } else if (SUSP_SIG(sue, 'A', 'A')) { - ret = ISO_SUCCESS; -/* >>> ts A90112 - ret = read_susp_AA(sue, &aa, &aacont); -*/ + ret = read_aaip_AA(sue, "AA", &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 NM entry"); + "Invalid AA entry"); + continue; } - #endif /* Libisofs_with_aaiP */ @@ -1512,6 +1554,13 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent, ifsdata->info = atts; ifsdata->name = name; +#ifdef Libisofs_with_aaiP + + ifsdata->aa_string = aa_string; + +#endif /* Libisofs_with_aaiP */ + + /* save extents */ ifsdata->sections = realloc(ifsdata->sections, (1 + ifsdata->nsections) * sizeof(struct iso_file_section)); diff --git a/libisofs/libisofs.h b/libisofs/libisofs.h index 564f091..3beff48 100644 --- a/libisofs/libisofs.h +++ b/libisofs/libisofs.h @@ -459,7 +459,12 @@ struct iso_filesystem */ struct IsoFileSource_Iface { - /* reserved for future usage, set to 0 */ + /* ts A90114 */ + /** + * Tells the version of the interface: + * Version 0 provides functions up to (*lseek)(). + * Version 1 additionally provides function *(get_aa_string)(). + */ int version; /** @@ -654,13 +659,38 @@ struct IsoFileSource_Iface * 2 The offset is set to the size of the file plus offset bytes * (SEEK_END). * @return - * Absolute offset posistion on the file, or < 0 on error. Cast the + * Absolute offset position of the file, or < 0 on error. Cast the * returning value to int to get a valid libisofs error. * * @since 0.6.4 */ off_t (*lseek)(IsoFileSource *src, off_t offset, int flag); + /* Add-ons of .version 1 begin here */ + + /* ts A90114 */ + /** + * Valid only if .version is > 0. See above. + * Get the AA string with encoded ACL and/or POSIX Extended Attributes. + * (Not to be confused with ECMA-119 Extended Attributes). + * @param flag Bitfield for control purposes + * bit0= Transfer ownership of AA string data. + * src will free the eventual cached data and might + * not be able to produce it again. + * @param aa_string Returns a pointer to the AA string data. If no AA + * string is available, *aa_string becomes NULL. + * The caller is responsible for finally calling free() + * on non-NULL results. + * (See doc/susp_aaip_0_2.txt for the meaning of AA and + * libisofs/aaip_0_2.h for encoding and decoding.) + * @return 1 means success (*aa_string == NULL is possible) + * <0 means failure and must b a valid libisofs error code + * (e.g. ISO_FILE_ERROR if no better one can be found). + * @since 0.6.14 + */ + unsigned char *(*get_aa_string)(IsoFileSource *src, + unsigned char **aa_string, int flag); + /* * TODO #00004 Add a get_mime_type() function. * This can be useful for GUI apps, to choose the icon of the file diff --git a/libisofs/rockridge.c b/libisofs/rockridge.c index 5df24a1..dfe747c 100644 --- a/libisofs/rockridge.c +++ b/libisofs/rockridge.c @@ -1346,7 +1346,6 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type, /* Obtain AA field string from node and write it to directory entry or CE area. */ - aapt = NULL; ret = ISO_SUCCESS; num_aapt = 0; diff --git a/libisofs/rockridge.h b/libisofs/rockridge.h index eebf1ce..e72376d 100644 --- a/libisofs/rockridge.h +++ b/libisofs/rockridge.h @@ -28,6 +28,17 @@ #include "ecma119.h" + +/* ts A90112 : Enable experiments about EA and ACL +*/ +#define Libisofs_with_aaiP yes + +/* ts A90112 + <<< write dummy AAIP fields with any node + # define Libisofs_with_aaip_dummY yes +*/ + + #define SUSP_SIG(entry, a, b) ((entry->sig[0] == a) && (entry->sig[1] == b)) /** @@ -115,6 +126,18 @@ struct rr_SL { uint8_t comps[1]; }; + +#ifdef Libisofs_with_aaiP + +/** Arbitrary Attribute (AAIP, see doc/susp_aaip_0_2.txt) */ +struct rr_AA { + uint8_t flags[1]; + uint8_t comps[1]; +}; + +#endif /* Libisofs_with_aaiP */ + + /** * Struct for a SUSP System User Entry (SUSP, 4.1) */ @@ -133,6 +156,11 @@ struct susp_sys_user_entry struct rr_NM NM; struct rr_CL CL; struct rr_SL SL; + +#ifdef Libisofs_with_aaiP + struct rr_AA AA; +#endif /* Libisofs_with_aaiP */ + } data; /* 5 to 4+len_sue */ }; @@ -265,13 +293,32 @@ int read_rr_SL(struct susp_sys_user_entry *sl, char **dest, int *cont); int read_rr_PN(struct susp_sys_user_entry *pn, struct stat *st); -/* ts A90112 : Enable experiments about EA and ACL -*/ -#define Libisofs_with_aaiP yes +#ifdef Libisofs_with_aaiP + +/** + * Collects the AA field string from single AA fields. + * (see doc/susp_aaip_0_2.txt) + * @param aa Signature of fields for inner representation. It will + * replace the signature of of the submitted SUSP field. + * Advised is "AA". + * @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. + * Begin with *aa_size == 0, or own storage size. + * @param aa_len Current occupied size of aa_string. + * 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. + * Fields will be ignored as soon as it is 1. + * Begin with *is_done == 0 + * @param flag Unused yet. Submit 0. + */ +int read_aaip_AA(struct susp_sys_user_entry *sue, char aa[2], + unsigned char **aa_string, size_t *aa_size, size_t *aa_len, + size_t *prev_field, int *is_done, int flag); + +#endif -/* ts A90112 - <<< write dummy AAIP fields with any node - # define Libisofs_with_aaip_dummY yes -*/ #endif /* LIBISO_ROCKRIDGE_H */ diff --git a/libisofs/rockridge_read.c b/libisofs/rockridge_read.c index 05b5b4f..a87ba49 100644 --- a/libisofs/rockridge_read.c +++ b/libisofs/rockridge_read.c @@ -417,3 +417,54 @@ int read_rr_PN(struct susp_sys_user_entry *pn, struct stat *st) | (dev_t)iso_read_bb(pn->data.PN.low, 4, NULL); return ISO_SUCCESS; } + + +#ifdef Libisofs_with_aaiP + + +int read_aaip_AA(struct susp_sys_user_entry *sue, char aa[2], + 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; + } + + /* Eventually create or grow storage */ + if (*aa_size == 0 || *aa_string == 0) { + *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] = aa[0]; + aapt[1] = aa[1]; + aapt[2] = sue->len_sue[0]; + aapt[3] = 1; + aapt[4] = 0; + /* Append sue payload */ + memcpy(aapt + 5, sue->data.AA.comps, sue->len_sue[0]); + + *is_done = sue->data.AA.flags[0] & 1; + + return ISO_SUCCESS; +} + +#endif /* Libisofs_with_aaiP */ +