Compare commits
73 Commits
release-0.
...
release-1.
Author | SHA1 | Date | |
---|---|---|---|
8a752b50fa | |||
c38b1a3a3a | |||
73c9c7f244 | |||
0b9f03bb23 | |||
d1c3a017e3 | |||
b200feceed | |||
7958b2ea22 | |||
c0bdf4d3b5 | |||
71efc996e3 | |||
61383dea2d | |||
270cd1cad5 | |||
559e9b564d | |||
d8a56f60ef | |||
10e3b2939a | |||
ba67523278 | |||
f09964cf51 | |||
e4a70a823d | |||
655d86b97a | |||
f2f780115b | |||
b6be8457f7 | |||
1238c19494 | |||
2caf527f67 | |||
43eae7502b | |||
e035146e01 | |||
de3e21629f | |||
d79a3fcec4 | |||
de079cec42 | |||
b33d06eb0c | |||
dfdaa2902a | |||
0173c51c23 | |||
a118127e9c | |||
1f24b39879 | |||
16863755be | |||
b25ac0f52d | |||
5c59295e72 | |||
85893bf58b | |||
722327e4b8 | |||
ab0a981814 | |||
38483d894e | |||
1082e628d1 | |||
74c68224c7 | |||
200697898d | |||
a3eeda3d23 | |||
92073c45ef | |||
81cded618d | |||
84c0bd37ff | |||
4e60feaeab | |||
d6e150a10e | |||
35ceac65f7 | |||
45ffdef845 | |||
55d6ae343d | |||
a69f45e8cd | |||
68c3ae522e | |||
8e2748f23b | |||
f923a79929 | |||
362b15f4d5 | |||
2649045dfe | |||
3d427bdf70 | |||
8b2af3ac36 | |||
113358daea | |||
6927fd35e8 | |||
fb231ff186 | |||
b2fde289b1 | |||
dcc6ffd184 | |||
27e69c38ab | |||
f4b2bfc0d6 | |||
5482d5d7b4 | |||
b2997dcc46 | |||
48ae8acbd6 | |||
a488f8fb14 | |||
ea8da1f7d3 | |||
8ad92a08ea | |||
35c043a0f9 |
@ -1,7 +1,7 @@
|
||||
Vreixo Formoso <metalpain2002@yahoo.es>,
|
||||
Mario Danic <mario.danic@gmail.com>,
|
||||
Thomas Schmitt <scdbackup@gmx.net>
|
||||
Copyright (C) 2007-2010 Vreixo Formoso, Mario Danic, Thomas Schmitt
|
||||
Copyright (C) 2007-2011 Vreixo Formoso, Mario Danic, Thomas Schmitt
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
|
76
ChangeLog
76
ChangeLog
@ -1,11 +1,55 @@
|
||||
bzr branch lp:libisofs/for-libisoburn (to become libisofs-0.6.40.tar.gz)
|
||||
|
||||
libisofs-1.0.6.tar.gz Sat Apr 09 2011
|
||||
===============================================================================
|
||||
- no novelties yet -
|
||||
* New API call iso_write_opts_set_joliet_long_names()
|
||||
* New error codes for oversized file addresses
|
||||
|
||||
libisofs-1.0.4.tar.gz Thu Mar 10 2011
|
||||
===============================================================================
|
||||
* Bug fix: Compilation failed if --disable-zlib was configured
|
||||
* Bug fix: isohybrid image size was not aligned to cylinder boundary.
|
||||
* New no_md5 value 2 for API call iso_read_opts_set_no_md5()
|
||||
* New option bits 8 and 9 with iso_write_opts_set_system_area()
|
||||
|
||||
libisofs-1.0.2.tar.gz Tue Feb 23 2011
|
||||
===============================================================================
|
||||
* Bug fix: iso_write_opts_set_aaip(opts, 1) could cause fatal miscalculation
|
||||
of the root directory size. This eventually truncated directory
|
||||
tree and spoiled all data file content.
|
||||
* Bug fix: Volume Descriptor Set Terminator contained non-zero bytes in
|
||||
the reserved field (ECMA-119 8.3.4). The bytes stem from the
|
||||
previously written Volume Descriptor.
|
||||
* New API calls iso_tree_clone(), iso_stream_clone.
|
||||
* New IsoFileSourceIface version 2 with method clone_src().
|
||||
* New IsoStreamIface version 4 with method clone_stream().
|
||||
* New public function prototype iso_node_xinfo_cloner.
|
||||
* New API calls iso_node_xinfo_make_clonable(), iso_node_xinfo_get_cloner().
|
||||
* New public iso_node_xinfo_cloner instance aaip_xinfo_cloner().
|
||||
* New API calls iso_node_get_next_xinfo(), iso_node_remove_all_xinfo().
|
||||
* New API call iso_node_remove_tree().
|
||||
* New API call iso_write_opts_set_old_empty().
|
||||
|
||||
libisofs-1.0.0.tar.gz Mon Jan 17 2011
|
||||
===============================================================================
|
||||
* Bug fix: ECMA-119 directory names were truncated to 8 characters if
|
||||
lowercase characters or full ASCII are allowed.
|
||||
* New API call iso_write_opts_set_untranslated_name_len()
|
||||
* New API call iso_write_opts_set_allow_dir_id_ext()
|
||||
* New API call iso_memory_stream_new(). (Was formely a private call.)
|
||||
|
||||
libisofs-0.6.40.tar.gz Fri Dec 10 2010
|
||||
===============================================================================
|
||||
* New API call iso_write_opts_set_disc_label(), new system area type
|
||||
3 = SUN Disk Label for booting SUN SPARC systems.
|
||||
* New API call iso_write_opts_set_will_cancel() avoids start of write thread
|
||||
and is to be used to inquire the future image size.
|
||||
* New error reply code ISO_DISPLACE_ROLLOVER for external data sources with
|
||||
address displacement.
|
||||
|
||||
libisofs-0.6.38.tar.gz Sat Oct 23 2010
|
||||
===============================================================================
|
||||
* New API calls iso_write_opts_attach_jte() and iso_write_opts_detach_jte()
|
||||
allow to use of libjte for jigdo production.
|
||||
allow to use libjte for jigdo production.
|
||||
* New API call iso_write_opts_set_tail_blocks() for tail padding inside
|
||||
ISO image.
|
||||
* New API call iso_image_generator_is_running() to learn when the write thread
|
||||
@ -198,29 +242,3 @@ Libisofs 0.6.2
|
||||
* Completely new API
|
||||
* Long term commitment to ABI libisofs.so.6
|
||||
|
||||
libisofs-0.2.8.tar.gz Tue Jul 31 2007
|
||||
===============================================================================
|
||||
* Support for hidden files
|
||||
* Eltorito support
|
||||
* Charset support
|
||||
* Support for inode caching
|
||||
* Ordering files on image
|
||||
* Unit tests
|
||||
* A lot of other features and bugfixes
|
||||
* Note: ABI has been broken.
|
||||
|
||||
libisofs-0.2.5.tar.gz Tue Jul 31 2007
|
||||
===============================================================================
|
||||
* Bugfix release. Fixed the ECMA-related problem with iso tree generation.
|
||||
There is newer release 0.2.8 with a lot of new features.
|
||||
|
||||
libisofs-0.2.4.tar.gz Jan 03 2007
|
||||
===============================================================================
|
||||
* Bugfix release. Fixes lots of problems people have encountered, including but
|
||||
not limited to broken docs generation.
|
||||
|
||||
libisofs-0.2.3.tar.gz Sat Dec 02 2006
|
||||
===============================================================================
|
||||
* Bugfix release, with some improvements for freebsd support.
|
||||
* Requires libburn to compile.
|
||||
|
||||
|
1
README
1
README
@ -54,6 +54,7 @@ applications which use it. This dependency can be avoided by configure options
|
||||
--disable-libacl avoid use of ACL functions like acl_to_text()
|
||||
--disable-xattr avoid use of xattr functions like listxattr()
|
||||
--disable-zlib avoid use of zlib functions like compress2()
|
||||
--disable-libjte avoid use of libjte functions
|
||||
|
||||
See INSTALL file for general options of ./configure.
|
||||
|
||||
|
26
configure.ac
26
configure.ac
@ -1,4 +1,4 @@
|
||||
AC_INIT([libisofs], [0.6.38], [http://libburnia-project.org])
|
||||
AC_INIT([libisofs], [1.0.6], [http://libburnia-project.org])
|
||||
AC_PREREQ([2.50])
|
||||
dnl AC_CONFIG_HEADER([config.h])
|
||||
|
||||
@ -38,9 +38,9 @@ dnl It rather feeds the API function iso_lib_version().
|
||||
dnl
|
||||
dnl If LIBISOFS_*_VERSION changes, be sure to change AC_INIT above to match.
|
||||
dnl
|
||||
LIBISOFS_MAJOR_VERSION=0
|
||||
LIBISOFS_MINOR_VERSION=6
|
||||
LIBISOFS_MICRO_VERSION=38
|
||||
LIBISOFS_MAJOR_VERSION=1
|
||||
LIBISOFS_MINOR_VERSION=0
|
||||
LIBISOFS_MICRO_VERSION=6
|
||||
LIBISOFS_VERSION=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION.$LIBISOFS_MICRO_VERSION
|
||||
|
||||
AC_SUBST(LIBISOFS_MAJOR_VERSION)
|
||||
@ -50,10 +50,10 @@ AC_SUBST(LIBISOFS_VERSION)
|
||||
|
||||
dnl Libtool versioning
|
||||
LT_RELEASE=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION
|
||||
# 2010.10.23 development jump has not yet happened
|
||||
# SONAME = 40 - 34 = 6 . Library name = libisofs.6.34.0
|
||||
LT_CURRENT=40
|
||||
LT_AGE=34
|
||||
# 2011.04.09 development jump has not yet happened
|
||||
# SONAME = 50 - 44 = 6 . Library name = libisofs.6.44.0
|
||||
LT_CURRENT=50
|
||||
LT_AGE=44
|
||||
LT_REVISION=0
|
||||
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
|
||||
|
||||
@ -133,15 +133,15 @@ AC_ARG_ENABLE(debug,
|
||||
, enable_debug=yes)
|
||||
if test x$enable_debug != xyes; then
|
||||
if test x$GCC = xyes; then
|
||||
CFLAGS="$CFLAGS -O3"
|
||||
CFLAGS="$CFLAGS -fexpensive-optimizations"
|
||||
CFLAGS="-O3 $CFLAGS"
|
||||
CFLAGS="-fexpensive-optimizations $CFLAGS"
|
||||
fi
|
||||
CFLAGS="$CFLAGS -DNDEBUG"
|
||||
CFLAGS="-DNDEBUG $CFLAGS"
|
||||
else
|
||||
if test x$GCC = xyes; then
|
||||
CFLAGS="$CFLAGS -g -pedantic -Wall"
|
||||
CFLAGS="-g -pedantic -Wall $CFLAGS"
|
||||
fi
|
||||
CFLAGS="$CFLAGS -DDEBUG"
|
||||
CFLAGS="-DDEBUG $CFLAGS"
|
||||
fi
|
||||
|
||||
dnl Verbose debug to make libisofs issue more debug messages
|
||||
|
27
demo/demo.c
27
demo/demo.c
@ -50,6 +50,7 @@ static char helptext[][80] = {
|
||||
#include <fcntl.h>
|
||||
#include <err.h>
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
#ifndef PATH_MAX
|
||||
@ -372,7 +373,11 @@ int gesture_iso(int argc, char **argv)
|
||||
iso_write_opts_free(opts);
|
||||
|
||||
while (burn_src->read_xt(burn_src, buf, 2048) == 2048) {
|
||||
fwrite(buf, 1, 2048, fp);
|
||||
result = fwrite(buf, 1, 2048, fp);
|
||||
if (result < 2048) {
|
||||
printf ("Cannot write block. errno= %d\n", errno);
|
||||
goto ex;
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
burn_src->free_data(burn_src);
|
||||
@ -537,7 +542,7 @@ int gesture_iso_read(int argc, char **argv)
|
||||
|
||||
int gesture_iso_cat(int argc, char **argv)
|
||||
{
|
||||
int res;
|
||||
int res, write_ret;
|
||||
IsoFilesystem *fs;
|
||||
IsoFileSource *file;
|
||||
struct stat info;
|
||||
@ -596,7 +601,11 @@ int gesture_iso_cat(int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
while ((res = iso_file_source_read(file, buf, 1024)) > 0) {
|
||||
fwrite(buf, 1, res, stdout);
|
||||
write_ret = fwrite(buf, 1, res, stdout);
|
||||
if (write_ret < res) {
|
||||
printf ("Cannot write block to stdout. errno= %d\n", errno);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (res < 0) {
|
||||
fprintf(stderr, "Error reading, err = %d\n", res);
|
||||
@ -700,7 +709,11 @@ int gesture_iso_modify(int argc, char **argv)
|
||||
iso_write_opts_free(opts);
|
||||
|
||||
while (burn_src->read_xt(burn_src, buf, 2048) == 2048) {
|
||||
fwrite(buf, 1, 2048, fp);
|
||||
result = fwrite(buf, 1, 2048, fp);
|
||||
if (result < 2048) {
|
||||
printf ("Cannot write block. errno= %d\n", errno);
|
||||
goto ex;
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
burn_src->free_data(burn_src);
|
||||
@ -814,7 +827,11 @@ int gesture_iso_ms(int argc, char **argv)
|
||||
iso_write_opts_free(opts);
|
||||
|
||||
while (burn_src->read_xt(burn_src, buf, 2048) == 2048) {
|
||||
fwrite(buf, 1, 2048, fp);
|
||||
result = fwrite(buf, 1, 2048, fp);
|
||||
if (result < 2048) {
|
||||
printf ("Cannot write block. errno= %d\n", errno);
|
||||
goto ex;
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
burn_src->free_data(burn_src);
|
||||
|
@ -11,7 +11,7 @@ This information is collected from various sources. Some is backed by
|
||||
specifications, some is just rumor which happens to work (maybe not even that).
|
||||
|
||||
|
||||
Content
|
||||
Content
|
||||
|
||||
EL Torito CD booting, for PC-BIOS x86, PowerPC, (old) Mac, EFI.
|
||||
|
||||
@ -23,6 +23,8 @@ MIPS Volume Header, for MIPS Big Endian, e.g. SGI Indigo2.
|
||||
|
||||
DEC Boot Block, for MIPS Little Endian , e.g. DECstation.
|
||||
|
||||
SUN Disk Label and boot images, for SUN SPARC
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
@ -155,8 +157,8 @@ Byte Range | Value | Meaning
|
||||
| | "the number of virtual/emulated sectors the system
|
||||
| | will store at Load Segment during the initial boot
|
||||
| | procedure."
|
||||
| | libisofs stores 1 for emulated boot_media and
|
||||
| | 0 for boot_media == 0.
|
||||
| | libisofs stores 1 for emulated boot_media and a
|
||||
| | user defined value for boot_media == 0. Often: 4.
|
||||
| |
|
||||
8 - 11 | load_rba | Load RBA. The 2 kB block address where the boot
|
||||
| | image file content is located in the ISO 9660 image.
|
||||
@ -208,8 +210,8 @@ Byte Range | Value | Meaning
|
||||
| |
|
||||
6 - 7 | sec_count | Sector Count.
|
||||
| | See above Initial/Default Entry
|
||||
| | libisofs stores 1 for emulated boot_media and
|
||||
| | 0 for boot_media == 0.
|
||||
| | libisofs stores 1 for emulated boot_media and a
|
||||
| | user defined value for boot_media == 0. Often: 4.
|
||||
| |
|
||||
8 - 11 | load_rba | Load RBA. The 2 kB block address where the boot
|
||||
| | image file content is located in the ISO 9660 image.
|
||||
@ -256,7 +258,7 @@ Sources:
|
||||
|
||||
The candidates for MBR booting will normally use El Torito rather than MBR
|
||||
if the ISO image is presented on CD, DVD, or BD media.
|
||||
The eventual MBR comes into effect it the image is on a media that is
|
||||
The eventual MBR comes into effect if the image is on a media that is
|
||||
interpreted by the BIOS as some kind of hard disk. Usually real hard disks,
|
||||
floppy disks, USB sticks, memory cards.
|
||||
|
||||
@ -524,46 +526,6 @@ Byte Range | Value | Meaning
|
||||
up to 2048 | 0 | ISO 9660 Block end padding
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
|
||||
Test image produced by
|
||||
genisoimage -o /u/test/mips_boot.iso -mips-boot checksum.c jte
|
||||
which reports
|
||||
Found mips boot image checksum.c, using extent 636 (0x27C), #blocks 14336 (0x3800)
|
||||
|
||||
xorriso reports as 2048 byte LBA of the boot image dummy file
|
||||
File data lba: 0 , 159 , 7 , 14330 , '/CHECKSUM.C'
|
||||
|
||||
First 512 bytes in hex:
|
||||
0 : 0b e5 a9 41 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
16 : 00 00 00 00 00 00 00 00 00 00 00 00 00 51 00 00
|
||||
32 : 00 01 00 00 00 00 00 20 02 00 00 00 00 00 00 34
|
||||
48 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
64 : 00 00 00 00 00 00 00 00 63 68 65 63 6b 73 75 6d
|
||||
80 : 00 00 02 7c 00 00 38 00 00 00 00 00 00 00 00 00
|
||||
... 0 ...
|
||||
400 : 00 00 00 00 00 00 00 00 00 00 0a 28 00 00 00 00
|
||||
416 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
432 : 00 00 0a 28 00 00 00 00 00 00 00 06 00 00 00 00
|
||||
... 0 ...
|
||||
496 : 00 00 00 00 00 00 00 00 22 ec 2c c9 00 00 00 00
|
||||
|
||||
The 32 bit two's complement of bytes 0 to 503 is 0x22ec2cc9.
|
||||
|
||||
In decimal:
|
||||
0 : 11 229 169 65 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
16 : 0 0 0 0 0 0 0 0 0 0 0 0 0 81 0 0
|
||||
32 : 0 1 0 0 0 0 0 32 2 0 0 0 0 0 0 52
|
||||
48 : 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
64 : 0 0 0 0 0 0 0 0 99 104 101 99 107 115 117 109
|
||||
80 : 0 0 2 124 0 0 56 0 0 0 0 0 0 0 0 0
|
||||
... 0 ...
|
||||
400 : 0 0 0 0 0 0 0 0 0 0 10 40 0 0 0 0
|
||||
416 : 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
432 : 0 0 10 40 0 0 0 0 0 0 0 6 0 0 0 0
|
||||
... 0 ...
|
||||
496 : 0 0 0 0 0 0 0 0 34 236 44 201 0 0 0 0
|
||||
|
||||
Cleartext part:
|
||||
64 : c h e c k s u m
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
@ -648,6 +610,109 @@ Byte Range | Value | Meaning
|
||||
16 - 19 | p_filesz | /* Segment size in file */
|
||||
|-> seg_size | Needed for seg_size
|
||||
| |
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
|
||||
SUN Disk Label and boot images
|
||||
for SUN SPARC
|
||||
|
||||
Sources:
|
||||
cdrtools-2.01.01a77/mkisofs/sunlabel.h
|
||||
cdrtools-2.01.01a77/mkisofs/mkisofs.8
|
||||
by Joerg Schilling
|
||||
|
||||
|
||||
The Disk Label is written to the first 512 bytes of the image. It can mark
|
||||
8 partitions (slices ) of which the first contains the ISO image. The other
|
||||
7 may contain boot images.
|
||||
Words are composed big-endian style.
|
||||
|
||||
Boot images are provided externally. mkisofs arranges them after the end of
|
||||
the ISO image so that each starts at a cylinder boundary (320 kB).
|
||||
|
||||
There is a mechanism in mkisofs which fills unused partitions by copies of
|
||||
their predecessor in the partition table:
|
||||
"If the special filename ... is used, the actual and all following
|
||||
boot partitions are mapped to the previous partition.
|
||||
If mkisofs is called with -G image -B ... all boot partitions are
|
||||
mapped to the partition that contains the ISO9660 filesystem."
|
||||
|
||||
|
||||
Disk Label components:
|
||||
|
||||
Byte Range | Value | Meaning
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
0 - 127 | label | ASCII Label
|
||||
| | "CD-ROM Disc with Sun sparc boot created by ..."
|
||||
| | mkisofs option -sparc-label
|
||||
| |
|
||||
128 - 263 | ========== | /* vtoc inclusions from AT&T SVr4 */
|
||||
| |
|
||||
128 - 131 | 1 | Layout version
|
||||
132 - 139 | 0 | /* volume name */
|
||||
140 - 141 | 8 | Number of partitions
|
||||
| |
|
||||
142 - 173 | ========== | 8 partition entries of 4 bytes
|
||||
| |
|
||||
142 - 145 | ========== | Entry for partition 1
|
||||
142 - 143 | 4 | ID tag of partition: 4 = User partition
|
||||
144 - 145 | 0x10 | Permissions: 0x10 = read-only
|
||||
| |
|
||||
146 - 149 | ========== | Entry for partition 2
|
||||
146 - 147 | id_tag2 | ID tag of partition:
|
||||
| | 0 = unused
|
||||
| | 2 = Root partition with boot image
|
||||
148 - 149 | perm2 | Permissions:
|
||||
| | 0 = unused
|
||||
| | 0x10 = read-only (if used)
|
||||
| |
|
||||
150 - 173 | ========== | Entries for partition 3 to 8.
|
||||
| | See above: Entry for partition 2
|
||||
| |
|
||||
174 - 175 | 0 | Padding
|
||||
| |
|
||||
176 - 187 | 0 | /* info for mboot */
|
||||
| |
|
||||
188 - 191 | 0x600ddeee | /* to verify vtoc sanity */
|
||||
| |
|
||||
192 - 231 | 0 | Reserved
|
||||
| |
|
||||
232 - 263 | 0 | 8 Timestamps of yet unknown format
|
||||
| |
|
||||
264 - 419 | 0 | Padding
|
||||
| |
|
||||
420 - 443 | ========== | Disk properties
|
||||
| |
|
||||
420 - 421 | 350 | Rotations per minute
|
||||
422 - 423 | 2048 | Number of physical cylinders (fixely 640 MB)
|
||||
424 - 425 | 0 | /* alternates per cylinder */
|
||||
426 - 429 | 0 | /* obsolete */
|
||||
430 - 431 | 1 | /* interleave factor */
|
||||
432 - 433 | 2048 | Number of data cylinders (fixely 640 MB)
|
||||
434 - 435 | 0 | /* # of alternate cylinders */
|
||||
436 - 437 | 1 | Number of heads per cylinder (i.e. 1 cyl = 320 kB)
|
||||
438 - 439 | 640 | Number of sectors per head (i.e. 1 head = 320 kB)
|
||||
440 - 443 | 0 | /* obsolete */
|
||||
| |
|
||||
444 - 507 | ========== | Partition table
|
||||
| |
|
||||
444 - 451 | ========== | Partition table entry #1
|
||||
| |
|
||||
444 - 447 | start_cyl | Start cylinder
|
||||
| |
|
||||
448 - 451 | num_blocks | Number of blocks in partition
|
||||
| |
|
||||
452 - 507 | ========== | Partition table entries #2 to #8
|
||||
| ... | See above Partition table entry #1
|
||||
| |
|
||||
508 - 509 | 0xdabe | Magic Number
|
||||
| |
|
||||
510 - 511 | checksum | The result of exoring 2-byte words 0 to 254
|
||||
| |
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
@ -22,6 +22,8 @@ Purpose:
|
||||
END is also the block address of the start of the checksum recording
|
||||
area in the image.
|
||||
See also isofs.cx .
|
||||
This attribute shall eventually be attached to the root directory entry
|
||||
and be global for the whole image.
|
||||
|
||||
Format of Value:
|
||||
START_LEN | START_BYTES | END_LEN | END_BYTES |
|
||||
@ -150,7 +152,7 @@ Registered:
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
This text is under
|
||||
Copyright (c) 2009 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||
Copyright (c) 2009 - 2011 Thomas Schmitt <scdbackup@gmx.net>
|
||||
It shall only be modified in sync with libisofs and other software which
|
||||
makes use of AAIP. Please mail change requests to mailing list
|
||||
<libburn-hackers@pykix.org> or to the copyright holder in private.
|
||||
|
@ -11,7 +11,14 @@
|
||||
#define LIBISO_BUFFER_H_
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#else
|
||||
#ifdef HAVE_INTTYPES_H
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define BLOCK_SIZE 2048
|
||||
|
||||
|
@ -26,10 +26,6 @@
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX Libisofs_default_path_maX
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
void iso_node_builder_ref(IsoNodeBuilder *builder)
|
||||
@ -75,6 +71,8 @@ int default_create_file(IsoNodeBuilder *builder, IsoImage *image,
|
||||
iso_file_source_ref(src);
|
||||
|
||||
name = iso_file_source_get_name(src);
|
||||
if (strlen(name) > LIBISOFS_NODE_NAME_MAX)
|
||||
name[LIBISOFS_NODE_NAME_MAX] = 0;
|
||||
ret = iso_node_new_file(name, stream, &node);
|
||||
if (ret < 0) {
|
||||
iso_stream_unref(stream);
|
||||
@ -122,6 +120,8 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
||||
}
|
||||
|
||||
name = iso_file_source_get_name(src);
|
||||
if (strlen(name) > LIBISOFS_NODE_NAME_MAX)
|
||||
name[LIBISOFS_NODE_NAME_MAX] = 0;
|
||||
fs = iso_file_source_get_filesystem(src);
|
||||
new = NULL;
|
||||
|
||||
@ -157,10 +157,10 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
||||
case S_IFLNK:
|
||||
{
|
||||
/* source is a symbolic link */
|
||||
char dest[PATH_MAX];
|
||||
char dest[LIBISOFS_NODE_PATH_MAX];
|
||||
IsoSymlink *link;
|
||||
|
||||
ret = iso_file_source_readlink(src, dest, PATH_MAX);
|
||||
ret = iso_file_source_readlink(src, dest, LIBISOFS_NODE_PATH_MAX);
|
||||
if (ret < 0) {
|
||||
break;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2007 Mario Danic
|
||||
* Copyright (c) 2009 - 2010 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2011 Thomas Schmitt
|
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
@ -107,7 +107,7 @@ void ecma119_image_free(Ecma119Image *t)
|
||||
free(t->writers);
|
||||
if (t->partition_root != NULL)
|
||||
ecma119_node_free(t->partition_root);
|
||||
for (i = 0; i < 4; i++)
|
||||
for (i = 0; i < ISO_MAX_PARTITIONS; i++)
|
||||
if (t->appended_partitions[i] != NULL)
|
||||
free(t->appended_partitions[i]);
|
||||
|
||||
@ -141,7 +141,7 @@ static int show_chunk_to_jte(Ecma119Image *target, char *buf, int count)
|
||||
static
|
||||
int need_version_number(Ecma119Image *t, Ecma119Node *n)
|
||||
{
|
||||
if (t->omit_version_numbers & 1) {
|
||||
if ((t->omit_version_numbers & 1) || t->untranslated_name_len > 0) {
|
||||
return 0;
|
||||
}
|
||||
if (n->type == ECMA119_DIR || n->type == ECMA119_PLACEHOLDER) {
|
||||
@ -188,9 +188,9 @@ size_t calc_dir_size(Ecma119Image *t, Ecma119Node *dir, size_t *ce)
|
||||
/* size of "." and ".." entries */
|
||||
len = 34 + 34;
|
||||
if (t->rockridge) {
|
||||
len += rrip_calc_len(t, dir, 1, 255 - 34, &ce_len);
|
||||
len += rrip_calc_len(t, dir, 1, 34, &ce_len);
|
||||
*ce += ce_len;
|
||||
len += rrip_calc_len(t, dir, 2, 255 - 34, &ce_len);
|
||||
len += rrip_calc_len(t, dir, 2, 34, &ce_len);
|
||||
*ce += ce_len;
|
||||
}
|
||||
|
||||
@ -203,7 +203,7 @@ size_t calc_dir_size(Ecma119Image *t, Ecma119Node *dir, size_t *ce)
|
||||
for (section = 0; section < nsections; ++section) {
|
||||
size_t dirent_len = calc_dirent_len(t, child);
|
||||
if (t->rockridge) {
|
||||
dirent_len += rrip_calc_len(t, child, 0, 255 - dirent_len, &ce_len);
|
||||
dirent_len += rrip_calc_len(t, child, 0, dirent_len, &ce_len);
|
||||
*ce += ce_len;
|
||||
}
|
||||
remaining = BLOCK_SIZE - (len % BLOCK_SIZE);
|
||||
@ -329,6 +329,9 @@ int ecma119_writer_compute_data_blocks(IsoImageWriter *writer)
|
||||
image start and not for the partition */;
|
||||
|
||||
}
|
||||
|
||||
target->tree_end_block = target->curblock;
|
||||
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
@ -380,11 +383,14 @@ void write_one_dir_record(Ecma119Image *t, Ecma119Node *node, int file_id,
|
||||
multi_extend = (node->info.file->nsections - 1 == extent) ? 0 : 1;
|
||||
} else {
|
||||
/*
|
||||
* for nodes other than files and dirs, we set both
|
||||
* len and block to 0
|
||||
* for nodes other than files and dirs, we set len to 0, and
|
||||
* the content block address to a dummy value.
|
||||
*/
|
||||
len = 0;
|
||||
block = 0;
|
||||
if (! t->old_empty)
|
||||
block = t->empty_file_block;
|
||||
else
|
||||
block = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -594,7 +600,7 @@ int write_one_dir(Ecma119Image *t, Ecma119Node *dir, Ecma119Node *parent)
|
||||
|
||||
/* write the "." and ".." entries first */
|
||||
if (t->rockridge) {
|
||||
ret = rrip_get_susp_fields(t, dir, 1, 255 - 32, &info);
|
||||
ret = rrip_get_susp_fields(t, dir, 1, 34, &info);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
@ -604,7 +610,7 @@ int write_one_dir(Ecma119Image *t, Ecma119Node *dir, Ecma119Node *parent)
|
||||
buf += len;
|
||||
|
||||
if (t->rockridge) {
|
||||
ret = rrip_get_susp_fields(t, dir, 2, 255 - 32, &info);
|
||||
ret = rrip_get_susp_fields(t, dir, 2, 34, &info);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
@ -630,7 +636,7 @@ int write_one_dir(Ecma119Image *t, Ecma119Node *dir, Ecma119Node *parent)
|
||||
|
||||
/* get the SUSP fields if rockridge is enabled */
|
||||
if (t->rockridge) {
|
||||
ret = rrip_get_susp_fields(t, child, 0, 255 - len, &info);
|
||||
ret = rrip_get_susp_fields(t, child, 0, len, &info);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
@ -871,6 +877,7 @@ int ecma119_writer_write_data(IsoImageWriter *writer)
|
||||
{
|
||||
int ret;
|
||||
Ecma119Image *t;
|
||||
uint32_t curblock;
|
||||
|
||||
if (writer == NULL) {
|
||||
return ISO_ASSERT_FAILURE;
|
||||
@ -888,6 +895,20 @@ int ecma119_writer_write_data(IsoImageWriter *writer)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
curblock = (t->bytes_written / 2048) + t->ms_block;
|
||||
if (curblock != t->tree_end_block) {
|
||||
char msg[100];
|
||||
|
||||
sprintf(msg,
|
||||
"Calculated and written ECMA-119 tree end differ: %lu <> %lu",
|
||||
(unsigned long) t->tree_end_block,
|
||||
(unsigned long) curblock);
|
||||
iso_msgs_submit(0, msg, 0, "WARNING", 0);
|
||||
|
||||
t->tree_end_block = 1;/* Mark for harsher reaction at end of writing */
|
||||
}
|
||||
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
@ -1087,7 +1108,36 @@ int zero_writer_free_data(IsoImageWriter *writer)
|
||||
}
|
||||
|
||||
static
|
||||
int zero_writer_create(Ecma119Image *target, uint32_t num_blocks)
|
||||
int tail_writer_compute_data_blocks(IsoImageWriter *writer)
|
||||
{
|
||||
int ret;
|
||||
Ecma119Image *target;
|
||||
struct iso_zero_writer_data_struct *data;
|
||||
char msg[160];
|
||||
|
||||
target = writer->target;
|
||||
ret = iso_align_isohybrid(target, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
data = (struct iso_zero_writer_data_struct *) writer->data;
|
||||
if (data->num_blocks != target->tail_blocks) {
|
||||
sprintf(msg, "Aligned image size to cylinder size by %d blocks",
|
||||
target->tail_blocks - data->num_blocks);
|
||||
iso_msgs_submit(0, msg, 0, "NOTE", 0);
|
||||
data->num_blocks = target->tail_blocks;
|
||||
}
|
||||
if (target->tail_blocks <= 0)
|
||||
return ISO_SUCCESS;
|
||||
ret = zero_writer_compute_data_blocks(writer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
@param flag bit0= use tail_writer_compute_data_blocks rather than
|
||||
zero_writer_compute_data_blocks
|
||||
*/
|
||||
static
|
||||
int zero_writer_create(Ecma119Image *target, uint32_t num_blocks, int flag)
|
||||
{
|
||||
IsoImageWriter *writer;
|
||||
struct iso_zero_writer_data_struct *data;
|
||||
@ -1103,7 +1153,11 @@ int zero_writer_create(Ecma119Image *target, uint32_t num_blocks)
|
||||
}
|
||||
data->num_blocks = num_blocks;
|
||||
|
||||
writer->compute_data_blocks = zero_writer_compute_data_blocks;
|
||||
if (flag & 1) {
|
||||
writer->compute_data_blocks = tail_writer_compute_data_blocks;
|
||||
} else {
|
||||
writer->compute_data_blocks = zero_writer_compute_data_blocks;
|
||||
}
|
||||
writer->write_vol_desc = zero_writer_write_vol_desc;
|
||||
writer->write_data = zero_writer_write_data;
|
||||
writer->free_data = zero_writer_free_data;
|
||||
@ -1135,6 +1189,8 @@ int write_vol_desc_terminator(Ecma119Image *target)
|
||||
uint8_t buf[BLOCK_SIZE];
|
||||
struct ecma119_vol_desc_terminator *vol;
|
||||
|
||||
memset(buf, 0, BLOCK_SIZE);
|
||||
|
||||
vol = (struct ecma119_vol_desc_terminator *) buf;
|
||||
|
||||
vol->vol_desc_type[0] = 255;
|
||||
@ -1209,7 +1265,7 @@ int write_head_part2(Ecma119Image *target, int *write_count, int flag)
|
||||
return ISO_SUCCESS;
|
||||
|
||||
/* Write multi-session padding up to target->partition_offset + 16 */
|
||||
memset(buf, 0, 2048);
|
||||
memset(buf, 0, BLOCK_SIZE);
|
||||
for(; *write_count < target->partition_offset + 16; (*write_count)++) {
|
||||
res = iso_write(target, buf, BLOCK_SIZE);
|
||||
if (res < 0)
|
||||
@ -1299,13 +1355,20 @@ static int finish_libjte(Ecma119Image *target)
|
||||
|
||||
|
||||
static int write_mbr_partition_file(Ecma119Image *target, char *path,
|
||||
uint32_t blocks, int flag)
|
||||
uint32_t prepad, uint32_t blocks, int flag)
|
||||
{
|
||||
FILE *fp = NULL;
|
||||
uint32_t i;
|
||||
uint8_t buf[BLOCK_SIZE];
|
||||
int ret;
|
||||
|
||||
memset(buf, 0, BLOCK_SIZE);
|
||||
for (i = 0; i < prepad; i++) {
|
||||
ret = iso_write(target, buf, BLOCK_SIZE);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
fp = fopen(path, "rb");
|
||||
if (fp == NULL)
|
||||
return ISO_BAD_PARTITION_FILE;
|
||||
@ -1325,8 +1388,8 @@ static int write_mbr_partition_file(Ecma119Image *target, char *path,
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
if (fp != NULL)
|
||||
fclose(fp);
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
@ -1334,7 +1397,7 @@ static int write_mbr_partition_file(Ecma119Image *target, char *path,
|
||||
static
|
||||
void *write_function(void *arg)
|
||||
{
|
||||
int res;
|
||||
int res, first_partition = 1, last_partition = 0, sa_type;
|
||||
size_t i;
|
||||
IsoImageWriter *writer;
|
||||
|
||||
@ -1358,16 +1421,26 @@ void *write_function(void *arg)
|
||||
}
|
||||
|
||||
/* Append partition data */
|
||||
for (i = 0; i < 4; i++) {
|
||||
sa_type = (target->system_area_options >> 2) & 0x3f;
|
||||
if (sa_type == 0) { /* MBR */
|
||||
first_partition = 1;
|
||||
last_partition = 4;
|
||||
} else if (sa_type == 3) { /* SUN Disk Label */
|
||||
first_partition = 2;
|
||||
last_partition = 8;
|
||||
}
|
||||
for (i = first_partition - 1; i <= last_partition - 1; i++) {
|
||||
if (target->appended_partitions[i] == NULL)
|
||||
continue;
|
||||
if (target->appended_partitions[i][0] == 0)
|
||||
continue;
|
||||
res = write_mbr_partition_file(target, target->appended_partitions[i],
|
||||
target->appended_part_prepad[i],
|
||||
target->appended_part_size[i], 0);
|
||||
if (res < 0)
|
||||
goto write_error;
|
||||
}
|
||||
|
||||
|
||||
/* Transplant checksum buffer from Ecma119Image to IsoImage */
|
||||
transplant_checksum_buffer(target, 0);
|
||||
|
||||
@ -1383,6 +1456,12 @@ void *write_function(void *arg)
|
||||
Eventually free target */
|
||||
ecma119_image_free(target);
|
||||
|
||||
if (target->tree_end_block == 1) {
|
||||
iso_msgs_submit(0,
|
||||
"Image is most likely damaged. Calculated/written block address mismatch.",
|
||||
0, "FATAL", 0);
|
||||
}
|
||||
|
||||
#ifdef Libisofs_with_pthread_exiT
|
||||
pthread_exit(NULL);
|
||||
#else
|
||||
@ -1395,7 +1474,9 @@ void *write_function(void *arg)
|
||||
target->eff_partition_offset = 0;
|
||||
if (res == ISO_CANCELED) {
|
||||
/* canceled */
|
||||
iso_msg_submit(target->image->id, ISO_IMAGE_WRITE_CANCELED, 0, NULL);
|
||||
if (!target->will_cancel)
|
||||
iso_msg_submit(target->image->id, ISO_IMAGE_WRITE_CANCELED,
|
||||
0, NULL);
|
||||
} else {
|
||||
/* image write error */
|
||||
iso_msg_submit(target->image->id, ISO_WRITE_ERROR, res,
|
||||
@ -1520,6 +1601,7 @@ static
|
||||
int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
{
|
||||
int ret, i, voldesc_size, nwriters, image_checksums_mad = 0, tag_pos;
|
||||
int sa_type;
|
||||
Ecma119Image *target;
|
||||
IsoImageWriter *writer;
|
||||
int el_torito_writer_index = -1, file_src_writer_index = -1;
|
||||
@ -1547,6 +1629,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
target->image = src;
|
||||
iso_image_ref(src);
|
||||
|
||||
target->will_cancel = opts->will_cancel;
|
||||
target->iso_level = opts->level;
|
||||
target->rockridge = opts->rockridge;
|
||||
target->joliet = opts->joliet;
|
||||
@ -1554,6 +1637,9 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
target->hardlinks = opts->hardlinks;
|
||||
target->aaip = opts->aaip;
|
||||
target->always_gmt = opts->always_gmt;
|
||||
target->old_empty = opts->old_empty;
|
||||
target->untranslated_name_len = opts->untranslated_name_len;
|
||||
target->allow_dir_id_ext = opts->allow_dir_id_ext;
|
||||
target->omit_version_numbers = opts->omit_version_numbers
|
||||
| opts->max_37_char_filenames;
|
||||
target->allow_deep_paths = opts->allow_deep_paths;
|
||||
@ -1564,6 +1650,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
target->allow_full_ascii = opts->allow_full_ascii;
|
||||
target->relaxed_vol_atts = opts->relaxed_vol_atts;
|
||||
target->joliet_longer_paths = opts->joliet_longer_paths;
|
||||
target->joliet_long_names = opts->joliet_long_names;
|
||||
target->rrip_version_1_10 = opts->rrip_version_1_10;
|
||||
target->rrip_1_10_px_ino = opts->rrip_1_10_px_ino;
|
||||
target->aaip_susp_1_10 = opts->aaip_susp_1_10;
|
||||
@ -1613,10 +1700,11 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
system_area = src->system_area_data;
|
||||
system_area_options = src->system_area_options;
|
||||
} else {
|
||||
system_area_options = opts->system_area_options & 0xfc;
|
||||
system_area_options = opts->system_area_options & 0xfffffffc;
|
||||
}
|
||||
if ((system_area_options & 0xfc) != 0)
|
||||
for (i = 0; i < 4; i++)
|
||||
sa_type = (system_area_options >> 2) & 0x3f;
|
||||
if (sa_type != 0 && sa_type != 3)
|
||||
for (i = 0; i < ISO_MAX_PARTITIONS; i++)
|
||||
if (opts->appended_partitions[i] != NULL)
|
||||
return ISO_NON_MBR_SYS_AREA;
|
||||
|
||||
@ -1641,9 +1729,9 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
target->partition_secs_per_head = opts->partition_secs_per_head;
|
||||
target->partition_heads_per_cyl = opts->partition_heads_per_cyl;
|
||||
if (target->partition_secs_per_head == 0)
|
||||
target->partition_secs_per_head = 63;
|
||||
target->partition_secs_per_head = 32;
|
||||
if (target->partition_heads_per_cyl == 0)
|
||||
target->partition_heads_per_cyl = 255;
|
||||
target->partition_heads_per_cyl = 64;
|
||||
target->eff_partition_offset = 0;
|
||||
target->partition_root = NULL;
|
||||
target->partition_l_table_pos = 0;
|
||||
@ -1708,7 +1796,13 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
target->mipsel_p_vaddr = 0;
|
||||
target->mipsel_p_filesz = 0;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
target->empty_file_block = 0;
|
||||
target->tree_end_block = 0;
|
||||
|
||||
target->wthread_is_running = 0;
|
||||
|
||||
for (i = 0; i < ISO_MAX_PARTITIONS; i++) {
|
||||
target->appended_partitions[i] = NULL;
|
||||
if (opts->appended_partitions[i] != NULL) {
|
||||
target->appended_partitions[i] =
|
||||
strdup(opts->appended_partitions[i]);
|
||||
@ -1716,9 +1810,10 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
return ISO_OUT_OF_MEM;
|
||||
target->appended_part_types[i] = opts->appended_part_types[i];
|
||||
}
|
||||
target->appended_part_prepad[i] = 0;
|
||||
target->appended_part_start[i] = target->appended_part_size[i] = 0;
|
||||
}
|
||||
|
||||
strcpy(target->ascii_disc_label, opts->ascii_disc_label);
|
||||
|
||||
/*
|
||||
* 2. Based on those options, create needed writers: iso, joliet...
|
||||
@ -1749,8 +1844,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
if (target->iso1999) {
|
||||
nwriters++;
|
||||
}
|
||||
if (target->tail_blocks > 0)
|
||||
nwriters++;
|
||||
nwriters++; /* Tail padding writer */
|
||||
if ((target->md5_file_checksums & 1) || target->md5_session_checksum) {
|
||||
nwriters++;
|
||||
image_checksums_mad = 1; /* from here on the loaded checksums are
|
||||
@ -1809,6 +1903,11 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
/* Volume Descriptor Set Terminator */
|
||||
target->curblock++;
|
||||
|
||||
/* All empty files point to the Volume Descriptor Set Terminator
|
||||
* rather than to addresses of non-empty files.
|
||||
*/
|
||||
target->empty_file_block = target->curblock - 1;
|
||||
|
||||
/*
|
||||
* Create the writer for possible padding to ensure that in case of image
|
||||
* growing we can safely overwrite the first 64 KiB of image.
|
||||
@ -1827,11 +1926,9 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
|
||||
|
||||
/* IMPORTANT: This must be the last writer before the checksum writer */
|
||||
if (target->tail_blocks > 0) {
|
||||
ret = zero_writer_create(target, target->tail_blocks);
|
||||
if (ret < 0)
|
||||
goto target_cleanup;
|
||||
}
|
||||
ret = zero_writer_create(target, target->tail_blocks, 1);
|
||||
if (ret < 0)
|
||||
goto target_cleanup;
|
||||
|
||||
if ((target->md5_file_checksums & 1) || target->md5_session_checksum) {
|
||||
ret = checksum_writer_create(target);
|
||||
@ -1885,8 +1982,15 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
if (i == el_torito_writer_index)
|
||||
continue;
|
||||
|
||||
/* Exposing address of data start to IsoWriteOpts */
|
||||
/* Exposing address of data start to IsoWriteOpts and memorizing
|
||||
this address for all files which have no block address:
|
||||
symbolic links, device files, empty data files.
|
||||
filesrc_writer_compute_data_blocks() and filesrc_writer_write_data()
|
||||
will account resp. write this single block.
|
||||
*/
|
||||
if (i == file_src_writer_index) {
|
||||
if (! target->old_empty)
|
||||
target->empty_file_block = target->curblock;
|
||||
opts->data_start_lba = target->curblock;
|
||||
}
|
||||
|
||||
@ -2018,6 +2122,20 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
/* This was possibly altered by above overwrite buffer production */
|
||||
target->vol_space_size = target->curblock - target->ms_block;
|
||||
|
||||
/*
|
||||
*/
|
||||
#define Libisofs_print_size_no_forK 1
|
||||
|
||||
#ifdef Libisofs_print_size_no_forK
|
||||
if (opts->will_cancel) {
|
||||
iso_msg_debug(target->image->id,
|
||||
"Will not start write thread because of iso_write_opts_set_will_cancel");
|
||||
*img = target;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* 4. Create and start writing thread */
|
||||
if (target->md5_session_checksum) {
|
||||
/* After any fake writes are done: Initialize image checksum context */
|
||||
@ -2059,6 +2177,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
ret = ISO_THREAD_ERROR;
|
||||
goto target_cleanup;
|
||||
}
|
||||
target->wthread_is_running= 1;
|
||||
|
||||
/*
|
||||
* Notice that once we reach this point, target belongs to the writer
|
||||
@ -2115,8 +2234,11 @@ static void bs_free_data(struct burn_source *bs)
|
||||
iso_ring_buffer_reader_close(target->buffer, 0);
|
||||
|
||||
/* wait until writer thread finishes */
|
||||
pthread_join(target->wthread, NULL);
|
||||
iso_msg_debug(target->image->id, "Writer thread joined");
|
||||
if (target->wthread_is_running) {
|
||||
pthread_join(target->wthread, NULL);
|
||||
target->wthread_is_running = 0;
|
||||
iso_msg_debug(target->image->id, "Writer thread joined");
|
||||
}
|
||||
}
|
||||
|
||||
iso_msg_debug(target->image->id,
|
||||
@ -2148,9 +2270,11 @@ int bs_cancel(struct burn_source *bs)
|
||||
}
|
||||
|
||||
/* wait until writer thread finishes */
|
||||
pthread_join(target->wthread, NULL);
|
||||
|
||||
iso_msg_debug(target->image->id, "Writer thread joined");
|
||||
if (target->wthread_is_running) {
|
||||
pthread_join(target->wthread, NULL);
|
||||
target->wthread_is_running = 0;
|
||||
iso_msg_debug(target->image->id, "Writer thread joined");
|
||||
}
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
@ -2213,6 +2337,8 @@ int iso_write(Ecma119Image *target, void *buf, size_t count)
|
||||
/* reader cancelled */
|
||||
return ISO_CANCELED;
|
||||
}
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (target->checksum_ctx != NULL) {
|
||||
/* Add to image checksum */
|
||||
target->checksum_counter += count;
|
||||
@ -2224,7 +2350,7 @@ int iso_write(Ecma119Image *target, void *buf, size_t count)
|
||||
return ret;
|
||||
|
||||
/* total size is 0 when writing the overwrite buffer */
|
||||
if (ret > 0 && (target->total_size != (off_t) 0)){
|
||||
if (target->total_size != (off_t) 0){
|
||||
unsigned int kbw, kbt;
|
||||
int percent;
|
||||
|
||||
@ -2241,7 +2367,7 @@ int iso_write(Ecma119Image *target, void *buf, size_t count)
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
int iso_write_opts_new(IsoWriteOpts **opts, int profile)
|
||||
@ -2306,8 +2432,13 @@ int iso_write_opts_new(IsoWriteOpts **opts, int profile)
|
||||
#endif /* Libisofs_with_libjtE */
|
||||
|
||||
wopts->tail_blocks = 0;
|
||||
for (i = 0; i < 4; i++)
|
||||
for (i = 0; i < ISO_MAX_PARTITIONS; i++)
|
||||
wopts->appended_partitions[i] = NULL;
|
||||
wopts->ascii_disc_label[0] = 0;
|
||||
wopts->will_cancel = 0;
|
||||
wopts->allow_dir_id_ext = 0;
|
||||
wopts->old_empty = 0;
|
||||
wopts->untranslated_name_len = 0;
|
||||
|
||||
*opts = wopts;
|
||||
return ISO_SUCCESS;
|
||||
@ -2323,13 +2454,22 @@ void iso_write_opts_free(IsoWriteOpts *opts)
|
||||
free(opts->output_charset);
|
||||
if (opts->system_area_data != NULL)
|
||||
free(opts->system_area_data);
|
||||
for (i = 0; i < 4; i++)
|
||||
for (i = 0; i < ISO_MAX_PARTITIONS; i++)
|
||||
if (opts->appended_partitions[i] != NULL)
|
||||
free(opts->appended_partitions[i]);
|
||||
|
||||
free(opts);
|
||||
}
|
||||
|
||||
int iso_write_opts_set_will_cancel(IsoWriteOpts *opts, int will_cancel)
|
||||
{
|
||||
if (opts == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
opts->will_cancel = !!will_cancel;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
int iso_write_opts_set_iso_level(IsoWriteOpts *opts, int level)
|
||||
{
|
||||
if (opts == NULL) {
|
||||
@ -2387,6 +2527,40 @@ int iso_write_opts_set_aaip(IsoWriteOpts *opts, int enable)
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
int iso_write_opts_set_old_empty(IsoWriteOpts *opts, int enable)
|
||||
{
|
||||
if (opts == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
opts->old_empty = enable ? 1 : 0;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
int iso_write_opts_set_untranslated_name_len(IsoWriteOpts *opts, int len)
|
||||
{
|
||||
if (opts == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
if (len == -1)
|
||||
opts->untranslated_name_len = ISO_UNTRANSLATED_NAMES_MAX;
|
||||
else if(len == 0)
|
||||
opts->untranslated_name_len = 0;
|
||||
else if(len > ISO_UNTRANSLATED_NAMES_MAX || len < 0)
|
||||
return ISO_WRONG_ARG_VALUE;
|
||||
else
|
||||
opts->untranslated_name_len = len;
|
||||
return opts->untranslated_name_len;
|
||||
}
|
||||
|
||||
int iso_write_opts_set_allow_dir_id_ext(IsoWriteOpts *opts, int allow)
|
||||
{
|
||||
if (opts == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
opts->allow_dir_id_ext = allow ? 1 : 0;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
int iso_write_opts_set_omit_version_numbers(IsoWriteOpts *opts, int omit)
|
||||
{
|
||||
if (opts == NULL) {
|
||||
@ -2468,6 +2642,15 @@ int iso_write_opts_set_joliet_longer_paths(IsoWriteOpts *opts, int allow)
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
int iso_write_opts_set_joliet_long_names(IsoWriteOpts *opts, int allow)
|
||||
{
|
||||
if (opts == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
opts->joliet_long_names = allow ? 1 : 0;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
int iso_write_opts_set_rrip_version_1_10(IsoWriteOpts *opts, int oldvers)
|
||||
{
|
||||
if (opts == NULL) {
|
||||
@ -2737,7 +2920,7 @@ int iso_write_opts_set_system_area(IsoWriteOpts *opts, char data[32768],
|
||||
memcpy(opts->system_area_data, data, 32768);
|
||||
}
|
||||
if (!(flag & 4))
|
||||
opts->system_area_options = options & 0xff;
|
||||
opts->system_area_options = options & 0x3ff;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
@ -2806,7 +2989,7 @@ int iso_write_opts_set_tail_blocks(IsoWriteOpts *opts, uint32_t num_blocks)
|
||||
int iso_write_opts_set_partition_img(IsoWriteOpts *opts, int partition_number,
|
||||
uint8_t partition_type, char *image_path, int flag)
|
||||
{
|
||||
if (partition_number < 1 || partition_number > 4)
|
||||
if (partition_number < 1 || partition_number > ISO_MAX_PARTITIONS)
|
||||
return ISO_BAD_PARTITION_NO;
|
||||
|
||||
if (opts->appended_partitions[partition_number - 1] != NULL)
|
||||
@ -2819,3 +3002,10 @@ int iso_write_opts_set_partition_img(IsoWriteOpts *opts, int partition_number,
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
int iso_write_opts_set_disc_label(IsoWriteOpts *opts, char *label)
|
||||
{
|
||||
strncpy(opts->ascii_disc_label, label, ISO_DISC_LABEL_SIZE - 1);
|
||||
opts->ascii_disc_label[ISO_DISC_LABEL_SIZE - 1] = 0;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2009 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2011 Thomas Schmitt
|
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
@ -15,7 +15,14 @@
|
||||
#include "util.h"
|
||||
#include "buffer.h"
|
||||
|
||||
#ifdef HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#else
|
||||
#ifdef HAVE_INTTYPES_H
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#define BLOCK_SIZE 2048
|
||||
@ -32,11 +39,44 @@
|
||||
*/
|
||||
#define ISO_EXTENT_SIZE 0xFFFFF800
|
||||
|
||||
/*
|
||||
* The maximum number of partition images that can be registered. Depending
|
||||
* on the system area type, the effectively usable number may be smaller or
|
||||
* even 0.
|
||||
*/
|
||||
#define ISO_MAX_PARTITIONS 8
|
||||
|
||||
/*
|
||||
* The cylindersize with SUN Disk Label
|
||||
* (512 bytes/sector, 640 sectors/head, 1 head/cyl = 320 KiB).
|
||||
* Expressed in ECMA-119 blocks of 2048 bytes/block.
|
||||
*/
|
||||
#define ISO_SUN_CYL_SIZE 160
|
||||
|
||||
/*
|
||||
* Maximum length of a disc label text plus 1.
|
||||
*/
|
||||
#define ISO_DISC_LABEL_SIZE 129
|
||||
|
||||
|
||||
/* The maximum lenght of an specs violating ECMA-119 file identifier.
|
||||
The theoretical limit is 254 - 34 - 28 (len of SUSP CE entry) = 192
|
||||
Currently the practical limit is 254 - 34 - 96 (non-CE RR entries) - 28 (CE)
|
||||
*/
|
||||
#ifdef Libisofs_with_rrip_rR
|
||||
#define ISO_UNTRANSLATED_NAMES_MAX 92
|
||||
#else
|
||||
#define ISO_UNTRANSLATED_NAMES_MAX 96
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Holds the options for the image generation.
|
||||
*/
|
||||
struct iso_write_opts {
|
||||
|
||||
int will_cancel;
|
||||
|
||||
int level; /**< ISO level to write at. (ECMA-119, 10) */
|
||||
|
||||
/** Which extensions to support. */
|
||||
@ -54,6 +94,14 @@ struct iso_write_opts {
|
||||
* but it is supposed to work on most moderns systems. Use with caution.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Convert directory names for ECMA-119 the same way as other file names
|
||||
* but do not force dots or add version numbers.
|
||||
* This violates ECMA-119 by allowing one "." and especially ISO level 1
|
||||
* by allowing DOS style 8.3 names rather than only 8 characters.
|
||||
*/
|
||||
unsigned int allow_dir_id_ext :1;
|
||||
|
||||
/**
|
||||
* Omit the version number (";1") at the end of the ISO-9660 identifiers.
|
||||
* Version numbers are usually not used.
|
||||
@ -113,6 +161,11 @@ struct iso_write_opts {
|
||||
*/
|
||||
unsigned int joliet_longer_paths :1;
|
||||
|
||||
/**
|
||||
* Allow Joliet names up to 103 characters rather than 64.
|
||||
*/
|
||||
unsigned int joliet_long_names :1;
|
||||
|
||||
/**
|
||||
* Write Rock Ridge info as of specification RRIP-1.10 rather than
|
||||
* RRIP-1.12: signature "RRIP_1991A" rather than "IEEE_1282",
|
||||
@ -196,6 +249,26 @@ struct iso_write_opts {
|
||||
uid_t uid; /** uid to use when replace_uid == 2. */
|
||||
gid_t gid; /** gid to use when replace_gid == 2. */
|
||||
|
||||
/**
|
||||
* See API call iso_write_opts_set_old_empty().
|
||||
*/
|
||||
unsigned int old_empty :1;
|
||||
|
||||
/**
|
||||
* Extra Caution: This option breaks any assumptions about names that
|
||||
* are supported by ECMA-119 specifications.
|
||||
* Omit any translation which would make a file name compliant to the
|
||||
* ECMA-119 rules. This includes and exceeds omit_version_numbers,
|
||||
* max_37_char_filenames, no_force_dots bit0, allow_lowercase.
|
||||
* The maximum name length is given by this variable.
|
||||
* There is a length limit of ISO_UNTRANSLATED_NAMES_MAX characters,
|
||||
* because ECMA-119 allows 254 byte in a directory record, some
|
||||
* of them are occupied by ECMA-119, some more are needed for SUSP CE,
|
||||
* and some are fixely occupied by libisofs Rock Ridge code.
|
||||
* The default value 0 disables this feature.
|
||||
*/
|
||||
unsigned int untranslated_name_len;
|
||||
|
||||
/**
|
||||
* 0 to use IsoNode timestamps, 1 to use recording time, 2 to use
|
||||
* values from timestamp field. This has only meaning if RR extensions
|
||||
@ -337,8 +410,12 @@ struct iso_write_opts {
|
||||
/* Eventual disk file paths of prepared images which shall be appended
|
||||
after the ISO image and described by partiton table entries in a MBR
|
||||
*/
|
||||
char *appended_partitions[4];
|
||||
uint8_t appended_part_types[4];
|
||||
char *appended_partitions[ISO_MAX_PARTITIONS];
|
||||
uint8_t appended_part_types[ISO_MAX_PARTITIONS];
|
||||
|
||||
/* Eventual name of the non-ISO aspect of the image. E.g. SUN ASCII label.
|
||||
*/
|
||||
char ascii_disc_label[ISO_DISC_LABEL_SIZE];
|
||||
};
|
||||
|
||||
typedef struct ecma119_image Ecma119Image;
|
||||
@ -355,6 +432,8 @@ struct ecma119_image
|
||||
IsoImage *image;
|
||||
Ecma119Node *root;
|
||||
|
||||
int will_cancel :1;
|
||||
|
||||
unsigned int iso_level :2;
|
||||
|
||||
/* extensions */
|
||||
@ -371,6 +450,7 @@ struct ecma119_image
|
||||
unsigned int always_gmt :1;
|
||||
|
||||
/* relaxed constraints */
|
||||
unsigned int allow_dir_id_ext :1;
|
||||
unsigned int omit_version_numbers :2;
|
||||
unsigned int allow_deep_paths :1;
|
||||
unsigned int allow_longer_paths :1;
|
||||
@ -384,6 +464,9 @@ struct ecma119_image
|
||||
/** Allow paths on Joliet tree to be larger than 240 bytes */
|
||||
unsigned int joliet_longer_paths :1;
|
||||
|
||||
/** Allow Joliet names up to 103 characters rather than 64 */
|
||||
unsigned int joliet_long_names :1;
|
||||
|
||||
/** Write old fashioned RRIP-1.10 rather than RRIP-1.12 */
|
||||
unsigned int rrip_version_1_10 :1;
|
||||
|
||||
@ -415,6 +498,9 @@ struct ecma119_image
|
||||
mode_t dir_mode;
|
||||
time_t timestamp;
|
||||
|
||||
unsigned int old_empty :1;
|
||||
unsigned int untranslated_name_len;
|
||||
|
||||
/**
|
||||
* if sort files or not. Sorting is based of the weight of each file
|
||||
*/
|
||||
@ -442,6 +528,17 @@ struct ecma119_image
|
||||
*/
|
||||
uint32_t curblock;
|
||||
|
||||
/*
|
||||
* The address to be used for the content pointer of empty data files.
|
||||
*/
|
||||
uint32_t empty_file_block;
|
||||
|
||||
/*
|
||||
* The calculated block address after ECMA-119 tree and eventual
|
||||
* tree checksum tag.
|
||||
*/
|
||||
uint32_t tree_end_block;
|
||||
|
||||
/*
|
||||
* number of dirs in ECMA-119 tree, computed together with dir position,
|
||||
* and needed for path table computation in a efficient way
|
||||
@ -486,19 +583,27 @@ struct ecma119_image
|
||||
*/
|
||||
char *system_area_data;
|
||||
/*
|
||||
* bit0= Only with PC-BIOS DOS MBR
|
||||
* bit0= Only with DOS MBR
|
||||
* Make bytes 446 - 512 of the system area a partition
|
||||
* table which reserves partition 1 from byte 63*512 to the
|
||||
* end of the ISO image. Assumed are 63 secs/hed, 255 head/cyl.
|
||||
* (GRUB protective msdos label.)
|
||||
* This works with and without system_area_data.
|
||||
* bit1= Only with PC-BIOS DOS MBR
|
||||
* bit1= Only with DOS MBR
|
||||
* Apply isohybrid MBR patching to the system area.
|
||||
* This works only with system_area_data plus ISOLINUX boot image
|
||||
* and only if not bit0 is set.
|
||||
* bit2-7= System area type
|
||||
* 0= DOS MBR
|
||||
* 1= MIPS Big Endian Volume Header
|
||||
* 2= DEC Boot Block for MIPS Little Endian
|
||||
* 3= SUN Disk Label for SUN SPARC
|
||||
* bit8-9= Only with DOS MBR
|
||||
* Cylinder alignment mode eventually pads the image to make it
|
||||
* end at a cylinder boundary.
|
||||
* 0 = auto (align if bit1)
|
||||
* 1 = always align to cylinder boundary
|
||||
* 2 = never align to cylinder boundary
|
||||
*/
|
||||
int system_area_options;
|
||||
|
||||
@ -553,6 +658,7 @@ struct ecma119_image
|
||||
|
||||
/* writer thread descriptor */
|
||||
pthread_t wthread;
|
||||
int wthread_is_running;
|
||||
pthread_attr_t th_attr;
|
||||
|
||||
/* User settable PVD time stamps */
|
||||
@ -601,11 +707,14 @@ struct ecma119_image
|
||||
uint32_t mipsel_p_vaddr;
|
||||
uint32_t mipsel_p_filesz;
|
||||
|
||||
char *appended_partitions[4];
|
||||
uint8_t appended_part_types[4];
|
||||
char *appended_partitions[ISO_MAX_PARTITIONS];
|
||||
uint8_t appended_part_types[ISO_MAX_PARTITIONS];
|
||||
/* Counted in blocks of 2048 */
|
||||
uint32_t appended_part_start[4];
|
||||
uint32_t appended_part_size[4];
|
||||
uint32_t appended_part_prepad[ISO_MAX_PARTITIONS];
|
||||
uint32_t appended_part_start[ISO_MAX_PARTITIONS];
|
||||
uint32_t appended_part_size[ISO_MAX_PARTITIONS];
|
||||
|
||||
char ascii_disc_label[ISO_DISC_LABEL_SIZE];
|
||||
|
||||
};
|
||||
|
||||
|
@ -12,6 +12,9 @@
|
||||
#include "../config.h"
|
||||
#endif
|
||||
|
||||
/* Must be before ecma119.h because of eventual Libisofs_with_rrip_rR */
|
||||
#include "libisofs.h"
|
||||
|
||||
#include "ecma119_tree.h"
|
||||
#include "ecma119.h"
|
||||
#include "node.h"
|
||||
@ -29,7 +32,7 @@
|
||||
static
|
||||
int get_iso_name(Ecma119Image *img, IsoNode *iso, char **name)
|
||||
{
|
||||
int ret, relaxed;
|
||||
int ret, relaxed, free_ascii_name= 0, force_dots = 0, max_len;
|
||||
char *ascii_name;
|
||||
char *isoname= NULL;
|
||||
|
||||
@ -38,9 +41,16 @@ int get_iso_name(Ecma119Image *img, IsoNode *iso, char **name)
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
ret = str2ascii(img->input_charset, iso->name, &ascii_name);
|
||||
if (img->untranslated_name_len > 0) {
|
||||
ascii_name = iso->name;
|
||||
ret = 1;
|
||||
} else {
|
||||
ret = str2ascii(img->input_charset, iso->name, &ascii_name);
|
||||
free_ascii_name = 1;
|
||||
}
|
||||
if (ret < 0) {
|
||||
iso_msg_submit(img->image->id, ret, 0, "Can't convert %s", iso->name);
|
||||
iso_msg_submit(img->image->id, ret, 0,
|
||||
"Cannot convert name '%s' to ASCII", iso->name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -49,8 +59,18 @@ int get_iso_name(Ecma119Image *img, IsoNode *iso, char **name)
|
||||
} else {
|
||||
relaxed = (int)img->allow_lowercase;
|
||||
}
|
||||
if (iso->type == LIBISO_DIR) {
|
||||
if (img->max_37_char_filenames) {
|
||||
if (iso->type == LIBISO_DIR && !(img->allow_dir_id_ext)) {
|
||||
if (img->untranslated_name_len > 0) {
|
||||
if (strlen(ascii_name) > img->untranslated_name_len) {
|
||||
needs_transl:;
|
||||
iso_msg_submit(img->image->id, ISO_NAME_NEEDS_TRANSL, 0,
|
||||
"File name too long (%d > %d) for untranslated recording: '%s'",
|
||||
strlen(ascii_name), img->untranslated_name_len,
|
||||
ascii_name);
|
||||
return ISO_NAME_NEEDS_TRANSL;
|
||||
}
|
||||
isoname = strdup(ascii_name);
|
||||
} else if (img->max_37_char_filenames) {
|
||||
isoname = iso_r_dirid(ascii_name, 37, relaxed);
|
||||
} else if (img->iso_level == 1) {
|
||||
if (relaxed) {
|
||||
@ -60,32 +80,40 @@ int get_iso_name(Ecma119Image *img, IsoNode *iso, char **name)
|
||||
}
|
||||
} else {
|
||||
if (relaxed) {
|
||||
isoname = iso_r_dirid(ascii_name, 8, relaxed);
|
||||
isoname = iso_r_dirid(ascii_name, 31, relaxed);
|
||||
} else {
|
||||
isoname = iso_2_dirid(ascii_name);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (img->max_37_char_filenames) {
|
||||
isoname = iso_r_fileid(ascii_name, 36, relaxed,
|
||||
(img->no_force_dots & 1) ? 0 : 1);
|
||||
force_dots = !((img->no_force_dots & 1) || iso->type == LIBISO_DIR);
|
||||
if (img->untranslated_name_len > 0) {
|
||||
if (strlen(ascii_name) > img->untranslated_name_len)
|
||||
goto needs_transl;
|
||||
isoname = strdup(ascii_name);
|
||||
} else if (img->max_37_char_filenames) {
|
||||
isoname = iso_r_fileid(ascii_name, 36, relaxed, force_dots);
|
||||
} else if (img->iso_level == 1) {
|
||||
if (relaxed) {
|
||||
isoname = iso_r_fileid(ascii_name, 11, relaxed,
|
||||
(img->no_force_dots & 1) ? 0 : 1);
|
||||
if (relaxed || !force_dots) {
|
||||
if (strchr(ascii_name, '.') == NULL)
|
||||
max_len = 8;
|
||||
else
|
||||
max_len = 11;
|
||||
isoname = iso_r_fileid(ascii_name, max_len, relaxed,
|
||||
force_dots);
|
||||
} else {
|
||||
isoname = iso_1_fileid(ascii_name);
|
||||
}
|
||||
} else {
|
||||
if (relaxed) {
|
||||
isoname = iso_r_fileid(ascii_name, 30, relaxed,
|
||||
(img->no_force_dots & 1) ? 0 : 1);
|
||||
if (relaxed || !force_dots) {
|
||||
isoname = iso_r_fileid(ascii_name, 30, relaxed, force_dots);
|
||||
} else {
|
||||
isoname = iso_2_fileid(ascii_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
free(ascii_name);
|
||||
if (free_ascii_name)
|
||||
free(ascii_name);
|
||||
if (isoname != NULL) {
|
||||
*name = isoname;
|
||||
return ISO_SUCCESS;
|
||||
@ -416,8 +444,6 @@ int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree,
|
||||
!!hidden);
|
||||
if (cret < 0) {
|
||||
/* error */
|
||||
if (!hidden)
|
||||
ecma119_node_free(node);
|
||||
ret = cret;
|
||||
break;
|
||||
} else if (cret == ISO_SUCCESS && !hidden) {
|
||||
@ -537,6 +563,18 @@ int mangle_single_dir(Ecma119Image *img, Ecma119Node *dir, int max_file_len,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (img->untranslated_name_len) {
|
||||
/* This should not happen because no two IsoNode names should be
|
||||
identical and only unaltered IsoNode names should be seen here.
|
||||
Thus the Ema119Node names should be unique.
|
||||
*/
|
||||
iso_msg_submit(img->image->id, ISO_NAME_NEEDS_TRANSL, 0,
|
||||
"ECMA-119 file name collision: '%s'",
|
||||
children[i]->iso_name);
|
||||
ret = ISO_NAME_NEEDS_TRANSL;
|
||||
goto mangle_cleanup;
|
||||
}
|
||||
|
||||
/*
|
||||
* A max of 7 characters is good enought, it allows handling up to
|
||||
* 9,999,999 files with same name. We can increment this to
|
||||
@ -553,10 +591,11 @@ int mangle_single_dir(Ecma119Image *img, Ecma119Node *dir, int max_file_len,
|
||||
|
||||
/* compute name and extension */
|
||||
dot = strrchr(full_name, '.');
|
||||
if (dot != NULL && children[i]->type != ECMA119_DIR) {
|
||||
if (dot != NULL &&
|
||||
(children[i]->type != ECMA119_DIR || img->allow_dir_id_ext)) {
|
||||
|
||||
/*
|
||||
* File (not dir) with extension
|
||||
* File (normally not dir) with extension
|
||||
* Note that we don't need to check for placeholders, as
|
||||
* tree reparent happens later, so no placeholders can be
|
||||
* here at this time.
|
||||
@ -596,10 +635,10 @@ int mangle_single_dir(Ecma119Image *img, Ecma119Node *dir, int max_file_len,
|
||||
name[max] = '\0';
|
||||
}
|
||||
} else {
|
||||
/* Directory, or file without extension */
|
||||
/* Directory (normally), or file without extension */
|
||||
if (children[i]->type == ECMA119_DIR) {
|
||||
max = max_dir_len - digits;
|
||||
dot = NULL; /* dots have no meaning in dirs */
|
||||
dot = NULL; /* dots (normally) have no meaning in dirs */
|
||||
} else {
|
||||
max = max_file_len - digits;
|
||||
}
|
||||
@ -716,7 +755,9 @@ int mangle_tree(Ecma119Image *img, int recurse)
|
||||
int max_file, max_dir;
|
||||
Ecma119Node *root;
|
||||
|
||||
if (img->max_37_char_filenames) {
|
||||
if (img->untranslated_name_len > 0) {
|
||||
max_file = max_dir = img->untranslated_name_len;
|
||||
} else if (img->max_37_char_filenames) {
|
||||
max_file = max_dir = 37;
|
||||
} else if (img->iso_level == 1) {
|
||||
max_file = 12; /* 8 + 3 + 1 */
|
||||
@ -1033,11 +1074,12 @@ int match_hardlinks(Ecma119Image *img, Ecma119Node *dir, int flag)
|
||||
iso_node_get_id(nodes[0]->node, &fs_id, &dev_id, &img_ino, 1);
|
||||
family_start = 0;
|
||||
for (i = 1; i < node_count; i++) {
|
||||
if (ecma119_node_cmp_hard(nodes + (i - 1), nodes + i) == 0) {
|
||||
if (nodes[i]->type != ECMA119_DIR &&
|
||||
ecma119_node_cmp_hard(nodes + (i - 1), nodes + i) == 0) {
|
||||
/* Still in same ino family */
|
||||
if (img_ino == 0) { /* Just in case any member knows its img_ino */
|
||||
iso_node_get_id(nodes[0]->node, &fs_id, &dev_id, &img_ino, 1);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
family_set_ino(img, nodes, family_start, i, img_ino, prev_ino, 0);
|
||||
|
@ -12,8 +12,8 @@
|
||||
#include "../config.h"
|
||||
#endif
|
||||
|
||||
#include "libisofs.h"
|
||||
#include "eltorito.h"
|
||||
#include "stream.h"
|
||||
#include "fsource.h"
|
||||
#include "filesrc.h"
|
||||
#include "image.h"
|
||||
@ -239,6 +239,7 @@ int iso_tree_add_boot_node(IsoDir *parent, const char *name, IsoBoot **boot)
|
||||
IsoBoot *node;
|
||||
IsoNode **pos;
|
||||
time_t now;
|
||||
int ret;
|
||||
|
||||
if (parent == NULL || name == NULL || boot == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
@ -248,9 +249,9 @@ int iso_tree_add_boot_node(IsoDir *parent, const char *name, IsoBoot **boot)
|
||||
}
|
||||
|
||||
/* check if the name is valid */
|
||||
if (!iso_node_is_valid_name(name)) {
|
||||
return ISO_WRONG_ARG_VALUE;
|
||||
}
|
||||
ret = iso_node_is_valid_name(name);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* find place where to insert */
|
||||
pos = &(parent->children);
|
||||
@ -309,6 +310,7 @@ int create_image(IsoImage *image, const char *image_path,
|
||||
int boot_media_type = 0;
|
||||
int load_sectors = 0; /* number of sector to load */
|
||||
unsigned char partition_type = 0;
|
||||
off_t size;
|
||||
IsoNode *imgfile;
|
||||
IsoStream *stream;
|
||||
|
||||
@ -317,6 +319,9 @@ int create_image(IsoImage *image, const char *image_path,
|
||||
return ret;
|
||||
}
|
||||
if (ret == 0) {
|
||||
iso_msg_submit(image->id, ISO_NODE_DOESNT_EXIST, 0,
|
||||
"El Torito boot image file missing in ISO image: '%s'",
|
||||
image_path);
|
||||
return ISO_NODE_DOESNT_EXIST;
|
||||
}
|
||||
|
||||
@ -331,9 +336,16 @@ int create_image(IsoImage *image, const char *image_path,
|
||||
return ISO_BOOT_IMAGE_NOT_VALID;
|
||||
}
|
||||
|
||||
size = iso_stream_get_size(stream);
|
||||
if (size <= 0) {
|
||||
iso_msg_submit(image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
|
||||
"Boot image file is empty");
|
||||
return ISO_BOOT_IMAGE_NOT_VALID;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case ELTORITO_FLOPPY_EMUL:
|
||||
switch (iso_stream_get_size(stream)) {
|
||||
switch (size) {
|
||||
case 1200 * 1024:
|
||||
boot_media_type = 1; /* 1.2 meg diskette */
|
||||
break;
|
||||
@ -471,6 +483,9 @@ int iso_image_set_boot_image(IsoImage *image, const char *image_path,
|
||||
catname[0] = '\0';
|
||||
ret = iso_tree_path_to_node(image, catdir, &p);
|
||||
if (ret <= 0) {
|
||||
iso_msg_submit(image->id, ISO_NODE_DOESNT_EXIST, 0,
|
||||
"Cannot find directory for El Torito boot catalog in ISO image: '%s'",
|
||||
catdir);
|
||||
free(catdir);
|
||||
return ret < 0 ? ret : ISO_NODE_DOESNT_EXIST;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* 2010 Thomas Schmitt
|
||||
* 2010 - 2011 Thomas Schmitt
|
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
@ -232,6 +232,12 @@ int filesrc_writer_compute_data_blocks(IsoImageWriter *writer)
|
||||
|
||||
t = writer->target;
|
||||
|
||||
/* Normally reserve a single zeroed block for all files which have
|
||||
no block address: symbolic links, device files, empty data files.
|
||||
*/
|
||||
if (! t->old_empty)
|
||||
t->curblock++;
|
||||
|
||||
/* on appendable images, ms files shouldn't be included */
|
||||
if (t->appendable) {
|
||||
inc_item = is_ms_file;
|
||||
@ -266,7 +272,12 @@ int filesrc_writer_compute_data_blocks(IsoImageWriter *writer)
|
||||
/*
|
||||
* final section
|
||||
*/
|
||||
file->sections[extent].block = t->curblock + extent * (ISO_EXTENT_SIZE / BLOCK_SIZE);
|
||||
if (section_size <= 0) {
|
||||
file->sections[extent].block = t->empty_file_block;
|
||||
} else {
|
||||
file->sections[extent].block =
|
||||
t->curblock + extent * (ISO_EXTENT_SIZE / BLOCK_SIZE);
|
||||
}
|
||||
file->sections[extent].size = (uint32_t)section_size;
|
||||
|
||||
t->curblock += DIV_UP(iso_file_src_get_size(file), BLOCK_SIZE);
|
||||
@ -342,11 +353,22 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
|
||||
return ISO_ASSERT_FAILURE;
|
||||
}
|
||||
|
||||
memset(buffer, 0, BLOCK_SIZE);
|
||||
t = writer->target;
|
||||
filelist = writer->data;
|
||||
|
||||
iso_msg_debug(t->image->id, "Writing Files...");
|
||||
|
||||
/* Normally write a single zeroed block as block address target for all
|
||||
files which have no block address:
|
||||
symbolic links, device files, empty data files.
|
||||
*/
|
||||
if (! t->old_empty) {
|
||||
ret = iso_write(t, buffer, BLOCK_SIZE);
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
while ((file = filelist[i++]) != NULL) {
|
||||
was_error = 0;
|
||||
|
@ -13,7 +13,13 @@
|
||||
#include "stream.h"
|
||||
#include "ecma119.h"
|
||||
|
||||
#ifdef HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#else
|
||||
#ifdef HAVE_INTTYPES_H
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
struct Iso_File_Src
|
||||
{
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2011 Thomas Schmitt
|
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
@ -20,6 +20,7 @@
|
||||
#include "../libisofs.h"
|
||||
#include "../filter.h"
|
||||
#include "../fsource.h"
|
||||
#include "../stream.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
@ -40,7 +41,7 @@
|
||||
* for classical pipe filtering.
|
||||
*/
|
||||
|
||||
|
||||
/* IMPORTANT: Any change must be reflected by extf_clone_stream() */
|
||||
/*
|
||||
* Individual runtime properties exist only as long as the stream is opened.
|
||||
*/
|
||||
@ -598,6 +599,36 @@ IsoStream *extf_get_input_stream(IsoStream *stream, int flag)
|
||||
return data->orig;
|
||||
}
|
||||
|
||||
static
|
||||
int extf_clone_stream(IsoStream *old_stream, IsoStream **new_stream, int flag)
|
||||
{
|
||||
int ret;
|
||||
IsoStream *new_input_stream, *stream;
|
||||
ExternalFilterStreamData *stream_data, *old_stream_data;
|
||||
|
||||
if (flag)
|
||||
return ISO_STREAM_NO_CLONE; /* unknown option required */
|
||||
|
||||
stream_data = calloc(1, sizeof(ExternalFilterStreamData));
|
||||
if (stream_data == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
ret = iso_stream_clone_filter_common(old_stream, &stream,
|
||||
&new_input_stream, 0);
|
||||
if (ret < 0) {
|
||||
free((char *) stream_data);
|
||||
return ret;
|
||||
}
|
||||
old_stream_data = (ExternalFilterStreamData *) old_stream->data;
|
||||
stream_data->id = ++extf_ino_id;
|
||||
stream_data->orig = new_input_stream;
|
||||
stream_data->cmd = old_stream_data->cmd;
|
||||
stream_data->cmd->refcount++;
|
||||
stream_data->size = old_stream_data->size;
|
||||
stream_data->running = NULL;
|
||||
stream->data = stream_data;
|
||||
*new_stream = stream;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
static
|
||||
int extf_cmp_ino(IsoStream *s1, IsoStream *s2);
|
||||
@ -605,7 +636,7 @@ int extf_cmp_ino(IsoStream *s1, IsoStream *s2);
|
||||
|
||||
|
||||
IsoStreamIface extf_stream_class = {
|
||||
3,
|
||||
4,
|
||||
"extf",
|
||||
extf_stream_open,
|
||||
extf_stream_close,
|
||||
@ -616,7 +647,8 @@ IsoStreamIface extf_stream_class = {
|
||||
extf_stream_free,
|
||||
extf_update_size,
|
||||
extf_get_input_stream,
|
||||
extf_cmp_ino
|
||||
extf_cmp_ino,
|
||||
extf_clone_stream
|
||||
};
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2011 Thomas Schmitt
|
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
@ -25,6 +25,7 @@
|
||||
#include "../filter.h"
|
||||
#include "../fsource.h"
|
||||
#include "../util.h"
|
||||
#include "../stream.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
@ -153,6 +154,7 @@ static int gzip_compression_level = 6;
|
||||
/*
|
||||
* The data payload of an individual Gzip Filter IsoStream
|
||||
*/
|
||||
/* IMPORTANT: Any change must be reflected by gzip_clone_stream() */
|
||||
typedef struct
|
||||
{
|
||||
IsoStream *orig;
|
||||
@ -529,12 +531,51 @@ IsoStream *gzip_get_input_stream(IsoStream *stream, int flag)
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
int gzip_clone_stream(IsoStream *old_stream, IsoStream **new_stream, int flag)
|
||||
{
|
||||
|
||||
#ifdef Libisofs_with_zliB
|
||||
|
||||
int ret;
|
||||
IsoStream *new_input_stream, *stream;
|
||||
GzipFilterStreamData *stream_data, *old_stream_data;
|
||||
|
||||
if (flag)
|
||||
return ISO_STREAM_NO_CLONE; /* unknown option required */
|
||||
|
||||
stream_data = calloc(1, sizeof(GzipFilterStreamData));
|
||||
if (stream_data == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
ret = iso_stream_clone_filter_common(old_stream, &stream,
|
||||
&new_input_stream, 0);
|
||||
if (ret < 0) {
|
||||
free((char *) stream_data);
|
||||
return ret;
|
||||
}
|
||||
old_stream_data = (GzipFilterStreamData *) old_stream->data;
|
||||
stream_data->orig = new_input_stream;
|
||||
stream_data->size = old_stream_data->size;
|
||||
stream_data->running = NULL;
|
||||
stream_data->id = ++gzip_ino_id;
|
||||
stream->data = stream_data;
|
||||
*new_stream = stream;
|
||||
return ISO_SUCCESS;
|
||||
|
||||
#else /* Libisofs_with_zliB */
|
||||
|
||||
return ISO_STREAM_NO_CLONE;
|
||||
|
||||
#endif /* ! Libisofs_with_zliB */
|
||||
|
||||
}
|
||||
|
||||
static
|
||||
int gzip_cmp_ino(IsoStream *s1, IsoStream *s2);
|
||||
|
||||
|
||||
IsoStreamIface gzip_stream_compress_class = {
|
||||
3,
|
||||
4,
|
||||
"gzip",
|
||||
gzip_stream_open,
|
||||
gzip_stream_close,
|
||||
@ -545,12 +586,13 @@ IsoStreamIface gzip_stream_compress_class = {
|
||||
gzip_stream_free,
|
||||
gzip_update_size,
|
||||
gzip_get_input_stream,
|
||||
gzip_cmp_ino
|
||||
gzip_cmp_ino,
|
||||
gzip_clone_stream
|
||||
};
|
||||
|
||||
|
||||
IsoStreamIface gzip_stream_uncompress_class = {
|
||||
3,
|
||||
4,
|
||||
"pizg",
|
||||
gzip_stream_open,
|
||||
gzip_stream_close,
|
||||
@ -561,7 +603,8 @@ IsoStreamIface gzip_stream_uncompress_class = {
|
||||
gzip_stream_free,
|
||||
gzip_update_size,
|
||||
gzip_get_input_stream,
|
||||
gzip_cmp_ino
|
||||
gzip_cmp_ino,
|
||||
gzip_clone_stream
|
||||
};
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2011 Thomas Schmitt
|
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
@ -22,6 +22,7 @@
|
||||
#include "../filter.h"
|
||||
#include "../fsource.h"
|
||||
#include "../util.h"
|
||||
#include "../stream.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
@ -167,6 +168,7 @@ static int ziso_compression_level = 6;
|
||||
|
||||
/*
|
||||
* The common data payload of an individual Zisofs Filter IsoStream
|
||||
* IMPORTANT: Any change must be reflected by ziso_clone_stream().
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
@ -183,6 +185,7 @@ typedef struct
|
||||
|
||||
/*
|
||||
* The data payload of an individual Zisofs Filter Compressor IsoStream
|
||||
* IMPORTANT: Any change must be reflected by ziso_clone_stream().
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
@ -198,6 +201,7 @@ typedef struct
|
||||
|
||||
/*
|
||||
* The data payload of an individual Zisofs Filter Uncompressor IsoStream
|
||||
* IMPORTANT: Any change must be reflected by ziso_clone_stream().
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
@ -779,13 +783,63 @@ IsoStream *ziso_get_input_stream(IsoStream *stream, int flag)
|
||||
return data->orig;
|
||||
}
|
||||
|
||||
static
|
||||
int ziso_clone_stream(IsoStream *old_stream, IsoStream **new_stream, int flag)
|
||||
{
|
||||
int ret;
|
||||
IsoStream *new_input_stream = NULL, *stream = NULL;
|
||||
ZisofsFilterStreamData *stream_data, *old_stream_data;
|
||||
ZisofsUncomprStreamData *uncompr, *old_uncompr;
|
||||
ZisofsComprStreamData *compr, *old_compr;
|
||||
|
||||
if (flag)
|
||||
return ISO_STREAM_NO_CLONE; /* unknown option required */
|
||||
|
||||
ret = iso_stream_clone_filter_common(old_stream, &stream,
|
||||
&new_input_stream, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (old_stream->class->read == &ziso_stream_uncompress) {
|
||||
uncompr = calloc(1, sizeof(ZisofsUncomprStreamData));
|
||||
if (uncompr == NULL)
|
||||
goto no_mem;
|
||||
stream_data = (ZisofsFilterStreamData *) uncompr;
|
||||
old_uncompr = (ZisofsUncomprStreamData *) old_stream->data;
|
||||
uncompr->header_size_div4 = old_uncompr->header_size_div4;
|
||||
uncompr->block_size_log2 = old_uncompr->block_size_log2;
|
||||
} else {
|
||||
compr = calloc(1, sizeof(ZisofsComprStreamData));
|
||||
if (compr == NULL)
|
||||
goto no_mem;
|
||||
stream_data = (ZisofsFilterStreamData *) compr;
|
||||
old_compr = (ZisofsComprStreamData *) old_stream->data;
|
||||
compr->orig_size = old_compr->orig_size;
|
||||
compr->block_pointers = NULL;
|
||||
}
|
||||
old_stream_data = (ZisofsFilterStreamData *) old_stream->data;
|
||||
stream_data->orig = new_input_stream;
|
||||
stream_data->size = old_stream_data->size;
|
||||
stream_data->running = NULL;
|
||||
stream_data->id = ++ziso_ino_id;
|
||||
stream->data = stream_data;
|
||||
*new_stream = stream;
|
||||
return ISO_SUCCESS;
|
||||
no_mem:
|
||||
if (new_input_stream != NULL)
|
||||
iso_stream_unref(new_input_stream);
|
||||
if (stream != NULL)
|
||||
iso_stream_unref(stream);
|
||||
return ISO_OUT_OF_MEM;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
int ziso_cmp_ino(IsoStream *s1, IsoStream *s2);
|
||||
|
||||
|
||||
IsoStreamIface ziso_stream_compress_class = {
|
||||
3,
|
||||
4,
|
||||
"ziso",
|
||||
ziso_stream_open,
|
||||
ziso_stream_close,
|
||||
@ -796,12 +850,13 @@ IsoStreamIface ziso_stream_compress_class = {
|
||||
ziso_stream_free,
|
||||
ziso_update_size,
|
||||
ziso_get_input_stream,
|
||||
ziso_cmp_ino
|
||||
ziso_cmp_ino,
|
||||
ziso_clone_stream
|
||||
};
|
||||
|
||||
|
||||
IsoStreamIface ziso_stream_uncompress_class = {
|
||||
3,
|
||||
4,
|
||||
"osiz",
|
||||
ziso_stream_open,
|
||||
ziso_stream_close,
|
||||
@ -812,7 +867,8 @@ IsoStreamIface ziso_stream_uncompress_class = {
|
||||
ziso_stream_free,
|
||||
ziso_update_size,
|
||||
ziso_get_input_stream,
|
||||
ziso_cmp_ino
|
||||
ziso_cmp_ino,
|
||||
ziso_clone_stream
|
||||
};
|
||||
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2009 - 2010 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2011 Thomas Schmitt
|
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
@ -35,11 +35,6 @@
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX Libisofs_default_path_maX
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Options for image reading.
|
||||
* There are four kind of options:
|
||||
@ -72,7 +67,7 @@ struct iso_read_opts
|
||||
unsigned int nojoliet : 1; /*< Do not read Joliet extensions */
|
||||
unsigned int noiso1999 : 1; /*< Do not read ISO 9660:1999 enhanced tree */
|
||||
unsigned int noaaip : 1; /* Do not read AAIP extension for xattr and ACL */
|
||||
unsigned int nomd5 : 1; /* Do not read MD5 array */
|
||||
unsigned int nomd5 : 2; /* Do not read MD5 array */
|
||||
|
||||
/**
|
||||
* Hand out new inode numbers and overwrite eventually read PX inode
|
||||
@ -267,7 +262,7 @@ typedef struct
|
||||
int aaip_load;
|
||||
|
||||
/** Whether the MD5 array shall be read if available.
|
||||
* 1 = yes , 0 = no
|
||||
* 2 = yes, but do not check tags , 1 = yes , 0 = no
|
||||
*/
|
||||
int md5_load;
|
||||
|
||||
@ -317,6 +312,7 @@ typedef struct
|
||||
|
||||
typedef struct image_fs_data ImageFileSourceData;
|
||||
|
||||
/* IMPORTANT: Any change must be reflected by ifs_clone_src */
|
||||
struct image_fs_data
|
||||
{
|
||||
IsoImageFilesystem *fs; /**< reference to the image it belongs to */
|
||||
@ -952,6 +948,7 @@ int ifs_readlink(IsoFileSource *src, char *buf, size_t bufsiz)
|
||||
{
|
||||
char *dest;
|
||||
size_t len;
|
||||
int ret;
|
||||
ImageFileSourceData *data;
|
||||
|
||||
if (src == NULL || buf == NULL || src->data == NULL) {
|
||||
@ -970,14 +967,15 @@ int ifs_readlink(IsoFileSource *src, char *buf, size_t bufsiz)
|
||||
|
||||
dest = (char*)data->data.content;
|
||||
len = strlen(dest);
|
||||
if (bufsiz <= len) {
|
||||
|
||||
ret = ISO_SUCCESS;
|
||||
if (len >= bufsiz) {
|
||||
ret = ISO_RR_PATH_TOO_LONG;
|
||||
len = bufsiz - 1;
|
||||
}
|
||||
|
||||
strncpy(buf, dest, len);
|
||||
buf[len] = '\0';
|
||||
|
||||
return ISO_SUCCESS;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static
|
||||
@ -1043,10 +1041,87 @@ int ifs_get_aa_string(IsoFileSource *src, unsigned char **aa_string, int flag)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static
|
||||
int ifs_clone_src(IsoFileSource *old_source,
|
||||
IsoFileSource **new_source, int flag)
|
||||
{
|
||||
IsoFileSource *src = NULL;
|
||||
ImageFileSourceData *old_data, *new_data = NULL;
|
||||
char *new_name = NULL;
|
||||
struct iso_file_section *new_sections = NULL;
|
||||
void *new_aa_string = NULL;
|
||||
int i, ret;
|
||||
|
||||
if (flag)
|
||||
return ISO_STREAM_NO_CLONE; /* unknown option required */
|
||||
|
||||
old_data = (ImageFileSourceData *) old_source->data;
|
||||
*new_source = NULL;
|
||||
src = calloc(1, sizeof(IsoFileSource));
|
||||
if (src == NULL)
|
||||
goto no_mem;
|
||||
new_name = strdup(old_data->name);
|
||||
if (new_name == NULL)
|
||||
goto no_mem;
|
||||
new_data = calloc(1, sizeof(ImageFileSourceData));
|
||||
|
||||
if (new_data == NULL)
|
||||
goto no_mem;
|
||||
if (old_data->nsections > 0) {
|
||||
new_sections = calloc(old_data->nsections,
|
||||
sizeof(struct iso_file_section));
|
||||
if (new_sections == NULL)
|
||||
goto no_mem;
|
||||
}
|
||||
ret = aaip_xinfo_cloner(old_data->aa_string, &new_aa_string, 0);
|
||||
if (ret < 0)
|
||||
goto no_mem;
|
||||
|
||||
new_data->fs = old_data->fs;
|
||||
|
||||
new_data->parent = old_data->parent;
|
||||
|
||||
memcpy(&(new_data->info), &(old_data->info), sizeof(struct stat));
|
||||
new_data->name = new_name;
|
||||
new_data->sections = new_sections;
|
||||
new_data->nsections = old_data->nsections;
|
||||
for (i = 0; i < new_data->nsections; i++)
|
||||
memcpy(new_data->sections + i, old_data->sections + i,
|
||||
sizeof(struct iso_file_section));
|
||||
new_data->opened = old_data->opened;
|
||||
#ifdef Libisofs_with_zliB
|
||||
new_data->header_size_div4 = old_data->header_size_div4;
|
||||
new_data->block_size_log2 = old_data->block_size_log2;
|
||||
new_data->uncompressed_size = old_data->uncompressed_size;
|
||||
#endif
|
||||
new_data->data.content = NULL;
|
||||
new_data->aa_string = (unsigned char *) new_aa_string;
|
||||
|
||||
src->class = old_source->class;
|
||||
src->refcount = 1;
|
||||
src->data = new_data;
|
||||
*new_source = src;
|
||||
iso_file_source_ref(new_data->parent);
|
||||
iso_filesystem_ref(new_data->fs);
|
||||
return ISO_SUCCESS;
|
||||
no_mem:;
|
||||
if (src != NULL)
|
||||
free((char *) src);
|
||||
if (new_data != NULL)
|
||||
free((char *) new_data);
|
||||
if (new_name != NULL)
|
||||
free(new_name);
|
||||
if (new_sections != NULL)
|
||||
free((char *) new_sections);
|
||||
if (new_aa_string != NULL)
|
||||
aaip_xinfo_func(new_aa_string, 1);
|
||||
return ISO_OUT_OF_MEM;
|
||||
}
|
||||
|
||||
|
||||
IsoFileSourceIface ifs_class = {
|
||||
|
||||
1, /* version */
|
||||
2, /* version */
|
||||
ifs_get_path,
|
||||
ifs_get_name,
|
||||
ifs_lstat,
|
||||
@ -1060,7 +1135,8 @@ IsoFileSourceIface ifs_class = {
|
||||
ifs_get_filesystem,
|
||||
ifs_free,
|
||||
ifs_lseek,
|
||||
ifs_get_aa_string
|
||||
ifs_get_aa_string,
|
||||
ifs_clone_src
|
||||
|
||||
};
|
||||
|
||||
@ -2339,6 +2415,10 @@ int iso_src_check_sb_tree(IsoDataSource *src, uint32_t start_lba, int flag)
|
||||
ret = iso_util_eval_md5_tag(block, desired, start_lba + i,
|
||||
ctx, start_lba, &tag_type, &next_tag, 0);
|
||||
iso_md5_compute(ctx, block, 2048);
|
||||
if (ret == ISO_MD5_TAG_COPIED) { /* growing without emulated TOC */
|
||||
ret = 2;
|
||||
goto ex;
|
||||
}
|
||||
if (ret == ISO_MD5_AREA_CORRUPTED || ret == ISO_MD5_TAG_MISMATCH)
|
||||
ret = ISO_SB_TREE_CORRUPTED;
|
||||
if (ret < 0)
|
||||
@ -2425,7 +2505,12 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
|
||||
data->dir_mode = opts->dir_mode & ~S_IFMT;
|
||||
data->msgid = msgid;
|
||||
data->aaip_load = !opts->noaaip;
|
||||
data->md5_load = !opts->nomd5;
|
||||
if (opts->nomd5 == 0)
|
||||
data->md5_load = 1;
|
||||
else if (opts->nomd5 == 2)
|
||||
data->md5_load = 2;
|
||||
else
|
||||
data->md5_load = 0;
|
||||
data->aaip_version = -1;
|
||||
data->make_new_ino = opts->make_new_ino;
|
||||
data->num_bootimgs = 0;
|
||||
@ -2453,7 +2538,7 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
|
||||
ifs->free = ifs_fs_free;
|
||||
|
||||
/* read Volume Descriptors and ensure it is a valid image */
|
||||
if (data->md5_load) {
|
||||
if (data->md5_load == 1) {
|
||||
/* From opts->block on : check for superblock and tree tags */;
|
||||
ret = iso_src_check_sb_tree(src, opts->block, 0);
|
||||
if (ret < 0) {
|
||||
@ -2796,8 +2881,17 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
||||
break;
|
||||
if (idx < fsdata->num_bootimgs) {
|
||||
/* it is boot image node */
|
||||
|
||||
if (image->bootcat->bootimages[idx]->image != NULL) {
|
||||
/* idx is already occupied, try to find unoccupied one
|
||||
which has the same block address.
|
||||
*/
|
||||
for (; idx < fsdata->num_bootimgs; idx++)
|
||||
if (fsdata->eltorito && data->sections[0].block ==
|
||||
fsdata->bootblocks[idx] &&
|
||||
image->bootcat->bootimages[idx]->image == NULL)
|
||||
break;
|
||||
}
|
||||
if (idx >= fsdata->num_bootimgs) {
|
||||
ret = iso_msg_submit(image->id, ISO_EL_TORITO_WARN, 0,
|
||||
"More than one ISO node has been found for the same boot image.");
|
||||
if (ret < 0) {
|
||||
@ -2829,10 +2923,10 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
||||
case S_IFLNK:
|
||||
{
|
||||
/* source is a symbolic link */
|
||||
char dest[PATH_MAX];
|
||||
char dest[LIBISOFS_NODE_PATH_MAX];
|
||||
IsoSymlink *link;
|
||||
|
||||
ret = iso_file_source_readlink(src, dest, PATH_MAX);
|
||||
ret = iso_file_source_readlink(src, dest, LIBISOFS_NODE_PATH_MAX);
|
||||
if (ret < 0) {
|
||||
free(name);
|
||||
return ret;
|
||||
@ -3146,6 +3240,8 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
|
||||
size_t size;
|
||||
void *ctx = NULL;
|
||||
char md5[16];
|
||||
struct el_torito_boot_catalog *catalog = NULL;
|
||||
ElToritoBootImage *boot_image = NULL;
|
||||
|
||||
if (image == NULL || src == NULL || opts == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
@ -3233,8 +3329,6 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
|
||||
|
||||
/* if old image has el-torito, add a new catalog */
|
||||
if (data->eltorito) {
|
||||
struct el_torito_boot_catalog *catalog;
|
||||
ElToritoBootImage *boot_image= NULL;
|
||||
|
||||
catalog = calloc(1, sizeof(struct el_torito_boot_catalog));
|
||||
if (catalog == NULL) {
|
||||
@ -3260,11 +3354,13 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
|
||||
memcpy(boot_image->selection_crit, data->selection_crits, 20);
|
||||
|
||||
catalog->bootimages[catalog->num_bootimages] = boot_image;
|
||||
boot_image = NULL;
|
||||
catalog->num_bootimages++;
|
||||
}
|
||||
for ( ; idx < Libisofs_max_boot_imageS; idx++)
|
||||
catalog->bootimages[idx] = NULL;
|
||||
image->bootcat = catalog;
|
||||
catalog = NULL; /* So it does not get freed */
|
||||
}
|
||||
|
||||
/* recursively add image */
|
||||
@ -3443,6 +3539,10 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
|
||||
image->fs = fsback;
|
||||
image->builder = blback;
|
||||
|
||||
if (catalog != NULL)
|
||||
el_torito_boot_catalog_free(catalog);
|
||||
if (boot_image != NULL)
|
||||
free((char *) boot_image);
|
||||
iso_file_source_unref(newroot);
|
||||
fs->close(fs);
|
||||
iso_filesystem_unref(fs);
|
||||
@ -3594,7 +3694,7 @@ int iso_read_opts_set_no_md5(IsoReadOpts *opts, int no_md5)
|
||||
if (opts == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
opts->nomd5 = no_md5 ? 1 : 0;
|
||||
opts->nomd5 = no_md5 == 2 ? 2 : no_md5 == 1 ? 1 : 0;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,7 @@ int iso_file_source_new_lfs(IsoFileSource *parent, const char *name,
|
||||
*/
|
||||
IsoFilesystem *lfs= NULL;
|
||||
|
||||
|
||||
/* IMPORTANT: Any change must be reflected by lfs_clone_src() */
|
||||
typedef struct
|
||||
{
|
||||
/** reference to the parent (if root it points to itself) */
|
||||
@ -412,7 +412,7 @@ int lfs_readdir(IsoFileSource *src, IsoFileSource **child)
|
||||
static
|
||||
int lfs_readlink(IsoFileSource *src, char *buf, size_t bufsiz)
|
||||
{
|
||||
int size;
|
||||
int size, ret;
|
||||
_LocalFsFileSource *data;
|
||||
char *path;
|
||||
|
||||
@ -431,7 +431,7 @@ int lfs_readlink(IsoFileSource *src, char *buf, size_t bufsiz)
|
||||
* invoke readlink, with bufsiz -1 to reserve an space for
|
||||
* the NULL character
|
||||
*/
|
||||
size = readlink(path, buf, bufsiz - 1);
|
||||
size = readlink(path, buf, bufsiz);
|
||||
free(path);
|
||||
if (size < 0) {
|
||||
/* error */
|
||||
@ -455,8 +455,13 @@ int lfs_readlink(IsoFileSource *src, char *buf, size_t bufsiz)
|
||||
}
|
||||
|
||||
/* NULL-terminate the buf */
|
||||
ret = ISO_SUCCESS;
|
||||
if (size >= bufsiz) {
|
||||
ret = ISO_RR_PATH_TOO_LONG;
|
||||
size = bufsiz - 1;
|
||||
}
|
||||
buf[size] = '\0';
|
||||
return ISO_SUCCESS;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static
|
||||
@ -534,10 +539,56 @@ ex:;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static
|
||||
int lfs_clone_src(IsoFileSource *old_source,
|
||||
IsoFileSource **new_source, int flag)
|
||||
{
|
||||
IsoFileSource *src = NULL;
|
||||
char *new_name = NULL;
|
||||
_LocalFsFileSource *old_data, *new_data = NULL;
|
||||
|
||||
if (flag)
|
||||
return ISO_STREAM_NO_CLONE; /* unknown option required */
|
||||
|
||||
old_data = (_LocalFsFileSource *) old_source->data;
|
||||
*new_source = NULL;
|
||||
src = calloc(1, sizeof(IsoFileSource));
|
||||
if (src == NULL)
|
||||
goto no_mem;
|
||||
new_name = strdup(old_data->name);
|
||||
if (new_name == NULL)
|
||||
goto no_mem;
|
||||
|
||||
new_data = calloc(1, sizeof(_LocalFsFileSource));
|
||||
if (new_data == NULL)
|
||||
goto no_mem;
|
||||
new_data->openned = 0;
|
||||
new_data->info.fd = -1; /* the value does not matter with (openned == 0) */
|
||||
new_data->name = new_name;
|
||||
new_data->parent = old_data->parent;
|
||||
|
||||
src->class = old_source->class;
|
||||
src->refcount = 1;
|
||||
src->data = new_data;
|
||||
*new_source = src;
|
||||
|
||||
iso_file_source_ref(new_data->parent);
|
||||
iso_filesystem_ref(lfs);
|
||||
return ISO_SUCCESS;
|
||||
no_mem:;
|
||||
if (src != NULL)
|
||||
free((char *) src);
|
||||
if (new_data != NULL)
|
||||
free((char *) new_data);
|
||||
if (new_name != NULL)
|
||||
free(new_name);
|
||||
return ISO_OUT_OF_MEM;
|
||||
}
|
||||
|
||||
|
||||
IsoFileSourceIface lfs_class = {
|
||||
|
||||
1, /* version */
|
||||
2, /* version */
|
||||
lfs_get_path,
|
||||
lfs_get_name,
|
||||
lfs_lstat,
|
||||
@ -551,7 +602,8 @@ IsoFileSourceIface lfs_class = {
|
||||
lfs_get_filesystem,
|
||||
lfs_free,
|
||||
lfs_lseek,
|
||||
lfs_get_aa_string
|
||||
lfs_get_aa_string,
|
||||
lfs_clone_src
|
||||
|
||||
};
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2009 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2011 Thomas Schmitt
|
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
@ -33,9 +33,16 @@
|
||||
int iso_local_filesystem_new(IsoFilesystem **fs);
|
||||
|
||||
|
||||
/* Rank two IsoFileSource by their eventual old image LBAs.
|
||||
/* Rank two IsoFileSource of ifs_class by their eventual old image LBAs.
|
||||
Other IsoFileSource classes will be ranked only roughly.
|
||||
*/
|
||||
int iso_ifs_sections_cmp(IsoFileSource *s1, IsoFileSource *s2, int flag);
|
||||
|
||||
|
||||
/* Create an independent copy of an ifs_class IsoFileSource.
|
||||
*/
|
||||
int iso_ifs_source_clone(IsoFileSource *old_source, IsoFileSource **new_source,
|
||||
int flag);
|
||||
|
||||
|
||||
#endif /*LIBISO_FSOURCE_H_*/
|
||||
|
@ -32,7 +32,7 @@
|
||||
* @param image
|
||||
* Location where the image pointer will be stored.
|
||||
* @return
|
||||
* 1 sucess, < 0 error
|
||||
* 1 success, < 0 error
|
||||
*/
|
||||
int iso_image_new(const char *name, IsoImage **image)
|
||||
{
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "filesrc.h"
|
||||
#include "eltorito.h"
|
||||
#include "libisofs.h"
|
||||
#include "util.h"
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
@ -42,12 +43,11 @@ int get_joliet_name(Ecma119Image *t, IsoNode *iso, uint16_t **name)
|
||||
iso_msg_debug(t->image->id, "Can't convert %s", iso->name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* TODO #00022 : support relaxed constraints in joliet filenames */
|
||||
if (iso->type == LIBISO_DIR) {
|
||||
jname = iso_j_dir_id(ucs_name);
|
||||
jname = iso_j_dir_id(ucs_name, t->joliet_long_names << 1);
|
||||
} else {
|
||||
jname = iso_j_file_id(ucs_name, !!(t->no_force_dots & 2));
|
||||
jname = iso_j_file_id(ucs_name,
|
||||
(t->joliet_long_names << 1) | !!(t->no_force_dots & 2));
|
||||
}
|
||||
free(ucs_name);
|
||||
if (jname != NULL) {
|
||||
@ -248,7 +248,7 @@ int create_tree(Ecma119Image *t, IsoNode *iso, JolietNode **tree, int pathlen)
|
||||
char *ipath = iso_tree_get_node_path(iso);
|
||||
ret = iso_msg_submit(t->image->id, ISO_FILE_IGNORED, 0,
|
||||
"Can't add %s to Joliet tree. %s can only be added to a "
|
||||
"Rock Ridget tree.", ipath, (iso->type == LIBISO_SYMLINK ?
|
||||
"Rock Ridge tree.", ipath, (iso->type == LIBISO_SYMLINK ?
|
||||
"Symlinks" : "Special files"));
|
||||
free(ipath);
|
||||
}
|
||||
@ -303,8 +303,15 @@ int joliet_create_mangled_name(uint16_t *dest, uint16_t *src, int digits,
|
||||
int ret, pos;
|
||||
uint16_t *ucsnumber;
|
||||
char fmt[16];
|
||||
char nstr[72]; /* The only caller of this function allocates dest with 66
|
||||
elements and limits digits to < 8 */
|
||||
char nstr[72];
|
||||
/* was: The only caller of this function allocates dest
|
||||
with 66 elements and limits digits to < 8
|
||||
But this does not match the usage of nstr which has to take
|
||||
the decimal representation of an int.
|
||||
*/
|
||||
|
||||
if (digits >= 8)
|
||||
return ISO_ASSERT_FAILURE;
|
||||
|
||||
sprintf(fmt, "%%0%dd", digits);
|
||||
sprintf(nstr, fmt, number);
|
||||
@ -337,7 +344,7 @@ static
|
||||
int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
|
||||
{
|
||||
int ret;
|
||||
int i, nchildren;
|
||||
int i, nchildren, maxchar = 64;
|
||||
JolietNode **children;
|
||||
IsoHTable *table;
|
||||
int need_sort = 0;
|
||||
@ -345,6 +352,9 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
|
||||
nchildren = dir->info.dir->nchildren;
|
||||
children = dir->info.dir->children;
|
||||
|
||||
if (t->joliet_long_names)
|
||||
maxchar = 103;
|
||||
|
||||
/* a hash table will temporary hold the names, for fast searching */
|
||||
ret = iso_htable_create((nchildren * 100) / 80, iso_str_hash,
|
||||
(compare_function_t)ucscmp, &table);
|
||||
@ -361,7 +371,7 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
|
||||
|
||||
for (i = 0; i < nchildren; ++i) {
|
||||
uint16_t *name, *ext;
|
||||
uint16_t full_name[66];
|
||||
uint16_t full_name[LIBISO_JOLIET_NAME_MAX];
|
||||
int max; /* computed max len for name, without extension */
|
||||
int j = i;
|
||||
int digits = 1; /* characters to change per name */
|
||||
@ -380,7 +390,7 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
|
||||
* A max of 7 characters is good enought, it allows handling up to
|
||||
* 9,999,999 files with same name.
|
||||
*/
|
||||
/* Important: joliet_create_mangled_name() relies on digits < 72 */
|
||||
/* Important: joliet_create_mangled_name() relies on digits < 8 */
|
||||
|
||||
while (digits < 8) {
|
||||
int ok, k;
|
||||
@ -403,7 +413,7 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
|
||||
ext = dot + 1;
|
||||
|
||||
extlen = ucslen(ext);
|
||||
max = 65 - extlen - 1 - digits;
|
||||
max = maxchar + 1 - extlen - 1 - digits;
|
||||
if (max <= 0) {
|
||||
/* this can happen if extension is too long */
|
||||
if (extlen + max > 3) {
|
||||
@ -413,7 +423,7 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
|
||||
*/
|
||||
extlen = extlen + max - 1;
|
||||
ext[extlen] = 0;
|
||||
max = 66 - extlen - 1 - digits;
|
||||
max = maxchar + 2 - extlen - 1 - digits;
|
||||
} else {
|
||||
/*
|
||||
* error, we don't support extensions < 3
|
||||
@ -430,10 +440,10 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
|
||||
} else {
|
||||
/* Directory, or file without extension */
|
||||
if (children[i]->type == JOLIET_DIR) {
|
||||
max = 65 - digits;
|
||||
max = maxchar + 1 - digits;
|
||||
dot = NULL; /* dots have no meaning in dirs */
|
||||
} else {
|
||||
max = 65 - digits;
|
||||
max = maxchar + 1 - digits;
|
||||
}
|
||||
name = full_name;
|
||||
if (max < ucslen(name)) {
|
||||
@ -446,7 +456,7 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
|
||||
ok = 1;
|
||||
/* change name of each file */
|
||||
for (k = i; k <= j; ++k) {
|
||||
uint16_t tmp[66];
|
||||
uint16_t tmp[LIBISO_JOLIET_NAME_MAX];
|
||||
while (1) {
|
||||
ret = joliet_create_mangled_name(tmp, name, digits,
|
||||
change, ext);
|
||||
|
@ -18,6 +18,10 @@
|
||||
#include "libisofs.h"
|
||||
#include "ecma119.h"
|
||||
|
||||
/* was formerly 66 = 64 + 2. Now 105 = 103 + 2.
|
||||
*/
|
||||
#define LIBISO_JOLIET_NAME_MAX 105
|
||||
|
||||
enum joliet_node_type {
|
||||
JOLIET_FILE,
|
||||
JOLIET_DIR
|
||||
|
@ -1,6 +1,10 @@
|
||||
|
||||
#ifndef LIBISO_LIBISOFS_H_
|
||||
#define LIBISO_LIBISOFS_H_
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007-2008 Vreixo Formoso, Mario Danic
|
||||
* Copyright (c) 2009-2010 Thomas Schmitt
|
||||
* Copyright (c) 2009-2011 Thomas Schmitt
|
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
@ -24,11 +28,28 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LIBISO_LIBISOFS_H_
|
||||
#define LIBISO_LIBISOFS_H_
|
||||
/*
|
||||
* Normally this API is operated via public functions and opaque object
|
||||
* handles. But it also exposes several C structures which may be used to
|
||||
* provide custom functionality for the objects of the API. The same
|
||||
* structures are used for internal objects of libisofs, too.
|
||||
* You are not supposed to manipulate the entrails of such objects if they
|
||||
* are not your own custom extensions.
|
||||
*
|
||||
* See for an example IsoStream = struct iso_stream below.
|
||||
*/
|
||||
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifdef HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#else
|
||||
#ifdef HAVE_INTTYPES_H
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
struct burn_source;
|
||||
@ -322,7 +343,7 @@ struct iso_data_source
|
||||
* automatically called by iso_data_source_unref() when refcount reach
|
||||
* 0.
|
||||
*/
|
||||
void (*free_data)(IsoDataSource *);
|
||||
void (*free_data)(IsoDataSource *src);
|
||||
|
||||
/** Source specific data */
|
||||
void *data;
|
||||
@ -494,6 +515,8 @@ struct IsoFileSource_Iface
|
||||
* @since 0.6.2
|
||||
* Version 1 additionally provides function *(get_aa_string)().
|
||||
* @since 0.6.14
|
||||
* Version 2 additionally provides function *(clone_src)().
|
||||
* @since 1.0.2
|
||||
*/
|
||||
int version;
|
||||
|
||||
@ -728,6 +751,24 @@ struct IsoFileSource_Iface
|
||||
int (*get_aa_string)(IsoFileSource *src,
|
||||
unsigned char **aa_string, int flag);
|
||||
|
||||
/**
|
||||
* Produce a copy of a source. It must be possible to operate both source
|
||||
* objects concurrently.
|
||||
*
|
||||
* @param old_src
|
||||
* The existing source object to be copied
|
||||
* @param new_stream
|
||||
* Will return a pointer to the copy
|
||||
* @param flag
|
||||
* Bitfield for control purposes. Submit 0 for now.
|
||||
* The function shall return ISO_STREAM_NO_CLONE on unknown flag bits.
|
||||
*
|
||||
* @since 1.0.2
|
||||
* Present if .version is 2 or higher.
|
||||
*/
|
||||
int (*clone_src)(IsoFileSource *old_src, IsoFileSource **new_src,
|
||||
int flag);
|
||||
|
||||
/*
|
||||
* TODO #00004 Add a get_mime_type() function.
|
||||
* This can be useful for GUI apps, to choose the icon of the file
|
||||
@ -752,6 +793,31 @@ struct iso_file_source
|
||||
#endif /* ! Libisofs_h_as_cpluspluS */
|
||||
#endif /* ! __cplusplus */
|
||||
|
||||
|
||||
/* A class of IsoStream is implemented by a class description
|
||||
* IsoStreamIface = struct IsoStream_Iface
|
||||
* and a structure of data storage for each instance of IsoStream.
|
||||
* This structure shall be known to the functions of the IsoStreamIface.
|
||||
* To create a custom IsoStream class:
|
||||
* - Define the structure of the custom instance data.
|
||||
* - Implement the methods which are described by the definition of
|
||||
* struct IsoStream_Iface (see below),
|
||||
* - Create a static instance of IsoStreamIface which lists the methods as
|
||||
* C function pointers. (Example in libisofs/stream.c : fsrc_stream_class)
|
||||
* To create an instance of that class:
|
||||
* - Allocate sizeof(IsoStream) bytes of memory and initialize it as
|
||||
* struct iso_stream :
|
||||
* - Point to the custom IsoStreamIface by member .class .
|
||||
* - Set member .refcount to 1.
|
||||
* - Let member .data point to the custom instance data.
|
||||
*
|
||||
* Regrettably the choice of the structure member name "class" makes it
|
||||
* impossible to implement this generic interface in C++ language directly.
|
||||
* If C++ is absolutely necessary then you will have to make own copies
|
||||
* of the public API structures. Use other names but take care to maintain
|
||||
* the same memory layout.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Representation of file contents. It is an stream of bytes, functionally
|
||||
* like a pipe.
|
||||
@ -787,6 +853,7 @@ extern ino_t serial_id;
|
||||
*
|
||||
* @since 0.6.4
|
||||
*/
|
||||
|
||||
struct IsoStream_Iface
|
||||
{
|
||||
/*
|
||||
@ -799,6 +866,8 @@ struct IsoStream_Iface
|
||||
* get_input_stream() added. A filter stream must have version 2.
|
||||
* Version 3 (since 0.6.20)
|
||||
* compare() added. A filter stream should have version 3.
|
||||
* Version 4 (since 1.0.2)
|
||||
* clone_stream() added.
|
||||
*/
|
||||
int version;
|
||||
|
||||
@ -841,7 +910,7 @@ struct IsoStream_Iface
|
||||
off_t (*get_size)(IsoStream *stream);
|
||||
|
||||
/**
|
||||
* Attempts to read up to count bytes from the given stream into
|
||||
* Attempt to read up to count bytes from the given stream into
|
||||
* the buffer starting at buf. The implementation has to make sure that
|
||||
* either the full desired count of bytes is delivered or that the
|
||||
* next call to this function will return EOF or error.
|
||||
@ -857,12 +926,9 @@ struct IsoStream_Iface
|
||||
int (*read)(IsoStream *stream, void *buf, size_t count);
|
||||
|
||||
/**
|
||||
* Whether this IsoStream can be read several times, with the same results.
|
||||
* For example, a regular file is repeatable, you can read it as many
|
||||
* times as you want. However, a pipe isn't.
|
||||
*
|
||||
* This function doesn't take into account if the file has been modified
|
||||
* between the two reads.
|
||||
* Tell whether this IsoStream can be read several times, with the same
|
||||
* results. For example, a regular file is repeatable, you can read it
|
||||
* as many times as you want. However, a pipe is not.
|
||||
*
|
||||
* @return
|
||||
* 1 if stream is repeatable, 0 if not,
|
||||
@ -883,13 +949,13 @@ struct IsoStream_Iface
|
||||
void (*free)(IsoStream *stream);
|
||||
|
||||
/**
|
||||
* Updates the size of the IsoStream with the current size of the
|
||||
* underlying source. After calling this, get_size() will return
|
||||
* the new size. This should never be called after
|
||||
* iso_image_create_burn_source() was called and the image was not
|
||||
* completely written. To update the size of all files before written the
|
||||
* image, you may want to call iso_image_update_sizes() just before
|
||||
* iso_image_create_burn_source().
|
||||
* Update the size of the IsoStream with the current size of the underlying
|
||||
* source, if the source is prone to size changes. After calling this,
|
||||
* get_size() shall eventually return the new size.
|
||||
* This will never be called after iso_image_create_burn_source() was
|
||||
* called and before the image was completely written.
|
||||
* (The API call to update the size of all files in the image is
|
||||
* iso_image_update_sizes()).
|
||||
*
|
||||
* @return
|
||||
* 1 if ok, < 0 on error (has to be a valid libisofs error code)
|
||||
@ -900,15 +966,15 @@ struct IsoStream_Iface
|
||||
int (*update_size)(IsoStream *stream);
|
||||
|
||||
/**
|
||||
* Obtains the eventual input stream of a filter stream.
|
||||
* Retrieve the eventual input stream of a filter stream.
|
||||
*
|
||||
* @param stream
|
||||
* The eventual filter stream to be inquired.
|
||||
* @param flag
|
||||
* Bitfield for control purposes. Submit 0 for now.
|
||||
* Bitfield for control purposes. 0 means normal behavior.
|
||||
* @return
|
||||
* The input stream, if one exists. Elsewise NULL.
|
||||
* No extra reference to the stream is taken by this call.
|
||||
* No extra reference to the stream shall be taken by this call.
|
||||
*
|
||||
* @since 0.6.18
|
||||
* Present if .version is 2 or higher.
|
||||
@ -920,33 +986,32 @@ struct IsoStream_Iface
|
||||
* produce the same output. If in any doubt, then this comparison should
|
||||
* indicate no match. A match might allow hardlinking of IsoFile objects.
|
||||
*
|
||||
* This function has to establish an equivalence and order relation:
|
||||
* If this function cannot accept one of the given stream types, then
|
||||
* the decision must be delegated to
|
||||
* iso_stream_cmp_ino(s1, s2, 1);
|
||||
* This is also appropriate if one has reason to implement stream.cmp_ino()
|
||||
* without having an own special comparison algorithm.
|
||||
*
|
||||
* With filter streams the decision whether the underlying chains of
|
||||
* streams match should be delegated to
|
||||
* iso_stream_cmp_ino(iso_stream_get_input_stream(s1, 0),
|
||||
* iso_stream_get_input_stream(s2, 0), 0);
|
||||
*
|
||||
* The stream.cmp_ino() function has to establish an equivalence and order
|
||||
* relation:
|
||||
* cmp_ino(A,A) == 0
|
||||
* cmp_ino(A,B) == -cmp_ino(B,A)
|
||||
* if cmp_ino(A,B) == 0 && cmp_ino(B,C) == 0 then cmp_ino(A,C) == 0
|
||||
* if cmp_ino(A,B) < 0 && cmp_ino(B,C) < 0 then cmp_ino(A,C) < 0
|
||||
*
|
||||
* A big hazard to the last constraint are tests which do not apply to some
|
||||
* types of streams. In this case for any A that is applicable and any B
|
||||
* that is not applicable, cmp_ino(A,B) must have the same non-zero
|
||||
* result. I.e. a pair of applicable and non-applicable streams must
|
||||
* return that non-zero result before the test for a pair of applicable
|
||||
* streams would happen.
|
||||
* types of streams.Thus it is mandatory to let iso_stream_cmp_ino(s1,s2,1)
|
||||
* decide in this case.
|
||||
*
|
||||
* A function s1.(*cmp_ino)() must only accept stream s2 if function
|
||||
* s2.(*cmp_ino)() would accept s1. Best is to accept only the own stream
|
||||
* type or to have the same function for a family of similar stream types.
|
||||
*
|
||||
* If the function cannot accept one of the given stream types, then
|
||||
* the decision must be delegated to
|
||||
* iso_stream_cmp_ino(s1, s2, 1);
|
||||
* This is also appropriate if one has reason to implement stream.cmp_ino()
|
||||
* without special comparison algorithm.
|
||||
* With filter streams the decision whether the underlying chains of
|
||||
* streams match should be delegated to
|
||||
* iso_stream_cmp_ino(iso_stream_get_input_stream(s1, 0),
|
||||
* iso_stream_get_input_stream(s2, 0), 0);
|
||||
*
|
||||
* @param s1
|
||||
* The first stream to compare. Expect foreign stream types.
|
||||
* @param s2
|
||||
@ -959,6 +1024,26 @@ struct IsoStream_Iface
|
||||
*/
|
||||
int (*cmp_ino)(IsoStream *s1, IsoStream *s2);
|
||||
|
||||
/**
|
||||
* Produce a copy of a stream. It must be possible to operate both stream
|
||||
* objects concurrently.
|
||||
*
|
||||
* @param old_stream
|
||||
* The existing stream object to be copied
|
||||
* @param new_stream
|
||||
* Will return a pointer to the copy
|
||||
* @param flag
|
||||
* Bitfield for control purposes. 0 means normal behavior.
|
||||
* The function shall return ISO_STREAM_NO_CLONE on unknown flag bits.
|
||||
* @return
|
||||
* 1 in case of success, or an error code < 0
|
||||
*
|
||||
* @since 1.0.2
|
||||
* Present if .version is 4 or higher.
|
||||
*/
|
||||
int (*clone_stream)(IsoStream *old_stream, IsoStream **new_stream,
|
||||
int flag);
|
||||
|
||||
};
|
||||
|
||||
#ifndef __cplusplus
|
||||
@ -1120,9 +1205,9 @@ int iso_lib_is_compatible(int major, int minor, int micro);
|
||||
*
|
||||
* @since 0.6.2
|
||||
*/
|
||||
#define iso_lib_header_version_major 0
|
||||
#define iso_lib_header_version_minor 6
|
||||
#define iso_lib_header_version_micro 38
|
||||
#define iso_lib_header_version_major 1
|
||||
#define iso_lib_header_version_minor 0
|
||||
#define iso_lib_header_version_micro 6
|
||||
|
||||
/**
|
||||
* Usage discussion:
|
||||
@ -1205,6 +1290,27 @@ int iso_write_opts_new(IsoWriteOpts **opts, int profile);
|
||||
*/
|
||||
void iso_write_opts_free(IsoWriteOpts *opts);
|
||||
|
||||
/**
|
||||
* Announce that only the image size is desired, that the struct burn_source
|
||||
* which is set to consume the image output stream will stay inactive,
|
||||
* and that the write thread will be cancelled anyway by the .cancel() method
|
||||
* of the struct burn_source.
|
||||
* This avoids to create a write thread which would begin production of the
|
||||
* image stream and would generate a MISHAP event when burn_source.cancel()
|
||||
* gets into effect.
|
||||
*
|
||||
* @param opts
|
||||
* The option set to be manipulated.
|
||||
* @param will_cancel
|
||||
* 0= normal image generation
|
||||
* 1= prepare for being canceled before image stream output is completed
|
||||
* @return
|
||||
* 1 success, < 0 error
|
||||
*
|
||||
* @since 0.6.40
|
||||
*/
|
||||
int iso_write_opts_set_will_cancel(IsoWriteOpts *opts, int will_cancel);
|
||||
|
||||
/**
|
||||
* Set the ISO-9960 level to write at.
|
||||
*
|
||||
@ -1323,6 +1429,70 @@ int iso_write_opts_set_hardlinks(IsoWriteOpts *opts, int enable);
|
||||
*/
|
||||
int iso_write_opts_set_aaip(IsoWriteOpts *opts, int enable);
|
||||
|
||||
/**
|
||||
* Use this only if you need to reproduce a suboptimal behavior of older
|
||||
* versions of libisofs. They used address 0 for links and device files,
|
||||
* and the address of the Volume Descriptor Set Terminator for empty data
|
||||
* files.
|
||||
* New versions let symbolic links, device files, and empty data files point
|
||||
* to a dedicated block of zero-bytes after the end of the directory trees.
|
||||
* (Single-pass reader libarchive needs to see all directory info before
|
||||
* processing any data files.)
|
||||
*
|
||||
* @param opts
|
||||
* The option set to be manipulated.
|
||||
* @param enable
|
||||
* 1 = use the suboptimal block addresses in the range of 0 to 115.
|
||||
* 0 = use the address of a block after the directory tree. (Default)
|
||||
*
|
||||
* @since 1.0.2
|
||||
*/
|
||||
int iso_write_opts_set_old_empty(IsoWriteOpts *opts, int enable);
|
||||
|
||||
/**
|
||||
* Caution: This option breaks any assumptions about names that
|
||||
* are supported by ECMA-119 specifications.
|
||||
* Try to omit any translation which would make a file name compliant to the
|
||||
* ECMA-119 rules. This includes and exceeds omit_version_numbers,
|
||||
* max_37_char_filenames, no_force_dots bit0, allow_full_ascii. Further it
|
||||
* prevents the conversion from local character set to ASCII.
|
||||
* The maximum name length is given by this call. If a filename exceeds
|
||||
* this length or cannot be recorded untranslated for other reasons, then
|
||||
* image production is aborted with ISO_NAME_NEEDS_TRANSL.
|
||||
* Currently the length limit is 96 characters, because an ECMA-119 directory
|
||||
* record may at most have 254 bytes and up to 158 other bytes must fit into
|
||||
* the record. Probably 96 more bytes can be made free for the name in future.
|
||||
* @param opts
|
||||
* The option set to be manipulated.
|
||||
* @param len
|
||||
* 0 = disable this feature and perform name translation according to
|
||||
* other settings.
|
||||
* >0 = Omit any translation. Eventually abort image production
|
||||
* if a name is longer than the given value.
|
||||
* -1 = Like >0. Allow maximum possible length (currently 96)
|
||||
* @return >=0 success, <0 failure
|
||||
* In case of >=0 the return value tells the effectively set len.
|
||||
* E.g. 96 after using len == -1.
|
||||
* @since 1.0.0
|
||||
*/
|
||||
int iso_write_opts_set_untranslated_name_len(IsoWriteOpts *opts, int len);
|
||||
|
||||
/**
|
||||
* Convert directory names for ECMA-119 similar to other file names, but do
|
||||
* not force a dot or add a version number.
|
||||
* This violates ECMA-119 by allowing one "." and especially ISO level 1
|
||||
* by allowing DOS style 8.3 names rather than only 8 characters.
|
||||
* (mkisofs and its clones seem to do this violation.)
|
||||
* @param opts
|
||||
* The option set to be manipulated.
|
||||
* @param allow
|
||||
* 1= allow dots , 0= disallow dots and convert them
|
||||
* @return
|
||||
* 1 success, < 0 error
|
||||
* @since 1.0.0
|
||||
*/
|
||||
int iso_write_opts_set_allow_dir_id_ext(IsoWriteOpts *opts, int allow);
|
||||
|
||||
/**
|
||||
* Omit the version number (";1") at the end of the ISO-9660 identifiers.
|
||||
* This breaks ECMA-119 specification, but version numbers are usually not
|
||||
@ -1415,6 +1585,15 @@ int iso_write_opts_set_relaxed_vol_atts(IsoWriteOpts *opts, int allow);
|
||||
*/
|
||||
int iso_write_opts_set_joliet_longer_paths(IsoWriteOpts *opts, int allow);
|
||||
|
||||
/**
|
||||
* Allow leaf names in the Joliet tree to have up to 103 characters.
|
||||
* Normal limit is 64.
|
||||
* This breaks Joliet specification. Use with caution.
|
||||
*
|
||||
* @since 1.0.6
|
||||
*/
|
||||
int iso_write_opts_set_joliet_long_names(IsoWriteOpts *opts, int allow);
|
||||
|
||||
/**
|
||||
* Write Rock Ridge info as of specification RRIP-1.10 rather than RRIP-1.12:
|
||||
* signature "RRIP_1991A" rather than "IEEE_1282", field PX without file
|
||||
@ -1751,6 +1930,9 @@ int iso_write_opts_set_fifo_size(IsoWriteOpts *opts, size_t fifo_size);
|
||||
*
|
||||
* If system area data are given or options bit0 is set, then bit1 of
|
||||
* el_torito_set_isolinux_options() is automatically disabled.
|
||||
*
|
||||
* @param opts
|
||||
* The option set to be manipulated.
|
||||
* @param data
|
||||
* Either NULL or 32 kB of data. Do not submit less bytes !
|
||||
* @param options
|
||||
@ -1780,6 +1962,19 @@ int iso_write_opts_set_fifo_size(IsoWriteOpts *opts, size_t fifo_size);
|
||||
* iso_image_add_mips_boot_file() will be activated.
|
||||
* This will overwrite the first 512 bytes of the submitted
|
||||
* data.
|
||||
* @since 0.6.40
|
||||
* 3= SUN Disk Label for SUN SPARC
|
||||
* Submit up to 7 SPARC boot images by
|
||||
* iso_write_opts_set_partition_img() for partition numbers 2
|
||||
* to 8.
|
||||
* This will overwrite the first 512 bytes of the submitted
|
||||
* bit8-9= Only with System area type 0 = MBR
|
||||
* @since 1.0.4
|
||||
* Cylinder alignment mode eventually pads the image to make it
|
||||
* end at a cylinder boundary.
|
||||
* 0 = auto (align if bit1)
|
||||
* 1 = always align to cylinder boundary
|
||||
* 2 = never align to cylinder boundary
|
||||
* @param flag
|
||||
* bit0 = invalidate any attached system area data. Same as data == NULL
|
||||
* (This re-activates eventually loaded image System Area data.
|
||||
@ -1787,12 +1982,28 @@ int iso_write_opts_set_fifo_size(IsoWriteOpts *opts, size_t fifo_size);
|
||||
* bit1 = keep data unaltered
|
||||
* bit2 = keep options unaltered
|
||||
* @return
|
||||
* ISO_SUCCESS or error
|
||||
* ISO_SUCCESS or error
|
||||
* @since 0.6.30
|
||||
*/
|
||||
int iso_write_opts_set_system_area(IsoWriteOpts *opts, char data[32768],
|
||||
int options, int flag);
|
||||
|
||||
/**
|
||||
* Set a name for the system area. This setting is ignored unless system area
|
||||
* type 3 "SUN Disk Label" is in effect by iso_write_opts_set_system_area().
|
||||
* In this case it will replace the default text at the start of the image:
|
||||
* "CD-ROM Disc with Sun sparc boot created by libisofs"
|
||||
*
|
||||
* @param opts
|
||||
* The option set to be manipulated.
|
||||
* @param label
|
||||
* A text of up to 128 characters.
|
||||
* @return
|
||||
* ISO_SUCCESS or error
|
||||
* @since 0.6.40
|
||||
*/
|
||||
int iso_write_opts_set_disc_label(IsoWriteOpts *opts, char *label);
|
||||
|
||||
/**
|
||||
* Explicitely set the four timestamps of the emerging Primary Volume
|
||||
* Descriptor. Default with all parameters is 0.
|
||||
@ -1873,9 +2084,9 @@ int iso_write_opts_set_part_offset(IsoWriteOpts *opts,
|
||||
tests. It can be prevented by ./configure option --disable-libjte .
|
||||
@since 0.6.38
|
||||
*/
|
||||
#define iso_libjte_req_major 0
|
||||
#define iso_libjte_req_minor 1
|
||||
#define iso_libjte_req_micro 1
|
||||
#define iso_libjte_req_major 1
|
||||
#define iso_libjte_req_minor 0
|
||||
#define iso_libjte_req_micro 0
|
||||
|
||||
/**
|
||||
* Associate a libjte environment object to the upcomming write run.
|
||||
@ -1936,24 +2147,33 @@ int iso_write_opts_detach_jte(IsoWriteOpts *opts, void **libjte_handle);
|
||||
*/
|
||||
int iso_write_opts_set_tail_blocks(IsoWriteOpts *opts, uint32_t num_blocks);
|
||||
|
||||
|
||||
/**
|
||||
* Cause an arbitrary data file to be appended to the ISO image and to be
|
||||
* described by a partition table entry in an MBR at the start of the
|
||||
* ISO image.
|
||||
* described by a partition table entry in an MBR or SUN Disk Label at the
|
||||
* start of the ISO image.
|
||||
* The partition entry will bear the size of the image file rounded up to
|
||||
* the next multiple of 2048 bytes.
|
||||
* MBR or SUN Disk Label are selected by iso_write_opts_set_system_area()
|
||||
* system area type: 0 selects MBR partition table. 3 selects a SUN partition
|
||||
* table with 320 kB start alignment.
|
||||
*
|
||||
* @param opts
|
||||
* The option set to be manipulated.
|
||||
* @param partition_number
|
||||
* Depicts the partition table entry which shall describe the
|
||||
* appended image. Range 1 to 4.
|
||||
* 1 will cause the whole ISO image to be unclaimable space before
|
||||
* partition 1.
|
||||
* appended image.
|
||||
* Range with MBR: 1 to 4. 1 will cause the whole ISO image to be
|
||||
* unclaimable space before partition 1.
|
||||
* Range with SUN Disk Label: 2 to 8.
|
||||
* @param image_path
|
||||
* File address in the local file system.
|
||||
* With SUN Disk Label: an empty name causes the partition to become
|
||||
* a copy of the next lower partition.
|
||||
* @param image_type
|
||||
* The partition type. E.g. FAT12 = 0x01 , FAT16 = 0x06,
|
||||
* The MBR partition type. E.g. FAT12 = 0x01 , FAT16 = 0x06,
|
||||
* Linux Native Partition = 0x83. See fdisk command L.
|
||||
* This parameter is ignored with SUN Disk Label.
|
||||
* @return
|
||||
* ISO_SUCCESS or error
|
||||
*
|
||||
@ -2126,8 +2346,10 @@ int iso_read_opts_set_no_aaip(IsoReadOpts *opts, int noaaip);
|
||||
* @param opts
|
||||
* The option set to be manipulated
|
||||
* @param no_md5
|
||||
* 0 = Read MD5 array if available, refuse on non-matching MD5 tags
|
||||
* 1 = Do not read MD5 checksum array
|
||||
* 0 = Read Md% array if available
|
||||
* 2 = Read MD5 array, but do not check MD5 tags
|
||||
* @since 1.0.4
|
||||
* All other values are reserved.
|
||||
*
|
||||
* @since 0.6.22
|
||||
@ -2915,6 +3137,8 @@ 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 bootimg
|
||||
* The image to set options on
|
||||
* @param options
|
||||
* bitmask style flag. The following values are defined:
|
||||
*
|
||||
@ -2942,8 +3166,6 @@ int el_torito_seems_boot_info_table(ElToritoBootImage *bootimg, int flag);
|
||||
* For that you need isolinux.bin from SYSLINUX 3.72 or later.
|
||||
* IMPORTANT: The application has to take care that the image
|
||||
* on media gets padded up to the next full MB.
|
||||
* @param bootimg
|
||||
* The image to set options on
|
||||
* @param flag
|
||||
* Reserved for future usage, set to 0.
|
||||
* @return
|
||||
@ -3076,9 +3298,9 @@ void iso_node_unref(IsoNode *node);
|
||||
enum IsoNodeType iso_node_get_type(IsoNode *node);
|
||||
|
||||
/**
|
||||
* Function to handle particular extended information. The function
|
||||
* pointer acts as an identifier for the type of the information. Structs
|
||||
* with same information type must use the same function.
|
||||
* Class of functions to handle particular extended information. A function
|
||||
* instance acts as an identifier for the type of the information. Structs
|
||||
* with same information type must use a pointer to the same function.
|
||||
*
|
||||
* @param data
|
||||
* Attached data
|
||||
@ -3133,6 +3355,20 @@ int iso_node_add_xinfo(IsoNode *node, iso_node_xinfo_func proc, void *data);
|
||||
*/
|
||||
int iso_node_remove_xinfo(IsoNode *node, iso_node_xinfo_func proc);
|
||||
|
||||
/**
|
||||
* Remove all extended information from the given node.
|
||||
*
|
||||
* @param node
|
||||
* The node where to remove all extended info
|
||||
* @param flag
|
||||
* Bitfield for control purposes, unused yet, submit 0
|
||||
* @return
|
||||
* 1 on success, < 0 on error
|
||||
*
|
||||
* @since 1.0.2
|
||||
*/
|
||||
int iso_node_remove_all_xinfo(IsoNode *node, int flag);
|
||||
|
||||
/**
|
||||
* Get the given extended info (defined by the proc function) from the
|
||||
* given node.
|
||||
@ -3152,6 +3388,102 @@ int iso_node_remove_xinfo(IsoNode *node, iso_node_xinfo_func proc);
|
||||
*/
|
||||
int iso_node_get_xinfo(IsoNode *node, iso_node_xinfo_func proc, void **data);
|
||||
|
||||
|
||||
/**
|
||||
* Get the next pair of function pointer and data of an iteration of the
|
||||
* list of extended informations. Like:
|
||||
* iso_node_xinfo_func proc;
|
||||
* void *handle = NULL, *data;
|
||||
* while (iso_node_get_next_xinfo(node, &handle, &proc, &data) == 1) {
|
||||
* ... make use of proc and data ...
|
||||
* }
|
||||
* The iteration allocates no memory. So you may end it without any disposal
|
||||
* action.
|
||||
* IMPORTANT: Do not continue iterations after manipulating the extended
|
||||
* information of a node. Memory corruption hazard !
|
||||
* @param node
|
||||
* The node to inquire
|
||||
* @param handle
|
||||
* The opaque iteration handle. Initialize iteration by submitting
|
||||
* a pointer to a void pointer with value NULL.
|
||||
* Do not alter its content until iteration has ended.
|
||||
* @param proc
|
||||
* The function pointer which serves as key
|
||||
* @param data
|
||||
* Will be filled with the extended info corresponding to the given proc
|
||||
* function
|
||||
* @return
|
||||
* 1 on success
|
||||
* 0 if iteration has ended (proc and data are invalid then)
|
||||
* < 0 on error
|
||||
*
|
||||
* @since 1.0.2
|
||||
*/
|
||||
int iso_node_get_next_xinfo(IsoNode *node, void **handle,
|
||||
iso_node_xinfo_func *proc, void **data);
|
||||
|
||||
|
||||
/**
|
||||
* Class of functions to clone extended information. A function instance gets
|
||||
* associated to a particular iso_node_xinfo_func instance by function
|
||||
* iso_node_xinfo_make_clonable(). This is a precondition to have IsoNode
|
||||
* objects clonable which carry data for a particular iso_node_xinfo_func.
|
||||
*
|
||||
* @param old_data
|
||||
* Data item to be cloned
|
||||
* @param new_data
|
||||
* Shall return the cloned data item
|
||||
* @param flag
|
||||
* Unused yet, submit 0
|
||||
* The function shall return ISO_XINFO_NO_CLONE on unknown flag bits.
|
||||
* @return
|
||||
* > 0 number of allocated bytes
|
||||
* 0 no size info is available
|
||||
* < 0 error
|
||||
*
|
||||
* @since 1.0.2
|
||||
*/
|
||||
typedef int (*iso_node_xinfo_cloner)(void *old_data, void **new_data,int flag);
|
||||
|
||||
/**
|
||||
* Associate a iso_node_xinfo_cloner to a particular class of extended
|
||||
* information in order to make it clonable.
|
||||
*
|
||||
* @param proc
|
||||
* The key and disposal function which identifies the particular
|
||||
* extended information class.
|
||||
* @param cloner
|
||||
* The cloner function which shall be associated with proc.
|
||||
* @param flag
|
||||
* Unused yet, submit 0
|
||||
* @return
|
||||
* 1 success, < 0 error
|
||||
*
|
||||
* @since 1.0.2
|
||||
*/
|
||||
int iso_node_xinfo_make_clonable(iso_node_xinfo_func proc,
|
||||
iso_node_xinfo_cloner cloner, int flag);
|
||||
|
||||
/**
|
||||
* Inquire the registered cloner function for a particular class of
|
||||
* extended information.
|
||||
*
|
||||
* @param proc
|
||||
* The key and disposal function which identifies the particular
|
||||
* extended information class.
|
||||
* @param cloner
|
||||
* Will return the cloner function which is associated with proc, or NULL.
|
||||
* @param flag
|
||||
* Unused yet, submit 0
|
||||
* @return
|
||||
* 1 success, 0 no cloner registered for proc, < 0 error
|
||||
*
|
||||
* @since 1.0.2
|
||||
*/
|
||||
int iso_node_xinfo_get_cloner(iso_node_xinfo_func proc,
|
||||
iso_node_xinfo_cloner *cloner, int flag);
|
||||
|
||||
|
||||
/**
|
||||
* Set the name of a node. Note that if the node is already added to a dir
|
||||
* this can fail if dir already contains a node with the new name.
|
||||
@ -3531,23 +3863,39 @@ int iso_dir_iter_take(IsoDirIter *iter);
|
||||
|
||||
/**
|
||||
* Removes a child from a directory during an iteration and unref() it.
|
||||
* It's like iso_node_remove(), but to be used during a directory iteration.
|
||||
* The node removed will be the last returned by the iteration.
|
||||
* Like iso_node_remove(), but to be used during a directory iteration.
|
||||
* The node removed will be the one returned by the previous iteration.
|
||||
*
|
||||
* If you call this function twice without calling iso_dir_iter_next between
|
||||
* them is not allowed and you will get an ISO_ERROR in second call.
|
||||
* It is not allowed to call this function twice without calling
|
||||
* iso_dir_iter_next inbetween.
|
||||
*
|
||||
* @return
|
||||
* 1 on succes, < 0 error
|
||||
* Possible errors:
|
||||
* ISO_NULL_POINTER, if iter is NULL
|
||||
* ISO_ERROR, on wrong iter usage, for example by call this before
|
||||
* ISO_ERROR, on wrong iter usage, for example by calling this before
|
||||
* iso_dir_iter_next.
|
||||
*
|
||||
* @since 0.6.2
|
||||
*/
|
||||
int iso_dir_iter_remove(IsoDirIter *iter);
|
||||
|
||||
/**
|
||||
* Removes a node by iso_node_remove() or iso_dir_iter_remove(). If the node
|
||||
* is a directory then the whole tree of nodes underneath is removed too.
|
||||
*
|
||||
* @param node
|
||||
* The node to be removed.
|
||||
* @param iter
|
||||
* If not NULL, then the node will be removed by iso_dir_iter_remove(iter)
|
||||
* else it will be removed by iso_node_remove(node).
|
||||
* @return
|
||||
* 1 is success, <0 indicates error
|
||||
*
|
||||
* @since 1.0.2
|
||||
*/
|
||||
int iso_node_remove_tree(IsoNode *node, IsoDirIter *boss_iter);
|
||||
|
||||
|
||||
/**
|
||||
* @since 0.6.4
|
||||
@ -3926,6 +4274,24 @@ int iso_tree_add_new_dir(IsoDir *parent, const char *name, IsoDir **dir);
|
||||
int iso_tree_add_new_file(IsoDir *parent, const char *name, IsoStream *stream,
|
||||
IsoFile **file);
|
||||
|
||||
/**
|
||||
* Create an IsoStream object from content which is stored in a dynamically
|
||||
* allocated memory buffer. The new stream will become owner of the buffer
|
||||
* and apply free() to it when the stream finally gets destroyed itself.
|
||||
*
|
||||
* @param buf
|
||||
* The dynamically allocated memory buffer with the stream content.
|
||||
* @parm size
|
||||
* The number of bytes which may be read from buf.
|
||||
* @param stream
|
||||
* Will return a reference to the newly created stream.
|
||||
* @return
|
||||
* ISO_SUCCESS or <0 for error. E.g. ISO_NULL_POINTER, ISO_OUT_OF_MEM.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
int iso_memory_stream_new(unsigned char *buf, size_t size, IsoStream **stream);
|
||||
|
||||
/**
|
||||
* Add a new symlink to the directory tree. Permissions are set to 0777,
|
||||
* owner and hidden atts are taken from parent. You can modify any of them
|
||||
@ -4266,6 +4632,57 @@ int iso_tree_add_new_cut_out_node(IsoImage *image, IsoDir *parent,
|
||||
off_t offset, off_t size,
|
||||
IsoNode **node);
|
||||
|
||||
/**
|
||||
* Create a copy of the given node under a different path. If the node is
|
||||
* actually a directory then clone its whole subtree.
|
||||
* This call may fail because an IsoFile is encountered which gets fed by an
|
||||
* IsoStream which cannot be cloned. See also IsoStream_Iface method
|
||||
* clone_stream().
|
||||
* Surely clonable node types are:
|
||||
* IsoDir,
|
||||
* IsoSymlink,
|
||||
* IsoSpecial,
|
||||
* IsoFile from a loaded ISO image,
|
||||
* IsoFile referring to local filesystem files,
|
||||
* IsoFile created by iso_tree_add_new_file
|
||||
* from a stream created by iso_memory_stream_new(),
|
||||
* IsoFile created by iso_tree_add_new_cut_out_node()
|
||||
* Silently ignored are nodes of type IsoBoot.
|
||||
* An IsoFile node with IsoStream filters can be cloned if all those filters
|
||||
* are clonable and the node would be clonable without filter.
|
||||
* Clonable IsoStream filters are created by:
|
||||
* iso_file_add_zisofs_filter()
|
||||
* iso_file_add_gzip_filter()
|
||||
* iso_file_add_external_filter()
|
||||
* An IsoNode with extended information as of iso_node_add_xinfo() can only be
|
||||
* cloned if each of the iso_node_xinfo_func instances is associated to a
|
||||
* clone function. See iso_node_xinfo_make_clonable().
|
||||
* All internally used classes of extended information are clonable.
|
||||
*
|
||||
* @param node
|
||||
* The node to be cloned.
|
||||
* @param new_parent
|
||||
* The existing directory node where to insert the cloned node.
|
||||
* @param new_name
|
||||
* The name for the cloned node. It must not yet exist in new_parent,
|
||||
* unless it is a directory and node is a directory and flag bit0 is set.
|
||||
* @param new_node
|
||||
* Will return a pointer (without reference) to the newly created clone.
|
||||
* @param flag
|
||||
* Bitfield for control purposes. Submit any undefined bits as 0.
|
||||
* bit0= Merge directories rather than returning ISO_NODE_NAME_NOT_UNIQUE.
|
||||
* This will not allow to overwrite any existing node.
|
||||
* Attributes of existing directories will not be overwritten.
|
||||
* @return
|
||||
* <0 means error, 1 = new node created,
|
||||
* 2 = if flag bit0 is set: new_node is a directory which already existed.
|
||||
*
|
||||
* @since 1.0.2
|
||||
*/
|
||||
int iso_tree_clone(IsoNode *node,
|
||||
IsoDir *new_parent, char *new_name, IsoNode **new_node,
|
||||
int flag);
|
||||
|
||||
/**
|
||||
* Add the contents of a dir to a given directory of the iso tree.
|
||||
*
|
||||
@ -4764,11 +5181,12 @@ int iso_file_source_readdir(IsoFileSource *src, IsoFileSource **child);
|
||||
* @param src
|
||||
* An IsoFileSource corresponding to a symbolic link.
|
||||
* @param buf
|
||||
* allocated buffer of at least bufsiz bytes.
|
||||
* The dest. will be copied there, and it will be NULL-terminated
|
||||
* Allocated buffer of at least bufsiz bytes.
|
||||
* The destination string will be copied there, and it will be 0-terminated
|
||||
* if the return value indicates success or ISO_RR_PATH_TOO_LONG.
|
||||
* @param bufsiz
|
||||
* characters to be copied. Destination link will be truncated if
|
||||
* it is larger than given size. This includes the 0x0 character.
|
||||
* Maximum number of buf characters + 1. The string will be truncated if
|
||||
* it is larger than bufsiz - 1 and ISO_RR_PATH_TOO_LONG. will be returned.
|
||||
* @return
|
||||
* 1 on success, < 0 on error
|
||||
* Error codes:
|
||||
@ -4779,6 +5197,7 @@ int iso_file_source_readdir(IsoFileSource *src, IsoFileSource **child);
|
||||
* ISO_OUT_OF_MEM
|
||||
* ISO_FILE_BAD_PATH
|
||||
* ISO_FILE_DOESNT_EXIST
|
||||
* ISO_RR_PATH_TOO_LONG (@since 1.0.6)
|
||||
*
|
||||
* @since 0.6.2
|
||||
*/
|
||||
@ -5065,6 +5484,30 @@ char *iso_stream_get_source_path(IsoStream *stream, int flag);
|
||||
*/
|
||||
int iso_stream_cmp_ino(IsoStream *s1, IsoStream *s2, int flag);
|
||||
|
||||
|
||||
/**
|
||||
* Produce a copy of a stream. It must be possible to operate both stream
|
||||
* objects concurrently. The success of this function depends on the
|
||||
* existence of a IsoStream_Iface.clone_stream() method with the stream
|
||||
* and with its eventual subordinate streams.
|
||||
* See iso_tree_clone() for a list of surely clonable built-in streams.
|
||||
*
|
||||
* @param old_stream
|
||||
* The existing stream object to be copied
|
||||
* @param new_stream
|
||||
* Will return a pointer to the copy
|
||||
* @param flag
|
||||
* Bitfield for control purposes. Submit 0 for now.
|
||||
* @return
|
||||
* >0 means success
|
||||
* ISO_STREAM_NO_CLONE is issued if no .clone_stream() exists
|
||||
* other error return values < 0 may occur depending on kind of stream
|
||||
*
|
||||
* @since 1.0.2
|
||||
*/
|
||||
int iso_stream_clone(IsoStream *old_stream, IsoStream **new_stream, int flag);
|
||||
|
||||
|
||||
/* --------------------------------- AAIP --------------------------------- */
|
||||
|
||||
/**
|
||||
@ -5091,6 +5534,12 @@ int iso_stream_cmp_ino(IsoStream *s1, IsoStream *s2, int flag);
|
||||
*/
|
||||
int aaip_xinfo_func(void *data, int flag);
|
||||
|
||||
/**
|
||||
* The iso_node_xinfo_cloner function which gets associated to aaip_xinfo_func
|
||||
* by iso_init() resp. iso_init_with_flag() via iso_node_xinfo_make_clonable().
|
||||
* @since 1.0.2
|
||||
*/
|
||||
int aaip_xinfo_cloner(void *old_data, void **new_data, int flag);
|
||||
|
||||
/**
|
||||
* Get the eventual ACLs which are associated with the node.
|
||||
@ -6363,6 +6812,34 @@ int iso_md5_match(char first_md5[16], char second_md5[16]);
|
||||
(FAILURE, HIGH, -371) */
|
||||
#define ISO_NON_MBR_SYS_AREA 0xE830FE8D
|
||||
|
||||
/** Displacement offset leads outside 32 bit range (FAILURE, HIGH, -372) */
|
||||
#define ISO_DISPLACE_ROLLOVER 0xE830FE8C
|
||||
|
||||
/** File name cannot be written into ECMA-119 untranslated
|
||||
(FAILURE, HIGH, -373) */
|
||||
#define ISO_NAME_NEEDS_TRANSL 0xE830FE8B
|
||||
|
||||
/** Data file input stream object offers no cloning method
|
||||
(FAILURE, HIGH, -374) */
|
||||
#define ISO_STREAM_NO_CLONE 0xE830FE8A
|
||||
|
||||
/** Extended information class offers no cloning method
|
||||
(FAILURE, HIGH, -375) */
|
||||
#define ISO_XINFO_NO_CLONE 0xE830FE89
|
||||
|
||||
/** Found copied superblock checksum tag (WARNING, HIGH, -376) */
|
||||
#define ISO_MD5_TAG_COPIED 0xD030FE88
|
||||
|
||||
/** Rock Ridge leaf name too long (FAILURE, HIGH, -377) */
|
||||
#define ISO_RR_NAME_TOO_LONG 0xE830FE87
|
||||
|
||||
/** Reserved Rock Ridge leaf name (FAILURE, HIGH, -378) */
|
||||
#define ISO_RR_NAME_RESERVED 0xE830FE86
|
||||
|
||||
/** Rock Ridge path too long (FAILURE, HIGH, -379) */
|
||||
#define ISO_RR_PATH_TOO_LONG 0xE830FE85
|
||||
|
||||
|
||||
|
||||
/* Internal developer note:
|
||||
Place new error codes directly above this comment.
|
||||
|
@ -1,5 +1,6 @@
|
||||
LIBISOFS6 {
|
||||
global:
|
||||
aaip_xinfo_cloner;
|
||||
aaip_xinfo_func;
|
||||
el_torito_get_bootable;
|
||||
el_torito_get_boot_media_type;
|
||||
@ -133,6 +134,7 @@ iso_md5_compute;
|
||||
iso_md5_end;
|
||||
iso_md5_match;
|
||||
iso_md5_start;
|
||||
iso_memory_stream_new;
|
||||
iso_msgs_submit;
|
||||
iso_new_find_conditions_and;
|
||||
iso_new_find_conditions_atime;
|
||||
@ -155,6 +157,7 @@ iso_node_get_hidden;
|
||||
iso_node_get_mode;
|
||||
iso_node_get_mtime;
|
||||
iso_node_get_name;
|
||||
iso_node_get_next_xinfo;
|
||||
iso_node_get_old_image_lba;
|
||||
iso_node_get_parent;
|
||||
iso_node_get_permissions;
|
||||
@ -165,6 +168,8 @@ iso_node_get_xinfo;
|
||||
iso_node_lookup_attr;
|
||||
iso_node_ref;
|
||||
iso_node_remove;
|
||||
iso_node_remove_all_xinfo;
|
||||
iso_node_remove_tree;
|
||||
iso_node_remove_xinfo;
|
||||
iso_node_set_acl_text;
|
||||
iso_node_set_atime;
|
||||
@ -179,6 +184,8 @@ iso_node_set_sort_weight;
|
||||
iso_node_set_uid;
|
||||
iso_node_take;
|
||||
iso_node_unref;
|
||||
iso_node_xinfo_get_cloner;
|
||||
iso_node_xinfo_make_clonable;
|
||||
iso_node_zf_by_magic;
|
||||
iso_obtain_msgs;
|
||||
iso_read_image_features_destroy;
|
||||
@ -209,6 +216,7 @@ iso_set_local_charset;
|
||||
iso_set_msgs_severities;
|
||||
iso_sev_to_text;
|
||||
iso_special_get_dev;
|
||||
iso_stream_clone;
|
||||
iso_stream_close;
|
||||
iso_stream_cmp_ino;
|
||||
iso_stream_get_external_filter;
|
||||
@ -234,6 +242,7 @@ iso_tree_add_new_node;
|
||||
iso_tree_add_new_special;
|
||||
iso_tree_add_new_symlink;
|
||||
iso_tree_add_node;
|
||||
iso_tree_clone;
|
||||
iso_tree_get_follow_symlinks;
|
||||
iso_tree_get_ignore_hidden;
|
||||
iso_tree_get_ignore_special;
|
||||
@ -255,6 +264,7 @@ iso_write_opts_new;
|
||||
iso_write_opts_set_aaip;
|
||||
iso_write_opts_set_aaip_susp_1_10;
|
||||
iso_write_opts_set_allow_deep_paths;
|
||||
iso_write_opts_set_allow_dir_id_ext;
|
||||
iso_write_opts_set_allow_full_ascii;
|
||||
iso_write_opts_set_allow_longer_paths;
|
||||
iso_write_opts_set_allow_lowercase;
|
||||
@ -266,15 +276,18 @@ iso_write_opts_set_default_gid;
|
||||
iso_write_opts_set_default_timestamp;
|
||||
iso_write_opts_set_default_uid;
|
||||
iso_write_opts_set_dir_rec_mtime;
|
||||
iso_write_opts_set_disc_label;
|
||||
iso_write_opts_set_fifo_size;
|
||||
iso_write_opts_set_hardlinks;
|
||||
iso_write_opts_set_iso1999;
|
||||
iso_write_opts_set_iso_level;
|
||||
iso_write_opts_set_joliet;
|
||||
iso_write_opts_set_joliet_long_names;
|
||||
iso_write_opts_set_joliet_longer_paths;
|
||||
iso_write_opts_set_max_37_char_filenames;
|
||||
iso_write_opts_set_ms_block;
|
||||
iso_write_opts_set_no_force_dots;
|
||||
iso_write_opts_set_old_empty;
|
||||
iso_write_opts_set_omit_version_numbers;
|
||||
iso_write_opts_set_output_charset;
|
||||
iso_write_opts_set_overwrite_buf;
|
||||
@ -292,6 +305,8 @@ iso_write_opts_set_scdbackup_tag;
|
||||
iso_write_opts_set_sort_files;
|
||||
iso_write_opts_set_system_area;
|
||||
iso_write_opts_set_tail_blocks;
|
||||
iso_write_opts_set_untranslated_name_len;
|
||||
iso_write_opts_set_will_cancel;
|
||||
iso_zisofs_get_params;
|
||||
iso_zisofs_get_refcounts;
|
||||
iso_zisofs_set_params;
|
||||
|
@ -4,7 +4,15 @@
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#ifdef HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#else
|
||||
#ifdef HAVE_INTTYPES_H
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
@ -378,21 +386,19 @@ int make_isolinux_mbr(int32_t *img_blocks, uint32_t boot_lba,
|
||||
int part_offset, int part_number, int fs_type,
|
||||
uint8_t *buf, int flag)
|
||||
{
|
||||
uint32_t spc, id, part, nominal_part_size;
|
||||
uint32_t id, part, nominal_part_size;
|
||||
off_t hd_img_blocks, hd_boot_lba;
|
||||
char *wpt;
|
||||
/* For generating a weak random number */
|
||||
struct timeval tv;
|
||||
struct timezone tz;
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
/* Padding of image_size to a multiple of sector_count*head_count
|
||||
happens already at compute time and is implemented by
|
||||
an appropriate increase of Ecma119Image->tail_blocks.
|
||||
*/
|
||||
|
||||
wpt = (char *) buf + 432;
|
||||
|
||||
|
@ -12,7 +12,14 @@
|
||||
#include "../config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#else
|
||||
#ifdef HAVE_INTTYPES_H
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
@ -417,6 +424,22 @@ int checksum_cx_xinfo_func(void *data, int flag)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* The iso_node_xinfo_cloner function which gets associated to
|
||||
* checksum_cx_xinfo_func by iso_init() resp. iso_init_with_flag() via
|
||||
* iso_node_xinfo_make_clonable()
|
||||
*/
|
||||
int checksum_cx_xinfo_cloner(void *old_data, void **new_data, int flag)
|
||||
{
|
||||
*new_data = NULL;
|
||||
if (flag)
|
||||
return ISO_XINFO_NO_CLONE;
|
||||
if (old_data == NULL)
|
||||
return 0;
|
||||
/* data is an int disguised as pointer. It does not point to memory. */
|
||||
*new_data = old_data;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Function to identify and manage md5 sums of unspecified providence stored
|
||||
* directly in this xinfo.
|
||||
@ -429,6 +452,24 @@ int checksum_md5_xinfo_func(void *data, int flag)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* The iso_node_xinfo_cloner function which gets associated to
|
||||
* checksum_md5_xinfo_func by iso_init() resp. iso_init_with_flag() via
|
||||
* iso_node_xinfo_make_clonable()
|
||||
*/
|
||||
int checksum_md5_xinfo_cloner(void *old_data, void **new_data, int flag)
|
||||
{
|
||||
*new_data = NULL;
|
||||
if (flag)
|
||||
return ISO_XINFO_NO_CLONE;
|
||||
if (old_data == NULL)
|
||||
return 0;
|
||||
*new_data = calloc(1, 16);
|
||||
if (*new_data == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
memcpy(*new_data, old_data, 16);
|
||||
return 16;
|
||||
}
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2009 - 2011 Thomas Schmitt
|
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
@ -36,6 +37,7 @@
|
||||
#include "messages.h"
|
||||
|
||||
#include "util.h"
|
||||
#include "node.h"
|
||||
|
||||
|
||||
/*
|
||||
@ -79,11 +81,76 @@ int abort_threshold = LIBISO_MSGS_SEV_FAILURE;
|
||||
struct libiso_msgs *libiso_msgr = NULL;
|
||||
|
||||
|
||||
/* ------------- List of xinfo clone functions ----------- */
|
||||
|
||||
struct iso_xinfo_cloner_assoc {
|
||||
iso_node_xinfo_func proc;
|
||||
iso_node_xinfo_cloner cloner;
|
||||
struct iso_xinfo_cloner_assoc *next;
|
||||
};
|
||||
|
||||
struct iso_xinfo_cloner_assoc *iso_xinfo_cloner_list = NULL;
|
||||
|
||||
/* API */
|
||||
int iso_node_xinfo_make_clonable(iso_node_xinfo_func proc,
|
||||
iso_node_xinfo_cloner cloner, int flag)
|
||||
{
|
||||
struct iso_xinfo_cloner_assoc *assoc;
|
||||
|
||||
/* Look for existing assoc of proc */
|
||||
for (assoc = iso_xinfo_cloner_list; assoc != NULL; assoc = assoc->next)
|
||||
if (assoc->proc == proc)
|
||||
break;
|
||||
|
||||
if (assoc == NULL) {
|
||||
assoc = calloc(1, sizeof(struct iso_xinfo_cloner_assoc));
|
||||
if (assoc == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
assoc->proc = proc;
|
||||
assoc->next = iso_xinfo_cloner_list;
|
||||
iso_xinfo_cloner_list = assoc;
|
||||
}
|
||||
assoc->cloner = cloner;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
/* API */
|
||||
int iso_node_xinfo_get_cloner(iso_node_xinfo_func proc,
|
||||
iso_node_xinfo_cloner *cloner, int flag)
|
||||
{
|
||||
struct iso_xinfo_cloner_assoc *assoc;
|
||||
|
||||
*cloner = NULL;
|
||||
for (assoc = iso_xinfo_cloner_list; assoc != NULL; assoc = assoc->next) {
|
||||
if (assoc->proc != proc)
|
||||
continue;
|
||||
*cloner = assoc->cloner;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
int iso_node_xinfo_dispose_cloners(int flag)
|
||||
{
|
||||
struct iso_xinfo_cloner_assoc *assoc, *next;
|
||||
|
||||
for (assoc = iso_xinfo_cloner_list; assoc != NULL; assoc = next) {
|
||||
next = assoc->next;
|
||||
free((char *) assoc);
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* ------------- End of xinfo clone functions list ----------- */
|
||||
|
||||
|
||||
/*
|
||||
@param flag bit0= do not set up locale by LC_* environment variables
|
||||
*/
|
||||
int iso_init_with_flag(int flag)
|
||||
{
|
||||
int ret;
|
||||
|
||||
#ifdef Libisofs_with_libjtE
|
||||
|
||||
@ -119,7 +186,6 @@ LIBJTE_MISCONFIGURATION_ = 0;
|
||||
|
||||
#endif /* Libisofs_with_libjtE */
|
||||
|
||||
|
||||
if (! (flag & 1)) {
|
||||
iso_init_locale(0);
|
||||
}
|
||||
@ -129,10 +195,29 @@ LIBJTE_MISCONFIGURATION_ = 0;
|
||||
}
|
||||
libiso_msgs_set_severities(libiso_msgr, LIBISO_MSGS_SEV_NEVER,
|
||||
LIBISO_MSGS_SEV_FATAL, "libisofs: ", 0);
|
||||
|
||||
ret = iso_node_xinfo_make_clonable(aaip_xinfo_func, aaip_xinfo_cloner, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = iso_node_xinfo_make_clonable(checksum_cx_xinfo_func,
|
||||
checksum_cx_xinfo_cloner, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = iso_node_xinfo_make_clonable(checksum_md5_xinfo_func,
|
||||
checksum_md5_xinfo_cloner, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = iso_node_xinfo_make_clonable(zisofs_zf_xinfo_func,
|
||||
zisofs_zf_xinfo_cloner, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = iso_node_xinfo_make_clonable(iso_px_ino_xinfo_func,
|
||||
iso_px_ino_xinfo_cloner, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int iso_init()
|
||||
{
|
||||
return iso_init_with_flag(0);
|
||||
@ -141,6 +226,7 @@ int iso_init()
|
||||
void iso_finish()
|
||||
{
|
||||
libiso_msgs_destroy(&libiso_msgr, 0);
|
||||
iso_node_xinfo_dispose_cloners(0);
|
||||
}
|
||||
|
||||
int iso_set_abort_severity(char *severity)
|
||||
@ -359,6 +445,22 @@ const char *iso_error_to_msg(int errcode)
|
||||
return "Cannot open data file for appended partition";
|
||||
case ISO_NON_MBR_SYS_AREA:
|
||||
return "May not combine appended partition with non-MBR system area";
|
||||
case ISO_DISPLACE_ROLLOVER:
|
||||
return "Displacement offset leads outside 32 bit range";
|
||||
case ISO_NAME_NEEDS_TRANSL:
|
||||
return "File name cannot be written into ECMA-119 untranslated";
|
||||
case ISO_STREAM_NO_CLONE:
|
||||
return "Data file input stream object offers no cloning method";
|
||||
case ISO_XINFO_NO_CLONE:
|
||||
return "Extended information class offers no cloning method";
|
||||
case ISO_MD5_TAG_COPIED:
|
||||
return "Found copied superblock checksum tag";
|
||||
case ISO_RR_NAME_TOO_LONG:
|
||||
return "Rock Ridge leaf name too long";
|
||||
case ISO_RR_NAME_RESERVED:
|
||||
return "Reserved Rock Ridge leaf name";
|
||||
case ISO_RR_PATH_TOO_LONG:
|
||||
return "Rock Ridge path too long";
|
||||
default:
|
||||
return "Unknown error";
|
||||
}
|
||||
|
@ -46,7 +46,6 @@ int iso_msg_is_abort(int errcode);
|
||||
int iso_msg_submit(int imgid, int errcode, int causedby, const char *fmt, ...);
|
||||
|
||||
|
||||
/* ts A80222 */
|
||||
/* To be called with events which report incidents with individual input
|
||||
files from the local filesystem. Not with image nodes, files containing an
|
||||
image or similar file-like objects.
|
||||
|
241
libisofs/node.c
241
libisofs/node.c
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2009 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2011 Thomas Schmitt
|
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
@ -28,11 +28,6 @@
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX Libisofs_default_path_maX
|
||||
#endif
|
||||
|
||||
|
||||
struct dir_iter_data
|
||||
{
|
||||
/* points to the last visited child, to NULL before start */
|
||||
@ -226,6 +221,89 @@ int iso_node_get_xinfo(IsoNode *node, iso_node_xinfo_func proc, void **data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* API */
|
||||
int iso_node_get_next_xinfo(IsoNode *node, void **handle,
|
||||
iso_node_xinfo_func *proc, void **data)
|
||||
{
|
||||
IsoExtendedInfo *xinfo;
|
||||
|
||||
if (node == NULL || handle == NULL || proc == NULL || data == NULL)
|
||||
return ISO_NULL_POINTER;
|
||||
*proc = NULL;
|
||||
*data = NULL;
|
||||
xinfo = (IsoExtendedInfo *) *handle;
|
||||
if (xinfo == NULL)
|
||||
xinfo = node->xinfo;
|
||||
else
|
||||
xinfo = xinfo->next;
|
||||
*handle = xinfo;
|
||||
if (xinfo == NULL)
|
||||
return 0;
|
||||
*proc = xinfo->process;
|
||||
*data = xinfo->data;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
int iso_node_remove_all_xinfo(IsoNode *node, int flag)
|
||||
{
|
||||
IsoExtendedInfo *pos, *next;
|
||||
|
||||
for (pos = node->xinfo; pos != NULL; pos = next) {
|
||||
next = pos->next;
|
||||
pos->process(pos->data, 1);
|
||||
free((char *) pos);
|
||||
}
|
||||
node->xinfo = NULL;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
static
|
||||
int iso_node_revert_xinfo_list(IsoNode *node, int flag)
|
||||
{
|
||||
|
||||
IsoExtendedInfo *pos, *next, *prev = NULL;
|
||||
|
||||
for (pos = node->xinfo; pos != NULL; pos = next) {
|
||||
next = pos->next;
|
||||
pos->next = prev;
|
||||
prev = pos;
|
||||
}
|
||||
node->xinfo = prev;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
int iso_node_clone_xinfo(IsoNode *from_node, IsoNode *to_node, int flag)
|
||||
{
|
||||
void *handle = NULL, *data, *new_data;
|
||||
iso_node_xinfo_func proc;
|
||||
iso_node_xinfo_cloner cloner;
|
||||
int ret;
|
||||
|
||||
iso_node_remove_all_xinfo(to_node, 0);
|
||||
while (1) {
|
||||
ret = iso_node_get_next_xinfo(from_node, &handle, &proc, &data);
|
||||
if (ret <= 0)
|
||||
break;
|
||||
ret = iso_node_xinfo_get_cloner(proc, &cloner, 0);
|
||||
if (ret == 0)
|
||||
return ISO_XINFO_NO_CLONE;
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = (*cloner)(data, &new_data, 0);
|
||||
if (ret < 0)
|
||||
break;
|
||||
ret = iso_node_add_xinfo(to_node, proc, new_data);
|
||||
if (ret < 0)
|
||||
break;
|
||||
}
|
||||
if (ret < 0) {
|
||||
iso_node_remove_all_xinfo(to_node, 0);
|
||||
} else {
|
||||
ret = iso_node_revert_xinfo_list(to_node, 0);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type of an IsoNode.
|
||||
*/
|
||||
@ -242,6 +320,7 @@ enum IsoNodeType iso_node_get_type(IsoNode *node)
|
||||
int iso_node_set_name(IsoNode *node, const char *name)
|
||||
{
|
||||
char *new;
|
||||
int ret;
|
||||
|
||||
if ((IsoNode*)node->parent == node) {
|
||||
/* you can't change name of the root node */
|
||||
@ -249,9 +328,9 @@ int iso_node_set_name(IsoNode *node, const char *name)
|
||||
}
|
||||
|
||||
/* check if the name is valid */
|
||||
if (!iso_node_is_valid_name(name)) {
|
||||
return ISO_WRONG_ARG_VALUE;
|
||||
}
|
||||
ret = iso_node_is_valid_name(name);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (node->parent != NULL) {
|
||||
/* check if parent already has a node with same name */
|
||||
@ -651,6 +730,9 @@ int iso_node_take(IsoNode *node)
|
||||
if (dir == NULL) {
|
||||
return ISO_NODE_NOT_ADDED_TO_DIR;
|
||||
}
|
||||
|
||||
/* >>> Do not take root directory ! (dir == node) ? */;
|
||||
|
||||
pos = iso_dir_find_node(dir, node);
|
||||
if (pos == NULL) {
|
||||
/* should never occur */
|
||||
@ -686,6 +768,44 @@ int iso_node_remove(IsoNode *node)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* API */
|
||||
int iso_node_remove_tree(IsoNode *node, IsoDirIter *boss_iter)
|
||||
{
|
||||
IsoDirIter *iter = NULL;
|
||||
IsoNode *sub_node;
|
||||
int ret;
|
||||
|
||||
if (node->type != LIBISO_DIR) {
|
||||
|
||||
/* >>> Do not remove root directory ! (node->parent == node) ? */;
|
||||
|
||||
ret = iso_dir_get_children((IsoDir *) node, &iter);
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
while(1) {
|
||||
ret = iso_dir_iter_next(iter, &sub_node);
|
||||
if (ret == 0)
|
||||
break;
|
||||
ret = iso_node_remove_tree(sub_node, iter);
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
}
|
||||
if (node->parent == NULL) {
|
||||
/* node is not grafted into a boss directory */
|
||||
iso_node_unref(node);
|
||||
goto ex;
|
||||
}
|
||||
}
|
||||
if (boss_iter != NULL)
|
||||
ret = iso_dir_iter_remove(boss_iter);
|
||||
else
|
||||
ret = iso_node_remove(node);
|
||||
ex:;
|
||||
if (iter != NULL)
|
||||
iso_dir_iter_free(iter);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the parent of the given iso tree node. No extra ref is added to the
|
||||
* returned directory, you must take your ref. with iso_node_ref() if you
|
||||
@ -881,10 +1001,11 @@ const char *iso_symlink_get_dest(const IsoSymlink *link)
|
||||
int iso_symlink_set_dest(IsoSymlink *link, const char *dest)
|
||||
{
|
||||
char *d;
|
||||
if (!iso_node_is_valid_link_dest(dest)) {
|
||||
/* guard against null or empty dest */
|
||||
return ISO_WRONG_ARG_VALUE;
|
||||
}
|
||||
int ret;
|
||||
|
||||
ret = iso_node_is_valid_link_dest(dest);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
d = strdup(dest);
|
||||
if (d == NULL) {
|
||||
return ISO_OUT_OF_MEM;
|
||||
@ -1035,22 +1156,23 @@ int iso_node_is_valid_name(const char *name)
|
||||
{
|
||||
/* a name can't be NULL */
|
||||
if (name == NULL) {
|
||||
return 0;
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
|
||||
/* guard against the empty string or big names... */
|
||||
if (name[0] == '\0' || strlen(name) > 255) {
|
||||
return 0;
|
||||
}
|
||||
if (name[0] == '\0')
|
||||
return ISO_RR_NAME_RESERVED;
|
||||
if (strlen(name) > LIBISOFS_NODE_NAME_MAX)
|
||||
return ISO_RR_NAME_TOO_LONG;
|
||||
|
||||
/* ...against "." and ".." names... */
|
||||
if (!strcmp(name, ".") || !strcmp(name, "..")) {
|
||||
return 0;
|
||||
return ISO_RR_NAME_RESERVED;
|
||||
}
|
||||
|
||||
/* ...and against names with '/' */
|
||||
if (strchr(name, '/') != NULL) {
|
||||
return 0;
|
||||
return ISO_RR_NAME_RESERVED;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -1068,13 +1190,14 @@ int iso_node_is_valid_link_dest(const char *dest)
|
||||
|
||||
/* a dest can't be NULL */
|
||||
if (dest == NULL) {
|
||||
return 0;
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
|
||||
/* guard against the empty string or big dest... */
|
||||
if (dest[0] == '\0' || strlen(dest) > PATH_MAX) {
|
||||
return 0;
|
||||
}
|
||||
if (dest[0] == '\0')
|
||||
return ISO_RR_NAME_RESERVED;
|
||||
if (strlen(dest) > LIBISOFS_NODE_PATH_MAX)
|
||||
return ISO_RR_PATH_TOO_LONG;
|
||||
|
||||
/* check that all components are valid */
|
||||
if (!strcmp(dest, "/")) {
|
||||
@ -1084,7 +1207,7 @@ int iso_node_is_valid_link_dest(const char *dest)
|
||||
|
||||
ptr = strdup(dest);
|
||||
if (ptr == NULL) {
|
||||
return 0;
|
||||
return ISO_OUT_OF_MEM;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
@ -1092,7 +1215,7 @@ int iso_node_is_valid_link_dest(const char *dest)
|
||||
while (component) {
|
||||
if (strcmp(component, ".") && strcmp(component, "..")) {
|
||||
ret = iso_node_is_valid_name(component);
|
||||
if (ret == 0) {
|
||||
if (ret < 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1251,15 +1374,16 @@ int iso_node_new_root(IsoDir **root)
|
||||
int iso_node_new_dir(char *name, IsoDir **dir)
|
||||
{
|
||||
IsoDir *new;
|
||||
int ret;
|
||||
|
||||
if (dir == NULL || name == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
|
||||
/* check if the name is valid */
|
||||
if (!iso_node_is_valid_name(name)) {
|
||||
return ISO_WRONG_ARG_VALUE;
|
||||
}
|
||||
ret = iso_node_is_valid_name(name);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
new = calloc(1, sizeof(IsoDir));
|
||||
if (new == NULL) {
|
||||
@ -1276,15 +1400,16 @@ int iso_node_new_dir(char *name, IsoDir **dir)
|
||||
int iso_node_new_file(char *name, IsoStream *stream, IsoFile **file)
|
||||
{
|
||||
IsoFile *new;
|
||||
int ret;
|
||||
|
||||
if (file == NULL || name == NULL || stream == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
|
||||
/* check if the name is valid */
|
||||
if (!iso_node_is_valid_name(name)) {
|
||||
return ISO_WRONG_ARG_VALUE;
|
||||
}
|
||||
ret = iso_node_is_valid_name(name);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
new = calloc(1, sizeof(IsoFile));
|
||||
if (new == NULL) {
|
||||
@ -1304,21 +1429,21 @@ int iso_node_new_file(char *name, IsoStream *stream, IsoFile **file)
|
||||
int iso_node_new_symlink(char *name, char *dest, IsoSymlink **link)
|
||||
{
|
||||
IsoSymlink *new;
|
||||
int ret;
|
||||
|
||||
if (link == NULL || name == NULL || dest == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
|
||||
/* check if the name is valid */
|
||||
if (!iso_node_is_valid_name(name)) {
|
||||
return ISO_WRONG_ARG_VALUE;
|
||||
}
|
||||
ret = iso_node_is_valid_name(name);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* check if destination is valid */
|
||||
if (!iso_node_is_valid_link_dest(dest)) {
|
||||
/* guard against null or empty dest */
|
||||
return ISO_WRONG_ARG_VALUE;
|
||||
}
|
||||
ret = iso_node_is_valid_link_dest(dest);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
new = calloc(1, sizeof(IsoSymlink));
|
||||
if (new == NULL) {
|
||||
@ -1340,6 +1465,7 @@ int iso_node_new_special(char *name, mode_t mode, dev_t dev,
|
||||
IsoSpecial **special)
|
||||
{
|
||||
IsoSpecial *new;
|
||||
int ret;
|
||||
|
||||
if (special == NULL || name == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
@ -1349,9 +1475,9 @@ int iso_node_new_special(char *name, mode_t mode, dev_t dev,
|
||||
}
|
||||
|
||||
/* check if the name is valid */
|
||||
if (!iso_node_is_valid_name(name)) {
|
||||
return ISO_WRONG_ARG_VALUE;
|
||||
}
|
||||
ret = iso_node_is_valid_name(name);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
new = calloc(1, sizeof(IsoSpecial));
|
||||
if (new == NULL) {
|
||||
@ -2153,6 +2279,23 @@ int zisofs_zf_xinfo_func(void *data, int flag)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* The iso_node_xinfo_cloner function which gets associated to
|
||||
* zisofs_zf_xinfo_func by iso_init() resp. iso_init_with_flag() via
|
||||
* iso_node_xinfo_make_clonable()
|
||||
*/
|
||||
int zisofs_zf_xinfo_cloner(void *old_data, void **new_data, int flag)
|
||||
{
|
||||
*new_data = NULL;
|
||||
if (flag)
|
||||
return ISO_XINFO_NO_CLONE;
|
||||
if (old_data == NULL)
|
||||
return 0;
|
||||
*new_data = calloc(1, sizeof(struct zisofs_zf_info));
|
||||
if (*new_data == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
memcpy(*new_data, old_data, sizeof(struct zisofs_zf_info));
|
||||
return (int) sizeof(struct zisofs_zf_info);
|
||||
}
|
||||
|
||||
/* Checks whether a file effectively bears a zisofs file header and eventually
|
||||
* marks this by a struct zisofs_zf_info as xinfo of the file node.
|
||||
@ -2274,6 +2417,21 @@ int iso_px_ino_xinfo_func(void *data, int flag)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* The iso_node_xinfo_cloner function which gets associated to
|
||||
* iso_px_ino_xinfo_func by iso_init() resp. iso_init_with_flag() via
|
||||
* iso_node_xinfo_make_clonable()
|
||||
*/
|
||||
int iso_px_ino_xinfo_cloner(void *old_data, void **new_data, int flag)
|
||||
{
|
||||
*new_data = NULL;
|
||||
if (flag)
|
||||
return ISO_XINFO_NO_CLONE;
|
||||
*new_data = calloc(1, sizeof(ino_t));
|
||||
if (*new_data == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
memcpy(*new_data, old_data, sizeof(ino_t));
|
||||
return (int) sizeof(ino_t);
|
||||
}
|
||||
|
||||
/*
|
||||
* @param flag
|
||||
@ -2364,7 +2522,6 @@ int iso_node_set_ino_xinfo(IsoNode *node, ino_t ino, int flag)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int iso_node_set_ino(IsoNode *node, ino_t ino, int flag)
|
||||
{
|
||||
int ret;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2009 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2011 Thomas Schmitt
|
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
@ -20,7 +20,38 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#else
|
||||
#ifdef HAVE_INTTYPES_H
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* Maximum length of a leaf name in the libisofs node tree. This is currently
|
||||
restricted by the implemented maximum length of a Rock Ridge name.
|
||||
This might later become larger and may then be limited to smaller values.
|
||||
|
||||
Rock Ridge specs do not impose an explicit limit on name length.
|
||||
But 255 is also specified by
|
||||
http://pubs.opengroup.org/onlinepubs/009695399/basedefs/limits.h.html
|
||||
which says
|
||||
NAME_MAX >= _XOPEN_NAME_MAX = 255
|
||||
*/
|
||||
#define LIBISOFS_NODE_NAME_MAX 255
|
||||
|
||||
|
||||
/* Maximum length of a path in the libisofs node tree.
|
||||
Rock Ridge specs do not impose an explicit limit on path length.
|
||||
|
||||
http://pubs.opengroup.org/onlinepubs/009695399/basedefs/limits.h.html
|
||||
says
|
||||
PATH_MAX >= _XOPEN_PATH_MAX = 1024
|
||||
*/
|
||||
#define LIBISOFS_NODE_PATH_MAX 1024
|
||||
|
||||
|
||||
/**
|
||||
* The extended information is a way to attach additional information to each
|
||||
@ -113,6 +144,7 @@ struct Iso_Dir
|
||||
IsoNode *children; /**< list of children. ptr to first child */
|
||||
};
|
||||
|
||||
/* IMPORTANT: Any change must be reflected by iso_tree_clone_file. */
|
||||
struct Iso_File
|
||||
{
|
||||
IsoNode node;
|
||||
@ -277,7 +309,7 @@ int iso_node_new_special(char *name, mode_t mode, dev_t dev,
|
||||
* Check if a given name is valid for an iso node.
|
||||
*
|
||||
* @return
|
||||
* 1 if yes, 0 if not
|
||||
* 1 if yes, <0 if not. The value is a specific ISO_* error code.
|
||||
*/
|
||||
int iso_node_is_valid_name(const char *name);
|
||||
|
||||
@ -473,4 +505,35 @@ int iso_root_get_isofsca(IsoNode *node, uint32_t *start_lba, uint32_t *end_lba,
|
||||
int flag);
|
||||
|
||||
|
||||
/**
|
||||
* Copy the xinfo list from one node to the another.
|
||||
*/
|
||||
int iso_node_clone_xinfo(IsoNode *from_node, IsoNode *to_node, int flag);
|
||||
|
||||
|
||||
/**
|
||||
* The iso_node_xinfo_func instance which governs the storing of the inode
|
||||
* number from Rock Ridge field PX.
|
||||
*/
|
||||
int iso_px_ino_xinfo_func(void *data, int flag);
|
||||
|
||||
/* The iso_node_xinfo_cloner function which gets associated to
|
||||
* iso_px_ino_xinfo_func by iso_init() resp. iso_init_with_flag() via
|
||||
* iso_node_xinfo_make_clonable()
|
||||
*/
|
||||
int iso_px_ino_xinfo_cloner(void *old_data, void **new_data, int flag);
|
||||
|
||||
|
||||
/* Function to identify and manage ZF parameters of zisofs compression.
|
||||
* data is supposed to be a pointer to struct zisofs_zf_info
|
||||
*/
|
||||
int zisofs_zf_xinfo_func(void *data, int flag);
|
||||
|
||||
/* The iso_node_xinfo_cloner function which gets associated to
|
||||
* zisofs_zf_xinfo_func by iso_init() resp. iso_init_with_flag() via
|
||||
* iso_node_xinfo_make_clonable()
|
||||
*/
|
||||
int zisofs_zf_xinfo_cloner(void *old_data, void **new_data, int flag);
|
||||
|
||||
|
||||
#endif /*LIBISO_NODE_H_*/
|
||||
|
@ -13,6 +13,9 @@
|
||||
#include "../config.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "rockridge.h"
|
||||
#include "node.h"
|
||||
#include "ecma119_tree.h"
|
||||
@ -22,7 +25,12 @@
|
||||
#include "aaip_0_2.h"
|
||||
#include "libisofs.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifdef Libisofs_with_rrip_rR
|
||||
#define ISO_ROCKRIDGE_IN_DIR_REC 128
|
||||
#else
|
||||
#define ISO_ROCKRIDGE_IN_DIR_REC 124
|
||||
#endif
|
||||
|
||||
|
||||
static
|
||||
@ -329,7 +337,12 @@ static
|
||||
int rrip_add_NM(Ecma119Image *t, struct susp_info *susp, char *name, int size,
|
||||
int flags, int ce)
|
||||
{
|
||||
uint8_t *NM = malloc(size + 5);
|
||||
uint8_t *NM;
|
||||
|
||||
if (size > 250)
|
||||
return ISO_ASSERT_FAILURE;
|
||||
|
||||
NM = malloc(size + 5);
|
||||
if (NM == NULL) {
|
||||
return ISO_OUT_OF_MEM;
|
||||
}
|
||||
@ -897,7 +910,7 @@ int add_zf_field(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* API */
|
||||
int aaip_xinfo_func(void *data, int flag)
|
||||
{
|
||||
if (flag & 1) {
|
||||
@ -906,6 +919,23 @@ int aaip_xinfo_func(void *data, int flag)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* API */
|
||||
int aaip_xinfo_cloner(void *old_data, void **new_data, int flag)
|
||||
{
|
||||
size_t aa_size;
|
||||
|
||||
*new_data = NULL;
|
||||
if (old_data == NULL)
|
||||
return 0;
|
||||
aa_size = aaip_count_bytes((unsigned char *) old_data, 0);
|
||||
if (aa_size <= 0)
|
||||
return ISO_AAIP_BAD_AASTRING;
|
||||
*new_data = calloc(1, aa_size);
|
||||
if (*new_data == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
memcpy(*new_data, old_data, aa_size);
|
||||
return (int) aa_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute SUA length and eventual Continuation Area length of field NM and
|
||||
@ -920,6 +950,7 @@ int aaip_xinfo_func(void *data, int flag)
|
||||
* (*su_size and *ce stay unaltered in this case)
|
||||
* <0= error:
|
||||
* -1= not enough SUA space for 28 bytes of CE entry
|
||||
* -2= out of memory
|
||||
*/
|
||||
static
|
||||
int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
|
||||
@ -956,6 +987,9 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
|
||||
if (!(flag & 1))
|
||||
goto unannounced_ca;
|
||||
namelen = namelen - (space - *su_size - 5);
|
||||
|
||||
/* >>> Need to handle lengths > 250 */;
|
||||
|
||||
*ce = 5 + namelen;
|
||||
*su_size = space;
|
||||
}
|
||||
@ -968,6 +1002,8 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
|
||||
int cew = (*ce != 0); /* are we writing to CA ? */
|
||||
|
||||
dest = get_rr_fname(t, ((IsoSymlink*)n->node)->dest);
|
||||
if (dest == NULL)
|
||||
return -2;
|
||||
prev = dest;
|
||||
cur = strchr(prev, '/');
|
||||
while (1) {
|
||||
@ -996,8 +1032,10 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
|
||||
* TODO this can be handled better, but for now SL
|
||||
* will be completelly moved into the CA
|
||||
*/
|
||||
if (!(flag & 1))
|
||||
if (!(flag & 1)) {
|
||||
free(dest);
|
||||
goto unannounced_ca;
|
||||
}
|
||||
cew = 1;
|
||||
} else {
|
||||
sl_len += clen;
|
||||
@ -1097,6 +1135,44 @@ unannounced_ca:;
|
||||
}
|
||||
|
||||
|
||||
/* @param flag bit0= Do not add data but only count sua_free and ce_len
|
||||
param info may be NULL in this case
|
||||
*/
|
||||
static
|
||||
int add_aa_string(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
|
||||
size_t *sua_free, size_t *ce_len, int flag)
|
||||
{
|
||||
int ret;
|
||||
uint8_t *aapt;
|
||||
void *xipt;
|
||||
size_t num_aapt= 0;
|
||||
|
||||
if (!t->aaip)
|
||||
return 1;
|
||||
|
||||
ret = iso_node_get_xinfo(n->node, aaip_xinfo_func, &xipt);
|
||||
if (ret == 1) {
|
||||
num_aapt = aaip_count_bytes((unsigned char *) xipt, 0);
|
||||
if (num_aapt > 0) {
|
||||
if (flag & 1) {
|
||||
ret = aaip_add_AL(t, NULL,NULL, num_aapt, sua_free, ce_len, 1);
|
||||
} else {
|
||||
aapt = malloc(num_aapt);
|
||||
if (aapt == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
memcpy(aapt, xipt, num_aapt);
|
||||
ret = aaip_add_AL(t, info, &aapt, num_aapt, sua_free, ce_len,
|
||||
0);
|
||||
}
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
/* aapt is NULL now and the memory is owned by t */
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute the length needed for write all RR and SUSP entries for a given
|
||||
* node.
|
||||
@ -1104,27 +1180,31 @@ unannounced_ca:;
|
||||
* @param type
|
||||
* 0 normal entry, 1 "." entry for that node (it is a dir), 2 ".."
|
||||
* for that node (i.e., it will refer to the parent)
|
||||
* @param space
|
||||
* Available space in the System Use Area for the directory record.
|
||||
* @param used_up
|
||||
* Already occupied space in the directory record.
|
||||
* @param ce
|
||||
* Will be filled with the space needed in a CE
|
||||
* @return
|
||||
* The size needed for the RR entries in the System Use Area
|
||||
*/
|
||||
size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t space,
|
||||
size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t used_up,
|
||||
size_t *ce)
|
||||
{
|
||||
size_t su_size;
|
||||
size_t su_size, space;
|
||||
int ret;
|
||||
size_t aaip_sua_free= 0, aaip_len= 0;
|
||||
|
||||
/* Directory record length must be even (ECMA-119, 9.1.13). Maximum is 254.
|
||||
*/
|
||||
space = 254 - used_up - (used_up % 2);
|
||||
if (type < 0 || type > 2 || space < ISO_ROCKRIDGE_IN_DIR_REC) {
|
||||
iso_msg_submit(t->image->id, ISO_ASSERT_FAILURE, 0,
|
||||
"Unknown node type %d or short RR space %d < %d in directory record",
|
||||
type, (int) space, ISO_ROCKRIDGE_IN_DIR_REC);
|
||||
return ISO_ASSERT_FAILURE;
|
||||
}
|
||||
|
||||
/* space min is 255 - 33 - 37 = 185
|
||||
* At the same time, it is always an odd number, but we need to pad it
|
||||
* propertly to ensure the length of a directory record is a even number
|
||||
* (ECMA-119, 9.1.13). Thus, in fact the real space is always space - 1
|
||||
*/
|
||||
space--;
|
||||
*ce = 0;
|
||||
|
||||
su_size = 0;
|
||||
|
||||
/* If AAIP enabled and announced by ER : account for 5 bytes of ES */;
|
||||
@ -1169,7 +1249,9 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t space,
|
||||
/* Try without CE */
|
||||
ret = susp_calc_nm_sl_al(t, n, space, &su_size, ce, 0);
|
||||
if (ret == 0) /* Retry with CE */
|
||||
susp_calc_nm_sl_al(t, n, space, &su_size, ce, 1);
|
||||
ret = susp_calc_nm_sl_al(t, n, space, &su_size, ce, 1);
|
||||
if (ret == -2)
|
||||
return ISO_OUT_OF_MEM;
|
||||
|
||||
} else {
|
||||
|
||||
@ -1190,9 +1272,15 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t space,
|
||||
} else {
|
||||
*ce = 182;
|
||||
}
|
||||
if (t->aaip) {
|
||||
if (t->aaip && !t->aaip_susp_1_10) {
|
||||
*ce += 160; /* ER of AAIP */
|
||||
}
|
||||
/* Compute length of AAIP string of root node */
|
||||
aaip_sua_free= 0;
|
||||
ret = add_aa_string(t, n, NULL, &aaip_sua_free, &aaip_len, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
*ce += aaip_len;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1224,43 +1312,6 @@ void susp_info_free(struct susp_info* susp)
|
||||
}
|
||||
|
||||
|
||||
/* @param flag bit0= Do not add data but only count sua_free and ce_len
|
||||
*/
|
||||
static
|
||||
int add_aa_string(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
|
||||
size_t *sua_free, size_t *ce_len, int flag)
|
||||
{
|
||||
int ret;
|
||||
uint8_t *aapt;
|
||||
void *xipt;
|
||||
size_t num_aapt= 0;
|
||||
|
||||
if (!t->aaip)
|
||||
return 1;
|
||||
|
||||
ret = iso_node_get_xinfo(n->node, aaip_xinfo_func, &xipt);
|
||||
if (ret == 1) {
|
||||
num_aapt = aaip_count_bytes((unsigned char *) xipt, 0);
|
||||
if (num_aapt > 0) {
|
||||
if (flag & 1) {
|
||||
ret = aaip_add_AL(t, NULL,NULL, num_aapt, sua_free, ce_len, 1);
|
||||
} else {
|
||||
aapt = malloc(num_aapt);
|
||||
if (aapt == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
memcpy(aapt, xipt, num_aapt);
|
||||
ret = aaip_add_AL(t, info, &aapt, num_aapt, sua_free, ce_len,
|
||||
0);
|
||||
}
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
/* aapt is NULL now and the memory is owned by t */
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fill a struct susp_info with the RR/SUSP entries needed for a given
|
||||
* node.
|
||||
@ -1268,8 +1319,8 @@ int add_aa_string(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
|
||||
* @param type
|
||||
* 0 normal entry, 1 "." entry for that node (it is a dir), 2 ".."
|
||||
* for that node (i.e., it will refer to the parent)
|
||||
* @param space
|
||||
* Available space in the System Use Area for the directory record.
|
||||
* @param used_up
|
||||
* Already occupied space in the directory record.
|
||||
* @param info
|
||||
* Pointer to the struct susp_info where the entries will be stored.
|
||||
* If some entries need to go to a Continuation Area, they will be added
|
||||
@ -1279,7 +1330,7 @@ int add_aa_string(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
|
||||
* 1 success, < 0 error
|
||||
*/
|
||||
int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
||||
size_t space, struct susp_info *info)
|
||||
size_t used_up, struct susp_info *info)
|
||||
{
|
||||
int ret;
|
||||
size_t i;
|
||||
@ -1291,13 +1342,20 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
||||
size_t su_size_pd, ce_len_pd; /* predicted sizes of SUA and CA */
|
||||
int ce_is_predicted = 0;
|
||||
size_t aaip_sua_free= 0, aaip_len= 0;
|
||||
size_t space;
|
||||
|
||||
if (t == NULL || n == NULL || info == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
if (type < 0 || type > 2 || space < 185) {
|
||||
/* space min is 255 - 33 - 37 = 185 */
|
||||
return ISO_WRONG_ARG_VALUE;
|
||||
|
||||
/* Directory record length must be even (ECMA-119, 9.1.13). Maximum is 254.
|
||||
*/
|
||||
space = 254 - used_up - (used_up % 2);
|
||||
if (type < 0 || type > 2 || space < ISO_ROCKRIDGE_IN_DIR_REC) {
|
||||
iso_msg_submit(t->image->id, ISO_ASSERT_FAILURE, 0,
|
||||
"Unknown node type %d or short RR space %d < %d in directory record",
|
||||
type, (int) space, ISO_ROCKRIDGE_IN_DIR_REC);
|
||||
return ISO_ASSERT_FAILURE;
|
||||
}
|
||||
|
||||
if (type == 2 && n->parent != NULL) {
|
||||
@ -1306,13 +1364,6 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
||||
node = n;
|
||||
}
|
||||
|
||||
/* space min is 255 - 33 - 37 = 185
|
||||
* At the same time, it is always an odd number, but we need to pad it
|
||||
* propertly to ensure the length of a directory record is a even number
|
||||
* (ECMA-119, 9.1.13). Thus, in fact the real space is always space - 1
|
||||
*/
|
||||
space--;
|
||||
|
||||
/*
|
||||
* SP must be the first entry for the "." record of the root directory
|
||||
* (SUSP, 5.3)
|
||||
@ -1384,6 +1435,13 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
||||
}
|
||||
}
|
||||
|
||||
if (info->suf_len + 28 > space) {
|
||||
iso_msg_submit(t->image->id, ISO_ASSERT_FAILURE, 0,
|
||||
"Directory Record overflow. name='%s' , suf_len=%d > space=%d - 28\n",
|
||||
node->iso_name, (int) info->suf_len, (int) space);
|
||||
return ISO_ASSERT_FAILURE;
|
||||
}
|
||||
|
||||
if (type == 0) {
|
||||
size_t sua_free; /* free space in the SUA */
|
||||
int nm_type = 0; /* 0 whole entry in SUA, 1 part in CE */
|
||||
@ -1404,10 +1462,14 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
||||
ce_len_pd = ce_len;
|
||||
ret = susp_calc_nm_sl_al(t, n, space, &su_size_pd, &ce_len_pd, 0);
|
||||
if (ret == 0) { /* Have to use CA. 28 bytes of CE are necessary */
|
||||
susp_calc_nm_sl_al(t, n, space, &su_size_pd, &ce_len_pd, 1);
|
||||
ret = susp_calc_nm_sl_al(t, n, space, &su_size_pd, &ce_len_pd, 1);
|
||||
sua_free -= 28;
|
||||
ce_is_predicted = 1;
|
||||
}
|
||||
if (ret == -2) {
|
||||
ret = ISO_OUT_OF_MEM;
|
||||
goto add_susp_cleanup;
|
||||
}
|
||||
|
||||
/* NM entry */
|
||||
if (5 + namelen <= sua_free) {
|
||||
@ -1605,6 +1667,9 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
||||
/*
|
||||
* ..and the part that goes to continuation area.
|
||||
*/
|
||||
|
||||
/* >>> Need a loop to handle lengths > 250 */;
|
||||
|
||||
ret = rrip_add_NM(t, info, name + namelen, strlen(name + namelen),
|
||||
0, 1);
|
||||
if (ret < 0) {
|
||||
@ -1670,7 +1735,7 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
||||
|
||||
/* Compute length of AAIP string of root node */
|
||||
aaip_sua_free= 0;
|
||||
ret = add_aa_string(t, n, info, &aaip_sua_free, &aaip_len, 1);
|
||||
ret = add_aa_string(t, n, NULL, &aaip_sua_free, &aaip_len, 1);
|
||||
if (ret < 0)
|
||||
goto add_susp_cleanup;
|
||||
|
||||
|
@ -443,7 +443,7 @@ int read_rr_PN(struct susp_sys_user_entry *pn, struct stat *st)
|
||||
}
|
||||
|
||||
|
||||
/* AA is the field signature of AAIP versions < 2.0
|
||||
/* AA is the obsolete field signature of AAIP versions < 2.0
|
||||
*/
|
||||
int read_aaip_AA(struct susp_sys_user_entry *sue,
|
||||
unsigned char **aa_string, size_t *aa_size, size_t *aa_len,
|
||||
@ -514,7 +514,7 @@ int read_aaip_AA(struct susp_sys_user_entry *sue,
|
||||
}
|
||||
|
||||
|
||||
/* AL is the obsolete field signature of AAIP versions >= 2.0
|
||||
/* AL is the field signature of AAIP versions >= 2.0
|
||||
*/
|
||||
int read_aaip_AL(struct susp_sys_user_entry *sue,
|
||||
unsigned char **aa_string, size_t *aa_size, size_t *aa_len,
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2009 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2011 Thomas Schmitt
|
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
@ -16,6 +16,7 @@
|
||||
#include "stream.h"
|
||||
#include "fsource.h"
|
||||
#include "util.h"
|
||||
#include "node.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -157,8 +158,64 @@ int fsrc_update_size(IsoStream *stream)
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
static
|
||||
IsoStream *fsrc_get_input_stream(IsoStream *stream, int flag)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static
|
||||
int fsrc_cmp_ino(IsoStream *s1, IsoStream *s2)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = iso_stream_cmp_ino(s1, s2, 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int fsrc_clone_stream(IsoStream *old_stream, IsoStream **new_stream,
|
||||
int flag)
|
||||
{
|
||||
FSrcStreamData *data, *new_data;
|
||||
IsoStream *stream;
|
||||
int ret;
|
||||
|
||||
if (flag)
|
||||
return ISO_STREAM_NO_CLONE; /* unknown option required */
|
||||
|
||||
data = (FSrcStreamData*) old_stream->data;
|
||||
if (data->src->class->version < 2)
|
||||
return ISO_STREAM_NO_CLONE; /* No clone_src() method available */
|
||||
|
||||
*new_stream = NULL;
|
||||
stream = calloc(1, sizeof(IsoStream));
|
||||
if (stream == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
new_data = calloc(1, sizeof(FSrcStreamData));
|
||||
if (new_data == NULL) {
|
||||
free((char *) stream);
|
||||
return ISO_OUT_OF_MEM;
|
||||
}
|
||||
*new_stream = stream;
|
||||
stream->class = old_stream->class;
|
||||
stream->refcount = 1;
|
||||
stream->data = new_data;
|
||||
|
||||
ret = data->src->class->clone_src(data->src, &(new_data->src), 0);
|
||||
if (ret < 0) {
|
||||
free((char *) stream);
|
||||
free((char *) new_data);
|
||||
return ret;
|
||||
}
|
||||
new_data->dev_id = data->dev_id;
|
||||
new_data->ino_id = data->ino_id;
|
||||
new_data->size = data->size;
|
||||
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
IsoStreamIface fsrc_stream_class = {
|
||||
1, /* update_size is defined for this stream */
|
||||
4, /* version */
|
||||
"fsrc",
|
||||
fsrc_open,
|
||||
fsrc_close,
|
||||
@ -167,7 +224,10 @@ IsoStreamIface fsrc_stream_class = {
|
||||
fsrc_is_repeatable,
|
||||
fsrc_get_id,
|
||||
fsrc_free,
|
||||
fsrc_update_size
|
||||
fsrc_update_size,
|
||||
fsrc_get_input_stream,
|
||||
fsrc_cmp_ino,
|
||||
fsrc_clone_stream
|
||||
};
|
||||
|
||||
int iso_file_source_stream_new(IsoFileSource *src, IsoStream **stream)
|
||||
@ -375,11 +435,76 @@ void cut_out_free(IsoStream *stream)
|
||||
free(data);
|
||||
}
|
||||
|
||||
static
|
||||
int cut_out_update_size(IsoStream *stream)
|
||||
{
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
static
|
||||
IsoStream* cut_out_get_input_stream(IsoStream *stream, int flag)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static
|
||||
int cut_out_cmp_ino(IsoStream *s1, IsoStream *s2)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = iso_stream_cmp_ino(s1, s2, 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static
|
||||
int cut_out_clone_stream(IsoStream *old_stream, IsoStream **new_stream,
|
||||
int flag)
|
||||
{
|
||||
struct cut_out_stream *data, *new_data;
|
||||
IsoStream *stream;
|
||||
int ret;
|
||||
|
||||
if (flag)
|
||||
return ISO_STREAM_NO_CLONE; /* unknown option required */
|
||||
|
||||
data = (struct cut_out_stream *) old_stream->data;
|
||||
if (data->src->class->version < 2)
|
||||
return ISO_STREAM_NO_CLONE; /* No clone_src() method available */
|
||||
|
||||
*new_stream = NULL;
|
||||
stream = calloc(1, sizeof(IsoStream));
|
||||
if (stream == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
stream->refcount = 1;
|
||||
stream->class = old_stream->class;
|
||||
new_data = calloc(1, sizeof(struct cut_out_stream));
|
||||
if (new_data == NULL) {
|
||||
free((char *) stream);
|
||||
return ISO_OUT_OF_MEM;
|
||||
}
|
||||
ret = data->src->class->clone_src(data->src, &(new_data->src), 0);
|
||||
if (ret < 0) {
|
||||
free((char *) stream);
|
||||
free((char *) new_data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
new_data->dev_id = (dev_t) 0;
|
||||
new_data->ino_id = cut_out_serial_id++;
|
||||
new_data->offset = data->offset;
|
||||
new_data->size = data->size;
|
||||
new_data->pos = 0;
|
||||
|
||||
stream->data = new_data;
|
||||
*new_stream = stream;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO update cut out streams to deal with update_size(). Seems hard.
|
||||
*/
|
||||
IsoStreamIface cut_out_stream_class = {
|
||||
0,
|
||||
4, /* version */
|
||||
"cout",
|
||||
cut_out_open,
|
||||
cut_out_close,
|
||||
@ -387,7 +512,12 @@ IsoStreamIface cut_out_stream_class = {
|
||||
cut_out_read,
|
||||
cut_out_is_repeatable,
|
||||
cut_out_get_id,
|
||||
cut_out_free
|
||||
cut_out_free,
|
||||
cut_out_update_size,
|
||||
cut_out_get_input_stream,
|
||||
cut_out_cmp_ino,
|
||||
cut_out_clone_stream
|
||||
|
||||
};
|
||||
|
||||
int iso_cut_out_stream_new(IsoFileSource *src, off_t offset, off_t size,
|
||||
@ -549,12 +679,77 @@ void mem_free(IsoStream *stream)
|
||||
{
|
||||
MemStreamData *data;
|
||||
data = (MemStreamData*)stream->data;
|
||||
free(data->buf);
|
||||
if (data->buf != NULL)
|
||||
free(data->buf);
|
||||
free(data);
|
||||
}
|
||||
|
||||
static
|
||||
int mem_update_size(IsoStream *stream)
|
||||
{
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
static
|
||||
IsoStream* mem_get_input_stream(IsoStream *stream, int flag)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static
|
||||
int mem_cmp_ino(IsoStream *s1, IsoStream *s2)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = iso_stream_cmp_ino(s1, s2, 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static
|
||||
int mem_clone_stream(IsoStream *old_stream, IsoStream **new_stream,
|
||||
int flag)
|
||||
{
|
||||
MemStreamData *data, *new_data;
|
||||
IsoStream *stream;
|
||||
uint8_t *new_buf = NULL;
|
||||
|
||||
if (flag)
|
||||
return ISO_STREAM_NO_CLONE; /* unknown option required */
|
||||
|
||||
*new_stream = NULL;
|
||||
stream = calloc(1, sizeof(IsoStream));
|
||||
if (stream == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
stream->refcount = 1;
|
||||
stream->class = old_stream->class;
|
||||
new_data = calloc(1, sizeof(MemStreamData));
|
||||
if (new_data == NULL) {
|
||||
free((char *) stream);
|
||||
return ISO_OUT_OF_MEM;
|
||||
}
|
||||
data = (MemStreamData *) old_stream->data;
|
||||
if (data->size > 0) {
|
||||
new_buf = calloc(1, data->size);
|
||||
if (new_buf == NULL) {
|
||||
free((char *) stream);
|
||||
free((char *) new_data);
|
||||
return ISO_OUT_OF_MEM;
|
||||
}
|
||||
memcpy(new_buf, data->buf, data->size);
|
||||
}
|
||||
new_data->buf = new_buf;
|
||||
new_data->offset = -1;
|
||||
new_data->ino_id = mem_serial_id++;
|
||||
new_data->size = data->size;
|
||||
|
||||
stream->data = new_data;
|
||||
*new_stream = stream;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
IsoStreamIface mem_stream_class = {
|
||||
0,
|
||||
4, /* version */
|
||||
"mem ",
|
||||
mem_open,
|
||||
mem_close,
|
||||
@ -562,7 +757,12 @@ IsoStreamIface mem_stream_class = {
|
||||
mem_read,
|
||||
mem_is_repeatable,
|
||||
mem_get_id,
|
||||
mem_free
|
||||
mem_free,
|
||||
mem_update_size,
|
||||
mem_get_input_stream,
|
||||
mem_cmp_ino,
|
||||
mem_clone_stream
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
@ -570,7 +770,7 @@ IsoStreamIface mem_stream_class = {
|
||||
* When the Stream refcount reach 0, the buffer is free(3).
|
||||
*
|
||||
* @return
|
||||
* 1 sucess, < 0 error
|
||||
* 1 success, < 0 error
|
||||
*/
|
||||
int iso_memory_stream_new(unsigned char *buf, size_t size, IsoStream **stream)
|
||||
{
|
||||
@ -669,7 +869,8 @@ void iso_stream_get_file_name(IsoStream *stream, char *name)
|
||||
if (!strncmp(type, "fsrc", 4)) {
|
||||
FSrcStreamData *data = stream->data;
|
||||
char *path = iso_file_source_get_path(data->src);
|
||||
strncpy(name, path, PATH_MAX);
|
||||
strncpy(name, path, PATH_MAX - 1);
|
||||
name[PATH_MAX - 1] = 0;
|
||||
free(path);
|
||||
} else if (!strncmp(type, "boot", 4)) {
|
||||
strcpy(name, "BOOT CATALOG");
|
||||
@ -924,3 +1125,42 @@ ex:;
|
||||
iso_md5_end(&ctx, md5);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* API */
|
||||
int iso_stream_clone(IsoStream *old_stream, IsoStream **new_stream, int flag)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (old_stream->class->version < 4)
|
||||
return ISO_STREAM_NO_CLONE;
|
||||
ret = old_stream->class->clone_stream(old_stream, new_stream, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int iso_stream_clone_filter_common(IsoStream *old_stream,
|
||||
IsoStream **new_stream,
|
||||
IsoStream **new_input, int flag)
|
||||
{
|
||||
IsoStream *stream, *input_stream;
|
||||
int ret;
|
||||
|
||||
*new_stream = NULL;
|
||||
*new_input = NULL;
|
||||
input_stream = iso_stream_get_input_stream(old_stream, 0);
|
||||
if (input_stream == NULL)
|
||||
return ISO_STREAM_NO_CLONE;
|
||||
stream = calloc(1, sizeof(IsoStream));
|
||||
if (stream == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
ret = iso_stream_clone(input_stream, new_input, 0);
|
||||
if (ret < 0) {
|
||||
free((char *) stream);
|
||||
return ret;
|
||||
}
|
||||
stream->class = old_stream->class;
|
||||
stream->refcount = 1;
|
||||
stream->data = NULL;
|
||||
*new_stream = stream;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2009 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2011 Thomas Schmitt
|
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
@ -15,6 +15,7 @@
|
||||
*/
|
||||
#include "fsource.h"
|
||||
|
||||
/* IMPORTANT: Any change must be reflected by fsrc_clone_stream */
|
||||
typedef struct
|
||||
{
|
||||
IsoFileSource *src;
|
||||
@ -28,7 +29,8 @@ typedef struct
|
||||
/**
|
||||
* Get an identifier for the file of the source, for debug purposes
|
||||
* @param name
|
||||
* Should provide at least PATH_MAX bytes
|
||||
* Must provide at least PATH_MAX bytes. If no PATH_MAX is defined
|
||||
* then assume PATH_MAX = Libisofs_default_path_maX from libisofs.h
|
||||
*/
|
||||
void iso_stream_get_file_name(IsoStream *stream, char *name);
|
||||
|
||||
@ -55,15 +57,6 @@ int iso_file_source_stream_new(IsoFileSource *src, IsoStream **stream);
|
||||
int iso_cut_out_stream_new(IsoFileSource *src, off_t offset, off_t size,
|
||||
IsoStream **stream);
|
||||
|
||||
/**
|
||||
* Create a stream for reading from a arbitrary memory buffer.
|
||||
* When the Stream refcount reach 0, the buffer is free(3).
|
||||
*
|
||||
* @return
|
||||
* 1 sucess, < 0 error
|
||||
*/
|
||||
int iso_memory_stream_new(unsigned char *buf, size_t size, IsoStream **stream);
|
||||
|
||||
/**
|
||||
* Obtain eventual zisofs ZF field entry parameters from a file source out
|
||||
* of a loaded ISO image.
|
||||
@ -103,5 +96,20 @@ int iso_stream_read_buffer(IsoStream *stream, char *buf, size_t count,
|
||||
int iso_stream_make_md5(IsoStream *stream, char md5[16], int flag);
|
||||
|
||||
|
||||
/**
|
||||
* Create a clone of the input stream of old_stream and a roughly initialized
|
||||
* clone of old_stream which has the same class and refcount 1. Its data
|
||||
* pointer will be NULL and needs to be filled by an expert which knows how
|
||||
* to clone the data of old_stream.
|
||||
* @param old_stream The existing stream which is in process of cloning
|
||||
* @param new_stream Will return the uninitialized memory object which shall
|
||||
* later become the clone of old_stream.
|
||||
* @param new_input The clone of the input stream of old stream.
|
||||
* @param flag Submit 0 for now.
|
||||
* @return ISO_SUCCESS or an error code <0
|
||||
*/
|
||||
int iso_stream_clone_filter_common(IsoStream *old_stream,
|
||||
IsoStream **new_stream,
|
||||
IsoStream **new_input, int flag);
|
||||
|
||||
#endif /*STREAM_H_*/
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "ecma119_tree.h"
|
||||
#include "image.h"
|
||||
#include "messages.h"
|
||||
#include "ecma119.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
@ -79,13 +80,16 @@ void iso_compute_cyl_head_sec(uint32_t *img_blocks, int hpc, int sph,
|
||||
*/
|
||||
int iso_compute_append_partitions(Ecma119Image *t, int flag)
|
||||
{
|
||||
int ret, i;
|
||||
uint32_t pos, size;
|
||||
int ret, i, sa_type;
|
||||
uint32_t pos, size, add_pos = 0;
|
||||
struct stat stbuf;
|
||||
|
||||
sa_type = (t->system_area_options >> 2) & 0x3f;
|
||||
pos = (t->vol_space_size + t->ms_block);
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (i = 0; i < ISO_MAX_PARTITIONS; i++) {
|
||||
if (t->appended_partitions[i] == NULL)
|
||||
continue;
|
||||
if (t->appended_partitions[i][0] == 0)
|
||||
continue;
|
||||
ret = stat(t->appended_partitions[i], &stbuf);
|
||||
if (ret == -1)
|
||||
@ -93,10 +97,13 @@ int iso_compute_append_partitions(Ecma119Image *t, int flag)
|
||||
if (! S_ISREG(stbuf.st_mode))
|
||||
return ISO_BAD_PARTITION_FILE;
|
||||
size = ((stbuf.st_size + 2047) / 2048);
|
||||
t->appended_part_start[i] = pos;
|
||||
if (sa_type == 3 && (pos % ISO_SUN_CYL_SIZE))
|
||||
add_pos = ISO_SUN_CYL_SIZE - (pos % ISO_SUN_CYL_SIZE);
|
||||
t->appended_part_prepad[i] = add_pos;
|
||||
t->appended_part_start[i] = pos + add_pos;
|
||||
t->appended_part_size[i] = size;
|
||||
pos += size;
|
||||
t->total_size += size * 2048;
|
||||
pos += add_pos + size;
|
||||
t->total_size += (add_pos + size) * 2048;
|
||||
}
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
@ -565,9 +572,122 @@ static int make_mipsel_boot_block(Ecma119Image *t, uint8_t *buf, int flag)
|
||||
}
|
||||
|
||||
|
||||
/* The following two functions were implemented according to
|
||||
doc/boot_sectors.txt section "SUN Disk Label and boot images" which
|
||||
was derived by Thomas Schmitt from
|
||||
cdrtools-2.01.01a77/mkisofs/sunlabel.h
|
||||
cdrtools-2.01.01a77/mkisofs/mkisofs.8
|
||||
by Joerg Schilling
|
||||
|
||||
Both functions are entirely under copyright (C) 2010 Thomas Schmitt.
|
||||
*/
|
||||
|
||||
/* @parm flag bit0= copy from next lower valid partition table entry
|
||||
*/
|
||||
static int write_sun_partition_entry(int partition_number,
|
||||
char *appended_partitions[],
|
||||
uint32_t partition_offset[], uint32_t partition_size[],
|
||||
uint32_t cyl_size, uint8_t *buf, int flag)
|
||||
{
|
||||
uint8_t *wpt;
|
||||
int read_idx, i;
|
||||
|
||||
if (partition_number < 1 || partition_number > 8)
|
||||
return ISO_ASSERT_FAILURE;
|
||||
|
||||
/* 142 - 173 | ========== | 8 partition entries of 4 bytes */
|
||||
wpt = buf + 142 + (partition_number - 1) * 4;
|
||||
if (partition_number == 1)
|
||||
iso_msb(wpt, 4, 2); /* 4 = User partition */
|
||||
else
|
||||
iso_msb(wpt, 2, 2); /* 2 = Root partition with boot image */
|
||||
iso_msb(wpt + 2, 0x10, 2); /* Permissions: 0x10 = read-only */
|
||||
|
||||
/* 444 - 507 | ========== | Partition table */
|
||||
wpt = buf + 444 + (partition_number - 1) * 8;
|
||||
read_idx = partition_number - 1;
|
||||
if (flag & 1) {
|
||||
/* Search next lower valid partition table entry. #1 is default */
|
||||
for (read_idx = partition_number - 2; read_idx > 0; read_idx--)
|
||||
if (appended_partitions[read_idx] != NULL)
|
||||
if (appended_partitions[read_idx][0] != 0)
|
||||
break;
|
||||
}
|
||||
iso_msb(wpt, partition_offset[read_idx] / (uint32_t) ISO_SUN_CYL_SIZE, 4);
|
||||
iso_msb(wpt + 4, partition_size[read_idx] * 4, 4);
|
||||
|
||||
/* 510 - 511 | checksum | The result of exoring 2-byte words 0 to 254 */
|
||||
buf[510] = buf[511] = 0;
|
||||
for (i = 0; i < 510; i += 2) {
|
||||
buf[510] ^= buf[i];
|
||||
buf[511] ^= buf[i + 1];
|
||||
}
|
||||
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write SUN Disk Label with ISO in partition 1 and unused 2 to 8
|
||||
*/
|
||||
static int make_sun_disk_label(Ecma119Image *t, uint8_t *buf, int flag)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Bytes 512 to 32767 may come from image or external file */
|
||||
memset(buf, 0, 512);
|
||||
|
||||
/* 0 - 127 | label | ASCII Label */
|
||||
if (t->ascii_disc_label[0])
|
||||
strncpy((char *) buf, t->ascii_disc_label, 128);
|
||||
else
|
||||
strcpy((char *) buf,
|
||||
"CD-ROM Disc with Sun sparc boot created by libisofs");
|
||||
|
||||
/* 128 - 131 | 1 | Layout version */
|
||||
iso_msb(buf + 128, 1, 4);
|
||||
|
||||
/* 140 - 141 | 8 | Number of partitions */
|
||||
iso_msb(buf + 140, 8, 2);
|
||||
|
||||
/* 188 - 191 | 0x600ddeee | vtoc sanity */
|
||||
iso_msb(buf + 188, 0x600ddeee, 4);
|
||||
|
||||
/* 420 - 421 | 350 | Rotations per minute */
|
||||
iso_msb(buf + 420, 350, 2);
|
||||
|
||||
/* 422 - 423 | 2048 | Number of physical cylinders (fixely 640 MB) */
|
||||
iso_msb(buf + 422, 2048, 2);
|
||||
|
||||
/* 430 - 431 | 1 | interleave factor */
|
||||
iso_msb(buf + 430, 1, 2);
|
||||
|
||||
/* 432 - 433 | 2048 | Number of data cylinders (fixely 640 MB) */
|
||||
iso_msb(buf + 432, 2048, 2);
|
||||
|
||||
/* 436 - 437 | 1 | Number of heads per cylinder (1 cyl = 320 kB)*/
|
||||
iso_msb(buf + 436, 1, 2);
|
||||
|
||||
/* 438 - 439 | 640 | Number of sectors per head (1 head = 320 kB) */
|
||||
iso_msb(buf + 438, 640, 2);
|
||||
|
||||
/* 508 - 509 | 0xdabe | Magic Number */
|
||||
iso_msb(buf + 508, 0xdabe, 2);
|
||||
|
||||
/* Set partition 1 to describe ISO image and compute checksum */
|
||||
t->appended_part_start[0] = 0;
|
||||
t->appended_part_size[0] = t->curblock;
|
||||
ret = write_sun_partition_entry(1, t->appended_partitions,
|
||||
t->appended_part_start, t->appended_part_size,
|
||||
ISO_SUN_CYL_SIZE, buf, 0);
|
||||
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
|
||||
{
|
||||
int ret, int_img_blocks, sa_type, i, will_append = 0;
|
||||
int first_partition = 1, last_partition = 4;
|
||||
uint32_t img_blocks;
|
||||
|
||||
if ((t == NULL) || (buf == NULL)) {
|
||||
@ -578,7 +698,11 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
|
||||
memset(buf, 0, 16 * BLOCK_SIZE);
|
||||
|
||||
sa_type = (t->system_area_options >> 2) & 0x3f;
|
||||
for (i = 0; i < 4; i++)
|
||||
if (sa_type == 3) {
|
||||
first_partition = 2;
|
||||
last_partition = 8;
|
||||
}
|
||||
for (i = first_partition - 1; i <= last_partition - 1; i++)
|
||||
if (t->appended_partitions[i] != NULL) {
|
||||
will_append = 1;
|
||||
break;
|
||||
@ -648,6 +772,10 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
} else if (sa_type == 3) {
|
||||
ret = make_sun_disk_label(t, buf, 0);
|
||||
if (ret != ISO_SUCCESS)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (t->partition_offset > 0 && sa_type == 0) {
|
||||
@ -661,16 +789,138 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
|
||||
}
|
||||
|
||||
/* This eventually overwrites the partition table entries made so far */
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (i = first_partition - 1; i <= last_partition - 1; i++) {
|
||||
if (t->appended_partitions[i] == NULL)
|
||||
continue;
|
||||
ret = write_mbr_partition_entry(i + 1, t->appended_part_types[i],
|
||||
if (sa_type == 3) {
|
||||
ret = write_sun_partition_entry(i + 1, t->appended_partitions,
|
||||
t->appended_part_start, t->appended_part_size,
|
||||
ISO_SUN_CYL_SIZE,
|
||||
buf, t->appended_partitions[i][0] == 0);
|
||||
} else {
|
||||
ret = write_mbr_partition_entry(i + 1, t->appended_part_types[i],
|
||||
t->appended_part_start[i], t->appended_part_size[i],
|
||||
t->partition_secs_per_head, t->partition_heads_per_cyl,
|
||||
buf, 0);
|
||||
}
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
/* Choose *heads_per_cyl so that
|
||||
- *heads_per_cyl * secs_per_head * 1024 >= imgsize / 512
|
||||
- *heads_per_cyl * secs_per_head is divisible by 4
|
||||
- it is as small as possible (to reduce aligment overhead)
|
||||
- it is <= 255
|
||||
@return 1= success , 0= cannot achieve goals
|
||||
*/
|
||||
static
|
||||
int try_sph(off_t imgsize, int secs_per_head, int *heads_per_cyl, int flag)
|
||||
{
|
||||
off_t hd_blocks, hpc;
|
||||
|
||||
hd_blocks= imgsize / 512;
|
||||
hpc = hd_blocks / secs_per_head / 1024;
|
||||
if (hpc * secs_per_head * 1024 < hd_blocks)
|
||||
hpc++;
|
||||
if ((secs_per_head % 4) == 0) {
|
||||
;
|
||||
} else if ((secs_per_head % 2) == 0) {
|
||||
hpc += (hpc % 2);
|
||||
} else if(hpc % 4) {
|
||||
hpc += 4 - (hpc % 4);
|
||||
}
|
||||
if (hpc > 255)
|
||||
return 0;
|
||||
*heads_per_cyl = hpc;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int iso_align_isohybrid(Ecma119Image *t, int flag)
|
||||
{
|
||||
int sa_type, ret, always_align;
|
||||
uint32_t img_blocks;
|
||||
off_t imgsize, cylsize = 0, frac;
|
||||
char msg[160];
|
||||
|
||||
sa_type = (t->system_area_options >> 2) & 0x3f;
|
||||
if (sa_type != 0)
|
||||
return ISO_SUCCESS;
|
||||
always_align = (t->system_area_options >> 8) & 3;
|
||||
|
||||
img_blocks = t->curblock;
|
||||
imgsize = ((off_t) img_blocks) * (off_t) 2048;
|
||||
if (((t->system_area_options & 3) || always_align)
|
||||
&& (off_t) (t->partition_heads_per_cyl * t->partition_secs_per_head
|
||||
* 1024) * (off_t) 512 < imgsize) {
|
||||
/* Choose small values which can represent the image size */
|
||||
/* First try 32 sectors per head */
|
||||
ret = try_sph(imgsize, 32, &(t->partition_heads_per_cyl), 0);
|
||||
if (ret == 1) {
|
||||
t->partition_secs_per_head = 32;
|
||||
} else {
|
||||
/* Did not work with 32. Try 63 */
|
||||
t->partition_secs_per_head = 63;
|
||||
ret = try_sph(imgsize, 63, &(t->partition_heads_per_cyl), 0);
|
||||
if (ret != 1)
|
||||
t->partition_heads_per_cyl = 255;
|
||||
}
|
||||
cylsize = t->partition_heads_per_cyl * t->partition_secs_per_head *512;
|
||||
frac = imgsize % cylsize;
|
||||
sprintf(msg, "Automatically adjusted MBR geometry to %d/%d/%d",
|
||||
(int) (imgsize / cylsize + !!frac),
|
||||
t->partition_heads_per_cyl, t->partition_secs_per_head);
|
||||
iso_msgs_submit(0, msg, 0, "NOTE", 0);
|
||||
}
|
||||
|
||||
if (always_align >= 2)
|
||||
return ISO_SUCCESS;
|
||||
|
||||
cylsize = 0;
|
||||
if (t->catalog != NULL &&
|
||||
(t->catalog->bootimages[0]->isolinux_options & 0x0a) == 0x02) {
|
||||
/* Check for isolinux image with magic number of 3.72 and produce
|
||||
an MBR from our built-in template. (Deprecated since 31 Mar 2010)
|
||||
*/
|
||||
if (img_blocks >= 0x40000000)
|
||||
return ISO_SUCCESS;
|
||||
cylsize = 64 * 32 * 512;
|
||||
} else if ((t->system_area_options & 2) || always_align) {
|
||||
/* Patch externally provided system area as isohybrid MBR */
|
||||
if (t->catalog == NULL || t->system_area_data == NULL) {
|
||||
/* isohybrid makes only sense together with ISOLINUX boot image
|
||||
and externally provided System Area.
|
||||
*/
|
||||
return ISO_ISOLINUX_CANT_PATCH;
|
||||
}
|
||||
cylsize = t->partition_heads_per_cyl * t->partition_secs_per_head
|
||||
* 512;
|
||||
}
|
||||
if (cylsize == 0)
|
||||
return ISO_SUCCESS;
|
||||
if (((double) imgsize) / (double) cylsize > 1024.0) {
|
||||
iso_msgs_submit(0,
|
||||
"Image size exceeds 1024 cylinders. Cannot align partition.",
|
||||
0, "WARNING", 0);
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
frac = imgsize % cylsize;
|
||||
imgsize += (frac > 0 ? cylsize - frac : 0);
|
||||
|
||||
frac = imgsize - ((off_t) img_blocks) * (off_t) 2048;
|
||||
if (frac == 0)
|
||||
return ISO_SUCCESS;
|
||||
if (frac % 2048) {
|
||||
sprintf(msg,
|
||||
"Cylinder size %d not divisible by 2048. Cannot align partition.",
|
||||
(int) cylsize);
|
||||
iso_msgs_submit(0, msg, 0, "WARNING", 0);
|
||||
} else {
|
||||
t->tail_blocks += frac / 2048;
|
||||
}
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
@ -46,6 +46,11 @@ int make_isohybrid_mbr(int bin_lba, int *img_blocks, char *mbr, int flag);
|
||||
*/
|
||||
int iso_write_system_area(Ecma119Image *t, uint8_t *buf);
|
||||
|
||||
/**
|
||||
* Adjust t->tail_blocks to the eventual alignment needs of isohybrid booting.
|
||||
*/
|
||||
int iso_align_isohybrid(Ecma119Image *t, int flag);
|
||||
|
||||
|
||||
/**
|
||||
* Read the necessary ELF information from the first MIPS boot file.
|
||||
|
213
libisofs/tree.c
213
libisofs/tree.c
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2011 Thomas Schmitt
|
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
@ -31,11 +32,6 @@
|
||||
#include <fnmatch.h>
|
||||
|
||||
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX Libisofs_default_path_maX
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Add a new directory to the iso tree.
|
||||
*
|
||||
@ -979,17 +975,214 @@ char *iso_tree_get_node_path(IsoNode *node)
|
||||
if ((IsoNode*)node->parent == node) {
|
||||
return strdup("/");
|
||||
} else {
|
||||
char path[PATH_MAX];
|
||||
char *parent_path = iso_tree_get_node_path((IsoNode*)node->parent);
|
||||
char *path = NULL, *parent_path;
|
||||
parent_path = iso_tree_get_node_path((IsoNode*)node->parent);
|
||||
if (parent_path == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (strlen(parent_path) == 1) {
|
||||
snprintf(path, PATH_MAX, "/%s", node->name);
|
||||
path = calloc(1, strlen(node->name) + 2);
|
||||
if (path == NULL)
|
||||
return NULL;
|
||||
sprintf(path, "/%s", node->name);
|
||||
} else {
|
||||
snprintf(path, PATH_MAX, "%s/%s", parent_path, node->name);
|
||||
path = calloc(1, strlen(parent_path) + strlen(node->name) + 2);
|
||||
if (path == NULL)
|
||||
return NULL;
|
||||
sprintf(path, "%s/%s", parent_path, node->name);
|
||||
}
|
||||
free(parent_path);
|
||||
return strdup(path);
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------- tree cloning ------------------------------ */
|
||||
|
||||
static
|
||||
int iso_tree_copy_node_attr(IsoNode *old_node, IsoNode *new_node, int flag)
|
||||
{
|
||||
int ret;
|
||||
|
||||
new_node->mode = old_node->mode;
|
||||
new_node->uid = old_node->uid;
|
||||
new_node->gid = old_node->gid;
|
||||
new_node->atime = old_node->atime;
|
||||
new_node->mtime = old_node->mtime;
|
||||
new_node->ctime = old_node->ctime;
|
||||
new_node->hidden = old_node->hidden;
|
||||
ret = iso_node_clone_xinfo(old_node, new_node, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
@param flag bit0= merge directory with *new_node
|
||||
*/
|
||||
static
|
||||
int iso_tree_clone_dir(IsoDir *old_dir,
|
||||
IsoDir *new_parent, char *new_name, IsoNode **new_node,
|
||||
int flag)
|
||||
{
|
||||
IsoDir *new_dir = NULL;
|
||||
IsoNode *sub_node = NULL, *new_sub_node = NULL;
|
||||
IsoDirIter *iter = NULL;
|
||||
int ret;
|
||||
|
||||
if (flag & 1) {
|
||||
new_dir = (IsoDir *) *new_node;
|
||||
} else {
|
||||
*new_node = NULL;
|
||||
ret = iso_tree_add_new_dir(new_parent, new_name, &new_dir);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
/* Avoid traversal of target directory to allow cloning of old_dir to a
|
||||
subordinate of old_dir.
|
||||
*/
|
||||
iso_node_take((IsoNode *) new_dir);
|
||||
|
||||
ret = iso_dir_get_children(old_dir, &iter);
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
while(1) {
|
||||
ret = iso_dir_iter_next(iter, &sub_node);
|
||||
if (ret == 0)
|
||||
break;
|
||||
ret = iso_tree_clone(sub_node, new_dir, sub_node->name, &new_sub_node,
|
||||
flag & 1);
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
}
|
||||
|
||||
/* Now graft in the new tree resp. graft back the merged tree */
|
||||
ret = iso_dir_add_node(new_parent, (IsoNode *) new_dir, 0);
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
|
||||
if (!(flag & 1))
|
||||
*new_node = (IsoNode *) new_dir;
|
||||
ret = ISO_SUCCESS;
|
||||
ex:;
|
||||
if (iter != NULL)
|
||||
iso_dir_iter_free(iter);
|
||||
if (ret < 0 && new_dir != NULL) {
|
||||
if (flag & 1) {
|
||||
/* graft back the merged tree (eventually with half copy) */
|
||||
iso_dir_add_node(new_parent, (IsoNode *) new_dir, 0);
|
||||
} else {
|
||||
iso_node_remove_tree((IsoNode *) new_dir, NULL);
|
||||
*new_node = NULL;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static
|
||||
int iso_tree_clone_file(IsoFile *old_file,
|
||||
IsoDir *new_parent, char *new_name, IsoNode **new_node,
|
||||
int flag)
|
||||
{
|
||||
IsoStream *new_stream = NULL;
|
||||
IsoFile *new_file = NULL;
|
||||
int ret;
|
||||
|
||||
*new_node = NULL;
|
||||
|
||||
ret = iso_stream_clone(old_file->stream, &new_stream, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = iso_tree_add_new_file(new_parent, new_name, new_stream, &new_file);
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
new_stream = NULL; /* now owned by new_file */
|
||||
new_file->sort_weight = old_file->sort_weight;
|
||||
*new_node = (IsoNode *) new_file;
|
||||
ret = ISO_SUCCESS;
|
||||
ex:;
|
||||
if (new_stream != NULL)
|
||||
iso_stream_unref(new_stream);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static
|
||||
int iso_tree_clone_symlink(IsoSymlink *node,
|
||||
IsoDir *new_parent, char *new_name, IsoNode **new_node,
|
||||
int flag)
|
||||
{
|
||||
IsoSymlink *new_sym;
|
||||
int ret;
|
||||
|
||||
*new_node = NULL;
|
||||
|
||||
ret = iso_tree_add_new_symlink(new_parent, new_name, node->dest, &new_sym);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
new_sym->fs_id = node->fs_id;
|
||||
new_sym->st_dev = node->st_dev;
|
||||
new_sym->st_ino = node->st_ino;
|
||||
*new_node = (IsoNode *) new_sym;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
static
|
||||
int iso_tree_clone_special(IsoSpecial *node,
|
||||
IsoDir *new_parent, char *new_name, IsoNode **new_node,
|
||||
int flag)
|
||||
{
|
||||
IsoSpecial *new_spec;
|
||||
IsoNode *iso_node;
|
||||
int ret;
|
||||
|
||||
iso_node = (IsoNode *) node;
|
||||
ret = iso_tree_add_new_special(new_parent, new_name, iso_node->mode,
|
||||
node->dev, &new_spec);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
new_spec->fs_id = node->fs_id;
|
||||
new_spec->st_dev = node->st_dev;
|
||||
new_spec->st_ino = node->st_ino;
|
||||
*new_node = (IsoNode *) new_spec;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
/* API */
|
||||
int iso_tree_clone(IsoNode *node,
|
||||
IsoDir *new_parent, char *new_name, IsoNode **new_node,
|
||||
int flag)
|
||||
{
|
||||
int ret = ISO_SUCCESS;
|
||||
|
||||
if (iso_dir_get_node(new_parent, new_name, new_node) == 1) {
|
||||
if (! (node->type == LIBISO_DIR && (*new_node)->type == LIBISO_DIR &&
|
||||
(flag & 1))) {
|
||||
*new_node = NULL;
|
||||
return ISO_NODE_NAME_NOT_UNIQUE;
|
||||
}
|
||||
} else
|
||||
flag &= ~1;
|
||||
|
||||
if (node->type == LIBISO_DIR) {
|
||||
ret = iso_tree_clone_dir((IsoDir *) node, new_parent, new_name,
|
||||
new_node, flag & 1);
|
||||
} else if (node->type == LIBISO_FILE) {
|
||||
ret = iso_tree_clone_file((IsoFile *) node, new_parent, new_name,
|
||||
new_node, 0);
|
||||
} else if (node->type == LIBISO_SYMLINK) {
|
||||
ret = iso_tree_clone_symlink((IsoSymlink *) node, new_parent, new_name,
|
||||
new_node, 0);
|
||||
} else if (node->type == LIBISO_SPECIAL) {
|
||||
ret = iso_tree_clone_special((IsoSpecial *) node, new_parent, new_name,
|
||||
new_node, 0);
|
||||
} else if (node->type == LIBISO_BOOT) {
|
||||
ret = ISO_SUCCESS; /* API says they are silently ignored */
|
||||
}
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (flag & 1)
|
||||
return 2; /* merged two directories, *new_node is not new */
|
||||
ret = iso_tree_copy_node_attr(node, *new_node, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
173
libisofs/util.c
173
libisofs/util.c
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2007 Mario Danic
|
||||
* Copyright (c) 2009 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2011 Thomas Schmitt
|
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
@ -16,6 +16,7 @@
|
||||
#include "util.h"
|
||||
#include "libisofs.h"
|
||||
#include "messages.h"
|
||||
#include "joliet.h"
|
||||
#include "../version.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
@ -773,6 +774,8 @@ char *iso_r_dirid(const char *src, int size, int relaxed)
|
||||
len = size;
|
||||
}
|
||||
dest = malloc(len + 1);
|
||||
if (dest == NULL)
|
||||
return NULL;
|
||||
for (i = 0; i < len; i++) {
|
||||
char c= src[i];
|
||||
if (relaxed == 2) {
|
||||
@ -914,16 +917,20 @@ ex:;
|
||||
|
||||
/*
|
||||
bit0= no_force_dots
|
||||
bit1= allow 103 characters rather than 64
|
||||
*/
|
||||
uint16_t *iso_j_file_id(const uint16_t *src, int flag)
|
||||
{
|
||||
uint16_t *dot;
|
||||
size_t lname, lext, lnname, lnext, pos, i;
|
||||
uint16_t dest[66]; /* 66 = 64 (name + ext) + 1 (.) + 1 (\0) */
|
||||
size_t lname, lext, lnname, lnext, pos, i, maxchar = 64;
|
||||
uint16_t dest[LIBISO_JOLIET_NAME_MAX];
|
||||
/* was: 66 = 64 (name + ext) + 1 (.) + 1 (\0) */
|
||||
|
||||
if (src == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (flag & 2)
|
||||
maxchar = 103;
|
||||
|
||||
dot = ucsrchr(src, '.');
|
||||
|
||||
@ -935,14 +942,15 @@ uint16_t *iso_j_file_id(const uint16_t *src, int flag)
|
||||
*/
|
||||
if (dot == NULL || cmp_ucsbe(dot + 1, '\0') == 0) {
|
||||
lname = ucslen(src);
|
||||
lnname = (lname > 64) ? 64 : lname;
|
||||
lnname = (lname > maxchar) ? maxchar : lname;
|
||||
lext = lnext = 0;
|
||||
} else {
|
||||
lext = ucslen(dot + 1);
|
||||
lname = ucslen(src) - lext - 1;
|
||||
lnext = (ucslen(src) > 65 && lext > 3) ? (lname < 61 ? 64 - lname : 3)
|
||||
lnext = (ucslen(src) > maxchar + 1 && lext > 3)
|
||||
? (lname < maxchar - 3 ? maxchar - lname : 3)
|
||||
: lext;
|
||||
lnname = (ucslen(src) > 65) ? 64 - lnext : lname;
|
||||
lnname = (ucslen(src) > maxchar + 1) ? maxchar - lnext : lname;
|
||||
}
|
||||
|
||||
if (lnname == 0 && lnext == 0) {
|
||||
@ -984,18 +992,22 @@ is_done:;
|
||||
return ucsdup(dest);
|
||||
}
|
||||
|
||||
uint16_t *iso_j_dir_id(const uint16_t *src)
|
||||
/* @param flag bit1= allow 103 characters rather than 64
|
||||
*/
|
||||
uint16_t *iso_j_dir_id(const uint16_t *src, int flag)
|
||||
{
|
||||
size_t len, i;
|
||||
uint16_t dest[65]; /* 65 = 64 + 1 (\0) */
|
||||
size_t len, i, maxchar = 64;
|
||||
uint16_t dest[LIBISO_JOLIET_NAME_MAX]; /* was: 65 = 64 + 1 (\0) */
|
||||
|
||||
if (src == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (flag & 2)
|
||||
maxchar = 103;
|
||||
|
||||
len = ucslen(src);
|
||||
if (len > 64) {
|
||||
len = 64;
|
||||
if (len > maxchar) {
|
||||
len = maxchar;
|
||||
}
|
||||
for (i = 0; i < len; i++) {
|
||||
uint16_t c = src[i];
|
||||
@ -1036,6 +1048,8 @@ uint16_t *ucsdup(const uint16_t *str)
|
||||
size_t len = ucslen(str);
|
||||
|
||||
ret = malloc(2 * (len + 1));
|
||||
if (ret == NULL)
|
||||
return NULL;
|
||||
if (ret != NULL) {
|
||||
memcpy(ret, str, 2 * (len + 1));
|
||||
}
|
||||
@ -1294,12 +1308,41 @@ void iso_datetime_17(unsigned char *buf, time_t t, int always_gmt)
|
||||
}
|
||||
|
||||
#ifndef HAVE_TIMEGM
|
||||
|
||||
/* putenv is SVr4, POSIX.1-2001, 4.3BSD , setenv is 4.3BSD, POSIX.1-2001.
|
||||
So putenv is more widely available.
|
||||
Also, setenv spoils eventual putenv expectation of applications because
|
||||
putenv installs the original string which then may be altered from
|
||||
its owner. setenv installs a copy that may not be altered.
|
||||
Both are slow.
|
||||
Thus first try with a naive implementation that assumes no leap seconds.
|
||||
If it fails a test with gmtime() then use the slow function with mktime().
|
||||
*/
|
||||
#define Libisofs_use_putenV yes
|
||||
|
||||
static
|
||||
time_t timegm(struct tm *tm)
|
||||
time_t env_timegm(struct tm *tm)
|
||||
{
|
||||
time_t ret;
|
||||
char *tz;
|
||||
|
||||
#ifdef Libisofs_use_putenV
|
||||
|
||||
static char unset_name[] = {"TZ"};
|
||||
|
||||
tz = getenv("TZ");
|
||||
putenv("TZ=");
|
||||
tzset();
|
||||
ret = mktime(tm);
|
||||
if (tz != NULL) {
|
||||
/* tz is a pointer to the value part in a string of form "TZ="value */
|
||||
putenv(tz - 3);
|
||||
} else
|
||||
putenv(unset_name); /* not daring to submit constant */
|
||||
tzset();
|
||||
|
||||
#else /* Libisofs_use_putenV */
|
||||
|
||||
tz = getenv("TZ");
|
||||
setenv("TZ", "", 1);
|
||||
tzset();
|
||||
@ -1309,9 +1352,92 @@ time_t timegm(struct tm *tm)
|
||||
else
|
||||
unsetenv("TZ");
|
||||
tzset();
|
||||
|
||||
#endif /* ! Libisofs_use_putenV */
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static
|
||||
int ts_is_leapyear(int tm_year) /* years since 1900 */
|
||||
{
|
||||
return ((tm_year % 4) == 0 && ((tm_year % 100) != 0 ||
|
||||
(tm_year % 400) == 100));
|
||||
}
|
||||
|
||||
/* Fast implementation without leap seconds.
|
||||
Inspired by but not copied from code by Kungliga Tekniska Hgskolan
|
||||
(Royal Institute of Technology, Stockholm, Sweden),
|
||||
which was modified by Andrew Tridgell for Samba4.
|
||||
I claim own copyright 2011 Thomas Schmitt <scdbackup@gmx.net>.
|
||||
*/
|
||||
static
|
||||
time_t ts_timegm(struct tm *tm)
|
||||
{
|
||||
time_t ret;
|
||||
static int month_length_normal[12] =
|
||||
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
|
||||
static int month_length_leap[12] =
|
||||
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
|
||||
int *month_length_pt;
|
||||
int years, i;
|
||||
|
||||
ret = 0;
|
||||
|
||||
years = tm->tm_year - 70; /* Years since 1970 */
|
||||
if (years < 0)
|
||||
return ret;
|
||||
for (i = 0; i < years; i++) {
|
||||
ret += 365 * 86400;
|
||||
if (ts_is_leapyear(70 + i))
|
||||
ret += 86400;
|
||||
}
|
||||
if (ts_is_leapyear(tm->tm_year))
|
||||
month_length_pt = month_length_leap;
|
||||
else
|
||||
month_length_pt = month_length_normal;
|
||||
for (i = 0; i < tm->tm_mon; i++)
|
||||
ret += month_length_pt[i] * 86400;
|
||||
ret += (tm->tm_mday - 1) * 86400;
|
||||
ret += tm->tm_hour * 3600;
|
||||
ret += tm->tm_min * 60;
|
||||
ret += tm->tm_sec;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static
|
||||
time_t timegm(struct tm *tm)
|
||||
{
|
||||
time_t raw_t, ret;
|
||||
struct tm *test_tm, input_tm_copy;
|
||||
|
||||
/* Beware of ill effects if tm is result of gmtime() or alike */
|
||||
memcpy(&input_tm_copy, tm, sizeof(struct tm));
|
||||
|
||||
/* Try without leapseconds (which are rarely implemented, as it seems) */
|
||||
raw_t = ts_timegm(tm);
|
||||
if (raw_t == 0)
|
||||
return raw_t;
|
||||
|
||||
/* Check whether this translates back to the input values */
|
||||
test_tm = gmtime(&raw_t);
|
||||
if (input_tm_copy.tm_sec == test_tm->tm_sec &&
|
||||
input_tm_copy.tm_min == test_tm->tm_min &&
|
||||
input_tm_copy.tm_hour == test_tm->tm_hour &&
|
||||
input_tm_copy.tm_mday == test_tm->tm_mday &&
|
||||
input_tm_copy.tm_mon == test_tm->tm_mon &&
|
||||
input_tm_copy.tm_year == test_tm->tm_year) {
|
||||
ret = raw_t;
|
||||
} else {
|
||||
/* Mismatch. Use slow method around mktime() */
|
||||
ret = env_timegm(&input_tm_copy);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#endif /* ! HAVE_TIMEGM */
|
||||
|
||||
|
||||
time_t iso_datetime_read_7(const uint8_t *buf)
|
||||
{
|
||||
@ -1323,6 +1449,7 @@ time_t iso_datetime_read_7(const uint8_t *buf)
|
||||
tm.tm_hour = buf[3];
|
||||
tm.tm_min = buf[4];
|
||||
tm.tm_sec = buf[5];
|
||||
|
||||
return timegm(&tm) - ((int8_t)buf[6]) * 60 * 15;
|
||||
}
|
||||
|
||||
@ -1460,6 +1587,8 @@ char *ucs2str(const char *buf, size_t len)
|
||||
|
||||
/* ensure enought space */
|
||||
out = calloc(outbytes, 1);
|
||||
if (out == NULL)
|
||||
return NULL;
|
||||
|
||||
/* convert to local charset */
|
||||
conv_ret = iso_iconv_open(&conv, iso_get_local_charset(0), "UCS-2BE", 0);
|
||||
@ -1721,10 +1850,24 @@ unexpected_type:;
|
||||
iso_msg_submit(-1, ISO_MD5_TAG_UNEXPECTED, 0, NULL);
|
||||
ret = 0;
|
||||
goto ex;
|
||||
} else if(pos != lba) {
|
||||
} else if (pos != lba) {
|
||||
if (*tag_type == 2) { /* Superblock tag */
|
||||
if (lba < 32) {
|
||||
/* Check whether this is a copied superblock */
|
||||
range_start -= (off_t) pos - (off_t) lba;
|
||||
if (range_start != ctx_start_lba) {
|
||||
|
||||
/* >>> check for matching MD5 ? */;
|
||||
|
||||
ret = ISO_MD5_TAG_MISPLACED;
|
||||
} else
|
||||
ret = ISO_MD5_TAG_COPIED;
|
||||
goto ex;
|
||||
}
|
||||
}
|
||||
ret = ISO_MD5_TAG_MISPLACED;
|
||||
goto ex;
|
||||
} else if(range_start != ctx_start_lba) {
|
||||
} else if (range_start != ctx_start_lba) {
|
||||
ret = ISO_MD5_TAG_MISPLACED;
|
||||
}
|
||||
ret = iso_md5_clone(ctx, &cloned_ctx);
|
||||
|
@ -11,7 +11,14 @@
|
||||
#ifndef LIBISO_UTIL_H_
|
||||
#define LIBISO_UTIL_H_
|
||||
|
||||
#ifdef HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#else
|
||||
#ifdef HAVE_INTTYPES_H
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#ifndef MAX
|
||||
@ -146,13 +153,15 @@ char *iso_r_fileid(const char *src, size_t len, int relaxed, int forcedot);
|
||||
|
||||
/**
|
||||
* Create a Joliet file identifier that consists of name and extension. The
|
||||
* combined name and extension length will not exceed 128 bytes, and the
|
||||
* name and extension will be separated (.). All characters consist of
|
||||
* 2 bytes and the resulting string is NULL-terminated by a 2-byte NULL.
|
||||
* combined name and extension length will normally not exceed 64 characters
|
||||
* (= 128 bytes). The name and the extension will be separated (.).
|
||||
* All characters consist of 2 bytes and the resulting string is
|
||||
* NULL-terminated by a 2-byte NULL.
|
||||
*
|
||||
* Note that version number and (;1) is not appended.
|
||||
* @param flag
|
||||
* bit0= no_force_dots
|
||||
* bit1= allow 103 characters rather than 64
|
||||
* @return
|
||||
* NULL if the original name and extension both are of length 0.
|
||||
*/
|
||||
@ -164,10 +173,12 @@ uint16_t *iso_j_file_id(const uint16_t *src, int flag);
|
||||
* and the name and extension will be separated (.). All characters consist of
|
||||
* 2 bytes and the resulting string is NULL-terminated by a 2-byte NULL.
|
||||
*
|
||||
* @param flag
|
||||
* bit1= allow 103 characters rather than 64
|
||||
* @return
|
||||
* NULL if the original name and extension both are of length 0.
|
||||
*/
|
||||
uint16_t *iso_j_dir_id(const uint16_t *src);
|
||||
uint16_t *iso_j_dir_id(const uint16_t *src, int flag);
|
||||
|
||||
/**
|
||||
* Like strlen, but for Joliet strings.
|
||||
@ -505,12 +516,26 @@ int iso_util_tag_magic(int tag_type, char **tag_magic, int *len, int flag);
|
||||
*/
|
||||
int checksum_cx_xinfo_func(void *data, int flag);
|
||||
|
||||
/* The iso_node_xinfo_cloner function which gets associated to
|
||||
* checksum_cx_xinfo_func by iso_init() resp. iso_init_with_flag() via
|
||||
* iso_node_xinfo_make_clonable()
|
||||
*/
|
||||
int checksum_cx_xinfo_cloner(void *old_data, void **new_data, int flag);
|
||||
|
||||
|
||||
/* Function to identify and manage md5 sums of unspecified providence stored
|
||||
* directly in this xinfo. This is supposed to override any other recorded
|
||||
* MD5 of the node unless data get copied and checksummed during that copying.
|
||||
*/
|
||||
int checksum_md5_xinfo_func(void *data, int flag);
|
||||
|
||||
/* The iso_node_xinfo_cloner function which gets associated to
|
||||
* checksum_md5_xinfo_func by iso_init() resp. iso_init_with_flag() via
|
||||
* iso_node_xinfo_make_clonable()
|
||||
*/
|
||||
int checksum_md5_xinfo_cloner(void *old_data, void **new_data, int flag);
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user