diff --git a/libisofs/fs_image.c b/libisofs/fs_image.c index 810b072..8d8159b 100644 --- a/libisofs/fs_image.c +++ b/libisofs/fs_image.c @@ -1008,6 +1008,33 @@ IsoFileSourceIface ifs_class = { }; + +/* Used from libisofs/stream.c : iso_stream_get_src_zf() */ +int iso_ifs_source_get_zf(IsoFileSource *src, int *header_size_div4, + int *block_size_log2, uint32_t *uncompressed_size, + int flag) +{ + +#ifdef Libisofs_with_zliB + + ImageFileSourceData *data; + + if (src->class != &ifs_class) + return 0; + data = src->data; + *header_size_div4 = data->header_size_div4; + *block_size_log2 = data->block_size_log2; + *uncompressed_size = data->uncompressed_size; + return 1; + +#else + + return 0; + +#endif /* ! Libisofs_with_zliB */ +} + + /** * Read a file name from a directory record, doing the needed charset * conversion diff --git a/libisofs/rockridge.c b/libisofs/rockridge.c index 6521731..117e8ba 100644 --- a/libisofs/rockridge.c +++ b/libisofs/rockridge.c @@ -806,7 +806,8 @@ int add_zf_field(Ecma119Image *t, Ecma119Node *n, struct susp_info *info, int ret, will_copy = 1, stream_type = 0, do_zf = 0; int header_size_div4 = 0, block_size_log2 = 0; uint32_t uncompressed_size = 0; - IsoStream *stream = NULL, *input_stream, *next_stream; + IsoStream *stream = NULL, *input_stream, *last_stream, *first_stream; + IsoStream *first_filter = NULL; IsoFile *file; /* Intimate friendship with this function in filters/zisofs.c */ @@ -819,18 +820,34 @@ int add_zf_field(Ecma119Image *t, Ecma119Node *n, struct susp_info *info, return 2; file = (IsoFile *) n->node; + /* Inspect: last_stream < ... < first_filter < first_stream */ + /* The content is in zisofs format if: + It gets copied and + the last stream is a ziso stream, + or it had a ZF entry and is unfiltered + >>> or its last stream delivers a zisofs file header + or it stays uncopied and + the first filter is an osiz stream, + or it had a ZF entry + >>> or its first stream delivers a zisofs file header + */ + if (t->appendable && file->from_old_session) will_copy = 0; - next_stream = stream = iso_file_get_stream(file); - while (!will_copy) { /* Obtain second-most original stream - (the eventual osiz filter on the image stream) */ - input_stream = iso_stream_get_input_stream(next_stream, 0); + first_filter = first_stream = last_stream = iso_file_get_stream(file); + while (1) { + input_stream = iso_stream_get_input_stream(first_stream, 0); if (input_stream == NULL) break; - - stream = next_stream; - next_stream = input_stream; + first_filter = first_stream; + first_stream = input_stream; + } + if (will_copy) { + stream = last_stream; + } else { + /* (the eventual osiz filter on the image stream) */ + stream = first_filter; } /* Determine stream type : 1=ziso , -1=osiz , 0=other */ @@ -840,18 +857,33 @@ int add_zf_field(Ecma119Image *t, Ecma119Node *n, struct susp_info *info, return ret; if (stream_type == 1 && will_copy) { - do_zf = 1; + do_zf = 1; } else if (stream_type == -1 && !will_copy) { - do_zf = 1; - - /* >>> } else if (t->zisofs_magic) { */ - - /* >>> open stream via temporary osiz filter and read 0 bytes. - If no error: do_zf = 1; */; - /* >>> obtain - header_size_div4, block_size_log2, uncompressed_size */; - + do_zf = 1; + } else if(first_stream == last_stream || !will_copy) { + /* Try whether the image side stream remembers a ZF field */ + ret = iso_stream_get_src_zf(first_stream, &header_size_div4, + &block_size_log2, &uncompressed_size, 0); + if (ret == 1 && header_size_div4 > 0) + do_zf = 1; } + +#ifdef Libisofs_not_yeT + if (t->zisofs_magic && (flag & 1) && !do_zf) { + + if (will_copy) { + stream = last_stream; + } else { + stream = first_stream; + } + /* >>> open stream via temporary osiz filter and read 0 bytes. + If no error: do_zf = 1; */; + /* >>> obtain + header_size_div4, block_size_log2, uncompressed_size */; + /* >>> record info for runs with !(flag&1) : as n->node->xinfo */; + } +#endif + if (!do_zf) return 2; diff --git a/libisofs/stream.c b/libisofs/stream.c index 3ae17c1..3aa2332 100644 --- a/libisofs/stream.c +++ b/libisofs/stream.c @@ -225,6 +225,30 @@ int iso_file_source_stream_new(IsoFileSource *src, IsoStream **stream) return ISO_SUCCESS; } + +int iso_stream_get_src_zf(IsoStream *stream, int *header_size_div4, + int *block_size_log2, uint32_t *uncompressed_size, + int flag) +{ + int ret; + FSrcStreamData *data; + IsoFileSource *src; + + /* Intimate friendship with libisofs/fs_image.c */ + int iso_ifs_source_get_zf(IsoFileSource *src, int *header_size_div4, + int *block_size_log2, uint32_t *uncompressed_size, int flag); + + if (stream->class != &fsrc_stream_class) + return 0; + data = stream->data; + src = data->src; + + ret = iso_ifs_source_get_zf(src, header_size_div4, block_size_log2, + uncompressed_size, 0); + return ret; +} + + struct cut_out_stream { IsoFileSource *src; diff --git a/libisofs/stream.h b/libisofs/stream.h index 0f394cf..5585bc0 100644 --- a/libisofs/stream.h +++ b/libisofs/stream.h @@ -62,4 +62,16 @@ int iso_cut_out_stream_new(IsoFileSource *src, off_t offset, off_t size, */ int iso_memory_stream_new(unsigned char *buf, size_t size, IsoStream **stream); +/** + * Obtain eventual zisofs ZF field entry parameters from a file source out + * of a loaded ISO image. + * To make hope for non-zero reply the stream has to be the original stream + * of an IsoFile with .from_old_session==1. The call is safe with any stream + * type, though, unless fsrc_stream_class would be used without FSrcStreamData. + * @return 1= returned parameters are valid, 0=no ZF info found , <0 error + */ +int iso_stream_get_src_zf(IsoStream *stream, int *header_size_div4, + int *block_size_log2, uint32_t *uncompressed_size, + int flag); + #endif /*STREAM_H_*/