Compare commits

...

147 Commits

Author SHA1 Message Date
46e96ee616 Version leap to 1.3.2 2013-08-07 15:10:10 +02:00
7e60e60e62 Updated changelog 2013-08-07 10:56:23 +02:00
d55ed2d1ca New API calls iso_image_get_app_use() and iso_image_set_app_use() 2013-08-04 12:32:31 +02:00
77c8349c56 Bug fix: iso_finish() left an invalid global pointer, which a subsequent call of iso_init() would try to dereference. 2013-07-31 09:53:43 +02:00
b1c7ed6e29 Avoided a confusing error message from iso_image_update_sizes(),
prepared macro for non-confusing error message,
and introduced flag bit0 to iso_stream_get_input_stream()
2013-06-25 14:56:29 +02:00
e886722d65 The sort weight of data files loaded from ISO image is now 2 exp 28 to 1
rather than 2 exp 31 - 1 to - 2 exp 31
2013-05-24 12:35:43 +02:00
b80b339de3 Version leap to 1.3.1 2013-05-17 19:51:39 +02:00
efbd05203d Version leap to 1.3.0 2013-05-17 19:47:58 +02:00
6ca1d76d60 Updated change log 2013-05-17 09:52:40 +02:00
e1b54056e8 Added a new source of information about CHRP to boot_sectors.txt 2013-05-01 20:28:24 +02:00
d5cd610ac7 Bug fix: The protective MBR partition for GPT started at block 0 instead of 1 2013-04-17 20:54:02 +02:00
91f5ebb376 Bug fix: GPT header CRC was computed from all 512 bytes rather than from 92. 2013-04-17 16:45:51 +02:00
ff3b439bda Changed Libisofs_grub2_sparc_patch_lba_poS to Libisofs_grub2_sparc_patch_adr_poS 2013-04-14 08:15:29 +02:00
4672c79181 Changed Libisofs_grub2_sparc_patch_lba_poS to Libisofs_grub2_sparc_patch_adr_poS 2013-04-14 08:14:27 +02:00
83cb07b23c New API calls iso_image_set_sparc_core() and iso_image_get_sparc_core(). 2013-04-13 22:17:26 +02:00
439a14da1d Bug fix: Reserved and unused fields of APM entries were not zeroed. 2013-04-13 12:11:26 +02:00
d66eef42f6 Corrected Libisofs_grub2_mbr_patch_offsT from 3 to 4 2013-04-13 09:25:42 +02:00
337bade549 New option bits with el_torito_set_isolinux_options() and
iso_write_opts_set_system_area() to control GRUB2 patching of
boot image and MBR
2013-04-13 08:38:52 +02:00
eb6503a8ad * Bug fix: Unspecified Expiration Time and Effective Time of ISO volume was
represented by 0-bytes rather than ASCII '0' digits.
2013-04-10 13:55:20 +02:00
1a2e1c767e Now repeating Rock Ridge warnings at most once per loaded image. 2013-04-10 13:32:53 +02:00
858c5479c8 Changed some warning texts from "RR" to "Rock Ridge" 2013-04-10 13:32:09 +02:00
d36b3d04a8 Temporarily hosting a test bed for syslinux/core/fs/susp_rr.c in libisofs/fs_image.c 2013-03-31 13:37:39 +02:00
da41eb8c6e Version leap to 1.2.9 2013-03-18 21:54:59 +01:00
775b7a11b4 Version leap to 1.2.8 2013-03-18 21:47:22 +01:00
23679b86ff Updated changelog 2013-03-18 08:32:16 +01:00
a4f07eb3b3 New API call iso_image_get_pvd_times(). 2013-03-12 17:42:13 +01:00
6905ab3e56 Bug fix: Image size prediction altered the pointers to MD5 of data files
which stem from a previous session.
2013-01-14 18:13:49 +01:00
05e7f84966 Bug fix: Reading damaged Rock Ridge data could cause SIGSEGV by NULL. 2013-01-11 16:22:14 +01:00
6e5f840f11 Version leap to 1.2.7 2013-01-08 15:38:01 +01:00
df37211b7b Updated copyright year in libisofs.h 2013-01-08 12:46:04 +01:00
bd81e44da0 Version leap to 1.2.6 (second try) 2013-01-08 08:55:03 +01:00
37792c5713 Version leap to 1.2.6 2013-01-08 08:50:51 +01:00
4fb98d9c3c Updated changelog 2013-01-08 08:35:55 +01:00
57a14ec0be Adapted severity list production to the format of libburn 2013-01-08 08:29:57 +01:00
c5d8c26653 Bug fix: Prevented a memory fault when reading damaged Rock Ridge information 2013-01-08 08:28:52 +01:00
4ff777ee58 Bug fix: Isohybrid production without any boot image led to SIGSEGV by NULL 2012-10-23 08:31:42 +02:00
46bb5945c6 Improved quality of random UUIDs 2012-10-22 18:59:07 +02:00
a585d6a32d Clarifications in the description of el_torito_set_isolinux_options() 2012-10-22 18:12:10 +02:00
b77917fb63 Bug fix: Non-zero partition offset zeroized the MBR copies of GPT partition
table entries which were enabled by el_torito_set_isolinux_options()
2012-10-07 11:53:36 +02:00
4673733c4b New iso_write_opts_set_system_area() cylinder alignment mode "all".
This commit revokes the statement that rev 1042 is a bug fix.
The old behavior is a feature. The former bug fix is now triggered by
mode "all".
2012-09-21 13:56:43 +02:00
f3e63e3cf7 Bug fix: Appended partitions did not obey cylinder alignment 2012-09-19 18:01:08 +02:00
fb9b3a298c Minor changes with documentation 2012-07-20 21:04:15 +02:00
1539ff120e Reacted on compiler warning on Solaris. 2012-07-20 21:03:34 +02:00
20cc592765 Version leap to 1.2.5 2012-07-20 20:08:53 +02:00
1dd05f63a7 Version leap to 1.2.4 2012-07-20 20:04:30 +02:00
fe07c87788 Updated changelog 2012-07-20 14:23:03 +02:00
8c58e2a012 Corrected some indentation 2012-07-20 13:14:57 +02:00
b6b8b1625c Removed obsolete code variations from hfsplus.c 2012-07-20 13:10:18 +02:00
042dbd01ed Removed obsolete development marks 2012-07-20 12:21:36 +02:00
7001121a3f New flag bit with iso_node_set_attrs() to protect namespace "isofs" 2012-07-12 18:16:38 +02:00
942ec97c7b Made Libisofs_with_rr_reloc_diR unconditional 2012-07-11 15:52:53 +02:00
8b2edd7ca4 Mad new hfsplus_case.c usable for GNU xorriso 2012-07-11 12:16:45 +02:00
2e6c3efda2 Corrected a comment in new hfsplus_case.c 2012-07-11 12:09:18 +02:00
2e63856dee Replaced implementation of HFS+ case-insensitive character conversion
by one of my own copyright.
2012-07-11 11:31:45 +02:00
b211ce6804 Clarified copyright of libisofs/hfsplus_classes.c 2012-07-07 11:40:18 +02:00
4c2a24514d Replaced use of ntohs() and htons() by iso_ntohs() and iso_htons(). 2012-07-06 17:33:45 +02:00
b07d60bbfc Moved some functions from util.c to hfsplus.c 2012-07-03 18:56:26 +02:00
e8f6f924bd Adjusting symbolic links in HFS+ which are affected by name mangling 2012-07-02 19:57:25 +02:00
7a8995f322 New API call iso_tree_resolve_symlink(). 2012-07-01 18:41:54 +02:00
2c88e74798 Introduced mangling of HFS+ names for case-insensitive uniqueness. 2012-06-30 21:48:42 +02:00
2d441cca5d New API call iso_write_opts_set_hfsp_block_size(). 2012-06-27 20:39:57 +02:00
7e49fb553b Enabled the opportunity to set HFSPLUS_BLOCK_SIZE to 512 for experiments. 2012-06-24 16:00:03 +02:00
af367561a6 Setting the boot bit with the CHRP MBR partition. 2012-06-22 16:33:03 +02:00
85bedae639 Introduced opportunity to choose an MBR partition number with
struct iso_mbr_partition_request and iso_quick_mbr_entry().
2012-06-21 12:29:00 +02:00
bbd198a81b Avoiding a SIGSEGV if no El Torito is involved. Introduced by rev 1014. 2012-06-20 20:40:15 +02:00
2a08471c04 Trying to get push to work after merge. 2012-06-20 19:41:10 +02:00
72bdd7a3d0 Small update in doc/boot_sectors.txt 2012-06-20 19:32:30 +02:00
bab3cf0c7c New option bits 2 to 7 with el_torito_set_isolinux_options() 2012-06-20 19:21:35 +02:00
862d4fb571 Revoked rev 1013: Partition type of PReP is indeed 0x41. 2012-06-20 13:08:37 +02:00
27277914c6 Ended the special out-of-loop handling of eltorito_writer_compute_data_blocks() 2012-06-19 16:49:03 +02:00
2d3bbe51ed Corrected partition type of PReP from 0x41 to 0x42 2012-06-19 11:37:44 +02:00
5288cec97d Removed an obsolete experimental member from Ecma119Image 2012-06-18 15:13:48 +02:00
09b314c66f Reacted on harmless compiler warning. 2012-06-18 14:43:56 +02:00
55e134fb1c Enabled writing of EFI El Torito boot image as EFI System Partition outside
the range of the HFS+ partition.
2012-06-18 10:06:16 +02:00
9882d983b9 Avoiding to print a NULL pointer via %s in a HFS+ debug message 2012-06-17 12:56:32 +02:00
6fd859a2c1 Closed a potential memory leak in case of memory shortage 2012-06-15 20:07:30 +02:00
4d10b8c73c Silenced compiler warnings about too modern array initilization. 2012-06-14 13:46:31 +02:00
0ebc8fe186 Provisorily moved tail writer after checksum writer
and accounted for size of backup GPT in cylinder alignment of tail writer.
2012-06-13 13:31:37 +02:00
912e0cd1be Provisorily allowing the combination of HFS+ and CHRP. 2012-06-13 08:15:38 +02:00
3a60720099 Correcterd criterion for enabling CHRP partition entry. 2012-06-12 21:58:55 +02:00
c166a49889 Bug fix: Partition cylinder alignment worked only if both, El Torito and
application provided system area data were present.
2012-06-12 21:21:14 +02:00
6fc3bb6777 New ystem area sub type CHRP with iso_write_opts_set_system_area() 2012-06-12 21:16:56 +02:00
d7401f0a4c Updated description of boot sectors by sparse info about PReP, CHRP.
Described the layout for GRUB2 based hybrid images.
2012-06-12 17:42:22 +02:00
6a3273dc72 New API calls so_write_opts_set_prep_img(), iso_write_opts_set_efi_bootp() 2012-06-12 13:24:50 +02:00
0897896713 Inner API for requesting MBR partition table entries. 2012-06-11 13:05:46 +02:00
1de0284eaa New API call iso_write_opts_set_fat(). (FAT feature not implemented yet.) 2012-06-10 19:41:00 +02:00
7c6c3466e9 Provisorily moved gpt_tail_writer to the very end of the writer list. 2012-06-10 16:08:36 +02:00
3528795b55 Corrected computation for error ISO_OVWRT_FIFO_TOO_SMALL. 2012-06-10 15:09:08 +02:00
3b95f4c4c4 Closed a small memory leak found by valgrind 2012-06-10 12:52:34 +02:00
2cc387fcce Aborting image generation in case of ISO_OVWRT_FIFO_TOO_SMALL. 2012-06-10 12:48:22 +02:00
45bee0a849 Marking HFS+ partition in APM as automountable for legacy Macs. 2012-06-10 10:42:39 +02:00
7fd36ffade Reserved new AAIP names isofs.hb and isofs.hx for storing HFS+ attributes. 2012-06-07 23:15:16 +02:00
5427fa9e17 Described the layout of APM and GPT. Moved description of isohybrid
and grub-mkrescue to the end of boot_sectors.txt.
2012-06-07 15:38:05 +02:00
ce17f78d59 Changed APM data partition flags from 0x03 to 0x13. 2012-06-07 15:35:58 +02:00
1bbdb97a2d Small change in iso_hybrid_fs.txt 2012-06-07 10:58:51 +02:00
f39e73d2ce Updated the documentation about the overall framework of libisofs
image production and opportunities to add metadata of other filesystem
types.
2012-06-07 10:45:09 +02:00
74bc1808a1 Renamed gpt_tail_writer_ecma119_writer_create() to gpt_tail_writer_create(). 2012-06-07 10:38:27 +02:00
ad251e8c7d Mentioned in API description the impact of iso_write_opts_set_hfsplus()
on System Area.
2012-06-06 18:58:00 +02:00
cb3a6f8bb0 Pre-computing size of data file content area and publishing it to
writers as Ecma119Image.filesrc_blocks.
2012-06-05 21:29:52 +02:00
a3285f6e5d Silenced a compiler warning 2012-06-05 17:00:16 +02:00
36502f8ae3 Second stage of implementation of GPT production.
It implements the writer class for the backup GPT.
2012-06-04 20:39:34 +02:00
21109ffcf1 Disabled GTP test mock-up. 2012-06-02 19:37:23 +02:00
bcd4b88319 First stage of implementation of GPT production.
The writer class for the backup GPT is not implemented yet.
2012-06-02 19:32:22 +02:00
714ef6493a New API call iso_image_hfsplus_get_blessed() 2012-05-30 16:42:12 +02:00
01b2ee088b Silenced a harmless compiler warning. 2012-05-30 12:51:37 +02:00
2ed96d89f9 Corrections to HFS+ code by Vladimir Serbinko. 2012-05-30 08:57:04 +02:00
cc71d9e30b Now writing micro mock-up of APM Block0.
Corrected block size handling with APM entry 1.
2012-05-29 22:17:09 +02:00
4fd7faa636 Fixed a bug about APM that was introduced with rev 968. Found by Vladimir. 2012-05-29 21:20:42 +02:00
d2c19ed2b4 New adjustemets to HFS+ by Vladimir Serbinenko. 2012-05-29 17:59:42 +02:00
63df7749fa Silenced compiler warnings by fixing micro bugs. 2012-05-28 09:27:07 +02:00
e9eb22f514 New error code ISO_BOOT_APM_OVERLAP 2012-05-28 09:17:17 +02:00
e57e45e40b New API call iso_write_opts_set_hfsp_serial_number(). 2012-05-27 18:55:04 +02:00
1ed3ba7933 Introduced internal pseudo-random generators iso_random_uuid() and
iso_random_8byte().
2012-05-27 16:05:56 +02:00
3e2479c095 Fixed a bug in yet unused code which was introduced by rev 965. 2012-05-26 23:17:59 +02:00
bc7e8acb74 Corrected three comments about recently introduced error codes. 2012-05-26 23:09:55 +02:00
8770148cad Introduced inner API iso_apm_partition_request for definition of
Apple Partition Map entries by hfsplus.c.
2012-05-26 23:04:42 +02:00
6fc6a09040 Fixed several memory problems introduced by rev 965 2012-05-25 20:57:06 +02:00
a72fd6a309 Corrected a comment in libisofs.h 2012-05-25 19:55:45 +02:00
82f39020cf Attributed HFS+ blessings to IsoImage rather than IsoWriteOpts. 2012-05-25 19:34:09 +02:00
1842921b2c Adaptions to new HFS+ blessing interface by Vladimir Serbinenko. 2012-05-25 18:19:46 +02:00
ab11c954d9 Created API and hfsplus interface of HFS+ blessing.
But iso_write_opts_bless() is still a dummy.
2012-05-25 14:40:06 +02:00
177864bd13 Made struct iso_hfsplus_xinfo_data clonable. 2012-05-25 10:42:26 +02:00
ed986aa4ea HFS+ enhancement by Vladimir Serbinenko:
Mostly symlinks, POSIX files and attributes.
2012-05-25 08:25:45 +02:00
45bf3d9717 Cleaned out obsolete development remarks. 2012-05-24 21:46:53 +02:00
c1df1c9fd8 Corrected type of the new iso_hfsplus_xinfo_data members. 2012-05-24 19:49:52 +02:00
a7ae64e3c7 Removed an unused variable. 2012-05-24 19:33:57 +02:00
6cb5f802af Committing the yet incomplete implementation of SYSLINUX isohybrid
for MBR, UEFI and x86-Mac. This shall avoid tangling with ongoing HFS+
efforts.
2012-05-24 19:31:00 +02:00
a8b20b87aa New API functions iso_hfsplus_xinfo_func(), iso_hfsplus_xinfo_new()
and pre-version 0 of struct iso_hfsplus_xinfo_data.
2012-05-24 19:27:03 +02:00
201e7f15df Including <arpa/inet.h> 2012-05-24 13:54:49 +02:00
f040f31d05 Registered new error ISO_SECT_SCATTERED in iso_error_to_msg(). 2012-05-24 13:06:49 +02:00
9e2d82fc78 Updated Vladimir Serbinenko's work. 2012-05-24 11:27:21 +02:00
1a5c02a27e Updated Vladimir Serbinenko's work. Replaced his extension of Iso_File_Src
by a function that computes the size from Iso_File_Src.sections.
2012-05-24 09:19:23 +02:00
e5a4e33ebd Bug fix: Joliet name comparison was done as signed bytes and thus produced
a peculiar sorting order. Thanks to Vladimir Serbinenko. (For previous commit
too.)
2012-05-23 20:59:14 +02:00
fae423fb54 Bug fix: The separator dot of Joliet names was byte swapped on big-endian
machines.
2012-05-23 20:58:31 +02:00
e97bd3ed2d Added Vladimir Serbinenko to list of libisofs authors. 2012-05-23 19:41:39 +02:00
2c540b1f43 Vladimir Serbinenko began to implement production of HFS+ metadata.
This revision introduces the writer class and a first attempt to integrate
it into image production. Not yet functional.
2012-05-23 14:47:49 +02:00
6982971796 Bug fix: Volume descriptors of Joliet and ISO 9660:1999 beared non-zero
Effective Date, involuntarily restricting the early end of their lifetime.
Thanks to Vladimir Serbinenko.
2012-05-22 16:46:17 +02:00
3c7c534ded Bug fix: File Structure Version field of ISO 9660:1999 Enhanced Volume
Descriptor was 1 instead of 2. Thanks to Vladimir Serbinenko.
2012-05-20 20:37:25 +02:00
262e49ad6b Documented probable isohybrid.c bugs and polished overview table. 2012-05-09 12:03:50 +02:00
502bea814e Documented MBR partitions and GUIDs 2012-05-08 19:46:03 +02:00
fa784d619c Corrected a wrong statement about CRC of empty input 2012-05-07 20:50:48 +02:00
977161cda1 Described the CRC algorithm of GPT 2012-05-07 20:33:53 +02:00
dc2b27ca51 Added an overview table to EFI isohybrid description. 2012-05-06 14:11:34 +02:00
abd2137906 Beginning to describe EFI isohybrid with Apple partition map and GPT. 2012-05-06 10:08:21 +02:00
ff95a84130 Bug fix: Symbol iso_fs_global_id was missing in libisofs.ver.
Thanks to: http://upstream-tracker.org/versions/libisofs.html
2012-04-28 08:51:50 +02:00
f384961808 Bug fix: Memory corruption when reading bootable image that was truncated
before the storage location of the boot catalog
2012-04-19 09:29:31 +02:00
81dd6ce55a Version leap to 1.2.3 2012-04-02 19:12:39 +02:00
40 changed files with 9220 additions and 759 deletions

View File

@ -1,3 +1,4 @@
Vreixo Formoso
Mario Danic
Vladimir Serbinenko
Thomas Schmitt

View File

@ -1,4 +1,68 @@
bzr branch lp:libisofs/for-libisoburn (to become libisofs-1.2.2.tar.gz)
libisofs-1.3.2.tar.gz Wed Aug 07 2013
===============================================================================
* Bug fix: iso_finish() left an invalid global pointer, which a subsequent
call of iso_init() would try to dereference.
* The sort weight of data files loaded from ISO image is now 2 exp 28 to 1
rather than 2 exp 31 - 1 to - 2 exp 31
libisofs-1.3.0.tar.gz Fri May 17 2013
===============================================================================
* Bug fix: GPT header CRC was computed from all 512 bytes rather than from 92.
* Bug fix: Unspecified Expiration Time and Effective Time of ISO volume was
represented by 0-bytes rather than ASCII '0' digits.
* Bug fix: Reserved and unused fields of APM entries were not zeroed.
* Bug fix: The protective MBR partition for GPT started at block 0 instead of 1.
* New option bits with el_torito_set_isolinux_options() and
iso_write_opts_set_system_area() to control GRUB2 patching of
boot image and MBR.
* New API calls iso_image_set_sparc_core() and iso_image_get_sparc_core().
libisofs-1.2.8.tar.gz Mon Mar 18 2013
===============================================================================
* Bug fix: Image size prediction altered the pointers to MD5 of data files
which stem from a previous session.
* Bug fix: Reading damaged Rock Ridge data could cause SIGSEGV by NULL.
* New API call iso_image_get_pvd_times().
libisofs-1.2.6.tar.gz Tue Jan 08 2013
===============================================================================
* Bug fix: Appended partitions did not obey cylinder alignment
* Bug fix: Non-zero partition offset zeroized the MBR copies of GPT partition
table entries
* Bug fix: Isohybrid production without any boot image led to SIGSEGV by NULL
* Bug fix: Prevented a memory fault when reading damaged Rock Ridge information
libisofs-1.2.4.tar.gz Fri Jul 20 2012
===============================================================================
* Bug fix: Memory corruption when reading bootable image that was truncated
before the storage location of the boot catalog
* Bug fix: Symbol iso_fs_global_id was missing in libisofs.ver.
* Bug fix: Volume descriptors of Joliet and ISO 9660:1999 beared non-zero
Effective Date, involuntarily restricting the early end of
their lifetime.
* Bug fix: File Structure Version field of ISO 9660:1999 Enhanced Volume
Descriptor was 1 instead of 2.
* Bug fix: The separator dot of Joliet names was byte swapped on big-endian
machines.
* Bug fix: Joliet name comparison was done as signed bytes and thus produced
a peculiar sorting order.
* Bug fix: Partition cylinder alignment worked only if both, El Torito and
application provided system area data were present.
* New API function iso_write_opts_set_hfsplus
* New API functions iso_hfsplus_xinfo_func(), iso_hfsplus_xinfo_new(), and
new struct iso_hfsplus_xinfo_data.
* New API call iso_write_opts_set_hfsp_serial_number()
* New API calls iso_image_hfsplus_bless and iso_image_hfsplus_get_blessed(),
and new public enum IsoHfsplusBlessings.
* New API calls so_write_opts_set_prep_img(), iso_write_opts_set_efi_bootp()
* New API call iso_write_opts_set_hfsp_block_size()
* New API call iso_tree_resolve_symlink()
* New system area sub type CHRP with iso_write_opts_set_system_area()
* New option bits 2 to 8 for GPT and APM with el_torito_set_isolinux_options()
* New flag bit with iso_node_set_attrs() to protect namespace "isofs"
* New IsoHideNodeFlag value LIBISO_HIDE_ON_HFSPLUS
libisofs-1.2.2.tar.gz Mon Apr 02 2012
===============================================================================
* New API call iso_write_opts_set_rr_reloc()
* Bug fix: Directory name mapping to ISO level 1 was too liberal if
@ -7,7 +71,6 @@ bzr branch lp:libisofs/for-libisoburn (to become libisofs-1.2.2.tar.gz)
* Improved standards compliance for ISO level 1 names with partly relaxed
constraints.
libisofs-1.2.0.tar.gz Sat Jan 28 2012
===============================================================================
* Extended influence of iso_write_opts_set_dir_rec_mtime() to Joliet and

View File

@ -66,6 +66,11 @@ libisofs_libisofs_la_SOURCES = \
libisofs/rockridge_read.c \
libisofs/joliet.h \
libisofs/joliet.c \
libisofs/hfsplus.h \
libisofs/hfsplus.c \
libisofs/hfsplus_decompose.c \
libisofs/hfsplus_classes.c \
libisofs/hfsplus_case.c \
libisofs/eltorito.h \
libisofs/eltorito.c \
libisofs/system_area.h \

5
README
View File

@ -4,7 +4,10 @@
Released under GPL (see COPYING file for details).
Copyright (C) 2008 - 2010 Vreixo Formoso, Mario Danic, Thomas Schmitt
Copyright (C) 2008 - 2012 Vreixo Formoso,
Mario Danic,
Vladimir Serbinenko,
Thomas Schmitt
libisofs is part of the libburnia project (libburnia-project.org)
------------------------------------------------------------------------------

View File

@ -1,4 +1,4 @@
AC_INIT([libisofs], [1.2.2], [http://libburnia-project.org])
AC_INIT([libisofs], [1.3.2], [http://libburnia-project.org])
AC_PREREQ([2.50])
dnl AC_CONFIG_HEADER([config.h])
@ -40,7 +40,7 @@ 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_MINOR_VERSION=3
LIBISOFS_MICRO_VERSION=2
LIBISOFS_VERSION=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION.$LIBISOFS_MICRO_VERSION
@ -51,10 +51,10 @@ AC_SUBST(LIBISOFS_VERSION)
dnl Libtool versioning
LT_RELEASE=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION
# 2012.01.28 development jump has not yet happened
# SONAME = 64 - 58 = 6 . Library name = libisofs.6.58.0
LT_CURRENT=64
LT_AGE=58
# 2013.08.07 development jump has not yet happened
# SONAME = 74 - 68 = 6 . Library name = libisofs.6.68.0
LT_CURRENT=74
LT_AGE=68
LT_REVISION=0
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`

View File

@ -15,9 +15,11 @@ 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.
MBR, for PC-BIOS x86 from (pseudo-) hard disk
- SYSLINUX isohybrid MBR
- GRUB2 grub-mkrescue MBR.
Master Boot Record (MBR), for PC-BIOS x86 from (pseudo-) hard disk
Apple Partition Map (APM), for more modern Mac
GUID Partition Table (GPT), for EFI from (pseudo-) hard disk
MIPS Volume Header, for MIPS Big Endian, e.g. SGI Indigo2.
@ -25,6 +27,16 @@ DEC Boot Block, for MIPS Little Endian , e.g. DECstation.
SUN Disk Label and boot images, for SUN SPARC
PowerPC Reference Platform (PReP), for IBM PowerPC
Common Hardware Reference Platform (CHRP), for IBM PowerPC
Combinations of boot mechanisms:
- SYSLINUX isohybrid MBR
- SYSLINUX isohybrid for MBR, UEFI and x86-Mac
- GRUB2 grub-mkrescue MBR
>>> Mac and/or PowerPC bootable GRUB2 image with HFS+/FAT, APM,
EFI GPT partition, PreP MBR partition, mountable FAT partition
------------------------------------------------------------------------------
@ -44,7 +56,13 @@ with arbitrary content. This prescription is obeyed by PC-BIOS systems only
if the ISO 9660 image is presented on CD, DVD or BD media.
In this case the El Torito Boot record is the starting point of booting.
The Boot Record is a ECMA-119 Volume Descriptor which is eventually located
After the System Area, an ISO 9660 image usually has three distinct block
intervals for:
- Volume descriptors (Primary Volume Descriptor, Boot Record, Joliet, ...)
- Directory trees, tables, boot catalog, embedded partitions and filesystems.
- Data file content, including content of El Torito boot images.
The Boot Record is an ECMA-119 Volume Descriptor which is eventually located
at 2 kB block number 17 (decimal). Its content points to the location of the
Boot Catalog.
The format is described in part by ECMA-119 8.2 "Boot Record" and further
@ -101,7 +119,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 is:
Further in use by GRUB2 and ISOLINUX is:
0xef = EFI, a competitor resp. successor to PC-BIOS, possibly in use with
Intel ia64 Itanium and possibly with newer Apple machines.
@ -248,7 +266,7 @@ Byte Range | Value | Meaning
------------------------------------------------------------------------------
MBR
Master Boot Record (MBR)
for PC-BIOS x86 from (pseudo-) hard disk
Sources:
@ -343,92 +361,244 @@ See <libisofs/libisofs.h> for call iso_write_opts_set_part_offset()
and http://libburnia-project.org/wiki/PartitionOffset for examples with
program xorriso.
------------------------------------------------------------------------------
Apple Partition Map (APM)
for Apple Macs introduced since 2000 and more computer-like than iPad
from CD and often from (pseudo-) hard disk
Sources:
http://mjg59.dreamwidth.org/11285.html
http://opensource.apple.com/source/IOStorageFamily/IOStorageFamily-116/IOApplePartitionScheme.h (typedef struct Block0)
http://www.informit.com/articles/article.aspx?p=376123&seqNum=3
syslinux-4.05/utils/isohybrid.c
Mail conversations with Vladimir Serbinenko.
APM has an adjustable block size. Because the ISO images shall always work
on optical media, and in order to make room for the header block of an
additional GPT, only block size 2048 is considered here.
The role of APM in the boot process is to guide the firmware to a
HFS+ filesystem.
Block0 of an APM begins at byte 0 of the medium. Thus it collides with MBR and
other boot sector formats. By lucky coincidence it is possible to compose
a mock-up of a Block0 which is acceptable to firmware which expects APM,
and is also harmless x86 machine code with no negative side effects.
So it is possible to combine APM with an especially prepared MBR.
The layout of a Block0 of an APM is:
Byte Range | Value | Meaning (all numbers are stored big endian)
---------- | ---------- | ----------------------------------------------------
0 - 1 | sig | Signature 0x45 = 'E' , 0x52 = 'R'
2 - 3 | block_size | 0x0800 = 2048
4 - 7 | block_count| Number of blocks covered by APM
| | Often some x86-harmless dummy. E.g. 0x9090 = 37008
| | or 0xeb02ffff = 3,942,842,367
8 - 9 | dev_type | obscure: "device type"
10 - 11 | dev_id | obscure: "device id"
12 - 15 | drv_data | obscure: "driver data"
16 - 17 | drv_count | obscure: "driver descriptor count"
18 - 81 | drv_map | obscure: "driver descriptor table"
| | with 8 entries of 16 bytes each
82 - 511 | reserved |
---------- | ---------- | ----------------------------------------------------
The SYSLINUX program isohybrid.c overwrites the first 32 bytes of this
layout by its dummy values. It uses the small block_count 0x00009090 and
sets all bytes up to 31 to 0.
The libisofs HFS+ extension by Vladimir Serbinenko overwrites only the
first 8 bytes. It uses the large block_count 0xeb02ffff.
Block0 and the following APM entries each occupy 1 block of the announced size.
The first APM entry describes the range from its own start to the end of the
last APM entry. Each of the other APM entries describes a partition.
The layout of an Apple partition map entry is:
Byte Range | Value | Meaning (all numbers are stored big endian)
---------- | ---------- | ----------------------------------------------------
0 - 1 | sig | Signature 0x50 = 'P' , 0x4d = 'M'
2 - 3 | reserved |
4 - 7 | map_entries| Number of partition entries.
| | All entries show the same number.
8 - 11 | start_block| "physical block start of partition"
12 - 15 | block_count| "physical block count of partition"
16 - 47 | name | Partition name
48 - 79 | type | Type string
80 - 83 | lb_start | Logical block start = 0
84 - 87 | lb_count | Logical block count (same as block_count)
88 - 91 | flags | Status flags
| | bit0= entry is valid
| | bit1= entry is allocated
| | bit4= partition is readable
| | bit5= partition is writable
| | bit30= automatic mount (legacy Mac)
92 - 95 | boot_block | Logical start block number of boot code = 0
96 - 99 | boot_bytes | Number of bytes in boot code = 0
100 - 119 | | More boot code stuff = 0
120 - 135 | processor | "processor type" = 0
136 - 511 | reserved |
---------- | ---------- | ----------------------------------------------------
For the first APM entry (byte 0x0800), the following values apply:
map_entries = number of APM entries, including itself. E.g. 4.
start_block = 1
block_count = map_entries
name = "Apple"
type = "Apple_partition_map"
flags = 3
libisofs uses APM to mark a HFS+ filesystem partition within an ISO 9660 image.
Usually the APM has 3 more entries after the first entry:
Entry 2 (byte 0x1000) describes the block interval from ISO image start to
the start of the HFS+ filesystem meta data.
start_block = 16
block_count = start_of_hfs - 16
name = "Gap0"
type = "ISO9660_data"
flags = 0x13
Entry 3 (byte 0x1800) describes the interval from the start of the HFS+ meta
data to the end of the HFS+ data at the end of its partition. This includes all
content blocks of the data files in the ISO image.
start_block = start_of_hfs
block_count = end_of_hfs - start_of_hfs
name = "HFSPLUS_Hybrid"
type = "Apple_HFS"
flags = 0x40000013
Entry 4 (byte 0x2000) describes the interval from the end of the HFS+
partition to the end of the ISO image. It is possible that this interval is
empty. In this case, no fourth APM entry will be written.
start_block = end_of_hfs
block_count = end_of_iso - end_of_hfs
name = "Gap1"
type = "ISO9660_data"
flags = 0x13
>>> Open questions:
>>> What HFS+ blessings are needed for booting ?
>>> What files need what HFS creator and type settings ?
------------------------------------------------------------------------------
SYSLINUX Isohybrid MBR
GUID Partition Table (GPT)
for alternative mountability paths
and for EFI booting of some Apple Macs from (pseudo-) hard disk
Sources:
syslinux-3.72/utils/isohybrid , a perl script by H. Peter Anvin = hpa.
Mailing list conversations with hpa.
http://mjg59.dreamwidth.org/11285.html
http://mjg59.fedorapeople.org/Fedora-LiveCD.iso
http://en.wikipedia.org/wiki/GUID_Partition_Table
http://en.wikipedia.org/wiki/GUID
An isohybrid MBR directs the booting BIOS to an ISOLINUX boot image which
is also the target of an El Torito boot catalog entry.
For that purpose one has to take an MBR template and has to set a few bytes
to values which sufficiently describe the ISO image and the boot image file.
GPT is the partition map format of EFI, a successor of PC-BIOS.
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.
Words are composed little-endian style.
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 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.
Byte Range | Value | Meaning
The header block format is:
Byte Range | Value | Meaning (little endian numbers, LBA unit is 512 byte)
---------- | ---------- | ----------------------------------------------------
0 - 431 | = opaque = | Syslinux machine code provided by MBR template
| |
432 - 439 | hd_bootlba | Address of the ISOLINUX boot image file in the
| | ISO image. Counted in 512 byte blocks.
| |
440 - 443 | mbr_id | Random number
444 - 445 | 0 | Padding
| |
446 - 509 | ========== | Partition table
| |
446 - 461 | part_entry | Partition table entry 1 describing ISO image size
| | starting at LBA 0. I.e. contrary to tradition.
| | See above for partition table entry format.
| |
462 - 509 | 0 | Unused partition entries 2 to 4
510 - 511 | 0xaa55 | MBR signature
0 - 7 | sig | Signature "EFI PART" (with no trailing zero)
8 - 11 | revision | Revision = {0x00, 0x00, 0x01, 0x00} meaning "1.0"
12 - 15 | head_size | Header size = 0x5c = 92
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.
40 - 47 | first_lba | First usable LBA for partitions
48 - 55 | last_lba | Last usable LBA for partitions
56 - 71 | guid | Disk GUID, Random
72 - 79 | part_start | Partition entries start
| | Normally this is 2. But to co-exist with APM, it
| might become some other number up to 62.
80 - 83 | entry_count| Number of partition entries
84 - 87 | entry_size | Size of a partition entry = 0x80 = 128
88 - 91 | p_arr_crc | CRC-32 of the partition array
92 - 511 | reserved | Must be 0
---------- | ---------- | ----------------------------------------------------
The CRC-32 algorithm can be characterized as follows:
The generating polynomial has the bit representation 0x104c11db7.
The seed value for a bit shifting division algorithm is 0x46af6449. It is
chosen so that the CRC of 0 bytes of input is 0x00000000.
The least significant bits of input bytes get processed first. I.e. bit0 of
the last input byte gets mapped to x exp (7 + 32), bit7 of this byte gets
mapped to x exp (0 + 32).
The resulting division residue gets bitwise mirrored. E.g. bit0 becomes bit31,
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
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.
The partition table is an array of entries. Each has a size of 128 bytes.
A partition table entry looks like:
Byte Range | Value | Meaning (numbers are stored little endian)
---------- | ---------- | ----------------------------------------------------
0 - 15 | type_guid | Partition type GUID
16 - 31 | part_guid | Unique partition GUID, Random
32 - 39 | start_lba | First LBA
40 - 47 | end_lba | Last LBA (inclusive)
48 - 55 | flags | Attribute flags
| | bit0= "System Partition" Do not alter.
| | bit2= Legacy BIOS bootable (MBR partition type 0x80)
| | bit60= read-only
56 - 127 | name | Characters encoded as UTF-16LE. Padded by 0-bytes.
---------- | ---------- | ----------------------------------------------------
hpa about MBR templates and partition table filesystem types:
About header field "Location of header backup block":
"[MBR templates] are available in the Syslinux build tree under the names:
mbr/isohdp[fp]x*.bin
The default probably should be mbr/isohdppx.bin, but it's ultimately up
to the user.
[...]
Note: the filesystem type is largely arbitrary, in theory it can be any
value other than 0x00, 0x05, 0x0f, 0x85, 0xee, or 0xef. 0x17 ("Windows
IFS Hidden") seems safeish, some people believe 0x83 (Linux) is better.
"
Near to the end of the image, after any data blocks which might be of interest
for the filesystems covered by GPT partitions, there is a backup of partition
table and header block.
The header block is supposed to mark the end of the usable medium. But libisofs
may have the need to add more data.
The partition table is stored directly before the header block. So it will
normally not begin at a 2 KiB block start.
------------------------------------------------------------------------------
GRUB2 grub-mkrescue MBR
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.
Byte Range | Value | Meaning
The content of the backup partition table is the same as the one of the
primary table.
The backup header differs from the primary header by
Byte Range | Value | Meaning (little endian numbers, LBA unit is 512 byte)
---------- | ---------- | ----------------------------------------------------
0 - 445 | = opaque = | GRUB2 machine code provided by MBR template
| |
446 - 509 | ========== | Partition table
| |
446 - 461 | part_entry | Partition table entry 1 describing ISO image size
| | Peculiar is the start offset of 1 block.
| | This prevents mounting of the partition.
| | See above for partition table entry format.
| |
462 - 509 | 0 | Unused partition entries 2 to 4
510 - 511 | 0xaa55 | MBR signature
16 - 19 | head_crc | CRC-32 of this header while head_crc is 0.
| | 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.
| | Points to primary header block = 1
72 - 79 | part_start | Partition entries start.
| | Points to start of backup partition table.
---------- | ---------- | ----------------------------------------------------
Vladimir Serbinenko about the partition table entry:
"Currently we use first and not last entry. You need to:
1) Zero-fill 446-510
2) Put 0x55, 0xAA into 510-512
3) Put 0x80 (for bootable partition), 0, 2, 0 (C/H/S of the start), 0xcd
(partition type), [3 bytes of C/H/S end], 0x01, 0x00, 0x00, 0x00 (LBA
start in little endian), [LBA end in little endian] at 446-462
"
An EFI System partition usually contains the same data blocks as the El Torito
boot image for EFI. It is used for booting some Macs from (pseudo-) hard disk.
------------------------------------------------------------------------------
@ -715,6 +885,41 @@ Byte Range | Value | Meaning
---------- | ---------- | ----------------------------------------------------
------------------------------------------------------------------------------
PowerPC Reference Platform (PReP)
for IBM PowerPC
Sources:
Mail conversations with Vladimir Serbinenko.
PReP boots via a MBR partition containing only raw ELF and having type 0x41.
------------------------------------------------------------------------------
Common Hardware Reference Platform (CHRP)
for IBM PowerPC
Sources:
Mail conversations with Vladimir Serbinenko.
http://stuff.mit.edu/afs/sipb/contrib/doc/specs/protocol/chrp/chrp1_7a.pdf
CHRP is marked by an MBR partition entry of type 0x96 spanning the whole
ISO 9660 image.
The specs in chrp1_7a.pdf promise that CHRP also recognizes ISO 9660 file
systems on unpartitioned disks. (See 11.1.1. Media Layout Format)
Vladimir Serbinenko stated:
PReP boot may be preferable. At least it can co-exist with other partitions
in the ISO image [without causing overlapping between partitions].
------------------------------------------------------------------------------
>>> ??? HP-PA
@ -723,5 +928,505 @@ Byte Range | Value | Meaning
>>> ??? DEC Alpha
------------------------------------------------------------------------------
Combinations of boot mechanisms
------------------------------------------------------------------------------
SYSLINUX Isohybrid MBR
Sources:
syslinux-3.72/utils/isohybrid , a perl script by H. Peter Anvin = hpa.
Mailing list conversations with hpa.
An isohybrid MBR directs the booting BIOS to an ISOLINUX boot image which
is also the target of an El Torito boot catalog entry.
For that purpose one has to take an MBR template and has to set a few bytes
to values which sufficiently describe the ISO image and the boot image file.
Words are composed little-endian style.
Byte Range | Value | Meaning
---------- | ---------- | ----------------------------------------------------
0 - 431 | = opaque = | Syslinux machine code provided by MBR template
| |
432 - 439 | hd_bootlba | Address of the ISOLINUX boot image file in the
| | ISO image. Counted in 512 byte blocks.
| |
440 - 443 | mbr_id | Random number
444 - 445 | 0 | Padding
| |
446 - 509 | ========== | Partition table
| |
446 - 461 | part_entry | Partition table entry 1 describing ISO image size
| | rounded up to the next full MiB. The partition starts
| | at LBA 0. (I.e. contrary to tradition.)
| | See above for partition table entry format.
| |
462 - 509 | 0 | Unused partition entries 2 to 4
510 - 511 | 0xaa55 | MBR signature
---------- | ---------- | ----------------------------------------------------
The ISO image file gets padded up to the next full MiB.
hpa about MBR templates and partition table filesystem types:
"[MBR templates] are available in the Syslinux build tree under the names:
mbr/isohdp[fp]x*.bin
The default probably should be mbr/isohdppx.bin, but it's ultimately up
to the user.
[...]
Note: the filesystem type is largely arbitrary, in theory it can be any
value other than 0x00, 0x05, 0x0f, 0x85, 0xee, or 0xef. 0x17 ("Windows
IFS Hidden") seems safeish, some people believe 0x83 (Linux) is better.
"
>>> SYSLINUX isohybrid for MBR, UEFI and x86-Mac
Sources:
http://mjg59.dreamwidth.org/11285.html
http://mjg59.fedorapeople.org/Fedora-LiveCD.iso
http://opensource.apple.com/source/IOStorageFamily/IOStorageFamily-116/IOApplePartitionScheme.h (typedef struct Block0)
http://www.informit.com/articles/article.aspx?p=376123&seqNum=3
http://en.wikipedia.org/wiki/GUID_Partition_Table
http://en.wikipedia.org/wiki/GUID
syslinux-4.05/utils/isohybrid.c
>>> Motivation: What systems will use the additional data ? amd64 UEFI ?
This is a very condensed format which exposes a lot of entry points for boot
firmware. It disobeys some of the prescriptions in the previous chapter.
Byte Range | Value | Meaning
-------------- | ---------- | -------------------------------------------------
0 - 511 | mbr | Isohybrid MBR pointing to x86 boot image file,
| | with three entries in its partition map.
| | It shares its first 32 bytes with apm_head.
0 - 31 | apm_head | Mock-up of the start of the first block of
| | an Apple Partition Map (APM).
446 - 461 | mbr_entry1 | Partition table entry 1 describing the size of
| | the ISO image plus the backup GPT, padded up to
| | the next full MiB.
462 - 477 | mbr_entry2 | Entry 2 describing the EFI VFAT boot image.
478 - 493 | mbr_entry3 | Entry 3 describing the HFS+ boot image.
| |
512 - 1023 | gpt_head | GPT header describing the GPT partition array.
1024 - 2047 | unused |
2048 - 4095 | apm_entry1 | APM entry 1 describing APM entries 1 to 3.
4096 - 6143 | apm_entry2 | APM entry 2 describing the EFI VFAT boot image.
6144 - 8195 | apm_entry3 | APM entry 3 describing the HFS+ boot image.
8192 - 8319 | gpt_entry1 | GPT partition entry 1 for the ISO image size.
8320 - 8447 | gpt_entry2 | GPT partition entry 2 for EFI VFAT boot image,
8448 - 8575 | gpt_entry3 | GPT partition entry 3 for the HFS+ boot image.
8576 - 24575 | gtp_empty | Empty GPT partition entries 4 to 128.
24576 - 32767 | unused |
32768 - 34815 | iso_pvd | ISO 9660 superblock
34816 - 36863 | el_torito | EL Torito boot block pointing to a boot catalog
| | with entries for the MBR boot image (platform id
| | 0x00), and for the two other boot images
| | (platform id 0xef)
-------------- | ---------- | -------------------------------------------------
For the purpose of booting, there may be two EFI boot image files in the
ISO image. A VFAT image and a HFS+ image. The content of both is not in the
scope of this document.
These boot images get announced by EL Torito boot catalog entries with
Platform Id 0xef.
Newer SYSLINUX MBR templates begin by 32 bytes of machine code which are
intentionally non-essential:
33 ed 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
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:
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
that is described in the following text.
The layout of Block0 is constant:
Byte Range | Value | Meaning (all numbers are stored big endian)
---------- | ---------- | ----------------------------------------------------
0 - 1 | sig | Signature 0x45 = 'E' , 0x52 = 'R'
2 - 3 | block_size | 0x0800 = 2048
4 - 7 | block_count| 0x9090 = 37008
8 - 9 | dev_type | obscure: "device type" = 0
10 - 11 | dev_id | obscure: "device id" = 0
12 - 15 | drv_data | obscure: "driver data" = 0
16 - 17 | drv_count | obscure: "driver descriptor count" = 0
18 - 81 | drv_map | obscure: "driver descriptor table"
| | with 8 entries of 16 bytes each
| | first 14 bytes are 0
---------- | ---------- | ----------------------------------------------------
The block_count of 0x9090 is pure fantasy. It shall only mark the disc as
not empty.
The data block ranges of the two EFI boot images get described by MBR
partition entries 2 and 3, which thus claim blocks inside of partition 1.
This partition nesting is acceptable to some EFI implementations only if the
type of partition 1 is 0x00.
The MBR partition entry number 1 is
80 00 01 00 00 3f a0 89 00 00 00 00 00 50 14 00
It marks the partition as bootable, starting at block 0, with a size that
is the smallest full MiB not smaller than the ISO image size + 18 KiB.
(The 18 KiB are needed for the GPT backup.)
The ISO image has a size of 332362 blocks of 2K = 1329448 * 512 = 649.14 MiB.
The partition size is 0x145000 = 1331200 * 512 = 650 MiB.
Start C/H/S = 0/0/1, type is 0x0 ("Empty"), end C/H/S is 649/63/32.
Partition 2:
00 fe ff ff ef fe ff ff a4 00 00 00 70 04 00 00
Start block is 0xa4 = 164 * 512 = 41 * 2048. The VFAT image file.
Partition size is 0x0470 = 1136 * 512. The size of that file.
Start C/H/S = 1023/254/63, type 0xef (fdisk says: "EFI (FAT-12/16/"),
end C/H/S = 1023/254/63.
Partition 3:
00 fe ff ff 00 fe ff ff 44 05 00 00 c0 08 00 00
Start block is 0x0544 = 1348 * 512 = 337 * 2048. The HFS+ image file.
Partition size is 0x08c0 = 2240 * 512. The size of that file.
Start C/H/S = 1023/254/63, type 0x00 ("Empty"), end C/H/S = 1023/254/63.
The second 512-block in the ISO image is the GPT header.
45 46 49 20 50 41 52 54 00 00 01 00 5c 00 00 00
E F I P A R T
13 db 71 5d 00 00 00 00 01 00 00 00 00 00 00 00
fe 4f 14 00 00 00 00 00 30 00 00 00 00 00 00 00
de 4f 14 00 00 00 00 00 73 23 c8 79 19 e6 97 4d
95 17 69 30 c5 38 e2 99 10 00 00 00 00 00 00 00
80 00 00 00 80 00 00 00 5b 6b 8a 65
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
| | This is 1 KiB before the end of MBR partition 1
| | (but should be 512 bytes).
| | (Potential isohybrid.c bug #1:
| | Backup GPT is dislocated by 512 bytes.)
40 - 47 | first_lba | First usable LBA for partitions = 0x30 = 48
48 - 55 | last_lba | Last usable LBA for partitions = 0x144fde = 1331166
56 - 71 | guid | Disk GUID
| | Random, produced by uuid_generate(),
| | 32,16,16 byte swapped
72 - 79 | part_start | Partition entries start LBA = 0x10 = 16 = byte 0x2000
| | (This is unusual. It leaves room for the Apple
| | partition map entries.)
80 - 83 | entry_count| Number of partition entries 0x80 = 128
84 - 87 | entry_size | Size of a partition entry = 0x80 = 128
---------- | ---------- | ----------------------------------------------------
Because the block size was announced as 2048, the first Apple partition map
entry is located at byte 0x800 = 2048.
It describes the partition map itself:
50 4d 00 00 00 00 00 03 00 00 00 01 00 00 00 10
P M
41 70 70 6c 65 00 00 00 00 00 00 00 00 00 00 00
A p p l e
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
41 70 70 6c 65 5f 70 61 72 74 69 74 69 6f 6e 5f
A p p l e _ p a r t i t i o n _
6d 61 70 00 00 00 00 00 00 00 00 00 00 00 00 00
m a p
00 00 00 00 00 00 00 0a 00 00 00 03 00 00 00 00
Byte Range | Value | Meaning (all numbers are stored big endian)
---------- | ---------- | ----------------------------------------------------
4 - 7 | map_entries| "number of partition entries" = 3
8 - 11 | start_block| "physical block start of partition" = 1
12 - 15 | block_count| "physical block count of partition" = 16
| | (Potential isohybrid.c bug #2:
| | The value of 16 claims the ISO 9660 PVD as part of
| | the partition table. It should be 4 instead.)
16 - 47 | name | Partition name = "Apple"
48 - 79 | type | Type string = "Apple_partition_map"
80 - 83 | lb_start | Logical block start = 0
84 - 87 | lb_count | Logical block count = 10
88 - 91 | flags | Status flags = 3 (valid, allocated)
92 - 95 | boot_block | Logical start block number of boot code = 0
96 - 99 | boot_bytes | Number of bytes in boot code = 0
100 - 119 | | More boot code stuff = 0
120 - 135 | processor | "processor type" = 0
136 - 511 | reserved |
---------- | ---------- | ----------------------------------------------------
(Potential isohybrid.c bug #2:
Apple partition map entries bear the block count for blocks of 512 bytes
whereas Apple Block0 announces blocks of 2048 bytes.)
The next Apple partition map entry is at byte 0x1000 = 4096:
50 4d 00 00 00 00 00 03 00 00 00 29 00 00 04 70
45 46 49 00 00 00 00 00 00 00 00 00 00 00 00 00
E F I
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
41 70 70 6c 65 5f 48 46 53 00 00 00 00 00 00 00
A p p l e _ H F S
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 04 70 00 00 00 33 00 00 00 00
3 partitions, start block is 0x29 = 41,
block count is 0x0470 = 1136 (should be 284), name is "EFI",
type is "Apple_HFS" (although this is a FAT image),
logical block start = 0, lb_count = 1136 (should be 284),
flags = 0x33 : valid, allocated, readable, writable.
This points to file /isolinux/efiboot.img in the ISO image.
(Potential isohybrid.c bug #2:
Apple partition map entries bear the block count for blocks of 512 bytes
whereas Apple Block0 announces blocks of 2048 bytes.)
At byte 0x1800 = 6144, there is Apple partition map entry 3:
50 4d 00 00 00 00 00 03 00 00 01 51 00 00 08 c0
45 46 49 00 00 00 00 00 00 00 00 00 00 00 00 00
E F I
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
41 70 70 6c 65 5f 48 46 53 00 00 00 00 00 00 00
A p p l e _ H F S
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 08 c0 00 00 00 33 00 00 00 00
3 partitions, start block is 0x0151 = 337 (LBA of /isolinux/macboot.img),
block count = 0x08c0 = 2240 (should be 560), name is "EFI",
type is "Apple_HFS", logical block start = 0, lb_count = 2240 (should be 560),
flags = 0x33 : valid, allocated, readable, writable.
(Potential isohybrid.c bug #2:
Apple partition map entries bear the block count for blocks of 512 bytes
whereas Apple Block0 announces blocks of 2048 bytes.)
At byte 0x2000 = 8192 begins the GPT partition array.
It ends at byte 0x4000 = 16384.
a2 a0 d0 eb e5 b9 33 44 87 c0 68 b6 b7 26 99 c7
a1 87 a1 ba 4d 2c 27 45 ae 05 cf ab a6 fa 87 c1
00 00 00 00 00 00 00 00 28 49 14 00 00 00 00 00
00 00 00 00 00 00 00 00 49 53 4f 48 79 62 72 69
I S O H y b r i
64 20 49 53 4f 00 49 53 4f 48 79 62 72 69 64 00
d I S O I S O H y b r i d
41 70 70 6c 00 00 00 00 00 00 00 00 00 00 00 00
A p p l
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Byte Range | Value | Meaning (numbers are stored little endian)
---------- | ---------- | ----------------------------------------------------
0 - 15 | type_guid | Partition type GUID = Basic data partition
| | Wikipedia: "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7"
| | (Note: The first three words are shown byte swapped)
16 - 31 | part_guid | Unique partition GUID
| | Random, produced by uuid_generate()
| | 32,16,16 byte swapped
32 - 39 | start_lba | First LBA = 0
40 - 47 | end_lba | Last LBA (inclusive) = 0x144828 = 1329448
| | This is the ISO image size in blocks of 512.
| | (Potential isohybrid.c bug #3:
| | The end_lba in the first GPT entry should be 1 less
| | than the count of 512 byte blocks of the ISO image.)
48 - 55 | flags | Attribute flags = 0
56 - 127 | name | Wikipedia says UTF-16LE.
| | (Potential isohybrid.c bug #4:
| | The name in Fedora-LiveCD.iso is 8 bit and result
| | of faulty memory operation on a text constant.)
---------- | ---------- | ----------------------------------------------------
Next entry is at 0x2800 = 10240:
a2 a0 d0 eb e5 b9 33 44 87 c0 68 b6 b7 26 99 c7
c8 de c8 1f fb f0 51 40 8c 8a d2 f6 b1 46 16 dc
a4 00 00 00 00 00 00 00 13 05 00 00 00 00 00 00
00 00 00 00 00 00 00 00 49 53 4f 48 79 62 72 69
I S O H y b r i
64 00 41 70 70 6c 65 00 41 70 70 6c 00 00 00 00
d A p p l e A p p l
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Partition type GUID : "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7" = Basic data
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.)
Next entry at byte 0x02100 = 8448:
00 53 46 48 00 00 aa 11 aa 11 00 30 65 43 ec ac
c8 de c8 1f fb f0 51 40 8c 8a d2 f6 b1 46 16 dc
44 05 00 00 00 00 00 00 03 0e 00 00 00 00 00 00
00 00 00 00 00 00 00 00 49 53 4f 48 79 62 72 69
I S O H y b r i
64 00 41 70 70 6c 65 00 41 70 70 6c 00 00 00 00
d A p p l e A p p l
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Partition type GUID : "48465300-0000-11AA-AA11-00306543ECAC" = HFS+
Start block is 0x0544 = 1348 * 512 = 337 * 2048. The HFS+ image file.
Last block is 0x0e03 = 3587 = 1348 + 2239. Correct.
(Potential isohybrid.c bug #4:
Wrong character set and incidential bytes in GPT partition name.)
The rest of the System Area is 0 up to the Primary Volume Descriptor
at block 16.
The ISO image file gets padded up to full MiB with sufficient room for the GPT
backup which is stored near the very end of the image file. There is need for
at least 16.5 KiB, which effectively occupy 18 KiB.
The backup partition array is stored 17 KiB before the end of MBR partition 1
resp. the image file.
(Potential isohybrid.c bug #1:
Wikipedia suggests "LBA -33" counted from end. This would be 16.5 KiB before
end.)
The GPT header is stored 1 KiB before the end of MBR partition 1.
(Potential isohybrid.c bug #1:
Wikipedia suggests "LBA -1" counted from end. This would be 512 bytes.)
45 46 49 20 50 41 52 54 00 00 01 00 5c 00 00 00
E F I P A R T
f6 61 10 1c 00 00 00 00 fe 4f 14 00 00 00 00 00
01 00 00 00 00 00 00 00 30 00 00 00 00 00 00 00
de 4f 14 00 00 00 00 00 73 23 c8 79 19 e6 97 4d
95 17 69 30 c5 38 e2 99 de 4f 14 00 00 00 00 00
80 00 00 00 80 00 00 00 5b 6b 8a 65
It differs by its own CRC and by some of its parameters:
Own address is 0x144ffe. The backup lba is 0x01 = Primary GPT header.
Partition entries start is 0x144fde
(Potential isohybrid.c bug #1:
This overlaps with the last usable LBA. The backup GPT must move up by
512 bytes.)
------------------------------------------------------------------------------
GRUB2 grub-mkrescue MBR
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.
Byte Range | Value | Meaning
---------- | ---------- | ----------------------------------------------------
0 - 445 | = opaque = | GRUB2 machine code provided by MBR template
| |
446 - 509 | ========== | Partition table
| |
446 - 461 | part_entry | Partition table entry 1 describing ISO image size
| | Peculiar is the start offset of 1 block.
| | This prevents mounting of the partition.
| | See above for partition table entry format.
| |
462 - 509 | 0 | Unused partition entries 2 to 4
510 - 511 | 0xaa55 | MBR signature
---------- | ---------- | ----------------------------------------------------
Vladimir Serbinenko about the partition table entry:
"Currently we use first and not last entry. You need to:
1) Zero-fill 446-510
2) Put 0x55, 0xAA into 510-512
3) Put 0x80 (for bootable partition), 0, 2, 0 (C/H/S of the start), 0xcd
(partition type), [3 bytes of C/H/S end], 0x01, 0x00, 0x00, 0x00 (LBA
start in little endian), [LBA end in little endian] at 446-462
"
------------------------------------------------------------------------------
>>> Mac and/or PowerPC bootable GRUB2 image with HFS+/FAT, APM,
EFI GPT partition, PreP MBR partition, mountable FAT partition
>>> ? With PC-BIOS MBR x86 Code ?
This storage layout was mainly defined by Vladimir Serbinenko. It relies much
on the embedded HFS+/FAT filesystem for which he provided the code to libisofs.
Start Blocks (2 KiB):
0 System Area
16 Volume Descriptors
TREE ISO-RR tree, Joliet tree, other trees and meta data, except HFS+/FAT
EFI EFI boot image partition (optional)
PREP Prep image partition (optional)
HFAT HFS+/FAT metadata (optional)
DATA Data file content (including El Torito boot images)
HFSB HFS superblock backup (if HFS+/FAT metadata)
TAIL Further tails and paddings (optional)
GPTB GPT backup (if GPT in System Area)
END End of ISO image
System Area may contain simultaneously:
MBR (x86 boot code must leave room for 8 bytes mock-up of APM Block0)
APM
GPT
MBR Partitions:
0xee from 0 to PREP-1, protective partition, announcing presence of GPT
0x41 from PREP to HFAT-1, PreP partition
0x0c from HFAT to END-1, FAT partition, bootable bit on
0x00 Empty partition
GPT Partitions:
The primary GPT itself covers the System Area.
Basic Data from 16 to EFI-1, protects first part of ISO image
EFI System from EFI to PREP-1, offers EFI image for booting
Basic Data from PREP to HFAT-1, protects PreP partition
HFS+ from HFAT to TAIL-1, offers HFS+ for mounting
Basic Data from TAIL to GPTB-1, protects rest of ISO image (if there is)
APM Partitions:
The range from end of APM to end of System Area stays unprotected.
(The primary GPT might sit there.)
Apple_partition_map from 1 to 3 or 4, covers the APM itself
ISO9660_data from 16 to HFAT-1, covers first part of ISO image
Apple_HFS from HFAT to GPTB-1, offers HFS+ for boot and mount
ISO9660_data from GPTB to END-1, covers rest of ISO image
(might be omitted if empty)
El Torito:
Boot image for 80x86 PC-BIOS
Boot image for EFI (usually the same file as the partition EFI to PREP-1).
If optional components are not present, then their addresses coincide with
the address of the next component that is present. E.g. HFAT == DATA if no
HFS+/FAT filesystem is present.
If no FAT filesystem is present within HFS+/FAT, then the type of the last
partition is 0xcd.
If neither EFI, nor PreP, nor FAT within HFS+/FAT, are present, then there
is only one partition. It has type 0xee, if GPT is present in the System Area.
It has type 0xcd and offset 1*512, if no GPT is present.
Involved -as mkisofs options:
-hfsplus
-fat
-efi-boot-part DISKFILE
-prep-boot-part DISKFILE
>>> What boots by what ?
------------------------------------------------------------------------------

View File

@ -3,7 +3,7 @@
by Thomas Schmitt - mailto:scdbackup@gmx.net
Libburnia project - mailto:libburn-hackers@pykix.org
21 Feb 2012
07 Jun 2012
The overall framework for the filesystem images produced by libisofs is given
@ -84,6 +84,23 @@ libisofs/ecma119.h at struct ecma119_image.system_area_options and in
libisofs/libisofs.h at call iso_write_opts_set_system_area(). See e.g.
"MIPS Big Endian Volume Header".
libisofs/system_area.h offers an inner API to define partitions for Apple
Partition Map (APM) and for GPT from within the compute_data_blocks methods
of the IsoImageWriter objects (see below). If both get combined, then
APM block size must be 2048. In this case, the partition entries of APM
and GPT overwrite the following bytes of the submitted
Ecma119Image.system_area_data:
0x0000 to 0x0007 by { 0x45, 0x52, 0x08 0x00, 0xeb, 0x02, 0xff, 0xff}
0x0200 to 0x02ff by GPT header block
0x0800 to APM_end by APM blocks (APM_end = 2048*(Num_APM_partitions + 1)
APM_end+1 to 0x7fff by GPT entries
This offers still room for a PC-BIOS MBR which has essentially no-op commands
in its first 8 bytes.
If no GPT is desired, then the bytes after APM_end stay unaltered.
If more modesty with overwriting is needed, then this would have to be caused
by either a specialized system area type or by additional elements of the
inner API for APM and GPT.
The layout of the areas above image_start+16 is defined in function
libisofs/ecma119.c:ecma119_image_new(). This is done by creating and
@ -120,6 +137,8 @@ libisofs will call the methods of the writer object when it computes the
block addresses of the various image components, when it writes volume
descriptors, when it writes directory trees, and when it finally disposes the
Ecma119Image object.
Before calling the first method, it will publish the number of data file
content blocks in Ecma119Image.filesrc_blocks.
The method IsoImageWriter.compute_data_blocks() has to predict the storage
needs in the area of directory trees.
@ -148,6 +167,15 @@ struct iso_file_section is defined in libisofs/libisofs.h.
IsoImageWriter.free_data() disposes the writer and the JolietNode tree.
Further examples for add-on writers are those created by:
hfsplus_writer_create() is in charge for initial part of an
embedded HFS+ filesystem
hfsplus_tail_writer_create() is in charge for trailing part of HFS+
after the data file content area
gpt_tail_writer_create() is in charge for the backup GPT near the
end of the ISO image
-------------------------------------------------------------------------------
This text is under

View File

@ -123,6 +123,55 @@ Registered:
-------------------------------------------------------------------------------
Name:
isofs.hb
Purpose:
Records the IsoHfsplusBlessings blessing of a IsoNode as defined
in libisofs.h. At image load time, this info shall 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.
Format of Value:
BLESSING
This is a single byte out of {'p', 'i', 's', '9', 'x'} for
ISO_HFSPLUS_BLESS_PPC_BOOTDIR, ISO_HFSPLUS_BLESS_INTEL_BOOTFILE,
ISO_HFSPLUS_BLESS_SHOWFOLDER, ISO_HFSPLUS_BLESS_OS9_FOLDER,
ISO_HFSPLUS_BLESS_OSX_FOLDER.
Example:
{ 'p' }
Registered:
07 Jun 2012 by Thomas Schmitt for xorriso.
-------------------------------------------------------------------------------
Name:
isofs.hx
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
attachment for iso_hfsplus_xinfo_func so that it is available for
the HFS+ writer when a new ISO 9660 / HFS+ image gets produced.
Format of Value:
VERSION_LEN | VERSION | CREATOR | TYPE
VERSION_LEN complies to ISO 9660 Format section 7.1.1.
The byte string VERSION begins with the most significant byte.
VERSION == 0 is the only one that is currently defined. It assures the
existence of 4 bytes CREATOR and 4 bytes TYPE.
Higher versions will keep these 8 bytes and possibly add new ones.
Example:
{ 1, 0, 'Y', 'Y', 'D', 'N', 'T', 'E', 'X', 'T' }
Registered:
07 Jun 2012 by Thomas Schmitt for xorriso.
-------------------------------------------------------------------------------
Name:
isofs.st

View File

@ -1,7 +1,7 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2007 Mario Danic
* Copyright (c) 2009 - 2012 Thomas Schmitt
* Copyright (c) 2009 - 2013 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -21,6 +21,7 @@
#include "ecma119.h"
#include "joliet.h"
#include "hfsplus.h"
#include "iso1999.h"
#include "eltorito.h"
#include "ecma119_tree.h"
@ -89,14 +90,8 @@ void ecma119_image_free(Ecma119Image *t)
writer->free_data(writer);
free(writer);
}
#ifdef Libisofs_with_rr_reloc_diR
if (t->rr_reloc_dir != NULL)
free(t->rr_reloc_dir);
#endif /* Libisofs_with_rr_reloc_diR */
if (t->input_charset != NULL)
free(t->input_charset);
if (t->output_charset != NULL)
@ -115,9 +110,25 @@ void ecma119_image_free(Ecma119Image *t)
free(t->writers);
if (t->partition_root != NULL)
ecma119_node_free(t->partition_root);
if (t->prep_partition != NULL)
free(t->prep_partition);
if (t->efi_boot_partition != NULL)
free(t->efi_boot_partition);
for (i = 0; i < ISO_MAX_PARTITIONS; i++)
if (t->appended_partitions[i] != NULL)
free(t->appended_partitions[i]);
for (i = 0; i < ISO_HFSPLUS_BLESS_MAX; i++)
if (t->hfsplus_blessed[i] != NULL)
iso_node_unref(t->hfsplus_blessed[i]);
for (i = 0; (int) i < t->apm_req_count; i++)
if (t->apm_req[i] != NULL)
free(t->apm_req[i]);
for (i = 0; (int) i < t->mbr_req_count; i++)
if (t->mbr_req[i] != NULL)
free(t->mbr_req[i]);
for (i = 0; (int) i < t->gpt_req_count; i++)
if (t->gpt_req[i] != NULL)
free(t->gpt_req[i]);
free(t);
}
@ -451,6 +462,64 @@ char *get_relaxed_vol_id(Ecma119Image *t, const char *name)
return strdup(name);
}
/**
* Set the timestamps of Primary, Supplementary, or Enhanced Volume Descriptor.
*/
void ecma119_set_voldescr_times(IsoImageWriter *writer,
struct ecma119_pri_vol_desc *vol)
{
Ecma119Image *t = writer->target;
int i;
if (t->vol_uuid[0]) {
for(i = 0; i < 16; i++)
if(t->vol_uuid[i] < '0' || t->vol_uuid[i] > '9')
break;
else
vol->vol_creation_time[i] = t->vol_uuid[i];
for(; i < 16; i++)
vol->vol_creation_time[i] = '1';
vol->vol_creation_time[16] = 0;
} else if (t->vol_creation_time > 0)
iso_datetime_17(vol->vol_creation_time, t->vol_creation_time,
t->always_gmt);
else
iso_datetime_17(vol->vol_creation_time, t->now, t->always_gmt);
if (t->vol_uuid[0]) {
for(i = 0; i < 16; i++)
if(t->vol_uuid[i] < '0' || t->vol_uuid[i] > '9')
break;
else
vol->vol_modification_time[i] = t->vol_uuid[i];
for(; i < 16; i++)
vol->vol_modification_time[i] = '1';
vol->vol_modification_time[16] = 0;
} else if (t->vol_modification_time > 0)
iso_datetime_17(vol->vol_modification_time, t->vol_modification_time,
t->always_gmt);
else
iso_datetime_17(vol->vol_modification_time, t->now, t->always_gmt);
if (t->vol_expiration_time > 0) {
iso_datetime_17(vol->vol_expiration_time, t->vol_expiration_time,
t->always_gmt);
} else {
for(i = 0; i < 16; i++)
vol->vol_expiration_time[i] = '0';
vol->vol_expiration_time[16] = 0;
}
if (t->vol_effective_time > 0) {
iso_datetime_17(vol->vol_effective_time, t->vol_effective_time,
t->always_gmt);
} else {
for(i = 0; i < 16; i++)
vol->vol_effective_time[i] = '0';
vol->vol_effective_time[16] = 0;
}
}
/**
* Write the Primary Volume Descriptor (ECMA-119, 8.4)
*/
@ -460,7 +529,6 @@ int ecma119_writer_write_vol_desc(IsoImageWriter *writer)
IsoImage *image;
Ecma119Image *t;
struct ecma119_pri_vol_desc vol;
int i;
char *vol_id, *pub_id, *data_id, *volset_id;
char *system_id, *application_id, *copyright_file_id;
char *abstract_file_id, *biblio_file_id;
@ -526,46 +594,11 @@ int ecma119_writer_write_vol_desc(IsoImageWriter *writer)
strncpy_pad((char*)vol.abstract_file_id, abstract_file_id, 37);
strncpy_pad((char*)vol.bibliographic_file_id, biblio_file_id, 37);
if (t->vol_uuid[0]) {
for(i = 0; i < 16; i++)
if(t->vol_uuid[i] < '0' || t->vol_uuid[i] > '9')
break;
else
vol.vol_creation_time[i] = t->vol_uuid[i];
for(; i < 16; i++)
vol.vol_creation_time[i] = '1';
vol.vol_creation_time[16] = 0;
} else if (t->vol_creation_time > 0)
iso_datetime_17(vol.vol_creation_time, t->vol_creation_time,
t->always_gmt);
else
iso_datetime_17(vol.vol_creation_time, t->now, t->always_gmt);
if (t->vol_uuid[0]) {
for(i = 0; i < 16; i++)
if(t->vol_uuid[i] < '0' || t->vol_uuid[i] > '9')
break;
else
vol.vol_modification_time[i] = t->vol_uuid[i];
for(; i < 16; i++)
vol.vol_modification_time[i] = '1';
vol.vol_modification_time[16] = 0;
} else if (t->vol_modification_time > 0)
iso_datetime_17(vol.vol_modification_time, t->vol_modification_time,
t->always_gmt);
else
iso_datetime_17(vol.vol_modification_time, t->now, t->always_gmt);
if (t->vol_expiration_time > 0)
iso_datetime_17(vol.vol_expiration_time, t->vol_expiration_time,
t->always_gmt);
if (t->vol_effective_time > 0)
iso_datetime_17(vol.vol_effective_time, t->vol_effective_time,
t->always_gmt);
ecma119_set_voldescr_times(writer, &vol);
vol.file_structure_version[0] = 1;
memcpy(vol.app_use, image->application_use, 512);
free(vol_id);
free(volset_id);
free(pub_id);
@ -959,6 +992,14 @@ int ecma119_writer_create(Ecma119Image *target)
return ret;
}
if (target->image->sparc_core_node != NULL) {
/* Obtain a duplicate of the IsoFile's Ecma119Node->file */
ret = iso_file_src_create(target, target->image->sparc_core_node,
&target->sparc_core_src);
if (ret < 0)
return ret;
}
if(target->partition_offset > 0) {
/* Create second tree */
target->eff_partition_offset = target->partition_offset;
@ -1231,10 +1272,11 @@ static
int write_head_part1(Ecma119Image *target, int *write_count, int flag)
{
int res, i;
uint8_t sa[16 * BLOCK_SIZE];
uint8_t *sa;
IsoImageWriter *writer;
size_t buffer_size = 0, buffer_free = 0, buffer_start_free = 0;
sa = target->sys_area_as_written;
iso_ring_buffer_get_buf_status(target->buffer, &buffer_size,
&buffer_start_free);
*write_count = 0;
@ -1326,6 +1368,8 @@ int write_head_part2(Ecma119Image *target, int *write_count, int flag)
ret = ISO_SUCCESS;
ex:;
if (buf != NULL)
free(buf);
return ret;
}
@ -1377,8 +1421,8 @@ static int finish_libjte(Ecma119Image *target)
}
static int write_mbr_partition_file(Ecma119Image *target, char *path,
uint32_t prepad, uint32_t blocks, int flag)
int iso_write_partition_file(Ecma119Image *target, char *path,
uint32_t prepad, uint32_t blocks, int flag)
{
FILE *fp = NULL;
uint32_t i;
@ -1460,7 +1504,7 @@ void *write_function(void *arg)
continue;
if (target->appended_partitions[i][0] == 0)
continue;
res = write_mbr_partition_file(target, target->appended_partitions[i],
res = iso_write_partition_file(target, target->appended_partitions[i],
target->appended_part_prepad[i],
target->appended_part_size[i], 0);
if (res < 0)
@ -1484,7 +1528,15 @@ void *write_function(void *arg)
if (target->tree_end_block == 1) {
iso_msgs_submit(0,
"Image is most likely damaged. Calculated/written block address mismatch.",
"Image is most likely damaged. Calculated/written tree end address mismatch.",
0, "FATAL", 0);
}
if (target->bytes_written != target->total_size) {
iso_msg_debug(target->image->id,
"bytes_written = %.f <-> total_size = %.f",
(double) target->bytes_written, (double) target->total_size);
iso_msgs_submit(0,
"Image is most likely damaged. Calculated/written image end address mismatch.",
0, "FATAL", 0);
}
@ -1581,7 +1633,8 @@ int checksum_prepare_nodes(Ecma119Image *target, IsoNode *node, int flag)
*/;
} else if (ret == 1 && img->checksum_array == NULL) {
/* No checksum array loaded. Delete "isofs.cx" */
iso_node_set_attrs(node, (size_t) 1,
if (!target->will_cancel)
iso_node_set_attrs(node, (size_t) 1,
&cx_names, cx_value_lengths, &cx_valuept, 4 | 8);
no_md5 = 1;
} else if (ret == 1 && value_length == 4) {
@ -1607,8 +1660,9 @@ int checksum_prepare_nodes(Ecma119Image *target, IsoNode *node, int flag)
}
/* Equip nodes with provisory isofs.cx numbers: 4 byte, all 0.
Omit those from old image which will not be copied and have no MD5.
Do not alter the nodes if this is only a will_cancel run.
*/
if (!no_md5) {
if (!(target->will_cancel || no_md5)) {
ret = iso_file_set_isofscx(file, (unsigned int) 0, 0);
if (ret < 0)
return ret;
@ -1635,7 +1689,6 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
char *system_area = NULL;
int write_count = 0, write_count_mem;
/* 1. Allocate target and copy opts there */
target = calloc(1, sizeof(Ecma119Image));
if (target == NULL) {
@ -1659,6 +1712,8 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
target->iso_level = opts->level;
target->rockridge = opts->rockridge;
target->joliet = opts->joliet;
target->hfsplus = opts->hfsplus;
target->fat = opts->fat;
target->iso1999 = opts->iso1999;
target->hardlinks = opts->hardlinks;
target->aaip = opts->aaip;
@ -1682,9 +1737,6 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
target->rrip_1_10_px_ino = opts->rrip_1_10_px_ino;
target->aaip_susp_1_10 = opts->aaip_susp_1_10;
target->dir_rec_mtime = opts->dir_rec_mtime;
#ifdef Libisofs_with_rr_reloc_diR
target->rr_reloc_dir = NULL;
if (opts->rr_reloc_dir != NULL) {
target->rr_reloc_dir = strdup(opts->rr_reloc_dir);
@ -1695,9 +1747,6 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
}
target->rr_reloc_flags = opts->rr_reloc_flags;
target->rr_reloc_node = NULL;
#endif /* Libisofs_with_rr_reloc_diR */
target->sort_files = opts->sort_files;
target->replace_uid = opts->replace_uid ? 1 : 0;
@ -1750,6 +1799,8 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
for (i = 0; i < ISO_MAX_PARTITIONS; i++)
if (opts->appended_partitions[i] != NULL)
return ISO_NON_MBR_SYS_AREA;
if (sa_type != 0 && opts->prep_partition != NULL)
return ISO_NON_MBR_SYS_AREA;
target->system_area_data = NULL;
if (system_area != NULL) {
@ -1798,6 +1849,8 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
goto target_cleanup;
}
memcpy(target->hfsp_serial_number, opts->hfsp_serial_number, 8);
target->md5_file_checksums = opts->md5_file_checksums;
target->md5_session_checksum = opts->md5_session_checksum;
strcpy(target->scdbackup_tag_parm, opts->scdbackup_tag_parm);
@ -1839,11 +1892,28 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
target->mipsel_p_vaddr = 0;
target->mipsel_p_filesz = 0;
target->sparc_core_src = NULL;
target->empty_file_block = 0;
target->tree_end_block = 0;
target->wthread_is_running = 0;
target->prep_partition = NULL;
if (opts->prep_partition != NULL) {
target->prep_partition = strdup(opts->prep_partition);
if (target->prep_partition == NULL)
return ISO_OUT_OF_MEM;
}
target->prep_part_size = 0;
target->efi_boot_partition = NULL;
if (opts->efi_boot_partition != NULL) {
target->efi_boot_partition = strdup(opts->efi_boot_partition);
if (target->efi_boot_partition == NULL)
return ISO_OUT_OF_MEM;
}
target->efi_boot_part_size = 0;
target->efi_boot_part_filesrc = NULL;
for (i = 0; i < ISO_MAX_PARTITIONS; i++) {
target->appended_partitions[i] = NULL;
if (opts->appended_partitions[i] != NULL) {
@ -1857,6 +1927,35 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
target->appended_part_start[i] = target->appended_part_size[i] = 0;
}
strcpy(target->ascii_disc_label, opts->ascii_disc_label);
for (i = 0; i < ISO_HFSPLUS_BLESS_MAX; i++) {
target->hfsplus_blessed[i] = src->hfsplus_blessed[i];
if (target->hfsplus_blessed[i] != NULL)
iso_node_ref(target->hfsplus_blessed[i]);
}
target->apm_block_size = opts->apm_block_size;
target->hfsp_block_size = opts->hfsp_block_size;
target->hfsp_cat_node_size = 0;
target->hfsp_iso_block_fac = 0;
target->hfsp_collision_count = 0;
target->apm_req_count = 0;
target->apm_req_flags = 0;
for (i = 0; i < ISO_APM_ENTRIES_MAX; i++)
target->apm_req[i] = NULL;
for (i = 0; i < ISO_MBR_ENTRIES_MAX; i++)
target->mbr_req[i] = NULL;
target->mbr_req_count = 0;
for (i = 0; i < ISO_GPT_ENTRIES_MAX; i++)
target->gpt_req[i] = NULL;
target->gpt_req_count = 0;
target->gpt_req_flags = 0;
target->gpt_part_start = 0;
target->gpt_backup_end = 0;
target->gpt_backup_size = 0;
target->gpt_max_entries = 0;
target->gpt_is_computed = 0;
target->filesrc_start = 0;
target->filesrc_blocks = 0;
/*
* 2. Based on those options, create needed writers: iso, joliet...
@ -1887,6 +1986,11 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
if (target->iso1999) {
nwriters++;
}
nwriters++; /* Partition Prepend writer */
if (target->hfsplus || target->fat) {
nwriters+= 2;
}
nwriters++; /* GPT backup tail writer */
nwriters++; /* Tail padding writer */
if ((target->md5_file_checksums & 1) || target->md5_session_checksum) {
nwriters++;
@ -1960,6 +2064,25 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
goto target_cleanup;
}
/* The writer for MBR and GPT partitions outside iso_file_src.
* If PreP or FAT are desired, it creates MBR partition entries and
* surrounding protecting partition entries.
* If EFI boot partition is desired, it creates a GPT entry for it.
*/
ret = partprepend_writer_create(target);
if (ret < 0)
goto target_cleanup;
/* create writer for HFS+/FAT structure */
/* Impotant: It must be created directly before iso_file_src_writer_create.
*/
if (target->hfsplus || target->fat) {
ret = hfsplus_writer_create(target);
if (ret < 0) {
goto target_cleanup;
}
}
/* create writer for file contents */
ret = iso_file_src_writer_create(target);
if (ret < 0) {
@ -1967,18 +2090,73 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
}
file_src_writer_index = target->nwriters - 1;
/* create writer for HFS+ structure */
if (target->hfsplus || target->fat) {
ret = hfsplus_tail_writer_create(target);
if (ret < 0) {
goto target_cleanup;
}
}
/* >>> Decide whether the GPT tail writer can be the last of all
*/
#define Libisofs_gpt_writer_lasT yes
#ifndef Libisofs_gpt_writer_lasT
/* This writer has to be added to the list after any writer which might
request production of APM or GPT partition entries by its
compute_data_blocks() method. Its compute_data_blocks() fills the gaps
in APM requests. It determines the position of primary GPT and
backup GPT. Further it reserves blocks for the backup GPT.
*/
ret = gpt_tail_writer_create(target);
if (ret < 0)
goto target_cleanup;
#endif /* ! Libisofs_gpt_writer_lasT */
/* >>> Should not the checksum writer come before the zero writer ?
*/
#define Libisofs_checksums_before_paddinG yes
#ifndef Libisofs_checksums_before_paddinG
/* >>> ??? Why is this important ? */
/* IMPORTANT: This must be the last writer before the checksum writer */
ret = zero_writer_create(target, target->tail_blocks, 1);
if (ret < 0)
goto target_cleanup;
#endif /* !Libisofs_checksums_before_paddinG */
if ((target->md5_file_checksums & 1) || target->md5_session_checksum) {
ret = checksum_writer_create(target);
if (ret < 0)
goto target_cleanup;
}
#ifdef Libisofs_checksums_before_paddinG
ret = zero_writer_create(target, target->tail_blocks, 1);
if (ret < 0)
goto target_cleanup;
#endif /* Libisofs_checksums_before_paddinG */
#ifdef Libisofs_gpt_writer_lasT
/* This writer shall be the last one in the list, because it protects the
image on media which are seen as GPT partitioned.
In any case it has to come after any writer which might request
production of APM or GPT partition entries by its compute_data_blocks()
method.
gpt_tail_writer_compute_data_blocks() fills the gaps in APM requests.
It determines the position of primary GPT and backup GPT.
Further it reserves blocks for the backup GPT.
*/
ret = gpt_tail_writer_create(target);
if (ret < 0)
goto target_cleanup;
#endif /* Libisofs_gpt_writer_lasT */
if (target->partition_offset > 0) {
/* After volume descriptors and superblock tag are accounted for:
account for second volset
@ -2012,6 +2190,15 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
}
/* At least the FAT computation needs to know the size of filesrc data
in advance. So this call produces target->filesrc_blocks and
relative extent addresses, which get absolute in
filesrc_writer_compute_data_blocks().
*/
ret = filesrc_writer_pre_compute(target->writers[file_src_writer_index]);
if (ret < 0)
goto target_cleanup;
/*
* 3.
* Call compute_data_blocks() in each Writer.
@ -2021,10 +2208,6 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
for (i = 0; i < (int) target->nwriters; ++i) {
IsoImageWriter *writer = target->writers[i];
/* Delaying boot image patching until new LBA is known */
if (i == el_torito_writer_index)
continue;
/* Exposing address of data start to IsoWriteOpts and memorizing
this address for all files which have no block address:
symbolic links, device files, empty data files.
@ -2043,14 +2226,9 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
}
}
/* Now perform delayed image patching and System Area preparations */
if (el_torito_writer_index >= 0) {
IsoImageWriter *writer = target->writers[el_torito_writer_index];
ret = writer->compute_data_blocks(writer);
if (ret < 0) {
goto target_cleanup;
}
}
ret = iso_patch_eltoritos(target);
if (ret < 0)
goto target_cleanup;
if (((target->system_area_options & 0xfc) >> 2) == 2) {
ret = iso_read_mipsel_elf(target, 0);
if (ret < 0)
@ -2071,10 +2249,11 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
/* create the ring buffer */
if (opts->overwrite != NULL &&
opts->fifo_size / 2048 < 32 + target->partition_offset) {
opts->fifo_size < 32 + target->partition_offset) {
/* The ring buffer must be large enough to take opts->overwrite
*/
ret = ISO_OVWRT_FIFO_TOO_SMALL;
goto target_cleanup;
}
ret = iso_ring_buffer_new(opts->fifo_size, &target->buffer);
if (ret < 0) {
@ -2193,6 +2372,13 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
iso_image_free_checksums(target->image, 0);
image_checksums_mad = 0;
if (target->apm_block_size == 0) {
if (target->gpt_req_count)
target->apm_block_size = 2048; /* Combinable with GPT */
else
target->apm_block_size = 512; /* Mountable on Linux */
}
/* ensure the thread is created joinable */
pthread_attr_init(&(target->th_attr));
pthread_attr_setdetachstate(&(target->th_attr), PTHREAD_CREATE_JOINABLE);
@ -2335,8 +2521,6 @@ int bs_set_size(struct burn_source *bs, off_t size)
return 1;
}
#ifdef Libisofs_with_rr_reloc_diR
static
int dive_to_depth_8(IsoDir *dir, int depth)
{
@ -2395,9 +2579,6 @@ int make_reloc_dir_if_needed(IsoImage *img, IsoWriteOpts *opts, int flag)
return 1;
}
#endif /* Libisofs_with_rr_reloc_diR */
int iso_image_create_burn_source(IsoImage *image, IsoWriteOpts *opts,
struct burn_source **burn_src)
{
@ -2414,8 +2595,6 @@ int iso_image_create_burn_source(IsoImage *image, IsoWriteOpts *opts,
return ISO_OUT_OF_MEM;
}
#ifdef Libisofs_with_rr_reloc_diR
if (!opts->allow_deep_paths) {
ret = make_reloc_dir_if_needed(image, opts, 0);
if (ret < 0) {
@ -2424,8 +2603,6 @@ int iso_image_create_burn_source(IsoImage *image, IsoWriteOpts *opts,
}
}
#endif /* Libisofs_with_rr_reloc_diR */
ret = ecma119_image_new(image, opts, &target);
if (ret < 0) {
free(source);
@ -2450,6 +2627,12 @@ int iso_write(Ecma119Image *target, void *buf, size_t count)
{
int ret;
if (target->bytes_written + (off_t) count > target->total_size) {
iso_msg_submit(target->image->id, ISO_ASSERT_FAILURE, 0,
"ISO overwrite");
return ISO_ASSERT_FAILURE;
}
ret = iso_ring_buffer_write(target->buffer, buf, count);
if (ret == 0) {
/* reader cancelled */
@ -2531,16 +2714,12 @@ int iso_write_opts_new(IsoWriteOpts **opts, int profile)
return ISO_ASSERT_FAILURE;
break;
}
wopts->hfsplus = 0;
wopts->fat = 0;
wopts->fifo_size = 1024; /* 2 MB buffer */
wopts->sort_files = 1; /* file sorting is always good */
#ifdef Libisofs_with_rr_reloc_diR
wopts->rr_reloc_dir = NULL;
wopts->rr_reloc_flags = 0;
#endif /* Libisofs_with_rr_reloc_diR */
wopts->system_area_data = NULL;
wopts->system_area_options = 0;
wopts->vol_creation_time = 0;
@ -2557,6 +2736,8 @@ int iso_write_opts_new(IsoWriteOpts **opts, int profile)
#endif /* Libisofs_with_libjtE */
wopts->tail_blocks = 0;
wopts->prep_partition = NULL;
wopts->efi_boot_partition = NULL;
for (i = 0; i < ISO_MAX_PARTITIONS; i++)
wopts->appended_partitions[i] = NULL;
wopts->ascii_disc_label[0] = 0;
@ -2564,6 +2745,10 @@ int iso_write_opts_new(IsoWriteOpts **opts, int profile)
wopts->allow_dir_id_ext = 0;
wopts->old_empty = 0;
wopts->untranslated_name_len = 0;
for (i = 0; i < 8; i++)
wopts->hfsp_serial_number[i] = 0;
wopts->apm_block_size = 0;
wopts->hfsp_block_size = 0;
*opts = wopts;
return ISO_SUCCESS;
@ -2577,16 +2762,14 @@ void iso_write_opts_free(IsoWriteOpts *opts)
return;
}
free(opts->output_charset);
#ifdef Libisofs_with_rr_reloc_diR
if (opts->rr_reloc_dir != NULL)
free(opts->rr_reloc_dir);
#endif /* Libisofs_with_rr_reloc_diR */
if (opts->system_area_data != NULL)
free(opts->system_area_data);
if (opts->prep_partition != NULL)
free(opts->prep_partition);
if (opts->efi_boot_partition != NULL)
free(opts->efi_boot_partition);
for (i = 0; i < ISO_MAX_PARTITIONS; i++)
if (opts->appended_partitions[i] != NULL)
free(opts->appended_partitions[i]);
@ -2633,6 +2816,24 @@ int iso_write_opts_set_joliet(IsoWriteOpts *opts, int enable)
return ISO_SUCCESS;
}
int iso_write_opts_set_hfsplus(IsoWriteOpts *opts, int enable)
{
if (opts == NULL) {
return ISO_NULL_POINTER;
}
opts->hfsplus = enable ? 1 : 0;
return ISO_SUCCESS;
}
int iso_write_opts_set_fat(IsoWriteOpts *opts, int enable)
{
if (opts == NULL) {
return ISO_NULL_POINTER;
}
opts->fat = enable ? 1 : 0;
return ISO_SUCCESS;
}
int iso_write_opts_set_iso1999(IsoWriteOpts *opts, int enable)
{
if (opts == NULL) {
@ -3062,8 +3263,9 @@ int iso_write_opts_get_data_start(IsoWriteOpts *opts, uint32_t *data_start,
* ISOLINUX boot image (see iso_image_set_boot_image()) and
* only if not bit0 is set.
* bit2-7= System area type
* 0= PC-BIOS DOS MBR
* 1= MIPS Big Endian Volume Header
* bit8-9= Only with System area type 0 = MBR
* Cylinder alignment mode
* bit10-13= System area sub type
* @param flag bit0 = invalidate any attached system area data
* same as data == NULL
* bit1 = keep data unaltered
@ -3085,7 +3287,7 @@ int iso_write_opts_set_system_area(IsoWriteOpts *opts, char data[32768],
memcpy(opts->system_area_data, data, 32768);
}
if (!(flag & 4))
opts->system_area_options = options & 0x3ff;
opts->system_area_options = options & 0x7fff;
return ISO_SUCCESS;
}
@ -3151,19 +3353,44 @@ int iso_write_opts_set_tail_blocks(IsoWriteOpts *opts, uint32_t num_blocks)
return ISO_SUCCESS;
}
int iso_write_opts_set_prep_img(IsoWriteOpts *opts, char *image_path, int flag)
{
if (opts->prep_partition != NULL)
free(opts->prep_partition);
if (image_path == NULL)
return ISO_SUCCESS;
opts->prep_partition = strdup(image_path);
if (opts->prep_partition == NULL)
return ISO_OUT_OF_MEM;
return ISO_SUCCESS;
}
int iso_write_opts_set_efi_bootp(IsoWriteOpts *opts, char *image_path,
int flag)
{
if (opts->efi_boot_partition != NULL)
free(opts->efi_boot_partition);
if (image_path == NULL)
return ISO_SUCCESS;
opts->efi_boot_partition = strdup(image_path);
if (opts->efi_boot_partition == NULL)
return ISO_OUT_OF_MEM;
return ISO_SUCCESS;
}
int iso_write_opts_set_partition_img(IsoWriteOpts *opts, int partition_number,
uint8_t partition_type, char *image_path, int flag)
{
if (partition_number < 1 || partition_number > ISO_MAX_PARTITIONS)
return ISO_BAD_PARTITION_NO;
if (opts->appended_partitions[partition_number - 1] != NULL)
free(opts->appended_partitions[partition_number - 1]);
if (image_path == NULL)
return ISO_SUCCESS;
opts->appended_partitions[partition_number - 1] = strdup(image_path);
if (opts->appended_partitions[partition_number - 1] == NULL)
return ISO_OUT_OF_MEM;
opts->appended_part_types[partition_number - 1] = partition_type;
return ISO_SUCCESS;
}
@ -3173,4 +3400,25 @@ int iso_write_opts_set_disc_label(IsoWriteOpts *opts, char *label)
opts->ascii_disc_label[ISO_DISC_LABEL_SIZE - 1] = 0;
return ISO_SUCCESS;
}
int iso_write_opts_set_hfsp_serial_number(IsoWriteOpts *opts,
uint8_t serial_number[8])
{
memcpy(opts->hfsp_serial_number, serial_number, 8);
return ISO_SUCCESS;
}
int iso_write_opts_set_hfsp_block_size(IsoWriteOpts *opts,
int hfsp_block_size, int apm_block_size)
{
if (hfsp_block_size != 0 && hfsp_block_size != 512 &&
hfsp_block_size != 2048)
return ISO_BOOT_HFSP_BAD_BSIZE;
opts->hfsp_block_size = hfsp_block_size;
if (apm_block_size != 0 && apm_block_size != 512 && apm_block_size != 2048)
return ISO_BOOT_HFSP_BAD_BSIZE;
opts->apm_block_size = apm_block_size;
return ISO_SUCCESS;
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2012 Thomas Schmitt
* Copyright (c) 2009 - 2013 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -70,6 +70,23 @@
#endif
/* The theoretical maximum number of Apple Partition Map entries in the
System Area of an ISO image:
Block0 plus 63 entries with block size 512
*/
#define ISO_APM_ENTRIES_MAX 63
/* The maximum number of MBR partition table entries.
*/
#define ISO_MBR_ENTRIES_MAX 4
/* The theoretical maximum number of GPT entries in the System Area of an
ISO image:
MBR plus GPT header block plus 248 GPT entries of 128 bytes each.
*/
#define ISO_GPT_ENTRIES_MAX 248
/**
* Holds the options for the image generation.
*/
@ -83,6 +100,8 @@ struct iso_write_opts {
unsigned int rockridge :1;
unsigned int joliet :1;
unsigned int iso1999 :1;
unsigned int hfsplus :1;
unsigned int fat :1;
unsigned int aaip :1; /* whether to write eventual ACL and EAs */
@ -433,6 +452,16 @@ struct iso_write_opts {
*/
uint32_t tail_blocks;
/* Eventual disk file path of a PreP partition which shall be prepended
to HFS+/FAT and IsoFileSrc areas and marked by an MBR partition entry.
*/
char *prep_partition;
/* 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;
/* Eventual disk file paths of prepared images which shall be appended
after the ISO image and described by partiton table entries in a MBR
*/
@ -442,12 +471,27 @@ struct iso_write_opts {
/* Eventual name of the non-ISO aspect of the image. E.g. SUN ASCII label.
*/
char ascii_disc_label[ISO_DISC_LABEL_SIZE];
/* HFS+ image serial number.
* 00...00 means that it shall be generated by libisofs.
*/
uint8_t hfsp_serial_number[8];
/* Allocation block size of HFS+ : 0= auto , 512, or 2048
*/
int hfsp_block_size;
/* Block size of and in APM : 0= auto , 512, or 2048
*/
int apm_block_size;
};
typedef struct ecma119_image Ecma119Image;
typedef struct ecma119_node Ecma119Node;
typedef struct joliet_node JolietNode;
typedef struct iso1999_node Iso1999Node;
typedef struct hfsplus_node HFSPlusNode;
typedef struct Iso_File_Src IsoFileSrc;
typedef struct Iso_Image_Writer IsoImageWriter;
@ -467,6 +511,8 @@ struct ecma119_image
unsigned int joliet :1;
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() */
@ -544,6 +590,11 @@ struct ecma119_image
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. */
@ -592,6 +643,29 @@ struct ecma119_image
uint32_t joliet_l_path_table_pos;
uint32_t joliet_m_path_table_pos;
/*
* HFS+ related information
* (by Vladimir Serbinenko, see libisofs/hfsplus.c)
*/
HFSPlusNode *hfsp_leafs;
struct hfsplus_btree_level *hfsp_levels;
uint32_t hfsp_nlevels;
uint32_t hfsp_part_start;
uint32_t hfsp_nfiles;
uint32_t hfsp_ndirs;
uint32_t hfsp_cat_id;
uint32_t hfsp_allocation_blocks;
uint32_t hfsp_allocation_file_start;
uint32_t hfsp_extent_file_start;
uint32_t hfsp_catalog_file_start;
uint32_t hfsp_total_blocks;
uint32_t hfsp_allocation_size;
uint32_t hfsp_nleafs;
uint32_t hfsp_curleaf;
uint32_t hfsp_nnodes;
uint32_t hfsp_bless_id[ISO_HFSPLUS_BLESS_MAX];
uint32_t hfsp_collision_count;
/*
* ISO 9660:1999 related information
*/
@ -639,6 +713,15 @@ struct ecma119_image
* 0 = auto (align if bit1)
* 1 = always align to cylinder boundary
* 2 = never align to cylinder boundary
* 3 = always align, additionally pad up and align partitions
* which were appended by iso_write_opts_set_partition_img()
* bit10-13= System area sub type
* With type 0 = MBR:
* Gets overridden by bit0 and bit1.
* 0 = no particular sub type
* 1 = CHRP: A single MBR partition of type 0x96 covers the
* ISO image. Not compatible with any other feature
* which needs to have own MBR partition entries.
*/
int system_area_options;
@ -742,6 +825,11 @@ struct ecma119_image
uint32_t mipsel_p_vaddr;
uint32_t mipsel_p_filesz;
/* A data file of which the position and size shall be written after
a SUN Disk Label.
*/
IsoFileSrc *sparc_core_src;
char *appended_partitions[ISO_MAX_PARTITIONS];
uint8_t appended_part_types[ISO_MAX_PARTITIONS];
/* Counted in blocks of 2048 */
@ -751,6 +839,84 @@ struct ecma119_image
char ascii_disc_label[ISO_DISC_LABEL_SIZE];
/* See IsoImage and libisofs.h */
IsoNode *hfsplus_blessed[ISO_HFSPLUS_BLESS_MAX];
/* Block sizes come from write options.
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 */
/* Apple Partition Map description. To be composed during IsoImageWriter
method ->compute_data_blocks() by calling iso_register_apm_entry().
Make sure that the composing writers get registered before the
gpt_tail_writer.
*/
struct iso_apm_partition_request *apm_req[ISO_APM_ENTRIES_MAX];
int apm_req_count;
/* bit1= Do not fill gaps in Apple Partition Map
bit2= apm_req entries use apm_block_size in start_block and block_count.
Normally these two parameters are counted in 2 KiB blocks.
*/
int apm_req_flags;
/* MBR partition table description. To be composed during IsoImageWriter
method ->compute_data_blocks() by calling iso_register_mbr_entry().
*/
struct iso_mbr_partition_request *mbr_req[ISO_MBR_ENTRIES_MAX];
int mbr_req_count;
char *prep_partition;
uint32_t prep_part_size;
/* GPT description. To be composed during IsoImageWriter
method ->compute_data_blocks() by calling iso_register_gpt_entry().
Make sure that the composing writers get registered before the
gpt_tail_writer.
*/
struct iso_gpt_partition_request *gpt_req[ISO_GPT_ENTRIES_MAX];
int gpt_req_count;
/* bit0= GPT partitions may overlap */
int gpt_req_flags;
char *efi_boot_partition;
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().
*/
/* 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 */
uint32_t gpt_backup_end;
uint32_t gpt_backup_size;
uint32_t gpt_max_entries;
int gpt_is_computed;
/* Message from write_head_part1()/iso_write_system_area() to the
write_data() methods of the writers.
*/
uint8_t sys_area_as_written[16 * BLOCK_SIZE];
/* Size of the filesrc_writer area (data file content).
This is available before any IsoImageWriter.compute_data_blocks()
is called.
*/
uint32_t filesrc_start;
uint32_t filesrc_blocks;
};
#define BP(a,b) [(b) - (a) + 1]
@ -881,5 +1047,11 @@ struct ecma119_vol_desc_terminator
uint8_t reserved BP(8, 2048);
};
void ecma119_set_voldescr_times(IsoImageWriter *writer,
struct ecma119_pri_vol_desc *vol);
/* Copies a data file into the ISO image output stream */
int iso_write_partition_file(Ecma119Image *target, char *path,
uint32_t prepad, uint32_t blocks, int flag);
#endif /*LIBISO_ECMA119_H_*/

View File

@ -153,16 +153,10 @@ needs_transl:;
int ecma119_is_dedicated_reloc_dir(Ecma119Image *img, Ecma119Node *node)
{
#ifdef Libisofs_with_rr_reloc_diR
if (img->rr_reloc_node == node &&
node != img->root && node != img->partition_root &&
(img->rr_reloc_flags & 2))
return 1;
#endif /* Libisofs_with_rr_reloc_diR */
return 0;
}
@ -474,9 +468,6 @@ int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree,
if (ret < 0) {
goto ex;
}
#ifdef Libisofs_with_rr_reloc_diR
if (depth == 1) { /* root is default */
image->rr_reloc_node = node;
} else if (depth == 2) {
@ -486,10 +477,6 @@ int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree,
strcmp(iso->name, image->rr_reloc_dir) == 0)
image->rr_reloc_node = node;
}
#endif /* Libisofs_with_rr_reloc_diR */
}
ret = ISO_SUCCESS;
pos = dir->children;
@ -734,8 +721,11 @@ int mangle_single_dir(Ecma119Image *img, Ecma119Node *dir, int max_file_len,
ret = ISO_OUT_OF_MEM;
goto mangle_cleanup;
}
#ifdef Libisofs_extra_verbose_debuG
iso_msg_debug(img->image->id, "\"%s\" renamed to \"%s\"",
children[k]->iso_name, new);
#endif
iso_htable_remove_ptr(table, children[k]->iso_name, NULL);
free(children[k]->iso_name);
@ -959,9 +949,6 @@ int reorder_tree(Ecma119Image *img, Ecma119Node *dir,
max_path = pathlen + 1 + max_child_name_len(dir);
if (level > 8 || max_path > 255) {
#ifdef Libisofs_with_rr_reloc_diR
reloc = img->rr_reloc_node;
if (reloc == NULL) {
if (img->eff_partition_offset > 0) {
@ -970,17 +957,6 @@ int reorder_tree(Ecma119Image *img, Ecma119Node *dir,
reloc = img->root;
}
}
#else
if (img->eff_partition_offset > 0) {
reloc = img->partition_root;
} else {
reloc = img->root;
}
#endif /* ! Libisofs_with_rr_reloc_diR */
ret = reparent(dir, reloc);
if (ret < 0) {
return ret;
@ -1235,13 +1211,7 @@ int ecma119_tree_create(Ecma119Image *img)
* above could insert new directories into the relocation directory.
* Note that recurse = 0, as we don't need to recurse.
*/
#ifdef Libisofs_with_rr_reloc_diR
ret = mangle_tree(img, img->rr_reloc_node, 0);
#else
ret = mangle_tree(img, NULL, 0);
#endif
if (ret < 0) {
return ret;
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2010 Thomas Schmitt
* Copyright (c) 2010 - 2013 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -160,7 +160,13 @@ int el_torito_get_selection_crit(ElToritoBootImage *bootimg, uint8_t crit[20])
/* API */
int el_torito_seems_boot_info_table(ElToritoBootImage *bootimg, int flag)
{
return bootimg->seems_boot_info_table;
switch (flag & 15) {
case 0:
return bootimg->seems_boot_info_table;
case 1:
return bootimg->seems_grub2_boot_info;
}
return 0;
}
/**
@ -197,14 +203,14 @@ void el_torito_patch_isolinux_image(ElToritoBootImage *bootimg)
*/
int el_torito_set_isolinux_options(ElToritoBootImage *bootimg, int options, int flag)
{
bootimg->isolinux_options = (options & 0x03);
bootimg->isolinux_options = (options & 0x03ff);
return ISO_SUCCESS;
}
/* API */
int el_torito_get_isolinux_options(ElToritoBootImage *bootimg, int flag)
{
return bootimg->isolinux_options & 0x03;
return bootimg->isolinux_options & 0x03ff;
}
/* API */
@ -1032,7 +1038,7 @@ int el_torito_catalog_file_src_create(Ecma119Image *target, IsoFileSrc **src)
}
/* fill fields */
file->prev_img = 0; /* TODO allow copy of old img catalog???? */
file->no_write = 0; /* TODO allow copy of old img catalog???? */
file->checksum_index = 0;
file->nsections = 1;
file->sections = calloc(1, sizeof(struct iso_file_section));
@ -1096,13 +1102,14 @@ 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
*/
static
int patch_boot_image(uint8_t *buf, Ecma119Image *t, size_t imgsize, int idx)
int patch_boot_info_table(uint8_t *buf, Ecma119Image *t,
size_t imgsize, int idx)
{
int ret;
@ -1116,29 +1123,41 @@ int patch_boot_image(uint8_t *buf, Ecma119Image *t, size_t imgsize, int idx)
return ret;
}
/**
* Patch a GRUB2 El Torito boot image.
*/
static
int eltorito_writer_compute_data_blocks(IsoImageWriter *writer)
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)
{
/*
* We have nothing to write, but if we need to patch an isolinux image,
* this is a good place to do so.
*/
Ecma119Image *t;
int ret, idx;
size_t size;
uint8_t *buf;
IsoStream *new = NULL;
IsoStream *original = NULL;
if (writer == NULL) {
return ISO_NULL_POINTER;
}
if (t->catalog == NULL)
return ISO_SUCCESS;
t = writer->target;
/* Patch the boot image info tables if indicated */
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);
@ -1162,9 +1181,20 @@ int eltorito_writer_compute_data_blocks(IsoImageWriter *writer)
}
/* ok, patch the read buffer */
ret = patch_boot_image(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
@ -1179,6 +1209,16 @@ int eltorito_writer_compute_data_blocks(IsoImageWriter *writer)
return ISO_SUCCESS;
}
static
int eltorito_writer_compute_data_blocks(IsoImageWriter *writer)
{
/*
* We have nothing to write.
*/
return ISO_SUCCESS;
}
/**
* Write the Boot Record Volume Descriptor (ECMA-119, 8.2)
*/
@ -1221,7 +1261,7 @@ int eltorito_writer_free_data(IsoImageWriter *writer)
int eltorito_writer_create(Ecma119Image *target)
{
int ret, idx;
int ret, idx, outsource_efi = 0;
IsoImageWriter *writer;
IsoFile *bootimg;
IsoFileSrc *src;
@ -1253,6 +1293,9 @@ int eltorito_writer_create(Ecma119Image *target)
}
}
if (target->efi_boot_partition != NULL)
if (strcmp(target->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;
ret = iso_file_src_create(target, bootimg, &src);
@ -1263,12 +1306,35 @@ int eltorito_writer_create(Ecma119Image *target)
/* For patching an image, it needs to be copied always */
if (target->catalog->bootimages[idx]->isolinux_options & 0x01) {
src->prev_img = 0;
src->no_write = 0;
}
/* If desired: Recognize first EFI boot image that will be newly
written, and mark it as claimed for being a partition.
*/
if (outsource_efi &&
target->catalog->bootimages[idx]->platform_id == 0xef &&
src->no_write == 0) {
target->efi_boot_part_filesrc = src;
src->sections[0].block = 0xfffffffe;
((IsoNode *) bootimg)->hidden |=
LIBISO_HIDE_ON_HFSPLUS | LIBISO_HIDE_ON_FAT;
outsource_efi = 0;
}
}
/* we need the bootable volume descriptor */
target->curblock++;
if (outsource_efi) {
/* Disable EFI Boot partition and complain */
free(target->efi_boot_partition);
target->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;
}
return ISO_SUCCESS;
}

View File

@ -58,13 +58,20 @@ struct el_torito_boot_image {
* Whether the boot image seems to contain a boot_info_table
*/
unsigned int seems_boot_info_table:1;
unsigned int seems_grub2_boot_info:1;
/**
* isolinux options
* bit 0 -> whether to patch image
* bit 1 -> whether to put built-in isolinux 3.72 isohybrid-MBR into image
* System Area (deprecated)
*
* bit2-7= Mentioning in isohybrid GPT
* 0= do not mention in GPT
* 1= mention as EFI partition
* 2= Mention as HFS+ partition
* bit8= Mention in isohybrid Apple partition map
*/
unsigned int isolinux_options:2;
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. */
@ -75,6 +82,7 @@ struct el_torito_boot_image {
uint8_t platform_id;
uint8_t id_string[28];
uint8_t selection_crit[20];
};
/** El-Torito, 2.1 */
@ -144,5 +152,16 @@ int eltorito_writer_create(Ecma119Image *target);
int make_boot_info_table(uint8_t *buf, uint32_t pvd_lba,
uint32_t boot_lba, uint32_t imgsize);
/* Patch the boot images if indicated.
*/
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

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* 2010 - 2011 Thomas Schmitt
* 2010 - 2012 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
@ -68,7 +68,7 @@ int iso_file_src_cmp(const void *n1, const void *n2)
int iso_file_src_create(Ecma119Image *img, IsoFile *file, IsoFileSrc **src)
{
int ret;
int ret, i;
IsoFileSrc *fsrc;
unsigned int fs_id;
dev_t dev_id;
@ -88,7 +88,7 @@ int iso_file_src_create(Ecma119Image *img, IsoFile *file, IsoFileSrc **src)
}
/* fill key and other atts */
fsrc->prev_img = file->from_old_session;
fsrc->no_write = (file->from_old_session && img->appendable);
if (file->from_old_session && img->appendable) {
/*
* On multisession discs we keep file sections from old image.
@ -112,7 +112,14 @@ int iso_file_src_create(Ecma119Image *img, IsoFile *file, IsoFileSrc **src)
} else {
fsrc->nsections = 1;
}
fsrc->sections = calloc(fsrc->nsections, sizeof(struct iso_file_section));
fsrc->sections = calloc(fsrc->nsections,
sizeof(struct iso_file_section));
if (fsrc->sections == NULL) {
free(fsrc);
return ISO_OUT_OF_MEM;
}
for (i = 0; i < fsrc->nsections; i++)
fsrc->sections[i].block = 0;
}
fsrc->sort_weight = file->sort_weight;
fsrc->stream = file->stream;
@ -120,7 +127,7 @@ int iso_file_src_create(Ecma119Image *img, IsoFile *file, IsoFileSrc **src)
/* insert the filesrc in the tree */
ret = iso_rbtree_insert(img->files, fsrc, (void**)src);
if (ret <= 0) {
if (ret == 0 && (*src)->checksum_index > 0) {
if (ret == 0 && (*src)->checksum_index > 0 && !img->will_cancel) {
/* Duplicate file source was mapped to previously registered source
*/
cret = iso_file_set_isofscx(file, (*src)->checksum_index, 0);
@ -145,7 +152,7 @@ int iso_file_src_create(Ecma119Image *img, IsoFile *file, IsoFileSrc **src)
no_md5 = 1;
}
if ((img->md5_file_checksums & 1) && !no_md5) {
if ((img->md5_file_checksums & 1) && !(no_md5 || img->will_cancel)) {
img->checksum_idx_counter++;
if (img->checksum_idx_counter < 0x7fffffff) {
fsrc->checksum_index = img->checksum_idx_counter;
@ -214,16 +221,15 @@ static int cmp_by_weight(const void *f1, const void *f2)
}
static
int is_ms_file(void *arg)
int shall_be_written(void *arg)
{
IsoFileSrc *f = (IsoFileSrc *)arg;
return f->prev_img ? 0 : 1;
return f->no_write ? 0 : 1;
}
static
int filesrc_writer_compute_data_blocks(IsoImageWriter *writer)
int filesrc_writer_pre_compute(IsoImageWriter *writer)
{
size_t i, size;
size_t i, size, is_external;
Ecma119Image *t;
IsoFileSrc **filelist;
int (*inc_item)(void *);
@ -233,16 +239,17 @@ int filesrc_writer_compute_data_blocks(IsoImageWriter *writer)
}
t = writer->target;
t->filesrc_blocks = 0;
/* 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)
t->curblock++;
t->filesrc_blocks++;
/* on appendable images, ms files shouldn't be included */
if (t->appendable) {
inc_item = is_ms_file;
inc_item = shall_be_written;
} else {
inc_item = NULL;
}
@ -262,10 +269,18 @@ int filesrc_writer_compute_data_blocks(IsoImageWriter *writer)
for (i = 0; i < size; ++i) {
int extent = 0;
IsoFileSrc *file = filelist[i];
off_t section_size;
off_t section_size = iso_stream_get_size(file->stream);
/* 0xfffffffe in emerging image means that this is an external
partition. Only assess extent sizes but do not count as part
of filesrc_writer output.
*/
is_external = (file->no_write == 0 &&
file->sections[0].block == 0xfffffffe);
section_size = iso_stream_get_size(file->stream);
for (extent = 0; extent < file->nsections - 1; ++extent) {
file->sections[extent].block = t->curblock + extent *
file->sections[extent].block = t->filesrc_blocks + extent *
(ISO_EXTENT_SIZE / BLOCK_SIZE);
file->sections[extent].size = ISO_EXTENT_SIZE;
section_size -= (off_t) ISO_EXTENT_SIZE;
@ -275,14 +290,29 @@ int filesrc_writer_compute_data_blocks(IsoImageWriter *writer)
* final section
*/
if (section_size <= 0) {
file->sections[extent].block = t->empty_file_block;
/* Will become t->empty_file_block
in filesrc_writer_compute_data_blocks()
Special use of 0xffffffe0 to 0xffffffff is covered by
mspad_writer which enforces a minimum start of filesrc at
block 0x00000020.
*/
file->sections[extent].block = 0xffffffff;
} else {
file->sections[extent].block =
t->curblock + extent * (ISO_EXTENT_SIZE / BLOCK_SIZE);
t->filesrc_blocks + extent * (ISO_EXTENT_SIZE / BLOCK_SIZE);
}
file->sections[extent].size = (uint32_t)section_size;
t->curblock += DIV_UP(iso_file_src_get_size(file), BLOCK_SIZE);
/* 0xfffffffe in emerging image means that this is an external
partition. Others will take care of the content data.
*/
if (is_external) {
file->sections[0].block = 0xfffffffe;
file->no_write = 1; /* Ban for filesrc_writer */
continue;
}
t->filesrc_blocks += DIV_UP(iso_file_src_get_size(file), BLOCK_SIZE);
}
/* the list is only needed by this writer, store locally */
@ -290,6 +320,46 @@ int filesrc_writer_compute_data_blocks(IsoImageWriter *writer)
return ISO_SUCCESS;
}
static
int filesrc_writer_compute_data_blocks(IsoImageWriter *writer)
{
Ecma119Image *t;
int extent = 0;
size_t i;
IsoFileSrc *file;
IsoFileSrc **filelist;
if (writer == NULL) {
return ISO_ASSERT_FAILURE;
}
t = writer->target;
filelist = (IsoFileSrc **) writer->data;
/* >>> HFS: need to align to allocation block size */;
/* >>> HFS: ??? how to handle multi-extent files ? */;
t->filesrc_start = t->curblock;
/* Give all extent addresses their final absolute value */
i = 0;
while ((file = filelist[i++]) != NULL) {
/* Skip external partitions */
if (file->no_write)
continue;
for (extent = 0; extent < file->nsections; ++extent) {
if (file->sections[extent].block == 0xffffffff)
file->sections[extent].block = t->empty_file_block;
else
file->sections[extent].block += t->curblock;
}
}
t->curblock += t->filesrc_blocks;
return ISO_SUCCESS;
}
static
int filesrc_writer_write_vol_desc(IsoImageWriter *writer)
{
@ -332,26 +402,247 @@ int filesrc_make_md5(Ecma119Image *t, IsoFileSrc *file, char md5[16], int flag)
return iso_stream_make_md5(file->stream, md5, 0);
}
static
int filesrc_writer_write_data(IsoImageWriter *writer)
/* name must be NULL or offer at least PATH_MAX characters.
buffer must be NULL or offer at least BLOCK_SIZE characters.
*/
int iso_filesrc_write_data(Ecma119Image *t, IsoFileSrc *file,
char *name, char *buffer, int flag)
{
int res, ret, was_error;
size_t i, b;
Ecma119Image *t = NULL;
IsoFileSrc *file;
IsoFileSrc **filelist;
char *name = NULL;
char *buffer = NULL;
char *name_data = NULL;
char *buffer_data = NULL;
size_t b;
off_t file_size;
uint32_t nblocks;
void *ctx= NULL;
char md5[16], pre_md5[16];
int pre_md5_valid = 0;
IsoStream *stream, *inp;
#ifdef Libisofs_with_libjtE
int jte_begun = 0;
#endif
if (name == NULL) {
LIBISO_ALLOC_MEM(name_data, char, PATH_MAX);
name = name_data;
}
if (buffer == NULL) {
LIBISO_ALLOC_MEM(buffer_data, char, BLOCK_SIZE);
buffer = buffer_data;
}
was_error = 0;
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)) {
/* Obtain an MD5 of content by a first read pass */
pre_md5_valid = filesrc_make_md5(t, file, pre_md5, 0);
}
res = filesrc_open(file);
/* Get file name from end of filter chain */
for (stream = file->stream; ; stream = inp) {
inp = iso_stream_get_input_stream(stream, 0);
if (inp == NULL)
break;
}
iso_stream_get_file_name(stream, name);
if (res < 0) {
/*
* UPS, very ugly error, the best we can do is just to write
* 0's to image
*/
iso_report_errfile(name, ISO_FILE_CANT_WRITE, 0, 0);
was_error = 1;
res = iso_msg_submit(t->image->id, ISO_FILE_CANT_WRITE, res,
"File \"%s\" can't be opened. Filling with 0s.", name);
if (res < 0) {
ret = res; /* aborted due to error severity */
goto ex;
}
memset(buffer, 0, BLOCK_SIZE);
for (b = 0; b < nblocks; ++b) {
res = iso_write(t, buffer, BLOCK_SIZE);
if (res < 0) {
/* ko, writer error, we need to go out! */
ret = res;
goto ex;
}
}
ret = ISO_SUCCESS;
goto ex;
} else if (res > 1) {
iso_report_errfile(name, ISO_FILE_CANT_WRITE, 0, 0);
was_error = 1;
res = iso_msg_submit(t->image->id, ISO_FILE_CANT_WRITE, 0,
"Size of file \"%s\" has changed. It will be %s", name,
(res == 2 ? "truncated" : "padded with 0's"));
if (res < 0) {
filesrc_close(file);
ret = res; /* aborted due to error severity */
goto ex;
}
}
#ifdef LIBISOFS_VERBOSE_DEBUG
else {
iso_msg_debug(t->image->id, "Writing file %s", name);
}
#endif
/* >>> 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,
BLOCK_SIZE, file_size);
if (res <= 0) {
res = iso_libjte_forward_msgs(t->libjte_handle, t->image->id,
ISO_LIBJTE_FILE_FAILED, 0);
if (res < 0) {
filesrc_close(file);
ret = ISO_LIBJTE_FILE_FAILED;
goto ex;
}
}
jte_begun = 1;
}
#endif /* Libisofs_with_libjtE */
if (file->checksum_index > 0) {
/* initialize file checksum */
res = iso_md5_start(&ctx);
if (res <= 0)
file->checksum_index = 0;
}
/* write file contents to image */
for (b = 0; b < nblocks; ++b) {
int wres;
res = filesrc_read(file, buffer, BLOCK_SIZE);
if (res < 0) {
/* read error */
break;
}
wres = iso_write(t, buffer, BLOCK_SIZE);
if (wres < 0) {
/* ko, writer error, we need to go out! */
filesrc_close(file);
ret = wres;
goto ex;
}
if (file->checksum_index > 0) {
/* Add to file checksum */
if (file_size - b * BLOCK_SIZE > BLOCK_SIZE)
res = BLOCK_SIZE;
else
res = file_size - b * BLOCK_SIZE;
res = iso_md5_compute(ctx, buffer, res);
if (res <= 0)
file->checksum_index = 0;
}
}
filesrc_close(file);
if (b < nblocks) {
/* premature end of file, due to error or eof */
iso_report_errfile(name, ISO_FILE_CANT_WRITE, 0, 0);
was_error = 1;
if (res < 0) {
/* error */
res = iso_msg_submit(t->image->id, ISO_FILE_CANT_WRITE, res,
"Read error in file %s.", name);
} else {
/* eof */
res = iso_msg_submit(t->image->id, ISO_FILE_CANT_WRITE, 0,
"Premature end of file %s.", name);
}
if (res < 0) {
ret = res; /* aborted due error severity */
goto ex;
}
/* fill with 0s */
iso_msg_submit(t->image->id, ISO_FILE_CANT_WRITE, 0,
"Filling with 0");
memset(buffer, 0, BLOCK_SIZE);
while (b++ < nblocks) {
res = iso_write(t, buffer, BLOCK_SIZE);
if (res < 0) {
/* ko, writer error, we need to go out! */
ret = res;
goto ex;
}
if (file->checksum_index > 0) {
/* Add to file checksum */
if (file_size - b * BLOCK_SIZE > BLOCK_SIZE)
res = BLOCK_SIZE;
else
res = file_size - b * BLOCK_SIZE;
res = iso_md5_compute(ctx, buffer, res);
if (res <= 0)
file->checksum_index = 0;
}
}
}
if (file->checksum_index > 0 &&
file->checksum_index <= t->checksum_idx_counter) {
/* Obtain checksum and dispose checksum context */
res = iso_md5_end(&ctx, md5);
if (res <= 0)
file->checksum_index = 0;
if ((t->md5_file_checksums & 2) && pre_md5_valid > 0 &&
!was_error) {
if (! iso_md5_match(md5, pre_md5)) {
/* Issue MISHAP event */
iso_report_errfile(name, ISO_MD5_STREAM_CHANGE, 0, 0);
was_error = 1;
res = iso_msg_submit(t->image->id, ISO_MD5_STREAM_CHANGE,0,
"Content of file '%s' changed while it was written into the image.",
name);
if (res < 0) {
ret = res; /* aborted due to error severity */
goto ex;
}
}
}
/* Write md5 into checksum buffer at file->checksum_index */
memcpy(t->checksum_buffer + 16 * file->checksum_index, md5, 16);
}
ret = ISO_SUCCESS;
ex:;
if (ctx != NULL) /* avoid any memory leak */
iso_md5_end(&ctx, md5);
#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,
ISO_LIBJTE_END_FAILED, 0);
if (res <= 0 && ret >= 0)
ret = ISO_LIBJTE_FILE_FAILED;
}
#endif /* Libisofs_with_libjtE */
LIBISO_FREE_MEM(buffer_data);
LIBISO_FREE_MEM(name_data);
return ret;
}
static
int filesrc_writer_write_data(IsoImageWriter *writer)
{
int ret;
size_t i;
Ecma119Image *t = NULL;
IsoFileSrc *file;
IsoFileSrc **filelist;
char *name = NULL;
char *buffer = NULL;
if (writer == NULL) {
ret = ISO_ASSERT_FAILURE; goto ex;
}
@ -375,216 +666,28 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
i = 0;
while ((file = filelist[i++]) != NULL) {
was_error = 0;
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)) {
/* Obtain an MD5 of content by a first read pass */
pre_md5_valid = filesrc_make_md5(t, file, pre_md5, 0);
if (file->no_write) {
/* Do not write external partitions */
iso_msg_debug(t->image->id,
"filesrc_writer: Skipping no_write-src [%.f , %.f]",
(double) file->sections[0].block,
(double) (file->sections[0].block - 1 +
(file->sections[0].size + 2047) / BLOCK_SIZE));
continue;
}
res = filesrc_open(file);
/* Get file name from end of filter chain */
for (stream = file->stream; ; stream = inp) {
inp = iso_stream_get_input_stream(stream, 0);
if (inp == NULL)
break;
}
iso_stream_get_file_name(stream, name);
if (res < 0) {
/*
* UPS, very ugly error, the best we can do is just to write
* 0's to image
*/
iso_report_errfile(name, ISO_FILE_CANT_WRITE, 0, 0);
was_error = 1;
res = iso_msg_submit(t->image->id, ISO_FILE_CANT_WRITE, res,
"File \"%s\" can't be opened. Filling with 0s.", name);
if (res < 0) {
ret = res; /* aborted due to error severity */
goto ex;
}
memset(buffer, 0, BLOCK_SIZE);
for (b = 0; b < nblocks; ++b) {
res = iso_write(t, buffer, BLOCK_SIZE);
if (res < 0) {
/* ko, writer error, we need to go out! */
ret = res;
goto ex;
}
}
continue;
} else if (res > 1) {
iso_report_errfile(name, ISO_FILE_CANT_WRITE, 0, 0);
was_error = 1;
res = iso_msg_submit(t->image->id, ISO_FILE_CANT_WRITE, 0,
"Size of file \"%s\" has changed. It will be %s", name,
(res == 2 ? "truncated" : "padded with 0's"));
if (res < 0) {
filesrc_close(file);
ret = res; /* aborted due to error severity */
goto ex;
}
}
#ifdef LIBISOFS_VERBOSE_DEBUG
else {
iso_msg_debug(t->image->id, "Writing file %s", name);
}
#endif
#ifdef Libisofs_with_libjtE
if (t->libjte_handle != NULL) {
res = libjte_begin_data_file(t->libjte_handle, name,
BLOCK_SIZE, file_size);
if (res <= 0) {
res = iso_libjte_forward_msgs(t->libjte_handle, t->image->id,
ISO_LIBJTE_FILE_FAILED, 0);
if (res < 0) {
filesrc_close(file);
ret = ISO_LIBJTE_FILE_FAILED;
goto ex;
}
}
jte_begun = 1;
}
#endif /* Libisofs_with_libjtE */
if (file->checksum_index > 0) {
/* initialize file checksum */
res = iso_md5_start(&ctx);
if (res <= 0)
file->checksum_index = 0;
}
/* write file contents to image */
for (b = 0; b < nblocks; ++b) {
int wres;
res = filesrc_read(file, buffer, BLOCK_SIZE);
if (res < 0) {
/* read error */
break;
}
wres = iso_write(t, buffer, BLOCK_SIZE);
if (wres < 0) {
/* ko, writer error, we need to go out! */
filesrc_close(file);
ret = wres;
goto ex;
}
if (file->checksum_index > 0) {
/* Add to file checksum */
if (file_size - b * BLOCK_SIZE > BLOCK_SIZE)
res = BLOCK_SIZE;
else
res = file_size - b * BLOCK_SIZE;
res = iso_md5_compute(ctx, buffer, res);
if (res <= 0)
file->checksum_index = 0;
}
}
filesrc_close(file);
if (b < nblocks) {
/* premature end of file, due to error or eof */
iso_report_errfile(name, ISO_FILE_CANT_WRITE, 0, 0);
was_error = 1;
if (res < 0) {
/* error */
res = iso_msg_submit(t->image->id, ISO_FILE_CANT_WRITE, res,
"Read error in file %s.", name);
} else {
/* eof */
res = iso_msg_submit(t->image->id, ISO_FILE_CANT_WRITE, 0,
"Premature end of file %s.", name);
}
if (res < 0) {
ret = res; /* aborted due error severity */
goto ex;
}
/* fill with 0s */
iso_msg_submit(t->image->id, ISO_FILE_CANT_WRITE, 0,
"Filling with 0");
memset(buffer, 0, BLOCK_SIZE);
while (b++ < nblocks) {
res = iso_write(t, buffer, BLOCK_SIZE);
if (res < 0) {
/* ko, writer error, we need to go out! */
ret = res;
goto ex;
}
if (file->checksum_index > 0) {
/* Add to file checksum */
if (file_size - b * BLOCK_SIZE > BLOCK_SIZE)
res = BLOCK_SIZE;
else
res = file_size - b * BLOCK_SIZE;
res = iso_md5_compute(ctx, buffer, res);
if (res <= 0)
file->checksum_index = 0;
}
}
}
if (file->checksum_index > 0 &&
file->checksum_index <= t->checksum_idx_counter) {
/* Obtain checksum and dispose checksum context */
res = iso_md5_end(&ctx, md5);
if (res <= 0)
file->checksum_index = 0;
if ((t->md5_file_checksums & 2) && pre_md5_valid > 0 &&
!was_error) {
if (! iso_md5_match(md5, pre_md5)) {
/* Issue MISHAP event */
iso_report_errfile(name, ISO_MD5_STREAM_CHANGE, 0, 0);
was_error = 1;
res = iso_msg_submit(t->image->id, ISO_MD5_STREAM_CHANGE,0,
"Content of file '%s' changed while it was written into the image.",
name);
if (res < 0) {
ret = res; /* aborted due to error severity */
goto ex;
}
}
}
/* Write md5 into checksum buffer at file->checksum_index */
memcpy(t->checksum_buffer + 16 * file->checksum_index, md5, 16);
}
#ifdef Libisofs_with_libjtE
if (t->libjte_handle != NULL) {
res = libjte_end_data_file(t->libjte_handle);
if (res <= 0) {
iso_libjte_forward_msgs(t->libjte_handle, t->image->id,
ISO_LIBJTE_FILE_FAILED, 0);
ret = ISO_LIBJTE_FILE_FAILED;
goto ex;
}
jte_begun = 0;
}
#endif /* Libisofs_with_libjtE */
ret = iso_filesrc_write_data(t, file, name, buffer, 0);
if (ret < 0)
goto ex;
}
ret = ISO_SUCCESS;
ex:;
if (ctx != NULL) /* avoid any memory leak */
iso_md5_end(&ctx, md5);
#ifdef Libisofs_with_libjtE
if (jte_begun && t != NULL) {
libjte_end_data_file(t->libjte_handle);
iso_libjte_forward_msgs(t->libjte_handle, t->image->id,
ISO_LIBJTE_END_FAILED, 0);
}
#endif /* Libisofs_with_libjtE */
LIBISO_FREE_MEM(buffer);
LIBISO_FREE_MEM(name);
return ret;
}
static
int filesrc_writer_free_data(IsoImageWriter *writer)
{

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* 2012 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
@ -21,12 +22,33 @@
#endif
#endif
/* Abstraction of data file content in the emerging image.
*/
struct Iso_File_Src
{
unsigned int prev_img :1; /**< if the file comes from a previous image */
/* This marks an IsoFileSrc which shall only expose its extent addresses
and sizes but shall not be counted or written by filesrc_writer.
*/
unsigned int no_write :1;
unsigned int checksum_index :31;
/** File Sections of the file in the image */
/* Special sections[0].block values while they are relative
before filesrc_writer_compute_data_blocks().
Valid only with .no_write == 0:
0xfffffffe This Iso_File_Src is claimed as external partition.
Others will take care of the content data.
filesrc_writer shall neither count nor write it.
At write_data time it is already converted to
a fileadress between Ecma119Image.ms_block and
Ecma119Image.filesrc_start - 1.
0xffffffff This is the block to which empty files shall point.
Normal data files have relative addresses from 0 to 0xffffffdf.
They cannot be higher, because mspad_writer forces the absolute
filesrc addresses to start at least at 0x20.
*/
struct iso_file_section *sections;
int nsections;
@ -93,4 +115,21 @@ off_t iso_file_src_get_size(IsoFileSrc *file);
*/
int iso_file_src_writer_create(Ecma119Image *target);
/**
* Determine number of filesrc blocks in the image and compute extent addresses
* relative to start of the file source writer area.
* filesrc_writer_compute_data_blocks() later makes them absolute.
*/
int filesrc_writer_pre_compute(IsoImageWriter *writer);
/**
* Write the content of file into the output stream of t.
* name must be NULL or offer at least PATH_MAX characters of storage.
* buffer must be NULL or offer at least BLOCK_SIZE characters of storage.
* flag is not used yet, submit 0.
*/
int iso_filesrc_write_data(Ecma119Image *t, IsoFileSrc *file,
char *name, char *buffer, int flag);
#endif /*LIBISO_FILESRC_H_*/

View File

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

1844
libisofs/hfsplus.c Normal file

File diff suppressed because it is too large Load Diff

197
libisofs/hfsplus.h Normal file
View File

@ -0,0 +1,197 @@
/*
* Copyright (c) 2012 Vladimir Serbinenko
*
* 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.
*/
/**
* Declare HFS+ related structures.
*/
#ifndef LIBISO_HFSPLUS_H
#define LIBISO_HFSPLUS_H
#include "libisofs.h"
#include "ecma119.h"
#define LIBISO_HFSPLUS_NAME_MAX 255
enum hfsplus_node_type {
HFSPLUS_DIR = 1,
HFSPLUS_FILE = 2,
HFSPLUS_DIR_THREAD = 3,
HFSPLUS_FILE_THREAD = 4
};
struct hfsplus_btree_node
{
uint32_t start;
uint32_t cnt;
uint32_t strlen;
uint16_t *str;
uint32_t parent_id;
};
struct hfsplus_btree_level
{
uint32_t level_size;
struct hfsplus_btree_node *nodes;
};
struct hfsplus_node
{
/* Note: .type HFSPLUS_DIR_THREAD and HFSPLUS_FILE_THREAD do not own their
.name and .cmp_name. They have copies of others, if ever.
*/
uint16_t *name; /* Name in UTF-16BE, decomposed. */
uint16_t *cmp_name; /* Name used for comparing. */
IsoNode *node; /*< reference to the iso node */
enum { UNIX_NONE, UNIX_SYMLINK, UNIX_SPECIAL } unix_type;
uint32_t symlink_block;
char *symlink_dest;
enum hfsplus_node_type type;
IsoFileSrc *file;
uint32_t cat_id;
uint32_t parent_id;
uint32_t nchildren;
uint32_t strlen;
uint32_t used_size;
};
int hfsplus_writer_create(Ecma119Image *target);
int hfsplus_tail_writer_create(Ecma119Image *target);
struct hfsplus_extent
{
/* The first block of a file on disk. */
uint32_t start;
/* The amount of blocks described by this extent. */
uint32_t count;
} __attribute__ ((packed));
struct hfsplus_forkdata
{
uint64_t size;
uint32_t clumpsize;
uint32_t blocks;
struct hfsplus_extent extents[8];
} __attribute__ ((packed));
struct hfsplus_volheader
{
uint16_t magic;
uint16_t version;
uint32_t attributes;
uint32_t last_mounted_version;
uint32_t journal;
uint32_t ctime;
uint32_t utime;
uint32_t backup_time;
uint32_t fsck_time;
uint32_t file_count;
uint32_t folder_count;
uint32_t blksize;
uint32_t total_blocks;
uint32_t free_blocks;
uint32_t next_allocation;
uint32_t rsrc_clumpsize;
uint32_t data_clumpsize;
uint32_t catalog_node_id;
uint32_t write_count;
uint64_t encodings_bitmap;
uint32_t ppc_bootdir;
uint32_t intel_bootfile;
/* Folder opened when disk is mounted. */
uint32_t showfolder;
uint32_t os9folder;
uint32_t unused;
uint32_t osxfolder;
uint64_t num_serial;
struct hfsplus_forkdata allocations_file;
struct hfsplus_forkdata extents_file;
struct hfsplus_forkdata catalog_file;
struct hfsplus_forkdata attrib_file;
struct hfsplus_forkdata startup_file;
} __attribute__ ((packed));
struct hfsplus_btnode
{
uint32_t next;
uint32_t prev;
int8_t type;
uint8_t height;
uint16_t count;
uint16_t unused;
} __attribute__ ((packed));
/* The header of a HFS+ B+ Tree. */
struct hfsplus_btheader
{
uint16_t depth;
uint32_t root;
uint32_t leaf_records;
uint32_t first_leaf_node;
uint32_t last_leaf_node;
uint16_t nodesize;
uint16_t keysize;
uint32_t total_nodes;
uint32_t free_nodes;
uint16_t reserved1;
uint32_t clump_size;
uint8_t btree_type;
uint8_t key_compare;
uint32_t attributes;
uint32_t reserved[16];
} __attribute__ ((packed));
struct hfsplus_catfile_thread
{
uint16_t type;
uint16_t reserved;
uint32_t parentid;
uint16_t namelen;
} __attribute__ ((packed));
struct hfsplus_catfile_common
{
uint16_t type;
uint16_t flags;
uint32_t valence; /* for files: reserved. */
uint32_t fileid;
uint32_t ctime;
uint32_t mtime;
uint32_t attr_mtime;
uint32_t atime;
uint32_t backup_time;
uint32_t uid;
uint32_t gid;
uint8_t user_flags;
uint8_t group_flags;
uint16_t mode;
uint32_t special;
uint8_t file_type[4]; /* For folders: window size */
uint8_t file_creator[4]; /* For folders: window size */
uint8_t finder_info[24];
uint32_t text_encoding;
uint32_t reserved;
} __attribute__ ((packed));
#define HFSPLUS_MAX_DECOMPOSE_LEN 4
extern uint16_t (*hfsplus_decompose_pages[256])[HFSPLUS_MAX_DECOMPOSE_LEN + 1];
void make_hfsplus_decompose_pages();
extern uint16_t *hfsplus_class_pages[256];
void make_hfsplus_class_pages();
extern const uint16_t hfsplus_casefold[];
#endif /* LIBISO_HFSPLUS_H */

472
libisofs/hfsplus_case.c Normal file
View File

@ -0,0 +1,472 @@
/*
* Copyright (c) 2012 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
* or later as published by the Free Software Foundation.
* See COPYING file for details.
*/
/**
* Maps UTF-16BE double-byte characters to the representative of their
* equivalence class under the relation of HFS+ case-insensitivity.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include "libisofs.h"
/* The translation list utf16be_transl was generated by a program which
compared input and output of existing example code by Apple Inc.
found published on
http://developer.apple.com/legacy/mac/library/#technotes/tn/tn1150.html
Each deviation was recorded as pair of byte pairs. The first pair gives
the input, the second pair gives the output. If a byte pair is not mentioned
in this list as input, then it gets mapped to itself.
Pairs which get mapped to pair 0,0 shall be ignored with HFS+ comparisons.
Another comparison run verified that both implementations yield the same
character translation with all 65536 possible input bit patterns.
*/
static uint8_t utf16be_transl[] = {
0x00, 0x00, 0xff, 0xff,
0x00, 0x41, 0x00, 0x61,
0x00, 0x42, 0x00, 0x62,
0x00, 0x43, 0x00, 0x63,
0x00, 0x44, 0x00, 0x64,
0x00, 0x45, 0x00, 0x65,
0x00, 0x46, 0x00, 0x66,
0x00, 0x47, 0x00, 0x67,
0x00, 0x48, 0x00, 0x68,
0x00, 0x49, 0x00, 0x69,
0x00, 0x4a, 0x00, 0x6a,
0x00, 0x4b, 0x00, 0x6b,
0x00, 0x4c, 0x00, 0x6c,
0x00, 0x4d, 0x00, 0x6d,
0x00, 0x4e, 0x00, 0x6e,
0x00, 0x4f, 0x00, 0x6f,
0x00, 0x50, 0x00, 0x70,
0x00, 0x51, 0x00, 0x71,
0x00, 0x52, 0x00, 0x72,
0x00, 0x53, 0x00, 0x73,
0x00, 0x54, 0x00, 0x74,
0x00, 0x55, 0x00, 0x75,
0x00, 0x56, 0x00, 0x76,
0x00, 0x57, 0x00, 0x77,
0x00, 0x58, 0x00, 0x78,
0x00, 0x59, 0x00, 0x79,
0x00, 0x5a, 0x00, 0x7a,
0x00, 0xc6, 0x00, 0xe6,
0x00, 0xd0, 0x00, 0xf0,
0x00, 0xd8, 0x00, 0xf8,
0x00, 0xde, 0x00, 0xfe,
0x01, 0x10, 0x01, 0x11,
0x01, 0x26, 0x01, 0x27,
0x01, 0x32, 0x01, 0x33,
0x01, 0x3f, 0x01, 0x40,
0x01, 0x41, 0x01, 0x42,
0x01, 0x4a, 0x01, 0x4b,
0x01, 0x52, 0x01, 0x53,
0x01, 0x66, 0x01, 0x67,
0x01, 0x81, 0x02, 0x53,
0x01, 0x82, 0x01, 0x83,
0x01, 0x84, 0x01, 0x85,
0x01, 0x86, 0x02, 0x54,
0x01, 0x87, 0x01, 0x88,
0x01, 0x89, 0x02, 0x56,
0x01, 0x8a, 0x02, 0x57,
0x01, 0x8b, 0x01, 0x8c,
0x01, 0x8e, 0x01, 0xdd,
0x01, 0x8f, 0x02, 0x59,
0x01, 0x90, 0x02, 0x5b,
0x01, 0x91, 0x01, 0x92,
0x01, 0x93, 0x02, 0x60,
0x01, 0x94, 0x02, 0x63,
0x01, 0x96, 0x02, 0x69,
0x01, 0x97, 0x02, 0x68,
0x01, 0x98, 0x01, 0x99,
0x01, 0x9c, 0x02, 0x6f,
0x01, 0x9d, 0x02, 0x72,
0x01, 0x9f, 0x02, 0x75,
0x01, 0xa2, 0x01, 0xa3,
0x01, 0xa4, 0x01, 0xa5,
0x01, 0xa7, 0x01, 0xa8,
0x01, 0xa9, 0x02, 0x83,
0x01, 0xac, 0x01, 0xad,
0x01, 0xae, 0x02, 0x88,
0x01, 0xb1, 0x02, 0x8a,
0x01, 0xb2, 0x02, 0x8b,
0x01, 0xb3, 0x01, 0xb4,
0x01, 0xb5, 0x01, 0xb6,
0x01, 0xb7, 0x02, 0x92,
0x01, 0xb8, 0x01, 0xb9,
0x01, 0xbc, 0x01, 0xbd,
0x01, 0xc4, 0x01, 0xc6,
0x01, 0xc5, 0x01, 0xc6,
0x01, 0xc7, 0x01, 0xc9,
0x01, 0xc8, 0x01, 0xc9,
0x01, 0xca, 0x01, 0xcc,
0x01, 0xcb, 0x01, 0xcc,
0x01, 0xe4, 0x01, 0xe5,
0x01, 0xf1, 0x01, 0xf3,
0x01, 0xf2, 0x01, 0xf3,
0x03, 0x91, 0x03, 0xb1,
0x03, 0x92, 0x03, 0xb2,
0x03, 0x93, 0x03, 0xb3,
0x03, 0x94, 0x03, 0xb4,
0x03, 0x95, 0x03, 0xb5,
0x03, 0x96, 0x03, 0xb6,
0x03, 0x97, 0x03, 0xb7,
0x03, 0x98, 0x03, 0xb8,
0x03, 0x99, 0x03, 0xb9,
0x03, 0x9a, 0x03, 0xba,
0x03, 0x9b, 0x03, 0xbb,
0x03, 0x9c, 0x03, 0xbc,
0x03, 0x9d, 0x03, 0xbd,
0x03, 0x9e, 0x03, 0xbe,
0x03, 0x9f, 0x03, 0xbf,
0x03, 0xa0, 0x03, 0xc0,
0x03, 0xa1, 0x03, 0xc1,
0x03, 0xa3, 0x03, 0xc3,
0x03, 0xa4, 0x03, 0xc4,
0x03, 0xa5, 0x03, 0xc5,
0x03, 0xa6, 0x03, 0xc6,
0x03, 0xa7, 0x03, 0xc7,
0x03, 0xa8, 0x03, 0xc8,
0x03, 0xa9, 0x03, 0xc9,
0x03, 0xe2, 0x03, 0xe3,
0x03, 0xe4, 0x03, 0xe5,
0x03, 0xe6, 0x03, 0xe7,
0x03, 0xe8, 0x03, 0xe9,
0x03, 0xea, 0x03, 0xeb,
0x03, 0xec, 0x03, 0xed,
0x03, 0xee, 0x03, 0xef,
0x04, 0x02, 0x04, 0x52,
0x04, 0x04, 0x04, 0x54,
0x04, 0x05, 0x04, 0x55,
0x04, 0x06, 0x04, 0x56,
0x04, 0x08, 0x04, 0x58,
0x04, 0x09, 0x04, 0x59,
0x04, 0x0a, 0x04, 0x5a,
0x04, 0x0b, 0x04, 0x5b,
0x04, 0x0f, 0x04, 0x5f,
0x04, 0x10, 0x04, 0x30,
0x04, 0x11, 0x04, 0x31,
0x04, 0x12, 0x04, 0x32,
0x04, 0x13, 0x04, 0x33,
0x04, 0x14, 0x04, 0x34,
0x04, 0x15, 0x04, 0x35,
0x04, 0x16, 0x04, 0x36,
0x04, 0x17, 0x04, 0x37,
0x04, 0x18, 0x04, 0x38,
0x04, 0x1a, 0x04, 0x3a,
0x04, 0x1b, 0x04, 0x3b,
0x04, 0x1c, 0x04, 0x3c,
0x04, 0x1d, 0x04, 0x3d,
0x04, 0x1e, 0x04, 0x3e,
0x04, 0x1f, 0x04, 0x3f,
0x04, 0x20, 0x04, 0x40,
0x04, 0x21, 0x04, 0x41,
0x04, 0x22, 0x04, 0x42,
0x04, 0x23, 0x04, 0x43,
0x04, 0x24, 0x04, 0x44,
0x04, 0x25, 0x04, 0x45,
0x04, 0x26, 0x04, 0x46,
0x04, 0x27, 0x04, 0x47,
0x04, 0x28, 0x04, 0x48,
0x04, 0x29, 0x04, 0x49,
0x04, 0x2a, 0x04, 0x4a,
0x04, 0x2b, 0x04, 0x4b,
0x04, 0x2c, 0x04, 0x4c,
0x04, 0x2d, 0x04, 0x4d,
0x04, 0x2e, 0x04, 0x4e,
0x04, 0x2f, 0x04, 0x4f,
0x04, 0x60, 0x04, 0x61,
0x04, 0x62, 0x04, 0x63,
0x04, 0x64, 0x04, 0x65,
0x04, 0x66, 0x04, 0x67,
0x04, 0x68, 0x04, 0x69,
0x04, 0x6a, 0x04, 0x6b,
0x04, 0x6c, 0x04, 0x6d,
0x04, 0x6e, 0x04, 0x6f,
0x04, 0x70, 0x04, 0x71,
0x04, 0x72, 0x04, 0x73,
0x04, 0x74, 0x04, 0x75,
0x04, 0x78, 0x04, 0x79,
0x04, 0x7a, 0x04, 0x7b,
0x04, 0x7c, 0x04, 0x7d,
0x04, 0x7e, 0x04, 0x7f,
0x04, 0x80, 0x04, 0x81,
0x04, 0x90, 0x04, 0x91,
0x04, 0x92, 0x04, 0x93,
0x04, 0x94, 0x04, 0x95,
0x04, 0x96, 0x04, 0x97,
0x04, 0x98, 0x04, 0x99,
0x04, 0x9a, 0x04, 0x9b,
0x04, 0x9c, 0x04, 0x9d,
0x04, 0x9e, 0x04, 0x9f,
0x04, 0xa0, 0x04, 0xa1,
0x04, 0xa2, 0x04, 0xa3,
0x04, 0xa4, 0x04, 0xa5,
0x04, 0xa6, 0x04, 0xa7,
0x04, 0xa8, 0x04, 0xa9,
0x04, 0xaa, 0x04, 0xab,
0x04, 0xac, 0x04, 0xad,
0x04, 0xae, 0x04, 0xaf,
0x04, 0xb0, 0x04, 0xb1,
0x04, 0xb2, 0x04, 0xb3,
0x04, 0xb4, 0x04, 0xb5,
0x04, 0xb6, 0x04, 0xb7,
0x04, 0xb8, 0x04, 0xb9,
0x04, 0xba, 0x04, 0xbb,
0x04, 0xbc, 0x04, 0xbd,
0x04, 0xbe, 0x04, 0xbf,
0x04, 0xc3, 0x04, 0xc4,
0x04, 0xc7, 0x04, 0xc8,
0x04, 0xcb, 0x04, 0xcc,
0x05, 0x31, 0x05, 0x61,
0x05, 0x32, 0x05, 0x62,
0x05, 0x33, 0x05, 0x63,
0x05, 0x34, 0x05, 0x64,
0x05, 0x35, 0x05, 0x65,
0x05, 0x36, 0x05, 0x66,
0x05, 0x37, 0x05, 0x67,
0x05, 0x38, 0x05, 0x68,
0x05, 0x39, 0x05, 0x69,
0x05, 0x3a, 0x05, 0x6a,
0x05, 0x3b, 0x05, 0x6b,
0x05, 0x3c, 0x05, 0x6c,
0x05, 0x3d, 0x05, 0x6d,
0x05, 0x3e, 0x05, 0x6e,
0x05, 0x3f, 0x05, 0x6f,
0x05, 0x40, 0x05, 0x70,
0x05, 0x41, 0x05, 0x71,
0x05, 0x42, 0x05, 0x72,
0x05, 0x43, 0x05, 0x73,
0x05, 0x44, 0x05, 0x74,
0x05, 0x45, 0x05, 0x75,
0x05, 0x46, 0x05, 0x76,
0x05, 0x47, 0x05, 0x77,
0x05, 0x48, 0x05, 0x78,
0x05, 0x49, 0x05, 0x79,
0x05, 0x4a, 0x05, 0x7a,
0x05, 0x4b, 0x05, 0x7b,
0x05, 0x4c, 0x05, 0x7c,
0x05, 0x4d, 0x05, 0x7d,
0x05, 0x4e, 0x05, 0x7e,
0x05, 0x4f, 0x05, 0x7f,
0x05, 0x50, 0x05, 0x80,
0x05, 0x51, 0x05, 0x81,
0x05, 0x52, 0x05, 0x82,
0x05, 0x53, 0x05, 0x83,
0x05, 0x54, 0x05, 0x84,
0x05, 0x55, 0x05, 0x85,
0x05, 0x56, 0x05, 0x86,
0x10, 0xa0, 0x10, 0xd0,
0x10, 0xa1, 0x10, 0xd1,
0x10, 0xa2, 0x10, 0xd2,
0x10, 0xa3, 0x10, 0xd3,
0x10, 0xa4, 0x10, 0xd4,
0x10, 0xa5, 0x10, 0xd5,
0x10, 0xa6, 0x10, 0xd6,
0x10, 0xa7, 0x10, 0xd7,
0x10, 0xa8, 0x10, 0xd8,
0x10, 0xa9, 0x10, 0xd9,
0x10, 0xaa, 0x10, 0xda,
0x10, 0xab, 0x10, 0xdb,
0x10, 0xac, 0x10, 0xdc,
0x10, 0xad, 0x10, 0xdd,
0x10, 0xae, 0x10, 0xde,
0x10, 0xaf, 0x10, 0xdf,
0x10, 0xb0, 0x10, 0xe0,
0x10, 0xb1, 0x10, 0xe1,
0x10, 0xb2, 0x10, 0xe2,
0x10, 0xb3, 0x10, 0xe3,
0x10, 0xb4, 0x10, 0xe4,
0x10, 0xb5, 0x10, 0xe5,
0x10, 0xb6, 0x10, 0xe6,
0x10, 0xb7, 0x10, 0xe7,
0x10, 0xb8, 0x10, 0xe8,
0x10, 0xb9, 0x10, 0xe9,
0x10, 0xba, 0x10, 0xea,
0x10, 0xbb, 0x10, 0xeb,
0x10, 0xbc, 0x10, 0xec,
0x10, 0xbd, 0x10, 0xed,
0x10, 0xbe, 0x10, 0xee,
0x10, 0xbf, 0x10, 0xef,
0x10, 0xc0, 0x10, 0xf0,
0x10, 0xc1, 0x10, 0xf1,
0x10, 0xc2, 0x10, 0xf2,
0x10, 0xc3, 0x10, 0xf3,
0x10, 0xc4, 0x10, 0xf4,
0x10, 0xc5, 0x10, 0xf5,
0x20, 0x0c, 0x00, 0x00,
0x20, 0x0d, 0x00, 0x00,
0x20, 0x0e, 0x00, 0x00,
0x20, 0x0f, 0x00, 0x00,
0x20, 0x2a, 0x00, 0x00,
0x20, 0x2b, 0x00, 0x00,
0x20, 0x2c, 0x00, 0x00,
0x20, 0x2d, 0x00, 0x00,
0x20, 0x2e, 0x00, 0x00,
0x20, 0x6a, 0x00, 0x00,
0x20, 0x6b, 0x00, 0x00,
0x20, 0x6c, 0x00, 0x00,
0x20, 0x6d, 0x00, 0x00,
0x20, 0x6e, 0x00, 0x00,
0x20, 0x6f, 0x00, 0x00,
0x21, 0x60, 0x21, 0x70,
0x21, 0x61, 0x21, 0x71,
0x21, 0x62, 0x21, 0x72,
0x21, 0x63, 0x21, 0x73,
0x21, 0x64, 0x21, 0x74,
0x21, 0x65, 0x21, 0x75,
0x21, 0x66, 0x21, 0x76,
0x21, 0x67, 0x21, 0x77,
0x21, 0x68, 0x21, 0x78,
0x21, 0x69, 0x21, 0x79,
0x21, 0x6a, 0x21, 0x7a,
0x21, 0x6b, 0x21, 0x7b,
0x21, 0x6c, 0x21, 0x7c,
0x21, 0x6d, 0x21, 0x7d,
0x21, 0x6e, 0x21, 0x7e,
0x21, 0x6f, 0x21, 0x7f,
0xfe, 0xff, 0x00, 0x00,
0xff, 0x21, 0xff, 0x41,
0xff, 0x22, 0xff, 0x42,
0xff, 0x23, 0xff, 0x43,
0xff, 0x24, 0xff, 0x44,
0xff, 0x25, 0xff, 0x45,
0xff, 0x26, 0xff, 0x46,
0xff, 0x27, 0xff, 0x47,
0xff, 0x28, 0xff, 0x48,
0xff, 0x29, 0xff, 0x49,
0xff, 0x2a, 0xff, 0x4a,
0xff, 0x2b, 0xff, 0x4b,
0xff, 0x2c, 0xff, 0x4c,
0xff, 0x2d, 0xff, 0x4d,
0xff, 0x2e, 0xff, 0x4e,
0xff, 0x2f, 0xff, 0x4f,
0xff, 0x30, 0xff, 0x50,
0xff, 0x31, 0xff, 0x51,
0xff, 0x32, 0xff, 0x52,
0xff, 0x33, 0xff, 0x53,
0xff, 0x34, 0xff, 0x54,
0xff, 0x35, 0xff, 0x55,
0xff, 0x36, 0xff, 0x56,
0xff, 0x37, 0xff, 0x57,
0xff, 0x38, 0xff, 0x58,
0xff, 0x39, 0xff, 0x59,
0xff, 0x3a, 0xff, 0x5a,
0x00
};
static int utf16be_transl_count = 329;
/* These are the start indice in utf16be_transl[] for the page numbers 0 to 9
as classified by function what_page().
As soon as the first byte of the input pair in utf16be_transl[] changes,
the search can be ended and output is equal to input.
If page -1 is returned by what_page(), then input is equal to output.
*/
static int utf16be_transl_starts[] = {
0, 31, 81, 112, 195, 233, 271, 286, 302, 303
};
static int what_page(uint16_t x)
{
switch(((uint8_t *) &x)[0]) {
case 0:
return 0;
case 1:
return 1;
case 3:
return 2;
case 4:
return 3;
case 5:
return 4;
case 16:
return 5;
case 32:
return 6;
case 33:
return 7;
case 254:
return 8;
case 255:
return 9;
default:
return -1; /* no mapping */
}
}
/* Accelerator for the ASCII subset which is expected to be the most
frequently used one.
*/
static uint16_t cmp_name_page0(uint16_t x)
{
uint8_t *low;
low = ((uint8_t *) &x) + 1;
if (x == 0)
return 0xffff;
if (*low <= 0x40)
;
else if (*low <= 0x5a)
*low = *low + 0x20;
else if (*low < 0xc6)
;
else if (*low == 0xc6)
*low = 0xe6;
else if (*low == 0xd0)
*low = 0xf0;
else if (*low == 0xd8)
*low = 0xf8;
else if (*low == 0xde)
*low = 0xfe;
return x;
}
/* Converts a character into the representative of its HFS+ equivalence
class.
@param x The UTF-16BE character to be converted.
@return 0 = ignore character with comparisons
else the case-insensitive character.
*/
uint16_t iso_hfsplus_cichar(uint16_t x)
{
int page, i;
uint16_t ret;
uint8_t low, high;
high = ((uint8_t *) &x)[0];
low = ((uint8_t *) &x)[1];
page = what_page(x);
if (page < 0)
return x; /* No translation needed */
if (page == 0)
return cmp_name_page0(x); /* Accelerator for ASCII subset */
for (i = utf16be_transl_starts[page] * 4; i < utf16be_transl_count * 4;
i += 4) {
if (utf16be_transl[i] != high)
break;
if (utf16be_transl[i + 1] == low) {
((uint8_t *) &ret)[0] = utf16be_transl[i + 2];
((uint8_t *) &ret)[1] = utf16be_transl[i + 3];
return ret;
}
}
return x;
}

460
libisofs/hfsplus_classes.c Normal file
View File

@ -0,0 +1,460 @@
/*
*
* Based on Unicode 3.2.0.
* See http://www.unicode.org/copyright.html
* Quote from there:
* "Copyright (c) 1991-2012 Unicode, Inc. All rights reserved.
* [...]
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of the Unicode data files and any associated documentation
* (the "Data Files") or Unicode software and any associated documentation
* (the "Software") to deal in the Data Files or Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish,
* distribute, and/or sell copies of the Data Files or Software, and to permit
* persons to whom the Data Files or Software are furnished to do so, provided
* that (a) the above copyright notice(s) and this permission notice appear
* with all copies of the Data Files or Software, (b) both the above copyright
* notice(s) and this permission notice appear in associated documentation,
* and (c) there is clear notice in each modified Data File or in the Software
* as well as in the documentation associated with the Data File(s) or
* Software that the data or software has been modified."
*
*
* For this particular implementation:
*
* Copyright (c) 2012 Vladimir Serbinenko
* Copyright (c) 2012 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
* or later as published by the Free Software Foundation.
* See COPYING file for details.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include <string.h>
#include "hfsplus.h"
/* This encodes a matrix of page and character, with 16-bit words as elements.
Initially the matrix is filled with zeros.
1: The first element is the page number.
If it is equal or lower than the previous one, then the matrix is done.
2: The next element is the character number
If it is equal or lower than the previous one, the page is done. Goto 1.
3: The next element is the byte value. Goto 2.
*/
static uint16_t class_page_data[] = {
/* page 03 */
0x03,
0x00, 0x230,
0x01, 0x230,
0x02, 0x230,
0x03, 0x230,
0x04, 0x230,
0x05, 0x230,
0x06, 0x230,
0x07, 0x230,
0x08, 0x230,
0x09, 0x230,
0x0a, 0x230,
0x0b, 0x230,
0x0c, 0x230,
0x0d, 0x230,
0x0e, 0x230,
0x0f, 0x230,
0x10, 0x230,
0x11, 0x230,
0x12, 0x230,
0x13, 0x230,
0x14, 0x230,
0x15, 0x232,
0x16, 0x220,
0x17, 0x220,
0x18, 0x220,
0x19, 0x220,
0x1a, 0x232,
0x1b, 0x216,
0x1c, 0x220,
0x1d, 0x220,
0x1e, 0x220,
0x1f, 0x220,
0x20, 0x220,
0x21, 0x202,
0x22, 0x202,
0x23, 0x220,
0x24, 0x220,
0x25, 0x220,
0x26, 0x220,
0x27, 0x202,
0x28, 0x202,
0x29, 0x220,
0x2a, 0x220,
0x2b, 0x220,
0x2c, 0x220,
0x2d, 0x220,
0x2e, 0x220,
0x2f, 0x220,
0x30, 0x220,
0x31, 0x220,
0x32, 0x220,
0x33, 0x220,
0x34, 0x1,
0x35, 0x1,
0x36, 0x1,
0x37, 0x1,
0x38, 0x1,
0x39, 0x220,
0x3a, 0x220,
0x3b, 0x220,
0x3c, 0x220,
0x3d, 0x230,
0x3e, 0x230,
0x3f, 0x230,
0x40, 0x230,
0x41, 0x230,
0x42, 0x230,
0x43, 0x230,
0x44, 0x230,
0x45, 0x240,
0x46, 0x230,
0x47, 0x220,
0x48, 0x220,
0x49, 0x220,
0x4a, 0x230,
0x4b, 0x230,
0x4c, 0x230,
0x4d, 0x220,
0x4e, 0x220,
0x60, 0x234,
0x61, 0x234,
0x62, 0x233,
0x63, 0x230,
0x64, 0x230,
0x65, 0x230,
0x66, 0x230,
0x67, 0x230,
0x68, 0x230,
0x69, 0x230,
0x6a, 0x230,
0x6b, 0x230,
0x6c, 0x230,
0x6d, 0x230,
0x6e, 0x230,
0x6f, 0x230,
0x00,
/* page04 */
0x04,
0x83, 0x230,
0x84, 0x230,
0x85, 0x230,
0x86, 0x230,
0x00,
/* page05 */
0x05,
0x91, 0x220,
0x92, 0x230,
0x93, 0x230,
0x94, 0x230,
0x95, 0x230,
0x96, 0x220,
0x97, 0x230,
0x98, 0x230,
0x99, 0x230,
0x9a, 0x222,
0x9b, 0x220,
0x9c, 0x230,
0x9d, 0x230,
0x9e, 0x230,
0x9f, 0x230,
0xa0, 0x230,
0xa1, 0x230,
0xa3, 0x220,
0xa4, 0x220,
0xa5, 0x220,
0xa6, 0x220,
0xa7, 0x220,
0xa8, 0x230,
0xa9, 0x230,
0xaa, 0x220,
0xab, 0x230,
0xac, 0x230,
0xad, 0x222,
0xae, 0x228,
0xaf, 0x230,
0xb0, 0x10,
0xb1, 0x11,
0xb2, 0x12,
0xb3, 0x13,
0xb4, 0x14,
0xb5, 0x15,
0xb6, 0x16,
0xb7, 0x17,
0xb8, 0x18,
0xb9, 0x19,
0xbb, 0x20,
0xbc, 0x21,
0xbd, 0x22,
0xbf, 0x23,
0xc1, 0x24,
0xc2, 0x25,
0xc4, 0x230,
0x00,
/* page06 */
0x06,
0x4b, 0x27,
0x4c, 0x28,
0x4d, 0x29,
0x4e, 0x30,
0x4f, 0x31,
0x50, 0x32,
0x51, 0x33,
0x52, 0x34,
0x53, 0x230,
0x54, 0x230,
0x55, 0x220,
0x70, 0x35,
0xd6, 0x230,
0xd7, 0x230,
0xd8, 0x230,
0xd9, 0x230,
0xda, 0x230,
0xdb, 0x230,
0xdc, 0x230,
0xdf, 0x230,
0xe0, 0x230,
0xe1, 0x230,
0xe2, 0x230,
0xe3, 0x220,
0xe4, 0x230,
0xe7, 0x230,
0xe8, 0x230,
0xea, 0x220,
0xeb, 0x230,
0xec, 0x230,
0xed, 0x220,
0x00,
/* page07 */
0x07,
0x11, 0x36,
0x30, 0x230,
0x31, 0x220,
0x32, 0x230,
0x33, 0x230,
0x34, 0x220,
0x35, 0x230,
0x36, 0x230,
0x37, 0x220,
0x38, 0x220,
0x39, 0x220,
0x3a, 0x230,
0x3b, 0x220,
0x3c, 0x220,
0x3d, 0x230,
0x3e, 0x220,
0x3f, 0x230,
0x40, 0x230,
0x41, 0x230,
0x42, 0x220,
0x43, 0x230,
0x44, 0x220,
0x45, 0x230,
0x46, 0x220,
0x47, 0x230,
0x48, 0x220,
0x49, 0x230,
0x4a, 0x230,
0x00,
/* page09 */
0x09,
0x3c, 0x7,
0x4d, 0x9,
0x51, 0x230,
0x52, 0x220,
0x53, 0x230,
0x54, 0x230,
0xbc, 0x7,
0xcd, 0x9,
0x00,
/* page0a */
0x0a,
0x3c, 0x7,
0x4d, 0x9,
0xbc, 0x7,
0xcd, 0x9,
0x00,
/* page0b */
0x0b,
0x3c, 0x7,
0x4d, 0x9,
0xcd, 0x9,
0x00,
/* page0c */
0x0c,
0x4d, 0x9,
0x55, 0x84,
0x56, 0x91,
0xcd, 0x9,
0x00,
/* page0d */
0x0d,
0x4d, 0x9,
0xca, 0x9,
0x00,
/* page0e */
0x0e,
0x38, 0x103,
0x39, 0x103,
0x3a, 0x9,
0x48, 0x107,
0x49, 0x107,
0x4a, 0x107,
0x4b, 0x107,
0xb8, 0x118,
0xb9, 0x118,
0xc8, 0x122,
0xc9, 0x122,
0xca, 0x122,
0xcb, 0x122,
0x00,
/* page0f */
0x0f,
0x18, 0x220,
0x19, 0x220,
0x35, 0x220,
0x37, 0x220,
0x39, 0x216,
0x71, 0x129,
0x72, 0x130,
0x74, 0x132,
0x7a, 0x130,
0x7b, 0x130,
0x7c, 0x130,
0x7d, 0x130,
0x80, 0x130,
0x82, 0x230,
0x83, 0x230,
0x84, 0x9,
0x86, 0x230,
0x87, 0x230,
0xc6, 0x220,
0x00,
/* page10 */
0x10,
0x37, 0x7,
0x39, 0x9,
0x00,
/* page17 */
0x17,
0x14, 0x9,
0x34, 0x9,
0xd2, 0x9,
0x00,
/* page18 */
0x18,
0xa9, 0x228,
0x00,
/* page20 */
0x20,
0xd0, 0x230,
0xd1, 0x230,
0xd2, 0x1,
0xd3, 0x1,
0xd4, 0x230,
0xd5, 0x230,
0xd6, 0x230,
0xd7, 0x230,
0xd8, 0x1,
0xd9, 0x1,
0xda, 0x1,
0xdb, 0x230,
0xdc, 0x230,
0xe1, 0x230,
0xe5, 0x1,
0xe6, 0x1,
0xe7, 0x230,
0xe8, 0x220,
0xe9, 0x230,
0xea, 0x1,
0x00,
/* page30 */
0x30,
0x2a, 0x218,
0x2b, 0x228,
0x2c, 0x232,
0x2d, 0x222,
0x2e, 0x224,
0x2f, 0x224,
0x99, 0x8,
0x9a, 0x8,
0x00,
/* pagefb */
0xfb,
0x1e, 0x26,
0x00,
/* pagefe */
0xfe,
0x20, 0x230,
0x21, 0x230,
0x22, 0x230,
0x23, 0x230,
};
uint16_t *hfsplus_class_pages[256];
static uint16_t class_pages[19][256];
void make_hfsplus_class_pages()
{
int page_idx = -1, char_idx, i;
uint16_t *rpt, *page_pt;
int page_count = 0;
memset(class_pages, 0, 19 * 256);
for (i = 0; i < 256; i++)
hfsplus_class_pages[i] = NULL;
rpt = (uint16_t *) class_page_data;
page_pt = (uint16_t *) class_pages;
while (1) {
if (*rpt <= page_idx)
break;
page_count++;
page_idx = *(rpt++);
char_idx = -1;
while (1) {
if(*rpt <= char_idx)
break;
char_idx = *(rpt++);
page_pt[char_idx] = *(rpt++);
}
rpt++;
hfsplus_class_pages[page_idx] = class_pages[page_count - 1];
page_pt += 256;
}
}

1090
libisofs/hfsplus_decompose.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 Thomas Schmitt
* Copyright (c) 2009 - 2013 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -78,11 +78,13 @@ int iso_image_new(const char *name, IsoImage **image)
img->volset_id = strdup(name);
img->volume_id = strdup(name);
}
memset(img->application_use, 0, 512);
img->system_area_data = NULL;
img->system_area_options = 0;
img->num_mips_boot_files = 0;
for (i = 0; i < 15; i++)
img->mips_boot_file_paths[i] = NULL;
img->sparc_core_node = NULL;
img->builder_ignore_acl = 1;
img->builder_ignore_ea = 1;
img->inode_counter = 0;
@ -93,6 +95,9 @@ int iso_image_new(const char *name, IsoImage **image)
img->checksum_idx_count = 0;
img->checksum_array = NULL;
img->generator_is_running = 0;
for (i = 0; i < ISO_HFSPLUS_BLESS_MAX; i++)
img->hfsplus_blessed[i] = NULL;
*image = img;
return ISO_SUCCESS;
}
@ -112,25 +117,29 @@ void iso_image_ref(IsoImage *image)
*/
void iso_image_unref(IsoImage *image)
{
if (--image->refcount == 0) {
int nexcl;
int nexcl, i;
if (--image->refcount == 0) {
/* we need to free the image */
if (image->user_data_free != NULL) {
/* free attached data */
image->user_data_free(image->user_data);
}
for (nexcl = 0; nexcl < image->nexcludes; ++nexcl) {
free(image->excludes[nexcl]);
}
free(image->excludes);
for (i = 0; i < ISO_HFSPLUS_BLESS_MAX; i++)
if (image->hfsplus_blessed[i] != NULL)
iso_node_unref(image->hfsplus_blessed[i]);
iso_node_unref((IsoNode*)image->root);
iso_node_builder_unref(image->builder);
iso_filesystem_unref(image->fs);
el_torito_boot_catalog_free(image->bootcat);
iso_image_give_up_mips_boot(image, 0);
if (image->sparc_core_node != NULL)
iso_node_unref((IsoNode *) image->sparc_core_node);
free(image->volset_id);
free(image->volume_id);
free(image->publisher_id);
@ -140,6 +149,10 @@ void iso_image_unref(IsoImage *image)
free(image->copyright_file_id);
free(image->abstract_file_id);
free(image->biblio_file_id);
free(image->creation_time);
free(image->modification_time);
free(image->expiration_time);
free(image->effective_time);
if (image->used_inodes != NULL)
free(image->used_inodes);
if (image->system_area_data != NULL)
@ -330,6 +343,50 @@ const char *iso_image_get_biblio_file_id(const IsoImage *image)
return image->biblio_file_id;
}
int iso_image_set_pvd_times(IsoImage *image,
char *creation_time, char *modification_time,
char *expiration_time, char *effective_time)
{
if (creation_time == NULL || modification_time == NULL ||
expiration_time == NULL || effective_time == NULL)
return ISO_NULL_POINTER;
image->creation_time = strdup(creation_time);
image->modification_time = strdup(modification_time);
image->expiration_time = strdup(expiration_time);
image->effective_time = strdup(effective_time);
if (image->creation_time == NULL || image->modification_time == NULL ||
image->expiration_time == NULL || image->effective_time == NULL)
return ISO_OUT_OF_MEM;
return ISO_SUCCESS;
}
int iso_image_get_pvd_times(IsoImage *image,
char **creation_time, char **modification_time,
char **expiration_time, char **effective_time)
{
if (image->creation_time == NULL || image->modification_time == NULL ||
image->expiration_time == NULL || image->effective_time == NULL)
return ISO_NULL_POINTER;
*creation_time = image->creation_time;
*modification_time = image->modification_time;
*expiration_time = image->expiration_time;
*effective_time = image->effective_time;
return ISO_SUCCESS;
}
void iso_image_set_app_use(IsoImage *image, const char *app_use_data,
int count)
{
if (count < 0)
count= 0;
else if(count > 512)
count= 512;
if (count > 0)
memcpy(image->application_use, app_use_data, count);
if (count < 512)
memset(image->application_use + count, 0, 512 - count);
}
int iso_image_get_msg_id(IsoImage *image)
{
return image->id;
@ -349,6 +406,14 @@ static
int dir_update_size(IsoImage *image, IsoDir *dir)
{
IsoNode *pos;
#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;
@ -357,13 +422,51 @@ int dir_update_size(IsoImage *image, IsoDir *dir)
} 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
}
#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 */
}
#endif /* Libisofs_update_sizes_abortablE */
pos = pos->next;
}
return ISO_SUCCESS;
@ -657,3 +760,94 @@ int iso_image_give_up_mips_boot(IsoImage *image, int flag)
image->num_mips_boot_files = 0;
return ISO_SUCCESS;
}
static void unset_blessing(IsoImage *img, unsigned int idx)
{
if (img->hfsplus_blessed[idx] != NULL)
iso_node_unref(img->hfsplus_blessed[idx]);
img->hfsplus_blessed[idx] = NULL;
}
/* API */
int iso_image_hfsplus_bless(IsoImage *img, enum IsoHfsplusBlessings blessing,
IsoNode *node, int flag)
{
unsigned int i, ok = 0;
if (flag & 2) {
/* Delete any blessing */
for (i = 0; i < ISO_HFSPLUS_BLESS_MAX; i++) {
if (img->hfsplus_blessed[i] == node || node == NULL) {
unset_blessing(img, i);
ok = 1;
}
}
return ok;
}
if (blessing == ISO_HFSPLUS_BLESS_MAX)
return ISO_WRONG_ARG_VALUE;
if (flag & 1) {
/* Delete a particular blessing */
if (img->hfsplus_blessed[blessing] == node || node == NULL) {
unset_blessing(img, (unsigned int) blessing);
return 1;
}
return 0;
}
if (node == NULL) {
unset_blessing(img, (unsigned int) blessing);
return 1;
}
/* No two hats on one node */
for (i = 0; i < ISO_HFSPLUS_BLESS_MAX && node != NULL; i++)
if (i != blessing && img->hfsplus_blessed[i] == node)
return 0;
/* Enforce correct file type */
if (blessing == ISO_HFSPLUS_BLESS_INTEL_BOOTFILE) {
if (node->type != LIBISO_FILE)
return 0;
} else {
if (node->type != LIBISO_DIR)
return 0;
}
unset_blessing(img, (unsigned int) blessing);
img->hfsplus_blessed[blessing] = node;
if (node != NULL)
iso_node_ref(node);
return 1;
}
/* API */
int iso_image_hfsplus_get_blessed(IsoImage *img, IsoNode ***blessed_nodes,
int *bless_max, int flag)
{
*blessed_nodes = img->hfsplus_blessed;
*bless_max = ISO_HFSPLUS_BLESS_MAX;
return 1;
}
/* API */
int iso_image_set_sparc_core(IsoImage *img, IsoFile *sparc_core, int flag)
{
if (img->sparc_core_node != NULL)
iso_node_unref((IsoNode *) img->sparc_core_node);
img->sparc_core_node = sparc_core;
if (sparc_core != NULL)
iso_node_ref((IsoNode *) sparc_core);
return 1;
}
/* API */
int iso_image_get_sparc_core(IsoImage *img, IsoFile **sparc_core, int flag)
{
*sparc_core = img->sparc_core_node;
return 1;
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 Thomas Schmitt
* Copyright (c) 2009 - 2012 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
@ -49,6 +49,11 @@ struct Iso_Image
char *copyright_file_id;
char *abstract_file_id;
char *biblio_file_id;
char *creation_time;
char *modification_time;
char *expiration_time;
char *effective_time;
char application_use[512];
/* el-torito boot catalog */
struct el_torito_boot_catalog *bootcat;
@ -65,6 +70,10 @@ struct Iso_Image
int num_mips_boot_files;
char *mips_boot_file_paths[15]; /* ISO 9660 Rock Ridge Paths */
/* A data file of which the position and size shall be written after
a SUN Disk Label.
*/
IsoFile *sparc_core_node;
/* image identifier, for message origin identifier */
int id;
@ -180,6 +189,13 @@ struct Iso_Image
*/
int generator_is_running;
/* Pointers to directories or files which shall be get a HFS+ blessing.
* libisofs/hfsplus.c et.al. will compare these pointers
* with the ->node pointer of Ecma119Nodes.
* See libisofs.h
*/
IsoNode *hfsplus_blessed[ISO_HFSPLUS_BLESS_MAX];
};
@ -227,4 +243,8 @@ int iso_image_set_checksums(IsoImage *image, char *checksum_array,
uint32_t idx_count, int flag);
int iso_image_set_pvd_times(IsoImage *image,
char *creation_time, char *modification_time,
char *expiration_time, char *effective_time);
#endif /*LIBISO_IMAGE_H_*/

View File

@ -19,6 +19,7 @@
#include "filesrc.h"
#include "eltorito.h"
#include "util.h"
#include "ecma119.h"
#include <stdlib.h>
#include <stdio.h>
@ -801,10 +802,8 @@ int iso1999_writer_write_vol_desc(IsoImageWriter *writer)
strncpy_pad((char*)vol.abstract_file_id, abstract_file_id, 37);
strncpy_pad((char*)vol.bibliographic_file_id, biblio_file_id, 37);
iso_datetime_17(vol.vol_creation_time, t->now, t->always_gmt);
iso_datetime_17(vol.vol_modification_time, t->now, t->always_gmt);
iso_datetime_17(vol.vol_effective_time, t->now, t->always_gmt);
vol.file_structure_version[0] = 1;
ecma119_set_voldescr_times(writer, (struct ecma119_pri_vol_desc *) &vol);
vol.file_structure_version[0] = 2;
free(vol_id);
free(volset_id);

View File

@ -21,6 +21,7 @@
#include "eltorito.h"
#include "libisofs.h"
#include "util.h"
#include "ecma119.h"
#include <stdlib.h>
@ -332,11 +333,12 @@ int joliet_create_mangled_name(uint16_t *dest, uint16_t *src, int digits,
if (ext[0] != (uint16_t)0) {
size_t extlen = ucslen(ext);
dest[pos++] = (uint16_t)0x2E00; /* '.' in big endian UCS */
iso_msb((uint8_t *) (dest + pos), 0x002E, 2); /* '.' in UCS */
pos++;
ucsncpy(dest + pos, ext, extlen);
pos += extlen;
}
dest[pos] = (uint16_t)0;
iso_msb((uint8_t *) (dest + pos), 0, 2);
free(ucsnumber);
return ISO_SUCCESS;
}
@ -911,9 +913,7 @@ int joliet_writer_write_vol_desc(IsoImageWriter *writer)
ucsncpy_pad((uint16_t*)vol.abstract_file_id, abstract_file_id, 37);
ucsncpy_pad((uint16_t*)vol.bibliographic_file_id, biblio_file_id, 37);
iso_datetime_17(vol.vol_creation_time, t->now, t->always_gmt);
iso_datetime_17(vol.vol_modification_time, t->now, t->always_gmt);
iso_datetime_17(vol.vol_effective_time, t->now, t->always_gmt);
ecma119_set_voldescr_times(writer, (struct ecma119_pri_vol_desc *) &vol);
vol.file_structure_version[0] = 1;
free(vol_id);

View File

@ -288,7 +288,7 @@ int libiso_msgs__sev_to_text(int severity, char **severity_name,
int flag)
{
if(flag&1) {
*severity_name= "NEVER\nABORT\nFATAL\nFAILURE\nMISHAP\nSORRY\nWARNING\nHINT\nNOTE\nUPDATE\nDEBUG\nERRFILE\nALL";
*severity_name= "ALL ERRFILE DEBUG UPDATE NOTE HINT WARNING SORRY MISHAP FAILURE FATAL ABORT NEVER";
return(1);
}
*severity_name= "";

View File

@ -316,7 +316,7 @@ int libiso_msgs_submit(struct libiso_msgs *m, int origin, int error_code,
/** Convert a registered severity number into a severity name
@param flag Bitfield for control purposes:
bit0= list all severity names in a newline separated string
bit0= list all severity names in a blank separated string
@return >0 success, <=0 failure
*/
int libiso_msgs__sev_to_text(int severity, char **severity_name,

View File

@ -4,7 +4,7 @@
/*
* Copyright (c) 2007-2008 Vreixo Formoso, Mario Danic
* Copyright (c) 2009-2012 Thomas Schmitt
* Copyright (c) 2009-2013 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -83,7 +83,7 @@
* @since 0.6.2
*/
#define iso_lib_header_version_major 1
#define iso_lib_header_version_minor 2
#define iso_lib_header_version_minor 3
#define iso_lib_header_version_micro 2
/**
@ -295,6 +295,16 @@ enum IsoHideNodeFlag {
/** Hide the node in the ISO-9660:1999 tree, if that format is enabled */
LIBISO_HIDE_ON_1999 = 1 << 2,
/** Hide the node in the HFS+ tree, if that format is enabled.
@since 1.2.4
*/
LIBISO_HIDE_ON_HFSPLUS = 1 << 4,
/** Hide the node in the FAT tree, if that format is enabled.
@since 1.2.4
*/
LIBISO_HIDE_ON_FAT = 1 << 5,
/** With IsoNode and IsoBoot: Write data content even if the node is
* not visible in any tree.
* With directory nodes : Write data content of IsoNode and IsoBoot
@ -1391,6 +1401,96 @@ int iso_write_opts_set_rockridge(IsoWriteOpts *opts, int enable);
*/
int iso_write_opts_set_joliet(IsoWriteOpts *opts, int enable);
/**
* Whether to add a HFS+ filesystem to the image which points to the same
* file content as the other directory trees.
* It will get marked by an Apple Partition Map in the System Area of the ISO
* image. This may collide with data submitted by
* iso_write_opts_set_system_area()
* and with settings made by
* el_torito_set_isolinux_options()
* The first 8 bytes of the System Area get overwritten by
* {0x45, 0x52, 0x08 0x00, 0xeb, 0x02, 0xff, 0xff}
* which can be executed as x86 machine code without negative effects.
* So if an MBR gets combined with this feature, then its first 8 bytes
* should contain no essential commands.
* The next blocks of 2 KiB in the System Area will be occupied by APM entries.
* The first one covers the part of the ISO image before the HFS+ filesystem
* metadata. The second one marks the range from HFS+ metadata to the end
* of file content data. If more ISO image data follow, then a third partition
* entry gets produced. Other features of libisofs might cause the need for
* more APM entries.
*
* @param opts
* The option set to be manipulated.
* @param enable
* 1 to enable HFS+ extension, 0 to not add HFS+ metadata and APM
* @return
* 1 success, < 0 error
*
* @since 1.2.4
*/
int iso_write_opts_set_hfsplus(IsoWriteOpts *opts, int enable);
/**
* >>> Production of FAT32 is not implemented yet.
* >>> This call exists only as preparation for implementation.
*
* Whether to add a FAT32 filesystem to the image which points to the same
* file content as the other directory trees.
*
* >>> FAT32 is planned to get implemented in co-existence with HFS+
* >>> Describe impact on MBR
*
* @param opts
* The option set to be manipulated.
* @param enable
* 1 to enable FAT32 extension, 0 to not add FAT metadata
* @return
* 1 success, < 0 error
*
* @since 1.2.4
*/
int iso_write_opts_set_fat(IsoWriteOpts *opts, int enable);
/**
* Supply a serial number for the HFS+ extension of the emerging image.
*
* @param opts
* The option set to be manipulated.
* @param serial_number
* 8 bytes which should be unique to the image.
* If all bytes are 0, then the serial number will be generated as
* random number by libisofs. This is the default setting.
* @return
* 1 success, < 0 error
*
* @since 1.2.4
*/
int iso_write_opts_set_hfsp_serial_number(IsoWriteOpts *opts,
uint8_t serial_number[8]);
/**
* Set the block size for Apple Partition Map and for HFS+.
*
* @param opts
* The option set to be manipulated.
* @param hfsp_block_size
* The allocation block size to be used by the HFS+ fileystem.
* 0, 512, or 2048
* @param hfsp_block_size
* The block size to be used for and within the Apple Partition Map.
* 0, 512, or 2048.
* Size 512 is not compatible with options which produce GPT.
* @return
* 1 success, < 0 error
*
* @since 1.2.4
*/
int iso_write_opts_set_hfsp_block_size(IsoWriteOpts *opts,
int hfsp_block_size, int apm_block_size);
/**
* Whether to use newer ISO-9660:1999 version.
*
@ -2056,30 +2156,50 @@ int iso_write_opts_set_fifo_size(IsoWriteOpts *opts, size_t fifo_size);
* bit2-7= System area type
* 0= with bit0 or bit1: MBR
* else: unspecified type which will be used unaltered.
* @since 0.6.38
* 1= MIPS Big Endian Volume Header
* @since 0.6.38
* Submit up to 15 MIPS Big Endian boot files by
* iso_image_add_mips_boot_file().
* This will overwrite the first 512 bytes of the submitted
* data.
* 2= DEC Boot Block for MIPS Little Endian
* @since 0.6.38
* The first boot file submitted by
* iso_image_add_mips_boot_file() will be activated.
* This will overwrite the first 512 bytes of the submitted
* data.
* @since 0.6.40
* 3= SUN Disk Label for SUN SPARC
* @since 0.6.40
* Submit up to 7 SPARC boot images by
* iso_write_opts_set_partition_img() for partition numbers 2
* to 8.
* This will overwrite the first 512 bytes of the submitted
* data.
* bit8-9= Only with System area type 0 = MBR
* @since 1.0.4
* Cylinder alignment mode eventually pads the image to make it
* end at a cylinder boundary.
* @since 1.0.4
* Cylinder alignment mode eventually pads the image to make it
* end at a cylinder boundary.
* 0 = auto (align if bit1)
* 1 = always align to cylinder boundary
* 2 = never align to cylinder boundary
* 3 = always align, additionally pad up and align partitions
* which were appended by iso_write_opts_set_partition_img()
* @since 1.2.6
* bit10-13= System area sub type
* @since 1.2.4
* With type 0 = MBR:
* Gets overridden by bit0 and bit1.
* 0 = no particular sub type
* 1 = CHRP: A single MBR partition of type 0x96 covers the
* ISO image. Not compatible with any other feature
* which needs to have own MBR partition entries.
* bit14= Only with System area type 0 = MBR
* GRUB2 boot provisions:
* @since 1.3.0
* Patch system area at byte 92 to 99 with 512-block address + 1
* of the first boot image file. Little-endian 8-byte.
* Should be combined with options bit0.
* Will not be in effect if options bit1 is set.
* @param flag
* bit0 = invalidate any attached system area data. Same as data == NULL
* (This re-activates eventually loaded image System Area data.
@ -2111,7 +2231,10 @@ int iso_write_opts_set_disc_label(IsoWriteOpts *opts, char *label);
/**
* Explicitely set the four timestamps of the emerging Primary Volume
* Descriptor. Default with all parameters is 0.
* Descriptor and in the volume descriptors of Joliet and ISO 9660:1999,
* if those are to be generated.
* Default with all parameters is 0.
*
* ECMA-119 defines them as:
* @param opts
* The option set to be manipulated.
@ -2252,6 +2375,65 @@ int iso_write_opts_detach_jte(IsoWriteOpts *opts, void **libjte_handle);
*/
int iso_write_opts_set_tail_blocks(IsoWriteOpts *opts, uint32_t num_blocks);
/**
* Copy a data file from the local filesystem into the emerging ISO image.
* Mark it by an MBR partition entry as PreP partition and also cause
* protective MBR partition entries before and after this partition.
* Vladimir Serbinenko stated aboy PreP = PowerPC Reference Platform :
* "PreP [...] refers mainly to IBM hardware. PreP boot is a partition
* containing only raw ELF and having type 0x41."
*
* This feature is only combinable with system area type 0
* and currently not combinable with ISOLINUX isohybrid production.
* It overrides --protective-msdos-label. See iso_write_opts_set_system_area().
* Only partition 4 stays available for iso_write_opts_set_partition_img().
* It is compatible with HFS+/FAT production by storing the PreP partition
* before the start of the HFS+/FAT partition.
*
* @param opts
* The option set to be manipulated.
* @param image_path
* File address in the local file system.
* NULL revokes production of the PreP partition.
* @param flag
* Reserved for future usage, set to 0.
* @return
* ISO_SUCCESS or error
*
* @since 1.2.4
*/
int iso_write_opts_set_prep_img(IsoWriteOpts *opts, char *image_path,
int flag);
/**
* Copy a data file from the local filesystem into the emerging ISO image.
* Mark it by an GPT partition entry as EFI System partition, and also cause
* protective GPT partition entries before and after the partition.
* GPT = Globally Unique Identifier Partition Table
*
* This feature may collide with data submitted by
* iso_write_opts_set_system_area()
* and with settings made by
* el_torito_set_isolinux_options()
* It is compatible with HFS+/FAT production by storing the EFI partition
* before the start of the HFS+/FAT partition.
* The GPT overwrites byte 0x0200 to 0x03ff of the system area and all
* further bytes above 0x0800 which are not used by an Apple Partition Map.
*
* @param opts
* The option set to be manipulated.
* @param image_path
* File address in the local file system.
* NULL revokes production of the EFI boot partition.
* @param flag
* Reserved for future usage, set to 0.
* @return
* ISO_SUCCESS or error
*
* @since 1.2.4
*/
int iso_write_opts_set_efi_bootp(IsoWriteOpts *opts, char *image_path,
int flag);
/**
* Cause an arbitrary data file to be appended to the ISO image and to be
@ -2279,6 +2461,8 @@ int iso_write_opts_set_tail_blocks(IsoWriteOpts *opts, uint32_t num_blocks);
* The MBR partition type. E.g. FAT12 = 0x01 , FAT16 = 0x06,
* Linux Native Partition = 0x83. See fdisk command L.
* This parameter is ignored with SUN Disk Label.
* @param flag
* Reserved for future usage, set to 0.
* @return
* ISO_SUCCESS or error
*
@ -2711,7 +2895,7 @@ void iso_image_set_volset_id(IsoImage *image, const char *volset_id);
/**
* Get the volset identifier.
* The returned string is owned by the image and should not be freed nor
* The returned string is owned by the image and must not be freed nor
* changed.
*
* @since 0.6.2
@ -2727,7 +2911,7 @@ void iso_image_set_volume_id(IsoImage *image, const char *volume_id);
/**
* Get the volume identifier.
* The returned string is owned by the image and should not be freed nor
* The returned string is owned by the image and must not be freed nor
* changed.
*
* @since 0.6.2
@ -2743,7 +2927,7 @@ void iso_image_set_publisher_id(IsoImage *image, const char *publisher_id);
/**
* Get the publisher of a image.
* The returned string is owned by the image and should not be freed nor
* The returned string is owned by the image and must not be freed nor
* changed.
*
* @since 0.6.2
@ -2760,7 +2944,7 @@ void iso_image_set_data_preparer_id(IsoImage *image,
/**
* Get the data preparer of a image.
* The returned string is owned by the image and should not be freed nor
* The returned string is owned by the image and must not be freed nor
* changed.
*
* @since 0.6.2
@ -2776,7 +2960,7 @@ void iso_image_set_system_id(IsoImage *image, const char *system_id);
/**
* Get the system id of a image.
* The returned string is owned by the image and should not be freed nor
* The returned string is owned by the image and must not be freed nor
* changed.
*
* @since 0.6.2
@ -2792,7 +2976,7 @@ void iso_image_set_application_id(IsoImage *image, const char *application_id);
/**
* Get the application id of a image.
* The returned string is owned by the image and should not be freed nor
* The returned string is owned by the image and must not be freed nor
* changed.
*
* @since 0.6.2
@ -2810,7 +2994,7 @@ void iso_image_set_copyright_file_id(IsoImage *image,
/**
* Get the copyright information of a image.
* The returned string is owned by the image and should not be freed nor
* The returned string is owned by the image and must not be freed nor
* changed.
*
* @since 0.6.2
@ -2828,7 +3012,7 @@ void iso_image_set_abstract_file_id(IsoImage *image,
/**
* Get the abstract information of a image.
* The returned string is owned by the image and should not be freed nor
* The returned string is owned by the image and must not be freed nor
* changed.
*
* @since 0.6.2
@ -2845,13 +3029,72 @@ void iso_image_set_biblio_file_id(IsoImage *image, const char *biblio_file_id);
/**
* Get the biblio information of a image.
* The returned string is owned by the image and should not be freed nor
* changed.
* The returned string is owned by the image and must not be freed or changed.
*
* @since 0.6.2
*/
const char *iso_image_get_biblio_file_id(const IsoImage *image);
/**
* Fill Application Use field of the Primary Volume Descriptor.
* ECMA-119 8.4.32 Application Use (BP 884 to 1395)
* "This field shall be reserved for application use. Its content
* is not specified by this Standard."
*
* @param image
* The image to manipulate.
* @param app_use_data
* Up to 512 bytes of data.
* @param count
* The number of bytes in app_use_data. If the number is smaller than 512,
* then the remaining bytes will be set to 0.
* @since 1.3.2
*/
void iso_image_set_app_use(IsoImage *image, const char *app_use_data,
int count);
/**
* Get the current setting for the Application Use field of the Primary Volume
* Descriptor.
* The returned char array of 512 bytes is owned by the image and must not
* be freed or changed.
*
* @param image
* The image to inquire
* @since 1.3.2
*/
const char *iso_image_get_app_use(IsoImage *image);
/**
* Get the four timestamps from the Primary Volume Descriptor of the imported
* ISO image. The timestamps are strings which are either empty or consist
* of 17 digits of the form YYYYMMDDhhmmsscc.
* None of the returned string pointers shall be used for altering or freeing
* data. They are just for reading.
*
* @param image
* The image to be inquired.
* @param vol_creation_time
* Returns a pointer to the Volume Creation time:
* When "the information in the volume was created."
* @param vol_modification_time
* Returns a pointer to Volume Modification time:
* When "the information in the volume was last modified."
* @param vol_expiration_time
* Returns a pointer to Volume Expiration time:
* When "the information in the volume may be regarded as obsolete."
* @param vol_effective_time
* Returns a pointer to Volume Expiration time:
* When "the information in the volume may be used."
* @return
* ISO_SUCCESS or error
*
* @since 1.2.8
*/
int iso_image_get_pvd_times(IsoImage *image,
char **creation_time, char **modification_time,
char **expiration_time, char **effective_time);
/**
* Create a new set of El-Torito bootable images by adding a boot catalog
* and the default boot image.
@ -2880,7 +3123,7 @@ const char *iso_image_get_biblio_file_id(const IsoImage *image);
* creation time.
* @param boot
* Location where a pointer to the added boot image will be stored. That
* object is owned by the IsoImage and should not be freed by the user,
* object is owned by the IsoImage and must not be freed by the user,
* nor dereferenced once the last reference to the IsoImage was disposed
* via iso_image_unref(). A NULL value is allowed if you don't need a
* reference to the boot image.
@ -2930,7 +3173,7 @@ int iso_image_add_boot_image(IsoImage *image, const char *image_path,
* the image and catalog tree nodes. An application would want those, for
* example, to prevent the user removing it.
*
* Both nodes are owned by libisofs and should not be freed. You can get your
* Both nodes are owned by libisofs and must not be freed. You can get your
* own ref with iso_node_ref(). You can also check if the node is already
* on the tree by getting its parent (note that when reading El-Torito info
* from a previous image, the nodes might not be on the tree even if you haven't
@ -2942,7 +3185,7 @@ int iso_image_add_boot_image(IsoImage *image, const char *image_path,
* The image from which to get the boot image.
* @param boot
* If not NULL, it will be filled with a pointer to the boot image, if
* any. That object is owned by the IsoImage and should not be freed by
* any. That object is owned by the IsoImage and must not be freed by
* the user, nor dereferenced once the last reference to the IsoImage was
* disposed via iso_image_unref().
* @param imgnode
@ -3190,7 +3433,7 @@ int el_torito_get_bootable(ElToritoBootImage *bootimg);
* the CD-ROM".
* Further boot images put 28 bytes into their Section Header.
* El Torito 1.0 states that "If the BIOS understands the ID string, it
* may choose to boot the * system using one of these entries in place
* may choose to boot the system using one of these entries in place
* of the INITIAL/DEFAULT entry." (The INITIAL/DEFAULT entry points to the
* first boot image.)
* @return
@ -3260,9 +3503,15 @@ int el_torito_get_selection_crit(ElToritoBootImage *bootimg, uint8_t crit[20]);
* @param bootimg
* The image to inquire
* @param flag
* Reserved for future usage, set to 0.
* Bitfield for control purposes:
* bit0 - bit3= mode
* 0 = inquire for classic boot info table as described in man mkisofs
* @since 0.6.32
* 1 = inquire for GRUB2 boot info as of bit9 of options of
* el_torito_set_isolinux_options()
* @since 1.3.0
* @return
* 1 = seems to contain oot info table , 0 = quite surely not
* 1 = seems to contain the inquired boot info, 0 = quite surely not
* @since 0.6.32
*/
int el_torito_seems_boot_info_table(ElToritoBootImage *bootimg, int flag);
@ -3276,30 +3525,61 @@ int el_torito_seems_boot_info_table(ElToritoBootImage *bootimg, int flag);
* @param options
* bitmask style flag. The following values are defined:
*
* bit 0 -> 1 to patch the boot info table of the boot image.
* 1 does the same as mkisofs option -boot-info-table.
* Needed for ISOLINUX or GRUB boot images with platform ID 0.
* The table is located at byte 8 of the boot image file.
* Its size is 56 bytes.
* The original boot image file on disk will not be modified.
* bit0= Patch the boot info table of the boot image.
* This does the same as mkisofs option -boot-info-table.
* Needed for ISOLINUX or GRUB boot images with platform ID 0.
* The table is located at byte 8 of the boot image file.
* Its size is 56 bytes.
* The original boot image file on disk will not be modified.
*
* One may use el_torito_seems_boot_info_table() for a
* qualified guess whether a boot info table is present in
* the boot image. If the result is 1 then it should get bit0
* set if its content gets copied to a new LBA.
* One may use el_torito_seems_boot_info_table() for a
* qualified guess whether a boot info table is present in
* the boot image. If the result is 1 then it should get bit0
* set if its content gets copied to a new LBA.
*
* bit 1 -> 1 to generate a ISOLINUX isohybrid image with MBR.
* ----------------------------------------------------------
* @deprecated since 31 Mar 2010:
* The author of syslinux, H. Peter Anvin requested that this
* feature shall not be used any more. He intends to cease
* support for the MBR template that is included in libisofs.
* ----------------------------------------------------------
* A hybrid image is a boot image that boots from either
* CD/DVD media or from disk-like media, e.g. USB stick.
* For that you need isolinux.bin from SYSLINUX 3.72 or later.
* IMPORTANT: The application has to take care that the image
* on media gets padded up to the next full MB.
* bit1= Generate a ISOLINUX isohybrid image with MBR.
* ----------------------------------------------------------
* @deprecated since 31 Mar 2010:
* The author of syslinux, H. Peter Anvin requested that this
* feature shall not be used any more. He intends to cease
* support for the MBR template that is included in libisofs.
* ----------------------------------------------------------
* A hybrid image is a boot image that boots from either
* CD/DVD media or from disk-like media, e.g. USB stick.
* For that you need isolinux.bin from SYSLINUX 3.72 or later.
* IMPORTANT: The application has to take care that the image
* on media gets padded up to the next full MB.
* Under seiveral circumstances it might get aligned
* automatically. But there is no warranty.
* bit2-7= Mentioning in isohybrid GPT
* 0= Do not mention in GPT
* 1= Mention as Basic Data partition.
* This cannot be combined with GPT partitions as of
* iso_write_opts_set_efi_bootp()
* @since 1.2.4
* 2= Mention as HFS+ partition.
* This cannot be combined with HFS+ production by
* iso_write_opts_set_hfsplus().
* @since 1.2.4
* Primary GPT and backup GPT get written if at least one
* ElToritoBootImage shall be mentioned.
* The first three mentioned GPT partitions get mirrored in the
* the partition table of the isohybrid MBR. They get type 0xfe.
* The MBR partition entry for PC-BIOS gets type 0x00 rather
* than 0x17.
* Often it is one of the further MBR partitions which actually
* gets used by EFI.
* @since 1.2.4
* bit8= Mention in isohybrid Apple partition map
* APM get written if at least one ElToritoBootImage shall be
* mentioned. The ISOLINUX MBR must look suitable or else an error
* event will happen at image generation time.
* @since 1.2.4
* bit9= GRUB2 boot info
* Patch the boot image file at byte 1012 with the 512-block
* address + 2. Two little endian 32-bit words. Low word first.
* This is combinable with bit0.
* @since 1.3.0
* @param flag
* Reserved for future usage, set to 0.
* @return
@ -3343,7 +3623,7 @@ void el_torito_patch_isolinux_image(ElToritoBootImage *bootimg);
* @param img
* The image to be inquired.
* @param data
* A byte array of at least 32768 bytesi to take the loaded bytes.
* A byte array of at least 32768 bytes to take the loaded bytes.
* @param options
* The option bits which will be applied if not overridden by
* iso_write_opts_set_system_area(). See there.
@ -3407,6 +3687,41 @@ int iso_image_get_mips_boot_files(IsoImage *image, char *paths[15], int flag);
*/
int iso_image_give_up_mips_boot(IsoImage *image, int flag);
/**
* Designate a data file in the ISO image of which the position and size
* shall be written after the SUN Disk Label. The position is written as
* 64-bit big-endian number to byte position 0x228. The size is written
* as 32-bit big-endian to 0x230.
* This setting has an effect only if system area type is set to 3
* with iso_write_opts_set_system_area().
*
* @param img
* The image to be manipulated.
* @param sparc_core
* The IsoFile which shall be mentioned after the SUN Disk label.
* NULL is a permissible value. It disables this feature.
* @param flag
* Bitfield for control purposes, unused yet, submit 0
* @return
* 1 is success , <0 means error
* @since 1.3.0
*/
int iso_image_set_sparc_core(IsoImage *img, IsoFile *sparc_core, int flag);
/**
* Obtain the current setting of iso_image_set_sparc_core().
*
* @param img
* The image to be inquired.
* @param sparc_core
* Will return a pointer to the IsoFile (or NULL, which is not an error)
* @param flag
* Bitfield for control purposes, unused yet, submit 0
* @return
* 1 is success , <0 means error
* @since 1.3.0
*/
int iso_image_get_sparc_core(IsoImage *img, IsoFile **sparc_core, int flag);
/**
* Increments the reference counting of the given node.
@ -3512,8 +3827,8 @@ int iso_node_remove_all_xinfo(IsoNode *node, int flag);
* @param proc
* The function pointer which serves as key
* @param data
* Will be filled with the extended info corresponding to the given proc
* function
* Will after successful call point to the xinfo data corresponding
* to the given proc. This is a pointer, not a feeable data copy.
* @return
* 1 on success, 0 if node does not have extended info of the requested
* type, < 0 on error
@ -3638,7 +3953,7 @@ int iso_node_set_name(IsoNode *node, const char *name);
/**
* Get the name of a node.
* The returned string belongs to the node and should not be modified nor
* The returned string belongs to the node and must not be modified nor
* freed. Use strdup if you really need your own copy.
*
* @since 0.6.2
@ -4217,7 +4532,7 @@ int iso_dir_find_children(IsoDir* dir, IsoFindCondition *cond,
/**
* Get the destination of a node.
* The returned string belongs to the node and should not be modified nor
* The returned string belongs to the node and must not be modified nor
* freed. Use strdup if you really need your own copy.
*
* @since 0.6.2
@ -4868,6 +5183,37 @@ int iso_tree_path_to_node(IsoImage *image, const char *path, IsoNode **node);
*/
char *iso_tree_get_node_path(IsoNode *node);
/**
* Get the destination node of a symbolic link within the IsoImage.
*
* @param img
* The image wherein to try resolving the link.
* @param sym
* The symbolic link node which to resolve.
* @param res
* Will return the found destination node, in case of success.
* Call iso_node_ref() / iso_node_unref() if you intend to use the node
* over API calls which might in any event delete it.
* @param depth
* Prevents endless loops. Submit as 0.
* @param flag
* Bitfield for control purposes. Submit 0 for now.
* @return
* 1 on success,
* < 0 on failure, especially ISO_DEEP_SYMLINK and ISO_DEAD_SYMLINK
*
* @since 1.2.4
*/
int iso_tree_resolve_symlink(IsoImage *img, IsoSymlink *sym, IsoNode **res,
int *depth, int flag);
/* Maximum number link resolution steps before ISO_DEEP_SYMLINK gets
* returned by iso_tree_resolve_symlink().
*
* @since 1.2.4
*/
#define LIBISO_MAX_LINK_DEPTH 100
/**
* Increments the reference counting of the given IsoDataSource.
*
@ -5854,6 +6200,10 @@ int iso_node_lookup_attr(IsoNode *node, char *name,
* I.e. those with a non-empty name which does not begin by "user."
* (The empty name is always allowed and governed by bit0.) This
* deletes all previously existing attributes if not bit1 is set.
* bit4= Do not affect attributes from namespace "isofs".
* To be combined with bit3 for copying attributes from local
* filesystem to ISO image.
* @since 1.2.4
* @return
* 1 = ok
* < 0 = error
@ -6100,7 +6450,10 @@ int iso_file_remove_filter(IsoFile *file, int flag);
* @param stream
* The eventual filter stream to be inquired.
* @param flag
* Bitfield for control purposes. Submit 0 for now.
* Bitfield for control purposes.
* bit0= Follow the chain of input streams and return the one at the
* end of the chain.
* @since 1.3.2
* @return
* The input stream, if one exists. Elsewise NULL.
* No extra reference to the stream is taken by this call.
@ -6608,6 +6961,144 @@ int iso_md5_end(void **md5_context, char result[16]);
int iso_md5_match(char first_md5[16], char second_md5[16]);
/* -------------------------------- For HFS+ ------------------------------- */
/**
* HFS+ attributes which may be attached to IsoNode objects as data parameter
* of iso_node_add_xinfo(). As parameter proc use iso_hfsplus_xinfo_func().
* Create instances of this struct by iso_hfsplus_xinfo_new().
*
* @since 1.2.4
*/
struct iso_hfsplus_xinfo_data {
/* Currently set to 0 by iso_hfsplus_xinfo_new() */
int version;
/* Attributes available with version 0.
* See: http://en.wikipedia.org/wiki/Creator_code , .../Type_code
* @since 1.2.4
*/
uint8_t creator_code[4];
uint8_t type_code[4];
};
/**
* The function that is used to mark struct iso_hfsplus_xinfo_data at IsoNodes
* and finally disposes such structs when their IsoNodes get disposed.
* Usually an application does not call this function, but only uses it as
* parameter of xinfo calls like iso_node_add_xinfo() or iso_node_get_xinfo().
*
* @since 1.2.4
*/
int iso_hfsplus_xinfo_func(void *data, int flag);
/**
* Create an instance of struct iso_hfsplus_xinfo_new().
*
* @param flag
* Bitfield for control purposes. Unused yet. Submit 0.
* @return
* A pointer to the new object
* NULL indicates failure to allocate memory
*
* @since 1.2.4
*/
struct iso_hfsplus_xinfo_data *iso_hfsplus_xinfo_new(int flag);
/**
* HFS+ blessings are relationships between HFS+ enhanced ISO images and
* particular files in such images. Except for ISO_HFSPLUS_BLESS_INTEL_BOOTFILE
* and ISO_HFSPLUS_BLESS_MAX, these files have to be directories.
* No file may have more than one blessing. Each blessing can only be issued
* to one file.
*
* @since 1.2.4
*/
enum IsoHfsplusBlessings {
/* The blessing that is issued by mkisofs option -hfs-bless. */
ISO_HFSPLUS_BLESS_PPC_BOOTDIR,
/* To be applied to a data file */
ISO_HFSPLUS_BLESS_INTEL_BOOTFILE,
/* Further blessings for directories */
ISO_HFSPLUS_BLESS_SHOWFOLDER,
ISO_HFSPLUS_BLESS_OS9_FOLDER,
ISO_HFSPLUS_BLESS_OSX_FOLDER,
/* Not a blessing, but telling the number of blessings in this list */
ISO_HFSPLUS_BLESS_MAX
};
/**
* Issue a blessing to a particular IsoNode. If the blessing is already issued
* to some file, then it gets revoked from that one.
*
* @param image
* The image to manipulate.
* @param blessing
* The kind of blessing to be issued.
* @param node
* The file that shall be blessed. It must actually be an IsoDir or
* IsoFile as is appropriate for the kind of blessing. (See above enum.)
* The node may not yet bear a blessing other than the desired one.
* If node is NULL, then the blessing will be revoked from any node
* which bears it.
* @param flag
* Bitfield for control purposes.
* bit0= Revoke blessing if node != NULL bears it.
* bit1= Revoke any blessing of the node, regardless of parameter
* blessing. If node is NULL, then revoke all blessings in
* the image.
* @return
* 1 means successful blessing or revokation of an existing blessing.
* 0 means the node already bears another blessing, or is of wrong type,
* or that the node was not blessed and revokation was desired.
* <0 is one of the listed error codes.
*
* @since 1.2.4
*/
int iso_image_hfsplus_bless(IsoImage *img, enum IsoHfsplusBlessings blessing,
IsoNode *node, int flag);
/**
* Get the array of nodes which are currently blessed.
* Array indice correspond to enum IsoHfsplusBlessings.
* Array element value NULL means that no node bears that blessing.
*
* Several usage restrictions apply. See parameter blessed_nodes.
*
* @param image
* The image to inquire.
* @param blessed_nodes
* Will return a pointer to an internal node array of image.
* This pointer is valid only as long as image exists and only until
* iso_image_hfsplus_bless() gets used to manipulate the blessings.
* Do not free() this array. Do not alter the content of the array
* directly, but rather use iso_image_hfsplus_bless() and re-inquire
* by iso_image_hfsplus_get_blessed().
* This call does not impose an extra reference on the nodes in the
* array. So do not iso_node_unref() them.
* Nodes listed here are not necessarily grafted into the tree of
* the IsoImage.
* @param bless_max
* Will return the number of elements in the array.
* It is unlikely but not outruled that it will be larger than
* ISO_HFSPLUS_BLESS_MAX in this libisofs.h file.
* @param flag
* Bitfield for control purposes. Submit 0.
* @return
* 1 means success, <0 means error
*
* @since 1.2.4
*/
int iso_image_hfsplus_get_blessed(IsoImage *img, IsoNode ***blessed_nodes,
int *bless_max, int flag);
/************ Error codes and return values for libisofs ********************/
/** successfully execution */
@ -6843,7 +7334,6 @@ int iso_md5_match(char first_md5[16], char second_md5[16]);
(FAILURE, HIGH, -343) */
#define ISO_AAIP_NON_USER_NAME 0xE830FEA9
/** Too many references on a single IsoExternalFilterCommand
(FAILURE, HIGH, -344) */
#define ISO_EXTF_TOO_OFTEN 0xE830FEA8
@ -6969,7 +7459,7 @@ int iso_md5_match(char first_md5[16], char second_md5[16]);
/** Cannot open data file for appended partition (FAILURE, HIGH, -370) */
#define ISO_BAD_PARTITION_FILE 0xE830FE8E
/** May not combine appended partition with non-MBR system area
/** May not combine MBR partition with non-MBR system area
(FAILURE, HIGH, -371) */
#define ISO_NON_MBR_SYS_AREA 0xE830FE8D
@ -7004,15 +7494,61 @@ int iso_md5_match(char first_md5[16], char second_md5[16]);
#define ISO_AAIP_BAD_ATTR_NAME 0xE830FE84
/** ACL text contains multiple entries of user::, group::, other::
(FAILURE, HIGH, -379) */
(FAILURE, HIGH, -381) */
#define ISO_AAIP_ACL_MULT_OBJ 0xE830FE83
/** File sections do not form consecutive array of blocks
(FAILURE, HIGH, -382) */
#define ISO_SECT_SCATTERED 0xE830FE82
/** Too many Apple Partition Map entries requested (FAILURE, HIGH, -383) */
#define ISO_BOOT_TOO_MANY_APM 0xE830FE81
/** Overlapping Apple Partition Map entries requested (FAILURE, HIGH, -384) */
#define ISO_BOOT_APM_OVERLAP 0xE830FE80
/** Too many GPT entries requested (FAILURE, HIGH, -385) */
#define ISO_BOOT_TOO_MANY_GPT 0xE830FE7F
/** Overlapping GPT entries requested (FAILURE, HIGH, -386) */
#define ISO_BOOT_GPT_OVERLAP 0xE830FE7E
/** Too many MBR partition entries requested (FAILURE, HIGH, -387) */
#define ISO_BOOT_TOO_MANY_MBR 0xE830FE7D
/** Overlapping MBR partition entries requested (FAILURE, HIGH, -388) */
#define ISO_BOOT_MBR_OVERLAP 0xE830FE7C
/** Attempt to use an MBR partition entry twice (FAILURE, HIGH, -389) */
#define ISO_BOOT_MBR_COLLISION 0xE830FE7B
/** No suitable El Torito EFI boot image for exposure as GPT partition
(FAILURE, HIGH, -390) */
#define ISO_BOOT_NO_EFI_ELTO 0xE830FE7A
/** Not a supported HFS+ or APM block size (FAILURE, HIGH, -391) */
#define ISO_BOOT_HFSP_BAD_BSIZE 0xE830FE79
/** APM block size prevents coexistence with GPT (FAILURE, HIGH, -392) */
#define ISO_BOOT_APM_GPT_BSIZE 0xE830FE78
/** Name collision in HFS+, mangling not possible (FAILURE, HIGH, -393) */
#define ISO_HFSP_NO_MANGLE 0xE830FE77
/** Symbolic link cannot be resolved (FAILURE, HIGH, -394) */
#define ISO_DEAD_SYMLINK 0xE830FE76
/** Too many chained symbolic links (FAILURE, HIGH, -395) */
#define ISO_DEEP_SYMLINK 0xE830FE75
/** Unrecognized file type in ISO image (FAILURE, HIGH, -396) */
#define ISO_BAD_ISO_FILETYPE 0xE830FE74
/* Internal developer note:
Place new error codes directly above this comment.
Newly introduced errors must get a message entry in
libisofs/message.c, function iso_error_to_msg()
libisofs/messages.c, function iso_error_to_msg()
*/
/* ! PLACE NEW ERROR CODES ABOVE. NOT AFTER THIS LINE ! */
@ -7057,42 +7593,12 @@ int iso_md5_match(char first_md5[16], char second_md5[16]);
This allows to use arbitrary program code as provider of track input data.
Objects compliant to this interface are either provided by the application
or by API calls of libburn: burn_fd_source_new() , burn_file_source_new(),
or by API calls of libburn: burn_fd_source_new(), burn_file_source_new(),
and burn_fifo_source_new().
The API calls allow to use any file object as data source. Consider to feed
an eventual custom data stream asynchronously into a pipe(2) and to let
libburn handle the rest.
In this case the following rule applies:
Call burn_source_free() exactly once for every source obtained from
libburn API. You MUST NOT otherwise use or manipulate its components.
libisofs acts as "application" and implements an own class of burn_source.
Instances of that class are handed out by iso_image_create_burn_source().
In general, burn_source objects can be freed as soon as they are attached
to track objects. The track objects will keep them alive and dispose them
when they are no longer needed. With a fifo burn_source it makes sense to
keep the own reference for inquiring its state while burning is in
progress.
---
The following description of burn_source applies only to application
implemented burn_source objects. You need not to know it for API provided
ones.
If you really implement an own passive data producer by this interface,
then beware: it can do anything and it can spoil everything.
In this case the functions (*read), (*get_size), (*set_size), (*free_data)
MUST be implemented by the application and attached to the object at
creation time.
Function (*read_sub) is allowed to be NULL or it MUST be implemented and
attached.
burn_source.refcount MUST be handled properly: If not exactly as many
references are freed as have been obtained, then either memory leaks or
corrupted memory are the consequence.
All objects which are referred to by *data must be kept existent until
(*free_data) is called via burn_source_free() by the last referer.
*/
struct burn_source {
@ -7225,11 +7731,6 @@ struct burn_source {
/* currently none being tested */
/* Perform the operations promised by iso_write_opts_set_rr_reloc() */
#define Libisofs_with_rr_reloc_diR yes
/* ---------------------------- Experiments ---------------------------- */

View File

@ -65,9 +65,12 @@ iso_file_source_unref;
iso_filesystem_ref;
iso_filesystem_unref;
iso_finish;
iso_fs_global_id;
iso_get_local_charset;
iso_get_messenger;
iso_gzip_get_refcounts;
iso_hfsplus_xinfo_func;
iso_hfsplus_xinfo_new;
iso_image_add_boot_image;
iso_image_add_mips_boot_file;
iso_image_attach_data;
@ -85,6 +88,7 @@ iso_image_fs_get_volume_id;
iso_image_generator_is_running;
iso_image_get_abstract_file_id;
iso_image_get_all_boot_imgs;
iso_image_get_app_use;
iso_image_get_application_id;
iso_image_get_attached_data;
iso_image_get_biblio_file_id;
@ -95,18 +99,23 @@ iso_image_get_data_preparer_id;
iso_image_get_mips_boot_files;
iso_image_get_msg_id;
iso_image_get_publisher_id;
iso_image_get_pvd_times;
iso_image_get_root;
iso_image_get_session_md5;
iso_image_get_sparc_core;
iso_image_get_system_area;
iso_image_get_system_id;
iso_image_get_volset_id;
iso_image_get_volume_id;
iso_image_give_up_mips_boot;
iso_image_hfsplus_bless;
iso_image_hfsplus_get_blessed;
iso_image_import;
iso_image_new;
iso_image_ref;
iso_image_remove_boot_image;
iso_image_set_abstract_file_id;
iso_image_set_app_use;
iso_image_set_application_id;
iso_image_set_biblio_file_id;
iso_image_set_boot_catalog_hidden;
@ -116,6 +125,7 @@ iso_image_set_copyright_file_id;
iso_image_set_data_preparer_id;
iso_image_set_ignore_aclea;
iso_image_set_publisher_id;
iso_image_set_sparc_core;
iso_image_set_system_id;
iso_image_set_volset_id;
iso_image_set_volume_id;
@ -252,6 +262,7 @@ iso_tree_get_node_path;
iso_tree_get_replace_mode;
iso_tree_path_to_node;
iso_tree_remove_exclude;
iso_tree_resolve_symlink;
iso_tree_set_follow_symlinks;
iso_tree_set_ignore_hidden;
iso_tree_set_ignore_special;
@ -280,8 +291,13 @@ iso_write_opts_set_default_timestamp;
iso_write_opts_set_default_uid;
iso_write_opts_set_dir_rec_mtime;
iso_write_opts_set_disc_label;
iso_write_opts_set_efi_bootp;
iso_write_opts_set_fat;
iso_write_opts_set_fifo_size;
iso_write_opts_set_hardlinks;
iso_write_opts_set_hfsp_block_size;
iso_write_opts_set_hfsp_serial_number;
iso_write_opts_set_hfsplus;
iso_write_opts_set_iso1999;
iso_write_opts_set_iso_level;
iso_write_opts_set_joliet;
@ -296,6 +312,7 @@ iso_write_opts_set_output_charset;
iso_write_opts_set_overwrite_buf;
iso_write_opts_set_part_offset;
iso_write_opts_set_partition_img;
iso_write_opts_set_prep_img;
iso_write_opts_set_pvd_times;
iso_write_opts_set_record_md5;
iso_write_opts_set_relaxed_vol_atts;

View File

@ -23,6 +23,11 @@
/* for gettimeofday() */
#include <sys/time.h>
#include "filesrc.h"
#include "ecma119.h"
#include "eltorito.h"
#include "system_area.h"
/* This code stems from syslinux-3.72/utils/isohybrid, a perl script
under GPL which is Copyright 2002-2008 H. Peter Anvin.
@ -45,7 +50,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-2010 Thomas Schmitt
and 2008-2012 Thomas Schmitt
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
@ -353,6 +358,12 @@ Main:
*/
/* The new stuff about GPT and APM which was learned from Matthew Garret
and isohybrid.c is described in doc/boot_sectord.txt chapter
"SYSLINUX isohybrid for MBR, UEFI and x86-Mac"
*/
static
int lba512chs_to_buf(char **wpt, off_t lba, int head_count, int sector_count)
{
@ -377,23 +388,206 @@ int lba512chs_to_buf(char **wpt, off_t lba, int head_count, int sector_count)
}
/* Find out whether GPT and APM are desired
flag bit0 = register APM and GPT requests in Ecma119Image
*/
int assess_isohybrid_gpt_apm(Ecma119Image *t, int *gpt_count, int gpt_idx[128],
int *apm_count, int flag)
{
int i, ilx_opts, j, ret, num_img;
uint32_t block_count;
uint8_t gpt_name[72];
static uint8_t zero_uuid[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
static uint8_t basic_data_uuid[16] = {
0xa2, 0xa0, 0xd0, 0xeb, 0xe5, 0xb9, 0x33, 0x44,
0x87, 0xc0, 0x68, 0xb6, 0xb7, 0x26, 0x99, 0xc7
};
static uint8_t hfs_uuid[16] = {
0x00, 0x53, 0x46, 0x48, 0x00, 0x00, 0xaa, 0x11,
0xaa, 0x11, 0x00, 0x30, 0x65, 0x43, 0xec, 0xac
};
uint8_t *uuid;
static uint64_t gpt_flags = (((uint64_t) 1) << 60) | 1;
*gpt_count = 0;
*apm_count = 0;
if (t->catalog != NULL)
num_img = t->catalog->num_bootimages;
else
num_img = 0;
for (i = 0; i < num_img; i++) {
ilx_opts = t->catalog->bootimages[i]->isolinux_options;
if (((ilx_opts >> 2) & 63) == 1 || ((ilx_opts >> 2) & 63) == 2) {
if (*gpt_count < 128)
gpt_idx[*gpt_count]= i;
(*gpt_count)++;
if ((flag & 1) && t->bootsrc[i] != NULL) {
/* Register GPT entry */
memset(gpt_name, 0, 72);
sprintf((char *) gpt_name, "ISOHybrid%d", *gpt_count);
iso_ascii_utf_16le(gpt_name);
if (((ilx_opts >> 2) & 63) == 2)
uuid = hfs_uuid;
else
uuid = basic_data_uuid;
block_count = 0;
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);
if (ret < 0)
return ret;
}
}
if (ilx_opts & 256) {
(*apm_count)++;
if ((flag & 1) && t->bootsrc[i] != NULL) {
/* Register APM entry */
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,
block_count, "EFI", "Apple_HFS");
if (ret < 0)
return ret;
/* Prevent gap filling */
t->apm_req_flags |= 2;
t->apm_block_size = 2048;
}
}
}
if ((flag & 1) && *gpt_count > 0) {
/* Register overall GPT partition */
memset(gpt_name, 0, 72);
sprintf((char *) gpt_name, "ISOHybrid");
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,
basic_data_uuid, zero_uuid, gpt_flags,
(uint8_t *) gpt_name);
if (ret < 0)
return ret;
/* Remove ban on GPT overlapping */
t->gpt_req_flags |= 1;
}
return ISO_SUCCESS;
}
/* Insert APM head into MBR */
static int insert_apm_head(uint8_t *buf, int apm_count)
{
int i;
static uint8_t apm_mbr_start[32] = {
0x33, 0xed, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90
};
static uint8_t apm_head[32] = {
0x45, 0x52, 0x08, 0x00, 0x00, 0x00, 0x90, 0x90,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
if (apm_count) {
for (i = 0; i < 32; i++)
if(buf[i] != apm_mbr_start[i])
break;
if (i < 32) {
/* Maybe it is already patched by apm_head ? */
for (i = 0; i < 32; i++)
if(buf[i] != apm_head[i])
break;
}
if (i < 32) {
iso_msgs_submit(0,
"MBR template file seems not prepared for Apple Partition Map.",
0, "FAILURE", 0);
return ISO_ISOLINUX_CANT_PATCH;
}
for (i = 0; i < 32; i++)
buf[i] = apm_head[i];
}
return ISO_SUCCESS;
}
/* Describe GPT boot images as MBR partitions */
static int gpt_images_as_mbr_partitions(Ecma119Image *t, char *wpt,
int gpt_idx[128], int *gpt_cursor)
{
int ilx_opts;
off_t hd_blocks;
static uint8_t dummy_chs[3] = {
0xfe, 0xff, 0xff,
};
wpt[0] = 0;
memcpy(wpt + 1, dummy_chs, 3);
ilx_opts = t->catalog->bootimages[gpt_idx[*gpt_cursor]]->isolinux_options;
if (((ilx_opts >> 2) & 63) == 2)
wpt[4] = 0x00; /* HFS gets marked as "Empty" */
else
((unsigned char *) wpt)[4] = 0xef; /* "EFI (FAT-12/16/" */
memcpy(wpt + 5, dummy_chs, 3);
/* Start LBA (in 512 blocks) */
wpt += 8;
lsb_to_buf(&wpt, t->bootsrc[gpt_idx[*gpt_cursor]]->sections[0].block * 4,
32, 0);
/* Number of blocks */
hd_blocks = t->bootsrc[gpt_idx[*gpt_cursor]]->sections[0].size;
hd_blocks = hd_blocks / 512 + !!(hd_blocks % 512);
lsb_to_buf(&wpt, (int) hd_blocks, 32, 0);
(*gpt_cursor)++;
return ISO_SUCCESS;
}
/*
* @param flag bit0= make own random MBR Id from current time
*/
int make_isolinux_mbr(int32_t *img_blocks, uint32_t boot_lba,
uint32_t mbr_id, int head_count, int sector_count,
int make_isolinux_mbr(int32_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;
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;
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;
ret = assess_isohybrid_gpt_apm(t, &gpt_count, gpt_idx, &apm_count, 0);
if (ret < 0)
return ret;
/* The rest of APM has already been written by iso_write_apm().
But the isohybrid APM head differs from the hfsplus_writer APM head.
*/
ret = insert_apm_head(buf, apm_count);
if (ret < 0)
return ret;
/* Padding of image_size to a multiple of sector_count*head_count
happens already at compute time and is implemented by
an appropriate increase of Ecma119Image->tail_blocks.
@ -422,10 +616,21 @@ int make_isolinux_mbr(int32_t *img_blocks, uint32_t boot_lba,
/* # Offset 446
*/
gpt_cursor= 0;
for (part = 1 ; part <= 4; part++) {
if ((int) part != part_number) {
/* if this_partition != partition_number: write 16 zero bytes */
/* if this_partition != partition_number: write 16 zero bytes
(this is now overriden by the eventual desire to announce
EFI and HFS boot images.)
*/
memset(wpt, 0, 16);
if (gpt_cursor < gpt_count) {
ret = gpt_images_as_mbr_partitions(t, wpt, gpt_idx,
&gpt_cursor);
if (ret < 0)
return ret;
}
wpt+= 16;
continue;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009 Thomas Schmitt
* Copyright (c) 2009 - 2013 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -527,18 +527,25 @@ int checksum_copy_old_nodes(Ecma119Image *target, IsoNode *node, int flag)
if (md5_pt == NULL)
return 0;
ret = iso_node_lookup_attr(node, "isofs.cx", &value_length,
&value, 0);
if (ret == 1 && value_length == 4) {
for (i = 0; i < 4; i++)
idx = (idx << 8) | ((unsigned char *) value)[i];
if (idx > 0 && idx <= target->checksum_idx_counter) {
memcpy(target->checksum_buffer + 16 * idx, md5_pt, 16);
if (!target->will_cancel) {
ret = iso_node_lookup_attr(node, "isofs.cx", &value_length,
&value, 0);
if (ret == 1 && value_length == 4) {
for (i = 0; i < 4; i++)
idx = (idx << 8) | ((unsigned char *) value)[i];
if (idx > 0 && idx <= target->checksum_idx_counter) {
memcpy(target->checksum_buffer + 16 * idx, md5_pt, 16);
}
}
if (value != NULL)
free(value);
/* ts B30114 : It is unclear why these are removed here.
At least with the opts->will_cancel runs,
this is not appropriate.
*/
iso_node_remove_xinfo(node, checksum_md5_xinfo_func);
}
if (value != NULL)
free(value);
iso_node_remove_xinfo(node, checksum_md5_xinfo_func);
iso_node_remove_xinfo(node, checksum_cx_xinfo_func);
}
} else if (node->type == LIBISO_DIR) {

View File

@ -139,6 +139,7 @@ int iso_node_xinfo_dispose_cloners(int flag)
next = assoc->next;
free((char *) assoc);
}
iso_xinfo_cloner_list= NULL;
return(1);
}
@ -215,6 +216,10 @@ LIBJTE_MISCONFIGURATION_ = 0;
iso_px_ino_xinfo_cloner, 0);
if (ret < 0)
return ret;
ret = iso_node_xinfo_make_clonable(iso_hfsplus_xinfo_func,
iso_hfsplus_xinfo_cloner, 0);
if (ret < 0)
return ret;
return 1;
}
@ -340,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:
@ -356,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:
@ -447,7 +452,7 @@ const char *iso_error_to_msg(int errcode)
case ISO_BAD_PARTITION_FILE:
return "Cannot open data file for appended partition";
case ISO_NON_MBR_SYS_AREA:
return "May not combine appended partition with non-MBR system area";
return "May not combine MBR partition with non-MBR system area";
case ISO_DISPLACE_ROLLOVER:
return "Displacement offset leads outside 32 bit range";
case ISO_NAME_NEEDS_TRANSL:
@ -468,6 +473,36 @@ const char *iso_error_to_msg(int errcode)
return "Attribute name cannot be represented";
case ISO_AAIP_ACL_MULT_OBJ:
return "ACL text contains multiple entries of user::, group::, other::";
case ISO_SECT_SCATTERED:
return "File sections do not form consecutive array of blocks";
case ISO_BOOT_TOO_MANY_APM:
return "Too many Apple Partition Map entries requested";
case ISO_BOOT_APM_OVERLAP:
return "Overlapping Apple Partition Map entries requested";
case ISO_BOOT_TOO_MANY_GPT:
return "Too many GPT entries requested";
case ISO_BOOT_GPT_OVERLAP:
return "Overlapping GPT entries requested";
case ISO_BOOT_TOO_MANY_MBR:
return "Too many MBR partition entries requested";
case ISO_BOOT_MBR_OVERLAP:
return "Overlapping MBR partition entries requested";
case ISO_BOOT_MBR_COLLISION:
return "Attempt to use an MBR partition entry twice";
case ISO_BOOT_NO_EFI_ELTO:
return "No suitable El Torito EFI boot image for exposure as GPT partition";
case ISO_BOOT_HFSP_BAD_BSIZE:
return "Not a supported HFS+ or APM block size";
case ISO_BOOT_APM_GPT_BSIZE:
return "APM block size prevents coexistence with GPT";
case ISO_HFSP_NO_MANGLE:
return "Name collision in HFS+, mangling not possible";
case ISO_DEAD_SYMLINK:
return "Symbolic link cannot be resolved";
case ISO_DEEP_SYMLINK:
return "Too many chained symbolic links";
case ISO_BAD_ISO_FILETYPE:
return "Unrecognized file type in ISO image";
default:
return "Unknown error";
}

View File

@ -55,6 +55,8 @@ void iso_node_ref(IsoNode *node)
*/
void iso_node_unref(IsoNode *node)
{
if (node == NULL)
return;
if (--node->refcount == 0) {
switch (node->type) {
case LIBISO_DIR:
@ -1725,6 +1727,7 @@ int attr_enlarge_list(char ***names, size_t **value_lengths, char ***values,
bit2= delete the given names rather than overwrite
their content
bit4= do not overwrite value of empty name
bit5= do not overwrite isofs attributes
bit15= release memory and return 1
*/
static
@ -1773,6 +1776,8 @@ int iso_node_merge_xattr(IsoNode *node, size_t num_attrs, char **names,
continue;
if (names[i][0] == 0 && (flag & 16))
continue;
if ((flag & 32) && strncmp(names[i], "isofs.", 6) == 0)
continue;
for (j = 0; j < *m_num_attrs; j++) {
if ((*m_names)[j] == NULL)
continue;
@ -1818,6 +1823,8 @@ int iso_node_merge_xattr(IsoNode *node, size_t num_attrs, char **names,
continue;
if (names[i][0] == 0 && (flag & 16))
continue;
if ((flag & 32) && strncmp(names[i], "isofs.", 6) == 0)
continue;
for (j = 0; j < *m_num_attrs; j++) {
if ((*m_names)[j] == NULL)
continue;
@ -1868,13 +1875,13 @@ int iso_node_set_attrs(IsoNode *node, size_t num_attrs, char **names,
for (i = 0; i < num_attrs; i++)
if (strncmp(names[i], "user.", 5) != 0 && names[i][0] != 0)
return ISO_AAIP_NON_USER_NAME;
if ((flag & (2 | 4)) || !(flag & 8)) {
if ((flag & (2 | 4 | 16)) || !(flag & 8)) {
/* Merge old and new lists */
ret = iso_node_merge_xattr(
node, num_attrs, names, value_lengths, values,
&m_num, &m_names, &m_value_lengths, &m_values,
(flag & 4) | (!(flag & 2)) | ((!(flag & 1)) << 4));
(flag & 4) | (!(flag & 2)) | ((!(flag & 1)) << 4) |
((flag & 16) << 1));
if (ret < 0)
goto ex;
num_attrs = m_num;

View File

@ -1246,17 +1246,11 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t used_up,
/* we need to add a RE entry */
su_size += 4;
}
#ifdef Libisofs_with_rr_reloc_diR
} else if(ecma119_is_dedicated_reloc_dir(t, n) &&
(t->rr_reloc_flags & 1)) {
/* The dedicated relocation directory shall be marked by RE */
su_size += 4;
}
#endif /* Libisofs_with_rr_reloc_diR */
} else if (n->type == ECMA119_SPECIAL) {
if (S_ISBLK(n->node->mode) || S_ISCHR(n->node->mode)) {
/* block or char device, we need a PN entry */
@ -1442,18 +1436,12 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
goto add_susp_cleanup;
}
}
#ifdef Libisofs_with_rr_reloc_diR
} else if(ecma119_is_dedicated_reloc_dir(t, n) &&
(t->rr_reloc_flags & 1)) {
/* The dedicated relocation directory shall be marked by RE */
ret = rrip_add_RE(t, node, info);
if (ret < 0)
goto add_susp_cleanup;
#endif /* Libisofs_with_rr_reloc_diR */
}
} else if (n->type == ECMA119_SPECIAL) {
if (S_ISBLK(n->node->mode) || S_ISCHR(n->node->mode)) {

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2008 Vreixo Formoso
* Copyright (c) 2012 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,4 +64,219 @@ int iso_read_mipsel_elf(Ecma119Image *t, int flag);
*/
int iso_compute_append_partitions(Ecma119Image *t, int flag);
/* The parameter struct for production of a single MBR partition entry.
See also the description of MBR in doc/boot_sectors.txt.
No sorting by start sector and gap filling is done before the System Area
gets written. But the entries may get assigned to a desired slot number
in the table.
Requested entries with block_count == 0 get expanded to the start of
the next requested entry resp. to image end, if no entry follows.
start_block of a follwing entry must be at least a high as the sum of
start_block and block_count of the previous entry.
Empty requested entries will be represented as 16 bytes of 0.
*/
struct iso_mbr_partition_request {
/* 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.
*/
uint64_t block_count;
/* Partition type */
uint8_t type_byte;
/* 0x80 = bootable */
uint8_t status_byte;
/* If >= 1 && <= 4 : The partition slot number in MBR.
If more than one partition desires the same slot, then an error
ISO_BOOT_MBR_COLLISION occurs at registration time.
Use iso_mbr_entry_slot_is_free() to detect this in advance.
If desired_slot is 0, then the partition entry is put into the
lowest MBR slot that is not occupied by an entry with desired_slot > 0
or by an entry that was registered before this entry.
*/
int desired_slot;
};
/* Copies the content of req and registers it in t.mbr_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_mbr_entry(Ecma119Image *t,
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,
uint64_t start_block, uint64_t block_count,
uint8_t type_byte, uint8_t status_byte,
int desired_slot);
/* Peek in advance whether a desired slot number is already occupied by a
registered MBR entry.
Parameter slot may be between 0 and 4. 0 always returns "free".
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);
/* 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 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.
If no such entry is requested, then it will be prepended automatically
with name "Apple" and type "Apple_partition_map".
The requested entries will get sorted and gaps will be filled by more
entries.
*/
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;
/* All 32 bytes get copied to the system area.
Take care to pad up short strings by 0.
*/
uint8_t name[32];
uint8_t type[32];
};
/* Copies the content of req and registers it in t.apm_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_apm_entry(Ecma119Image *t,
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);
/* These two pseudo-random generators produce byte strings which will
surely not duplicate in the first 256 calls. If more calls are necessary
in the same process, then one must wait until the output of
gettimeofday(2) changes.
It is advised to obtain them as late as possible, so that Ecma119Image *t
can distinguish itself from other image production setups which might be
run on other machines with the same process number at the same time.
*/
/* Produces a weakly random variation of a hardcoded real random uuid
*/
void iso_random_uuid(Ecma119Image *t, uint8_t uuid[16]);
/* The parameter struct for production of a single GPT entry.
See also the partial GPT description in doc/boot_sectors.txt.
The list of entries is stored in Ecma119Image.gpt_req.
The GPT header block at byte 0x200 will get produced automatically.
The requested entries will get sorted and gaps will be filled by more
entries. Overlapping partitions are allowed only if
(Ecma119Image.gpt_req_flags & 1).
The block_count will be truncated to the image size before the GPT backup.
The GPT entries will be stored after the Apple Partition Map, if such
gets generated too. Both partition descriptions must fit into the 32 KiB
of the ISO 9660 System Area.
GPT can be combined with APM only if (Ecma119Image.apm_block_size > 512).
Otherwise, block 1 of APM and GPT header block would collide.
So Ecma119Image.apm_block_size is set automatically to 2048 if at least
one GPT entry is requested. (One could try 1024 ...).
*/
struct iso_gpt_partition_request {
/* Always given in blocks of 2 KiB.
Written to the ISO image in blocks of 512.
*/
uint32_t start_block;
uint32_t block_count;
/* The registered GUID which defines the partition type */
uint8_t type_guid[16];
/* An individual GUID which shall be unique to the partition.
If the caller submits 0...0 then a (weak) random uuid will be generated.
*/
uint8_t partition_guid[16];
/* bit0= "System Partition" Do not alter,
bit2= Legacy BIOS bootable (MBR partition type 0x80)
bit60= read-only
*/
uint64_t flags;
/* Fill with text encoded as UTF-16LE.
All 72 bytes get copied to the system area.
Take care to pad up short strings by 0.
*/
uint8_t name[72];
};
/* 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,
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,
uint8_t type_guid[16], uint8_t partition_guid[16],
uint64_t flags, uint8_t name[72]);
/* Internal helper that will be used by system_area.c and make_isohybrid_mbr.c
*/
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);
/* Creates the Partition Prepend writer.
*/
int partprepend_writer_create(Ecma119Image *target);
/* Creates the GPT backup tail writer.
*/
int gpt_tail_writer_create(Ecma119Image *target);
/* Only for up to 36 characters ISO-8859-1 (or ASCII) input */
void iso_ascii_utf_16le(uint8_t gap_name[72]);
/* Parameters of MBR patching for GRUB2
Might later become variables in Ecma119Image
*/
#define Libisofs_grub2_mbr_patch_poS 0x1b0
#define Libisofs_grub2_mbr_patch_offsT 4
/* Parameters of SUN Disk Label patching for GRUB2
See API iso_image_set_sparc_core().
*/
#define Libisofs_grub2_sparc_patch_adr_poS 0x228
#define Libisofs_grub2_sparc_patch_size_poS 0x230
#endif /* SYSTEM_AREA_H_ */

View File

@ -803,6 +803,8 @@ int iso_add_dir_src_rec(IsoImage *image, IsoDir *parent, IsoFileSource *dir)
ret = iso_file_source_lstat(file, &info);
}
if (ret < 0) {
ret = iso_msg_submit(image->id, ISO_FILE_CANT_ADD, ret,
"Error when adding file %s", path);
goto dir_rec_continue;
}
@ -1196,3 +1198,84 @@ int iso_tree_clone(IsoNode *node,
return ret;
}
int iso_tree_resolve_symlink(IsoImage *img, IsoSymlink *sym, IsoNode **res,
int *depth, int flag)
{
IsoDir *cur_dir = NULL;
IsoNode *n, *resolved_node;
char *dest, *dest_start, *dest_end;
int ret = 0;
unsigned int comp_len, dest_len;
dest = sym->dest;
dest_len = strlen(dest);
if (dest[0] == '/') {
/* ??? How to resolve absolute links without knowing the
path of the future mount point ?
??? Would it be better to throw error ?
I can only assume that it gets mounted at / during some stage
of booting.
*/;
cur_dir = img->root;
dest_end = dest;
} else {
cur_dir = sym->node.parent;
if (cur_dir == NULL)
cur_dir = img->root;
dest_end = dest - 1;
}
while (dest_end < dest + dest_len) {
dest_start = dest_end + 1;
dest_end = strchr(dest_start, '/');
if (dest_end == NULL)
dest_end = dest_start + strlen(dest_start);
comp_len = dest_end - dest_start;
if (comp_len == 0 || (comp_len == 1 && dest_start[0] == '.'))
continue;
if (comp_len == 2 && dest_start[0] == '.' && dest_start[1] == '.') {
cur_dir = cur_dir->node.parent;
if (cur_dir == NULL) /* link shoots over root */
return ISO_DEAD_SYMLINK;
continue;
}
/* Search node in cur_dir */
for (n = cur_dir->children; n != NULL; n = n->next)
if (strncmp(dest_start, n->name, comp_len) == 0 &&
strlen(n->name) == comp_len)
break;
if (n == NULL)
return ISO_DEAD_SYMLINK;
if (n->type == LIBISO_DIR) {
cur_dir = (IsoDir *) n;
} else if (n->type == LIBISO_SYMLINK) {
if (*depth >= LIBISO_MAX_LINK_DEPTH)
return ISO_DEEP_SYMLINK;
(*depth)++;
ret = iso_tree_resolve_symlink(img, (IsoSymlink *) n,
&resolved_node, depth, 0);
if (ret < 0)
return ret;
if (resolved_node->type != LIBISO_DIR) {
n = resolved_node;
goto leaf_type;
}
cur_dir = (IsoDir *) resolved_node;
} else {
leaf_type:;
if (dest_end < dest + dest_len) /* attempt to dive into file */
return ISO_DEAD_SYMLINK;
*res = n;
return ISO_SUCCESS;
}
}
*res = (IsoNode *) cur_dir;
return ISO_SUCCESS;
}

View File

@ -1225,12 +1225,13 @@ uint16_t *ucsdup(const uint16_t *str)
/**
* Although each character is 2 bytes, we actually compare byte-by-byte
* (thats what the spec says).
* because the words are big-endian. Comparing possibly swapped words
* would make the sorting order depend on the machine byte order.
*/
int ucscmp(const uint16_t *s1, const uint16_t *s2)
{
const char *s = (const char*)s1;
const char *t = (const char*)s2;
const uint8_t *s = (const uint8_t*)s1;
const uint8_t *t = (const uint8_t*)s2;
size_t len1 = ucslen(s1);
size_t len2 = ucslen(s2);
size_t i, len = MIN(len1, len2) * 2;
@ -1354,6 +1355,18 @@ void iso_bb(uint8_t *buf, uint32_t num, int bytes)
iso_msb(buf+bytes, num, bytes);
}
/* An alternative to iso_lsb() which advances the write pointer
*/
int iso_lsb_to_buf(char **wpt, uint32_t value, int bytes, int flag)
{
int b, bits;
bits = bytes * 8;
for (b = 0; b < bits; b += 8)
*((unsigned char *) ((*wpt)++)) = (value >> b) & 0xff;
return (1);
}
uint32_t iso_read_lsb(const uint8_t *buf, int bytes)
{
int i;
@ -2063,4 +2076,19 @@ void *iso_alloc_mem(size_t size, size_t count, int flag)
iso_msg_submit(-1, ISO_OUT_OF_MEM, 0, "Out of virtual memory");
return pt;
}
uint16_t iso_ntohs(uint16_t v)
{
return iso_read_msb((uint8_t *) &v, 2);
}
uint16_t iso_htons(uint16_t v)
{
uint16_t ret;
iso_msb((uint8_t *) &ret, (uint32_t) v, 2);
return ret;
}

View File

@ -232,6 +232,10 @@ void iso_lsb(uint8_t *buf, uint32_t num, int bytes);
void iso_msb(uint8_t *buf, uint32_t num, int bytes);
void iso_bb(uint8_t *buf, uint32_t num, int bytes);
/* An alternative to iso_lsb() which advances the write pointer
*/
int iso_lsb_to_buf(char **wpt, uint32_t value, int bytes, int flag);
uint32_t iso_read_lsb(const uint8_t *buf, int bytes);
uint32_t iso_read_msb(const uint8_t *buf, int bytes);
@ -543,6 +547,12 @@ int checksum_md5_xinfo_func(void *data, int flag);
*/
int checksum_md5_xinfo_cloner(void *old_data, void **new_data, int flag);
/* The iso_node_xinfo_cloner function which gets associated to
* iso_hfsplus_xinfo_func by iso_init() resp. iso_init_with_flag() via
* iso_node_xinfo_make_clonable()
*/
int iso_hfsplus_xinfo_cloner(void *old_data, void **new_data, int flag);
/* ------------------------------------------------------------------------- */
@ -567,4 +577,12 @@ void *iso_alloc_mem(size_t size, size_t count, int flag);
}
/* ------------------------------------------------------------------------- */
/* To avoid the need to include more system header files */
uint16_t iso_ntohs(uint16_t v);
uint16_t iso_htons(uint16_t v);
#endif /*LIBISO_UTIL_H_*/