Compare commits

..

27 Commits

Author SHA1 Message Date
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
31 changed files with 1853 additions and 336 deletions

101
README
View File

@ -7,6 +7,39 @@ 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
See INSTALL file for further details.
------------------------------------------------------------------------------
libisofs is a library to create an ISO-9660 filesystem, supports extensions
@ -23,7 +56,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 +100,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,12 +112,12 @@ 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.
- ECMA-119 Extended attributes.
- Non El-Torito boot info.
- ...
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.
@ -93,16 +127,19 @@ b) Bootable El-Torito images may have several problems, that result in a new
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.
isolinux images need to have hardcoded the root dir lba in their boot
information table.
libisofs makes an educated guess at load time whether a boot image
contains such a table. Its outcome can be inquired by call
el_torito_seems_boot_info_table().
If one knows to have isolinux or GRUB El-Torito-bootable images, or if
a boot information table seems to exist, it is advised to apply the
el_torito_patch_isolinux_image() function.
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 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 +150,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

@ -50,8 +50,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 +66,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 +87,50 @@ 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 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.32], [http://libburnia-project.org])
AC_PREREQ([2.50])
dnl AC_CONFIG_HEADER([config.h])
@ -46,7 +46,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=32
LIBISOFS_VERSION=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION.$LIBISOFS_MICRO_VERSION
AC_SUBST(LIBISOFS_MAJOR_VERSION)
@ -56,10 +56,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.05.03 development jump has not yet happened
# SONAME = 34 - 28 = 6 . Library name = libisofs.6.28.0
LT_CURRENT=34
LT_AGE=28
LT_REVISION=0
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
@ -91,6 +91,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)

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

@ -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,7 +11,7 @@
To be included by aaip_0_2.c
Copyright (c) 2009 Thomas Schmitt, libburnia project, GPLv2
Copyright (c) 2009 Thomas Schmitt, libburnia project, GPLv2+
*/

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

View File

@ -7,7 +7,7 @@
To be included by aaip_0_2.c
Copyright (c) 2009 Thomas Schmitt, libburnia project, GPLv2
Copyright (c) 2009 Thomas Schmitt, libburnia project, GPLv2+
*/

View File

@ -7,7 +7,7 @@
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+
*/
@ -567,7 +567,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

@ -20,7 +20,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 +100,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 +217,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 +230,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

@ -1,7 +1,7 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2007 Mario Danic
* 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
@ -72,6 +72,10 @@ void ecma119_image_free(Ecma119Image *t)
free(t->input_charset);
if (t->output_charset != NULL)
free(t->output_charset);
if (t->bootsrc != NULL)
free(t->bootsrc);
if (t->system_area_data != NULL)
free(t->system_area_data);
#ifdef Libisofs_with_checksumS
if (t->checksum_ctx != NULL) { /* dispose checksum context */
@ -93,7 +97,7 @@ void ecma119_image_free(Ecma119Image *t)
static
int need_version_number(Ecma119Image *t, Ecma119Node *n)
{
if (t->omit_version_numbers) {
if (t->omit_version_numbers & 1) {
return 0;
}
if (n->type == ECMA119_DIR || n->type == ECMA119_PLACEHOLDER) {
@ -339,7 +343,7 @@ void write_one_dir_record(Ecma119Image *t, Ecma119Node *node, int file_id,
iso_datetime_7(rec->recording_time, t->now, t->always_gmt);
}
rec->flags[0] = ((node->type == ECMA119_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;
/*
@ -380,7 +384,7 @@ int ecma119_writer_write_vol_desc(IsoImageWriter *writer)
IsoImage *image;
Ecma119Image *t;
struct ecma119_pri_vol_desc vol;
int i;
char *vol_id, *pub_id, *data_id, *volset_id;
char *system_id, *application_id, *copyright_file_id;
char *abstract_file_id, *biblio_file_id;
@ -417,9 +421,9 @@ int ecma119_writer_write_vol_desc(IsoImageWriter *writer)
strncpy_pad((char*)vol.system_id, system_id, 32);
strncpy_pad((char*)vol.volume_id, vol_id, 32);
iso_bb(vol.vol_space_size, t->vol_space_size, 4);
iso_bb(vol.vol_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->path_table_size, 4);
iso_lsb(vol.l_path_table_pos, t->l_path_table_pos, 4);
iso_msb(vol.m_path_table_pos, t->m_path_table_pos, 4);
@ -435,9 +439,44 @@ int ecma119_writer_write_vol_desc(IsoImageWriter *writer)
strncpy_pad((char*)vol.abstract_file_id, abstract_file_id, 37);
strncpy_pad((char*)vol.bibliographic_file_id, biblio_file_id, 37);
iso_datetime_17(vol.vol_creation_time, t->now, t->always_gmt);
iso_datetime_17(vol.vol_modification_time, t->now, t->always_gmt);
iso_datetime_17(vol.vol_effective_time, t->now, t->always_gmt);
if (t->vol_uuid[0]) {
for(i = 0; i < 16; i++)
if(t->vol_uuid[i] < '0' || t->vol_uuid[i] > '9')
break;
else
vol.vol_creation_time[i] = t->vol_uuid[i];
for(; i < 16; i++)
vol.vol_creation_time[i] = '1';
vol.vol_creation_time[16] = 0;
} else if (t->vol_creation_time > 0)
iso_datetime_17(vol.vol_creation_time, t->vol_creation_time,
t->always_gmt);
else
iso_datetime_17(vol.vol_creation_time, t->now, t->always_gmt);
if (t->vol_uuid[0]) {
for(i = 0; i < 16; i++)
if(t->vol_uuid[i] < '0' || t->vol_uuid[i] > '9')
break;
else
vol.vol_modification_time[i] = t->vol_uuid[i];
for(; i < 16; i++)
vol.vol_modification_time[i] = '1';
vol.vol_modification_time[16] = 0;
} else if (t->vol_modification_time > 0)
iso_datetime_17(vol.vol_modification_time, t->vol_modification_time,
t->always_gmt);
else
iso_datetime_17(vol.vol_modification_time, t->now, t->always_gmt);
if (t->vol_expiration_time > 0)
iso_datetime_17(vol.vol_expiration_time, t->vol_expiration_time,
t->always_gmt);
if (t->vol_effective_time > 0)
iso_datetime_17(vol.vol_effective_time, t->vol_effective_time,
t->always_gmt);
vol.file_structure_version[0] = 1;
free(vol_id);
@ -1065,7 +1104,9 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
{
int ret, i, voldesc_size, nwriters, image_checksums_mad = 0, tag_pos;
Ecma119Image *target;
int el_torito_writer_index = -1, file_src_writer_index= -1;
int el_torito_writer_index = -1, file_src_writer_index = -1;
int system_area_options = 0;
char *system_area = NULL;
/* 1. Allocate target and copy opts there */
target = calloc(1, sizeof(Ecma119Image));
@ -1126,6 +1167,44 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
/* el-torito? */
target->eltorito = (src->bootcat == NULL ? 0 : 1);
target->catalog = src->bootcat;
if (target->catalog != NULL) {
target->num_bootsrc = target->catalog->num_bootimages;
target->bootsrc = calloc(target->num_bootsrc + 1,
sizeof(IsoFileSrc *));
if (target->bootsrc == NULL) {
ret = ISO_OUT_OF_MEM;
goto target_cleanup;
}
for (i= 0; i < target->num_bootsrc; i++)
target->bootsrc[i] = NULL;
} else {
target->num_bootsrc = 0;
target->bootsrc = NULL;
}
if (opts->system_area_data != NULL) {
system_area = opts->system_area_data;
system_area_options = opts->system_area_options;
} else if (src->system_area_data != NULL) {
system_area = src->system_area_data;
system_area_options = src->system_area_options;
}
target->system_area_data = NULL;
if (system_area != NULL) {
target->system_area_data = calloc(32768, 1);
if (target->system_area_data == NULL) {
ret = ISO_OUT_OF_MEM;
goto target_cleanup;
}
memcpy(target->system_area_data, system_area, 32768);
}
target->system_area_options = system_area_options;
target->vol_creation_time = opts->vol_creation_time;
target->vol_modification_time = opts->vol_modification_time;
target->vol_expiration_time = opts->vol_expiration_time;
target->vol_effective_time = opts->vol_effective_time;
strcpy(target->vol_uuid, opts->vol_uuid);
target->input_charset = strdup(iso_get_local_charset(0));
if (target->input_charset == NULL) {
@ -1689,6 +1768,14 @@ int iso_write_opts_new(IsoWriteOpts **opts, int profile)
wopts->fifo_size = 1024; /* 2 MB buffer */
wopts->sort_files = 1; /* file sorting is always good */
wopts->system_area_data = NULL;
wopts->system_area_options = 0;
wopts->vol_creation_time = 0;
wopts->vol_modification_time = 0;
wopts->vol_expiration_time = 0;
wopts->vol_effective_time = 0;
wopts->vol_uuid[0]= 0;
*opts = wopts;
return ISO_SUCCESS;
}
@ -1700,6 +1787,8 @@ void iso_write_opts_free(IsoWriteOpts *opts)
}
free(opts->output_charset);
if(opts->system_area_data != NULL)
free(opts->system_area_data);
free(opts);
}
@ -1765,7 +1854,7 @@ int iso_write_opts_set_omit_version_numbers(IsoWriteOpts *opts, int omit)
if (opts == NULL) {
return ISO_NULL_POINTER;
}
opts->omit_version_numbers = omit ? 1 : 0;
opts->omit_version_numbers = omit & 3;
return ISO_SUCCESS;
}
@ -1801,7 +1890,7 @@ int iso_write_opts_set_no_force_dots(IsoWriteOpts *opts, int no)
if (opts == NULL) {
return ISO_NULL_POINTER;
}
opts->no_force_dots = no ? 1 : 0;
opts->no_force_dots = no & 3;
return ISO_SUCCESS;
}
@ -2085,3 +2174,43 @@ int iso_write_opts_get_data_start(IsoWriteOpts *opts, uint32_t *data_start,
return ISO_SUCCESS;
}
/*
* @param data Either NULL or 32 kB of data. Do not submit less bytes !
* @param options bit0 = apply GRUB protective msdos label
* @param flag bit0 = invalidate any attached system area data
* same as data == NULL
*/
int iso_write_opts_set_system_area(IsoWriteOpts *opts, char data[32768],
int options, int flag)
{
if (data == NULL || (flag & 1)) { /* Disable */
if (opts->system_area_data != NULL)
free(opts->system_area_data);
opts->system_area_data = NULL;
} else if (!(flag & 2)) {
if (opts->system_area_data == NULL) {
opts->system_area_data = calloc(32768, 1);
if (opts->system_area_data == NULL)
return ISO_OUT_OF_MEM;
}
memcpy(opts->system_area_data, data, 32768);
}
if (!(flag & 4))
opts->system_area_options = options & 3;
return ISO_SUCCESS;
}
int iso_write_opts_set_pvd_times(IsoWriteOpts *opts,
time_t vol_creation_time, time_t vol_modification_time,
time_t vol_expiration_time, time_t vol_effective_time,
char *vol_uuid)
{
opts->vol_creation_time = vol_creation_time;
opts->vol_modification_time = vol_modification_time;
opts->vol_expiration_time = vol_expiration_time;
opts->vol_effective_time = vol_effective_time;
strncpy(opts->vol_uuid, vol_uuid, 16);
opts->vol_uuid[16] = 0;
return ISO_SUCCESS;
}

View File

@ -57,8 +57,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 +84,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
@ -298,6 +302,22 @@ 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];
};
typedef struct ecma119_image Ecma119Image;
@ -328,11 +348,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;
@ -434,7 +454,28 @@ 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= 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= 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.
*/
int system_area_options;
/*
* Number of pad blocks that we need to write. Padding blocks are blocks
@ -492,6 +533,16 @@ struct ecma119_image
/* writer thread descriptor */
pthread_t wthread;
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];
};
#define BP(a,b) [(b) - (a) + 1]

View File

@ -64,18 +64,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);
}

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
@ -17,9 +18,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 +57,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 +81,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 +101,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 +117,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 +179,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 +197,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
@ -333,10 +411,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 +432,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;
@ -413,8 +496,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 +524,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 +568,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 +579,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 +627,68 @@ 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->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;
}
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 +699,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 +712,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 +724,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 +790,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;
}
@ -757,7 +973,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 +989,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 +1023,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 +1061,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,13 +1073,16 @@ 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;
@ -856,7 +1098,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 +1109,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;
@ -918,7 +1160,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 +1191,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,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
@ -102,6 +102,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 +279,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 */
@ -2106,19 +2120,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 +2138,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 +2211,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 +2228,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 +2375,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 +2414,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;
@ -2419,21 +2487,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 +2548,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 +2669,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 +2781,16 @@ 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) {
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 +2798,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 +2938,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 +2995,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 +3012,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 +3125,11 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
IsoFileSource *newroot;
_ImageFsData *data;
struct el_torito_boot_catalog *oldbootcat;
uint8_t *rpt;
IsoFileSource *boot_src;
IsoNode *node;
#ifdef Libisofs_with_checksumS
int i;
uint32_t old_checksum_start_lba;
uint32_t old_checksum_end_lba;
uint32_t old_checksum_idx_count;
@ -2969,7 +3137,6 @@ 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
@ -2978,12 +3145,30 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
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) {
@ -3048,23 +3233,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 +3294,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,
@ -3221,6 +3419,10 @@ 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;
@ -3332,8 +3534,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 +3672,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

@ -74,6 +74,8 @@ 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->builder_ignore_acl = 1;
img->builder_ignore_ea = 1;
img->inode_counter = 0;
@ -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)
{

View File

@ -53,6 +53,11 @@ 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;
/* image identifier, for message origin identifier */
int id;

View File

@ -712,7 +712,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 +763,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);

View File

@ -43,7 +43,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) {
@ -574,7 +574,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;
}
@ -722,7 +722,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++] = ';';
@ -758,7 +758,7 @@ void write_one_dir_record(Ecma119Image *t, JolietNode *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 == 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;
}
@ -833,9 +833,9 @@ int joliet_writer_write_vol_desc(IsoImageWriter *writer)
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_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);
@ -899,7 +899,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;
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007-2008 Vreixo Formoso, Mario Danic
* 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
@ -10,7 +10,7 @@
/*
*
* Applications must use 64 bit off_t, e.g. on 32-bit Linux by defining
* Applications must use 64 bit off_t, e.g. on 32-bit GNU/Linux by defining
* #define _LARGEFILE_SOURCE
* #define _FILE_OFFSET_BITS 64
* or take special precautions to interface with the library by 64 bit integers
@ -374,7 +374,7 @@ extern unsigned int iso_fs_global_id;
* access and read file contents. Note that this doesn't need to be tied
* to the disc filesystem used in the partition being accessed. For example,
* we have an IsoFilesystem implementation to access any mounted filesystem,
* using standard Linux functions. It is also legal, of course, to implement
* using standard POSIX functions. It is also legal, of course, to implement
* an IsoFilesystem to deal with a specific filesystem over raw partitions.
* That is what we do, for example, to access an ISO Image.
*
@ -1091,7 +1091,7 @@ int iso_lib_is_compatible(int major, int minor, int micro);
*/
#define iso_lib_header_version_major 0
#define iso_lib_header_version_minor 6
#define iso_lib_header_version_micro 28
#define iso_lib_header_version_micro 32
/**
* Usage discussion:
@ -1286,7 +1286,9 @@ int iso_write_opts_set_aaip(IsoWriteOpts *opts, int enable);
* Omit the version number (";1") at the end of the ISO-9660 identifiers.
* This breaks ECMA-119 specification, but version numbers are usually not
* used, so it should work on most systems. Use with caution.
*
* @param omit
* bit0= omit version number with ECMA-119 and Joliet
* bit1= omit version number with Joliet alone (@since 0.6.30)
* @since 0.6.2
*/
int iso_write_opts_set_omit_version_numbers(IsoWriteOpts *opts, int omit);
@ -1324,6 +1326,9 @@ int iso_write_opts_set_max_37_char_filenames(IsoWriteOpts *opts, int allow);
* extension. libisofs adds it if original filename doesn't has one. Set
* this to 1 to prevent this behavior.
* This breaks ECMA-119 specification. Use with caution.
* @param no
* bit0= no forced dot with ECMA-119
* bit1= no forced dot with Joliet (@since 0.6.30)
*
* @since 0.6.2
*/
@ -1680,6 +1685,75 @@ int iso_write_opts_set_overwrite_buf(IsoWriteOpts *opts, uint8_t *overwrite);
*/
int iso_write_opts_set_fifo_size(IsoWriteOpts *opts, size_t fifo_size);
/*
* Attach 32 kB of binary data which shall get written to the first 32 kB
* of the ISO image, the ECMA-119 System Area. This space is intended for
* system dependent boot software, e.g. a Master Boot Record which allows to
* boot from USB sticks or hard disks. ECMA-119 makes no own assumptions or
* prescriptions about the byte content.
*
* If system area data are given or options bit0 is set, then bit1 of
* el_torito_set_isolinux_options() is automatically disabled.
* @param data
* Either NULL or 32 kB of data. Do not submit less bytes !
* @param options
* Can cause manipulations of submitted data before they get written:
* bit0= apply a --protective-msdos-label as of grub-mkisofs.
* This means to patch bytes 446 to 512 of the system area so
* that one partition is defined which begins at the second
* 512-byte block of the image and ends where the image ends.
* This works with and without system_area_data.
* bit1= apply isohybrid MBR patching to the system area.
* This works only with system area data from SYSLINUX plus an
* ISOLINUX boot image (see iso_image_set_boot_image()) and
* only if not bit0 is set.
* @param flag
* bit0 = invalidate any attached system area data. Same as data == NULL
* (This re-activates eventually loaded image System Area data.
* To erase those, submit 32 kB of zeros without flag bit0.)
* bit1 = keep data unaltered
* bit2 = keep options unaltered
* @return
* ISO_SUCCESS or error
* @since 0.6.30
*/
int iso_write_opts_set_system_area(IsoWriteOpts *opts, char data[32768],
int options, int flag);
/**
* Explicitely set the four timestamps of the emerging Primary Volume
* Descriptor. Default with all parameters is 0.
* ECMA-119 defines them as:
* @param vol_creation_time
* When "the information in the volume was created."
* A value of 0 means that the timepoint of write start is to be used.
* @param vol_modification_time
* When "the information in the volume was last modified."
* A value of 0 means that the timepoint of write start is to be used.
* @param vol_expiration_time
* When "the information in the volume may be regarded as obsolete."
* A value of 0 means that the information never shall expire.
* @param vol_effective_time
* When "the information in the volume may be used."
* A value of 0 means that not such retention is intended.
* @param uuid
* If this text is not empty, then it overrides vol_creation_time and
* vol_modification_time by copying the first 16 decimal digits from
* uuid, eventually padding up with decimal '1', and writing a NUL-byte
* as timezone.
* Other than with vol_*_time the resulting string in the ISO image
* is fully predictable and free of timezone pitfalls.
* It should express a reasonable time in form YYYYMMDDhhmmsscc
* E.g.: "2010040711405800" = 7 Apr 2010 11:40:58 (+0 centiseconds)
*
* @since 0.6.30
*/
int iso_write_opts_set_pvd_times(IsoWriteOpts *opts,
time_t vol_creation_time, time_t vol_modification_time,
time_t vol_expiration_time, time_t vol_effective_time,
char *vol_uuid);
/**
* Inquire the start address of the file data blocks after having used
* IsoWriteOpts with iso_image_create_burn_source().
@ -1922,6 +1996,20 @@ int iso_read_opts_set_input_charset(IsoReadOpts *opts, const char *charset);
*/
int iso_read_opts_auto_input_charset(IsoReadOpts *opts, int mode);
/**
* Enable or disable loading of the first 32768 bytes of the session.
*
* @param mode
* Bitfield for control purposes:
* bit0= Load System Area data and attach them to the image so that they
* get written by the next session, if not overridden by
* iso_write_opts_set_system_area().
* Submit any other bits with value 0.
*
* @since 0.6.30
*
*/
int iso_read_opts_load_system_area(IsoReadOpts *opts, int mode);
/**
* Import a previous session or image, for growing or modify.
@ -2195,16 +2283,15 @@ void iso_image_set_biblio_file_id(IsoImage *image, const char *biblio_file_id);
const char *iso_image_get_biblio_file_id(const IsoImage *image);
/**
* Create a bootable image by adding a El-Torito boot image.
*
* This also add a catalog boot node to the image filesystem tree.
* Create a new set of El-Torito bootable images by adding a boot catalog
* and the default boot image.
* Further boot images may then be added by iso_image_add_boot_image().
*
* @param image
* The image to make bootable. If it was already bootable this function
* returns an error and the image remains unmodified.
* @param image_path
* The absolute path on the image tree of a regular file to use as
* default boot image.
* The absolute path of a IsoFile to be used as default boot image.
* @param type
* The boot media type. This can be one of 3 types:
* - Floppy emulation: Boot image file must be exactly
@ -2237,10 +2324,36 @@ int iso_image_set_boot_image(IsoImage *image, const char *image_path,
const char *catalog_path,
ElToritoBootImage **boot);
/**
* Add a further boot image to the set of El-Torito bootable images.
* This set has already to be created by iso_image_set_boot_image().
* Up to 31 further boot images may be added.
*
* @param image
* The image to which the boot image shall be added.
* returns an error and the image remains unmodified.
* @param image_path
* The absolute path of a IsoFile to be used as default boot image.
* @param type
* The boot media type. See iso_image_set_boot_image
* @param flag
* Bitfield for control purposes. Unused yet. Submit 0.
* @param boot
* Location where a pointer to the added boot image will be stored.
* See iso_image_set_boot_image
* @return
* 1 on success, < 0 on error
*
* @since 0.6.32
*/
int iso_image_add_boot_image(IsoImage *image, const char *image_path,
enum eltorito_boot_media_type type, int flag,
ElToritoBootImage **boot);
/* TODO #00026 : add support for "hidden" bootable images. */
/**
* Get El-Torito boot image of an ISO image, if any.
* Get the El-Torito boot catalog and the 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
@ -2278,7 +2391,35 @@ int iso_image_get_boot_image(IsoImage *image, ElToritoBootImage **boot,
IsoFile **imgnode, IsoBoot **catnode);
/**
* Removes the El-Torito bootable image.
* Get all El-Torito boot images of an ISO image.
*
* The first of these boot images is the same as returned by
* iso_image_get_boot_image(). The others are alternative boot images.
*
* @param image
* The image from which to get the boot images.
* @param num_boots
* The number of available array elements in boots and bootnodes.
* @param boots
* Returns NULL or an allocated array of pointers to boot images.
* Apply system call free(boots) to dispose it.
* @param bootnodes
* Returns NULL or an allocated array of pointers to the IsoFile nodes
* which bear the content of the boot images in boots.
* @param flag
* Bitfield for control purposes. Unused yet. Submit 0.
* @return
* 1 on success, 0 no El-Torito catalog and boot image attached,
* < 0 error.
*
* @since 0.6.32
*/
int iso_image_get_all_boot_imgs(IsoImage *image, int *num_boots,
ElToritoBootImage ***boots, IsoFile ***bootnodes, int flag);
/**
* Removes all El-Torito boot images from the ISO image.
*
* The IsoBoot node that acts as placeholder for the catalog is also removed
* for the image tree, if there.
@ -2289,6 +2430,74 @@ int iso_image_get_boot_image(IsoImage *image, ElToritoBootImage **boot,
*/
void iso_image_remove_boot_image(IsoImage *image);
/**
* Sets the sort weight of the boot catalog that is attached to an IsoImage.
*
* For the meaning of sort weights see iso_node_set_sort_weight().
* That function cannot be applied to the emerging boot catalog because
* it is not represented by an IsoFile.
*
* @param image
* The image to manipulate.
* @param sort_weight
* The larger this value, the lower will be the block address of the
* boot catalog record.
* @return
* 0= no boot catalog attached , 1= ok , <0 = error
*
* @since 0.6.32
*/
int iso_image_set_boot_catalog_weight(IsoImage *image, int sort_weight);
/**
* Get the boot media type as of parameter "type" of iso_image_set_boot_image()
* resp. iso_image_add_boot_image().
*
* @param bootimg
* The image to inquire
* @param media_type
* Returns the media type
* @return
* 1 = ok , < 0 = error
*
* @since 0.6.32
*/
int el_torito_get_boot_media_type(ElToritoBootImage *bootimg,
enum eltorito_boot_media_type *media_type);
/**
* Sets the platform ID of the boot image.
*
* The Platform ID gets written into the boot catalog at byte 1 of the
* Validation Entry, or at byte 1 of a Section Header Entry.
* If Platform ID and ID String of two consequtive bootimages are the same
*
* @param bootimg
* The image to manipulate.
* @param id
* A Platform ID as of
* El Torito 1.0 : 0x00= 80x86, 0x01= PowerPC, 0x02= Mac
* Others : 0xef= EFI
* @return
* 1 ok , <=0 error
*
* @since 0.6.32
*/
int el_torito_set_boot_platform_id(ElToritoBootImage *bootimg, uint8_t id);
/**
* Get the platform ID value. See el_torito_set_boot_platform_id().
*
* @param bootimg
* The image to inquire
* @return
* 0 - 255 : The platform ID
* < 0 : error
*
* @since 0.6.32
*/
int el_torito_get_boot_platform_id(ElToritoBootImage *bootimg);
/**
* 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.
@ -2297,6 +2506,19 @@ void iso_image_remove_boot_image(IsoImage *image);
*/
void el_torito_set_load_seg(ElToritoBootImage *bootimg, short segment);
/**
* Get the load segment value. See el_torito_set_load_seg().
*
* @param bootimg
* The image to inquire
* @return
* 0 - 65535 : The load segment value
* < 0 : error
*
* @since 0.6.32
*/
int el_torito_get_load_seg(ElToritoBootImage *bootimg);
/**
* Sets the number of sectors (512b) to be load at load segment during
* the initial boot procedure. This is only for
@ -2306,6 +2528,19 @@ void el_torito_set_load_seg(ElToritoBootImage *bootimg, short segment);
*/
void el_torito_set_load_size(ElToritoBootImage *bootimg, short sectors);
/**
* Get the load size. See el_torito_set_load_size().
*
* @param bootimg
* The image to inquire
* @return
* 0 - 65535 : The load size value
* < 0 : error
*
* @since 0.6.32
*/
int el_torito_get_load_size(ElToritoBootImage *bootimg);
/**
* Marks the specified boot image as not bootable
*
@ -2314,30 +2549,131 @@ void el_torito_set_load_size(ElToritoBootImage *bootimg, short sectors);
void el_torito_set_no_bootable(ElToritoBootImage *bootimg);
/**
* 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.
* Get the bootability flag. See el_torito_set_no_bootable().
*
* @since 0.6.2
* @deprecated Use el_torito_set_isolinux_options() instead
* @param bootimg
* The image to inquire
* @return
* 0 = not bootable, 1 = bootable , <0 = error
*
* @since 0.6.32
*/
void el_torito_patch_isolinux_image(ElToritoBootImage *bootimg);
int el_torito_get_bootable(ElToritoBootImage *bootimg);
/**
* Specifies options for IsoLinux boot images. This should only be used with
* isolinux boot images.
* Set the id_string of the Validation Entry resp. Sector Header Entry which
* will govern the boot image Section Entry in the El Torito Catalog.
*
* @param bootimg
* The image to manipulate.
* @param id_string
* The first boot image puts 24 bytes of ID string into the Validation
* Entry, where they shall "identify the manufacturer/developer of
* the CD-ROM".
* Further boot images put 28 bytes into their Section Header.
* El Torito 1.0 states that "If the BIOS understands the ID string, it
* may choose to boot the * system using one of these entries in place
* of the INITIAL/DEFAULT entry." (The INITIAL/DEFAULT entry points to the
* first boot image.)
* @return
* 1 = ok , <0 = error
*
* @since 0.6.32
*/
int el_torito_set_id_string(ElToritoBootImage *bootimg, uint8_t id_string[28]);
/**
* Get the id_string as of el_torito_set_id_string().
*
* @param bootimg
* The image to inquire
* @param id_string
* Returns 28 bytes of id string
* @return
* 1 = ok , <0 = error
*
* @since 0.6.32
*/
int el_torito_get_id_string(ElToritoBootImage *bootimg, uint8_t id_string[28]);
/**
* Set the Selection Criteria of a boot image.
*
* @param bootimg
* The image to manipulate.
* @param crit
* The first boot image has no selection criteria. They will be ignored.
* Further boot images put 1 byte of Selection Criteria Type and 19
* bytes of data into their Section Entry.
* El Torito 1.0 states that "The format of the selection criteria is
* a function of the BIOS vendor. In the case of a foreign language
* BIOS three bytes would be used to identify the language".
* Type byte == 0 means "no criteria",
* type byte == 1 means "Language and Version Information (IBM)".
* @return
* 1 = ok , <0 = error
*
* @since 0.6.32
*/
int el_torito_set_selection_crit(ElToritoBootImage *bootimg, uint8_t crit[20]);
/**
* Get the Selection Criteria bytes as of el_torito_set_selection_crit().
*
* @param bootimg
* The image to inquire
* @param id_string
* Returns 20 bytes of type and data
* @return
* 1 = ok , <0 = error
*
* @since 0.6.32
*/
int el_torito_get_selection_crit(ElToritoBootImage *bootimg, uint8_t crit[20]);
/**
* Makes a guess whether the boot image was patched by a boot information
* table. It is advisable to patch such boot images if their content gets
* copied to a new location. See el_torito_set_isolinux_options().
* Note: The reply can be positive only if the boot image was imported
* from an existing ISO image.
*
* @param bootimg
* The image to inquire
* @return
* 1 = seems to contain oot info table , 0 = quite surely not
* @since 0.6.32
*/
int el_torito_seems_boot_info_table(ElToritoBootImage *bootimg, int flag);
/**
* Specifies options for ISOLINUX or GRUB boot images. This should only be used
* if the type of boot image is known.
*
* @param options
* bitmask style flag. The following values are defined:
*
* bit 0 -> 1 to patch the image, 0 to not
* 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 will not be modified. This is
* needed to allow isolinux images to be bootable.
* bit 1 -> 1 to generate an hybrid image with MBR, 0 to not
* An hybrid image is a boot image that boots from either
* bit 0 -> 1 to patch the boot info table of the boot image.
* 1 does the same as mkisofs option -boot-info-table.
* Needed for ISOLINUX or GRUB boot images with platform ID 0.
* The table is located at byte 8 of the boot image file.
* Its size is 56 bytes.
* The original boot image file on disk will not be modified.
*
* One may use el_torito_seems_boot_info_table() for a
* qualified guess whether a boot info table is present in
* the boot image. If the result is 1 then it should get bit0
* set if its content gets copied to a new LBA.
*
* bit 1 -> 1 to generate a ISOLINUX isohybrid image with MBR.
* ----------------------------------------------------------
* @deprecated since 31 Mar 2010:
* The author of syslinux, H. Peter Anvin requested that this
* feature shall not be used any more. He intends to cease
* support for the MBR template that is included in libisofs.
* ----------------------------------------------------------
* A hybrid image is a boot image that boots from either
* CD/DVD media or from disk-like media, e.g. USB stick.
* For that you need isolinux.bin from SYSLINUX 3.72 or later.
* IMPORTANT: The application has to take care that the image
@ -2348,7 +2684,55 @@ void el_torito_patch_isolinux_image(ElToritoBootImage *bootimg);
* 1 success, < 0 on error
* @since 0.6.12
*/
int el_torito_set_isolinux_options(ElToritoBootImage *bootimg, int options, int flag);
int el_torito_set_isolinux_options(ElToritoBootImage *bootimg,
int options, int flag);
/**
* Get the options as of el_torito_set_isolinux_options().
*
* @param bootimg
* The image to inquire
* @param flag
* Reserved for future usage, set to 0.
* @return
* >= 0 returned option bits , <0 = error
*
* @since 0.6.32
*/
int el_torito_get_isolinux_options(ElToritoBootImage *bootimg, int flag);
/** Deprecated:
* Specifies that this image needs to be patched. This involves the writing
* of a 16 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.
*
* @since 0.6.2
* @deprecated Use el_torito_set_isolinux_options() instead
*/
void el_torito_patch_isolinux_image(ElToritoBootImage *bootimg);
/**
* Obtain a copy of the eventually loaded first 32768 bytes of the imported
* session, the System Area.
* It will be written to the start of the next session unless it gets
* overwritten by iso_write_opts_set_system_area().
*
* @param img
* The image to be inquired.
* @param data
* A byte array of at least 32768 bytesi to take the loaded bytes.
* @param options
* The option bits which will be applied if not overridden by
* iso_write_opts_set_system_area(). See there.
* @param flag
* Bitfield for control purposes, unused yet, submit 0
* @return
* 1 on success, 0 if no System Area was loaded, < 0 error.
* @since 0.6.30
*/
int iso_image_get_system_area(IsoImage *img, char data[32768],
int *options, int flag);
/**
* Increments the reference counting of the given node.
@ -2576,14 +2960,14 @@ time_t iso_node_get_ctime(const IsoNode *node);
/**
* Set if the node will be hidden in RR/ISO tree, Joliet tree or both.
*
* If the file is set as hidden in one tree, it won't be included there, so
* If the file is set as hidden in one tree, it wil not be included there, so
* it won't be visible in a OS accessing CD using that tree. For example,
* GNU/Linux systems access to Rock Ridge / ISO9960 tree in order to see
* what is recorded on CD, while MS Windows make use of the Joliet tree. If a
* file is hidden only in Joliet, it won't be visible in Windows systems,
* while still visible in Linux.
* file is hidden only in Joliet, it wil not be visible in Windows systems,
* while still visible in GNU/Linux.
*
* If a file is hidden in both trees, it won't be written to image.
* If a file is hidden in both trees, it will not be written to image.
*
* @param node
* The node that is to be hidden.
@ -3034,8 +3418,8 @@ const char *iso_symlink_get_dest(const IsoSymlink *link);
int iso_symlink_set_dest(IsoSymlink *link, const char *dest);
/**
* Sets the order in which a node will be written on image. High weihted files
* will be written first, so in a disc them will be written near the center.
* Sets the order in which a node will be written on image. The data content
* of files with high weight will be written to low block addresses.
*
* @param node
* The node which weight will be changed. If it's a dir, this function
@ -3044,6 +3428,7 @@ int iso_symlink_set_dest(IsoSymlink *link, const char *dest);
* @param w
* The weight as a integer number, the greater this value is, the
* closer from the begining of image the file will be written.
* Default value at IsoNode creation is 0.
*
* @since 0.6.2
*/
@ -4364,7 +4749,7 @@ int aaip_xinfo_func(void *data, int flag);
* @param default_text
* Will return a pointer to the eventual "default" ACL or NULL if it
* is not available.
* (Linux directories can have a "default" ACL which influences
* (GNU/Linux directories can have a "default" ACL which influences
* the permissions of newly created files.)
* @param flag
* Bitfield for control purposes
@ -4401,7 +4786,7 @@ int iso_node_get_acl_text(IsoNode *node,
* @param default_text
* The text to be set into effect as "default" ACL. NULL will delete an
* eventually existing "default" ACL of the node.
* (Linux directories can have a "default" ACL which influences
* (GNU/Linux directories can have a "default" ACL which influences
* the permissions of newly created files.)
* @param flag
* Bitfield for control purposes
@ -5322,6 +5707,9 @@ int iso_md5_match(char first_md5[16], char second_md5[16]);
/** Trying to use an invalid file as boot image (FAILURE,HIGH, -68) */
#define ISO_BOOT_IMAGE_NOT_VALID 0xE830FFBB
/** Too many boot images (FAILURE,HIGH, -69) */
#define ISO_BOOT_IMAGE_OVERFLOW 0xE830FFBA
/**
* Error on file operation (FAILURE,HIGH, -128)
* (take a look at more specified error codes below)
@ -5423,11 +5811,11 @@ int iso_md5_match(char first_md5[16], char second_md5[16]);
/** Unsupported ECMA-119 feature (FAILURE,HIGH, -324) */
#define ISO_UNSUPPORTED_ECMA119 0xE830FEBC
/** Wrong or damaged El-Torito catalog (SORRY,HIGH, -325) */
#define ISO_WRONG_EL_TORITO 0xE030FEBB
/** Wrong or damaged El-Torito catalog (WARN,HIGH, -325) */
#define ISO_WRONG_EL_TORITO 0xD030FEBB
/** Unsupported El-Torito feature (SORRY,HIGH, -326) */
#define ISO_UNSUPPORTED_EL_TORITO 0xE030FEBA
/** Unsupported El-Torito feature (WARN,HIGH, -326) */
#define ISO_UNSUPPORTED_EL_TORITO 0xD030FEBA
/** Can't patch an isolinux boot image (SORRY,HIGH, -327) */
#define ISO_ISOLINUX_CANT_PATCH 0xE030FEB9

View File

@ -10,6 +10,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 +26,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 +52,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 +63,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 +235,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

@ -153,6 +153,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:

View File

@ -1284,6 +1284,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;

View File

@ -109,12 +109,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);
@ -243,10 +243,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);
}
@ -695,7 +695,7 @@ int susp_add_CE(Ecma119Image *t, size_t ce_len, struct susp_info *susp)
CE[3] = 1;
iso_bb(&CE[4], susp->ce_block, 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

@ -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
@ -12,28 +13,114 @@
#include "filesrc.h"
#include <string.h>
#include <stdio.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(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);
/* 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
*/
static
int make_grub_msdos_label(int img_blocks, uint8_t *buf, int flag)
{
uint8_t *wpt;
unsigned long end_lba, secs, end_sec, end_head, end_cyl;
int sph = 63, hpc = 255, i;
/* 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 */
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;
}
/* 1) Zero-fill 446-510 */
wpt = buf + 446;
memset(wpt, 0, 64);
/* 2) Put 0x55, 0xAA into 510-512 (actually 510-511) */
buf[510] = 0x55;
buf[511] = 0xAA;
/* 3) Put 0x80 (for bootable partition), */
*(wpt++) = 0x80;
/* 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;
}
int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
{
int ret;
int img_blocks;
if ((t == NULL) || (buf == NULL)) {
return ISO_NULL_POINTER;
}
@ -41,26 +128,41 @@ 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;
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 (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)
*/
ret = make_isohybrid_mbr(t->bootsrc[0]->sections[0].block,
&img_blocks, (char*)buf, 0);
if (ret != 1) {
/* error, it should never happen */
return ISO_ASSERT_FAILURE;
}
return ISO_SUCCESS;
}
if (t->system_area_options & 1) {
/* Write GRUB protective msdos label, i.e. a isimple partition table */
ret = make_grub_msdos_label(img_blocks, buf, 0);
if (ret != 1) /* error should never happen */
return ISO_ASSERT_FAILURE;
} else if(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, 64, 32, 0, 1, 0x17, buf, 1);
if (ret != 1)
return ret;
}
return ISO_SUCCESS;
}

View File

@ -908,7 +908,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 +957,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 +974,8 @@ uint16_t *iso_j_file_id(const uint16_t *src)
pos++;
}
}
is_done:;
set_ucsbe(dest + pos, '\0');
return ucsdup(dest);
}
@ -1206,7 +1215,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 +1259,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