Compare commits

...

22 Commits

Author SHA1 Message Date
efbd05203d Version leap to 1.3.0 2013-05-17 19:47:58 +02:00
6ca1d76d60 Updated change log 2013-05-17 09:52:40 +02:00
e1b54056e8 Added a new source of information about CHRP to boot_sectors.txt 2013-05-01 20:28:24 +02:00
d5cd610ac7 Bug fix: The protective MBR partition for GPT started at block 0 instead of 1 2013-04-17 20:54:02 +02:00
91f5ebb376 Bug fix: GPT header CRC was computed from all 512 bytes rather than from 92. 2013-04-17 16:45:51 +02:00
ff3b439bda Changed Libisofs_grub2_sparc_patch_lba_poS to Libisofs_grub2_sparc_patch_adr_poS 2013-04-14 08:15:29 +02:00
4672c79181 Changed Libisofs_grub2_sparc_patch_lba_poS to Libisofs_grub2_sparc_patch_adr_poS 2013-04-14 08:14:27 +02:00
83cb07b23c New API calls iso_image_set_sparc_core() and iso_image_get_sparc_core(). 2013-04-13 22:17:26 +02:00
439a14da1d Bug fix: Reserved and unused fields of APM entries were not zeroed. 2013-04-13 12:11:26 +02:00
d66eef42f6 Corrected Libisofs_grub2_mbr_patch_offsT from 3 to 4 2013-04-13 09:25:42 +02:00
337bade549 New option bits with el_torito_set_isolinux_options() and
iso_write_opts_set_system_area() to control GRUB2 patching of
boot image and MBR
2013-04-13 08:38:52 +02:00
eb6503a8ad * Bug fix: Unspecified Expiration Time and Effective Time of ISO volume was
represented by 0-bytes rather than ASCII '0' digits.
2013-04-10 13:55:20 +02:00
1a2e1c767e Now repeating Rock Ridge warnings at most once per loaded image. 2013-04-10 13:32:53 +02:00
858c5479c8 Changed some warning texts from "RR" to "Rock Ridge" 2013-04-10 13:32:09 +02:00
d36b3d04a8 Temporarily hosting a test bed for syslinux/core/fs/susp_rr.c in libisofs/fs_image.c 2013-03-31 13:37:39 +02:00
da41eb8c6e Version leap to 1.2.9 2013-03-18 21:54:59 +01:00
775b7a11b4 Version leap to 1.2.8 2013-03-18 21:47:22 +01:00
23679b86ff Updated changelog 2013-03-18 08:32:16 +01:00
a4f07eb3b3 New API call iso_image_get_pvd_times(). 2013-03-12 17:42:13 +01:00
6905ab3e56 Bug fix: Image size prediction altered the pointers to MD5 of data files
which stem from a previous session.
2013-01-14 18:13:49 +01:00
05e7f84966 Bug fix: Reading damaged Rock Ridge data could cause SIGSEGV by NULL. 2013-01-11 16:22:14 +01:00
6e5f840f11 Version leap to 1.2.7 2013-01-08 15:38:01 +01:00
17 changed files with 626 additions and 159 deletions

View File

@ -1,3 +1,22 @@
libisofs-1.3.0.tar.gz Fri May 17 2013
===============================================================================
* Bug fix: GPT header CRC was computed from all 512 bytes rather than from 92.
* Bug fix: Unspecified Expiration Time and Effective Time of ISO volume was
represented by 0-bytes rather than ASCII '0' digits.
* Bug fix: Reserved and unused fields of APM entries were not zeroed.
* Bug fix: The protective MBR partition for GPT started at block 0 instead of 1.
* New option bits with el_torito_set_isolinux_options() and
iso_write_opts_set_system_area() to control GRUB2 patching of
boot image and MBR.
* New API calls iso_image_set_sparc_core() and iso_image_get_sparc_core().
libisofs-1.2.8.tar.gz Mon Mar 18 2013
===============================================================================
* Bug fix: Image size prediction altered the pointers to MD5 of data files
which stem from a previous session.
* Bug fix: Reading damaged Rock Ridge data could cause SIGSEGV by NULL.
* New API call iso_image_get_pvd_times().
libisofs-1.2.6.tar.gz Tue Jan 08 2013 libisofs-1.2.6.tar.gz Tue Jan 08 2013
=============================================================================== ===============================================================================
* Bug fix: Appended partitions did not obey cylinder alignment * Bug fix: Appended partitions did not obey cylinder alignment

View File

@ -1,4 +1,4 @@
AC_INIT([libisofs], [1.2.6], [http://libburnia-project.org]) AC_INIT([libisofs], [1.3.0], [http://libburnia-project.org])
AC_PREREQ([2.50]) AC_PREREQ([2.50])
dnl AC_CONFIG_HEADER([config.h]) dnl AC_CONFIG_HEADER([config.h])
@ -40,8 +40,8 @@ dnl
dnl If LIBISOFS_*_VERSION changes, be sure to change AC_INIT above to match. dnl If LIBISOFS_*_VERSION changes, be sure to change AC_INIT above to match.
dnl dnl
LIBISOFS_MAJOR_VERSION=1 LIBISOFS_MAJOR_VERSION=1
LIBISOFS_MINOR_VERSION=2 LIBISOFS_MINOR_VERSION=3
LIBISOFS_MICRO_VERSION=6 LIBISOFS_MICRO_VERSION=0
LIBISOFS_VERSION=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION.$LIBISOFS_MICRO_VERSION LIBISOFS_VERSION=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION.$LIBISOFS_MICRO_VERSION
AC_SUBST(LIBISOFS_MAJOR_VERSION) AC_SUBST(LIBISOFS_MAJOR_VERSION)
@ -51,10 +51,10 @@ AC_SUBST(LIBISOFS_VERSION)
dnl Libtool versioning dnl Libtool versioning
LT_RELEASE=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION LT_RELEASE=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION
# 2013.01.08 development jump has not yet happened # 2013.05.17 development jump has not yet happened
# SONAME = 68 - 62 = 6 . Library name = libisofs.6.62.0 # SONAME = 72 - 66 = 6 . Library name = libisofs.6.66.0
LT_CURRENT=68 LT_CURRENT=72
LT_AGE=62 LT_AGE=66
LT_REVISION=0 LT_REVISION=0
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE` LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`

View File

@ -906,13 +906,18 @@ PReP boots via a MBR partition containing only raw ELF and having type 0x41.
Sources: Sources:
Mail conversations with Vladimir Serbinenko. Mail conversations with Vladimir Serbinenko.
http://stuff.mit.edu/afs/sipb/contrib/doc/specs/protocol/chrp/chrp1_7a.pdf
CHRP is marked by an MBR partition entry of type 0x96 spanning the whole CHRP is marked by an MBR partition entry of type 0x96 spanning the whole
ISO 9660 image. ISO 9660 image.
The specs in chrp1_7a.pdf promise that CHRP also recognizes ISO 9660 file
systems on unpartitioned disks. (See 11.1.1. Media Layout Format)
Vladimir Serbinenko stated:
PReP boot may be preferable. At least it can co-exist with other partitions PReP boot may be preferable. At least it can co-exist with other partitions
in the ISO image. in the ISO image [without causing overlapping between partitions].
------------------------------------------------------------------------------ ------------------------------------------------------------------------------

View File

@ -1,7 +1,7 @@
/* /*
* Copyright (c) 2007 Vreixo Formoso * Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2007 Mario Danic * Copyright (c) 2007 Mario Danic
* Copyright (c) 2009 - 2012 Thomas Schmitt * Copyright (c) 2009 - 2013 Thomas Schmitt
* *
* This file is part of the libisofs project; you can redistribute it and/or * 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 * modify it under the terms of the GNU General Public License version 2
@ -501,13 +501,23 @@ void ecma119_set_voldescr_times(IsoImageWriter *writer,
else else
iso_datetime_17(vol->vol_modification_time, t->now, t->always_gmt); iso_datetime_17(vol->vol_modification_time, t->now, t->always_gmt);
if (t->vol_expiration_time > 0) if (t->vol_expiration_time > 0) {
iso_datetime_17(vol->vol_expiration_time, t->vol_expiration_time, iso_datetime_17(vol->vol_expiration_time, t->vol_expiration_time,
t->always_gmt); t->always_gmt);
} else {
for(i = 0; i < 16; i++)
vol->vol_expiration_time[i] = '0';
vol->vol_expiration_time[16] = 0;
}
if (t->vol_effective_time > 0) if (t->vol_effective_time > 0) {
iso_datetime_17(vol->vol_effective_time, t->vol_effective_time, iso_datetime_17(vol->vol_effective_time, t->vol_effective_time,
t->always_gmt); t->always_gmt);
} else {
for(i = 0; i < 16; i++)
vol->vol_effective_time[i] = '0';
vol->vol_effective_time[16] = 0;
}
} }
/** /**
@ -980,6 +990,14 @@ int ecma119_writer_create(Ecma119Image *target)
return ret; return ret;
} }
if (target->image->sparc_core_node != NULL) {
/* Obtain a duplicate of the IsoFile's Ecma119Node->file */
ret = iso_file_src_create(target, target->image->sparc_core_node,
&target->sparc_core_src);
if (ret < 0)
return ret;
}
if(target->partition_offset > 0) { if(target->partition_offset > 0) {
/* Create second tree */ /* Create second tree */
target->eff_partition_offset = target->partition_offset; target->eff_partition_offset = target->partition_offset;
@ -1613,6 +1631,7 @@ int checksum_prepare_nodes(Ecma119Image *target, IsoNode *node, int flag)
*/; */;
} else if (ret == 1 && img->checksum_array == NULL) { } else if (ret == 1 && img->checksum_array == NULL) {
/* No checksum array loaded. Delete "isofs.cx" */ /* No checksum array loaded. Delete "isofs.cx" */
if (!target->will_cancel)
iso_node_set_attrs(node, (size_t) 1, iso_node_set_attrs(node, (size_t) 1,
&cx_names, cx_value_lengths, &cx_valuept, 4 | 8); &cx_names, cx_value_lengths, &cx_valuept, 4 | 8);
no_md5 = 1; no_md5 = 1;
@ -1639,8 +1658,9 @@ int checksum_prepare_nodes(Ecma119Image *target, IsoNode *node, int flag)
} }
/* Equip nodes with provisory isofs.cx numbers: 4 byte, all 0. /* Equip nodes with provisory isofs.cx numbers: 4 byte, all 0.
Omit those from old image which will not be copied and have no MD5. Omit those from old image which will not be copied and have no MD5.
Do not alter the nodes if this is only a will_cancel run.
*/ */
if (!no_md5) { if (!(target->will_cancel || no_md5)) {
ret = iso_file_set_isofscx(file, (unsigned int) 0, 0); ret = iso_file_set_isofscx(file, (unsigned int) 0, 0);
if (ret < 0) if (ret < 0)
return ret; return ret;
@ -1870,6 +1890,8 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
target->mipsel_p_vaddr = 0; target->mipsel_p_vaddr = 0;
target->mipsel_p_filesz = 0; target->mipsel_p_filesz = 0;
target->sparc_core_src = NULL;
target->empty_file_block = 0; target->empty_file_block = 0;
target->tree_end_block = 0; target->tree_end_block = 0;
@ -3263,7 +3285,7 @@ int iso_write_opts_set_system_area(IsoWriteOpts *opts, char data[32768],
memcpy(opts->system_area_data, data, 32768); memcpy(opts->system_area_data, data, 32768);
} }
if (!(flag & 4)) if (!(flag & 4))
opts->system_area_options = options & 0x3fff; opts->system_area_options = options & 0x7fff;
return ISO_SUCCESS; return ISO_SUCCESS;
} }

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2007 Vreixo Formoso * Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2012 Thomas Schmitt * Copyright (c) 2009 - 2013 Thomas Schmitt
* *
* This file is part of the libisofs project; you can redistribute it and/or * 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 * modify it under the terms of the GNU General Public License version 2
@ -825,6 +825,11 @@ struct ecma119_image
uint32_t mipsel_p_vaddr; uint32_t mipsel_p_vaddr;
uint32_t mipsel_p_filesz; uint32_t mipsel_p_filesz;
/* A data file of which the position and size shall be written after
a SUN Disk Label.
*/
IsoFileSrc *sparc_core_src;
char *appended_partitions[ISO_MAX_PARTITIONS]; char *appended_partitions[ISO_MAX_PARTITIONS];
uint8_t appended_part_types[ISO_MAX_PARTITIONS]; uint8_t appended_part_types[ISO_MAX_PARTITIONS];
/* Counted in blocks of 2048 */ /* Counted in blocks of 2048 */

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2007 Vreixo Formoso * Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2010 Thomas Schmitt * Copyright (c) 2010 - 2013 Thomas Schmitt
* *
* This file is part of the libisofs project; you can redistribute it and/or * 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 * modify it under the terms of the GNU General Public License version 2
@ -160,7 +160,13 @@ int el_torito_get_selection_crit(ElToritoBootImage *bootimg, uint8_t crit[20])
/* API */ /* API */
int el_torito_seems_boot_info_table(ElToritoBootImage *bootimg, int flag) int el_torito_seems_boot_info_table(ElToritoBootImage *bootimg, int flag)
{ {
switch (flag & 15) {
case 0:
return bootimg->seems_boot_info_table; return bootimg->seems_boot_info_table;
case 1:
return bootimg->seems_grub2_boot_info;
}
return 0;
} }
/** /**
@ -197,14 +203,14 @@ void el_torito_patch_isolinux_image(ElToritoBootImage *bootimg)
*/ */
int el_torito_set_isolinux_options(ElToritoBootImage *bootimg, int options, int flag) int el_torito_set_isolinux_options(ElToritoBootImage *bootimg, int options, int flag)
{ {
bootimg->isolinux_options = (options & 0x01ff); bootimg->isolinux_options = (options & 0x03ff);
return ISO_SUCCESS; return ISO_SUCCESS;
} }
/* API */ /* API */
int el_torito_get_isolinux_options(ElToritoBootImage *bootimg, int flag) int el_torito_get_isolinux_options(ElToritoBootImage *bootimg, int flag)
{ {
return bootimg->isolinux_options & 0x01ff; return bootimg->isolinux_options & 0x03ff;
} }
/* API */ /* API */
@ -1096,7 +1102,7 @@ int make_boot_info_table(uint8_t *buf, uint32_t pvd_lba,
} }
/** /**
* Patch an isolinux boot image. * Patch an El Torito boot image by a boot info table.
* *
* @return * @return
* 1 on success, 0 error (but continue), < 0 error * 1 on success, 0 error (but continue), < 0 error
@ -1117,6 +1123,27 @@ int patch_boot_info_table(uint8_t *buf, Ecma119Image *t,
return ret; return ret;
} }
/**
* Patch a GRUB2 El Torito boot image.
*/
static
int patch_grub2_boot_image(uint8_t *buf, Ecma119Image *t,
size_t imgsize, int idx,
size_t pos, int offst)
{
uint64_t blk;
if (imgsize < pos + 8)
return iso_msg_submit(t->image->id, ISO_ISOLINUX_CANT_PATCH, 0,
"Isolinux image too small for GRUB2. Will not patch it.");
blk = ((uint64_t) t->bootsrc[idx]->sections[0].block) * 4 + offst;
iso_lsb((buf + pos), blk & 0xffffffff, 4);
iso_lsb((buf + pos + 4), blk >> 32, 4);
return ISO_SUCCESS;
}
/* Patch the boot images if indicated */ /* Patch the boot images if indicated */
int iso_patch_eltoritos(Ecma119Image *t) int iso_patch_eltoritos(Ecma119Image *t)
{ {
@ -1130,7 +1157,7 @@ int iso_patch_eltoritos(Ecma119Image *t)
return ISO_SUCCESS; return ISO_SUCCESS;
for (idx = 0; idx < t->catalog->num_bootimages; idx++) { for (idx = 0; idx < t->catalog->num_bootimages; idx++) {
if (!(t->catalog->bootimages[idx]->isolinux_options & 0x01)) if (!(t->catalog->bootimages[idx]->isolinux_options & 0x201))
continue; continue;
original = t->bootsrc[idx]->stream; original = t->bootsrc[idx]->stream;
size = (size_t) iso_stream_get_size(original); size = (size_t) iso_stream_get_size(original);
@ -1154,8 +1181,19 @@ int iso_patch_eltoritos(Ecma119Image *t)
} }
/* ok, patch the read buffer */ /* ok, patch the read buffer */
if (t->catalog->bootimages[idx]->isolinux_options & 0x200) {
/* GRUB2 boot provisions */
ret = patch_grub2_boot_image(buf, t, size, idx,
Libisofs_grub2_elto_patch_poS,
Libisofs_grub2_elto_patch_offsT);
if (ret < 0)
return ret;
}
/* Must be done as last patching */
if (t->catalog->bootimages[idx]->isolinux_options & 0x01) {
/* Boot Info Table */
ret = patch_boot_info_table(buf, t, size, idx); ret = patch_boot_info_table(buf, t, size, idx);
if (ret < 0) { if (ret < 0)
return ret; return ret;
} }

View File

@ -58,6 +58,7 @@ struct el_torito_boot_image {
* Whether the boot image seems to contain a boot_info_table * Whether the boot image seems to contain a boot_info_table
*/ */
unsigned int seems_boot_info_table:1; unsigned int seems_boot_info_table:1;
unsigned int seems_grub2_boot_info:1;
/** /**
* isolinux options * isolinux options
* bit 0 -> whether to patch image * bit 0 -> whether to patch image
@ -155,4 +156,12 @@ int make_boot_info_table(uint8_t *buf, uint32_t pvd_lba,
*/ */
int iso_patch_eltoritos(Ecma119Image *t); int iso_patch_eltoritos(Ecma119Image *t);
/* Parameters for patch_grub2_boot_image()
Might later become variables in struct el_torito_boot_image.
*/
#define Libisofs_grub2_elto_patch_poS (512 * 5 - 12)
#define Libisofs_grub2_elto_patch_offsT 5
#endif /* LIBISO_ELTORITO_H */ #endif /* LIBISO_ELTORITO_H */

View File

@ -127,7 +127,7 @@ int iso_file_src_create(Ecma119Image *img, IsoFile *file, IsoFileSrc **src)
/* insert the filesrc in the tree */ /* insert the filesrc in the tree */
ret = iso_rbtree_insert(img->files, fsrc, (void**)src); ret = iso_rbtree_insert(img->files, fsrc, (void**)src);
if (ret <= 0) { if (ret <= 0) {
if (ret == 0 && (*src)->checksum_index > 0) { if (ret == 0 && (*src)->checksum_index > 0 && !img->will_cancel) {
/* Duplicate file source was mapped to previously registered source /* Duplicate file source was mapped to previously registered source
*/ */
cret = iso_file_set_isofscx(file, (*src)->checksum_index, 0); cret = iso_file_set_isofscx(file, (*src)->checksum_index, 0);
@ -152,7 +152,7 @@ int iso_file_src_create(Ecma119Image *img, IsoFile *file, IsoFileSrc **src)
no_md5 = 1; no_md5 = 1;
} }
if ((img->md5_file_checksums & 1) && !no_md5) { if ((img->md5_file_checksums & 1) && !(no_md5 || img->will_cancel)) {
img->checksum_idx_counter++; img->checksum_idx_counter++;
if (img->checksum_idx_counter < 0x7fffffff) { if (img->checksum_idx_counter < 0x7fffffff) {
fsrc->checksum_index = img->checksum_idx_counter; fsrc->checksum_index = img->checksum_idx_counter;

View File

@ -35,6 +35,22 @@
#include <stdio.h> #include <stdio.h>
/* Enable this and write the correct absolute path into the include statement
below in order to test the pending contribution to syslinux:
http://www.syslinux.org/archives/2013-March/019755.html
# def ine Libisofs_syslinux_tesT 1
*/
#ifdef Libisofs_syslinux_tesT
#define Isolinux_rockridge_in_libisofS 1
#include "/reiser/syslinux/core/fs/iso9660/susp_rr.c"
/*
# inc lude "/home/thomas/projekte/cdrskin_dir/libisoburn-develop/test/susp_rr.c"
*/
#endif /* Libisofs_syslinux_tesT */
/** /**
* Options for image reading. * Options for image reading.
* There are four kind of options: * There are four kind of options:
@ -241,6 +257,10 @@ typedef struct
char *copyright_file_id; char *copyright_file_id;
char *abstract_file_id; char *abstract_file_id;
char *biblio_file_id; char *biblio_file_id;
char *creation_time;
char *modification_time;
char *expiration_time;
char *effective_time;
/* extension information */ /* extension information */
@ -310,6 +330,30 @@ typedef struct
*/ */
int px_ino_status; int px_ino_status;
/* Which Rock Ridge error messages already have occured
bit0= Invalid PX entry
bit1= Invalid TF entry
bit2= New NM entry found without previous CONTINUE flag
bit3= Invalid NM entry
bit4= New SL entry found without previous CONTINUE flag
bit5= Invalid SL entry
bit6= Invalid SL entry, no child location
bit7= Invalid PN entry
bit8= Sparse files not supported
bit9= SP entry found in a directory entry other than '.' entry of root
bit10= ER entry found in a directory entry other than '.' entry of root
bit11= Invalid AA entry
bit12= Invalid AL entry
bit13= Invalid ZF entry
bit14= Rock Ridge PX entry is not present or invalid
bit15= Incomplete NM
bit16= Incomplete SL
bit17= Charset conversion error
bit18= Link without destination
*/
int rr_err_reported;
int rr_err_repeated;
} _ImageFsData; } _ImageFsData;
typedef struct image_fs_data ImageFileSourceData; typedef struct image_fs_data ImageFileSourceData;
@ -1229,6 +1273,30 @@ char *get_name(_ImageFsData *fsdata, const char *str, size_t len)
} }
static
int iso_rr_msg_submit(_ImageFsData *fsdata, int rr_err_bit,
int errcode, int causedby, const char *msg)
{
int ret;
if ((fsdata->rr_err_reported & (1 << rr_err_bit)) &&
(fsdata->rr_err_repeated & (1 << rr_err_bit))) {
if (iso_msg_is_abort(errcode))
return ISO_CANCELED;
return 0;
}
if (fsdata->rr_err_reported & (1 << rr_err_bit)) {
ret = iso_msg_submit(fsdata->msgid, errcode, causedby,
"MORE THAN ONCE : %s", msg);
fsdata->rr_err_repeated |= (1 << rr_err_bit);
} else {
ret = iso_msg_submit(fsdata->msgid, errcode, causedby, "%s", msg);
fsdata->rr_err_reported |= (1 << rr_err_bit);
}
return ret;
}
/** /**
* *
* @param src * @param src
@ -1419,7 +1487,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
ret = read_rr_PX(sue, &atts); ret = read_rr_PX(sue, &atts);
if (ret < 0) { if (ret < 0) {
/* notify and continue */ /* notify and continue */
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR_WARN, ret, ret = iso_rr_msg_submit(fsdata, 0, ISO_WRONG_RR_WARN, ret,
"Invalid PX entry"); "Invalid PX entry");
fsdata->px_ino_status |= 8; fsdata->px_ino_status |= 8;
} if (ret == 2) { } if (ret == 2) {
@ -1435,13 +1503,13 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
ret = read_rr_TF(sue, &atts); ret = read_rr_TF(sue, &atts);
if (ret < 0) { if (ret < 0) {
/* notify and continue */ /* notify and continue */
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR_WARN, ret, ret = iso_rr_msg_submit(fsdata, 1, ISO_WRONG_RR_WARN, ret,
"Invalid TF entry"); "Invalid TF entry");
} }
} else if (SUSP_SIG(sue, 'N', 'M')) { } else if (SUSP_SIG(sue, 'N', 'M')) {
if (name != NULL && namecont == 0) { if (name != NULL && namecont == 0) {
/* ups, RR standard violation */ /* ups, RR standard violation */
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR_WARN, 0, ret = iso_rr_msg_submit(fsdata, 2, ISO_WRONG_RR_WARN, 0,
"New NM entry found without previous" "New NM entry found without previous"
"CONTINUE flag. Ignored"); "CONTINUE flag. Ignored");
continue; continue;
@ -1449,13 +1517,52 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
ret = read_rr_NM(sue, &name, &namecont); ret = read_rr_NM(sue, &name, &namecont);
if (ret < 0) { if (ret < 0) {
/* notify and continue */ /* notify and continue */
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR_WARN, ret, ret = iso_rr_msg_submit(fsdata, 3, ISO_WRONG_RR_WARN, ret,
"Invalid NM entry"); "Invalid NM entry");
} }
#ifdef Libisofs_syslinux_tesT
if (name != NULL && !namecont) {
struct device syslinux_dev;
struct iso_sb_info syslinux_sbi;
struct fs_info syslinux_fsi;
char *syslinux_name = NULL;
int syslinux_name_len;
syslinux_dev.src = fsdata->src;
memset(&(syslinux_sbi.root), 0, 256);
syslinux_sbi.do_rr = 1;
syslinux_sbi.susp_skip = 0;
syslinux_fsi.fs_dev = &syslinux_dev;
syslinux_fsi.fs_info = &syslinux_sbi;
ret = susp_rr_get_nm(&syslinux_fsi, (char *) record,
&syslinux_name, &syslinux_name_len);
if (ret == 1) {
if (name == NULL || syslinux_name == NULL)
fprintf(stderr, "################ Hoppla. NULL\n");
else if(strcmp(syslinux_name, name) != 0)
fprintf(stderr,
"################ libisofs '%s' != '%s' susp_rr_get_nm()\n",
name, syslinux_name);
} else if (ret == 0) {
fprintf(stderr,
"################ '%s' not found by susp_rr_get_nm()\n", name);
} else {
fprintf(stderr, "################ 'susp_rr_get_nm() returned error\n");
}
if (syslinux_name != NULL)
free(syslinux_name);
}
#endif /* Libisofs_syslinux_tesT */
} else if (SUSP_SIG(sue, 'S', 'L')) { } else if (SUSP_SIG(sue, 'S', 'L')) {
if (linkdest != NULL && linkdestcont == 0) { if (linkdest != NULL && linkdestcont == 0) {
/* ups, RR standard violation */ /* ups, RR standard violation */
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR_WARN, 0, ret = iso_rr_msg_submit(fsdata, 4, ISO_WRONG_RR_WARN, 0,
"New SL entry found without previous" "New SL entry found without previous"
"CONTINUE flag. Ignored"); "CONTINUE flag. Ignored");
continue; continue;
@ -1463,7 +1570,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
ret = read_rr_SL(sue, &linkdest, &linkdestcont); ret = read_rr_SL(sue, &linkdest, &linkdestcont);
if (ret < 0) { if (ret < 0) {
/* notify and continue */ /* notify and continue */
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR_WARN, ret, ret = iso_rr_msg_submit(fsdata, 5, ISO_WRONG_RR_WARN, ret,
"Invalid SL entry"); "Invalid SL entry");
} }
} else if (SUSP_SIG(sue, 'R', 'E')) { } else if (SUSP_SIG(sue, 'R', 'E')) {
@ -1484,7 +1591,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
*/ */
relocated_dir = iso_read_bb(sue->data.CL.child_loc, 4, NULL); relocated_dir = iso_read_bb(sue->data.CL.child_loc, 4, NULL);
if (relocated_dir == 0) { if (relocated_dir == 0) {
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR, 0, ret = iso_rr_msg_submit(fsdata, 6, ISO_WRONG_RR, 0,
"Invalid SL entry, no child location"); "Invalid SL entry, no child location");
break; break;
} }
@ -1492,11 +1599,11 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
ret = read_rr_PN(sue, &atts); ret = read_rr_PN(sue, &atts);
if (ret < 0) { if (ret < 0) {
/* notify and continue */ /* notify and continue */
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR_WARN, ret, ret = iso_rr_msg_submit(fsdata, 7, ISO_WRONG_RR_WARN, ret,
"Invalid PN entry"); "Invalid PN entry");
} }
} else if (SUSP_SIG(sue, 'S', 'F')) { } else if (SUSP_SIG(sue, 'S', 'F')) {
ret = iso_msg_submit(fsdata->msgid, ISO_UNSUPPORTED_RR, 0, ret = iso_rr_msg_submit(fsdata, 8, ISO_UNSUPPORTED_RR, 0,
"Sparse files not supported."); "Sparse files not supported.");
break; break;
} else if (SUSP_SIG(sue, 'R', 'R')) { } else if (SUSP_SIG(sue, 'R', 'R')) {
@ -1512,7 +1619,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
*/ */
if (!(flag & 1)) { if (!(flag & 1)) {
/* notify and continue */ /* notify and continue */
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR, 0, ret = iso_rr_msg_submit(fsdata, 9, ISO_WRONG_RR, 0,
"SP entry found in a directory entry other " "SP entry found in a directory entry other "
"than '.' entry of root node"); "than '.' entry of root node");
} }
@ -1524,7 +1631,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
*/ */
if (!(flag & 1)) { if (!(flag & 1)) {
/* notify and continue */ /* notify and continue */
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR, 0, ret = iso_rr_msg_submit(fsdata, 10, ISO_WRONG_RR, 0,
"ER entry found in a directory entry other " "ER entry found in a directory entry other "
"than '.' entry of root node"); "than '.' entry of root node");
} }
@ -1539,7 +1646,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
&prev_field, &aa_done, 0); &prev_field, &aa_done, 0);
if (ret < 0) { if (ret < 0) {
/* notify and continue */ /* notify and continue */
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR_WARN, ret, ret = iso_rr_msg_submit(fsdata, 11, ISO_WRONG_RR_WARN, ret,
"Invalid AA entry"); "Invalid AA entry");
continue; continue;
} }
@ -1550,7 +1657,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
&prev_field, &aa_done, 0); &prev_field, &aa_done, 0);
if (ret < 0) { if (ret < 0) {
/* notify and continue */ /* notify and continue */
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR_WARN, ret, ret = iso_rr_msg_submit(fsdata, 12, ISO_WRONG_RR_WARN, ret,
"Invalid AL entry"); "Invalid AL entry");
continue; continue;
} }
@ -1563,7 +1670,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
&zisofs_bsl2, &zisofs_usize, 0); &zisofs_bsl2, &zisofs_usize, 0);
if (ret < 0 || zisofs_alg[0] != 'p' || zisofs_alg[1] != 'z') { if (ret < 0 || zisofs_alg[0] != 'p' || zisofs_alg[1] != 'z') {
/* notify and continue */ /* notify and continue */
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR_WARN, ret, ret = iso_rr_msg_submit(fsdata, 13, ISO_WRONG_RR_WARN, ret,
"Invalid ZF entry"); "Invalid ZF entry");
zisofs_hs4 = 0; zisofs_hs4 = 0;
continue; continue;
@ -1589,17 +1696,17 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
/* error was already submitted above */ /* error was already submitted above */
iso_msg_debug(fsdata->msgid, "Error parsing RR entries"); iso_msg_debug(fsdata->msgid, "Error parsing RR entries");
} else if (!relocated_dir && atts.st_mode == (mode_t) 0 ) { } else if (!relocated_dir && atts.st_mode == (mode_t) 0 ) {
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR, 0, "Mandatory " ret = iso_rr_msg_submit(fsdata, 14, ISO_WRONG_RR, 0, "Mandatory "
"Rock Ridge PX entry is not present or it " "Rock Ridge PX entry is not present or it "
"contains invalid values."); "contains invalid values.");
} else { } else {
/* ensure both name and link dest are finished */ /* ensure both name and link dest are finished */
if (namecont != 0) { if (namecont != 0) {
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR, 0, ret = iso_rr_msg_submit(fsdata, 15, ISO_WRONG_RR, 0,
"Incomplete RR name, last NM entry continues"); "Incomplete Rock Ridge name, last NM entry continues");
} }
if (linkdestcont != 0) { if (linkdestcont != 0) {
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR, 0, ret = iso_rr_msg_submit(fsdata, 16, ISO_WRONG_RR, 0,
"Incomplete link destination, last SL entry continues"); "Incomplete link destination, last SL entry continues");
} }
} }
@ -1613,6 +1720,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
ret = iso_aa_lookup_attr(aa_string, "isofs.cs", ret = iso_aa_lookup_attr(aa_string, "isofs.cs",
&cs_value_length, &cs_value, 0); &cs_value_length, &cs_value, 0);
if (ret == 1) { if (ret == 1) {
LIBISO_FREE_MEM(msg);
LIBISO_ALLOC_MEM(msg, char, 160); LIBISO_ALLOC_MEM(msg, char, 160);
if (fsdata->auto_input_charset & 1) { if (fsdata->auto_input_charset & 1) {
if (fsdata->input_charset != NULL) if (fsdata->input_charset != NULL)
@ -1640,10 +1748,13 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
&newname); &newname);
if (ret < 0) { if (ret < 0) {
/* its just a hint message */ /* its just a hint message */
ret = iso_msg_submit(fsdata->msgid, ISO_FILENAME_WRONG_CHARSET, LIBISO_FREE_MEM(msg);
ret, "Charset conversion error. Cannot " LIBISO_ALLOC_MEM(msg, char, 160);
"convert from %s to %s", sprintf(msg,
"Charset conversion error. Cannot convert from %.40s to %.40s",
fsdata->input_charset, fsdata->local_charset); fsdata->input_charset, fsdata->local_charset);
ret = iso_rr_msg_submit(fsdata, 17, ISO_FILENAME_WRONG_CHARSET,
ret, msg);
free(newname); free(newname);
if (ret < 0) { if (ret < 0) {
free(name); free(name);
@ -1662,10 +1773,13 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
ret = strconv(linkdest, fsdata->input_charset, ret = strconv(linkdest, fsdata->input_charset,
fsdata->local_charset, &newlinkdest); fsdata->local_charset, &newlinkdest);
if (ret < 0) { if (ret < 0) {
ret = iso_msg_submit(fsdata->msgid, ISO_FILENAME_WRONG_CHARSET, LIBISO_FREE_MEM(msg);
ret, "Charset conversion error. Cannot " LIBISO_ALLOC_MEM(msg, char, 160);
"convert from %s to %s", sprintf(msg,
"Charset conversion error. Cannot convert from %.40s to %.40s",
fsdata->input_charset, fsdata->local_charset); fsdata->input_charset, fsdata->local_charset);
ret = iso_rr_msg_submit(fsdata, 17, ISO_FILENAME_WRONG_CHARSET,
ret, msg);
free(newlinkdest); free(newlinkdest);
if (ret < 0) { if (ret < 0) {
free(name); free(name);
@ -1788,7 +1902,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
/* TODO #00014 : more sanity checks to ensure dir record info is valid */ /* TODO #00014 : more sanity checks to ensure dir record info is valid */
if (S_ISLNK(atts.st_mode) && (linkdest == NULL)) { if (S_ISLNK(atts.st_mode) && (linkdest == NULL)) {
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR, 0, ret = iso_rr_msg_submit(fsdata, 18, ISO_WRONG_RR, 0,
"Link without destination."); "Link without destination.");
free(name); free(name);
goto ex; goto ex;
@ -2089,6 +2203,10 @@ void ifs_fs_free(IsoFilesystem *fs)
free(data->copyright_file_id); free(data->copyright_file_id);
free(data->abstract_file_id); free(data->abstract_file_id);
free(data->biblio_file_id); free(data->biblio_file_id);
free(data->creation_time);
free(data->modification_time);
free(data->expiration_time);
free(data->effective_time);
free(data->input_charset); free(data->input_charset);
free(data->local_charset); free(data->local_charset);
@ -2123,6 +2241,27 @@ int read_root_susp_entries(_ImageFsData *data, uint32_t block)
/* record will be the "." directory entry for the root record */ /* record will be the "." directory entry for the root record */
record = (struct ecma119_dir_record *)buffer; record = (struct ecma119_dir_record *)buffer;
#ifdef Libisofs_syslinux_tesT
{
struct device syslinux_dev;
struct iso_sb_info syslinux_sbi;
struct fs_info syslinux_fsi;
syslinux_dev.src = data->src;
memcpy(&(syslinux_sbi.root), (char *) record, 256);
syslinux_sbi.do_rr = 1;
syslinux_sbi.susp_skip = 0;
syslinux_fsi.fs_dev = &syslinux_dev;
syslinux_fsi.fs_info = &syslinux_sbi;
ret = susp_rr_check_signatures(&syslinux_fsi, 1);
fprintf(stderr, "--------- susp_rr_check_signatures == %d , syslinux_sbi.do_rr == %d\n", ret, syslinux_sbi.do_rr);
}
#endif /* Libisofs_syslinux_tesT */
/* /*
* TODO #00015 : take care of CD-ROM XA discs when reading SP entry * TODO #00015 : take care of CD-ROM XA discs when reading SP entry
* SUSP specification claims that for CD-ROM XA the SP entry * SUSP specification claims that for CD-ROM XA the SP entry
@ -2318,6 +2457,14 @@ int read_pvm(_ImageFsData *data, uint32_t block)
data->abstract_file_id[0] = 0; data->abstract_file_id[0] = 0;
data->biblio_file_id[0] = 0; data->biblio_file_id[0] = 0;
} }
data->creation_time =
iso_util_strcopy_untail((char*) pvm->vol_creation_time, 17);
data->modification_time =
iso_util_strcopy_untail((char*) pvm->vol_modification_time, 17);
data->expiration_time =
iso_util_strcopy_untail((char*) pvm->vol_expiration_time, 17);
data->effective_time =
iso_util_strcopy_untail((char*) pvm->vol_effective_time, 17);
data->nblocks = iso_read_bb(pvm->vol_space_size, 4, NULL); data->nblocks = iso_read_bb(pvm->vol_space_size, 4, NULL);
@ -2607,6 +2754,8 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
data->bootblocks[i] = 0; data->bootblocks[i] = 0;
data->inode_counter = 0; data->inode_counter = 0;
data->px_ino_status = 0; data->px_ino_status = 0;
data->rr_err_reported = 0;
data->rr_err_repeated = 0;
data->local_charset = strdup(iso_get_local_charset(0)); data->local_charset = strdup(iso_get_local_charset(0));
@ -2857,9 +3006,9 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
{ {
int ret, idx, to_copy; int ret, idx, to_copy;
struct stat info; struct stat info;
IsoNode *new; IsoNode *new = NULL;
IsoBoot *bootcat; IsoBoot *bootcat;
char *name; char *name = NULL;
char *dest = NULL; char *dest = NULL;
ImageFileSourceData *data; ImageFileSourceData *data;
_ImageFsData *fsdata; _ImageFsData *fsdata;
@ -2887,7 +3036,6 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
goto ex; goto ex;
} }
new = NULL;
switch (info.st_mode & S_IFMT) { switch (info.st_mode & S_IFMT) {
case S_IFREG: case S_IFREG:
{ {
@ -2901,9 +3049,8 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
"More than one catalog node has been found. " "More than one catalog node has been found. "
"We can continue, but that could lead to " "We can continue, but that could lead to "
"problems"); "problems");
if (ret < 0) { if (ret < 0)
goto ex; goto ex;
}
iso_node_unref((IsoNode*)image->bootcat->node); iso_node_unref((IsoNode*)image->bootcat->node);
} }
@ -2911,9 +3058,7 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
* a regular file */ * a regular file */
new = calloc(1, sizeof(IsoBoot)); new = calloc(1, sizeof(IsoBoot));
if (new == NULL) { if (new == NULL) {
ret = ISO_OUT_OF_MEM; ret = ISO_OUT_OF_MEM; goto ex;
free(name);
goto ex;
} }
bootcat = (IsoBoot *) new; bootcat = (IsoBoot *) new;
bootcat->lba = data->sections[0].block; bootcat->lba = data->sections[0].block;
@ -2924,10 +3069,7 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
if (bootcat->size > 0) { if (bootcat->size > 0) {
bootcat->content = calloc(1, bootcat->size); bootcat->content = calloc(1, bootcat->size);
if (bootcat->content == NULL) { if (bootcat->content == NULL) {
ret = ISO_OUT_OF_MEM; ret = ISO_OUT_OF_MEM; goto ex;
free(name);
free(new);
goto ex;
} }
to_copy = bootcat->size; to_copy = bootcat->size;
if (bootcat->size > fsdata->catsize) if (bootcat->size > fsdata->catsize)
@ -2944,16 +3086,14 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
IsoFile *file; IsoFile *file;
ret = iso_file_source_stream_new(src, &stream); ret = iso_file_source_stream_new(src, &stream);
if (ret < 0) { if (ret < 0)
free(name);
goto ex; goto ex;
}
/* take a ref to the src, as stream has taken our ref */ /* take a ref to the src, as stream has taken our ref */
iso_file_source_ref(src); iso_file_source_ref(src);
file = calloc(1, sizeof(IsoFile)); file = calloc(1, sizeof(IsoFile));
if (file == NULL) { if (file == NULL) {
free(name);
iso_stream_unref(stream); iso_stream_unref(stream);
{ret = ISO_OUT_OF_MEM; goto ex;} {ret = ISO_OUT_OF_MEM; goto ex;}
} }
@ -2977,7 +3117,6 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
data->block_size_log2, data->block_size_log2,
data->uncompressed_size, 0); data->uncompressed_size, 0);
if (ret < 0) { if (ret < 0) {
free(name);
iso_stream_unref(stream); iso_stream_unref(stream);
goto ex; goto ex;
} }
@ -3008,7 +3147,6 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
ret = iso_msg_submit(image->id, ISO_EL_TORITO_WARN, 0, ret = iso_msg_submit(image->id, ISO_EL_TORITO_WARN, 0,
"More than one ISO node has been found for the same boot image."); "More than one ISO node has been found for the same boot image.");
if (ret < 0) { if (ret < 0) {
free(name);
iso_stream_unref(stream); iso_stream_unref(stream);
goto ex; goto ex;
} }
@ -3026,7 +3164,6 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
/* source is a directory */ /* source is a directory */
new = calloc(1, sizeof(IsoDir)); new = calloc(1, sizeof(IsoDir));
if (new == NULL) { if (new == NULL) {
free(name);
{ret = ISO_OUT_OF_MEM; goto ex;} {ret = ISO_OUT_OF_MEM; goto ex;}
} }
new->type = LIBISO_DIR; new->type = LIBISO_DIR;
@ -3042,12 +3179,10 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
ret = iso_file_source_readlink(src, dest, LIBISOFS_NODE_PATH_MAX); ret = iso_file_source_readlink(src, dest, LIBISOFS_NODE_PATH_MAX);
if (ret < 0) { if (ret < 0) {
free(name);
goto ex; goto ex;
} }
link = calloc(1, sizeof(IsoSymlink)); link = calloc(1, sizeof(IsoSymlink));
if (link == NULL) { if (link == NULL) {
free(name);
{ret = ISO_OUT_OF_MEM; goto ex;} {ret = ISO_OUT_OF_MEM; goto ex;}
} }
link->dest = strdup(dest); link->dest = strdup(dest);
@ -3068,8 +3203,7 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
IsoSpecial *special; IsoSpecial *special;
special = calloc(1, sizeof(IsoSpecial)); special = calloc(1, sizeof(IsoSpecial));
if (special == NULL) { if (special == NULL) {
free(name); ret = ISO_OUT_OF_MEM; goto ex;
{ret = ISO_OUT_OF_MEM; goto ex;}
} }
special->dev = info.st_rdev; special->dev = info.st_rdev;
special->node.type = LIBISO_SPECIAL; special->node.type = LIBISO_SPECIAL;
@ -3080,11 +3214,12 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
new->refcount = 0; new->refcount = 0;
} }
break; break;
default:
ret = ISO_BAD_ISO_FILETYPE; goto ex;
} }
/* fill fields */ /* fill fields */
new->refcount++; new->refcount++;
new->name = name; new->name = name; name = NULL;
new->mode = info.st_mode; new->mode = info.st_mode;
new->uid = info.st_uid; new->uid = info.st_uid;
new->gid = info.st_gid; new->gid = info.st_gid;
@ -3099,7 +3234,7 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
ret = src_aa_to_node(src, new, 0); ret = src_aa_to_node(src, new, 0);
if (ret < 0) { if (ret < 0) {
goto failure; goto ex;
} }
/* Attach ino as xinfo if valid and no IsoStream is involved */ /* Attach ino as xinfo if valid and no IsoStream is involved */
@ -3107,18 +3242,17 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
!fsdata->make_new_ino) { !fsdata->make_new_ino) {
ret = iso_node_set_ino(new, info.st_ino, 0); ret = iso_node_set_ino(new, info.st_ino, 0);
if (ret < 0) if (ret < 0)
goto failure; goto ex;
} }
*node = new; *node = new; new = NULL;
{ret = ISO_SUCCESS; goto ex;} {ret = ISO_SUCCESS; goto ex;}
failure:; ex:;
/* todo: stuff any possible memory leak here */
if (name != NULL) if (name != NULL)
free(name); free(name);
free(new); if (new != NULL)
ex:; iso_node_unref(new);
LIBISO_FREE_MEM(dest); LIBISO_FREE_MEM(dest);
return ret; return ret;
} }
@ -3241,13 +3375,14 @@ static
int iso_image_eval_boot_info_table(IsoImage *image, struct iso_read_opts *opts, int iso_image_eval_boot_info_table(IsoImage *image, struct iso_read_opts *opts,
IsoDataSource *src, uint32_t iso_image_size, int flag) IsoDataSource *src, uint32_t iso_image_size, int flag)
{ {
int i, ret, section_count, todo, chunk; int i, j, ret, section_count, todo, chunk;
uint32_t img_lba, img_size, boot_pvd_found, image_pvd, alleged_size; uint32_t img_lba, img_size, boot_pvd_found, image_pvd, alleged_size;
struct iso_file_section *sections = NULL; struct iso_file_section *sections = NULL;
struct el_torito_boot_image *boot; struct el_torito_boot_image *boot;
uint8_t *boot_image_buf = NULL, boot_info_found[16], *buf = NULL; uint8_t *boot_image_buf = NULL, boot_info_found[16], *buf = NULL;
IsoStream *stream = NULL; IsoStream *stream = NULL;
IsoFile *boot_file; IsoFile *boot_file;
uint64_t blk;
if (image->bootcat == NULL) if (image->bootcat == NULL)
{ret = ISO_SUCCESS; goto ex;} {ret = ISO_SUCCESS; goto ex;}
@ -3256,6 +3391,7 @@ int iso_image_eval_boot_info_table(IsoImage *image, struct iso_read_opts *opts,
boot = image->bootcat->bootimages[i]; boot = image->bootcat->bootimages[i];
boot_file = boot->image; boot_file = boot->image;
boot->seems_boot_info_table = 0; boot->seems_boot_info_table = 0;
boot->seems_grub2_boot_info = 0;
img_size = iso_file_get_size(boot_file); img_size = iso_file_get_size(boot_file);
if (img_size > Libisofs_boot_image_max_sizE || img_size < 64) if (img_size > Libisofs_boot_image_max_sizE || img_size < 64)
continue; continue;
@ -3321,6 +3457,16 @@ int iso_image_eval_boot_info_table(IsoImage *image, struct iso_read_opts *opts,
goto ex; goto ex;
if (memcmp(boot_image_buf + 8, boot_info_found, 16) == 0) if (memcmp(boot_image_buf + 8, boot_info_found, 16) == 0)
boot->seems_boot_info_table = 1; boot->seems_boot_info_table = 1;
if (img_size >= Libisofs_grub2_elto_patch_poS + 8) {
blk = 0;
for (j = Libisofs_grub2_elto_patch_poS + 7;
j >= Libisofs_grub2_elto_patch_poS; j--)
blk = (blk << 8) | boot_image_buf[j];
if (blk == img_lba * 4 + Libisofs_grub2_elto_patch_offsT)
boot->seems_grub2_boot_info = 1;
}
free(boot_image_buf); free(boot_image_buf);
boot_image_buf = NULL; boot_image_buf = NULL;
} }
@ -3526,7 +3672,7 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
/* warn about hidden images */ /* warn about hidden images */
iso_msg_submit(image->id, ISO_EL_TORITO_HIDDEN, 0, iso_msg_submit(image->id, ISO_EL_TORITO_HIDDEN, 0,
"Found hidden El-Torito image. Its size could not " "Found hidden El-Torito image. Its size could not "
"be figure out, so image modify or boot image " "be figured out, so image modify or boot image "
"patching may lead to bad results."); "patching may lead to bad results.");
} }
if (image->bootcat->node == NULL) { if (image->bootcat->node == NULL) {
@ -3568,6 +3714,8 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
iso_image_set_copyright_file_id(image, data->copyright_file_id); iso_image_set_copyright_file_id(image, data->copyright_file_id);
iso_image_set_abstract_file_id(image, data->abstract_file_id); iso_image_set_abstract_file_id(image, data->abstract_file_id);
iso_image_set_biblio_file_id(image, data->biblio_file_id); iso_image_set_biblio_file_id(image, data->biblio_file_id);
iso_image_set_pvd_times(image, data->creation_time,
data->modification_time, data->expiration_time, data->effective_time);
if (features != NULL) { if (features != NULL) {
*features = malloc(sizeof(IsoReadImageFeatures)); *features = malloc(sizeof(IsoReadImageFeatures));

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2007 Vreixo Formoso * Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2012 Thomas Schmitt * Copyright (c) 2009 - 2013 Thomas Schmitt
* *
* This file is part of the libisofs project; you can redistribute it and/or * 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 * modify it under the terms of the GNU General Public License version 2
@ -83,6 +83,7 @@ int iso_image_new(const char *name, IsoImage **image)
img->num_mips_boot_files = 0; img->num_mips_boot_files = 0;
for (i = 0; i < 15; i++) for (i = 0; i < 15; i++)
img->mips_boot_file_paths[i] = NULL; img->mips_boot_file_paths[i] = NULL;
img->sparc_core_node = NULL;
img->builder_ignore_acl = 1; img->builder_ignore_acl = 1;
img->builder_ignore_ea = 1; img->builder_ignore_ea = 1;
img->inode_counter = 0; img->inode_counter = 0;
@ -136,6 +137,8 @@ void iso_image_unref(IsoImage *image)
iso_filesystem_unref(image->fs); iso_filesystem_unref(image->fs);
el_torito_boot_catalog_free(image->bootcat); el_torito_boot_catalog_free(image->bootcat);
iso_image_give_up_mips_boot(image, 0); iso_image_give_up_mips_boot(image, 0);
if (image->sparc_core_node != NULL)
iso_node_unref((IsoNode *) image->sparc_core_node);
free(image->volset_id); free(image->volset_id);
free(image->volume_id); free(image->volume_id);
free(image->publisher_id); free(image->publisher_id);
@ -145,6 +148,10 @@ void iso_image_unref(IsoImage *image)
free(image->copyright_file_id); free(image->copyright_file_id);
free(image->abstract_file_id); free(image->abstract_file_id);
free(image->biblio_file_id); free(image->biblio_file_id);
free(image->creation_time);
free(image->modification_time);
free(image->expiration_time);
free(image->effective_time);
if (image->used_inodes != NULL) if (image->used_inodes != NULL)
free(image->used_inodes); free(image->used_inodes);
if (image->system_area_data != NULL) if (image->system_area_data != NULL)
@ -335,6 +342,37 @@ const char *iso_image_get_biblio_file_id(const IsoImage *image)
return image->biblio_file_id; return image->biblio_file_id;
} }
int iso_image_set_pvd_times(IsoImage *image,
char *creation_time, char *modification_time,
char *expiration_time, char *effective_time)
{
if (creation_time == NULL || modification_time == NULL ||
expiration_time == NULL || effective_time == NULL)
return ISO_NULL_POINTER;
image->creation_time = strdup(creation_time);
image->modification_time = strdup(modification_time);
image->expiration_time = strdup(expiration_time);
image->effective_time = strdup(effective_time);
if (image->creation_time == NULL || image->modification_time == NULL ||
image->expiration_time == NULL || image->effective_time == NULL)
return ISO_OUT_OF_MEM;
return ISO_SUCCESS;
}
int iso_image_get_pvd_times(IsoImage *image,
char **creation_time, char **modification_time,
char **expiration_time, char **effective_time)
{
if (image->creation_time == NULL || image->modification_time == NULL ||
image->expiration_time == NULL || image->effective_time == NULL)
return ISO_NULL_POINTER;
*creation_time = image->creation_time;
*modification_time = image->modification_time;
*expiration_time = image->expiration_time;
*effective_time = image->effective_time;
return ISO_SUCCESS;
}
int iso_image_get_msg_id(IsoImage *image) int iso_image_get_msg_id(IsoImage *image)
{ {
return image->id; return image->id;
@ -732,3 +770,24 @@ int iso_image_hfsplus_get_blessed(IsoImage *img, IsoNode ***blessed_nodes,
return 1; return 1;
} }
/* API */
int iso_image_set_sparc_core(IsoImage *img, IsoFile *sparc_core, int flag)
{
if (img->sparc_core_node != NULL)
iso_node_unref((IsoNode *) img->sparc_core_node);
img->sparc_core_node = sparc_core;
if (sparc_core != NULL)
iso_node_ref((IsoNode *) sparc_core);
return 1;
}
/* API */
int iso_image_get_sparc_core(IsoImage *img, IsoFile **sparc_core, int flag)
{
*sparc_core = img->sparc_core_node;
return 1;
}

View File

@ -49,6 +49,10 @@ struct Iso_Image
char *copyright_file_id; char *copyright_file_id;
char *abstract_file_id; char *abstract_file_id;
char *biblio_file_id; char *biblio_file_id;
char *creation_time;
char *modification_time;
char *expiration_time;
char *effective_time;
/* el-torito boot catalog */ /* el-torito boot catalog */
struct el_torito_boot_catalog *bootcat; struct el_torito_boot_catalog *bootcat;
@ -65,6 +69,10 @@ struct Iso_Image
int num_mips_boot_files; int num_mips_boot_files;
char *mips_boot_file_paths[15]; /* ISO 9660 Rock Ridge Paths */ char *mips_boot_file_paths[15]; /* ISO 9660 Rock Ridge Paths */
/* A data file of which the position and size shall be written after
a SUN Disk Label.
*/
IsoFile *sparc_core_node;
/* image identifier, for message origin identifier */ /* image identifier, for message origin identifier */
int id; int id;
@ -234,4 +242,8 @@ int iso_image_set_checksums(IsoImage *image, char *checksum_array,
uint32_t idx_count, int flag); uint32_t idx_count, int flag);
int iso_image_set_pvd_times(IsoImage *image,
char *creation_time, char *modification_time,
char *expiration_time, char *effective_time);
#endif /*LIBISO_IMAGE_H_*/ #endif /*LIBISO_IMAGE_H_*/

View File

@ -83,8 +83,8 @@
* @since 0.6.2 * @since 0.6.2
*/ */
#define iso_lib_header_version_major 1 #define iso_lib_header_version_major 1
#define iso_lib_header_version_minor 2 #define iso_lib_header_version_minor 3
#define iso_lib_header_version_micro 6 #define iso_lib_header_version_micro 0
/** /**
* Get version of the libisofs library at runtime. * Get version of the libisofs library at runtime.
@ -2156,23 +2156,25 @@ int iso_write_opts_set_fifo_size(IsoWriteOpts *opts, size_t fifo_size);
* bit2-7= System area type * bit2-7= System area type
* 0= with bit0 or bit1: MBR * 0= with bit0 or bit1: MBR
* else: unspecified type which will be used unaltered. * else: unspecified type which will be used unaltered.
* @since 0.6.38
* 1= MIPS Big Endian Volume Header * 1= MIPS Big Endian Volume Header
* @since 0.6.38
* Submit up to 15 MIPS Big Endian boot files by * Submit up to 15 MIPS Big Endian boot files by
* iso_image_add_mips_boot_file(). * iso_image_add_mips_boot_file().
* This will overwrite the first 512 bytes of the submitted * This will overwrite the first 512 bytes of the submitted
* data. * data.
* 2= DEC Boot Block for MIPS Little Endian * 2= DEC Boot Block for MIPS Little Endian
* @since 0.6.38
* The first boot file submitted by * The first boot file submitted by
* iso_image_add_mips_boot_file() will be activated. * iso_image_add_mips_boot_file() will be activated.
* This will overwrite the first 512 bytes of the submitted * This will overwrite the first 512 bytes of the submitted
* data. * data.
* @since 0.6.40
* 3= SUN Disk Label for SUN SPARC * 3= SUN Disk Label for SUN SPARC
* @since 0.6.40
* Submit up to 7 SPARC boot images by * Submit up to 7 SPARC boot images by
* iso_write_opts_set_partition_img() for partition numbers 2 * iso_write_opts_set_partition_img() for partition numbers 2
* to 8. * to 8.
* This will overwrite the first 512 bytes of the submitted * This will overwrite the first 512 bytes of the submitted
* data.
* bit8-9= Only with System area type 0 = MBR * bit8-9= Only with System area type 0 = MBR
* @since 1.0.4 * @since 1.0.4
* Cylinder alignment mode eventually pads the image to make it * Cylinder alignment mode eventually pads the image to make it
@ -2191,6 +2193,13 @@ int iso_write_opts_set_fifo_size(IsoWriteOpts *opts, size_t fifo_size);
* 1 = CHRP: A single MBR partition of type 0x96 covers the * 1 = CHRP: A single MBR partition of type 0x96 covers the
* ISO image. Not compatible with any other feature * ISO image. Not compatible with any other feature
* which needs to have own MBR partition entries. * which needs to have own MBR partition entries.
* bit14= Only with System area type 0 = MBR
* GRUB2 boot provisions:
* @since 1.3.0
* Patch system area at byte 92 to 99 with 512-block address + 1
* of the first boot image file. Little-endian 8-byte.
* Should be combined with options bit0.
* Will not be in effect if options bit1 is set.
* @param flag * @param flag
* bit0 = invalidate any attached system area data. Same as data == NULL * bit0 = invalidate any attached system area data. Same as data == NULL
* (This re-activates eventually loaded image System Area data. * (This re-activates eventually loaded image System Area data.
@ -3027,6 +3036,36 @@ 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); const char *iso_image_get_biblio_file_id(const IsoImage *image);
/**
* Get the four timestamps from the Primary Volume Descriptor of the imported
* ISO image. The timestamps are strings which are either empty or consist
* of 17 digits of the form YYYYMMDDhhmmsscc.
* None of the returned string pointers shall be used for altering or freeing
* data. They are just for reading.
*
* @param image
* The image to be inquired.
* @param vol_creation_time
* Returns a pointer to the Volume Creation time:
* When "the information in the volume was created."
* @param vol_modification_time
* Returns a pointer to Volume Modification time:
* When "the information in the volume was last modified."
* @param vol_expiration_time
* Returns a pointer to Volume Expiration time:
* When "the information in the volume may be regarded as obsolete."
* @param vol_effective_time
* Returns a pointer to Volume Expiration time:
* When "the information in the volume may be used."
* @return
* ISO_SUCCESS or error
*
* @since 1.2.8
*/
int iso_image_get_pvd_times(IsoImage *image,
char **creation_time, char **modification_time,
char **expiration_time, char **effective_time);
/** /**
* Create a new set of El-Torito bootable images by adding a boot catalog * Create a new set of El-Torito bootable images by adding a boot catalog
* and the default boot image. * and the default boot image.
@ -3435,9 +3474,15 @@ int el_torito_get_selection_crit(ElToritoBootImage *bootimg, uint8_t crit[20]);
* @param bootimg * @param bootimg
* The image to inquire * The image to inquire
* @param flag * @param flag
* Reserved for future usage, set to 0. * Bitfield for control purposes:
* bit0 - bit3= mode
* 0 = inquire for classic boot info table as described in man mkisofs
* @since 0.6.32
* 1 = inquire for GRUB2 boot info as of bit9 of options of
* el_torito_set_isolinux_options()
* @since 1.3.0
* @return * @return
* 1 = seems to contain oot info table , 0 = quite surely not * 1 = seems to contain the inquired boot info, 0 = quite surely not
* @since 0.6.32 * @since 0.6.32
*/ */
int el_torito_seems_boot_info_table(ElToritoBootImage *bootimg, int flag); int el_torito_seems_boot_info_table(ElToritoBootImage *bootimg, int flag);
@ -3501,6 +3546,11 @@ int el_torito_seems_boot_info_table(ElToritoBootImage *bootimg, int flag);
* mentioned. The ISOLINUX MBR must look suitable or else an error * mentioned. The ISOLINUX MBR must look suitable or else an error
* event will happen at image generation time. * event will happen at image generation time.
* @since 1.2.4 * @since 1.2.4
* bit9= GRUB2 boot info
* Patch the boot image file at byte 1012 with the 512-block
* address + 2. Two little endian 32-bit words. Low word first.
* This is combinable with bit0.
* @since 1.3.0
* @param flag * @param flag
* Reserved for future usage, set to 0. * Reserved for future usage, set to 0.
* @return * @return
@ -3544,7 +3594,7 @@ void el_torito_patch_isolinux_image(ElToritoBootImage *bootimg);
* @param img * @param img
* The image to be inquired. * The image to be inquired.
* @param data * @param data
* A byte array of at least 32768 bytesi to take the loaded bytes. * A byte array of at least 32768 bytes to take the loaded bytes.
* @param options * @param options
* The option bits which will be applied if not overridden by * The option bits which will be applied if not overridden by
* iso_write_opts_set_system_area(). See there. * iso_write_opts_set_system_area(). See there.
@ -3608,6 +3658,41 @@ int iso_image_get_mips_boot_files(IsoImage *image, char *paths[15], int flag);
*/ */
int iso_image_give_up_mips_boot(IsoImage *image, int flag); int iso_image_give_up_mips_boot(IsoImage *image, int flag);
/**
* Designate a data file in the ISO image of which the position and size
* shall be written after the SUN Disk Label. The position is written as
* 64-bit big-endian number to byte position 0x228. The size is written
* as 32-bit big-endian to 0x230.
* This setting has an effect only if system area type is set to 3
* with iso_write_opts_set_system_area().
*
* @param img
* The image to be manipulated.
* @param sparc_core
* The IsoFile which shall be mentioned after the SUN Disk label.
* NULL is a permissible value. It disables this feature.
* @param flag
* Bitfield for control purposes, unused yet, submit 0
* @return
* 1 is success , <0 means error
* @since 1.3.0
*/
int iso_image_set_sparc_core(IsoImage *img, IsoFile *sparc_core, int flag);
/**
* Obtain the current setting of iso_image_set_sparc_core().
*
* @param img
* The image to be inquired.
* @param sparc_core
* Will return a pointer to the IsoFile (or NULL, which is not an error)
* @param flag
* Bitfield for control purposes, unused yet, submit 0
* @return
* 1 is success , <0 means error
* @since 1.3.0
*/
int iso_image_get_sparc_core(IsoImage *img, IsoFile **sparc_core, int flag);
/** /**
* Increments the reference counting of the given node. * Increments the reference counting of the given node.
@ -7424,11 +7509,14 @@ int iso_image_hfsplus_get_blessed(IsoImage *img, IsoNode ***blessed_nodes,
/** Too many chained symbolic links (FAILURE, HIGH, -395) */ /** Too many chained symbolic links (FAILURE, HIGH, -395) */
#define ISO_DEEP_SYMLINK 0xE830FE75 #define ISO_DEEP_SYMLINK 0xE830FE75
/** Unrecognized file type in ISO image (FAILURE, HIGH, -396) */
#define ISO_BAD_ISO_FILETYPE 0xE830FE74
/* Internal developer note: /* Internal developer note:
Place new error codes directly above this comment. Place new error codes directly above this comment.
Newly introduced errors must get a message entry in Newly introduced errors must get a message entry in
libisofs/message.c, function iso_error_to_msg() libisofs/messages.c, function iso_error_to_msg()
*/ */
/* ! PLACE NEW ERROR CODES ABOVE. NOT AFTER THIS LINE ! */ /* ! PLACE NEW ERROR CODES ABOVE. NOT AFTER THIS LINE ! */

View File

@ -98,8 +98,10 @@ iso_image_get_data_preparer_id;
iso_image_get_mips_boot_files; iso_image_get_mips_boot_files;
iso_image_get_msg_id; iso_image_get_msg_id;
iso_image_get_publisher_id; iso_image_get_publisher_id;
iso_image_get_pvd_times;
iso_image_get_root; iso_image_get_root;
iso_image_get_session_md5; iso_image_get_session_md5;
iso_image_get_sparc_core;
iso_image_get_system_area; iso_image_get_system_area;
iso_image_get_system_id; iso_image_get_system_id;
iso_image_get_volset_id; iso_image_get_volset_id;
@ -121,6 +123,7 @@ iso_image_set_copyright_file_id;
iso_image_set_data_preparer_id; iso_image_set_data_preparer_id;
iso_image_set_ignore_aclea; iso_image_set_ignore_aclea;
iso_image_set_publisher_id; iso_image_set_publisher_id;
iso_image_set_sparc_core;
iso_image_set_system_id; iso_image_set_system_id;
iso_image_set_volset_id; iso_image_set_volset_id;
iso_image_set_volume_id; iso_image_set_volume_id;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2009 Thomas Schmitt * Copyright (c) 2009 - 2013 Thomas Schmitt
* *
* This file is part of the libisofs project; you can redistribute it and/or * 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 * modify it under the terms of the GNU General Public License version 2
@ -527,6 +527,7 @@ int checksum_copy_old_nodes(Ecma119Image *target, IsoNode *node, int flag)
if (md5_pt == NULL) if (md5_pt == NULL)
return 0; return 0;
if (!target->will_cancel) {
ret = iso_node_lookup_attr(node, "isofs.cx", &value_length, ret = iso_node_lookup_attr(node, "isofs.cx", &value_length,
&value, 0); &value, 0);
if (ret == 1 && value_length == 4) { if (ret == 1 && value_length == 4) {
@ -538,7 +539,13 @@ int checksum_copy_old_nodes(Ecma119Image *target, IsoNode *node, int flag)
} }
if (value != NULL) if (value != NULL)
free(value); free(value);
/* ts B30114 : It is unclear why these are removed here.
At least with the opts->will_cancel runs,
this is not appropriate.
*/
iso_node_remove_xinfo(node, checksum_md5_xinfo_func); iso_node_remove_xinfo(node, checksum_md5_xinfo_func);
}
iso_node_remove_xinfo(node, checksum_cx_xinfo_func); iso_node_remove_xinfo(node, checksum_cx_xinfo_func);
} }
} else if (node->type == LIBISO_DIR) { } else if (node->type == LIBISO_DIR) {

View File

@ -344,9 +344,9 @@ const char *iso_error_to_msg(int errcode)
case ISO_WRONG_PVD: case ISO_WRONG_PVD:
return "Wrong or damaged Primary Volume Descriptor"; return "Wrong or damaged Primary Volume Descriptor";
case ISO_WRONG_RR: case ISO_WRONG_RR:
return "Wrong or damaged RR entry"; return "Wrong or damaged Rock Ridge entry";
case ISO_UNSUPPORTED_RR: case ISO_UNSUPPORTED_RR:
return "Unsupported RR feature"; return "Unsupported Rock Ridge feature";
case ISO_WRONG_ECMA119: case ISO_WRONG_ECMA119:
return "Wrong or damaged ECMA-119"; return "Wrong or damaged ECMA-119";
case ISO_UNSUPPORTED_ECMA119: case ISO_UNSUPPORTED_ECMA119:
@ -360,9 +360,9 @@ const char *iso_error_to_msg(int errcode)
case ISO_UNSUPPORTED_SUSP: case ISO_UNSUPPORTED_SUSP:
return "Unsupported SUSP feature"; return "Unsupported SUSP feature";
case ISO_WRONG_RR_WARN: case ISO_WRONG_RR_WARN:
return "Error on a RR entry that can be ignored"; return "Error on a Rock Ridge entry that can be ignored";
case ISO_SUSP_UNHANDLED: case ISO_SUSP_UNHANDLED:
return "Error on a RR entry that can be ignored"; return "Unhandled SUSP entry";
case ISO_SUSP_MULTIPLE_ER: case ISO_SUSP_MULTIPLE_ER:
return "Multiple ER SUSP entries found"; return "Multiple ER SUSP entries found";
case ISO_UNSUPPORTED_VD: case ISO_UNSUPPORTED_VD:
@ -500,6 +500,8 @@ const char *iso_error_to_msg(int errcode)
return "Symbolic link cannot be resolved"; return "Symbolic link cannot be resolved";
case ISO_DEEP_SYMLINK: case ISO_DEEP_SYMLINK:
return "Too many chained symbolic links"; return "Too many chained symbolic links";
case ISO_BAD_ISO_FILETYPE:
return "Unrecognized file type in ISO image";
default: default:
return "Unknown error"; return "Unknown error";
} }

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2008 Vreixo Formoso * Copyright (c) 2008 Vreixo Formoso
* Copyright (c) 2010 - 2012 Thomas Schmitt * Copyright (c) 2010 - 2013 Thomas Schmitt
* *
* This file is part of the libisofs project; you can redistribute it and/or * This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2 * modify it under the terms of the GNU General Public License version 2
@ -72,21 +72,25 @@ static int precompute_gpt(Ecma119Image *t);
/* /*
* @param flag bit0= img_blocks is start address rather than end address: * @param flag bit0= img_blocks is start address rather than end address:
do not subtract 1 do not subtract 1
bit1= img_blocks is counted in 512-byte units rather than 2 KiB
*/ */
static static
void iso_compute_cyl_head_sec(uint32_t *img_blocks, int hpc, int sph, void iso_compute_cyl_head_sec(uint64_t img_blocks, int hpc, int sph,
uint32_t *end_lba, uint32_t *end_sec, uint32_t *end_lba, uint32_t *end_sec,
uint32_t *end_head, uint32_t *end_cyl, int flag) uint32_t *end_head, uint32_t *end_cyl, int flag)
{ {
uint32_t secs; uint64_t secs;
/* Partition table unit is 512 bytes per sector, ECMA-119 unit is 2048 */ if(flag & 2)
if (*img_blocks >= 0x40000000) secs = img_blocks;
*img_blocks = 0x40000000 - 1; /* truncate rather than roll over */
if (flag & 1)
secs = *end_lba = *img_blocks * 4; /* first valid 512-lba */
else else
secs = *end_lba = *img_blocks * 4 - 1; /* last valid 512-lba */ secs = img_blocks * 4;
if (secs > (uint64_t) 0xfffffffc)
secs = 0xfffffffc; /* truncate rather than roll over */
if (flag & 1)
*end_lba = secs; /* first valid 512-lba */
else
secs = *end_lba = secs - 1; /* last valid 512-lba */
*end_cyl = secs / (sph * hpc); *end_cyl = secs / (sph * hpc);
secs -= *end_cyl * sph * hpc; secs -= *end_cyl * sph * hpc;
*end_head = secs / sph; *end_head = secs / sph;
@ -165,10 +169,12 @@ int iso_compute_append_partitions(Ecma119Image *t, int flag)
} }
/* Note: partition_offset and partition_size are counted in 2048 blocks /* @param flag
bit1= partition_offset and partition_size are counted in
blocks of 512 rather than 2048
*/ */
static int write_mbr_partition_entry(int partition_number, int partition_type, static int write_mbr_partition_entry(int partition_number, int partition_type,
uint32_t partition_offset, uint32_t partition_size, uint64_t partition_offset, uint64_t partition_size,
int sph, int hpc, uint8_t *buf, int flag) int sph, int hpc, uint8_t *buf, int flag)
{ {
uint8_t *wpt; uint8_t *wpt;
@ -178,10 +184,12 @@ static int write_mbr_partition_entry(int partition_number, int partition_type,
int i; int i;
after_end = partition_offset + partition_size; after_end = partition_offset + partition_size;
iso_compute_cyl_head_sec(&partition_offset, hpc, sph, iso_compute_cyl_head_sec((uint64_t) partition_offset, hpc, sph,
&start_lba, &start_sec, &start_head, &start_cyl, 1); &start_lba, &start_sec, &start_head, &start_cyl,
iso_compute_cyl_head_sec(&after_end, hpc, sph, 1 | (flag & 2));
&end_lba, &end_sec, &end_head, &end_cyl, 0); iso_compute_cyl_head_sec((uint64_t) after_end, hpc, sph,
&end_lba, &end_sec, &end_head, &end_cyl,
(flag & 2));
wpt = buf + 446 + (partition_number - 1) * 16; wpt = buf + 446 + (partition_number - 1) * 16;
/* Not bootable */ /* Not bootable */
@ -244,7 +252,7 @@ int make_grub_msdos_label(uint32_t img_blocks, int sph, int hpc,
uint32_t end_lba, end_sec, end_head, end_cyl; uint32_t end_lba, end_sec, end_head, end_cyl;
int i; int i;
iso_compute_cyl_head_sec(&img_blocks, hpc, sph, iso_compute_cyl_head_sec((uint64_t) img_blocks, hpc, sph,
&end_lba, &end_sec, &end_head, &end_cyl, 0); &end_lba, &end_sec, &end_head, &end_cyl, 0);
/* 1) Zero-fill 446-510 */ /* 1) Zero-fill 446-510 */
@ -308,9 +316,9 @@ int iso_offset_partition_start(uint32_t img_blocks, uint32_t partition_offset,
uint32_t start_lba, start_sec, start_head, start_cyl; uint32_t start_lba, start_sec, start_head, start_cyl;
int i; int i;
iso_compute_cyl_head_sec(&partition_offset, hpc, sph, iso_compute_cyl_head_sec((uint64_t) partition_offset, hpc, sph,
&start_lba, &start_sec, &start_head, &start_cyl, 1); &start_lba, &start_sec, &start_head, &start_cyl, 1);
iso_compute_cyl_head_sec(&img_blocks, hpc, sph, iso_compute_cyl_head_sec((uint64_t) img_blocks, hpc, sph,
&end_lba, &end_sec, &end_head, &end_cyl, 0); &end_lba, &end_sec, &end_head, &end_cyl, 0);
wpt = buf + 446; wpt = buf + 446;
@ -691,7 +699,8 @@ static int write_sun_partition_entry(int partition_number,
*/ */
static int make_sun_disk_label(Ecma119Image *t, uint8_t *buf, int flag) static int make_sun_disk_label(Ecma119Image *t, uint8_t *buf, int flag)
{ {
int ret; int ret, i;
uint64_t blk;
/* Bytes 512 to 32767 may come from image or external file */ /* Bytes 512 to 32767 may come from image or external file */
memset(buf, 0, 512); memset(buf, 0, 512);
@ -733,6 +742,16 @@ static int make_sun_disk_label(Ecma119Image *t, uint8_t *buf, int flag)
/* 508 - 509 | 0xdabe | Magic Number */ /* 508 - 509 | 0xdabe | Magic Number */
iso_msb(buf + 508, 0xdabe, 2); iso_msb(buf + 508, 0xdabe, 2);
if (t->sparc_core_src != NULL) {
/* May be used for grub-sparc. */
blk= ((uint64_t) t->sparc_core_src->sections[0].block) *
(uint64_t) 2048;
for (i = 0; i < 8; i++)
buf[Libisofs_grub2_sparc_patch_adr_poS + i] = blk >> ((7 - i) * 8);
iso_msb(buf + Libisofs_grub2_sparc_patch_size_poS,
t->sparc_core_src->sections[0].size, 4);
}
/* Set partition 1 to describe ISO image and compute checksum */ /* Set partition 1 to describe ISO image and compute checksum */
t->appended_part_start[0] = 0; t->appended_part_start[0] = 0;
t->appended_part_size[0] = t->curblock; t->appended_part_size[0] = t->curblock;
@ -794,7 +813,7 @@ int iso_quick_gpt_entry(Ecma119Image *t,
int iso_quick_mbr_entry(Ecma119Image *t, int iso_quick_mbr_entry(Ecma119Image *t,
uint32_t start_block, uint32_t block_count, uint64_t start_block, uint64_t block_count,
uint8_t type_byte, uint8_t status_byte, uint8_t type_byte, uint8_t status_byte,
int desired_slot) int desired_slot)
{ {
@ -880,7 +899,7 @@ static int iso_write_apm_entry(Ecma119Image *t, int apm_block_size,
else else
block_fac = 2048 / apm_block_size; block_fac = 2048 / apm_block_size;
memset(buf, apm_block_size, 0); memset(buf, 0, apm_block_size);
wpt = buf; wpt = buf;
/* Signature */ /* Signature */
@ -1115,10 +1134,11 @@ static int iso_write_mbr(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf)
/* <<< Dummy mock-up */ /* <<< Dummy mock-up */
if (t->mbr_req_count <= 0) { if (t->mbr_req_count <= 0) {
ret = iso_quick_mbr_entry(t, 0, 0, 0xee, 0, 0); ret = iso_quick_mbr_entry(t, (uint64_t) 0, (uint64_t) 0, 0xee, 0, 0);
if (ret < 0) if (ret < 0)
return ret; return ret;
ret = iso_quick_mbr_entry(t, 100, 0, 0x0c, 0x80, 1); ret = iso_quick_mbr_entry(t, ((uint64_t) 100) * 4, (uint64_t) 0,
0x0c, 0x80, 1);
if (ret < 0) if (ret < 0)
return ret; return ret;
} }
@ -1147,7 +1167,7 @@ static int iso_write_mbr(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf)
t->mbr_req[i]->block_count = t->mbr_req[i + 1]->start_block - t->mbr_req[i]->block_count = t->mbr_req[i + 1]->start_block -
t->mbr_req[i]->start_block; t->mbr_req[i]->start_block;
else else
t->mbr_req[i]->block_count = img_blocks - t->mbr_req[i]->block_count = ((uint64_t) img_blocks) * 4 -
t->mbr_req[i]->start_block; t->mbr_req[i]->start_block;
} }
@ -1184,7 +1204,7 @@ static int iso_write_mbr(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf)
ret = write_mbr_partition_entry(i + 1, (int) t->mbr_req[q]->type_byte, ret = write_mbr_partition_entry(i + 1, (int) t->mbr_req[q]->type_byte,
t->mbr_req[q]->start_block, t->mbr_req[q]->block_count, t->mbr_req[q]->start_block, t->mbr_req[q]->block_count,
t->partition_secs_per_head, t->partition_heads_per_cyl, t->partition_secs_per_head, t->partition_heads_per_cyl,
buf, 0); buf, 2);
if (ret < 0) if (ret < 0)
return ret; return ret;
buf[446 + i * 16] = t->mbr_req[q]->status_byte; buf[446 + i * 16] = t->mbr_req[q]->status_byte;
@ -1298,7 +1318,7 @@ int iso_write_gpt_header_block(Ecma119Image *t, uint32_t img_blocks,
} }
/* CRC-32 of this header while head_crc is 0 */ /* CRC-32 of this header while head_crc is 0 */
crc = iso_crc32_gpt((unsigned char *) buf, 512, 0); crc = iso_crc32_gpt((unsigned char *) buf, 92, 0);
wpt = ((char *) buf) + 16; wpt = ((char *) buf) + 16;
iso_lsb_to_buf(&wpt, crc, 4, 0); iso_lsb_to_buf(&wpt, crc, 4, 0);
@ -1417,6 +1437,8 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
int first_partition = 1, last_partition = 4, apm_flag, part_type; int first_partition = 1, last_partition = 4, apm_flag, part_type;
int gpt_count = 0, gpt_idx[128], apm_count = 0; int gpt_count = 0, gpt_idx[128], apm_count = 0;
uint32_t img_blocks; uint32_t img_blocks;
uint64_t blk;
uint8_t *wpt;
if ((t == NULL) || (buf == NULL)) { if ((t == NULL) || (buf == NULL)) {
return ISO_NULL_POINTER; return ISO_NULL_POINTER;
@ -1564,7 +1586,8 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
return ISO_ASSERT_FAILURE; return ISO_ASSERT_FAILURE;
if (t->partition_offset == 0) { if (t->partition_offset == 0) {
/* Re-write partion entry 1 : start at 0, type Linux */ /* Re-write partion entry 1 : start at 0, type Linux */
ret = write_mbr_partition_entry(1, 0x83, 0, img_blocks, ret = write_mbr_partition_entry(1, 0x83,
(uint64_t) 0, (uint64_t) img_blocks,
t->partition_secs_per_head, t->partition_heads_per_cyl, t->partition_secs_per_head, t->partition_heads_per_cyl,
buf, 0); buf, 0);
if (ret < 0) if (ret < 0)
@ -1599,7 +1622,8 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
buf, t->appended_partitions[i][0] == 0); buf, t->appended_partitions[i][0] == 0);
} else { } else {
ret = write_mbr_partition_entry(i + 1, t->appended_part_types[i], ret = write_mbr_partition_entry(i + 1, t->appended_part_types[i],
t->appended_part_start[i], t->appended_part_size[i], (uint64_t) t->appended_part_start[i],
(uint64_t) t->appended_part_size[i],
t->partition_secs_per_head, t->partition_heads_per_cyl, t->partition_secs_per_head, t->partition_heads_per_cyl,
buf, 0); buf, 0);
} }
@ -1607,6 +1631,15 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
return ret; return ret;
} }
if (sa_type == 0 && (t->system_area_options & 0x4000) && !do_isohybrid) {
/* Patch MBR for GRUB2 */
blk = t->bootsrc[0]->sections[0].block * 4 +
Libisofs_grub2_mbr_patch_offsT;
wpt = buf + Libisofs_grub2_mbr_patch_poS;
for (i = 0; i < 8; i++)
wpt[i] = blk >> (i * 8);
}
return ISO_SUCCESS; return ISO_SUCCESS;
} }
@ -2115,7 +2148,7 @@ tampered_head:;
/* Compute new header CRC */ /* Compute new header CRC */
memset(new_head + 16, 0, 4); memset(new_head + 16, 0, 4);
crc = iso_crc32_gpt((unsigned char *) new_head, 512, 0); crc = iso_crc32_gpt((unsigned char *) new_head, 92, 0);
iso_lsb(new_head + 16, crc, 4); iso_lsb(new_head + 16, crc, 4);
/* Copy GPT entries */ /* Copy GPT entries */
@ -2226,7 +2259,7 @@ static int partprepend_writer_compute_data_blocks(IsoImageWriter *writer)
if (t->prep_partition != NULL || t->fat || will_have_gpt || if (t->prep_partition != NULL || t->fat || will_have_gpt ||
t->mbr_req_count > 0) t->mbr_req_count > 0)
return ISO_BOOT_MBR_OVERLAP; return ISO_BOOT_MBR_OVERLAP;
ret = iso_quick_mbr_entry(t, (uint32_t) 0, (uint32_t) 0, ret = iso_quick_mbr_entry(t, (uint64_t) 0, (uint64_t) 0,
0x96, 0x80, 0); 0x96, 0x80, 0);
if (ret < 0) if (ret < 0)
return ret; return ret;
@ -2241,21 +2274,25 @@ static int partprepend_writer_compute_data_blocks(IsoImageWriter *writer)
} }
if (t->prep_part_size > 0 || t->fat || will_have_gpt) { if (t->prep_part_size > 0 || t->fat || will_have_gpt) {
/* Protecting MBR entry for ISO start or whole ISO */ /* Protecting MBR entry for ISO start or whole ISO */
ret = iso_quick_mbr_entry(t, (uint32_t) t->partition_offset, ret = iso_quick_mbr_entry(t, will_have_gpt ? (uint64_t) 1 :
(uint32_t) 0, will_have_gpt ? 0xee : 0xcd, 0, 0); ((uint64_t) t->partition_offset) * 4,
(uint64_t) 0,
will_have_gpt ? 0xee : 0xcd, 0, 0);
if (ret < 0) if (ret < 0)
return ret; return ret;
} }
if (t->prep_part_size > 0) { if (t->prep_part_size > 0) {
ret = iso_quick_mbr_entry(t, t->curblock, t->prep_part_size, 0x41, ret = iso_quick_mbr_entry(t, ((uint64_t) t->curblock) * 4,
0, 0); ((uint64_t) t->prep_part_size) * 4,
0x41, 0, 0);
if (ret < 0) if (ret < 0)
return ret; return ret;
t->curblock += t->prep_part_size; t->curblock += t->prep_part_size;
} }
if (t->prep_part_size > 0 || t->fat) { if (t->prep_part_size > 0 || t->fat) {
/* FAT partition or protecting MBR entry for ISO end */ /* FAT partition or protecting MBR entry for ISO end */
ret = iso_quick_mbr_entry(t, (uint32_t) t->curblock, (uint32_t) 0, ret = iso_quick_mbr_entry(t, ((uint64_t) t->curblock) * 4,
(uint64_t) 0,
t->fat ? 0x0c : 0xcd, 0, 0); t->fat ? 0x0c : 0xcd, 0, 0);
if (ret < 0) if (ret < 0)
return ret; return ret;

View File

@ -78,13 +78,13 @@ int iso_compute_append_partitions(Ecma119Image *t, int flag);
*/ */
struct iso_mbr_partition_request { struct iso_mbr_partition_request {
/* Always given in blocks of 2 KiB */ /* Always given in blocks of 512 bytes */
uint32_t start_block; uint64_t start_block;
/* A block count of 0 means that the partition reaches up to the start of /* A block count of 0 means that the partition reaches up to the start of
the next one. the next one.
*/ */
uint32_t block_count; uint64_t block_count;
/* Partition type */ /* Partition type */
uint8_t type_byte; uint8_t type_byte;
@ -115,7 +115,7 @@ int iso_register_mbr_entry(Ecma119Image *t,
name and type are 0-terminated strings, which may get silently truncated. name and type are 0-terminated strings, which may get silently truncated.
*/ */
int iso_quick_mbr_entry(Ecma119Image *t, int iso_quick_mbr_entry(Ecma119Image *t,
uint32_t start_block, uint32_t block_count, uint64_t start_block, uint64_t block_count,
uint8_t type_byte, uint8_t status_byte, uint8_t type_byte, uint8_t status_byte,
int desired_slot); int desired_slot);
@ -266,4 +266,17 @@ int gpt_tail_writer_create(Ecma119Image *target);
/* Only for up to 36 characters ISO-8859-1 (or ASCII) input */ /* Only for up to 36 characters ISO-8859-1 (or ASCII) input */
void iso_ascii_utf_16le(uint8_t gap_name[72]); void iso_ascii_utf_16le(uint8_t gap_name[72]);
/* Parameters of MBR patching for GRUB2
Might later become variables in Ecma119Image
*/
#define Libisofs_grub2_mbr_patch_poS 0x1b0
#define Libisofs_grub2_mbr_patch_offsT 4
/* Parameters of SUN Disk Label patching for GRUB2
See API iso_image_set_sparc_core().
*/
#define Libisofs_grub2_sparc_patch_adr_poS 0x228
#define Libisofs_grub2_sparc_patch_size_poS 0x230
#endif /* SYSTEM_AREA_H_ */ #endif /* SYSTEM_AREA_H_ */