From 429b4cd21ccec790bd117ab35909733810e9f165 Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Mon, 10 Aug 2009 21:23:30 +0200 Subject: [PATCH] New API calls iso_write_opts_set_record_md5(), iso_read_opts_set_no_md5() --- libisofs/ecma119.c | 32 +++++++++++++++------- libisofs/ecma119.h | 24 ++++++++++++++++- libisofs/filesrc.c | 2 +- libisofs/fs_image.c | 66 ++++++++++++++++++++++++++++----------------- libisofs/libisofs.h | 42 +++++++++++++++++++++++++---- libisofs/md5.c | 14 ++++++---- 6 files changed, 134 insertions(+), 46 deletions(-) diff --git a/libisofs/ecma119.c b/libisofs/ecma119.c index 4de22a0..c1f9316 100644 --- a/libisofs/ecma119.c +++ b/libisofs/ecma119.c @@ -1038,9 +1038,8 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img) #ifdef Libisofs_with_checksumS - /* >>> need an IsoWriteOpts component to control this */; - target->md5_checksums = 1; - + target->md5_file_checksums = opts->md5_file_checksums; + target->md5_session_checksum = opts->md5_session_checksum; target->checksum_idx_counter = 0; target->checksum_ctx = NULL; target->checksum_counter = 0; @@ -1074,7 +1073,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img) #ifdef Libisofs_with_checksumS - if (target->md5_checksums) { + if (target->md5_file_checksums || target->md5_session_checksum) { nwriters++; ret = checksum_prepare_image(src, 0); if (ret < 0) @@ -1154,7 +1153,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img) /* ??? Is it safe to add a writer after the content writer ? */ - if (target->md5_checksums) { + if (target->md5_file_checksums || target->md5_session_checksum) { ret = checksum_writer_create(target); if (ret < 0) goto target_cleanup; @@ -1274,10 +1273,12 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img) /* 4. Create and start writing thread */ #ifdef Libisofs_with_checksumS - /* After any fake writes are done: Initialize image checksum context */ - ret = libisofs_md5(&(target->checksum_ctx), NULL, 0, NULL, 1); - if (ret < 0) - return ret; + if (target->md5_session_checksum) { + /* After any fake writes are done: Initialize image checksum context */ + ret = libisofs_md5(&(target->checksum_ctx), NULL, 0, NULL, 1); + if (ret < 0) + return ret; + } #endif /* Libisofs_with_checksumS */ /* ensure the thread is created joinable */ @@ -1717,6 +1718,19 @@ int iso_write_opts_set_sort_files(IsoWriteOpts *opts, int sort) return ISO_SUCCESS; } +int iso_write_opts_set_record_md5(IsoWriteOpts *opts, int session, int files) +{ + +#ifdef Libisofs_with_checksumS + + opts->md5_session_checksum = !!session; + opts->md5_file_checksums = !!files; + +#endif /* Libisofs_with_checksumS */ + + return ISO_SUCCESS; +} + int iso_write_opts_set_replace_mode(IsoWriteOpts *opts, int dir_mode, int file_mode, int uid, int gid) { diff --git a/libisofs/ecma119.h b/libisofs/ecma119.h index a6684c9..8d6b5b7 100644 --- a/libisofs/ecma119.h +++ b/libisofs/ecma119.h @@ -147,6 +147,27 @@ struct iso_write_opts { */ unsigned int dir_rec_mtime :1; +#ifdef Libisofs_with_checksumS + + /** + * Compute MD5 checksum for the whole session and record it as index 0 of + * the checksum blocks after the data area of the session. The layout and + * position of these blocks will be recorded in xattr "isofs.ca" of the + * root node. See see also API call iso_image_get_session_md5(). + */ + unsigned int md5_session_checksum :1; + + /** + * Compute MD5 checksums for IsoFile objects and write them to blocks + * after the data area of the session. The layout and position of these + * blocks will be recorded in xattr "isofs.ca" of the root node. + * The indice of the MD5 sums will be recorded with the IsoFile directory + * entries as xattr "isofs.cx". See also API call iso_file_get_md5(). + */ + unsigned int md5_file_checksums :1; + +#endif /* Libisofs_with_checksumS */ + /** If files should be sorted based on their weight. */ unsigned int sort_files :1; @@ -314,7 +335,8 @@ struct ecma119_image #ifdef Libisofs_with_checksumS - unsigned int md5_checksums :1; + unsigned int md5_session_checksum :1; + unsigned int md5_file_checksums :1; #endif /* Libisofs_with_checksumS */ diff --git a/libisofs/filesrc.c b/libisofs/filesrc.c index d63b7e7..1899664 100644 --- a/libisofs/filesrc.c +++ b/libisofs/filesrc.c @@ -117,7 +117,7 @@ int iso_file_src_create(Ecma119Image *img, IsoFile *file, IsoFileSrc **src) #ifdef Libisofs_with_checksumS - if(img->md5_checksums) { + if(img->md5_file_checksums) { img->checksum_idx_counter++; if (img->checksum_idx_counter < 0x80000000) { fsrc->checksum_index= img->checksum_idx_counter; diff --git a/libisofs/fs_image.c b/libisofs/fs_image.c index 0b74dfc..2620385 100644 --- a/libisofs/fs_image.c +++ b/libisofs/fs_image.c @@ -62,6 +62,7 @@ struct iso_read_opts unsigned int nojoliet : 1; /*< Do not read Joliet extensions */ unsigned int noiso1999 : 1; /*< Do not read ISO 9660:1999 enhanced tree */ unsigned int noaaip : 1; /* Do not read AAIP extension for xattr and ACL */ + unsigned int nomd5 : 1; /* Do not read MD5 array */ /** * Hand out new inode numbers and overwrite eventually read PX inode @@ -249,6 +250,11 @@ typedef struct */ int aaip_load; + /** Whether the MD5 array shall be read if available. + * 1 = yes , 0 = no + */ + int md5_load; + /** Whether AAIP is present. Version major.minor = major * 100 + minor * Value -1 means that no AAIP ER was detected yet. */ @@ -2311,6 +2317,7 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts, data->dir_mode = opts->dir_mode & ~S_IFMT; data->msgid = msgid; data->aaip_load = !opts->noaaip; + data->md5_load = !opts->nomd5; data->aaip_version = -1; data->make_new_ino = opts->make_new_ino; data->inode_counter = 0; @@ -3149,32 +3156,31 @@ int iso_image_import(IsoImage *image, IsoDataSource *src, #ifdef Libisofs_with_checksumS - /* Read checksum buffer */ - - /* >>> needs to be controlled by iso_read_opts */; - - ret = iso_root_get_isofsca((IsoNode *) image->root, - &(image->checksum_start_lba), - &(image->checksum_end_lba), - &(image->checksum_idx_count), - &checksum_size, checksum_type, 0); - if (ret > 0) - if (checksum_size != 16 || strcmp(checksum_type, "MD5") != 0) - ret = 0; - if (ret > 0) { - size = image->checksum_idx_count / 128 + 1; - image->checksum_array = calloc(size, 2048); - if (image->checksum_array == NULL) { - ret = ISO_OUT_OF_MEM; - goto import_revert; - } - - /* Load from image->checksum_end_lba */; - for (i = 0; i < size; i++) { - rpt = (uint8_t *) (image->checksum_array + i * 2048); - ret = src->read_block(src, image->checksum_end_lba + i, rpt); - if (ret <= 0) + if (data->md5_load) { + /* Read checksum array */ + ret = iso_root_get_isofsca((IsoNode *) image->root, + &(image->checksum_start_lba), + &(image->checksum_end_lba), + &(image->checksum_idx_count), + &checksum_size, checksum_type, 0); + if (ret > 0) + if (checksum_size != 16 || strcmp(checksum_type, "MD5") != 0) + ret = 0; + if (ret > 0) { + size = image->checksum_idx_count / 128 + 1; + image->checksum_array = calloc(size, 2048); + if (image->checksum_array == NULL) { + ret = ISO_OUT_OF_MEM; goto import_revert; + } + + /* Load from image->checksum_end_lba */; + for (i = 0; i < size; i++) { + rpt = (uint8_t *) (image->checksum_array + i * 2048); + ret = src->read_block(src, image->checksum_end_lba + i, rpt); + if (ret <= 0) + goto import_revert; + } } } @@ -3291,6 +3297,7 @@ int iso_read_opts_new(IsoReadOpts **opts, int profile) ropts->file_mode = 0444; ropts->dir_mode = 0555; ropts->noaaip= 1; + ropts->nomd5= 1; *opts = ropts; return ISO_SUCCESS; @@ -3351,6 +3358,15 @@ int iso_read_opts_set_no_aaip(IsoReadOpts *opts, int noaaip) return ISO_SUCCESS; } +int iso_read_opts_set_no_md5(IsoReadOpts *opts, int no_md5) +{ + if (opts == NULL) { + return ISO_NULL_POINTER; + } + opts->nomd5 = no_md5 ? 1 : 0; + return ISO_SUCCESS; +} + int iso_read_opts_set_new_inos(IsoReadOpts *opts, int new_inos) { diff --git a/libisofs/libisofs.h b/libisofs/libisofs.h index 69d6b8d..2855caf 100644 --- a/libisofs/libisofs.h +++ b/libisofs/libisofs.h @@ -1415,6 +1415,22 @@ int iso_write_opts_set_dir_rec_mtime(IsoWriteOpts *opts, int allow); */ int iso_write_opts_set_sort_files(IsoWriteOpts *opts, int sort); +/** + * Whether to compute and record MD5 checksums for the whole session and/or + * for each single IsoFile object. The checksums represent the data as they + * were written into the image output stream, not necessarily as they were + * on hard disk at any point of time. + * See also calls iso_image_get_session_md5() and iso_file_get_md5(). + * @param opts + * The option set to be manipulated. + * @param session + * If not 0: compute session checksum + * @param files + * If not 0: compute a checksum for each single IsoFile object. + * @since 0.6.22 + */ +int iso_write_opts_set_record_md5(IsoWriteOpts *opts, int session, int files); + /** * Whether to set default values for files and directory permissions, gid and * uid. All these take one of three values: 0, 1 or 2. @@ -1755,6 +1771,22 @@ int iso_read_opts_set_no_iso1999(IsoReadOpts *opts, int noiso1999); */ int iso_read_opts_set_no_aaip(IsoReadOpts *opts, int noaaip); +/** + * Control reading of an array of MD5 checksums which is eventually stored + * at the end of a session. See also iso_write_opts_set_record_md5(). + * Important: Loading of the MD5 array will only work if AAIP is enabled + * because its position and layout is recorded in xattr "isofs.ca". + * + * @param no_md5 + * 1 = Do not read MD5 checksum array + * 0 = Read Md% array if available + * All other values are reserved. + * + * @since 0.6.22 + */ +int iso_read_opts_set_no_md5(IsoReadOpts *opts, int no_md5); + + /** * Control discarding of eventual inode numbers from existing images. * Such numbers may come from RRIP 1.12 entries PX. If not discarded they @@ -4963,7 +4995,7 @@ int iso_gzip_get_refcounts(off_t *gzip_count, off_t *gunzip_count, int flag); /** * Eventually obtain the recorded MD5 checksum of the session which was * loaded as ISO image. Such a checksum may be stored together with others - * in a contiguous array at the end of the ISO image. The session checksum + * in a contiguous array at the end of the session. The session checksum * covers the data blocks from address start_lba to address end_lba - 1. * It does not cover the recorded array of md5 checksums. * Layout, size, and position of the checksum array is recorded in the xattr @@ -4972,7 +5004,7 @@ int iso_gzip_get_refcounts(off_t *gzip_count, off_t *gunzip_count, int flag); * The image to inquire * @param start_lba * Eventually returns the first block address covered by md5 - * @param start_lba + * @param end_lba * Eventually returns the first block address not covered by md5 any more * @param md5 * Eventually returns 16 byte of MD5 checksum @@ -4989,8 +5021,8 @@ int iso_image_get_session_md5(IsoImage *image, uint32_t *start_lba, /** * Eventually obtain the recorded MD5 checksum of a data file from the loaded * ISO image. Such a checksum may be stored with others in a contiguous - * array at the end of the ISO image. The data file eventually has an xattr - * "isofs.cx" which gives the index in that array. + * array at the end of the loaded session. The data file eventually has an + * xattr "isofs.cx" which gives the index in that array. * @param image * The image from which file stems. * @param file @@ -5516,8 +5548,8 @@ struct burn_source { image. ENABLE ONLY FOR DEVELOPMENT TESTS ! - #define Libisofs_with_checksumS yes */ +#define Libisofs_with_checksumS yes #endif /*LIBISO_LIBISOFS_H_*/ diff --git a/libisofs/md5.c b/libisofs/md5.c index 20ea1b6..9265f31 100644 --- a/libisofs/md5.c +++ b/libisofs/md5.c @@ -457,11 +457,15 @@ int checksum_writer_write_data(IsoImageWriter *writer) iso_msg_debug(t->image->id, "Writing Checksums..."); /* Write image checksum to index 0 */ - /* >>> rather fork a result than killing t->checksum_ctx */; - res = libisofs_md5(&(t->checksum_ctx), NULL, 0, t->image_md5, - 2 | (1 << 15)); - if (res > 0) - memcpy(t->checksum_buffer + 0, t->image_md5, 16); + if (t->checksum_ctx != NULL) { + + /* >>> rather fork a result than killing t->checksum_ctx */; + + res = libisofs_md5(&(t->checksum_ctx), NULL, 0, t->image_md5, + 2 | (1 << 15)); + if (res > 0) + memcpy(t->checksum_buffer + 0, t->image_md5, 16); + } size = (t->checksum_idx_counter + 2) / 128 + 1;