Compare commits

...

910 Commits

Author SHA1 Message Date
517a8d9d4a New API call iso_write_opts_set_rrip_tf_long() and date check for year 2156 limit to produce 17-byte timestamps 2025-06-24 17:33:07 +02:00
2d4dd99b46 Fixed a potential problem with .. directory record on big-endian CPUs 2025-06-24 13:29:00 +02:00
a485e91d1a Enhanced reporting with --enable-dir-rec-size-check 2025-06-24 13:26:33 +02:00
c843d41b0b Bug fix: The .. directory record exposed Rock Ridge properties of its grand grand parent. Caused by commit 4d0063f7 in 2009 which fixed the block address pointer of the .. record. 2025-06-24 13:21:38 +02:00
955a7cd3bb New API call iso_local_create_dev() 2025-04-16 09:19:10 +02:00
f314f3059b Removed accidentially introduced condition HAVE_SYS_TYPES_H 2025-04-12 11:17:24 +02:00
4f4741401e Added missing includes of sys/types.h for ssize_t 2025-04-12 11:11:25 +02:00
b9faf575a8 Bug fix: The last trailing slash in a symbolic link target was not written 2025-04-07 09:34:16 +02:00
fa19885131 Bug fix: Empty symolic link target components which represent add-on slashes were written with ROOT flag set 2025-04-07 09:33:30 +02:00
73698da6e3 Bug fix: When reading multiple slashes in symbolic link targets they were condensed to a single one if not marked by the SL ROOT-flag 2025-04-07 09:15:25 +02:00
84402913a3 Rectified license text of libiso_msgs.c 2025-04-06 09:11:34 +02:00
30fcd2d84b Added to configure.ac explicit checks for stdint.h, inttypes.h, stdlib.h because slibtool does not put them into ./configure by default 2025-03-24 08:51:23 +01:00
17d297b3de New configuration option --enable-dir-rec-size-check 2025-03-01 15:56:40 +01:00
24e3f44715 Bug fix: Symbolic links with xattr could cause unusable ISO filesystems. Thanks Paul von Behren. 2025-03-01 15:10:00 +01:00
59d10562b1 New API call iso_write_opts_set_gpt_with_gaps 2024-12-16 18:12:29 +01:00
b7c1e03ff7 New API calls iso_node_get_projid(), iso_node_set_projid(), iso_local_get_projid(), iso_local_set_projid() 2024-11-03 19:17:32 +01:00
72f0365458 Bug fix: Empty AAIP value spoiled decoding of all AAIP attributes 2024-10-16 14:04:59 +02:00
6a100a645d Clarified meaning of "ISO 9660:1999" as Enhanced Volume Descriptor of ECMA-119 4th Edition 2024-10-06 11:08:47 +02:00
eed1e64aed Corrected a comment at function aaip_get_lfa_flags 2024-09-14 17:07:26 +02:00
411d818bf8 New error ISO_LFA_NO_OPEN_LOCAL to distinguish open failure from ioctl failure 2024-09-08 12:11:36 +02:00
5937ffddd7 Fixed iso_util_encode_lfa_flags() in respect to attribute "F" 2024-09-08 12:01:27 +02:00
9ef7e7ffbe Marked the list of lfa flags by "settable", "superuser", "directory only" 2024-09-07 18:19:48 +02:00
8d9fcf658a Made filelist weight sorting deterministic with different qsort implementations. By Henrik Lindström. 2024-09-01 18:41:10 +02:00
3a43995fb5 Made ECMA-119 tree sorting deterministic with different qsort implementations. By Henrik Lindström. 2024-09-01 18:37:47 +02:00
efaab52265 New flag bit5 for iso_file_source_get_aa_string() and iso_image_set_ignore_aclea(), new flag bit7 for iso_local_get_lfa_flags() 2024-08-27 10:51:36 +02:00
622b5645f0 New flag bit2 for iso_local_get_lfa_flags() and iso_local_set_lfa_flags() 2024-08-25 15:17:15 +02:00
c4769f333e Separated errors about Linux file attributes from those of xattr and ACL 2024-08-25 10:55:32 +02:00
70827242b2 Improved format of error messages from aaip-os-linux.c 2024-08-18 16:16:21 +02:00
443743d2d8 New API call iso_util_get_effective_lfa_mask() 2024-08-11 12:30:50 +02:00
d717613c93 Avoided touching local file attributes if no change would happen 2024-08-08 10:33:35 +02:00
08792a4711 Corrected a memory infringement in iso_util_decode_lfa_flags() 2024-08-07 15:19:15 +02:00
290ef77254 Improved handling of dead symbolic links in aaip_get_attr_list() 2024-08-06 19:48:16 +02:00
7fc7d65e05 New return value 4 of iso_local_get_lfa_flags(): file does not have lfa_flags 2024-08-06 19:05:07 +02:00
cc1884a0cb Changed in ./configure --enable-linux-attr-flags to --enable-lfa-flags 2024-07-23 17:01:42 +02:00
843587a7b4 Small corrections and adjustments to the recent commits 2024-07-20 13:28:11 +02:00
99700ac94b New API call iso_util_get_lfa_masks() 2024-07-19 22:24:02 +02:00
fbcacafb49 Fixed iso_local_set_lfa_flags() 2024-07-19 22:20:56 +02:00
d78028fca4 New API calls iso_local_get_lfa_flags(), iso_local_set_lfa_flags(), iso_node_get_lfa_flags(), iso_node_set_lfa_flags(), iso_util_decode_lfa_flags(), iso_util_encode_lfa_flags() 2024-07-16 15:05:11 +02:00
425f5d0fdd Removed germanisms about "eventual" from API description 2024-07-12 16:28:43 +02:00
78708015af Improved warning messages about symbolic links and special files in ISO 9660:1999 tree 2024-05-19 18:35:40 +02:00
57fcd4bfbb Fixed assessment of MIPS boot equipment which was broken by commit 405f0f0 2024-05-18 21:29:32 +02:00
483a68aaf2 Avoided use of uninitialized variables which was introduced by commit d9c548d 2024-05-18 13:42:37 +02:00
8ffd3b381b Clarified the API description of NULL data in iso_write_opts_set_system_area() 2024-05-12 21:56:15 +02:00
d9c548dbfc Bug fix: File path of imported BIOS boot image was forgotten when it gets overwritten by a file of the same name. Thanks Brian C. Lane. 2024-05-12 13:56:29 +02:00
8ed27c6255 Enabled up to 8 appended GPT partitions and improved their number mapping 2024-05-10 17:25:07 +02:00
405f0f04d4 Improved size estimation and property assessment of El Torito hidden boot images 2023-11-20 11:42:41 +01:00
8a8439768c Clarified in the description of iso_image_set_boot_image() the meaning of pseudo-path parameters "start" and "size" 2023-11-20 09:15:18 +01:00
9ec998f9fc Updated copyright year in README 2023-06-09 19:57:42 +02:00
8a4f1f88ae Explicitely included unistd.h in all source file which use ssize_t 2023-06-09 19:54:50 +02:00
09ec2fa4b7 Bug fix: On non-GNU/Linux systems ssize_t was not defined in rockridge.h . Report and fix proposal by Rui Chen. 2023-06-09 19:48:54 +02:00
5a867c43ab Version leap to 1.5.7 2023-06-07 19:10:34 +02:00
170318c42e Updated change log 2023-06-07 13:32:06 +02:00
c2d17b1c4b Version leap to 1.5.6 2023-06-07 13:28:22 +02:00
cdc7f52187 Reduced number of warnings about special files or symlinks in Joliet 2023-04-14 17:47:07 +02:00
bd415402f4 New API call iso_write_opts_set_max_ce_entries() 2023-01-22 16:03:44 +01:00
7109ba5675 Prevented endless CE loops when reading a very bad ISO fileystem 2023-01-11 12:06:28 +01:00
d35435b5a0 Bug fix: Size of further CE area was calculated wrong if its CE entry ended exactly at a block boundary 2022-12-13 09:53:27 +01:00
acb4bd143c Bug fix: Freshly cloned data files from imported image were not marked as
imported
2022-10-27 17:37:58 +02:00
71772baab7 Fixed assessment of omit_version_numbers and no_force_dots 2022-10-07 11:14:51 +02:00
83e5832ed0 New API calls iso_assess_written_features(), iso_read_image_feature_named(), iso_read_image_features_text() 2022-09-20 09:51:39 +02:00
9b7ccc9727 Improved error messages in case of failing Linux-specific ACL or xattr functions 2022-09-20 09:28:06 +02:00
c6cb7dfa3e Widened the lseek capacity determination to SEEK_SET with wanted size 2022-05-30 18:38:54 +02:00
ad55ec78e4 Avoided automatic MBR partition type 0x00 with iso_write_opts_set_part_like_isohybrid() if partitions do not overlap 2022-05-13 10:52:39 +02:00
011e2e85e6 Allowed lseekable device files with iso_tree_add_new_cut_out_node(). Proof-of-concept by Ivan Shmakov. 2022-04-26 12:12:15 +02:00
f457a4f8b9 Added missing stream type names to a diagnostic function 2022-04-26 12:06:18 +02:00
2af17490a0 Bug fix: The lseek methods of IsoFileSource for local filesystem and loaded ISO returned libisofs error codes as positive off_t numbers 2022-04-26 12:03:53 +02:00
da00291519 Let the original isohybrid GPT obey system_area() option bit 17: GPT writable 2022-04-23 09:32:44 +02:00
1d61b518b5 Bug fix: iso_write_opts_set_part_like_isohybrid() did not cause a MBR partition table if the partitions are data files in the ISO rather than appended 2022-04-23 09:30:34 +02:00
99251ade08 Avoid to overwrite the loaded MBR partition table just because partition offset is 16 2022-04-23 09:17:08 +02:00
da8e3e66e7 Exempted MBR partitions of type 0xEE from being ignored due to wrong size 2022-04-22 13:39:56 +02:00
3e61a61a21 Updated URLs, build instructions, and copyright in README file 2021-10-28 19:44:26 +02:00
80a0691660 Removed unneeded configure.ac macro AC_C_BIGENDIAN 2021-09-02 20:04:16 +02:00
1c4c04d4e2 New iso_write_opts_set_system_area() option bits 16: GPT "Legacy BIOS bootable" and 17: GPT writable 2021-05-25 21:10:28 +02:00
75499bcda9 Silenced a warning on 32 bit about value ISO_ZISOFS_V1_LIMIT too large for int 2021-03-12 09:37:07 +01:00
9e389186f7 Leave prediction of first CE gap to susp_*_to_ce() functions 2021-02-28 17:21:35 +01:00
7d248c46e1 Ignore mad MBR partitions which extend outside of medium size 2021-02-28 16:16:18 +01:00
98aea0c18a Heuristic fix for a new problem introduced by commit 058f18d 2021-02-03 13:31:25 +01:00
058f18d37a Bug fix: Large amounts of AAIP data or many long file names could cause with zisofs an unreadable filesystem after the warning "Calculated and written ECMA-119 tree end differ" 2021-02-01 18:46:34 +01:00
5add62bda0 Version leap to 1.5.5 2021-01-30 20:44:47 +01:00
2d1fec2569 Updated change log 2021-01-30 13:13:59 +01:00
4219bf4950 Version leap to 1.5.4 2021-01-30 13:12:35 +01:00
2a20e93b13 Small correction to commit 6241141 2020-12-07 20:59:14 +01:00
62411411db New API calls iso_read_image_features_tree_loaded() and iso_read_image_features_rr_loaded() 2020-12-07 18:02:24 +01:00
8f3ff65c04 Corrected size of GPT protective MBR partition with multi-session emulation 2020-11-26 11:49:58 +01:00
c068a19a8c New API call iso_read_opts_set_joliet_map(), new default joliet_map=stripped 2020-11-22 14:14:49 +01:00
cece6fb371 Bug fix: Appended APM partitions without HFS+ production had start and size 1 2020-11-15 15:23:03 +01:00
29cc5c8d31 Prevented writing of undesired bytes in make_sun_disk_label() (commit b0230b6) 2020-11-14 09:24:11 +01:00
92af0c9752 Adjusted fix 7e3b01b after learning that the bug stems from b0230b6 (unreleased) 2020-11-13 21:46:05 +01:00
daaee5e7e6 Fixed access to packed members of struct hfsplus_volheader. Thanks Felipe Franciosi. 2020-11-13 19:24:13 +01:00
7e3b01b53c Bug fix: Apple Partition Map entries wrote uninitialized data 2020-11-13 19:02:07 +01:00
1d5566f8bb Changed Public contact from libburn-hackers@pykix.org to bug-xorriso@gnu.org 2020-11-13 18:57:30 +01:00
ac9d55330d Fixed a new bug introduced with previous commit 2020-11-07 10:46:15 +01:00
b0687643c5 Bug fix: El Torito production failed if no catalog name was given and the boot image path contains no slash 2020-11-07 10:31:52 +01:00
5a98a4cda5 Corrected declaration of ziso_add_osiz_filter(). (Lapse in commit b107443) 2020-10-31 14:01:09 +01:00
b7a90c5194 Corrected description of new call iso_zisofs_ctrl_susp_z2() 2020-10-29 09:24:47 +01:00
8d70c75d4a Added doc/zisofs2_format.txt to EXTRA_DIST 2020-10-29 09:16:58 +01:00
9605bbe748 New API call iso_zisofs_ctrl_susp_z2() 2020-10-29 09:11:11 +01:00
46186e5f06 Added Z2 System Use Entry Format to zisofs2 specs 2020-10-29 08:31:31 +01:00
2ac62f0cac Fixed header size of ZF entries made for zisofs2 files compressed by libisofs 2020-10-29 08:23:15 +01:00
dc61e7d298 New flag bits 8 to 15 in API call iso_node_zf_by_magic() 2020-10-27 12:17:26 +01:00
d5ffecf2f5 Silenced a compiler warning if zlib is not enabled 2020-10-26 19:39:45 +01:00
80449f0dc9 New API calls iso_stream_zisofs_discard_bpt() and iso_image_zisofs_discard_bpt() 2020-10-25 16:59:32 +01:00
cc2e0e32a3 New iso_zisofs_ctrl parameters bpt_discard_file_blocks , bpt_discard_free_ratio 2020-10-22 13:22:13 +02:00
239ba69925 Accepting zisofs2 algorithms 2 to 5 for ZF by magic, but not for decompression 2020-10-18 16:46:44 +02:00
2ca3b292fb New iso_zisofs_ctrl parameter .block_number_target 2020-10-17 14:40:24 +02:00
f291e37ec1 Fixed wrong start block pointer of zisofs2 compression 2020-10-15 14:13:38 +02:00
b107443769 Implemented production and reading of zisofs2 for files larger than 4 GiB - 1. New API call iso_stream_get_zisofs_par(). New struct iso_zisofs_ctrl version 2. 2020-10-14 20:19:11 +02:00
d297ce3aed Prevented time rollover outside year intervals 1900-2155 and 1-9999 2020-09-21 21:17:20 +02:00
f962d0da66 Bug fix: Big-Endian MIPS Volume Header boot file size was rounded up to full 2048. Thanks René Rebe. 2020-07-07 12:31:52 +02:00
b0230b6ac8 Changed strncpy() to memcpy() in order to please static analyzers 2020-07-07 12:23:20 +02:00
69e332d17a New error code ISO_HFSPLUS_TOO_MANY_FILES instead of ISO_MANGLE_TOO_MUCH_FILES 2020-06-13 10:17:32 +02:00
6ca841e002 Reacted on compiler warnings of Debian Sid 2020-06-13 09:56:31 +02:00
c84f6ae689 Removed a germanism from description of iso_image_get_session_md5 2020-06-13 09:55:06 +02:00
ac248877a2 Re-enabled variable LT_RELEASE in configure.ac. Disabling was unintentional. 2019-11-26 11:24:23 +01:00
c1d9639dba Switched to usage of libjte-2.0.0 2019-11-24 13:19:07 +01:00
773be790e8 Fixed more spelling errors found by fossies.org with codespell 2019-10-30 20:37:24 +01:00
dc3d82cf36 Fixed spelling errors found by fossies.org with codespell 2019-10-28 15:56:58 +01:00
560c11617e Updated change log 2019-10-27 15:03:35 +01:00
fa43a5a25c Version leap to 1.5.3 2019-10-27 15:02:29 +01:00
4d8a467e1a Updated changelog. 2019-10-26 15:46:31 +02:00
65c4dce69a Version leap to 1.5.2 2019-10-26 15:44:16 +02:00
fe98b35afb Made sure that iso_image_get_bootcat() cannot return non-zero size with NULL content 2019-08-13 10:13:18 +02:00
130b46cf71 New flag bit2 of iso_node_set_acl_text() to be verbous about failures 2019-07-24 16:11:50 +02:00
eb7dc408e0 Added Alpha to table of content of boot sectors description 2019-07-24 16:06:21 +02:00
a5e209265d Putting doc/boot_sectors.txt into release tarball 2019-04-22 10:30:02 +02:00
458ab43ecd New API call iso_nowtime() 2019-04-18 10:56:01 +02:00
4b21386e82 Bug fix: SIGSEGV happened if options bit 14 of iso_write_opts_set_system_area() is set and no El Torito boot image is defined 2019-04-18 10:49:40 +02:00
c62d9d7b1b Replaced inclusion of version numbers from autotools by those from libisofs.h 2019-04-07 17:31:38 +02:00
3aab1cafc5 Disabled autotools macro AM_MAINTAINER_MODE on advise of Ross Burton 2019-04-07 10:41:49 +02:00
8fbc2fcdfd Made libisofs ready for building out-of-source. Thanks Ross Burton. 2019-04-05 18:04:46 +02:00
aed8bda955 New API calls iso_write_opts_set_part_type_guid(), iso_write_opts_set_iso_type_guid() 2019-02-18 12:47:09 +01:00
e1097dbb5d Changed interface of helper function iso_tell_max_part_range() 2019-01-15 19:07:01 +01:00
a1e75003b5 Bug fix: Appending partitions 5 to 8 caused damaged ISO filesystems if not for SUN disk label 2019-01-15 16:26:56 +01:00
4064a7e0ee Bug fix: Multi-session emulation spoiled GPT production "GPT partitions ... overlap". Regression towards 1.4.8 2019-01-10 20:15:44 +01:00
96261585f1 Bug fix: Appended GPT partitions were not covered by the protective MBR partition 2019-01-10 09:21:43 +01:00
01415ae208 New report line with iso_image_report_el_torito() "El Torito hdsiz/512:" 2018-11-05 14:06:09 +01:00
241b9ea832 Corrected and updated copyright statements 2018-10-06 20:40:08 +02:00
6a6343c146 Updated copyright dates in COPYING and README 2018-09-24 10:13:12 +02:00
a63b16f7da Updated change log 2018-09-16 15:01:42 +02:00
31c4c26567 Version leap to 1.5.1 2018-09-16 15:00:17 +02:00
6b31667ee4 Updated changelog. 2018-09-16 10:40:21 +02:00
066c6f685d Fixed failure to build on NetBSD because of undeclared variable 2018-09-16 10:37:49 +02:00
e317a8d93e Updated changelog. 2018-09-15 08:55:07 +02:00
d3c17d0555 Version leap to 1.5.0. 2018-09-15 08:50:35 +02:00
69c8c543a9 Improved message at image load time about hidden El Torito images for EFI 2018-06-10 19:51:47 +02:00
f39d4eefee Putting user defined padding after appended partitions 2018-06-04 09:35:01 +02:00
848e039e6d Preferring Linux include file sys/xattr.h over attr/attr.h 2018-05-18 17:20:24 +02:00
c5a9cc56e3 Changed bug fix 615dc7e997 of Mar 30 13:51:21 2018 +0200 2018-05-01 12:43:11 +02:00
310612174b Bug fix: Long Joliet names with leading dot were mangled one char too short 2018-03-31 18:20:55 +02:00
ad843f1723 Bug fix: Long Joliet names without dot were mangled with one character too many 2018-03-31 14:14:33 +02:00
615dc7e997 Bug fix: Add-on sessions with partition offset claimed too many blocks as size. Regression of version 1.4.8. 2018-03-30 13:51:21 +02:00
a936409a82 Fixed failure to compile with experimental Libisofs_appended_partitions_inlinE 2017-11-22 14:30:08 +01:00
580b154773 Adapted iso_node_merge_xattr to handling of all namespaces 2017-10-31 13:33:53 +01:00
1da3b17233 Changed a comment in Linux OS adapter 2017-10-31 13:30:26 +01:00
633b4d5f72 Updated project mail addresses 2017-10-23 10:39:48 +02:00
4b031b58ea New flag bit7 with iso_local_set_attrs() to avoid unnecessary write attempts. New return value 2 of IsoFileSource.get_aa_string() and iso_local_get_attrs(). New API calls iso_image_was_blind_attrs(), iso_local_set_attrs_errno(). 2017-10-23 10:36:10 +02:00
7d45c88cff New API call iso_image_get_ignore_aclea(),
new iso_image_set_ignore_aclea() and iso_file_source_get_aa_string() flag bit3 to import all xattr namespaces
2017-10-07 16:51:07 +02:00
79baab3fc9 Fixed a harmless lapse with static array initialization 2017-09-22 20:42:57 +02:00
53b2d6dcd7 Bug fix: Reading beyond array end for HFS+ production caused SIGSEGV with FreeBSD 11 CLANG -O2. Thanks ASX of GhostBSD. 2017-09-22 17:26:02 +02:00
874dc16d92 Fixed a message typo found by lintian 2017-09-16 10:40:35 +02:00
34e35865fe Silenced harmless compiler warning -Wimplicit-fallthrough 2017-09-15 22:29:02 +02:00
ce831f111c Updated change log 2017-09-12 21:53:42 +02:00
48ee49a7e0 Version leap to 1.4.9 2017-09-12 21:48:59 +02:00
bdfd4c4a37 Updated changelog. 2017-09-12 12:05:32 +02:00
dfc6de9f79 Version leap to 1.4.8. 2017-09-12 11:58:56 +02:00
7234425502 Updated changelog. 2017-09-12 11:51:16 +02:00
4e5a54c2f9 Swapped at recognition time the precendence of MBR properties "isohybrid" and "protective-msdos-label" 2017-09-09 16:36:43 +02:00
028f9275d3 Throw error if imported_iso interval would be overwritten by multi-session 2017-08-26 11:47:14 +02:00
cace41ec16 Enabled partition intervals with source "imported_iso" with ISO growing 2017-08-24 12:19:54 +02:00
e599a575dc Closed a memory leak about RRIP CL following 2017-08-21 19:43:19 +02:00
78b0a7b111 Disallowed RRIP CL chaining in order to break any endless loops. Debian bug 872761. Thanks Jakub Wilk and American Fuzzy Lop. 2017-08-21 19:41:20 +02:00
a7152f5794 Correcting previous commit for supporting multi-session 2017-08-21 12:34:13 +02:00
2a64d89e6e Refuse to read CE data blocks from after the end of ISO filesystem 2017-08-19 16:55:08 +02:00
31088d9acc Avoid to read blocks from start of CE area which do not belong to the given file 2017-08-19 14:54:23 +02:00
91490d5f34 Preventing use of zero sized SUSP CE entry which causes SIGSEGV. Debian bug 872590. Thanks Jakub Wilk and American Fuzzy Lop. 2017-08-19 11:08:02 +02:00
661b68ce8c Preventing buffer overflow with AAIP AL entry of insufficient size. Debian bug 872545. Thanks Jakub Wilk and American Fuzzy Lop. 2017-08-18 14:56:50 +02:00
16bde11076 Preventing memory leak caused by RRIP SL entry without PX entry that marks the file as symbolic link 2017-08-18 11:11:05 +02:00
36c8800ff3 Preventing buffer underread with empty RRIP SL component. Debian bug 872475. Thanks Jakub Wilk and American Fuzzy Lop. 2017-08-18 10:56:59 +02:00
860a91dd2f Preventing NULL dereference if root directory bears a RRIP RE entry 2017-08-17 08:49:28 +02:00
280108d2d5 Updated change log 2017-08-14 18:08:48 +02:00
1e40ed3fab Bug fix: Keeping and patching of loaded boot images failed. Regression by version 1.4.4. 2017-08-14 17:51:05 +02:00
e19a338a09 Re-added two empty lines which were lost by previous commit 2017-08-13 14:51:39 +02:00
c6e4035918 Added boot sector knowledge gained from Natalia Portillo 2017-08-13 13:34:53 +02:00
18ab6019bc Let ISO size cover appended partitions if --protective-msdos-label or nonzero -partition_offset is given 2017-07-02 15:11:20 +02:00
6282bbc0bc Bug fix: Bit 15 of iso_write_opts_set_system_area did not work with generic MBR 2017-06-29 23:06:07 +02:00
d7737e3ed5 Removed ban on reading El Torito platform ids other than 0 and 0xef 2017-06-03 20:23:54 +02:00
fb8697081b Reacted on harmless compiler warning about uninitialized variable. 2017-04-25 12:11:33 +02:00
0e7300b1a8 Clarified meaning of MBR partition boot flag 2017-04-10 10:02:05 +02:00
94e4bfb42b Adapted recognizing of partition offset to the changes of rev afb10aa / 1348 2017-04-09 20:58:45 +02:00
86f6ffc9c9 Let iso_mbr_part_type 0xee override ban on 0xee without GPT 2017-03-19 11:14:49 +01:00
5600f3d726 When deciding boot flag, consider MBR partition slot empty only if entirely 0 2017-02-27 18:27:59 +01:00
e66b9bfe0c New API call iso_write_opts_set_iso_mbr_part_type() 2017-02-27 09:59:34 +01:00
094b3f7546 Updated copyright year in system_area.c 2017-01-24 13:00:11 +01:00
5c1c5cd964 Bug fix: Appended partitions of size >= 4 GiB led to abort with error message "FATAL : ISO overwrite". Thanks to Sven Haardiek. 2017-01-24 10:43:10 +01:00
215280448f Bug fix: Protective MBR for GPT could emerge with boot flag set. 2017-01-03 12:54:54 +01:00
3043b5f660 Enabled recognition of partition offset of grub-mkrescue-sed.sh mode "gpt_appended" 2016-12-25 15:46:11 +01:00
afb10aac3b Claiming full output size in first PVD if partition offset is non-zero 2016-12-25 10:05:26 +01:00
76181d0aa3 Restricted volume size of PVD with non-zero partition offset to filesystem size even if the first PVD claims the whole output size 2016-12-25 10:00:07 +01:00
8ec75eea6a Bug fix: Non-SUSP data in System Use Area prevented image loading if Rock Ridge was enabled. Thanks to Jonathan Dowland. 2016-11-23 22:52:11 +01:00
01020ef544 Committed missing part of rev dc6cd94/1342 2016-11-23 22:07:21 +01:00
2961bdef9f Updated change log 2016-11-13 10:20:24 +01:00
ed209e0b6e Mentioned Vladimir Serbinenko in libisofs copyright list 2016-11-13 10:13:47 +01:00
dc6cd946ba New API calls el_torito_set_full_load(), el_torito_get_full_load() 2016-11-13 10:05:18 +01:00
c51efce8d1 Bug fix: iso_read_opts_set_no_rockridge() did not prevent reading of root SUSP 2016-11-13 09:52:25 +01:00
8bf32d8d14 Prepared some of the documentation for move to dev.lovelyhq.com 2016-11-13 09:39:53 +01:00
561e2a6aaa Version leap to 1.4.7 2016-09-16 20:58:19 +02:00
e7dd325ff6 Version leap to 1.4.6. 2016-09-16 11:45:12 +02:00
0447496710 Updated changelog. 2016-09-16 11:07:20 +02:00
496b8051c5 Bug fix: Interpretation of 17 digit timestamps was wrong. 2016-09-13 20:10:17 +02:00
63c074b0aa Changed severity of ISO_FILE_TOO_BIG from WARNING to FAILURE. 2016-09-12 18:01:14 +02:00
2be47f9af8 Bug fix: SIGSEGV by NULL when a data file was larger than ISO level allows. 2016-09-12 17:58:13 +02:00
bf5678c6d4 Removed obsoleted doxygen.conf tags XML_SCHEMA, XML_DTD, SHOW_DIRECTORIES,
HTML_ALIGN_MEMBERS. Corrected EXAMPLE_PATH.
Corrected a few comments which caused valid doxygen complaints.
2016-08-29 17:00:32 +02:00
9d64318502 Corrected understanding of relation of RFC 4122 and UEFI GUID.
Thanks Andrei Borzenkov.
2016-08-14 22:24:53 +02:00
866f647fad New API calls iso_generate_gpt_guid() and +iso_write_opts_set_gpt_guid(). 2016-08-12 18:18:47 +02:00
2f134dcdcb Eased re-enabling of libtool --silent at bootstrap time 2016-08-11 12:08:18 +02:00
b14ee71d51 Setting El torito boot catalog file timestamps to Ecma119Image.now. 2016-08-07 21:11:08 +02:00
c5c9d4e7bf Setting Ecma119Image.now to maximum of effective olume creation date and
volume modification date.
2016-08-07 10:48:03 +02:00
6321ed4d97 Made isohybrid MBR id reproducible if vol_modification_time or vol_uuid are set 2016-08-05 20:59:17 +02:00
188e36178b Reacted on some of the complaints of codespell 2016-07-22 16:03:51 +02:00
cbfa9afcf1 Treating OpenBSD like NetBSD. Thanks to SASANO Takayoshi. 2016-07-21 11:44:49 +02:00
cb519b3692 Reacted on compiler warning of Debian Sid. (By accident the wrong code was
equivalent to the correct code.)
2016-07-03 18:06:40 +02:00
8407d9e936 Updated ChangeLog 2016-07-01 21:19:19 +02:00
d482eb4c96 Version leap to 1.4.5 2016-07-01 19:58:26 +02:00
1786ceb276 Version leap to 1.4.4 2016-07-01 19:53:15 +02:00
f51fc50356 Updated changelog 2016-07-01 09:50:04 +02:00
02de4570d1 Included <unistd.h> in aaip_0_2.h to fix a build time issue with musl libc.
Thanks to Baruch Siach.
2016-05-24 13:07:00 +02:00
2a41b4817c Removed option --silent from libtool runs 2016-04-27 16:44:27 +02:00
9440e3061c Recognizing SUN Sparc Disk Label of ISOs smaller than 300 kB. 2016-04-25 11:55:57 +02:00
122dfe7b87 Re-instated recognition of libisofs PReP which was broken by rev 1295. 2016-04-24 10:38:45 +02:00
03662f0832 Recognizing the newly introduced consequences of protective msdos label
with alternative grub-mkrescue boot layouts.
2016-04-20 20:11:57 +02:00
eb09bcf9e5 Prevented option --version-script with linker run of xorriso. By Matthias Klose. 2016-04-19 09:17:34 +02:00
5880636a50 Prevented appended partition from being marked twice in GPT if it is used as
El Torito boot image.
2016-03-31 20:26:36 +02:00
b5fb98a2a3 Bug fix: Oversized text in ISO_SYSAREA_REPORT_DOC_ALPHA.
Thanks to Etienne Bergeron.
2016-03-30 21:35:53 +02:00
b269557743 Bug fix: At image loading time GRUB2 MBR was not recognized if the partition
table is not the protective one as described by UEFI.
2016-03-23 11:24:36 +01:00
0fd7d4d7eb Added "extern C" to libisofs.h 2016-03-15 21:26:06 +01:00
d8dca37d65 Replaced unused timezone parameter of gettimeofday() by NULL 2016-03-10 21:04:48 +01:00
cd84f0927f Introduced image size tolerance of 300 kB in order to recognize SUN Disk Label
that was generated by genisoimage -B "...".
2016-02-27 15:12:11 +01:00
477bbb89bb Fixed typo "occured" -> "occurred" 2016-02-05 13:52:26 +01:00
31fcdc0ba6 New API calls iso_write_opts_set_appended_as_apm(), iso_write_opts_set_part_like_isohybrid() 2016-02-05 10:47:04 +01:00
7c05d2a865 Enabled use of --interval:appended_partition_ with ISO growing. 2016-01-20 11:35:29 +01:00
3d15642307 Preventing production of surplus isohybrid MBR partition for BIOS boot image.
The problem was introduced by rev 1299.
2016-01-17 16:28:40 +01:00
872b5c6c67 New bit15 with options of iso_write_opts_set_system_area() to enforce
MBR bootable/active flag.
2016-01-01 18:17:40 +01:00
ec35bb21c0 Provisory new pseudo path for El Torito boot images:
--interval:appened_partition_N:all::
2015-12-30 18:56:32 +01:00
93f3cb1823 Another fix for Libisofs_mjg_boot_for_grub2 with original grub-mkrescue options 2015-12-28 11:51:29 +01:00
fea7be5168 Fixed result of Libisofs_mjg_boot_for_grub2 with original grub-mkrescue options 2015-12-28 11:30:53 +01:00
bd25db9283 Experimental macro Libisofs_mjg_boot_for_grub2 for alternative partition layout 2015-12-27 16:07:27 +01:00
97eec6162c Bug fix: HFS+ directories could announce more children than they actually have. 2015-12-26 12:25:28 +01:00
17e8cb6697 Bug fix: The HFS+ filesystem was not marked by in GPT of GRUB2 hybrid layout. 2015-12-23 20:49:13 +01:00
9e01d3654e Experimental macros Libisofs_protective_msdos_plus_boot_dummY and
Libisofs_pmpbd_on_lba0 to test augmentation of GRUB2 protective msdos label.
2015-12-22 14:24:08 +01:00
009ce1be8f Bug fix: When reading an ISO filesystem, the presence of
system area options flag bit0 (-protective-msdos-label)
         was not recognized if a partition is appended.
2015-12-22 12:25:50 +01:00
c79299ba08 Bug fix: Options bit0 of iso_write_opts_set_system_area() was not forwarded
to image production if no system area data were given.
         This prevented xorrisofs option --protective-msdos-label from working.
2015-12-22 12:23:13 +01:00
b3701f0b18 Removed the false prediction that HFS+ would cause GPT. 2015-12-22 11:52:33 +01:00
83b864efd2 Clarified virtual sector size of El Torito. Changed germanoid use of "eventual". 2015-12-21 17:31:30 +01:00
cd0f57dd1a Bug fix: HFS+ production could cause MBR partition of type 0xEE without GPT. 2015-12-20 18:46:44 +01:00
4c9cb6b96b Coordinated expectations of build system and source code in respect to
loacl support for ACL and extended file attributes. (Rev 1288 actually
belongs to this commit.)
2015-12-15 11:04:49 +01:00
9c334891cf Silenced a warning about unused variable if no local extended file attributes
are enabled. (Previous commit should have been part of the next one.)
2015-12-15 11:01:01 +01:00
2f6103b783 Silenced a warning about unused variable if no local extended file attributes
are enabled.
2015-12-15 10:59:23 +01:00
f32ee7da83 Completed update of change log 2015-11-28 22:08:44 +01:00
52972811f8 Version leap to 1.4.3 2015-11-28 21:49:07 +01:00
089982022c Version leap to 1.4.2 2015-11-28 21:13:51 +01:00
a6316ff05c Updated changelog 2015-11-28 12:00:49 +01:00
02a972a2d7 Closed a memory leak during retrieval of xattr. 2015-10-15 17:32:58 +02:00
da8ad0d2aa Made clear that a freed pointer variable is not really used any more.
Coverity CID 17846.
2015-10-15 11:53:56 +02:00
79e6312397 Refactored error handling while encoding AAIP information.
Again Coverity CID 12564.
2015-10-15 08:38:56 +02:00
b3a183fceb Made sure that mangling name buffer of 40 bytes cannot overflow.
Coverity CID 12589.
2015-10-13 19:30:17 +02:00
355f1f7ea2 Avoided to have an unused variable with --disable-xattr. Coverity CID 12544. 2015-10-13 14:40:42 +02:00
57fd669d1d Fixed compile time warnings with configure --disable-xattr --disable-libac.
Instigated by Coverity CID 12543.
2015-10-13 14:28:34 +02:00
6047464b6b Revoking previous change. It differs from the handling of F_GETFL failure.
So O_NONBLOCK is intended to be nice to have but not mandatory.
2015-10-13 11:02:11 +02:00
e8b94e7b50 Checking the return value of fcntl(F_SETFL O_NONBLOCK). Coverity CID 12536. 2015-10-13 10:49:16 +02:00
49dd9dc993 Closed memory leaks with demo/demo -iso_read and updated.
Inspired by Coverity CID 12561.
2015-10-12 22:49:47 +02:00
93e1fc52d0 Closed memory leaks with demo/demo -iso_ms and updated.
Inspired by Coverity CID 12559 and 12560.
2015-10-12 19:45:46 +02:00
4838cd59a7 Closed more memory leaks with demo/demo -iso_modify. Coverity CID 12558. 2015-10-12 16:46:18 +02:00
d51b1738dd Closed memory leaks with demo/demo -iso_modify and updated it a bit.
Inspired by Coverity CID 12557.
2015-10-12 15:50:43 +02:00
6252ae2065 Overhauled demo/demo -iso_cat. Better error messages. Closed memory leaks.
Instigated by Coverity CID 12555.
2015-10-12 14:14:14 +02:00
cb1e56478a Initializing name truncation parameters of IsoReadOpts to prevent
failure of demo/demo -iso_cat, which does not load the ISO image.
2015-10-12 11:48:27 +02:00
05d0ee4a37 Fixed double free in case of error while looking up path in loaded ISO image. 2015-10-12 10:56:42 +02:00
c6aedc9eb5 Fixed double free introduced with rev 1233. 2015-10-11 19:57:36 +02:00
505bf23aa4 Made sure that missing boot catalog at image load time causes no SIGSEGV
by NULL. Coverity CID 12552.
2015-10-11 18:25:13 +02:00
ccef2f29da Avoiding NULL pointer dereference in case of unexpected file type.
Coverity CID 12550.
2015-10-11 17:36:30 +02:00
b904926443 Checking success of strdup(). Indirectly found by Coverity CID 12548. 2015-10-11 16:11:02 +02:00
7bdc4c96f5 Avoided to close unopened file pointer in case of error. Coverity CID 12546. 2015-10-11 15:18:03 +02:00
fa5e27458a Removed surplus test which was always true. Coverity CID 12539. 2015-10-11 11:02:54 +02:00
7c29a94ab6 Taking into respect the return value of a function which can fail.
Coverity CID 12595.
2015-10-11 10:15:38 +02:00
a4c1e04820 Removed assignment of an unused function result. Coverity CID 12594. 2015-10-11 09:49:15 +02:00
50132d4ff7 Added forgotten emergency exit with faulty MD5 tags. Coverity CID 12596. 2015-10-11 09:44:15 +02:00
4c1c1ea152 voided to have dead code ifndef Libisofs_with_aaip_acL. Coverity CID 12593. 2015-10-10 22:01:05 +02:00
a16d4a28f4 Explicitely set tm_isdst to 0 before calling timegm. Coverity CID 12592. 2015-10-10 21:33:08 +02:00
4633ea3bc8 Explicitely set tm_isdst to 0 before calling timegm. Coverity CID 12591. 2015-10-10 21:31:13 +02:00
430c005666 Corrected initial allocation size of a pointer array. Coverity CID 12588. 2015-10-10 16:47:15 +02:00
af55722830 Corrected allocation size of a pointer array. Coverity CID 12587. 2015-10-10 16:34:29 +02:00
d1da5718c7 Corrected allocation size of a pointer array. Coverity CID 12586. 2015-10-10 16:32:44 +02:00
afb2878773 Corrected allocation size of a pointer array. Coverity CID 12585. 2015-10-10 16:28:48 +02:00
4e7432c20f Removed unnecessary test for NULL. Coverity CID 12584. 2015-10-10 16:02:07 +02:00
7ef616f268 Delaying access to pointer until after NULL check. Coverity CID 12583. 2015-10-10 15:53:55 +02:00
d5f1eb9c65 Closed memory leaks with errors in ecma119_image_new(). Coverity CID 12582. 2015-10-10 15:21:27 +02:00
28b41bce2c Closed memory leaks with errors during creation of HFS+ filesystem.
Coverity CID 12581.
2015-10-10 14:54:06 +02:00
5ac3216933 Closed memory leak with lack of memory during retrieval of HFS+ names.
Coverity CID 12580.
2015-10-10 13:11:31 +02:00
05a2171e04 Closed memory leak with lack of memory during character set conversion.
Coverity CID 12579.
2015-10-10 12:29:01 +02:00
188a41f041 Closed memory leaks with faulty ACL text. Coverity CID 12578. 2015-10-10 12:19:28 +02:00
fbe7f1e89d Closed memory leak with assert error or memory shortage while creating
SL entry. Coverity CID 12576.
2015-10-10 11:48:52 +02:00
d04abdcfbd Closed memory leak with memory shortage while creating IsoSymlink object.
Coverity CID 12575.
2015-10-10 11:05:41 +02:00
a6542e5fa9 Closed memory leak with error while creating IsoFile object. Coverity CID 12574. 2015-10-09 20:42:08 +02:00
78d2c02ad8 Closed memory leak with error in iso_file_make_md5(). Coverity CID 12573. 2015-10-09 20:35:15 +02:00
48453ef1da Closed memory leaks with errors during ISO image import. Coverity CID 12572. 2015-10-09 20:07:29 +02:00
7928c4ec3f Closed memory leak with lack of memory during ISO image import.
Coverity CID 12571.
2015-10-09 19:44:46 +02:00
379e223a5c Cosmetic change in function return value. Coverity CID 12570. 2015-10-09 17:23:08 +02:00
e4750907e3 Removed unused opportunity to call static create_image() with NULL for bootimg.
Coverity CID 12569.
2015-10-09 15:53:29 +02:00
8f76b59541 Closed nasty memory leak with new API call iso_image_dir_get_node().
Coverity CID 12568.
2015-10-09 15:40:24 +02:00
0433b7ea75 Closed memory leak with lack of memory during character set conversion.
Coverity CID 12567.
2015-10-09 15:28:04 +02:00
d8fb8b26a6 Closed memory leak with lack of memory during character set conversion.
Coverity CID 12566.
2015-10-09 14:14:55 +02:00
b9ccdeda72 Closed memory leak with lack of memory during ISO image loading.
Coverity CID 12565.
2015-10-09 13:38:47 +02:00
d04f438ba1 Closed memory leak with Rock Ridge character set conversion failure.
Coverity CID 12562.
2015-10-09 13:25:42 +02:00
e35cb88328 Made sure that iso_file_get_old_image_sections() returns non-NULL only
if section_count > 0. Made sure that callers in libisofs expect all possible
outcome as announced by API description.
2015-10-09 12:03:14 +02:00
83fb614462 Closed memory leak in (improbable) case of error when attaching AAIP
attributes to IsoNode. Coverity CID 12564.
2015-10-09 11:03:38 +02:00
e5f6811795 Reacted on Coverity CID 12538. Mostly cosmetic. 2015-10-08 23:20:29 +02:00
f3b836194c Pleasing Coverity for the improbable case that a builtin error message
length exceeds 4095 bytes.
2015-10-08 23:02:06 +02:00
3a870d23e3 Consolidated maximum length of namespace names. Coverity CID 12590. 2015-10-08 22:40:37 +02:00
06ea46c8d5 Bug fix: Freeing wrong pointer in case of memory shortage. Coverty CID 12600. 2015-10-08 19:52:23 +02:00
d427a03192 Bug fix: Double free if a boot image has no extents. Coverity CID 12599. 2015-10-08 19:47:01 +02:00
2b6071b445 Bug fix: Double free if a boot image has no extents. Coverity CID 12598. 2015-10-08 19:43:08 +02:00
fc448e09c9 Bug fix: Double free if no charset WCHAR_T is available. Coverity CID 12597.
(previous was CID 12601)
2015-10-08 19:35:22 +02:00
7b7da47d86 Bug fix: Double free if no charset WCHAR_T is available. Coverity CID 12597. 2015-10-08 19:27:28 +02:00
01c7a0d5ec Accept Rock Ridge Creation time as ctime if no Attributes time is present. 2015-10-04 18:47:38 +02:00
905f4f898f Fixed SIGSEGV while image import. Introduced by rev 1216. 2015-09-28 20:39:12 +02:00
b9ec876c40 Preventing a theoretically possible negative array index in find_utf8_start() 2015-09-28 11:36:45 +02:00
72ef369a40 Let loaded image adjust truncate length regardless whether larger or
smaller than the current truncate length.
2015-09-27 18:03:18 +02:00
218e26c974 Bug fix: iso_node_get_name() of root node returned NULL pointer rather than
an empty string
2015-09-27 12:30:24 +02:00
395128ef5f New AAIP variable isofs.nt records name truncation parameters. 2015-09-25 19:07:53 +02:00
7a3560035a Rectified handling of oversized filenames by new API calls:
iso_image_set_truncate_mode, iso_image_get_truncate_mode,
iso_truncate_leaf_name, iso_image_set_node_name, iso_image_tree_clone,
iso_image_add_new_dir, iso_image_add_new_file, iso_image_add_new_special,
iso_image_add_new_symlink, iso_image_dir_get_node, iso_image_path_to_node,
2015-09-17 13:59:05 +02:00
7ac5b75748 Bug fix: Names read from Joliet tree where stripped of trailing ";1" 2015-09-07 13:17:08 +02:00
6c3dc3ce4a New API call iso_read_opts_set_ecma119_map(). 2015-08-17 21:52:33 +02:00
bdbaf81e9c Bug fix: zisofs compression caused SIGSEGV (by reading) with files larger than
524160 KiB.
2015-08-11 22:58:37 +02:00
c8ed18695f Restricted size of patchable boot images to 32 MB and prevented
stream filtering on such boot images.
2015-08-11 12:02:26 +02:00
d3fefe4735 Changed wrong use of "resp." in docs 2015-08-01 16:58:40 +02:00
6db3f6ca44 Still trying to get the correct mail address in commits. 2015-07-27 19:58:28 +02:00
bf19f73ea6 Test: Trying to get my user id back. 2015-07-27 19:51:55 +02:00
6947bfe5ec Sorted the data file content extents by ECMA-119 tree rather than
by the red-black tree which shall consolidate files with identical
source object. Discovered and repaired a flaw in transitivity of
iso_stream_cmp_ino().
2015-07-27 13:50:57 +02:00
94f8503b57 Excluded empty data files from being recognized as El Torito boot images
when an ISO gets loaded.
2015-05-23 15:43:39 +02:00
cb519e221e Silenced compiler warnings of NetBSD and Solaris. 2015-05-20 12:19:37 +02:00
d09a317f51 Updated ChangeLog 2015-05-17 22:58:32 +02:00
2beb0d001b Version leap to 1.4.1 2015-05-17 21:16:35 +02:00
6c9b81a474 Version leap to 1.4.0 2015-05-17 19:27:00 +02:00
393cc070f3 Included stdlib.h in libisofs/util.h to get off_t defined in FreeBSD. 2015-05-17 17:08:04 +02:00
006caa2fd2 Updated changelog. 2015-05-17 10:27:55 +02:00
c47167058a Improved handling of cylinder alignment if the resulting image size
size is not divisible by 2048. Old behavior was to not align. New is
to pad up by a few blocks of 512 bytes.
2015-05-10 09:34:45 +02:00
5a3d84cbbb Fixed omissions of rev 1197 about so_write_opts_set_prep_img() and
iso_write_opts_set_efi_bootp().
2015-04-28 14:21:36 +02:00
5f6e64b792 Bug fix: GPT production did not yield proper results with appended sessions
resp. with TOC emulation enabled.
2015-04-25 12:13:11 +02:00
d4b8cbe474 New API object iso_interval_reader. Enabling flag bits for older API calls
iso_write_opts_set_prep_img(), iso_write_opts_set_efi_bootp(),
and iso_write_opts_set_partition_img().
2015-04-23 15:46:04 +02:00
a0719328ea Bug fix: A zero sized GPT partition was marked after the last appended
GPT partition.
2015-04-18 14:07:16 +02:00
c8776e605e Bug fix: iso_image_report_system_area() did not show GPT partitions of size 0. 2015-04-18 13:54:54 +02:00
003aa5832e Fixing an omission of rev 1183. Protective MBR was produced for
appended GPT partitions only if ISOLINUX isohybrid was enabled.
2015-04-14 20:13:06 +02:00
a78864252e Mentioned official UEFI 2.4 specs in description of boot sectors. 2015-03-16 15:03:58 +01:00
e56a782b89 Bug fix: If iso_write_opts_set_hardlinks() enabled automatic inode numbers,
then they did not get into effect with nodes were zisofs decoder filters got
attached during the image load process.
2015-03-09 19:59:54 +01:00
9e17516e0d Based the iso_stream_cmp_ino() comparison of streams from the loaded
ISO filesystem on their data extents rather than on their inode numbers.
2015-03-09 19:49:39 +01:00
e29cd723dd Accounting for a long AAIP list in root directory. 2015-03-05 15:44:47 +01:00
b0694b4e25 Name change with some debugging macros. 2015-03-01 22:18:59 +01:00
850302dde5 Fixed another bug introduced by rev 1084.
The assumption was wrong that CE must be the last SUSP entry in its
directory record.
2015-03-01 22:14:35 +01:00
26b4222948 Fixed a bug introduced with rev 1184.
Calculated size of the directory tree could differ from written size.
2015-03-01 17:52:19 +01:00
782bb7854e New system area type 6 = DEC Alpha SRM boot sector.
New API calls iso_image_set_alpha_boot(), iso_image_get_alpha_boot().
Thanks to Helge Deller.
2015-02-28 15:13:38 +01:00
9c33eb5f10 Forgot to update copyright in previous commit. 2015-02-28 14:45:29 +01:00
8e55195edc Working around a Linux kernel bug, which hides files of which the
Rock Ridge CE entry points to a range that crosses a block boundary,
or of which the byte offset is larger than the block size of 2048.
Thanks to Joerg Meyer.
2015-02-26 17:56:34 +01:00
527b613607 New API call iso_write_opts_set_appended_as_gpt()
and marking of appended partitions in GPT if GPT emerges for other reasons.
2015-02-06 11:59:25 +01:00
0819f93f79 Minor changes about GPT in description of boot sectors 2015-02-06 11:57:06 +01:00
3b0ba17f3d Avoiding a SIGSEGV with loading a faulty ISO filesystem.
Debian bug 774152. Thanks to Jakub Wilk.
2014-12-29 18:32:53 +01:00
0611f468c2 Fixed buffer overflow in demo/demo.c with gesture -iso_read.
Debian bug 774147. Thanks to Jakub Wilk.
2014-12-29 15:08:47 +01:00
5c6ce72c02 Fixed a typo in message of make install.
Debian bug 774140. Thanks to Jakub Wilk.
2014-12-29 11:51:30 +01:00
585a54d020 Improved size estimation when loading ISO with hidden El Torito images 2014-12-03 20:22:30 +01:00
7ea6d4ebcb Forced ECMA-119 timestamp generation to GMT if no timezone info is available. 2014-11-28 12:08:21 +01:00
3e33fa5fa1 Equipped all non-system-dependent open(2) calls with O_BINARY. 2014-11-26 14:44:43 +01:00
cdc336a02b Checking at configure time for timezone integer variable. 2014-11-26 14:26:14 +01:00
288eb75745 Removed a surplus function definition from system_area.h which spoiled
compilation on Cygwin. Thanks to Gary Jiang.
2014-11-21 10:26:46 +01:00
210b5817cb Letting lfs_read() retry if read(2) returns a short byte count. 2014-11-20 13:15:35 +01:00
2fe0bf511b Continuing GPT inspection even if reading of GPT backup fails 2014-11-11 12:28:23 +01:00
af23ad0f90 Bug fix: Only 128 bytes of an emerging GPT header block were zeroized 2014-11-04 13:48:31 +01:00
0fc4421e15 Bug fix: The header indicator of the last El Torito catalog section header
was set to 0x90 rather than 0x91 if more than one boot image is in that
section.
2014-10-11 14:57:48 +02:00
6ed2404420 Recording the need for boot-info-table and grub2-boot-info
in El Torito images which get defined by commands rather
than being loaded from an ISO filesystem.
2014-10-11 14:31:13 +02:00
a22c16d5ef Increased default weight of El Torito boot catalog to 1 billion 2014-10-05 13:17:53 +02:00
5384342336 Re-arranged help texts of iso_image_report_system_area() and iso_image_report_el_torito() 2014-10-05 13:15:51 +02:00
a97c66ebb8 Preserving the weights of imported boot image files 2014-10-03 17:41:59 +02:00
1c2851b5ba Preserving the weights of imported boot image files. 2014-10-03 17:07:35 +02:00
cbea1335d8 Small corrections with MBR assessment of iso_image_report_system_area() 2014-10-03 09:46:59 +02:00
6da58860ec Mentioned /ppc/bootinfo.txt in description of CHRP 2014-09-27 11:08:59 +02:00
c47451d12b Bug fix: iso_image_report_system_area() caused SIGSEGV by NULL if no valid
ISO 9660 image was loeaded. Thanks to OmegaPhil.
2014-08-16 15:01:11 +02:00
a068a1349a Updated copyright date 2014-07-06 08:54:50 +02:00
eae886bcb5 Version leap to 1.3.9 2014-06-28 08:19:22 +02:00
288e778875 Version leap to 1.3.8 2014-06-28 08:14:27 +02:00
8e687db01d Updated changelog 2014-06-27 18:45:14 +02:00
273182aa2a Avoiding complaints of iso_image_report_system_area() about backup GPT
created by a corrected version of syslinux/utils/isohybrid.c
2014-06-23 14:31:23 +02:00
e26d07ee77 Enabled recording and restoring of extattr on NetBSD 2014-06-20 09:07:51 +02:00
1b5caac764 Made declarations of make_isolinux_mbr() consistent.
Debian bug 751501. Thanks to Michael Tautschnig.
2014-06-13 16:25:00 +02:00
42821af4e6 Tolerating ECMA-119 Extended Attributes when loading an image 2014-06-13 09:34:30 +02:00
c17ba1980a Clarified which inode is local ino_t and which is Rock Ridge uint32_t. 2014-05-27 21:31:53 +02:00
1df1642a61 Corrected help text of iso_image_report_system_area() 2014-05-08 20:07:46 +02:00
c07f42dfd4 Unified width of index columns to 3 digits in output of iso_image_report_*() 2014-04-29 19:39:42 +02:00
443156e100 Re-arranged output lines of iso_image_report_el_torito() 2014-04-29 19:17:06 +02:00
2f517301de Reacted on a compiler warning about an unused variable. 2014-04-28 21:06:10 +02:00
0bce145343 Changed report format of detected El Torito boot image options 2014-04-27 15:13:57 +02:00
6d64bc23cf Estimating size of El Torito boot images which are not represented by a file 2014-04-27 12:09:13 +02:00
25295d2bb0 Polished help text of iso_image_report_system_area() 2014-04-25 09:40:37 +02:00
3370f666f9 Split the large macro ISO_SYSAREA_REPORT_DOC into several parts ISO_SYSAREA_REPORT_DOC* 2014-04-24 13:56:52 +02:00
ad279352e3 New API call iso_image_report_el_torito() 2014-04-24 10:15:56 +02:00
dfd74d3d04 Bug fix: iso_file_get_old_image_lba() returned 0 in case of valid lba. 2014-04-23 16:22:37 +02:00
593844b0ed Recognizing partition offset 16 if the MBR is a protective msdos label 2014-04-15 10:18:50 +02:00
083795cba2 Changed start of overall isohybrid GPT partition from 0 to partition_offset 2014-04-14 17:54:07 +02:00
3b06d25a37 Removed a surplus semicolon of previous changeset 2014-04-14 16:18:50 +02:00
9e5158f59e Closed a memory leak introduced with rev 1133 2014-04-14 16:06:32 +02:00
d93be961e1 Closed a memory leak with disposal of iso_image_report_system_area() result 2014-04-13 11:21:33 +02:00
8c1c0775d6 Closed a memory leak with loading of hidden boot images 2014-04-13 11:07:10 +02:00
2f8bd3ac01 Split the output of iso_image_report_system_area() into separate texts. 2014-04-13 09:16:45 +02:00
6edc1ac057 New API call iso_crc32_gpt() 2014-04-12 14:54:54 +02:00
a394f4dfd2 Bug fix: The GUIDs of main GPT and backup GPT differed if more than one
System Area was written into the ISO image.
2014-04-11 16:15:19 +02:00
dd27f579eb New API call iso_image_report_system_area() 2014-04-11 15:39:45 +02:00
1ac59bec46 Clarified PALO header versions in boot sector description 2014-04-09 23:59:09 +02:00
af843e446f Included fcntl.h in libisofs.h to work around "#define open open64" in
fcntl.h of AIX. Thanks to Richard Nolde.
2014-04-09 09:48:31 +02:00
e6e037f87e Re-enabled HP-PA PALO boot preparations 2014-04-09 09:02:51 +02:00
ca2643b52b Updated description of boot sector formats 2014-04-09 08:31:34 +02:00
ed8066580a Reacted on compiler warning of gcc on AIX. Thanks Richard Nolde. 2014-04-03 21:45:19 +02:00
97ec68530b Applied similar bug fixes to Joliet and ISO 9660:1999 2014-04-02 19:40:17 +02:00
185cbd99bf Bug fix: Prevent allocation of empty ECMA-119 directory children list.
Thanks Richard Nolde.
2014-04-02 19:06:53 +02:00
0e00aeb638 Bug fix: Prevent allocation of empty hash tables. Thanks Richard Nolde. 2014-04-02 18:40:03 +02:00
03b45c3151 Version leap to 1.3.7 2014-03-04 17:08:29 +01:00
b82ca42f87 Version leap to 1.3.6 2014-03-04 17:00:54 +01:00
1a8a216822 Updated changelog 2014-03-04 10:05:57 +01:00
ef528f2f0e Temporarily disabled the unfinished HP-PA PALO bootability preparations 2014-03-04 09:23:04 +01:00
bedfa914d5 Temporarily disabled the unfinished HP-PA PALO bootability preparations 2014-03-03 20:15:08 +01:00
5383ae2faa Fixed a memory fault introduced with rev 1106 2014-02-16 14:42:39 +01:00
d23462657b Installed debugging code for error ISO_RR_NAME_RESERVED 2014-02-16 14:40:28 +01:00
b41e36365d Fixed a write to array index -1 with demo/demo -tree 2014-02-16 14:31:33 +01:00
985015cea1 Making sure that PVD time strings are allocated with 17 bytes plus trailing 0 2014-02-13 16:25:15 +01:00
27d4c79d0e Silenced warnings about -Wchar-subscripts, added /usr/local for NetBSD 2014-02-11 09:28:27 +01:00
5b78efb12a Clarified the content of the PVD timestamps. 2014-02-09 13:29:50 +01:00
2c2fb7caf2 Fixed a harmless bug introduced with rev 1111. 2014-01-26 10:07:10 +01:00
d51cefb097 Adapted HP-PA boot sector code to upcomming PALO header version 5 2014-01-16 11:59:58 +01:00
7637d13e11 New API calls iso_image_set_hppa_palo() and iso_image_get_hppa_palo() 2014-01-14 09:43:28 +01:00
b9b5284f22 Beautified the collision avoiding names 2014-01-04 16:28:25 +01:00
afa65e9f2a Reduced minimum length of collision avoiding name from 8 to 7 2014-01-03 21:16:56 +01:00
5e1aaca232 Avoided unnecessary recursion with production of collision avoiding names 2014-01-03 20:53:59 +01:00
fea649835c Small fix of previous change 2014-01-03 20:00:04 +01:00
44f475a4ef Improved handling of unconvertable file names and name collsions during iso_image_import() 2014-01-03 18:29:29 +01:00
60eb7e883c Issueing warnings when Joliet file names with non-UCS-2 characters get read 2013-12-31 13:14:42 +01:00
9b4e0b611a Bug fix: Division by zero if HFS+ was combined with TOC emulation for overwritable media. 2013-12-28 16:45:29 +01:00
1be57e34ec Completed implementation of API call iso_conv_name_chars() 2013-12-28 15:36:33 +01:00
b0e68bbcaa Fixed a memory access error introduced with rev 1099 2013-12-22 19:07:28 +01:00
fa61b94ac8 Consolidated the single copies of IsoWriteOpts members in Ecma119Image
by having a copy of the whole IsoWriteOpts in Ecma119Image
2013-12-22 19:02:44 +01:00
3e3c15812b New API call iso_conv_name_chars(), provisory implementation 2013-12-19 15:41:55 +01:00
88555bd059 New API call iso_write_opts_set_joliet_utf16()
and ability to read Joliet names as UTF-16BE
2013-12-17 21:45:52 +01:00
ba47d1534c Version leap to 1.3.5 2013-12-12 14:44:22 +01:00
b7dc0f4057 Version leap to 1.3.4 2013-12-12 14:37:11 +01:00
0ab9f5f8d2 Updated changelog 2013-12-12 09:30:25 +01:00
1338f29d62 Added a comment to node.c 2013-12-12 09:25:40 +01:00
bc5e2227c8 Encoding HFS+ names in UTF-16 rather than UCS-2. 2013-11-26 12:47:43 +01:00
654ff82345 Mentioned boot image address in newer GRUB2 MBR 2013-11-18 13:22:17 +01:00
6baeae70e0 Mentioned GRUB2 Boot Info in boot_sectors.txt 2013-11-18 12:58:50 +01:00
b987972660 Updated copyright year in README 2013-09-25 13:07:38 +02:00
c78526abce Reacted on warnings of Debian buildd with clang 2013-09-16 20:52:14 +02:00
b95e1bb85c Giving sort weight 2 as default to El Torito boot images. 2013-09-07 21:37:27 +02:00
7aa2582129 Reacted on warnings of PLD Linux build log 2013-09-05 10:01:08 +02:00
3f29d70aba Preserving MD5s of files from old session until the end of the new
write run. If the write run fails, the old MD5s get restored.
2013-08-20 11:48:24 +02:00
567d3ddafb Fixed the rollover protection for checksum indice. 2013-08-17 12:49:01 +02:00
c47f85c639 Removed an obsolete sentence from docs. 2013-08-17 12:48:04 +02:00
40310b4fd7 Updated ChangeLog to new development cycle. 2013-08-07 15:53:43 +02:00
f34c274f21 Version leap to 1.3.3 2013-08-07 15:12:43 +02:00
46e96ee616 Version leap to 1.3.2 2013-08-07 15:10:10 +02:00
7e60e60e62 Updated changelog 2013-08-07 10:56:23 +02:00
d55ed2d1ca New API calls iso_image_get_app_use() and iso_image_set_app_use() 2013-08-04 12:32:31 +02:00
77c8349c56 Bug fix: iso_finish() left an invalid global pointer, which a subsequent call of iso_init() would try to dereference. 2013-07-31 09:53:43 +02:00
b1c7ed6e29 Avoided a confusing error message from iso_image_update_sizes(),
prepared macro for non-confusing error message,
and introduced flag bit0 to iso_stream_get_input_stream()
2013-06-25 14:56:29 +02:00
e886722d65 The sort weight of data files loaded from ISO image is now 2 exp 28 to 1
rather than 2 exp 31 - 1 to - 2 exp 31
2013-05-24 12:35:43 +02:00
b80b339de3 Version leap to 1.3.1 2013-05-17 19:51:39 +02:00
efbd05203d Version leap to 1.3.0 2013-05-17 19:47:58 +02:00
6ca1d76d60 Updated change log 2013-05-17 09:52:40 +02:00
e1b54056e8 Added a new source of information about CHRP to boot_sectors.txt 2013-05-01 20:28:24 +02:00
d5cd610ac7 Bug fix: The protective MBR partition for GPT started at block 0 instead of 1 2013-04-17 20:54:02 +02:00
91f5ebb376 Bug fix: GPT header CRC was computed from all 512 bytes rather than from 92. 2013-04-17 16:45:51 +02:00
ff3b439bda Changed Libisofs_grub2_sparc_patch_lba_poS to Libisofs_grub2_sparc_patch_adr_poS 2013-04-14 08:15:29 +02:00
4672c79181 Changed Libisofs_grub2_sparc_patch_lba_poS to Libisofs_grub2_sparc_patch_adr_poS 2013-04-14 08:14:27 +02:00
83cb07b23c New API calls iso_image_set_sparc_core() and iso_image_get_sparc_core(). 2013-04-13 22:17:26 +02:00
439a14da1d Bug fix: Reserved and unused fields of APM entries were not zeroed. 2013-04-13 12:11:26 +02:00
d66eef42f6 Corrected Libisofs_grub2_mbr_patch_offsT from 3 to 4 2013-04-13 09:25:42 +02:00
337bade549 New option bits with el_torito_set_isolinux_options() and
iso_write_opts_set_system_area() to control GRUB2 patching of
boot image and MBR
2013-04-13 08:38:52 +02:00
eb6503a8ad * Bug fix: Unspecified Expiration Time and Effective Time of ISO volume was
represented by 0-bytes rather than ASCII '0' digits.
2013-04-10 13:55:20 +02:00
1a2e1c767e Now repeating Rock Ridge warnings at most once per loaded image. 2013-04-10 13:32:53 +02:00
858c5479c8 Changed some warning texts from "RR" to "Rock Ridge" 2013-04-10 13:32:09 +02:00
d36b3d04a8 Temporarily hosting a test bed for syslinux/core/fs/susp_rr.c in libisofs/fs_image.c 2013-03-31 13:37:39 +02:00
da41eb8c6e Version leap to 1.2.9 2013-03-18 21:54:59 +01:00
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
125789feef Version leap to 1.2.2 2012-04-02 19:00:27 +02:00
37efffcf26 Removed obsolete development comments 2012-04-02 11:36:16 +02:00
b2c281d0c6 Updated ChangeLog 2012-03-27 13:51:52 +02:00
8a2fa9fe2e New API call iso_write_opts_set_allow_7bit_ascii(). 2012-03-22 11:18:44 +01:00
1247edff95 Reacted on warnings of cppcheck. 2012-03-21 20:28:15 +01:00
a2fe1a4100 Corrected flaws of revision 926. 2012-03-14 13:50:46 +01:00
4eb4146474 Improved standards compliance for ISO level 1 names with partly relaxed
constraints.
2012-03-14 09:07:59 +01:00
ce35aefb32 Bug fix: Directory name mapping to ISO level 1 was too liberal if
iso_write_opts_set_allow_dir_id_ext() was enabled.
2012-03-13 09:38:29 +01:00
269e0b19a5 Improved the ISO level 1 mapping of file names which begin by a dot. 2012-03-13 09:20:20 +01:00
0a8bb0e9b8 Made sure that empty relocation directory name leads to root directory. 2012-03-10 11:29:03 +01:00
76f2a5f4d3 New API call iso_write_opts_set_rr_reloc() 2012-03-09 19:59:51 +01:00
e49f9672bc Disabled skipping of ECMA-119 directory /RR_MOVED by name. 2012-03-06 16:18:05 +01:00
37f880797d Small comment change in libisofs/libisofs.h 2012-03-06 15:14:45 +01:00
475eb36978 Small change in doc/iso_hybrid_fs.txt 2012-03-06 15:13:45 +01:00
ac9116c64e Fixed a typo in doc/iso_hybrid_fs.txt 2012-02-22 18:06:23 +01:00
b1c218c280 Described the opportunities and constraints of ISO 9660 hybrid fileystems,
and the libisofs implementation needs when adding further filesystem types.
2012-02-21 22:30:29 +01:00
ebea7c29ef Reporting name of base file with error message for filtered streams 2012-02-11 19:09:40 +01:00
09c49f777a Version leap to 1.2.1 2012-01-27 15:57:45 +01:00
5f76be9d76 Version leap to 1.2.0 2012-01-27 10:59:50 +01:00
305fe3f496 Updated changelog 2012-01-27 10:56:50 +01:00
191c3245af Corrected libburnia domain name in AAIP documentation 2012-01-24 14:48:42 +01:00
b5b30b1c75 Updated ChangeLog 2012-01-24 14:00:27 +01:00
6a1bbaa902 Extended influence of iso_write_opts_set_dir_rec_mtime() to Joliet and
ISO 9660:1999.
2012-01-14 15:54:25 +01:00
bddc44d1ca Added ./bootstrap script to release tarball 2011-12-03 15:58:38 +01:00
9b61ff377c Removing demo/.libs with make clean 2011-12-03 15:43:18 +01:00
22fed6bedb Reacted on warning of cppcheck 2011-10-09 18:26:13 +02:00
3433592f69 Version leap to 1.1.7 2011-09-27 14:33:07 +02:00
d787ecbcd9 Version leap to 1.1.6 2011-09-27 14:29:18 +02:00
182edb3a00 Updated changelog 2011-09-26 19:10:13 +02:00
cb25d4d4e5 Clarified a remark about maximum length of RR name parts in CA. 2011-09-26 18:23:24 +02:00
afdef92343 Moved version number macros higher in libisofs/libisofs.h 2011-09-24 16:38:20 +02:00
2bc7084315 Adaptions and remarks about GNU/Hurd 2011-08-30 19:20:18 +02:00
6d10908a58 Detecting and rejecting multiple entries of user::, group::, other:: in ACL text 2011-08-24 09:23:02 +02:00
2ba54fafe7 New optional tolerance towards failure to restore "default" ACLS on FreeBSD. 2011-08-23 12:40:09 +02:00
ca63dac7e3 Enabled recording and restoring of extattr on FreeBSD.
Gave up unconditional ACL support in favor of configure control.
2011-08-22 17:10:13 +02:00
f885da8087 Avoided to restore xattr of namespace "isofs" if non-"user" restoring is
enabled.
2011-08-22 15:57:16 +02:00
8438db02cf Avoided to call calloc() for 0 bytes when reading Linux xattr. 2011-08-22 12:37:11 +02:00
ce19db5e19 Bug fix: On Solaris: False out-of-memory errors when writing images. 2011-08-19 12:40:45 +02:00
aeb5258ae2 Removed rogue comma from FreeBSD ACL adapter 2011-08-18 16:06:33 +02:00
f10c2d7779 New API call iso_local_attr_support() 2011-08-18 15:07:31 +02:00
82bfcf429a Bug fix: No ACLs were recorded on FreeBSD. 2011-08-18 10:29:34 +02:00
8fb8c01a0f Corrected a theoretical flaw in a code path which is not yet used. 2011-08-18 10:28:41 +02:00
73910e2f3c Bug fix: ACL entries of groups and of user id 0 were not properly recorded
and cannot be restored.
2011-08-18 10:26:09 +02:00
9c5fc21679 Small change in a comment 2011-08-18 10:24:47 +02:00
3a82f213e0 Implemented direct iconv conversion for the case that the traditional
two-step conversion via character set "WCHAR_T" fails. E.g. on Solaris.
2011-08-11 18:22:49 +02:00
6892c734e2 Bug fix: The function for restoring ACLs and xattr returned error on
FreeBSD, even if no xattr were to be restored.
2011-08-09 19:00:03 +02:00
66f6937c17 Clarified stream version prescription and made internal stream data
instances static.
2011-08-09 14:59:19 +02:00
baa5b7cd42 Added missing symbol serial_id to libisofs.ver 2011-08-09 14:58:46 +02:00
f2658ef173 Started new development cycle 2011-08-09 12:32:04 +02:00
ecdb3aeb1d Version leap to 1.1.5 2011-08-08 13:58:43 +02:00
745a878884 Version leap to 1.1.4 2011-08-08 09:35:46 +02:00
6ae8386c23 Bug fix: The function for restoring ACLs and xattr returned error on systems
other than Linux and FreeBSD, even if nothing was to be restored.
2011-08-08 08:25:18 +02:00
b90e613246 Reacted on warnings of cppcheck 2011-07-11 12:44:12 +02:00
bbc3caf86b Reacted on warnings of cppcheck 2011-07-11 12:43:12 +02:00
b086d53274 Reacted on warnings of cppcheck 2011-07-11 12:41:30 +02:00
17b36623a6 Version leap to 1.1.3 2011-07-08 14:42:09 +02:00
286648574d Version leap to 1.1.2 2011-07-08 10:28:12 +02:00
317bba395e Updated changelog 2011-07-08 10:25:24 +02:00
541b41b6a1 Clarified a comment about retrieving content of boot catalog. 2011-07-07 14:11:30 +02:00
91a8be5262 Silenced a warning of cppcheck about possible null pointer dereference. 2011-07-06 12:31:37 +02:00
91e99703b4 Reacted on warnings of -Wunused-but-set-variable 2011-07-04 18:54:11 +02:00
dd7dac3397 Reacted on warnings of -Wunused-but-set-variable 2011-07-04 16:07:35 +02:00
43d4833dd6 Reacted on warnings of -Wunused-but-set-variable 2011-07-04 16:06:16 +02:00
dd1629b5ca Reacted on warnings of -Wunused-but-set-variable 2011-07-04 16:04:05 +02:00
bc8138ce78 Reacted on warnings of -Wunused-but-set-variable 2011-07-04 16:00:29 +02:00
2d568c1dbb Reacted on warnings of -Wunused-but-set-variable 2011-07-04 15:56:26 +02:00
842b62d111 Reacted on warnings of -Wunused-but-set-variable 2011-07-04 15:50:52 +02:00
4f3357e3ec Reacted on warnings of -Wunused-but-set-variable 2011-07-04 15:39:38 +02:00
9ffe91c372 Reacted on warnings of -Wunused-but-set-variable 2011-07-04 15:37:55 +02:00
7e2add413a Reacted on warnings of -Wunused-but-set-variable 2011-07-04 15:35:43 +02:00
004aefd0b7 New API call iso_image_get_bootcat() 2011-07-03 21:02:19 +02:00
00955ba85c Version leap to 1.1.1 2011-06-18 19:22:11 +02:00
4a79812d15 Version leap to 1.1.0 2011-06-18 14:23:02 +02:00
9b2f97e4b7 Updated changelog 2011-06-18 14:06:38 +02:00
35cfb756be Bug fix: Padding as of iso_write_opts_set_tail_blocks() was added only
after cylinder alignment as of iso_write_opts_set_system_area()
         and thus spoiled this alignment.
2011-06-15 17:09:48 +02:00
2835fccfa4 Replaced some large local variables by other means in libisofs/util.c 2011-06-12 12:46:52 +02:00
31c7f68990 Replaced some large local variables by other means in libisofs/system_area.c 2011-06-12 12:28:38 +02:00
4e0ca258de Replaced some large local variables by other means in libisofs/stream.c 2011-06-12 09:59:53 +02:00
9653854462 Replaced some large local variables by other means in libisofs/rockridge.c 2011-06-12 09:51:08 +02:00
6e95f8bbcb Replaced some large local variables by other means in libisofs/messages.c 2011-06-11 22:23:44 +02:00
ce3aa0d5c7 Replaced some large local variables by other means in libisofs/md5.c 2011-06-11 19:23:32 +02:00
d5bfc552c4 Replaced some large local variables by other means in libisofs/joliet.c 2011-06-11 16:33:57 +02:00
bad54a5967 Replaced some large local variables by other means in libisofs/iso1999.c 2011-06-11 13:42:55 +02:00
49b0a89bfe Replaced some large local variables by other means in libisofs/fs_image.c 2011-06-11 12:40:33 +02:00
265df5fbe3 Replaced some large local variables by other means in libisofs/filesrc.c 2011-06-11 11:08:20 +02:00
f089bcf66a Replaced some large local variables by other means in libisofs/ecma119.c 2011-06-10 14:55:57 +02:00
062e5f0bf0 Changed error code of libisofs/util.h from -1 to ISO_OUT_OF_MEM 2011-06-10 14:55:34 +02:00
d932bfcdea Replaced some large local variables by other means in libisofs/builder.c 2011-06-09 16:51:00 +02:00
3ef67cb49d Replaced some large local variables by other means in libisofs/aaip_0_2.c 2011-06-09 14:27:41 +02:00
f08ae22dbe Macros LIBISO_ALLOC_MEM, LIBISO_FREE_MEM for replaceing local variables 2011-06-09 14:23:21 +02:00
45d316d1ca Added option -I . to aclocal in bootstrap script on advise of George Danchev 2011-06-09 14:21:20 +02:00
4d8fc6ffee Introduced AC_CONFIG_MACRO_DIR() and ACLOCAL_AMFLAGS on advise of George Danchev 2011-06-08 21:27:53 +02:00
023e413624 Reacted on -Wextra -Wno-unused-parameter warnings of gcc for
libisofs/aaip-os-freebsd.c
2011-06-02 10:28:52 +02:00
d361186bca Made callers of iso_file_source_get_path() aware that NULL might be returned. 2011-06-01 11:37:30 +02:00
e7d9559d16 Avoiding to produce NM field for "." and ".." entries if Rock Ridge
version 1.10 is chosen by iso_write_opts_set_rrip_version_1_10()
2011-06-01 11:34:45 +02:00
94eecbb123 Reacted on static code checker warning reported by George Danchev 2011-05-22 20:23:48 +02:00
777f74ea0b Added options -Wextra -Wno-unused-parameter for gcc 2011-05-22 16:35:22 +02:00
2b8d47ddd8 Reacted on -Wextra -Wno-unused-parameter warnings of gcc for util_rbtree.c 2011-05-21 23:21:14 +02:00
e839b7b368 Reacted on -Wextra -Wno-unused-parameter warnings of gcc for util.c 2011-05-21 23:20:44 +02:00
1334027a83 Reacted on -Wextra -Wno-unused-parameter warnings of gcc for tree.c 2011-05-21 23:19:34 +02:00
8d3a0a6a9e Reacted on -Wextra -Wno-unused-parameter warnings of gcc for system_area.c 2011-05-21 23:19:06 +02:00
7b7ea41f12 Reacted on -Wextra -Wno-unused-parameter warnings of gcc for stream.c 2011-05-21 23:18:35 +02:00
bb5886094e Reacted on -Wextra -Wno-unused-parameter warnings of gcc for rockridge_read.c 2011-05-21 23:18:00 +02:00
b076ce9b44 Reacted on -Wextra -Wno-unused-parameter warnings of gcc for rockridge.c 2011-05-21 23:17:38 +02:00
05f26898f3 Reacted on -Wextra -Wno-unused-parameter warnings of gcc for node.c 2011-05-21 23:16:35 +02:00
a698f0ee22 Reacted on -Wextra -Wno-unused-parameter warnings of gcc for messages.c 2011-05-21 23:16:10 +02:00
e69854b35f Reacted on -Wextra -Wno-unused-parameter warnings of gcc for md5.c 2011-05-21 23:15:48 +02:00
228995c148 Reacted on -Wextra -Wno-unused-parameter warnings of gcc for make_isohybrid_mbr.c 2011-05-21 23:15:19 +02:00
071e14f9b0 Reacted on -Wextra -Wno-unused-parameter warnings of gcc for joliet.c 2011-05-21 23:14:49 +02:00
b08d6271ab Reacted on -Wextra -Wno-unused-parameter warnings of gcc for iso1999.c 2011-05-21 23:14:16 +02:00
431d31fff6 Reacted on -Wextra -Wno-unused-parameter warnings of gcc for fs_local.c 2011-05-21 23:13:40 +02:00
a37571c6c5 Reacted on -Wextra -Wno-unused-parameter warnings of gcc for fs_image.c 2011-05-21 23:13:16 +02:00
6e98006640 Reacted on -Wextra -Wno-unused-parameter warnings of gcc for filters/zisofs.c 2011-05-21 23:12:29 +02:00
d264e818c3 Reacted on -Wextra -Wno-unused-parameter warnings of gcc for filters/gzip.c 2011-05-21 23:11:48 +02:00
d0f740facf Reacted on -Wextra -Wno-unused-parameter warnings of gcc for eltorito.c 2011-05-21 23:11:18 +02:00
944b5a6152 Reacted on -Wextra -Wno-unused-parameter warnings of gcc for ecma119_tree.c 2011-05-21 23:10:21 +02:00
b51232fef4 Reacted on -Wextra -Wno-unused-parameter warnings of gcc for ecma119.c 2011-05-21 23:09:44 +02:00
99f037e210 Reacted on -Wextra -Wno-unused-parameter warnings of gcc for buffer.c 2011-05-21 23:08:53 +02:00
c794a48a06 Reacted on -Wextra -Wno-unused-parameter warnings of gcc for aaip_0_2.c 2011-05-21 23:08:14 +02:00
47d599e8c3 Reacted on -Wextra -Wno-unused-parameter warnings of gcc for aaip-os-linux.c 2011-05-21 23:05:17 +02:00
0a87e838df Mentioned the need to define uint32_t when including libisofs.h 2011-05-19 15:43:44 +02:00
e945e38add Mentioned upcomming version in ChangeLog 2011-05-13 09:01:01 +02:00
6d68abc707 Version leap to 1.0.9 2011-05-12 18:59:38 +02:00
e80dd0735b Version leap to 1.0.8 2011-05-12 18:55:58 +02:00
c276681735 Updated changelog. 2011-05-12 16:43:46 +02:00
1d723f0834 Corrected an inappropriate variable type when setting xattr or ACL. 2011-05-12 16:22:02 +02:00
1a4b2a2584 Bug fix: SIGSEGV if the path given by iso_image_add_mips_boot_file()
does not exist in the image at image production time.
2011-05-09 15:32:27 +02:00
4eb2a7199c Bug fix: iso_write_opts_set_system_area() with system area types
1=MIPS Big Endian and 2=MIPS Little Endian caused SIGSEGV.
2011-05-09 15:12:52 +02:00
6d5e68fd01 Clarified two comments. 2011-05-06 13:32:06 +02:00
fed8b23017 Returning proper error code on memory shortage with iso_node_lookup_attr(). 2011-05-06 13:30:37 +02:00
e3329a98a9 Corrected previous revision which freed memory too generously 2011-05-01 22:49:34 +02:00
49efbdad76 Closed tiny memory leak detected by valgrind. 2011-05-01 16:44:20 +02:00
9538a5d57b Performing collision test before FileSource creation in iso_tree_add_new_node() 2011-04-28 20:24:17 +02:00
66dc6c2d0e Disabled HAVE_DOT in doxygen.conf 2011-04-15 14:52:36 +02:00
81608815ae Closed a memory leak which happened in case of memory shortage. 2011-04-11 20:49:03 +02:00
ae5ab4a08f Closed a memory leak of 32 kB per loaded ISO image. 2011-04-11 20:47:34 +02:00
76b6737570 Bug fix: While loading an ISO image several reads to malloc
memory occured with byte index -1. (Found by Valgrind after years
of operation without visible problems.)
2011-04-11 20:19:35 +02:00
9210a57500 Version leap to 1.0.7 2011-04-09 11:11:36 +02:00
8a752b50fa Version leap to 1.0.6 2011-04-08 19:47:18 +02:00
c38b1a3a3a Updated changelog 2011-04-08 19:00:33 +02:00
73c9c7f244 Removed inactive debugging code 2011-04-08 18:56:08 +02:00
0b9f03bb23 Fixed a typo in comments 2011-04-05 09:20:25 +02:00
d1c3a017e3 Cleaned up use of PATH_MAX (local filesystem) and LIBISOFS_NODE_PATH_MAX
(ISO filesystem).
2011-04-03 11:02:15 +02:00
b200feceed Requiring libjte version 1.0.0 (if libjte is to be linked at all). 2011-04-02 16:30:23 +02:00
7958b2ea22 Mentioned configure option to disable libjte 2011-03-31 18:26:23 +02:00
c0bdf4d3b5 Reacted on warning about theoretical memory leak. 2011-03-28 20:43:13 +02:00
71efc996e3 New error code ISO_RR_PATH_TOO_LONG. 2011-03-28 15:00:44 +02:00
61383dea2d New error codes ISO_RR_NAME_TOO_LONG and ISO_RR_NAME_RESERVED for
occasions which previously returned ISO_WRONG_ARG_VALUE.
2011-03-26 20:54:20 +01:00
270cd1cad5 Closed a memory leak found by valgrind. 2011-03-26 19:23:51 +01:00
559e9b564d New API call iso_write_opts_set_joliet_long_names() 2011-03-26 15:38:08 +01:00
d8a56f60ef Interpreting the return values of fwrite() in demo/demo.c 2011-03-11 09:09:39 +01:00
10e3b2939a Updated copyright year 2011-03-10 20:03:35 +01:00
ba67523278 Version leap to 1.0.5 2011-03-10 13:43:13 +01:00
f09964cf51 Version leap to 1.0.4 2011-03-10 09:22:57 +01:00
e4a70a823d Updated changelog 2011-03-10 08:36:03 +01:00
655d86b97a Bug fix: Compilation failed if --disable-zlib was configured 2011-03-09 21:24:47 +01:00
f2f780115b New no_md5 value 2 for API call iso_read_opts_set_no_md5() 2011-03-08 19:37:52 +01:00
b6be8457f7 Fixed a memory hog introduced with rev 775. 2011-03-07 11:11:58 +01:00
1238c19494 Changed message about cylinder alignment. 2011-03-04 15:14:11 +01:00
2caf527f67 Refusign cylinder alignment if it is impossible to do it exactly. 2011-03-04 11:24:36 +01:00
43eae7502b New option bits 8 and 9 with iso_write_opts_set_system_area(). 2011-03-03 19:14:40 +01:00
e035146e01 Bug fix: isohybrid image size was not aligned to cylinder boundary.
Now the cylinder size gets adjusted if the image does not fit into 1024 cyl.
2011-03-01 18:31:59 +01:00
de3e21629f Corrected little flaws detected by George Danchev with cpp. 2011-02-24 20:02:56 +01:00
d79a3fcec4 Incresed mismatch test severity to FATAL again. 2011-02-23 20:16:59 +01:00
de079cec42 Version leap to 1.0.3 2011-02-23 20:14:10 +01:00
b33d06eb0c Version leap to 1.0.2 2011-02-23 13:01:56 +01:00
dfdaa2902a Reduced size mismtach test severity to WARNING.
This shall avoid the risk of false positives as long as the test is new.
2011-02-23 12:11:57 +01:00
0173c51c23 Updated change log. 2011-02-22 20:54:39 +01:00
a118127e9c Re-enabled use of system provide function timegm(), if available. 2011-02-21 13:46:46 +01:00
1f24b39879 Corrected sequence of IsoNode xinfo list after cloning. 2011-02-21 12:35:50 +01:00
16863755be Installed a check for miscalculated ECMA-119 tree size. 2011-02-20 12:10:26 +01:00
b25ac0f52d Avoided to give directories the same PX inode number.
(Solaris believes in them.)
2011-02-18 18:59:00 +01:00
5c59295e72 Bug fix: With a probability of 2 to 5 percent, AAIP could spoil the image
by miscalculating the number of root directory's CE blocks.
This lead to fatal offset of all further data by one block.
All sub directories and all data file content is affected.
Quite obvious to see. The problem existed since March 2009.
AAIP is used for recording of ACL and xattr. The problem gets enabled by call
iso_write_opts_set_aaip(opts, 1).
2011-02-18 17:39:21 +01:00
85893bf58b Removed warning not to use iso_tree_clone(). 2011-02-15 15:24:31 +01:00
722327e4b8 Overwriting eventually existing cloner of iso_node_xinfo_func with
iso_node_xinfo_make_clonable().
2011-02-12 14:48:31 +01:00
ab0a981814 Added capability to merge directories of cloned tree with existing
target tree.
2011-02-12 13:52:17 +01:00
38483d894e Added missing iso_filesystem_ref() for cloned node from local filesystem. 2011-02-01 22:16:05 +01:00
1082e628d1 New API calls iso_tree_clone(), iso_stream_clone.
New IsoFileSourceIface version 2 with method clone_src().
New IsoStreamIface version 4 with method clone_stream().
New public function prototype iso_node_xinfo_cloner.
New API calls iso_node_xinfo_make_clonable(), iso_node_xinfo_get_cloner().
New public iso_node_xinfo_cloner instance aaip_xinfo_cloner().
New API calls iso_node_get_next_xinfo(), iso_node_remove_all_xinfo().
New API call iso_node_remove_tree().
2011-02-01 19:16:45 +01:00
74c68224c7 Changed name of freshly introduce API call iso_write_opts_set_high_empty_address
to iso_write_opts_set_old_empty, reverted the meaning and the default.
2011-01-26 19:38:50 +01:00
200697898d New API call iso_write_opts_set_high_empty_address(). 2011-01-26 14:24:18 +01:00
a3eeda3d23 Yet incomplete implementation of IsoNode cloning.
(Commited to avoid tangling with upcomming 
 iso_write_opts_set_no_dummy_block_adr())
2011-01-25 10:50:37 +01:00
92073c45ef Bug fix: Volume Descriptor Set Terminator contained non-zero bytes in
the reserved field (ECMA-119 8.3.4). The bytes stem from an uninitialized
local variable.
2011-01-24 15:03:09 +01:00
81cded618d Better hiding of a defunct #ifndef 2011-01-18 17:50:26 +01:00
84c0bd37ff Avoiding <stdint.h> if not available. Trying to use <inttypes.h> in that case. 2011-01-18 16:18:09 +01:00
4e60feaeab Avoiding the use of setenv() and unsetenv() which are not available
on Solaris 9.
2011-01-18 15:26:19 +01:00
d6e150a10e Version leap to 1.0.1 2011-01-16 13:35:07 +01:00
35ceac65f7 Version leap to 1.0.0 2011-01-16 13:29:39 +01:00
45ffdef845 Closed loophole for undefined variable with new call
iso_write_opts_set_untranslated_name_len()
2011-01-16 13:28:07 +01:00
55d6ae343d Updated changelog 2011-01-16 11:17:07 +01:00
a69f45e8cd Made provisory test for directory record overflow permanent 2011-01-16 11:10:08 +01:00
68c3ae522e Added iso_memory_stream_new to list of public symbols. 2011-01-01 15:07:10 +01:00
8e2748f23b New API call iso_memory_stream_new(). (Was formely a private acll.) 2011-01-01 14:55:26 +01:00
f923a79929 New API call iso_write_opts_set_allow_dir_id_ext() 2010-12-25 08:11:19 +01:00
362b15f4d5 Bug fix: ECMA-119 directory names were truncated to 8 characters if
lowercase characters or full ASCII are allowed.
2010-12-24 20:31:24 +01:00
2649045dfe New API call iso_write_opts_set_untranslated_name_len() 2010-12-22 14:21:00 +01:00
3d427bdf70 Corrected a statemenent about Sector Count in boot record documentation. 2010-12-14 06:36:12 +01:00
8b2af3ac36 Prepending ./configure generated options to CFLAGS rather than appending them 2010-12-13 08:47:24 +01:00
113358daea Version leap to 0.6.41 2010-12-10 12:42:43 +01:00
6927fd35e8 Version leap to 0.6.40 2010-12-10 11:27:46 +01:00
fb231ff186 Updated changelog 2010-12-10 11:22:25 +01:00
b2fde289b1 Removed old change timestamp 2010-12-10 11:15:42 +01:00
dcc6ffd184 Avoiding to start writer thread if iso_write_opts_set_will_cancel() is set to 1. 2010-12-06 17:05:35 +01:00
27e69c38ab New error reply code ISO_DISPLACE_ROLLOVER for external data sources with
address displacement.
2010-11-30 09:47:22 +01:00
f4b2bfc0d6 Better messages if boot image or boot catalog directory are missing. 2010-11-25 17:01:40 +01:00
5482d5d7b4 Improvements about the block address of empty data files 2010-11-25 14:40:44 +01:00
b2997dcc46 New API call iso_write_opts_set_will_cancel() 2010-11-24 11:00:21 +01:00
48ae8acbd6 Better handling of El Torito boot images with identical block address
at image load time.
2010-11-24 10:06:19 +01:00
a488f8fb14 New API call iso_write_opts_set_disc_label(),
new system area type 3 = SUN Disk Label
2010-11-05 15:34:42 +01:00
ea8da1f7d3 Added a description of SUN Disk Label for SUN SPARC machines. 2010-11-01 16:05:47 +01:00
8ad92a08ea Fixed a typo in a warning message. 2010-10-27 07:57:38 +02:00
35c043a0f9 Version leap to 0.6.39 2010-10-23 16:31:47 +02:00
fce35ac718 Version leap to 0.6.38 2010-10-23 15:28:02 +02:00
01518896f9 Updated Changelog 2010-10-23 15:25:33 +02:00
caf90e35f5 Fixed session oversize bug with emulated multi-session.
Introduced by revision 721.
2010-10-19 12:45:26 +02:00
1f486fd78b Coordinated appending of partition images with situations other than
isohybrid MBR production or partition offset.
2010-10-19 10:14:26 +02:00
b58d1e28ef New API call iso_write_opts_set_partition_img(). 2010-10-18 16:56:00 +02:00
ebb5937568 Removed obsolete development macro case. 2010-10-16 19:05:46 +02:00
ef444fb29c Removed remaining questions about MIPS Big Endian. Now rounding up the count
of cylinders.
Described MBR DOS-style partition table format.
2010-10-16 11:24:52 +02:00
1ccbaa302c United macro Xorriso_jte_standalonE with macro Xorriso_standalonE 2010-10-15 14:24:31 +02:00
0d35100eb0 New system area type 2 = MIPS Little Endian / DEC Boot Block. 2010-10-15 12:19:53 +02:00
48316af1d9 Made development option Libisofs_mips_boot_file_pathS unconditional. 2010-10-15 09:23:09 +02:00
a75fb9a894 New system area type 2 for Little Endian MIPS DEC boot block. 2010-10-14 22:34:32 +02:00
a0ba4b976c Described El Torito, grub-mkrescue MBR, MIPS Little Endian booting. 2010-10-14 17:26:56 +02:00
870280a018 Small adjustments and bug fix with new MIPS boot facility. 2010-10-13 16:59:18 +02:00
f33df0ef29 New API calls iso_image_add_mips_boot_file(), iso_image_get_mips_boot_files(),
iso_image_give_up_mips_boot().
The preliminary ban has been lifted to combine El Torito and MIPS Big Endian
boot facilities.
The current state of boot record documentation has been added to bzr.
2010-10-12 20:24:17 +02:00
2a087f6f39 Silenced a warning about const or non-const. 2010-10-12 12:23:16 +02:00
b07d3ab0c3 Provisory implementation of MIPS big endian Volume Header production.
For now it is mutually exclusive with El Torito production.
It will always be mutually exclusive with MBR production.
2010-10-12 12:20:27 +02:00
f12df92600 Requiring libjte-0.1.1 if enabled. Prepared for GNU xorriso to include libjte. 2010-10-07 13:43:57 +02:00
8a75d35c46 New API call iso_image_generator_is_running().
Prevented a potential race condition between Ecma119Image disposal by
burn_source and final activities of ISO generator thread.
2010-10-06 17:33:46 +02:00
bb28c69cae Stuffed a memory leak discovered by valgrind. 2010-10-05 19:58:54 +02:00
25068a4de2 Declared that iso_lib_version() and iso_lib_is_compatible() are permitted
before iso_init().
2010-10-04 15:47:09 +02:00
d2094a0d80 Compile time test and run time test for sufficiently recent libjte if enabled. 2010-10-04 14:56:24 +02:00
16dcf4a29c Draining and forwarding possibly enabled libjte message list.
Changed severity of error code ISO_LIBJTE_FILE_FAILED to MISHAP.
2010-10-04 13:18:06 +02:00
69a25c9734 New API call iso_write_opts_set_tail_blocks() for tail padding inside ISO image 2010-10-02 22:57:09 +02:00
a387a8b06a Removed hardcoded libjte test because xorriso now has a -jigdo command. 2010-09-30 09:31:40 +02:00
a9af97733e Allowed NULL as second arg of iso_write_opts_detach_jte(). 2010-09-29 10:08:30 +02:00
c30674095b Updated hardcoded JTE test case so that it produces non-trivial files. 2010-09-28 16:44:25 +02:00
be838b6940 Disabled the hardcoded JTE test which was introduced by previous revision 2010-09-28 12:15:23 +02:00
b0c79a9a1e New API calls iso_write_opts_attach_jte() and iso_write_opts_detach_jte() 2010-09-28 12:12:33 +02:00
8725baa55f Making use of libjte if installed and if not ./configure --disable-libjte 2010-09-27 18:22:05 +02:00
59ab73c57f On Linux: Run ldconfig during make install,if not --disable-ldconfig-at-install 2010-09-22 12:55:13 +02:00
7386596bfa Version leap to 0.6.37 2010-09-15 11:14:12 +02:00
4833ef23e5 Updated ChangeLog. 2010-09-15 11:11:02 +02:00
14171bdd3a Version leap to 0.6.36 2010-09-15 10:55:14 +02:00
d37eba5344 Removed outdated development marks 2010-09-15 09:28:05 +02:00
3b616dae38 Meaningful change log file derived by George Danchev from web site 2010-09-15 08:43:04 +02:00
a2758b27e6 Automatic C++ detection by using macro __cplusplus 2010-09-11 19:18:42 +02:00
d5c4af7378 Removed development marks and an obsolete conditional compilation case. 2010-09-11 13:25:51 +02:00
90f37b8183 Introduced macro Libisofs_h_as_cpluspluS to avoid the definitions of
struct iso_file_source and struct iso_stream when libisofs.h is included
in C++ files. (The definitions contain members with name "class".)
2010-09-11 11:50:47 +02:00
1d4f26f325 Adjusted new partition offset feature for multi-session and MD5 tags. 2010-09-10 13:45:37 +02:00
08e442a2ab Removed dummy filter xor_sencrypt because there are real filters now. 2010-09-06 12:19:51 +02:00
017dcb39f2 New API function iso_write_opts_set_part_offset() controls creation of
an MBR with a first partiton table entry that bears non-zero start address.
A second set of volume descriptors and directory tree+tables gets created
which can be used to mount the image at the partition start.
Not yet implemented for second set: ISO 9660:1999, MD5 checksums.
2010-09-05 12:43:48 +02:00
95121e2f9f Forgot to store util_rbtree.c before previous commit. 2010-09-01 19:18:35 +02:00
ba11413a6f Corrected several memory leaks and potential NULL pointer evaluations
in case of memory shortage. All reported by George Danchev.
2010-09-01 10:45:10 +02:00
e1888df5ab Hopefully silenced warnings of doxygen on Debian buildd 2010-08-06 12:49:22 +02:00
dceef03633 Removed problematic DETAILS_AT_TOP to silence warning of Debian buildd 2010-07-30 19:10:55 +02:00
443c5d41db Removed obsolete comment 2010-07-06 10:53:04 +02:00
e60171986b Let configure perform linker test with --version-script if enabled 2010-07-06 10:50:28 +02:00
fe45249e9e Gave up use of alloca() in favor of calloc() and free(),
because alloca.h is needed on Solaris and not available on FreeBSD.
2010-07-05 19:14:47 +02:00
b01f017a6d Hiding all non-API symbols from the linker by use of --version-script 2010-07-05 18:20:59 +02:00
73bc3ae512 Include file alloca.h was missing in demo program 2010-07-01 13:50:42 +02:00
b6427d3b2b Version leap to 0.6.35 2010-06-28 21:21:06 +02:00
438024d11b Version leap to 0.6.34 2010-06-28 14:12:33 +02:00
1d6fdf51dc New error code ISO_BOOT_NO_CATALOG 2010-06-23 19:54:51 +02:00
281462802f Reacted on harmless compiler warnings about allegedly uninitialized variables 2010-06-20 15:41:06 +02:00
2b2a86ea2e Moved some functions into the Libisofs_with_zliB case
which caused compiler warnings on OpenSuse Build Service.
2010-06-20 15:08:08 +02:00
c0963596e5 New API call iso_node_get_hidden(). 2010-06-20 09:18:30 +02:00
9be5b241e2 New API call iso_node_set_hidden(),
new IsoHideNodeFlag value LIBISO_HIDE_BUT_WRITE.
2010-06-18 22:03:41 +02:00
fcde936670 Remove a probably outdated test that was always false. 2010-06-04 16:21:14 +02:00
73c6bc49c6 Moved inclusion of config.h to top position.
Solaris complained about redefined _FILE_OFFSET_BITS. See man lfcompile.
2010-05-29 09:34:00 +02:00
5ed507da83 Forgotten inclusion of ../config.h in filters/*.c 2010-05-17 14:35:10 +02:00
ae626b9570 Eventually including autotools generated ../config.h with all source files.
(GNU xorriso plans to use autoheader for a diet of its build messages.)
2010-05-16 10:20:12 +02:00
3528493b92 Removed development macro Libisofs_with_checksumS
and made the affected code unconditional.
2010-05-08 22:24:02 +02:00
9cf460a3b1 Version leap to 0.6.33 2010-05-03 14:44:21 +02:00
84132ec7bf Version leap to 0.6.32 2010-05-03 14:34:36 +02:00
eb23260459 Removed most of the development remarks of 0.6.31 2010-05-01 20:38:01 +02:00
4978424328 Corrected calls of functions iso_lsb(), iso_msb(), iso_bb() which used
integer types other than uint32_t.
2010-04-30 11:36:14 +02:00
e4cf93665a Making an educated guess whether the boot images contain a boot info table.
New API call el_torito_seems_boot_info_table() publishes this guess.
2010-04-29 15:10:18 +02:00
3d9367d52a Closed memory leak about boot catalog node. 2010-04-25 20:27:17 +02:00
03b030c56d New API calls el_torito_get_isolinux_options(), el_torito_get_boot_media_type() 2010-04-25 14:11:45 +02:00
a3fe82100b Fixed a bug introduced with previous revision 655. 2010-04-23 19:00:50 +02:00
02d7a690eb New API calls el_torito_set_id_string(), el_torito_get_id_string(),
el_torito_set_selection_crit(), el_torito_get_selection_crit().
2010-04-23 18:01:27 +02:00
ace0d1ab2e Bug fix of previous revision 653:
SIGSEGV because of dereferencing NULL when writing without boot image.
2010-04-22 23:13:54 +02:00
59d143c1f0 Added support for multiple boot images.
New API calls iso_image_add_boot_image() , iso_image_get_all_boot_imgs(),
el_torito_get_boot_platform_id(), el_torito_get_load_seg(),
el_torito_get_load_size(), el_torito_get_bootable()
2010-04-22 14:04:51 +02:00
da2c0520cc Changed new API call from iso_image_set_boot_platform_id() to
el_torito_set_boot_platform_id().
Introduced new API call iso_image_set_boot_catalog_weight().
2010-04-20 16:23:17 +02:00
517f520570 New API call iso_image_set_boot_platform_id().
Downgraded ISO_WRONG_EL_TORITO and ISO_UNSUPPORTED_EL_TORITO from SORRY
to WARN and implemented the tolerance that is promised by their message
texts.
2010-04-20 11:10:00 +02:00
98d2b4c996 Version leap to 0.6.31 2010-04-17 13:23:49 +02:00
481d425580 Version leap to 0.6.30 2010-04-17 13:18:56 +02:00
99e988d652 Updated genealogy of isohybrid MBR production. 2010-04-17 08:46:45 +02:00
38a7b4a5b1 New API calls iso_read_opts_load_system_area() and iso_image_get_system_area() 2010-04-16 21:49:44 +02:00
9dc894584d Enhanced configure tests for iconv. Now aborting if not available. 2010-04-15 12:16:41 +02:00
1a7ab679cd Extended effect of iso_write_opts_set_pvd_times() parameter uuid to
creation time, to keep it consistent with modification time.
2010-04-14 12:00:43 +02:00
016baf9984 Implemented no_force_dots and separate omit_version_numbers for
Joliet to allow producing the same Joliet names as mkisofs -J.
2010-04-13 10:18:55 +02:00
b089f2e978 New bit1 of iso_write_opts_set_system_area() options.
New inner call make_isolinux_mbr() produces a bootable System Area
from an ISOLINUX mbr/isohdp[fp]x*.bin file and an ISOLINUX
El Torito bootable image (isolinux.bin).
2010-04-10 18:50:59 +02:00
c3d5ab7bc7 New API call iso_write_opts_set_pvd_times(). 2010-04-07 21:03:00 +02:00
f13167335a New API call iso_write_opts_set_system_area() acts like mkisofs option -G 2010-04-06 14:41:36 +02:00
f0f378c38f Adjusted copyright and license statements in single files. 2010-02-14 11:39:34 +01:00
907b44c556 Added copyright statements to technical specs in doc directory. 2010-02-13 14:18:40 +01:00
00011036dd Updated license situation of make_isohybrid_mbr.c 2010-02-12 21:57:48 +01:00
55497d3931 Changed comments from "Linux" to "GNU/Linux" where appropriate. 2010-02-12 20:14:15 +01:00
c47f206fe3 Version leap to 0.6.29 2010-02-10 15:45:19 +01:00
82 changed files with 38980 additions and 4087 deletions

View File

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

View File

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

572
ChangeLog
View File

@ -1 +1,573 @@
git clone git@dev.lovelyhq.com:libburnia/libisofs.git
(to become libisofs-1.5.8 or higher)
===============================================================================
- no novelties yet -
libisofs-1.5.6.pl01.tar.gz Fri Jun 09 2023
===============================================================================
* Bug fix: On non-GNU/Linux systems ssize_t was not defined in rockridge.h .
Report and fix proposal by Rui Chen
libisofs-1.5.6.tar.gz Wed Jun 07 2023
===============================================================================
* Bug fix: iso_write_opts_set_part_like_isohybrid() did not cause a MBR
partition table if the partitions are data files in the ISO
rather than appended
* Bug fix: The lseek methods of IsoFileSource for local filesystem and loaded
ISO returned libisofs error codes as positive off_t numbers
* Bug fix: Freshly cloned data files from imported image were not marked as
imported. Thanks to Ivan Shmakov. (Closes: #1022851)
* Bug fix: Size of further CE area was calculated wrong if its CE entry ended
exactly at a block boundary
* New iso_write_opts_set_system_area() option bits 16:
GPT "Legacy BIOS bootable" and 17: GPT writable
* New API calls iso_assess_written_features(), iso_read_image_feature_named(),
iso_read_image_features_text()
* Allowed lseekable device files with iso_tree_add_new_cut_out_node().
Proof-of-concept by Ivan Shmakov.
* New API call iso_write_opts_set_max_ce_entries()
libisofs-1.5.4.tar.gz Sat Jan 30 2021
===============================================================================
* Bug fix: Large amounts of AAIP data or many long file names could cause with
zisofs an unreadable filesystem after the warning "Calculated and
written ECMA-119 tree end differ"
* Bug fix: Big-Endian MIPS Volume Header boot file size was rounded up to
full 2048. Thanks René Rebe.
* Bug fix: El Torito production failed if no catalog path is given and the
first boot image path contains no slash
* Bug fix: zisofs production was wrong on big-endian machines
* Bug fix: Apple Partition Map entries wrote uninitialized data
* Bug fix: Appended APM partitions without HFS+ production had start and size 1
* Switched to usage of libjte-2.0.0
* Implemented production and reading of zisofs2 for files larger than 4 GiB - 1.
* New struct iso_zisofs_ctrl version 2
* New API call iso_stream_get_zisofs_par()
* New API call iso_stream_zisofs_discard_bpt()
* New API call iso_image_zisofs_discard_bpt()
* New flag bits 8 to 15 in API call iso_node_zf_by_magic()
* New API call iso_zisofs_ctrl_susp_z2()
* New API call iso_read_opts_set_joliet_map(), new default joliet_map=stripped
* New API calls iso_read_image_features_tree_loaded() and
iso_read_image_features_rr_loaded()
libisofs-1.5.2.tar.gz Sat Oct 26 2019
===============================================================================
* New API calls iso_write_opts_set_part_type_guid(),
iso_write_opts_set_iso_type_guid()
* New API call iso_nowtime()
* New flag bit2 of iso_node_set_acl_text() to be verbous about failures
* Made libisofs ready for building out-of-source. Thanks Ross Burton.
* Bug fix: Appended GPT partitions were not covered by the protective MBR
partition
* Bug fix: Multi-session emulation spoiled GPT production.
"GPT partitions ... overlap". Regression towards 1.4.8
* Bug fix: Appending partitions 5 to 8 caused damaged ISO filesystems if not
for SUN disk label
* Bug fix: SIGSEGV happened if options bit 14 of
iso_write_opts_set_system_area() is set and no El Torito boot image
is defined
libisofs-1.5.0.tar.gz Sat Sep 15 2018
===============================================================================
* New API call iso_image_get_ignore_aclea(),
new iso_image_set_ignore_aclea() and iso_file_source_get_aa_string()
flag bit3 to import all xattr namespaces
* New API calls iso_image_was_blind_attrs(), iso_local_set_attrs_errno().
* New flag bit7 with iso_local_set_attrs() to avoid unnecessary write attempts.
* New return value 2 of IsoFileSource.get_aa_string() and iso_local_get_attrs().
* Now putting user defined padding after appended partitions.
* Bug fix: Add-on sessions with partition offset claimed too many blocks as
size. Regression of version 1.4.8.
* Bug fix: Long Joliet names without dot were mangled with one character too
many. Long Joliet names with leading dot were mangled one char
too short.
* Bug fix: Reading beyond array end for HFS+ production caused SIGSEGV with
FreeBSD 11 CLANG -O2. Thanks ASX of GhostBSD.
libisofs-1.4.8.tar.gz Tue Sep 12 2017
===============================================================================
* Bug fix: iso_read_opts_set_no_rockridge() did not prevent reading of root
SUSP.
* Bug fix: Non-SUSP data in System Use Area prevented image loading if
Rock Ridge was enabled. Thanks to Jonathan Dowland.
* Bug fix: Protective MBR for GPT could emerge with boot flag set.
* Bug fix: Appended partitions of size >= 4 GiB led to abort with error message
"FATAL : ISO overwrite". Thanks to Sven Haardiek.
* Bug fix: Bit 15 of iso_write_opts_set_system_area did not work with generic
MBR.
* Bug fix: Keeping and patching of loaded boot images failed.
Regression by version 1.4.4.
* Bug fix: Program crashes by intentionally wrong ISO image input.
Found by American Fuzzy Lop and Jakub Wilk.
Debian bug reports: 872372, 872475, 872545, 872590, 872761.
* New API calls el_torito_set_full_load(), el_torito_get_full_load().
* New API call iso_write_opts_set_iso_mbr_part_type().
libisofs-1.4.6.tar.gz Fri Sep 16 2016
===============================================================================
* Bug fix: SIGSEGV by NULL when a data file was larger than ISO level allows.
* Bug fix: Interpretation of 17 digit timestamps was wrong.
* New API calls iso_generate_gpt_guid() and iso_write_opts_set_gpt_guid().
* Made several pseudo-random ids reproducible by overriding volume modification
time.
libisofs-1.4.4.tar.gz Fri Jul 01 2016
===============================================================================
* Bug fix: HFS+ production could cause MBR partition of type 0xEE without GPT.
* Bug fix: Protective MBR was not produced if no System Area data are given.
* Bug fix: Protective MBR was not recognized if partition is appended.
* Bug fix: The HFS+ filesystem was not marked in GPT of GRUB2 hybrid layout.
* Bug fix: HFS+ directories could announce more children than they actually
have.
* Bug fix: At image loading time GRUB2 MBR was not recognized if the partition
table is not the protective one as described by UEFI.
* Bug fix: Oversized text in ISO_SYSAREA_REPORT_DOC_ALPHA.
Thanks to Etienne Bergeron.
* New pseudo path for El Torito boot images:
--interval:appened_partition_N:all::
* New bit15 with options of iso_write_opts_set_system_area() to enforce
MBR bootable/active flag.
* New API calls iso_write_opts_set_appended_as_apm(),
iso_write_opts_set_part_like_isohybrid().
* Introduced image size tolerance of 300 kB in order to recognize SUN Disk
Label that was generated by genisoimage -B "...".
* Added "extern C" to libisofs.h
* Removed option --silent from libtool runs.
libisofs-1.4.2.tar.gz Sat Nov 28 2015
===============================================================================
* Bug fix: zisofs compression caused SIGSEGV (by reading) with files larger
than 524160 KiB.
* Bug fix: iso_node_get_name() of root node returned NULL pointer rather than
an empty string
* Bug fix: Names read from Joliet tree where stripped of trailing ";1"
* Now sorting the data file content extents by ECMA-119 tree, rather than
by the red-black tree which shall consolidate files with identical
source object.
* New API call iso_read_opts_set_ecma119_map().
* New AAIP variable isofs.nt records name truncation parameters.
* Rectified handling of oversized filenames by new API calls:
iso_image_set_truncate_mode, iso_image_get_truncate_mode,
iso_truncate_leaf_name, iso_image_set_node_name, iso_image_tree_clone,
iso_image_add_new_dir, iso_image_add_new_file, iso_image_add_new_special,
iso_image_add_new_symlink, iso_image_dir_get_node, iso_image_path_to_node
* Result of a Coverity audit: 50+ code changes, but no easy-to-trigger bugs
libisofs-1.4.0.tar.gz Sun May 17 2015
===============================================================================
* Bug fix: iso_image_report_system_area() caused SIGSEGV by NULL if no valid
ISO 9660 image was loeaded. Thanks to OmegaPhil.
* Bug fix: A SIGSEGV could happen when loading a faulty ISO filesystem.
Debian bug 774152. Thanks to Jakub Wilk.
* Bug fix: Rock Ridge Continuation Area could be produced crossing a block
boundary. This is heavily disliked by the Linux kernel and spoils
the representation of directories which contain many symbolic links.
* Bug fix: If iso_write_opts_set_hardlinks() enabled automatic inode numbers,
then they did not get into effect with nodes were zisofs decoder
filters got attached during the image load process.
* Bug fix: The header indicator of the last El Torito catalog section header
was set to 0x90 rather than 0x91 if more than one boot image is in
that section.
* Bug fix: Only 128 bytes of an emerging GPT header block were zeroized.
* Bug fix: iso_image_report_system_area() did not show GPT partitions of
size 0.
* Bug fix: A zero sized GPT partition was marked after the last appended
GPT partition.
* Bug fix: GPT production did not yield proper results with appended sessions
or with TOC emulation enabled.
* Increased default weight of El Torito boot catalog to 1 billion.
* Improved handling of cylinder alignment if the resulting image size is not
divisible by 2048. Old behavior was to not align. New is to pad up by a
few blocks of 512 bytes.
* New API call iso_write_opts_set_appended_as_gpt()
and marking of appended partitions in GPT if GPT emerges for other reasons.
* New system area type 6 = DEC Alpha SRM boot sector.
New API calls iso_image_set_alpha_boot(), iso_image_get_alpha_boot().
Thanks to Helge Deller.
* New API object iso_interval_reader. Enabling flag bits for older API calls
iso_write_opts_set_prep_img(), iso_write_opts_set_efi_bootp(),
and iso_write_opts_set_partition_img().
libisofs-1.3.8.tar.gz Sat Jun 28 2014
===============================================================================
* Bug fix: Prevent allocation of empty hash tables. Thanks Richard Nolde.
* Bug fix: Prevent allocation of empty directory children lists.
Thanks Richard Nolde.
* Bug fix: The GUIDs of main GPT and backup GPT differed if more than one
System Area was written into the ISO image.
* New API calls iso_image_report_el_torito() and iso_image_report_system_area()
* New API call iso_crc32_gpt()
libisofs-1.3.6.tar.gz Tue Mar 04 2014
===============================================================================
* Bug fix: Division by zero if HFS+ was combined with TOC emulation for
overwritable media.
* New API call iso_write_opts_set_joliet_utf16() and ability to read Joliet
names as UTF-16BE
* New API call iso_conv_name_chars()
libisofs-1.3.4.tar.gz Thu Dec 12 2013
===============================================================================
* Giving sort weight 2 as default to El Torito boot images
* Encoding HFS+ names in UTF-16 rather than UCS-2.
libisofs-1.3.2.tar.gz Wed Aug 07 2013
===============================================================================
* Bug fix: iso_finish() left an invalid global pointer, which a subsequent
call of iso_init() would try to dereference.
* The sort weight of data files loaded from ISO image is now 2 exp 28 to 1
rather than 2 exp 31 - 1 to - 2 exp 31
libisofs-1.3.0.tar.gz Fri May 17 2013
===============================================================================
* Bug fix: GPT header CRC was computed from all 512 bytes rather than from 92.
* Bug fix: Unspecified Expiration Time and Effective Time of ISO volume was
represented by 0-bytes rather than ASCII '0' digits.
* Bug fix: Reserved and unused fields of APM entries were not zeroed.
* Bug fix: The protective MBR partition for GPT started at block 0 instead of 1.
* New option bits with el_torito_set_isolinux_options() and
iso_write_opts_set_system_area() to control GRUB2 patching of
boot image and MBR.
* New API calls iso_image_set_sparc_core() and iso_image_get_sparc_core().
libisofs-1.2.8.tar.gz Mon Mar 18 2013
===============================================================================
* 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
iso_write_opts_set_allow_dir_id_ext() was enabled
* New API call iso_write_opts_set_allow_7bit_ascii()
* 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
ISO 9660:1999.
libisofs-1.1.6.tar.gz Tue Sep 27 2011
===============================================================================
* Bug fix: On Solaris: False out-of-memory errors when writing images.
* Bug fix: On FreeBSD: No ACLs were recorded.
* Bug fix: ACL entries of groups and of user id 0 were not properly recorded
and cannot be restored.
* Bug fix: On FreeBSD: The function for restoring ACLs and xattr returned
error, even if no xattr were to be restored.
* New API call iso_local_attr_support()
* Enabled recording and restoring of extattr on FreeBSD.
libisofs-1.1.4.tar.gz Mon Aug 08 2011
===============================================================================
* Bug fix: The function for restoring ACLs and xattr returned error on systems
other than Linux and FreeBSD, even if nothing was to be restored.
libisofs-1.1.2.tar.gz Fri Jul 08 2011
===============================================================================
* New API call iso_image_get_bootcat()
libisofs-1.1.0.tar.gz Sat Jun 18 2011
===============================================================================
* Bug fix: Padding as of iso_write_opts_set_tail_blocks() was added only
after cylinder alignment as of iso_write_opts_set_system_area()
and thus spoiled this alignment.
libisofs-1.0.8.tar.gz Thu May 12 2011
===============================================================================
* Bug fix: iso_write_opts_set_system_area() with system area types
1=MIPS Big Endian and 2=MIPS Little Endian caused SIGSEGV.
* Bug fix: SIGSEGV if the path given by iso_image_add_mips_boot_file()
does not exist in the image at image production time.
* Bug fix: While loading an ISO image: Several reads to malloc
memory occured with byte index -1. (Found by Valgrind after
years of operation without visible problems.)
* Bug fix: Closed a memory leak of 32 kB per loaded ISO image.
libisofs-1.0.6.tar.gz Sat Apr 09 2011
===============================================================================
* New API call iso_write_opts_set_joliet_long_names()
* New error codes for oversized file addresses
libisofs-1.0.4.tar.gz Thu Mar 10 2011
===============================================================================
* Bug fix: Compilation failed if --disable-zlib was configured
* Bug fix: isohybrid image size was not aligned to cylinder boundary.
* New no_md5 value 2 for API call iso_read_opts_set_no_md5()
* New option bits 8 and 9 with iso_write_opts_set_system_area()
libisofs-1.0.2.tar.gz Tue Feb 23 2011
===============================================================================
* Bug fix: iso_write_opts_set_aaip(opts, 1) could cause fatal miscalculation
of the root directory size. This eventually truncated directory
tree and spoiled all data file content.
* Bug fix: Volume Descriptor Set Terminator contained non-zero bytes in
the reserved field (ECMA-119 8.3.4). The bytes stem from the
previously written Volume Descriptor.
* New API calls iso_tree_clone(), iso_stream_clone.
* New IsoFileSourceIface version 2 with method clone_src().
* New IsoStreamIface version 4 with method clone_stream().
* New public function prototype iso_node_xinfo_cloner.
* New API calls iso_node_xinfo_make_clonable(), iso_node_xinfo_get_cloner().
* New public iso_node_xinfo_cloner instance aaip_xinfo_cloner().
* New API calls iso_node_get_next_xinfo(), iso_node_remove_all_xinfo().
* New API call iso_node_remove_tree().
* New API call iso_write_opts_set_old_empty().
libisofs-1.0.0.tar.gz Mon Jan 17 2011
===============================================================================
* Bug fix: ECMA-119 directory names were truncated to 8 characters if
lowercase characters or full ASCII are allowed.
* New API call iso_write_opts_set_untranslated_name_len()
* New API call iso_write_opts_set_allow_dir_id_ext()
* New API call iso_memory_stream_new(). (Was formely a private call.)
libisofs-0.6.40.tar.gz Fri Dec 10 2010
===============================================================================
* New API call iso_write_opts_set_disc_label(), new system area type
3 = SUN Disk Label for booting SUN SPARC systems.
* New API call iso_write_opts_set_will_cancel() avoids start of write thread
and is to be used to inquire the future image size.
* New error reply code ISO_DISPLACE_ROLLOVER for external data sources with
address displacement.
libisofs-0.6.38.tar.gz Sat Oct 23 2010
===============================================================================
* New API calls iso_write_opts_attach_jte() and iso_write_opts_detach_jte()
allow to use libjte for jigdo production.
* New API call iso_write_opts_set_tail_blocks() for tail padding inside
ISO image.
* New API call iso_image_generator_is_running() to learn when the write thread
is done.
* New API calls iso_image_add_mips_boot_file(),
iso_image_get_mips_boot_files(), iso_image_give_up_mips_boot().
* New API call iso_write_opts_set_partition_img() for appending e.g. a small
empty FAT12 filesystem which may be used on USB stick.
libisofs-0.6.36.tar.gz Wed Sep 15 2010
===============================================================================
* New API function iso_write_opts_set_part_offset() controls creation of
an MBR with a first partiton table entry that bears non-zero start address.
A second set of volume descriptors and directory tree+tables gets created
which can be used to mount the image at the partition start.
* Hiding all non-API symbols from the linker by use of --version-script
* Automatic C++ detection in libisofs.h by using macro __cplusplus
* Corrected several memory leaks and potential NULL pointer evaluations
in case of memory shortage.
* Now with history of release notes in ./ChangeLog file.
libisofs-0.6.34.tar.gz Tue Jun 29 2010
===============================================================================
* New API call iso_image_set_boot_catalog_hidden()
* New API call iso_node_get_hidden()
* New IsoHideNodeFlag bit LIBISO_HIDE_BUT_WRITE
* New error code ISO_BOOT_NO_CATALOG
* Opportunity to reduce compile line length by including "config.h"
libisofs-0.6.32.tar.gz Mon May 03 2010
===============================================================================
* New API call iso_image_set_boot_catalog_weight()
* New API call iso_image_add_boot_image()
* New API calls el_torito_set_boot_platform_id(), el_torito_set_id_string(),
el_torito_set_selection_crit()
* New API calls iso_image_get_all_boot_imgs(), el_torito_get_boot_platform_id(),
el_torito_get_load_seg(), el_torito_get_load_size(), el_torito_get_bootable(),
el_torito_get_id_string(), el_torito_get_selection_crit(),
el_torito_get_isolinux_options(), el_torito_get_boot_media_type()
* New API call el_torito_seems_boot_info_table()
libisofs-0.6.30.tar.gz Sat Apr 17 2010
===============================================================================
* New API call iso_write_opts_set_system_area() acts like mkisofs option -G.
* New API call iso_write_opts_set_pvd_times().
* Now able to produce a bootable System Area from an ISOLINUX mbr/isohdp
[fp]x*.bin file and an ISOLINUX El Torito bootable image (isolinux.bin).
* Now able to produce the same Joliet names as mkisofs.
* New API calls iso_read_opts_load_system_area() and
iso_image_get_system_area() for multi-session handling of MBRs.
libisofs-0.6.28.tar.gz Wed Feb 10 2010
===============================================================================
* Bug fix: Random checksum index could sneak in via boot catalog node
and cause a SIGSEGV.
* Improved compilability out of the box on FreeBSD.
libisofs-0.6.26.tar.gz Wed Jan 20 2010
===============================================================================
* Bug fix: Invalid old checksum tags were preserved with
iso_write_opts_set_overwrite_buf(), if the new session produced no checksums.
* The checksum buffer for the emerging image gets now marked as invalid if
image generation is canceled.
* More graceful reaction on filesystems where ACL are not enabled but
nevertheless requested by the application.
* Adaptions to problems reported by Debian buildd.
libisofs-0.6.24.tar.gz Thu Oct 08 2009
===============================================================================
* Bug fix: Short Rock Ridge names got stripped of trailing blanks when loaded
and written again to a follow-up session. Long names could lose inner blanks.
* Bug fix: Avoided to return NULL or single blanks as content of id strings by
API calls iso_image_get_volset_id() ... iso_image_get_biblio_file_id().
* New API call iso_write_opts_set_scdbackup_tag().
libisofs-0.6.22.tar.gz Tue Aug 25 2009
===============================================================================
* New API call iso_write_opts_set_record_md5() for writing MD5 sums.
* New API call iso_read_opts_set_no_md5() for importing MD5 sums.
* New API calls iso_image_get_session_md5() and iso_file_get_md5().
* New API calls iso_md5_start(), iso_md5_compute(), iso_md5_clone(),
iso_md5_end(), iso_md5_match() for own MD5 computations.
* New API call iso_util_decode_md5_tag() to recognize and parse checksum tags.
* New API call iso_file_make_md5() to equip old file nodes with MD5.
* Improvements with ./configure and its help text.
libisofs-0.6.20.tar.gz Sun May 30 2009
===============================================================================
* Optional automatic detection and recording of hard link
relations between files.
* Support for restoring hard link relations by the app.
libisofs-0.6.18.tar.gz Fri Apr 17 2009
===============================================================================
* Opportunity to set the input charset automatically from an eventual xattr
"isofs.cs" of the image root node.
* New general filter API to inquire and remove filters.
* Specialized APIs for installing filters which are based on external processes
or based on zlib.
* New API call to inquire the original source path of a data file in an
emerging image.
libisofs-0.6.16.tar.gz Wed Mar 11
===============================================================================
* Bug fix: The ".." directory record pointed to the same data block as the "."
entry.
* Bug fix: The use of iso_write_opts_set_rrip_version_1_10() caused a wrong
size announcement in the CE entry which points to the ER signature
of the image root.
* New API call iso_write_opts_get_data_start() inquires the start address of
the data section of an emerging ISO image.
* ISO image generation does not absolutely depend on the availability of
character set "WCHAR_T" with iconv_open(3) any more.
libisofs-0.6.14.tar.gz Sat Feb 28 2009
===============================================================================
* New API calls iso_image_set_ignore_aclea(), iso_read_opts_set_no_aaip()
control import of ACL and xattr.
* New API calls iso_write_opts_set_aaip(), iso_write_opts_set_aaip_susp_1_10()
control output of ACL and xattr into generated ISO image.
* New API call iso_file_source_get_aa_string(), new function member
get_aa_string() in IsoFileSource_Iface allow to access opaquely encoded ACL
and xattr. New function handle aaip_xinfo_func attaches aa_strings to
IsoNode objects.
* New API calls iso_node_get_acl_text(), iso_node_set_acl_text(),
iso_node_get_perms_wo_acl() allow inquiry and manipulation of ACLs in
IsoNode objects.
* New API calls iso_node_get_attrs(), iso_node_set_attrs() allow inquiry and
manipulation of xattr in IsoNode objects.
libisofs-0.6.12.tar.gz Wed Nov 26 2008
===============================================================================
* New API calls iso_set_local_charset() and iso_get_local_charset()
* New API calls iso_write_opts_set_rrip_version_1_10() and
iso_write_opts_set_dir_rec_mtime()
* New API call el_torito_set_isolinux_options() allows to patch ISOLINUX boot
images and to generate a isohybrid MBR on the fly. Such an MBR makes the ISO
image bootable from disk-like hardware, e.g. from USB stick. The ISOLINUX
boot image has to be of syslinux 3.72 or later to allow MBR generation.
* Old API call el_torito_patch_isolinux_image() is deprecated now.
libisofs-0.6.10.pl01.tar.gz Wed Nov 19 2008
===============================================================================
* Bug fix: If images generated by mkisofs were loaded then files of size 0
could share their size information with files that contain data. Ticket #144.
* Bug fix: ISOLINUX boot images were patched suitable for El Torito but not for
an eventual MBR added by SYSLINUX script isohybrid.
libisofs 0.6.10 Mon Oct 6 2008:
===============================================================================
* Bug fix: Patching of existing ISOLINUX boot images led to a SIGSEGV.
* Bug fix: Adding a new ISOLINUX boot image or patching of an existing one
caused a read operation although writing had already begun.
libisofs-0.6.8.tar.gz Thu Sep 18 2008
===============================================================================
* Support for very large data files in the ISO 9660 image
(Level 3, multi-extent)
* Bug fix: it was assumed that isolinux images were always a multiple of 4
bytes
* New API call iso_image_update_sizes() to refresh recorded file sizes
immediately before image generation begins
libisofs-0.6.6.tar.gz Sun Jun 1 2008
===============================================================================
* Bug fix: major,minor numbers of device files were not read properly from
existing images
* Bug fix: iso_tree_path_to_node() returned 1 if a directory path component was
a non-directory file
* New API call iso_special_get_dev() retrieves major, minor numbers of device
files
libisofs-0.6.4.tar.gz Sun Apr 27 2008
===============================================================================
* Extended information: iso_node_add_xinfo()
* New node iteration: iso_dir_find_children()
* Custom image file content via iso_tree_add_new_file()
* Missing feature added to map a disk file to an arbitrary image file path via
iso_tree_add_new_node()
* Obtain image path of a node object via iso_tree_get_node_path()
* Various bugfixes
libisofs-0.6.2.1.tar.gz Thu Feb 14 2008
===============================================================================
* FIX: missing buffer.h preventing build from succeeding
Libisofs 0.6.2
===============================================================================
* Initial release of new generation libisofs
* Completely new API
* Long term commitment to ABI libisofs.so.6

View File

@ -1,4 +1,8 @@
# Copyright (c) 2007 Vreixo Formoso
# Copyright (c) 2009 - 2024 Thomas Schmitt
# Provided under the terms of the GNU General Public License version 2 or later.
# ts A90315 : LIBBURNIA_PKGCONFDIR is defined OS specific in acinclude.m4
# was: pkgconfigdir=$(libdir)/pkgconfig
pkgconfigdir=$(LIBBURNIA_PKGCONFDIR)
@ -6,17 +10,27 @@ pkgconfigdir=$(LIBBURNIA_PKGCONFDIR)
libincludedir=$(includedir)/libisofs
lib_LTLIBRARIES = libisofs/libisofs.la
ACLOCAL_AMFLAGS = -I ./
# Enable this if the source includes generated files like version.h
# AM_CPPFLAGS = -I $(top_builddir)/libisofs
## ========================================================================= ##
# Build libraries
libisofs_libisofs_la_LDFLAGS = \
-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) $(LIBLDFLAGS)
# Eventually enabling system adapters for ACL and EA.
# ts A90409: Eventually enabling use of zlib.
libisofs_libisofs_la_CFLAGS = $(LIBACL_DEF) $(XATTR_DEF) $(ZLIB_DEF)
# Enabling system adapters for ACL and EA.
# ts A90409: Enabling use of zlib.
# ts B00927: Enabling use of libjte (Jigdo Template Extraction)
# ts C40713: Enabling system adapter for Linux chattr(1) flags
# ts C41009: Enabling system adapter for project id of XFS-style quota
# Also enabling zlib, libjte, and directory size prediction check.
libisofs_libisofs_la_CFLAGS = $(LIBACL_DEF) $(XATTR_DEF) $(LFA_DEF) \
$(PROJID_DEF) $(ZLIB_DEF) $(LIBJTE_DEF) \
$(DIR_REC_SIZE_CHECK)
# ts A90114 : added aaip_0_2.*
@ -42,7 +56,6 @@ libisofs_libisofs_la_SOURCES = \
libisofs/stream.c \
libisofs/filter.h \
libisofs/filter.c \
libisofs/filters/xor_encrypt.c \
libisofs/filters/external.c \
libisofs/filters/zisofs.c \
libisofs/filters/gzip.c \
@ -64,6 +77,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 \
@ -81,6 +99,9 @@ libisofs_libisofs_la_LIBADD= \
libinclude_HEADERS = \
libisofs/libisofs.h
install-exec-hook:
$(LIBBURNIA_LDCONFIG_CMD) "$(DESTDIR)$(libdir)" || echo 'NOTE: Explicit dynamic library configuration failed. If needed, configure manually for:' "$(DESTDIR)$(libdir)"
## ========================================================================= ##
## Build demo applications
@ -103,8 +124,8 @@ noinst_PROGRAMS = \
# ts A90807
# Consolidated demo code for having less linker mesages with a make run.
demo_demo_CPPFLAGS = -Ilibisofs
# Consolidated demo code for having less linker messages with a make run.
demo_demo_CPPFLAGS = -I $(top_srcdir)/libisofs
demo_demo_LDADD = $(libisofs_libisofs_la_OBJECTS) $(libisofs_libisofs_la_LIBADD)
demo_demo_SOURCES = demo/demo.c
@ -215,6 +236,12 @@ demo_demo_SOURCES = demo/demo.c
# test/mocked_fsrc.h \
# test/mocked_fsrc.c
# "make clean" shall remove a few stubborn .libs directories
# which George Danchev reported Dec 03 2011.
# Learned from: http://www.gnu.org/software/automake/manual/automake.html#Clean
clean-local:
-rm -rf demo/.libs
## ========================================================================= ##
## Build documentation (You need Doxygen for this to work)
@ -245,6 +272,7 @@ nodist_pkgconfig_DATA = \
# ts A80114 : added aaip-os*
EXTRA_DIST = \
bootstrap \
libisofs-1.pc.in \
version.h.in \
doc/doxygen.conf.in \
@ -261,7 +289,10 @@ EXTRA_DIST = \
doc/susp_aaip_2_0.txt \
doc/susp_aaip_isofs_names.txt \
doc/zisofs_format.txt \
doc/zisofs2_format.txt \
doc/checksums.txt \
doc/boot_sectors.txt \
libisofs/libisofs.ver \
libisofs/aaip-os-dummy.c \
libisofs/aaip-os-linux.c \
libisofs/aaip-os-freebsd.c

127
README
View File

@ -2,11 +2,66 @@
libisofs
------------------------------------------------------------------------------
Released under GPL (see COPYING file for details).
Released under GNU General Public License version 2 or later.
See COPYING file for details.
Copyright (C) 2008 - 2010 Vreixo Formoso, Mario Danic, Thomas Schmitt
Copyright (C) 2008 - 2023 Vreixo Formoso,
Mario Danic,
Vladimir Serbinenko,
Thomas Schmitt
libisofs is part of the libburnia project (libburnia-project.org)
------------------------------------------------------------------------------
Download, Build and Installation
libisofs code is maintained in a git repository at dev.lovelyhq.com
(https://dev.lovelyhq.com/libburnia/libisofs). You can download it with:
$ git clone https://dev.lovelyhq.com/libburnia/libisofs.git
Our build system is based on autotools. For preparing the build you will need
autotools of at least version 1.7. If you have downloaded the code from the
repository, first of all you need to execute
./bootstrap
in the toplevel directory ./libisofs, in order to execute autotools.
Alternatively you may unpack a release tarball for which you do not need
autotools installed. For the most recent release of libisofs see:
https://dev.lovelyhq.com/libburnia/web/wiki/Releases
To build libisofs go into its toplevel directory and execute
./configure --prefix=/usr
make
To make the libraries accessible for running and developing applications
make install
On GNU/Linux it will try to run program ldconfig with the library installation
directory as only argument. Failure to do so will not abort installation.
One may disable ldconfig by ./configure option --disable-ldconfig-at-install .
By use of a version script, the libisofs.so library exposes no other function
names but those of the API definitions in <libisofs/libisofs.h>.
If -Wl,--version-script=... makes problems with the local compiler, then
disable this encapsulation feature by
./configure --disable-versioned-libs
make clean ; make
The ./configure script checks for the availability of supporting libraries.
If found, they will become mandatory for the emerging libisofs.so and all
applications which use it. This dependency can be avoided by configure options
--disable-libacl avoid use of ACL functions like acl_to_text()
--disable-xattr avoid use of xattr functions like listxattr()
--disable-zlib avoid use of zlib functions like compress2()
--disable-libjte avoid use of libjte functions
See INSTALL file for general options of ./configure.
------------------------------------------------------------------------------
libisofs is a library to create an ISO-9660 filesystem, supports extensions
@ -23,7 +78,7 @@ Features:
- Creates ISO-9660 images from local files.
- Support for RockRidge and Joliet extensions.
- Support for ISO-9660:1999 (version 2).
- Support for El-Torito bootable images.
- Support for El-Torito bootable images. Tested are: PC-BIOS and EFI.
- Support for multi-extent data files up to 400 GB (level 3).
- Full-featured edition of the image files, including: addition of new
files, removing of existent files, moving files, renaming files,
@ -67,8 +122,9 @@ Features:
Requirements:
-------------
- libburn 0.4.2 headers must be installed at compile time. It is not required
at runtime.
- iconv() functions for character set conversion must be available.
Either implicitely as in Linux or by a separate library like libiconv
on FreeBSD.
Know bugs:
----------
@ -78,31 +134,20 @@ Multisession and image growing can lead to undesired results in several cases:
a) Images with unsupported features, such as:
- UDF.
- HSF/HFS+ or other Mac extensions.
- El-Torito with multiple entries.
- ECMA-119 with extended attributes.
- Non El-Torito boot info.
- ECMA-119 Extended attributes.
- ...
In all these cases, the resulting new image (or new session) could lack some
features of the original image.
features of the original image. Nevertheless, the ECMA-119 System Area with
an eventual Master Boot Record gets preserved by default.
In some cases libisofs will issue warning messages, or even refuse to grow
or modify the image. Others remain undetected. Images created with libisofs
do not have this problems.
b) Bootable El-Torito images may have several problems, that result in a new
image that is not bootable, or that boots from an outdated session. In many
cases it is recommended to add boot info again in the new session.
- isolinux images won't be bootable after a modify. This is because
isolinux images need to have hardcoded the root dir lba. libisofs cannot
know whether an image is an isolinux image or not, so the user is
responsible to tell libisofs that it must patch the image, with the
el_torito_patch_isolinux_image() function. This problem could also exists
on other boot images.
- Most boot images are highly dependent of the image contents, so if the
user moves or removes some files on image it is possible they won't boot
anymore.
- There is no safer way to modify hidden boot images, as the size of the
boot image can't be figured out.
b) Bootable El-Torito images may have problems, that result in a new image that
is not bootable, or that boots from an outdated session. In some cases it
might be necessary to add boot info again in a new first session.
- There is no safe way to modify hidden boot images, as the size of the
boot image can't be figured out.
c) Generated images could have different ECMA-119 low level names, due to
different way to mangle names, to new files added that force old files to
@ -113,38 +158,6 @@ c) Generated images could have different ECMA-119 low level names, due to
relaxed contraints), otherwise libisofs might arbitrarily change the names.
------------------------------------------------------------------------------
Download, Build and Installation
libisofs code is mantained in a Bazaar repository at Launchpad
(https://launchpad.net/libisofs/). You can download it with:
$ bzr branch lp:libisofs
Our build system is based on autotools. For preparing the build you will need
autotools of at least version 1.7. If you have download the code from the
repository, first of all you need to execute
./autogen.sh
on toplevel dir to execute autotools.
Alternatively you may unpack a release tarball for which you do not need
autotools installed.
To build libisofs it should be sufficient to go into its toplevel directory
and execute
./configure --prefix=/usr
make
To make the libraries accessible for running resp. developing applications
make install
See INSTALL file for further details.
------------------------------------------------------------------------------
This program is free software; you can redistribute it and/or modify
@ -195,5 +208,5 @@ We are firmly committed to allow GPLv2+ now and with future releases.
Signed: Mario Danic, Thomas Schmitt
Agreement joined later by: Vreixo Formoso
Public contact: <libburn-hackers@pykix.org>
Public contact: <bug-xorriso@gnu.org>

View File

@ -1,7 +1,12 @@
dnl Copyright (c) 2009 - 2019 Thomas Schmitt
dnl Provided under the terms of the GNU General Public License version 2 or later.
AC_DEFUN([LIBBURNIA_SET_FLAGS],
[
case $target_os in
freebsd*)
freebsd* | netbsd*)
LDFLAGS="$LDFLAGS -L/usr/local/lib"
CPPFLAGS="$CPPFLAGS -I/usr/local/include"
;;
@ -16,13 +21,21 @@ AC_DEFUN([TARGET_SHIZZLE],
AC_MSG_CHECKING([target operating system])
LIBBURNIA_SUPP_ACL=none
LIBBURNIA_SUPP_FATTR=none
LIBBURNIA_LDCONFIG_CMD="echo 'No ldconfig run performed. If needed, configure manually for:'"
case $target in
*-*-linux*)
ARCH=linux
LIBBURN_ARCH_LIBS=
LIBBURNIA_SUPP_ACL=libacl
LIBBURNIA_SUPP_FATTR=xattr
LIBBURNIA_LDCONFIG_CMD=ldconfig
;;
*-*-freebsd*)
ARCH=freebsd
LIBBURNIA_SUPP_ACL=libacl
LIBBURNIA_SUPP_FATTR=extattr
LIBBURN_ARCH_LIBS=-lcam
# This may later be overridden by configure --enable-libdir-pkgconfig
@ -50,8 +63,9 @@ dnl From Bruno Haible.
dnl
AC_DEFUN([LIBBURNIA_CHECK_ICONV],
[
dnl Check whether it is allowed to link with -liconv
AC_MSG_CHECKING([for separate -liconv ])
AC_MSG_CHECKING([for iconv() in separate -liconv ])
libburnia_liconv="no"
libburnia_save_LIBS="$LIBS"
LIBS="$LIBS -liconv"
@ -65,6 +79,13 @@ AC_DEFUN([LIBBURNIA_CHECK_ICONV],
)
AC_MSG_RESULT([$libburnia_liconv])
if test x"$libburnia_save_LIBS" = x"$LIBS"
then
dnl GNU iconv has no function iconv() but libiconv() and a macro iconv()
dnl It is not tested whether this is detected by above macro.
AC_CHECK_LIB(iconv, libiconv, , )
fi
dnl Check for iconv(..., const char **inbuf, ...)
AC_MSG_CHECKING([for const qualifier with iconv() ])
AC_TRY_COMPILE([
@ -79,6 +100,67 @@ size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, si
])
dnl LIBBURNIA_ASSERT_ICONV is by Thomas Schmitt, libburnia project
dnl
AC_DEFUN([LIBBURNIA_ASSERT_ICONV],
[
if test x$LIBISOFS_ASSUME_ICONV = x
then
dnl Check for the essential gestures of libisofs/util.c
AC_MSG_CHECKING([for iconv() to be accessible now ])
AC_TRY_LINK([
#include <stdlib.h>
#include <wchar.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include <stdio.h>
#include <limits.h>
#include <iconv.h>
#include <locale.h>
#include <langinfo.h>
#include <unistd.h>],
[iconv_t cd = iconv_open("","");
iconv(cd,NULL,NULL,NULL,NULL);
iconv_close(cd);
], [iconv_test="yes"], [iconv_test="no"]
)
AC_MSG_RESULT([$iconv_test])
if test x$iconv_test = xno
then
echo >&2
echo "Cannot get function iconv() to work. Configuration aborted." >&2
echo "Check whether your system needs a separate libiconv installed." >&2
echo "If it is installed but not found, try something like" >&2
echo ' export LDFLAGS="$LDFLAGS -L/usr/local/lib"' >&2
echo ' export CPPFLAGS="$CPPFLAGS -I/usr/local/include"' >&2
echo ' export LIBS="$LIBS -liconv"' >&2
echo "You may override this test by exporting variable" >&2
echo " LIBISOFS_ASSUME_ICONV=yes" >&2
echo >&2
(exit 1); exit 1;
fi
fi
])
dnl LIBISOFS_ASSERT_VERS_LIBS is by Thomas Schmitt, libburnia project
dnl It tests whether -Wl,--version-script=... works with the compiler
AC_DEFUN([LIBISOFS_ASSERT_VERS_LIBS],
[
libburnia_save_LDFLAGS="$LDFLAGS"
LDFLAGS="$LDFLAGS -Wl,--version-script=$srcdir/libisofs/libisofs.ver"
AC_TRY_LINK([#include <stdio.h>], [printf("Hello\n");],
[vers_libs_test="yes"], [vers_libs_test="no"])
if test x$vers_libs_test = xyes
then
LIBLDFLAGS="-Wl,--version-script=$srcdir/libisofs/libisofs.ver"
fi
LDFLAGS="$libburnia_save_LDFLAGS"
AC_SUBST(LIBLDFLAGS)
])
dnl LIBBURNIA_SET_PKGCONFIG determines the install directory for the *.pc file.
dnl Important: Must be performed _after_ TARGET_SHIZZLE
dnl
@ -129,3 +211,15 @@ dnl For debugging only
])
dnl LIBBURNIA_TRY_TIMEZONE is by Thomas Schmitt, libburnia project
dnl It tests whether the global variable exists and is suitable for
dnl integer arithmetics.
AC_DEFUN([LIBBURNIA_TRY_TIMEZONE],
[
echo -n "checking for timezone variable ... "
AC_TRY_LINK([ #include <time.h> ], [long int i; i = 1 - timezone; ],
[LIBBURNIA_TIMEZONE="timezone"], [LIBBURNIA_TIMEZONE="0"]
)
echo "$LIBBURNIA_TIMEZONE"
])

View File

@ -1,10 +1,7 @@
#!/bin/sh -x
aclocal
aclocal -I .
libtoolize --copy --force
autoconf
# ts A61101 : libburn is not prepared for config.h
# autoheader
automake --foreign --add-missing --copy --include-deps

View File

@ -1,4 +1,4 @@
AC_INIT([libisofs], [0.6.28], [http://libburnia-project.org])
AC_INIT([libisofs], [1.5.7], [http://libburnia-project.org])
AC_PREREQ([2.50])
dnl AC_CONFIG_HEADER([config.h])
@ -8,12 +8,7 @@ AC_CANONICAL_TARGET
LIBBURNIA_SET_FLAGS
AM_INIT_AUTOMAKE([subdir-objects])
dnl A61101 This breaks Linux build (makes 32 bit off_t)
dnl http://sourceware.org/autobook/autobook/autobook_96.html says
dnl one must include some config.h and this was a pitfall.
dnl So why dig the pit at all ?
dnl AM_CONFIG_HEADER(config.h)
AC_CONFIG_MACRO_DIR([./])
dnl
dnl if MAJOR or MINOR version changes, be sure to change AC_INIT above to match
@ -31,8 +26,8 @@ dnl
dnl LT_CURRENT, LT_REVISION and LT_AGE get set directly now.
dnl
dnl SONAME of the emerging library is LT_CURRENT - LT_AGE.
dnl The linker will do no finer checks. Especially no age range check for
dnl the cdrskin binary. If SONAME matches, then the couple starts.
dnl The linker will do no finer checks. If SONAME matches, then the couple
dnl starts.
dnl
dnl Therefore a run time check is provided by libisofs function
dnl iso_lib_version(). It returns the major, minor and micro revision of the
@ -44,9 +39,9 @@ dnl It rather feeds the API function iso_lib_version().
dnl
dnl If LIBISOFS_*_VERSION changes, be sure to change AC_INIT above to match.
dnl
LIBISOFS_MAJOR_VERSION=0
LIBISOFS_MINOR_VERSION=6
LIBISOFS_MICRO_VERSION=28
LIBISOFS_MAJOR_VERSION=1
LIBISOFS_MINOR_VERSION=5
LIBISOFS_MICRO_VERSION=7
LIBISOFS_VERSION=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION.$LIBISOFS_MICRO_VERSION
AC_SUBST(LIBISOFS_MAJOR_VERSION)
@ -56,10 +51,10 @@ AC_SUBST(LIBISOFS_VERSION)
dnl Libtool versioning
LT_RELEASE=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION
# 2010.02.10 development jump has not yet happened
# SONAME = 30 - 24 = 6 . Library name = libisofs.6.24.0
LT_CURRENT=30
LT_AGE=24
dnl 2023.05.07 development jump has not yet happened
dnl SONAME = 98 - 92 = 6 . Library name = libisofs.6.92.0
LT_CURRENT=98
LT_AGE=92
LT_REVISION=0
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
@ -72,12 +67,12 @@ AC_SUBST(LT_CURRENT_MINUS_AGE)
AC_PREFIX_DEFAULT([/usr/local])
test "$prefix" = "NONE" && prefix=$ac_default_prefix
AM_MAINTAINER_MODE
dnl ts B90405 : Disabled on advise of Ross Burton
dnl AM_MAINTAINER_MODE
AM_PROG_CC_C_O
AC_C_CONST
AC_C_INLINE
AC_C_BIGENDIAN
dnl Large file support
AC_SYS_LARGEFILE
@ -91,14 +86,19 @@ dnl If iconv(3) is in an extra lib, then it gets added to variable LIBS.
dnl If not, then no -liconv will be added.
LIBBURNIA_CHECK_ICONV
dnl To abort configuration if iconv() still cannot be compiled
LIBBURNIA_ASSERT_ICONV
AC_PROG_LIBTOOL
AC_SUBST(LIBTOOL_DEPS)
LIBTOOL="$LIBTOOL --silent"
# LIBTOOL="$LIBTOOL --silent"
AC_PROG_INSTALL
AC_CHECK_HEADERS()
dnl GNU libtool checks them by default/unconditionally, but slibtool does not.
dnl So accept the ugly double check and -DHAVE_*_H arguments with GNU libtool.
AC_CHECK_HEADERS(stdint.h inttypes.h stdlib.h)
dnl Use GNU extensions if available
AC_DEFINE(_GNU_SOURCE, 1)
@ -116,6 +116,16 @@ AC_CHECK_DECL([timegm],
,
[#include <time.h>])
dnl Whether timezone is an integer variable
AH_TEMPLATE([Libburnia_timezonE], [Either timezone or 0])
LIBBURNIA_TRY_TIMEZONE
if test x$LIBBURNIA_TIMEZONE = xtimezone
then
AC_DEFINE([Libburnia_timezonE], [timezone])
else
AC_DEFINE([Libburnia_timezonE], [0])
fi
dnl Check if non standard eaccess() function is available
AC_CHECK_DECL([eaccess],
[AC_DEFINE(HAVE_EACCESS, 1, [Define this if eaccess function is available])],
@ -136,15 +146,15 @@ AC_ARG_ENABLE(debug,
, enable_debug=yes)
if test x$enable_debug != xyes; then
if test x$GCC = xyes; then
CFLAGS="$CFLAGS -O3"
CFLAGS="$CFLAGS -fexpensive-optimizations"
CFLAGS="-O3 $CFLAGS"
CFLAGS="-fexpensive-optimizations $CFLAGS"
fi
CFLAGS="$CFLAGS -DNDEBUG"
CFLAGS="-DNDEBUG $CFLAGS"
else
if test x$GCC = xyes; then
CFLAGS="$CFLAGS -g -pedantic -Wall"
CFLAGS="-g -pedantic -Wall -Wextra -Wno-unused-parameter -Wno-char-subscripts $CFLAGS"
fi
CFLAGS="$CFLAGS -DDEBUG"
CFLAGS="-DDEBUG $CFLAGS"
fi
dnl Verbose debug to make libisofs issue more debug messages
@ -162,34 +172,154 @@ LIBBURNIA_SET_PKGCONFIG
dnl Add compiler-specific flags
AC_ARG_ENABLE(libacl,
[ --enable-libacl Enable use of libacl by libisofs, default=yes],
[ --enable-libacl Enable use of ACL functions by libisofs, default=yes],
, enable_libacl=yes)
if test "x$enable_libacl" = xyes; then
LIBACL_DEF=
has_acl_h_but_no_func=0
if test x$LIBBURNIA_SUPP_ACL = xlibacl
then
if test x$enable_libacl = xyes; then
dnl Check whether there is libacl-devel and libacl-runtime.
dnl If not, erase this macro which would enable use of acl_to_text and others
LIBACL_DEF="-DLibisofs_with_aaip_acL"
LIBACL_DEF="-DLibisofs_with_aaip_acL"
dnl The empty yes case obviously causes -lacl to be linked
AC_CHECK_HEADER(sys/acl.h, AC_CHECK_LIB(acl, acl_to_text, , LIBACL_DEF= ), LIBACL_DEF= )
AC_CHECK_HEADER(sys/acl.h, AC_CHECK_LIB(acl, acl_to_text, , has_acl_h_but_no_libacl=1 ), LIBACL_DEF= )
if test "$has_acl_h_but_no_libacl" = 1
then
AC_CHECK_LIB(c, acl_to_text, X= , LIBACL_DEF= )
fi
fi
fi
if test x$LIBACL_DEF = x-DLibisofs_with_aaip_acL
then
if test x$has_acl_h_but_no_libacl = x1
then
echo "enabled local processing of ACL"
else
echo "enabled libacl, local processing of ACL"
fi
else
LIBACL_DEF=
echo "disabled local processing of ACL"
fi
AC_SUBST(LIBACL_DEF)
dnl ts A90123
dnl ts A90123 - B80508
AC_ARG_ENABLE(xattr,
[ --enable-xattr Enable use of xattr by libisofs, default=yes],
, enable_xattr=yes)
if test "x$enable_xattr" = xyes; then
dnl Check whether there is the header for Linux xattr.
[ --enable-xattr Enable use of extended file attributes by libisofs, default=yes],
, enable_xattr=yes)
AC_ARG_ENABLE(xattr-h-pref-attr,
[ --enable-xattr-h-pref-attr Prefer include file attr/xattr.h over sys/xattr.h, default=no],
, enable_xattr_h_pref_attr=no)
XATTR_DEF=
XATTR_ADDON_DEF=
if test x"$LIBBURNIA_SUPP_FATTR" = xxattr
then
if test "x$enable_xattr" = xyes; then
dnl Check whether there is the header for Linux xattr.
dnl If not, erase this macro which would enable use of listxattr and others
XATTR_DEF="-DLibisofs_with_aaip_xattR"
AC_CHECK_HEADER(attr/xattr.h, AC_CHECK_LIB(c, listxattr, X= , XATTR_DEF= ), XATTR_DEF= )
else
XATTR_DEF=
XATTR_A_DEF=
XATTR_S_DEF=
if test x"$enable_xattr_h_pref_attr" = xyes
then
echo "prefering include file attr/xattr.h over sys/attr.h"
XATTR_A_DEF=1
AC_CHECK_HEADER(attr/xattr.h, AC_CHECK_LIB(c, listxattr, X= ,
XATTR_A_DEF= ), XATTR_A_DEF= )
if test x"$XATTR_A_DEF" = x1
then
XATTR_DEF="-DLibisofs_with_aaip_xattR"
else
XATTR_S_DEF=1
AC_CHECK_HEADER(sys/xattr.h, AC_CHECK_LIB(c, listxattr, X= ,
XATTR_S_DEF= ), XATTR_S_DEF= )
if test x"$XATTR_S_DEF" = x1
then
XATTR_DEF="-DLibisofs_with_aaip_xattR"
XATTR_ADDON_DEF="-DLibisofs_with_sys_xattR"
fi
fi
else
XATTR_S_DEF=1
AC_CHECK_HEADER(sys/xattr.h, AC_CHECK_LIB(c, listxattr, X= ,
XATTR_S_DEF= ), XATTR_S_DEF= )
if test x"$XATTR_S_DEF" = x1
then
XATTR_DEF="-DLibisofs_with_aaip_xattR"
XATTR_ADDON_DEF="-DLibisofs_with_sys_xattR"
else
XATTR_A_DEF=1
AC_CHECK_HEADER(attr/xattr.h, AC_CHECK_LIB(c, listxattr, X= ,
XATTR_A_DEF= ), XATTR_A_DEF= )
if test x"$XATTR_A_DEF" = x1
then
XATTR_DEF="-DLibisofs_with_aaip_xattR"
fi
fi
fi
if test x"$XATTR_S_DEF" = x1
then
echo "decided to include file sys/attr.h"
elif test x"$XATTR_A_DEF" = x1
then
echo "decided to include file attr/xattr.h"
fi
fi
elif test x"$LIBBURNIA_SUPP_FATTR" = xextattr
then
if test "x$enable_xattr" = xyes; then
XATTR_DEF="-DLibisofs_with_freebsd_extattR"
AC_CHECK_HEADER(sys/extattr.h, AC_CHECK_LIB(c, extattr_list_file, X=,
XATTR_DEF= ), XATTR_DEF= )
fi
fi
if test x$XATTR_DEF = x-DLibisofs_with_aaip_xattR
then
echo "enabled xattr, local processing of extended file attributes Linux style"
elif test x$XATTR_DEF = x-DLibisofs_with_freebsd_extattR
then
echo "enabled extattr, local processing of extended file attributes FreeBSD style"
else
echo "disabled local processing of extended file attributes"
fi
XATTR_DEF="$XATTR_DEF $XATTR_ADDON_DEF"
AC_SUBST(XATTR_DEF)
dnl ts C40713
LFA_DEF=
AC_ARG_ENABLE(lfa-flags,
[ --enable-lfa-flags Enable processing of Linux chattr(1) flags, default=yes],
, enable_lfa_flags=yes)
if test x"$enable_lfa_flags" = xyes; then
AC_CHECK_HEADER(linux/fs.h, LFA_DEF="-DLibisofs_with_aaip_lfa_flagS",
LFA_DEF=)
fi
if test x"$LFA_DEF" = x; then
echo "disabled Linux chattr(1) flags"
else
echo "enabled Linux chattr(1) flags"
fi
AC_SUBST(LFA_DEF)
dnl ts C41009
PROJID_DEF=
AC_ARG_ENABLE(projid,
[ --enable-projid Enable processing of XFS-style project id, default=yes],
, enable_projid=yes)
if test x"$enable_projid" = xyes; then
AC_CHECK_HEADER(linux/fs.h, PROJID_DEF="-DLibisofs_with_aaip_projiD",
PROJID_DEF=)
fi
if test x"$PROJID_DEF" = x; then
echo "disabled XFS-style project id"
else
echo "enabled XFS-style project id"
fi
AC_SUBST(PROJID_DEF)
dnl ts A90409
AC_ARG_ENABLE(zlib,
@ -208,6 +338,63 @@ else
fi
AC_SUBST(ZLIB_DEF)
dnl ts B00927
AC_ARG_ENABLE(libjte,
[ --enable-libjte Enable use of libjte >= 2.0 by libisofs, default=yes],
, enable_libjte=yes)
if test "x$enable_libjte" = xyes; then
LIBJTE_DEF="-DLibisofs_with_libjtE"
AC_CHECK_HEADER(libjte/libjte.h, AC_CHECK_LIB(jte, libjte_set_checksum_algorithm, , LIBJTE_DEF= ), LIBJTE_DEF= )
else
LIBJTE_DEF=
fi
AC_SUBST(LIBJTE_DEF)
dnl ts C50224
AC_ARG_ENABLE(dir-rec-size-check,
[ --enable-dir-rec-size-check Detailed check of directory size prediction, default=no],
, dir_rec_size_check=no)
if test x$enable_dir_rec_size_check = xyes; then
DIR_REC_SIZE_CHECK="-DLibisofs_dir_rec_size_checK"
echo "enabled detailed check of directory size prediction"
else
DIR_REC_SIZE_CHECK=
echo "disabled detailed check of directory size prediction"
fi
AC_SUBST(DIR_REC_SIZE_CHECK)
# Library versioning normally serves a complex purpose.
# Since libisofs obeys strict ABI backward compatibility, it needs only the
# simple feature to declare function names "global:" or "local:". Only the
# global ones are visible to applications at library load time.
AC_ARG_ENABLE(versioned-libs,
[ --enable-versioned-libs Enable strict symbol encapsulation , default=yes],
, enable_versioned_libs=yes)
if test x$enable_versioned_libs = xyes; then
vers_libs_test=no
LIBISOFS_ASSERT_VERS_LIBS
if test x$vers_libs_test = xno
then
echo "disabled strict symbol encapsulation (test failed)"
else
echo "enabled strict symbol encapsulation"
fi
else
echo "disabled strict symbol encapsulation"
fi
AC_ARG_ENABLE(ldconfig-at-install,
[ --enable-ldconfig-at-install On GNU/Linux run ldconfig, default=yes],
, ldconfig_at_install=yes)
if test x$ldconfig_at_install = xyes; then
dummy=dummy
else
LIBBURNIA_LDCONFIG_CMD="echo 'NOTE: ldconfig is disabled. If needed, configure manually for:'"
echo "disabled run of ldconfig during installation on GNU/Linux"
fi
AC_SUBST(LIBBURNIA_LDCONFIG_CMD)
AC_CONFIG_FILES([
Makefile

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 - 2009 Vreixo Formoso, Thomas Schmitt
* Copyright (c) 2007 - 2016 Vreixo Formoso, Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -24,7 +24,9 @@ static char helptext[][80] = {
" Output the contents of an iso image.",
" -iso_cat image_file path_in_image",
" Extract a file from a given ISO image and put out its content",
" to stdout. The file is addressed by path_in_image.",
" to stdout. The file is addressed by path_in_image. The ISO",
" image does not get loaded but rather the lookups are done",
" directly in the image file.",
" -iso_modify image_file absolute_directory_path output_file",
" Load an iso image, add a directory, and write complete image.",
" -iso_ms image_lba nwa image_file directory_path output_file",
@ -50,26 +52,30 @@ static char helptext[][80] = {
#include <fcntl.h>
#include <err.h>
#include <limits.h>
#include <errno.h>
#define LIBISOFS_WITHOUT_LIBBURN yes
#include "libisofs.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <err.h>
#ifndef PATH_MAX
#define PATH_MAX Libisofs_default_path_maX
#endif
/* ----------------------------- utilities -------------------------- */
void demo_report_iso_err(int err, char *occasion)
{
char *severity;
fprintf(stderr, "%s : err = 0x%X", occasion, (unsigned int) err);
if (err < 0) {
iso_sev_to_text(iso_error_get_severity(err), &severity);
fprintf(stderr, " -> %s '%s'", severity, iso_error_to_msg(err));
}
fprintf(stderr, "\n");
}
/* ------------------------- from demo/tree.c ----------------------- */
static void
@ -98,14 +104,17 @@ tree_print_dir(IsoDir *dir, int level)
int i;
IsoDirIter *iter;
IsoNode *node;
char *sp = alloca(level * 2 + 1);
char *sp;
sp = calloc(1, level * 2 + 1);
for (i = 0; i < level * 2; i += 2) {
sp[i] = '|';
sp[i+1] = ' ';
}
sp[level * 2-1] = '-';
if (level > 0)
sp[level * 2 - 1] = '-';
sp[level * 2] = '\0';
iso_dir_get_children(dir, &iter);
@ -132,6 +141,7 @@ tree_print_dir(IsoDir *dir, int level)
}
}
iso_dir_iter_free(iter);
free(sp);
}
int gesture_tree(int argc, char **argv)
@ -270,7 +280,7 @@ int gesture_iso(int argc, char **argv)
IsoImage *image;
struct burn_source *burn_src;
unsigned char buf[2048];
FILE *fd;
FILE *fp = NULL;
IsoWriteOpts *opts;
char *volid = "VOLID";
char *boot_img = NULL;
@ -281,7 +291,7 @@ int gesture_iso(int argc, char **argv)
case 'h':
iso_usage(argv);
iso_help();
exit(0);
goto ex;
break;
case 'J':
j = 1;
@ -303,7 +313,7 @@ int gesture_iso(int argc, char **argv)
break;
case '?':
iso_usage(argv);
exit(1);
goto ex;
break;
}
}
@ -311,30 +321,31 @@ int gesture_iso(int argc, char **argv)
if (argc < 2) {
printf ("Please pass directory from which to build ISO\n");
iso_usage(argv);
return 1;
goto ex;
}
if (argc < 3) {
printf ("Please supply output file\n");
iso_usage(argv);
return 1;
goto ex;
}
fd = fopen(argv[optind+1], "w");
if (!fd) {
fp = fopen(argv[optind+1], "w");
if (fp == NULL) {
err(1, "error opening output file");
goto ex;
}
result = iso_init();
if (result < 0) {
printf ("Can't initialize libisofs\n");
return 1;
goto ex;
}
iso_set_msgs_severities("NEVER", "ALL", "");
result = iso_image_new(volid, &image);
if (result < 0) {
printf ("Error creating image\n");
return 1;
goto ex;
}
iso_tree_set_follow_symlinks(image, 0);
iso_tree_set_ignore_hidden(image, 0);
@ -346,7 +357,7 @@ int gesture_iso(int argc, char **argv)
argv[optind]);
if (result < 0) {
printf ("Error adding directory %d\n", result);
return 1;
goto ex;
}
if (boot_img) {
@ -356,7 +367,7 @@ int gesture_iso(int argc, char **argv)
"/isolinux/boot.cat", &bootimg);
if (result < 0) {
printf ("Error adding boot image %d\n", result);
return 1;
goto ex;
}
el_torito_set_load_size(bootimg, 4);
el_torito_patch_isolinux_image(bootimg);
@ -364,8 +375,8 @@ int gesture_iso(int argc, char **argv)
result = iso_write_opts_new(&opts, 0);
if (result < 0) {
printf ("Cant create write opts, error %d\n", result);
return 1;
printf ("Cannot create write opts, error %d\n", result);
goto ex;
}
iso_write_opts_set_iso_level(opts, level);
iso_write_opts_set_rockridge(opts, rr);
@ -374,22 +385,30 @@ int gesture_iso(int argc, char **argv)
result = iso_image_create_burn_source(image, opts, &burn_src);
if (result < 0) {
printf ("Cant create image, error %d\n", result);
return 1;
printf ("Cannot create image, error %d\n", result);
goto ex;
}
iso_write_opts_free(opts);
while (burn_src->read_xt(burn_src, buf, 2048) == 2048) {
fwrite(buf, 1, 2048, fd);
result = fwrite(buf, 1, 2048, fp);
if (result < 2048) {
printf ("Cannot write block. errno= %d\n", errno);
goto ex;
}
}
fclose(fd);
fclose(fp);
burn_src->free_data(burn_src);
free(burn_src);
iso_image_unref(image);
iso_finish();
return 0;
ex:;
if (fp != NULL)
fclose(fp);
return 1;
}
@ -436,14 +455,17 @@ iso_read_print_dir(IsoFileSource *dir, int level)
int ret, i;
IsoFileSource *file;
struct stat info;
char *sp = alloca(level * 2 + 1);
char *sp;
sp = calloc(1, level * 2 + 1);
for (i = 0; i < level * 2; i += 2) {
sp[i] = '|';
sp[i+1] = ' ';
}
sp[level * 2-1] = '-';
if (level > 0)
sp[level * 2 - 1] = '-';
sp[level * 2] = '\0';
ret = iso_file_source_open(dir);
@ -466,41 +488,48 @@ iso_read_print_dir(IsoFileSource *dir, int level)
if (ret < 0) {
printf ("Can't print dir\n");
}
free(sp);
}
int gesture_iso_read(int argc, char **argv)
{
int result;
IsoImageFilesystem *fs;
IsoDataSource *src;
IsoFileSource *root;
IsoReadOpts *ropts;
int result, initialized = 0, return_val = 1;
IsoImageFilesystem *fs = NULL;
IsoDataSource *src = NULL;
IsoFileSource *root = NULL;
IsoReadOpts *ropts = NULL;
if (argc != 2) {
printf ("You need to specify a valid path\n");
return 1;
goto ex;
}
iso_init();
result = iso_init();
if (result < 0) {
demo_report_iso_err(result, "Cannot init libisofs");
goto ex;
}
initialized = 1;
iso_set_msgs_severities("NEVER", "ALL", "");
result = iso_data_source_new_from_file(argv[1], &src);
if (result < 0) {
printf ("Error creating data source\n");
return 1;
demo_report_iso_err(result, "Error creating data source");
goto ex;
}
result = iso_read_opts_new(&ropts, 0);
if (result < 0) {
fprintf(stderr, "Error creating read options\n");
return 1;
demo_report_iso_err(result, "Error creating read options");
goto ex;
}
result = iso_image_filesystem_new(src, ropts, 1, &fs);
iso_read_opts_free(ropts);
if (result < 0) {
printf ("Error creating filesystem\n");
return 1;
demo_report_iso_err(result, "Error creating filesystem");
goto ex;
}
iso_read_opts_free(ropts);
ropts = NULL;
printf("\nVOLUME INFORMATION\n");
printf("==================\n\n");
@ -519,18 +548,27 @@ int gesture_iso_read(int argc, char **argv)
result = fs->get_root(fs, &root);
if (result < 0) {
printf ("Can't get root %d\n", result);
return 1;
demo_report_iso_err(result, "Cannot get root object");
goto ex;
}
/* iso_read_print_file_src(root); */
iso_read_print_dir(root, 0);
iso_file_source_unref(root);
fs->close(fs);
iso_filesystem_unref((IsoFilesystem*)fs);
iso_data_source_unref(src);
iso_finish();
return 0;
return_val = 0;
ex:;
if (root != NULL)
iso_file_source_unref(root);
if (ropts != NULL)
iso_read_opts_free(ropts);
if (fs != NULL) {
fs->close(fs);
iso_filesystem_unref((IsoFilesystem*)fs);
}
if (src != NULL)
iso_data_source_unref(src);
if (initialized)
iso_finish();
return return_val;
}
@ -539,79 +577,101 @@ int gesture_iso_read(int argc, char **argv)
int gesture_iso_cat(int argc, char **argv)
{
int res;
IsoFilesystem *fs;
IsoFileSource *file;
int res, write_ret, ret;
IsoFilesystem *fs = NULL;
IsoFileSource *file = NULL;
struct stat info;
IsoDataSource *src;
IsoReadOpts *opts;
IsoDataSource *src = NULL;
IsoReadOpts *opts = NULL;
if (argc != 3) {
fprintf(stderr, "Usage: isocat /path/to/image /path/to/file\n");
fprintf(stderr, "Usage: -iso_cat /path/to/image /path/to/file\n");
return 1;
}
res = iso_init();
if (res < 0) {
fprintf(stderr, "Can't init libisofs\n");
demo_report_iso_err(res, "Cannot init libisofs");
return 1;
}
/* Important Note:
From here on memory objects get created which need to be freed in
the end. Therefore in case of problems no direct return, but rather
a hop to label "ex:", where cleanup happens.
*/
res = iso_data_source_new_from_file(argv[1], &src);
if (res < 0) {
fprintf(stderr, "Error creating data source\n");
return 1;
demo_report_iso_err(res, "Error creating data source object");
ret = 1; goto ex;
}
res = iso_read_opts_new(&opts, 0);
if (res < 0) {
fprintf(stderr, "Error creating read options\n");
return 1;
demo_report_iso_err(res, "Error creating read options object");
ret = 1; goto ex;
}
res = iso_image_filesystem_new(src, opts, 1, &fs);
if (res < 0) {
fprintf(stderr, "Error creating filesystem\n");
return 1;
demo_report_iso_err(res, "Error creating filesystem object");
ret = 1; goto ex;
}
iso_read_opts_free(opts);
opts = NULL;
res = fs->get_by_path(fs, argv[2], &file);
if (res < 0) {
fprintf(stderr, "Can't get file, err = %d\n", res);
return 1;
demo_report_iso_err(res, "Cannot get file object with given path");
ret = 1; goto ex;
}
res = iso_file_source_lstat(file, &info);
if (res < 0) {
fprintf(stderr, "Can't stat file, err = %d\n", res);
return 1;
demo_report_iso_err(res,
"Cannot inquire type of file object with given path");
ret = 1; goto ex;
}
if (S_ISDIR(info.st_mode)) {
fprintf(stderr, "Path refers to a directory!!\n");
return 1;
ret = 1; goto ex;
} else {
char buf[1024];
res = iso_file_source_open(file);
if (res < 0) {
fprintf(stderr, "Can't open file, err = %d\n", res);
return 1;
demo_report_iso_err(res,
"Cannot open file object with given path");
ret = 1; goto ex;
}
while ((res = iso_file_source_read(file, buf, 1024)) > 0) {
fwrite(buf, 1, res, stdout);
}
if (res < 0) {
fprintf(stderr, "Error reading, err = %d\n", res);
return 1;
write_ret = fwrite(buf, 1, res, stdout);
if (write_ret < res) {
printf ("Cannot write block to stdout. errno= %d\n", errno);
iso_file_source_close(file);
ret = 1; goto ex;
}
}
iso_file_source_close(file);
if (res < 0) {
demo_report_iso_err(res, "Error while reading data content");
fprintf(stderr, "Error reading, err = 0x%X\n", (unsigned int) res);
ret = 1; goto ex;
}
}
iso_file_source_unref(file);
iso_filesystem_unref(fs);
iso_data_source_unref(src);
ret = 0;
ex:;
if (file != NULL)
iso_file_source_unref(file);
if (fs != NULL)
iso_filesystem_unref(fs);
if (opts != NULL)
iso_read_opts_free(opts);
if (src != NULL)
iso_data_source_unref(src);
iso_finish();
return 0;
return ret;
}
@ -625,40 +685,46 @@ void iso_modify_usage(char **argv)
int gesture_iso_modify(int argc, char **argv)
{
int result;
IsoImage *image;
IsoDataSource *src;
struct burn_source *burn_src;
int result, return_val = 1, initialized = 0;
IsoImage *image = NULL;
IsoDataSource *src = NULL;
struct burn_source *burn_src = NULL;
unsigned char buf[2048];
FILE *fd;
IsoWriteOpts *opts;
IsoReadOpts *ropts;
FILE *fp = NULL;
IsoWriteOpts *opts = NULL;
IsoReadOpts *ropts = NULL;
if (argc < 4) {
iso_modify_usage(argv);
return 1;
goto ex;
}
fd = fopen(argv[3], "w");
if (!fd) {
fp = fopen(argv[3], "w");
if (fp == NULL) {
err(1, "error opening output file");
goto ex;
}
iso_init();
result = iso_init();
if (result < 0) {
demo_report_iso_err(result, "Cannot init libisofs");
goto ex;
}
initialized = 1;
iso_set_msgs_severities("NEVER", "ALL", "");
/* create the data source to accesss previous image */
result = iso_data_source_new_from_file(argv[1], &src);
if (result < 0) {
printf ("Error creating data source\n");
return 1;
demo_report_iso_err(result, "Error creating data source");
goto ex;
}
/* create the image context */
result = iso_image_new("volume_id", &image);
if (result < 0) {
printf ("Error creating image\n");
return 1;
demo_report_iso_err(result, "Error creating image");
goto ex;
}
iso_tree_set_follow_symlinks(image, 0);
iso_tree_set_ignore_hidden(image, 0);
@ -666,50 +732,75 @@ int gesture_iso_modify(int argc, char **argv)
/* import previous image */
result = iso_read_opts_new(&ropts, 0);
if (result < 0) {
fprintf(stderr, "Error creating read options\n");
return 1;
demo_report_iso_err(result, "Error creating read options");
goto ex;
}
result = iso_image_import(image, src, ropts, NULL);
iso_read_opts_free(ropts);
iso_data_source_unref(src);
if (result < 0) {
printf ("Error importing previous session %d\n", result);
return 1;
demo_report_iso_err(result, "Error importing previous session");
goto ex;
}
/* (One could of course keep them alive until cleanup) */
iso_read_opts_free(ropts);
ropts = NULL;
iso_data_source_unref(src);
src = NULL;
/* add new dir */
result = iso_tree_add_dir_rec(image, iso_image_get_root(image), argv[2]);
if (result < 0) {
printf ("Error adding directory %d\n", result);
return 1;
demo_report_iso_err(result, "Error adding directory");
goto ex;
}
/* generate a new image with both previous and added contents */
/* Generate a new image with both previous and added contents.
Profile 1 means Rock Ridge and ISO level 3.
*/
result = iso_write_opts_new(&opts, 1);
if (result < 0) {
printf("Cant create write opts, error %d\n", result);
return 1;
demo_report_iso_err(result, "Cannot create write opts");
goto ex;
}
/* for isolinux: iso_write_opts_set_allow_full_ascii(opts, 1); */
/* Prefer specs violation over relocation deep directories */
iso_write_opts_set_allow_deep_paths(opts, 1);
/* For MS-Windows readers : iso_write_opts_set_joliet(opts, 1); */
result = iso_image_create_burn_source(image, opts, &burn_src);
if (result < 0) {
printf ("Cant create image, error %d\n", result);
return 1;
demo_report_iso_err(result, "Cannot create image object");
goto ex;
}
iso_write_opts_free(opts);
opts = NULL;
while (burn_src->read_xt(burn_src, buf, 2048) == 2048) {
fwrite(buf, 1, 2048, fd);
result = fwrite(buf, 1, 2048, fp);
if (result < 2048) {
fprintf (stderr, "Cannot write block. errno= %d\n", errno);
goto ex;
}
}
fclose(fd);
burn_src->free_data(burn_src);
free(burn_src);
iso_image_unref(image);
iso_finish();
return 0;
return_val = 0;
ex:
if (fp != NULL)
fclose(fp);
if (opts != NULL)
iso_write_opts_free(opts);
if (burn_src != NULL) {
burn_src->free_data(burn_src);
free(burn_src);
}
if (image != NULL)
iso_image_unref(image);
if (ropts != NULL)
iso_read_opts_free(ropts);
if (src != NULL)
iso_data_source_unref(src);
if (initialized)
iso_finish();
return return_val;
}
@ -723,47 +814,54 @@ void iso_ms_usage(char **argv)
int gesture_iso_ms(int argc, char **argv)
{
int result;
IsoImage *image;
IsoDataSource *src;
struct burn_source *burn_src;
int result, return_val = 1, initialized = 0;
IsoImage *image = NULL;
IsoDataSource *src = NULL;
struct burn_source *burn_src = NULL;
unsigned char buf[2048];
FILE *fd;
IsoWriteOpts *opts;
IsoReadOpts *ropts;
FILE *fp = NULL;
IsoWriteOpts *opts = NULL;
IsoReadOpts *ropts = NULL;
uint32_t ms_block;
if (argc < 6) {
iso_ms_usage(argv);
return 1;
goto ex;
}
if (strcmp(argv[3], argv[5]) == 0) {
fprintf(stderr,
"image_file and output_file must not be the same file.\n");
return 1;
goto ex;
}
fd = fopen(argv[5], "w");
if (!fd) {
fp = fopen(argv[5], "w");
if (!fp) {
err(1, "error opening output file");
goto ex;
}
iso_init();
result = iso_init();
if (result < 0) {
demo_report_iso_err(result, "Cannot init libisofs");
goto ex;
}
initialized = 1;
iso_set_msgs_severities("NEVER", "ALL", "");
/* create the data source to accesss previous image */
result = iso_data_source_new_from_file(argv[3], &src);
if (result < 0) {
printf ("Error creating data source\n");
return 1;
demo_report_iso_err(result, "Error creating data source");
goto ex;
}
/* create the image context */
result = iso_image_new("volume_id", &image);
if (result < 0) {
printf ("Error creating image\n");
return 1;
demo_report_iso_err(result, "Error creating image");
goto ex;
}
iso_tree_set_follow_symlinks(image, 0);
iso_tree_set_ignore_hidden(image, 0);
@ -772,29 +870,31 @@ int gesture_iso_ms(int argc, char **argv)
result = iso_read_opts_new(&ropts, 0);
if (result < 0) {
fprintf(stderr, "Error creating read options\n");
return 1;
goto ex;
}
iso_read_opts_set_start_block(ropts, atoi(argv[1]));
result = iso_image_import(image, src, ropts, NULL);
iso_read_opts_free(ropts);
ropts = NULL;
iso_data_source_unref(src);
src = NULL;
if (result < 0) {
printf ("Error importing previous session %d\n", result);
return 1;
demo_report_iso_err(result, "Error importing previous session");
goto ex;
}
/* add new dir */
result = iso_tree_add_dir_rec(image, iso_image_get_root(image), argv[4]);
if (result < 0) {
printf ("Error adding directory %d\n", result);
return 1;
demo_report_iso_err(result, "Error adding directory");
goto ex;
}
/* generate a multisession image with new contents */
result = iso_write_opts_new(&opts, 1);
if (result < 0) {
printf("Cant create write opts, error %d\n", result);
return 1;
demo_report_iso_err(result, "Cannot create write opts");
goto ex;
}
/* round up to 32kb aligment = 16 block */
@ -804,21 +904,39 @@ int gesture_iso_ms(int argc, char **argv)
result = iso_image_create_burn_source(image, opts, &burn_src);
if (result < 0) {
printf ("Cant create image, error %d\n", result);
return 1;
printf ("Cannot create image, error %d\n", result);
goto ex;
}
iso_write_opts_free(opts);
opts = NULL;
while (burn_src->read_xt(burn_src, buf, 2048) == 2048) {
fwrite(buf, 1, 2048, fd);
result = fwrite(buf, 1, 2048, fp);
if (result < 2048) {
printf ("Cannot write block. errno= %d\n", errno);
goto ex;
}
}
fclose(fd);
burn_src->free_data(burn_src);
free(burn_src);
iso_image_unref(image);
iso_finish();
return 0;
return_val = 0;
ex:;
if (burn_src != NULL) {
burn_src->free_data(burn_src);
free(burn_src);
}
if (opts != NULL)
iso_write_opts_free(opts);
if (image)
iso_image_unref(image);
if (ropts != NULL)
iso_read_opts_free(ropts);
if (src != NULL)
iso_data_source_unref(src);
if (initialized)
iso_finish();
if (fp != NULL)
fclose(fp);
return return_val;
}

1709
doc/boot_sectors.txt Normal file

File diff suppressed because it is too large Load Diff

View File

@ -79,7 +79,7 @@ Tag_id distinguishes the following tag types
"libisofs_checksum_tag_v1" Session tag
A relocated superblock may appear at LBA 0 of an image which was produced for
being stored in a disk file or on overwriteable media (e.g. DVD+RW, BD-RE).
being stored in a disk file or on overwritable media (e.g. DVD+RW, BD-RE).
Typically there is a first session recorded with a superblock at LBA 32 and
the next session may follow shortly after its session tag. (Typically at the
next block address which is divisible by 32.) Normally no session starts after
@ -131,10 +131,10 @@ checksums as strings of 32 hex digits.
range_start=
The block address where the session is supposed to start. If this does not
match the session start on media then the volume descriptors of the
image have been relocated. (This can happen with overwriteable media. If
image have been relocated. (This can happen with overwritable media. If
checksumming started at LBA 0 and finds range_start=32, then one has to
restart checksumming at LBA 32. See libburn/doc/cookbook.txt
"ISO 9660 multi-session emulation on overwriteable media" for background
"ISO 9660 multi-session emulation on overwritable media" for background
information.)
range_size=
@ -189,7 +189,7 @@ With tag type 2:
Keep the original MD5 context of the data blocks and clone one for obtaining
the MD5 bytes.
If the MD5s match, then compute the checksum block and all folowing ones into
If the MD5s match, then compute the checksum block and all following ones into
the kept MD5 context and go on with reading and computing for the tree checksum
tag. This will be found at block address next_tag, verified and parsed by:
iso_util_decode_md5_tag(block, &tag_type, &pos,
@ -211,7 +211,7 @@ next_tag. Go on by looking for tag type 2 and follow above prescription.
Checking the Data Part of the Session
In order to check the trustworthyness of a whole session, continue reading
In order to check the trustworthiness of a whole session, continue reading
and checksumming after the tree was verified.
Read and checksum the blocks. When reaching block address next_tag (from the
@ -232,7 +232,7 @@ If the media is sequentially recordable, obtain a table of content and check
the first track of each session as prescribed above in Checking Before Image
Tree Loading and in Checking the Data Part of the Session.
With disk files or overwriteable media, look for a relocated superblock tag
With disk files or overwritable media, look for a relocated superblock tag
but do not hop to address next_tag (given by session_start=). Instead look at
LBA 32 for the first session and check it as prescribed above.
After reaching its end, round up the read address to the next multiple of 32
@ -305,3 +305,16 @@ The size of the volume is 2456606865 bytes, which have a MD5 sum of
The checksum of "2_2 B00109.143415 2456606865 485bbef110870c45754d7adcc844a72c"
is c2355d5ea3c94d792ff5893dfe0d6d7b.
-------------------------------------------------------------------------------
This text is under
Copyright (c) 2009 - 2010 Thomas Schmitt <scdbackup@gmx.net>
It shall only be modified in sync with libisofs and other software which
makes use of libisofs checksums. Please mail change requests to mailing list
<libburn-hackers@pykix.org> or to the copyright holder in private.
Only if you cannot reach the copyright holder for at least one month it is
permissible to modify this text under the same license as the affected
copy of libisofs.
If you do so, you commit yourself to taking reasonable effort to stay in
sync with the other interested users of this text.

View File

@ -19,9 +19,13 @@ Contents:
-------------------------------------------------------------------------------
1. References:
Meanwhile this is specified in ECMA-119 4th Edition of 2019 by the description
of the Enhanced Volume Descriptor.
The old name "ISO 9660:1999" comes from:
ISO/IEC DIS 9660:1999(E) "Information processing. Volume and file structure of
CD­-ROM for Information Interchange"
-------------------------------------------------------------------------------
2. General

View File

@ -154,13 +154,6 @@ QT_AUTOBRIEF = NO
MULTILINE_CPP_IS_BRIEF = YES
# If the DETAILS_AT_TOP tag is set to YES then Doxygen
# will output the detailed description near the top, like JavaDoc.
# If set to NO, the detailed description appears after the member
# documentation.
DETAILS_AT_TOP = YES
# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
# member inherits the documentation from any documented member that it
# re-implements.
@ -401,12 +394,6 @@ MAX_INITIALIZER_LINES = 30
SHOW_USED_FILES = YES
# If the sources in your project are distributed over multiple directories
# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
# in the documentation. The default is NO.
SHOW_DIRECTORIES = NO
# The FILE_VERSION_FILTER tag can be used to specify a program or script that
# doxygen should invoke to get the current version for each file (typically from the
# version control system). Doxygen will invoke the program by executing (via
@ -534,7 +521,7 @@ EXCLUDE_SYMBOLS =
# directories that contain example code fragments that are included (see
# the \include command).
EXAMPLE_PATH = test
EXAMPLE_PATH = demo/demo.c
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
@ -705,12 +692,6 @@ HTML_FOOTER =
HTML_STYLESHEET =
# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
# files or namespaces will be aligned in HTML using tables. If set to
# NO a bullet list will be used.
HTML_ALIGN_MEMBERS = YES
# If the GENERATE_HTMLHELP tag is set to YES, additional index files
# will be generated that can be used as input for tools like the
# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
@ -945,18 +926,6 @@ GENERATE_XML = NO
XML_OUTPUT = xml
# The XML_SCHEMA tag can be used to specify an XML schema,
# which can be used by a validating XML parser to check the
# syntax of the XML files.
XML_SCHEMA =
# The XML_DTD tag can be used to specify an XML DTD,
# which can be used by a validating XML parser to check the
# syntax of the XML files.
XML_DTD =
# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
# dump the program listings (including syntax highlighting
# and cross-referencing information) to the XML output. Note that
@ -1150,7 +1119,8 @@ HIDE_UNDOC_RELATIONS = YES
# toolkit from AT&T and Lucent Bell Labs. The other options in this section
# have no effect if this option is set to NO (the default)
HAVE_DOT = YES
# ts B10415: dot causes sigsegv on Debian buildd
HAVE_DOT = NO
# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
# will generate a graph for each documented class showing the direct and

187
doc/iso_hybrid_fs.txt Normal file
View File

@ -0,0 +1,187 @@
Overview of ISO 9660 hybrid filesystems as libisofs output
by Thomas Schmitt - mailto:scdbackup@gmx.net
Libburnia project - mailto:libburn-hackers@pykix.org
07 Jun 2012
The overall framework for the filesystem images produced by libisofs is given
by ECMA-119, which is also known as ISO 9660. The hybrid aspect is the
opportunity to add access structures of other filesystems.
The framework suggests a logical block size of 2048 and divides the space of
filesystem blocks into several parts:
- The System Area. Beginning at the image start block.
32 KiB of arbitrary data, which are not considered to be
part of structure or payload of the ISO image.
- The Volume Descriptors. Beginning at image start block + 16.
The Primary Volume Descriptor block is the starting point of the ECMA-119
tree of directories and files. Among other information, it records the size
of the image block space. Other descriptor blocks may lead to boot images
or to the directory trees of add-on filesystems (e.g. Joliet).
- The area of directory structures and data file content.
libisofs divides it into two sub areas:
- Directory structures.
They record the file names and attributes of the ECMA-119 tree and
of eventual add-on filesystem.
- Data file content.
The blocks in this area are referred by zero or more file entries in the
directory trees. They store the data content or regular files. Start block
address of a file and exact byte count are stored in the trees.
libisofs may slide-in some data blocks which are neither part of the structure
nor part of file content. See doc/checksums.txt, Checksum Array, Checksum Tags.
In the same way, the superblocks of other filesystems could be inserted into
the image.
The only block addresses which are fixely occupied are image_start+16 (Primary
Volume Descriptor) and image_start+17 (first possible position of Volume
Descriptor Set Terminator).
Nevertheless, libisofs considers as reserved the blocks image_start+16 to
image_start+31, because add-ons like El Torito, Joliet, or ISO 9660:1999
need their own volume descriptors stored before the volume descriptor set
terminator block. Only one volume descriptor per add-on filesystem may be
written there, and its exact position will be chosen by libisofs.
The System Area in image_start to image_start+15 may be used for a partition
table or the superblock of an additional filesystem structure.
Another place for superblocks is after image_start+31. E.g. UDF stores its
Anchor at block address 256, or at media_size - 1 - 256, or at media_size - 1.
In both cases the superblocks would point to filesystem-specific data which
are stored in the area of directory structures. These data would then refer to
the same file contents as the ECMA-119 directory structure.
-----------------------------------------------------------------------
What libisofs needs to get implemented for a new add-on filesystem:
The emerging overall image is represented by an Ecma119Image object.
This is an instance of quite fat struct ecma119_image which, among many
others, holds some parameters which are specific to the implemented add-on
filesystems. It is defined in libisofs/ecma119.h.
It gets programmed by applications via API calls for IsoWriteOpts which is
defined as struct iso_write_opts in libisofs/ecma119.h.
The content of the System Area may be submitted opaquely via
Ecma119Image.system_area_data or it may get generated underneath
libisofs/system_area.c:iso_write_system_area() by a specific "System area type"
in Ecma119Image.system_area_options. The latter happens when the block adresses
of all components, directories, and files are determined. (One may have to
dig deep in the graph of objects to obtain everything.)
If a new system area type is needed, then it has to be documented in
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
registering writer objects.
Writers are instances of typedef struct Iso_Image_Writer IsoImageWriter.
The struct is defined in libisofs/writer.h.
The Joliet writer is a comprehensive example of an add-on filesystem writer.
First it gets counted for the allocation of the registration array
if (target->joliet) {
nwriters++;
}
Later it gets created and registered
if (target->joliet) {
ret = joliet_writer_create(target);
The function libisofs/joliet.c:joliet_writer_create() accounts for one block
that will hold the Joliet volume descriptor
/* we need the volume descriptor */
target->curblock++;
Not all add-on filesystems will need a volume descriptor. Joliet does.
joliet_writer_create() further generates a tree of JolietNode objects by
traversing the image model tree of IsoNode objects.
ret = joliet_tree_create(target);
If a JolietNode represents a regular file then it refers to an IsoFileSrc
object, which represents its data content in the emerging image.
struct Iso_File_Src is defined in libisofs/filesrc.h.
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.
It computes and records Joliet-specific addresses and sizes:
Ecma119Image.joliet_ndirs, Ecma119Image.joliet_l_path_table_pos,
Ecma119Image.joliet_m_path_table_pos , Ecma119Image.joliet_path_table_size
Ecma119Image.j_part_l_path_table_pos, Ecma119Image.j_part_m_path_table_pos
as well as the sizes and block addresses of Joliet directories.
It increases the counter of virtually written blocks:
Ecma119Image.curblock
which is used to determine the start addresses of the image parts and
finally gives the overall image size.
The method IsoImageWriter.write_vol_desc() composes and writes the Joliet
volume descriptor. (Such writing is not necessarily needed for add-on
filesystems.)
IsoImageWriter.write_data() writes the records of the Joliet directory tree.
This has to be exactly the same number of blocks by which Ecma119Image.curblock
was increased during IsoImageWriter.compute_data_blocks().
When it gets called, the number of content data extents, their sizes, and their
addresses are known: JolietNode.IsoFileSrc->nsections, ->sections[].size,
->sections[].block.
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
Copyright (c) 2012 Thomas Schmitt <scdbackup@gmx.net>
It shall only be modified in sync with libisofs. Please mail change requests to
mailing list <libburn-hackers@pykix.org> or to the copyright holder in private.
If you make use of the license to derive modified versions of libisofs then
you are entitled to modify this text under that same license.

View File

@ -45,7 +45,7 @@ more data bytes than with SL, though, and any of the 256 possible byte values.
The reader shall be prepared to detect and handle oversized data.
One or more AL entries form the Attribute List of a file object with
an even number of components. Each two consequtive components form a pair of
an even number of components. Each two consecutive components form a pair of
Name and Value.
The empty name indicates that the value is a compact representation of ACLs.
@ -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
@ -157,9 +155,10 @@ types. "system." is file system dependent and often restricted in the
choice of names. "user." is portable and allows to choose about any name.
Namespace "isofs." is defined for internal use of AAIP enhanced ISO 9660
file systems. Names in this namespace should be registered at libburnia.org.
file systems. Names in this namespace should be registered at
libburnia-project.org.
Further namespaces may be registered at libburnia.org.
Further namespaces may be registered at libburnia-project.org.
The reserved start bytes of names have the following meaning
0x01 escape reserved character at start of name
@ -218,7 +217,7 @@ S_IRWXG. If there is ACL_USER_N or ACL_GROUP_N there must also be ACL_MASK.
A numeric qualifier is a binary number of variable length up to 4 bytes. The
Most Significant Byte comes first. The number shall be the "POSIX File User ID"
resp. "POSIX File Group ID" as also used in RRIP PX entries. The ids of owning
or "POSIX File Group ID" as also used in RRIP PX entries. The ids of owning
user and owning group shall be taken from the PX entry of the file object.
Optional TRANSLATE entries may associate user or group names with numeric
@ -236,7 +235,7 @@ An eventually needed qualifier is stored in one or more Qualifier Records.
[b] "BP 2 - Qualifier Record Head" shall be present only if QUALIFIER is set
to 1. It shall give the number of Qualifier Bytes and eventually
indicate that the qualifier continues in a Qualifier Record which comes
imediately after this record.
immediately after this record.
0 to 127 Q_LENGTH, the qualifier is complete by this record
128 to 255 Q_LENGTH+128, the qualifier is continued by next record
So a Qualifier Record can contain at most 127 Qualifier Bytes.
@ -360,7 +359,7 @@ SUSP-1.10 does not specify ES entries at all and allows to have extension
entries without announcing them by an ER entry. So if a second ER entry is
not bearable, then the SUSP-1.10 downgrade of AAIP allows to omit the
AAIP ER and the ES entries. But if there is the AAIP ER then there must be ES
at the appropriate places. Else the format would explicitely violate SUSP-1.12.
at the appropriate places. Else the format would explicitly violate SUSP-1.12.
-------------------------------------------------------------------------------
Model Relations:
@ -443,3 +442,14 @@ Program mkisofs emits entry XA
-------------------------------------------------------------------------------
This text is under
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.
Only if you cannot reach the copyright holder for at least one month it is
permissible to modify this text under the same license as the affected
copy of libisofs.
If you do so, you commit yourself to taking reasonable effort to stay in
sync with the other interested users of this text.

View File

@ -4,11 +4,13 @@
Directory of Namespace "isofs."
by Thomas Schmitt - mailto:scdbackup@gmx.net
Libburnia project - mailto:libburn-hackers@pykix.org
Libburnia project - mailto:bug-xorriso@gnu.org
The following names are defined for AAIP namespace "isofs." as mentioned in
specification of AAIP :
specification of AAIP. Unless explicitly stated otherwise, numbers with
names like *_LEN are 8 bit unsigned integers, those with *_BYTES are 32 bit
unsigned integers.
-------------------------------------------------------------------------------
@ -22,6 +24,8 @@ Purpose:
END is also the block address of the start of the checksum recording
area in the image.
See also isofs.cx .
This attribute shall be attached to the root directory entry
and be global for the whole image.
Format of Value:
START_LEN | START_BYTES | END_LEN | END_BYTES |
@ -63,8 +67,8 @@ Purpose:
Records the name of the character set that was used as output character
set when writing the RRIP name tree of the ISO 9660 image. It shall be
suitable as parameter for function iconv_open(3).
This attribute shall eventually be attached to the root directory entry
and be global for the whole image.
This attribute shall be attached to the root directory entry and be
global for the whole image.
Format of Value:
Shall hold the character set name without terminating 0-byte.
@ -105,6 +109,7 @@ Name:
Purpose:
Records .st_dev and .st_ino of struct stat of the file source in the
local filesystem. See man 2 stat.
Both values may be unsigned integers up to 255 bytes.
Format of Value:
DEV_LEN | DEV_BYTES | INO_LEN | INO_BYTES
@ -121,6 +126,152 @@ Registered:
-------------------------------------------------------------------------------
Name:
isofs.fa
Purpose:
Records the file attribute flags as of Linux program chattr(1) and
ioctl(FS_IOC_GETFLAGS) in <linux/fs.h> as bits in a byte string.
Known from Debian GNU/Linux 8 to 12 are:
bit0= FS_SECRM_FL 's' zero blocks on deletion +
bit1= FS_UNRM_FL 'u' on delete prepare for undelete +
bit2= FS_COMPR_FL 'c' compress +
bit3= FS_SYNC_FL 'S' synchronous write +
bit4= FS_IMMUTABLE_FL 'i' immutable +*
bit5= FS_APPEND_FL 'a' appending write only +*
bit6= FS_NODUMP_FL 'd' dump(8) shall ignore this file +
bit7= FS_NOATIME_FL 'A' do not update atime +
bit8= FS_DIRTY_FL 'Z' compressed dirty file
bit9= FS_COMPRBLK_FL (? one or more compressed clusters)
bit10= FS_NOCOMP_FL 'm' do not compress +
bit11= FS_ECOMPR_FL 'E' compression error (old)
FS_ENCRYPT_FL 'E' encrypted file (new)
bit12= FS_BTREE_FL (? btree format dir)
FS_INDEX_FL 'I' hash-indexed directory
bit13= FS_IMAGIC_FL (? AFS directory)
bit14= FS_JOURNAL_DATA_FL 'j' data journalling +*
bit15= FS_NOTAIL_FL 't' no tail-merging +
bit16= FS_DIRSYNC_FL 'D' synchronous directory updates +/
bit17= FS_TOPDIR_FL 'T' top of directory hierarchy +/
bit18= FS_HUGE_FILE_FL ('h' huge file ? 'h' old, FS_HUGE_FILE_FL new)
bit19= FS_EXTENT_FL 'e' using extents
bit20= FS_DIRECTIO_FL (? use direct i/o) (old)
FS_VERITY_FL 'V' fs-verity enabled (new)
bit21= FS_EA_INODE_FL (? Inode used for large EA)
bit22= FS_EOFBLOCKS_FL (? reserved for ext4)
bit23= FS_NOCOW_FL 'C' no copy on write +
bit25= FS_DAX_FL 'x' direct access +
bit28= FS_INLINE_DATA_FL 'N' data stored in inode
bit29= FS_PROJINHERIT_FL 'P' project hierarchy +/
bit30= FS_CASEFOLD_FL 'F' case-insensitive directory lookups +/
bit31= FS_RESERVED_FL (? reserved for ext2 lib)
Marks for supposed settability properties according to man chattr:
"+" means "settable".
"*" means "superuser power is needed".
"/" means "for directories only".
Format of Value:
A byte string which begins with the most significant byte.
Example:
(FS_SECRM_FL|FS_APPEND_FL|FS_NOCOMP_FL) = 0x421
{ 4 , 33 }
Registered:
12 Jul 2024 by Thomas Schmitt for libisofs.
-------------------------------------------------------------------------------
Name:
isofs.hb
Purpose:
Records the IsoHfsplusBlessings blessing of a IsoNode as defined
in libisofs.h. At image load time, this info may be converted back
into a relation between IsoImage and IsoNode so that it is available for
the HFS+ writer when a new ISO 9660 / HFS+ image gets produced.
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 may be converted back into an xinfo
attachment for iso_hfsplus_xinfo_func so that it is available for
the HFS+ writer when a new ISO 9660 / HFS+ image gets produced.
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.nt
Purpose:
Records the name truncation mode and the truncation length for Rock Ridge
names. See iso_image_set_truncate_mode() in libisofs.h.
This attribute shall be attached to the root directory entry and be
global for the whole image.
Format of Value:
MODE_LEN | MODE_BYTES | LENGTH_LEN | LENGTH_BYTES
Example:
{ 1, 1, 1, 255 }
Registered:
24 Sep 2015 by Thomas Schmitt for libisofs.
-------------------------------------------------------------------------------
Name:
isofs.pi
Purpose:
Records the project id for XFS-style quota management.
See man xfs_quota(8).
Missing isofs.pi is defaulted to project id 0.
Format of Value:
A byte string which begins with the most significant byte.
Up to four bytes are permissible.
Example:
Project id 258
{ 1, 2 }
Registered:
09 Oct 2024 by Thomas Schmitt for libisofs.
-------------------------------------------------------------------------------
Name:
isofs.st
@ -132,7 +283,7 @@ Purpose:
The RRIP timestamps have a blind second during which a change after
node registration would not be recognizable for incremental backups
which are based in "isofs.di" rather than on content comparison.
This attribute shall eventually be attached to the root directory entry
This attribute shall be attached to the root directory entry
and be global for the whole image.
Format of Value:
@ -149,3 +300,14 @@ Registered:
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
This text is under
Copyright (c) 2009 - 2024 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
<bug-xorriso@gnu.org> or to the copyright holder in private.
Only if you cannot reach the copyright holder for at least one month it is
permissible to modify this text under the same license as the affected
copy of libisofs. Currently: GNU General Public License version 2 or later.
If you do so, you commit yourself to taking reasonable effort to stay in
sync with the other interested users of this text.

262
doc/zisofs2_format.txt Normal file
View File

@ -0,0 +1,262 @@
Description of the zisofs2 Format
Revision 2.0-dev
as of zisofs2-tools by
Valentín KIVACHUK BURDÁ and Thomas SCHMITT
1 Oct 2020
The zisofs2 format was invented by Valentín KIVACHUK BURDÁ and
Thomas SCHMITT (as extension of zisofs by H. Peter Anvin). It compresses
data file content, marks it by a header and provides a pointer array for
coarse random access. Within a RRIP enhanced ISO 9660 image the format
is additionally marked by a System Use entry with signature "ZF" or "Z2".
The uncompressed size of a single zisofs2 compressed file is restricted
to 2^64 - 1 bytes. Larger files shall not be compressed.
The format of version 1 of zisofs is supported by this specification.
Using it for files with uncompressed size smaller than 4 GiB is friendly
towards software which does not know about zisofs2.
See section **LEGACY** for a summary of version 1 of zisofs.
Data Types
ISO 9660:7.3.1 - little endian 4-byte words
ISO 9660:7.1.1 - unsigned single bytes
ISO 9660:7.3.3 - 8-bytes value, first in little endian, then big endian.
#uint64 - 8-bytes unsigned value in little endian
Supported compressors
The file header has this layout:
@alg_id @alg_char Description
1 'PZ' (50)(5A) Zlib
2 'XZ' (78)(7A) XZ
3 'L4' (6C)(34) LZ4
4 'ZD' (7A)(64) Zstandard
5 'B2' (62)(32) Bzip2
@alg_id is a 7.1.1 value. @alg_char is 2 ASCII characters stored as 2 bytes
Values of @alg_id = 0 and @alg_char = 'pz'(70)(7A) are reserved and
must not be used. Other compressors are allowed and may be added to this
list in the future
Compressor strategy
The default strategy for a compressor is to compress each input data block
independently. The zisofs2 spec may define in the future other strategies,
which will have a new @alg_id, @alg_char and a description in this section.
File Header
The file header has this layout:
Offset Type Identifier Contents
--------------------------------------------------------------------------
0 (8 bytes) @hdr_magic Magic num (EF 22 55 A1 BC 1B 95 A0)
8 7.1.1 @hdr_version File header version (0)
9 7.1.1 @hdr_size header_size >> 2 (6)
10 7.1.1 @alg_id Algorithm Type (>=1)
11 7.1.1 @hdr_bsize log2(block_size) (15, 16, or 17)
12 #uint64 @size Uncompressed file size
20 (4 bytes) - Padding. Ignored
So its size is 24.
Readers shall be able to handle log2(block_size) values 15, 16 and 17
i.e. block sizes 32 kB, 64 kB, and 128 kB. Writers must not use
other sizes.
Block Pointers
There are ceil(input_size / block_size) input resp. output blocks.
Each input block is of fixed size whereas the output blocks have varying
size (down to 0). For each output block there is an offset pointer giving
its byte address in the overall file content. The next block pointer in the
array tells the start of the next block which begins immediately after the
end of its predecessor. A final pointer (*eob*) gives the first invalid
byte address and thus marks the end of the last block.
So there are ceil(input_size / block_size) + 1 block pointers.
They are stored directly after the file header, i.e. beginning at byte 24,
as an array of values in #uint64 format (8 bytes).
Legacy format (zisofs) may be used, which is described in section *LEGACY*
Data Part
The data part begins immediately after the pointer array (*eob*). In
principle it consists of the variable length output blocks as delivered by
different compression algorithms when fed with the fixed size input blocks.
A special case of input and output block is defined:
Zero-length blocks represent a block full of 0-bytes.
Such input blocks do not get processed by compress2() but shall be mapped
to 0-sized output directly. Vice versa 0-sized blocks have to bypass
uncompress() when being read.
ZF System Use Entry Format
The ZF entry follows the general layout of SUSP resp. RRIP.
Its fields are:
[1] "BP 1 to BP 2 - Signature Word" shall be (5A)(46) ("ZF").
[2] "BP 3 - Length" shall specify as an 8-bit number the length in
bytes of the ZF entry recorded according to ISO 9660:7.1.1.
This length is 16 decimal.
Refer to **LEGACY**
[3] "BP 4 - System Use Entry Version" shall be 2 as in ISO 9660:7.1.1.
Refer to **LEGACY**
[4] "BP 5 to BP 6 - Algorithm" shall be two chars to indicate the
compression algorithm. For example, (50)(5A) ("PZ")
(This is a copy of @alg_char). Refer to **LEGACY**
[5] "BP 7 - Header Size Div 4" shall specify as an 8-bit number the
number of 4-byte words in the header part of the file data recorded
according to ISO 9660:7.1.1.
(This is a copy of @hdr_size).
[6] "BP 8 - Log2 of Block Size" shall specify as an 8-bit number the
binary logarithm of the compression block size recorded according to
ISO 9660:7.1.1.
(This is a copy of header byte 13 (@hdr_bsize), resp. header BP 14.
The value has to be 15, 16 or 17 i.e. 32 kiB, 64 kiB, or 128 kiB.)
[7] "BP 9 to BP 16 - Virtual Uncompressed File Size" shall contain
as a 64-bit unsigned little endian number the uncompressed
file size represented by the given extent. Refer to **LEGACY**
| 'Z' | 'F' | LENGTH | 2 | 'P' | 'Z' | HEADER SIZE DIV 4 |
| LOG2 BLOCK SIZE | UNCOMPRESSED SIZE |
Example (block size 128 kiB, uncompressed file size = 40 TB):
{ 'Z', 'F', 16, 2, 'P', 'Z', 8, 17,
0x00, 0x80, 0xCA, 0x39, 0x61, 0x24, 0x00, 0x00 }
Z2 System Use Entry Format
Linux kernels which are configured by CONFIG_ZISOFS to recognize zisofs
but are not aware of zisofs2 will complain about ZF entries which announce
algorithms other than "pz". The system log will show for each zisofs2
compressed file at first stat(2) or open(2) a line like this:
isofs: Unknown ZF compression algorithm: PZ
To avoid these complaints, it is possible to use
[1] "BP 1 to BP 2 - Signature Word" shall be (5A)(32) ("Z2").
instead of "ZF" with the System Use Entry Format specified above.
Everything else shall be like in ZF format version 2, including the version
number itself:
[3] "BP 4 - System Use Entry Version" shall be 2 as in ISO 9660:7.1.1.
**LEGACY**
zisofs2 supports old readers by respecting the zisofs format. This section
describes which definitions from zisofs2 must change to be compatible
with zisofs.
- General behaviour
The uncompressed size of a single zisofs compressed file is restricted
to 4 GiB - 1. Larger files shall not be compressed.
- Supported algorithms
Only algorithm Zlib with default strategy is supported.
- The file header must follow this structure:
Offset Type Identifier Contents
0 (8 bytes) @hdr_magic Magic number (37 E4 53 96 C9 DB D6 07)
8 7.3.1 @size Uncompressed file size
12 7.1.1 @hdr_size header_size >> 2 (4)
13 7.1.1 @hdr_bsize log2(block_size) (15, 16, or 17)
14 (2 bytes) - Reserved, must be zero
So its size is 16.
- Block pointers
The array must use ISO 9660:7.3.1 (4 bytes) values.
- ZF entry
Its fields are:
[1] "BP 1 to BP 2 - Signature Word" shall be (5A)(46) ("ZF").
[2] "BP 3 - Length" must be 16 decimal.
[3] "BP 4 - System Use Entry Version" must be 1.
[4] "BP 5 to BP 6 - Algorithm" must be (70)(7A) ("pz").
[5] "BP 7 - Header Size Div 4" - same as zisofs2.
[6] "BP 8 - Log2 of Block Size" - same as zisofs2.
[7] "BP 9 to BP 16 - Uncompressed Size" This field shall be recorded
according to ISO 9660:7.3.3.
(This number is the same as @size )
| 'Z' | 'F' | LENGTH | 1 | 'p' | 'z' | HEADER SIZE DIV 4 |
| LOG2 BLOCK SIZE | UNCOMPRESSED SIZE |
Example (block size 32 kiB, uncompressed file size = 1,234,567 bytes):
{ 'Z', 'F', 16, 1, 'p', 'z', 4, 15,
0x87, 0xD6, 0x12, 0x00, 0x00, 0x12, 0xD6, 0x87 }
References:
zisofs2-tools
https://github.com/vk496/zisofs2-tools
zisofs-tools
http://freshmeat.net/projects/zisofs-tools/
zlib:
/usr/include/zlib.h
cdrtools with mkisofs
ftp://ftp.berlios.de/pub/cdrecord/alpha
ECMA-119 aka ISO 9660
http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-119.pdf
SUSP 1.12
ftp://ftp.ymi.com/pub/rockridge/susp112.ps
RRIP 1.12
ftp://ftp.ymi.com/pub/rockridge/rrip112.ps
zisofs version 1
libisofs-*/doc/zisofs_format.txt
https://dev.lovelyhq.com/libburnia/libisofs/raw/branch/master/doc/zisofs_format.txt
---------------------------------------------------------------------------
This text is under
Copyright (c) 2009 - 2010, 2020 Thomas SCHMITT <scdbackup@gmx.net>
Copyright (c) 2020 - Valentín KIVACHUK BURDÁ <vk18496@gmail.com>
It shall reflect the effective technical specifications as implemented in
zisofs2-tools and the Linux kernel. So please contact mailing list
<bug-xorriso@gnu.org> or to the copyright holders in private, if you
want to make changes.
Only if you cannot reach the copyright holder for at least one month it is
permissible to modify and distribute this text under the license "GPLv3".

View File

@ -37,7 +37,7 @@ i.e. block sizes 32 kB, 64 kB, and 128 kB. Writers must not use other sizes.
Block Pointers
There are ceil(input_size / block_size) input resp. output blocks.
There are ceil(input_size / block_size) input and output blocks.
Each input block is of fixed size whereas the output blocks have varying
size (down to 0). For each output block there is an offset pointer giving
its byte address in the overall file content. The next block pointer in the
@ -68,7 +68,7 @@ when being read.
ZF may only be applied to files with a single extent and less than 4 GiB of
uncompressed size.
The ZF entry follows the general layout of SUSP resp. RRIP.
The ZF entry follows the general layout of SUSP and RRIP.
Its fields are:
[1] "BP 1 to BP 2 - Signature Word" shall be (5A)(46) ("ZF").
@ -85,19 +85,18 @@ Its fields are:
[5] "BP 7 - Header Size Div 4" shall specify as an 8-bit number the number of
4-byte words in the header part of the file data recorded according
to ISO 9660:7.1.1.
(This is a copy of header byte 12, resp. header BP 13).
(This is a copy of header byte 12 / BP 13).
[6] "BP 8 - Log2 of Block Size" shall specify as an 8-bit number the binary
logarithm of the compression block size recorded according to
ISO 9660:7.1.1.
(This is a copy of header byte 13, resp. header BP 14.
(This is a copy of header byte 13 / BP 14.
The value has to be 15, 16 or 17 i.e. 32 kiB, 64 kiB, or 128 kiB.)
[7] "BP 9 to BP 16 - Uncompressed Size" shall tell the number of uncompressed
bytes represented by the given extent. This field shall be recorded
according to ISO 9660:7.3.3.
(This number is the same as in header bytes 8 to 11, resp header BP 9
to BP 12.)
(This number is the same as in header bytes 8 to 11 / BP 9 to BP 12.)
| 'Z' | 'F' | LENGTH | 1 | 'p' | 'z' | HEADER SIZE DIV 4 | LOG2 BLOCK SIZE
| UNCOMPRESSED SIZE |
@ -141,3 +140,14 @@ SUSP 1.12
RRIP 1.12
ftp://ftp.ymi.com/pub/rockridge/rrip112.ps
-------------------------------------------------------------------------------
This text is under
Copyright (c) 2009 - 2010 Thomas Schmitt <scdbackup@gmx.net>
It shall reflect the effective technical specifications as implemented in
zisofs-tools and the Linux kernel. So please contact mailing list
<libburn-hackers@pykix.org> or to the copyright holder in private, if you
want to make changes.
Only if you cannot reach the copyright holder for at least one month it is
permissible to modify and distribute this text under the license "BSD revised".

View File

@ -11,10 +11,19 @@
To be included by aaip_0_2.c
Copyright (c) 2009 Thomas Schmitt, libburnia project, GPLv2
Copyright (c) 2009 - 2025 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 <ctype.h>
#include <sys/types.h>
#include <unistd.h>
@ -24,6 +33,31 @@
#include <sys/stat.h>
/* ------------------------------ Inquiry --------------------------------- */
/* See also API iso_local_attr_support().
@param flag
Bitfield for control purposes
bit0= inquire availability of ACL
bit1= inquire availability of xattr
bit2 - bit7= Reserved for future types.
It is permissibile to set them to 1 already now.
bit8 and higher: reserved, submit 0
@return
Bitfield corresponding to flag.
bit0= ACL adapter is enabled
bit1= xattr adapter is enabled
bit2= Linux-like file attribute flags (chattr) adapter is enabled
bit3= inquire availability of XFS-style project id
bit4 - bit7= Reserved for future types.
bit8 and higher: reserved, do not interpret these
*/
int aaip_local_attr_support(int flag)
{
return(0);
}
/* ------------------------------ Getters --------------------------------- */
/* Obtain the ACL of the given file in long text form.
@ -50,6 +84,29 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
}
/* Obtain the file attribute flags of the given file as bit array in uint64_t.
The bit numbers are compatible to the FS_*_FL definitions in Linux.
*/
int aaip_get_lfa_flags(char *path, uint64_t *lfa_flags, int *max_bit,
int *os_errno, int flag)
{
*lfa_flags= 0;
*max_bit= -1;
*os_errno= 0;
return(0);
}
/* Obtain the project id for XFS-style quota management.
*/
int aaip_get_projid(char *path, uint32_t *projid, int *os_errno, int flag)
{
*projid= 0;
*os_errno= 0;
return(0);
}
/* ------------------------------ Setters --------------------------------- */
@ -72,10 +129,14 @@ int aaip_set_acl_text(char *path, char *text, int flag)
-7 support of ACL not enabled at compile time
*/
int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
size_t *value_lengths, char **values, int flag)
size_t *value_lengths, char **values, int *errnos,
int flag)
{
size_t i;
for(i= 0; i < num_attrs; i++)
errnos[i]= 0;
for(i= 0; i < num_attrs; i++) {
if(names[i] == NULL || values[i] == NULL)
continue;
@ -85,8 +146,12 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
continue;
}
/* Extended Attribute */
if(!(flag & 4))
return(-6);
if(flag & 4)
continue;
if(!(flag & 8))
if(strncmp(names[i], "user.", 5))
continue;
return(-6);
}
if(flag & 2)
return(-6);
@ -94,3 +159,43 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
}
int aaip_set_lfa_flags(char *path, uint64_t lfa_flags, int max_bit,
int *os_errno, int flag)
{
*os_errno= 0;
return(0);
}
/* Set the project id for XFS-style quota management.
*/
int aaip_set_projid(char *path, uint32_t projid, int *os_errno, int flag)
{
*os_errno= 0;
return(0);
}
/* -------- API for creating device files in the local filesystem --------- */
/* API */
/* @param flag bit0= do not issue error messages
*/
int iso_local_create_dev(char *disk_path, mode_t st_mode, dev_t dev,
int *os_errno, int flag)
{
/* From man mknod:
POSIX.1-2001 says: "The only portable use of mknod() is to create a
FIFO-special file. If mode is not S_IFIFO or dev is not 0, the behav
ior of mknod() is unspecified."
*/
*os_errno= 0;
if(!(flag & 1))
iso_msg_submit(-1, ISO_DEV_NO_CREATION, 0,
"File \"%s\" cannot be created because device file creation is not enabled",
disk_path);
return ISO_DEV_NO_CREATION;
}

View File

@ -3,14 +3,23 @@
aaip-os-freebsd.c
Arbitrary Attribute Interchange Protocol , system adapter for getting and
setting of ACLs and ixattr.
setting of ACLs and xattr.
To be included by aaip_0_2.c
To be included by aaip_0_2.c for FreeBSD, NetBSD, and OpenBSD
Copyright (c) 2009 Thomas Schmitt, libburnia project, GPLv2
Copyright (c) 2009 - 2025 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 <ctype.h>
#include <sys/types.h>
#include <unistd.h>
@ -20,15 +29,81 @@
#include <sys/stat.h>
#include <errno.h>
#ifndef Libisofs_with_aaip_acL
/* It seems ACL is fixely integrated in FreeBSD libc. There is no libacl. */
#define Libisofs_with_aaip_acL yes
#endif
#ifdef Libisofs_with_aaip_acL
#include <sys/acl.h>
#endif
#ifdef Libisofs_with_freebsd_extattR
#include <sys/extattr.h>
#endif
#include <sys/statvfs.h>
/* <<< Use old ACL adapter code that is unable to deal with extattr */
/* # define Libisofs_old_freebsd_acl_adapteR */
/* ------------------------------ Inquiry --------------------------------- */
/* See also API iso_local_attr_support().
@param flag
Bitfield for control purposes
bit0= inquire availability of ACL
bit1= inquire availability of xattr
bit2 - bit7= Reserved for future types.
It is permissibile to set them to 1 already now.
bit8 and higher: reserved, submit 0
@return
Bitfield corresponding to flag.
bit0= ACL adapter is enabled
bit1= xattr adapter is enabled
bit2= Linux-like file attribute flags (chattr) adapter is enabled
bit3= inquire availability of XFS-style project id
bit4 - bit7= Reserved for future types.
bit8 and higher: reserved, do not interpret these
*/
int aaip_local_attr_support(int flag)
{
int ret= 0;
#ifdef Libisofs_with_aaip_acL
if(flag & 1)
ret|= 1;
#endif
#ifdef Libisofs_with_freebsd_extattR
if(flag & 2)
ret|= 2;
#endif
return(ret);
}
#ifdef Libisofs_with_freebsd_extattR
static int aaip_extattr_path_supp(char *path, int flag)
{
#ifdef MNT_EXTATTR
int ret;
struct statvfs statvfs_buf;
ret = statvfs(path, &statvfs_buf);
if(ret == -1)
return(1);
return(!!(statvfs_buf.f_flag & MNT_EXTATTR));
#else /* MNT_EXTATTR */
return(1);
#endif /* ! MNT_EXTATTR */
}
#endif /* Libisofs_with_freebsd_extattR */
/* ------------------------------ Getters --------------------------------- */
@ -133,6 +208,387 @@ int aaip_get_acl_text(char *path, char **text, int flag)
}
#ifndef Libisofs_old_freebsd_acl_adapteR
#ifdef Libisofs_with_freebsd_extattR
/*
@param flag Bitfield for control purposes
bit5= in case of symbolic link: inquire link target
*/
static int aaip_extattr_make_list(char *path, int attrnamespace,
char **list, ssize_t *list_size, int flag)
{
*list= NULL;
*list_size= 0;
/* man 2 extattr_list_file:
If data is NULL in a call to extattr_get_file() and extattr_list_file()
then the size of defined extended attribute data will be returned,
*/
if(flag & 32) /* follow link */
*list_size= extattr_list_file(path, attrnamespace, NULL, (size_t) 0);
else
*list_size= extattr_list_link(path, attrnamespace, NULL, (size_t) 0);
if(*list_size == -1) {
if(! aaip_extattr_path_supp(path, 0)) {
*list_size = 0;
return(2);
}
if(errno == EPERM && attrnamespace == EXTATTR_NAMESPACE_SYSTEM) {
*list_size = 0;
return(3);
}
return(0);
}
if(*list_size == 0)
return(2);
*list= calloc(*list_size, 1);
if(*list == NULL)
return(-1);
if(flag & 32)
*list_size= extattr_list_file(path, attrnamespace, *list,
(size_t) *list_size);
else
*list_size= extattr_list_link(path, attrnamespace, *list,
(size_t) *list_size);
if(*list_size == -1)
return(0);
return(1);
}
/*
@param flag Bitfield for control purposes
bit0= preserve existing namelist content
bit1= ignore names with NUL rather than returning error
*/
static int aaip_extattr_make_namelist(char *path, char *attrnamespace,
char *list, ssize_t list_size,
char **namelist, ssize_t *namelist_size,
ssize_t *num_names, int flag)
{
int i, j, len, new_bytes= 0, space_len;
char *new_list= NULL, *wpt;
if(!(flag & 1)) {
*namelist= NULL;
*namelist_size= 0;
*num_names= 0;
}
if(list_size <= 0)
return(1);
space_len= strlen(attrnamespace);
for(i= 0; i < list_size; i+= len + 1) {
len= *((unsigned char *) (list + i));
if(len == 0)
return ISO_AAIP_BAD_ATTR_NAME; /* empty name is reserved for ACL */
for(j= 0; j < len; j++)
if(list[i + 1 + j] == 0) {
if(flag & 2)
continue;
return ISO_AAIP_BAD_ATTR_NAME; /* names may not contain 0-bytes */
}
new_bytes+= space_len + 1 + len + 1;
}
if((flag & 1) && *namelist_size > 0)
new_bytes+= *namelist_size;
new_list= calloc(new_bytes, 1);
if(new_list == NULL)
return(ISO_OUT_OF_MEM);
wpt= new_list;
if((flag & 1) && *namelist_size > 0) {
memcpy(new_list, *namelist, *namelist_size);
wpt= new_list + *namelist_size;
}
for(i= 0; i < list_size; i+= len + 1) {
len= *((unsigned char *) (list + i));
if(flag & 2) {
for(j= 0; j < len; j++)
if(list[i + j] == 0)
continue;
}
memcpy(wpt, attrnamespace, space_len);
wpt[space_len]= '.';
wpt+= space_len + 1;
memcpy(wpt, list + i + 1, len);
wpt+= len;
*(wpt++)= 0;
(*num_names)++;
}
if((flag & 1) && *namelist != NULL)
free(*namelist);
*namelist= new_list;
*namelist_size= new_bytes;
return(1);
}
static int get_single_attr(char *path, char *name, size_t *value_length,
char **value_bytes, int flag)
{
char *namept;
int attrnamespace;
ssize_t value_ret;
*value_bytes= NULL;
*value_length= 0;
if(strncmp(name, "user.", 5) == 0) {
attrnamespace= EXTATTR_NAMESPACE_USER;
namept= name + 5;
} else {
if(!(flag & 8))
return(0);
attrnamespace= EXTATTR_NAMESPACE_SYSTEM;
namept= name + 7;
}
/* Predict length of value */
if(flag & 32) /* follow link */
value_ret= extattr_get_file(path, attrnamespace, namept, NULL, (size_t) 0);
else
value_ret= extattr_get_link(path, attrnamespace, namept, NULL, (size_t) 0);
if(value_ret == -1)
return(0);
*value_bytes= calloc(value_ret + 1, 1);
if(*value_bytes == NULL)
return(-1);
/* Obtain value */
if(flag & 32) /* follow link */
value_ret= extattr_get_file(path, attrnamespace, namept,
*value_bytes, (size_t) value_ret);
else
value_ret= extattr_get_link(path, attrnamespace, namept,
*value_bytes, (size_t) value_ret);
if(value_ret == -1) {
free(*value_bytes);
*value_bytes= NULL;
*value_length= 0;
return(0);
}
*value_length= value_ret;
return(1);
}
#endif /* Libisofs_with_freebsd_extattR */
/* Obtain the Extended Attributes and/or the ACLs of the given file in a form
that is ready for aaip_encode().
@param path Path to the file
@param num_attrs Will return the number of name-value pairs
@param names Will return an array of pointers to 0-terminated names
@param value_lengths Will return an array with the lengths of values
@param values Will return an array of pointers to 8-bit values
@param flag Bitfield for control purposes
bit0= obtain ACL (access and eventually default)
bit1= use numeric ACL qualifiers rather than names
bit2= do not obtain attributes other than ACL
bit3= do not ignore eventual non-user attributes
I.e. those with a name which does not begin
by "user."
bit4= do not return trivial ACL that matches st_mode
bit5= in case of symbolic link: inquire link target
bit6= do not obtain Linux style file attribute flags
(chattr).
This obtaining is not implemented here anyways.
bit8= do not obtain XFS-style project id.
This obtaining is not implemented here anyways.
bit15= free memory of names, value_lengths, values
@return 1 ok
2 ok, no permission to inspect non-user namespaces
<=0 error
-1= out of memory
-2= program error with prediction of result size
-3= error with conversion of name to uid or gid
*/
int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
size_t **value_lengths, char ***values, int flag)
{
int ret;
ssize_t i, num_names= 0;
#ifdef Libisofs_with_aaip_acL
unsigned char *a_acl= NULL;
char *a_acl_text= NULL;
size_t a_acl_len= 0;
#endif
#ifdef Libisofs_with_freebsd_extattR
char *list= NULL, *user_list= NULL, *sys_list= NULL;
ssize_t value_ret, list_size= 0, user_list_size= 0;
ssize_t sys_list_size= 0;
int acl_names= 0;
#endif
int no_perm_for_system= 0;
if(flag & (1 << 15)) { /* Free memory */
{ret= 1; goto ex;}
}
*num_attrs= 0;
*names= NULL;
*value_lengths= NULL;
*values= NULL;
/* Set up arrays */
#ifdef Libisofs_with_freebsd_extattR
if(!(flag & 4)) { /* Get extattr names */
/* Linux : Names are encoded as name NUL
FreeBSD: Names are encoded as length_byte:chars (no NUL)
AAIP demands names not to contain NUL bytes.
*/
/* Obtain lists of names
Must be done separately for namespaces. See man 9 extattr :
EXTATTR_NAMESPACE_USER , EXTATTR_NAMESPACE_SYSTEM
Must then be marked by "user." and "system." for libisofs use.
*/
ret= aaip_extattr_make_list(path, EXTATTR_NAMESPACE_USER,
&user_list, &user_list_size, flag & 32);
if(ret <= 0)
{ret= -1; goto ex;}
if(flag & 8) {
ret= aaip_extattr_make_list(path, EXTATTR_NAMESPACE_SYSTEM,
&sys_list, &sys_list_size, flag & 32);
if(ret <= 0)
{ret= -1; goto ex;}
if(ret == 3)
no_perm_for_system= 1;
}
/* Check for NUL in names, convert into a linuxish list of namespace.name */
ret= aaip_extattr_make_namelist(path, "user", user_list, user_list_size,
&list, &list_size, &num_names, 0);
if(ret <= 0)
goto ex;
ret= aaip_extattr_make_namelist(path, "system", sys_list, sys_list_size,
&list, &list_size, &num_names, 1);
if(ret <= 0)
goto ex;
}
#endif /* Libisofs_with_freebsd_extattR */
#ifdef Libisofs_with_aaip_acL
if(flag & 1) {
num_names++;
#ifdef Libisofs_with_freebsd_extattR
acl_names= 1;
#endif
}
#endif
if(num_names == 0)
{ret= 1; goto ex;}
(*names)= calloc(num_names, sizeof(char *));
(*value_lengths)= calloc(num_names, sizeof(size_t));
(*values)= calloc(num_names, sizeof(char *));
if(*names == NULL || *value_lengths == NULL || *values == NULL)
{ret= -1; goto ex;}
for(i= 0; i < num_names; i++) {
(*names)[i]= NULL;
(*values)[i]= NULL;
(*value_lengths)[i]= 0;
}
#ifdef Libisofs_with_freebsd_extattR
if(!(flag & 4)) { /* Get xattr values */
for(i= 0; i < list_size && (size_t) num_names - acl_names > *num_attrs;
i+= strlen(list + i) + 1) {
if(!(flag & 8))
if(strncmp(list + i, "user.", 5))
continue;
(*names)[(*num_attrs)++]= strdup(list + i);
if((*names)[(*num_attrs) - 1] == NULL)
{ret= -1; goto ex;}
}
for(i= 0; (size_t) i < *num_attrs; i++) {
value_ret= get_single_attr(path, (*names)[i], *value_lengths + i,
*values + i, flag & (8 | 32));
if(value_ret <= 0)
{ret= -1; goto ex;}
}
}
#endif /* Libisofs_with_freebsd_extattR */
#ifdef Libisofs_with_aaip_acL
if(flag & 1) { /* Obtain ACL */
/* access-ACL */
aaip_get_acl_text(path, &a_acl_text, flag & (16 | 32));
if(a_acl_text == NULL) {
/* empty ACL / only st_mode info was found in ACL */
ret= 1 + no_perm_for_system;
goto ex;
}
ret= aaip_encode_acl(a_acl_text, (mode_t) 0, &a_acl_len, &a_acl, flag & 2);
if(ret <= 0)
goto ex;
/* Note: There are no default-ACL in FreeBSD */
/* Set as attribute with empty name */;
(*names)[*num_attrs]= strdup("");
if((*names)[*num_attrs] == NULL)
{ret= -1; goto ex;}
(*values)[*num_attrs]= (char *) a_acl;
a_acl= NULL;
(*value_lengths)[*num_attrs]= a_acl_len;
(*num_attrs)++;
}
#endif /* Libisofs_with_aaip_acL */
ret= 1 + no_perm_for_system;
ex:;
#ifdef Libisofs_with_aaip_acL
if(a_acl != NULL)
free(a_acl);
if(a_acl_text != NULL)
aaip_get_acl_text("", &a_acl_text, 1 << 15); /* free */
#endif
#ifdef Libisofs_with_freebsd_extattR
if(list != NULL)
free(list);
if(user_list != NULL)
free(user_list);
if(sys_list != NULL)
free(sys_list);
#endif
if(ret <= 0 || (flag & (1 << 15))) {
if(*names != NULL) {
for(i= 0; (size_t) i < *num_attrs; i++)
free((*names)[i]);
free(*names);
}
*names= NULL;
if(*value_lengths != NULL)
free(*value_lengths);
*value_lengths= NULL;
if(*values != NULL) {
for(i= 0; (size_t) i < *num_attrs; i++)
free((*values)[i]);
free(*values);
}
*values= NULL;
*num_attrs= 0;
}
return(ret);
}
#else /* ! Libisofs_old_freebsd_acl_adapteR */
/* Obtain the Extended Attributes and/or the ACLs of the given file in a form
that is ready for aaip_encode().
@ -142,26 +598,38 @@ int aaip_get_acl_text(char *path, char **text, int flag)
@param path Path to the file
@param num_attrs Will return the number of name-value pairs
@param names Will return an array of pointers to 0-terminated names
@param value_lengths Will return an arry with the lenghts of values
@param value_lengths Will return an array with the lengths of values
@param values Will return an array of pointers to 8-bit values
@param flag Bitfield for control purposes
bit0= obtain ACL (access and eventually default)
bit1= use numeric ACL qualifiers rather than names
bit2= do not encode attributes other than ACL
bit3= -reserved-
bit3= do not ignore eventual non-user attributes
I.e. those which are not from name space
EXTATTR_NAMESPACE_USER
bit4= do not return trivial ACL that matches st_mode
bit5= in case of symbolic link: inquire link target
bit6= do not obtain Linux style file attribute flags
(chattr).
This obtaining is not implemented here anyways.
bit15= free memory of names, value_lengths, values
@return >0 ok
<=0 error
-1= out of memory
-2= program error with prediction of result size
-3= error with conversion of name to uid or gid
*/
int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
size_t **value_lengths, char ***values, int flag)
{
int ret;
ssize_t i, num_names;
size_t a_acl_len= 0, acl_len= 0;
unsigned char *a_acl= NULL, *d_acl= NULL, *acl= NULL;
#ifdef Libisofs_with_aaip_acL
size_t a_acl_len= 0;
unsigned char *a_acl= NULL;
char *acl_text= NULL;
#endif
if(flag & (1 << 15)) { /* Free memory */
{ret= 1; goto ex;}
@ -207,25 +675,26 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
(*names)[*num_attrs]= strdup("");
if((*names)[*num_attrs] == NULL)
{ret= -1; goto ex;}
(*values)[*num_attrs]= (char *) acl;
(*value_lengths)[*num_attrs]= acl_len;
(*values)[*num_attrs]= (char *) a_acl;
a_acl= NULL;
(*value_lengths)[*num_attrs]= a_acl_len;
(*num_attrs)++;
}
#endif /* Libisofs_with_aaip_acL */
#endif /* ! Libisofs_with_aaip_acL */
ret= 1;
ex:;
#ifdef Libisofs_with_aaip_acL
if(a_acl != NULL)
free(a_acl);
if(d_acl != NULL)
free(d_acl);
if(acl_text != NULL)
aaip_get_acl_text("", &acl_text, 1 << 15); /* free */
#endif /* Libisofs_with_aaip_acL */
if(ret <= 0 || (flag & (1 << 15))) {
if(*names != NULL) {
for(i= 0; i < *num_attrs; i++)
for(i= 0; i < (ssize_t) *num_attrs; i++)
free((*names)[i]);
free(*names);
}
@ -234,18 +703,41 @@ ex:;
free(*value_lengths);
*value_lengths= NULL;
if(*values != NULL) {
for(i= 0; i < *num_attrs; i++)
for(i= 0; i < (ssize_t) *num_attrs; i++)
free((*values)[i]);
free(*values);
}
if(acl != NULL)
free(acl);
*values= NULL;
*num_attrs= 0;
}
return(ret);
}
#endif /* Libisofs_old_freebsd_acl_adapteR */
/* Obtain the file attribute flags of the given file as bit array in uint64_t.
The bit numbers are compatible to the FS_*_FL definitions in Linux.
*/
int aaip_get_lfa_flags(char *path, uint64_t *lfa_flags, int *max_bit,
int *os_errno, int flag)
{
*lfa_flags= 0;
*max_bit= -1;
*os_errno= 0;
return(0);
}
/* Obtain the project id for XFS-style quota management.
*/
int aaip_get_projid(char *path, uint32_t *projid, int *os_errno, int flag)
{
*projid= 0;
*os_errno= 0;
return(0);
}
/* ------------------------------ Setters --------------------------------- */
@ -255,9 +747,14 @@ ex:;
@param text The input text (0 terminated, ACL long text form)
@param flag Bitfield for control purposes
bit0= set default ACL rather than access ACL
bit5= in case of symbolic link: manipulate link target
bit6= tolerate inappropriate presence or absence of
directory default ACL
@return > 0 ok
0 no suitable ACL manipulation adapter available
-1 failure of system ACL service (see errno)
-2 ACL support not enabled at compile time
-2 attempt to manipulate ACL of a symbolic link
without bit5 or with no suitable link target
*/
int aaip_set_acl_text(char *path, char *text, int flag)
{
@ -298,13 +795,242 @@ ex:
#else /* Libisofs_with_aaip_acL */
return(-2);
return(0);
#endif /* ! Libisofs_with_aaip_acL */
}
#ifndef Libisofs_old_freebsd_acl_adapteR
#ifdef Libisofs_with_freebsd_extattR
/*
@param flag Bitfield for control purposes
bit5= in case of symbolic link: manipulate link target
*/
static int aaip_extattr_delete_names(char *path, int attrnamespace,
char *list, ssize_t list_size, int flag)
{
int len;
char name[256];
ssize_t value_ret, i;
for(i= 0; i < list_size; i+= len + 1) {
len= *((unsigned char *) (list + i));
if(len > 0)
strncpy(name, list + i + 1, len);
name[len]= 0;
if(flag & 32)
value_ret= extattr_delete_file(path, attrnamespace, name);
else
value_ret= extattr_delete_file(path, attrnamespace, name);
if(value_ret == -1)
return(0);
}
return(1);
}
#endif /* Libisofs_with_freebsd_extattR */
static void register_errno(int *errnos, int i, int in_errno)
{
if(in_errno > 0)
errnos[i]= in_errno;
else
errnos[i]= -1;
}
/* Bring the given attributes and/or ACLs into effect with the given file.
@param flag Bitfield for control purposes
bit0= decode and set ACLs
bit1= first clear all existing attributes of the file
bit2= do not set attributes other than ACLs
bit3= do not ignore eventual non-user attributes.
I.e. those with a name which does not begin
by "user."
bit5= in case of symbolic link: manipulate link target
bit6= tolerate inappropriate presence or absence of
directory default ACL
bit7= void setting a name value pair if it already
exists and has the desired value.
@return 1 success
-1 error memory allocation
-2 error with decoding of ACL
-3 error with setting ACL
-4 error with setting attribute
-5 error with deleting attributes
-6 support of xattr not enabled at compile time
-7 support of ACL not enabled at compile time
-8 unsupported xattr namespace
ISO_AAIP_ACL_MULT_OBJ multiple entries of user::, group::, other::
*/
int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
size_t *value_lengths, char **values,
int *errnos, int flag)
{
int ret, has_default_acl= 0, end_ret= 1;
size_t i, consumed, acl_text_fill, acl_idx= 0;
char *acl_text= NULL;
#ifdef Libisofs_with_freebsd_extattR
char *user_list= NULL, *sys_list= NULL, *namept, *old_value;
ssize_t user_list_size= 0, sys_list_size= 0, value_ret;
int attrnamespace;
size_t old_value_l;
int skip;
#endif
for(i= 0; i < num_attrs; i++)
errnos[i]= 0;
#ifdef Libisofs_with_freebsd_extattR
if(flag & 2) { /* Delete all file attributes */
ret= aaip_extattr_make_list(path, EXTATTR_NAMESPACE_USER,
&user_list, &user_list_size, flag & 32);
if(ret <= 0)
{ret= -1; goto ex;}
ret= aaip_extattr_delete_names(path, EXTATTR_NAMESPACE_USER,
user_list, user_list_size, flag & 32);
if(ret <= 0)
{ret= -5; goto ex;}
if(flag & 8) {
ret= aaip_extattr_make_list(path, EXTATTR_NAMESPACE_SYSTEM,
&sys_list, &sys_list_size, flag & 32);
if(ret <= 0)
{ret= -5; goto ex;}
ret= aaip_extattr_delete_names(path, EXTATTR_NAMESPACE_SYSTEM,
sys_list, sys_list_size, flag & 32);
if(ret <= 0)
{ret= -5; goto ex;}
}
}
#endif /* Libisofs_with_freebsd_extattR */
for(i= 0; i < num_attrs; i++) {
if(names[i] == NULL || values[i] == NULL)
continue;
if(names[i][0] == 0) { /* ACLs */
if(flag & 1)
acl_idx= i + 1;
continue;
}
/* Extended Attribute */
if(flag & 4)
continue;
#ifdef Libisofs_with_freebsd_extattR
if(strncmp(names[i], "user.", 5) == 0) {
attrnamespace= EXTATTR_NAMESPACE_USER;
namept= names[i] + 5;
} else if(strncmp(names[i], "isofs.", 6) == 0 || !(flag & 8)) {
continue;
} else if(strncmp(names[i], "system.", 7) == 0) {
attrnamespace= EXTATTR_NAMESPACE_SYSTEM;
namept= names[i] + 7;
} else {
register_errno(errnos, i, (int) EFAULT);
end_ret= -8;
continue;
}
skip= 0;
if(flag & 128) {
value_ret= get_single_attr(path, names[i], &old_value_l,
&old_value, flag & (8 | 32));
if(value_ret > 0 && old_value_l == value_lengths[i]) {
if(memcmp(old_value, values[i], value_lengths[i]) == 0)
skip= 1;
}
if(old_value != NULL)
free(old_value);
}
if(!skip) {
if(flag & 32)
ret= extattr_set_file(path, attrnamespace, namept,
values[i], value_lengths[i]);
else
ret= extattr_set_link(path, attrnamespace, namept,
values[i], value_lengths[i]);
if(ret == -1) {
register_errno(errnos, i, errno);
if(end_ret != 1)
end_ret= -4;
continue;
}
}
#else
if(strncmp(names[i], "user.", 5) == 0)
;
else if(strncmp(names[i], "isofs.", 6) == 0 || !(flag & 8))
continue;
{ret= -6; goto ex;}
#endif /* Libisofs_with_freebsd_extattR */
}
/* Decode ACLs */
/* It is important that this happens after restoring xattr which might be
representations of ACL, too. If isofs ACL are enabled, then they shall
override the xattr ones.
*/
if(acl_idx == 0)
{ret= end_ret; goto ex;}
i= acl_idx - 1;
ret= aaip_decode_acl((unsigned char *) values[i], value_lengths[i],
&consumed, NULL, 0, &acl_text_fill, 1);
if(ret < -3)
goto ex;
if(ret <= 0)
{ret= -2; goto ex;}
acl_text= calloc(acl_text_fill, 1);
if(acl_text == NULL)
{ret= -1; goto ex;}
ret= aaip_decode_acl((unsigned char *) values[i], value_lengths[i],
&consumed, acl_text, acl_text_fill, &acl_text_fill, 0);
if(ret < -3)
goto ex;
if(ret <= 0)
{ret= -2; goto ex;}
has_default_acl= (ret == 2);
#ifdef Libisofs_with_aaip_acL
ret= aaip_set_acl_text(path, acl_text, flag & (32 | 64));
if(ret == -1)
register_errno(errnos, i, errno);
if(ret <= 0)
{ret= -3; goto ex;}
#else
{ret= -7; goto ex;}
#endif
if(has_default_acl && !(flag & 64))
{ret= -3; goto ex;}
ret= end_ret;
ex:;
if(acl_text != NULL)
free(acl_text);
#ifdef Libisofs_with_freebsd_extattR
if(user_list != NULL)
free(user_list);
if(sys_list != NULL)
free(sys_list);
#endif /* Libisofs_with_freebsd_extattR */
return(ret);
}
#else /* ! Libisofs_old_freebsd_acl_adapteR */
/* Bring the given attributes and/or ACLs into effect with the given file.
Note: There are no Extended Attributes in FreeBSD. So only ACL get set.
@ -313,6 +1039,9 @@ ex:
bit0= decode and set ACLs
( bit1= first clear all existing attributes of the file )
( bit2= do not set attributes other than ACLs )
( bit3= do not ignore eventual non-user attributes.
I.e. those with a name which does not begin
by "user." )
@return 1 success
-1 error memory allocation
-2 error with decoding of ACL
@ -334,6 +1063,8 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
continue;
if(names[i][0] == 0) { /* Decode ACLs */
/* access ACL */
if(!(flag & 1))
continue;
ret= aaip_decode_acl((unsigned char *) values[i], value_lengths[i],
&consumed, NULL, 0, &acl_text_fill, 1);
if(ret <= 0)
@ -375,8 +1106,14 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
if(ret <= 0)
{ret= -3; goto ex;}
}
} else
} else {
if(flag & 4)
continue;
if(!(flag & 8))
if(strncmp(names[i], "user.", 5))
continue;
was_xattr= 1;
}
}
ret= 1;
if(was_xattr)
@ -389,4 +1126,64 @@ ex:;
return(ret);
}
#endif /* Libisofs_old_freebsd_acl_adapteR */
int aaip_set_lfa_flags(char *path, uint64_t lfa_flags, int max_bit,
int *os_errno, int flag)
{
*os_errno= 0;
return(0);
}
/* Set the project id for XFS-style quota management.
*/
int aaip_set_projid(char *path, uint32_t projid, int *os_errno, int flag)
{
*os_errno= 0;
return(0);
}
/* -------- API for creating device files in the local filesystem --------- */
/* API */
/* @param flag bit0= do not issue error messages
*/
int iso_local_create_dev(char *disk_path, mode_t st_mode, dev_t dev,
int *os_errno, int flag)
{
int ret;
*os_errno= 0;
if((st_mode & S_IFMT) != S_IFBLK && (st_mode & S_IFMT) != S_IFCHR) {
if(!(flag & 1))
iso_msg_submit(-1, ISO_DEV_NO_CREATION, 0,
"Device file \"%s\" cannot be created because not of type S_IFBLK or S_IFCHR",
disk_path);
return ISO_DEV_NO_CREATION;
}
st_mode&= (S_IFMT | 07777);
ret= mknod(disk_path, st_mode, dev);
if(ret == -1) {
*os_errno= errno;
if(!(flag & 1)) {
if(errno > 0) {
iso_msg_submit(-1, ISO_DEV_NOT_CREATED, 0,
"Creation of device file \"%s\" failed with %d '%s'",
disk_path, errno, strerror(errno));
} else {
iso_msg_submit(-1, ISO_DEV_NOT_CREATED, 0,
"Creation of device file \"%s\" failed without error code",
disk_path);
}
}
return ISO_DEV_NOT_CREATED;
}
return(ISO_SUCCESS);
}

File diff suppressed because it is too large Load Diff

View File

@ -4,13 +4,22 @@
Arbitrary Attribute Interchange Protocol , AAIP versions 0.2 , 1.0 , 2.0.
Implementation of encoding and decoding xattr and ACL.
See test/aaip_0_2.h
See libisofs/aaip_0_2.h
http://libburnia-project.org/wiki/AAIP
Copyright (c) 2009 Thomas Schmitt, libburnia project, GPLv2
Copyright (c) 2009 - 2024 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 <ctype.h>
#include <sys/types.h>
#include <unistd.h>
@ -22,6 +31,8 @@
#include <sys/stat.h>
#include "libisofs.h"
#include "util.h"
#include "messages.h"
/*
#define Aaip_encode_debuG 1
@ -57,12 +68,12 @@
#define Aaip_namespace_trusteD 0x05
#define Aaip_namespace_securitY 0x06
static char Aaip_namespace_textS[][16]= {"", "", "system.", "user.", "isofs.",
"trusted.", "security."};
/* maximum expansion: "security." */
#define Aaip_max_name_expansioN 9
static char Aaip_namespace_textS[][Aaip_max_name_expansioN + 1]=
{"", "", "system.", "user.", "isofs.", "trusted.", "security."};
/* --------------------------------- Encoder ---------------------------- */
@ -83,27 +94,30 @@ static int aaip_encode_pair(char *name, size_t attr_length, char *attr,
no longer needed
@param flag Bitfield for control purposes
bit0= set CONTINUE bit of last AAIP field to 1
@return >0 is the number of SUSP fields generated,
0 means error
@return >= 0 is the number of SUSP fields generated,
< 0 means error
*/
size_t aaip_encode(size_t num_attrs, char **names,
size_t *value_lengths, char **values,
size_t *result_len, unsigned char **result, int flag)
ssize_t aaip_encode(size_t num_attrs, char **names,
size_t *value_lengths, char **values,
size_t *result_len, unsigned char **result, int flag)
{
size_t mem_size= 0, comp_size;
unsigned int number_of_fields, i, num_recs, total_recs= 0, ret;
ssize_t ret;
unsigned int number_of_fields, i, num_recs;
/* Predict memory needs, number of SUSP fields and component records */
*result = NULL;
*result_len= 0;
for(i= 0; i < num_attrs; i++) {
ret= aaip_encode_pair(names[i], value_lengths[i], values[i],
&num_recs, &comp_size, NULL, (size_t) 0, 1);
if(ret <= 0)
if(ret < 0)
return(ret);
mem_size+= comp_size;
total_recs= num_recs;
}
number_of_fields= mem_size / 250 + !!(mem_size % 250);
if(number_of_fields == 0)
return(0);
mem_size+= number_of_fields * 5;
#ifdef Aaip_encode_debuG
@ -114,14 +128,18 @@ size_t aaip_encode(size_t num_attrs, char **names,
#endif
if(*result == NULL)
return 0;
return ISO_OUT_OF_MEM;
/* Encode pairs into result */
for(i= 0; i < num_attrs; i++) {
ret= aaip_encode_pair(names[i], value_lengths[i], values[i],
&num_recs, &comp_size, *result, *result_len, 0);
if(ret <= 0)
if(ret < 0) {
free(*result);
*result = NULL;
*result_len = 0;
return(ret);
}
(*result_len)+= comp_size;
}
@ -154,9 +172,9 @@ size_t aaip_encode(size_t num_attrs, char **names,
ret= 0;
for(i= 0; i < *result_len; i+= ((unsigned char *) (*result))[i + 2])
ret++;
if(ret != number_of_fields) {
if(ret != (int) number_of_fields) {
fprintf(stderr, "aaip_encode(): WRONG NUMBER OF FIELDS %d <> %d\n",
number_of_fields, ret);
(int) number_of_fields, ret);
}
#endif /* Aaip_encode_debuG */
@ -183,7 +201,7 @@ static int aaip_encode_comp(unsigned char *result, size_t *result_fill,
aaip_encode_byte(result, result_fill, 0);
return(1);
}
for(rpt= data; rpt - data < l;) {
for(rpt= data; rpt - data < (ssize_t) l;) {
todo= l - (rpt - data) + (prefix > 0);
aaip_encode_byte(result, result_fill, (todo > 255));
if(todo > 255)
@ -194,7 +212,7 @@ static int aaip_encode_comp(unsigned char *result, size_t *result_fill,
todo--;
prefix= 0;
}
for(comp_start= rpt; rpt - comp_start < todo; rpt++)
for(comp_start= rpt; rpt - comp_start < (ssize_t) todo; rpt++)
aaip_encode_byte(result, result_fill, *((unsigned char *) rpt));
}
return(1);
@ -263,8 +281,13 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
bit2= this is a default ACL, prepend SWITCH_MARK
bit3= check for completeness of list and eventually
fill up with entries deduced from st_mode
bit4= be verbose about failure causes
@return >0 means ok
0 means error
<=0 means error
-1= out of memory
-2= program error with prediction of result size
-3= error with conversion of name to uid or gid
ISO_AAIP_ACL_MULT_OBJ= multiple entries of user::, group::, other::
*/
int aaip_encode_acl(char *acl_text, mode_t st_mode,
size_t *result_len, unsigned char **result, int flag)
@ -274,9 +297,11 @@ int aaip_encode_acl(char *acl_text, mode_t st_mode,
*result= NULL;
*result_len= 0;
bytes= aaip_encode_acl_text(acl_text, st_mode,
(size_t) 0, NULL, 1 | (flag & (2 | 4 | 8)));
(size_t) 0, NULL, 1 | (flag & (2 | 4 | 8 | 16)));
if(bytes < -2)
return(bytes);
if(bytes < 0)
return(0);
return((int) bytes - 1);
if(flag & 1) {
*result_len= bytes;
return(1);
@ -287,10 +312,14 @@ int aaip_encode_acl(char *acl_text, mode_t st_mode,
(*result)[bytes]= 0;
*result_len= bytes;
bytes= aaip_encode_acl_text(acl_text, st_mode, *result_len, *result,
(flag & (2 | 4 | 8)));
if(bytes != *result_len) {
(flag & (2 | 4 | 8 | 16)));
if(bytes < -2)
return(bytes);
if(bytes < 0)
return((int) bytes - 1);
if((size_t) bytes != *result_len) {
*result_len= 0;
return(0);
return(-2);
}
return(1);
}
@ -335,28 +364,34 @@ static int aaip_make_aaip_perms(int r, int w, int x)
bit2= this is a default ACL, prepend SWITCH_MARK 1
bit3= check for completeness of list and eventually
fill up with entries deduced from st_mode
bit4= be verbose about failure causes
@return >=0 number of bytes produced resp. counted
<0 means error
-1: result size overflow
-2: conversion error with user name or group name
ISO_AAIP_ACL_MULT_OBJ: multiple entries of user::, group::, other::
*/
static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
size_t result_size, unsigned char *result, int flag)
{
char *rpt, *npt, *cpt;
int qualifier= 0, perms, type, i, qualifier_len= 0, num_recs, needed= 0;
int qualifier= 0, perms, type, i, qualifier_len= 0, num_recs, needed= 0, ret;
unsigned int has_u= 0, has_g= 0, has_o= 0, has_m= 0, is_trivial= 1;
uid_t uid, huid;
gid_t gid, hgid;
ssize_t count= 0;
struct passwd *pwd;
struct group *grp;
char name[1024];
char *name = NULL;
int name_size= 1024;
double num;
LIBISO_ALLOC_MEM(name, char, name_size);
if(flag & 4) {
/* set SWITCH_MARK to indicate a default ACL */;
if(!(flag & 1)) {
if(count >= result_size)
return(-1);
if((size_t) count >= result_size)
goto result_size_overflow;
result[count]= (Aaip_SWITCH_MARK << 4) | Aaip_EXEC;
}
count++;
@ -380,9 +415,20 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
if(strncmp(rpt, "user:", 5) == 0) {
if(cpt - rpt == 5) {
type= Aaip_ACL_USER_OBJ;
if (has_u) {
/* >>> Duplicate u:: entry. */;
/* >>> ??? If it matches the previous one: ignore */
if(flag & 16)
iso_msg_submit(-1, ISO_AAIP_ACL_MULT_OBJ, 0,
"Duplicate u:: entry detected in ACL text");
ret = ISO_AAIP_ACL_MULT_OBJ;
goto ex;
}
has_u++;
} else {
if(cpt - (rpt + 5) >= sizeof(name))
if(cpt - (rpt + 5) >= name_size)
continue;
is_trivial= 0;
strncpy(name, rpt + 5, cpt - (rpt + 5));
@ -392,8 +438,13 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
pwd= getpwnam(name);
if(pwd == NULL) {
num= aaip_numeric_id(name, 0);
if(num <= 0)
goto user_by_name;
if(num <= 0) {
/* ACL_USER is not part of AAIP 2.0 */
if(flag & 16)
iso_msg_submit(-1, ISO_AAIP_BAD_ACL_TEXT, 0,
"Unknown user name found in ACL text: '%s'", name);
{ret= -2; goto ex;}
}
uid= huid= num;
} else
uid= huid= pwd->pw_uid;
@ -401,31 +452,51 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
for(i= 0; huid != 0; i++)
huid= huid >> 8;
qualifier_len= i;
if(qualifier_len <= 0)
qualifier_len= 1;
for(i= 0; i < qualifier_len ; i++)
name[i]= uid >> (8 * (qualifier_len - i - 1));
} else {
user_by_name:;
type= Aaip_ACL_USER;
qualifier_len= strlen(name);
if(qualifier_len <= 0)
qualifier_len= 1;
}
qualifier= 1;
}
} else if(strncmp(rpt, "group:", 6) == 0) {
if(cpt - rpt == 6) {
type= Aaip_ACL_GROUP_OBJ;
if (has_g) {
/* >>> Duplicate g:: entry. */;
/* >>> ??? If it matches the previous one: ignore */
if(flag & 16)
iso_msg_submit(-1, ISO_AAIP_ACL_MULT_OBJ, 0,
"Duplicate g:: entry detected in ACL text");
ret = ISO_AAIP_ACL_MULT_OBJ;
goto ex;
}
has_g++;
} else {
if(cpt - (rpt + 6) >= sizeof(name))
if(cpt - (rpt + 6) >= name_size)
continue;
is_trivial= 0;
strncpy(name, rpt + 6, cpt - (rpt + 6));
name[cpt - (rpt + 6)]= 0;
if(flag & 2) {
type= Aaip_ACL_GROUP_N;
grp= getgrnam(name);
if(grp == NULL) {
num= aaip_numeric_id(name, 0);
if(num <= 0)
goto group_by_name;
if(num <= 0) {
/* ACL_GROUP is not part of AAIP 2.0 */
if(flag & 16)
iso_msg_submit(-1, ISO_AAIP_BAD_ACL_TEXT, 0,
"Unknown group name found in ACL text: '%s'", name);
{ret= -2; goto ex;}
}
gid= hgid= num;
} else
gid= hgid= grp->gr_gid;
@ -433,18 +504,31 @@ user_by_name:;
for(i= 0; hgid != 0; i++)
hgid= hgid >> 8;
qualifier_len= i;
if(qualifier_len <= 0)
qualifier_len= 1;
for(i= 0; i < qualifier_len ; i++)
name[i]= gid >> (8 * (qualifier_len - i - 1));
} else {
group_by_name:;
type= Aaip_ACL_GROUP;
qualifier_len= strlen(name);
if(qualifier_len <= 0)
qualifier_len= 1;
}
qualifier= 1;
}
} else if(strncmp(rpt, "other:", 6) == 0) {
type= Aaip_ACL_OTHER;
if (has_o) {
/* >>> Duplicate o:: entry. */;
/* >>> ??? If it matches the previous one: ignore */
if(flag & 16)
iso_msg_submit(-1, ISO_AAIP_ACL_MULT_OBJ, 0,
"Duplicate o:: entry detected in ACL text");
ret = ISO_AAIP_ACL_MULT_OBJ;
goto ex;
}
has_o++;
} else if(strncmp(rpt, "mask:", 5) == 0) {
type= Aaip_ACL_MASK;
@ -457,8 +541,8 @@ group_by_name:;
perms= aaip_make_aaip_perms(cpt[1] == 'r', cpt[2] == 'w', cpt[3] == 'x');
if(!(flag & 1)) {
if(count >= result_size)
return(-1);
if((size_t) count >= result_size)
goto result_size_overflow;
result[count]= perms | ((!!qualifier) << 3) | (type << 4);
}
count++;
@ -466,8 +550,8 @@ group_by_name:;
if(qualifier) {
num_recs= (qualifier_len / 127) + !!(qualifier_len % 127);
if(!(flag & 1)) {
if(count + 1 > result_size)
return(-1);
if((size_t) (count + 1) > result_size)
goto result_size_overflow;
for(i= 0; i < num_recs; i++) {
if(i < num_recs - 1)
result[count++]= 255;
@ -476,8 +560,8 @@ group_by_name:;
if(result[count - 1] == 0)
result[count - 1]= 127;
}
if(count + (result[count - 1] & 127) > result_size)
return(-1);
if((size_t) (count + (result[count - 1] & 127)) > result_size)
goto result_size_overflow;
memcpy(result + count, name + i * 127, result[count - 1] & 127);
count+= result[count - 1] & 127;
}
@ -491,8 +575,8 @@ group_by_name:;
if(flag & 1)
count+= needed;
else {
if(count + needed > result_size)
return(-1);
if((size_t) (count + needed) > result_size)
goto result_size_overflow;
}
}
if ((flag & 8) && needed > 0 && !(flag & 1)) {
@ -517,7 +601,17 @@ group_by_name:;
result[count++]= perms | (Aaip_ACL_MASK << 4);
}
}
return(count);
ret= count;
ex:;
LIBISO_FREE_MEM(name);
return(ret);
result_size_overflow:;
if(flag & 16)
iso_msg_submit(-1, ISO_ASSERT_FAILURE, 0,
"Program error: Text to ACL conversion result size overflow");
ret= -1;
goto ex;
}
@ -529,13 +623,14 @@ int aaip_encode_both_acl(char *a_acl_text, char *d_acl_text, mode_t st_mode,
unsigned char *a_acl= NULL, *d_acl= NULL, *acl= NULL;
if(a_acl_text != NULL) {
ret= aaip_encode_acl(a_acl_text, st_mode, &a_acl_len, &a_acl, flag & 11);
ret= aaip_encode_acl(a_acl_text, st_mode, &a_acl_len, &a_acl,
flag & (1 | 2 | 8 | 16));
if(ret <= 0)
goto ex;
}
if(d_acl_text != NULL) {
ret= aaip_encode_acl(d_acl_text, (mode_t) 0, &d_acl_len, &d_acl,
(flag & 3) | 4);
(flag & (1 | 2 | 16)) | 4);
if(ret <= 0)
goto ex;
}
@ -567,7 +662,7 @@ ex:;
}
/* Linux man 5 acl says:
/* GNU/Linux man 5 acl says:
The permissions defined by ACLs are a superset of the permissions speci-
fied by the file permission bits. The permissions defined for the file
owner correspond to the permissions of the ACL_USER_OBJ entry. The per-
@ -584,7 +679,7 @@ ex:;
mission bits.
*/
/* Analyze occurence of ACL tag types in long text form. If not disabled by
/* Analyze occurrence of ACL tag types in long text form. If not disabled by
parameter flag remove the entries of type "user::" , "group::" , "other::" ,
or "other:" from an ACL in long text form if they match the bits in st_mode
as described by man 2 stat and man 5 acl.
@ -805,6 +900,26 @@ int aaip_add_acl_st_mode(char *acl_text, mode_t st_mode, int flag)
}
int aaip_encode_uint64(uint64_t lfa_flags, unsigned char value[8],
int *length, int flag)
{
int i, l;
*length = 1;
value[0] = 0;
/* How many bytes are needed to catch all set bits ? Minimum is 1. */
l= 8;
for(i= 1; i < l; i++)
if(lfa_flags < (uint64_t) 1 << (i * 8))
break;
*length= i;
for(i= 0; i < *length; i++)
value[*length - 1 - i]= (lfa_flags >> (8 * i)) & 0xff;
return(1);
}
/* --------------------------------- Decoder ---------------------------- */
/* --- private --- */
@ -1116,9 +1231,9 @@ static int aaip_consume_rec_head(struct aaip_state *aaip,
size_t todo;
todo= *num_data;
if(todo > aaip->aa_missing)
if(todo > (size_t) aaip->aa_missing)
todo= aaip->aa_missing;
if(todo >= aaip->rec_head_missing)
if(todo >= (size_t) aaip->rec_head_missing)
todo= aaip->rec_head_missing;
if(!aaip->recs_invalid)
aaip_push_to_recs(aaip, *data, todo, 0);
@ -1140,9 +1255,9 @@ static int aaip_consume_rec_data(struct aaip_state *aaip,
size_t todo;
todo= *num_data;
if(todo > aaip->aa_missing)
if(todo > (size_t) aaip->aa_missing)
todo= aaip->aa_missing;
if(todo > aaip->rec_missing)
if(todo > (size_t) aaip->rec_missing)
todo= aaip->rec_missing;
if(!aaip->recs_invalid)
aaip_push_to_recs(aaip, *data, todo, 1);
@ -1174,7 +1289,7 @@ static int aaip_consume_aa_head(struct aaip_state *aaip,
unsigned char aa_head[5];
todo= *num_data;
if(todo >= aaip->aa_head_missing)
if(todo >= (size_t) aaip->aa_head_missing)
todo= aaip->aa_head_missing;
aaip_push_to_recs(aaip, *data, todo, 0);
aaip->aa_head_missing-= todo;
@ -1206,8 +1321,11 @@ static int aaip_consume_aa_data(struct aaip_state *aaip,
while(*num_data > 0 && aaip->aa_missing > 0) {
if(aaip->rec_head_missing > 0) {
aaip_consume_rec_head(aaip, data, num_data, 0);
if(*num_data == 0 || aaip->aa_missing <= 0)
return(1);
if(*num_data == 0 || aaip->aa_missing <= 0) {
if(aaip->rec_head_missing > 0 || aaip->rec_missing > 0)
return(1);
/* empty record data: go on with processing it */
}
}
aaip_consume_rec_data(aaip, data, num_data, 0);
}
@ -1221,7 +1339,7 @@ static int aaip_consume_aa_data(struct aaip_state *aaip,
aaip_push_to_recs(aaip, zero_char, 1, 0);
} else {
/* fill in missing btes */
for(i= 0; i < aaip->rec_missing; i++)
for(i= 0; (int) i < aaip->rec_missing; i++)
aaip_push_to_recs(aaip, zero_char, 1, 1);
}
aaip->rec_head_missing= 2;
@ -1692,7 +1810,7 @@ int aaip_decode_attrs(struct aaip_state **handle,
unsigned char *data, size_t num_data, size_t *consumed,
int flag)
{
int ret, was_non_aa= 0;
int ret;
struct aaip_state *aaip;
size_t h_num, *h_lengths, i, new_mem, pair_consumed= 0;
char **h_names, **h_values, *hpt;
@ -1750,8 +1868,8 @@ int aaip_decode_attrs(struct aaip_state **handle,
if(aaip->list_mem_used >= memory_limit)
return(3);
aaip->list_mem_used+= new_mem;
aaip->name_buf= calloc(sizeof(char *), Aaip_initial_name_leN);
aaip->value_buf= calloc(sizeof(char *), Aaip_initial_value_leN);
aaip->name_buf= calloc(1, Aaip_initial_name_leN);
aaip->value_buf= calloc(1, Aaip_initial_value_leN);
if(aaip->name_buf == NULL || aaip->value_buf == NULL)
return(-1);
aaip->name_buf_size= Aaip_initial_name_leN;
@ -1781,7 +1899,6 @@ int aaip_decode_attrs(struct aaip_state **handle,
return(ret);
} else if(ret == -1) { /* non-AAIP field detected */
was_non_aa= 1;
if(pair_consumed <= 0)
return(-4); /* interpretation did not advance */
@ -1866,7 +1983,7 @@ int aaip_decode_attrs(struct aaip_state **handle,
@param handle The decoding context created by aaip_decode_attrs()
@param num_attrs Will return the number of name-value pairs
@param names Will return an array of pointers to 0-terminated names
@param value_lengths Will return an arry with the lenghts of values
@param value_lengths Will return an array with the lengths of values
@param values Will return an array of pointers to 8-bit values
@param flag Bitfield for control purposes
bit15= free memory of names, value_lengths, values
@ -1964,14 +2081,16 @@ static int aaip_read_qualifier(unsigned char *data, size_t num_data,
char *name, size_t name_size, size_t *name_fill,
int flag)
{
int is_done= 0, rec_len= 0;
int is_done= 0;
size_t rec_len= 0;
unsigned char *rpt;
*name_fill= 0;
for(rpt= data; !is_done; rpt+= rec_len) {
rec_len= (*rpt) & 127;
is_done= !((*rpt) & 128);
if(*name_fill + rec_len >= name_size || rpt + 1 + rec_len - data > num_data)
if(*name_fill + rec_len >= name_size ||
(size_t) (rpt + 1 + rec_len - data) > num_data)
return(-1);
memcpy(name + *name_fill, rpt + 1, rec_len);
rpt+= 1 + rec_len;
@ -2009,20 +2128,21 @@ int aaip_decode_acl(unsigned char *data, size_t num_data, size_t *consumed,
size_t *acl_text_fill, int flag)
{
unsigned char *rpt;
char perm_text[4], *wpt, name[1024];
int type, qualifier= 0, perm, ret, i, cnt;
size_t w_size, name_fill= 0;
char perm_text[4], *wpt, *name= NULL;
int type, qualifier= 0, perm, ret, cnt, name_size= 1024;
size_t w_size= 0, name_fill= 0, i;
uid_t uid;
gid_t gid;
struct passwd *pwd;
struct group *grp;
LIBISO_ALLOC_MEM(name, char, name_size);
cnt= flag & 1;
*consumed= 0;
wpt= acl_text;
w_size= acl_text_size;
*acl_text_fill= 0;
for(rpt= data; rpt - data < num_data; ) {
for(rpt= data; (size_t) (rpt - data) < num_data; ) {
perm= *rpt;
strcpy(perm_text, "---");
if(perm & Aaip_READ)
@ -2034,14 +2154,14 @@ int aaip_decode_acl(unsigned char *data, size_t num_data, size_t *consumed,
type= (*rpt) >> 4;
if(type == Aaip_FUTURE_VERSION) /* indicate to caller: version mismatch */
return(-3);
{ret = -3; goto ex;}
qualifier= !!((*rpt) & 8);
if(qualifier) {
ret= aaip_read_qualifier(rpt + 1, num_data - (rpt + 1 - data),
name, sizeof(name), &name_fill, 0);
name, name_size, &name_fill, 0);
if(ret <= 0)
return(-1);
{ret = -1; goto ex;}
}
/* Advance read pointer */
@ -2082,7 +2202,7 @@ int aaip_decode_acl(unsigned char *data, size_t num_data, size_t *consumed,
pwd= getpwuid(uid);
if(pwd == NULL)
sprintf(name, "%.f", (double) uid);
else if(strlen(pwd->pw_name) >= sizeof(name))
else if(strlen(pwd->pw_name) >= (size_t) name_size)
sprintf(name, "%.f", (double) uid);
else
strcpy(name, pwd->pw_name);
@ -2096,7 +2216,7 @@ int aaip_decode_acl(unsigned char *data, size_t num_data, size_t *consumed,
grp= getgrgid(gid);
if(grp == NULL)
sprintf(name, "%.f", (double) gid);
else if(strlen(grp->gr_name) >= sizeof(name))
else if(strlen(grp->gr_name) >= (size_t) name_size)
sprintf(name, "%.f", (double) gid);
else
strcpy(name, grp->gr_name);
@ -2104,15 +2224,17 @@ int aaip_decode_acl(unsigned char *data, size_t num_data, size_t *consumed,
ret= aaip_write_acl_line(&wpt, &w_size, "group", name, perm_text, cnt);
} else {
/* indicate to caller: unknown type */
return(-4);
{ret = -4; goto ex;}
}
if(ret <= 0)
return(-2);
{ret = -2; goto ex;}
}
ret= 1;
ex:;
*acl_text_fill= w_size;
if(flag & 1)
*acl_text_fill= w_size + 1;
(*acl_text_fill)++;
LIBISO_FREE_MEM(name);
return(ret);
}
@ -2120,19 +2242,61 @@ ex:;
/* ----------------------- Adapter for operating systems ----------------- */
#ifdef Libisofs_use_os_dummY
#include "aaip-os-dummy.c"
#else
#ifdef __FreeBSD__
#include "aaip-os-freebsd.c"
#else
#ifdef __FreeBSD_kernel__
#ifdef NIX
#ifdef Libisofs_with_aaip_xattR
/* ts B51213: xattr system library calls are only stubs */
#include "aaip-os-linux.c"
#else
/* ts B51213: extattr system library calls are not even present */
#include "aaip-os-freebsd.c"
#endif /* ! Libisofs_with_aaip_xattR */
#else /* NIX */
/* ts B51213: so we still end up at the dummy */
#include "aaip-os-dummy.c"
#endif /* ! NIX */
#else
#ifdef __NetBSD__
#include "aaip-os-freebsd.c"
#else
#ifdef __OpenBSD__
#include "aaip-os-freebsd.c"
#else
#ifdef __linux
#include "aaip-os-linux.c"
/* August 2011: aaip-os-linux.c would also work for GNU/Hurd : ifdef __GNU__
Libraries and headers are present on Debian GNU/Hurd but there is no
ACL or xattr support in the filesystems yet.
Further, llistxattr() produces ENOSYS "Function not implemented".
So it makes few sense to enable it here.
*/
#else
#include "aaip-os-dummy.c"
#endif /* ! __linux */
#endif /* ! __OpenBSD__ */
#endif /* ! __NetBSD__ */
#endif /* ! __FreeBSD_kernel__ */
#endif /* ! __FreeBSD__ */
#endif /* ! Libisofs_use_os_dummY */

View File

@ -9,13 +9,22 @@
test/aaip_0_2.h - Public declarations
Copyright (c) 2009 Thomas Schmitt, libburnia project, GPLv2
Copyright (c) 2009 - 2024 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.
*/
#ifndef Aaip_h_is_includeD
#define Aaip_h_is_includeD yes
/* For ssize_t */
#include <unistd.h>
#include <sys/types.h>
/* --------------------------------- Encoder ---------------------------- */
@ -30,12 +39,12 @@
no longer needed
@param flag Bitfield for control purposes
bit0= set CONTINUE bit of last AAIP field to 1
@return >0 is the number of SUSP fields generated,
0 means error
@return >= 0 is the number of SUSP fields generated,
< 0 means error
*/
size_t aaip_encode(size_t num_attrs, char **names,
size_t *value_lengths, char **values,
size_t *result_len, unsigned char **result, int flag);
ssize_t aaip_encode(size_t num_attrs, char **names,
size_t *value_lengths, char **values,
size_t *result_len, unsigned char **result, int flag);
/* ------ ACL representation ------ */
@ -56,7 +65,11 @@ size_t aaip_encode(size_t num_attrs, char **names,
bit3= check for completeness of list and eventually
fill up with entries deduced from st_mode
@return >0 means ok
0 means error
<=0 means error
-1= out of memory
-2= program error with prediction of result size
-3= error with conversion of name to uid or gid
ISO_AAIP_ACL_MULT_OBJ= multiple entries of user::, group::, other::
*/
int aaip_encode_acl(char *acl_text, mode_t st_mode,
size_t *result_len, unsigned char **result, int flag);
@ -80,13 +93,13 @@ int aaip_encode_acl(char *acl_text, mode_t st_mode,
bit3= check for completeness of list and eventually
fill up with entries deduced from st_mode
@return >0 means ok
0 means error
<=0 means error, see aaip_encode_acl
*/
int aaip_encode_both_acl(char *a_acl_text, char *d_acl_text, mode_t st_mode,
size_t *result_len, unsigned char **result, int flag);
/* Analyze occurence of ACL tag types in long text form. If not disabled by
/* Analyze occurrence of ACL tag types in long text form. If not disabled by
parameter flag remove the entries of type "user::" , "group::" , "other::" ,
or "other:" from an ACL in long text form if they match the bits in st_mode
as described by man 2 stat and man 5 acl.
@ -143,8 +156,42 @@ int aaip_cleanout_st_mode(char *acl_text, mode_t *st_mode, int flag);
int aaip_add_acl_st_mode(char *acl_text, mode_t st_mode, int flag);
/* Encode a Linux style file attribute flag bits array to a byte string
which represents the flags bits in isofs.fa .
@param lfa_flags Bit array as obtained by aaip_get_lfa_flags()
@param value Will be filled with 1 to 8 byte values
@param length Will return the number of filled-in value bytes
@return <0 failure
*/
int aaip_encode_uint64(uint64_t lfa_flags, unsigned char value[8],
int *length, int flag);
/* ------ OS interface ------ */
/* See also API iso_local_attr_support().
@param flag
Bitfield for control purposes
bit0= inquire availability of ACL
bit1= inquire availability of xattr
bit2= inquire availability of Linux-like file attribute flags
bit3= inquire availability of XFS-style project id
bit4 - bit7= Reserved for future types.
It is permissibile to set them to 1 already now.
bit8 and higher: reserved, submit 0
@return
Bitfield corresponding to flag. If bits are set, th
bit0= ACL adapter is enabled
bit1= xattr adapter is enabled
bit2= Linux-like file attribute flags adapter is enabled
bit3= XFS-style project id is enabled
bit4 - bit7= Reserved for future types.
It is permissibile to set them to 1 already now.
bit8 and higher: reserved, do not interpret these
*/
int aaip_local_attr_support(int flag);
/* Obtain the ACL of the given file in long text form.
@param path Path to the file
@param text Will hold the result. This is a managed object which
@ -169,7 +216,7 @@ int aaip_get_acl_text(char *path, char **text, int flag);
@param path Path to the file
@param num_attrs Will return the number of name-value pairs
@param names Will return an array of pointers to 0-terminated names
@param value_lengths Will return an arry with the lenghts of values
@param value_lengths Will return an array with the lengths of values
@param values Will return an array of pointers to 8-bit values
@param flag Bitfield for control purposes
bit0= obtain ACLs (access and eventually default) via
@ -180,6 +227,12 @@ int aaip_get_acl_text(char *path, char **text, int flag);
I.e. those with a name which does not begin
by "user."
bit4= do not return trivial ACL that matches st_mode
bit5= in case of symbolic link: inquire link target
bit6= do not obtain Linux style file attribute flags
(chattr)
bit7= Without bit6: Ignore non-settable flags and do
not record "isofs.fa" if all flags are zero
bit8= do not obtain XFS-style project id
bit15= free memory of names, value_lengths, values
@return >0 ok
<=0 error
@ -188,6 +241,54 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
size_t **value_lengths, char ***values, int flag);
/* Obtain the file attribute flags of the given file as bit array in uint64_t.
The bit numbers are compatible to the FS_*_FL definitions in Linux
include file <linux/fs.h>. A (possibly outdated) copy of them is in
doc/susp_aaip_isofs_names.txt, name isofs.fa .
The attribute flags of other systems may or may not be mappable to these
flags.
@param path Path to the file
@param lfa_flags Will get filled with the FS_*_FL
@param max_bit Will tell the highest bit that is possibly set
(-1 = surely no bit is valid)
@param os_errno Will get filled with errno if a system call fails
@param flag Bitfield for control purposes.
bit0= consider ENOTTY from FS_IOC_GETFLAGS an error
(else return 4 on ENOTTY)
bit2= do not issue own error messages with operating
system errors
bit7= Ignore non-settable flags
@return 1= ok, all local attribute flags are in lfa_flags
2= ok, but some local flags could not be mapped to
the FS_*_FL bits
4= ok, ENOTTY from FS_IOC_GETFLAGS
0= local flags retrieval not enabled at compile time
<0 error with system calls:
-1= error with open(2)
-2= error with ioctl(2), not pardoned by bit0
*/
int aaip_get_lfa_flags(char *path, uint64_t *lfa_flags, int *max_bit,
int *os_errno, int flag);
/* Obtain the project id for XFS-style quota management.
See man xfs_quota(8).
@param path Path to the file.
@param projid Will get filled with the project id.
@param os_errno Will get filled with errno in case of error.
@param flag Bitfield for control purposes.
bit2= do not issue own error messages with operating
system errors
@return 1= ok, *projid is valid
0= local project id retrieval not enabled at compile
time
<0 error with system calls:
-1= error with open(2)
-2= error with ioctl(2)
*/
int aaip_get_projid(char *path, uint32_t *projid, int *os_errno, int flag);
/* --------------------------------- Decoder ---------------------------- */
/*
@ -405,7 +506,7 @@ int aaip_decode_attrs(struct aaip_state **handle,
@param handle The decoding context created by aaip_decode_attrs()
@param num_attrs Will return the number of name-value pairs
@param names Will return an array of pointers to 0-terminated names
@param value_lengths Will return an arry with the lenghts of values
@param value_lengths Will return an array with the lengths of values
@param values Will return an array of pointers to 8-bit values
@param flag Bitfield for control purposes
bit15= free memory of names, value_lengths, values
@ -478,9 +579,56 @@ int aaip_set_acl_text(char *path, char *text, int flag);
-5 error with deleting attributes
-6 support of xattr not enabled at compile time
-7 support of ACL not enabled at compile time
-8 unsupported xattr namespace
ISO_AAIP_ACL_MULT_OBJ multiple entries of user::, group::, other::
*/
int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
size_t *value_lengths, char **values, int flag);
size_t *value_lengths, char **values,
int *errnos, int flag);
/* Bring the given file attribute flags into effect with the given file.
The bit numbers are compatible to the FS_*_FL definitions in Linux
include file <linux/fs.h>. A (possibly outdated) copy of them is in
doc/susp_aaip_isofs_names.txt, name isofs.fa .
The attribute flags of other systems may or may not be mappable to these
flags.
@param path Path to the file
@param lfa_flags File attribute flag bits
@param max_bit Gives an upper limit of the highest set flag bit.
(-1 = surely no bit is valid)
On Linux this must be smaller than sizeof(long) * 8.
@param os_errno Will get filled with errno if a system call fails
@param flag Bitfield for control purposes:
bit2= do not issue own error messages with operating
system errors
@return 1= ok, all lfa_flags bits were written
2= ok, but some FS_*_FL bits could not be mapped to
local flags
0= local flags setting not enabled at compile time
<0 error with system calls or with max_bit:
-1= error with open(2)
-2= error with ioctl(2)
-3= error with max_bit
*/
int aaip_set_lfa_flags(char *path, uint64_t lfa_flags, int max_bit,
int *os_errno, int flag);
/* Set the project id for XFS-style quota management.
@param path Path to the file.
@param projid Contains the project id for the file.
@param os_errno Will get filled with errno in case of error.
@param flag Bitfield for control purposes.
bit2= do not issue own error messages with operating
system errors
@return 1= ok, projid was written
0= local flags setting not enabled at compile time
-1= error with open(2)
-2= error with ioctl(FS_IOC_FSGETXATTR)
-3= error with ioctl(FS_IOC_FSSETXATTR)
*/
int aaip_set_projid(char *path, uint32_t projid, int *os_errno, int flag);
#endif /* ! Aaip_h_is_includeD */

View File

@ -12,11 +12,15 @@
*
* TODO #00010 : optimize ring buffer
* - write/read at the end of buffer requires a second mutex_lock, even if
* there's enought space/data at the beginning
* there's enough space/data at the beginning
* - pre-buffer for writes < BLOCK_SIZE
*
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
/*
Use the copy of the struct burn_source definition in libisofs.h
*/
@ -141,12 +145,12 @@ void iso_ring_buffer_free(IsoRingBuffer *buf)
* @param
* Number of bytes to write
* @return
* 1 succes, 0 read finished, < 0 error
* 1 success, 0 read finished, < 0 error
*/
int iso_ring_buffer_write(IsoRingBuffer *buf, uint8_t *data, size_t count)
{
size_t len;
int bytes_write = 0;
size_t bytes_write = 0;
if (buf == NULL || data == NULL) {
return ISO_NULL_POINTER;
@ -161,7 +165,7 @@ int iso_ring_buffer_write(IsoRingBuffer *buf, uint8_t *data, size_t count)
/*
* Note. There's only a writer, so we have no race conditions.
* Thus, the while(buf->size == buf->cap) is used here
* only to propertly detect the reader has been cancelled
* only to properly detect the reader has been cancelled
*/
if (buf->rend) {
@ -192,7 +196,7 @@ int iso_ring_buffer_write(IsoRingBuffer *buf, uint8_t *data, size_t count)
/**
* Read count bytes from the buffer into dest. It blocks until the desired
* bytes has been read. If the writer finishes before outputting enought
* bytes has been read. If the writer finishes before outputting enough
* bytes, 0 (EOF) is returned, the number of bytes already read remains
* unknown.
*
@ -202,7 +206,7 @@ int iso_ring_buffer_write(IsoRingBuffer *buf, uint8_t *data, size_t count)
int iso_ring_buffer_read(IsoRingBuffer *buf, uint8_t *dest, size_t count)
{
size_t len;
int bytes_read = 0;
size_t bytes_read = 0;
if (buf == NULL || dest == NULL) {
return ISO_NULL_POINTER;
@ -215,7 +219,7 @@ int iso_ring_buffer_read(IsoRingBuffer *buf, uint8_t *dest, size_t count)
/*
* Note. There's only a reader, so we have no race conditions.
* Thus, the while(buf->size == 0) is used here just to ensure
* a reader detects the EOF propertly if the writer has been
* a reader detects the EOF properly if the writer has been
* canceled while the reader was waiting
*/
@ -289,7 +293,51 @@ unsigned int iso_ring_buffer_get_times_empty(IsoRingBuffer *buf)
}
/**
/** Internal via buffer.h
*
* Get the status of a ring buffer.
*
* @param buf
* The ring buffer object to inquire
* @param size
* Will be filled with the total size of the buffer, in bytes
* @param free_bytes
* Will be filled with the bytes currently available in buffer
* @return
* < 0 error, > 0 state:
* 1="active" : input and consumption are active
* 2="ending" : input has ended without error
* 3="failing" : input had error and ended,
* 5="abandoned" : consumption has ended prematurely
* 6="ended" : consumption has ended without input error
* 7="aborted" : consumption has ended after input error
*/
int iso_ring_buffer_get_buf_status(IsoRingBuffer *buf, size_t *size,
size_t *free_bytes)
{
int ret;
if (buf == NULL) {
return ISO_NULL_POINTER;
}
/* get mutex */
pthread_mutex_lock(&buf->mutex);
if (size) {
*size = buf->cap;
}
if (free_bytes) {
*free_bytes = buf->cap - buf->size;
}
ret = (buf->rend ? 4 : 0) + (buf->wend + 1);
pthread_mutex_unlock(&buf->mutex);
return ret;
}
/** API via libisofs.h
*
* Get the status of the buffer used by a burn_source.
*
* @param b
@ -317,18 +365,7 @@ int iso_ring_buffer_get_status(struct burn_source *b, size_t *size,
return ISO_NULL_POINTER;
}
buf = ((Ecma119Image*)(b->data))->buffer;
/* get mutex */
pthread_mutex_lock(&buf->mutex);
if (size) {
*size = buf->cap;
}
if (free_bytes) {
*free_bytes = buf->cap - buf->size;
}
ret = (buf->rend ? 4 : 0) + (buf->wend + 1);
pthread_mutex_unlock(&buf->mutex);
ret = iso_ring_buffer_get_buf_status(buf, size, free_bytes);
return ret;
}

View File

@ -11,7 +11,14 @@
#define LIBISO_BUFFER_H_
#include <stdlib.h>
#ifdef HAVE_STDINT_H
#include <stdint.h>
#else
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#endif
#define BLOCK_SIZE 2048
@ -48,13 +55,13 @@ void iso_ring_buffer_free(IsoRingBuffer *buf);
* @param
* Number of bytes to write
* @return
* 1 succes, 0 read finished, < 0 error
* 1 success, 0 read finished, < 0 error
*/
int iso_ring_buffer_write(IsoRingBuffer *buf, uint8_t *data, size_t count);
/**
* Read count bytes from the buffer into dest. It blocks until the desired
* bytes has been read. If the writer finishes before outputting enought
* bytes has been read. If the writer finishes before outputting enough
* bytes, 0 (EOF) is returned, the number of bytes already read remains
* unknown.
*
@ -63,9 +70,31 @@ int iso_ring_buffer_write(IsoRingBuffer *buf, uint8_t *data, size_t count);
*/
int iso_ring_buffer_read(IsoRingBuffer *buf, uint8_t *dest, size_t count);
/** Backend of API call iso_ring_buffer_get_status()
*
* Get the status of a ring buffer.
*
* @param buf
* The ring buffer object to inquire
* @param size
* Will be filled with the total size of the buffer, in bytes
* @param free_bytes
* Will be filled with the bytes currently available in buffer
* @return
* < 0 error, > 0 state:
* 1="active" : input and consumption are active
* 2="ending" : input has ended without error
* 3="failing" : input had error and ended,
* 5="abandoned" : consumption has ended prematurely
* 6="ended" : consumption has ended without input error
* 7="aborted" : consumption has ended after input error
*/
int iso_ring_buffer_get_buf_status(IsoRingBuffer *buf, size_t *size,
size_t *free_bytes);
/**
* Close the buffer (to be called by the writer).
* You have to explicity close the buffer when you don't have more data to
* You have to explicitly close the buffer when you don't have more data to
* write, otherwise reader will be waiting forever.
*
* @param error

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 Thomas Schmitt
* Copyright (c) 2009 - 2024 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
@ -8,6 +8,10 @@
* See COPYING file for details.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
/* libisofs.h defines aaip_xinfo_func */
#include "libisofs.h"
@ -16,15 +20,13 @@
#include "fsource.h"
#include "image.h"
#include "aaip_0_2.h"
#include "util.h"
#include "messages.h"
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#ifndef PATH_MAX
#define PATH_MAX Libisofs_default_path_maX
#endif
#include <stdio.h>
@ -71,6 +73,15 @@ int default_create_file(IsoNodeBuilder *builder, IsoImage *image,
iso_file_source_ref(src);
name = iso_file_source_get_name(src);
if ((int) strlen(name) > image->truncate_length) {
ret = iso_truncate_rr_name(image->truncate_mode,
image->truncate_length, name, 0);
if (ret < 0) {
iso_stream_unref(stream);
free(name);
return ret;
}
}
ret = iso_node_new_file(name, stream, &node);
if (ret < 0) {
iso_stream_unref(stream);
@ -93,18 +104,20 @@ 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;
int ret, name_is_attached = 0;
struct stat info;
IsoNode *new;
IsoFilesystem *fs;
char *name;
unsigned char *aa_string;
char *name = NULL;
unsigned char *aa_string = NULL;
char *a_text = NULL, *d_text = NULL;
char *dest = NULL;
IsoSymlink *link;
if (builder == NULL || src == NULL || node == NULL) {
return ISO_NULL_POINTER;
{ret = ISO_NULL_POINTER; goto ex;}
}
/* get info about source */
@ -114,10 +127,24 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
ret = iso_file_source_lstat(src, &info);
}
if (ret < 0) {
return ret;
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 ((int) strlen(name) > image->truncate_length) {
ret = iso_truncate_rr_name(image->truncate_mode,
image->truncate_length, name, 0);
if (ret < 0)
goto ex;
}
fs = iso_file_source_get_filesystem(src);
new = NULL;
@ -153,10 +180,8 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
case S_IFLNK:
{
/* source is a symbolic link */
char dest[PATH_MAX];
IsoSymlink *link;
ret = iso_file_source_readlink(src, dest, PATH_MAX);
LIBISO_ALLOC_MEM(dest, char, LIBISOFS_NODE_PATH_MAX);
ret = iso_file_source_readlink(src, dest, LIBISOFS_NODE_PATH_MAX);
if (ret < 0) {
break;
}
@ -190,12 +215,14 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
}
}
break;
default:
ret = ISO_BAD_FSRC_FILETYPE;
goto ex;
}
if (ret < 0) {
free(name);
return ret;
}
if (ret < 0)
goto ex;
name_is_attached = 1;
/* fill fields */
iso_node_set_perms_internal(new, info.st_mode, 1);
@ -209,34 +236,53 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
/* Eventually set S_IRWXG from ACL */
if (image->builder_ignore_acl) {
ret = iso_file_source_get_aa_string(src, &aa_string, 4);
if (aa_string != NULL)
if (ret >= 0 && aa_string != NULL)
iso_aa_get_acl_text(aa_string, info.st_mode, &a_text, &d_text, 16);
if (a_text != NULL) {
if (ret >= 0 && a_text != NULL) {
aaip_cleanout_st_mode(a_text, &(info.st_mode), 4 | 16);
iso_node_set_perms_internal(new, info.st_mode, 1);
}
iso_aa_get_acl_text(aa_string, info.st_mode, &a_text, &d_text,
1 << 15); /* free ACL texts */
if(aa_string != NULL)
free(aa_string);
aa_string = NULL;
}
/* Obtain ownership of eventual AAIP string */
ret = iso_file_source_get_aa_string(src, &aa_string,
1 | (image->builder_ignore_acl << 1) |
(image->builder_ignore_ea << 2 ));
if (ret == 1 && aa_string != NULL) {
(image->builder_ignore_ea << 2) |
(image->builder_take_all_ea << 3) |
((!image->builder_ignore_lfa_flags) << 4) |
(image->builder_ignore_ro_lfa_flags << 5) |
((!image->builder_ignore_projid) << 6));
if(ret == 2)
image->blind_on_local_get_attrs = 1;
if (ret > 0 && aa_string != NULL) {
ret = iso_node_add_xinfo(new, aaip_xinfo_func, aa_string);
if (ret < 0)
return ret;
goto ex;
} else if(aa_string != NULL) {
free(aa_string);
}
*node = new;
return ISO_SUCCESS;
ret = ISO_SUCCESS;
ex:;
if (name != NULL && !name_is_attached)
free(name);
LIBISO_FREE_MEM(dest);
return ret;
}
static
void default_free(IsoNodeBuilder *builder)
{
/* The .free() method of IsoNodeBuilder shall free private data but not
the builder itself. The latter is done in iso_node_builder_unref().
*/
return;
}

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
@ -33,7 +34,7 @@ struct Iso_Node_Builder
* always be created, even if src is another kind of file.
*
* In that case, if the implementation can't do the conversion, it
* should fail propertly.
* should fail properly.
*
* Note that the src is never unref, so you need to free it.
*
@ -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.

1021
libisofs/changelog.txt Normal file

File diff suppressed because it is too large Load Diff

View File

@ -7,6 +7,10 @@
* See COPYING file for details.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include "libisofs.h"
#include "util.h"
@ -17,6 +21,11 @@
#include <fcntl.h>
#include <unistd.h>
/* O_BINARY is needed for Cygwin but undefined elsewhere */
#ifndef O_BINARY
#define O_BINARY 0
#endif
/**
* Private data for File IsoDataSource
*/
@ -61,7 +70,7 @@ int ds_open(IsoDataSource *src)
return ISO_FILE_ALREADY_OPENED;
}
fd = open(data->path, O_RDONLY);
fd = open(data->path, O_RDONLY | O_BINARY);
if (fd == -1) {
return ISO_FILE_ERROR;
}
@ -136,7 +145,7 @@ void ds_free_data(IsoDataSource *src)
/**
* Create a new IsoDataSource from a local file. This is suitable for
* accessing regular .iso images, or to acces drives via its block device
* accessing regular .iso images, or to access drives via its block device
* and standard POSIX I/O calls.
*
* @param path

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 - 2025 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
@ -15,7 +15,14 @@
#include "util.h"
#include "buffer.h"
#ifdef HAVE_STDINT_H
#include <stdint.h>
#else
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#endif
#include <pthread.h>
#define BLOCK_SIZE 2048
@ -26,27 +33,85 @@
#define MAX_ISO_FILE_SECTION_SIZE 0xffffffff
/*
* When a file need to be splitted in several sections, the maximum size
* When a file need to be split in several sections, the maximum size
* of such sections, but the last one. Set to a multiple of BLOCK_SIZE.
* Default to 4GB - 2048 = 0xFFFFF800
*/
#define ISO_EXTENT_SIZE 0xFFFFF800
/*
* The maximum number of partition images that can be registered. Depending
* on the system area type, the effectively usable number may be smaller or
* even 0.
*/
#define ISO_MAX_PARTITIONS 8
/*
* The cylindersize with SUN Disk Label
* (512 bytes/sector, 640 sectors/head, 1 head/cyl = 320 KiB).
* Expressed in ECMA-119 blocks of 2048 bytes/block.
*/
#define ISO_SUN_CYL_SIZE 160
/*
* Maximum length of a disc label text plus 1.
*/
#define ISO_DISC_LABEL_SIZE 129
/* The maximum length of an specs violating ECMA-119 file identifier.
The theoretical limit is 254 - 34 - 28 (len of SUSP CE entry) = 192
Currently the practical limit is 254 - 34 - 96 (non-CE RR entries) - 28 (CE)
*/
#ifdef Libisofs_with_rrip_rR
#define ISO_UNTRANSLATED_NAMES_MAX 92
#else
#define ISO_UNTRANSLATED_NAMES_MAX 96
#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 defaulted to '_'.
*/
#define ISO_JOLIET_UCS2_WARN_MAX 3
/**
* Holds the options for the image generation.
*/
struct iso_write_opts {
int level; /**< ISO level to write at. (ECMA-119, 10) */
int will_cancel;
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 */
/* allways write timestamps in GMT */
/* always write timestamps in GMT */
unsigned int always_gmt :1;
/*
@ -54,11 +119,21 @@ struct iso_write_opts {
* but it is supposed to work on most moderns systems. Use with caution.
*/
/**
* Convert directory names for ECMA-119 the same way as other file names
* but do not force dots or add version numbers.
* This violates ECMA-119 by allowing one "." and especially ISO level 1
* by allowing DOS style 8.3 names rather than only 8 characters.
*/
unsigned int allow_dir_id_ext :1;
/**
* Omit the version number (";1") at the end of the ISO-9660 identifiers.
* Version numbers are usually not used.
* bit0= ECMA-119 and Joliet (for historical reasons)
* bit1= Joliet
*/
unsigned int omit_version_numbers :1;
unsigned int omit_version_numbers :2;
/**
* Allow ISO-9660 directory hierarchy to be deeper than 8 levels.
@ -82,8 +157,10 @@ struct iso_write_opts {
* ISO-9660 forces filenames to have a ".", that separates file name from
* extension. libisofs adds it if original filename doesn't has one. Set
* this to 1 to prevent this behavior
* bit0= ECMA-119
* bit1= Joliet
*/
unsigned int no_force_dots :1;
unsigned int no_force_dots :2;
/**
* Allow lowercase characters in ISO-9660 filenames. By default, only
@ -97,9 +174,16 @@ struct iso_write_opts {
*/
unsigned int allow_full_ascii :1;
/**
* If not allow_full_ascii is set: allow all 7 bit characters that would
* be allowed by allow_full_ascii. But still map lowercase to uppercase if
* not allow_lowercase is set to 1.
*/
unsigned int allow_7bit_ascii :1;
/**
* Allow all characters to be part of Volume and Volset identifiers on
* the Primary Volume Descriptor. This breaks ISO-9660 contraints, but
* the Primary Volume Descriptor. This breaks ISO-9660 constraints, but
* should work on modern systems.
*/
unsigned int relaxed_vol_atts :1;
@ -109,6 +193,16 @@ struct iso_write_opts {
*/
unsigned int joliet_longer_paths :1;
/**
* Allow Joliet names up to 103 characters rather than 64.
*/
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",
@ -121,6 +215,12 @@ struct iso_write_opts {
*/
unsigned int rrip_1_10_px_ino :1;
/**
* Write field TF with timestamps of long form with 17 bytes instead
* of 7-byte timestamps
*/
unsigned int rrip_tf_long :1;
/**
* See iso_write_opts_set_hardlinks()
*/
@ -129,7 +229,7 @@ struct iso_write_opts {
/**
* Write AAIP as extension according to SUSP 1.10 rather than SUSP 1.12.
* I.e. without announcing it by an ER field and thus without the need
* to preceed the RRIP fields by an ES and to preceed the AA field by ES.
* to precede the RRIP fields by an ES and to precede the AA field by ES.
* This saves bytes and might avoid problems with readers which dislike
* ER fields other than the ones for RRIP.
* On the other hand, SUSP 1.12 frowns on such unannounced extensions
@ -145,10 +245,27 @@ struct iso_write_opts {
* to expect that we do have a creation timestamp with the source.
* mkisofs writes mtimes and the result seems more suitable if mounted
* without Rock Ridge support.)
* bit0= ECMA-119, bit1= Joliet, bit2= ISO 9660:1999
*/
unsigned int dir_rec_mtime :1;
unsigned int dir_rec_mtime :3;
#ifdef Libisofs_with_checksumS
/**
* This describes the directory where to store Rock Ridge relocated
* directories.
* If not relaxation "allow_deep_paths" is in effect, it is necessary to
* relocate directories so that no ECMA-119 file path has more than
* 8 components. For Rock Ridge the relocated directories are linked forth
* and back to a placeholder at their original position in path level 8
* (entries CL and PL). Directories marked by entry RE are to be considered
* artefacts of relocation and shall not be read into a Rock Ridge tree.
* For plain ECMA-119, the relocation directory is just a normal directory
* which contains normal files and directories.
*/
char *rr_reloc_dir; /* IsoNode name in root directory */
int rr_reloc_flags; /* bit0= mark auto-created rr_reloc_dir by RE
bit1= directory was auto-created
(cannot be set via API)
*/
/**
* Compute MD5 checksum for the whole session and record it as index 0 of
@ -170,15 +287,13 @@ struct iso_write_opts {
*/
unsigned int md5_file_checksums :2;
#endif /* Libisofs_with_checksumS */
/** If files should be sorted based on their weight. */
unsigned int sort_files :1;
/**
* The following options set the default values for files and directory
* permissions, gid and uid. All these take one of three values: 0, 1 or 2.
* If 0, the corresponding attribute will be kept as setted in the IsoNode.
* If 0, the corresponding attribute will be kept as set in the IsoNode.
* Unless you have changed it, it corresponds to the value on disc, so it
* is suitable for backup purposes. If set to 1, the corresponding attrib.
* will be changed by a default suitable value. Finally, if you set it to
@ -196,6 +311,26 @@ struct iso_write_opts {
uid_t uid; /** uid to use when replace_uid == 2. */
gid_t gid; /** gid to use when replace_gid == 2. */
/**
* See API call iso_write_opts_set_old_empty().
*/
unsigned int old_empty :1;
/**
* Extra Caution: This option breaks any assumptions about names that
* are supported by ECMA-119 specifications.
* Omit any translation which would make a file name compliant to the
* ECMA-119 rules. This includes and exceeds omit_version_numbers,
* max_37_char_filenames, no_force_dots bit0, allow_lowercase.
* The maximum name length is given by this variable.
* There is a length limit of ISO_UNTRANSLATED_NAMES_MAX characters,
* because ECMA-119 allows 254 byte in a directory record, some
* of them are occupied by ECMA-119, some more are needed for SUSP CE,
* and some are fixely occupied by libisofs Rock Ridge code.
* The default value 0 disables this feature.
*/
unsigned int untranslated_name_len;
/**
* 0 to use IsoNode timestamps, 1 to use recording time, 2 to use
* values from timestamp field. This has only meaning if RR extensions
@ -220,7 +355,7 @@ struct iso_write_opts {
* or write to an .iso file for future burning or distribution.
*
* On the other side, an appendable image is not self contained, it refers
* to serveral files that are stored outside the image. Its usage is for
* to several files that are stored outside the image. Its usage is for
* multisession discs, where you add data in a new session, while the
* previous session data can still be accessed. In those cases, the old
* data is not written again. Instead, the new image refers to it, and thus
@ -252,7 +387,7 @@ struct iso_write_opts {
/**
* When not NULL, it should point to a buffer of at least 64KiB, where
* libisofs will write the contents that should be written at the beginning
* of a overwriteable media, to grow the image. The growing of an image is
* of a overwritable media, to grow the image. The growing of an image is
* a way, used by first time in growisofs by Andy Polyakov, to allow the
* appending of new data to non-multisession media, such as DVD+RW, in the
* same way you append a new session to a multisession disc, i.e., without
@ -264,7 +399,7 @@ struct iso_write_opts {
*
* You should initialize the buffer either with 0s, or with the contents of
* the first blocks of the image you're growing. In most cases, 0 is good
* enought.
* enough.
*/
uint8_t *overwrite;
@ -298,71 +433,166 @@ struct iso_write_opts {
*/
char *scdbackup_tag_written;
/*
* See ecma119_image : System Area related information
*/
char *system_area_data;
int system_area_size;
int system_area_options;
/* 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.
Must be 0 or >= 16. (Actually >= number of voldescr + checksum tag)
*/
uint32_t partition_offset;
/* 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;
#ifdef Libisofs_with_libjtE
/* Parameters and state of Jigdo Template Export environment.
*/
struct libjte_env *libjte_handle;
#endif /* Libisofs_with_libjtE */
/* A trailing padding of zero bytes which belongs to the image
*/
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;
int prep_part_flag;
/* Eventual disk file path of an EFI system partition image which shall
be prepended to HFS+/FAT and IsoFileSrc areas and marked by a GPT entry.
*/
char *efi_boot_partition;
int efi_boot_part_flag;
/* Disk file paths of prepared images which shall be appended
after the ISO image and described by partition table entries in a MBR.
NULL means unused.
*/
char *appended_partitions[ISO_MAX_PARTITIONS];
uint8_t appended_part_types[ISO_MAX_PARTITIONS];
int appended_part_flags[ISO_MAX_PARTITIONS];
uint8_t appended_part_type_guids[ISO_MAX_PARTITIONS][16];
/* Flags in case that appended partitions show up in GPT:
bit0= appended_part_type_guids is valid
*/
uint8_t appended_part_gpt_flags[ISO_MAX_PARTITIONS];
/* If 1: With appended partitions: create protective MBR and mark by GPT
*/
int appended_as_gpt;
/* If 1: With appended partitions: mark by APM partition
*/
int appended_as_apm;
/* If 1: Obey struct el_torito_boot_image.isolinux_options bit2-7 and bit8.
I.e. mention boot image as partition in GPT and/or APM.
*/
int part_like_isohybrid;
/* The type to use for the mountable ISO partition if there is any and if
the type is not mandatorily determined for particular circumstances like
compliant GPT, CHRP, or PReP.
-1 = use the default value (e.g. 0xcd, 0x83, 0x17)
0x00 to 0xff = value to use if possible
*/
int iso_mbr_part_type;
/* iso_write_opts_set_iso_type_guid
*/
uint8_t iso_gpt_type_guid[16];
/* bit0= iso_gpt_type_guid is valid
bit1= gaps in the image coverage are allowed
bit2= with bit1: do not sort GPT partition array by start block
bit3= with bit1: do not create partition 1 for ISO filesystem
*/
int iso_gpt_flag;
/* 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;
/* User defined GUID for GPT header and base of reproducible partition
GUIDs. (Not to be confused with volume "UUID", which is actually a
timestamp.)
See API call iso_write_opts_set_gpt_guid().
*/
uint8_t gpt_disk_guid[16];
int gpt_disk_guid_mode;
/* Maximum number of CE entries per file */
uint32_t max_ce_entries;
/* Whether to try dropping AAIP data on too many CE:
bit0-3 = Mode:
0 = throw ISO_TOO_MANY_CE, without trying to drop anything
1 = drop non-isofs fattr
2 = drop ACL if dropping non-isofs fattr does not suffice
*/
int max_ce_drop_attr;
};
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;
struct ecma119_image
{
int refcount;
IsoImage *image;
Ecma119Node *root;
unsigned int iso_level :2;
IsoWriteOpts *opts;
/* 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 omit_version_numbers :1;
unsigned int allow_deep_paths :1;
unsigned int allow_longer_paths :1;
unsigned int max_37_char_filenames :1;
unsigned int no_force_dots :1;
unsigned int allow_lowercase :1;
unsigned int allow_full_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;
/** 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 timestamp mtime of source */
unsigned int dir_rec_mtime :1;
#ifdef Libisofs_with_checksumS
unsigned int md5_session_checksum :1;
unsigned int md5_file_checksums :2;
#endif /* Libisofs_with_checksumS */
/* The ECMA-119 directory node where to store Rock Ridge relocated
directories. (Path is in IsoWriteOpts.rr_reloc_dir)
*/
Ecma119Node *rr_reloc_node; /* Directory node in ecma119_image */
/*
* 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;
@ -370,30 +600,35 @@ 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;
/**
* 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. */
/* Total size of the output. Counted in bytes.
* Includes ISO filesystem and appended data.
*/
off_t total_size;
/** Size actually governed by the ISO filesystem part of the output */
uint32_t vol_space_size;
/* Bytes already written, just for progress notification */
/* 1= write the total size into the PVD of the ISO,
* 0= write vol_space_size
*/
int pvd_size_is_total_size;
/* Bytes already written to image output */
off_t bytes_written;
/* just for progress notification */
int percent_written;
/*
@ -402,6 +637,17 @@ struct ecma119_image
*/
uint32_t curblock;
/*
* The address to be used for the content pointer of empty data files.
*/
uint32_t empty_file_block;
/*
* The calculated block address after ECMA-119 tree and eventual
* tree checksum tag.
*/
uint32_t tree_end_block;
/*
* number of dirs in ECMA-119 tree, computed together with dir position,
* and needed for path table computation in a efficient way
@ -419,6 +665,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
@ -434,7 +704,55 @@ struct ecma119_image
*/
struct el_torito_boot_catalog *catalog;
IsoFileSrc *cat; /**< location of the boot catalog in the new image */
IsoFileSrc *bootimg; /**< location of the boot image in the new image */
int num_bootsrc;
IsoFileSrc **bootsrc; /* location of the boot images in the new image */
int *boot_appended_idx; /* Appended partition which serve as boot images */
uint32_t *boot_intvl_start; /* In blocks of 2048 bytes */
uint32_t *boot_intvl_size; /* In blocks of 512 bytes */
/*
* System Area related information
*/
/* Content of an embedded boot image. Valid if not NULL.
* In that case it must point to a memory buffer at least 32 kB.
*/
char *system_area_data;
/*
* bit0= Only with DOS MBR
* Make bytes 446 - 512 of the system area a partition
* table which reserves partition 1 from byte 63*512 to the
* end of the ISO image. Assumed are 63 secs/hed, 255 head/cyl.
* (GRUB protective msdos label.)
* This works with and without system_area_data.
* bit1= Only with DOS MBR
* Apply isohybrid MBR patching to the system area.
* This works only with system_area_data plus ISOLINUX boot image
* and only if not bit0 is set.
* bit2-7= System area type
* 0= DOS MBR
* 1= MIPS Big Endian Volume Header
* 2= DEC Boot Block for MIPS Little Endian
* 3= SUN Disk Label for SUN SPARC
* bit8-9= Only with DOS MBR
* Cylinder alignment mode eventually pads the image to make it
* end at a cylinder boundary.
* 0 = auto (align if bit1)
* 1 = always align to cylinder boundary
* 2 = never align to cylinder boundary
* 3 = always align, additionally pad up and align partitions
* which were appended by iso_write_opts_set_partition_img()
* 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;
/*
* Number of pad blocks that we need to write. Padding blocks are blocks
@ -449,7 +767,7 @@ struct ecma119_image
* file data is written in the first 64 KiB, that are the bytes we usually
* overwrite.
*/
uint32_t pad_blocks;
uint32_t mspad_blocks;
size_t nwriters;
IsoImageWriter **writers;
@ -457,7 +775,7 @@ struct ecma119_image
/* tree of files sources */
IsoRBTree *files;
#ifdef Libisofs_with_checksumS
struct iso_filesrc_list_item *ecma119_hidden_list;
unsigned int checksum_idx_counter;
void *checksum_ctx;
@ -476,22 +794,160 @@ 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;
#endif /* Libisofs_with_checksumS */
/* Buffer for communication between burn_source and writer thread */
IsoRingBuffer *buffer;
/* writer thread descriptor */
pthread_t wthread;
int wthread_is_running;
pthread_attr_t th_attr;
/* 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;
/* The currently applicable LBA offset. To be subtracted from any LBA
* that is mentioned in volume descriptors, trees, path tables,
* Either 0 or .partition_offset
*/
uint32_t eff_partition_offset;
/* The second ECMA-119 directory tree and path tables */
Ecma119Node *partition_root;
uint32_t partition_l_table_pos;
uint32_t partition_m_table_pos;
/* The second Joliet directory tree and path tables */
JolietNode *j_part_root;
uint32_t j_part_l_path_table_pos;
uint32_t j_part_m_path_table_pos;
/* 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;
/* A data file of which the position and size shall be written after
a SUN Disk Label.
*/
IsoFileSrc *sparc_core_src;
/* Trailing padding of ISO filesystem partition for cylinder alignment */
/* Only in effect with Libisofs_part_align_writeR */
uint32_t part_align_blocks;
uint32_t alignment_end_block;
/* 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];
int have_appended_partitions;
/* 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 * hfsp_block_size */
int hfsp_iso_block_fac; /* 2048 / hfsp_block_size */
/* Apple Partition Map description. To be composed during IsoImageWriter
method ->compute_data_blocks() by calling iso_register_apm_entry().
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;
/* Number of bytes which have to be added after the cylinder aligned end
of the overall ISO partition because clinder size is not a multiple
of 2048
*/
int post_iso_part_pad;
uint32_t prep_part_size;
/* GPT description. To be composed during IsoImageWriter
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;
/* Whether the eventual backup GPT is not part of the ISO filesystem */
int gpt_backup_outside;
/* The base UUID for the generated GPT UUIDs */
uint8_t gpt_uuid_base[16];
/* The counter which distinguishes the GPT UUIDs */
uint32_t gpt_uuid_counter;
uint32_t efi_boot_part_size;
IsoFileSrc *efi_boot_part_filesrc; /* Just a pointer. Do not free. */
/* Messages from gpt_tail_writer_compute_data_blocks() to
iso_write_system_area().
*/
uint8_t gpt_disk_guid[16];
int gpt_disk_guid_set;
/* Start of GPT entries in System Area, block size 512 */
uint32_t gpt_part_start;
/* The ISO block number after the backup GPT header , block size 2048 */
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];
int sys_area_already_written;
/* 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;
/* Number of CE entries in currently processed node */
uint32_t curr_ce_entries;
/* Count of symbolic links and special files which could not be represented
in Joliet.
*/
unsigned long joliet_symlinks;
unsigned long joliet_specials;
/* Count of symbolic links and special files which could not be represented
in ISO 9660:1999.
*/
unsigned long iso1999_symlinks;
unsigned long iso1999_specials;
};
#define BP(a,b) [(b) - (a) + 1]
@ -622,5 +1078,38 @@ 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);
/* Tells whether ivr is a reader from imported_iso in a multi-session
add-on situation, and thus to be kept in place.
*/
int iso_interval_reader_keep(Ecma119Image *target,
struct iso_interval_reader *ivr,
int flag);
/* @return: ISO_SUCCESS = ok, ISO_SUCCESS + 1 = keep , < 0 = error */
int iso_interval_reader_start_size(Ecma119Image *t, char *path,
off_t *start_byte, off_t *byte_count,
int flag);
/* Obtains start and end number of appended partition range and returns
the number of valid entries in the list of appended partitions.
*/
int iso_count_appended_partitions(Ecma119Image *target,
int *first_partition, int *last_partition);
/* Determines the range of valid partition numbers depending on partition
table type.
*/
void iso_tell_max_part_range(IsoWriteOpts *opts,
int *first_partition, int *last_partition,
int flag);
#endif /*LIBISO_ECMA119_H_*/

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 Thomas Schmitt
* Copyright (c) 2009 - 2016 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
@ -8,6 +8,13 @@
* See COPYING file for details.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
/* Must be before ecma119.h because of eventual Libisofs_with_rrip_rR */
#include "libisofs.h"
#include "ecma119_tree.h"
#include "ecma119.h"
#include "node.h"
@ -22,66 +29,122 @@
#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;
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;
}
ret = str2ascii(img->input_charset, iso->name, &ascii_name);
if (opts->untranslated_name_len > 0) {
ascii_name = node_name;
ret = 1;
} else {
ret = str2ascii(input_charset, node_name, &ascii_name);
free_ascii_name = 1;
}
if (ret < 0) {
iso_msg_submit(img->image->id, ret, 0, "Can't convert %s", 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 (iso->type == LIBISO_DIR) {
if (img->max_37_char_filenames) {
if (opts->allow_7bit_ascii)
relaxed |= 4;
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:;
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), opts->untranslated_name_len,
ascii_name);
return ISO_NAME_NEEDS_TRANSL;
}
isoname = strdup(ascii_name);
} 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
if (relaxed) {
isoname = iso_r_dirid(ascii_name, 8, relaxed);
} else {
isoname = iso_1_dirid(ascii_name);
isoname = iso_1_dirid(ascii_name, 0);
}
#else /* Libisofs_old_ecma119_nameS */
isoname = iso_1_dirid(ascii_name, relaxed);
#endif /* ! Libisofs_old_ecma119_nameS */
} else {
if (relaxed) {
isoname = iso_r_dirid(ascii_name, 8, relaxed);
isoname = iso_r_dirid(ascii_name, 31, relaxed);
} else {
isoname = iso_2_dirid(ascii_name);
}
}
} else {
if (img->max_37_char_filenames) {
isoname = iso_r_fileid(ascii_name, 36, relaxed,
img->no_force_dots ? 0 : 1);
} else if (img->iso_level == 1) {
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 (opts->max_37_char_filenames) {
isoname = iso_r_fileid(ascii_name, 36, relaxed, force_dots);
} else if (opts->iso_level == 1) {
#ifdef Libisofs_old_ecma119_nameS
int max_len;
if (relaxed) {
isoname = iso_r_fileid(ascii_name, 11, relaxed,
img->no_force_dots ? 0 : 1);
if (strchr(ascii_name, '.') == NULL)
max_len = 8;
else
max_len = 11;
isoname = iso_r_fileid(ascii_name, max_len, relaxed,
force_dots);
} else {
isoname = iso_1_fileid(ascii_name);
isoname = iso_1_fileid(ascii_name, 0, force_dots);
}
#else /* Libisofs_old_ecma119_nameS */
isoname = iso_1_fileid(ascii_name, relaxed, force_dots);
#endif /* ! Libisofs_old_ecma119_nameS */
} else {
if (relaxed) {
isoname = iso_r_fileid(ascii_name, 30, relaxed,
img->no_force_dots ? 0 : 1);
if (relaxed || !force_dots) {
isoname = iso_r_fileid(ascii_name, 30, relaxed, force_dots);
} else {
isoname = iso_2_fileid(ascii_name);
}
}
}
free(ascii_name);
if (free_ascii_name)
free(ascii_name);
if (isoname != NULL) {
*name = isoname;
return ISO_SUCCESS;
@ -94,6 +157,25 @@ int get_iso_name(Ecma119Image *img, IsoNode *iso, char **name)
}
}
static
int get_iso_name(Ecma119Image *img, IsoNode *iso, char **name)
{
int ret;
ret = iso_get_ecma119_name(img->opts, img->input_charset, img->image->id,
iso->name, iso->type, name, 0);
return ret;
}
int ecma119_is_dedicated_reloc_dir(Ecma119Image *img, Ecma119Node *node)
{
if (img->rr_reloc_node == node &&
node != img->root && node != img->partition_root &&
(img->opts->rr_reloc_flags & 2))
return 1;
return 0;
}
static
int create_ecma119_node(Ecma119Image *img, IsoNode *iso, Ecma119Node **node)
{
@ -119,23 +201,26 @@ static
int create_dir(Ecma119Image *img, IsoDir *iso, Ecma119Node **node)
{
int ret;
Ecma119Node **children;
Ecma119Node **children = NULL;
struct ecma119_dir_info *dir_info;
children = calloc(1, sizeof(void*) * iso->nchildren);
if (children == NULL) {
return ISO_OUT_OF_MEM;
if (iso->nchildren > 0) {
children = calloc(1, sizeof(void*) * iso->nchildren);
if (children == NULL)
return ISO_OUT_OF_MEM;
}
dir_info = calloc(1, sizeof(struct ecma119_dir_info));
if (dir_info == NULL) {
free(children);
if (children != NULL)
free(children);
return ISO_OUT_OF_MEM;
}
ret = create_ecma119_node(img, (IsoNode*)iso, node);
if (ret < 0) {
free(children);
if (children != NULL)
free(children);
free(dir_info);
return ret;
}
@ -146,6 +231,30 @@ int create_dir(Ecma119Image *img, IsoDir *iso, Ecma119Node **node)
return ISO_SUCCESS;
}
static
int create_file_src(Ecma119Image *img, IsoFile *iso, IsoFileSrc **src)
{
int ret;
off_t size;
size = iso_stream_get_size(iso->stream);
if (size > (off_t)MAX_ISO_FILE_SECTION_SIZE && img->opts->iso_level != 3) {
char *ipath = iso_tree_get_node_path(ISO_NODE(iso));
iso_msg_submit(img->image->id, ISO_FILE_TOO_BIG, 0,
"File \"%s\" cannot be added to image because "
"its size is 4 GiB or larger", ipath);
free(ipath);
return ISO_FILE_TOO_BIG;
}
ret = iso_file_src_create(img, iso, src);
if (ret < 0) {
return ret;
}
return 0;
}
/**
* Create a new ECMA-119 node representing a regular file from a iso file
* node.
@ -155,19 +264,8 @@ int create_file(Ecma119Image *img, IsoFile *iso, Ecma119Node **node)
{
int ret;
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) {
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 "
"is greater than 4GB", ipath);
free(ipath);
return ret;
}
ret = iso_file_src_create(img, iso, &src);
ret = create_file_src(img, iso, &src);
if (ret < 0) {
return ret;
}
@ -254,11 +352,12 @@ void ecma119_node_free(Ecma119Node *node)
return;
}
if (node->type == ECMA119_DIR) {
int i;
size_t i;
for (i = 0; i < node->info.dir->nchildren; i++) {
ecma119_node_free(node->info.dir->children[i]);
}
free(node->info.dir->children);
if (node->info.dir->children != NULL)
free(node->info.dir->children);
free(node->info.dir);
}
free(node->iso_name);
@ -266,60 +365,114 @@ void ecma119_node_free(Ecma119Node *node)
free(node);
}
static
int add_to_hidden_list(Ecma119Image *image, IsoFileSrc *src)
{
int ret;
struct iso_filesrc_list_item *item;
LIBISO_ALLOC_MEM(item, struct iso_filesrc_list_item, 1);
item->src = src;
item->next = image->ecma119_hidden_list;
image->ecma119_hidden_list = item;
ret = ISO_SUCCESS;
ex:
return ret;
}
int iso_filesrc_list_destroy(struct iso_filesrc_list_item **start_item)
{
struct iso_filesrc_list_item *item, *next;
for (item = *start_item; item != NULL; item = next) {
next = item->next;
LIBISO_FREE_MEM(item);
}
return ISO_SUCCESS;
}
/**
*
* @param flag
* bit0= iso is in a hidden directory. Thus hide it.
* @return
* 1 success, 0 node ignored, < 0 error
*
*/
static
int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree,
int depth, int pathlen)
int depth, int pathlen, int flag)
{
int ret;
Ecma119Node *node;
int ret, hidden;
Ecma119Node *node = NULL;
int max_path;
char *iso_name= NULL;
char *iso_name= NULL, *ipath = NULL;
IsoFileSrc *src = NULL;
IsoWriteOpts *opts;
if (image == NULL || iso == NULL || tree == NULL) {
return ISO_NULL_POINTER;
}
opts = image->opts;
*tree = NULL;
hidden = flag & 1;
if (iso->hidden & LIBISO_HIDE_ON_RR) {
/* file will be ignored */
return 0;
hidden = 1;
if (!((iso->hidden & LIBISO_HIDE_BUT_WRITE) ||
iso->type == LIBISO_BOOT)) {
return 0; /* file will be ignored */
}
}
ret = get_iso_name(image, iso, &iso_name);
if (ret < 0) {
return ret;
}
max_path = pathlen + 1 + (iso_name ? strlen(iso_name) : 0);
if (!image->rockridge) {
if ((iso->type == LIBISO_DIR && depth > 8) && !image->allow_deep_paths) {
char *ipath = iso_tree_get_node_path(iso);
return 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);
free(iso_name);
free(ipath);
return ret;
} else if (max_path > 255 && !image->allow_longer_paths) {
char *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 path length "
"is greater than 255 characters", ipath);
free(iso_name);
free(ipath);
return ret;
if (hidden) {
max_path= pathlen;
} else {
ret = get_iso_name(image, iso, &iso_name);
if (ret < 0) {
iso_name = NULL; /* invalid, do not free */
goto ex;
}
max_path = pathlen + 1 + (iso_name ? strlen(iso_name) : 0);
if (!opts->rockridge) {
if ((iso->type == LIBISO_DIR && depth > 8) &&
!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 && !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, "
"because path length "
"is greater than 255 characters", ipath);
goto ex;
}
}
}
switch (iso->type) {
case LIBISO_FILE:
ret = create_file(image, (IsoFile*)iso, &node);
if (hidden) {
ret = create_file_src(image, (IsoFile *) iso, &src);
if (ret <= 0)
goto ex;
ret = add_to_hidden_list(image, src);
} else {
ret = create_file(image, (IsoFile*)iso, &node);
}
break;
case LIBISO_SYMLINK:
if (image->rockridge) {
if (hidden) {
ret = 0; /* Hidden means non-existing */
goto ex;
}
if (opts->rockridge) {
ret = create_symlink(image, (IsoSymlink*)iso, &node);
} else {
/* symlinks are only supported when RR is enabled */
@ -331,7 +484,11 @@ int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree,
}
break;
case LIBISO_SPECIAL:
if (image->rockridge) {
if (hidden) {
ret = 0; /* Hidden means non-existing */
goto ex;
}
if (opts->rockridge) {
ret = create_special(image, (IsoSpecial*)iso, &node);
} else {
/* special files are only supported when RR is enabled */
@ -344,7 +501,14 @@ int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree,
break;
case LIBISO_BOOT:
if (image->eltorito) {
ret = create_boot_cat(image, (IsoBoot*)iso, &node);
if (hidden) {
ret = el_torito_catalog_file_src_create(image, &src);
if (ret <= 0)
goto ex;
ret = add_to_hidden_list(image, src);
} else {
ret = create_boot_cat(image, (IsoBoot*)iso, &node);
}
} else {
/* log and ignore */
ret = iso_msg_submit(image->image->id, ISO_FILE_IGNORED, 0,
@ -355,21 +519,34 @@ int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree,
{
IsoNode *pos;
IsoDir *dir = (IsoDir*)iso;
ret = create_dir(image, dir, &node);
if (ret < 0) {
return ret;
if (!hidden) {
ret = create_dir(image, dir, &node);
if (ret < 0) {
goto ex;
}
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 (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;
}
}
ret = ISO_SUCCESS;
pos = dir->children;
while (pos) {
int cret;
Ecma119Node *child;
cret = create_tree(image, pos, &child, depth + 1, max_path);
cret = create_tree(image, pos, &child, depth + 1, max_path,
!!hidden);
if (cret < 0) {
/* error */
ecma119_node_free(node);
ret = cret;
break;
} else if (cret == ISO_SUCCESS) {
} else if (cret == ISO_SUCCESS && !hidden) {
/* add child to this node */
int nchildren = node->info.dir->nchildren++;
node->info.dir->children[nchildren] = child;
@ -381,15 +558,30 @@ int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree,
break;
default:
/* should never happen */
return ISO_ASSERT_FAILURE;
ret = ISO_ASSERT_FAILURE;
goto ex;
}
if (ret <= 0) {
free(iso_name);
return ret;
goto ex;
}
node->iso_name = iso_name;
*tree = node;
return ISO_SUCCESS;
if (!hidden) {
node->iso_name = iso_name;
iso_name = NULL; /* now owned by node, do not free */
*tree = node;
node = NULL; /* now owned by caller, do not free */
}
ret = ISO_SUCCESS;
ex:
if (iso_name != NULL)
free(iso_name);
if (ipath != NULL)
free(ipath);
if (node != NULL)
ecma119_node_free(node);
if (hidden && ret == ISO_SUCCESS)
ret = 0;
/* The sources of hidden files are now owned by the rb-tree */
return ret;
}
/**
@ -403,17 +595,41 @@ int cmp_node_name(const void *f1, const void *f2)
return strcmp(f->iso_name, g->iso_name);
}
/**
* Compare the iso name of two ECMA-119 nodes, without equivalences.
* Nodes with equal iso names are instead ordered by their real names.
*
* This is used to make the initial tree sort deterministic, before
* iso names are mangled to become unique.
*/
static
int cmp_node_name_tiebreak(const void *f1, const void *f2)
{
Ecma119Node *f, *g;
int cmp;
cmp = cmp_node_name(f1, f2);
if (cmp)
return cmp;
f = *((Ecma119Node**)f1);
g = *((Ecma119Node**)f2);
return strcmp(f->node->name, g->node->name);
}
/**
* Sorts a the children of each directory in the ECMA-119 tree represented
* by \p root, acording to the order specified in ECMA-119, section 9.3.
* by \p root, according to the order specified in ECMA-119, section 9.3.
*/
static
void sort_tree(Ecma119Node *root)
{
size_t i;
if (root->info.dir->children == NULL)
return;
qsort(root->info.dir->children, root->info.dir->nchildren, sizeof(void*),
cmp_node_name);
cmp_node_name_tiebreak);
for (i = 0; i < root->info.dir->nchildren; i++) {
if (root->info.dir->children[i]->type == ECMA119_DIR)
sort_tree(root->info.dir->children[i]);
@ -440,6 +656,9 @@ int mangle_single_dir(Ecma119Image *img, Ecma119Node *dir, int max_file_len,
nchildren = dir->info.dir->nchildren;
children = dir->info.dir->children;
if (nchildren <= 0)
return ISO_SUCCESS; /* nothing to do */
/* a hash table will temporary hold the names, for fast searching */
ret = iso_htable_create((nchildren * 100) / 80, iso_str_hash,
(compare_function_t)strcmp, &table);
@ -457,6 +676,7 @@ int mangle_single_dir(Ecma119Image *img, Ecma119Node *dir, int max_file_len,
for (i = 0; i < nchildren; ++i) {
char *name, *ext;
char full_name[40];
const int full_max_len = 40 - 1;
int max; /* computed max len for name, without extension */
int j = i;
int digits = 1; /* characters to change per name */
@ -471,8 +691,20 @@ int mangle_single_dir(Ecma119Image *img, Ecma119Node *dir, int max_file_len,
continue;
}
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.
*/
iso_msg_submit(img->image->id, ISO_NAME_NEEDS_TRANSL, 0,
"ECMA-119 file name collision: '%s'",
children[i]->iso_name);
ret = ISO_NAME_NEEDS_TRANSL;
goto mangle_cleanup;
}
/*
* A max of 7 characters is good enought, it allows handling up to
* A max of 7 characters is good enough, it allows handling up to
* 9,999,999 files with same name. We can increment this to
* max_name_len, but the int_pow() function must then be modified
* to return a bigger integer.
@ -483,14 +715,17 @@ int mangle_single_dir(Ecma119Image *img, Ecma119Node *dir, int max_file_len,
int change = 0; /* number to be written */
/* copy name to buffer */
strcpy(full_name, children[i]->iso_name);
strncpy(full_name, children[i]->iso_name, full_max_len);
full_name[full_max_len] = 0;
/* compute name and extension */
dot = strrchr(full_name, '.');
if (dot != NULL && children[i]->type != ECMA119_DIR) {
if (dot != NULL &&
(children[i]->type != ECMA119_DIR ||
img->opts->allow_dir_id_ext)) {
/*
* File (not dir) with extension
* File (normally not dir) with extension
* Note that we don't need to check for placeholders, as
* tree reparent happens later, so no placeholders can be
* here at this time.
@ -530,15 +765,15 @@ int mangle_single_dir(Ecma119Image *img, Ecma119Node *dir, int max_file_len,
name[max] = '\0';
}
} else {
/* Directory, or file without extension */
/* Directory (normally), or file without extension */
if (children[i]->type == ECMA119_DIR) {
max = max_dir_len - digits;
dot = NULL; /* dots have no meaning in dirs */
dot = NULL; /* dots (normally) have no meaning in dirs */
} else {
max = max_file_len - digits;
}
name = full_name;
if (max < strlen(name)) {
if ((size_t) max < strlen(name)) {
name[max] = '\0';
}
/* let ext be an empty string */
@ -573,8 +808,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);
@ -645,22 +883,32 @@ int mangle_dir(Ecma119Image *img, Ecma119Node *dir, int max_file_len,
}
static
int mangle_tree(Ecma119Image *img, int recurse)
int mangle_tree(Ecma119Image *img, Ecma119Node *dir, int recurse)
{
int max_file, max_dir;
Ecma119Node *root;
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 {
max_file = max_dir = 31;
}
if (recurse) {
return mangle_dir(img, img->root, max_file, max_dir);
if (dir != NULL) {
root = dir;
} else if (img->eff_partition_offset > 0) {
root = img->partition_root;
} else {
return mangle_single_dir(img, img->root, max_file, max_dir);
root = img->root;
}
if (recurse) {
return mangle_dir(img, root, max_file, max_dir);
} else {
return mangle_single_dir(img, root, max_file, max_dir);
}
}
@ -774,35 +1022,61 @@ int reparent(Ecma119Node *child, Ecma119Node *parent)
* 1 success, < 0 error
*/
static
int reorder_tree(Ecma119Image *img, Ecma119Node *dir, int level, int pathlen)
int reorder_tree(Ecma119Image *img, Ecma119Node *dir,
int dir_level, int dir_pathlen)
{
int ret;
size_t max_path;
int ret, level, pathlen, newpathlen;
size_t max_path, i;
Ecma119Node *reloc, *child;
/* might change by relocation */
level = dir_level;
pathlen = dir_pathlen;
max_path = pathlen + 1 + max_child_name_len(dir);
if (level > 8 || max_path > 255) {
ret = reparent(dir, img->root);
reloc = img->rr_reloc_node;
if (reloc == NULL) {
if (img->eff_partition_offset > 0) {
reloc = img->partition_root;
} else {
reloc = img->root;
}
}
ret = reparent(dir, reloc);
if (ret < 0) {
return ret;
}
/*
* we are appended to the root's children now, so there is no
* need to recurse (the root will hit us again)
*/
} else {
size_t i;
if (reloc == img->root || reloc == img->partition_root) {
/*
* we are appended to the root's children now, so there is no
* need to recurse (the root will hit us again)
*/
return ISO_SUCCESS;
}
for (i = 0; i < dir->info.dir->nchildren; i++) {
Ecma119Node *child = dir->info.dir->children[i];
if (child->type == ECMA119_DIR) {
int newpathlen = pathlen + 1 + strlen(child->iso_name);
ret = reorder_tree(img, child, level + 1, newpathlen);
if (ret < 0) {
return ret;
}
}
/* dir is now the relocated Ecma119Node */
pathlen = 37 + 1; /* The dir name might get longer by mangling */
level = 2;
if (img->opts->rr_reloc_dir != NULL) {
pathlen += strlen(img->rr_reloc_node->iso_name) + 1;
if(img->opts->rr_reloc_dir[0] != 0)
level = 3;
}
}
if (ecma119_is_dedicated_reloc_dir(img, (Ecma119Node *) dir))
return ISO_SUCCESS;
for (i = 0; i < dir->info.dir->nchildren; i++) {
child = dir->info.dir->children[i];
if (child->type == ECMA119_DIR) {
newpathlen = pathlen + 1 + strlen(child->iso_name);
ret = reorder_tree(img, child, level + 1, newpathlen);
if (ret < 0)
return ret;
}
}
return ISO_SUCCESS;
@ -908,6 +1182,11 @@ int family_set_ino(Ecma119Image *img, Ecma119Node **nodes, size_t family_start,
*/
if (img_ino == prev_ino)
img_ino = 0;
/* Accept only if it is within the 32 bit range. */
if (((uint64_t) img_ino) > 0xffffffff)
img_ino = 0;
}
if (img_ino == 0) {
img_ino = img_give_ino_number(img->image, 0);
@ -941,7 +1220,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 *),
@ -955,11 +1234,12 @@ int match_hardlinks(Ecma119Image *img, Ecma119Node *dir, int flag)
iso_node_get_id(nodes[0]->node, &fs_id, &dev_id, &img_ino, 1);
family_start = 0;
for (i = 1; i < node_count; i++) {
if (ecma119_node_cmp_hard(nodes + (i - 1), nodes + i) == 0) {
if (nodes[i]->type != ECMA119_DIR &&
ecma119_node_cmp_hard(nodes + (i - 1), nodes + i) == 0) {
/* Still in same ino family */
if (img_ino == 0) { /* Just in case any member knows its img_ino */
iso_node_get_id(nodes[0]->node, &fs_id, &dev_id, &img_ino, 1);
}
}
continue;
}
family_set_ino(img, nodes, family_start, i, img_ino, prev_ino, 0);
@ -981,7 +1261,7 @@ int ecma119_tree_create(Ecma119Image *img)
int ret;
Ecma119Node *root;
ret = create_tree(img, (IsoNode*)img->image->root, &root, 1, 0);
ret = create_tree(img, (IsoNode*)img->image->root, &root, 1, 0, 0);
if (ret <= 0) {
if (ret == 0) {
/* unexpected error, root ignored!! This can't happen */
@ -989,10 +1269,14 @@ int ecma119_tree_create(Ecma119Image *img)
}
return ret;
}
img->root = root;
if (img->eff_partition_offset > 0) {
img->partition_root = root;
} else {
img->root = root;
}
iso_msg_debug(img->image->id, "Matching hardlinks...");
ret = match_hardlinks(img, img->root, 0);
ret = match_hardlinks(img, root, 0);
if (ret < 0) {
return ret;
}
@ -1001,25 +1285,25 @@ int ecma119_tree_create(Ecma119Image *img)
sort_tree(root);
iso_msg_debug(img->image->id, "Mangling names...");
ret = mangle_tree(img, 1);
ret = mangle_tree(img, NULL, 1);
if (ret < 0) {
return ret;
}
if (img->rockridge && !img->allow_deep_paths) {
if (img->opts->rockridge && !img->opts->allow_deep_paths) {
/* reorder the tree, acording to RRIP, 4.1.5 */
ret = reorder_tree(img, img->root, 1, 0);
/* Relocate deep directories, according to RRIP, 4.1.5 */
ret = reorder_tree(img, root, 1, 0);
if (ret < 0) {
return ret;
}
/*
* and we need to remangle the root directory, as the function
* above could insert new directories into the root.
* above could insert new directories into the relocation directory.
* Note that recurse = 0, as we don't need to recurse.
*/
ret = mangle_tree(img, 0);
ret = mangle_tree(img, img->rr_reloc_node, 0);
if (ret < 0) {
return ret;
}
@ -1027,3 +1311,35 @@ int ecma119_tree_create(Ecma119Image *img)
return ISO_SUCCESS;
}
/**
* Search the tree for a certain IsoNode and return its owning Ecma119Node
* or NULL.
*/
static
Ecma119Node *search_iso_node(Ecma119Node *root, IsoNode *node)
{
size_t i;
Ecma119Node *res = NULL;
if (root->node == node)
return root;
for (i = 0; i < root->info.dir->nchildren && res == NULL; i++) {
if (root->info.dir->children[i]->type == ECMA119_DIR)
res = search_iso_node(root->info.dir->children[i], node);
else if (root->info.dir->children[i]->node == node)
res = root->info.dir->children[i];
}
return res;
}
Ecma119Node *ecma119_search_iso_node(Ecma119Image *img, IsoNode *node)
{
Ecma119Node *res = NULL;
if (img->root != NULL)
res = search_iso_node(img->root, node);
return res;
}

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* 2012 - 2025 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,9 +64,7 @@ struct ecma119_node
IsoNode *node; /*< reference to the iso node */
/* >>> ts A90501 : Shouldn't this be uint32_t
as this is what PX will take ? */
ino_t ino;
uint32_t ino;
nlink_t nlink;
@ -78,8 +77,22 @@ struct ecma119_node
/** this field points to the relocated directory. */
Ecma119Node *real_me;
} info;
/* If set to 1, use 17-byte time format in RRIP field TF */
unsigned int rrip_tf_long :1;
};
/* For recording files which are hidden in ECMA-119 */
struct iso_filesrc_list_item
{
IsoFileSrc *src;
struct iso_filesrc_list_item *next;
};
int iso_filesrc_list_destroy(struct iso_filesrc_list_item **start_item);
/**
*
*/
@ -90,4 +103,25 @@ int ecma119_tree_create(Ecma119Image *img);
*/
void ecma119_node_free(Ecma119Node *node);
/**
* Search the tree for a certain IsoNode and return its owning Ecma119Node
* or NULL.
*/
Ecma119Node *ecma119_search_iso_node(Ecma119Image *img, IsoNode *node);
/**
* Tell whether node is a dedicated relocation directory which only contains
* relocated directories.
*/
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_*/

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2010 - 2024 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
@ -25,27 +26,83 @@
struct Iso_Boot
{
IsoNode node;
/* Want to get content of loaded boot catalog.
Vreixo took care not to make it an IsoFile at load time.
So this is implemented independently of IsoStream.
*/
uint32_t lba;
off_t size;
char *content;
};
/* Not more than 32 so that all entries fit into 2048 bytes */
#define Libisofs_max_boot_imageS 32
struct el_torito_boot_catalog {
IsoBoot *node; /* node of the catalog */
struct el_torito_boot_image *image; /* default boot image */
int num_bootimages;
struct el_torito_boot_image *bootimages[Libisofs_max_boot_imageS];
/* [0]= default boot image */
/* Weight value for image sorting */
int sort_weight;
};
struct el_torito_boot_image {
IsoFile *image;
/* Path of image at the time of ISO image loading (NULL = hidden image) */
char *image_path;
/* Overrides .image if >= 0 : array index of appended partition */
int appended_idx;
uint32_t appended_start; /* In blocks of 2048 bytes */
uint32_t appended_size; /* In blocks of 512 bytes */
unsigned int bootable:1; /**< If the entry is bootable. */
/**
* Whether the boot image seems to contain a boot_info_table
*/
unsigned int seems_boot_info_table:1;
unsigned int seems_grub2_boot_info:1;
/**
* Whether the boot image seems to be capable of isohybrid
*/
unsigned int seems_isohybrid_capable:1;
/**
* isolinux options
* bit 0 -> whether to patch image
* bit 1 -> whether to create isolinux 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 char type; /**< The type of image */
unsigned int isolinux_options;
unsigned char type; /**< The type of image :
0=no emulation , 1=fd 1.2 MB , 2=fd 1.4 MB
3=fd 3.8 MB , 4=hdd (size in partition table)
*/
unsigned char partition_type; /**< type of partition for HD-emul images */
short load_seg; /**< Load segment for the initial boot image. */
short load_size; /**< Number of sectors to load. */
uint32_t emul_hdd_size; /* 512-bytes LBA after highest partition end from
HD-emul partition table
*/
uint16_t load_seg; /**< Load segment for the initial boot image. */
uint16_t load_size; /**< Number of sectors to load. */
int load_size_full; /* 1= override load_size by image size */
/* Byte 1 of Validation Entry or Section Header Entry:
0= 80x86, 1= PowerPC, 2= Mac, 0xef= EFI */
uint8_t platform_id;
uint8_t id_string[28];
uint8_t selection_crit[20];
};
/** El-Torito, 2.1 */
@ -75,8 +132,8 @@ struct el_torito_default_entry {
struct el_torito_section_header {
uint8_t header_indicator BP(1, 1);
uint8_t platform_id BP(2, 2);
uint8_t number BP(3, 4);
uint8_t character BP(5, 32);
uint8_t num_entries BP(3, 4);
uint8_t id_string BP(5, 32);
};
/** El-Torito, 2.4 */
@ -106,4 +163,32 @@ int el_torito_catalog_file_src_create(Ecma119Image *target, IsoFileSrc **src);
*/
int eltorito_writer_create(Ecma119Image *target);
/**
* Insert boot info table content into buf.
*
* @return
* 1 on success, 0 error (but continue), < 0 error
*/
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
/* Maximum size of a boot image which is marked by
el_torito_set_isolinux_options() for patching (boot info table,
GRUB2 boot info, maybe others).
*/
#define Libisofs_elto_max_patchablE (32 * 1024 * 1024)
#endif /* LIBISO_ELTORITO_H */

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* 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
@ -7,6 +8,11 @@
* See COPYING file for details.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include "libisofs.h"
#include "filesrc.h"
#include "node.h"
#include "util.h"
@ -14,15 +20,29 @@
#include "messages.h"
#include "image.h"
#include "stream.h"
#ifdef Libisofs_with_checksumS
#include "md5.h"
#endif /* Libisofs_with_checksumS */
#include <stdlib.h>
#include <string.h>
#include <limits.h>
/* <<< */
#include <stdio.h>
#ifdef Xorriso_standalonE
#ifdef Xorriso_with_libjtE
#include "../libjte/libjte.h"
#endif
#else
#ifdef Libisofs_with_libjtE
#include <libjte/libjte.h>
#endif
#endif /* ! Xorriso_standalonE */
#ifndef PATH_MAX
#define PATH_MAX Libisofs_default_path_maX
@ -48,16 +68,13 @@ 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;
ino_t ino_id;
#ifdef Libisofs_with_checksumS
int cret, no_md5= 0;
void *xipt = NULL;
#endif
if (img == NULL || file == NULL || src == NULL) {
return ISO_NULL_POINTER;
@ -71,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.
*/
@ -95,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;
@ -103,29 +127,22 @@ 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) {
#ifdef Libisofs_with_checksumS
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);
if (cret < 0)
ret = cret;
}
#endif /* Libisofs_with_checksumS */
free(fsrc->sections);
free(fsrc);
return ret;
}
iso_stream_ref(fsrc->stream);
#ifdef Libisofs_with_checksumS
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)
@ -136,21 +153,20 @@ 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)
return cret;
}
#endif /* Libisofs_with_checksumS */
return ISO_SUCCESS;
}
@ -202,46 +218,83 @@ static int cmp_by_weight(const void *f1, const void *f2)
{
IsoFileSrc *f = *((IsoFileSrc**)f1);
IsoFileSrc *g = *((IsoFileSrc**)f2);
int cmp;
/* higher weighted first */
return g->sort_weight - f->sort_weight;
cmp = g->sort_weight - f->sort_weight;
if (cmp)
return cmp;
/* Make the result of qsort(3) stable by avoiding return value 0 as good
as possible. If not f == g, then their ->taken values are supposed
to differ.
*/
if(f->taken == g->taken)
return 0;
return f->taken < g->taken ? -1 : 1;
}
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 shall_be_written_if_not_taken(void *arg)
{
size_t i, size;
IsoFileSrc *f = (IsoFileSrc *)arg;
return f->no_write || f->taken ? 0 : 1;
}
int filesrc_writer_pre_compute(IsoImageWriter *writer)
{
size_t i, size, is_external;
Ecma119Image *t;
IsoFileSrc **filelist;
int (*inc_item)(void *);
size_t omitted_count;
IsoFileSrc **iso_ecma119_to_filesrc_array(Ecma119Image *t,
int (*include_item)(void *),
size_t *size);
if (writer == NULL) {
return ISO_ASSERT_FAILURE;
}
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->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;
}
/* store the filesrcs in a array */
filelist = (IsoFileSrc**)iso_rbtree_to_array(t->files, inc_item, &size);
filelist = (IsoFileSrc**) iso_ecma119_to_filesrc_array(t, inc_item, &size);
omitted_count = iso_rbtree_count_array(t->files, (size_t) 0,
shall_be_written_if_not_taken);
if (omitted_count > 0) {
iso_msg_submit(t->image->id, ISO_NOT_REPRODUCIBLE, 0,
"Cannot arrange content of data files in surely reproducible way");
LIBISO_FREE_MEM(filelist);
filelist = (IsoFileSrc**)iso_rbtree_to_array(
t->files, inc_item, &size);
}
if (filelist == NULL) {
return ISO_OUT_OF_MEM;
}
/* sort files by weight, if needed */
if (t->sort_files) {
if (t->opts->sort_files) {
qsort(filelist, size, sizeof(void*), cmp_by_weight);
}
@ -249,10 +302,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;
@ -261,10 +322,30 @@ int filesrc_writer_compute_data_blocks(IsoImageWriter *writer)
/*
* final section
*/
file->sections[extent].block = t->curblock + extent * (ISO_EXTENT_SIZE / BLOCK_SIZE);
if (section_size <= 0) {
/* 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->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 */
@ -272,6 +353,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)
{
@ -304,139 +425,189 @@ int filesrc_read(IsoFileSrc *file, char *buf, size_t count)
return iso_stream_read_buffer(file->stream, buf, count, &got);
}
#ifdef Libisofs_with_checksumS
/* @return 1=ok, md5 is valid,
0= not ok, go on,
<0 fatal error, abort
*/
static
int filesrc_make_md5(Ecma119Image *t, IsoFileSrc *file, char md5[16], int flag)
{
return iso_stream_make_md5(file->stream, md5, 0);
}
#endif /* Libisofs_with_checksumS */
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;
IsoFileSrc *file;
IsoFileSrc **filelist;
char name[PATH_MAX];
char buffer[BLOCK_SIZE];
char *name_data = NULL;
char *buffer_data = NULL;
size_t b;
off_t file_size;
uint32_t nblocks;
#ifdef Libisofs_with_checksumS
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 (writer == NULL) {
return ISO_ASSERT_FAILURE;
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;
}
t = writer->target;
filelist = writer->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);
iso_msg_debug(t->image->id, "Writing Files...");
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);
#ifdef Libisofs_with_checksumS
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);
}
#endif /* Libisofs_with_checksumS */
res = filesrc_open(file);
iso_stream_get_file_name(file->stream, name);
/* 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) {
/*
* 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);
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) {
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 */
/* 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);
}
else {
iso_msg_debug(t->image->id, "Writing file %s", name);
}
#endif
#ifdef Libisofs_with_checksumS
/* >>> 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) {
/* initialize file checksum */
res = iso_md5_start(&ctx);
/* 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;
}
}
#endif /* Libisofs_with_checksumS */
/* write file contents to image */
for (b = 0; b < nblocks; ++b) {
int wres;
res = filesrc_read(file, buffer, BLOCK_SIZE);
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) {
/* 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;
ret = res;
goto ex;
}
#ifdef Libisofs_with_checksumS
if (file->checksum_index > 0) {
/* Add to file checksum */
if (file_size - b * BLOCK_SIZE > BLOCK_SIZE)
@ -447,104 +618,109 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
if (res <= 0)
file->checksum_index = 0;
}
#endif /* Libisofs_with_checksumS */
}
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 (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) {
/* ko, writer error, we need to go out! */
ret = res;
ret = res; /* aborted due to error severity */
goto ex;
}
#ifdef Libisofs_with_checksumS
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;
}
#endif /* Libisofs_with_checksumS */
}
}
#ifdef Libisofs_with_checksumS
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);
}
#endif /* Libisofs_with_checksumS */
/* Write md5 into checksum buffer at file->checksum_index */
memcpy(t->checksum_buffer + 16 * file->checksum_index, md5, 16);
}
ret = ISO_SUCCESS;
ex:;
#ifdef Libisofs_with_checksumS
if (ctx != NULL) /* avoid any memory leak */
iso_md5_end(&ctx, md5);
#endif
#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;
}
LIBISO_ALLOC_MEM(name, char, PATH_MAX);
LIBISO_ALLOC_MEM(buffer, char, BLOCK_SIZE);
t = writer->target;
filelist = writer->data;
iso_msg_debug(t->image->id, "Writing Files...");
/* Normally write a single zeroed block as block address target for all
files which have no block address:
symbolic links, device files, empty data files.
*/
if (! t->opts->old_empty) {
ret = iso_write(t, buffer, BLOCK_SIZE);
if (ret < 0)
goto ex;
}
i = 0;
while ((file = filelist[i++]) != NULL) {
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;
}
ret = iso_filesrc_write_data(t, file, name, buffer, 0);
if (ret < 0)
goto ex;
}
ret = ISO_SUCCESS;
ex:;
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
@ -13,20 +14,48 @@
#include "stream.h"
#include "ecma119.h"
#ifdef HAVE_STDINT_H
#include <stdint.h>
#else
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#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 */
#ifdef Libisofs_with_checksumS
/* 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;
#endif /* Libisofs_with_checksumS */
/* Is > 0 if the object was already put into the filelist array.
In this case, the value is the order in which it was inserted,
which can be used for stable sorting of the filelist array in
case of identical file weights.
*/
size_t taken;
/** 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 +122,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

@ -8,6 +8,10 @@
* See COPYING file for details.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include "libisofs.h"
#include "filter.h"
#include "node.h"

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009 Thomas Schmitt
* Copyright (c) 2009 - 2011 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
@ -13,9 +13,14 @@
*
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include "../libisofs.h"
#include "../filter.h"
#include "../fsource.h"
#include "../stream.h"
#include <sys/types.h>
#include <sys/time.h>
@ -36,7 +41,7 @@
* for classical pipe filtering.
*/
/* IMPORTANT: Any change must be reflected by extf_clone_stream() */
/*
* Individual runtime properties exist only as long as the stream is opened.
*/
@ -594,6 +599,36 @@ IsoStream *extf_get_input_stream(IsoStream *stream, int flag)
return data->orig;
}
static
int extf_clone_stream(IsoStream *old_stream, IsoStream **new_stream, int flag)
{
int ret;
IsoStream *new_input_stream, *stream;
ExternalFilterStreamData *stream_data, *old_stream_data;
if (flag)
return ISO_STREAM_NO_CLONE; /* unknown option required */
stream_data = calloc(1, sizeof(ExternalFilterStreamData));
if (stream_data == NULL)
return ISO_OUT_OF_MEM;
ret = iso_stream_clone_filter_common(old_stream, &stream,
&new_input_stream, 0);
if (ret < 0) {
free((char *) stream_data);
return ret;
}
old_stream_data = (ExternalFilterStreamData *) old_stream->data;
stream_data->id = ++extf_ino_id;
stream_data->orig = new_input_stream;
stream_data->cmd = old_stream_data->cmd;
stream_data->cmd->refcount++;
stream_data->size = old_stream_data->size;
stream_data->running = NULL;
stream->data = stream_data;
*new_stream = stream;
return ISO_SUCCESS;
}
static
int extf_cmp_ino(IsoStream *s1, IsoStream *s2);
@ -601,7 +636,7 @@ int extf_cmp_ino(IsoStream *s1, IsoStream *s2);
IsoStreamIface extf_stream_class = {
3,
4,
"extf",
extf_stream_open,
extf_stream_close,
@ -612,21 +647,49 @@ IsoStreamIface extf_stream_class = {
extf_stream_free,
extf_update_size,
extf_get_input_stream,
extf_cmp_ino
extf_cmp_ino,
extf_clone_stream
};
static
int extf_cmp_ino(IsoStream *s1, IsoStream *s2)
{
int i;
ExternalFilterStreamData *data1, *data2;
IsoExternalFilterCommand *cmd1, *cmd2;
/* This function may rely on being called by iso_stream_cmp_ino()
only with s1, s2 which both point to it as their .cmp_ino() function.
It would be a programming error to let any other than extf_stream_class
point to extf_cmp_ino(). This fallback endangers transitivity of
iso_stream_cmp_ino().
*/
if (s1->class != &extf_stream_class || s2->class != &extf_stream_class)
return iso_stream_cmp_ino(s1, s2, 1);
data1 = (ExternalFilterStreamData*) s1->data;
data2 = (ExternalFilterStreamData*) s2->data;
if (data1->cmd != data2->cmd)
return (data1->cmd < data2->cmd ? -1 : 1);
cmd1 = data1->cmd;
cmd2 = data2->cmd;
if (cmd1 != cmd2) {
if (strcmp(cmd1->name, cmd2->name) != 0)
return strcmp(cmd1->name, cmd2->name);
if (strcmp(cmd1->path, cmd2->path) != 0)
return strcmp(cmd1->path, cmd2->path);
if (cmd1->argc != cmd2->argc)
return cmd1->argc < cmd2->argc ? -1 : 1;
for (i = 0; i < cmd1->argc; i++) {
if (strcmp(cmd1->argv[i], cmd2->argv[i]) != 0)
return strcmp(cmd1->argv[i], cmd2->argv[i]);
}
if (cmd1->behavior != cmd2->behavior)
return cmd1->behavior < cmd2->behavior ? -1 : 1;
if (strcmp(cmd1->suffix, cmd2->suffix) != 0)
return strcmp(cmd1->suffix, cmd2->suffix);
}
/* Both streams apply the same treatment to their input streams */
return iso_stream_cmp_ino(data1->orig, data2->orig, 0);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009 Thomas Schmitt
* Copyright (c) 2009 - 2011 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
@ -17,10 +17,15 @@
*
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include "../libisofs.h"
#include "../filter.h"
#include "../fsource.h"
#include "../util.h"
#include "../stream.h"
#include <sys/types.h>
#include <sys/time.h>
@ -149,6 +154,7 @@ static int gzip_compression_level = 6;
/*
* The data payload of an individual Gzip Filter IsoStream
*/
/* IMPORTANT: Any change must be reflected by gzip_clone_stream() */
typedef struct
{
IsoStream *orig;
@ -388,7 +394,7 @@ int gzip_stream_convert(IsoStream *stream, void *buf, size_t desired, int flag)
if (cnv_ret == Z_STREAM_ERROR || cnv_ret == Z_BUF_ERROR) {
return (rng->error_ret = ISO_ZLIB_COMPR_ERR);
}
if (strm->avail_out < rng->out_buffer_size)
if ((int) strm->avail_out < rng->out_buffer_size)
break; /* output is available */
if (strm->avail_in == 0) /* all pending input consumed */
break;
@ -525,12 +531,54 @@ IsoStream *gzip_get_input_stream(IsoStream *stream, int flag)
}
static
int gzip_clone_stream(IsoStream *old_stream, IsoStream **new_stream, int flag)
{
#ifdef Libisofs_with_zliB
int ret;
IsoStream *new_input_stream, *stream;
GzipFilterStreamData *stream_data, *old_stream_data;
if (flag)
return ISO_STREAM_NO_CLONE; /* unknown option required */
stream_data = calloc(1, sizeof(GzipFilterStreamData));
if (stream_data == NULL)
return ISO_OUT_OF_MEM;
ret = iso_stream_clone_filter_common(old_stream, &stream,
&new_input_stream, 0);
if (ret < 0) {
free((char *) stream_data);
return ret;
}
old_stream_data = (GzipFilterStreamData *) old_stream->data;
stream_data->orig = new_input_stream;
stream_data->size = old_stream_data->size;
stream_data->running = NULL;
stream_data->id = ++gzip_ino_id;
stream->data = stream_data;
*new_stream = stream;
return ISO_SUCCESS;
#else /* Libisofs_with_zliB */
return ISO_STREAM_NO_CLONE;
#endif /* ! Libisofs_with_zliB */
}
static
int gzip_cmp_ino(IsoStream *s1, IsoStream *s2);
static
int gzip_uncompress_cmp_ino(IsoStream *s1, IsoStream *s2);
IsoStreamIface gzip_stream_compress_class = {
3,
4,
"gzip",
gzip_stream_open,
gzip_stream_close,
@ -541,12 +589,13 @@ IsoStreamIface gzip_stream_compress_class = {
gzip_stream_free,
gzip_update_size,
gzip_get_input_stream,
gzip_cmp_ino
gzip_cmp_ino,
gzip_clone_stream
};
IsoStreamIface gzip_stream_uncompress_class = {
3,
4,
"pizg",
gzip_stream_open,
gzip_stream_close,
@ -557,16 +606,44 @@ IsoStreamIface gzip_stream_uncompress_class = {
gzip_stream_free,
gzip_update_size,
gzip_get_input_stream,
gzip_cmp_ino
gzip_uncompress_cmp_ino,
gzip_clone_stream
};
static
int gzip_cmp_ino(IsoStream *s1, IsoStream *s2)
{
/* This function may rely on being called by iso_stream_cmp_ino()
only with s1, s2 which both point to it as their .cmp_ino() function.
It would be a programming error to let any other than
gzip_stream_compress_class point to gzip_cmp_ino().
This fallback endangers transitivity of iso_stream_cmp_ino().
*/
if (s1->class != s2->class || (s1->class != &gzip_stream_compress_class &&
s2->class != &gzip_stream_compress_class))
return iso_stream_cmp_ino(s1, s2, 1);
/* Both streams apply the same treatment to their input streams */
return iso_stream_cmp_ino(iso_stream_get_input_stream(s1, 0),
iso_stream_get_input_stream(s2, 0), 0);
}
static
int gzip_uncompress_cmp_ino(IsoStream *s1, IsoStream *s2)
{
/* This function may rely on being called by iso_stream_cmp_ino()
only with s1, s2 which both point to it as their .cmp_ino() function.
It would be a programming error to let any other than
gzip_stream_uncompress_class point to gzip_uncompress_cmp_ino().
*/
if (s1->class != s2->class ||
(s1->class != &gzip_stream_uncompress_class &&
s2->class != &gzip_stream_uncompress_class))
return iso_stream_cmp_ino(s1, s2, 1);
/* Both streams apply the same treatment to their input streams */
return iso_stream_cmp_ino(iso_stream_get_input_stream(s1, 0),
iso_stream_get_input_stream(s2, 0), 0);
}

View File

@ -1,188 +0,0 @@
/*
* Copyright (c) 2008 Vreixo Formoso
*
* 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.
*/
#include "../libisofs.h"
#include "../filter.h"
#include "../fsource.h"
/*
* A simple Filter implementation for example purposes. It encrypts a file
* by XORing each byte by a given key.
*/
static ino_t xor_ino_id = 0;
typedef struct
{
IsoStream *orig;
uint8_t key;
ino_t id;
} XorEncryptStreamData;
static
int xor_encrypt_stream_open(IsoStream *stream)
{
XorEncryptStreamData *data;
if (stream == NULL) {
return ISO_NULL_POINTER;
}
data = (XorEncryptStreamData*)stream->data;
return iso_stream_open(data->orig);
}
static
int xor_encrypt_stream_close(IsoStream *stream)
{
XorEncryptStreamData *data;
if (stream == NULL) {
return ISO_NULL_POINTER;
}
data = stream->data;
return iso_stream_close(data->orig);
}
static
off_t xor_encrypt_stream_get_size(IsoStream *stream)
{
XorEncryptStreamData *data;
if (stream == NULL) {
return ISO_NULL_POINTER;
}
data = stream->data;
return iso_stream_get_size(data->orig);
}
static
int xor_encrypt_stream_read(IsoStream *stream, void *buf, size_t count)
{
int ret, len;
XorEncryptStreamData *data;
uint8_t *buffer = buf;
if (stream == NULL) {
return ISO_NULL_POINTER;
}
data = stream->data;
ret = iso_stream_read(data->orig, buf, count);
if (ret < 0) {
return ret;
}
/* xor */
for (len = 0; len < ret; ++len) {
buffer[len] = buffer[len] ^ data->key;
}
return ret;
}
static
int xor_encrypt_stream_is_repeatable(IsoStream *stream)
{
/* the filter can't be created if underlying stream is not repeatable */
return 1;
}
static
void xor_encrypt_stream_get_id(IsoStream *stream, unsigned int *fs_id,
dev_t *dev_id, ino_t *ino_id)
{
XorEncryptStreamData *data = stream->data;
*fs_id = ISO_FILTER_FS_ID;
*dev_id = XOR_ENCRYPT_DEV_ID;
*ino_id = data->id;
}
static
void xor_encrypt_stream_free(IsoStream *stream)
{
XorEncryptStreamData *data = stream->data;
iso_stream_unref(data->orig);
free(data);
}
IsoStreamIface xor_encrypt_stream_class = {
0,
"xorf",
xor_encrypt_stream_open,
xor_encrypt_stream_close,
xor_encrypt_stream_get_size,
xor_encrypt_stream_read,
xor_encrypt_stream_is_repeatable,
xor_encrypt_stream_get_id,
xor_encrypt_stream_free
};
static
void xor_encrypt_filter_free(FilterContext *filter)
{
free(filter->data);
}
static
int xor_encrypt_filter_get_filter(FilterContext *filter, IsoStream *original,
IsoStream **filtered)
{
IsoStream *str;
XorEncryptStreamData *data;
if (filter == NULL || original == NULL || filtered == NULL) {
return ISO_NULL_POINTER;
}
str = malloc(sizeof(IsoStream));
if (str == NULL) {
return ISO_OUT_OF_MEM;
}
data = malloc(sizeof(XorEncryptStreamData));
if (str == NULL) {
free(str);
return ISO_OUT_OF_MEM;
}
/* fill data */
data->key = *((uint8_t*)filter->data);
data->id = xor_ino_id++;
/* get reference to the source */
data->orig = original;
iso_stream_ref(original);
str->refcount = 1;
str->data = data;
str->class = &xor_encrypt_stream_class;
*filtered = str;
return ISO_SUCCESS;
}
int create_xor_encrypt_filter(uint8_t key, FilterContext **filter)
{
FilterContext *f;
uint8_t *data;
f = calloc(1, sizeof(FilterContext));
if (f == NULL) {
return ISO_OUT_OF_MEM;
}
data = malloc(sizeof(uint8_t));
if (data == NULL) {
free(f);
return ISO_OUT_OF_MEM;
}
f->refcount = 1;
f->version = 0;
*data = key;
f->data = data;
f->free = xor_encrypt_filter_free;
f->get_filter = xor_encrypt_filter_get_filter;
return ISO_SUCCESS;
}

File diff suppressed because it is too large Load Diff

View File

@ -7,6 +7,10 @@
* See COPYING file for details.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include "libisofs.h"
#include "node.h"
@ -61,7 +65,7 @@ int get_next(struct find_iter_data *iter, IsoNode **n)
iter->itersec = NULL;
}
if (ret != 0) {
/* succes or error */
/* success or error */
return ret;
}
}
@ -137,11 +141,12 @@ void update_next(IsoDirIter *iter)
static
int find_iter_next(IsoDirIter *iter, IsoNode **node)
{
struct find_iter_data *data = iter->data;
struct find_iter_data *data;
if (iter == NULL || node == NULL) {
return ISO_NULL_POINTER;
}
data = iter->data;
if (data->err < 0) {
return data->err;

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 - 2024 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
@ -12,6 +12,10 @@
* Filesystem/FileSource implementation to access the local filesystem.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include "fsource.h"
#include "util.h"
#include "aaip_0_2.h"
@ -26,6 +30,11 @@
#include <libgen.h>
#include <string.h>
/* O_BINARY is needed for Cygwin but undefined elsewhere */
#ifndef O_BINARY
#define O_BINARY 0
#endif
static
int iso_file_source_new_lfs(IsoFileSource *parent, const char *name,
IsoFileSource **src);
@ -35,13 +44,13 @@ int iso_file_source_new_lfs(IsoFileSource *parent, const char *name,
*/
IsoFilesystem *lfs= NULL;
/* IMPORTANT: Any change must be reflected by lfs_clone_src() */
typedef struct
{
/** reference to the parent (if root it points to itself) */
IsoFileSource *parent;
char *name;
unsigned int openned :2; /* 0: not openned, 1: file, 2:dir */
unsigned int openned :2; /* 0: not opened, 1: file, 2:dir */
union
{
int fd;
@ -58,9 +67,19 @@ char* lfs_get_path(IsoFileSource *src)
if (data->parent == src) {
return strdup("/");
} else {
char *path = lfs_get_path(data->parent);
int pathlen = strlen(path);
path = realloc(path, pathlen + strlen(data->name) + 2);
char *path, *new_path;
int pathlen;
path = lfs_get_path(data->parent);
if (path == NULL)
return NULL;
pathlen = strlen(path);
new_path = realloc(path, pathlen + strlen(data->name) + 2);
if (new_path == NULL) {
free(path);
return NULL;
}
path= new_path;
if (pathlen != 1) {
/* pathlen can only be 1 for root */
path[pathlen] = '/';
@ -81,14 +100,14 @@ char* lfs_get_name(IsoFileSource *src)
static
int lfs_lstat(IsoFileSource *src, struct stat *info)
{
_LocalFsFileSource *data;
char *path;
if (src == NULL || info == NULL) {
return ISO_NULL_POINTER;
}
data = src->data;
path = lfs_get_path(src);
if (path == NULL)
return ISO_OUT_OF_MEM;
if (lstat(path, info) != 0) {
int err;
@ -114,6 +133,7 @@ int lfs_lstat(IsoFileSource *src, struct stat *info)
err = ISO_FILE_ERROR;
break;
}
free(path);
return err;
}
free(path);
@ -123,14 +143,14 @@ int lfs_lstat(IsoFileSource *src, struct stat *info)
static
int lfs_stat(IsoFileSource *src, struct stat *info)
{
_LocalFsFileSource *data;
char *path;
if (src == NULL || info == NULL) {
return ISO_NULL_POINTER;
}
data = src->data;
path = lfs_get_path(src);
if (path == NULL)
return ISO_OUT_OF_MEM;
if (stat(path, info) != 0) {
int err;
@ -156,6 +176,7 @@ int lfs_stat(IsoFileSource *src, struct stat *info)
err = ISO_FILE_ERROR;
break;
}
free(path);
return err;
}
free(path);
@ -166,13 +187,11 @@ static
int lfs_access(IsoFileSource *src)
{
int ret;
_LocalFsFileSource *data;
char *path;
if (src == NULL) {
return ISO_NULL_POINTER;
}
data = src->data;
path = lfs_get_path(src);
ret = iso_eaccess(path);
@ -208,7 +227,7 @@ int lfs_open(IsoFileSource *src)
data->info.dir = opendir(path);
data->openned = data->info.dir ? 2 : 0;
} else {
data->info.fd = open(path, O_RDONLY);
data->info.fd = open(path, O_RDONLY | O_BINARY);
data->openned = data->info.fd != -1 ? 1 : 0;
}
free(path);
@ -268,6 +287,9 @@ static
int lfs_read(IsoFileSource *src, void *buf, size_t count)
{
_LocalFsFileSource *data;
size_t to_read, done = 0;
int ret;
uint8_t *buf8;
if (src == NULL || buf == NULL) {
return ISO_NULL_POINTER;
@ -279,28 +301,28 @@ int lfs_read(IsoFileSource *src, void *buf, size_t count)
data = src->data;
switch (data->openned) {
case 1: /* not dir */
{
int ret;
ret = read(data->info.fd, buf, count);
buf8 = (uint8_t *) buf; /* for pointer arithmetic */
for (to_read = count; to_read > 0; to_read = count - done) {
if (to_read > 1024 * 1024)
to_read = 1024 * 1024;
ret = read(data->info.fd, buf8 + done, to_read);
if (ret < 0) {
/* error on read */
switch (errno) {
case EINTR:
ret = ISO_INTERRUPTED;
break;
return ISO_INTERRUPTED;
case EFAULT:
ret = ISO_OUT_OF_MEM;
break;
return ISO_OUT_OF_MEM;
case EIO:
ret = ISO_FILE_READ_ERROR;
break;
default:
ret = ISO_FILE_ERROR;
break;
return ISO_FILE_READ_ERROR;
}
return ISO_FILE_ERROR;
}
return ret;
if (ret == 0) /* EOF */
break;
done += ret;
}
return done;
case 2: /* directory */
return ISO_FILE_IS_DIR;
default:
@ -315,7 +337,7 @@ off_t lfs_lseek(IsoFileSource *src, off_t offset, int flag)
int whence;
if (src == NULL) {
return (off_t)ISO_NULL_POINTER;
return (off_t)((int) ISO_NULL_POINTER);
}
switch (flag) {
case 0:
@ -325,7 +347,7 @@ off_t lfs_lseek(IsoFileSource *src, off_t offset, int flag)
case 2:
whence = SEEK_END; break;
default:
return (off_t)ISO_WRONG_ARG_VALUE;
return (off_t)((int) ISO_WRONG_ARG_VALUE);
}
data = src->data;
@ -338,19 +360,19 @@ off_t lfs_lseek(IsoFileSource *src, off_t offset, int flag)
/* error on read */
switch (errno) {
case ESPIPE:
ret = (off_t)ISO_FILE_ERROR;
ret = (off_t)((int) ISO_FILE_ERROR);
break;
default:
ret = (off_t)ISO_ERROR;
ret = (off_t)((int) ISO_ERROR);
break;
}
}
return ret;
}
case 2: /* directory */
return (off_t)ISO_FILE_IS_DIR;
return (off_t)((int) ISO_FILE_IS_DIR);
default:
return (off_t)ISO_FILE_NOT_OPENED;
return (off_t)((int) ISO_FILE_NOT_OPENED);
}
}
@ -398,8 +420,7 @@ int lfs_readdir(IsoFileSource *src, IsoFileSource **child)
static
int lfs_readlink(IsoFileSource *src, char *buf, size_t bufsiz)
{
int size;
_LocalFsFileSource *data;
int size, ret;
char *path;
if (src == NULL || buf == NULL) {
@ -410,14 +431,13 @@ int lfs_readlink(IsoFileSource *src, char *buf, size_t bufsiz)
return ISO_WRONG_ARG_VALUE;
}
data = src->data;
path = lfs_get_path(src);
/*
* invoke readlink, with bufsiz -1 to reserve an space for
* the NULL character
*/
size = readlink(path, buf, bufsiz - 1);
size = readlink(path, buf, bufsiz);
free(path);
if (size < 0) {
/* error */
@ -441,8 +461,13 @@ int lfs_readlink(IsoFileSource *src, char *buf, size_t bufsiz)
}
/* NULL-terminate the buf */
ret = ISO_SUCCESS;
if ((size_t) size >= bufsiz) {
ret = ISO_RR_PATH_TOO_LONG;
size = bufsiz - 1;
}
buf[size] = '\0';
return ISO_SUCCESS;
return ret;
}
static
@ -458,7 +483,7 @@ void lfs_free(IsoFileSource *src)
data = src->data;
/* close the file if it is already openned */
/* close the file if it is already opened */
if (data->openned) {
src->class->close(src);
}
@ -474,56 +499,114 @@ void lfs_free(IsoFileSource *src)
static
int lfs_get_aa_string(IsoFileSource *src, unsigned char **aa_string, int flag)
{
int ret;
size_t num_attrs = 0, *value_lengths = NULL, result_len, sret;
int ret, no_non_user_perm= 0;
size_t num_attrs = 0, *value_lengths = NULL, result_len;
ssize_t sret;
char *path = NULL, **names = NULL, **values = NULL;
unsigned char *result = NULL;
_LocalFsFileSource *data;
data = src->data;
*aa_string = NULL;
if ((flag & 3 ) == 3) {
if ((flag & (2 | 4 | 16 | 64) ) == (2 | 4)) {
/* Neither ACL nor xattr shall be read, lfa_flags are not wanted */
ret = 1;
goto ex;
}
/* Obtain EAs and ACLs ("access" and "default"). ACLs encoded according
to AAIP ACL representation. Clean out st_mode ACL entries.
Obtain Linux style attribute flags and XFS-style project id.
*/
path = iso_file_source_get_path(src);
ret = aaip_get_attr_list(path, &num_attrs, &names,
&value_lengths, &values,
(!(flag & 2)) | 2 | (flag & 4) | 16);
if (ret <= 0) {
ret = ISO_FILE_ERROR;
if (path == NULL) {
ret = ISO_NULL_POINTER;
goto ex;
}
ret = aaip_get_attr_list(path, &num_attrs, &names,
&value_lengths, &values,
(!(flag & 2)) | 2 | (flag & 4) | (flag & 8) | 16 |
((!(flag & 16)) << 6) | ((!!(flag & 32)) << 7) |
((!(flag & 64)) << 8));
if (ret <= 0) {
if (ret == -2)
ret = ISO_AAIP_NO_GET_LOCAL;
else
ret = ISO_FILE_ERROR;
goto ex;
}
if(ret == 2)
no_non_user_perm= 1;
if (num_attrs == 0)
result = NULL;
else {
sret = aaip_encode(num_attrs, names,
value_lengths, values, &result_len, &result, 0);
if (sret == 0) {
ret = ISO_OUT_OF_MEM;
if (sret < 0) {
ret = sret;
goto ex;
}
}
}
*aa_string = result;
ret = 1;
ret = 1 + no_non_user_perm;
ex:;
if (path != NULL)
free(path);
if (names != NULL || value_lengths != NULL || values != NULL)
aaip_get_attr_list(path, &num_attrs, &names, &value_lengths, &values,
aaip_get_attr_list(NULL, &num_attrs, &names, &value_lengths, &values,
1 << 15); /* free memory */
return ret;
}
static
int lfs_clone_src(IsoFileSource *old_source,
IsoFileSource **new_source, int flag)
{
IsoFileSource *src = NULL;
char *new_name = NULL;
_LocalFsFileSource *old_data, *new_data = NULL;
if (flag)
return ISO_STREAM_NO_CLONE; /* unknown option required */
old_data = (_LocalFsFileSource *) old_source->data;
*new_source = NULL;
src = calloc(1, sizeof(IsoFileSource));
if (src == NULL)
goto no_mem;
new_name = strdup(old_data->name);
if (new_name == NULL)
goto no_mem;
new_data = calloc(1, sizeof(_LocalFsFileSource));
if (new_data == NULL)
goto no_mem;
new_data->openned = 0;
new_data->info.fd = -1; /* the value does not matter with (openned == 0) */
new_data->name = new_name;
new_data->parent = old_data->parent;
src->class = old_source->class;
src->refcount = 1;
src->data = new_data;
*new_source = src;
iso_file_source_ref(new_data->parent);
iso_filesystem_ref(lfs);
return ISO_SUCCESS;
no_mem:;
if (src != NULL)
free((char *) src);
if (new_data != NULL)
free((char *) new_data);
if (new_name != NULL)
free(new_name);
return ISO_OUT_OF_MEM;
}
IsoFileSourceIface lfs_class = {
1, /* version */
2, /* version */
lfs_get_path,
lfs_get_name,
lfs_lstat,
@ -537,7 +620,8 @@ IsoFileSourceIface lfs_class = {
lfs_get_filesystem,
lfs_free,
lfs_lseek,
lfs_get_aa_string
lfs_get_aa_string,
lfs_clone_src
};
@ -735,7 +819,7 @@ int iso_local_filesystem_new(IsoFilesystem **fs)
}
/* fill struct */
strncpy(lfs->type, "file", 4);
memcpy(lfs->type, "file", 4);
lfs->refcount = 1;
lfs->version = 0;
lfs->data = NULL; /* we don't need private data */
@ -751,6 +835,15 @@ int iso_local_filesystem_new(IsoFilesystem **fs)
}
int iso_local_attr_support(int flag)
{
int ret;
ret= aaip_local_attr_support(flag & 255);
return ret;
}
int iso_local_get_acl_text(char *disk_path, char **text, int flag)
{
int ret;
@ -774,13 +867,42 @@ int iso_local_set_acl_text(char *disk_path, char *text, int flag)
int iso_local_get_attrs(char *disk_path, size_t *num_attrs, char ***names,
size_t **value_lengths, char ***values, int flag)
{
int ret;
int ret, lfa, prj;
lfa = (flag & 64) ^ 64;
prj = (flag & (1 << 8)) ^ (1 << 8);
ret = aaip_get_attr_list(disk_path,
num_attrs, names, value_lengths, values,
(flag & (1 | 4 | 8 | 32 | (1 << 15))) | 2 | 16);
(flag & (1 | 4 | 8 | 32 | 256 | (1 << 15))) |
2 | 16 | lfa | prj);
if (ret <= 0)
return ISO_AAIP_NO_GET_LOCAL;
return 1 + (ret == 2);
}
int iso_local_set_attrs_errno(char *disk_path, size_t num_attrs, char **names,
size_t *value_lengths, char **values,
int *errnos, int flag)
{
int ret;
ret = aaip_set_attr_list(disk_path, num_attrs, names, value_lengths,
values, errnos,
(flag & (8 | 32 | 64 | 128)) | !(flag & 1));
if (ret <= 0) {
if (ret == -1)
return ISO_OUT_OF_MEM;
if (ret == -2)
return ISO_AAIP_BAD_AASTRING;
if (ret >= -5)
return ISO_AAIP_NO_SET_LOCAL;
if (ret == -6 || ret == -7)
return ISO_AAIP_NOT_ENABLED;
if (ret == -8)
return ISO_AAIP_BAD_ATTR_NAME;
return ret;
}
return 1;
}
@ -789,17 +911,18 @@ int iso_local_set_attrs(char *disk_path, size_t num_attrs, char **names,
size_t *value_lengths, char **values, int flag)
{
int ret;
int *errnos = NULL;
ret = aaip_set_attr_list(disk_path, num_attrs, names, value_lengths,
values, (flag & (8 | 32)) | !(flag & 1));
if (ret <= 0) {
if (ret == -1)
return ISO_OUT_OF_MEM;
if (ret == -2)
return ISO_AAIP_BAD_AASTRING;
return ISO_AAIP_NO_SET_LOCAL;
if(num_attrs > 0) {
errnos= calloc(num_attrs, sizeof(int));
if(errnos == NULL)
return ISO_OUT_OF_MEM;
}
return 1;
ret= iso_local_set_attrs_errno(disk_path, num_attrs, names, value_lengths,
values, errnos, flag);
if(errnos != NULL)
free(errnos);
return ret;
}
@ -824,3 +947,181 @@ int iso_local_get_perms_wo_acl(char *disk_path, mode_t *st_mode, int flag)
return 1;
}
/*
* @param flag
* Bitfield for control purposes
* bit2= do not issue own error messages with operating system errors
* bit5= in case of symbolic link: inquire link target
* bit7= Ignore non-settable Linux-like file attribute flags
* @return
* 1= ok, lfa_flags is valid
* 2= ok, but some local flags could not be mapped to the FS_*_FL bits
* 3= ok, symbolic link encountered, flag bit5 not set, lfa_flags set to 0
* 4= ok, file did not bear attribute flags. E.g. because not S_IFDIR or
* S_IFREG, or because unsuitable filesystem.
* lfa_flags is set to 0
* <0= error with system calls
*/
int iso_local_get_lfa_flags(char *disk_path, uint64_t *lfa_flags, int *max_bit,
int *os_errno, int flag)
{
int ret;
struct stat stbuf;
*lfa_flags = 0;
*max_bit = -1;
*os_errno = 0;
if (flag & 32)
ret = stat(disk_path, &stbuf);
else
ret = lstat(disk_path, &stbuf);
if (ret == -1) {
*os_errno = errno;
return ISO_FILE_DOESNT_EXIST;
}
if ((stbuf.st_mode & S_IFMT) == S_IFLNK && !(flag & 32))
return 3;
ret = aaip_get_lfa_flags(disk_path, lfa_flags, max_bit, os_errno,
flag & (4 | (1 << 7)));
if(ret == 0)
return ISO_LFA_NOT_ENABLED;
if(ret == -1)
return ISO_LFA_NO_OPEN_LOCAL;
if(ret < 0)
return ISO_LFA_NO_GET_LOCAL;
return ret;
}
/*
* @param flag Bitfield for control purposes
* bit0= do not try to change known superuser flags
* bit1= change only known chattr settable flags
* bit2= do not issue own error messages with operating system errors
* bit5= in case of symbolic link: operate on link target
* @return
* 1 = ok, all lfa_flags bits were written
* 2 = ok, but some FS_*_FL bits could not be mapped to local flags
* 3 = ok, symbolic link encountered, flag bit5 not set, nothing done
* <0 = error
*/
int iso_local_set_lfa_flags(char *disk_path, uint64_t lfa_flags, int max_bit,
uint64_t change_mask, int *os_errno, int flag)
{
int ret, old_max_bit;
struct stat stbuf;
uint64_t eff_flags;
*os_errno = 0;
if (flag & 32)
ret = stat(disk_path, &stbuf);
else
ret = lstat(disk_path, &stbuf);
if (ret == -1) {
*os_errno = errno;
return ISO_FILE_DOESNT_EXIST;
}
if ((stbuf.st_mode & S_IFMT) == S_IFLNK && !(flag & 32))
return 3;
change_mask= iso_util_get_effective_lfa_mask(change_mask, flag & 3);
if (change_mask == 0) {
return 1;
} else if (change_mask == ~((uint64_t) 0)) {
eff_flags = lfa_flags;
} else {
ret = aaip_get_lfa_flags(disk_path, &eff_flags, &old_max_bit, os_errno,
flag & 4);
if (ret == 0)
return ISO_LFA_NOT_ENABLED;
if (ret == -1)
return ISO_LFA_NO_OPEN_LOCAL;
if (ret < 0)
return ISO_LFA_NO_GET_LOCAL;
eff_flags &= ~change_mask;
eff_flags |= (lfa_flags & change_mask);
}
ret= aaip_set_lfa_flags(disk_path, eff_flags, max_bit, os_errno, flag & 4);
if(ret == 0)
return ISO_LFA_NOT_ENABLED;
if (ret == -1)
return ISO_LFA_NO_OPEN_LOCAL;
if(ret < 0)
return ISO_LFA_NO_SET_LOCAL;
return ret;
}
/*
* @param flag
* Bitfield for control purposes
* bit2= do not issue own error messages with operating system errors
* bit5= in case of symbolic link: inquire link target
* @return
* 1= ok, projid is valid
* 3 = ok, symbolic link encountered, flag bit5 not set, projid set to 0
* <0= error with system calls
*/
int iso_local_get_projid(char *disk_path, uint32_t *projid, int *os_errno,
int flag)
{
int ret;
struct stat stbuf;
*projid = 0;
*os_errno = 0;
if (flag & 32)
ret = stat(disk_path, &stbuf);
else
ret = lstat(disk_path, &stbuf);
if (ret == -1) {
*os_errno = errno;
return ISO_FILE_DOESNT_EXIST;
}
ret = aaip_get_projid(disk_path, projid, os_errno, flag & 4);
if(ret == 0)
return ISO_PROJID_NOT_ENABLED;
if(ret == -1)
return ISO_PROJID_NO_OPEN_LOCAL;
if(ret < 0)
return ISO_PROJID_NO_SET_LOCAL;
return ret;
}
/*
* @param flag Bitfield for control purposes
* bit2= do not issue own error messages with operating system errors
* bit5= in case of symbolic link: manipulate link target
* @return
* 1 = ok, projid was written
* 3 = ok, symbolic link encountered, flag bit5 not set, nothing done
* <0 = error
*/
int iso_local_set_projid(char *disk_path, uint32_t projid, int *os_errno,
int flag)
{
int ret;
struct stat stbuf;
*os_errno = 0;
if (flag & 32)
ret = stat(disk_path, &stbuf);
else
ret = lstat(disk_path, &stbuf);
if (ret == -1) {
*os_errno = errno;
return ISO_FILE_DOESNT_EXIST;
}
if ((stbuf.st_mode & S_IFMT) == S_IFLNK && !(flag & 32))
return 3;
ret = aaip_set_projid(disk_path, projid, os_errno, flag & 4);
if(ret == 0)
return ISO_PROJID_NOT_ENABLED;
if (ret == -1)
return ISO_PROJID_NO_OPEN_LOCAL;
if(ret < 0)
return ISO_PROJID_NO_SET_LOCAL;
return ret;
}

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2022 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
@ -7,6 +8,10 @@
* See COPYING file for details.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include "fsource.h"
#include <stdlib.h>
@ -129,3 +134,104 @@ int iso_file_source_get_aa_string(IsoFileSource *src,
return src->class->get_aa_string(src, aa_string, flag);
}
/* @flag bit0= Open and close src
bit1= Try iso_file_source_lseek(, 0) (=SEEK_SET) with wanted_size
@return <0 iso_file_source_lseek failed , >= 0 readable capacity
*/
off_t iso_file_source_lseek_capacity(IsoFileSource *src, off_t wanted_size,
int flag)
{
int ret, opened = 0;
off_t end, old, reset;
struct stat info;
ret = iso_file_source_stat(src, &info);
if (ret < 0) {
end = -1;
goto ex;
}
if (S_ISDIR(info.st_mode) || S_ISLNK(info.st_mode) ||
S_ISFIFO(info.st_mode) || S_ISSOCK(info.st_mode)) {
/* open(2) on fifo can block and have side effects.
Active Unix sockets have not been tested but they make as few sense
as directories or symbolic links.
*/
end = -1;
goto ex;
}
if (flag & 1) {
ret = iso_file_source_open(src);
if (ret < 0) {
end = -1;
goto ex;
}
opened = 1;
}
old = iso_file_source_lseek(src, 0, 1);
if (old < 0) {
end = -1;
goto ex;
}
if(flag & 2) {
end = iso_file_source_lseek(src, wanted_size, 0);
} else {
end = iso_file_source_lseek(src, 0, 2);
}
if (end < 0) {
end = -1;
goto ex;
}
reset = iso_file_source_lseek(src, old, 0);
if (reset != old) {
end = -1;
goto ex;
}
ex:;
if (opened) {
iso_file_source_close(src);
}
return end;
}
/* Determine whether src is random-access readable and return its capacity.
@flag bit0= For iso_file_source_lseek_capacity(): Open and close src
bit1= wanted_size is valid
*/
off_t iso_file_source_determine_capacity(IsoFileSource *src, off_t wanted_size,
int flag)
{
int ret;
off_t src_size, src_seek_size= -1;
struct stat info;
ret = iso_file_source_stat(src, &info);
if (ret < 0) {
return (off_t) -1;
}
if (S_ISREG(info.st_mode)) {
return info.st_size;
}
src_size = iso_file_source_lseek_capacity(src, wanted_size, (flag & 1));
if (src_size > 0) {
return src_size;
}
if (!(flag & 2)) {
if (src_size == 0) {
return 0;
}
return -1;
}
src_seek_size= src_size;
src_size = iso_file_source_lseek_capacity(src, wanted_size,
2 | (flag & 1));
if (src_size >= 0) {
return src_size;
} else if (src_seek_size >= 0) {
return src_seek_size;
}
return -1;
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 Thomas Schmitt
* Copyright (c) 2009 - 2022 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -28,14 +28,35 @@
* Create a new IsoFilesystem to deal with local filesystem.
*
* @return
* 1 sucess, < 0 error
* 1 success, < 0 error
*/
int iso_local_filesystem_new(IsoFilesystem **fs);
/* Rank two IsoFileSource by their eventual old image LBAs.
Other IsoFileSource classes will be ranked only roughly.
/* Rank two IsoFileSource of ifs_class by their eventual old image LBAs.
* @param cmp_ret will return the reply value -1, 0, or 1.
* @return 1= *cmp_ret is a valid reply
* 0= not both streams are of ifs_class,
* *cmp_ret is only a rough estimation.
*/
int iso_ifs_sections_cmp(IsoFileSource *s1, IsoFileSource *s2, int flag);
int iso_ifs_sections_cmp(IsoFileSource *s1, IsoFileSource *s2, int *cmp_ret,
int flag);
/* Create an independent copy of an ifs_class IsoFileSource.
*/
int iso_ifs_source_clone(IsoFileSource *old_source, IsoFileSource **new_source,
int flag);
off_t iso_file_source_lseek_capacity(IsoFileSource *src, off_t wanted_size,
int flag);
/* Determine whether src is random-access readable and return its capacity.
*/
off_t iso_file_source_determine_capacity(IsoFileSource *src, off_t wanted_size,
int flag);
#endif /*LIBISO_FSOURCE_H_*/

1877
libisofs/hfsplus.c Normal file

File diff suppressed because it is too large Load Diff

202
libisofs/hfsplus.h Normal file
View File

@ -0,0 +1,202 @@
/*
* 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);
void iso_setup_hfsplus_block_size(Ecma119Image *target);
#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;
}

464
libisofs/hfsplus_classes.c Normal file
View File

@ -0,0 +1,464 @@
/*
*
* 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,
0x00,
/* End of list */
0x00
};
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 * sizeof(uint16_t));
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 - 2024 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
@ -8,16 +8,126 @@
* See COPYING file for details.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include "libisofs.h"
#include "image.h"
#include "node.h"
#include "messages.h"
#include "eltorito.h"
#include "system_area.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
int iso_imported_sa_new(struct iso_imported_sys_area **boots, int flag)
{
struct iso_imported_sys_area *b;
*boots = NULL;
b = calloc(1, sizeof(struct iso_imported_sys_area));
if (b == NULL)
return ISO_OUT_OF_MEM;
b->mbr_req = NULL;
b->apm_req = NULL;
b->gpt_req = NULL;
b->gpt_backup_comments = NULL;
b->mips_boot_file_paths = NULL;
b->mips_vd_entries = NULL;
b->sparc_disc_label = NULL;
b->sparc_core_node = NULL;
b->sparc_core_node_path = NULL;
b->sparc_entries = NULL;
b->hppa_cmdline = NULL;
b->hppa_bootloader = NULL;
b->hppa_kernel_32 = NULL;
b->hppa_kernel_64 = NULL;
b->hppa_ramdisk = NULL;
b->alpha_boot_image = NULL;
*boots = b;
return 1;
}
int iso_imported_sa_unref(struct iso_imported_sys_area **boots, int flag)
{
int i;
struct iso_imported_sys_area *b;
b = *boots;
if (b == NULL)
return 2;
if (b->refcount > 0)
b->refcount--;
if (b->refcount > 0)
return 2;
if (b->mbr_req != NULL) {
for (i = 0; i < b->mbr_req_count; i++) {
if (b->mbr_req[i] != NULL)
LIBISO_FREE_MEM(b->mbr_req[i]->image_path);
LIBISO_FREE_MEM(b->mbr_req[i]);
}
LIBISO_FREE_MEM(b->mbr_req);
}
if (b->apm_req != NULL) {
for (i = 0; i < b->apm_req_count; i++) {
if (b->apm_req[i] != NULL)
LIBISO_FREE_MEM(b->apm_req[i]->image_path);
LIBISO_FREE_MEM(b->apm_req[i]);
}
LIBISO_FREE_MEM(b->apm_req);
}
if (b->gpt_req != NULL) {
for (i = 0; i < b->gpt_req_count; i++) {
if (b->gpt_req[i] != NULL)
LIBISO_FREE_MEM(b->gpt_req[i]->image_path);
LIBISO_FREE_MEM(b->gpt_req[i]);
}
LIBISO_FREE_MEM(b->gpt_req);
}
LIBISO_FREE_MEM(b->gpt_backup_comments);
if (b->mips_boot_file_paths != NULL) {
for (i = 0; i < b->num_mips_boot_files; i++)
LIBISO_FREE_MEM(b->mips_boot_file_paths[i]);
LIBISO_FREE_MEM(b->mips_boot_file_paths);
}
if (b->mips_vd_entries != NULL) {
for (i = 0; i < b->num_mips_boot_files; i++)
LIBISO_FREE_MEM(b->mips_vd_entries[i]);
LIBISO_FREE_MEM(b->mips_vd_entries);
}
LIBISO_FREE_MEM(b->mipsel_boot_file_path);
LIBISO_FREE_MEM(b->sparc_disc_label);
if (b->sparc_core_node != NULL)
iso_node_unref((IsoNode *) b->sparc_core_node);
LIBISO_FREE_MEM(b->sparc_core_node_path);
LIBISO_FREE_MEM(b->sparc_entries);
LIBISO_FREE_MEM(b->hppa_cmdline);
LIBISO_FREE_MEM(b->hppa_bootloader);
LIBISO_FREE_MEM(b->hppa_kernel_32);
LIBISO_FREE_MEM(b->hppa_kernel_64);
LIBISO_FREE_MEM(b->hppa_ramdisk);
LIBISO_FREE_MEM(b->alpha_boot_image);
LIBISO_FREE_MEM(b);
*boots = NULL;
return 1;
}
/**
* Create a new image, empty.
*
@ -28,11 +138,11 @@
* @param image
* Location where the image pointer will be stored.
* @return
* 1 sucess, < 0 error
* 1 success, < 0 error
*/
int iso_image_new(const char *name, IsoImage **image)
{
int res;
int res, i;
IsoImage *img;
if (image == NULL) {
@ -74,18 +184,45 @@ int iso_image_new(const char *name, IsoImage **image)
img->volset_id = strdup(name);
img->volume_id = strdup(name);
}
memset(img->application_use, 0, 512);
img->system_area_data = NULL;
img->system_area_options = 0;
img->num_mips_boot_files = 0;
for (i = 0; i < 15; i++)
img->mips_boot_file_paths[i] = NULL;
img->sparc_core_node = NULL;
img->hppa_cmdline= NULL;
img->hppa_bootloader = NULL;
img->hppa_kernel_32 = NULL;
img->hppa_kernel_64 = NULL;
img->hppa_ramdisk = NULL;
img->alpha_boot_image = NULL;
img->import_src = NULL;
img->builder_ignore_acl = 1;
img->builder_ignore_ea = 1;
img->builder_ignore_lfa_flags = 1;
img->builder_ignore_ro_lfa_flags = 0;
img->builder_ignore_projid = 1;
img->truncate_mode = 1;
img->truncate_length = LIBISOFS_NODE_NAME_MAX;
img->truncate_buffer[0] = 0;
img->inode_counter = 0;
img->used_inodes = NULL;
img->used_inodes_start = 0;
#ifdef Libisofs_with_checksumS
img->checksum_start_lba = 0;
img->checksum_end_lba = 0;
img->checksum_idx_count = 0;
img->checksum_array = NULL;
#endif
img->generator_is_running = 0;
for (i = 0; i < ISO_HFSPLUS_BLESS_MAX; i++)
img->hfsplus_blessed[i] = NULL;
img->collision_warnings = 0;
img->imported_sa_info = NULL;
img->blind_on_local_get_attrs = 0;
img->do_deeper_tree_inspection = 0;
img->tree_loaded = 0;
img->rr_loaded = 0;
img->tree_compliance = NULL;
*image = img;
return ISO_SUCCESS;
@ -100,30 +237,40 @@ void iso_image_ref(IsoImage *image)
}
/**
* Decrements the reference couting of the given image.
* Decrements the reference counting of the given image.
* If it reaches 0, the image is free, together with its tree nodes (whether
* their refcount reach 0 too, of course).
*/
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);
iso_image_set_hppa_palo(image, NULL, NULL, NULL, NULL, NULL, 1);
if (image->alpha_boot_image != NULL)
free(image->alpha_boot_image);
if (image->import_src != NULL)
iso_data_source_unref(image->import_src);
free(image->volset_id);
free(image->volume_id);
free(image->publisher_id);
@ -133,9 +280,18 @@ 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)
free(image->system_area_data);
iso_image_free_checksums(image, 0);
iso_imported_sa_unref(&(image->imported_sa_info), 0);
if (image->tree_compliance != NULL)
iso_write_opts_free(image->tree_compliance);
free(image);
}
}
@ -143,17 +299,12 @@ void iso_image_unref(IsoImage *image)
int iso_image_free_checksums(IsoImage *image, int flag)
{
#ifdef Libisofs_with_checksumS
image->checksum_start_lba = 0;
image->checksum_end_lba = 0;
image->checksum_idx_count = 0;
if (image->checksum_array != NULL)
free(image->checksum_array);
image->checksum_array = NULL;
#endif /* Libisofs_with_checksumS */
return 1;
}
@ -173,13 +324,13 @@ int iso_image_free_checksums(IsoImage *image, int flag)
*/
int iso_image_attach_data(IsoImage *image, void *data, void (*give_up)(void*))
{
if (image == NULL || (data != NULL && free == NULL)) {
if (image == NULL) {
return ISO_NULL_POINTER;
}
if (image->user_data != NULL) {
/* free previously attached data */
if (image->user_data_free) {
if (image->user_data_free != NULL) {
image->user_data_free(image->user_data);
}
image->user_data = NULL;
@ -326,30 +477,142 @@ 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;
}
int iso_image_get_system_area(IsoImage *img, char system_area_data[32768],
int *options, int flag)
{
*options = img->system_area_options;
if (img->system_area_data == NULL)
return 0;
memcpy(system_area_data, img->system_area_data, 32768);
return 1;
}
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;
@ -369,6 +632,21 @@ void iso_image_set_ignore_aclea(IsoImage *image, int what)
{
image->builder_ignore_acl = (what & 1);
image->builder_ignore_ea = !!(what & 2);
image->builder_ignore_lfa_flags = !(what & 4);
image->builder_take_all_ea = !!(what & 8);
image->builder_ignore_ro_lfa_flags = !!(what & 32);
image->builder_ignore_projid = !!(what & 64);
}
int iso_image_get_ignore_aclea(IsoImage *image)
{
return image->builder_ignore_acl |
(image->builder_ignore_ea << 1) |
((!image->builder_ignore_lfa_flags) << 2) |
(image->builder_take_all_ea << 3) |
(image->builder_ignore_ro_lfa_flags << 5) |
((!image->builder_ignore_projid) << 6);
}
@ -445,7 +723,8 @@ ex:;
/**
* A global counter for inode numbers for the ISO image filesystem.
* A global counter for Rock Ridge inode numbers in the ISO image filesystem.
*
* On image import it gets maxed by the eventual inode numbers from PX
* entries. Up to the first 32 bit rollover it simply increments the counter.
* After the first rollover it uses a look ahead bitmap which gets filled
@ -455,13 +734,13 @@ ex:;
* @param image The image where the number shall be used
* @param flag bit0= reset count (Caution: image must get new inos then)
* @return
* Since ino_t 0 is used as default and considered self-unique,
* Since 0 is used as default and considered self-unique,
* the value 0 should only be returned in case of error.
*/
ino_t img_give_ino_number(IsoImage *image, int flag)
uint32_t img_give_ino_number(IsoImage *image, int flag)
{
int ret;
ino_t new_ino, ino_idx;
uint64_t new_ino, ino_idx;
static uint64_t limit = 0xffffffff;
if (flag & 1) {
@ -471,10 +750,10 @@ ino_t img_give_ino_number(IsoImage *image, int flag)
image->used_inodes = NULL;
image->used_inodes_start = 0;
}
new_ino = image->inode_counter + 1;
new_ino = ((uint64_t) image->inode_counter) + 1;
if (image->used_inodes == NULL) {
if (new_ino > 0 && new_ino <= limit) {
image->inode_counter = new_ino;
image->inode_counter = (uint32_t) new_ino;
return image->inode_counter;
}
}
@ -580,39 +859,381 @@ ex:;
int iso_image_get_session_md5(IsoImage *image, uint32_t *start_lba,
uint32_t *end_lba, char md5[16], int flag)
{
#ifdef Libisofs_with_checksumS
if (image->checksum_array == NULL || image->checksum_idx_count < 1)
return 0;
*start_lba = image->checksum_start_lba;
*end_lba = image->checksum_end_lba;
memcpy(md5, image->checksum_array, 16);
return ISO_SUCCESS;
#else
return 0;
#endif /* ! Libisofs_with_checksumS */
}
int iso_image_set_checksums(IsoImage *image, char *checksum_array,
uint32_t start_lba, uint32_t end_lba,
uint32_t idx_count, int flag)
{
#ifdef Libisofs_with_checksumS
iso_image_free_checksums(image, 0);
image->checksum_array = checksum_array;
image->checksum_start_lba = start_lba;
image->checksum_end_lba = end_lba;
image->checksum_idx_count = idx_count;
#endif /* Libisofs_with_checksumS */
return 1;
}
int iso_image_generator_is_running(IsoImage *image)
{
return image->generator_is_running;
}
/* API */
int iso_image_add_mips_boot_file(IsoImage *image, char *path, int flag)
{
if (image->num_mips_boot_files >= 15)
return ISO_BOOT_TOO_MANY_MIPS;
image->mips_boot_file_paths[image->num_mips_boot_files] = strdup(path);
if (image->mips_boot_file_paths[image->num_mips_boot_files] == NULL)
return ISO_OUT_OF_MEM;
image->num_mips_boot_files++;
return ISO_SUCCESS;
}
/* API */
int iso_image_get_mips_boot_files(IsoImage *image, char *paths[15], int flag)
{
int i;
for (i = 0; i < image->num_mips_boot_files; i++)
paths[i] = image->mips_boot_file_paths[i];
for (; i < 15; i++)
paths[i] = NULL;
return image->num_mips_boot_files;
}
/* API */
int iso_image_give_up_mips_boot(IsoImage *image, int flag)
{
int i;
for (i = 0; i < image->num_mips_boot_files; i++)
if (image->mips_boot_file_paths[i] != NULL) {
free(image->mips_boot_file_paths[i]);
image->mips_boot_file_paths[i] = NULL;
}
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,
char *what, int flag)
{
int ret, err;
IsoNode *node;
IsoFile *file;
if (path == NULL && !(flag & 1))
return ISO_SUCCESS;
if (iso_clone_mgtd_mem(path, target, 0) < 0)
return ISO_OUT_OF_MEM;
if (path == NULL)
return ISO_SUCCESS;
ret = iso_tree_path_to_node(img, path, &node);
if (ret < 0)
return ret;
if (ret == 0) {
iso_msg_submit(img->id, ISO_BOOT_FILE_MISSING, 0,
"Cannot find in ISO image: %s file '%s'", what, path);
return ISO_BOOT_FILE_MISSING;
}
if (iso_node_get_type(node) != LIBISO_FILE) {
err = ISO_HPPA_PALO_NOTREG;
if (strncmp(what, "DEC Alpha", 9) == 0)
err = ISO_ALPHA_BOOT_NOTREG;
iso_msg_submit(img->id, err, 0,
"%s file is not a data file: '%s'", what, path);
return err;
}
file = (IsoFile *) node;
if (!(file->explicit_weight || file->from_old_session))
file->sort_weight = 2;
return ISO_SUCCESS;
}
/* API */
/* @param flag
Bitfield for control purposes
bit0= Let NULL parameters free the corresponding image properties.
Else only the non-NULL parameters of this call have an effect.
*/
int iso_image_set_hppa_palo(IsoImage *img, char *cmdline, char *bootloader,
char *kernel_32, char *kernel_64, char *ramdisk,
int flag)
{
int ret;
static char *what = "HP-PA PALO";
if (cmdline != NULL || (flag & 1))
if (iso_clone_mgtd_mem(cmdline, &(img->hppa_cmdline), 0) < 0)
return ISO_OUT_OF_MEM;
ret = hppa_palo_set_path(img, bootloader, &(img->hppa_bootloader), what,
flag & 1);
if (ret < 0)
return ret;
ret = hppa_palo_set_path(img, kernel_32, &(img->hppa_kernel_32), what,
flag & 1);
if (ret < 0)
return ret;
ret = hppa_palo_set_path(img, kernel_64, &(img->hppa_kernel_64), what,
flag & 1);
if (ret < 0)
return ret;
ret = hppa_palo_set_path(img, ramdisk, &(img->hppa_ramdisk), what,
flag & 1);
if (ret < 0)
return ret;
return ISO_SUCCESS;
}
/* API */
int iso_image_get_hppa_palo(IsoImage *img, char **cmdline, char **bootloader,
char **kernel_32, char **kernel_64, char **ramdisk)
{
*cmdline = img->hppa_cmdline;
*bootloader = img->hppa_bootloader;
*kernel_32 = img->hppa_kernel_32;
*kernel_64 = img->hppa_kernel_64;
*ramdisk = img->hppa_ramdisk;
return ISO_SUCCESS;
}
/* API */
int iso_image_set_alpha_boot(IsoImage *img, char *boot_loader_path, int flag)
{
int ret;
ret = hppa_palo_set_path(img, boot_loader_path, &(img->alpha_boot_image),
"DEC Alpha Bootloader", 1);
if (ret < 0)
return ret;
return ISO_SUCCESS;
}
/* API */
int iso_image_get_alpha_boot(IsoImage *img, char **boot_loader_path)
{
*boot_loader_path = img->alpha_boot_image;
return ISO_SUCCESS;
}
/* API */
int iso_image_set_truncate_mode(IsoImage *img, int mode, int length)
{
if (mode < 0 || mode > 1)
return ISO_WRONG_ARG_VALUE;
if (length < 64 || length > LIBISOFS_NODE_NAME_MAX)
return ISO_WRONG_ARG_VALUE;
img->truncate_mode = mode;
img->truncate_length = length;
return ISO_SUCCESS;
}
/* API */
int iso_image_get_truncate_mode(IsoImage *img, int *mode, int *length)
{
*mode = img->truncate_mode;
*length = img->truncate_length;
return ISO_SUCCESS;
}
/* Warning: Not thread-safe */
int iso_image_truncate_name(IsoImage *image, const char *name, char **namept,
int flag)
{
int ret;
if (name == NULL)
return ISO_NULL_POINTER;
if ((int) strlen(name) <= image->truncate_length) {
*namept = (char *) name;
return ISO_SUCCESS;
}
*namept = image->truncate_buffer;
if (name != image->truncate_buffer)
strncpy(image->truncate_buffer, name, 4095);
image->truncate_buffer[4095] = 0;
ret = iso_truncate_rr_name(image->truncate_mode, image->truncate_length,
image->truncate_buffer, 0);
return ret;
}
/* API */
int iso_image_was_blind_attrs(IsoImage *image, int flag)
{
int ret;
if (image == NULL)
return ISO_NULL_POINTER;
ret = image->blind_on_local_get_attrs;
if (flag & 1)
image->blind_on_local_get_attrs = 0;
return ret;
}
/*
* @param flag bit0= recursion is active
*/
static
int iso_dir_zisofs_discard_bpt(IsoDir *dir, int flag)
{
int ret;
IsoDirIter *iter = NULL;
IsoNode *node;
IsoDir *subdir;
IsoFile *file;
IsoStream *stream;
ret = iso_dir_get_children(dir, &iter);
if (ret < 0)
return ret;
while (iso_dir_iter_next(iter, &node) == 1) {
if (iso_node_get_type(node) == LIBISO_DIR) {
subdir = (IsoDir *) node;
ret = iso_dir_zisofs_discard_bpt(subdir, flag | 1);
if (ret < 0)
goto ex;
continue;
}
if (iso_node_get_type(node) != LIBISO_FILE)
continue;
file = (IsoFile *) node;
stream = iso_file_get_stream(file);
if (stream == NULL)
continue;
ret = iso_stream_zisofs_discard_bpt(stream, 0);
if (ret < 0)
goto ex;
}
ret = ISO_SUCCESS;
ex:;
if (iter != NULL)
iso_dir_iter_free(iter);
return ret;
}
/* API */
int iso_image_zisofs_discard_bpt(IsoImage *image, int flag)
{
int ret;
IsoDir *dir;
if (image == NULL)
return ISO_NULL_POINTER;
dir = image->root;
if (dir == NULL)
return ISO_SUCCESS;
ret = iso_dir_zisofs_discard_bpt(dir, 0);
return ret;
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 Thomas Schmitt
* Copyright (c) 2009 - 2024 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,13 +22,16 @@
*/
#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.
* Global objects such as the message_queues must belogn to that
* context. Thus we will have, for example, a msg queue per image,
* so images are completelly independent and can be managed together.
* (Usefull, for example, in Multiple-Document-Interface GUI apps.
* so images are completely independent and can be managed together.
* (Useful, for example, in Multiple-Document-Interface GUI apps.
* [The stuff we have in init belongs really to image!]
*/
@ -49,10 +52,47 @@ 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;
/* Eventually loaded system area data, or NULL */
char *system_area_data;
/* Prescribed/detected options, see iso_write_opts_set_system_area() */
/* >>> Needs to be coordinated with .imported_sa_info->system_area_options
*/
int system_area_options;
/*
* Up to 15 boot files can be referred by a MIPS Big Endian Volume Header.
The mips_boot_file_paths are ISO 9660 Rock Ridge paths.
*/
int num_mips_boot_files;
char *mips_boot_file_paths[15]; /* ISO 9660 Rock Ridge Paths */
/* A data file of which the position and size shall be written after
a SUN Disk Label.
*/
IsoFile *sparc_core_node;
/*
* Parameters for HP-PA PALO boot sector. cmdline is a string. The other
* four are absolute paths to data files in the ISO image.
*/
char *hppa_cmdline;
char *hppa_bootloader;
char *hppa_kernel_32;
char *hppa_kernel_64;
char *hppa_ramdisk;
/* Absolute DEC Alpha boot image path in the ISO image */
char *alpha_boot_image;
/* image identifier, for message origin identifier */
int id;
@ -61,6 +101,11 @@ struct Iso_Image
*/
IsoFilesystem *fs;
/**
* Block storage of imported ISO if demanded by IsoReadOpts.
*/
IsoDataSource *import_src;
/*
* Default builder to use when adding files to the image tree.
*/
@ -100,6 +145,33 @@ struct Iso_Image
*/
unsigned int builder_ignore_ea : 1;
/**
* If not builder_ignore_ea : import all xattr namespaces from local
* filesystem, not only "user.
*/
unsigned int builder_take_all_ea : 1;
/**
* Whether to ignore Linux style file attribute flags (chattr).
* Not in effect with loading a complete ISO image but only with image
* manipulation.
*/
unsigned int builder_ignore_lfa_flags : 1;
/**
* Whether to ignore Linux style file attribute flags (chattr) which are
* only readable but non-settable ("ZEIheVN").
* Not in effect with loading a complete ISO image but only with image
* manipulation.
*/
unsigned int builder_ignore_ro_lfa_flags : 1;
/* Whether to ignore XFS-style project id.
* Not in effect with loading a complete ISO image but only with image
* manipulation.
*/
unsigned int builder_ignore_projid : 1;
/**
* Files to exclude. Wildcard support is included.
*/
@ -115,6 +187,20 @@ struct Iso_Image
/* TODO
enum iso_replace_mode (*confirm_replace)(IsoFileSource *src, IsoNode *node);
*/
/**
* What to do in case of name longer than truncate_length:
* 0= throw FAILURE
* 1= truncate to truncate_length with MD5 of whole name at end
*/
int truncate_mode;
int truncate_length;
/**
* This is a convenience buffer for name truncation during image
* manipulation where libisofs is not thread-safe anyway.
*/
char truncate_buffer[4096];
/**
* When this is not NULL, it is a pointer to a function that will
@ -136,20 +222,20 @@ struct Iso_Image
* Inode number management. inode_counter is taken over from
* IsoImageFilesystem._ImageFsData after image import.
* It is to be used with img_give_ino_number()
*/
ino_t inode_counter;
* This is a Rock Ridge file serial number. Thus 32 bit.
*/
uint32_t inode_counter;
/*
* A bitmap of used inode numbers in an interval beginning at
* used_inodes_start and holding ISO_USED_INODE_RANGE bits.
* If a bit is set, then the corresponding inode number is occupied.
* This interval is kept around inode_counter and eventually gets
* advanced by ISO_USED_INODE_RANGE numbers in a tree traversal
* done by img_collect_inos().
* done by img_collect_inos(). The value will stay in the 32 bit range,
* although used_inodes_start is 64 bit to better handle rollovers.
*/
uint8_t *used_inodes;
ino_t used_inodes_start;
#ifdef Libisofs_with_checksumS
uint64_t used_inodes_start;
/**
* Array of MD5 checksums as announced by xattr "isofs.ca" of the
@ -163,11 +249,48 @@ struct Iso_Image
uint32_t checksum_idx_count;
char *checksum_array;
#endif /* Libisofs_with_checksumS */
/**
* Whether a write run has been started by iso_image_create_burn_source()
* and has not yet been finished.
*/
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;
/* Contains the assessment of boot aspects of the loaded image */
struct iso_imported_sys_area *imported_sa_info;
/* Whether some local filesystem xattr namespace could not be explored
* during node building.
*/
int blind_on_local_get_attrs;
/* Deeper tree inspection when reading an IsoImage assesses traces of the
used write options.
*/
int do_deeper_tree_inspection;
int tree_loaded; /* 0=ISO 9660/ECMA-119 1=Joliet 2=ISO 9660:1999 */
int rr_loaded; /* 0=plain ISO 9660/ECMA-119 1=Rock Ridge */
IsoWriteOpts *tree_compliance;
};
/* Apply truncation mode to name, using image->truncate_buffer to perform
truncation if needed.
Warning: Not thread-safe !
*/
int iso_image_truncate_name(IsoImage *image, const char *name, char **namept,
int flag);
/* Collect the bitmap of used inode numbers in the range of
_ImageFsData.used_inodes_start + ISO_USED_INODE_RANGE
@ -186,10 +309,10 @@ int img_collect_inos(IsoImage *image, IsoDir *dir, int flag);
* @param image The image where the number shall be used
* @param flag bit0= reset count (Caution: image must get new inos then)
* @return
* Since ino_t 0 is used as default and considered self-unique,
* Since 0 is used as default and considered self-unique,
* the value 0 should only be returned in case of error.
*/
ino_t img_give_ino_number(IsoImage *image, int flag);
uint32_t img_give_ino_number(IsoImage *image, int flag);
/* @param flag bit0= overwrite any ino, else only ino == 0
bit1= install inode with non-data, non-directory files
@ -212,4 +335,151 @@ 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);
/* Collects boot block information obtained from the system area of
imported images
*/
struct iso_imported_sys_area {
int refcount;
/* Whether there was some System Area data at all */
int is_not_zero;
/* Giving the error number if the assessment ended by an error */
int overall_return;
/* Block address of loaded Primar Volume Descriptor */
uint32_t pvd_block;
/* Size of the imported ISO image */
uint32_t image_size;
/* see libisofs.h : iso_write_opts_set_system_area() */
int system_area_options;
/* The perceived MBR partitions */
struct iso_mbr_partition_request **mbr_req;
int mbr_req_count;
/* see ecma119.h : struct ecma119_image , struct iso_write_opts */
/* Effective partition table parameter: 1 to 63, 0= disabled/default */
int partition_secs_per_head;
/* 1 to 255, 0= disabled/default */
int partition_heads_per_cyl;
/* see ecma119.h : struct iso_write_opts */
uint32_t partition_offset;
/* 2048-byte start LBA and block count of PreP partition */
uint32_t prep_part_start;
uint32_t prep_part_size;
/* see ecma119.h : struct ecma119_image */
struct iso_apm_partition_request **apm_req;
int apm_req_count;
int apm_req_flags;
/* Number of found "GapNN", "ISO9660_data" partitions in APM */
int apm_gap_count;
/* see ecma119.h : struct iso_write_opts */
int apm_block_size;
/* >>> see ecma119.h : struct iso_write_opts */
int hfsp_block_size;
/* see ecma119.h : struct ecma119_image */
struct iso_gpt_partition_request **gpt_req;
int gpt_req_count;
int gpt_req_flags;
/* see ecma119.h : struct ecma119_image */
uint8_t gpt_disk_guid[16];
/* Start of GPT entries in System Area, block size 512 */
uint64_t gpt_part_start;
uint32_t gpt_max_entries;
uint64_t gpt_first_lba;
uint64_t gpt_last_lba;
uint64_t gpt_backup_lba;
char *gpt_backup_comments;
uint32_t gpt_head_crc_found;
uint32_t gpt_head_crc_should;
uint32_t gpt_array_crc_found;
uint32_t gpt_array_crc_should;
/* see image.h : struct Iso_Image */
int num_mips_boot_files;
char **mips_boot_file_paths; /* ISO 9660 Rock Ridge Paths */
struct iso_mips_voldir_entry **mips_vd_entries;
/* see ecma119.h : struct ecma119_image */
/* Memorized ELF parameters from MIPS Little Endian boot file */
uint32_t mipsel_e_entry;
uint32_t mipsel_p_offset;
uint32_t mipsel_p_vaddr;
uint32_t mipsel_p_filesz;
uint32_t mipsel_seg_start;
char *mipsel_boot_file_path;
/* see image.h : struct Iso_Image */
char *sparc_disc_label;
int sparc_secs_per_head;
int sparc_heads_per_cyl;
struct iso_sun_disk_label_entry *sparc_entries;
int sparc_entry_count;
/* grub2-sparc-core : a node in the ISO image
published at bytes 0x228 to 0x233
*/
uint64_t sparc_grub2_core_adr;
uint32_t sparc_grub2_core_size;
IsoFile *sparc_core_node;
/* Only for representing the imported ISO:
Path of file which held the partition content.
NULL = no such file
*/
char *sparc_core_node_path;
/* see image.h : struct Iso_Image */
int hppa_hdrversion;
char *hppa_cmdline;
uint32_t hppa_kern32_adr;
uint32_t hppa_kern32_len;
uint32_t hppa_kern64_adr;
uint32_t hppa_kern64_len;
uint32_t hppa_ramdisk_adr;
uint32_t hppa_ramdisk_len;
uint32_t hppa_bootloader_adr;
uint32_t hppa_bootloader_len;
uint32_t hppa_ipl_entry;
char *hppa_kernel_32;
char *hppa_kernel_64;
char *hppa_ramdisk;
char *hppa_bootloader;
uint64_t alpha_boot_image_size;
uint64_t alpha_boot_image_adr;
char *alpha_boot_image;
/* Some block addresses of active and first session:
PVD, L Pathtable, Opt L, M Pathtable, Opt M, root directory
*/
uint32_t meta_struct_blocks[12];
int num_meta_struct_blocks;
};
int iso_imported_sa_new(struct iso_imported_sys_area **sa_info, int flag);
int iso_imported_sa_unref(struct iso_imported_sys_area **sa_info, int flag);
void iso_image_assess_ecma119_name(IsoImage *image, struct stat *info,
char *path, char *name);
void iso_image_assess_joliet_name(IsoImage *image, struct stat *info,
char *path, char *name);
#endif /*LIBISO_IMAGE_H_*/

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2011-2024 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
@ -7,12 +8,18 @@
* See COPYING file for details.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include "iso1999.h"
#include "messages.h"
#include "writer.h"
#include "image.h"
#include "filesrc.h"
#include "eltorito.h"
#include "util.h"
#include "ecma119.h"
#include <stdlib.h>
#include <stdio.h>
@ -52,7 +59,7 @@ int get_iso1999_name(Ecma119Image *t, const char *str, char **fname)
}
}
/* ISO 9660:1999 7.5.1 */
/* ISO 9660:1999 7.5.1 and ECMA-119 4th Edition 7.5.1 */
if (strlen(name) > 207) {
name[207] = '\0';
}
@ -69,11 +76,12 @@ void iso1999_node_free(Iso1999Node *node)
return;
}
if (node->type == ISO1999_DIR) {
int i;
size_t i;
for (i = 0; i < node->info.dir->nchildren; i++) {
iso1999_node_free(node->info.dir->children[i]);
}
free(node->info.dir->children);
if (node->info.dir->children != NULL)
free(node->info.dir->children);
free(node->info.dir);
}
iso_node_unref(node->node);
@ -82,7 +90,8 @@ void iso1999_node_free(Iso1999Node *node)
}
/**
* Create a low level ISO 9660:1999 node
* Create a low level node of the tree of Enhanced Volume Descriptor
* (aka ISO 9660:1999) as of ECMA-119 4th Edition.
* @return
* 1 success, 0 ignored, < 0 error
*/
@ -104,11 +113,14 @@ int create_node(Ecma119Image *t, IsoNode *iso, Iso1999Node **node)
free(n);
return ISO_OUT_OF_MEM;
}
n->info.dir->children = calloc(sizeof(void*), dir->nchildren);
if (n->info.dir->children == NULL) {
free(n->info.dir);
free(n);
return ISO_OUT_OF_MEM;
n->info.dir->children = NULL;
if (dir->nchildren > 0) {
n->info.dir->children = calloc(sizeof(void*), dir->nchildren);
if (n->info.dir->children == NULL) {
free(n->info.dir);
free(n);
return ISO_OUT_OF_MEM;
}
}
n->type = ISO1999_DIR;
} else if (iso->type == LIBISO_FILE) {
@ -118,7 +130,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 "
@ -161,7 +173,8 @@ int create_node(Ecma119Image *t, IsoNode *iso, Iso1999Node **node)
}
/**
* Create the low level ISO 9660:1999 tree from the high level ISO tree.
* Create the low level tree of an Enhanced Volume Descriptor
* (aka ISO 9660:1999) as of ECMA-119 4th Edition from the high level ISO tree.
*
* @return
* 1 success, 0 file ignored, < 0 error
@ -187,7 +200,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, "
@ -240,14 +253,33 @@ int create_tree(Ecma119Image *t, IsoNode *iso, Iso1999Node **tree, int pathlen)
}
break;
case LIBISO_SYMLINK:
case LIBISO_SPECIAL:
{
t->iso1999_symlinks++;
if (t->iso1999_symlinks == 1) {
char *ipath = iso_tree_get_node_path(iso);
ret = iso_msg_submit(t->image->id, ISO_FILE_IGNORED, 0,
"Can't add %s to ISO 9660:1999 tree. This kind of files "
"can only be added to a Rock Ridget tree. Skipping.",
ipath);
"Cannot add symbolic link %s to ISO 9660:1999 tree. Skipping.",
ipath);
free(ipath);
} else {
if (t->iso1999_symlinks == 2)
iso_msg_submit(t->image->id, ISO_FILE_IGNORED, 0,
"More symbolic links were omitted from ISO 9660:1999 tree.");
ret = 0;
}
break;
case LIBISO_SPECIAL:
t->iso1999_specials++;
if (t->iso1999_specials == 1) {
char *ipath = iso_tree_get_node_path(iso);
ret = iso_msg_submit(t->image->id, ISO_FILE_IGNORED, 0,
"Cannot add special file %s to ISO 9660:1999 tree. Skipping.",
ipath);
free(ipath);
} else {
if (t->iso1999_specials == 2)
iso_msg_submit(t->image->id, ISO_FILE_IGNORED, 0,
"More special files were omitted from ISO 9660:1999 tree.");
ret = 0;
}
break;
default:
@ -270,22 +302,24 @@ cmp_node(const void *f1, const void *f2)
Iso1999Node *g = *((Iso1999Node**)f2);
/**
* TODO #00027 Follow ISO 9660:1999 specs when sorting files
* strcmp do not does exactly what ISO 9660:1999, 9.3, as characters
* < 0x20 " " are allowed, so name len must be taken into accout
* TODO #00027 Follow ECMA-119 4th Edition specs when sorting files
* strcmp do not does exactly what paragraph 9.3 prescribe, as characters
* < 0x20 " " are allowed, so name len must be taken into account
*/
return strcmp(f->name, g->name);
}
/**
* Sort the entries inside an ISO 9660:1999 directory, according to
* ISO 9660:1999, 9.3
* ISO 9660:1999 / ECMA-119 4th Edition, 9.3
*/
static
void sort_tree(Iso1999Node *root)
{
size_t i;
if (root->info.dir->children == NULL)
return;
qsort(root->info.dir->children, root->info.dir->nchildren,
sizeof(void*), cmp_node);
for (i = 0; i < root->info.dir->nchildren; i++) {
@ -301,29 +335,35 @@ int mangle_single_dir(Ecma119Image *img, Iso1999Node *dir)
int ret;
int i, nchildren;
Iso1999Node **children;
IsoHTable *table;
IsoHTable *table = NULL;
int need_sort = 0;
char *full_name = NULL, *tmp = NULL;
nchildren = dir->info.dir->nchildren;
if (nchildren <= 0) {
ret = ISO_SUCCESS;
goto ex;
}
children = dir->info.dir->children;
LIBISO_ALLOC_MEM(full_name, char, 208);
LIBISO_ALLOC_MEM(tmp, char, 208);
/* a hash table will temporary hold the names, for fast searching */
ret = iso_htable_create((nchildren * 100) / 80, iso_str_hash,
(compare_function_t)strcmp, &table);
if (ret < 0) {
return ret;
goto ex;
}
for (i = 0; i < nchildren; ++i) {
char *name = children[i]->name;
ret = iso_htable_add(table, name, name);
if (ret < 0) {
goto mangle_cleanup;
goto ex;
}
}
for (i = 0; i < nchildren; ++i) {
char *name, *ext;
char full_name[208];
int max; /* computed max len for name, without extension */
int j = i;
int digits = 1; /* characters to change per name */
@ -339,7 +379,7 @@ int mangle_single_dir(Ecma119Image *img, Iso1999Node *dir)
}
/*
* A max of 7 characters is good enought, it allows handling up to
* A max of 7 characters is good enough, it allows handling up to
* 9,999,999 files with same name.
*/
while (digits < 8) {
@ -380,7 +420,7 @@ int mangle_single_dir(Ecma119Image *img, Iso1999Node *dir)
* This can't happen with current limit of digits.
*/
ret = ISO_ERROR;
goto mangle_cleanup;
goto ex;
}
}
/* ok, reduce name by digits */
@ -394,7 +434,7 @@ int mangle_single_dir(Ecma119Image *img, Iso1999Node *dir)
}
max = 207 - digits;
name = full_name;
if (max < strlen(name)) {
if ((size_t) max < strlen(name)) {
name[max] = '\0';
}
/* let ext be an empty string */
@ -404,7 +444,6 @@ int mangle_single_dir(Ecma119Image *img, Iso1999Node *dir)
ok = 1;
/* change name of each file */
for (k = i; k <= j; ++k) {
char tmp[208];
char fmt[16];
if (dot != NULL) {
sprintf(fmt, "%%s%%0%dd.%%s", digits);
@ -427,7 +466,7 @@ int mangle_single_dir(Ecma119Image *img, Iso1999Node *dir)
char *new = strdup(tmp);
if (new == NULL) {
ret = ISO_OUT_OF_MEM;
goto mangle_cleanup;
goto ex;
}
iso_msg_debug(img->image->id, "\"%s\" renamed to \"%s\"",
children[k]->name, new);
@ -455,7 +494,7 @@ int mangle_single_dir(Ecma119Image *img, Iso1999Node *dir)
}
if (digits == 8) {
ret = ISO_MANGLE_TOO_MUCH_FILES;
goto mangle_cleanup;
goto ex;
}
i = j;
}
@ -469,8 +508,10 @@ int mangle_single_dir(Ecma119Image *img, Iso1999Node *dir)
ret = ISO_SUCCESS;
mangle_cleanup : ;
ex:;
iso_htable_destroy(table, NULL);
LIBISO_FREE_MEM(tmp);
LIBISO_FREE_MEM(full_name);
return ret;
}
@ -546,7 +587,7 @@ size_t calc_dirent_len(Ecma119Image *t, Iso1999Node *n)
/**
* Computes the total size of all directory entries of a single dir, as
* stated in ISO 9660:1999, 6.8.1.3
* stated in ISO 9660:1999 / ECMA-119 4th Edition, 6.8.1.3
*/
static
size_t calc_dir_size(Ecma119Image *t, Iso1999Node *dir)
@ -577,7 +618,7 @@ size_t calc_dir_size(Ecma119Image *t, Iso1999Node *dir)
/*
* The size of a dir is always a multiple of block size, as we must add
* the size of the unused space after the last directory record
* (ISO 9660:1999, 6.8.1.3)
* (ISO 9660:1999 / ECMA-119 4th Edition, 6.8.1.3)
*/
len = ROUND_UP(len, BLOCK_SIZE);
@ -604,7 +645,8 @@ void calc_dir_pos(Ecma119Image *t, Iso1999Node *dir)
}
/**
* Compute the length of the path table (ISO 9660:1999, 6.9), in bytes.
* Compute the length of the path table (ISO 9660:1999 / ECMA-119 4th Edition,
* 6.9), in bytes.
*/
static
uint32_t calc_path_table_size(Iso1999Node *dir)
@ -660,7 +702,7 @@ int iso1999_writer_compute_data_blocks(IsoImageWriter *writer)
}
/**
* Write a single directory record (ISO 9660:1999, 9.1).
* Write a single directory record (ISO 9660:1999 / ECMA-119 4th Edition, 9.1).
*
* @param file_id
* if >= 0, we use it instead of the filename (for "." and ".." entries).
@ -679,8 +721,9 @@ void write_one_dir_record(Ecma119Image *t, Iso1999Node *node, int file_id,
: (uint8_t*)node->name;
struct ecma119_dir_record *rec = (struct ecma119_dir_record*)buf;
IsoNode *iso;
len_dr = 33 + len_fi + (len_fi % 2 ? 0 : 1);
len_dr = 33 + len_fi + ((len_fi % 2) ? 0 : 1);
memcpy(rec->file_id, name, len_fi);
@ -710,14 +753,23 @@ void write_one_dir_record(Ecma119Image *t, Iso1999Node *node, int file_id,
rec->len_dr[0] = len_dr;
iso_bb(rec->block, block, 4);
iso_bb(rec->length, len, 4);
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->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, 1, 2);
iso_bb(rec->vol_seq_number, (uint32_t) 1, 2);
rec->len_fi[0] = len_fi;
}
/**
* Write the enhanced volume descriptor (ISO/IEC 9660:1999, 8.5)
* Write the enhanced volume descriptor
* (ISO/IEC 9660:1999 / ECMA-119 4th Edition, 8.5)
*/
static
int iso1999_writer_write_vol_desc(IsoImageWriter *writer)
@ -758,14 +810,16 @@ int iso1999_writer_write_vol_desc(IsoImageWriter *writer)
vol.vol_desc_type[0] = 2;
memcpy(vol.std_identifier, "CD001", 5);
/* descriptor version is 2 (ISO/IEC 9660:1999, 8.5.2) */
/* descriptor version is 2
* (ISO/IEC 9660:1999 / ECMA-119 4th Edition, 8.5.2)
*/
vol.vol_desc_version[0] = 2;
strncpy_pad((char*)vol.volume_id, vol_id, 32);
iso_bb(vol.vol_space_size, t->vol_space_size, 4);
iso_bb(vol.vol_set_size, 1, 2);
iso_bb(vol.vol_seq_number, 1, 2);
iso_bb(vol.block_size, BLOCK_SIZE, 2);
iso_bb(vol.vol_set_size, (uint32_t) 1, 2);
iso_bb(vol.vol_seq_number, (uint32_t) 1, 2);
iso_bb(vol.block_size, (uint32_t) BLOCK_SIZE, 2);
iso_bb(vol.path_table_size, t->iso1999_path_table_size, 4);
iso_lsb(vol.l_path_table_pos, t->iso1999_l_path_table_pos, 4);
iso_msb(vol.m_path_table_pos, t->iso1999_m_path_table_pos, 4);
@ -783,10 +837,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);
@ -806,15 +858,15 @@ static
int write_one_dir(Ecma119Image *t, Iso1999Node *dir)
{
int ret;
uint8_t buffer[BLOCK_SIZE];
uint8_t *buffer = NULL;
size_t i;
size_t fi_len, len;
/* buf will point to current write position on buffer */
uint8_t *buf = buffer;
uint8_t *buf;
/* initialize buffer with 0s */
memset(buffer, 0, BLOCK_SIZE);
LIBISO_ALLOC_MEM(buffer, uint8_t, BLOCK_SIZE);
buf = buffer;
/* write the "." and ".." entries first */
write_one_dir_record(t, dir, 0, buf, 1, 0);
@ -828,7 +880,7 @@ int write_one_dir(Ecma119Image *t, Iso1999Node *dir)
/* compute len of directory entry */
fi_len = strlen(child->name);
len = fi_len + 33 + (fi_len % 2 ? 0 : 1);
len = fi_len + 33 + ((fi_len % 2) ? 0 : 1);
nsections = (child->type == ISO1999_FILE) ? child->info.file->nsections : 1;
for (section = 0; section < nsections; ++section) {
@ -836,7 +888,7 @@ int write_one_dir(Ecma119Image *t, Iso1999Node *dir)
/* dir doesn't fit in current block */
ret = iso_write(t, buffer, BLOCK_SIZE);
if (ret < 0) {
return ret;
goto ex;
}
memset(buffer, 0, BLOCK_SIZE);
buf = buffer;
@ -849,6 +901,8 @@ int write_one_dir(Ecma119Image *t, Iso1999Node *dir)
/* write the last block */
ret = iso_write(t, buffer, BLOCK_SIZE);
ex:;
LIBISO_FREE_MEM(buffer);
return ret;
}
@ -881,13 +935,17 @@ static
int write_path_table(Ecma119Image *t, Iso1999Node **pathlist, int l_type)
{
size_t i, len;
uint8_t buf[256]; /* 256 is just a convenient size larger enought */
uint8_t *buf = NULL;
struct ecma119_path_table_record *rec;
void (*write_int)(uint8_t*, uint32_t, int);
Iso1999Node *dir;
uint32_t path_table_size;
int parent = 0;
int ret= ISO_SUCCESS;
uint8_t *zeros = NULL;
/* 256 is just a convenient size large enough */
LIBISO_ALLOC_MEM(buf, uint8_t, 256);
path_table_size = 0;
write_int = l_type ? iso_lsb : iso_msb;
@ -914,7 +972,7 @@ int write_path_table(Ecma119Image *t, Iso1999Node **pathlist, int l_type)
ret = iso_write(t, buf, len);
if (ret < 0) {
/* error */
return ret;
goto ex;
}
path_table_size += len;
}
@ -922,11 +980,14 @@ int write_path_table(Ecma119Image *t, Iso1999Node **pathlist, int l_type)
/* we need to fill the last block with zeros */
path_table_size %= BLOCK_SIZE;
if (path_table_size) {
uint8_t zeros[BLOCK_SIZE];
LIBISO_ALLOC_MEM(zeros, uint8_t, BLOCK_SIZE);
len = BLOCK_SIZE - path_table_size;
memset(zeros, 0, len);
ret = iso_write(t, zeros, len);
}
ex:;
LIBISO_FREE_MEM(zeros);
LIBISO_FREE_MEM(buf);
return ret;
}
@ -997,7 +1058,9 @@ int iso1999_writer_write_data(IsoImageWriter *writer)
static
int iso1999_writer_free_data(IsoImageWriter *writer)
{
/* free the ISO 9660:1999 tree */
/* free the ISO 9660:1999 / ECMA-119 4th Edition Enhanced Volume Descriptor
* tree
*/
Ecma119Image *t = writer->target;
iso1999_node_free(t->iso1999_root);
return ISO_SUCCESS;
@ -1024,6 +1087,7 @@ int iso1999_writer_create(Ecma119Image *target)
"Creating low level ISO 9660:1999 tree...");
ret = iso1999_tree_create(target);
if (ret < 0) {
free((char *) writer);
return ret;
}

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2024 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
@ -8,11 +9,11 @@
*/
/**
* Structures related to ISO/IEC 9660:1999, that is version 2 of ISO-9660
* "See doc/devel/cookbook/ISO 9660-1999" and
* ISO/IEC DIS 9660:1999(E) "Information processing. Volume and file structure
* of CD­-ROM for Information Interchange"
* for further details.
* Structures related to the Enhanced Volume Descriptor as of ECMA-119 4th
* Edition. See there and in "doc/devel/cookbook/ISO 9660-1999" for further
* details.
* This optional tree is also known as ISO/IEC DIS 9660:1999, a once proposed
* version 2 of ISO-9660.
*/
#ifndef LIBISO_ISO1999_H
@ -49,7 +50,7 @@ struct iso1999_node
};
/**
* Create a IsoWriter to deal with ISO 9660:1999 estructures, and add it to
* Create a IsoWriter to deal with ISO 9660:1999 structures, and add it to
* the given target.
*
* @return

View File

@ -1,6 +1,7 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2007 Mario Danic
* Copyright (c) 2011-2018 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
@ -8,6 +9,10 @@
* See COPYING file for details.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include "joliet.h"
#include "messages.h"
#include "writer.h"
@ -15,38 +20,77 @@
#include "filesrc.h"
#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;
}
/* TODO #00022 : support relaxed constraints in joliet filenames */
if (iso->type == LIBISO_DIR) {
jname = iso_j_dir_id(ucs_name);
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 {
jname = iso_j_file_id(ucs_name);
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);
}
}
}
}
free(ucs_name);
if (jname != NULL) {
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,
(opts->joliet_long_names << 1) | !!(opts->no_force_dots & 2));
}
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 {
@ -58,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)
{
@ -65,11 +122,12 @@ void joliet_node_free(JolietNode *node)
return;
}
if (node->type == JOLIET_DIR) {
int i;
size_t i;
for (i = 0; i < node->info.dir->nchildren; i++) {
joliet_node_free(node->info.dir->children[i]);
}
free(node->info.dir->children);
if (node->info.dir->children != NULL)
free(node->info.dir->children);
free(node->info.dir);
}
iso_node_unref(node->node);
@ -100,11 +158,14 @@ int create_node(Ecma119Image *t, IsoNode *iso, JolietNode **node)
free(joliet);
return ISO_OUT_OF_MEM;
}
joliet->info.dir->children = calloc(sizeof(void*), dir->nchildren);
if (joliet->info.dir->children == NULL) {
free(joliet->info.dir);
free(joliet);
return ISO_OUT_OF_MEM;
joliet->info.dir->children = NULL;
if (dir->nchildren > 0) {
joliet->info.dir->children = calloc(sizeof(void*), dir->nchildren);
if (joliet->info.dir->children == NULL) {
free(joliet->info.dir);
free(joliet);
return ISO_OUT_OF_MEM;
}
}
joliet->type = JOLIET_DIR;
} else if (iso->type == LIBISO_FILE) {
@ -114,7 +175,8 @@ int create_node(Ecma119Image *t, IsoNode *iso, JolietNode **node)
IsoFile *file = (IsoFile*) iso;
size = iso_stream_get_size(file->stream);
if (size > (off_t)MAX_ISO_FILE_SECTION_SIZE && t->iso_level != 3) {
if (size > (off_t)MAX_ISO_FILE_SECTION_SIZE &&
t->opts->iso_level != 3) {
char *ipath = iso_tree_get_node_path(iso);
free(joliet);
ret = iso_msg_submit(t->image->id, ISO_FILE_TOO_BIG, 0,
@ -182,7 +244,7 @@ int create_tree(Ecma119Image *t, IsoNode *iso, JolietNode **tree, int pathlen)
return ret;
}
max_path = pathlen + 1 + (jname ? ucslen(jname) * 2 : 0);
if (!t->joliet_longer_paths && max_path > 240) {
if (!t->opts->joliet_longer_paths && max_path > 240) {
char *ipath = iso_tree_get_node_path(iso);
/*
* Wow!! Joliet is even more restrictive than plain ISO-9660,
@ -239,14 +301,36 @@ int create_tree(Ecma119Image *t, IsoNode *iso, JolietNode **tree, int pathlen)
}
break;
case LIBISO_SYMLINK:
case LIBISO_SPECIAL:
{
t->joliet_symlinks++;
if (t->joliet_symlinks == 1) {
char *ipath = iso_tree_get_node_path(iso);
/* This first ret might indicate the need to abort */
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 "
"Rock Ridget tree.", ipath, (iso->type == LIBISO_SYMLINK ?
"Symlinks" : "Special files"));
"Cannot add %s to Joliet tree. Symlinks can only be added to a "
"Rock Ridge tree.", ipath);
free(ipath);
} else {
if (t->joliet_symlinks == 2)
iso_msg_submit(t->image->id, ISO_FILE_IGNORED, 0,
"More symbolic links were omitted from Joliet tree.");
ret = 0;
}
break;
case LIBISO_SPECIAL:
t->joliet_specials++;
if (t->joliet_specials == 1) {
char *ipath = iso_tree_get_node_path(iso);
/* This first ret might indicate the need to abort */
ret = iso_msg_submit(t->image->id, ISO_FILE_IGNORED, 0,
"Cannot add %s to Joliet tree. "
"Special files can only be added to a Rock Ridge tree.",
ipath);
free(ipath);
} else {
if (t->joliet_specials == 2)
iso_msg_submit(t->image->id, ISO_FILE_IGNORED, 0,
"More special files were omitted from Joliet tree.");
ret = 0;
}
break;
default:
@ -275,6 +359,8 @@ void sort_tree(JolietNode *root)
{
size_t i;
if (root->info.dir->children == NULL)
return;
qsort(root->info.dir->children, root->info.dir->nchildren,
sizeof(void*), cmp_node);
for (i = 0; i < root->info.dir->nchildren; i++) {
@ -299,8 +385,15 @@ int joliet_create_mangled_name(uint16_t *dest, uint16_t *src, int digits,
int ret, pos;
uint16_t *ucsnumber;
char fmt[16];
char nstr[72]; /* The only caller of this function allocates dest with 66
elements and limits digits to < 8 */
char nstr[72];
/* was: The only caller of this function allocates dest
with 66 elements and limits digits to < 8
But this does not match the usage of nstr which has to take
the decimal representation of an int.
*/
if (digits >= 8)
return ISO_ASSERT_FAILURE;
sprintf(fmt, "%%0%dd", digits);
sprintf(nstr, fmt, number);
@ -320,32 +413,58 @@ 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;
}
/*
* From Joliet specs:
* "ISO 9660 (Section 7.5.1) states that the sum of the following shall not
* exceed 30:
* - If there is a file name, the length of the file name.
* - If there is a file name extension, the length of the file name extension.
* On Joliet compliant media, however, the sum as calculated above shall not
* exceed 128 [bytes], to allow for longer file identifiers."
*
* I.e. the dot does not count.
*
* (We have an option to lift the limit from 64*2 to 103*2, which is the
* maximum to fit into an ISO 9660 directory record.)
*/
static
int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
{
int ret;
int i, nchildren;
int i, nchildren, maxchar = 64;
JolietNode **children;
IsoHTable *table;
IsoHTable *table = NULL;
int need_sort = 0;
uint16_t *full_name = NULL;
uint16_t *tmp = NULL;
nchildren = dir->info.dir->nchildren;
if (nchildren <= 0) {
ret = ISO_SUCCESS;
goto ex;
}
children = dir->info.dir->children;
LIBISO_ALLOC_MEM(full_name, uint16_t, LIBISO_JOLIET_NAME_MAX);
LIBISO_ALLOC_MEM(tmp, uint16_t, LIBISO_JOLIET_NAME_MAX);
if (t->opts->joliet_long_names)
maxchar = 103;
/* a hash table will temporary hold the names, for fast searching */
ret = iso_htable_create((nchildren * 100) / 80, iso_str_hash,
(compare_function_t)ucscmp, &table);
if (ret < 0) {
return ret;
goto ex;
}
for (i = 0; i < nchildren; ++i) {
uint16_t *name = children[i]->name;
@ -357,7 +476,6 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
for (i = 0; i < nchildren; ++i) {
uint16_t *name, *ext;
uint16_t full_name[66];
int max; /* computed max len for name, without extension */
int j = i;
int digits = 1; /* characters to change per name */
@ -373,10 +491,10 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
}
/*
* A max of 7 characters is good enought, it allows handling up to
* A max of 7 characters is good enough, it allows handling up to
* 9,999,999 files with same name.
*/
/* Important: joliet_create_mangled_name() relies on digits < 72 */
/* Important: joliet_create_mangled_name() relies on digits < 8 */
while (digits < 8) {
int ok, k;
@ -399,25 +517,26 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
ext = dot + 1;
extlen = ucslen(ext);
max = 65 - extlen - 1 - digits;
max = maxchar - extlen - digits;
if (max <= 0) {
/* this can happen if extension is too long */
if (extlen + max > 3) {
/*
* This can happen if the extension is too long.
* Reduce its length, to give name at least one
* original character, if it has any.
*/
max = (dot > full_name);
extlen = maxchar - max - digits;
if (extlen < 3) {
/*
* reduce extension len, to give name an extra char
* note that max is negative or 0
*/
extlen = extlen + max - 1;
ext[extlen] = 0;
max = 66 - extlen - 1 - digits;
} else {
/*
* error, we don't support extensions < 3
* This can't happen with current limit of digits.
* error, we do not reduce extensions to length < 3
*
* This cannot happen with current limit of digits
* because maxchar is at least 64 and digits at most 7.
*/
ret = ISO_ERROR;
goto mangle_cleanup;
}
ext[extlen] = 0;
}
/* ok, reduce name by digits */
if (name + max < dot) {
@ -426,13 +545,13 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
} else {
/* Directory, or file without extension */
if (children[i]->type == JOLIET_DIR) {
max = 65 - digits;
max = maxchar - digits;
dot = NULL; /* dots have no meaning in dirs */
} else {
max = 65 - digits;
max = maxchar - digits;
}
name = full_name;
if (max < ucslen(name)) {
if ((size_t) max < ucslen(name)) {
name[max] = 0;
}
/* let ext be an empty string */
@ -442,7 +561,6 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
ok = 1;
/* change name of each file */
for (k = i; k <= j; ++k) {
uint16_t tmp[66];
while (1) {
ret = joliet_create_mangled_name(tmp, name, digits,
change, ext);
@ -504,7 +622,10 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
ret = ISO_SUCCESS;
mangle_cleanup : ;
ex:;
iso_htable_destroy(table, NULL);
LIBISO_FREE_MEM(tmp);
LIBISO_FREE_MEM(full_name);
return ret;
}
@ -552,17 +673,19 @@ int joliet_tree_create(Ecma119Image *t)
}
/* the Joliet tree is stored in Ecma119Image target */
t->joliet_root = root;
if (t->eff_partition_offset > 0) {
t->j_part_root = root;
} else {
t->joliet_root = root;
}
iso_msg_debug(t->image->id, "Sorting the Joliet tree...");
sort_tree(root);
iso_msg_debug(t->image->id, "Mangling Joliet names...");
ret = mangle_tree(t, t->joliet_root);
if (ret < 0) {
ret = mangle_tree(t, root);
if (ret < 0)
return ret;
}
return ISO_SUCCESS;
}
@ -574,7 +697,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) {
if (n->type == JOLIET_FILE && !(t->opts->omit_version_numbers & 3)) {
/* take into account version numbers */
ret += 4;
}
@ -669,6 +792,7 @@ int joliet_writer_compute_data_blocks(IsoImageWriter *writer)
{
Ecma119Image *t;
uint32_t path_table_size;
size_t ndirs;
if (writer == NULL) {
return ISO_OUT_OF_MEM;
@ -692,6 +816,24 @@ 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->opts->partition_offset > 0) {
/* Take into respect second directory tree */
ndirs = t->joliet_ndirs;
t->joliet_ndirs = 0;
calc_dir_pos(t, t->j_part_root);
if (t->joliet_ndirs != ndirs) {
iso_msg_submit(t->image->id, ISO_ASSERT_FAILURE, 0,
"Number of directories differs in Joliet partiton_tree");
return ISO_ASSERT_FAILURE;
}
/* Take into respect second set of path tables */
path_table_size = calc_path_table_size(t->j_part_root);
t->j_part_l_path_table_pos = t->curblock;
t->curblock += DIV_UP(path_table_size, BLOCK_SIZE);
t->j_part_m_path_table_pos = t->curblock;
t->curblock += DIV_UP(path_table_size, BLOCK_SIZE);
}
return ISO_SUCCESS;
}
@ -717,12 +859,13 @@ void write_one_dir_record(Ecma119Image *t, JolietNode *node, int file_id,
: (uint8_t*)node->name;
struct ecma119_dir_record *rec = (struct ecma119_dir_record*)buf;
IsoNode *iso;
len_dr = 33 + len_fi + (len_fi % 2 ? 0 : 1);
len_dr = 33 + len_fi + ((len_fi % 2) ? 0 : 1);
memcpy(rec->file_id, name, len_fi);
if (node->type == JOLIET_FILE && !t->omit_version_numbers) {
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++] = ';';
@ -754,11 +897,19 @@ void write_one_dir_record(Ecma119Image *t, JolietNode *node, int file_id,
node = node->parent;
rec->len_dr[0] = len_dr;
iso_bb(rec->block, block, 4);
iso_bb(rec->block, block - t->eff_partition_offset, 4);
iso_bb(rec->length, len, 4);
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->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, 1, 2);
iso_bb(rec->vol_seq_number, (uint32_t) 1, 2);
rec->len_fi[0] = len_fi;
}
@ -776,21 +927,24 @@ 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;
}
static
int joliet_writer_write_vol_desc(IsoImageWriter *writer)
{
IsoImage *image;
@ -831,16 +985,25 @@ int joliet_writer_write_vol_desc(IsoImageWriter *writer)
/* make use of UCS-2 Level 3 */
memcpy(vol.esc_sequences, "%/E", 3);
iso_bb(vol.vol_space_size, t->vol_space_size, 4);
iso_bb(vol.vol_set_size, 1, 2);
iso_bb(vol.vol_seq_number, 1, 2);
iso_bb(vol.block_size, BLOCK_SIZE, 2);
iso_bb(vol.vol_space_size, t->vol_space_size - t->eff_partition_offset,
4);
iso_bb(vol.vol_set_size, (uint32_t) 1, 2);
iso_bb(vol.vol_seq_number, (uint32_t) 1, 2);
iso_bb(vol.block_size, (uint32_t) BLOCK_SIZE, 2);
iso_bb(vol.path_table_size, t->joliet_path_table_size, 4);
iso_lsb(vol.l_path_table_pos, t->joliet_l_path_table_pos, 4);
iso_msb(vol.m_path_table_pos, t->joliet_m_path_table_pos, 4);
write_one_dir_record(t, t->joliet_root, 0, vol.root_dir_record, 1, 0);
if (t->eff_partition_offset > 0) {
/* Point to second tables and second root */
iso_lsb(vol.l_path_table_pos,
t->j_part_l_path_table_pos - t->eff_partition_offset, 4);
iso_msb(vol.m_path_table_pos,
t->j_part_m_path_table_pos - t->eff_partition_offset, 4);
write_one_dir_record(t, t->j_part_root, 0, vol.root_dir_record, 1, 0);
} else {
iso_lsb(vol.l_path_table_pos, t->joliet_l_path_table_pos, 4);
iso_msb(vol.m_path_table_pos, t->joliet_m_path_table_pos, 4);
write_one_dir_record(t, t->joliet_root, 0, vol.root_dir_record, 1, 0);
}
ucsncpy_pad((uint16_t*)vol.vol_set_id, volset_id, 128);
ucsncpy_pad((uint16_t*)vol.publisher_id, pub_id, 128);
@ -853,9 +1016,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);
@ -876,15 +1037,16 @@ static
int write_one_dir(Ecma119Image *t, JolietNode *dir)
{
int ret;
uint8_t buffer[BLOCK_SIZE];
uint8_t *buffer = NULL;
size_t i;
size_t fi_len, len;
/* buf will point to current write position on buffer */
uint8_t *buf = buffer;
uint8_t *buf;
/* initialize buffer with 0s */
memset(buffer, 0, BLOCK_SIZE);
LIBISO_ALLOC_MEM(buffer, uint8_t, BLOCK_SIZE);
buf = buffer;
/* write the "." and ".." entries first */
write_one_dir_record(t, dir, 0, buf, 1, 0);
@ -899,7 +1061,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) {
if (child->type == JOLIET_FILE &&
!(t->opts->omit_version_numbers & 3)) {
len += 4;
}
@ -911,7 +1074,7 @@ int write_one_dir(Ecma119Image *t, JolietNode *dir)
/* dir doesn't fit in current block */
ret = iso_write(t, buffer, BLOCK_SIZE);
if (ret < 0) {
return ret;
goto ex;
}
memset(buffer, 0, BLOCK_SIZE);
buf = buffer;
@ -924,6 +1087,8 @@ int write_one_dir(Ecma119Image *t, JolietNode *dir)
/* write the last block */
ret = iso_write(t, buffer, BLOCK_SIZE);
ex:;
LIBISO_FREE_MEM(buffer);
return ret;
}
@ -956,14 +1121,18 @@ static
int write_path_table(Ecma119Image *t, JolietNode **pathlist, int l_type)
{
size_t i, len;
uint8_t buf[256]; /* 256 is just a convenient size larger enought */
uint8_t *buf = NULL;
struct ecma119_path_table_record *rec;
void (*write_int)(uint8_t*, uint32_t, int);
JolietNode *dir;
uint32_t path_table_size;
int parent = 0;
int ret= ISO_SUCCESS;
uint8_t *zeros = NULL;
/* 256 is just a convenient size large enough */
LIBISO_ALLOC_MEM(buf, uint8_t, 256);
LIBISO_ALLOC_MEM(zeros, uint8_t, BLOCK_SIZE);
path_table_size = 0;
write_int = l_type ? iso_lsb : iso_msb;
@ -980,7 +1149,8 @@ int write_path_table(Ecma119Image *t, JolietNode **pathlist, int l_type)
rec = (struct ecma119_path_table_record*) buf;
rec->len_di[0] = dir->parent ? (uint8_t) ucslen(dir->name) * 2 : 1;
rec->len_xa[0] = 0;
write_int(rec->block, dir->info.dir->block, 4);
write_int(rec->block, dir->info.dir->block - t->eff_partition_offset,
4);
write_int(rec->parent, parent + 1, 2);
if (dir->parent) {
memcpy(rec->dir_id, dir->name, rec->len_di[0]);
@ -989,7 +1159,7 @@ int write_path_table(Ecma119Image *t, JolietNode **pathlist, int l_type)
ret = iso_write(t, buf, len);
if (ret < 0) {
/* error */
return ret;
goto ex;
}
path_table_size += len;
}
@ -997,11 +1167,13 @@ int write_path_table(Ecma119Image *t, JolietNode **pathlist, int l_type)
/* we need to fill the last block with zeros */
path_table_size %= BLOCK_SIZE;
if (path_table_size) {
uint8_t zeros[BLOCK_SIZE];
len = BLOCK_SIZE - path_table_size;
memset(zeros, 0, len);
ret = iso_write(t, zeros, len);
}
ex:;
LIBISO_FREE_MEM(zeros);
LIBISO_FREE_MEM(buf);
return ret;
}
@ -1019,7 +1191,12 @@ int write_path_tables(Ecma119Image *t)
if (pathlist == NULL) {
return ISO_OUT_OF_MEM;
}
pathlist[0] = t->joliet_root;
if (t->eff_partition_offset > 0) {
pathlist[0] = t->j_part_root;
} else {
pathlist[0] = t->joliet_root;
}
cur = 1;
for (i = 0; i < t->joliet_ndirs; i++) {
@ -1047,18 +1224,21 @@ int write_path_tables(Ecma119Image *t)
}
static
int joliet_writer_write_data(IsoImageWriter *writer)
int joliet_writer_write_dirs(IsoImageWriter *writer)
{
int ret;
Ecma119Image *t;
JolietNode *root;
if (writer == NULL) {
return ISO_NULL_POINTER;
}
t = writer->target;
/* first of all, we write the directory structure */
ret = write_dirs(t, t->joliet_root);
if (t->eff_partition_offset > 0) {
root = t->j_part_root;
} else {
root = t->joliet_root;
}
ret = write_dirs(t, root);
if (ret < 0) {
return ret;
}
@ -1069,12 +1249,40 @@ int joliet_writer_write_data(IsoImageWriter *writer)
return ret;
}
static
int joliet_writer_write_data(IsoImageWriter *writer)
{
int ret;
Ecma119Image *t;
if (writer == NULL) {
return ISO_NULL_POINTER;
}
t = writer->target;
ret = joliet_writer_write_dirs(writer);
if (ret < 0)
return ret;
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)
return ret;
}
return ISO_SUCCESS;
}
static
int joliet_writer_free_data(IsoImageWriter *writer)
{
/* free the Joliet tree */
Ecma119Image *t = writer->target;
joliet_node_free(t->joliet_root);
if (t->j_part_root != NULL)
joliet_node_free(t->j_part_root);
t->j_part_root = NULL;
return ISO_SUCCESS;
}
@ -1098,12 +1306,23 @@ int joliet_writer_create(Ecma119Image *target)
iso_msg_debug(target->image->id, "Creating low level Joliet tree...");
ret = joliet_tree_create(target);
if (ret < 0) {
free((char *) writer);
return ret;
}
/* add this writer to image */
target->writers[target->nwriters++] = writer;
if(target->opts->partition_offset > 0) {
/* Create second tree */
target->eff_partition_offset = target->opts->partition_offset;
ret = joliet_tree_create(target);
if (ret < 0) {
return ret;
}
target->eff_partition_offset = 0;
}
/* we need the volume descriptor */
target->curblock++;
return ISO_SUCCESS;

View File

@ -18,6 +18,10 @@
#include "libisofs.h"
#include "ecma119.h"
/* was formerly 66 = 64 + 2. Now 105 = 103 + 2.
*/
#define LIBISO_JOLIET_NAME_MAX 105
enum joliet_node_type {
JOLIET_FILE,
JOLIET_DIR
@ -54,4 +58,18 @@ struct joliet_node
*/
int joliet_writer_create(Ecma119Image *target);
/* Not to be called but only for comparison with target->writers[i]
*/
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

@ -1,10 +1,19 @@
/* libiso_msgs (generated from libdax_msgs : Fri Feb 22 19:42:52 CET 2008)
Message handling facility of libisofs.
Copyright (C) 2006 - 2008 Thomas Schmitt <scdbackup@gmx.net>,
provided under GPL version 2 or later
Copyright (C) 2006 - 2016 Thomas Schmitt <scdbackup@gmx.net>,
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 <stdio.h>
#include <sys/types.h>
#include <unistd.h>
@ -29,14 +38,13 @@ static int libiso_msgs_item_new(struct libiso_msgs_item **item,
int ret;
struct libiso_msgs_item *o;
struct timeval tv;
struct timezone tz;
(*item)= o=
(struct libiso_msgs_item *) malloc(sizeof(struct libiso_msgs_item));
if(o==NULL)
return(-1);
o->timestamp= 0.0;
ret= gettimeofday(&tv,&tz);
ret= gettimeofday(&tv, NULL);
if(ret==0)
o->timestamp= tv.tv_sec+0.000001*tv.tv_usec;
o->process_id= getpid();
@ -284,7 +292,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

@ -1,8 +1,13 @@
/* libiso_msgs (generated from libdax_msgs : Fri Feb 22 19:42:52 CET 2008)
Message handling facility of libisofs.
Copyright (C) 2006-2008 Thomas Schmitt <scdbackup@gmx.net>,
provided under GPL version 2 or later
Copyright (C) 2006-2016 Thomas Schmitt <scdbackup@gmx.net>,
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.
*/
@ -221,7 +226,7 @@ struct libiso_msgs_item;
*/
#define LIBISO_MSGS_SEV_ABORT 0x71000000
/** A severity to exclude resp. discard any possible message.
/** A severity to exclude or discard any possible message.
Do not use this severity for submitting.
*/
#define LIBISO_MSGS_SEV_NEVER 0x7fffffff
@ -266,8 +271,9 @@ int libiso_msgs_new(struct libiso_msgs **m, int flag);
/** Destroy a message handling facility and all its eventual messages.
The submitted pointer gets set to NULL.
Actually only the last destroy call of all offical references to the object
will really dispose it. All others just decrement the reference counter.
Actually only the last destroy call of all official references to the
object will really dispose it. All others just decrement the reference
counter.
Call this function only with official reference pointers obtained by
libiso_msgs_new() or libiso_msgs_refer(), and only once per such pointer.
@param flag Bitfield for control purposes (unused yet, submit 0)
@ -316,7 +322,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,
@ -421,7 +427,7 @@ Range "elmom" : 0x00010000 to 0x0001ffff
------------------------------------------------------------------------------
Range "scdbackup" : 0x00020000 to 0x0002ffff
Acessing and defending drives:
Accessing and defending drives:
0x00020001 (SORRY,LOW) = Cannot open busy device
0x00020002 (SORRY,HIGH) = Encountered error when closing drive
@ -510,7 +516,7 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
0x00020148 (SORRY,HIGH) = Cannot write desired amount of data
0x00020149 (SORRY,HIGH) = Unsuitable filetype for pseudo-drive
0x0002014a (SORRY,HIGH) = Cannot read desired amount of data
0x0002014b (SORRY,HIGH) = Drive is already registered resp. scanned
0x0002014b (SORRY,HIGH) = Drive is already registered and scanned
0x0002014c (FATAL,HIGH) = Emulated drive caught in SCSI function
0x0002014d (SORRY,HIGH) = Asynchromous SCSI error
0x0002014f (SORRY,HIGH) = Timeout with asynchromous SCSI command
@ -553,11 +559,11 @@ Range "vreixo" : 0x00030000 to 0x0003ffff
0x0003ffbc (FAILURE,HIGH) = Image already bootable
0x0003ffbb (FAILURE,HIGH) = Trying to use an invalid file as boot image
0x0003ff80 (FAILURE,HIGH) = Error on file operation
0x0003ff7f (FAILURE,HIGH) = Trying to open an already openned file
0x0003ff7f (FAILURE,HIGH) = Trying to open an already opened file
0x0003ff7e (FAILURE,HIGH) = Access to file is not allowed
0x0003ff7d (FAILURE,HIGH) = Incorrect path to file
0x0003ff7c (FAILURE,HIGH) = The file does not exist in the filesystem
0x0003ff7b (FAILURE,HIGH) = Trying to read or close a file not openned
0x0003ff7b (FAILURE,HIGH) = Trying to read or close a file not opened
0x0003ff7a (FAILURE,HIGH) = Directory used where no dir is expected
0x0003ff79 (FAILURE,HIGH) = File read error
0x0003ff78 (FAILURE,HIGH) = Not dir used where a dir is expected
@ -608,7 +614,7 @@ X 0x00030203 (HINT,MEDIUM) = Unsupported El-Torito feature
X 0x00030204 (SORRY,HIGH) = Invalid file to be an El-Torito image
X 0x00030205 (WARNING,MEDIUM)= Cannot properly patch isolinux image
X 0x00030206 (WARNING,MEDIUM)= Copying El-Torito from a previous image without
X enought info about it
X enough info about it
X 0x00030301 (NOTE,MEDIUM) = Unsupported file type for Joliet tree

File diff suppressed because it is too large Load Diff

405
libisofs/libisofs.ver Normal file
View File

@ -0,0 +1,405 @@
LIBISOFS6 {
global:
aaip_xinfo_cloner;
aaip_xinfo_func;
el_torito_get_bootable;
el_torito_get_boot_media_type;
el_torito_get_boot_platform_id;
el_torito_get_full_load;
el_torito_get_id_string;
el_torito_get_isolinux_options;
el_torito_get_load_seg;
el_torito_get_load_size;
el_torito_get_selection_crit;
el_torito_patch_isolinux_image;
el_torito_seems_boot_info_table;
el_torito_set_boot_platform_id;
el_torito_set_full_load;
el_torito_set_id_string;
el_torito_set_isolinux_options;
el_torito_set_load_seg;
el_torito_set_load_size;
el_torito_set_no_bootable;
el_torito_set_selection_crit;
iso_assess_written_features;
iso_conv_name_chars;
iso_crc32_gpt;
iso_data_source_new_from_file;
iso_data_source_ref;
iso_data_source_unref;
iso_dir_add_node;
iso_dir_find_children;
iso_dir_get_children;
iso_dir_get_children_count;
iso_dir_get_node;
iso_dir_iter_free;
iso_dir_iter_has_next;
iso_dir_iter_next;
iso_dir_iter_remove;
iso_dir_iter_take;
iso_error_get_code;
iso_error_get_priority;
iso_error_get_severity;
iso_error_to_msg;
iso_file_add_external_filter;
iso_file_add_gzip_filter;
iso_file_add_zisofs_filter;
iso_file_get_md5;
iso_file_get_old_image_lba;
iso_file_get_old_image_sections;
iso_file_get_size;
iso_file_get_sort_weight;
iso_file_get_stream;
iso_file_make_md5;
iso_file_remove_filter;
iso_file_source_access;
iso_file_source_close;
iso_file_source_get_aa_string;
iso_file_source_get_filesystem;
iso_file_source_get_name;
iso_file_source_get_path;
iso_file_source_lseek;
iso_file_source_lstat;
iso_file_source_open;
iso_file_source_read;
iso_file_source_readdir;
iso_file_source_readlink;
iso_file_source_ref;
iso_file_source_stat;
iso_file_source_unref;
iso_filesystem_ref;
iso_filesystem_unref;
iso_finish;
iso_fs_global_id;
iso_generate_gpt_guid;
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_add_new_dir;
iso_image_add_new_file;
iso_image_add_new_special;
iso_image_add_new_symlink;
iso_image_attach_data;
iso_image_create_burn_source;
iso_image_dir_get_node;
iso_image_filesystem_new;
iso_image_fs_get_abstract_file_id;
iso_image_fs_get_application_id;
iso_image_fs_get_biblio_file_id;
iso_image_fs_get_copyright_file_id;
iso_image_fs_get_data_preparer_id;
iso_image_fs_get_publisher_id;
iso_image_fs_get_system_id;
iso_image_fs_get_volset_id;
iso_image_fs_get_volume_id;
iso_image_generator_is_running;
iso_image_get_abstract_file_id;
iso_image_get_all_boot_imgs;
iso_image_get_alpha_boot;
iso_image_get_app_use;
iso_image_get_application_id;
iso_image_get_attached_data;
iso_image_get_biblio_file_id;
iso_image_get_bootcat;
iso_image_get_boot_image;
iso_image_get_copyright_file_id;
iso_image_get_data_preparer_id;
iso_image_get_hppa_palo;
iso_image_get_ignore_aclea;
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_truncate_mode;
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_path_to_node;
iso_image_ref;
iso_image_remove_boot_image;
iso_image_report_el_torito;
iso_image_report_system_area;
iso_image_set_abstract_file_id;
iso_image_set_alpha_boot;
iso_image_set_app_use;
iso_image_set_application_id;
iso_image_set_biblio_file_id;
iso_image_set_boot_catalog_hidden;
iso_image_set_boot_catalog_weight;
iso_image_set_boot_image;
iso_image_set_copyright_file_id;
iso_image_set_data_preparer_id;
iso_image_set_hppa_palo;
iso_image_set_ignore_aclea;
iso_image_set_node_name;
iso_image_set_publisher_id;
iso_image_set_sparc_core;
iso_image_set_system_id;
iso_image_set_truncate_mode;
iso_image_set_volset_id;
iso_image_set_volume_id;
iso_image_tree_clone;
iso_image_unref;
iso_image_update_sizes;
iso_image_was_blind_attrs;
iso_image_zisofs_discard_bpt;
iso_init;
iso_init_with_flag;
iso_interval_reader_destroy;
iso_interval_reader_new;
iso_interval_reader_read;
iso_lib_is_compatible;
iso_lib_version;
iso_local_attr_support;
iso_local_get_acl_text;
iso_local_get_attrs;
iso_local_get_perms_wo_acl;
iso_local_set_acl_text;
iso_local_set_attrs;
iso_local_set_attrs_errno;
iso_md5_clone;
iso_md5_compute;
iso_md5_end;
iso_md5_match;
iso_md5_start;
iso_memory_stream_new;
iso_msgs_submit;
iso_new_find_conditions_and;
iso_new_find_conditions_atime;
iso_new_find_conditions_ctime;
iso_new_find_conditions_gid;
iso_new_find_conditions_mode;
iso_new_find_conditions_mtime;
iso_new_find_conditions_name;
iso_new_find_conditions_not;
iso_new_find_conditions_or;
iso_new_find_conditions_uid;
iso_node_add_xinfo;
iso_node_cmp_ino;
iso_node_get_acl_text;
iso_node_get_atime;
iso_node_get_attrs;
iso_node_get_ctime;
iso_node_get_gid;
iso_node_get_hidden;
iso_node_get_mode;
iso_node_get_mtime;
iso_node_get_name;
iso_node_get_next_xinfo;
iso_node_get_old_image_lba;
iso_node_get_parent;
iso_node_get_permissions;
iso_node_get_perms_wo_acl;
iso_node_get_type;
iso_node_get_uid;
iso_node_get_xinfo;
iso_node_lookup_attr;
iso_node_ref;
iso_node_remove;
iso_node_remove_all_xinfo;
iso_node_remove_tree;
iso_node_remove_xinfo;
iso_node_set_acl_text;
iso_node_set_atime;
iso_node_set_attrs;
iso_node_set_ctime;
iso_node_set_gid;
iso_node_set_hidden;
iso_node_set_mtime;
iso_node_set_name;
iso_node_set_permissions;
iso_node_set_sort_weight;
iso_node_set_uid;
iso_node_take;
iso_node_unref;
iso_node_xinfo_get_cloner;
iso_node_xinfo_make_clonable;
iso_node_zf_by_magic;
iso_nowtime;
iso_obtain_msgs;
iso_read_image_feature_named;
iso_read_image_features_destroy;
iso_read_image_features_get_size;
iso_read_image_features_has_eltorito;
iso_read_image_features_has_iso1999;
iso_read_image_features_has_joliet;
iso_read_image_features_has_rockridge;
iso_read_image_features_rr_loaded;
iso_read_image_features_text;
iso_read_image_features_tree_loaded;
iso_read_opts_auto_input_charset;
iso_read_opts_free;
iso_read_opts_keep_import_src;
iso_read_opts_load_system_area;
iso_read_opts_new;
iso_read_opts_set_default_gid;
iso_read_opts_set_default_permissions;
iso_read_opts_set_default_uid;
iso_read_opts_set_ecma119_map;
iso_read_opts_set_input_charset;
iso_read_opts_set_joliet_map;
iso_read_opts_set_new_inos;
iso_read_opts_set_no_aaip;
iso_read_opts_set_no_iso1999;
iso_read_opts_set_no_joliet;
iso_read_opts_set_no_md5;
iso_read_opts_set_no_rockridge;
iso_read_opts_set_preferjoliet;
iso_read_opts_set_start_block;
iso_ring_buffer_get_status;
iso_set_abort_severity;
iso_set_local_charset;
iso_set_msgs_severities;
iso_sev_to_text;
iso_special_get_dev;
iso_stream_clone;
iso_stream_close;
iso_stream_cmp_ino;
iso_stream_get_external_filter;
iso_stream_get_id;
iso_stream_get_input_stream;
iso_stream_get_size;
iso_stream_get_source_path;
iso_stream_get_zisofs_par;
iso_stream_is_repeatable;
iso_stream_open;
iso_stream_read;
iso_stream_ref;
iso_stream_unref;
iso_stream_update_size;
iso_stream_zisofs_discard_bpt;
iso_symlink_get_dest;
iso_symlink_set_dest;
iso_text_to_sev;
iso_tree_add_dir_rec;
iso_tree_add_exclude;
iso_tree_add_new_cut_out_node;
iso_tree_add_new_dir;
iso_tree_add_new_file;
iso_tree_add_new_node;
iso_tree_add_new_special;
iso_tree_add_new_symlink;
iso_tree_add_node;
iso_tree_clone;
iso_tree_get_follow_symlinks;
iso_tree_get_ignore_hidden;
iso_tree_get_ignore_special;
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;
iso_tree_set_replace_mode;
iso_tree_set_report_callback;
iso_truncate_leaf_name;
iso_util_decode_md5_tag;
iso_write_opts_attach_jte;
iso_write_opts_detach_jte;
iso_write_opts_free;
iso_write_opts_get_data_start;
iso_write_opts_new;
iso_write_opts_set_aaip;
iso_write_opts_set_aaip_susp_1_10;
iso_write_opts_set_allow_7bit_ascii;
iso_write_opts_set_allow_deep_paths;
iso_write_opts_set_allow_dir_id_ext;
iso_write_opts_set_allow_full_ascii;
iso_write_opts_set_allow_longer_paths;
iso_write_opts_set_allow_lowercase;
iso_write_opts_set_always_gmt;
iso_write_opts_set_appendable;
iso_write_opts_set_appended_as_apm;
iso_write_opts_set_appended_as_gpt;
iso_write_opts_set_default_dir_mode;
iso_write_opts_set_default_file_mode;
iso_write_opts_set_default_gid;
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_gpt_guid;
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_iso_mbr_part_type;
iso_write_opts_set_iso_type_guid;
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_max_ce_entries;
iso_write_opts_set_ms_block;
iso_write_opts_set_no_force_dots;
iso_write_opts_set_old_empty;
iso_write_opts_set_omit_version_numbers;
iso_write_opts_set_output_charset;
iso_write_opts_set_overwrite_buf;
iso_write_opts_set_part_offset;
iso_write_opts_set_part_like_isohybrid;
iso_write_opts_set_part_type_guid;
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;
iso_write_opts_set_replace_mode;
iso_write_opts_set_replace_timestamps;
iso_write_opts_set_rockridge;
iso_write_opts_set_rr_reloc;
iso_write_opts_set_rrip_1_10_px_ino;
iso_write_opts_set_rrip_version_1_10;
iso_write_opts_set_scdbackup_tag;
iso_write_opts_set_sort_files;
iso_write_opts_set_system_area;
iso_write_opts_set_tail_blocks;
iso_write_opts_set_untranslated_name_len;
iso_write_opts_set_will_cancel;
iso_zisofs_ctrl_susp_z2;
iso_zisofs_get_params;
iso_zisofs_get_refcounts;
iso_zisofs_set_params;
serial_id;
local: *;
};
LIBISOFS6_1.5.8 {
iso_local_create_dev;
iso_local_get_lfa_flags;
iso_local_get_projid;
iso_local_set_lfa_flags;
iso_local_set_projid;
iso_node_get_lfa_flags;
iso_node_get_projid;
iso_node_set_lfa_flags;
iso_node_set_projid;
iso_util_decode_lfa_flags;
iso_util_encode_lfa_flags;
iso_util_get_effective_lfa_mask;
iso_util_get_lfa_masks;
iso_write_opts_set_gpt_with_gaps;
iso_write_opts_set_rrip_tf_long;
} LIBISOFS6;

View File

@ -1,5 +1,28 @@
/*
* Copyright (c) 2002 - 2008 H. Peter Anvin
* Copyright (c) 2008 - 2022 Thomas Schmitt
* with special credits to Matthew Garrett for isohybrid with GPT and APM
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
* or later as published by the Free Software Foundation.
* See COPYING file for details.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include <ctype.h>
#ifdef HAVE_STDINT_H
#include <stdint.h>
#else
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#endif
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
@ -10,6 +33,14 @@
/* for gettimeofday() */
#include <sys/time.h>
#include "filesrc.h"
#include "ecma119.h"
#include "eltorito.h"
#include "system_area.h"
#include "image.h"
#include "messages.h"
/* This code stems from syslinux-3.72/utils/isohybrid, a perl script
under GPL which is Copyright 2002-2008 H. Peter Anvin.
@ -25,13 +56,13 @@ and is now under the licenses to which H.Peter Anvin agreed:
or both, at your option.
Sincerely, H. Peter Anvin
In the context of xorriso-standalone, this code is under GPLv2 derived from
LGPL. In the context of libisofs this code derives its matching open source
In the context of GNU xorriso, this code is under GPLv3+ derived from LGPL.
In the context of libisofs this code derives its matching free software
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-2009 libburnia project.
and 2008-2015 Thomas Schmitt
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
@ -51,8 +82,9 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* A helper function. One could replace it by one or two macros. */
static int lsb_to_buf(char **wpt, int value, int bits, int flag)
static int lsb_to_buf(char **wpt, uint32_t value, int bits, int flag)
{
int b;
@ -61,6 +93,11 @@ static int lsb_to_buf(char **wpt, int value, int bits, int flag)
return (1);
}
/* ====================================================================== */
/* Deprecated Function */
/* ====================================================================== */
/*
* Create a MBR for an isohybrid enabled ISOLINUX boot image.
*
@ -115,13 +152,12 @@ int make_isohybrid_mbr(int bin_lba, int *img_blocks, char *mbr, int flag)
static int h = 64, s = 32;
int i, warn_size = 0, id;
int i, id;
char *wpt;
off_t imgsize, cylsize, frac, padding, c, cc;
/* For generating a weak random number */
struct timeval tv;
struct timezone tz;
if (bin_lba < 0 || bin_lba >= (1 << 29))
return (0); /* 1 TB limit of signed 32 bit addressing of 512 byte blocks */
@ -144,7 +180,6 @@ int make_isohybrid_mbr(int bin_lba, int *img_blocks, char *mbr, int flag)
*img_blocks = imgsize / (off_t) 2048;
c = imgsize / cylsize;
if (c > 1024) {
warn_size = 1;
cc = 1024;
} else
cc = c;
@ -177,7 +212,7 @@ int make_isohybrid_mbr(int bin_lba, int *img_blocks, char *mbr, int flag)
from. An environment variable ?
125: Whatever, i use some 32-bit random value with no crypto strength.
*/
gettimeofday(&tv, &tz);
gettimeofday(&tv, NULL);
id = 0xffffffff & (tv.tv_sec ^ (tv.tv_usec * 2000));
/*
@ -228,3 +263,523 @@ int make_isohybrid_mbr(int bin_lba, int *img_blocks, char *mbr, int flag)
return (1);
}
/* ====================================================================== */
/* The New MBR Producer */
/* ====================================================================== */
/* The new MBR producer for isohybrid is a slightly generalized version of
the deprecated function make_isohybrid_mbr(). It complies to the urge
of H.Peter Anvin not to hardcode MBR templates but rather to read a
file from the Syslinux tree, and to patch it as was done with the old
MBR producer.
The old algorithm was clarified publicly by the following mail.
Changes towards the old algorithm:
- 512-byte LBA of boot image is extended to 64 bit (we stay with 32)
- check for a magic number is now gone
The new implementation tries to use similar terms as the mail in order
to facilitate its future discussion with Syslinux developers.
From hpa@zytor.com Thu Apr 1 08:32:52 2010
Date: Wed, 31 Mar 2010 14:53:51 -0700
From: H. Peter Anvin <hpa@zytor.com>
To: For discussion of Syslinux and tftp-hpa <syslinux@zytor.com>
Cc: Thomas Schmitt <scdbackup@gmx.net>
Subject: Re: [syslinux] port syslinux isohybrid perl script to C
[...]
[me:]
> Currently i lack of blob and prescriptions.
The blobs are available in the Syslinux build tree under the names:
mbr/isohdp[fp]x*.bin
The default probably should be mbr/isohdppx.bin, but it's ultimately up
to the user.
User definable parameters:
-> MBR ID (default random 32-bit number,
or preserved from previous instance)
-> Sector count (default 32, range 1-63)
-> Head count (default 64, range 1-256)
-> Partition offset (default 0, range 0-64)
-> Partition number (default 1, range 1-4)
-> Filesystem type (default 0x17, range 1-255)
Note: the filesystem type is largely arbitrary, in theory it can be any
value other than 0x00, 0x05, 0x0f, 0x85, 0xee, or 0xef. 0x17 ("Windows
IFS Hidden") seems safeish, some people believe 0x83 (Linux) is better.
Here is the prescriptions for how to install it:
All numbers are littleendian. "word" means 16 bits, "dword" means 32
bits, "qword" means 64 bits.
Common subroutine LBA_to_CHS():
s = (lba % sector_count) + 1
t = (lba / sector_count)
h = (t % head_count)
c = (t / head_count)
if (c >= 1024):
c = 1023
h = head_count
s = sector_count
s = s | ((c & 0x300) >> 2)
c = c & 0xff
write byte h
write byte s
write byte c
Main:
Pad image_size to a multiple of sector_count*head_count
Use the input file unmodified for bytes 0..431
write qword boot_lba # Offset 432
write dword mbr_id # Offset 440
write word 0 # Offset 444
# Offset 446
For each partition entry 1..4:
if this_partition != partition_number:
write 16 zero bytes
else:
write byte 0x80
write LBA_to_CHS(partition_offset)
write byte filesystem_type
write LBA_to_CHS(image_size-1)
write dword partition_offset
write dword image_size
# Offset 510
write word 0xaa55
Use the input file unmodified for bytes 512..32767
(pad with zero as necessary)
[...]
-hpa
*/
/* 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)
{
int s, t, h, c;
s = (lba % sector_count) + 1;
t = (lba / sector_count);
h = (t % head_count);
c = (t / head_count);
if (c >= 1024) {
c = 1023;
h = head_count; /* >>> not -1 ? Limits head_count to 255 */
s = sector_count;
}
s = s | ((c & 0x300) >> 2);
c = c & 0xff;
(*((unsigned char **) wpt))[0] = h;
(*((unsigned char **) wpt))[1] = s;
(*((unsigned char **) wpt))[2] = c;
(*wpt)+= 3;
return(1);
}
/* Find out whether GPT and APM are desired
flag bit0 = register APM and GPT requests in Ecma119Image
bit1 = do not asses and register APM
bit2 = do not register overall GPT partition
*/
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;
uint64_t start_block;
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, *type_guid;
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) &&
!(t->boot_appended_idx[i] >= 0 && t->opts->appended_as_gpt)) {
if (*gpt_count < 128)
gpt_idx[*gpt_count] = i;
(*gpt_count)++;
if ((flag & 1) &&
(t->bootsrc[i] != NULL || t->boot_appended_idx[i] >= 0)) {
/* 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;
if (t->boot_appended_idx[i] >= 0) {
block_count = t->appended_part_size[
t->boot_appended_idx[i]];
start_block = ((uint64_t) t->appended_part_start[
t->boot_appended_idx[i]]) * 4;
} else {
block_count = 0;
for (j = 0; j < t->bootsrc[i]->nsections; j++)
block_count += t->bootsrc[i]->sections[j].size / 2048;
start_block = ((uint64_t) t->bootsrc[i]->sections[0].block)
* 4;
}
ret = iso_quick_gpt_entry(
t->gpt_req, &(t->gpt_req_count),
start_block, ((uint64_t) block_count) * 4,
uuid, zero_uuid, gpt_flags, (uint8_t *) gpt_name);
if (ret < 0)
return ret;
}
}
if ((ilx_opts & 256) && !(flag & 2)) {
(*apm_count)++;
if ((flag & 1) &&
(t->bootsrc[i] != NULL || t->boot_appended_idx[i] >= 0)) {
/* Register APM entry */
if (t->boot_appended_idx[i] >= 0) {
block_count = t->appended_part_size[
t->boot_appended_idx[i]];
start_block = t->appended_part_start[
t->boot_appended_idx[i]];
} else {
block_count = 0;
for (j = 0; j < t->bootsrc[i]->nsections; j++)
block_count += t->bootsrc[i]->sections[j].size / 2048;
start_block = t->bootsrc[i]->sections[0].block;
}
ret = iso_quick_apm_entry(t->apm_req, &(t->apm_req_count),
(uint32_t) start_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 (*gpt_count > 0 && !(flag & 4)) {
(*gpt_count)++;
if (*gpt_count < 128)
gpt_idx[*gpt_count] = -1;
}
if ((flag & 1) && *gpt_count > 0 && !(flag & 4)) {
/* Register overall GPT partition */
memset(gpt_name, 0, 72);
sprintf((char *) gpt_name, "ISOHybrid");
iso_ascii_utf_16le(gpt_name);
if (t->opts->iso_gpt_flag & 1)
type_guid = t->opts->iso_gpt_type_guid;
else
type_guid = basic_data_uuid;
if (t->system_area_options & (1 << 16))
gpt_flags|= 4; /* Legacy BIOS bootable */
if (t->opts->system_area_options & (1 << 17))
gpt_flags &= ~(((uint64_t) 1) << 60); /* Not read-only */
/* Let it be open ended. iso_write_gpt() will truncate it as needed. */
block_count = 0xffffffff;
ret = iso_quick_gpt_entry(t->gpt_req, &(t->gpt_req_count),
(uint64_t) t->opts->partition_offset * 4,
((uint64_t) block_count) * 4,
type_guid, 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, skip = 0;
off_t hd_blocks;
static uint8_t dummy_chs[3] = {
0xfe, 0xff, 0xff,
};
if (gpt_idx[*gpt_cursor] < 0)
skip = 1;
else if (t->bootsrc[gpt_idx[*gpt_cursor]] == NULL)
skip = 1;
if (skip) {
(*gpt_cursor)++;
return 2;
}
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;
}
/* For generating a weak random number */
static uint32_t iso_make_mbr_id(Ecma119Image *t, int flag)
{
uint32_t id;
struct timeval tv;
if(t->opts->vol_uuid[0]) {
id = iso_crc32_gpt((unsigned char *) t->opts->vol_uuid, 16, 0);
} else if(t->opts->vol_modification_time > 0) {
id = iso_crc32_gpt((unsigned char *) &(t->opts->vol_modification_time),
sizeof(time_t), 0);
} else {
gettimeofday(&tv, NULL);
id = 0xffffffff & (tv.tv_sec ^ (tv.tv_usec * 2000));
}
return id;
}
/*
* @param flag bit0= make own random MBR Id from current time
* or from overridden modification time
* bit1= create protective MBR as of UEFI/GPT specs
* bit2= write only partition table
* do not insert APM mockup head
* do not treat bytes before code as isohybrid MBR
* do not create MBR id
* bit3= replace fs_type 0x00 by 0x17 if appropriate
*/
int make_isolinux_mbr(uint32_t *img_blocks, Ecma119Image *t,
int part_offset, int part_number, int fs_type,
uint8_t *buf, int flag)
{
uint32_t id, part, nominal_part_size, mbr_part_start;
off_t hd_img_blocks, hd_boot_lba;
char *wpt, *fs_type_wpt = NULL;
uint32_t boot_lba;
int head_count, sector_count, ret, part_is_in_img = 0;
int gpt_count = 0, gpt_idx[128], apm_count = 0, gpt_cursor, i;
if (t->bootsrc[0] == NULL)
return iso_msg_submit(t->image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
"Cannot refer by isohybrid MBR to data outside of ISO 9660 filesystem.");
for (i = 0; i < 128; i++)
gpt_idx[i] = -1;
if (flag & 2) {
part_number = 1;
part_offset = 1;
}
hd_img_blocks = ((off_t) *img_blocks) * (off_t) 4 -
t->post_iso_part_pad / 512;
boot_lba = t->bootsrc[0]->sections[0].block;
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;
if(flag & 4) {
wpt= (char *) buf + 446;
} else {
/* 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.
*/
wpt = (char *) buf + 432;
/* write qword boot_lba # Offset 432
*/
hd_boot_lba = ((off_t) boot_lba) * (off_t) 4;
lsb_to_buf(&wpt, hd_boot_lba & 0xffffffff, 32, 0);
lsb_to_buf(&wpt, hd_boot_lba >> 32, 32, 0);
/* write dword mbr_id # Offset 440
(here some 32-bit random value with no crypto strength)
*/
if (flag & 1) {
id = iso_make_mbr_id(t, 0);
lsb_to_buf(&wpt, id, 32, 0);
} else {
wpt+= 4;
}
/* write word 0 # Offset 444
*/
lsb_to_buf(&wpt, 0, 16, 0);
}
/* # 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
(this is now overridden 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;
}
/* Will this hit the part_number partition ? */
mbr_part_start = iso_read_lsb((uint8_t *) (wpt + 8), 4);
if (mbr_part_start > 0 &&
mbr_part_start < hd_img_blocks + part_offset)
part_is_in_img = 1;
wpt+= 16;
continue;
}
/* write byte 0x80 if bootable
write LBA_to_CHS(partition_offset)
write byte filesystem_type
write LBA_to_CHS(image_size-1)
write dword partition_offset
write dword image_size
*/
if (flag & 2)
lsb_to_buf(&wpt, 0x00, 8, 0);
else
lsb_to_buf(&wpt, 0x80, 8, 0);
lba512chs_to_buf(&wpt, part_offset, head_count, sector_count);
fs_type_wpt = wpt;
lsb_to_buf(&wpt, fs_type, 8, 0);
lba512chs_to_buf(&wpt, hd_img_blocks - 1, head_count, sector_count);
lsb_to_buf(&wpt, part_offset, 32, 0);
if (hd_img_blocks - (off_t) part_offset > (off_t) 0xffffffff)
nominal_part_size = 0xffffffff;
else
nominal_part_size = hd_img_blocks - (off_t) part_offset;
lsb_to_buf(&wpt, nominal_part_size, 32, 0);
}
/* write word 0xaa55 # Offset 510
*/
lsb_to_buf(&wpt, 0xaa55, 16, 0);
/* Check whether automatically determined fs_type 0x00 can become 0x17 */
if ((flag & 8) && fs_type_wpt != NULL && fs_type == 0x00 &&
t->opts->iso_mbr_part_type != fs_type && !part_is_in_img) {
if (t->opts->iso_mbr_part_type >= 0 &&
t->opts->iso_mbr_part_type <= 255) {
lsb_to_buf(&fs_type_wpt, t->opts->iso_mbr_part_type, 8, 0);
} else {
lsb_to_buf(&fs_type_wpt, 0x17, 8, 0);
}
}
return(1);
}

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
@ -8,7 +8,18 @@
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
#else
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#endif
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
@ -218,10 +229,10 @@ static int md5_init(libisofs_md5_ctx *ctx, int flag)
static int md5_update(libisofs_md5_ctx *ctx, unsigned char *data,
int datalen, int flag)
{
unsigned int i, index, partlen;
int i, index, partlen;
/* Compute number of bytes mod 64 */
index = (unsigned int)((ctx->count[0] >> 3) & 0x3F);
index = ((ctx->count[0] >> 3) & 0x3F);
/* Update number of bits */
if ((ctx->count[0] += ((uint32_t) datalen << 3)) <
((uint32_t) datalen << 3))
@ -413,6 +424,22 @@ int checksum_cx_xinfo_func(void *data, int flag)
return 1;
}
/* The iso_node_xinfo_cloner function which gets associated to
* checksum_cx_xinfo_func by iso_init() resp. iso_init_with_flag() via
* iso_node_xinfo_make_clonable()
*/
int checksum_cx_xinfo_cloner(void *old_data, void **new_data, int flag)
{
*new_data = NULL;
if (flag)
return ISO_XINFO_NO_CLONE;
if (old_data == NULL)
return 0;
/* data is an int disguised as pointer. It does not point to memory. */
*new_data = old_data;
return 0;
}
/* Function to identify and manage md5 sums of unspecified providence stored
* directly in this xinfo.
@ -425,13 +452,29 @@ int checksum_md5_xinfo_func(void *data, int flag)
return 1;
}
/* The iso_node_xinfo_cloner function which gets associated to
* checksum_md5_xinfo_func by iso_init() resp. iso_init_with_flag() via
* iso_node_xinfo_make_clonable()
*/
int checksum_md5_xinfo_cloner(void *old_data, void **new_data, int flag)
{
*new_data = NULL;
if (flag)
return ISO_XINFO_NO_CLONE;
if (old_data == NULL)
return 0;
*new_data = calloc(1, 16);
if (*new_data == NULL)
return ISO_OUT_OF_MEM;
memcpy(*new_data, old_data, 16);
return 16;
}
/* ----------------------------------------------------------------------- */
/* MD5 checksum image writer */
#ifdef Libisofs_with_checksumS
/*
@flag bit0= recursion
bit1= session will be appended to an existing image
@ -454,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 */
@ -484,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) {
@ -508,15 +557,10 @@ int checksum_copy_old_nodes(Ecma119Image *target, IsoNode *node, int flag)
return ISO_SUCCESS;
}
#endif /* Libisofs_with_checksumS */
static
int checksum_writer_compute_data_blocks(IsoImageWriter *writer)
{
#ifdef Libisofs_with_checksumS
size_t size;
Ecma119Image *t;
int ret;
@ -527,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++;
@ -557,9 +601,6 @@ int checksum_writer_compute_data_blocks(IsoImageWriter *writer)
t->checksum_idx_counter + 2, 16, "MD5", 0);
if (ret < 0)
return ret;
#endif /* Libisofs_with_checksumS */
return ISO_SUCCESS;
}
@ -580,20 +621,12 @@ int checksum_writer_write_vol_desc(IsoImageWriter *writer)
static
int checksum_writer_write_data(IsoImageWriter *writer)
{
#ifdef Libisofs_with_checksumS
int wres, res;
size_t i, size;
Ecma119Image *t;
void *ctx = NULL;
char md5[16];
#ifdef NIX
char tag_block[2048];
int l;
#endif
if (writer == NULL) {
return ISO_ASSERT_FAILURE;
}
@ -649,12 +682,6 @@ ex:;
if (ctx != NULL)
iso_md5_end(&ctx, md5);
return(res);
#else /* Libisofs_with_checksumS */
return ISO_SUCCESS;
#endif /* ! Libisofs_with_checksumS */
}
@ -684,17 +711,11 @@ int checksum_writer_create(Ecma119Image *target)
/* add this writer to image */
target->writers[target->nwriters++] = writer;
#ifdef Libisofs_with_checksumS
/* 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++;
}
#endif /* Libisofs_with_checksumS */
return ISO_SUCCESS;
}
@ -702,20 +723,18 @@ int checksum_writer_create(Ecma119Image *target)
static
int iso_md5_write_scdbackup_tag(Ecma119Image *t, char *tag_block, int flag)
{
#ifdef Libisofs_with_checksumS
void *ctx = NULL;
off_t pos = 0, line_start;
int record_len, block_len, res, i;
char postext[40], md5[16], record[160];
int record_len, block_len, ret, i;
char postext[40], md5[16], *record = NULL;
LIBISO_ALLOC_MEM(record, char, 160);
line_start = strlen(tag_block);
iso_md5_compute(t->checksum_ctx, tag_block, line_start);
res = iso_md5_clone(t->checksum_ctx, &ctx);
if (res < 0)
ret = iso_md5_clone(t->checksum_ctx, &ctx);
if (ret < 0)
goto ex;
res = iso_md5_end(&ctx, md5);
ret = iso_md5_end(&ctx, md5);
pos = (off_t) t->checksum_tag_pos * (off_t) 2048 + line_start;
if(pos >= 1000000000)
@ -723,15 +742,15 @@ 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,
"%2.2x", ((unsigned char *) md5)[i]);
record_len += 32;
res = iso_md5_start(&ctx);
if (res < 0)
ret = iso_md5_start(&ctx);
if (ret < 0)
goto ex;
iso_md5_compute(ctx, record, record_len);
iso_md5_end(&ctx, md5);
@ -745,20 +764,15 @@ 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);
res = ISO_SUCCESS;
ret = ISO_SUCCESS;
ex:;
if (ctx != NULL)
iso_md5_end(&ctx, md5);
return res;
#else
return ISO_SUCCESS;
#endif /* Libisofs_with_checksumS */
LIBISO_FREE_MEM(record);
return ret;
}
@ -767,28 +781,25 @@ ex:;
* 1= session tag (End checksumming.)
* 2= superblock tag (System Area and Volume Descriptors)
* 3= tree tag (ECMA-119 and Rock Ridge tree)
* 4= relocated superblock tag (at LBA 0 of overwriteable media)
* 4= relocated superblock tag (at LBA 0 of overwritable media)
* Write to target->opts_overwrite rather than to iso_write().
*/
int iso_md5_write_tag(Ecma119Image *t, int flag)
{
#ifdef Libisofs_with_checksumS
int res, mode, l, i, wres, tag_id_len;
int ret, mode, l, i, wres, tag_id_len;
void *ctx = NULL;
char md5[16], tag_block[2048], *tag_id;
char md5[16], *tag_block = NULL, *tag_id;
uint32_t size = 0, pos = 0, start;
LIBISO_ALLOC_MEM(tag_block, char, 2048);
start = t->checksum_range_start;
memset(tag_block, 0, 2048);
mode = flag & 255;
if (mode < 1 || mode > 4)
return ISO_WRONG_ARG_VALUE;
res = iso_md5_clone(t->checksum_ctx, &ctx);
if (res < 0)
return res;
res = iso_md5_end(&ctx, md5);
{ret = ISO_WRONG_ARG_VALUE; goto ex;}
ret = iso_md5_clone(t->checksum_ctx, &ctx);
if (ret < 0)
goto ex;
ret = iso_md5_end(&ctx, md5);
if (mode == 1) {
size = t->checksum_range_size;
pos = t->checksum_tag_pos;
@ -803,7 +814,7 @@ int iso_md5_write_tag(Ecma119Image *t, int flag)
}
size = pos - start;
}
if (res < 0)
if (ret < 0)
goto ex;
iso_util_tag_magic(mode, &tag_id, &tag_id_len, 0);
@ -816,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);
@ -825,8 +836,8 @@ int iso_md5_write_tag(Ecma119Image *t, int flag)
((unsigned char *) md5)[i]);
l+= 32;
res = iso_md5_start(&ctx);
if (res > 0) {
ret = iso_md5_start(&ctx);
if (ret > 0) {
iso_md5_compute(ctx, tag_block, l);
iso_md5_end(&ctx, md5);
strcpy(tag_block + l, " self=");
@ -837,12 +848,12 @@ 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 {
res = iso_md5_write_scdbackup_tag(t, tag_block, 0);
if (res < 0)
ret = iso_md5_write_scdbackup_tag(t, tag_block, 0);
if (ret < 0)
goto ex;
}
}
@ -853,23 +864,17 @@ int iso_md5_write_tag(Ecma119Image *t, int flag)
} else {
wres = iso_write(t, tag_block, 2048);
if (wres < 0) {
res = wres;
ret = wres;
goto ex;
}
}
res = ISO_SUCCESS;
ret = ISO_SUCCESS;
ex:;
if (ctx != NULL)
iso_md5_end(&ctx, md5);
return res;
#else /* Libisofs_with_checksumS */
return ISO_SUCCESS;
#endif /* ! Libisofs_with_checksumS */
LIBISO_FREE_MEM(tag_block);
return ret;
}

View File

@ -1,22 +1,44 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2023 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 <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#ifdef Xorriso_standalonE
#ifdef Xorriso_with_libjtE
#include "../libjte/libjte.h"
#endif
#else
#ifdef Libisofs_with_libjtE
#include <libjte/libjte.h>
#endif
#endif /* ! Xorriso_standalonE */
#include "libiso_msgs.h"
#include "libisofs.h"
#include "messages.h"
#include "util.h"
#include "node.h"
#include "stream.h"
/*
@ -60,11 +82,111 @@ int abort_threshold = LIBISO_MSGS_SEV_FAILURE;
struct libiso_msgs *libiso_msgr = NULL;
/* ------------- List of xinfo clone functions ----------- */
struct iso_xinfo_cloner_assoc {
iso_node_xinfo_func proc;
iso_node_xinfo_cloner cloner;
struct iso_xinfo_cloner_assoc *next;
};
struct iso_xinfo_cloner_assoc *iso_xinfo_cloner_list = NULL;
/* API */
int iso_node_xinfo_make_clonable(iso_node_xinfo_func proc,
iso_node_xinfo_cloner cloner, int flag)
{
struct iso_xinfo_cloner_assoc *assoc;
/* Look for existing assoc of proc */
for (assoc = iso_xinfo_cloner_list; assoc != NULL; assoc = assoc->next)
if (assoc->proc == proc)
break;
if (assoc == NULL) {
assoc = calloc(1, sizeof(struct iso_xinfo_cloner_assoc));
if (assoc == NULL)
return ISO_OUT_OF_MEM;
assoc->proc = proc;
assoc->next = iso_xinfo_cloner_list;
iso_xinfo_cloner_list = assoc;
}
assoc->cloner = cloner;
return ISO_SUCCESS;
}
/* API */
int iso_node_xinfo_get_cloner(iso_node_xinfo_func proc,
iso_node_xinfo_cloner *cloner, int flag)
{
struct iso_xinfo_cloner_assoc *assoc;
*cloner = NULL;
for (assoc = iso_xinfo_cloner_list; assoc != NULL; assoc = assoc->next) {
if (assoc->proc != proc)
continue;
*cloner = assoc->cloner;
return 1;
}
return 0;
}
static
int iso_node_xinfo_dispose_cloners(int flag)
{
struct iso_xinfo_cloner_assoc *assoc, *next;
for (assoc = iso_xinfo_cloner_list; assoc != NULL; assoc = next) {
next = assoc->next;
free((char *) assoc);
}
iso_xinfo_cloner_list= NULL;
return(1);
}
/* ------------- End of xinfo clone functions list ----------- */
/*
@param flag bit0= do not set up locale by LC_* environment variables
*/
int iso_init_with_flag(int flag)
{
int ret;
#ifdef Libisofs_with_libjtE
/* Ugly compile time check for header version compatibility.
If everything matches, then it produces no C code. In case of mismatch,
intentionally faulty C code will be inserted.
*/
/* The indentation is an advise of man gcc to help old compilers ignoring */
#if iso_libjte_req_major > LIBJTE_VERSION_MAJOR
#define Libisofs_libjte_dot_h_too_olD 1
#endif
#if iso_libjte_req_major == LIBJTE_VERSION_MAJOR && iso_libjte_req_minor > LIBJTE_VERSION_MINOR
#define Libisofs_libjte_dot_h_too_olD 1
#endif
#if iso_libjte_req_minor == LIBJTE_VERSION_MINOR && iso_libjte_req_micro > LIBJTE_VERSION_MICRO
#define Libisofs_libjte_dot_h_too_olD 1
#endif
#ifdef Libisofs_libjte_dot_h_too_olD
LIBJTE_MISCONFIGURATION = 0;
INTENTIONAL_ABORT_OF_COMPILATION__HEADERFILE_libjte_dot_h_TOO_OLD__SEE_libisofs_dot_h_AND_messages_c = 0;
LIBJTE_MISCONFIGURATION_ = 0;
#endif
if (! libjte__is_compatible(LIBJTE_VERSION_MAJOR, LIBJTE_VERSION_MINOR,
LIBJTE_VERSION_MICRO, 0)) {
fprintf(stderr,
"\nlibisofs: libjte TOO OLD ! Need at least libjte-%d.%d.%d\n\n",
LIBJTE_VERSION_MAJOR, LIBJTE_VERSION_MINOR,
LIBJTE_VERSION_MICRO);
return ISO_FATAL_ERROR;
}
#endif /* Libisofs_with_libjtE */
if (! (flag & 1)) {
iso_init_locale(0);
@ -75,10 +197,33 @@ int iso_init_with_flag(int flag)
}
libiso_msgs_set_severities(libiso_msgr, LIBISO_MSGS_SEV_NEVER,
LIBISO_MSGS_SEV_FATAL, "libisofs: ", 0);
ret = iso_node_xinfo_make_clonable(aaip_xinfo_func, aaip_xinfo_cloner, 0);
if (ret < 0)
return ret;
ret = iso_node_xinfo_make_clonable(checksum_cx_xinfo_func,
checksum_cx_xinfo_cloner, 0);
if (ret < 0)
return ret;
ret = iso_node_xinfo_make_clonable(checksum_md5_xinfo_func,
checksum_md5_xinfo_cloner, 0);
if (ret < 0)
return ret;
ret = iso_node_xinfo_make_clonable(zisofs_zf_xinfo_func,
zisofs_zf_xinfo_cloner, 0);
if (ret < 0)
return ret;
ret = iso_node_xinfo_make_clonable(iso_px_ino_xinfo_func,
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;
}
int iso_init()
{
return iso_init_with_flag(0);
@ -87,6 +232,8 @@ int iso_init()
void iso_finish()
{
libiso_msgs_destroy(&libiso_msgr, 0);
iso_node_xinfo_dispose_cloners(0);
iso_stream_destroy_cmpranks(0);
}
int iso_set_abort_severity(char *severity)
@ -105,15 +252,18 @@ int iso_set_abort_severity(char *severity)
void iso_msg_debug(int imgid, const char *fmt, ...)
{
char msg[MAX_MSG_LEN];
char *msg = NULL;
va_list ap;
LIBISO_ALLOC_MEM_VOID(msg, char, MAX_MSG_LEN);
va_start(ap, fmt);
vsnprintf(msg, MAX_MSG_LEN, fmt, ap);
va_end(ap);
libiso_msgs_submit(libiso_msgr, imgid, 0x00000002, LIBISO_MSGS_SEV_DEBUG,
LIBISO_MSGS_PRIO_ZERO, msg, 0, 0);
ex:;
LIBISO_FREE_MEM(msg);
}
const char *iso_error_to_msg(int errcode)
@ -153,6 +303,8 @@ const char *iso_error_to_msg(int errcode)
return "Try to set the boot image of an already bootable image";
case ISO_BOOT_IMAGE_NOT_VALID:
return "Trying to use an invalid file as boot image";
case ISO_BOOT_IMAGE_OVERFLOW:
return "Too many boot images added";
case ISO_FILE_ERROR:
return "Error on file operation";
case ISO_FILE_ALREADY_OPENED:
@ -195,9 +347,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:
@ -211,9 +363,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:
@ -228,7 +380,7 @@ const char *iso_error_to_msg(int errcode)
case ISO_DATA_SOURCE_MISHAP:
case ISO_DATA_SOURCE_FAILURE:
case ISO_DATA_SOURCE_FATAL:
return "Read error occured with IsoDataSource";
return "Read error occurred with IsoDataSource";
case ISO_AAIP_IGNORED:
return "AAIP info with ACL or xattr in ISO image will be ignored";
case ISO_AAIP_BAD_ACL:
@ -240,9 +392,11 @@ const char *iso_error_to_msg(int errcode)
case ISO_AAIP_BAD_AASTRING:
return "Error with decoding AAIP info for ACL or xattr";
case ISO_AAIP_NO_GET_LOCAL:
return "Error with reading ACL or xattr from local file";
case ISO_AAIP_NO_GET_LOCAL_S:
return "Error with reading ACL or other attributes from local file";
case ISO_AAIP_NO_SET_LOCAL:
return "Error with attaching ACL or xattr to local file";
case ISO_AAIP_NO_SET_LOCAL_S:
return "Error with attaching ACL or other attributes to local file";
case ISO_AAIP_NON_USER_NAME:
return "Unallowed attempt to set an xattr with non-userspace name";
case ISO_EXTF_TOO_OFTEN:
@ -250,13 +404,13 @@ const char *iso_error_to_msg(int errcode)
case ISO_ZLIB_NOT_ENABLED:
return "Use of zlib was not enabled at compile time";
case ISO_ZISOFS_TOO_LARGE:
return "Cannot apply zisofs filter to file >= 4 GiB";
return "File too large. Cannot apply zisofs filter.";
case ISO_FILTER_WRONG_INPUT:
return "Filter input differs from previous run";
case ISO_ZLIB_COMPR_ERR:
return "zlib compression/decompression error";
case ISO_ZISOFS_WRONG_INPUT:
return "Input stream is not in zisofs format";
return "Input stream is not in a supported zisofs format";
case ISO_ZISOFS_PARAM_LOCK:
return "Cannot set global zisofs parameters while filters exist";
case ISO_ZLIB_EARLY_EOF:
@ -277,6 +431,176 @@ const char *iso_error_to_msg(int errcode)
return "Detected file content changes while it was written into the image";
case ISO_SCDBACKUP_TAG_NOT_0:
return "Session does not start at LBA 0. scdbackup checksum tag not written.";
case ISO_BOOT_NO_CATALOG:
return "No boot catalog created yet";
case ISO_OVWRT_MS_TOO_SMALL:
return "Multi-session offset too small for overwrite buffer";
case ISO_PART_OFFST_TOO_SMALL:
return "Partition offset too small for first tree root.";
case ISO_OVWRT_FIFO_TOO_SMALL:
return "The ring buffer is too small for overwrite buffer";
case ISO_LIBJTE_NOT_ENABLED:
return "Use of libjte was not enabled at compile time";
case ISO_LIBJTE_START_FAILED:
return "Failed to start up Jigdo Template Extraction";
case ISO_LIBJTE_END_FAILED:
return "Failed to finish Jigdo Template Extraction";
case ISO_LIBJTE_FILE_FAILED:
return "Failed to process file for Jigdo Template Extraction";
case ISO_BOOT_TOO_MANY_MIPS:
return "Too many MIPS Big Endian boot files given (max. 15)";
case ISO_BOOT_FILE_MISSING:
return "Boot file missing in image";
case ISO_BAD_PARTITION_NO:
return "Partition number out of range";
case ISO_BAD_PARTITION_FILE:
return "Cannot open data file for appended partition";
case ISO_NON_MBR_SYS_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:
return "File name cannot be written into ECMA-119 untranslated";
case ISO_STREAM_NO_CLONE:
return "Data file input stream object offers no cloning method";
case ISO_XINFO_NO_CLONE:
return "Extended information class offers no cloning method";
case ISO_MD5_TAG_COPIED:
return "Found copied superblock checksum tag";
case ISO_RR_NAME_TOO_LONG:
return "Rock Ridge leaf name too long";
case ISO_RR_NAME_RESERVED:
return "Reserved Rock Ridge leaf name";
case ISO_RR_PATH_TOO_LONG:
return "Rock Ridge path too long";
case ISO_AAIP_BAD_ATTR_NAME:
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";
case ISO_SYSAREA_PROBLEMS:
return "Problems encountered during inspection of System Area";
case ISO_INQ_SYSAREA_PROP:
return "Unrecognized inquiry for system area property";
case ISO_ALPHA_BOOT_NOTREG:
return "DEC Alpha Boot Loader file is not a data file";
case ISO_NO_KEPT_DATA_SRC:
return "No data source of imported ISO image available";
case ISO_MALFORMED_READ_INTVL:
return "Malformed description string for interval reader";
case ISO_INTVL_READ_PROBLEM:
return "Unreadable file, premature EOF, or failure to seek for interval reader";
case ISO_NOT_REPRODUCIBLE:
return "Cannot arrange content of data files in surely reproducible way";
case ISO_PATCH_FILTERED_BOOT:
return "May not write boot info into filtered stream of boot image";
case ISO_PATCH_OVERSIZED_BOOT:
return "Boot image to large to buffer for writing boot info";
case ISO_RR_NAME_TRUNCATED:
return "File name had to be truncated and MD5 marked";
case ISO_TRUNCATE_ISOFSNT:
return "File name truncation length changed by loaded image info";
case ISO_GENERAL_NOTE:
return "A general note message was issued";
case ISO_BAD_FSRC_FILETYPE:
return "Unrecognized file type of IsoFileSrc object";
case ISO_GPT_NO_VOL_UUID:
return "Cannot derive GPT GUID from undefined pseudo-UUID volume timestamp";
case ISO_BAD_GPT_GUID_MODE:
return "Unrecognized GPT disk GUID setup mode";
case ISO_NO_ROOT_DIR:
return "Unable to obtain root directory";
case ISO_SUSP_WRONG_CE_SIZE:
return "Zero sized, oversized, or mislocated SUSP CE area found";
case ISO_MULTI_OVER_IMPORTED:
return "Multi-session would overwrite imported_iso interval";
case ISO_ELTO_EFI_HIDDEN:
return "El-Torito EFI image is hidden";
case ISO_HFSPLUS_TOO_MANY_FILES:
return "Too many files in HFS+ directory tree";
case ISO_ZISOFS_TOO_MANY_PTR:
return "Too many zisofs block pointers needed overall";
case ISO_ZISOFS_BPT_UNDERRUN:
return "Prevented zisofs block pointer counter underrun";
case ISO_ZISOFS_UNKNOWN_SIZE:
return "Cannot obtain size of zisofs compressed stream";
case ISO_UNDEF_READ_FEATURE:
return "Undefined IsoReadImageFeatures name";
case ISO_TOO_MANY_CE:
return "Too many CE entries for single file";
case ISO_TOO_MANY_CE_FOR_LINUX:
return "Too many CE entries for single file when mounted by Linux";
case ISO_CE_REMOVING_ATTR:
return "Too many CE entries for single file, removing attributes";
case ISO_LFA_UNKNOWN_LETTER:
return "Unknown Linux-like chattr letter encountered during conversion";
case ISO_LFA_UNKNOWN_BIT:
return "Unknown Linux-like file attribute flag bit encountered during conversion";
case ISO_LFA_NOT_ENABLED:
return "Local Linux-like file attribute processing not enabled at compile time";
case ISO_LFA_NO_GET_LOCAL:
return "Error with getting Linux-like file attributes of local file";
case ISO_LFA_NO_SET_LOCAL:
return "Error with setting Linux-like file attributes of local file";
case ISO_LFA_NO_OPEN_LOCAL:
return "Failure to open local file for Linux-like file attributes";
case ISO_PROJID_NOT_ENABLED:
return "Local XFS-style file project id processing not enabled at compile time";
case ISO_PROJID_NO_GET_LOCAL:
return "Error with getting XFS-style project id of local file";
case ISO_PROJID_NO_SET_LOCAL:
return "Error with setting XFS-style project id of local file";
case ISO_PROJID_NO_OPEN_LOCAL:
return "Failure to open local file for XFS-style project id";
case ISO_DIR_REC_SIZE_MISMATCH:
return "Size calculation mismatch with directory record or continuation area";
case ISO_INSANE_CE_SIZE:
return "More than 4294967295 bytes of Continuation area";
case ISO_DEV_NOT_CREATED:
return "Creation of device file in local filesystem failed";
case ISO_DEV_NO_CREATION:
return "Creation of device file type in local filesystem not enabled";
default:
return "Unknown error";
}
@ -296,7 +620,7 @@ int iso_msg_submit(int imgid, int errcode, int causedby, const char *fmt, ...)
va_list ap;
/* when called with ISO_CANCELED, we don't need to submit any message */
if (errcode == ISO_CANCELED && fmt == NULL) {
if (errcode == (int) ISO_CANCELED && fmt == NULL) {
return ISO_CANCELED;
}
@ -305,7 +629,8 @@ int iso_msg_submit(int imgid, int errcode, int causedby, const char *fmt, ...)
vsnprintf(msg, MAX_MSG_LEN, fmt, ap);
va_end(ap);
} else {
strncpy(msg, iso_error_to_msg(errcode), MAX_MSG_LEN);
strncpy(msg, iso_error_to_msg(errcode), MAX_MSG_LEN - 1);
msg[MAX_MSG_LEN - 1] = 0;
}
libiso_msgs_submit(libiso_msgr, imgid, ISO_ERR_CODE(errcode),
@ -417,8 +742,6 @@ int iso_obtain_msgs(char *minimum_severity, int *error_code, int *imgid,
}
/* ts A80222 : derived from libburn/init.c:burn_msgs_submit()
*/
int iso_msgs_submit(int error_code, char msg_text[], int os_errno,
char severity[], int origin)
{
@ -446,8 +769,6 @@ int iso_msgs_submit(int error_code, char msg_text[], int os_errno,
}
/* ts A80222 : derived from libburn/init.c:burn_text_to_sev()
*/
int iso_text_to_sev(char *severity_name, int *sevno)
{
int ret;
@ -459,8 +780,6 @@ int iso_text_to_sev(char *severity_name, int *sevno)
}
/* ts A80222 : derived from libburn/init.c:burn_sev_to_text()
*/
int iso_sev_to_text(int severity_number, char **severity_name)
{
int ret;
@ -499,7 +818,6 @@ int iso_error_get_code(int e)
}
/* ts A80222 */
int iso_report_errfile(char *path, int error_code, int os_errno, int flag)
{
libiso_msgs_submit(libiso_msgr, 0, error_code,
@ -507,3 +825,33 @@ int iso_report_errfile(char *path, int error_code, int os_errno, int flag)
path, os_errno, 0);
return(1);
}
int iso_libjte_forward_msgs(void *libjte_handle,
int imgid, int errcode, int flag)
{
#ifdef Libisofs_with_libjtE
char *msg = NULL;
int res;
struct libjte_env *handle = (struct libjte_env *) libjte_handle;
res = ISO_SUCCESS;
while(1) {
msg= libjte_get_next_message(handle);
if(msg == NULL)
break;
res = iso_msg_submit(imgid, errcode, 0, msg);
free(msg);
}
return res;
#else /* Libisofs_with_libjtE */
return ISO_SUCCESS;
#endif /* ! Libisofs_with_libjtE */
}

View File

@ -46,7 +46,6 @@ int iso_msg_is_abort(int errcode);
int iso_msg_submit(int imgid, int errcode, int causedby, const char *fmt, ...);
/* ts A80222 */
/* To be called with events which report incidents with individual input
files from the local filesystem. Not with image nodes, files containing an
image or similar file-like objects.
@ -54,4 +53,10 @@ int iso_msg_submit(int imgid, int errcode, int causedby, const char *fmt, ...);
int iso_report_errfile(char *path, int error_code, int os_errno, int flag);
/* Drains the libjte message list and puts out the messages via
iso_msg_submit()
*/
int iso_libjte_forward_msgs(void *libjte_handle,
int imgid, int errcode, int flag);
#endif /*MESSAGES_H_*/

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 - 2023 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
@ -20,7 +20,38 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#ifdef HAVE_STDINT_H
#include <stdint.h>
#else
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#endif
/* Maximum length of a leaf name in the libisofs node tree. This is currently
restricted by the implemented maximum length of a Rock Ridge name.
This might later become larger and may then be limited to smaller values.
Rock Ridge specs do not impose an explicit limit on name length.
But 255 is also specified by
http://pubs.opengroup.org/onlinepubs/009695399/basedefs/limits.h.html
which says
NAME_MAX >= _XOPEN_NAME_MAX = 255
*/
#define LIBISOFS_NODE_NAME_MAX 255
/* Maximum length of a path in the libisofs node tree.
Rock Ridge specs do not impose an explicit limit on path length.
http://pubs.opengroup.org/onlinepubs/009695399/basedefs/limits.h.html
says
PATH_MAX >= _XOPEN_PATH_MAX = 1024
*/
#define LIBISOFS_NODE_PATH_MAX 1024
/**
* The extended information is a way to attach additional information to each
@ -113,12 +144,20 @@ struct Iso_Dir
IsoNode *children; /**< list of children. ptr to first child */
};
/* IMPORTANT: Any change must be reflected by iso_tree_clone_file. */
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
@ -245,7 +284,7 @@ int iso_node_new_symlink(char *name, char *dest, IsoSymlink **link);
* Create a new special file node. As far as libisofs concerns,
* an special file is a block device, a character device, a FIFO (named pipe)
* or a socket. You can choose the specific kind of file you want to add
* by setting mode propertly (see man 2 stat).
* by setting mode properly (see man 2 stat).
*
* Note that special files are only written to image when Rock Ridge
* extensions are enabled. Moreover, a special file is just a directory entry
@ -277,7 +316,7 @@ int iso_node_new_special(char *name, mode_t mode, dev_t dev,
* Check if a given name is valid for an iso node.
*
* @return
* 1 if yes, 0 if not
* 1 if yes, <0 if not. The value is a specific ISO_* error code.
*/
int iso_node_is_valid_name(const char *name);
@ -383,6 +422,12 @@ int iso_aa_get_attrs(unsigned char *aa_string, size_t *num_attrs,
int iso_aa_lookup_attr(unsigned char *aa_string, char *name,
size_t *value_length, char **value, int flag);
/**
* Delete variables of all namespaces except isofs
*
* @param flag bit0= delete ACL, too
*/
int iso_node_remove_fattr(IsoNode *node, int flag);
/**
* Function to identify and manage ZF parameters which do not stem from ZF
@ -398,9 +443,10 @@ int zisofs_zf_xinfo_func(void *data, int flag);
* Parameter structure which is to be managed by zisofs_zf_xinfo_func.
*/
struct zisofs_zf_info {
uint32_t uncompressed_size;
uint64_t uncompressed_size;
uint8_t header_size_div4;
uint8_t block_size_log2;
uint8_t zisofs_algo[2];
};
/**
@ -448,7 +494,7 @@ int iso_node_cmp_flag(IsoNode *n1, IsoNode *n2, int flag);
/**
* Set the checksum index (typically comming from IsoFileSrc.checksum_index)
* Set the checksum index (typically coming from IsoFileSrc.checksum_index)
* of a regular file node. The index is encoded as xattr "isofs.cx" with
* four bytes of value.
*/
@ -473,4 +519,51 @@ int iso_root_get_isofsca(IsoNode *node, uint32_t *start_lba, uint32_t *end_lba,
int flag);
/**
* Record and get truncation parameters as of iso_image_set_truncate_mode() by
* "isofs.nt".
*/
int iso_root_set_isofsnt(IsoNode *node, uint32_t truncate_mode,
uint32_t truncate_length, int flag);
int iso_root_get_isofsnt(IsoNode *node, uint32_t *truncate_mode,
uint32_t *truncate_length, int flag);
/**
* Copy the xinfo list from one node to the another.
*/
int iso_node_clone_xinfo(IsoNode *from_node, IsoNode *to_node, int flag);
/**
* The iso_node_xinfo_func instance which governs the storing of the inode
* number from Rock Ridge field PX.
*/
int iso_px_ino_xinfo_func(void *data, int flag);
/* The iso_node_xinfo_cloner function which gets associated to
* iso_px_ino_xinfo_func by iso_init() resp. iso_init_with_flag() via
* iso_node_xinfo_make_clonable()
*/
int iso_px_ino_xinfo_cloner(void *old_data, void **new_data, int flag);
/* Function to identify and manage ZF parameters of zisofs compression.
* data is supposed to be a pointer to struct zisofs_zf_info
*/
int zisofs_zf_xinfo_func(void *data, int flag);
/* The iso_node_xinfo_cloner function which gets associated to
* zisofs_zf_xinfo_func by iso_init() resp. iso_init_with_flag() via
* iso_node_xinfo_make_clonable()
*/
int zisofs_zf_xinfo_cloner(void *old_data, void **new_data, int flag);
/* Performing search for possibly truncated node name.
*/
int iso_dir_get_node_trunc(IsoDir *dir, int truncate_length,
const char *name, IsoNode **node);
#endif /*LIBISO_NODE_H_*/

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2007 Mario Danic
* Copyright (c) 2009 Thomas Schmitt
* Copyright (c) 2009 - 2025 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
@ -41,6 +41,10 @@
#include "ecma119.h"
/* For ssize_t */
#include <sys/types.h>
#include <unistd.h>
#define SUSP_SIG(entry, a, b) ((entry->sig[0] == a) && (entry->sig[1] == b))
@ -63,10 +67,35 @@ struct susp_info
uint32_t ce_block;
uint32_t ce_len;
/* Storage for Continuation Area for a whole directory */
size_t n_ce_susp_fields;
uint8_t **ce_susp_fields;
/* The number of allocated members in ce_susp_fields */
size_t alloc_ce_susp_fields;
/* Marks the start index in ce_susp_fields of the current node */
size_t current_ce_start;
/* Tells the really written number of Continuation Area payload bytes
after rrip_write_ce_fields() wrote them to the output stream.
*/
uint64_t ce_written_len;
};
/* Step to increase allocated size of susp_info.ce_susp_fields */
#define ISO_SUSP_CE_ALLOC_STEP 16
/* Upper limit for use of 7-byte time form: 01 Jan 2150 00:00:00 UTC
That is six years before the end of the 7-byte form capacity, just to
allow future software archeologists to widen this time limit to end of
year 2155 so that any problems with the longer TF can be sorted out
before it is too late.
*/
#define ISO_RR_SHORT_FORM_TIME_LIMIT 5680281600
/* SUSP 5.1 */
struct susp_CE {
uint8_t block[8];
@ -186,11 +215,13 @@ struct susp_sys_user_entry
* Available space in the System Use Area for the directory record.
* @param ce
* Will be filled with the space needed in a CE
* @param base_ce
* Fill of continuation area by previous nodes of same dir
* @return
* The size needed for the RR entries in the System Use Area
*/
size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t space,
size_t *ce);
ssize_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t space,
size_t *ce, size_t base_ce);
/**
* Fill a struct susp_info with the RR/SUSP entries needed for a given
@ -205,7 +236,7 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t space,
* Pointer to the struct susp_info where the entries will be stored.
* If some entries need to go to a Continuation Area, they will be added
* to the existing ce_susp_fields, and ce_len will be incremented
* propertly. Please ensure ce_block is initialized propertly.
* properly. Please ensure ce_block is initialized properly.
* @return
* 1 success, < 0 error
*/
@ -217,9 +248,10 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
* fields are not written.
* If info does not contain any SUSP entry this function just return.
* After written, the info susp_fields array will be freed, and the counters
* updated propertly.
* updated properly.
* @return the number of written bytes
*/
void rrip_write_susp_fields(Ecma119Image *t, struct susp_info *info,
int rrip_write_susp_fields(Ecma119Image *t, struct susp_info *info,
uint8_t *buf);
/**
@ -240,7 +272,7 @@ typedef struct susp_iterator SuspIterator;
SuspIterator *
susp_iter_new(IsoDataSource *src, struct ecma119_dir_record *record,
uint8_t len_skp, int msgid);
uint32_t fs_blocks, uint8_t len_skp, int msgid);
/**
* Get the next SUSP System User Entry using given iterator.
@ -252,7 +284,8 @@ susp_iter_new(IsoDataSource *src, struct ecma119_dir_record *record,
* @return
* 1 on success, 0 if no more entries, < 0 error
*/
int susp_iter_next(SuspIterator *iter, struct susp_sys_user_entry **sue);
int susp_iter_next(SuspIterator *iter, struct susp_sys_user_entry **sue,
int flag);
/**
* Free a given susp iterator.
@ -344,6 +377,14 @@ int read_aaip_AL(struct susp_sys_user_entry *sue,
*/
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);
uint64_t *uncompressed_size, int flag);
/**
* Convert a RR filename to the requested charset.
* @param flag bit0= do not issue error messages
*/
int iso_get_rr_name(IsoWriteOpts *opts, char *input_charset,
char *output_charset, int imgid,
char *str, char **name, int flag);
#endif /* LIBISO_ROCKRIDGE_H */

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 Thomas Schmitt
* Copyright (c) 2009 - 2025 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
@ -13,6 +13,10 @@
* Rock Ridge and AAIP extensions on an ECMA-119 image.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include "libisofs.h"
#include "ecma119.h"
#include "util.h"
@ -31,6 +35,12 @@ struct susp_iterator
IsoDataSource *src;
int msgid;
/* Number of blocks in the ISO 9660 filesystem */
uint32_t fs_blocks;
/* For detecting (nearly) endless loops */
uint32_t ce_counter;
/* block and offset for next continuation area */
uint32_t ce_block;
uint32_t ce_off;
@ -43,7 +53,7 @@ struct susp_iterator
SuspIterator*
susp_iter_new(IsoDataSource *src, struct ecma119_dir_record *record,
uint8_t len_skp, int msgid)
uint32_t fs_blocks, uint8_t len_skp, int msgid)
{
int pad = (record->len_fi[0] + 1) % 2;
struct susp_iterator *iter = malloc(sizeof(struct susp_iterator));
@ -56,19 +66,48 @@ susp_iter_new(IsoDataSource *src, struct ecma119_dir_record *record,
iter->size = record->len_dr[0] - record->len_fi[0] - 33 - pad;
iter->src = src;
iter->msgid = msgid;
iter->fs_blocks = fs_blocks;
iter->ce_counter = 0;
iter->ce_len = 0;
iter->ce_block = 0;
iter->ce_off = 0;
iter->buffer = NULL;
return iter;
}
int susp_iter_next(SuspIterator *iter, struct susp_sys_user_entry **sue)
/* More than 1 MiB in a single file's CE area is suspicious */
#define ISO_SUSP_MAX_CE_BYTES (1024 * 1024)
/* More than 100000 CE entries in a file is suspicious */
#define ISO_SUSP_MAX_CE_HOPS 100000
/* @param flag bit0 = First call on root:
Not yet clear whether this is SUSP at all
*/
int susp_iter_next(SuspIterator *iter, struct susp_sys_user_entry **sue,
int flag)
{
struct susp_sys_user_entry *entry;
process_entry:;
entry = (struct susp_sys_user_entry*)(iter->base + iter->pos);
if (flag & 1) {
/* Yet unclear whether it is SUSP at all */
if (iter->size < 7)
return 0;
if (!SUSP_SIG(entry, 'S', 'P'))
return 0;
if (entry->len_sue[0] < 7)
return 0;
/* Looks like SUSP enough to pass the further processing here. */
/* In case of CE hop do not run this check again */
flag &= ~1;
}
if ( (iter->pos + 4 > iter->size) || (SUSP_SIG(entry, 'S', 'T'))) {
/*
@ -77,23 +116,31 @@ int susp_iter_next(SuspIterator *iter, struct susp_sys_user_entry **sue)
* (IEEE 1281, SUSP. section 4)
*/
if (iter->ce_len) {
uint32_t block;
int nblocks;
uint32_t block, nblocks, skipped_blocks, skipped_bytes;
/* A CE has found, there is another continuation area */
nblocks = DIV_UP(iter->ce_off + iter->ce_len, BLOCK_SIZE);
/* A CE was found, there is another continuation area */
skipped_blocks = iter->ce_off / BLOCK_SIZE;
skipped_bytes = skipped_blocks * BLOCK_SIZE;
nblocks = DIV_UP(iter->ce_off - skipped_bytes + iter->ce_len,
BLOCK_SIZE);
if (nblocks <= 0 || iter->ce_len > ISO_SUSP_MAX_CE_BYTES)
return ISO_SUSP_WRONG_CE_SIZE;
if (((uint64_t) iter->ce_block) + skipped_blocks + nblocks >
(uint64_t) iter->fs_blocks)
return ISO_SUSP_WRONG_CE_SIZE;
iter->buffer = realloc(iter->buffer, nblocks * BLOCK_SIZE);
/* read all blocks needed to cache the full CE */
/* Read blocks needed to cache the given CE area range */
for (block = 0; block < nblocks; ++block) {
int ret;
ret = iter->src->read_block(iter->src, iter->ce_block + block,
iter->buffer + block * BLOCK_SIZE);
ret = iter->src->read_block(iter->src,
iter->ce_block + skipped_blocks + block,
iter->buffer + block * BLOCK_SIZE);
if (ret < 0) {
return ret;
}
}
iter->base = iter->buffer + iter->ce_off;
iter->base = iter->buffer + (iter->ce_off - skipped_bytes);
iter->pos = 0;
iter->size = iter->ce_len;
iter->ce_len = 0;
@ -117,9 +164,9 @@ int susp_iter_next(SuspIterator *iter, struct susp_sys_user_entry **sue)
if (iter->ce_len) {
int ret;
ret = iso_msg_submit(iter->msgid, ISO_UNSUPPORTED_SUSP, 0,
"More than one CE System user entry has found in a single "
"More than one CE System user entry was found in a single "
"System Use field or continuation area. This breaks SUSP "
"standard and it's not supported. Ignoring last CE. Maybe "
"standard and is not supported. Ignoring last CE. Maybe "
"the image is damaged.");
if (ret < 0) {
return ret;
@ -131,10 +178,15 @@ int susp_iter_next(SuspIterator *iter, struct susp_sys_user_entry **sue)
}
/* we don't want to return CE entry to the user */
return susp_iter_next(iter, sue);
if (++(iter->ce_counter) > ISO_SUSP_MAX_CE_HOPS) {
iso_msg_submit(iter->msgid, ISO_WRONG_RR, 0,
"Damaged RR/SUSP information: Too many CE hops.");
return ISO_WRONG_RR;
}
goto process_entry;
} else if (SUSP_SIG(entry, 'P', 'D')) {
/* skip padding */
return susp_iter_next(iter, sue);
goto process_entry;
}
*sue = entry;
@ -208,10 +260,19 @@ int read_rr_TF(struct susp_sys_user_entry *tf, struct stat *st)
/* 1. Creation time */
if (tf->data.TF.flags[0] & (1 << 0)) {
/* the creation is the recording time. we ignore this */
/* TODO maybe it would be good to manage it in ms discs, where
* the recording time could be different than now!! */
/* Linux accepts ctime by Creation time and by Attributes time.
* If both are given, then Attribute time will win.
*/
if (tf->len_sue[0] < 5 + (nts+1) * s) {
/* RR TF entry too short. */
return ISO_WRONG_RR;
}
if (s == 7) {
time = iso_datetime_read_7(&tf->data.TF.t_stamps[nts*7]);
} else {
time = iso_datetime_read_17(&tf->data.TF.t_stamps[nts*17]);
}
st->st_ctime = time;
++nts;
}
@ -324,7 +385,7 @@ int read_rr_NM(struct susp_sys_user_entry *nm, char **name, int *cont)
*/
int read_rr_SL(struct susp_sys_user_entry *sl, char **dest, int *cont)
{
int pos;
int pos, real_root_flag = 0, in_root = 0;
if (sl == NULL || dest == NULL) {
return ISO_NULL_POINTER;
@ -338,7 +399,10 @@ int read_rr_SL(struct susp_sys_user_entry *sl, char **dest, int *cont)
char *comp;
uint8_t len;
uint8_t flags = sl->data.SL.comps[pos];
in_root = real_root_flag;
real_root_flag = 0;
if (flags & 0x2) {
/* current directory */
len = 1;
@ -348,9 +412,26 @@ int read_rr_SL(struct susp_sys_user_entry *sl, char **dest, int *cont)
len = 2;
comp = "..";
} else if (flags & 0x8) {
/* root directory */
len = 1;
/* Alleged root directory.
Normally only the first component should have this bit set.
But genisoimage and older libisofs both set bit 3 with
any empty component which represents an add-on slash.
*/
comp = "/";
if (pos == 0 || in_root) {
/* Real root directory or add-on slash of root slash */
len = 1;
real_root_flag = 1;
} else if (pos + 2 + sl->data.SL.comps[pos + 1] + 5 >=
sl->len_sue[0]) {
/* A final component with bit 3 traditionally leads to a
double slash in Linux and in older libisofs.
*/
len = 1;
} else {
/* Just a mislead component in the inner of the path */
len = 0;
}
} else if (flags & ~0x01) {
/* unsupported flag component */
return ISO_UNSUPPORTED_RR;
@ -362,12 +443,13 @@ int read_rr_SL(struct susp_sys_user_entry *sl, char **dest, int *cont)
if (*cont == 1) {
/* new component */
size_t size = strlen(*dest);
*dest = realloc(*dest, strlen(*dest) + len + 2);
if (*dest == NULL) {
return ISO_OUT_OF_MEM;
}
/* it is a new compoenent, add the '/' */
if ((*dest)[size-1] != '/') {
/* it is a new component, add the '/' */
if (!(pos == 0 || in_root)) {
(*dest)[size] = '/';
(*dest)[size+1] = '\0';
}
@ -381,6 +463,7 @@ int read_rr_SL(struct susp_sys_user_entry *sl, char **dest, int *cont)
/* we don't have to add the '/' */
strncat(*dest, comp, len);
} else {
/* The first component begins */
*dest = iso_util_strcopy(comp, len);
}
if (*dest == NULL) {
@ -409,7 +492,7 @@ int read_rr_PN(struct susp_sys_user_entry *pn, struct stat *st)
{
int high_shift= 0;
if (pn == NULL || pn == NULL) {
if (pn == NULL || st == NULL) {
return ISO_NULL_POINTER;
}
if (pn->sig[0] != 'P' || pn->sig[1] != 'N') {
@ -439,7 +522,7 @@ int read_rr_PN(struct susp_sys_user_entry *pn, struct stat *st)
}
/* AA is the field signature of AAIP versions < 2.0
/* AA is the obsolete field signature of AAIP versions < 2.0
*/
int read_aaip_AA(struct susp_sys_user_entry *sue,
unsigned char **aa_string, size_t *aa_size, size_t *aa_len,
@ -450,24 +533,27 @@ int read_aaip_AA(struct susp_sys_user_entry *sue,
if (*is_done) {
/* To coexist with Apple ISO :
Gracefully react on eventually trailing Apple AA
Gracefully react on possibly trailing Apple AA
*/
if (sue->version[0] != 1 || sue->len_sue[0] == 7)
return ISO_SUCCESS;
return ISO_WRONG_RR;
}
/* Eventually create or grow storage */
if (*aa_size == 0 || *aa_string == NULL) {
/* Gracefully react on eventually leading Apple AA
/* Gracefully react on possibly leading Apple AA
*/
if (sue->version[0] != 1 || sue->len_sue[0] < 9) {
if (sue->version[0] != 1 || sue->len_sue[0] < 9)
return ISO_SUCCESS;
}
}
/* A valid AAIP AA entry has 5 header bytes and at least 1 component byte
*/
if (sue->len_sue[0] < 6)
return ISO_WRONG_RR;
/* Possibly create or grow storage */
if (*aa_size == 0 || *aa_string == NULL) {
*aa_size = *aa_len + sue->len_sue[0];
*aa_string = calloc(*aa_size, 1);
*aa_len = 0;
@ -510,7 +596,7 @@ int read_aaip_AA(struct susp_sys_user_entry *sue,
}
/* AL is the obsolete field signature of AAIP versions >= 2.0
/* AL is the field signature of AAIP versions >= 2.0
*/
int read_aaip_AL(struct susp_sys_user_entry *sue,
unsigned char **aa_string, size_t *aa_size, size_t *aa_len,
@ -523,7 +609,12 @@ int read_aaip_AL(struct susp_sys_user_entry *sue,
if (sue->version[0] != 1)
return ISO_WRONG_RR;
/* Eventually create or grow storage */
/* A valid AL entry has 5 header bytes and at least 1 component byte
*/
if (sue->len_sue[0] < 6)
return ISO_WRONG_RR;
/* Possibly create or grow storage */
if (*aa_size == 0 || *aa_string == NULL) {
*aa_size = *aa_len + sue->len_sue[0];
*aa_string = calloc(*aa_size, 1);
@ -560,29 +651,36 @@ int read_aaip_AL(struct susp_sys_user_entry *sue,
}
/**
* Reads the zisofs parameters from a ZF field (see doc/zisofs_format.txt).
* Reads the zisofs parameters from a ZF field (see doc/zisofs_format.txt
* and doc/zisofs2_format.txt).
*
* @return
* 1 on success, < 0 on error
*/
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)
uint64_t *uncompressed_size, int flag)
{
if (zf == NULL) {
return ISO_NULL_POINTER;
}
if (zf->sig[0] != 'Z' || zf->sig[1] != 'F') {
if ((zf->sig[0] != 'Z' || zf->sig[1] != 'F') &&
(zf->sig[0] != 'Z' || zf->sig[1] != '2'))
return ISO_WRONG_ARG_VALUE;
}
if (zf->len_sue[0] != 16) {
return ISO_WRONG_RR;
}
if (zf->version[0] > 2)
return ISO_WRONG_RR;
algorithm[0] = zf->data.ZF.parameters[0];
algorithm[1] = zf->data.ZF.parameters[1];
*header_size_div4 = zf->data.ZF.parameters[2];
*block_size_log2 = zf->data.ZF.parameters[3];
*uncompressed_size = iso_read_bb(&(zf->data.ZF.parameters[4]), 4, NULL);
if (zf->version[0] == 1)
*uncompressed_size = iso_read_bb(&(zf->data.ZF.parameters[4]), 4,
NULL);
else
*uncompressed_size = iso_read_lsb64(&(zf->data.ZF.parameters[4]));
return ISO_SUCCESS;
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 Thomas Schmitt
* Copyright (c) 2009 - 2022 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
@ -8,15 +8,22 @@
* See COPYING file for details.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include "libisofs.h"
#include "stream.h"
#include "fsource.h"
#include "util.h"
#include "node.h"
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#ifndef PATH_MAX
@ -153,8 +160,56 @@ int fsrc_update_size(IsoStream *stream)
return ISO_SUCCESS;
}
static
IsoStream *fsrc_get_input_stream(IsoStream *stream, int flag)
{
return NULL;
}
int fsrc_clone_stream(IsoStream *old_stream, IsoStream **new_stream,
int flag)
{
FSrcStreamData *data, *new_data;
IsoStream *stream;
int ret;
if (flag)
return ISO_STREAM_NO_CLONE; /* unknown option required */
data = (FSrcStreamData*) old_stream->data;
if (data->src->class->version < 2)
return ISO_STREAM_NO_CLONE; /* No clone_src() method available */
*new_stream = NULL;
stream = calloc(1, sizeof(IsoStream));
if (stream == NULL)
return ISO_OUT_OF_MEM;
new_data = calloc(1, sizeof(FSrcStreamData));
if (new_data == NULL) {
free((char *) stream);
return ISO_OUT_OF_MEM;
}
*new_stream = stream;
stream->class = old_stream->class;
stream->refcount = 1;
stream->data = new_data;
ret = data->src->class->clone_src(data->src, &(new_data->src), 0);
if (ret < 0) {
free((char *) stream);
free((char *) new_data);
return ret;
}
new_data->dev_id = data->dev_id;
new_data->ino_id = data->ino_id;
new_data->size = data->size;
return ISO_SUCCESS;
}
static
IsoStreamIface fsrc_stream_class = {
1, /* update_size is defined for this stream */
4, /* version */
"fsrc",
fsrc_open,
fsrc_close,
@ -163,7 +218,10 @@ IsoStreamIface fsrc_stream_class = {
fsrc_is_repeatable,
fsrc_get_id,
fsrc_free,
fsrc_update_size
fsrc_update_size,
fsrc_get_input_stream,
NULL,
fsrc_clone_stream
};
int iso_file_source_stream_new(IsoFileSource *src, IsoStream **stream)
@ -234,25 +292,25 @@ int iso_file_source_stream_new(IsoFileSource *src, IsoStream **stream)
}
int iso_stream_get_src_zf(IsoStream *stream, int *header_size_div4,
int *block_size_log2, uint32_t *uncompressed_size,
int flag)
int iso_stream_get_src_zf(IsoStream *stream, uint8_t zisofs_algo[2],
int *header_size_div4, int *block_size_log2,
uint64_t *uncompressed_size, int flag)
{
int ret;
FSrcStreamData *data;
IsoFileSource *src;
/* Intimate friendship with libisofs/fs_image.c */
int iso_ifs_source_get_zf(IsoFileSource *src, int *header_size_div4,
int *block_size_log2, uint32_t *uncompressed_size, int flag);
int iso_ifs_source_get_zf(IsoFileSource *src, uint8_t zisofs_algo[2],
int *header_size_div4, int *block_size_log2,
uint64_t *uncompressed_size, int flag);
if (stream->class != &fsrc_stream_class)
return 0;
data = stream->data;
src = data->src;
ret = iso_ifs_source_get_zf(src, header_size_div4, block_size_log2,
uncompressed_size, 0);
ret = iso_ifs_source_get_zf(src, zisofs_algo, header_size_div4,
block_size_log2, uncompressed_size, 0);
return ret;
}
@ -274,6 +332,7 @@ int cut_out_open(IsoStream *stream)
{
int ret;
struct stat info;
off_t src_size, pos;
IsoFileSource *src;
struct cut_out_stream *data;
@ -292,20 +351,26 @@ int cut_out_open(IsoStream *stream)
return ret;
}
{
off_t ret;
if (data->offset > info.st_size) {
/* file is smaller than expected */
ret = iso_file_source_lseek(src, info.st_size, 0);
} else {
ret = iso_file_source_lseek(src, data->offset, 0);
}
if (ret < 0) {
return (int) ret;
}
if (S_ISREG(info.st_mode)) {
src_size= info.st_size;
} else {
/* Determine src_size and lseekability of device */
src_size = iso_file_source_determine_capacity(src,
data->offset + data->size, 2);
if (src_size <= 0)
return ISO_WRONG_ARG_VALUE;
}
if (data->offset > src_size) {
/* file is smaller than expected */
pos = iso_file_source_lseek(src, src_size, 0);
} else {
pos = iso_file_source_lseek(src, data->offset, 0);
}
if (pos < 0) {
return (int) pos;
}
data->pos = 0;
if (data->offset + data->size > info.st_size) {
if (data->offset + data->size > src_size) {
return 3; /* file smaller than expected */
} else {
return ISO_SUCCESS;
@ -334,7 +399,7 @@ static
int cut_out_read(IsoStream *stream, void *buf, size_t count)
{
struct cut_out_stream *data = stream->data;
count = (size_t)MIN(data->size - data->pos, count);
count = (size_t) MIN((size_t) (data->size - data->pos), count);
if (count == 0) {
return 0;
}
@ -371,11 +436,68 @@ void cut_out_free(IsoStream *stream)
free(data);
}
static
int cut_out_update_size(IsoStream *stream)
{
return ISO_SUCCESS;
}
static
IsoStream* cut_out_get_input_stream(IsoStream *stream, int flag)
{
return NULL;
}
static
int cut_out_clone_stream(IsoStream *old_stream, IsoStream **new_stream,
int flag)
{
struct cut_out_stream *data, *new_data;
IsoStream *stream;
int ret;
if (flag)
return ISO_STREAM_NO_CLONE; /* unknown option required */
data = (struct cut_out_stream *) old_stream->data;
if (data->src->class->version < 2)
return ISO_STREAM_NO_CLONE; /* No clone_src() method available */
*new_stream = NULL;
stream = calloc(1, sizeof(IsoStream));
if (stream == NULL)
return ISO_OUT_OF_MEM;
stream->refcount = 1;
stream->class = old_stream->class;
new_data = calloc(1, sizeof(struct cut_out_stream));
if (new_data == NULL) {
free((char *) stream);
return ISO_OUT_OF_MEM;
}
ret = data->src->class->clone_src(data->src, &(new_data->src), 0);
if (ret < 0) {
free((char *) stream);
free((char *) new_data);
return ret;
}
new_data->dev_id = (dev_t) 0;
new_data->ino_id = cut_out_serial_id++;
new_data->offset = data->offset;
new_data->size = data->size;
new_data->pos = 0;
stream->data = new_data;
*new_stream = stream;
return ISO_SUCCESS;
}
/*
* TODO update cut out streams to deal with update_size(). Seems hard.
*/
static
IsoStreamIface cut_out_stream_class = {
0,
4, /* version */
"cout",
cut_out_open,
cut_out_close,
@ -383,13 +505,19 @@ IsoStreamIface cut_out_stream_class = {
cut_out_read,
cut_out_is_repeatable,
cut_out_get_id,
cut_out_free
cut_out_free,
cut_out_update_size,
cut_out_get_input_stream,
NULL,
cut_out_clone_stream
};
int iso_cut_out_stream_new(IsoFileSource *src, off_t offset, off_t size,
IsoStream **stream)
{
int r;
off_t src_size;
struct stat info;
IsoStream *str;
struct cut_out_stream *data;
@ -405,10 +533,16 @@ int iso_cut_out_stream_new(IsoFileSource *src, off_t offset, off_t size,
if (r < 0) {
return r;
}
if (!S_ISREG(info.st_mode)) {
return ISO_WRONG_ARG_VALUE;
if (S_ISREG(info.st_mode)) {
src_size = info.st_size;
} else {
/* Open src, do iso_source_lseek(SEEK_END), close src */
src_size = iso_file_source_determine_capacity(src, offset + size, 3);
if (src_size <= 0)
return ISO_WRONG_ARG_VALUE;
}
if (offset > info.st_size) {
if (offset > src_size) {
return ISO_FILE_OFFSET_TOO_BIG;
}
@ -433,7 +567,7 @@ int iso_cut_out_stream_new(IsoFileSource *src, off_t offset, off_t size,
iso_file_source_ref(src);
data->offset = offset;
data->size = MIN(info.st_size - offset, size);
data->size = MIN(src_size - offset, size);
/* get the id numbers */
data->dev_id = (dev_t) 0;
@ -513,7 +647,7 @@ int mem_read(IsoStream *stream, void *buf, size_t count)
return ISO_FILE_NOT_OPENED;
}
if (data->offset >= data->size) {
if (data->offset >= (ssize_t) data->size) {
return 0; /* EOF */
}
@ -545,12 +679,69 @@ void mem_free(IsoStream *stream)
{
MemStreamData *data;
data = (MemStreamData*)stream->data;
free(data->buf);
if (data->buf != NULL)
free(data->buf);
free(data);
}
static
int mem_update_size(IsoStream *stream)
{
return ISO_SUCCESS;
}
static
IsoStream* mem_get_input_stream(IsoStream *stream, int flag)
{
return NULL;
}
static
int mem_clone_stream(IsoStream *old_stream, IsoStream **new_stream,
int flag)
{
MemStreamData *data, *new_data;
IsoStream *stream;
uint8_t *new_buf = NULL;
if (flag)
return ISO_STREAM_NO_CLONE; /* unknown option required */
*new_stream = NULL;
stream = calloc(1, sizeof(IsoStream));
if (stream == NULL)
return ISO_OUT_OF_MEM;
stream->refcount = 1;
stream->class = old_stream->class;
new_data = calloc(1, sizeof(MemStreamData));
if (new_data == NULL) {
free((char *) stream);
return ISO_OUT_OF_MEM;
}
data = (MemStreamData *) old_stream->data;
if (data->size > 0) {
new_buf = calloc(1, data->size);
if (new_buf == NULL) {
free((char *) stream);
free((char *) new_data);
return ISO_OUT_OF_MEM;
}
memcpy(new_buf, data->buf, data->size);
}
new_data->buf = new_buf;
new_data->offset = -1;
new_data->ino_id = mem_serial_id++;
new_data->size = data->size;
stream->data = new_data;
*new_stream = stream;
return ISO_SUCCESS;
}
static
IsoStreamIface mem_stream_class = {
0,
4, /* version */
"mem ",
mem_open,
mem_close,
@ -558,7 +749,12 @@ IsoStreamIface mem_stream_class = {
mem_read,
mem_is_repeatable,
mem_get_id,
mem_free
mem_free,
mem_update_size,
mem_get_input_stream,
NULL,
mem_clone_stream
};
/**
@ -566,7 +762,7 @@ IsoStreamIface mem_stream_class = {
* When the Stream refcount reach 0, the buffer is free(3).
*
* @return
* 1 sucess, < 0 error
* 1 success, < 0 error
*/
int iso_memory_stream_new(unsigned char *buf, size_t size, IsoStream **stream)
{
@ -582,7 +778,7 @@ int iso_memory_stream_new(unsigned char *buf, size_t size, IsoStream **stream)
return ISO_OUT_OF_MEM;
}
data = malloc(sizeof(MemStreamData));
if (str == NULL) {
if (data == NULL) {
free(str);
return ISO_OUT_OF_MEM;
}
@ -665,30 +861,57 @@ void iso_stream_get_file_name(IsoStream *stream, char *name)
if (!strncmp(type, "fsrc", 4)) {
FSrcStreamData *data = stream->data;
char *path = iso_file_source_get_path(data->src);
strncpy(name, path, PATH_MAX);
if (path == NULL) {
name[0] = 0;
return;
}
strncpy(name, path, PATH_MAX - 1);
name[PATH_MAX - 1] = 0;
free(path);
} else if (!strncmp(type, "boot", 4)) {
strcpy(name, "BOOT CATALOG");
} else if (!strncmp(type, "cout", 4)) {
strcpy(name, "CUT_OUT FILE");
} else if (!strncmp(type, "mem ", 4)) {
strcpy(name, "MEM SOURCE");
} else if (!strncmp(type, "boot", 4)) {
strcpy(name, "BOOT CATALOG");
} else if (!strncmp(type, "extf", 4)) {
strcpy(name, "EXTERNAL FILTER");
} else if (!strncmp(type, "ziso", 4)) {
strcpy(name, "ZISOFS COMPRESSION FILTER");
} else if (!strncmp(type, "osiz", 4)) {
strcpy(name, "ZISOFS DECOMPRESSION FILTER");
} else if (!strncmp(type, "gzip", 4)) {
strcpy(name, "GZIP COMPRESSION FILTER");
} else if (!strncmp(type, "pizg", 4)) {
strcpy(name, "GZIP DECOMPRESSION FILTER");
} else if (!strncmp(type, "user", 4)) {
strcpy(name, "USER SUPPLIED STREAM");
} else {
strcpy(name, "UNKNOWN SOURCE");
}
}
/* @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)
@ -721,12 +944,22 @@ ex:;
return path;
}
/* @return 1 = ok , 0 = not an ISO image stream , <0 = error */
/*
@param flag bit0= in case of filter stream do not dig for base stream
@return 1 = ok , 0 = not an ISO image stream , <0 = error
*/
int iso_stream_set_image_ino(IsoStream *stream, ino_t ino, int flag)
{
IsoStream *base_stream;
if (stream == NULL) {
return ISO_NULL_POINTER;
}
if (!(flag & 1)) {
base_stream = iso_stream_get_input_stream(stream, 1);
if (base_stream != NULL)
stream = base_stream;
}
if (stream->class == &fsrc_stream_class) {
FSrcStreamData *fsrc_data = stream->data;
fsrc_data->ino_id = ino;
@ -735,6 +968,104 @@ int iso_stream_set_image_ino(IsoStream *stream, ino_t ino, int flag)
return 0;
}
int iso_stream_cmp_ifs_sections(IsoStream *s1, IsoStream *s2, int *cmp_ret,
int flag)
{
int ret;
FSrcStreamData *fssd1, *fssd2;
IsoFileSource *src1, *src2;
/* Must keep any suspect in the game to preserve transitivity of the
calling function by ranking applicable streams lower than
non-applicable. ones.
*/
if (s1->class != &fsrc_stream_class && s2->class != &fsrc_stream_class)
return 0;
/* Compare eventual image data section LBA and sizes */
if (s1->class == &fsrc_stream_class) {
fssd1= (FSrcStreamData *) s1->data;
src1 = fssd1->src;
} else {
src1 = NULL;
}
if (s2->class == &fsrc_stream_class) {
fssd2= (FSrcStreamData *) s2->data;
src2 = fssd2->src;
} else {
src2 = NULL;
}
ret = iso_ifs_sections_cmp(src1, src2, cmp_ret, 1);
if (ret <= 0)
return 0;
return 1;
}
/* Maintain and exploit a list of stream compare functions seen by
iso_stream_cmp_ino(). This is needed to separate stream comparison
families in order to keep iso_stream_cmp_ino() transitive while
alternative stream->class->cmp_ino() decide inside the families.
*/
struct iso_streamcmprank {
int (*cmp_func)(IsoStream *s1, IsoStream *s2);
struct iso_streamcmprank *next;
};
static struct iso_streamcmprank *streamcmpranks = NULL;
static
int iso_get_streamcmprank(int (*cmp_func)(IsoStream *s1, IsoStream *s2),
int flag)
{
int idx;
struct iso_streamcmprank *cpr, *last_cpr = NULL;
idx = 0;
for (cpr = streamcmpranks; cpr != NULL; cpr = cpr->next) {
if (cpr->cmp_func == cmp_func)
break;
idx++;
last_cpr = cpr;
}
if (cpr != NULL)
return idx;
LIBISO_ALLOC_MEM_VOID(cpr, struct iso_streamcmprank, 1);
cpr->cmp_func = cmp_func;
cpr->next = NULL;
if (last_cpr != NULL)
last_cpr->next = cpr;
if (streamcmpranks == NULL)
streamcmpranks = cpr;
return idx;
ex:;
return -1;
}
static
int iso_cmp_streamcmpranks(int (*cf1)(IsoStream *s1, IsoStream *s2),
int (*cf2)(IsoStream *s1, IsoStream *s2))
{
int rank1, rank2;
rank1 = iso_get_streamcmprank(cf1, 0);
rank2 = iso_get_streamcmprank(cf2, 0);
return rank1 < rank2 ? -1 : 1;
}
int iso_stream_destroy_cmpranks(int flag)
{
struct iso_streamcmprank *cpr, *next;
for (cpr = streamcmpranks; cpr != NULL; cpr = next) {
next = cpr->next;
LIBISO_FREE_MEM(cpr);
}
streamcmpranks = NULL;
return ISO_SUCCESS;
}
/* API */
int iso_stream_cmp_ino(IsoStream *s1, IsoStream *s2, int flag)
{
@ -743,8 +1074,6 @@ int iso_stream_cmp_ino(IsoStream *s1, IsoStream *s2, int flag)
dev_t dev_id1, dev_id2;
ino_t ino_id1, ino_id2;
off_t size1, size2;
FSrcStreamData *fssd1, *fssd2;
/*
#define Libisofs_stream_cmp_ino_debuG 1
@ -761,10 +1090,72 @@ int iso_stream_cmp_ino(IsoStream *s1, IsoStream *s2, int flag)
if (s2 == NULL)
return 1;
if (s1->class->version >= 3 && !(flag & 1)) {
/* Filters may have smarter methods to compare themselves with others */
ret = s1->class->cmp_ino(s1, s2);
return ret;
/* This stays transitive by the fact that
iso_stream_cmp_ifs_sections() is transitive,
returns > 0 if s1 or s2 are applicable,
ret is -1 if s1 is applicable but s2 is not,
ret is 1 if s1 is not applicable but s2 is.
Proof:
Be A the set of applicable streams, S and G transitive and
antisymmetric relations in respect to outcome {-1, 0, 1}.
The combined relation R shall be defined by
I. R(a,b) = S(a,b) if a in A or b in A, else G(a,b)
Further S shall have the property
II. S(a,b) = -1 if a in A and b not in A
Then R can be proven to be transitive:
By enumerating the 8 combinations of a,b,c being in A or not, we get
5 cases of pure S or pure G. Three cases are mixed:
a,b not in A, c in A : G(a,b) == -1, S(b,c) == -1 -> S(a,c) == -1
Impossible because S(b,c) == -1 contradicts II.
a,c not in A, b in A : S(a,b) == -1, S(b,c) == -1 -> G(a,c) == -1
Impossible because S(a,b) == -1 contradicts II.
b,c not in A, a in A : S(a,b) == -1, G(b,c) == -1 -> S(a,c) == -1
Always true because S(a,c) == -1 by definition II.
*/
if (iso_stream_cmp_ifs_sections(s1, s2, &ret, 0) > 0)
return ret; /* Both are unfiltered from loaded ISO filesystem */
if (!(flag & 1)) {
/* Filters may have smarter methods to compare themselves with others.
Transitivity is ensured by ranking mixed pairs by the rank of their
comparison functions, and by ranking streams with .cmp_ino lower
than streams without.
(One could merge (class->version < 3) and (cmp_ino == NULL).)
Here we define S for "and" rather than "or"
I. R(a,b) = S(a,b) if a in A and b in A, else G(a,b)
and the function ranking in case of "exor" makes sure that
II. G(a,b) = -1 if a in A and b not in A
Again we get three mixed cases:
a not in A, b,c in A : G(a,b) == -1, S(b,c) == -1 -> G(a,c) == -1
Impossible because G(a,b) == -1 contradicts II.
b not in A, a,c in A : G(a,b) == -1, G(b,c) == -1 -> S(a,c) == -1
Impossible because G(b,c) == -1 contradicts II.
c not in A, a,b in A : S(a,b) == -1, G(b,c) == -1 -> G(a,c) == -1
Always true because G(a,c) == -1 by definition II.
*/
if ((s1->class->version >= 3) ^ (s2->class->version >= 3)) {
/* One of both has no own com_ino function. Rank it as larger. */
return s1->class->version >= 3 ? -1 : 1;
} else if (s1->class->version >= 3) {
if (s1->class->cmp_ino == s2->class->cmp_ino) {
if (s1->class->cmp_ino == NULL) {
/* Both are NULL. No decision by .cmp_ino(). */;
} else {
/* Both are compared by the same function */
ret = s1->class->cmp_ino(s1, s2);
return ret;
}
} else {
/* Not the same cmp_ino() function. Decide by list rank of
function while building the list on the fly.
*/
ret = iso_cmp_streamcmpranks(s1->class->cmp_ino,
s2->class->cmp_ino);
return ret;
}
}
}
iso_stream_get_id(s1, &fs_id1, &dev_id1, &ino_id1);
@ -820,14 +1211,6 @@ int iso_stream_cmp_ino(IsoStream *s1, IsoStream *s2, int flag)
if (s1->class != s2->class)
return (s1->class < s2->class ? -1 : 1);
if (s1->class == &fsrc_stream_class) {
/* Compare eventual image data section LBA and sizes */
fssd1= (FSrcStreamData *) s1->data;
fssd2= (FSrcStreamData *) s2->data;
ret = iso_ifs_sections_cmp(fssd1->src, fssd2->src, 0);
if (ret != 0)
return ret;
}
if (fs_id1 == 0 && dev_id1 == 0 && ino_id1 == 0) {
return (s1 < s2 ? -1 : 1);
}
@ -864,9 +1247,6 @@ int iso_stream_read_buffer(IsoStream *stream, char *buf, size_t count,
return 1;
}
#ifdef Libisofs_with_checksumS
/* @param flag bit0= dig out most original stream (e.g. because from old image)
@return 1=ok, md5 is valid,
0= not ok,
@ -874,14 +1254,15 @@ int iso_stream_read_buffer(IsoStream *stream, char *buf, size_t count,
*/
int iso_stream_make_md5(IsoStream *stream, char md5[16], int flag)
{
int res, is_open = 0;
char buffer[2048];
int ret, is_open = 0;
char * buffer = NULL;
void *ctx= NULL;
off_t file_size;
uint32_t b, nblocks;
size_t got_bytes;
IsoStream *input_stream;
LIBISO_ALLOC_MEM(buffer, char, 2048);
if (flag & 1) {
while(1) {
input_stream = iso_stream_get_input_stream(stream, 0);
@ -892,37 +1273,74 @@ int iso_stream_make_md5(IsoStream *stream, char md5[16], int flag)
}
if (! iso_stream_is_repeatable(stream))
return 0;
res = iso_md5_start(&ctx);
if (res < 0)
return res;
res = iso_stream_open(stream);
if (res < 0)
return 0;
{ret = 0; goto ex;}
ret = iso_md5_start(&ctx);
if (ret < 0)
goto ex;
ret = iso_stream_open(stream);
if (ret < 0)
goto ex;
is_open = 1;
file_size = iso_stream_get_size(stream);
nblocks = DIV_UP(file_size, 2048);
for (b = 0; b < nblocks; ++b) {
res = iso_stream_read_buffer(stream, buffer, 2048, &got_bytes);
if (res < 0) {
res = 0;
ret = iso_stream_read_buffer(stream, buffer, 2048, &got_bytes);
if (ret < 0) {
ret = 0;
goto ex;
}
/* Do not use got_bytes to stay closer to IsoFileSrc processing */
if (file_size - b * 2048 > 2048)
res = 2048;
ret = 2048;
else
res = file_size - b * 2048;
iso_md5_compute(ctx, buffer, res);
ret = file_size - b * 2048;
iso_md5_compute(ctx, buffer, ret);
}
res = 1;
ret = 1;
ex:;
if (is_open)
iso_stream_close(stream);
if (ctx != NULL)
iso_md5_end(&ctx, md5);
return res;
LIBISO_FREE_MEM(buffer);
return ret;
}
#endif /* Libisofs_with_checksumS */
/* API */
int iso_stream_clone(IsoStream *old_stream, IsoStream **new_stream, int flag)
{
int ret;
if (old_stream->class->version < 4)
return ISO_STREAM_NO_CLONE;
ret = old_stream->class->clone_stream(old_stream, new_stream, 0);
return ret;
}
int iso_stream_clone_filter_common(IsoStream *old_stream,
IsoStream **new_stream,
IsoStream **new_input, int flag)
{
IsoStream *stream, *input_stream;
int ret;
*new_stream = NULL;
*new_input = NULL;
input_stream = iso_stream_get_input_stream(old_stream, 0);
if (input_stream == NULL)
return ISO_STREAM_NO_CLONE;
stream = calloc(1, sizeof(IsoStream));
if (stream == NULL)
return ISO_OUT_OF_MEM;
ret = iso_stream_clone(input_stream, new_input, 0);
if (ret < 0) {
free((char *) stream);
return ret;
}
stream->class = old_stream->class;
stream->refcount = 1;
stream->data = NULL;
*new_stream = stream;
return ISO_SUCCESS;
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 Thomas Schmitt
* Copyright (c) 2009 - 2016 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
@ -15,6 +15,7 @@
*/
#include "fsource.h"
/* IMPORTANT: Any change must be reflected by fsrc_clone_stream */
typedef struct
{
IsoFileSource *src;
@ -28,18 +29,19 @@ typedef struct
/**
* Get an identifier for the file of the source, for debug purposes
* @param name
* Should provide at least PATH_MAX bytes
* Must provide at least PATH_MAX bytes. If no PATH_MAX is defined
* then assume PATH_MAX = Libisofs_default_path_maX from libisofs.h
*/
void iso_stream_get_file_name(IsoStream *stream, char *name);
/**
* Create a stream to read from a IsoFileSource.
* The stream will take the ref. to the IsoFileSource, so after a successfully
* exectution of this function, you musn't unref() the source, unless you
* execution of this function, you must not unref() the source, unless you
* take an extra ref.
*
* @return
* 1 sucess, < 0 error
* 1 success, < 0 error
* Possible errors:
*
*/
@ -50,20 +52,11 @@ int iso_file_source_stream_new(IsoFileSource *src, IsoStream **stream);
* The stream will add a ref. to the IsoFileSource.
*
* @return
* 1 sucess, < 0 error
* 1 success, < 0 error
*/
int iso_cut_out_stream_new(IsoFileSource *src, off_t offset, off_t size,
IsoStream **stream);
/**
* Create a stream for reading from a arbitrary memory buffer.
* When the Stream refcount reach 0, the buffer is free(3).
*
* @return
* 1 sucess, < 0 error
*/
int iso_memory_stream_new(unsigned char *buf, size_t size, IsoStream **stream);
/**
* Obtain eventual zisofs ZF field entry parameters from a file source out
* of a loaded ISO image.
@ -72,9 +65,9 @@ int iso_memory_stream_new(unsigned char *buf, size_t size, IsoStream **stream);
* type, though, unless fsrc_stream_class would be used without FSrcStreamData.
* @return 1= returned parameters are valid, 0=no ZF info found , <0 error
*/
int iso_stream_get_src_zf(IsoStream *stream, int *header_size_div4,
int *block_size_log2, uint32_t *uncompressed_size,
int flag);
int iso_stream_get_src_zf(IsoStream *stream, uint8_t zisofs_algo[2],
int *header_size_div4, int *block_size_log2,
uint64_t *uncompressed_size, int flag);
/**
* Set the inode number of a stream that is based on FSrcStreamData, i.e.
@ -103,5 +96,29 @@ int iso_stream_read_buffer(IsoStream *stream, char *buf, size_t count,
int iso_stream_make_md5(IsoStream *stream, char md5[16], int flag);
/**
* Create a clone of the input stream of old_stream and a roughly initialized
* clone of old_stream which has the same class and refcount 1. Its data
* pointer will be NULL and needs to be filled by an expert which knows how
* to clone the data of old_stream.
* @param old_stream The existing stream which is in process of cloning
* @param new_stream Will return the uninitialized memory object which shall
* later become the clone of old_stream.
* @param new_input The clone of the input stream of old stream.
* @param flag Submit 0 for now.
* @return ISO_SUCCESS or an error code <0
*/
int iso_stream_clone_filter_common(IsoStream *old_stream,
IsoStream **new_stream,
IsoStream **new_input, int flag);
/**
* Dispose the internal list of stream class cmp_ino() functions. It is
* a static global of stream.c, created and used by iso_stream_cmp_ino().
* This function is supposed to be called by iso_finish() only.
*/
int iso_stream_destroy_cmpranks(int flag);
#endif /*STREAM_H_*/

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2008 Vreixo Formoso
* Copyright (c) 2012 - 2024 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
@ -41,9 +42,333 @@ int make_isohybrid_mbr(int bin_lba, int *img_blocks, char *mbr, int flag);
*
* @param buf
* A buffer with at least 32 K allocated
* @param flag
* bit0= t->opts->ms_block is not counted in t->total_size
* @return
* 1 if success, < 0 on error
*/
int iso_write_system_area(Ecma119Image *t, uint8_t *buf);
int iso_write_system_area(Ecma119Image *t, uint8_t *buf, int flag);
/**
* Adjust t->tail_blocks to the eventual alignment needs of isohybrid booting.
*/
int iso_align_isohybrid(Ecma119Image *t, int flag);
/**
* Read the necessary ELF information from the first MIPS boot file.
* See doc/boot_sectors.txt "DEC Boot Block" for "MIPS Little Endian".
*/
int iso_read_mipsel_elf(Ecma119Image *t, int flag);
/* Compute size and position of appended partitions.
*/
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 following 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;
/* Only when representing an imported partition:
Path of file in imported ISO which holds the partition content.
NULL = no such file
*/
char *image_path;
};
/* 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(struct iso_mbr_partition_request **req_array,
int *mbr_req_count,
struct iso_mbr_partition_request *req, int flag);
/* Convenience frontend for iso_register_mbr_entry().
name and type are 0-terminated strings, which may get silently truncated.
*/
int iso_quick_mbr_entry(struct iso_mbr_partition_request **req_array,
int *mbr_req_count,
uint64_t start_block, uint64_t block_count,
uint8_t type_byte, uint8_t status_byte,
int desired_slot);
/* 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(struct iso_mbr_partition_request **req_array,
int mbr_req_count, int slot);
/* The parameter struct for production of a single Apple Partition Map entry.
See also the partial APM description in doc/boot_sectors.txt.
The list of entries is stored e.g. in Ecma119Image.apm_req, .apm_req_count.
The size of a block can be chosen by setting Ecma119Image.apm_block_size.
If an entry has start_block <=1, then its block_count will be adjusted
to the final size of the partition map.
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.
*/
uint64_t start_block;
uint64_t block_count;
/* All 32 bytes get copied to the system area.
Take care to pad up short strings by 0.
*/
uint8_t name[32];
uint8_t type[32];
/* Status of the request object itself:
bit0= this is an automatically placed filler partition
*/
uint32_t req_status;
/* Only when representing an imported partition:
Path of file in imported ISO which holds the partition content.
NULL = no such file
*/
char *image_path;
};
/* 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(struct iso_apm_partition_request **req_array,
int *apm_req_count,
struct iso_apm_partition_request *req, int flag);
/* Convenience frontend for iso_register_apm_entry().
name and type are 0-terminated strings, which may get silently truncated.
*/
int iso_quick_apm_entry(struct iso_apm_partition_request **req_array,
int *apm_req_count,
uint32_t start_block, uint32_t block_count,
char *name, char *type);
/* These two pseudo-random generators produce byte strings which will
surely not duplicate in the first 256 calls. If more calls are necessary
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 GPT disk or partition GUID.
Pseudo-random by iso_generate_gpt_guid() if t->gpt_uuid_counter is 0.
Else derived reproducibly by counter number from t->gpt_uuid_base.
*/
void iso_gpt_uuid(Ecma119Image *t, uint8_t uuid[16]);
/* Mark a given byte string as UUID version 4, RFC 4122.
*/
void iso_mark_guid_version_4(uint8_t *u);
/* 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 512 bytes.
*/
uint64_t start_block;
uint64_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];
/* Only if read from imported image: Table index of partition (first = 1)
*/
uint32_t idx;
/* Status of the request object itself:
bit0= this is an automatically placed filler partition
*/
uint32_t req_status;
/* Desired partition number in emerging GPT: first = 1, no desire = 0
GPT partitions get sorted by start LBA. Gaps of uncovered blocks get
filled. If the resulting sequence positions the partition at a lower
slot than desired, then empty slots get inserted to match the desire.
If the sequence positions the partition at a higher slot, then a mere
note is issued and the partition gets into the higher slot.
*/
int desired_slot;
/* Only when representing an imported partition:
Path of file in imported ISO which holds the partition content.
NULL = no such file
*/
char *image_path;
};
/* 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(struct iso_gpt_partition_request **req_array,
int *gpt_req_count,
struct iso_gpt_partition_request *req, int flag);
/* Convenience frontend for iso_register_gpt_entry().
name has to be already encoded as UTF-16LE.
*/
int iso_quick_gpt_entry(struct iso_gpt_partition_request **req_array,
int *gpt_req_count,
uint64_t start_block, uint64_t block_count,
uint8_t type_guid[16], uint8_t partition_guid[16],
uint64_t flags, uint8_t name[72]);
/* Deletes the partition requests for gap filling in GPT and APM.
Purpose is to get the request list clean again after a multi-session
emulation superblock was created and handed to the application.
*/
void iso_delete_gpt_apm_fillers(Ecma119Image *target, int flag);
/* 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);
/* The description of a loaded MIPS Big Endian Volume Directory Entry
*/
struct iso_mips_voldir_entry {
char name[9];
uint32_t boot_block;
uint32_t boot_bytes;
};
/* The description of a loaded SUN Disk Label partition */
struct iso_sun_disk_label_entry {
int idx;
uint16_t id_tag;
uint16_t permissions;
uint32_t start_cyl;
uint32_t num_blocks;
};
/* Creates the Partition Prepend writer.
*/
int partprepend_writer_create(Ecma119Image *target);
/* Creates the Inline Partition Append Writer
*/
int partappend_writer_create(Ecma119Image *target);
/* Creates the GPT backup tail writer.
*/
int gpt_tail_writer_create(Ecma119Image *target);
/* Not for execution but only to identify the writer by
( writer->write_vol_desc == gpt_tail_writer_write_vol_desc )
*/
int gpt_tail_writer_write_vol_desc(IsoImageWriter *writer);
/* Only for up to 36 characters ISO-8859-1 (or ASCII) input */
void iso_ascii_utf_16le(uint8_t gap_name[72]);
/* Parameters of MBR patching for GRUB2
Might later become variables in Ecma119Image
*/
#define Libisofs_grub2_mbr_patch_poS 0x1b0
#define Libisofs_grub2_mbr_patch_offsT 4
/* Parameters of SUN Disk Label patching for GRUB2
See API iso_image_set_sparc_core().
*/
#define Libisofs_grub2_sparc_patch_adr_poS 0x228
#define Libisofs_grub2_sparc_patch_size_poS 0x230
/* Put appended partitions into the writer range
*/
#define Libisofs_appended_partitions_inlinE yes
#ifdef Libisofs_appended_partitions_inlinE
/* For padding after appended partitions (and also after backup GPT)
*/
#define Libisofs_part_align_writeR yes
#endif
#endif /* SYSTEM_AREA_H_ */

File diff suppressed because it is too large Load Diff

View File

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

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 - 2022 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
@ -11,9 +11,22 @@
#ifndef LIBISO_UTIL_H_
#define LIBISO_UTIL_H_
#ifdef HAVE_STDINT_H
#include <stdint.h>
#else
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#endif
#include <time.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#include <fcntl.h>
#ifndef MAX
# define MAX(a, b) (((a) > (b)) ? (a) : (b))
#endif
@ -42,16 +55,23 @@ int iso_init_locale(int flag);
* @param ocharset
* Output charset. Must be supported by iconv
* @param output
* Location where the pointer to the ouput string will be stored
* Location where the pointer to the output string will be stored
* @return
* 1 on success, < 0 on error
*/
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
*
@ -60,7 +80,7 @@ int strnconv(const char *str, const char *icharset, const char *ocharset,
* @param input
* Input string
* @param output
* Location where the pointer to the ouput string will be stored
* Location where the pointer to the output string will be stored
* @return
* 1 on success, < 0 on error
*/
@ -75,19 +95,38 @@ int str2ascii(const char *icharset, const char *input, char **output);
* @param input
* Input string
* @param output
* Location where the pointer to the ouput string will be stored
* Location where the pointer to the output string will be stored
* @return
* 1 on success, < 0 on error
*/
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 output 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.
*
* @param src
* The identifier, in ASCII encoding.
* @param relaxed
* 0 only allow d-characters, 1 allow also lowe case chars,
* 2 allow all characters
*/
char *iso_1_dirid(const char *src);
char *iso_1_dirid(const char *src, int relaxed);
/**
* Create a level 2 directory identifier.
@ -117,8 +156,13 @@ char *iso_r_dirid(const char *src, int size, int relaxed);
*
* @param src
* The identifier, in ASCII encoding.
* @param relaxed
* 0 only allow d-characters, 1 allow also lowe case chars,
* 2 allow all characters
* @param force_dots
* If 1 then prepend empty extension by SEPARATOR1 = '.'
*/
char *iso_1_fileid(const char *src);
char *iso_1_fileid(const char *src, int relaxed, int force_dots);
/**
* Create a level 2 file identifier.
@ -146,16 +190,19 @@ char *iso_r_fileid(const char *src, size_t len, int relaxed, int forcedot);
/**
* Create a Joliet file identifier that consists of name and extension. The
* combined name and extension length will not exceed 128 bytes, and the
* name and extension will be separated (.). All characters consist of
* 2 bytes and the resulting string is NULL-terminated by a 2-byte NULL.
* combined name and extension length will normally not exceed 64 characters
* (= 128 bytes). The name and the extension will be separated (.).
* All characters consist of 2 bytes and the resulting string is
* NULL-terminated by a 2-byte NULL.
*
* Note that version number and (;1) is not appended.
*
* @param flag
* bit0= no_force_dots
* bit1= allow 103 characters rather than 64
* @return
* NULL if the original name and extension both are of length 0.
*/
uint16_t *iso_j_file_id(const uint16_t *src);
uint16_t *iso_j_file_id(const uint16_t *src, int flag);
/**
* Create a Joliet directory identifier that consists of name and optionally
@ -163,10 +210,12 @@ uint16_t *iso_j_file_id(const uint16_t *src);
* and the name and extension will be separated (.). All characters consist of
* 2 bytes and the resulting string is NULL-terminated by a 2-byte NULL.
*
* @param flag
* bit1= allow 103 characters rather than 64
* @return
* NULL if the original name and extension both are of length 0.
*/
uint16_t *iso_j_dir_id(const uint16_t *src);
uint16_t *iso_j_dir_id(const uint16_t *src, int flag);
/**
* Like strlen, but for Joliet strings.
@ -200,18 +249,35 @@ 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
* 1 on succes, < 0 error, 0 if input was null (output is set to null)
* 1 on success, < 0 error, 0 if input was null (output is set to null)
*/
int str2d_char(const char *icharset, const char *input, char **output);
int str2a_char(const char *icharset, const char *input, char **output);
/* Check for membership in the d-, a-, or j-character set */
int valid_d_char(char c);
int valid_a_char(char c);
int valid_j_char(uint16_t c);
void iso_lsb(uint8_t *buf, uint32_t num, int bytes);
void iso_lsb64(uint8_t *buf, uint64_t num);
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);
@ -220,6 +286,9 @@ uint32_t iso_read_msb(const uint8_t *buf, int bytes);
*/
uint32_t iso_read_bb(const uint8_t *buf, int bytes, int *error);
uint64_t iso_read_lsb64(const uint8_t *buf);
uint64_t iso_read_msb64(const uint8_t *buf);
/**
* Records the date/time into a 7 byte buffer (ECMA-119, 9.1.5)
*
@ -338,13 +407,19 @@ size_t iso_rbtree_get_size(IsoRBTree *tree);
* without counting the final NULL item.
* @return
* A sorted array with the contents of the tree, or NULL if there is not
* enought memory to allocate the array. You should free(3) the array when
* enough memory to allocate the array. You should free(3) the array when
* no more needed. Note that the array is NULL-terminated, and thus it
* has size + 1 length.
*/
void **iso_rbtree_to_array(IsoRBTree *tree, int (*include_item)(void *),
size_t *size);
/** Predict the size of the array which gets returned by iso_rbtree_to_array().
*/
size_t iso_rbtree_count_array(IsoRBTree *tree, size_t initial_count,
int (*include_item)(void *));
/**
* Create a new hash table.
*
@ -491,6 +566,14 @@ int iso_util_eval_md5_tag(char *block, int desired, uint32_t lba,
int iso_util_tag_magic(int tag_type, char **tag_magic, int *len, int flag);
int iso_util_bin_to_hex(char *target, uint8_t *bytes, int num_bytes, int flag);
int iso_util_hex_to_bin(char *hex, char *bin, int bin_size, int *bin_count,
int flag);
int iso_truncate_rr_name(int truncate_mode, int truncate_length,
char *name, int flag);
/* ------------------------------------------------------------------------- */
/* In md5.h these function prototypes would be neighbors of (Ecma119Image *)
@ -504,13 +587,84 @@ int iso_util_tag_magic(int tag_type, char **tag_magic, int *len, int flag);
*/
int checksum_cx_xinfo_func(void *data, int flag);
/* The iso_node_xinfo_cloner function which gets associated to
* checksum_cx_xinfo_func by iso_init() resp. iso_init_with_flag() via
* iso_node_xinfo_make_clonable()
*/
int checksum_cx_xinfo_cloner(void *old_data, void **new_data, int flag);
/* Function to identify and manage md5 sums of unspecified providence stored
* directly in this xinfo. This is supposed to override any other recorded
* MD5 of the node unless data get copied and checksummed during that copying.
*/
int checksum_md5_xinfo_func(void *data, int flag);
/* The iso_node_xinfo_cloner function which gets associated to
* checksum_md5_xinfo_func by iso_init() resp. iso_init_with_flag() via
* iso_node_xinfo_make_clonable()
*/
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);
/* ------------------------------------------------------------------------- */
void *iso_alloc_mem(size_t size, size_t count, int flag);
#define LIBISO_ALLOC_MEM(pt, typ, count) { \
pt= (typ *) iso_alloc_mem(sizeof(typ), (size_t) (count), 0); \
if(pt == NULL) { \
ret= ISO_OUT_OF_MEM; goto ex; \
} }
#define LIBISO_ALLOC_MEM_VOID(pt, typ, count) { \
pt= (typ *) iso_alloc_mem(sizeof(typ), (size_t) (count), 0); \
if(pt == NULL) { \
goto ex; \
} }
#define LIBISO_FREE_MEM(pt) { \
if(pt != NULL) \
free((char *) pt); \
}
/*
@param in Valid memory or NULL
@param out Returns valid memory or NULL
@param size Number of bytes to copy. 0 means strlen(in)+1 if not NULL.
@return 1 or ISO_OUT_OF_MEM
*/
int iso_clone_mem(char *in, char **out, size_t size);
/* Like iso_clone_mem but first freeing *out if not NULL
*/
int iso_clone_mgtd_mem(char *in, char **out, size_t size);
/** Convert a text into a number of type double and multiply it by unit code
[kmgt] (2^10 to 2^40) or [s] (2048) or [d] (512).
(Also accepts capital letters.)
@param text Input like "42", "223062s", "3m" or "-1g"
@param flag Bitfield for control purposes:
bit0= return -1 rather than 0 on failure
bit1= if scaled then compute the last byte of the last unit
@return The derived value
*/
off_t iso_scanf_io_size(char *text, int flag);
/* ------------------------------------------------------------------------- */
/* 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_*/

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
@ -7,6 +8,10 @@
* See COPYING file for details.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include "util.h"
#include "libisofs.h"
@ -318,9 +323,10 @@ int iso_htable_create(size_t size, hash_funtion_t hash,
{
IsoHTable *t;
if (table == NULL) {
return ISO_OUT_OF_MEM;
}
if (size <= 0)
return ISO_WRONG_ARG_VALUE;
if (table == NULL)
return ISO_NULL_POINTER;
t = malloc(sizeof(IsoHTable));
if (t == NULL) {

View File

@ -7,6 +7,10 @@
* See COPYING file for details.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include "util.h"
#include "libisofs.h"
@ -160,7 +164,7 @@ int iso_rbtree_insert(IsoRBTree *tree, void *data, void **item)
new = data;
added = 1;
} else {
struct iso_rbnode head = { 0 }; /* False tree root */
struct iso_rbnode head = { 0, {NULL, NULL}, 0 }; /* False tree root */
struct iso_rbnode *g, *t; /* Grandparent & parent */
struct iso_rbnode *p, *q; /* Iterator & parent */
@ -273,7 +277,7 @@ size_t rbtree_to_array_aux(struct iso_rbnode *root, void **array, size_t pos,
* NULL pointer.
* @return
* A sorted array with the contents of the tree, or NULL if there is not
* enought memory to allocate the array. You should free(3) the array when
* enough memory to allocate the array. You should free(3) the array when
* no more needed. Note that the array is NULL-terminated, and thus it
* has size + 1 length.
*/
@ -281,7 +285,7 @@ void ** iso_rbtree_to_array(IsoRBTree *tree, int (*include_item)(void *),
size_t *size)
{
size_t pos;
void **array;
void **array, **new_array;
array = malloc((tree->size + 1) * sizeof(void*));
if (array == NULL) {
@ -292,10 +296,50 @@ void ** iso_rbtree_to_array(IsoRBTree *tree, int (*include_item)(void *),
pos = rbtree_to_array_aux(tree->root, array, 0, include_item);
array[pos] = NULL;
array = realloc(array, (pos + 1) * sizeof(void*));
new_array = realloc(array, (pos + 1) * sizeof(void*));
if (new_array == NULL) {
free((char *) array);
return NULL;
}
array= new_array;
if (size) {
*size = pos;
}
return array;
}
static
size_t rbtree_count_array_aux(struct iso_rbnode *root, size_t pos,
int (*include_item)(void *))
{
if (root == NULL) {
return pos;
}
pos = rbtree_count_array_aux(root->ch[0], pos, include_item);
if (include_item == NULL || include_item(root->data)) {
/*
{
IsoFileSrc* src = (IsoFileSrc*) root->data;
fprintf(stderr, "libisofs_DEBUG: rbtree_count_array_aux : not taken : '%s'\n",
iso_stream_get_source_path(src->stream, 0));
}
*/
pos++;
}
pos = rbtree_count_array_aux(root->ch[1], pos, include_item);
return pos;
}
size_t iso_rbtree_count_array(IsoRBTree *tree, size_t initial_count,
int (*include_item)(void *))
{
size_t pos;
pos = rbtree_count_array_aux(tree->root, initial_count, include_item);
return pos;
}

View File

@ -29,13 +29,13 @@ struct Iso_Image_Writer
};
/**
* This is the function all Writers shoudl call to write data to image.
* This is the function all Writers should call to write data to image.
* Currently, it is just a wrapper for write(2) Unix system call.
*
* It is implemented in ecma119.c
*
* @return
* 1 on sucess, < 0 error
* 1 on success, < 0 error
*/
int iso_write(Ecma119Image *target, void *buf, size_t count);