Compare commits

...

188 Commits

Author SHA1 Message Date
b82ca42f87 Version leap to 1.3.6 2014-03-04 17:00:54 +01:00
1a8a216822 Updated changelog 2014-03-04 10:05:57 +01:00
ef528f2f0e Temporarily disabled the unfinished HP-PA PALO bootability preparations 2014-03-04 09:23:04 +01:00
bedfa914d5 Temporarily disabled the unfinished HP-PA PALO bootability preparations 2014-03-03 20:15:08 +01:00
5383ae2faa Fixed a memory fault introduced with rev 1106 2014-02-16 14:42:39 +01:00
d23462657b Installed debugging code for error ISO_RR_NAME_RESERVED 2014-02-16 14:40:28 +01:00
b41e36365d Fixed a write to array index -1 with demo/demo -tree 2014-02-16 14:31:33 +01:00
985015cea1 Making sure that PVD time strings are allocated with 17 bytes plus trailing 0 2014-02-13 16:25:15 +01:00
27d4c79d0e Silenced warnings about -Wchar-subscripts, added /usr/local for NetBSD 2014-02-11 09:28:27 +01:00
5b78efb12a Clarified the content of the PVD timestamps. 2014-02-09 13:29:50 +01:00
2c2fb7caf2 Fixed a harmless bug introduced with rev 1111. 2014-01-26 10:07:10 +01:00
d51cefb097 Adapted HP-PA boot sector code to upcomming PALO header version 5 2014-01-16 11:59:58 +01:00
7637d13e11 New API calls iso_image_set_hppa_palo() and iso_image_get_hppa_palo() 2014-01-14 09:43:28 +01:00
b9b5284f22 Beautified the collision avoiding names 2014-01-04 16:28:25 +01:00
afa65e9f2a Reduced minimum length of collision avoiding name from 8 to 7 2014-01-03 21:16:56 +01:00
5e1aaca232 Avoided unnecessary recursion with production of collision avoiding names 2014-01-03 20:53:59 +01:00
fea649835c Small fix of previous change 2014-01-03 20:00:04 +01:00
44f475a4ef Improved handling of unconvertable file names and name collsions during iso_image_import() 2014-01-03 18:29:29 +01:00
60eb7e883c Issueing warnings when Joliet file names with non-UCS-2 characters get read 2013-12-31 13:14:42 +01:00
9b4e0b611a Bug fix: Division by zero if HFS+ was combined with TOC emulation for overwritable media. 2013-12-28 16:45:29 +01:00
1be57e34ec Completed implementation of API call iso_conv_name_chars() 2013-12-28 15:36:33 +01:00
b0e68bbcaa Fixed a memory access error introduced with rev 1099 2013-12-22 19:07:28 +01:00
fa61b94ac8 Consolidated the single copies of IsoWriteOpts members in Ecma119Image
by having a copy of the whole IsoWriteOpts in Ecma119Image
2013-12-22 19:02:44 +01:00
3e3c15812b New API call iso_conv_name_chars(), provisory implementation 2013-12-19 15:41:55 +01:00
88555bd059 New API call iso_write_opts_set_joliet_utf16()
and ability to read Joliet names as UTF-16BE
2013-12-17 21:45:52 +01:00
ba47d1534c Version leap to 1.3.5 2013-12-12 14:44:22 +01:00
b7dc0f4057 Version leap to 1.3.4 2013-12-12 14:37:11 +01:00
0ab9f5f8d2 Updated changelog 2013-12-12 09:30:25 +01:00
1338f29d62 Added a comment to node.c 2013-12-12 09:25:40 +01:00
bc5e2227c8 Encoding HFS+ names in UTF-16 rather than UCS-2. 2013-11-26 12:47:43 +01:00
654ff82345 Mentioned boot image address in newer GRUB2 MBR 2013-11-18 13:22:17 +01:00
6baeae70e0 Mentioned GRUB2 Boot Info in boot_sectors.txt 2013-11-18 12:58:50 +01:00
b987972660 Updated copyright year in README 2013-09-25 13:07:38 +02:00
c78526abce Reacted on warnings of Debian buildd with clang 2013-09-16 20:52:14 +02:00
b95e1bb85c Giving sort weight 2 as default to El Torito boot images. 2013-09-07 21:37:27 +02:00
7aa2582129 Reacted on warnings of PLD Linux build log 2013-09-05 10:01:08 +02:00
3f29d70aba Preserving MD5s of files from old session until the end of the new
write run. If the write run fails, the old MD5s get restored.
2013-08-20 11:48:24 +02:00
567d3ddafb Fixed the rollover protection for checksum indice. 2013-08-17 12:49:01 +02:00
c47f85c639 Removed an obsolete sentence from docs. 2013-08-17 12:48:04 +02:00
40310b4fd7 Updated ChangeLog to new development cycle. 2013-08-07 15:53:43 +02:00
f34c274f21 Version leap to 1.3.3 2013-08-07 15:12:43 +02:00
46e96ee616 Version leap to 1.3.2 2013-08-07 15:10:10 +02:00
7e60e60e62 Updated changelog 2013-08-07 10:56:23 +02:00
d55ed2d1ca New API calls iso_image_get_app_use() and iso_image_set_app_use() 2013-08-04 12:32:31 +02:00
77c8349c56 Bug fix: iso_finish() left an invalid global pointer, which a subsequent call of iso_init() would try to dereference. 2013-07-31 09:53:43 +02:00
b1c7ed6e29 Avoided a confusing error message from iso_image_update_sizes(),
prepared macro for non-confusing error message,
and introduced flag bit0 to iso_stream_get_input_stream()
2013-06-25 14:56:29 +02:00
e886722d65 The sort weight of data files loaded from ISO image is now 2 exp 28 to 1
rather than 2 exp 31 - 1 to - 2 exp 31
2013-05-24 12:35:43 +02:00
b80b339de3 Version leap to 1.3.1 2013-05-17 19:51:39 +02:00
efbd05203d Version leap to 1.3.0 2013-05-17 19:47:58 +02:00
6ca1d76d60 Updated change log 2013-05-17 09:52:40 +02:00
e1b54056e8 Added a new source of information about CHRP to boot_sectors.txt 2013-05-01 20:28:24 +02:00
d5cd610ac7 Bug fix: The protective MBR partition for GPT started at block 0 instead of 1 2013-04-17 20:54:02 +02:00
91f5ebb376 Bug fix: GPT header CRC was computed from all 512 bytes rather than from 92. 2013-04-17 16:45:51 +02:00
ff3b439bda Changed Libisofs_grub2_sparc_patch_lba_poS to Libisofs_grub2_sparc_patch_adr_poS 2013-04-14 08:15:29 +02:00
4672c79181 Changed Libisofs_grub2_sparc_patch_lba_poS to Libisofs_grub2_sparc_patch_adr_poS 2013-04-14 08:14:27 +02:00
83cb07b23c New API calls iso_image_set_sparc_core() and iso_image_get_sparc_core(). 2013-04-13 22:17:26 +02:00
439a14da1d Bug fix: Reserved and unused fields of APM entries were not zeroed. 2013-04-13 12:11:26 +02:00
d66eef42f6 Corrected Libisofs_grub2_mbr_patch_offsT from 3 to 4 2013-04-13 09:25:42 +02:00
337bade549 New option bits with el_torito_set_isolinux_options() and
iso_write_opts_set_system_area() to control GRUB2 patching of
boot image and MBR
2013-04-13 08:38:52 +02:00
eb6503a8ad * Bug fix: Unspecified Expiration Time and Effective Time of ISO volume was
represented by 0-bytes rather than ASCII '0' digits.
2013-04-10 13:55:20 +02:00
1a2e1c767e Now repeating Rock Ridge warnings at most once per loaded image. 2013-04-10 13:32:53 +02:00
858c5479c8 Changed some warning texts from "RR" to "Rock Ridge" 2013-04-10 13:32:09 +02:00
d36b3d04a8 Temporarily hosting a test bed for syslinux/core/fs/susp_rr.c in libisofs/fs_image.c 2013-03-31 13:37:39 +02:00
da41eb8c6e Version leap to 1.2.9 2013-03-18 21:54:59 +01:00
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
50 changed files with 11208 additions and 1298 deletions

View File

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

View File

@ -1,4 +1,81 @@
bzr branch lp:libisofs/for-libisoburn (to become libisofs-1.2.2.tar.gz)
libisofs-1.3.6.tar.gz Tue Mar 04 2014
===============================================================================
* Bug fix: Division by zero if HFS+ was combined with TOC emulation for
overwritable media.
* New API call iso_write_opts_set_joliet_utf16() and ability to read Joliet
names as UTF-16BE
* New API call iso_conv_name_chars()
libisofs-1.3.4.tar.gz Thu Dec 12 2013
===============================================================================
* Giving sort weight 2 as default to El Torito boot images
* Encoding HFS+ names in UTF-16 rather than UCS-2.
libisofs-1.3.2.tar.gz Wed Aug 07 2013
===============================================================================
* Bug fix: iso_finish() left an invalid global pointer, which a subsequent
call of iso_init() would try to dereference.
* The sort weight of data files loaded from ISO image is now 2 exp 28 to 1
rather than 2 exp 31 - 1 to - 2 exp 31
libisofs-1.3.0.tar.gz Fri May 17 2013
===============================================================================
* Bug fix: GPT header CRC was computed from all 512 bytes rather than from 92.
* Bug fix: Unspecified Expiration Time and Effective Time of ISO volume was
represented by 0-bytes rather than ASCII '0' digits.
* Bug fix: Reserved and unused fields of APM entries were not zeroed.
* Bug fix: The protective MBR partition for GPT started at block 0 instead of 1.
* New option bits with el_torito_set_isolinux_options() and
iso_write_opts_set_system_area() to control GRUB2 patching of
boot image and MBR.
* New API calls iso_image_set_sparc_core() and iso_image_get_sparc_core().
libisofs-1.2.8.tar.gz Mon Mar 18 2013
===============================================================================
* 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 +84,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 - 2013 Vreixo Formoso,
Mario Danic,
Vladimir Serbinenko,
Thomas Schmitt
libisofs is part of the libburnia project (libburnia-project.org)
------------------------------------------------------------------------------

View File

@ -1,7 +1,7 @@
AC_DEFUN([LIBBURNIA_SET_FLAGS],
[
case $target_os in
freebsd*)
freebsd* | netbsd*)
LDFLAGS="$LDFLAGS -L/usr/local/lib"
CPPFLAGS="$CPPFLAGS -I/usr/local/include"
;;

View File

@ -1,4 +1,4 @@
AC_INIT([libisofs], [1.2.2], [http://libburnia-project.org])
AC_INIT([libisofs], [1.3.6], [http://libburnia-project.org])
AC_PREREQ([2.50])
dnl AC_CONFIG_HEADER([config.h])
@ -40,8 +40,8 @@ dnl
dnl If LIBISOFS_*_VERSION changes, be sure to change AC_INIT above to match.
dnl
LIBISOFS_MAJOR_VERSION=1
LIBISOFS_MINOR_VERSION=2
LIBISOFS_MICRO_VERSION=2
LIBISOFS_MINOR_VERSION=3
LIBISOFS_MICRO_VERSION=6
LIBISOFS_VERSION=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION.$LIBISOFS_MICRO_VERSION
AC_SUBST(LIBISOFS_MAJOR_VERSION)
@ -51,10 +51,10 @@ AC_SUBST(LIBISOFS_VERSION)
dnl Libtool versioning
LT_RELEASE=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION
# 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
# 2014.03.04 development jump has not yet happened
# SONAME = 78 - 72 = 6 . Library name = libisofs.6.72.0
LT_CURRENT=78
LT_AGE=72
LT_REVISION=0
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
@ -140,7 +140,7 @@ if test x$enable_debug != xyes; then
CFLAGS="-DNDEBUG $CFLAGS"
else
if test x$GCC = xyes; then
CFLAGS="-g -pedantic -Wall -Wextra -Wno-unused-parameter $CFLAGS"
CFLAGS="-g -pedantic -Wall -Wextra -Wno-unused-parameter -Wno-char-subscripts $CFLAGS"
fi
CFLAGS="-DDEBUG $CFLAGS"
fi

View File

@ -95,7 +95,8 @@ tree_print_dir(IsoDir *dir, int level)
sp[i+1] = ' ';
}
sp[level * 2-1] = '-';
if (level > 0)
sp[level * 2 - 1] = '-';
sp[level * 2] = '\0';
iso_dir_get_children(dir, &iter);

File diff suppressed because it is too large Load Diff

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

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

View File

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

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

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2011 Thomas Schmitt
* Copyright (c) 2009 - 2014 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -96,7 +96,7 @@ int default_create_file(IsoNodeBuilder *builder, IsoImage *image,
static
int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
IsoFileSource *src, IsoNode **node)
IsoFileSource *src, char *in_name, IsoNode **node)
{
int ret;
struct stat info;
@ -122,7 +122,15 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
goto ex;
}
name = iso_file_source_get_name(src);
if (in_name == NULL) {
name = iso_file_source_get_name(src);
} else {
name = strdup(in_name);
if (name == NULL) {
ret = ISO_OUT_OF_MEM; goto ex;
}
}
if (strlen(name) > LIBISOFS_NODE_NAME_MAX)
name[LIBISOFS_NODE_NAME_MAX] = 0;
fs = iso_file_source_get_filesystem(src);

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2014 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -47,6 +48,7 @@ struct Iso_Node_Builder
* Create a new IsoNode from a IsoFileSource. The type of the node to be
* created is determined from the type of the file source. Name,
* permissions and other attributes are taken from source file.
* But name may be overridden by parameter name if it is not NULL.
*
* Note that the src is never unref, so you need to free it.
*
@ -54,7 +56,7 @@ struct Iso_Node_Builder
* 1 on success, < 0 on error
*/
int (*create_node)(IsoNodeBuilder *builder, IsoImage *image,
IsoFileSource *src, IsoNode **node);
IsoFileSource *src, char *name, IsoNode **node);
/**
* Free implementation specific data. Should never be called by user.

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2012 Thomas Schmitt
* Copyright (c) 2009 - 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,29 @@
#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
/* How many warnings to issue about writing Joliet names which cannot be
properly represented in UCS-2 and thus had to be defaultet to '_'.
*/
#define ISO_JOLIET_UCS2_WARN_MAX 3
/**
* Holds the options for the image generation.
*/
@ -77,12 +100,14 @@ struct iso_write_opts {
int will_cancel;
int level; /**< ISO level to write at. (ECMA-119, 10) */
int iso_level; /**< ISO level to write at. (ECMA-119, 10) */
/** Which extensions to support. */
unsigned int rockridge :1;
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 */
@ -173,6 +198,11 @@ struct iso_write_opts {
*/
unsigned int joliet_long_names :1;
/**
* Use UTF-16BE rather than its subset UCS-2
*/
unsigned int joliet_utf16 :1;
/**
* Write Rock Ridge info as of specification RRIP-1.10 rather than
* RRIP-1.12: signature "RRIP_1991A" rather than "IEEE_1282",
@ -401,6 +431,7 @@ struct iso_write_opts {
* See ecma119_image : System Area related information
*/
char *system_area_data;
int system_area_size;
int system_area_options;
/* User settable PVD time stamps */
@ -433,6 +464,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 +483,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;
@ -458,68 +514,19 @@ struct ecma119_image
IsoImage *image;
Ecma119Node *root;
int will_cancel :1;
IsoWriteOpts *opts;
unsigned int iso_level :2;
/* extensions */
unsigned int rockridge :1;
unsigned int joliet :1;
/** Whether El Torito data will be produced */
unsigned int eltorito :1;
unsigned int iso1999 :1;
unsigned int hardlinks:1; /* see iso_write_opts_set_hardlinks() */
unsigned int aaip :1; /* see iso_write_opts_set_aaip() */
/* allways write timestamps in GMT */
unsigned int always_gmt :1;
/* relaxed constraints */
unsigned int allow_dir_id_ext :1;
unsigned int omit_version_numbers :2;
unsigned int allow_deep_paths :1;
unsigned int allow_longer_paths :1;
unsigned int max_37_char_filenames :1;
unsigned int no_force_dots :2;
unsigned int allow_lowercase :1;
unsigned int allow_full_ascii :1;
unsigned int allow_7bit_ascii :1;
unsigned int relaxed_vol_atts : 1;
/** Allow paths on Joliet tree to be larger than 240 bytes */
unsigned int joliet_longer_paths :1;
/** Allow Joliet names up to 103 characters rather than 64 */
unsigned int joliet_long_names :1;
/** Write old fashioned RRIP-1.10 rather than RRIP-1.12 */
unsigned int rrip_version_1_10 :1;
/** Write field PX with file serial number even with RRIP-1.10 */
unsigned int rrip_1_10_px_ino :1;
/* Write AAIP as extension according to SUSP 1.10 rather than SUSP 1.12. */
unsigned int aaip_susp_1_10 :1;
/* Store in ECMA-119, Joliet, ISO 9660:1999 timestamp the mtime of source
bit0= ECMA-119, bit1= Joliet, bit2= ISO 9660:1999.
/* The ECMA-119 directory node where to store Rock Ridge relocated
directories. (Path is in IsoWriteOpts.rr_reloc_dir)
*/
unsigned int dir_rec_mtime :3;
/* The ECMA-119 directory where to store Rock Ridge relocated directories.
*/
char *rr_reloc_dir; /* IsoNode name in root directory */
int rr_reloc_flags;
Ecma119Node *rr_reloc_node; /* Directory node in ecma119_image */
unsigned int md5_session_checksum :1;
unsigned int md5_file_checksums :2;
/*
* Mode replace. If one of these flags is set, the correspodent values are
* replaced with values below.
* replaced with values below. Both get computed from IsoWriteOpts.
*/
unsigned int replace_uid :1;
unsigned int replace_gid :1;
@ -527,25 +534,17 @@ struct ecma119_image
unsigned int replace_dir_mode :1;
unsigned int replace_timestamps :1;
/* Mode replacement values. */
uid_t uid;
gid_t gid;
mode_t file_mode;
mode_t dir_mode;
time_t timestamp;
unsigned int old_empty :1;
unsigned int untranslated_name_len;
/**
* if sort files or not. Sorting is based of the weight of each file
*/
int sort_files;
/* Effective charsets */
char *input_charset;
char *output_charset;
unsigned int appendable : 1;
uint32_t ms_block; /**< start block for a ms image */
time_t now; /**< Time at which writing began. */
/** Total size of the output. This only includes the current volume. */
@ -591,6 +590,30 @@ struct ecma119_image
uint32_t joliet_path_table_size;
uint32_t joliet_l_path_table_pos;
uint32_t joliet_m_path_table_pos;
size_t joliet_ucs2_failures;
/*
* HFS+ related information
* (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 +662,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;
@ -680,14 +712,6 @@ struct ecma119_image
Use only underneath ecma119_image_new()
and if not NULL*/
/* ??? Is there a reason why we copy lots of items from IsoWriteOpts
rather than taking ownership of the IsoWriteOpts object which
is submitted with ecma119_image_new() ?
*/
char scdbackup_tag_parm[100];
char *scdbackup_tag_written;
/* Buffer for communication between burn_source and writer thread */
IsoRingBuffer *buffer;
@ -696,20 +720,7 @@ struct ecma119_image
int wthread_is_running;
pthread_attr_t th_attr;
/* User settable PVD time stamps */
time_t vol_creation_time;
time_t vol_modification_time;
time_t vol_expiration_time;
time_t vol_effective_time;
/* To eventually override vol_creation_time and vol_modification_time
* by unconverted string with timezone 0
*/
char vol_uuid[17];
/* The number of unclaimed 2K blocks before
start of partition 1 as of the MBR in system area. */
uint32_t partition_offset;
/* Partition table parameter: 1 to 63, 0= disabled/default */
/* Effective partition table parameter: 1 to 63, 0= disabled/default */
int partition_secs_per_head;
/* 1 to 255, 0= disabled/default */
int partition_heads_per_cyl;
@ -730,26 +741,92 @@ struct ecma119_image
uint32_t j_part_l_path_table_pos;
uint32_t j_part_m_path_table_pos;
#ifdef Libisofs_with_libjtE
struct libjte_env *libjte_handle;
#endif /* Libisofs_with_libjtE */
uint32_t tail_blocks;
/* Memorized ELF parameters from MIPS Little Endian boot file */
uint32_t mipsel_e_entry;
uint32_t mipsel_p_offset;
uint32_t mipsel_p_vaddr;
uint32_t mipsel_p_filesz;
char *appended_partitions[ISO_MAX_PARTITIONS];
uint8_t appended_part_types[ISO_MAX_PARTITIONS];
/* A data file of which the position and size shall be written after
a SUN Disk Label.
*/
IsoFileSrc *sparc_core_src;
/* Counted in blocks of 2048 */
uint32_t appended_part_prepad[ISO_MAX_PARTITIONS];
uint32_t appended_part_start[ISO_MAX_PARTITIONS];
uint32_t appended_part_size[ISO_MAX_PARTITIONS];
char ascii_disc_label[ISO_DISC_LABEL_SIZE];
/* 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.
*/
/* Allocation block size of HFS+
May be defined to 512 or 2048 before hfsplus_writer_create().
*/
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;
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;
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;
};
@ -881,5 +958,14 @@ 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);
void issue_ucs2_warning_summary(size_t failures);
#endif /*LIBISO_ECMA119_H_*/

View File

@ -29,52 +29,57 @@
#include <string.h>
#include <stdio.h>
static
int get_iso_name(Ecma119Image *img, IsoNode *iso, char **name)
/* @param flag bit0= Do not issue error messages
*/
int iso_get_ecma119_name(IsoWriteOpts *opts, char *input_charset, int imgid,
char *node_name, enum IsoNodeType node_type,
char **name, int flag)
{
int ret, relaxed, free_ascii_name= 0, force_dots = 0;
int ret, relaxed, free_ascii_name = 0, force_dots = 0;
char *ascii_name;
char *isoname= NULL;
char *isoname = NULL;
if (iso->name == NULL) {
if (node_name == NULL) {
/* it is not necessarily an error, it can be the root */
return ISO_SUCCESS;
}
if (img->untranslated_name_len > 0) {
ascii_name = iso->name;
if (opts->untranslated_name_len > 0) {
ascii_name = node_name;
ret = 1;
} else {
ret = str2ascii(img->input_charset, iso->name, &ascii_name);
ret = str2ascii(input_charset, node_name, &ascii_name);
free_ascii_name = 1;
}
if (ret < 0) {
iso_msg_submit(img->image->id, ret, 0,
"Cannot convert name '%s' to ASCII", iso->name);
if (!(flag & 512))
iso_msg_submit(imgid, ret, 0,
"Cannot convert name '%s' to ASCII", node_name);
return ret;
}
if (img->allow_full_ascii) {
if (opts->allow_full_ascii) {
relaxed = 2;
} else {
relaxed = (int)img->allow_lowercase;
relaxed = (int)opts->allow_lowercase;
}
if (img->allow_7bit_ascii)
if (opts->allow_7bit_ascii)
relaxed |= 4;
if (iso->type == LIBISO_DIR && !(img->allow_dir_id_ext)) {
if (img->untranslated_name_len > 0) {
if (strlen(ascii_name) > img->untranslated_name_len) {
if (node_type == LIBISO_DIR && !(opts->allow_dir_id_ext)) {
if (opts->untranslated_name_len > 0) {
if (strlen(ascii_name) > opts->untranslated_name_len) {
needs_transl:;
iso_msg_submit(img->image->id, ISO_NAME_NEEDS_TRANSL, 0,
if (!(flag & 512))
iso_msg_submit(imgid, ISO_NAME_NEEDS_TRANSL, 0,
"File name too long (%d > %d) for untranslated recording: '%s'",
strlen(ascii_name), img->untranslated_name_len,
ascii_name);
strlen(ascii_name), opts->untranslated_name_len,
ascii_name);
return ISO_NAME_NEEDS_TRANSL;
}
isoname = strdup(ascii_name);
} else if (img->max_37_char_filenames) {
} else if (opts->max_37_char_filenames) {
isoname = iso_r_dirid(ascii_name, 37, relaxed);
} else if (img->iso_level == 1) {
} else if (opts->iso_level == 1) {
#ifdef Libisofs_old_ecma119_nameS
@ -99,14 +104,15 @@ needs_transl:;
}
}
} else {
force_dots = !((img->no_force_dots & 1) || iso->type == LIBISO_DIR);
if (img->untranslated_name_len > 0) {
if (strlen(ascii_name) > img->untranslated_name_len)
force_dots = !((opts->no_force_dots & 1) ||
node_type == LIBISO_DIR);
if (opts->untranslated_name_len > 0) {
if (strlen(ascii_name) > opts->untranslated_name_len)
goto needs_transl;
isoname = strdup(ascii_name);
} else if (img->max_37_char_filenames) {
} else if (opts->max_37_char_filenames) {
isoname = iso_r_fileid(ascii_name, 36, relaxed, force_dots);
} else if (img->iso_level == 1) {
} else if (opts->iso_level == 1) {
#ifdef Libisofs_old_ecma119_nameS
@ -151,18 +157,22 @@ needs_transl:;
}
}
static
int get_iso_name(Ecma119Image *img, IsoNode *iso, char **name)
{
int ret;
ret = iso_get_ecma119_name(img->opts, img->input_charset, img->image->id,
iso->name, iso->type, name, 0);
return ret;
}
int ecma119_is_dedicated_reloc_dir(Ecma119Image *img, Ecma119Node *node)
{
#ifdef Libisofs_with_rr_reloc_diR
if (img->rr_reloc_node == node &&
node != img->root && node != img->partition_root &&
(img->rr_reloc_flags & 2))
(img->opts->rr_reloc_flags & 2))
return 1;
#endif /* Libisofs_with_rr_reloc_diR */
return 0;
}
@ -226,7 +236,7 @@ int create_file_src(Ecma119Image *img, IsoFile *iso, IsoFileSrc **src)
off_t size;
size = iso_stream_get_size(iso->stream);
if (size > (off_t)MAX_ISO_FILE_SECTION_SIZE && img->iso_level != 3) {
if (size > (off_t)MAX_ISO_FILE_SECTION_SIZE && img->opts->iso_level != 3) {
char *ipath = iso_tree_get_node_path(ISO_NODE(iso));
ret = iso_msg_submit(img->image->id, ISO_FILE_TOO_BIG, 0,
"File \"%s\" can't be added to image because "
@ -367,6 +377,7 @@ int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree,
int max_path;
char *iso_name= NULL, *ipath = NULL;
IsoFileSrc *src = NULL;
IsoWriteOpts *opts = image->opts;
if (image == NULL || iso == NULL || tree == NULL) {
return ISO_NULL_POINTER;
@ -391,16 +402,16 @@ int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree,
goto ex;
}
max_path = pathlen + 1 + (iso_name ? strlen(iso_name) : 0);
if (!image->rockridge) {
if (!opts->rockridge) {
if ((iso->type == LIBISO_DIR && depth > 8) &&
!image->allow_deep_paths) {
ipath = iso_tree_get_node_path(iso);
!opts->allow_deep_paths) {
ipath = iso_tree_get_node_path(iso);
ret = iso_msg_submit(image->image->id, ISO_FILE_IMGPATH_WRONG,
0, "File \"%s\" can't be added, "
"because directory depth "
"is greater than 8.", ipath);
goto ex;
} else if (max_path > 255 && !image->allow_longer_paths) {
} else if (max_path > 255 && !opts->allow_longer_paths) {
ipath = iso_tree_get_node_path(iso);
ret = iso_msg_submit(image->image->id, ISO_FILE_IMGPATH_WRONG,
0, "File \"%s\" can't be added, "
@ -424,7 +435,7 @@ int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree,
ret = 0; /* Hidden means non-existing */
goto ex;
}
if (image->rockridge) {
if (opts->rockridge) {
ret = create_symlink(image, (IsoSymlink*)iso, &node);
} else {
/* symlinks are only supported when RR is enabled */
@ -440,7 +451,7 @@ int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree,
ret = 0; /* Hidden means non-existing */
goto ex;
}
if (image->rockridge) {
if (opts->rockridge) {
ret = create_special(image, (IsoSpecial*)iso, &node);
} else {
/* special files are only supported when RR is enabled */
@ -474,22 +485,15 @@ 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) {
/* Directories in root may be used as relocation dir */
if (image->rr_reloc_dir != NULL)
if (image->rr_reloc_dir[0] != 0 &&
strcmp(iso->name, image->rr_reloc_dir) == 0)
if (opts->rr_reloc_dir != NULL)
if (opts->rr_reloc_dir[0] != 0 &&
strcmp(iso->name, opts->rr_reloc_dir) == 0)
image->rr_reloc_node = node;
}
#endif /* Libisofs_with_rr_reloc_diR */
}
ret = ISO_SUCCESS;
pos = dir->children;
@ -619,7 +623,7 @@ int mangle_single_dir(Ecma119Image *img, Ecma119Node *dir, int max_file_len,
continue;
}
if (img->untranslated_name_len) {
if (img->opts->untranslated_name_len) {
/* This should not happen because no two IsoNode names should be
identical and only unaltered IsoNode names should be seen here.
Thus the Ema119Node names should be unique.
@ -648,7 +652,8 @@ int mangle_single_dir(Ecma119Image *img, Ecma119Node *dir, int max_file_len,
/* compute name and extension */
dot = strrchr(full_name, '.');
if (dot != NULL &&
(children[i]->type != ECMA119_DIR || img->allow_dir_id_ext)) {
(children[i]->type != ECMA119_DIR ||
img->opts->allow_dir_id_ext)) {
/*
* File (normally not dir) with extension
@ -734,8 +739,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);
@ -811,11 +819,11 @@ int mangle_tree(Ecma119Image *img, Ecma119Node *dir, int recurse)
int max_file, max_dir;
Ecma119Node *root;
if (img->untranslated_name_len > 0) {
max_file = max_dir = img->untranslated_name_len;
} else if (img->max_37_char_filenames) {
if (img->opts->untranslated_name_len > 0) {
max_file = max_dir = img->opts->untranslated_name_len;
} else if (img->opts->max_37_char_filenames) {
max_file = max_dir = 37;
} else if (img->iso_level == 1) {
} else if (img->opts->iso_level == 1) {
max_file = 12; /* 8 + 3 + 1 */
max_dir = 8;
} else {
@ -959,9 +967,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 +975,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;
@ -997,9 +991,9 @@ int reorder_tree(Ecma119Image *img, Ecma119Node *dir,
/* dir is now the relocated Ecma119Node */
pathlen = 37 + 1; /* The dir name might get longer by mangling */
level = 2;
if (img->rr_reloc_dir != NULL) {
if (img->opts->rr_reloc_dir != NULL) {
pathlen += strlen(img->rr_reloc_node->iso_name) + 1;
if(img->rr_reloc_dir[0] != 0)
if(img->opts->rr_reloc_dir[0] != 0)
level = 3;
}
}
@ -1152,7 +1146,7 @@ int match_hardlinks(Ecma119Image *img, Ecma119Node *dir, int flag)
goto ex;
/* Sort according to id tuples, IsoFileSrc identity, properties, xattr. */
if (img->hardlinks)
if (img->opts->hardlinks)
qsort(nodes, node_count, sizeof(Ecma119Node *), ecma119_node_cmp_hard);
else
qsort(nodes, node_count, sizeof(Ecma119Node *),
@ -1222,7 +1216,7 @@ int ecma119_tree_create(Ecma119Image *img)
return ret;
}
if (img->rockridge && !img->allow_deep_paths) {
if (img->opts->rockridge && !img->opts->allow_deep_paths) {
/* Relocate deep directories, acording to RRIP, 4.1.5 */
ret = reorder_tree(img, root, 1, 0);
@ -1235,13 +1229,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

@ -103,5 +103,13 @@ Ecma119Node *ecma119_search_iso_node(Ecma119Image *img, IsoNode *node);
*/
int ecma119_is_dedicated_reloc_dir(Ecma119Image *img, Ecma119Node *node);
/**
* Determines the ECMA-119 name from node name.
* @param flag bit0= Do not issue error messages
*/
int iso_get_ecma119_name(IsoWriteOpts *opts, char *input_charset, int imgid,
char *node_name, enum IsoNodeType node_type,
char **name, int flag);
#endif /*LIBISO_ECMA119_TREE_H_*/

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2010 Thomas Schmitt
* Copyright (c) 2010 - 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 */
@ -306,7 +312,8 @@ int iso_tree_add_boot_node(IsoDir *parent, const char *name, IsoBoot **boot)
static
int create_image(IsoImage *image, const char *image_path,
enum eltorito_boot_media_type type,
struct el_torito_boot_image **bootimg)
struct el_torito_boot_image **bootimg,
IsoFile **bootnode)
{
int ret;
struct el_torito_boot_image *boot;
@ -317,6 +324,7 @@ int create_image(IsoImage *image, const char *image_path,
IsoNode *imgfile;
IsoStream *stream;
*bootnode = NULL;
ret = iso_tree_path_to_node(image, image_path, &imgfile);
if (ret < 0) {
return ret;
@ -331,6 +339,7 @@ int create_image(IsoImage *image, const char *image_path,
if (imgfile->type != LIBISO_FILE) {
return ISO_BOOT_IMAGE_NOT_VALID;
}
*bootnode = (IsoFile *) imgfile;
stream = ((IsoFile*)imgfile)->stream;
@ -455,6 +464,7 @@ int iso_image_set_boot_image(IsoImage *image, const char *image_path,
struct el_torito_boot_catalog *catalog;
ElToritoBootImage *boot_image= NULL;
IsoBoot *cat_node= NULL;
IsoFile *boot_node;
if (image == NULL || image_path == NULL || catalog_path == NULL) {
return ISO_NULL_POINTER;
@ -507,7 +517,7 @@ int iso_image_set_boot_image(IsoImage *image, const char *image_path,
}
/* create the boot image */
ret = create_image(image, image_path, type, &boot_image);
ret = create_image(image, image_path, type, &boot_image, &boot_node);
if (ret < 0) {
goto boot_image_cleanup;
}
@ -524,6 +534,8 @@ int iso_image_set_boot_image(IsoImage *image, const char *image_path,
catalog->bootimages[i] = NULL;
catalog->node = cat_node;
catalog->sort_weight = 1000; /* slightly high */
if (!boot_node->explicit_weight)
boot_node->sort_weight = 2;
iso_node_ref((IsoNode*)cat_node);
image->bootcat = catalog;
@ -694,14 +706,17 @@ int iso_image_add_boot_image(IsoImage *image, const char *image_path,
int ret;
struct el_torito_boot_catalog *catalog = image->bootcat;
ElToritoBootImage *boot_img;
IsoFile *boot_node;
if(catalog == NULL)
return ISO_BOOT_NO_CATALOG;
if (catalog->num_bootimages >= Libisofs_max_boot_imageS)
return ISO_BOOT_IMAGE_OVERFLOW;
ret = create_image(image, image_path, type, &boot_img);
ret = create_image(image, image_path, type, &boot_img, &boot_node);
if (ret < 0)
return ret;
if (!boot_node->explicit_weight)
boot_node->sort_weight = 2;
catalog->bootimages[catalog->num_bootimages] = boot_img;
catalog->num_bootimages++;
if (boot != NULL)
@ -1032,7 +1047,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 +1111,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;
@ -1110,35 +1126,47 @@ int patch_boot_image(uint8_t *buf, Ecma119Image *t, size_t imgsize, int idx)
return iso_msg_submit(t->image->id, ISO_ISOLINUX_CANT_PATCH, 0,
"Isolinux image too small. We won't patch it.");
}
ret = make_boot_info_table(buf, t->ms_block + (uint32_t) 16,
ret = make_boot_info_table(buf, t->opts->ms_block + (uint32_t) 16,
t->bootsrc[idx]->sections[0].block,
(uint32_t) imgsize);
return ret;
}
/**
* Patch a GRUB2 El Torito boot image.
*/
static
int 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 +1190,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 +1218,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 +1270,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 +1302,9 @@ int eltorito_writer_create(Ecma119Image *target)
}
}
if (target->opts->efi_boot_partition != NULL)
if (strcmp(target->opts->efi_boot_partition, "--efi-boot-image") == 0)
outsource_efi = 1;
for (idx = 0; idx < target->catalog->num_bootimages; idx++) {
bootimg = target->catalog->bootimages[idx]->image;
ret = iso_file_src_create(target, bootimg, &src);
@ -1263,12 +1315,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->opts->efi_boot_partition);
target->opts->efi_boot_partition = NULL;
iso_msg_submit(target->image->id, ISO_BOOT_NO_EFI_ELTO, 0,
"No newly added El Torito EFI boot image found for exposure as GPT partition");
return ISO_BOOT_NO_EFI_ELTO;
}
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,8 +88,8 @@ int iso_file_src_create(Ecma119Image *img, IsoFile *file, IsoFileSrc **src)
}
/* fill key and other atts */
fsrc->prev_img = file->from_old_session;
if (file->from_old_session && img->appendable) {
fsrc->no_write = (file->from_old_session && img->opts->appendable);
if (file->from_old_session && img->opts->appendable) {
/*
* On multisession discs we keep file sections from old image.
*/
@ -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,8 @@ int iso_file_src_create(Ecma119Image *img, IsoFile *file, IsoFileSrc **src)
/* insert the filesrc in the tree */
ret = iso_rbtree_insert(img->files, fsrc, (void**)src);
if (ret <= 0) {
if (ret == 0 && (*src)->checksum_index > 0) {
if (ret == 0 && (*src)->checksum_index > 0 &&
!img->opts->will_cancel) {
/* Duplicate file source was mapped to previously registered source
*/
cret = iso_file_set_isofscx(file, (*src)->checksum_index, 0);
@ -133,8 +141,8 @@ int iso_file_src_create(Ecma119Image *img, IsoFile *file, IsoFileSrc **src)
}
iso_stream_ref(fsrc->stream);
if ((img->md5_file_checksums & 1) &&
file->from_old_session && img->appendable) {
if ((img->opts->md5_file_checksums & 1) &&
file->from_old_session && img->opts->appendable) {
ret = iso_node_get_xinfo((IsoNode *) file, checksum_md5_xinfo_func,
&xipt);
if (ret <= 0)
@ -145,13 +153,14 @@ int iso_file_src_create(Ecma119Image *img, IsoFile *file, IsoFileSrc **src)
no_md5 = 1;
}
if ((img->md5_file_checksums & 1) && !no_md5) {
if ((img->opts->md5_file_checksums & 1) &&
!(no_md5 || img->opts->will_cancel)) {
img->checksum_idx_counter++;
if (img->checksum_idx_counter < 0x7fffffff) {
fsrc->checksum_index = img->checksum_idx_counter;
} else {
fsrc->checksum_index= 0;
img->checksum_idx_counter= 0x7fffffff; /* keep from rolling over */
img->checksum_idx_counter= 0x7ffffffe; /* keep from rolling over */
}
cret = iso_file_set_isofscx(file, (*src)->checksum_index, 0);
if (cret < 0)
@ -214,16 +223,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 +241,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++;
if (! t->opts->old_empty)
t->filesrc_blocks++;
/* on appendable images, ms files shouldn't be included */
if (t->appendable) {
inc_item = is_ms_file;
if (t->opts->appendable) {
inc_item = shall_be_written;
} else {
inc_item = NULL;
}
@ -254,7 +263,7 @@ int filesrc_writer_compute_data_blocks(IsoImageWriter *writer)
}
/* sort files by weight, if needed */
if (t->sort_files) {
if (t->opts->sort_files) {
qsort(filelist, size, sizeof(void*), cmp_by_weight);
}
@ -262,10 +271,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 +292,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 +322,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 +404,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->opts->md5_file_checksums & 2)) {
/* Obtain an MD5 of content by a first read pass */
pre_md5_valid = filesrc_make_md5(t, file, pre_md5, 0);
}
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->opts->libjte_handle != NULL) {
res = libjte_begin_data_file(t->opts->libjte_handle, name,
BLOCK_SIZE, file_size);
if (res <= 0) {
res = iso_libjte_forward_msgs(t->opts->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->opts->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->opts->libjte_handle);
iso_libjte_forward_msgs(t->opts->libjte_handle, t->image->id,
ISO_LIBJTE_END_FAILED, 0);
if (res <= 0 && ret >= 0)
ret = ISO_LIBJTE_FILE_FAILED;
}
#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;
}
@ -367,7 +660,7 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
files which have no block address:
symbolic links, device files, empty data files.
*/
if (! t->old_empty) {
if (! t->opts->old_empty) {
ret = iso_write(t, buffer, BLOCK_SIZE);
if (ret < 0)
goto ex;
@ -375,216 +668,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

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2011 Thomas Schmitt
* Copyright (c) 2009 - 2014 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -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,32 @@ 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;
size_t joliet_ucs2_failures;
} _ImageFsData;
typedef struct image_fs_data ImageFileSourceData;
@ -430,6 +476,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;
}
@ -1189,33 +1237,107 @@ int iso_ifs_source_get_zf(IsoFileSource *src, int *header_size_div4,
}
static
int make_hopefully_unique_name(_ImageFsData *fsdata,
char *str, size_t len, char **name)
{
int ret, name_len, i;
char c, *smashed = NULL, md5[16];
void *md5_context = NULL;
/* Shorten so that 32 characters of MD5 fit.
If shorter than 8, pad up to 8 by '_'.
Smash characters to [0-9A-Za-z_.].
Append MD5 of original str as hex digits.
*/
name_len = len > 223 ? 223 : len;
LIBISO_ALLOC_MEM(smashed, char, (name_len >= 8 ? name_len : 8) + 32 + 1);
memcpy(smashed, str, name_len);
for (; name_len < 8; name_len++)
smashed[name_len] = '_';
smashed[name_len] = 0;
for (i = 0; i < name_len; i++) {
c = smashed[i];
if (c == '.' || (c >= '0' && c <= '9') ||
c == '_' || (c >= 'a' && c <= 'z'))
continue;
smashed[i] = '_';
}
ret = iso_md5_start(&md5_context);
if (ret != 1)
goto ex;
ret = iso_md5_compute(md5_context, str, len);
if (ret != 1)
goto ex;
ret = iso_md5_end(&md5_context, md5);
if (ret != 1)
goto ex;
for (i = 0; i < 16; i++)
sprintf(smashed + i * 2 + name_len, "%2.2x",
((unsigned char *) md5)[i]);
name_len += 32;
smashed[name_len] = 0;
*name = smashed; smashed = NULL;
ret = ISO_SUCCESS;
ex:
LIBISO_FREE_MEM(smashed);
if (md5_context != NULL)
iso_md5_end(&md5_context, md5);
return ret;
}
/**
* Read a file name from a directory record, doing the needed charset
* conversion
*/
static
char *get_name(_ImageFsData *fsdata, const char *str, size_t len)
char *get_name(_ImageFsData *fsdata, char *str, size_t len)
{
int ret;
char *name = NULL;
char *name = NULL, *from_ucs = NULL;
if (strcmp(fsdata->local_charset, fsdata->input_charset)) {
/* charset conversion needed */
ret = strnconv(str, fsdata->input_charset, fsdata->local_charset, len,
&name);
if (ret == 1) {
if (fsdata->iso_root_block == fsdata->svd_root_block) {
/* Reading from Joliet : Check whether UTF-16 was needed */
ret = strnconv(str, "UCS-2BE", fsdata->local_charset,
len, &from_ucs);
if (ret == 1)
ret = (strcmp(name, from_ucs) == 0);
if (ret != 1) {
fsdata->joliet_ucs2_failures++;
if (fsdata->joliet_ucs2_failures <=
ISO_JOLIET_UCS2_WARN_MAX)
iso_msg_submit(-1, ISO_NAME_NOT_UCS2, 0,
"Joliet filename valid only with character set UTF-16 : \"%s\"",
name);
}
if (from_ucs != NULL)
free(from_ucs);
}
return name;
} else {
ret = iso_msg_submit(fsdata->msgid, ISO_FILENAME_WRONG_CHARSET, ret,
"Charset conversion error. Cannot convert from %s to %s",
"Cannot convert from charset %s to %s",
fsdata->input_charset, fsdata->local_charset);
if (ret < 0) {
return NULL; /* aborted */
}
/* fallback */
ret = make_hopefully_unique_name(fsdata, str, len, &name);
if (ret == ISO_SUCCESS)
return name;
return NULL;
}
}
/* we reach here when the charset conversion is not needed or has failed */
/* we reach here when the charset conversion is not needed */
name = malloc(len + 1);
if (name == NULL) {
@ -1227,6 +1349,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 +1563,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 +1579,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 +1593,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 +1646,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 +1667,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 +1675,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 +1695,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 +1707,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 +1722,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 +1733,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 +1746,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 +1772,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 +1796,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 +1824,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,
"Cannot convert from charset %.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 +1849,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 +1978,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 +2279,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 +2317,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 +2532,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 +2830,9 @@ 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->joliet_ucs2_failures = 0;
data->local_charset = strdup(iso_get_local_charset(0));
@ -2755,7 +2983,10 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
if (!opts->nojoliet && opts->preferjoliet && data->joliet) {
/* if user prefers joliet, that is used */
iso_msg_debug(data->msgid, "Reading Joliet extensions.");
data->input_charset = strdup("UCS-2BE");
/* Although Joliet prescribes UCS-2BE, interpret names by its
superset UTF-16BE in order to avoid conversion failures.
*/
data->input_charset = strdup("UTF-16BE");
data->rr = RR_EXT_NO;
data->iso_root_block = data->svd_root_block;
} else {
@ -2768,7 +2999,7 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
if (!opts->nojoliet && data->joliet) {
/* joliet will be used */
iso_msg_debug(data->msgid, "Reading Joliet extensions.");
data->input_charset = strdup("UCS-2BE");
data->input_charset = strdup("UTF-16BE");
data->iso_root_block = data->svd_root_block;
} else if (!opts->noiso1999 && data->iso1999) {
/* we will read ISO 9660:1999 */
@ -2851,13 +3082,14 @@ int src_aa_to_node(IsoFileSource *src, IsoNode *node, int flag)
static
int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
IsoFileSource *src, IsoNode **node)
IsoFileSource *src, char *in_name,
IsoNode **node)
{
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;
@ -2877,7 +3109,14 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
data = (ImageFileSourceData*)src->data;
fsdata = data->fs->data;
name = iso_file_source_get_name(src);
if (in_name == NULL) {
name = iso_file_source_get_name(src);
} else {
name = strdup(in_name);
if (name == NULL) {
ret = ISO_OUT_OF_MEM; goto ex;
}
}
/* get info about source */
ret = iso_file_source_lstat(src, &info);
@ -2885,7 +3124,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 +3137,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 +3146,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 +3157,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 +3174,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 +3192,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 +3216,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 +3246,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 +3263,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 +3278,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 +3302,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 +3313,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 +3333,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 +3341,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 +3474,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 +3490,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 +3556,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;
}
@ -3332,6 +3579,22 @@ ex:;
return ret;
}
static
void issue_collision_warning_summary(size_t failures)
{
if (failures > ISO_IMPORT_COLL_WARN_MAX) {
iso_msg_submit(-1, ISO_IMPORT_COLLISION, 0,
"More file name collisions had to be resolved");
}
if (failures > 0) {
iso_msg_submit(-1, ISO_IMPORT_COLLISION, 0,
"Sum of resolved file name collisions: %.f",
(double) failures);
}
}
int iso_image_import(IsoImage *image, IsoDataSource *src,
struct iso_read_opts *opts,
IsoReadImageFeatures **features)
@ -3475,12 +3738,13 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
/* recursively add image */
ret = iso_add_dir_src_rec(image, image->root, newroot);
/* error during recursive image addition? */
if (ret < 0) {
/* error during recursive image addition */
iso_node_builder_unref(image->builder);
goto import_revert;
}
issue_ucs2_warning_summary(data->joliet_ucs2_failures);
issue_collision_warning_summary(image->collision_warnings);
/* Take over inode management from IsoImageFilesystem.
data->inode_counter is supposed to hold the maximum PX inode number.
@ -3514,7 +3778,7 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
goto import_revert;
}
ret = image_builder_create_node(image->builder, image, boot_src,
&node);
NULL, &node);
if (ret < 0) {
iso_node_builder_unref(image->builder);
goto import_revert;
@ -3524,7 +3788,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 +3820,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 +3830,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 +3910,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 +3922,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)

1850
libisofs/hfsplus.c Normal file

File diff suppressed because it is too large Load Diff

201
libisofs/hfsplus.h Normal file
View File

@ -0,0 +1,201 @@
/*
* 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[];
int iso_get_hfsplus_name(char *input_charset, int imgid, char *name,
uint16_t **result, uint32_t *result_len, uint16_t **cmp_name);
#endif /* LIBISO_HFSPLUS_H */

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 - 2014 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -78,11 +78,18 @@ int iso_image_new(const char *name, IsoImage **image)
img->volset_id = strdup(name);
img->volume_id = strdup(name);
}
memset(img->application_use, 0, 512);
img->system_area_data = NULL;
img->system_area_options = 0;
img->num_mips_boot_files = 0;
for (i = 0; i < 15; i++)
img->mips_boot_file_paths[i] = NULL;
img->sparc_core_node = NULL;
img->hppa_cmdline= NULL;
img->hppa_bootloader= NULL;
img->hppa_kernel_32= NULL;
img->hppa_kernel_64= NULL;
img->hppa_ramdisk= NULL;
img->builder_ignore_acl = 1;
img->builder_ignore_ea = 1;
img->inode_counter = 0;
@ -93,6 +100,10 @@ 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;
img->collision_warnings = 0;
*image = img;
return ISO_SUCCESS;
}
@ -112,25 +123,36 @@ 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);
#ifdef Libisofs_enable_unreleased_hppa_palO
iso_image_set_hppa_palo(image, NULL, NULL, NULL, NULL, NULL, 1);
#endif
free(image->volset_id);
free(image->volume_id);
free(image->publisher_id);
@ -140,6 +162,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 +356,55 @@ 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 = calloc(18, 1); /* Surely including a trailing 0 */
image->modification_time = calloc(18, 1);
image->expiration_time = calloc(18, 1);
image->effective_time = calloc(18, 1);
if (image->creation_time == NULL || image->modification_time == NULL ||
image->expiration_time == NULL || image->effective_time == NULL)
return ISO_OUT_OF_MEM;
/* (If the string is too short, a non-zero timezone will not be stored) */
strncpy(image->creation_time, creation_time, 17);
strncpy(image->modification_time, modification_time, 17);
strncpy(image->expiration_time, expiration_time, 17);
strncpy(image->effective_time, effective_time, 17);
return ISO_SUCCESS;
}
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,21 +424,74 @@ static
int dir_update_size(IsoImage *image, IsoDir *dir)
{
IsoNode *pos;
int ret;
#ifdef Libisofs_update_sizes_abortablE
char *path= NULL;
IsoStream *base_stream;
int cancel_ret, ret;
uint32_t lba;
#endif
pos = dir->children;
while (pos) {
int ret = 1;
if (pos->type == LIBISO_FILE) {
ret = iso_stream_update_size(ISO_FILE(pos)->stream);
} else if (pos->type == LIBISO_DIR) {
/* recurse */
ret = dir_update_size(image, ISO_DIR(pos));
#ifdef Libisofs_update_sizes_abortablE
if (ret == ISO_CANCELED)
return ret; /* Message already issued by dir_update_size */
#endif
} else {
ret = 1;
}
#ifdef Libisofs_update_sizes_abortablE
/* This would report error and abort according to severity threshold.
But it is desirable to let the update_size crawler continue
its work after e.g. a file has vanished from hard disk.
So normally this macro case should be disabled.
*/
if (ret < 0) {
ret = iso_msg_submit(image->id, ret, 0, NULL);
if (ret < 0) {
return ret; /* cancel due error threshold */
cancel_ret = iso_msg_submit(image->id, ret, 0, NULL);
path = iso_tree_get_node_path(pos);
if (path != NULL) {
iso_msg_submit(image->id, ret, 0,
"ISO path : %s", path);
free(path);
}
/* Report source path with streams which do not come from
the loaded ISO filesystem */
if (pos->type == LIBISO_FILE &&
iso_node_get_old_image_lba(pos, &lba, 0) == 0) {
base_stream = iso_stream_get_input_stream(
ISO_FILE(pos)->stream, 1);
if (base_stream == NULL)
base_stream = ISO_FILE(pos)->stream;
path = iso_stream_get_source_path(base_stream, 0);
if (path != NULL) {
iso_msg_submit(image->id, ret, 0,
"Local path: %s", path);
free(path);
}
}
if (cancel_ret < 0)
return cancel_ret; /* cancel due error threshold */
}
#else
if (ret < 0)
ret = 1; /* ignore error */
#endif /* ! Libisofs_update_sizes_abortablE */
pos = pos->next;
}
return ISO_SUCCESS;
@ -657,3 +785,176 @@ 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;
}
/* @param flag
bit0= Let NULL parameters free the corresponding image properties.
Else only the non-NULL parameters of this call have an effect.
*/
static int hppa_palo_set_path(IsoImage *img, char *path, char **target,
int flag)
{
int ret;
IsoNode *node;
IsoFile *file;
if (path == NULL && !(flag & 1))
return ISO_SUCCESS;
if (iso_clone_mgtd_mem(path, target, 0) < 0)
return ISO_OUT_OF_MEM;
if (path == NULL)
return ISO_SUCCESS;
ret = iso_tree_path_to_node(img, path, &node);
if (ret < 0)
return ret;
if (ret == 0) {
iso_msg_submit(img->id, ISO_BOOT_FILE_MISSING, 0,
"Cannot find in ISO image: HP-PA file '%s'", path);
return ISO_BOOT_FILE_MISSING;
}
if (iso_node_get_type(node) != LIBISO_FILE) {
iso_msg_submit(img->id, ISO_HPPA_PALO_NOTREG, 0,
"HP-PA PALO file is not a data file: '%s'", path);
return ISO_HPPA_PALO_NOTREG;
}
file = (IsoFile *) node;
if (!file->explicit_weight)
file->sort_weight = 2;
return ISO_SUCCESS;
}
/* API */
/* @param flag
Bitfield for control purposes
bit0= Let NULL parameters free the corresponding image properties.
Else only the non-NULL parameters of this call have an effect.
*/
int iso_image_set_hppa_palo(IsoImage *img, char *cmdline, char *bootloader,
char *kernel_32, char *kernel_64, char *ramdisk,
int flag)
{
int ret;
if (cmdline != NULL || (flag & 1))
if (iso_clone_mgtd_mem(cmdline, &(img->hppa_cmdline), 0) < 0)
return ISO_OUT_OF_MEM;
ret = hppa_palo_set_path(img, bootloader, &(img->hppa_bootloader),
flag & 1);
if (ret < 0)
return ret;
ret = hppa_palo_set_path(img, kernel_32, &(img->hppa_kernel_32), flag & 1);
if (ret < 0)
return ret;
ret = hppa_palo_set_path(img, kernel_64, &(img->hppa_kernel_64), flag & 1);
if (ret < 0)
return ret;
ret = hppa_palo_set_path(img, ramdisk, &(img->hppa_ramdisk), flag & 1);
if (ret < 0)
return ret;
return ISO_SUCCESS;
}
/* API */
int iso_image_get_hppa_palo(IsoImage *img, char **cmdline, char **bootloader,
char **kernel_32, char **kernel_64, char **ramdisk)
{
*cmdline = img->hppa_cmdline;
*bootloader = img->hppa_bootloader;
*kernel_32 = img->hppa_kernel_32;
*kernel_64 = img->hppa_kernel_64;
*ramdisk = img->hppa_ramdisk;
return ISO_SUCCESS;
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 Thomas Schmitt
* Copyright (c) 2009 - 2014 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -22,6 +22,9 @@
*/
#define ISO_USED_INODE_RANGE (1 << 18)
/* How many warnings to issue about name collisions during iso_image_import()
*/
#define ISO_IMPORT_COLL_WARN_MAX 10
/*
* Image is a context for image manipulation.
@ -49,6 +52,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 +73,20 @@ struct Iso_Image
int num_mips_boot_files;
char *mips_boot_file_paths[15]; /* ISO 9660 Rock Ridge Paths */
/* A data file of which the position and size shall be written after
a SUN Disk Label.
*/
IsoFile *sparc_core_node;
/*
* Parameters for HP-PA PALO boot sector. cmdline is a string. The other
* four are absolute paths to data files in the ISO image.
*/
char *hppa_cmdline;
char *hppa_bootloader;
char *hppa_kernel_32;
char *hppa_kernel_64;
char *hppa_ramdisk;
/* image identifier, for message origin identifier */
int id;
@ -180,6 +202,16 @@ 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];
/* Counts the name collisions while iso_image_import() */
size_t collision_warnings;
};
@ -227,4 +259,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>
@ -124,7 +125,7 @@ int create_node(Ecma119Image *t, IsoNode *iso, Iso1999Node **node)
IsoFile *file = (IsoFile*) iso;
size = iso_stream_get_size(file->stream);
if (size > (off_t)MAX_ISO_FILE_SECTION_SIZE && t->iso_level != 3) {
if (size > (off_t)MAX_ISO_FILE_SECTION_SIZE && t->opts->iso_level != 3) {
char *ipath = iso_tree_get_node_path(iso);
ret = iso_msg_submit(t->image->id, ISO_FILE_TOO_BIG, 0,
"File \"%s\" can't be added to image because is "
@ -193,7 +194,7 @@ int create_tree(Ecma119Image *t, IsoNode *iso, Iso1999Node **tree, int pathlen)
}
max_path = pathlen + 1 + (iso_name ? strlen(iso_name): 0);
if (!t->allow_longer_paths && max_path > 255) {
if (!t->opts->allow_longer_paths && max_path > 255) {
char *ipath = iso_tree_get_node_path(iso);
ret = iso_msg_submit(t->image->id, ISO_FILE_IMGPATH_WRONG, 0,
"File \"%s\" can't be added to ISO 9660:1999 tree, "
@ -307,7 +308,7 @@ int mangle_single_dir(Ecma119Image *img, Iso1999Node *dir)
int ret;
int i, nchildren;
Iso1999Node **children;
IsoHTable *table;
IsoHTable *table = NULL;
int need_sort = 0;
char *full_name = NULL, *tmp = NULL;
@ -721,13 +722,13 @@ void write_one_dir_record(Ecma119Image *t, Iso1999Node *node, int file_id,
iso_bb(rec->block, block, 4);
iso_bb(rec->length, len, 4);
/* was: iso_datetime_7(rec->recording_time, t->now, t->always_gmt);
/* was: iso_datetime_7(rec->recording_time, t->now, t->opts->always_gmt);
*/
iso= node->node;
iso_datetime_7(rec->recording_time,
(t->dir_rec_mtime & 4) ? ( t->replace_timestamps ?
t->timestamp : iso->mtime )
: t->now, t->always_gmt);
(t->opts->dir_rec_mtime & 4) ? ( t->replace_timestamps ?
t->timestamp : iso->mtime )
: t->now, t->opts->always_gmt);
rec->flags[0] = ((node->type == ISO1999_DIR) ? 2 : 0) | (multi_extend ? 0x80 : 0);
iso_bb(rec->vol_seq_number, (uint32_t) 1, 2);
@ -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,37 +21,76 @@
#include "eltorito.h"
#include "libisofs.h"
#include "util.h"
#include "ecma119.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
static
int get_joliet_name(Ecma119Image *t, IsoNode *iso, uint16_t **name)
/* @param flag bit0= Do not issue error messages
*/
int iso_get_joliet_name(IsoWriteOpts *opts, char *input_charset, int imgid,
char *node_name, enum IsoNodeType node_type,
size_t *joliet_ucs2_failures,
uint16_t **name, int flag)
{
int ret;
uint16_t *ucs_name;
int ret = ISO_SUCCESS;
uint16_t *ucs_name = NULL, *utf16_name = NULL;
uint16_t *jname = NULL;
if (iso->name == NULL) {
if (node_name == NULL) {
/* it is not necessarily an error, it can be the root */
*name = NULL;
return ISO_SUCCESS;
}
ret = str2ucs(t->input_charset, iso->name, &ucs_name);
if (ret < 0) {
iso_msg_debug(t->image->id, "Can't convert %s", iso->name);
return ret;
if (opts->joliet_utf16) {
ret = str2utf16be(input_charset, node_name, &ucs_name);
if (ret < 0) {
if (!(flag & 512))
iso_msg_debug(imgid, "Cannot convert to UTF-16 : \"%s\"",
node_name);
goto ex;
}
} else {
ret = str2ucs(input_charset, node_name, &ucs_name);
if (ret < 0) {
if (!(flag & 512))
iso_msg_debug(imgid, "Cannot convert to UCS-2 : \"%s\"",
node_name);
goto ex;
}
ret = str2utf16be(input_charset, node_name, &utf16_name);
if (ret == ISO_SUCCESS) {
if (ucscmp(ucs_name, utf16_name) != 0) {
(*joliet_ucs2_failures)++;
if (*joliet_ucs2_failures <= ISO_JOLIET_UCS2_WARN_MAX &&
!(flag & 512)) {
iso_msg_submit(imgid, ISO_NAME_NOT_UCS2, 0,
"Filename not suitable for Joliet character set UCS-2 : \"%s\"",
node_name);
}
}
}
}
if (iso->type == LIBISO_DIR) {
jname = iso_j_dir_id(ucs_name, t->joliet_long_names << 1);
if (node_type == LIBISO_DIR) {
jname = iso_j_dir_id(ucs_name, opts->joliet_long_names << 1);
} else {
jname = iso_j_file_id(ucs_name,
(t->joliet_long_names << 1) | !!(t->no_force_dots & 2));
(opts->joliet_long_names << 1) | !!(opts->no_force_dots & 2));
}
free(ucs_name);
if (jname != NULL) {
ret = ISO_SUCCESS;
ex:;
if (ucs_name != NULL)
free(ucs_name);
if (utf16_name != NULL)
free(utf16_name);
if (ret != ISO_SUCCESS) {
if (jname != NULL)
free(jname);
return ret;
} else if (jname != NULL) {
*name = jname;
return ISO_SUCCESS;
} else {
@ -63,6 +102,19 @@ int get_joliet_name(Ecma119Image *t, IsoNode *iso, uint16_t **name)
}
}
static
int get_joliet_name(Ecma119Image *t, IsoNode *iso, uint16_t **name)
{
int ret;
ret = iso_get_joliet_name(t->opts, t->input_charset, t->image->id,
iso->name, iso->type, &(t->joliet_ucs2_failures),
name, 0);
return ret;
}
static
void joliet_node_free(JolietNode *node)
{
@ -119,7 +171,8 @@ int create_node(Ecma119Image *t, IsoNode *iso, JolietNode **node)
IsoFile *file = (IsoFile*) iso;
size = iso_stream_get_size(file->stream);
if (size > (off_t)MAX_ISO_FILE_SECTION_SIZE && t->iso_level != 3) {
if (size > (off_t)MAX_ISO_FILE_SECTION_SIZE &&
t->opts->iso_level != 3) {
char *ipath = iso_tree_get_node_path(iso);
free(joliet);
ret = iso_msg_submit(t->image->id, ISO_FILE_TOO_BIG, 0,
@ -187,7 +240,7 @@ int create_tree(Ecma119Image *t, IsoNode *iso, JolietNode **tree, int pathlen)
return ret;
}
max_path = pathlen + 1 + (jname ? ucslen(jname) * 2 : 0);
if (!t->joliet_longer_paths && max_path > 240) {
if (!t->opts->joliet_longer_paths && max_path > 240) {
char *ipath = iso_tree_get_node_path(iso);
/*
* Wow!! Joliet is even more restrictive than plain ISO-9660,
@ -248,7 +301,7 @@ int create_tree(Ecma119Image *t, IsoNode *iso, JolietNode **tree, int pathlen)
{
char *ipath = iso_tree_get_node_path(iso);
ret = iso_msg_submit(t->image->id, ISO_FILE_IGNORED, 0,
"Can't add %s to Joliet tree. %s can only be added to a "
"Cannot add %s to Joliet tree. %s can only be added to a "
"Rock Ridge tree.", ipath, (iso->type == LIBISO_SYMLINK ?
"Symlinks" : "Special files"));
free(ipath);
@ -332,11 +385,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;
}
@ -347,7 +401,7 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
int ret;
int i, nchildren, maxchar = 64;
JolietNode **children;
IsoHTable *table;
IsoHTable *table = NULL;
int need_sort = 0;
uint16_t *full_name = NULL;
uint16_t *tmp = NULL;
@ -357,7 +411,7 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
nchildren = dir->info.dir->nchildren;
children = dir->info.dir->children;
if (t->joliet_long_names)
if (t->opts->joliet_long_names)
maxchar = 103;
/* a hash table will temporary hold the names, for fast searching */
@ -596,7 +650,7 @@ size_t calc_dirent_len(Ecma119Image *t, JolietNode *n)
{
/* note than name len is always even, so we always need the pad byte */
int ret = n->name ? ucslen(n->name) * 2 + 34 : 34;
if (n->type == JOLIET_FILE && !(t->omit_version_numbers & 3)) {
if (n->type == JOLIET_FILE && !(t->opts->omit_version_numbers & 3)) {
/* take into account version numbers */
ret += 4;
}
@ -715,7 +769,7 @@ int joliet_writer_compute_data_blocks(IsoImageWriter *writer)
t->curblock += DIV_UP(path_table_size, BLOCK_SIZE);
t->joliet_path_table_size = path_table_size;
if (t->partition_offset > 0) {
if (t->opts->partition_offset > 0) {
/* Take into respect second directory tree */
ndirs = t->joliet_ndirs;
t->joliet_ndirs = 0;
@ -764,7 +818,7 @@ void write_one_dir_record(Ecma119Image *t, JolietNode *node, int file_id,
memcpy(rec->file_id, name, len_fi);
if (node->type == JOLIET_FILE && !(t->omit_version_numbers & 3)) {
if (node->type == JOLIET_FILE && !(t->opts->omit_version_numbers & 3)) {
len_dr += 4;
rec->file_id[len_fi++] = 0;
rec->file_id[len_fi++] = ';';
@ -799,13 +853,13 @@ void write_one_dir_record(Ecma119Image *t, JolietNode *node, int file_id,
iso_bb(rec->block, block - t->eff_partition_offset, 4);
iso_bb(rec->length, len, 4);
/* was: iso_datetime_7(rec->recording_time, t->now, t->always_gmt);
/* was: iso_datetime_7(rec->recording_time, t->now, t->opts->always_gmt);
*/
iso= node->node;
iso_datetime_7(rec->recording_time,
(t->dir_rec_mtime & 2) ? ( t->replace_timestamps ?
t->timestamp : iso->mtime )
: t->now, t->always_gmt);
(t->opts->dir_rec_mtime & 2) ? ( t->replace_timestamps ?
t->timestamp : iso->mtime )
: t->now, t->opts->always_gmt);
rec->flags[0] = ((node->type == JOLIET_DIR) ? 2 : 0) | (multi_extend ? 0x80 : 0);
iso_bb(rec->vol_seq_number, (uint32_t) 1, 2);
@ -826,18 +880,22 @@ void ucsncpy_pad(uint16_t *dest, const uint16_t *src, size_t max)
csrc = (char*)src;
if (src != NULL) {
len = MIN(ucslen(src) * 2, max);
len = MIN(ucslen(src) * 2, max - (max % 2));
} else {
len = 0;
}
for (i = 0; i < len; ++i)
cdest[i] = csrc[i];
if (len >= 2)
iso_handle_split_utf16(dest + (len / 2 - 1));
for (i = len; i < max; i += 2) {
for (i = len; i + 1 < max; i += 2) {
cdest[i] = '\0';
cdest[i + 1] = ' ';
}
if (max % 2)
cdest[max - 1] = 0;
}
int joliet_writer_write_vol_desc(IsoImageWriter *writer)
@ -911,9 +969,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);
@ -958,7 +1014,8 @@ int write_one_dir(Ecma119Image *t, JolietNode *dir)
/* compute len of directory entry */
fi_len = ucslen(child->name) * 2;
len = fi_len + 34;
if (child->type == JOLIET_FILE && !(t->omit_version_numbers & 3)) {
if (child->type == JOLIET_FILE &&
!(t->opts->omit_version_numbers & 3)) {
len += 4;
}
@ -1160,8 +1217,8 @@ int joliet_writer_write_data(IsoImageWriter *writer)
if (ret < 0)
return ret;
if (t->partition_offset > 0) {
t->eff_partition_offset = t->partition_offset;
if (t->opts->partition_offset > 0) {
t->eff_partition_offset = t->opts->partition_offset;
ret = joliet_writer_write_dirs(writer);
t->eff_partition_offset = 0;
if (ret < 0)
@ -1209,9 +1266,9 @@ int joliet_writer_create(Ecma119Image *target)
/* add this writer to image */
target->writers[target->nwriters++] = writer;
if(target->partition_offset > 0) {
if(target->opts->partition_offset > 0) {
/* Create second tree */
target->eff_partition_offset = target->partition_offset;
target->eff_partition_offset = target->opts->partition_offset;
ret = joliet_tree_create(target);
if (ret < 0) {
return ret;

View File

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

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,

File diff suppressed because it is too large Load Diff

View File

@ -19,6 +19,7 @@ el_torito_set_load_seg;
el_torito_set_load_size;
el_torito_set_no_bootable;
el_torito_set_selection_crit;
iso_conv_name_chars;
iso_data_source_new_from_file;
iso_data_source_ref;
iso_data_source_unref;
@ -65,9 +66,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 +89,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 +100,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 +126,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 +263,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,13 +292,19 @@ 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;
iso_write_opts_set_joliet_long_names;
iso_write_opts_set_joliet_longer_paths;
iso_write_opts_set_joliet_utf16;
iso_write_opts_set_max_37_char_filenames;
iso_write_opts_set_ms_block;
iso_write_opts_set_no_force_dots;
@ -296,6 +314,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,205 @@ 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->opts->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;
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;
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.
@ -414,6 +607,8 @@ int make_isolinux_mbr(int32_t *img_blocks, uint32_t boot_lba,
gettimeofday(&tv, &tz);
id = 0xffffffff & (tv.tv_sec ^ (tv.tv_usec * 2000));
lsb_to_buf(&wpt, id, 32, 0);
} else {
wpt+= 4;
}
/* write word 0 # Offset 444
@ -422,10 +617,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
@ -497,7 +497,7 @@ int checksum_copy_old_nodes(Ecma119Image *target, IsoNode *node, int flag)
if (node->type == LIBISO_FILE) {
file = (IsoFile *) node;
if (file->from_old_session && target->appendable) {
if (file->from_old_session && target->opts->appendable) {
/* Look for checksums at various places */
/* Try checksum directly stored with node */
@ -527,19 +527,25 @@ int checksum_copy_old_nodes(Ecma119Image *target, IsoNode *node, int flag)
if (md5_pt == NULL)
return 0;
ret = iso_node_lookup_attr(node, "isofs.cx", &value_length,
&value, 0);
if (ret == 1 && value_length == 4) {
for (i = 0; i < 4; i++)
idx = (idx << 8) | ((unsigned char *) value)[i];
if (idx > 0 && idx <= target->checksum_idx_counter) {
memcpy(target->checksum_buffer + 16 * idx, md5_pt, 16);
if (!target->opts->will_cancel) {
ret = iso_node_lookup_attr(node, "isofs.cx", &value_length,
&value, 0);
if (ret == 1 && value_length == 4) {
for (i = 0; i < 4; i++)
idx = (idx << 8) | ((unsigned char *) value)[i];
if (idx > 0 && idx <= target->checksum_idx_counter) {
memcpy(target->checksum_buffer + 16 * idx, md5_pt, 16);
}
}
if (value != NULL)
free(value);
/* >>> ts B30114 : It is unclear why these are removed here.
At least with the opts->will_cancel runs,
this is not appropriate.
*/
iso_node_remove_xinfo(node, checksum_md5_xinfo_func);
}
if (value != NULL)
free(value);
iso_node_remove_xinfo(node, checksum_md5_xinfo_func);
iso_node_remove_xinfo(node, checksum_cx_xinfo_func);
}
} else if (node->type == LIBISO_DIR) {
for (pos = ((IsoDir *) node)->children; pos != NULL; pos = pos->next) {
@ -565,8 +571,8 @@ int checksum_writer_compute_data_blocks(IsoImageWriter *writer)
t = writer->target;
t->checksum_array_pos = t->curblock;
/* (t->curblock already contains t->ms_block) */
t->checksum_range_start = t->ms_block;
/* (t->curblock already contains t->opts->ms_block) */
t->checksum_range_start = t->opts->ms_block;
size = (t->checksum_idx_counter + 2) / 128;
if (size * 128 < t->checksum_idx_counter + 2)
size++;
@ -706,7 +712,7 @@ int checksum_writer_create(Ecma119Image *target)
/* add this writer to image */
target->writers[target->nwriters++] = writer;
/* Account for superblock checksum tag */
if (target->md5_session_checksum) {
if (target->opts->md5_session_checksum) {
target->checksum_sb_tag_pos = target->curblock;
target->curblock++;
}
@ -736,7 +742,7 @@ int iso_md5_write_scdbackup_tag(Ecma119Image *t, char *tag_block, int flag)
(unsigned int) (pos % 1000000000));
else
sprintf(postext, "%u", (unsigned int) pos);
sprintf(record, "%s %s ", t->scdbackup_tag_parm, postext);
sprintf(record, "%s %s ", t->opts->scdbackup_tag_parm, postext);
record_len = strlen(record);
for (i = 0; i < 16; i++)
sprintf(record + record_len + 2 * i,
@ -758,8 +764,8 @@ int iso_md5_write_scdbackup_tag(Ecma119Image *t, char *tag_block, int flag)
block_len+= 32;
tag_block[block_len++]= '\n';
if (t->scdbackup_tag_written != NULL)
strncpy(t->scdbackup_tag_written, tag_block + line_start,
if (t->opts->scdbackup_tag_written != NULL)
strncpy(t->opts->scdbackup_tag_written, tag_block + line_start,
block_len - line_start);
ret = ISO_SUCCESS;
ex:;
@ -821,7 +827,7 @@ int iso_md5_write_tag(Ecma119Image *t, int flag)
} else if (mode == 3) {
sprintf(tag_block + l, " next=%u", t->checksum_tag_pos);
} else if (mode == 4) {
sprintf(tag_block + l, " session_start=%u", t->ms_block);
sprintf(tag_block + l, " session_start=%u", t->opts->ms_block);
}
strcat(tag_block + l, " md5=");
l = strlen(tag_block);
@ -842,8 +848,8 @@ int iso_md5_write_tag(Ecma119Image *t, int flag)
}
tag_block[l + 32] = '\n';
if (mode == 1 && t->scdbackup_tag_parm[0]) {
if (t->ms_block > 0) {
if (mode == 1 && t->opts->scdbackup_tag_parm[0]) {
if (t->opts->ms_block > 0) {
iso_msg_submit(t->image->id, ISO_SCDBACKUP_TAG_NOT_0, 0, NULL);
} else {
ret = iso_md5_write_scdbackup_tag(t, tag_block, 0);

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2011 Thomas Schmitt
* Copyright (c) 2009 - 2014 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -139,6 +139,7 @@ int iso_node_xinfo_dispose_cloners(int flag)
next = assoc->next;
free((char *) assoc);
}
iso_xinfo_cloner_list= NULL;
return(1);
}
@ -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,48 @@ 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";
case ISO_NAME_NOT_UCS2:
return "Filename not suitable for character set UCS-2";
case ISO_IMPORT_COLLISION:
return "File name collision during ISO image import";
case ISO_HPPA_PALO_INCOMPL:
return "Incomplete HP-PA PALO boot parameters";
case ISO_HPPA_PALO_OFLOW:
return "HP-PA PALO boot address exceeds 2 GB";
case ISO_HPPA_PALO_NOTREG:
return "HP-PA PALO file is not a data file";
case ISO_HPPA_PALO_CMDLEN:
return "HP-PA PALO command line too long";
default:
return "Unknown error";
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2011 Thomas Schmitt
* Copyright (c) 2009 - 2014 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -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:
@ -1046,6 +1048,7 @@ void iso_node_set_sort_weight(IsoNode *node, int w)
}
} else if (node->type == LIBISO_FILE) {
((IsoFile*)node)->sort_weight = w;
((IsoFile*)node)->explicit_weight = 1;
}
}
@ -1170,20 +1173,27 @@ int iso_node_is_valid_name(const char *name)
/* guard against the empty string or big names... */
if (name[0] == '\0')
return ISO_RR_NAME_RESERVED;
goto rr_reserved;
if (strlen(name) > LIBISOFS_NODE_NAME_MAX)
return ISO_RR_NAME_TOO_LONG;
/* ...against "." and ".." names... */
if (!strcmp(name, ".") || !strcmp(name, "..")) {
return ISO_RR_NAME_RESERVED;
}
if (!strcmp(name, ".") || !strcmp(name, ".."))
goto rr_reserved;
/* ...and against names with '/' */
if (strchr(name, '/') != NULL) {
return ISO_RR_NAME_RESERVED;
}
if (strchr(name, '/') != NULL)
goto rr_reserved;
return 1;
rr_reserved:;
/* # define Libisofs_debug_rr_reserveD */
#ifdef Libisofs_debug_rr_reserveD
fprintf(stderr, "libisofs_DEBUG: ISO_RR_NAME_RESERVED with '%s'\n", name);
#endif
return ISO_RR_NAME_RESERVED;
}
/**
@ -1203,8 +1213,12 @@ int iso_node_is_valid_link_dest(const char *dest)
}
/* guard against the empty string or big dest... */
if (dest[0] == '\0')
if (dest[0] == '\0') {
#ifdef Libisofs_debug_rr_reserveD
fprintf(stderr, "libisofs_DEBUG: ISO_RR_NAME_RESERVED by empty link target\n");
#endif
return ISO_RR_NAME_RESERVED;
}
if (strlen(dest) > LIBISOFS_NODE_PATH_MAX)
return ISO_RR_PATH_TOO_LONG;
@ -1428,6 +1442,8 @@ int iso_node_new_file(char *name, IsoStream *stream, IsoFile **file)
new->node.type = LIBISO_FILE;
new->node.name = name;
new->node.mode = S_IFREG;
new->from_old_session = 0;
new->explicit_weight = 0;
new->sort_weight = 0;
new->stream = stream;
@ -1725,6 +1741,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 +1790,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 +1837,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 +1889,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;
@ -2559,6 +2580,7 @@ int iso_node_set_ino(IsoNode *node, ino_t ino, int flag)
ret = iso_stream_set_image_ino(file->stream, ino, 0);
if (ret < 0 || ret == 1)
return ret;
/* ret == 0 means that the stream is not from loaded ISO image */
} else if (node->type == LIBISO_SYMLINK) {
symlink = (IsoSymlink *) node;
@ -2749,6 +2771,8 @@ int iso_node_cmp_ino(IsoNode *n1, IsoNode *n2, int flag)
}
/* @param flag bit0= delete isofs.cx rather than setting it
*/
int iso_file_set_isofscx(IsoFile *file, unsigned int checksum_index,
int flag)
{
@ -2758,9 +2782,14 @@ int iso_file_set_isofscx(IsoFile *file, unsigned int checksum_index,
char *valuept;
int i, ret;
valuept= (char *) value;
if (flag & 1) {
ret = iso_node_set_attrs((IsoNode *) file, (size_t) 1,
&names, value_lengths, &valuept, 4 | 8);
return ret;
}
for(i = 0; i < 4; i++)
value[3 - i] = (checksum_index >> (8 * i)) & 0xff;
valuept= (char *) value;
ret = iso_node_set_attrs((IsoNode *) file, (size_t) 1,
&names, value_lengths, &valuept, 2 | 8);
return ret;

View File

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

View File

@ -115,7 +115,7 @@ int rrip_add_PX(Ecma119Image *t, Ecma119Node *n, struct susp_info *susp)
PX[0] = 'P';
PX[1] = 'X';
if (t->rrip_1_10_px_ino || !t->rrip_version_1_10 ) {
if (t->opts->rrip_1_10_px_ino || !t->opts->rrip_version_1_10 ) {
PX[2] = 44;
} else {
PX[2] = 36;
@ -125,7 +125,7 @@ int rrip_add_PX(Ecma119Image *t, Ecma119Node *n, struct susp_info *susp)
iso_bb(&PX[12], (uint32_t) n->nlink, 4);
iso_bb(&PX[20], (uint32_t) px_get_uid(t, n), 4);
iso_bb(&PX[28], (uint32_t) px_get_gid(t, n), 4);
if (t->rrip_1_10_px_ino || !t->rrip_version_1_10) {
if (t->opts->rrip_1_10_px_ino || !t->opts->rrip_version_1_10) {
iso_bb(&PX[36], (uint32_t) n->ino, 4);
}
@ -153,11 +153,11 @@ int rrip_add_TF(Ecma119Image *t, Ecma119Node *n, struct susp_info *susp)
iso = n->node;
iso_datetime_7(&TF[5], t->replace_timestamps ? t->timestamp : iso->mtime,
t->always_gmt);
t->opts->always_gmt);
iso_datetime_7(&TF[12], t->replace_timestamps ? t->timestamp : iso->atime,
t->always_gmt);
t->opts->always_gmt);
iso_datetime_7(&TF[19], t->replace_timestamps ? t->timestamp : iso->ctime,
t->always_gmt);
t->opts->always_gmt);
return susp_append(t, susp, TF);
}
@ -294,29 +294,44 @@ int rrip_add_CL(Ecma119Image *t, Ecma119Node *n, struct susp_info *susp)
/**
* Convert a RR filename to the requested charset. On any conversion error,
* the original name will be used.
* @param flag bit0= do not issue error messages
*/
static
char *get_rr_fname(Ecma119Image *t, const char *str)
int iso_get_rr_name(IsoWriteOpts *opts, char *input_charset,
char *output_charset, int imgid,
char *str, char **name, int flag)
{
int ret;
char *name;
if (!strcmp(t->input_charset, t->output_charset)) {
if (!strcmp(input_charset, output_charset)) {
/* no conversion needed */
return strdup(str);
ret = iso_clone_mem(str, name, 0);
return ret;
}
ret = strconv(str, t->input_charset, t->output_charset, &name);
ret = strconv(str, input_charset, output_charset, name);
if (ret < 0) {
/* TODO we should check for possible cancelation */
iso_msg_submit(t->image->id, ISO_FILENAME_WRONG_CHARSET, ret,
"Charset conversion error. Can't convert %s from %s to %s",
str, t->input_charset, t->output_charset);
if (!(flag & 1))
iso_msg_submit(imgid, ISO_FILENAME_WRONG_CHARSET, ret,
"Charset conversion error. Cannot convert %s from %s to %s",
str, input_charset, output_charset);
/* use the original name, it's the best we can do */
name = strdup(str);
ret = iso_clone_mem(str, name, 0);
return ISO_FILENAME_WRONG_CHARSET;
}
return ISO_SUCCESS;
}
static
char *get_rr_fname(Ecma119Image *t, char *str)
{
int ret;
char *name = NULL;
ret = iso_get_rr_name(t->opts, t->input_charset, t->output_charset,
t->image->id, str, &name, 0);
return name;
}
@ -542,7 +557,7 @@ int aaip_add_AL(Ecma119Image *t, struct susp_info *susp,
int ret, done = 0, len, es_extra = 0;
uint8_t *aapt, *cpt;
if (!t->aaip_susp_1_10)
if (!t->opts->aaip_susp_1_10)
es_extra = 5;
if (*sua_free < num_data + es_extra || *ce_len > 0) {
*ce_len += num_data + es_extra;
@ -553,7 +568,7 @@ int aaip_add_AL(Ecma119Image *t, struct susp_info *susp,
return ISO_SUCCESS;
/* If AAIP enabled and announced by ER : Write ES field to announce AAIP */
if (t->aaip && !t->aaip_susp_1_10) {
if (t->opts->aaip && !t->opts->aaip_susp_1_10) {
ret = susp_add_ES(t, susp, (*ce_len > 0), 1);
if (ret < 0)
return ret;
@ -606,7 +621,7 @@ int rrip_add_ER(Ecma119Image *t, struct susp_info *susp)
{
unsigned char *ER;
if (!t->rrip_version_1_10) {
if (!t->opts->rrip_version_1_10) {
/*
According to RRIP 1.12 this is the future form:
4.3 "Specification of the ER System Use Entry Values for RRIP"
@ -851,7 +866,7 @@ int add_zf_field(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
zisofs file header when inquired)
*/
if (t->appendable && file->from_old_session)
if (t->opts->appendable && file->from_old_session)
will_copy = 0;
first_filter = first_stream = last_stream = iso_file_get_stream(file);
@ -1124,7 +1139,7 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
/* obtain num_aapt from node */
xipt = NULL;
num_aapt = 0;
if (t->aaip) {
if (t->opts->aaip) {
ret = iso_node_get_xinfo(n->node, aaip_xinfo_func, &xipt);
if (ret == 1) {
num_aapt = aaip_count_bytes((unsigned char *) xipt, 0);
@ -1160,7 +1175,7 @@ int add_aa_string(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
void *xipt;
size_t num_aapt= 0;
if (!t->aaip)
if (!t->opts->aaip)
return 1;
ret = iso_node_get_xinfo(n->node, aaip_xinfo_func, &xipt);
@ -1221,7 +1236,7 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t used_up,
su_size = 0;
/* If AAIP enabled and announced by ER : account for 5 bytes of ES */;
if (t->aaip && !t->aaip_susp_1_10)
if (t->opts->aaip && !t->opts->aaip_susp_1_10)
su_size += 5;
#ifdef Libisofs_with_rrip_rR
@ -1230,7 +1245,7 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t used_up,
#endif
/* PX and TF, we are sure they always fit in SUA */
if (t->rrip_1_10_px_ino || !t->rrip_version_1_10) {
if (t->opts->rrip_1_10_px_ino || !t->opts->rrip_version_1_10) {
su_size += 44 + 26;
} else {
su_size += 36 + 26;
@ -1246,17 +1261,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)) {
(t->opts->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 */
@ -1280,7 +1289,7 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t used_up,
/* "." or ".." entry */
if (!t->rrip_version_1_10)
if (!t->opts->rrip_version_1_10)
su_size += 5; /* NM field */
if (type == 1 && n->parent == NULL) {
@ -1291,12 +1300,12 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t used_up,
*/
su_size += 7 + 28; /* SP + CE */
/* ER of RRIP */
if (t->rrip_version_1_10) {
if (t->opts->rrip_version_1_10) {
*ce = 237;
} else {
*ce = 182;
}
if (t->aaip && !t->aaip_susp_1_10) {
if (t->opts->aaip && !t->opts->aaip_susp_1_10) {
*ce += 160; /* ER of AAIP */
}
/* Compute length of AAIP string of root node */
@ -1400,7 +1409,7 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
}
/* If AAIP enabled and announced by ER : Announce RRIP by ES */
if (t->aaip && !t->aaip_susp_1_10) {
if (t->opts->aaip && !t->opts->aaip_susp_1_10) {
ret = susp_add_ES(t, info, 0, 0);
if (ret < 0)
goto add_susp_cleanup;
@ -1442,18 +1451,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)) {
(t->opts->rr_reloc_flags & 1)) {
/* The dedicated relocation directory shall be marked by RE */
ret = rrip_add_RE(t, node, info);
if (ret < 0)
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)) {
@ -1752,7 +1755,7 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
/* "." or ".." entry */
/* write the NM entry */
if (t->rrip_version_1_10) {
if (t->opts->rrip_version_1_10) {
/* RRIP-1.10:
"NM" System Use Fields recorded for the ISO 9660 directory
records with names (00) and (01), used to designate the
@ -1792,12 +1795,12 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
* Note that SP entry was already added above
*/
if (t->rrip_version_1_10) {
if (t->opts->rrip_version_1_10) {
rrip_er_len = 237;
} else {
rrip_er_len = 182;
}
if (t->aaip && !t->aaip_susp_1_10) {
if (t->opts->aaip && !t->opts->aaip_susp_1_10) {
aaip_er_len = 160;
}
@ -1816,7 +1819,7 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
if (ret < 0) {
goto add_susp_cleanup;
}
if (t->aaip && !t->aaip_susp_1_10) {
if (t->opts->aaip && !t->opts->aaip_susp_1_10) {
ret = aaip_add_ER(t, info, 0);
if (ret < 0) {
goto add_susp_cleanup;

View File

@ -346,4 +346,13 @@ int read_zisofs_ZF(struct susp_sys_user_entry *zf, uint8_t algorithm[2],
uint8_t *header_size_div4, uint8_t *block_size_log2,
uint32_t *uncompressed_size, int flag);
/**
* Convert a RR filename to the requested charset. On any conversion error,
* the original name will be used.
* @param flag bit0= do not issue error messages
*/
int iso_get_rr_name(IsoWriteOpts *opts, char *input_charset,
char *output_charset, int imgid,
char *str, char **name, int flag);
#endif /* LIBISO_ROCKRIDGE_H */

View File

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

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

@ -241,8 +241,8 @@ ex:;
return retval;
}
int strnconv(const char *str, const char *icharset, const char *ocharset,
size_t len, char **output)
int strnconvl(const char *str, const char *icharset, const char *ocharset,
size_t len, char **output, size_t *out_len)
{
size_t inbytes;
size_t outbytes;
@ -278,7 +278,8 @@ int strnconv(const char *str, const char *icharset, const char *ocharset,
*ret = '\0';
iso_iconv_close(&conv, 0);
*output = malloc(ret - out + 1);
*out_len = ret - out;
*output = malloc(*out_len + 1);
if (*output == NULL) {
retval = ISO_OUT_OF_MEM;
goto ex;
@ -291,6 +292,15 @@ ex:;
return retval;
}
int strnconv(const char *str, const char *icharset, const char *ocharset,
size_t len, char **output)
{
size_t l;
return strnconvl(str, icharset, ocharset, len, output, &l);
}
/**
* Convert a str in a specified codeset to WCHAR_T.
* The result must be free() when no more needed
@ -667,6 +677,123 @@ int str2ucs(const char *icharset, const char *input, uint16_t **output)
return ISO_SUCCESS;
}
int str2utf16be(const char *icharset, const char *input, uint16_t **output)
{
int result;
wchar_t *wsrc_ = NULL;
char *src;
char *ret = NULL;
char *ret_ = NULL;
struct iso_iconv_handle conv;
int conv_ret = 0;
int direct_conv = 0;
size_t loop_counter = 0, loop_limit = 3;
size_t numchars;
size_t outbytes;
size_t inbytes;
size_t n;
if (icharset == NULL || input == NULL || output == NULL) {
return ISO_NULL_POINTER;
}
/*
Try the direct conversion.
*/
conv_ret = iso_iconv_open(&conv, "UTF-16BE", (char *) icharset, 0);
if (conv_ret > 0) {
direct_conv = 1;
src = (char *) input;
inbytes = strlen(input);
loop_limit = inbytes + 3;
outbytes = (2 * inbytes + 1) * sizeof(uint16_t);
ret_ = malloc(outbytes);
if (ret_ == NULL)
return ISO_OUT_OF_MEM;
ret = ret_;
} else {
/* Try via intermediate character set WCHAR_T.
*/
result = str2wchar(icharset, input, &wsrc_);
if (result == (int) ISO_SUCCESS) {
src = (char *)wsrc_;
numchars = wcslen(wsrc_);
inbytes = numchars * sizeof(wchar_t);
loop_limit = inbytes + 3;
ret_ = malloc((2 * numchars+1) * sizeof(uint16_t));
if (ret_ == NULL)
return ISO_OUT_OF_MEM;
outbytes = 2 * numchars * sizeof(uint16_t);
ret = ret_;
/* initialize iconv */
conv_ret = iso_iconv_open(&conv, "UTF-16BE", "WCHAR_T", 0);
if (conv_ret <= 0) {
free(wsrc_);
free(ret_);
}
} else if (result != (int) ISO_CHARSET_CONV_ERROR)
return result;
}
if (conv_ret <= 0) {
return ISO_CHARSET_CONV_ERROR;
}
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
while (n == (size_t) -1) {
/* The destination buffer is too small. Stops here. */
if (errno == E2BIG)
break;
/* An incomplete multi bytes sequence was found. We
* can't do anything here. That's quite unlikely. */
if (errno == EINVAL)
break;
/* The last possible error is an invalid multi bytes
* sequence. Just replace the character with a "_".
* Probably the character doesn't exist in UCS */
set_ucsbe((uint16_t*) ret, '_');
ret += sizeof(uint16_t);
outbytes -= sizeof(uint16_t);
if (!outbytes)
break;
/* There was an error with one character but some other remain
* to be converted. That's probably a multibyte character.
* See above comment. */
if (direct_conv) {
src++;
inbytes--;
} else {
src += sizeof(wchar_t);
inbytes -= sizeof(wchar_t);
}
if (!inbytes)
break;
/* Just to appease my remorse about unclear loop ends */
loop_counter++;
if (loop_counter > loop_limit)
break;
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
}
iso_iconv_close(&conv, 0);
/* close the UTF-16 string */
set_ucsbe((uint16_t*) ret, '\0');
if (wsrc_ != NULL)
free(wsrc_);
*output = (uint16_t*)ret_;
return ISO_SUCCESS;
}
static int valid_d_char(char c)
{
return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c == '_');
@ -1080,7 +1207,7 @@ uint16_t *iso_j_file_id(const uint16_t *src, int flag)
{
uint16_t *dot, *retval = NULL;
size_t lname, lext, lnname, lnext, pos, i, maxchar = 64;
uint16_t *dest = NULL;
uint16_t *dest = NULL, c;
LIBISO_ALLOC_MEM_VOID(dest, uint16_t, LIBISO_JOLIET_NAME_MAX);
/* was: 66 = 64 (name + ext) + 1 (.) + 1 (\0) */
@ -1120,7 +1247,7 @@ uint16_t *iso_j_file_id(const uint16_t *src, int flag)
/* Convert up to lnname characters of the filename. */
for (i = 0; i < lnname; i++) {
uint16_t c = src[i];
c = src[i];
if (valid_j_char(c)) {
dest[pos++] = c;
} else {
@ -1128,6 +1255,8 @@ uint16_t *iso_j_file_id(const uint16_t *src, int flag)
pos++;
}
}
if (pos > 0)
iso_handle_split_utf16(dest + (pos - 1));
if ((flag & 1) && lnext <= 0)
goto is_done;
@ -1145,6 +1274,7 @@ uint16_t *iso_j_file_id(const uint16_t *src, int flag)
pos++;
}
}
iso_handle_split_utf16(dest + (pos - 1));
is_done:;
set_ucsbe(dest + pos, '\0');
@ -1181,6 +1311,7 @@ uint16_t *iso_j_dir_id(const uint16_t *src, int flag)
set_ucsbe(dest + i, '_');
}
}
iso_handle_split_utf16(dest + (len - 1));
set_ucsbe(dest + len, '\0');
retval = ucsdup(dest);
ex:
@ -1225,12 +1356,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;
@ -1261,6 +1393,8 @@ uint16_t *ucsncpy(uint16_t *dest, const uint16_t *src, size_t n)
{
n = MIN(n, ucslen(src) + 1);
memcpy(dest, src, n*2);
if (n >= 2)
iso_handle_split_utf16(dest + (n - 2));
return dest;
}
@ -1354,6 +1488,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 +2209,56 @@ 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;
}
/* If an UTF-16 surrogate pair was split : Change to UTF-16 '_'.
(UCS-2 is promised to reserve 0xd800 to 0xdbff for UTF-16).
*/
void iso_handle_split_utf16(uint16_t *utf_word)
{
unsigned char *hb;
hb = (unsigned char *) utf_word;
if ((hb[0] & 0xfc) == 0xd8)
set_ucsbe(utf_word, '_');
}
int iso_clone_mem(char *in, char **out, size_t size)
{
if (in == NULL) {
*out = NULL;
return 1;
}
if (size == 0)
size = strlen(in) + 1;
*out = calloc(1, size);
if (*out == NULL)
return ISO_OUT_OF_MEM;
memcpy(*out, in, size);
return 1;
}
int iso_clone_mgtd_mem(char *in, char **out, size_t size)
{
if (*out != NULL)
free(*out);
return iso_clone_mem(in, out, size);
}

View File

@ -56,9 +56,16 @@ int iso_init_locale(int flag);
int strconv(const char *input, const char *icharset, const char *ocharset,
char **output);
/* Like strconv but processing len input bytes rather than strlen(input)
*/
int strnconv(const char *str, const char *icharset, const char *ocharset,
size_t len, char **output);
/* Like strnconv but also returning the number of bytes in *output.
*/
int strnconvl(const char *str, const char *icharset, const char *ocharset,
size_t len, char **output, size_t *out_len);
/**
* Convert a given string from any input charset to ASCII
*
@ -88,6 +95,22 @@ int str2ascii(const char *icharset, const char *input, char **output);
*/
int str2ucs(const char *icharset, const char *input, uint16_t **output);
/**
* Convert a given string from any input charset to UTF-16BE charset,
* used for HFS+ file identifiers.
* (UTF-16 differs from older UCS-2 by having multi word characters.)
*
* @param icharset
* Input charset. Must be supported by iconv
* @param input
* Input string
* @param output
* Location where the pointer to the ouput string will be stored
* @return
* 1 on success, < 0 on error
*/
int str2utf16be(const char *icharset, const char *input, uint16_t **output);
/**
* Create a level 1 directory identifier.
*
@ -220,6 +243,12 @@ uint16_t *ucscpy(uint16_t *dest, const uint16_t *src);
*/
uint16_t *ucsncpy(uint16_t *dest, const uint16_t *src, size_t n);
/**
* Check whether utf_word is the first surrogate word of a pair.
* If so, change it to UTF-16 character '_'.
*/
void iso_handle_split_utf16(uint16_t *utf_word);
/**
* Convert a given input string to d-chars.
* @return
@ -232,6 +261,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 +576,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 +606,25 @@ void *iso_alloc_mem(size_t size, size_t count, int flag);
}
/*
@param in Valid memory or NULL
@param out Returns valid memory or NULL
@param size Number of bytes to copy. 0 means strlen(in)+1 if not NULL.
@return 1 or ISO_OUT_OF_MEM
*/
int iso_clone_mem(char *in, char **out, size_t size);
/* Like iso_clone_mem but first freeing *out if not NULL
*/
int iso_clone_mgtd_mem(char *in, char **out, size_t size);
/* ------------------------------------------------------------------------- */
/* 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_*/