Compare commits

...

15 Commits

Author SHA1 Message Date
b7dc0f4057 Version leap to 1.3.4 2013-12-12 14:37:11 +01:00
0ab9f5f8d2 Updated changelog 2013-12-12 09:30:25 +01:00
1338f29d62 Added a comment to node.c 2013-12-12 09:25:40 +01:00
bc5e2227c8 Encoding HFS+ names in UTF-16 rather than UCS-2. 2013-11-26 12:47:43 +01:00
654ff82345 Mentioned boot image address in newer GRUB2 MBR 2013-11-18 13:22:17 +01:00
6baeae70e0 Mentioned GRUB2 Boot Info in boot_sectors.txt 2013-11-18 12:58:50 +01:00
b987972660 Updated copyright year in README 2013-09-25 13:07:38 +02:00
c78526abce Reacted on warnings of Debian buildd with clang 2013-09-16 20:52:14 +02:00
b95e1bb85c Giving sort weight 2 as default to El Torito boot images. 2013-09-07 21:37:27 +02:00
7aa2582129 Reacted on warnings of PLD Linux build log 2013-09-05 10:01:08 +02:00
3f29d70aba Preserving MD5s of files from old session until the end of the new
write run. If the write run fails, the old MD5s get restored.
2013-08-20 11:48:24 +02:00
567d3ddafb Fixed the rollover protection for checksum indice. 2013-08-17 12:49:01 +02:00
c47f85c639 Removed an obsolete sentence from docs. 2013-08-17 12:48:04 +02:00
40310b4fd7 Updated ChangeLog to new development cycle. 2013-08-07 15:53:43 +02:00
f34c274f21 Version leap to 1.3.3 2013-08-07 15:12:43 +02:00
20 changed files with 337 additions and 96 deletions

View File

@ -1,3 +1,8 @@
libisofs-1.3.4.tar.gz Thu Dec 12 2013
===============================================================================
* Giving sort weight 2 as default to El Torito boot images
* Encoding HFS+ names in UTF-16 rather than UCS-2.
libisofs-1.3.2.tar.gz Wed Aug 07 2013 libisofs-1.3.2.tar.gz Wed Aug 07 2013
=============================================================================== ===============================================================================
* Bug fix: iso_finish() left an invalid global pointer, which a subsequent * Bug fix: iso_finish() left an invalid global pointer, which a subsequent

2
README
View File

@ -4,7 +4,7 @@
Released under GPL (see COPYING file for details). Released under GPL (see COPYING file for details).
Copyright (C) 2008 - 2012 Vreixo Formoso, Copyright (C) 2008 - 2013 Vreixo Formoso,
Mario Danic, Mario Danic,
Vladimir Serbinenko, Vladimir Serbinenko,
Thomas Schmitt Thomas Schmitt

View File

@ -1,4 +1,4 @@
AC_INIT([libisofs], [1.3.2], [http://libburnia-project.org]) AC_INIT([libisofs], [1.3.4], [http://libburnia-project.org])
AC_PREREQ([2.50]) AC_PREREQ([2.50])
dnl AC_CONFIG_HEADER([config.h]) dnl AC_CONFIG_HEADER([config.h])
@ -41,7 +41,7 @@ dnl If LIBISOFS_*_VERSION changes, be sure to change AC_INIT above to match.
dnl dnl
LIBISOFS_MAJOR_VERSION=1 LIBISOFS_MAJOR_VERSION=1
LIBISOFS_MINOR_VERSION=3 LIBISOFS_MINOR_VERSION=3
LIBISOFS_MICRO_VERSION=2 LIBISOFS_MICRO_VERSION=4
LIBISOFS_VERSION=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION.$LIBISOFS_MICRO_VERSION LIBISOFS_VERSION=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION.$LIBISOFS_MICRO_VERSION
AC_SUBST(LIBISOFS_MAJOR_VERSION) AC_SUBST(LIBISOFS_MAJOR_VERSION)
@ -51,10 +51,10 @@ AC_SUBST(LIBISOFS_VERSION)
dnl Libtool versioning dnl Libtool versioning
LT_RELEASE=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION LT_RELEASE=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION
# 2013.08.07 development jump has not yet happened # 2013.12.12 development jump has not yet happened
# SONAME = 74 - 68 = 6 . Library name = libisofs.6.68.0 # SONAME = 76 - 70 = 6 . Library name = libisofs.6.70.0
LT_CURRENT=74 LT_CURRENT=76
LT_AGE=68 LT_AGE=70
LT_REVISION=0 LT_REVISION=0
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE` LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`

View File

@ -15,6 +15,8 @@ specifications, some is just rumor which happens to work (maybe not even that).
EL Torito CD booting, for PC-BIOS x86, PowerPC, (old) Mac, EFI. EL Torito CD booting, for PC-BIOS x86, PowerPC, (old) Mac, EFI.
Boot Info Table and GRUB2 Boot Info
Master Boot Record (MBR), for PC-BIOS x86 from (pseudo-) hard disk Master Boot Record (MBR), for PC-BIOS x86 from (pseudo-) hard disk
Apple Partition Map (APM), for more modern Mac Apple Partition Map (APM), for more modern Mac
@ -48,7 +50,6 @@ Sources:
El Torito, Bootable CD-ROM Format Specification, Version 1.0, 1995 El Torito, Bootable CD-ROM Format Specification, Version 1.0, 1995
which refers to ECMA-119, the standard for ISO 9660 filesystems. which refers to ECMA-119, the standard for ISO 9660 filesystems.
libisofs/eltorito.[ch] by Vreixo Formoso. libisofs/eltorito.[ch] by Vreixo Formoso.
man mkisofs by Joerg Schilling.
ECMA-119 prescribes that the first 32 kB of an ISO 9660 image are System Area ECMA-119 prescribes that the first 32 kB of an ISO 9660 image are System Area
@ -237,10 +238,22 @@ Byte Range | Value | Meaning
12 - 31 | sel_crit | "Vendor unique selection criteria." 12 - 31 | sel_crit | "Vendor unique selection criteria."
---------- | ---------- | ---------------------------------------------------- ---------- | ---------- | ----------------------------------------------------
------------------------------------------------------------------------------
Boot Info Table and GRUB2 Boot Info
Sources:
man mkisofs by Joerg Schilling
Mail conversations with Vladimir Serbinenko.
The boot image file content is mostly opaque to the ISO 9660 image generator. The boot image file content is mostly opaque to the ISO 9660 image generator.
Nevertheless there is a tradition named "Boot Info Table" which prescribes Nevertheless there is a tradition named "Boot Info Table" which prescribes
to write information into byte fields of the boot image file content. to write information into byte fields of the boot image file content.
Recent versions of GRUB2 expect a similar patching which has no name yet.
For now let's call it "GRUB2 Boot Info"
There are no general means known how a producer of ISO 9660 images could There are no general means known how a producer of ISO 9660 images could
detect the need for Boot Info Table production. detect the need for Boot Info Table production.
It rather needs a hint from the user who has to know whether the boot image It rather needs a hint from the user who has to know whether the boot image
@ -249,19 +262,31 @@ The Boot Info Table begins at byte 8 of the boot image content.
Byte Range | Value | Meaning Byte Range | Value | Meaning
---------- | ---------- | ---------------------------------------------------- ---------- | ---------- | ----------------------------------------------------
8 - 11 | pvd_lba | Block address of the Primary Volume Descriptor 8 - 11 | pvd_lba | Block address of the Primary Volume Descriptor.
| | This is the session start LBA + 16. | | This is the session start LBA + 16.
| | | |
12 - 15 | file_lba | Block address of the start of the boot image file 12 - 15 | file_lba | Block address of the start of the boot image file
| | content. | | content. Block size is 2048.
| | | |
16 - 19 | file_len | Number of bytes in boot image file content. 16 - 19 | file_len | Number of bytes in boot image file content.
| | | |
20 - 23 | checksum | Little-endian: The sum of all 32-bit words of the 20 - 23 | checksum | The sum of all 32-bit words of the file content
| | file content from byte 64 to file end. | | from byte 64 to file end.
| | | |
24 - 63 | 0 | Reserved 24 - 63 | 0 | Reserved
---------- | ---------- | ---------------------------------------------------- ---------- | ---------- | ----------------------------------------------------
All numbers are stored little-endian.
GRUB2 Boot Info represents a particular block address inside the boot image.
It may well be combined with Boot Info Table. See GRUB2 script grub-mkrescue
use of xorrisofs options -boot-info-table and --grub2-boot-info.
Byte Range | Value | Meaning
---------- | ---------- | ----------------------------------------------------
2548 -2555 | grub2_adr | Block address of the start of the boot image file
| | content plus 5. Block size is 512.
| | 64 bit Little-endian.
---------- | ---------- | ----------------------------------------------------
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
@ -1326,12 +1351,21 @@ Sources:
Mailing list conversations with Vladimir Serbinenko. Mailing list conversations with Vladimir Serbinenko.
The MBR file that is used with GRUB2 script grub-mkrescue needs only a The MBR file that is used with older versions of GRUB2 script grub-mkrescue
partition table entry which describes the image size. needs only a partition table entry which describes the image size.
Newer versions get patched by the block address of the content of the first
El Torito boot image. See grub-mkrescue use of xorrisofs option --grub2-mbr.
Byte Range | Value | Meaning Byte Range | Value | Meaning
---------- | ---------- | ---------------------------------------------------- ---------- | ---------- | ----------------------------------------------------
0 - 445 | = opaque = | GRUB2 machine code provided by MBR template 0 - 431 | = opaque = | GRUB2 machine code provided by MBR template
| |
432 - 439 | bootimg_adr| With newer versions of grub-mkrescue:
| | Block address of the start of the boot image file
| | content plus 4. Block size is 512.
| | 64 bit Little-endian.
| |
440 - 445 | = opaque = | provided by MBR template
| | | |
446 - 509 | ========== | Partition table 446 - 509 | ========== | Partition table
| | | |

View File

@ -109,8 +109,6 @@ Each Component Record shall have the following format:
[B] "BP 2 - Component Length (LEN_CP)" shall specify as an 8-bit number the [B] "BP 2 - Component Length (LEN_CP)" shall specify as an 8-bit number the
number of component bytes in the Component Record. This length shall not number of component bytes in the Component Record. This length shall not
include the first two bytes of the Component Record. include the first two bytes of the Component Record.
If any of the bit positions 1-3 is set, the value of this field shall be
set to ZERO and no Component Content shall be recorded.
This field shall be recorded according to ISO 9660 Format section 7.1.1. This field shall be recorded according to ISO 9660 Format section 7.1.1.
[C] "BP 3 to 2 + LEN_CP - Component Content" shall contain the component [C] "BP 3 to 2 + LEN_CP - Component Content" shall contain the component
@ -445,7 +443,7 @@ Program mkisofs emits entry XA
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
This text is under This text is under
Copyright (c) 2009 - 2010 Thomas Schmitt <scdbackup@gmx.net> Copyright (c) 2009 - 2013 Thomas Schmitt <scdbackup@gmx.net>
It shall only be modified in sync with libisofs and other software which It shall only be modified in sync with libisofs and other software which
makes use of AAIP. Please mail change requests to mailing list makes use of AAIP. Please mail change requests to mailing list
<libburn-hackers@pykix.org> or to the copyright holder in private. <libburn-hackers@pykix.org> or to the copyright holder in private.

View File

@ -2065,7 +2065,7 @@ int aaip_decode_acl(unsigned char *data, size_t num_data, size_t *consumed,
unsigned char *rpt; unsigned char *rpt;
char perm_text[4], *wpt, *name= NULL; char perm_text[4], *wpt, *name= NULL;
int type, qualifier= 0, perm, ret, cnt, name_size= 1024; int type, qualifier= 0, perm, ret, cnt, name_size= 1024;
size_t w_size, name_fill= 0, i; size_t w_size= 0, name_fill= 0, i;
uid_t uid; uid_t uid;
gid_t gid; gid_t gid;
struct passwd *pwd; struct passwd *pwd;

View File

@ -1230,6 +1230,48 @@ int zero_writer_create(Ecma119Image *target, uint32_t num_blocks, int flag)
return ISO_SUCCESS; return ISO_SUCCESS;
} }
/* @param flag bit0= restore preserved cx (else dispose them)
*/
static
int process_preserved_cx(IsoDir *dir, int flag)
{
int ret, i;
unsigned int cx_value;
void *xipt;
IsoNode *pos;
pos = dir->children;
for (pos = dir->children; pos != NULL; pos = pos->next) {
if (pos->type == LIBISO_FILE) {
if (flag & 1) {
/* Restore preserved cx state of nodes */
ret = iso_node_get_xinfo(pos, checksum_cx_xinfo_func,
&xipt);
if (ret == 1) {
/* xipt is an int disguised as void pointer */
cx_value = 0;
for (i = 0; i < 4; i++)
cx_value =
(cx_value << 8) | ((unsigned char *) &xipt)[i];
ret = iso_file_set_isofscx((IsoFile *) pos, cx_value, 0);
if (ret < 0)
return ret;
} else if (ret == 0) {
/* Node had no cx before the write run. Delete cx. */
iso_file_set_isofscx((IsoFile *) pos, 0, 1);
}
}
iso_node_remove_xinfo(pos, checksum_cx_xinfo_func);
} else if (pos->type == LIBISO_DIR) {
ret = process_preserved_cx((IsoDir *) pos, flag);
if (ret != 0)
return ret;
}
}
return 0;
}
static static
int transplant_checksum_buffer(Ecma119Image *target, int flag) int transplant_checksum_buffer(Ecma119Image *target, int flag)
{ {
@ -1240,6 +1282,10 @@ int transplant_checksum_buffer(Ecma119Image *target, int flag)
target->checksum_idx_counter + 2, 0); target->checksum_idx_counter + 2, 0);
target->checksum_buffer = NULL; target->checksum_buffer = NULL;
target->checksum_idx_counter = 0; target->checksum_idx_counter = 0;
/* Delete recorded cx xinfo */
process_preserved_cx(target->image->root, 0);
return 1; return 1;
} }
@ -1546,7 +1592,7 @@ void *write_function(void *arg)
return NULL; return NULL;
#endif #endif
write_error: ; write_error: ;
if (res != (int) ISO_LIBJTE_END_FAILED) if (res != (int) ISO_LIBJTE_END_FAILED)
finish_libjte(target); finish_libjte(target);
target->eff_partition_offset = 0; target->eff_partition_offset = 0;
@ -1562,11 +1608,9 @@ void *write_function(void *arg)
} }
iso_ring_buffer_writer_close(target->buffer, 1); iso_ring_buffer_writer_close(target->buffer, 1);
/* Transplant checksum buffer away from Ecma119Image */ /* Re-activate recorded cx xinfo */
transplant_checksum_buffer(target, 0); process_preserved_cx(target->image->root, 1);
/* Invalidate the transplanted checksum buffer in IsoImage */
iso_image_free_checksums(target->image, 0);
target->image->generator_is_running = 0; target->image->generator_is_running = 0;
/* Give up reference claim made in ecma119_image_new(). /* Give up reference claim made in ecma119_image_new().
@ -1605,86 +1649,92 @@ int checksum_prepare_nodes(Ecma119Image *target, IsoNode *node, int flag)
IsoNode *pos; IsoNode *pos;
IsoFile *file; IsoFile *file;
IsoImage *img; IsoImage *img;
int ret, i, no_md5 = 0, has_xinfo = 0; int ret, i, no_md5 = 0, has_xinfo = 0, has_attr = 0;
size_t value_length; size_t old_cx_value_length = 0;
unsigned int idx = 0; unsigned int idx = 0;
char *value= NULL; char *old_cx_value= NULL;
void *xipt = NULL; void *xipt = NULL;
static char *cx_names = "isofs.cx";
static size_t cx_value_lengths[1] = {0};
char *cx_valuept = "";
img= target->image; img= target->image;
if (node->type == LIBISO_FILE) { if (node->type == LIBISO_FILE) {
file = (IsoFile *) node; file = (IsoFile *) node;
if (file->from_old_session) {
/* Record attribute isofs.cx as xinfo before it can get overwritten
for the emerging image.
The recorded index will be used to retrieve the loaded MD5
and it will be brought back into effect if cancellation of
image production prevents that the old MD5 array gets replaced
by the new one.
*/
has_attr = iso_node_lookup_attr(node, "isofs.cx",
&old_cx_value_length, &old_cx_value, 0);
if (has_attr == 1 && old_cx_value_length == 4) {
for (i = 0; i < 4; i++)
idx = (idx << 8) | ((unsigned char *) old_cx_value)[i];
if (idx > 0 && idx < 0x8000000) {
/* xipt is an int disguised as void pointer */
for (i = 0; i < 4; i++)
((char *) &xipt)[i] = old_cx_value[i];
ret = iso_node_add_xinfo(node, checksum_cx_xinfo_func,
xipt);
if (ret < 0)
goto ex;
} else
no_md5 = 1;
}
}
if (file->from_old_session && target->appendable) { if (file->from_old_session && target->appendable) {
/* Save MD5 data of files from old image which will not /* Save MD5 data of files from old image which will not
be copied and have an MD5 recorded in the old image. */ be copied and have an MD5 recorded in the old image. */
has_xinfo = iso_node_get_xinfo(node, checksum_md5_xinfo_func, has_xinfo = iso_node_get_xinfo(node, checksum_md5_xinfo_func,
&xipt); &xipt);
if (has_xinfo <= 0) {
ret = iso_node_lookup_attr(node, "isofs.cx", &value_length,
&value, 0);
}
if (has_xinfo > 0) { if (has_xinfo > 0) {
/* xinfo MD5 overrides everything else unless data get copied /* xinfo MD5 overrides everything else unless data get copied
and checksummed during that copying and checksummed during that copying
*/; */;
} else if (ret == 1 && img->checksum_array == NULL) { } else if (has_attr == 1 && img->checksum_array == NULL) {
/* No checksum array loaded. Delete "isofs.cx" */ /* No checksum array loaded. Delete "isofs.cx" */
if (!target->will_cancel) if (!target->will_cancel)
iso_node_set_attrs(node, (size_t) 1, iso_file_set_isofscx((IsoFile *) node, 0, 1);
&cx_names, cx_value_lengths, &cx_valuept, 4 | 8);
no_md5 = 1; no_md5 = 1;
} else if (ret == 1 && value_length == 4) { } else if (!(has_attr == 1 && old_cx_value_length == 4)) {
for (i = 0; i < 4; i++)
idx = (idx << 8) | ((unsigned char *) value)[i];
if (idx > 0 && idx < 0x8000000) {
/* xipt is an int disguised as void pointer */
for (i = 0; i < 4; i++)
((char *) &xipt)[i] = value[i];
ret = iso_node_add_xinfo(node, checksum_cx_xinfo_func,
xipt);
if (ret < 0)
return ret;
} else
no_md5 = 1;
} else {
no_md5 = 1; no_md5 = 1;
} }
if (value != NULL) {
free(value);
value= NULL;
}
} }
/* Equip nodes with provisory isofs.cx numbers: 4 byte, all 0. /* Equip nodes with provisory isofs.cx numbers: 4 byte, all 0.
Omit those from old image which will not be copied and have no MD5. Omit those from old image which will not be copied and have no MD5.
Do not alter the nodes if this is only a will_cancel run. Do not alter the nodes if this is only a will_cancel run.
*/ */
if (!(target->will_cancel || no_md5)) { if (!(target->will_cancel || no_md5)) {
/* Record provisory new index */
ret = iso_file_set_isofscx(file, (unsigned int) 0, 0); ret = iso_file_set_isofscx(file, (unsigned int) 0, 0);
if (ret < 0) if (ret < 0)
return ret; goto ex;
} }
} else if (node->type == LIBISO_DIR) { } else if (node->type == LIBISO_DIR) {
for (pos = ((IsoDir *) node)->children; pos != NULL; pos = pos->next) { for (pos = ((IsoDir *) node)->children; pos != NULL; pos = pos->next) {
ret = checksum_prepare_nodes(target, pos, 1); ret = checksum_prepare_nodes(target, pos, 1);
if (ret < 0) if (ret < 0)
return ret; goto ex;
} }
} }
return ISO_SUCCESS; ret = ISO_SUCCESS;
ex:;
if (old_cx_value != NULL)
free(old_cx_value);
return ret;
} }
static static
int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img) int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
{ {
int ret, i, voldesc_size, nwriters, image_checksums_mad = 0, tag_pos; int ret, i, voldesc_size, nwriters, tag_pos;
int sa_type; int sa_type;
Ecma119Image *target; Ecma119Image *target;
IsoImageWriter *writer; IsoImageWriter *writer;
int el_torito_writer_index = -1, file_src_writer_index = -1; int file_src_writer_index = -1;
int system_area_options = 0; int system_area_options = 0;
char *system_area = NULL; char *system_area = NULL;
int write_count = 0, write_count_mem; int write_count = 0, write_count_mem;
@ -1994,9 +2044,6 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
nwriters++; /* Tail padding writer */ nwriters++; /* Tail padding writer */
if ((target->md5_file_checksums & 1) || target->md5_session_checksum) { if ((target->md5_file_checksums & 1) || target->md5_session_checksum) {
nwriters++; nwriters++;
image_checksums_mad = 1; /* from here on the loaded checksums are
not consistent with isofs.cx any more.
*/
ret = checksum_prepare_image(src, 0); ret = checksum_prepare_image(src, 0);
if (ret < 0) if (ret < 0)
goto target_cleanup; goto target_cleanup;
@ -2026,7 +2073,6 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
if (ret < 0) { if (ret < 0) {
goto target_cleanup; goto target_cleanup;
} }
el_torito_writer_index = target->nwriters - 1;
} }
/* create writer for Joliet structure */ /* create writer for Joliet structure */
@ -2367,10 +2413,6 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
if (ret < 0) if (ret < 0)
goto target_cleanup; goto target_cleanup;
} }
/* Dispose old image checksum buffer. The one of target is supposed to
get attached at the end of write_function(). */
iso_image_free_checksums(target->image, 0);
image_checksums_mad = 0;
if (target->apm_block_size == 0) { if (target->apm_block_size == 0) {
if (target->gpt_req_count) if (target->gpt_req_count)
@ -2418,9 +2460,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
*img = target; *img = target;
return ISO_SUCCESS; return ISO_SUCCESS;
target_cleanup: ; target_cleanup: ;
if(image_checksums_mad) /* No checksums is better than mad checksums */
iso_image_free_checksums(target->image, 0);
target->image->generator_is_running = 0; target->image->generator_is_running = 0;
ecma119_image_free(target); ecma119_image_free(target);
return ret; return ret;

View File

@ -312,7 +312,8 @@ int iso_tree_add_boot_node(IsoDir *parent, const char *name, IsoBoot **boot)
static static
int create_image(IsoImage *image, const char *image_path, int create_image(IsoImage *image, const char *image_path,
enum eltorito_boot_media_type type, enum eltorito_boot_media_type type,
struct el_torito_boot_image **bootimg) struct el_torito_boot_image **bootimg,
IsoFile **bootnode)
{ {
int ret; int ret;
struct el_torito_boot_image *boot; struct el_torito_boot_image *boot;
@ -323,6 +324,7 @@ int create_image(IsoImage *image, const char *image_path,
IsoNode *imgfile; IsoNode *imgfile;
IsoStream *stream; IsoStream *stream;
*bootnode = NULL;
ret = iso_tree_path_to_node(image, image_path, &imgfile); ret = iso_tree_path_to_node(image, image_path, &imgfile);
if (ret < 0) { if (ret < 0) {
return ret; return ret;
@ -337,6 +339,7 @@ int create_image(IsoImage *image, const char *image_path,
if (imgfile->type != LIBISO_FILE) { if (imgfile->type != LIBISO_FILE) {
return ISO_BOOT_IMAGE_NOT_VALID; return ISO_BOOT_IMAGE_NOT_VALID;
} }
*bootnode = (IsoFile *) imgfile;
stream = ((IsoFile*)imgfile)->stream; stream = ((IsoFile*)imgfile)->stream;
@ -461,6 +464,7 @@ int iso_image_set_boot_image(IsoImage *image, const char *image_path,
struct el_torito_boot_catalog *catalog; struct el_torito_boot_catalog *catalog;
ElToritoBootImage *boot_image= NULL; ElToritoBootImage *boot_image= NULL;
IsoBoot *cat_node= NULL; IsoBoot *cat_node= NULL;
IsoFile *boot_node;
if (image == NULL || image_path == NULL || catalog_path == NULL) { if (image == NULL || image_path == NULL || catalog_path == NULL) {
return ISO_NULL_POINTER; return ISO_NULL_POINTER;
@ -513,7 +517,7 @@ int iso_image_set_boot_image(IsoImage *image, const char *image_path,
} }
/* create the boot image */ /* create the boot image */
ret = create_image(image, image_path, type, &boot_image); ret = create_image(image, image_path, type, &boot_image, &boot_node);
if (ret < 0) { if (ret < 0) {
goto boot_image_cleanup; goto boot_image_cleanup;
} }
@ -530,6 +534,8 @@ int iso_image_set_boot_image(IsoImage *image, const char *image_path,
catalog->bootimages[i] = NULL; catalog->bootimages[i] = NULL;
catalog->node = cat_node; catalog->node = cat_node;
catalog->sort_weight = 1000; /* slightly high */ catalog->sort_weight = 1000; /* slightly high */
if (!boot_node->explicit_weight)
boot_node->sort_weight = 2;
iso_node_ref((IsoNode*)cat_node); iso_node_ref((IsoNode*)cat_node);
image->bootcat = catalog; image->bootcat = catalog;
@ -700,14 +706,17 @@ int iso_image_add_boot_image(IsoImage *image, const char *image_path,
int ret; int ret;
struct el_torito_boot_catalog *catalog = image->bootcat; struct el_torito_boot_catalog *catalog = image->bootcat;
ElToritoBootImage *boot_img; ElToritoBootImage *boot_img;
IsoFile *boot_node;
if(catalog == NULL) if(catalog == NULL)
return ISO_BOOT_NO_CATALOG; return ISO_BOOT_NO_CATALOG;
if (catalog->num_bootimages >= Libisofs_max_boot_imageS) if (catalog->num_bootimages >= Libisofs_max_boot_imageS)
return ISO_BOOT_IMAGE_OVERFLOW; return ISO_BOOT_IMAGE_OVERFLOW;
ret = create_image(image, image_path, type, &boot_img); ret = create_image(image, image_path, type, &boot_img, &boot_node);
if (ret < 0) if (ret < 0)
return ret; return ret;
if (!boot_node->explicit_weight)
boot_node->sort_weight = 2;
catalog->bootimages[catalog->num_bootimages] = boot_img; catalog->bootimages[catalog->num_bootimages] = boot_img;
catalog->num_bootimages++; catalog->num_bootimages++;
if (boot != NULL) if (boot != NULL)

View File

@ -158,7 +158,7 @@ int iso_file_src_create(Ecma119Image *img, IsoFile *file, IsoFileSrc **src)
fsrc->checksum_index = img->checksum_idx_counter; fsrc->checksum_index = img->checksum_idx_counter;
} else { } else {
fsrc->checksum_index= 0; fsrc->checksum_index= 0;
img->checksum_idx_counter= 0x7fffffff; /* keep from rolling over */ img->checksum_idx_counter= 0x7ffffffe; /* keep from rolling over */
} }
cret = iso_file_set_isofscx(file, (*src)->checksum_index, 0); cret = iso_file_set_isofscx(file, (*src)->checksum_index, 0);
if (cret < 0) if (cret < 0)

View File

@ -128,7 +128,7 @@ int set_hfsplus_name(Ecma119Image *t, char *name, HFSPlusNode *node)
return ISO_SUCCESS; return ISO_SUCCESS;
} }
ret = str2ucs(t->input_charset, name, &ucs_name); ret = str2utf16be(t->input_charset, name, &ucs_name);
if (ret < 0) { if (ret < 0) {
iso_msg_debug(t->image->id, "Can't convert %s", name); iso_msg_debug(t->image->id, "Can't convert %s", name);
return ret; return ret;
@ -477,8 +477,8 @@ static
int hfsplus_writer_compute_data_blocks(IsoImageWriter *writer) int hfsplus_writer_compute_data_blocks(IsoImageWriter *writer)
{ {
Ecma119Image *t; Ecma119Image *t;
uint32_t i, link_blocks, hfsp_curblock; uint32_t i, hfsp_curblock;
uint32_t block_fac, cat_node_size, block_size; uint32_t block_fac, block_size;
if (writer == NULL) { if (writer == NULL) {
return ISO_OUT_OF_MEM; return ISO_OUT_OF_MEM;
@ -487,7 +487,6 @@ int hfsplus_writer_compute_data_blocks(IsoImageWriter *writer)
t = writer->target; t = writer->target;
block_size = t->hfsp_block_size; block_size = t->hfsp_block_size;
block_fac = t->hfsp_iso_block_fac; block_fac = t->hfsp_iso_block_fac;
cat_node_size = t->hfsp_cat_node_size;
iso_msg_debug(t->image->id, "(b) curblock=%d, nodes =%d", t->curblock, t->hfsp_nnodes); iso_msg_debug(t->image->id, "(b) curblock=%d, nodes =%d", t->curblock, t->hfsp_nnodes);
t->hfsp_part_start = t->curblock * block_fac; t->hfsp_part_start = t->curblock * block_fac;
@ -500,7 +499,7 @@ int hfsplus_writer_compute_data_blocks(IsoImageWriter *writer)
t->hfsp_catalog_file_start = hfsp_curblock; t->hfsp_catalog_file_start = hfsp_curblock;
/* /*
hfsp_curblock += (t->hfsp_nnodes * cat_node_size + block_size - 1) / block_size; hfsp_curblock += (t->hfsp_nnodes * t->hfsp_cat_node_size + block_size - 1) / block_size;
*/ */
hfsp_curblock += 2 * t->hfsp_nnodes; hfsp_curblock += 2 * t->hfsp_nnodes;
@ -509,7 +508,6 @@ int hfsplus_writer_compute_data_blocks(IsoImageWriter *writer)
iso_msg_debug(t->image->id, "(d) hfsp_curblock=%d, nodes =%d", hfsp_curblock, t->hfsp_nnodes); iso_msg_debug(t->image->id, "(d) hfsp_curblock=%d, nodes =%d", hfsp_curblock, t->hfsp_nnodes);
link_blocks = 0;
for (i = 0; i < t->hfsp_nleafs; i++) for (i = 0; i < t->hfsp_nleafs; i++)
if (t->hfsp_leafs[i].unix_type == UNIX_SYMLINK) if (t->hfsp_leafs[i].unix_type == UNIX_SYMLINK)
{ {
@ -1227,7 +1225,7 @@ int update_symlink(Ecma119Image *target, uint32_t changed_idx, char *new_name,
char *orig_dest, *orig_start, *orig_end; char *orig_dest, *orig_start, *orig_end;
char *hfsp_dest, *hfsp_start, *hfsp_end; char *hfsp_dest, *hfsp_start, *hfsp_end;
int ret = 0; int ret = 0;
unsigned int comp_len, orig_len, hfsp_len, hfsp_comp_len; unsigned int comp_len, orig_len, hfsp_len;
if (target->hfsp_leafs[link_idx].node->type != LIBISO_SYMLINK) if (target->hfsp_leafs[link_idx].node->type != LIBISO_SYMLINK)
return ISO_SUCCESS; return ISO_SUCCESS;
@ -1271,7 +1269,6 @@ int update_symlink(Ecma119Image *target, uint32_t changed_idx, char *new_name,
hfsp_end = strchr(hfsp_start, '/'); hfsp_end = strchr(hfsp_start, '/');
if (hfsp_end == NULL) if (hfsp_end == NULL)
hfsp_end = hfsp_start + strlen(hfsp_start); hfsp_end = hfsp_start + strlen(hfsp_start);
hfsp_comp_len = hfsp_end - hfsp_start;
if (comp_len == 0 || (comp_len == 1 && orig_start[0] == '.')) if (comp_len == 0 || (comp_len == 1 && orig_start[0] == '.'))
continue; continue;

View File

@ -406,6 +406,7 @@ static
int dir_update_size(IsoImage *image, IsoDir *dir) int dir_update_size(IsoImage *image, IsoDir *dir)
{ {
IsoNode *pos; IsoNode *pos;
int ret;
#ifdef Libisofs_update_sizes_abortablE #ifdef Libisofs_update_sizes_abortablE
char *path= NULL; char *path= NULL;
@ -416,7 +417,6 @@ int dir_update_size(IsoImage *image, IsoDir *dir)
pos = dir->children; pos = dir->children;
while (pos) { while (pos) {
int ret = 1;
if (pos->type == LIBISO_FILE) { if (pos->type == LIBISO_FILE) {
ret = iso_stream_update_size(ISO_FILE(pos)->stream); ret = iso_stream_update_size(ISO_FILE(pos)->stream);
} else if (pos->type == LIBISO_DIR) { } else if (pos->type == LIBISO_DIR) {
@ -428,6 +428,8 @@ int dir_update_size(IsoImage *image, IsoDir *dir)
return ret; /* Message already issued by dir_update_size */ return ret; /* Message already issued by dir_update_size */
#endif #endif
} else {
ret = 1;
} }
#ifdef Libisofs_update_sizes_abortablE #ifdef Libisofs_update_sizes_abortablE
@ -465,7 +467,12 @@ int dir_update_size(IsoImage *image, IsoDir *dir)
return cancel_ret; /* cancel due error threshold */ return cancel_ret; /* cancel due error threshold */
} }
#endif /* Libisofs_update_sizes_abortablE */ #else
if (ret < 0)
ret = 1; /* ignore error */
#endif /* ! Libisofs_update_sizes_abortablE */
pos = pos->next; pos = pos->next;
} }

View File

@ -308,7 +308,7 @@ int mangle_single_dir(Ecma119Image *img, Iso1999Node *dir)
int ret; int ret;
int i, nchildren; int i, nchildren;
Iso1999Node **children; Iso1999Node **children;
IsoHTable *table; IsoHTable *table = NULL;
int need_sort = 0; int need_sort = 0;
char *full_name = NULL, *tmp = NULL; char *full_name = NULL, *tmp = NULL;

View File

@ -349,7 +349,7 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
int ret; int ret;
int i, nchildren, maxchar = 64; int i, nchildren, maxchar = 64;
JolietNode **children; JolietNode **children;
IsoHTable *table; IsoHTable *table = NULL;
int need_sort = 0; int need_sort = 0;
uint16_t *full_name = NULL; uint16_t *full_name = NULL;
uint16_t *tmp = NULL; uint16_t *tmp = NULL;

View File

@ -84,7 +84,7 @@
*/ */
#define iso_lib_header_version_major 1 #define iso_lib_header_version_major 1
#define iso_lib_header_version_minor 3 #define iso_lib_header_version_minor 3
#define iso_lib_header_version_micro 2 #define iso_lib_header_version_micro 4
/** /**
* Get version of the libisofs library at runtime. * Get version of the libisofs library at runtime.

View File

@ -563,7 +563,7 @@ int make_isolinux_mbr(int32_t *img_blocks, Ecma119Image *t,
uint32_t id, part, nominal_part_size; uint32_t id, part, nominal_part_size;
off_t hd_img_blocks, hd_boot_lba; off_t hd_img_blocks, hd_boot_lba;
char *wpt; char *wpt;
uint32_t boot_lba, mbr_id; uint32_t boot_lba;
int head_count, sector_count, ret; int head_count, sector_count, ret;
int gpt_count = 0, gpt_idx[128], apm_count = 0, gpt_cursor; int gpt_count = 0, gpt_idx[128], apm_count = 0, gpt_cursor;
/* For generating a weak random number */ /* For generating a weak random number */
@ -573,7 +573,6 @@ int make_isolinux_mbr(int32_t *img_blocks, Ecma119Image *t,
hd_img_blocks = ((off_t) *img_blocks) * (off_t) 4; hd_img_blocks = ((off_t) *img_blocks) * (off_t) 4;
boot_lba = t->bootsrc[0]->sections[0].block; boot_lba = t->bootsrc[0]->sections[0].block;
mbr_id = 0;
head_count = t->partition_heads_per_cyl; head_count = t->partition_heads_per_cyl;
sector_count = t->partition_secs_per_head; sector_count = t->partition_secs_per_head;
@ -608,6 +607,8 @@ int make_isolinux_mbr(int32_t *img_blocks, Ecma119Image *t,
gettimeofday(&tv, &tz); gettimeofday(&tv, &tz);
id = 0xffffffff & (tv.tv_sec ^ (tv.tv_usec * 2000)); id = 0xffffffff & (tv.tv_sec ^ (tv.tv_usec * 2000));
lsb_to_buf(&wpt, id, 32, 0); lsb_to_buf(&wpt, id, 32, 0);
} else {
wpt+= 4;
} }
/* write word 0 # Offset 444 /* write word 0 # Offset 444

View File

@ -540,13 +540,12 @@ int checksum_copy_old_nodes(Ecma119Image *target, IsoNode *node, int flag)
if (value != NULL) if (value != NULL)
free(value); free(value);
/* ts B30114 : It is unclear why these are removed here. /* >>> ts B30114 : It is unclear why these are removed here.
At least with the opts->will_cancel runs, At least with the opts->will_cancel runs,
this is not appropriate. this is not appropriate.
*/ */
iso_node_remove_xinfo(node, checksum_md5_xinfo_func); iso_node_remove_xinfo(node, checksum_md5_xinfo_func);
} }
iso_node_remove_xinfo(node, checksum_cx_xinfo_func);
} }
} else if (node->type == LIBISO_DIR) { } else if (node->type == LIBISO_DIR) {
for (pos = ((IsoDir *) node)->children; pos != NULL; pos = pos->next) { for (pos = ((IsoDir *) node)->children; pos != NULL; pos = pos->next) {

View File

@ -1048,6 +1048,7 @@ void iso_node_set_sort_weight(IsoNode *node, int w)
} }
} else if (node->type == LIBISO_FILE) { } else if (node->type == LIBISO_FILE) {
((IsoFile*)node)->sort_weight = w; ((IsoFile*)node)->sort_weight = w;
((IsoFile*)node)->explicit_weight = 1;
} }
} }
@ -1430,6 +1431,8 @@ int iso_node_new_file(char *name, IsoStream *stream, IsoFile **file)
new->node.type = LIBISO_FILE; new->node.type = LIBISO_FILE;
new->node.name = name; new->node.name = name;
new->node.mode = S_IFREG; new->node.mode = S_IFREG;
new->from_old_session = 0;
new->explicit_weight = 0;
new->sort_weight = 0; new->sort_weight = 0;
new->stream = stream; new->stream = stream;
@ -2566,6 +2569,7 @@ int iso_node_set_ino(IsoNode *node, ino_t ino, int flag)
ret = iso_stream_set_image_ino(file->stream, ino, 0); ret = iso_stream_set_image_ino(file->stream, ino, 0);
if (ret < 0 || ret == 1) if (ret < 0 || ret == 1)
return ret; return ret;
/* ret == 0 means that the stream is not from loaded ISO image */
} else if (node->type == LIBISO_SYMLINK) { } else if (node->type == LIBISO_SYMLINK) {
symlink = (IsoSymlink *) node; symlink = (IsoSymlink *) node;
@ -2756,6 +2760,8 @@ int iso_node_cmp_ino(IsoNode *n1, IsoNode *n2, int flag)
} }
/* @param flag bit0= delete isofs.cx rather than setting it
*/
int iso_file_set_isofscx(IsoFile *file, unsigned int checksum_index, int iso_file_set_isofscx(IsoFile *file, unsigned int checksum_index,
int flag) int flag)
{ {
@ -2765,9 +2771,14 @@ int iso_file_set_isofscx(IsoFile *file, unsigned int checksum_index,
char *valuept; char *valuept;
int i, ret; int i, ret;
valuept= (char *) value;
if (flag & 1) {
ret = iso_node_set_attrs((IsoNode *) file, (size_t) 1,
&names, value_lengths, &valuept, 4 | 8);
return ret;
}
for(i = 0; i < 4; i++) for(i = 0; i < 4; i++)
value[3 - i] = (checksum_index >> (8 * i)) & 0xff; value[3 - i] = (checksum_index >> (8 * i)) & 0xff;
valuept= (char *) value;
ret = iso_node_set_attrs((IsoNode *) file, (size_t) 1, ret = iso_node_set_attrs((IsoNode *) file, (size_t) 1,
&names, value_lengths, &valuept, 2 | 8); &names, value_lengths, &valuept, 2 | 8);
return ret; return ret;

View File

@ -149,8 +149,15 @@ struct Iso_File
{ {
IsoNode node; IsoNode node;
/* 1 = The node was loaded from an existing ISO image and still refers
to its data content there.
*/
unsigned int from_old_session : 1; unsigned int from_old_session : 1;
/* 1 = The node got attributed a weight by iso_node_set_sort_weight().
*/
unsigned int explicit_weight : 1;
/** /**
* It sorts the order in which the file data is written to the CD image. * It sorts the order in which the file data is written to the CD image.
* Higher weighting files are written at the beginning of image * Higher weighting files are written at the beginning of image

View File

@ -667,6 +667,123 @@ int str2ucs(const char *icharset, const char *input, uint16_t **output)
return ISO_SUCCESS; return ISO_SUCCESS;
} }
int str2utf16be(const char *icharset, const char *input, uint16_t **output)
{
int result;
wchar_t *wsrc_ = NULL;
char *src;
char *ret = NULL;
char *ret_ = NULL;
struct iso_iconv_handle conv;
int conv_ret = 0;
int direct_conv = 0;
size_t loop_counter = 0, loop_limit = 3;
size_t numchars;
size_t outbytes;
size_t inbytes;
size_t n;
if (icharset == NULL || input == NULL || output == NULL) {
return ISO_NULL_POINTER;
}
/*
Try the direct conversion.
*/
conv_ret = iso_iconv_open(&conv, "UTF-16BE", (char *) icharset, 0);
if (conv_ret > 0) {
direct_conv = 1;
src = (char *) input;
inbytes = strlen(input);
loop_limit = inbytes + 3;
outbytes = (2 * inbytes + 1) * sizeof(uint16_t);
ret_ = malloc(outbytes);
if (ret_ == NULL)
return ISO_OUT_OF_MEM;
ret = ret_;
} else {
/* Try via intermediate character set WCHAR_T.
*/
result = str2wchar(icharset, input, &wsrc_);
if (result == (int) ISO_SUCCESS) {
src = (char *)wsrc_;
numchars = wcslen(wsrc_);
inbytes = numchars * sizeof(wchar_t);
loop_limit = inbytes + 3;
ret_ = malloc((2 * numchars+1) * sizeof(uint16_t));
if (ret_ == NULL)
return ISO_OUT_OF_MEM;
outbytes = 2 * numchars * sizeof(uint16_t);
ret = ret_;
/* initialize iconv */
conv_ret = iso_iconv_open(&conv, "UTF-16BE", "WCHAR_T", 0);
if (conv_ret <= 0) {
free(wsrc_);
free(ret_);
}
} else if (result != (int) ISO_CHARSET_CONV_ERROR)
return result;
}
if (conv_ret <= 0) {
return ISO_CHARSET_CONV_ERROR;
}
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
while (n == (size_t) -1) {
/* The destination buffer is too small. Stops here. */
if (errno == E2BIG)
break;
/* An incomplete multi bytes sequence was found. We
* can't do anything here. That's quite unlikely. */
if (errno == EINVAL)
break;
/* The last possible error is an invalid multi bytes
* sequence. Just replace the character with a "_".
* Probably the character doesn't exist in UCS */
set_ucsbe((uint16_t*) ret, '_');
ret += sizeof(uint16_t);
outbytes -= sizeof(uint16_t);
if (!outbytes)
break;
/* There was an error with one character but some other remain
* to be converted. That's probably a multibyte character.
* See above comment. */
if (direct_conv) {
src++;
inbytes--;
} else {
src += sizeof(wchar_t);
inbytes -= sizeof(wchar_t);
}
if (!inbytes)
break;
/* Just to appease my remorse about unclear loop ends */
loop_counter++;
if (loop_counter > loop_limit)
break;
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
}
iso_iconv_close(&conv, 0);
/* close the UTF-16 string */
set_ucsbe((uint16_t*) ret, '\0');
if (wsrc_ != NULL)
free(wsrc_);
*output = (uint16_t*)ret_;
return ISO_SUCCESS;
}
static int valid_d_char(char c) static int valid_d_char(char c)
{ {
return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c == '_'); return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c == '_');

View File

@ -88,6 +88,22 @@ int str2ascii(const char *icharset, const char *input, char **output);
*/ */
int str2ucs(const char *icharset, const char *input, uint16_t **output); int str2ucs(const char *icharset, const char *input, uint16_t **output);
/**
* Convert a given string from any input charset to UTF-16BE charset,
* used for HFS+ file identifiers.
* (UTF-16 differs from older UCS-2 by having multi word characters.)
*
* @param icharset
* Input charset. Must be supported by iconv
* @param input
* Input string
* @param output
* Location where the pointer to the ouput string will be stored
* @return
* 1 on success, < 0 on error
*/
int str2utf16be(const char *icharset, const char *input, uint16_t **output);
/** /**
* Create a level 1 directory identifier. * Create a level 1 directory identifier.
* *