Compare commits
114 Commits
release-1.
...
release-1.
Author | SHA1 | Date | |
---|---|---|---|
4a79812d15 | |||
9b2f97e4b7 | |||
35cfb756be | |||
2835fccfa4 | |||
31c7f68990 | |||
4e0ca258de | |||
9653854462 | |||
6e95f8bbcb | |||
ce3aa0d5c7 | |||
d5bfc552c4 | |||
bad54a5967 | |||
49b0a89bfe | |||
265df5fbe3 | |||
f089bcf66a | |||
062e5f0bf0 | |||
d932bfcdea | |||
3ef67cb49d | |||
f08ae22dbe | |||
45d316d1ca | |||
4d8fc6ffee | |||
023e413624 | |||
d361186bca | |||
e7d9559d16 | |||
94eecbb123 | |||
777f74ea0b | |||
2b8d47ddd8 | |||
e839b7b368 | |||
1334027a83 | |||
8d3a0a6a9e | |||
7b7ea41f12 | |||
bb5886094e | |||
b076ce9b44 | |||
05f26898f3 | |||
a698f0ee22 | |||
e69854b35f | |||
228995c148 | |||
071e14f9b0 | |||
b08d6271ab | |||
431d31fff6 | |||
a37571c6c5 | |||
6e98006640 | |||
d264e818c3 | |||
d0f740facf | |||
944b5a6152 | |||
b51232fef4 | |||
99f037e210 | |||
c794a48a06 | |||
47d599e8c3 | |||
0a87e838df | |||
e945e38add | |||
6d68abc707 | |||
e80dd0735b | |||
c276681735 | |||
1d723f0834 | |||
1a4b2a2584 | |||
4eb2a7199c | |||
6d5e68fd01 | |||
fed8b23017 | |||
e3329a98a9 | |||
49efbdad76 | |||
9538a5d57b | |||
66dc6c2d0e | |||
81608815ae | |||
ae5ab4a08f | |||
76b6737570 | |||
9210a57500 | |||
8a752b50fa | |||
c38b1a3a3a | |||
73c9c7f244 | |||
0b9f03bb23 | |||
d1c3a017e3 | |||
b200feceed | |||
7958b2ea22 | |||
c0bdf4d3b5 | |||
71efc996e3 | |||
61383dea2d | |||
270cd1cad5 | |||
559e9b564d | |||
d8a56f60ef | |||
10e3b2939a | |||
ba67523278 | |||
f09964cf51 | |||
e4a70a823d | |||
655d86b97a | |||
f2f780115b | |||
b6be8457f7 | |||
1238c19494 | |||
2caf527f67 | |||
43eae7502b | |||
e035146e01 | |||
de3e21629f | |||
d79a3fcec4 | |||
de079cec42 | |||
b33d06eb0c | |||
dfdaa2902a | |||
0173c51c23 | |||
a118127e9c | |||
1f24b39879 | |||
16863755be | |||
b25ac0f52d | |||
5c59295e72 | |||
85893bf58b | |||
722327e4b8 | |||
ab0a981814 | |||
38483d894e | |||
1082e628d1 | |||
74c68224c7 | |||
200697898d | |||
a3eeda3d23 | |||
92073c45ef | |||
81cded618d | |||
84c0bd37ff | |||
4e60feaeab | |||
d6e150a10e |
@ -1,7 +1,7 @@
|
|||||||
Vreixo Formoso <metalpain2002@yahoo.es>,
|
Vreixo Formoso <metalpain2002@yahoo.es>,
|
||||||
Mario Danic <mario.danic@gmail.com>,
|
Mario Danic <mario.danic@gmail.com>,
|
||||||
Thomas Schmitt <scdbackup@gmx.net>
|
Thomas Schmitt <scdbackup@gmx.net>
|
||||||
Copyright (C) 2007-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
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
48
ChangeLog
48
ChangeLog
@ -1,6 +1,50 @@
|
|||||||
bzr branch lp:libisofs/for-libisoburn (to become libisofs-1.0.2.tar.gz)
|
|
||||||
|
libisofs-1.1.0.tar.gz Sat Jun 18 2011
|
||||||
===============================================================================
|
===============================================================================
|
||||||
- no novelties yet
|
* Bug fix: Padding as of iso_write_opts_set_tail_blocks() was added only
|
||||||
|
after cylinder alignment as of iso_write_opts_set_system_area()
|
||||||
|
and thus spoiled this alignment.
|
||||||
|
|
||||||
|
libisofs-1.0.8.tar.gz Thu May 12 2011
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: iso_write_opts_set_system_area() with system area types
|
||||||
|
1=MIPS Big Endian and 2=MIPS Little Endian caused SIGSEGV.
|
||||||
|
* Bug fix: SIGSEGV if the path given by iso_image_add_mips_boot_file()
|
||||||
|
does not exist in the image at image production time.
|
||||||
|
* Bug fix: While loading an ISO image: Several reads to malloc
|
||||||
|
memory occured with byte index -1. (Found by Valgrind after
|
||||||
|
years of operation without visible problems.)
|
||||||
|
* Bug fix: Closed a memory leak of 32 kB per loaded ISO image.
|
||||||
|
|
||||||
|
libisofs-1.0.6.tar.gz Sat Apr 09 2011
|
||||||
|
===============================================================================
|
||||||
|
* New API call iso_write_opts_set_joliet_long_names()
|
||||||
|
* New error codes for oversized file addresses
|
||||||
|
|
||||||
|
libisofs-1.0.4.tar.gz Thu Mar 10 2011
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: Compilation failed if --disable-zlib was configured
|
||||||
|
* Bug fix: isohybrid image size was not aligned to cylinder boundary.
|
||||||
|
* New no_md5 value 2 for API call iso_read_opts_set_no_md5()
|
||||||
|
* New option bits 8 and 9 with iso_write_opts_set_system_area()
|
||||||
|
|
||||||
|
libisofs-1.0.2.tar.gz Tue Feb 23 2011
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: iso_write_opts_set_aaip(opts, 1) could cause fatal miscalculation
|
||||||
|
of the root directory size. This eventually truncated directory
|
||||||
|
tree and spoiled all data file content.
|
||||||
|
* Bug fix: Volume Descriptor Set Terminator contained non-zero bytes in
|
||||||
|
the reserved field (ECMA-119 8.3.4). The bytes stem from the
|
||||||
|
previously written Volume Descriptor.
|
||||||
|
* New API calls iso_tree_clone(), iso_stream_clone.
|
||||||
|
* New IsoFileSourceIface version 2 with method clone_src().
|
||||||
|
* New IsoStreamIface version 4 with method clone_stream().
|
||||||
|
* New public function prototype iso_node_xinfo_cloner.
|
||||||
|
* New API calls iso_node_xinfo_make_clonable(), iso_node_xinfo_get_cloner().
|
||||||
|
* New public iso_node_xinfo_cloner instance aaip_xinfo_cloner().
|
||||||
|
* New API calls iso_node_get_next_xinfo(), iso_node_remove_all_xinfo().
|
||||||
|
* New API call iso_node_remove_tree().
|
||||||
|
* New API call iso_write_opts_set_old_empty().
|
||||||
|
|
||||||
libisofs-1.0.0.tar.gz Mon Jan 17 2011
|
libisofs-1.0.0.tar.gz Mon Jan 17 2011
|
||||||
===============================================================================
|
===============================================================================
|
||||||
|
@ -6,6 +6,7 @@ pkgconfigdir=$(LIBBURNIA_PKGCONFDIR)
|
|||||||
libincludedir=$(includedir)/libisofs
|
libincludedir=$(includedir)/libisofs
|
||||||
|
|
||||||
lib_LTLIBRARIES = libisofs/libisofs.la
|
lib_LTLIBRARIES = libisofs/libisofs.la
|
||||||
|
ACLOCAL_AMFLAGS = -I ./
|
||||||
|
|
||||||
## ========================================================================= ##
|
## ========================================================================= ##
|
||||||
|
|
||||||
|
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-libacl avoid use of ACL functions like acl_to_text()
|
||||||
--disable-xattr avoid use of xattr functions like listxattr()
|
--disable-xattr avoid use of xattr functions like listxattr()
|
||||||
--disable-zlib avoid use of zlib functions like compress2()
|
--disable-zlib avoid use of zlib functions like compress2()
|
||||||
|
--disable-libjte avoid use of libjte functions
|
||||||
|
|
||||||
See INSTALL file for general options of ./configure.
|
See INSTALL file for general options of ./configure.
|
||||||
|
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
#!/bin/sh -x
|
#!/bin/sh -x
|
||||||
|
|
||||||
aclocal
|
aclocal -I .
|
||||||
libtoolize --copy --force
|
libtoolize --copy --force
|
||||||
autoconf
|
autoconf
|
||||||
|
|
||||||
# ts A61101 : libburn is not prepared for config.h
|
|
||||||
# autoheader
|
|
||||||
|
|
||||||
automake --foreign --add-missing --copy --include-deps
|
automake --foreign --add-missing --copy --include-deps
|
||||||
|
15
configure.ac
15
configure.ac
@ -1,4 +1,4 @@
|
|||||||
AC_INIT([libisofs], [1.0.0], [http://libburnia-project.org])
|
AC_INIT([libisofs], [1.1.0], [http://libburnia-project.org])
|
||||||
AC_PREREQ([2.50])
|
AC_PREREQ([2.50])
|
||||||
dnl AC_CONFIG_HEADER([config.h])
|
dnl AC_CONFIG_HEADER([config.h])
|
||||||
|
|
||||||
@ -8,6 +8,7 @@ AC_CANONICAL_TARGET
|
|||||||
LIBBURNIA_SET_FLAGS
|
LIBBURNIA_SET_FLAGS
|
||||||
|
|
||||||
AM_INIT_AUTOMAKE([subdir-objects])
|
AM_INIT_AUTOMAKE([subdir-objects])
|
||||||
|
AC_CONFIG_MACRO_DIR([./])
|
||||||
|
|
||||||
dnl
|
dnl
|
||||||
dnl if MAJOR or MINOR version changes, be sure to change AC_INIT above to match
|
dnl if MAJOR or MINOR version changes, be sure to change AC_INIT above to match
|
||||||
@ -39,7 +40,7 @@ dnl
|
|||||||
dnl If LIBISOFS_*_VERSION changes, be sure to change AC_INIT above to match.
|
dnl If LIBISOFS_*_VERSION changes, be sure to change AC_INIT above to match.
|
||||||
dnl
|
dnl
|
||||||
LIBISOFS_MAJOR_VERSION=1
|
LIBISOFS_MAJOR_VERSION=1
|
||||||
LIBISOFS_MINOR_VERSION=0
|
LIBISOFS_MINOR_VERSION=1
|
||||||
LIBISOFS_MICRO_VERSION=0
|
LIBISOFS_MICRO_VERSION=0
|
||||||
LIBISOFS_VERSION=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION.$LIBISOFS_MICRO_VERSION
|
LIBISOFS_VERSION=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION.$LIBISOFS_MICRO_VERSION
|
||||||
|
|
||||||
@ -50,10 +51,10 @@ AC_SUBST(LIBISOFS_VERSION)
|
|||||||
|
|
||||||
dnl Libtool versioning
|
dnl Libtool versioning
|
||||||
LT_RELEASE=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION
|
LT_RELEASE=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION
|
||||||
# 2011.01.16 development jump has not yet happened
|
# 2011.06.18 development jump has not yet happened
|
||||||
# SONAME = 44 - 38 = 6 . Library name = libisofs.6.38.0
|
# SONAME = 54 - 48 = 6 . Library name = libisofs.6.48.0
|
||||||
LT_CURRENT=44
|
LT_CURRENT=54
|
||||||
LT_AGE=38
|
LT_AGE=48
|
||||||
LT_REVISION=0
|
LT_REVISION=0
|
||||||
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
|
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
|
||||||
|
|
||||||
@ -139,7 +140,7 @@ if test x$enable_debug != xyes; then
|
|||||||
CFLAGS="-DNDEBUG $CFLAGS"
|
CFLAGS="-DNDEBUG $CFLAGS"
|
||||||
else
|
else
|
||||||
if test x$GCC = xyes; then
|
if test x$GCC = xyes; then
|
||||||
CFLAGS="-g -pedantic -Wall $CFLAGS"
|
CFLAGS="-g -pedantic -Wall -Wextra -Wno-unused-parameter $CFLAGS"
|
||||||
fi
|
fi
|
||||||
CFLAGS="-DDEBUG $CFLAGS"
|
CFLAGS="-DDEBUG $CFLAGS"
|
||||||
fi
|
fi
|
||||||
|
27
demo/demo.c
27
demo/demo.c
@ -50,6 +50,7 @@ static char helptext[][80] = {
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
|
||||||
#ifndef PATH_MAX
|
#ifndef PATH_MAX
|
||||||
@ -372,7 +373,11 @@ int gesture_iso(int argc, char **argv)
|
|||||||
iso_write_opts_free(opts);
|
iso_write_opts_free(opts);
|
||||||
|
|
||||||
while (burn_src->read_xt(burn_src, buf, 2048) == 2048) {
|
while (burn_src->read_xt(burn_src, buf, 2048) == 2048) {
|
||||||
fwrite(buf, 1, 2048, fp);
|
result = fwrite(buf, 1, 2048, fp);
|
||||||
|
if (result < 2048) {
|
||||||
|
printf ("Cannot write block. errno= %d\n", errno);
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
burn_src->free_data(burn_src);
|
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 gesture_iso_cat(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int res;
|
int res, write_ret;
|
||||||
IsoFilesystem *fs;
|
IsoFilesystem *fs;
|
||||||
IsoFileSource *file;
|
IsoFileSource *file;
|
||||||
struct stat info;
|
struct stat info;
|
||||||
@ -596,7 +601,11 @@ int gesture_iso_cat(int argc, char **argv)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
while ((res = iso_file_source_read(file, buf, 1024)) > 0) {
|
while ((res = iso_file_source_read(file, buf, 1024)) > 0) {
|
||||||
fwrite(buf, 1, res, stdout);
|
write_ret = fwrite(buf, 1, res, stdout);
|
||||||
|
if (write_ret < res) {
|
||||||
|
printf ("Cannot write block to stdout. errno= %d\n", errno);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
fprintf(stderr, "Error reading, err = %d\n", res);
|
fprintf(stderr, "Error reading, err = %d\n", res);
|
||||||
@ -700,7 +709,11 @@ int gesture_iso_modify(int argc, char **argv)
|
|||||||
iso_write_opts_free(opts);
|
iso_write_opts_free(opts);
|
||||||
|
|
||||||
while (burn_src->read_xt(burn_src, buf, 2048) == 2048) {
|
while (burn_src->read_xt(burn_src, buf, 2048) == 2048) {
|
||||||
fwrite(buf, 1, 2048, fp);
|
result = fwrite(buf, 1, 2048, fp);
|
||||||
|
if (result < 2048) {
|
||||||
|
printf ("Cannot write block. errno= %d\n", errno);
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
burn_src->free_data(burn_src);
|
burn_src->free_data(burn_src);
|
||||||
@ -814,7 +827,11 @@ int gesture_iso_ms(int argc, char **argv)
|
|||||||
iso_write_opts_free(opts);
|
iso_write_opts_free(opts);
|
||||||
|
|
||||||
while (burn_src->read_xt(burn_src, buf, 2048) == 2048) {
|
while (burn_src->read_xt(burn_src, buf, 2048) == 2048) {
|
||||||
fwrite(buf, 1, 2048, fp);
|
result = fwrite(buf, 1, 2048, fp);
|
||||||
|
if (result < 2048) {
|
||||||
|
printf ("Cannot write block. errno= %d\n", errno);
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
burn_src->free_data(burn_src);
|
burn_src->free_data(burn_src);
|
||||||
|
@ -1143,7 +1143,8 @@ HIDE_UNDOC_RELATIONS = YES
|
|||||||
# toolkit from AT&T and Lucent Bell Labs. The other options in this section
|
# toolkit from AT&T and Lucent Bell Labs. The other options in this section
|
||||||
# have no effect if this option is set to NO (the default)
|
# have no effect if this option is set to NO (the default)
|
||||||
|
|
||||||
HAVE_DOT = YES
|
# ts B10415: dot causes sigsegv on Debian buildd
|
||||||
|
HAVE_DOT = NO
|
||||||
|
|
||||||
# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
|
# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
|
||||||
# will generate a graph for each documented class showing the direct and
|
# will generate a graph for each documented class showing the direct and
|
||||||
|
@ -22,6 +22,8 @@ Purpose:
|
|||||||
END is also the block address of the start of the checksum recording
|
END is also the block address of the start of the checksum recording
|
||||||
area in the image.
|
area in the image.
|
||||||
See also isofs.cx .
|
See also isofs.cx .
|
||||||
|
This attribute shall eventually be attached to the root directory entry
|
||||||
|
and be global for the whole image.
|
||||||
|
|
||||||
Format of Value:
|
Format of Value:
|
||||||
START_LEN | START_BYTES | END_LEN | END_BYTES |
|
START_LEN | START_BYTES | END_LEN | END_BYTES |
|
||||||
@ -150,7 +152,7 @@ Registered:
|
|||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
This text is under
|
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
|
It shall only be modified in sync with libisofs and other software which
|
||||||
makes use of AAIP. Please mail change requests to mailing list
|
makes use of AAIP. Please mail change requests to mailing list
|
||||||
<libburn-hackers@pykix.org> or to the copyright holder in private.
|
<libburn-hackers@pykix.org> or to the copyright holder in private.
|
||||||
|
@ -229,7 +229,7 @@ ex:;
|
|||||||
|
|
||||||
if(ret <= 0 || (flag & (1 << 15))) {
|
if(ret <= 0 || (flag & (1 << 15))) {
|
||||||
if(*names != NULL) {
|
if(*names != NULL) {
|
||||||
for(i= 0; i < *num_attrs; i++)
|
for(i= 0; i < (ssize_t) *num_attrs; i++)
|
||||||
free((*names)[i]);
|
free((*names)[i]);
|
||||||
free(*names);
|
free(*names);
|
||||||
}
|
}
|
||||||
@ -238,7 +238,7 @@ ex:;
|
|||||||
free(*value_lengths);
|
free(*value_lengths);
|
||||||
*value_lengths= NULL;
|
*value_lengths= NULL;
|
||||||
if(*values != NULL) {
|
if(*values != NULL) {
|
||||||
for(i= 0; i < *num_attrs; i++)
|
for(i= 0; i < (ssize_t) *num_attrs; i++)
|
||||||
free((*values)[i]);
|
free((*values)[i]);
|
||||||
free(*values);
|
free(*values);
|
||||||
}
|
}
|
||||||
|
@ -220,7 +220,7 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
|
|||||||
(*value_lengths)[i]= 0;
|
(*value_lengths)[i]= 0;
|
||||||
}
|
}
|
||||||
if(!(flag & 4)) {
|
if(!(flag & 4)) {
|
||||||
for(i= 0; i < list_size && num_names > *num_attrs;
|
for(i= 0; i < list_size && (size_t) num_names > *num_attrs;
|
||||||
i+= strlen(list + i) + 1) {
|
i+= strlen(list + i) + 1) {
|
||||||
if(!(flag & 8))
|
if(!(flag & 8))
|
||||||
if(strncmp(list + i, "user.", 5))
|
if(strncmp(list + i, "user.", 5))
|
||||||
@ -234,7 +234,7 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
|
|||||||
#ifdef Libisofs_with_aaip_xattR
|
#ifdef Libisofs_with_aaip_xattR
|
||||||
|
|
||||||
if(!(flag & 4)) { /* Get xattr values */
|
if(!(flag & 4)) { /* Get xattr values */
|
||||||
for(i= 0; i < *num_attrs; i++) {
|
for(i= 0; (size_t) i < *num_attrs; i++) {
|
||||||
if(!(flag & 8))
|
if(!(flag & 8))
|
||||||
if(strncmp((*names)[i], "user.", 5))
|
if(strncmp((*names)[i], "user.", 5))
|
||||||
continue;
|
continue;
|
||||||
@ -299,7 +299,7 @@ ex:;
|
|||||||
free(list);
|
free(list);
|
||||||
if(ret <= 0 || (flag & (1 << 15))) {
|
if(ret <= 0 || (flag & (1 << 15))) {
|
||||||
if(*names != NULL) {
|
if(*names != NULL) {
|
||||||
for(i= 0; i < *num_attrs; i++)
|
for(i= 0; (size_t) i < *num_attrs; i++)
|
||||||
free((*names)[i]);
|
free((*names)[i]);
|
||||||
free(*names);
|
free(*names);
|
||||||
}
|
}
|
||||||
@ -308,7 +308,7 @@ ex:;
|
|||||||
free(*value_lengths);
|
free(*value_lengths);
|
||||||
*value_lengths= NULL;
|
*value_lengths= NULL;
|
||||||
if(*values != NULL) {
|
if(*values != NULL) {
|
||||||
for(i= 0; i < *num_attrs; i++)
|
for(i= 0; (size_t) i < *num_attrs; i++)
|
||||||
free((*values)[i]);
|
free((*values)[i]);
|
||||||
free(*values);
|
free(*values);
|
||||||
}
|
}
|
||||||
@ -401,7 +401,7 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
|
|||||||
size_t i, consumed, acl_text_fill, acl_idx= 0, h_consumed;
|
size_t i, consumed, acl_text_fill, acl_idx= 0, h_consumed;
|
||||||
char *acl_text= NULL, *list= NULL;
|
char *acl_text= NULL, *list= NULL;
|
||||||
#ifdef Libisofs_with_aaip_xattR
|
#ifdef Libisofs_with_aaip_xattR
|
||||||
size_t list_size= 0;
|
ssize_t list_size= 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef Libisofs_with_aaip_xattR
|
#ifdef Libisofs_with_aaip_xattR
|
||||||
@ -422,7 +422,7 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
|
|||||||
list_size= llistxattr(path, list, list_size);
|
list_size= llistxattr(path, list, list_size);
|
||||||
if(list_size == -1)
|
if(list_size == -1)
|
||||||
{ret= -5; goto ex;}
|
{ret= -5; goto ex;}
|
||||||
for(i= 0; i < list_size; i+= strlen(list + i) + 1) {
|
for(i= 0; i < (size_t) list_size; i+= strlen(list + i) + 1) {
|
||||||
if(!(flag & 8))
|
if(!(flag & 8))
|
||||||
if(strncmp(list + i, "user.", 5))
|
if(strncmp(list + i, "user.", 5))
|
||||||
continue;
|
continue;
|
||||||
|
@ -4,10 +4,10 @@
|
|||||||
Arbitrary Attribute Interchange Protocol , AAIP versions 0.2 , 1.0 , 2.0.
|
Arbitrary Attribute Interchange Protocol , AAIP versions 0.2 , 1.0 , 2.0.
|
||||||
Implementation of encoding and decoding xattr and ACL.
|
Implementation of encoding and decoding xattr and ACL.
|
||||||
|
|
||||||
See test/aaip_0_2.h
|
See libisofs/aaip_0_2.h
|
||||||
http://libburnia-project.org/wiki/AAIP
|
http://libburnia-project.org/wiki/AAIP
|
||||||
|
|
||||||
Copyright (c) 2009 Thomas Schmitt, libburnia project, GPLv2+
|
Copyright (c) 2009 - 2011 Thomas Schmitt, libburnia project, GPLv2+
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -26,6 +26,7 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include "libisofs.h"
|
#include "libisofs.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#define Aaip_encode_debuG 1
|
#define Aaip_encode_debuG 1
|
||||||
@ -187,7 +188,7 @@ static int aaip_encode_comp(unsigned char *result, size_t *result_fill,
|
|||||||
aaip_encode_byte(result, result_fill, 0);
|
aaip_encode_byte(result, result_fill, 0);
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
for(rpt= data; rpt - data < l;) {
|
for(rpt= data; rpt - data < (ssize_t) l;) {
|
||||||
todo= l - (rpt - data) + (prefix > 0);
|
todo= l - (rpt - data) + (prefix > 0);
|
||||||
aaip_encode_byte(result, result_fill, (todo > 255));
|
aaip_encode_byte(result, result_fill, (todo > 255));
|
||||||
if(todo > 255)
|
if(todo > 255)
|
||||||
@ -198,7 +199,7 @@ static int aaip_encode_comp(unsigned char *result, size_t *result_fill,
|
|||||||
todo--;
|
todo--;
|
||||||
prefix= 0;
|
prefix= 0;
|
||||||
}
|
}
|
||||||
for(comp_start= rpt; rpt - comp_start < todo; rpt++)
|
for(comp_start= rpt; rpt - comp_start < (ssize_t) todo; rpt++)
|
||||||
aaip_encode_byte(result, result_fill, *((unsigned char *) rpt));
|
aaip_encode_byte(result, result_fill, *((unsigned char *) rpt));
|
||||||
}
|
}
|
||||||
return(1);
|
return(1);
|
||||||
@ -292,7 +293,7 @@ int aaip_encode_acl(char *acl_text, mode_t st_mode,
|
|||||||
*result_len= bytes;
|
*result_len= bytes;
|
||||||
bytes= aaip_encode_acl_text(acl_text, st_mode, *result_len, *result,
|
bytes= aaip_encode_acl_text(acl_text, st_mode, *result_len, *result,
|
||||||
(flag & (2 | 4 | 8)));
|
(flag & (2 | 4 | 8)));
|
||||||
if(bytes != *result_len) {
|
if((size_t) bytes != *result_len) {
|
||||||
*result_len= 0;
|
*result_len= 0;
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
@ -346,21 +347,23 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
|
|||||||
size_t result_size, unsigned char *result, int flag)
|
size_t result_size, unsigned char *result, int flag)
|
||||||
{
|
{
|
||||||
char *rpt, *npt, *cpt;
|
char *rpt, *npt, *cpt;
|
||||||
int qualifier= 0, perms, type, i, qualifier_len= 0, num_recs, needed= 0;
|
int qualifier= 0, perms, type, i, qualifier_len= 0, num_recs, needed= 0, ret;
|
||||||
unsigned int has_u= 0, has_g= 0, has_o= 0, has_m= 0, is_trivial= 1;
|
unsigned int has_u= 0, has_g= 0, has_o= 0, has_m= 0, is_trivial= 1;
|
||||||
uid_t uid, huid;
|
uid_t uid, huid;
|
||||||
gid_t gid, hgid;
|
gid_t gid, hgid;
|
||||||
ssize_t count= 0;
|
ssize_t count= 0;
|
||||||
struct passwd *pwd;
|
struct passwd *pwd;
|
||||||
struct group *grp;
|
struct group *grp;
|
||||||
char name[1024];
|
char *name = NULL;
|
||||||
|
int name_size= 1024;
|
||||||
double num;
|
double num;
|
||||||
|
|
||||||
|
LIBISO_ALLOC_MEM(name, char, name_size);
|
||||||
if(flag & 4) {
|
if(flag & 4) {
|
||||||
/* set SWITCH_MARK to indicate a default ACL */;
|
/* set SWITCH_MARK to indicate a default ACL */;
|
||||||
if(!(flag & 1)) {
|
if(!(flag & 1)) {
|
||||||
if(count >= result_size)
|
if((size_t) count >= result_size)
|
||||||
return(-1);
|
{ret= -1; goto ex;}
|
||||||
result[count]= (Aaip_SWITCH_MARK << 4) | Aaip_EXEC;
|
result[count]= (Aaip_SWITCH_MARK << 4) | Aaip_EXEC;
|
||||||
}
|
}
|
||||||
count++;
|
count++;
|
||||||
@ -386,7 +389,7 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
|
|||||||
type= Aaip_ACL_USER_OBJ;
|
type= Aaip_ACL_USER_OBJ;
|
||||||
has_u++;
|
has_u++;
|
||||||
} else {
|
} else {
|
||||||
if(cpt - (rpt + 5) >= sizeof(name))
|
if(cpt - (rpt + 5) >= name_size)
|
||||||
continue;
|
continue;
|
||||||
is_trivial= 0;
|
is_trivial= 0;
|
||||||
strncpy(name, rpt + 5, cpt - (rpt + 5));
|
strncpy(name, rpt + 5, cpt - (rpt + 5));
|
||||||
@ -419,7 +422,7 @@ user_by_name:;
|
|||||||
type= Aaip_ACL_GROUP_OBJ;
|
type= Aaip_ACL_GROUP_OBJ;
|
||||||
has_g++;
|
has_g++;
|
||||||
} else {
|
} else {
|
||||||
if(cpt - (rpt + 6) >= sizeof(name))
|
if(cpt - (rpt + 6) >= name_size)
|
||||||
continue;
|
continue;
|
||||||
is_trivial= 0;
|
is_trivial= 0;
|
||||||
strncpy(name, rpt + 6, cpt - (rpt + 6));
|
strncpy(name, rpt + 6, cpt - (rpt + 6));
|
||||||
@ -461,8 +464,8 @@ group_by_name:;
|
|||||||
perms= aaip_make_aaip_perms(cpt[1] == 'r', cpt[2] == 'w', cpt[3] == 'x');
|
perms= aaip_make_aaip_perms(cpt[1] == 'r', cpt[2] == 'w', cpt[3] == 'x');
|
||||||
|
|
||||||
if(!(flag & 1)) {
|
if(!(flag & 1)) {
|
||||||
if(count >= result_size)
|
if((size_t) count >= result_size)
|
||||||
return(-1);
|
{ret= -1; goto ex;}
|
||||||
result[count]= perms | ((!!qualifier) << 3) | (type << 4);
|
result[count]= perms | ((!!qualifier) << 3) | (type << 4);
|
||||||
}
|
}
|
||||||
count++;
|
count++;
|
||||||
@ -470,8 +473,8 @@ group_by_name:;
|
|||||||
if(qualifier) {
|
if(qualifier) {
|
||||||
num_recs= (qualifier_len / 127) + !!(qualifier_len % 127);
|
num_recs= (qualifier_len / 127) + !!(qualifier_len % 127);
|
||||||
if(!(flag & 1)) {
|
if(!(flag & 1)) {
|
||||||
if(count + 1 > result_size)
|
if((size_t) (count + 1) > result_size)
|
||||||
return(-1);
|
{ret= -1; goto ex;}
|
||||||
for(i= 0; i < num_recs; i++) {
|
for(i= 0; i < num_recs; i++) {
|
||||||
if(i < num_recs - 1)
|
if(i < num_recs - 1)
|
||||||
result[count++]= 255;
|
result[count++]= 255;
|
||||||
@ -480,8 +483,8 @@ group_by_name:;
|
|||||||
if(result[count - 1] == 0)
|
if(result[count - 1] == 0)
|
||||||
result[count - 1]= 127;
|
result[count - 1]= 127;
|
||||||
}
|
}
|
||||||
if(count + (result[count - 1] & 127) > result_size)
|
if((size_t) (count + (result[count - 1] & 127)) > result_size)
|
||||||
return(-1);
|
{ret= -1; goto ex;}
|
||||||
memcpy(result + count, name + i * 127, result[count - 1] & 127);
|
memcpy(result + count, name + i * 127, result[count - 1] & 127);
|
||||||
count+= result[count - 1] & 127;
|
count+= result[count - 1] & 127;
|
||||||
}
|
}
|
||||||
@ -495,8 +498,8 @@ group_by_name:;
|
|||||||
if(flag & 1)
|
if(flag & 1)
|
||||||
count+= needed;
|
count+= needed;
|
||||||
else {
|
else {
|
||||||
if(count + needed > result_size)
|
if((size_t) (count + needed) > result_size)
|
||||||
return(-1);
|
{ret= -1; goto ex;}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((flag & 8) && needed > 0 && !(flag & 1)) {
|
if ((flag & 8) && needed > 0 && !(flag & 1)) {
|
||||||
@ -521,7 +524,10 @@ group_by_name:;
|
|||||||
result[count++]= perms | (Aaip_ACL_MASK << 4);
|
result[count++]= perms | (Aaip_ACL_MASK << 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return(count);
|
ret= count;
|
||||||
|
ex:;
|
||||||
|
LIBISO_FREE_MEM(name);
|
||||||
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1120,9 +1126,9 @@ static int aaip_consume_rec_head(struct aaip_state *aaip,
|
|||||||
size_t todo;
|
size_t todo;
|
||||||
|
|
||||||
todo= *num_data;
|
todo= *num_data;
|
||||||
if(todo > aaip->aa_missing)
|
if(todo > (size_t) aaip->aa_missing)
|
||||||
todo= aaip->aa_missing;
|
todo= aaip->aa_missing;
|
||||||
if(todo >= aaip->rec_head_missing)
|
if(todo >= (size_t) aaip->rec_head_missing)
|
||||||
todo= aaip->rec_head_missing;
|
todo= aaip->rec_head_missing;
|
||||||
if(!aaip->recs_invalid)
|
if(!aaip->recs_invalid)
|
||||||
aaip_push_to_recs(aaip, *data, todo, 0);
|
aaip_push_to_recs(aaip, *data, todo, 0);
|
||||||
@ -1144,9 +1150,9 @@ static int aaip_consume_rec_data(struct aaip_state *aaip,
|
|||||||
size_t todo;
|
size_t todo;
|
||||||
|
|
||||||
todo= *num_data;
|
todo= *num_data;
|
||||||
if(todo > aaip->aa_missing)
|
if(todo > (size_t) aaip->aa_missing)
|
||||||
todo= aaip->aa_missing;
|
todo= aaip->aa_missing;
|
||||||
if(todo > aaip->rec_missing)
|
if(todo > (size_t) aaip->rec_missing)
|
||||||
todo= aaip->rec_missing;
|
todo= aaip->rec_missing;
|
||||||
if(!aaip->recs_invalid)
|
if(!aaip->recs_invalid)
|
||||||
aaip_push_to_recs(aaip, *data, todo, 1);
|
aaip_push_to_recs(aaip, *data, todo, 1);
|
||||||
@ -1178,7 +1184,7 @@ static int aaip_consume_aa_head(struct aaip_state *aaip,
|
|||||||
unsigned char aa_head[5];
|
unsigned char aa_head[5];
|
||||||
|
|
||||||
todo= *num_data;
|
todo= *num_data;
|
||||||
if(todo >= aaip->aa_head_missing)
|
if(todo >= (size_t) aaip->aa_head_missing)
|
||||||
todo= aaip->aa_head_missing;
|
todo= aaip->aa_head_missing;
|
||||||
aaip_push_to_recs(aaip, *data, todo, 0);
|
aaip_push_to_recs(aaip, *data, todo, 0);
|
||||||
aaip->aa_head_missing-= todo;
|
aaip->aa_head_missing-= todo;
|
||||||
@ -1225,7 +1231,7 @@ static int aaip_consume_aa_data(struct aaip_state *aaip,
|
|||||||
aaip_push_to_recs(aaip, zero_char, 1, 0);
|
aaip_push_to_recs(aaip, zero_char, 1, 0);
|
||||||
} else {
|
} else {
|
||||||
/* fill in missing btes */
|
/* fill in missing btes */
|
||||||
for(i= 0; i < aaip->rec_missing; i++)
|
for(i= 0; (int) i < aaip->rec_missing; i++)
|
||||||
aaip_push_to_recs(aaip, zero_char, 1, 1);
|
aaip_push_to_recs(aaip, zero_char, 1, 1);
|
||||||
}
|
}
|
||||||
aaip->rec_head_missing= 2;
|
aaip->rec_head_missing= 2;
|
||||||
@ -1968,14 +1974,16 @@ static int aaip_read_qualifier(unsigned char *data, size_t num_data,
|
|||||||
char *name, size_t name_size, size_t *name_fill,
|
char *name, size_t name_size, size_t *name_fill,
|
||||||
int flag)
|
int flag)
|
||||||
{
|
{
|
||||||
int is_done= 0, rec_len= 0;
|
int is_done= 0;
|
||||||
|
size_t rec_len= 0;
|
||||||
unsigned char *rpt;
|
unsigned char *rpt;
|
||||||
|
|
||||||
*name_fill= 0;
|
*name_fill= 0;
|
||||||
for(rpt= data; !is_done; rpt+= rec_len) {
|
for(rpt= data; !is_done; rpt+= rec_len) {
|
||||||
rec_len= (*rpt) & 127;
|
rec_len= (*rpt) & 127;
|
||||||
is_done= !((*rpt) & 128);
|
is_done= !((*rpt) & 128);
|
||||||
if(*name_fill + rec_len >= name_size || rpt + 1 + rec_len - data > num_data)
|
if(*name_fill + rec_len >= name_size ||
|
||||||
|
(size_t) (rpt + 1 + rec_len - data) > num_data)
|
||||||
return(-1);
|
return(-1);
|
||||||
memcpy(name + *name_fill, rpt + 1, rec_len);
|
memcpy(name + *name_fill, rpt + 1, rec_len);
|
||||||
rpt+= 1 + rec_len;
|
rpt+= 1 + rec_len;
|
||||||
@ -2013,20 +2021,21 @@ int aaip_decode_acl(unsigned char *data, size_t num_data, size_t *consumed,
|
|||||||
size_t *acl_text_fill, int flag)
|
size_t *acl_text_fill, int flag)
|
||||||
{
|
{
|
||||||
unsigned char *rpt;
|
unsigned char *rpt;
|
||||||
char perm_text[4], *wpt, name[1024];
|
char perm_text[4], *wpt, *name= NULL;
|
||||||
int type, qualifier= 0, perm, ret, i, cnt;
|
int type, qualifier= 0, perm, ret, cnt, name_size= 1024;
|
||||||
size_t w_size, name_fill= 0;
|
size_t w_size, name_fill= 0, i;
|
||||||
uid_t uid;
|
uid_t uid;
|
||||||
gid_t gid;
|
gid_t gid;
|
||||||
struct passwd *pwd;
|
struct passwd *pwd;
|
||||||
struct group *grp;
|
struct group *grp;
|
||||||
|
|
||||||
|
LIBISO_ALLOC_MEM(name, char, name_size);
|
||||||
cnt= flag & 1;
|
cnt= flag & 1;
|
||||||
*consumed= 0;
|
*consumed= 0;
|
||||||
wpt= acl_text;
|
wpt= acl_text;
|
||||||
w_size= acl_text_size;
|
w_size= acl_text_size;
|
||||||
*acl_text_fill= 0;
|
*acl_text_fill= 0;
|
||||||
for(rpt= data; rpt - data < num_data; ) {
|
for(rpt= data; (size_t) (rpt - data) < num_data; ) {
|
||||||
perm= *rpt;
|
perm= *rpt;
|
||||||
strcpy(perm_text, "---");
|
strcpy(perm_text, "---");
|
||||||
if(perm & Aaip_READ)
|
if(perm & Aaip_READ)
|
||||||
@ -2038,14 +2047,14 @@ int aaip_decode_acl(unsigned char *data, size_t num_data, size_t *consumed,
|
|||||||
|
|
||||||
type= (*rpt) >> 4;
|
type= (*rpt) >> 4;
|
||||||
if(type == Aaip_FUTURE_VERSION) /* indicate to caller: version mismatch */
|
if(type == Aaip_FUTURE_VERSION) /* indicate to caller: version mismatch */
|
||||||
return(-3);
|
{ret = -3; goto ex;}
|
||||||
|
|
||||||
qualifier= !!((*rpt) & 8);
|
qualifier= !!((*rpt) & 8);
|
||||||
if(qualifier) {
|
if(qualifier) {
|
||||||
ret= aaip_read_qualifier(rpt + 1, num_data - (rpt + 1 - data),
|
ret= aaip_read_qualifier(rpt + 1, num_data - (rpt + 1 - data),
|
||||||
name, sizeof(name), &name_fill, 0);
|
name, name_size, &name_fill, 0);
|
||||||
if(ret <= 0)
|
if(ret <= 0)
|
||||||
return(-1);
|
{ret = -1; goto ex;}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Advance read pointer */
|
/* Advance read pointer */
|
||||||
@ -2086,7 +2095,7 @@ int aaip_decode_acl(unsigned char *data, size_t num_data, size_t *consumed,
|
|||||||
pwd= getpwuid(uid);
|
pwd= getpwuid(uid);
|
||||||
if(pwd == NULL)
|
if(pwd == NULL)
|
||||||
sprintf(name, "%.f", (double) uid);
|
sprintf(name, "%.f", (double) uid);
|
||||||
else if(strlen(pwd->pw_name) >= sizeof(name))
|
else if(strlen(pwd->pw_name) >= (size_t) name_size)
|
||||||
sprintf(name, "%.f", (double) uid);
|
sprintf(name, "%.f", (double) uid);
|
||||||
else
|
else
|
||||||
strcpy(name, pwd->pw_name);
|
strcpy(name, pwd->pw_name);
|
||||||
@ -2100,7 +2109,7 @@ int aaip_decode_acl(unsigned char *data, size_t num_data, size_t *consumed,
|
|||||||
grp= getgrgid(gid);
|
grp= getgrgid(gid);
|
||||||
if(grp == NULL)
|
if(grp == NULL)
|
||||||
sprintf(name, "%.f", (double) gid);
|
sprintf(name, "%.f", (double) gid);
|
||||||
else if(strlen(grp->gr_name) >= sizeof(name))
|
else if(strlen(grp->gr_name) >= (size_t) name_size)
|
||||||
sprintf(name, "%.f", (double) gid);
|
sprintf(name, "%.f", (double) gid);
|
||||||
else
|
else
|
||||||
strcpy(name, grp->gr_name);
|
strcpy(name, grp->gr_name);
|
||||||
@ -2108,15 +2117,16 @@ int aaip_decode_acl(unsigned char *data, size_t num_data, size_t *consumed,
|
|||||||
ret= aaip_write_acl_line(&wpt, &w_size, "group", name, perm_text, cnt);
|
ret= aaip_write_acl_line(&wpt, &w_size, "group", name, perm_text, cnt);
|
||||||
} else {
|
} else {
|
||||||
/* indicate to caller: unknown type */
|
/* indicate to caller: unknown type */
|
||||||
return(-4);
|
{ret = -4; goto ex;}
|
||||||
}
|
}
|
||||||
if(ret <= 0)
|
if(ret <= 0)
|
||||||
return(-2);
|
{ret = -2; goto ex;}
|
||||||
}
|
}
|
||||||
ret= 1;
|
ret= 1;
|
||||||
ex:;
|
ex:;
|
||||||
if(flag & 1)
|
if(flag & 1)
|
||||||
*acl_text_fill= w_size + 1;
|
*acl_text_fill= w_size + 1;
|
||||||
|
LIBISO_FREE_MEM(name);
|
||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,7 +150,7 @@ void iso_ring_buffer_free(IsoRingBuffer *buf)
|
|||||||
int iso_ring_buffer_write(IsoRingBuffer *buf, uint8_t *data, size_t count)
|
int iso_ring_buffer_write(IsoRingBuffer *buf, uint8_t *data, size_t count)
|
||||||
{
|
{
|
||||||
size_t len;
|
size_t len;
|
||||||
int bytes_write = 0;
|
size_t bytes_write = 0;
|
||||||
|
|
||||||
if (buf == NULL || data == NULL) {
|
if (buf == NULL || data == NULL) {
|
||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
@ -206,7 +206,7 @@ int iso_ring_buffer_write(IsoRingBuffer *buf, uint8_t *data, size_t count)
|
|||||||
int iso_ring_buffer_read(IsoRingBuffer *buf, uint8_t *dest, size_t count)
|
int iso_ring_buffer_read(IsoRingBuffer *buf, uint8_t *dest, size_t count)
|
||||||
{
|
{
|
||||||
size_t len;
|
size_t len;
|
||||||
int bytes_read = 0;
|
size_t bytes_read = 0;
|
||||||
|
|
||||||
if (buf == NULL || dest == NULL) {
|
if (buf == NULL || dest == NULL) {
|
||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
|
@ -11,7 +11,14 @@
|
|||||||
#define LIBISO_BUFFER_H_
|
#define LIBISO_BUFFER_H_
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_STDINT_H
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_INTTYPES_H
|
||||||
|
#include <inttypes.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#define BLOCK_SIZE 2048
|
#define BLOCK_SIZE 2048
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
* Copyright (c) 2009 Thomas Schmitt
|
* Copyright (c) 2009 - 2011 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* This file is part of the libisofs project; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License version 2
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -20,16 +20,13 @@
|
|||||||
#include "fsource.h"
|
#include "fsource.h"
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
#include "aaip_0_2.h"
|
#include "aaip_0_2.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#ifndef PATH_MAX
|
|
||||||
#define PATH_MAX Libisofs_default_path_maX
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void iso_node_builder_ref(IsoNodeBuilder *builder)
|
void iso_node_builder_ref(IsoNodeBuilder *builder)
|
||||||
@ -75,6 +72,8 @@ int default_create_file(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
iso_file_source_ref(src);
|
iso_file_source_ref(src);
|
||||||
|
|
||||||
name = iso_file_source_get_name(src);
|
name = iso_file_source_get_name(src);
|
||||||
|
if (strlen(name) > LIBISOFS_NODE_NAME_MAX)
|
||||||
|
name[LIBISOFS_NODE_NAME_MAX] = 0;
|
||||||
ret = iso_node_new_file(name, stream, &node);
|
ret = iso_node_new_file(name, stream, &node);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
iso_stream_unref(stream);
|
iso_stream_unref(stream);
|
||||||
@ -106,9 +105,11 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
char *name;
|
char *name;
|
||||||
unsigned char *aa_string = NULL;
|
unsigned char *aa_string = NULL;
|
||||||
char *a_text = NULL, *d_text = NULL;
|
char *a_text = NULL, *d_text = NULL;
|
||||||
|
char *dest = NULL;
|
||||||
|
IsoSymlink *link;
|
||||||
|
|
||||||
if (builder == NULL || src == NULL || node == NULL) {
|
if (builder == NULL || src == NULL || node == NULL) {
|
||||||
return ISO_NULL_POINTER;
|
{ret = ISO_NULL_POINTER; goto ex;}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get info about source */
|
/* get info about source */
|
||||||
@ -118,10 +119,12 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
ret = iso_file_source_lstat(src, &info);
|
ret = iso_file_source_lstat(src, &info);
|
||||||
}
|
}
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
name = iso_file_source_get_name(src);
|
name = iso_file_source_get_name(src);
|
||||||
|
if (strlen(name) > LIBISOFS_NODE_NAME_MAX)
|
||||||
|
name[LIBISOFS_NODE_NAME_MAX] = 0;
|
||||||
fs = iso_file_source_get_filesystem(src);
|
fs = iso_file_source_get_filesystem(src);
|
||||||
new = NULL;
|
new = NULL;
|
||||||
|
|
||||||
@ -157,10 +160,8 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
case S_IFLNK:
|
case S_IFLNK:
|
||||||
{
|
{
|
||||||
/* source is a symbolic link */
|
/* source is a symbolic link */
|
||||||
char dest[PATH_MAX];
|
LIBISO_ALLOC_MEM(dest, char, LIBISOFS_NODE_PATH_MAX);
|
||||||
IsoSymlink *link;
|
ret = iso_file_source_readlink(src, dest, LIBISOFS_NODE_PATH_MAX);
|
||||||
|
|
||||||
ret = iso_file_source_readlink(src, dest, PATH_MAX);
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -198,7 +199,7 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
free(name);
|
free(name);
|
||||||
return ret;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fill fields */
|
/* fill fields */
|
||||||
@ -233,19 +234,25 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
if (ret == 1 && aa_string != NULL) {
|
if (ret == 1 && aa_string != NULL) {
|
||||||
ret = iso_node_add_xinfo(new, aaip_xinfo_func, aa_string);
|
ret = iso_node_add_xinfo(new, aaip_xinfo_func, aa_string);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
goto ex;
|
||||||
} else if(aa_string != NULL) {
|
} else if(aa_string != NULL) {
|
||||||
free(aa_string);
|
free(aa_string);
|
||||||
}
|
}
|
||||||
|
|
||||||
*node = new;
|
*node = new;
|
||||||
|
|
||||||
return ISO_SUCCESS;
|
ret = ISO_SUCCESS;
|
||||||
|
ex:;
|
||||||
|
LIBISO_FREE_MEM(dest);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
void default_free(IsoNodeBuilder *builder)
|
void default_free(IsoNodeBuilder *builder)
|
||||||
{
|
{
|
||||||
|
/* The .free() method of IsoNodeBuilder shall free private data but not
|
||||||
|
the builder itself. The latter is done in iso_node_builder_unref().
|
||||||
|
*/
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
* Copyright (c) 2007 Mario Danic
|
* Copyright (c) 2007 Mario Danic
|
||||||
* Copyright (c) 2009 - 2010 Thomas Schmitt
|
* Copyright (c) 2009 - 2011 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* This file is part of the libisofs project; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License version 2
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -329,6 +329,9 @@ int ecma119_writer_compute_data_blocks(IsoImageWriter *writer)
|
|||||||
image start and not for the partition */;
|
image start and not for the partition */;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
target->tree_end_block = target->curblock;
|
||||||
|
|
||||||
return ISO_SUCCESS;
|
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;
|
multi_extend = (node->info.file->nsections - 1 == extent) ? 0 : 1;
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* for nodes other than files and dirs, we set both
|
* for nodes other than files and dirs, we set len to 0, and
|
||||||
* len and block to 0
|
* the content block address to a dummy value.
|
||||||
*/
|
*/
|
||||||
len = 0;
|
len = 0;
|
||||||
block = 0;
|
if (! t->old_empty)
|
||||||
|
block = t->empty_file_block;
|
||||||
|
else
|
||||||
|
block = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -570,16 +576,16 @@ static
|
|||||||
int write_one_dir(Ecma119Image *t, Ecma119Node *dir, Ecma119Node *parent)
|
int write_one_dir(Ecma119Image *t, Ecma119Node *dir, Ecma119Node *parent)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
uint8_t buffer[BLOCK_SIZE];
|
uint8_t *buffer = NULL;
|
||||||
size_t i;
|
size_t i;
|
||||||
size_t fi_len, len;
|
size_t fi_len, len;
|
||||||
struct susp_info info;
|
struct susp_info info;
|
||||||
|
|
||||||
/* buf will point to current write position on buffer */
|
/* buf will point to current write position on buffer */
|
||||||
uint8_t *buf = buffer;
|
uint8_t *buf;
|
||||||
|
|
||||||
/* initialize buffer with 0s */
|
LIBISO_ALLOC_MEM(buffer, uint8_t, BLOCK_SIZE);
|
||||||
memset(buffer, 0, BLOCK_SIZE);
|
buf = buffer;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* set susp_info to 0's, this way code for both plain ECMA-119 and
|
* set susp_info to 0's, this way code for both plain ECMA-119 and
|
||||||
@ -596,7 +602,7 @@ int write_one_dir(Ecma119Image *t, Ecma119Node *dir, Ecma119Node *parent)
|
|||||||
if (t->rockridge) {
|
if (t->rockridge) {
|
||||||
ret = rrip_get_susp_fields(t, dir, 1, 34, &info);
|
ret = rrip_get_susp_fields(t, dir, 1, 34, &info);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
goto ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
len = 34 + info.suf_len;
|
len = 34 + info.suf_len;
|
||||||
@ -606,7 +612,7 @@ int write_one_dir(Ecma119Image *t, Ecma119Node *dir, Ecma119Node *parent)
|
|||||||
if (t->rockridge) {
|
if (t->rockridge) {
|
||||||
ret = rrip_get_susp_fields(t, dir, 2, 34, &info);
|
ret = rrip_get_susp_fields(t, dir, 2, 34, &info);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
goto ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
len = 34 + info.suf_len;
|
len = 34 + info.suf_len;
|
||||||
@ -632,7 +638,7 @@ int write_one_dir(Ecma119Image *t, Ecma119Node *dir, Ecma119Node *parent)
|
|||||||
if (t->rockridge) {
|
if (t->rockridge) {
|
||||||
ret = rrip_get_susp_fields(t, child, 0, len, &info);
|
ret = rrip_get_susp_fields(t, child, 0, len, &info);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
goto ex;
|
||||||
}
|
}
|
||||||
len += info.suf_len;
|
len += info.suf_len;
|
||||||
}
|
}
|
||||||
@ -641,7 +647,7 @@ int write_one_dir(Ecma119Image *t, Ecma119Node *dir, Ecma119Node *parent)
|
|||||||
/* dir doesn't fit in current block */
|
/* dir doesn't fit in current block */
|
||||||
ret = iso_write(t, buffer, BLOCK_SIZE);
|
ret = iso_write(t, buffer, BLOCK_SIZE);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
goto ex;
|
||||||
}
|
}
|
||||||
memset(buffer, 0, BLOCK_SIZE);
|
memset(buffer, 0, BLOCK_SIZE);
|
||||||
buf = buffer;
|
buf = buffer;
|
||||||
@ -655,7 +661,7 @@ int write_one_dir(Ecma119Image *t, Ecma119Node *dir, Ecma119Node *parent)
|
|||||||
/* write the last block */
|
/* write the last block */
|
||||||
ret = iso_write(t, buffer, BLOCK_SIZE);
|
ret = iso_write(t, buffer, BLOCK_SIZE);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* write the Continuation Area if needed */
|
/* write the Continuation Area if needed */
|
||||||
@ -663,6 +669,8 @@ int write_one_dir(Ecma119Image *t, Ecma119Node *dir, Ecma119Node *parent)
|
|||||||
ret = rrip_write_ce_fields(t, &info);
|
ret = rrip_write_ce_fields(t, &info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ex:;
|
||||||
|
LIBISO_FREE_MEM(buffer);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -702,6 +710,7 @@ int write_path_table(Ecma119Image *t, Ecma119Node **pathlist, int l_type)
|
|||||||
uint32_t path_table_size;
|
uint32_t path_table_size;
|
||||||
int parent = 0;
|
int parent = 0;
|
||||||
int ret= ISO_SUCCESS;
|
int ret= ISO_SUCCESS;
|
||||||
|
uint8_t *zeros = NULL;
|
||||||
|
|
||||||
path_table_size = 0;
|
path_table_size = 0;
|
||||||
write_int = l_type ? iso_lsb : iso_msb;
|
write_int = l_type ? iso_lsb : iso_msb;
|
||||||
@ -729,7 +738,7 @@ int write_path_table(Ecma119Image *t, Ecma119Node **pathlist, int l_type)
|
|||||||
ret = iso_write(t, buf, len);
|
ret = iso_write(t, buf, len);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
/* error */
|
/* error */
|
||||||
return ret;
|
goto ex;
|
||||||
}
|
}
|
||||||
path_table_size += len;
|
path_table_size += len;
|
||||||
}
|
}
|
||||||
@ -737,11 +746,12 @@ int write_path_table(Ecma119Image *t, Ecma119Node **pathlist, int l_type)
|
|||||||
/* we need to fill the last block with zeros */
|
/* we need to fill the last block with zeros */
|
||||||
path_table_size %= BLOCK_SIZE;
|
path_table_size %= BLOCK_SIZE;
|
||||||
if (path_table_size) {
|
if (path_table_size) {
|
||||||
uint8_t zeros[BLOCK_SIZE];
|
|
||||||
len = BLOCK_SIZE - path_table_size;
|
len = BLOCK_SIZE - path_table_size;
|
||||||
memset(zeros, 0, len);
|
LIBISO_ALLOC_MEM(zeros, uint8_t, len);
|
||||||
ret = iso_write(t, zeros, len);
|
ret = iso_write(t, zeros, len);
|
||||||
}
|
}
|
||||||
|
ex:;
|
||||||
|
LIBISO_FREE_MEM(zeros);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -871,24 +881,41 @@ int ecma119_writer_write_data(IsoImageWriter *writer)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
Ecma119Image *t;
|
Ecma119Image *t;
|
||||||
|
uint32_t curblock;
|
||||||
|
char *msg = NULL;
|
||||||
|
|
||||||
|
if (writer == NULL)
|
||||||
|
{ret = ISO_ASSERT_FAILURE; goto ex;}
|
||||||
|
|
||||||
if (writer == NULL) {
|
|
||||||
return ISO_ASSERT_FAILURE;
|
|
||||||
}
|
|
||||||
t = writer->target;
|
t = writer->target;
|
||||||
|
|
||||||
ret = ecma119_writer_write_dirs(writer);
|
ret = ecma119_writer_write_dirs(writer);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
goto ex;
|
||||||
|
|
||||||
if (t->partition_offset > 0) {
|
if (t->partition_offset > 0) {
|
||||||
t->eff_partition_offset = t->partition_offset;
|
t->eff_partition_offset = t->partition_offset;
|
||||||
ret = ecma119_writer_write_dirs(writer);
|
ret = ecma119_writer_write_dirs(writer);
|
||||||
t->eff_partition_offset = 0;
|
t->eff_partition_offset = 0;
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
goto ex;
|
||||||
}
|
}
|
||||||
return ISO_SUCCESS;
|
|
||||||
|
curblock = (t->bytes_written / 2048) + t->ms_block;
|
||||||
|
if (curblock != t->tree_end_block) {
|
||||||
|
LIBISO_ALLOC_MEM(msg, char, 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 */
|
||||||
|
}
|
||||||
|
ret = ISO_SUCCESS;
|
||||||
|
ex:;
|
||||||
|
LIBISO_FREE_MEM(msg);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
@ -969,27 +996,30 @@ int mspad_writer_write_data(IsoImageWriter *writer)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
Ecma119Image *t;
|
Ecma119Image *t;
|
||||||
uint8_t pad[BLOCK_SIZE];
|
uint8_t *pad = NULL;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
if (writer == NULL) {
|
if (writer == NULL) {
|
||||||
return ISO_ASSERT_FAILURE;
|
{ret = ISO_ASSERT_FAILURE; goto ex;}
|
||||||
}
|
}
|
||||||
t = writer->target;
|
t = writer->target;
|
||||||
|
|
||||||
if (t->mspad_blocks == 0) {
|
if (t->mspad_blocks == 0) {
|
||||||
return ISO_SUCCESS;
|
{ret = ISO_SUCCESS; goto ex;}
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(pad, 0, BLOCK_SIZE);
|
LIBISO_ALLOC_MEM(pad, uint8_t, BLOCK_SIZE);
|
||||||
for (i = 0; i < t->mspad_blocks; ++i) {
|
for (i = 0; i < t->mspad_blocks; ++i) {
|
||||||
ret = iso_write(t, pad, BLOCK_SIZE);
|
ret = iso_write(t, pad, BLOCK_SIZE);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
goto ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ISO_SUCCESS;
|
ret = ISO_SUCCESS;
|
||||||
|
ex:;
|
||||||
|
LIBISO_FREE_MEM(pad);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
@ -1055,23 +1085,26 @@ int zero_writer_write_data(IsoImageWriter *writer)
|
|||||||
int ret;
|
int ret;
|
||||||
Ecma119Image *t;
|
Ecma119Image *t;
|
||||||
struct iso_zero_writer_data_struct *data;
|
struct iso_zero_writer_data_struct *data;
|
||||||
uint8_t pad[BLOCK_SIZE];
|
uint8_t *pad = NULL;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
if (writer == NULL)
|
if (writer == NULL)
|
||||||
return ISO_ASSERT_FAILURE;
|
{ret = ISO_ASSERT_FAILURE; goto ex;}
|
||||||
t = writer->target;
|
t = writer->target;
|
||||||
data = (struct iso_zero_writer_data_struct *) writer->data;
|
data = (struct iso_zero_writer_data_struct *) writer->data;
|
||||||
|
|
||||||
if (data->num_blocks == 0)
|
if (data->num_blocks == 0)
|
||||||
return ISO_SUCCESS;
|
{ret = ISO_SUCCESS; goto ex;}
|
||||||
memset(pad, 0, BLOCK_SIZE);
|
LIBISO_ALLOC_MEM(pad, uint8_t, BLOCK_SIZE);
|
||||||
for (i = 0; i < data->num_blocks; ++i) {
|
for (i = 0; i < data->num_blocks; ++i) {
|
||||||
ret = iso_write(t, pad, BLOCK_SIZE);
|
ret = iso_write(t, pad, BLOCK_SIZE);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
goto ex;
|
||||||
}
|
}
|
||||||
return ISO_SUCCESS;
|
ret = ISO_SUCCESS;
|
||||||
|
ex:;
|
||||||
|
LIBISO_FREE_MEM(pad);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
@ -1087,7 +1120,36 @@ int zero_writer_free_data(IsoImageWriter *writer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static
|
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[80];
|
||||||
|
|
||||||
|
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;
|
IsoImageWriter *writer;
|
||||||
struct iso_zero_writer_data_struct *data;
|
struct iso_zero_writer_data_struct *data;
|
||||||
@ -1103,7 +1165,11 @@ int zero_writer_create(Ecma119Image *target, uint32_t num_blocks)
|
|||||||
}
|
}
|
||||||
data->num_blocks = 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_vol_desc = zero_writer_write_vol_desc;
|
||||||
writer->write_data = zero_writer_write_data;
|
writer->write_data = zero_writer_write_data;
|
||||||
writer->free_data = zero_writer_free_data;
|
writer->free_data = zero_writer_free_data;
|
||||||
@ -1131,18 +1197,22 @@ int transplant_checksum_buffer(Ecma119Image *target, int flag)
|
|||||||
static
|
static
|
||||||
int write_vol_desc_terminator(Ecma119Image *target)
|
int write_vol_desc_terminator(Ecma119Image *target)
|
||||||
{
|
{
|
||||||
int res;
|
int ret;
|
||||||
uint8_t buf[BLOCK_SIZE];
|
uint8_t *buf = NULL;
|
||||||
struct ecma119_vol_desc_terminator *vol;
|
struct ecma119_vol_desc_terminator *vol;
|
||||||
|
|
||||||
|
LIBISO_ALLOC_MEM(buf, uint8_t, BLOCK_SIZE);
|
||||||
|
|
||||||
vol = (struct ecma119_vol_desc_terminator *) buf;
|
vol = (struct ecma119_vol_desc_terminator *) buf;
|
||||||
|
|
||||||
vol->vol_desc_type[0] = 255;
|
vol->vol_desc_type[0] = 255;
|
||||||
memcpy(vol->std_identifier, "CD001", 5);
|
memcpy(vol->std_identifier, "CD001", 5);
|
||||||
vol->vol_desc_version[0] = 1;
|
vol->vol_desc_version[0] = 1;
|
||||||
|
|
||||||
res = iso_write(target, buf, BLOCK_SIZE);
|
ret = iso_write(target, buf, BLOCK_SIZE);
|
||||||
return res;
|
ex:
|
||||||
|
LIBISO_FREE_MEM(buf);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1173,7 +1243,7 @@ int write_head_part1(Ecma119Image *target, int *write_count, int flag)
|
|||||||
|
|
||||||
/* write volume descriptors, one per writer */
|
/* write volume descriptors, one per writer */
|
||||||
iso_msg_debug(target->image->id, "Write volume descriptors");
|
iso_msg_debug(target->image->id, "Write volume descriptors");
|
||||||
for (i = 0; i < target->nwriters; ++i) {
|
for (i = 0; i < (int) target->nwriters; ++i) {
|
||||||
writer = target->writers[i];
|
writer = target->writers[i];
|
||||||
res = writer->write_vol_desc(writer);
|
res = writer->write_vol_desc(writer);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
@ -1201,26 +1271,27 @@ write_error:;
|
|||||||
static
|
static
|
||||||
int write_head_part2(Ecma119Image *target, int *write_count, int flag)
|
int write_head_part2(Ecma119Image *target, int *write_count, int flag)
|
||||||
{
|
{
|
||||||
int res, i;
|
int ret, i;
|
||||||
uint8_t buf[BLOCK_SIZE];
|
uint8_t *buf = NULL;
|
||||||
IsoImageWriter *writer;
|
IsoImageWriter *writer;
|
||||||
|
|
||||||
if (target->partition_offset <= 0)
|
if (target->partition_offset <= 0)
|
||||||
return ISO_SUCCESS;
|
{ret = ISO_SUCCESS; goto ex;}
|
||||||
|
|
||||||
/* Write multi-session padding up to target->partition_offset + 16 */
|
/* Write multi-session padding up to target->partition_offset + 16 */
|
||||||
memset(buf, 0, 2048);
|
LIBISO_ALLOC_MEM(buf, uint8_t, BLOCK_SIZE);
|
||||||
for(; *write_count < target->partition_offset + 16; (*write_count)++) {
|
for(; *write_count < (int) target->partition_offset + 16;
|
||||||
res = iso_write(target, buf, BLOCK_SIZE);
|
(*write_count)++) {
|
||||||
if (res < 0)
|
ret = iso_write(target, buf, BLOCK_SIZE);
|
||||||
goto write_error;
|
if (ret < 0)
|
||||||
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write volume descriptors subtracting
|
/* Write volume descriptors subtracting
|
||||||
target->partiton_offset from any LBA pointer.
|
target->partiton_offset from any LBA pointer.
|
||||||
*/
|
*/
|
||||||
target->eff_partition_offset = target->partition_offset;
|
target->eff_partition_offset = target->partition_offset;
|
||||||
for (i = 0; i < target->nwriters; ++i) {
|
for (i = 0; i < (int) target->nwriters; ++i) {
|
||||||
writer = target->writers[i];
|
writer = target->writers[i];
|
||||||
/* Not all writers have an entry in the partion volume descriptor set.
|
/* Not all writers have an entry in the partion volume descriptor set.
|
||||||
It must be guaranteed that they write exactly one block.
|
It must be guaranteed that they write exactly one block.
|
||||||
@ -1231,23 +1302,23 @@ int write_head_part2(Ecma119Image *target, int *write_count, int flag)
|
|||||||
if(writer->write_vol_desc != ecma119_writer_write_vol_desc &&
|
if(writer->write_vol_desc != ecma119_writer_write_vol_desc &&
|
||||||
writer->write_vol_desc != joliet_writer_write_vol_desc)
|
writer->write_vol_desc != joliet_writer_write_vol_desc)
|
||||||
continue;
|
continue;
|
||||||
res = writer->write_vol_desc(writer);
|
ret = writer->write_vol_desc(writer);
|
||||||
if (res < 0)
|
if (ret < 0)
|
||||||
goto write_error;
|
goto ex;
|
||||||
(*write_count)++;
|
(*write_count)++;
|
||||||
}
|
}
|
||||||
res = write_vol_desc_terminator(target);
|
ret = write_vol_desc_terminator(target);
|
||||||
if (res < 0)
|
if (ret < 0)
|
||||||
goto write_error;
|
goto ex;
|
||||||
(*write_count)++;
|
(*write_count)++;
|
||||||
target->eff_partition_offset = 0;
|
target->eff_partition_offset = 0;
|
||||||
|
|
||||||
/* >>> TWINTREE: Postponed for now:
|
/* >>> TWINTREE: Postponed for now:
|
||||||
Write second superblock checksum tag */;
|
Write second superblock checksum tag */;
|
||||||
|
|
||||||
return ISO_SUCCESS;
|
ret = ISO_SUCCESS;
|
||||||
write_error:;
|
ex:;
|
||||||
return res;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
@ -1303,19 +1374,19 @@ static int write_mbr_partition_file(Ecma119Image *target, char *path,
|
|||||||
{
|
{
|
||||||
FILE *fp = NULL;
|
FILE *fp = NULL;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
uint8_t buf[BLOCK_SIZE];
|
uint8_t *buf = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
memset(buf, 0, BLOCK_SIZE);
|
LIBISO_ALLOC_MEM(buf, uint8_t, BLOCK_SIZE);
|
||||||
for (i = 0; i < prepad; i++) {
|
for (i = 0; i < prepad; i++) {
|
||||||
ret = iso_write(target, buf, BLOCK_SIZE);
|
ret = iso_write(target, buf, BLOCK_SIZE);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
fp = fopen(path, "rb");
|
fp = fopen(path, "rb");
|
||||||
if (fp == NULL)
|
if (fp == NULL)
|
||||||
return ISO_BAD_PARTITION_FILE;
|
{ret = ISO_BAD_PARTITION_FILE; goto ex;}
|
||||||
|
|
||||||
for (i = 0; i < blocks; i++) {
|
for (i = 0; i < blocks; i++) {
|
||||||
memset(buf, 0, BLOCK_SIZE);
|
memset(buf, 0, BLOCK_SIZE);
|
||||||
@ -1329,12 +1400,15 @@ static int write_mbr_partition_file(Ecma119Image *target, char *path,
|
|||||||
ret = iso_write(target, buf, BLOCK_SIZE);
|
ret = iso_write(target, buf, BLOCK_SIZE);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
return ret;
|
goto ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fp != NULL)
|
if (fp != NULL)
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
return ISO_SUCCESS;
|
ret = ISO_SUCCESS;
|
||||||
|
ex:;
|
||||||
|
LIBISO_FREE_MEM(buf);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1342,7 +1416,7 @@ static
|
|||||||
void *write_function(void *arg)
|
void *write_function(void *arg)
|
||||||
{
|
{
|
||||||
int res, first_partition = 1, last_partition = 0, sa_type;
|
int res, first_partition = 1, last_partition = 0, sa_type;
|
||||||
size_t i;
|
int i;
|
||||||
IsoImageWriter *writer;
|
IsoImageWriter *writer;
|
||||||
|
|
||||||
Ecma119Image *target = (Ecma119Image*)arg;
|
Ecma119Image *target = (Ecma119Image*)arg;
|
||||||
@ -1356,7 +1430,7 @@ void *write_function(void *arg)
|
|||||||
goto write_error;
|
goto write_error;
|
||||||
|
|
||||||
/* write data for each writer */
|
/* write data for each writer */
|
||||||
for (i = 0; i < target->nwriters; ++i) {
|
for (i = 0; i < (int) target->nwriters; ++i) {
|
||||||
writer = target->writers[i];
|
writer = target->writers[i];
|
||||||
res = writer->write_data(writer);
|
res = writer->write_data(writer);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
@ -1400,6 +1474,12 @@ void *write_function(void *arg)
|
|||||||
Eventually free target */
|
Eventually free target */
|
||||||
ecma119_image_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
|
#ifdef Libisofs_with_pthread_exiT
|
||||||
pthread_exit(NULL);
|
pthread_exit(NULL);
|
||||||
#else
|
#else
|
||||||
@ -1407,10 +1487,10 @@ void *write_function(void *arg)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
write_error: ;
|
write_error: ;
|
||||||
if (res != ISO_LIBJTE_END_FAILED)
|
if (res != (int) ISO_LIBJTE_END_FAILED)
|
||||||
finish_libjte(target);
|
finish_libjte(target);
|
||||||
target->eff_partition_offset = 0;
|
target->eff_partition_offset = 0;
|
||||||
if (res == ISO_CANCELED) {
|
if (res == (int) ISO_CANCELED) {
|
||||||
/* canceled */
|
/* canceled */
|
||||||
if (!target->will_cancel)
|
if (!target->will_cancel)
|
||||||
iso_msg_submit(target->image->id, ISO_IMAGE_WRITE_CANCELED,
|
iso_msg_submit(target->image->id, ISO_IMAGE_WRITE_CANCELED,
|
||||||
@ -1575,6 +1655,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
|||||||
target->hardlinks = opts->hardlinks;
|
target->hardlinks = opts->hardlinks;
|
||||||
target->aaip = opts->aaip;
|
target->aaip = opts->aaip;
|
||||||
target->always_gmt = opts->always_gmt;
|
target->always_gmt = opts->always_gmt;
|
||||||
|
target->old_empty = opts->old_empty;
|
||||||
target->untranslated_name_len = opts->untranslated_name_len;
|
target->untranslated_name_len = opts->untranslated_name_len;
|
||||||
target->allow_dir_id_ext = opts->allow_dir_id_ext;
|
target->allow_dir_id_ext = opts->allow_dir_id_ext;
|
||||||
target->omit_version_numbers = opts->omit_version_numbers
|
target->omit_version_numbers = opts->omit_version_numbers
|
||||||
@ -1587,6 +1668,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
|||||||
target->allow_full_ascii = opts->allow_full_ascii;
|
target->allow_full_ascii = opts->allow_full_ascii;
|
||||||
target->relaxed_vol_atts = opts->relaxed_vol_atts;
|
target->relaxed_vol_atts = opts->relaxed_vol_atts;
|
||||||
target->joliet_longer_paths = opts->joliet_longer_paths;
|
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_version_1_10 = opts->rrip_version_1_10;
|
||||||
target->rrip_1_10_px_ino = opts->rrip_1_10_px_ino;
|
target->rrip_1_10_px_ino = opts->rrip_1_10_px_ino;
|
||||||
target->aaip_susp_1_10 = opts->aaip_susp_1_10;
|
target->aaip_susp_1_10 = opts->aaip_susp_1_10;
|
||||||
@ -1636,7 +1718,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
|||||||
system_area = src->system_area_data;
|
system_area = src->system_area_data;
|
||||||
system_area_options = src->system_area_options;
|
system_area_options = src->system_area_options;
|
||||||
} else {
|
} else {
|
||||||
system_area_options = opts->system_area_options & 0xfc;
|
system_area_options = opts->system_area_options & 0xfffffffc;
|
||||||
}
|
}
|
||||||
sa_type = (system_area_options >> 2) & 0x3f;
|
sa_type = (system_area_options >> 2) & 0x3f;
|
||||||
if (sa_type != 0 && sa_type != 3)
|
if (sa_type != 0 && sa_type != 3)
|
||||||
@ -1665,9 +1747,9 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
|||||||
target->partition_secs_per_head = opts->partition_secs_per_head;
|
target->partition_secs_per_head = opts->partition_secs_per_head;
|
||||||
target->partition_heads_per_cyl = opts->partition_heads_per_cyl;
|
target->partition_heads_per_cyl = opts->partition_heads_per_cyl;
|
||||||
if (target->partition_secs_per_head == 0)
|
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)
|
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->eff_partition_offset = 0;
|
||||||
target->partition_root = NULL;
|
target->partition_root = NULL;
|
||||||
target->partition_l_table_pos = 0;
|
target->partition_l_table_pos = 0;
|
||||||
@ -1733,6 +1815,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
|||||||
target->mipsel_p_filesz = 0;
|
target->mipsel_p_filesz = 0;
|
||||||
|
|
||||||
target->empty_file_block = 0;
|
target->empty_file_block = 0;
|
||||||
|
target->tree_end_block = 0;
|
||||||
|
|
||||||
target->wthread_is_running = 0;
|
target->wthread_is_running = 0;
|
||||||
|
|
||||||
@ -1779,8 +1862,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
|||||||
if (target->iso1999) {
|
if (target->iso1999) {
|
||||||
nwriters++;
|
nwriters++;
|
||||||
}
|
}
|
||||||
if (target->tail_blocks > 0)
|
nwriters++; /* Tail padding writer */
|
||||||
nwriters++;
|
|
||||||
if ((target->md5_file_checksums & 1) || target->md5_session_checksum) {
|
if ((target->md5_file_checksums & 1) || target->md5_session_checksum) {
|
||||||
nwriters++;
|
nwriters++;
|
||||||
image_checksums_mad = 1; /* from here on the loaded checksums are
|
image_checksums_mad = 1; /* from here on the loaded checksums are
|
||||||
@ -1862,11 +1944,9 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
|||||||
|
|
||||||
|
|
||||||
/* IMPORTANT: This must be the last writer before the checksum writer */
|
/* IMPORTANT: This must be the last writer before the checksum writer */
|
||||||
if (target->tail_blocks > 0) {
|
ret = zero_writer_create(target, target->tail_blocks, 1);
|
||||||
ret = zero_writer_create(target, target->tail_blocks);
|
if (ret < 0)
|
||||||
if (ret < 0)
|
goto target_cleanup;
|
||||||
goto target_cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((target->md5_file_checksums & 1) || target->md5_session_checksum) {
|
if ((target->md5_file_checksums & 1) || target->md5_session_checksum) {
|
||||||
ret = checksum_writer_create(target);
|
ret = checksum_writer_create(target);
|
||||||
@ -1887,7 +1967,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
|||||||
target->curblock = target->ms_block + target->partition_offset + 16;
|
target->curblock = target->ms_block + target->partition_offset + 16;
|
||||||
|
|
||||||
/* Account for partition tree volume descriptors */
|
/* Account for partition tree volume descriptors */
|
||||||
for (i = 0; i < target->nwriters; ++i) {
|
for (i = 0; i < (int) target->nwriters; ++i) {
|
||||||
/* Not all writers have an entry in the partition
|
/* Not all writers have an entry in the partition
|
||||||
volume descriptor set.
|
volume descriptor set.
|
||||||
*/
|
*/
|
||||||
@ -1913,15 +1993,22 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
|||||||
* That function computes the size needed by its structures and
|
* That function computes the size needed by its structures and
|
||||||
* increments image current block propertly.
|
* increments image current block propertly.
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < target->nwriters; ++i) {
|
for (i = 0; i < (int) target->nwriters; ++i) {
|
||||||
IsoImageWriter *writer = target->writers[i];
|
IsoImageWriter *writer = target->writers[i];
|
||||||
|
|
||||||
/* Delaying boot image patching until new LBA is known */
|
/* Delaying boot image patching until new LBA is known */
|
||||||
if (i == el_torito_writer_index)
|
if (i == el_torito_writer_index)
|
||||||
continue;
|
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 (i == file_src_writer_index) {
|
||||||
|
if (! target->old_empty)
|
||||||
|
target->empty_file_block = target->curblock;
|
||||||
opts->data_start_lba = target->curblock;
|
opts->data_start_lba = target->curblock;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2268,6 +2355,8 @@ int iso_write(Ecma119Image *target, void *buf, size_t count)
|
|||||||
/* reader cancelled */
|
/* reader cancelled */
|
||||||
return ISO_CANCELED;
|
return ISO_CANCELED;
|
||||||
}
|
}
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
if (target->checksum_ctx != NULL) {
|
if (target->checksum_ctx != NULL) {
|
||||||
/* Add to image checksum */
|
/* Add to image checksum */
|
||||||
target->checksum_counter += count;
|
target->checksum_counter += count;
|
||||||
@ -2279,7 +2368,7 @@ int iso_write(Ecma119Image *target, void *buf, size_t count)
|
|||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* total size is 0 when writing the overwrite buffer */
|
/* 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;
|
unsigned int kbw, kbt;
|
||||||
int percent;
|
int percent;
|
||||||
|
|
||||||
@ -2296,7 +2385,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)
|
int iso_write_opts_new(IsoWriteOpts **opts, int profile)
|
||||||
@ -2366,6 +2455,7 @@ int iso_write_opts_new(IsoWriteOpts **opts, int profile)
|
|||||||
wopts->ascii_disc_label[0] = 0;
|
wopts->ascii_disc_label[0] = 0;
|
||||||
wopts->will_cancel = 0;
|
wopts->will_cancel = 0;
|
||||||
wopts->allow_dir_id_ext = 0;
|
wopts->allow_dir_id_ext = 0;
|
||||||
|
wopts->old_empty = 0;
|
||||||
wopts->untranslated_name_len = 0;
|
wopts->untranslated_name_len = 0;
|
||||||
|
|
||||||
*opts = wopts;
|
*opts = wopts;
|
||||||
@ -2455,6 +2545,15 @@ int iso_write_opts_set_aaip(IsoWriteOpts *opts, int enable)
|
|||||||
return ISO_SUCCESS;
|
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)
|
int iso_write_opts_set_untranslated_name_len(IsoWriteOpts *opts, int len)
|
||||||
{
|
{
|
||||||
if (opts == NULL) {
|
if (opts == NULL) {
|
||||||
@ -2561,6 +2660,15 @@ int iso_write_opts_set_joliet_longer_paths(IsoWriteOpts *opts, int allow)
|
|||||||
return ISO_SUCCESS;
|
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)
|
int iso_write_opts_set_rrip_version_1_10(IsoWriteOpts *opts, int oldvers)
|
||||||
{
|
{
|
||||||
if (opts == NULL) {
|
if (opts == NULL) {
|
||||||
@ -2830,7 +2938,7 @@ int iso_write_opts_set_system_area(IsoWriteOpts *opts, char data[32768],
|
|||||||
memcpy(opts->system_area_data, data, 32768);
|
memcpy(opts->system_area_data, data, 32768);
|
||||||
}
|
}
|
||||||
if (!(flag & 4))
|
if (!(flag & 4))
|
||||||
opts->system_area_options = options & 0xff;
|
opts->system_area_options = options & 0x3ff;
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
* Copyright (c) 2009 Thomas Schmitt
|
* Copyright (c) 2009 - 2011 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* This file is part of the libisofs project; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License version 2
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -15,7 +15,14 @@
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_STDINT_H
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_INTTYPES_H
|
||||||
|
#include <inttypes.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
#define BLOCK_SIZE 2048
|
#define BLOCK_SIZE 2048
|
||||||
@ -154,6 +161,11 @@ struct iso_write_opts {
|
|||||||
*/
|
*/
|
||||||
unsigned int joliet_longer_paths :1;
|
unsigned int joliet_longer_paths :1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allow Joliet names up to 103 characters rather than 64.
|
||||||
|
*/
|
||||||
|
unsigned int joliet_long_names :1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write Rock Ridge info as of specification RRIP-1.10 rather than
|
* Write Rock Ridge info as of specification RRIP-1.10 rather than
|
||||||
* RRIP-1.12: signature "RRIP_1991A" rather than "IEEE_1282",
|
* RRIP-1.12: signature "RRIP_1991A" rather than "IEEE_1282",
|
||||||
@ -232,6 +244,16 @@ struct iso_write_opts {
|
|||||||
unsigned int replace_uid :2;
|
unsigned int replace_uid :2;
|
||||||
unsigned int replace_gid :2;
|
unsigned int replace_gid :2;
|
||||||
|
|
||||||
|
mode_t dir_mode; /** Mode to use on dirs when replace_dir_mode == 2. */
|
||||||
|
mode_t file_mode; /** Mode to use on files when replace_file_mode == 2. */
|
||||||
|
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
|
* Extra Caution: This option breaks any assumptions about names that
|
||||||
* are supported by ECMA-119 specifications.
|
* are supported by ECMA-119 specifications.
|
||||||
@ -247,11 +269,6 @@ struct iso_write_opts {
|
|||||||
*/
|
*/
|
||||||
unsigned int untranslated_name_len;
|
unsigned int untranslated_name_len;
|
||||||
|
|
||||||
mode_t dir_mode; /** Mode to use on dirs when replace_dir_mode == 2. */
|
|
||||||
mode_t file_mode; /** Mode to use on files when replace_file_mode == 2. */
|
|
||||||
uid_t uid; /** uid to use when replace_uid == 2. */
|
|
||||||
gid_t gid; /** gid to use when replace_gid == 2. */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 0 to use IsoNode timestamps, 1 to use recording time, 2 to use
|
* 0 to use IsoNode timestamps, 1 to use recording time, 2 to use
|
||||||
* values from timestamp field. This has only meaning if RR extensions
|
* values from timestamp field. This has only meaning if RR extensions
|
||||||
@ -447,6 +464,9 @@ struct ecma119_image
|
|||||||
/** Allow paths on Joliet tree to be larger than 240 bytes */
|
/** Allow paths on Joliet tree to be larger than 240 bytes */
|
||||||
unsigned int joliet_longer_paths :1;
|
unsigned int joliet_longer_paths :1;
|
||||||
|
|
||||||
|
/** Allow Joliet names up to 103 characters rather than 64 */
|
||||||
|
unsigned int joliet_long_names :1;
|
||||||
|
|
||||||
/** Write old fashioned RRIP-1.10 rather than RRIP-1.12 */
|
/** Write old fashioned RRIP-1.10 rather than RRIP-1.12 */
|
||||||
unsigned int rrip_version_1_10 :1;
|
unsigned int rrip_version_1_10 :1;
|
||||||
|
|
||||||
@ -472,14 +492,15 @@ struct ecma119_image
|
|||||||
unsigned int replace_dir_mode :1;
|
unsigned int replace_dir_mode :1;
|
||||||
unsigned int replace_timestamps :1;
|
unsigned int replace_timestamps :1;
|
||||||
|
|
||||||
unsigned int untranslated_name_len;
|
|
||||||
|
|
||||||
uid_t uid;
|
uid_t uid;
|
||||||
gid_t gid;
|
gid_t gid;
|
||||||
mode_t file_mode;
|
mode_t file_mode;
|
||||||
mode_t dir_mode;
|
mode_t dir_mode;
|
||||||
time_t timestamp;
|
time_t timestamp;
|
||||||
|
|
||||||
|
unsigned int old_empty :1;
|
||||||
|
unsigned int untranslated_name_len;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* if sort files or not. Sorting is based of the weight of each file
|
* if sort files or not. Sorting is based of the weight of each file
|
||||||
*/
|
*/
|
||||||
@ -512,6 +533,12 @@ struct ecma119_image
|
|||||||
*/
|
*/
|
||||||
uint32_t empty_file_block;
|
uint32_t empty_file_block;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The calculated block address after ECMA-119 tree and eventual
|
||||||
|
* tree checksum tag.
|
||||||
|
*/
|
||||||
|
uint32_t tree_end_block;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* number of dirs in ECMA-119 tree, computed together with dir position,
|
* number of dirs in ECMA-119 tree, computed together with dir position,
|
||||||
* and needed for path table computation in a efficient way
|
* and needed for path table computation in a efficient way
|
||||||
@ -556,19 +583,27 @@ struct ecma119_image
|
|||||||
*/
|
*/
|
||||||
char *system_area_data;
|
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
|
* Make bytes 446 - 512 of the system area a partition
|
||||||
* table which reserves partition 1 from byte 63*512 to the
|
* table which reserves partition 1 from byte 63*512 to the
|
||||||
* end of the ISO image. Assumed are 63 secs/hed, 255 head/cyl.
|
* end of the ISO image. Assumed are 63 secs/hed, 255 head/cyl.
|
||||||
* (GRUB protective msdos label.)
|
* (GRUB protective msdos label.)
|
||||||
* This works with and without system_area_data.
|
* 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.
|
* Apply isohybrid MBR patching to the system area.
|
||||||
* This works only with system_area_data plus ISOLINUX boot image
|
* This works only with system_area_data plus ISOLINUX boot image
|
||||||
* and only if not bit0 is set.
|
* and only if not bit0 is set.
|
||||||
* bit2-7= System area type
|
* bit2-7= System area type
|
||||||
* 0= DOS MBR
|
* 0= DOS MBR
|
||||||
* 1= MIPS Big Endian Volume Header
|
* 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;
|
int system_area_options;
|
||||||
|
|
||||||
|
@ -299,7 +299,7 @@ void ecma119_node_free(Ecma119Node *node)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (node->type == ECMA119_DIR) {
|
if (node->type == ECMA119_DIR) {
|
||||||
int i;
|
size_t i;
|
||||||
for (i = 0; i < node->info.dir->nchildren; i++) {
|
for (i = 0; i < node->info.dir->nchildren; i++) {
|
||||||
ecma119_node_free(node->info.dir->children[i]);
|
ecma119_node_free(node->info.dir->children[i]);
|
||||||
}
|
}
|
||||||
@ -643,7 +643,7 @@ int mangle_single_dir(Ecma119Image *img, Ecma119Node *dir, int max_file_len,
|
|||||||
max = max_file_len - digits;
|
max = max_file_len - digits;
|
||||||
}
|
}
|
||||||
name = full_name;
|
name = full_name;
|
||||||
if (max < strlen(name)) {
|
if ((size_t) max < strlen(name)) {
|
||||||
name[max] = '\0';
|
name[max] = '\0';
|
||||||
}
|
}
|
||||||
/* let ext be an empty string */
|
/* let ext be an empty string */
|
||||||
@ -1074,11 +1074,12 @@ int match_hardlinks(Ecma119Image *img, Ecma119Node *dir, int flag)
|
|||||||
iso_node_get_id(nodes[0]->node, &fs_id, &dev_id, &img_ino, 1);
|
iso_node_get_id(nodes[0]->node, &fs_id, &dev_id, &img_ino, 1);
|
||||||
family_start = 0;
|
family_start = 0;
|
||||||
for (i = 1; i < node_count; i++) {
|
for (i = 1; i < node_count; i++) {
|
||||||
if (ecma119_node_cmp_hard(nodes + (i - 1), nodes + i) == 0) {
|
if (nodes[i]->type != ECMA119_DIR &&
|
||||||
|
ecma119_node_cmp_hard(nodes + (i - 1), nodes + i) == 0) {
|
||||||
/* Still in same ino family */
|
/* Still in same ino family */
|
||||||
if (img_ino == 0) { /* Just in case any member knows its img_ino */
|
if (img_ino == 0) { /* Just in case any member knows its img_ino */
|
||||||
iso_node_get_id(nodes[0]->node, &fs_id, &dev_id, &img_ino, 1);
|
iso_node_get_id(nodes[0]->node, &fs_id, &dev_id, &img_ino, 1);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
family_set_ino(img, nodes, family_start, i, img_ino, prev_ino, 0);
|
family_set_ino(img, nodes, family_start, i, img_ino, prev_ino, 0);
|
||||||
|
@ -239,6 +239,7 @@ int iso_tree_add_boot_node(IsoDir *parent, const char *name, IsoBoot **boot)
|
|||||||
IsoBoot *node;
|
IsoBoot *node;
|
||||||
IsoNode **pos;
|
IsoNode **pos;
|
||||||
time_t now;
|
time_t now;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (parent == NULL || name == NULL || boot == NULL) {
|
if (parent == NULL || name == NULL || boot == NULL) {
|
||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
@ -248,9 +249,9 @@ int iso_tree_add_boot_node(IsoDir *parent, const char *name, IsoBoot **boot)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* check if the name is valid */
|
/* check if the name is valid */
|
||||||
if (!iso_node_is_valid_name(name)) {
|
ret = iso_node_is_valid_name(name);
|
||||||
return ISO_WRONG_ARG_VALUE;
|
if (ret < 0)
|
||||||
}
|
return ret;
|
||||||
|
|
||||||
/* find place where to insert */
|
/* find place where to insert */
|
||||||
pos = &(parent->children);
|
pos = &(parent->children);
|
||||||
@ -383,14 +384,14 @@ int create_image(IsoImage *image, const char *image_path,
|
|||||||
if (ret != sizeof(mbr)) {
|
if (ret != sizeof(mbr)) {
|
||||||
iso_msg_submit(image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
|
iso_msg_submit(image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
|
||||||
"Can't read MBR from image file.");
|
"Can't read MBR from image file.");
|
||||||
return ret < 0 ? ret : ISO_FILE_READ_ERROR;
|
return ret < 0 ? ret : (int) ISO_FILE_READ_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check valid MBR signature */
|
/* check valid MBR signature */
|
||||||
if ( mbr.sign1 != 0x55 || mbr.sign2 != 0xAA ) {
|
if ( mbr.sign1 != 0x55 || mbr.sign2 != 0xAA ) {
|
||||||
iso_msg_submit(image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
|
iso_msg_submit(image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
|
||||||
"Invalid MBR. Wrong signature.");
|
"Invalid MBR. Wrong signature.");
|
||||||
return ISO_BOOT_IMAGE_NOT_VALID;
|
return (int) ISO_BOOT_IMAGE_NOT_VALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ensure single partition */
|
/* ensure single partition */
|
||||||
@ -486,7 +487,7 @@ int iso_image_set_boot_image(IsoImage *image, const char *image_path,
|
|||||||
"Cannot find directory for El Torito boot catalog in ISO image: '%s'",
|
"Cannot find directory for El Torito boot catalog in ISO image: '%s'",
|
||||||
catdir);
|
catdir);
|
||||||
free(catdir);
|
free(catdir);
|
||||||
return ret < 0 ? ret : ISO_NODE_DOESNT_EXIST;
|
return ret < 0 ? ret : (int) ISO_NODE_DOESNT_EXIST;
|
||||||
}
|
}
|
||||||
if (p->type != LIBISO_DIR) {
|
if (p->type != LIBISO_DIR) {
|
||||||
free(catdir);
|
free(catdir);
|
||||||
@ -836,10 +837,10 @@ int catalog_open(IsoStream *stream)
|
|||||||
for (j = i + 1; j < cat->num_bootimages; j++) {
|
for (j = i + 1; j < cat->num_bootimages; j++) {
|
||||||
if (boots[i]->platform_id != boots[j]->platform_id)
|
if (boots[i]->platform_id != boots[j]->platform_id)
|
||||||
break;
|
break;
|
||||||
for (k = 0; k < sizeof(boots[i]->id_string); k++)
|
for (k = 0; k < (int) sizeof(boots[i]->id_string); k++)
|
||||||
if (boots[i]->id_string[k] != boots[j]->id_string[k])
|
if (boots[i]->id_string[k] != boots[j]->id_string[k])
|
||||||
break;
|
break;
|
||||||
if (k < sizeof(boots[i]->id_string))
|
if (k < (int) sizeof(boots[i]->id_string))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
num_entries = j - i;
|
num_entries = j - i;
|
||||||
@ -895,7 +896,7 @@ int catalog_read(IsoStream *stream, void *buf, size_t count)
|
|||||||
return ISO_FILE_NOT_OPENED;
|
return ISO_FILE_NOT_OPENED;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = MIN(count, BLOCK_SIZE - data->offset);
|
len = MIN(count, (size_t) (BLOCK_SIZE - data->offset));
|
||||||
memcpy(buf, data->buffer + data->offset, len);
|
memcpy(buf, data->buffer + data->offset, len);
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
@ -935,7 +936,11 @@ IsoStreamIface catalog_stream_class = {
|
|||||||
catalog_read,
|
catalog_read,
|
||||||
catalog_is_repeatable,
|
catalog_is_repeatable,
|
||||||
catalog_get_id,
|
catalog_get_id,
|
||||||
catalog_free
|
catalog_free,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1126,8 +1131,8 @@ int eltorito_writer_compute_data_blocks(IsoImageWriter *writer)
|
|||||||
}
|
}
|
||||||
ret = iso_stream_read(original, buf, size);
|
ret = iso_stream_read(original, buf, size);
|
||||||
iso_stream_close(original);
|
iso_stream_close(original);
|
||||||
if (ret != size) {
|
if (ret != (int) size) {
|
||||||
return (ret < 0) ? ret : ISO_FILE_READ_ERROR;
|
return (ret < 0) ? ret : (int) ISO_FILE_READ_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ok, patch the read buffer */
|
/* ok, patch the read buffer */
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* 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
|
* This file is part of the libisofs project; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License version 2
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -232,6 +232,12 @@ int filesrc_writer_compute_data_blocks(IsoImageWriter *writer)
|
|||||||
|
|
||||||
t = writer->target;
|
t = writer->target;
|
||||||
|
|
||||||
|
/* Normally reserve a single zeroed block for all files which have
|
||||||
|
no block address: symbolic links, device files, empty data files.
|
||||||
|
*/
|
||||||
|
if (! t->old_empty)
|
||||||
|
t->curblock++;
|
||||||
|
|
||||||
/* on appendable images, ms files shouldn't be included */
|
/* on appendable images, ms files shouldn't be included */
|
||||||
if (t->appendable) {
|
if (t->appendable) {
|
||||||
inc_item = is_ms_file;
|
inc_item = is_ms_file;
|
||||||
@ -329,11 +335,11 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
|
|||||||
{
|
{
|
||||||
int res, ret, was_error;
|
int res, ret, was_error;
|
||||||
size_t i, b;
|
size_t i, b;
|
||||||
Ecma119Image *t;
|
Ecma119Image *t = NULL;
|
||||||
IsoFileSrc *file;
|
IsoFileSrc *file;
|
||||||
IsoFileSrc **filelist;
|
IsoFileSrc **filelist;
|
||||||
char name[PATH_MAX];
|
char *name = NULL;
|
||||||
char buffer[BLOCK_SIZE];
|
char *buffer = NULL;
|
||||||
off_t file_size;
|
off_t file_size;
|
||||||
uint32_t nblocks;
|
uint32_t nblocks;
|
||||||
void *ctx= NULL;
|
void *ctx= NULL;
|
||||||
@ -344,14 +350,26 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (writer == NULL) {
|
if (writer == NULL) {
|
||||||
return ISO_ASSERT_FAILURE;
|
ret = ISO_ASSERT_FAILURE; goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LIBISO_ALLOC_MEM(name, char, PATH_MAX);
|
||||||
|
LIBISO_ALLOC_MEM(buffer, char, BLOCK_SIZE);
|
||||||
t = writer->target;
|
t = writer->target;
|
||||||
filelist = writer->data;
|
filelist = writer->data;
|
||||||
|
|
||||||
iso_msg_debug(t->image->id, "Writing Files...");
|
iso_msg_debug(t->image->id, "Writing Files...");
|
||||||
|
|
||||||
|
/* Normally write a single zeroed block as block address target for all
|
||||||
|
files which have no block address:
|
||||||
|
symbolic links, device files, empty data files.
|
||||||
|
*/
|
||||||
|
if (! t->old_empty) {
|
||||||
|
ret = iso_write(t, buffer, BLOCK_SIZE);
|
||||||
|
if (ret < 0)
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
while ((file = filelist[i++]) != NULL) {
|
while ((file = filelist[i++]) != NULL) {
|
||||||
was_error = 0;
|
was_error = 0;
|
||||||
@ -545,13 +563,15 @@ ex:;
|
|||||||
iso_md5_end(&ctx, md5);
|
iso_md5_end(&ctx, md5);
|
||||||
|
|
||||||
#ifdef Libisofs_with_libjtE
|
#ifdef Libisofs_with_libjtE
|
||||||
if (jte_begun) {
|
if (jte_begun && t != NULL) {
|
||||||
libjte_end_data_file(t->libjte_handle);
|
libjte_end_data_file(t->libjte_handle);
|
||||||
iso_libjte_forward_msgs(t->libjte_handle, t->image->id,
|
iso_libjte_forward_msgs(t->libjte_handle, t->image->id,
|
||||||
ISO_LIBJTE_END_FAILED, 0);
|
ISO_LIBJTE_END_FAILED, 0);
|
||||||
}
|
}
|
||||||
#endif /* Libisofs_with_libjtE */
|
#endif /* Libisofs_with_libjtE */
|
||||||
|
|
||||||
|
LIBISO_FREE_MEM(buffer);
|
||||||
|
LIBISO_FREE_MEM(name);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,7 +13,13 @@
|
|||||||
#include "stream.h"
|
#include "stream.h"
|
||||||
#include "ecma119.h"
|
#include "ecma119.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_STDINT_H
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_INTTYPES_H
|
||||||
|
#include <inttypes.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
struct Iso_File_Src
|
struct Iso_File_Src
|
||||||
{
|
{
|
||||||
|
@ -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
|
* This file is part of the libisofs project; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License version 2
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -20,6 +20,7 @@
|
|||||||
#include "../libisofs.h"
|
#include "../libisofs.h"
|
||||||
#include "../filter.h"
|
#include "../filter.h"
|
||||||
#include "../fsource.h"
|
#include "../fsource.h"
|
||||||
|
#include "../stream.h"
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
@ -40,7 +41,7 @@
|
|||||||
* for classical pipe filtering.
|
* for classical pipe filtering.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* IMPORTANT: Any change must be reflected by extf_clone_stream() */
|
||||||
/*
|
/*
|
||||||
* Individual runtime properties exist only as long as the stream is opened.
|
* Individual runtime properties exist only as long as the stream is opened.
|
||||||
*/
|
*/
|
||||||
@ -598,6 +599,36 @@ IsoStream *extf_get_input_stream(IsoStream *stream, int flag)
|
|||||||
return data->orig;
|
return data->orig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int extf_clone_stream(IsoStream *old_stream, IsoStream **new_stream, int flag)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
IsoStream *new_input_stream, *stream;
|
||||||
|
ExternalFilterStreamData *stream_data, *old_stream_data;
|
||||||
|
|
||||||
|
if (flag)
|
||||||
|
return ISO_STREAM_NO_CLONE; /* unknown option required */
|
||||||
|
|
||||||
|
stream_data = calloc(1, sizeof(ExternalFilterStreamData));
|
||||||
|
if (stream_data == NULL)
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
ret = iso_stream_clone_filter_common(old_stream, &stream,
|
||||||
|
&new_input_stream, 0);
|
||||||
|
if (ret < 0) {
|
||||||
|
free((char *) stream_data);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
old_stream_data = (ExternalFilterStreamData *) old_stream->data;
|
||||||
|
stream_data->id = ++extf_ino_id;
|
||||||
|
stream_data->orig = new_input_stream;
|
||||||
|
stream_data->cmd = old_stream_data->cmd;
|
||||||
|
stream_data->cmd->refcount++;
|
||||||
|
stream_data->size = old_stream_data->size;
|
||||||
|
stream_data->running = NULL;
|
||||||
|
stream->data = stream_data;
|
||||||
|
*new_stream = stream;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
int extf_cmp_ino(IsoStream *s1, IsoStream *s2);
|
int extf_cmp_ino(IsoStream *s1, IsoStream *s2);
|
||||||
@ -605,7 +636,7 @@ int extf_cmp_ino(IsoStream *s1, IsoStream *s2);
|
|||||||
|
|
||||||
|
|
||||||
IsoStreamIface extf_stream_class = {
|
IsoStreamIface extf_stream_class = {
|
||||||
3,
|
4,
|
||||||
"extf",
|
"extf",
|
||||||
extf_stream_open,
|
extf_stream_open,
|
||||||
extf_stream_close,
|
extf_stream_close,
|
||||||
@ -616,7 +647,8 @@ IsoStreamIface extf_stream_class = {
|
|||||||
extf_stream_free,
|
extf_stream_free,
|
||||||
extf_update_size,
|
extf_update_size,
|
||||||
extf_get_input_stream,
|
extf_get_input_stream,
|
||||||
extf_cmp_ino
|
extf_cmp_ino,
|
||||||
|
extf_clone_stream
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,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
|
* This file is part of the libisofs project; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License version 2
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -25,6 +25,7 @@
|
|||||||
#include "../filter.h"
|
#include "../filter.h"
|
||||||
#include "../fsource.h"
|
#include "../fsource.h"
|
||||||
#include "../util.h"
|
#include "../util.h"
|
||||||
|
#include "../stream.h"
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
@ -153,6 +154,7 @@ static int gzip_compression_level = 6;
|
|||||||
/*
|
/*
|
||||||
* The data payload of an individual Gzip Filter IsoStream
|
* The data payload of an individual Gzip Filter IsoStream
|
||||||
*/
|
*/
|
||||||
|
/* IMPORTANT: Any change must be reflected by gzip_clone_stream() */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
IsoStream *orig;
|
IsoStream *orig;
|
||||||
@ -392,7 +394,7 @@ int gzip_stream_convert(IsoStream *stream, void *buf, size_t desired, int flag)
|
|||||||
if (cnv_ret == Z_STREAM_ERROR || cnv_ret == Z_BUF_ERROR) {
|
if (cnv_ret == Z_STREAM_ERROR || cnv_ret == Z_BUF_ERROR) {
|
||||||
return (rng->error_ret = ISO_ZLIB_COMPR_ERR);
|
return (rng->error_ret = ISO_ZLIB_COMPR_ERR);
|
||||||
}
|
}
|
||||||
if (strm->avail_out < rng->out_buffer_size)
|
if ((int) strm->avail_out < rng->out_buffer_size)
|
||||||
break; /* output is available */
|
break; /* output is available */
|
||||||
if (strm->avail_in == 0) /* all pending input consumed */
|
if (strm->avail_in == 0) /* all pending input consumed */
|
||||||
break;
|
break;
|
||||||
@ -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
|
static
|
||||||
int gzip_cmp_ino(IsoStream *s1, IsoStream *s2);
|
int gzip_cmp_ino(IsoStream *s1, IsoStream *s2);
|
||||||
|
|
||||||
|
|
||||||
IsoStreamIface gzip_stream_compress_class = {
|
IsoStreamIface gzip_stream_compress_class = {
|
||||||
3,
|
4,
|
||||||
"gzip",
|
"gzip",
|
||||||
gzip_stream_open,
|
gzip_stream_open,
|
||||||
gzip_stream_close,
|
gzip_stream_close,
|
||||||
@ -545,12 +586,13 @@ IsoStreamIface gzip_stream_compress_class = {
|
|||||||
gzip_stream_free,
|
gzip_stream_free,
|
||||||
gzip_update_size,
|
gzip_update_size,
|
||||||
gzip_get_input_stream,
|
gzip_get_input_stream,
|
||||||
gzip_cmp_ino
|
gzip_cmp_ino,
|
||||||
|
gzip_clone_stream
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
IsoStreamIface gzip_stream_uncompress_class = {
|
IsoStreamIface gzip_stream_uncompress_class = {
|
||||||
3,
|
4,
|
||||||
"pizg",
|
"pizg",
|
||||||
gzip_stream_open,
|
gzip_stream_open,
|
||||||
gzip_stream_close,
|
gzip_stream_close,
|
||||||
@ -561,7 +603,8 @@ IsoStreamIface gzip_stream_uncompress_class = {
|
|||||||
gzip_stream_free,
|
gzip_stream_free,
|
||||||
gzip_update_size,
|
gzip_update_size,
|
||||||
gzip_get_input_stream,
|
gzip_get_input_stream,
|
||||||
gzip_cmp_ino
|
gzip_cmp_ino,
|
||||||
|
gzip_clone_stream
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,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
|
* This file is part of the libisofs project; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License version 2
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -22,6 +22,7 @@
|
|||||||
#include "../filter.h"
|
#include "../filter.h"
|
||||||
#include "../fsource.h"
|
#include "../fsource.h"
|
||||||
#include "../util.h"
|
#include "../util.h"
|
||||||
|
#include "../stream.h"
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
@ -167,6 +168,7 @@ static int ziso_compression_level = 6;
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* The common data payload of an individual Zisofs Filter IsoStream
|
* The common data payload of an individual Zisofs Filter IsoStream
|
||||||
|
* IMPORTANT: Any change must be reflected by ziso_clone_stream().
|
||||||
*/
|
*/
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@ -183,6 +185,7 @@ typedef struct
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* The data payload of an individual Zisofs Filter Compressor IsoStream
|
* The data payload of an individual Zisofs Filter Compressor IsoStream
|
||||||
|
* IMPORTANT: Any change must be reflected by ziso_clone_stream().
|
||||||
*/
|
*/
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@ -198,6 +201,7 @@ typedef struct
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* The data payload of an individual Zisofs Filter Uncompressor IsoStream
|
* The data payload of an individual Zisofs Filter Uncompressor IsoStream
|
||||||
|
* IMPORTANT: Any change must be reflected by ziso_clone_stream().
|
||||||
*/
|
*/
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@ -572,7 +576,8 @@ int ziso_stream_uncompress(IsoStream *stream, void *buf, size_t desired)
|
|||||||
rng->block_pointers[i] =
|
rng->block_pointers[i] =
|
||||||
iso_read_lsb((uint8_t *) (rng->block_pointers + i), 4);
|
iso_read_lsb((uint8_t *) (rng->block_pointers + i), 4);
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
if (rng->block_pointers[i] - rng->block_pointers[i - 1]
|
if ((int) (rng->block_pointers[i] -
|
||||||
|
rng->block_pointers[i - 1])
|
||||||
> block_max)
|
> block_max)
|
||||||
block_max = rng->block_pointers[i]
|
block_max = rng->block_pointers[i]
|
||||||
- rng->block_pointers[i - 1];
|
- rng->block_pointers[i - 1];
|
||||||
@ -615,7 +620,7 @@ int ziso_stream_uncompress(IsoStream *stream, void *buf, size_t desired)
|
|||||||
if (ret != Z_OK)
|
if (ret != Z_OK)
|
||||||
return (rng->error_ret = ISO_ZLIB_COMPR_ERR);
|
return (rng->error_ret = ISO_ZLIB_COMPR_ERR);
|
||||||
rng->buffer_fill = buf_len;
|
rng->buffer_fill = buf_len;
|
||||||
if (buf_len < rng->block_size &&
|
if ((int) buf_len < rng->block_size &&
|
||||||
i != rng->block_pointer_fill - 1)
|
i != rng->block_pointer_fill - 1)
|
||||||
return (rng->error_ret = ISO_ZISOFS_WRONG_INPUT);
|
return (rng->error_ret = ISO_ZISOFS_WRONG_INPUT);
|
||||||
} else if(ret == 0) {
|
} else if(ret == 0) {
|
||||||
@ -779,13 +784,63 @@ IsoStream *ziso_get_input_stream(IsoStream *stream, int flag)
|
|||||||
return data->orig;
|
return data->orig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int ziso_clone_stream(IsoStream *old_stream, IsoStream **new_stream, int flag)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
IsoStream *new_input_stream = NULL, *stream = NULL;
|
||||||
|
ZisofsFilterStreamData *stream_data, *old_stream_data;
|
||||||
|
ZisofsUncomprStreamData *uncompr, *old_uncompr;
|
||||||
|
ZisofsComprStreamData *compr, *old_compr;
|
||||||
|
|
||||||
|
if (flag)
|
||||||
|
return ISO_STREAM_NO_CLONE; /* unknown option required */
|
||||||
|
|
||||||
|
ret = iso_stream_clone_filter_common(old_stream, &stream,
|
||||||
|
&new_input_stream, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (old_stream->class->read == &ziso_stream_uncompress) {
|
||||||
|
uncompr = calloc(1, sizeof(ZisofsUncomprStreamData));
|
||||||
|
if (uncompr == NULL)
|
||||||
|
goto no_mem;
|
||||||
|
stream_data = (ZisofsFilterStreamData *) uncompr;
|
||||||
|
old_uncompr = (ZisofsUncomprStreamData *) old_stream->data;
|
||||||
|
uncompr->header_size_div4 = old_uncompr->header_size_div4;
|
||||||
|
uncompr->block_size_log2 = old_uncompr->block_size_log2;
|
||||||
|
} else {
|
||||||
|
compr = calloc(1, sizeof(ZisofsComprStreamData));
|
||||||
|
if (compr == NULL)
|
||||||
|
goto no_mem;
|
||||||
|
stream_data = (ZisofsFilterStreamData *) compr;
|
||||||
|
old_compr = (ZisofsComprStreamData *) old_stream->data;
|
||||||
|
compr->orig_size = old_compr->orig_size;
|
||||||
|
compr->block_pointers = NULL;
|
||||||
|
}
|
||||||
|
old_stream_data = (ZisofsFilterStreamData *) old_stream->data;
|
||||||
|
stream_data->orig = new_input_stream;
|
||||||
|
stream_data->size = old_stream_data->size;
|
||||||
|
stream_data->running = NULL;
|
||||||
|
stream_data->id = ++ziso_ino_id;
|
||||||
|
stream->data = stream_data;
|
||||||
|
*new_stream = stream;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
no_mem:
|
||||||
|
if (new_input_stream != NULL)
|
||||||
|
iso_stream_unref(new_input_stream);
|
||||||
|
if (stream != NULL)
|
||||||
|
iso_stream_unref(stream);
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
int ziso_cmp_ino(IsoStream *s1, IsoStream *s2);
|
int ziso_cmp_ino(IsoStream *s1, IsoStream *s2);
|
||||||
|
|
||||||
|
|
||||||
IsoStreamIface ziso_stream_compress_class = {
|
IsoStreamIface ziso_stream_compress_class = {
|
||||||
3,
|
4,
|
||||||
"ziso",
|
"ziso",
|
||||||
ziso_stream_open,
|
ziso_stream_open,
|
||||||
ziso_stream_close,
|
ziso_stream_close,
|
||||||
@ -796,12 +851,13 @@ IsoStreamIface ziso_stream_compress_class = {
|
|||||||
ziso_stream_free,
|
ziso_stream_free,
|
||||||
ziso_update_size,
|
ziso_update_size,
|
||||||
ziso_get_input_stream,
|
ziso_get_input_stream,
|
||||||
ziso_cmp_ino
|
ziso_cmp_ino,
|
||||||
|
ziso_clone_stream
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
IsoStreamIface ziso_stream_uncompress_class = {
|
IsoStreamIface ziso_stream_uncompress_class = {
|
||||||
3,
|
4,
|
||||||
"osiz",
|
"osiz",
|
||||||
ziso_stream_open,
|
ziso_stream_open,
|
||||||
ziso_stream_close,
|
ziso_stream_close,
|
||||||
@ -812,7 +868,8 @@ IsoStreamIface ziso_stream_uncompress_class = {
|
|||||||
ziso_stream_free,
|
ziso_stream_free,
|
||||||
ziso_update_size,
|
ziso_update_size,
|
||||||
ziso_get_input_stream,
|
ziso_get_input_stream,
|
||||||
ziso_cmp_ino
|
ziso_cmp_ino,
|
||||||
|
ziso_clone_stream
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* 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
|
* This file is part of the libisofs project; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License version 2
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -35,11 +35,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
#ifndef PATH_MAX
|
|
||||||
#define PATH_MAX Libisofs_default_path_maX
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Options for image reading.
|
* Options for image reading.
|
||||||
* There are four kind of options:
|
* 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 nojoliet : 1; /*< Do not read Joliet extensions */
|
||||||
unsigned int noiso1999 : 1; /*< Do not read ISO 9660:1999 enhanced tree */
|
unsigned int noiso1999 : 1; /*< Do not read ISO 9660:1999 enhanced tree */
|
||||||
unsigned int noaaip : 1; /* Do not read AAIP extension for xattr and ACL */
|
unsigned int noaaip : 1; /* Do not read AAIP extension for xattr and ACL */
|
||||||
unsigned int nomd5 : 1; /* Do not read MD5 array */
|
unsigned int nomd5 : 2; /* Do not read MD5 array */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hand out new inode numbers and overwrite eventually read PX inode
|
* Hand out new inode numbers and overwrite eventually read PX inode
|
||||||
@ -267,7 +262,7 @@ typedef struct
|
|||||||
int aaip_load;
|
int aaip_load;
|
||||||
|
|
||||||
/** Whether the MD5 array shall be read if available.
|
/** Whether the MD5 array shall be read if available.
|
||||||
* 1 = yes , 0 = no
|
* 2 = yes, but do not check tags , 1 = yes , 0 = no
|
||||||
*/
|
*/
|
||||||
int md5_load;
|
int md5_load;
|
||||||
|
|
||||||
@ -317,6 +312,7 @@ typedef struct
|
|||||||
|
|
||||||
typedef struct image_fs_data ImageFileSourceData;
|
typedef struct image_fs_data ImageFileSourceData;
|
||||||
|
|
||||||
|
/* IMPORTANT: Any change must be reflected by ifs_clone_src */
|
||||||
struct image_fs_data
|
struct image_fs_data
|
||||||
{
|
{
|
||||||
IsoImageFilesystem *fs; /**< reference to the image it belongs to */
|
IsoImageFilesystem *fs; /**< reference to the image it belongs to */
|
||||||
@ -396,6 +392,8 @@ char* ifs_get_path(IsoFileSource *src)
|
|||||||
char *path, *new_path;
|
char *path, *new_path;
|
||||||
int pathlen;
|
int pathlen;
|
||||||
|
|
||||||
|
if (data->name == NULL)
|
||||||
|
return NULL;
|
||||||
path = ifs_get_path(data->parent);
|
path = ifs_get_path(data->parent);
|
||||||
if (path == NULL)
|
if (path == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -474,15 +472,16 @@ int read_dir(ImageFileSourceData *data)
|
|||||||
IsoImageFilesystem *fs;
|
IsoImageFilesystem *fs;
|
||||||
_ImageFsData *fsdata;
|
_ImageFsData *fsdata;
|
||||||
struct ecma119_dir_record *record;
|
struct ecma119_dir_record *record;
|
||||||
uint8_t buffer[BLOCK_SIZE];
|
uint8_t *buffer = NULL;
|
||||||
IsoFileSource *child = NULL;
|
IsoFileSource *child = NULL;
|
||||||
uint32_t pos = 0;
|
uint32_t pos = 0;
|
||||||
uint32_t tlen = 0;
|
uint32_t tlen = 0;
|
||||||
|
|
||||||
if (data == NULL) {
|
if (data == NULL) {
|
||||||
return ISO_NULL_POINTER;
|
ret = ISO_NULL_POINTER; goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LIBISO_ALLOC_MEM(buffer, uint8_t, BLOCK_SIZE);
|
||||||
fs = data->fs;
|
fs = data->fs;
|
||||||
fsdata = fs->data;
|
fsdata = fs->data;
|
||||||
|
|
||||||
@ -490,7 +489,7 @@ int read_dir(ImageFileSourceData *data)
|
|||||||
block = data->sections[0].block;
|
block = data->sections[0].block;
|
||||||
ret = fsdata->src->read_block(fsdata->src, block, buffer);
|
ret = fsdata->src->read_block(fsdata->src, block, buffer);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* "." entry, get size of the dir and skip */
|
/* "." entry, get size of the dir and skip */
|
||||||
@ -514,7 +513,7 @@ int read_dir(ImageFileSourceData *data)
|
|||||||
*/
|
*/
|
||||||
ret = fsdata->src->read_block(fsdata->src, ++block, buffer);
|
ret = fsdata->src->read_block(fsdata->src, ++block, buffer);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
goto ex;
|
||||||
}
|
}
|
||||||
tlen += 2048 - pos;
|
tlen += 2048 - pos;
|
||||||
pos = 0;
|
pos = 0;
|
||||||
@ -559,7 +558,7 @@ int read_dir(ImageFileSourceData *data)
|
|||||||
free(ifsdata);
|
free(ifsdata);
|
||||||
free(child);
|
free(child);
|
||||||
}
|
}
|
||||||
return ret;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add to the child list */
|
/* add to the child list */
|
||||||
@ -568,7 +567,7 @@ int read_dir(ImageFileSourceData *data)
|
|||||||
node = malloc(sizeof(struct child_list));
|
node = malloc(sizeof(struct child_list));
|
||||||
if (node == NULL) {
|
if (node == NULL) {
|
||||||
iso_file_source_unref(child);
|
iso_file_source_unref(child);
|
||||||
return ISO_OUT_OF_MEM;
|
{ret = ISO_OUT_OF_MEM; goto ex;}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Note that we insert in reverse order. This leads to faster
|
* Note that we insert in reverse order. This leads to faster
|
||||||
@ -585,7 +584,10 @@ int read_dir(ImageFileSourceData *data)
|
|||||||
pos += record->len_dr[0];
|
pos += record->len_dr[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
return ISO_SUCCESS;
|
ret = ISO_SUCCESS;
|
||||||
|
ex:;
|
||||||
|
LIBISO_FREE_MEM(buffer);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
@ -952,6 +954,7 @@ int ifs_readlink(IsoFileSource *src, char *buf, size_t bufsiz)
|
|||||||
{
|
{
|
||||||
char *dest;
|
char *dest;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
int ret;
|
||||||
ImageFileSourceData *data;
|
ImageFileSourceData *data;
|
||||||
|
|
||||||
if (src == NULL || buf == NULL || src->data == NULL) {
|
if (src == NULL || buf == NULL || src->data == NULL) {
|
||||||
@ -970,14 +973,15 @@ int ifs_readlink(IsoFileSource *src, char *buf, size_t bufsiz)
|
|||||||
|
|
||||||
dest = (char*)data->data.content;
|
dest = (char*)data->data.content;
|
||||||
len = strlen(dest);
|
len = strlen(dest);
|
||||||
if (bufsiz <= len) {
|
|
||||||
|
ret = ISO_SUCCESS;
|
||||||
|
if (len >= bufsiz) {
|
||||||
|
ret = ISO_RR_PATH_TOO_LONG;
|
||||||
len = bufsiz - 1;
|
len = bufsiz - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
strncpy(buf, dest, len);
|
strncpy(buf, dest, len);
|
||||||
buf[len] = '\0';
|
buf[len] = '\0';
|
||||||
|
return ret;
|
||||||
return ISO_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
@ -1043,10 +1047,87 @@ int ifs_get_aa_string(IsoFileSource *src, unsigned char **aa_string, int flag)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int ifs_clone_src(IsoFileSource *old_source,
|
||||||
|
IsoFileSource **new_source, int flag)
|
||||||
|
{
|
||||||
|
IsoFileSource *src = NULL;
|
||||||
|
ImageFileSourceData *old_data, *new_data = NULL;
|
||||||
|
char *new_name = NULL;
|
||||||
|
struct iso_file_section *new_sections = NULL;
|
||||||
|
void *new_aa_string = NULL;
|
||||||
|
int i, ret;
|
||||||
|
|
||||||
|
if (flag)
|
||||||
|
return ISO_STREAM_NO_CLONE; /* unknown option required */
|
||||||
|
|
||||||
|
old_data = (ImageFileSourceData *) old_source->data;
|
||||||
|
*new_source = NULL;
|
||||||
|
src = calloc(1, sizeof(IsoFileSource));
|
||||||
|
if (src == NULL)
|
||||||
|
goto no_mem;
|
||||||
|
new_name = strdup(old_data->name);
|
||||||
|
if (new_name == NULL)
|
||||||
|
goto no_mem;
|
||||||
|
new_data = calloc(1, sizeof(ImageFileSourceData));
|
||||||
|
|
||||||
|
if (new_data == NULL)
|
||||||
|
goto no_mem;
|
||||||
|
if (old_data->nsections > 0) {
|
||||||
|
new_sections = calloc(old_data->nsections,
|
||||||
|
sizeof(struct iso_file_section));
|
||||||
|
if (new_sections == NULL)
|
||||||
|
goto no_mem;
|
||||||
|
}
|
||||||
|
ret = aaip_xinfo_cloner(old_data->aa_string, &new_aa_string, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
goto no_mem;
|
||||||
|
|
||||||
|
new_data->fs = old_data->fs;
|
||||||
|
|
||||||
|
new_data->parent = old_data->parent;
|
||||||
|
|
||||||
|
memcpy(&(new_data->info), &(old_data->info), sizeof(struct stat));
|
||||||
|
new_data->name = new_name;
|
||||||
|
new_data->sections = new_sections;
|
||||||
|
new_data->nsections = old_data->nsections;
|
||||||
|
for (i = 0; i < new_data->nsections; i++)
|
||||||
|
memcpy(new_data->sections + i, old_data->sections + i,
|
||||||
|
sizeof(struct iso_file_section));
|
||||||
|
new_data->opened = old_data->opened;
|
||||||
|
#ifdef Libisofs_with_zliB
|
||||||
|
new_data->header_size_div4 = old_data->header_size_div4;
|
||||||
|
new_data->block_size_log2 = old_data->block_size_log2;
|
||||||
|
new_data->uncompressed_size = old_data->uncompressed_size;
|
||||||
|
#endif
|
||||||
|
new_data->data.content = NULL;
|
||||||
|
new_data->aa_string = (unsigned char *) new_aa_string;
|
||||||
|
|
||||||
|
src->class = old_source->class;
|
||||||
|
src->refcount = 1;
|
||||||
|
src->data = new_data;
|
||||||
|
*new_source = src;
|
||||||
|
iso_file_source_ref(new_data->parent);
|
||||||
|
iso_filesystem_ref(new_data->fs);
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
no_mem:;
|
||||||
|
if (src != NULL)
|
||||||
|
free((char *) src);
|
||||||
|
if (new_data != NULL)
|
||||||
|
free((char *) new_data);
|
||||||
|
if (new_name != NULL)
|
||||||
|
free(new_name);
|
||||||
|
if (new_sections != NULL)
|
||||||
|
free((char *) new_sections);
|
||||||
|
if (new_aa_string != NULL)
|
||||||
|
aaip_xinfo_func(new_aa_string, 1);
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
IsoFileSourceIface ifs_class = {
|
IsoFileSourceIface ifs_class = {
|
||||||
|
|
||||||
1, /* version */
|
2, /* version */
|
||||||
ifs_get_path,
|
ifs_get_path,
|
||||||
ifs_get_name,
|
ifs_get_name,
|
||||||
ifs_lstat,
|
ifs_lstat,
|
||||||
@ -1060,7 +1141,8 @@ IsoFileSourceIface ifs_class = {
|
|||||||
ifs_get_filesystem,
|
ifs_get_filesystem,
|
||||||
ifs_free,
|
ifs_free,
|
||||||
ifs_lseek,
|
ifs_lseek,
|
||||||
ifs_get_aa_string
|
ifs_get_aa_string,
|
||||||
|
ifs_clone_src
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1169,7 +1251,8 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
|||||||
int aa_done = 0;
|
int aa_done = 0;
|
||||||
char *cs_value = NULL;
|
char *cs_value = NULL;
|
||||||
size_t cs_value_length = 0;
|
size_t cs_value_length = 0;
|
||||||
char msg[160];
|
char *msg = NULL;
|
||||||
|
uint8_t *buffer = NULL;
|
||||||
|
|
||||||
int has_px = 0;
|
int has_px = 0;
|
||||||
|
|
||||||
@ -1179,7 +1262,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (fs == NULL || fs->data == NULL || record == NULL || src == NULL) {
|
if (fs == NULL || fs->data == NULL || record == NULL || src == NULL) {
|
||||||
return ISO_NULL_POINTER;
|
ret = ISO_NULL_POINTER; goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
fsdata = (_ImageFsData*)fs->data;
|
fsdata = (_ImageFsData*)fs->data;
|
||||||
@ -1198,7 +1281,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
|||||||
"in interleaved mode. We do not support this mode, as we think "
|
"in interleaved mode. We do not support this mode, as we think "
|
||||||
"it is not used. If you are reading this, then we are wrong :) "
|
"it is not used. If you are reading this, then we are wrong :) "
|
||||||
"Please contact libisofs developers, so we can fix this.");
|
"Please contact libisofs developers, so we can fix this.");
|
||||||
return ISO_UNSUPPORTED_ECMA119;
|
{ret = ISO_UNSUPPORTED_ECMA119; goto ex;}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1209,7 +1292,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
|||||||
iso_msg_submit(fsdata->msgid, ISO_UNSUPPORTED_ECMA119, 0,
|
iso_msg_submit(fsdata->msgid, ISO_UNSUPPORTED_ECMA119, 0,
|
||||||
"Unsupported image. This image has at least one file with "
|
"Unsupported image. This image has at least one file with "
|
||||||
"ECMA-119 Extended Attributes, that are not supported");
|
"ECMA-119 Extended Attributes, that are not supported");
|
||||||
return ISO_UNSUPPORTED_ECMA119;
|
{ret = ISO_UNSUPPORTED_ECMA119; goto ex;}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO #00013 : check for unsupported flags when reading a dir record */
|
/* TODO #00013 : check for unsupported flags when reading a dir record */
|
||||||
@ -1224,13 +1307,13 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
|||||||
if (new_name == NULL) {
|
if (new_name == NULL) {
|
||||||
iso_msg_submit(fsdata->msgid, ISO_WRONG_ECMA119, 0,
|
iso_msg_submit(fsdata->msgid, ISO_WRONG_ECMA119, 0,
|
||||||
"Cannot retrieve file name");
|
"Cannot retrieve file name");
|
||||||
return ISO_WRONG_ECMA119;
|
{ret = ISO_WRONG_ECMA119; goto ex;}
|
||||||
}
|
}
|
||||||
if (strcmp(new_name, data->name)) {
|
if (strcmp(new_name, data->name)) {
|
||||||
iso_msg_submit(fsdata->msgid, ISO_WRONG_ECMA119, 0,
|
iso_msg_submit(fsdata->msgid, ISO_WRONG_ECMA119, 0,
|
||||||
"Multi-extent file lacks last entry.");
|
"Multi-extent file lacks last entry.");
|
||||||
free(new_name);
|
free(new_name);
|
||||||
return ISO_WRONG_ECMA119;
|
{ret = ISO_WRONG_ECMA119; goto ex;}
|
||||||
}
|
}
|
||||||
free(new_name);
|
free(new_name);
|
||||||
}
|
}
|
||||||
@ -1245,7 +1328,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
|||||||
if (record->flags[0] & 0x02) {
|
if (record->flags[0] & 0x02) {
|
||||||
iso_msg_submit(fsdata->msgid, ISO_WRONG_ECMA119, 0,
|
iso_msg_submit(fsdata->msgid, ISO_WRONG_ECMA119, 0,
|
||||||
"Directories with more than one section are not allowed.");
|
"Directories with more than one section are not allowed.");
|
||||||
return ISO_WRONG_ECMA119;
|
{ret = ISO_WRONG_ECMA119; goto ex;}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*src == NULL) {
|
if (*src == NULL) {
|
||||||
@ -1286,7 +1369,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
|||||||
|
|
||||||
ifsdata->info.st_size += (off_t) ifsdata->sections[ifsdata->nsections].size;
|
ifsdata->info.st_size += (off_t) ifsdata->sections[ifsdata->nsections].size;
|
||||||
ifsdata->nsections++;
|
ifsdata->nsections++;
|
||||||
return 2;
|
{ret = 2; goto ex;}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1304,7 +1387,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
|||||||
iter = susp_iter_new(fsdata->src, record, fsdata->len_skp,
|
iter = susp_iter_new(fsdata->src, record, fsdata->len_skp,
|
||||||
fsdata->msgid);
|
fsdata->msgid);
|
||||||
if (iter == NULL) {
|
if (iter == NULL) {
|
||||||
return ISO_OUT_OF_MEM;
|
{ret = ISO_OUT_OF_MEM; goto ex;}
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((ret = susp_iter_next(iter, &sue)) > 0) {
|
while ((ret = susp_iter_next(iter, &sue)) > 0) {
|
||||||
@ -1373,7 +1456,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
|||||||
*/
|
*/
|
||||||
susp_iter_free(iter);
|
susp_iter_free(iter);
|
||||||
free(name);
|
free(name);
|
||||||
return 0; /* it's not an error */
|
{ret = 0; goto ex;} /* it's not an error */
|
||||||
} else if (SUSP_SIG(sue, 'C', 'L')) {
|
} else if (SUSP_SIG(sue, 'C', 'L')) {
|
||||||
/*
|
/*
|
||||||
* This entry is a placeholder for a relocated dir.
|
* This entry is a placeholder for a relocated dir.
|
||||||
@ -1505,13 +1588,14 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
|||||||
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
free(name);
|
free(name);
|
||||||
return ret;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((flag & 1) && aa_string != NULL) {
|
if ((flag & 1) && aa_string != NULL) {
|
||||||
ret = iso_aa_lookup_attr(aa_string, "isofs.cs",
|
ret = iso_aa_lookup_attr(aa_string, "isofs.cs",
|
||||||
&cs_value_length, &cs_value, 0);
|
&cs_value_length, &cs_value, 0);
|
||||||
if (ret == 1) {
|
if (ret == 1) {
|
||||||
|
LIBISO_ALLOC_MEM(msg, char, 160);
|
||||||
if (fsdata->auto_input_charset & 1) {
|
if (fsdata->auto_input_charset & 1) {
|
||||||
if (fsdata->input_charset != NULL)
|
if (fsdata->input_charset != NULL)
|
||||||
free(fsdata->input_charset);
|
free(fsdata->input_charset);
|
||||||
@ -1523,6 +1607,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
|||||||
sprintf(msg,
|
sprintf(msg,
|
||||||
"Character set name recorded in ISO image: '%.80s'",
|
"Character set name recorded in ISO image: '%.80s'",
|
||||||
cs_value);
|
cs_value);
|
||||||
|
free(cs_value);
|
||||||
}
|
}
|
||||||
iso_msgs_submit(0, msg, 0, "NOTE", 0);
|
iso_msgs_submit(0, msg, 0, "NOTE", 0);
|
||||||
cs_value = NULL;
|
cs_value = NULL;
|
||||||
@ -1544,7 +1629,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
|||||||
free(newname);
|
free(newname);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
free(name);
|
free(name);
|
||||||
return ret;
|
goto ex;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
free(name);
|
free(name);
|
||||||
@ -1566,7 +1651,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
|||||||
free(newlinkdest);
|
free(newlinkdest);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
free(name);
|
free(name);
|
||||||
return ret;
|
goto ex;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
free(linkdest);
|
free(linkdest);
|
||||||
@ -1599,15 +1684,17 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
|||||||
if (record->len_fi[0] == 1 && record->file_id[0] == 0) {
|
if (record->len_fi[0] == 1 && record->file_id[0] == 0) {
|
||||||
/* "." entry, we can call this for root node, so... */
|
/* "." entry, we can call this for root node, so... */
|
||||||
if (!(atts.st_mode & S_IFDIR)) {
|
if (!(atts.st_mode & S_IFDIR)) {
|
||||||
return iso_msg_submit(fsdata->msgid, ISO_WRONG_ECMA119, 0,
|
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_ECMA119, 0,
|
||||||
"Wrong ISO file name. \".\" not dir");
|
"Wrong ISO file name. \".\" not dir");
|
||||||
|
goto ex;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
name = get_name(fsdata, (char*)record->file_id, record->len_fi[0]);
|
name = get_name(fsdata, (char*)record->file_id, record->len_fi[0]);
|
||||||
if (name == NULL) {
|
if (name == NULL) {
|
||||||
return iso_msg_submit(fsdata->msgid, ISO_WRONG_ECMA119, 0,
|
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_ECMA119, 0,
|
||||||
"Cannot retrieve file name");
|
"Cannot retrieve file name");
|
||||||
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* remove trailing version number */
|
/* remove trailing version number */
|
||||||
@ -1633,24 +1720,24 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
|||||||
* Thus, we need to read attributes for this directory from the "."
|
* Thus, we need to read attributes for this directory from the "."
|
||||||
* entry of the relocated dir.
|
* entry of the relocated dir.
|
||||||
*/
|
*/
|
||||||
uint8_t buffer[BLOCK_SIZE];
|
|
||||||
|
|
||||||
|
LIBISO_ALLOC_MEM(buffer, uint8_t, BLOCK_SIZE);
|
||||||
ret = fsdata->src->read_block(fsdata->src, relocated_dir, buffer);
|
ret = fsdata->src->read_block(fsdata->src, relocated_dir, buffer);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = iso_file_source_new_ifs(fs, parent, (struct ecma119_dir_record*)
|
ret = iso_file_source_new_ifs(fs, parent, (struct ecma119_dir_record*)
|
||||||
buffer, src, 0);
|
buffer, src, 0);
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
return ret;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* but the real name is the name of the placeholder */
|
/* but the real name is the name of the placeholder */
|
||||||
ifsdata = (ImageFileSourceData*) (*src)->data;
|
ifsdata = (ImageFileSourceData*) (*src)->data;
|
||||||
ifsdata->name = name;
|
ifsdata->name = name;
|
||||||
|
|
||||||
return ISO_SUCCESS;
|
{ret = ISO_SUCCESS; goto ex;}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Production of missing inode numbers is delayed until the image is
|
/* Production of missing inode numbers is delayed until the image is
|
||||||
@ -1686,7 +1773,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
|||||||
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR, 0,
|
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR, 0,
|
||||||
"Link without destination.");
|
"Link without destination.");
|
||||||
free(name);
|
free(name);
|
||||||
return ret;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ok, we can now create the file source */
|
/* ok, we can now create the file source */
|
||||||
@ -1754,13 +1841,17 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
|||||||
ifsrc->refcount = 1;
|
ifsrc->refcount = 1;
|
||||||
|
|
||||||
*src = ifsrc;
|
*src = ifsrc;
|
||||||
return ISO_SUCCESS;
|
{ret = ISO_SUCCESS; goto ex;}
|
||||||
|
|
||||||
ifs_cleanup: ;
|
ifs_cleanup: ;
|
||||||
free(name);
|
free(name);
|
||||||
free(linkdest);
|
free(linkdest);
|
||||||
free(ifsdata);
|
free(ifsdata);
|
||||||
free(ifsrc);
|
free(ifsrc);
|
||||||
|
|
||||||
|
ex:;
|
||||||
|
LIBISO_FREE_MEM(msg);
|
||||||
|
LIBISO_FREE_MEM(buffer);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1769,25 +1860,26 @@ int ifs_get_root(IsoFilesystem *fs, IsoFileSource **root)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
_ImageFsData *data;
|
_ImageFsData *data;
|
||||||
uint8_t buffer[BLOCK_SIZE];
|
uint8_t *buffer = NULL;
|
||||||
|
|
||||||
if (fs == NULL || fs->data == NULL || root == NULL) {
|
if (fs == NULL || fs->data == NULL || root == NULL) {
|
||||||
return ISO_NULL_POINTER;
|
ret = ISO_NULL_POINTER; goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LIBISO_ALLOC_MEM(buffer, uint8_t, BLOCK_SIZE);
|
||||||
data = (_ImageFsData*)fs->data;
|
data = (_ImageFsData*)fs->data;
|
||||||
|
|
||||||
/* open the filesystem */
|
/* open the filesystem */
|
||||||
ret = ifs_fs_open((IsoImageFilesystem*)fs);
|
ret = ifs_fs_open((IsoImageFilesystem*)fs);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read extend for root record */
|
/* read extend for root record */
|
||||||
ret = data->src->read_block(data->src, data->iso_root_block, buffer);
|
ret = data->src->read_block(data->src, data->iso_root_block, buffer);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
ifs_fs_close((IsoImageFilesystem*)fs);
|
ifs_fs_close((IsoImageFilesystem*)fs);
|
||||||
return ret;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get root attributes from "." entry */
|
/* get root attributes from "." entry */
|
||||||
@ -1796,6 +1888,8 @@ int ifs_get_root(IsoFilesystem *fs, IsoFileSource **root)
|
|||||||
(struct ecma119_dir_record*) buffer, root, 1);
|
(struct ecma119_dir_record*) buffer, root, 1);
|
||||||
|
|
||||||
ifs_fs_close((IsoImageFilesystem*)fs);
|
ifs_fs_close((IsoImageFilesystem*)fs);
|
||||||
|
ex:;
|
||||||
|
LIBISO_FREE_MEM(buffer);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1998,14 +2092,15 @@ static
|
|||||||
int read_root_susp_entries(_ImageFsData *data, uint32_t block)
|
int read_root_susp_entries(_ImageFsData *data, uint32_t block)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
unsigned char buffer[2048];
|
unsigned char *buffer = NULL;
|
||||||
struct ecma119_dir_record *record;
|
struct ecma119_dir_record *record;
|
||||||
struct susp_sys_user_entry *sue;
|
struct susp_sys_user_entry *sue;
|
||||||
SuspIterator *iter;
|
SuspIterator *iter;
|
||||||
|
|
||||||
|
LIBISO_ALLOC_MEM(buffer, unsigned char, 2048);
|
||||||
ret = data->src->read_block(data->src, block, buffer);
|
ret = data->src->read_block(data->src, block, buffer);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* record will be the "." directory entry for the root record */
|
/* record will be the "." directory entry for the root record */
|
||||||
@ -2020,7 +2115,7 @@ int read_root_susp_entries(_ImageFsData *data, uint32_t block)
|
|||||||
|
|
||||||
iter = susp_iter_new(data->src, record, data->len_skp, data->msgid);
|
iter = susp_iter_new(data->src, record, data->len_skp, data->msgid);
|
||||||
if (iter == NULL) {
|
if (iter == NULL) {
|
||||||
return ISO_OUT_OF_MEM;
|
ret = ISO_OUT_OF_MEM; goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* first entry must be an SP system use entry */
|
/* first entry must be an SP system use entry */
|
||||||
@ -2028,11 +2123,11 @@ int read_root_susp_entries(_ImageFsData *data, uint32_t block)
|
|||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
/* error */
|
/* error */
|
||||||
susp_iter_free(iter);
|
susp_iter_free(iter);
|
||||||
return ret;
|
goto ex;
|
||||||
} else if (ret == 0 || !SUSP_SIG(sue, 'S', 'P') ) {
|
} else if (ret == 0 || !SUSP_SIG(sue, 'S', 'P') ) {
|
||||||
iso_msg_debug(data->msgid, "SUSP/RR is not being used.");
|
iso_msg_debug(data->msgid, "SUSP/RR is not being used.");
|
||||||
susp_iter_free(iter);
|
susp_iter_free(iter);
|
||||||
return ISO_SUCCESS;
|
{ret = ISO_SUCCESS; goto ex;}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* it is a SP system use entry */
|
/* it is a SP system use entry */
|
||||||
@ -2040,9 +2135,10 @@ int read_root_susp_entries(_ImageFsData *data, uint32_t block)
|
|||||||
|| sue->data.SP.ef[0] != 0xEF) {
|
|| sue->data.SP.ef[0] != 0xEF) {
|
||||||
|
|
||||||
susp_iter_free(iter);
|
susp_iter_free(iter);
|
||||||
return iso_msg_submit(data->msgid, ISO_UNSUPPORTED_SUSP, 0,
|
ret = iso_msg_submit(data->msgid, ISO_UNSUPPORTED_SUSP, 0,
|
||||||
"SUSP SP system use entry seems to be wrong. "
|
"SUSP SP system use entry seems to be wrong. "
|
||||||
"Ignoring Rock Ridge Extensions.");
|
"Ignoring Rock Ridge Extensions.");
|
||||||
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
iso_msg_debug(data->msgid, "SUSP/RR is being used.");
|
iso_msg_debug(data->msgid, "SUSP/RR is being used.");
|
||||||
@ -2127,10 +2223,13 @@ int read_root_susp_entries(_ImageFsData *data, uint32_t block)
|
|||||||
susp_iter_free(iter);
|
susp_iter_free(iter);
|
||||||
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ISO_SUCCESS;
|
ret = ISO_SUCCESS;
|
||||||
|
ex:
|
||||||
|
LIBISO_FREE_MEM(buffer);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
@ -2163,11 +2262,12 @@ int read_pvm(_ImageFsData *data, uint32_t block)
|
|||||||
int ret;
|
int ret;
|
||||||
struct ecma119_pri_vol_desc *pvm;
|
struct ecma119_pri_vol_desc *pvm;
|
||||||
struct ecma119_dir_record *rootdr;
|
struct ecma119_dir_record *rootdr;
|
||||||
uint8_t buffer[BLOCK_SIZE];
|
uint8_t *buffer = NULL;
|
||||||
|
|
||||||
|
LIBISO_ALLOC_MEM(buffer, uint8_t, BLOCK_SIZE);
|
||||||
ret = read_pvd_block(data->src, block, buffer, NULL);
|
ret = read_pvd_block(data->src, block, buffer, NULL);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
goto ex;
|
||||||
/* ok, it is a valid PVD */
|
/* ok, it is a valid PVD */
|
||||||
pvm = (struct ecma119_pri_vol_desc *)buffer;
|
pvm = (struct ecma119_pri_vol_desc *)buffer;
|
||||||
|
|
||||||
@ -2215,7 +2315,10 @@ int read_pvm(_ImageFsData *data, uint32_t block)
|
|||||||
* example.
|
* example.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
return ISO_SUCCESS;
|
ret = ISO_SUCCESS;
|
||||||
|
ex:;
|
||||||
|
LIBISO_FREE_MEM(buffer);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2229,12 +2332,13 @@ int read_el_torito_boot_catalog(_ImageFsData *data, uint32_t block)
|
|||||||
struct el_torito_validation_entry *ve;
|
struct el_torito_validation_entry *ve;
|
||||||
struct el_torito_section_header *sh;
|
struct el_torito_section_header *sh;
|
||||||
struct el_torito_section_entry *entry; /* also usable as default_entry */
|
struct el_torito_section_entry *entry; /* also usable as default_entry */
|
||||||
unsigned char buffer[BLOCK_SIZE];
|
unsigned char *buffer = NULL;
|
||||||
|
|
||||||
|
LIBISO_ALLOC_MEM(buffer, unsigned char, BLOCK_SIZE);
|
||||||
data->num_bootimgs = 0;
|
data->num_bootimgs = 0;
|
||||||
ret = data->src->read_block(data->src, block, buffer);
|
ret = data->src->read_block(data->src, block, buffer);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
ve = (struct el_torito_validation_entry*)buffer;
|
ve = (struct el_torito_validation_entry*)buffer;
|
||||||
@ -2245,7 +2349,7 @@ int read_el_torito_boot_catalog(_ImageFsData *data, uint32_t block)
|
|||||||
iso_msg_submit(data->msgid, ISO_WRONG_EL_TORITO, 0,
|
iso_msg_submit(data->msgid, ISO_WRONG_EL_TORITO, 0,
|
||||||
"Wrong or damaged El-Torito Catalog. El-Torito info "
|
"Wrong or damaged El-Torito Catalog. El-Torito info "
|
||||||
"will be ignored.");
|
"will be ignored.");
|
||||||
return ISO_WRONG_EL_TORITO;
|
{ret = ISO_WRONG_EL_TORITO; goto ex;}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check for a valid platform */
|
/* check for a valid platform */
|
||||||
@ -2253,7 +2357,7 @@ int read_el_torito_boot_catalog(_ImageFsData *data, uint32_t block)
|
|||||||
iso_msg_submit(data->msgid, ISO_UNSUPPORTED_EL_TORITO, 0,
|
iso_msg_submit(data->msgid, ISO_UNSUPPORTED_EL_TORITO, 0,
|
||||||
"Unsupported El-Torito platform. Only 80x86 and EFI are "
|
"Unsupported El-Torito platform. Only 80x86 and EFI are "
|
||||||
"supported. El-Torito info will be ignored.");
|
"supported. El-Torito info will be ignored.");
|
||||||
return ISO_UNSUPPORTED_EL_TORITO;
|
{ret = ISO_UNSUPPORTED_EL_TORITO; goto ex;}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ok, once we are here we assume it is a valid catalog */
|
/* ok, once we are here we assume it is a valid catalog */
|
||||||
@ -2306,7 +2410,10 @@ int read_el_torito_boot_catalog(_ImageFsData *data, uint32_t block)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
after_bootblocks:;
|
after_bootblocks:;
|
||||||
return ISO_SUCCESS;
|
ret = ISO_SUCCESS;
|
||||||
|
ex:;
|
||||||
|
LIBISO_FREE_MEM(buffer);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2320,11 +2427,12 @@ static
|
|||||||
int iso_src_check_sb_tree(IsoDataSource *src, uint32_t start_lba, int flag)
|
int iso_src_check_sb_tree(IsoDataSource *src, uint32_t start_lba, int flag)
|
||||||
{
|
{
|
||||||
int tag_type, ret;
|
int tag_type, ret;
|
||||||
char block[2048], md5[16];
|
char *block = NULL, md5[16];
|
||||||
int desired = (1 << 2);
|
int desired = (1 << 2);
|
||||||
void *ctx = NULL;
|
void *ctx = NULL;
|
||||||
uint32_t next_tag = 0, i;
|
uint32_t next_tag = 0, i;
|
||||||
|
|
||||||
|
LIBISO_ALLOC_MEM(block, char, 2048);
|
||||||
ret = iso_md5_start(&ctx);
|
ret = iso_md5_start(&ctx);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto ex;
|
goto ex;
|
||||||
@ -2339,7 +2447,12 @@ int iso_src_check_sb_tree(IsoDataSource *src, uint32_t start_lba, int flag)
|
|||||||
ret = iso_util_eval_md5_tag(block, desired, start_lba + i,
|
ret = iso_util_eval_md5_tag(block, desired, start_lba + i,
|
||||||
ctx, start_lba, &tag_type, &next_tag, 0);
|
ctx, start_lba, &tag_type, &next_tag, 0);
|
||||||
iso_md5_compute(ctx, block, 2048);
|
iso_md5_compute(ctx, block, 2048);
|
||||||
if (ret == ISO_MD5_AREA_CORRUPTED || ret == ISO_MD5_TAG_MISMATCH)
|
if (ret == (int) ISO_MD5_TAG_COPIED) {/* growing without emulated TOC */
|
||||||
|
ret = 2;
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
if (ret == (int) ISO_MD5_AREA_CORRUPTED ||
|
||||||
|
ret == (int) ISO_MD5_TAG_MISMATCH)
|
||||||
ret = ISO_SB_TREE_CORRUPTED;
|
ret = ISO_SB_TREE_CORRUPTED;
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto ex;
|
goto ex;
|
||||||
@ -2373,7 +2486,8 @@ int iso_src_check_sb_tree(IsoDataSource *src, uint32_t start_lba, int flag)
|
|||||||
}
|
}
|
||||||
ret = iso_util_eval_md5_tag(block, (1 << 3), start_lba + i - 1,
|
ret = iso_util_eval_md5_tag(block, (1 << 3), start_lba + i - 1,
|
||||||
ctx, start_lba, &tag_type, &next_tag, 0);
|
ctx, start_lba, &tag_type, &next_tag, 0);
|
||||||
if (ret == ISO_MD5_AREA_CORRUPTED || ret == ISO_MD5_TAG_MISMATCH)
|
if (ret == (int) ISO_MD5_AREA_CORRUPTED ||
|
||||||
|
ret == (int) ISO_MD5_TAG_MISMATCH)
|
||||||
ret = ISO_SB_TREE_CORRUPTED;
|
ret = ISO_SB_TREE_CORRUPTED;
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto ex;
|
goto ex;
|
||||||
@ -2382,6 +2496,7 @@ int iso_src_check_sb_tree(IsoDataSource *src, uint32_t start_lba, int flag)
|
|||||||
ex:
|
ex:
|
||||||
if (ctx != NULL)
|
if (ctx != NULL)
|
||||||
iso_md5_end(&ctx, md5);
|
iso_md5_end(&ctx, md5);
|
||||||
|
LIBISO_FREE_MEM(block);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2393,21 +2508,22 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
|
|||||||
uint32_t block;
|
uint32_t block;
|
||||||
IsoImageFilesystem *ifs;
|
IsoImageFilesystem *ifs;
|
||||||
_ImageFsData *data;
|
_ImageFsData *data;
|
||||||
uint8_t buffer[BLOCK_SIZE];
|
uint8_t *buffer = NULL;
|
||||||
|
|
||||||
if (src == NULL || opts == NULL || fs == NULL) {
|
if (src == NULL || opts == NULL || fs == NULL) {
|
||||||
return ISO_NULL_POINTER;
|
ret = ISO_NULL_POINTER; goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LIBISO_ALLOC_MEM(buffer, uint8_t, BLOCK_SIZE);
|
||||||
data = calloc(1, sizeof(_ImageFsData));
|
data = calloc(1, sizeof(_ImageFsData));
|
||||||
if (data == NULL) {
|
if (data == NULL) {
|
||||||
return ISO_OUT_OF_MEM;
|
ret = ISO_OUT_OF_MEM; goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
ifs = calloc(1, sizeof(IsoImageFilesystem));
|
ifs = calloc(1, sizeof(IsoImageFilesystem));
|
||||||
if (ifs == NULL) {
|
if (ifs == NULL) {
|
||||||
free(data);
|
free(data);
|
||||||
return ISO_OUT_OF_MEM;
|
{ret = ISO_OUT_OF_MEM; goto ex;}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get our ref to IsoDataSource */
|
/* get our ref to IsoDataSource */
|
||||||
@ -2425,7 +2541,12 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
|
|||||||
data->dir_mode = opts->dir_mode & ~S_IFMT;
|
data->dir_mode = opts->dir_mode & ~S_IFMT;
|
||||||
data->msgid = msgid;
|
data->msgid = msgid;
|
||||||
data->aaip_load = !opts->noaaip;
|
data->aaip_load = !opts->noaaip;
|
||||||
data->md5_load = !opts->nomd5;
|
if (opts->nomd5 == 0)
|
||||||
|
data->md5_load = 1;
|
||||||
|
else if (opts->nomd5 == 2)
|
||||||
|
data->md5_load = 2;
|
||||||
|
else
|
||||||
|
data->md5_load = 0;
|
||||||
data->aaip_version = -1;
|
data->aaip_version = -1;
|
||||||
data->make_new_ino = opts->make_new_ino;
|
data->make_new_ino = opts->make_new_ino;
|
||||||
data->num_bootimgs = 0;
|
data->num_bootimgs = 0;
|
||||||
@ -2453,7 +2574,7 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
|
|||||||
ifs->free = ifs_fs_free;
|
ifs->free = ifs_fs_free;
|
||||||
|
|
||||||
/* read Volume Descriptors and ensure it is a valid image */
|
/* read Volume Descriptors and ensure it is a valid image */
|
||||||
if (data->md5_load) {
|
if (data->md5_load == 1) {
|
||||||
/* From opts->block on : check for superblock and tree tags */;
|
/* From opts->block on : check for superblock and tree tags */;
|
||||||
ret = iso_src_check_sb_tree(src, opts->block, 0);
|
ret = iso_src_check_sb_tree(src, opts->block, 0);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@ -2504,8 +2625,8 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
|
|||||||
} else {
|
} else {
|
||||||
data->catblock = iso_read_lsb(vol->boot_catalog, 4);
|
data->catblock = iso_read_lsb(vol->boot_catalog, 4);
|
||||||
ret = read_el_torito_boot_catalog(data, data->catblock);
|
ret = read_el_torito_boot_catalog(data, data->catblock);
|
||||||
if (ret < 0 && ret != ISO_UNSUPPORTED_EL_TORITO &&
|
if (ret < 0 && ret != (int) ISO_UNSUPPORTED_EL_TORITO &&
|
||||||
ret != ISO_WRONG_EL_TORITO) {
|
ret != (int) ISO_WRONG_EL_TORITO) {
|
||||||
goto fs_cleanup;
|
goto fs_cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2626,11 +2747,14 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
|
|||||||
/* and finally return. Note that we keep the DataSource opened */
|
/* and finally return. Note that we keep the DataSource opened */
|
||||||
|
|
||||||
*fs = ifs;
|
*fs = ifs;
|
||||||
return ISO_SUCCESS;
|
{ret = ISO_SUCCESS; goto ex;}
|
||||||
|
|
||||||
fs_cleanup: ;
|
fs_cleanup: ;
|
||||||
ifs_fs_free(ifs);
|
ifs_fs_free(ifs);
|
||||||
free(ifs);
|
free(ifs);
|
||||||
|
|
||||||
|
ex:;
|
||||||
|
LIBISO_FREE_MEM(buffer);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2682,6 +2806,7 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
struct stat info;
|
struct stat info;
|
||||||
IsoNode *new;
|
IsoNode *new;
|
||||||
char *name;
|
char *name;
|
||||||
|
char *dest = NULL;
|
||||||
ImageFileSourceData *data;
|
ImageFileSourceData *data;
|
||||||
_ImageFsData *fsdata;
|
_ImageFsData *fsdata;
|
||||||
|
|
||||||
@ -2694,7 +2819,7 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
|
|
||||||
|
|
||||||
if (builder == NULL || src == NULL || node == NULL || src->data == NULL) {
|
if (builder == NULL || src == NULL || node == NULL || src->data == NULL) {
|
||||||
return ISO_NULL_POINTER;
|
ret = ISO_NULL_POINTER; goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
data = (ImageFileSourceData*)src->data;
|
data = (ImageFileSourceData*)src->data;
|
||||||
@ -2705,7 +2830,7 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
/* get info about source */
|
/* get info about source */
|
||||||
ret = iso_file_source_lstat(src, &info);
|
ret = iso_file_source_lstat(src, &info);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
new = NULL;
|
new = NULL;
|
||||||
@ -2723,7 +2848,7 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
"We can continue, but that could lead to "
|
"We can continue, but that could lead to "
|
||||||
"problems");
|
"problems");
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
goto ex;
|
||||||
}
|
}
|
||||||
iso_node_unref((IsoNode*)image->bootcat->node);
|
iso_node_unref((IsoNode*)image->bootcat->node);
|
||||||
}
|
}
|
||||||
@ -2734,7 +2859,7 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
if (new == NULL) {
|
if (new == NULL) {
|
||||||
ret = ISO_OUT_OF_MEM;
|
ret = ISO_OUT_OF_MEM;
|
||||||
free(name);
|
free(name);
|
||||||
return ret;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* and set the image node */
|
/* and set the image node */
|
||||||
@ -2748,7 +2873,7 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
ret = iso_file_source_stream_new(src, &stream);
|
ret = iso_file_source_stream_new(src, &stream);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
free(name);
|
free(name);
|
||||||
return ret;
|
goto ex;
|
||||||
}
|
}
|
||||||
/* take a ref to the src, as stream has taken our ref */
|
/* take a ref to the src, as stream has taken our ref */
|
||||||
iso_file_source_ref(src);
|
iso_file_source_ref(src);
|
||||||
@ -2757,7 +2882,7 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
if (file == NULL) {
|
if (file == NULL) {
|
||||||
free(name);
|
free(name);
|
||||||
iso_stream_unref(stream);
|
iso_stream_unref(stream);
|
||||||
return ISO_OUT_OF_MEM;
|
{ret = ISO_OUT_OF_MEM; goto ex;}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* mark file as from old session */
|
/* mark file as from old session */
|
||||||
@ -2781,7 +2906,7 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
free(name);
|
free(name);
|
||||||
iso_stream_unref(stream);
|
iso_stream_unref(stream);
|
||||||
return ret;
|
goto ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2812,7 +2937,7 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
free(name);
|
free(name);
|
||||||
iso_stream_unref(stream);
|
iso_stream_unref(stream);
|
||||||
return ret;
|
goto ex;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* and set the image node */
|
/* and set the image node */
|
||||||
@ -2829,7 +2954,7 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
new = calloc(1, sizeof(IsoDir));
|
new = calloc(1, sizeof(IsoDir));
|
||||||
if (new == NULL) {
|
if (new == NULL) {
|
||||||
free(name);
|
free(name);
|
||||||
return ISO_OUT_OF_MEM;
|
{ret = ISO_OUT_OF_MEM; goto ex;}
|
||||||
}
|
}
|
||||||
new->type = LIBISO_DIR;
|
new->type = LIBISO_DIR;
|
||||||
new->refcount = 0;
|
new->refcount = 0;
|
||||||
@ -2838,18 +2963,19 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
case S_IFLNK:
|
case S_IFLNK:
|
||||||
{
|
{
|
||||||
/* source is a symbolic link */
|
/* source is a symbolic link */
|
||||||
char dest[PATH_MAX];
|
|
||||||
IsoSymlink *link;
|
IsoSymlink *link;
|
||||||
|
|
||||||
ret = iso_file_source_readlink(src, dest, PATH_MAX);
|
LIBISO_ALLOC_MEM(dest, char, LIBISOFS_NODE_PATH_MAX);
|
||||||
|
|
||||||
|
ret = iso_file_source_readlink(src, dest, LIBISOFS_NODE_PATH_MAX);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
free(name);
|
free(name);
|
||||||
return ret;
|
goto ex;
|
||||||
}
|
}
|
||||||
link = calloc(1, sizeof(IsoSymlink));
|
link = calloc(1, sizeof(IsoSymlink));
|
||||||
if (link == NULL) {
|
if (link == NULL) {
|
||||||
free(name);
|
free(name);
|
||||||
return ISO_OUT_OF_MEM;
|
{ret = ISO_OUT_OF_MEM; goto ex;}
|
||||||
}
|
}
|
||||||
link->dest = strdup(dest);
|
link->dest = strdup(dest);
|
||||||
link->node.type = LIBISO_SYMLINK;
|
link->node.type = LIBISO_SYMLINK;
|
||||||
@ -2870,7 +2996,7 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
special = calloc(1, sizeof(IsoSpecial));
|
special = calloc(1, sizeof(IsoSpecial));
|
||||||
if (special == NULL) {
|
if (special == NULL) {
|
||||||
free(name);
|
free(name);
|
||||||
return ISO_OUT_OF_MEM;
|
{ret = ISO_OUT_OF_MEM; goto ex;}
|
||||||
}
|
}
|
||||||
special->dev = info.st_rdev;
|
special->dev = info.st_rdev;
|
||||||
special->node.type = LIBISO_SPECIAL;
|
special->node.type = LIBISO_SPECIAL;
|
||||||
@ -2912,13 +3038,15 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
}
|
}
|
||||||
|
|
||||||
*node = new;
|
*node = new;
|
||||||
return ISO_SUCCESS;
|
{ret = ISO_SUCCESS; goto ex;}
|
||||||
|
|
||||||
failure:;
|
failure:;
|
||||||
/* todo: stuff any possible memory leak here */
|
/* todo: stuff any possible memory leak here */
|
||||||
if (name != NULL)
|
if (name != NULL)
|
||||||
free(name);
|
free(name);
|
||||||
free(new);
|
free(new);
|
||||||
|
ex:;
|
||||||
|
LIBISO_FREE_MEM(dest);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3044,12 +3172,13 @@ int iso_image_eval_boot_info_table(IsoImage *image, struct iso_read_opts *opts,
|
|||||||
uint32_t img_lba, img_size, boot_pvd_found, image_pvd, alleged_size;
|
uint32_t img_lba, img_size, boot_pvd_found, image_pvd, alleged_size;
|
||||||
struct iso_file_section *sections = NULL;
|
struct iso_file_section *sections = NULL;
|
||||||
struct el_torito_boot_image *boot;
|
struct el_torito_boot_image *boot;
|
||||||
uint8_t *boot_image_buf = NULL, boot_info_found[16], buf[BLOCK_SIZE];
|
uint8_t *boot_image_buf = NULL, boot_info_found[16], *buf = NULL;
|
||||||
IsoStream *stream = NULL;
|
IsoStream *stream = NULL;
|
||||||
IsoFile *boot_file;
|
IsoFile *boot_file;
|
||||||
|
|
||||||
if (image->bootcat == NULL)
|
if (image->bootcat == NULL)
|
||||||
return ISO_SUCCESS;
|
{ret = ISO_SUCCESS; goto ex;}
|
||||||
|
LIBISO_ALLOC_MEM(buf, uint8_t, BLOCK_SIZE);
|
||||||
for (i = 0; i < image->bootcat->num_bootimages; i++) {
|
for (i = 0; i < image->bootcat->num_bootimages; i++) {
|
||||||
boot = image->bootcat->bootimages[i];
|
boot = image->bootcat->bootimages[i];
|
||||||
boot_file = boot->image;
|
boot_file = boot->image;
|
||||||
@ -3089,7 +3218,7 @@ int iso_image_eval_boot_info_table(IsoImage *image, struct iso_read_opts *opts,
|
|||||||
ret = iso_stream_read(stream, boot_image_buf + (img_size - todo),
|
ret = iso_stream_read(stream, boot_image_buf + (img_size - todo),
|
||||||
chunk);
|
chunk);
|
||||||
if (ret != chunk) {
|
if (ret != chunk) {
|
||||||
ret = (ret < 0) ? ret : ISO_FILE_READ_ERROR;
|
ret = (ret < 0) ? ret : (int) ISO_FILE_READ_ERROR;
|
||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
todo -= chunk;
|
todo -= chunk;
|
||||||
@ -3128,6 +3257,7 @@ ex:;
|
|||||||
free(boot_image_buf);
|
free(boot_image_buf);
|
||||||
if (stream != NULL)
|
if (stream != NULL)
|
||||||
iso_stream_close(stream);
|
iso_stream_close(stream);
|
||||||
|
LIBISO_FREE_MEM(buf);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3155,6 +3285,8 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
|
|||||||
size_t size;
|
size_t size;
|
||||||
void *ctx = NULL;
|
void *ctx = NULL;
|
||||||
char md5[16];
|
char md5[16];
|
||||||
|
struct el_torito_boot_catalog *catalog = NULL;
|
||||||
|
ElToritoBootImage *boot_image = NULL;
|
||||||
|
|
||||||
if (image == NULL || src == NULL || opts == NULL) {
|
if (image == NULL || src == NULL || opts == NULL) {
|
||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
@ -3242,8 +3374,6 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
|
|||||||
|
|
||||||
/* if old image has el-torito, add a new catalog */
|
/* if old image has el-torito, add a new catalog */
|
||||||
if (data->eltorito) {
|
if (data->eltorito) {
|
||||||
struct el_torito_boot_catalog *catalog;
|
|
||||||
ElToritoBootImage *boot_image= NULL;
|
|
||||||
|
|
||||||
catalog = calloc(1, sizeof(struct el_torito_boot_catalog));
|
catalog = calloc(1, sizeof(struct el_torito_boot_catalog));
|
||||||
if (catalog == NULL) {
|
if (catalog == NULL) {
|
||||||
@ -3269,11 +3399,13 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
|
|||||||
memcpy(boot_image->selection_crit, data->selection_crits, 20);
|
memcpy(boot_image->selection_crit, data->selection_crits, 20);
|
||||||
|
|
||||||
catalog->bootimages[catalog->num_bootimages] = boot_image;
|
catalog->bootimages[catalog->num_bootimages] = boot_image;
|
||||||
|
boot_image = NULL;
|
||||||
catalog->num_bootimages++;
|
catalog->num_bootimages++;
|
||||||
}
|
}
|
||||||
for ( ; idx < Libisofs_max_boot_imageS; idx++)
|
for ( ; idx < Libisofs_max_boot_imageS; idx++)
|
||||||
catalog->bootimages[idx] = NULL;
|
catalog->bootimages[idx] = NULL;
|
||||||
image->bootcat = catalog;
|
image->bootcat = catalog;
|
||||||
|
catalog = NULL; /* So it does not get freed */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* recursively add image */
|
/* recursively add image */
|
||||||
@ -3396,7 +3528,7 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Load from image->checksum_end_lba */;
|
/* Load from image->checksum_end_lba */;
|
||||||
for (i = 0; i < size; i++) {
|
for (i = 0; i < (int) size; i++) {
|
||||||
rpt = (uint8_t *) (image->checksum_array + i * 2048);
|
rpt = (uint8_t *) (image->checksum_array + i * 2048);
|
||||||
ret = src->read_block(src, image->checksum_end_lba + i, rpt);
|
ret = src->read_block(src, image->checksum_end_lba + i, rpt);
|
||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
@ -3409,7 +3541,7 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
|
|||||||
ret = ISO_OUT_OF_MEM;
|
ret = ISO_OUT_OF_MEM;
|
||||||
goto import_revert;
|
goto import_revert;
|
||||||
}
|
}
|
||||||
for (i = 0; i < image->checksum_idx_count - 1; i++)
|
for (i = 0; i < (int) image->checksum_idx_count - 1; i++)
|
||||||
iso_md5_compute(ctx, image->checksum_array + i * 16, 16);
|
iso_md5_compute(ctx, image->checksum_array + i * 16, 16);
|
||||||
iso_md5_end(&ctx, md5);
|
iso_md5_end(&ctx, md5);
|
||||||
for (i = 0; i < 16; i++)
|
for (i = 0; i < 16; i++)
|
||||||
@ -3452,6 +3584,10 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
|
|||||||
image->fs = fsback;
|
image->fs = fsback;
|
||||||
image->builder = blback;
|
image->builder = blback;
|
||||||
|
|
||||||
|
if (catalog != NULL)
|
||||||
|
el_torito_boot_catalog_free(catalog);
|
||||||
|
if (boot_image != NULL)
|
||||||
|
free((char *) boot_image);
|
||||||
iso_file_source_unref(newroot);
|
iso_file_source_unref(newroot);
|
||||||
fs->close(fs);
|
fs->close(fs);
|
||||||
iso_filesystem_unref(fs);
|
iso_filesystem_unref(fs);
|
||||||
@ -3603,7 +3739,7 @@ int iso_read_opts_set_no_md5(IsoReadOpts *opts, int no_md5)
|
|||||||
if (opts == NULL) {
|
if (opts == NULL) {
|
||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
}
|
}
|
||||||
opts->nomd5 = no_md5 ? 1 : 0;
|
opts->nomd5 = no_md5 == 2 ? 2 : no_md5 == 1 ? 1 : 0;
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ int iso_file_source_new_lfs(IsoFileSource *parent, const char *name,
|
|||||||
*/
|
*/
|
||||||
IsoFilesystem *lfs= NULL;
|
IsoFilesystem *lfs= NULL;
|
||||||
|
|
||||||
|
/* IMPORTANT: Any change must be reflected by lfs_clone_src() */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
/** reference to the parent (if root it points to itself) */
|
/** reference to the parent (if root it points to itself) */
|
||||||
@ -103,6 +103,8 @@ int lfs_lstat(IsoFileSource *src, struct stat *info)
|
|||||||
}
|
}
|
||||||
data = src->data;
|
data = src->data;
|
||||||
path = lfs_get_path(src);
|
path = lfs_get_path(src);
|
||||||
|
if (path == NULL)
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
|
||||||
if (lstat(path, info) != 0) {
|
if (lstat(path, info) != 0) {
|
||||||
int err;
|
int err;
|
||||||
@ -128,6 +130,7 @@ int lfs_lstat(IsoFileSource *src, struct stat *info)
|
|||||||
err = ISO_FILE_ERROR;
|
err = ISO_FILE_ERROR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
free(path);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
free(path);
|
free(path);
|
||||||
@ -145,6 +148,8 @@ int lfs_stat(IsoFileSource *src, struct stat *info)
|
|||||||
}
|
}
|
||||||
data = src->data;
|
data = src->data;
|
||||||
path = lfs_get_path(src);
|
path = lfs_get_path(src);
|
||||||
|
if (path == NULL)
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
|
||||||
if (stat(path, info) != 0) {
|
if (stat(path, info) != 0) {
|
||||||
int err;
|
int err;
|
||||||
@ -170,6 +175,7 @@ int lfs_stat(IsoFileSource *src, struct stat *info)
|
|||||||
err = ISO_FILE_ERROR;
|
err = ISO_FILE_ERROR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
free(path);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
free(path);
|
free(path);
|
||||||
@ -412,7 +418,7 @@ int lfs_readdir(IsoFileSource *src, IsoFileSource **child)
|
|||||||
static
|
static
|
||||||
int lfs_readlink(IsoFileSource *src, char *buf, size_t bufsiz)
|
int lfs_readlink(IsoFileSource *src, char *buf, size_t bufsiz)
|
||||||
{
|
{
|
||||||
int size;
|
int size, ret;
|
||||||
_LocalFsFileSource *data;
|
_LocalFsFileSource *data;
|
||||||
char *path;
|
char *path;
|
||||||
|
|
||||||
@ -431,7 +437,7 @@ int lfs_readlink(IsoFileSource *src, char *buf, size_t bufsiz)
|
|||||||
* invoke readlink, with bufsiz -1 to reserve an space for
|
* invoke readlink, with bufsiz -1 to reserve an space for
|
||||||
* the NULL character
|
* the NULL character
|
||||||
*/
|
*/
|
||||||
size = readlink(path, buf, bufsiz - 1);
|
size = readlink(path, buf, bufsiz);
|
||||||
free(path);
|
free(path);
|
||||||
if (size < 0) {
|
if (size < 0) {
|
||||||
/* error */
|
/* error */
|
||||||
@ -455,8 +461,13 @@ int lfs_readlink(IsoFileSource *src, char *buf, size_t bufsiz)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* NULL-terminate the buf */
|
/* NULL-terminate the buf */
|
||||||
|
ret = ISO_SUCCESS;
|
||||||
|
if ((size_t) size >= bufsiz) {
|
||||||
|
ret = ISO_RR_PATH_TOO_LONG;
|
||||||
|
size = bufsiz - 1;
|
||||||
|
}
|
||||||
buf[size] = '\0';
|
buf[size] = '\0';
|
||||||
return ISO_SUCCESS;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
@ -506,6 +517,10 @@ int lfs_get_aa_string(IsoFileSource *src, unsigned char **aa_string, int flag)
|
|||||||
to AAIP ACL representation. Clean out st_mode ACL entries.
|
to AAIP ACL representation. Clean out st_mode ACL entries.
|
||||||
*/
|
*/
|
||||||
path = iso_file_source_get_path(src);
|
path = iso_file_source_get_path(src);
|
||||||
|
if (path == NULL) {
|
||||||
|
ret = ISO_NULL_POINTER;
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
ret = aaip_get_attr_list(path, &num_attrs, &names,
|
ret = aaip_get_attr_list(path, &num_attrs, &names,
|
||||||
&value_lengths, &values,
|
&value_lengths, &values,
|
||||||
(!(flag & 2)) | 2 | (flag & 4) | 16);
|
(!(flag & 2)) | 2 | (flag & 4) | 16);
|
||||||
@ -534,10 +549,56 @@ ex:;
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int lfs_clone_src(IsoFileSource *old_source,
|
||||||
|
IsoFileSource **new_source, int flag)
|
||||||
|
{
|
||||||
|
IsoFileSource *src = NULL;
|
||||||
|
char *new_name = NULL;
|
||||||
|
_LocalFsFileSource *old_data, *new_data = NULL;
|
||||||
|
|
||||||
|
if (flag)
|
||||||
|
return ISO_STREAM_NO_CLONE; /* unknown option required */
|
||||||
|
|
||||||
|
old_data = (_LocalFsFileSource *) old_source->data;
|
||||||
|
*new_source = NULL;
|
||||||
|
src = calloc(1, sizeof(IsoFileSource));
|
||||||
|
if (src == NULL)
|
||||||
|
goto no_mem;
|
||||||
|
new_name = strdup(old_data->name);
|
||||||
|
if (new_name == NULL)
|
||||||
|
goto no_mem;
|
||||||
|
|
||||||
|
new_data = calloc(1, sizeof(_LocalFsFileSource));
|
||||||
|
if (new_data == NULL)
|
||||||
|
goto no_mem;
|
||||||
|
new_data->openned = 0;
|
||||||
|
new_data->info.fd = -1; /* the value does not matter with (openned == 0) */
|
||||||
|
new_data->name = new_name;
|
||||||
|
new_data->parent = old_data->parent;
|
||||||
|
|
||||||
|
src->class = old_source->class;
|
||||||
|
src->refcount = 1;
|
||||||
|
src->data = new_data;
|
||||||
|
*new_source = src;
|
||||||
|
|
||||||
|
iso_file_source_ref(new_data->parent);
|
||||||
|
iso_filesystem_ref(lfs);
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
no_mem:;
|
||||||
|
if (src != NULL)
|
||||||
|
free((char *) src);
|
||||||
|
if (new_data != NULL)
|
||||||
|
free((char *) new_data);
|
||||||
|
if (new_name != NULL)
|
||||||
|
free(new_name);
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
IsoFileSourceIface lfs_class = {
|
IsoFileSourceIface lfs_class = {
|
||||||
|
|
||||||
1, /* version */
|
2, /* version */
|
||||||
lfs_get_path,
|
lfs_get_path,
|
||||||
lfs_get_name,
|
lfs_get_name,
|
||||||
lfs_lstat,
|
lfs_lstat,
|
||||||
@ -551,7 +612,8 @@ IsoFileSourceIface lfs_class = {
|
|||||||
lfs_get_filesystem,
|
lfs_get_filesystem,
|
||||||
lfs_free,
|
lfs_free,
|
||||||
lfs_lseek,
|
lfs_lseek,
|
||||||
lfs_get_aa_string
|
lfs_get_aa_string,
|
||||||
|
lfs_clone_src
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
* Copyright (c) 2009 Thomas Schmitt
|
* Copyright (c) 2009 - 2011 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* This file is part of the libisofs project; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License version 2
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -33,9 +33,16 @@
|
|||||||
int iso_local_filesystem_new(IsoFilesystem **fs);
|
int iso_local_filesystem_new(IsoFilesystem **fs);
|
||||||
|
|
||||||
|
|
||||||
/* Rank two IsoFileSource by their eventual old image LBAs.
|
/* Rank two IsoFileSource of ifs_class by their eventual old image LBAs.
|
||||||
Other IsoFileSource classes will be ranked only roughly.
|
Other IsoFileSource classes will be ranked only roughly.
|
||||||
*/
|
*/
|
||||||
int iso_ifs_sections_cmp(IsoFileSource *s1, IsoFileSource *s2, int flag);
|
int iso_ifs_sections_cmp(IsoFileSource *s1, IsoFileSource *s2, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/* Create an independent copy of an ifs_class IsoFileSource.
|
||||||
|
*/
|
||||||
|
int iso_ifs_source_clone(IsoFileSource *old_source, IsoFileSource **new_source,
|
||||||
|
int flag);
|
||||||
|
|
||||||
|
|
||||||
#endif /*LIBISO_FSOURCE_H_*/
|
#endif /*LIBISO_FSOURCE_H_*/
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
* @param image
|
* @param image
|
||||||
* Location where the image pointer will be stored.
|
* Location where the image pointer will be stored.
|
||||||
* @return
|
* @return
|
||||||
* 1 sucess, < 0 error
|
* 1 success, < 0 error
|
||||||
*/
|
*/
|
||||||
int iso_image_new(const char *name, IsoImage **image)
|
int iso_image_new(const char *name, IsoImage **image)
|
||||||
{
|
{
|
||||||
@ -142,6 +142,8 @@ void iso_image_unref(IsoImage *image)
|
|||||||
free(image->biblio_file_id);
|
free(image->biblio_file_id);
|
||||||
if (image->used_inodes != NULL)
|
if (image->used_inodes != NULL)
|
||||||
free(image->used_inodes);
|
free(image->used_inodes);
|
||||||
|
if (image->system_area_data != NULL)
|
||||||
|
free(image->system_area_data);
|
||||||
iso_image_free_checksums(image, 0);
|
iso_image_free_checksums(image, 0);
|
||||||
free(image);
|
free(image);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
|
* Copyright (c) 2011 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* This file is part of the libisofs project; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License version 2
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -17,6 +18,7 @@
|
|||||||
#include "image.h"
|
#include "image.h"
|
||||||
#include "filesrc.h"
|
#include "filesrc.h"
|
||||||
#include "eltorito.h"
|
#include "eltorito.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -73,7 +75,7 @@ void iso1999_node_free(Iso1999Node *node)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (node->type == ISO1999_DIR) {
|
if (node->type == ISO1999_DIR) {
|
||||||
int i;
|
size_t i;
|
||||||
for (i = 0; i < node->info.dir->nchildren; i++) {
|
for (i = 0; i < node->info.dir->nchildren; i++) {
|
||||||
iso1999_node_free(node->info.dir->children[i]);
|
iso1999_node_free(node->info.dir->children[i]);
|
||||||
}
|
}
|
||||||
@ -307,7 +309,10 @@ int mangle_single_dir(Ecma119Image *img, Iso1999Node *dir)
|
|||||||
Iso1999Node **children;
|
Iso1999Node **children;
|
||||||
IsoHTable *table;
|
IsoHTable *table;
|
||||||
int need_sort = 0;
|
int need_sort = 0;
|
||||||
|
char *full_name = NULL, *tmp = NULL;
|
||||||
|
|
||||||
|
LIBISO_ALLOC_MEM(full_name, char, 208);
|
||||||
|
LIBISO_ALLOC_MEM(tmp, char, 208);
|
||||||
nchildren = dir->info.dir->nchildren;
|
nchildren = dir->info.dir->nchildren;
|
||||||
children = dir->info.dir->children;
|
children = dir->info.dir->children;
|
||||||
|
|
||||||
@ -315,19 +320,18 @@ int mangle_single_dir(Ecma119Image *img, Iso1999Node *dir)
|
|||||||
ret = iso_htable_create((nchildren * 100) / 80, iso_str_hash,
|
ret = iso_htable_create((nchildren * 100) / 80, iso_str_hash,
|
||||||
(compare_function_t)strcmp, &table);
|
(compare_function_t)strcmp, &table);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
goto ex;
|
||||||
}
|
}
|
||||||
for (i = 0; i < nchildren; ++i) {
|
for (i = 0; i < nchildren; ++i) {
|
||||||
char *name = children[i]->name;
|
char *name = children[i]->name;
|
||||||
ret = iso_htable_add(table, name, name);
|
ret = iso_htable_add(table, name, name);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
goto mangle_cleanup;
|
goto ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < nchildren; ++i) {
|
for (i = 0; i < nchildren; ++i) {
|
||||||
char *name, *ext;
|
char *name, *ext;
|
||||||
char full_name[208];
|
|
||||||
int max; /* computed max len for name, without extension */
|
int max; /* computed max len for name, without extension */
|
||||||
int j = i;
|
int j = i;
|
||||||
int digits = 1; /* characters to change per name */
|
int digits = 1; /* characters to change per name */
|
||||||
@ -384,7 +388,7 @@ int mangle_single_dir(Ecma119Image *img, Iso1999Node *dir)
|
|||||||
* This can't happen with current limit of digits.
|
* This can't happen with current limit of digits.
|
||||||
*/
|
*/
|
||||||
ret = ISO_ERROR;
|
ret = ISO_ERROR;
|
||||||
goto mangle_cleanup;
|
goto ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* ok, reduce name by digits */
|
/* ok, reduce name by digits */
|
||||||
@ -398,7 +402,7 @@ int mangle_single_dir(Ecma119Image *img, Iso1999Node *dir)
|
|||||||
}
|
}
|
||||||
max = 207 - digits;
|
max = 207 - digits;
|
||||||
name = full_name;
|
name = full_name;
|
||||||
if (max < strlen(name)) {
|
if ((size_t) max < strlen(name)) {
|
||||||
name[max] = '\0';
|
name[max] = '\0';
|
||||||
}
|
}
|
||||||
/* let ext be an empty string */
|
/* let ext be an empty string */
|
||||||
@ -408,7 +412,6 @@ int mangle_single_dir(Ecma119Image *img, Iso1999Node *dir)
|
|||||||
ok = 1;
|
ok = 1;
|
||||||
/* change name of each file */
|
/* change name of each file */
|
||||||
for (k = i; k <= j; ++k) {
|
for (k = i; k <= j; ++k) {
|
||||||
char tmp[208];
|
|
||||||
char fmt[16];
|
char fmt[16];
|
||||||
if (dot != NULL) {
|
if (dot != NULL) {
|
||||||
sprintf(fmt, "%%s%%0%dd.%%s", digits);
|
sprintf(fmt, "%%s%%0%dd.%%s", digits);
|
||||||
@ -431,7 +434,7 @@ int mangle_single_dir(Ecma119Image *img, Iso1999Node *dir)
|
|||||||
char *new = strdup(tmp);
|
char *new = strdup(tmp);
|
||||||
if (new == NULL) {
|
if (new == NULL) {
|
||||||
ret = ISO_OUT_OF_MEM;
|
ret = ISO_OUT_OF_MEM;
|
||||||
goto mangle_cleanup;
|
goto ex;
|
||||||
}
|
}
|
||||||
iso_msg_debug(img->image->id, "\"%s\" renamed to \"%s\"",
|
iso_msg_debug(img->image->id, "\"%s\" renamed to \"%s\"",
|
||||||
children[k]->name, new);
|
children[k]->name, new);
|
||||||
@ -459,7 +462,7 @@ int mangle_single_dir(Ecma119Image *img, Iso1999Node *dir)
|
|||||||
}
|
}
|
||||||
if (digits == 8) {
|
if (digits == 8) {
|
||||||
ret = ISO_MANGLE_TOO_MUCH_FILES;
|
ret = ISO_MANGLE_TOO_MUCH_FILES;
|
||||||
goto mangle_cleanup;
|
goto ex;
|
||||||
}
|
}
|
||||||
i = j;
|
i = j;
|
||||||
}
|
}
|
||||||
@ -473,8 +476,10 @@ int mangle_single_dir(Ecma119Image *img, Iso1999Node *dir)
|
|||||||
|
|
||||||
ret = ISO_SUCCESS;
|
ret = ISO_SUCCESS;
|
||||||
|
|
||||||
mangle_cleanup : ;
|
ex:;
|
||||||
iso_htable_destroy(table, NULL);
|
iso_htable_destroy(table, NULL);
|
||||||
|
LIBISO_FREE_MEM(tmp);
|
||||||
|
LIBISO_FREE_MEM(full_name);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -810,15 +815,15 @@ static
|
|||||||
int write_one_dir(Ecma119Image *t, Iso1999Node *dir)
|
int write_one_dir(Ecma119Image *t, Iso1999Node *dir)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
uint8_t buffer[BLOCK_SIZE];
|
uint8_t *buffer = NULL;
|
||||||
size_t i;
|
size_t i;
|
||||||
size_t fi_len, len;
|
size_t fi_len, len;
|
||||||
|
|
||||||
/* buf will point to current write position on buffer */
|
/* buf will point to current write position on buffer */
|
||||||
uint8_t *buf = buffer;
|
uint8_t *buf;
|
||||||
|
|
||||||
/* initialize buffer with 0s */
|
LIBISO_ALLOC_MEM(buffer, uint8_t, BLOCK_SIZE);
|
||||||
memset(buffer, 0, BLOCK_SIZE);
|
buf = buffer;
|
||||||
|
|
||||||
/* write the "." and ".." entries first */
|
/* write the "." and ".." entries first */
|
||||||
write_one_dir_record(t, dir, 0, buf, 1, 0);
|
write_one_dir_record(t, dir, 0, buf, 1, 0);
|
||||||
@ -840,7 +845,7 @@ int write_one_dir(Ecma119Image *t, Iso1999Node *dir)
|
|||||||
/* dir doesn't fit in current block */
|
/* dir doesn't fit in current block */
|
||||||
ret = iso_write(t, buffer, BLOCK_SIZE);
|
ret = iso_write(t, buffer, BLOCK_SIZE);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
goto ex;
|
||||||
}
|
}
|
||||||
memset(buffer, 0, BLOCK_SIZE);
|
memset(buffer, 0, BLOCK_SIZE);
|
||||||
buf = buffer;
|
buf = buffer;
|
||||||
@ -853,6 +858,8 @@ int write_one_dir(Ecma119Image *t, Iso1999Node *dir)
|
|||||||
|
|
||||||
/* write the last block */
|
/* write the last block */
|
||||||
ret = iso_write(t, buffer, BLOCK_SIZE);
|
ret = iso_write(t, buffer, BLOCK_SIZE);
|
||||||
|
ex:;
|
||||||
|
LIBISO_FREE_MEM(buffer);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -885,13 +892,17 @@ static
|
|||||||
int write_path_table(Ecma119Image *t, Iso1999Node **pathlist, int l_type)
|
int write_path_table(Ecma119Image *t, Iso1999Node **pathlist, int l_type)
|
||||||
{
|
{
|
||||||
size_t i, len;
|
size_t i, len;
|
||||||
uint8_t buf[256]; /* 256 is just a convenient size larger enought */
|
uint8_t *buf = NULL;
|
||||||
struct ecma119_path_table_record *rec;
|
struct ecma119_path_table_record *rec;
|
||||||
void (*write_int)(uint8_t*, uint32_t, int);
|
void (*write_int)(uint8_t*, uint32_t, int);
|
||||||
Iso1999Node *dir;
|
Iso1999Node *dir;
|
||||||
uint32_t path_table_size;
|
uint32_t path_table_size;
|
||||||
int parent = 0;
|
int parent = 0;
|
||||||
int ret= ISO_SUCCESS;
|
int ret= ISO_SUCCESS;
|
||||||
|
uint8_t *zeros = NULL;
|
||||||
|
|
||||||
|
/* 256 is just a convenient size large enought */
|
||||||
|
LIBISO_ALLOC_MEM(buf, uint8_t, 256);
|
||||||
|
|
||||||
path_table_size = 0;
|
path_table_size = 0;
|
||||||
write_int = l_type ? iso_lsb : iso_msb;
|
write_int = l_type ? iso_lsb : iso_msb;
|
||||||
@ -918,7 +929,7 @@ int write_path_table(Ecma119Image *t, Iso1999Node **pathlist, int l_type)
|
|||||||
ret = iso_write(t, buf, len);
|
ret = iso_write(t, buf, len);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
/* error */
|
/* error */
|
||||||
return ret;
|
goto ex;
|
||||||
}
|
}
|
||||||
path_table_size += len;
|
path_table_size += len;
|
||||||
}
|
}
|
||||||
@ -926,11 +937,14 @@ int write_path_table(Ecma119Image *t, Iso1999Node **pathlist, int l_type)
|
|||||||
/* we need to fill the last block with zeros */
|
/* we need to fill the last block with zeros */
|
||||||
path_table_size %= BLOCK_SIZE;
|
path_table_size %= BLOCK_SIZE;
|
||||||
if (path_table_size) {
|
if (path_table_size) {
|
||||||
uint8_t zeros[BLOCK_SIZE];
|
LIBISO_ALLOC_MEM(zeros, uint8_t, BLOCK_SIZE);
|
||||||
len = BLOCK_SIZE - path_table_size;
|
len = BLOCK_SIZE - path_table_size;
|
||||||
memset(zeros, 0, len);
|
memset(zeros, 0, len);
|
||||||
ret = iso_write(t, zeros, len);
|
ret = iso_write(t, zeros, len);
|
||||||
}
|
}
|
||||||
|
ex:;
|
||||||
|
LIBISO_FREE_MEM(zeros);
|
||||||
|
LIBISO_FREE_MEM(buf);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
* Copyright (c) 2007 Mario Danic
|
* Copyright (c) 2007 Mario Danic
|
||||||
|
* Copyright (c) 2011 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* This file is part of the libisofs project; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License version 2
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -19,6 +20,7 @@
|
|||||||
#include "filesrc.h"
|
#include "filesrc.h"
|
||||||
#include "eltorito.h"
|
#include "eltorito.h"
|
||||||
#include "libisofs.h"
|
#include "libisofs.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -42,12 +44,11 @@ int get_joliet_name(Ecma119Image *t, IsoNode *iso, uint16_t **name)
|
|||||||
iso_msg_debug(t->image->id, "Can't convert %s", iso->name);
|
iso_msg_debug(t->image->id, "Can't convert %s", iso->name);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO #00022 : support relaxed constraints in joliet filenames */
|
|
||||||
if (iso->type == LIBISO_DIR) {
|
if (iso->type == LIBISO_DIR) {
|
||||||
jname = iso_j_dir_id(ucs_name);
|
jname = iso_j_dir_id(ucs_name, t->joliet_long_names << 1);
|
||||||
} else {
|
} else {
|
||||||
jname = iso_j_file_id(ucs_name, !!(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);
|
free(ucs_name);
|
||||||
if (jname != NULL) {
|
if (jname != NULL) {
|
||||||
@ -69,7 +70,7 @@ void joliet_node_free(JolietNode *node)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (node->type == JOLIET_DIR) {
|
if (node->type == JOLIET_DIR) {
|
||||||
int i;
|
size_t i;
|
||||||
for (i = 0; i < node->info.dir->nchildren; i++) {
|
for (i = 0; i < node->info.dir->nchildren; i++) {
|
||||||
joliet_node_free(node->info.dir->children[i]);
|
joliet_node_free(node->info.dir->children[i]);
|
||||||
}
|
}
|
||||||
@ -303,8 +304,15 @@ int joliet_create_mangled_name(uint16_t *dest, uint16_t *src, int digits,
|
|||||||
int ret, pos;
|
int ret, pos;
|
||||||
uint16_t *ucsnumber;
|
uint16_t *ucsnumber;
|
||||||
char fmt[16];
|
char fmt[16];
|
||||||
char nstr[72]; /* The only caller of this function allocates dest with 66
|
char nstr[72];
|
||||||
elements and limits digits to < 8 */
|
/* was: The only caller of this function allocates dest
|
||||||
|
with 66 elements and limits digits to < 8
|
||||||
|
But this does not match the usage of nstr which has to take
|
||||||
|
the decimal representation of an int.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (digits >= 8)
|
||||||
|
return ISO_ASSERT_FAILURE;
|
||||||
|
|
||||||
sprintf(fmt, "%%0%dd", digits);
|
sprintf(fmt, "%%0%dd", digits);
|
||||||
sprintf(nstr, fmt, number);
|
sprintf(nstr, fmt, number);
|
||||||
@ -337,19 +345,26 @@ static
|
|||||||
int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
|
int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
int i, nchildren;
|
int i, nchildren, maxchar = 64;
|
||||||
JolietNode **children;
|
JolietNode **children;
|
||||||
IsoHTable *table;
|
IsoHTable *table;
|
||||||
int need_sort = 0;
|
int need_sort = 0;
|
||||||
|
uint16_t *full_name = NULL;
|
||||||
|
uint16_t *tmp = NULL;
|
||||||
|
|
||||||
|
LIBISO_ALLOC_MEM(full_name, uint16_t, LIBISO_JOLIET_NAME_MAX);
|
||||||
|
LIBISO_ALLOC_MEM(tmp, uint16_t, LIBISO_JOLIET_NAME_MAX);
|
||||||
nchildren = dir->info.dir->nchildren;
|
nchildren = dir->info.dir->nchildren;
|
||||||
children = dir->info.dir->children;
|
children = dir->info.dir->children;
|
||||||
|
|
||||||
|
if (t->joliet_long_names)
|
||||||
|
maxchar = 103;
|
||||||
|
|
||||||
/* a hash table will temporary hold the names, for fast searching */
|
/* a hash table will temporary hold the names, for fast searching */
|
||||||
ret = iso_htable_create((nchildren * 100) / 80, iso_str_hash,
|
ret = iso_htable_create((nchildren * 100) / 80, iso_str_hash,
|
||||||
(compare_function_t)ucscmp, &table);
|
(compare_function_t)ucscmp, &table);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
goto ex;
|
||||||
}
|
}
|
||||||
for (i = 0; i < nchildren; ++i) {
|
for (i = 0; i < nchildren; ++i) {
|
||||||
uint16_t *name = children[i]->name;
|
uint16_t *name = children[i]->name;
|
||||||
@ -361,7 +376,6 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
|
|||||||
|
|
||||||
for (i = 0; i < nchildren; ++i) {
|
for (i = 0; i < nchildren; ++i) {
|
||||||
uint16_t *name, *ext;
|
uint16_t *name, *ext;
|
||||||
uint16_t full_name[66];
|
|
||||||
int max; /* computed max len for name, without extension */
|
int max; /* computed max len for name, without extension */
|
||||||
int j = i;
|
int j = i;
|
||||||
int digits = 1; /* characters to change per name */
|
int digits = 1; /* characters to change per name */
|
||||||
@ -380,7 +394,7 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
|
|||||||
* A max of 7 characters is good enought, it allows handling up to
|
* A max of 7 characters is good enought, it allows handling up to
|
||||||
* 9,999,999 files with same name.
|
* 9,999,999 files with same name.
|
||||||
*/
|
*/
|
||||||
/* Important: joliet_create_mangled_name() relies on digits < 72 */
|
/* Important: joliet_create_mangled_name() relies on digits < 8 */
|
||||||
|
|
||||||
while (digits < 8) {
|
while (digits < 8) {
|
||||||
int ok, k;
|
int ok, k;
|
||||||
@ -403,7 +417,7 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
|
|||||||
ext = dot + 1;
|
ext = dot + 1;
|
||||||
|
|
||||||
extlen = ucslen(ext);
|
extlen = ucslen(ext);
|
||||||
max = 65 - extlen - 1 - digits;
|
max = maxchar + 1 - extlen - 1 - digits;
|
||||||
if (max <= 0) {
|
if (max <= 0) {
|
||||||
/* this can happen if extension is too long */
|
/* this can happen if extension is too long */
|
||||||
if (extlen + max > 3) {
|
if (extlen + max > 3) {
|
||||||
@ -413,7 +427,7 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
|
|||||||
*/
|
*/
|
||||||
extlen = extlen + max - 1;
|
extlen = extlen + max - 1;
|
||||||
ext[extlen] = 0;
|
ext[extlen] = 0;
|
||||||
max = 66 - extlen - 1 - digits;
|
max = maxchar + 2 - extlen - 1 - digits;
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* error, we don't support extensions < 3
|
* error, we don't support extensions < 3
|
||||||
@ -430,13 +444,13 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
|
|||||||
} else {
|
} else {
|
||||||
/* Directory, or file without extension */
|
/* Directory, or file without extension */
|
||||||
if (children[i]->type == JOLIET_DIR) {
|
if (children[i]->type == JOLIET_DIR) {
|
||||||
max = 65 - digits;
|
max = maxchar + 1 - digits;
|
||||||
dot = NULL; /* dots have no meaning in dirs */
|
dot = NULL; /* dots have no meaning in dirs */
|
||||||
} else {
|
} else {
|
||||||
max = 65 - digits;
|
max = maxchar + 1 - digits;
|
||||||
}
|
}
|
||||||
name = full_name;
|
name = full_name;
|
||||||
if (max < ucslen(name)) {
|
if ((size_t) max < ucslen(name)) {
|
||||||
name[max] = 0;
|
name[max] = 0;
|
||||||
}
|
}
|
||||||
/* let ext be an empty string */
|
/* let ext be an empty string */
|
||||||
@ -446,7 +460,6 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
|
|||||||
ok = 1;
|
ok = 1;
|
||||||
/* change name of each file */
|
/* change name of each file */
|
||||||
for (k = i; k <= j; ++k) {
|
for (k = i; k <= j; ++k) {
|
||||||
uint16_t tmp[66];
|
|
||||||
while (1) {
|
while (1) {
|
||||||
ret = joliet_create_mangled_name(tmp, name, digits,
|
ret = joliet_create_mangled_name(tmp, name, digits,
|
||||||
change, ext);
|
change, ext);
|
||||||
@ -508,7 +521,10 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
|
|||||||
ret = ISO_SUCCESS;
|
ret = ISO_SUCCESS;
|
||||||
|
|
||||||
mangle_cleanup : ;
|
mangle_cleanup : ;
|
||||||
|
ex:;
|
||||||
iso_htable_destroy(table, NULL);
|
iso_htable_destroy(table, NULL);
|
||||||
|
LIBISO_FREE_MEM(tmp);
|
||||||
|
LIBISO_FREE_MEM(full_name);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -909,15 +925,16 @@ static
|
|||||||
int write_one_dir(Ecma119Image *t, JolietNode *dir)
|
int write_one_dir(Ecma119Image *t, JolietNode *dir)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
uint8_t buffer[BLOCK_SIZE];
|
uint8_t *buffer = NULL;
|
||||||
size_t i;
|
size_t i;
|
||||||
size_t fi_len, len;
|
size_t fi_len, len;
|
||||||
|
|
||||||
/* buf will point to current write position on buffer */
|
/* buf will point to current write position on buffer */
|
||||||
uint8_t *buf = buffer;
|
uint8_t *buf;
|
||||||
|
|
||||||
/* initialize buffer with 0s */
|
/* initialize buffer with 0s */
|
||||||
memset(buffer, 0, BLOCK_SIZE);
|
LIBISO_ALLOC_MEM(buffer, uint8_t, BLOCK_SIZE);
|
||||||
|
buf = buffer;
|
||||||
|
|
||||||
/* write the "." and ".." entries first */
|
/* write the "." and ".." entries first */
|
||||||
write_one_dir_record(t, dir, 0, buf, 1, 0);
|
write_one_dir_record(t, dir, 0, buf, 1, 0);
|
||||||
@ -944,7 +961,7 @@ int write_one_dir(Ecma119Image *t, JolietNode *dir)
|
|||||||
/* dir doesn't fit in current block */
|
/* dir doesn't fit in current block */
|
||||||
ret = iso_write(t, buffer, BLOCK_SIZE);
|
ret = iso_write(t, buffer, BLOCK_SIZE);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
goto ex;
|
||||||
}
|
}
|
||||||
memset(buffer, 0, BLOCK_SIZE);
|
memset(buffer, 0, BLOCK_SIZE);
|
||||||
buf = buffer;
|
buf = buffer;
|
||||||
@ -957,6 +974,8 @@ int write_one_dir(Ecma119Image *t, JolietNode *dir)
|
|||||||
|
|
||||||
/* write the last block */
|
/* write the last block */
|
||||||
ret = iso_write(t, buffer, BLOCK_SIZE);
|
ret = iso_write(t, buffer, BLOCK_SIZE);
|
||||||
|
ex:;
|
||||||
|
LIBISO_FREE_MEM(buffer);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -989,14 +1008,18 @@ static
|
|||||||
int write_path_table(Ecma119Image *t, JolietNode **pathlist, int l_type)
|
int write_path_table(Ecma119Image *t, JolietNode **pathlist, int l_type)
|
||||||
{
|
{
|
||||||
size_t i, len;
|
size_t i, len;
|
||||||
uint8_t buf[256]; /* 256 is just a convenient size larger enought */
|
uint8_t *buf = NULL;
|
||||||
struct ecma119_path_table_record *rec;
|
struct ecma119_path_table_record *rec;
|
||||||
void (*write_int)(uint8_t*, uint32_t, int);
|
void (*write_int)(uint8_t*, uint32_t, int);
|
||||||
JolietNode *dir;
|
JolietNode *dir;
|
||||||
uint32_t path_table_size;
|
uint32_t path_table_size;
|
||||||
int parent = 0;
|
int parent = 0;
|
||||||
int ret= ISO_SUCCESS;
|
int ret= ISO_SUCCESS;
|
||||||
|
uint8_t *zeros = NULL;
|
||||||
|
|
||||||
|
/* 256 is just a convenient size large enought */
|
||||||
|
LIBISO_ALLOC_MEM(buf, uint8_t, 256);
|
||||||
|
LIBISO_ALLOC_MEM(zeros, uint8_t, BLOCK_SIZE);
|
||||||
path_table_size = 0;
|
path_table_size = 0;
|
||||||
write_int = l_type ? iso_lsb : iso_msb;
|
write_int = l_type ? iso_lsb : iso_msb;
|
||||||
|
|
||||||
@ -1023,7 +1046,7 @@ int write_path_table(Ecma119Image *t, JolietNode **pathlist, int l_type)
|
|||||||
ret = iso_write(t, buf, len);
|
ret = iso_write(t, buf, len);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
/* error */
|
/* error */
|
||||||
return ret;
|
goto ex;
|
||||||
}
|
}
|
||||||
path_table_size += len;
|
path_table_size += len;
|
||||||
}
|
}
|
||||||
@ -1031,11 +1054,13 @@ int write_path_table(Ecma119Image *t, JolietNode **pathlist, int l_type)
|
|||||||
/* we need to fill the last block with zeros */
|
/* we need to fill the last block with zeros */
|
||||||
path_table_size %= BLOCK_SIZE;
|
path_table_size %= BLOCK_SIZE;
|
||||||
if (path_table_size) {
|
if (path_table_size) {
|
||||||
uint8_t zeros[BLOCK_SIZE];
|
|
||||||
len = BLOCK_SIZE - path_table_size;
|
len = BLOCK_SIZE - path_table_size;
|
||||||
memset(zeros, 0, len);
|
memset(zeros, 0, len);
|
||||||
ret = iso_write(t, zeros, len);
|
ret = iso_write(t, zeros, len);
|
||||||
}
|
}
|
||||||
|
ex:;
|
||||||
|
LIBISO_FREE_MEM(zeros);
|
||||||
|
LIBISO_FREE_MEM(buf);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,10 @@
|
|||||||
#include "libisofs.h"
|
#include "libisofs.h"
|
||||||
#include "ecma119.h"
|
#include "ecma119.h"
|
||||||
|
|
||||||
|
/* was formerly 66 = 64 + 2. Now 105 = 103 + 2.
|
||||||
|
*/
|
||||||
|
#define LIBISO_JOLIET_NAME_MAX 105
|
||||||
|
|
||||||
enum joliet_node_type {
|
enum joliet_node_type {
|
||||||
JOLIET_FILE,
|
JOLIET_FILE,
|
||||||
JOLIET_DIR
|
JOLIET_DIR
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
|
|
||||||
|
#ifndef LIBISO_LIBISOFS_H_
|
||||||
|
#define LIBISO_LIBISOFS_H_
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007-2008 Vreixo Formoso, Mario Danic
|
* 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
|
* This file is part of the libisofs project; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License version 2
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -14,21 +18,47 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* Applications must use 64 bit off_t, e.g. on 32-bit GNU/Linux by defining
|
* Applications must use 64 bit off_t.
|
||||||
|
* E.g. on 32-bit GNU/Linux by defining
|
||||||
* #define _LARGEFILE_SOURCE
|
* #define _LARGEFILE_SOURCE
|
||||||
* #define _FILE_OFFSET_BITS 64
|
* #define _FILE_OFFSET_BITS 64
|
||||||
* or take special precautions to interface with the library by 64 bit integers
|
* The minimum requirement is to interface with the library by 64 bit signed
|
||||||
* where this .h files prescribe off_t. Not to use 64 bit file i/o will keep
|
* integers where libisofs.h or libisoburn.h prescribe off_t.
|
||||||
* the application from producing and processing ISO images of more than 2 GB
|
* Failure to do so may result in surprising malfunction or memory faults.
|
||||||
* size.
|
*
|
||||||
|
* Application files which include libisofs/libisofs.h must provide
|
||||||
|
* definitions for uint32_t and uint8_t.
|
||||||
|
* This can be achieved either:
|
||||||
|
* - by using autotools which will define HAVE_STDINT_H or HAVE_INTTYPES_H
|
||||||
|
* according to its ./configure tests,
|
||||||
|
* - or by defining the macros HAVE_STDINT_H resp. HAVE_INTTYPES_H according
|
||||||
|
* to the local situation,
|
||||||
|
* - or by appropriately defining uint32_t and uint8_t by other means,
|
||||||
|
* e.g. by including inttypes.h before including libisofs.h
|
||||||
|
*/
|
||||||
|
#ifdef HAVE_STDINT_H
|
||||||
|
#include <stdint.h>
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_INTTYPES_H
|
||||||
|
#include <inttypes.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef LIBISO_LIBISOFS_H_
|
|
||||||
#define LIBISO_LIBISOFS_H_
|
|
||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
struct burn_source;
|
struct burn_source;
|
||||||
@ -137,6 +167,15 @@ struct iso_file_section
|
|||||||
uint32_t size;
|
uint32_t size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* If you get here because of a compilation error like
|
||||||
|
|
||||||
|
/usr/include/libisofs/libisofs.h:166: error:
|
||||||
|
expected specifier-qualifier-list before 'uint32_t'
|
||||||
|
|
||||||
|
then see the paragraph above about the definition of uint32_t.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Context for iterate on directory children.
|
* Context for iterate on directory children.
|
||||||
* @see iso_dir_get_children()
|
* @see iso_dir_get_children()
|
||||||
@ -419,7 +458,10 @@ struct iso_filesystem
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve a file from its absolute path inside the filesystem.
|
* Retrieve a file from its absolute path inside the filesystem.
|
||||||
*
|
* @param file
|
||||||
|
* Returns a pointer to a IsoFileSource object representing the
|
||||||
|
* file. It has to be disposed by iso_file_source_unref() when
|
||||||
|
* no longer needed.
|
||||||
* @return
|
* @return
|
||||||
* 1 success, < 0 error (has to be a valid libisofs error code)
|
* 1 success, < 0 error (has to be a valid libisofs error code)
|
||||||
* Error codes:
|
* Error codes:
|
||||||
@ -494,6 +536,8 @@ struct IsoFileSource_Iface
|
|||||||
* @since 0.6.2
|
* @since 0.6.2
|
||||||
* Version 1 additionally provides function *(get_aa_string)().
|
* Version 1 additionally provides function *(get_aa_string)().
|
||||||
* @since 0.6.14
|
* @since 0.6.14
|
||||||
|
* Version 2 additionally provides function *(clone_src)().
|
||||||
|
* @since 1.0.2
|
||||||
*/
|
*/
|
||||||
int version;
|
int version;
|
||||||
|
|
||||||
@ -728,6 +772,24 @@ struct IsoFileSource_Iface
|
|||||||
int (*get_aa_string)(IsoFileSource *src,
|
int (*get_aa_string)(IsoFileSource *src,
|
||||||
unsigned char **aa_string, int flag);
|
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.
|
* TODO #00004 Add a get_mime_type() function.
|
||||||
* This can be useful for GUI apps, to choose the icon of the file
|
* This can be useful for GUI apps, to choose the icon of the file
|
||||||
@ -752,6 +814,31 @@ struct iso_file_source
|
|||||||
#endif /* ! Libisofs_h_as_cpluspluS */
|
#endif /* ! Libisofs_h_as_cpluspluS */
|
||||||
#endif /* ! __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
|
* Representation of file contents. It is an stream of bytes, functionally
|
||||||
* like a pipe.
|
* like a pipe.
|
||||||
@ -787,6 +874,7 @@ extern ino_t serial_id;
|
|||||||
*
|
*
|
||||||
* @since 0.6.4
|
* @since 0.6.4
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct IsoStream_Iface
|
struct IsoStream_Iface
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -799,6 +887,8 @@ struct IsoStream_Iface
|
|||||||
* get_input_stream() added. A filter stream must have version 2.
|
* get_input_stream() added. A filter stream must have version 2.
|
||||||
* Version 3 (since 0.6.20)
|
* Version 3 (since 0.6.20)
|
||||||
* compare() added. A filter stream should have version 3.
|
* compare() added. A filter stream should have version 3.
|
||||||
|
* Version 4 (since 1.0.2)
|
||||||
|
* clone_stream() added.
|
||||||
*/
|
*/
|
||||||
int version;
|
int version;
|
||||||
|
|
||||||
@ -841,7 +931,7 @@ struct IsoStream_Iface
|
|||||||
off_t (*get_size)(IsoStream *stream);
|
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
|
* the buffer starting at buf. The implementation has to make sure that
|
||||||
* either the full desired count of bytes is delivered or that the
|
* either the full desired count of bytes is delivered or that the
|
||||||
* next call to this function will return EOF or error.
|
* next call to this function will return EOF or error.
|
||||||
@ -857,12 +947,9 @@ struct IsoStream_Iface
|
|||||||
int (*read)(IsoStream *stream, void *buf, size_t count);
|
int (*read)(IsoStream *stream, void *buf, size_t count);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether this IsoStream can be read several times, with the same results.
|
* Tell whether this IsoStream can be read several times, with the same
|
||||||
* For example, a regular file is repeatable, you can read it as many
|
* results. For example, a regular file is repeatable, you can read it
|
||||||
* times as you want. However, a pipe isn't.
|
* as many times as you want. However, a pipe is not.
|
||||||
*
|
|
||||||
* This function doesn't take into account if the file has been modified
|
|
||||||
* between the two reads.
|
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* 1 if stream is repeatable, 0 if not,
|
* 1 if stream is repeatable, 0 if not,
|
||||||
@ -883,13 +970,13 @@ struct IsoStream_Iface
|
|||||||
void (*free)(IsoStream *stream);
|
void (*free)(IsoStream *stream);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the size of the IsoStream with the current size of the
|
* Update the size of the IsoStream with the current size of the underlying
|
||||||
* underlying source. After calling this, get_size() will return
|
* source, if the source is prone to size changes. After calling this,
|
||||||
* the new size. This should never be called after
|
* get_size() shall eventually return the new size.
|
||||||
* iso_image_create_burn_source() was called and the image was not
|
* This will never be called after iso_image_create_burn_source() was
|
||||||
* completely written. To update the size of all files before written the
|
* called and before the image was completely written.
|
||||||
* image, you may want to call iso_image_update_sizes() just before
|
* (The API call to update the size of all files in the image is
|
||||||
* iso_image_create_burn_source().
|
* iso_image_update_sizes()).
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* 1 if ok, < 0 on error (has to be a valid libisofs error code)
|
* 1 if ok, < 0 on error (has to be a valid libisofs error code)
|
||||||
@ -900,15 +987,15 @@ struct IsoStream_Iface
|
|||||||
int (*update_size)(IsoStream *stream);
|
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
|
* @param stream
|
||||||
* The eventual filter stream to be inquired.
|
* The eventual filter stream to be inquired.
|
||||||
* @param flag
|
* @param flag
|
||||||
* Bitfield for control purposes. Submit 0 for now.
|
* Bitfield for control purposes. 0 means normal behavior.
|
||||||
* @return
|
* @return
|
||||||
* The input stream, if one exists. Elsewise NULL.
|
* 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
|
* @since 0.6.18
|
||||||
* Present if .version is 2 or higher.
|
* Present if .version is 2 or higher.
|
||||||
@ -920,33 +1007,32 @@ struct IsoStream_Iface
|
|||||||
* produce the same output. If in any doubt, then this comparison should
|
* produce the same output. If in any doubt, then this comparison should
|
||||||
* indicate no match. A match might allow hardlinking of IsoFile objects.
|
* 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,A) == 0
|
||||||
* cmp_ino(A,B) == -cmp_ino(B,A)
|
* 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
|
||||||
* 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
|
* 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
|
* types of streams.Thus it is mandatory to let iso_stream_cmp_ino(s1,s2,1)
|
||||||
* that is not applicable, cmp_ino(A,B) must have the same non-zero
|
* decide in this case.
|
||||||
* 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.
|
|
||||||
*
|
*
|
||||||
* A function s1.(*cmp_ino)() must only accept stream s2 if function
|
* 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
|
* 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.
|
* 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
|
* @param s1
|
||||||
* The first stream to compare. Expect foreign stream types.
|
* The first stream to compare. Expect foreign stream types.
|
||||||
* @param s2
|
* @param s2
|
||||||
@ -959,6 +1045,26 @@ struct IsoStream_Iface
|
|||||||
*/
|
*/
|
||||||
int (*cmp_ino)(IsoStream *s1, IsoStream *s2);
|
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
|
#ifndef __cplusplus
|
||||||
@ -1121,7 +1227,7 @@ int iso_lib_is_compatible(int major, int minor, int micro);
|
|||||||
* @since 0.6.2
|
* @since 0.6.2
|
||||||
*/
|
*/
|
||||||
#define iso_lib_header_version_major 1
|
#define iso_lib_header_version_major 1
|
||||||
#define iso_lib_header_version_minor 0
|
#define iso_lib_header_version_minor 1
|
||||||
#define iso_lib_header_version_micro 0
|
#define iso_lib_header_version_micro 0
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1344,6 +1450,26 @@ int iso_write_opts_set_hardlinks(IsoWriteOpts *opts, int enable);
|
|||||||
*/
|
*/
|
||||||
int iso_write_opts_set_aaip(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
|
* Caution: This option breaks any assumptions about names that
|
||||||
* are supported by ECMA-119 specifications.
|
* are supported by ECMA-119 specifications.
|
||||||
@ -1480,6 +1606,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);
|
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:
|
* 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
|
* signature "RRIP_1991A" rather than "IEEE_1282", field PX without file
|
||||||
@ -1854,7 +1989,13 @@ int iso_write_opts_set_fifo_size(IsoWriteOpts *opts, size_t fifo_size);
|
|||||||
* iso_write_opts_set_partition_img() for partition numbers 2
|
* iso_write_opts_set_partition_img() for partition numbers 2
|
||||||
* to 8.
|
* to 8.
|
||||||
* This will overwrite the first 512 bytes of the submitted
|
* This will overwrite the first 512 bytes of the submitted
|
||||||
* data.
|
* bit8-9= Only with System area type 0 = MBR
|
||||||
|
* @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
|
* @param flag
|
||||||
* bit0 = invalidate any attached system area data. Same as data == NULL
|
* bit0 = invalidate any attached system area data. Same as data == NULL
|
||||||
* (This re-activates eventually loaded image System Area data.
|
* (This re-activates eventually loaded image System Area data.
|
||||||
@ -1964,9 +2105,9 @@ int iso_write_opts_set_part_offset(IsoWriteOpts *opts,
|
|||||||
tests. It can be prevented by ./configure option --disable-libjte .
|
tests. It can be prevented by ./configure option --disable-libjte .
|
||||||
@since 0.6.38
|
@since 0.6.38
|
||||||
*/
|
*/
|
||||||
#define iso_libjte_req_major 0
|
#define iso_libjte_req_major 1
|
||||||
#define iso_libjte_req_minor 1
|
#define iso_libjte_req_minor 0
|
||||||
#define iso_libjte_req_micro 1
|
#define iso_libjte_req_micro 0
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Associate a libjte environment object to the upcomming write run.
|
* Associate a libjte environment object to the upcomming write run.
|
||||||
@ -2226,8 +2367,10 @@ int iso_read_opts_set_no_aaip(IsoReadOpts *opts, int noaaip);
|
|||||||
* @param opts
|
* @param opts
|
||||||
* The option set to be manipulated
|
* The option set to be manipulated
|
||||||
* @param no_md5
|
* @param no_md5
|
||||||
|
* 0 = Read MD5 array if available, refuse on non-matching MD5 tags
|
||||||
* 1 = Do not read MD5 checksum array
|
* 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.
|
* All other values are reserved.
|
||||||
*
|
*
|
||||||
* @since 0.6.22
|
* @since 0.6.22
|
||||||
@ -3015,6 +3158,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
|
* Specifies options for ISOLINUX or GRUB boot images. This should only be used
|
||||||
* if the type of boot image is known.
|
* if the type of boot image is known.
|
||||||
*
|
*
|
||||||
|
* @param bootimg
|
||||||
|
* The image to set options on
|
||||||
* @param options
|
* @param options
|
||||||
* bitmask style flag. The following values are defined:
|
* bitmask style flag. The following values are defined:
|
||||||
*
|
*
|
||||||
@ -3042,8 +3187,6 @@ int el_torito_seems_boot_info_table(ElToritoBootImage *bootimg, int flag);
|
|||||||
* For that you need isolinux.bin from SYSLINUX 3.72 or later.
|
* For that you need isolinux.bin from SYSLINUX 3.72 or later.
|
||||||
* IMPORTANT: The application has to take care that the image
|
* IMPORTANT: The application has to take care that the image
|
||||||
* on media gets padded up to the next full MB.
|
* on media gets padded up to the next full MB.
|
||||||
* @param bootimg
|
|
||||||
* The image to set options on
|
|
||||||
* @param flag
|
* @param flag
|
||||||
* Reserved for future usage, set to 0.
|
* Reserved for future usage, set to 0.
|
||||||
* @return
|
* @return
|
||||||
@ -3176,9 +3319,9 @@ void iso_node_unref(IsoNode *node);
|
|||||||
enum IsoNodeType iso_node_get_type(IsoNode *node);
|
enum IsoNodeType iso_node_get_type(IsoNode *node);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to handle particular extended information. The function
|
* Class of functions to handle particular extended information. A function
|
||||||
* pointer acts as an identifier for the type of the information. Structs
|
* instance acts as an identifier for the type of the information. Structs
|
||||||
* with same information type must use the same function.
|
* with same information type must use a pointer to the same function.
|
||||||
*
|
*
|
||||||
* @param data
|
* @param data
|
||||||
* Attached data
|
* Attached data
|
||||||
@ -3233,6 +3376,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);
|
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
|
* Get the given extended info (defined by the proc function) from the
|
||||||
* given node.
|
* given node.
|
||||||
@ -3252,6 +3409,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);
|
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
|
* 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.
|
* this can fail if dir already contains a node with the new name.
|
||||||
@ -3631,23 +3884,39 @@ int iso_dir_iter_take(IsoDirIter *iter);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes a child from a directory during an iteration and unref() it.
|
* 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.
|
* Like iso_node_remove(), but to be used during a directory iteration.
|
||||||
* The node removed will be the last returned by the 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
|
* It is not allowed to call this function twice without calling
|
||||||
* them is not allowed and you will get an ISO_ERROR in second call.
|
* iso_dir_iter_next inbetween.
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* 1 on succes, < 0 error
|
* 1 on succes, < 0 error
|
||||||
* Possible errors:
|
* Possible errors:
|
||||||
* ISO_NULL_POINTER, if iter is NULL
|
* 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.
|
* iso_dir_iter_next.
|
||||||
*
|
*
|
||||||
* @since 0.6.2
|
* @since 0.6.2
|
||||||
*/
|
*/
|
||||||
int iso_dir_iter_remove(IsoDirIter *iter);
|
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
|
* @since 0.6.4
|
||||||
@ -4384,6 +4653,57 @@ int iso_tree_add_new_cut_out_node(IsoImage *image, IsoDir *parent,
|
|||||||
off_t offset, off_t size,
|
off_t offset, off_t size,
|
||||||
IsoNode **node);
|
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.
|
* Add the contents of a dir to a given directory of the iso tree.
|
||||||
*
|
*
|
||||||
@ -4882,11 +5202,12 @@ int iso_file_source_readdir(IsoFileSource *src, IsoFileSource **child);
|
|||||||
* @param src
|
* @param src
|
||||||
* An IsoFileSource corresponding to a symbolic link.
|
* An IsoFileSource corresponding to a symbolic link.
|
||||||
* @param buf
|
* @param buf
|
||||||
* allocated buffer of at least bufsiz bytes.
|
* Allocated buffer of at least bufsiz bytes.
|
||||||
* The dest. will be copied there, and it will be NULL-terminated
|
* 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
|
* @param bufsiz
|
||||||
* characters to be copied. Destination link will be truncated if
|
* Maximum number of buf characters + 1. The string will be truncated if
|
||||||
* it is larger than given size. This includes the 0x0 character.
|
* it is larger than bufsiz - 1 and ISO_RR_PATH_TOO_LONG. will be returned.
|
||||||
* @return
|
* @return
|
||||||
* 1 on success, < 0 on error
|
* 1 on success, < 0 on error
|
||||||
* Error codes:
|
* Error codes:
|
||||||
@ -4897,6 +5218,7 @@ int iso_file_source_readdir(IsoFileSource *src, IsoFileSource **child);
|
|||||||
* ISO_OUT_OF_MEM
|
* ISO_OUT_OF_MEM
|
||||||
* ISO_FILE_BAD_PATH
|
* ISO_FILE_BAD_PATH
|
||||||
* ISO_FILE_DOESNT_EXIST
|
* ISO_FILE_DOESNT_EXIST
|
||||||
|
* ISO_RR_PATH_TOO_LONG (@since 1.0.6)
|
||||||
*
|
*
|
||||||
* @since 0.6.2
|
* @since 0.6.2
|
||||||
*/
|
*/
|
||||||
@ -5183,6 +5505,30 @@ char *iso_stream_get_source_path(IsoStream *stream, int flag);
|
|||||||
*/
|
*/
|
||||||
int iso_stream_cmp_ino(IsoStream *s1, IsoStream *s2, 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 --------------------------------- */
|
/* --------------------------------- AAIP --------------------------------- */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -5209,6 +5555,12 @@ int iso_stream_cmp_ino(IsoStream *s1, IsoStream *s2, int flag);
|
|||||||
*/
|
*/
|
||||||
int aaip_xinfo_func(void *data, 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.
|
* Get the eventual ACLs which are associated with the node.
|
||||||
@ -6488,6 +6840,27 @@ int iso_md5_match(char first_md5[16], char second_md5[16]);
|
|||||||
(FAILURE, HIGH, -373) */
|
(FAILURE, HIGH, -373) */
|
||||||
#define ISO_NAME_NEEDS_TRANSL 0xE830FE8B
|
#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:
|
/* Internal developer note:
|
||||||
Place new error codes directly above this comment.
|
Place new error codes directly above this comment.
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
LIBISOFS6 {
|
LIBISOFS6 {
|
||||||
global:
|
global:
|
||||||
|
aaip_xinfo_cloner;
|
||||||
aaip_xinfo_func;
|
aaip_xinfo_func;
|
||||||
el_torito_get_bootable;
|
el_torito_get_bootable;
|
||||||
el_torito_get_boot_media_type;
|
el_torito_get_boot_media_type;
|
||||||
@ -156,6 +157,7 @@ iso_node_get_hidden;
|
|||||||
iso_node_get_mode;
|
iso_node_get_mode;
|
||||||
iso_node_get_mtime;
|
iso_node_get_mtime;
|
||||||
iso_node_get_name;
|
iso_node_get_name;
|
||||||
|
iso_node_get_next_xinfo;
|
||||||
iso_node_get_old_image_lba;
|
iso_node_get_old_image_lba;
|
||||||
iso_node_get_parent;
|
iso_node_get_parent;
|
||||||
iso_node_get_permissions;
|
iso_node_get_permissions;
|
||||||
@ -166,6 +168,8 @@ iso_node_get_xinfo;
|
|||||||
iso_node_lookup_attr;
|
iso_node_lookup_attr;
|
||||||
iso_node_ref;
|
iso_node_ref;
|
||||||
iso_node_remove;
|
iso_node_remove;
|
||||||
|
iso_node_remove_all_xinfo;
|
||||||
|
iso_node_remove_tree;
|
||||||
iso_node_remove_xinfo;
|
iso_node_remove_xinfo;
|
||||||
iso_node_set_acl_text;
|
iso_node_set_acl_text;
|
||||||
iso_node_set_atime;
|
iso_node_set_atime;
|
||||||
@ -180,6 +184,8 @@ iso_node_set_sort_weight;
|
|||||||
iso_node_set_uid;
|
iso_node_set_uid;
|
||||||
iso_node_take;
|
iso_node_take;
|
||||||
iso_node_unref;
|
iso_node_unref;
|
||||||
|
iso_node_xinfo_get_cloner;
|
||||||
|
iso_node_xinfo_make_clonable;
|
||||||
iso_node_zf_by_magic;
|
iso_node_zf_by_magic;
|
||||||
iso_obtain_msgs;
|
iso_obtain_msgs;
|
||||||
iso_read_image_features_destroy;
|
iso_read_image_features_destroy;
|
||||||
@ -210,6 +216,7 @@ iso_set_local_charset;
|
|||||||
iso_set_msgs_severities;
|
iso_set_msgs_severities;
|
||||||
iso_sev_to_text;
|
iso_sev_to_text;
|
||||||
iso_special_get_dev;
|
iso_special_get_dev;
|
||||||
|
iso_stream_clone;
|
||||||
iso_stream_close;
|
iso_stream_close;
|
||||||
iso_stream_cmp_ino;
|
iso_stream_cmp_ino;
|
||||||
iso_stream_get_external_filter;
|
iso_stream_get_external_filter;
|
||||||
@ -235,6 +242,7 @@ iso_tree_add_new_node;
|
|||||||
iso_tree_add_new_special;
|
iso_tree_add_new_special;
|
||||||
iso_tree_add_new_symlink;
|
iso_tree_add_new_symlink;
|
||||||
iso_tree_add_node;
|
iso_tree_add_node;
|
||||||
|
iso_tree_clone;
|
||||||
iso_tree_get_follow_symlinks;
|
iso_tree_get_follow_symlinks;
|
||||||
iso_tree_get_ignore_hidden;
|
iso_tree_get_ignore_hidden;
|
||||||
iso_tree_get_ignore_special;
|
iso_tree_get_ignore_special;
|
||||||
@ -274,10 +282,12 @@ iso_write_opts_set_hardlinks;
|
|||||||
iso_write_opts_set_iso1999;
|
iso_write_opts_set_iso1999;
|
||||||
iso_write_opts_set_iso_level;
|
iso_write_opts_set_iso_level;
|
||||||
iso_write_opts_set_joliet;
|
iso_write_opts_set_joliet;
|
||||||
|
iso_write_opts_set_joliet_long_names;
|
||||||
iso_write_opts_set_joliet_longer_paths;
|
iso_write_opts_set_joliet_longer_paths;
|
||||||
iso_write_opts_set_max_37_char_filenames;
|
iso_write_opts_set_max_37_char_filenames;
|
||||||
iso_write_opts_set_ms_block;
|
iso_write_opts_set_ms_block;
|
||||||
iso_write_opts_set_no_force_dots;
|
iso_write_opts_set_no_force_dots;
|
||||||
|
iso_write_opts_set_old_empty;
|
||||||
iso_write_opts_set_omit_version_numbers;
|
iso_write_opts_set_omit_version_numbers;
|
||||||
iso_write_opts_set_output_charset;
|
iso_write_opts_set_output_charset;
|
||||||
iso_write_opts_set_overwrite_buf;
|
iso_write_opts_set_overwrite_buf;
|
||||||
|
@ -4,7 +4,15 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_STDINT_H
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_INTTYPES_H
|
||||||
|
#include <inttypes.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -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,
|
int part_offset, int part_number, int fs_type,
|
||||||
uint8_t *buf, int flag)
|
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;
|
off_t hd_img_blocks, hd_boot_lba;
|
||||||
char *wpt;
|
char *wpt;
|
||||||
/* For generating a weak random number */
|
/* For generating a weak random number */
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
struct timezone tz;
|
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;
|
hd_img_blocks = ((off_t) *img_blocks) * (off_t) 4;
|
||||||
if (hd_img_blocks % spc) {
|
|
||||||
hd_img_blocks += spc - (hd_img_blocks % spc);
|
/* Padding of image_size to a multiple of sector_count*head_count
|
||||||
*img_blocks = hd_img_blocks / 4 + !!(hd_img_blocks % 4);
|
happens already at compute time and is implemented by
|
||||||
}
|
an appropriate increase of Ecma119Image->tail_blocks.
|
||||||
|
*/
|
||||||
|
|
||||||
wpt = (char *) buf + 432;
|
wpt = (char *) buf + 432;
|
||||||
|
|
||||||
@ -418,7 +424,7 @@ int make_isolinux_mbr(int32_t *img_blocks, uint32_t boot_lba,
|
|||||||
/* # Offset 446
|
/* # Offset 446
|
||||||
*/
|
*/
|
||||||
for (part = 1 ; part <= 4; part++) {
|
for (part = 1 ; part <= 4; part++) {
|
||||||
if (part != part_number) {
|
if ((int) part != part_number) {
|
||||||
/* if this_partition != partition_number: write 16 zero bytes */
|
/* if this_partition != partition_number: write 16 zero bytes */
|
||||||
memset(wpt, 0, 16);
|
memset(wpt, 0, 16);
|
||||||
wpt+= 16;
|
wpt+= 16;
|
||||||
|
103
libisofs/md5.c
103
libisofs/md5.c
@ -12,7 +12,14 @@
|
|||||||
#include "../config.h"
|
#include "../config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_STDINT_H
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_INTTYPES_H
|
||||||
|
#include <inttypes.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -222,10 +229,10 @@ static int md5_init(libisofs_md5_ctx *ctx, int flag)
|
|||||||
static int md5_update(libisofs_md5_ctx *ctx, unsigned char *data,
|
static int md5_update(libisofs_md5_ctx *ctx, unsigned char *data,
|
||||||
int datalen, int flag)
|
int datalen, int flag)
|
||||||
{
|
{
|
||||||
unsigned int i, index, partlen;
|
int i, index, partlen;
|
||||||
|
|
||||||
/* Compute number of bytes mod 64 */
|
/* Compute number of bytes mod 64 */
|
||||||
index = (unsigned int)((ctx->count[0] >> 3) & 0x3F);
|
index = ((ctx->count[0] >> 3) & 0x3F);
|
||||||
/* Update number of bits */
|
/* Update number of bits */
|
||||||
if ((ctx->count[0] += ((uint32_t) datalen << 3)) <
|
if ((ctx->count[0] += ((uint32_t) datalen << 3)) <
|
||||||
((uint32_t) datalen << 3))
|
((uint32_t) datalen << 3))
|
||||||
@ -417,6 +424,22 @@ int checksum_cx_xinfo_func(void *data, int flag)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The iso_node_xinfo_cloner function which gets associated to
|
||||||
|
* checksum_cx_xinfo_func by iso_init() resp. iso_init_with_flag() via
|
||||||
|
* iso_node_xinfo_make_clonable()
|
||||||
|
*/
|
||||||
|
int checksum_cx_xinfo_cloner(void *old_data, void **new_data, int flag)
|
||||||
|
{
|
||||||
|
*new_data = NULL;
|
||||||
|
if (flag)
|
||||||
|
return ISO_XINFO_NO_CLONE;
|
||||||
|
if (old_data == NULL)
|
||||||
|
return 0;
|
||||||
|
/* data is an int disguised as pointer. It does not point to memory. */
|
||||||
|
*new_data = old_data;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Function to identify and manage md5 sums of unspecified providence stored
|
/* Function to identify and manage md5 sums of unspecified providence stored
|
||||||
* directly in this xinfo.
|
* directly in this xinfo.
|
||||||
@ -429,6 +452,24 @@ int checksum_md5_xinfo_func(void *data, int flag)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The iso_node_xinfo_cloner function which gets associated to
|
||||||
|
* checksum_md5_xinfo_func by iso_init() resp. iso_init_with_flag() via
|
||||||
|
* iso_node_xinfo_make_clonable()
|
||||||
|
*/
|
||||||
|
int checksum_md5_xinfo_cloner(void *old_data, void **new_data, int flag)
|
||||||
|
{
|
||||||
|
*new_data = NULL;
|
||||||
|
if (flag)
|
||||||
|
return ISO_XINFO_NO_CLONE;
|
||||||
|
if (old_data == NULL)
|
||||||
|
return 0;
|
||||||
|
*new_data = calloc(1, 16);
|
||||||
|
if (*new_data == NULL)
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
memcpy(*new_data, old_data, 16);
|
||||||
|
return 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------- */
|
/* ----------------------------------------------------------------------- */
|
||||||
|
|
||||||
@ -580,11 +621,6 @@ int checksum_writer_write_data(IsoImageWriter *writer)
|
|||||||
void *ctx = NULL;
|
void *ctx = NULL;
|
||||||
char md5[16];
|
char md5[16];
|
||||||
|
|
||||||
#ifdef NIX
|
|
||||||
char tag_block[2048];
|
|
||||||
int l;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (writer == NULL) {
|
if (writer == NULL) {
|
||||||
return ISO_ASSERT_FAILURE;
|
return ISO_ASSERT_FAILURE;
|
||||||
}
|
}
|
||||||
@ -683,15 +719,16 @@ int iso_md5_write_scdbackup_tag(Ecma119Image *t, char *tag_block, int flag)
|
|||||||
{
|
{
|
||||||
void *ctx = NULL;
|
void *ctx = NULL;
|
||||||
off_t pos = 0, line_start;
|
off_t pos = 0, line_start;
|
||||||
int record_len, block_len, res, i;
|
int record_len, block_len, ret, i;
|
||||||
char postext[40], md5[16], record[160];
|
char postext[40], md5[16], *record = NULL;
|
||||||
|
|
||||||
|
LIBISO_ALLOC_MEM(record, char, 160);
|
||||||
line_start = strlen(tag_block);
|
line_start = strlen(tag_block);
|
||||||
iso_md5_compute(t->checksum_ctx, tag_block, line_start);
|
iso_md5_compute(t->checksum_ctx, tag_block, line_start);
|
||||||
res = iso_md5_clone(t->checksum_ctx, &ctx);
|
ret = iso_md5_clone(t->checksum_ctx, &ctx);
|
||||||
if (res < 0)
|
if (ret < 0)
|
||||||
goto ex;
|
goto ex;
|
||||||
res = iso_md5_end(&ctx, md5);
|
ret = iso_md5_end(&ctx, md5);
|
||||||
|
|
||||||
pos = (off_t) t->checksum_tag_pos * (off_t) 2048 + line_start;
|
pos = (off_t) t->checksum_tag_pos * (off_t) 2048 + line_start;
|
||||||
if(pos >= 1000000000)
|
if(pos >= 1000000000)
|
||||||
@ -706,8 +743,8 @@ int iso_md5_write_scdbackup_tag(Ecma119Image *t, char *tag_block, int flag)
|
|||||||
"%2.2x", ((unsigned char *) md5)[i]);
|
"%2.2x", ((unsigned char *) md5)[i]);
|
||||||
record_len += 32;
|
record_len += 32;
|
||||||
|
|
||||||
res = iso_md5_start(&ctx);
|
ret = iso_md5_start(&ctx);
|
||||||
if (res < 0)
|
if (ret < 0)
|
||||||
goto ex;
|
goto ex;
|
||||||
iso_md5_compute(ctx, record, record_len);
|
iso_md5_compute(ctx, record, record_len);
|
||||||
iso_md5_end(&ctx, md5);
|
iso_md5_end(&ctx, md5);
|
||||||
@ -724,11 +761,12 @@ int iso_md5_write_scdbackup_tag(Ecma119Image *t, char *tag_block, int flag)
|
|||||||
if (t->scdbackup_tag_written != NULL)
|
if (t->scdbackup_tag_written != NULL)
|
||||||
strncpy(t->scdbackup_tag_written, tag_block + line_start,
|
strncpy(t->scdbackup_tag_written, tag_block + line_start,
|
||||||
block_len - line_start);
|
block_len - line_start);
|
||||||
res = ISO_SUCCESS;
|
ret = ISO_SUCCESS;
|
||||||
ex:;
|
ex:;
|
||||||
if (ctx != NULL)
|
if (ctx != NULL)
|
||||||
iso_md5_end(&ctx, md5);
|
iso_md5_end(&ctx, md5);
|
||||||
return res;
|
LIBISO_FREE_MEM(record);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -742,20 +780,20 @@ ex:;
|
|||||||
*/
|
*/
|
||||||
int iso_md5_write_tag(Ecma119Image *t, int flag)
|
int iso_md5_write_tag(Ecma119Image *t, int flag)
|
||||||
{
|
{
|
||||||
int res, mode, l, i, wres, tag_id_len;
|
int ret, mode, l, i, wres, tag_id_len;
|
||||||
void *ctx = NULL;
|
void *ctx = NULL;
|
||||||
char md5[16], tag_block[2048], *tag_id;
|
char md5[16], *tag_block = NULL, *tag_id;
|
||||||
uint32_t size = 0, pos = 0, start;
|
uint32_t size = 0, pos = 0, start;
|
||||||
|
|
||||||
|
LIBISO_ALLOC_MEM(tag_block, char, 2048);
|
||||||
start = t->checksum_range_start;
|
start = t->checksum_range_start;
|
||||||
memset(tag_block, 0, 2048);
|
|
||||||
mode = flag & 255;
|
mode = flag & 255;
|
||||||
if (mode < 1 || mode > 4)
|
if (mode < 1 || mode > 4)
|
||||||
return ISO_WRONG_ARG_VALUE;
|
{ret = ISO_WRONG_ARG_VALUE; goto ex;}
|
||||||
res = iso_md5_clone(t->checksum_ctx, &ctx);
|
ret = iso_md5_clone(t->checksum_ctx, &ctx);
|
||||||
if (res < 0)
|
if (ret < 0)
|
||||||
return res;
|
goto ex;
|
||||||
res = iso_md5_end(&ctx, md5);
|
ret = iso_md5_end(&ctx, md5);
|
||||||
if (mode == 1) {
|
if (mode == 1) {
|
||||||
size = t->checksum_range_size;
|
size = t->checksum_range_size;
|
||||||
pos = t->checksum_tag_pos;
|
pos = t->checksum_tag_pos;
|
||||||
@ -770,7 +808,7 @@ int iso_md5_write_tag(Ecma119Image *t, int flag)
|
|||||||
}
|
}
|
||||||
size = pos - start;
|
size = pos - start;
|
||||||
}
|
}
|
||||||
if (res < 0)
|
if (ret < 0)
|
||||||
goto ex;
|
goto ex;
|
||||||
|
|
||||||
iso_util_tag_magic(mode, &tag_id, &tag_id_len, 0);
|
iso_util_tag_magic(mode, &tag_id, &tag_id_len, 0);
|
||||||
@ -792,8 +830,8 @@ int iso_md5_write_tag(Ecma119Image *t, int flag)
|
|||||||
((unsigned char *) md5)[i]);
|
((unsigned char *) md5)[i]);
|
||||||
l+= 32;
|
l+= 32;
|
||||||
|
|
||||||
res = iso_md5_start(&ctx);
|
ret = iso_md5_start(&ctx);
|
||||||
if (res > 0) {
|
if (ret > 0) {
|
||||||
iso_md5_compute(ctx, tag_block, l);
|
iso_md5_compute(ctx, tag_block, l);
|
||||||
iso_md5_end(&ctx, md5);
|
iso_md5_end(&ctx, md5);
|
||||||
strcpy(tag_block + l, " self=");
|
strcpy(tag_block + l, " self=");
|
||||||
@ -808,8 +846,8 @@ int iso_md5_write_tag(Ecma119Image *t, int flag)
|
|||||||
if (t->ms_block > 0) {
|
if (t->ms_block > 0) {
|
||||||
iso_msg_submit(t->image->id, ISO_SCDBACKUP_TAG_NOT_0, 0, NULL);
|
iso_msg_submit(t->image->id, ISO_SCDBACKUP_TAG_NOT_0, 0, NULL);
|
||||||
} else {
|
} else {
|
||||||
res = iso_md5_write_scdbackup_tag(t, tag_block, 0);
|
ret = iso_md5_write_scdbackup_tag(t, tag_block, 0);
|
||||||
if (res < 0)
|
if (ret < 0)
|
||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -820,16 +858,17 @@ int iso_md5_write_tag(Ecma119Image *t, int flag)
|
|||||||
} else {
|
} else {
|
||||||
wres = iso_write(t, tag_block, 2048);
|
wres = iso_write(t, tag_block, 2048);
|
||||||
if (wres < 0) {
|
if (wres < 0) {
|
||||||
res = wres;
|
ret = wres;
|
||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
res = ISO_SUCCESS;
|
ret = ISO_SUCCESS;
|
||||||
ex:;
|
ex:;
|
||||||
if (ctx != NULL)
|
if (ctx != NULL)
|
||||||
iso_md5_end(&ctx, md5);
|
iso_md5_end(&ctx, md5);
|
||||||
return res;
|
LIBISO_FREE_MEM(tag_block);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
|
* Copyright (c) 2009 - 2011 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* This file is part of the libisofs project; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License version 2
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -36,6 +37,7 @@
|
|||||||
#include "messages.h"
|
#include "messages.h"
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "node.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -79,11 +81,76 @@ int abort_threshold = LIBISO_MSGS_SEV_FAILURE;
|
|||||||
struct libiso_msgs *libiso_msgr = NULL;
|
struct libiso_msgs *libiso_msgr = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------- List of xinfo clone functions ----------- */
|
||||||
|
|
||||||
|
struct iso_xinfo_cloner_assoc {
|
||||||
|
iso_node_xinfo_func proc;
|
||||||
|
iso_node_xinfo_cloner cloner;
|
||||||
|
struct iso_xinfo_cloner_assoc *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct iso_xinfo_cloner_assoc *iso_xinfo_cloner_list = NULL;
|
||||||
|
|
||||||
|
/* API */
|
||||||
|
int iso_node_xinfo_make_clonable(iso_node_xinfo_func proc,
|
||||||
|
iso_node_xinfo_cloner cloner, int flag)
|
||||||
|
{
|
||||||
|
struct iso_xinfo_cloner_assoc *assoc;
|
||||||
|
|
||||||
|
/* Look for existing assoc of proc */
|
||||||
|
for (assoc = iso_xinfo_cloner_list; assoc != NULL; assoc = assoc->next)
|
||||||
|
if (assoc->proc == proc)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (assoc == NULL) {
|
||||||
|
assoc = calloc(1, sizeof(struct iso_xinfo_cloner_assoc));
|
||||||
|
if (assoc == NULL)
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
assoc->proc = proc;
|
||||||
|
assoc->next = iso_xinfo_cloner_list;
|
||||||
|
iso_xinfo_cloner_list = assoc;
|
||||||
|
}
|
||||||
|
assoc->cloner = cloner;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* API */
|
||||||
|
int iso_node_xinfo_get_cloner(iso_node_xinfo_func proc,
|
||||||
|
iso_node_xinfo_cloner *cloner, int flag)
|
||||||
|
{
|
||||||
|
struct iso_xinfo_cloner_assoc *assoc;
|
||||||
|
|
||||||
|
*cloner = NULL;
|
||||||
|
for (assoc = iso_xinfo_cloner_list; assoc != NULL; assoc = assoc->next) {
|
||||||
|
if (assoc->proc != proc)
|
||||||
|
continue;
|
||||||
|
*cloner = assoc->cloner;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int iso_node_xinfo_dispose_cloners(int flag)
|
||||||
|
{
|
||||||
|
struct iso_xinfo_cloner_assoc *assoc, *next;
|
||||||
|
|
||||||
|
for (assoc = iso_xinfo_cloner_list; assoc != NULL; assoc = next) {
|
||||||
|
next = assoc->next;
|
||||||
|
free((char *) assoc);
|
||||||
|
}
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------- End of xinfo clone functions list ----------- */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@param flag bit0= do not set up locale by LC_* environment variables
|
@param flag bit0= do not set up locale by LC_* environment variables
|
||||||
*/
|
*/
|
||||||
int iso_init_with_flag(int flag)
|
int iso_init_with_flag(int flag)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
#ifdef Libisofs_with_libjtE
|
#ifdef Libisofs_with_libjtE
|
||||||
|
|
||||||
@ -119,7 +186,6 @@ LIBJTE_MISCONFIGURATION_ = 0;
|
|||||||
|
|
||||||
#endif /* Libisofs_with_libjtE */
|
#endif /* Libisofs_with_libjtE */
|
||||||
|
|
||||||
|
|
||||||
if (! (flag & 1)) {
|
if (! (flag & 1)) {
|
||||||
iso_init_locale(0);
|
iso_init_locale(0);
|
||||||
}
|
}
|
||||||
@ -129,10 +195,29 @@ LIBJTE_MISCONFIGURATION_ = 0;
|
|||||||
}
|
}
|
||||||
libiso_msgs_set_severities(libiso_msgr, LIBISO_MSGS_SEV_NEVER,
|
libiso_msgs_set_severities(libiso_msgr, LIBISO_MSGS_SEV_NEVER,
|
||||||
LIBISO_MSGS_SEV_FATAL, "libisofs: ", 0);
|
LIBISO_MSGS_SEV_FATAL, "libisofs: ", 0);
|
||||||
|
|
||||||
|
ret = iso_node_xinfo_make_clonable(aaip_xinfo_func, aaip_xinfo_cloner, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
ret = iso_node_xinfo_make_clonable(checksum_cx_xinfo_func,
|
||||||
|
checksum_cx_xinfo_cloner, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
ret = iso_node_xinfo_make_clonable(checksum_md5_xinfo_func,
|
||||||
|
checksum_md5_xinfo_cloner, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
ret = iso_node_xinfo_make_clonable(zisofs_zf_xinfo_func,
|
||||||
|
zisofs_zf_xinfo_cloner, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
ret = iso_node_xinfo_make_clonable(iso_px_ino_xinfo_func,
|
||||||
|
iso_px_ino_xinfo_cloner, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int iso_init()
|
int iso_init()
|
||||||
{
|
{
|
||||||
return iso_init_with_flag(0);
|
return iso_init_with_flag(0);
|
||||||
@ -141,6 +226,7 @@ int iso_init()
|
|||||||
void iso_finish()
|
void iso_finish()
|
||||||
{
|
{
|
||||||
libiso_msgs_destroy(&libiso_msgr, 0);
|
libiso_msgs_destroy(&libiso_msgr, 0);
|
||||||
|
iso_node_xinfo_dispose_cloners(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int iso_set_abort_severity(char *severity)
|
int iso_set_abort_severity(char *severity)
|
||||||
@ -159,15 +245,19 @@ int iso_set_abort_severity(char *severity)
|
|||||||
|
|
||||||
void iso_msg_debug(int imgid, const char *fmt, ...)
|
void iso_msg_debug(int imgid, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
char msg[MAX_MSG_LEN];
|
char *msg = NULL;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
LIBISO_ALLOC_MEM(msg, char, MAX_MSG_LEN);
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
vsnprintf(msg, MAX_MSG_LEN, fmt, ap);
|
vsnprintf(msg, MAX_MSG_LEN, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
libiso_msgs_submit(libiso_msgr, imgid, 0x00000002, LIBISO_MSGS_SEV_DEBUG,
|
libiso_msgs_submit(libiso_msgr, imgid, 0x00000002, LIBISO_MSGS_SEV_DEBUG,
|
||||||
LIBISO_MSGS_PRIO_ZERO, msg, 0, 0);
|
LIBISO_MSGS_PRIO_ZERO, msg, 0, 0);
|
||||||
|
ex:;
|
||||||
|
LIBISO_FREE_MEM(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *iso_error_to_msg(int errcode)
|
const char *iso_error_to_msg(int errcode)
|
||||||
@ -363,6 +453,18 @@ const char *iso_error_to_msg(int errcode)
|
|||||||
return "Displacement offset leads outside 32 bit range";
|
return "Displacement offset leads outside 32 bit range";
|
||||||
case ISO_NAME_NEEDS_TRANSL:
|
case ISO_NAME_NEEDS_TRANSL:
|
||||||
return "File name cannot be written into ECMA-119 untranslated";
|
return "File name cannot be written into ECMA-119 untranslated";
|
||||||
|
case ISO_STREAM_NO_CLONE:
|
||||||
|
return "Data file input stream object offers no cloning method";
|
||||||
|
case ISO_XINFO_NO_CLONE:
|
||||||
|
return "Extended information class offers no cloning method";
|
||||||
|
case ISO_MD5_TAG_COPIED:
|
||||||
|
return "Found copied superblock checksum tag";
|
||||||
|
case ISO_RR_NAME_TOO_LONG:
|
||||||
|
return "Rock Ridge leaf name too long";
|
||||||
|
case ISO_RR_NAME_RESERVED:
|
||||||
|
return "Reserved Rock Ridge leaf name";
|
||||||
|
case ISO_RR_PATH_TOO_LONG:
|
||||||
|
return "Rock Ridge path too long";
|
||||||
default:
|
default:
|
||||||
return "Unknown error";
|
return "Unknown error";
|
||||||
}
|
}
|
||||||
@ -382,7 +484,7 @@ int iso_msg_submit(int imgid, int errcode, int causedby, const char *fmt, ...)
|
|||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
/* when called with ISO_CANCELED, we don't need to submit any message */
|
/* when called with ISO_CANCELED, we don't need to submit any message */
|
||||||
if (errcode == ISO_CANCELED && fmt == NULL) {
|
if (errcode == (int) ISO_CANCELED && fmt == NULL) {
|
||||||
return ISO_CANCELED;
|
return ISO_CANCELED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
249
libisofs/node.c
249
libisofs/node.c
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
* Copyright (c) 2009 Thomas Schmitt
|
* Copyright (c) 2009 - 2011 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* This file is part of the libisofs project; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License version 2
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -28,11 +28,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
#ifndef PATH_MAX
|
|
||||||
#define PATH_MAX Libisofs_default_path_maX
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
struct dir_iter_data
|
struct dir_iter_data
|
||||||
{
|
{
|
||||||
/* points to the last visited child, to NULL before start */
|
/* points to the last visited child, to NULL before start */
|
||||||
@ -226,6 +221,89 @@ int iso_node_get_xinfo(IsoNode *node, iso_node_xinfo_func proc, void **data)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* API */
|
||||||
|
int iso_node_get_next_xinfo(IsoNode *node, void **handle,
|
||||||
|
iso_node_xinfo_func *proc, void **data)
|
||||||
|
{
|
||||||
|
IsoExtendedInfo *xinfo;
|
||||||
|
|
||||||
|
if (node == NULL || handle == NULL || proc == NULL || data == NULL)
|
||||||
|
return ISO_NULL_POINTER;
|
||||||
|
*proc = NULL;
|
||||||
|
*data = NULL;
|
||||||
|
xinfo = (IsoExtendedInfo *) *handle;
|
||||||
|
if (xinfo == NULL)
|
||||||
|
xinfo = node->xinfo;
|
||||||
|
else
|
||||||
|
xinfo = xinfo->next;
|
||||||
|
*handle = xinfo;
|
||||||
|
if (xinfo == NULL)
|
||||||
|
return 0;
|
||||||
|
*proc = xinfo->process;
|
||||||
|
*data = xinfo->data;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int iso_node_remove_all_xinfo(IsoNode *node, int flag)
|
||||||
|
{
|
||||||
|
IsoExtendedInfo *pos, *next;
|
||||||
|
|
||||||
|
for (pos = node->xinfo; pos != NULL; pos = next) {
|
||||||
|
next = pos->next;
|
||||||
|
pos->process(pos->data, 1);
|
||||||
|
free((char *) pos);
|
||||||
|
}
|
||||||
|
node->xinfo = NULL;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int iso_node_revert_xinfo_list(IsoNode *node, int flag)
|
||||||
|
{
|
||||||
|
|
||||||
|
IsoExtendedInfo *pos, *next, *prev = NULL;
|
||||||
|
|
||||||
|
for (pos = node->xinfo; pos != NULL; pos = next) {
|
||||||
|
next = pos->next;
|
||||||
|
pos->next = prev;
|
||||||
|
prev = pos;
|
||||||
|
}
|
||||||
|
node->xinfo = prev;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int iso_node_clone_xinfo(IsoNode *from_node, IsoNode *to_node, int flag)
|
||||||
|
{
|
||||||
|
void *handle = NULL, *data, *new_data;
|
||||||
|
iso_node_xinfo_func proc;
|
||||||
|
iso_node_xinfo_cloner cloner;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
iso_node_remove_all_xinfo(to_node, 0);
|
||||||
|
while (1) {
|
||||||
|
ret = iso_node_get_next_xinfo(from_node, &handle, &proc, &data);
|
||||||
|
if (ret <= 0)
|
||||||
|
break;
|
||||||
|
ret = iso_node_xinfo_get_cloner(proc, &cloner, 0);
|
||||||
|
if (ret == 0)
|
||||||
|
return ISO_XINFO_NO_CLONE;
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
ret = (*cloner)(data, &new_data, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
break;
|
||||||
|
ret = iso_node_add_xinfo(to_node, proc, new_data);
|
||||||
|
if (ret < 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ret < 0) {
|
||||||
|
iso_node_remove_all_xinfo(to_node, 0);
|
||||||
|
} else {
|
||||||
|
ret = iso_node_revert_xinfo_list(to_node, 0);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the type of an IsoNode.
|
* Get the type of an IsoNode.
|
||||||
*/
|
*/
|
||||||
@ -242,6 +320,7 @@ enum IsoNodeType iso_node_get_type(IsoNode *node)
|
|||||||
int iso_node_set_name(IsoNode *node, const char *name)
|
int iso_node_set_name(IsoNode *node, const char *name)
|
||||||
{
|
{
|
||||||
char *new;
|
char *new;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if ((IsoNode*)node->parent == node) {
|
if ((IsoNode*)node->parent == node) {
|
||||||
/* you can't change name of the root node */
|
/* you can't change name of the root node */
|
||||||
@ -249,9 +328,9 @@ int iso_node_set_name(IsoNode *node, const char *name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* check if the name is valid */
|
/* check if the name is valid */
|
||||||
if (!iso_node_is_valid_name(name)) {
|
ret = iso_node_is_valid_name(name);
|
||||||
return ISO_WRONG_ARG_VALUE;
|
if (ret < 0)
|
||||||
}
|
return ret;
|
||||||
|
|
||||||
if (node->parent != NULL) {
|
if (node->parent != NULL) {
|
||||||
/* check if parent already has a node with same name */
|
/* check if parent already has a node with same name */
|
||||||
@ -651,6 +730,9 @@ int iso_node_take(IsoNode *node)
|
|||||||
if (dir == NULL) {
|
if (dir == NULL) {
|
||||||
return ISO_NODE_NOT_ADDED_TO_DIR;
|
return ISO_NODE_NOT_ADDED_TO_DIR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* >>> Do not take root directory ! (dir == node) ? */;
|
||||||
|
|
||||||
pos = iso_dir_find_node(dir, node);
|
pos = iso_dir_find_node(dir, node);
|
||||||
if (pos == NULL) {
|
if (pos == NULL) {
|
||||||
/* should never occur */
|
/* should never occur */
|
||||||
@ -686,6 +768,44 @@ int iso_node_remove(IsoNode *node)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* API */
|
||||||
|
int iso_node_remove_tree(IsoNode *node, IsoDirIter *boss_iter)
|
||||||
|
{
|
||||||
|
IsoDirIter *iter = NULL;
|
||||||
|
IsoNode *sub_node;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (node->type != LIBISO_DIR) {
|
||||||
|
|
||||||
|
/* >>> Do not remove root directory ! (node->parent == node) ? */;
|
||||||
|
|
||||||
|
ret = iso_dir_get_children((IsoDir *) node, &iter);
|
||||||
|
if (ret < 0)
|
||||||
|
goto ex;
|
||||||
|
while(1) {
|
||||||
|
ret = iso_dir_iter_next(iter, &sub_node);
|
||||||
|
if (ret == 0)
|
||||||
|
break;
|
||||||
|
ret = iso_node_remove_tree(sub_node, iter);
|
||||||
|
if (ret < 0)
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
if (node->parent == NULL) {
|
||||||
|
/* node is not grafted into a boss directory */
|
||||||
|
iso_node_unref(node);
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (boss_iter != NULL)
|
||||||
|
ret = iso_dir_iter_remove(boss_iter);
|
||||||
|
else
|
||||||
|
ret = iso_node_remove(node);
|
||||||
|
ex:;
|
||||||
|
if (iter != NULL)
|
||||||
|
iso_dir_iter_free(iter);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the parent of the given iso tree node. No extra ref is added to the
|
* Get the parent of the given iso tree node. No extra ref is added to the
|
||||||
* returned directory, you must take your ref. with iso_node_ref() if you
|
* returned directory, you must take your ref. with iso_node_ref() if you
|
||||||
@ -881,10 +1001,11 @@ const char *iso_symlink_get_dest(const IsoSymlink *link)
|
|||||||
int iso_symlink_set_dest(IsoSymlink *link, const char *dest)
|
int iso_symlink_set_dest(IsoSymlink *link, const char *dest)
|
||||||
{
|
{
|
||||||
char *d;
|
char *d;
|
||||||
if (!iso_node_is_valid_link_dest(dest)) {
|
int ret;
|
||||||
/* guard against null or empty dest */
|
|
||||||
return ISO_WRONG_ARG_VALUE;
|
ret = iso_node_is_valid_link_dest(dest);
|
||||||
}
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
d = strdup(dest);
|
d = strdup(dest);
|
||||||
if (d == NULL) {
|
if (d == NULL) {
|
||||||
return ISO_OUT_OF_MEM;
|
return ISO_OUT_OF_MEM;
|
||||||
@ -1035,22 +1156,23 @@ int iso_node_is_valid_name(const char *name)
|
|||||||
{
|
{
|
||||||
/* a name can't be NULL */
|
/* a name can't be NULL */
|
||||||
if (name == NULL) {
|
if (name == NULL) {
|
||||||
return 0;
|
return ISO_NULL_POINTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* guard against the empty string or big names... */
|
/* guard against the empty string or big names... */
|
||||||
if (name[0] == '\0' || strlen(name) > 255) {
|
if (name[0] == '\0')
|
||||||
return 0;
|
return ISO_RR_NAME_RESERVED;
|
||||||
}
|
if (strlen(name) > LIBISOFS_NODE_NAME_MAX)
|
||||||
|
return ISO_RR_NAME_TOO_LONG;
|
||||||
|
|
||||||
/* ...against "." and ".." names... */
|
/* ...against "." and ".." names... */
|
||||||
if (!strcmp(name, ".") || !strcmp(name, "..")) {
|
if (!strcmp(name, ".") || !strcmp(name, "..")) {
|
||||||
return 0;
|
return ISO_RR_NAME_RESERVED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ...and against names with '/' */
|
/* ...and against names with '/' */
|
||||||
if (strchr(name, '/') != NULL) {
|
if (strchr(name, '/') != NULL) {
|
||||||
return 0;
|
return ISO_RR_NAME_RESERVED;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -1068,13 +1190,14 @@ int iso_node_is_valid_link_dest(const char *dest)
|
|||||||
|
|
||||||
/* a dest can't be NULL */
|
/* a dest can't be NULL */
|
||||||
if (dest == NULL) {
|
if (dest == NULL) {
|
||||||
return 0;
|
return ISO_NULL_POINTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* guard against the empty string or big dest... */
|
/* guard against the empty string or big dest... */
|
||||||
if (dest[0] == '\0' || strlen(dest) > PATH_MAX) {
|
if (dest[0] == '\0')
|
||||||
return 0;
|
return ISO_RR_NAME_RESERVED;
|
||||||
}
|
if (strlen(dest) > LIBISOFS_NODE_PATH_MAX)
|
||||||
|
return ISO_RR_PATH_TOO_LONG;
|
||||||
|
|
||||||
/* check that all components are valid */
|
/* check that all components are valid */
|
||||||
if (!strcmp(dest, "/")) {
|
if (!strcmp(dest, "/")) {
|
||||||
@ -1084,7 +1207,7 @@ int iso_node_is_valid_link_dest(const char *dest)
|
|||||||
|
|
||||||
ptr = strdup(dest);
|
ptr = strdup(dest);
|
||||||
if (ptr == NULL) {
|
if (ptr == NULL) {
|
||||||
return 0;
|
return ISO_OUT_OF_MEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = 1;
|
ret = 1;
|
||||||
@ -1092,7 +1215,7 @@ int iso_node_is_valid_link_dest(const char *dest)
|
|||||||
while (component) {
|
while (component) {
|
||||||
if (strcmp(component, ".") && strcmp(component, "..")) {
|
if (strcmp(component, ".") && strcmp(component, "..")) {
|
||||||
ret = iso_node_is_valid_name(component);
|
ret = iso_node_is_valid_name(component);
|
||||||
if (ret == 0) {
|
if (ret < 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1251,15 +1374,16 @@ int iso_node_new_root(IsoDir **root)
|
|||||||
int iso_node_new_dir(char *name, IsoDir **dir)
|
int iso_node_new_dir(char *name, IsoDir **dir)
|
||||||
{
|
{
|
||||||
IsoDir *new;
|
IsoDir *new;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (dir == NULL || name == NULL) {
|
if (dir == NULL || name == NULL) {
|
||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check if the name is valid */
|
/* check if the name is valid */
|
||||||
if (!iso_node_is_valid_name(name)) {
|
ret = iso_node_is_valid_name(name);
|
||||||
return ISO_WRONG_ARG_VALUE;
|
if (ret < 0)
|
||||||
}
|
return ret;
|
||||||
|
|
||||||
new = calloc(1, sizeof(IsoDir));
|
new = calloc(1, sizeof(IsoDir));
|
||||||
if (new == NULL) {
|
if (new == NULL) {
|
||||||
@ -1276,15 +1400,16 @@ int iso_node_new_dir(char *name, IsoDir **dir)
|
|||||||
int iso_node_new_file(char *name, IsoStream *stream, IsoFile **file)
|
int iso_node_new_file(char *name, IsoStream *stream, IsoFile **file)
|
||||||
{
|
{
|
||||||
IsoFile *new;
|
IsoFile *new;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (file == NULL || name == NULL || stream == NULL) {
|
if (file == NULL || name == NULL || stream == NULL) {
|
||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check if the name is valid */
|
/* check if the name is valid */
|
||||||
if (!iso_node_is_valid_name(name)) {
|
ret = iso_node_is_valid_name(name);
|
||||||
return ISO_WRONG_ARG_VALUE;
|
if (ret < 0)
|
||||||
}
|
return ret;
|
||||||
|
|
||||||
new = calloc(1, sizeof(IsoFile));
|
new = calloc(1, sizeof(IsoFile));
|
||||||
if (new == NULL) {
|
if (new == NULL) {
|
||||||
@ -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)
|
int iso_node_new_symlink(char *name, char *dest, IsoSymlink **link)
|
||||||
{
|
{
|
||||||
IsoSymlink *new;
|
IsoSymlink *new;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (link == NULL || name == NULL || dest == NULL) {
|
if (link == NULL || name == NULL || dest == NULL) {
|
||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check if the name is valid */
|
/* check if the name is valid */
|
||||||
if (!iso_node_is_valid_name(name)) {
|
ret = iso_node_is_valid_name(name);
|
||||||
return ISO_WRONG_ARG_VALUE;
|
if (ret < 0)
|
||||||
}
|
return ret;
|
||||||
|
|
||||||
/* check if destination is valid */
|
/* check if destination is valid */
|
||||||
if (!iso_node_is_valid_link_dest(dest)) {
|
ret = iso_node_is_valid_link_dest(dest);
|
||||||
/* guard against null or empty dest */
|
if (ret < 0)
|
||||||
return ISO_WRONG_ARG_VALUE;
|
return ret;
|
||||||
}
|
|
||||||
|
|
||||||
new = calloc(1, sizeof(IsoSymlink));
|
new = calloc(1, sizeof(IsoSymlink));
|
||||||
if (new == NULL) {
|
if (new == NULL) {
|
||||||
@ -1340,6 +1465,7 @@ int iso_node_new_special(char *name, mode_t mode, dev_t dev,
|
|||||||
IsoSpecial **special)
|
IsoSpecial **special)
|
||||||
{
|
{
|
||||||
IsoSpecial *new;
|
IsoSpecial *new;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (special == NULL || name == NULL) {
|
if (special == NULL || name == NULL) {
|
||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
@ -1349,9 +1475,9 @@ int iso_node_new_special(char *name, mode_t mode, dev_t dev,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* check if the name is valid */
|
/* check if the name is valid */
|
||||||
if (!iso_node_is_valid_name(name)) {
|
ret = iso_node_is_valid_name(name);
|
||||||
return ISO_WRONG_ARG_VALUE;
|
if (ret < 0)
|
||||||
}
|
return ret;
|
||||||
|
|
||||||
new = calloc(1, sizeof(IsoSpecial));
|
new = calloc(1, sizeof(IsoSpecial));
|
||||||
if (new == NULL) {
|
if (new == NULL) {
|
||||||
@ -1447,7 +1573,7 @@ int iso_aa_get_attrs(unsigned char *aa_string, size_t *num_attrs,
|
|||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rpt - aa_string != len) {
|
if ((size_t) (rpt - aa_string) != len) {
|
||||||
/* aaip_decode_attrs() returns 2 but still bytes are left */
|
/* aaip_decode_attrs() returns 2 but still bytes are left */
|
||||||
ret = ISO_AAIP_BAD_AASTRING;
|
ret = ISO_AAIP_BAD_AASTRING;
|
||||||
goto ex;
|
goto ex;
|
||||||
@ -1489,13 +1615,13 @@ int iso_aa_lookup_attr(unsigned char *aa_string, char *name,
|
|||||||
|
|
||||||
ret = iso_aa_get_attrs(aa_string, &num_attrs, &names,
|
ret = iso_aa_get_attrs(aa_string, &num_attrs, &names,
|
||||||
&value_lengths, &values, 0);
|
&value_lengths, &values, 0);
|
||||||
for (i = 0; i < num_attrs; i++) {
|
for (i = 0; i < (int) num_attrs; i++) {
|
||||||
if (strcmp(names[i], name))
|
if (strcmp(names[i], name))
|
||||||
continue;
|
continue;
|
||||||
*value_length = value_lengths[i];
|
*value_length = value_lengths[i];
|
||||||
*value = calloc(*value_length + 1, 1);
|
*value = calloc(*value_length + 1, 1);
|
||||||
if (*value == NULL) {
|
if (*value == NULL) {
|
||||||
ret = ISO_OUT_OF_MEM;
|
found = ISO_OUT_OF_MEM;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (*value_length > 0)
|
if (*value_length > 0)
|
||||||
@ -2153,6 +2279,23 @@ int zisofs_zf_xinfo_func(void *data, int flag)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The iso_node_xinfo_cloner function which gets associated to
|
||||||
|
* zisofs_zf_xinfo_func by iso_init() resp. iso_init_with_flag() via
|
||||||
|
* iso_node_xinfo_make_clonable()
|
||||||
|
*/
|
||||||
|
int zisofs_zf_xinfo_cloner(void *old_data, void **new_data, int flag)
|
||||||
|
{
|
||||||
|
*new_data = NULL;
|
||||||
|
if (flag)
|
||||||
|
return ISO_XINFO_NO_CLONE;
|
||||||
|
if (old_data == NULL)
|
||||||
|
return 0;
|
||||||
|
*new_data = calloc(1, sizeof(struct zisofs_zf_info));
|
||||||
|
if (*new_data == NULL)
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
memcpy(*new_data, old_data, sizeof(struct zisofs_zf_info));
|
||||||
|
return (int) sizeof(struct zisofs_zf_info);
|
||||||
|
}
|
||||||
|
|
||||||
/* Checks whether a file effectively bears a zisofs file header and eventually
|
/* Checks whether a file effectively bears a zisofs file header and eventually
|
||||||
* marks this by a struct zisofs_zf_info as xinfo of the file node.
|
* marks this by a struct zisofs_zf_info as xinfo of the file node.
|
||||||
@ -2274,6 +2417,21 @@ int iso_px_ino_xinfo_func(void *data, int flag)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The iso_node_xinfo_cloner function which gets associated to
|
||||||
|
* iso_px_ino_xinfo_func by iso_init() resp. iso_init_with_flag() via
|
||||||
|
* iso_node_xinfo_make_clonable()
|
||||||
|
*/
|
||||||
|
int iso_px_ino_xinfo_cloner(void *old_data, void **new_data, int flag)
|
||||||
|
{
|
||||||
|
*new_data = NULL;
|
||||||
|
if (flag)
|
||||||
|
return ISO_XINFO_NO_CLONE;
|
||||||
|
*new_data = calloc(1, sizeof(ino_t));
|
||||||
|
if (*new_data == NULL)
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
memcpy(*new_data, old_data, sizeof(ino_t));
|
||||||
|
return (int) sizeof(ino_t);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @param flag
|
* @param flag
|
||||||
@ -2364,7 +2522,6 @@ int iso_node_set_ino_xinfo(IsoNode *node, ino_t ino, int flag)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int iso_node_set_ino(IsoNode *node, ino_t ino, int flag)
|
int iso_node_set_ino(IsoNode *node, ino_t ino, int flag)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@ -2693,7 +2850,7 @@ int iso_file_get_md5(IsoImage *image, IsoFile *file, char md5[16], int flag)
|
|||||||
ret = 0;
|
ret = 0;
|
||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
for (i = 0; i < value_len; i++)
|
for (i = 0; i < (int) value_len; i++)
|
||||||
idx = (idx << 8) | ((unsigned char *) value)[i];
|
idx = (idx << 8) | ((unsigned char *) value)[i];
|
||||||
if (idx == 0 || idx > image->checksum_idx_count - 1) {
|
if (idx == 0 || idx > image->checksum_idx_count - 1) {
|
||||||
/* (last index is not MD5 of a file) */
|
/* (last index is not MD5 of a file) */
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
* Copyright (c) 2009 Thomas Schmitt
|
* Copyright (c) 2009 - 2011 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* This file is part of the libisofs project; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License version 2
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -20,7 +20,38 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_STDINT_H
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_INTTYPES_H
|
||||||
|
#include <inttypes.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Maximum length of a leaf name in the libisofs node tree. This is currently
|
||||||
|
restricted by the implemented maximum length of a Rock Ridge name.
|
||||||
|
This might later become larger and may then be limited to smaller values.
|
||||||
|
|
||||||
|
Rock Ridge specs do not impose an explicit limit on name length.
|
||||||
|
But 255 is also specified by
|
||||||
|
http://pubs.opengroup.org/onlinepubs/009695399/basedefs/limits.h.html
|
||||||
|
which says
|
||||||
|
NAME_MAX >= _XOPEN_NAME_MAX = 255
|
||||||
|
*/
|
||||||
|
#define LIBISOFS_NODE_NAME_MAX 255
|
||||||
|
|
||||||
|
|
||||||
|
/* Maximum length of a path in the libisofs node tree.
|
||||||
|
Rock Ridge specs do not impose an explicit limit on path length.
|
||||||
|
|
||||||
|
http://pubs.opengroup.org/onlinepubs/009695399/basedefs/limits.h.html
|
||||||
|
says
|
||||||
|
PATH_MAX >= _XOPEN_PATH_MAX = 1024
|
||||||
|
*/
|
||||||
|
#define LIBISOFS_NODE_PATH_MAX 1024
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The extended information is a way to attach additional information to each
|
* The extended information is a way to attach additional information to each
|
||||||
@ -113,6 +144,7 @@ struct Iso_Dir
|
|||||||
IsoNode *children; /**< list of children. ptr to first child */
|
IsoNode *children; /**< list of children. ptr to first child */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* IMPORTANT: Any change must be reflected by iso_tree_clone_file. */
|
||||||
struct Iso_File
|
struct Iso_File
|
||||||
{
|
{
|
||||||
IsoNode node;
|
IsoNode node;
|
||||||
@ -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.
|
* Check if a given name is valid for an iso node.
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* 1 if yes, 0 if not
|
* 1 if yes, <0 if not. The value is a specific ISO_* error code.
|
||||||
*/
|
*/
|
||||||
int iso_node_is_valid_name(const char *name);
|
int iso_node_is_valid_name(const char *name);
|
||||||
|
|
||||||
@ -473,4 +505,35 @@ int iso_root_get_isofsca(IsoNode *node, uint32_t *start_lba, uint32_t *end_lba,
|
|||||||
int flag);
|
int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy the xinfo list from one node to the another.
|
||||||
|
*/
|
||||||
|
int iso_node_clone_xinfo(IsoNode *from_node, IsoNode *to_node, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The iso_node_xinfo_func instance which governs the storing of the inode
|
||||||
|
* number from Rock Ridge field PX.
|
||||||
|
*/
|
||||||
|
int iso_px_ino_xinfo_func(void *data, int flag);
|
||||||
|
|
||||||
|
/* The iso_node_xinfo_cloner function which gets associated to
|
||||||
|
* iso_px_ino_xinfo_func by iso_init() resp. iso_init_with_flag() via
|
||||||
|
* iso_node_xinfo_make_clonable()
|
||||||
|
*/
|
||||||
|
int iso_px_ino_xinfo_cloner(void *old_data, void **new_data, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/* Function to identify and manage ZF parameters of zisofs compression.
|
||||||
|
* data is supposed to be a pointer to struct zisofs_zf_info
|
||||||
|
*/
|
||||||
|
int zisofs_zf_xinfo_func(void *data, int flag);
|
||||||
|
|
||||||
|
/* The iso_node_xinfo_cloner function which gets associated to
|
||||||
|
* zisofs_zf_xinfo_func by iso_init() resp. iso_init_with_flag() via
|
||||||
|
* iso_node_xinfo_make_clonable()
|
||||||
|
*/
|
||||||
|
int zisofs_zf_xinfo_cloner(void *old_data, void **new_data, int flag);
|
||||||
|
|
||||||
|
|
||||||
#endif /*LIBISO_NODE_H_*/
|
#endif /*LIBISO_NODE_H_*/
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
* Copyright (c) 2007 Mario Danic
|
* Copyright (c) 2007 Mario Danic
|
||||||
* Copyright (c) 2009 Thomas Schmitt
|
* Copyright (c) 2009 - 2011 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* This file is part of the libisofs project; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License version 2
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -337,7 +337,12 @@ static
|
|||||||
int rrip_add_NM(Ecma119Image *t, struct susp_info *susp, char *name, int size,
|
int rrip_add_NM(Ecma119Image *t, struct susp_info *susp, char *name, int size,
|
||||||
int flags, int ce)
|
int flags, int ce)
|
||||||
{
|
{
|
||||||
uint8_t *NM = malloc(size + 5);
|
uint8_t *NM;
|
||||||
|
|
||||||
|
if (size > 250)
|
||||||
|
return ISO_ASSERT_FAILURE;
|
||||||
|
|
||||||
|
NM = malloc(size + 5);
|
||||||
if (NM == NULL) {
|
if (NM == NULL) {
|
||||||
return ISO_OUT_OF_MEM;
|
return ISO_OUT_OF_MEM;
|
||||||
}
|
}
|
||||||
@ -445,8 +450,8 @@ static
|
|||||||
int rrip_add_SL(Ecma119Image *t, struct susp_info *susp, uint8_t **comp,
|
int rrip_add_SL(Ecma119Image *t, struct susp_info *susp, uint8_t **comp,
|
||||||
size_t n, int ce)
|
size_t n, int ce)
|
||||||
{
|
{
|
||||||
int ret, i, j;
|
int ret;
|
||||||
|
size_t i, j;
|
||||||
int total_comp_len = 0;
|
int total_comp_len = 0;
|
||||||
size_t pos, written = 0;
|
size_t pos, written = 0;
|
||||||
|
|
||||||
@ -905,7 +910,7 @@ int add_zf_field(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* API */
|
||||||
int aaip_xinfo_func(void *data, int flag)
|
int aaip_xinfo_func(void *data, int flag)
|
||||||
{
|
{
|
||||||
if (flag & 1) {
|
if (flag & 1) {
|
||||||
@ -914,6 +919,23 @@ int aaip_xinfo_func(void *data, int flag)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* API */
|
||||||
|
int aaip_xinfo_cloner(void *old_data, void **new_data, int flag)
|
||||||
|
{
|
||||||
|
size_t aa_size;
|
||||||
|
|
||||||
|
*new_data = NULL;
|
||||||
|
if (old_data == NULL)
|
||||||
|
return 0;
|
||||||
|
aa_size = aaip_count_bytes((unsigned char *) old_data, 0);
|
||||||
|
if (aa_size <= 0)
|
||||||
|
return ISO_AAIP_BAD_AASTRING;
|
||||||
|
*new_data = calloc(1, aa_size);
|
||||||
|
if (*new_data == NULL)
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
memcpy(*new_data, old_data, aa_size);
|
||||||
|
return (int) aa_size;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compute SUA length and eventual Continuation Area length of field NM and
|
* Compute SUA length and eventual Continuation Area length of field NM and
|
||||||
@ -928,6 +950,7 @@ int aaip_xinfo_func(void *data, int flag)
|
|||||||
* (*su_size and *ce stay unaltered in this case)
|
* (*su_size and *ce stay unaltered in this case)
|
||||||
* <0= error:
|
* <0= error:
|
||||||
* -1= not enough SUA space for 28 bytes of CE entry
|
* -1= not enough SUA space for 28 bytes of CE entry
|
||||||
|
* -2= out of memory
|
||||||
*/
|
*/
|
||||||
static
|
static
|
||||||
int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
|
int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
|
||||||
@ -964,6 +987,9 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
|
|||||||
if (!(flag & 1))
|
if (!(flag & 1))
|
||||||
goto unannounced_ca;
|
goto unannounced_ca;
|
||||||
namelen = namelen - (space - *su_size - 5);
|
namelen = namelen - (space - *su_size - 5);
|
||||||
|
|
||||||
|
/* >>> Need to handle lengths > 250 */;
|
||||||
|
|
||||||
*ce = 5 + namelen;
|
*ce = 5 + namelen;
|
||||||
*su_size = space;
|
*su_size = space;
|
||||||
}
|
}
|
||||||
@ -976,6 +1002,8 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
|
|||||||
int cew = (*ce != 0); /* are we writing to CA ? */
|
int cew = (*ce != 0); /* are we writing to CA ? */
|
||||||
|
|
||||||
dest = get_rr_fname(t, ((IsoSymlink*)n->node)->dest);
|
dest = get_rr_fname(t, ((IsoSymlink*)n->node)->dest);
|
||||||
|
if (dest == NULL)
|
||||||
|
return -2;
|
||||||
prev = dest;
|
prev = dest;
|
||||||
cur = strchr(prev, '/');
|
cur = strchr(prev, '/');
|
||||||
while (1) {
|
while (1) {
|
||||||
@ -1004,8 +1032,10 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
|
|||||||
* TODO this can be handled better, but for now SL
|
* TODO this can be handled better, but for now SL
|
||||||
* will be completelly moved into the CA
|
* will be completelly moved into the CA
|
||||||
*/
|
*/
|
||||||
if (!(flag & 1))
|
if (!(flag & 1)) {
|
||||||
|
free(dest);
|
||||||
goto unannounced_ca;
|
goto unannounced_ca;
|
||||||
|
}
|
||||||
cew = 1;
|
cew = 1;
|
||||||
} else {
|
} else {
|
||||||
sl_len += clen;
|
sl_len += clen;
|
||||||
@ -1024,8 +1054,8 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
|
|||||||
* First, we check how many bytes fit in current
|
* First, we check how many bytes fit in current
|
||||||
* SL field
|
* SL field
|
||||||
*/
|
*/
|
||||||
int fit = 255 - sl_len - 2;
|
ssize_t fit = 255 - sl_len - 2;
|
||||||
if (clen - 250 <= fit) {
|
if ((ssize_t) (clen - 250) <= fit) {
|
||||||
/*
|
/*
|
||||||
* the component can be divided between this
|
* the component can be divided between this
|
||||||
* and another SL entry
|
* and another SL entry
|
||||||
@ -1105,6 +1135,44 @@ unannounced_ca:;
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* @param flag bit0= Do not add data but only count sua_free and ce_len
|
||||||
|
param info may be NULL in this case
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
int add_aa_string(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
|
||||||
|
size_t *sua_free, size_t *ce_len, int flag)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
uint8_t *aapt;
|
||||||
|
void *xipt;
|
||||||
|
size_t num_aapt= 0;
|
||||||
|
|
||||||
|
if (!t->aaip)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
ret = iso_node_get_xinfo(n->node, aaip_xinfo_func, &xipt);
|
||||||
|
if (ret == 1) {
|
||||||
|
num_aapt = aaip_count_bytes((unsigned char *) xipt, 0);
|
||||||
|
if (num_aapt > 0) {
|
||||||
|
if (flag & 1) {
|
||||||
|
ret = aaip_add_AL(t, NULL,NULL, num_aapt, sua_free, ce_len, 1);
|
||||||
|
} else {
|
||||||
|
aapt = malloc(num_aapt);
|
||||||
|
if (aapt == NULL)
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
memcpy(aapt, xipt, num_aapt);
|
||||||
|
ret = aaip_add_AL(t, info, &aapt, num_aapt, sua_free, ce_len,
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
/* aapt is NULL now and the memory is owned by t */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compute the length needed for write all RR and SUSP entries for a given
|
* Compute the length needed for write all RR and SUSP entries for a given
|
||||||
* node.
|
* node.
|
||||||
@ -1124,6 +1192,7 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t used_up,
|
|||||||
{
|
{
|
||||||
size_t su_size, space;
|
size_t su_size, space;
|
||||||
int ret;
|
int ret;
|
||||||
|
size_t aaip_sua_free= 0, aaip_len= 0;
|
||||||
|
|
||||||
/* Directory record length must be even (ECMA-119, 9.1.13). Maximum is 254.
|
/* Directory record length must be even (ECMA-119, 9.1.13). Maximum is 254.
|
||||||
*/
|
*/
|
||||||
@ -1180,13 +1249,16 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t used_up,
|
|||||||
/* Try without CE */
|
/* Try without CE */
|
||||||
ret = susp_calc_nm_sl_al(t, n, space, &su_size, ce, 0);
|
ret = susp_calc_nm_sl_al(t, n, space, &su_size, ce, 0);
|
||||||
if (ret == 0) /* Retry with CE */
|
if (ret == 0) /* Retry with CE */
|
||||||
susp_calc_nm_sl_al(t, n, space, &su_size, ce, 1);
|
ret = susp_calc_nm_sl_al(t, n, space, &su_size, ce, 1);
|
||||||
|
if (ret == -2)
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* "." or ".." entry */
|
/* "." or ".." entry */
|
||||||
|
|
||||||
su_size += 5; /* NM field */
|
if (!t->rrip_version_1_10)
|
||||||
|
su_size += 5; /* NM field */
|
||||||
|
|
||||||
if (type == 1 && n->parent == NULL) {
|
if (type == 1 && n->parent == NULL) {
|
||||||
/*
|
/*
|
||||||
@ -1201,9 +1273,15 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t used_up,
|
|||||||
} else {
|
} else {
|
||||||
*ce = 182;
|
*ce = 182;
|
||||||
}
|
}
|
||||||
if (t->aaip) {
|
if (t->aaip && !t->aaip_susp_1_10) {
|
||||||
*ce += 160; /* ER of AAIP */
|
*ce += 160; /* ER of AAIP */
|
||||||
}
|
}
|
||||||
|
/* Compute length of AAIP string of root node */
|
||||||
|
aaip_sua_free= 0;
|
||||||
|
ret = add_aa_string(t, n, NULL, &aaip_sua_free, &aaip_len, 1);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
*ce += aaip_len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1235,43 +1313,6 @@ void susp_info_free(struct susp_info* susp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* @param flag bit0= Do not add data but only count sua_free and ce_len
|
|
||||||
*/
|
|
||||||
static
|
|
||||||
int add_aa_string(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
|
|
||||||
size_t *sua_free, size_t *ce_len, int flag)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
uint8_t *aapt;
|
|
||||||
void *xipt;
|
|
||||||
size_t num_aapt= 0;
|
|
||||||
|
|
||||||
if (!t->aaip)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
ret = iso_node_get_xinfo(n->node, aaip_xinfo_func, &xipt);
|
|
||||||
if (ret == 1) {
|
|
||||||
num_aapt = aaip_count_bytes((unsigned char *) xipt, 0);
|
|
||||||
if (num_aapt > 0) {
|
|
||||||
if (flag & 1) {
|
|
||||||
ret = aaip_add_AL(t, NULL,NULL, num_aapt, sua_free, ce_len, 1);
|
|
||||||
} else {
|
|
||||||
aapt = malloc(num_aapt);
|
|
||||||
if (aapt == NULL)
|
|
||||||
return ISO_OUT_OF_MEM;
|
|
||||||
memcpy(aapt, xipt, num_aapt);
|
|
||||||
ret = aaip_add_AL(t, info, &aapt, num_aapt, sua_free, ce_len,
|
|
||||||
0);
|
|
||||||
}
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
/* aapt is NULL now and the memory is owned by t */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fill a struct susp_info with the RR/SUSP entries needed for a given
|
* Fill a struct susp_info with the RR/SUSP entries needed for a given
|
||||||
* node.
|
* node.
|
||||||
@ -1302,7 +1343,7 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
|||||||
size_t su_size_pd, ce_len_pd; /* predicted sizes of SUA and CA */
|
size_t su_size_pd, ce_len_pd; /* predicted sizes of SUA and CA */
|
||||||
int ce_is_predicted = 0;
|
int ce_is_predicted = 0;
|
||||||
size_t aaip_sua_free= 0, aaip_len= 0;
|
size_t aaip_sua_free= 0, aaip_len= 0;
|
||||||
size_t space;
|
int space;
|
||||||
|
|
||||||
if (t == NULL || n == NULL || info == NULL) {
|
if (t == NULL || n == NULL || info == NULL) {
|
||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
@ -1314,7 +1355,7 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
|||||||
if (type < 0 || type > 2 || space < ISO_ROCKRIDGE_IN_DIR_REC) {
|
if (type < 0 || type > 2 || space < ISO_ROCKRIDGE_IN_DIR_REC) {
|
||||||
iso_msg_submit(t->image->id, ISO_ASSERT_FAILURE, 0,
|
iso_msg_submit(t->image->id, ISO_ASSERT_FAILURE, 0,
|
||||||
"Unknown node type %d or short RR space %d < %d in directory record",
|
"Unknown node type %d or short RR space %d < %d in directory record",
|
||||||
type, (int) space, ISO_ROCKRIDGE_IN_DIR_REC);
|
type, space, ISO_ROCKRIDGE_IN_DIR_REC);
|
||||||
return ISO_ASSERT_FAILURE;
|
return ISO_ASSERT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1398,7 +1439,7 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
|||||||
if (info->suf_len + 28 > space) {
|
if (info->suf_len + 28 > space) {
|
||||||
iso_msg_submit(t->image->id, ISO_ASSERT_FAILURE, 0,
|
iso_msg_submit(t->image->id, ISO_ASSERT_FAILURE, 0,
|
||||||
"Directory Record overflow. name='%s' , suf_len=%d > space=%d - 28\n",
|
"Directory Record overflow. name='%s' , suf_len=%d > space=%d - 28\n",
|
||||||
node->iso_name, (int) info->suf_len, (int) space);
|
node->iso_name, (int) info->suf_len, space);
|
||||||
return ISO_ASSERT_FAILURE;
|
return ISO_ASSERT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1420,12 +1461,18 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
|||||||
/* Try whether NM, SL, AL will fit into SUA */
|
/* Try whether NM, SL, AL will fit into SUA */
|
||||||
su_size_pd = info->suf_len;
|
su_size_pd = info->suf_len;
|
||||||
ce_len_pd = ce_len;
|
ce_len_pd = ce_len;
|
||||||
ret = susp_calc_nm_sl_al(t, n, space, &su_size_pd, &ce_len_pd, 0);
|
ret = susp_calc_nm_sl_al(t, n, (size_t) space,
|
||||||
|
&su_size_pd, &ce_len_pd, 0);
|
||||||
if (ret == 0) { /* Have to use CA. 28 bytes of CE are necessary */
|
if (ret == 0) { /* Have to use CA. 28 bytes of CE are necessary */
|
||||||
susp_calc_nm_sl_al(t, n, space, &su_size_pd, &ce_len_pd, 1);
|
ret = susp_calc_nm_sl_al(t, n, (size_t) space,
|
||||||
|
&su_size_pd, &ce_len_pd, 1);
|
||||||
sua_free -= 28;
|
sua_free -= 28;
|
||||||
ce_is_predicted = 1;
|
ce_is_predicted = 1;
|
||||||
}
|
}
|
||||||
|
if (ret == -2) {
|
||||||
|
ret = ISO_OUT_OF_MEM;
|
||||||
|
goto add_susp_cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
/* NM entry */
|
/* NM entry */
|
||||||
if (5 + namelen <= sua_free) {
|
if (5 + namelen <= sua_free) {
|
||||||
@ -1510,8 +1557,8 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
|||||||
* First, we check how many bytes fit in current
|
* First, we check how many bytes fit in current
|
||||||
* SL field
|
* SL field
|
||||||
*/
|
*/
|
||||||
int fit = 255 - sl_len - 2;
|
ssize_t fit = 255 - sl_len - 2;
|
||||||
if (clen - 250 <= fit) {
|
if ((ssize_t) (clen - 250) <= fit) {
|
||||||
/*
|
/*
|
||||||
* the component can be divided between this
|
* the component can be divided between this
|
||||||
* and another SL entry
|
* and another SL entry
|
||||||
@ -1623,6 +1670,9 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
|||||||
/*
|
/*
|
||||||
* ..and the part that goes to continuation area.
|
* ..and the part that goes to continuation area.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* >>> Need a loop to handle lengths > 250 */;
|
||||||
|
|
||||||
ret = rrip_add_NM(t, info, name + namelen, strlen(name + namelen),
|
ret = rrip_add_NM(t, info, name + namelen, strlen(name + namelen),
|
||||||
0, 1);
|
0, 1);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@ -1664,9 +1714,36 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
|||||||
/* "." or ".." entry */
|
/* "." or ".." entry */
|
||||||
|
|
||||||
/* write the NM entry */
|
/* write the NM entry */
|
||||||
ret = rrip_add_NM(t, info, NULL, 0, 1 << type, 0);
|
if (t->rrip_version_1_10) {
|
||||||
if (ret < 0) {
|
/* RRIP-1.10:
|
||||||
goto add_susp_cleanup;
|
"NM" System Use Fields recorded for the ISO 9660 directory
|
||||||
|
records with names (00) and (01), used to designate the
|
||||||
|
current and parent directories, respectively, should be
|
||||||
|
ignored. Instead, the receiving system should convert these
|
||||||
|
names to the appropriate receiving system-dependent
|
||||||
|
designations for the current and parent directories.
|
||||||
|
*/
|
||||||
|
/* mkisofs obviously writes no NM for '.' and '..' .
|
||||||
|
Program isoinfo shows empty names with records as of RRIP-1.12
|
||||||
|
*/
|
||||||
|
/* no op */;
|
||||||
|
} else {
|
||||||
|
/* RRIP-1.12:
|
||||||
|
If the ISO 9660 Directory Record File Identifier is (00), then
|
||||||
|
the CURRENT bit of the "NM" Flags field [...], if present, shall
|
||||||
|
be set to ONE. If the ISO 9660 Directory Record File Identifier
|
||||||
|
is (01), then the PARENT bit of the "NM" Flags field [...],
|
||||||
|
if present, shall be set to ONE.
|
||||||
|
[...]
|
||||||
|
"BP 3 - Length (LEN_NM)" shall specify as an 8-bit number the
|
||||||
|
length in bytes [...]. If bit position 1, 2, or 5 of the "NM"
|
||||||
|
Flags is set to ONE, the value of this field shall be 5 and no
|
||||||
|
Name Content shall be recorded.
|
||||||
|
[The CURRENT bit has position 1. The PARENT bit has position 2.]
|
||||||
|
*/
|
||||||
|
ret = rrip_add_NM(t, info, NULL, 0, 1 << type, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
goto add_susp_cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == 1 && n->parent == NULL) {
|
if (type == 1 && n->parent == NULL) {
|
||||||
@ -1688,7 +1765,7 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
|||||||
|
|
||||||
/* Compute length of AAIP string of root node */
|
/* Compute length of AAIP string of root node */
|
||||||
aaip_sua_free= 0;
|
aaip_sua_free= 0;
|
||||||
ret = add_aa_string(t, n, info, &aaip_sua_free, &aaip_len, 1);
|
ret = add_aa_string(t, n, NULL, &aaip_sua_free, &aaip_len, 1);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto add_susp_cleanup;
|
goto add_susp_cleanup;
|
||||||
|
|
||||||
@ -1774,12 +1851,13 @@ void rrip_write_susp_fields(Ecma119Image *t, struct susp_info *info,
|
|||||||
int rrip_write_ce_fields(Ecma119Image *t, struct susp_info *info)
|
int rrip_write_ce_fields(Ecma119Image *t, struct susp_info *info)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
uint8_t padding[BLOCK_SIZE];
|
uint8_t *padding = NULL;
|
||||||
int ret= ISO_SUCCESS;
|
int ret= ISO_SUCCESS;
|
||||||
|
|
||||||
if (info->n_ce_susp_fields == 0) {
|
if (info->n_ce_susp_fields == 0) {
|
||||||
return ret;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
LIBISO_ALLOC_MEM(padding, uint8_t, BLOCK_SIZE);
|
||||||
|
|
||||||
for (i = 0; i < info->n_ce_susp_fields; i++) {
|
for (i = 0; i < info->n_ce_susp_fields; i++) {
|
||||||
ret = iso_write(t, info->ce_susp_fields[i],
|
ret = iso_write(t, info->ce_susp_fields[i],
|
||||||
@ -1805,6 +1883,8 @@ int rrip_write_ce_fields(Ecma119Image *t, struct susp_info *info)
|
|||||||
info->ce_susp_fields = NULL;
|
info->ce_susp_fields = NULL;
|
||||||
info->n_ce_susp_fields = 0;
|
info->n_ce_susp_fields = 0;
|
||||||
info->ce_len = 0;
|
info->ce_len = 0;
|
||||||
|
ex:;
|
||||||
|
LIBISO_FREE_MEM(padding);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,8 +81,7 @@ int susp_iter_next(SuspIterator *iter, struct susp_sys_user_entry **sue)
|
|||||||
* (IEEE 1281, SUSP. section 4)
|
* (IEEE 1281, SUSP. section 4)
|
||||||
*/
|
*/
|
||||||
if (iter->ce_len) {
|
if (iter->ce_len) {
|
||||||
uint32_t block;
|
uint32_t block, nblocks;
|
||||||
int nblocks;
|
|
||||||
|
|
||||||
/* A CE has found, there is another continuation area */
|
/* A CE has found, there is another continuation area */
|
||||||
nblocks = DIV_UP(iter->ce_off + iter->ce_len, BLOCK_SIZE);
|
nblocks = DIV_UP(iter->ce_off + iter->ce_len, BLOCK_SIZE);
|
||||||
@ -443,7 +442,7 @@ int read_rr_PN(struct susp_sys_user_entry *pn, struct stat *st)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* AA is the field signature of AAIP versions < 2.0
|
/* AA is the obsolete field signature of AAIP versions < 2.0
|
||||||
*/
|
*/
|
||||||
int read_aaip_AA(struct susp_sys_user_entry *sue,
|
int read_aaip_AA(struct susp_sys_user_entry *sue,
|
||||||
unsigned char **aa_string, size_t *aa_size, size_t *aa_len,
|
unsigned char **aa_string, size_t *aa_size, size_t *aa_len,
|
||||||
@ -514,7 +513,7 @@ int read_aaip_AA(struct susp_sys_user_entry *sue,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* AL is the obsolete field signature of AAIP versions >= 2.0
|
/* AL is the field signature of AAIP versions >= 2.0
|
||||||
*/
|
*/
|
||||||
int read_aaip_AL(struct susp_sys_user_entry *sue,
|
int read_aaip_AL(struct susp_sys_user_entry *sue,
|
||||||
unsigned char **aa_string, size_t *aa_size, size_t *aa_len,
|
unsigned char **aa_string, size_t *aa_size, size_t *aa_len,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
* Copyright (c) 2009 Thomas Schmitt
|
* Copyright (c) 2009 - 2011 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* This file is part of the libisofs project; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License version 2
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -16,6 +16,7 @@
|
|||||||
#include "stream.h"
|
#include "stream.h"
|
||||||
#include "fsource.h"
|
#include "fsource.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "node.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -157,8 +158,64 @@ int fsrc_update_size(IsoStream *stream)
|
|||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
IsoStream *fsrc_get_input_stream(IsoStream *stream, int flag)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int fsrc_cmp_ino(IsoStream *s1, IsoStream *s2)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = iso_stream_cmp_ino(s1, s2, 1);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fsrc_clone_stream(IsoStream *old_stream, IsoStream **new_stream,
|
||||||
|
int flag)
|
||||||
|
{
|
||||||
|
FSrcStreamData *data, *new_data;
|
||||||
|
IsoStream *stream;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (flag)
|
||||||
|
return ISO_STREAM_NO_CLONE; /* unknown option required */
|
||||||
|
|
||||||
|
data = (FSrcStreamData*) old_stream->data;
|
||||||
|
if (data->src->class->version < 2)
|
||||||
|
return ISO_STREAM_NO_CLONE; /* No clone_src() method available */
|
||||||
|
|
||||||
|
*new_stream = NULL;
|
||||||
|
stream = calloc(1, sizeof(IsoStream));
|
||||||
|
if (stream == NULL)
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
new_data = calloc(1, sizeof(FSrcStreamData));
|
||||||
|
if (new_data == NULL) {
|
||||||
|
free((char *) stream);
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
}
|
||||||
|
*new_stream = stream;
|
||||||
|
stream->class = old_stream->class;
|
||||||
|
stream->refcount = 1;
|
||||||
|
stream->data = new_data;
|
||||||
|
|
||||||
|
ret = data->src->class->clone_src(data->src, &(new_data->src), 0);
|
||||||
|
if (ret < 0) {
|
||||||
|
free((char *) stream);
|
||||||
|
free((char *) new_data);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
new_data->dev_id = data->dev_id;
|
||||||
|
new_data->ino_id = data->ino_id;
|
||||||
|
new_data->size = data->size;
|
||||||
|
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
IsoStreamIface fsrc_stream_class = {
|
IsoStreamIface fsrc_stream_class = {
|
||||||
1, /* update_size is defined for this stream */
|
4, /* version */
|
||||||
"fsrc",
|
"fsrc",
|
||||||
fsrc_open,
|
fsrc_open,
|
||||||
fsrc_close,
|
fsrc_close,
|
||||||
@ -167,7 +224,10 @@ IsoStreamIface fsrc_stream_class = {
|
|||||||
fsrc_is_repeatable,
|
fsrc_is_repeatable,
|
||||||
fsrc_get_id,
|
fsrc_get_id,
|
||||||
fsrc_free,
|
fsrc_free,
|
||||||
fsrc_update_size
|
fsrc_update_size,
|
||||||
|
fsrc_get_input_stream,
|
||||||
|
fsrc_cmp_ino,
|
||||||
|
fsrc_clone_stream
|
||||||
};
|
};
|
||||||
|
|
||||||
int iso_file_source_stream_new(IsoFileSource *src, IsoStream **stream)
|
int iso_file_source_stream_new(IsoFileSource *src, IsoStream **stream)
|
||||||
@ -338,7 +398,7 @@ static
|
|||||||
int cut_out_read(IsoStream *stream, void *buf, size_t count)
|
int cut_out_read(IsoStream *stream, void *buf, size_t count)
|
||||||
{
|
{
|
||||||
struct cut_out_stream *data = stream->data;
|
struct cut_out_stream *data = stream->data;
|
||||||
count = (size_t)MIN(data->size - data->pos, count);
|
count = (size_t) MIN((size_t) (data->size - data->pos), count);
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -375,11 +435,76 @@ void cut_out_free(IsoStream *stream)
|
|||||||
free(data);
|
free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int cut_out_update_size(IsoStream *stream)
|
||||||
|
{
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
IsoStream* cut_out_get_input_stream(IsoStream *stream, int flag)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int cut_out_cmp_ino(IsoStream *s1, IsoStream *s2)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = iso_stream_cmp_ino(s1, s2, 1);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int cut_out_clone_stream(IsoStream *old_stream, IsoStream **new_stream,
|
||||||
|
int flag)
|
||||||
|
{
|
||||||
|
struct cut_out_stream *data, *new_data;
|
||||||
|
IsoStream *stream;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (flag)
|
||||||
|
return ISO_STREAM_NO_CLONE; /* unknown option required */
|
||||||
|
|
||||||
|
data = (struct cut_out_stream *) old_stream->data;
|
||||||
|
if (data->src->class->version < 2)
|
||||||
|
return ISO_STREAM_NO_CLONE; /* No clone_src() method available */
|
||||||
|
|
||||||
|
*new_stream = NULL;
|
||||||
|
stream = calloc(1, sizeof(IsoStream));
|
||||||
|
if (stream == NULL)
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
stream->refcount = 1;
|
||||||
|
stream->class = old_stream->class;
|
||||||
|
new_data = calloc(1, sizeof(struct cut_out_stream));
|
||||||
|
if (new_data == NULL) {
|
||||||
|
free((char *) stream);
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
}
|
||||||
|
ret = data->src->class->clone_src(data->src, &(new_data->src), 0);
|
||||||
|
if (ret < 0) {
|
||||||
|
free((char *) stream);
|
||||||
|
free((char *) new_data);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
new_data->dev_id = (dev_t) 0;
|
||||||
|
new_data->ino_id = cut_out_serial_id++;
|
||||||
|
new_data->offset = data->offset;
|
||||||
|
new_data->size = data->size;
|
||||||
|
new_data->pos = 0;
|
||||||
|
|
||||||
|
stream->data = new_data;
|
||||||
|
*new_stream = stream;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TODO update cut out streams to deal with update_size(). Seems hard.
|
* TODO update cut out streams to deal with update_size(). Seems hard.
|
||||||
*/
|
*/
|
||||||
IsoStreamIface cut_out_stream_class = {
|
IsoStreamIface cut_out_stream_class = {
|
||||||
0,
|
4, /* version */
|
||||||
"cout",
|
"cout",
|
||||||
cut_out_open,
|
cut_out_open,
|
||||||
cut_out_close,
|
cut_out_close,
|
||||||
@ -387,7 +512,12 @@ IsoStreamIface cut_out_stream_class = {
|
|||||||
cut_out_read,
|
cut_out_read,
|
||||||
cut_out_is_repeatable,
|
cut_out_is_repeatable,
|
||||||
cut_out_get_id,
|
cut_out_get_id,
|
||||||
cut_out_free
|
cut_out_free,
|
||||||
|
cut_out_update_size,
|
||||||
|
cut_out_get_input_stream,
|
||||||
|
cut_out_cmp_ino,
|
||||||
|
cut_out_clone_stream
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int iso_cut_out_stream_new(IsoFileSource *src, off_t offset, off_t size,
|
int iso_cut_out_stream_new(IsoFileSource *src, off_t offset, off_t size,
|
||||||
@ -517,7 +647,7 @@ int mem_read(IsoStream *stream, void *buf, size_t count)
|
|||||||
return ISO_FILE_NOT_OPENED;
|
return ISO_FILE_NOT_OPENED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data->offset >= data->size) {
|
if (data->offset >= (ssize_t) data->size) {
|
||||||
return 0; /* EOF */
|
return 0; /* EOF */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -549,12 +679,77 @@ void mem_free(IsoStream *stream)
|
|||||||
{
|
{
|
||||||
MemStreamData *data;
|
MemStreamData *data;
|
||||||
data = (MemStreamData*)stream->data;
|
data = (MemStreamData*)stream->data;
|
||||||
free(data->buf);
|
if (data->buf != NULL)
|
||||||
|
free(data->buf);
|
||||||
free(data);
|
free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int mem_update_size(IsoStream *stream)
|
||||||
|
{
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
IsoStream* mem_get_input_stream(IsoStream *stream, int flag)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int mem_cmp_ino(IsoStream *s1, IsoStream *s2)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = iso_stream_cmp_ino(s1, s2, 1);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int mem_clone_stream(IsoStream *old_stream, IsoStream **new_stream,
|
||||||
|
int flag)
|
||||||
|
{
|
||||||
|
MemStreamData *data, *new_data;
|
||||||
|
IsoStream *stream;
|
||||||
|
uint8_t *new_buf = NULL;
|
||||||
|
|
||||||
|
if (flag)
|
||||||
|
return ISO_STREAM_NO_CLONE; /* unknown option required */
|
||||||
|
|
||||||
|
*new_stream = NULL;
|
||||||
|
stream = calloc(1, sizeof(IsoStream));
|
||||||
|
if (stream == NULL)
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
stream->refcount = 1;
|
||||||
|
stream->class = old_stream->class;
|
||||||
|
new_data = calloc(1, sizeof(MemStreamData));
|
||||||
|
if (new_data == NULL) {
|
||||||
|
free((char *) stream);
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
}
|
||||||
|
data = (MemStreamData *) old_stream->data;
|
||||||
|
if (data->size > 0) {
|
||||||
|
new_buf = calloc(1, data->size);
|
||||||
|
if (new_buf == NULL) {
|
||||||
|
free((char *) stream);
|
||||||
|
free((char *) new_data);
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
}
|
||||||
|
memcpy(new_buf, data->buf, data->size);
|
||||||
|
}
|
||||||
|
new_data->buf = new_buf;
|
||||||
|
new_data->offset = -1;
|
||||||
|
new_data->ino_id = mem_serial_id++;
|
||||||
|
new_data->size = data->size;
|
||||||
|
|
||||||
|
stream->data = new_data;
|
||||||
|
*new_stream = stream;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
IsoStreamIface mem_stream_class = {
|
IsoStreamIface mem_stream_class = {
|
||||||
0,
|
4, /* version */
|
||||||
"mem ",
|
"mem ",
|
||||||
mem_open,
|
mem_open,
|
||||||
mem_close,
|
mem_close,
|
||||||
@ -562,7 +757,12 @@ IsoStreamIface mem_stream_class = {
|
|||||||
mem_read,
|
mem_read,
|
||||||
mem_is_repeatable,
|
mem_is_repeatable,
|
||||||
mem_get_id,
|
mem_get_id,
|
||||||
mem_free
|
mem_free,
|
||||||
|
mem_update_size,
|
||||||
|
mem_get_input_stream,
|
||||||
|
mem_cmp_ino,
|
||||||
|
mem_clone_stream
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -570,7 +770,7 @@ IsoStreamIface mem_stream_class = {
|
|||||||
* When the Stream refcount reach 0, the buffer is free(3).
|
* When the Stream refcount reach 0, the buffer is free(3).
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* 1 sucess, < 0 error
|
* 1 success, < 0 error
|
||||||
*/
|
*/
|
||||||
int iso_memory_stream_new(unsigned char *buf, size_t size, IsoStream **stream)
|
int iso_memory_stream_new(unsigned char *buf, size_t size, IsoStream **stream)
|
||||||
{
|
{
|
||||||
@ -669,7 +869,12 @@ void iso_stream_get_file_name(IsoStream *stream, char *name)
|
|||||||
if (!strncmp(type, "fsrc", 4)) {
|
if (!strncmp(type, "fsrc", 4)) {
|
||||||
FSrcStreamData *data = stream->data;
|
FSrcStreamData *data = stream->data;
|
||||||
char *path = iso_file_source_get_path(data->src);
|
char *path = iso_file_source_get_path(data->src);
|
||||||
strncpy(name, path, PATH_MAX);
|
if (path == NULL) {
|
||||||
|
name[0] = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
strncpy(name, path, PATH_MAX - 1);
|
||||||
|
name[PATH_MAX - 1] = 0;
|
||||||
free(path);
|
free(path);
|
||||||
} else if (!strncmp(type, "boot", 4)) {
|
} else if (!strncmp(type, "boot", 4)) {
|
||||||
strcpy(name, "BOOT CATALOG");
|
strcpy(name, "BOOT CATALOG");
|
||||||
@ -875,14 +1080,15 @@ int iso_stream_read_buffer(IsoStream *stream, char *buf, size_t count,
|
|||||||
*/
|
*/
|
||||||
int iso_stream_make_md5(IsoStream *stream, char md5[16], int flag)
|
int iso_stream_make_md5(IsoStream *stream, char md5[16], int flag)
|
||||||
{
|
{
|
||||||
int res, is_open = 0;
|
int ret, is_open = 0;
|
||||||
char buffer[2048];
|
char * buffer = NULL;
|
||||||
void *ctx= NULL;
|
void *ctx= NULL;
|
||||||
off_t file_size;
|
off_t file_size;
|
||||||
uint32_t b, nblocks;
|
uint32_t b, nblocks;
|
||||||
size_t got_bytes;
|
size_t got_bytes;
|
||||||
IsoStream *input_stream;
|
IsoStream *input_stream;
|
||||||
|
|
||||||
|
LIBISO_ALLOC_MEM(buffer, char, 2048);
|
||||||
if (flag & 1) {
|
if (flag & 1) {
|
||||||
while(1) {
|
while(1) {
|
||||||
input_stream = iso_stream_get_input_stream(stream, 0);
|
input_stream = iso_stream_get_input_stream(stream, 0);
|
||||||
@ -893,34 +1099,74 @@ int iso_stream_make_md5(IsoStream *stream, char md5[16], int flag)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (! iso_stream_is_repeatable(stream))
|
if (! iso_stream_is_repeatable(stream))
|
||||||
return 0;
|
{ret = 0; goto ex;}
|
||||||
res = iso_md5_start(&ctx);
|
ret = iso_md5_start(&ctx);
|
||||||
if (res < 0)
|
if (ret < 0)
|
||||||
return res;
|
goto ex;
|
||||||
res = iso_stream_open(stream);
|
ret = iso_stream_open(stream);
|
||||||
if (res < 0)
|
if (ret < 0)
|
||||||
return 0;
|
goto ex;
|
||||||
is_open = 1;
|
is_open = 1;
|
||||||
file_size = iso_stream_get_size(stream);
|
file_size = iso_stream_get_size(stream);
|
||||||
nblocks = DIV_UP(file_size, 2048);
|
nblocks = DIV_UP(file_size, 2048);
|
||||||
for (b = 0; b < nblocks; ++b) {
|
for (b = 0; b < nblocks; ++b) {
|
||||||
res = iso_stream_read_buffer(stream, buffer, 2048, &got_bytes);
|
ret = iso_stream_read_buffer(stream, buffer, 2048, &got_bytes);
|
||||||
if (res < 0) {
|
if (ret < 0) {
|
||||||
res = 0;
|
ret = 0;
|
||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
/* Do not use got_bytes to stay closer to IsoFileSrc processing */
|
/* Do not use got_bytes to stay closer to IsoFileSrc processing */
|
||||||
if (file_size - b * 2048 > 2048)
|
if (file_size - b * 2048 > 2048)
|
||||||
res = 2048;
|
ret = 2048;
|
||||||
else
|
else
|
||||||
res = file_size - b * 2048;
|
ret = file_size - b * 2048;
|
||||||
iso_md5_compute(ctx, buffer, res);
|
iso_md5_compute(ctx, buffer, ret);
|
||||||
}
|
}
|
||||||
res = 1;
|
ret = 1;
|
||||||
ex:;
|
ex:;
|
||||||
if (is_open)
|
if (is_open)
|
||||||
iso_stream_close(stream);
|
iso_stream_close(stream);
|
||||||
if (ctx != NULL)
|
if (ctx != NULL)
|
||||||
iso_md5_end(&ctx, md5);
|
iso_md5_end(&ctx, md5);
|
||||||
return res;
|
LIBISO_FREE_MEM(buffer);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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) 2007 Vreixo Formoso
|
||||||
* Copyright (c) 2009 Thomas Schmitt
|
* Copyright (c) 2009 - 2011 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* This file is part of the libisofs project; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License version 2
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
#include "fsource.h"
|
#include "fsource.h"
|
||||||
|
|
||||||
|
/* IMPORTANT: Any change must be reflected by fsrc_clone_stream */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
IsoFileSource *src;
|
IsoFileSource *src;
|
||||||
@ -28,7 +29,8 @@ typedef struct
|
|||||||
/**
|
/**
|
||||||
* Get an identifier for the file of the source, for debug purposes
|
* Get an identifier for the file of the source, for debug purposes
|
||||||
* @param name
|
* @param name
|
||||||
* Should provide at least PATH_MAX bytes
|
* Must provide at least PATH_MAX bytes. If no PATH_MAX is defined
|
||||||
|
* then assume PATH_MAX = Libisofs_default_path_maX from libisofs.h
|
||||||
*/
|
*/
|
||||||
void iso_stream_get_file_name(IsoStream *stream, char *name);
|
void iso_stream_get_file_name(IsoStream *stream, char *name);
|
||||||
|
|
||||||
@ -94,5 +96,20 @@ int iso_stream_read_buffer(IsoStream *stream, char *buf, size_t count,
|
|||||||
int iso_stream_make_md5(IsoStream *stream, char md5[16], int flag);
|
int iso_stream_make_md5(IsoStream *stream, char md5[16], int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a clone of the input stream of old_stream and a roughly initialized
|
||||||
|
* clone of old_stream which has the same class and refcount 1. Its data
|
||||||
|
* pointer will be NULL and needs to be filled by an expert which knows how
|
||||||
|
* to clone the data of old_stream.
|
||||||
|
* @param old_stream The existing stream which is in process of cloning
|
||||||
|
* @param new_stream Will return the uninitialized memory object which shall
|
||||||
|
* later become the clone of old_stream.
|
||||||
|
* @param new_input The clone of the input stream of old stream.
|
||||||
|
* @param flag Submit 0 for now.
|
||||||
|
* @return ISO_SUCCESS or an error code <0
|
||||||
|
*/
|
||||||
|
int iso_stream_clone_filter_common(IsoStream *old_stream,
|
||||||
|
IsoStream **new_stream,
|
||||||
|
IsoStream **new_input, int flag);
|
||||||
|
|
||||||
#endif /*STREAM_H_*/
|
#endif /*STREAM_H_*/
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2008 Vreixo Formoso
|
* Copyright (c) 2008 Vreixo Formoso
|
||||||
* Copyright (c) 2010 Thomas Schmitt
|
* Copyright (c) 2010 - 2011 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* This file is part of the libisofs project; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License version 2
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -305,9 +305,9 @@ static int boot_nodes_from_iso_path(Ecma119Image *t, char *path,
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = iso_tree_path_to_node(t->image, path, iso_node);
|
ret = iso_tree_path_to_node(t->image, path, iso_node);
|
||||||
if (ret < 0) {
|
if (ret <= 0) {
|
||||||
iso_msg_submit(t->image->id, ISO_BOOT_FILE_MISSING, 0,
|
iso_msg_submit(t->image->id, ISO_BOOT_FILE_MISSING, 0,
|
||||||
"Cannot find %s '%s'", purpose, path);
|
"Cannot find in ISO image: %s '%s'", purpose, path);
|
||||||
return ISO_BOOT_FILE_MISSING;
|
return ISO_BOOT_FILE_MISSING;
|
||||||
}
|
}
|
||||||
if ((*iso_node)->type != LIBISO_FILE) {
|
if ((*iso_node)->type != LIBISO_FILE) {
|
||||||
@ -387,7 +387,7 @@ static int make_mips_volume_header(Ecma119Image *t, uint8_t *buf, int flag)
|
|||||||
/* 84 - 87 | boot_bytes | File length in bytes */
|
/* 84 - 87 | boot_bytes | File length in bytes */
|
||||||
/* 88 - 311 | 0 | Volume Directory Entries 2 to 15 */
|
/* 88 - 311 | 0 | Volume Directory Entries 2 to 15 */
|
||||||
|
|
||||||
for (idx = 0; idx < t->image->num_mips_boot_files; idx++) {
|
for (idx = 0; (int) idx < t->image->num_mips_boot_files; idx++) {
|
||||||
ret = boot_nodes_from_iso_path(t, t->image->mips_boot_file_paths[idx],
|
ret = boot_nodes_from_iso_path(t, t->image->mips_boot_file_paths[idx],
|
||||||
&node, &ecma_node, "MIPS boot file", 0);
|
&node, &ecma_node, "MIPS boot file", 0);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
@ -457,18 +457,19 @@ int iso_read_mipsel_elf(Ecma119Image *t, int flag)
|
|||||||
{
|
{
|
||||||
uint32_t phdr_adr, todo, count;
|
uint32_t phdr_adr, todo, count;
|
||||||
int ret;
|
int ret;
|
||||||
uint8_t elf_buf[2048];
|
uint8_t *elf_buf = NULL;
|
||||||
IsoNode *iso_node;
|
IsoNode *iso_node;
|
||||||
Ecma119Node *ecma_node;
|
Ecma119Node *ecma_node;
|
||||||
IsoStream *stream;
|
IsoStream *stream;
|
||||||
|
|
||||||
if (t->image->num_mips_boot_files <= 0)
|
if (t->image->num_mips_boot_files <= 0)
|
||||||
return ISO_SUCCESS;
|
{ret = ISO_SUCCESS; goto ex;}
|
||||||
|
|
||||||
|
LIBISO_ALLOC_MEM(elf_buf, uint8_t, 2048);
|
||||||
ret = boot_nodes_from_iso_path(t, t->image->mips_boot_file_paths[0],
|
ret = boot_nodes_from_iso_path(t, t->image->mips_boot_file_paths[0],
|
||||||
&iso_node, &ecma_node, "MIPS boot file", 0);
|
&iso_node, &ecma_node, "MIPS boot file", 0);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
goto ex;
|
||||||
stream = iso_file_get_stream((IsoFile *) iso_node);
|
stream = iso_file_get_stream((IsoFile *) iso_node);
|
||||||
|
|
||||||
ret = iso_stream_open(stream);
|
ret = iso_stream_open(stream);
|
||||||
@ -476,7 +477,7 @@ int iso_read_mipsel_elf(Ecma119Image *t, int flag)
|
|||||||
iso_msg_submit(t->image->id, ret, 0,
|
iso_msg_submit(t->image->id, ret, 0,
|
||||||
"Cannot open designated MIPS boot file '%s'",
|
"Cannot open designated MIPS boot file '%s'",
|
||||||
t->image->mips_boot_file_paths[0]);
|
t->image->mips_boot_file_paths[0]);
|
||||||
return ret;
|
goto ex;
|
||||||
}
|
}
|
||||||
ret = iso_stream_read(stream, elf_buf, 32);
|
ret = iso_stream_read(stream, elf_buf, 32);
|
||||||
if (ret != 32) {
|
if (ret != 32) {
|
||||||
@ -485,7 +486,7 @@ cannot_read:;
|
|||||||
iso_msg_submit(t->image->id, ret, 0,
|
iso_msg_submit(t->image->id, ret, 0,
|
||||||
"Cannot read from designated MIPS boot file '%s'",
|
"Cannot read from designated MIPS boot file '%s'",
|
||||||
t->image->mips_boot_file_paths[0]);
|
t->image->mips_boot_file_paths[0]);
|
||||||
return ret;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -504,7 +505,7 @@ cannot_read:;
|
|||||||
count = todo;
|
count = todo;
|
||||||
todo -= count;
|
todo -= count;
|
||||||
ret = iso_stream_read(stream, elf_buf, count);
|
ret = iso_stream_read(stream, elf_buf, count);
|
||||||
if (ret != count)
|
if (ret != (int) count)
|
||||||
goto cannot_read;
|
goto cannot_read;
|
||||||
}
|
}
|
||||||
ret = iso_stream_read(stream, elf_buf, 20);
|
ret = iso_stream_read(stream, elf_buf, 20);
|
||||||
@ -521,7 +522,10 @@ cannot_read:;
|
|||||||
t->mipsel_p_filesz = iso_read_lsb(elf_buf + 16, 4);
|
t->mipsel_p_filesz = iso_read_lsb(elf_buf + 16, 4);
|
||||||
|
|
||||||
iso_stream_close(stream);
|
iso_stream_close(stream);
|
||||||
return ISO_SUCCESS;
|
ret = ISO_SUCCESS;
|
||||||
|
ex:;
|
||||||
|
LIBISO_FREE_MEM(elf_buf);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -809,3 +813,122 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
|
|||||||
|
|
||||||
return ISO_SUCCESS;
|
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 = NULL;
|
||||||
|
|
||||||
|
LIBISO_ALLOC_MEM(msg, char, 160);
|
||||||
|
sa_type = (t->system_area_options >> 2) & 0x3f;
|
||||||
|
if (sa_type != 0)
|
||||||
|
{ret = ISO_SUCCESS; goto ex;}
|
||||||
|
always_align = (t->system_area_options >> 8) & 3;
|
||||||
|
|
||||||
|
img_blocks = t->curblock + t->tail_blocks;
|
||||||
|
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)
|
||||||
|
{ret = ISO_SUCCESS; goto ex;}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{ret = ISO_SUCCESS; goto ex;}
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
{ret = ISO_ISOLINUX_CANT_PATCH; goto ex;}
|
||||||
|
}
|
||||||
|
cylsize = t->partition_heads_per_cyl * t->partition_secs_per_head
|
||||||
|
* 512;
|
||||||
|
}
|
||||||
|
if (cylsize == 0)
|
||||||
|
{ret = ISO_SUCCESS; goto ex;}
|
||||||
|
if (((double) imgsize) / (double) cylsize > 1024.0) {
|
||||||
|
iso_msgs_submit(0,
|
||||||
|
"Image size exceeds 1024 cylinders. Cannot align partition.",
|
||||||
|
0, "WARNING", 0);
|
||||||
|
{ret = ISO_SUCCESS; goto ex;}
|
||||||
|
}
|
||||||
|
|
||||||
|
frac = imgsize % cylsize;
|
||||||
|
imgsize += (frac > 0 ? cylsize - frac : 0);
|
||||||
|
|
||||||
|
frac = imgsize - ((off_t) img_blocks) * (off_t) 2048;
|
||||||
|
if (frac == 0)
|
||||||
|
{ret = ISO_SUCCESS; goto ex;}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
ret = ISO_SUCCESS;
|
||||||
|
ex:;
|
||||||
|
LIBISO_FREE_MEM(msg);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
@ -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);
|
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.
|
* Read the necessary ELF information from the first MIPS boot file.
|
||||||
|
263
libisofs/tree.c
263
libisofs/tree.c
@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
|
* Copyright (c) 2011 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* This file is part of the libisofs project; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License version 2
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -31,11 +32,6 @@
|
|||||||
#include <fnmatch.h>
|
#include <fnmatch.h>
|
||||||
|
|
||||||
|
|
||||||
#ifndef PATH_MAX
|
|
||||||
#define PATH_MAX Libisofs_default_path_maX
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a new directory to the iso tree.
|
* Add a new directory to the iso tree.
|
||||||
*
|
*
|
||||||
@ -482,12 +478,12 @@ int iso_tree_remove_exclude(IsoImage *image, const char *path)
|
|||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < image->nexcludes; ++i) {
|
for (i = 0; (int) i < image->nexcludes; ++i) {
|
||||||
if (strcmp(image->excludes[i], path) == 0) {
|
if (strcmp(image->excludes[i], path) == 0) {
|
||||||
/* exclude found */
|
/* exclude found */
|
||||||
free(image->excludes[i]);
|
free(image->excludes[i]);
|
||||||
--image->nexcludes;
|
--image->nexcludes;
|
||||||
for (j = i; j < image->nexcludes; ++j) {
|
for (j = i; (int) j < image->nexcludes; ++j) {
|
||||||
image->excludes[j] = image->excludes[j+1];
|
image->excludes[j] = image->excludes[j+1];
|
||||||
}
|
}
|
||||||
image->excludes = realloc(image->excludes, image->nexcludes *
|
image->excludes = realloc(image->excludes, image->nexcludes *
|
||||||
@ -578,20 +574,19 @@ int iso_tree_add_new_node(IsoImage *image, IsoDir *parent, const char *name,
|
|||||||
*node = NULL;
|
*node = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
fs = image->fs;
|
|
||||||
result = fs->get_by_path(fs, path, &file);
|
|
||||||
if (result < 0) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* find place where to insert */
|
/* find place where to insert */
|
||||||
result = iso_dir_exists(parent, name, &pos);
|
result = iso_dir_exists(parent, name, &pos);
|
||||||
if (result) {
|
if (result) {
|
||||||
/* a node with same name already exists */
|
/* a node with same name already exists */
|
||||||
iso_file_source_unref(file);
|
|
||||||
return ISO_NODE_NAME_NOT_UNIQUE;
|
return ISO_NODE_NAME_NOT_UNIQUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fs = image->fs;
|
||||||
|
result = fs->get_by_path(fs, path, &file);
|
||||||
|
if (result < 0) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
result = image->builder->create_node(image->builder, image, file, &new);
|
result = image->builder->create_node(image->builder, image, file, &new);
|
||||||
|
|
||||||
/* free the file */
|
/* free the file */
|
||||||
@ -766,11 +761,16 @@ int iso_add_dir_src_rec(IsoImage *image, IsoDir *parent, IsoFileSource *dir)
|
|||||||
|
|
||||||
ret = iso_file_source_open(dir);
|
ret = iso_file_source_open(dir);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
char *path = iso_file_source_get_path(dir);
|
path = iso_file_source_get_path(dir);
|
||||||
/* instead of the probable error, we throw a sorry event */
|
/* instead of the probable error, we throw a sorry event */
|
||||||
ret = iso_msg_submit(image->id, ISO_FILE_CANT_ADD, ret,
|
if (path != NULL) {
|
||||||
"Can't open dir %s", path);
|
ret = iso_msg_submit(image->id, ISO_FILE_CANT_ADD, ret,
|
||||||
free(path);
|
"Can't open dir %s", path);
|
||||||
|
free(path);
|
||||||
|
} else {
|
||||||
|
ret = iso_msg_submit(image->id, ISO_NULL_POINTER, ret,
|
||||||
|
"Can't open dir. NULL pointer caught as dir name");
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -790,6 +790,11 @@ int iso_add_dir_src_rec(IsoImage *image, IsoDir *parent, IsoFileSource *dir)
|
|||||||
}
|
}
|
||||||
|
|
||||||
path = iso_file_source_get_path(file);
|
path = iso_file_source_get_path(file);
|
||||||
|
if (path == NULL) {
|
||||||
|
ret = iso_msg_submit(image->id, ISO_NULL_POINTER, ret,
|
||||||
|
"NULL pointer caught as file path");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
name = strrchr(path, '/') + 1;
|
name = strrchr(path, '/') + 1;
|
||||||
|
|
||||||
if (image->follow_symlinks) {
|
if (image->follow_symlinks) {
|
||||||
@ -852,7 +857,7 @@ int iso_add_dir_src_rec(IsoImage *image, IsoDir *parent, IsoFileSource *dir)
|
|||||||
ret = iso_dir_insert(parent, new, pos, replace);
|
ret = iso_dir_insert(parent, new, pos, replace);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
iso_node_unref(new);
|
iso_node_unref(new);
|
||||||
if (ret != ISO_NODE_NAME_NOT_UNIQUE) {
|
if (ret != (int) ISO_NODE_NAME_NOT_UNIQUE) {
|
||||||
/* error */
|
/* error */
|
||||||
goto dir_rec_continue;
|
goto dir_rec_continue;
|
||||||
} else {
|
} else {
|
||||||
@ -972,24 +977,222 @@ int iso_tree_path_to_node(IsoImage *image, const char *path, IsoNode **node)
|
|||||||
|
|
||||||
char *iso_tree_get_node_path(IsoNode *node)
|
char *iso_tree_get_node_path(IsoNode *node)
|
||||||
{
|
{
|
||||||
if (node == NULL || node->parent == NULL) {
|
char *path = NULL, *parent_path = NULL;
|
||||||
|
|
||||||
|
if (node == NULL || node->parent == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
|
|
||||||
if ((IsoNode*)node->parent == node) {
|
if ((IsoNode*)node->parent == node) {
|
||||||
return strdup("/");
|
return strdup("/");
|
||||||
} else {
|
} else {
|
||||||
char path[PATH_MAX];
|
parent_path = iso_tree_get_node_path((IsoNode*)node->parent);
|
||||||
char *parent_path = iso_tree_get_node_path((IsoNode*)node->parent);
|
if (parent_path == NULL)
|
||||||
if (parent_path == NULL) {
|
goto ex;
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (strlen(parent_path) == 1) {
|
if (strlen(parent_path) == 1) {
|
||||||
snprintf(path, PATH_MAX, "/%s", node->name);
|
path = calloc(1, strlen(node->name) + 2);
|
||||||
|
if (path == NULL)
|
||||||
|
goto ex;
|
||||||
|
sprintf(path, "/%s", node->name);
|
||||||
} else {
|
} else {
|
||||||
snprintf(path, PATH_MAX, "%s/%s", parent_path, node->name);
|
path = calloc(1, strlen(parent_path) + strlen(node->name) + 2);
|
||||||
|
if (path == NULL)
|
||||||
|
goto ex;
|
||||||
|
sprintf(path, "%s/%s", parent_path, node->name);
|
||||||
}
|
}
|
||||||
free(parent_path);
|
|
||||||
return strdup(path);
|
|
||||||
}
|
}
|
||||||
|
ex:;
|
||||||
|
if (parent_path != NULL)
|
||||||
|
free(parent_path);
|
||||||
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ------------------------- tree cloning ------------------------------ */
|
||||||
|
|
||||||
|
static
|
||||||
|
int iso_tree_copy_node_attr(IsoNode *old_node, IsoNode *new_node, int flag)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
new_node->mode = old_node->mode;
|
||||||
|
new_node->uid = old_node->uid;
|
||||||
|
new_node->gid = old_node->gid;
|
||||||
|
new_node->atime = old_node->atime;
|
||||||
|
new_node->mtime = old_node->mtime;
|
||||||
|
new_node->ctime = old_node->ctime;
|
||||||
|
new_node->hidden = old_node->hidden;
|
||||||
|
ret = iso_node_clone_xinfo(old_node, new_node, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
@param flag bit0= merge directory with *new_node
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
int iso_tree_clone_dir(IsoDir *old_dir,
|
||||||
|
IsoDir *new_parent, char *new_name, IsoNode **new_node,
|
||||||
|
int flag)
|
||||||
|
{
|
||||||
|
IsoDir *new_dir = NULL;
|
||||||
|
IsoNode *sub_node = NULL, *new_sub_node = NULL;
|
||||||
|
IsoDirIter *iter = NULL;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (flag & 1) {
|
||||||
|
new_dir = (IsoDir *) *new_node;
|
||||||
|
} else {
|
||||||
|
*new_node = NULL;
|
||||||
|
ret = iso_tree_add_new_dir(new_parent, new_name, &new_dir);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
/* Avoid traversal of target directory to allow cloning of old_dir to a
|
||||||
|
subordinate of old_dir.
|
||||||
|
*/
|
||||||
|
iso_node_take((IsoNode *) new_dir);
|
||||||
|
|
||||||
|
ret = iso_dir_get_children(old_dir, &iter);
|
||||||
|
if (ret < 0)
|
||||||
|
goto ex;
|
||||||
|
while(1) {
|
||||||
|
ret = iso_dir_iter_next(iter, &sub_node);
|
||||||
|
if (ret == 0)
|
||||||
|
break;
|
||||||
|
ret = iso_tree_clone(sub_node, new_dir, sub_node->name, &new_sub_node,
|
||||||
|
flag & 1);
|
||||||
|
if (ret < 0)
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now graft in the new tree resp. graft back the merged tree */
|
||||||
|
ret = iso_dir_add_node(new_parent, (IsoNode *) new_dir, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
goto ex;
|
||||||
|
|
||||||
|
if (!(flag & 1))
|
||||||
|
*new_node = (IsoNode *) new_dir;
|
||||||
|
ret = ISO_SUCCESS;
|
||||||
|
ex:;
|
||||||
|
if (iter != NULL)
|
||||||
|
iso_dir_iter_free(iter);
|
||||||
|
if (ret < 0 && new_dir != NULL) {
|
||||||
|
if (flag & 1) {
|
||||||
|
/* graft back the merged tree (eventually with half copy) */
|
||||||
|
iso_dir_add_node(new_parent, (IsoNode *) new_dir, 0);
|
||||||
|
} else {
|
||||||
|
iso_node_remove_tree((IsoNode *) new_dir, NULL);
|
||||||
|
*new_node = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int iso_tree_clone_file(IsoFile *old_file,
|
||||||
|
IsoDir *new_parent, char *new_name, IsoNode **new_node,
|
||||||
|
int flag)
|
||||||
|
{
|
||||||
|
IsoStream *new_stream = NULL;
|
||||||
|
IsoFile *new_file = NULL;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
*new_node = NULL;
|
||||||
|
|
||||||
|
ret = iso_stream_clone(old_file->stream, &new_stream, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = iso_tree_add_new_file(new_parent, new_name, new_stream, &new_file);
|
||||||
|
if (ret < 0)
|
||||||
|
goto ex;
|
||||||
|
new_stream = NULL; /* now owned by new_file */
|
||||||
|
new_file->sort_weight = old_file->sort_weight;
|
||||||
|
*new_node = (IsoNode *) new_file;
|
||||||
|
ret = ISO_SUCCESS;
|
||||||
|
ex:;
|
||||||
|
if (new_stream != NULL)
|
||||||
|
iso_stream_unref(new_stream);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int iso_tree_clone_symlink(IsoSymlink *node,
|
||||||
|
IsoDir *new_parent, char *new_name, IsoNode **new_node,
|
||||||
|
int flag)
|
||||||
|
{
|
||||||
|
IsoSymlink *new_sym;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
*new_node = NULL;
|
||||||
|
|
||||||
|
ret = iso_tree_add_new_symlink(new_parent, new_name, node->dest, &new_sym);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
new_sym->fs_id = node->fs_id;
|
||||||
|
new_sym->st_dev = node->st_dev;
|
||||||
|
new_sym->st_ino = node->st_ino;
|
||||||
|
*new_node = (IsoNode *) new_sym;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int iso_tree_clone_special(IsoSpecial *node,
|
||||||
|
IsoDir *new_parent, char *new_name, IsoNode **new_node,
|
||||||
|
int flag)
|
||||||
|
{
|
||||||
|
IsoSpecial *new_spec;
|
||||||
|
IsoNode *iso_node;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
iso_node = (IsoNode *) node;
|
||||||
|
ret = iso_tree_add_new_special(new_parent, new_name, iso_node->mode,
|
||||||
|
node->dev, &new_spec);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
new_spec->fs_id = node->fs_id;
|
||||||
|
new_spec->st_dev = node->st_dev;
|
||||||
|
new_spec->st_ino = node->st_ino;
|
||||||
|
*new_node = (IsoNode *) new_spec;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* API */
|
||||||
|
int iso_tree_clone(IsoNode *node,
|
||||||
|
IsoDir *new_parent, char *new_name, IsoNode **new_node,
|
||||||
|
int flag)
|
||||||
|
{
|
||||||
|
int ret = ISO_SUCCESS;
|
||||||
|
|
||||||
|
if (iso_dir_get_node(new_parent, new_name, new_node) == 1) {
|
||||||
|
if (! (node->type == LIBISO_DIR && (*new_node)->type == LIBISO_DIR &&
|
||||||
|
(flag & 1))) {
|
||||||
|
*new_node = NULL;
|
||||||
|
return ISO_NODE_NAME_NOT_UNIQUE;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
flag &= ~1;
|
||||||
|
|
||||||
|
if (node->type == LIBISO_DIR) {
|
||||||
|
ret = iso_tree_clone_dir((IsoDir *) node, new_parent, new_name,
|
||||||
|
new_node, flag & 1);
|
||||||
|
} else if (node->type == LIBISO_FILE) {
|
||||||
|
ret = iso_tree_clone_file((IsoFile *) node, new_parent, new_name,
|
||||||
|
new_node, 0);
|
||||||
|
} else if (node->type == LIBISO_SYMLINK) {
|
||||||
|
ret = iso_tree_clone_symlink((IsoSymlink *) node, new_parent, new_name,
|
||||||
|
new_node, 0);
|
||||||
|
} else if (node->type == LIBISO_SPECIAL) {
|
||||||
|
ret = iso_tree_clone_special((IsoSpecial *) node, new_parent, new_name,
|
||||||
|
new_node, 0);
|
||||||
|
} else if (node->type == LIBISO_BOOT) {
|
||||||
|
ret = ISO_SUCCESS; /* API says they are silently ignored */
|
||||||
|
}
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
if (flag & 1)
|
||||||
|
return 2; /* merged two directories, *new_node is not new */
|
||||||
|
ret = iso_tree_copy_node_attr(node, *new_node, 0);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
234
libisofs/util.c
234
libisofs/util.c
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
* Copyright (c) 2007 Mario Danic
|
* Copyright (c) 2007 Mario Danic
|
||||||
* Copyright (c) 2009 Thomas Schmitt
|
* Copyright (c) 2009 - 2011 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* This file is part of the libisofs project; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License version 2
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -16,6 +16,7 @@
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "libisofs.h"
|
#include "libisofs.h"
|
||||||
#include "messages.h"
|
#include "messages.h"
|
||||||
|
#include "joliet.h"
|
||||||
#include "../version.h"
|
#include "../version.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -218,7 +219,7 @@ int strconv(const char *str, const char *icharset, const char *ocharset,
|
|||||||
src = (char *)str;
|
src = (char *)str;
|
||||||
ret = (char *)out;
|
ret = (char *)out;
|
||||||
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
|
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
|
||||||
if (n == -1) {
|
if (n == (size_t) -1) {
|
||||||
/* error */
|
/* error */
|
||||||
iso_iconv_close(&conv, 0);
|
iso_iconv_close(&conv, 0);
|
||||||
retval = ISO_CHARSET_CONV_ERROR;
|
retval = ISO_CHARSET_CONV_ERROR;
|
||||||
@ -268,7 +269,7 @@ int strnconv(const char *str, const char *icharset, const char *ocharset,
|
|||||||
src = (char *)str;
|
src = (char *)str;
|
||||||
ret = (char *)out;
|
ret = (char *)out;
|
||||||
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
|
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
|
||||||
if (n == -1) {
|
if (n == (size_t) -1) {
|
||||||
/* error */
|
/* error */
|
||||||
iso_iconv_close(&conv, 0);
|
iso_iconv_close(&conv, 0);
|
||||||
retval = ISO_CHARSET_CONV_ERROR;
|
retval = ISO_CHARSET_CONV_ERROR;
|
||||||
@ -335,7 +336,7 @@ int str2wchar(const char *icharset, const char *input, wchar_t **output)
|
|||||||
src = (char *)input;
|
src = (char *)input;
|
||||||
|
|
||||||
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
|
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
|
||||||
while (n == -1) {
|
while (n == (size_t) -1) {
|
||||||
|
|
||||||
if (errno == E2BIG) {
|
if (errno == E2BIG) {
|
||||||
/* error, should never occur */
|
/* error, should never occur */
|
||||||
@ -434,7 +435,7 @@ int str2ascii(const char *icharset, const char *input, char **output)
|
|||||||
}
|
}
|
||||||
|
|
||||||
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
|
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
|
||||||
while (n == -1) {
|
while (n == (size_t) -1) {
|
||||||
/* The destination buffer is too small. Stops here. */
|
/* The destination buffer is too small. Stops here. */
|
||||||
if (errno == E2BIG)
|
if (errno == E2BIG)
|
||||||
break;
|
break;
|
||||||
@ -565,7 +566,7 @@ int str2ucs(const char *icharset, const char *input, uint16_t **output)
|
|||||||
}
|
}
|
||||||
|
|
||||||
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
|
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
|
||||||
while (n == -1) {
|
while (n == (size_t) -1) {
|
||||||
/* The destination buffer is too small. Stops here. */
|
/* The destination buffer is too small. Stops here. */
|
||||||
if (errno == E2BIG)
|
if (errno == E2BIG)
|
||||||
break;
|
break;
|
||||||
@ -635,7 +636,7 @@ char *iso_dirid(const char *src, int size)
|
|||||||
char name[32];
|
char name[32];
|
||||||
|
|
||||||
len = strlen(src);
|
len = strlen(src);
|
||||||
if (len > size) {
|
if ((int) len > size) {
|
||||||
len = size;
|
len = size;
|
||||||
}
|
}
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
@ -769,7 +770,7 @@ char *iso_r_dirid(const char *src, int size, int relaxed)
|
|||||||
char *dest;
|
char *dest;
|
||||||
|
|
||||||
len = strlen(src);
|
len = strlen(src);
|
||||||
if (len > size) {
|
if ((int) len > size) {
|
||||||
len = size;
|
len = size;
|
||||||
}
|
}
|
||||||
dest = malloc(len + 1);
|
dest = malloc(len + 1);
|
||||||
@ -837,15 +838,15 @@ char *iso_r_fileid(const char *src, size_t len, int relaxed, int forcedot)
|
|||||||
*/
|
*/
|
||||||
if (dot == NULL || *(dot + 1) == '\0') {
|
if (dot == NULL || *(dot + 1) == '\0') {
|
||||||
lname = strlen(src);
|
lname = strlen(src);
|
||||||
lnname = (lname > len) ? len : lname;
|
lnname = (lname > (int) len) ? (int) len : lname;
|
||||||
lext = lnext = 0;
|
lext = lnext = 0;
|
||||||
} else {
|
} else {
|
||||||
lext = strlen(dot + 1);
|
lext = strlen(dot + 1);
|
||||||
lname = strlen(src) - lext - 1;
|
lname = strlen(src) - lext - 1;
|
||||||
lnext = (strlen(src) > len + 1 && lext > 3) ?
|
lnext = (strlen(src) > len + 1 && lext > 3) ?
|
||||||
(lname < len - 3 ? len - lname : 3)
|
(lname < (int) len - 3 ? (int) len - lname : 3)
|
||||||
: lext;
|
: lext;
|
||||||
lnname = (strlen(src) > len + 1) ? len - lnext : lname;
|
lnname = (strlen(src) > len + 1) ? (int) len - lnext : lname;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lnname == 0 && lnext == 0) {
|
if (lnname == 0 && lnext == 0) {
|
||||||
@ -916,16 +917,23 @@ ex:;
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
bit0= no_force_dots
|
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 *iso_j_file_id(const uint16_t *src, int flag)
|
||||||
{
|
{
|
||||||
uint16_t *dot;
|
uint16_t *dot, *retval = NULL;
|
||||||
size_t lname, lext, lnname, lnext, pos, i;
|
size_t lname, lext, lnname, lnext, pos, i, maxchar = 64;
|
||||||
uint16_t dest[66]; /* 66 = 64 (name + ext) + 1 (.) + 1 (\0) */
|
uint16_t *dest = NULL;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
LIBISO_ALLOC_MEM(dest, uint16_t, LIBISO_JOLIET_NAME_MAX);
|
||||||
|
/* was: 66 = 64 (name + ext) + 1 (.) + 1 (\0) */
|
||||||
|
|
||||||
if (src == NULL) {
|
if (src == NULL) {
|
||||||
return NULL;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
if (flag & 2)
|
||||||
|
maxchar = 103;
|
||||||
|
|
||||||
dot = ucsrchr(src, '.');
|
dot = ucsrchr(src, '.');
|
||||||
|
|
||||||
@ -937,18 +945,19 @@ uint16_t *iso_j_file_id(const uint16_t *src, int flag)
|
|||||||
*/
|
*/
|
||||||
if (dot == NULL || cmp_ucsbe(dot + 1, '\0') == 0) {
|
if (dot == NULL || cmp_ucsbe(dot + 1, '\0') == 0) {
|
||||||
lname = ucslen(src);
|
lname = ucslen(src);
|
||||||
lnname = (lname > 64) ? 64 : lname;
|
lnname = (lname > maxchar) ? maxchar : lname;
|
||||||
lext = lnext = 0;
|
lext = lnext = 0;
|
||||||
} else {
|
} else {
|
||||||
lext = ucslen(dot + 1);
|
lext = ucslen(dot + 1);
|
||||||
lname = ucslen(src) - lext - 1;
|
lname = ucslen(src) - lext - 1;
|
||||||
lnext = (ucslen(src) > 65 && lext > 3) ? (lname < 61 ? 64 - lname : 3)
|
lnext = (ucslen(src) > maxchar + 1 && lext > 3)
|
||||||
|
? (lname < maxchar - 3 ? maxchar - lname : 3)
|
||||||
: lext;
|
: lext;
|
||||||
lnname = (ucslen(src) > 65) ? 64 - lnext : lname;
|
lnname = (ucslen(src) > maxchar + 1) ? maxchar - lnext : lname;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lnname == 0 && lnext == 0) {
|
if (lnname == 0 && lnext == 0) {
|
||||||
return NULL;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
pos = 0;
|
pos = 0;
|
||||||
@ -983,21 +992,31 @@ uint16_t *iso_j_file_id(const uint16_t *src, int flag)
|
|||||||
|
|
||||||
is_done:;
|
is_done:;
|
||||||
set_ucsbe(dest + pos, '\0');
|
set_ucsbe(dest + pos, '\0');
|
||||||
return ucsdup(dest);
|
retval = ucsdup(dest);
|
||||||
|
ex:;
|
||||||
|
LIBISO_FREE_MEM(dest);
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t *iso_j_dir_id(const uint16_t *src)
|
/* @param flag bit1= allow 103 characters rather than 64
|
||||||
|
*/
|
||||||
|
uint16_t *iso_j_dir_id(const uint16_t *src, int flag)
|
||||||
{
|
{
|
||||||
size_t len, i;
|
size_t len, i, maxchar = 64;
|
||||||
uint16_t dest[65]; /* 65 = 64 + 1 (\0) */
|
uint16_t *dest = NULL, *retval = NULL;
|
||||||
|
int ret;
|
||||||
|
/* was: 65 = 64 + 1 (\0) */
|
||||||
|
LIBISO_ALLOC_MEM(dest, uint16_t, LIBISO_JOLIET_NAME_MAX);
|
||||||
|
|
||||||
if (src == NULL) {
|
if (src == NULL) {
|
||||||
return NULL;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
if (flag & 2)
|
||||||
|
maxchar = 103;
|
||||||
|
|
||||||
len = ucslen(src);
|
len = ucslen(src);
|
||||||
if (len > 64) {
|
if (len > maxchar) {
|
||||||
len = 64;
|
len = maxchar;
|
||||||
}
|
}
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
uint16_t c = src[i];
|
uint16_t c = src[i];
|
||||||
@ -1008,7 +1027,10 @@ uint16_t *iso_j_dir_id(const uint16_t *src)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
set_ucsbe(dest + len, '\0');
|
set_ucsbe(dest + len, '\0');
|
||||||
return ucsdup(dest);
|
retval = ucsdup(dest);
|
||||||
|
ex:
|
||||||
|
LIBISO_FREE_MEM(dest);
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ucslen(const uint16_t *str)
|
size_t ucslen(const uint16_t *str)
|
||||||
@ -1298,12 +1320,41 @@ void iso_datetime_17(unsigned char *buf, time_t t, int always_gmt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef HAVE_TIMEGM
|
#ifndef HAVE_TIMEGM
|
||||||
|
|
||||||
|
/* putenv is SVr4, POSIX.1-2001, 4.3BSD , setenv is 4.3BSD, POSIX.1-2001.
|
||||||
|
So putenv is more widely available.
|
||||||
|
Also, setenv spoils eventual putenv expectation of applications because
|
||||||
|
putenv installs the original string which then may be altered from
|
||||||
|
its owner. setenv installs a copy that may not be altered.
|
||||||
|
Both are slow.
|
||||||
|
Thus first try with a naive implementation that assumes no leap seconds.
|
||||||
|
If it fails a test with gmtime() then use the slow function with mktime().
|
||||||
|
*/
|
||||||
|
#define Libisofs_use_putenV yes
|
||||||
|
|
||||||
static
|
static
|
||||||
time_t timegm(struct tm *tm)
|
time_t env_timegm(struct tm *tm)
|
||||||
{
|
{
|
||||||
time_t ret;
|
time_t ret;
|
||||||
char *tz;
|
char *tz;
|
||||||
|
|
||||||
|
#ifdef Libisofs_use_putenV
|
||||||
|
|
||||||
|
static char unset_name[] = {"TZ"};
|
||||||
|
|
||||||
|
tz = getenv("TZ");
|
||||||
|
putenv("TZ=");
|
||||||
|
tzset();
|
||||||
|
ret = mktime(tm);
|
||||||
|
if (tz != NULL) {
|
||||||
|
/* tz is a pointer to the value part in a string of form "TZ="value */
|
||||||
|
putenv(tz - 3);
|
||||||
|
} else
|
||||||
|
putenv(unset_name); /* not daring to submit constant */
|
||||||
|
tzset();
|
||||||
|
|
||||||
|
#else /* Libisofs_use_putenV */
|
||||||
|
|
||||||
tz = getenv("TZ");
|
tz = getenv("TZ");
|
||||||
setenv("TZ", "", 1);
|
setenv("TZ", "", 1);
|
||||||
tzset();
|
tzset();
|
||||||
@ -1313,9 +1364,92 @@ time_t timegm(struct tm *tm)
|
|||||||
else
|
else
|
||||||
unsetenv("TZ");
|
unsetenv("TZ");
|
||||||
tzset();
|
tzset();
|
||||||
|
|
||||||
|
#endif /* ! Libisofs_use_putenV */
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
static
|
||||||
|
int ts_is_leapyear(int tm_year) /* years since 1900 */
|
||||||
|
{
|
||||||
|
return ((tm_year % 4) == 0 && ((tm_year % 100) != 0 ||
|
||||||
|
(tm_year % 400) == 100));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fast implementation without leap seconds.
|
||||||
|
Inspired by but not copied from code by Kungliga Tekniska Hgskolan
|
||||||
|
(Royal Institute of Technology, Stockholm, Sweden),
|
||||||
|
which was modified by Andrew Tridgell for Samba4.
|
||||||
|
I claim own copyright 2011 Thomas Schmitt <scdbackup@gmx.net>.
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
time_t ts_timegm(struct tm *tm)
|
||||||
|
{
|
||||||
|
time_t ret;
|
||||||
|
static int month_length_normal[12] =
|
||||||
|
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
|
||||||
|
static int month_length_leap[12] =
|
||||||
|
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
|
||||||
|
int *month_length_pt;
|
||||||
|
int years, i;
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
years = tm->tm_year - 70; /* Years since 1970 */
|
||||||
|
if (years < 0)
|
||||||
|
return ret;
|
||||||
|
for (i = 0; i < years; i++) {
|
||||||
|
ret += 365 * 86400;
|
||||||
|
if (ts_is_leapyear(70 + i))
|
||||||
|
ret += 86400;
|
||||||
|
}
|
||||||
|
if (ts_is_leapyear(tm->tm_year))
|
||||||
|
month_length_pt = month_length_leap;
|
||||||
|
else
|
||||||
|
month_length_pt = month_length_normal;
|
||||||
|
for (i = 0; i < tm->tm_mon; i++)
|
||||||
|
ret += month_length_pt[i] * 86400;
|
||||||
|
ret += (tm->tm_mday - 1) * 86400;
|
||||||
|
ret += tm->tm_hour * 3600;
|
||||||
|
ret += tm->tm_min * 60;
|
||||||
|
ret += tm->tm_sec;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
time_t timegm(struct tm *tm)
|
||||||
|
{
|
||||||
|
time_t raw_t, ret;
|
||||||
|
struct tm *test_tm, input_tm_copy;
|
||||||
|
|
||||||
|
/* Beware of ill effects if tm is result of gmtime() or alike */
|
||||||
|
memcpy(&input_tm_copy, tm, sizeof(struct tm));
|
||||||
|
|
||||||
|
/* Try without leapseconds (which are rarely implemented, as it seems) */
|
||||||
|
raw_t = ts_timegm(tm);
|
||||||
|
if (raw_t == 0)
|
||||||
|
return raw_t;
|
||||||
|
|
||||||
|
/* Check whether this translates back to the input values */
|
||||||
|
test_tm = gmtime(&raw_t);
|
||||||
|
if (input_tm_copy.tm_sec == test_tm->tm_sec &&
|
||||||
|
input_tm_copy.tm_min == test_tm->tm_min &&
|
||||||
|
input_tm_copy.tm_hour == test_tm->tm_hour &&
|
||||||
|
input_tm_copy.tm_mday == test_tm->tm_mday &&
|
||||||
|
input_tm_copy.tm_mon == test_tm->tm_mon &&
|
||||||
|
input_tm_copy.tm_year == test_tm->tm_year) {
|
||||||
|
ret = raw_t;
|
||||||
|
} else {
|
||||||
|
/* Mismatch. Use slow method around mktime() */
|
||||||
|
ret = env_timegm(&input_tm_copy);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* ! HAVE_TIMEGM */
|
||||||
|
|
||||||
|
|
||||||
time_t iso_datetime_read_7(const uint8_t *buf)
|
time_t iso_datetime_read_7(const uint8_t *buf)
|
||||||
{
|
{
|
||||||
@ -1327,6 +1461,7 @@ time_t iso_datetime_read_7(const uint8_t *buf)
|
|||||||
tm.tm_hour = buf[3];
|
tm.tm_hour = buf[3];
|
||||||
tm.tm_min = buf[4];
|
tm.tm_min = buf[4];
|
||||||
tm.tm_sec = buf[5];
|
tm.tm_sec = buf[5];
|
||||||
|
|
||||||
return timegm(&tm) - ((int8_t)buf[6]) * 60 * 15;
|
return timegm(&tm) - ((int8_t)buf[6]) * 60 * 15;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1413,16 +1548,17 @@ char *iso_util_strcopy(const char *buf, size_t len)
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *iso_util_strcopy_untail(const char *buf, size_t len)
|
char *iso_util_strcopy_untail(const char *buf, size_t len_in)
|
||||||
{
|
{
|
||||||
char *str;
|
char *str;
|
||||||
|
int len;
|
||||||
|
|
||||||
str = iso_util_strcopy(buf, len);
|
str = iso_util_strcopy(buf, len_in);
|
||||||
if (str == NULL) {
|
if (str == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/* remove trailing spaces */
|
/* remove trailing spaces */
|
||||||
for (len = len-1; len >= 0; --len) {
|
for (len = len_in - 1; len >= 0; --len) {
|
||||||
if (str[len] != ' ')
|
if (str[len] != ' ')
|
||||||
break;
|
break;
|
||||||
str[len] = 0;
|
str[len] = 0;
|
||||||
@ -1477,7 +1613,7 @@ char *ucs2str(const char *buf, size_t len)
|
|||||||
|
|
||||||
n = iso_iconv(&conv, &src, &inbytes, &str, &outbytes, 0);
|
n = iso_iconv(&conv, &src, &inbytes, &str, &outbytes, 0);
|
||||||
iso_iconv_close(&conv, 0);
|
iso_iconv_close(&conv, 0);
|
||||||
if (n == -1) {
|
if (n == (size_t) -1) {
|
||||||
/* error */
|
/* error */
|
||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
@ -1714,12 +1850,12 @@ int iso_util_eval_md5_tag(char *block, int desired, uint32_t lba,
|
|||||||
*tag_type = 0;
|
*tag_type = 0;
|
||||||
decode_ret = iso_util_decode_md5_tag(block, tag_type, &pos,
|
decode_ret = iso_util_decode_md5_tag(block, tag_type, &pos,
|
||||||
&range_start, &range_size, next_tag, md5, 0);
|
&range_start, &range_size, next_tag, md5, 0);
|
||||||
if (decode_ret != 1 && decode_ret != ISO_MD5_AREA_CORRUPTED)
|
if (decode_ret != 1 && decode_ret != (int) ISO_MD5_AREA_CORRUPTED)
|
||||||
return 0;
|
return 0;
|
||||||
if (*tag_type > 30)
|
if (*tag_type > 30)
|
||||||
goto unexpected_type;
|
goto unexpected_type;
|
||||||
|
|
||||||
if (decode_ret == ISO_MD5_AREA_CORRUPTED) {
|
if (decode_ret == (int) ISO_MD5_AREA_CORRUPTED) {
|
||||||
ret = decode_ret;
|
ret = decode_ret;
|
||||||
goto ex;
|
goto ex;
|
||||||
} else if (!((1 << *tag_type) & desired)) {
|
} else if (!((1 << *tag_type) & desired)) {
|
||||||
@ -1727,10 +1863,24 @@ unexpected_type:;
|
|||||||
iso_msg_submit(-1, ISO_MD5_TAG_UNEXPECTED, 0, NULL);
|
iso_msg_submit(-1, ISO_MD5_TAG_UNEXPECTED, 0, NULL);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
goto ex;
|
goto ex;
|
||||||
} else if(pos != lba) {
|
} else if (pos != lba) {
|
||||||
|
if (*tag_type == 2) { /* Superblock tag */
|
||||||
|
if (lba < 32) {
|
||||||
|
/* Check whether this is a copied superblock */
|
||||||
|
range_start -= (off_t) pos - (off_t) lba;
|
||||||
|
if (range_start != ctx_start_lba) {
|
||||||
|
|
||||||
|
/* >>> check for matching MD5 ? */;
|
||||||
|
|
||||||
|
ret = ISO_MD5_TAG_MISPLACED;
|
||||||
|
} else
|
||||||
|
ret = ISO_MD5_TAG_COPIED;
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
ret = ISO_MD5_TAG_MISPLACED;
|
ret = ISO_MD5_TAG_MISPLACED;
|
||||||
goto ex;
|
goto ex;
|
||||||
} else if(range_start != ctx_start_lba) {
|
} else if (range_start != ctx_start_lba) {
|
||||||
ret = ISO_MD5_TAG_MISPLACED;
|
ret = ISO_MD5_TAG_MISPLACED;
|
||||||
}
|
}
|
||||||
ret = iso_md5_clone(ctx, &cloned_ctx);
|
ret = iso_md5_clone(ctx, &cloned_ctx);
|
||||||
@ -1748,4 +1898,14 @@ ex:;
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void *iso_alloc_mem(size_t size, size_t count, int flag)
|
||||||
|
{
|
||||||
|
void *pt;
|
||||||
|
|
||||||
|
pt = calloc(size, count);
|
||||||
|
if(pt == NULL)
|
||||||
|
iso_msg_submit(-1, ISO_OUT_OF_MEM, 0, "Out of virtual memory");
|
||||||
|
return pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,14 @@
|
|||||||
#ifndef LIBISO_UTIL_H_
|
#ifndef LIBISO_UTIL_H_
|
||||||
#define LIBISO_UTIL_H_
|
#define LIBISO_UTIL_H_
|
||||||
|
|
||||||
|
#ifdef HAVE_STDINT_H
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_INTTYPES_H
|
||||||
|
#include <inttypes.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#ifndef MAX
|
#ifndef MAX
|
||||||
@ -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
|
* Create a Joliet file identifier that consists of name and extension. The
|
||||||
* combined name and extension length will not exceed 128 bytes, and the
|
* combined name and extension length will normally not exceed 64 characters
|
||||||
* name and extension will be separated (.). All characters consist of
|
* (= 128 bytes). The name and the extension will be separated (.).
|
||||||
* 2 bytes and the resulting string is NULL-terminated by a 2-byte NULL.
|
* All characters consist of 2 bytes and the resulting string is
|
||||||
|
* NULL-terminated by a 2-byte NULL.
|
||||||
*
|
*
|
||||||
* Note that version number and (;1) is not appended.
|
* Note that version number and (;1) is not appended.
|
||||||
* @param flag
|
* @param flag
|
||||||
* bit0= no_force_dots
|
* bit0= no_force_dots
|
||||||
|
* bit1= allow 103 characters rather than 64
|
||||||
* @return
|
* @return
|
||||||
* NULL if the original name and extension both are of length 0.
|
* NULL if the original name and extension both are of length 0.
|
||||||
*/
|
*/
|
||||||
@ -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
|
* and the name and extension will be separated (.). All characters consist of
|
||||||
* 2 bytes and the resulting string is NULL-terminated by a 2-byte NULL.
|
* 2 bytes and the resulting string is NULL-terminated by a 2-byte NULL.
|
||||||
*
|
*
|
||||||
|
* @param flag
|
||||||
|
* bit1= allow 103 characters rather than 64
|
||||||
* @return
|
* @return
|
||||||
* NULL if the original name and extension both are of length 0.
|
* NULL if the original name and extension both are of length 0.
|
||||||
*/
|
*/
|
||||||
uint16_t *iso_j_dir_id(const uint16_t *src);
|
uint16_t *iso_j_dir_id(const uint16_t *src, int flag);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Like strlen, but for Joliet strings.
|
* Like strlen, but for Joliet strings.
|
||||||
@ -505,13 +516,41 @@ int iso_util_tag_magic(int tag_type, char **tag_magic, int *len, int flag);
|
|||||||
*/
|
*/
|
||||||
int checksum_cx_xinfo_func(void *data, int flag);
|
int checksum_cx_xinfo_func(void *data, int flag);
|
||||||
|
|
||||||
|
/* The iso_node_xinfo_cloner function which gets associated to
|
||||||
|
* checksum_cx_xinfo_func by iso_init() resp. iso_init_with_flag() via
|
||||||
|
* iso_node_xinfo_make_clonable()
|
||||||
|
*/
|
||||||
|
int checksum_cx_xinfo_cloner(void *old_data, void **new_data, int flag);
|
||||||
|
|
||||||
|
|
||||||
/* Function to identify and manage md5 sums of unspecified providence stored
|
/* Function to identify and manage md5 sums of unspecified providence stored
|
||||||
* directly in this xinfo. This is supposed to override any other recorded
|
* directly in this xinfo. This is supposed to override any other recorded
|
||||||
* MD5 of the node unless data get copied and checksummed during that copying.
|
* MD5 of the node unless data get copied and checksummed during that copying.
|
||||||
*/
|
*/
|
||||||
int checksum_md5_xinfo_func(void *data, int flag);
|
int checksum_md5_xinfo_func(void *data, int flag);
|
||||||
|
|
||||||
|
/* The iso_node_xinfo_cloner function which gets associated to
|
||||||
|
* checksum_md5_xinfo_func by iso_init() resp. iso_init_with_flag() via
|
||||||
|
* iso_node_xinfo_make_clonable()
|
||||||
|
*/
|
||||||
|
int checksum_md5_xinfo_cloner(void *old_data, void **new_data, int flag);
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
void *iso_alloc_mem(size_t size, size_t count, int flag);
|
||||||
|
|
||||||
|
#define LIBISO_ALLOC_MEM(pt, typ, count) { \
|
||||||
|
pt= (typ *) iso_alloc_mem(sizeof(typ), (size_t) (count), 0); \
|
||||||
|
if(pt == NULL) { \
|
||||||
|
ret= ISO_OUT_OF_MEM; goto ex; \
|
||||||
|
} }
|
||||||
|
|
||||||
|
#define LIBISO_FREE_MEM(pt) { \
|
||||||
|
if(pt != NULL) \
|
||||||
|
free((char *) pt); \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /*LIBISO_UTIL_H_*/
|
#endif /*LIBISO_UTIL_H_*/
|
||||||
|
@ -164,7 +164,7 @@ int iso_rbtree_insert(IsoRBTree *tree, void *data, void **item)
|
|||||||
new = data;
|
new = data;
|
||||||
added = 1;
|
added = 1;
|
||||||
} else {
|
} else {
|
||||||
struct iso_rbnode head = { 0 }; /* False tree root */
|
struct iso_rbnode head = { 0, {NULL, NULL}, 0 }; /* False tree root */
|
||||||
|
|
||||||
struct iso_rbnode *g, *t; /* Grandparent & parent */
|
struct iso_rbnode *g, *t; /* Grandparent & parent */
|
||||||
struct iso_rbnode *p, *q; /* Iterator & parent */
|
struct iso_rbnode *p, *q; /* Iterator & parent */
|
||||||
|
Reference in New Issue
Block a user