Compare commits

..

144 Commits

Author SHA1 Message Date
6c9b81a474 Version leap to 1.4.0 2015-05-17 19:27:00 +02:00
393cc070f3 Included stdlib.h in libisofs/util.h to get off_t defined in FreeBSD. 2015-05-17 17:08:04 +02:00
006caa2fd2 Updated changelog. 2015-05-17 10:27:55 +02:00
c47167058a Improved handling of cylinder alignment if the resulting image size
size is not divisible by 2048. Old behavior was to not align. New is
to pad up by a few blocks of 512 bytes.
2015-05-10 09:34:45 +02:00
5a3d84cbbb Fixed omissions of rev 1197 about so_write_opts_set_prep_img() and
iso_write_opts_set_efi_bootp().
2015-04-28 14:21:36 +02:00
5f6e64b792 Bug fix: GPT production did not yield proper results with appended sessions
resp. with TOC emulation enabled.
2015-04-25 12:13:11 +02:00
d4b8cbe474 New API object iso_interval_reader. Enabling flag bits for older API calls
iso_write_opts_set_prep_img(), iso_write_opts_set_efi_bootp(),
and iso_write_opts_set_partition_img().
2015-04-23 15:46:04 +02:00
a0719328ea Bug fix: A zero sized GPT partition was marked after the last appended
GPT partition.
2015-04-18 14:07:16 +02:00
c8776e605e Bug fix: iso_image_report_system_area() did not show GPT partitions of size 0. 2015-04-18 13:54:54 +02:00
003aa5832e Fixing an omission of rev 1183. Protective MBR was produced for
appended GPT partitions only if ISOLINUX isohybrid was enabled.
2015-04-14 20:13:06 +02:00
a78864252e Mentioned official UEFI 2.4 specs in description of boot sectors. 2015-03-16 15:03:58 +01:00
e56a782b89 Bug fix: If iso_write_opts_set_hardlinks() enabled automatic inode numbers,
then they did not get into effect with nodes were zisofs decoder filters got
attached during the image load process.
2015-03-09 19:59:54 +01:00
9e17516e0d Based the iso_stream_cmp_ino() comparison of streams from the loaded
ISO filesystem on their data extents rather than on their inode numbers.
2015-03-09 19:49:39 +01:00
e29cd723dd Accounting for a long AAIP list in root directory. 2015-03-05 15:44:47 +01:00
b0694b4e25 Name change with some debugging macros. 2015-03-01 22:18:59 +01:00
850302dde5 Fixed another bug introduced by rev 1084.
The assumption was wrong that CE must be the last SUSP entry in its
directory record.
2015-03-01 22:14:35 +01:00
26b4222948 Fixed a bug introduced with rev 1184.
Calculated size of the directory tree could differ from written size.
2015-03-01 17:52:19 +01:00
782bb7854e New system area type 6 = DEC Alpha SRM boot sector.
New API calls iso_image_set_alpha_boot(), iso_image_get_alpha_boot().
Thanks to Helge Deller.
2015-02-28 15:13:38 +01:00
9c33eb5f10 Forgot to update copyright in previous commit. 2015-02-28 14:45:29 +01:00
8e55195edc Working around a Linux kernel bug, which hides files of which the
Rock Ridge CE entry points to a range that crosses a block boundary,
or of which the byte offset is larger than the block size of 2048.
Thanks to Joerg Meyer.
2015-02-26 17:56:34 +01:00
527b613607 New API call iso_write_opts_set_appended_as_gpt()
and marking of appended partitions in GPT if GPT emerges for other reasons.
2015-02-06 11:59:25 +01:00
0819f93f79 Minor changes about GPT in description of boot sectors 2015-02-06 11:57:06 +01:00
3b0ba17f3d Avoiding a SIGSEGV with loading a faulty ISO filesystem.
Debian bug 774152. Thanks to Jakub Wilk.
2014-12-29 18:32:53 +01:00
0611f468c2 Fixed buffer overflow in demo/demo.c with gesture -iso_read.
Debian bug 774147. Thanks to Jakub Wilk.
2014-12-29 15:08:47 +01:00
5c6ce72c02 Fixed a typo in message of make install.
Debian bug 774140. Thanks to Jakub Wilk.
2014-12-29 11:51:30 +01:00
585a54d020 Improved size estimation when loading ISO with hidden El Torito images 2014-12-03 20:22:30 +01:00
7ea6d4ebcb Forced ECMA-119 timestamp generation to GMT if no timezone info is available. 2014-11-28 12:08:21 +01:00
3e33fa5fa1 Equipped all non-system-dependent open(2) calls with O_BINARY. 2014-11-26 14:44:43 +01:00
cdc336a02b Checking at configure time for timezone integer variable. 2014-11-26 14:26:14 +01:00
288eb75745 Removed a surplus function definition from system_area.h which spoiled
compilation on Cygwin. Thanks to Gary Jiang.
2014-11-21 10:26:46 +01:00
210b5817cb Letting lfs_read() retry if read(2) returns a short byte count. 2014-11-20 13:15:35 +01:00
2fe0bf511b Continuing GPT inspection even if reading of GPT backup fails 2014-11-11 12:28:23 +01:00
af23ad0f90 Bug fix: Only 128 bytes of an emerging GPT header block were zeroized 2014-11-04 13:48:31 +01:00
0fc4421e15 Bug fix: The header indicator of the last El Torito catalog section header
was set to 0x90 rather than 0x91 if more than one boot image is in that
section.
2014-10-11 14:57:48 +02:00
6ed2404420 Recording the need for boot-info-table and grub2-boot-info
in El Torito images which get defined by commands rather
than being loaded from an ISO filesystem.
2014-10-11 14:31:13 +02:00
a22c16d5ef Increased default weight of El Torito boot catalog to 1 billion 2014-10-05 13:17:53 +02:00
5384342336 Re-arranged help texts of iso_image_report_system_area() and iso_image_report_el_torito() 2014-10-05 13:15:51 +02:00
a97c66ebb8 Preserving the weights of imported boot image files 2014-10-03 17:41:59 +02:00
1c2851b5ba Preserving the weights of imported boot image files. 2014-10-03 17:07:35 +02:00
cbea1335d8 Small corrections with MBR assessment of iso_image_report_system_area() 2014-10-03 09:46:59 +02:00
6da58860ec Mentioned /ppc/bootinfo.txt in description of CHRP 2014-09-27 11:08:59 +02:00
c47451d12b Bug fix: iso_image_report_system_area() caused SIGSEGV by NULL if no valid
ISO 9660 image was loeaded. Thanks to OmegaPhil.
2014-08-16 15:01:11 +02:00
a068a1349a Updated copyright date 2014-07-06 08:54:50 +02:00
eae886bcb5 Version leap to 1.3.9 2014-06-28 08:19:22 +02:00
288e778875 Version leap to 1.3.8 2014-06-28 08:14:27 +02:00
8e687db01d Updated changelog 2014-06-27 18:45:14 +02:00
273182aa2a Avoiding complaints of iso_image_report_system_area() about backup GPT
created by a corrected version of syslinux/utils/isohybrid.c
2014-06-23 14:31:23 +02:00
e26d07ee77 Enabled recording and restoring of extattr on NetBSD 2014-06-20 09:07:51 +02:00
1b5caac764 Made declarations of make_isolinux_mbr() consistent.
Debian bug 751501. Thanks to Michael Tautschnig.
2014-06-13 16:25:00 +02:00
42821af4e6 Tolerating ECMA-119 Extended Attributes when loading an image 2014-06-13 09:34:30 +02:00
c17ba1980a Clarified which inode is local ino_t and which is Rock Ridge uint32_t. 2014-05-27 21:31:53 +02:00
1df1642a61 Corrected help text of iso_image_report_system_area() 2014-05-08 20:07:46 +02:00
c07f42dfd4 Unified width of index columns to 3 digits in output of iso_image_report_*() 2014-04-29 19:39:42 +02:00
443156e100 Re-arranged output lines of iso_image_report_el_torito() 2014-04-29 19:17:06 +02:00
2f517301de Reacted on a compiler warning about an unused variable. 2014-04-28 21:06:10 +02:00
0bce145343 Changed report format of detected El Torito boot image options 2014-04-27 15:13:57 +02:00
6d64bc23cf Estimating size of El Torito boot images which are not represented by a file 2014-04-27 12:09:13 +02:00
25295d2bb0 Polished help text of iso_image_report_system_area() 2014-04-25 09:40:37 +02:00
3370f666f9 Split the large macro ISO_SYSAREA_REPORT_DOC into several parts ISO_SYSAREA_REPORT_DOC* 2014-04-24 13:56:52 +02:00
ad279352e3 New API call iso_image_report_el_torito() 2014-04-24 10:15:56 +02:00
dfd74d3d04 Bug fix: iso_file_get_old_image_lba() returned 0 in case of valid lba. 2014-04-23 16:22:37 +02:00
593844b0ed Recognizing partition offset 16 if the MBR is a protective msdos label 2014-04-15 10:18:50 +02:00
083795cba2 Changed start of overall isohybrid GPT partition from 0 to partition_offset 2014-04-14 17:54:07 +02:00
3b06d25a37 Removed a surplus semicolon of previous changeset 2014-04-14 16:18:50 +02:00
9e5158f59e Closed a memory leak introduced with rev 1133 2014-04-14 16:06:32 +02:00
d93be961e1 Closed a memory leak with disposal of iso_image_report_system_area() result 2014-04-13 11:21:33 +02:00
8c1c0775d6 Closed a memory leak with loading of hidden boot images 2014-04-13 11:07:10 +02:00
2f8bd3ac01 Split the output of iso_image_report_system_area() into separate texts. 2014-04-13 09:16:45 +02:00
6edc1ac057 New API call iso_crc32_gpt() 2014-04-12 14:54:54 +02:00
a394f4dfd2 Bug fix: The GUIDs of main GPT and backup GPT differed if more than one
System Area was written into the ISO image.
2014-04-11 16:15:19 +02:00
dd27f579eb New API call iso_image_report_system_area() 2014-04-11 15:39:45 +02:00
1ac59bec46 Clarified PALO header versions in boot sector description 2014-04-09 23:59:09 +02:00
af843e446f Included fcntl.h in libisofs.h to work around "#define open open64" in
fcntl.h of AIX. Thanks to Richard Nolde.
2014-04-09 09:48:31 +02:00
e6e037f87e Re-enabled HP-PA PALO boot preparations 2014-04-09 09:02:51 +02:00
ca2643b52b Updated description of boot sector formats 2014-04-09 08:31:34 +02:00
ed8066580a Reacted on compiler warning of gcc on AIX. Thanks Richard Nolde. 2014-04-03 21:45:19 +02:00
97ec68530b Applied similar bug fixes to Joliet and ISO 9660:1999 2014-04-02 19:40:17 +02:00
185cbd99bf Bug fix: Prevent allocation of empty ECMA-119 directory children list.
Thanks Richard Nolde.
2014-04-02 19:06:53 +02:00
0e00aeb638 Bug fix: Prevent allocation of empty hash tables. Thanks Richard Nolde. 2014-04-02 18:40:03 +02:00
03b45c3151 Version leap to 1.3.7 2014-03-04 17:08:29 +01:00
b82ca42f87 Version leap to 1.3.6 2014-03-04 17:00:54 +01:00
1a8a216822 Updated changelog 2014-03-04 10:05:57 +01:00
ef528f2f0e Temporarily disabled the unfinished HP-PA PALO bootability preparations 2014-03-04 09:23:04 +01:00
bedfa914d5 Temporarily disabled the unfinished HP-PA PALO bootability preparations 2014-03-03 20:15:08 +01:00
5383ae2faa Fixed a memory fault introduced with rev 1106 2014-02-16 14:42:39 +01:00
d23462657b Installed debugging code for error ISO_RR_NAME_RESERVED 2014-02-16 14:40:28 +01:00
b41e36365d Fixed a write to array index -1 with demo/demo -tree 2014-02-16 14:31:33 +01:00
985015cea1 Making sure that PVD time strings are allocated with 17 bytes plus trailing 0 2014-02-13 16:25:15 +01:00
27d4c79d0e Silenced warnings about -Wchar-subscripts, added /usr/local for NetBSD 2014-02-11 09:28:27 +01:00
5b78efb12a Clarified the content of the PVD timestamps. 2014-02-09 13:29:50 +01:00
2c2fb7caf2 Fixed a harmless bug introduced with rev 1111. 2014-01-26 10:07:10 +01:00
d51cefb097 Adapted HP-PA boot sector code to upcomming PALO header version 5 2014-01-16 11:59:58 +01:00
7637d13e11 New API calls iso_image_set_hppa_palo() and iso_image_get_hppa_palo() 2014-01-14 09:43:28 +01:00
b9b5284f22 Beautified the collision avoiding names 2014-01-04 16:28:25 +01:00
afa65e9f2a Reduced minimum length of collision avoiding name from 8 to 7 2014-01-03 21:16:56 +01:00
5e1aaca232 Avoided unnecessary recursion with production of collision avoiding names 2014-01-03 20:53:59 +01:00
fea649835c Small fix of previous change 2014-01-03 20:00:04 +01:00
44f475a4ef Improved handling of unconvertable file names and name collsions during iso_image_import() 2014-01-03 18:29:29 +01:00
60eb7e883c Issueing warnings when Joliet file names with non-UCS-2 characters get read 2013-12-31 13:14:42 +01:00
9b4e0b611a Bug fix: Division by zero if HFS+ was combined with TOC emulation for overwritable media. 2013-12-28 16:45:29 +01:00
1be57e34ec Completed implementation of API call iso_conv_name_chars() 2013-12-28 15:36:33 +01:00
b0e68bbcaa Fixed a memory access error introduced with rev 1099 2013-12-22 19:07:28 +01:00
fa61b94ac8 Consolidated the single copies of IsoWriteOpts members in Ecma119Image
by having a copy of the whole IsoWriteOpts in Ecma119Image
2013-12-22 19:02:44 +01:00
3e3c15812b New API call iso_conv_name_chars(), provisory implementation 2013-12-19 15:41:55 +01:00
88555bd059 New API call iso_write_opts_set_joliet_utf16()
and ability to read Joliet names as UTF-16BE
2013-12-17 21:45:52 +01:00
ba47d1534c Version leap to 1.3.5 2013-12-12 14:44:22 +01:00
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
50 changed files with 7927 additions and 1241 deletions

View File

@ -1,7 +1,7 @@
Vreixo Formoso <metalpain2002@yahoo.es>,
Mario Danic <mario.danic@gmail.com>,
Thomas Schmitt <scdbackup@gmx.net>
Copyright (C) 2007-2011 Vreixo Formoso, Mario Danic, Thomas Schmitt
Copyright (C) 2007-2014 Vreixo Formoso, Mario Danic, Thomas Schmitt
This program is free software; you can redistribute it and/or modify

View File

@ -1,9 +1,87 @@
libisofs-1.4.0.tar.gz Sun May 17 2014
===============================================================================
* Bug fix: iso_image_report_system_area() caused SIGSEGV by NULL if no valid
ISO 9660 image was loeaded. Thanks to OmegaPhil.
* Bug fix: A SIGSEGV could happen when loading a faulty ISO filesystem.
Debian bug 774152. Thanks to Jakub Wilk.
* Bug fix: Rock Ridge Continuation Area could be produced crossing a block
boundary. This is heavily disliked by the Linux kernel and spoils
the representation of directories which contain many symbolic links.
* Bug fix: If iso_write_opts_set_hardlinks() enabled automatic inode numbers,
then they did not get into effect with nodes were zisofs decoder
filters got attached during the image load process.
* Bug fix: The header indicator of the last El Torito catalog section header
was set to 0x90 rather than 0x91 if more than one boot image is in
that section.
* Bug fix: Only 128 bytes of an emerging GPT header block were zeroized.
* Bug fix: iso_image_report_system_area() did not show GPT partitions of
size 0.
* Bug fix: A zero sized GPT partition was marked after the last appended
GPT partition.
* Bug fix: GPT production did not yield proper results with appended sessions
resp. with TOC emulation enabled.
* Increased default weight of El Torito boot catalog to 1 billion.
* Improved handling of cylinder alignment if the resulting image size is not
divisible by 2048. Old behavior was to not align. New is to pad up by a
few blocks of 512 bytes.
* New API call iso_write_opts_set_appended_as_gpt()
and marking of appended partitions in GPT if GPT emerges for other reasons.
* New system area type 6 = DEC Alpha SRM boot sector.
New API calls iso_image_set_alpha_boot(), iso_image_get_alpha_boot().
Thanks to Helge Deller.
* New API object iso_interval_reader. Enabling flag bits for older API calls
iso_write_opts_set_prep_img(), iso_write_opts_set_efi_bootp(),
and iso_write_opts_set_partition_img().
libisofs-1.3.8.tar.gz Sat Jun 28 2014
===============================================================================
* Bug fix: Prevent allocation of empty hash tables. Thanks Richard Nolde.
* Bug fix: Prevent allocation of empty directory children lists.
Thanks Richard Nolde.
* Bug fix: The GUIDs of main GPT and backup GPT differed if more than one
System Area was written into the ISO image.
* New API calls iso_image_report_el_torito() and iso_image_report_system_area()
* New API call iso_crc32_gpt()
libisofs-1.3.6.tar.gz Tue Mar 04 2014
===============================================================================
* Bug fix: Division by zero if HFS+ was combined with TOC emulation for
overwritable media.
* New API call iso_write_opts_set_joliet_utf16() and ability to read Joliet
names as UTF-16BE
* New API call iso_conv_name_chars()
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
===============================================================================
* New API call iso_image_get_pvd_times().
* 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
===============================================================================

View File

@ -89,7 +89,7 @@ libinclude_HEADERS = \
libisofs/libisofs.h
install-exec-hook:
$(LIBBURNIA_LDCONFIG_CMD) "$(DESTDIR)$(libdir)" || echo 'NOTE: Explicite dynamic library configuration failed. If needed, configure manually for:' "$(DESTDIR)$(libdir)"
$(LIBBURNIA_LDCONFIG_CMD) "$(DESTDIR)$(libdir)" || echo 'NOTE: Explicit dynamic library configuration failed. If needed, configure manually for:' "$(DESTDIR)$(libdir)"
## ========================================================================= ##

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,7 +1,7 @@
AC_DEFUN([LIBBURNIA_SET_FLAGS],
[
case $target_os in
freebsd*)
freebsd* | netbsd*)
LDFLAGS="$LDFLAGS -L/usr/local/lib"
CPPFLAGS="$CPPFLAGS -I/usr/local/include"
;;
@ -198,3 +198,15 @@ dnl For debugging only
])
dnl LIBBURNIA_TRY_TIMEZONE is by Thomas Schmitt, libburnia project
dnl It tests whether the global variable exists and is suitable for
dnl integer arithmetics.
AC_DEFUN([LIBBURNIA_TRY_TIMEZONE],
[
echo -n "checking for timezone variable ... "
AC_TRY_LINK([ #include <time.h> ], [long int i; i = 1 - timezone; ],
[LIBBURNIA_TIMEZONE="timezone"], [LIBBURNIA_TIMEZONE="0"]
)
echo "$LIBBURNIA_TIMEZONE"
])

View File

@ -1,4 +1,4 @@
AC_INIT([libisofs], [1.2.8], [http://libburnia-project.org])
AC_INIT([libisofs], [1.4.0], [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=8
LIBISOFS_MINOR_VERSION=4
LIBISOFS_MICRO_VERSION=0
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.03.18 development jump has not yet happened
# SONAME = 70 - 64 = 6 . Library name = libisofs.6.64.0
LT_CURRENT=70
LT_AGE=64
# 2015.05.17 development jump has not yet happened
# SONAME = 82 - 76 = 6 . Library name = libisofs.6.76.0
LT_CURRENT=82
LT_AGE=76
LT_REVISION=0
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
@ -114,6 +114,16 @@ AC_CHECK_DECL([timegm],
,
[#include <time.h>])
dnl Whether timezone is an integer variable
AH_TEMPLATE([Libburnia_timezonE], [Either timezone or 0])
LIBBURNIA_TRY_TIMEZONE
if test x$LIBBURNIA_TIMEZONE = xtimezone
then
AC_DEFINE([Libburnia_timezonE], [timezone])
else
AC_DEFINE([Libburnia_timezonE], [0])
fi
dnl Check if non standard eaccess() function is available
AC_CHECK_DECL([eaccess],
[AC_DEFINE(HAVE_EACCESS, 1, [Define this if eaccess function is available])],
@ -140,7 +150,7 @@ if test x$enable_debug != xyes; then
CFLAGS="-DNDEBUG $CFLAGS"
else
if test x$GCC = xyes; then
CFLAGS="-g -pedantic -Wall -Wextra -Wno-unused-parameter $CFLAGS"
CFLAGS="-g -pedantic -Wall -Wextra -Wno-unused-parameter -Wno-char-subscripts $CFLAGS"
fi
CFLAGS="-DDEBUG $CFLAGS"
fi

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 - 2009 Vreixo Formoso, Thomas Schmitt
* Copyright (c) 2007 - 2014 Vreixo Formoso, 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
@ -95,7 +95,8 @@ tree_print_dir(IsoDir *dir, int level)
sp[i+1] = ' ';
}
sp[level * 2-1] = '-';
if (level > 0)
sp[level * 2 - 1] = '-';
sp[level * 2] = '\0';
iso_dir_get_children(dir, &iter);
@ -445,7 +446,8 @@ iso_read_print_dir(IsoFileSource *dir, int level)
sp[i+1] = ' ';
}
sp[level * 2-1] = '-';
if (level > 0)
sp[level * 2 - 1] = '-';
sp[level * 2] = '\0';
ret = iso_file_source_open(dir);
@ -550,7 +552,7 @@ int gesture_iso_cat(int argc, char **argv)
IsoReadOpts *opts;
if (argc != 3) {
fprintf(stderr, "Usage: isocat /path/to/image /path/to/file\n");
fprintf(stderr, "Usage: -iso_cat /path/to/image /path/to/file\n");
return 1;
}

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
@ -26,11 +28,15 @@ MIPS Volume Header, for MIPS Big Endian, e.g. SGI Indigo2.
DEC Boot Block, for MIPS Little Endian , e.g. DECstation.
SUN Disk Label and boot images, for SUN SPARC
GRUB2 SUN SPARC Core File Address
PowerPC Reference Platform (PReP), for IBM PowerPC
Common Hardware Reference Platform (CHRP), for IBM PowerPC
HP-PA via PALO header version 4
HP-PA via PALO header version 5
Combinations of boot mechanisms:
- SYSLINUX isohybrid MBR
- SYSLINUX isohybrid for MBR, UEFI and x86-Mac
@ -48,7 +54,7 @@ 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.
http://www.uefi.org/sites/default/files/resources/2_4_Errata_B.pdf
ECMA-119 prescribes that the first 32 kB of an ISO 9660 image are System Area
@ -119,7 +125,7 @@ Defined by El Torito are:
0 = "80x86" which is used for standard PCs with Intel x86 or compatible CPU
1 = "PowerPC" (possibly for IBM machines with PowerPC CPU)
2 = "Mac" (possibly for Apple computers with MC68000 or PowerPC CPU)
Further in use by GRUB2 and ISOLINUX is:
UEFI 2.4 specifies in 12.3.2.1 "ISO-9660 and El Torito":
0xef = EFI, a competitor resp. successor to PC-BIOS, possibly in use with
Intel ia64 Itanium and possibly with newer Apple machines.
@ -237,10 +243,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 +267,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.
---------- | ---------- | ----------------------------------------------------
------------------------------------------------------------------------------
@ -499,6 +529,7 @@ Sources:
http://mjg59.fedorapeople.org/Fedora-LiveCD.iso
http://en.wikipedia.org/wiki/GUID_Partition_Table
http://en.wikipedia.org/wiki/GUID
http://www.uefi.org/sites/default/files/resources/2_4_Errata_B.pdf
GPT is the partition map format of EFI, a successor of PC-BIOS.
@ -506,8 +537,11 @@ Block size is always 512. GPT consists of a header block at block address 1 and
a partition table near the start of the medium. This is called the primary GPT.
There is a backup copy of header and table near the end of the medium.
GPT is particularly designed to co-exist with MBR. If it is present, then the
booting firmware may or may not prefer it over the MBR partition table.
GPT is particularly designed to co-exist with MBR. Officially only with a
Protective MBR which covers the whole medium (except the MBR itself) by
a single partition of type 0xee. Inofficially often with filesystem partitions
marked in both, GPT and MBR. In the latter case the booting firmware may
or may not prefer GPT over the MBR partition table.
GPT can co-exist with APM if APM block size is at least 1024. In this case,
the primary partition table will begin after the last APM entry block.
@ -520,7 +554,7 @@ Byte Range | Value | Meaning (little endian numbers, LBA unit is 512 byte)
16 - 19 | head_crc | CRC-32 of this header while head_crc is 0
20 - 23 | reserved | = 0
24 - 31 | curr_lba | Location of this header block = 1
32 - 39 | back_lba | Location of header backup block. See below.
32 - 39 | backup_lba | Location of header backup block. See below.
40 - 47 | first_lba | First usable LBA for partitions
48 - 55 | last_lba | Last usable LBA for partitions
56 - 71 | guid | Disk GUID, Random
@ -545,13 +579,12 @@ bit1 becomes bit30, and so on. Further it gets exored with 0xffffffff.
A GUID consists of a 32-bit integer, two 16-bit integers, and an array of
8 bytes. The integers are to be stored big-endian.
A globally registered class of GUID are the partition type GUIDs.
This example uses two of them
A globally registered class of GUID are the partition type GUIDs:
Basic data partition: a2 a0 d0 eb , e5 b9 , 33 44 , 87 c0 68 b6 b7 26 99 c7
HFS+ partition : 00 53 46 48 , 00 00 , aa 11 , aa 11 00 30 65 43 ec ac
EFI System partition: 28 73 2a c1 , 1f f8 , d2 11 , ba 4b 00 a0 c9 3e c9 3b
Note that the wikipedia list shows the first 32-bit word and the next two
16-bit words in little-endia interpretation.
16-bit words in little-endian interpretation.
The partition table is an array of entries. Each has a size of 128 bytes.
A partition table entry looks like:
@ -589,7 +622,7 @@ Byte Range | Value | Meaning (little endian numbers, LBA unit is 512 byte)
| | Is recomputed after the following changes.
24 - 31 | curr_lba | Location of this header block.
| | Shows own block address.
32 - 39 | back_lba | Location of header backup block.
32 - 39 | backup_lba | Location of header backup block.
| | Points to primary header block = 1
72 - 79 | part_start | Partition entries start.
| | Points to start of backup partition table.
@ -741,8 +774,8 @@ Byte Range | Value | Meaning
| | (Elf32_Phdr field p_filesz + 511) / 512;
| |
28 - 31 | seg_start | Segment file offset. Blocks 512 bytes.
| | ISO 9660 LBA of boot file * 4 plus offset
| | + offset which stems from ELF header of boot file:
| | ISO 9660 LBA of boot file * 4 plus offset which
| | stems from ELF header of boot file:
| | (Elf32_Phdr field p_offset + 511) / 512;
| |
32 - 431 | ========== | Boot Map Entries 2 to 51
@ -798,7 +831,7 @@ Sources:
The Disk Label is written to the first 512 bytes of the image. It can mark
8 partitions (slices ) of which the first contains the ISO image. The other
7 may contain boot images.
Words are composed big-endian style.
Words are composed big-endian style. Block size is 512.
Boot images are provided externally. mkisofs arranges them after the end of
the ISO image so that each starts at a cylinder boundary (320 kB).
@ -810,7 +843,6 @@ their predecessor in the partition table:
If mkisofs is called with -G image -B ... all boot partitions are
mapped to the partition that contains the ISO9660 filesystem."
Disk Label components:
Byte Range | Value | Meaning
@ -873,7 +905,7 @@ Byte Range | Value | Meaning
| |
444 - 447 | start_cyl | Start cylinder
| |
448 - 451 | num_blocks | Number of blocks in partition
448 - 451 | num_blocks | Number of 512-byte blocks in partition
| |
452 - 507 | ========== | Partition table entries #2 to #8
| ... | See above Partition table entry #1
@ -884,6 +916,30 @@ Byte Range | Value | Meaning
| |
---------- | ---------- | ----------------------------------------------------
------------------------------------------------------------------------------
GRUB2 SUN SPARC Core File Address
Sources:
Mail conversations with Vladimir Serbinenko.
GRUB2 lets libisofs write after the disk label block the address and size of a
data file in the ISO image. E.g. of /boot/grub/sparc64-ieee1275/core.img.
This is combined with a SUN Disk Label which exposes only the single partition
describing the overall ISO filesystem size.
Byte Range | Value | Meaning
------------ | ---------- | --------------------------------------------------
512 - 551 | opaque | Code and data provided by GRUB2
| |
552 - 559 | offset | Start byte number of the file. 64-bit big-endian.
| |
560 - 563 | size | Number of bytes in the file. 32-bit big-endian.
| |
564 - 32767 | opaque | Code and data provided by GRUB2
| |
------------ | ---------- | --------------------------------------------------
------------------------------------------------------------------------------
@ -906,22 +962,191 @@ 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
https://www.ibm.com/developerworks/community/wikis/home?lang=en#!/wiki/W51a7ffcf4dfd_4b40_9d82_446ebc23c550/page/PowerLinux%20Boot%20howto
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)
The firmware looks up a file /ppc/bootinfo.txt which in SGML-ish tag
<boot-script> contains firmware commands.
E.g. to execute the binary /boot/grub/powerpc.elf as first stage of GRUB2:
<boot-script>boot &device;:\boot\grub\powerpc.elf</boot-script>
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].
------------------------------------------------------------------------------
>>> ??? HP-PA
HP-PA via PALO header version 4
for HP PA-RISC
Sources:
cdrkit-1.1.10/genisoimage/boot-hppa.c
by Steve McIntyre <steve@einval.com>
who states "Heavily inspired by palo"
This format is expected by PALO versions before 1.92. Their source code defines
PALOHDRVERSION as 4. The format also serves as fallback for newer versions,
which expect header version 5, if a 0-byte is found at byte position 1024.
There are five parameters which get encoded into the first 248 bytes of the
System Area: cmdline, bootloader, 32-bit kernel, 64-bit kernel, and ramdisk.
They are all mandatory.
While cmdline is simply a string of at most 127 characters, the other four
point to data files inside the ISO image.
All numbers are recorded big endian.
Boot sector components:
Byte Range | Value | Meaning
---------- | ---------- | ----------------------------------------------------
0 - 1 | 0x8000 | Magic
| |
2 - 6 | "PALO" | Zero terminated string
| |
7 - 7 | 4 | Version
| |
8 - 11 | kern32_adr | Byte address of the "HPPA 32-bit kernel" file
| | genisoimage option -hppa-kernel-32
12 - 15 | kern32_len | Byte count of the "HPPA 32-bit kernel" file
| |
16 - 19 | ramdsk_adr | Byte address of the "HPPA ramdisk" file
| | genisoimage option -hppa-ramdisk
20 - 23 | ramdsk_len | Byte count of the "HPPA ramdisk" file
| |
24 - 151 | cmdline | "Command line"
| | genisoimage option -hppa-cmdline
| |
232 - 235 | kern64_adr | Byte address of the "HPPA 64-bit kernel" file
| | genisoimage option -hppa-kernel-64
236 - 239 | kern64_len | Byte count of the "HPPA 64-bit kernel" file
| |
240 - 243 | bootld_adr | Byte address of the "HPPA bootloader" file
| | genisoimage option -hppa-bootloader
244 - 247 | bootld_len | Byte count of the "HPPA bootloader" file
| |
---------- | ---------- | ----------------------------------------------------
------------------------------------------------------------------------------
>>> ??? DEC Alpha
HP-PA via PALO header version 5
for HP PA-RISC
Sources:
Public mail conversations with Helge Deller, beginning with
https://lists.debian.org/debian-hppa/2014/01/msg00016.html
http://git.kernel.org/cgit/linux/kernel/git/deller/palo.git/tree/lib/
(especially struct firstblock in common.h and struct partition in part.h)
This format is expected by PALO versions 1.92 or higher. They fall back to
header version 4 if a 0-byte is found at byte position 1024.
Their source code defines PALOHDRVERSION as 5.
There are five parameters which get encoded into the first 2048 bytes of the
System Area: cmdline, bootloader, 32-bit kernel, 64-bit kernel, and ramdisk.
They are all mandatory.
While cmdline is simply a string of at most 1023 characters, the other four
point to data files inside the ISO image.
Several fields of the firstblock shall be hardcoded to 0, on advise of
Helge Deller. Their description is shown in round brackets.
All numbers are recorded big endian.
Except flags, all 4-byte integers are signed.
Boot sector components:
Byte Range | Value | Meaning
---------- | ---------- | ----------------------------------------------------
0 - 1 | 0x8000 | Magic
| |
2 - 6 | "PALO" | Zero terminated string
| |
7 - 7 | 5 | Version
| |
8 - 11 | kern32_adr | Byte address of the 32-bit kernel file
| |
12 - 15 | kern32_len | Byte count of the 32-bit kernel file
| |
16 - 19 | ramdsk_adr | Byte address of the ramdisk file
| |
20 - 23 | ramdsk_len | Byte count of the ramdisk file
| |
24 - 141 | 0 | All 0s. Old command line of version 4.
| |
| |
220 - 223 | 0 | (Length of uncompressed 32-bit kernel)
| |
224 - 227 | 0 | (Length of uncompressed 64-bit kernel)
| |
228 - 231 | 0 | (flags)
| |
232 - 235 | kern64_adr | Byte address of the 64-bit kernel file
| |
236 - 239 | kern64_len | Byte count of the 64-bit kernel file
| |
240 - 243 | ipl_adr | Byte address of the bootloader file
| |
244 - 247 | ipl_len | Byte count of the bootloader file
| |
248 - 251 | 0 | (ipl_entry: offset to first command in bootloader)
| |
446 - 511 | 0 | (MBR partition table and signature)
| |
1024 -2047 | cmdline | Zero terminated command line of up to
| | 1023 characters
| |
---------- | ---------- | ----------------------------------------------------
------------------------------------------------------------------------------
DEC Alpha SRM boot sector
for Alpha architecture
Sources:
http://www.tldp.org/HOWTO/text/SRM-HOWTO
SRM Firmware Howto - Rich Payne, and David Huggins-Daines
cdrkit-1.1.10/genisoimage/boot-alpha.c
by Steve McIntyre
who states "Heavily inspired by isomarkboot by David Mosberger in 1996"
mail conversations with Helge Deller
The SRM firmware expects a Secondary Bootstrap Loader program, which usually
is a data file of the ISO filesystem. This loader is announced by size and
block address in the first 512 bytes of the System Area.
SRM accepts the boot sector and executes the loader if the checksum matches.
All numbers are recorded as unsigned 64 bit little endian.
Boot sector components:
Byte Range | Value | Meaning
---------- | ---------- | ----------------------------------------------------
0 - ? | boot_string| genisoimage writes
| | "Linux/Alpha aboot for ISO filesystem."
| | with terminating zero byte.
| |
? - 479 | 0 | Unused / undefined.
| |
480 - 487 | length | Size of boot loader file in units of 512 bytes.
| |
488 - 495 | address | LBA of the boot loader file in units of 512 bytes.
| |
496 - 503 | flag | "Always 0"
| |
504 - 511 | checksum | Sum of 64 bit words 0 to 63 (bytes 0 to 503).
| |
---------- | ---------- | ----------------------------------------------------
------------------------------------------------------------------------------
@ -1041,7 +1266,7 @@ intentionally non-essential:
They may be overwritten by other bytes which must not produce errors or
undesirable side effects when executed as x86 machine code.
The following 32 bytes from block 0 of an Apple Partiton Map (APM) are such
harmless code. They stem from Fedora-LiveCD.iso by Matthew Garret:
harmless code. They stem from Fedora-LiveCD.iso by Matthew Garrett:
45 52 08 00 00 00 90 90 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
They do not depend on any properties of the ISO image or the information
@ -1108,7 +1333,7 @@ Byte Range | Value | Meaning (little endian numbers, LBA unit is 512 byte)
---------- | ---------- | ----------------------------------------------------
12 - 15 | head_size | Header size = 0x5c = 92
24 - 31 | curr_lba | Location of this header block = 0x1
32 - 39 | back_lba | Location of header backup block = 0x144ffe = 1331198
32 - 39 | backup_lba | Location of header backup block = 0x144ffe = 1331198
| | This is 1 KiB before the end of MBR partition 1
| | (but should be 512 bytes).
| | (Potential isohybrid.c bug #1:
@ -1259,6 +1484,9 @@ Start at block 0xa4 = 164 * 512 = 41 * 2048. The VFAT image file.
Last block is 0x0513 = 1299 = 164 + 1135. This end is correct.
(Potential isohybrid.c bug #4:
Wrong character set and incidential bytes in GPT partition name.)
(Potential isohybrid.c bug #5:
The EFI System Partition should have type GUID :
"C12A7328-F81F-11D2-BA4B-00A0C93EC93B")
Next entry at byte 0x02100 = 8448:
@ -1321,12 +1549,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

@ -128,7 +128,7 @@ Name:
Purpose:
Records the IsoHfsplusBlessings blessing of a IsoNode as defined
in libisofs.h. At image load time, this info shall be converted back
in libisofs.h. At image load time, this info may be converted back
into a relation between IsoImage and IsoNode so that it is available for
the HFS+ writer when a new ISO 9660 / HFS+ image gets produced.
@ -152,7 +152,7 @@ Name:
Purpose:
Records the iso_hfsplus_xinfo_data information as defined in libisofs.h.
At image load time, this info shall be converted back into an xinfo
At image load time, this info may be converted back into an xinfo
attachment for iso_hfsplus_xinfo_func so that it is available for
the HFS+ writer when a new ISO 9660 / HFS+ image gets produced.

View File

@ -5,9 +5,9 @@
Arbitrary Attribute Interchange Protocol , system adapter for getting and
setting of ACLs and xattr.
To be included by aaip_0_2.c
To be included by aaip_0_2.c for FreeBSD and NetBSD
Copyright (c) 2009 - 2011 Thomas Schmitt, libburnia project, GPLv2+
Copyright (c) 2009 - 2014 Thomas Schmitt, libburnia project, GPLv2+
*/
@ -32,6 +32,8 @@
#include <sys/extattr.h>
#endif
#include <sys/statvfs.h>
/* <<< Use old ACL adapter code that is unable to deal with extattr */
/* # define Libisofs_old_freebsd_acl_adapteR */
@ -70,6 +72,32 @@ int aaip_local_attr_support(int flag)
}
#ifdef Libisofs_with_freebsd_extattR
static int aaip_extattr_path_supp(char *path, int flag)
{
#ifdef MNT_EXTATTR
int ret;
struct statvfs statvfs_buf;
ret = statvfs(path, &statvfs_buf);
if(ret == -1)
return(1);
return(!!(statvfs_buf.f_flag & MNT_EXTATTR));
#else /* MNT_EXTATTR */
return(1);
#endif /* ! MNT_EXTATTR */
}
#endif /* Libisofs_with_freebsd_extattR */
/* ------------------------------ Getters --------------------------------- */
/* Obtain the ACL of the given file in long text form.
@ -195,8 +223,13 @@ static int aaip_extattr_make_list(char *path, int attrnamespace,
*list_size= extattr_list_file(path, attrnamespace, NULL, (size_t) 0);
else
*list_size= extattr_list_link(path, attrnamespace, NULL, (size_t) 0);
if(*list_size == -1)
if(*list_size == -1) {
if(! aaip_extattr_path_supp(path, 0)) {
*list_size = 0;
return(2);
}
return(0);
}
if(*list_size == 0)
return(2);
*list= calloc(*list_size, 1);

View File

@ -5,7 +5,7 @@
Arbitrary Attribute Interchange Protocol , system adapter for getting and
setting of ACLs and xattr.
To be included by aaip_0_2.c
To be included by aaip_0_2.c for Linux
Copyright (c) 2009 - 2011 Thomas Schmitt, libburnia project, GPLv2+

View File

@ -7,7 +7,7 @@
See libisofs/aaip_0_2.h
http://libburnia-project.org/wiki/AAIP
Copyright (c) 2009 - 2011 Thomas Schmitt, libburnia project, GPLv2+
Copyright (c) 2009 - 2014 Thomas Schmitt, libburnia project, GPLv2+
*/
@ -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;
@ -2181,6 +2181,11 @@ ex:;
#include "aaip-os-freebsd.c"
#else
#ifdef __NetBSD__
#include "aaip-os-freebsd.c"
#else
#ifdef __linux
@ -2198,5 +2203,6 @@ ex:;
#include "aaip-os-dummy.c"
#endif /* ! __linux */
#endif /* ! __NetBSD__ */
#endif /* ! __FreeBSD__ */

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2011 Thomas Schmitt
* Copyright (c) 2009 - 2014 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
@ -96,7 +96,7 @@ int default_create_file(IsoNodeBuilder *builder, IsoImage *image,
static
int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
IsoFileSource *src, IsoNode **node)
IsoFileSource *src, char *in_name, IsoNode **node)
{
int ret;
struct stat info;
@ -122,7 +122,15 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
goto ex;
}
name = iso_file_source_get_name(src);
if (in_name == NULL) {
name = iso_file_source_get_name(src);
} else {
name = strdup(in_name);
if (name == NULL) {
ret = ISO_OUT_OF_MEM; goto ex;
}
}
if (strlen(name) > LIBISOFS_NODE_NAME_MAX)
name[LIBISOFS_NODE_NAME_MAX] = 0;
fs = iso_file_source_get_filesystem(src);

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2014 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
@ -47,6 +48,7 @@ struct Iso_Node_Builder
* Create a new IsoNode from a IsoFileSource. The type of the node to be
* created is determined from the type of the file source. Name,
* permissions and other attributes are taken from source file.
* But name may be overridden by parameter name if it is not NULL.
*
* Note that the src is never unref, so you need to free it.
*
@ -54,7 +56,7 @@ struct Iso_Node_Builder
* 1 on success, < 0 on error
*/
int (*create_node)(IsoNodeBuilder *builder, IsoImage *image,
IsoFileSource *src, IsoNode **node);
IsoFileSource *src, char *name, IsoNode **node);
/**
* Free implementation specific data. Should never be called by user.

View File

@ -21,6 +21,11 @@
#include <fcntl.h>
#include <unistd.h>
/* O_BINARY is needed for Cygwin but undefined elsewhere */
#ifndef O_BINARY
#define O_BINARY 0
#endif
/**
* Private data for File IsoDataSource
*/
@ -65,7 +70,7 @@ int ds_open(IsoDataSource *src)
return ISO_FILE_ALREADY_OPENED;
}
fd = open(data->path, O_RDONLY);
fd = open(data->path, O_RDONLY | O_BINARY);
if (fd == -1) {
return ISO_FILE_ERROR;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2012 Thomas Schmitt
* Copyright (c) 2009 - 2015 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
@ -87,6 +87,12 @@
#define ISO_GPT_ENTRIES_MAX 248
/* How many warnings to issue about writing Joliet names which cannot be
properly represented in UCS-2 and thus had to be defaultet to '_'.
*/
#define ISO_JOLIET_UCS2_WARN_MAX 3
/**
* Holds the options for the image generation.
*/
@ -94,7 +100,7 @@ struct iso_write_opts {
int will_cancel;
int level; /**< ISO level to write at. (ECMA-119, 10) */
int iso_level; /**< ISO level to write at. (ECMA-119, 10) */
/** Which extensions to support. */
unsigned int rockridge :1;
@ -192,6 +198,11 @@ struct iso_write_opts {
*/
unsigned int joliet_long_names :1;
/**
* Use UTF-16BE rather than its subset UCS-2
*/
unsigned int joliet_utf16 :1;
/**
* Write Rock Ridge info as of specification RRIP-1.10 rather than
* RRIP-1.12: signature "RRIP_1991A" rather than "IEEE_1282",
@ -420,6 +431,7 @@ struct iso_write_opts {
* See ecma119_image : System Area related information
*/
char *system_area_data;
int system_area_size;
int system_area_options;
/* User settable PVD time stamps */
@ -456,17 +468,24 @@ struct iso_write_opts {
to HFS+/FAT and IsoFileSrc areas and marked by an MBR partition entry.
*/
char *prep_partition;
int prep_part_flag;
/* Eventual disk file path of an EFI system partition image which shall
be prepended to HFS+/FAT and IsoFileSrc areas and marked by a GPT entry.
*/
char *efi_boot_partition;
int efi_boot_part_flag;
/* Eventual disk file paths of prepared images which shall be appended
after the ISO image and described by partiton table entries in a MBR
*/
char *appended_partitions[ISO_MAX_PARTITIONS];
uint8_t appended_part_types[ISO_MAX_PARTITIONS];
int appended_part_flags[ISO_MAX_PARTITIONS];
/* If 1: With appended partitions: create protective MBR and mark by GPT
*/
int appended_as_gpt;
/* Eventual name of the non-ISO aspect of the image. E.g. SUN ASCII label.
*/
@ -502,70 +521,19 @@ struct ecma119_image
IsoImage *image;
Ecma119Node *root;
int will_cancel :1;
IsoWriteOpts *opts;
unsigned int iso_level :2;
/* extensions */
unsigned int rockridge :1;
unsigned int joliet :1;
/** Whether El Torito data will be produced */
unsigned int eltorito :1;
unsigned int iso1999 :1;
unsigned int hfsplus :1;
unsigned int fat :1;
unsigned int hardlinks:1; /* see iso_write_opts_set_hardlinks() */
unsigned int aaip :1; /* see iso_write_opts_set_aaip() */
/* allways write timestamps in GMT */
unsigned int always_gmt :1;
/* relaxed constraints */
unsigned int allow_dir_id_ext :1;
unsigned int omit_version_numbers :2;
unsigned int allow_deep_paths :1;
unsigned int allow_longer_paths :1;
unsigned int max_37_char_filenames :1;
unsigned int no_force_dots :2;
unsigned int allow_lowercase :1;
unsigned int allow_full_ascii :1;
unsigned int allow_7bit_ascii :1;
unsigned int relaxed_vol_atts : 1;
/** Allow paths on Joliet tree to be larger than 240 bytes */
unsigned int joliet_longer_paths :1;
/** Allow Joliet names up to 103 characters rather than 64 */
unsigned int joliet_long_names :1;
/** Write old fashioned RRIP-1.10 rather than RRIP-1.12 */
unsigned int rrip_version_1_10 :1;
/** Write field PX with file serial number even with RRIP-1.10 */
unsigned int rrip_1_10_px_ino :1;
/* Write AAIP as extension according to SUSP 1.10 rather than SUSP 1.12. */
unsigned int aaip_susp_1_10 :1;
/* Store in ECMA-119, Joliet, ISO 9660:1999 timestamp the mtime of source
bit0= ECMA-119, bit1= Joliet, bit2= ISO 9660:1999.
/* The ECMA-119 directory node where to store Rock Ridge relocated
directories. (Path is in IsoWriteOpts.rr_reloc_dir)
*/
unsigned int dir_rec_mtime :3;
/* The ECMA-119 directory where to store Rock Ridge relocated directories.
*/
char *rr_reloc_dir; /* IsoNode name in root directory */
int rr_reloc_flags;
Ecma119Node *rr_reloc_node; /* Directory node in ecma119_image */
unsigned int md5_session_checksum :1;
unsigned int md5_file_checksums :2;
/*
* Mode replace. If one of these flags is set, the correspodent values are
* replaced with values below.
* replaced with values below. Both get computed from IsoWriteOpts.
*/
unsigned int replace_uid :1;
unsigned int replace_gid :1;
@ -573,30 +541,17 @@ struct ecma119_image
unsigned int replace_dir_mode :1;
unsigned int replace_timestamps :1;
/* Mode replacement values. */
uid_t uid;
gid_t gid;
mode_t file_mode;
mode_t dir_mode;
time_t timestamp;
unsigned int old_empty :1;
unsigned int untranslated_name_len;
/**
* if sort files or not. Sorting is based of the weight of each file
*/
int sort_files;
/* Effective charsets */
char *input_charset;
char *output_charset;
/* See iso_write_opts and iso_write_opts_set_hfsp_serial_number().
* 00...00 means that it shall be generated by libisofs.
*/
uint8_t hfsp_serial_number[8];
unsigned int appendable : 1;
uint32_t ms_block; /**< start block for a ms image */
time_t now; /**< Time at which writing began. */
/** Total size of the output. This only includes the current volume. */
@ -642,6 +597,7 @@ struct ecma119_image
uint32_t joliet_path_table_size;
uint32_t joliet_l_path_table_pos;
uint32_t joliet_m_path_table_pos;
size_t joliet_ucs2_failures;
/*
* HFS+ related information
@ -763,14 +719,6 @@ struct ecma119_image
Use only underneath ecma119_image_new()
and if not NULL*/
/* ??? Is there a reason why we copy lots of items from IsoWriteOpts
rather than taking ownership of the IsoWriteOpts object which
is submitted with ecma119_image_new() ?
*/
char scdbackup_tag_parm[100];
char *scdbackup_tag_written;
/* Buffer for communication between burn_source and writer thread */
IsoRingBuffer *buffer;
@ -779,20 +727,7 @@ struct ecma119_image
int wthread_is_running;
pthread_attr_t th_attr;
/* User settable PVD time stamps */
time_t vol_creation_time;
time_t vol_modification_time;
time_t vol_expiration_time;
time_t vol_effective_time;
/* To eventually override vol_creation_time and vol_modification_time
* by unconverted string with timezone 0
*/
char vol_uuid[17];
/* The number of unclaimed 2K blocks before
start of partition 1 as of the MBR in system area. */
uint32_t partition_offset;
/* Partition table parameter: 1 to 63, 0= disabled/default */
/* Effective partition table parameter: 1 to 63, 0= disabled/default */
int partition_secs_per_head;
/* 1 to 255, 0= disabled/default */
int partition_heads_per_cyl;
@ -813,26 +748,22 @@ struct ecma119_image
uint32_t j_part_l_path_table_pos;
uint32_t j_part_m_path_table_pos;
#ifdef Libisofs_with_libjtE
struct libjte_env *libjte_handle;
#endif /* Libisofs_with_libjtE */
uint32_t tail_blocks;
/* Memorized ELF parameters from MIPS Little Endian boot file */
uint32_t mipsel_e_entry;
uint32_t mipsel_p_offset;
uint32_t mipsel_p_vaddr;
uint32_t mipsel_p_filesz;
char *appended_partitions[ISO_MAX_PARTITIONS];
uint8_t appended_part_types[ISO_MAX_PARTITIONS];
/* A data file of which the position and size shall be written after
a SUN Disk Label.
*/
IsoFileSrc *sparc_core_src;
/* Counted in blocks of 2048 */
uint32_t appended_part_prepad[ISO_MAX_PARTITIONS];
uint32_t appended_part_start[ISO_MAX_PARTITIONS];
uint32_t appended_part_size[ISO_MAX_PARTITIONS];
char ascii_disc_label[ISO_DISC_LABEL_SIZE];
int have_appended_partitions;
/* See IsoImage and libisofs.h */
IsoNode *hfsplus_blessed[ISO_HFSPLUS_BLESS_MAX];
@ -841,17 +772,12 @@ struct ecma119_image
Only change a block size if it is 0. Set only to 512 or 2048.
If it stays 0 then it will become 512 or 2048 in time.
*/
/* Blocksize of Apple Partition Map
May be defined to 512 or 2048 before writer thread starts.
*/
int apm_block_size;
/* Allocation block size of HFS+
May be defined to 512 or 2048 before hfsplus_writer_create().
*/
int hfsp_block_size;
int hfsp_cat_node_size; /* 2 * apm_block_size */
int hfsp_iso_block_fac; /* 2048 / apm_block_size */
int hfsp_cat_node_size; /* 2 * hfsp_block_size */
int hfsp_iso_block_fac; /* 2048 / hfsp_block_size */
/* Apple Partition Map description. To be composed during IsoImageWriter
method ->compute_data_blocks() by calling iso_register_apm_entry().
@ -872,7 +798,12 @@ struct ecma119_image
struct iso_mbr_partition_request *mbr_req[ISO_MBR_ENTRIES_MAX];
int mbr_req_count;
char *prep_partition;
/* Number of bytes which have to be added after the cylinder aligned end
of the overall ISO partition because clinder size is not a multiple
of 2048
*/
int post_iso_part_pad;
uint32_t prep_part_size;
/* GPT description. To be composed during IsoImageWriter
@ -885,13 +816,17 @@ struct ecma119_image
/* bit0= GPT partitions may overlap */
int gpt_req_flags;
char *efi_boot_partition;
/* Whether the eventual backup GPT is not part of the ISO filesystem */
int gpt_backup_outside;
uint32_t efi_boot_part_size;
IsoFileSrc *efi_boot_part_filesrc; /* Just a pointer. Do not free. */
/* Messages from gpt_tail_writer_compute_data_blocks() to
iso_write_system_area().
*/
uint8_t gpt_disk_guid[16];
int gpt_disk_guid_set;
/* Start of GPT entries in System Area, block size 512 */
uint32_t gpt_part_start;
/* The ISO block number after the backup GPT header , block size 2048 */
@ -904,6 +839,7 @@ struct ecma119_image
write_data() methods of the writers.
*/
uint8_t sys_area_as_written[16 * BLOCK_SIZE];
int sys_area_already_written;
/* Size of the filesrc_writer area (data file content).
This is available before any IsoImageWriter.compute_data_blocks()
@ -1049,4 +985,7 @@ void ecma119_set_voldescr_times(IsoImageWriter *writer,
int iso_write_partition_file(Ecma119Image *target, char *path,
uint32_t prepad, uint32_t blocks, int flag);
void issue_ucs2_warning_summary(size_t failures);
#endif /*LIBISO_ECMA119_H_*/

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2012 Thomas Schmitt
* Copyright (c) 2009 - 2014 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
@ -29,52 +29,57 @@
#include <string.h>
#include <stdio.h>
static
int get_iso_name(Ecma119Image *img, IsoNode *iso, char **name)
/* @param flag bit0= Do not issue error messages
*/
int iso_get_ecma119_name(IsoWriteOpts *opts, char *input_charset, int imgid,
char *node_name, enum IsoNodeType node_type,
char **name, int flag)
{
int ret, relaxed, free_ascii_name= 0, force_dots = 0;
int ret, relaxed, free_ascii_name = 0, force_dots = 0;
char *ascii_name;
char *isoname= NULL;
char *isoname = NULL;
if (iso->name == NULL) {
if (node_name == NULL) {
/* it is not necessarily an error, it can be the root */
return ISO_SUCCESS;
}
if (img->untranslated_name_len > 0) {
ascii_name = iso->name;
if (opts->untranslated_name_len > 0) {
ascii_name = node_name;
ret = 1;
} else {
ret = str2ascii(img->input_charset, iso->name, &ascii_name);
ret = str2ascii(input_charset, node_name, &ascii_name);
free_ascii_name = 1;
}
if (ret < 0) {
iso_msg_submit(img->image->id, ret, 0,
"Cannot convert name '%s' to ASCII", iso->name);
if (!(flag & 512))
iso_msg_submit(imgid, ret, 0,
"Cannot convert name '%s' to ASCII", node_name);
return ret;
}
if (img->allow_full_ascii) {
if (opts->allow_full_ascii) {
relaxed = 2;
} else {
relaxed = (int)img->allow_lowercase;
relaxed = (int)opts->allow_lowercase;
}
if (img->allow_7bit_ascii)
if (opts->allow_7bit_ascii)
relaxed |= 4;
if (iso->type == LIBISO_DIR && !(img->allow_dir_id_ext)) {
if (img->untranslated_name_len > 0) {
if (strlen(ascii_name) > img->untranslated_name_len) {
if (node_type == LIBISO_DIR && !(opts->allow_dir_id_ext)) {
if (opts->untranslated_name_len > 0) {
if (strlen(ascii_name) > opts->untranslated_name_len) {
needs_transl:;
iso_msg_submit(img->image->id, ISO_NAME_NEEDS_TRANSL, 0,
if (!(flag & 512))
iso_msg_submit(imgid, ISO_NAME_NEEDS_TRANSL, 0,
"File name too long (%d > %d) for untranslated recording: '%s'",
strlen(ascii_name), img->untranslated_name_len,
ascii_name);
strlen(ascii_name), opts->untranslated_name_len,
ascii_name);
return ISO_NAME_NEEDS_TRANSL;
}
isoname = strdup(ascii_name);
} else if (img->max_37_char_filenames) {
} else if (opts->max_37_char_filenames) {
isoname = iso_r_dirid(ascii_name, 37, relaxed);
} else if (img->iso_level == 1) {
} else if (opts->iso_level == 1) {
#ifdef Libisofs_old_ecma119_nameS
@ -99,14 +104,15 @@ needs_transl:;
}
}
} else {
force_dots = !((img->no_force_dots & 1) || iso->type == LIBISO_DIR);
if (img->untranslated_name_len > 0) {
if (strlen(ascii_name) > img->untranslated_name_len)
force_dots = !((opts->no_force_dots & 1) ||
node_type == LIBISO_DIR);
if (opts->untranslated_name_len > 0) {
if (strlen(ascii_name) > opts->untranslated_name_len)
goto needs_transl;
isoname = strdup(ascii_name);
} else if (img->max_37_char_filenames) {
} else if (opts->max_37_char_filenames) {
isoname = iso_r_fileid(ascii_name, 36, relaxed, force_dots);
} else if (img->iso_level == 1) {
} else if (opts->iso_level == 1) {
#ifdef Libisofs_old_ecma119_nameS
@ -151,11 +157,21 @@ needs_transl:;
}
}
static
int get_iso_name(Ecma119Image *img, IsoNode *iso, char **name)
{
int ret;
ret = iso_get_ecma119_name(img->opts, img->input_charset, img->image->id,
iso->name, iso->type, name, 0);
return ret;
}
int ecma119_is_dedicated_reloc_dir(Ecma119Image *img, Ecma119Node *node)
{
if (img->rr_reloc_node == node &&
node != img->root && node != img->partition_root &&
(img->rr_reloc_flags & 2))
(img->opts->rr_reloc_flags & 2))
return 1;
return 0;
}
@ -185,23 +201,26 @@ static
int create_dir(Ecma119Image *img, IsoDir *iso, Ecma119Node **node)
{
int ret;
Ecma119Node **children;
Ecma119Node **children = NULL;
struct ecma119_dir_info *dir_info;
children = calloc(1, sizeof(void*) * iso->nchildren);
if (children == NULL) {
return ISO_OUT_OF_MEM;
if (iso->nchildren > 0) {
children = calloc(1, sizeof(void*) * iso->nchildren);
if (children == NULL)
return ISO_OUT_OF_MEM;
}
dir_info = calloc(1, sizeof(struct ecma119_dir_info));
if (dir_info == NULL) {
free(children);
if (children != NULL)
free(children);
return ISO_OUT_OF_MEM;
}
ret = create_ecma119_node(img, (IsoNode*)iso, node);
if (ret < 0) {
free(children);
if (children != NULL)
free(children);
free(dir_info);
return ret;
}
@ -220,7 +239,7 @@ int create_file_src(Ecma119Image *img, IsoFile *iso, IsoFileSrc **src)
off_t size;
size = iso_stream_get_size(iso->stream);
if (size > (off_t)MAX_ISO_FILE_SECTION_SIZE && img->iso_level != 3) {
if (size > (off_t)MAX_ISO_FILE_SECTION_SIZE && img->opts->iso_level != 3) {
char *ipath = iso_tree_get_node_path(ISO_NODE(iso));
ret = iso_msg_submit(img->image->id, ISO_FILE_TOO_BIG, 0,
"File \"%s\" can't be added to image because "
@ -337,7 +356,8 @@ void ecma119_node_free(Ecma119Node *node)
for (i = 0; i < node->info.dir->nchildren; i++) {
ecma119_node_free(node->info.dir->children[i]);
}
free(node->info.dir->children);
if (node->info.dir->children != NULL)
free(node->info.dir->children);
free(node->info.dir);
}
free(node->iso_name);
@ -361,6 +381,7 @@ int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree,
int max_path;
char *iso_name= NULL, *ipath = NULL;
IsoFileSrc *src = NULL;
IsoWriteOpts *opts = image->opts;
if (image == NULL || iso == NULL || tree == NULL) {
return ISO_NULL_POINTER;
@ -385,16 +406,16 @@ int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree,
goto ex;
}
max_path = pathlen + 1 + (iso_name ? strlen(iso_name) : 0);
if (!image->rockridge) {
if (!opts->rockridge) {
if ((iso->type == LIBISO_DIR && depth > 8) &&
!image->allow_deep_paths) {
ipath = iso_tree_get_node_path(iso);
!opts->allow_deep_paths) {
ipath = iso_tree_get_node_path(iso);
ret = iso_msg_submit(image->image->id, ISO_FILE_IMGPATH_WRONG,
0, "File \"%s\" can't be added, "
"because directory depth "
"is greater than 8.", ipath);
goto ex;
} else if (max_path > 255 && !image->allow_longer_paths) {
} else if (max_path > 255 && !opts->allow_longer_paths) {
ipath = iso_tree_get_node_path(iso);
ret = iso_msg_submit(image->image->id, ISO_FILE_IMGPATH_WRONG,
0, "File \"%s\" can't be added, "
@ -418,7 +439,7 @@ int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree,
ret = 0; /* Hidden means non-existing */
goto ex;
}
if (image->rockridge) {
if (opts->rockridge) {
ret = create_symlink(image, (IsoSymlink*)iso, &node);
} else {
/* symlinks are only supported when RR is enabled */
@ -434,7 +455,7 @@ int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree,
ret = 0; /* Hidden means non-existing */
goto ex;
}
if (image->rockridge) {
if (opts->rockridge) {
ret = create_special(image, (IsoSpecial*)iso, &node);
} else {
/* special files are only supported when RR is enabled */
@ -472,9 +493,9 @@ int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree,
image->rr_reloc_node = node;
} else if (depth == 2) {
/* Directories in root may be used as relocation dir */
if (image->rr_reloc_dir != NULL)
if (image->rr_reloc_dir[0] != 0 &&
strcmp(iso->name, image->rr_reloc_dir) == 0)
if (opts->rr_reloc_dir != NULL)
if (opts->rr_reloc_dir[0] != 0 &&
strcmp(iso->name, opts->rr_reloc_dir) == 0)
image->rr_reloc_node = node;
}
}
@ -547,6 +568,8 @@ void sort_tree(Ecma119Node *root)
{
size_t i;
if (root->info.dir->children == NULL)
return;
qsort(root->info.dir->children, root->info.dir->nchildren, sizeof(void*),
cmp_node_name);
for (i = 0; i < root->info.dir->nchildren; i++) {
@ -575,6 +598,9 @@ int mangle_single_dir(Ecma119Image *img, Ecma119Node *dir, int max_file_len,
nchildren = dir->info.dir->nchildren;
children = dir->info.dir->children;
if (nchildren <= 0)
return ISO_SUCCESS; /* nothing to do */
/* a hash table will temporary hold the names, for fast searching */
ret = iso_htable_create((nchildren * 100) / 80, iso_str_hash,
(compare_function_t)strcmp, &table);
@ -606,7 +632,7 @@ int mangle_single_dir(Ecma119Image *img, Ecma119Node *dir, int max_file_len,
continue;
}
if (img->untranslated_name_len) {
if (img->opts->untranslated_name_len) {
/* This should not happen because no two IsoNode names should be
identical and only unaltered IsoNode names should be seen here.
Thus the Ema119Node names should be unique.
@ -635,7 +661,8 @@ int mangle_single_dir(Ecma119Image *img, Ecma119Node *dir, int max_file_len,
/* compute name and extension */
dot = strrchr(full_name, '.');
if (dot != NULL &&
(children[i]->type != ECMA119_DIR || img->allow_dir_id_ext)) {
(children[i]->type != ECMA119_DIR ||
img->opts->allow_dir_id_ext)) {
/*
* File (normally not dir) with extension
@ -801,11 +828,11 @@ int mangle_tree(Ecma119Image *img, Ecma119Node *dir, int recurse)
int max_file, max_dir;
Ecma119Node *root;
if (img->untranslated_name_len > 0) {
max_file = max_dir = img->untranslated_name_len;
} else if (img->max_37_char_filenames) {
if (img->opts->untranslated_name_len > 0) {
max_file = max_dir = img->opts->untranslated_name_len;
} else if (img->opts->max_37_char_filenames) {
max_file = max_dir = 37;
} else if (img->iso_level == 1) {
} else if (img->opts->iso_level == 1) {
max_file = 12; /* 8 + 3 + 1 */
max_dir = 8;
} else {
@ -973,9 +1000,9 @@ int reorder_tree(Ecma119Image *img, Ecma119Node *dir,
/* dir is now the relocated Ecma119Node */
pathlen = 37 + 1; /* The dir name might get longer by mangling */
level = 2;
if (img->rr_reloc_dir != NULL) {
if (img->opts->rr_reloc_dir != NULL) {
pathlen += strlen(img->rr_reloc_node->iso_name) + 1;
if(img->rr_reloc_dir[0] != 0)
if(img->opts->rr_reloc_dir[0] != 0)
level = 3;
}
}
@ -1095,6 +1122,11 @@ int family_set_ino(Ecma119Image *img, Ecma119Node **nodes, size_t family_start,
*/
if (img_ino == prev_ino)
img_ino = 0;
/* Accept only if it is within the 32 bit range. */
if (((uint64_t) img_ino) > 0xffffffff)
img_ino = 0;
}
if (img_ino == 0) {
img_ino = img_give_ino_number(img->image, 0);
@ -1128,7 +1160,7 @@ int match_hardlinks(Ecma119Image *img, Ecma119Node *dir, int flag)
goto ex;
/* Sort according to id tuples, IsoFileSrc identity, properties, xattr. */
if (img->hardlinks)
if (img->opts->hardlinks)
qsort(nodes, node_count, sizeof(Ecma119Node *), ecma119_node_cmp_hard);
else
qsort(nodes, node_count, sizeof(Ecma119Node *),
@ -1198,7 +1230,7 @@ int ecma119_tree_create(Ecma119Image *img)
return ret;
}
if (img->rockridge && !img->allow_deep_paths) {
if (img->opts->rockridge && !img->opts->allow_deep_paths) {
/* Relocate deep directories, acording to RRIP, 4.1.5 */
ret = reorder_tree(img, root, 1, 0);

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* 2012 Thomas Schmitt
* 2012 - 2014 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
@ -64,9 +64,7 @@ struct ecma119_node
IsoNode *node; /*< reference to the iso node */
/* >>> ts A90501 : Shouldn't this be uint32_t
as this is what PX will take ? */
ino_t ino;
uint32_t ino;
nlink_t nlink;
@ -103,5 +101,13 @@ Ecma119Node *ecma119_search_iso_node(Ecma119Image *img, IsoNode *node);
*/
int ecma119_is_dedicated_reloc_dir(Ecma119Image *img, Ecma119Node *node);
/**
* Determines the ECMA-119 name from node name.
* @param flag bit0= Do not issue error messages
*/
int iso_get_ecma119_name(IsoWriteOpts *opts, char *input_charset, int imgid,
char *node_name, enum IsoNodeType node_type,
char **name, int flag);
#endif /*LIBISO_ECMA119_TREE_H_*/

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2010 Thomas Schmitt
* Copyright (c) 2010 - 2014 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
@ -82,15 +82,16 @@ void el_torito_set_load_seg(ElToritoBootImage *bootimg, short segment)
{
if (bootimg->type != 0)
return;
bootimg->load_seg = segment;
if (segment < 0)
bootimg->load_seg = 0x1000 + segment;
else
bootimg->load_seg = segment;
}
/* API */
int el_torito_get_load_seg(ElToritoBootImage *bootimg)
{
if (bootimg->load_seg < 0)
return 0xffff - bootimg->load_seg;
return bootimg->load_seg;
return (int) bootimg->load_seg;
}
/**
@ -102,15 +103,16 @@ void el_torito_set_load_size(ElToritoBootImage *bootimg, short sectors)
{
if (bootimg->type != 0)
return;
bootimg->load_size = sectors;
if (sectors < 0)
bootimg->load_size = 0x10000 + sectors;
else
bootimg->load_size = sectors;
}
/* API */
int el_torito_get_load_size(ElToritoBootImage *bootimg)
{
if (bootimg->load_size < 0)
return 0xffff - bootimg->load_size;
return bootimg->load_size;
return (int) bootimg->load_size;
}
/**
@ -160,7 +162,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 +205,16 @@ 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);
bootimg->seems_boot_info_table = !!(options & 1);
bootimg->seems_grub2_boot_info = !!(options & (1 << 9));
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 +316,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 +328,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 +343,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;
@ -431,6 +444,8 @@ int create_image(IsoImage *image, const char *image_path,
iso_node_ref(imgfile); /* get our ref */
boot->bootable = 1;
boot->seems_boot_info_table = 0;
boot->seems_grub2_boot_info = 0;
boot->seems_isohybrid_capable = 0;
boot->isolinux_options = 0;
boot->type = boot_media_type;
boot->partition_type = partition_type;
@ -455,6 +470,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 +523,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;
}
@ -523,7 +539,9 @@ int iso_image_set_boot_image(IsoImage *image, const char *image_path,
for (i = 1; i < Libisofs_max_boot_imageS; i++)
catalog->bootimages[i] = NULL;
catalog->node = cat_node;
catalog->sort_weight = 1000; /* slightly high */
catalog->sort_weight = 1000000000; /* very high */
if (!(boot_node->explicit_weight || boot_node->from_old_session))
boot_node->sort_weight = 2;
iso_node_ref((IsoNode*)cat_node);
image->bootcat = catalog;
@ -694,14 +712,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->from_old_session))
boot_node->sort_weight = 2;
catalog->bootimages[catalog->num_bootimages] = boot_img;
catalog->num_bootimages++;
if (boot != NULL)
@ -793,7 +814,8 @@ write_section_header(uint8_t *buf, Ecma119Image *t, int idx, int num_entries)
(struct el_torito_section_header *) buf;
/* 0x90 = more section headers follow , 0x91 = final section */
e->header_indicator[0] = 0x90 + (idx == t->catalog->num_bootimages - 1);
e->header_indicator[0] =
0x90 + (idx == t->catalog->num_bootimages - num_entries);
e->platform_id[0] = t->catalog->bootimages[idx]->platform_id;
e->num_entries[0] = num_entries & 0xff;
e->num_entries[1] = (num_entries >> 8) & 0xff;;
@ -936,7 +958,8 @@ int catalog_is_repeatable(IsoStream *stream)
/**
* fs_id will be the id reserved for El-Torito
* dev_id will be 0 for catalog, 1 for boot image (if needed)
* we leave ino_id for future use when we support multiple boot images
* ino_id 0 is supposed to be unique. At write time it will get assigned
* an automatic file serial number in the ISO, if needed.
*/
static
void catalog_get_id(IsoStream *stream, unsigned int *fs_id, dev_t *dev_id,
@ -1096,7 +1119,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
@ -1111,12 +1134,33 @@ int patch_boot_info_table(uint8_t *buf, Ecma119Image *t,
return iso_msg_submit(t->image->id, ISO_ISOLINUX_CANT_PATCH, 0,
"Isolinux image too small. We won't patch it.");
}
ret = make_boot_info_table(buf, t->ms_block + (uint32_t) 16,
ret = make_boot_info_table(buf, t->opts->ms_block + (uint32_t) 16,
t->bootsrc[idx]->sections[0].block,
(uint32_t) imgsize);
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 +1174,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);
@ -1150,13 +1194,27 @@ int iso_patch_eltoritos(Ecma119Image *t)
ret = iso_stream_read(original, buf, size);
iso_stream_close(original);
if (ret != (int) size) {
if (ret >= 0)
iso_msg_submit(t->image->id, ISO_FILE_READ_ERROR, 0,
"Cannot read all bytes from El Torito boot image for boot info table");
return (ret < 0) ? ret : (int) ISO_FILE_READ_ERROR;
}
/* 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
@ -1255,8 +1313,8 @@ int eltorito_writer_create(Ecma119Image *target)
}
}
if (target->efi_boot_partition != NULL)
if (strcmp(target->efi_boot_partition, "--efi-boot-image") == 0)
if (target->opts->efi_boot_partition != NULL)
if (strcmp(target->opts->efi_boot_partition, "--efi-boot-image") == 0)
outsource_efi = 1;
for (idx = 0; idx < target->catalog->num_bootimages; idx++) {
bootimg = target->catalog->bootimages[idx]->image;
@ -1290,8 +1348,8 @@ int eltorito_writer_create(Ecma119Image *target)
if (outsource_efi) {
/* Disable EFI Boot partition and complain */
free(target->efi_boot_partition);
target->efi_boot_partition = NULL;
free(target->opts->efi_boot_partition);
target->opts->efi_boot_partition = NULL;
iso_msg_submit(target->image->id, ISO_BOOT_NO_EFI_ELTO, 0,
"No newly added El Torito EFI boot image found for exposure as GPT partition");
return ISO_BOOT_NO_EFI_ELTO;

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2010 Thomas Schmitt
* Copyright (c) 2010 - 2014 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
@ -58,6 +58,11 @@ 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;
/**
* Whether the boot image seems to be capable of isohybrid
*/
unsigned int seems_isohybrid_capable:1;
/**
* isolinux options
* bit 0 -> whether to patch image
@ -73,8 +78,8 @@ struct el_torito_boot_image {
unsigned int isolinux_options;
unsigned char type; /**< The type of image */
unsigned char partition_type; /**< type of partition for HD-emul images */
short load_seg; /**< Load segment for the initial boot image. */
short load_size; /**< Number of sectors to load. */
uint16_t load_seg; /**< Load segment for the initial boot image. */
uint16_t load_size; /**< Number of sectors to load. */
/* Byte 1 of Validation Entry or Section Header Entry:
0= 80x86, 1= PowerPC, 2= Mac, 0xef= EFI */
@ -155,4 +160,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

@ -88,8 +88,8 @@ int iso_file_src_create(Ecma119Image *img, IsoFile *file, IsoFileSrc **src)
}
/* fill key and other atts */
fsrc->no_write = (file->from_old_session && img->appendable);
if (file->from_old_session && img->appendable) {
fsrc->no_write = (file->from_old_session && img->opts->appendable);
if (file->from_old_session && img->opts->appendable) {
/*
* On multisession discs we keep file sections from old image.
*/
@ -127,7 +127,8 @@ 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 && !img->will_cancel) {
if (ret == 0 && (*src)->checksum_index > 0 &&
!img->opts->will_cancel) {
/* Duplicate file source was mapped to previously registered source
*/
cret = iso_file_set_isofscx(file, (*src)->checksum_index, 0);
@ -140,8 +141,8 @@ int iso_file_src_create(Ecma119Image *img, IsoFile *file, IsoFileSrc **src)
}
iso_stream_ref(fsrc->stream);
if ((img->md5_file_checksums & 1) &&
file->from_old_session && img->appendable) {
if ((img->opts->md5_file_checksums & 1) &&
file->from_old_session && img->opts->appendable) {
ret = iso_node_get_xinfo((IsoNode *) file, checksum_md5_xinfo_func,
&xipt);
if (ret <= 0)
@ -152,13 +153,14 @@ int iso_file_src_create(Ecma119Image *img, IsoFile *file, IsoFileSrc **src)
no_md5 = 1;
}
if ((img->md5_file_checksums & 1) && !(no_md5 || img->will_cancel)) {
if ((img->opts->md5_file_checksums & 1) &&
!(no_md5 || img->opts->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)
@ -244,11 +246,11 @@ int filesrc_writer_pre_compute(IsoImageWriter *writer)
/* Normally reserve a single zeroed block for all files which have
no block address: symbolic links, device files, empty data files.
*/
if (! t->old_empty)
if (! t->opts->old_empty)
t->filesrc_blocks++;
/* on appendable images, ms files shouldn't be included */
if (t->appendable) {
if (t->opts->appendable) {
inc_item = shall_be_written;
} else {
inc_item = NULL;
@ -261,7 +263,7 @@ int filesrc_writer_pre_compute(IsoImageWriter *writer)
}
/* sort files by weight, if needed */
if (t->sort_files) {
if (t->opts->sort_files) {
qsort(filelist, size, sizeof(void*), cmp_by_weight);
}
@ -436,7 +438,7 @@ int iso_filesrc_write_data(Ecma119Image *t, IsoFileSrc *file,
file_size = iso_file_src_get_size(file);
nblocks = DIV_UP(file_size, BLOCK_SIZE);
pre_md5_valid = 0;
if (file->checksum_index > 0 && (t->md5_file_checksums & 2)) {
if (file->checksum_index > 0 && (t->opts->md5_file_checksums & 2)) {
/* Obtain an MD5 of content by a first read pass */
pre_md5_valid = filesrc_make_md5(t, file, pre_md5, 0);
}
@ -494,11 +496,11 @@ int iso_filesrc_write_data(Ecma119Image *t, IsoFileSrc *file,
/* >>> HFS: need to align to allocation block size */;
#ifdef Libisofs_with_libjtE
if (t->libjte_handle != NULL) {
res = libjte_begin_data_file(t->libjte_handle, name,
if (t->opts->libjte_handle != NULL) {
res = libjte_begin_data_file(t->opts->libjte_handle, name,
BLOCK_SIZE, file_size);
if (res <= 0) {
res = iso_libjte_forward_msgs(t->libjte_handle, t->image->id,
res = iso_libjte_forward_msgs(t->opts->libjte_handle, t->image->id,
ISO_LIBJTE_FILE_FAILED, 0);
if (res < 0) {
filesrc_close(file);
@ -593,7 +595,7 @@ int iso_filesrc_write_data(Ecma119Image *t, IsoFileSrc *file,
res = iso_md5_end(&ctx, md5);
if (res <= 0)
file->checksum_index = 0;
if ((t->md5_file_checksums & 2) && pre_md5_valid > 0 &&
if ((t->opts->md5_file_checksums & 2) && pre_md5_valid > 0 &&
!was_error) {
if (! iso_md5_match(md5, pre_md5)) {
/* Issue MISHAP event */
@ -619,8 +621,8 @@ ex:;
#ifdef Libisofs_with_libjtE
if (jte_begun) {
res = libjte_end_data_file(t->libjte_handle);
iso_libjte_forward_msgs(t->libjte_handle, t->image->id,
res = libjte_end_data_file(t->opts->libjte_handle);
iso_libjte_forward_msgs(t->opts->libjte_handle, t->image->id,
ISO_LIBJTE_END_FAILED, 0);
if (res <= 0 && ret >= 0)
ret = ISO_LIBJTE_FILE_FAILED;
@ -658,7 +660,7 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
files which have no block address:
symbolic links, device files, empty data files.
*/
if (! t->old_empty) {
if (! t->opts->old_empty) {
ret = iso_write(t, buffer, BLOCK_SIZE);
if (ret < 0)
goto ex;

File diff suppressed because it is too large Load Diff

View File

@ -30,6 +30,11 @@
#include <libgen.h>
#include <string.h>
/* O_BINARY is needed for Cygwin but undefined elsewhere */
#ifndef O_BINARY
#define O_BINARY 0
#endif
static
int iso_file_source_new_lfs(IsoFileSource *parent, const char *name,
IsoFileSource **src);
@ -222,7 +227,7 @@ int lfs_open(IsoFileSource *src)
data->info.dir = opendir(path);
data->openned = data->info.dir ? 2 : 0;
} else {
data->info.fd = open(path, O_RDONLY);
data->info.fd = open(path, O_RDONLY | O_BINARY);
data->openned = data->info.fd != -1 ? 1 : 0;
}
free(path);
@ -282,6 +287,9 @@ static
int lfs_read(IsoFileSource *src, void *buf, size_t count)
{
_LocalFsFileSource *data;
size_t to_read, done = 0;
int ret;
uint8_t *buf8;
if (src == NULL || buf == NULL) {
return ISO_NULL_POINTER;
@ -293,28 +301,28 @@ int lfs_read(IsoFileSource *src, void *buf, size_t count)
data = src->data;
switch (data->openned) {
case 1: /* not dir */
{
int ret;
ret = read(data->info.fd, buf, count);
buf8 = (uint8_t *) buf; /* for pointer arithmetic */
for (to_read = count; to_read > 0; to_read = count - done) {
if (to_read > 1024 * 1024)
to_read = 1024 * 1024;
ret = read(data->info.fd, buf8 + done, to_read);
if (ret < 0) {
/* error on read */
switch (errno) {
case EINTR:
ret = ISO_INTERRUPTED;
break;
return ISO_INTERRUPTED;
case EFAULT:
ret = ISO_OUT_OF_MEM;
break;
return ISO_OUT_OF_MEM;
case EIO:
ret = ISO_FILE_READ_ERROR;
break;
default:
ret = ISO_FILE_ERROR;
break;
return ISO_FILE_READ_ERROR;
}
return ISO_FILE_ERROR;
}
return ret;
if (ret == 0) /* EOF */
break;
done += ret;
}
return done;
case 2: /* directory */
return ISO_FILE_IS_DIR;
default:

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2011 Thomas Schmitt
* Copyright (c) 2009 - 2015 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
@ -34,9 +34,13 @@ int iso_local_filesystem_new(IsoFilesystem **fs);
/* Rank two IsoFileSource of ifs_class by their eventual old image LBAs.
Other IsoFileSource classes will be ranked only roughly.
* @param cmp_ret will return the reply value -1, 0, or 1.
* @return 1= *cmp_ret is a valid reply
* 0= not both streams are of ifs_class,
* *cmp_ret is only a rough estimation.
*/
int iso_ifs_sections_cmp(IsoFileSource *s1, IsoFileSource *s2, int flag);
int iso_ifs_sections_cmp(IsoFileSource *s1, IsoFileSource *s2, int *cmp_ret,
int flag);
/* Create an independent copy of an ifs_class IsoFileSource.

View File

@ -115,8 +115,8 @@ uint8_t get_class (uint16_t v)
return hfsplus_class_pages[high][low];
}
static
int set_hfsplus_name(Ecma119Image *t, char *name, HFSPlusNode *node)
int iso_get_hfsplus_name(char *input_charset, int imgid, char *name,
uint16_t **result, uint32_t *result_len, uint16_t **cmp_name)
{
int ret;
uint16_t *ucs_name, *iptr, *optr;
@ -128,19 +128,19 @@ int set_hfsplus_name(Ecma119Image *t, char *name, HFSPlusNode *node)
return ISO_SUCCESS;
}
ret = str2ucs(t->input_charset, name, &ucs_name);
ret = str2utf16be(input_charset, name, &ucs_name);
if (ret < 0) {
iso_msg_debug(t->image->id, "Can't convert %s", name);
iso_msg_debug(imgid, "Cannot convert '%s'", name);
return ret;
}
curlen = ucslen (ucs_name);
node->name = calloc ((curlen * HFSPLUS_MAX_DECOMPOSE_LEN + 1),
sizeof (node->name[0]));
if (!node->name)
return ISO_OUT_OF_MEM;
*result = calloc ((curlen * HFSPLUS_MAX_DECOMPOSE_LEN + 1),
sizeof (uint16_t));
if (*result == NULL)
return ISO_OUT_OF_MEM;
for (iptr = ucs_name, optr = node->name; *iptr; iptr++)
for (iptr = ucs_name, optr = *result; *iptr; iptr++)
{
const uint16_t *dptr;
uint16_t val = iso_ntohs (*iptr);
@ -189,7 +189,7 @@ int set_hfsplus_name(Ecma119Image *t, char *name, HFSPlusNode *node)
if (!ucs_name[0])
break;
last_class = get_class (ucs_name[0]);
for (optr = node->name + 1; *optr; optr++)
for (optr = *result + 1; *optr; optr++)
{
uint8_t new_class = get_class (*optr);
@ -207,11 +207,11 @@ int set_hfsplus_name(Ecma119Image *t, char *name, HFSPlusNode *node)
}
while (done);
node->cmp_name = calloc ((ucslen (node->name) + 1), sizeof (node->cmp_name[0]));
if (!node->cmp_name)
*cmp_name = calloc ((ucslen (*result) + 1), sizeof (uint16_t));
if (*cmp_name == NULL)
return ISO_OUT_OF_MEM;
for (iptr = node->name, optr = node->cmp_name; *iptr; iptr++)
for (iptr = *result, optr = *cmp_name; *iptr; iptr++)
{
*optr = iso_hfsplus_cichar(*iptr);
if (*optr != 0)
@ -221,10 +221,19 @@ int set_hfsplus_name(Ecma119Image *t, char *name, HFSPlusNode *node)
free (ucs_name);
node->strlen = ucslen (node->name);
*result_len = ucslen (*result);
return ISO_SUCCESS;
}
static
int set_hfsplus_name(Ecma119Image *t, char *name, HFSPlusNode *node)
{
int ret;
ret = iso_get_hfsplus_name(t->input_charset, t->image->id, name,
&(node->name), &(node->strlen), &(node->cmp_name));
return ret;
}
/* >>> ts B20617
This should be HFSPlusNode rather than IsoNode in order to have access
@ -429,7 +438,7 @@ int hfsplus_tail_writer_compute_data_blocks(IsoImageWriter *writer)
}
t = writer->target;
block_size = t->hfsp_block_size;
block_size = t->opts->hfsp_block_size;
block_fac = t->hfsp_iso_block_fac;
#ifdef Libisofs_ts_debuG
@ -466,7 +475,8 @@ int hfsplus_tail_writer_compute_data_blocks(IsoImageWriter *writer)
t->hfsp_total_blocks = hfsp_curblock - t->hfsp_part_start;
return iso_quick_apm_entry(t, t->hfsp_part_start / block_fac,
return iso_quick_apm_entry(t->apm_req, &(t->apm_req_count),
t->hfsp_part_start / block_fac,
t->hfsp_total_blocks / block_fac +
!!(t->hfsp_total_blocks % block_fac),
"HFSPLUS_Hybrid", "Apple_HFS");
@ -477,17 +487,16 @@ 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;
}
t = writer->target;
block_size = t->hfsp_block_size;
block_size = t->opts->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 +509,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 +518,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)
{
@ -584,7 +592,7 @@ write_sb (Ecma119Image *t)
iso_msg_debug(t->image->id, "Write HFS+ superblock");
block_size = t->hfsp_block_size;
block_size = t->opts->hfsp_block_size;
memset (buffer, 0, sizeof (buffer));
ret = iso_write(t, buffer, 1024);
@ -644,7 +652,7 @@ write_sb (Ecma119Image *t)
}
memcpy (&sb.num_serial, &t->hfsp_serial_number, 8);
memcpy (&sb.num_serial, &t->opts->hfsp_serial_number, 8);
ret = iso_write(t, &sb, sizeof (sb));
if (ret < 0)
return ret;
@ -667,7 +675,7 @@ int hfsplus_writer_write_data(IsoImageWriter *writer)
}
t = writer->target;
block_size = t->hfsp_block_size;
block_size = t->opts->hfsp_block_size;
block_fac = t->hfsp_iso_block_fac;
cat_node_size = t->hfsp_cat_node_size;
@ -1035,7 +1043,7 @@ int hfsplus_tail_writer_write_data(IsoImageWriter *writer)
}
t = writer->target;
block_size = t->hfsp_block_size;
block_size = t->opts->hfsp_block_size;
#ifdef Libisofs_ts_debuG
iso_msg_debug(t->image->id, "hfsplus tail writer writes at = %.f",
@ -1227,7 +1235,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 +1279,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;
@ -1582,10 +1589,10 @@ int hfsplus_writer_create(Ecma119Image *target)
make_hfsplus_decompose_pages();
make_hfsplus_class_pages();
if (target->hfsp_block_size == 0)
target->hfsp_block_size = HFSPLUS_DEFAULT_BLOCK_SIZE;
target->hfsp_cat_node_size = 2 * target->hfsp_block_size;
target->hfsp_iso_block_fac = 2048 / target->hfsp_block_size;
if (target->opts->hfsp_block_size == 0)
target->opts->hfsp_block_size = HFSPLUS_DEFAULT_BLOCK_SIZE;
target->hfsp_cat_node_size = 2 * target->opts->hfsp_block_size;
target->hfsp_iso_block_fac = 2048 / target->opts->hfsp_block_size;
cat_node_size = target->hfsp_cat_node_size;
writer->compute_data_blocks = hfsplus_writer_compute_data_blocks;

View File

@ -194,4 +194,8 @@ void make_hfsplus_class_pages();
extern const uint16_t hfsplus_casefold[];
int iso_get_hfsplus_name(char *input_charset, int imgid, char *name,
uint16_t **result, uint32_t *result_len, uint16_t **cmp_name);
#endif /* LIBISO_HFSPLUS_H */

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2012 Thomas Schmitt
* Copyright (c) 2009 - 2015 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
@ -22,6 +22,100 @@
#include <string.h>
#include <stdio.h>
int iso_imported_sa_new(struct iso_imported_sys_area **boots, int flag)
{
struct iso_imported_sys_area *b;
*boots = NULL;
b = calloc(1, sizeof(struct iso_imported_sys_area));
if (b == NULL)
return ISO_OUT_OF_MEM;
b->mbr_req = NULL;
b->apm_req = NULL;
b->gpt_req = NULL;
b->gpt_backup_comments = NULL;
b->mips_boot_file_paths = NULL;
b->mips_vd_entries = NULL;
b->sparc_disc_label = NULL;
b->sparc_core_node = NULL;
b->sparc_entries = NULL;
b->hppa_cmdline = NULL;
b->hppa_bootloader = NULL;
b->hppa_kernel_32 = NULL;
b->hppa_kernel_64 = NULL;
b->hppa_ramdisk = NULL;
b->alpha_boot_image = NULL;
*boots = b;
return 1;
}
int iso_imported_sa_unref(struct iso_imported_sys_area **boots, int flag)
{
int i;
struct iso_imported_sys_area *b;
b = *boots;
if (b == NULL)
return 2;
if (b->refcount > 0)
b->refcount--;
if (b->refcount > 0)
return 2;
if (b->mbr_req != NULL) {
for (i = 0; i < b->mbr_req_count; i++)
LIBISO_FREE_MEM(b->mbr_req[i]);
LIBISO_FREE_MEM(b->mbr_req);
}
if (b->apm_req != NULL) {
for (i = 0; i < b->apm_req_count; i++)
LIBISO_FREE_MEM(b->apm_req[i]);
LIBISO_FREE_MEM(b->apm_req);
}
if (b->gpt_req != NULL) {
for (i = 0; i < b->gpt_req_count; i++)
LIBISO_FREE_MEM(b->gpt_req[i]);
LIBISO_FREE_MEM(b->gpt_req);
}
LIBISO_FREE_MEM(b->gpt_backup_comments);
if (b->mips_boot_file_paths != NULL) {
for (i = 0; i < b->num_mips_boot_files; i++)
LIBISO_FREE_MEM(b->mips_boot_file_paths[i]);
LIBISO_FREE_MEM(b->mips_boot_file_paths);
}
if (b->mips_vd_entries != NULL) {
for (i = 0; i < b->num_mips_boot_files; i++)
LIBISO_FREE_MEM(b->mips_vd_entries[i]);
LIBISO_FREE_MEM(b->mips_vd_entries);
}
LIBISO_FREE_MEM(b->mipsel_boot_file_path);
LIBISO_FREE_MEM(b->sparc_disc_label);
if (b->sparc_core_node != NULL)
iso_node_unref((IsoNode *) b->sparc_core_node);
LIBISO_FREE_MEM(b->sparc_entries);
LIBISO_FREE_MEM(b->hppa_cmdline);
LIBISO_FREE_MEM(b->hppa_bootloader);
LIBISO_FREE_MEM(b->hppa_kernel_32);
LIBISO_FREE_MEM(b->hppa_kernel_64);
LIBISO_FREE_MEM(b->hppa_ramdisk);
LIBISO_FREE_MEM(b->alpha_boot_image);
LIBISO_FREE_MEM(b);
*boots = NULL;
return 1;
}
/**
* Create a new image, empty.
*
@ -78,11 +172,20 @@ 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->hppa_cmdline= NULL;
img->hppa_bootloader = NULL;
img->hppa_kernel_32 = NULL;
img->hppa_kernel_64 = NULL;
img->hppa_ramdisk = NULL;
img->alpha_boot_image = NULL;
img->import_src = NULL;
img->builder_ignore_acl = 1;
img->builder_ignore_ea = 1;
img->inode_counter = 0;
@ -95,6 +198,8 @@ int iso_image_new(const char *name, IsoImage **image)
img->generator_is_running = 0;
for (i = 0; i < ISO_HFSPLUS_BLESS_MAX; i++)
img->hfsplus_blessed[i] = NULL;
img->collision_warnings = 0;
img->imported_sa_info = NULL;
*image = img;
return ISO_SUCCESS;
@ -136,6 +241,13 @@ 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);
iso_image_set_hppa_palo(image, NULL, NULL, NULL, NULL, NULL, 1);
if (image->alpha_boot_image != NULL)
free(image->alpha_boot_image);
if (image->import_src != NULL)
iso_data_source_unref(image->import_src);
free(image->volset_id);
free(image->volume_id);
free(image->publisher_id);
@ -154,6 +266,7 @@ void iso_image_unref(IsoImage *image)
if (image->system_area_data != NULL)
free(image->system_area_data);
iso_image_free_checksums(image, 0);
iso_imported_sa_unref(&(image->imported_sa_info), 0);
free(image);
}
}
@ -346,13 +459,18 @@ int iso_image_set_pvd_times(IsoImage *image,
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);
image->creation_time = calloc(18, 1); /* Surely including a trailing 0 */
image->modification_time = calloc(18, 1);
image->expiration_time = calloc(18, 1);
image->effective_time = calloc(18, 1);
if (image->creation_time == NULL || image->modification_time == NULL ||
image->expiration_time == NULL || image->effective_time == NULL)
return ISO_OUT_OF_MEM;
/* (If the string is too short, a non-zero timezone will not be stored) */
strncpy(image->creation_time, creation_time, 17);
strncpy(image->modification_time, modification_time, 17);
strncpy(image->expiration_time, expiration_time, 17);
strncpy(image->effective_time, effective_time, 17);
return ISO_SUCCESS;
}
@ -370,6 +488,19 @@ int iso_image_get_pvd_times(IsoImage *image,
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;
@ -389,21 +520,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;
@ -499,7 +683,8 @@ ex:;
/**
* A global counter for inode numbers for the ISO image filesystem.
* A global counter for Rock Ridge inode numbers in the ISO image filesystem.
*
* On image import it gets maxed by the eventual inode numbers from PX
* entries. Up to the first 32 bit rollover it simply increments the counter.
* After the first rollover it uses a look ahead bitmap which gets filled
@ -509,13 +694,13 @@ ex:;
* @param image The image where the number shall be used
* @param flag bit0= reset count (Caution: image must get new inos then)
* @return
* Since ino_t 0 is used as default and considered self-unique,
* Since 0 is used as default and considered self-unique,
* the value 0 should only be returned in case of error.
*/
ino_t img_give_ino_number(IsoImage *image, int flag)
uint32_t img_give_ino_number(IsoImage *image, int flag)
{
int ret;
ino_t new_ino, ino_idx;
uint64_t new_ino, ino_idx;
static uint64_t limit = 0xffffffff;
if (flag & 1) {
@ -525,10 +710,10 @@ ino_t img_give_ino_number(IsoImage *image, int flag)
image->used_inodes = NULL;
image->used_inodes_start = 0;
}
new_ino = image->inode_counter + 1;
new_ino = ((uint64_t) image->inode_counter) + 1;
if (image->used_inodes == NULL) {
if (new_ino > 0 && new_ino <= limit) {
image->inode_counter = new_ino;
image->inode_counter = (uint32_t) new_ino;
return image->inode_counter;
}
}
@ -767,3 +952,134 @@ 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;
}
/* @param flag
bit0= Let NULL parameters free the corresponding image properties.
Else only the non-NULL parameters of this call have an effect.
*/
static int hppa_palo_set_path(IsoImage *img, char *path, char **target,
char *what, int flag)
{
int ret, err;
IsoNode *node;
IsoFile *file;
if (path == NULL && !(flag & 1))
return ISO_SUCCESS;
if (iso_clone_mgtd_mem(path, target, 0) < 0)
return ISO_OUT_OF_MEM;
if (path == NULL)
return ISO_SUCCESS;
ret = iso_tree_path_to_node(img, path, &node);
if (ret < 0)
return ret;
if (ret == 0) {
iso_msg_submit(img->id, ISO_BOOT_FILE_MISSING, 0,
"Cannot find in ISO image: %s file '%s'", what, path);
return ISO_BOOT_FILE_MISSING;
}
if (iso_node_get_type(node) != LIBISO_FILE) {
err = ISO_HPPA_PALO_NOTREG;
if (strncmp(what, "DEC Alpha", 9) == 0)
err = ISO_ALPHA_BOOT_NOTREG;
iso_msg_submit(img->id, err, 0,
"%s file is not a data file: '%s'", what, path);
return err;
}
file = (IsoFile *) node;
if (!(file->explicit_weight || file->from_old_session))
file->sort_weight = 2;
return ISO_SUCCESS;
}
/* API */
/* @param flag
Bitfield for control purposes
bit0= Let NULL parameters free the corresponding image properties.
Else only the non-NULL parameters of this call have an effect.
*/
int iso_image_set_hppa_palo(IsoImage *img, char *cmdline, char *bootloader,
char *kernel_32, char *kernel_64, char *ramdisk,
int flag)
{
int ret;
static char *what = "HP-PA PALO";
if (cmdline != NULL || (flag & 1))
if (iso_clone_mgtd_mem(cmdline, &(img->hppa_cmdline), 0) < 0)
return ISO_OUT_OF_MEM;
ret = hppa_palo_set_path(img, bootloader, &(img->hppa_bootloader), what,
flag & 1);
if (ret < 0)
return ret;
ret = hppa_palo_set_path(img, kernel_32, &(img->hppa_kernel_32), what,
flag & 1);
if (ret < 0)
return ret;
ret = hppa_palo_set_path(img, kernel_64, &(img->hppa_kernel_64), what,
flag & 1);
if (ret < 0)
return ret;
ret = hppa_palo_set_path(img, ramdisk, &(img->hppa_ramdisk), what,
flag & 1);
if (ret < 0)
return ret;
return ISO_SUCCESS;
}
/* API */
int iso_image_get_hppa_palo(IsoImage *img, char **cmdline, char **bootloader,
char **kernel_32, char **kernel_64, char **ramdisk)
{
*cmdline = img->hppa_cmdline;
*bootloader = img->hppa_bootloader;
*kernel_32 = img->hppa_kernel_32;
*kernel_64 = img->hppa_kernel_64;
*ramdisk = img->hppa_ramdisk;
return ISO_SUCCESS;
}
/* API */
int iso_image_set_alpha_boot(IsoImage *img, char *boot_loader_path, int flag)
{
int ret;
ret = hppa_palo_set_path(img, boot_loader_path, &(img->alpha_boot_image),
"DEC Alpha Bootloader", 1);
if (ret < 0)
return ret;
return ISO_SUCCESS;
}
/* API */
int iso_image_get_alpha_boot(IsoImage *img, char **boot_loader_path)
{
*boot_loader_path = img->alpha_boot_image;
return ISO_SUCCESS;
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2012 Thomas Schmitt
* Copyright (c) 2009 - 2015 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
@ -22,6 +22,9 @@
*/
#define ISO_USED_INODE_RANGE (1 << 18)
/* How many warnings to issue about name collisions during iso_image_import()
*/
#define ISO_IMPORT_COLL_WARN_MAX 10
/*
* Image is a context for image manipulation.
@ -53,6 +56,7 @@ struct Iso_Image
char *modification_time;
char *expiration_time;
char *effective_time;
char application_use[512];
/* el-torito boot catalog */
struct el_torito_boot_catalog *bootcat;
@ -60,6 +64,8 @@ struct Iso_Image
/* Eventually loaded system area data, or NULL */
char *system_area_data;
/* Prescribed/detected options, see iso_write_opts_set_system_area() */
/* >>> Needs to be coordinated with .imported_sa_info->system_area_options
*/
int system_area_options;
/*
@ -69,6 +75,23 @@ 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;
/*
* Parameters for HP-PA PALO boot sector. cmdline is a string. The other
* four are absolute paths to data files in the ISO image.
*/
char *hppa_cmdline;
char *hppa_bootloader;
char *hppa_kernel_32;
char *hppa_kernel_64;
char *hppa_ramdisk;
/* Absolute DEC Alpha boot image path in the ISO image */
char *alpha_boot_image;
/* image identifier, for message origin identifier */
int id;
@ -78,6 +101,11 @@ struct Iso_Image
*/
IsoFilesystem *fs;
/**
* Block storage of imported ISO if demanded by IsoReadOpts.
*/
IsoDataSource *import_src;
/*
* Default builder to use when adding files to the image tree.
*/
@ -153,18 +181,20 @@ struct Iso_Image
* Inode number management. inode_counter is taken over from
* IsoImageFilesystem._ImageFsData after image import.
* It is to be used with img_give_ino_number()
*/
ino_t inode_counter;
* This is a Rock Ridge file serial number. Thus 32 bit.
*/
uint32_t inode_counter;
/*
* A bitmap of used inode numbers in an interval beginning at
* used_inodes_start and holding ISO_USED_INODE_RANGE bits.
* If a bit is set, then the corresponding inode number is occupied.
* This interval is kept around inode_counter and eventually gets
* advanced by ISO_USED_INODE_RANGE numbers in a tree traversal
* done by img_collect_inos().
* done by img_collect_inos(). The value will stay in the 32 bit range,
* although used_inodes_start is 64 bit to better handle rollovers.
*/
uint8_t *used_inodes;
ino_t used_inodes_start;
uint64_t used_inodes_start;
/**
* Array of MD5 checksums as announced by xattr "isofs.ca" of the
@ -191,6 +221,12 @@ struct Iso_Image
*/
IsoNode *hfsplus_blessed[ISO_HFSPLUS_BLESS_MAX];
/* Counts the name collisions while iso_image_import() */
size_t collision_warnings;
/* Contains the assessment of boot aspects of the loaded image */
struct iso_imported_sys_area *imported_sa_info;
};
@ -212,10 +248,10 @@ int img_collect_inos(IsoImage *image, IsoDir *dir, int flag);
* @param image The image where the number shall be used
* @param flag bit0= reset count (Caution: image must get new inos then)
* @return
* Since ino_t 0 is used as default and considered self-unique,
* Since 0 is used as default and considered self-unique,
* the value 0 should only be returned in case of error.
*/
ino_t img_give_ino_number(IsoImage *image, int flag);
uint32_t img_give_ino_number(IsoImage *image, int flag);
/* @param flag bit0= overwrite any ino, else only ino == 0
bit1= install inode with non-data, non-directory files
@ -242,4 +278,137 @@ int iso_image_set_pvd_times(IsoImage *image,
char *creation_time, char *modification_time,
char *expiration_time, char *effective_time);
/* Collects boot block information obtained from the system area of
imported images
*/
struct iso_imported_sys_area {
int refcount;
/* Whether there was some System Area data at all */
int is_not_zero;
/* Giving the error number if the assessment ended by an error */
int overall_return;
/* Block address of loaded Primar Volume Descriptor */
uint32_t pvd_block;
/* Size of the imported ISO image */
uint32_t image_size;
/* see libisofs.h : iso_write_opts_set_system_area() */
int system_area_options;
/* The perceived MBR partitions */
struct iso_mbr_partition_request **mbr_req;
int mbr_req_count;
/* see ecma119.h : struct ecma119_image , struct iso_write_opts */
/* Effective partition table parameter: 1 to 63, 0= disabled/default */
int partition_secs_per_head;
/* 1 to 255, 0= disabled/default */
int partition_heads_per_cyl;
/* see ecma119.h : struct iso_write_opts */
uint32_t partition_offset;
/* 2048-byte start LBA and block count of PreP partition */
uint32_t prep_part_start;
uint32_t prep_part_size;
/* see ecma119.h : struct ecma119_image */
struct iso_apm_partition_request **apm_req;
int apm_req_count;
int apm_req_flags;
/* Number of found "GapNN", "ISO9660_data" partitions in APM */
int apm_gap_count;
/* see ecma119.h : struct iso_write_opts */
int apm_block_size;
/* >>> see ecma119.h : struct iso_write_opts */
int hfsp_block_size;
/* see ecma119.h : struct ecma119_image */
struct iso_gpt_partition_request **gpt_req;
int gpt_req_count;
int gpt_req_flags;
/* see ecma119.h : struct ecma119_image */
uint8_t gpt_disk_guid[16];
/* Start of GPT entries in System Area, block size 512 */
uint64_t gpt_part_start;
uint32_t gpt_max_entries;
uint64_t gpt_first_lba;
uint64_t gpt_last_lba;
uint64_t gpt_backup_lba;
char *gpt_backup_comments;
uint32_t gpt_head_crc_found;
uint32_t gpt_head_crc_should;
uint32_t gpt_array_crc_found;
uint32_t gpt_array_crc_should;
/* see image.h : struct Iso_Image */
int num_mips_boot_files;
char **mips_boot_file_paths; /* ISO 9660 Rock Ridge Paths */
struct iso_mips_voldir_entry **mips_vd_entries;
/* see ecma119.h : struct ecma119_image */
/* Memorized ELF parameters from MIPS Little Endian boot file */
uint32_t mipsel_e_entry;
uint32_t mipsel_p_offset;
uint32_t mipsel_p_vaddr;
uint32_t mipsel_p_filesz;
uint32_t mipsel_seg_start;
char *mipsel_boot_file_path;
/* see image.h : struct Iso_Image */
char *sparc_disc_label;
int sparc_secs_per_head;
int sparc_heads_per_cyl;
struct iso_sun_disk_label_entry *sparc_entries;
int sparc_entry_count;
/* grub2-sparc-core : a node in the ISO image
published at bytes 0x228 to 0x233
*/
uint64_t sparc_grub2_core_adr;
uint32_t sparc_grub2_core_size;
IsoFile *sparc_core_node;
/* see image.h : struct Iso_Image */
int hppa_hdrversion;
char *hppa_cmdline;
uint32_t hppa_kern32_adr;
uint32_t hppa_kern32_len;
uint32_t hppa_kern64_adr;
uint32_t hppa_kern64_len;
uint32_t hppa_ramdisk_adr;
uint32_t hppa_ramdisk_len;
uint32_t hppa_bootloader_adr;
uint32_t hppa_bootloader_len;
uint32_t hppa_ipl_entry;
char *hppa_kernel_32;
char *hppa_kernel_64;
char *hppa_ramdisk;
char *hppa_bootloader;
uint64_t alpha_boot_image_size;
uint64_t alpha_boot_image_adr;
char *alpha_boot_image;
/* Some block addresses of active and first session:
PVD, L Pathtable, Opt L, M Pathtable, Opt M, root directory
*/
uint32_t meta_struct_blocks[12];
int num_meta_struct_blocks;
};
int iso_imported_sa_new(struct iso_imported_sys_area **sa_info, int flag);
int iso_imported_sa_unref(struct iso_imported_sys_area **sa_info, int flag);
#endif /*LIBISO_IMAGE_H_*/

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2011-2012 Thomas Schmitt
* Copyright (c) 2011-2014 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
@ -80,7 +80,8 @@ void iso1999_node_free(Iso1999Node *node)
for (i = 0; i < node->info.dir->nchildren; i++) {
iso1999_node_free(node->info.dir->children[i]);
}
free(node->info.dir->children);
if (node->info.dir->children != NULL)
free(node->info.dir->children);
free(node->info.dir);
}
iso_node_unref(node->node);
@ -111,11 +112,14 @@ int create_node(Ecma119Image *t, IsoNode *iso, Iso1999Node **node)
free(n);
return ISO_OUT_OF_MEM;
}
n->info.dir->children = calloc(sizeof(void*), dir->nchildren);
if (n->info.dir->children == NULL) {
free(n->info.dir);
free(n);
return ISO_OUT_OF_MEM;
n->info.dir->children = NULL;
if (dir->nchildren > 0) {
n->info.dir->children = calloc(sizeof(void*), dir->nchildren);
if (n->info.dir->children == NULL) {
free(n->info.dir);
free(n);
return ISO_OUT_OF_MEM;
}
}
n->type = ISO1999_DIR;
} else if (iso->type == LIBISO_FILE) {
@ -125,7 +129,7 @@ int create_node(Ecma119Image *t, IsoNode *iso, Iso1999Node **node)
IsoFile *file = (IsoFile*) iso;
size = iso_stream_get_size(file->stream);
if (size > (off_t)MAX_ISO_FILE_SECTION_SIZE && t->iso_level != 3) {
if (size > (off_t)MAX_ISO_FILE_SECTION_SIZE && t->opts->iso_level != 3) {
char *ipath = iso_tree_get_node_path(iso);
ret = iso_msg_submit(t->image->id, ISO_FILE_TOO_BIG, 0,
"File \"%s\" can't be added to image because is "
@ -194,7 +198,7 @@ int create_tree(Ecma119Image *t, IsoNode *iso, Iso1999Node **tree, int pathlen)
}
max_path = pathlen + 1 + (iso_name ? strlen(iso_name): 0);
if (!t->allow_longer_paths && max_path > 255) {
if (!t->opts->allow_longer_paths && max_path > 255) {
char *ipath = iso_tree_get_node_path(iso);
ret = iso_msg_submit(t->image->id, ISO_FILE_IMGPATH_WRONG, 0,
"File \"%s\" can't be added to ISO 9660:1999 tree, "
@ -293,6 +297,8 @@ void sort_tree(Iso1999Node *root)
{
size_t i;
if (root->info.dir->children == NULL)
return;
qsort(root->info.dir->children, root->info.dir->nchildren,
sizeof(void*), cmp_node);
for (i = 0; i < root->info.dir->nchildren; i++) {
@ -308,14 +314,18 @@ 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;
nchildren = dir->info.dir->nchildren;
if (nchildren <= 0) {
ret = ISO_SUCCESS;
goto ex;
}
children = dir->info.dir->children;
LIBISO_ALLOC_MEM(full_name, char, 208);
LIBISO_ALLOC_MEM(tmp, char, 208);
nchildren = dir->info.dir->nchildren;
children = dir->info.dir->children;
/* a hash table will temporary hold the names, for fast searching */
ret = iso_htable_create((nchildren * 100) / 80, iso_str_hash,
@ -722,13 +732,13 @@ void write_one_dir_record(Ecma119Image *t, Iso1999Node *node, int file_id,
iso_bb(rec->block, block, 4);
iso_bb(rec->length, len, 4);
/* was: iso_datetime_7(rec->recording_time, t->now, t->always_gmt);
/* was: iso_datetime_7(rec->recording_time, t->now, t->opts->always_gmt);
*/
iso= node->node;
iso_datetime_7(rec->recording_time,
(t->dir_rec_mtime & 4) ? ( t->replace_timestamps ?
t->timestamp : iso->mtime )
: t->now, t->always_gmt);
(t->opts->dir_rec_mtime & 4) ? ( t->replace_timestamps ?
t->timestamp : iso->mtime )
: t->now, t->opts->always_gmt);
rec->flags[0] = ((node->type == ISO1999_DIR) ? 2 : 0) | (multi_extend ? 0x80 : 0);
iso_bb(rec->vol_seq_number, (uint32_t) 1, 2);

View File

@ -1,7 +1,7 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2007 Mario Danic
* Copyright (c) 2011-2012 Thomas Schmitt
* Copyright (c) 2011-2014 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
@ -28,31 +28,69 @@
#include <stdio.h>
#include <string.h>
static
int get_joliet_name(Ecma119Image *t, IsoNode *iso, uint16_t **name)
/* @param flag bit0= Do not issue error messages
*/
int iso_get_joliet_name(IsoWriteOpts *opts, char *input_charset, int imgid,
char *node_name, enum IsoNodeType node_type,
size_t *joliet_ucs2_failures,
uint16_t **name, int flag)
{
int ret;
uint16_t *ucs_name;
int ret = ISO_SUCCESS;
uint16_t *ucs_name = NULL, *utf16_name = NULL;
uint16_t *jname = NULL;
if (iso->name == NULL) {
if (node_name == NULL) {
/* it is not necessarily an error, it can be the root */
*name = NULL;
return ISO_SUCCESS;
}
ret = str2ucs(t->input_charset, iso->name, &ucs_name);
if (ret < 0) {
iso_msg_debug(t->image->id, "Can't convert %s", iso->name);
return ret;
if (opts->joliet_utf16) {
ret = str2utf16be(input_charset, node_name, &ucs_name);
if (ret < 0) {
if (!(flag & 512))
iso_msg_debug(imgid, "Cannot convert to UTF-16 : \"%s\"",
node_name);
goto ex;
}
} else {
ret = str2ucs(input_charset, node_name, &ucs_name);
if (ret < 0) {
if (!(flag & 512))
iso_msg_debug(imgid, "Cannot convert to UCS-2 : \"%s\"",
node_name);
goto ex;
}
ret = str2utf16be(input_charset, node_name, &utf16_name);
if (ret == ISO_SUCCESS) {
if (ucscmp(ucs_name, utf16_name) != 0) {
(*joliet_ucs2_failures)++;
if (*joliet_ucs2_failures <= ISO_JOLIET_UCS2_WARN_MAX &&
!(flag & 512)) {
iso_msg_submit(imgid, ISO_NAME_NOT_UCS2, 0,
"Filename not suitable for Joliet character set UCS-2 : \"%s\"",
node_name);
}
}
}
}
if (iso->type == LIBISO_DIR) {
jname = iso_j_dir_id(ucs_name, t->joliet_long_names << 1);
if (node_type == LIBISO_DIR) {
jname = iso_j_dir_id(ucs_name, opts->joliet_long_names << 1);
} else {
jname = iso_j_file_id(ucs_name,
(t->joliet_long_names << 1) | !!(t->no_force_dots & 2));
(opts->joliet_long_names << 1) | !!(opts->no_force_dots & 2));
}
free(ucs_name);
if (jname != NULL) {
ret = ISO_SUCCESS;
ex:;
if (ucs_name != NULL)
free(ucs_name);
if (utf16_name != NULL)
free(utf16_name);
if (ret != ISO_SUCCESS) {
if (jname != NULL)
free(jname);
return ret;
} else if (jname != NULL) {
*name = jname;
return ISO_SUCCESS;
} else {
@ -64,6 +102,19 @@ int get_joliet_name(Ecma119Image *t, IsoNode *iso, uint16_t **name)
}
}
static
int get_joliet_name(Ecma119Image *t, IsoNode *iso, uint16_t **name)
{
int ret;
ret = iso_get_joliet_name(t->opts, t->input_charset, t->image->id,
iso->name, iso->type, &(t->joliet_ucs2_failures),
name, 0);
return ret;
}
static
void joliet_node_free(JolietNode *node)
{
@ -75,7 +126,8 @@ void joliet_node_free(JolietNode *node)
for (i = 0; i < node->info.dir->nchildren; i++) {
joliet_node_free(node->info.dir->children[i]);
}
free(node->info.dir->children);
if (node->info.dir->children != NULL)
free(node->info.dir->children);
free(node->info.dir);
}
iso_node_unref(node->node);
@ -106,11 +158,14 @@ int create_node(Ecma119Image *t, IsoNode *iso, JolietNode **node)
free(joliet);
return ISO_OUT_OF_MEM;
}
joliet->info.dir->children = calloc(sizeof(void*), dir->nchildren);
if (joliet->info.dir->children == NULL) {
free(joliet->info.dir);
free(joliet);
return ISO_OUT_OF_MEM;
joliet->info.dir->children = NULL;
if (dir->nchildren > 0) {
joliet->info.dir->children = calloc(sizeof(void*), dir->nchildren);
if (joliet->info.dir->children == NULL) {
free(joliet->info.dir);
free(joliet);
return ISO_OUT_OF_MEM;
}
}
joliet->type = JOLIET_DIR;
} else if (iso->type == LIBISO_FILE) {
@ -120,7 +175,8 @@ int create_node(Ecma119Image *t, IsoNode *iso, JolietNode **node)
IsoFile *file = (IsoFile*) iso;
size = iso_stream_get_size(file->stream);
if (size > (off_t)MAX_ISO_FILE_SECTION_SIZE && t->iso_level != 3) {
if (size > (off_t)MAX_ISO_FILE_SECTION_SIZE &&
t->opts->iso_level != 3) {
char *ipath = iso_tree_get_node_path(iso);
free(joliet);
ret = iso_msg_submit(t->image->id, ISO_FILE_TOO_BIG, 0,
@ -188,7 +244,7 @@ int create_tree(Ecma119Image *t, IsoNode *iso, JolietNode **tree, int pathlen)
return ret;
}
max_path = pathlen + 1 + (jname ? ucslen(jname) * 2 : 0);
if (!t->joliet_longer_paths && max_path > 240) {
if (!t->opts->joliet_longer_paths && max_path > 240) {
char *ipath = iso_tree_get_node_path(iso);
/*
* Wow!! Joliet is even more restrictive than plain ISO-9660,
@ -249,7 +305,7 @@ int create_tree(Ecma119Image *t, IsoNode *iso, JolietNode **tree, int pathlen)
{
char *ipath = iso_tree_get_node_path(iso);
ret = iso_msg_submit(t->image->id, ISO_FILE_IGNORED, 0,
"Can't add %s to Joliet tree. %s can only be added to a "
"Cannot add %s to Joliet tree. %s can only be added to a "
"Rock Ridge tree.", ipath, (iso->type == LIBISO_SYMLINK ?
"Symlinks" : "Special files"));
free(ipath);
@ -281,6 +337,8 @@ void sort_tree(JolietNode *root)
{
size_t i;
if (root->info.dir->children == NULL)
return;
qsort(root->info.dir->children, root->info.dir->nchildren,
sizeof(void*), cmp_node);
for (i = 0; i < root->info.dir->nchildren; i++) {
@ -349,17 +407,21 @@ 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;
nchildren = dir->info.dir->nchildren;
if (nchildren <= 0) {
ret = ISO_SUCCESS;
goto ex;
}
children = dir->info.dir->children;
LIBISO_ALLOC_MEM(full_name, uint16_t, LIBISO_JOLIET_NAME_MAX);
LIBISO_ALLOC_MEM(tmp, uint16_t, LIBISO_JOLIET_NAME_MAX);
nchildren = dir->info.dir->nchildren;
children = dir->info.dir->children;
if (t->joliet_long_names)
if (t->opts->joliet_long_names)
maxchar = 103;
/* a hash table will temporary hold the names, for fast searching */
@ -598,7 +660,7 @@ size_t calc_dirent_len(Ecma119Image *t, JolietNode *n)
{
/* note than name len is always even, so we always need the pad byte */
int ret = n->name ? ucslen(n->name) * 2 + 34 : 34;
if (n->type == JOLIET_FILE && !(t->omit_version_numbers & 3)) {
if (n->type == JOLIET_FILE && !(t->opts->omit_version_numbers & 3)) {
/* take into account version numbers */
ret += 4;
}
@ -717,7 +779,7 @@ int joliet_writer_compute_data_blocks(IsoImageWriter *writer)
t->curblock += DIV_UP(path_table_size, BLOCK_SIZE);
t->joliet_path_table_size = path_table_size;
if (t->partition_offset > 0) {
if (t->opts->partition_offset > 0) {
/* Take into respect second directory tree */
ndirs = t->joliet_ndirs;
t->joliet_ndirs = 0;
@ -766,7 +828,7 @@ void write_one_dir_record(Ecma119Image *t, JolietNode *node, int file_id,
memcpy(rec->file_id, name, len_fi);
if (node->type == JOLIET_FILE && !(t->omit_version_numbers & 3)) {
if (node->type == JOLIET_FILE && !(t->opts->omit_version_numbers & 3)) {
len_dr += 4;
rec->file_id[len_fi++] = 0;
rec->file_id[len_fi++] = ';';
@ -801,13 +863,13 @@ void write_one_dir_record(Ecma119Image *t, JolietNode *node, int file_id,
iso_bb(rec->block, block - t->eff_partition_offset, 4);
iso_bb(rec->length, len, 4);
/* was: iso_datetime_7(rec->recording_time, t->now, t->always_gmt);
/* was: iso_datetime_7(rec->recording_time, t->now, t->opts->always_gmt);
*/
iso= node->node;
iso_datetime_7(rec->recording_time,
(t->dir_rec_mtime & 2) ? ( t->replace_timestamps ?
t->timestamp : iso->mtime )
: t->now, t->always_gmt);
(t->opts->dir_rec_mtime & 2) ? ( t->replace_timestamps ?
t->timestamp : iso->mtime )
: t->now, t->opts->always_gmt);
rec->flags[0] = ((node->type == JOLIET_DIR) ? 2 : 0) | (multi_extend ? 0x80 : 0);
iso_bb(rec->vol_seq_number, (uint32_t) 1, 2);
@ -828,18 +890,22 @@ void ucsncpy_pad(uint16_t *dest, const uint16_t *src, size_t max)
csrc = (char*)src;
if (src != NULL) {
len = MIN(ucslen(src) * 2, max);
len = MIN(ucslen(src) * 2, max - (max % 2));
} else {
len = 0;
}
for (i = 0; i < len; ++i)
cdest[i] = csrc[i];
if (len >= 2)
iso_handle_split_utf16(dest + (len / 2 - 1));
for (i = len; i < max; i += 2) {
for (i = len; i + 1 < max; i += 2) {
cdest[i] = '\0';
cdest[i + 1] = ' ';
}
if (max % 2)
cdest[max - 1] = 0;
}
int joliet_writer_write_vol_desc(IsoImageWriter *writer)
@ -958,7 +1024,8 @@ int write_one_dir(Ecma119Image *t, JolietNode *dir)
/* compute len of directory entry */
fi_len = ucslen(child->name) * 2;
len = fi_len + 34;
if (child->type == JOLIET_FILE && !(t->omit_version_numbers & 3)) {
if (child->type == JOLIET_FILE &&
!(t->opts->omit_version_numbers & 3)) {
len += 4;
}
@ -1160,8 +1227,8 @@ int joliet_writer_write_data(IsoImageWriter *writer)
if (ret < 0)
return ret;
if (t->partition_offset > 0) {
t->eff_partition_offset = t->partition_offset;
if (t->opts->partition_offset > 0) {
t->eff_partition_offset = t->opts->partition_offset;
ret = joliet_writer_write_dirs(writer);
t->eff_partition_offset = 0;
if (ret < 0)
@ -1209,9 +1276,9 @@ int joliet_writer_create(Ecma119Image *target)
/* add this writer to image */
target->writers[target->nwriters++] = writer;
if(target->partition_offset > 0) {
if(target->opts->partition_offset > 0) {
/* Create second tree */
target->eff_partition_offset = target->partition_offset;
target->eff_partition_offset = target->opts->partition_offset;
ret = joliet_tree_create(target);
if (ret < 0) {
return ret;

View File

@ -63,5 +63,13 @@ int joliet_writer_create(Ecma119Image *target);
*/
int joliet_writer_write_vol_desc(IsoImageWriter *writer);
/**
* Determine the Joliet name from node name.
* @param flag bit0= Do not issue error messages
*/
int iso_get_joliet_name(IsoWriteOpts *opts, char *input_charset, int imgid,
char *node_name, enum IsoNodeType node_type,
size_t *joliet_ucs2_failures,
uint16_t **name, int flag);
#endif /* LIBISO_JOLIET_H */

File diff suppressed because it is too large Load Diff

View File

@ -19,6 +19,8 @@ el_torito_set_load_seg;
el_torito_set_load_size;
el_torito_set_no_bootable;
el_torito_set_selection_crit;
iso_conv_name_chars;
iso_crc32_gpt;
iso_data_source_new_from_file;
iso_data_source_ref;
iso_data_source_unref;
@ -88,6 +90,8 @@ 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_alpha_boot;
iso_image_get_app_use;
iso_image_get_application_id;
iso_image_get_attached_data;
iso_image_get_biblio_file_id;
@ -95,12 +99,14 @@ iso_image_get_bootcat;
iso_image_get_boot_image;
iso_image_get_copyright_file_id;
iso_image_get_data_preparer_id;
iso_image_get_hppa_palo;
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,7 +118,11 @@ iso_image_import;
iso_image_new;
iso_image_ref;
iso_image_remove_boot_image;
iso_image_report_el_torito;
iso_image_report_system_area;
iso_image_set_abstract_file_id;
iso_image_set_alpha_boot;
iso_image_set_app_use;
iso_image_set_application_id;
iso_image_set_biblio_file_id;
iso_image_set_boot_catalog_hidden;
@ -120,8 +130,10 @@ iso_image_set_boot_catalog_weight;
iso_image_set_boot_image;
iso_image_set_copyright_file_id;
iso_image_set_data_preparer_id;
iso_image_set_hppa_palo;
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;
@ -129,6 +141,9 @@ iso_image_unref;
iso_image_update_sizes;
iso_init;
iso_init_with_flag;
iso_interval_reader_destroy;
iso_interval_reader_new;
iso_interval_reader_read;
iso_lib_is_compatible;
iso_lib_version;
iso_local_attr_support;
@ -204,6 +219,7 @@ iso_read_image_features_has_joliet;
iso_read_image_features_has_rockridge;
iso_read_opts_auto_input_charset;
iso_read_opts_free;
iso_read_opts_keep_import_src;
iso_read_opts_load_system_area;
iso_read_opts_new;
iso_read_opts_set_default_gid;
@ -280,6 +296,7 @@ iso_write_opts_set_allow_longer_paths;
iso_write_opts_set_allow_lowercase;
iso_write_opts_set_always_gmt;
iso_write_opts_set_appendable;
iso_write_opts_set_appended_as_gpt;
iso_write_opts_set_default_dir_mode;
iso_write_opts_set_default_file_mode;
iso_write_opts_set_default_gid;
@ -299,6 +316,7 @@ iso_write_opts_set_iso_level;
iso_write_opts_set_joliet;
iso_write_opts_set_joliet_long_names;
iso_write_opts_set_joliet_longer_paths;
iso_write_opts_set_joliet_utf16;
iso_write_opts_set_max_37_char_filenames;
iso_write_opts_set_ms_block;
iso_write_opts_set_no_force_dots;

View File

@ -1,3 +1,13 @@
/*
* Copyright (c) 2008 - 2015 Thomas Schmitt
* with special credits to H. Peter Anvin for isohybrid
* and to Matthew Garrett for isohybrid with GPT and APM
*
* 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
* or later as published by the Free Software Foundation.
* See COPYING file for details.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
@ -50,7 +60,7 @@ license from above stem licenses, typically from LGPL.
In case its generosity is needed, here is the 2-clause BSD license:
make_isohybrid_mbr.c is copyright 2002-2008 H. Peter Anvin
and 2008-2012 Thomas Schmitt
and 2008-2014 Thomas Schmitt
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
@ -435,9 +445,10 @@ int assess_isohybrid_gpt_apm(Ecma119Image *t, int *gpt_count, int gpt_idx[128],
for (j = 0; j < t->bootsrc[i]->nsections; j++)
block_count += t->bootsrc[i]->sections[j].size / 2048;
ret = iso_quick_gpt_entry(
t, t->bootsrc[i]->sections[0].block,
block_count, uuid, zero_uuid, gpt_flags,
(uint8_t *) gpt_name);
t->gpt_req, &(t->gpt_req_count),
((uint64_t) t->bootsrc[i]->sections[0].block) * 4,
((uint64_t) block_count) * 4,
uuid, zero_uuid, gpt_flags, (uint8_t *) gpt_name);
if (ret < 0)
return ret;
}
@ -449,13 +460,14 @@ int assess_isohybrid_gpt_apm(Ecma119Image *t, int *gpt_count, int gpt_idx[128],
block_count = 0;
for (j = 0; j < t->bootsrc[i]->nsections; j++)
block_count += t->bootsrc[i]->sections[j].size / 2048;
ret = iso_quick_apm_entry(t, t->bootsrc[i]->sections[0].block,
ret = iso_quick_apm_entry(t->apm_req, &(t->apm_req_count),
t->bootsrc[i]->sections[0].block,
block_count, "EFI", "Apple_HFS");
if (ret < 0)
return ret;
/* Prevent gap filling */
t->apm_req_flags |= 2;
t->apm_block_size = 2048;
t->opts->apm_block_size = 2048;
}
}
}
@ -466,7 +478,9 @@ int assess_isohybrid_gpt_apm(Ecma119Image *t, int *gpt_count, int gpt_idx[128],
iso_ascii_utf_16le(gpt_name);
/* Let it be open ended. iso_write_gpt() will truncate it as needed. */
block_count = 0xffffffff;
ret = iso_quick_gpt_entry(t, (uint32_t) 0, block_count,
ret = iso_quick_gpt_entry(t->gpt_req, &(t->gpt_req_count),
(uint64_t) t->opts->partition_offset * 4,
((uint64_t) block_count) * 4,
basic_data_uuid, zero_uuid, gpt_flags,
(uint8_t *) gpt_name);
if (ret < 0)
@ -555,25 +569,31 @@ static int gpt_images_as_mbr_partitions(Ecma119Image *t, char *wpt,
/*
* @param flag bit0= make own random MBR Id from current time
* bit1= create protective MBR as of UEFI/GPT specs
*/
int make_isolinux_mbr(int32_t *img_blocks, Ecma119Image *t,
int make_isolinux_mbr(uint32_t *img_blocks, Ecma119Image *t,
int part_offset, int part_number, int fs_type,
uint8_t *buf, int flag)
{
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 */
struct timeval tv;
struct timezone tz;
hd_img_blocks = ((off_t) *img_blocks) * (off_t) 4;
if (flag & 2) {
part_number = 1;
part_offset = 1;
}
hd_img_blocks = ((off_t) *img_blocks) * (off_t) 4 -
t->post_iso_part_pad / 512;
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 +628,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
@ -634,14 +656,17 @@ int make_isolinux_mbr(int32_t *img_blocks, Ecma119Image *t,
wpt+= 16;
continue;
}
/* write byte 0x80
/* write byte 0x80 if bootable
write LBA_to_CHS(partition_offset)
write byte filesystem_type
write LBA_to_CHS(image_size-1)
write dword partition_offset
write dword image_size
*/
lsb_to_buf(&wpt, 0x80, 8, 0);
if (flag & 2)
lsb_to_buf(&wpt, 0x00, 8, 0);
else
lsb_to_buf(&wpt, 0x80, 8, 0);
lba512chs_to_buf(&wpt, part_offset, head_count, sector_count);
lsb_to_buf(&wpt, fs_type, 8, 0);
lba512chs_to_buf(&wpt, hd_img_blocks - 1, head_count, sector_count);

View File

@ -497,7 +497,7 @@ int checksum_copy_old_nodes(Ecma119Image *target, IsoNode *node, int flag)
if (node->type == LIBISO_FILE) {
file = (IsoFile *) node;
if (file->from_old_session && target->appendable) {
if (file->from_old_session && target->opts->appendable) {
/* Look for checksums at various places */
/* Try checksum directly stored with node */
@ -527,7 +527,7 @@ int checksum_copy_old_nodes(Ecma119Image *target, IsoNode *node, int flag)
if (md5_pt == NULL)
return 0;
if (!target->will_cancel) {
if (!target->opts->will_cancel) {
ret = iso_node_lookup_attr(node, "isofs.cx", &value_length,
&value, 0);
if (ret == 1 && value_length == 4) {
@ -540,13 +540,12 @@ int checksum_copy_old_nodes(Ecma119Image *target, IsoNode *node, int flag)
if (value != NULL)
free(value);
/* ts B30114 : It is unclear why these are removed here.
At least with the opts->will_cancel runs,
this is not appropriate.
/* >>> ts B30114 : It is unclear why these are removed here.
At least with the opts->will_cancel runs,
this is not appropriate.
*/
iso_node_remove_xinfo(node, checksum_md5_xinfo_func);
}
iso_node_remove_xinfo(node, checksum_cx_xinfo_func);
}
} else if (node->type == LIBISO_DIR) {
for (pos = ((IsoDir *) node)->children; pos != NULL; pos = pos->next) {
@ -572,8 +571,8 @@ int checksum_writer_compute_data_blocks(IsoImageWriter *writer)
t = writer->target;
t->checksum_array_pos = t->curblock;
/* (t->curblock already contains t->ms_block) */
t->checksum_range_start = t->ms_block;
/* (t->curblock already contains t->opts->ms_block) */
t->checksum_range_start = t->opts->ms_block;
size = (t->checksum_idx_counter + 2) / 128;
if (size * 128 < t->checksum_idx_counter + 2)
size++;
@ -713,7 +712,7 @@ int checksum_writer_create(Ecma119Image *target)
/* add this writer to image */
target->writers[target->nwriters++] = writer;
/* Account for superblock checksum tag */
if (target->md5_session_checksum) {
if (target->opts->md5_session_checksum) {
target->checksum_sb_tag_pos = target->curblock;
target->curblock++;
}
@ -743,7 +742,7 @@ int iso_md5_write_scdbackup_tag(Ecma119Image *t, char *tag_block, int flag)
(unsigned int) (pos % 1000000000));
else
sprintf(postext, "%u", (unsigned int) pos);
sprintf(record, "%s %s ", t->scdbackup_tag_parm, postext);
sprintf(record, "%s %s ", t->opts->scdbackup_tag_parm, postext);
record_len = strlen(record);
for (i = 0; i < 16; i++)
sprintf(record + record_len + 2 * i,
@ -765,8 +764,8 @@ int iso_md5_write_scdbackup_tag(Ecma119Image *t, char *tag_block, int flag)
block_len+= 32;
tag_block[block_len++]= '\n';
if (t->scdbackup_tag_written != NULL)
strncpy(t->scdbackup_tag_written, tag_block + line_start,
if (t->opts->scdbackup_tag_written != NULL)
strncpy(t->opts->scdbackup_tag_written, tag_block + line_start,
block_len - line_start);
ret = ISO_SUCCESS;
ex:;
@ -828,7 +827,7 @@ int iso_md5_write_tag(Ecma119Image *t, int flag)
} else if (mode == 3) {
sprintf(tag_block + l, " next=%u", t->checksum_tag_pos);
} else if (mode == 4) {
sprintf(tag_block + l, " session_start=%u", t->ms_block);
sprintf(tag_block + l, " session_start=%u", t->opts->ms_block);
}
strcat(tag_block + l, " md5=");
l = strlen(tag_block);
@ -849,8 +848,8 @@ int iso_md5_write_tag(Ecma119Image *t, int flag)
}
tag_block[l + 32] = '\n';
if (mode == 1 && t->scdbackup_tag_parm[0]) {
if (t->ms_block > 0) {
if (mode == 1 && t->opts->scdbackup_tag_parm[0]) {
if (t->opts->ms_block > 0) {
iso_msg_submit(t->image->id, ISO_SCDBACKUP_TAG_NOT_0, 0, NULL);
} else {
ret = iso_md5_write_scdbackup_tag(t, tag_block, 0);

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2011 Thomas Schmitt
* Copyright (c) 2009 - 2014 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
@ -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:
@ -502,6 +503,30 @@ const char *iso_error_to_msg(int errcode)
return "Too many chained symbolic links";
case ISO_BAD_ISO_FILETYPE:
return "Unrecognized file type in ISO image";
case ISO_NAME_NOT_UCS2:
return "Filename not suitable for character set UCS-2";
case ISO_IMPORT_COLLISION:
return "File name collision during ISO image import";
case ISO_HPPA_PALO_INCOMPL:
return "Incomplete HP-PA PALO boot parameters";
case ISO_HPPA_PALO_OFLOW:
return "HP-PA PALO boot address exceeds 2 GB";
case ISO_HPPA_PALO_NOTREG:
return "HP-PA PALO file is not a data file";
case ISO_HPPA_PALO_CMDLEN:
return "HP-PA PALO command line too long";
case ISO_SYSAREA_PROBLEMS:
return "Problems encountered during inspection of System Area";
case ISO_INQ_SYSAREA_PROP:
return "Unrecognized inquiry for system area property";
case ISO_ALPHA_BOOT_NOTREG:
return "DEC Alpha Boot Loader file is not a data file";
case ISO_NO_KEPT_DATA_SRC:
return "No data source of imported ISO image available";
case ISO_MALFORMED_READ_INTVL:
return "Malformed description string for interval reader";
case ISO_INTVL_READ_PROBLEM:
return "Unreadable file, premature EOF, or failure to seek for interval reader";
default:
return "Unknown error";
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2011 Thomas Schmitt
* Copyright (c) 2009 - 2014 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
@ -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;
}
}
@ -1130,7 +1131,7 @@ int iso_file_get_old_image_lba(IsoFile *file, uint32_t *lba, int flag)
}
*lba = sections[0].block;
free(sections);
return 0;
return 1;
}
@ -1172,20 +1173,27 @@ int iso_node_is_valid_name(const char *name)
/* guard against the empty string or big names... */
if (name[0] == '\0')
return ISO_RR_NAME_RESERVED;
goto rr_reserved;
if (strlen(name) > LIBISOFS_NODE_NAME_MAX)
return ISO_RR_NAME_TOO_LONG;
/* ...against "." and ".." names... */
if (!strcmp(name, ".") || !strcmp(name, "..")) {
return ISO_RR_NAME_RESERVED;
}
if (!strcmp(name, ".") || !strcmp(name, ".."))
goto rr_reserved;
/* ...and against names with '/' */
if (strchr(name, '/') != NULL) {
return ISO_RR_NAME_RESERVED;
}
if (strchr(name, '/') != NULL)
goto rr_reserved;
return 1;
rr_reserved:;
/* # define Libisofs_debug_rr_reserveD */
#ifdef Libisofs_debug_rr_reserveD
fprintf(stderr, "libisofs_DEBUG: ISO_RR_NAME_RESERVED with '%s'\n", name);
#endif
return ISO_RR_NAME_RESERVED;
}
/**
@ -1205,8 +1213,12 @@ int iso_node_is_valid_link_dest(const char *dest)
}
/* guard against the empty string or big dest... */
if (dest[0] == '\0')
if (dest[0] == '\0') {
#ifdef Libisofs_debug_rr_reserveD
fprintf(stderr, "libisofs_DEBUG: ISO_RR_NAME_RESERVED by empty link target\n");
#endif
return ISO_RR_NAME_RESERVED;
}
if (strlen(dest) > LIBISOFS_NODE_PATH_MAX)
return ISO_RR_PATH_TOO_LONG;
@ -1430,6 +1442,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 +2580,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 +2771,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 +2782,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

@ -1,7 +1,7 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2007 Mario Danic
* Copyright (c) 2009 - 2012 Thomas Schmitt
* Copyright (c) 2009 - 2015 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
@ -32,10 +32,16 @@
#define ISO_ROCKRIDGE_IN_DIR_REC 124
#endif
#define ISO_CE_ENTRY_SIZE 28
static
int susp_add_ES(Ecma119Image *t, struct susp_info *susp, int to_ce, int seqno);
static
int susp_make_CE(Ecma119Image *t, uint8_t **CE,
uint32_t block_offset, uint32_t byte_offset, uint32_t size);
static
int susp_append(Ecma119Image *t, struct susp_info *susp, uint8_t *data)
@ -54,14 +60,76 @@ int susp_append(Ecma119Image *t, struct susp_info *susp, uint8_t *data)
static
int susp_append_ce(Ecma119Image *t, struct susp_info *susp, uint8_t *data)
{
susp->n_ce_susp_fields++;
susp->ce_susp_fields = realloc(susp->ce_susp_fields, sizeof(void*)
* susp->n_ce_susp_fields);
if (susp->ce_susp_fields == NULL) {
return ISO_OUT_OF_MEM;
int to_alloc = 1, ret;
unsigned char *pad;
uint8_t *CE;
size_t next_alloc;
if (data[0] &&
(susp->ce_len + data[2] + ISO_CE_ENTRY_SIZE - 1) / BLOCK_SIZE !=
susp->ce_len / BLOCK_SIZE) {
/* Linux fs/isofs wants byte_offset + ce_len <= BLOCK_SIZE.
So this Continuation Area needs to end by a CE which points
to the start of the next block.
*/
to_alloc = 2;
if ((susp->ce_len + ISO_CE_ENTRY_SIZE) % BLOCK_SIZE)
to_alloc = 3; /* need a PAD pseudo entry */
}
if (susp->ce_susp_fields == NULL)
susp->alloc_ce_susp_fields = 0;
if (susp->n_ce_susp_fields + to_alloc > susp->alloc_ce_susp_fields) {
next_alloc = susp->alloc_ce_susp_fields;
while (susp->n_ce_susp_fields + to_alloc > next_alloc)
next_alloc += ISO_SUSP_CE_ALLOC_STEP;
susp->ce_susp_fields = realloc(susp->ce_susp_fields,
sizeof(uint8_t *) * next_alloc);
if (susp->ce_susp_fields == NULL)
return ISO_OUT_OF_MEM;
susp->alloc_ce_susp_fields = next_alloc;
}
if (to_alloc >= 2) {
/* Insert CE entry (actual CE size later by susp_update_CE_sizes) */
ret = susp_make_CE(t, &CE, (uint32_t) (susp->ce_block +
susp->ce_len / BLOCK_SIZE + 1),
(uint32_t) 0, (uint32_t) 2048);
if (ret < 0)
return ret;
susp->ce_susp_fields[susp->n_ce_susp_fields] = CE;
susp->ce_len += ISO_CE_ENTRY_SIZE;
susp->n_ce_susp_fields++;
}
if (to_alloc >= 3) {
#ifdef Libisofs_ce_calc_debuG
fprintf(stderr,
"\nlibburn_DEBUG: Inserting %d bytes of CE padding\n\n",
(int) (BLOCK_SIZE - (susp->ce_len % BLOCK_SIZE)));
#endif /* Libisofs_ce_calc_debuG */
pad = malloc(1);
if (pad == NULL)
return ISO_OUT_OF_MEM;
pad[0] = 0;
susp->ce_susp_fields[susp->n_ce_susp_fields] = pad;
if (susp->ce_len % BLOCK_SIZE)
susp->ce_len += BLOCK_SIZE - (susp->ce_len % BLOCK_SIZE);
susp->n_ce_susp_fields++;
}
susp->ce_susp_fields[susp->n_ce_susp_fields] = data;
susp->n_ce_susp_fields++;
if (data[0] == 0) {
if (susp->ce_len % BLOCK_SIZE)
susp->ce_len += BLOCK_SIZE - (susp->ce_len % BLOCK_SIZE);
} else {
susp->ce_len += data[2];
}
susp->ce_susp_fields[susp->n_ce_susp_fields - 1] = data;
susp->ce_len += data[2];
return ISO_SUCCESS;
}
@ -115,7 +183,7 @@ int rrip_add_PX(Ecma119Image *t, Ecma119Node *n, struct susp_info *susp)
PX[0] = 'P';
PX[1] = 'X';
if (t->rrip_1_10_px_ino || !t->rrip_version_1_10 ) {
if (t->opts->rrip_1_10_px_ino || !t->opts->rrip_version_1_10 ) {
PX[2] = 44;
} else {
PX[2] = 36;
@ -125,7 +193,7 @@ int rrip_add_PX(Ecma119Image *t, Ecma119Node *n, struct susp_info *susp)
iso_bb(&PX[12], (uint32_t) n->nlink, 4);
iso_bb(&PX[20], (uint32_t) px_get_uid(t, n), 4);
iso_bb(&PX[28], (uint32_t) px_get_gid(t, n), 4);
if (t->rrip_1_10_px_ino || !t->rrip_version_1_10) {
if (t->opts->rrip_1_10_px_ino || !t->opts->rrip_version_1_10) {
iso_bb(&PX[36], (uint32_t) n->ino, 4);
}
@ -153,11 +221,11 @@ int rrip_add_TF(Ecma119Image *t, Ecma119Node *n, struct susp_info *susp)
iso = n->node;
iso_datetime_7(&TF[5], t->replace_timestamps ? t->timestamp : iso->mtime,
t->always_gmt);
t->opts->always_gmt);
iso_datetime_7(&TF[12], t->replace_timestamps ? t->timestamp : iso->atime,
t->always_gmt);
t->opts->always_gmt);
iso_datetime_7(&TF[19], t->replace_timestamps ? t->timestamp : iso->ctime,
t->always_gmt);
t->opts->always_gmt);
return susp_append(t, susp, TF);
}
@ -294,29 +362,46 @@ int rrip_add_CL(Ecma119Image *t, Ecma119Node *n, struct susp_info *susp)
/**
* Convert a RR filename to the requested charset. On any conversion error,
* the original name will be used.
* @param flag bit0= do not issue error messages
*/
static
char *get_rr_fname(Ecma119Image *t, const char *str)
int iso_get_rr_name(IsoWriteOpts *opts, char *input_charset,
char *output_charset, int imgid,
char *str, char **name, int flag)
{
int ret;
char *name;
if (!strcmp(t->input_charset, t->output_charset)) {
if (!strcmp(input_charset, output_charset)) {
/* no conversion needed */
return strdup(str);
ret = iso_clone_mem(str, name, 0);
return ret;
}
ret = strconv(str, t->input_charset, t->output_charset, &name);
ret = strconv(str, input_charset, output_charset, name);
if (ret < 0) {
/* TODO we should check for possible cancelation */
iso_msg_submit(t->image->id, ISO_FILENAME_WRONG_CHARSET, ret,
"Charset conversion error. Can't convert %s from %s to %s",
str, t->input_charset, t->output_charset);
if (!(flag & 1))
iso_msg_submit(imgid, ISO_FILENAME_WRONG_CHARSET, ret,
"Charset conversion error. Cannot convert %s from %s to %s",
str, input_charset, output_charset);
/* use the original name, it's the best we can do */
name = strdup(str);
ret = iso_clone_mem(str, name, 0);
return ISO_FILENAME_WRONG_CHARSET;
}
return ISO_SUCCESS;
}
static
char *get_rr_fname(Ecma119Image *t, char *str)
{
int ret;
char *name = NULL;
ret = iso_get_rr_name(t->opts, t->input_charset, t->output_charset,
t->image->id, str, &name, 0);
if (ret < 0)
return NULL;
return name;
}
@ -530,22 +615,56 @@ int rrip_add_SL(Ecma119Image *t, struct susp_info *susp, uint8_t **comp,
}
/* @param flag bit1= care about crossing block boundaries */
static
int susp_calc_add_to_ce(size_t *ce, size_t base_ce, int add, int flag)
{
if (flag & 2) {
/* Account for inserted CE before size exceeds block size */
if ((*ce + base_ce + add + ISO_CE_ENTRY_SIZE - 1) / BLOCK_SIZE !=
(*ce + base_ce) / BLOCK_SIZE) {
/* Insert CE and padding */
*ce += ISO_CE_ENTRY_SIZE;
if ((*ce + base_ce) % BLOCK_SIZE)
*ce += BLOCK_SIZE - ((*ce + base_ce) % BLOCK_SIZE);
}
}
*ce += add;
return ISO_SUCCESS;
}
/*
@param flag bit0= only account sizes in sua_free resp. ce_len
parameters susp and data may be NULL in this case
@param flag bit0= only account sizes in sua_free resp. ce_len.
Parameter susp may be NULL in this case
bit1= account for crossing block boundaries
(implied by bit0 == 0)
@param ce_len counts the freshly added CA size of the current node
@param ce_mem tells the CA size of previous nodes in the same directory
*/
static
int aaip_add_AL(Ecma119Image *t, struct susp_info *susp,
uint8_t **data, size_t num_data,
size_t *sua_free, size_t *ce_len, int flag)
size_t *sua_free, size_t *ce_len, size_t ce_mem, int flag)
{
int ret, done = 0, len, es_extra = 0;
uint8_t *aapt, *cpt;
size_t count = 0;
if (!t->aaip_susp_1_10)
if (!(flag & 1))
flag |= 2;
if (!t->opts->aaip_susp_1_10)
es_extra = 5;
if (*sua_free < num_data + es_extra || *ce_len > 0) {
*ce_len += num_data + es_extra;
if (es_extra > 0)
susp_calc_add_to_ce(ce_len, ce_mem, es_extra, flag & 2);
done = 0;
for (aapt = *data; !done; aapt += aapt[2]) {
done = !(aapt[4] & 1);
len = aapt[2];
susp_calc_add_to_ce(ce_len, ce_mem, len, flag & 2);
count += len;
}
} else {
*sua_free -= num_data + es_extra;
}
@ -553,7 +672,7 @@ int aaip_add_AL(Ecma119Image *t, struct susp_info *susp,
return ISO_SUCCESS;
/* If AAIP enabled and announced by ER : Write ES field to announce AAIP */
if (t->aaip && !t->aaip_susp_1_10) {
if (t->opts->aaip && !t->opts->aaip_susp_1_10) {
ret = susp_add_ES(t, susp, (*ce_len > 0), 1);
if (ret < 0)
return ret;
@ -571,6 +690,7 @@ int aaip_add_AL(Ecma119Image *t, struct susp_info *susp,
}
/* Multiple fields have to be handed over as single field copies */
done = 0;
for (aapt = *data; !done; aapt += aapt[2]) {
done = !(aapt[4] & 1);
len = aapt[2];
@ -606,7 +726,7 @@ int rrip_add_ER(Ecma119Image *t, struct susp_info *susp)
{
unsigned char *ER;
if (!t->rrip_version_1_10) {
if (!t->opts->rrip_version_1_10) {
/*
According to RRIP 1.12 this is the future form:
4.3 "Specification of the ER System Use Entry Values for RRIP"
@ -705,6 +825,35 @@ int aaip_add_ER(Ecma119Image *t, struct susp_info *susp, int flag)
}
/**
* Create the byte representation of a CE entry.
* (SUSP, 5.1).
*/
static
int susp_make_CE(Ecma119Image *t, uint8_t **CE,
uint32_t block_offset, uint32_t byte_offset, uint32_t size)
{
uint8_t *data;
*CE = NULL;
data = calloc(1, 28);
if (data == NULL)
return ISO_OUT_OF_MEM;
*CE = data;
data[0] = 'C';
data[1] = 'E';
data[2] = 28;
data[3] = 1;
iso_bb(&data[4], block_offset - t->eff_partition_offset, 4);
iso_bb(&data[12], byte_offset, 4);
iso_bb(&data[20], size, 4);
return ISO_SUCCESS;
}
/**
* Add a CE System Use Entry to the given tree node. A "CE" is used to add
* a continuation area, where additional System Use Entry can be written.
@ -713,20 +862,18 @@ int aaip_add_ER(Ecma119Image *t, struct susp_info *susp, int flag)
static
int susp_add_CE(Ecma119Image *t, size_t ce_len, struct susp_info *susp)
{
uint8_t *CE = malloc(28);
if (CE == NULL) {
return ISO_OUT_OF_MEM;
}
CE[0] = 'C';
CE[1] = 'E';
CE[2] = 28;
CE[3] = 1;
iso_bb(&CE[4], susp->ce_block - t->eff_partition_offset, 4);
iso_bb(&CE[12], susp->ce_len, 4);
iso_bb(&CE[20], (uint32_t) ce_len, 4);
uint32_t block_offset, byte_offset;
uint8_t *CE;
int ret;
/* Linux fs/isofs wants byte_offset + ce_len <= BLOCK_SIZE
* Here the byte_offset is reduced to the minimum.
*/
block_offset = susp->ce_block + susp->ce_len / BLOCK_SIZE;
byte_offset = susp->ce_len % BLOCK_SIZE;
ret = susp_make_CE(t, &CE, block_offset, byte_offset, (uint32_t) ce_len);
if (ret < 0)
return ret;
return susp_append(t, susp, CE);
}
@ -782,6 +929,27 @@ int susp_add_ES(Ecma119Image *t, struct susp_info *susp, int to_ce, int seqno)
}
/**
* A field beginning by 0 causes rrip_write_ce_fields() to pad up to the
* next block.
*/
static
int pseudo_susp_add_PAD(Ecma119Image *t, struct susp_info *susp)
{
unsigned char *pad;
int ret;
pad = malloc(1);
if (pad == NULL)
return ISO_OUT_OF_MEM;
pad[0] = 0;
ret = susp_append_ce(t, susp, pad);
if (ret < 0)
return ret;
return ISO_SUCCESS;
}
/**
* see doc/zisofs_format.txt : "ZF System Use Entry Format"
*/
@ -813,10 +981,12 @@ int zisofs_add_ZF(Ecma119Image *t, struct susp_info *susp, int to_ce,
/* @param flag bit0= Do not add data but only count sua_free and ce_len
bit1= account for crossing block boundaries
(implied by bit0 == 0)
*/
static
int add_zf_field(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
size_t *sua_free, size_t *ce_len, int flag)
size_t *sua_free, size_t *ce_len, size_t base_ce, int flag)
{
int ret, will_copy = 1, stream_type = 0, do_zf = 0;
int header_size_div4 = 0, block_size_log2 = 0;
@ -832,6 +1002,8 @@ int add_zf_field(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
int *header_size_div4, int *block_size_log2,
uint32_t *uncompressed_size, int flag);
if (!(flag & 1))
flag |= 2;
if (iso_node_get_type(n->node) != LIBISO_FILE)
return 2;
@ -851,7 +1023,7 @@ int add_zf_field(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
zisofs file header when inquired)
*/
if (t->appendable && file->from_old_session)
if (t->opts->appendable && file->from_old_session)
will_copy = 0;
first_filter = first_stream = last_stream = iso_file_get_stream(file);
@ -905,7 +1077,7 @@ int add_zf_field(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
/* Account for field size */
if (*sua_free < 16 || *ce_len > 0) {
*ce_len += 16;
susp_calc_add_to_ce(ce_len, base_ce, 16, flag & 2);
} else {
*sua_free -= 16;
}
@ -953,10 +1125,15 @@ int aaip_xinfo_cloner(void *old_data, void **new_data, int flag)
* a CE entry of 28 bytes in SUA, this computation fails if not the 28 bytes
* are taken into account at start. In this case the caller should retry with
* bit0 set.
* If the resulting *ce added to base_ce is in a different block than base_ce,
* then computation with bit0 fails and the caller should finally try bit1.
*
* @param flag bit0= assume CA usage (else return 0 on SUA overflow)
* bit1= let CA start at block start (else return 0 if
* *ce crosses a block boundary)
* @return 1= ok, computation of *su_size and *ce is valid
* 0= not ok, CA usage is necessary but bit0 was not set
* or *ce crosses boundary and bit1 was not set
* (*su_size and *ce stay unaltered in this case)
* <0= error:
* -1= not enough SUA space for 28 bytes of CE entry
@ -964,19 +1141,44 @@ int aaip_xinfo_cloner(void *old_data, void **new_data, int flag)
*/
static
int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
size_t *su_size, size_t *ce, int flag)
size_t *su_size, size_t *ce, size_t base_ce, int flag)
{
char *name;
size_t namelen, su_mem, ce_mem;
void *xipt;
size_t num_aapt = 0, sua_free = 0;
int ret;
uint8_t *aapt;
#ifdef Libisofs_ce_calc_debug_extrA
if (n->node->name != NULL)
fprintf(stderr, "libburn_DEBUG: susp_calc_nm_sl_al : %.f %s \n",
(double) base_ce, n->node->name);
#endif /* Libisofs_ce_calc_debug_extrA */
su_mem = *su_size;
ce_mem = *ce;
if (*ce > 0 && !(flag & 1))
goto unannounced_ca;
if (flag & 2) {
flag |= 1;
if (base_ce % BLOCK_SIZE) {
#ifdef Libisofs_ce_calc_debuG
fprintf(stderr,
"\nlibburn_DEBUG: Accounting for %d bytes CE padding : %s\n\n",
(int) (BLOCK_SIZE - (base_ce % BLOCK_SIZE)), n->node->name);
#endif /* Libisofs_ce_calc_debuG */
*ce += BLOCK_SIZE - (base_ce % BLOCK_SIZE);
}
}
name = get_rr_fname(t, n->node->name);
namelen = strlen(name);
free(name);
@ -1003,7 +1205,7 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
of the name will always fit into the directory entry.)
*/;
*ce = 5 + namelen;
susp_calc_add_to_ce(ce, base_ce, 5 + namelen, flag & 2);
*su_size = space;
}
if (n->type == ECMA119_SYMLINK) {
@ -1073,21 +1275,26 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
* the component can be divided between this
* and another SL entry
*/
*ce += 255; /* this SL, full */
sl_len = 5 + (clen - fit);
/* Will fill up old SL and write it */
susp_calc_add_to_ce(ce, base_ce, 255, flag & 2);
sl_len = 5 + (clen - fit); /* Start new SL */
} else {
/*
* the component will need a 2rd SL entry in
* any case, so we prefer to don't write
* anything in this SL
*/
*ce += sl_len + 255;
sl_len = 5 + (clen - 250) + 2;
/* Will write non-full old SL */
susp_calc_add_to_ce(ce, base_ce, sl_len, flag & 2);
/* Will write another full SL */
susp_calc_add_to_ce(ce, base_ce, 255, flag & 2);
sl_len = 5 + (clen - 250) + 2; /* Start new SL */
}
} else {
/* case 2, create a new SL entry */
*ce += sl_len;
sl_len = 5 + clen;
/* Will write non-full old SL */
susp_calc_add_to_ce(ce, base_ce, sl_len, flag & 2);
sl_len = 5 + clen; /* Start new SL */
}
} else {
sl_len += clen;
@ -1109,14 +1316,14 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
/* the whole SL fits into the SUA */
*su_size += sl_len;
} else {
*ce += sl_len;
susp_calc_add_to_ce(ce, base_ce, sl_len, flag & 2);
}
}
/* Find out whether ZF is to be added and account for its bytes */
sua_free = space - *su_size;
add_zf_field(t, n, NULL, &sua_free, ce, 1);
add_zf_field(t, n, NULL, &sua_free, ce, base_ce, 1 | (flag & 2));
*su_size = space - sua_free;
if (*ce > 0 && !(flag & 1))
goto unannounced_ca;
@ -1124,7 +1331,7 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
/* obtain num_aapt from node */
xipt = NULL;
num_aapt = 0;
if (t->aaip) {
if (t->opts->aaip) {
ret = iso_node_get_xinfo(n->node, aaip_xinfo_func, &xipt);
if (ret == 1) {
num_aapt = aaip_count_bytes((unsigned char *) xipt, 0);
@ -1133,12 +1340,46 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
/* let the expert decide where to add num_aapt */
if (num_aapt > 0) {
sua_free = space - *su_size;
aaip_add_AL(t, NULL, NULL, num_aapt, &sua_free, ce, 1);
aapt = (uint8_t *) xipt;
aaip_add_AL(t, NULL, &aapt, num_aapt, &sua_free, ce, base_ce,
1 | (flag & 2));
*su_size = space - sua_free;
if (*ce > 0 && !(flag & 1))
goto unannounced_ca;
}
#ifdef Libisofs_ce_calc_debug_filetraP
if (n->node->name != NULL)
if (strcmp(n->node->name, "...insert.leaf.name.here...") == 0)
fprintf(stderr,
"libburn_DEBUG: filename breakpoint susp_calc_nm_sl_al\n");
#endif /* Libisofs_ce_calc_debug_filetraP */
if (*ce > 0 && !(flag & 2)) {
if (base_ce / BLOCK_SIZE !=
(base_ce + *ce + ISO_CE_ENTRY_SIZE - 1) / BLOCK_SIZE) {
#ifdef Libisofs_ce_calc_debuG
fprintf(stderr,
"\nlibburn_DEBUG: Crossed block boundary: %.f (%lu) -> %.f (%lu) : %s\n\n",
(double) base_ce, (unsigned long) (base_ce / BLOCK_SIZE),
(double) (base_ce + *ce - 1),
(unsigned long)
((base_ce + *ce + ISO_CE_ENTRY_SIZE - 1) / BLOCK_SIZE),
n->node->name);
#endif /* Libisofs_ce_calc_debuG */
/* Crossed a block boundary */
*su_size = su_mem;
*ce = ce_mem;
return 0;
}
}
return 1;
unannounced_ca:;
@ -1150,17 +1391,19 @@ unannounced_ca:;
/* @param flag bit0= Do not add data but only count sua_free and ce_len
param info may be NULL in this case
bit1= account for crossing block boundaries
(implied by bit0 == 0)
*/
static
int add_aa_string(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
size_t *sua_free, size_t *ce_len, int flag)
size_t *sua_free, size_t *ce_len, size_t base_ce, int flag)
{
int ret;
uint8_t *aapt;
void *xipt;
size_t num_aapt= 0;
if (!t->aaip)
if (!t->opts->aaip)
return 1;
ret = iso_node_get_xinfo(n->node, aaip_xinfo_func, &xipt);
@ -1168,18 +1411,20 @@ int add_aa_string(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
num_aapt = aaip_count_bytes((unsigned char *) xipt, 0);
if (num_aapt > 0) {
if (flag & 1) {
ret = aaip_add_AL(t, NULL,NULL, num_aapt, sua_free, ce_len, 1);
aapt = (unsigned char *) xipt;
ret = aaip_add_AL(t, NULL, &aapt, num_aapt, sua_free, ce_len,
base_ce, flag & (1 | 2));
} else {
aapt = malloc(num_aapt);
if (aapt == NULL)
return ISO_OUT_OF_MEM;
memcpy(aapt, xipt, num_aapt);
ret = aaip_add_AL(t, info, &aapt, num_aapt, sua_free, ce_len,
0);
base_ce, 0);
/* aapt is NULL now and the memory is owned by t */
}
if (ret < 0)
return ret;
/* aapt is NULL now and the memory is owned by t */
}
}
return 1;
@ -1197,11 +1442,13 @@ int add_aa_string(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
* Already occupied space in the directory record.
* @param ce
* Will be filled with the space needed in a CE
* @param base_ce
* Predicted fill of continuation area by previous nodes of same dir
* @return
* The size needed for the RR entries in the System Use Area
*/
size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t used_up,
size_t *ce)
size_t *ce, size_t base_ce)
{
size_t su_size, space;
int ret;
@ -1221,7 +1468,7 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t used_up,
su_size = 0;
/* If AAIP enabled and announced by ER : account for 5 bytes of ES */;
if (t->aaip && !t->aaip_susp_1_10)
if (t->opts->aaip && !t->opts->aaip_susp_1_10)
su_size += 5;
#ifdef Libisofs_with_rrip_rR
@ -1230,7 +1477,7 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t used_up,
#endif
/* PX and TF, we are sure they always fit in SUA */
if (t->rrip_1_10_px_ino || !t->rrip_version_1_10) {
if (t->opts->rrip_1_10_px_ino || !t->opts->rrip_version_1_10) {
su_size += 44 + 26;
} else {
su_size += 36 + 26;
@ -1247,7 +1494,7 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t used_up,
su_size += 4;
}
} else if(ecma119_is_dedicated_reloc_dir(t, n) &&
(t->rr_reloc_flags & 1)) {
(t->opts->rr_reloc_flags & 1)) {
/* The dedicated relocation directory shall be marked by RE */
su_size += 4;
}
@ -1264,9 +1511,11 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t used_up,
if (type == 0) {
/* Try without CE */
ret = susp_calc_nm_sl_al(t, n, space, &su_size, ce, 0);
if (ret == 0) /* Retry with CE */
ret = susp_calc_nm_sl_al(t, n, space, &su_size, ce, 1);
ret = susp_calc_nm_sl_al(t, n, space, &su_size, ce, base_ce, 0);
if (ret == 0) /* Retry with CE but no block crossing */
ret = susp_calc_nm_sl_al(t, n, space, &su_size, ce, base_ce, 1);
if (ret == 0) /* Retry with aligned CE and block hopping */
ret = susp_calc_nm_sl_al(t, n, space, &su_size, ce, base_ce, 1 | 2);
if (ret == -2)
return ISO_OUT_OF_MEM;
@ -1274,7 +1523,7 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t used_up,
/* "." or ".." entry */
if (!t->rrip_version_1_10)
if (!t->opts->rrip_version_1_10)
su_size += 5; /* NM field */
if (type == 1 && n->parent == NULL) {
@ -1285,17 +1534,21 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t used_up,
*/
su_size += 7 + 28; /* SP + CE */
/* ER of RRIP */
if (t->rrip_version_1_10) {
if (t->opts->rrip_version_1_10) {
*ce = 237;
} else {
*ce = 182;
}
if (t->aaip && !t->aaip_susp_1_10) {
if (t->opts->aaip && !t->opts->aaip_susp_1_10) {
*ce += 160; /* ER of AAIP */
}
/* Compute length of AAIP string of root node */
/* Compute length of AAIP string of root node.
Will write all AIIP to CA, which already starts at
block boundary. So no need for three tries.
*/
aaip_sua_free= 0;
ret = add_aa_string(t, n, NULL, &aaip_sua_free, &aaip_len, 1);
ret = add_aa_string(t, n, NULL, &aaip_sua_free, &aaip_len, base_ce,
1 | 2);
if (ret < 0)
return ret;
*ce += aaip_len;
@ -1359,7 +1612,7 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
size_t rrip_er_len= 182;
size_t su_size_pd, ce_len_pd; /* predicted sizes of SUA and CA */
int ce_is_predicted = 0;
size_t aaip_sua_free= 0, aaip_len= 0;
size_t aaip_sua_free= 0, aaip_len= 0, ce_mem;
int space;
if (t == NULL || n == NULL || info == NULL) {
@ -1376,6 +1629,18 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
return ISO_ASSERT_FAILURE;
}
/* Mark start index of node's continuation area for later update */
info->current_ce_start = info->n_ce_susp_fields;
ce_mem = info->ce_len;
#ifdef Libisofs_ce_calc_debug_filetraP
if (n->node->name != NULL)
if (strcmp(n->node->name, "...put.leafname.here...") == 0)
fprintf(stderr, "libburn_DEBUG: filename breakpoint\n");
#endif /* Libisofs_ce_calc_debug_filetraP */
if (type == 2 && n->parent != NULL) {
node = n->parent;
} else {
@ -1394,7 +1659,7 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
}
/* If AAIP enabled and announced by ER : Announce RRIP by ES */
if (t->aaip && !t->aaip_susp_1_10) {
if (t->opts->aaip && !t->opts->aaip_susp_1_10) {
ret = susp_add_ES(t, info, 0, 0);
if (ret < 0)
goto add_susp_cleanup;
@ -1437,7 +1702,7 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
}
}
} else if(ecma119_is_dedicated_reloc_dir(t, n) &&
(t->rr_reloc_flags & 1)) {
(t->opts->rr_reloc_flags & 1)) {
/* The dedicated relocation directory shall be marked by RE */
ret = rrip_add_RE(t, node, info);
if (ret < 0)
@ -1485,10 +1750,14 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
su_size_pd = info->suf_len;
ce_len_pd = ce_len;
ret = susp_calc_nm_sl_al(t, n, (size_t) space,
&su_size_pd, &ce_len_pd, 0);
&su_size_pd, &ce_len_pd, info->ce_len, 0);
if (ret == 0) { /* Have to use CA. 28 bytes of CE are necessary */
ret = susp_calc_nm_sl_al(t, n, (size_t) space,
&su_size_pd, &ce_len_pd, 1);
&su_size_pd, &ce_len_pd, info->ce_len, 1);
if (ret == 0) /* Retry with aligned CE and block hopping */
ret = susp_calc_nm_sl_al(t, n, (size_t) space,
&su_size_pd, &ce_len_pd, info->ce_len,
1 | 2);
sua_free -= 28;
ce_is_predicted = 1;
}
@ -1682,6 +1951,26 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
}
if (ce_is_predicted) {
if ((info->ce_len % BLOCK_SIZE) &&
(info->ce_len + ce_len_pd - 1 ) / BLOCK_SIZE !=
info->ce_len / BLOCK_SIZE) {
/* Linux fs/isofs wants byte_offset + ce_len <= BLOCK_SIZE
* Insert padding to shift CE offset to next block start
*/
#ifdef Libisofs_ce_calc_debuG
fprintf(stderr,
"\nlibburn_DEBUG: Inserting %d bytes of CE padding : %s\n\n",
(int) (BLOCK_SIZE - (info->ce_len % BLOCK_SIZE)),
n->node->name);
#endif /* Libisofs_ce_calc_debuG */
ret = pseudo_susp_add_PAD(t, info);
if (ret < 0)
goto add_susp_cleanup;
}
/* Add the CE entry */
ret = susp_add_CE(t, ce_len_pd, info);
if (ret < 0) {
@ -1723,14 +2012,14 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
}
/* Eventually write zisofs ZF field */
ret = add_zf_field(t, n, info, &sua_free, &ce_len, 0);
ret = add_zf_field(t, n, info, &sua_free, &ce_len, ce_mem, 0);
if (ret < 0)
goto add_susp_cleanup;
/* Eventually obtain AAIP field string from node
and write it to directory entry or CE area.
*/
ret = add_aa_string(t, n, info, &sua_free, &ce_len, 0);
ret = add_aa_string(t, n, info, &sua_free, &ce_len, ce_mem, 0);
if (ret < 0)
goto add_susp_cleanup;
@ -1740,7 +2029,7 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
/* "." or ".." entry */
/* write the NM entry */
if (t->rrip_version_1_10) {
if (t->opts->rrip_version_1_10) {
/* RRIP-1.10:
"NM" System Use Fields recorded for the ISO 9660 directory
records with names (00) and (01), used to designate the
@ -1780,18 +2069,19 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
* Note that SP entry was already added above
*/
if (t->rrip_version_1_10) {
if (t->opts->rrip_version_1_10) {
rrip_er_len = 237;
} else {
rrip_er_len = 182;
}
if (t->aaip && !t->aaip_susp_1_10) {
if (t->opts->aaip && !t->opts->aaip_susp_1_10) {
aaip_er_len = 160;
}
/* Compute length of AAIP string of root node */
aaip_sua_free= 0;
ret = add_aa_string(t, n, NULL, &aaip_sua_free, &aaip_len, 1);
ret = add_aa_string(t, n, NULL, &aaip_sua_free, &aaip_len, ce_mem,
1 | 2);
if (ret < 0)
goto add_susp_cleanup;
@ -1804,7 +2094,7 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
if (ret < 0) {
goto add_susp_cleanup;
}
if (t->aaip && !t->aaip_susp_1_10) {
if (t->opts->aaip && !t->opts->aaip_susp_1_10) {
ret = aaip_add_ER(t, info, 0);
if (ret < 0) {
goto add_susp_cleanup;
@ -1812,7 +2102,8 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
}
/* Write AAIP string of root node */
aaip_sua_free= aaip_len= 0;
ret = add_aa_string(t, n, info, &aaip_sua_free, &aaip_len, 0);
ret = add_aa_string(t, n, info, &aaip_sua_free, &aaip_len, ce_mem,
0);
if (ret < 0)
goto add_susp_cleanup;
@ -1837,6 +2128,55 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
return ret;
}
/* Update the sizes of CE fields at end of info->susp_fields and in
single node range of info->ce_susp_fields.
*/
static
int susp_update_CE_sizes(Ecma119Image *t, struct susp_info *info, int flag)
{
size_t i, curr_pos;
uint8_t *curr_ce;
uint32_t size;
if (info->n_susp_fields == 0 ||
info->n_ce_susp_fields - info->current_ce_start == 0)
return ISO_SUCCESS;
for (i = 0; i < info->n_susp_fields; i++)
if (info->susp_fields[i][0] == 'C')
if(info->susp_fields[i][1] == 'E')
break;
if (i >= info->n_susp_fields) {
iso_msg_submit(t->image->id, ISO_ASSERT_FAILURE, 0,
"System Use Area field contains no CE, but there are fields in Continuation Area");
return ISO_ASSERT_FAILURE;
}
curr_ce = info->susp_fields[i];
curr_pos = 0;
for (i = info->current_ce_start; i < info->n_ce_susp_fields; i++) {
if (info->ce_susp_fields[i][0] == 0) {
curr_pos = 0; /* pseudo SUSP PAD */
continue;
}
if (info->ce_susp_fields[i][0] == 'C' &&
info->ce_susp_fields[i][1] == 'E') {
size = (curr_pos + info->ce_susp_fields[i][2]) % BLOCK_SIZE;
if (size == 0)
size = BLOCK_SIZE;
iso_bb(curr_ce + 20, size, 4);
curr_ce = info->ce_susp_fields[i];
}
curr_pos = (curr_pos + info->ce_susp_fields[i][2]) % 2048;
}
if (curr_pos > 0) {
size = curr_pos % BLOCK_SIZE;
iso_bb(curr_ce + 20, size, 4);
}
return ISO_SUCCESS;
}
/**
* Write the given SUSP fields into buf. Note that Continuation Area
* fields are not written.
@ -1849,11 +2189,16 @@ void rrip_write_susp_fields(Ecma119Image *t, struct susp_info *info,
{
size_t i;
size_t pos = 0;
int ret;
if (info->n_susp_fields == 0) {
return;
}
ret = susp_update_CE_sizes(t, info, 0);
if (ret < 0)
return;
for (i = 0; i < info->n_susp_fields; i++) {
memcpy(buf + pos, info->susp_fields[i], info->susp_fields[i][2]);
pos += info->susp_fields[i][2];
@ -1879,6 +2224,7 @@ int rrip_write_ce_fields(Ecma119Image *t, struct susp_info *info)
size_t i;
uint8_t *padding = NULL;
int ret= ISO_SUCCESS;
uint64_t written = 0, pad_size;
if (info->n_ce_susp_fields == 0) {
goto ex;
@ -1886,11 +2232,24 @@ int rrip_write_ce_fields(Ecma119Image *t, struct susp_info *info)
LIBISO_ALLOC_MEM(padding, uint8_t, BLOCK_SIZE);
for (i = 0; i < info->n_ce_susp_fields; i++) {
if (info->ce_susp_fields[i][0] == 0) {
/* Pseudo field: pad up to next block boundary */
pad_size = BLOCK_SIZE - (written % BLOCK_SIZE);
if (pad_size == BLOCK_SIZE)
continue;
memset(padding, 0, pad_size);
ret = iso_write(t, padding, pad_size);
if (ret < 0)
goto write_ce_field_cleanup;
written += pad_size;
continue;
}
ret = iso_write(t, info->ce_susp_fields[i],
info->ce_susp_fields[i][2]);
if (ret < 0) {
goto write_ce_field_cleanup;
}
written += info->ce_susp_fields[i][2];
}
/* pad continuation area until block size */
@ -1898,6 +2257,9 @@ int rrip_write_ce_fields(Ecma119Image *t, struct susp_info *info)
if (i > 0 && i < BLOCK_SIZE) {
memset(padding, 0, i);
ret = iso_write(t, padding, i);
if (ret < 0)
goto write_ce_field_cleanup;
written += i;
}
write_ce_field_cleanup: ;
@ -1908,6 +2270,7 @@ int rrip_write_ce_fields(Ecma119Image *t, struct susp_info *info)
free(info->ce_susp_fields);
info->ce_susp_fields = NULL;
info->n_ce_susp_fields = 0;
info->alloc_ce_susp_fields = 0;
info->ce_len = 0;
ex:;
LIBISO_FREE_MEM(padding);

View File

@ -1,7 +1,7 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2007 Mario Danic
* Copyright (c) 2009 Thomas Schmitt
* Copyright (c) 2009 - 2015 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
@ -63,10 +63,22 @@ struct susp_info
uint32_t ce_block;
uint32_t ce_len;
/* Storage for Continuation Area for a whole directory */
size_t n_ce_susp_fields;
uint8_t **ce_susp_fields;
/* The number of allocated members in ce_susp_fields */
size_t alloc_ce_susp_fields;
/* Marks the start index in ce_susp_fields of the current node */
size_t current_ce_start;
};
/* Step to increase allocated size of susp_info.ce_susp_fields */
#define ISO_SUSP_CE_ALLOC_STEP 16
/* SUSP 5.1 */
struct susp_CE {
uint8_t block[8];
@ -186,11 +198,13 @@ struct susp_sys_user_entry
* Available space in the System Use Area for the directory record.
* @param ce
* Will be filled with the space needed in a CE
* @param base_ce
* Fill of continuation area by previous nodes of same dir
* @return
* The size needed for the RR entries in the System Use Area
*/
size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t space,
size_t *ce);
size_t *ce, size_t base_ce);
/**
* Fill a struct susp_info with the RR/SUSP entries needed for a given
@ -346,4 +360,13 @@ int read_zisofs_ZF(struct susp_sys_user_entry *zf, uint8_t algorithm[2],
uint8_t *header_size_div4, uint8_t *block_size_log2,
uint32_t *uncompressed_size, int flag);
/**
* Convert a RR filename to the requested charset. On any conversion error,
* the original name will be used.
* @param flag bit0= do not issue error messages
*/
int iso_get_rr_name(IsoWriteOpts *opts, char *input_charset,
char *output_charset, int imgid,
char *str, char **name, int flag);
#endif /* LIBISO_ROCKRIDGE_H */

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2011 Thomas Schmitt
* Copyright (c) 2009 - 2015 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
@ -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)
@ -933,12 +943,22 @@ ex:;
return path;
}
/* @return 1 = ok , 0 = not an ISO image stream , <0 = error */
/*
@param flag bit0= in case of filter stream do not dig for base stream
@return 1 = ok , 0 = not an ISO image stream , <0 = error
*/
int iso_stream_set_image_ino(IsoStream *stream, ino_t ino, int flag)
{
IsoStream *base_stream;
if (stream == NULL) {
return ISO_NULL_POINTER;
}
if (!(flag & 1)) {
base_stream = iso_stream_get_input_stream(stream, 1);
if (base_stream != NULL)
stream = base_stream;
}
if (stream->class == &fsrc_stream_class) {
FSrcStreamData *fsrc_data = stream->data;
fsrc_data->ino_id = ino;
@ -947,6 +967,23 @@ int iso_stream_set_image_ino(IsoStream *stream, ino_t ino, int flag)
return 0;
}
int iso_stream_cmp_ifs_sections(IsoStream *s1, IsoStream *s2, int *cmp_ret,
int flag)
{
int ret;
FSrcStreamData *fssd1, *fssd2;
if (s1->class != &fsrc_stream_class || s2->class != &fsrc_stream_class)
return 0;
/* Compare eventual image data section LBA and sizes */
fssd1= (FSrcStreamData *) s1->data;
fssd2= (FSrcStreamData *) s2->data;
ret = iso_ifs_sections_cmp(fssd1->src, fssd2->src, cmp_ret, 0);
if (ret <= 0)
return 0;
return 1;
}
/* API */
int iso_stream_cmp_ino(IsoStream *s1, IsoStream *s2, int flag)
{
@ -955,8 +992,6 @@ int iso_stream_cmp_ino(IsoStream *s1, IsoStream *s2, int flag)
dev_t dev_id1, dev_id2;
ino_t ino_id1, ino_id2;
off_t size1, size2;
FSrcStreamData *fssd1, *fssd2;
/*
#define Libisofs_stream_cmp_ino_debuG 1
@ -973,6 +1008,9 @@ int iso_stream_cmp_ino(IsoStream *s1, IsoStream *s2, int flag)
if (s2 == NULL)
return 1;
if (iso_stream_cmp_ifs_sections(s1, s2, &ret, 0) > 0)
return ret; /* Both are unfiltered from loaded ISO filesystem */
if (s1->class->version >= 3 && !(flag & 1)) {
/* Filters may have smarter methods to compare themselves with others */
ret = s1->class->cmp_ino(s1, s2);
@ -1032,14 +1070,6 @@ int iso_stream_cmp_ino(IsoStream *s1, IsoStream *s2, int flag)
if (s1->class != s2->class)
return (s1->class < s2->class ? -1 : 1);
if (s1->class == &fsrc_stream_class) {
/* Compare eventual image data section LBA and sizes */
fssd1= (FSrcStreamData *) s1->data;
fssd2= (FSrcStreamData *) s2->data;
ret = iso_ifs_sections_cmp(fssd1->src, fssd2->src, 0);
if (ret != 0)
return ret;
}
if (fs_id1 == 0 && dev_id1 == 0 && ino_id1 == 0) {
return (s1 < s2 ? -1 : 1);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2008 Vreixo Formoso
* Copyright (c) 2012 Thomas Schmitt
* Copyright (c) 2012 - 2015 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,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;
@ -108,14 +108,16 @@ struct iso_mbr_partition_request {
I.e. after the call the submitted storage of req can be disposed or re-used.
Submit 0 as value flag.
*/
int iso_register_mbr_entry(Ecma119Image *t,
int iso_register_mbr_entry(struct iso_mbr_partition_request **req_array,
int *mbr_req_count,
struct iso_mbr_partition_request *req, int flag);
/* Convenience frontend for iso_register_mbr_entry().
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,
int iso_quick_mbr_entry(struct iso_mbr_partition_request **req_array,
int *mbr_req_count,
uint64_t start_block, uint64_t block_count,
uint8_t type_byte, uint8_t status_byte,
int desired_slot);
@ -125,12 +127,13 @@ int iso_quick_mbr_entry(Ecma119Image *t,
Return value is 0 if occupied, 1 if free, and -1 if the slot number is
out of range.
*/
int iso_mbr_entry_slot_is_free(Ecma119Image *t, int slot);
int iso_mbr_entry_slot_is_free(struct iso_mbr_partition_request **req_array,
int mbr_req_count, int slot);
/* The parameter struct for production of a single Apple Partition Map entry.
See also the partial APM description in doc/boot_sectors.txt.
The list of entries is stored in Ecma119Image.apm_req.
The list of entries is stored e.g. in Ecma119Image.apm_req, .apm_req_count.
The size of a block can be chosen by setting Ecma119Image.apm_block_size.
If an entry has start_block <=1, then its block_count will be adjusted
to the final size of the partition map.
@ -144,8 +147,8 @@ struct iso_apm_partition_request {
/* Given in blocks of 2 KiB unless (Ecma119Image.apm_req_flags & 4).
Written to the ISO image according to Ecma119Image.apm_block_size.
*/
uint32_t start_block;
uint32_t block_count;
uint64_t start_block;
uint64_t block_count;
/* All 32 bytes get copied to the system area.
Take care to pad up short strings by 0.
@ -158,20 +161,17 @@ struct iso_apm_partition_request {
I.e. after the call the submitted storage of req can be disposed or re-used.
Submit 0 as value flag.
*/
int iso_register_apm_entry(Ecma119Image *t,
int iso_register_apm_entry(struct iso_apm_partition_request **req_array,
int *apm_req_count,
struct iso_apm_partition_request *req, int flag);
/* Convenience frontend for iso_register_apm_entry().
name and type are 0-terminated strings, which may get silently truncated.
*/
int iso_quick_apm_entry(Ecma119Image *t,
uint32_t start_block, uint32_t block_count, char *name, char *type);
/* CRC-32 as of GPT and Ethernet.
*/
unsigned int iso_crc32_gpt(unsigned char *data, int count, int flag);
int iso_quick_apm_entry(struct iso_apm_partition_request **req_array,
int *apm_req_count,
uint32_t start_block, uint32_t block_count,
char *name, char *type);
/* These two pseudo-random generators produce byte strings which will
surely not duplicate in the first 256 calls. If more calls are necessary
@ -206,11 +206,10 @@ void iso_random_uuid(Ecma119Image *t, uint8_t uuid[16]);
*/
struct iso_gpt_partition_request {
/* Always given in blocks of 2 KiB.
Written to the ISO image in blocks of 512.
/* Always given in blocks of 512 bytes.
*/
uint32_t start_block;
uint32_t block_count;
uint64_t start_block;
uint64_t block_count;
/* The registered GUID which defines the partition type */
uint8_t type_guid[16];
@ -231,20 +230,26 @@ struct iso_gpt_partition_request {
Take care to pad up short strings by 0.
*/
uint8_t name[72];
/* Only if read from imported image: Table index of partition (first = 1)
*/
uint32_t idx;
};
/* Copies the content of req and registers it in t.gpt_req[].
I.e. after the call the submitted storage of req can be disposed or re-used.
Submit 0 as value flag.
*/
int iso_register_gpt_entry(Ecma119Image *t,
int iso_register_gpt_entry(struct iso_gpt_partition_request **req_array,
int *gpt_req_count,
struct iso_gpt_partition_request *req, int flag);
/* Convenience frontend for iso_register_gpt_entry().
name has to be already encoded as UTF-16LE.
*/
int iso_quick_gpt_entry(Ecma119Image *t,
uint32_t start_block, uint32_t block_count,
int iso_quick_gpt_entry(struct iso_gpt_partition_request **req_array,
int *gpt_req_count,
uint64_t start_block, uint64_t block_count,
uint8_t type_guid[16], uint8_t partition_guid[16],
uint64_t flags, uint8_t name[72]);
@ -255,15 +260,61 @@ int iso_write_gpt_header_block(Ecma119Image *t, uint32_t img_blocks,
uint8_t *buf, uint32_t max_entries,
uint32_t part_start, uint32_t p_arr_crc);
/* The description of a loaded MIPS Big Endian Volume Directory Entry
*/
struct iso_mips_voldir_entry {
char name[9];
uint32_t boot_block;
uint32_t boot_bytes;
};
/* The description of a loaded SUN Disk Label partition */
struct iso_sun_disk_label_entry {
int idx;
uint16_t id_tag;
uint16_t permissions;
uint32_t start_cyl;
uint32_t num_blocks;
};
/* Creates the Partition Prepend writer.
*/
int partprepend_writer_create(Ecma119Image *target);
/* Creates the Inline Partition Append Writer
*/
int partappend_writer_create(Ecma119Image *target);
/* Creates the GPT backup tail writer.
*/
int gpt_tail_writer_create(Ecma119Image *target);
/* Not for execution but only to identify the writer by
( writer->write_vol_desc == gpt_tail_writer_write_vol_desc )
*/
int gpt_tail_writer_write_vol_desc(IsoImageWriter *writer);
/* 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
/* >>> It is unclear whether there is a use case for appended partitions
inside the ISO filesystem range.
# define Libisofs_appended_partitions_inlinE yes
*/
#endif /* SYSTEM_AREA_H_ */

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2011 Thomas Schmitt
* Copyright (c) 2011 - 2014 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
@ -23,6 +23,7 @@
#include "builder.h"
#include "messages.h"
#include "tree.h"
#include "util.h"
#include <stdlib.h>
#include <string.h>
@ -502,10 +503,10 @@ int iso_tree_add_node_builder(IsoImage *image, IsoDir *parent,
int result;
IsoNode *new;
IsoNode **pos;
char *name;
char *name = NULL;
if (parent == NULL || src == NULL || builder == NULL) {
return ISO_NULL_POINTER;
result = ISO_NULL_POINTER; goto ex;
}
if (node) {
*node = NULL;
@ -515,23 +516,25 @@ int iso_tree_add_node_builder(IsoImage *image, IsoDir *parent,
/* find place where to insert */
result = iso_dir_exists(parent, name, &pos);
free(name);
if (result) {
/* a node with same name already exists */
return ISO_NODE_NAME_NOT_UNIQUE;
result = ISO_NODE_NAME_NOT_UNIQUE; goto ex;
}
result = builder->create_node(builder, image, src, &new);
if (result < 0) {
return result;
}
result = builder->create_node(builder, image, src, name, &new);
if (result < 0)
goto ex;
if (node) {
*node = new;
}
/* finally, add node to parent */
return iso_dir_insert(parent, (IsoNode*)new, pos, ISO_REPLACE_NEVER);
result = iso_dir_insert(parent, (IsoNode*)new, pos, ISO_REPLACE_NEVER);
ex:
if (name != NULL)
free(name);
return result;
}
int iso_tree_add_node(IsoImage *image, IsoDir *parent, const char *path,
@ -587,7 +590,8 @@ int iso_tree_add_new_node(IsoImage *image, IsoDir *parent, const char *name,
return result;
}
result = image->builder->create_node(image->builder, image, file, &new);
result = image->builder->create_node(image->builder, image, file,
(char *) name, &new);
/* free the file */
iso_file_source_unref(file);
@ -596,12 +600,6 @@ int iso_tree_add_new_node(IsoImage *image, IsoDir *parent, const char *name,
return result;
}
result = iso_node_set_name(new, name);
if (result < 0) {
iso_node_unref(new);
return result;
}
if (node) {
*node = new;
}
@ -742,6 +740,176 @@ int check_special(IsoImage *image, mode_t mode)
return 0;
}
static
void ascii_increment(char *name, int len, int pos, int rollover_carry)
{
int c;
again:;
if (pos < 0 || pos >= len)
pos = len - 1;
c = name[pos];
if (c >= '0' && c < '9') {
c++;
} else if (c == '9') {
c = 'A';
} else if (c >= 'A' && c < 'Z') {
c++;
} else if (c == 'Z') {
c = '_';
} else if (c == '_') {
c = 'a';
} else if (c >= 'a' && c < 'z') {
c++;
} else if (c == 'z') {
c = '0';
name[pos] = c;
pos--;
if (pos >= 0 || rollover_carry)
goto again;
return;
} else {
if (pos == len - 1 || name[pos + 1] == '.')
c = '_'; /* Make first change less riddling */
else
c = '0'; /* But else use the full range of valid characters */
}
name[pos] = c;
}
static
int insert_underscores(char *name, int *len, int *at_pos, int count,
char **new_name)
{
int ret;
LIBISO_ALLOC_MEM(*new_name, char, count + *len + 1);
if (*at_pos > 0)
memcpy(*new_name, name, *at_pos);
if (count > 0)
memset(*new_name + *at_pos, '_', count);
if (*len > *at_pos)
memcpy(*new_name + *at_pos + count, name + *at_pos, *len - *at_pos);
(*new_name)[count + *len] = 0;
*len += count;
*at_pos += count;
ret= ISO_SUCCESS;
ex:;
return ret;
}
static
int make_incrementable_name(char **name, char **unique_name, int *low_pos,
int *rollover_carry, int *pre_check)
{
char *dpt, *npt;
int first, len, ret;
/* The incrementable part of the file shall have at least 7 characters.
There may be up to pow(2.0,32.0)*2048/33 = 266548273400 files.
The set of increment result characters has 63 elements.
pow(63.0,7.0) is nearly 15 times larger than 266548273400.
*/
static int min_incr = 7;
/* At most two suffixes of total length up to 12, like .tar.bz2,
shall be preserved. The incrementable part will eventually be
padded up.
Incrementing begins before the last suffix in any case. But when this
rolls over on short prefixes, then long last suffixes will get used
as high characters of the incremental part. This is indicated by
*rollover_carry which corresponds to the parameter of ascii_increment()
with the same name.
*/
static int max_suffix = 12;
*rollover_carry = 0;
*pre_check = 0;
len = strlen(*name);
/* Check if the part before the first dot is long enough.
If not, then preserve the last two short suffixes.
*/
dpt = strchr(*name, '.');
if (dpt != NULL)
if ((dpt - *name) < min_incr)
dpt = strrchr(*name, '.');
if (dpt != NULL) {
first= (dpt - *name);
if (dpt > *name && len - first < max_suffix) {
for(npt = dpt - 1; npt >= *name && *npt != '.'; npt--);
if (npt >= *name) {
if (len - (npt - *name) <= max_suffix) {
first= (npt - *name);
dpt = npt;
}
}
}
} else
first= len;
if (first < min_incr && (len - first) <= max_suffix) {
ret = insert_underscores(*name, &len, &first, min_incr - first,
unique_name);
if (ret < 0)
goto ex;
*pre_check = 1; /* It might now already be unique */
} else if (len < 64) {
/* Insert an underscore to preserve the original name at least for the
first few increments
*/
ret = insert_underscores(*name, &len, &first, 1, unique_name);
if (ret < 0)
goto ex;
*pre_check = 1;
} else {
LIBISO_ALLOC_MEM(*unique_name, char, len + 1);
memcpy(*unique_name, *name, len);
if (first < min_incr)
*rollover_carry = 1; /* Do not get caged before the dots */
}
(*unique_name)[len] = 0;
*low_pos = first - 1;
ret = 1;
ex:;
return(ret);
}
static
int make_really_unique_name(IsoDir *parent, char **name, char **unique_name,
IsoNode ***pos, int flag)
{
int ret, rollover_carry = 0, pre_check = 0, ascii_idx = -1, len;
ret = make_incrementable_name(name, unique_name, &ascii_idx,
&rollover_carry, &pre_check);
if (ret < 0)
goto ex;
len = strlen(*unique_name);
while (1) {
if (!pre_check)
ascii_increment(*unique_name, len, ascii_idx, !!rollover_carry);
else
pre_check = 0;
ret = iso_dir_exists(parent, *unique_name, pos);
if (ret < 0)
goto ex;
if (ret == 0)
break;
}
*name = *unique_name;
ret = ISO_SUCCESS;
ex:;
if (ret < 0) {
LIBISO_FREE_MEM(*unique_name);
*unique_name = NULL;
}
return ret;
}
/**
* Recursively add a given directory to the image tree.
*
@ -750,12 +918,12 @@ int check_special(IsoImage *image, mode_t mode)
*/
int iso_add_dir_src_rec(IsoImage *image, IsoDir *parent, IsoFileSource *dir)
{
int ret;
int ret, dir_is_open = 0;
IsoNodeBuilder *builder;
IsoFileSource *file;
IsoNode **pos;
struct stat info;
char *name, *path;
char *name, *path, *allocated_name = NULL;
IsoNode *new;
enum iso_replace_mode replace;
@ -771,8 +939,9 @@ int iso_add_dir_src_rec(IsoImage *image, IsoDir *parent, IsoFileSource *dir)
ret = iso_msg_submit(image->id, ISO_NULL_POINTER, ret,
"Can't open dir. NULL pointer caught as dir name");
}
return ret;
goto ex;
}
dir_is_open = 1;
builder = image->builder;
@ -785,15 +954,16 @@ int iso_add_dir_src_rec(IsoImage *image, IsoDir *parent, IsoFileSource *dir)
if (ret < 0) {
/* error reading dir */
ret = iso_msg_submit(image->id, ret, ret, "Error reading dir");
goto ex;
}
break;
break; /* End of directory */
}
path = iso_file_source_get_path(file);
if (path == NULL) {
ret = iso_msg_submit(image->id, ISO_NULL_POINTER, ret,
"NULL pointer caught as file path");
return ret;
goto ex;
}
name = strrchr(path, '/') + 1;
@ -803,6 +973,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;
}
@ -825,19 +997,25 @@ int iso_add_dir_src_rec(IsoImage *image, IsoDir *parent, IsoFileSource *dir)
/* find place where to insert */
ret = iso_dir_exists(parent, name, &pos);
/* TODO
* if (ret && replace == ISO_REPLACE_ASK) {
* replace = /....
* }
*/
/* chek if we must insert or not */
/* TODO check for other replace behavior */
if (ret && (replace == ISO_REPLACE_NEVER)) {
/* skip file */
goto dir_rec_continue;
if (ret) {
/* Resolve name collision
e.g. caused by fs_image.c:make_hopefully_unique_name()
*/
LIBISO_FREE_MEM(allocated_name); allocated_name = NULL;
ret = make_really_unique_name(parent, &name, &allocated_name, &pos,
0);
if (ret < 0)
goto ex;
image->collision_warnings++;
if (image->collision_warnings < ISO_IMPORT_COLL_WARN_MAX) {
ret = iso_msg_submit(image->id, ISO_IMPORT_COLLISION, 0,
"File name collision resolved with %s . Now: %s",
path, name);
if (ret < 0)
goto ex;
}
}
/* if we are here we must insert. Give user a chance for cancel */
if (image->report) {
int r = image->report(image, file);
@ -846,7 +1024,7 @@ int iso_add_dir_src_rec(IsoImage *image, IsoDir *parent, IsoFileSource *dir)
goto dir_rec_continue;
}
}
ret = builder->create_node(builder, image, file, &new);
ret = builder->create_node(builder, image, file, name, &new);
if (ret < 0) {
ret = iso_msg_submit(image->id, ISO_FILE_CANT_ADD, ret,
"Error when adding file %s", path);
@ -882,14 +1060,17 @@ dir_rec_continue:;
/* check for error severity to decide what to do */
if (ret < 0) {
ret = iso_msg_submit(image->id, ret, 0, NULL);
if (ret < 0) {
break;
}
if (ret < 0)
goto ex;
}
} /* while */
iso_file_source_close(dir);
return ret < 0 ? ret : ISO_SUCCESS;
ret = ISO_SUCCESS;
ex:;
if (dir_is_open)
iso_file_source_close(dir);
LIBISO_FREE_MEM(allocated_name);
return ret;
}
int iso_tree_add_dir_rec(IsoImage *image, IsoDir *parent, const char *dir)
@ -1006,6 +1187,65 @@ ex:;
return path;
}
/* Note: No reference is taken to the found node.
@param flag bit0= recursion
*/
int iso_tree_get_node_of_block(IsoImage *image, IsoDir *dir, uint32_t block,
IsoNode **found, uint32_t *next_above, int flag)
{
int ret, section_count, i;
IsoDirIter *iter = NULL;
IsoNode *node;
IsoDir *subdir;
IsoFile *file;
struct iso_file_section *sections = NULL;
uint32_t na = 0;
if (dir == NULL)
dir = image->root;
ret = iso_dir_get_children(dir, &iter);
while (iso_dir_iter_next(iter, &node) == 1 ) {
if (ISO_NODE_IS_FILE(node)) {
file = (IsoFile *) node;
ret = iso_file_get_old_image_sections(file, &section_count,
&sections, 0);
if (ret <= 0)
continue;
for (i = 0; i < section_count; i++) {
if (sections[i].block <= block &&
block - sections[i].block <
(((off_t) sections[i].size) + 2047) / 2048) {
*found = node;
ret = 1; goto ex;
}
if ((na == 0 || sections[i].block < na) &&
sections[i].block > block)
na = sections[i].block;
}
free(sections); sections = NULL;
} else if (ISO_NODE_IS_DIR(node)) {
subdir = (IsoDir *) node;
ret = iso_tree_get_node_of_block(image, subdir, block, found, &na,
1);
if (ret != 0)
goto ex;
}
}
if (next_above != NULL && (na > 0 || !(flag & 1)))
if (*next_above == 0 || *next_above > na || !(flag & 1))
*next_above = na;
ret = 0;
ex:
if (sections != NULL)
free(sections);
if (iter != NULL)
iso_dir_iter_free(iter);
return ret;
}
/* ------------------------- tree cloning ------------------------------ */
static

View File

@ -19,4 +19,9 @@
*/
int iso_add_dir_src_rec(IsoImage *image, IsoDir *parent, IsoFileSource *dir);
int iso_tree_get_node_of_block(IsoImage *image, IsoDir *dir, uint32_t block,
IsoNode **found, uint32_t *next_above, int flag);
#endif /*LIBISO_IMAGE_TREE_H_*/

View File

@ -241,8 +241,8 @@ ex:;
return retval;
}
int strnconv(const char *str, const char *icharset, const char *ocharset,
size_t len, char **output)
int strnconvl(const char *str, const char *icharset, const char *ocharset,
size_t len, char **output, size_t *out_len)
{
size_t inbytes;
size_t outbytes;
@ -278,7 +278,8 @@ int strnconv(const char *str, const char *icharset, const char *ocharset,
*ret = '\0';
iso_iconv_close(&conv, 0);
*output = malloc(ret - out + 1);
*out_len = ret - out;
*output = malloc(*out_len + 1);
if (*output == NULL) {
retval = ISO_OUT_OF_MEM;
goto ex;
@ -291,6 +292,15 @@ ex:;
return retval;
}
int strnconv(const char *str, const char *icharset, const char *ocharset,
size_t len, char **output)
{
size_t l;
return strnconvl(str, icharset, ocharset, len, output, &l);
}
/**
* Convert a str in a specified codeset to WCHAR_T.
* The result must be free() when no more needed
@ -667,6 +677,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 == '_');
@ -1080,7 +1207,7 @@ uint16_t *iso_j_file_id(const uint16_t *src, int flag)
{
uint16_t *dot, *retval = NULL;
size_t lname, lext, lnname, lnext, pos, i, maxchar = 64;
uint16_t *dest = NULL;
uint16_t *dest = NULL, c;
LIBISO_ALLOC_MEM_VOID(dest, uint16_t, LIBISO_JOLIET_NAME_MAX);
/* was: 66 = 64 (name + ext) + 1 (.) + 1 (\0) */
@ -1120,7 +1247,7 @@ uint16_t *iso_j_file_id(const uint16_t *src, int flag)
/* Convert up to lnname characters of the filename. */
for (i = 0; i < lnname; i++) {
uint16_t c = src[i];
c = src[i];
if (valid_j_char(c)) {
dest[pos++] = c;
} else {
@ -1128,6 +1255,8 @@ uint16_t *iso_j_file_id(const uint16_t *src, int flag)
pos++;
}
}
if (pos > 0)
iso_handle_split_utf16(dest + (pos - 1));
if ((flag & 1) && lnext <= 0)
goto is_done;
@ -1145,6 +1274,7 @@ uint16_t *iso_j_file_id(const uint16_t *src, int flag)
pos++;
}
}
iso_handle_split_utf16(dest + (pos - 1));
is_done:;
set_ucsbe(dest + pos, '\0');
@ -1181,6 +1311,7 @@ uint16_t *iso_j_dir_id(const uint16_t *src, int flag)
set_ucsbe(dest + i, '_');
}
}
iso_handle_split_utf16(dest + (len - 1));
set_ucsbe(dest + len, '\0');
retval = ucsdup(dest);
ex:
@ -1262,6 +1393,8 @@ uint16_t *ucsncpy(uint16_t *dest, const uint16_t *src, size_t n)
{
n = MIN(n, ucslen(src) + 1);
memcpy(dest, src, n*2);
if (n >= 2)
iso_handle_split_utf16(dest + (n - 2));
return dest;
}
@ -1401,6 +1534,26 @@ uint32_t iso_read_bb(const uint8_t *buf, int bytes, int *error)
return v1;
}
uint64_t iso_read_lsb64(const uint8_t *buf)
{
int i;
uint64_t ret = 0;
for (i=0; i < 8; i++)
ret += ((uint64_t) buf[i]) << (i * 8);
return ret;
}
uint64_t iso_read_msb64(const uint8_t *buf)
{
int i;
uint64_t ret = 0;
for (i=0; i < 8; i++)
ret += ((uint64_t) buf[7 - i]) << (i * 8);
return ret;
}
void iso_datetime_7(unsigned char *buf, time_t t, int always_gmt)
{
static int tzsetup = 0;
@ -1421,8 +1574,14 @@ void iso_datetime_7(unsigned char *buf, time_t t, int always_gmt)
#else
if (tm.tm_isdst < 0)
tm.tm_isdst = 0;
tzoffset = ( - timezone / 60 / 15 ) + 4 * tm.tm_isdst;
#ifndef Libburnia_timezonE
#define Libburnia_timezonE timezone
#endif
#if Libburnia_timezonE == 0
always_gmt = 1;
#endif
tzoffset = ( - Libburnia_timezonE / 60 / 15 ) + 4 * tm.tm_isdst;
#endif /* ! HAVE_TM_GMTOFF */
if (tzoffset > 52 || tzoffset < -48 || always_gmt) {
/* absurd timezone offset, represent time in GMT */
@ -1467,8 +1626,14 @@ void iso_datetime_17(unsigned char *buf, time_t t, int always_gmt)
#else
if (tm.tm_isdst < 0)
tm.tm_isdst = 0;
tzoffset = ( - timezone / 60 / 15 ) + 4 * tm.tm_isdst;
#ifndef Libburnia_timezonE
#define Libburnia_timezonE timezone
#endif
#if Libburnia_timezonE == 0
always_gmt = 1;
#endif
tzoffset = ( - Libburnia_timezonE / 60 / 15 ) + 4 * tm.tm_isdst;
#endif /* ! HAVE_TM_GMTOFF */
if (tzoffset > 52 || tzoffset < -48 || always_gmt) {
/* absurd timezone offset, represent time in GMT */
@ -1878,6 +2043,17 @@ int iso_util_dec_to_uint32(char *dec, uint32_t *value, int flag)
}
int iso_util_bin_to_hex(char *target, uint8_t *bytes, int num_bytes, int flag)
{
int i;
for (i = 0; i < num_bytes; i++)
sprintf(target + 2 * i, "%-2.2x", bytes[i]);
target[2 * num_bytes] = 0;
return 1;
}
int iso_util_hex_to_bin(char *hex, char *bin, int bin_size, int *bin_count,
int flag)
{
@ -2092,3 +2268,78 @@ uint16_t iso_htons(uint16_t v)
return ret;
}
/* If an UTF-16 surrogate pair was split : Change to UTF-16 '_'.
(UCS-2 is promised to reserve 0xd800 to 0xdbff for UTF-16).
*/
void iso_handle_split_utf16(uint16_t *utf_word)
{
unsigned char *hb;
hb = (unsigned char *) utf_word;
if ((hb[0] & 0xfc) == 0xd8)
set_ucsbe(utf_word, '_');
}
int iso_clone_mem(char *in, char **out, size_t size)
{
if (in == NULL) {
*out = NULL;
return 1;
}
if (size == 0)
size = strlen(in) + 1;
*out = calloc(1, size);
if (*out == NULL)
return ISO_OUT_OF_MEM;
memcpy(*out, in, size);
return 1;
}
int iso_clone_mgtd_mem(char *in, char **out, size_t size)
{
if (*out != NULL)
free(*out);
return iso_clone_mem(in, out, size);
}
/** Convert a text into a number of type double and multiply it by unit code
[kmgt] (2^10 to 2^40) or [s] (2048) or [d] (512).
(Also accepts capital letters.)
@param text Input like "42", "223062s", "3m" or "-1g"
@param flag Bitfield for control purposes:
bit0= return -1 rathern than 0 on failure
bit1= if scaled then compute the last byte of the last unit
@return The derived value
*/
off_t iso_scanf_io_size(char *text, int flag)
{
int c;
off_t ret = 0, fac = 1;
char *rpt;
for (rpt = text; *rpt >= '0' && *rpt <= '9'; rpt++)
ret = ret * 10 + (*rpt - '0');
if (rpt == text)
return (off_t) (flag & 1 ? -1 : 0);
c = *rpt;
if (c=='k' || c=='K')
fac = 1024;
else if (c=='m' || c=='M')
fac = 1024 * 1024;
else if (c=='g' || c=='G')
fac = 1024 * 1024 * 1024;
else if (c=='t' || c=='T')
fac = ((off_t) 1024) * 1024 * 1024 * 1024;
else if (c=='s' || c=='S')
fac = 2048;
else if (c=='d' || c=='D')
fac = 512;
ret *= fac;
if (flag & 2)
ret += fac - 1;
return ret;
}

View File

@ -21,6 +21,12 @@
#include <time.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#include <fcntl.h>
#ifndef MAX
# define MAX(a, b) (((a) > (b)) ? (a) : (b))
#endif
@ -56,9 +62,16 @@ int iso_init_locale(int flag);
int strconv(const char *input, const char *icharset, const char *ocharset,
char **output);
/* Like strconv but processing len input bytes rather than strlen(input)
*/
int strnconv(const char *str, const char *icharset, const char *ocharset,
size_t len, char **output);
/* Like strnconv but also returning the number of bytes in *output.
*/
int strnconvl(const char *str, const char *icharset, const char *ocharset,
size_t len, char **output, size_t *out_len);
/**
* Convert a given string from any input charset to ASCII
*
@ -88,6 +101,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.
*
@ -220,6 +249,12 @@ uint16_t *ucscpy(uint16_t *dest, const uint16_t *src);
*/
uint16_t *ucsncpy(uint16_t *dest, const uint16_t *src, size_t n);
/**
* Check whether utf_word is the first surrogate word of a pair.
* If so, change it to UTF-16 character '_'.
*/
void iso_handle_split_utf16(uint16_t *utf_word);
/**
* Convert a given input string to d-chars.
* @return
@ -244,6 +279,9 @@ uint32_t iso_read_msb(const uint8_t *buf, int bytes);
*/
uint32_t iso_read_bb(const uint8_t *buf, int bytes, int *error);
uint64_t iso_read_lsb64(const uint8_t *buf);
uint64_t iso_read_msb64(const uint8_t *buf);
/**
* Records the date/time into a 7 byte buffer (ECMA-119, 9.1.5)
*
@ -515,6 +553,12 @@ int iso_util_eval_md5_tag(char *block, int desired, uint32_t lba,
int iso_util_tag_magic(int tag_type, char **tag_magic, int *len, int flag);
int iso_util_bin_to_hex(char *target, uint8_t *bytes, int num_bytes, int flag);
int iso_util_hex_to_bin(char *hex, char *bin, int bin_size, int *bin_count,
int flag);
/* ------------------------------------------------------------------------- */
/* In md5.h these function prototypes would be neighbors of (Ecma119Image *)
@ -577,6 +621,29 @@ void *iso_alloc_mem(size_t size, size_t count, int flag);
}
/*
@param in Valid memory or NULL
@param out Returns valid memory or NULL
@param size Number of bytes to copy. 0 means strlen(in)+1 if not NULL.
@return 1 or ISO_OUT_OF_MEM
*/
int iso_clone_mem(char *in, char **out, size_t size);
/* Like iso_clone_mem but first freeing *out if not NULL
*/
int iso_clone_mgtd_mem(char *in, char **out, size_t size);
/** Convert a text into a number of type double and multiply it by unit code
[kmgt] (2^10 to 2^40) or [s] (2048) or [d] (512).
(Also accepts capital letters.)
@param text Input like "42", "223062s", "3m" or "-1g"
@param flag Bitfield for control purposes:
bit0= return -1 rathern than 0 on failure
bit1= if scaled then compute the last byte of the last unit
@return The derived value
*/
off_t iso_scanf_io_size(char *text, int flag);
/* ------------------------------------------------------------------------- */

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2014 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
@ -322,9 +323,10 @@ int iso_htable_create(size_t size, hash_funtion_t hash,
{
IsoHTable *t;
if (table == NULL) {
return ISO_OUT_OF_MEM;
}
if (size <= 0)
return ISO_WRONG_ARG_VALUE;
if (table == NULL)
return ISO_NULL_POINTER;
t = malloc(sizeof(IsoHTable));
if (t == NULL) {