diff --git a/libisofs/ecma119.c b/libisofs/ecma119.c index 98724ba..4444224 100644 --- a/libisofs/ecma119.c +++ b/libisofs/ecma119.c @@ -1103,7 +1103,9 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img) { int ret, i, voldesc_size, nwriters, image_checksums_mad = 0, tag_pos; Ecma119Image *target; - int el_torito_writer_index = -1, file_src_writer_index= -1; + int el_torito_writer_index = -1, file_src_writer_index = -1; + int system_area_options = 0; + char *system_area = NULL; /* 1. Allocate target and copy opts there */ target = calloc(1, sizeof(Ecma119Image)); @@ -1165,16 +1167,23 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img) target->eltorito = (src->bootcat == NULL ? 0 : 1); target->catalog = src->bootcat; + if (opts->system_area_data != NULL) { + system_area = opts->system_area_data; + system_area_options = opts->system_area_options; + } else if (src->system_area_data != NULL) { + system_area = src->system_area_data; + system_area_options = src->system_area_options; + } target->system_area_data = NULL; - if(opts->system_area_data != NULL) { + if (system_area != NULL) { target->system_area_data = calloc(32768, 1); if (target->system_area_data == NULL) { ret = ISO_OUT_OF_MEM; goto target_cleanup; } - memcpy(target->system_area_data, opts->system_area_data, 32768); + memcpy(target->system_area_data, system_area, 32768); } - target->system_area_options = opts->system_area_options; + target->system_area_options = system_area_options; target->vol_creation_time = opts->vol_creation_time; target->vol_modification_time = opts->vol_modification_time; @@ -2163,7 +2172,7 @@ int iso_write_opts_set_system_area(IsoWriteOpts *opts, char data[32768], if (opts->system_area_data != NULL) free(opts->system_area_data); opts->system_area_data = NULL; - } else { + } else if (!(flag & 2)) { if (opts->system_area_data == NULL) { opts->system_area_data = calloc(32768, 1); if (opts->system_area_data == NULL) @@ -2171,7 +2180,8 @@ int iso_write_opts_set_system_area(IsoWriteOpts *opts, char data[32768], } memcpy(opts->system_area_data, data, 32768); } - opts->system_area_options = options & 3; + if (!(flag & 4)) + opts->system_area_options = options & 3; return ISO_SUCCESS; } diff --git a/libisofs/fs_image.c b/libisofs/fs_image.c index 612bae1..e0af930 100644 --- a/libisofs/fs_image.c +++ b/libisofs/fs_image.c @@ -102,6 +102,12 @@ struct iso_read_opts */ int auto_input_charset; + + /** + * Enable or disable loading of the first 32768 bytes of the session and + * submission by iso_write_opts_set_system_area(data, 0). + */ + int load_system_area; }; /** @@ -2951,7 +2957,7 @@ int iso_image_import(IsoImage *image, IsoDataSource *src, struct iso_read_opts *opts, IsoReadImageFeatures **features) { - int ret, hflag; + int ret, hflag, i; IsoImageFilesystem *fs; IsoFilesystem *fsback; IsoNodeBuilder *blback; @@ -2959,9 +2965,9 @@ int iso_image_import(IsoImage *image, IsoDataSource *src, IsoFileSource *newroot; _ImageFsData *data; struct el_torito_boot_catalog *oldbootcat; + uint8_t *rpt; #ifdef Libisofs_with_checksumS - int i; uint32_t old_checksum_start_lba; uint32_t old_checksum_end_lba; uint32_t old_checksum_idx_count; @@ -2969,7 +2975,6 @@ int iso_image_import(IsoImage *image, IsoDataSource *src, char checksum_type[81]; uint32_t checksum_size; size_t size; - uint8_t *rpt; void *ctx = NULL; char md5[16]; #endif @@ -2978,12 +2983,30 @@ int iso_image_import(IsoImage *image, IsoDataSource *src, return ISO_NULL_POINTER; } + ret = iso_image_filesystem_new(src, opts, image->id, &fs); if (ret < 0) { return ret; } data = fs->data; + + if (opts->load_system_area) { + if (image->system_area_data != NULL) + free(image->system_area_data); + image->system_area_data = calloc(32768, 1); + if (image->system_area_data == NULL) + return ISO_OUT_OF_MEM; + image->system_area_options = 0; + /* Read 32768 bytes */ + for (i = 0; i < 16; i++) { + rpt = (uint8_t *) (image->system_area_data + i * 2048); + ret = src->read_block(src, opts->block + i, rpt); + if (ret < 0) + return ret; + } + } + /* get root from filesystem */ ret = fs->get_root(fs, &newroot); if (ret < 0) { @@ -3332,8 +3355,9 @@ int iso_read_opts_new(IsoReadOpts **opts, int profile) ropts->file_mode = 0444; ropts->dir_mode = 0555; - ropts->noaaip= 1; - ropts->nomd5= 1; + ropts->noaaip = 1; + ropts->nomd5 = 1; + ropts->load_system_area = 0; *opts = ropts; return ISO_SUCCESS; @@ -3469,6 +3493,15 @@ int iso_read_opts_auto_input_charset(IsoReadOpts *opts, int mode) return ISO_SUCCESS; } +int iso_read_opts_load_system_area(IsoReadOpts *opts, int mode) +{ + if (opts == NULL) { + return ISO_NULL_POINTER; + } + opts->load_system_area = mode & 1; + return ISO_SUCCESS; +} + /** * Destroy an IsoReadImageFeatures object obtained with iso_image_import. */ diff --git a/libisofs/image.c b/libisofs/image.c index e9ffce4..7dfaf25 100644 --- a/libisofs/image.c +++ b/libisofs/image.c @@ -74,6 +74,8 @@ int iso_image_new(const char *name, IsoImage **image) img->volset_id = strdup(name); img->volume_id = strdup(name); } + img->system_area_data = NULL; + img->system_area_options = 0; img->builder_ignore_acl = 1; img->builder_ignore_ea = 1; img->inode_counter = 0; @@ -331,6 +333,16 @@ int iso_image_get_msg_id(IsoImage *image) return image->id; } +int iso_image_get_system_area(IsoImage *img, char system_area_data[32768], + int *options, int flag) +{ + *options = img->system_area_options; + if (img->system_area_data == NULL) + return 0; + memcpy(system_area_data, img->system_area_data, 32768); + return 1; +} + static int dir_update_size(IsoImage *image, IsoDir *dir) { diff --git a/libisofs/image.h b/libisofs/image.h index 736eb3c..2db315b 100644 --- a/libisofs/image.h +++ b/libisofs/image.h @@ -53,6 +53,11 @@ struct Iso_Image /* el-torito boot catalog */ struct el_torito_boot_catalog *bootcat; + /* Eventually loaded system area data, or NULL */ + char *system_area_data; + /* Prescribed/detected options, see iso_write_opts_set_system_area() */ + int system_area_options; + /* image identifier, for message origin identifier */ int id; diff --git a/libisofs/libisofs.h b/libisofs/libisofs.h index 3299471..592df2c 100644 --- a/libisofs/libisofs.h +++ b/libisofs/libisofs.h @@ -1709,6 +1709,10 @@ int iso_write_opts_set_fifo_size(IsoWriteOpts *opts, size_t fifo_size); * only if not bit0 is set. * @param flag * bit0 = invalidate any attached system area data. Same as data == NULL + * (This re-activates eventually loaded image System Area data. + * To erase those, submit 32 kB of zeros without flag bit0.) + * bit1 = keep data unaltered + * bit2 = keep options unaltered * @return * ISO_SUCCESS or error * @since 0.6.30 @@ -1992,6 +1996,20 @@ int iso_read_opts_set_input_charset(IsoReadOpts *opts, const char *charset); */ int iso_read_opts_auto_input_charset(IsoReadOpts *opts, int mode); +/** + * Enable or disable loading of the first 32768 bytes of the session. + * + * @param mode + * Bitfield for control purposes: + * bit0= Load System Area data and attach them to the image so that they + * get written by the next session, if not overridden by + * iso_write_opts_set_system_area(). + * Submit any other bits with value 0. + * + * @since 0.6.30 + * + */ +int iso_read_opts_load_system_area(IsoReadOpts *opts, int mode); /** * Import a previous session or image, for growing or modify. @@ -2428,6 +2446,28 @@ void el_torito_patch_isolinux_image(ElToritoBootImage *bootimg); */ int el_torito_set_isolinux_options(ElToritoBootImage *bootimg, int options, int flag); +/** + * Obtain a copy of the eventually loaded first 32768 bytes of the imported + * session, the System Area. + * It will be written to the start of the next session unless it gets + * overwritten by iso_write_opts_set_system_area(). + * + * @param img + * The image to be inquired. + * @param data + * A byte array of at least 32768 bytesi to take the loaded bytes. + * @param options + * The option bits which will be applied if not overridden by + * iso_write_opts_set_system_area(). See there. + * @param flag + * Bitfield for control purposes, unused yet, submit 0 + * @return + * 1 on success, 0 if no System Area was loaded, < 0 error. + * @since 0.6.30 + */ +int iso_image_get_system_area(IsoImage *img, char data[32768], + int *options, int flag); + /** * Increments the reference counting of the given node. *