Compare commits
201 Commits
release-0.
...
release-1.
Author | SHA1 | Date | |
---|---|---|---|
e80dd0735b | |||
c276681735 | |||
1d723f0834 | |||
1a4b2a2584 | |||
4eb2a7199c | |||
6d5e68fd01 | |||
fed8b23017 | |||
e3329a98a9 | |||
49efbdad76 | |||
9538a5d57b | |||
66dc6c2d0e | |||
81608815ae | |||
ae5ab4a08f | |||
76b6737570 | |||
9210a57500 | |||
8a752b50fa | |||
c38b1a3a3a | |||
73c9c7f244 | |||
0b9f03bb23 | |||
d1c3a017e3 | |||
b200feceed | |||
7958b2ea22 | |||
c0bdf4d3b5 | |||
71efc996e3 | |||
61383dea2d | |||
270cd1cad5 | |||
559e9b564d | |||
d8a56f60ef | |||
10e3b2939a | |||
ba67523278 | |||
f09964cf51 | |||
e4a70a823d | |||
655d86b97a | |||
f2f780115b | |||
b6be8457f7 | |||
1238c19494 | |||
2caf527f67 | |||
43eae7502b | |||
e035146e01 | |||
de3e21629f | |||
d79a3fcec4 | |||
de079cec42 | |||
b33d06eb0c | |||
dfdaa2902a | |||
0173c51c23 | |||
a118127e9c | |||
1f24b39879 | |||
16863755be | |||
b25ac0f52d | |||
5c59295e72 | |||
85893bf58b | |||
722327e4b8 | |||
ab0a981814 | |||
38483d894e | |||
1082e628d1 | |||
74c68224c7 | |||
200697898d | |||
a3eeda3d23 | |||
92073c45ef | |||
81cded618d | |||
84c0bd37ff | |||
4e60feaeab | |||
d6e150a10e | |||
35ceac65f7 | |||
45ffdef845 | |||
55d6ae343d | |||
a69f45e8cd | |||
68c3ae522e | |||
8e2748f23b | |||
f923a79929 | |||
362b15f4d5 | |||
2649045dfe | |||
3d427bdf70 | |||
8b2af3ac36 | |||
113358daea | |||
6927fd35e8 | |||
fb231ff186 | |||
b2fde289b1 | |||
dcc6ffd184 | |||
27e69c38ab | |||
f4b2bfc0d6 | |||
5482d5d7b4 | |||
b2997dcc46 | |||
48ae8acbd6 | |||
a488f8fb14 | |||
ea8da1f7d3 | |||
8ad92a08ea | |||
35c043a0f9 | |||
fce35ac718 | |||
01518896f9 | |||
caf90e35f5 | |||
1f486fd78b | |||
b58d1e28ef | |||
ebb5937568 | |||
ef444fb29c | |||
1ccbaa302c | |||
0d35100eb0 | |||
48316af1d9 | |||
a75fb9a894 | |||
a0ba4b976c | |||
870280a018 | |||
f33df0ef29 | |||
2a087f6f39 | |||
b07d3ab0c3 | |||
f12df92600 | |||
8a75d35c46 | |||
bb28c69cae | |||
25068a4de2 | |||
d2094a0d80 | |||
16dcf4a29c | |||
69a25c9734 | |||
a387a8b06a | |||
a9af97733e | |||
c30674095b | |||
be838b6940 | |||
b0c79a9a1e | |||
8725baa55f | |||
59ab73c57f | |||
7386596bfa | |||
4833ef23e5 | |||
14171bdd3a | |||
d37eba5344 | |||
3b616dae38 | |||
a2758b27e6 | |||
d5c4af7378 | |||
90f37b8183 | |||
1d4f26f325 | |||
08e442a2ab | |||
017dcb39f2 | |||
95121e2f9f | |||
ba11413a6f | |||
e1888df5ab | |||
dceef03633 | |||
443c5d41db | |||
e60171986b | |||
fe45249e9e | |||
b01f017a6d | |||
73bc3ae512 | |||
b6427d3b2b | |||
438024d11b | |||
1d6fdf51dc | |||
281462802f | |||
2b2a86ea2e | |||
c0963596e5 | |||
9be5b241e2 | |||
fcde936670 | |||
73c6bc49c6 | |||
5ed507da83 | |||
ae626b9570 | |||
3528493b92 | |||
9cf460a3b1 | |||
84132ec7bf | |||
eb23260459 | |||
4978424328 | |||
e4cf93665a | |||
3d9367d52a | |||
03b030c56d | |||
a3fe82100b | |||
02d7a690eb | |||
ace0d1ab2e | |||
59d143c1f0 | |||
da2c0520cc | |||
517f520570 | |||
98d2b4c996 | |||
481d425580 | |||
99e988d652 | |||
38a7b4a5b1 | |||
9dc894584d | |||
1a7ab679cd | |||
016baf9984 | |||
b089f2e978 | |||
c3d5ab7bc7 | |||
f13167335a | |||
f0f378c38f | |||
907b44c556 | |||
00011036dd | |||
55497d3931 | |||
c47f206fe3 | |||
386ce0e60a | |||
9fe4172f0d | |||
61f2cdd02b | |||
f87c63da41 | |||
afebbe187d | |||
3951df25be | |||
4b0f175a89 | |||
633a8ada9e | |||
ce723a8c39 | |||
83ace3b486 | |||
23d3c43022 | |||
00470cbfea | |||
4c1abdf2bd | |||
f7842518fb | |||
d756551385 | |||
ced02f5903 | |||
819e3218f6 | |||
c874a159e2 | |||
a68e108333 | |||
da23a8166c | |||
cbb376a137 | |||
3852621bc0 | |||
0ff4cb34ed |
@ -1,12 +1,12 @@
|
|||||||
Vreixo Formoso <metalpain2002@yahoo.es>,
|
Vreixo Formoso <metalpain2002@yahoo.es>,
|
||||||
Mario Danic <mario.danic@gmail.com>,
|
Mario Danic <mario.danic@gmail.com>,
|
||||||
Thomas Schmitt <scdbackup@gmx.net>
|
Thomas Schmitt <scdbackup@gmx.net>
|
||||||
Copyright (C) 2007-2008 Vreixo Formoso, Mario Danic, Thomas Schmitt
|
Copyright (C) 2007-2011 Vreixo Formoso, Mario Danic, Thomas Schmitt
|
||||||
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License version 2 as
|
it under the terms of the GNU General Public License version 2 or later
|
||||||
published by the Free Software Foundation.
|
as published by the Free Software Foundation.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
253
ChangeLog
253
ChangeLog
@ -1 +1,254 @@
|
|||||||
|
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
|
||||||
|
|
||||||
|
@ -16,7 +16,9 @@ libisofs_libisofs_la_LDFLAGS = \
|
|||||||
|
|
||||||
# Eventually enabling system adapters for ACL and EA.
|
# Eventually enabling system adapters for ACL and EA.
|
||||||
# ts A90409: Eventually enabling use of zlib.
|
# ts A90409: Eventually enabling use of zlib.
|
||||||
libisofs_libisofs_la_CFLAGS = $(LIBACL_DEF) $(XATTR_DEF) $(ZLIB_DEF)
|
# ts B00927: Eventually enabling use of libjte (Jigdo Template Extraction)
|
||||||
|
libisofs_libisofs_la_CFLAGS = $(LIBACL_DEF) $(XATTR_DEF) $(ZLIB_DEF) \
|
||||||
|
$(LIBJTE_DEF)
|
||||||
|
|
||||||
# ts A90114 : added aaip_0_2.*
|
# ts A90114 : added aaip_0_2.*
|
||||||
|
|
||||||
@ -42,7 +44,6 @@ libisofs_libisofs_la_SOURCES = \
|
|||||||
libisofs/stream.c \
|
libisofs/stream.c \
|
||||||
libisofs/filter.h \
|
libisofs/filter.h \
|
||||||
libisofs/filter.c \
|
libisofs/filter.c \
|
||||||
libisofs/filters/xor_encrypt.c \
|
|
||||||
libisofs/filters/external.c \
|
libisofs/filters/external.c \
|
||||||
libisofs/filters/zisofs.c \
|
libisofs/filters/zisofs.c \
|
||||||
libisofs/filters/gzip.c \
|
libisofs/filters/gzip.c \
|
||||||
@ -81,6 +82,9 @@ libisofs_libisofs_la_LIBADD= \
|
|||||||
libinclude_HEADERS = \
|
libinclude_HEADERS = \
|
||||||
libisofs/libisofs.h
|
libisofs/libisofs.h
|
||||||
|
|
||||||
|
install-exec-hook:
|
||||||
|
$(LIBBURNIA_LDCONFIG_CMD) "$(DESTDIR)$(libdir)" || echo 'NOTE: Explicite dynamic library configuration failed. If needed, configure manually for:' "$(DESTDIR)$(libdir)"
|
||||||
|
|
||||||
## ========================================================================= ##
|
## ========================================================================= ##
|
||||||
|
|
||||||
## Build demo applications
|
## Build demo applications
|
||||||
@ -262,6 +266,7 @@ EXTRA_DIST = \
|
|||||||
doc/susp_aaip_isofs_names.txt \
|
doc/susp_aaip_isofs_names.txt \
|
||||||
doc/zisofs_format.txt \
|
doc/zisofs_format.txt \
|
||||||
doc/checksums.txt \
|
doc/checksums.txt \
|
||||||
|
libisofs/libisofs.ver \
|
||||||
libisofs/aaip-os-dummy.c \
|
libisofs/aaip-os-dummy.c \
|
||||||
libisofs/aaip-os-linux.c \
|
libisofs/aaip-os-linux.c \
|
||||||
libisofs/aaip-os-freebsd.c
|
libisofs/aaip-os-freebsd.c
|
||||||
|
376
README
376
README
@ -4,15 +4,69 @@
|
|||||||
|
|
||||||
Released under GPL (see COPYING file for details).
|
Released under GPL (see COPYING file for details).
|
||||||
|
|
||||||
Copyright (C) 2008 Vreixo Formoso, Mario Danic, Thomas Schmitt
|
Copyright (C) 2008 - 2010 Vreixo Formoso, Mario Danic, Thomas Schmitt
|
||||||
|
|
||||||
libisofs is part of the libburnia project (libburnia-project.org)
|
libisofs is part of the libburnia project (libburnia-project.org)
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
libisofs is a library to create an ISO-9660 filesystem, and supports extensions
|
Download, Build and Installation
|
||||||
like RockRidge or Joliet. It is also a full featured ISO-9660 editor, allowing
|
|
||||||
you to modify an ISO image or multisession disc, including file addition and
|
libisofs code is mantained in a Bazaar repository at Launchpad
|
||||||
removal, change of file names and attributes, etc
|
(https://launchpad.net/libisofs/). You can download it with:
|
||||||
|
|
||||||
|
$ bzr branch lp:libisofs/for-libisoburn
|
||||||
|
|
||||||
|
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. For the most recent release of libisofs see:
|
||||||
|
http://libburnia-project.org/wiki/Releases
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
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
|
||||||
|
like RockRidge or Joliet, and introduces an own extension AAIP.
|
||||||
|
It is a full featured ISO-9660 editor which composes and changes the directory
|
||||||
|
tree of an ISO image. This tree and its newly imported data file contents get
|
||||||
|
then written as independent single-session image or as add-on session for the
|
||||||
|
image from where the tree was originally loaded.
|
||||||
|
|
||||||
Features:
|
Features:
|
||||||
---------
|
---------
|
||||||
@ -20,32 +74,54 @@ Features:
|
|||||||
- Image creation
|
- Image creation
|
||||||
- Creates ISO-9660 images from local files.
|
- Creates ISO-9660 images from local files.
|
||||||
- Support for RockRidge and Joliet extensions.
|
- Support for RockRidge and Joliet extensions.
|
||||||
- Support for ISO-9660:1999 (version 2)
|
- 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.
|
||||||
- Full featured edition of file names and attributes on the image.
|
- Support for multi-extent data files up to 400 GB (level 3).
|
||||||
- Several options to relax ISO-9660 constraints.
|
|
||||||
- Special options for images intended for distribution (suitable default
|
|
||||||
modes for files, hiding of real timestamps...)
|
|
||||||
- Multisession
|
|
||||||
- Support for growing an existing image
|
|
||||||
- Full-featured edition of the image files, including: addition of new
|
- Full-featured edition of the image files, including: addition of new
|
||||||
files, removing of existent files, moving files, renaming files,
|
files, removing of existent files, moving files, renaming files,
|
||||||
change file attributes (permissions, timestamps...)
|
change file attributes (permissions, timestamps...)
|
||||||
- Support for "emulated multisession" or image growing, suitable for non
|
- Optional recording per file of non-ISO 9660 features:
|
||||||
multisession media such as DVD+RW
|
ACL, xattr, content MD5, hard link relations.
|
||||||
|
They do not hamper image readability by operating systems but can be
|
||||||
|
retrieved only via libisofs.
|
||||||
|
- Optional zisofs compression, gzip compression, external filter
|
||||||
|
processes.
|
||||||
|
- Several options to relax ISO-9660 constraints.
|
||||||
|
- Special options for images intended for distribution (suitable
|
||||||
|
default modes for files, hiding of real timestamps...).
|
||||||
|
- Image reading
|
||||||
|
- Image tree and data heap can be verified by stream reading and
|
||||||
|
eventually recorded MD5 tags.
|
||||||
|
- Directory tree and file attributes of ISO 9660 session get loaded
|
||||||
|
into memory for editing or for extraction into local filesystem.
|
||||||
|
- File content can be read by applications.
|
||||||
|
- Automatic zisofs decompression.
|
||||||
|
- Optional application of gzip decompression or external filter
|
||||||
|
processes.
|
||||||
|
- Eventually recorded MD5 of data file can be obtained, MD5 of data
|
||||||
|
stream can be computed and compared.
|
||||||
|
- Helper functions for restoring ACL and/or xattr to the local
|
||||||
|
filesystem.
|
||||||
|
- Multisession
|
||||||
|
- Support for growing an existing image on multi-session media.
|
||||||
|
- Support for "emulated multisession" on overwriteable media such as
|
||||||
|
DVD+RW, USB sticks, regular files.
|
||||||
|
- Support for blindly prepared add-on sessions (mkisofs style -M -C)
|
||||||
|
suitable for pipes which lead to an external burn program.
|
||||||
- Image modification
|
- Image modification
|
||||||
- It can create a completely new image from files on another image.
|
- Creates a completely new image from files out of another image and
|
||||||
- Full-featured edition of image contents
|
eventual editing operations. Suitable for any target medium.
|
||||||
- Others
|
- Others
|
||||||
- Handling of different input and output charset
|
- Handling of different input and output charset.
|
||||||
- Good integration with libburn for image burning.
|
- Good integration with libburn for image burning.
|
||||||
- Reliable, good handling of different kind of errors.
|
- Reliable, good handling of different kind of errors.
|
||||||
|
|
||||||
Requirements:
|
Requirements:
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
- libburn 0.4.2 headers must be installed at compile time. It is not required
|
- iconv() functions for character set conversion must be available.
|
||||||
at runtime.
|
Either implicitely as in Linux or by a separate library like libiconv
|
||||||
|
on FreeBSD.
|
||||||
|
|
||||||
Know bugs:
|
Know bugs:
|
||||||
----------
|
----------
|
||||||
@ -55,32 +131,20 @@ Multisession and image growing can lead to undesired results in several cases:
|
|||||||
a) Images with unsupported features, such as:
|
a) Images with unsupported features, such as:
|
||||||
- UDF.
|
- UDF.
|
||||||
- HSF/HFS+ or other Mac extensions.
|
- HSF/HFS+ or other Mac extensions.
|
||||||
- El-Torito with multiple entries.
|
- ECMA-119 Extended attributes.
|
||||||
- ECMA-119 with extended attributes, multiple extends per file.
|
|
||||||
- Non El-Torito boot info.
|
|
||||||
- zisofs compressed images.
|
|
||||||
- ...
|
- ...
|
||||||
In all these cases, the resulting new image (or new session) could lack some
|
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
|
In some cases libisofs will issue warning messages, or even refuse to grow
|
||||||
or modify the image. Others remain undetected. Images created with libisofs
|
or modify the image. Others remain undetected. Images created with libisofs
|
||||||
do not have this problems.
|
do not have this problems.
|
||||||
|
|
||||||
b) Bootable El-Torito images may have several problems, that result in a new
|
b) Bootable El-Torito images may have problems, that result in a new image that
|
||||||
image that is not bootable, or that boots from an outdated session. In many
|
is not bootable, or that boots from an outdated session. In some cases it
|
||||||
cases it is recommended to add boot info again in the new session.
|
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
|
||||||
- isolinux images won't be bootable after a modify. This is because
|
boot image can't be figured out.
|
||||||
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.
|
|
||||||
|
|
||||||
c) Generated images could have different ECMA-119 low level names, due to
|
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
|
different way to mangle names, to new files added that force old files to
|
||||||
@ -91,210 +155,11 @@ c) Generated images could have different ECMA-119 low level names, due to
|
|||||||
relaxed contraints), otherwise libisofs might arbitrarily change the names.
|
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.
|
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Overview of libburnia-project.org
|
|
||||||
|
|
||||||
libburnia-project.org is an open-source software project for reading, mastering
|
|
||||||
and writing optical discs.
|
|
||||||
For now this means only CD media and all single layer DVD media except DVD+R.
|
|
||||||
|
|
||||||
The project comprises of several more or less interdependent parts which
|
|
||||||
together strive to be a usable foundation for application development.
|
|
||||||
These are libraries, language bindings, and middleware binaries which emulate
|
|
||||||
classical (and valuable) Linux tools.
|
|
||||||
|
|
||||||
Our scope is currently Linux 2.4 and 2.6 only. For ports to other systems
|
|
||||||
we would need : login on a development machine resp. a live OS on CD or DVD,
|
|
||||||
advise from a system person about the equivalent of Linux sg or FreeBSD CAM,
|
|
||||||
volunteers for testing of realistic use cases.
|
|
||||||
|
|
||||||
We have a workable code base for burning CD and most single layer DVD.
|
|
||||||
The burn API is quite comprehensively documented and can be used to build a
|
|
||||||
presentable application.
|
|
||||||
We have a functional binary which emulates parts of cdrecord in order to
|
|
||||||
prove that usability, and in order to allow you to explore libburnia's scope
|
|
||||||
by help of existing cdrecord frontends.
|
|
||||||
|
|
||||||
The project components (list subject to growth, hopefully):
|
|
||||||
|
|
||||||
- libburn is the library by which preformatted data get onto optical media.
|
|
||||||
It uses either /dev/sgN (e.g. on kernel 2.4 with ide-scsi) or
|
|
||||||
/dev/hdX (e.g. on kernel 2.6).
|
|
||||||
libburn is the foundation of our cdrecord emulation. Its code is
|
|
||||||
independent of cdrecord. Its DVD capabilities are learned from
|
|
||||||
studying the code of dvd+rw-tools and MMC-5 specs. No code but only
|
|
||||||
the pure SCSI knowledge has been taken from dvd+rw-tools, though.
|
|
||||||
|
|
||||||
- libisofs is the library to pack up hard disk files and directories into a
|
|
||||||
ISO 9660 disk image. This may then be brought to media via libburn.
|
|
||||||
libisofs is to be the foundation of our upcoming mkisofs emulation.
|
|
||||||
|
|
||||||
- cdrskin is a limited cdrecord compatibility wrapper for libburn.
|
|
||||||
Cdrecord is a powerful GPL'ed burn program included in Joerg
|
|
||||||
Schilling's cdrtools. cdrskin strives to be a second source for
|
|
||||||
the services traditionally provided by cdrecord. Additionally it
|
|
||||||
provides libburn's DVD capabilities, where only -sao is compatible
|
|
||||||
with cdrecord.
|
|
||||||
cdrskin does not contain any bytes copied from cdrecord's sources.
|
|
||||||
Many bytes have been copied from the message output of cdrecord
|
|
||||||
runs, though.
|
|
||||||
See cdrskin/README and man cdrskin/cdrskin.1 for more.
|
|
||||||
|
|
||||||
- test is a collection of application gestures and examples given by the
|
|
||||||
authors of the library features. The main API example for libburn
|
|
||||||
is test/libburner.c .
|
|
||||||
Explore these examples if you look for inspiration.
|
|
||||||
|
|
||||||
We plan to be a responsive upstream. Bear with us. We are still practicing.
|
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Project history as far as known to me:
|
|
||||||
|
|
||||||
- Founded in 2002 as it seems. See mailing list archives
|
|
||||||
http://lists.freedesktop.org/archives/libburn/
|
|
||||||
The site of this founder team is reachable and offers download of a
|
|
||||||
(somewhat outdated) tarball and from CVS :
|
|
||||||
http://icculus.org/burn/
|
|
||||||
Copyright holders and most probably founders:
|
|
||||||
Derek Foreman and Ben Jansens.
|
|
||||||
|
|
||||||
- I came to using libburn in 2005. Founded the cdrskin project and submitted
|
|
||||||
necessary patches which were accepted or implemented better. Except one
|
|
||||||
remaining patch which prevented cdrskin from using vanilla libburn from CVS.
|
|
||||||
The cdrskin project site is reachable and offers download of the heavily
|
|
||||||
patched (elsewise outdated) tarball under the name cdrskin-0.1.2 :
|
|
||||||
http://scdbackup.sourceforge.net/cdrskin_eng.html
|
|
||||||
It has meanwhile moved to use vanilla libburn.pykix.org , though.
|
|
||||||
Version 0.1.4 constitutes the first release of this kind.
|
|
||||||
|
|
||||||
- In July 2006 our team mate Mario Danic announced a revival of libburn
|
|
||||||
which by about nearly everybody else was perceived as unfriendly fork.
|
|
||||||
Derek Foreman four days later posted a message which expressed his
|
|
||||||
discontent.
|
|
||||||
The situation first caused me to publically regret it and then - after i
|
|
||||||
got the opportunity to move in with cdrskin - gave me true reason to
|
|
||||||
personally apologize to Derek Foreman, Ben Jansens and the contibutors at
|
|
||||||
icculus.org/burn. Posted to both projects:
|
|
||||||
http://lists.freedesktop.org/archives/libburn/2006-August/000446.html
|
|
||||||
http://mailman-mail1.webfaction.com/pipermail/libburn-hackers/2006-August/000024.html
|
|
||||||
|
|
||||||
- Mid August 2006 project cdrskin established a branch office in
|
|
||||||
libburn.pykix.org so that all maintainers of our tools have one single place
|
|
||||||
to get the current (at least slightely) usable coordinated versions of
|
|
||||||
everything.
|
|
||||||
Project cdrskin will live forth independendly for a while but it is committed
|
|
||||||
to stay in sync with libburn.pykix.org (or some successor, if ever).
|
|
||||||
cdrskin is also committed to support icculus.org/burn if the pending fork
|
|
||||||
is made reality by content changes in that project. It will cease to maintain
|
|
||||||
a patched version of icculus.org/burn though. Precondition for a new
|
|
||||||
release of cdrskin on base of icculus.org/burn would be the pending
|
|
||||||
"whitelist patch" therefore.
|
|
||||||
I would rather prefer if both projects find consense and merge, or at least
|
|
||||||
cooperate. I have not given up hope totally, yet.
|
|
||||||
I, personally, will honor any approach.
|
|
||||||
|
|
||||||
- 2nd September 2006 the decision is made to strive for a consolidation of
|
|
||||||
copyright and a commitment to GPL in a reasonable and open minded way.
|
|
||||||
This is to avoid long term problems with code of unknown origin and
|
|
||||||
with finding consense among the not so clearly defined group of copyright
|
|
||||||
claimers and -holders.
|
|
||||||
libisofs is already claimed sole copyright Mario Danic.
|
|
||||||
cdrskin and libburner are already claimed sole copyright Thomas Schmitt.
|
|
||||||
Rewrites of other components will follow and concluded by claiming full
|
|
||||||
copyright within the group of libburn.pykix.org-copyright holders.
|
|
||||||
|
|
||||||
- 16th September 2006 feature freeze for release of libburn-0.2.2 .
|
|
||||||
|
|
||||||
- 20th September 2006 release of libburn-0.2.2 .
|
|
||||||
|
|
||||||
- 26th October 2006 feature freeze for cdrskin-0.2.4 based on libburn-0.2.3 .
|
|
||||||
This version of cdrskin is much more cdrecord compatible in repect
|
|
||||||
to drive addressing and audio features.
|
|
||||||
|
|
||||||
- 30th October 2006 release of cdrskin-0.2.4 .
|
|
||||||
|
|
||||||
- 13th November 2006 splitting releases of libburn+cdrskin from libisofs.
|
|
||||||
|
|
||||||
- 24th November 2006 release of libburn-0.2.6 and cdrskin-0.2.6 . cdrskin has
|
|
||||||
become suitable for unaware frontends as long as they perform only the core
|
|
||||||
of cdrecord use cases (including open-ended input streams, audio, and
|
|
||||||
multi-session).
|
|
||||||
|
|
||||||
- 28th November 2006 the umbrella project which encloses both, libisofs and
|
|
||||||
libburn, is now called libburnia. For the origin of this name, see
|
|
||||||
http://en.wikipedia.org/wiki/Liburnians .
|
|
||||||
|
|
||||||
- 16th January 2007 release of libburn-0.3.0 and cdrskin-0.3.0 . Now the scope
|
|
||||||
is widened to a first class of DVD media: overwriteable single layer types
|
|
||||||
DVD-RAM, DVD+RW, DVD-RW. This is not a cdrecord emulation but rather inspired
|
|
||||||
by dvd+rw-tools' "poor man" writing facility for this class of media.
|
|
||||||
Taking a bow towards Andy Polyakov.
|
|
||||||
|
|
||||||
- 11th February 2007 version 0.3.2 covers sequential DVD-RW and DVD-R with
|
|
||||||
multi-session and with DAO.
|
|
||||||
|
|
||||||
- 12th March 2007 version 0.3.4 supports DVD+R and thus covers all single layer
|
|
||||||
DVD media. Code for double layer DVD+/-R is implemented but awaits a tester
|
|
||||||
yet.
|
|
||||||
|
|
||||||
- 23th April 2007 version 0.3.6 follows the unanimous opinion of Linux kernel
|
|
||||||
people that one should not use /dev/sg on kernel 2.6.
|
|
||||||
|
|
||||||
- 31st July 2007 version 0.3.8 marks the first anniversary of libburn revival.
|
|
||||||
We look back on improved stability, a substantially extended list of media
|
|
||||||
and write modes, and better protection against typical user mishaps.
|
|
||||||
|
|
||||||
- 24th October 2007 version 0.4.0 is the foundation of new library libisoburn
|
|
||||||
and an upcomming integrated application for manipulating and writing
|
|
||||||
ISO 9660 + Rock Ridge images. cdrskin-0.4.0 got capabilities like growisofs
|
|
||||||
by these enhancements: growing of overwriteable media and disk files.
|
|
||||||
Taking again a bow towards Andy Polyakov.
|
|
||||||
|
|
||||||
- 26th Januar 2008 version 0.4.2 rectifies the version numbering so that we
|
|
||||||
reliably release libburn.so.4 as should have been done since libburn-0.3.2.
|
|
||||||
cdrskin now is by default linked dynamically and does a runtime check
|
|
||||||
to ensure not to be started with a libburn which is older than itself.
|
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License version 2 or later
|
||||||
the Free Software Foundation. To be exact: version 2 of that License.
|
as published by the Free Software Foundation.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
@ -309,19 +174,19 @@ Project history as far as known to me:
|
|||||||
Clarification in my name and in the name of Mario Danic, upcoming copyright
|
Clarification in my name and in the name of Mario Danic, upcoming copyright
|
||||||
holders on toplevel of libburnia. To be fully in effect after the remaining
|
holders on toplevel of libburnia. To be fully in effect after the remaining
|
||||||
other copyrighted code has been replaced by ours and by copyright-free
|
other copyrighted code has been replaced by ours and by copyright-free
|
||||||
contributions of our friends:
|
contributions of our friends.
|
||||||
|
|
||||||
|
Note:
|
||||||
|
In the particular case of libisofs there is no foreign copyright involved.
|
||||||
|
As of 2010 foreign copyright is only in component libburn.
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
We, the copyright holders, agree on the interpretation that
|
We will not raise any legal protest to dynamic linking of our libraries
|
||||||
dynamical linking of our libraries constitutes "use of" and
|
with applications that are not under GPL, as long as they fulfill
|
||||||
not "derivation from" our work in the sense of GPL, provided
|
the condition of offering the library source code used, whether
|
||||||
those libraries are compiled from our unaltered code.
|
altered or unaltered, under the GPLv2+, along with the application.
|
||||||
|
Nevertheless, the safest legal position is not to link libburn with
|
||||||
Thus you may link our libraries dynamically with applications
|
non-GPL compatible programs.
|
||||||
which are not under GPL. You may distribute our libraries and
|
|
||||||
application tools in binary form, if you fulfill the usual
|
|
||||||
condition of GPL to offer a copy of the source code -altered
|
|
||||||
or unaltered- under GPL.
|
|
||||||
|
|
||||||
We ask you politely to use our work in open source spirit
|
We ask you politely to use our work in open source spirit
|
||||||
and with the due reference to the entire open source community.
|
and with the due reference to the entire open source community.
|
||||||
@ -335,7 +200,10 @@ It is the open source idea of responsible freedom which will be
|
|||||||
decisive and you will have to prove that you exhausted all own
|
decisive and you will have to prove that you exhausted all own
|
||||||
means to qualify for GPL.
|
means to qualify for GPL.
|
||||||
|
|
||||||
For now we are firmly committed to maintain one single license: GPL.
|
We are firmly committed to allow GPLv2+ now and with future releases.
|
||||||
|
|
||||||
signed: Mario Danic, Thomas Schmitt
|
Signed: Mario Danic, Thomas Schmitt
|
||||||
|
Agreement joined later by: Vreixo Formoso
|
||||||
|
|
||||||
|
Public contact: <libburn-hackers@pykix.org>
|
||||||
|
|
||||||
|
82
acinclude.m4
82
acinclude.m4
@ -1,3 +1,14 @@
|
|||||||
|
AC_DEFUN([LIBBURNIA_SET_FLAGS],
|
||||||
|
[
|
||||||
|
case $target_os in
|
||||||
|
freebsd*)
|
||||||
|
LDFLAGS="$LDFLAGS -L/usr/local/lib"
|
||||||
|
CPPFLAGS="$CPPFLAGS -I/usr/local/include"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
AC_DEFUN([TARGET_SHIZZLE],
|
AC_DEFUN([TARGET_SHIZZLE],
|
||||||
[
|
[
|
||||||
ARCH=""
|
ARCH=""
|
||||||
@ -5,10 +16,12 @@ AC_DEFUN([TARGET_SHIZZLE],
|
|||||||
|
|
||||||
AC_MSG_CHECKING([target operating system])
|
AC_MSG_CHECKING([target operating system])
|
||||||
|
|
||||||
|
LIBBURNIA_LDCONFIG_CMD="echo 'No ldconfig run performed. If needed, configure manually for:'"
|
||||||
case $target in
|
case $target in
|
||||||
*-*-linux*)
|
*-*-linux*)
|
||||||
ARCH=linux
|
ARCH=linux
|
||||||
LIBBURN_ARCH_LIBS=
|
LIBBURN_ARCH_LIBS=
|
||||||
|
LIBBURNIA_LDCONFIG_CMD=ldconfig
|
||||||
;;
|
;;
|
||||||
*-*-freebsd*)
|
*-*-freebsd*)
|
||||||
ARCH=freebsd
|
ARCH=freebsd
|
||||||
@ -39,8 +52,9 @@ dnl From Bruno Haible.
|
|||||||
dnl
|
dnl
|
||||||
AC_DEFUN([LIBBURNIA_CHECK_ICONV],
|
AC_DEFUN([LIBBURNIA_CHECK_ICONV],
|
||||||
[
|
[
|
||||||
|
|
||||||
dnl Check whether it is allowed to link with -liconv
|
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_liconv="no"
|
||||||
libburnia_save_LIBS="$LIBS"
|
libburnia_save_LIBS="$LIBS"
|
||||||
LIBS="$LIBS -liconv"
|
LIBS="$LIBS -liconv"
|
||||||
@ -54,6 +68,13 @@ AC_DEFUN([LIBBURNIA_CHECK_ICONV],
|
|||||||
)
|
)
|
||||||
AC_MSG_RESULT([$libburnia_liconv])
|
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, ...)
|
dnl Check for iconv(..., const char **inbuf, ...)
|
||||||
AC_MSG_CHECKING([for const qualifier with iconv() ])
|
AC_MSG_CHECKING([for const qualifier with iconv() ])
|
||||||
AC_TRY_COMPILE([
|
AC_TRY_COMPILE([
|
||||||
@ -68,6 +89,65 @@ 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=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 = xno
|
||||||
|
then
|
||||||
|
LDFLAGS="$libburnia_save_LDFLAGS"
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
dnl LIBBURNIA_SET_PKGCONFIG determines the install directory for the *.pc file.
|
dnl LIBBURNIA_SET_PKGCONFIG determines the install directory for the *.pc file.
|
||||||
dnl Important: Must be performed _after_ TARGET_SHIZZLE
|
dnl Important: Must be performed _after_ TARGET_SHIZZLE
|
||||||
dnl
|
dnl
|
||||||
|
85
configure.ac
85
configure.ac
@ -1,17 +1,13 @@
|
|||||||
AC_INIT([libisofs], [0.6.24], [http://libburnia-project.org])
|
AC_INIT([libisofs], [1.0.8], [http://libburnia-project.org])
|
||||||
AC_PREREQ([2.50])
|
AC_PREREQ([2.50])
|
||||||
dnl AC_CONFIG_HEADER([config.h])
|
dnl AC_CONFIG_HEADER([config.h])
|
||||||
|
|
||||||
AC_CANONICAL_HOST
|
AC_CANONICAL_HOST
|
||||||
AC_CANONICAL_TARGET
|
AC_CANONICAL_TARGET
|
||||||
|
|
||||||
AM_INIT_AUTOMAKE([subdir-objects])
|
LIBBURNIA_SET_FLAGS
|
||||||
|
|
||||||
dnl A61101 This breaks Linux build (makes 32 bit off_t)
|
AM_INIT_AUTOMAKE([subdir-objects])
|
||||||
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)
|
|
||||||
|
|
||||||
dnl
|
dnl
|
||||||
dnl if MAJOR or MINOR version changes, be sure to change AC_INIT above to match
|
dnl if MAJOR or MINOR version changes, be sure to change AC_INIT above to match
|
||||||
@ -42,9 +38,9 @@ dnl It rather feeds the API function iso_lib_version().
|
|||||||
dnl
|
dnl
|
||||||
dnl If LIBISOFS_*_VERSION changes, be sure to change AC_INIT above to match.
|
dnl If LIBISOFS_*_VERSION changes, be sure to change AC_INIT above to match.
|
||||||
dnl
|
dnl
|
||||||
LIBISOFS_MAJOR_VERSION=0
|
LIBISOFS_MAJOR_VERSION=1
|
||||||
LIBISOFS_MINOR_VERSION=6
|
LIBISOFS_MINOR_VERSION=0
|
||||||
LIBISOFS_MICRO_VERSION=24
|
LIBISOFS_MICRO_VERSION=8
|
||||||
LIBISOFS_VERSION=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION.$LIBISOFS_MICRO_VERSION
|
LIBISOFS_VERSION=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION.$LIBISOFS_MICRO_VERSION
|
||||||
|
|
||||||
AC_SUBST(LIBISOFS_MAJOR_VERSION)
|
AC_SUBST(LIBISOFS_MAJOR_VERSION)
|
||||||
@ -54,11 +50,11 @@ AC_SUBST(LIBISOFS_VERSION)
|
|||||||
|
|
||||||
dnl Libtool versioning
|
dnl Libtool versioning
|
||||||
LT_RELEASE=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION
|
LT_RELEASE=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION
|
||||||
# 2009.10.08 development jump has not yet happened
|
# 2011.05.12 development jump has not yet happened
|
||||||
# SONAME = 26 - 20 = 6 . Library name = libisofs.6.20.0
|
# SONAME = 52 - 46 = 6 . Library name = libisofs.6.46.0
|
||||||
LT_CURRENT=26
|
LT_CURRENT=52
|
||||||
|
LT_AGE=46
|
||||||
LT_REVISION=0
|
LT_REVISION=0
|
||||||
LT_AGE=20
|
|
||||||
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
|
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
|
||||||
|
|
||||||
AC_SUBST(LT_RELEASE)
|
AC_SUBST(LT_RELEASE)
|
||||||
@ -89,6 +85,9 @@ 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.
|
dnl If not, then no -liconv will be added.
|
||||||
LIBBURNIA_CHECK_ICONV
|
LIBBURNIA_CHECK_ICONV
|
||||||
|
|
||||||
|
dnl To abort configuration if iconv() still cannot be compiled
|
||||||
|
LIBBURNIA_ASSERT_ICONV
|
||||||
|
|
||||||
|
|
||||||
AC_PROG_LIBTOOL
|
AC_PROG_LIBTOOL
|
||||||
AC_SUBST(LIBTOOL_DEPS)
|
AC_SUBST(LIBTOOL_DEPS)
|
||||||
@ -134,15 +133,15 @@ AC_ARG_ENABLE(debug,
|
|||||||
, enable_debug=yes)
|
, enable_debug=yes)
|
||||||
if test x$enable_debug != xyes; then
|
if test x$enable_debug != xyes; then
|
||||||
if test x$GCC = xyes; then
|
if test x$GCC = xyes; then
|
||||||
CFLAGS="$CFLAGS -O3"
|
CFLAGS="-O3 $CFLAGS"
|
||||||
CFLAGS="$CFLAGS -fexpensive-optimizations"
|
CFLAGS="-fexpensive-optimizations $CFLAGS"
|
||||||
fi
|
fi
|
||||||
CFLAGS="$CFLAGS -DNDEBUG"
|
CFLAGS="-DNDEBUG $CFLAGS"
|
||||||
else
|
else
|
||||||
if test x$GCC = xyes; then
|
if test x$GCC = xyes; then
|
||||||
CFLAGS="$CFLAGS -g -pedantic -Wall"
|
CFLAGS="-g -pedantic -Wall $CFLAGS"
|
||||||
fi
|
fi
|
||||||
CFLAGS="$CFLAGS -DDEBUG"
|
CFLAGS="-DDEBUG $CFLAGS"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
dnl Verbose debug to make libisofs issue more debug messages
|
dnl Verbose debug to make libisofs issue more debug messages
|
||||||
@ -196,14 +195,58 @@ AC_ARG_ENABLE(zlib,
|
|||||||
if test "x$enable_zlib" = xyes; then
|
if test "x$enable_zlib" = xyes; then
|
||||||
dnl Check whether there is the header for zlib.
|
dnl Check whether there is the header for zlib.
|
||||||
dnl If not, erase this macro which would enable use of compress2() and others.
|
dnl If not, erase this macro which would enable use of compress2() and others.
|
||||||
dnl The empty parameter after "compress2" causes -lz.
|
dnl Linking fails on SuSE 9.0 because zlib has compress2() but lacks
|
||||||
|
dnl compressBound(). So compressBound is the more modern thing to test.
|
||||||
|
dnl The empty parameter after "compressBound" causes -lz.
|
||||||
ZLIB_DEF="-DLibisofs_with_zliB"
|
ZLIB_DEF="-DLibisofs_with_zliB"
|
||||||
AC_CHECK_HEADER(zlib.h, AC_CHECK_LIB(z, compress2, , ZLIB_DEF= ), ZLIB_DEF= )
|
AC_CHECK_HEADER(zlib.h, AC_CHECK_LIB(z, compressBound, , ZLIB_DEF= ), ZLIB_DEF= )
|
||||||
else
|
else
|
||||||
ZLIB_DEF=
|
ZLIB_DEF=
|
||||||
fi
|
fi
|
||||||
AC_SUBST(ZLIB_DEF)
|
AC_SUBST(ZLIB_DEF)
|
||||||
|
|
||||||
|
dnl ts B00927
|
||||||
|
AC_ARG_ENABLE(libjte,
|
||||||
|
[ --enable-libjte Enable use of libjte 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_new, , LIBJTE_DEF= ), LIBJTE_DEF= )
|
||||||
|
else
|
||||||
|
LIBJTE_DEF=
|
||||||
|
fi
|
||||||
|
AC_SUBST(LIBJTE_DEF)
|
||||||
|
|
||||||
|
# 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([
|
AC_CONFIG_FILES([
|
||||||
Makefile
|
Makefile
|
||||||
|
@ -2,8 +2,9 @@
|
|||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "libisofs.h"
|
#include "libisofs.h"
|
||||||
|
@ -2,8 +2,9 @@
|
|||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "libisofs.h"
|
#include "libisofs.h"
|
||||||
|
154
demo/demo.c
154
demo/demo.c
@ -3,9 +3,9 @@
|
|||||||
* Copyright (c) 2007 - 2009 Vreixo Formoso, Thomas Schmitt
|
* Copyright (c) 2007 - 2009 Vreixo Formoso, Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
*
|
* See COPYING file for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static char helptext[][80] = {
|
static char helptext[][80] = {
|
||||||
@ -50,20 +50,13 @@ static char helptext[][80] = {
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef PATH_MAX
|
||||||
|
#define PATH_MAX Libisofs_default_path_maX
|
||||||
|
#endif
|
||||||
|
|
||||||
#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>
|
|
||||||
|
|
||||||
/* ------------------------- from demo/tree.c ----------------------- */
|
/* ------------------------- from demo/tree.c ----------------------- */
|
||||||
|
|
||||||
@ -93,7 +86,9 @@ tree_print_dir(IsoDir *dir, int level)
|
|||||||
int i;
|
int i;
|
||||||
IsoDirIter *iter;
|
IsoDirIter *iter;
|
||||||
IsoNode *node;
|
IsoNode *node;
|
||||||
char *sp = alloca(level * 2 + 1);
|
char *sp;
|
||||||
|
|
||||||
|
sp = calloc(1, level * 2 + 1);
|
||||||
|
|
||||||
for (i = 0; i < level * 2; i += 2) {
|
for (i = 0; i < level * 2; i += 2) {
|
||||||
sp[i] = '|';
|
sp[i] = '|';
|
||||||
@ -127,6 +122,7 @@ tree_print_dir(IsoDir *dir, int level)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
iso_dir_iter_free(iter);
|
iso_dir_iter_free(iter);
|
||||||
|
free(sp);
|
||||||
}
|
}
|
||||||
|
|
||||||
int gesture_tree(int argc, char **argv)
|
int gesture_tree(int argc, char **argv)
|
||||||
@ -265,7 +261,7 @@ int gesture_iso(int argc, char **argv)
|
|||||||
IsoImage *image;
|
IsoImage *image;
|
||||||
struct burn_source *burn_src;
|
struct burn_source *burn_src;
|
||||||
unsigned char buf[2048];
|
unsigned char buf[2048];
|
||||||
FILE *fd;
|
FILE *fp = NULL;
|
||||||
IsoWriteOpts *opts;
|
IsoWriteOpts *opts;
|
||||||
char *volid = "VOLID";
|
char *volid = "VOLID";
|
||||||
char *boot_img = NULL;
|
char *boot_img = NULL;
|
||||||
@ -276,7 +272,7 @@ int gesture_iso(int argc, char **argv)
|
|||||||
case 'h':
|
case 'h':
|
||||||
iso_usage(argv);
|
iso_usage(argv);
|
||||||
iso_help();
|
iso_help();
|
||||||
exit(0);
|
goto ex;
|
||||||
break;
|
break;
|
||||||
case 'J':
|
case 'J':
|
||||||
j = 1;
|
j = 1;
|
||||||
@ -298,7 +294,7 @@ int gesture_iso(int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
iso_usage(argv);
|
iso_usage(argv);
|
||||||
exit(1);
|
goto ex;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -306,30 +302,31 @@ int gesture_iso(int argc, char **argv)
|
|||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
printf ("Please pass directory from which to build ISO\n");
|
printf ("Please pass directory from which to build ISO\n");
|
||||||
iso_usage(argv);
|
iso_usage(argv);
|
||||||
return 1;
|
goto ex;
|
||||||
}
|
}
|
||||||
if (argc < 3) {
|
if (argc < 3) {
|
||||||
printf ("Please supply output file\n");
|
printf ("Please supply output file\n");
|
||||||
iso_usage(argv);
|
iso_usage(argv);
|
||||||
return 1;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
fd = fopen(argv[optind+1], "w");
|
fp = fopen(argv[optind+1], "w");
|
||||||
if (!fd) {
|
if (fp == NULL) {
|
||||||
err(1, "error opening output file");
|
err(1, "error opening output file");
|
||||||
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = iso_init();
|
result = iso_init();
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
printf ("Can't initialize libisofs\n");
|
printf ("Can't initialize libisofs\n");
|
||||||
return 1;
|
goto ex;
|
||||||
}
|
}
|
||||||
iso_set_msgs_severities("NEVER", "ALL", "");
|
iso_set_msgs_severities("NEVER", "ALL", "");
|
||||||
|
|
||||||
result = iso_image_new(volid, &image);
|
result = iso_image_new(volid, &image);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
printf ("Error creating image\n");
|
printf ("Error creating image\n");
|
||||||
return 1;
|
goto ex;
|
||||||
}
|
}
|
||||||
iso_tree_set_follow_symlinks(image, 0);
|
iso_tree_set_follow_symlinks(image, 0);
|
||||||
iso_tree_set_ignore_hidden(image, 0);
|
iso_tree_set_ignore_hidden(image, 0);
|
||||||
@ -341,7 +338,7 @@ int gesture_iso(int argc, char **argv)
|
|||||||
argv[optind]);
|
argv[optind]);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
printf ("Error adding directory %d\n", result);
|
printf ("Error adding directory %d\n", result);
|
||||||
return 1;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (boot_img) {
|
if (boot_img) {
|
||||||
@ -351,7 +348,7 @@ int gesture_iso(int argc, char **argv)
|
|||||||
"/isolinux/boot.cat", &bootimg);
|
"/isolinux/boot.cat", &bootimg);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
printf ("Error adding boot image %d\n", result);
|
printf ("Error adding boot image %d\n", result);
|
||||||
return 1;
|
goto ex;
|
||||||
}
|
}
|
||||||
el_torito_set_load_size(bootimg, 4);
|
el_torito_set_load_size(bootimg, 4);
|
||||||
el_torito_patch_isolinux_image(bootimg);
|
el_torito_patch_isolinux_image(bootimg);
|
||||||
@ -360,7 +357,7 @@ int gesture_iso(int argc, char **argv)
|
|||||||
result = iso_write_opts_new(&opts, 0);
|
result = iso_write_opts_new(&opts, 0);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
printf ("Cant create write opts, error %d\n", result);
|
printf ("Cant create write opts, error %d\n", result);
|
||||||
return 1;
|
goto ex;
|
||||||
}
|
}
|
||||||
iso_write_opts_set_iso_level(opts, level);
|
iso_write_opts_set_iso_level(opts, level);
|
||||||
iso_write_opts_set_rockridge(opts, rr);
|
iso_write_opts_set_rockridge(opts, rr);
|
||||||
@ -370,21 +367,29 @@ int gesture_iso(int argc, char **argv)
|
|||||||
result = iso_image_create_burn_source(image, opts, &burn_src);
|
result = iso_image_create_burn_source(image, opts, &burn_src);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
printf ("Cant create image, error %d\n", result);
|
printf ("Cant create image, error %d\n", result);
|
||||||
return 1;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
iso_write_opts_free(opts);
|
iso_write_opts_free(opts);
|
||||||
|
|
||||||
while (burn_src->read_xt(burn_src, buf, 2048) == 2048) {
|
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);
|
burn_src->free_data(burn_src);
|
||||||
free(burn_src);
|
free(burn_src);
|
||||||
|
|
||||||
iso_image_unref(image);
|
iso_image_unref(image);
|
||||||
iso_finish();
|
iso_finish();
|
||||||
return 0;
|
return 0;
|
||||||
|
ex:;
|
||||||
|
if (fp != NULL)
|
||||||
|
fclose(fp);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -431,7 +436,9 @@ iso_read_print_dir(IsoFileSource *dir, int level)
|
|||||||
int ret, i;
|
int ret, i;
|
||||||
IsoFileSource *file;
|
IsoFileSource *file;
|
||||||
struct stat info;
|
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) {
|
for (i = 0; i < level * 2; i += 2) {
|
||||||
sp[i] = '|';
|
sp[i] = '|';
|
||||||
@ -461,6 +468,7 @@ iso_read_print_dir(IsoFileSource *dir, int level)
|
|||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
printf ("Can't print dir\n");
|
printf ("Can't print dir\n");
|
||||||
}
|
}
|
||||||
|
free(sp);
|
||||||
}
|
}
|
||||||
|
|
||||||
int gesture_iso_read(int argc, char **argv)
|
int gesture_iso_read(int argc, char **argv)
|
||||||
@ -534,7 +542,7 @@ int gesture_iso_read(int argc, char **argv)
|
|||||||
|
|
||||||
int gesture_iso_cat(int argc, char **argv)
|
int gesture_iso_cat(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int res;
|
int res, write_ret;
|
||||||
IsoFilesystem *fs;
|
IsoFilesystem *fs;
|
||||||
IsoFileSource *file;
|
IsoFileSource *file;
|
||||||
struct stat info;
|
struct stat info;
|
||||||
@ -593,7 +601,11 @@ int gesture_iso_cat(int argc, char **argv)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
while ((res = iso_file_source_read(file, buf, 1024)) > 0) {
|
while ((res = iso_file_source_read(file, buf, 1024)) > 0) {
|
||||||
fwrite(buf, 1, res, stdout);
|
write_ret = fwrite(buf, 1, res, stdout);
|
||||||
|
if (write_ret < res) {
|
||||||
|
printf ("Cannot write block to stdout. errno= %d\n", errno);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
fprintf(stderr, "Error reading, err = %d\n", res);
|
fprintf(stderr, "Error reading, err = %d\n", res);
|
||||||
@ -625,18 +637,19 @@ int gesture_iso_modify(int argc, char **argv)
|
|||||||
IsoDataSource *src;
|
IsoDataSource *src;
|
||||||
struct burn_source *burn_src;
|
struct burn_source *burn_src;
|
||||||
unsigned char buf[2048];
|
unsigned char buf[2048];
|
||||||
FILE *fd;
|
FILE *fp = NULL;
|
||||||
IsoWriteOpts *opts;
|
IsoWriteOpts *opts;
|
||||||
IsoReadOpts *ropts;
|
IsoReadOpts *ropts;
|
||||||
|
|
||||||
if (argc < 4) {
|
if (argc < 4) {
|
||||||
iso_modify_usage(argv);
|
iso_modify_usage(argv);
|
||||||
return 1;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
fd = fopen(argv[3], "w");
|
fp = fopen(argv[3], "w");
|
||||||
if (!fd) {
|
if (fp == NULL) {
|
||||||
err(1, "error opening output file");
|
err(1, "error opening output file");
|
||||||
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
iso_init();
|
iso_init();
|
||||||
@ -646,14 +659,14 @@ int gesture_iso_modify(int argc, char **argv)
|
|||||||
result = iso_data_source_new_from_file(argv[1], &src);
|
result = iso_data_source_new_from_file(argv[1], &src);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
printf ("Error creating data source\n");
|
printf ("Error creating data source\n");
|
||||||
return 1;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create the image context */
|
/* create the image context */
|
||||||
result = iso_image_new("volume_id", &image);
|
result = iso_image_new("volume_id", &image);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
printf ("Error creating image\n");
|
printf ("Error creating image\n");
|
||||||
return 1;
|
goto ex;
|
||||||
}
|
}
|
||||||
iso_tree_set_follow_symlinks(image, 0);
|
iso_tree_set_follow_symlinks(image, 0);
|
||||||
iso_tree_set_ignore_hidden(image, 0);
|
iso_tree_set_ignore_hidden(image, 0);
|
||||||
@ -662,49 +675,57 @@ int gesture_iso_modify(int argc, char **argv)
|
|||||||
result = iso_read_opts_new(&ropts, 0);
|
result = iso_read_opts_new(&ropts, 0);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
fprintf(stderr, "Error creating read options\n");
|
fprintf(stderr, "Error creating read options\n");
|
||||||
return 1;
|
goto ex;
|
||||||
}
|
}
|
||||||
result = iso_image_import(image, src, ropts, NULL);
|
result = iso_image_import(image, src, ropts, NULL);
|
||||||
iso_read_opts_free(ropts);
|
iso_read_opts_free(ropts);
|
||||||
iso_data_source_unref(src);
|
iso_data_source_unref(src);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
printf ("Error importing previous session %d\n", result);
|
printf ("Error importing previous session %d\n", result);
|
||||||
return 1;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add new dir */
|
/* add new dir */
|
||||||
result = iso_tree_add_dir_rec(image, iso_image_get_root(image), argv[2]);
|
result = iso_tree_add_dir_rec(image, iso_image_get_root(image), argv[2]);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
printf ("Error adding directory %d\n", result);
|
printf ("Error adding directory %d\n", result);
|
||||||
return 1;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* generate a new image with both previous and added contents */
|
/* generate a new image with both previous and added contents */
|
||||||
result = iso_write_opts_new(&opts, 1);
|
result = iso_write_opts_new(&opts, 1);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
printf("Cant create write opts, error %d\n", result);
|
printf("Cant create write opts, error %d\n", result);
|
||||||
return 1;
|
goto ex;
|
||||||
}
|
}
|
||||||
/* for isolinux: iso_write_opts_set_allow_full_ascii(opts, 1); */
|
/* for isolinux: iso_write_opts_set_allow_full_ascii(opts, 1); */
|
||||||
|
|
||||||
result = iso_image_create_burn_source(image, opts, &burn_src);
|
result = iso_image_create_burn_source(image, opts, &burn_src);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
printf ("Cant create image, error %d\n", result);
|
printf ("Cant create image, error %d\n", result);
|
||||||
return 1;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
iso_write_opts_free(opts);
|
iso_write_opts_free(opts);
|
||||||
|
|
||||||
while (burn_src->read_xt(burn_src, buf, 2048) == 2048) {
|
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);
|
burn_src->free_data(burn_src);
|
||||||
free(burn_src);
|
free(burn_src);
|
||||||
|
|
||||||
iso_image_unref(image);
|
iso_image_unref(image);
|
||||||
iso_finish();
|
iso_finish();
|
||||||
return 0;
|
return 0;
|
||||||
|
ex:
|
||||||
|
if (fp != NULL)
|
||||||
|
fclose(fp);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -723,25 +744,26 @@ int gesture_iso_ms(int argc, char **argv)
|
|||||||
IsoDataSource *src;
|
IsoDataSource *src;
|
||||||
struct burn_source *burn_src;
|
struct burn_source *burn_src;
|
||||||
unsigned char buf[2048];
|
unsigned char buf[2048];
|
||||||
FILE *fd;
|
FILE *fp = NULL;
|
||||||
IsoWriteOpts *opts;
|
IsoWriteOpts *opts;
|
||||||
IsoReadOpts *ropts;
|
IsoReadOpts *ropts;
|
||||||
uint32_t ms_block;
|
uint32_t ms_block;
|
||||||
|
|
||||||
if (argc < 6) {
|
if (argc < 6) {
|
||||||
iso_ms_usage(argv);
|
iso_ms_usage(argv);
|
||||||
return 1;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(argv[3], argv[5]) == 0) {
|
if (strcmp(argv[3], argv[5]) == 0) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"image_file and output_file must not be the same file.\n");
|
"image_file and output_file must not be the same file.\n");
|
||||||
return 1;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
fd = fopen(argv[5], "w");
|
fp = fopen(argv[5], "w");
|
||||||
if (!fd) {
|
if (!fp) {
|
||||||
err(1, "error opening output file");
|
err(1, "error opening output file");
|
||||||
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
iso_init();
|
iso_init();
|
||||||
@ -751,14 +773,14 @@ int gesture_iso_ms(int argc, char **argv)
|
|||||||
result = iso_data_source_new_from_file(argv[3], &src);
|
result = iso_data_source_new_from_file(argv[3], &src);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
printf ("Error creating data source\n");
|
printf ("Error creating data source\n");
|
||||||
return 1;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create the image context */
|
/* create the image context */
|
||||||
result = iso_image_new("volume_id", &image);
|
result = iso_image_new("volume_id", &image);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
printf ("Error creating image\n");
|
printf ("Error creating image\n");
|
||||||
return 1;
|
goto ex;
|
||||||
}
|
}
|
||||||
iso_tree_set_follow_symlinks(image, 0);
|
iso_tree_set_follow_symlinks(image, 0);
|
||||||
iso_tree_set_ignore_hidden(image, 0);
|
iso_tree_set_ignore_hidden(image, 0);
|
||||||
@ -767,7 +789,7 @@ int gesture_iso_ms(int argc, char **argv)
|
|||||||
result = iso_read_opts_new(&ropts, 0);
|
result = iso_read_opts_new(&ropts, 0);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
fprintf(stderr, "Error creating read options\n");
|
fprintf(stderr, "Error creating read options\n");
|
||||||
return 1;
|
goto ex;
|
||||||
}
|
}
|
||||||
iso_read_opts_set_start_block(ropts, atoi(argv[1]));
|
iso_read_opts_set_start_block(ropts, atoi(argv[1]));
|
||||||
result = iso_image_import(image, src, ropts, NULL);
|
result = iso_image_import(image, src, ropts, NULL);
|
||||||
@ -775,21 +797,21 @@ int gesture_iso_ms(int argc, char **argv)
|
|||||||
iso_data_source_unref(src);
|
iso_data_source_unref(src);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
printf ("Error importing previous session %d\n", result);
|
printf ("Error importing previous session %d\n", result);
|
||||||
return 1;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add new dir */
|
/* add new dir */
|
||||||
result = iso_tree_add_dir_rec(image, iso_image_get_root(image), argv[4]);
|
result = iso_tree_add_dir_rec(image, iso_image_get_root(image), argv[4]);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
printf ("Error adding directory %d\n", result);
|
printf ("Error adding directory %d\n", result);
|
||||||
return 1;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* generate a multisession image with new contents */
|
/* generate a multisession image with new contents */
|
||||||
result = iso_write_opts_new(&opts, 1);
|
result = iso_write_opts_new(&opts, 1);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
printf("Cant create write opts, error %d\n", result);
|
printf("Cant create write opts, error %d\n", result);
|
||||||
return 1;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* round up to 32kb aligment = 16 block */
|
/* round up to 32kb aligment = 16 block */
|
||||||
@ -800,20 +822,28 @@ int gesture_iso_ms(int argc, char **argv)
|
|||||||
result = iso_image_create_burn_source(image, opts, &burn_src);
|
result = iso_image_create_burn_source(image, opts, &burn_src);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
printf ("Cant create image, error %d\n", result);
|
printf ("Cant create image, error %d\n", result);
|
||||||
return 1;
|
goto ex;
|
||||||
}
|
}
|
||||||
iso_write_opts_free(opts);
|
iso_write_opts_free(opts);
|
||||||
|
|
||||||
while (burn_src->read_xt(burn_src, buf, 2048) == 2048) {
|
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);
|
burn_src->free_data(burn_src);
|
||||||
free(burn_src);
|
free(burn_src);
|
||||||
|
|
||||||
iso_image_unref(image);
|
iso_image_unref(image);
|
||||||
iso_finish();
|
iso_finish();
|
||||||
return 0;
|
return 0;
|
||||||
|
ex:;
|
||||||
|
if (fp != NULL)
|
||||||
|
fclose(fp);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,8 +2,9 @@
|
|||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -10,6 +10,12 @@
|
|||||||
|
|
||||||
#include "libisofs.h"
|
#include "libisofs.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef PATH_MAX
|
||||||
|
#define PATH_MAX Libisofs_default_path_maX
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_permissions(mode_t mode)
|
print_permissions(mode_t mode)
|
||||||
{
|
{
|
||||||
|
11
demo/lsl.c
11
demo/lsl.c
@ -2,8 +2,9 @@
|
|||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "libisofs.h"
|
#include "libisofs.h"
|
||||||
@ -13,6 +14,12 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef PATH_MAX
|
||||||
|
#define PATH_MAX Libisofs_default_path_maX
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Little test program to test filesystem implementations.
|
* Little test program to test filesystem implementations.
|
||||||
*
|
*
|
||||||
|
727
doc/boot_sectors.txt
Normal file
727
doc/boot_sectors.txt
Normal file
@ -0,0 +1,727 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Collection of Boot Sector Formats for ISO 9660 Images
|
||||||
|
|
||||||
|
|
||||||
|
by Thomas Schmitt - mailto:scdbackup@gmx.net
|
||||||
|
Libburnia project - mailto:libburn-hackers@pykix.org
|
||||||
|
|
||||||
|
This information is collected from various sources. Some is backed by
|
||||||
|
specifications, some is just rumor which happens to work (maybe not even that).
|
||||||
|
|
||||||
|
|
||||||
|
Content
|
||||||
|
|
||||||
|
EL Torito CD booting, for PC-BIOS x86, PowerPC, (old) Mac, EFI.
|
||||||
|
|
||||||
|
MBR, for PC-BIOS x86 from (pseudo-) hard disk
|
||||||
|
- SYSLINUX isohybrid MBR
|
||||||
|
- GRUB2 grub-mkrescue MBR.
|
||||||
|
|
||||||
|
MIPS Volume Header, for MIPS Big Endian, e.g. SGI Indigo2.
|
||||||
|
|
||||||
|
DEC Boot Block, for MIPS Little Endian , e.g. DECstation.
|
||||||
|
|
||||||
|
SUN Disk Label and boot images, for SUN SPARC
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
EL Torito CD booting
|
||||||
|
for PC-BIOS x86, PowerPC, (old) Mac, EFI
|
||||||
|
|
||||||
|
Sources:
|
||||||
|
El Torito, Bootable CD-ROM Format Specification, Version 1.0, 1995
|
||||||
|
which refers to ECMA-119, the standard for ISO 9660 filesystems.
|
||||||
|
libisofs/eltorito.[ch] by Vreixo Formoso.
|
||||||
|
man mkisofs by Joerg Schilling.
|
||||||
|
|
||||||
|
|
||||||
|
ECMA-119 prescribes that the first 32 kB of an ISO 9660 image are System Area
|
||||||
|
with arbitrary content. This prescription is obeyed by PC-BIOS systems only
|
||||||
|
if the ISO 9660 image is presented on CD, DVD or BD media.
|
||||||
|
In this case the El Torito Boot record is the starting point of booting.
|
||||||
|
|
||||||
|
The Boot Record is a ECMA-119 Volume Descriptor which is eventually located
|
||||||
|
at 2 kB block number 17 (decimal). Its content points to the location of the
|
||||||
|
Boot Catalog.
|
||||||
|
The format is described in part by ECMA-119 8.2 "Boot Record" and further
|
||||||
|
specified by El Torito figure 7.
|
||||||
|
|
||||||
|
Byte Range | Value | Meaning
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
0 - 0 | 0 | Volume Descriptor Type. 0= Boot record
|
||||||
|
1 - 5 | "CD001" | Standard Identifier
|
||||||
|
6 - 6 | 1 | Volume Descriptor Version
|
||||||
|
7 - 38 | el_torito | Boot System Identifier
|
||||||
|
39 - 70 | 0 | Boot Identifier
|
||||||
|
| |
|
||||||
|
71 -2047 | ========== | Boot System Use
|
||||||
|
| |
|
||||||
|
71 - 74 | cataloglba | The 2 kB block number of the Boot Catalog
|
||||||
|
| | as little-endian 32 bit number.
|
||||||
|
| |
|
||||||
|
75 -2047 | 0 | Unused
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
|
||||||
|
el_torito is the constant string "EL TORITO SPECIFICATION" padded by 9 zeros.
|
||||||
|
cataloglba has to be provided by the file system generator.
|
||||||
|
|
||||||
|
|
||||||
|
The Boot Catalog lists the available boot images which may be prepared for
|
||||||
|
multiple system architectures, called "platforms".
|
||||||
|
It consists of one or more 2 kB blocks. The content is a sequence of fixed
|
||||||
|
format entries, 32 bytes each.
|
||||||
|
The entries are grouped in sections, which assign the entries to a particular
|
||||||
|
system architecture. The booting system will then choose an entry from an
|
||||||
|
appropriate section.
|
||||||
|
|
||||||
|
Byte Range | Value | Meaning
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
0 - 31 | ========== | Validation Entry
|
||||||
|
| | begins the first section, specifies an architecture
|
||||||
|
32 - 63 | ========== | Initial/Default Entry
|
||||||
|
| | points to a boot image for given architecture
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
Optional:
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
64 - 95 | ========== | Section Header entry
|
||||||
|
| | begins new section, specifies an architecture
|
||||||
|
96 - 127 | ========== | Section Entry
|
||||||
|
| | points to a boot image for given architecture
|
||||||
|
... | .......... | Optional more Section Entries
|
||||||
|
... | .......... | Optional more Section Headers and their Section
|
||||||
|
| | Entries
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
|
||||||
|
An architecture is refered by a Platform Id number.
|
||||||
|
Defined by El Torito are:
|
||||||
|
0 = "80x86" which is used for standard PCs with Intel x86 or compatible CPU
|
||||||
|
1 = "PowerPC" (possibly for IBM machines with PowerPC CPU)
|
||||||
|
2 = "Mac" (possibly for Apple computers with MC68000 or PowerPC CPU)
|
||||||
|
Further in use by GRUB2 is:
|
||||||
|
0xef = EFI, a competitor resp. successor to PC-BIOS, possibly in use with
|
||||||
|
Intel ia64 Itanium and possibly with newer Apple machines.
|
||||||
|
|
||||||
|
Words resp. numbers are represented are little-endian.
|
||||||
|
|
||||||
|
Validation Entry:
|
||||||
|
|
||||||
|
Byte Range | Value | Meaning
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
0 - 0 | 1 | Header Id
|
||||||
|
| |
|
||||||
|
1 - 1 | platform_id| Platform Id. One of: 0, 1, 2, 0xef. See above.
|
||||||
|
| |
|
||||||
|
2 - 3 | 0 | Reserved
|
||||||
|
4 - 27 | manuf_dev | ID string identifies the manufacturer/developer
|
||||||
|
| | (no non-zero examples known yet)
|
||||||
|
| |
|
||||||
|
28 - 29 | checksum | Checksum Word for the Validation Entry.
|
||||||
|
| | The sum of all words in the entry has to be 0.
|
||||||
|
| |
|
||||||
|
30 - 30 | 0x55 |
|
||||||
|
31 - 31 | 0xaa |
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
Initial/Default Entry:
|
||||||
|
|
||||||
|
Byte Range | Value | Meaning
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
0 - 0 | boot_indct | Boot Indicator: 0x88 = bootable, 0x00 = not bootable
|
||||||
|
| |
|
||||||
|
1 - 1 | boot_media | Boot Media Type (i.e. media emulated by boot image):
|
||||||
|
| | 0= no emulation , 1= 1.2 MB diskette, 2=1.44 MB,
|
||||||
|
| | 3= 2.88 MB , 4= hard disk
|
||||||
|
| | (About everybody uses 0 = no emulation)
|
||||||
|
| |
|
||||||
|
2 - 3 | load_seg | Load Segment. (meaning unclear)
|
||||||
|
| | "If this value is 0 the system will use the
|
||||||
|
| | traditional segment of 7C0."
|
||||||
|
| | libisofs default is 0
|
||||||
|
| |
|
||||||
|
4 - 4 | sys_type | System Type.
|
||||||
|
| | "Must be a copy of byte 5 from the partition table
|
||||||
|
| | found in the boot image."
|
||||||
|
| | libisofs reads the start the boot image as MBR
|
||||||
|
| | if boot_media == 4. This emulated MBR has a
|
||||||
|
| | partition table from where a byte gets copied.
|
||||||
|
| | Else this byte is 0.
|
||||||
|
| |
|
||||||
|
5 - 5 | 0 | Unused
|
||||||
|
| |
|
||||||
|
6 - 7 | sec_count | Sector Count.
|
||||||
|
| | "the number of virtual/emulated sectors the system
|
||||||
|
| | will store at Load Segment during the initial boot
|
||||||
|
| | procedure."
|
||||||
|
| | libisofs stores 1 for emulated boot_media and a
|
||||||
|
| | user defined value for boot_media == 0. Often: 4.
|
||||||
|
| |
|
||||||
|
8 - 11 | load_rba | Load RBA. The 2 kB block address where the boot
|
||||||
|
| | image file content is located in the ISO 9660 image.
|
||||||
|
| |
|
||||||
|
12 - 31 | 0 | Unused
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
Section Header Entry:
|
||||||
|
|
||||||
|
Byte Range | Value | Meaning
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
0 - 0 | head_ind | Header Indicator: 0x90 = more headers follow
|
||||||
|
| | 0x91 = final header, last section
|
||||||
|
| |
|
||||||
|
1 - 1 | platform_id| Platform Id. One of: 0, 1, 2, 0xef. See above.
|
||||||
|
| |
|
||||||
|
2 - 3 | num_entries| Number of entries to follow in this section
|
||||||
|
| |
|
||||||
|
4 - 31 | | ID string identifies the manufacturer/developer
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
Section Entry:
|
||||||
|
|
||||||
|
Byte Range | Value | Meaning
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
0 - 0 | boot_indct | Boot Indicator: 0x88 = bootable, 0x00 = not bootable
|
||||||
|
| |
|
||||||
|
1 - 1 | boot_media | Boot Media Type (i.e. media emulated by boot image):
|
||||||
|
| | Bit 0 to 3 govern emulation
|
||||||
|
| | 0= no emulation , 1= 1.2 MB diskette, 2=1.44 MB,
|
||||||
|
| | 3= 2.88 MB , 4= hard disk
|
||||||
|
| | (About everybody uses 0 = no emulation)
|
||||||
|
| | Bit 4 is reserved and must be 0
|
||||||
|
| | Bit 5 "Continuation entry follows" (meaning unclear)
|
||||||
|
| | Might be the indicator for Extension Entries,
|
||||||
|
| | which are not described here.
|
||||||
|
| | Bit 6 "Image contains an ATAPI driver"
|
||||||
|
| | Bit 7 "Image contains SCSI drivers"
|
||||||
|
| |
|
||||||
|
2 - 3 | load_seg | Load Segment. (meaning unclear)
|
||||||
|
| | See above Initial/Default Entry
|
||||||
|
| | libisofs default is 0.
|
||||||
|
4 - 4 | sys_type | System Type.
|
||||||
|
| | See above Initial/Default Entry
|
||||||
|
| | 0 if not emulation == 4.
|
||||||
|
5 - 5 | 0 | Unused
|
||||||
|
| |
|
||||||
|
6 - 7 | sec_count | Sector Count.
|
||||||
|
| | See above Initial/Default Entry
|
||||||
|
| | libisofs stores 1 for emulated boot_media and a
|
||||||
|
| | user defined value for boot_media == 0. Often: 4.
|
||||||
|
| |
|
||||||
|
8 - 11 | load_rba | Load RBA. The 2 kB block address where the boot
|
||||||
|
| | image file content is located in the ISO 9660 image.
|
||||||
|
| |
|
||||||
|
12 - 31 | sel_crit | "Vendor unique selection criteria."
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
The boot image file content is mostly opaque to the ISO 9660 image generator.
|
||||||
|
Nevertheless there is a tradition named "Boot Info Table" which prescribes
|
||||||
|
to write information into byte fields of the boot image file content.
|
||||||
|
There are no general means known how a producer of ISO 9660 images could
|
||||||
|
detect the need for Boot Info Table production.
|
||||||
|
It rather needs a hint from the user who has to know whether the boot image
|
||||||
|
expects a Boot Info Table.
|
||||||
|
The Boot Info Table begins at byte 8 of the boot image content.
|
||||||
|
|
||||||
|
Byte Range | Value | Meaning
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
8 - 11 | pvd_lba | Block address of the Primary Volume Descriptor
|
||||||
|
| | This is the session start LBA + 16.
|
||||||
|
| |
|
||||||
|
12 - 15 | file_lba | Block address of the start of the boot image file
|
||||||
|
| | content.
|
||||||
|
| |
|
||||||
|
16 - 19 | file_len | Number of bytes in boot image file content.
|
||||||
|
| |
|
||||||
|
20 - 23 | checksum | Little-endian: The sum of all 32-bit words of the
|
||||||
|
| | file content from byte 64 to file end.
|
||||||
|
| |
|
||||||
|
24 - 63 | 0 | Reserved
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
MBR
|
||||||
|
for PC-BIOS x86 from (pseudo-) hard disk
|
||||||
|
|
||||||
|
Sources:
|
||||||
|
http://en.wikipedia.org/wiki/Master_boot_record
|
||||||
|
Mailing list conversations with H. Peter Anvin and Vladimir Serbinenko.
|
||||||
|
|
||||||
|
|
||||||
|
The candidates for MBR booting will normally use El Torito rather than MBR
|
||||||
|
if the ISO image is presented on CD, DVD, or BD media.
|
||||||
|
The eventual MBR comes into effect if the image is on a media that is
|
||||||
|
interpreted by the BIOS as some kind of hard disk. Usually real hard disks,
|
||||||
|
floppy disks, USB sticks, memory cards.
|
||||||
|
|
||||||
|
An important part of an MBR is the DOS style partition table. It describes up
|
||||||
|
to four primary partitions. There are two formats used for block address:
|
||||||
|
Cylinder/Head/Sector (C/H/S) and Logical Block Address (LBA). Both are based
|
||||||
|
on units of 512 bytes. So MBR_LBA = ISO_LBA * 4.
|
||||||
|
|
||||||
|
For C/H/S, the sector address is broken up into whole cylinders, remaining
|
||||||
|
heads, and remaining sectors + 1. The nomenclature seems to stem from antique
|
||||||
|
drum storage.
|
||||||
|
There are two parameters, sectors_per_head and heads_per_cylinder which are not
|
||||||
|
stored in the MBR. So it is more or less arbitray how to convert a LBA into
|
||||||
|
a C/H/S address and vice versa. For maximum range of C/H/S addresses one
|
||||||
|
may use sectors_per_head = 63 , heads_per_cylinder = 255.
|
||||||
|
|
||||||
|
|
||||||
|
Words are composed little-endian style.
|
||||||
|
|
||||||
|
Byte Range | Value | Meaning
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
0 - 439 | = opaque = | Code Area filled with bytes for some boot system,
|
||||||
|
| | typically machine code.
|
||||||
|
| |
|
||||||
|
440 - 443 | disk_sgntr | Disc signature, an individual disk id of obscure
|
||||||
|
| | usability.
|
||||||
|
| | (The Code Area might extend up to this field.)
|
||||||
|
| |
|
||||||
|
444 - 445 | 0 | "usually nulls"
|
||||||
|
| | (The Code Area might extend up to this field.)
|
||||||
|
| |
|
||||||
|
446 - 461 | ========== | Partition Table Entry for partition 1
|
||||||
|
| |
|
||||||
|
446 - 446 | status | Governs bootability:
|
||||||
|
| | 0x80 = bootable/active , 0x00 non-bootable/inactive
|
||||||
|
| |
|
||||||
|
447 - 449 | ========== | C/H/S address of partition start
|
||||||
|
447 - 447 | start_head | Heads part of start address.
|
||||||
|
448 - 448 | start_c_s | Bits 0 to 5 : Sectors part of start address.
|
||||||
|
| | Bits 6 to 7 : Bits 8 to 9 of cylinders part.
|
||||||
|
449 - 449 | start_cyl | Lower 8 bits of cylinders part of start address
|
||||||
|
| |
|
||||||
|
450 - 450 | part_type | Partition type indicates the purpose or kind of
|
||||||
|
| | filesystem in the partition.
|
||||||
|
| |
|
||||||
|
451 - 453 | ========== | C/H/S address of last absolute sector in partition
|
||||||
|
451 - 451 | end_head | Heads part of end address.
|
||||||
|
452 - 452 | end_c_s | Bits 0 to 5 : Sectors part of end address.
|
||||||
|
| Values: 1 to 63, not 0.
|
||||||
|
| | Bits 6 to 7 : Bits 8 to 9 of cylinders part.
|
||||||
|
453 - 453 | end_cyl | Lower 8 bits of cylinders part of end address
|
||||||
|
| |
|
||||||
|
454 - 457 | start_lba | LBA of first absolute sector in partiton.
|
||||||
|
| | Block size is 512. Counting starts at 0.
|
||||||
|
| |
|
||||||
|
458 - 461 | num_blocks | Number of sectors in partition.
|
||||||
|
| |
|
||||||
|
462 - 477 | ========== | Partition Table Entry for partition 2
|
||||||
|
| part_entr2 | 16 bytes. Format as with partition 1.
|
||||||
|
| | All 0 means that partition is unused/undefined.
|
||||||
|
| |
|
||||||
|
478 - 493 | ========== | Partition Table Entry for partition 3
|
||||||
|
| part_entr3 | 16 bytes. See above.
|
||||||
|
| |
|
||||||
|
494 - 509 | ========== | Partition Table Entry for partition 4
|
||||||
|
| part_entr4 | 16 bytes. See above.
|
||||||
|
| |
|
||||||
|
510 - 510 | 0x55 | MBR signature
|
||||||
|
511 - 511 | 0xaa | MBR signature
|
||||||
|
| |
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
By tradition the MBR itself and possibly more blocks are not claimed by any
|
||||||
|
partition. But starting the first partition at a non-zero block address causes
|
||||||
|
on Linux a partition device file (e.g. /dev/sdb1) which cannot be used to mount
|
||||||
|
the ISO filesystem.
|
||||||
|
|
||||||
|
libisofs is able to produce a second set of trees and meta data which is
|
||||||
|
suitable for being mounted at start block 16 (ISO) resp. 64 (MBR).
|
||||||
|
See <libisofs/libisofs.h> for call iso_write_opts_set_part_offset()
|
||||||
|
and http://libburnia-project.org/wiki/PartitionOffset for examples with
|
||||||
|
program xorriso.
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
SYSLINUX Isohybrid MBR
|
||||||
|
|
||||||
|
Sources:
|
||||||
|
syslinux-3.72/utils/isohybrid , a perl script by H. Peter Anvin = hpa.
|
||||||
|
Mailing list conversations with hpa.
|
||||||
|
|
||||||
|
|
||||||
|
An isohybrid MBR directs the booting BIOS to an ISOLINUX boot image which
|
||||||
|
is also the target of an El Torito boot catalog entry.
|
||||||
|
For that purpose one has to take an MBR template and has to set a few bytes
|
||||||
|
to values which sufficiently describe the ISO image and the boot image file.
|
||||||
|
|
||||||
|
Words are composed little-endian style.
|
||||||
|
|
||||||
|
Byte Range | Value | Meaning
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
0 - 431 | = opaque = | Syslinux machine code provided by MBR template
|
||||||
|
| |
|
||||||
|
432 - 439 | hd_bootlba | Address of the ISOLINUX boot image file in the
|
||||||
|
| | ISO image. Counted in 512 byte blocks.
|
||||||
|
| |
|
||||||
|
440 - 443 | mbr_id | Random number
|
||||||
|
444 - 445 | 0 | Padding
|
||||||
|
| |
|
||||||
|
446 - 509 | ========== | Partition table
|
||||||
|
| |
|
||||||
|
446 - 461 | part_entry | Partition table entry 1 describing ISO image size
|
||||||
|
| | starting at LBA 0. I.e. contrary to tradition.
|
||||||
|
| | See above for partition table entry format.
|
||||||
|
| |
|
||||||
|
462 - 509 | 0 | Unused partition entries 2 to 4
|
||||||
|
510 - 511 | 0xaa55 | MBR signature
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
hpa about MBR templates and partition table filesystem types:
|
||||||
|
|
||||||
|
"[MBR templates] are available in the Syslinux build tree under the names:
|
||||||
|
mbr/isohdp[fp]x*.bin
|
||||||
|
The default probably should be mbr/isohdppx.bin, but it's ultimately up
|
||||||
|
to the user.
|
||||||
|
[...]
|
||||||
|
Note: the filesystem type is largely arbitrary, in theory it can be any
|
||||||
|
value other than 0x00, 0x05, 0x0f, 0x85, 0xee, or 0xef. 0x17 ("Windows
|
||||||
|
IFS Hidden") seems safeish, some people believe 0x83 (Linux) is better.
|
||||||
|
"
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
GRUB2 grub-mkrescue MBR
|
||||||
|
|
||||||
|
Sources:
|
||||||
|
Mailing list conversations with Vladimir Serbinenko.
|
||||||
|
|
||||||
|
|
||||||
|
The MBR file that is used with GRUB2 script grub-mkrescue needs only a
|
||||||
|
partition table entry which describes the image size.
|
||||||
|
|
||||||
|
Byte Range | Value | Meaning
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
0 - 445 | = opaque = | GRUB2 machine code provided by MBR template
|
||||||
|
| |
|
||||||
|
446 - 509 | ========== | Partition table
|
||||||
|
| |
|
||||||
|
446 - 461 | part_entry | Partition table entry 1 describing ISO image size
|
||||||
|
| | Peculiar is the start offset of 1 block.
|
||||||
|
| | This prevents mounting of the partition.
|
||||||
|
| | See above for partition table entry format.
|
||||||
|
| |
|
||||||
|
462 - 509 | 0 | Unused partition entries 2 to 4
|
||||||
|
510 - 511 | 0xaa55 | MBR signature
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
|
||||||
|
Vladimir Serbinenko about the partition table entry:
|
||||||
|
"Currently we use first and not last entry. You need to:
|
||||||
|
1) Zero-fill 446-510
|
||||||
|
2) Put 0x55, 0xAA into 510-512
|
||||||
|
3) Put 0x80 (for bootable partition), 0, 2, 0 (C/H/S of the start), 0xcd
|
||||||
|
(partition type), [3 bytes of C/H/S end], 0x01, 0x00, 0x00, 0x00 (LBA
|
||||||
|
start in little endian), [LBA end in little endian] at 446-462
|
||||||
|
"
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
MIPS Volume Header
|
||||||
|
for MIPS Big Endian, e.g. SGI Indigo2
|
||||||
|
|
||||||
|
Sources:
|
||||||
|
cdrkit-1.1.10/genisoimage/boot-mips.c
|
||||||
|
by Steve McIntyre <steve@einval.com>
|
||||||
|
which refers to
|
||||||
|
genisovh by Florian Lohoff <flo@rfc822.org>
|
||||||
|
and Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
|
||||||
|
who seem to have learned parameter settings from IRIX CD media
|
||||||
|
There are traces in the web which relate this to specs by
|
||||||
|
MIPS Computer Systems, Inc. , 1985
|
||||||
|
Silicon Graphics Computer Systems, Inc. , 2000
|
||||||
|
|
||||||
|
|
||||||
|
The first 512 bytes of the media constitute the Volume Header.
|
||||||
|
Words are composed big-endian style.
|
||||||
|
|
||||||
|
Byte Range | Value | Meaning
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
0 - 3 | 0x0be5a941 | Magic number
|
||||||
|
4 - 5 | 0 | Root partition number
|
||||||
|
6 - 7 | 0 | Swap partition number
|
||||||
|
8 - 23 | 0 | Name of file to boot (unclear what this means)
|
||||||
|
| |
|
||||||
|
24 - 71 | ========== | Device Parameters
|
||||||
|
| |
|
||||||
|
24 - 24 | 0 | Spiral addressing skew (unclear what this means)
|
||||||
|
25 - 25 | 0 | Words of 0 before header
|
||||||
|
26 - 26 | 0 | Words of 0 between hdr and data
|
||||||
|
27 - 27 | 0 | Spare sectors per cylinder
|
||||||
|
28 - 29 | num_cyl_l | Number of usable cylinder, lower two bytes
|
||||||
|
| | ((iso_size + BYTES_PER_SECTOR - 1) /
|
||||||
|
| | (SECTORS_PER_TRACK * BYTES_PER_SECTOR)) & 0xffff
|
||||||
|
30 - 31 | 0 | Starting head of volume 0
|
||||||
|
32 - 33 | 1 | Number of tracks per cylinder
|
||||||
|
34 - 34 | 0 | Depth of CTQ queue (unclear what this means)
|
||||||
|
35 - 35 | num_cyl_h | Number of usable cylinders, high byte
|
||||||
|
| | ((iso_size + BYTES_PER_SECTOR - 1) /
|
||||||
|
| | (SECTORS_PER_TRACK * BYTES_PER_SECTOR)) >> 16
|
||||||
|
36 - 37 | 0 | unused
|
||||||
|
38 - 39 | 32 | SECTORS_PER_TRACK
|
||||||
|
40 - 41 | 512 | BYTES_PER_SECTOR
|
||||||
|
42 - 43 | 0 | Sector interleave (unclear what this means)
|
||||||
|
44 - 47 | 0x00000034 | Controller characteristics composed from
|
||||||
|
| | DP_RESEEK 0x00000020 /* recalibrate as last resort */
|
||||||
|
| | DP_IGNOREERRORS 0x00000010
|
||||||
|
| | /* transfer data regardless of errors */
|
||||||
|
| | DP_TRKFWD 0x00000004
|
||||||
|
| | /* forward to replacement track */
|
||||||
|
48 - 51 | 0 | Bytes/sec for kernel stats
|
||||||
|
52 - 55 | 0 | Max num retries on data error
|
||||||
|
56 - 59 | 0 | ms per word to xfer, for iostat
|
||||||
|
60 - 71 | 0 | 6 parameter words for xylogics controllers
|
||||||
|
| |
|
||||||
|
72 - 311 | ========== | Volume Directory with 15 entries of 16 bytes each
|
||||||
|
| |
|
||||||
|
72 - 87 | ========== | Volume Directory Entry 1
|
||||||
|
72 - 79 | boot_name | Boot file basename, eventually padded by 0 to lenght 8
|
||||||
|
80 - 83 | boot_block | ISO 9660 LBA of boot file * 4, i.e. in blocks of 512
|
||||||
|
84 - 87 | boot_bytes | File length in bytes
|
||||||
|
| |
|
||||||
|
88 - 311 | see above | Volume Directory Entries 2 to 15
|
||||||
|
| |
|
||||||
|
312 - 504 | ========== | Partition Table with 16 entries of 12 bytes each
|
||||||
|
| |
|
||||||
|
312 - 407 | 0 | Unused partition entries 1 to 8
|
||||||
|
| |
|
||||||
|
408 - 419 | ========== | Partition Table Entry 9 for Volume Header
|
||||||
|
408 - 411 | part_blks | Number of 512 byte blocks in partition
|
||||||
|
| |(iso_size + (BYTES_PER_SECTOR - 1)) / BYTES_PER_SECTOR
|
||||||
|
412 - 415 | 0 | Start block of partition
|
||||||
|
416 - 419 | 0 | PTYPE_VOLHDR = Partition is volume header
|
||||||
|
| |
|
||||||
|
420 - 431 | 0 | Unused partition entry 10
|
||||||
|
| |
|
||||||
|
432 - 443 | ========== | Partition Table Entry 11 for Volume
|
||||||
|
432 - 435 | part_blks | Number of 512 byte blocks in partition
|
||||||
|
| |(iso_size + (BYTES_PER_SECTOR - 1)) / BYTES_PER_SECTOR
|
||||||
|
436 - 439 | 0 | Start block of partition
|
||||||
|
440 - 443 | 6 | PTYPE_VOLUME = Partition is entire volume
|
||||||
|
| |
|
||||||
|
444 - 503 | 0 | Unused partition entries 12 to 16
|
||||||
|
| |
|
||||||
|
504 - 507 | head_chk | Volume header checksum
|
||||||
|
| | The two's complement of bytes 0 to 503 read as big
|
||||||
|
| | endian unsigned 32 bit: sum(words) + head_chk == 0
|
||||||
|
| |
|
||||||
|
508 - 511 | 0 | Volume header end padding
|
||||||
|
| |
|
||||||
|
up to 2048 | 0 | ISO 9660 Block end padding
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
DEC Boot Block
|
||||||
|
for MIPS Little Endian , e.g. DECstation
|
||||||
|
|
||||||
|
Sources:
|
||||||
|
cdrkit-1.1.10/genisoimage/boot-mipsel.c
|
||||||
|
by Steve McIntyre <steve@einval.com>
|
||||||
|
which refers to
|
||||||
|
delo by Florian Lohoff <flo@rfc822.org>
|
||||||
|
and Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
|
||||||
|
cdrkit-1.1.10/include/glibc_elf.h
|
||||||
|
by Steve McIntyre
|
||||||
|
which is based on
|
||||||
|
<elf.h> from GNUC C Library by Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
|
||||||
|
There seems to be only one boot file possible.
|
||||||
|
Some information needs to be read out of the ELF headers of this boot file.
|
||||||
|
|
||||||
|
Byte Range | Value | Meaning
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
0 - 7 | 0 | Padding
|
||||||
|
| |
|
||||||
|
8 - 11 | 0x0002757a | Magic number
|
||||||
|
| |
|
||||||
|
12 - 15 | 1 | Mode /* 0: Single extent, 1: Multi extent boot */
|
||||||
|
| |
|
||||||
|
16 - 19 | load_adr | Load address /* Load below kernel */
|
||||||
|
| | Stems from ELF header of boot file.
|
||||||
|
| | See below Elf32_Phdr field p_vaddr.
|
||||||
|
| |
|
||||||
|
20 - 23 | exec_adr | Execution address /* And exec there */
|
||||||
|
| | Stems from ELF header of boot file.
|
||||||
|
| | See below Elf32_Ehdr field e_entry.
|
||||||
|
| |
|
||||||
|
24 - 31 | ========== | Boot Map Entry 1
|
||||||
|
| |
|
||||||
|
24 - 27 | seg_size | Segment size in file. Blocks of 512 bytes.
|
||||||
|
| | Stems from ELF header of boot file.
|
||||||
|
| | (Elf32_Phdr field p_filesz + 511) / 512;
|
||||||
|
| |
|
||||||
|
28 - 31 | seg_start | Segment file offset. Blocks 512 bytes.
|
||||||
|
| | ISO 9660 LBA of boot file * 4 plus offset
|
||||||
|
| | + offset which stems from ELF header of boot file:
|
||||||
|
| | (Elf32_Phdr field p_offset + 511) / 512;
|
||||||
|
| |
|
||||||
|
32 - 431 | ========== | Boot Map Entries 2 to 51
|
||||||
|
| 0 |
|
||||||
|
| |
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
Elf32_Ehdr gets loaded from boot file byte address 0:
|
||||||
|
|
||||||
|
Byte Range | Value | Meaning
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
0 - 23 | | ( Magic number, file information )
|
||||||
|
| |
|
||||||
|
24 - 27 | e_entry | /* Entry point virtual address */
|
||||||
|
| = exec_adr | Needed for exec_adr
|
||||||
|
| |
|
||||||
|
28 - 31 | e_phoff | /* Program header table file offset */
|
||||||
|
| | Byte address of Elf32_Phdr
|
||||||
|
| |
|
||||||
|
|
||||||
|
Elf32_Phdr gets loaded from boot file byte_address Elf32_Ehdr.e_phoff :
|
||||||
|
Byte Range | Value | Meaning
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
0 - 3 | | ( Segment type )
|
||||||
|
| |
|
||||||
|
4 - 7 | p_offset | /* Segment file offset */
|
||||||
|
|-> seg_start| Needed for seg_start
|
||||||
|
| |
|
||||||
|
8 - 11 | p_vaddr | /* Segment virtual address */
|
||||||
|
| =load_adr | Needed for load_adr
|
||||||
|
| |
|
||||||
|
12 - 15 | | (Segment physical address)
|
||||||
|
| |
|
||||||
|
16 - 19 | p_filesz | /* Segment size in file */
|
||||||
|
|-> seg_size | Needed for seg_size
|
||||||
|
| |
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
SUN Disk Label and boot images
|
||||||
|
for SUN SPARC
|
||||||
|
|
||||||
|
Sources:
|
||||||
|
cdrtools-2.01.01a77/mkisofs/sunlabel.h
|
||||||
|
cdrtools-2.01.01a77/mkisofs/mkisofs.8
|
||||||
|
by Joerg Schilling
|
||||||
|
|
||||||
|
|
||||||
|
The Disk Label is written to the first 512 bytes of the image. It can mark
|
||||||
|
8 partitions (slices ) of which the first contains the ISO image. The other
|
||||||
|
7 may contain boot images.
|
||||||
|
Words are composed big-endian style.
|
||||||
|
|
||||||
|
Boot images are provided externally. mkisofs arranges them after the end of
|
||||||
|
the ISO image so that each starts at a cylinder boundary (320 kB).
|
||||||
|
|
||||||
|
There is a mechanism in mkisofs which fills unused partitions by copies of
|
||||||
|
their predecessor in the partition table:
|
||||||
|
"If the special filename ... is used, the actual and all following
|
||||||
|
boot partitions are mapped to the previous partition.
|
||||||
|
If mkisofs is called with -G image -B ... all boot partitions are
|
||||||
|
mapped to the partition that contains the ISO9660 filesystem."
|
||||||
|
|
||||||
|
|
||||||
|
Disk Label components:
|
||||||
|
|
||||||
|
Byte Range | Value | Meaning
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
0 - 127 | label | ASCII Label
|
||||||
|
| | "CD-ROM Disc with Sun sparc boot created by ..."
|
||||||
|
| | mkisofs option -sparc-label
|
||||||
|
| |
|
||||||
|
128 - 263 | ========== | /* vtoc inclusions from AT&T SVr4 */
|
||||||
|
| |
|
||||||
|
128 - 131 | 1 | Layout version
|
||||||
|
132 - 139 | 0 | /* volume name */
|
||||||
|
140 - 141 | 8 | Number of partitions
|
||||||
|
| |
|
||||||
|
142 - 173 | ========== | 8 partition entries of 4 bytes
|
||||||
|
| |
|
||||||
|
142 - 145 | ========== | Entry for partition 1
|
||||||
|
142 - 143 | 4 | ID tag of partition: 4 = User partition
|
||||||
|
144 - 145 | 0x10 | Permissions: 0x10 = read-only
|
||||||
|
| |
|
||||||
|
146 - 149 | ========== | Entry for partition 2
|
||||||
|
146 - 147 | id_tag2 | ID tag of partition:
|
||||||
|
| | 0 = unused
|
||||||
|
| | 2 = Root partition with boot image
|
||||||
|
148 - 149 | perm2 | Permissions:
|
||||||
|
| | 0 = unused
|
||||||
|
| | 0x10 = read-only (if used)
|
||||||
|
| |
|
||||||
|
150 - 173 | ========== | Entries for partition 3 to 8.
|
||||||
|
| | See above: Entry for partition 2
|
||||||
|
| |
|
||||||
|
174 - 175 | 0 | Padding
|
||||||
|
| |
|
||||||
|
176 - 187 | 0 | /* info for mboot */
|
||||||
|
| |
|
||||||
|
188 - 191 | 0x600ddeee | /* to verify vtoc sanity */
|
||||||
|
| |
|
||||||
|
192 - 231 | 0 | Reserved
|
||||||
|
| |
|
||||||
|
232 - 263 | 0 | 8 Timestamps of yet unknown format
|
||||||
|
| |
|
||||||
|
264 - 419 | 0 | Padding
|
||||||
|
| |
|
||||||
|
420 - 443 | ========== | Disk properties
|
||||||
|
| |
|
||||||
|
420 - 421 | 350 | Rotations per minute
|
||||||
|
422 - 423 | 2048 | Number of physical cylinders (fixely 640 MB)
|
||||||
|
424 - 425 | 0 | /* alternates per cylinder */
|
||||||
|
426 - 429 | 0 | /* obsolete */
|
||||||
|
430 - 431 | 1 | /* interleave factor */
|
||||||
|
432 - 433 | 2048 | Number of data cylinders (fixely 640 MB)
|
||||||
|
434 - 435 | 0 | /* # of alternate cylinders */
|
||||||
|
436 - 437 | 1 | Number of heads per cylinder (i.e. 1 cyl = 320 kB)
|
||||||
|
438 - 439 | 640 | Number of sectors per head (i.e. 1 head = 320 kB)
|
||||||
|
440 - 443 | 0 | /* obsolete */
|
||||||
|
| |
|
||||||
|
444 - 507 | ========== | Partition table
|
||||||
|
| |
|
||||||
|
444 - 451 | ========== | Partition table entry #1
|
||||||
|
| |
|
||||||
|
444 - 447 | start_cyl | Start cylinder
|
||||||
|
| |
|
||||||
|
448 - 451 | num_blocks | Number of blocks in partition
|
||||||
|
| |
|
||||||
|
452 - 507 | ========== | Partition table entries #2 to #8
|
||||||
|
| ... | See above Partition table entry #1
|
||||||
|
| |
|
||||||
|
508 - 509 | 0xdabe | Magic Number
|
||||||
|
| |
|
||||||
|
510 - 511 | checksum | The result of exoring 2-byte words 0 to 254
|
||||||
|
| |
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
>>> ??? HP-PA
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
>>> ??? DEC Alpha
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
@ -59,7 +59,7 @@ Entry number N + 1 holds the MD5 checksum of entries 0 to N.
|
|||||||
|
|
||||||
Because the inquiry of AAIP attributes demands loading of the image tree,
|
Because the inquiry of AAIP attributes demands loading of the image tree,
|
||||||
there are also checksum tags which can be detected on the fly when reading
|
there are also checksum tags which can be detected on the fly when reading
|
||||||
and checksumming the session from the start point as learned from a media
|
and checksumming the session from its start point as learned from a media
|
||||||
table-of-content.
|
table-of-content.
|
||||||
|
|
||||||
The superblock checksum tag is written after the ECMA-119 volume descriptors.
|
The superblock checksum tag is written after the ECMA-119 volume descriptors.
|
||||||
@ -79,7 +79,7 @@ Tag_id distinguishes the following tag types
|
|||||||
"libisofs_checksum_tag_v1" Session tag
|
"libisofs_checksum_tag_v1" Session tag
|
||||||
|
|
||||||
A relocated superblock may appear at LBA 0 of an image which was produced for
|
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+R, BD-RE).
|
being stored in a disk file or on overwriteable media (e.g. DVD+RW, BD-RE).
|
||||||
Typically there is a first session recorded with a superblock at LBA 32 and
|
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
|
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
|
next block address which is divisible by 32.) Normally no session starts after
|
||||||
@ -280,3 +280,41 @@ to iso_image_import() when reading the image. If this source is associated
|
|||||||
to a libburn drive, then libburn function burn_read_data() can read directly
|
to a libburn drive, then libburn function burn_read_data() can read directly
|
||||||
from it.
|
from it.
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
scdbackup Checksum Tags
|
||||||
|
|
||||||
|
The session checksum tag does not occupy its whole block. So there is room to
|
||||||
|
store a scdbackup stream checksum tag, which is an ancestor format of the tags
|
||||||
|
described here. This feature allows scdbackup to omit its own checksum filter
|
||||||
|
if using xorriso as ISO 9660 formatter program.
|
||||||
|
Such a tag makes only sense if the session begins at LBA 0.
|
||||||
|
|
||||||
|
See scdbackup-*/README, appendix VERIFY for a specification.
|
||||||
|
|
||||||
|
Example of a scdbackup checksum tag:
|
||||||
|
scdbackup_checksum_tag_v0.1 2456606865 61 2_2 B00109.143415 2456606865 485bbef110870c45754d7adcc844a72c c2355d5ea3c94d792ff5893dfe0d6d7b
|
||||||
|
|
||||||
|
The tag is located at byte position 2456606865, contains 61 bytes of scdbackup
|
||||||
|
checksum record (the next four words):
|
||||||
|
Name of the backup volume is "2_2".
|
||||||
|
Written in year B0 = 2010 (A9 = 2009, B1 = 2011), January (01), 9th (09),
|
||||||
|
14:34:15 local time.
|
||||||
|
The size of the volume is 2456606865 bytes, which have a MD5 sum of
|
||||||
|
485bbef110870c45754d7adcc844a72c.
|
||||||
|
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.
|
||||||
|
|
||||||
|
@ -154,13 +154,6 @@ QT_AUTOBRIEF = NO
|
|||||||
|
|
||||||
MULTILINE_CPP_IS_BRIEF = YES
|
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
|
# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
|
||||||
# member inherits the documentation from any documented member that it
|
# member inherits the documentation from any documented member that it
|
||||||
# re-implements.
|
# re-implements.
|
||||||
@ -1150,7 +1143,8 @@ HIDE_UNDOC_RELATIONS = YES
|
|||||||
# toolkit from AT&T and Lucent Bell Labs. The other options in this section
|
# 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 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
|
# 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
|
# will generate a graph for each documented class showing the direct and
|
||||||
|
@ -443,3 +443,14 @@ Program mkisofs emits entry XA
|
|||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
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 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.
|
||||||
|
|
||||||
|
@ -22,6 +22,8 @@ Purpose:
|
|||||||
END is also the block address of the start of the checksum recording
|
END is also the block address of the start of the checksum recording
|
||||||
area in the image.
|
area in the image.
|
||||||
See also isofs.cx .
|
See also isofs.cx .
|
||||||
|
This attribute shall eventually be attached to the root directory entry
|
||||||
|
and be global for the whole image.
|
||||||
|
|
||||||
Format of Value:
|
Format of Value:
|
||||||
START_LEN | START_BYTES | END_LEN | END_BYTES |
|
START_LEN | START_BYTES | END_LEN | END_BYTES |
|
||||||
@ -149,3 +151,14 @@ Registered:
|
|||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
This text is under
|
||||||
|
Copyright (c) 2009 - 2011 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.
|
||||||
|
|
||||||
|
@ -141,3 +141,14 @@ SUSP 1.12
|
|||||||
RRIP 1.12
|
RRIP 1.12
|
||||||
ftp://ftp.ymi.com/pub/rockridge/rrip112.ps
|
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".
|
||||||
|
|
||||||
|
@ -11,10 +11,14 @@
|
|||||||
|
|
||||||
To be included by aaip_0_2.c
|
To be included by aaip_0_2.c
|
||||||
|
|
||||||
Copyright (c) 2009 Thomas Schmitt, libburnia project, GPLv2
|
Copyright (c) 2009 Thomas Schmitt, libburnia project, GPLv2+
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
aaip-os-freebsd.c
|
aaip-os-freebsd.c
|
||||||
Arbitrary Attribute Interchange Protocol , system adapter for getting and
|
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
|
||||||
|
|
||||||
@ -11,6 +11,10 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -18,6 +22,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#ifndef Libisofs_with_aaip_acL
|
#ifndef Libisofs_with_aaip_acL
|
||||||
/* It seems ACL is fixely integrated in FreeBSD libc. There is no libacl. */
|
/* It seems ACL is fixely integrated in FreeBSD libc. There is no libacl. */
|
||||||
@ -37,13 +42,14 @@
|
|||||||
finally has to be freed by a call to this function
|
finally has to be freed by a call to this function
|
||||||
with bit15 of flag.
|
with bit15 of flag.
|
||||||
@param flag Bitfield for control purposes
|
@param flag Bitfield for control purposes
|
||||||
bit0= obtain default ACL rather than access ACL
|
(bit0= obtain default ACL rather than access ACL)
|
||||||
bit4= set *text = NULL and return 2
|
bit4= set *text = NULL and return 2
|
||||||
if the ACL matches st_mode permissions.
|
if the ACL matches st_mode permissions.
|
||||||
bit5= in case of symbolic link: inquire link target
|
bit5= in case of symbolic link: inquire link target
|
||||||
bit15= free text and return 1
|
bit15= free text and return 1
|
||||||
@return > 0 ok
|
@return > 0 ok
|
||||||
0 ACL support not enabled at compile time
|
0 ACL support not enabled at compile time
|
||||||
|
or filesystem does not support ACL
|
||||||
-1 failure of system ACL service (see errno)
|
-1 failure of system ACL service (see errno)
|
||||||
-2 attempt to inquire ACL of a symbolic
|
-2 attempt to inquire ACL of a symbolic
|
||||||
link without bit4 or bit5
|
link without bit4 or bit5
|
||||||
@ -88,8 +94,18 @@ int aaip_get_acl_text(char *path, char **text, int flag)
|
|||||||
|
|
||||||
acl= acl_get_file(path, ACL_TYPE_ACCESS);
|
acl= acl_get_file(path, ACL_TYPE_ACCESS);
|
||||||
|
|
||||||
if(acl == NULL)
|
if(acl == NULL) {
|
||||||
|
if(errno == EOPNOTSUPP) {
|
||||||
|
/* filesystem does not support ACL */
|
||||||
|
if(flag & 16)
|
||||||
|
return(2);
|
||||||
|
|
||||||
|
/* >>> ??? fake ACL from POSIX permissions ? */;
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
return(-1);
|
return(-1);
|
||||||
|
}
|
||||||
*text= acl_to_text(acl, NULL);
|
*text= acl_to_text(acl, NULL);
|
||||||
acl_free(acl);
|
acl_free(acl);
|
||||||
|
|
||||||
@ -181,10 +197,8 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
|
|||||||
|
|
||||||
if(flag & 1) { /* Obtain ACL */
|
if(flag & 1) { /* Obtain ACL */
|
||||||
/* access-ACL */
|
/* access-ACL */
|
||||||
ret= aaip_get_acl_text(path, &acl_text, flag & (16 | 32));
|
aaip_get_acl_text(path, &acl_text, flag & (16 | 32));
|
||||||
if(ret <= 0)
|
if(acl_text == NULL)
|
||||||
goto ex;
|
|
||||||
if(ret == 2)
|
|
||||||
{ret= 1; goto ex;} /* empty ACL / only st_mode info was found in ACL */
|
{ret= 1; goto ex;} /* empty ACL / only st_mode info was found in ACL */
|
||||||
ret= aaip_encode_acl(acl_text, (mode_t) 0, &a_acl_len, &a_acl, flag & 2);
|
ret= aaip_encode_acl(acl_text, (mode_t) 0, &a_acl_len, &a_acl, flag & 2);
|
||||||
if(ret <= 0)
|
if(ret <= 0)
|
||||||
|
@ -7,10 +7,14 @@
|
|||||||
|
|
||||||
To be included by aaip_0_2.c
|
To be included by aaip_0_2.c
|
||||||
|
|
||||||
Copyright (c) 2009 Thomas Schmitt, libburnia project, GPLv2
|
Copyright (c) 2009 Thomas Schmitt, libburnia project, GPLv2+
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -18,6 +22,8 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
|
||||||
#ifdef Libisofs_with_aaip_acL
|
#ifdef Libisofs_with_aaip_acL
|
||||||
#include <sys/acl.h>
|
#include <sys/acl.h>
|
||||||
@ -46,6 +52,7 @@
|
|||||||
2 only st_mode permissions exist and bit 4 is set
|
2 only st_mode permissions exist and bit 4 is set
|
||||||
or empty ACL and bit0 is set
|
or empty ACL and bit0 is set
|
||||||
0 ACL support not enabled at compile time
|
0 ACL support not enabled at compile time
|
||||||
|
or filesystem does not support ACL
|
||||||
-1 failure of system ACL service (see errno)
|
-1 failure of system ACL service (see errno)
|
||||||
-2 attempt to inquire ACL of a symbolic link without
|
-2 attempt to inquire ACL of a symbolic link without
|
||||||
bit4 or bit5 resp. with no suitable link target
|
bit4 or bit5 resp. with no suitable link target
|
||||||
@ -79,8 +86,18 @@ int aaip_get_acl_text(char *path, char **text, int flag)
|
|||||||
}
|
}
|
||||||
|
|
||||||
acl= acl_get_file(path, (flag & 1) ? ACL_TYPE_DEFAULT : ACL_TYPE_ACCESS);
|
acl= acl_get_file(path, (flag & 1) ? ACL_TYPE_DEFAULT : ACL_TYPE_ACCESS);
|
||||||
if(acl == NULL)
|
if(acl == NULL) {
|
||||||
|
if(errno == ENOTSUP) {
|
||||||
|
/* filesystem does not support ACL */
|
||||||
|
if(flag & 16)
|
||||||
|
return(2);
|
||||||
|
|
||||||
|
/* >>> ??? fake ACL from POSIX permissions ? */;
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
return(-1);
|
return(-1);
|
||||||
|
}
|
||||||
*text= acl_to_text(acl, NULL);
|
*text= acl_to_text(acl, NULL);
|
||||||
acl_free(acl);
|
acl_free(acl);
|
||||||
|
|
||||||
@ -278,9 +295,9 @@ ex:;
|
|||||||
aaip_get_acl_text("", &a_acl_text, 1 << 15); /* free */
|
aaip_get_acl_text("", &a_acl_text, 1 << 15); /* free */
|
||||||
if(d_acl_text != NULL)
|
if(d_acl_text != NULL)
|
||||||
aaip_get_acl_text("", &d_acl_text, 1 << 15); /* free */
|
aaip_get_acl_text("", &d_acl_text, 1 << 15); /* free */
|
||||||
|
if(list != NULL)
|
||||||
|
free(list);
|
||||||
if(ret <= 0 || (flag & (1 << 15))) {
|
if(ret <= 0 || (flag & (1 << 15))) {
|
||||||
if(list != NULL)
|
|
||||||
free(list);
|
|
||||||
if(*names != NULL) {
|
if(*names != NULL) {
|
||||||
for(i= 0; i < *num_attrs; i++)
|
for(i= 0; i < *num_attrs; i++)
|
||||||
free((*names)[i]);
|
free((*names)[i]);
|
||||||
@ -384,7 +401,7 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
|
|||||||
size_t i, consumed, acl_text_fill, acl_idx= 0, h_consumed;
|
size_t i, consumed, acl_text_fill, acl_idx= 0, h_consumed;
|
||||||
char *acl_text= NULL, *list= NULL;
|
char *acl_text= NULL, *list= NULL;
|
||||||
#ifdef Libisofs_with_aaip_xattR
|
#ifdef Libisofs_with_aaip_xattR
|
||||||
size_t list_size= 0;
|
ssize_t list_size= 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef Libisofs_with_aaip_xattR
|
#ifdef Libisofs_with_aaip_xattR
|
||||||
|
@ -7,10 +7,14 @@
|
|||||||
See test/aaip_0_2.h
|
See test/aaip_0_2.h
|
||||||
http://libburnia-project.org/wiki/AAIP
|
http://libburnia-project.org/wiki/AAIP
|
||||||
|
|
||||||
Copyright (c) 2009 Thomas Schmitt, libburnia project, GPLv2
|
Copyright (c) 2009 Thomas Schmitt, libburnia project, GPLv2+
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -567,7 +571,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-
|
The permissions defined by ACLs are a superset of the permissions speci-
|
||||||
fied by the file permission bits. The permissions defined for the file
|
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-
|
owner correspond to the permissions of the ACL_USER_OBJ entry. The per-
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
test/aaip_0_2.h - Public declarations
|
test/aaip_0_2.h - Public declarations
|
||||||
|
|
||||||
Copyright (c) 2009 Thomas Schmitt, libburnia project, GPLv2
|
Copyright (c) 2009 Thomas Schmitt, libburnia project, GPLv2+
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -2,8 +2,9 @@
|
|||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -16,6 +17,10 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Use the copy of the struct burn_source definition in libisofs.h
|
Use the copy of the struct burn_source definition in libisofs.h
|
||||||
*/
|
*/
|
||||||
@ -288,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.
|
* Get the status of the buffer used by a burn_source.
|
||||||
*
|
*
|
||||||
* @param b
|
* @param b
|
||||||
@ -316,18 +365,7 @@ int iso_ring_buffer_get_status(struct burn_source *b, size_t *size,
|
|||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
}
|
}
|
||||||
buf = ((Ecma119Image*)(b->data))->buffer;
|
buf = ((Ecma119Image*)(b->data))->buffer;
|
||||||
|
ret = iso_ring_buffer_get_buf_status(buf, size, free_bytes);
|
||||||
/* 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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,15 +2,23 @@
|
|||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef LIBISO_BUFFER_H_
|
#ifndef LIBISO_BUFFER_H_
|
||||||
#define LIBISO_BUFFER_H_
|
#define LIBISO_BUFFER_H_
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_STDINT_H
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_INTTYPES_H
|
||||||
|
#include <inttypes.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#define BLOCK_SIZE 2048
|
#define BLOCK_SIZE 2048
|
||||||
|
|
||||||
@ -62,6 +70,28 @@ 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);
|
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).
|
* 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 explicity close the buffer when you don't have more data to
|
||||||
|
@ -3,10 +3,15 @@
|
|||||||
* Copyright (c) 2009 Thomas Schmitt
|
* Copyright (c) 2009 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/* libisofs.h defines aaip_xinfo_func */
|
/* libisofs.h defines aaip_xinfo_func */
|
||||||
#include "libisofs.h"
|
#include "libisofs.h"
|
||||||
|
|
||||||
@ -19,6 +24,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -65,6 +71,8 @@ int default_create_file(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
iso_file_source_ref(src);
|
iso_file_source_ref(src);
|
||||||
|
|
||||||
name = iso_file_source_get_name(src);
|
name = iso_file_source_get_name(src);
|
||||||
|
if (strlen(name) > LIBISOFS_NODE_NAME_MAX)
|
||||||
|
name[LIBISOFS_NODE_NAME_MAX] = 0;
|
||||||
ret = iso_node_new_file(name, stream, &node);
|
ret = iso_node_new_file(name, stream, &node);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
iso_stream_unref(stream);
|
iso_stream_unref(stream);
|
||||||
@ -94,7 +102,7 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
IsoNode *new;
|
IsoNode *new;
|
||||||
IsoFilesystem *fs;
|
IsoFilesystem *fs;
|
||||||
char *name;
|
char *name;
|
||||||
unsigned char *aa_string;
|
unsigned char *aa_string = NULL;
|
||||||
char *a_text = NULL, *d_text = NULL;
|
char *a_text = NULL, *d_text = NULL;
|
||||||
|
|
||||||
if (builder == NULL || src == NULL || node == NULL) {
|
if (builder == NULL || src == NULL || node == NULL) {
|
||||||
@ -112,6 +120,8 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
}
|
}
|
||||||
|
|
||||||
name = iso_file_source_get_name(src);
|
name = iso_file_source_get_name(src);
|
||||||
|
if (strlen(name) > LIBISOFS_NODE_NAME_MAX)
|
||||||
|
name[LIBISOFS_NODE_NAME_MAX] = 0;
|
||||||
fs = iso_file_source_get_filesystem(src);
|
fs = iso_file_source_get_filesystem(src);
|
||||||
new = NULL;
|
new = NULL;
|
||||||
|
|
||||||
@ -147,10 +157,10 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
case S_IFLNK:
|
case S_IFLNK:
|
||||||
{
|
{
|
||||||
/* source is a symbolic link */
|
/* source is a symbolic link */
|
||||||
char dest[PATH_MAX];
|
char dest[LIBISOFS_NODE_PATH_MAX];
|
||||||
IsoSymlink *link;
|
IsoSymlink *link;
|
||||||
|
|
||||||
ret = iso_file_source_readlink(src, dest, PATH_MAX);
|
ret = iso_file_source_readlink(src, dest, LIBISOFS_NODE_PATH_MAX);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -211,6 +221,9 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
}
|
}
|
||||||
iso_aa_get_acl_text(aa_string, info.st_mode, &a_text, &d_text,
|
iso_aa_get_acl_text(aa_string, info.st_mode, &a_text, &d_text,
|
||||||
1 << 15); /* free ACL texts */
|
1 << 15); /* free ACL texts */
|
||||||
|
if(aa_string != NULL)
|
||||||
|
free(aa_string);
|
||||||
|
aa_string = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Obtain ownership of eventual AAIP string */
|
/* Obtain ownership of eventual AAIP string */
|
||||||
@ -221,6 +234,8 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
ret = iso_node_add_xinfo(new, aaip_xinfo_func, aa_string);
|
ret = iso_node_add_xinfo(new, aaip_xinfo_func, aa_string);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
} else if(aa_string != NULL) {
|
||||||
|
free(aa_string);
|
||||||
}
|
}
|
||||||
|
|
||||||
*node = new;
|
*node = new;
|
||||||
@ -231,6 +246,9 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
static
|
static
|
||||||
void default_free(IsoNodeBuilder *builder)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,8 +2,9 @@
|
|||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef LIBISO_BUILDER_H_
|
#ifndef LIBISO_BUILDER_H_
|
||||||
|
@ -2,10 +2,15 @@
|
|||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libisofs.h"
|
#include "libisofs.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
1436
libisofs/ecma119.c
1436
libisofs/ecma119.c
File diff suppressed because it is too large
Load Diff
@ -1,10 +1,11 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
* 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
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef LIBISO_ECMA119_H_
|
#ifndef LIBISO_ECMA119_H_
|
||||||
@ -14,7 +15,14 @@
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_STDINT_H
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_INTTYPES_H
|
||||||
|
#include <inttypes.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
#define BLOCK_SIZE 2048
|
#define BLOCK_SIZE 2048
|
||||||
@ -31,11 +39,44 @@
|
|||||||
*/
|
*/
|
||||||
#define ISO_EXTENT_SIZE 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 lenght 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
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds the options for the image generation.
|
* Holds the options for the image generation.
|
||||||
*/
|
*/
|
||||||
struct iso_write_opts {
|
struct iso_write_opts {
|
||||||
|
|
||||||
|
int will_cancel;
|
||||||
|
|
||||||
int level; /**< ISO level to write at. (ECMA-119, 10) */
|
int level; /**< ISO level to write at. (ECMA-119, 10) */
|
||||||
|
|
||||||
/** Which extensions to support. */
|
/** Which extensions to support. */
|
||||||
@ -53,11 +94,21 @@ struct iso_write_opts {
|
|||||||
* but it is supposed to work on most moderns systems. Use with caution.
|
* 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.
|
* Omit the version number (";1") at the end of the ISO-9660 identifiers.
|
||||||
* Version numbers are usually not used.
|
* 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.
|
* Allow ISO-9660 directory hierarchy to be deeper than 8 levels.
|
||||||
@ -81,8 +132,10 @@ struct iso_write_opts {
|
|||||||
* ISO-9660 forces filenames to have a ".", that separates file name from
|
* ISO-9660 forces filenames to have a ".", that separates file name from
|
||||||
* extension. libisofs adds it if original filename doesn't has one. Set
|
* extension. libisofs adds it if original filename doesn't has one. Set
|
||||||
* this to 1 to prevent this behavior
|
* 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
|
* Allow lowercase characters in ISO-9660 filenames. By default, only
|
||||||
@ -108,6 +161,11 @@ struct iso_write_opts {
|
|||||||
*/
|
*/
|
||||||
unsigned int joliet_longer_paths :1;
|
unsigned int joliet_longer_paths :1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allow Joliet names up to 103 characters rather than 64.
|
||||||
|
*/
|
||||||
|
unsigned int joliet_long_names :1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write Rock Ridge info as of specification RRIP-1.10 rather than
|
* Write Rock Ridge info as of specification RRIP-1.10 rather than
|
||||||
* RRIP-1.12: signature "RRIP_1991A" rather than "IEEE_1282",
|
* RRIP-1.12: signature "RRIP_1991A" rather than "IEEE_1282",
|
||||||
@ -147,8 +205,6 @@ struct iso_write_opts {
|
|||||||
*/
|
*/
|
||||||
unsigned int dir_rec_mtime :1;
|
unsigned int dir_rec_mtime :1;
|
||||||
|
|
||||||
#ifdef Libisofs_with_checksumS
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compute MD5 checksum for the whole session and record it as index 0 of
|
* Compute MD5 checksum for the whole session and record it as index 0 of
|
||||||
* the checksum blocks after the data area of the session. The layout and
|
* the checksum blocks after the data area of the session. The layout and
|
||||||
@ -169,8 +225,6 @@ struct iso_write_opts {
|
|||||||
*/
|
*/
|
||||||
unsigned int md5_file_checksums :2;
|
unsigned int md5_file_checksums :2;
|
||||||
|
|
||||||
#endif /* Libisofs_with_checksumS */
|
|
||||||
|
|
||||||
/** If files should be sorted based on their weight. */
|
/** If files should be sorted based on their weight. */
|
||||||
unsigned int sort_files :1;
|
unsigned int sort_files :1;
|
||||||
|
|
||||||
@ -195,6 +249,26 @@ struct iso_write_opts {
|
|||||||
uid_t uid; /** uid to use when replace_uid == 2. */
|
uid_t uid; /** uid to use when replace_uid == 2. */
|
||||||
gid_t gid; /** gid to use when replace_gid == 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
|
* 0 to use IsoNode timestamps, 1 to use recording time, 2 to use
|
||||||
* values from timestamp field. This has only meaning if RR extensions
|
* values from timestamp field. This has only meaning if RR extensions
|
||||||
@ -297,6 +371,51 @@ struct iso_write_opts {
|
|||||||
*/
|
*/
|
||||||
char *scdbackup_tag_written;
|
char *scdbackup_tag_written;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See ecma119_image : System Area related information
|
||||||
|
*/
|
||||||
|
char *system_area_data;
|
||||||
|
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 paths of prepared images which shall be appended
|
||||||
|
after the ISO image and described by partiton table entries in a MBR
|
||||||
|
*/
|
||||||
|
char *appended_partitions[ISO_MAX_PARTITIONS];
|
||||||
|
uint8_t appended_part_types[ISO_MAX_PARTITIONS];
|
||||||
|
|
||||||
|
/* Eventual name of the non-ISO aspect of the image. E.g. SUN ASCII label.
|
||||||
|
*/
|
||||||
|
char ascii_disc_label[ISO_DISC_LABEL_SIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct ecma119_image Ecma119Image;
|
typedef struct ecma119_image Ecma119Image;
|
||||||
@ -308,9 +427,13 @@ typedef struct Iso_Image_Writer IsoImageWriter;
|
|||||||
|
|
||||||
struct ecma119_image
|
struct ecma119_image
|
||||||
{
|
{
|
||||||
|
int refcount;
|
||||||
|
|
||||||
IsoImage *image;
|
IsoImage *image;
|
||||||
Ecma119Node *root;
|
Ecma119Node *root;
|
||||||
|
|
||||||
|
int will_cancel :1;
|
||||||
|
|
||||||
unsigned int iso_level :2;
|
unsigned int iso_level :2;
|
||||||
|
|
||||||
/* extensions */
|
/* extensions */
|
||||||
@ -327,11 +450,12 @@ struct ecma119_image
|
|||||||
unsigned int always_gmt :1;
|
unsigned int always_gmt :1;
|
||||||
|
|
||||||
/* relaxed constraints */
|
/* relaxed constraints */
|
||||||
unsigned int omit_version_numbers :1;
|
unsigned int allow_dir_id_ext :1;
|
||||||
|
unsigned int omit_version_numbers :2;
|
||||||
unsigned int allow_deep_paths :1;
|
unsigned int allow_deep_paths :1;
|
||||||
unsigned int allow_longer_paths :1;
|
unsigned int allow_longer_paths :1;
|
||||||
unsigned int max_37_char_filenames :1;
|
unsigned int max_37_char_filenames :1;
|
||||||
unsigned int no_force_dots :1;
|
unsigned int no_force_dots :2;
|
||||||
unsigned int allow_lowercase :1;
|
unsigned int allow_lowercase :1;
|
||||||
unsigned int allow_full_ascii :1;
|
unsigned int allow_full_ascii :1;
|
||||||
|
|
||||||
@ -340,6 +464,9 @@ struct ecma119_image
|
|||||||
/** Allow paths on Joliet tree to be larger than 240 bytes */
|
/** Allow paths on Joliet tree to be larger than 240 bytes */
|
||||||
unsigned int joliet_longer_paths :1;
|
unsigned int joliet_longer_paths :1;
|
||||||
|
|
||||||
|
/** Allow Joliet names up to 103 characters rather than 64 */
|
||||||
|
unsigned int joliet_long_names :1;
|
||||||
|
|
||||||
/** Write old fashioned RRIP-1.10 rather than RRIP-1.12 */
|
/** Write old fashioned RRIP-1.10 rather than RRIP-1.12 */
|
||||||
unsigned int rrip_version_1_10 :1;
|
unsigned int rrip_version_1_10 :1;
|
||||||
|
|
||||||
@ -352,13 +479,9 @@ struct ecma119_image
|
|||||||
/* Store in ECMA-119 timestamp mtime of source */
|
/* Store in ECMA-119 timestamp mtime of source */
|
||||||
unsigned int dir_rec_mtime :1;
|
unsigned int dir_rec_mtime :1;
|
||||||
|
|
||||||
#ifdef Libisofs_with_checksumS
|
|
||||||
|
|
||||||
unsigned int md5_session_checksum :1;
|
unsigned int md5_session_checksum :1;
|
||||||
unsigned int md5_file_checksums :2;
|
unsigned int md5_file_checksums :2;
|
||||||
|
|
||||||
#endif /* Libisofs_with_checksumS */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mode replace. If one of these flags is set, the correspodent values are
|
* Mode replace. If one of these flags is set, the correspodent values are
|
||||||
* replaced with values below.
|
* replaced with values below.
|
||||||
@ -375,6 +498,9 @@ struct ecma119_image
|
|||||||
mode_t dir_mode;
|
mode_t dir_mode;
|
||||||
time_t timestamp;
|
time_t timestamp;
|
||||||
|
|
||||||
|
unsigned int old_empty :1;
|
||||||
|
unsigned int untranslated_name_len;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* if sort files or not. Sorting is based of the weight of each file
|
* if sort files or not. Sorting is based of the weight of each file
|
||||||
*/
|
*/
|
||||||
@ -391,8 +517,9 @@ struct ecma119_image
|
|||||||
off_t total_size;
|
off_t total_size;
|
||||||
uint32_t vol_space_size;
|
uint32_t vol_space_size;
|
||||||
|
|
||||||
/* Bytes already written, just for progress notification */
|
/* Bytes already written to image output */
|
||||||
off_t bytes_written;
|
off_t bytes_written;
|
||||||
|
/* just for progress notification */
|
||||||
int percent_written;
|
int percent_written;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -401,6 +528,17 @@ struct ecma119_image
|
|||||||
*/
|
*/
|
||||||
uint32_t curblock;
|
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,
|
* number of dirs in ECMA-119 tree, computed together with dir position,
|
||||||
* and needed for path table computation in a efficient way
|
* and needed for path table computation in a efficient way
|
||||||
@ -433,7 +571,41 @@ struct ecma119_image
|
|||||||
*/
|
*/
|
||||||
struct el_torito_boot_catalog *catalog;
|
struct el_torito_boot_catalog *catalog;
|
||||||
IsoFileSrc *cat; /**< location of the boot catalog in the new image */
|
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 */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
int system_area_options;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Number of pad blocks that we need to write. Padding blocks are blocks
|
* Number of pad blocks that we need to write. Padding blocks are blocks
|
||||||
@ -448,7 +620,7 @@ struct ecma119_image
|
|||||||
* file data is written in the first 64 KiB, that are the bytes we usually
|
* file data is written in the first 64 KiB, that are the bytes we usually
|
||||||
* overwrite.
|
* overwrite.
|
||||||
*/
|
*/
|
||||||
uint32_t pad_blocks;
|
uint32_t mspad_blocks;
|
||||||
|
|
||||||
size_t nwriters;
|
size_t nwriters;
|
||||||
IsoImageWriter **writers;
|
IsoImageWriter **writers;
|
||||||
@ -456,8 +628,6 @@ struct ecma119_image
|
|||||||
/* tree of files sources */
|
/* tree of files sources */
|
||||||
IsoRBTree *files;
|
IsoRBTree *files;
|
||||||
|
|
||||||
#ifdef Libisofs_with_checksumS
|
|
||||||
|
|
||||||
unsigned int checksum_idx_counter;
|
unsigned int checksum_idx_counter;
|
||||||
void *checksum_ctx;
|
void *checksum_ctx;
|
||||||
off_t checksum_counter;
|
off_t checksum_counter;
|
||||||
@ -483,14 +653,69 @@ struct ecma119_image
|
|||||||
char scdbackup_tag_parm[100];
|
char scdbackup_tag_parm[100];
|
||||||
char *scdbackup_tag_written;
|
char *scdbackup_tag_written;
|
||||||
|
|
||||||
#endif /* Libisofs_with_checksumS */
|
|
||||||
|
|
||||||
/* Buffer for communication between burn_source and writer thread */
|
/* Buffer for communication between burn_source and writer thread */
|
||||||
IsoRingBuffer *buffer;
|
IsoRingBuffer *buffer;
|
||||||
|
|
||||||
/* writer thread descriptor */
|
/* writer thread descriptor */
|
||||||
pthread_t wthread;
|
pthread_t wthread;
|
||||||
|
int wthread_is_running;
|
||||||
pthread_attr_t th_attr;
|
pthread_attr_t th_attr;
|
||||||
|
|
||||||
|
/* User settable PVD time stamps */
|
||||||
|
time_t vol_creation_time;
|
||||||
|
time_t vol_modification_time;
|
||||||
|
time_t vol_expiration_time;
|
||||||
|
time_t vol_effective_time;
|
||||||
|
/* To eventually override vol_creation_time and vol_modification_time
|
||||||
|
* by unconverted string with timezone 0
|
||||||
|
*/
|
||||||
|
char vol_uuid[17];
|
||||||
|
|
||||||
|
/* The number of unclaimed 2K blocks before
|
||||||
|
start of partition 1 as of the MBR in system area. */
|
||||||
|
uint32_t partition_offset;
|
||||||
|
/* Partition table parameter: 1 to 63, 0= disabled/default */
|
||||||
|
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;
|
||||||
|
|
||||||
|
#ifdef Libisofs_with_libjtE
|
||||||
|
struct libjte_env *libjte_handle;
|
||||||
|
#endif /* Libisofs_with_libjtE */
|
||||||
|
|
||||||
|
uint32_t tail_blocks;
|
||||||
|
|
||||||
|
/* Memorized ELF parameters from MIPS Little Endian boot file */
|
||||||
|
uint32_t mipsel_e_entry;
|
||||||
|
uint32_t mipsel_p_offset;
|
||||||
|
uint32_t mipsel_p_vaddr;
|
||||||
|
uint32_t mipsel_p_filesz;
|
||||||
|
|
||||||
|
char *appended_partitions[ISO_MAX_PARTITIONS];
|
||||||
|
uint8_t appended_part_types[ISO_MAX_PARTITIONS];
|
||||||
|
/* Counted in blocks of 2048 */
|
||||||
|
uint32_t appended_part_prepad[ISO_MAX_PARTITIONS];
|
||||||
|
uint32_t appended_part_start[ISO_MAX_PARTITIONS];
|
||||||
|
uint32_t appended_part_size[ISO_MAX_PARTITIONS];
|
||||||
|
|
||||||
|
char ascii_disc_label[ISO_DISC_LABEL_SIZE];
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define BP(a,b) [(b) - (a) + 1]
|
#define BP(a,b) [(b) - (a) + 1]
|
||||||
|
@ -3,10 +3,18 @@
|
|||||||
* Copyright (c) 2009 Thomas Schmitt
|
* Copyright (c) 2009 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* 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_tree.h"
|
||||||
#include "ecma119.h"
|
#include "ecma119.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
@ -24,7 +32,7 @@
|
|||||||
static
|
static
|
||||||
int get_iso_name(Ecma119Image *img, IsoNode *iso, char **name)
|
int get_iso_name(Ecma119Image *img, IsoNode *iso, char **name)
|
||||||
{
|
{
|
||||||
int ret, relaxed;
|
int ret, relaxed, free_ascii_name= 0, force_dots = 0, max_len;
|
||||||
char *ascii_name;
|
char *ascii_name;
|
||||||
char *isoname= NULL;
|
char *isoname= NULL;
|
||||||
|
|
||||||
@ -33,9 +41,16 @@ int get_iso_name(Ecma119Image *img, IsoNode *iso, char **name)
|
|||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = str2ascii(img->input_charset, iso->name, &ascii_name);
|
if (img->untranslated_name_len > 0) {
|
||||||
|
ascii_name = iso->name;
|
||||||
|
ret = 1;
|
||||||
|
} else {
|
||||||
|
ret = str2ascii(img->input_charset, iso->name, &ascii_name);
|
||||||
|
free_ascii_name = 1;
|
||||||
|
}
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
iso_msg_submit(img->image->id, ret, 0, "Can't convert %s", iso->name);
|
iso_msg_submit(img->image->id, ret, 0,
|
||||||
|
"Cannot convert name '%s' to ASCII", iso->name);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,8 +59,18 @@ int get_iso_name(Ecma119Image *img, IsoNode *iso, char **name)
|
|||||||
} else {
|
} else {
|
||||||
relaxed = (int)img->allow_lowercase;
|
relaxed = (int)img->allow_lowercase;
|
||||||
}
|
}
|
||||||
if (iso->type == LIBISO_DIR) {
|
if (iso->type == LIBISO_DIR && !(img->allow_dir_id_ext)) {
|
||||||
if (img->max_37_char_filenames) {
|
if (img->untranslated_name_len > 0) {
|
||||||
|
if (strlen(ascii_name) > img->untranslated_name_len) {
|
||||||
|
needs_transl:;
|
||||||
|
iso_msg_submit(img->image->id, ISO_NAME_NEEDS_TRANSL, 0,
|
||||||
|
"File name too long (%d > %d) for untranslated recording: '%s'",
|
||||||
|
strlen(ascii_name), img->untranslated_name_len,
|
||||||
|
ascii_name);
|
||||||
|
return ISO_NAME_NEEDS_TRANSL;
|
||||||
|
}
|
||||||
|
isoname = strdup(ascii_name);
|
||||||
|
} else if (img->max_37_char_filenames) {
|
||||||
isoname = iso_r_dirid(ascii_name, 37, relaxed);
|
isoname = iso_r_dirid(ascii_name, 37, relaxed);
|
||||||
} else if (img->iso_level == 1) {
|
} else if (img->iso_level == 1) {
|
||||||
if (relaxed) {
|
if (relaxed) {
|
||||||
@ -55,32 +80,40 @@ int get_iso_name(Ecma119Image *img, IsoNode *iso, char **name)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (relaxed) {
|
if (relaxed) {
|
||||||
isoname = iso_r_dirid(ascii_name, 8, relaxed);
|
isoname = iso_r_dirid(ascii_name, 31, relaxed);
|
||||||
} else {
|
} else {
|
||||||
isoname = iso_2_dirid(ascii_name);
|
isoname = iso_2_dirid(ascii_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (img->max_37_char_filenames) {
|
force_dots = !((img->no_force_dots & 1) || iso->type == LIBISO_DIR);
|
||||||
isoname = iso_r_fileid(ascii_name, 36, relaxed,
|
if (img->untranslated_name_len > 0) {
|
||||||
img->no_force_dots ? 0 : 1);
|
if (strlen(ascii_name) > img->untranslated_name_len)
|
||||||
|
goto needs_transl;
|
||||||
|
isoname = strdup(ascii_name);
|
||||||
|
} else if (img->max_37_char_filenames) {
|
||||||
|
isoname = iso_r_fileid(ascii_name, 36, relaxed, force_dots);
|
||||||
} else if (img->iso_level == 1) {
|
} else if (img->iso_level == 1) {
|
||||||
if (relaxed) {
|
if (relaxed || !force_dots) {
|
||||||
isoname = iso_r_fileid(ascii_name, 11, relaxed,
|
if (strchr(ascii_name, '.') == NULL)
|
||||||
img->no_force_dots ? 0 : 1);
|
max_len = 8;
|
||||||
|
else
|
||||||
|
max_len = 11;
|
||||||
|
isoname = iso_r_fileid(ascii_name, max_len, relaxed,
|
||||||
|
force_dots);
|
||||||
} else {
|
} else {
|
||||||
isoname = iso_1_fileid(ascii_name);
|
isoname = iso_1_fileid(ascii_name);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (relaxed) {
|
if (relaxed || !force_dots) {
|
||||||
isoname = iso_r_fileid(ascii_name, 30, relaxed,
|
isoname = iso_r_fileid(ascii_name, 30, relaxed, force_dots);
|
||||||
img->no_force_dots ? 0 : 1);
|
|
||||||
} else {
|
} else {
|
||||||
isoname = iso_2_fileid(ascii_name);
|
isoname = iso_2_fileid(ascii_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(ascii_name);
|
if (free_ascii_name)
|
||||||
|
free(ascii_name);
|
||||||
if (isoname != NULL) {
|
if (isoname != NULL) {
|
||||||
*name = isoname;
|
*name = isoname;
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
@ -145,15 +178,11 @@ int create_dir(Ecma119Image *img, IsoDir *iso, Ecma119Node **node)
|
|||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new ECMA-119 node representing a regular file from a iso file
|
|
||||||
* node.
|
|
||||||
*/
|
|
||||||
static
|
static
|
||||||
int create_file(Ecma119Image *img, IsoFile *iso, Ecma119Node **node)
|
int create_file_src(Ecma119Image *img, IsoFile *iso, IsoFileSrc **src)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
IsoFileSrc *src;
|
|
||||||
off_t size;
|
off_t size;
|
||||||
|
|
||||||
size = iso_stream_get_size(iso->stream);
|
size = iso_stream_get_size(iso->stream);
|
||||||
@ -165,8 +194,25 @@ int create_file(Ecma119Image *img, IsoFile *iso, Ecma119Node **node)
|
|||||||
free(ipath);
|
free(ipath);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
ret = iso_file_src_create(img, iso, src);
|
||||||
|
if (ret < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
ret = iso_file_src_create(img, iso, &src);
|
|
||||||
|
/**
|
||||||
|
* Create a new ECMA-119 node representing a regular file from a iso file
|
||||||
|
* node.
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
int create_file(Ecma119Image *img, IsoFile *iso, Ecma119Node **node)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
IsoFileSrc *src;
|
||||||
|
|
||||||
|
ret = create_file_src(img, iso, &src);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -266,58 +312,78 @@ void ecma119_node_free(Ecma119Node *node)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* @param flag
|
||||||
|
* bit0= iso is in a hidden directory. Thus hide it.
|
||||||
* @return
|
* @return
|
||||||
* 1 success, 0 node ignored, < 0 error
|
* 1 success, 0 node ignored, < 0 error
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static
|
static
|
||||||
int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree,
|
int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree,
|
||||||
int depth, int pathlen)
|
int depth, int pathlen, int flag)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret, hidden;
|
||||||
Ecma119Node *node;
|
Ecma119Node *node = NULL;
|
||||||
int max_path;
|
int max_path;
|
||||||
char *iso_name= NULL;
|
char *iso_name= NULL, *ipath = NULL;
|
||||||
|
IsoFileSrc *src = NULL;
|
||||||
|
|
||||||
if (image == NULL || iso == NULL || tree == NULL) {
|
if (image == NULL || iso == NULL || tree == NULL) {
|
||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
}
|
}
|
||||||
|
*tree = NULL;
|
||||||
|
|
||||||
|
hidden = flag & 1;
|
||||||
if (iso->hidden & LIBISO_HIDE_ON_RR) {
|
if (iso->hidden & LIBISO_HIDE_ON_RR) {
|
||||||
/* file will be ignored */
|
hidden = 1;
|
||||||
return 0;
|
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) {
|
if (hidden) {
|
||||||
return ret;
|
max_path= pathlen;
|
||||||
}
|
} else {
|
||||||
max_path = pathlen + 1 + (iso_name ? strlen(iso_name) : 0);
|
ret = get_iso_name(image, iso, &iso_name);
|
||||||
if (!image->rockridge) {
|
if (ret < 0) {
|
||||||
if ((iso->type == LIBISO_DIR && depth > 8) && !image->allow_deep_paths) {
|
iso_name = NULL; /* invalid, do not free */
|
||||||
char *ipath = iso_tree_get_node_path(iso);
|
goto ex;
|
||||||
return iso_msg_submit(image->image->id, ISO_FILE_IMGPATH_WRONG, 0,
|
}
|
||||||
"File \"%s\" can't be added, because directory depth "
|
max_path = pathlen + 1 + (iso_name ? strlen(iso_name) : 0);
|
||||||
"is greater than 8.", ipath);
|
if (!image->rockridge) {
|
||||||
free(iso_name);
|
if ((iso->type == LIBISO_DIR && depth > 8) &&
|
||||||
free(ipath);
|
!image->allow_deep_paths) {
|
||||||
return ret;
|
ipath = iso_tree_get_node_path(iso);
|
||||||
} else if (max_path > 255 && !image->allow_longer_paths) {
|
ret = iso_msg_submit(image->image->id, ISO_FILE_IMGPATH_WRONG,
|
||||||
char *ipath = iso_tree_get_node_path(iso);
|
0, "File \"%s\" can't be added, "
|
||||||
ret = iso_msg_submit(image->image->id, ISO_FILE_IMGPATH_WRONG, 0,
|
"because directory depth "
|
||||||
"File \"%s\" can't be added, because path length "
|
"is greater than 8.", ipath);
|
||||||
"is greater than 255 characters", ipath);
|
goto ex;
|
||||||
free(iso_name);
|
} else if (max_path > 255 && !image->allow_longer_paths) {
|
||||||
free(ipath);
|
ipath = iso_tree_get_node_path(iso);
|
||||||
return ret;
|
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) {
|
switch (iso->type) {
|
||||||
case LIBISO_FILE:
|
case LIBISO_FILE:
|
||||||
ret = create_file(image, (IsoFile*)iso, &node);
|
if (hidden) {
|
||||||
|
ret = create_file_src(image, (IsoFile *) iso, &src);
|
||||||
|
} else {
|
||||||
|
ret = create_file(image, (IsoFile*)iso, &node);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case LIBISO_SYMLINK:
|
case LIBISO_SYMLINK:
|
||||||
|
if (hidden) {
|
||||||
|
ret = 0; /* Hidden means non-existing */
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
if (image->rockridge) {
|
if (image->rockridge) {
|
||||||
ret = create_symlink(image, (IsoSymlink*)iso, &node);
|
ret = create_symlink(image, (IsoSymlink*)iso, &node);
|
||||||
} else {
|
} else {
|
||||||
@ -330,6 +396,10 @@ int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case LIBISO_SPECIAL:
|
case LIBISO_SPECIAL:
|
||||||
|
if (hidden) {
|
||||||
|
ret = 0; /* Hidden means non-existing */
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
if (image->rockridge) {
|
if (image->rockridge) {
|
||||||
ret = create_special(image, (IsoSpecial*)iso, &node);
|
ret = create_special(image, (IsoSpecial*)iso, &node);
|
||||||
} else {
|
} else {
|
||||||
@ -343,7 +413,11 @@ int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree,
|
|||||||
break;
|
break;
|
||||||
case LIBISO_BOOT:
|
case LIBISO_BOOT:
|
||||||
if (image->eltorito) {
|
if (image->eltorito) {
|
||||||
ret = create_boot_cat(image, (IsoBoot*)iso, &node);
|
if (hidden) {
|
||||||
|
ret = el_torito_catalog_file_src_create(image, &src);
|
||||||
|
} else {
|
||||||
|
ret = create_boot_cat(image, (IsoBoot*)iso, &node);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* log and ignore */
|
/* log and ignore */
|
||||||
ret = iso_msg_submit(image->image->id, ISO_FILE_IGNORED, 0,
|
ret = iso_msg_submit(image->image->id, ISO_FILE_IGNORED, 0,
|
||||||
@ -354,21 +428,25 @@ int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree,
|
|||||||
{
|
{
|
||||||
IsoNode *pos;
|
IsoNode *pos;
|
||||||
IsoDir *dir = (IsoDir*)iso;
|
IsoDir *dir = (IsoDir*)iso;
|
||||||
ret = create_dir(image, dir, &node);
|
|
||||||
if (ret < 0) {
|
if (!hidden) {
|
||||||
return ret;
|
ret = create_dir(image, dir, &node);
|
||||||
|
if (ret < 0) {
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
ret = ISO_SUCCESS;
|
||||||
pos = dir->children;
|
pos = dir->children;
|
||||||
while (pos) {
|
while (pos) {
|
||||||
int cret;
|
int cret;
|
||||||
Ecma119Node *child;
|
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) {
|
if (cret < 0) {
|
||||||
/* error */
|
/* error */
|
||||||
ecma119_node_free(node);
|
|
||||||
ret = cret;
|
ret = cret;
|
||||||
break;
|
break;
|
||||||
} else if (cret == ISO_SUCCESS) {
|
} else if (cret == ISO_SUCCESS && !hidden) {
|
||||||
/* add child to this node */
|
/* add child to this node */
|
||||||
int nchildren = node->info.dir->nchildren++;
|
int nchildren = node->info.dir->nchildren++;
|
||||||
node->info.dir->children[nchildren] = child;
|
node->info.dir->children[nchildren] = child;
|
||||||
@ -380,15 +458,30 @@ int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree,
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* should never happen */
|
/* should never happen */
|
||||||
return ISO_ASSERT_FAILURE;
|
ret = ISO_ASSERT_FAILURE;
|
||||||
|
goto ex;
|
||||||
}
|
}
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
free(iso_name);
|
goto ex;
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
node->iso_name = iso_name;
|
if (!hidden) {
|
||||||
*tree = node;
|
node->iso_name = iso_name;
|
||||||
return ISO_SUCCESS;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -470,6 +563,18 @@ int mangle_single_dir(Ecma119Image *img, Ecma119Node *dir, int max_file_len,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (img->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 enought, it allows handling up to
|
||||||
* 9,999,999 files with same name. We can increment this to
|
* 9,999,999 files with same name. We can increment this to
|
||||||
@ -486,10 +591,11 @@ int mangle_single_dir(Ecma119Image *img, Ecma119Node *dir, int max_file_len,
|
|||||||
|
|
||||||
/* compute name and extension */
|
/* compute name and extension */
|
||||||
dot = strrchr(full_name, '.');
|
dot = strrchr(full_name, '.');
|
||||||
if (dot != NULL && children[i]->type != ECMA119_DIR) {
|
if (dot != NULL &&
|
||||||
|
(children[i]->type != ECMA119_DIR || img->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
|
* Note that we don't need to check for placeholders, as
|
||||||
* tree reparent happens later, so no placeholders can be
|
* tree reparent happens later, so no placeholders can be
|
||||||
* here at this time.
|
* here at this time.
|
||||||
@ -529,10 +635,10 @@ int mangle_single_dir(Ecma119Image *img, Ecma119Node *dir, int max_file_len,
|
|||||||
name[max] = '\0';
|
name[max] = '\0';
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Directory, or file without extension */
|
/* Directory (normally), or file without extension */
|
||||||
if (children[i]->type == ECMA119_DIR) {
|
if (children[i]->type == ECMA119_DIR) {
|
||||||
max = max_dir_len - digits;
|
max = max_dir_len - digits;
|
||||||
dot = NULL; /* dots have no meaning in dirs */
|
dot = NULL; /* dots (normally) have no meaning in dirs */
|
||||||
} else {
|
} else {
|
||||||
max = max_file_len - digits;
|
max = max_file_len - digits;
|
||||||
}
|
}
|
||||||
@ -647,8 +753,11 @@ static
|
|||||||
int mangle_tree(Ecma119Image *img, int recurse)
|
int mangle_tree(Ecma119Image *img, int recurse)
|
||||||
{
|
{
|
||||||
int max_file, max_dir;
|
int max_file, max_dir;
|
||||||
|
Ecma119Node *root;
|
||||||
|
|
||||||
if (img->max_37_char_filenames) {
|
if (img->untranslated_name_len > 0) {
|
||||||
|
max_file = max_dir = img->untranslated_name_len;
|
||||||
|
} else if (img->max_37_char_filenames) {
|
||||||
max_file = max_dir = 37;
|
max_file = max_dir = 37;
|
||||||
} else if (img->iso_level == 1) {
|
} else if (img->iso_level == 1) {
|
||||||
max_file = 12; /* 8 + 3 + 1 */
|
max_file = 12; /* 8 + 3 + 1 */
|
||||||
@ -656,10 +765,15 @@ int mangle_tree(Ecma119Image *img, int recurse)
|
|||||||
} else {
|
} else {
|
||||||
max_file = max_dir = 31;
|
max_file = max_dir = 31;
|
||||||
}
|
}
|
||||||
if (recurse) {
|
if (img->eff_partition_offset > 0) {
|
||||||
return mangle_dir(img, img->root, max_file, max_dir);
|
root = img->partition_root;
|
||||||
} else {
|
} 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -777,11 +891,17 @@ int reorder_tree(Ecma119Image *img, Ecma119Node *dir, int level, int pathlen)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
size_t max_path;
|
size_t max_path;
|
||||||
|
Ecma119Node *root;
|
||||||
|
|
||||||
max_path = pathlen + 1 + max_child_name_len(dir);
|
max_path = pathlen + 1 + max_child_name_len(dir);
|
||||||
|
|
||||||
if (level > 8 || max_path > 255) {
|
if (level > 8 || max_path > 255) {
|
||||||
ret = reparent(dir, img->root);
|
if (img->eff_partition_offset > 0) {
|
||||||
|
root = img->partition_root;
|
||||||
|
} else {
|
||||||
|
root = img->root;
|
||||||
|
}
|
||||||
|
ret = reparent(dir, root);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -954,11 +1074,12 @@ int match_hardlinks(Ecma119Image *img, Ecma119Node *dir, int flag)
|
|||||||
iso_node_get_id(nodes[0]->node, &fs_id, &dev_id, &img_ino, 1);
|
iso_node_get_id(nodes[0]->node, &fs_id, &dev_id, &img_ino, 1);
|
||||||
family_start = 0;
|
family_start = 0;
|
||||||
for (i = 1; i < node_count; i++) {
|
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 */
|
/* Still in same ino family */
|
||||||
if (img_ino == 0) { /* Just in case any member knows its img_ino */
|
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);
|
iso_node_get_id(nodes[0]->node, &fs_id, &dev_id, &img_ino, 1);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
family_set_ino(img, nodes, family_start, i, img_ino, prev_ino, 0);
|
family_set_ino(img, nodes, family_start, i, img_ino, prev_ino, 0);
|
||||||
@ -980,7 +1101,7 @@ int ecma119_tree_create(Ecma119Image *img)
|
|||||||
int ret;
|
int ret;
|
||||||
Ecma119Node *root;
|
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) {
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
/* unexpected error, root ignored!! This can't happen */
|
/* unexpected error, root ignored!! This can't happen */
|
||||||
@ -988,10 +1109,14 @@ int ecma119_tree_create(Ecma119Image *img)
|
|||||||
}
|
}
|
||||||
return ret;
|
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...");
|
iso_msg_debug(img->image->id, "Matching hardlinks...");
|
||||||
ret = match_hardlinks(img, img->root, 0);
|
ret = match_hardlinks(img, root, 0);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -1008,7 +1133,7 @@ int ecma119_tree_create(Ecma119Image *img)
|
|||||||
if (img->rockridge && !img->allow_deep_paths) {
|
if (img->rockridge && !img->allow_deep_paths) {
|
||||||
|
|
||||||
/* reorder the tree, acording to RRIP, 4.1.5 */
|
/* reorder the tree, acording to RRIP, 4.1.5 */
|
||||||
ret = reorder_tree(img, img->root, 1, 0);
|
ret = reorder_tree(img, root, 1, 0);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -1026,3 +1151,35 @@ int ecma119_tree_create(Ecma119Image *img)
|
|||||||
|
|
||||||
return ISO_SUCCESS;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -2,8 +2,9 @@
|
|||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef LIBISO_ECMA119_TREE_H_
|
#ifndef LIBISO_ECMA119_TREE_H_
|
||||||
@ -89,4 +90,11 @@ int ecma119_tree_create(Ecma119Image *img);
|
|||||||
*/
|
*/
|
||||||
void ecma119_node_free(Ecma119Node *node);
|
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);
|
||||||
|
|
||||||
|
|
||||||
#endif /*LIBISO_ECMA119_TREE_H_*/
|
#endif /*LIBISO_ECMA119_TREE_H_*/
|
||||||
|
@ -1,13 +1,19 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
|
* Copyright (c) 2010 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "libisofs.h"
|
||||||
#include "eltorito.h"
|
#include "eltorito.h"
|
||||||
#include "stream.h"
|
|
||||||
#include "fsource.h"
|
#include "fsource.h"
|
||||||
#include "filesrc.h"
|
#include "filesrc.h"
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
@ -16,9 +22,10 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This table should be written with accuracy values at offset
|
* This table should be written with the actual values at offset
|
||||||
* 8 of boot image, when used ISOLINUX boot loader
|
* 8 of boot image, when used ISOLINUX boot loader
|
||||||
*/
|
*/
|
||||||
struct boot_info_table {
|
struct boot_info_table {
|
||||||
@ -54,6 +61,19 @@ struct hard_disc_mbr {
|
|||||||
uint8_t sign2;
|
uint8_t sign2;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* API */
|
||||||
|
int el_torito_set_boot_platform_id(ElToritoBootImage *bootimg, uint8_t id)
|
||||||
|
{
|
||||||
|
bootimg->platform_id = id;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* API */
|
||||||
|
int el_torito_get_boot_platform_id(ElToritoBootImage *bootimg)
|
||||||
|
{
|
||||||
|
return bootimg->platform_id;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the load segment for the initial boot image. This is only for
|
* Sets the load segment for the initial boot image. This is only for
|
||||||
* no emulation boot images, and is a NOP for other image types.
|
* no emulation boot images, and is a NOP for other image types.
|
||||||
@ -65,6 +85,14 @@ void el_torito_set_load_seg(ElToritoBootImage *bootimg, short segment)
|
|||||||
bootimg->load_seg = segment;
|
bootimg->load_seg = segment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* API */
|
||||||
|
int el_torito_get_load_seg(ElToritoBootImage *bootimg)
|
||||||
|
{
|
||||||
|
if (bootimg->load_seg < 0)
|
||||||
|
return 0xffff - bootimg->load_seg;
|
||||||
|
return bootimg->load_seg;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the number of sectors (512b) to be load at load segment during
|
* Sets the number of sectors (512b) to be load at load segment during
|
||||||
* the initial boot procedure. This is only for no emulation boot images,
|
* the initial boot procedure. This is only for no emulation boot images,
|
||||||
@ -77,6 +105,14 @@ void el_torito_set_load_size(ElToritoBootImage *bootimg, short sectors)
|
|||||||
bootimg->load_size = sectors;
|
bootimg->load_size = sectors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* API */
|
||||||
|
int el_torito_get_load_size(ElToritoBootImage *bootimg)
|
||||||
|
{
|
||||||
|
if (bootimg->load_size < 0)
|
||||||
|
return 0xffff - bootimg->load_size;
|
||||||
|
return bootimg->load_size;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Marks the specified boot image as not bootable
|
* Marks the specified boot image as not bootable
|
||||||
*/
|
*/
|
||||||
@ -85,8 +121,50 @@ void el_torito_set_no_bootable(ElToritoBootImage *bootimg)
|
|||||||
bootimg->bootable = 0;
|
bootimg->bootable = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* API */
|
||||||
|
int el_torito_get_bootable(ElToritoBootImage *bootimg)
|
||||||
|
{
|
||||||
|
return !!bootimg->bootable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* API */
|
||||||
|
int el_torito_set_id_string(ElToritoBootImage *bootimg, uint8_t id_string[28])
|
||||||
|
{
|
||||||
|
memcpy(bootimg->id_string, id_string, 28);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* API */
|
||||||
|
int el_torito_get_id_string(ElToritoBootImage *bootimg, uint8_t id_string[28])
|
||||||
|
{
|
||||||
|
|
||||||
|
memcpy(id_string, bootimg->id_string, 28);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* API */
|
||||||
|
int el_torito_set_selection_crit(ElToritoBootImage *bootimg, uint8_t crit[20])
|
||||||
|
{
|
||||||
|
memcpy(bootimg->selection_crit, crit, 20);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* API */
|
||||||
|
int el_torito_get_selection_crit(ElToritoBootImage *bootimg, uint8_t crit[20])
|
||||||
|
{
|
||||||
|
|
||||||
|
memcpy(crit, bootimg->selection_crit, 20);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* API */
|
||||||
|
int el_torito_seems_boot_info_table(ElToritoBootImage *bootimg, int flag)
|
||||||
|
{
|
||||||
|
return bootimg->seems_boot_info_table;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies that this image needs to be patched. This involves the writting
|
* Specifies that this image needs to be patched. This involves the writing
|
||||||
* of a 56 bytes boot information table at offset 8 of the boot image file.
|
* of a 56 bytes boot information table at offset 8 of the boot image file.
|
||||||
* The original boot image file won't be modified.
|
* The original boot image file won't be modified.
|
||||||
* This is needed for isolinux boot images.
|
* This is needed for isolinux boot images.
|
||||||
@ -105,7 +183,7 @@ void el_torito_patch_isolinux_image(ElToritoBootImage *bootimg)
|
|||||||
* bitmask style flag. The following values are defined:
|
* bitmask style flag. The following values are defined:
|
||||||
*
|
*
|
||||||
* bit 0 -> 1 to path the image, 0 to not
|
* bit 0 -> 1 to path the image, 0 to not
|
||||||
* Patching the image involves the writting of a 56 bytes
|
* Patching the image involves the writing of a 56 bytes
|
||||||
* boot information table at offset 8 of the boot image file.
|
* boot information table at offset 8 of the boot image file.
|
||||||
* The original boot image file won't be modified. This is needed
|
* The original boot image file won't be modified. This is needed
|
||||||
* to allow isolinux images to be bootable.
|
* to allow isolinux images to be bootable.
|
||||||
@ -123,31 +201,36 @@ int el_torito_set_isolinux_options(ElToritoBootImage *bootimg, int options, int
|
|||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO getter for boot image properties should be exposed
|
/* API */
|
||||||
* useful when reading discs */
|
int el_torito_get_isolinux_options(ElToritoBootImage *bootimg, int flag)
|
||||||
int el_torito_get_boot_media_type(const ElToritoBootImage *bootimg)
|
{
|
||||||
|
return bootimg->isolinux_options & 0x03;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* API */
|
||||||
|
int el_torito_get_boot_media_type(ElToritoBootImage *bootimg,
|
||||||
|
enum eltorito_boot_media_type *media_type)
|
||||||
{
|
{
|
||||||
if (bootimg) {
|
if (bootimg) {
|
||||||
switch (bootimg->type) {
|
switch (bootimg->type) {
|
||||||
case 1:
|
case 1:
|
||||||
case 2:
|
case 2:
|
||||||
case 3:
|
case 3:
|
||||||
return ELTORITO_FLOPPY_EMUL;
|
*media_type = ELTORITO_FLOPPY_EMUL;
|
||||||
break;
|
return 1;
|
||||||
case 4:
|
case 4:
|
||||||
return ELTORITO_HARD_DISC_EMUL;
|
*media_type = ELTORITO_HARD_DISC_EMUL;
|
||||||
break;
|
return 1;
|
||||||
case 0:
|
case 0:
|
||||||
return ELTORITO_NO_EMUL;
|
*media_type = ELTORITO_NO_EMUL;
|
||||||
break;
|
return 1;
|
||||||
default:
|
default:
|
||||||
/* should never happen */
|
/* should never happen */
|
||||||
return ISO_ASSERT_FAILURE;
|
return ISO_ASSERT_FAILURE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
return ISO_WRONG_ARG_VALUE;
|
|
||||||
}
|
}
|
||||||
|
return ISO_WRONG_ARG_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
@ -156,6 +239,7 @@ int iso_tree_add_boot_node(IsoDir *parent, const char *name, IsoBoot **boot)
|
|||||||
IsoBoot *node;
|
IsoBoot *node;
|
||||||
IsoNode **pos;
|
IsoNode **pos;
|
||||||
time_t now;
|
time_t now;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (parent == NULL || name == NULL || boot == NULL) {
|
if (parent == NULL || name == NULL || boot == NULL) {
|
||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
@ -165,9 +249,9 @@ int iso_tree_add_boot_node(IsoDir *parent, const char *name, IsoBoot **boot)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* check if the name is valid */
|
/* check if the name is valid */
|
||||||
if (!iso_node_is_valid_name(name)) {
|
ret = iso_node_is_valid_name(name);
|
||||||
return ISO_WRONG_ARG_VALUE;
|
if (ret < 0)
|
||||||
}
|
return ret;
|
||||||
|
|
||||||
/* find place where to insert */
|
/* find place where to insert */
|
||||||
pos = &(parent->children);
|
pos = &(parent->children);
|
||||||
@ -226,6 +310,7 @@ int create_image(IsoImage *image, const char *image_path,
|
|||||||
int boot_media_type = 0;
|
int boot_media_type = 0;
|
||||||
int load_sectors = 0; /* number of sector to load */
|
int load_sectors = 0; /* number of sector to load */
|
||||||
unsigned char partition_type = 0;
|
unsigned char partition_type = 0;
|
||||||
|
off_t size;
|
||||||
IsoNode *imgfile;
|
IsoNode *imgfile;
|
||||||
IsoStream *stream;
|
IsoStream *stream;
|
||||||
|
|
||||||
@ -234,6 +319,9 @@ int create_image(IsoImage *image, const char *image_path,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
|
iso_msg_submit(image->id, ISO_NODE_DOESNT_EXIST, 0,
|
||||||
|
"El Torito boot image file missing in ISO image: '%s'",
|
||||||
|
image_path);
|
||||||
return ISO_NODE_DOESNT_EXIST;
|
return ISO_NODE_DOESNT_EXIST;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,9 +336,16 @@ int create_image(IsoImage *image, const char *image_path,
|
|||||||
return ISO_BOOT_IMAGE_NOT_VALID;
|
return ISO_BOOT_IMAGE_NOT_VALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size = iso_stream_get_size(stream);
|
||||||
|
if (size <= 0) {
|
||||||
|
iso_msg_submit(image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
|
||||||
|
"Boot image file is empty");
|
||||||
|
return ISO_BOOT_IMAGE_NOT_VALID;
|
||||||
|
}
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ELTORITO_FLOPPY_EMUL:
|
case ELTORITO_FLOPPY_EMUL:
|
||||||
switch (iso_stream_get_size(stream)) {
|
switch (size) {
|
||||||
case 1200 * 1024:
|
case 1200 * 1024:
|
||||||
boot_media_type = 1; /* 1.2 meg diskette */
|
boot_media_type = 1; /* 1.2 meg diskette */
|
||||||
break;
|
break;
|
||||||
@ -332,10 +427,15 @@ int create_image(IsoImage *image, const char *image_path,
|
|||||||
boot->image = (IsoFile*)imgfile;
|
boot->image = (IsoFile*)imgfile;
|
||||||
iso_node_ref(imgfile); /* get our ref */
|
iso_node_ref(imgfile); /* get our ref */
|
||||||
boot->bootable = 1;
|
boot->bootable = 1;
|
||||||
|
boot->seems_boot_info_table = 0;
|
||||||
|
boot->isolinux_options = 0;
|
||||||
boot->type = boot_media_type;
|
boot->type = boot_media_type;
|
||||||
boot->load_size = load_sectors;
|
|
||||||
boot->partition_type = partition_type;
|
boot->partition_type = partition_type;
|
||||||
|
boot->load_seg = 0;
|
||||||
|
boot->load_size = load_sectors;
|
||||||
|
boot->platform_id = 0; /* 80x86 */
|
||||||
|
memset(boot->id_string, 0, sizeof(boot->id_string));
|
||||||
|
memset(boot->selection_crit, 0, sizeof(boot->selection_crit));
|
||||||
if (bootimg) {
|
if (bootimg) {
|
||||||
*bootimg = boot;
|
*bootimg = boot;
|
||||||
}
|
}
|
||||||
@ -348,7 +448,7 @@ int iso_image_set_boot_image(IsoImage *image, const char *image_path,
|
|||||||
const char *catalog_path,
|
const char *catalog_path,
|
||||||
ElToritoBootImage **boot)
|
ElToritoBootImage **boot)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret, i;
|
||||||
struct el_torito_boot_catalog *catalog;
|
struct el_torito_boot_catalog *catalog;
|
||||||
ElToritoBootImage *boot_image= NULL;
|
ElToritoBootImage *boot_image= NULL;
|
||||||
IsoBoot *cat_node= NULL;
|
IsoBoot *cat_node= NULL;
|
||||||
@ -383,6 +483,9 @@ int iso_image_set_boot_image(IsoImage *image, const char *image_path,
|
|||||||
catname[0] = '\0';
|
catname[0] = '\0';
|
||||||
ret = iso_tree_path_to_node(image, catdir, &p);
|
ret = iso_tree_path_to_node(image, catdir, &p);
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
|
iso_msg_submit(image->id, ISO_NODE_DOESNT_EXIST, 0,
|
||||||
|
"Cannot find directory for El Torito boot catalog in ISO image: '%s'",
|
||||||
|
catdir);
|
||||||
free(catdir);
|
free(catdir);
|
||||||
return ret < 0 ? ret : ISO_NODE_DOESNT_EXIST;
|
return ret < 0 ? ret : ISO_NODE_DOESNT_EXIST;
|
||||||
}
|
}
|
||||||
@ -407,13 +510,17 @@ int iso_image_set_boot_image(IsoImage *image, const char *image_path,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* creates the catalog with the given image */
|
/* creates the catalog with the given image */
|
||||||
catalog = malloc(sizeof(struct el_torito_boot_catalog));
|
catalog = calloc(1, sizeof(struct el_torito_boot_catalog));
|
||||||
if (catalog == NULL) {
|
if (catalog == NULL) {
|
||||||
ret = ISO_OUT_OF_MEM;
|
ret = ISO_OUT_OF_MEM;
|
||||||
goto boot_image_cleanup;
|
goto boot_image_cleanup;
|
||||||
}
|
}
|
||||||
catalog->image = boot_image;
|
catalog->num_bootimages = 1;
|
||||||
|
catalog->bootimages[0] = boot_image;
|
||||||
|
for (i = 1; i < Libisofs_max_boot_imageS; i++)
|
||||||
|
catalog->bootimages[i] = NULL;
|
||||||
catalog->node = cat_node;
|
catalog->node = cat_node;
|
||||||
|
catalog->sort_weight = 1000; /* slightly high */
|
||||||
iso_node_ref((IsoNode*)cat_node);
|
iso_node_ref((IsoNode*)cat_node);
|
||||||
image->bootcat = catalog;
|
image->bootcat = catalog;
|
||||||
|
|
||||||
@ -436,7 +543,7 @@ boot_image_cleanup:;
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get El-Torito boot image of an ISO image, if any.
|
* Get the boot catalog and the El-Torito default boot image of an ISO image.
|
||||||
*
|
*
|
||||||
* This can be useful, for example, to check if a volume read from a previous
|
* This can be useful, for example, to check if a volume read from a previous
|
||||||
* session or an existing image is bootable. It can also be useful to get
|
* session or an existing image is bootable. It can also be useful to get
|
||||||
@ -480,10 +587,10 @@ int iso_image_get_boot_image(IsoImage *image, ElToritoBootImage **boot,
|
|||||||
|
|
||||||
/* ok, image is bootable */
|
/* ok, image is bootable */
|
||||||
if (boot) {
|
if (boot) {
|
||||||
*boot = image->bootcat->image;
|
*boot = image->bootcat->bootimages[0];
|
||||||
}
|
}
|
||||||
if (imgnode) {
|
if (imgnode) {
|
||||||
*imgnode = image->bootcat->image->image;
|
*imgnode = image->bootcat->bootimages[0]->image;
|
||||||
}
|
}
|
||||||
if (catnode) {
|
if (catnode) {
|
||||||
*catnode = image->bootcat->node;
|
*catnode = image->bootcat->node;
|
||||||
@ -491,6 +598,40 @@ int iso_image_get_boot_image(IsoImage *image, ElToritoBootImage **boot,
|
|||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int iso_image_get_all_boot_imgs(IsoImage *image, int *num_boots,
|
||||||
|
ElToritoBootImage ***boots, IsoFile ***bootnodes, int flag)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
struct el_torito_boot_catalog *cat;
|
||||||
|
|
||||||
|
if (image == NULL)
|
||||||
|
return ISO_NULL_POINTER;
|
||||||
|
if (image->bootcat == NULL)
|
||||||
|
return 0;
|
||||||
|
cat = image->bootcat;
|
||||||
|
*num_boots = cat->num_bootimages;
|
||||||
|
*boots = NULL;
|
||||||
|
*bootnodes = NULL;
|
||||||
|
if (*num_boots <= 0)
|
||||||
|
return 0;
|
||||||
|
*boots = calloc(*num_boots, sizeof(ElToritoBootImage *));
|
||||||
|
*bootnodes = calloc(*num_boots, sizeof(IsoFile *));
|
||||||
|
if(*boots == NULL || *bootnodes == NULL) {
|
||||||
|
if (*boots != NULL)
|
||||||
|
free(*boots);
|
||||||
|
if (*bootnodes != NULL)
|
||||||
|
free(*bootnodes);
|
||||||
|
*boots = NULL;
|
||||||
|
*bootnodes = NULL;
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
}
|
||||||
|
for (i = 0; i < *num_boots; i++) {
|
||||||
|
(*boots)[i] = cat->bootimages[i];
|
||||||
|
(*bootnodes)[i] = image->bootcat->bootimages[i]->image;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes the El-Torito bootable image.
|
* Removes the El-Torito bootable image.
|
||||||
*
|
*
|
||||||
@ -505,28 +646,82 @@ void iso_image_remove_boot_image(IsoImage *image)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* remove catalog node from its parent
|
* remove catalog node from its parent and dispose it
|
||||||
* (the reference will be disposed next)
|
* (another reference is with the catalog)
|
||||||
*/
|
*/
|
||||||
iso_node_take((IsoNode*)image->bootcat->node);
|
if (iso_node_get_parent((IsoNode*) image->bootcat->node) != NULL) {
|
||||||
|
iso_node_take((IsoNode*) image->bootcat->node);
|
||||||
|
iso_node_unref((IsoNode*) image->bootcat->node);
|
||||||
|
}
|
||||||
|
|
||||||
/* free boot catalog and image, including references to nodes */
|
/* free boot catalog and image, including references to nodes */
|
||||||
el_torito_boot_catalog_free(image->bootcat);
|
el_torito_boot_catalog_free(image->bootcat);
|
||||||
image->bootcat = NULL;
|
image->bootcat = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* API */
|
||||||
|
int iso_image_add_boot_image(IsoImage *image, const char *image_path,
|
||||||
|
enum eltorito_boot_media_type type, int flag,
|
||||||
|
ElToritoBootImage **boot)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct el_torito_boot_catalog *catalog = image->bootcat;
|
||||||
|
ElToritoBootImage *boot_img;
|
||||||
|
|
||||||
|
if(catalog == NULL)
|
||||||
|
return ISO_BOOT_NO_CATALOG;
|
||||||
|
if (catalog->num_bootimages >= Libisofs_max_boot_imageS)
|
||||||
|
return ISO_BOOT_IMAGE_OVERFLOW;
|
||||||
|
ret = create_image(image, image_path, type, &boot_img);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
catalog->bootimages[catalog->num_bootimages] = boot_img;
|
||||||
|
catalog->num_bootimages++;
|
||||||
|
if (boot != NULL)
|
||||||
|
*boot = boot_img;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* API */
|
||||||
|
int iso_image_set_boot_catalog_weight(IsoImage *image, int sort_weight)
|
||||||
|
{
|
||||||
|
if (image->bootcat == NULL)
|
||||||
|
return 0;
|
||||||
|
image->bootcat->sort_weight = sort_weight;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* API */
|
||||||
|
int iso_image_set_boot_catalog_hidden(IsoImage *image, int hide_attrs)
|
||||||
|
{
|
||||||
|
if (image->bootcat == NULL)
|
||||||
|
return 0;
|
||||||
|
if (image->bootcat->node == NULL)
|
||||||
|
return 0;
|
||||||
|
iso_node_set_hidden((IsoNode *) image->bootcat->node, hide_attrs);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void el_torito_boot_catalog_free(struct el_torito_boot_catalog *cat)
|
void el_torito_boot_catalog_free(struct el_torito_boot_catalog *cat)
|
||||||
{
|
{
|
||||||
struct el_torito_boot_image *image;
|
struct el_torito_boot_image *image;
|
||||||
|
int i;
|
||||||
|
|
||||||
if (cat == NULL) {
|
if (cat == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
image = cat->image;
|
for (i = 0; i < Libisofs_max_boot_imageS; i++) {
|
||||||
iso_node_unref((IsoNode*)image->image);
|
image = cat->bootimages[i];
|
||||||
free(image);
|
if (image == NULL)
|
||||||
iso_node_unref((IsoNode*)cat->node);
|
continue;
|
||||||
|
if ((IsoNode*)image->image != NULL)
|
||||||
|
iso_node_unref((IsoNode*)image->image);
|
||||||
|
free(image);
|
||||||
|
}
|
||||||
|
if ((IsoNode*)cat->node != NULL)
|
||||||
|
iso_node_unref((IsoNode*)cat->node);
|
||||||
free(cat);
|
free(cat);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -537,11 +732,12 @@ struct catalog_stream
|
|||||||
{
|
{
|
||||||
Ecma119Image *target;
|
Ecma119Image *target;
|
||||||
uint8_t buffer[BLOCK_SIZE];
|
uint8_t buffer[BLOCK_SIZE];
|
||||||
int offset; /* -1 if stream is not openned */
|
int offset; /* -1 if stream is not opened */
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
write_validation_entry(uint8_t *buf)
|
write_validation_entry(uint8_t *buf, uint8_t platform_id,
|
||||||
|
uint8_t id_string[24])
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
int checksum;
|
int checksum;
|
||||||
@ -549,10 +745,10 @@ write_validation_entry(uint8_t *buf)
|
|||||||
struct el_torito_validation_entry *ve =
|
struct el_torito_validation_entry *ve =
|
||||||
(struct el_torito_validation_entry*)buf;
|
(struct el_torito_validation_entry*)buf;
|
||||||
ve->header_id[0] = 1;
|
ve->header_id[0] = 1;
|
||||||
ve->platform_id[0] = 0; /* 0: 80x86, 1: PowerPC, 2: Mac */
|
ve->platform_id[0] = platform_id;
|
||||||
|
memcpy(ve->id_string, id_string, sizeof(ve->id_string));
|
||||||
ve->key_byte1[0] = 0x55;
|
ve->key_byte1[0] = 0x55;
|
||||||
ve->key_byte2[0] = 0xAA;
|
ve->key_byte2[0] = 0xAA;
|
||||||
|
|
||||||
/* calculate the checksum, to ensure sum of all words is 0 */
|
/* calculate the checksum, to ensure sum of all words is 0 */
|
||||||
checksum = 0;
|
checksum = 0;
|
||||||
for (i = 0; i < sizeof(struct el_torito_validation_entry); i += 2) {
|
for (i = 0; i < sizeof(struct el_torito_validation_entry); i += 2) {
|
||||||
@ -561,35 +757,64 @@ write_validation_entry(uint8_t *buf)
|
|||||||
iso_lsb(ve->checksum, checksum, 2);
|
iso_lsb(ve->checksum, checksum, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
write_section_header(uint8_t *buf, Ecma119Image *t, int idx, int num_entries)
|
||||||
|
{
|
||||||
|
int pi;
|
||||||
|
char *id_string;
|
||||||
|
|
||||||
|
struct el_torito_section_header *e =
|
||||||
|
(struct el_torito_section_header *) buf;
|
||||||
|
|
||||||
|
/* 0x90 = more section headers follow , 0x91 = final section */
|
||||||
|
e->header_indicator[0] = 0x90 + (idx == t->catalog->num_bootimages - 1);
|
||||||
|
pi= e->platform_id[0] = t->catalog->bootimages[idx]->platform_id;
|
||||||
|
e->num_entries[0] = num_entries & 0xff;
|
||||||
|
e->num_entries[1] = (num_entries >> 8) & 0xff;;
|
||||||
|
id_string = (char *) e->id_string;
|
||||||
|
memcpy(id_string, t->catalog->bootimages[idx]->id_string,
|
||||||
|
sizeof(e->id_string));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write one section entry.
|
* Write one section entry.
|
||||||
* Currently this is used only for default image (the only supported just now)
|
* Usable for the Default Entry
|
||||||
|
* and for Section Entries with Selection criteria type == 0
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
write_section_entry(uint8_t *buf, Ecma119Image *t)
|
write_section_entry(uint8_t *buf, Ecma119Image *t, int idx)
|
||||||
{
|
{
|
||||||
struct el_torito_boot_image *img;
|
struct el_torito_boot_image *img;
|
||||||
struct el_torito_section_entry *se =
|
struct el_torito_section_entry *se =
|
||||||
(struct el_torito_section_entry*)buf;
|
(struct el_torito_section_entry*)buf;
|
||||||
|
|
||||||
img = t->catalog->image;
|
img = t->catalog->bootimages[idx];
|
||||||
|
|
||||||
se->boot_indicator[0] = img->bootable ? 0x88 : 0x00;
|
se->boot_indicator[0] = img->bootable ? 0x88 : 0x00;
|
||||||
se->boot_media_type[0] = img->type;
|
se->boot_media_type[0] = img->type;
|
||||||
iso_lsb(se->load_seg, img->load_seg, 2);
|
iso_lsb(se->load_seg, img->load_seg, 2);
|
||||||
se->system_type[0] = img->partition_type;
|
se->system_type[0] = img->partition_type;
|
||||||
iso_lsb(se->sec_count, img->load_size, 2);
|
iso_lsb(se->sec_count, img->load_size, 2);
|
||||||
iso_lsb(se->block, t->bootimg->sections[0].block, 4);
|
iso_lsb(se->block, t->bootsrc[idx]->sections[0].block, 4);
|
||||||
|
se->selec_criteria[0] = img->selection_crit[0];
|
||||||
|
memcpy(se->vendor_sc, img->selection_crit + 1, 19);
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
int catalog_open(IsoStream *stream)
|
int catalog_open(IsoStream *stream)
|
||||||
{
|
{
|
||||||
|
int i, j, k, num_entries;
|
||||||
struct catalog_stream *data;
|
struct catalog_stream *data;
|
||||||
|
uint8_t *wpt;
|
||||||
|
struct el_torito_boot_catalog *cat;
|
||||||
|
struct el_torito_boot_image **boots;
|
||||||
|
|
||||||
if (stream == NULL) {
|
if (stream == NULL) {
|
||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
}
|
}
|
||||||
data = stream->data;
|
data = stream->data;
|
||||||
|
cat = data->target->catalog;
|
||||||
|
boots = cat->bootimages;
|
||||||
|
|
||||||
if (data->offset != -1) {
|
if (data->offset != -1) {
|
||||||
return ISO_FILE_ALREADY_OPENED;
|
return ISO_FILE_ALREADY_OPENED;
|
||||||
@ -598,11 +823,36 @@ int catalog_open(IsoStream *stream)
|
|||||||
memset(data->buffer, 0, BLOCK_SIZE);
|
memset(data->buffer, 0, BLOCK_SIZE);
|
||||||
|
|
||||||
/* fill the buffer with the catalog contents */
|
/* fill the buffer with the catalog contents */
|
||||||
write_validation_entry(data->buffer);
|
write_validation_entry(data->buffer,
|
||||||
|
boots[0]->platform_id, boots[0]->id_string);
|
||||||
|
|
||||||
/* write default entry */
|
/* write default entry = first boot image */
|
||||||
write_section_entry(data->buffer + 32, data->target);
|
write_section_entry(data->buffer + 32, data->target, 0);
|
||||||
|
|
||||||
|
/* IMPORTANT: The maximum number of boot images must fit into BLOCK_SIZE */
|
||||||
|
wpt = data->buffer + 64;
|
||||||
|
for (i = 1; i < cat->num_bootimages; ) {
|
||||||
|
/* Look ahead and put images of same platform_id and id_string
|
||||||
|
into the same section */
|
||||||
|
for (j = i + 1; j < cat->num_bootimages; j++) {
|
||||||
|
if (boots[i]->platform_id != boots[j]->platform_id)
|
||||||
|
break;
|
||||||
|
for (k = 0; k < sizeof(boots[i]->id_string); k++)
|
||||||
|
if (boots[i]->id_string[k] != boots[j]->id_string[k])
|
||||||
|
break;
|
||||||
|
if (k < sizeof(boots[i]->id_string))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
num_entries = j - i;
|
||||||
|
|
||||||
|
write_section_header(wpt, data->target, i, num_entries);
|
||||||
|
wpt += 32;
|
||||||
|
for (j = 0; j < num_entries; j++) {
|
||||||
|
write_section_entry(wpt, data->target, i);
|
||||||
|
wpt += 32;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
data->offset = 0;
|
data->offset = 0;
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -702,12 +952,12 @@ int catalog_stream_new(Ecma119Image *target, IsoStream **stream)
|
|||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
str = malloc(sizeof(IsoStream));
|
str = calloc(1, sizeof(IsoStream));
|
||||||
if (str == NULL) {
|
if (str == NULL) {
|
||||||
return ISO_OUT_OF_MEM;
|
return ISO_OUT_OF_MEM;
|
||||||
}
|
}
|
||||||
data = malloc(sizeof(struct catalog_stream));
|
data = calloc(1, sizeof(struct catalog_stream));
|
||||||
if (str == NULL) {
|
if (data == NULL) {
|
||||||
free(str);
|
free(str);
|
||||||
return ISO_OUT_OF_MEM;
|
return ISO_OUT_OF_MEM;
|
||||||
}
|
}
|
||||||
@ -740,7 +990,7 @@ int el_torito_catalog_file_src_create(Ecma119Image *target, IsoFileSrc **src)
|
|||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
file = malloc(sizeof(IsoFileSrc));
|
file = calloc(1, sizeof(IsoFileSrc));
|
||||||
if (file == NULL) {
|
if (file == NULL) {
|
||||||
return ISO_OUT_OF_MEM;
|
return ISO_OUT_OF_MEM;
|
||||||
}
|
}
|
||||||
@ -753,9 +1003,10 @@ int el_torito_catalog_file_src_create(Ecma119Image *target, IsoFileSrc **src)
|
|||||||
|
|
||||||
/* fill fields */
|
/* fill fields */
|
||||||
file->prev_img = 0; /* TODO allow copy of old img catalog???? */
|
file->prev_img = 0; /* TODO allow copy of old img catalog???? */
|
||||||
|
file->checksum_index = 0;
|
||||||
file->nsections = 1;
|
file->nsections = 1;
|
||||||
file->sections = calloc(1, sizeof(struct iso_file_section));
|
file->sections = calloc(1, sizeof(struct iso_file_section));
|
||||||
file->sort_weight = 1000; /* slightly high */
|
file->sort_weight = target->catalog->sort_weight;
|
||||||
file->stream = stream;
|
file->stream = stream;
|
||||||
|
|
||||||
ret = iso_file_src_add(target, file, src);
|
ret = iso_file_src_add(target, file, src);
|
||||||
@ -771,27 +1022,26 @@ int el_torito_catalog_file_src_create(Ecma119Image *target, IsoFileSrc **src)
|
|||||||
/******************* EL-TORITO WRITER *******************************/
|
/******************* EL-TORITO WRITER *******************************/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Patch an isolinux boot image.
|
* Insert boot info table content into buf.
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* 1 on success, 0 error (but continue), < 0 error
|
* 1 on success, 0 error (but continue), < 0 error
|
||||||
*/
|
*/
|
||||||
static
|
int make_boot_info_table(uint8_t *buf, uint32_t pvd_lba,
|
||||||
int patch_boot_image(uint8_t *buf, Ecma119Image *t, size_t imgsize)
|
uint32_t boot_lba, uint32_t imgsize)
|
||||||
{
|
{
|
||||||
struct boot_info_table *info;
|
struct boot_info_table *info;
|
||||||
uint32_t checksum;
|
uint32_t checksum;
|
||||||
size_t offset;
|
uint32_t offset;
|
||||||
|
|
||||||
if (imgsize < 64) {
|
info = (struct boot_info_table *) (buf + 8);
|
||||||
return iso_msg_submit(t->image->id, ISO_ISOLINUX_CANT_PATCH, 0,
|
if (imgsize < 64)
|
||||||
"Isolinux image too small. We won't patch it.");
|
return ISO_ISOLINUX_CANT_PATCH;
|
||||||
}
|
|
||||||
|
|
||||||
/* compute checksum, as the the sum of all 32 bit words in boot image
|
/* compute checksum, as the the sum of all 32 bit words in boot image
|
||||||
* from offset 64 */
|
* from offset 64 */
|
||||||
checksum = 0;
|
checksum = 0;
|
||||||
offset = (size_t) 64;
|
offset = 64;
|
||||||
|
|
||||||
while (offset <= imgsize - 4) {
|
while (offset <= imgsize - 4) {
|
||||||
checksum += iso_read_lsb(buf + offset, 4);
|
checksum += iso_read_lsb(buf + offset, 4);
|
||||||
@ -806,16 +1056,36 @@ int patch_boot_image(uint8_t *buf, Ecma119Image *t, size_t imgsize)
|
|||||||
checksum += iso_read_lsb(buf + offset, imgsize - offset);
|
checksum += iso_read_lsb(buf + offset, imgsize - offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* patch boot info table */
|
|
||||||
info = (struct boot_info_table*)(buf + 8);
|
|
||||||
/*memset(info, 0, sizeof(struct boot_info_table));*/
|
/*memset(info, 0, sizeof(struct boot_info_table));*/
|
||||||
iso_lsb(info->bi_pvd, t->ms_block + 16, 4);
|
iso_lsb(info->bi_pvd, pvd_lba, 4);
|
||||||
iso_lsb(info->bi_file, t->bootimg->sections[0].block, 4);
|
iso_lsb(info->bi_file, boot_lba, 4);
|
||||||
iso_lsb(info->bi_length, imgsize, 4);
|
iso_lsb(info->bi_length, imgsize, 4);
|
||||||
iso_lsb(info->bi_csum, checksum, 4);
|
iso_lsb(info->bi_csum, checksum, 4);
|
||||||
|
memset(buf + 24, 0, 40);
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Patch an isolinux boot image.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* 1 on success, 0 error (but continue), < 0 error
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
int patch_boot_image(uint8_t *buf, Ecma119Image *t, size_t imgsize, int idx)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (imgsize < 64) {
|
||||||
|
return iso_msg_submit(t->image->id, ISO_ISOLINUX_CANT_PATCH, 0,
|
||||||
|
"Isolinux image too small. We won't patch it.");
|
||||||
|
}
|
||||||
|
ret = make_boot_info_table(buf, t->ms_block + (uint32_t) 16,
|
||||||
|
t->bootsrc[idx]->sections[0].block,
|
||||||
|
(uint32_t) imgsize);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
int eltorito_writer_compute_data_blocks(IsoImageWriter *writer)
|
int eltorito_writer_compute_data_blocks(IsoImageWriter *writer)
|
||||||
{
|
{
|
||||||
@ -824,7 +1094,11 @@ int eltorito_writer_compute_data_blocks(IsoImageWriter *writer)
|
|||||||
* this is a good place to do so.
|
* this is a good place to do so.
|
||||||
*/
|
*/
|
||||||
Ecma119Image *t;
|
Ecma119Image *t;
|
||||||
int ret;
|
int ret, idx;
|
||||||
|
size_t size;
|
||||||
|
uint8_t *buf;
|
||||||
|
IsoStream *new = NULL;
|
||||||
|
IsoStream *original = NULL;
|
||||||
|
|
||||||
if (writer == NULL) {
|
if (writer == NULL) {
|
||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
@ -832,19 +1106,23 @@ int eltorito_writer_compute_data_blocks(IsoImageWriter *writer)
|
|||||||
|
|
||||||
t = writer->target;
|
t = writer->target;
|
||||||
|
|
||||||
if (t->catalog->image->isolinux_options & 0x01) {
|
/* Patch the boot image info tables if indicated */
|
||||||
/* we need to patch the image */
|
for (idx = 0; idx < t->catalog->num_bootimages; idx++) {
|
||||||
size_t size;
|
if (!(t->catalog->bootimages[idx]->isolinux_options & 0x01))
|
||||||
uint8_t *buf;
|
continue;
|
||||||
IsoStream *new = NULL;
|
original = t->bootsrc[idx]->stream;
|
||||||
IsoStream *original = t->bootimg->stream;
|
|
||||||
size = (size_t) iso_stream_get_size(original);
|
size = (size_t) iso_stream_get_size(original);
|
||||||
buf = malloc(size);
|
|
||||||
|
/* >>> BOOT ts B00428 :
|
||||||
|
check whether size is not too large for buffering */;
|
||||||
|
|
||||||
|
buf = calloc(1, size);
|
||||||
if (buf == NULL) {
|
if (buf == NULL) {
|
||||||
return ISO_OUT_OF_MEM;
|
return ISO_OUT_OF_MEM;
|
||||||
}
|
}
|
||||||
ret = iso_stream_open(original);
|
ret = iso_stream_open(original);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
free(buf);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
ret = iso_stream_read(original, buf, size);
|
ret = iso_stream_read(original, buf, size);
|
||||||
@ -854,7 +1132,7 @@ int eltorito_writer_compute_data_blocks(IsoImageWriter *writer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ok, patch the read buffer */
|
/* ok, patch the read buffer */
|
||||||
ret = patch_boot_image(buf, t, size);
|
ret = patch_boot_image(buf, t, size, idx);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -865,7 +1143,7 @@ int eltorito_writer_compute_data_blocks(IsoImageWriter *writer)
|
|||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
t->bootimg->stream = new;
|
t->bootsrc[idx]->stream = new;
|
||||||
iso_stream_unref(original);
|
iso_stream_unref(original);
|
||||||
}
|
}
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
@ -887,7 +1165,6 @@ int eltorito_writer_write_vol_desc(IsoImageWriter *writer)
|
|||||||
|
|
||||||
t = writer->target;
|
t = writer->target;
|
||||||
cat = t->catalog;
|
cat = t->catalog;
|
||||||
|
|
||||||
iso_msg_debug(t->image->id, "Write El-Torito boot record");
|
iso_msg_debug(t->image->id, "Write El-Torito boot record");
|
||||||
|
|
||||||
memset(&vol, 0, sizeof(struct ecma119_boot_rec_vol_desc));
|
memset(&vol, 0, sizeof(struct ecma119_boot_rec_vol_desc));
|
||||||
@ -895,8 +1172,8 @@ int eltorito_writer_write_vol_desc(IsoImageWriter *writer)
|
|||||||
memcpy(vol.std_identifier, "CD001", 5);
|
memcpy(vol.std_identifier, "CD001", 5);
|
||||||
vol.vol_desc_version[0] = 1;
|
vol.vol_desc_version[0] = 1;
|
||||||
memcpy(vol.boot_sys_id, "EL TORITO SPECIFICATION", 23);
|
memcpy(vol.boot_sys_id, "EL TORITO SPECIFICATION", 23);
|
||||||
iso_lsb(vol.boot_catalog, t->cat->sections[0].block, 4);
|
iso_lsb(vol.boot_catalog,
|
||||||
|
t->cat->sections[0].block - t->eff_partition_offset, 4);
|
||||||
return iso_write(t, &vol, sizeof(struct ecma119_boot_rec_vol_desc));
|
return iso_write(t, &vol, sizeof(struct ecma119_boot_rec_vol_desc));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -916,12 +1193,12 @@ int eltorito_writer_free_data(IsoImageWriter *writer)
|
|||||||
|
|
||||||
int eltorito_writer_create(Ecma119Image *target)
|
int eltorito_writer_create(Ecma119Image *target)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret, idx;
|
||||||
IsoImageWriter *writer;
|
IsoImageWriter *writer;
|
||||||
IsoFile *bootimg;
|
IsoFile *bootimg;
|
||||||
IsoFileSrc *src;
|
IsoFileSrc *src;
|
||||||
|
|
||||||
writer = malloc(sizeof(IsoImageWriter));
|
writer = calloc(1, sizeof(IsoImageWriter));
|
||||||
if (writer == NULL) {
|
if (writer == NULL) {
|
||||||
return ISO_OUT_OF_MEM;
|
return ISO_OUT_OF_MEM;
|
||||||
}
|
}
|
||||||
@ -947,16 +1224,19 @@ int eltorito_writer_create(Ecma119Image *target)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bootimg = target->catalog->image->image;
|
|
||||||
ret = iso_file_src_create(target, bootimg, &src);
|
|
||||||
if (ret < 0) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
target->bootimg = src;
|
|
||||||
|
|
||||||
/* if we have selected to patch the image, it needs to be copied always */
|
for (idx = 0; idx < target->catalog->num_bootimages; idx++) {
|
||||||
if (target->catalog->image->isolinux_options & 0x01) {
|
bootimg = target->catalog->bootimages[idx]->image;
|
||||||
src->prev_img = 0;
|
ret = iso_file_src_create(target, bootimg, &src);
|
||||||
|
if (ret < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
target->bootsrc[idx] = src;
|
||||||
|
|
||||||
|
/* For patching an image, it needs to be copied always */
|
||||||
|
if (target->catalog->bootimages[idx]->isolinux_options & 0x01) {
|
||||||
|
src->prev_img = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we need the bootable volume descriptor */
|
/* we need the bootable volume descriptor */
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
|
* Copyright (c) 2010 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -26,25 +28,45 @@ struct Iso_Boot
|
|||||||
IsoNode node;
|
IsoNode node;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Not more than 32 so that all entries fit into 2048 bytes */
|
||||||
|
#define Libisofs_max_boot_imageS 32
|
||||||
|
|
||||||
struct el_torito_boot_catalog {
|
struct el_torito_boot_catalog {
|
||||||
IsoBoot *node; /* node of the 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 {
|
struct el_torito_boot_image {
|
||||||
IsoFile *image;
|
IsoFile *image;
|
||||||
|
|
||||||
unsigned int bootable:1; /**< If the entry is bootable. */
|
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;
|
||||||
/**
|
/**
|
||||||
* isolinux options
|
* isolinux options
|
||||||
* bit 0 -> whether to patch image
|
* 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)
|
||||||
*/
|
*/
|
||||||
unsigned int isolinux_options:2;
|
unsigned int isolinux_options:2;
|
||||||
unsigned char type; /**< The type of image */
|
unsigned char type; /**< The type of image */
|
||||||
unsigned char partition_type; /**< type of partition for HD-emul images */
|
unsigned char partition_type; /**< type of partition for HD-emul images */
|
||||||
short load_seg; /**< Load segment for the initial boot image. */
|
short load_seg; /**< Load segment for the initial boot image. */
|
||||||
short load_size; /**< Number of sectors to load. */
|
short load_size; /**< Number of sectors to load. */
|
||||||
|
|
||||||
|
/* 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 */
|
/** El-Torito, 2.1 */
|
||||||
@ -74,8 +96,8 @@ struct el_torito_default_entry {
|
|||||||
struct el_torito_section_header {
|
struct el_torito_section_header {
|
||||||
uint8_t header_indicator BP(1, 1);
|
uint8_t header_indicator BP(1, 1);
|
||||||
uint8_t platform_id BP(2, 2);
|
uint8_t platform_id BP(2, 2);
|
||||||
uint8_t number BP(3, 4);
|
uint8_t num_entries BP(3, 4);
|
||||||
uint8_t character BP(5, 32);
|
uint8_t id_string BP(5, 32);
|
||||||
};
|
};
|
||||||
|
|
||||||
/** El-Torito, 2.4 */
|
/** El-Torito, 2.4 */
|
||||||
@ -105,4 +127,14 @@ int el_torito_catalog_file_src_create(Ecma119Image *target, IsoFileSrc **src);
|
|||||||
*/
|
*/
|
||||||
int eltorito_writer_create(Ecma119Image *target);
|
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);
|
||||||
|
|
||||||
|
|
||||||
#endif /* LIBISO_ELTORITO_H */
|
#endif /* LIBISO_ELTORITO_H */
|
||||||
|
@ -1,11 +1,18 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
|
* 2010 - 2011 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "libisofs.h"
|
||||||
#include "filesrc.h"
|
#include "filesrc.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
@ -13,16 +20,33 @@
|
|||||||
#include "messages.h"
|
#include "messages.h"
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
#include "stream.h"
|
#include "stream.h"
|
||||||
|
|
||||||
#ifdef Libisofs_with_checksumS
|
|
||||||
#include "md5.h"
|
#include "md5.h"
|
||||||
#endif /* Libisofs_with_checksumS */
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <limits.h>
|
#include <limits.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
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
int iso_file_src_cmp(const void *n1, const void *n2)
|
int iso_file_src_cmp(const void *n1, const void *n2)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@ -47,11 +71,8 @@ int iso_file_src_create(Ecma119Image *img, IsoFile *file, IsoFileSrc **src)
|
|||||||
unsigned int fs_id;
|
unsigned int fs_id;
|
||||||
dev_t dev_id;
|
dev_t dev_id;
|
||||||
ino_t ino_id;
|
ino_t ino_id;
|
||||||
|
|
||||||
#ifdef Libisofs_with_checksumS
|
|
||||||
int cret, no_md5= 0;
|
int cret, no_md5= 0;
|
||||||
void *xipt = NULL;
|
void *xipt = NULL;
|
||||||
#endif
|
|
||||||
|
|
||||||
if (img == NULL || file == NULL || src == NULL) {
|
if (img == NULL || file == NULL || src == NULL) {
|
||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
@ -97,9 +118,6 @@ int iso_file_src_create(Ecma119Image *img, IsoFile *file, IsoFileSrc **src)
|
|||||||
/* insert the filesrc in the tree */
|
/* insert the filesrc in the tree */
|
||||||
ret = iso_rbtree_insert(img->files, fsrc, (void**)src);
|
ret = iso_rbtree_insert(img->files, fsrc, (void**)src);
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
|
|
||||||
#ifdef Libisofs_with_checksumS
|
|
||||||
|
|
||||||
if (ret == 0 && (*src)->checksum_index > 0) {
|
if (ret == 0 && (*src)->checksum_index > 0) {
|
||||||
/* Duplicate file source was mapped to previously registered source
|
/* Duplicate file source was mapped to previously registered source
|
||||||
*/
|
*/
|
||||||
@ -107,17 +125,12 @@ int iso_file_src_create(Ecma119Image *img, IsoFile *file, IsoFileSrc **src)
|
|||||||
if (cret < 0)
|
if (cret < 0)
|
||||||
ret = cret;
|
ret = cret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Libisofs_with_checksumS */
|
|
||||||
|
|
||||||
free(fsrc->sections);
|
free(fsrc->sections);
|
||||||
free(fsrc);
|
free(fsrc);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
iso_stream_ref(fsrc->stream);
|
iso_stream_ref(fsrc->stream);
|
||||||
|
|
||||||
#ifdef Libisofs_with_checksumS
|
|
||||||
|
|
||||||
if ((img->md5_file_checksums & 1) &&
|
if ((img->md5_file_checksums & 1) &&
|
||||||
file->from_old_session && img->appendable) {
|
file->from_old_session && img->appendable) {
|
||||||
ret = iso_node_get_xinfo((IsoNode *) file, checksum_md5_xinfo_func,
|
ret = iso_node_get_xinfo((IsoNode *) file, checksum_md5_xinfo_func,
|
||||||
@ -132,19 +145,17 @@ int iso_file_src_create(Ecma119Image *img, IsoFile *file, IsoFileSrc **src)
|
|||||||
|
|
||||||
if ((img->md5_file_checksums & 1) && !no_md5) {
|
if ((img->md5_file_checksums & 1) && !no_md5) {
|
||||||
img->checksum_idx_counter++;
|
img->checksum_idx_counter++;
|
||||||
if (img->checksum_idx_counter < 0x80000000) {
|
if (img->checksum_idx_counter < 0x7fffffff) {
|
||||||
fsrc->checksum_index = img->checksum_idx_counter;
|
fsrc->checksum_index = img->checksum_idx_counter;
|
||||||
} else {
|
} else {
|
||||||
fsrc->checksum_index= 0;
|
fsrc->checksum_index= 0;
|
||||||
img->checksum_idx_counter= 0x80000000; /* keep from rolling over */
|
img->checksum_idx_counter= 0x7fffffff; /* keep from rolling over */
|
||||||
}
|
}
|
||||||
cret = iso_file_set_isofscx(file, (*src)->checksum_index, 0);
|
cret = iso_file_set_isofscx(file, (*src)->checksum_index, 0);
|
||||||
if (cret < 0)
|
if (cret < 0)
|
||||||
return cret;
|
return cret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Libisofs_with_checksumS */
|
|
||||||
|
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,6 +232,12 @@ int filesrc_writer_compute_data_blocks(IsoImageWriter *writer)
|
|||||||
|
|
||||||
t = writer->target;
|
t = writer->target;
|
||||||
|
|
||||||
|
/* Normally reserve a single zeroed block for all files which have
|
||||||
|
no block address: symbolic links, device files, empty data files.
|
||||||
|
*/
|
||||||
|
if (! t->old_empty)
|
||||||
|
t->curblock++;
|
||||||
|
|
||||||
/* on appendable images, ms files shouldn't be included */
|
/* on appendable images, ms files shouldn't be included */
|
||||||
if (t->appendable) {
|
if (t->appendable) {
|
||||||
inc_item = is_ms_file;
|
inc_item = is_ms_file;
|
||||||
@ -255,7 +272,12 @@ int filesrc_writer_compute_data_blocks(IsoImageWriter *writer)
|
|||||||
/*
|
/*
|
||||||
* final section
|
* final section
|
||||||
*/
|
*/
|
||||||
file->sections[extent].block = t->curblock + extent * (ISO_EXTENT_SIZE / BLOCK_SIZE);
|
if (section_size <= 0) {
|
||||||
|
file->sections[extent].block = t->empty_file_block;
|
||||||
|
} else {
|
||||||
|
file->sections[extent].block =
|
||||||
|
t->curblock + extent * (ISO_EXTENT_SIZE / BLOCK_SIZE);
|
||||||
|
}
|
||||||
file->sections[extent].size = (uint32_t)section_size;
|
file->sections[extent].size = (uint32_t)section_size;
|
||||||
|
|
||||||
t->curblock += DIV_UP(iso_file_src_get_size(file), BLOCK_SIZE);
|
t->curblock += DIV_UP(iso_file_src_get_size(file), BLOCK_SIZE);
|
||||||
@ -298,21 +320,16 @@ int filesrc_read(IsoFileSrc *file, char *buf, size_t count)
|
|||||||
return iso_stream_read_buffer(file->stream, buf, count, &got);
|
return iso_stream_read_buffer(file->stream, buf, count, &got);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef Libisofs_with_checksumS
|
|
||||||
|
|
||||||
/* @return 1=ok, md5 is valid,
|
/* @return 1=ok, md5 is valid,
|
||||||
0= not ok, go on,
|
0= not ok, go on,
|
||||||
<0 fatal error, abort
|
<0 fatal error, abort
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static
|
static
|
||||||
int filesrc_make_md5(Ecma119Image *t, IsoFileSrc *file, char md5[16], int flag)
|
int filesrc_make_md5(Ecma119Image *t, IsoFileSrc *file, char md5[16], int flag)
|
||||||
{
|
{
|
||||||
return iso_stream_make_md5(file->stream, md5, 0);
|
return iso_stream_make_md5(file->stream, md5, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Libisofs_with_checksumS */
|
|
||||||
|
|
||||||
static
|
static
|
||||||
int filesrc_writer_write_data(IsoImageWriter *writer)
|
int filesrc_writer_write_data(IsoImageWriter *writer)
|
||||||
{
|
{
|
||||||
@ -325,39 +342,43 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
|
|||||||
char buffer[BLOCK_SIZE];
|
char buffer[BLOCK_SIZE];
|
||||||
off_t file_size;
|
off_t file_size;
|
||||||
uint32_t nblocks;
|
uint32_t nblocks;
|
||||||
|
|
||||||
#ifdef Libisofs_with_checksumS
|
|
||||||
void *ctx= NULL;
|
void *ctx= NULL;
|
||||||
char md5[16], pre_md5[16];
|
char md5[16], pre_md5[16];
|
||||||
int pre_md5_valid = 0;
|
int pre_md5_valid = 0;
|
||||||
|
#ifdef Libisofs_with_libjtE
|
||||||
|
int jte_begun = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
if (writer == NULL) {
|
if (writer == NULL) {
|
||||||
return ISO_ASSERT_FAILURE;
|
return ISO_ASSERT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memset(buffer, 0, BLOCK_SIZE);
|
||||||
t = writer->target;
|
t = writer->target;
|
||||||
filelist = writer->data;
|
filelist = writer->data;
|
||||||
|
|
||||||
iso_msg_debug(t->image->id, "Writing Files...");
|
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->old_empty) {
|
||||||
|
ret = iso_write(t, buffer, BLOCK_SIZE);
|
||||||
|
if (ret < 0)
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
while ((file = filelist[i++]) != NULL) {
|
while ((file = filelist[i++]) != NULL) {
|
||||||
was_error = 0;
|
was_error = 0;
|
||||||
file_size = iso_file_src_get_size(file);
|
file_size = iso_file_src_get_size(file);
|
||||||
nblocks = DIV_UP(file_size, BLOCK_SIZE);
|
nblocks = DIV_UP(file_size, BLOCK_SIZE);
|
||||||
|
|
||||||
#ifdef Libisofs_with_checksumS
|
|
||||||
|
|
||||||
pre_md5_valid = 0;
|
pre_md5_valid = 0;
|
||||||
if (file->checksum_index > 0 && (t->md5_file_checksums & 2)) {
|
if (file->checksum_index > 0 && (t->md5_file_checksums & 2)) {
|
||||||
/* Obtain an MD5 of content by a first read pass */
|
/* Obtain an MD5 of content by a first read pass */
|
||||||
pre_md5_valid = filesrc_make_md5(t, file, pre_md5, 0);
|
pre_md5_valid = filesrc_make_md5(t, file, pre_md5, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Libisofs_with_checksumS */
|
|
||||||
|
|
||||||
res = filesrc_open(file);
|
res = filesrc_open(file);
|
||||||
iso_stream_get_file_name(file->stream, name);
|
iso_stream_get_file_name(file->stream, name);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
@ -401,18 +422,29 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef Libisofs_with_libjtE
|
||||||
#ifdef Libisofs_with_checksumS
|
if (t->libjte_handle != NULL) {
|
||||||
|
res = libjte_begin_data_file(t->libjte_handle, name,
|
||||||
|
BLOCK_SIZE, file_size);
|
||||||
|
if (res <= 0) {
|
||||||
|
res = iso_libjte_forward_msgs(t->libjte_handle, t->image->id,
|
||||||
|
ISO_LIBJTE_FILE_FAILED, 0);
|
||||||
|
if (res < 0) {
|
||||||
|
filesrc_close(file);
|
||||||
|
ret = ISO_LIBJTE_FILE_FAILED;
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jte_begun = 1;
|
||||||
|
}
|
||||||
|
#endif /* Libisofs_with_libjtE */
|
||||||
|
|
||||||
if (file->checksum_index > 0) {
|
if (file->checksum_index > 0) {
|
||||||
/* initialize file checksum */
|
/* initialize file checksum */
|
||||||
res = iso_md5_start(&ctx);
|
res = iso_md5_start(&ctx);
|
||||||
if (res <= 0)
|
if (res <= 0)
|
||||||
file->checksum_index = 0;
|
file->checksum_index = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Libisofs_with_checksumS */
|
|
||||||
|
|
||||||
/* write file contents to image */
|
/* write file contents to image */
|
||||||
for (b = 0; b < nblocks; ++b) {
|
for (b = 0; b < nblocks; ++b) {
|
||||||
int wres;
|
int wres;
|
||||||
@ -428,9 +460,6 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
|
|||||||
ret = wres;
|
ret = wres;
|
||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef Libisofs_with_checksumS
|
|
||||||
|
|
||||||
if (file->checksum_index > 0) {
|
if (file->checksum_index > 0) {
|
||||||
/* Add to file checksum */
|
/* Add to file checksum */
|
||||||
if (file_size - b * BLOCK_SIZE > BLOCK_SIZE)
|
if (file_size - b * BLOCK_SIZE > BLOCK_SIZE)
|
||||||
@ -441,9 +470,6 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
|
|||||||
if (res <= 0)
|
if (res <= 0)
|
||||||
file->checksum_index = 0;
|
file->checksum_index = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Libisofs_with_checksumS */
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
filesrc_close(file);
|
filesrc_close(file);
|
||||||
@ -478,9 +504,6 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
|
|||||||
ret = res;
|
ret = res;
|
||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef Libisofs_with_checksumS
|
|
||||||
|
|
||||||
if (file->checksum_index > 0) {
|
if (file->checksum_index > 0) {
|
||||||
/* Add to file checksum */
|
/* Add to file checksum */
|
||||||
if (file_size - b * BLOCK_SIZE > BLOCK_SIZE)
|
if (file_size - b * BLOCK_SIZE > BLOCK_SIZE)
|
||||||
@ -491,15 +514,10 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
|
|||||||
if (res <= 0)
|
if (res <= 0)
|
||||||
file->checksum_index = 0;
|
file->checksum_index = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Libisofs_with_checksumS */
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (file->checksum_index > 0 &&
|
||||||
#ifdef Libisofs_with_checksumS
|
file->checksum_index <= t->checksum_idx_counter) {
|
||||||
|
|
||||||
if (file->checksum_index > 0) {
|
|
||||||
/* Obtain checksum and dispose checksum context */
|
/* Obtain checksum and dispose checksum context */
|
||||||
res = iso_md5_end(&ctx, md5);
|
res = iso_md5_end(&ctx, md5);
|
||||||
if (res <= 0)
|
if (res <= 0)
|
||||||
@ -523,17 +541,33 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
|
|||||||
memcpy(t->checksum_buffer + 16 * file->checksum_index, md5, 16);
|
memcpy(t->checksum_buffer + 16 * file->checksum_index, md5, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Libisofs_with_checksumS */
|
#ifdef Libisofs_with_libjtE
|
||||||
|
if (t->libjte_handle != NULL) {
|
||||||
|
res = libjte_end_data_file(t->libjte_handle);
|
||||||
|
if (res <= 0) {
|
||||||
|
iso_libjte_forward_msgs(t->libjte_handle, t->image->id,
|
||||||
|
ISO_LIBJTE_FILE_FAILED, 0);
|
||||||
|
ret = ISO_LIBJTE_FILE_FAILED;
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
jte_begun = 0;
|
||||||
|
}
|
||||||
|
#endif /* Libisofs_with_libjtE */
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = ISO_SUCCESS;
|
ret = ISO_SUCCESS;
|
||||||
ex:;
|
ex:;
|
||||||
|
|
||||||
#ifdef Libisofs_with_checksumS
|
|
||||||
if (ctx != NULL) /* avoid any memory leak */
|
if (ctx != NULL) /* avoid any memory leak */
|
||||||
iso_md5_end(&ctx, md5);
|
iso_md5_end(&ctx, md5);
|
||||||
#endif
|
|
||||||
|
#ifdef Libisofs_with_libjtE
|
||||||
|
if (jte_begun) {
|
||||||
|
libjte_end_data_file(t->libjte_handle);
|
||||||
|
iso_libjte_forward_msgs(t->libjte_handle, t->image->id,
|
||||||
|
ISO_LIBJTE_END_FAILED, 0);
|
||||||
|
}
|
||||||
|
#endif /* Libisofs_with_libjtE */
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -550,7 +584,7 @@ int iso_file_src_writer_create(Ecma119Image *target)
|
|||||||
{
|
{
|
||||||
IsoImageWriter *writer;
|
IsoImageWriter *writer;
|
||||||
|
|
||||||
writer = malloc(sizeof(IsoImageWriter));
|
writer = calloc(1, sizeof(IsoImageWriter));
|
||||||
if (writer == NULL) {
|
if (writer == NULL) {
|
||||||
return ISO_OUT_OF_MEM;
|
return ISO_OUT_OF_MEM;
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,9 @@
|
|||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
*/
|
*/
|
||||||
#ifndef LIBISO_FILESRC_H_
|
#ifndef LIBISO_FILESRC_H_
|
||||||
#define LIBISO_FILESRC_H_
|
#define LIBISO_FILESRC_H_
|
||||||
@ -12,19 +13,19 @@
|
|||||||
#include "stream.h"
|
#include "stream.h"
|
||||||
#include "ecma119.h"
|
#include "ecma119.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_STDINT_H
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_INTTYPES_H
|
||||||
|
#include <inttypes.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
struct Iso_File_Src
|
struct Iso_File_Src
|
||||||
{
|
{
|
||||||
unsigned int prev_img :1; /**< if the file comes from a previous image */
|
unsigned int prev_img :1; /**< if the file comes from a previous image */
|
||||||
|
|
||||||
#ifdef Libisofs_with_checksumS
|
|
||||||
|
|
||||||
unsigned int checksum_index :31;
|
unsigned int checksum_index :31;
|
||||||
|
|
||||||
#endif /* Libisofs_with_checksumS */
|
|
||||||
|
|
||||||
|
|
||||||
/** File Sections of the file in the image */
|
/** File Sections of the file in the image */
|
||||||
struct iso_file_section *sections;
|
struct iso_file_section *sections;
|
||||||
int nsections;
|
int nsections;
|
||||||
|
@ -3,10 +3,15 @@
|
|||||||
* Copyright (c) 2009 Thomas Schmitt
|
* Copyright (c) 2009 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libisofs.h"
|
#include "libisofs.h"
|
||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
|
@ -2,8 +2,9 @@
|
|||||||
* Copyright (c) 2008 Vreixo Formoso
|
* Copyright (c) 2008 Vreixo Formoso
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
*/
|
*/
|
||||||
#ifndef LIBISO_FILTER_H_
|
#ifndef LIBISO_FILTER_H_
|
||||||
#define LIBISO_FILTER_H_
|
#define LIBISO_FILTER_H_
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
/*
|
/*
|
||||||
* 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
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
*
|
*
|
||||||
* It implements a filter facility which can pipe a IsoStream into an external
|
* It implements a filter facility which can pipe a IsoStream into an external
|
||||||
* process, read its output and forward it as IsoStream output to an IsoFile.
|
* process, read its output and forward it as IsoStream output to an IsoFile.
|
||||||
@ -12,9 +13,14 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "../libisofs.h"
|
#include "../libisofs.h"
|
||||||
#include "../filter.h"
|
#include "../filter.h"
|
||||||
#include "../fsource.h"
|
#include "../fsource.h"
|
||||||
|
#include "../stream.h"
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
@ -35,7 +41,7 @@
|
|||||||
* for classical pipe filtering.
|
* 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.
|
* Individual runtime properties exist only as long as the stream is opened.
|
||||||
*/
|
*/
|
||||||
@ -593,6 +599,36 @@ IsoStream *extf_get_input_stream(IsoStream *stream, int flag)
|
|||||||
return data->orig;
|
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
|
static
|
||||||
int extf_cmp_ino(IsoStream *s1, IsoStream *s2);
|
int extf_cmp_ino(IsoStream *s1, IsoStream *s2);
|
||||||
@ -600,7 +636,7 @@ int extf_cmp_ino(IsoStream *s1, IsoStream *s2);
|
|||||||
|
|
||||||
|
|
||||||
IsoStreamIface extf_stream_class = {
|
IsoStreamIface extf_stream_class = {
|
||||||
3,
|
4,
|
||||||
"extf",
|
"extf",
|
||||||
extf_stream_open,
|
extf_stream_open,
|
||||||
extf_stream_close,
|
extf_stream_close,
|
||||||
@ -611,7 +647,8 @@ IsoStreamIface extf_stream_class = {
|
|||||||
extf_stream_free,
|
extf_stream_free,
|
||||||
extf_update_size,
|
extf_update_size,
|
||||||
extf_get_input_stream,
|
extf_get_input_stream,
|
||||||
extf_cmp_ino
|
extf_cmp_ino,
|
||||||
|
extf_clone_stream
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
/*
|
/*
|
||||||
* 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
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
*
|
*
|
||||||
* It implements a filter facility which can pipe a IsoStream into gzip
|
* It implements a filter facility which can pipe a IsoStream into gzip
|
||||||
* compression resp. uncompression, read its output and forward it as IsoStream
|
* compression resp. uncompression, read its output and forward it as IsoStream
|
||||||
@ -16,10 +17,15 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "../libisofs.h"
|
#include "../libisofs.h"
|
||||||
#include "../filter.h"
|
#include "../filter.h"
|
||||||
#include "../fsource.h"
|
#include "../fsource.h"
|
||||||
#include "../util.h"
|
#include "../util.h"
|
||||||
|
#include "../stream.h"
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
@ -148,6 +154,7 @@ static int gzip_compression_level = 6;
|
|||||||
/*
|
/*
|
||||||
* The data payload of an individual Gzip Filter IsoStream
|
* The data payload of an individual Gzip Filter IsoStream
|
||||||
*/
|
*/
|
||||||
|
/* IMPORTANT: Any change must be reflected by gzip_clone_stream() */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
IsoStream *orig;
|
IsoStream *orig;
|
||||||
@ -524,12 +531,51 @@ 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
|
static
|
||||||
int gzip_cmp_ino(IsoStream *s1, IsoStream *s2);
|
int gzip_cmp_ino(IsoStream *s1, IsoStream *s2);
|
||||||
|
|
||||||
|
|
||||||
IsoStreamIface gzip_stream_compress_class = {
|
IsoStreamIface gzip_stream_compress_class = {
|
||||||
3,
|
4,
|
||||||
"gzip",
|
"gzip",
|
||||||
gzip_stream_open,
|
gzip_stream_open,
|
||||||
gzip_stream_close,
|
gzip_stream_close,
|
||||||
@ -540,12 +586,13 @@ IsoStreamIface gzip_stream_compress_class = {
|
|||||||
gzip_stream_free,
|
gzip_stream_free,
|
||||||
gzip_update_size,
|
gzip_update_size,
|
||||||
gzip_get_input_stream,
|
gzip_get_input_stream,
|
||||||
gzip_cmp_ino
|
gzip_cmp_ino,
|
||||||
|
gzip_clone_stream
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
IsoStreamIface gzip_stream_uncompress_class = {
|
IsoStreamIface gzip_stream_uncompress_class = {
|
||||||
3,
|
4,
|
||||||
"pizg",
|
"pizg",
|
||||||
gzip_stream_open,
|
gzip_stream_open,
|
||||||
gzip_stream_close,
|
gzip_stream_close,
|
||||||
@ -556,7 +603,8 @@ IsoStreamIface gzip_stream_uncompress_class = {
|
|||||||
gzip_stream_free,
|
gzip_stream_free,
|
||||||
gzip_update_size,
|
gzip_update_size,
|
||||||
gzip_get_input_stream,
|
gzip_get_input_stream,
|
||||||
gzip_cmp_ino
|
gzip_cmp_ino,
|
||||||
|
gzip_clone_stream
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,187 +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 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;
|
|
||||||
}
|
|
@ -1,9 +1,10 @@
|
|||||||
/*
|
/*
|
||||||
* 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
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
*
|
*
|
||||||
* It implements a filter facility which can pipe a IsoStream into zisofs
|
* It implements a filter facility which can pipe a IsoStream into zisofs
|
||||||
* compression resp. uncompression, read its output and forward it as IsoStream
|
* compression resp. uncompression, read its output and forward it as IsoStream
|
||||||
@ -13,10 +14,15 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "../libisofs.h"
|
#include "../libisofs.h"
|
||||||
#include "../filter.h"
|
#include "../filter.h"
|
||||||
#include "../fsource.h"
|
#include "../fsource.h"
|
||||||
#include "../util.h"
|
#include "../util.h"
|
||||||
|
#include "../stream.h"
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
@ -162,6 +168,7 @@ static int ziso_compression_level = 6;
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* The common data payload of an individual Zisofs Filter IsoStream
|
* The common data payload of an individual Zisofs Filter IsoStream
|
||||||
|
* IMPORTANT: Any change must be reflected by ziso_clone_stream().
|
||||||
*/
|
*/
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@ -178,6 +185,7 @@ typedef struct
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* The data payload of an individual Zisofs Filter Compressor IsoStream
|
* The data payload of an individual Zisofs Filter Compressor IsoStream
|
||||||
|
* IMPORTANT: Any change must be reflected by ziso_clone_stream().
|
||||||
*/
|
*/
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@ -193,6 +201,7 @@ typedef struct
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* The data payload of an individual Zisofs Filter Uncompressor IsoStream
|
* The data payload of an individual Zisofs Filter Uncompressor IsoStream
|
||||||
|
* IMPORTANT: Any change must be reflected by ziso_clone_stream().
|
||||||
*/
|
*/
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@ -774,13 +783,63 @@ IsoStream *ziso_get_input_stream(IsoStream *stream, int flag)
|
|||||||
return data->orig;
|
return data->orig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int ziso_clone_stream(IsoStream *old_stream, IsoStream **new_stream, int flag)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
IsoStream *new_input_stream = NULL, *stream = NULL;
|
||||||
|
ZisofsFilterStreamData *stream_data, *old_stream_data;
|
||||||
|
ZisofsUncomprStreamData *uncompr, *old_uncompr;
|
||||||
|
ZisofsComprStreamData *compr, *old_compr;
|
||||||
|
|
||||||
|
if (flag)
|
||||||
|
return ISO_STREAM_NO_CLONE; /* unknown option required */
|
||||||
|
|
||||||
|
ret = iso_stream_clone_filter_common(old_stream, &stream,
|
||||||
|
&new_input_stream, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (old_stream->class->read == &ziso_stream_uncompress) {
|
||||||
|
uncompr = calloc(1, sizeof(ZisofsUncomprStreamData));
|
||||||
|
if (uncompr == NULL)
|
||||||
|
goto no_mem;
|
||||||
|
stream_data = (ZisofsFilterStreamData *) uncompr;
|
||||||
|
old_uncompr = (ZisofsUncomprStreamData *) old_stream->data;
|
||||||
|
uncompr->header_size_div4 = old_uncompr->header_size_div4;
|
||||||
|
uncompr->block_size_log2 = old_uncompr->block_size_log2;
|
||||||
|
} else {
|
||||||
|
compr = calloc(1, sizeof(ZisofsComprStreamData));
|
||||||
|
if (compr == NULL)
|
||||||
|
goto no_mem;
|
||||||
|
stream_data = (ZisofsFilterStreamData *) compr;
|
||||||
|
old_compr = (ZisofsComprStreamData *) old_stream->data;
|
||||||
|
compr->orig_size = old_compr->orig_size;
|
||||||
|
compr->block_pointers = NULL;
|
||||||
|
}
|
||||||
|
old_stream_data = (ZisofsFilterStreamData *) old_stream->data;
|
||||||
|
stream_data->orig = new_input_stream;
|
||||||
|
stream_data->size = old_stream_data->size;
|
||||||
|
stream_data->running = NULL;
|
||||||
|
stream_data->id = ++ziso_ino_id;
|
||||||
|
stream->data = stream_data;
|
||||||
|
*new_stream = stream;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
no_mem:
|
||||||
|
if (new_input_stream != NULL)
|
||||||
|
iso_stream_unref(new_input_stream);
|
||||||
|
if (stream != NULL)
|
||||||
|
iso_stream_unref(stream);
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
int ziso_cmp_ino(IsoStream *s1, IsoStream *s2);
|
int ziso_cmp_ino(IsoStream *s1, IsoStream *s2);
|
||||||
|
|
||||||
|
|
||||||
IsoStreamIface ziso_stream_compress_class = {
|
IsoStreamIface ziso_stream_compress_class = {
|
||||||
3,
|
4,
|
||||||
"ziso",
|
"ziso",
|
||||||
ziso_stream_open,
|
ziso_stream_open,
|
||||||
ziso_stream_close,
|
ziso_stream_close,
|
||||||
@ -791,12 +850,13 @@ IsoStreamIface ziso_stream_compress_class = {
|
|||||||
ziso_stream_free,
|
ziso_stream_free,
|
||||||
ziso_update_size,
|
ziso_update_size,
|
||||||
ziso_get_input_stream,
|
ziso_get_input_stream,
|
||||||
ziso_cmp_ino
|
ziso_cmp_ino,
|
||||||
|
ziso_clone_stream
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
IsoStreamIface ziso_stream_uncompress_class = {
|
IsoStreamIface ziso_stream_uncompress_class = {
|
||||||
3,
|
4,
|
||||||
"osiz",
|
"osiz",
|
||||||
ziso_stream_open,
|
ziso_stream_open,
|
||||||
ziso_stream_close,
|
ziso_stream_close,
|
||||||
@ -807,7 +867,8 @@ IsoStreamIface ziso_stream_uncompress_class = {
|
|||||||
ziso_stream_free,
|
ziso_stream_free,
|
||||||
ziso_update_size,
|
ziso_update_size,
|
||||||
ziso_get_input_stream,
|
ziso_get_input_stream,
|
||||||
ziso_cmp_ino
|
ziso_cmp_ino,
|
||||||
|
ziso_clone_stream
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -825,6 +886,9 @@ int ziso_cmp_ino(IsoStream *s1, IsoStream *s2)
|
|||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef Libisofs_with_zliB
|
||||||
|
|
||||||
static
|
static
|
||||||
void ziso_filter_free(FilterContext *filter)
|
void ziso_filter_free(FilterContext *filter)
|
||||||
{
|
{
|
||||||
@ -938,6 +1002,7 @@ int ziso_create_context(FilterContext **filter, int flag)
|
|||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* Libisofs_with_zliB */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @param flag bit0= if_block_reduction rather than if_reduction
|
* @param flag bit0= if_block_reduction rather than if_reduction
|
||||||
|
@ -2,10 +2,15 @@
|
|||||||
* Copyright (c) 2008 Vreixo Formoso
|
* Copyright (c) 2008 Vreixo Formoso
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libisofs.h"
|
#include "libisofs.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
|
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
* 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
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -12,6 +13,10 @@
|
|||||||
* IsoDataSource to read image data.
|
* IsoDataSource to read image data.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libisofs.h"
|
#include "libisofs.h"
|
||||||
#include "ecma119.h"
|
#include "ecma119.h"
|
||||||
#include "messages.h"
|
#include "messages.h"
|
||||||
@ -62,7 +67,7 @@ struct iso_read_opts
|
|||||||
unsigned int nojoliet : 1; /*< Do not read Joliet extensions */
|
unsigned int nojoliet : 1; /*< Do not read Joliet extensions */
|
||||||
unsigned int noiso1999 : 1; /*< Do not read ISO 9660:1999 enhanced tree */
|
unsigned int noiso1999 : 1; /*< Do not read ISO 9660:1999 enhanced tree */
|
||||||
unsigned int noaaip : 1; /* Do not read AAIP extension for xattr and ACL */
|
unsigned int noaaip : 1; /* Do not read AAIP extension for xattr and ACL */
|
||||||
unsigned int nomd5 : 1; /* Do not read MD5 array */
|
unsigned int nomd5 : 2; /* Do not read MD5 array */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hand out new inode numbers and overwrite eventually read PX inode
|
* Hand out new inode numbers and overwrite eventually read PX inode
|
||||||
@ -96,6 +101,12 @@ struct iso_read_opts
|
|||||||
*/
|
*/
|
||||||
int auto_input_charset;
|
int auto_input_charset;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable or disable loading of the first 32768 bytes of the session and
|
||||||
|
* submission by iso_write_opts_set_system_area(data, 0).
|
||||||
|
*/
|
||||||
|
int load_system_area;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -251,7 +262,7 @@ typedef struct
|
|||||||
int aaip_load;
|
int aaip_load;
|
||||||
|
|
||||||
/** Whether the MD5 array shall be read if available.
|
/** Whether the MD5 array shall be read if available.
|
||||||
* 1 = yes , 0 = no
|
* 2 = yes, but do not check tags , 1 = yes , 0 = no
|
||||||
*/
|
*/
|
||||||
int md5_load;
|
int md5_load;
|
||||||
|
|
||||||
@ -267,12 +278,20 @@ typedef struct
|
|||||||
|
|
||||||
/* el-torito information */
|
/* el-torito information */
|
||||||
unsigned int eltorito : 1; /* is el-torito available */
|
unsigned int eltorito : 1; /* is el-torito available */
|
||||||
unsigned int bootable:1; /**< If the entry is bootable. */
|
int num_bootimgs;
|
||||||
unsigned char type; /**< The type of image */
|
unsigned char platform_ids[Libisofs_max_boot_imageS];
|
||||||
unsigned char partition_type; /**< type of partition for HD-emul images */
|
unsigned char id_strings[Libisofs_max_boot_imageS][28];
|
||||||
short load_seg; /**< Load segment for the initial boot image. */
|
unsigned char selection_crits[Libisofs_max_boot_imageS][20];
|
||||||
short load_size; /**< Number of sectors to load. */
|
unsigned char boot_flags[Libisofs_max_boot_imageS]; /* bit0= bootable */
|
||||||
uint32_t imgblock; /**< Block for El-Torito boot image */
|
unsigned char media_types[Libisofs_max_boot_imageS];
|
||||||
|
unsigned char partition_types[Libisofs_max_boot_imageS];
|
||||||
|
short load_segs[Libisofs_max_boot_imageS];
|
||||||
|
short load_sizes[Libisofs_max_boot_imageS];
|
||||||
|
/** Block addresses of for El-Torito boot images.
|
||||||
|
Needed to recognize them when the get read from the directory tree.
|
||||||
|
*/
|
||||||
|
uint32_t bootblocks[Libisofs_max_boot_imageS];
|
||||||
|
|
||||||
uint32_t catblock; /**< Block for El-Torito catalog */
|
uint32_t catblock; /**< Block for El-Torito catalog */
|
||||||
|
|
||||||
/* Whether inode numbers from PX entries shall be discarded */
|
/* Whether inode numbers from PX entries shall be discarded */
|
||||||
@ -293,6 +312,7 @@ typedef struct
|
|||||||
|
|
||||||
typedef struct image_fs_data ImageFileSourceData;
|
typedef struct image_fs_data ImageFileSourceData;
|
||||||
|
|
||||||
|
/* IMPORTANT: Any change must be reflected by ifs_clone_src */
|
||||||
struct image_fs_data
|
struct image_fs_data
|
||||||
{
|
{
|
||||||
IsoImageFilesystem *fs; /**< reference to the image it belongs to */
|
IsoImageFilesystem *fs; /**< reference to the image it belongs to */
|
||||||
@ -369,9 +389,19 @@ char* ifs_get_path(IsoFileSource *src)
|
|||||||
if (data->parent == NULL) {
|
if (data->parent == NULL) {
|
||||||
return strdup("");
|
return strdup("");
|
||||||
} else {
|
} else {
|
||||||
char *path = ifs_get_path(data->parent);
|
char *path, *new_path;
|
||||||
int pathlen = strlen(path);
|
int pathlen;
|
||||||
path = realloc(path, pathlen + strlen(data->name) + 2);
|
|
||||||
|
path = ifs_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;
|
||||||
path[pathlen] = '/';
|
path[pathlen] = '/';
|
||||||
path[pathlen + 1] = '\0';
|
path[pathlen + 1] = '\0';
|
||||||
return strcat(path, data->name);
|
return strcat(path, data->name);
|
||||||
@ -918,6 +948,7 @@ int ifs_readlink(IsoFileSource *src, char *buf, size_t bufsiz)
|
|||||||
{
|
{
|
||||||
char *dest;
|
char *dest;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
int ret;
|
||||||
ImageFileSourceData *data;
|
ImageFileSourceData *data;
|
||||||
|
|
||||||
if (src == NULL || buf == NULL || src->data == NULL) {
|
if (src == NULL || buf == NULL || src->data == NULL) {
|
||||||
@ -936,14 +967,15 @@ int ifs_readlink(IsoFileSource *src, char *buf, size_t bufsiz)
|
|||||||
|
|
||||||
dest = (char*)data->data.content;
|
dest = (char*)data->data.content;
|
||||||
len = strlen(dest);
|
len = strlen(dest);
|
||||||
if (bufsiz <= len) {
|
|
||||||
|
ret = ISO_SUCCESS;
|
||||||
|
if (len >= bufsiz) {
|
||||||
|
ret = ISO_RR_PATH_TOO_LONG;
|
||||||
len = bufsiz - 1;
|
len = bufsiz - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
strncpy(buf, dest, len);
|
strncpy(buf, dest, len);
|
||||||
buf[len] = '\0';
|
buf[len] = '\0';
|
||||||
|
return ret;
|
||||||
return ISO_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
@ -1009,10 +1041,87 @@ int ifs_get_aa_string(IsoFileSource *src, unsigned char **aa_string, int flag)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int ifs_clone_src(IsoFileSource *old_source,
|
||||||
|
IsoFileSource **new_source, int flag)
|
||||||
|
{
|
||||||
|
IsoFileSource *src = NULL;
|
||||||
|
ImageFileSourceData *old_data, *new_data = NULL;
|
||||||
|
char *new_name = NULL;
|
||||||
|
struct iso_file_section *new_sections = NULL;
|
||||||
|
void *new_aa_string = NULL;
|
||||||
|
int i, ret;
|
||||||
|
|
||||||
|
if (flag)
|
||||||
|
return ISO_STREAM_NO_CLONE; /* unknown option required */
|
||||||
|
|
||||||
|
old_data = (ImageFileSourceData *) 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(ImageFileSourceData));
|
||||||
|
|
||||||
|
if (new_data == NULL)
|
||||||
|
goto no_mem;
|
||||||
|
if (old_data->nsections > 0) {
|
||||||
|
new_sections = calloc(old_data->nsections,
|
||||||
|
sizeof(struct iso_file_section));
|
||||||
|
if (new_sections == NULL)
|
||||||
|
goto no_mem;
|
||||||
|
}
|
||||||
|
ret = aaip_xinfo_cloner(old_data->aa_string, &new_aa_string, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
goto no_mem;
|
||||||
|
|
||||||
|
new_data->fs = old_data->fs;
|
||||||
|
|
||||||
|
new_data->parent = old_data->parent;
|
||||||
|
|
||||||
|
memcpy(&(new_data->info), &(old_data->info), sizeof(struct stat));
|
||||||
|
new_data->name = new_name;
|
||||||
|
new_data->sections = new_sections;
|
||||||
|
new_data->nsections = old_data->nsections;
|
||||||
|
for (i = 0; i < new_data->nsections; i++)
|
||||||
|
memcpy(new_data->sections + i, old_data->sections + i,
|
||||||
|
sizeof(struct iso_file_section));
|
||||||
|
new_data->opened = old_data->opened;
|
||||||
|
#ifdef Libisofs_with_zliB
|
||||||
|
new_data->header_size_div4 = old_data->header_size_div4;
|
||||||
|
new_data->block_size_log2 = old_data->block_size_log2;
|
||||||
|
new_data->uncompressed_size = old_data->uncompressed_size;
|
||||||
|
#endif
|
||||||
|
new_data->data.content = NULL;
|
||||||
|
new_data->aa_string = (unsigned char *) new_aa_string;
|
||||||
|
|
||||||
|
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(new_data->fs);
|
||||||
|
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);
|
||||||
|
if (new_sections != NULL)
|
||||||
|
free((char *) new_sections);
|
||||||
|
if (new_aa_string != NULL)
|
||||||
|
aaip_xinfo_func(new_aa_string, 1);
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
IsoFileSourceIface ifs_class = {
|
IsoFileSourceIface ifs_class = {
|
||||||
|
|
||||||
1, /* version */
|
2, /* version */
|
||||||
ifs_get_path,
|
ifs_get_path,
|
||||||
ifs_get_name,
|
ifs_get_name,
|
||||||
ifs_lstat,
|
ifs_lstat,
|
||||||
@ -1026,7 +1135,8 @@ IsoFileSourceIface ifs_class = {
|
|||||||
ifs_get_filesystem,
|
ifs_get_filesystem,
|
||||||
ifs_free,
|
ifs_free,
|
||||||
ifs_lseek,
|
ifs_lseek,
|
||||||
ifs_get_aa_string
|
ifs_get_aa_string,
|
||||||
|
ifs_clone_src
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1489,6 +1599,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
|||||||
sprintf(msg,
|
sprintf(msg,
|
||||||
"Character set name recorded in ISO image: '%.80s'",
|
"Character set name recorded in ISO image: '%.80s'",
|
||||||
cs_value);
|
cs_value);
|
||||||
|
free(cs_value);
|
||||||
}
|
}
|
||||||
iso_msgs_submit(0, msg, 0, "NOTE", 0);
|
iso_msgs_submit(0, msg, 0, "NOTE", 0);
|
||||||
cs_value = NULL;
|
cs_value = NULL;
|
||||||
@ -2100,19 +2211,15 @@ int read_root_susp_entries(_ImageFsData *data, uint32_t block)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
int read_pvm(_ImageFsData *data, uint32_t block)
|
int read_pvd_block(IsoDataSource *src, uint32_t block, uint8_t *buffer,
|
||||||
|
uint32_t *image_size)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct ecma119_pri_vol_desc *pvm;
|
struct ecma119_pri_vol_desc *pvm;
|
||||||
struct ecma119_dir_record *rootdr;
|
|
||||||
uint8_t buffer[BLOCK_SIZE];
|
|
||||||
|
|
||||||
/* read PVM */
|
ret = src->read_block(src, block, buffer);
|
||||||
ret = data->src->read_block(data->src, block, buffer);
|
if (ret < 0)
|
||||||
if (ret < 0) {
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
|
||||||
|
|
||||||
pvm = (struct ecma119_pri_vol_desc *)buffer;
|
pvm = (struct ecma119_pri_vol_desc *)buffer;
|
||||||
|
|
||||||
/* sanity checks */
|
/* sanity checks */
|
||||||
@ -2122,8 +2229,24 @@ int read_pvm(_ImageFsData *data, uint32_t block)
|
|||||||
|
|
||||||
return ISO_WRONG_PVD;
|
return ISO_WRONG_PVD;
|
||||||
}
|
}
|
||||||
|
if (image_size != NULL)
|
||||||
|
*image_size = iso_read_bb(pvm->vol_space_size, 4, NULL);
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int read_pvm(_ImageFsData *data, uint32_t block)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct ecma119_pri_vol_desc *pvm;
|
||||||
|
struct ecma119_dir_record *rootdr;
|
||||||
|
uint8_t buffer[BLOCK_SIZE];
|
||||||
|
|
||||||
|
ret = read_pvd_block(data->src, block, buffer, NULL);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
/* ok, it is a valid PVD */
|
/* ok, it is a valid PVD */
|
||||||
|
pvm = (struct ecma119_pri_vol_desc *)buffer;
|
||||||
|
|
||||||
/* fill volume attributes */
|
/* fill volume attributes */
|
||||||
/* TODO take care of input charset */
|
/* TODO take care of input charset */
|
||||||
@ -2179,11 +2302,13 @@ int read_pvm(_ImageFsData *data, uint32_t block)
|
|||||||
static
|
static
|
||||||
int read_el_torito_boot_catalog(_ImageFsData *data, uint32_t block)
|
int read_el_torito_boot_catalog(_ImageFsData *data, uint32_t block)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret, i, rx, last_done, idx;
|
||||||
struct el_torito_validation_entry *ve;
|
struct el_torito_validation_entry *ve;
|
||||||
struct el_torito_default_entry *entry;
|
struct el_torito_section_header *sh;
|
||||||
|
struct el_torito_section_entry *entry; /* also usable as default_entry */
|
||||||
unsigned char buffer[BLOCK_SIZE];
|
unsigned char buffer[BLOCK_SIZE];
|
||||||
|
|
||||||
|
data->num_bootimgs = 0;
|
||||||
ret = data->src->read_block(data->src, block, buffer);
|
ret = data->src->read_block(data->src, block, buffer);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
@ -2194,34 +2319,70 @@ int read_el_torito_boot_catalog(_ImageFsData *data, uint32_t block)
|
|||||||
/* check if it is a valid catalog (TODO: check also the checksum)*/
|
/* check if it is a valid catalog (TODO: check also the checksum)*/
|
||||||
if ( (ve->header_id[0] != 1) || (ve->key_byte1[0] != 0x55)
|
if ( (ve->header_id[0] != 1) || (ve->key_byte1[0] != 0x55)
|
||||||
|| (ve->key_byte2[0] != 0xAA) ) {
|
|| (ve->key_byte2[0] != 0xAA) ) {
|
||||||
|
iso_msg_submit(data->msgid, ISO_WRONG_EL_TORITO, 0,
|
||||||
return iso_msg_submit(data->msgid, ISO_WRONG_EL_TORITO, 0,
|
|
||||||
"Wrong or damaged El-Torito Catalog. El-Torito info "
|
"Wrong or damaged El-Torito Catalog. El-Torito info "
|
||||||
"will be ignored.");
|
"will be ignored.");
|
||||||
|
return ISO_WRONG_EL_TORITO;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check for a valid platform */
|
/* check for a valid platform */
|
||||||
if (ve->platform_id[0] != 0) {
|
if (ve->platform_id[0] != 0 && ve->platform_id[0] != 0xef) {
|
||||||
return iso_msg_submit(data->msgid, ISO_UNSUPPORTED_EL_TORITO, 0,
|
iso_msg_submit(data->msgid, ISO_UNSUPPORTED_EL_TORITO, 0,
|
||||||
"Unsupported El-Torito platform. Only 80x86 is "
|
"Unsupported El-Torito platform. Only 80x86 and EFI are "
|
||||||
"supported. El-Torito info will be ignored.");
|
"supported. El-Torito info will be ignored.");
|
||||||
|
return ISO_UNSUPPORTED_EL_TORITO;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ok, once we are here we assume it is a valid catalog */
|
/* ok, once we are here we assume it is a valid catalog */
|
||||||
|
|
||||||
/* parse the default entry */
|
/* parse the default entry */
|
||||||
entry = (struct el_torito_default_entry *)(buffer + 32);
|
entry = (struct el_torito_section_entry *)(buffer + 32);
|
||||||
|
|
||||||
data->eltorito = 1;
|
data->eltorito = 1;
|
||||||
data->bootable = entry->boot_indicator[0] ? 1 : 0;
|
/* The Default Entry is declared mandatory */
|
||||||
data->type = entry->boot_media_type[0];
|
data->num_bootimgs = 1;
|
||||||
data->partition_type = entry->system_type[0];
|
data->platform_ids[0] = ve->platform_id[0];
|
||||||
data->load_seg = iso_read_lsb(entry->load_seg, 2);
|
memcpy(data->id_strings[0], ve->id_string, 24);
|
||||||
data->load_size = iso_read_lsb(entry->sec_count, 2);
|
memset(data->id_strings[0] + 24, 0, 4);
|
||||||
data->imgblock = iso_read_lsb(entry->block, 4);
|
data->boot_flags[0] = entry->boot_indicator[0] ? 1 : 0;
|
||||||
|
data->media_types[0] = entry->boot_media_type[0];
|
||||||
/* TODO #00018 : check if there are more entries in the boot catalog */
|
data->partition_types[0] = entry->system_type[0];
|
||||||
|
data->load_segs[0] = iso_read_lsb(entry->load_seg, 2);
|
||||||
|
data->load_sizes[0] = iso_read_lsb(entry->sec_count, 2);
|
||||||
|
data->bootblocks[0] = iso_read_lsb(entry->block, 4);
|
||||||
|
/* The Default Entry has no selection criterion */
|
||||||
|
memset(data->selection_crits[0], 0, 20);
|
||||||
|
|
||||||
|
/* Read eventual more entries from the boot catalog */
|
||||||
|
last_done = 0;
|
||||||
|
for (rx = 64; (buffer[rx] & 0xfe) == 0x90 && !last_done; rx += 32) {
|
||||||
|
last_done = buffer[rx] & 1;
|
||||||
|
/* Read Section Header */
|
||||||
|
sh = (struct el_torito_section_header *) (buffer + rx);
|
||||||
|
for (i = 0; i < sh->num_entries[0]; i++) {
|
||||||
|
rx += 32;
|
||||||
|
if (data->num_bootimgs >= Libisofs_max_boot_imageS) {
|
||||||
|
ret = iso_msg_submit(data->msgid, ISO_EL_TORITO_WARN, 0,
|
||||||
|
"Too many boot images found. List truncated.");
|
||||||
|
goto after_bootblocks;
|
||||||
|
}
|
||||||
|
/* Read bootblock from section entry */
|
||||||
|
entry = (struct el_torito_section_entry *)(buffer + rx);
|
||||||
|
idx = data->num_bootimgs;
|
||||||
|
data->platform_ids[idx] = sh->platform_id[0];
|
||||||
|
memcpy(data->id_strings[idx], sh->id_string, 28);
|
||||||
|
data->boot_flags[idx] = entry->boot_indicator[0] ? 1 : 0;
|
||||||
|
data->media_types[idx] = entry->boot_media_type[0];
|
||||||
|
data->partition_types[idx] = entry->system_type[0];
|
||||||
|
data->load_segs[idx] = iso_read_lsb(entry->load_seg, 2);
|
||||||
|
data->load_sizes[idx] = iso_read_lsb(entry->sec_count, 2);
|
||||||
|
data->bootblocks[idx] = iso_read_lsb(entry->block, 4);
|
||||||
|
data->selection_crits[idx][0] = entry->selec_criteria[0];
|
||||||
|
memcpy(data->selection_crits[idx] + 1, entry->vendor_sc, 19);
|
||||||
|
data->num_bootimgs++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
after_bootblocks:;
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2255,6 +2416,10 @@ int iso_src_check_sb_tree(IsoDataSource *src, uint32_t start_lba, int flag)
|
|||||||
ret = iso_util_eval_md5_tag(block, desired, start_lba + i,
|
ret = iso_util_eval_md5_tag(block, desired, start_lba + i,
|
||||||
ctx, start_lba, &tag_type, &next_tag, 0);
|
ctx, start_lba, &tag_type, &next_tag, 0);
|
||||||
iso_md5_compute(ctx, block, 2048);
|
iso_md5_compute(ctx, block, 2048);
|
||||||
|
if (ret == ISO_MD5_TAG_COPIED) { /* growing without emulated TOC */
|
||||||
|
ret = 2;
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
if (ret == ISO_MD5_AREA_CORRUPTED || ret == ISO_MD5_TAG_MISMATCH)
|
if (ret == ISO_MD5_AREA_CORRUPTED || ret == ISO_MD5_TAG_MISMATCH)
|
||||||
ret = ISO_SB_TREE_CORRUPTED;
|
ret = ISO_SB_TREE_CORRUPTED;
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
@ -2305,7 +2470,7 @@ ex:
|
|||||||
int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
|
int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
|
||||||
int msgid, IsoImageFilesystem **fs)
|
int msgid, IsoImageFilesystem **fs)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret, i;
|
||||||
uint32_t block;
|
uint32_t block;
|
||||||
IsoImageFilesystem *ifs;
|
IsoImageFilesystem *ifs;
|
||||||
_ImageFsData *data;
|
_ImageFsData *data;
|
||||||
@ -2341,12 +2506,21 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
|
|||||||
data->dir_mode = opts->dir_mode & ~S_IFMT;
|
data->dir_mode = opts->dir_mode & ~S_IFMT;
|
||||||
data->msgid = msgid;
|
data->msgid = msgid;
|
||||||
data->aaip_load = !opts->noaaip;
|
data->aaip_load = !opts->noaaip;
|
||||||
data->md5_load = !opts->nomd5;
|
if (opts->nomd5 == 0)
|
||||||
|
data->md5_load = 1;
|
||||||
|
else if (opts->nomd5 == 2)
|
||||||
|
data->md5_load = 2;
|
||||||
|
else
|
||||||
|
data->md5_load = 0;
|
||||||
data->aaip_version = -1;
|
data->aaip_version = -1;
|
||||||
data->make_new_ino = opts->make_new_ino;
|
data->make_new_ino = opts->make_new_ino;
|
||||||
|
data->num_bootimgs = 0;
|
||||||
|
for (i = 0; i < Libisofs_max_boot_imageS; i++)
|
||||||
|
data->bootblocks[i] = 0;
|
||||||
data->inode_counter = 0;
|
data->inode_counter = 0;
|
||||||
data->px_ino_status = 0;
|
data->px_ino_status = 0;
|
||||||
|
|
||||||
|
|
||||||
data->local_charset = strdup(iso_get_local_charset(0));
|
data->local_charset = strdup(iso_get_local_charset(0));
|
||||||
if (data->local_charset == NULL) {
|
if (data->local_charset == NULL) {
|
||||||
ret = ISO_OUT_OF_MEM;
|
ret = ISO_OUT_OF_MEM;
|
||||||
@ -2365,10 +2539,7 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
|
|||||||
ifs->free = ifs_fs_free;
|
ifs->free = ifs_fs_free;
|
||||||
|
|
||||||
/* read Volume Descriptors and ensure it is a valid image */
|
/* read Volume Descriptors and ensure it is a valid image */
|
||||||
|
if (data->md5_load == 1) {
|
||||||
#ifdef Libisofs_with_checksumS
|
|
||||||
|
|
||||||
if (data->md5_load) {
|
|
||||||
/* From opts->block on : check for superblock and tree tags */;
|
/* From opts->block on : check for superblock and tree tags */;
|
||||||
ret = iso_src_check_sb_tree(src, opts->block, 0);
|
ret = iso_src_check_sb_tree(src, opts->block, 0);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@ -2382,8 +2553,6 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Libisofs_with_checksumS */
|
|
||||||
|
|
||||||
/* 1. first, open the filesystem */
|
/* 1. first, open the filesystem */
|
||||||
ifs_fs_open(ifs);
|
ifs_fs_open(ifs);
|
||||||
|
|
||||||
@ -2413,21 +2582,18 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
|
|||||||
|| vol->vol_desc_version[0] != 1
|
|| vol->vol_desc_version[0] != 1
|
||||||
|| strncmp((char*)vol->boot_sys_id,
|
|| strncmp((char*)vol->boot_sys_id,
|
||||||
"EL TORITO SPECIFICATION", 23)) {
|
"EL TORITO SPECIFICATION", 23)) {
|
||||||
|
iso_msg_submit(data->msgid,
|
||||||
ret = iso_msg_submit(data->msgid,
|
|
||||||
ISO_UNSUPPORTED_EL_TORITO, 0,
|
ISO_UNSUPPORTED_EL_TORITO, 0,
|
||||||
"Unsupported Boot Vol. Desc. Only El-Torito "
|
"Unsupported Boot Vol. Desc. Only El-Torito "
|
||||||
"Specification, Version 1.0 Volume "
|
"Specification, Version 1.0 Volume "
|
||||||
"Descriptors are supported. Ignoring boot info");
|
"Descriptors are supported. Ignoring boot info");
|
||||||
if (ret < 0) {
|
} else {
|
||||||
|
data->catblock = iso_read_lsb(vol->boot_catalog, 4);
|
||||||
|
ret = read_el_torito_boot_catalog(data, data->catblock);
|
||||||
|
if (ret < 0 && ret != ISO_UNSUPPORTED_EL_TORITO &&
|
||||||
|
ret != ISO_WRONG_EL_TORITO) {
|
||||||
goto fs_cleanup;
|
goto fs_cleanup;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
data->catblock = iso_read_lsb(vol->boot_catalog, 4);
|
|
||||||
ret = read_el_torito_boot_catalog(data, data->catblock);
|
|
||||||
if (ret < 0) {
|
|
||||||
goto fs_cleanup;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -2477,11 +2643,8 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
|
|||||||
*/
|
*/
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ret = iso_msg_submit(data->msgid, ISO_UNSUPPORTED_VD, 0,
|
iso_msg_submit(data->msgid, ISO_UNSUPPORTED_VD, 0,
|
||||||
"Ignoring Volume descriptor %x.", buffer[0]);
|
"Ignoring Volume descriptor %x.", buffer[0]);
|
||||||
if (ret < 0) {
|
|
||||||
goto fs_cleanup;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
block++;
|
block++;
|
||||||
@ -2601,7 +2764,7 @@ static
|
|||||||
int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
||||||
IsoFileSource *src, IsoNode **node)
|
IsoFileSource *src, IsoNode **node)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret, idx;
|
||||||
struct stat info;
|
struct stat info;
|
||||||
IsoNode *new;
|
IsoNode *new;
|
||||||
char *name;
|
char *name;
|
||||||
@ -2713,11 +2876,25 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
new = (IsoNode*) file;
|
new = (IsoNode*) file;
|
||||||
new->refcount = 0;
|
new->refcount = 0;
|
||||||
|
|
||||||
if (fsdata->eltorito && data->sections[0].block == fsdata->imgblock) {
|
for (idx = 0; idx < fsdata->num_bootimgs; idx++)
|
||||||
|
if (fsdata->eltorito && data->sections[0].block ==
|
||||||
|
fsdata->bootblocks[idx])
|
||||||
|
break;
|
||||||
|
if (idx < fsdata->num_bootimgs) {
|
||||||
/* it is boot image node */
|
/* it is boot image node */
|
||||||
if (image->bootcat->image->image != NULL) {
|
if (image->bootcat->bootimages[idx]->image != NULL) {
|
||||||
|
/* idx is already occupied, try to find unoccupied one
|
||||||
|
which has the same block address.
|
||||||
|
*/
|
||||||
|
for (; idx < fsdata->num_bootimgs; idx++)
|
||||||
|
if (fsdata->eltorito && data->sections[0].block ==
|
||||||
|
fsdata->bootblocks[idx] &&
|
||||||
|
image->bootcat->bootimages[idx]->image == NULL)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (idx >= fsdata->num_bootimgs) {
|
||||||
ret = iso_msg_submit(image->id, ISO_EL_TORITO_WARN, 0,
|
ret = iso_msg_submit(image->id, ISO_EL_TORITO_WARN, 0,
|
||||||
"More than one image node has been found.");
|
"More than one ISO node has been found for the same boot image.");
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
free(name);
|
free(name);
|
||||||
iso_stream_unref(stream);
|
iso_stream_unref(stream);
|
||||||
@ -2725,7 +2902,7 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* and set the image node */
|
/* and set the image node */
|
||||||
image->bootcat->image->image = file;
|
image->bootcat->bootimages[idx]->image = file;
|
||||||
new->refcount++;
|
new->refcount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2747,10 +2924,10 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
case S_IFLNK:
|
case S_IFLNK:
|
||||||
{
|
{
|
||||||
/* source is a symbolic link */
|
/* source is a symbolic link */
|
||||||
char dest[PATH_MAX];
|
char dest[LIBISOFS_NODE_PATH_MAX];
|
||||||
IsoSymlink *link;
|
IsoSymlink *link;
|
||||||
|
|
||||||
ret = iso_file_source_readlink(src, dest, PATH_MAX);
|
ret = iso_file_source_readlink(src, dest, LIBISOFS_NODE_PATH_MAX);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
free(name);
|
free(name);
|
||||||
return ret;
|
return ret;
|
||||||
@ -2865,7 +3042,7 @@ int iso_image_builder_new(IsoNodeBuilder *old, IsoNodeBuilder **builder)
|
|||||||
* accessible from the ISO filesystem.
|
* accessible from the ISO filesystem.
|
||||||
*/
|
*/
|
||||||
static
|
static
|
||||||
int create_boot_img_filesrc(IsoImageFilesystem *fs, IsoImage *image,
|
int create_boot_img_filesrc(IsoImageFilesystem *fs, IsoImage *image, int idx,
|
||||||
IsoFileSource **src)
|
IsoFileSource **src)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@ -2922,8 +3099,7 @@ int create_boot_img_filesrc(IsoImageFilesystem *fs, IsoImage *image,
|
|||||||
ifsdata->parent = NULL;
|
ifsdata->parent = NULL;
|
||||||
ifsdata->info = atts;
|
ifsdata->info = atts;
|
||||||
ifsdata->name = NULL;
|
ifsdata->name = NULL;
|
||||||
|
ifsdata->sections[0].block = fsdata->bootblocks[idx];
|
||||||
ifsdata->sections[0].block = fsdata->imgblock;
|
|
||||||
ifsdata->sections[0].size = BLOCK_SIZE;
|
ifsdata->sections[0].size = BLOCK_SIZE;
|
||||||
ifsdata->nsections = 1;
|
ifsdata->nsections = 1;
|
||||||
|
|
||||||
@ -2940,12 +3116,112 @@ boot_fs_cleanup: ;
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** ??? >>> ts B00428 : should the max size become public ? */
|
||||||
|
#define Libisofs_boot_image_max_sizE (4096*1024)
|
||||||
|
|
||||||
|
/** Guess which of the loaded boot images contain boot information tables.
|
||||||
|
Set boot->seems_boot_info_table accordingly.
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
int iso_image_eval_boot_info_table(IsoImage *image, struct iso_read_opts *opts,
|
||||||
|
IsoDataSource *src, uint32_t iso_image_size, int flag)
|
||||||
|
{
|
||||||
|
int i, ret, section_count, todo, chunk;
|
||||||
|
uint32_t img_lba, img_size, boot_pvd_found, image_pvd, alleged_size;
|
||||||
|
struct iso_file_section *sections = NULL;
|
||||||
|
struct el_torito_boot_image *boot;
|
||||||
|
uint8_t *boot_image_buf = NULL, boot_info_found[16], buf[BLOCK_SIZE];
|
||||||
|
IsoStream *stream = NULL;
|
||||||
|
IsoFile *boot_file;
|
||||||
|
|
||||||
|
if (image->bootcat == NULL)
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
for (i = 0; i < image->bootcat->num_bootimages; i++) {
|
||||||
|
boot = image->bootcat->bootimages[i];
|
||||||
|
boot_file = boot->image;
|
||||||
|
boot->seems_boot_info_table = 0;
|
||||||
|
img_size = iso_file_get_size(boot_file);
|
||||||
|
if (img_size > Libisofs_boot_image_max_sizE || img_size < 64)
|
||||||
|
continue;
|
||||||
|
img_lba = 0;
|
||||||
|
sections = NULL;
|
||||||
|
ret = iso_file_get_old_image_sections(boot_file,
|
||||||
|
§ion_count, §ions, 0);
|
||||||
|
if (ret == 1 && section_count > 0)
|
||||||
|
img_lba = sections[0].block;
|
||||||
|
if (sections != NULL) {
|
||||||
|
free(sections);
|
||||||
|
sections = NULL;
|
||||||
|
}
|
||||||
|
if(img_lba == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
boot_image_buf = calloc(1, img_size);
|
||||||
|
if (boot_image_buf == NULL) {
|
||||||
|
ret = ISO_OUT_OF_MEM;
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
stream = iso_file_get_stream(boot_file);
|
||||||
|
ret = iso_stream_open(stream);
|
||||||
|
if (ret < 0) {
|
||||||
|
stream = NULL;
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
for (todo = img_size; todo > 0; ) {
|
||||||
|
if (todo > BLOCK_SIZE)
|
||||||
|
chunk = BLOCK_SIZE;
|
||||||
|
else
|
||||||
|
chunk = todo;
|
||||||
|
ret = iso_stream_read(stream, boot_image_buf + (img_size - todo),
|
||||||
|
chunk);
|
||||||
|
if (ret != chunk) {
|
||||||
|
ret = (ret < 0) ? ret : ISO_FILE_READ_ERROR;
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
todo -= chunk;
|
||||||
|
}
|
||||||
|
iso_stream_close(stream);
|
||||||
|
stream = NULL;
|
||||||
|
|
||||||
|
memcpy(boot_info_found, boot_image_buf + 8, 16);
|
||||||
|
boot_pvd_found = iso_read_lsb(boot_info_found, 4);
|
||||||
|
image_pvd = (uint32_t) (opts->block + 16);
|
||||||
|
|
||||||
|
/* Accomodate to eventually relocated superblock */
|
||||||
|
if (image_pvd != boot_pvd_found &&
|
||||||
|
image_pvd == 16 && boot_pvd_found < iso_image_size) {
|
||||||
|
/* Check whether there is a PVD at boot_pvd_found
|
||||||
|
and whether it bears the same image size
|
||||||
|
*/
|
||||||
|
ret = read_pvd_block(src, boot_pvd_found, buf, &alleged_size);
|
||||||
|
if (ret == 1 &&
|
||||||
|
alleged_size + boot_pvd_found == iso_image_size + image_pvd)
|
||||||
|
image_pvd = boot_pvd_found;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = make_boot_info_table(boot_image_buf, image_pvd,
|
||||||
|
img_lba, img_size);
|
||||||
|
if (ret < 0)
|
||||||
|
goto ex;
|
||||||
|
if (memcmp(boot_image_buf + 8, boot_info_found, 16) == 0)
|
||||||
|
boot->seems_boot_info_table = 1;
|
||||||
|
free(boot_image_buf);
|
||||||
|
boot_image_buf = NULL;
|
||||||
|
}
|
||||||
|
ret = 1;
|
||||||
|
ex:;
|
||||||
|
if (boot_image_buf != NULL)
|
||||||
|
free(boot_image_buf);
|
||||||
|
if (stream != NULL)
|
||||||
|
iso_stream_close(stream);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int iso_image_import(IsoImage *image, IsoDataSource *src,
|
int iso_image_import(IsoImage *image, IsoDataSource *src,
|
||||||
struct iso_read_opts *opts,
|
struct iso_read_opts *opts,
|
||||||
IsoReadImageFeatures **features)
|
IsoReadImageFeatures **features)
|
||||||
{
|
{
|
||||||
int ret, hflag;
|
int ret, hflag, i, idx;
|
||||||
IsoImageFilesystem *fs;
|
IsoImageFilesystem *fs;
|
||||||
IsoFilesystem *fsback;
|
IsoFilesystem *fsback;
|
||||||
IsoNodeBuilder *blback;
|
IsoNodeBuilder *blback;
|
||||||
@ -2953,9 +3229,9 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
|
|||||||
IsoFileSource *newroot;
|
IsoFileSource *newroot;
|
||||||
_ImageFsData *data;
|
_ImageFsData *data;
|
||||||
struct el_torito_boot_catalog *oldbootcat;
|
struct el_torito_boot_catalog *oldbootcat;
|
||||||
|
uint8_t *rpt;
|
||||||
#ifdef Libisofs_with_checksumS
|
IsoFileSource *boot_src;
|
||||||
int i;
|
IsoNode *node;
|
||||||
uint32_t old_checksum_start_lba;
|
uint32_t old_checksum_start_lba;
|
||||||
uint32_t old_checksum_end_lba;
|
uint32_t old_checksum_end_lba;
|
||||||
uint32_t old_checksum_idx_count;
|
uint32_t old_checksum_idx_count;
|
||||||
@ -2963,21 +3239,39 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
|
|||||||
char checksum_type[81];
|
char checksum_type[81];
|
||||||
uint32_t checksum_size;
|
uint32_t checksum_size;
|
||||||
size_t size;
|
size_t size;
|
||||||
uint8_t *rpt;
|
|
||||||
void *ctx = NULL;
|
void *ctx = NULL;
|
||||||
char md5[16];
|
char md5[16];
|
||||||
#endif
|
struct el_torito_boot_catalog *catalog = NULL;
|
||||||
|
ElToritoBootImage *boot_image = NULL;
|
||||||
|
|
||||||
if (image == NULL || src == NULL || opts == NULL) {
|
if (image == NULL || src == NULL || opts == NULL) {
|
||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ret = iso_image_filesystem_new(src, opts, image->id, &fs);
|
ret = iso_image_filesystem_new(src, opts, image->id, &fs);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
data = fs->data;
|
data = fs->data;
|
||||||
|
|
||||||
|
|
||||||
|
if (opts->load_system_area) {
|
||||||
|
if (image->system_area_data != NULL)
|
||||||
|
free(image->system_area_data);
|
||||||
|
image->system_area_data = calloc(32768, 1);
|
||||||
|
if (image->system_area_data == NULL)
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
image->system_area_options = 0;
|
||||||
|
/* Read 32768 bytes */
|
||||||
|
for (i = 0; i < 16; i++) {
|
||||||
|
rpt = (uint8_t *) (image->system_area_data + i * 2048);
|
||||||
|
ret = src->read_block(src, opts->block + i, rpt);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* get root from filesystem */
|
/* get root from filesystem */
|
||||||
ret = fs->get_root(fs, &newroot);
|
ret = fs->get_root(fs, &newroot);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@ -2990,14 +3284,11 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
|
|||||||
oldroot = image->root;
|
oldroot = image->root;
|
||||||
oldbootcat = image->bootcat; /* could be NULL */
|
oldbootcat = image->bootcat; /* could be NULL */
|
||||||
image->bootcat = NULL;
|
image->bootcat = NULL;
|
||||||
|
|
||||||
#ifdef Libisofs_with_checksumS
|
|
||||||
old_checksum_start_lba = image->checksum_start_lba;
|
old_checksum_start_lba = image->checksum_start_lba;
|
||||||
old_checksum_end_lba = image->checksum_end_lba;
|
old_checksum_end_lba = image->checksum_end_lba;
|
||||||
old_checksum_idx_count = image->checksum_idx_count;
|
old_checksum_idx_count = image->checksum_idx_count;
|
||||||
old_checksum_array = image->checksum_array;
|
old_checksum_array = image->checksum_array;
|
||||||
image->checksum_array = NULL;
|
image->checksum_array = NULL;
|
||||||
#endif
|
|
||||||
|
|
||||||
/* create new builder */
|
/* create new builder */
|
||||||
ret = iso_image_builder_new(blback, &image->builder);
|
ret = iso_image_builder_new(blback, &image->builder);
|
||||||
@ -3039,27 +3330,38 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
|
|||||||
|
|
||||||
/* if old image has el-torito, add a new catalog */
|
/* if old image has el-torito, add a new catalog */
|
||||||
if (data->eltorito) {
|
if (data->eltorito) {
|
||||||
struct el_torito_boot_catalog *catalog;
|
|
||||||
ElToritoBootImage *boot_image= NULL;
|
|
||||||
|
|
||||||
boot_image = calloc(1, sizeof(ElToritoBootImage));
|
|
||||||
if (boot_image == NULL) {
|
|
||||||
ret = ISO_OUT_OF_MEM;
|
|
||||||
goto import_revert;
|
|
||||||
}
|
|
||||||
boot_image->bootable = data->bootable;
|
|
||||||
boot_image->type = data->type;
|
|
||||||
boot_image->partition_type = data->partition_type;
|
|
||||||
boot_image->load_seg = data->load_seg;
|
|
||||||
boot_image->load_size = data->load_size;
|
|
||||||
|
|
||||||
catalog = calloc(1, sizeof(struct el_torito_boot_catalog));
|
catalog = calloc(1, sizeof(struct el_torito_boot_catalog));
|
||||||
if (catalog == NULL) {
|
if (catalog == NULL) {
|
||||||
ret = ISO_OUT_OF_MEM;
|
ret = ISO_OUT_OF_MEM;
|
||||||
goto import_revert;
|
goto import_revert;
|
||||||
}
|
}
|
||||||
catalog->image = boot_image;
|
|
||||||
|
catalog->num_bootimages = 0;
|
||||||
|
for (idx = 0; idx < data->num_bootimgs; idx++) {
|
||||||
|
boot_image = calloc(1, sizeof(ElToritoBootImage));
|
||||||
|
if (boot_image == NULL) {
|
||||||
|
ret = ISO_OUT_OF_MEM;
|
||||||
|
goto import_revert;
|
||||||
|
}
|
||||||
|
boot_image->image = NULL;
|
||||||
|
boot_image->bootable = data->boot_flags[idx] & 1;
|
||||||
|
boot_image->type = data->media_types[idx];
|
||||||
|
boot_image->partition_type = data->partition_types[idx];
|
||||||
|
boot_image->load_seg = data->load_segs[idx];
|
||||||
|
boot_image->load_size = data->load_sizes[idx];
|
||||||
|
boot_image->platform_id = data->platform_ids[idx];
|
||||||
|
memcpy(boot_image->id_string, data->id_strings[idx], 28);
|
||||||
|
memcpy(boot_image->selection_crit, data->selection_crits, 20);
|
||||||
|
|
||||||
|
catalog->bootimages[catalog->num_bootimages] = boot_image;
|
||||||
|
boot_image = NULL;
|
||||||
|
catalog->num_bootimages++;
|
||||||
|
}
|
||||||
|
for ( ; idx < Libisofs_max_boot_imageS; idx++)
|
||||||
|
catalog->bootimages[idx] = NULL;
|
||||||
image->bootcat = catalog;
|
image->bootcat = catalog;
|
||||||
|
catalog = NULL; /* So it does not get freed */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* recursively add image */
|
/* recursively add image */
|
||||||
@ -3092,21 +3394,23 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (data->eltorito) {
|
if (data->eltorito) {
|
||||||
/* if catalog and image nodes were not filled, we create them here */
|
/* if catalog and boot image nodes were not filled,
|
||||||
if (image->bootcat->image->image == NULL) {
|
we create them here */
|
||||||
IsoFileSource *src;
|
for (idx = 0; idx < image->bootcat->num_bootimages; idx++) {
|
||||||
IsoNode *node;
|
if (image->bootcat->bootimages[idx]->image != NULL)
|
||||||
ret = create_boot_img_filesrc(fs, image, &src);
|
continue;
|
||||||
|
ret = create_boot_img_filesrc(fs, image, idx, &boot_src);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
iso_node_builder_unref(image->builder);
|
iso_node_builder_unref(image->builder);
|
||||||
goto import_revert;
|
goto import_revert;
|
||||||
}
|
}
|
||||||
ret = image_builder_create_node(image->builder, image, src, &node);
|
ret = image_builder_create_node(image->builder, image, boot_src,
|
||||||
|
&node);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
iso_node_builder_unref(image->builder);
|
iso_node_builder_unref(image->builder);
|
||||||
goto import_revert;
|
goto import_revert;
|
||||||
}
|
}
|
||||||
image->bootcat->image->image = (IsoFile*)node;
|
image->bootcat->bootimages[idx]->image = (IsoFile*)node;
|
||||||
|
|
||||||
/* warn about hidden images */
|
/* warn about hidden images */
|
||||||
iso_msg_submit(image->id, ISO_EL_TORITO_HIDDEN, 0,
|
iso_msg_submit(image->id, ISO_EL_TORITO_HIDDEN, 0,
|
||||||
@ -3159,8 +3463,6 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
|
|||||||
(*features)->size = data->nblocks;
|
(*features)->size = data->nblocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef Libisofs_with_checksumS
|
|
||||||
|
|
||||||
if (data->md5_load) {
|
if (data->md5_load) {
|
||||||
/* Read checksum array */
|
/* Read checksum array */
|
||||||
ret = iso_root_get_isofsca((IsoNode *) image->root,
|
ret = iso_root_get_isofsca((IsoNode *) image->root,
|
||||||
@ -3213,7 +3515,9 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Libisofs_with_checksumS */
|
ret = iso_image_eval_boot_info_table(image, opts, src, data->nblocks, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
goto import_revert;
|
||||||
|
|
||||||
ret = ISO_SUCCESS;
|
ret = ISO_SUCCESS;
|
||||||
goto import_cleanup;
|
goto import_cleanup;
|
||||||
@ -3224,14 +3528,11 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
|
|||||||
el_torito_boot_catalog_free(image->bootcat);
|
el_torito_boot_catalog_free(image->bootcat);
|
||||||
image->root = oldroot;
|
image->root = oldroot;
|
||||||
image->bootcat = oldbootcat;
|
image->bootcat = oldbootcat;
|
||||||
|
|
||||||
#ifdef Libisofs_with_checksumS
|
|
||||||
old_checksum_start_lba = image->checksum_start_lba;
|
old_checksum_start_lba = image->checksum_start_lba;
|
||||||
old_checksum_end_lba = image->checksum_end_lba;
|
old_checksum_end_lba = image->checksum_end_lba;
|
||||||
old_checksum_idx_count = image->checksum_idx_count;
|
old_checksum_idx_count = image->checksum_idx_count;
|
||||||
image->checksum_array = old_checksum_array;
|
image->checksum_array = old_checksum_array;
|
||||||
old_checksum_array = NULL;
|
old_checksum_array = NULL;
|
||||||
#endif
|
|
||||||
|
|
||||||
import_cleanup:;
|
import_cleanup:;
|
||||||
|
|
||||||
@ -3239,17 +3540,17 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
|
|||||||
image->fs = fsback;
|
image->fs = fsback;
|
||||||
image->builder = blback;
|
image->builder = blback;
|
||||||
|
|
||||||
|
if (catalog != NULL)
|
||||||
|
el_torito_boot_catalog_free(catalog);
|
||||||
|
if (boot_image != NULL)
|
||||||
|
free((char *) boot_image);
|
||||||
iso_file_source_unref(newroot);
|
iso_file_source_unref(newroot);
|
||||||
fs->close(fs);
|
fs->close(fs);
|
||||||
iso_filesystem_unref(fs);
|
iso_filesystem_unref(fs);
|
||||||
|
|
||||||
#ifdef Libisofs_with_checksumS
|
|
||||||
if (old_checksum_array != NULL)
|
if (old_checksum_array != NULL)
|
||||||
free(old_checksum_array);
|
free(old_checksum_array);
|
||||||
if (ctx != NULL)
|
if (ctx != NULL)
|
||||||
iso_md5_end(&ctx, md5);
|
iso_md5_end(&ctx, md5);
|
||||||
#endif
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3326,8 +3627,9 @@ int iso_read_opts_new(IsoReadOpts **opts, int profile)
|
|||||||
|
|
||||||
ropts->file_mode = 0444;
|
ropts->file_mode = 0444;
|
||||||
ropts->dir_mode = 0555;
|
ropts->dir_mode = 0555;
|
||||||
ropts->noaaip= 1;
|
ropts->noaaip = 1;
|
||||||
ropts->nomd5= 1;
|
ropts->nomd5 = 1;
|
||||||
|
ropts->load_system_area = 0;
|
||||||
|
|
||||||
*opts = ropts;
|
*opts = ropts;
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
@ -3393,7 +3695,7 @@ int iso_read_opts_set_no_md5(IsoReadOpts *opts, int no_md5)
|
|||||||
if (opts == NULL) {
|
if (opts == NULL) {
|
||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
}
|
}
|
||||||
opts->nomd5 = no_md5 ? 1 : 0;
|
opts->nomd5 = no_md5 == 2 ? 2 : no_md5 == 1 ? 1 : 0;
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3463,6 +3765,15 @@ int iso_read_opts_auto_input_charset(IsoReadOpts *opts, int mode)
|
|||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int iso_read_opts_load_system_area(IsoReadOpts *opts, int mode)
|
||||||
|
{
|
||||||
|
if (opts == NULL) {
|
||||||
|
return ISO_NULL_POINTER;
|
||||||
|
}
|
||||||
|
opts->load_system_area = mode & 1;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroy an IsoReadImageFeatures object obtained with iso_image_import.
|
* Destroy an IsoReadImageFeatures object obtained with iso_image_import.
|
||||||
*/
|
*/
|
||||||
|
@ -3,14 +3,19 @@
|
|||||||
* Copyright (c) 2009 Thomas Schmitt
|
* Copyright (c) 2009 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Filesystem/FileSource implementation to access the local filesystem.
|
* Filesystem/FileSource implementation to access the local filesystem.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "fsource.h"
|
#include "fsource.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "aaip_0_2.h"
|
#include "aaip_0_2.h"
|
||||||
@ -34,7 +39,7 @@ int iso_file_source_new_lfs(IsoFileSource *parent, const char *name,
|
|||||||
*/
|
*/
|
||||||
IsoFilesystem *lfs= NULL;
|
IsoFilesystem *lfs= NULL;
|
||||||
|
|
||||||
|
/* IMPORTANT: Any change must be reflected by lfs_clone_src() */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
/** reference to the parent (if root it points to itself) */
|
/** reference to the parent (if root it points to itself) */
|
||||||
@ -57,9 +62,19 @@ char* lfs_get_path(IsoFileSource *src)
|
|||||||
if (data->parent == src) {
|
if (data->parent == src) {
|
||||||
return strdup("/");
|
return strdup("/");
|
||||||
} else {
|
} else {
|
||||||
char *path = lfs_get_path(data->parent);
|
char *path, *new_path;
|
||||||
int pathlen = strlen(path);
|
int pathlen;
|
||||||
path = realloc(path, pathlen + strlen(data->name) + 2);
|
|
||||||
|
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) {
|
if (pathlen != 1) {
|
||||||
/* pathlen can only be 1 for root */
|
/* pathlen can only be 1 for root */
|
||||||
path[pathlen] = '/';
|
path[pathlen] = '/';
|
||||||
@ -397,7 +412,7 @@ int lfs_readdir(IsoFileSource *src, IsoFileSource **child)
|
|||||||
static
|
static
|
||||||
int lfs_readlink(IsoFileSource *src, char *buf, size_t bufsiz)
|
int lfs_readlink(IsoFileSource *src, char *buf, size_t bufsiz)
|
||||||
{
|
{
|
||||||
int size;
|
int size, ret;
|
||||||
_LocalFsFileSource *data;
|
_LocalFsFileSource *data;
|
||||||
char *path;
|
char *path;
|
||||||
|
|
||||||
@ -416,7 +431,7 @@ int lfs_readlink(IsoFileSource *src, char *buf, size_t bufsiz)
|
|||||||
* invoke readlink, with bufsiz -1 to reserve an space for
|
* invoke readlink, with bufsiz -1 to reserve an space for
|
||||||
* the NULL character
|
* the NULL character
|
||||||
*/
|
*/
|
||||||
size = readlink(path, buf, bufsiz - 1);
|
size = readlink(path, buf, bufsiz);
|
||||||
free(path);
|
free(path);
|
||||||
if (size < 0) {
|
if (size < 0) {
|
||||||
/* error */
|
/* error */
|
||||||
@ -440,8 +455,13 @@ int lfs_readlink(IsoFileSource *src, char *buf, size_t bufsiz)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* NULL-terminate the buf */
|
/* NULL-terminate the buf */
|
||||||
|
ret = ISO_SUCCESS;
|
||||||
|
if (size >= bufsiz) {
|
||||||
|
ret = ISO_RR_PATH_TOO_LONG;
|
||||||
|
size = bufsiz - 1;
|
||||||
|
}
|
||||||
buf[size] = '\0';
|
buf[size] = '\0';
|
||||||
return ISO_SUCCESS;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
@ -519,10 +539,56 @@ ex:;
|
|||||||
return ret;
|
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 = {
|
IsoFileSourceIface lfs_class = {
|
||||||
|
|
||||||
1, /* version */
|
2, /* version */
|
||||||
lfs_get_path,
|
lfs_get_path,
|
||||||
lfs_get_name,
|
lfs_get_name,
|
||||||
lfs_lstat,
|
lfs_lstat,
|
||||||
@ -536,7 +602,8 @@ IsoFileSourceIface lfs_class = {
|
|||||||
lfs_get_filesystem,
|
lfs_get_filesystem,
|
||||||
lfs_free,
|
lfs_free,
|
||||||
lfs_lseek,
|
lfs_lseek,
|
||||||
lfs_get_aa_string
|
lfs_get_aa_string,
|
||||||
|
lfs_clone_src
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2,10 +2,15 @@
|
|||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "fsource.h"
|
#include "fsource.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
* 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
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef LIBISO_FSOURCE_H_
|
#ifndef LIBISO_FSOURCE_H_
|
||||||
@ -32,9 +33,16 @@
|
|||||||
int iso_local_filesystem_new(IsoFilesystem **fs);
|
int iso_local_filesystem_new(IsoFilesystem **fs);
|
||||||
|
|
||||||
|
|
||||||
/* Rank two IsoFileSource by their eventual old image LBAs.
|
/* Rank two IsoFileSource of ifs_class by their eventual old image LBAs.
|
||||||
Other IsoFileSource classes will be ranked only roughly.
|
Other IsoFileSource classes will be ranked only roughly.
|
||||||
*/
|
*/
|
||||||
int iso_ifs_sections_cmp(IsoFileSource *s1, IsoFileSource *s2, int flag);
|
int iso_ifs_sections_cmp(IsoFileSource *s1, IsoFileSource *s2, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/* Create an independent copy of an ifs_class IsoFileSource.
|
||||||
|
*/
|
||||||
|
int iso_ifs_source_clone(IsoFileSource *old_source, IsoFileSource **new_source,
|
||||||
|
int flag);
|
||||||
|
|
||||||
|
|
||||||
#endif /*LIBISO_FSOURCE_H_*/
|
#endif /*LIBISO_FSOURCE_H_*/
|
||||||
|
106
libisofs/image.c
106
libisofs/image.c
@ -3,10 +3,15 @@
|
|||||||
* Copyright (c) 2009 Thomas Schmitt
|
* Copyright (c) 2009 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libisofs.h"
|
#include "libisofs.h"
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
@ -27,11 +32,11 @@
|
|||||||
* @param image
|
* @param image
|
||||||
* Location where the image pointer will be stored.
|
* Location where the image pointer will be stored.
|
||||||
* @return
|
* @return
|
||||||
* 1 sucess, < 0 error
|
* 1 success, < 0 error
|
||||||
*/
|
*/
|
||||||
int iso_image_new(const char *name, IsoImage **image)
|
int iso_image_new(const char *name, IsoImage **image)
|
||||||
{
|
{
|
||||||
int res;
|
int res, i;
|
||||||
IsoImage *img;
|
IsoImage *img;
|
||||||
|
|
||||||
if (image == NULL) {
|
if (image == NULL) {
|
||||||
@ -73,19 +78,21 @@ int iso_image_new(const char *name, IsoImage **image)
|
|||||||
img->volset_id = strdup(name);
|
img->volset_id = strdup(name);
|
||||||
img->volume_id = strdup(name);
|
img->volume_id = strdup(name);
|
||||||
}
|
}
|
||||||
|
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->builder_ignore_acl = 1;
|
img->builder_ignore_acl = 1;
|
||||||
img->builder_ignore_ea = 1;
|
img->builder_ignore_ea = 1;
|
||||||
img->inode_counter = 0;
|
img->inode_counter = 0;
|
||||||
img->used_inodes = NULL;
|
img->used_inodes = NULL;
|
||||||
img->used_inodes_start = 0;
|
img->used_inodes_start = 0;
|
||||||
|
|
||||||
#ifdef Libisofs_with_checksumS
|
|
||||||
img->checksum_start_lba = 0;
|
img->checksum_start_lba = 0;
|
||||||
img->checksum_end_lba = 0;
|
img->checksum_end_lba = 0;
|
||||||
img->checksum_idx_count = 0;
|
img->checksum_idx_count = 0;
|
||||||
img->checksum_array = NULL;
|
img->checksum_array = NULL;
|
||||||
#endif
|
img->generator_is_running = 0;
|
||||||
|
|
||||||
*image = img;
|
*image = img;
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -99,7 +106,7 @@ 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
|
* If it reaches 0, the image is free, together with its tree nodes (whether
|
||||||
* their refcount reach 0 too, of course).
|
* their refcount reach 0 too, of course).
|
||||||
*/
|
*/
|
||||||
@ -123,6 +130,7 @@ void iso_image_unref(IsoImage *image)
|
|||||||
iso_node_builder_unref(image->builder);
|
iso_node_builder_unref(image->builder);
|
||||||
iso_filesystem_unref(image->fs);
|
iso_filesystem_unref(image->fs);
|
||||||
el_torito_boot_catalog_free(image->bootcat);
|
el_torito_boot_catalog_free(image->bootcat);
|
||||||
|
iso_image_give_up_mips_boot(image, 0);
|
||||||
free(image->volset_id);
|
free(image->volset_id);
|
||||||
free(image->volume_id);
|
free(image->volume_id);
|
||||||
free(image->publisher_id);
|
free(image->publisher_id);
|
||||||
@ -134,6 +142,8 @@ void iso_image_unref(IsoImage *image)
|
|||||||
free(image->biblio_file_id);
|
free(image->biblio_file_id);
|
||||||
if (image->used_inodes != NULL)
|
if (image->used_inodes != NULL)
|
||||||
free(image->used_inodes);
|
free(image->used_inodes);
|
||||||
|
if (image->system_area_data != NULL)
|
||||||
|
free(image->system_area_data);
|
||||||
iso_image_free_checksums(image, 0);
|
iso_image_free_checksums(image, 0);
|
||||||
free(image);
|
free(image);
|
||||||
}
|
}
|
||||||
@ -142,17 +152,12 @@ void iso_image_unref(IsoImage *image)
|
|||||||
|
|
||||||
int iso_image_free_checksums(IsoImage *image, int flag)
|
int iso_image_free_checksums(IsoImage *image, int flag)
|
||||||
{
|
{
|
||||||
#ifdef Libisofs_with_checksumS
|
|
||||||
|
|
||||||
image->checksum_start_lba = 0;
|
image->checksum_start_lba = 0;
|
||||||
image->checksum_end_lba = 0;
|
image->checksum_end_lba = 0;
|
||||||
image->checksum_idx_count = 0;
|
image->checksum_idx_count = 0;
|
||||||
if (image->checksum_array != NULL)
|
if (image->checksum_array != NULL)
|
||||||
free(image->checksum_array);
|
free(image->checksum_array);
|
||||||
image->checksum_array = NULL;
|
image->checksum_array = NULL;
|
||||||
|
|
||||||
#endif /* Libisofs_with_checksumS */
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,13 +177,13 @@ int iso_image_free_checksums(IsoImage *image, int flag)
|
|||||||
*/
|
*/
|
||||||
int iso_image_attach_data(IsoImage *image, void *data, void (*give_up)(void*))
|
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;
|
return ISO_NULL_POINTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (image->user_data != NULL) {
|
if (image->user_data != NULL) {
|
||||||
/* free previously attached data */
|
/* 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_free(image->user_data);
|
||||||
}
|
}
|
||||||
image->user_data = NULL;
|
image->user_data = NULL;
|
||||||
@ -330,6 +335,16 @@ int iso_image_get_msg_id(IsoImage *image)
|
|||||||
return image->id;
|
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
|
static
|
||||||
int dir_update_size(IsoImage *image, IsoDir *dir)
|
int dir_update_size(IsoImage *image, IsoDir *dir)
|
||||||
{
|
{
|
||||||
@ -579,39 +594,66 @@ ex:;
|
|||||||
int iso_image_get_session_md5(IsoImage *image, uint32_t *start_lba,
|
int iso_image_get_session_md5(IsoImage *image, uint32_t *start_lba,
|
||||||
uint32_t *end_lba, char md5[16], int flag)
|
uint32_t *end_lba, char md5[16], int flag)
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifdef Libisofs_with_checksumS
|
|
||||||
|
|
||||||
if (image->checksum_array == NULL || image->checksum_idx_count < 1)
|
if (image->checksum_array == NULL || image->checksum_idx_count < 1)
|
||||||
return 0;
|
return 0;
|
||||||
*start_lba = image->checksum_start_lba;
|
*start_lba = image->checksum_start_lba;
|
||||||
*end_lba = image->checksum_end_lba;
|
*end_lba = image->checksum_end_lba;
|
||||||
memcpy(md5, image->checksum_array, 16);
|
memcpy(md5, image->checksum_array, 16);
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
#endif /* ! Libisofs_with_checksumS */
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int iso_image_set_checksums(IsoImage *image, char *checksum_array,
|
int iso_image_set_checksums(IsoImage *image, char *checksum_array,
|
||||||
uint32_t start_lba, uint32_t end_lba,
|
uint32_t start_lba, uint32_t end_lba,
|
||||||
uint32_t idx_count, int flag)
|
uint32_t idx_count, int flag)
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifdef Libisofs_with_checksumS
|
|
||||||
|
|
||||||
iso_image_free_checksums(image, 0);
|
iso_image_free_checksums(image, 0);
|
||||||
image->checksum_array = checksum_array;
|
image->checksum_array = checksum_array;
|
||||||
image->checksum_start_lba = start_lba;
|
image->checksum_start_lba = start_lba;
|
||||||
image->checksum_end_lba = end_lba;
|
image->checksum_end_lba = end_lba;
|
||||||
image->checksum_idx_count = idx_count;
|
image->checksum_idx_count = idx_count;
|
||||||
|
|
||||||
#endif /* Libisofs_with_checksumS */
|
|
||||||
|
|
||||||
return 1;
|
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;
|
||||||
|
}
|
||||||
|
@ -3,8 +3,9 @@
|
|||||||
* Copyright (c) 2009 Thomas Schmitt
|
* Copyright (c) 2009 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
*/
|
*/
|
||||||
#ifndef LIBISO_IMAGE_H_
|
#ifndef LIBISO_IMAGE_H_
|
||||||
#define LIBISO_IMAGE_H_
|
#define LIBISO_IMAGE_H_
|
||||||
@ -52,6 +53,19 @@ struct Iso_Image
|
|||||||
/* el-torito boot catalog */
|
/* el-torito boot catalog */
|
||||||
struct el_torito_boot_catalog *bootcat;
|
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() */
|
||||||
|
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 */
|
||||||
|
|
||||||
|
|
||||||
/* image identifier, for message origin identifier */
|
/* image identifier, for message origin identifier */
|
||||||
int id;
|
int id;
|
||||||
|
|
||||||
@ -148,8 +162,6 @@ struct Iso_Image
|
|||||||
uint8_t *used_inodes;
|
uint8_t *used_inodes;
|
||||||
ino_t used_inodes_start;
|
ino_t used_inodes_start;
|
||||||
|
|
||||||
#ifdef Libisofs_with_checksumS
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Array of MD5 checksums as announced by xattr "isofs.ca" of the
|
* Array of MD5 checksums as announced by xattr "isofs.ca" of the
|
||||||
* root node. Array element 0 contains an overall image checksum for the
|
* root node. Array element 0 contains an overall image checksum for the
|
||||||
@ -162,7 +174,11 @@ struct Iso_Image
|
|||||||
uint32_t checksum_idx_count;
|
uint32_t checksum_idx_count;
|
||||||
char *checksum_array;
|
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;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2,10 +2,15 @@
|
|||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "iso1999.h"
|
#include "iso1999.h"
|
||||||
#include "messages.h"
|
#include "messages.h"
|
||||||
#include "writer.h"
|
#include "writer.h"
|
||||||
@ -711,7 +716,7 @@ void write_one_dir_record(Ecma119Image *t, Iso1999Node *node, int file_id,
|
|||||||
iso_bb(rec->length, len, 4);
|
iso_bb(rec->length, len, 4);
|
||||||
iso_datetime_7(rec->recording_time, t->now, t->always_gmt);
|
iso_datetime_7(rec->recording_time, t->now, t->always_gmt);
|
||||||
rec->flags[0] = ((node->type == ISO1999_DIR) ? 2 : 0) | (multi_extend ? 0x80 : 0);
|
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;
|
rec->len_fi[0] = len_fi;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -762,9 +767,9 @@ int iso1999_writer_write_vol_desc(IsoImageWriter *writer)
|
|||||||
strncpy_pad((char*)vol.volume_id, vol_id, 32);
|
strncpy_pad((char*)vol.volume_id, vol_id, 32);
|
||||||
|
|
||||||
iso_bb(vol.vol_space_size, t->vol_space_size, 4);
|
iso_bb(vol.vol_space_size, t->vol_space_size, 4);
|
||||||
iso_bb(vol.vol_set_size, 1, 2);
|
iso_bb(vol.vol_set_size, (uint32_t) 1, 2);
|
||||||
iso_bb(vol.vol_seq_number, 1, 2);
|
iso_bb(vol.vol_seq_number, (uint32_t) 1, 2);
|
||||||
iso_bb(vol.block_size, BLOCK_SIZE, 2);
|
iso_bb(vol.block_size, (uint32_t) BLOCK_SIZE, 2);
|
||||||
iso_bb(vol.path_table_size, t->iso1999_path_table_size, 4);
|
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_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);
|
iso_msb(vol.m_path_table_pos, t->iso1999_m_path_table_pos, 4);
|
||||||
@ -1023,6 +1028,7 @@ int iso1999_writer_create(Ecma119Image *target)
|
|||||||
"Creating low level ISO 9660:1999 tree...");
|
"Creating low level ISO 9660:1999 tree...");
|
||||||
ret = iso1999_tree_create(target);
|
ret = iso1999_tree_create(target);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
free((char *) writer);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,8 +2,9 @@
|
|||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3,10 +3,15 @@
|
|||||||
* Copyright (c) 2007 Mario Danic
|
* Copyright (c) 2007 Mario Danic
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "joliet.h"
|
#include "joliet.h"
|
||||||
#include "messages.h"
|
#include "messages.h"
|
||||||
#include "writer.h"
|
#include "writer.h"
|
||||||
@ -14,6 +19,7 @@
|
|||||||
#include "filesrc.h"
|
#include "filesrc.h"
|
||||||
#include "eltorito.h"
|
#include "eltorito.h"
|
||||||
#include "libisofs.h"
|
#include "libisofs.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -37,12 +43,11 @@ int get_joliet_name(Ecma119Image *t, IsoNode *iso, uint16_t **name)
|
|||||||
iso_msg_debug(t->image->id, "Can't convert %s", iso->name);
|
iso_msg_debug(t->image->id, "Can't convert %s", iso->name);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO #00022 : support relaxed constraints in joliet filenames */
|
|
||||||
if (iso->type == LIBISO_DIR) {
|
if (iso->type == LIBISO_DIR) {
|
||||||
jname = iso_j_dir_id(ucs_name);
|
jname = iso_j_dir_id(ucs_name, t->joliet_long_names << 1);
|
||||||
} else {
|
} else {
|
||||||
jname = iso_j_file_id(ucs_name);
|
jname = iso_j_file_id(ucs_name,
|
||||||
|
(t->joliet_long_names << 1) | !!(t->no_force_dots & 2));
|
||||||
}
|
}
|
||||||
free(ucs_name);
|
free(ucs_name);
|
||||||
if (jname != NULL) {
|
if (jname != NULL) {
|
||||||
@ -243,7 +248,7 @@ int create_tree(Ecma119Image *t, IsoNode *iso, JolietNode **tree, int pathlen)
|
|||||||
char *ipath = iso_tree_get_node_path(iso);
|
char *ipath = iso_tree_get_node_path(iso);
|
||||||
ret = iso_msg_submit(t->image->id, ISO_FILE_IGNORED, 0,
|
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 "
|
"Can't add %s to Joliet tree. %s can only be added to a "
|
||||||
"Rock Ridget tree.", ipath, (iso->type == LIBISO_SYMLINK ?
|
"Rock Ridge tree.", ipath, (iso->type == LIBISO_SYMLINK ?
|
||||||
"Symlinks" : "Special files"));
|
"Symlinks" : "Special files"));
|
||||||
free(ipath);
|
free(ipath);
|
||||||
}
|
}
|
||||||
@ -298,8 +303,15 @@ int joliet_create_mangled_name(uint16_t *dest, uint16_t *src, int digits,
|
|||||||
int ret, pos;
|
int ret, pos;
|
||||||
uint16_t *ucsnumber;
|
uint16_t *ucsnumber;
|
||||||
char fmt[16];
|
char fmt[16];
|
||||||
char nstr[72]; /* The only caller of this function allocates dest with 66
|
char nstr[72];
|
||||||
elements and limits digits to < 8 */
|
/* 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(fmt, "%%0%dd", digits);
|
||||||
sprintf(nstr, fmt, number);
|
sprintf(nstr, fmt, number);
|
||||||
@ -332,7 +344,7 @@ static
|
|||||||
int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
|
int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
int i, nchildren;
|
int i, nchildren, maxchar = 64;
|
||||||
JolietNode **children;
|
JolietNode **children;
|
||||||
IsoHTable *table;
|
IsoHTable *table;
|
||||||
int need_sort = 0;
|
int need_sort = 0;
|
||||||
@ -340,6 +352,9 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
|
|||||||
nchildren = dir->info.dir->nchildren;
|
nchildren = dir->info.dir->nchildren;
|
||||||
children = dir->info.dir->children;
|
children = dir->info.dir->children;
|
||||||
|
|
||||||
|
if (t->joliet_long_names)
|
||||||
|
maxchar = 103;
|
||||||
|
|
||||||
/* a hash table will temporary hold the names, for fast searching */
|
/* a hash table will temporary hold the names, for fast searching */
|
||||||
ret = iso_htable_create((nchildren * 100) / 80, iso_str_hash,
|
ret = iso_htable_create((nchildren * 100) / 80, iso_str_hash,
|
||||||
(compare_function_t)ucscmp, &table);
|
(compare_function_t)ucscmp, &table);
|
||||||
@ -356,7 +371,7 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
|
|||||||
|
|
||||||
for (i = 0; i < nchildren; ++i) {
|
for (i = 0; i < nchildren; ++i) {
|
||||||
uint16_t *name, *ext;
|
uint16_t *name, *ext;
|
||||||
uint16_t full_name[66];
|
uint16_t full_name[LIBISO_JOLIET_NAME_MAX];
|
||||||
int max; /* computed max len for name, without extension */
|
int max; /* computed max len for name, without extension */
|
||||||
int j = i;
|
int j = i;
|
||||||
int digits = 1; /* characters to change per name */
|
int digits = 1; /* characters to change per name */
|
||||||
@ -375,7 +390,7 @@ 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 enought, it allows handling up to
|
||||||
* 9,999,999 files with same name.
|
* 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) {
|
while (digits < 8) {
|
||||||
int ok, k;
|
int ok, k;
|
||||||
@ -398,7 +413,7 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
|
|||||||
ext = dot + 1;
|
ext = dot + 1;
|
||||||
|
|
||||||
extlen = ucslen(ext);
|
extlen = ucslen(ext);
|
||||||
max = 65 - extlen - 1 - digits;
|
max = maxchar + 1 - extlen - 1 - digits;
|
||||||
if (max <= 0) {
|
if (max <= 0) {
|
||||||
/* this can happen if extension is too long */
|
/* this can happen if extension is too long */
|
||||||
if (extlen + max > 3) {
|
if (extlen + max > 3) {
|
||||||
@ -408,7 +423,7 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
|
|||||||
*/
|
*/
|
||||||
extlen = extlen + max - 1;
|
extlen = extlen + max - 1;
|
||||||
ext[extlen] = 0;
|
ext[extlen] = 0;
|
||||||
max = 66 - extlen - 1 - digits;
|
max = maxchar + 2 - extlen - 1 - digits;
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* error, we don't support extensions < 3
|
* error, we don't support extensions < 3
|
||||||
@ -425,10 +440,10 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
|
|||||||
} else {
|
} else {
|
||||||
/* Directory, or file without extension */
|
/* Directory, or file without extension */
|
||||||
if (children[i]->type == JOLIET_DIR) {
|
if (children[i]->type == JOLIET_DIR) {
|
||||||
max = 65 - digits;
|
max = maxchar + 1 - digits;
|
||||||
dot = NULL; /* dots have no meaning in dirs */
|
dot = NULL; /* dots have no meaning in dirs */
|
||||||
} else {
|
} else {
|
||||||
max = 65 - digits;
|
max = maxchar + 1 - digits;
|
||||||
}
|
}
|
||||||
name = full_name;
|
name = full_name;
|
||||||
if (max < ucslen(name)) {
|
if (max < ucslen(name)) {
|
||||||
@ -441,7 +456,7 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
|
|||||||
ok = 1;
|
ok = 1;
|
||||||
/* change name of each file */
|
/* change name of each file */
|
||||||
for (k = i; k <= j; ++k) {
|
for (k = i; k <= j; ++k) {
|
||||||
uint16_t tmp[66];
|
uint16_t tmp[LIBISO_JOLIET_NAME_MAX];
|
||||||
while (1) {
|
while (1) {
|
||||||
ret = joliet_create_mangled_name(tmp, name, digits,
|
ret = joliet_create_mangled_name(tmp, name, digits,
|
||||||
change, ext);
|
change, ext);
|
||||||
@ -551,17 +566,19 @@ int joliet_tree_create(Ecma119Image *t)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* the Joliet tree is stored in Ecma119Image target */
|
/* 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...");
|
iso_msg_debug(t->image->id, "Sorting the Joliet tree...");
|
||||||
sort_tree(root);
|
sort_tree(root);
|
||||||
|
|
||||||
iso_msg_debug(t->image->id, "Mangling Joliet names...");
|
iso_msg_debug(t->image->id, "Mangling Joliet names...");
|
||||||
ret = mangle_tree(t, t->joliet_root);
|
ret = mangle_tree(t, root);
|
||||||
if (ret < 0) {
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
|
||||||
|
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -573,7 +590,7 @@ size_t calc_dirent_len(Ecma119Image *t, JolietNode *n)
|
|||||||
{
|
{
|
||||||
/* note than name len is always even, so we always need the pad byte */
|
/* note than name len is always even, so we always need the pad byte */
|
||||||
int ret = n->name ? ucslen(n->name) * 2 + 34 : 34;
|
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->omit_version_numbers & 3)) {
|
||||||
/* take into account version numbers */
|
/* take into account version numbers */
|
||||||
ret += 4;
|
ret += 4;
|
||||||
}
|
}
|
||||||
@ -668,6 +685,7 @@ int joliet_writer_compute_data_blocks(IsoImageWriter *writer)
|
|||||||
{
|
{
|
||||||
Ecma119Image *t;
|
Ecma119Image *t;
|
||||||
uint32_t path_table_size;
|
uint32_t path_table_size;
|
||||||
|
size_t ndirs;
|
||||||
|
|
||||||
if (writer == NULL) {
|
if (writer == NULL) {
|
||||||
return ISO_OUT_OF_MEM;
|
return ISO_OUT_OF_MEM;
|
||||||
@ -691,6 +709,24 @@ int joliet_writer_compute_data_blocks(IsoImageWriter *writer)
|
|||||||
t->curblock += DIV_UP(path_table_size, BLOCK_SIZE);
|
t->curblock += DIV_UP(path_table_size, BLOCK_SIZE);
|
||||||
t->joliet_path_table_size = path_table_size;
|
t->joliet_path_table_size = path_table_size;
|
||||||
|
|
||||||
|
if (t->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;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -721,7 +757,7 @@ void write_one_dir_record(Ecma119Image *t, JolietNode *node, int file_id,
|
|||||||
|
|
||||||
memcpy(rec->file_id, name, len_fi);
|
memcpy(rec->file_id, name, len_fi);
|
||||||
|
|
||||||
if (node->type == JOLIET_FILE && !t->omit_version_numbers) {
|
if (node->type == JOLIET_FILE && !(t->omit_version_numbers & 3)) {
|
||||||
len_dr += 4;
|
len_dr += 4;
|
||||||
rec->file_id[len_fi++] = 0;
|
rec->file_id[len_fi++] = 0;
|
||||||
rec->file_id[len_fi++] = ';';
|
rec->file_id[len_fi++] = ';';
|
||||||
@ -753,11 +789,11 @@ void write_one_dir_record(Ecma119Image *t, JolietNode *node, int file_id,
|
|||||||
node = node->parent;
|
node = node->parent;
|
||||||
|
|
||||||
rec->len_dr[0] = len_dr;
|
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_bb(rec->length, len, 4);
|
||||||
iso_datetime_7(rec->recording_time, t->now, t->always_gmt);
|
iso_datetime_7(rec->recording_time, t->now, t->always_gmt);
|
||||||
rec->flags[0] = ((node->type == JOLIET_DIR) ? 2 : 0) | (multi_extend ? 0x80 : 0);
|
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;
|
rec->len_fi[0] = len_fi;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -789,7 +825,6 @@ void ucsncpy_pad(uint16_t *dest, const uint16_t *src, size_t max)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
|
||||||
int joliet_writer_write_vol_desc(IsoImageWriter *writer)
|
int joliet_writer_write_vol_desc(IsoImageWriter *writer)
|
||||||
{
|
{
|
||||||
IsoImage *image;
|
IsoImage *image;
|
||||||
@ -830,16 +865,25 @@ int joliet_writer_write_vol_desc(IsoImageWriter *writer)
|
|||||||
|
|
||||||
/* make use of UCS-2 Level 3 */
|
/* make use of UCS-2 Level 3 */
|
||||||
memcpy(vol.esc_sequences, "%/E", 3);
|
memcpy(vol.esc_sequences, "%/E", 3);
|
||||||
|
iso_bb(vol.vol_space_size, t->vol_space_size - t->eff_partition_offset,
|
||||||
iso_bb(vol.vol_space_size, t->vol_space_size, 4);
|
4);
|
||||||
iso_bb(vol.vol_set_size, 1, 2);
|
iso_bb(vol.vol_set_size, (uint32_t) 1, 2);
|
||||||
iso_bb(vol.vol_seq_number, 1, 2);
|
iso_bb(vol.vol_seq_number, (uint32_t) 1, 2);
|
||||||
iso_bb(vol.block_size, BLOCK_SIZE, 2);
|
iso_bb(vol.block_size, (uint32_t) BLOCK_SIZE, 2);
|
||||||
iso_bb(vol.path_table_size, t->joliet_path_table_size, 4);
|
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.vol_set_id, volset_id, 128);
|
||||||
ucsncpy_pad((uint16_t*)vol.publisher_id, pub_id, 128);
|
ucsncpy_pad((uint16_t*)vol.publisher_id, pub_id, 128);
|
||||||
@ -898,7 +942,7 @@ int write_one_dir(Ecma119Image *t, JolietNode *dir)
|
|||||||
/* compute len of directory entry */
|
/* compute len of directory entry */
|
||||||
fi_len = ucslen(child->name) * 2;
|
fi_len = ucslen(child->name) * 2;
|
||||||
len = fi_len + 34;
|
len = fi_len + 34;
|
||||||
if (child->type == JOLIET_FILE && !t->omit_version_numbers) {
|
if (child->type == JOLIET_FILE && !(t->omit_version_numbers & 3)) {
|
||||||
len += 4;
|
len += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -979,7 +1023,8 @@ int write_path_table(Ecma119Image *t, JolietNode **pathlist, int l_type)
|
|||||||
rec = (struct ecma119_path_table_record*) buf;
|
rec = (struct ecma119_path_table_record*) buf;
|
||||||
rec->len_di[0] = dir->parent ? (uint8_t) ucslen(dir->name) * 2 : 1;
|
rec->len_di[0] = dir->parent ? (uint8_t) ucslen(dir->name) * 2 : 1;
|
||||||
rec->len_xa[0] = 0;
|
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);
|
write_int(rec->parent, parent + 1, 2);
|
||||||
if (dir->parent) {
|
if (dir->parent) {
|
||||||
memcpy(rec->dir_id, dir->name, rec->len_di[0]);
|
memcpy(rec->dir_id, dir->name, rec->len_di[0]);
|
||||||
@ -1018,7 +1063,12 @@ int write_path_tables(Ecma119Image *t)
|
|||||||
if (pathlist == NULL) {
|
if (pathlist == NULL) {
|
||||||
return ISO_OUT_OF_MEM;
|
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;
|
cur = 1;
|
||||||
|
|
||||||
for (i = 0; i < t->joliet_ndirs; i++) {
|
for (i = 0; i < t->joliet_ndirs; i++) {
|
||||||
@ -1046,18 +1096,21 @@ int write_path_tables(Ecma119Image *t)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
int joliet_writer_write_data(IsoImageWriter *writer)
|
int joliet_writer_write_dirs(IsoImageWriter *writer)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
Ecma119Image *t;
|
Ecma119Image *t;
|
||||||
|
JolietNode *root;
|
||||||
|
|
||||||
if (writer == NULL) {
|
|
||||||
return ISO_NULL_POINTER;
|
|
||||||
}
|
|
||||||
t = writer->target;
|
t = writer->target;
|
||||||
|
|
||||||
/* first of all, we write the directory structure */
|
/* 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) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -1068,12 +1121,40 @@ int joliet_writer_write_data(IsoImageWriter *writer)
|
|||||||
return ret;
|
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->partition_offset > 0) {
|
||||||
|
t->eff_partition_offset = t->partition_offset;
|
||||||
|
ret = joliet_writer_write_dirs(writer);
|
||||||
|
t->eff_partition_offset = 0;
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
int joliet_writer_free_data(IsoImageWriter *writer)
|
int joliet_writer_free_data(IsoImageWriter *writer)
|
||||||
{
|
{
|
||||||
/* free the Joliet tree */
|
/* free the Joliet tree */
|
||||||
Ecma119Image *t = writer->target;
|
Ecma119Image *t = writer->target;
|
||||||
joliet_node_free(t->joliet_root);
|
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;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1097,12 +1178,23 @@ int joliet_writer_create(Ecma119Image *target)
|
|||||||
iso_msg_debug(target->image->id, "Creating low level Joliet tree...");
|
iso_msg_debug(target->image->id, "Creating low level Joliet tree...");
|
||||||
ret = joliet_tree_create(target);
|
ret = joliet_tree_create(target);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
free((char *) writer);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add this writer to image */
|
/* add this writer to image */
|
||||||
target->writers[target->nwriters++] = writer;
|
target->writers[target->nwriters++] = writer;
|
||||||
|
|
||||||
|
if(target->partition_offset > 0) {
|
||||||
|
/* Create second tree */
|
||||||
|
target->eff_partition_offset = target->partition_offset;
|
||||||
|
ret = joliet_tree_create(target);
|
||||||
|
if (ret < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
target->eff_partition_offset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* we need the volume descriptor */
|
/* we need the volume descriptor */
|
||||||
target->curblock++;
|
target->curblock++;
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
|
@ -3,8 +3,9 @@
|
|||||||
* Copyright (c) 2007 Mario Danic
|
* Copyright (c) 2007 Mario Danic
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -17,6 +18,10 @@
|
|||||||
#include "libisofs.h"
|
#include "libisofs.h"
|
||||||
#include "ecma119.h"
|
#include "ecma119.h"
|
||||||
|
|
||||||
|
/* was formerly 66 = 64 + 2. Now 105 = 103 + 2.
|
||||||
|
*/
|
||||||
|
#define LIBISO_JOLIET_NAME_MAX 105
|
||||||
|
|
||||||
enum joliet_node_type {
|
enum joliet_node_type {
|
||||||
JOLIET_FILE,
|
JOLIET_FILE,
|
||||||
JOLIET_DIR
|
JOLIET_DIR
|
||||||
@ -53,4 +58,10 @@ struct joliet_node
|
|||||||
*/
|
*/
|
||||||
int joliet_writer_create(Ecma119Image *target);
|
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);
|
||||||
|
|
||||||
|
|
||||||
#endif /* LIBISO_JOLIET_H */
|
#endif /* LIBISO_JOLIET_H */
|
||||||
|
@ -2,9 +2,13 @@
|
|||||||
/* libiso_msgs (generated from libdax_msgs : Fri Feb 22 19:42:52 CET 2008)
|
/* libiso_msgs (generated from libdax_msgs : Fri Feb 22 19:42:52 CET 2008)
|
||||||
Message handling facility of libisofs.
|
Message handling facility of libisofs.
|
||||||
Copyright (C) 2006 - 2008 Thomas Schmitt <scdbackup@gmx.net>,
|
Copyright (C) 2006 - 2008 Thomas Schmitt <scdbackup@gmx.net>,
|
||||||
provided under GPL version 2
|
provided under GPL version 2 or later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
/* libiso_msgs (generated from libdax_msgs : Fri Feb 22 19:42:52 CET 2008)
|
/* libiso_msgs (generated from libdax_msgs : Fri Feb 22 19:42:52 CET 2008)
|
||||||
Message handling facility of libisofs.
|
Message handling facility of libisofs.
|
||||||
Copyright (C) 2006-2008 Thomas Schmitt <scdbackup@gmx.net>,
|
Copyright (C) 2006-2008 Thomas Schmitt <scdbackup@gmx.net>,
|
||||||
provided under GPL version 2
|
provided under GPL version 2 or later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
1651
libisofs/libisofs.h
1651
libisofs/libisofs.h
File diff suppressed because it is too large
Load Diff
314
libisofs/libisofs.ver
Normal file
314
libisofs/libisofs.ver
Normal file
@ -0,0 +1,314 @@
|
|||||||
|
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_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_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_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_get_local_charset;
|
||||||
|
iso_get_messenger;
|
||||||
|
iso_gzip_get_refcounts;
|
||||||
|
iso_image_add_boot_image;
|
||||||
|
iso_image_add_mips_boot_file;
|
||||||
|
iso_image_attach_data;
|
||||||
|
iso_image_create_burn_source;
|
||||||
|
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_application_id;
|
||||||
|
iso_image_get_attached_data;
|
||||||
|
iso_image_get_biblio_file_id;
|
||||||
|
iso_image_get_boot_image;
|
||||||
|
iso_image_get_copyright_file_id;
|
||||||
|
iso_image_get_data_preparer_id;
|
||||||
|
iso_image_get_mips_boot_files;
|
||||||
|
iso_image_get_msg_id;
|
||||||
|
iso_image_get_publisher_id;
|
||||||
|
iso_image_get_root;
|
||||||
|
iso_image_get_session_md5;
|
||||||
|
iso_image_get_system_area;
|
||||||
|
iso_image_get_system_id;
|
||||||
|
iso_image_get_volset_id;
|
||||||
|
iso_image_get_volume_id;
|
||||||
|
iso_image_give_up_mips_boot;
|
||||||
|
iso_image_import;
|
||||||
|
iso_image_new;
|
||||||
|
iso_image_ref;
|
||||||
|
iso_image_remove_boot_image;
|
||||||
|
iso_image_set_abstract_file_id;
|
||||||
|
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_ignore_aclea;
|
||||||
|
iso_image_set_publisher_id;
|
||||||
|
iso_image_set_system_id;
|
||||||
|
iso_image_set_volset_id;
|
||||||
|
iso_image_set_volume_id;
|
||||||
|
iso_image_unref;
|
||||||
|
iso_image_update_sizes;
|
||||||
|
iso_init;
|
||||||
|
iso_init_with_flag;
|
||||||
|
iso_lib_is_compatible;
|
||||||
|
iso_lib_version;
|
||||||
|
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_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_obtain_msgs;
|
||||||
|
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_opts_auto_input_charset;
|
||||||
|
iso_read_opts_free;
|
||||||
|
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_input_charset;
|
||||||
|
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_is_repeatable;
|
||||||
|
iso_stream_open;
|
||||||
|
iso_stream_read;
|
||||||
|
iso_stream_ref;
|
||||||
|
iso_stream_unref;
|
||||||
|
iso_stream_update_size;
|
||||||
|
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_set_follow_symlinks;
|
||||||
|
iso_tree_set_ignore_hidden;
|
||||||
|
iso_tree_set_ignore_special;
|
||||||
|
iso_tree_set_replace_mode;
|
||||||
|
iso_tree_set_report_callback;
|
||||||
|
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_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_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_fifo_size;
|
||||||
|
iso_write_opts_set_hardlinks;
|
||||||
|
iso_write_opts_set_iso1999;
|
||||||
|
iso_write_opts_set_iso_level;
|
||||||
|
iso_write_opts_set_joliet;
|
||||||
|
iso_write_opts_set_joliet_long_names;
|
||||||
|
iso_write_opts_set_joliet_longer_paths;
|
||||||
|
iso_write_opts_set_max_37_char_filenames;
|
||||||
|
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_partition_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_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_get_params;
|
||||||
|
iso_zisofs_get_refcounts;
|
||||||
|
iso_zisofs_set_params;
|
||||||
|
local: *;
|
||||||
|
};
|
@ -1,5 +1,18 @@
|
|||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_STDINT_H
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_INTTYPES_H
|
||||||
|
#include <inttypes.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -10,6 +23,7 @@
|
|||||||
/* for gettimeofday() */
|
/* for gettimeofday() */
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
|
||||||
/* This code stems from syslinux-3.72/utils/isohybrid, a perl script
|
/* This code stems from syslinux-3.72/utils/isohybrid, a perl script
|
||||||
under GPL which is Copyright 2002-2008 H. Peter Anvin.
|
under GPL which is Copyright 2002-2008 H. Peter Anvin.
|
||||||
|
|
||||||
@ -25,13 +39,13 @@ and is now under the licenses to which H.Peter Anvin agreed:
|
|||||||
or both, at your option.
|
or both, at your option.
|
||||||
Sincerely, H. Peter Anvin
|
Sincerely, H. Peter Anvin
|
||||||
|
|
||||||
In the context of xorriso-standalone, this code is under GPLv2 derived from
|
In the context of GNU xorriso, this code is under GPLv3+ derived from LGPL.
|
||||||
LGPL. In the context of libisofs this code derives its matching open source
|
In the context of libisofs this code derives its matching free software
|
||||||
license from above stem licenses, typically from LGPL.
|
license from above stem licenses, typically from LGPL.
|
||||||
In case its generosity is needed, here is the 2-clause BSD license:
|
In case its generosity is needed, here is the 2-clause BSD license:
|
||||||
|
|
||||||
make_isohybrid_mbr.c is copyright 2002-2008 H. Peter Anvin
|
make_isohybrid_mbr.c is copyright 2002-2008 H. Peter Anvin
|
||||||
and 2008-2009 libburnia project.
|
and 2008-2010 Thomas Schmitt
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright notice,
|
1. Redistributions of source code must retain the above copyright notice,
|
||||||
this list of conditions and the following disclaimer.
|
this list of conditions and the following disclaimer.
|
||||||
@ -51,8 +65,9 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/* A helper function. One could replace it by one or two macros. */
|
/* 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;
|
int b;
|
||||||
|
|
||||||
@ -61,6 +76,11 @@ static int lsb_to_buf(char **wpt, int value, int bits, int flag)
|
|||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ====================================================================== */
|
||||||
|
/* Deprecated Function */
|
||||||
|
/* ====================================================================== */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create a MBR for an isohybrid enabled ISOLINUX boot image.
|
* Create a MBR for an isohybrid enabled ISOLINUX boot image.
|
||||||
*
|
*
|
||||||
@ -228,3 +248,212 @@ int make_isohybrid_mbr(int bin_lba, int *img_blocks, char *mbr, int flag)
|
|||||||
return (1);
|
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
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @param flag bit0= make own random MBR Id from current time
|
||||||
|
*/
|
||||||
|
int make_isolinux_mbr(int32_t *img_blocks, uint32_t boot_lba,
|
||||||
|
uint32_t mbr_id, int head_count, int sector_count,
|
||||||
|
int part_offset, int part_number, int fs_type,
|
||||||
|
uint8_t *buf, int flag)
|
||||||
|
{
|
||||||
|
uint32_t id, part, nominal_part_size;
|
||||||
|
off_t hd_img_blocks, hd_boot_lba;
|
||||||
|
char *wpt;
|
||||||
|
/* For generating a weak random number */
|
||||||
|
struct timeval tv;
|
||||||
|
struct timezone tz;
|
||||||
|
|
||||||
|
hd_img_blocks = ((off_t) *img_blocks) * (off_t) 4;
|
||||||
|
|
||||||
|
/* 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) {
|
||||||
|
gettimeofday(&tv, &tz);
|
||||||
|
id = 0xffffffff & (tv.tv_sec ^ (tv.tv_usec * 2000));
|
||||||
|
lsb_to_buf(&wpt, id, 32, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* write word 0 # Offset 444
|
||||||
|
*/
|
||||||
|
lsb_to_buf(&wpt, 0, 16, 0);
|
||||||
|
|
||||||
|
/* # Offset 446
|
||||||
|
*/
|
||||||
|
for (part = 1 ; part <= 4; part++) {
|
||||||
|
if (part != part_number) {
|
||||||
|
/* if this_partition != partition_number: write 16 zero bytes */
|
||||||
|
memset(wpt, 0, 16);
|
||||||
|
wpt+= 16;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* 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
|
||||||
|
*/
|
||||||
|
lsb_to_buf(&wpt, 0x80, 8, 0);
|
||||||
|
lba512chs_to_buf(&wpt, part_offset, head_count, sector_count);
|
||||||
|
lsb_to_buf(&wpt, fs_type, 8, 0);
|
||||||
|
lba512chs_to_buf(&wpt, hd_img_blocks - 1, head_count, sector_count);
|
||||||
|
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);
|
||||||
|
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,12 +2,24 @@
|
|||||||
* Copyright (c) 2009 Thomas Schmitt
|
* Copyright (c) 2009 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_STDINT_H
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_INTTYPES_H
|
||||||
|
#include <inttypes.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -412,6 +424,22 @@ int checksum_cx_xinfo_func(void *data, int flag)
|
|||||||
return 1;
|
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
|
/* Function to identify and manage md5 sums of unspecified providence stored
|
||||||
* directly in this xinfo.
|
* directly in this xinfo.
|
||||||
@ -424,13 +452,29 @@ int checksum_md5_xinfo_func(void *data, int flag)
|
|||||||
return 1;
|
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 */
|
/* MD5 checksum image writer */
|
||||||
|
|
||||||
#ifdef Libisofs_with_checksumS
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@flag bit0= recursion
|
@flag bit0= recursion
|
||||||
bit1= session will be appended to an existing image
|
bit1= session will be appended to an existing image
|
||||||
@ -507,15 +551,10 @@ int checksum_copy_old_nodes(Ecma119Image *target, IsoNode *node, int flag)
|
|||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Libisofs_with_checksumS */
|
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
int checksum_writer_compute_data_blocks(IsoImageWriter *writer)
|
int checksum_writer_compute_data_blocks(IsoImageWriter *writer)
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifdef Libisofs_with_checksumS
|
|
||||||
|
|
||||||
size_t size;
|
size_t size;
|
||||||
Ecma119Image *t;
|
Ecma119Image *t;
|
||||||
int ret;
|
int ret;
|
||||||
@ -556,9 +595,6 @@ int checksum_writer_compute_data_blocks(IsoImageWriter *writer)
|
|||||||
t->checksum_idx_counter + 2, 16, "MD5", 0);
|
t->checksum_idx_counter + 2, 16, "MD5", 0);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
#endif /* Libisofs_with_checksumS */
|
|
||||||
|
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -579,9 +615,6 @@ int checksum_writer_write_vol_desc(IsoImageWriter *writer)
|
|||||||
static
|
static
|
||||||
int checksum_writer_write_data(IsoImageWriter *writer)
|
int checksum_writer_write_data(IsoImageWriter *writer)
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifdef Libisofs_with_checksumS
|
|
||||||
|
|
||||||
int wres, res;
|
int wres, res;
|
||||||
size_t i, size;
|
size_t i, size;
|
||||||
Ecma119Image *t;
|
Ecma119Image *t;
|
||||||
@ -648,12 +681,6 @@ ex:;
|
|||||||
if (ctx != NULL)
|
if (ctx != NULL)
|
||||||
iso_md5_end(&ctx, md5);
|
iso_md5_end(&ctx, md5);
|
||||||
return(res);
|
return(res);
|
||||||
|
|
||||||
#else /* Libisofs_with_checksumS */
|
|
||||||
|
|
||||||
return ISO_SUCCESS;
|
|
||||||
|
|
||||||
#endif /* ! Libisofs_with_checksumS */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -683,17 +710,11 @@ int checksum_writer_create(Ecma119Image *target)
|
|||||||
|
|
||||||
/* add this writer to image */
|
/* add this writer to image */
|
||||||
target->writers[target->nwriters++] = writer;
|
target->writers[target->nwriters++] = writer;
|
||||||
|
|
||||||
#ifdef Libisofs_with_checksumS
|
|
||||||
|
|
||||||
/* Account for superblock checksum tag */
|
/* Account for superblock checksum tag */
|
||||||
if (target->md5_session_checksum) {
|
if (target->md5_session_checksum) {
|
||||||
target->checksum_sb_tag_pos = target->curblock;
|
target->checksum_sb_tag_pos = target->curblock;
|
||||||
target->curblock++;
|
target->curblock++;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Libisofs_with_checksumS */
|
|
||||||
|
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -701,9 +722,6 @@ int checksum_writer_create(Ecma119Image *target)
|
|||||||
static
|
static
|
||||||
int iso_md5_write_scdbackup_tag(Ecma119Image *t, char *tag_block, int flag)
|
int iso_md5_write_scdbackup_tag(Ecma119Image *t, char *tag_block, int flag)
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifdef Libisofs_with_checksumS
|
|
||||||
|
|
||||||
void *ctx = NULL;
|
void *ctx = NULL;
|
||||||
off_t pos = 0, line_start;
|
off_t pos = 0, line_start;
|
||||||
int record_len, block_len, res, i;
|
int record_len, block_len, res, i;
|
||||||
@ -752,12 +770,6 @@ ex:;
|
|||||||
if (ctx != NULL)
|
if (ctx != NULL)
|
||||||
iso_md5_end(&ctx, md5);
|
iso_md5_end(&ctx, md5);
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
return ISO_SUCCESS;
|
|
||||||
|
|
||||||
#endif /* Libisofs_with_checksumS */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -771,9 +783,6 @@ ex:;
|
|||||||
*/
|
*/
|
||||||
int iso_md5_write_tag(Ecma119Image *t, int flag)
|
int iso_md5_write_tag(Ecma119Image *t, int flag)
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifdef Libisofs_with_checksumS
|
|
||||||
|
|
||||||
int res, mode, l, i, wres, tag_id_len;
|
int res, mode, l, i, wres, tag_id_len;
|
||||||
void *ctx = NULL;
|
void *ctx = NULL;
|
||||||
char md5[16], tag_block[2048], *tag_id;
|
char md5[16], tag_block[2048], *tag_id;
|
||||||
@ -862,13 +871,6 @@ ex:;
|
|||||||
if (ctx != NULL)
|
if (ctx != NULL)
|
||||||
iso_md5_end(&ctx, md5);
|
iso_md5_end(&ctx, md5);
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
#else /* Libisofs_with_checksumS */
|
|
||||||
|
|
||||||
return ISO_SUCCESS;
|
|
||||||
|
|
||||||
#endif /* ! Libisofs_with_checksumS */
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,8 +2,9 @@
|
|||||||
* Copyright (c) 2009 Thomas Schmitt
|
* Copyright (c) 2009 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef LIBISO_MD5_H_
|
#ifndef LIBISO_MD5_H_
|
||||||
|
@ -1,21 +1,43 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
|
* Copyright (c) 2009 - 2011 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* 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 <stdlib.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.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 "libiso_msgs.h"
|
||||||
#include "libisofs.h"
|
#include "libisofs.h"
|
||||||
#include "messages.h"
|
#include "messages.h"
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "node.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -59,11 +81,110 @@ int abort_threshold = LIBISO_MSGS_SEV_FAILURE;
|
|||||||
struct libiso_msgs *libiso_msgr = NULL;
|
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);
|
||||||
|
}
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------- End of xinfo clone functions list ----------- */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@param flag bit0= do not set up locale by LC_* environment variables
|
@param flag bit0= do not set up locale by LC_* environment variables
|
||||||
*/
|
*/
|
||||||
int iso_init_with_flag(int flag)
|
int iso_init_with_flag(int flag)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
#ifdef Libisofs_with_libjtE
|
||||||
|
|
||||||
|
/* Ugly compile time check for header version compatibility.
|
||||||
|
If everthing matches, then it produces no C code. In case of mismatch,
|
||||||
|
intentionally faulty C code will be inserted.
|
||||||
|
*/
|
||||||
|
/* The indendation 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)) {
|
if (! (flag & 1)) {
|
||||||
iso_init_locale(0);
|
iso_init_locale(0);
|
||||||
@ -74,10 +195,29 @@ int iso_init_with_flag(int flag)
|
|||||||
}
|
}
|
||||||
libiso_msgs_set_severities(libiso_msgr, LIBISO_MSGS_SEV_NEVER,
|
libiso_msgs_set_severities(libiso_msgr, LIBISO_MSGS_SEV_NEVER,
|
||||||
LIBISO_MSGS_SEV_FATAL, "libisofs: ", 0);
|
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;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int iso_init()
|
int iso_init()
|
||||||
{
|
{
|
||||||
return iso_init_with_flag(0);
|
return iso_init_with_flag(0);
|
||||||
@ -86,6 +226,7 @@ int iso_init()
|
|||||||
void iso_finish()
|
void iso_finish()
|
||||||
{
|
{
|
||||||
libiso_msgs_destroy(&libiso_msgr, 0);
|
libiso_msgs_destroy(&libiso_msgr, 0);
|
||||||
|
iso_node_xinfo_dispose_cloners(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int iso_set_abort_severity(char *severity)
|
int iso_set_abort_severity(char *severity)
|
||||||
@ -152,6 +293,8 @@ const char *iso_error_to_msg(int errcode)
|
|||||||
return "Try to set the boot image of an already bootable image";
|
return "Try to set the boot image of an already bootable image";
|
||||||
case ISO_BOOT_IMAGE_NOT_VALID:
|
case ISO_BOOT_IMAGE_NOT_VALID:
|
||||||
return "Trying to use an invalid file as boot image";
|
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:
|
case ISO_FILE_ERROR:
|
||||||
return "Error on file operation";
|
return "Error on file operation";
|
||||||
case ISO_FILE_ALREADY_OPENED:
|
case ISO_FILE_ALREADY_OPENED:
|
||||||
@ -276,6 +419,48 @@ const char *iso_error_to_msg(int errcode)
|
|||||||
return "Detected file content changes while it was written into the image";
|
return "Detected file content changes while it was written into the image";
|
||||||
case ISO_SCDBACKUP_TAG_NOT_0:
|
case ISO_SCDBACKUP_TAG_NOT_0:
|
||||||
return "Session does not start at LBA 0. scdbackup checksum tag not written.";
|
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 appended 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";
|
||||||
default:
|
default:
|
||||||
return "Unknown error";
|
return "Unknown error";
|
||||||
}
|
}
|
||||||
@ -416,8 +601,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,
|
int iso_msgs_submit(int error_code, char msg_text[], int os_errno,
|
||||||
char severity[], int origin)
|
char severity[], int origin)
|
||||||
{
|
{
|
||||||
@ -445,8 +628,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 iso_text_to_sev(char *severity_name, int *sevno)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@ -458,8 +639,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 iso_sev_to_text(int severity_number, char **severity_name)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@ -498,7 +677,6 @@ int iso_error_get_code(int e)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts A80222 */
|
|
||||||
int iso_report_errfile(char *path, int error_code, int os_errno, int flag)
|
int iso_report_errfile(char *path, int error_code, int os_errno, int flag)
|
||||||
{
|
{
|
||||||
libiso_msgs_submit(libiso_msgr, 0, error_code,
|
libiso_msgs_submit(libiso_msgr, 0, error_code,
|
||||||
@ -506,3 +684,33 @@ int iso_report_errfile(char *path, int error_code, int os_errno, int flag)
|
|||||||
path, os_errno, 0);
|
path, os_errno, 0);
|
||||||
return(1);
|
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 */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -2,8 +2,9 @@
|
|||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -45,7 +46,6 @@ int iso_msg_is_abort(int errcode);
|
|||||||
int iso_msg_submit(int imgid, int errcode, int causedby, const char *fmt, ...);
|
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
|
/* To be called with events which report incidents with individual input
|
||||||
files from the local filesystem. Not with image nodes, files containing an
|
files from the local filesystem. Not with image nodes, files containing an
|
||||||
image or similar file-like objects.
|
image or similar file-like objects.
|
||||||
@ -53,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);
|
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_*/
|
#endif /*MESSAGES_H_*/
|
||||||
|
275
libisofs/node.c
275
libisofs/node.c
@ -1,12 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
* 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
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libisofs.h"
|
#include "libisofs.h"
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
@ -22,6 +27,7 @@
|
|||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
struct dir_iter_data
|
struct dir_iter_data
|
||||||
{
|
{
|
||||||
/* points to the last visited child, to NULL before start */
|
/* points to the last visited child, to NULL before start */
|
||||||
@ -201,6 +207,7 @@ int iso_node_get_xinfo(IsoNode *node, iso_node_xinfo_func proc, void **data)
|
|||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*data = NULL;
|
||||||
pos = node->xinfo;
|
pos = node->xinfo;
|
||||||
while (pos != NULL) {
|
while (pos != NULL) {
|
||||||
if (pos->process == proc) {
|
if (pos->process == proc) {
|
||||||
@ -214,6 +221,89 @@ int iso_node_get_xinfo(IsoNode *node, iso_node_xinfo_func proc, void **data)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* API */
|
||||||
|
int iso_node_get_next_xinfo(IsoNode *node, void **handle,
|
||||||
|
iso_node_xinfo_func *proc, void **data)
|
||||||
|
{
|
||||||
|
IsoExtendedInfo *xinfo;
|
||||||
|
|
||||||
|
if (node == NULL || handle == NULL || proc == NULL || data == NULL)
|
||||||
|
return ISO_NULL_POINTER;
|
||||||
|
*proc = NULL;
|
||||||
|
*data = NULL;
|
||||||
|
xinfo = (IsoExtendedInfo *) *handle;
|
||||||
|
if (xinfo == NULL)
|
||||||
|
xinfo = node->xinfo;
|
||||||
|
else
|
||||||
|
xinfo = xinfo->next;
|
||||||
|
*handle = xinfo;
|
||||||
|
if (xinfo == NULL)
|
||||||
|
return 0;
|
||||||
|
*proc = xinfo->process;
|
||||||
|
*data = xinfo->data;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int iso_node_remove_all_xinfo(IsoNode *node, int flag)
|
||||||
|
{
|
||||||
|
IsoExtendedInfo *pos, *next;
|
||||||
|
|
||||||
|
for (pos = node->xinfo; pos != NULL; pos = next) {
|
||||||
|
next = pos->next;
|
||||||
|
pos->process(pos->data, 1);
|
||||||
|
free((char *) pos);
|
||||||
|
}
|
||||||
|
node->xinfo = NULL;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int iso_node_revert_xinfo_list(IsoNode *node, int flag)
|
||||||
|
{
|
||||||
|
|
||||||
|
IsoExtendedInfo *pos, *next, *prev = NULL;
|
||||||
|
|
||||||
|
for (pos = node->xinfo; pos != NULL; pos = next) {
|
||||||
|
next = pos->next;
|
||||||
|
pos->next = prev;
|
||||||
|
prev = pos;
|
||||||
|
}
|
||||||
|
node->xinfo = prev;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int iso_node_clone_xinfo(IsoNode *from_node, IsoNode *to_node, int flag)
|
||||||
|
{
|
||||||
|
void *handle = NULL, *data, *new_data;
|
||||||
|
iso_node_xinfo_func proc;
|
||||||
|
iso_node_xinfo_cloner cloner;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
iso_node_remove_all_xinfo(to_node, 0);
|
||||||
|
while (1) {
|
||||||
|
ret = iso_node_get_next_xinfo(from_node, &handle, &proc, &data);
|
||||||
|
if (ret <= 0)
|
||||||
|
break;
|
||||||
|
ret = iso_node_xinfo_get_cloner(proc, &cloner, 0);
|
||||||
|
if (ret == 0)
|
||||||
|
return ISO_XINFO_NO_CLONE;
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
ret = (*cloner)(data, &new_data, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
break;
|
||||||
|
ret = iso_node_add_xinfo(to_node, proc, new_data);
|
||||||
|
if (ret < 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ret < 0) {
|
||||||
|
iso_node_remove_all_xinfo(to_node, 0);
|
||||||
|
} else {
|
||||||
|
ret = iso_node_revert_xinfo_list(to_node, 0);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the type of an IsoNode.
|
* Get the type of an IsoNode.
|
||||||
*/
|
*/
|
||||||
@ -230,6 +320,7 @@ enum IsoNodeType iso_node_get_type(IsoNode *node)
|
|||||||
int iso_node_set_name(IsoNode *node, const char *name)
|
int iso_node_set_name(IsoNode *node, const char *name)
|
||||||
{
|
{
|
||||||
char *new;
|
char *new;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if ((IsoNode*)node->parent == node) {
|
if ((IsoNode*)node->parent == node) {
|
||||||
/* you can't change name of the root node */
|
/* you can't change name of the root node */
|
||||||
@ -237,9 +328,9 @@ int iso_node_set_name(IsoNode *node, const char *name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* check if the name is valid */
|
/* check if the name is valid */
|
||||||
if (!iso_node_is_valid_name(name)) {
|
ret = iso_node_is_valid_name(name);
|
||||||
return ISO_WRONG_ARG_VALUE;
|
if (ret < 0)
|
||||||
}
|
return ret;
|
||||||
|
|
||||||
if (node->parent != NULL) {
|
if (node->parent != NULL) {
|
||||||
/* check if parent already has a node with same name */
|
/* check if parent already has a node with same name */
|
||||||
@ -420,6 +511,12 @@ void iso_node_set_hidden(IsoNode *node, int hide_attrs)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int iso_node_get_hidden(IsoNode *node)
|
||||||
|
{
|
||||||
|
return node->hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a new node to a dir. Note that this function don't add a new ref to
|
* Add a new node to a dir. Note that this function don't add a new ref to
|
||||||
* the node, so you don't need to free it, it will be automatically freed
|
* the node, so you don't need to free it, it will be automatically freed
|
||||||
@ -633,6 +730,9 @@ int iso_node_take(IsoNode *node)
|
|||||||
if (dir == NULL) {
|
if (dir == NULL) {
|
||||||
return ISO_NODE_NOT_ADDED_TO_DIR;
|
return ISO_NODE_NOT_ADDED_TO_DIR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* >>> Do not take root directory ! (dir == node) ? */;
|
||||||
|
|
||||||
pos = iso_dir_find_node(dir, node);
|
pos = iso_dir_find_node(dir, node);
|
||||||
if (pos == NULL) {
|
if (pos == NULL) {
|
||||||
/* should never occur */
|
/* should never occur */
|
||||||
@ -668,6 +768,44 @@ int iso_node_remove(IsoNode *node)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* API */
|
||||||
|
int iso_node_remove_tree(IsoNode *node, IsoDirIter *boss_iter)
|
||||||
|
{
|
||||||
|
IsoDirIter *iter = NULL;
|
||||||
|
IsoNode *sub_node;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (node->type != LIBISO_DIR) {
|
||||||
|
|
||||||
|
/* >>> Do not remove root directory ! (node->parent == node) ? */;
|
||||||
|
|
||||||
|
ret = iso_dir_get_children((IsoDir *) node, &iter);
|
||||||
|
if (ret < 0)
|
||||||
|
goto ex;
|
||||||
|
while(1) {
|
||||||
|
ret = iso_dir_iter_next(iter, &sub_node);
|
||||||
|
if (ret == 0)
|
||||||
|
break;
|
||||||
|
ret = iso_node_remove_tree(sub_node, iter);
|
||||||
|
if (ret < 0)
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
if (node->parent == NULL) {
|
||||||
|
/* node is not grafted into a boss directory */
|
||||||
|
iso_node_unref(node);
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (boss_iter != NULL)
|
||||||
|
ret = iso_dir_iter_remove(boss_iter);
|
||||||
|
else
|
||||||
|
ret = iso_node_remove(node);
|
||||||
|
ex:;
|
||||||
|
if (iter != NULL)
|
||||||
|
iso_dir_iter_free(iter);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the parent of the given iso tree node. No extra ref is added to the
|
* Get the parent of the given iso tree node. No extra ref is added to the
|
||||||
* returned directory, you must take your ref. with iso_node_ref() if you
|
* returned directory, you must take your ref. with iso_node_ref() if you
|
||||||
@ -863,10 +1001,11 @@ const char *iso_symlink_get_dest(const IsoSymlink *link)
|
|||||||
int iso_symlink_set_dest(IsoSymlink *link, const char *dest)
|
int iso_symlink_set_dest(IsoSymlink *link, const char *dest)
|
||||||
{
|
{
|
||||||
char *d;
|
char *d;
|
||||||
if (!iso_node_is_valid_link_dest(dest)) {
|
int ret;
|
||||||
/* guard against null or empty dest */
|
|
||||||
return ISO_WRONG_ARG_VALUE;
|
ret = iso_node_is_valid_link_dest(dest);
|
||||||
}
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
d = strdup(dest);
|
d = strdup(dest);
|
||||||
if (d == NULL) {
|
if (d == NULL) {
|
||||||
return ISO_OUT_OF_MEM;
|
return ISO_OUT_OF_MEM;
|
||||||
@ -1017,22 +1156,23 @@ int iso_node_is_valid_name(const char *name)
|
|||||||
{
|
{
|
||||||
/* a name can't be NULL */
|
/* a name can't be NULL */
|
||||||
if (name == NULL) {
|
if (name == NULL) {
|
||||||
return 0;
|
return ISO_NULL_POINTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* guard against the empty string or big names... */
|
/* guard against the empty string or big names... */
|
||||||
if (name[0] == '\0' || strlen(name) > 255) {
|
if (name[0] == '\0')
|
||||||
return 0;
|
return ISO_RR_NAME_RESERVED;
|
||||||
}
|
if (strlen(name) > LIBISOFS_NODE_NAME_MAX)
|
||||||
|
return ISO_RR_NAME_TOO_LONG;
|
||||||
|
|
||||||
/* ...against "." and ".." names... */
|
/* ...against "." and ".." names... */
|
||||||
if (!strcmp(name, ".") || !strcmp(name, "..")) {
|
if (!strcmp(name, ".") || !strcmp(name, "..")) {
|
||||||
return 0;
|
return ISO_RR_NAME_RESERVED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ...and against names with '/' */
|
/* ...and against names with '/' */
|
||||||
if (strchr(name, '/') != NULL) {
|
if (strchr(name, '/') != NULL) {
|
||||||
return 0;
|
return ISO_RR_NAME_RESERVED;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -1050,13 +1190,14 @@ int iso_node_is_valid_link_dest(const char *dest)
|
|||||||
|
|
||||||
/* a dest can't be NULL */
|
/* a dest can't be NULL */
|
||||||
if (dest == NULL) {
|
if (dest == NULL) {
|
||||||
return 0;
|
return ISO_NULL_POINTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* guard against the empty string or big dest... */
|
/* guard against the empty string or big dest... */
|
||||||
if (dest[0] == '\0' || strlen(dest) > PATH_MAX) {
|
if (dest[0] == '\0')
|
||||||
return 0;
|
return ISO_RR_NAME_RESERVED;
|
||||||
}
|
if (strlen(dest) > LIBISOFS_NODE_PATH_MAX)
|
||||||
|
return ISO_RR_PATH_TOO_LONG;
|
||||||
|
|
||||||
/* check that all components are valid */
|
/* check that all components are valid */
|
||||||
if (!strcmp(dest, "/")) {
|
if (!strcmp(dest, "/")) {
|
||||||
@ -1066,7 +1207,7 @@ int iso_node_is_valid_link_dest(const char *dest)
|
|||||||
|
|
||||||
ptr = strdup(dest);
|
ptr = strdup(dest);
|
||||||
if (ptr == NULL) {
|
if (ptr == NULL) {
|
||||||
return 0;
|
return ISO_OUT_OF_MEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = 1;
|
ret = 1;
|
||||||
@ -1074,7 +1215,7 @@ int iso_node_is_valid_link_dest(const char *dest)
|
|||||||
while (component) {
|
while (component) {
|
||||||
if (strcmp(component, ".") && strcmp(component, "..")) {
|
if (strcmp(component, ".") && strcmp(component, "..")) {
|
||||||
ret = iso_node_is_valid_name(component);
|
ret = iso_node_is_valid_name(component);
|
||||||
if (ret == 0) {
|
if (ret < 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1233,15 +1374,16 @@ int iso_node_new_root(IsoDir **root)
|
|||||||
int iso_node_new_dir(char *name, IsoDir **dir)
|
int iso_node_new_dir(char *name, IsoDir **dir)
|
||||||
{
|
{
|
||||||
IsoDir *new;
|
IsoDir *new;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (dir == NULL || name == NULL) {
|
if (dir == NULL || name == NULL) {
|
||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check if the name is valid */
|
/* check if the name is valid */
|
||||||
if (!iso_node_is_valid_name(name)) {
|
ret = iso_node_is_valid_name(name);
|
||||||
return ISO_WRONG_ARG_VALUE;
|
if (ret < 0)
|
||||||
}
|
return ret;
|
||||||
|
|
||||||
new = calloc(1, sizeof(IsoDir));
|
new = calloc(1, sizeof(IsoDir));
|
||||||
if (new == NULL) {
|
if (new == NULL) {
|
||||||
@ -1258,15 +1400,16 @@ int iso_node_new_dir(char *name, IsoDir **dir)
|
|||||||
int iso_node_new_file(char *name, IsoStream *stream, IsoFile **file)
|
int iso_node_new_file(char *name, IsoStream *stream, IsoFile **file)
|
||||||
{
|
{
|
||||||
IsoFile *new;
|
IsoFile *new;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (file == NULL || name == NULL || stream == NULL) {
|
if (file == NULL || name == NULL || stream == NULL) {
|
||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check if the name is valid */
|
/* check if the name is valid */
|
||||||
if (!iso_node_is_valid_name(name)) {
|
ret = iso_node_is_valid_name(name);
|
||||||
return ISO_WRONG_ARG_VALUE;
|
if (ret < 0)
|
||||||
}
|
return ret;
|
||||||
|
|
||||||
new = calloc(1, sizeof(IsoFile));
|
new = calloc(1, sizeof(IsoFile));
|
||||||
if (new == NULL) {
|
if (new == NULL) {
|
||||||
@ -1276,6 +1419,7 @@ int iso_node_new_file(char *name, IsoStream *stream, IsoFile **file)
|
|||||||
new->node.type = LIBISO_FILE;
|
new->node.type = LIBISO_FILE;
|
||||||
new->node.name = name;
|
new->node.name = name;
|
||||||
new->node.mode = S_IFREG;
|
new->node.mode = S_IFREG;
|
||||||
|
new->sort_weight = 0;
|
||||||
new->stream = stream;
|
new->stream = stream;
|
||||||
|
|
||||||
*file = new;
|
*file = new;
|
||||||
@ -1285,21 +1429,21 @@ int iso_node_new_file(char *name, IsoStream *stream, IsoFile **file)
|
|||||||
int iso_node_new_symlink(char *name, char *dest, IsoSymlink **link)
|
int iso_node_new_symlink(char *name, char *dest, IsoSymlink **link)
|
||||||
{
|
{
|
||||||
IsoSymlink *new;
|
IsoSymlink *new;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (link == NULL || name == NULL || dest == NULL) {
|
if (link == NULL || name == NULL || dest == NULL) {
|
||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check if the name is valid */
|
/* check if the name is valid */
|
||||||
if (!iso_node_is_valid_name(name)) {
|
ret = iso_node_is_valid_name(name);
|
||||||
return ISO_WRONG_ARG_VALUE;
|
if (ret < 0)
|
||||||
}
|
return ret;
|
||||||
|
|
||||||
/* check if destination is valid */
|
/* check if destination is valid */
|
||||||
if (!iso_node_is_valid_link_dest(dest)) {
|
ret = iso_node_is_valid_link_dest(dest);
|
||||||
/* guard against null or empty dest */
|
if (ret < 0)
|
||||||
return ISO_WRONG_ARG_VALUE;
|
return ret;
|
||||||
}
|
|
||||||
|
|
||||||
new = calloc(1, sizeof(IsoSymlink));
|
new = calloc(1, sizeof(IsoSymlink));
|
||||||
if (new == NULL) {
|
if (new == NULL) {
|
||||||
@ -1321,6 +1465,7 @@ int iso_node_new_special(char *name, mode_t mode, dev_t dev,
|
|||||||
IsoSpecial **special)
|
IsoSpecial **special)
|
||||||
{
|
{
|
||||||
IsoSpecial *new;
|
IsoSpecial *new;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (special == NULL || name == NULL) {
|
if (special == NULL || name == NULL) {
|
||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
@ -1330,9 +1475,9 @@ int iso_node_new_special(char *name, mode_t mode, dev_t dev,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* check if the name is valid */
|
/* check if the name is valid */
|
||||||
if (!iso_node_is_valid_name(name)) {
|
ret = iso_node_is_valid_name(name);
|
||||||
return ISO_WRONG_ARG_VALUE;
|
if (ret < 0)
|
||||||
}
|
return ret;
|
||||||
|
|
||||||
new = calloc(1, sizeof(IsoSpecial));
|
new = calloc(1, sizeof(IsoSpecial));
|
||||||
if (new == NULL) {
|
if (new == NULL) {
|
||||||
@ -1476,7 +1621,7 @@ int iso_aa_lookup_attr(unsigned char *aa_string, char *name,
|
|||||||
*value_length = value_lengths[i];
|
*value_length = value_lengths[i];
|
||||||
*value = calloc(*value_length + 1, 1);
|
*value = calloc(*value_length + 1, 1);
|
||||||
if (*value == NULL) {
|
if (*value == NULL) {
|
||||||
ret = ISO_OUT_OF_MEM;
|
found = ISO_OUT_OF_MEM;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (*value_length > 0)
|
if (*value_length > 0)
|
||||||
@ -2134,6 +2279,23 @@ int zisofs_zf_xinfo_func(void *data, int flag)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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)
|
||||||
|
{
|
||||||
|
*new_data = NULL;
|
||||||
|
if (flag)
|
||||||
|
return ISO_XINFO_NO_CLONE;
|
||||||
|
if (old_data == NULL)
|
||||||
|
return 0;
|
||||||
|
*new_data = calloc(1, sizeof(struct zisofs_zf_info));
|
||||||
|
if (*new_data == NULL)
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
memcpy(*new_data, old_data, sizeof(struct zisofs_zf_info));
|
||||||
|
return (int) sizeof(struct zisofs_zf_info);
|
||||||
|
}
|
||||||
|
|
||||||
/* Checks whether a file effectively bears a zisofs file header and eventually
|
/* Checks whether a file effectively bears a zisofs file header and eventually
|
||||||
* marks this by a struct zisofs_zf_info as xinfo of the file node.
|
* marks this by a struct zisofs_zf_info as xinfo of the file node.
|
||||||
@ -2255,6 +2417,21 @@ int iso_px_ino_xinfo_func(void *data, int flag)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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)
|
||||||
|
{
|
||||||
|
*new_data = NULL;
|
||||||
|
if (flag)
|
||||||
|
return ISO_XINFO_NO_CLONE;
|
||||||
|
*new_data = calloc(1, sizeof(ino_t));
|
||||||
|
if (*new_data == NULL)
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
memcpy(*new_data, old_data, sizeof(ino_t));
|
||||||
|
return (int) sizeof(ino_t);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @param flag
|
* @param flag
|
||||||
@ -2345,7 +2522,6 @@ int iso_node_set_ino_xinfo(IsoNode *node, ino_t ino, int flag)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int iso_node_set_ino(IsoNode *node, ino_t ino, int flag)
|
int iso_node_set_ino(IsoNode *node, ino_t ino, int flag)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@ -2651,9 +2827,6 @@ ex:;
|
|||||||
/* API */
|
/* API */
|
||||||
int iso_file_get_md5(IsoImage *image, IsoFile *file, char md5[16], int flag)
|
int iso_file_get_md5(IsoImage *image, IsoFile *file, char md5[16], int flag)
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifdef Libisofs_with_checksumS
|
|
||||||
|
|
||||||
int ret, i;
|
int ret, i;
|
||||||
size_t value_len;
|
size_t value_len;
|
||||||
char *value = NULL;
|
char *value = NULL;
|
||||||
@ -2693,21 +2866,12 @@ ex:;
|
|||||||
if (value != NULL)
|
if (value != NULL)
|
||||||
free(value);
|
free(value);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
#endif /* ! Libisofs_with_checksumS */
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* API */
|
/* API */
|
||||||
int iso_file_make_md5(IsoFile *file, int flag)
|
int iso_file_make_md5(IsoFile *file, int flag)
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifdef Libisofs_with_checksumS
|
|
||||||
int ret, dig = 0;
|
int ret, dig = 0;
|
||||||
char *md5 = NULL;
|
char *md5 = NULL;
|
||||||
|
|
||||||
@ -2728,13 +2892,6 @@ int iso_file_make_md5(IsoFile *file, int flag)
|
|||||||
ret = 1;
|
ret = 1;
|
||||||
ex:;
|
ex:;
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
return ISO_ERROR;
|
|
||||||
|
|
||||||
#endif /* ! Libisofs_with_checksumS */
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
* 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
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
*/
|
*/
|
||||||
#ifndef LIBISO_NODE_H_
|
#ifndef LIBISO_NODE_H_
|
||||||
#define LIBISO_NODE_H_
|
#define LIBISO_NODE_H_
|
||||||
@ -19,7 +20,38 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_STDINT_H
|
||||||
#include <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
|
* The extended information is a way to attach additional information to each
|
||||||
@ -112,6 +144,7 @@ struct Iso_Dir
|
|||||||
IsoNode *children; /**< list of children. ptr to first child */
|
IsoNode *children; /**< list of children. ptr to first child */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* IMPORTANT: Any change must be reflected by iso_tree_clone_file. */
|
||||||
struct Iso_File
|
struct Iso_File
|
||||||
{
|
{
|
||||||
IsoNode node;
|
IsoNode node;
|
||||||
@ -276,7 +309,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.
|
* Check if a given name is valid for an iso node.
|
||||||
*
|
*
|
||||||
* @return
|
* @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);
|
int iso_node_is_valid_name(const char *name);
|
||||||
|
|
||||||
@ -472,4 +505,35 @@ int iso_root_get_isofsca(IsoNode *node, uint32_t *start_lba, uint32_t *end_lba,
|
|||||||
int flag);
|
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);
|
||||||
|
|
||||||
|
|
||||||
#endif /*LIBISO_NODE_H_*/
|
#endif /*LIBISO_NODE_H_*/
|
||||||
|
@ -4,10 +4,18 @@
|
|||||||
* Copyright (c) 2009 Thomas Schmitt
|
* Copyright (c) 2009 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* 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 <stdio.h>
|
||||||
|
|
||||||
#include "rockridge.h"
|
#include "rockridge.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
#include "ecma119_tree.h"
|
#include "ecma119_tree.h"
|
||||||
@ -17,7 +25,12 @@
|
|||||||
#include "aaip_0_2.h"
|
#include "aaip_0_2.h"
|
||||||
#include "libisofs.h"
|
#include "libisofs.h"
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
#ifdef Libisofs_with_rrip_rR
|
||||||
|
#define ISO_ROCKRIDGE_IN_DIR_REC 128
|
||||||
|
#else
|
||||||
|
#define ISO_ROCKRIDGE_IN_DIR_REC 124
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
@ -108,12 +121,12 @@ int rrip_add_PX(Ecma119Image *t, Ecma119Node *n, struct susp_info *susp)
|
|||||||
PX[2] = 36;
|
PX[2] = 36;
|
||||||
}
|
}
|
||||||
PX[3] = 1;
|
PX[3] = 1;
|
||||||
iso_bb(&PX[4], px_get_mode(t, n), 4);
|
iso_bb(&PX[4], (uint32_t) px_get_mode(t, n), 4);
|
||||||
iso_bb(&PX[12], n->nlink, 4);
|
iso_bb(&PX[12], (uint32_t) n->nlink, 4);
|
||||||
iso_bb(&PX[20], px_get_uid(t, n), 4);
|
iso_bb(&PX[20], (uint32_t) px_get_uid(t, n), 4);
|
||||||
iso_bb(&PX[28], px_get_gid(t, n), 4);
|
iso_bb(&PX[28], (uint32_t) px_get_gid(t, n), 4);
|
||||||
if (t->rrip_1_10_px_ino || !t->rrip_version_1_10) {
|
if (t->rrip_1_10_px_ino || !t->rrip_version_1_10) {
|
||||||
iso_bb(&PX[36], n->ino, 4);
|
iso_bb(&PX[36], (uint32_t) n->ino, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
return susp_append(t, susp, PX);
|
return susp_append(t, susp, PX);
|
||||||
@ -179,7 +192,8 @@ int rrip_add_PL(Ecma119Image *t, Ecma119Node *n, struct susp_info *susp)
|
|||||||
PL[3] = 1;
|
PL[3] = 1;
|
||||||
|
|
||||||
/* write the location of the real parent, already computed */
|
/* write the location of the real parent, already computed */
|
||||||
iso_bb(&PL[4], n->info.dir->real_parent->info.dir->block, 4);
|
iso_bb(&PL[4],
|
||||||
|
n->info.dir->real_parent->info.dir->block - t->eff_partition_offset, 4);
|
||||||
return susp_append(t, susp, PL);
|
return susp_append(t, susp, PL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,10 +256,10 @@ int rrip_add_PN(Ecma119Image *t, Ecma119Node *n, struct susp_info *susp)
|
|||||||
*/
|
*/
|
||||||
if (sizeof(node->dev) > 4) {
|
if (sizeof(node->dev) > 4) {
|
||||||
high_shift = 32;
|
high_shift = 32;
|
||||||
iso_bb(&PN[4], node->dev >> high_shift, 4);
|
iso_bb(&PN[4], (uint32_t) (node->dev >> high_shift), 4);
|
||||||
} else
|
} else
|
||||||
iso_bb(&PN[4], 0, 4);
|
iso_bb(&PN[4], 0, 4);
|
||||||
iso_bb(&PN[12], node->dev & 0xffffffff, 4);
|
iso_bb(&PN[12], (uint32_t) (node->dev & 0xffffffff), 4);
|
||||||
return susp_append(t, susp, PN);
|
return susp_append(t, susp, PN);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -272,7 +286,8 @@ int rrip_add_CL(Ecma119Image *t, Ecma119Node *n, struct susp_info *susp)
|
|||||||
CL[1] = 'L';
|
CL[1] = 'L';
|
||||||
CL[2] = 12;
|
CL[2] = 12;
|
||||||
CL[3] = 1;
|
CL[3] = 1;
|
||||||
iso_bb(&CL[4], n->info.real_me->info.dir->block, 4);
|
iso_bb(&CL[4], n->info.real_me->info.dir->block - t->eff_partition_offset,
|
||||||
|
4);
|
||||||
return susp_append(t, susp, CL);
|
return susp_append(t, susp, CL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -322,7 +337,12 @@ static
|
|||||||
int rrip_add_NM(Ecma119Image *t, struct susp_info *susp, char *name, int size,
|
int rrip_add_NM(Ecma119Image *t, struct susp_info *susp, char *name, int size,
|
||||||
int flags, int ce)
|
int flags, int ce)
|
||||||
{
|
{
|
||||||
uint8_t *NM = malloc(size + 5);
|
uint8_t *NM;
|
||||||
|
|
||||||
|
if (size > 250)
|
||||||
|
return ISO_ASSERT_FAILURE;
|
||||||
|
|
||||||
|
NM = malloc(size + 5);
|
||||||
if (NM == NULL) {
|
if (NM == NULL) {
|
||||||
return ISO_OUT_OF_MEM;
|
return ISO_OUT_OF_MEM;
|
||||||
}
|
}
|
||||||
@ -692,9 +712,10 @@ int susp_add_CE(Ecma119Image *t, size_t ce_len, struct susp_info *susp)
|
|||||||
CE[1] = 'E';
|
CE[1] = 'E';
|
||||||
CE[2] = 28;
|
CE[2] = 28;
|
||||||
CE[3] = 1;
|
CE[3] = 1;
|
||||||
iso_bb(&CE[4], susp->ce_block, 4);
|
|
||||||
|
iso_bb(&CE[4], susp->ce_block - t->eff_partition_offset, 4);
|
||||||
iso_bb(&CE[12], susp->ce_len, 4);
|
iso_bb(&CE[12], susp->ce_len, 4);
|
||||||
iso_bb(&CE[20], ce_len, 4);
|
iso_bb(&CE[20], (uint32_t) ce_len, 4);
|
||||||
|
|
||||||
return susp_append(t, susp, CE);
|
return susp_append(t, susp, CE);
|
||||||
}
|
}
|
||||||
@ -889,7 +910,7 @@ int add_zf_field(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* API */
|
||||||
int aaip_xinfo_func(void *data, int flag)
|
int aaip_xinfo_func(void *data, int flag)
|
||||||
{
|
{
|
||||||
if (flag & 1) {
|
if (flag & 1) {
|
||||||
@ -898,6 +919,23 @@ int aaip_xinfo_func(void *data, int flag)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* API */
|
||||||
|
int aaip_xinfo_cloner(void *old_data, void **new_data, int flag)
|
||||||
|
{
|
||||||
|
size_t aa_size;
|
||||||
|
|
||||||
|
*new_data = NULL;
|
||||||
|
if (old_data == NULL)
|
||||||
|
return 0;
|
||||||
|
aa_size = aaip_count_bytes((unsigned char *) old_data, 0);
|
||||||
|
if (aa_size <= 0)
|
||||||
|
return ISO_AAIP_BAD_AASTRING;
|
||||||
|
*new_data = calloc(1, aa_size);
|
||||||
|
if (*new_data == NULL)
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
memcpy(*new_data, old_data, aa_size);
|
||||||
|
return (int) aa_size;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compute SUA length and eventual Continuation Area length of field NM and
|
* Compute SUA length and eventual Continuation Area length of field NM and
|
||||||
@ -912,6 +950,7 @@ int aaip_xinfo_func(void *data, int flag)
|
|||||||
* (*su_size and *ce stay unaltered in this case)
|
* (*su_size and *ce stay unaltered in this case)
|
||||||
* <0= error:
|
* <0= error:
|
||||||
* -1= not enough SUA space for 28 bytes of CE entry
|
* -1= not enough SUA space for 28 bytes of CE entry
|
||||||
|
* -2= out of memory
|
||||||
*/
|
*/
|
||||||
static
|
static
|
||||||
int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
|
int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
|
||||||
@ -948,6 +987,9 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
|
|||||||
if (!(flag & 1))
|
if (!(flag & 1))
|
||||||
goto unannounced_ca;
|
goto unannounced_ca;
|
||||||
namelen = namelen - (space - *su_size - 5);
|
namelen = namelen - (space - *su_size - 5);
|
||||||
|
|
||||||
|
/* >>> Need to handle lengths > 250 */;
|
||||||
|
|
||||||
*ce = 5 + namelen;
|
*ce = 5 + namelen;
|
||||||
*su_size = space;
|
*su_size = space;
|
||||||
}
|
}
|
||||||
@ -960,6 +1002,8 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
|
|||||||
int cew = (*ce != 0); /* are we writing to CA ? */
|
int cew = (*ce != 0); /* are we writing to CA ? */
|
||||||
|
|
||||||
dest = get_rr_fname(t, ((IsoSymlink*)n->node)->dest);
|
dest = get_rr_fname(t, ((IsoSymlink*)n->node)->dest);
|
||||||
|
if (dest == NULL)
|
||||||
|
return -2;
|
||||||
prev = dest;
|
prev = dest;
|
||||||
cur = strchr(prev, '/');
|
cur = strchr(prev, '/');
|
||||||
while (1) {
|
while (1) {
|
||||||
@ -988,8 +1032,10 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
|
|||||||
* TODO this can be handled better, but for now SL
|
* TODO this can be handled better, but for now SL
|
||||||
* will be completelly moved into the CA
|
* will be completelly moved into the CA
|
||||||
*/
|
*/
|
||||||
if (!(flag & 1))
|
if (!(flag & 1)) {
|
||||||
|
free(dest);
|
||||||
goto unannounced_ca;
|
goto unannounced_ca;
|
||||||
|
}
|
||||||
cew = 1;
|
cew = 1;
|
||||||
} else {
|
} else {
|
||||||
sl_len += clen;
|
sl_len += clen;
|
||||||
@ -1089,6 +1135,44 @@ unannounced_ca:;
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* @param flag bit0= Do not add data but only count sua_free and ce_len
|
||||||
|
param info may be NULL in this case
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
int add_aa_string(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
|
||||||
|
size_t *sua_free, size_t *ce_len, int flag)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
uint8_t *aapt;
|
||||||
|
void *xipt;
|
||||||
|
size_t num_aapt= 0;
|
||||||
|
|
||||||
|
if (!t->aaip)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
ret = iso_node_get_xinfo(n->node, aaip_xinfo_func, &xipt);
|
||||||
|
if (ret == 1) {
|
||||||
|
num_aapt = aaip_count_bytes((unsigned char *) xipt, 0);
|
||||||
|
if (num_aapt > 0) {
|
||||||
|
if (flag & 1) {
|
||||||
|
ret = aaip_add_AL(t, NULL,NULL, num_aapt, sua_free, ce_len, 1);
|
||||||
|
} else {
|
||||||
|
aapt = malloc(num_aapt);
|
||||||
|
if (aapt == NULL)
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
memcpy(aapt, xipt, num_aapt);
|
||||||
|
ret = aaip_add_AL(t, info, &aapt, num_aapt, sua_free, ce_len,
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
/* aapt is NULL now and the memory is owned by t */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compute the length needed for write all RR and SUSP entries for a given
|
* Compute the length needed for write all RR and SUSP entries for a given
|
||||||
* node.
|
* node.
|
||||||
@ -1096,27 +1180,31 @@ unannounced_ca:;
|
|||||||
* @param type
|
* @param type
|
||||||
* 0 normal entry, 1 "." entry for that node (it is a dir), 2 ".."
|
* 0 normal entry, 1 "." entry for that node (it is a dir), 2 ".."
|
||||||
* for that node (i.e., it will refer to the parent)
|
* for that node (i.e., it will refer to the parent)
|
||||||
* @param space
|
* @param used_up
|
||||||
* Available space in the System Use Area for the directory record.
|
* Already occupied space in the directory record.
|
||||||
* @param ce
|
* @param ce
|
||||||
* Will be filled with the space needed in a CE
|
* Will be filled with the space needed in a CE
|
||||||
* @return
|
* @return
|
||||||
* The size needed for the RR entries in the System Use Area
|
* 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 rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t used_up,
|
||||||
size_t *ce)
|
size_t *ce)
|
||||||
{
|
{
|
||||||
size_t su_size;
|
size_t su_size, space;
|
||||||
int ret;
|
int ret;
|
||||||
|
size_t aaip_sua_free= 0, aaip_len= 0;
|
||||||
|
|
||||||
|
/* Directory record length must be even (ECMA-119, 9.1.13). Maximum is 254.
|
||||||
|
*/
|
||||||
|
space = 254 - used_up - (used_up % 2);
|
||||||
|
if (type < 0 || type > 2 || space < ISO_ROCKRIDGE_IN_DIR_REC) {
|
||||||
|
iso_msg_submit(t->image->id, ISO_ASSERT_FAILURE, 0,
|
||||||
|
"Unknown node type %d or short RR space %d < %d in directory record",
|
||||||
|
type, (int) space, ISO_ROCKRIDGE_IN_DIR_REC);
|
||||||
|
return ISO_ASSERT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
/* space min is 255 - 33 - 37 = 185
|
|
||||||
* At the same time, it is always an odd number, but we need to pad it
|
|
||||||
* propertly to ensure the length of a directory record is a even number
|
|
||||||
* (ECMA-119, 9.1.13). Thus, in fact the real space is always space - 1
|
|
||||||
*/
|
|
||||||
space--;
|
|
||||||
*ce = 0;
|
*ce = 0;
|
||||||
|
|
||||||
su_size = 0;
|
su_size = 0;
|
||||||
|
|
||||||
/* If AAIP enabled and announced by ER : account for 5 bytes of ES */;
|
/* If AAIP enabled and announced by ER : account for 5 bytes of ES */;
|
||||||
@ -1161,7 +1249,9 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t space,
|
|||||||
/* Try without CE */
|
/* Try without CE */
|
||||||
ret = susp_calc_nm_sl_al(t, n, space, &su_size, ce, 0);
|
ret = susp_calc_nm_sl_al(t, n, space, &su_size, ce, 0);
|
||||||
if (ret == 0) /* Retry with CE */
|
if (ret == 0) /* Retry with CE */
|
||||||
susp_calc_nm_sl_al(t, n, space, &su_size, ce, 1);
|
ret = susp_calc_nm_sl_al(t, n, space, &su_size, ce, 1);
|
||||||
|
if (ret == -2)
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
@ -1182,9 +1272,15 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t space,
|
|||||||
} else {
|
} else {
|
||||||
*ce = 182;
|
*ce = 182;
|
||||||
}
|
}
|
||||||
if (t->aaip) {
|
if (t->aaip && !t->aaip_susp_1_10) {
|
||||||
*ce += 160; /* ER of AAIP */
|
*ce += 160; /* ER of AAIP */
|
||||||
}
|
}
|
||||||
|
/* Compute length of AAIP string of root node */
|
||||||
|
aaip_sua_free= 0;
|
||||||
|
ret = add_aa_string(t, n, NULL, &aaip_sua_free, &aaip_len, 1);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
*ce += aaip_len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1216,43 +1312,6 @@ void susp_info_free(struct susp_info* susp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* @param flag bit0= Do not add data but only count sua_free and ce_len
|
|
||||||
*/
|
|
||||||
static
|
|
||||||
int add_aa_string(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
|
|
||||||
size_t *sua_free, size_t *ce_len, int flag)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
uint8_t *aapt;
|
|
||||||
void *xipt;
|
|
||||||
size_t num_aapt= 0;
|
|
||||||
|
|
||||||
if (!t->aaip)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
ret = iso_node_get_xinfo(n->node, aaip_xinfo_func, &xipt);
|
|
||||||
if (ret == 1) {
|
|
||||||
num_aapt = aaip_count_bytes((unsigned char *) xipt, 0);
|
|
||||||
if (num_aapt > 0) {
|
|
||||||
if (flag & 1) {
|
|
||||||
ret = aaip_add_AL(t, NULL,NULL, num_aapt, sua_free, ce_len, 1);
|
|
||||||
} else {
|
|
||||||
aapt = malloc(num_aapt);
|
|
||||||
if (aapt == NULL)
|
|
||||||
return ISO_OUT_OF_MEM;
|
|
||||||
memcpy(aapt, xipt, num_aapt);
|
|
||||||
ret = aaip_add_AL(t, info, &aapt, num_aapt, sua_free, ce_len,
|
|
||||||
0);
|
|
||||||
}
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
/* aapt is NULL now and the memory is owned by t */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fill a struct susp_info with the RR/SUSP entries needed for a given
|
* Fill a struct susp_info with the RR/SUSP entries needed for a given
|
||||||
* node.
|
* node.
|
||||||
@ -1260,8 +1319,8 @@ int add_aa_string(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
|
|||||||
* @param type
|
* @param type
|
||||||
* 0 normal entry, 1 "." entry for that node (it is a dir), 2 ".."
|
* 0 normal entry, 1 "." entry for that node (it is a dir), 2 ".."
|
||||||
* for that node (i.e., it will refer to the parent)
|
* for that node (i.e., it will refer to the parent)
|
||||||
* @param space
|
* @param used_up
|
||||||
* Available space in the System Use Area for the directory record.
|
* Already occupied space in the directory record.
|
||||||
* @param info
|
* @param info
|
||||||
* Pointer to the struct susp_info where the entries will be stored.
|
* 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
|
* If some entries need to go to a Continuation Area, they will be added
|
||||||
@ -1271,7 +1330,7 @@ int add_aa_string(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
|
|||||||
* 1 success, < 0 error
|
* 1 success, < 0 error
|
||||||
*/
|
*/
|
||||||
int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
||||||
size_t space, struct susp_info *info)
|
size_t used_up, struct susp_info *info)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
size_t i;
|
size_t i;
|
||||||
@ -1283,13 +1342,20 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
|||||||
size_t su_size_pd, ce_len_pd; /* predicted sizes of SUA and CA */
|
size_t su_size_pd, ce_len_pd; /* predicted sizes of SUA and CA */
|
||||||
int ce_is_predicted = 0;
|
int ce_is_predicted = 0;
|
||||||
size_t aaip_sua_free= 0, aaip_len= 0;
|
size_t aaip_sua_free= 0, aaip_len= 0;
|
||||||
|
size_t space;
|
||||||
|
|
||||||
if (t == NULL || n == NULL || info == NULL) {
|
if (t == NULL || n == NULL || info == NULL) {
|
||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
}
|
}
|
||||||
if (type < 0 || type > 2 || space < 185) {
|
|
||||||
/* space min is 255 - 33 - 37 = 185 */
|
/* Directory record length must be even (ECMA-119, 9.1.13). Maximum is 254.
|
||||||
return ISO_WRONG_ARG_VALUE;
|
*/
|
||||||
|
space = 254 - used_up - (used_up % 2);
|
||||||
|
if (type < 0 || type > 2 || space < ISO_ROCKRIDGE_IN_DIR_REC) {
|
||||||
|
iso_msg_submit(t->image->id, ISO_ASSERT_FAILURE, 0,
|
||||||
|
"Unknown node type %d or short RR space %d < %d in directory record",
|
||||||
|
type, (int) space, ISO_ROCKRIDGE_IN_DIR_REC);
|
||||||
|
return ISO_ASSERT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == 2 && n->parent != NULL) {
|
if (type == 2 && n->parent != NULL) {
|
||||||
@ -1298,13 +1364,6 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
|||||||
node = n;
|
node = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* space min is 255 - 33 - 37 = 185
|
|
||||||
* At the same time, it is always an odd number, but we need to pad it
|
|
||||||
* propertly to ensure the length of a directory record is a even number
|
|
||||||
* (ECMA-119, 9.1.13). Thus, in fact the real space is always space - 1
|
|
||||||
*/
|
|
||||||
space--;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SP must be the first entry for the "." record of the root directory
|
* SP must be the first entry for the "." record of the root directory
|
||||||
* (SUSP, 5.3)
|
* (SUSP, 5.3)
|
||||||
@ -1376,6 +1435,13 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (info->suf_len + 28 > space) {
|
||||||
|
iso_msg_submit(t->image->id, ISO_ASSERT_FAILURE, 0,
|
||||||
|
"Directory Record overflow. name='%s' , suf_len=%d > space=%d - 28\n",
|
||||||
|
node->iso_name, (int) info->suf_len, (int) space);
|
||||||
|
return ISO_ASSERT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
if (type == 0) {
|
if (type == 0) {
|
||||||
size_t sua_free; /* free space in the SUA */
|
size_t sua_free; /* free space in the SUA */
|
||||||
int nm_type = 0; /* 0 whole entry in SUA, 1 part in CE */
|
int nm_type = 0; /* 0 whole entry in SUA, 1 part in CE */
|
||||||
@ -1396,10 +1462,14 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
|||||||
ce_len_pd = ce_len;
|
ce_len_pd = ce_len;
|
||||||
ret = susp_calc_nm_sl_al(t, n, space, &su_size_pd, &ce_len_pd, 0);
|
ret = susp_calc_nm_sl_al(t, n, space, &su_size_pd, &ce_len_pd, 0);
|
||||||
if (ret == 0) { /* Have to use CA. 28 bytes of CE are necessary */
|
if (ret == 0) { /* Have to use CA. 28 bytes of CE are necessary */
|
||||||
susp_calc_nm_sl_al(t, n, space, &su_size_pd, &ce_len_pd, 1);
|
ret = susp_calc_nm_sl_al(t, n, space, &su_size_pd, &ce_len_pd, 1);
|
||||||
sua_free -= 28;
|
sua_free -= 28;
|
||||||
ce_is_predicted = 1;
|
ce_is_predicted = 1;
|
||||||
}
|
}
|
||||||
|
if (ret == -2) {
|
||||||
|
ret = ISO_OUT_OF_MEM;
|
||||||
|
goto add_susp_cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
/* NM entry */
|
/* NM entry */
|
||||||
if (5 + namelen <= sua_free) {
|
if (5 + namelen <= sua_free) {
|
||||||
@ -1597,6 +1667,9 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
|||||||
/*
|
/*
|
||||||
* ..and the part that goes to continuation area.
|
* ..and the part that goes to continuation area.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* >>> Need a loop to handle lengths > 250 */;
|
||||||
|
|
||||||
ret = rrip_add_NM(t, info, name + namelen, strlen(name + namelen),
|
ret = rrip_add_NM(t, info, name + namelen, strlen(name + namelen),
|
||||||
0, 1);
|
0, 1);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@ -1662,7 +1735,7 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
|||||||
|
|
||||||
/* Compute length of AAIP string of root node */
|
/* Compute length of AAIP string of root node */
|
||||||
aaip_sua_free= 0;
|
aaip_sua_free= 0;
|
||||||
ret = add_aa_string(t, n, info, &aaip_sua_free, &aaip_len, 1);
|
ret = add_aa_string(t, n, NULL, &aaip_sua_free, &aaip_len, 1);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto add_susp_cleanup;
|
goto add_susp_cleanup;
|
||||||
|
|
||||||
|
@ -4,8 +4,9 @@
|
|||||||
* Copyright (c) 2009 Thomas Schmitt
|
* Copyright (c) 2009 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3,8 +3,9 @@
|
|||||||
* Copyright (c) 2009 Thomas Schmitt
|
* Copyright (c) 2009 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -12,6 +13,10 @@
|
|||||||
* Rock Ridge and AAIP extensions on an ECMA-119 image.
|
* Rock Ridge and AAIP extensions on an ECMA-119 image.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libisofs.h"
|
#include "libisofs.h"
|
||||||
#include "ecma119.h"
|
#include "ecma119.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
@ -438,7 +443,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,
|
int read_aaip_AA(struct susp_sys_user_entry *sue,
|
||||||
unsigned char **aa_string, size_t *aa_size, size_t *aa_len,
|
unsigned char **aa_string, size_t *aa_size, size_t *aa_len,
|
||||||
@ -509,7 +514,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,
|
int read_aaip_AL(struct susp_sys_user_entry *sue,
|
||||||
unsigned char **aa_string, size_t *aa_size, size_t *aa_len,
|
unsigned char **aa_string, size_t *aa_size, size_t *aa_len,
|
||||||
|
@ -1,22 +1,34 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
* 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
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libisofs.h"
|
#include "libisofs.h"
|
||||||
#include "stream.h"
|
#include "stream.h"
|
||||||
#include "fsource.h"
|
#include "fsource.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "node.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef PATH_MAX
|
||||||
|
#define PATH_MAX Libisofs_default_path_maX
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
ino_t serial_id = (ino_t)1;
|
ino_t serial_id = (ino_t)1;
|
||||||
ino_t mem_serial_id = (ino_t)1;
|
ino_t mem_serial_id = (ino_t)1;
|
||||||
ino_t cut_out_serial_id = (ino_t)1;
|
ino_t cut_out_serial_id = (ino_t)1;
|
||||||
@ -146,8 +158,64 @@ int fsrc_update_size(IsoStream *stream)
|
|||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
IsoStream *fsrc_get_input_stream(IsoStream *stream, int flag)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int fsrc_cmp_ino(IsoStream *s1, IsoStream *s2)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = iso_stream_cmp_ino(s1, s2, 1);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
IsoStreamIface fsrc_stream_class = {
|
IsoStreamIface fsrc_stream_class = {
|
||||||
1, /* update_size is defined for this stream */
|
4, /* version */
|
||||||
"fsrc",
|
"fsrc",
|
||||||
fsrc_open,
|
fsrc_open,
|
||||||
fsrc_close,
|
fsrc_close,
|
||||||
@ -156,7 +224,10 @@ IsoStreamIface fsrc_stream_class = {
|
|||||||
fsrc_is_repeatable,
|
fsrc_is_repeatable,
|
||||||
fsrc_get_id,
|
fsrc_get_id,
|
||||||
fsrc_free,
|
fsrc_free,
|
||||||
fsrc_update_size
|
fsrc_update_size,
|
||||||
|
fsrc_get_input_stream,
|
||||||
|
fsrc_cmp_ino,
|
||||||
|
fsrc_clone_stream
|
||||||
};
|
};
|
||||||
|
|
||||||
int iso_file_source_stream_new(IsoFileSource *src, IsoStream **stream)
|
int iso_file_source_stream_new(IsoFileSource *src, IsoStream **stream)
|
||||||
@ -364,11 +435,76 @@ void cut_out_free(IsoStream *stream)
|
|||||||
free(data);
|
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_cmp_ino(IsoStream *s1, IsoStream *s2)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = iso_stream_cmp_ino(s1, s2, 1);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
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.
|
* TODO update cut out streams to deal with update_size(). Seems hard.
|
||||||
*/
|
*/
|
||||||
IsoStreamIface cut_out_stream_class = {
|
IsoStreamIface cut_out_stream_class = {
|
||||||
0,
|
4, /* version */
|
||||||
"cout",
|
"cout",
|
||||||
cut_out_open,
|
cut_out_open,
|
||||||
cut_out_close,
|
cut_out_close,
|
||||||
@ -376,7 +512,12 @@ IsoStreamIface cut_out_stream_class = {
|
|||||||
cut_out_read,
|
cut_out_read,
|
||||||
cut_out_is_repeatable,
|
cut_out_is_repeatable,
|
||||||
cut_out_get_id,
|
cut_out_get_id,
|
||||||
cut_out_free
|
cut_out_free,
|
||||||
|
cut_out_update_size,
|
||||||
|
cut_out_get_input_stream,
|
||||||
|
cut_out_cmp_ino,
|
||||||
|
cut_out_clone_stream
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int iso_cut_out_stream_new(IsoFileSource *src, off_t offset, off_t size,
|
int iso_cut_out_stream_new(IsoFileSource *src, off_t offset, off_t size,
|
||||||
@ -538,12 +679,77 @@ void mem_free(IsoStream *stream)
|
|||||||
{
|
{
|
||||||
MemStreamData *data;
|
MemStreamData *data;
|
||||||
data = (MemStreamData*)stream->data;
|
data = (MemStreamData*)stream->data;
|
||||||
free(data->buf);
|
if (data->buf != NULL)
|
||||||
|
free(data->buf);
|
||||||
free(data);
|
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_cmp_ino(IsoStream *s1, IsoStream *s2)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = iso_stream_cmp_ino(s1, s2, 1);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
IsoStreamIface mem_stream_class = {
|
IsoStreamIface mem_stream_class = {
|
||||||
0,
|
4, /* version */
|
||||||
"mem ",
|
"mem ",
|
||||||
mem_open,
|
mem_open,
|
||||||
mem_close,
|
mem_close,
|
||||||
@ -551,7 +757,12 @@ IsoStreamIface mem_stream_class = {
|
|||||||
mem_read,
|
mem_read,
|
||||||
mem_is_repeatable,
|
mem_is_repeatable,
|
||||||
mem_get_id,
|
mem_get_id,
|
||||||
mem_free
|
mem_free,
|
||||||
|
mem_update_size,
|
||||||
|
mem_get_input_stream,
|
||||||
|
mem_cmp_ino,
|
||||||
|
mem_clone_stream
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -559,7 +770,7 @@ IsoStreamIface mem_stream_class = {
|
|||||||
* When the Stream refcount reach 0, the buffer is free(3).
|
* When the Stream refcount reach 0, the buffer is free(3).
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* 1 sucess, < 0 error
|
* 1 success, < 0 error
|
||||||
*/
|
*/
|
||||||
int iso_memory_stream_new(unsigned char *buf, size_t size, IsoStream **stream)
|
int iso_memory_stream_new(unsigned char *buf, size_t size, IsoStream **stream)
|
||||||
{
|
{
|
||||||
@ -575,7 +786,7 @@ int iso_memory_stream_new(unsigned char *buf, size_t size, IsoStream **stream)
|
|||||||
return ISO_OUT_OF_MEM;
|
return ISO_OUT_OF_MEM;
|
||||||
}
|
}
|
||||||
data = malloc(sizeof(MemStreamData));
|
data = malloc(sizeof(MemStreamData));
|
||||||
if (str == NULL) {
|
if (data == NULL) {
|
||||||
free(str);
|
free(str);
|
||||||
return ISO_OUT_OF_MEM;
|
return ISO_OUT_OF_MEM;
|
||||||
}
|
}
|
||||||
@ -658,7 +869,8 @@ void iso_stream_get_file_name(IsoStream *stream, char *name)
|
|||||||
if (!strncmp(type, "fsrc", 4)) {
|
if (!strncmp(type, "fsrc", 4)) {
|
||||||
FSrcStreamData *data = stream->data;
|
FSrcStreamData *data = stream->data;
|
||||||
char *path = iso_file_source_get_path(data->src);
|
char *path = iso_file_source_get_path(data->src);
|
||||||
strncpy(name, path, PATH_MAX);
|
strncpy(name, path, PATH_MAX - 1);
|
||||||
|
name[PATH_MAX - 1] = 0;
|
||||||
free(path);
|
free(path);
|
||||||
} else if (!strncmp(type, "boot", 4)) {
|
} else if (!strncmp(type, "boot", 4)) {
|
||||||
strcpy(name, "BOOT CATALOG");
|
strcpy(name, "BOOT CATALOG");
|
||||||
@ -857,9 +1069,6 @@ int iso_stream_read_buffer(IsoStream *stream, char *buf, size_t count,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef Libisofs_with_checksumS
|
|
||||||
|
|
||||||
|
|
||||||
/* @param flag bit0= dig out most original stream (e.g. because from old image)
|
/* @param flag bit0= dig out most original stream (e.g. because from old image)
|
||||||
@return 1=ok, md5 is valid,
|
@return 1=ok, md5 is valid,
|
||||||
0= not ok,
|
0= not ok,
|
||||||
@ -917,5 +1126,41 @@ ex:;
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
#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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
* 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
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
*/
|
*/
|
||||||
#ifndef LIBISO_STREAM_H_
|
#ifndef LIBISO_STREAM_H_
|
||||||
#define LIBISO_STREAM_H_
|
#define LIBISO_STREAM_H_
|
||||||
@ -14,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
#include "fsource.h"
|
#include "fsource.h"
|
||||||
|
|
||||||
|
/* IMPORTANT: Any change must be reflected by fsrc_clone_stream */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
IsoFileSource *src;
|
IsoFileSource *src;
|
||||||
@ -27,7 +29,8 @@ typedef struct
|
|||||||
/**
|
/**
|
||||||
* Get an identifier for the file of the source, for debug purposes
|
* Get an identifier for the file of the source, for debug purposes
|
||||||
* @param name
|
* @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);
|
void iso_stream_get_file_name(IsoStream *stream, char *name);
|
||||||
|
|
||||||
@ -54,15 +57,6 @@ int iso_file_source_stream_new(IsoFileSource *src, IsoStream **stream);
|
|||||||
int iso_cut_out_stream_new(IsoFileSource *src, off_t offset, off_t size,
|
int iso_cut_out_stream_new(IsoFileSource *src, off_t offset, off_t size,
|
||||||
IsoStream **stream);
|
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
|
* Obtain eventual zisofs ZF field entry parameters from a file source out
|
||||||
* of a loaded ISO image.
|
* of a loaded ISO image.
|
||||||
@ -102,5 +96,20 @@ 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 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);
|
||||||
|
|
||||||
#endif /*STREAM_H_*/
|
#endif /*STREAM_H_*/
|
||||||
|
@ -1,38 +1,695 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2008 Vreixo Formoso
|
* Copyright (c) 2008 Vreixo Formoso
|
||||||
|
* Copyright (c) 2010 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "libisofs.h"
|
||||||
#include "system_area.h"
|
#include "system_area.h"
|
||||||
#include "eltorito.h"
|
#include "eltorito.h"
|
||||||
#include "filesrc.h"
|
#include "filesrc.h"
|
||||||
|
#include "ecma119_tree.h"
|
||||||
|
#include "image.h"
|
||||||
|
#include "messages.h"
|
||||||
|
#include "ecma119.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create a MBR for an isohybrid enabled ISOLINUX boot image.
|
* Create a MBR for an isohybrid enabled ISOLINUX boot image.
|
||||||
*
|
* See libisofs/make_isohybrid_mbr.c
|
||||||
* It is assumed that the caller has verified the readiness of the boot image
|
* Deprecated.
|
||||||
* by checking for 0xfb 0xc0 0x78 0x70 at bytes 0x40 to 0x43 of isolinux.bin.
|
|
||||||
*
|
|
||||||
* @param bin_lba The predicted LBA of isolinux.bin within the emerging ISO.
|
|
||||||
* @param img_blocks The predicted number of 2048 byte blocks in the ISO.
|
|
||||||
* It will get rounded up to full MBs and that many blocks
|
|
||||||
* must really be written as ISO 9660 image.
|
|
||||||
* @param mbr A buffer of at least 512 bytes to take the result which is
|
|
||||||
* to be written as the very beginning of the ISO.
|
|
||||||
* @param flag unused yet, submit 0
|
|
||||||
* @return <0 = fatal, 0 = failed , 1 = ok , 2 = ok with size warning
|
|
||||||
*/
|
*/
|
||||||
int make_isohybrid_mbr(int bin_lba, int *img_blocks, char *mbr, int flag);
|
int make_isohybrid_mbr(int bin_lba, int *img_blocks, char *mbr, int flag);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The New ISOLINUX MBR Producer.
|
||||||
|
* Be cautious with changing parameters. Only few combinations are tested.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int make_isolinux_mbr(uint32_t *img_blocks, uint32_t boot_lba,
|
||||||
|
uint32_t mbr_id, int head_count, int sector_count,
|
||||||
|
int part_offset, int part_number, int fs_type,
|
||||||
|
uint8_t *buf, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @param flag bit0= img_blocks is start address rather than end address:
|
||||||
|
do not subtract 1
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
void iso_compute_cyl_head_sec(uint32_t *img_blocks, int hpc, int sph,
|
||||||
|
uint32_t *end_lba, uint32_t *end_sec,
|
||||||
|
uint32_t *end_head, uint32_t *end_cyl, int flag)
|
||||||
|
{
|
||||||
|
uint32_t secs;
|
||||||
|
|
||||||
|
/* Partition table unit is 512 bytes per sector, ECMA-119 unit is 2048 */
|
||||||
|
if (*img_blocks >= 0x40000000)
|
||||||
|
*img_blocks = 0x40000000 - 1; /* truncate rather than roll over */
|
||||||
|
if (flag & 1)
|
||||||
|
secs = *end_lba = *img_blocks * 4; /* first valid 512-lba */
|
||||||
|
else
|
||||||
|
secs = *end_lba = *img_blocks * 4 - 1; /* last valid 512-lba */
|
||||||
|
*end_cyl = secs / (sph * hpc);
|
||||||
|
secs -= *end_cyl * sph * hpc;
|
||||||
|
*end_head = secs / sph;
|
||||||
|
*end_sec = secs - *end_head * sph + 1; /* Sector count starts by 1 */
|
||||||
|
if (*end_cyl >= 1024) {
|
||||||
|
*end_cyl = 1023;
|
||||||
|
*end_head = hpc - 1;
|
||||||
|
*end_sec = sph;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Compute size and position of appended partitions.
|
||||||
|
*/
|
||||||
|
int iso_compute_append_partitions(Ecma119Image *t, int flag)
|
||||||
|
{
|
||||||
|
int ret, i, sa_type;
|
||||||
|
uint32_t pos, size, add_pos = 0;
|
||||||
|
struct stat stbuf;
|
||||||
|
|
||||||
|
sa_type = (t->system_area_options >> 2) & 0x3f;
|
||||||
|
pos = (t->vol_space_size + t->ms_block);
|
||||||
|
for (i = 0; i < ISO_MAX_PARTITIONS; i++) {
|
||||||
|
if (t->appended_partitions[i] == NULL)
|
||||||
|
continue;
|
||||||
|
if (t->appended_partitions[i][0] == 0)
|
||||||
|
continue;
|
||||||
|
ret = stat(t->appended_partitions[i], &stbuf);
|
||||||
|
if (ret == -1)
|
||||||
|
return ISO_BAD_PARTITION_FILE;
|
||||||
|
if (! S_ISREG(stbuf.st_mode))
|
||||||
|
return ISO_BAD_PARTITION_FILE;
|
||||||
|
size = ((stbuf.st_size + 2047) / 2048);
|
||||||
|
if (sa_type == 3 && (pos % ISO_SUN_CYL_SIZE))
|
||||||
|
add_pos = ISO_SUN_CYL_SIZE - (pos % ISO_SUN_CYL_SIZE);
|
||||||
|
t->appended_part_prepad[i] = add_pos;
|
||||||
|
t->appended_part_start[i] = pos + add_pos;
|
||||||
|
t->appended_part_size[i] = size;
|
||||||
|
pos += add_pos + size;
|
||||||
|
t->total_size += (add_pos + size) * 2048;
|
||||||
|
}
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Note: partition_offset and partition_size are counted in 2048 blocks
|
||||||
|
*/
|
||||||
|
static int write_mbr_partition_entry(int partition_number, int partition_type,
|
||||||
|
uint32_t partition_offset, uint32_t partition_size,
|
||||||
|
int sph, int hpc, uint8_t *buf, int flag)
|
||||||
|
{
|
||||||
|
uint8_t *wpt;
|
||||||
|
uint32_t end_lba, end_sec, end_head, end_cyl;
|
||||||
|
uint32_t start_lba, start_sec, start_head, start_cyl;
|
||||||
|
uint32_t after_end;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
after_end = partition_offset + partition_size;
|
||||||
|
iso_compute_cyl_head_sec(&partition_offset, hpc, sph,
|
||||||
|
&start_lba, &start_sec, &start_head, &start_cyl, 1);
|
||||||
|
iso_compute_cyl_head_sec(&after_end, hpc, sph,
|
||||||
|
&end_lba, &end_sec, &end_head, &end_cyl, 0);
|
||||||
|
wpt = buf + 446 + (partition_number - 1) * 16;
|
||||||
|
|
||||||
|
/* Not bootable */
|
||||||
|
*(wpt++) = 0x00;
|
||||||
|
|
||||||
|
/* C/H/S of the start */
|
||||||
|
*(wpt++) = start_head;
|
||||||
|
*(wpt++) = start_sec | ((start_cyl & 0x300) >> 2);
|
||||||
|
*(wpt++) = start_cyl & 0xff;
|
||||||
|
|
||||||
|
/* (partition type) */
|
||||||
|
*(wpt++) = partition_type;
|
||||||
|
|
||||||
|
/* 3 bytes of C/H/S end */
|
||||||
|
*(wpt++) = end_head;
|
||||||
|
*(wpt++) = end_sec | ((end_cyl & 0x300) >> 2);
|
||||||
|
*(wpt++) = end_cyl & 0xff;
|
||||||
|
|
||||||
|
/* LBA start in little endian */
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
*(wpt++) = (start_lba >> (8 * i)) & 0xff;
|
||||||
|
|
||||||
|
/* Number of sectors in partition, little endian */
|
||||||
|
end_lba = end_lba - start_lba + 1;
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
*(wpt++) = (end_lba >> (8 * i)) & 0xff;
|
||||||
|
|
||||||
|
/* Afaik, partition tables are recognize donly with MBR signature */
|
||||||
|
buf[510] = 0x55;
|
||||||
|
buf[511] = 0xAA;
|
||||||
|
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* This is the gesture of grub-mkisofs --protective-msdos-label as explained by
|
||||||
|
Vladimir Serbinenko <phcoder@gmail.com>, 2 April 2010, on grub-devel@gnu.org
|
||||||
|
"Currently we use first and not last entry. You need to:
|
||||||
|
1) Zero-fill 446-510
|
||||||
|
2) Put 0x55, 0xAA into 510-512
|
||||||
|
3) Put 0x80 (for bootable partition), 0, 2, 0 (C/H/S of the start), 0xcd
|
||||||
|
(partition type), [3 bytes of C/H/S end], 0x01, 0x00, 0x00, 0x00 (LBA
|
||||||
|
start in little endian), [LBA end in little endian] at 446-462
|
||||||
|
"
|
||||||
|
|
||||||
|
"C/H/S end" means the CHS address of the last block in the partition.
|
||||||
|
It seems that not "[LBA end in little endian]" but "number of blocks"
|
||||||
|
should go into bytes 458-461. But with a start lba of 1, this is the
|
||||||
|
same number.
|
||||||
|
See also http://en.wikipedia.org/wiki/Master_boot_record
|
||||||
|
|
||||||
|
flag bit0= do not write 0x55, 0xAA to 510,511
|
||||||
|
bit1= do not mark partition as bootable
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
int make_grub_msdos_label(uint32_t img_blocks, int sph, int hpc,
|
||||||
|
uint8_t *buf, int flag)
|
||||||
|
{
|
||||||
|
uint8_t *wpt;
|
||||||
|
uint32_t end_lba, end_sec, end_head, end_cyl;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
iso_compute_cyl_head_sec(&img_blocks, hpc, sph,
|
||||||
|
&end_lba, &end_sec, &end_head, &end_cyl, 0);
|
||||||
|
|
||||||
|
/* 1) Zero-fill 446-510 */
|
||||||
|
wpt = buf + 446;
|
||||||
|
memset(wpt, 0, 64);
|
||||||
|
|
||||||
|
if (!(flag & 1)) {
|
||||||
|
/* 2) Put 0x55, 0xAA into 510-512 (actually 510-511) */
|
||||||
|
buf[510] = 0x55;
|
||||||
|
buf[511] = 0xAA;
|
||||||
|
}
|
||||||
|
if (!(flag & 2)) {
|
||||||
|
/* 3) Put 0x80 (for bootable partition), */
|
||||||
|
*(wpt++) = 0x80;
|
||||||
|
} else {
|
||||||
|
*(wpt++) = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 0, 2, 0 (C/H/S of the start), */
|
||||||
|
*(wpt++) = 0;
|
||||||
|
*(wpt++) = 2;
|
||||||
|
*(wpt++) = 0;
|
||||||
|
|
||||||
|
/* 0xcd (partition type) */
|
||||||
|
*(wpt++) = 0xcd;
|
||||||
|
|
||||||
|
/* [3 bytes of C/H/S end], */
|
||||||
|
*(wpt++) = end_head;
|
||||||
|
*(wpt++) = end_sec | ((end_cyl & 0x300) >> 2);
|
||||||
|
*(wpt++) = end_cyl & 0xff;
|
||||||
|
|
||||||
|
|
||||||
|
/* 0x01, 0x00, 0x00, 0x00 (LBA start in little endian), */
|
||||||
|
*(wpt++) = 0x01;
|
||||||
|
*(wpt++) = 0x00;
|
||||||
|
*(wpt++) = 0x00;
|
||||||
|
*(wpt++) = 0x00;
|
||||||
|
|
||||||
|
/* [LBA end in little endian] */
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
*(wpt++) = (end_lba >> (8 * i)) & 0xff;
|
||||||
|
|
||||||
|
/* at 446-462 */
|
||||||
|
if (wpt - buf != 462) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"libisofs: program error in make_grub_msdos_label: \"assert 462\"\n");
|
||||||
|
return ISO_ASSERT_FAILURE;
|
||||||
|
}
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* @param flag bit0= zeroize partitions entries 2, 3, 4
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
int iso_offset_partition_start(uint32_t img_blocks, uint32_t partition_offset,
|
||||||
|
int sph, int hpc, uint8_t *buf, int flag)
|
||||||
|
{
|
||||||
|
uint8_t *wpt;
|
||||||
|
uint32_t end_lba, end_sec, end_head, end_cyl;
|
||||||
|
uint32_t start_lba, start_sec, start_head, start_cyl;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
iso_compute_cyl_head_sec(&partition_offset, hpc, sph,
|
||||||
|
&start_lba, &start_sec, &start_head, &start_cyl, 1);
|
||||||
|
iso_compute_cyl_head_sec(&img_blocks, hpc, sph,
|
||||||
|
&end_lba, &end_sec, &end_head, &end_cyl, 0);
|
||||||
|
wpt = buf + 446;
|
||||||
|
|
||||||
|
/* Let pass only legal bootability values */
|
||||||
|
if (*wpt != 0 && *wpt != 0x80)
|
||||||
|
(*wpt) = 0;
|
||||||
|
wpt++;
|
||||||
|
|
||||||
|
/* C/H/S of the start */
|
||||||
|
*(wpt++) = start_head;
|
||||||
|
*(wpt++) = start_sec | ((start_cyl & 0x300) >> 2);
|
||||||
|
*(wpt++) = start_cyl & 0xff;
|
||||||
|
|
||||||
|
/* (partition type) */
|
||||||
|
wpt++;
|
||||||
|
|
||||||
|
/* 3 bytes of C/H/S end */
|
||||||
|
*(wpt++) = end_head;
|
||||||
|
*(wpt++) = end_sec | ((end_cyl & 0x300) >> 2);
|
||||||
|
*(wpt++) = end_cyl & 0xff;
|
||||||
|
|
||||||
|
/* LBA start in little endian */
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
*(wpt++) = (start_lba >> (8 * i)) & 0xff;
|
||||||
|
|
||||||
|
/* Number of sectors in partition, little endian */
|
||||||
|
end_lba = end_lba - start_lba + 1;
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
*(wpt++) = (end_lba >> (8 * i)) & 0xff;
|
||||||
|
|
||||||
|
if (wpt - buf != 462) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"libisofs: program error in iso_offset_partition_start: \"assert 462\"\n");
|
||||||
|
return ISO_ASSERT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flag & 1) /* zeroize the other partition entries */
|
||||||
|
memset(wpt, 0, 3 * 16);
|
||||||
|
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int boot_nodes_from_iso_path(Ecma119Image *t, char *path,
|
||||||
|
IsoNode **iso_node, Ecma119Node **ecma_node,
|
||||||
|
char *purpose, int flag)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = iso_tree_path_to_node(t->image, path, iso_node);
|
||||||
|
if (ret <= 0) {
|
||||||
|
iso_msg_submit(t->image->id, ISO_BOOT_FILE_MISSING, 0,
|
||||||
|
"Cannot find in ISO image: %s '%s'", purpose, path);
|
||||||
|
return ISO_BOOT_FILE_MISSING;
|
||||||
|
}
|
||||||
|
if ((*iso_node)->type != LIBISO_FILE) {
|
||||||
|
iso_msg_submit(t->image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
|
||||||
|
"Designated boot file is not a data file: '%s'", path);
|
||||||
|
return ISO_BOOT_IMAGE_NOT_VALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ecma_node= ecma119_search_iso_node(t, *iso_node);
|
||||||
|
if (*ecma_node == NULL) {
|
||||||
|
iso_msg_submit(t->image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
|
||||||
|
"Program error: IsoFile has no Ecma119Node: '%s'", path);
|
||||||
|
return ISO_ASSERT_FAILURE;
|
||||||
|
} else {
|
||||||
|
if ((*ecma_node)->type != ECMA119_FILE) {
|
||||||
|
iso_msg_submit(t->image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
|
||||||
|
"Program error: Ecma119Node of IsoFile is no ECMA119_FILE: '%s'",
|
||||||
|
path);
|
||||||
|
return ISO_ASSERT_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* This function was implemented according to doc/boot_sectors.txt section
|
||||||
|
"MIPS Volume Header" which was derived by Thomas Schmitt from
|
||||||
|
cdrkit-1.1.10/genisoimage/boot-mips.c by Steve McIntyre which is based
|
||||||
|
on work of Florian Lohoff and Thiemo Seufer who possibly learned from
|
||||||
|
documents of MIPS Computer Systems, Inc. and Silicon Graphics Computer
|
||||||
|
Systems, Inc.
|
||||||
|
This function itself is entirely under copyright (C) 2010 Thomas Schmitt.
|
||||||
|
*/
|
||||||
|
static int make_mips_volume_header(Ecma119Image *t, uint8_t *buf, int flag)
|
||||||
|
{
|
||||||
|
char *namept, *name_field;
|
||||||
|
uint32_t num_cyl, idx, blocks, num, checksum;
|
||||||
|
off_t image_size;
|
||||||
|
static uint32_t bps = 512, spt = 32;
|
||||||
|
Ecma119Node *ecma_node;
|
||||||
|
IsoNode *node;
|
||||||
|
IsoStream *stream;
|
||||||
|
off_t file_size;
|
||||||
|
uint32_t file_lba;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* Bytes 512 to 32767 may come from image or external file */
|
||||||
|
memset(buf, 0, 512);
|
||||||
|
|
||||||
|
image_size = t->curblock * 2048;
|
||||||
|
|
||||||
|
/* 0 - 3 | 0x0be5a941 | Magic number */
|
||||||
|
iso_msb(buf, 0x0be5a941, 4);
|
||||||
|
|
||||||
|
/* 28 - 29 | num_cyl_l | Number of usable cylinder, lower two bytes */
|
||||||
|
num_cyl = (image_size + (bps * spt) - 1) / (bps * spt);
|
||||||
|
iso_msb(buf + 28, num_cyl & 0xffff, 2);
|
||||||
|
|
||||||
|
/* 32 - 33 | 1 | Number of tracks per cylinder */
|
||||||
|
iso_msb(buf + 32, 1, 2);
|
||||||
|
|
||||||
|
/* 35 - 35 | num_cyl_h | Number of usable cylinders, high byte */
|
||||||
|
buf[35] = (num_cyl >> 16) & 0xff;
|
||||||
|
|
||||||
|
/* 38 - 39 | 32 | Sectors per track */
|
||||||
|
iso_msb(buf + 38, spt, 2);
|
||||||
|
|
||||||
|
/* 40 - 41 | 512 | Bytes per sector */
|
||||||
|
iso_msb(buf + 40, bps, 2);
|
||||||
|
|
||||||
|
/* 44 - 47 | 0x00000034 | Controller characteristics */
|
||||||
|
iso_msb(buf + 44, 0x00000034, 4);
|
||||||
|
|
||||||
|
/* 72 - 87 | ========== | Volume Directory Entry 1 */
|
||||||
|
/* 72 - 79 | boot_name | Boot file basename */
|
||||||
|
/* 80 - 83 | boot_block | ISO 9660 LBA of boot file * 4 */
|
||||||
|
/* 84 - 87 | boot_bytes | File length in bytes */
|
||||||
|
/* 88 - 311 | 0 | Volume Directory Entries 2 to 15 */
|
||||||
|
|
||||||
|
for (idx = 0; idx < t->image->num_mips_boot_files; idx++) {
|
||||||
|
ret = boot_nodes_from_iso_path(t, t->image->mips_boot_file_paths[idx],
|
||||||
|
&node, &ecma_node, "MIPS boot file", 0);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
namept = (char *) iso_node_get_name(node);
|
||||||
|
name_field = (char *) (buf + (72 + 16 * idx));
|
||||||
|
strncpy(name_field, namept, 8);
|
||||||
|
|
||||||
|
file_lba = ecma_node->info.file->sections[0].block;
|
||||||
|
|
||||||
|
iso_msb(buf + (72 + 16 * idx) + 8, file_lba * 4, 4);
|
||||||
|
|
||||||
|
stream = iso_file_get_stream((IsoFile *) node);
|
||||||
|
file_size = iso_stream_get_size(stream);
|
||||||
|
|
||||||
|
/* Shall i really round up to 2048 ? Steve says yes.*/
|
||||||
|
iso_msb(buf + (72 + 16 * idx) + 12,
|
||||||
|
((file_size + 2047) / 2048 ) * 2048, 4);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 408 - 411 | part_blks | Number of 512 byte blocks in partition */
|
||||||
|
blocks = (image_size + bps - 1) / bps;
|
||||||
|
iso_msb(buf + 408, blocks, 4);
|
||||||
|
/* 416 - 419 | 0 | Partition is volume header */
|
||||||
|
iso_msb(buf + 416, 0, 4);
|
||||||
|
|
||||||
|
/* 432 - 435 | part_blks | Number of 512 byte blocks in partition */
|
||||||
|
iso_msb(buf + 432, blocks, 4);
|
||||||
|
iso_msb(buf + 444, 6, 4);
|
||||||
|
|
||||||
|
/* 504 - 507 | head_chk | Volume header checksum
|
||||||
|
The two's complement of bytes 0 to 503 read
|
||||||
|
as big endian unsigned 32 bit:
|
||||||
|
sum(32-bit-words) + head_chk == 0
|
||||||
|
*/
|
||||||
|
checksum = 0;
|
||||||
|
for (idx = 0; idx < 504; idx += 4) {
|
||||||
|
num = iso_read_msb(buf + idx, 4);
|
||||||
|
/* Addition modulo a natural number is commutative and associative.
|
||||||
|
Thus the inverse of a sum is the sum of the inverses of the addends.
|
||||||
|
*/
|
||||||
|
checksum -= num;
|
||||||
|
}
|
||||||
|
iso_msb(buf + 504, checksum, 4);
|
||||||
|
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* The following two functions were implemented according to
|
||||||
|
doc/boot_sectors.txt section "MIPS Little Endian" which was derived
|
||||||
|
by Thomas Schmitt from
|
||||||
|
cdrkit-1.1.10/genisoimage/boot-mipsel.c by Steve McIntyre which is based
|
||||||
|
on work of Florian Lohoff and Thiemo Seufer,
|
||||||
|
and from <elf.h> by Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
Both functions are entirely under copyright (C) 2010 Thomas Schmitt.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the necessary ELF information from the first MIPS boot file.
|
||||||
|
* This is done before image writing starts.
|
||||||
|
*/
|
||||||
|
int iso_read_mipsel_elf(Ecma119Image *t, int flag)
|
||||||
|
{
|
||||||
|
uint32_t phdr_adr, todo, count;
|
||||||
|
int ret;
|
||||||
|
uint8_t elf_buf[2048];
|
||||||
|
IsoNode *iso_node;
|
||||||
|
Ecma119Node *ecma_node;
|
||||||
|
IsoStream *stream;
|
||||||
|
|
||||||
|
if (t->image->num_mips_boot_files <= 0)
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
|
||||||
|
ret = boot_nodes_from_iso_path(t, t->image->mips_boot_file_paths[0],
|
||||||
|
&iso_node, &ecma_node, "MIPS boot file", 0);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
stream = iso_file_get_stream((IsoFile *) iso_node);
|
||||||
|
|
||||||
|
ret = iso_stream_open(stream);
|
||||||
|
if (ret < 0) {
|
||||||
|
iso_msg_submit(t->image->id, ret, 0,
|
||||||
|
"Cannot open designated MIPS boot file '%s'",
|
||||||
|
t->image->mips_boot_file_paths[0]);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
ret = iso_stream_read(stream, elf_buf, 32);
|
||||||
|
if (ret != 32) {
|
||||||
|
cannot_read:;
|
||||||
|
iso_stream_close(stream);
|
||||||
|
iso_msg_submit(t->image->id, ret, 0,
|
||||||
|
"Cannot read from designated MIPS boot file '%s'",
|
||||||
|
t->image->mips_boot_file_paths[0]);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 24 - 27 | e_entry | Entry point virtual address */
|
||||||
|
t->mipsel_e_entry = iso_read_lsb(elf_buf + 24, 4);
|
||||||
|
|
||||||
|
/* 28 - 31 | e_phoff | Program header table file offset */
|
||||||
|
phdr_adr = iso_read_lsb(elf_buf + 28, 4);
|
||||||
|
|
||||||
|
/* Skip stream up to byte address phdr_adr */
|
||||||
|
todo = phdr_adr - 32;
|
||||||
|
while (todo > 0) {
|
||||||
|
if (todo > 2048)
|
||||||
|
count = 2048;
|
||||||
|
else
|
||||||
|
count = todo;
|
||||||
|
todo -= count;
|
||||||
|
ret = iso_stream_read(stream, elf_buf, count);
|
||||||
|
if (ret != count)
|
||||||
|
goto cannot_read;
|
||||||
|
}
|
||||||
|
ret = iso_stream_read(stream, elf_buf, 20);
|
||||||
|
if (ret != 20)
|
||||||
|
goto cannot_read;
|
||||||
|
|
||||||
|
/* 4 - 7 | p_offset | Segment file offset */
|
||||||
|
t->mipsel_p_offset = iso_read_lsb(elf_buf + 4, 4);
|
||||||
|
|
||||||
|
/* 8 - 11 | p_vaddr | Segment virtual address */
|
||||||
|
t->mipsel_p_vaddr = iso_read_lsb(elf_buf + 8, 4);
|
||||||
|
|
||||||
|
/* 16 - 19 | p_filesz | Segment size in file */
|
||||||
|
t->mipsel_p_filesz = iso_read_lsb(elf_buf + 16, 4);
|
||||||
|
|
||||||
|
iso_stream_close(stream);
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write DEC Bootblock from previously read ELF parameters.
|
||||||
|
* This is done when image writing has already begun.
|
||||||
|
*/
|
||||||
|
static int make_mipsel_boot_block(Ecma119Image *t, uint8_t *buf, int flag)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
uint32_t seg_size, seg_start;
|
||||||
|
IsoNode *iso_node;
|
||||||
|
Ecma119Node *ecma_node;
|
||||||
|
|
||||||
|
/* Bytes 512 to 32767 may come from image or external file */
|
||||||
|
memset(buf, 0, 512);
|
||||||
|
|
||||||
|
if (t->image->num_mips_boot_files <= 0)
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
|
||||||
|
ret = boot_nodes_from_iso_path(t, t->image->mips_boot_file_paths[0],
|
||||||
|
&iso_node, &ecma_node, "MIPS boot file", 0);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
/* 8 - 11 | 0x0002757a | Magic number */
|
||||||
|
iso_lsb(buf + 8, 0x0002757a, 4);
|
||||||
|
|
||||||
|
/* 12 - 15 | 1 | Mode 1: Multi extent boot */
|
||||||
|
iso_lsb(buf + 12, 1, 4);
|
||||||
|
|
||||||
|
/* 16 - 19 | load_adr | Load address */
|
||||||
|
iso_lsb(buf + 16, t->mipsel_p_vaddr, 4);
|
||||||
|
|
||||||
|
/* 20 - 23 | exec_adr | Execution address */
|
||||||
|
iso_lsb(buf + 20, t->mipsel_e_entry, 4);
|
||||||
|
|
||||||
|
/* 24 - 27 | seg_size | Segment size in file. */
|
||||||
|
seg_size = (t->mipsel_p_filesz + 511) / 512;
|
||||||
|
iso_lsb(buf + 24, seg_size, 4);
|
||||||
|
|
||||||
|
/* 28 - 31 | seg_start | Segment file offset */
|
||||||
|
seg_start = ecma_node->info.file->sections[0].block * 4
|
||||||
|
+ (t->mipsel_p_offset + 511) / 512;
|
||||||
|
iso_lsb(buf + 28, seg_start, 4);
|
||||||
|
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* The following two functions were implemented according to
|
||||||
|
doc/boot_sectors.txt section "SUN Disk Label and boot images" which
|
||||||
|
was derived by Thomas Schmitt from
|
||||||
|
cdrtools-2.01.01a77/mkisofs/sunlabel.h
|
||||||
|
cdrtools-2.01.01a77/mkisofs/mkisofs.8
|
||||||
|
by Joerg Schilling
|
||||||
|
|
||||||
|
Both functions are entirely under copyright (C) 2010 Thomas Schmitt.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* @parm flag bit0= copy from next lower valid partition table entry
|
||||||
|
*/
|
||||||
|
static int write_sun_partition_entry(int partition_number,
|
||||||
|
char *appended_partitions[],
|
||||||
|
uint32_t partition_offset[], uint32_t partition_size[],
|
||||||
|
uint32_t cyl_size, uint8_t *buf, int flag)
|
||||||
|
{
|
||||||
|
uint8_t *wpt;
|
||||||
|
int read_idx, i;
|
||||||
|
|
||||||
|
if (partition_number < 1 || partition_number > 8)
|
||||||
|
return ISO_ASSERT_FAILURE;
|
||||||
|
|
||||||
|
/* 142 - 173 | ========== | 8 partition entries of 4 bytes */
|
||||||
|
wpt = buf + 142 + (partition_number - 1) * 4;
|
||||||
|
if (partition_number == 1)
|
||||||
|
iso_msb(wpt, 4, 2); /* 4 = User partition */
|
||||||
|
else
|
||||||
|
iso_msb(wpt, 2, 2); /* 2 = Root partition with boot image */
|
||||||
|
iso_msb(wpt + 2, 0x10, 2); /* Permissions: 0x10 = read-only */
|
||||||
|
|
||||||
|
/* 444 - 507 | ========== | Partition table */
|
||||||
|
wpt = buf + 444 + (partition_number - 1) * 8;
|
||||||
|
read_idx = partition_number - 1;
|
||||||
|
if (flag & 1) {
|
||||||
|
/* Search next lower valid partition table entry. #1 is default */
|
||||||
|
for (read_idx = partition_number - 2; read_idx > 0; read_idx--)
|
||||||
|
if (appended_partitions[read_idx] != NULL)
|
||||||
|
if (appended_partitions[read_idx][0] != 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
iso_msb(wpt, partition_offset[read_idx] / (uint32_t) ISO_SUN_CYL_SIZE, 4);
|
||||||
|
iso_msb(wpt + 4, partition_size[read_idx] * 4, 4);
|
||||||
|
|
||||||
|
/* 510 - 511 | checksum | The result of exoring 2-byte words 0 to 254 */
|
||||||
|
buf[510] = buf[511] = 0;
|
||||||
|
for (i = 0; i < 510; i += 2) {
|
||||||
|
buf[510] ^= buf[i];
|
||||||
|
buf[511] ^= buf[i + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write SUN Disk Label with ISO in partition 1 and unused 2 to 8
|
||||||
|
*/
|
||||||
|
static int make_sun_disk_label(Ecma119Image *t, uint8_t *buf, int flag)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* Bytes 512 to 32767 may come from image or external file */
|
||||||
|
memset(buf, 0, 512);
|
||||||
|
|
||||||
|
/* 0 - 127 | label | ASCII Label */
|
||||||
|
if (t->ascii_disc_label[0])
|
||||||
|
strncpy((char *) buf, t->ascii_disc_label, 128);
|
||||||
|
else
|
||||||
|
strcpy((char *) buf,
|
||||||
|
"CD-ROM Disc with Sun sparc boot created by libisofs");
|
||||||
|
|
||||||
|
/* 128 - 131 | 1 | Layout version */
|
||||||
|
iso_msb(buf + 128, 1, 4);
|
||||||
|
|
||||||
|
/* 140 - 141 | 8 | Number of partitions */
|
||||||
|
iso_msb(buf + 140, 8, 2);
|
||||||
|
|
||||||
|
/* 188 - 191 | 0x600ddeee | vtoc sanity */
|
||||||
|
iso_msb(buf + 188, 0x600ddeee, 4);
|
||||||
|
|
||||||
|
/* 420 - 421 | 350 | Rotations per minute */
|
||||||
|
iso_msb(buf + 420, 350, 2);
|
||||||
|
|
||||||
|
/* 422 - 423 | 2048 | Number of physical cylinders (fixely 640 MB) */
|
||||||
|
iso_msb(buf + 422, 2048, 2);
|
||||||
|
|
||||||
|
/* 430 - 431 | 1 | interleave factor */
|
||||||
|
iso_msb(buf + 430, 1, 2);
|
||||||
|
|
||||||
|
/* 432 - 433 | 2048 | Number of data cylinders (fixely 640 MB) */
|
||||||
|
iso_msb(buf + 432, 2048, 2);
|
||||||
|
|
||||||
|
/* 436 - 437 | 1 | Number of heads per cylinder (1 cyl = 320 kB)*/
|
||||||
|
iso_msb(buf + 436, 1, 2);
|
||||||
|
|
||||||
|
/* 438 - 439 | 640 | Number of sectors per head (1 head = 320 kB) */
|
||||||
|
iso_msb(buf + 438, 640, 2);
|
||||||
|
|
||||||
|
/* 508 - 509 | 0xdabe | Magic Number */
|
||||||
|
iso_msb(buf + 508, 0xdabe, 2);
|
||||||
|
|
||||||
|
/* Set partition 1 to describe ISO image and compute checksum */
|
||||||
|
t->appended_part_start[0] = 0;
|
||||||
|
t->appended_part_size[0] = t->curblock;
|
||||||
|
ret = write_sun_partition_entry(1, t->appended_partitions,
|
||||||
|
t->appended_part_start, t->appended_part_size,
|
||||||
|
ISO_SUN_CYL_SIZE, buf, 0);
|
||||||
|
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
|
int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
|
||||||
{
|
{
|
||||||
|
int ret, int_img_blocks, sa_type, i, will_append = 0;
|
||||||
|
int first_partition = 1, last_partition = 4;
|
||||||
|
uint32_t img_blocks;
|
||||||
|
|
||||||
if ((t == NULL) || (buf == NULL)) {
|
if ((t == NULL) || (buf == NULL)) {
|
||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
}
|
}
|
||||||
@ -40,26 +697,230 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
|
|||||||
/* set buf to 0s */
|
/* set buf to 0s */
|
||||||
memset(buf, 0, 16 * BLOCK_SIZE);
|
memset(buf, 0, 16 * BLOCK_SIZE);
|
||||||
|
|
||||||
if (t->catalog != NULL && t->catalog->image->isolinux_options & 0x02) {
|
sa_type = (t->system_area_options >> 2) & 0x3f;
|
||||||
/* We need to write a MBR for an hybrid image */
|
if (sa_type == 3) {
|
||||||
int ret;
|
first_partition = 2;
|
||||||
int img_blocks;
|
last_partition = 8;
|
||||||
|
}
|
||||||
|
for (i = first_partition - 1; i <= last_partition - 1; i++)
|
||||||
|
if (t->appended_partitions[i] != NULL) {
|
||||||
|
will_append = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
img_blocks = t->curblock;
|
img_blocks = t->curblock;
|
||||||
ret = make_isohybrid_mbr(t->bootimg->sections[0].block, &img_blocks, (char*)buf, 0);
|
if (t->system_area_data != NULL) {
|
||||||
|
/* Write more or less opaque boot image */
|
||||||
/*
|
memcpy(buf, t->system_area_data, 16 * BLOCK_SIZE);
|
||||||
API description of el_torito_set_isolinux_options() prescribes
|
|
||||||
to pad to full MB.
|
|
||||||
So this is not urgent any more :
|
|
||||||
|
|
||||||
// FIXME the new img_blocks size should be taken into account
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
} else if (sa_type == 0 && t->catalog != NULL &&
|
||||||
|
(t->catalog->bootimages[0]->isolinux_options & 0x0a) == 0x02) {
|
||||||
|
/* Check for isolinux image with magic number of 3.72 and produce
|
||||||
|
an MBR from our built-in template. (Deprecated since 31 Mar 2010)
|
||||||
|
*/
|
||||||
|
if (img_blocks < 0x80000000) {
|
||||||
|
int_img_blocks= img_blocks;
|
||||||
|
} else {
|
||||||
|
int_img_blocks= 0x7ffffff0;
|
||||||
|
}
|
||||||
|
ret = make_isohybrid_mbr(t->bootsrc[0]->sections[0].block,
|
||||||
|
&int_img_blocks, (char*)buf, 0);
|
||||||
if (ret != 1) {
|
if (ret != 1) {
|
||||||
/* error, it should never happen */
|
/* error, it should never happen */
|
||||||
return ISO_ASSERT_FAILURE;
|
return ISO_ASSERT_FAILURE;
|
||||||
}
|
}
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
if (sa_type == 0 && (t->system_area_options & 1)) {
|
||||||
|
/* Write GRUB protective msdos label, i.e. a simple partition table */
|
||||||
|
ret = make_grub_msdos_label(img_blocks, t->partition_secs_per_head,
|
||||||
|
t->partition_heads_per_cyl, buf, 0);
|
||||||
|
if (ret != ISO_SUCCESS) /* error should never happen */
|
||||||
|
return ISO_ASSERT_FAILURE;
|
||||||
|
} else if(sa_type == 0 && (t->system_area_options & 2)) {
|
||||||
|
/* Patch externally provided system area as isohybrid MBR */
|
||||||
|
if (t->catalog == NULL || t->system_area_data == NULL) {
|
||||||
|
/* isohybrid makes only sense together with ISOLINUX boot image
|
||||||
|
and externally provided System Area.
|
||||||
|
*/
|
||||||
|
return ISO_ISOLINUX_CANT_PATCH;
|
||||||
|
}
|
||||||
|
ret = make_isolinux_mbr(&img_blocks, t->bootsrc[0]->sections[0].block,
|
||||||
|
(uint32_t) 0, t->partition_heads_per_cyl,
|
||||||
|
t->partition_secs_per_head, 0, 1, 0x17, buf, 1);
|
||||||
|
if (ret != 1)
|
||||||
|
return ret;
|
||||||
|
} else if (sa_type == 1) {
|
||||||
|
ret = make_mips_volume_header(t, buf, 0);
|
||||||
|
if (ret != ISO_SUCCESS)
|
||||||
|
return ret;
|
||||||
|
} else if (sa_type == 2) {
|
||||||
|
ret = make_mipsel_boot_block(t, buf, 0);
|
||||||
|
if (ret != ISO_SUCCESS)
|
||||||
|
return ret;
|
||||||
|
} else if ((t->partition_offset > 0 || will_append) && sa_type == 0) {
|
||||||
|
/* Write a simple partition table. */
|
||||||
|
ret = make_grub_msdos_label(img_blocks, t->partition_secs_per_head,
|
||||||
|
t->partition_heads_per_cyl, buf, 2);
|
||||||
|
if (ret != ISO_SUCCESS) /* error should never happen */
|
||||||
|
return ISO_ASSERT_FAILURE;
|
||||||
|
if (t->partition_offset == 0) {
|
||||||
|
/* Re-write partion entry 1 : start at 0, type Linux */
|
||||||
|
ret = write_mbr_partition_entry(1, 0x83, 0, img_blocks,
|
||||||
|
t->partition_secs_per_head, t->partition_heads_per_cyl,
|
||||||
|
buf, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
} else if (sa_type == 3) {
|
||||||
|
ret = make_sun_disk_label(t, buf, 0);
|
||||||
|
if (ret != ISO_SUCCESS)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t->partition_offset > 0 && sa_type == 0) {
|
||||||
|
/* Adjust partition table to partition offset */
|
||||||
|
img_blocks = t->curblock; /* value might be altered */
|
||||||
|
ret = iso_offset_partition_start(img_blocks, t->partition_offset,
|
||||||
|
t->partition_secs_per_head,
|
||||||
|
t->partition_heads_per_cyl, buf, 1);
|
||||||
|
if (ret != ISO_SUCCESS) /* error should never happen */
|
||||||
|
return ISO_ASSERT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This eventually overwrites the partition table entries made so far */
|
||||||
|
for (i = first_partition - 1; i <= last_partition - 1; i++) {
|
||||||
|
if (t->appended_partitions[i] == NULL)
|
||||||
|
continue;
|
||||||
|
if (sa_type == 3) {
|
||||||
|
ret = write_sun_partition_entry(i + 1, t->appended_partitions,
|
||||||
|
t->appended_part_start, t->appended_part_size,
|
||||||
|
ISO_SUN_CYL_SIZE,
|
||||||
|
buf, t->appended_partitions[i][0] == 0);
|
||||||
|
} else {
|
||||||
|
ret = write_mbr_partition_entry(i + 1, t->appended_part_types[i],
|
||||||
|
t->appended_part_start[i], t->appended_part_size[i],
|
||||||
|
t->partition_secs_per_head, t->partition_heads_per_cyl,
|
||||||
|
buf, 0);
|
||||||
|
}
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Choose *heads_per_cyl so that
|
||||||
|
- *heads_per_cyl * secs_per_head * 1024 >= imgsize / 512
|
||||||
|
- *heads_per_cyl * secs_per_head is divisible by 4
|
||||||
|
- it is as small as possible (to reduce aligment overhead)
|
||||||
|
- it is <= 255
|
||||||
|
@return 1= success , 0= cannot achieve goals
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
int try_sph(off_t imgsize, int secs_per_head, int *heads_per_cyl, int flag)
|
||||||
|
{
|
||||||
|
off_t hd_blocks, hpc;
|
||||||
|
|
||||||
|
hd_blocks= imgsize / 512;
|
||||||
|
hpc = hd_blocks / secs_per_head / 1024;
|
||||||
|
if (hpc * secs_per_head * 1024 < hd_blocks)
|
||||||
|
hpc++;
|
||||||
|
if ((secs_per_head % 4) == 0) {
|
||||||
|
;
|
||||||
|
} else if ((secs_per_head % 2) == 0) {
|
||||||
|
hpc += (hpc % 2);
|
||||||
|
} else if(hpc % 4) {
|
||||||
|
hpc += 4 - (hpc % 4);
|
||||||
|
}
|
||||||
|
if (hpc > 255)
|
||||||
|
return 0;
|
||||||
|
*heads_per_cyl = hpc;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int iso_align_isohybrid(Ecma119Image *t, int flag)
|
||||||
|
{
|
||||||
|
int sa_type, ret, always_align;
|
||||||
|
uint32_t img_blocks;
|
||||||
|
off_t imgsize, cylsize = 0, frac;
|
||||||
|
char msg[160];
|
||||||
|
|
||||||
|
sa_type = (t->system_area_options >> 2) & 0x3f;
|
||||||
|
if (sa_type != 0)
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
always_align = (t->system_area_options >> 8) & 3;
|
||||||
|
|
||||||
|
img_blocks = t->curblock;
|
||||||
|
imgsize = ((off_t) img_blocks) * (off_t) 2048;
|
||||||
|
if (((t->system_area_options & 3) || always_align)
|
||||||
|
&& (off_t) (t->partition_heads_per_cyl * t->partition_secs_per_head
|
||||||
|
* 1024) * (off_t) 512 < imgsize) {
|
||||||
|
/* Choose small values which can represent the image size */
|
||||||
|
/* First try 32 sectors per head */
|
||||||
|
ret = try_sph(imgsize, 32, &(t->partition_heads_per_cyl), 0);
|
||||||
|
if (ret == 1) {
|
||||||
|
t->partition_secs_per_head = 32;
|
||||||
|
} else {
|
||||||
|
/* Did not work with 32. Try 63 */
|
||||||
|
t->partition_secs_per_head = 63;
|
||||||
|
ret = try_sph(imgsize, 63, &(t->partition_heads_per_cyl), 0);
|
||||||
|
if (ret != 1)
|
||||||
|
t->partition_heads_per_cyl = 255;
|
||||||
|
}
|
||||||
|
cylsize = t->partition_heads_per_cyl * t->partition_secs_per_head *512;
|
||||||
|
frac = imgsize % cylsize;
|
||||||
|
sprintf(msg, "Automatically adjusted MBR geometry to %d/%d/%d",
|
||||||
|
(int) (imgsize / cylsize + !!frac),
|
||||||
|
t->partition_heads_per_cyl, t->partition_secs_per_head);
|
||||||
|
iso_msgs_submit(0, msg, 0, "NOTE", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (always_align >= 2)
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
|
||||||
|
cylsize = 0;
|
||||||
|
if (t->catalog != NULL &&
|
||||||
|
(t->catalog->bootimages[0]->isolinux_options & 0x0a) == 0x02) {
|
||||||
|
/* Check for isolinux image with magic number of 3.72 and produce
|
||||||
|
an MBR from our built-in template. (Deprecated since 31 Mar 2010)
|
||||||
|
*/
|
||||||
|
if (img_blocks >= 0x40000000)
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
cylsize = 64 * 32 * 512;
|
||||||
|
} else if ((t->system_area_options & 2) || always_align) {
|
||||||
|
/* Patch externally provided system area as isohybrid MBR */
|
||||||
|
if (t->catalog == NULL || t->system_area_data == NULL) {
|
||||||
|
/* isohybrid makes only sense together with ISOLINUX boot image
|
||||||
|
and externally provided System Area.
|
||||||
|
*/
|
||||||
|
return ISO_ISOLINUX_CANT_PATCH;
|
||||||
|
}
|
||||||
|
cylsize = t->partition_heads_per_cyl * t->partition_secs_per_head
|
||||||
|
* 512;
|
||||||
|
}
|
||||||
|
if (cylsize == 0)
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
if (((double) imgsize) / (double) cylsize > 1024.0) {
|
||||||
|
iso_msgs_submit(0,
|
||||||
|
"Image size exceeds 1024 cylinders. Cannot align partition.",
|
||||||
|
0, "WARNING", 0);
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
frac = imgsize % cylsize;
|
||||||
|
imgsize += (frac > 0 ? cylsize - frac : 0);
|
||||||
|
|
||||||
|
frac = imgsize - ((off_t) img_blocks) * (off_t) 2048;
|
||||||
|
if (frac == 0)
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
if (frac % 2048) {
|
||||||
|
sprintf(msg,
|
||||||
|
"Cylinder size %d not divisible by 2048. Cannot align partition.",
|
||||||
|
(int) cylsize);
|
||||||
|
iso_msgs_submit(0, msg, 0, "WARNING", 0);
|
||||||
|
} else {
|
||||||
|
t->tail_blocks += frac / 2048;
|
||||||
}
|
}
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,9 @@
|
|||||||
* Copyright (c) 2008 Vreixo Formoso
|
* Copyright (c) 2008 Vreixo Formoso
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -45,4 +46,21 @@ int make_isohybrid_mbr(int bin_lba, int *img_blocks, char *mbr, int flag);
|
|||||||
*/
|
*/
|
||||||
int iso_write_system_area(Ecma119Image *t, uint8_t *buf);
|
int iso_write_system_area(Ecma119Image *t, uint8_t *buf);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
|
||||||
#endif /* SYSTEM_AREA_H_ */
|
#endif /* SYSTEM_AREA_H_ */
|
||||||
|
246
libisofs/tree.c
246
libisofs/tree.c
@ -1,15 +1,21 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
|
* Copyright (c) 2011 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Functions that act on the iso tree.
|
* Functions that act on the iso tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libisofs.h"
|
#include "libisofs.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
@ -25,6 +31,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <fnmatch.h>
|
#include <fnmatch.h>
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a new directory to the iso tree.
|
* Add a new directory to the iso tree.
|
||||||
*
|
*
|
||||||
@ -567,20 +574,19 @@ int iso_tree_add_new_node(IsoImage *image, IsoDir *parent, const char *name,
|
|||||||
*node = NULL;
|
*node = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
fs = image->fs;
|
|
||||||
result = fs->get_by_path(fs, path, &file);
|
|
||||||
if (result < 0) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* find place where to insert */
|
/* find place where to insert */
|
||||||
result = iso_dir_exists(parent, name, &pos);
|
result = iso_dir_exists(parent, name, &pos);
|
||||||
if (result) {
|
if (result) {
|
||||||
/* a node with same name already exists */
|
/* a node with same name already exists */
|
||||||
iso_file_source_unref(file);
|
|
||||||
return ISO_NODE_NAME_NOT_UNIQUE;
|
return ISO_NODE_NAME_NOT_UNIQUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fs = image->fs;
|
||||||
|
result = fs->get_by_path(fs, path, &file);
|
||||||
|
if (result < 0) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
result = image->builder->create_node(image->builder, image, file, &new);
|
result = image->builder->create_node(image->builder, image, file, &new);
|
||||||
|
|
||||||
/* free the file */
|
/* free the file */
|
||||||
@ -914,7 +920,7 @@ int iso_tree_path_to_node(IsoImage *image, const char *path, IsoNode **node)
|
|||||||
int result;
|
int result;
|
||||||
IsoNode *n;
|
IsoNode *n;
|
||||||
IsoDir *dir;
|
IsoDir *dir;
|
||||||
char *ptr, *brk_info, *component;
|
char *ptr, *brk_info = NULL, *component;
|
||||||
|
|
||||||
if (image == NULL || path == NULL) {
|
if (image == NULL || path == NULL) {
|
||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
@ -961,24 +967,222 @@ int iso_tree_path_to_node(IsoImage *image, const char *path, IsoNode **node)
|
|||||||
|
|
||||||
char *iso_tree_get_node_path(IsoNode *node)
|
char *iso_tree_get_node_path(IsoNode *node)
|
||||||
{
|
{
|
||||||
if (node == NULL || node->parent == NULL) {
|
char *path = NULL, *parent_path = NULL;
|
||||||
|
|
||||||
|
if (node == NULL || node->parent == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
|
|
||||||
if ((IsoNode*)node->parent == node) {
|
if ((IsoNode*)node->parent == node) {
|
||||||
return strdup("/");
|
return strdup("/");
|
||||||
} else {
|
} else {
|
||||||
char path[PATH_MAX];
|
parent_path = iso_tree_get_node_path((IsoNode*)node->parent);
|
||||||
char *parent_path = iso_tree_get_node_path((IsoNode*)node->parent);
|
if (parent_path == NULL)
|
||||||
if (parent_path == NULL) {
|
goto ex;
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (strlen(parent_path) == 1) {
|
if (strlen(parent_path) == 1) {
|
||||||
snprintf(path, PATH_MAX, "/%s", node->name);
|
path = calloc(1, strlen(node->name) + 2);
|
||||||
|
if (path == NULL)
|
||||||
|
goto ex;
|
||||||
|
sprintf(path, "/%s", node->name);
|
||||||
} else {
|
} else {
|
||||||
snprintf(path, PATH_MAX, "%s/%s", parent_path, node->name);
|
path = calloc(1, strlen(parent_path) + strlen(node->name) + 2);
|
||||||
|
if (path == NULL)
|
||||||
|
goto ex;
|
||||||
|
sprintf(path, "%s/%s", parent_path, node->name);
|
||||||
}
|
}
|
||||||
free(parent_path);
|
|
||||||
return strdup(path);
|
|
||||||
}
|
}
|
||||||
|
ex:;
|
||||||
|
if (parent_path != NULL)
|
||||||
|
free(parent_path);
|
||||||
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ------------------------- tree cloning ------------------------------ */
|
||||||
|
|
||||||
|
static
|
||||||
|
int iso_tree_copy_node_attr(IsoNode *old_node, IsoNode *new_node, int flag)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
new_node->mode = old_node->mode;
|
||||||
|
new_node->uid = old_node->uid;
|
||||||
|
new_node->gid = old_node->gid;
|
||||||
|
new_node->atime = old_node->atime;
|
||||||
|
new_node->mtime = old_node->mtime;
|
||||||
|
new_node->ctime = old_node->ctime;
|
||||||
|
new_node->hidden = old_node->hidden;
|
||||||
|
ret = iso_node_clone_xinfo(old_node, new_node, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
@param flag bit0= merge directory with *new_node
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
int iso_tree_clone_dir(IsoDir *old_dir,
|
||||||
|
IsoDir *new_parent, char *new_name, IsoNode **new_node,
|
||||||
|
int flag)
|
||||||
|
{
|
||||||
|
IsoDir *new_dir = NULL;
|
||||||
|
IsoNode *sub_node = NULL, *new_sub_node = NULL;
|
||||||
|
IsoDirIter *iter = NULL;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (flag & 1) {
|
||||||
|
new_dir = (IsoDir *) *new_node;
|
||||||
|
} else {
|
||||||
|
*new_node = NULL;
|
||||||
|
ret = iso_tree_add_new_dir(new_parent, new_name, &new_dir);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
/* Avoid traversal of target directory to allow cloning of old_dir to a
|
||||||
|
subordinate of old_dir.
|
||||||
|
*/
|
||||||
|
iso_node_take((IsoNode *) new_dir);
|
||||||
|
|
||||||
|
ret = iso_dir_get_children(old_dir, &iter);
|
||||||
|
if (ret < 0)
|
||||||
|
goto ex;
|
||||||
|
while(1) {
|
||||||
|
ret = iso_dir_iter_next(iter, &sub_node);
|
||||||
|
if (ret == 0)
|
||||||
|
break;
|
||||||
|
ret = iso_tree_clone(sub_node, new_dir, sub_node->name, &new_sub_node,
|
||||||
|
flag & 1);
|
||||||
|
if (ret < 0)
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now graft in the new tree resp. graft back the merged tree */
|
||||||
|
ret = iso_dir_add_node(new_parent, (IsoNode *) new_dir, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
goto ex;
|
||||||
|
|
||||||
|
if (!(flag & 1))
|
||||||
|
*new_node = (IsoNode *) new_dir;
|
||||||
|
ret = ISO_SUCCESS;
|
||||||
|
ex:;
|
||||||
|
if (iter != NULL)
|
||||||
|
iso_dir_iter_free(iter);
|
||||||
|
if (ret < 0 && new_dir != NULL) {
|
||||||
|
if (flag & 1) {
|
||||||
|
/* graft back the merged tree (eventually with half copy) */
|
||||||
|
iso_dir_add_node(new_parent, (IsoNode *) new_dir, 0);
|
||||||
|
} else {
|
||||||
|
iso_node_remove_tree((IsoNode *) new_dir, NULL);
|
||||||
|
*new_node = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int iso_tree_clone_file(IsoFile *old_file,
|
||||||
|
IsoDir *new_parent, char *new_name, IsoNode **new_node,
|
||||||
|
int flag)
|
||||||
|
{
|
||||||
|
IsoStream *new_stream = NULL;
|
||||||
|
IsoFile *new_file = NULL;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
*new_node = NULL;
|
||||||
|
|
||||||
|
ret = iso_stream_clone(old_file->stream, &new_stream, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = iso_tree_add_new_file(new_parent, new_name, new_stream, &new_file);
|
||||||
|
if (ret < 0)
|
||||||
|
goto ex;
|
||||||
|
new_stream = NULL; /* now owned by new_file */
|
||||||
|
new_file->sort_weight = old_file->sort_weight;
|
||||||
|
*new_node = (IsoNode *) new_file;
|
||||||
|
ret = ISO_SUCCESS;
|
||||||
|
ex:;
|
||||||
|
if (new_stream != NULL)
|
||||||
|
iso_stream_unref(new_stream);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int iso_tree_clone_symlink(IsoSymlink *node,
|
||||||
|
IsoDir *new_parent, char *new_name, IsoNode **new_node,
|
||||||
|
int flag)
|
||||||
|
{
|
||||||
|
IsoSymlink *new_sym;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
*new_node = NULL;
|
||||||
|
|
||||||
|
ret = iso_tree_add_new_symlink(new_parent, new_name, node->dest, &new_sym);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
new_sym->fs_id = node->fs_id;
|
||||||
|
new_sym->st_dev = node->st_dev;
|
||||||
|
new_sym->st_ino = node->st_ino;
|
||||||
|
*new_node = (IsoNode *) new_sym;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int iso_tree_clone_special(IsoSpecial *node,
|
||||||
|
IsoDir *new_parent, char *new_name, IsoNode **new_node,
|
||||||
|
int flag)
|
||||||
|
{
|
||||||
|
IsoSpecial *new_spec;
|
||||||
|
IsoNode *iso_node;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
iso_node = (IsoNode *) node;
|
||||||
|
ret = iso_tree_add_new_special(new_parent, new_name, iso_node->mode,
|
||||||
|
node->dev, &new_spec);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
new_spec->fs_id = node->fs_id;
|
||||||
|
new_spec->st_dev = node->st_dev;
|
||||||
|
new_spec->st_ino = node->st_ino;
|
||||||
|
*new_node = (IsoNode *) new_spec;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* API */
|
||||||
|
int iso_tree_clone(IsoNode *node,
|
||||||
|
IsoDir *new_parent, char *new_name, IsoNode **new_node,
|
||||||
|
int flag)
|
||||||
|
{
|
||||||
|
int ret = ISO_SUCCESS;
|
||||||
|
|
||||||
|
if (iso_dir_get_node(new_parent, new_name, new_node) == 1) {
|
||||||
|
if (! (node->type == LIBISO_DIR && (*new_node)->type == LIBISO_DIR &&
|
||||||
|
(flag & 1))) {
|
||||||
|
*new_node = NULL;
|
||||||
|
return ISO_NODE_NAME_NOT_UNIQUE;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
flag &= ~1;
|
||||||
|
|
||||||
|
if (node->type == LIBISO_DIR) {
|
||||||
|
ret = iso_tree_clone_dir((IsoDir *) node, new_parent, new_name,
|
||||||
|
new_node, flag & 1);
|
||||||
|
} else if (node->type == LIBISO_FILE) {
|
||||||
|
ret = iso_tree_clone_file((IsoFile *) node, new_parent, new_name,
|
||||||
|
new_node, 0);
|
||||||
|
} else if (node->type == LIBISO_SYMLINK) {
|
||||||
|
ret = iso_tree_clone_symlink((IsoSymlink *) node, new_parent, new_name,
|
||||||
|
new_node, 0);
|
||||||
|
} else if (node->type == LIBISO_SPECIAL) {
|
||||||
|
ret = iso_tree_clone_special((IsoSpecial *) node, new_parent, new_name,
|
||||||
|
new_node, 0);
|
||||||
|
} else if (node->type == LIBISO_BOOT) {
|
||||||
|
ret = ISO_SUCCESS; /* API says they are silently ignored */
|
||||||
|
}
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
if (flag & 1)
|
||||||
|
return 2; /* merged two directories, *new_node is not new */
|
||||||
|
ret = iso_tree_copy_node_attr(node, *new_node, 0);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -2,8 +2,9 @@
|
|||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
*/
|
*/
|
||||||
#ifndef LIBISO_IMAGE_TREE_H_
|
#ifndef LIBISO_IMAGE_TREE_H_
|
||||||
#define LIBISO_IMAGE_TREE_H_
|
#define LIBISO_IMAGE_TREE_H_
|
||||||
|
203
libisofs/util.c
203
libisofs/util.c
@ -1,15 +1,22 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
* Copyright (c) 2007 Mario Danic
|
* Copyright (c) 2007 Mario Danic
|
||||||
|
* Copyright (c) 2009 - 2011 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "libisofs.h"
|
#include "libisofs.h"
|
||||||
#include "messages.h"
|
#include "messages.h"
|
||||||
|
#include "joliet.h"
|
||||||
#include "../version.h"
|
#include "../version.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -767,6 +774,8 @@ char *iso_r_dirid(const char *src, int size, int relaxed)
|
|||||||
len = size;
|
len = size;
|
||||||
}
|
}
|
||||||
dest = malloc(len + 1);
|
dest = malloc(len + 1);
|
||||||
|
if (dest == NULL)
|
||||||
|
return NULL;
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
char c= src[i];
|
char c= src[i];
|
||||||
if (relaxed == 2) {
|
if (relaxed == 2) {
|
||||||
@ -906,15 +915,22 @@ ex:;
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t *iso_j_file_id(const uint16_t *src)
|
/*
|
||||||
|
bit0= no_force_dots
|
||||||
|
bit1= allow 103 characters rather than 64
|
||||||
|
*/
|
||||||
|
uint16_t *iso_j_file_id(const uint16_t *src, int flag)
|
||||||
{
|
{
|
||||||
uint16_t *dot;
|
uint16_t *dot;
|
||||||
size_t lname, lext, lnname, lnext, pos, i;
|
size_t lname, lext, lnname, lnext, pos, i, maxchar = 64;
|
||||||
uint16_t dest[66]; /* 66 = 64 (name + ext) + 1 (.) + 1 (\0) */
|
uint16_t dest[LIBISO_JOLIET_NAME_MAX];
|
||||||
|
/* was: 66 = 64 (name + ext) + 1 (.) + 1 (\0) */
|
||||||
|
|
||||||
if (src == NULL) {
|
if (src == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
if (flag & 2)
|
||||||
|
maxchar = 103;
|
||||||
|
|
||||||
dot = ucsrchr(src, '.');
|
dot = ucsrchr(src, '.');
|
||||||
|
|
||||||
@ -926,14 +942,15 @@ uint16_t *iso_j_file_id(const uint16_t *src)
|
|||||||
*/
|
*/
|
||||||
if (dot == NULL || cmp_ucsbe(dot + 1, '\0') == 0) {
|
if (dot == NULL || cmp_ucsbe(dot + 1, '\0') == 0) {
|
||||||
lname = ucslen(src);
|
lname = ucslen(src);
|
||||||
lnname = (lname > 64) ? 64 : lname;
|
lnname = (lname > maxchar) ? maxchar : lname;
|
||||||
lext = lnext = 0;
|
lext = lnext = 0;
|
||||||
} else {
|
} else {
|
||||||
lext = ucslen(dot + 1);
|
lext = ucslen(dot + 1);
|
||||||
lname = ucslen(src) - lext - 1;
|
lname = ucslen(src) - lext - 1;
|
||||||
lnext = (ucslen(src) > 65 && lext > 3) ? (lname < 61 ? 64 - lname : 3)
|
lnext = (ucslen(src) > maxchar + 1 && lext > 3)
|
||||||
|
? (lname < maxchar - 3 ? maxchar - lname : 3)
|
||||||
: lext;
|
: lext;
|
||||||
lnname = (ucslen(src) > 65) ? 64 - lnext : lname;
|
lnname = (ucslen(src) > maxchar + 1) ? maxchar - lnext : lname;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lnname == 0 && lnext == 0) {
|
if (lnname == 0 && lnext == 0) {
|
||||||
@ -952,6 +969,10 @@ uint16_t *iso_j_file_id(const uint16_t *src)
|
|||||||
pos++;
|
pos++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((flag & 1) && lnext <= 0)
|
||||||
|
goto is_done;
|
||||||
|
|
||||||
set_ucsbe(dest + pos, '.');
|
set_ucsbe(dest + pos, '.');
|
||||||
pos++;
|
pos++;
|
||||||
|
|
||||||
@ -965,22 +986,28 @@ uint16_t *iso_j_file_id(const uint16_t *src)
|
|||||||
pos++;
|
pos++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is_done:;
|
||||||
set_ucsbe(dest + pos, '\0');
|
set_ucsbe(dest + pos, '\0');
|
||||||
return ucsdup(dest);
|
return ucsdup(dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t *iso_j_dir_id(const uint16_t *src)
|
/* @param flag bit1= allow 103 characters rather than 64
|
||||||
|
*/
|
||||||
|
uint16_t *iso_j_dir_id(const uint16_t *src, int flag)
|
||||||
{
|
{
|
||||||
size_t len, i;
|
size_t len, i, maxchar = 64;
|
||||||
uint16_t dest[65]; /* 65 = 64 + 1 (\0) */
|
uint16_t dest[LIBISO_JOLIET_NAME_MAX]; /* was: 65 = 64 + 1 (\0) */
|
||||||
|
|
||||||
if (src == NULL) {
|
if (src == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
if (flag & 2)
|
||||||
|
maxchar = 103;
|
||||||
|
|
||||||
len = ucslen(src);
|
len = ucslen(src);
|
||||||
if (len > 64) {
|
if (len > maxchar) {
|
||||||
len = 64;
|
len = maxchar;
|
||||||
}
|
}
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
uint16_t c = src[i];
|
uint16_t c = src[i];
|
||||||
@ -1021,6 +1048,8 @@ uint16_t *ucsdup(const uint16_t *str)
|
|||||||
size_t len = ucslen(str);
|
size_t len = ucslen(str);
|
||||||
|
|
||||||
ret = malloc(2 * (len + 1));
|
ret = malloc(2 * (len + 1));
|
||||||
|
if (ret == NULL)
|
||||||
|
return NULL;
|
||||||
if (ret != NULL) {
|
if (ret != NULL) {
|
||||||
memcpy(ret, str, 2 * (len + 1));
|
memcpy(ret, str, 2 * (len + 1));
|
||||||
}
|
}
|
||||||
@ -1204,7 +1233,7 @@ void iso_datetime_7(unsigned char *buf, time_t t, int always_gmt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
memset(&tm, 0, sizeof(tm));
|
memset(&tm, 0, sizeof(tm));
|
||||||
tm.tm_isdst = -1; /* some Linuxes change tm_isdst only if it is -1 */
|
tm.tm_isdst = -1; /* some OSes change tm_isdst only if it is -1 */
|
||||||
localtime_r(&t, &tm);
|
localtime_r(&t, &tm);
|
||||||
|
|
||||||
#ifdef HAVE_TM_GMTOFF
|
#ifdef HAVE_TM_GMTOFF
|
||||||
@ -1248,7 +1277,7 @@ void iso_datetime_17(unsigned char *buf, time_t t, int always_gmt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
memset(&tm, 0, sizeof(tm));
|
memset(&tm, 0, sizeof(tm));
|
||||||
tm.tm_isdst = -1; /* some Linuxes change tm_isdst only if it is -1 */
|
tm.tm_isdst = -1; /* some OSes change tm_isdst only if it is -1 */
|
||||||
localtime_r(&t, &tm);
|
localtime_r(&t, &tm);
|
||||||
|
|
||||||
localtime_r(&t, &tm);
|
localtime_r(&t, &tm);
|
||||||
@ -1279,12 +1308,41 @@ void iso_datetime_17(unsigned char *buf, time_t t, int always_gmt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef HAVE_TIMEGM
|
#ifndef HAVE_TIMEGM
|
||||||
|
|
||||||
|
/* putenv is SVr4, POSIX.1-2001, 4.3BSD , setenv is 4.3BSD, POSIX.1-2001.
|
||||||
|
So putenv is more widely available.
|
||||||
|
Also, setenv spoils eventual putenv expectation of applications because
|
||||||
|
putenv installs the original string which then may be altered from
|
||||||
|
its owner. setenv installs a copy that may not be altered.
|
||||||
|
Both are slow.
|
||||||
|
Thus first try with a naive implementation that assumes no leap seconds.
|
||||||
|
If it fails a test with gmtime() then use the slow function with mktime().
|
||||||
|
*/
|
||||||
|
#define Libisofs_use_putenV yes
|
||||||
|
|
||||||
static
|
static
|
||||||
time_t timegm(struct tm *tm)
|
time_t env_timegm(struct tm *tm)
|
||||||
{
|
{
|
||||||
time_t ret;
|
time_t ret;
|
||||||
char *tz;
|
char *tz;
|
||||||
|
|
||||||
|
#ifdef Libisofs_use_putenV
|
||||||
|
|
||||||
|
static char unset_name[] = {"TZ"};
|
||||||
|
|
||||||
|
tz = getenv("TZ");
|
||||||
|
putenv("TZ=");
|
||||||
|
tzset();
|
||||||
|
ret = mktime(tm);
|
||||||
|
if (tz != NULL) {
|
||||||
|
/* tz is a pointer to the value part in a string of form "TZ="value */
|
||||||
|
putenv(tz - 3);
|
||||||
|
} else
|
||||||
|
putenv(unset_name); /* not daring to submit constant */
|
||||||
|
tzset();
|
||||||
|
|
||||||
|
#else /* Libisofs_use_putenV */
|
||||||
|
|
||||||
tz = getenv("TZ");
|
tz = getenv("TZ");
|
||||||
setenv("TZ", "", 1);
|
setenv("TZ", "", 1);
|
||||||
tzset();
|
tzset();
|
||||||
@ -1294,9 +1352,92 @@ time_t timegm(struct tm *tm)
|
|||||||
else
|
else
|
||||||
unsetenv("TZ");
|
unsetenv("TZ");
|
||||||
tzset();
|
tzset();
|
||||||
|
|
||||||
|
#endif /* ! Libisofs_use_putenV */
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
static
|
||||||
|
int ts_is_leapyear(int tm_year) /* years since 1900 */
|
||||||
|
{
|
||||||
|
return ((tm_year % 4) == 0 && ((tm_year % 100) != 0 ||
|
||||||
|
(tm_year % 400) == 100));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fast implementation without leap seconds.
|
||||||
|
Inspired by but not copied from code by Kungliga Tekniska Hgskolan
|
||||||
|
(Royal Institute of Technology, Stockholm, Sweden),
|
||||||
|
which was modified by Andrew Tridgell for Samba4.
|
||||||
|
I claim own copyright 2011 Thomas Schmitt <scdbackup@gmx.net>.
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
time_t ts_timegm(struct tm *tm)
|
||||||
|
{
|
||||||
|
time_t ret;
|
||||||
|
static int month_length_normal[12] =
|
||||||
|
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
|
||||||
|
static int month_length_leap[12] =
|
||||||
|
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
|
||||||
|
int *month_length_pt;
|
||||||
|
int years, i;
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
years = tm->tm_year - 70; /* Years since 1970 */
|
||||||
|
if (years < 0)
|
||||||
|
return ret;
|
||||||
|
for (i = 0; i < years; i++) {
|
||||||
|
ret += 365 * 86400;
|
||||||
|
if (ts_is_leapyear(70 + i))
|
||||||
|
ret += 86400;
|
||||||
|
}
|
||||||
|
if (ts_is_leapyear(tm->tm_year))
|
||||||
|
month_length_pt = month_length_leap;
|
||||||
|
else
|
||||||
|
month_length_pt = month_length_normal;
|
||||||
|
for (i = 0; i < tm->tm_mon; i++)
|
||||||
|
ret += month_length_pt[i] * 86400;
|
||||||
|
ret += (tm->tm_mday - 1) * 86400;
|
||||||
|
ret += tm->tm_hour * 3600;
|
||||||
|
ret += tm->tm_min * 60;
|
||||||
|
ret += tm->tm_sec;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
time_t timegm(struct tm *tm)
|
||||||
|
{
|
||||||
|
time_t raw_t, ret;
|
||||||
|
struct tm *test_tm, input_tm_copy;
|
||||||
|
|
||||||
|
/* Beware of ill effects if tm is result of gmtime() or alike */
|
||||||
|
memcpy(&input_tm_copy, tm, sizeof(struct tm));
|
||||||
|
|
||||||
|
/* Try without leapseconds (which are rarely implemented, as it seems) */
|
||||||
|
raw_t = ts_timegm(tm);
|
||||||
|
if (raw_t == 0)
|
||||||
|
return raw_t;
|
||||||
|
|
||||||
|
/* Check whether this translates back to the input values */
|
||||||
|
test_tm = gmtime(&raw_t);
|
||||||
|
if (input_tm_copy.tm_sec == test_tm->tm_sec &&
|
||||||
|
input_tm_copy.tm_min == test_tm->tm_min &&
|
||||||
|
input_tm_copy.tm_hour == test_tm->tm_hour &&
|
||||||
|
input_tm_copy.tm_mday == test_tm->tm_mday &&
|
||||||
|
input_tm_copy.tm_mon == test_tm->tm_mon &&
|
||||||
|
input_tm_copy.tm_year == test_tm->tm_year) {
|
||||||
|
ret = raw_t;
|
||||||
|
} else {
|
||||||
|
/* Mismatch. Use slow method around mktime() */
|
||||||
|
ret = env_timegm(&input_tm_copy);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* ! HAVE_TIMEGM */
|
||||||
|
|
||||||
|
|
||||||
time_t iso_datetime_read_7(const uint8_t *buf)
|
time_t iso_datetime_read_7(const uint8_t *buf)
|
||||||
{
|
{
|
||||||
@ -1308,6 +1449,7 @@ time_t iso_datetime_read_7(const uint8_t *buf)
|
|||||||
tm.tm_hour = buf[3];
|
tm.tm_hour = buf[3];
|
||||||
tm.tm_min = buf[4];
|
tm.tm_min = buf[4];
|
||||||
tm.tm_sec = buf[5];
|
tm.tm_sec = buf[5];
|
||||||
|
|
||||||
return timegm(&tm) - ((int8_t)buf[6]) * 60 * 15;
|
return timegm(&tm) - ((int8_t)buf[6]) * 60 * 15;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1394,16 +1536,17 @@ char *iso_util_strcopy(const char *buf, size_t len)
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *iso_util_strcopy_untail(const char *buf, size_t len)
|
char *iso_util_strcopy_untail(const char *buf, size_t len_in)
|
||||||
{
|
{
|
||||||
char *str;
|
char *str;
|
||||||
|
int len;
|
||||||
|
|
||||||
str = iso_util_strcopy(buf, len);
|
str = iso_util_strcopy(buf, len_in);
|
||||||
if (str == NULL) {
|
if (str == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/* remove trailing spaces */
|
/* remove trailing spaces */
|
||||||
for (len = len-1; len >= 0; --len) {
|
for (len = len_in - 1; len >= 0; --len) {
|
||||||
if (str[len] != ' ')
|
if (str[len] != ' ')
|
||||||
break;
|
break;
|
||||||
str[len] = 0;
|
str[len] = 0;
|
||||||
@ -1445,6 +1588,8 @@ char *ucs2str(const char *buf, size_t len)
|
|||||||
|
|
||||||
/* ensure enought space */
|
/* ensure enought space */
|
||||||
out = calloc(outbytes, 1);
|
out = calloc(outbytes, 1);
|
||||||
|
if (out == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
/* convert to local charset */
|
/* convert to local charset */
|
||||||
conv_ret = iso_iconv_open(&conv, iso_get_local_charset(0), "UCS-2BE", 0);
|
conv_ret = iso_iconv_open(&conv, iso_get_local_charset(0), "UCS-2BE", 0);
|
||||||
@ -1706,10 +1851,24 @@ unexpected_type:;
|
|||||||
iso_msg_submit(-1, ISO_MD5_TAG_UNEXPECTED, 0, NULL);
|
iso_msg_submit(-1, ISO_MD5_TAG_UNEXPECTED, 0, NULL);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
goto ex;
|
goto ex;
|
||||||
} else if(pos != lba) {
|
} else if (pos != lba) {
|
||||||
|
if (*tag_type == 2) { /* Superblock tag */
|
||||||
|
if (lba < 32) {
|
||||||
|
/* Check whether this is a copied superblock */
|
||||||
|
range_start -= (off_t) pos - (off_t) lba;
|
||||||
|
if (range_start != ctx_start_lba) {
|
||||||
|
|
||||||
|
/* >>> check for matching MD5 ? */;
|
||||||
|
|
||||||
|
ret = ISO_MD5_TAG_MISPLACED;
|
||||||
|
} else
|
||||||
|
ret = ISO_MD5_TAG_COPIED;
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
ret = ISO_MD5_TAG_MISPLACED;
|
ret = ISO_MD5_TAG_MISPLACED;
|
||||||
goto ex;
|
goto ex;
|
||||||
} else if(range_start != ctx_start_lba) {
|
} else if (range_start != ctx_start_lba) {
|
||||||
ret = ISO_MD5_TAG_MISPLACED;
|
ret = ISO_MD5_TAG_MISPLACED;
|
||||||
}
|
}
|
||||||
ret = iso_md5_clone(ctx, &cloned_ctx);
|
ret = iso_md5_clone(ctx, &cloned_ctx);
|
||||||
|
@ -1,15 +1,24 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
|
* Copyright (c) 2009 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef LIBISO_UTIL_H_
|
#ifndef LIBISO_UTIL_H_
|
||||||
#define LIBISO_UTIL_H_
|
#define LIBISO_UTIL_H_
|
||||||
|
|
||||||
|
#ifdef HAVE_STDINT_H
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_INTTYPES_H
|
||||||
|
#include <inttypes.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#ifndef MAX
|
#ifndef MAX
|
||||||
@ -144,16 +153,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
|
* Create a Joliet file identifier that consists of name and extension. The
|
||||||
* combined name and extension length will not exceed 128 bytes, and the
|
* combined name and extension length will normally not exceed 64 characters
|
||||||
* name and extension will be separated (.). All characters consist of
|
* (= 128 bytes). The name and the extension will be separated (.).
|
||||||
* 2 bytes and the resulting string is NULL-terminated by a 2-byte NULL.
|
* 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.
|
* Note that version number and (;1) is not appended.
|
||||||
*
|
* @param flag
|
||||||
|
* bit0= no_force_dots
|
||||||
|
* bit1= allow 103 characters rather than 64
|
||||||
* @return
|
* @return
|
||||||
* NULL if the original name and extension both are of length 0.
|
* 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
|
* Create a Joliet directory identifier that consists of name and optionally
|
||||||
@ -161,10 +173,12 @@ uint16_t *iso_j_file_id(const uint16_t *src);
|
|||||||
* and the name and extension will be separated (.). All characters consist of
|
* 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.
|
* 2 bytes and the resulting string is NULL-terminated by a 2-byte NULL.
|
||||||
*
|
*
|
||||||
|
* @param flag
|
||||||
|
* bit1= allow 103 characters rather than 64
|
||||||
* @return
|
* @return
|
||||||
* NULL if the original name and extension both are of length 0.
|
* 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.
|
* Like strlen, but for Joliet strings.
|
||||||
@ -246,20 +260,6 @@ time_t iso_datetime_read_17(const uint8_t *buf);
|
|||||||
*/
|
*/
|
||||||
int iso_eaccess(const char *path);
|
int iso_eaccess(const char *path);
|
||||||
|
|
||||||
#ifdef NIX
|
|
||||||
/* <<< Buggy and not used any more */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy up to \p len chars from \p buf and return this newly allocated
|
|
||||||
* string. The new string is null-terminated.
|
|
||||||
* Note:
|
|
||||||
* Trailing blanks will be removed. But the first one of an all blank string
|
|
||||||
* persists. It is unclear whether this is a bug or a feature.
|
|
||||||
*/
|
|
||||||
char *strcopy(const char *buf, size_t len);
|
|
||||||
|
|
||||||
#endif /* NIX */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy up to \p len chars from \p buf and return this newly allocated
|
* Copy up to \p len chars from \p buf and return this newly allocated
|
||||||
* string. The new string is null-terminated.
|
* string. The new string is null-terminated.
|
||||||
@ -516,12 +516,26 @@ int iso_util_tag_magic(int tag_type, char **tag_magic, int *len, int flag);
|
|||||||
*/
|
*/
|
||||||
int checksum_cx_xinfo_func(void *data, 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
|
/* Function to identify and manage md5 sums of unspecified providence stored
|
||||||
* directly in this xinfo. This is supposed to override any other recorded
|
* 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.
|
* MD5 of the node unless data get copied and checksummed during that copying.
|
||||||
*/
|
*/
|
||||||
int checksum_md5_xinfo_func(void *data, int flag);
|
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);
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,10 +2,15 @@
|
|||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "libisofs.h"
|
#include "libisofs.h"
|
||||||
|
|
||||||
|
@ -2,10 +2,15 @@
|
|||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "libisofs.h"
|
#include "libisofs.h"
|
||||||
|
|
||||||
@ -280,7 +285,7 @@ void ** iso_rbtree_to_array(IsoRBTree *tree, int (*include_item)(void *),
|
|||||||
size_t *size)
|
size_t *size)
|
||||||
{
|
{
|
||||||
size_t pos;
|
size_t pos;
|
||||||
void **array;
|
void **array, **new_array;
|
||||||
|
|
||||||
array = malloc((tree->size + 1) * sizeof(void*));
|
array = malloc((tree->size + 1) * sizeof(void*));
|
||||||
if (array == NULL) {
|
if (array == NULL) {
|
||||||
@ -291,7 +296,12 @@ void ** iso_rbtree_to_array(IsoRBTree *tree, int (*include_item)(void *),
|
|||||||
pos = rbtree_to_array_aux(tree->root, array, 0, include_item);
|
pos = rbtree_to_array_aux(tree->root, array, 0, include_item);
|
||||||
array[pos] = NULL;
|
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) {
|
if (size) {
|
||||||
*size = pos;
|
*size = pos;
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,9 @@
|
|||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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 as
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
* published by the Free Software Foundation. See COPYING file for details.
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
*/
|
*/
|
||||||
#ifndef LIBISO_IMAGE_WRITER_H_
|
#ifndef LIBISO_IMAGE_WRITER_H_
|
||||||
#define LIBISO_IMAGE_WRITER_H_
|
#define LIBISO_IMAGE_WRITER_H_
|
||||||
|
Reference in New Issue
Block a user