Compare commits

...

44 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
46e96ee616 Version leap to 1.3.2 2013-08-07 15:10:10 +02:00
7e60e60e62 Updated changelog 2013-08-07 10:56:23 +02:00
d55ed2d1ca New API calls iso_image_get_app_use() and iso_image_set_app_use() 2013-08-04 12:32:31 +02:00
77c8349c56 Bug fix: iso_finish() left an invalid global pointer, which a subsequent call of iso_init() would try to dereference. 2013-07-31 09:53:43 +02:00
b1c7ed6e29 Avoided a confusing error message from iso_image_update_sizes(),
prepared macro for non-confusing error message,
and introduced flag bit0 to iso_stream_get_input_stream()
2013-06-25 14:56:29 +02:00
e886722d65 The sort weight of data files loaded from ISO image is now 2 exp 28 to 1
rather than 2 exp 31 - 1 to - 2 exp 31
2013-05-24 12:35:43 +02:00
b80b339de3 Version leap to 1.3.1 2013-05-17 19:51:39 +02:00
efbd05203d Version leap to 1.3.0 2013-05-17 19:47:58 +02:00
6ca1d76d60 Updated change log 2013-05-17 09:52:40 +02:00
e1b54056e8 Added a new source of information about CHRP to boot_sectors.txt 2013-05-01 20:28:24 +02:00
d5cd610ac7 Bug fix: The protective MBR partition for GPT started at block 0 instead of 1 2013-04-17 20:54:02 +02:00
91f5ebb376 Bug fix: GPT header CRC was computed from all 512 bytes rather than from 92. 2013-04-17 16:45:51 +02:00
ff3b439bda Changed Libisofs_grub2_sparc_patch_lba_poS to Libisofs_grub2_sparc_patch_adr_poS 2013-04-14 08:15:29 +02:00
4672c79181 Changed Libisofs_grub2_sparc_patch_lba_poS to Libisofs_grub2_sparc_patch_adr_poS 2013-04-14 08:14:27 +02:00
83cb07b23c New API calls iso_image_set_sparc_core() and iso_image_get_sparc_core(). 2013-04-13 22:17:26 +02:00
439a14da1d Bug fix: Reserved and unused fields of APM entries were not zeroed. 2013-04-13 12:11:26 +02:00
d66eef42f6 Corrected Libisofs_grub2_mbr_patch_offsT from 3 to 4 2013-04-13 09:25:42 +02:00
337bade549 New option bits with el_torito_set_isolinux_options() and
iso_write_opts_set_system_area() to control GRUB2 patching of
boot image and MBR
2013-04-13 08:38:52 +02:00
eb6503a8ad * Bug fix: Unspecified Expiration Time and Effective Time of ISO volume was
represented by 0-bytes rather than ASCII '0' digits.
2013-04-10 13:55:20 +02:00
1a2e1c767e Now repeating Rock Ridge warnings at most once per loaded image. 2013-04-10 13:32:53 +02:00
858c5479c8 Changed some warning texts from "RR" to "Rock Ridge" 2013-04-10 13:32:09 +02:00
d36b3d04a8 Temporarily hosting a test bed for syslinux/core/fs/susp_rr.c in libisofs/fs_image.c 2013-03-31 13:37:39 +02:00
da41eb8c6e Version leap to 1.2.9 2013-03-18 21:54:59 +01:00
775b7a11b4 Version leap to 1.2.8 2013-03-18 21:47:22 +01:00
23679b86ff Updated changelog 2013-03-18 08:32:16 +01:00
a4f07eb3b3 New API call iso_image_get_pvd_times(). 2013-03-12 17:42:13 +01:00
6905ab3e56 Bug fix: Image size prediction altered the pointers to MD5 of data files
which stem from a previous session.
2013-01-14 18:13:49 +01:00
05e7f84966 Bug fix: Reading damaged Rock Ridge data could cause SIGSEGV by NULL. 2013-01-11 16:22:14 +01:00
6e5f840f11 Version leap to 1.2.7 2013-01-08 15:38:01 +01:00
30 changed files with 1103 additions and 267 deletions

View File

@ -1,3 +1,34 @@
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
call of iso_init() would try to dereference.
* The sort weight of data files loaded from ISO image is now 2 exp 28 to 1
rather than 2 exp 31 - 1 to - 2 exp 31
libisofs-1.3.0.tar.gz Fri May 17 2013
===============================================================================
* Bug fix: GPT header CRC was computed from all 512 bytes rather than from 92.
* Bug fix: Unspecified Expiration Time and Effective Time of ISO volume was
represented by 0-bytes rather than ASCII '0' digits.
* Bug fix: Reserved and unused fields of APM entries were not zeroed.
* Bug fix: The protective MBR partition for GPT started at block 0 instead of 1.
* New option bits with el_torito_set_isolinux_options() and
iso_write_opts_set_system_area() to control GRUB2 patching of
boot image and MBR.
* New API calls iso_image_set_sparc_core() and iso_image_get_sparc_core().
libisofs-1.2.8.tar.gz Mon Mar 18 2013
===============================================================================
* Bug fix: Image size prediction altered the pointers to MD5 of data files
which stem from a previous session.
* Bug fix: Reading damaged Rock Ridge data could cause SIGSEGV by NULL.
* New API call iso_image_get_pvd_times().
libisofs-1.2.6.tar.gz Tue Jan 08 2013
===============================================================================
* Bug fix: Appended partitions did not obey cylinder alignment

2
README
View File

@ -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

View File

@ -1,4 +1,4 @@
AC_INIT([libisofs], [1.2.6], [http://libburnia-project.org])
AC_INIT([libisofs], [1.3.4], [http://libburnia-project.org])
AC_PREREQ([2.50])
dnl AC_CONFIG_HEADER([config.h])
@ -40,8 +40,8 @@ dnl
dnl If LIBISOFS_*_VERSION changes, be sure to change AC_INIT above to match.
dnl
LIBISOFS_MAJOR_VERSION=1
LIBISOFS_MINOR_VERSION=2
LIBISOFS_MICRO_VERSION=6
LIBISOFS_MINOR_VERSION=3
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.01.08 development jump has not yet happened
# SONAME = 68 - 62 = 6 . Library name = libisofs.6.62.0
LT_CURRENT=68
LT_AGE=62
# 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`

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.
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.
---------- | ---------- | ----------------------------------------------------
------------------------------------------------------------------------------
@ -906,13 +931,18 @@ PReP boots via a MBR partition containing only raw ELF and having type 0x41.
Sources:
Mail conversations with Vladimir Serbinenko.
http://stuff.mit.edu/afs/sipb/contrib/doc/specs/protocol/chrp/chrp1_7a.pdf
CHRP is marked by an MBR partition entry of type 0x96 spanning the whole
ISO 9660 image.
The specs in chrp1_7a.pdf promise that CHRP also recognizes ISO 9660 file
systems on unpartitioned disks. (See 11.1.1. Media Layout Format)
Vladimir Serbinenko stated:
PReP boot may be preferable. At least it can co-exist with other partitions
in the ISO image.
in the ISO image [without causing overlapping between partitions].
------------------------------------------------------------------------------
@ -1321,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
| |

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
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.

View File

@ -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;

View File

@ -1,7 +1,7 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2007 Mario Danic
* Copyright (c) 2009 - 2012 Thomas Schmitt
* Copyright (c) 2009 - 2013 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
@ -501,13 +501,23 @@ void ecma119_set_voldescr_times(IsoImageWriter *writer,
else
iso_datetime_17(vol->vol_modification_time, t->now, t->always_gmt);
if (t->vol_expiration_time > 0)
if (t->vol_expiration_time > 0) {
iso_datetime_17(vol->vol_expiration_time, t->vol_expiration_time,
t->always_gmt);
} else {
for(i = 0; i < 16; i++)
vol->vol_expiration_time[i] = '0';
vol->vol_expiration_time[16] = 0;
}
if (t->vol_effective_time > 0)
if (t->vol_effective_time > 0) {
iso_datetime_17(vol->vol_effective_time, t->vol_effective_time,
t->always_gmt);
} else {
for(i = 0; i < 16; i++)
vol->vol_effective_time[i] = '0';
vol->vol_effective_time[16] = 0;
}
}
/**
@ -587,6 +597,8 @@ int ecma119_writer_write_vol_desc(IsoImageWriter *writer)
ecma119_set_voldescr_times(writer, &vol);
vol.file_structure_version[0] = 1;
memcpy(vol.app_use, image->application_use, 512);
free(vol_id);
free(volset_id);
free(pub_id);
@ -980,6 +992,14 @@ int ecma119_writer_create(Ecma119Image *target)
return ret;
}
if (target->image->sparc_core_node != NULL) {
/* Obtain a duplicate of the IsoFile's Ecma119Node->file */
ret = iso_file_src_create(target, target->image->sparc_core_node,
&target->sparc_core_src);
if (ret < 0)
return ret;
}
if(target->partition_offset > 0) {
/* Create second tree */
target->eff_partition_offset = target->partition_offset;
@ -1210,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)
{
@ -1220,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;
}
@ -1526,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;
@ -1542,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().
@ -1585,84 +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" */
iso_node_set_attrs(node, (size_t) 1,
&cx_names, cx_value_lengths, &cx_valuept, 4 | 8);
if (!target->will_cancel)
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 (!no_md5) {
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;
@ -1870,6 +1942,8 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
target->mipsel_p_vaddr = 0;
target->mipsel_p_filesz = 0;
target->sparc_core_src = NULL;
target->empty_file_block = 0;
target->tree_end_block = 0;
@ -1970,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;
@ -2002,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 */
@ -2343,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)
@ -2394,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;
@ -3263,7 +3327,7 @@ int iso_write_opts_set_system_area(IsoWriteOpts *opts, char data[32768],
memcpy(opts->system_area_data, data, 32768);
}
if (!(flag & 4))
opts->system_area_options = options & 0x3fff;
opts->system_area_options = options & 0x7fff;
return ISO_SUCCESS;
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2012 Thomas Schmitt
* Copyright (c) 2009 - 2013 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
@ -825,6 +825,11 @@ struct ecma119_image
uint32_t mipsel_p_vaddr;
uint32_t mipsel_p_filesz;
/* A data file of which the position and size shall be written after
a SUN Disk Label.
*/
IsoFileSrc *sparc_core_src;
char *appended_partitions[ISO_MAX_PARTITIONS];
uint8_t appended_part_types[ISO_MAX_PARTITIONS];
/* Counted in blocks of 2048 */

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2010 Thomas Schmitt
* Copyright (c) 2010 - 2013 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
@ -160,7 +160,13 @@ int el_torito_get_selection_crit(ElToritoBootImage *bootimg, uint8_t crit[20])
/* API */
int el_torito_seems_boot_info_table(ElToritoBootImage *bootimg, int flag)
{
return bootimg->seems_boot_info_table;
switch (flag & 15) {
case 0:
return bootimg->seems_boot_info_table;
case 1:
return bootimg->seems_grub2_boot_info;
}
return 0;
}
/**
@ -197,14 +203,14 @@ void el_torito_patch_isolinux_image(ElToritoBootImage *bootimg)
*/
int el_torito_set_isolinux_options(ElToritoBootImage *bootimg, int options, int flag)
{
bootimg->isolinux_options = (options & 0x01ff);
bootimg->isolinux_options = (options & 0x03ff);
return ISO_SUCCESS;
}
/* API */
int el_torito_get_isolinux_options(ElToritoBootImage *bootimg, int flag)
{
return bootimg->isolinux_options & 0x01ff;
return bootimg->isolinux_options & 0x03ff;
}
/* API */
@ -306,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;
@ -317,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;
@ -331,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;
@ -455,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;
@ -507,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;
}
@ -524,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;
@ -694,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)
@ -1096,7 +1111,7 @@ int make_boot_info_table(uint8_t *buf, uint32_t pvd_lba,
}
/**
* Patch an isolinux boot image.
* Patch an El Torito boot image by a boot info table.
*
* @return
* 1 on success, 0 error (but continue), < 0 error
@ -1117,6 +1132,27 @@ int patch_boot_info_table(uint8_t *buf, Ecma119Image *t,
return ret;
}
/**
* Patch a GRUB2 El Torito boot image.
*/
static
int patch_grub2_boot_image(uint8_t *buf, Ecma119Image *t,
size_t imgsize, int idx,
size_t pos, int offst)
{
uint64_t blk;
if (imgsize < pos + 8)
return iso_msg_submit(t->image->id, ISO_ISOLINUX_CANT_PATCH, 0,
"Isolinux image too small for GRUB2. Will not patch it.");
blk = ((uint64_t) t->bootsrc[idx]->sections[0].block) * 4 + offst;
iso_lsb((buf + pos), blk & 0xffffffff, 4);
iso_lsb((buf + pos + 4), blk >> 32, 4);
return ISO_SUCCESS;
}
/* Patch the boot images if indicated */
int iso_patch_eltoritos(Ecma119Image *t)
{
@ -1130,7 +1166,7 @@ int iso_patch_eltoritos(Ecma119Image *t)
return ISO_SUCCESS;
for (idx = 0; idx < t->catalog->num_bootimages; idx++) {
if (!(t->catalog->bootimages[idx]->isolinux_options & 0x01))
if (!(t->catalog->bootimages[idx]->isolinux_options & 0x201))
continue;
original = t->bootsrc[idx]->stream;
size = (size_t) iso_stream_get_size(original);
@ -1154,9 +1190,20 @@ int iso_patch_eltoritos(Ecma119Image *t)
}
/* ok, patch the read buffer */
ret = patch_boot_info_table(buf, t, size, idx);
if (ret < 0) {
return ret;
if (t->catalog->bootimages[idx]->isolinux_options & 0x200) {
/* GRUB2 boot provisions */
ret = patch_grub2_boot_image(buf, t, size, idx,
Libisofs_grub2_elto_patch_poS,
Libisofs_grub2_elto_patch_offsT);
if (ret < 0)
return ret;
}
/* Must be done as last patching */
if (t->catalog->bootimages[idx]->isolinux_options & 0x01) {
/* Boot Info Table */
ret = patch_boot_info_table(buf, t, size, idx);
if (ret < 0)
return ret;
}
/* replace the original stream with a memory stream that reads from

View File

@ -58,6 +58,7 @@ struct el_torito_boot_image {
* Whether the boot image seems to contain a boot_info_table
*/
unsigned int seems_boot_info_table:1;
unsigned int seems_grub2_boot_info:1;
/**
* isolinux options
* bit 0 -> whether to patch image
@ -155,4 +156,12 @@ int make_boot_info_table(uint8_t *buf, uint32_t pvd_lba,
*/
int iso_patch_eltoritos(Ecma119Image *t);
/* Parameters for patch_grub2_boot_image()
Might later become variables in struct el_torito_boot_image.
*/
#define Libisofs_grub2_elto_patch_poS (512 * 5 - 12)
#define Libisofs_grub2_elto_patch_offsT 5
#endif /* LIBISO_ELTORITO_H */

View File

@ -127,7 +127,7 @@ int iso_file_src_create(Ecma119Image *img, IsoFile *file, IsoFileSrc **src)
/* insert the filesrc in the tree */
ret = iso_rbtree_insert(img->files, fsrc, (void**)src);
if (ret <= 0) {
if (ret == 0 && (*src)->checksum_index > 0) {
if (ret == 0 && (*src)->checksum_index > 0 && !img->will_cancel) {
/* Duplicate file source was mapped to previously registered source
*/
cret = iso_file_set_isofscx(file, (*src)->checksum_index, 0);
@ -152,13 +152,13 @@ int iso_file_src_create(Ecma119Image *img, IsoFile *file, IsoFileSrc **src)
no_md5 = 1;
}
if ((img->md5_file_checksums & 1) && !no_md5) {
if ((img->md5_file_checksums & 1) && !(no_md5 || img->will_cancel)) {
img->checksum_idx_counter++;
if (img->checksum_idx_counter < 0x7fffffff) {
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)

View File

@ -35,6 +35,22 @@
#include <stdio.h>
/* Enable this and write the correct absolute path into the include statement
below in order to test the pending contribution to syslinux:
http://www.syslinux.org/archives/2013-March/019755.html
# def ine Libisofs_syslinux_tesT 1
*/
#ifdef Libisofs_syslinux_tesT
#define Isolinux_rockridge_in_libisofS 1
#include "/reiser/syslinux/core/fs/iso9660/susp_rr.c"
/*
# inc lude "/home/thomas/projekte/cdrskin_dir/libisoburn-develop/test/susp_rr.c"
*/
#endif /* Libisofs_syslinux_tesT */
/**
* Options for image reading.
* There are four kind of options:
@ -241,6 +257,10 @@ typedef struct
char *copyright_file_id;
char *abstract_file_id;
char *biblio_file_id;
char *creation_time;
char *modification_time;
char *expiration_time;
char *effective_time;
/* extension information */
@ -310,6 +330,30 @@ typedef struct
*/
int px_ino_status;
/* Which Rock Ridge error messages already have occured
bit0= Invalid PX entry
bit1= Invalid TF entry
bit2= New NM entry found without previous CONTINUE flag
bit3= Invalid NM entry
bit4= New SL entry found without previous CONTINUE flag
bit5= Invalid SL entry
bit6= Invalid SL entry, no child location
bit7= Invalid PN entry
bit8= Sparse files not supported
bit9= SP entry found in a directory entry other than '.' entry of root
bit10= ER entry found in a directory entry other than '.' entry of root
bit11= Invalid AA entry
bit12= Invalid AL entry
bit13= Invalid ZF entry
bit14= Rock Ridge PX entry is not present or invalid
bit15= Incomplete NM
bit16= Incomplete SL
bit17= Charset conversion error
bit18= Link without destination
*/
int rr_err_reported;
int rr_err_repeated;
} _ImageFsData;
typedef struct image_fs_data ImageFileSourceData;
@ -1229,6 +1273,30 @@ char *get_name(_ImageFsData *fsdata, const char *str, size_t len)
}
static
int iso_rr_msg_submit(_ImageFsData *fsdata, int rr_err_bit,
int errcode, int causedby, const char *msg)
{
int ret;
if ((fsdata->rr_err_reported & (1 << rr_err_bit)) &&
(fsdata->rr_err_repeated & (1 << rr_err_bit))) {
if (iso_msg_is_abort(errcode))
return ISO_CANCELED;
return 0;
}
if (fsdata->rr_err_reported & (1 << rr_err_bit)) {
ret = iso_msg_submit(fsdata->msgid, errcode, causedby,
"MORE THAN ONCE : %s", msg);
fsdata->rr_err_repeated |= (1 << rr_err_bit);
} else {
ret = iso_msg_submit(fsdata->msgid, errcode, causedby, "%s", msg);
fsdata->rr_err_reported |= (1 << rr_err_bit);
}
return ret;
}
/**
*
* @param src
@ -1419,8 +1487,8 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
ret = read_rr_PX(sue, &atts);
if (ret < 0) {
/* notify and continue */
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR_WARN, ret,
"Invalid PX entry");
ret = iso_rr_msg_submit(fsdata, 0, ISO_WRONG_RR_WARN, ret,
"Invalid PX entry");
fsdata->px_ino_status |= 8;
} if (ret == 2) {
if (fsdata->inode_counter < atts.st_ino)
@ -1435,13 +1503,13 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
ret = read_rr_TF(sue, &atts);
if (ret < 0) {
/* notify and continue */
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR_WARN, ret,
"Invalid TF entry");
ret = iso_rr_msg_submit(fsdata, 1, ISO_WRONG_RR_WARN, ret,
"Invalid TF entry");
}
} else if (SUSP_SIG(sue, 'N', 'M')) {
if (name != NULL && namecont == 0) {
/* ups, RR standard violation */
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR_WARN, 0,
ret = iso_rr_msg_submit(fsdata, 2, ISO_WRONG_RR_WARN, 0,
"New NM entry found without previous"
"CONTINUE flag. Ignored");
continue;
@ -1449,13 +1517,52 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
ret = read_rr_NM(sue, &name, &namecont);
if (ret < 0) {
/* notify and continue */
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR_WARN, ret,
"Invalid NM entry");
ret = iso_rr_msg_submit(fsdata, 3, ISO_WRONG_RR_WARN, ret,
"Invalid NM entry");
}
#ifdef Libisofs_syslinux_tesT
if (name != NULL && !namecont) {
struct device syslinux_dev;
struct iso_sb_info syslinux_sbi;
struct fs_info syslinux_fsi;
char *syslinux_name = NULL;
int syslinux_name_len;
syslinux_dev.src = fsdata->src;
memset(&(syslinux_sbi.root), 0, 256);
syslinux_sbi.do_rr = 1;
syslinux_sbi.susp_skip = 0;
syslinux_fsi.fs_dev = &syslinux_dev;
syslinux_fsi.fs_info = &syslinux_sbi;
ret = susp_rr_get_nm(&syslinux_fsi, (char *) record,
&syslinux_name, &syslinux_name_len);
if (ret == 1) {
if (name == NULL || syslinux_name == NULL)
fprintf(stderr, "################ Hoppla. NULL\n");
else if(strcmp(syslinux_name, name) != 0)
fprintf(stderr,
"################ libisofs '%s' != '%s' susp_rr_get_nm()\n",
name, syslinux_name);
} else if (ret == 0) {
fprintf(stderr,
"################ '%s' not found by susp_rr_get_nm()\n", name);
} else {
fprintf(stderr, "################ 'susp_rr_get_nm() returned error\n");
}
if (syslinux_name != NULL)
free(syslinux_name);
}
#endif /* Libisofs_syslinux_tesT */
} else if (SUSP_SIG(sue, 'S', 'L')) {
if (linkdest != NULL && linkdestcont == 0) {
/* ups, RR standard violation */
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR_WARN, 0,
ret = iso_rr_msg_submit(fsdata, 4, ISO_WRONG_RR_WARN, 0,
"New SL entry found without previous"
"CONTINUE flag. Ignored");
continue;
@ -1463,8 +1570,8 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
ret = read_rr_SL(sue, &linkdest, &linkdestcont);
if (ret < 0) {
/* notify and continue */
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR_WARN, ret,
"Invalid SL entry");
ret = iso_rr_msg_submit(fsdata, 5, ISO_WRONG_RR_WARN, ret,
"Invalid SL entry");
}
} else if (SUSP_SIG(sue, 'R', 'E')) {
/*
@ -1484,7 +1591,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
*/
relocated_dir = iso_read_bb(sue->data.CL.child_loc, 4, NULL);
if (relocated_dir == 0) {
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR, 0,
ret = iso_rr_msg_submit(fsdata, 6, ISO_WRONG_RR, 0,
"Invalid SL entry, no child location");
break;
}
@ -1492,12 +1599,12 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
ret = read_rr_PN(sue, &atts);
if (ret < 0) {
/* notify and continue */
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR_WARN, ret,
"Invalid PN entry");
ret = iso_rr_msg_submit(fsdata, 7, ISO_WRONG_RR_WARN, ret,
"Invalid PN entry");
}
} else if (SUSP_SIG(sue, 'S', 'F')) {
ret = iso_msg_submit(fsdata->msgid, ISO_UNSUPPORTED_RR, 0,
"Sparse files not supported.");
ret = iso_rr_msg_submit(fsdata, 8, ISO_UNSUPPORTED_RR, 0,
"Sparse files not supported.");
break;
} else if (SUSP_SIG(sue, 'R', 'R')) {
/* This was an optional flag byte in RRIP 1.09 which told the
@ -1512,7 +1619,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
*/
if (!(flag & 1)) {
/* notify and continue */
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR, 0,
ret = iso_rr_msg_submit(fsdata, 9, ISO_WRONG_RR, 0,
"SP entry found in a directory entry other "
"than '.' entry of root node");
}
@ -1524,7 +1631,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
*/
if (!(flag & 1)) {
/* notify and continue */
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR, 0,
ret = iso_rr_msg_submit(fsdata, 10, ISO_WRONG_RR, 0,
"ER entry found in a directory entry other "
"than '.' entry of root node");
}
@ -1539,8 +1646,8 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
&prev_field, &aa_done, 0);
if (ret < 0) {
/* notify and continue */
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR_WARN, ret,
"Invalid AA entry");
ret = iso_rr_msg_submit(fsdata, 11, ISO_WRONG_RR_WARN, ret,
"Invalid AA entry");
continue;
}
@ -1550,8 +1657,8 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
&prev_field, &aa_done, 0);
if (ret < 0) {
/* notify and continue */
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR_WARN, ret,
"Invalid AL entry");
ret = iso_rr_msg_submit(fsdata, 12, ISO_WRONG_RR_WARN, ret,
"Invalid AL entry");
continue;
}
@ -1563,7 +1670,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
&zisofs_bsl2, &zisofs_usize, 0);
if (ret < 0 || zisofs_alg[0] != 'p' || zisofs_alg[1] != 'z') {
/* notify and continue */
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR_WARN, ret,
ret = iso_rr_msg_submit(fsdata, 13, ISO_WRONG_RR_WARN, ret,
"Invalid ZF entry");
zisofs_hs4 = 0;
continue;
@ -1589,17 +1696,17 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
/* error was already submitted above */
iso_msg_debug(fsdata->msgid, "Error parsing RR entries");
} else if (!relocated_dir && atts.st_mode == (mode_t) 0 ) {
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR, 0, "Mandatory "
ret = iso_rr_msg_submit(fsdata, 14, ISO_WRONG_RR, 0, "Mandatory "
"Rock Ridge PX entry is not present or it "
"contains invalid values.");
} else {
/* ensure both name and link dest are finished */
if (namecont != 0) {
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR, 0,
"Incomplete RR name, last NM entry continues");
ret = iso_rr_msg_submit(fsdata, 15, ISO_WRONG_RR, 0,
"Incomplete Rock Ridge name, last NM entry continues");
}
if (linkdestcont != 0) {
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR, 0,
ret = iso_rr_msg_submit(fsdata, 16, ISO_WRONG_RR, 0,
"Incomplete link destination, last SL entry continues");
}
}
@ -1613,6 +1720,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
ret = iso_aa_lookup_attr(aa_string, "isofs.cs",
&cs_value_length, &cs_value, 0);
if (ret == 1) {
LIBISO_FREE_MEM(msg);
LIBISO_ALLOC_MEM(msg, char, 160);
if (fsdata->auto_input_charset & 1) {
if (fsdata->input_charset != NULL)
@ -1640,10 +1748,13 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
&newname);
if (ret < 0) {
/* its just a hint message */
ret = iso_msg_submit(fsdata->msgid, ISO_FILENAME_WRONG_CHARSET,
ret, "Charset conversion error. Cannot "
"convert from %s to %s",
LIBISO_FREE_MEM(msg);
LIBISO_ALLOC_MEM(msg, char, 160);
sprintf(msg,
"Charset conversion error. Cannot convert from %.40s to %.40s",
fsdata->input_charset, fsdata->local_charset);
ret = iso_rr_msg_submit(fsdata, 17, ISO_FILENAME_WRONG_CHARSET,
ret, msg);
free(newname);
if (ret < 0) {
free(name);
@ -1662,10 +1773,13 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
ret = strconv(linkdest, fsdata->input_charset,
fsdata->local_charset, &newlinkdest);
if (ret < 0) {
ret = iso_msg_submit(fsdata->msgid, ISO_FILENAME_WRONG_CHARSET,
ret, "Charset conversion error. Cannot "
"convert from %s to %s",
LIBISO_FREE_MEM(msg);
LIBISO_ALLOC_MEM(msg, char, 160);
sprintf(msg,
"Charset conversion error. Cannot convert from %.40s to %.40s",
fsdata->input_charset, fsdata->local_charset);
ret = iso_rr_msg_submit(fsdata, 17, ISO_FILENAME_WRONG_CHARSET,
ret, msg);
free(newlinkdest);
if (ret < 0) {
free(name);
@ -1788,8 +1902,8 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
/* TODO #00014 : more sanity checks to ensure dir record info is valid */
if (S_ISLNK(atts.st_mode) && (linkdest == NULL)) {
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR, 0,
"Link without destination.");
ret = iso_rr_msg_submit(fsdata, 18, ISO_WRONG_RR, 0,
"Link without destination.");
free(name);
goto ex;
}
@ -2089,6 +2203,10 @@ void ifs_fs_free(IsoFilesystem *fs)
free(data->copyright_file_id);
free(data->abstract_file_id);
free(data->biblio_file_id);
free(data->creation_time);
free(data->modification_time);
free(data->expiration_time);
free(data->effective_time);
free(data->input_charset);
free(data->local_charset);
@ -2123,6 +2241,27 @@ int read_root_susp_entries(_ImageFsData *data, uint32_t block)
/* record will be the "." directory entry for the root record */
record = (struct ecma119_dir_record *)buffer;
#ifdef Libisofs_syslinux_tesT
{
struct device syslinux_dev;
struct iso_sb_info syslinux_sbi;
struct fs_info syslinux_fsi;
syslinux_dev.src = data->src;
memcpy(&(syslinux_sbi.root), (char *) record, 256);
syslinux_sbi.do_rr = 1;
syslinux_sbi.susp_skip = 0;
syslinux_fsi.fs_dev = &syslinux_dev;
syslinux_fsi.fs_info = &syslinux_sbi;
ret = susp_rr_check_signatures(&syslinux_fsi, 1);
fprintf(stderr, "--------- susp_rr_check_signatures == %d , syslinux_sbi.do_rr == %d\n", ret, syslinux_sbi.do_rr);
}
#endif /* Libisofs_syslinux_tesT */
/*
* TODO #00015 : take care of CD-ROM XA discs when reading SP entry
* SUSP specification claims that for CD-ROM XA the SP entry
@ -2317,7 +2456,15 @@ int read_pvm(_ImageFsData *data, uint32_t block)
data->copyright_file_id[0] = 0;
data->abstract_file_id[0] = 0;
data->biblio_file_id[0] = 0;
}
}
data->creation_time =
iso_util_strcopy_untail((char*) pvm->vol_creation_time, 17);
data->modification_time =
iso_util_strcopy_untail((char*) pvm->vol_modification_time, 17);
data->expiration_time =
iso_util_strcopy_untail((char*) pvm->vol_expiration_time, 17);
data->effective_time =
iso_util_strcopy_untail((char*) pvm->vol_effective_time, 17);
data->nblocks = iso_read_bb(pvm->vol_space_size, 4, NULL);
@ -2607,6 +2754,8 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
data->bootblocks[i] = 0;
data->inode_counter = 0;
data->px_ino_status = 0;
data->rr_err_reported = 0;
data->rr_err_repeated = 0;
data->local_charset = strdup(iso_get_local_charset(0));
@ -2857,9 +3006,9 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
{
int ret, idx, to_copy;
struct stat info;
IsoNode *new;
IsoNode *new = NULL;
IsoBoot *bootcat;
char *name;
char *name = NULL;
char *dest = NULL;
ImageFileSourceData *data;
_ImageFsData *fsdata;
@ -2887,7 +3036,6 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
goto ex;
}
new = NULL;
switch (info.st_mode & S_IFMT) {
case S_IFREG:
{
@ -2901,9 +3049,8 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
"More than one catalog node has been found. "
"We can continue, but that could lead to "
"problems");
if (ret < 0) {
if (ret < 0)
goto ex;
}
iso_node_unref((IsoNode*)image->bootcat->node);
}
@ -2911,9 +3058,7 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
* a regular file */
new = calloc(1, sizeof(IsoBoot));
if (new == NULL) {
ret = ISO_OUT_OF_MEM;
free(name);
goto ex;
ret = ISO_OUT_OF_MEM; goto ex;
}
bootcat = (IsoBoot *) new;
bootcat->lba = data->sections[0].block;
@ -2924,10 +3069,7 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
if (bootcat->size > 0) {
bootcat->content = calloc(1, bootcat->size);
if (bootcat->content == NULL) {
ret = ISO_OUT_OF_MEM;
free(name);
free(new);
goto ex;
ret = ISO_OUT_OF_MEM; goto ex;
}
to_copy = bootcat->size;
if (bootcat->size > fsdata->catsize)
@ -2944,16 +3086,14 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
IsoFile *file;
ret = iso_file_source_stream_new(src, &stream);
if (ret < 0) {
free(name);
if (ret < 0)
goto ex;
}
/* take a ref to the src, as stream has taken our ref */
iso_file_source_ref(src);
file = calloc(1, sizeof(IsoFile));
if (file == NULL) {
free(name);
iso_stream_unref(stream);
{ret = ISO_OUT_OF_MEM; goto ex;}
}
@ -2964,8 +3104,19 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
/*
* and we set the sort weight based on the block on image, to
* improve performance on image modifying.
*
* This was too obtrusive because it occupied the highest
* possible weight ranks:
* file->sort_weight = INT_MAX - data->sections[0].block;
*
* So a try to be more nice and rely on caching with tiles
* of at least 16 blocks. This occupies a range within
* the interval of 1 to 2 exp 28 = 268,435,456.
* (Dividing each number separately saves from integer
* rollover problems.)
*/
file->sort_weight = INT_MAX - data->sections[0].block;
file->sort_weight =
fsdata->nblocks / 16 - data->sections[0].block / 16 + 1;
file->stream = stream;
file->node.type = LIBISO_FILE;
@ -2977,7 +3128,6 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
data->block_size_log2,
data->uncompressed_size, 0);
if (ret < 0) {
free(name);
iso_stream_unref(stream);
goto ex;
}
@ -3008,7 +3158,6 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
ret = iso_msg_submit(image->id, ISO_EL_TORITO_WARN, 0,
"More than one ISO node has been found for the same boot image.");
if (ret < 0) {
free(name);
iso_stream_unref(stream);
goto ex;
}
@ -3026,7 +3175,6 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
/* source is a directory */
new = calloc(1, sizeof(IsoDir));
if (new == NULL) {
free(name);
{ret = ISO_OUT_OF_MEM; goto ex;}
}
new->type = LIBISO_DIR;
@ -3042,12 +3190,10 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
ret = iso_file_source_readlink(src, dest, LIBISOFS_NODE_PATH_MAX);
if (ret < 0) {
free(name);
goto ex;
}
link = calloc(1, sizeof(IsoSymlink));
if (link == NULL) {
free(name);
{ret = ISO_OUT_OF_MEM; goto ex;}
}
link->dest = strdup(dest);
@ -3068,8 +3214,7 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
IsoSpecial *special;
special = calloc(1, sizeof(IsoSpecial));
if (special == NULL) {
free(name);
{ret = ISO_OUT_OF_MEM; goto ex;}
ret = ISO_OUT_OF_MEM; goto ex;
}
special->dev = info.st_rdev;
special->node.type = LIBISO_SPECIAL;
@ -3080,11 +3225,12 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
new->refcount = 0;
}
break;
default:
ret = ISO_BAD_ISO_FILETYPE; goto ex;
}
/* fill fields */
new->refcount++;
new->name = name;
new->name = name; name = NULL;
new->mode = info.st_mode;
new->uid = info.st_uid;
new->gid = info.st_gid;
@ -3099,7 +3245,7 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
ret = src_aa_to_node(src, new, 0);
if (ret < 0) {
goto failure;
goto ex;
}
/* Attach ino as xinfo if valid and no IsoStream is involved */
@ -3107,18 +3253,17 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
!fsdata->make_new_ino) {
ret = iso_node_set_ino(new, info.st_ino, 0);
if (ret < 0)
goto failure;
goto ex;
}
*node = new;
*node = new; new = NULL;
{ret = ISO_SUCCESS; goto ex;}
failure:;
/* todo: stuff any possible memory leak here */
ex:;
if (name != NULL)
free(name);
free(new);
ex:;
if (new != NULL)
iso_node_unref(new);
LIBISO_FREE_MEM(dest);
return ret;
}
@ -3241,13 +3386,14 @@ static
int iso_image_eval_boot_info_table(IsoImage *image, struct iso_read_opts *opts,
IsoDataSource *src, uint32_t iso_image_size, int flag)
{
int i, ret, section_count, todo, chunk;
int i, j, ret, section_count, todo, chunk;
uint32_t img_lba, img_size, boot_pvd_found, image_pvd, alleged_size;
struct iso_file_section *sections = NULL;
struct el_torito_boot_image *boot;
uint8_t *boot_image_buf = NULL, boot_info_found[16], *buf = NULL;
IsoStream *stream = NULL;
IsoFile *boot_file;
uint64_t blk;
if (image->bootcat == NULL)
{ret = ISO_SUCCESS; goto ex;}
@ -3256,6 +3402,7 @@ int iso_image_eval_boot_info_table(IsoImage *image, struct iso_read_opts *opts,
boot = image->bootcat->bootimages[i];
boot_file = boot->image;
boot->seems_boot_info_table = 0;
boot->seems_grub2_boot_info = 0;
img_size = iso_file_get_size(boot_file);
if (img_size > Libisofs_boot_image_max_sizE || img_size < 64)
continue;
@ -3321,6 +3468,16 @@ int iso_image_eval_boot_info_table(IsoImage *image, struct iso_read_opts *opts,
goto ex;
if (memcmp(boot_image_buf + 8, boot_info_found, 16) == 0)
boot->seems_boot_info_table = 1;
if (img_size >= Libisofs_grub2_elto_patch_poS + 8) {
blk = 0;
for (j = Libisofs_grub2_elto_patch_poS + 7;
j >= Libisofs_grub2_elto_patch_poS; j--)
blk = (blk << 8) | boot_image_buf[j];
if (blk == img_lba * 4 + Libisofs_grub2_elto_patch_offsT)
boot->seems_grub2_boot_info = 1;
}
free(boot_image_buf);
boot_image_buf = NULL;
}
@ -3526,7 +3683,7 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
/* warn about hidden images */
iso_msg_submit(image->id, ISO_EL_TORITO_HIDDEN, 0,
"Found hidden El-Torito image. Its size could not "
"be figure out, so image modify or boot image "
"be figured out, so image modify or boot image "
"patching may lead to bad results.");
}
if (image->bootcat->node == NULL) {
@ -3568,6 +3725,8 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
iso_image_set_copyright_file_id(image, data->copyright_file_id);
iso_image_set_abstract_file_id(image, data->abstract_file_id);
iso_image_set_biblio_file_id(image, data->biblio_file_id);
iso_image_set_pvd_times(image, data->creation_time,
data->modification_time, data->expiration_time, data->effective_time);
if (features != NULL) {
*features = malloc(sizeof(IsoReadImageFeatures));

View File

@ -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;

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2012 Thomas Schmitt
* Copyright (c) 2009 - 2013 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
@ -78,11 +78,13 @@ int iso_image_new(const char *name, IsoImage **image)
img->volset_id = strdup(name);
img->volume_id = strdup(name);
}
memset(img->application_use, 0, 512);
img->system_area_data = NULL;
img->system_area_options = 0;
img->num_mips_boot_files = 0;
for (i = 0; i < 15; i++)
img->mips_boot_file_paths[i] = NULL;
img->sparc_core_node = NULL;
img->builder_ignore_acl = 1;
img->builder_ignore_ea = 1;
img->inode_counter = 0;
@ -136,6 +138,8 @@ void iso_image_unref(IsoImage *image)
iso_filesystem_unref(image->fs);
el_torito_boot_catalog_free(image->bootcat);
iso_image_give_up_mips_boot(image, 0);
if (image->sparc_core_node != NULL)
iso_node_unref((IsoNode *) image->sparc_core_node);
free(image->volset_id);
free(image->volume_id);
free(image->publisher_id);
@ -145,6 +149,10 @@ void iso_image_unref(IsoImage *image)
free(image->copyright_file_id);
free(image->abstract_file_id);
free(image->biblio_file_id);
free(image->creation_time);
free(image->modification_time);
free(image->expiration_time);
free(image->effective_time);
if (image->used_inodes != NULL)
free(image->used_inodes);
if (image->system_area_data != NULL)
@ -335,6 +343,50 @@ const char *iso_image_get_biblio_file_id(const IsoImage *image)
return image->biblio_file_id;
}
int iso_image_set_pvd_times(IsoImage *image,
char *creation_time, char *modification_time,
char *expiration_time, char *effective_time)
{
if (creation_time == NULL || modification_time == NULL ||
expiration_time == NULL || effective_time == NULL)
return ISO_NULL_POINTER;
image->creation_time = strdup(creation_time);
image->modification_time = strdup(modification_time);
image->expiration_time = strdup(expiration_time);
image->effective_time = strdup(effective_time);
if (image->creation_time == NULL || image->modification_time == NULL ||
image->expiration_time == NULL || image->effective_time == NULL)
return ISO_OUT_OF_MEM;
return ISO_SUCCESS;
}
int iso_image_get_pvd_times(IsoImage *image,
char **creation_time, char **modification_time,
char **expiration_time, char **effective_time)
{
if (image->creation_time == NULL || image->modification_time == NULL ||
image->expiration_time == NULL || image->effective_time == NULL)
return ISO_NULL_POINTER;
*creation_time = image->creation_time;
*modification_time = image->modification_time;
*expiration_time = image->expiration_time;
*effective_time = image->effective_time;
return ISO_SUCCESS;
}
void iso_image_set_app_use(IsoImage *image, const char *app_use_data,
int count)
{
if (count < 0)
count= 0;
else if(count > 512)
count= 512;
if (count > 0)
memcpy(image->application_use, app_use_data, count);
if (count < 512)
memset(image->application_use + count, 0, 512 - count);
}
int iso_image_get_msg_id(IsoImage *image)
{
return image->id;
@ -354,21 +406,74 @@ static
int dir_update_size(IsoImage *image, IsoDir *dir)
{
IsoNode *pos;
int ret;
#ifdef Libisofs_update_sizes_abortablE
char *path= NULL;
IsoStream *base_stream;
int cancel_ret, ret;
uint32_t lba;
#endif
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) {
/* recurse */
ret = dir_update_size(image, ISO_DIR(pos));
#ifdef Libisofs_update_sizes_abortablE
if (ret == ISO_CANCELED)
return ret; /* Message already issued by dir_update_size */
#endif
} else {
ret = 1;
}
#ifdef Libisofs_update_sizes_abortablE
/* This would report error and abort according to severity threshold.
But it is desirable to let the update_size crawler continue
its work after e.g. a file has vanished from hard disk.
So normally this macro case should be disabled.
*/
if (ret < 0) {
ret = iso_msg_submit(image->id, ret, 0, NULL);
if (ret < 0) {
return ret; /* cancel due error threshold */
cancel_ret = iso_msg_submit(image->id, ret, 0, NULL);
path = iso_tree_get_node_path(pos);
if (path != NULL) {
iso_msg_submit(image->id, ret, 0,
"ISO path : %s", path);
free(path);
}
/* Report source path with streams which do not come from
the loaded ISO filesystem */
if (pos->type == LIBISO_FILE &&
iso_node_get_old_image_lba(pos, &lba, 0) == 0) {
base_stream = iso_stream_get_input_stream(
ISO_FILE(pos)->stream, 1);
if (base_stream == NULL)
base_stream = ISO_FILE(pos)->stream;
path = iso_stream_get_source_path(base_stream, 0);
if (path != NULL) {
iso_msg_submit(image->id, ret, 0,
"Local path: %s", path);
free(path);
}
}
if (cancel_ret < 0)
return cancel_ret; /* cancel due error threshold */
}
#else
if (ret < 0)
ret = 1; /* ignore error */
#endif /* ! Libisofs_update_sizes_abortablE */
pos = pos->next;
}
return ISO_SUCCESS;
@ -732,3 +837,24 @@ int iso_image_hfsplus_get_blessed(IsoImage *img, IsoNode ***blessed_nodes,
return 1;
}
/* API */
int iso_image_set_sparc_core(IsoImage *img, IsoFile *sparc_core, int flag)
{
if (img->sparc_core_node != NULL)
iso_node_unref((IsoNode *) img->sparc_core_node);
img->sparc_core_node = sparc_core;
if (sparc_core != NULL)
iso_node_ref((IsoNode *) sparc_core);
return 1;
}
/* API */
int iso_image_get_sparc_core(IsoImage *img, IsoFile **sparc_core, int flag)
{
*sparc_core = img->sparc_core_node;
return 1;
}

View File

@ -49,6 +49,11 @@ struct Iso_Image
char *copyright_file_id;
char *abstract_file_id;
char *biblio_file_id;
char *creation_time;
char *modification_time;
char *expiration_time;
char *effective_time;
char application_use[512];
/* el-torito boot catalog */
struct el_torito_boot_catalog *bootcat;
@ -65,6 +70,10 @@ struct Iso_Image
int num_mips_boot_files;
char *mips_boot_file_paths[15]; /* ISO 9660 Rock Ridge Paths */
/* A data file of which the position and size shall be written after
a SUN Disk Label.
*/
IsoFile *sparc_core_node;
/* image identifier, for message origin identifier */
int id;
@ -234,4 +243,8 @@ int iso_image_set_checksums(IsoImage *image, char *checksum_array,
uint32_t idx_count, int flag);
int iso_image_set_pvd_times(IsoImage *image,
char *creation_time, char *modification_time,
char *expiration_time, char *effective_time);
#endif /*LIBISO_IMAGE_H_*/

View File

@ -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;

View File

@ -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;

View File

@ -83,8 +83,8 @@
* @since 0.6.2
*/
#define iso_lib_header_version_major 1
#define iso_lib_header_version_minor 2
#define iso_lib_header_version_micro 6
#define iso_lib_header_version_minor 3
#define iso_lib_header_version_micro 4
/**
* Get version of the libisofs library at runtime.
@ -2156,23 +2156,25 @@ int iso_write_opts_set_fifo_size(IsoWriteOpts *opts, size_t fifo_size);
* bit2-7= System area type
* 0= with bit0 or bit1: MBR
* else: unspecified type which will be used unaltered.
* @since 0.6.38
* 1= MIPS Big Endian Volume Header
* @since 0.6.38
* Submit up to 15 MIPS Big Endian boot files by
* iso_image_add_mips_boot_file().
* This will overwrite the first 512 bytes of the submitted
* data.
* 2= DEC Boot Block for MIPS Little Endian
* @since 0.6.38
* The first boot file submitted by
* iso_image_add_mips_boot_file() will be activated.
* This will overwrite the first 512 bytes of the submitted
* data.
* @since 0.6.40
* 3= SUN Disk Label for SUN SPARC
* @since 0.6.40
* Submit up to 7 SPARC boot images by
* iso_write_opts_set_partition_img() for partition numbers 2
* to 8.
* This will overwrite the first 512 bytes of the submitted
* data.
* bit8-9= Only with System area type 0 = MBR
* @since 1.0.4
* Cylinder alignment mode eventually pads the image to make it
@ -2191,6 +2193,13 @@ int iso_write_opts_set_fifo_size(IsoWriteOpts *opts, size_t fifo_size);
* 1 = CHRP: A single MBR partition of type 0x96 covers the
* ISO image. Not compatible with any other feature
* which needs to have own MBR partition entries.
* bit14= Only with System area type 0 = MBR
* GRUB2 boot provisions:
* @since 1.3.0
* Patch system area at byte 92 to 99 with 512-block address + 1
* of the first boot image file. Little-endian 8-byte.
* Should be combined with options bit0.
* Will not be in effect if options bit1 is set.
* @param flag
* bit0 = invalidate any attached system area data. Same as data == NULL
* (This re-activates eventually loaded image System Area data.
@ -2886,7 +2895,7 @@ void iso_image_set_volset_id(IsoImage *image, const char *volset_id);
/**
* Get the volset identifier.
* The returned string is owned by the image and should not be freed nor
* The returned string is owned by the image and must not be freed nor
* changed.
*
* @since 0.6.2
@ -2902,7 +2911,7 @@ void iso_image_set_volume_id(IsoImage *image, const char *volume_id);
/**
* Get the volume identifier.
* The returned string is owned by the image and should not be freed nor
* The returned string is owned by the image and must not be freed nor
* changed.
*
* @since 0.6.2
@ -2918,7 +2927,7 @@ void iso_image_set_publisher_id(IsoImage *image, const char *publisher_id);
/**
* Get the publisher of a image.
* The returned string is owned by the image and should not be freed nor
* The returned string is owned by the image and must not be freed nor
* changed.
*
* @since 0.6.2
@ -2935,7 +2944,7 @@ void iso_image_set_data_preparer_id(IsoImage *image,
/**
* Get the data preparer of a image.
* The returned string is owned by the image and should not be freed nor
* The returned string is owned by the image and must not be freed nor
* changed.
*
* @since 0.6.2
@ -2951,7 +2960,7 @@ void iso_image_set_system_id(IsoImage *image, const char *system_id);
/**
* Get the system id of a image.
* The returned string is owned by the image and should not be freed nor
* The returned string is owned by the image and must not be freed nor
* changed.
*
* @since 0.6.2
@ -2967,7 +2976,7 @@ void iso_image_set_application_id(IsoImage *image, const char *application_id);
/**
* Get the application id of a image.
* The returned string is owned by the image and should not be freed nor
* The returned string is owned by the image and must not be freed nor
* changed.
*
* @since 0.6.2
@ -2985,7 +2994,7 @@ void iso_image_set_copyright_file_id(IsoImage *image,
/**
* Get the copyright information of a image.
* The returned string is owned by the image and should not be freed nor
* The returned string is owned by the image and must not be freed nor
* changed.
*
* @since 0.6.2
@ -3003,7 +3012,7 @@ void iso_image_set_abstract_file_id(IsoImage *image,
/**
* Get the abstract information of a image.
* The returned string is owned by the image and should not be freed nor
* The returned string is owned by the image and must not be freed nor
* changed.
*
* @since 0.6.2
@ -3020,13 +3029,72 @@ void iso_image_set_biblio_file_id(IsoImage *image, const char *biblio_file_id);
/**
* Get the biblio information of a image.
* The returned string is owned by the image and should not be freed nor
* changed.
* The returned string is owned by the image and must not be freed or changed.
*
* @since 0.6.2
*/
const char *iso_image_get_biblio_file_id(const IsoImage *image);
/**
* Fill Application Use field of the Primary Volume Descriptor.
* ECMA-119 8.4.32 Application Use (BP 884 to 1395)
* "This field shall be reserved for application use. Its content
* is not specified by this Standard."
*
* @param image
* The image to manipulate.
* @param app_use_data
* Up to 512 bytes of data.
* @param count
* The number of bytes in app_use_data. If the number is smaller than 512,
* then the remaining bytes will be set to 0.
* @since 1.3.2
*/
void iso_image_set_app_use(IsoImage *image, const char *app_use_data,
int count);
/**
* Get the current setting for the Application Use field of the Primary Volume
* Descriptor.
* The returned char array of 512 bytes is owned by the image and must not
* be freed or changed.
*
* @param image
* The image to inquire
* @since 1.3.2
*/
const char *iso_image_get_app_use(IsoImage *image);
/**
* Get the four timestamps from the Primary Volume Descriptor of the imported
* ISO image. The timestamps are strings which are either empty or consist
* of 17 digits of the form YYYYMMDDhhmmsscc.
* None of the returned string pointers shall be used for altering or freeing
* data. They are just for reading.
*
* @param image
* The image to be inquired.
* @param vol_creation_time
* Returns a pointer to the Volume Creation time:
* When "the information in the volume was created."
* @param vol_modification_time
* Returns a pointer to Volume Modification time:
* When "the information in the volume was last modified."
* @param vol_expiration_time
* Returns a pointer to Volume Expiration time:
* When "the information in the volume may be regarded as obsolete."
* @param vol_effective_time
* Returns a pointer to Volume Expiration time:
* When "the information in the volume may be used."
* @return
* ISO_SUCCESS or error
*
* @since 1.2.8
*/
int iso_image_get_pvd_times(IsoImage *image,
char **creation_time, char **modification_time,
char **expiration_time, char **effective_time);
/**
* Create a new set of El-Torito bootable images by adding a boot catalog
* and the default boot image.
@ -3055,7 +3123,7 @@ const char *iso_image_get_biblio_file_id(const IsoImage *image);
* creation time.
* @param boot
* Location where a pointer to the added boot image will be stored. That
* object is owned by the IsoImage and should not be freed by the user,
* object is owned by the IsoImage and must not be freed by the user,
* nor dereferenced once the last reference to the IsoImage was disposed
* via iso_image_unref(). A NULL value is allowed if you don't need a
* reference to the boot image.
@ -3105,7 +3173,7 @@ int iso_image_add_boot_image(IsoImage *image, const char *image_path,
* the image and catalog tree nodes. An application would want those, for
* example, to prevent the user removing it.
*
* Both nodes are owned by libisofs and should not be freed. You can get your
* Both nodes are owned by libisofs and must not be freed. You can get your
* own ref with iso_node_ref(). You can also check if the node is already
* on the tree by getting its parent (note that when reading El-Torito info
* from a previous image, the nodes might not be on the tree even if you haven't
@ -3117,7 +3185,7 @@ int iso_image_add_boot_image(IsoImage *image, const char *image_path,
* The image from which to get the boot image.
* @param boot
* If not NULL, it will be filled with a pointer to the boot image, if
* any. That object is owned by the IsoImage and should not be freed by
* any. That object is owned by the IsoImage and must not be freed by
* the user, nor dereferenced once the last reference to the IsoImage was
* disposed via iso_image_unref().
* @param imgnode
@ -3435,9 +3503,15 @@ int el_torito_get_selection_crit(ElToritoBootImage *bootimg, uint8_t crit[20]);
* @param bootimg
* The image to inquire
* @param flag
* Reserved for future usage, set to 0.
* Bitfield for control purposes:
* bit0 - bit3= mode
* 0 = inquire for classic boot info table as described in man mkisofs
* @since 0.6.32
* 1 = inquire for GRUB2 boot info as of bit9 of options of
* el_torito_set_isolinux_options()
* @since 1.3.0
* @return
* 1 = seems to contain oot info table , 0 = quite surely not
* 1 = seems to contain the inquired boot info, 0 = quite surely not
* @since 0.6.32
*/
int el_torito_seems_boot_info_table(ElToritoBootImage *bootimg, int flag);
@ -3501,6 +3575,11 @@ int el_torito_seems_boot_info_table(ElToritoBootImage *bootimg, int flag);
* mentioned. The ISOLINUX MBR must look suitable or else an error
* event will happen at image generation time.
* @since 1.2.4
* bit9= GRUB2 boot info
* Patch the boot image file at byte 1012 with the 512-block
* address + 2. Two little endian 32-bit words. Low word first.
* This is combinable with bit0.
* @since 1.3.0
* @param flag
* Reserved for future usage, set to 0.
* @return
@ -3544,7 +3623,7 @@ void el_torito_patch_isolinux_image(ElToritoBootImage *bootimg);
* @param img
* The image to be inquired.
* @param data
* A byte array of at least 32768 bytesi to take the loaded bytes.
* A byte array of at least 32768 bytes to take the loaded bytes.
* @param options
* The option bits which will be applied if not overridden by
* iso_write_opts_set_system_area(). See there.
@ -3608,6 +3687,41 @@ int iso_image_get_mips_boot_files(IsoImage *image, char *paths[15], int flag);
*/
int iso_image_give_up_mips_boot(IsoImage *image, int flag);
/**
* Designate a data file in the ISO image of which the position and size
* shall be written after the SUN Disk Label. The position is written as
* 64-bit big-endian number to byte position 0x228. The size is written
* as 32-bit big-endian to 0x230.
* This setting has an effect only if system area type is set to 3
* with iso_write_opts_set_system_area().
*
* @param img
* The image to be manipulated.
* @param sparc_core
* The IsoFile which shall be mentioned after the SUN Disk label.
* NULL is a permissible value. It disables this feature.
* @param flag
* Bitfield for control purposes, unused yet, submit 0
* @return
* 1 is success , <0 means error
* @since 1.3.0
*/
int iso_image_set_sparc_core(IsoImage *img, IsoFile *sparc_core, int flag);
/**
* Obtain the current setting of iso_image_set_sparc_core().
*
* @param img
* The image to be inquired.
* @param sparc_core
* Will return a pointer to the IsoFile (or NULL, which is not an error)
* @param flag
* Bitfield for control purposes, unused yet, submit 0
* @return
* 1 is success , <0 means error
* @since 1.3.0
*/
int iso_image_get_sparc_core(IsoImage *img, IsoFile **sparc_core, int flag);
/**
* Increments the reference counting of the given node.
@ -3839,7 +3953,7 @@ int iso_node_set_name(IsoNode *node, const char *name);
/**
* Get the name of a node.
* The returned string belongs to the node and should not be modified nor
* The returned string belongs to the node and must not be modified nor
* freed. Use strdup if you really need your own copy.
*
* @since 0.6.2
@ -4418,7 +4532,7 @@ int iso_dir_find_children(IsoDir* dir, IsoFindCondition *cond,
/**
* Get the destination of a node.
* The returned string belongs to the node and should not be modified nor
* The returned string belongs to the node and must not be modified nor
* freed. Use strdup if you really need your own copy.
*
* @since 0.6.2
@ -6336,7 +6450,10 @@ int iso_file_remove_filter(IsoFile *file, int flag);
* @param stream
* The eventual filter stream to be inquired.
* @param flag
* Bitfield for control purposes. Submit 0 for now.
* Bitfield for control purposes.
* bit0= Follow the chain of input streams and return the one at the
* end of the chain.
* @since 1.3.2
* @return
* The input stream, if one exists. Elsewise NULL.
* No extra reference to the stream is taken by this call.
@ -7424,11 +7541,14 @@ int iso_image_hfsplus_get_blessed(IsoImage *img, IsoNode ***blessed_nodes,
/** Too many chained symbolic links (FAILURE, HIGH, -395) */
#define ISO_DEEP_SYMLINK 0xE830FE75
/** Unrecognized file type in ISO image (FAILURE, HIGH, -396) */
#define ISO_BAD_ISO_FILETYPE 0xE830FE74
/* Internal developer note:
Place new error codes directly above this comment.
Newly introduced errors must get a message entry in
libisofs/message.c, function iso_error_to_msg()
libisofs/messages.c, function iso_error_to_msg()
*/
/* ! PLACE NEW ERROR CODES ABOVE. NOT AFTER THIS LINE ! */

View File

@ -88,6 +88,7 @@ iso_image_fs_get_volume_id;
iso_image_generator_is_running;
iso_image_get_abstract_file_id;
iso_image_get_all_boot_imgs;
iso_image_get_app_use;
iso_image_get_application_id;
iso_image_get_attached_data;
iso_image_get_biblio_file_id;
@ -98,8 +99,10 @@ iso_image_get_data_preparer_id;
iso_image_get_mips_boot_files;
iso_image_get_msg_id;
iso_image_get_publisher_id;
iso_image_get_pvd_times;
iso_image_get_root;
iso_image_get_session_md5;
iso_image_get_sparc_core;
iso_image_get_system_area;
iso_image_get_system_id;
iso_image_get_volset_id;
@ -112,6 +115,7 @@ iso_image_new;
iso_image_ref;
iso_image_remove_boot_image;
iso_image_set_abstract_file_id;
iso_image_set_app_use;
iso_image_set_application_id;
iso_image_set_biblio_file_id;
iso_image_set_boot_catalog_hidden;
@ -121,6 +125,7 @@ iso_image_set_copyright_file_id;
iso_image_set_data_preparer_id;
iso_image_set_ignore_aclea;
iso_image_set_publisher_id;
iso_image_set_sparc_core;
iso_image_set_system_id;
iso_image_set_volset_id;
iso_image_set_volume_id;

View File

@ -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

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009 Thomas Schmitt
* Copyright (c) 2009 - 2013 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
@ -527,19 +527,25 @@ int checksum_copy_old_nodes(Ecma119Image *target, IsoNode *node, int flag)
if (md5_pt == NULL)
return 0;
ret = iso_node_lookup_attr(node, "isofs.cx", &value_length,
&value, 0);
if (ret == 1 && value_length == 4) {
for (i = 0; i < 4; i++)
idx = (idx << 8) | ((unsigned char *) value)[i];
if (idx > 0 && idx <= target->checksum_idx_counter) {
memcpy(target->checksum_buffer + 16 * idx, md5_pt, 16);
if (!target->will_cancel) {
ret = iso_node_lookup_attr(node, "isofs.cx", &value_length,
&value, 0);
if (ret == 1 && value_length == 4) {
for (i = 0; i < 4; i++)
idx = (idx << 8) | ((unsigned char *) value)[i];
if (idx > 0 && idx <= target->checksum_idx_counter) {
memcpy(target->checksum_buffer + 16 * idx, md5_pt, 16);
}
}
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.
*/
iso_node_remove_xinfo(node, checksum_md5_xinfo_func);
}
if (value != NULL)
free(value);
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) {

View File

@ -139,6 +139,7 @@ int iso_node_xinfo_dispose_cloners(int flag)
next = assoc->next;
free((char *) assoc);
}
iso_xinfo_cloner_list= NULL;
return(1);
}
@ -344,9 +345,9 @@ const char *iso_error_to_msg(int errcode)
case ISO_WRONG_PVD:
return "Wrong or damaged Primary Volume Descriptor";
case ISO_WRONG_RR:
return "Wrong or damaged RR entry";
return "Wrong or damaged Rock Ridge entry";
case ISO_UNSUPPORTED_RR:
return "Unsupported RR feature";
return "Unsupported Rock Ridge feature";
case ISO_WRONG_ECMA119:
return "Wrong or damaged ECMA-119";
case ISO_UNSUPPORTED_ECMA119:
@ -360,9 +361,9 @@ const char *iso_error_to_msg(int errcode)
case ISO_UNSUPPORTED_SUSP:
return "Unsupported SUSP feature";
case ISO_WRONG_RR_WARN:
return "Error on a RR entry that can be ignored";
return "Error on a Rock Ridge entry that can be ignored";
case ISO_SUSP_UNHANDLED:
return "Error on a RR entry that can be ignored";
return "Unhandled SUSP entry";
case ISO_SUSP_MULTIPLE_ER:
return "Multiple ER SUSP entries found";
case ISO_UNSUPPORTED_VD:
@ -500,6 +501,8 @@ const char *iso_error_to_msg(int errcode)
return "Symbolic link cannot be resolved";
case ISO_DEEP_SYMLINK:
return "Too many chained symbolic links";
case ISO_BAD_ISO_FILETYPE:
return "Unrecognized file type in ISO image";
default:
return "Unknown error";
}

View File

@ -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;

View File

@ -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

View File

@ -890,17 +890,27 @@ void iso_stream_get_file_name(IsoStream *stream, char *name)
}
}
/* @param flag bit0= Obtain most fundamental stream */
IsoStream *iso_stream_get_input_stream(IsoStream *stream, int flag)
{
IsoStreamIface* class;
IsoStream *result = NULL, *next;
if (stream == NULL) {
return NULL;
}
class = stream->class;
if (class->version < 2)
return NULL;
return class->get_input_stream(stream, 0);
while (1) {
class = stream->class;
if (class->version < 2)
return result;
next = class->get_input_stream(stream, 0);
if (next == NULL)
return result;
result = next;
if (!(flag & 1))
return result;
stream = result;
}
}
char *iso_stream_get_source_path(IsoStream *stream, int flag)

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2008 Vreixo Formoso
* Copyright (c) 2010 - 2012 Thomas Schmitt
* Copyright (c) 2010 - 2013 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
@ -72,21 +72,25 @@ static int precompute_gpt(Ecma119Image *t);
/*
* @param flag bit0= img_blocks is start address rather than end address:
do not subtract 1
bit1= img_blocks is counted in 512-byte units rather than 2 KiB
*/
static
void iso_compute_cyl_head_sec(uint32_t *img_blocks, int hpc, int sph,
void iso_compute_cyl_head_sec(uint64_t img_blocks, int hpc, int sph,
uint32_t *end_lba, uint32_t *end_sec,
uint32_t *end_head, uint32_t *end_cyl, int flag)
{
uint32_t secs;
uint64_t secs;
/* Partition table unit is 512 bytes per sector, ECMA-119 unit is 2048 */
if (*img_blocks >= 0x40000000)
*img_blocks = 0x40000000 - 1; /* truncate rather than roll over */
if (flag & 1)
secs = *end_lba = *img_blocks * 4; /* first valid 512-lba */
if(flag & 2)
secs = img_blocks;
else
secs = *end_lba = *img_blocks * 4 - 1; /* last valid 512-lba */
secs = img_blocks * 4;
if (secs > (uint64_t) 0xfffffffc)
secs = 0xfffffffc; /* truncate rather than roll over */
if (flag & 1)
*end_lba = secs; /* first valid 512-lba */
else
secs = *end_lba = secs - 1; /* last valid 512-lba */
*end_cyl = secs / (sph * hpc);
secs -= *end_cyl * sph * hpc;
*end_head = secs / sph;
@ -165,10 +169,12 @@ int iso_compute_append_partitions(Ecma119Image *t, int flag)
}
/* Note: partition_offset and partition_size are counted in 2048 blocks
/* @param flag
bit1= partition_offset and partition_size are counted in
blocks of 512 rather than 2048
*/
static int write_mbr_partition_entry(int partition_number, int partition_type,
uint32_t partition_offset, uint32_t partition_size,
uint64_t partition_offset, uint64_t partition_size,
int sph, int hpc, uint8_t *buf, int flag)
{
uint8_t *wpt;
@ -178,10 +184,12 @@ static int write_mbr_partition_entry(int partition_number, int partition_type,
int i;
after_end = partition_offset + partition_size;
iso_compute_cyl_head_sec(&partition_offset, hpc, sph,
&start_lba, &start_sec, &start_head, &start_cyl, 1);
iso_compute_cyl_head_sec(&after_end, hpc, sph,
&end_lba, &end_sec, &end_head, &end_cyl, 0);
iso_compute_cyl_head_sec((uint64_t) partition_offset, hpc, sph,
&start_lba, &start_sec, &start_head, &start_cyl,
1 | (flag & 2));
iso_compute_cyl_head_sec((uint64_t) after_end, hpc, sph,
&end_lba, &end_sec, &end_head, &end_cyl,
(flag & 2));
wpt = buf + 446 + (partition_number - 1) * 16;
/* Not bootable */
@ -244,7 +252,7 @@ int make_grub_msdos_label(uint32_t img_blocks, int sph, int hpc,
uint32_t end_lba, end_sec, end_head, end_cyl;
int i;
iso_compute_cyl_head_sec(&img_blocks, hpc, sph,
iso_compute_cyl_head_sec((uint64_t) img_blocks, hpc, sph,
&end_lba, &end_sec, &end_head, &end_cyl, 0);
/* 1) Zero-fill 446-510 */
@ -308,9 +316,9 @@ int iso_offset_partition_start(uint32_t img_blocks, uint32_t partition_offset,
uint32_t start_lba, start_sec, start_head, start_cyl;
int i;
iso_compute_cyl_head_sec(&partition_offset, hpc, sph,
iso_compute_cyl_head_sec((uint64_t) partition_offset, hpc, sph,
&start_lba, &start_sec, &start_head, &start_cyl, 1);
iso_compute_cyl_head_sec(&img_blocks, hpc, sph,
iso_compute_cyl_head_sec((uint64_t) img_blocks, hpc, sph,
&end_lba, &end_sec, &end_head, &end_cyl, 0);
wpt = buf + 446;
@ -691,7 +699,8 @@ static int write_sun_partition_entry(int partition_number,
*/
static int make_sun_disk_label(Ecma119Image *t, uint8_t *buf, int flag)
{
int ret;
int ret, i;
uint64_t blk;
/* Bytes 512 to 32767 may come from image or external file */
memset(buf, 0, 512);
@ -733,6 +742,16 @@ static int make_sun_disk_label(Ecma119Image *t, uint8_t *buf, int flag)
/* 508 - 509 | 0xdabe | Magic Number */
iso_msb(buf + 508, 0xdabe, 2);
if (t->sparc_core_src != NULL) {
/* May be used for grub-sparc. */
blk= ((uint64_t) t->sparc_core_src->sections[0].block) *
(uint64_t) 2048;
for (i = 0; i < 8; i++)
buf[Libisofs_grub2_sparc_patch_adr_poS + i] = blk >> ((7 - i) * 8);
iso_msb(buf + Libisofs_grub2_sparc_patch_size_poS,
t->sparc_core_src->sections[0].size, 4);
}
/* Set partition 1 to describe ISO image and compute checksum */
t->appended_part_start[0] = 0;
t->appended_part_size[0] = t->curblock;
@ -794,7 +813,7 @@ int iso_quick_gpt_entry(Ecma119Image *t,
int iso_quick_mbr_entry(Ecma119Image *t,
uint32_t start_block, uint32_t block_count,
uint64_t start_block, uint64_t block_count,
uint8_t type_byte, uint8_t status_byte,
int desired_slot)
{
@ -880,7 +899,7 @@ static int iso_write_apm_entry(Ecma119Image *t, int apm_block_size,
else
block_fac = 2048 / apm_block_size;
memset(buf, apm_block_size, 0);
memset(buf, 0, apm_block_size);
wpt = buf;
/* Signature */
@ -1115,10 +1134,11 @@ static int iso_write_mbr(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf)
/* <<< Dummy mock-up */
if (t->mbr_req_count <= 0) {
ret = iso_quick_mbr_entry(t, 0, 0, 0xee, 0, 0);
ret = iso_quick_mbr_entry(t, (uint64_t) 0, (uint64_t) 0, 0xee, 0, 0);
if (ret < 0)
return ret;
ret = iso_quick_mbr_entry(t, 100, 0, 0x0c, 0x80, 1);
ret = iso_quick_mbr_entry(t, ((uint64_t) 100) * 4, (uint64_t) 0,
0x0c, 0x80, 1);
if (ret < 0)
return ret;
}
@ -1147,7 +1167,7 @@ static int iso_write_mbr(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf)
t->mbr_req[i]->block_count = t->mbr_req[i + 1]->start_block -
t->mbr_req[i]->start_block;
else
t->mbr_req[i]->block_count = img_blocks -
t->mbr_req[i]->block_count = ((uint64_t) img_blocks) * 4 -
t->mbr_req[i]->start_block;
}
@ -1184,7 +1204,7 @@ static int iso_write_mbr(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf)
ret = write_mbr_partition_entry(i + 1, (int) t->mbr_req[q]->type_byte,
t->mbr_req[q]->start_block, t->mbr_req[q]->block_count,
t->partition_secs_per_head, t->partition_heads_per_cyl,
buf, 0);
buf, 2);
if (ret < 0)
return ret;
buf[446 + i * 16] = t->mbr_req[q]->status_byte;
@ -1298,7 +1318,7 @@ int iso_write_gpt_header_block(Ecma119Image *t, uint32_t img_blocks,
}
/* CRC-32 of this header while head_crc is 0 */
crc = iso_crc32_gpt((unsigned char *) buf, 512, 0);
crc = iso_crc32_gpt((unsigned char *) buf, 92, 0);
wpt = ((char *) buf) + 16;
iso_lsb_to_buf(&wpt, crc, 4, 0);
@ -1417,6 +1437,8 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
int first_partition = 1, last_partition = 4, apm_flag, part_type;
int gpt_count = 0, gpt_idx[128], apm_count = 0;
uint32_t img_blocks;
uint64_t blk;
uint8_t *wpt;
if ((t == NULL) || (buf == NULL)) {
return ISO_NULL_POINTER;
@ -1564,7 +1586,8 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
return ISO_ASSERT_FAILURE;
if (t->partition_offset == 0) {
/* Re-write partion entry 1 : start at 0, type Linux */
ret = write_mbr_partition_entry(1, 0x83, 0, img_blocks,
ret = write_mbr_partition_entry(1, 0x83,
(uint64_t) 0, (uint64_t) img_blocks,
t->partition_secs_per_head, t->partition_heads_per_cyl,
buf, 0);
if (ret < 0)
@ -1599,7 +1622,8 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
buf, t->appended_partitions[i][0] == 0);
} else {
ret = write_mbr_partition_entry(i + 1, t->appended_part_types[i],
t->appended_part_start[i], t->appended_part_size[i],
(uint64_t) t->appended_part_start[i],
(uint64_t) t->appended_part_size[i],
t->partition_secs_per_head, t->partition_heads_per_cyl,
buf, 0);
}
@ -1607,6 +1631,15 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
return ret;
}
if (sa_type == 0 && (t->system_area_options & 0x4000) && !do_isohybrid) {
/* Patch MBR for GRUB2 */
blk = t->bootsrc[0]->sections[0].block * 4 +
Libisofs_grub2_mbr_patch_offsT;
wpt = buf + Libisofs_grub2_mbr_patch_poS;
for (i = 0; i < 8; i++)
wpt[i] = blk >> (i * 8);
}
return ISO_SUCCESS;
}
@ -2115,7 +2148,7 @@ tampered_head:;
/* Compute new header CRC */
memset(new_head + 16, 0, 4);
crc = iso_crc32_gpt((unsigned char *) new_head, 512, 0);
crc = iso_crc32_gpt((unsigned char *) new_head, 92, 0);
iso_lsb(new_head + 16, crc, 4);
/* Copy GPT entries */
@ -2226,7 +2259,7 @@ static int partprepend_writer_compute_data_blocks(IsoImageWriter *writer)
if (t->prep_partition != NULL || t->fat || will_have_gpt ||
t->mbr_req_count > 0)
return ISO_BOOT_MBR_OVERLAP;
ret = iso_quick_mbr_entry(t, (uint32_t) 0, (uint32_t) 0,
ret = iso_quick_mbr_entry(t, (uint64_t) 0, (uint64_t) 0,
0x96, 0x80, 0);
if (ret < 0)
return ret;
@ -2241,21 +2274,25 @@ static int partprepend_writer_compute_data_blocks(IsoImageWriter *writer)
}
if (t->prep_part_size > 0 || t->fat || will_have_gpt) {
/* Protecting MBR entry for ISO start or whole ISO */
ret = iso_quick_mbr_entry(t, (uint32_t) t->partition_offset,
(uint32_t) 0, will_have_gpt ? 0xee : 0xcd, 0, 0);
ret = iso_quick_mbr_entry(t, will_have_gpt ? (uint64_t) 1 :
((uint64_t) t->partition_offset) * 4,
(uint64_t) 0,
will_have_gpt ? 0xee : 0xcd, 0, 0);
if (ret < 0)
return ret;
}
if (t->prep_part_size > 0) {
ret = iso_quick_mbr_entry(t, t->curblock, t->prep_part_size, 0x41,
0, 0);
ret = iso_quick_mbr_entry(t, ((uint64_t) t->curblock) * 4,
((uint64_t) t->prep_part_size) * 4,
0x41, 0, 0);
if (ret < 0)
return ret;
t->curblock += t->prep_part_size;
}
if (t->prep_part_size > 0 || t->fat) {
/* FAT partition or protecting MBR entry for ISO end */
ret = iso_quick_mbr_entry(t, (uint32_t) t->curblock, (uint32_t) 0,
ret = iso_quick_mbr_entry(t, ((uint64_t) t->curblock) * 4,
(uint64_t) 0,
t->fat ? 0x0c : 0xcd, 0, 0);
if (ret < 0)
return ret;

View File

@ -78,13 +78,13 @@ int iso_compute_append_partitions(Ecma119Image *t, int flag);
*/
struct iso_mbr_partition_request {
/* Always given in blocks of 2 KiB */
uint32_t start_block;
/* Always given in blocks of 512 bytes */
uint64_t start_block;
/* A block count of 0 means that the partition reaches up to the start of
the next one.
*/
uint32_t block_count;
uint64_t block_count;
/* Partition type */
uint8_t type_byte;
@ -115,7 +115,7 @@ int iso_register_mbr_entry(Ecma119Image *t,
name and type are 0-terminated strings, which may get silently truncated.
*/
int iso_quick_mbr_entry(Ecma119Image *t,
uint32_t start_block, uint32_t block_count,
uint64_t start_block, uint64_t block_count,
uint8_t type_byte, uint8_t status_byte,
int desired_slot);
@ -266,4 +266,17 @@ int gpt_tail_writer_create(Ecma119Image *target);
/* Only for up to 36 characters ISO-8859-1 (or ASCII) input */
void iso_ascii_utf_16le(uint8_t gap_name[72]);
/* Parameters of MBR patching for GRUB2
Might later become variables in Ecma119Image
*/
#define Libisofs_grub2_mbr_patch_poS 0x1b0
#define Libisofs_grub2_mbr_patch_offsT 4
/* Parameters of SUN Disk Label patching for GRUB2
See API iso_image_set_sparc_core().
*/
#define Libisofs_grub2_sparc_patch_adr_poS 0x228
#define Libisofs_grub2_sparc_patch_size_poS 0x230
#endif /* SYSTEM_AREA_H_ */

View File

@ -803,6 +803,8 @@ int iso_add_dir_src_rec(IsoImage *image, IsoDir *parent, IsoFileSource *dir)
ret = iso_file_source_lstat(file, &info);
}
if (ret < 0) {
ret = iso_msg_submit(image->id, ISO_FILE_CANT_ADD, ret,
"Error when adding file %s", path);
goto dir_rec_continue;
}

View File

@ -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 == '_');

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);
/**
* 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.
*