Compare commits

..

103 Commits

Author SHA1 Message Date
6927fd35e8 Version leap to 0.6.40 2010-12-10 11:27:46 +01:00
fb231ff186 Updated changelog 2010-12-10 11:22:25 +01:00
b2fde289b1 Removed old change timestamp 2010-12-10 11:15:42 +01:00
dcc6ffd184 Avoiding to start writer thread if iso_write_opts_set_will_cancel() is set to 1. 2010-12-06 17:05:35 +01:00
27e69c38ab New error reply code ISO_DISPLACE_ROLLOVER for external data sources with
address displacement.
2010-11-30 09:47:22 +01:00
f4b2bfc0d6 Better messages if boot image or boot catalog directory are missing. 2010-11-25 17:01:40 +01:00
5482d5d7b4 Improvements about the block address of empty data files 2010-11-25 14:40:44 +01:00
b2997dcc46 New API call iso_write_opts_set_will_cancel() 2010-11-24 11:00:21 +01:00
48ae8acbd6 Better handling of El Torito boot images with identical block address
at image load time.
2010-11-24 10:06:19 +01:00
a488f8fb14 New API call iso_write_opts_set_disc_label(),
new system area type 3 = SUN Disk Label
2010-11-05 15:34:42 +01:00
ea8da1f7d3 Added a description of SUN Disk Label for SUN SPARC machines. 2010-11-01 16:05:47 +01:00
8ad92a08ea Fixed a typo in a warning message. 2010-10-27 07:57:38 +02:00
35c043a0f9 Version leap to 0.6.39 2010-10-23 16:31:47 +02:00
fce35ac718 Version leap to 0.6.38 2010-10-23 15:28:02 +02:00
01518896f9 Updated Changelog 2010-10-23 15:25:33 +02:00
caf90e35f5 Fixed session oversize bug with emulated multi-session.
Introduced by revision 721.
2010-10-19 12:45:26 +02:00
1f486fd78b Coordinated appending of partition images with situations other than
isohybrid MBR production or partition offset.
2010-10-19 10:14:26 +02:00
b58d1e28ef New API call iso_write_opts_set_partition_img(). 2010-10-18 16:56:00 +02:00
ebb5937568 Removed obsolete development macro case. 2010-10-16 19:05:46 +02:00
ef444fb29c Removed remaining questions about MIPS Big Endian. Now rounding up the count
of cylinders.
Described MBR DOS-style partition table format.
2010-10-16 11:24:52 +02:00
1ccbaa302c United macro Xorriso_jte_standalonE with macro Xorriso_standalonE 2010-10-15 14:24:31 +02:00
0d35100eb0 New system area type 2 = MIPS Little Endian / DEC Boot Block. 2010-10-15 12:19:53 +02:00
48316af1d9 Made development option Libisofs_mips_boot_file_pathS unconditional. 2010-10-15 09:23:09 +02:00
a75fb9a894 New system area type 2 for Little Endian MIPS DEC boot block. 2010-10-14 22:34:32 +02:00
a0ba4b976c Described El Torito, grub-mkrescue MBR, MIPS Little Endian booting. 2010-10-14 17:26:56 +02:00
870280a018 Small adjustments and bug fix with new MIPS boot facility. 2010-10-13 16:59:18 +02:00
f33df0ef29 New API calls iso_image_add_mips_boot_file(), iso_image_get_mips_boot_files(),
iso_image_give_up_mips_boot().
The preliminary ban has been lifted to combine El Torito and MIPS Big Endian
boot facilities.
The current state of boot record documentation has been added to bzr.
2010-10-12 20:24:17 +02:00
2a087f6f39 Silenced a warning about const or non-const. 2010-10-12 12:23:16 +02:00
b07d3ab0c3 Provisory implementation of MIPS big endian Volume Header production.
For now it is mutually exclusive with El Torito production.
It will always be mutually exclusive with MBR production.
2010-10-12 12:20:27 +02:00
f12df92600 Requiring libjte-0.1.1 if enabled. Prepared for GNU xorriso to include libjte. 2010-10-07 13:43:57 +02:00
8a75d35c46 New API call iso_image_generator_is_running().
Prevented a potential race condition between Ecma119Image disposal by
burn_source and final activities of ISO generator thread.
2010-10-06 17:33:46 +02:00
bb28c69cae Stuffed a memory leak discovered by valgrind. 2010-10-05 19:58:54 +02:00
25068a4de2 Declared that iso_lib_version() and iso_lib_is_compatible() are permitted
before iso_init().
2010-10-04 15:47:09 +02:00
d2094a0d80 Compile time test and run time test for sufficiently recent libjte if enabled. 2010-10-04 14:56:24 +02:00
16dcf4a29c Draining and forwarding possibly enabled libjte message list.
Changed severity of error code ISO_LIBJTE_FILE_FAILED to MISHAP.
2010-10-04 13:18:06 +02:00
69a25c9734 New API call iso_write_opts_set_tail_blocks() for tail padding inside ISO image 2010-10-02 22:57:09 +02:00
a387a8b06a Removed hardcoded libjte test because xorriso now has a -jigdo command. 2010-09-30 09:31:40 +02:00
a9af97733e Allowed NULL as second arg of iso_write_opts_detach_jte(). 2010-09-29 10:08:30 +02:00
c30674095b Updated hardcoded JTE test case so that it produces non-trivial files. 2010-09-28 16:44:25 +02:00
be838b6940 Disabled the hardcoded JTE test which was introduced by previous revision 2010-09-28 12:15:23 +02:00
b0c79a9a1e New API calls iso_write_opts_attach_jte() and iso_write_opts_detach_jte() 2010-09-28 12:12:33 +02:00
8725baa55f Making use of libjte if installed and if not ./configure --disable-libjte 2010-09-27 18:22:05 +02:00
59ab73c57f On Linux: Run ldconfig during make install,if not --disable-ldconfig-at-install 2010-09-22 12:55:13 +02:00
7386596bfa Version leap to 0.6.37 2010-09-15 11:14:12 +02:00
4833ef23e5 Updated ChangeLog. 2010-09-15 11:11:02 +02:00
14171bdd3a Version leap to 0.6.36 2010-09-15 10:55:14 +02:00
d37eba5344 Removed outdated development marks 2010-09-15 09:28:05 +02:00
3b616dae38 Meaningful change log file derived by George Danchev from web site 2010-09-15 08:43:04 +02:00
a2758b27e6 Automatic C++ detection by using macro __cplusplus 2010-09-11 19:18:42 +02:00
d5c4af7378 Removed development marks and an obsolete conditional compilation case. 2010-09-11 13:25:51 +02:00
90f37b8183 Introduced macro Libisofs_h_as_cpluspluS to avoid the definitions of
struct iso_file_source and struct iso_stream when libisofs.h is included
in C++ files. (The definitions contain members with name "class".)
2010-09-11 11:50:47 +02:00
1d4f26f325 Adjusted new partition offset feature for multi-session and MD5 tags. 2010-09-10 13:45:37 +02:00
08e442a2ab Removed dummy filter xor_sencrypt because there are real filters now. 2010-09-06 12:19:51 +02:00
017dcb39f2 New API function iso_write_opts_set_part_offset() controls creation of
an MBR with a first partiton table entry that bears non-zero start address.
A second set of volume descriptors and directory tree+tables gets created
which can be used to mount the image at the partition start.
Not yet implemented for second set: ISO 9660:1999, MD5 checksums.
2010-09-05 12:43:48 +02:00
95121e2f9f Forgot to store util_rbtree.c before previous commit. 2010-09-01 19:18:35 +02:00
ba11413a6f Corrected several memory leaks and potential NULL pointer evaluations
in case of memory shortage. All reported by George Danchev.
2010-09-01 10:45:10 +02:00
e1888df5ab Hopefully silenced warnings of doxygen on Debian buildd 2010-08-06 12:49:22 +02:00
dceef03633 Removed problematic DETAILS_AT_TOP to silence warning of Debian buildd 2010-07-30 19:10:55 +02:00
443c5d41db Removed obsolete comment 2010-07-06 10:53:04 +02:00
e60171986b Let configure perform linker test with --version-script if enabled 2010-07-06 10:50:28 +02:00
fe45249e9e Gave up use of alloca() in favor of calloc() and free(),
because alloca.h is needed on Solaris and not available on FreeBSD.
2010-07-05 19:14:47 +02:00
b01f017a6d Hiding all non-API symbols from the linker by use of --version-script 2010-07-05 18:20:59 +02:00
73bc3ae512 Include file alloca.h was missing in demo program 2010-07-01 13:50:42 +02:00
b6427d3b2b Version leap to 0.6.35 2010-06-28 21:21:06 +02:00
438024d11b Version leap to 0.6.34 2010-06-28 14:12:33 +02:00
1d6fdf51dc New error code ISO_BOOT_NO_CATALOG 2010-06-23 19:54:51 +02:00
281462802f Reacted on harmless compiler warnings about allegedly uninitialized variables 2010-06-20 15:41:06 +02:00
2b2a86ea2e Moved some functions into the Libisofs_with_zliB case
which caused compiler warnings on OpenSuse Build Service.
2010-06-20 15:08:08 +02:00
c0963596e5 New API call iso_node_get_hidden(). 2010-06-20 09:18:30 +02:00
9be5b241e2 New API call iso_node_set_hidden(),
new IsoHideNodeFlag value LIBISO_HIDE_BUT_WRITE.
2010-06-18 22:03:41 +02:00
fcde936670 Remove a probably outdated test that was always false. 2010-06-04 16:21:14 +02:00
73c6bc49c6 Moved inclusion of config.h to top position.
Solaris complained about redefined _FILE_OFFSET_BITS. See man lfcompile.
2010-05-29 09:34:00 +02:00
5ed507da83 Forgotten inclusion of ../config.h in filters/*.c 2010-05-17 14:35:10 +02:00
ae626b9570 Eventually including autotools generated ../config.h with all source files.
(GNU xorriso plans to use autoheader for a diet of its build messages.)
2010-05-16 10:20:12 +02:00
3528493b92 Removed development macro Libisofs_with_checksumS
and made the affected code unconditional.
2010-05-08 22:24:02 +02:00
9cf460a3b1 Version leap to 0.6.33 2010-05-03 14:44:21 +02:00
84132ec7bf Version leap to 0.6.32 2010-05-03 14:34:36 +02:00
eb23260459 Removed most of the development remarks of 0.6.31 2010-05-01 20:38:01 +02:00
4978424328 Corrected calls of functions iso_lsb(), iso_msb(), iso_bb() which used
integer types other than uint32_t.
2010-04-30 11:36:14 +02:00
e4cf93665a Making an educated guess whether the boot images contain a boot info table.
New API call el_torito_seems_boot_info_table() publishes this guess.
2010-04-29 15:10:18 +02:00
3d9367d52a Closed memory leak about boot catalog node. 2010-04-25 20:27:17 +02:00
03b030c56d New API calls el_torito_get_isolinux_options(), el_torito_get_boot_media_type() 2010-04-25 14:11:45 +02:00
a3fe82100b Fixed a bug introduced with previous revision 655. 2010-04-23 19:00:50 +02:00
02d7a690eb New API calls el_torito_set_id_string(), el_torito_get_id_string(),
el_torito_set_selection_crit(), el_torito_get_selection_crit().
2010-04-23 18:01:27 +02:00
ace0d1ab2e Bug fix of previous revision 653:
SIGSEGV because of dereferencing NULL when writing without boot image.
2010-04-22 23:13:54 +02:00
59d143c1f0 Added support for multiple boot images.
New API calls iso_image_add_boot_image() , iso_image_get_all_boot_imgs(),
el_torito_get_boot_platform_id(), el_torito_get_load_seg(),
el_torito_get_load_size(), el_torito_get_bootable()
2010-04-22 14:04:51 +02:00
da2c0520cc Changed new API call from iso_image_set_boot_platform_id() to
el_torito_set_boot_platform_id().
Introduced new API call iso_image_set_boot_catalog_weight().
2010-04-20 16:23:17 +02:00
517f520570 New API call iso_image_set_boot_platform_id().
Downgraded ISO_WRONG_EL_TORITO and ISO_UNSUPPORTED_EL_TORITO from SORRY
to WARN and implemented the tolerance that is promised by their message
texts.
2010-04-20 11:10:00 +02:00
98d2b4c996 Version leap to 0.6.31 2010-04-17 13:23:49 +02:00
481d425580 Version leap to 0.6.30 2010-04-17 13:18:56 +02:00
99e988d652 Updated genealogy of isohybrid MBR production. 2010-04-17 08:46:45 +02:00
38a7b4a5b1 New API calls iso_read_opts_load_system_area() and iso_image_get_system_area() 2010-04-16 21:49:44 +02:00
9dc894584d Enhanced configure tests for iconv. Now aborting if not available. 2010-04-15 12:16:41 +02:00
1a7ab679cd Extended effect of iso_write_opts_set_pvd_times() parameter uuid to
creation time, to keep it consistent with modification time.
2010-04-14 12:00:43 +02:00
016baf9984 Implemented no_force_dots and separate omit_version_numbers for
Joliet to allow producing the same Joliet names as mkisofs -J.
2010-04-13 10:18:55 +02:00
b089f2e978 New bit1 of iso_write_opts_set_system_area() options.
New inner call make_isolinux_mbr() produces a bootable System Area
from an ISOLINUX mbr/isohdp[fp]x*.bin file and an ISOLINUX
El Torito bootable image (isolinux.bin).
2010-04-10 18:50:59 +02:00
c3d5ab7bc7 New API call iso_write_opts_set_pvd_times(). 2010-04-07 21:03:00 +02:00
f13167335a New API call iso_write_opts_set_system_area() acts like mkisofs option -G 2010-04-06 14:41:36 +02:00
f0f378c38f Adjusted copyright and license statements in single files. 2010-02-14 11:39:34 +01:00
907b44c556 Added copyright statements to technical specs in doc directory. 2010-02-13 14:18:40 +01:00
00011036dd Updated license situation of make_isohybrid_mbr.c 2010-02-12 21:57:48 +01:00
55497d3931 Changed comments from "Linux" to "GNU/Linux" where appropriate. 2010-02-12 20:14:15 +01:00
c47f206fe3 Version leap to 0.6.29 2010-02-10 15:45:19 +01:00
61 changed files with 6241 additions and 1201 deletions

208
ChangeLog
View File

@ -1 +1,209 @@
bzr branch lp:libisofs/for-libisoburn (to become libisofs-0.6.42.tar.gz)
===============================================================================
- no novelties yet
libisofs-0.6.40.tar.gz Fri Dec 10 2010
===============================================================================
* New API call iso_write_opts_set_disc_label(), new system area type
3 = SUN Disk Label for booting SUN SPARC systems.
* New API call iso_write_opts_set_will_cancel() avoids start of write thread
and is to be used to inquire the future image size.
* New error reply code ISO_DISPLACE_ROLLOVER for external data sources with
address displacement.
libisofs-0.6.38.tar.gz Sat Oct 23 2010
===============================================================================
* New API calls iso_write_opts_attach_jte() and iso_write_opts_detach_jte()
allow to use libjte for jigdo production.
* New API call iso_write_opts_set_tail_blocks() for tail padding inside
ISO image.
* New API call iso_image_generator_is_running() to learn when the write thread
is done.
* New API calls iso_image_add_mips_boot_file(),
iso_image_get_mips_boot_files(), iso_image_give_up_mips_boot().
* New API call iso_write_opts_set_partition_img() for appending e.g. a small
empty FAT12 filesystem which may be used on USB stick.
libisofs-0.6.36.tar.gz Wed Sep 15 2010
===============================================================================
* New API function iso_write_opts_set_part_offset() controls creation of
an MBR with a first partiton table entry that bears non-zero start address.
A second set of volume descriptors and directory tree+tables gets created
which can be used to mount the image at the partition start.
* Hiding all non-API symbols from the linker by use of --version-script
* Automatic C++ detection in libisofs.h by using macro __cplusplus
* Corrected several memory leaks and potential NULL pointer evaluations
in case of memory shortage.
* Now with history of release notes in ./ChangeLog file.
libisofs-0.6.34.tar.gz Tue Jun 29 2010
===============================================================================
* New API call iso_image_set_boot_catalog_hidden()
* New API call iso_node_get_hidden()
* New IsoHideNodeFlag bit LIBISO_HIDE_BUT_WRITE
* New error code ISO_BOOT_NO_CATALOG
* Opportunity to reduce compile line length by including "config.h"
libisofs-0.6.32.tar.gz Mon May 03 2010
===============================================================================
* New API call iso_image_set_boot_catalog_weight()
* New API call iso_image_add_boot_image()
* New API calls el_torito_set_boot_platform_id(), el_torito_set_id_string(),
el_torito_set_selection_crit()
* New API calls iso_image_get_all_boot_imgs(), el_torito_get_boot_platform_id(),
el_torito_get_load_seg(), el_torito_get_load_size(), el_torito_get_bootable(),
el_torito_get_id_string(), el_torito_get_selection_crit(),
el_torito_get_isolinux_options(), el_torito_get_boot_media_type()
* New API call el_torito_seems_boot_info_table()
libisofs-0.6.30.tar.gz Sat Apr 17 2010
===============================================================================
* New API call iso_write_opts_set_system_area() acts like mkisofs option -G.
* New API call iso_write_opts_set_pvd_times().
* Now able to produce a bootable System Area from an ISOLINUX mbr/isohdp
[fp]x*.bin file and an ISOLINUX El Torito bootable image (isolinux.bin).
* Now able to produce the same Joliet names as mkisofs.
* New API calls iso_read_opts_load_system_area() and
iso_image_get_system_area() for multi-session handling of MBRs.
libisofs-0.6.28.tar.gz Wed Feb 10 2010
===============================================================================
* Bug fix: Random checksum index could sneak in via boot catalog node
and cause a SIGSEGV.
* Improved compilability out of the box on FreeBSD.
libisofs-0.6.26.tar.gz Wed Jan 20 2010
===============================================================================
* Bug fix: Invalid old checksum tags were preserved with
iso_write_opts_set_overwrite_buf(), if the new session produced no checksums.
* The checksum buffer for the emerging image gets now marked as invalid if
image generation is canceled.
* More graceful reaction on filesystems where ACL are not enabled but
nevertheless requested by the application.
* Adaptions to problems reported by Debian buildd.
libisofs-0.6.24.tar.gz Thu Oct 08 2009
===============================================================================
* Bug fix: Short Rock Ridge names got stripped of trailing blanks when loaded
and written again to a follow-up session. Long names could lose inner blanks.
* Bug fix: Avoided to return NULL or single blanks as content of id strings by
API calls iso_image_get_volset_id() ... iso_image_get_biblio_file_id().
* New API call iso_write_opts_set_scdbackup_tag().
libisofs-0.6.22.tar.gz Tue Aug 25 2009
===============================================================================
* New API call iso_write_opts_set_record_md5() for writing MD5 sums.
* New API call iso_read_opts_set_no_md5() for importing MD5 sums.
* New API calls iso_image_get_session_md5() and iso_file_get_md5().
* New API calls iso_md5_start(), iso_md5_compute(), iso_md5_clone(),
iso_md5_end(), iso_md5_match() for own MD5 computations.
* New API call iso_util_decode_md5_tag() to recognize and parse checksum tags.
* New API call iso_file_make_md5() to equip old file nodes with MD5.
* Improvements with ./configure and its help text.
libisofs-0.6.20.tar.gz Sun May 30 2009
===============================================================================
* Optional automatic detection and recording of hard link
relations between files.
* Support for restoring hard link relations by the app.
libisofs-0.6.18.tar.gz Fri Apr 17 2009
===============================================================================
* Opportunity to set the input charset automatically from an eventual xattr
"isofs.cs" of the image root node.
* New general filter API to inquire and remove filters.
* Specialized APIs for installing filters which are based on external processes
or based on zlib.
* New API call to inquire the original source path of a data file in an
emerging image.
libisofs-0.6.16.tar.gz Wed Mar 11
===============================================================================
* Bug fix: The ".." directory record pointed to the same data block as the "."
entry.
* Bug fix: The use of iso_write_opts_set_rrip_version_1_10() caused a wrong
size announcement in the CE entry which points to the ER signature
of the image root.
* New API call iso_write_opts_get_data_start() inquires the start address of
the data section of an emerging ISO image.
* ISO image generation does not absolutely depend on the availability of
character set "WCHAR_T" with iconv_open(3) any more.
libisofs-0.6.14.tar.gz Sat Feb 28 2009
===============================================================================
* New API calls iso_image_set_ignore_aclea(), iso_read_opts_set_no_aaip()
control import of ACL and xattr.
* New API calls iso_write_opts_set_aaip(), iso_write_opts_set_aaip_susp_1_10()
control output of ACL and xattr into generated ISO image.
* New API call iso_file_source_get_aa_string(), new function member
get_aa_string() in IsoFileSource_Iface allow to access opaquely encoded ACL
and xattr. New function handle aaip_xinfo_func attaches aa_strings to
IsoNode objects.
* New API calls iso_node_get_acl_text(), iso_node_set_acl_text(),
iso_node_get_perms_wo_acl() allow inquiry and manipulation of ACLs in
IsoNode objects.
* New API calls iso_node_get_attrs(), iso_node_set_attrs() allow inquiry and
manipulation of xattr in IsoNode objects.
libisofs-0.6.12.tar.gz Wed Nov 26 2008
===============================================================================
* New API calls iso_set_local_charset() and iso_get_local_charset()
* New API calls iso_write_opts_set_rrip_version_1_10() and
iso_write_opts_set_dir_rec_mtime()
* New API call el_torito_set_isolinux_options() allows to patch ISOLINUX boot
images and to generate a isohybrid MBR on the fly. Such an MBR makes the ISO
image bootable from disk-like hardware, e.g. from USB stick. The ISOLINUX
boot image has to be of syslinux 3.72 or later to allow MBR generation.
* Old API call el_torito_patch_isolinux_image() is deprecated now.
libisofs-0.6.10.pl01.tar.gz Wed Nov 19 2008
===============================================================================
* Bug fix: If images generated by mkisofs were loaded then files of size 0
could share their size information with files that contain data. Ticket #144.
* Bug fix: ISOLINUX boot images were patched suitable for El Torito but not for
an eventual MBR added by SYSLINUX script isohybrid.
libisofs 0.6.10 Mon Oct 6 2008:
===============================================================================
* Bug fix: Patching of existing ISOLINUX boot images led to a SIGSEGV.
* Bug fix: Adding a new ISOLINUX boot image or patching of an existing one
caused a read operation although writing had already begun.
libisofs-0.6.8.tar.gz Thu Sep 18 2008
===============================================================================
* Support for very large data files in the ISO 9660 image
(Level 3, multi-extent)
* Bug fix: it was assumed that isolinux images were always a multiple of 4
bytes
* New API call iso_image_update_sizes() to refresh recorded file sizes
immediately before image generation begins
libisofs-0.6.6.tar.gz Sun Jun 1 2008
===============================================================================
* Bug fix: major,minor numbers of device files were not read properly from
existing images
* Bug fix: iso_tree_path_to_node() returned 1 if a directory path component was
a non-directory file
* New API call iso_special_get_dev() retrieves major, minor numbers of device
files
libisofs-0.6.4.tar.gz Sun Apr 27 2008
===============================================================================
* Extended information: iso_node_add_xinfo()
* New node iteration: iso_dir_find_children()
* Custom image file content via iso_tree_add_new_file()
* Missing feature added to map a disk file to an arbitrary image file path via
iso_tree_add_new_node()
* Obtain image path of a node object via iso_tree_get_node_path()
* Various bugfixes
libisofs-0.6.2.1.tar.gz Thu Feb 14 2008
===============================================================================
* FIX: missing buffer.h preventing build from succeeding
Libisofs 0.6.2
===============================================================================
* Initial release of new generation libisofs
* Completely new API
* Long term commitment to ABI libisofs.so.6

View File

@ -16,7 +16,9 @@ libisofs_libisofs_la_LDFLAGS = \
# Eventually enabling system adapters for ACL and EA.
# ts A90409: Eventually enabling use of zlib.
libisofs_libisofs_la_CFLAGS = $(LIBACL_DEF) $(XATTR_DEF) $(ZLIB_DEF)
# 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.*
@ -42,7 +44,6 @@ libisofs_libisofs_la_SOURCES = \
libisofs/stream.c \
libisofs/filter.h \
libisofs/filter.c \
libisofs/filters/xor_encrypt.c \
libisofs/filters/external.c \
libisofs/filters/zisofs.c \
libisofs/filters/gzip.c \
@ -81,6 +82,9 @@ libisofs_libisofs_la_LIBADD= \
libinclude_HEADERS = \
libisofs/libisofs.h
install-exec-hook:
$(LIBBURNIA_LDCONFIG_CMD) "$(DESTDIR)$(libdir)" || echo 'NOTE: Explicite dynamic library configuration failed. If needed, configure manually for:' "$(DESTDIR)$(libdir)"
## ========================================================================= ##
## Build demo applications
@ -262,6 +266,7 @@ EXTRA_DIST = \
doc/susp_aaip_isofs_names.txt \
doc/zisofs_format.txt \
doc/checksums.txt \
libisofs/libisofs.ver \
libisofs/aaip-os-dummy.c \
libisofs/aaip-os-linux.c \
libisofs/aaip-os-freebsd.c

117
README
View File

@ -7,6 +7,57 @@ Released under GPL (see COPYING file for details).
Copyright (C) 2008 - 2010 Vreixo Formoso, Mario Danic, Thomas Schmitt
libisofs is part of the libburnia project (libburnia-project.org)
------------------------------------------------------------------------------
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/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()
See INSTALL file for general options of ./configure.
------------------------------------------------------------------------------
libisofs is a library to create an ISO-9660 filesystem, supports extensions
@ -23,7 +74,7 @@ Features:
- Creates ISO-9660 images from local files.
- Support for RockRidge and Joliet extensions.
- Support for ISO-9660:1999 (version 2).
- Support for El-Torito bootable images.
- Support for El-Torito bootable images. Tested are: PC-BIOS and EFI.
- Support for multi-extent data files up to 400 GB (level 3).
- Full-featured edition of the image files, including: addition of new
files, removing of existent files, moving files, renaming files,
@ -67,8 +118,9 @@ Features:
Requirements:
-------------
- libburn 0.4.2 headers must be installed at compile time. It is not required
at runtime.
- iconv() functions for character set conversion must be available.
Either implicitely as in Linux or by a separate library like libiconv
on FreeBSD.
Know bugs:
----------
@ -78,31 +130,20 @@ Multisession and image growing can lead to undesired results in several cases:
a) Images with unsupported features, such as:
- UDF.
- HSF/HFS+ or other Mac extensions.
- El-Torito with multiple entries.
- ECMA-119 with extended attributes.
- Non El-Torito boot info.
- ECMA-119 Extended attributes.
- ...
In all these cases, the resulting new image (or new session) could lack some
features of the original image.
features of the original image. Nevertheless, the ECMA-119 System Area with
an eventual Master Boot Record gets preserved by default.
In some cases libisofs will issue warning messages, or even refuse to grow
or modify the image. Others remain undetected. Images created with libisofs
do not have this problems.
b) Bootable El-Torito images may have several problems, that result in a new
image that is not bootable, or that boots from an outdated session. In many
cases it is recommended to add boot info again in the new session.
- isolinux images won't be bootable after a modify. This is because
isolinux images need to have hardcoded the root dir lba. libisofs cannot
know whether an image is an isolinux image or not, so the user is
responsible to tell libisofs that it must patch the image, with the
el_torito_patch_isolinux_image() function. This problem could also exists
on other boot images.
- Most boot images are highly dependent of the image contents, so if the
user moves or removes some files on image it is possible they won't boot
anymore.
- There is no safer way to modify hidden boot images, as the size of the
boot image can't be figured out.
b) Bootable El-Torito images may have problems, that result in a new image that
is not bootable, or that boots from an outdated session. In some cases it
might be necessary to add boot info again in a new first session.
- There is no safe way to modify hidden boot images, as the size of the
boot image can't be figured out.
c) Generated images could have different ECMA-119 low level names, due to
different way to mangle names, to new files added that force old files to
@ -113,38 +154,6 @@ c) Generated images could have different ECMA-119 low level names, due to
relaxed contraints), otherwise libisofs might arbitrarily change the names.
------------------------------------------------------------------------------
Download, Build and Installation
libisofs code is mantained in a Bazaar repository at Launchpad
(https://launchpad.net/libisofs/). You can download it with:
$ bzr branch lp:libisofs
Our build system is based on autotools. For preparing the build you will need
autotools of at least version 1.7. If you have download the code from the
repository, first of all you need to execute
./autogen.sh
on toplevel dir to execute autotools.
Alternatively you may unpack a release tarball for which you do not need
autotools installed.
To build libisofs it should be sufficient to go into its toplevel directory
and execute
./configure --prefix=/usr
make
To make the libraries accessible for running resp. developing applications
make install
See INSTALL file for further details.
------------------------------------------------------------------------------
This program is free software; you can redistribute it and/or modify

View File

@ -16,10 +16,12 @@ AC_DEFUN([TARGET_SHIZZLE],
AC_MSG_CHECKING([target operating system])
LIBBURNIA_LDCONFIG_CMD="echo 'No ldconfig run performed. If needed, configure manually for:'"
case $target in
*-*-linux*)
ARCH=linux
LIBBURN_ARCH_LIBS=
LIBBURNIA_LDCONFIG_CMD=ldconfig
;;
*-*-freebsd*)
ARCH=freebsd
@ -50,8 +52,9 @@ dnl From Bruno Haible.
dnl
AC_DEFUN([LIBBURNIA_CHECK_ICONV],
[
dnl Check whether it is allowed to link with -liconv
AC_MSG_CHECKING([for separate -liconv ])
AC_MSG_CHECKING([for iconv() in separate -liconv ])
libburnia_liconv="no"
libburnia_save_LIBS="$LIBS"
LIBS="$LIBS -liconv"
@ -65,6 +68,13 @@ AC_DEFUN([LIBBURNIA_CHECK_ICONV],
)
AC_MSG_RESULT([$libburnia_liconv])
if test x"$libburnia_save_LIBS" = x"$LIBS"
then
dnl GNU iconv has no function iconv() but libiconv() and a macro iconv()
dnl It is not tested whether this is detected by above macro.
AC_CHECK_LIB(iconv, libiconv, , )
fi
dnl Check for iconv(..., const char **inbuf, ...)
AC_MSG_CHECKING([for const qualifier with iconv() ])
AC_TRY_COMPILE([
@ -79,6 +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 Important: Must be performed _after_ TARGET_SHIZZLE
dnl

View File

@ -1,4 +1,4 @@
AC_INIT([libisofs], [0.6.28], [http://libburnia-project.org])
AC_INIT([libisofs], [0.6.40], [http://libburnia-project.org])
AC_PREREQ([2.50])
dnl AC_CONFIG_HEADER([config.h])
@ -9,12 +9,6 @@ LIBBURNIA_SET_FLAGS
AM_INIT_AUTOMAKE([subdir-objects])
dnl A61101 This breaks Linux build (makes 32 bit off_t)
dnl http://sourceware.org/autobook/autobook/autobook_96.html says
dnl one must include some config.h and this was a pitfall.
dnl So why dig the pit at all ?
dnl AM_CONFIG_HEADER(config.h)
dnl
dnl if MAJOR or MINOR version changes, be sure to change AC_INIT above to match
dnl
@ -46,7 +40,7 @@ dnl If LIBISOFS_*_VERSION changes, be sure to change AC_INIT above to match.
dnl
LIBISOFS_MAJOR_VERSION=0
LIBISOFS_MINOR_VERSION=6
LIBISOFS_MICRO_VERSION=28
LIBISOFS_MICRO_VERSION=40
LIBISOFS_VERSION=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION.$LIBISOFS_MICRO_VERSION
AC_SUBST(LIBISOFS_MAJOR_VERSION)
@ -56,10 +50,10 @@ AC_SUBST(LIBISOFS_VERSION)
dnl Libtool versioning
LT_RELEASE=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION
# 2010.02.10 development jump has not yet happened
# SONAME = 30 - 24 = 6 . Library name = libisofs.6.24.0
LT_CURRENT=30
LT_AGE=24
# 2010.12.10 development jump has not yet happened
# SONAME = 42 - 36 = 6 . Library name = libisofs.6.36.0
LT_CURRENT=42
LT_AGE=36
LT_REVISION=0
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
@ -91,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.
LIBBURNIA_CHECK_ICONV
dnl To abort configuration if iconv() still cannot be compiled
LIBBURNIA_ASSERT_ICONV
AC_PROG_LIBTOOL
AC_SUBST(LIBTOOL_DEPS)
@ -208,6 +205,48 @@ else
fi
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([
Makefile

View File

@ -52,19 +52,6 @@ static char helptext[][80] = {
#include <limits.h>
#define LIBISOFS_WITHOUT_LIBBURN yes
#include "libisofs.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <err.h>
#ifndef PATH_MAX
#define PATH_MAX Libisofs_default_path_maX
#endif
@ -98,7 +85,9 @@ tree_print_dir(IsoDir *dir, int level)
int i;
IsoDirIter *iter;
IsoNode *node;
char *sp = alloca(level * 2 + 1);
char *sp;
sp = calloc(1, level * 2 + 1);
for (i = 0; i < level * 2; i += 2) {
sp[i] = '|';
@ -132,6 +121,7 @@ tree_print_dir(IsoDir *dir, int level)
}
}
iso_dir_iter_free(iter);
free(sp);
}
int gesture_tree(int argc, char **argv)
@ -270,7 +260,7 @@ int gesture_iso(int argc, char **argv)
IsoImage *image;
struct burn_source *burn_src;
unsigned char buf[2048];
FILE *fd;
FILE *fp = NULL;
IsoWriteOpts *opts;
char *volid = "VOLID";
char *boot_img = NULL;
@ -281,7 +271,7 @@ int gesture_iso(int argc, char **argv)
case 'h':
iso_usage(argv);
iso_help();
exit(0);
goto ex;
break;
case 'J':
j = 1;
@ -303,7 +293,7 @@ int gesture_iso(int argc, char **argv)
break;
case '?':
iso_usage(argv);
exit(1);
goto ex;
break;
}
}
@ -311,30 +301,31 @@ int gesture_iso(int argc, char **argv)
if (argc < 2) {
printf ("Please pass directory from which to build ISO\n");
iso_usage(argv);
return 1;
goto ex;
}
if (argc < 3) {
printf ("Please supply output file\n");
iso_usage(argv);
return 1;
goto ex;
}
fd = fopen(argv[optind+1], "w");
if (!fd) {
fp = fopen(argv[optind+1], "w");
if (fp == NULL) {
err(1, "error opening output file");
goto ex;
}
result = iso_init();
if (result < 0) {
printf ("Can't initialize libisofs\n");
return 1;
goto ex;
}
iso_set_msgs_severities("NEVER", "ALL", "");
result = iso_image_new(volid, &image);
if (result < 0) {
printf ("Error creating image\n");
return 1;
goto ex;
}
iso_tree_set_follow_symlinks(image, 0);
iso_tree_set_ignore_hidden(image, 0);
@ -346,7 +337,7 @@ int gesture_iso(int argc, char **argv)
argv[optind]);
if (result < 0) {
printf ("Error adding directory %d\n", result);
return 1;
goto ex;
}
if (boot_img) {
@ -356,7 +347,7 @@ int gesture_iso(int argc, char **argv)
"/isolinux/boot.cat", &bootimg);
if (result < 0) {
printf ("Error adding boot image %d\n", result);
return 1;
goto ex;
}
el_torito_set_load_size(bootimg, 4);
el_torito_patch_isolinux_image(bootimg);
@ -365,7 +356,7 @@ int gesture_iso(int argc, char **argv)
result = iso_write_opts_new(&opts, 0);
if (result < 0) {
printf ("Cant create write opts, error %d\n", result);
return 1;
goto ex;
}
iso_write_opts_set_iso_level(opts, level);
iso_write_opts_set_rockridge(opts, rr);
@ -375,21 +366,25 @@ int gesture_iso(int argc, char **argv)
result = iso_image_create_burn_source(image, opts, &burn_src);
if (result < 0) {
printf ("Cant create image, error %d\n", result);
return 1;
goto ex;
}
iso_write_opts_free(opts);
while (burn_src->read_xt(burn_src, buf, 2048) == 2048) {
fwrite(buf, 1, 2048, fd);
fwrite(buf, 1, 2048, fp);
}
fclose(fd);
fclose(fp);
burn_src->free_data(burn_src);
free(burn_src);
iso_image_unref(image);
iso_finish();
return 0;
ex:;
if (fp != NULL)
fclose(fp);
return 1;
}
@ -436,7 +431,9 @@ iso_read_print_dir(IsoFileSource *dir, int level)
int ret, i;
IsoFileSource *file;
struct stat info;
char *sp = alloca(level * 2 + 1);
char *sp;
sp = calloc(1, level * 2 + 1);
for (i = 0; i < level * 2; i += 2) {
sp[i] = '|';
@ -466,6 +463,7 @@ iso_read_print_dir(IsoFileSource *dir, int level)
if (ret < 0) {
printf ("Can't print dir\n");
}
free(sp);
}
int gesture_iso_read(int argc, char **argv)
@ -630,18 +628,19 @@ int gesture_iso_modify(int argc, char **argv)
IsoDataSource *src;
struct burn_source *burn_src;
unsigned char buf[2048];
FILE *fd;
FILE *fp = NULL;
IsoWriteOpts *opts;
IsoReadOpts *ropts;
if (argc < 4) {
iso_modify_usage(argv);
return 1;
goto ex;
}
fd = fopen(argv[3], "w");
if (!fd) {
fp = fopen(argv[3], "w");
if (fp == NULL) {
err(1, "error opening output file");
goto ex;
}
iso_init();
@ -651,14 +650,14 @@ int gesture_iso_modify(int argc, char **argv)
result = iso_data_source_new_from_file(argv[1], &src);
if (result < 0) {
printf ("Error creating data source\n");
return 1;
goto ex;
}
/* create the image context */
result = iso_image_new("volume_id", &image);
if (result < 0) {
printf ("Error creating image\n");
return 1;
goto ex;
}
iso_tree_set_follow_symlinks(image, 0);
iso_tree_set_ignore_hidden(image, 0);
@ -667,49 +666,53 @@ int gesture_iso_modify(int argc, char **argv)
result = iso_read_opts_new(&ropts, 0);
if (result < 0) {
fprintf(stderr, "Error creating read options\n");
return 1;
goto ex;
}
result = iso_image_import(image, src, ropts, NULL);
iso_read_opts_free(ropts);
iso_data_source_unref(src);
if (result < 0) {
printf ("Error importing previous session %d\n", result);
return 1;
goto ex;
}
/* add new dir */
result = iso_tree_add_dir_rec(image, iso_image_get_root(image), argv[2]);
if (result < 0) {
printf ("Error adding directory %d\n", result);
return 1;
goto ex;
}
/* generate a new image with both previous and added contents */
result = iso_write_opts_new(&opts, 1);
if (result < 0) {
printf("Cant create write opts, error %d\n", result);
return 1;
goto ex;
}
/* for isolinux: iso_write_opts_set_allow_full_ascii(opts, 1); */
result = iso_image_create_burn_source(image, opts, &burn_src);
if (result < 0) {
printf ("Cant create image, error %d\n", result);
return 1;
goto ex;
}
iso_write_opts_free(opts);
while (burn_src->read_xt(burn_src, buf, 2048) == 2048) {
fwrite(buf, 1, 2048, fd);
fwrite(buf, 1, 2048, fp);
}
fclose(fd);
fclose(fp);
burn_src->free_data(burn_src);
free(burn_src);
iso_image_unref(image);
iso_finish();
return 0;
return 0;
ex:
if (fp != NULL)
fclose(fp);
return 1;
}
@ -728,25 +731,26 @@ int gesture_iso_ms(int argc, char **argv)
IsoDataSource *src;
struct burn_source *burn_src;
unsigned char buf[2048];
FILE *fd;
FILE *fp = NULL;
IsoWriteOpts *opts;
IsoReadOpts *ropts;
uint32_t ms_block;
if (argc < 6) {
iso_ms_usage(argv);
return 1;
goto ex;
}
if (strcmp(argv[3], argv[5]) == 0) {
fprintf(stderr,
"image_file and output_file must not be the same file.\n");
return 1;
goto ex;
}
fd = fopen(argv[5], "w");
if (!fd) {
fp = fopen(argv[5], "w");
if (!fp) {
err(1, "error opening output file");
goto ex;
}
iso_init();
@ -756,14 +760,14 @@ int gesture_iso_ms(int argc, char **argv)
result = iso_data_source_new_from_file(argv[3], &src);
if (result < 0) {
printf ("Error creating data source\n");
return 1;
goto ex;
}
/* create the image context */
result = iso_image_new("volume_id", &image);
if (result < 0) {
printf ("Error creating image\n");
return 1;
goto ex;
}
iso_tree_set_follow_symlinks(image, 0);
iso_tree_set_ignore_hidden(image, 0);
@ -772,7 +776,7 @@ int gesture_iso_ms(int argc, char **argv)
result = iso_read_opts_new(&ropts, 0);
if (result < 0) {
fprintf(stderr, "Error creating read options\n");
return 1;
goto ex;
}
iso_read_opts_set_start_block(ropts, atoi(argv[1]));
result = iso_image_import(image, src, ropts, NULL);
@ -780,21 +784,21 @@ int gesture_iso_ms(int argc, char **argv)
iso_data_source_unref(src);
if (result < 0) {
printf ("Error importing previous session %d\n", result);
return 1;
goto ex;
}
/* add new dir */
result = iso_tree_add_dir_rec(image, iso_image_get_root(image), argv[4]);
if (result < 0) {
printf ("Error adding directory %d\n", result);
return 1;
goto ex;
}
/* generate a multisession image with new contents */
result = iso_write_opts_new(&opts, 1);
if (result < 0) {
printf("Cant create write opts, error %d\n", result);
return 1;
goto ex;
}
/* round up to 32kb aligment = 16 block */
@ -805,20 +809,24 @@ int gesture_iso_ms(int argc, char **argv)
result = iso_image_create_burn_source(image, opts, &burn_src);
if (result < 0) {
printf ("Cant create image, error %d\n", result);
return 1;
goto ex;
}
iso_write_opts_free(opts);
while (burn_src->read_xt(burn_src, buf, 2048) == 2048) {
fwrite(buf, 1, 2048, fd);
fwrite(buf, 1, 2048, fp);
}
fclose(fd);
fclose(fp);
burn_src->free_data(burn_src);
free(burn_src);
iso_image_unref(image);
iso_finish();
return 0;
return 0;
ex:;
if (fp != NULL)
fclose(fp);
return 1;
}

727
doc/boot_sectors.txt Normal file
View 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
| | 0 for boot_media == 0.
| |
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
| | 0 for boot_media == 0.
| |
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
------------------------------------------------------------------------------

View File

@ -305,3 +305,16 @@ The size of the volume is 2456606865 bytes, which have a MD5 sum of
The checksum of "2_2 B00109.143415 2456606865 485bbef110870c45754d7adcc844a72c"
is c2355d5ea3c94d792ff5893dfe0d6d7b.
-------------------------------------------------------------------------------
This text is under
Copyright (c) 2009 - 2010 Thomas Schmitt <scdbackup@gmx.net>
It shall only be modified in sync with libisofs and other software which
makes use of libisofs checksums. Please mail change requests to mailing list
<libburn-hackers@pykix.org> or to the copyright holder in private.
Only if you cannot reach the copyright holder for at least one month it is
permissible to modify this text under the same license as the affected
copy of libisofs.
If you do so, you commit yourself to taking reasonable effort to stay in
sync with the other interested users of this text.

View File

@ -154,13 +154,6 @@ QT_AUTOBRIEF = NO
MULTILINE_CPP_IS_BRIEF = YES
# If the DETAILS_AT_TOP tag is set to YES then Doxygen
# will output the detailed description near the top, like JavaDoc.
# If set to NO, the detailed description appears after the member
# documentation.
DETAILS_AT_TOP = YES
# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
# member inherits the documentation from any documented member that it
# re-implements.

View File

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

View File

@ -149,3 +149,14 @@ Registered:
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
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.

View File

@ -141,3 +141,14 @@ SUSP 1.12
RRIP 1.12
ftp://ftp.ymi.com/pub/rockridge/rrip112.ps
-------------------------------------------------------------------------------
This text is under
Copyright (c) 2009 - 2010 Thomas Schmitt <scdbackup@gmx.net>
It shall reflect the effective technical specifications as implemented in
zisofs-tools and the Linux kernel. So please contact mailing list
<libburn-hackers@pykix.org> or to the copyright holder in private, if you
want to make changes.
Only if you cannot reach the copyright holder for at least one month it is
permissible to modify and distribute this text under the license "BSD revised".

View File

@ -11,10 +11,14 @@
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 <sys/types.h>
#include <unistd.h>

View File

@ -3,7 +3,7 @@
aaip-os-freebsd.c
Arbitrary Attribute Interchange Protocol , system adapter for getting and
setting of ACLs and ixattr.
setting of ACLs and xattr.
To be included by aaip_0_2.c
@ -11,6 +11,10 @@
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include <ctype.h>
#include <sys/types.h>
#include <unistd.h>

View File

@ -7,10 +7,14 @@
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 <sys/types.h>
#include <unistd.h>
@ -291,9 +295,9 @@ ex:;
aaip_get_acl_text("", &a_acl_text, 1 << 15); /* free */
if(d_acl_text != NULL)
aaip_get_acl_text("", &d_acl_text, 1 << 15); /* free */
if(list != NULL)
free(list);
if(ret <= 0 || (flag & (1 << 15))) {
if(list != NULL)
free(list);
if(*names != NULL) {
for(i= 0; i < *num_attrs; i++)
free((*names)[i]);

View File

@ -7,10 +7,14 @@
See test/aaip_0_2.h
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 <sys/types.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-
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-

View File

@ -9,7 +9,7 @@
test/aaip_0_2.h - Public declarations
Copyright (c) 2009 Thomas Schmitt, libburnia project, GPLv2
Copyright (c) 2009 Thomas Schmitt, libburnia project, GPLv2+
*/

View File

@ -17,6 +17,10 @@
*
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
/*
Use the copy of the struct burn_source definition in libisofs.h
*/
@ -289,7 +293,51 @@ unsigned int iso_ring_buffer_get_times_empty(IsoRingBuffer *buf)
}
/**
/** Internal via buffer.h
*
* Get the status of a ring buffer.
*
* @param buf
* The ring buffer object to inquire
* @param size
* Will be filled with the total size of the buffer, in bytes
* @param free_bytes
* Will be filled with the bytes currently available in buffer
* @return
* < 0 error, > 0 state:
* 1="active" : input and consumption are active
* 2="ending" : input has ended without error
* 3="failing" : input had error and ended,
* 5="abandoned" : consumption has ended prematurely
* 6="ended" : consumption has ended without input error
* 7="aborted" : consumption has ended after input error
*/
int iso_ring_buffer_get_buf_status(IsoRingBuffer *buf, size_t *size,
size_t *free_bytes)
{
int ret;
if (buf == NULL) {
return ISO_NULL_POINTER;
}
/* get mutex */
pthread_mutex_lock(&buf->mutex);
if (size) {
*size = buf->cap;
}
if (free_bytes) {
*free_bytes = buf->cap - buf->size;
}
ret = (buf->rend ? 4 : 0) + (buf->wend + 1);
pthread_mutex_unlock(&buf->mutex);
return ret;
}
/** API via libisofs.h
*
* Get the status of the buffer used by a burn_source.
*
* @param b
@ -317,18 +365,7 @@ int iso_ring_buffer_get_status(struct burn_source *b, size_t *size,
return ISO_NULL_POINTER;
}
buf = ((Ecma119Image*)(b->data))->buffer;
/* get mutex */
pthread_mutex_lock(&buf->mutex);
if (size) {
*size = buf->cap;
}
if (free_bytes) {
*free_bytes = buf->cap - buf->size;
}
ret = (buf->rend ? 4 : 0) + (buf->wend + 1);
pthread_mutex_unlock(&buf->mutex);
ret = iso_ring_buffer_get_buf_status(buf, size, free_bytes);
return ret;
}

View File

@ -63,6 +63,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);
/** Backend of API call iso_ring_buffer_get_status()
*
* Get the status of a ring buffer.
*
* @param buf
* The ring buffer object to inquire
* @param size
* Will be filled with the total size of the buffer, in bytes
* @param free_bytes
* Will be filled with the bytes currently available in buffer
* @return
* < 0 error, > 0 state:
* 1="active" : input and consumption are active
* 2="ending" : input has ended without error
* 3="failing" : input had error and ended,
* 5="abandoned" : consumption has ended prematurely
* 6="ended" : consumption has ended without input error
* 7="aborted" : consumption has ended after input error
*/
int iso_ring_buffer_get_buf_status(IsoRingBuffer *buf, size_t *size,
size_t *free_bytes);
/**
* Close the buffer (to be called by the writer).
* You have to explicity close the buffer when you don't have more data to

View File

@ -8,6 +8,10 @@
* See COPYING file for details.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
/* libisofs.h defines aaip_xinfo_func */
#include "libisofs.h"
@ -20,7 +24,7 @@
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <stdio.h>
#ifndef PATH_MAX
#define PATH_MAX Libisofs_default_path_maX
@ -100,7 +104,7 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
IsoNode *new;
IsoFilesystem *fs;
char *name;
unsigned char *aa_string;
unsigned char *aa_string = NULL;
char *a_text = NULL, *d_text = NULL;
if (builder == NULL || src == NULL || node == NULL) {
@ -217,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,
1 << 15); /* free ACL texts */
if(aa_string != NULL)
free(aa_string);
aa_string = NULL;
}
/* Obtain ownership of eventual AAIP string */
@ -227,6 +234,8 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
ret = iso_node_add_xinfo(new, aaip_xinfo_func, aa_string);
if (ret < 0)
return ret;
} else if(aa_string != NULL) {
free(aa_string);
}
*node = new;

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -32,11 +32,33 @@
*/
#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
/**
* Holds the options for the image generation.
*/
struct iso_write_opts {
int will_cancel;
int level; /**< ISO level to write at. (ECMA-119, 10) */
/** Which extensions to support. */
@ -57,8 +79,10 @@ struct iso_write_opts {
/**
* Omit the version number (";1") at the end of the ISO-9660 identifiers.
* Version numbers are usually not used.
* bit0= ECMA-119 and Joliet (for historical reasons)
* bit1= Joliet
*/
unsigned int omit_version_numbers :1;
unsigned int omit_version_numbers :2;
/**
* Allow ISO-9660 directory hierarchy to be deeper than 8 levels.
@ -82,8 +106,10 @@ struct iso_write_opts {
* ISO-9660 forces filenames to have a ".", that separates file name from
* extension. libisofs adds it if original filename doesn't has one. Set
* this to 1 to prevent this behavior
* bit0= ECMA-119
* bit1= Joliet
*/
unsigned int no_force_dots :1;
unsigned int no_force_dots :2;
/**
* Allow lowercase characters in ISO-9660 filenames. By default, only
@ -148,8 +174,6 @@ struct iso_write_opts {
*/
unsigned int dir_rec_mtime :1;
#ifdef Libisofs_with_checksumS
/**
* 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
@ -170,8 +194,6 @@ struct iso_write_opts {
*/
unsigned int md5_file_checksums :2;
#endif /* Libisofs_with_checksumS */
/** If files should be sorted based on their weight. */
unsigned int sort_files :1;
@ -298,6 +320,51 @@ struct iso_write_opts {
*/
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;
@ -309,9 +376,13 @@ typedef struct Iso_Image_Writer IsoImageWriter;
struct ecma119_image
{
int refcount;
IsoImage *image;
Ecma119Node *root;
int will_cancel :1;
unsigned int iso_level :2;
/* extensions */
@ -328,11 +399,11 @@ struct ecma119_image
unsigned int always_gmt :1;
/* relaxed constraints */
unsigned int omit_version_numbers :1;
unsigned int omit_version_numbers :2;
unsigned int allow_deep_paths :1;
unsigned int allow_longer_paths :1;
unsigned int max_37_char_filenames :1;
unsigned int no_force_dots :1;
unsigned int no_force_dots :2;
unsigned int allow_lowercase :1;
unsigned int allow_full_ascii :1;
@ -353,13 +424,9 @@ struct ecma119_image
/* Store in ECMA-119 timestamp mtime of source */
unsigned int dir_rec_mtime :1;
#ifdef Libisofs_with_checksumS
unsigned int md5_session_checksum :1;
unsigned int md5_file_checksums :2;
#endif /* Libisofs_with_checksumS */
/*
* Mode replace. If one of these flags is set, the correspodent values are
* replaced with values below.
@ -392,8 +459,9 @@ struct ecma119_image
off_t total_size;
uint32_t vol_space_size;
/* Bytes already written, just for progress notification */
/* Bytes already written to image output */
off_t bytes_written;
/* just for progress notification */
int percent_written;
/*
@ -402,6 +470,11 @@ struct ecma119_image
*/
uint32_t curblock;
/*
* The address to be used for the content pointer of empty data files.
*/
uint32_t empty_file_block;
/*
* number of dirs in ECMA-119 tree, computed together with dir position,
* and needed for path table computation in a efficient way
@ -434,7 +507,33 @@ struct ecma119_image
*/
struct el_torito_boot_catalog *catalog;
IsoFileSrc *cat; /**< location of the boot catalog in the new image */
IsoFileSrc *bootimg; /**< location of the boot image in the new image */
int num_bootsrc;
IsoFileSrc **bootsrc; /* location of the boot images in the new image */
/*
* 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 PC-BIOS 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 PC-BIOS 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
*/
int system_area_options;
/*
* Number of pad blocks that we need to write. Padding blocks are blocks
@ -449,7 +548,7 @@ struct ecma119_image
* file data is written in the first 64 KiB, that are the bytes we usually
* overwrite.
*/
uint32_t pad_blocks;
uint32_t mspad_blocks;
size_t nwriters;
IsoImageWriter **writers;
@ -457,8 +556,6 @@ struct ecma119_image
/* tree of files sources */
IsoRBTree *files;
#ifdef Libisofs_with_checksumS
unsigned int checksum_idx_counter;
void *checksum_ctx;
off_t checksum_counter;
@ -484,14 +581,69 @@ struct ecma119_image
char scdbackup_tag_parm[100];
char *scdbackup_tag_written;
#endif /* Libisofs_with_checksumS */
/* Buffer for communication between burn_source and writer thread */
IsoRingBuffer *buffer;
/* writer thread descriptor */
pthread_t wthread;
int wthread_is_running;
pthread_attr_t th_attr;
/* 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]

View File

@ -8,6 +8,10 @@
* See COPYING file for details.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include "ecma119_tree.h"
#include "ecma119.h"
#include "node.h"
@ -64,18 +68,18 @@ int get_iso_name(Ecma119Image *img, IsoNode *iso, char **name)
} else {
if (img->max_37_char_filenames) {
isoname = iso_r_fileid(ascii_name, 36, relaxed,
img->no_force_dots ? 0 : 1);
(img->no_force_dots & 1) ? 0 : 1);
} else if (img->iso_level == 1) {
if (relaxed) {
isoname = iso_r_fileid(ascii_name, 11, relaxed,
img->no_force_dots ? 0 : 1);
(img->no_force_dots & 1) ? 0 : 1);
} else {
isoname = iso_1_fileid(ascii_name);
}
} else {
if (relaxed) {
isoname = iso_r_fileid(ascii_name, 30, relaxed,
img->no_force_dots ? 0 : 1);
(img->no_force_dots & 1) ? 0 : 1);
} else {
isoname = iso_2_fileid(ascii_name);
}
@ -146,15 +150,11 @@ int create_dir(Ecma119Image *img, IsoDir *iso, Ecma119Node **node)
return ISO_SUCCESS;
}
/**
* 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 create_file_src(Ecma119Image *img, IsoFile *iso, IsoFileSrc **src)
{
int ret;
IsoFileSrc *src;
off_t size;
size = iso_stream_get_size(iso->stream);
@ -166,8 +166,25 @@ int create_file(Ecma119Image *img, IsoFile *iso, Ecma119Node **node)
free(ipath);
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) {
return ret;
}
@ -267,58 +284,78 @@ void ecma119_node_free(Ecma119Node *node)
}
/**
*
* @param flag
* bit0= iso is in a hidden directory. Thus hide it.
* @return
* 1 success, 0 node ignored, < 0 error
*
*/
static
int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree,
int depth, int pathlen)
int depth, int pathlen, int flag)
{
int ret;
Ecma119Node *node;
int ret, hidden;
Ecma119Node *node = NULL;
int max_path;
char *iso_name= NULL;
char *iso_name= NULL, *ipath = NULL;
IsoFileSrc *src = NULL;
if (image == NULL || iso == NULL || tree == NULL) {
return ISO_NULL_POINTER;
}
*tree = NULL;
hidden = flag & 1;
if (iso->hidden & LIBISO_HIDE_ON_RR) {
/* file will be ignored */
return 0;
hidden = 1;
if (!((iso->hidden & LIBISO_HIDE_BUT_WRITE) ||
iso->type == LIBISO_BOOT)) {
return 0; /* file will be ignored */
}
}
ret = get_iso_name(image, iso, &iso_name);
if (ret < 0) {
return ret;
}
max_path = pathlen + 1 + (iso_name ? strlen(iso_name) : 0);
if (!image->rockridge) {
if ((iso->type == LIBISO_DIR && depth > 8) && !image->allow_deep_paths) {
char *ipath = iso_tree_get_node_path(iso);
return iso_msg_submit(image->image->id, ISO_FILE_IMGPATH_WRONG, 0,
"File \"%s\" can't be added, because directory depth "
"is greater than 8.", ipath);
free(iso_name);
free(ipath);
return ret;
} else if (max_path > 255 && !image->allow_longer_paths) {
char *ipath = iso_tree_get_node_path(iso);
ret = iso_msg_submit(image->image->id, ISO_FILE_IMGPATH_WRONG, 0,
"File \"%s\" can't be added, because path length "
"is greater than 255 characters", ipath);
free(iso_name);
free(ipath);
return ret;
if (hidden) {
max_path= pathlen;
} else {
ret = get_iso_name(image, iso, &iso_name);
if (ret < 0) {
iso_name = NULL; /* invalid, do not free */
goto ex;
}
max_path = pathlen + 1 + (iso_name ? strlen(iso_name) : 0);
if (!image->rockridge) {
if ((iso->type == LIBISO_DIR && depth > 8) &&
!image->allow_deep_paths) {
ipath = iso_tree_get_node_path(iso);
ret = iso_msg_submit(image->image->id, ISO_FILE_IMGPATH_WRONG,
0, "File \"%s\" can't be added, "
"because directory depth "
"is greater than 8.", ipath);
goto ex;
} else if (max_path > 255 && !image->allow_longer_paths) {
ipath = iso_tree_get_node_path(iso);
ret = iso_msg_submit(image->image->id, ISO_FILE_IMGPATH_WRONG,
0, "File \"%s\" can't be added, "
"because path length "
"is greater than 255 characters", ipath);
goto ex;
}
}
}
switch (iso->type) {
case LIBISO_FILE:
ret = create_file(image, (IsoFile*)iso, &node);
if (hidden) {
ret = create_file_src(image, (IsoFile *) iso, &src);
} else {
ret = create_file(image, (IsoFile*)iso, &node);
}
break;
case LIBISO_SYMLINK:
if (hidden) {
ret = 0; /* Hidden means non-existing */
goto ex;
}
if (image->rockridge) {
ret = create_symlink(image, (IsoSymlink*)iso, &node);
} else {
@ -331,6 +368,10 @@ int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree,
}
break;
case LIBISO_SPECIAL:
if (hidden) {
ret = 0; /* Hidden means non-existing */
goto ex;
}
if (image->rockridge) {
ret = create_special(image, (IsoSpecial*)iso, &node);
} else {
@ -344,7 +385,11 @@ int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree,
break;
case LIBISO_BOOT:
if (image->eltorito) {
ret = create_boot_cat(image, (IsoBoot*)iso, &node);
if (hidden) {
ret = el_torito_catalog_file_src_create(image, &src);
} else {
ret = create_boot_cat(image, (IsoBoot*)iso, &node);
}
} else {
/* log and ignore */
ret = iso_msg_submit(image->image->id, ISO_FILE_IGNORED, 0,
@ -355,21 +400,27 @@ int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree,
{
IsoNode *pos;
IsoDir *dir = (IsoDir*)iso;
ret = create_dir(image, dir, &node);
if (ret < 0) {
return ret;
if (!hidden) {
ret = create_dir(image, dir, &node);
if (ret < 0) {
goto ex;
}
}
ret = ISO_SUCCESS;
pos = dir->children;
while (pos) {
int cret;
Ecma119Node *child;
cret = create_tree(image, pos, &child, depth + 1, max_path);
cret = create_tree(image, pos, &child, depth + 1, max_path,
!!hidden);
if (cret < 0) {
/* error */
ecma119_node_free(node);
if (!hidden)
ecma119_node_free(node);
ret = cret;
break;
} else if (cret == ISO_SUCCESS) {
} else if (cret == ISO_SUCCESS && !hidden) {
/* add child to this node */
int nchildren = node->info.dir->nchildren++;
node->info.dir->children[nchildren] = child;
@ -381,15 +432,30 @@ int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree,
break;
default:
/* should never happen */
return ISO_ASSERT_FAILURE;
ret = ISO_ASSERT_FAILURE;
goto ex;
}
if (ret <= 0) {
free(iso_name);
return ret;
goto ex;
}
node->iso_name = iso_name;
*tree = node;
return ISO_SUCCESS;
if (!hidden) {
node->iso_name = iso_name;
iso_name = NULL; /* now owned by node, do not free */
*tree = node;
node = NULL; /* now owned by caller, do not free */
}
ret = ISO_SUCCESS;
ex:
if (iso_name != NULL)
free(iso_name);
if (ipath != NULL)
free(ipath);
if (node != NULL)
ecma119_node_free(node);
if (hidden && ret == ISO_SUCCESS)
ret = 0;
/* The sources of hidden files are now owned by the rb-tree */
return ret;
}
/**
@ -648,6 +714,7 @@ static
int mangle_tree(Ecma119Image *img, int recurse)
{
int max_file, max_dir;
Ecma119Node *root;
if (img->max_37_char_filenames) {
max_file = max_dir = 37;
@ -657,10 +724,15 @@ int mangle_tree(Ecma119Image *img, int recurse)
} else {
max_file = max_dir = 31;
}
if (recurse) {
return mangle_dir(img, img->root, max_file, max_dir);
if (img->eff_partition_offset > 0) {
root = img->partition_root;
} else {
return mangle_single_dir(img, img->root, max_file, max_dir);
root = img->root;
}
if (recurse) {
return mangle_dir(img, root, max_file, max_dir);
} else {
return mangle_single_dir(img, root, max_file, max_dir);
}
}
@ -778,11 +850,17 @@ int reorder_tree(Ecma119Image *img, Ecma119Node *dir, int level, int pathlen)
{
int ret;
size_t max_path;
Ecma119Node *root;
max_path = pathlen + 1 + max_child_name_len(dir);
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) {
return ret;
}
@ -981,7 +1059,7 @@ int ecma119_tree_create(Ecma119Image *img)
int ret;
Ecma119Node *root;
ret = create_tree(img, (IsoNode*)img->image->root, &root, 1, 0);
ret = create_tree(img, (IsoNode*)img->image->root, &root, 1, 0, 0);
if (ret <= 0) {
if (ret == 0) {
/* unexpected error, root ignored!! This can't happen */
@ -989,10 +1067,14 @@ int ecma119_tree_create(Ecma119Image *img)
}
return ret;
}
img->root = root;
if (img->eff_partition_offset > 0) {
img->partition_root = root;
} else {
img->root = root;
}
iso_msg_debug(img->image->id, "Matching hardlinks...");
ret = match_hardlinks(img, img->root, 0);
ret = match_hardlinks(img, root, 0);
if (ret < 0) {
return ret;
}
@ -1009,7 +1091,7 @@ int ecma119_tree_create(Ecma119Image *img)
if (img->rockridge && !img->allow_deep_paths) {
/* 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) {
return ret;
}
@ -1027,3 +1109,35 @@ int ecma119_tree_create(Ecma119Image *img)
return ISO_SUCCESS;
}
/**
* Search the tree for a certain IsoNode and return its owning Ecma119Node
* or NULL.
*/
static
Ecma119Node *search_iso_node(Ecma119Node *root, IsoNode *node)
{
size_t i;
Ecma119Node *res = NULL;
if (root->node == node)
return root;
for (i = 0; i < root->info.dir->nchildren && res == NULL; i++) {
if (root->info.dir->children[i]->type == ECMA119_DIR)
res = search_iso_node(root->info.dir->children[i], node);
else if (root->info.dir->children[i]->node == node)
res = root->info.dir->children[i];
}
return res;
}
Ecma119Node *ecma119_search_iso_node(Ecma119Image *img, IsoNode *node)
{
Ecma119Node *res = NULL;
if (img->root != NULL)
res = search_iso_node(img->root, node);
return res;
}

View File

@ -90,4 +90,11 @@ int ecma119_tree_create(Ecma119Image *img);
*/
void ecma119_node_free(Ecma119Node *node);
/**
* Search the tree for a certain IsoNode and return its owning Ecma119Node
* or NULL.
*/
Ecma119Node *ecma119_search_iso_node(Ecma119Image *img, IsoNode *node);
#endif /*LIBISO_ECMA119_TREE_H_*/

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2010 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -7,6 +8,10 @@
* See COPYING file for details.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include "eltorito.h"
#include "stream.h"
#include "fsource.h"
@ -17,9 +22,10 @@
#include <stdlib.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
*/
struct boot_info_table {
@ -55,6 +61,19 @@ struct hard_disc_mbr {
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
* no emulation boot images, and is a NOP for other image types.
@ -66,6 +85,14 @@ void el_torito_set_load_seg(ElToritoBootImage *bootimg, short 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
* the initial boot procedure. This is only for no emulation boot images,
@ -78,6 +105,14 @@ void el_torito_set_load_size(ElToritoBootImage *bootimg, short 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
*/
@ -86,8 +121,50 @@ void el_torito_set_no_bootable(ElToritoBootImage *bootimg)
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.
* The original boot image file won't be modified.
* This is needed for isolinux boot images.
@ -106,7 +183,7 @@ void el_torito_patch_isolinux_image(ElToritoBootImage *bootimg)
* bitmask style flag. The following values are defined:
*
* 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.
* The original boot image file won't be modified. This is needed
* to allow isolinux images to be bootable.
@ -124,31 +201,36 @@ int el_torito_set_isolinux_options(ElToritoBootImage *bootimg, int options, int
return ISO_SUCCESS;
}
/* TODO getter for boot image properties should be exposed
* useful when reading discs */
int el_torito_get_boot_media_type(const ElToritoBootImage *bootimg)
/* API */
int el_torito_get_isolinux_options(ElToritoBootImage *bootimg, int flag)
{
return bootimg->isolinux_options & 0x03;
}
/* API */
int el_torito_get_boot_media_type(ElToritoBootImage *bootimg,
enum eltorito_boot_media_type *media_type)
{
if (bootimg) {
switch (bootimg->type) {
case 1:
case 2:
case 3:
return ELTORITO_FLOPPY_EMUL;
break;
*media_type = ELTORITO_FLOPPY_EMUL;
return 1;
case 4:
return ELTORITO_HARD_DISC_EMUL;
break;
*media_type = ELTORITO_HARD_DISC_EMUL;
return 1;
case 0:
return ELTORITO_NO_EMUL;
break;
*media_type = ELTORITO_NO_EMUL;
return 1;
default:
/* should never happen */
return ISO_ASSERT_FAILURE;
break;
}
} else {
return ISO_WRONG_ARG_VALUE;
}
return ISO_WRONG_ARG_VALUE;
}
static
@ -227,6 +309,7 @@ int create_image(IsoImage *image, const char *image_path,
int boot_media_type = 0;
int load_sectors = 0; /* number of sector to load */
unsigned char partition_type = 0;
off_t size;
IsoNode *imgfile;
IsoStream *stream;
@ -235,6 +318,9 @@ int create_image(IsoImage *image, const char *image_path,
return ret;
}
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;
}
@ -249,9 +335,16 @@ int create_image(IsoImage *image, const char *image_path,
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) {
case ELTORITO_FLOPPY_EMUL:
switch (iso_stream_get_size(stream)) {
switch (size) {
case 1200 * 1024:
boot_media_type = 1; /* 1.2 meg diskette */
break;
@ -333,10 +426,15 @@ int create_image(IsoImage *image, const char *image_path,
boot->image = (IsoFile*)imgfile;
iso_node_ref(imgfile); /* get our ref */
boot->bootable = 1;
boot->seems_boot_info_table = 0;
boot->isolinux_options = 0;
boot->type = boot_media_type;
boot->load_size = load_sectors;
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) {
*bootimg = boot;
}
@ -349,7 +447,7 @@ int iso_image_set_boot_image(IsoImage *image, const char *image_path,
const char *catalog_path,
ElToritoBootImage **boot)
{
int ret;
int ret, i;
struct el_torito_boot_catalog *catalog;
ElToritoBootImage *boot_image= NULL;
IsoBoot *cat_node= NULL;
@ -384,6 +482,9 @@ int iso_image_set_boot_image(IsoImage *image, const char *image_path,
catname[0] = '\0';
ret = iso_tree_path_to_node(image, catdir, &p);
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);
return ret < 0 ? ret : ISO_NODE_DOESNT_EXIST;
}
@ -413,8 +514,12 @@ int iso_image_set_boot_image(IsoImage *image, const char *image_path,
ret = ISO_OUT_OF_MEM;
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->sort_weight = 1000; /* slightly high */
iso_node_ref((IsoNode*)cat_node);
image->bootcat = catalog;
@ -437,7 +542,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
* session or an existing image is bootable. It can also be useful to get
@ -481,10 +586,10 @@ int iso_image_get_boot_image(IsoImage *image, ElToritoBootImage **boot,
/* ok, image is bootable */
if (boot) {
*boot = image->bootcat->image;
*boot = image->bootcat->bootimages[0];
}
if (imgnode) {
*imgnode = image->bootcat->image->image;
*imgnode = image->bootcat->bootimages[0]->image;
}
if (catnode) {
*catnode = image->bootcat->node;
@ -492,6 +597,40 @@ int iso_image_get_boot_image(IsoImage *image, ElToritoBootImage **boot,
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.
*
@ -506,28 +645,82 @@ void iso_image_remove_boot_image(IsoImage *image)
return;
/*
* remove catalog node from its parent
* (the reference will be disposed next)
* remove catalog node from its parent and dispose it
* (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 */
el_torito_boot_catalog_free(image->bootcat);
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)
{
struct el_torito_boot_image *image;
int i;
if (cat == NULL) {
return;
}
image = cat->image;
iso_node_unref((IsoNode*)image->image);
free(image);
iso_node_unref((IsoNode*)cat->node);
for (i = 0; i < Libisofs_max_boot_imageS; i++) {
image = cat->bootimages[i];
if (image == NULL)
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);
}
@ -538,11 +731,12 @@ struct catalog_stream
{
Ecma119Image *target;
uint8_t buffer[BLOCK_SIZE];
int offset; /* -1 if stream is not openned */
int offset; /* -1 if stream is not opened */
};
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;
int checksum;
@ -550,10 +744,10 @@ write_validation_entry(uint8_t *buf)
struct el_torito_validation_entry *ve =
(struct el_torito_validation_entry*)buf;
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_byte2[0] = 0xAA;
/* calculate the checksum, to ensure sum of all words is 0 */
checksum = 0;
for (i = 0; i < sizeof(struct el_torito_validation_entry); i += 2) {
@ -562,35 +756,64 @@ write_validation_entry(uint8_t *buf)
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.
* 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
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_section_entry *se =
(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_media_type[0] = img->type;
iso_lsb(se->load_seg, img->load_seg, 2);
se->system_type[0] = img->partition_type;
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
int catalog_open(IsoStream *stream)
{
int i, j, k, num_entries;
struct catalog_stream *data;
uint8_t *wpt;
struct el_torito_boot_catalog *cat;
struct el_torito_boot_image **boots;
if (stream == NULL) {
return ISO_NULL_POINTER;
}
data = stream->data;
cat = data->target->catalog;
boots = cat->bootimages;
if (data->offset != -1) {
return ISO_FILE_ALREADY_OPENED;
@ -599,11 +822,36 @@ int catalog_open(IsoStream *stream)
memset(data->buffer, 0, BLOCK_SIZE);
/* 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_section_entry(data->buffer + 32, data->target);
/* write default entry = first boot image */
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;
return ISO_SUCCESS;
}
@ -708,7 +956,7 @@ int catalog_stream_new(Ecma119Image *target, IsoStream **stream)
return ISO_OUT_OF_MEM;
}
data = calloc(1, sizeof(struct catalog_stream));
if (str == NULL) {
if (data == NULL) {
free(str);
return ISO_OUT_OF_MEM;
}
@ -757,7 +1005,7 @@ int el_torito_catalog_file_src_create(Ecma119Image *target, IsoFileSrc **src)
file->checksum_index = 0;
file->nsections = 1;
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;
ret = iso_file_src_add(target, file, src);
@ -773,27 +1021,26 @@ int el_torito_catalog_file_src_create(Ecma119Image *target, IsoFileSrc **src)
/******************* EL-TORITO WRITER *******************************/
/**
* Patch an isolinux boot image.
* Insert boot info table content into buf.
*
* @return
* 1 on success, 0 error (but continue), < 0 error
*/
static
int patch_boot_image(uint8_t *buf, Ecma119Image *t, size_t imgsize)
int make_boot_info_table(uint8_t *buf, uint32_t pvd_lba,
uint32_t boot_lba, uint32_t imgsize)
{
struct boot_info_table *info;
uint32_t checksum;
size_t offset;
uint32_t offset;
if (imgsize < 64) {
return iso_msg_submit(t->image->id, ISO_ISOLINUX_CANT_PATCH, 0,
"Isolinux image too small. We won't patch it.");
}
info = (struct boot_info_table *) (buf + 8);
if (imgsize < 64)
return ISO_ISOLINUX_CANT_PATCH;
/* compute checksum, as the the sum of all 32 bit words in boot image
* from offset 64 */
checksum = 0;
offset = (size_t) 64;
offset = 64;
while (offset <= imgsize - 4) {
checksum += iso_read_lsb(buf + offset, 4);
@ -808,16 +1055,36 @@ int patch_boot_image(uint8_t *buf, Ecma119Image *t, size_t imgsize)
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));*/
iso_lsb(info->bi_pvd, t->ms_block + 16, 4);
iso_lsb(info->bi_file, t->bootimg->sections[0].block, 4);
iso_lsb(info->bi_pvd, pvd_lba, 4);
iso_lsb(info->bi_file, boot_lba, 4);
iso_lsb(info->bi_length, imgsize, 4);
iso_lsb(info->bi_csum, checksum, 4);
memset(buf + 24, 0, 40);
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
int eltorito_writer_compute_data_blocks(IsoImageWriter *writer)
{
@ -826,7 +1093,11 @@ int eltorito_writer_compute_data_blocks(IsoImageWriter *writer)
* this is a good place to do so.
*/
Ecma119Image *t;
int ret;
int ret, idx;
size_t size;
uint8_t *buf;
IsoStream *new = NULL;
IsoStream *original = NULL;
if (writer == NULL) {
return ISO_NULL_POINTER;
@ -834,19 +1105,23 @@ int eltorito_writer_compute_data_blocks(IsoImageWriter *writer)
t = writer->target;
if (t->catalog->image->isolinux_options & 0x01) {
/* we need to patch the image */
size_t size;
uint8_t *buf;
IsoStream *new = NULL;
IsoStream *original = t->bootimg->stream;
/* Patch the boot image info tables if indicated */
for (idx = 0; idx < t->catalog->num_bootimages; idx++) {
if (!(t->catalog->bootimages[idx]->isolinux_options & 0x01))
continue;
original = t->bootsrc[idx]->stream;
size = (size_t) iso_stream_get_size(original);
/* >>> BOOT ts B00428 :
check whether size is not too large for buffering */;
buf = calloc(1, size);
if (buf == NULL) {
return ISO_OUT_OF_MEM;
}
ret = iso_stream_open(original);
if (ret < 0) {
free(buf);
return ret;
}
ret = iso_stream_read(original, buf, size);
@ -856,7 +1131,7 @@ int eltorito_writer_compute_data_blocks(IsoImageWriter *writer)
}
/* ok, patch the read buffer */
ret = patch_boot_image(buf, t, size);
ret = patch_boot_image(buf, t, size, idx);
if (ret < 0) {
return ret;
}
@ -867,7 +1142,7 @@ int eltorito_writer_compute_data_blocks(IsoImageWriter *writer)
if (ret < 0) {
return ret;
}
t->bootimg->stream = new;
t->bootsrc[idx]->stream = new;
iso_stream_unref(original);
}
return ISO_SUCCESS;
@ -889,7 +1164,6 @@ int eltorito_writer_write_vol_desc(IsoImageWriter *writer)
t = writer->target;
cat = t->catalog;
iso_msg_debug(t->image->id, "Write El-Torito boot record");
memset(&vol, 0, sizeof(struct ecma119_boot_rec_vol_desc));
@ -897,8 +1171,8 @@ int eltorito_writer_write_vol_desc(IsoImageWriter *writer)
memcpy(vol.std_identifier, "CD001", 5);
vol.vol_desc_version[0] = 1;
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));
}
@ -918,7 +1192,7 @@ int eltorito_writer_free_data(IsoImageWriter *writer)
int eltorito_writer_create(Ecma119Image *target)
{
int ret;
int ret, idx;
IsoImageWriter *writer;
IsoFile *bootimg;
IsoFileSrc *src;
@ -949,16 +1223,19 @@ int eltorito_writer_create(Ecma119Image *target)
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 */
if (target->catalog->image->isolinux_options & 0x01) {
src->prev_img = 0;
for (idx = 0; idx < target->catalog->num_bootimages; idx++) {
bootimg = target->catalog->bootimages[idx]->image;
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 */

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2010 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -27,25 +28,45 @@ struct Iso_Boot
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 {
IsoBoot *node; /* node of the catalog */
struct el_torito_boot_image *image; /* default boot image */
int num_bootimages;
struct el_torito_boot_image *bootimages[Libisofs_max_boot_imageS];
/* [0]= default boot image */
/* Weight value for image sorting */
int sort_weight;
};
struct el_torito_boot_image {
IsoFile *image;
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
* 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 char type; /**< The type of image */
unsigned char partition_type; /**< type of partition for HD-emul images */
short load_seg; /**< Load segment for the initial boot image. */
short load_size; /**< Number of sectors to load. */
/* Byte 1 of Validation Entry or Section Header Entry:
0= 80x86, 1= PowerPC, 2= Mac, 0xef= EFI */
uint8_t platform_id;
uint8_t id_string[28];
uint8_t selection_crit[20];
};
/** El-Torito, 2.1 */
@ -75,8 +96,8 @@ struct el_torito_default_entry {
struct el_torito_section_header {
uint8_t header_indicator BP(1, 1);
uint8_t platform_id BP(2, 2);
uint8_t number BP(3, 4);
uint8_t character BP(5, 32);
uint8_t num_entries BP(3, 4);
uint8_t id_string BP(5, 32);
};
/** El-Torito, 2.4 */
@ -106,4 +127,14 @@ int el_torito_catalog_file_src_create(Ecma119Image *target, IsoFileSrc **src);
*/
int eltorito_writer_create(Ecma119Image *target);
/**
* Insert boot info table content into buf.
*
* @return
* 1 on success, 0 error (but continue), < 0 error
*/
int make_boot_info_table(uint8_t *buf, uint32_t pvd_lba,
uint32_t boot_lba, uint32_t imgsize);
#endif /* LIBISO_ELTORITO_H */

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* 2010 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -7,6 +8,11 @@
* See COPYING file for details.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include "libisofs.h"
#include "filesrc.h"
#include "node.h"
#include "util.h"
@ -14,16 +20,28 @@
#include "messages.h"
#include "image.h"
#include "stream.h"
#ifdef Libisofs_with_checksumS
#include "md5.h"
#endif /* Libisofs_with_checksumS */
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#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
@ -53,11 +71,8 @@ int iso_file_src_create(Ecma119Image *img, IsoFile *file, IsoFileSrc **src)
unsigned int fs_id;
dev_t dev_id;
ino_t ino_id;
#ifdef Libisofs_with_checksumS
int cret, no_md5= 0;
void *xipt = NULL;
#endif
if (img == NULL || file == NULL || src == NULL) {
return ISO_NULL_POINTER;
@ -103,9 +118,6 @@ int iso_file_src_create(Ecma119Image *img, IsoFile *file, IsoFileSrc **src)
/* insert the filesrc in the tree */
ret = iso_rbtree_insert(img->files, fsrc, (void**)src);
if (ret <= 0) {
#ifdef Libisofs_with_checksumS
if (ret == 0 && (*src)->checksum_index > 0) {
/* Duplicate file source was mapped to previously registered source
*/
@ -113,17 +125,12 @@ int iso_file_src_create(Ecma119Image *img, IsoFile *file, IsoFileSrc **src)
if (cret < 0)
ret = cret;
}
#endif /* Libisofs_with_checksumS */
free(fsrc->sections);
free(fsrc);
return ret;
}
iso_stream_ref(fsrc->stream);
#ifdef Libisofs_with_checksumS
if ((img->md5_file_checksums & 1) &&
file->from_old_session && img->appendable) {
ret = iso_node_get_xinfo((IsoNode *) file, checksum_md5_xinfo_func,
@ -149,8 +156,6 @@ int iso_file_src_create(Ecma119Image *img, IsoFile *file, IsoFileSrc **src)
return cret;
}
#endif /* Libisofs_with_checksumS */
return ISO_SUCCESS;
}
@ -261,7 +266,12 @@ int filesrc_writer_compute_data_blocks(IsoImageWriter *writer)
/*
* final section
*/
file->sections[extent].block = t->curblock + extent * (ISO_EXTENT_SIZE / BLOCK_SIZE);
if (section_size <= 0) {
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;
t->curblock += DIV_UP(iso_file_src_get_size(file), BLOCK_SIZE);
@ -304,21 +314,16 @@ int filesrc_read(IsoFileSrc *file, char *buf, size_t count)
return iso_stream_read_buffer(file->stream, buf, count, &got);
}
#ifdef Libisofs_with_checksumS
/* @return 1=ok, md5 is valid,
0= not ok, go on,
<0 fatal error, abort
*/
static
int filesrc_make_md5(Ecma119Image *t, IsoFileSrc *file, char md5[16], int flag)
{
return iso_stream_make_md5(file->stream, md5, 0);
}
#endif /* Libisofs_with_checksumS */
static
int filesrc_writer_write_data(IsoImageWriter *writer)
{
@ -331,14 +336,13 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
char buffer[BLOCK_SIZE];
off_t file_size;
uint32_t nblocks;
#ifdef Libisofs_with_checksumS
void *ctx= NULL;
char md5[16], pre_md5[16];
int pre_md5_valid = 0;
#ifdef Libisofs_with_libjtE
int jte_begun = 0;
#endif
if (writer == NULL) {
return ISO_ASSERT_FAILURE;
}
@ -353,17 +357,11 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
was_error = 0;
file_size = iso_file_src_get_size(file);
nblocks = DIV_UP(file_size, BLOCK_SIZE);
#ifdef Libisofs_with_checksumS
pre_md5_valid = 0;
if (file->checksum_index > 0 && (t->md5_file_checksums & 2)) {
/* Obtain an MD5 of content by a first read pass */
pre_md5_valid = filesrc_make_md5(t, file, pre_md5, 0);
}
#endif /* Libisofs_with_checksumS */
res = filesrc_open(file);
iso_stream_get_file_name(file->stream, name);
if (res < 0) {
@ -407,18 +405,29 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
}
#endif
#ifdef Libisofs_with_checksumS
#ifdef Libisofs_with_libjtE
if (t->libjte_handle != NULL) {
res = libjte_begin_data_file(t->libjte_handle, name,
BLOCK_SIZE, file_size);
if (res <= 0) {
res = iso_libjte_forward_msgs(t->libjte_handle, t->image->id,
ISO_LIBJTE_FILE_FAILED, 0);
if (res < 0) {
filesrc_close(file);
ret = ISO_LIBJTE_FILE_FAILED;
goto ex;
}
}
jte_begun = 1;
}
#endif /* Libisofs_with_libjtE */
if (file->checksum_index > 0) {
/* initialize file checksum */
res = iso_md5_start(&ctx);
if (res <= 0)
file->checksum_index = 0;
}
#endif /* Libisofs_with_checksumS */
/* write file contents to image */
for (b = 0; b < nblocks; ++b) {
int wres;
@ -434,9 +443,6 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
ret = wres;
goto ex;
}
#ifdef Libisofs_with_checksumS
if (file->checksum_index > 0) {
/* Add to file checksum */
if (file_size - b * BLOCK_SIZE > BLOCK_SIZE)
@ -447,9 +453,6 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
if (res <= 0)
file->checksum_index = 0;
}
#endif /* Libisofs_with_checksumS */
}
filesrc_close(file);
@ -484,9 +487,6 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
ret = res;
goto ex;
}
#ifdef Libisofs_with_checksumS
if (file->checksum_index > 0) {
/* Add to file checksum */
if (file_size - b * BLOCK_SIZE > BLOCK_SIZE)
@ -497,14 +497,8 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
if (res <= 0)
file->checksum_index = 0;
}
#endif /* Libisofs_with_checksumS */
}
}
#ifdef Libisofs_with_checksumS
if (file->checksum_index > 0 &&
file->checksum_index <= t->checksum_idx_counter) {
/* Obtain checksum and dispose checksum context */
@ -530,17 +524,33 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
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;
ex:;
#ifdef Libisofs_with_checksumS
if (ctx != NULL) /* avoid any memory leak */
iso_md5_end(&ctx, md5);
#endif
#ifdef Libisofs_with_libjtE
if (jte_begun) {
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;
}

View File

@ -18,14 +18,8 @@
struct Iso_File_Src
{
unsigned int prev_img :1; /**< if the file comes from a previous image */
#ifdef Libisofs_with_checksumS
unsigned int checksum_index :31;
#endif /* Libisofs_with_checksumS */
/** File Sections of the file in the image */
struct iso_file_section *sections;
int nsections;

View File

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

View File

@ -13,6 +13,10 @@
*
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include "../libisofs.h"
#include "../filter.h"
#include "../fsource.h"

View File

@ -17,6 +17,10 @@
*
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include "../libisofs.h"
#include "../filter.h"
#include "../fsource.h"

View File

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

View File

@ -14,6 +14,10 @@
*
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include "../libisofs.h"
#include "../filter.h"
#include "../fsource.h"
@ -826,6 +830,9 @@ int ziso_cmp_ino(IsoStream *s1, IsoStream *s2)
/* ------------------------------------------------------------------------- */
#ifdef Libisofs_with_zliB
static
void ziso_filter_free(FilterContext *filter)
{
@ -913,8 +920,6 @@ int ziso_filter_get_uncompressor(FilterContext *filter, IsoStream *original,
}
#ifdef Libisofs_with_zliB
/* Produce a parameter object suitable for iso_file_add_filter().
* It may be disposed by free() after all those calls are made.
*

View File

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

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 Thomas Schmitt
* Copyright (c) 2009 - 2010 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -13,6 +13,10 @@
* IsoDataSource to read image data.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include "libisofs.h"
#include "ecma119.h"
#include "messages.h"
@ -102,6 +106,12 @@ struct iso_read_opts
*/
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;
};
/**
@ -273,12 +283,20 @@ typedef struct
/* el-torito information */
unsigned int eltorito : 1; /* is el-torito available */
unsigned int bootable:1; /**< If the entry is bootable. */
unsigned char type; /**< The type of image */
unsigned char partition_type; /**< type of partition for HD-emul images */
short load_seg; /**< Load segment for the initial boot image. */
short load_size; /**< Number of sectors to load. */
uint32_t imgblock; /**< Block for El-Torito boot image */
int num_bootimgs;
unsigned char platform_ids[Libisofs_max_boot_imageS];
unsigned char id_strings[Libisofs_max_boot_imageS][28];
unsigned char selection_crits[Libisofs_max_boot_imageS][20];
unsigned char boot_flags[Libisofs_max_boot_imageS]; /* bit0= bootable */
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 */
/* Whether inode numbers from PX entries shall be discarded */
@ -375,9 +393,19 @@ char* ifs_get_path(IsoFileSource *src)
if (data->parent == NULL) {
return strdup("");
} else {
char *path = ifs_get_path(data->parent);
int pathlen = strlen(path);
path = realloc(path, pathlen + strlen(data->name) + 2);
char *path, *new_path;
int pathlen;
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 + 1] = '\0';
return strcat(path, data->name);
@ -2106,19 +2134,15 @@ int read_root_susp_entries(_ImageFsData *data, uint32_t block)
}
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;
struct ecma119_pri_vol_desc *pvm;
struct ecma119_dir_record *rootdr;
uint8_t buffer[BLOCK_SIZE];
/* read PVM */
ret = data->src->read_block(data->src, block, buffer);
if (ret < 0) {
ret = src->read_block(src, block, buffer);
if (ret < 0)
return ret;
}
pvm = (struct ecma119_pri_vol_desc *)buffer;
/* sanity checks */
@ -2128,8 +2152,24 @@ int read_pvm(_ImageFsData *data, uint32_t block)
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 */
pvm = (struct ecma119_pri_vol_desc *)buffer;
/* fill volume attributes */
/* TODO take care of input charset */
@ -2185,11 +2225,13 @@ int read_pvm(_ImageFsData *data, uint32_t block)
static
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_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];
data->num_bootimgs = 0;
ret = data->src->read_block(data->src, block, buffer);
if (ret < 0) {
return ret;
@ -2200,34 +2242,70 @@ int read_el_torito_boot_catalog(_ImageFsData *data, uint32_t block)
/* check if it is a valid catalog (TODO: check also the checksum)*/
if ( (ve->header_id[0] != 1) || (ve->key_byte1[0] != 0x55)
|| (ve->key_byte2[0] != 0xAA) ) {
return iso_msg_submit(data->msgid, ISO_WRONG_EL_TORITO, 0,
iso_msg_submit(data->msgid, ISO_WRONG_EL_TORITO, 0,
"Wrong or damaged El-Torito Catalog. El-Torito info "
"will be ignored.");
return ISO_WRONG_EL_TORITO;
}
/* check for a valid platform */
if (ve->platform_id[0] != 0) {
return iso_msg_submit(data->msgid, ISO_UNSUPPORTED_EL_TORITO, 0,
"Unsupported El-Torito platform. Only 80x86 is "
if (ve->platform_id[0] != 0 && ve->platform_id[0] != 0xef) {
iso_msg_submit(data->msgid, ISO_UNSUPPORTED_EL_TORITO, 0,
"Unsupported El-Torito platform. Only 80x86 and EFI are "
"supported. El-Torito info will be ignored.");
return ISO_UNSUPPORTED_EL_TORITO;
}
/* ok, once we are here we assume it is a valid catalog */
/* parse the default entry */
entry = (struct el_torito_default_entry *)(buffer + 32);
entry = (struct el_torito_section_entry *)(buffer + 32);
data->eltorito = 1;
data->bootable = entry->boot_indicator[0] ? 1 : 0;
data->type = entry->boot_media_type[0];
data->partition_type = entry->system_type[0];
data->load_seg = iso_read_lsb(entry->load_seg, 2);
data->load_size = iso_read_lsb(entry->sec_count, 2);
data->imgblock = iso_read_lsb(entry->block, 4);
/* TODO #00018 : check if there are more entries in the boot catalog */
/* The Default Entry is declared mandatory */
data->num_bootimgs = 1;
data->platform_ids[0] = ve->platform_id[0];
memcpy(data->id_strings[0], ve->id_string, 24);
memset(data->id_strings[0] + 24, 0, 4);
data->boot_flags[0] = entry->boot_indicator[0] ? 1 : 0;
data->media_types[0] = entry->boot_media_type[0];
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;
}
@ -2311,7 +2389,7 @@ ex:
int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
int msgid, IsoImageFilesystem **fs)
{
int ret;
int ret, i;
uint32_t block;
IsoImageFilesystem *ifs;
_ImageFsData *data;
@ -2350,9 +2428,13 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
data->md5_load = !opts->nomd5;
data->aaip_version = -1;
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->px_ino_status = 0;
data->local_charset = strdup(iso_get_local_charset(0));
if (data->local_charset == NULL) {
ret = ISO_OUT_OF_MEM;
@ -2371,9 +2453,6 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
ifs->free = ifs_fs_free;
/* read Volume Descriptors and ensure it is a valid image */
#ifdef Libisofs_with_checksumS
if (data->md5_load) {
/* From opts->block on : check for superblock and tree tags */;
ret = iso_src_check_sb_tree(src, opts->block, 0);
@ -2388,8 +2467,6 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
}
}
#endif /* Libisofs_with_checksumS */
/* 1. first, open the filesystem */
ifs_fs_open(ifs);
@ -2419,21 +2496,18 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
|| vol->vol_desc_version[0] != 1
|| strncmp((char*)vol->boot_sys_id,
"EL TORITO SPECIFICATION", 23)) {
ret = iso_msg_submit(data->msgid,
iso_msg_submit(data->msgid,
ISO_UNSUPPORTED_EL_TORITO, 0,
"Unsupported Boot Vol. Desc. Only El-Torito "
"Specification, Version 1.0 Volume "
"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;
}
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;
@ -2483,11 +2557,8 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
*/
break;
default:
ret = iso_msg_submit(data->msgid, ISO_UNSUPPORTED_VD, 0,
"Ignoring Volume descriptor %x.", buffer[0]);
if (ret < 0) {
goto fs_cleanup;
}
iso_msg_submit(data->msgid, ISO_UNSUPPORTED_VD, 0,
"Ignoring Volume descriptor %x.", buffer[0]);
break;
}
block++;
@ -2607,7 +2678,7 @@ static
int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
IsoFileSource *src, IsoNode **node)
{
int ret;
int ret, idx;
struct stat info;
IsoNode *new;
char *name;
@ -2719,11 +2790,25 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
new = (IsoNode*) file;
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 */
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,
"More than one image node has been found.");
"More than one ISO node has been found for the same boot image.");
if (ret < 0) {
free(name);
iso_stream_unref(stream);
@ -2731,7 +2816,7 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
}
} else {
/* and set the image node */
image->bootcat->image->image = file;
image->bootcat->bootimages[idx]->image = file;
new->refcount++;
}
}
@ -2871,7 +2956,7 @@ int iso_image_builder_new(IsoNodeBuilder *old, IsoNodeBuilder **builder)
* accessible from the ISO filesystem.
*/
static
int create_boot_img_filesrc(IsoImageFilesystem *fs, IsoImage *image,
int create_boot_img_filesrc(IsoImageFilesystem *fs, IsoImage *image, int idx,
IsoFileSource **src)
{
int ret;
@ -2928,8 +3013,7 @@ int create_boot_img_filesrc(IsoImageFilesystem *fs, IsoImage *image,
ifsdata->parent = NULL;
ifsdata->info = atts;
ifsdata->name = NULL;
ifsdata->sections[0].block = fsdata->imgblock;
ifsdata->sections[0].block = fsdata->bootblocks[idx];
ifsdata->sections[0].size = BLOCK_SIZE;
ifsdata->nsections = 1;
@ -2946,12 +3030,112 @@ boot_fs_cleanup: ;
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,
&section_count, &sections, 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,
struct iso_read_opts *opts,
IsoReadImageFeatures **features)
{
int ret, hflag;
int ret, hflag, i, idx;
IsoImageFilesystem *fs;
IsoFilesystem *fsback;
IsoNodeBuilder *blback;
@ -2959,9 +3143,9 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
IsoFileSource *newroot;
_ImageFsData *data;
struct el_torito_boot_catalog *oldbootcat;
#ifdef Libisofs_with_checksumS
int i;
uint8_t *rpt;
IsoFileSource *boot_src;
IsoNode *node;
uint32_t old_checksum_start_lba;
uint32_t old_checksum_end_lba;
uint32_t old_checksum_idx_count;
@ -2969,21 +3153,37 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
char checksum_type[81];
uint32_t checksum_size;
size_t size;
uint8_t *rpt;
void *ctx = NULL;
char md5[16];
#endif
if (image == NULL || src == NULL || opts == NULL) {
return ISO_NULL_POINTER;
}
ret = iso_image_filesystem_new(src, opts, image->id, &fs);
if (ret < 0) {
return ret;
}
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 */
ret = fs->get_root(fs, &newroot);
if (ret < 0) {
@ -2996,14 +3196,11 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
oldroot = image->root;
oldbootcat = image->bootcat; /* could be NULL */
image->bootcat = NULL;
#ifdef Libisofs_with_checksumS
old_checksum_start_lba = image->checksum_start_lba;
old_checksum_end_lba = image->checksum_end_lba;
old_checksum_idx_count = image->checksum_idx_count;
old_checksum_array = image->checksum_array;
image->checksum_array = NULL;
#endif
/* create new builder */
ret = iso_image_builder_new(blback, &image->builder);
@ -3048,23 +3245,34 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
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));
if (catalog == NULL) {
ret = ISO_OUT_OF_MEM;
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;
catalog->num_bootimages++;
}
for ( ; idx < Libisofs_max_boot_imageS; idx++)
catalog->bootimages[idx] = NULL;
image->bootcat = catalog;
}
@ -3098,21 +3306,23 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
}
if (data->eltorito) {
/* if catalog and image nodes were not filled, we create them here */
if (image->bootcat->image->image == NULL) {
IsoFileSource *src;
IsoNode *node;
ret = create_boot_img_filesrc(fs, image, &src);
/* if catalog and boot image nodes were not filled,
we create them here */
for (idx = 0; idx < image->bootcat->num_bootimages; idx++) {
if (image->bootcat->bootimages[idx]->image != NULL)
continue;
ret = create_boot_img_filesrc(fs, image, idx, &boot_src);
if (ret < 0) {
iso_node_builder_unref(image->builder);
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) {
iso_node_builder_unref(image->builder);
goto import_revert;
}
image->bootcat->image->image = (IsoFile*)node;
image->bootcat->bootimages[idx]->image = (IsoFile*)node;
/* warn about hidden images */
iso_msg_submit(image->id, ISO_EL_TORITO_HIDDEN, 0,
@ -3165,8 +3375,6 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
(*features)->size = data->nblocks;
}
#ifdef Libisofs_with_checksumS
if (data->md5_load) {
/* Read checksum array */
ret = iso_root_get_isofsca((IsoNode *) image->root,
@ -3219,7 +3427,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;
goto import_cleanup;
@ -3230,14 +3440,11 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
el_torito_boot_catalog_free(image->bootcat);
image->root = oldroot;
image->bootcat = oldbootcat;
#ifdef Libisofs_with_checksumS
old_checksum_start_lba = image->checksum_start_lba;
old_checksum_end_lba = image->checksum_end_lba;
old_checksum_idx_count = image->checksum_idx_count;
image->checksum_array = old_checksum_array;
old_checksum_array = NULL;
#endif
import_cleanup:;
@ -3248,14 +3455,10 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
iso_file_source_unref(newroot);
fs->close(fs);
iso_filesystem_unref(fs);
#ifdef Libisofs_with_checksumS
if (old_checksum_array != NULL)
free(old_checksum_array);
if (ctx != NULL)
iso_md5_end(&ctx, md5);
#endif
return ret;
}
@ -3332,8 +3535,9 @@ int iso_read_opts_new(IsoReadOpts **opts, int profile)
ropts->file_mode = 0444;
ropts->dir_mode = 0555;
ropts->noaaip= 1;
ropts->nomd5= 1;
ropts->noaaip = 1;
ropts->nomd5 = 1;
ropts->load_system_area = 0;
*opts = ropts;
return ISO_SUCCESS;
@ -3469,6 +3673,15 @@ int iso_read_opts_auto_input_charset(IsoReadOpts *opts, int mode)
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.
*/

View File

@ -12,6 +12,10 @@
* Filesystem/FileSource implementation to access the local filesystem.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include "fsource.h"
#include "util.h"
#include "aaip_0_2.h"
@ -58,9 +62,19 @@ char* lfs_get_path(IsoFileSource *src)
if (data->parent == src) {
return strdup("/");
} else {
char *path = lfs_get_path(data->parent);
int pathlen = strlen(path);
path = realloc(path, pathlen + strlen(data->name) + 2);
char *path, *new_path;
int pathlen;
path = lfs_get_path(data->parent);
if (path == NULL)
return NULL;
pathlen = strlen(path);
new_path = realloc(path, pathlen + strlen(data->name) + 2);
if (new_path == NULL) {
free(path);
return NULL;
}
path= new_path;
if (pathlen != 1) {
/* pathlen can only be 1 for root */
path[pathlen] = '/';

View File

@ -7,6 +7,10 @@
* See COPYING file for details.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include "fsource.h"
#include <stdlib.h>

View File

@ -8,6 +8,10 @@
* See COPYING file for details.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include "libisofs.h"
#include "image.h"
#include "node.h"
@ -32,7 +36,7 @@
*/
int iso_image_new(const char *name, IsoImage **image)
{
int res;
int res, i;
IsoImage *img;
if (image == NULL) {
@ -74,19 +78,21 @@ int iso_image_new(const char *name, IsoImage **image)
img->volset_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_ea = 1;
img->inode_counter = 0;
img->used_inodes = NULL;
img->used_inodes_start = 0;
#ifdef Libisofs_with_checksumS
img->checksum_start_lba = 0;
img->checksum_end_lba = 0;
img->checksum_idx_count = 0;
img->checksum_array = NULL;
#endif
img->generator_is_running = 0;
*image = img;
return ISO_SUCCESS;
}
@ -100,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
* their refcount reach 0 too, of course).
*/
@ -124,6 +130,7 @@ void iso_image_unref(IsoImage *image)
iso_node_builder_unref(image->builder);
iso_filesystem_unref(image->fs);
el_torito_boot_catalog_free(image->bootcat);
iso_image_give_up_mips_boot(image, 0);
free(image->volset_id);
free(image->volume_id);
free(image->publisher_id);
@ -143,17 +150,12 @@ void iso_image_unref(IsoImage *image)
int iso_image_free_checksums(IsoImage *image, int flag)
{
#ifdef Libisofs_with_checksumS
image->checksum_start_lba = 0;
image->checksum_end_lba = 0;
image->checksum_idx_count = 0;
if (image->checksum_array != NULL)
free(image->checksum_array);
image->checksum_array = NULL;
#endif /* Libisofs_with_checksumS */
return 1;
}
@ -173,13 +175,13 @@ int iso_image_free_checksums(IsoImage *image, int flag)
*/
int iso_image_attach_data(IsoImage *image, void *data, void (*give_up)(void*))
{
if (image == NULL || (data != NULL && free == NULL)) {
if (image == NULL) {
return ISO_NULL_POINTER;
}
if (image->user_data != NULL) {
/* free previously attached data */
if (image->user_data_free) {
if (image->user_data_free != NULL) {
image->user_data_free(image->user_data);
}
image->user_data = NULL;
@ -331,6 +333,16 @@ int iso_image_get_msg_id(IsoImage *image)
return image->id;
}
int iso_image_get_system_area(IsoImage *img, char system_area_data[32768],
int *options, int flag)
{
*options = img->system_area_options;
if (img->system_area_data == NULL)
return 0;
memcpy(system_area_data, img->system_area_data, 32768);
return 1;
}
static
int dir_update_size(IsoImage *image, IsoDir *dir)
{
@ -580,39 +592,66 @@ ex:;
int iso_image_get_session_md5(IsoImage *image, uint32_t *start_lba,
uint32_t *end_lba, char md5[16], int flag)
{
#ifdef Libisofs_with_checksumS
if (image->checksum_array == NULL || image->checksum_idx_count < 1)
return 0;
*start_lba = image->checksum_start_lba;
*end_lba = image->checksum_end_lba;
memcpy(md5, image->checksum_array, 16);
return ISO_SUCCESS;
#else
return 0;
#endif /* ! Libisofs_with_checksumS */
}
int iso_image_set_checksums(IsoImage *image, char *checksum_array,
uint32_t start_lba, uint32_t end_lba,
uint32_t idx_count, int flag)
{
#ifdef Libisofs_with_checksumS
iso_image_free_checksums(image, 0);
image->checksum_array = checksum_array;
image->checksum_start_lba = start_lba;
image->checksum_end_lba = end_lba;
image->checksum_idx_count = idx_count;
#endif /* Libisofs_with_checksumS */
return 1;
}
int iso_image_generator_is_running(IsoImage *image)
{
return image->generator_is_running;
}
/* API */
int iso_image_add_mips_boot_file(IsoImage *image, char *path, int flag)
{
if (image->num_mips_boot_files >= 15)
return ISO_BOOT_TOO_MANY_MIPS;
image->mips_boot_file_paths[image->num_mips_boot_files] = strdup(path);
if (image->mips_boot_file_paths[image->num_mips_boot_files] == NULL)
return ISO_OUT_OF_MEM;
image->num_mips_boot_files++;
return ISO_SUCCESS;
}
/* API */
int iso_image_get_mips_boot_files(IsoImage *image, char *paths[15], int flag)
{
int i;
for (i = 0; i < image->num_mips_boot_files; i++)
paths[i] = image->mips_boot_file_paths[i];
for (; i < 15; i++)
paths[i] = NULL;
return image->num_mips_boot_files;
}
/* API */
int iso_image_give_up_mips_boot(IsoImage *image, int flag)
{
int i;
for (i = 0; i < image->num_mips_boot_files; i++)
if (image->mips_boot_file_paths[i] != NULL) {
free(image->mips_boot_file_paths[i]);
image->mips_boot_file_paths[i] = NULL;
}
image->num_mips_boot_files = 0;
return ISO_SUCCESS;
}

View File

@ -53,6 +53,19 @@ struct Iso_Image
/* el-torito boot catalog */
struct el_torito_boot_catalog *bootcat;
/* Eventually loaded system area data, or NULL */
char *system_area_data;
/* Prescribed/detected options, see iso_write_opts_set_system_area() */
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 */
int id;
@ -149,8 +162,6 @@ struct Iso_Image
uint8_t *used_inodes;
ino_t used_inodes_start;
#ifdef Libisofs_with_checksumS
/**
* Array of MD5 checksums as announced by xattr "isofs.ca" of the
* root node. Array element 0 contains an overall image checksum for the
@ -163,7 +174,11 @@ struct Iso_Image
uint32_t checksum_idx_count;
char *checksum_array;
#endif /* Libisofs_with_checksumS */
/**
* Whether a write run has been started by iso_image_create_burn_source()
* and has not yet been finished.
*/
int generator_is_running;
};

View File

@ -7,6 +7,10 @@
* See COPYING file for details.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include "iso1999.h"
#include "messages.h"
#include "writer.h"
@ -712,7 +716,7 @@ void write_one_dir_record(Ecma119Image *t, Iso1999Node *node, int file_id,
iso_bb(rec->length, len, 4);
iso_datetime_7(rec->recording_time, t->now, t->always_gmt);
rec->flags[0] = ((node->type == ISO1999_DIR) ? 2 : 0) | (multi_extend ? 0x80 : 0);
iso_bb(rec->vol_seq_number, 1, 2);
iso_bb(rec->vol_seq_number, (uint32_t) 1, 2);
rec->len_fi[0] = len_fi;
}
@ -763,9 +767,9 @@ int iso1999_writer_write_vol_desc(IsoImageWriter *writer)
strncpy_pad((char*)vol.volume_id, vol_id, 32);
iso_bb(vol.vol_space_size, t->vol_space_size, 4);
iso_bb(vol.vol_set_size, 1, 2);
iso_bb(vol.vol_seq_number, 1, 2);
iso_bb(vol.block_size, BLOCK_SIZE, 2);
iso_bb(vol.vol_set_size, (uint32_t) 1, 2);
iso_bb(vol.vol_seq_number, (uint32_t) 1, 2);
iso_bb(vol.block_size, (uint32_t) BLOCK_SIZE, 2);
iso_bb(vol.path_table_size, t->iso1999_path_table_size, 4);
iso_lsb(vol.l_path_table_pos, t->iso1999_l_path_table_pos, 4);
iso_msb(vol.m_path_table_pos, t->iso1999_m_path_table_pos, 4);
@ -1024,6 +1028,7 @@ int iso1999_writer_create(Ecma119Image *target)
"Creating low level ISO 9660:1999 tree...");
ret = iso1999_tree_create(target);
if (ret < 0) {
free((char *) writer);
return ret;
}

View File

@ -8,6 +8,10 @@
* See COPYING file for details.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include "joliet.h"
#include "messages.h"
#include "writer.h"
@ -43,7 +47,7 @@ int get_joliet_name(Ecma119Image *t, IsoNode *iso, uint16_t **name)
if (iso->type == LIBISO_DIR) {
jname = iso_j_dir_id(ucs_name);
} else {
jname = iso_j_file_id(ucs_name);
jname = iso_j_file_id(ucs_name, !!(t->no_force_dots & 2));
}
free(ucs_name);
if (jname != NULL) {
@ -244,7 +248,7 @@ int create_tree(Ecma119Image *t, IsoNode *iso, JolietNode **tree, int pathlen)
char *ipath = iso_tree_get_node_path(iso);
ret = iso_msg_submit(t->image->id, ISO_FILE_IGNORED, 0,
"Can't add %s to Joliet tree. %s can only be added to a "
"Rock Ridget tree.", ipath, (iso->type == LIBISO_SYMLINK ?
"Rock Ridge tree.", ipath, (iso->type == LIBISO_SYMLINK ?
"Symlinks" : "Special files"));
free(ipath);
}
@ -552,17 +556,19 @@ int joliet_tree_create(Ecma119Image *t)
}
/* the Joliet tree is stored in Ecma119Image target */
t->joliet_root = root;
if (t->eff_partition_offset > 0) {
t->j_part_root = root;
} else {
t->joliet_root = root;
}
iso_msg_debug(t->image->id, "Sorting the Joliet tree...");
sort_tree(root);
iso_msg_debug(t->image->id, "Mangling Joliet names...");
ret = mangle_tree(t, t->joliet_root);
if (ret < 0) {
ret = mangle_tree(t, root);
if (ret < 0)
return ret;
}
return ISO_SUCCESS;
}
@ -574,7 +580,7 @@ size_t calc_dirent_len(Ecma119Image *t, JolietNode *n)
{
/* note than name len is always even, so we always need the pad byte */
int ret = n->name ? ucslen(n->name) * 2 + 34 : 34;
if (n->type == JOLIET_FILE && !t->omit_version_numbers) {
if (n->type == JOLIET_FILE && !(t->omit_version_numbers & 3)) {
/* take into account version numbers */
ret += 4;
}
@ -669,6 +675,7 @@ int joliet_writer_compute_data_blocks(IsoImageWriter *writer)
{
Ecma119Image *t;
uint32_t path_table_size;
size_t ndirs;
if (writer == NULL) {
return ISO_OUT_OF_MEM;
@ -692,6 +699,24 @@ int joliet_writer_compute_data_blocks(IsoImageWriter *writer)
t->curblock += DIV_UP(path_table_size, BLOCK_SIZE);
t->joliet_path_table_size = path_table_size;
if (t->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;
}
@ -722,7 +747,7 @@ void write_one_dir_record(Ecma119Image *t, JolietNode *node, int file_id,
memcpy(rec->file_id, name, len_fi);
if (node->type == JOLIET_FILE && !t->omit_version_numbers) {
if (node->type == JOLIET_FILE && !(t->omit_version_numbers & 3)) {
len_dr += 4;
rec->file_id[len_fi++] = 0;
rec->file_id[len_fi++] = ';';
@ -754,11 +779,11 @@ void write_one_dir_record(Ecma119Image *t, JolietNode *node, int file_id,
node = node->parent;
rec->len_dr[0] = len_dr;
iso_bb(rec->block, block, 4);
iso_bb(rec->block, block - t->eff_partition_offset, 4);
iso_bb(rec->length, len, 4);
iso_datetime_7(rec->recording_time, t->now, t->always_gmt);
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;
}
@ -790,7 +815,6 @@ void ucsncpy_pad(uint16_t *dest, const uint16_t *src, size_t max)
}
}
static
int joliet_writer_write_vol_desc(IsoImageWriter *writer)
{
IsoImage *image;
@ -831,16 +855,25 @@ int joliet_writer_write_vol_desc(IsoImageWriter *writer)
/* make use of UCS-2 Level 3 */
memcpy(vol.esc_sequences, "%/E", 3);
iso_bb(vol.vol_space_size, t->vol_space_size, 4);
iso_bb(vol.vol_set_size, 1, 2);
iso_bb(vol.vol_seq_number, 1, 2);
iso_bb(vol.block_size, BLOCK_SIZE, 2);
iso_bb(vol.vol_space_size, t->vol_space_size - t->eff_partition_offset,
4);
iso_bb(vol.vol_set_size, (uint32_t) 1, 2);
iso_bb(vol.vol_seq_number, (uint32_t) 1, 2);
iso_bb(vol.block_size, (uint32_t) BLOCK_SIZE, 2);
iso_bb(vol.path_table_size, t->joliet_path_table_size, 4);
iso_lsb(vol.l_path_table_pos, t->joliet_l_path_table_pos, 4);
iso_msb(vol.m_path_table_pos, t->joliet_m_path_table_pos, 4);
write_one_dir_record(t, t->joliet_root, 0, vol.root_dir_record, 1, 0);
if (t->eff_partition_offset > 0) {
/* Point to second tables and second root */
iso_lsb(vol.l_path_table_pos,
t->j_part_l_path_table_pos - t->eff_partition_offset, 4);
iso_msb(vol.m_path_table_pos,
t->j_part_m_path_table_pos - t->eff_partition_offset, 4);
write_one_dir_record(t, t->j_part_root, 0, vol.root_dir_record, 1, 0);
} else {
iso_lsb(vol.l_path_table_pos, t->joliet_l_path_table_pos, 4);
iso_msb(vol.m_path_table_pos, t->joliet_m_path_table_pos, 4);
write_one_dir_record(t, t->joliet_root, 0, vol.root_dir_record, 1, 0);
}
ucsncpy_pad((uint16_t*)vol.vol_set_id, volset_id, 128);
ucsncpy_pad((uint16_t*)vol.publisher_id, pub_id, 128);
@ -899,7 +932,7 @@ int write_one_dir(Ecma119Image *t, JolietNode *dir)
/* compute len of directory entry */
fi_len = ucslen(child->name) * 2;
len = fi_len + 34;
if (child->type == JOLIET_FILE && !t->omit_version_numbers) {
if (child->type == JOLIET_FILE && !(t->omit_version_numbers & 3)) {
len += 4;
}
@ -980,7 +1013,8 @@ int write_path_table(Ecma119Image *t, JolietNode **pathlist, int l_type)
rec = (struct ecma119_path_table_record*) buf;
rec->len_di[0] = dir->parent ? (uint8_t) ucslen(dir->name) * 2 : 1;
rec->len_xa[0] = 0;
write_int(rec->block, dir->info.dir->block, 4);
write_int(rec->block, dir->info.dir->block - t->eff_partition_offset,
4);
write_int(rec->parent, parent + 1, 2);
if (dir->parent) {
memcpy(rec->dir_id, dir->name, rec->len_di[0]);
@ -1019,7 +1053,12 @@ int write_path_tables(Ecma119Image *t)
if (pathlist == NULL) {
return ISO_OUT_OF_MEM;
}
pathlist[0] = t->joliet_root;
if (t->eff_partition_offset > 0) {
pathlist[0] = t->j_part_root;
} else {
pathlist[0] = t->joliet_root;
}
cur = 1;
for (i = 0; i < t->joliet_ndirs; i++) {
@ -1047,18 +1086,21 @@ int write_path_tables(Ecma119Image *t)
}
static
int joliet_writer_write_data(IsoImageWriter *writer)
int joliet_writer_write_dirs(IsoImageWriter *writer)
{
int ret;
Ecma119Image *t;
JolietNode *root;
if (writer == NULL) {
return ISO_NULL_POINTER;
}
t = writer->target;
/* first of all, we write the directory structure */
ret = write_dirs(t, t->joliet_root);
if (t->eff_partition_offset > 0) {
root = t->j_part_root;
} else {
root = t->joliet_root;
}
ret = write_dirs(t, root);
if (ret < 0) {
return ret;
}
@ -1069,12 +1111,40 @@ int joliet_writer_write_data(IsoImageWriter *writer)
return ret;
}
static
int joliet_writer_write_data(IsoImageWriter *writer)
{
int ret;
Ecma119Image *t;
if (writer == NULL) {
return ISO_NULL_POINTER;
}
t = writer->target;
ret = joliet_writer_write_dirs(writer);
if (ret < 0)
return ret;
if (t->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
int joliet_writer_free_data(IsoImageWriter *writer)
{
/* free the Joliet tree */
Ecma119Image *t = writer->target;
joliet_node_free(t->joliet_root);
if (t->j_part_root != NULL)
joliet_node_free(t->j_part_root);
t->j_part_root = NULL;
return ISO_SUCCESS;
}
@ -1098,12 +1168,23 @@ int joliet_writer_create(Ecma119Image *target)
iso_msg_debug(target->image->id, "Creating low level Joliet tree...");
ret = joliet_tree_create(target);
if (ret < 0) {
free((char *) writer);
return ret;
}
/* add this writer to image */
target->writers[target->nwriters++] = writer;
if(target->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 */
target->curblock++;
return ISO_SUCCESS;

View File

@ -54,4 +54,10 @@ struct joliet_node
*/
int joliet_writer_create(Ecma119Image *target);
/* Not to be called but only for comparison with target->writers[i]
*/
int joliet_writer_write_vol_desc(IsoImageWriter *writer);
#endif /* LIBISO_JOLIET_H */

View File

@ -5,6 +5,10 @@
provided under GPL version 2 or later
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

File diff suppressed because it is too large Load Diff

301
libisofs/libisofs.ver Normal file
View File

@ -0,0 +1,301 @@
LIBISOFS6 {
global:
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_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_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_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_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_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_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_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_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_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_will_cancel;
iso_zisofs_get_params;
iso_zisofs_get_refcounts;
iso_zisofs_set_params;
local: *;
};

View File

@ -1,3 +1,8 @@
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include <ctype.h>
#include <stdint.h>
#include <sys/types.h>
@ -10,6 +15,7 @@
/* for gettimeofday() */
#include <sys/time.h>
/* This code stems from syslinux-3.72/utils/isohybrid, a perl script
under GPL which is Copyright 2002-2008 H. Peter Anvin.
@ -25,13 +31,13 @@ and is now under the licenses to which H.Peter Anvin agreed:
or both, at your option.
Sincerely, H. Peter Anvin
In the context of xorriso-standalone, this code is under GPLv2 derived from
LGPL. In the context of libisofs this code derives its matching open source
In the context of GNU xorriso, this code is under GPLv3+ derived from LGPL.
In the context of libisofs this code derives its matching free software
license from above stem licenses, typically from LGPL.
In case its generosity is needed, here is the 2-clause BSD license:
make_isohybrid_mbr.c is copyright 2002-2008 H. Peter Anvin
and 2008-2009 libburnia project.
and 2008-2010 Thomas Schmitt
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
@ -51,8 +57,9 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* A helper function. One could replace it by one or two macros. */
static int lsb_to_buf(char **wpt, int value, int bits, int flag)
static int lsb_to_buf(char **wpt, uint32_t value, int bits, int flag)
{
int b;
@ -61,6 +68,11 @@ static int lsb_to_buf(char **wpt, int value, int bits, int flag)
return (1);
}
/* ====================================================================== */
/* Deprecated Function */
/* ====================================================================== */
/*
* Create a MBR for an isohybrid enabled ISOLINUX boot image.
*
@ -228,3 +240,214 @@ int make_isohybrid_mbr(int bin_lba, int *img_blocks, char *mbr, int flag)
return (1);
}
/* ====================================================================== */
/* The New MBR Producer */
/* ====================================================================== */
/* The new MBR producer for isohybrid is a slightly generalized version of
the deprecated function make_isohybrid_mbr(). It complies to the urge
of H.Peter Anvin not to hardcode MBR templates but rather to read a
file from the Syslinux tree, and to patch it as was done with the old
MBR producer.
The old algorithm was clarified publicly by the following mail.
Changes towards the old algorithm:
- 512-byte LBA of boot image is extended to 64 bit (we stay with 32)
- check for a magic number is now gone
The new implementation tries to use similar terms as the mail in order
to facilitate its future discussion with Syslinux developers.
From hpa@zytor.com Thu Apr 1 08:32:52 2010
Date: Wed, 31 Mar 2010 14:53:51 -0700
From: H. Peter Anvin <hpa@zytor.com>
To: For discussion of Syslinux and tftp-hpa <syslinux@zytor.com>
Cc: Thomas Schmitt <scdbackup@gmx.net>
Subject: Re: [syslinux] port syslinux isohybrid perl script to C
[...]
[me:]
> Currently i lack of blob and prescriptions.
The blobs are available in the Syslinux build tree under the names:
mbr/isohdp[fp]x*.bin
The default probably should be mbr/isohdppx.bin, but it's ultimately up
to the user.
User definable parameters:
-> MBR ID (default random 32-bit number,
or preserved from previous instance)
-> Sector count (default 32, range 1-63)
-> Head count (default 64, range 1-256)
-> Partition offset (default 0, range 0-64)
-> Partition number (default 1, range 1-4)
-> Filesystem type (default 0x17, range 1-255)
Note: the filesystem type is largely arbitrary, in theory it can be any
value other than 0x00, 0x05, 0x0f, 0x85, 0xee, or 0xef. 0x17 ("Windows
IFS Hidden") seems safeish, some people believe 0x83 (Linux) is better.
Here is the prescriptions for how to install it:
All numbers are littleendian. "word" means 16 bits, "dword" means 32
bits, "qword" means 64 bits.
Common subroutine LBA_to_CHS():
s = (lba % sector_count) + 1
t = (lba / sector_count)
h = (t % head_count)
c = (t / head_count)
if (c >= 1024):
c = 1023
h = head_count
s = sector_count
s = s | ((c & 0x300) >> 2)
c = c & 0xff
write byte h
write byte s
write byte c
Main:
Pad image_size to a multiple of sector_count*head_count
Use the input file unmodified for bytes 0..431
write qword boot_lba # Offset 432
write dword mbr_id # Offset 440
write word 0 # Offset 444
# Offset 446
For each partition entry 1..4:
if this_partition != partition_number:
write 16 zero bytes
else:
write byte 0x80
write LBA_to_CHS(partition_offset)
write byte filesystem_type
write LBA_to_CHS(image_size-1)
write dword partition_offset
write dword image_size
# Offset 510
write word 0xaa55
Use the input file unmodified for bytes 512..32767
(pad with zero as necessary)
[...]
-hpa
*/
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 spc, 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;
/* Pad image_size to a multiple of sector_count*head_count
*/
spc = head_count * sector_count;
hd_img_blocks = ((off_t) *img_blocks) * (off_t) 4;
if (hd_img_blocks % spc) {
hd_img_blocks += spc - (hd_img_blocks % spc);
*img_blocks = hd_img_blocks / 4 + !!(hd_img_blocks % 4);
}
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);
}

View File

@ -8,6 +8,10 @@
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
@ -430,8 +434,6 @@ int checksum_md5_xinfo_func(void *data, int flag)
/* MD5 checksum image writer */
#ifdef Libisofs_with_checksumS
/*
@flag bit0= recursion
bit1= session will be appended to an existing image
@ -508,15 +510,10 @@ int checksum_copy_old_nodes(Ecma119Image *target, IsoNode *node, int flag)
return ISO_SUCCESS;
}
#endif /* Libisofs_with_checksumS */
static
int checksum_writer_compute_data_blocks(IsoImageWriter *writer)
{
#ifdef Libisofs_with_checksumS
size_t size;
Ecma119Image *t;
int ret;
@ -557,9 +554,6 @@ int checksum_writer_compute_data_blocks(IsoImageWriter *writer)
t->checksum_idx_counter + 2, 16, "MD5", 0);
if (ret < 0)
return ret;
#endif /* Libisofs_with_checksumS */
return ISO_SUCCESS;
}
@ -580,9 +574,6 @@ int checksum_writer_write_vol_desc(IsoImageWriter *writer)
static
int checksum_writer_write_data(IsoImageWriter *writer)
{
#ifdef Libisofs_with_checksumS
int wres, res;
size_t i, size;
Ecma119Image *t;
@ -649,12 +640,6 @@ ex:;
if (ctx != NULL)
iso_md5_end(&ctx, md5);
return(res);
#else /* Libisofs_with_checksumS */
return ISO_SUCCESS;
#endif /* ! Libisofs_with_checksumS */
}
@ -684,17 +669,11 @@ int checksum_writer_create(Ecma119Image *target)
/* add this writer to image */
target->writers[target->nwriters++] = writer;
#ifdef Libisofs_with_checksumS
/* Account for superblock checksum tag */
if (target->md5_session_checksum) {
target->checksum_sb_tag_pos = target->curblock;
target->curblock++;
}
#endif /* Libisofs_with_checksumS */
return ISO_SUCCESS;
}
@ -702,9 +681,6 @@ int checksum_writer_create(Ecma119Image *target)
static
int iso_md5_write_scdbackup_tag(Ecma119Image *t, char *tag_block, int flag)
{
#ifdef Libisofs_with_checksumS
void *ctx = NULL;
off_t pos = 0, line_start;
int record_len, block_len, res, i;
@ -753,12 +729,6 @@ ex:;
if (ctx != NULL)
iso_md5_end(&ctx, md5);
return res;
#else
return ISO_SUCCESS;
#endif /* Libisofs_with_checksumS */
}
@ -772,9 +742,6 @@ ex:;
*/
int iso_md5_write_tag(Ecma119Image *t, int flag)
{
#ifdef Libisofs_with_checksumS
int res, mode, l, i, wres, tag_id_len;
void *ctx = NULL;
char md5[16], tag_block[2048], *tag_id;
@ -863,13 +830,6 @@ ex:;
if (ctx != NULL)
iso_md5_end(&ctx, md5);
return res;
#else /* Libisofs_with_checksumS */
return ISO_SUCCESS;
#endif /* ! Libisofs_with_checksumS */
}

View File

@ -6,12 +6,31 @@
* or later as published by the Free Software Foundation.
* See COPYING file for details.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#ifdef Xorriso_standalonE
#ifdef Xorriso_with_libjtE
#include "../libjte/libjte.h"
#endif
#else
#ifdef Libisofs_with_libjtE
#include <libjte/libjte.h>
#endif
#endif /* ! Xorriso_standalonE */
#include "libiso_msgs.h"
#include "libisofs.h"
#include "messages.h"
@ -66,6 +85,41 @@ struct libiso_msgs *libiso_msgr = NULL;
int iso_init_with_flag(int flag)
{
#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)) {
iso_init_locale(0);
}
@ -153,6 +207,8 @@ const char *iso_error_to_msg(int errcode)
return "Try to set the boot image of an already bootable image";
case ISO_BOOT_IMAGE_NOT_VALID:
return "Trying to use an invalid file as boot image";
case ISO_BOOT_IMAGE_OVERFLOW:
return "Too many boot images added";
case ISO_FILE_ERROR:
return "Error on file operation";
case ISO_FILE_ALREADY_OPENED:
@ -277,6 +333,34 @@ const char *iso_error_to_msg(int errcode)
return "Detected file content changes while it was written into the image";
case ISO_SCDBACKUP_TAG_NOT_0:
return "Session does not start at LBA 0. scdbackup checksum tag not written.";
case ISO_BOOT_NO_CATALOG:
return "No boot catalog created yet";
case ISO_OVWRT_MS_TOO_SMALL:
return "Multi-session offset too small for overwrite buffer";
case ISO_PART_OFFST_TOO_SMALL:
return "Partition offset too small for first tree root.";
case ISO_OVWRT_FIFO_TOO_SMALL:
return "The ring buffer is too small for overwrite buffer";
case ISO_LIBJTE_NOT_ENABLED:
return "Use of libjte was not enabled at compile time";
case ISO_LIBJTE_START_FAILED:
return "Failed to start up Jigdo Template Extraction";
case ISO_LIBJTE_END_FAILED:
return "Failed to finish Jigdo Template Extraction";
case ISO_LIBJTE_FILE_FAILED:
return "Failed to process file for Jigdo Template Extraction";
case ISO_BOOT_TOO_MANY_MIPS:
return "Too many MIPS Big Endian boot files given (max. 15)";
case ISO_BOOT_FILE_MISSING:
return "Boot file missing in image";
case ISO_BAD_PARTITION_NO:
return "Partition number out of range";
case ISO_BAD_PARTITION_FILE:
return "Cannot open data file for appended partition";
case ISO_NON_MBR_SYS_AREA:
return "May not combine appended partition with non-MBR system area";
case ISO_DISPLACE_ROLLOVER:
return "Displacement offset leads outside 32 bit range";
default:
return "Unknown error";
}
@ -417,8 +501,6 @@ int iso_obtain_msgs(char *minimum_severity, int *error_code, int *imgid,
}
/* ts A80222 : derived from libburn/init.c:burn_msgs_submit()
*/
int iso_msgs_submit(int error_code, char msg_text[], int os_errno,
char severity[], int origin)
{
@ -446,8 +528,6 @@ int iso_msgs_submit(int error_code, char msg_text[], int os_errno,
}
/* ts A80222 : derived from libburn/init.c:burn_text_to_sev()
*/
int iso_text_to_sev(char *severity_name, int *sevno)
{
int ret;
@ -459,8 +539,6 @@ int iso_text_to_sev(char *severity_name, int *sevno)
}
/* ts A80222 : derived from libburn/init.c:burn_sev_to_text()
*/
int iso_sev_to_text(int severity_number, char **severity_name)
{
int ret;
@ -499,7 +577,6 @@ int iso_error_get_code(int e)
}
/* ts A80222 */
int iso_report_errfile(char *path, int error_code, int os_errno, int flag)
{
libiso_msgs_submit(libiso_msgr, 0, error_code,
@ -507,3 +584,33 @@ int iso_report_errfile(char *path, int error_code, int os_errno, int flag)
path, os_errno, 0);
return(1);
}
int iso_libjte_forward_msgs(void *libjte_handle,
int imgid, int errcode, int flag)
{
#ifdef Libisofs_with_libjtE
char *msg = NULL;
int res;
struct libjte_env *handle = (struct libjte_env *) libjte_handle;
res = ISO_SUCCESS;
while(1) {
msg= libjte_get_next_message(handle);
if(msg == NULL)
break;
res = iso_msg_submit(imgid, errcode, 0, msg);
free(msg);
}
return res;
#else /* Libisofs_with_libjtE */
return ISO_SUCCESS;
#endif /* ! Libisofs_with_libjtE */
}

View File

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

View File

@ -8,6 +8,10 @@
* See COPYING file for details.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include "libisofs.h"
#include "image.h"
#include "node.h"
@ -428,6 +432,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
* the node, so you don't need to free it, it will be automatically freed
@ -1284,6 +1294,7 @@ int iso_node_new_file(char *name, IsoStream *stream, IsoFile **file)
new->node.type = LIBISO_FILE;
new->node.name = name;
new->node.mode = S_IFREG;
new->sort_weight = 0;
new->stream = stream;
*file = new;
@ -2659,9 +2670,6 @@ ex:;
/* API */
int iso_file_get_md5(IsoImage *image, IsoFile *file, char md5[16], int flag)
{
#ifdef Libisofs_with_checksumS
int ret, i;
size_t value_len;
char *value = NULL;
@ -2701,21 +2709,12 @@ ex:;
if (value != NULL)
free(value);
return ret;
#else
return 0;
#endif /* ! Libisofs_with_checksumS */
}
/* API */
int iso_file_make_md5(IsoFile *file, int flag)
{
#ifdef Libisofs_with_checksumS
int ret, dig = 0;
char *md5 = NULL;
@ -2736,13 +2735,6 @@ int iso_file_make_md5(IsoFile *file, int flag)
ret = 1;
ex:;
return ret;
#else
return ISO_ERROR;
#endif /* ! Libisofs_with_checksumS */
}

View File

@ -9,6 +9,10 @@
* See COPYING file for details.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include "rockridge.h"
#include "node.h"
#include "ecma119_tree.h"
@ -109,12 +113,12 @@ int rrip_add_PX(Ecma119Image *t, Ecma119Node *n, struct susp_info *susp)
PX[2] = 36;
}
PX[3] = 1;
iso_bb(&PX[4], px_get_mode(t, n), 4);
iso_bb(&PX[12], n->nlink, 4);
iso_bb(&PX[20], px_get_uid(t, n), 4);
iso_bb(&PX[28], px_get_gid(t, n), 4);
iso_bb(&PX[4], (uint32_t) px_get_mode(t, n), 4);
iso_bb(&PX[12], (uint32_t) n->nlink, 4);
iso_bb(&PX[20], (uint32_t) px_get_uid(t, n), 4);
iso_bb(&PX[28], (uint32_t) px_get_gid(t, n), 4);
if (t->rrip_1_10_px_ino || !t->rrip_version_1_10) {
iso_bb(&PX[36], n->ino, 4);
iso_bb(&PX[36], (uint32_t) n->ino, 4);
}
return susp_append(t, susp, PX);
@ -180,7 +184,8 @@ int rrip_add_PL(Ecma119Image *t, Ecma119Node *n, struct susp_info *susp)
PL[3] = 1;
/* 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);
}
@ -243,10 +248,10 @@ int rrip_add_PN(Ecma119Image *t, Ecma119Node *n, struct susp_info *susp)
*/
if (sizeof(node->dev) > 4) {
high_shift = 32;
iso_bb(&PN[4], node->dev >> high_shift, 4);
iso_bb(&PN[4], (uint32_t) (node->dev >> high_shift), 4);
} else
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);
}
@ -273,7 +278,8 @@ int rrip_add_CL(Ecma119Image *t, Ecma119Node *n, struct susp_info *susp)
CL[1] = 'L';
CL[2] = 12;
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);
}
@ -693,9 +699,10 @@ int susp_add_CE(Ecma119Image *t, size_t ce_len, struct susp_info *susp)
CE[1] = 'E';
CE[2] = 28;
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[20], ce_len, 4);
iso_bb(&CE[20], (uint32_t) ce_len, 4);
return susp_append(t, susp, CE);
}

View File

@ -13,6 +13,10 @@
* Rock Ridge and AAIP extensions on an ECMA-119 image.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include "libisofs.h"
#include "ecma119.h"
#include "util.h"

View File

@ -8,6 +8,10 @@
* See COPYING file for details.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include "libisofs.h"
#include "stream.h"
#include "fsource.h"
@ -582,7 +586,7 @@ int iso_memory_stream_new(unsigned char *buf, size_t size, IsoStream **stream)
return ISO_OUT_OF_MEM;
}
data = malloc(sizeof(MemStreamData));
if (str == NULL) {
if (data == NULL) {
free(str);
return ISO_OUT_OF_MEM;
}
@ -864,9 +868,6 @@ int iso_stream_read_buffer(IsoStream *stream, char *buf, size_t count,
return 1;
}
#ifdef Libisofs_with_checksumS
/* @param flag bit0= dig out most original stream (e.g. because from old image)
@return 1=ok, md5 is valid,
0= not ok,
@ -923,6 +924,3 @@ ex:;
iso_md5_end(&ctx, md5);
return res;
}
#endif /* Libisofs_with_checksumS */

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2008 Vreixo Formoso
* Copyright (c) 2010 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -7,33 +8,688 @@
* See COPYING file for details.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include "libisofs.h"
#include "system_area.h"
#include "eltorito.h"
#include "filesrc.h"
#include "ecma119_tree.h"
#include "image.h"
#include "messages.h"
#include "ecma119.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.
*
* It is assumed that the caller has verified the readiness of the boot image
* 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
* See libisofs/make_isohybrid_mbr.c
* Deprecated.
*/
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 %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 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)) {
return ISO_NULL_POINTER;
}
@ -41,26 +697,115 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
/* set buf to 0s */
memset(buf, 0, 16 * BLOCK_SIZE);
if (t->catalog != NULL && t->catalog->image->isolinux_options & 0x02) {
/* We need to write a MBR for an hybrid image */
int ret;
int img_blocks;
sa_type = (t->system_area_options >> 2) & 0x3f;
if (sa_type == 3) {
first_partition = 2;
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;
ret = make_isohybrid_mbr(t->bootimg->sections[0].block, &img_blocks, (char*)buf, 0);
/*
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
*/
img_blocks = t->curblock;
if (t->system_area_data != NULL) {
/* Write more or less opaque boot image */
memcpy(buf, t->system_area_data, 16 * BLOCK_SIZE);
} 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) {
/* error, it should never happen */
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;
}

View File

@ -46,4 +46,16 @@ int make_isohybrid_mbr(int bin_lba, int *img_blocks, char *mbr, int flag);
*/
int iso_write_system_area(Ecma119Image *t, uint8_t *buf);
/**
* 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_ */

View File

@ -11,6 +11,10 @@
* Functions that act on the iso tree.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include "libisofs.h"
#include "node.h"
#include "image.h"

View File

@ -9,6 +9,10 @@
* See COPYING file for details.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include "util.h"
#include "libisofs.h"
#include "messages.h"
@ -908,7 +912,10 @@ ex:;
return retval;
}
uint16_t *iso_j_file_id(const uint16_t *src)
/*
bit0= no_force_dots
*/
uint16_t *iso_j_file_id(const uint16_t *src, int flag)
{
uint16_t *dot;
size_t lname, lext, lnname, lnext, pos, i;
@ -954,6 +961,10 @@ uint16_t *iso_j_file_id(const uint16_t *src)
pos++;
}
}
if ((flag & 1) && lnext <= 0)
goto is_done;
set_ucsbe(dest + pos, '.');
pos++;
@ -967,6 +978,8 @@ uint16_t *iso_j_file_id(const uint16_t *src)
pos++;
}
}
is_done:;
set_ucsbe(dest + pos, '\0');
return ucsdup(dest);
}
@ -1206,7 +1219,7 @@ void iso_datetime_7(unsigned char *buf, time_t t, int always_gmt)
}
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);
#ifdef HAVE_TM_GMTOFF
@ -1250,7 +1263,7 @@ void iso_datetime_17(unsigned char *buf, time_t t, int always_gmt)
}
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);

View File

@ -151,11 +151,12 @@ char *iso_r_fileid(const char *src, size_t len, int relaxed, int forcedot);
* 2 bytes and the resulting string is NULL-terminated by a 2-byte NULL.
*
* Note that version number and (;1) is not appended.
*
* @param flag
* bit0= no_force_dots
* @return
* NULL if the original name and extension both are of length 0.
*/
uint16_t *iso_j_file_id(const uint16_t *src);
uint16_t *iso_j_file_id(const uint16_t *src, int flag);
/**
* Create a Joliet directory identifier that consists of name and optionally

View File

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

View File

@ -7,6 +7,10 @@
* See COPYING file for details.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include "util.h"
#include "libisofs.h"
@ -281,7 +285,7 @@ void ** iso_rbtree_to_array(IsoRBTree *tree, int (*include_item)(void *),
size_t *size)
{
size_t pos;
void **array;
void **array, **new_array;
array = malloc((tree->size + 1) * sizeof(void*));
if (array == NULL) {
@ -292,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);
array[pos] = NULL;
array = realloc(array, (pos + 1) * sizeof(void*));
new_array = realloc(array, (pos + 1) * sizeof(void*));
if (new_array == NULL) {
free((char *) array);
return NULL;
}
array= new_array;
if (size) {
*size = pos;
}