Compare commits
15 Commits
release-1.
...
release-1.
Author | SHA1 | Date | |
---|---|---|---|
b7dc0f4057 | |||
0ab9f5f8d2 | |||
1338f29d62 | |||
bc5e2227c8 | |||
654ff82345 | |||
6baeae70e0 | |||
b987972660 | |||
c78526abce | |||
b95e1bb85c | |||
7aa2582129 | |||
3f29d70aba | |||
567d3ddafb | |||
c47f85c639 | |||
40310b4fd7 | |||
f34c274f21 |
@ -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
|
||||
===============================================================================
|
||||
* Bug fix: iso_finish() left an invalid global pointer, which a subsequent
|
||||
|
2
README
2
README
@ -4,7 +4,7 @@
|
||||
|
||||
Released under GPL (see COPYING file for details).
|
||||
|
||||
Copyright (C) 2008 - 2012 Vreixo Formoso,
|
||||
Copyright (C) 2008 - 2013 Vreixo Formoso,
|
||||
Mario Danic,
|
||||
Vladimir Serbinenko,
|
||||
Thomas Schmitt
|
||||
|
12
configure.ac
12
configure.ac
@ -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])
|
||||
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
|
||||
LIBISOFS_MAJOR_VERSION=1
|
||||
LIBISOFS_MINOR_VERSION=3
|
||||
LIBISOFS_MICRO_VERSION=2
|
||||
LIBISOFS_MICRO_VERSION=4
|
||||
LIBISOFS_VERSION=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION.$LIBISOFS_MICRO_VERSION
|
||||
|
||||
AC_SUBST(LIBISOFS_MAJOR_VERSION)
|
||||
@ -51,10 +51,10 @@ AC_SUBST(LIBISOFS_VERSION)
|
||||
|
||||
dnl Libtool versioning
|
||||
LT_RELEASE=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION
|
||||
# 2013.08.07 development jump has not yet happened
|
||||
# SONAME = 74 - 68 = 6 . Library name = libisofs.6.68.0
|
||||
LT_CURRENT=74
|
||||
LT_AGE=68
|
||||
# 2013.12.12 development jump has not yet happened
|
||||
# SONAME = 76 - 70 = 6 . Library name = libisofs.6.70.0
|
||||
LT_CURRENT=76
|
||||
LT_AGE=70
|
||||
LT_REVISION=0
|
||||
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
|
||||
|
||||
|
@ -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.
|
||||
|
||||
Boot Info Table and GRUB2 Boot Info
|
||||
|
||||
Master Boot Record (MBR), for PC-BIOS x86 from (pseudo-) hard disk
|
||||
|
||||
Apple Partition Map (APM), for more modern Mac
|
||||
@ -48,7 +50,6 @@ Sources:
|
||||
El Torito, Bootable CD-ROM Format Specification, Version 1.0, 1995
|
||||
which refers to ECMA-119, the standard for ISO 9660 filesystems.
|
||||
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
|
||||
@ -237,10 +238,22 @@ Byte Range | Value | Meaning
|
||||
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.
|
||||
Nevertheless there is a tradition named "Boot Info Table" which prescribes
|
||||
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
|
||||
detect the need for Boot Info Table production.
|
||||
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
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
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.
|
||||
| |
|
||||
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.
|
||||
| |
|
||||
20 - 23 | checksum | Little-endian: The sum of all 32-bit words of the
|
||||
| | file content from byte 64 to file end.
|
||||
20 - 23 | checksum | The sum of all 32-bit words of the file content
|
||||
| | from byte 64 to file end.
|
||||
| |
|
||||
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.
|
||||
|
||||
|
||||
The MBR file that is used with GRUB2 script grub-mkrescue needs only a
|
||||
partition table entry which describes the image size.
|
||||
The MBR file that is used with older versions of GRUB2 script grub-mkrescue
|
||||
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
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
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
|
||||
| |
|
||||
|
@ -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
|
||||
number of component bytes in the Component Record. This length shall not
|
||||
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.
|
||||
|
||||
[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
|
||||
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
|
||||
makes use of AAIP. Please mail change requests to mailing list
|
||||
<libburn-hackers@pykix.org> or to the copyright holder in private.
|
||||
|
@ -2065,7 +2065,7 @@ int aaip_decode_acl(unsigned char *data, size_t num_data, size_t *consumed,
|
||||
unsigned char *rpt;
|
||||
char perm_text[4], *wpt, *name= NULL;
|
||||
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;
|
||||
gid_t gid;
|
||||
struct passwd *pwd;
|
||||
|
@ -1230,6 +1230,48 @@ int zero_writer_create(Ecma119Image *target, uint32_t num_blocks, int flag)
|
||||
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
|
||||
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_buffer = NULL;
|
||||
target->checksum_idx_counter = 0;
|
||||
|
||||
/* Delete recorded cx xinfo */
|
||||
process_preserved_cx(target->image->root, 0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1546,7 +1592,7 @@ void *write_function(void *arg)
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
write_error: ;
|
||||
write_error: ;
|
||||
if (res != (int) ISO_LIBJTE_END_FAILED)
|
||||
finish_libjte(target);
|
||||
target->eff_partition_offset = 0;
|
||||
@ -1562,11 +1608,9 @@ void *write_function(void *arg)
|
||||
}
|
||||
iso_ring_buffer_writer_close(target->buffer, 1);
|
||||
|
||||
/* Transplant checksum buffer away from Ecma119Image */
|
||||
transplant_checksum_buffer(target, 0);
|
||||
/* Invalidate the transplanted checksum buffer in IsoImage */
|
||||
iso_image_free_checksums(target->image, 0);
|
||||
|
||||
/* Re-activate recorded cx xinfo */
|
||||
process_preserved_cx(target->image->root, 1);
|
||||
|
||||
target->image->generator_is_running = 0;
|
||||
|
||||
/* 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;
|
||||
IsoFile *file;
|
||||
IsoImage *img;
|
||||
int ret, i, no_md5 = 0, has_xinfo = 0;
|
||||
size_t value_length;
|
||||
int ret, i, no_md5 = 0, has_xinfo = 0, has_attr = 0;
|
||||
size_t old_cx_value_length = 0;
|
||||
unsigned int idx = 0;
|
||||
char *value= NULL;
|
||||
char *old_cx_value= NULL;
|
||||
void *xipt = NULL;
|
||||
static char *cx_names = "isofs.cx";
|
||||
static size_t cx_value_lengths[1] = {0};
|
||||
char *cx_valuept = "";
|
||||
|
||||
img= target->image;
|
||||
|
||||
if (node->type == LIBISO_FILE) {
|
||||
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) {
|
||||
/* Save MD5 data of files from old image which will not
|
||||
be copied and have an MD5 recorded in the old image. */
|
||||
has_xinfo = iso_node_get_xinfo(node, checksum_md5_xinfo_func,
|
||||
&xipt);
|
||||
if (has_xinfo <= 0) {
|
||||
ret = iso_node_lookup_attr(node, "isofs.cx", &value_length,
|
||||
&value, 0);
|
||||
}
|
||||
if (has_xinfo > 0) {
|
||||
/* xinfo MD5 overrides everything else unless data get copied
|
||||
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" */
|
||||
if (!target->will_cancel)
|
||||
iso_node_set_attrs(node, (size_t) 1,
|
||||
&cx_names, cx_value_lengths, &cx_valuept, 4 | 8);
|
||||
iso_file_set_isofscx((IsoFile *) node, 0, 1);
|
||||
no_md5 = 1;
|
||||
} else if (ret == 1 && 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 {
|
||||
} else if (!(has_attr == 1 && old_cx_value_length == 4)) {
|
||||
no_md5 = 1;
|
||||
}
|
||||
if (value != NULL) {
|
||||
free(value);
|
||||
value= NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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.
|
||||
Do not alter the nodes if this is only a will_cancel run.
|
||||
*/
|
||||
if (!(target->will_cancel || no_md5)) {
|
||||
/* Record provisory new index */
|
||||
ret = iso_file_set_isofscx(file, (unsigned int) 0, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
} else if (node->type == LIBISO_DIR) {
|
||||
for (pos = ((IsoDir *) node)->children; pos != NULL; pos = pos->next) {
|
||||
ret = checksum_prepare_nodes(target, pos, 1);
|
||||
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
|
||||
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;
|
||||
Ecma119Image *target;
|
||||
IsoImageWriter *writer;
|
||||
int el_torito_writer_index = -1, file_src_writer_index = -1;
|
||||
int file_src_writer_index = -1;
|
||||
int system_area_options = 0;
|
||||
char *system_area = NULL;
|
||||
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 */
|
||||
if ((target->md5_file_checksums & 1) || target->md5_session_checksum) {
|
||||
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);
|
||||
if (ret < 0)
|
||||
goto target_cleanup;
|
||||
@ -2026,7 +2073,6 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
if (ret < 0) {
|
||||
goto target_cleanup;
|
||||
}
|
||||
el_torito_writer_index = target->nwriters - 1;
|
||||
}
|
||||
|
||||
/* create writer for Joliet structure */
|
||||
@ -2367,10 +2413,6 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
if (ret < 0)
|
||||
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->gpt_req_count)
|
||||
@ -2418,9 +2460,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
*img = target;
|
||||
return ISO_SUCCESS;
|
||||
|
||||
target_cleanup: ;
|
||||
if(image_checksums_mad) /* No checksums is better than mad checksums */
|
||||
iso_image_free_checksums(target->image, 0);
|
||||
target_cleanup: ;
|
||||
target->image->generator_is_running = 0;
|
||||
ecma119_image_free(target);
|
||||
return ret;
|
||||
|
@ -312,7 +312,8 @@ int iso_tree_add_boot_node(IsoDir *parent, const char *name, IsoBoot **boot)
|
||||
static
|
||||
int create_image(IsoImage *image, const char *image_path,
|
||||
enum eltorito_boot_media_type type,
|
||||
struct el_torito_boot_image **bootimg)
|
||||
struct el_torito_boot_image **bootimg,
|
||||
IsoFile **bootnode)
|
||||
{
|
||||
int ret;
|
||||
struct el_torito_boot_image *boot;
|
||||
@ -323,6 +324,7 @@ int create_image(IsoImage *image, const char *image_path,
|
||||
IsoNode *imgfile;
|
||||
IsoStream *stream;
|
||||
|
||||
*bootnode = NULL;
|
||||
ret = iso_tree_path_to_node(image, image_path, &imgfile);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
@ -337,6 +339,7 @@ int create_image(IsoImage *image, const char *image_path,
|
||||
if (imgfile->type != LIBISO_FILE) {
|
||||
return ISO_BOOT_IMAGE_NOT_VALID;
|
||||
}
|
||||
*bootnode = (IsoFile *) imgfile;
|
||||
|
||||
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;
|
||||
ElToritoBootImage *boot_image= NULL;
|
||||
IsoBoot *cat_node= NULL;
|
||||
IsoFile *boot_node;
|
||||
|
||||
if (image == NULL || image_path == NULL || catalog_path == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
@ -513,7 +517,7 @@ int iso_image_set_boot_image(IsoImage *image, const char *image_path,
|
||||
}
|
||||
|
||||
/* 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) {
|
||||
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->node = cat_node;
|
||||
catalog->sort_weight = 1000; /* slightly high */
|
||||
if (!boot_node->explicit_weight)
|
||||
boot_node->sort_weight = 2;
|
||||
iso_node_ref((IsoNode*)cat_node);
|
||||
image->bootcat = catalog;
|
||||
|
||||
@ -700,14 +706,17 @@ int iso_image_add_boot_image(IsoImage *image, const char *image_path,
|
||||
int ret;
|
||||
struct el_torito_boot_catalog *catalog = image->bootcat;
|
||||
ElToritoBootImage *boot_img;
|
||||
IsoFile *boot_node;
|
||||
|
||||
if(catalog == NULL)
|
||||
return ISO_BOOT_NO_CATALOG;
|
||||
if (catalog->num_bootimages >= Libisofs_max_boot_imageS)
|
||||
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)
|
||||
return ret;
|
||||
if (!boot_node->explicit_weight)
|
||||
boot_node->sort_weight = 2;
|
||||
catalog->bootimages[catalog->num_bootimages] = boot_img;
|
||||
catalog->num_bootimages++;
|
||||
if (boot != NULL)
|
||||
|
@ -158,7 +158,7 @@ int iso_file_src_create(Ecma119Image *img, IsoFile *file, IsoFileSrc **src)
|
||||
fsrc->checksum_index = img->checksum_idx_counter;
|
||||
} else {
|
||||
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);
|
||||
if (cret < 0)
|
||||
|
@ -128,7 +128,7 @@ int set_hfsplus_name(Ecma119Image *t, char *name, HFSPlusNode *node)
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
ret = str2ucs(t->input_charset, name, &ucs_name);
|
||||
ret = str2utf16be(t->input_charset, name, &ucs_name);
|
||||
if (ret < 0) {
|
||||
iso_msg_debug(t->image->id, "Can't convert %s", name);
|
||||
return ret;
|
||||
@ -477,8 +477,8 @@ static
|
||||
int hfsplus_writer_compute_data_blocks(IsoImageWriter *writer)
|
||||
{
|
||||
Ecma119Image *t;
|
||||
uint32_t i, link_blocks, hfsp_curblock;
|
||||
uint32_t block_fac, cat_node_size, block_size;
|
||||
uint32_t i, hfsp_curblock;
|
||||
uint32_t block_fac, block_size;
|
||||
|
||||
if (writer == NULL) {
|
||||
return ISO_OUT_OF_MEM;
|
||||
@ -487,7 +487,6 @@ int hfsplus_writer_compute_data_blocks(IsoImageWriter *writer)
|
||||
t = writer->target;
|
||||
block_size = t->hfsp_block_size;
|
||||
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);
|
||||
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;
|
||||
|
||||
/*
|
||||
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;
|
||||
|
||||
@ -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);
|
||||
|
||||
link_blocks = 0;
|
||||
for (i = 0; i < t->hfsp_nleafs; i++)
|
||||
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 *hfsp_dest, *hfsp_start, *hfsp_end;
|
||||
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)
|
||||
return ISO_SUCCESS;
|
||||
@ -1271,7 +1269,6 @@ int update_symlink(Ecma119Image *target, uint32_t changed_idx, char *new_name,
|
||||
hfsp_end = strchr(hfsp_start, '/');
|
||||
if (hfsp_end == NULL)
|
||||
hfsp_end = hfsp_start + strlen(hfsp_start);
|
||||
hfsp_comp_len = hfsp_end - hfsp_start;
|
||||
|
||||
if (comp_len == 0 || (comp_len == 1 && orig_start[0] == '.'))
|
||||
continue;
|
||||
|
@ -406,6 +406,7 @@ static
|
||||
int dir_update_size(IsoImage *image, IsoDir *dir)
|
||||
{
|
||||
IsoNode *pos;
|
||||
int ret;
|
||||
|
||||
#ifdef Libisofs_update_sizes_abortablE
|
||||
char *path= NULL;
|
||||
@ -416,7 +417,6 @@ int dir_update_size(IsoImage *image, IsoDir *dir)
|
||||
|
||||
pos = dir->children;
|
||||
while (pos) {
|
||||
int ret = 1;
|
||||
if (pos->type == LIBISO_FILE) {
|
||||
ret = iso_stream_update_size(ISO_FILE(pos)->stream);
|
||||
} 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 */
|
||||
#endif
|
||||
|
||||
} else {
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
#ifdef Libisofs_update_sizes_abortablE
|
||||
@ -465,7 +467,12 @@ int dir_update_size(IsoImage *image, IsoDir *dir)
|
||||
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;
|
||||
}
|
||||
|
@ -308,7 +308,7 @@ int mangle_single_dir(Ecma119Image *img, Iso1999Node *dir)
|
||||
int ret;
|
||||
int i, nchildren;
|
||||
Iso1999Node **children;
|
||||
IsoHTable *table;
|
||||
IsoHTable *table = NULL;
|
||||
int need_sort = 0;
|
||||
char *full_name = NULL, *tmp = NULL;
|
||||
|
||||
|
@ -349,7 +349,7 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
|
||||
int ret;
|
||||
int i, nchildren, maxchar = 64;
|
||||
JolietNode **children;
|
||||
IsoHTable *table;
|
||||
IsoHTable *table = NULL;
|
||||
int need_sort = 0;
|
||||
uint16_t *full_name = NULL;
|
||||
uint16_t *tmp = NULL;
|
||||
|
@ -84,7 +84,7 @@
|
||||
*/
|
||||
#define iso_lib_header_version_major 1
|
||||
#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.
|
||||
|
@ -563,7 +563,7 @@ int make_isolinux_mbr(int32_t *img_blocks, Ecma119Image *t,
|
||||
uint32_t id, part, nominal_part_size;
|
||||
off_t hd_img_blocks, hd_boot_lba;
|
||||
char *wpt;
|
||||
uint32_t boot_lba, mbr_id;
|
||||
uint32_t boot_lba;
|
||||
int head_count, sector_count, ret;
|
||||
int gpt_count = 0, gpt_idx[128], apm_count = 0, gpt_cursor;
|
||||
/* 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;
|
||||
|
||||
boot_lba = t->bootsrc[0]->sections[0].block;
|
||||
mbr_id = 0;
|
||||
head_count = t->partition_heads_per_cyl;
|
||||
sector_count = t->partition_secs_per_head;
|
||||
|
||||
@ -608,6 +607,8 @@ int make_isolinux_mbr(int32_t *img_blocks, Ecma119Image *t,
|
||||
gettimeofday(&tv, &tz);
|
||||
id = 0xffffffff & (tv.tv_sec ^ (tv.tv_usec * 2000));
|
||||
lsb_to_buf(&wpt, id, 32, 0);
|
||||
} else {
|
||||
wpt+= 4;
|
||||
}
|
||||
|
||||
/* write word 0 # Offset 444
|
||||
|
@ -540,13 +540,12 @@ int checksum_copy_old_nodes(Ecma119Image *target, IsoNode *node, int flag)
|
||||
if (value != NULL)
|
||||
free(value);
|
||||
|
||||
/* ts B30114 : It is unclear why these are removed here.
|
||||
At least with the opts->will_cancel runs,
|
||||
this is not appropriate.
|
||||
/* >>> ts B30114 : It is unclear why these are removed here.
|
||||
At least with the opts->will_cancel runs,
|
||||
this is not appropriate.
|
||||
*/
|
||||
iso_node_remove_xinfo(node, checksum_md5_xinfo_func);
|
||||
}
|
||||
iso_node_remove_xinfo(node, checksum_cx_xinfo_func);
|
||||
}
|
||||
} else if (node->type == LIBISO_DIR) {
|
||||
for (pos = ((IsoDir *) node)->children; pos != NULL; pos = pos->next) {
|
||||
|
@ -1048,6 +1048,7 @@ void iso_node_set_sort_weight(IsoNode *node, int w)
|
||||
}
|
||||
} else if (node->type == LIBISO_FILE) {
|
||||
((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.name = name;
|
||||
new->node.mode = S_IFREG;
|
||||
new->from_old_session = 0;
|
||||
new->explicit_weight = 0;
|
||||
new->sort_weight = 0;
|
||||
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);
|
||||
if (ret < 0 || ret == 1)
|
||||
return ret;
|
||||
/* ret == 0 means that the stream is not from loaded ISO image */
|
||||
|
||||
} else if (node->type == LIBISO_SYMLINK) {
|
||||
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 flag)
|
||||
{
|
||||
@ -2765,9 +2771,14 @@ int iso_file_set_isofscx(IsoFile *file, unsigned int checksum_index,
|
||||
char *valuept;
|
||||
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++)
|
||||
value[3 - i] = (checksum_index >> (8 * i)) & 0xff;
|
||||
valuept= (char *) value;
|
||||
ret = iso_node_set_attrs((IsoNode *) file, (size_t) 1,
|
||||
&names, value_lengths, &valuept, 2 | 8);
|
||||
return ret;
|
||||
|
@ -149,8 +149,15 @@ struct Iso_File
|
||||
{
|
||||
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;
|
||||
|
||||
/* 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.
|
||||
* Higher weighting files are written at the beginning of image
|
||||
|
117
libisofs/util.c
117
libisofs/util.c
@ -667,6 +667,123 @@ int str2ucs(const char *icharset, const char *input, uint16_t **output)
|
||||
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)
|
||||
{
|
||||
return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c == '_');
|
||||
|
@ -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);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
|
Reference in New Issue
Block a user