diff --git a/doc/susp_aaip_0_2.txt b/doc/susp_aaip_0_2.txt index a2959bb..0eb7e83 100644 --- a/doc/susp_aaip_0_2.txt +++ b/doc/susp_aaip_0_2.txt @@ -3,7 +3,7 @@ Arbitrary Attribute Interchange Protocol Draft version 0.2 - Dec 19 2008 + Jan 25 2008 Interchange of Persistent File Attributes @@ -344,8 +344,8 @@ Pending considerations: - shall "AA" be fixely defined as signature ? -- shall an "ER" be issued at all ? - >>> look into SUSP 1.12 for ES +- shall an "ER" be issued at all ? (SUSP 1.10 would allow to omit) + >>> mention ES because of SUSP 1.12 - shall the tag types ACL_USER and ACL_GROUP with non-numeric qualifier be revoked ? diff --git a/libisofs/ecma119.c b/libisofs/ecma119.c index 91e0c6b..fb3cf02 100644 --- a/libisofs/ecma119.c +++ b/libisofs/ecma119.c @@ -900,6 +900,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img) target->relaxed_vol_atts = opts->relaxed_vol_atts; target->joliet_longer_paths = opts->joliet_longer_paths; target->rrip_version_1_10 = opts->rrip_version_1_10; + target->aaip_susp_1_10 = opts->aaip_susp_1_10; target->dir_rec_mtime = opts->dir_rec_mtime; target->sort_files = opts->sort_files; @@ -1515,6 +1516,16 @@ int iso_write_opts_set_rrip_version_1_10(IsoWriteOpts *opts, int oldvers) return ISO_SUCCESS; } +/* ts A90125 */ +int iso_write_opts_set_aaip_susp_1_10(IsoWriteOpts *opts, int oldvers) +{ + if (opts == NULL) { + return ISO_NULL_POINTER; + } + opts->aaip_susp_1_10 = oldvers ? 1 : 0; + return ISO_SUCCESS; +} + int iso_write_opts_set_dir_rec_mtime(IsoWriteOpts *opts, int allow) { if (opts == NULL) { diff --git a/libisofs/ecma119.h b/libisofs/ecma119.h index d0d8f47..97251a2 100644 --- a/libisofs/ecma119.h +++ b/libisofs/ecma119.h @@ -115,6 +115,20 @@ struct iso_write_opts { */ unsigned int rrip_version_1_10 :1; + /* ts A90125 */ + /** + * 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 by an ES and to preceed the AA field by ES. + * This saves bytes 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 + * and prescribes ER and ES. It does this since year 1994. + * + * In effect only if above flag .aaip is set to 1. + */ + unsigned int aaip_susp_1_10 :1; + /** * Store as ECMA-119 Directory Record timestamp the mtime of the source * rather than the image creation time. (The ECMA-119 prescription seems @@ -271,6 +285,10 @@ struct ecma119_image /** Write old fashioned RRIP-1.10 rather than RRIP-1.12 */ unsigned int rrip_version_1_10 :1; + /* ts A90125 */ + /* Write AAIP as extension according to SUSP 1.10 rather than SUSP 1.12. */ + unsigned int aaip_susp_1_10 :1; + /* Store in ECMA-119 timestamp mtime of source */ unsigned int dir_rec_mtime :1; diff --git a/libisofs/libisofs.h b/libisofs/libisofs.h index 9a26136..035947b 100644 --- a/libisofs/libisofs.h +++ b/libisofs/libisofs.h @@ -1239,6 +1239,22 @@ int iso_write_opts_set_joliet_longer_paths(IsoWriteOpts *opts, int allow); */ int iso_write_opts_set_rrip_version_1_10(IsoWriteOpts *opts, int oldvers); +/* ts A90125 */ +/** + * 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. + * 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 + * and prescribes ER and ES. It does this since the year 1994. + * + * In effect only if above iso_write_opts_set_aaip() enables writing of AAIP. + * + * @since 0.6.14 + */ +int iso_write_opts_set_aaip_susp_1_10(IsoWriteOpts *opts, int oldvers); + /** * Store as ECMA-119 Directory Record timestamp the mtime of the source * rather than the image creation time. diff --git a/libisofs/rockridge.c b/libisofs/rockridge.c index 0cab79b..1a46290 100644 --- a/libisofs/rockridge.c +++ b/libisofs/rockridge.c @@ -26,6 +26,15 @@ #include +#ifdef Libisofs_with_aaiP + +/* ts A90125 */ +static +int susp_add_ES(Ecma119Image *t, struct susp_info *susp, int to_ce, int seqno); + +#endif /* Libisofs_with_aaiP */ + + static int susp_append(Ecma119Image *t, struct susp_info *susp, uint8_t *data) { @@ -476,23 +485,33 @@ int rrip_add_SL(Ecma119Image *t, struct susp_info *susp, uint8_t **comp, /* ts A90112 */ /* @param flag bit0= only account sizes in sua_free resp. ce_len - parameters t, susp, data may be NULL in this case + parameters susp and data may be NULL in this case */ static int aaip_add_AA(Ecma119Image *t, struct susp_info *susp, uint8_t **data, size_t num_data, size_t *sua_free, size_t *ce_len, int flag) { - int ret, done = 0, len; + int ret, done = 0, len, es_extra = 0; uint8_t *aapt, *cpt; - if (*sua_free < num_data || *ce_len > 0) { - *ce_len += num_data; + if (!t->aaip_susp_1_10) + es_extra = 5; + if (*sua_free < num_data + es_extra || *ce_len > 0) { + *ce_len += num_data + es_extra; } else { - *sua_free -= num_data; + *sua_free -= num_data + es_extra; } if (flag & 1) return ISO_SUCCESS; + + /* If AAIP enabled and announced by ER : Write ES field to announce AAIP */ + if (t->aaip && !t->aaip_susp_1_10) { + ret = susp_add_ES(t, susp, (*ce_len > 0), 1); + if (ret < 0) + return ret; + } + aapt = *data; if (!(aapt[4] & 1)) { /* Single field can be handed over directly */ @@ -691,6 +710,35 @@ int susp_add_SP(Ecma119Image *t, struct susp_info *susp) } +/* ts A90125 */ +/** + * SUSP 1.12: [...] shall specify as an 8-bit number the Extension + * Sequence Number of the extension specification utilized in the entries + * immediately following this System Use Entry. The Extension Sequence + * Numbers of multiple extension specifications on a volume shall correspond to + * the order in which their "ER" System Use Entries are recorded [...] + */ +static +int susp_add_ES(Ecma119Image *t, struct susp_info *susp, int to_ce, int seqno) +{ + unsigned char *ES = malloc(5); + + if (ES == NULL) { + return ISO_OUT_OF_MEM; + } + ES[0] = 'E'; + ES[1] = 'S'; + ES[2] = (unsigned char) 5; + ES[3] = (unsigned char) 1; + ES[4] = (unsigned char) seqno; + if (to_ce) { + return susp_append_ce(t, susp, ES); + } else { + return susp_append(t, susp, ES); + } +} + + #ifdef Libisofs_with_aaiP /* ts A90114 */ @@ -892,7 +940,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(NULL, NULL, NULL, num_aapt, &sua_free, ce, 1); + aaip_add_AA(t, NULL, NULL, num_aapt, &sua_free, ce, 1); *su_size = space - sua_free; if (*ce > 0 && !(flag & 1)) goto unannounced_ca; @@ -949,11 +997,22 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t space, space--; *ce = 0; + su_size = 0; + +#ifdef Libisofs_with_aaiP + + /* ts A90125 */ + /* If AAIP enabled and announced by ER : account for 5 bytes of ES */; + if (t->aaip && !t->aaip_susp_1_10) + su_size += 5; + +#endif /* Libisofs_with_aaiP */ + /* PX and TF, we are sure they always fit in SUA */ if (!t->rrip_version_1_10) { - su_size = 44 + 26; + su_size += 44 + 26; } else { - su_size = 36 + 26; + su_size += 36 + 26; } if (n->type == ECMA119_DIR) { @@ -1137,7 +1196,7 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t space, /* let the expert decide where to add num_aapt */ if (num_aapt > 0) { sua_free = space - su_size; - aaip_add_AA(NULL, NULL, NULL, num_aapt, &sua_free, ce, 1); + aaip_add_AA(t, NULL, NULL, num_aapt, &sua_free, ce, 1); su_size = space - sua_free; } @@ -1276,6 +1335,18 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type, } } +#ifdef Libisofs_with_aaiP + + /* ts A90125 */ + /* If AAIP enabled and announced by ER : Announce RRIP by ES */ + if (t->aaip && !t->aaip_susp_1_10) { + ret = susp_add_ES(t, info, 0, 0); + if (ret < 0) + goto add_susp_cleanup; + } + +#endif /* Libisofs_with_aaiP */ + /* PX and TF, we are sure they always fit in SUA */ ret = rrip_add_PX(t, node, info); if (ret < 0) { @@ -1699,7 +1770,7 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type, #else /* Libisofs_with_aaip_dummY */ - if (t->aaip) { + if (t->aaip && !t->aaip_susp_1_10) { #endif /* ! Libisofs_with_aaip_dummY */ @@ -1727,7 +1798,7 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type, #else /* Libisofs_with_aaip_dummY */ - if (t->aaip) { + if (t->aaip && !t->aaip_susp_1_10) { #endif /* ! Libisofs_with_aaip_dummY */