diff --git a/libisofs/ecma119.c b/libisofs/ecma119.c index 99a6dcd..b640ff0 100644 --- a/libisofs/ecma119.c +++ b/libisofs/ecma119.c @@ -380,11 +380,14 @@ void write_one_dir_record(Ecma119Image *t, Ecma119Node *node, int file_id, multi_extend = (node->info.file->nsections - 1 == extent) ? 0 : 1; } else { /* - * for nodes other than files and dirs, we set both - * len and block to 0 + * for nodes other than files and dirs, we set len to 0, and + * the content block address to a dummy value. */ len = 0; - block = 0; + if (t->high_empty_address) + block = t->empty_file_block; + else + block = 0; } /* @@ -1577,6 +1580,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img) target->hardlinks = opts->hardlinks; target->aaip = opts->aaip; target->always_gmt = opts->always_gmt; + target->high_empty_address = opts->high_empty_address; target->untranslated_name_len = opts->untranslated_name_len; target->allow_dir_id_ext = opts->allow_dir_id_ext; target->omit_version_numbers = opts->omit_version_numbers @@ -1922,8 +1926,15 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img) if (i == el_torito_writer_index) continue; - /* Exposing address of data start to IsoWriteOpts */ + /* Exposing address of data start to IsoWriteOpts iand memorizing + this address for for all files which have no block address: + symbolic links, device files, empty data files. + filesrc_writer_compute_data_blocks() and filesrc_writer_write_data() + will account resp. write this single block. + */ if (i == file_src_writer_index) { + if (target->high_empty_address) + target->empty_file_block = target->curblock; opts->data_start_lba = target->curblock; } @@ -2368,6 +2379,7 @@ int iso_write_opts_new(IsoWriteOpts **opts, int profile) wopts->ascii_disc_label[0] = 0; wopts->will_cancel = 0; wopts->allow_dir_id_ext = 0; + wopts->high_empty_address = 0; wopts->untranslated_name_len = 0; *opts = wopts; @@ -2457,6 +2469,15 @@ int iso_write_opts_set_aaip(IsoWriteOpts *opts, int enable) return ISO_SUCCESS; } +int iso_write_opts_set_high_empty_address(IsoWriteOpts *opts, int enable) +{ + if (opts == NULL) { + return ISO_NULL_POINTER; + } + opts->high_empty_address = enable ? 1 : 0; + return ISO_SUCCESS; +} + int iso_write_opts_set_untranslated_name_len(IsoWriteOpts *opts, int len) { if (opts == NULL) { diff --git a/libisofs/ecma119.h b/libisofs/ecma119.h index b44f26e..7230f2a 100644 --- a/libisofs/ecma119.h +++ b/libisofs/ecma119.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2007 Vreixo Formoso - * Copyright (c) 2009 Thomas Schmitt + * Copyright (c) 2009 - 2011 Thomas Schmitt * * This file is part of the libisofs project; you can redistribute it and/or * modify it under the terms of the GNU General Public License version 2 @@ -244,6 +244,16 @@ struct iso_write_opts { uid_t uid; /** uid to use when replace_uid == 2. */ gid_t gid; /** gid to use when replace_gid == 2. */ + /** + * Let symbolic links, device files, and empty data files point to + * a block address after the end of the directory tree, rather than + * using LBA 0 for links and devices, and the address of the Volume + * Descriptor Set Terminator for empty data files. + * Single-pass reader libarchive sorts by ths address and needs to see all + * directory info before processing any data files. + */ + unsigned int high_empty_address :1; + /** * Extra Caution: This option breaks any assumptions about names that * are supported by ECMA-119 specifications. @@ -485,6 +495,7 @@ struct ecma119_image mode_t dir_mode; time_t timestamp; + unsigned int high_empty_address :1; unsigned int untranslated_name_len; /** diff --git a/libisofs/filesrc.c b/libisofs/filesrc.c index 4f0afbc..abd55be 100644 --- a/libisofs/filesrc.c +++ b/libisofs/filesrc.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2007 Vreixo Formoso - * 2010 Thomas Schmitt + * 2010 - 2011 Thomas Schmitt * * This file is part of the libisofs project; you can redistribute it and/or * modify it under the terms of the GNU General Public License version 2 @@ -232,6 +232,12 @@ int filesrc_writer_compute_data_blocks(IsoImageWriter *writer) t = writer->target; + /* Eventually reserve a single zeroed block for all files which have + no block address: symbolic links, device files, empty data files. + */ + if (t->high_empty_address) + t->curblock++; + /* on appendable images, ms files shouldn't be included */ if (t->appendable) { inc_item = is_ms_file; @@ -347,11 +353,22 @@ int filesrc_writer_write_data(IsoImageWriter *writer) return ISO_ASSERT_FAILURE; } + memset(buffer, 0, BLOCK_SIZE); t = writer->target; filelist = writer->data; iso_msg_debug(t->image->id, "Writing Files..."); + /* Eventually write a single zeroed block as block address target for all + files which have no block address: + symbolic links, device files, empty data files. + */ + if (t->high_empty_address) { + ret = iso_write(t, buffer, BLOCK_SIZE); + if (ret < 0) + goto ex; + } + i = 0; while ((file = filelist[i++]) != NULL) { was_error = 0; diff --git a/libisofs/libisofs.h b/libisofs/libisofs.h index bf80ed4..48f323f 100644 --- a/libisofs/libisofs.h +++ b/libisofs/libisofs.h @@ -1370,6 +1370,24 @@ int iso_write_opts_set_hardlinks(IsoWriteOpts *opts, int enable); */ int iso_write_opts_set_aaip(IsoWriteOpts *opts, int enable); +/** + * Let symbolic links, device files, and empty data files point to a + * dedicated block of zero bytes after the end of the directory trees, rather + * than using address 0 for links and device files, resp. the address of the + * Volume Descriptor Set Terminator for empty data files. + * (Single-pass reader libarchive sorts by this address and needs to see all + * directory info before processing any data files.) + * + * @param opts + * The option set to be manipulated. + * @param enable + * 1 = use the address of a block after the directory tree. + * 0 = use the traditional block addresses in the range of 0 to 31. + * + * @since 1.0.2 + */ +int iso_write_opts_set_high_empty_address(IsoWriteOpts *opts, int enable); + /** * Caution: This option breaks any assumptions about names that * are supported by ECMA-119 specifications. diff --git a/libisofs/libisofs.ver b/libisofs/libisofs.ver index c79dff4..a9647a4 100644 --- a/libisofs/libisofs.ver +++ b/libisofs/libisofs.ver @@ -274,6 +274,7 @@ iso_write_opts_set_dir_rec_mtime; iso_write_opts_set_disc_label; iso_write_opts_set_fifo_size; iso_write_opts_set_hardlinks; +iso_write_opts_set_high_empty_address; iso_write_opts_set_iso1999; iso_write_opts_set_iso_level; iso_write_opts_set_joliet;