Compare commits

..

82 Commits

Author SHA1 Message Date
089982022c Version leap to 1.4.2 2015-11-28 21:13:51 +01:00
a6316ff05c Updated changelog 2015-11-28 12:00:49 +01:00
02a972a2d7 Closed a memory leak during retrieval of xattr. 2015-10-15 17:32:58 +02:00
da8ad0d2aa Made clear that a freed pointer variable is not really used any more.
Coverity CID 17846.
2015-10-15 11:53:56 +02:00
79e6312397 Refactored error handling while encoding AAIP information.
Again Coverity CID 12564.
2015-10-15 08:38:56 +02:00
b3a183fceb Made sure that mangling name buffer of 40 bytes cannot overflow.
Coverity CID 12589.
2015-10-13 19:30:17 +02:00
355f1f7ea2 Avoided to have an unused variable with --disable-xattr. Coverity CID 12544. 2015-10-13 14:40:42 +02:00
57fd669d1d Fixed compile time warnings with configure --disable-xattr --disable-libac.
Instigated by Coverity CID 12543.
2015-10-13 14:28:34 +02:00
6047464b6b Revoking previous change. It differs from the handling of F_GETFL failure.
So O_NONBLOCK is intended to be nice to have but not mandatory.
2015-10-13 11:02:11 +02:00
e8b94e7b50 Checking the return value of fcntl(F_SETFL O_NONBLOCK). Coverity CID 12536. 2015-10-13 10:49:16 +02:00
49dd9dc993 Closed memory leaks with demo/demo -iso_read and updated.
Inspired by Coverity CID 12561.
2015-10-12 22:49:47 +02:00
93e1fc52d0 Closed memory leaks with demo/demo -iso_ms and updated.
Inspired by Coverity CID 12559 and 12560.
2015-10-12 19:45:46 +02:00
4838cd59a7 Closed more memory leaks with demo/demo -iso_modify. Coverity CID 12558. 2015-10-12 16:46:18 +02:00
d51b1738dd Closed memory leaks with demo/demo -iso_modify and updated it a bit.
Inspired by Coverity CID 12557.
2015-10-12 15:50:43 +02:00
6252ae2065 Overhauled demo/demo -iso_cat. Better error messages. Closed memory leaks.
Instigated by Coverity CID 12555.
2015-10-12 14:14:14 +02:00
cb1e56478a Initializing name truncation parameters of IsoReadOpts to prevent
failure of demo/demo -iso_cat, which does not load the ISO image.
2015-10-12 11:48:27 +02:00
05d0ee4a37 Fixed double free in case of error while looking up path in loaded ISO image. 2015-10-12 10:56:42 +02:00
c6aedc9eb5 Fixed double free introduced with rev 1233. 2015-10-11 19:57:36 +02:00
505bf23aa4 Made sure that missing boot catalog at image load time causes no SIGSEGV
by NULL. Coverity CID 12552.
2015-10-11 18:25:13 +02:00
ccef2f29da Avoiding NULL pointer dereference in case of unexpected file type.
Coverity CID 12550.
2015-10-11 17:36:30 +02:00
b904926443 Checking success of strdup(). Indirectly found by Coverity CID 12548. 2015-10-11 16:11:02 +02:00
7bdc4c96f5 Avoided to close unopened file pointer in case of error. Coverity CID 12546. 2015-10-11 15:18:03 +02:00
fa5e27458a Removed surplus test which was always true. Coverity CID 12539. 2015-10-11 11:02:54 +02:00
7c29a94ab6 Taking into respect the return value of a function which can fail.
Coverity CID 12595.
2015-10-11 10:15:38 +02:00
a4c1e04820 Removed assignment of an unused function result. Coverity CID 12594. 2015-10-11 09:49:15 +02:00
50132d4ff7 Added forgotten emergency exit with faulty MD5 tags. Coverity CID 12596. 2015-10-11 09:44:15 +02:00
4c1c1ea152 voided to have dead code ifndef Libisofs_with_aaip_acL. Coverity CID 12593. 2015-10-10 22:01:05 +02:00
a16d4a28f4 Explicitely set tm_isdst to 0 before calling timegm. Coverity CID 12592. 2015-10-10 21:33:08 +02:00
4633ea3bc8 Explicitely set tm_isdst to 0 before calling timegm. Coverity CID 12591. 2015-10-10 21:31:13 +02:00
430c005666 Corrected initial allocation size of a pointer array. Coverity CID 12588. 2015-10-10 16:47:15 +02:00
af55722830 Corrected allocation size of a pointer array. Coverity CID 12587. 2015-10-10 16:34:29 +02:00
d1da5718c7 Corrected allocation size of a pointer array. Coverity CID 12586. 2015-10-10 16:32:44 +02:00
afb2878773 Corrected allocation size of a pointer array. Coverity CID 12585. 2015-10-10 16:28:48 +02:00
4e7432c20f Removed unnecessary test for NULL. Coverity CID 12584. 2015-10-10 16:02:07 +02:00
7ef616f268 Delaying access to pointer until after NULL check. Coverity CID 12583. 2015-10-10 15:53:55 +02:00
d5f1eb9c65 Closed memory leaks with errors in ecma119_image_new(). Coverity CID 12582. 2015-10-10 15:21:27 +02:00
28b41bce2c Closed memory leaks with errors during creation of HFS+ filesystem.
Coverity CID 12581.
2015-10-10 14:54:06 +02:00
5ac3216933 Closed memory leak with lack of memory during retrieval of HFS+ names.
Coverity CID 12580.
2015-10-10 13:11:31 +02:00
05a2171e04 Closed memory leak with lack of memory during character set conversion.
Coverity CID 12579.
2015-10-10 12:29:01 +02:00
188a41f041 Closed memory leaks with faulty ACL text. Coverity CID 12578. 2015-10-10 12:19:28 +02:00
fbe7f1e89d Closed memory leak with assert error or memory shortage while creating
SL entry. Coverity CID 12576.
2015-10-10 11:48:52 +02:00
d04abdcfbd Closed memory leak with memory shortage while creating IsoSymlink object.
Coverity CID 12575.
2015-10-10 11:05:41 +02:00
a6542e5fa9 Closed memory leak with error while creating IsoFile object. Coverity CID 12574. 2015-10-09 20:42:08 +02:00
78d2c02ad8 Closed memory leak with error in iso_file_make_md5(). Coverity CID 12573. 2015-10-09 20:35:15 +02:00
48453ef1da Closed memory leaks with errors during ISO image import. Coverity CID 12572. 2015-10-09 20:07:29 +02:00
7928c4ec3f Closed memory leak with lack of memory during ISO image import.
Coverity CID 12571.
2015-10-09 19:44:46 +02:00
379e223a5c Cosmetic change in function return value. Coverity CID 12570. 2015-10-09 17:23:08 +02:00
e4750907e3 Removed unused opportunity to call static create_image() with NULL for bootimg.
Coverity CID 12569.
2015-10-09 15:53:29 +02:00
8f76b59541 Closed nasty memory leak with new API call iso_image_dir_get_node().
Coverity CID 12568.
2015-10-09 15:40:24 +02:00
0433b7ea75 Closed memory leak with lack of memory during character set conversion.
Coverity CID 12567.
2015-10-09 15:28:04 +02:00
d8fb8b26a6 Closed memory leak with lack of memory during character set conversion.
Coverity CID 12566.
2015-10-09 14:14:55 +02:00
b9ccdeda72 Closed memory leak with lack of memory during ISO image loading.
Coverity CID 12565.
2015-10-09 13:38:47 +02:00
d04f438ba1 Closed memory leak with Rock Ridge character set conversion failure.
Coverity CID 12562.
2015-10-09 13:25:42 +02:00
e35cb88328 Made sure that iso_file_get_old_image_sections() returns non-NULL only
if section_count > 0. Made sure that callers in libisofs expect all possible
outcome as announced by API description.
2015-10-09 12:03:14 +02:00
83fb614462 Closed memory leak in (improbable) case of error when attaching AAIP
attributes to IsoNode. Coverity CID 12564.
2015-10-09 11:03:38 +02:00
e5f6811795 Reacted on Coverity CID 12538. Mostly cosmetic. 2015-10-08 23:20:29 +02:00
f3b836194c Pleasing Coverity for the improbable case that a builtin error message
length exceeds 4095 bytes.
2015-10-08 23:02:06 +02:00
3a870d23e3 Consolidated maximum length of namespace names. Coverity CID 12590. 2015-10-08 22:40:37 +02:00
06ea46c8d5 Bug fix: Freeing wrong pointer in case of memory shortage. Coverty CID 12600. 2015-10-08 19:52:23 +02:00
d427a03192 Bug fix: Double free if a boot image has no extents. Coverity CID 12599. 2015-10-08 19:47:01 +02:00
2b6071b445 Bug fix: Double free if a boot image has no extents. Coverity CID 12598. 2015-10-08 19:43:08 +02:00
fc448e09c9 Bug fix: Double free if no charset WCHAR_T is available. Coverity CID 12597.
(previous was CID 12601)
2015-10-08 19:35:22 +02:00
7b7da47d86 Bug fix: Double free if no charset WCHAR_T is available. Coverity CID 12597. 2015-10-08 19:27:28 +02:00
01c7a0d5ec Accept Rock Ridge Creation time as ctime if no Attributes time is present. 2015-10-04 18:47:38 +02:00
905f4f898f Fixed SIGSEGV while image import. Introduced by rev 1216. 2015-09-28 20:39:12 +02:00
b9ec876c40 Preventing a theoretically possible negative array index in find_utf8_start() 2015-09-28 11:36:45 +02:00
72ef369a40 Let loaded image adjust truncate length regardless whether larger or
smaller than the current truncate length.
2015-09-27 18:03:18 +02:00
218e26c974 Bug fix: iso_node_get_name() of root node returned NULL pointer rather than
an empty string
2015-09-27 12:30:24 +02:00
395128ef5f New AAIP variable isofs.nt records name truncation parameters. 2015-09-25 19:07:53 +02:00
7a3560035a Rectified handling of oversized filenames by new API calls:
iso_image_set_truncate_mode, iso_image_get_truncate_mode,
iso_truncate_leaf_name, iso_image_set_node_name, iso_image_tree_clone,
iso_image_add_new_dir, iso_image_add_new_file, iso_image_add_new_special,
iso_image_add_new_symlink, iso_image_dir_get_node, iso_image_path_to_node,
2015-09-17 13:59:05 +02:00
7ac5b75748 Bug fix: Names read from Joliet tree where stripped of trailing ";1" 2015-09-07 13:17:08 +02:00
6c3dc3ce4a New API call iso_read_opts_set_ecma119_map(). 2015-08-17 21:52:33 +02:00
bdbaf81e9c Bug fix: zisofs compression caused SIGSEGV (by reading) with files larger than
524160 KiB.
2015-08-11 22:58:37 +02:00
c8ed18695f Restricted size of patchable boot images to 32 MB and prevented
stream filtering on such boot images.
2015-08-11 12:02:26 +02:00
d3fefe4735 Changed wrong use of "resp." in docs 2015-08-01 16:58:40 +02:00
6db3f6ca44 Still trying to get the correct mail address in commits. 2015-07-27 19:58:28 +02:00
bf19f73ea6 Test: Trying to get my user id back. 2015-07-27 19:51:55 +02:00
6947bfe5ec Sorted the data file content extents by ECMA-119 tree rather than
by the red-black tree which shall consolidate files with identical
source object. Discovered and repaired a flaw in transitivity of
iso_stream_cmp_ino().
2015-07-27 13:50:57 +02:00
94f8503b57 Excluded empty data files from being recognized as El Torito boot images
when an ISO gets loaded.
2015-05-23 15:43:39 +02:00
cb519e221e Silenced compiler warnings of NetBSD and Solaris. 2015-05-20 12:19:37 +02:00
d09a317f51 Updated ChangeLog 2015-05-17 22:58:32 +02:00
2beb0d001b Version leap to 1.4.1 2015-05-17 21:16:35 +02:00
46 changed files with 2234 additions and 516 deletions

View File

@ -1,7 +1,7 @@
Vreixo Formoso <metalpain2002@yahoo.es>,
Mario Danic <mario.danic@gmail.com>,
Thomas Schmitt <scdbackup@gmx.net>
Copyright (C) 2007-2014 Vreixo Formoso, Mario Danic, Thomas Schmitt
Copyright (C) 2007-2015 Vreixo Formoso, Mario Danic, Thomas Schmitt
This program is free software; you can redistribute it and/or modify

View File

@ -1,4 +1,23 @@
libisofs-1.4.0.tar.gz Sun May 17 2014
libisofs-1.4.2.tar.gz Sat Nov 28 2015
===============================================================================
* Bug fix: zisofs compression caused SIGSEGV (by reading) with files larger
than 524160 KiB.
* Bug fix: iso_node_get_name() of root node returned NULL pointer rather than
an empty string
* Bug fix: Names read from Joliet tree where stripped of trailing ";1"
* Now sorting the data file content extents by ECMA-119 tree, rather than
by the red-black tree which shall consolidate files with identical
source object.
* New API call iso_read_opts_set_ecma119_map().
* New AAIP variable isofs.nt records name truncation parameters.
* Rectified handling of oversized filenames by new API calls:
iso_image_set_truncate_mode, iso_image_get_truncate_mode,
iso_truncate_leaf_name, iso_image_set_node_name, iso_image_tree_clone,
iso_image_add_new_dir, iso_image_add_new_file, iso_image_add_new_special,
iso_image_add_new_symlink, iso_image_dir_get_node, iso_image_path_to_node
* Result of a Coverity audit: 50+ code changes, but no easy-to-trigger bugs
libisofs-1.4.0.tar.gz Sun May 17 2015
===============================================================================
* Bug fix: iso_image_report_system_area() caused SIGSEGV by NULL if no valid
ISO 9660 image was loeaded. Thanks to OmegaPhil.
@ -19,7 +38,7 @@ libisofs-1.4.0.tar.gz Sun May 17 2014
* Bug fix: A zero sized GPT partition was marked after the last appended
GPT partition.
* Bug fix: GPT production did not yield proper results with appended sessions
resp. with TOC emulation enabled.
or with TOC emulation enabled.
* Increased default weight of El Torito boot catalog to 1 billion.
* Improved handling of cylinder alignment if the resulting image size is not
divisible by 2048. Old behavior was to not align. New is to pad up by a
@ -33,7 +52,6 @@ libisofs-1.4.0.tar.gz Sun May 17 2014
iso_write_opts_set_prep_img(), iso_write_opts_set_efi_bootp(),
and iso_write_opts_set_partition_img().
libisofs-1.3.8.tar.gz Sat Jun 28 2014
===============================================================================
* Bug fix: Prevent allocation of empty hash tables. Thanks Richard Nolde.

4
README
View File

@ -4,7 +4,7 @@
Released under GPL (see COPYING file for details).
Copyright (C) 2008 - 2013 Vreixo Formoso,
Copyright (C) 2008 - 2015 Vreixo Formoso,
Mario Danic,
Vladimir Serbinenko,
Thomas Schmitt
@ -37,7 +37,7 @@ and execute
./configure --prefix=/usr
make
To make the libraries accessible for running resp. developing applications
To make the libraries accessible for running and developing applications
make install
On GNU/Linux it will try to run program ldconfig with the library installation

View File

@ -1,4 +1,4 @@
AC_INIT([libisofs], [1.4.0], [http://libburnia-project.org])
AC_INIT([libisofs], [1.4.2], [http://libburnia-project.org])
AC_PREREQ([2.50])
dnl AC_CONFIG_HEADER([config.h])
@ -41,7 +41,7 @@ dnl If LIBISOFS_*_VERSION changes, be sure to change AC_INIT above to match.
dnl
LIBISOFS_MAJOR_VERSION=1
LIBISOFS_MINOR_VERSION=4
LIBISOFS_MICRO_VERSION=0
LIBISOFS_MICRO_VERSION=2
LIBISOFS_VERSION=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION.$LIBISOFS_MICRO_VERSION
AC_SUBST(LIBISOFS_MAJOR_VERSION)
@ -51,10 +51,10 @@ AC_SUBST(LIBISOFS_VERSION)
dnl Libtool versioning
LT_RELEASE=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION
# 2015.05.17 development jump has not yet happened
# SONAME = 82 - 76 = 6 . Library name = libisofs.6.76.0
LT_CURRENT=82
LT_AGE=76
# 2015.11.28 development jump has not yet happened
# SONAME = 84 - 78 = 6 . Library name = libisofs.6.78.0
LT_CURRENT=84
LT_AGE=78
LT_REVISION=0
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 - 2014 Vreixo Formoso, Thomas Schmitt
* Copyright (c) 2007 - 2015 Vreixo Formoso, Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -24,7 +24,9 @@ static char helptext[][80] = {
" Output the contents of an iso image.",
" -iso_cat image_file path_in_image",
" Extract a file from a given ISO image and put out its content",
" to stdout. The file is addressed by path_in_image.",
" to stdout. The file is addressed by path_in_image. The ISO",
" image does not get loaded but rather the lookups are done",
" directly in the image file.",
" -iso_modify image_file absolute_directory_path output_file",
" Load an iso image, add a directory, and write complete image.",
" -iso_ms image_lba nwa image_file directory_path output_file",
@ -58,6 +60,22 @@ static char helptext[][80] = {
#endif
/* ----------------------------- utilities -------------------------- */
void demo_report_iso_err(int err, char *occasion)
{
char *severity;
fprintf(stderr, "%s : err = 0x%X", occasion, (unsigned int) err);
if (err < 0) {
iso_sev_to_text(iso_error_get_severity(err), &severity);
fprintf(stderr, " -> %s '%s'", severity, iso_error_to_msg(err));
}
fprintf(stderr, "\n");
}
/* ------------------------- from demo/tree.c ----------------------- */
static void
@ -475,37 +493,43 @@ iso_read_print_dir(IsoFileSource *dir, int level)
int gesture_iso_read(int argc, char **argv)
{
int result;
IsoImageFilesystem *fs;
IsoDataSource *src;
IsoFileSource *root;
IsoReadOpts *ropts;
int result, initialized = 0, return_val = 1;
IsoImageFilesystem *fs = NULL;
IsoDataSource *src = NULL;
IsoFileSource *root = NULL;
IsoReadOpts *ropts = NULL;
if (argc != 2) {
printf ("You need to specify a valid path\n");
return 1;
goto ex;
}
iso_init();
result = iso_init();
if (result < 0) {
demo_report_iso_err(result, "Cannot init libisofs");
goto ex;
}
initialized = 1;
iso_set_msgs_severities("NEVER", "ALL", "");
result = iso_data_source_new_from_file(argv[1], &src);
if (result < 0) {
printf ("Error creating data source\n");
return 1;
demo_report_iso_err(result, "Error creating data source");
goto ex;
}
result = iso_read_opts_new(&ropts, 0);
if (result < 0) {
fprintf(stderr, "Error creating read options\n");
return 1;
demo_report_iso_err(result, "Error creating read options");
goto ex;
}
result = iso_image_filesystem_new(src, ropts, 1, &fs);
iso_read_opts_free(ropts);
if (result < 0) {
printf ("Error creating filesystem\n");
return 1;
demo_report_iso_err(result, "Error creating filesystem");
goto ex;
}
iso_read_opts_free(ropts);
ropts = NULL;
printf("\nVOLUME INFORMATION\n");
printf("==================\n\n");
@ -524,18 +548,27 @@ int gesture_iso_read(int argc, char **argv)
result = fs->get_root(fs, &root);
if (result < 0) {
printf ("Can't get root %d\n", result);
return 1;
demo_report_iso_err(result, "Cannot get root object");
goto ex;
}
/* iso_read_print_file_src(root); */
iso_read_print_dir(root, 0);
iso_file_source_unref(root);
fs->close(fs);
iso_filesystem_unref((IsoFilesystem*)fs);
iso_data_source_unref(src);
iso_finish();
return 0;
return_val = 0;
ex:;
if (root != NULL)
iso_file_source_unref(root);
if (ropts != NULL)
iso_read_opts_free(ropts);
if (fs != NULL) {
fs->close(fs);
iso_filesystem_unref((IsoFilesystem*)fs);
}
if (src != NULL)
iso_data_source_unref(src);
if (initialized)
iso_finish();
return return_val;
}
@ -544,12 +577,12 @@ int gesture_iso_read(int argc, char **argv)
int gesture_iso_cat(int argc, char **argv)
{
int res, write_ret;
IsoFilesystem *fs;
IsoFileSource *file;
int res, write_ret, ret;
IsoFilesystem *fs = NULL;
IsoFileSource *file = NULL;
struct stat info;
IsoDataSource *src;
IsoReadOpts *opts;
IsoDataSource *src = NULL;
IsoReadOpts *opts = NULL;
if (argc != 3) {
fprintf(stderr, "Usage: -iso_cat /path/to/image /path/to/file\n");
@ -558,69 +591,87 @@ int gesture_iso_cat(int argc, char **argv)
res = iso_init();
if (res < 0) {
fprintf(stderr, "Can't init libisofs\n");
demo_report_iso_err(res, "Cannot init libisofs");
return 1;
}
/* Important Note:
From here on memory objects get created which need to be freed in
the end. Therefore in case of problems no direct return, but rather
a hop to label "ex:", where cleanup happens.
*/
res = iso_data_source_new_from_file(argv[1], &src);
if (res < 0) {
fprintf(stderr, "Error creating data source\n");
return 1;
demo_report_iso_err(res, "Error creating data source object");
ret = 1; goto ex;
}
res = iso_read_opts_new(&opts, 0);
if (res < 0) {
fprintf(stderr, "Error creating read options\n");
return 1;
demo_report_iso_err(res, "Error creating read options object");
ret = 1; goto ex;
}
res = iso_image_filesystem_new(src, opts, 1, &fs);
if (res < 0) {
fprintf(stderr, "Error creating filesystem\n");
return 1;
demo_report_iso_err(res, "Error creating filesystem object");
ret = 1; goto ex;
}
iso_read_opts_free(opts);
opts = NULL;
res = fs->get_by_path(fs, argv[2], &file);
if (res < 0) {
fprintf(stderr, "Can't get file, err = %d\n", res);
return 1;
demo_report_iso_err(res, "Cannot get file object with given path");
ret = 1; goto ex;
}
res = iso_file_source_lstat(file, &info);
if (res < 0) {
fprintf(stderr, "Can't stat file, err = %d\n", res);
return 1;
demo_report_iso_err(res,
"Cannot inquire type of file object with given path");
ret = 1; goto ex;
}
if (S_ISDIR(info.st_mode)) {
fprintf(stderr, "Path refers to a directory!!\n");
return 1;
ret = 1; goto ex;
} else {
char buf[1024];
res = iso_file_source_open(file);
if (res < 0) {
fprintf(stderr, "Can't open file, err = %d\n", res);
return 1;
demo_report_iso_err(res,
"Cannot open file object with given path");
ret = 1; goto ex;
}
while ((res = iso_file_source_read(file, buf, 1024)) > 0) {
write_ret = fwrite(buf, 1, res, stdout);
if (write_ret < res) {
printf ("Cannot write block to stdout. errno= %d\n", errno);
return 1;
iso_file_source_close(file);
ret = 1; goto ex;
}
}
if (res < 0) {
fprintf(stderr, "Error reading, err = %d\n", res);
return 1;
}
iso_file_source_close(file);
if (res < 0) {
demo_report_iso_err(res, "Error while reading data content");
fprintf(stderr, "Error reading, err = 0x%X\n", (unsigned int) res);
ret = 1; goto ex;
}
}
iso_file_source_unref(file);
iso_filesystem_unref(fs);
iso_data_source_unref(src);
ret = 0;
ex:;
if (file != NULL)
iso_file_source_unref(file);
if (fs != NULL)
iso_filesystem_unref(fs);
if (opts != NULL)
iso_read_opts_free(opts);
if (src != NULL)
iso_data_source_unref(src);
iso_finish();
return 0;
return ret;
}
@ -634,14 +685,14 @@ void iso_modify_usage(char **argv)
int gesture_iso_modify(int argc, char **argv)
{
int result;
IsoImage *image;
IsoDataSource *src;
struct burn_source *burn_src;
int result, return_val = 1, initialized = 0;
IsoImage *image = NULL;
IsoDataSource *src = NULL;
struct burn_source *burn_src = NULL;
unsigned char buf[2048];
FILE *fp = NULL;
IsoWriteOpts *opts;
IsoReadOpts *ropts;
IsoWriteOpts *opts = NULL;
IsoReadOpts *ropts = NULL;
if (argc < 4) {
iso_modify_usage(argv);
@ -654,20 +705,25 @@ int gesture_iso_modify(int argc, char **argv)
goto ex;
}
iso_init();
result = iso_init();
if (result < 0) {
demo_report_iso_err(result, "Cannot init libisofs");
goto ex;
}
initialized = 1;
iso_set_msgs_severities("NEVER", "ALL", "");
/* create the data source to accesss previous image */
result = iso_data_source_new_from_file(argv[1], &src);
if (result < 0) {
printf ("Error creating data source\n");
demo_report_iso_err(result, "Error creating data source");
goto ex;
}
/* create the image context */
result = iso_image_new("volume_id", &image);
if (result < 0) {
printf ("Error creating image\n");
demo_report_iso_err(result, "Error creating image");
goto ex;
}
iso_tree_set_follow_symlinks(image, 0);
@ -676,58 +732,75 @@ int gesture_iso_modify(int argc, char **argv)
/* import previous image */
result = iso_read_opts_new(&ropts, 0);
if (result < 0) {
fprintf(stderr, "Error creating read options\n");
demo_report_iso_err(result, "Error creating read options");
goto ex;
}
result = iso_image_import(image, src, ropts, NULL);
iso_read_opts_free(ropts);
iso_data_source_unref(src);
if (result < 0) {
printf ("Error importing previous session %d\n", result);
demo_report_iso_err(result, "Error importing previous session");
goto ex;
}
/* (One could of course keep them alive until cleanup) */
iso_read_opts_free(ropts);
ropts = NULL;
iso_data_source_unref(src);
src = NULL;
/* add new dir */
result = iso_tree_add_dir_rec(image, iso_image_get_root(image), argv[2]);
if (result < 0) {
printf ("Error adding directory %d\n", result);
demo_report_iso_err(result, "Error adding directory");
goto ex;
}
/* generate a new image with both previous and added contents */
/* Generate a new image with both previous and added contents.
Profile 1 means Rock Ridge and ISO level 3.
*/
result = iso_write_opts_new(&opts, 1);
if (result < 0) {
printf("Cant create write opts, error %d\n", result);
demo_report_iso_err(result, "Cannot create write opts");
goto ex;
}
/* for isolinux: iso_write_opts_set_allow_full_ascii(opts, 1); */
/* Prefer specs violation over relocation deep directories */
iso_write_opts_set_allow_deep_paths(opts, 1);
/* For MS-Windows readers : iso_write_opts_set_joliet(opts, 1); */
result = iso_image_create_burn_source(image, opts, &burn_src);
if (result < 0) {
printf ("Cant create image, error %d\n", result);
demo_report_iso_err(result, "Cannot create image object");
goto ex;
}
iso_write_opts_free(opts);
opts = NULL;
while (burn_src->read_xt(burn_src, buf, 2048) == 2048) {
result = fwrite(buf, 1, 2048, fp);
if (result < 2048) {
printf ("Cannot write block. errno= %d\n", errno);
fprintf (stderr, "Cannot write block. errno= %d\n", errno);
goto ex;
}
}
fclose(fp);
burn_src->free_data(burn_src);
free(burn_src);
iso_image_unref(image);
iso_finish();
return 0;
return_val = 0;
ex:
if (fp != NULL)
fclose(fp);
return 1;
if (opts != NULL)
iso_write_opts_free(opts);
if (burn_src != NULL) {
burn_src->free_data(burn_src);
free(burn_src);
}
if (image != NULL)
iso_image_unref(image);
if (ropts != NULL)
iso_read_opts_free(ropts);
if (src != NULL)
iso_data_source_unref(src);
if (initialized)
iso_finish();
return return_val;
}
@ -741,14 +814,14 @@ void iso_ms_usage(char **argv)
int gesture_iso_ms(int argc, char **argv)
{
int result;
IsoImage *image;
IsoDataSource *src;
struct burn_source *burn_src;
int result, return_val = 1, initialized = 0;
IsoImage *image = NULL;
IsoDataSource *src = NULL;
struct burn_source *burn_src = NULL;
unsigned char buf[2048];
FILE *fp = NULL;
IsoWriteOpts *opts;
IsoReadOpts *ropts;
IsoWriteOpts *opts = NULL;
IsoReadOpts *ropts = NULL;
uint32_t ms_block;
if (argc < 6) {
@ -768,20 +841,26 @@ int gesture_iso_ms(int argc, char **argv)
goto ex;
}
iso_init();
result = iso_init();
if (result < 0) {
demo_report_iso_err(result, "Cannot init libisofs");
goto ex;
}
initialized = 1;
iso_set_msgs_severities("NEVER", "ALL", "");
/* create the data source to accesss previous image */
result = iso_data_source_new_from_file(argv[3], &src);
if (result < 0) {
printf ("Error creating data source\n");
demo_report_iso_err(result, "Error creating data source");
goto ex;
}
/* create the image context */
result = iso_image_new("volume_id", &image);
if (result < 0) {
printf ("Error creating image\n");
demo_report_iso_err(result, "Error creating image");
goto ex;
}
iso_tree_set_follow_symlinks(image, 0);
@ -796,23 +875,25 @@ int gesture_iso_ms(int argc, char **argv)
iso_read_opts_set_start_block(ropts, atoi(argv[1]));
result = iso_image_import(image, src, ropts, NULL);
iso_read_opts_free(ropts);
ropts = NULL;
iso_data_source_unref(src);
src = NULL;
if (result < 0) {
printf ("Error importing previous session %d\n", result);
demo_report_iso_err(result, "Error importing previous session");
goto ex;
}
/* add new dir */
result = iso_tree_add_dir_rec(image, iso_image_get_root(image), argv[4]);
if (result < 0) {
printf ("Error adding directory %d\n", result);
demo_report_iso_err(result, "Error adding directory");
goto ex;
}
/* generate a multisession image with new contents */
result = iso_write_opts_new(&opts, 1);
if (result < 0) {
printf("Cant create write opts, error %d\n", result);
demo_report_iso_err(result, "Cannot create write opts");
goto ex;
}
@ -827,6 +908,7 @@ int gesture_iso_ms(int argc, char **argv)
goto ex;
}
iso_write_opts_free(opts);
opts = NULL;
while (burn_src->read_xt(burn_src, buf, 2048) == 2048) {
result = fwrite(buf, 1, 2048, fp);
@ -835,17 +917,26 @@ int gesture_iso_ms(int argc, char **argv)
goto ex;
}
}
fclose(fp);
burn_src->free_data(burn_src);
free(burn_src);
iso_image_unref(image);
iso_finish();
return 0;
return_val = 0;
ex:;
if (burn_src != NULL) {
burn_src->free_data(burn_src);
free(burn_src);
}
if (opts != NULL)
iso_write_opts_free(opts);
if (image)
iso_image_unref(image);
if (ropts != NULL)
iso_read_opts_free(ropts);
if (src != NULL)
iso_data_source_unref(src);
if (initialized)
iso_finish();
if (fp != NULL)
fclose(fp);
return 1;
return return_val;
}

View File

@ -126,10 +126,10 @@ Defined by El Torito are:
1 = "PowerPC" (possibly for IBM machines with PowerPC CPU)
2 = "Mac" (possibly for Apple computers with MC68000 or PowerPC CPU)
UEFI 2.4 specifies in 12.3.2.1 "ISO-9660 and El Torito":
0xef = EFI, a competitor resp. successor to PC-BIOS, possibly in use with
Intel ia64 Itanium and possibly with newer Apple machines.
0xef = EFI, a competitor and successor to PC-BIOS, further in use with
Intel ia64 Itanium and newer Apple machines.
Words resp. numbers are represented are little-endian.
Words and numbers are represented as little-endian.
Validation Entry:
@ -386,7 +386,7 @@ on Linux a partition device file (e.g. /dev/sdb1) which cannot be used to mount
the ISO filesystem.
libisofs is able to produce a second set of trees and meta data which is
suitable for being mounted at start block 16 (ISO) resp. 64 (MBR).
suitable for being mounted at start block 16 (ISO) which is block 64 in MBR.
See <libisofs/libisofs.h> for call iso_write_opts_set_part_offset()
and http://libburnia-project.org/wiki/PartitionOffset for examples with
program xorriso.
@ -1515,8 +1515,8 @@ The ISO image file gets padded up to full MiB with sufficient room for the GPT
backup which is stored near the very end of the image file. There is need for
at least 16.5 KiB, which effectively occupy 18 KiB.
The backup partition array is stored 17 KiB before the end of MBR partition 1
resp. the image file.
The backup partition array is stored 17 KiB before the end of MBR partition 1,
which is also the end of the image file.
(Potential isohybrid.c bug #1:
Wikipedia suggests "LBA -33" counted from end. This would be 16.5 KiB before
end.)

View File

@ -217,7 +217,7 @@ S_IRWXG. If there is ACL_USER_N or ACL_GROUP_N there must also be ACL_MASK.
A numeric qualifier is a binary number of variable length up to 4 bytes. The
Most Significant Byte comes first. The number shall be the "POSIX File User ID"
resp. "POSIX File Group ID" as also used in RRIP PX entries. The ids of owning
or "POSIX File Group ID" as also used in RRIP PX entries. The ids of owning
user and owning group shall be taken from the PX entry of the file object.
Optional TRANSLATE entries may associate user or group names with numeric

View File

@ -8,7 +8,9 @@
The following names are defined for AAIP namespace "isofs." as mentioned in
specification of AAIP :
specification of AAIP. Unless explicitly stated otherwise, numbers with
names like *_LEN are 8 bit unsigned integers, those with *_BYTES are 32 bit
unsigned integers.
-------------------------------------------------------------------------------
@ -22,7 +24,7 @@ Purpose:
END is also the block address of the start of the checksum recording
area in the image.
See also isofs.cx .
This attribute shall eventually be attached to the root directory entry
This attribute shall be attached to the root directory entry
and be global for the whole image.
Format of Value:
@ -65,8 +67,8 @@ Purpose:
Records the name of the character set that was used as output character
set when writing the RRIP name tree of the ISO 9660 image. It shall be
suitable as parameter for function iconv_open(3).
This attribute shall eventually be attached to the root directory entry
and be global for the whole image.
This attribute shall be attached to the root directory entry and be
global for the whole image.
Format of Value:
Shall hold the character set name without terminating 0-byte.
@ -107,6 +109,7 @@ Name:
Purpose:
Records .st_dev and .st_ino of struct stat of the file source in the
local filesystem. See man 2 stat.
Both values may be unsigned integers up to 255 bytes.
Format of Value:
DEV_LEN | DEV_BYTES | INO_LEN | INO_BYTES
@ -172,6 +175,26 @@ Registered:
-------------------------------------------------------------------------------
Name:
isofs.nt
Purpose:
Records the name truncation mode and the truncation length for Rock Ridge
names. See iso_image_set_truncate_mode() in libisofs.h.
This attribute shall be attached to the root directory entry and be
global for the whole image.
Format of Value:
MODE_LEN | MODE_BYTES | LENGTH_LEN | LENGTH_BYTES
Example:
{ 1, 1, 1, 255 }
Registered:
24 Sep 2015 by Thomas Schmitt for libisofs.
-------------------------------------------------------------------------------
Name:
isofs.st
@ -183,7 +206,7 @@ Purpose:
The RRIP timestamps have a blind second during which a change after
node registration would not be recognizable for incremental backups
which are based in "isofs.di" rather than on content comparison.
This attribute shall eventually be attached to the root directory entry
This attribute shall be attached to the root directory entry
and be global for the whole image.
Format of Value:

View File

@ -37,7 +37,7 @@ i.e. block sizes 32 kB, 64 kB, and 128 kB. Writers must not use other sizes.
Block Pointers
There are ceil(input_size / block_size) input resp. output blocks.
There are ceil(input_size / block_size) input and output blocks.
Each input block is of fixed size whereas the output blocks have varying
size (down to 0). For each output block there is an offset pointer giving
its byte address in the overall file content. The next block pointer in the
@ -68,7 +68,7 @@ when being read.
ZF may only be applied to files with a single extent and less than 4 GiB of
uncompressed size.
The ZF entry follows the general layout of SUSP resp. RRIP.
The ZF entry follows the general layout of SUSP and RRIP.
Its fields are:
[1] "BP 1 to BP 2 - Signature Word" shall be (5A)(46) ("ZF").
@ -85,19 +85,18 @@ Its fields are:
[5] "BP 7 - Header Size Div 4" shall specify as an 8-bit number the number of
4-byte words in the header part of the file data recorded according
to ISO 9660:7.1.1.
(This is a copy of header byte 12, resp. header BP 13).
(This is a copy of header byte 12 / BP 13).
[6] "BP 8 - Log2 of Block Size" shall specify as an 8-bit number the binary
logarithm of the compression block size recorded according to
ISO 9660:7.1.1.
(This is a copy of header byte 13, resp. header BP 14.
(This is a copy of header byte 13 / BP 14.
The value has to be 15, 16 or 17 i.e. 32 kiB, 64 kiB, or 128 kiB.)
[7] "BP 9 to BP 16 - Uncompressed Size" shall tell the number of uncompressed
bytes represented by the given extent. This field shall be recorded
according to ISO 9660:7.3.3.
(This number is the same as in header bytes 8 to 11, resp header BP 9
to BP 12.)
(This number is the same as in header bytes 8 to 11 / BP 9 to BP 12.)
| 'Z' | 'F' | LENGTH | 1 | 'p' | 'z' | HEADER SIZE DIV 4 | LOG2 BLOCK SIZE
| UNCOMPRESSED SIZE |

View File

@ -39,7 +39,7 @@
It is permissibile to set them to 1 already now.
bit8 and higher: reserved, submit 0
@return
Bitfield corresponding to flag. If bits are set, th
Bitfield corresponding to flag.
bit0= ACL adapter is enabled
bit1= xattr adapter is enabled
bit2 - bit7= Reserved for future types.

View File

@ -49,7 +49,7 @@
It is permissibile to set them to 1 already now.
bit8 and higher: reserved, submit 0
@return
Bitfield corresponding to flag. If bits are set, th
Bitfield corresponding to flag.
bit0= ACL adapter is enabled
bit1= xattr adapter is enabled
bit2 - bit7= Reserved for future types.
@ -687,7 +687,7 @@ ex:;
0 no suitable ACL manipulation adapter available
-1 failure of system ACL service (see errno)
-2 attempt to manipulate ACL of a symbolic link
without bit5 resp. with no suitable link target
without bit5 or with no suitable link target
*/
int aaip_set_acl_text(char *path, char *text, int flag)
{

View File

@ -89,7 +89,7 @@ int aaip_local_attr_support(int flag)
or filesystem does not support ACL
-1 failure of system ACL service (see errno)
-2 attempt to inquire ACL of a symbolic link without
bit4 or bit5 resp. with no suitable link target
bit4 or bit5 or with no suitable link target
*/
int aaip_get_acl_text(char *path, char **text, int flag)
{
@ -186,16 +186,20 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
size_t **value_lengths, char ***values, int flag)
{
int ret;
ssize_t i, num_names= 0;
#ifdef Libisofs_with_aaip_acL
unsigned char *acl= NULL;
char *a_acl_text= NULL, *d_acl_text= NULL;
size_t acl_len= 0;
#define Libisofs_aaip_get_attr_activE yes
#endif
#ifdef Libisofs_with_aaip_xattR
char *list= NULL;
ssize_t value_ret, retry= 0, list_size= 0;
#define Libisofs_aaip_get_attr_activE yes
#endif
#ifdef Libisofs_aaip_get_attr_activE
ssize_t i, num_names= 0;
#endif
if(flag & (1 << 15)) { /* Free memory */
@ -207,6 +211,14 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
*value_lengths= NULL;
*values= NULL;
#ifndef Libisofs_aaip_get_attr_activE
ret = 1;
ex:;
return ret;
#else /* Libisofs_aaip_get_attr_activE */
/* Set up arrays */
#ifdef Libisofs_with_aaip_xattR
@ -361,6 +373,9 @@ ex:;
*num_attrs= 0;
}
return(ret);
#endif /* Libisofs_aaip_get_attr_activE */
}
@ -377,7 +392,7 @@ ex:;
0 ACL support not enabled at compile time
-1 failure of system ACL service (see errno)
-2 attempt to manipulate ACL of a symbolic link
without bit5 resp. with no suitable link target
without bit5 or with no suitable link target
*/
int aaip_set_acl_text(char *path, char *text, int flag)
{
@ -444,12 +459,18 @@ ex:
int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
size_t *value_lengths, char **values, int flag)
{
int ret, has_default_acl= 0;
size_t i, consumed, acl_text_fill, acl_idx= 0, h_consumed;
char *acl_text= NULL, *list= NULL;
int ret;
size_t i, consumed, acl_text_fill, acl_idx= 0;
char *acl_text= NULL;
#ifdef Libisofs_with_aaip_xattR
char *list= NULL;
ssize_t list_size= 0;
#endif
#ifdef Libisofs_with_aaip_acL
size_t h_consumed;
int has_default_acl= 0;
#endif
#ifdef Libisofs_with_aaip_xattR
@ -539,15 +560,14 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
goto ex;
if(ret <= 0)
{ret= -2; goto ex;}
has_default_acl= (ret == 2);
#ifdef Libisofs_with_aaip_acL
has_default_acl= (ret == 2);
ret= aaip_set_acl_text(path, acl_text, flag & 32);
if(ret <= 0)
{ret= -3; goto ex;}
#else
{ret= -7; goto ex;}
#endif
/* "default" ACL */
if(has_default_acl) {
free(acl_text);
@ -582,11 +602,22 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
}
}
ret= 1;
#else
ret= -7;
#endif /* !Libisofs_with_aaip_acL */
ex:;
if(acl_text != NULL)
free(acl_text);
#ifdef Libisofs_with_aaip_xattR
if(list != NULL)
free(list);
#endif
return(ret);
}

View File

@ -7,7 +7,7 @@
See libisofs/aaip_0_2.h
http://libburnia-project.org/wiki/AAIP
Copyright (c) 2009 - 2014 Thomas Schmitt, libburnia project, GPLv2+
Copyright (c) 2009 - 2015 Thomas Schmitt, libburnia project, GPLv2+
*/
@ -62,12 +62,12 @@
#define Aaip_namespace_trusteD 0x05
#define Aaip_namespace_securitY 0x06
static char Aaip_namespace_textS[][16]= {"", "", "system.", "user.", "isofs.",
"trusted.", "security."};
/* maximum expansion: "security." */
#define Aaip_max_name_expansioN 9
static char Aaip_namespace_textS[][Aaip_max_name_expansioN + 1]=
{"", "", "system.", "user.", "isofs.", "trusted.", "security."};
/* --------------------------------- Encoder ---------------------------- */
@ -88,26 +88,30 @@ static int aaip_encode_pair(char *name, size_t attr_length, char *attr,
no longer needed
@param flag Bitfield for control purposes
bit0= set CONTINUE bit of last AAIP field to 1
@return >0 is the number of SUSP fields generated,
0 means error
@return >= 0 is the number of SUSP fields generated,
< 0 means error
*/
size_t aaip_encode(size_t num_attrs, char **names,
size_t *value_lengths, char **values,
size_t *result_len, unsigned char **result, int flag)
ssize_t aaip_encode(size_t num_attrs, char **names,
size_t *value_lengths, char **values,
size_t *result_len, unsigned char **result, int flag)
{
size_t mem_size= 0, comp_size, ret;
size_t mem_size= 0, comp_size;
ssize_t ret;
unsigned int number_of_fields, i, num_recs;
/* Predict memory needs, number of SUSP fields and component records */
*result = NULL;
*result_len= 0;
for(i= 0; i < num_attrs; i++) {
ret= aaip_encode_pair(names[i], value_lengths[i], values[i],
&num_recs, &comp_size, NULL, (size_t) 0, 1);
if(ret <= 0)
if(ret < 0)
return(ret);
mem_size+= comp_size;
}
number_of_fields= mem_size / 250 + !!(mem_size % 250);
if(number_of_fields == 0)
return(0);
mem_size+= number_of_fields * 5;
#ifdef Aaip_encode_debuG
@ -118,14 +122,18 @@ size_t aaip_encode(size_t num_attrs, char **names,
#endif
if(*result == NULL)
return 0;
return ISO_OUT_OF_MEM;
/* Encode pairs into result */
for(i= 0; i < num_attrs; i++) {
ret= aaip_encode_pair(names[i], value_lengths[i], values[i],
&num_recs, &comp_size, *result, *result_len, 0);
if(ret <= 0)
if(ret < 0) {
free(*result);
*result = NULL;
*result_len = 0;
return(ret);
}
(*result_len)+= comp_size;
}
@ -404,7 +412,8 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
/* >>> Duplicate u:: entry. */;
/* >>> ??? If it matches the previous one: ignore */
return((int) ISO_AAIP_ACL_MULT_OBJ);
ret = ISO_AAIP_ACL_MULT_OBJ;
goto ex;
}
has_u++;
} else {
@ -449,7 +458,8 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
/* >>> Duplicate g:: entry. */;
/* >>> ??? If it matches the previous one: ignore */
return((int) ISO_AAIP_ACL_MULT_OBJ);
ret = ISO_AAIP_ACL_MULT_OBJ;
goto ex;
}
has_g++;
} else {
@ -493,7 +503,8 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
/* >>> Duplicate o:: entry. */;
/* >>> ??? If it matches the previous one: ignore */
return((int) ISO_AAIP_ACL_MULT_OBJ);
ret = ISO_AAIP_ACL_MULT_OBJ;
goto ex;
}
has_o++;
} else if(strncmp(rpt, "mask:", 5) == 0) {
@ -1803,8 +1814,8 @@ int aaip_decode_attrs(struct aaip_state **handle,
if(aaip->list_mem_used >= memory_limit)
return(3);
aaip->list_mem_used+= new_mem;
aaip->name_buf= calloc(sizeof(char *), Aaip_initial_name_leN);
aaip->value_buf= calloc(sizeof(char *), Aaip_initial_value_leN);
aaip->name_buf= calloc(1, Aaip_initial_name_leN);
aaip->value_buf= calloc(1, Aaip_initial_value_leN);
if(aaip->name_buf == NULL || aaip->value_buf == NULL)
return(-1);
aaip->name_buf_size= Aaip_initial_name_leN;

View File

@ -30,12 +30,12 @@
no longer needed
@param flag Bitfield for control purposes
bit0= set CONTINUE bit of last AAIP field to 1
@return >0 is the number of SUSP fields generated,
0 means error
@return >= 0 is the number of SUSP fields generated,
< 0 means error
*/
size_t aaip_encode(size_t num_attrs, char **names,
size_t *value_lengths, char **values,
size_t *result_len, unsigned char **result, int flag);
ssize_t aaip_encode(size_t num_attrs, char **names,
size_t *value_lengths, char **values,
size_t *result_len, unsigned char **result, int flag);
/* ------ ACL representation ------ */

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2014 Thomas Schmitt
* Copyright (c) 2009 - 2015 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -21,6 +21,7 @@
#include "image.h"
#include "aaip_0_2.h"
#include "util.h"
#include "messages.h"
#include <stdlib.h>
#include <string.h>
@ -72,8 +73,15 @@ int default_create_file(IsoNodeBuilder *builder, IsoImage *image,
iso_file_source_ref(src);
name = iso_file_source_get_name(src);
if (strlen(name) > LIBISOFS_NODE_NAME_MAX)
name[LIBISOFS_NODE_NAME_MAX] = 0;
if ((int) strlen(name) > image->truncate_length) {
ret = iso_truncate_rr_name(image->truncate_mode,
image->truncate_length, name, 0);
if (ret < 0) {
iso_stream_unref(stream);
free(name);
return ret;
}
}
ret = iso_node_new_file(name, stream, &node);
if (ret < 0) {
iso_stream_unref(stream);
@ -98,11 +106,11 @@ static
int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
IsoFileSource *src, char *in_name, IsoNode **node)
{
int ret;
int ret, name_is_attached = 0;
struct stat info;
IsoNode *new;
IsoFilesystem *fs;
char *name;
char *name = NULL;
unsigned char *aa_string = NULL;
char *a_text = NULL, *d_text = NULL;
char *dest = NULL;
@ -131,8 +139,12 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
}
}
if (strlen(name) > LIBISOFS_NODE_NAME_MAX)
name[LIBISOFS_NODE_NAME_MAX] = 0;
if ((int) strlen(name) > image->truncate_length) {
ret = iso_truncate_rr_name(image->truncate_mode,
image->truncate_length, name, 0);
if (ret < 0)
goto ex;
}
fs = iso_file_source_get_filesystem(src);
new = NULL;
@ -203,12 +215,14 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
}
}
break;
}
if (ret < 0) {
free(name);
default:
ret = ISO_BAD_FSRC_FILETYPE;
goto ex;
}
if (ret < 0)
goto ex;
name_is_attached = 1;
/* fill fields */
iso_node_set_perms_internal(new, info.st_mode, 1);
@ -222,9 +236,9 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
/* Eventually set S_IRWXG from ACL */
if (image->builder_ignore_acl) {
ret = iso_file_source_get_aa_string(src, &aa_string, 4);
if (aa_string != NULL)
if (ret >= 0 && aa_string != NULL)
iso_aa_get_acl_text(aa_string, info.st_mode, &a_text, &d_text, 16);
if (a_text != NULL) {
if (ret >= 0 && a_text != NULL) {
aaip_cleanout_st_mode(a_text, &(info.st_mode), 4 | 16);
iso_node_set_perms_internal(new, info.st_mode, 1);
}
@ -251,6 +265,8 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
ret = ISO_SUCCESS;
ex:;
if (name != NULL && !name_is_attached)
free(name);
LIBISO_FREE_MEM(dest);
return ret;
}

View File

@ -88,6 +88,8 @@ void ecma119_image_free(Ecma119Image *t)
iso_image_unref(t->image);
if (t->files != NULL)
iso_rbtree_destroy(t->files, iso_file_src_free);
if (t->ecma119_hidden_list != NULL)
iso_filesrc_list_destroy(&(t->ecma119_hidden_list));
if (t->buffer != NULL)
iso_ring_buffer_free(t->buffer);
@ -1562,7 +1564,7 @@ int iso_ivr_read_number(char *start_pt, char *end_pt, off_t *result, int flag)
txt[end_pt - start_pt] = 0;
num = iso_scanf_io_size(start_pt, 1 | (flag & 2));
if (num < 0.0 || num > 0xffffffffffff) {
if (num < 0.0 || num > 281474976710655.0) {
iso_msg_submit(-1, ISO_MALFORMED_READ_INTVL, 0,
"Negative or overly large number in interval reader description string");
return ISO_MALFORMED_READ_INTVL;
@ -1995,7 +1997,7 @@ int iso_write_partition_file(Ecma119Image *target, char *path,
off_t byte_count;
FILE *fp = NULL;
uint32_t i, intvl_blocks;
uint32_t i;
uint8_t *buf = NULL;
int ret;
@ -2011,7 +2013,6 @@ int iso_write_partition_file(Ecma119Image *target, char *path,
&ivr, &byte_count, 0);
if (ret < 0)
goto ex;
intvl_blocks = (byte_count + BLOCK_SIZE - 1) / BLOCK_SIZE;
for (i = 0; i < blocks; i++) {
ret = iso_interval_reader_read(ivr, buf, &buf_fill, 0);
if (ret < 0)
@ -2036,7 +2037,8 @@ int iso_write_partition_file(Ecma119Image *target, char *path,
}
ret = iso_write(target, buf, BLOCK_SIZE);
if (ret < 0) {
fclose(fp);
if (fp != NULL)
fclose(fp);
goto ex;
}
}
@ -2344,6 +2346,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
if (ret < 0) {
goto target_cleanup;
}
target->ecma119_hidden_list = NULL;
target->image = src;
iso_image_ref(src);
@ -2396,10 +2399,14 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
sa_type = (system_area_options >> 2) & 0x3f;
if (sa_type != 0 && sa_type != 3)
for (i = 0; i < ISO_MAX_PARTITIONS; i++)
if (opts->appended_partitions[i] != NULL)
return ISO_NON_MBR_SYS_AREA;
if (sa_type != 0 && opts->prep_partition != NULL)
return ISO_NON_MBR_SYS_AREA;
if (opts->appended_partitions[i] != NULL) {
ret = ISO_NON_MBR_SYS_AREA;
goto target_cleanup;
}
if (sa_type != 0 && opts->prep_partition != NULL) {
ret = ISO_NON_MBR_SYS_AREA;
goto target_cleanup;
}
target->system_area_data = NULL;
if (system_area != NULL) {
@ -2534,6 +2541,12 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
break;
}
ret = iso_root_set_isofsnt((IsoNode *) (src->root),
(uint32_t) src->truncate_mode,
(uint32_t) src->truncate_length, 0);
if (ret < 0)
goto target_cleanup;
/*
* 2. Based on those options, create needed writers: iso, joliet...
* Each writer inits its structures and stores needed info into
@ -3414,8 +3427,7 @@ int iso_write_opts_clone(IsoWriteOpts *in, IsoWriteOpts **out, int flag)
return ISO_SUCCESS;
out_of_mem:;
if (o != NULL)
iso_write_opts_free(o);
iso_write_opts_free(o);
return ISO_OUT_OF_MEM;
}
@ -4253,3 +4265,83 @@ ex:
}
static
void ecma119_filesrc_array(Ecma119Node *dir,
int (*include_item)(void *),
IsoFileSrc **filelist, size_t *size, int just_count)
{
size_t i;
Ecma119Node *child;
for (i = 0; i < dir->info.dir->nchildren; i++) {
child = dir->info.dir->children[i];
if (child->type == ECMA119_DIR) {
ecma119_filesrc_array(child, include_item, filelist, size,
just_count);
} else if (child->type == ECMA119_FILE) {
if (include_item != NULL)
if (!include_item((void *) child->info.file))
continue;
if (just_count) {
(*size)++;
} else {
if (!child->info.file->taken) {
filelist[*size] = child->info.file;
child->info.file->taken = 1;
(*size)++;
}
}
}
}
}
static
void hidden_filesrc_array(Ecma119Image *t,
int (*include_item)(void *),
IsoFileSrc **filelist, size_t *size, int just_count)
{
struct iso_filesrc_list_item *item;
for (item = t->ecma119_hidden_list; item != NULL; item = item->next) {
if (include_item != NULL)
if (!include_item((void *) item->src))
continue;
if (just_count) {
(*size)++;
} else {
if (!item->src->taken) {
filelist[*size] = item->src;
item->src->taken = 1;
(*size)++;
}
}
}
}
IsoFileSrc **iso_ecma119_to_filesrc_array(Ecma119Image *t,
int (*include_item)(void *),
size_t *size)
{
IsoFileSrc **filelist = NULL;
/* Count nodes */
*size = 0;
ecma119_filesrc_array(t->root, include_item, filelist, size, 1);
hidden_filesrc_array(t, include_item, filelist, size, 1);
LIBISO_ALLOC_MEM_VOID(filelist, IsoFileSrc *, *size + 1);
/* Fill array */
*size = 0;
ecma119_filesrc_array(t->root, include_item, filelist, size, 0);
hidden_filesrc_array(t, include_item, filelist, size, 0);
filelist[*size] = NULL;
return filelist;
ex: /* LIBISO_ALLOC_MEM failed */
*size = 0;
return NULL;
}

View File

@ -702,6 +702,8 @@ struct ecma119_image
/* tree of files sources */
IsoRBTree *files;
struct iso_filesrc_list_item *ecma119_hidden_list;
unsigned int checksum_idx_counter;
void *checksum_ctx;
off_t checksum_counter;

View File

@ -365,6 +365,35 @@ void ecma119_node_free(Ecma119Node *node)
free(node);
}
static
int add_to_hidden_list(Ecma119Image *image, IsoFileSrc *src)
{
int ret;
struct iso_filesrc_list_item *item;
LIBISO_ALLOC_MEM(item, struct iso_filesrc_list_item, 1);
item->src = src;
item->next = image->ecma119_hidden_list;
image->ecma119_hidden_list = item;
ret = ISO_SUCCESS;
ex:
return ret;
}
int iso_filesrc_list_destroy(struct iso_filesrc_list_item **start_item)
{
struct iso_filesrc_list_item *item, *next;
for (item = *start_item; item != NULL; item = next) {
next = item->next;
LIBISO_FREE_MEM(item);
}
return ISO_SUCCESS;
}
/**
* @param flag
* bit0= iso is in a hidden directory. Thus hide it.
@ -381,11 +410,12 @@ int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree,
int max_path;
char *iso_name= NULL, *ipath = NULL;
IsoFileSrc *src = NULL;
IsoWriteOpts *opts = image->opts;
IsoWriteOpts *opts;
if (image == NULL || iso == NULL || tree == NULL) {
return ISO_NULL_POINTER;
}
opts = image->opts;
*tree = NULL;
hidden = flag & 1;
@ -430,6 +460,9 @@ int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree,
case LIBISO_FILE:
if (hidden) {
ret = create_file_src(image, (IsoFile *) iso, &src);
if (ret <= 0)
goto ex;
ret = add_to_hidden_list(image, src);
} else {
ret = create_file(image, (IsoFile*)iso, &node);
}
@ -470,6 +503,9 @@ int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree,
if (image->eltorito) {
if (hidden) {
ret = el_torito_catalog_file_src_create(image, &src);
if (ret <= 0)
goto ex;
ret = add_to_hidden_list(image, src);
} else {
ret = create_boot_cat(image, (IsoBoot*)iso, &node);
}
@ -618,6 +654,7 @@ int mangle_single_dir(Ecma119Image *img, Ecma119Node *dir, int max_file_len,
for (i = 0; i < nchildren; ++i) {
char *name, *ext;
char full_name[40];
const int full_max_len = 40 - 1;
int max; /* computed max len for name, without extension */
int j = i;
int digits = 1; /* characters to change per name */
@ -656,7 +693,8 @@ int mangle_single_dir(Ecma119Image *img, Ecma119Node *dir, int max_file_len,
int change = 0; /* number to be written */
/* copy name to buffer */
strcpy(full_name, children[i]->iso_name);
strncpy(full_name, children[i]->iso_name, full_max_len);
full_name[full_max_len] = 0;
/* compute name and extension */
dot = strrchr(full_name, '.');

View File

@ -79,6 +79,17 @@ struct ecma119_node
} info;
};
/* For recording files which are hidden in ECMA-119 */
struct iso_filesrc_list_item
{
IsoFileSrc *src;
struct iso_filesrc_list_item *next;
};
int iso_filesrc_list_destroy(struct iso_filesrc_list_item **start_item);
/**
*
*/

View File

@ -454,9 +454,7 @@ int create_image(IsoImage *image, const char *image_path,
boot->platform_id = 0; /* 80x86 */
memset(boot->id_string, 0, sizeof(boot->id_string));
memset(boot->selection_crit, 0, sizeof(boot->selection_crit));
if (bootimg) {
*bootimg = boot;
}
*bootimg = boot;
return ISO_SUCCESS;
}
@ -1178,10 +1176,10 @@ int iso_patch_eltoritos(Ecma119Image *t)
continue;
original = t->bootsrc[idx]->stream;
size = (size_t) iso_stream_get_size(original);
/* >>> BOOT ts B00428 :
check whether size is not too large for buffering */;
if (size > Libisofs_elto_max_patchablE)
return ISO_PATCH_OVERSIZED_BOOT;
if (iso_stream_get_input_stream(original, 0) != NULL)
return ISO_PATCH_FILTERED_BOOT;
buf = calloc(1, size);
if (buf == NULL) {
return ISO_OUT_OF_MEM;

View File

@ -168,4 +168,11 @@ int iso_patch_eltoritos(Ecma119Image *t);
#define Libisofs_grub2_elto_patch_offsT 5
/* Maximum size of a boot image which is marked by
el_torito_set_isolinux_options() for patching (boot info table,
GRUB2 boot info, maybe others).
*/
#define Libisofs_elto_max_patchablE (32 * 1024 * 1024)
#endif /* LIBISO_ELTORITO_H */

View File

@ -229,12 +229,23 @@ int shall_be_written(void *arg)
return f->no_write ? 0 : 1;
}
static
int shall_be_written_if_not_taken(void *arg)
{
IsoFileSrc *f = (IsoFileSrc *)arg;
return f->no_write || f->taken ? 0 : 1;
}
int filesrc_writer_pre_compute(IsoImageWriter *writer)
{
size_t i, size, is_external;
Ecma119Image *t;
IsoFileSrc **filelist;
int (*inc_item)(void *);
size_t omitted_count;
IsoFileSrc **iso_ecma119_to_filesrc_array(Ecma119Image *t,
int (*include_item)(void *),
size_t *size);
if (writer == NULL) {
return ISO_ASSERT_FAILURE;
@ -257,7 +268,16 @@ int filesrc_writer_pre_compute(IsoImageWriter *writer)
}
/* store the filesrcs in a array */
filelist = (IsoFileSrc**)iso_rbtree_to_array(t->files, inc_item, &size);
filelist = (IsoFileSrc**) iso_ecma119_to_filesrc_array(t, inc_item, &size);
omitted_count = iso_rbtree_count_array(t->files, (size_t) 0,
shall_be_written_if_not_taken);
if (omitted_count > 0) {
iso_msg_submit(t->image->id, ISO_NOT_REPRODUCIBLE, 0,
"Cannot arrange content of data files in surely reproducible way");
LIBISO_FREE_MEM(filelist);
filelist = (IsoFileSrc**)iso_rbtree_to_array(
t->files, inc_item, &size);
}
if (filelist == NULL) {
return ISO_OUT_OF_MEM;
}

View File

@ -32,6 +32,10 @@ struct Iso_File_Src
*/
unsigned int no_write :1;
/* Is 1 if the object was already put into the filelist array.
*/
unsigned int taken :1;
unsigned int checksum_index :31;
/** File Sections of the file in the image */

View File

@ -655,14 +655,41 @@ IsoStreamIface extf_stream_class = {
static
int extf_cmp_ino(IsoStream *s1, IsoStream *s2)
{
int i;
ExternalFilterStreamData *data1, *data2;
IsoExternalFilterCommand *cmd1, *cmd2;
/* This function may rely on being called by iso_stream_cmp_ino()
only with s1, s2 which both point to it as their .cmp_ino() function.
It would be a programming error to let any other than extf_stream_class
point to extf_cmp_ino(). This fallback endangers transitivity of
iso_stream_cmp_ino().
*/
if (s1->class != &extf_stream_class || s2->class != &extf_stream_class)
return iso_stream_cmp_ino(s1, s2, 1);
data1 = (ExternalFilterStreamData*) s1->data;
data2 = (ExternalFilterStreamData*) s2->data;
if (data1->cmd != data2->cmd)
return (data1->cmd < data2->cmd ? -1 : 1);
cmd1 = data1->cmd;
cmd2 = data2->cmd;
if (cmd1 != cmd2) {
if (strcmp(cmd1->name, cmd2->name) != 0)
return strcmp(cmd1->name, cmd2->name);
if (strcmp(cmd1->path, cmd2->path) != 0)
return strcmp(cmd1->path, cmd2->path);
if (cmd1->argc != cmd2->argc)
return cmd1->argc < cmd2->argc ? -1 : 1;
for (i = 0; i < cmd1->argc; i++) {
if (strcmp(cmd1->argv[i], cmd2->argv[i]) != 0)
return strcmp(cmd1->argv[i], cmd2->argv[i]);
}
if (cmd1->behavior != cmd2->behavior)
return cmd1->behavior < cmd2->behavior ? -1 : 1;
if (strcmp(cmd1->suffix, cmd2->suffix) != 0)
return strcmp(cmd1->suffix, cmd2->suffix);
}
/* Both streams apply the same treatment to their input streams */
return iso_stream_cmp_ino(data1->orig, data2->orig, 0);
}

View File

@ -573,6 +573,9 @@ int gzip_clone_stream(IsoStream *old_stream, IsoStream **new_stream, int flag)
static
int gzip_cmp_ino(IsoStream *s1, IsoStream *s2);
static
int gzip_uncompress_cmp_ino(IsoStream *s1, IsoStream *s2);
IsoStreamIface gzip_stream_compress_class = {
4,
@ -603,17 +606,44 @@ IsoStreamIface gzip_stream_uncompress_class = {
gzip_stream_free,
gzip_update_size,
gzip_get_input_stream,
gzip_cmp_ino,
gzip_uncompress_cmp_ino,
gzip_clone_stream
};
static
int gzip_cmp_ino(IsoStream *s1, IsoStream *s2)
{
/* This function may rely on being called by iso_stream_cmp_ino()
only with s1, s2 which both point to it as their .cmp_ino() function.
It would be a programming error to let any other than
gzip_stream_compress_class point to gzip_cmp_ino().
This fallback endangers transitivity of iso_stream_cmp_ino().
*/
if (s1->class != s2->class || (s1->class != &gzip_stream_compress_class &&
s2->class != &gzip_stream_compress_class))
return iso_stream_cmp_ino(s1, s2, 1);
/* Both streams apply the same treatment to their input streams */
return iso_stream_cmp_ino(iso_stream_get_input_stream(s1, 0),
iso_stream_get_input_stream(s2, 0), 0);
}
static
int gzip_uncompress_cmp_ino(IsoStream *s1, IsoStream *s2)
{
/* This function may rely on being called by iso_stream_cmp_ino()
only with s1, s2 which both point to it as their .cmp_ino() function.
It would be a programming error to let any other than
gzip_stream_uncompress_class point to gzip_uncompress_cmp_ino().
*/
if (s1->class != s2->class ||
(s1->class != &gzip_stream_uncompress_class &&
s2->class != &gzip_stream_uncompress_class))
return iso_stream_cmp_ino(s1, s2, 1);
/* Both streams apply the same treatment to their input streams */
return iso_stream_cmp_ino(iso_stream_get_input_stream(s1, 0),
iso_stream_get_input_stream(s2, 0), 0);
}

View File

@ -130,9 +130,9 @@ int ziso_running_new(ZisofsFilterRuntime **running, int flag)
o->block_size = ziso_block_size;
#ifdef Libisofs_with_zliB
o->buffer_size= compressBound((uLong) ziso_block_size);
o->buffer_size = compressBound((uLong) ziso_block_size);
#else
o->buffer_size= 2 * ziso_block_size;
o->buffer_size = 2 * ziso_block_size;
#endif
o->read_buffer = calloc(o->block_size, 1);
o->block_buffer = calloc(o->buffer_size, 1);
@ -381,7 +381,7 @@ int ziso_stream_compress(IsoStream *stream, void *buf, size_t desired)
if (todo * 4 > rng->buffer_size)
todo = rng->buffer_size / 4;
memcpy(rng->block_buffer,
data->block_pointers + 4 * rng->block_pointer_rpos,
data->block_pointers + rng->block_pointer_rpos,
todo * 4);
rng->buffer_rpos = 0;
rng->buffer_fill = todo * 4;
@ -838,6 +838,9 @@ no_mem:
static
int ziso_cmp_ino(IsoStream *s1, IsoStream *s2);
static
int ziso_uncompress_cmp_ino(IsoStream *s1, IsoStream *s2);
IsoStreamIface ziso_stream_compress_class = {
4,
@ -868,7 +871,7 @@ IsoStreamIface ziso_stream_uncompress_class = {
ziso_stream_free,
ziso_update_size,
ziso_get_input_stream,
ziso_cmp_ino,
ziso_uncompress_cmp_ino,
ziso_clone_stream
};
@ -876,9 +879,36 @@ IsoStreamIface ziso_stream_uncompress_class = {
static
int ziso_cmp_ino(IsoStream *s1, IsoStream *s2)
{
/* This function may rely on being called by iso_stream_cmp_ino()
only with s1, s2 which both point to it as their .cmp_ino() function.
It would be a programming error to let any other than
ziso_stream_compress_class point to ziso_cmp_ino().
*/
if (s1->class != s2->class || (s1->class != &ziso_stream_compress_class &&
s2->class != &ziso_stream_uncompress_class))
iso_stream_cmp_ino(s1, s2, 1);
/* Both streams apply the same treatment to their input streams */
return iso_stream_cmp_ino(iso_stream_get_input_stream(s1, 0),
iso_stream_get_input_stream(s2, 0), 0);
}
static
int ziso_uncompress_cmp_ino(IsoStream *s1, IsoStream *s2)
{
/* This function may rely on being called by iso_stream_cmp_ino()
only with s1, s2 which both point to it as their .cmp_ino() function.
It would be a programming error to let any other than
ziso_stream_uncompress_class point to ziso_uncompress_cmp_ino().
This fallback endangers transitivity of iso_stream_cmp_ino().
*/
if (s1->class != s2->class ||
(s1->class != &ziso_stream_uncompress_class &&
s2->class != &ziso_stream_uncompress_class))
iso_stream_cmp_ino(s1, s2, 1);
/* Both streams apply the same treatment to their input streams */
return iso_stream_cmp_ino(iso_stream_get_input_stream(s1, 0),
iso_stream_get_input_stream(s2, 0), 0);
}

View File

@ -34,6 +34,7 @@
#include <langinfo.h>
#include <limits.h>
#include <stdio.h>
#include <ctype.h>
/* Enable this and write the correct absolute path into the include statement
@ -98,6 +99,17 @@ struct iso_read_opts
*/
unsigned int preferjoliet : 1;
/**
* If neither Rock Ridge nor Joliet is used, the ECMA-119 names are mapped
* according to one of these rules
* 0 = unmapped: show name as recorded in ECMA-119 directory record
* (not suitable for writing them to a new ISO filesystem)
* 1 = stripped: like unmapped, but strip off trailing ";1" or ".;1"
* 2 = uppercase: like stripped, but {a-z} mapped to {A-Z}
* 3 = lowercase: like stripped, but {A-Z} mapped to {a-z}
*/
unsigned int ecma119_map : 2;
uid_t uid; /**< Default uid when no RR */
gid_t gid; /**< Default uid when no RR */
mode_t dir_mode; /**< Default mode when no RR (only permissions) */
@ -130,6 +142,14 @@ struct iso_read_opts
*/
int keep_import_src;
/**
* What to do in case of name longer than truncate_length:
* 0= throw FAILURE
* 1= truncate to truncate_length with MD5 of whole name at end
*/
int truncate_mode;
int truncate_length;
};
/**
@ -283,6 +303,13 @@ typedef struct
/** If ISO 9660:1999 is available on image */
unsigned int iso1999 : 1;
/**
* See struct iso_read_opts.
*/
int truncate_mode;
int truncate_length;
unsigned int ecma119_map : 2;
/** Whether AAIP info shall be loaded if it is present.
* 1 = yes , 0 = no
*/
@ -1398,7 +1425,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
struct ecma119_dir_record *record,
IsoFileSource **src, int flag)
{
int ret;
int ret, ecma119_map, skip_nm = 0;
struct stat atts;
time_t recorded;
_ImageFsData *fsdata;
@ -1418,10 +1445,9 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
unsigned char *aa_string = NULL;
size_t aa_size = 0, aa_len = 0, prev_field = 0;
int aa_done = 0;
char *cs_value = NULL;
size_t cs_value_length = 0;
char *msg = NULL;
uint8_t *buffer = NULL;
char *cpt;
int has_px = 0;
@ -1439,6 +1465,13 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
memset(&atts, 0, sizeof(struct stat));
atts.st_nlink = 1;
/* Set preliminary file type */
if (record->flags[0] & 0x02) {
atts.st_mode = S_IFDIR;
} else {
atts.st_mode = S_IFREG;
}
/*
* First of all, check for unsupported ECMA-119 features
*/
@ -1580,11 +1613,15 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
"Invalid TF entry");
}
} else if (SUSP_SIG(sue, 'N', 'M')) {
if (skip_nm)
continue; /* in NM error bailout mode */
if (name != NULL && namecont == 0) {
/* ups, RR standard violation */
ret = iso_rr_msg_submit(fsdata, 2, ISO_WRONG_RR_WARN, 0,
"New NM entry found without previous"
"CONTINUE flag. Ignored");
skip_nm = 1;
continue;
}
ret = read_rr_NM(sue, &name, &namecont);
@ -1592,6 +1629,14 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
/* notify and continue */
ret = iso_rr_msg_submit(fsdata, 3, ISO_WRONG_RR_WARN, ret,
"Invalid NM entry");
continue;
}
if (name != NULL) if (strlen(name) > 4095) {
/* Preliminarily truncate totally oversized name */
ret = iso_rr_msg_submit(fsdata, 3, ISO_WRONG_RR_WARN, ret,
"Totally oversized NM list");
skip_nm = 1;
continue;
}
#ifdef Libisofs_syslinux_tesT
@ -1789,30 +1834,6 @@ if (name != NULL && !namecont) {
goto ex;
}
if ((flag & 1) && aa_string != NULL) {
ret = iso_aa_lookup_attr(aa_string, "isofs.cs",
&cs_value_length, &cs_value, 0);
if (ret == 1) {
LIBISO_FREE_MEM(msg);
LIBISO_ALLOC_MEM(msg, char, 160);
if (fsdata->auto_input_charset & 1) {
if (fsdata->input_charset != NULL)
free(fsdata->input_charset);
fsdata->input_charset = cs_value;
sprintf(msg,
"Learned from ISO image: input character set '%.80s'",
cs_value);
} else {
sprintf(msg,
"Character set name recorded in ISO image: '%.80s'",
cs_value);
free(cs_value);
}
iso_msgs_submit(0, msg, 0, "NOTE", 0);
cs_value = NULL;
}
}
/* convert name to needed charset */
if (strcmp(fsdata->input_charset, fsdata->local_charset) && name) {
/* we need to convert name charset */
@ -1904,7 +1925,11 @@ if (name != NULL && !namecont) {
/* remove trailing version number */
len = strlen(name);
if (len > 2 && name[len-2] == ';' && name[len-1] == '1') {
ecma119_map = fsdata->ecma119_map;
if (fsdata->iso_root_block == fsdata->svd_root_block)
ecma119_map = 0;
if (ecma119_map >= 1 && ecma119_map <= 3 &&
len > 2 && name[len-2] == ';' && name[len-1] == '1') {
if (len > 3 && name[len-3] == '.') {
/*
* the "." is mandatory, so in most cases is included only
@ -1915,6 +1940,28 @@ if (name != NULL && !namecont) {
name[len-2] = '\0';
}
}
if (ecma119_map == 2 || ecma119_map == 3) {
for (cpt = name; *cpt != 0; cpt++) {
if (ecma119_map == 2) {
if (islower(*cpt))
*cpt = toupper(*cpt);
} else {
if (isupper(*cpt))
*cpt = tolower(*cpt);
}
}
}
}
}
if (name != NULL) {
if ((int) strlen(name) > fsdata->truncate_length) {
ret = iso_truncate_rr_name(fsdata->truncate_mode,
fsdata->truncate_length, name, 0);
if (ret < 0)
goto ex;
}
}
@ -2136,7 +2183,7 @@ static
int ifs_get_by_path(IsoFilesystem *fs, const char *path, IsoFileSource **file)
{
int ret;
IsoFileSource *src;
IsoFileSource *src = NULL;
char *ptr, *brk_info, *component;
if (fs == NULL || fs->data == NULL || path == NULL || file == NULL) {
@ -2185,6 +2232,7 @@ int ifs_get_by_path(IsoFilesystem *fs, const char *path, IsoFileSource **file)
ret = ifs_get_file(src, component, &child);
iso_file_source_unref(src);
src = NULL;
if (ret <= 0) {
break;
}
@ -2195,7 +2243,8 @@ int ifs_get_by_path(IsoFilesystem *fs, const char *path, IsoFileSource **file)
free(ptr);
if (ret < 0) {
iso_file_source_unref(src);
if (src != NULL)
iso_file_source_unref(src);
} else if (ret == 0) {
ret = ISO_FILE_DOESNT_EXIST;
} else {
@ -2641,8 +2690,8 @@ int read_el_torito_boot_catalog(_ImageFsData *data, uint32_t block)
/* >>> ts B10703 : need to continue rather than abort */;
ret = iso_msg_submit(data->msgid, ISO_EL_TORITO_WARN, 0,
"Too many boot images found. List truncated.");
iso_msg_submit(data->msgid, ISO_EL_TORITO_WARN, 0,
"Too many boot images found. List truncated.");
goto after_bootblocks;
}
/* Read bootblock from section entry */
@ -2837,6 +2886,8 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
data->local_charset = strdup(iso_get_local_charset(0));
if (data->local_charset == NULL) {
ret = ISO_OUT_OF_MEM;
LIBISO_FREE_MEM(data);
data = NULL;
goto fs_cleanup;
}
@ -3013,6 +3064,9 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
data->input_charset = strdup("ASCII");
}
}
data->truncate_mode = opts->truncate_mode;
data->truncate_length = opts->truncate_length;
data->ecma119_map = opts->ecma119_map;
if (data->input_charset == NULL) {
if (opts->input_charset != NULL) {
@ -3227,10 +3281,14 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
new = (IsoNode*) file;
new->refcount = 0;
for (idx = 0; idx < fsdata->num_bootimgs; idx++)
if (fsdata->eltorito && data->sections[0].block ==
fsdata->bootblocks[idx])
break;
if (data->sections[0].size > 0) {
for (idx = 0; idx < fsdata->num_bootimgs; idx++)
if (fsdata->eltorito && data->sections[0].block ==
fsdata->bootblocks[idx])
break;
} else {
idx = fsdata->num_bootimgs;
}
if (idx < fsdata->num_bootimgs) {
/* it is boot image node */
if (image->bootcat->bootimages[idx]->image != NULL) {
@ -3741,7 +3799,7 @@ int iso_analyze_mbr_ptable(IsoImage *image, int flag)
/* Register partition as iso_mbr_partition_request */
if (sai->mbr_req == NULL) {
sai->mbr_req = calloc(ISO_MBR_ENTRIES_MAX,
sizeof(struct iso_mbr_partition_request));
sizeof(struct iso_mbr_partition_request *));
if (sai->mbr_req == NULL)
{ret = ISO_OUT_OF_MEM; goto ex;}
}
@ -3819,7 +3877,7 @@ int iso_analyze_isohybrid(IsoImage *image, int flag)
&sections, 0);
if (ret < 0)
return ret;
if (section_count > 0)
if (ret > 0 && section_count > 0)
eltorito_lba = sections[0].block;
free(sections);
@ -4225,7 +4283,7 @@ int iso_analyze_gpt(IsoImage *image, IsoDataSource *src, int flag)
block_count = block_count + 1 - start_block;
if (sai->gpt_req == NULL) {
sai->gpt_req = calloc(ISO_GPT_ENTRIES_MAX,
sizeof(struct iso_gpt_partition_request));
sizeof(struct iso_gpt_partition_request *));
if (sai->gpt_req == NULL)
return ISO_OUT_OF_MEM;
}
@ -4340,7 +4398,7 @@ int iso_analyze_apm(IsoImage *image, IsoDataSource *src, int flag)
name[32] = 0;
if (sai->apm_req == NULL) {
sai->apm_req = calloc(ISO_APM_ENTRIES_MAX,
sizeof(struct iso_apm_partition_request));
sizeof(struct iso_apm_partition_request *));
if (sai->apm_req == NULL)
return ISO_OUT_OF_MEM;
}
@ -4674,7 +4732,7 @@ int iso_analyze_alpha_boot(IsoImage *image, IsoDataSource *src, int flag)
file = (IsoFile *) node;
ret = iso_file_get_old_image_sections(file, &section_count,
&sections, 0);
if (ret > 0) {
if (ret > 0 && section_count > 0) {
size = sections[0].size / 512 + !!(sections[0].size % 512);
free(sections);
if (size != sai->alpha_boot_image_size)
@ -4795,19 +4853,23 @@ int iso_impsysa_reduce_next_above(IsoImage *image, uint32_t block,
sai->apm_req[i]->block_count) /
(2048 / sai->apm_block_size)));
}
if (image->bootcat != NULL)
if (image->bootcat != NULL) {
if (image->bootcat->node != NULL)
iso_impsysa_reduce_na(block, next_above, image->bootcat->node->lba);
for (i= 0; i < image->bootcat->num_bootimages; i++) {
img = image->bootcat->bootimages[i];
ret = iso_file_get_old_image_sections(img->image, &section_count,
&sections, 0);
if (ret > 0 && section_count > 0)
if (block != sections[0].block)
iso_impsysa_reduce_na(block, next_above, sections[0].block);
if (sections != NULL)
free(sections);
iso_impsysa_reduce_na(block, next_above,
image->bootcat->node->lba);
for (i= 0; i < image->bootcat->num_bootimages; i++) {
img = image->bootcat->bootimages[i];
ret = iso_file_get_old_image_sections(img->image, &section_count,
&sections, 0);
if (ret > 0 && section_count > 0)
if (block != sections[0].block)
iso_impsysa_reduce_na(block, next_above,
sections[0].block);
if (sections != NULL) {
free(sections);
sections = NULL;
}
}
}
iso_impsysa_reduce_na(block, next_above, sai->image_size);
@ -5234,7 +5296,7 @@ int iso_report_help(char **doc, char ***result, int *line_count, int flag)
return ISO_OUT_OF_MEM;
buf = calloc(1, count);
if (buf == NULL) {
free(result);
free(*result);
*result = NULL;
return ISO_OUT_OF_MEM;
}
@ -5307,8 +5369,10 @@ int iso_eltorito_report(IsoImage *image, struct iso_impsysa_result *target,
if (ret > 0 && section_count > 0)
lba = sections[0].block;
lba_mem[i]= lba;
if (sections != NULL)
if (sections != NULL) {
free(sections);
sections = NULL;
}
sprintf(msg,
"El Torito boot img : %3d %4s %c %5s 0x%4.4x 0x%2.2x %5u %10u",
i + 1, pltf, img->bootable ? 'y' : 'n', emul_code,
@ -5607,8 +5671,10 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
IsoNode *node;
char *old_checksum_array = NULL;
char checksum_type[81];
uint32_t checksum_size;
size_t size;
uint32_t checksum_size, truncate_mode, truncate_length;
size_t size, attr_value_length;
char *attr_value;
unsigned char *aa_string = NULL;
void *ctx = NULL;
char md5[16];
struct el_torito_boot_catalog *catalog = NULL;
@ -5618,7 +5684,8 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
return ISO_NULL_POINTER;
}
opts->truncate_mode = image->truncate_mode;
opts->truncate_length = image->truncate_length;
ret = iso_image_filesystem_new(src, opts, image->id, &fs);
if (ret < 0) {
return ret;
@ -5634,24 +5701,55 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
if (image->system_area_data != NULL)
free(image->system_area_data);
image->system_area_data = calloc(32768, 1);
if (image->system_area_data == NULL)
if (image->system_area_data == NULL) {
iso_filesystem_unref(fs);
return ISO_OUT_OF_MEM;
}
image->system_area_options = 0;
/* Read 32768 bytes */
for (i = 0; i < 16; i++) {
rpt = (uint8_t *) (image->system_area_data + i * 2048);
ret = src->read_block(src, opts->block + i, rpt);
if (ret < 0)
if (ret < 0) {
iso_filesystem_unref(fs);
return ret;
}
}
}
/* get root from filesystem */
ret = fs->get_root(fs, &newroot);
if (ret < 0) {
iso_filesystem_unref(fs);
return ret;
}
/* Lookup character set even if no AAIP loading is enabled */
ret = iso_file_source_get_aa_string(newroot, &aa_string, 2);
if (ret == 1 && aa_string != NULL) {
ret = iso_aa_lookup_attr(aa_string, "isofs.cs",
&attr_value_length, &attr_value, 0);
free(aa_string);
} else {
ret = 0;
}
if (ret == 1) {
if (data->auto_input_charset & 1) {
if (data->input_charset != NULL)
free(data->input_charset);
data->input_charset = attr_value;
iso_msg_submit(image->id, ISO_GENERAL_NOTE, 0,
"Learned from ISO image: input character set '%.80s'",
attr_value);
} else {
iso_msg_submit(image->id, ISO_GENERAL_NOTE, 0,
"Ignored character set name recorded in ISO image: '%.80s'",
attr_value);
free(attr_value);
}
attr_value = NULL;
}
/* backup image filesystem, builder and root */
fsback = image->fs;
blback = image->builder;
@ -5699,6 +5797,22 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
}
}
ret = iso_root_get_isofsnt(&(image->root->node), &truncate_mode,
&truncate_length, 0);
if (ret == 1 && (int) truncate_mode == image->truncate_mode &&
image->truncate_mode == 1 &&
truncate_length >= 64 && truncate_length <= 255 &&
(int) truncate_length != image->truncate_length) {
data->truncate_mode = opts->truncate_mode = image->truncate_mode =
truncate_mode;
data->truncate_length = opts->truncate_length =
image->truncate_length = truncate_length;
iso_msg_submit(image->id, ISO_TRUNCATE_ISOFSNT, 0,
"File name truncation length changed by loaded image info: %d",
(int) truncate_length);
}
/* if old image has el-torito, add a new catalog */
if (data->eltorito) {
@ -5815,6 +5929,7 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
if (bootcat->size > 0) {
bootcat->content = calloc(1, bootcat->size);
if (bootcat->content == NULL) {
free(node);
ret = ISO_OUT_OF_MEM;
goto import_revert;
}
@ -6037,9 +6152,12 @@ int iso_read_opts_new(IsoReadOpts **opts, int profile)
ropts->file_mode = 0444;
ropts->dir_mode = 0555;
ropts->noaaip = 1;
ropts->ecma119_map = 1;
ropts->nomd5 = 1;
ropts->load_system_area = 0;
ropts->keep_import_src = 0;
ropts->truncate_mode = 1;
ropts->truncate_length = LIBISOFS_NODE_NAME_MAX;
*opts = ropts;
return ISO_SUCCESS;
@ -6128,6 +6246,17 @@ int iso_read_opts_set_preferjoliet(IsoReadOpts *opts, int preferjoliet)
return ISO_SUCCESS;
}
int iso_read_opts_set_ecma119_map(IsoReadOpts *opts, int ecma119_map)
{
if (opts == NULL) {
return ISO_NULL_POINTER;
}
if (ecma119_map < 0 || ecma119_map > 3)
return 0;
opts->ecma119_map = ecma119_map;
return ISO_SUCCESS;
}
int iso_read_opts_set_default_uid(IsoReadOpts *opts, uid_t uid)
{
if (opts == NULL) {
@ -6272,6 +6401,8 @@ int iso_file_get_old_image_sections(IsoFile *file, int *section_count,
if (flag != 0) {
return ISO_WRONG_ARG_VALUE;
}
*section_count = 0;
*sections = NULL;
if (file->from_old_session != 0) {
/*
@ -6304,6 +6435,8 @@ int iso_file_get_old_image_sections(IsoFile *file, int *section_count,
ifsdata = data->src->data;
*section_count = ifsdata->nsections;
if (*section_count <= 0)
return 1;
*sections = malloc(ifsdata->nsections *
sizeof(struct iso_file_section));
if (*sections == NULL) {
@ -6316,35 +6449,76 @@ int iso_file_get_old_image_sections(IsoFile *file, int *section_count,
return 0;
}
/* Rank two IsoFileSource by their eventual old image LBAs.
Other IsoFileSource classes will be ranked only roughly.
/* Rank two IsoFileSource by their eventual old image LBAs if still non-zero.
Other IsoFileSource classes and zeroized LBAs will be ranked only roughly.
flag bit0 preserves transitivity of the caller by evaluating ifs_class with
non-zero block address as smaller than anything else.
flag bit1 could harm reproducibility of ISO image output.
@param flag bit0= if s1 exor s2 is of applicable class, then enforce
a valid test result by comparing classes
bit1= if both are applicable but also have sections[].block == 0
then enforce a valid test result by comparing object addresses.
*/
int iso_ifs_sections_cmp(IsoFileSource *s1, IsoFileSource *s2, int *cmp_ret,
int flag)
{
int i;
ImageFileSourceData *d1, *d2;
ImageFileSourceData *d1 = NULL, *d2 = NULL;
IsoFileSourceIface *class1 = NULL, *class2 = NULL;
if (s1->class != s2->class) {
*cmp_ret = (s1->class < s2->class ? -1 : 1);
return 0;
/* Newly created IsoFileSrc from imported IsoFile (e.g. boot image)
is not an applicable source. It must be kept from causing a decision
with other non-applicables.
*/
if (s1 != NULL) {
class1 = (IsoFileSourceIface *) s1->class;
if (class1 == &ifs_class) {
d1 = (ImageFileSourceData *) s1->data;
if (d1->nsections > 0)
if (d1->sections[0].block == 0)
class1 = NULL;
}
}
if (s1->class != &ifs_class) {
if (s2 != NULL) {
class2 = (IsoFileSourceIface *) s2->class;
if (class2 == &ifs_class) {
d2 = (ImageFileSourceData *) s2->data;
if (d2->nsections > 0)
if (d2->sections[0].block == 0)
class2 = NULL;
}
}
if (class1 != &ifs_class && class2 != &ifs_class) {
*cmp_ret = 0;
return 0;
}
d1 = s1->data;
d2 = s2->data;
if (d1->nsections < 1)
return 0;
if (d1->sections[0].size < 1)
return 0;
for (i = 0; i < d1->nsections; i++) {
if (i >= d2->nsections) {
*cmp_ret = 1;
if (class1 != class2) {
*cmp_ret = (class1 == &ifs_class ? -1 : 1);
if (flag & 1)
return 1;
}
return 0;
}
if (d1->nsections != d2->nsections) {
*cmp_ret = d1->nsections < d2->nsections ? -1 : 1;
return 1;
}
if (d1->nsections == 0) {
*cmp_ret = 0;
return 1;
}
if (d1->sections[0].size < 1 || d2->sections[0].size < 1) {
if (d1->sections[0].size > d2->sections[0].size)
*cmp_ret = 1;
else if (d1->sections[0].size < d2->sections[0].size)
*cmp_ret = -1;
else
*cmp_ret = 0;
return 1;
}
for (i = 0; i < d1->nsections; i++) {
if (d1->sections[i].block != d2->sections[i].block) {
*cmp_ret = (d1->sections[i].block < d2->sections[i].block ? -1 : 1);
return 1;
@ -6354,10 +6528,6 @@ int iso_ifs_sections_cmp(IsoFileSource *s1, IsoFileSource *s2, int *cmp_ret,
return 1;
}
}
if (i < d2->nsections) {
*cmp_ret = -1;
return 1;
}
*cmp_ret = 0;
return 1;
}

View File

@ -500,7 +500,8 @@ static
int lfs_get_aa_string(IsoFileSource *src, unsigned char **aa_string, int flag)
{
int ret;
size_t num_attrs = 0, *value_lengths = NULL, result_len, sret;
size_t num_attrs = 0, *value_lengths = NULL, result_len;
ssize_t sret;
char *path = NULL, **names = NULL, **values = NULL;
unsigned char *result = NULL;
@ -533,10 +534,10 @@ int lfs_get_aa_string(IsoFileSource *src, unsigned char **aa_string, int flag)
else {
sret = aaip_encode(num_attrs, names,
value_lengths, values, &result_len, &result, 0);
if (sret == 0) {
ret = ISO_OUT_OF_MEM;
if (sret < 0) {
ret = sret;
goto ex;
}
}
}
*aa_string = result;
ret = 1;
@ -544,7 +545,7 @@ ex:;
if (path != NULL)
free(path);
if (names != NULL || value_lengths != NULL || values != NULL)
aaip_get_attr_list(path, &num_attrs, &names, &value_lengths, &values,
aaip_get_attr_list(NULL, &num_attrs, &names, &value_lengths, &values,
1 << 15); /* free memory */
return ret;
}

View File

@ -137,8 +137,10 @@ int iso_get_hfsplus_name(char *input_charset, int imgid, char *name,
curlen = ucslen (ucs_name);
*result = calloc ((curlen * HFSPLUS_MAX_DECOMPOSE_LEN + 1),
sizeof (uint16_t));
if (*result == NULL)
if (*result == NULL) {
free(ucs_name);
return ISO_OUT_OF_MEM;
}
for (iptr = ucs_name, optr = *result; *iptr; iptr++)
{
@ -208,8 +210,12 @@ int iso_get_hfsplus_name(char *input_charset, int imgid, char *name,
while (done);
*cmp_name = calloc ((ucslen (*result) + 1), sizeof (uint16_t));
if (*cmp_name == NULL)
return ISO_OUT_OF_MEM;
if (*cmp_name == NULL) {
free(ucs_name);
free(*result);
*result = NULL;
return ISO_OUT_OF_MEM;
}
for (iptr = *result, optr = *cmp_name; *iptr; iptr++)
{
@ -1573,7 +1579,7 @@ int mangle_leafs(Ecma119Image *target, int flag)
int hfsplus_writer_create(Ecma119Image *target)
{
int ret;
IsoImageWriter *writer;
IsoImageWriter *writer = NULL;
int max_levels;
int level = 0;
IsoNode *pos;
@ -1583,7 +1589,8 @@ int hfsplus_writer_create(Ecma119Image *target)
writer = calloc(1, sizeof(IsoImageWriter));
if (writer == NULL) {
return ISO_OUT_OF_MEM;
ret = ISO_OUT_OF_MEM;
goto ex;
}
make_hfsplus_decompose_pages();
@ -1607,10 +1614,8 @@ int hfsplus_writer_create(Ecma119Image *target)
target->hfsp_ndirs = 0;
target->hfsp_cat_id = 16;
ret = hfsplus_count_tree(target, (IsoNode*)target->image->root);
if (ret < 0) {
free((char *) writer);
return ret;
}
if (ret < 0)
goto ex;
for (i = 0; i < ISO_HFSPLUS_BLESS_MAX; i++)
target->hfsp_bless_id[i] = 0;
@ -1620,12 +1625,13 @@ int hfsplus_writer_create(Ecma119Image *target)
target->hfsp_leafs = calloc (target->hfsp_nleafs, sizeof (target->hfsp_leafs[0]));
if (target->hfsp_leafs == NULL) {
return ISO_OUT_OF_MEM;
ret = ISO_OUT_OF_MEM;
goto ex;
}
ret = set_hfsplus_name (target, target->image->volume_id,
&target->hfsp_leafs[target->hfsp_curleaf]);
if (ret < 0)
return ret;
goto ex;
target->hfsp_leafs[target->hfsp_curleaf].node = (IsoNode *) target->image->root;
target->hfsp_leafs[target->hfsp_curleaf].used_size = target->hfsp_leafs[target->hfsp_curleaf].strlen * 2 + 8 + 2 + sizeof (struct hfsplus_catfile_common);
@ -1656,8 +1662,10 @@ int hfsplus_writer_create(Ecma119Image *target)
{
int cret;
cret = create_tree(target, pos, 2);
if (cret < 0)
return cret;
if (cret < 0) {
ret = cret;
goto ex;
}
pos = pos->next;
target->hfsp_leafs[0].nchildren++;
}
@ -1667,13 +1675,14 @@ int hfsplus_writer_create(Ecma119Image *target)
ret = mangle_leafs(target, 0);
if (ret < 0)
return ret;
goto ex;
for (max_levels = 0; target->hfsp_nleafs >> max_levels; max_levels++);
max_levels += 2;
target->hfsp_levels = calloc (max_levels, sizeof (target->hfsp_levels[0]));
if (target->hfsp_levels == NULL) {
return ISO_OUT_OF_MEM;
ret = ISO_OUT_OF_MEM;
goto ex;
}
target->hfsp_nnodes = 1;
@ -1683,9 +1692,10 @@ int hfsplus_writer_create(Ecma119Image *target)
unsigned bytes_rem = cat_node_size - sizeof (struct hfsplus_btnode) - 2;
target->hfsp_levels[level].nodes = calloc ((target->hfsp_nleafs + 1), sizeof (target->hfsp_levels[level].nodes[0]));
if (!target->hfsp_levels[level].nodes)
return ISO_OUT_OF_MEM;
if (!target->hfsp_levels[level].nodes) {
ret = ISO_OUT_OF_MEM;
goto ex;
}
target->hfsp_levels[level].level_size = 0;
for (i = 0; i < target->hfsp_nleafs; i++)
{
@ -1740,8 +1750,10 @@ int hfsplus_writer_create(Ecma119Image *target)
level++;
target->hfsp_levels[level].nodes = calloc (((last_size + 1) / 2), sizeof (target->hfsp_levels[level].nodes[0]));
if (!target->hfsp_levels[level].nodes)
return ISO_OUT_OF_MEM;
if (!target->hfsp_levels[level].nodes) {
ret = ISO_OUT_OF_MEM;
goto ex;
}
target->hfsp_levels[level].level_size = 0;
@ -1776,16 +1788,21 @@ int hfsplus_writer_create(Ecma119Image *target)
if (target->hfsp_nnodes > (cat_node_size - 0x100) * 8)
{
return iso_msg_submit(target->image->id, ISO_MANGLE_TOO_MUCH_FILES, 0,
"HFS+ map nodes aren't implemented");
return ISO_MANGLE_TOO_MUCH_FILES;
iso_msg_submit(target->image->id, ISO_MANGLE_TOO_MUCH_FILES, 0,
"HFS+ map nodes aren't implemented");
ret = ISO_MANGLE_TOO_MUCH_FILES;
goto ex;
}
/* add this writer to image */
target->writers[target->nwriters++] = writer;
writer = NULL;
return ISO_SUCCESS;
ret = ISO_SUCCESS;
ex:;
if (writer != NULL)
free(writer);
return ret;
}
int hfsplus_tail_writer_create(Ecma119Image *target)
@ -1832,7 +1849,7 @@ struct iso_hfsplus_xinfo_data *iso_hfsplus_xinfo_new(int flag)
}
/* The iso_node_xinfo_cloner function which gets associated to
* iso_hfsplus_xinfo_func by iso_init() resp. iso_init_with_flag() via
* iso_hfsplus_xinfo_func by iso_init() or iso_init_with_flag() via
* iso_node_xinfo_make_clonable()
*/
int iso_hfsplus_xinfo_cloner(void *old_data, void **new_data, int flag)

View File

@ -188,6 +188,9 @@ int iso_image_new(const char *name, IsoImage **image)
img->import_src = NULL;
img->builder_ignore_acl = 1;
img->builder_ignore_ea = 1;
img->truncate_mode = 1;
img->truncate_length = LIBISOFS_NODE_NAME_MAX;
img->truncate_buffer[0] = 0;
img->inode_counter = 0;
img->used_inodes = NULL;
img->used_inodes_start = 0;
@ -1083,3 +1086,45 @@ int iso_image_get_alpha_boot(IsoImage *img, char **boot_loader_path)
}
/* API */
int iso_image_set_truncate_mode(IsoImage *img, int mode, int length)
{
if (mode < 0 || mode > 1)
return ISO_WRONG_ARG_VALUE;
if (length < 64 || length > LIBISOFS_NODE_NAME_MAX)
return ISO_WRONG_ARG_VALUE;
img->truncate_mode = mode;
img->truncate_length = length;
return ISO_SUCCESS;
}
/* API */
int iso_image_get_truncate_mode(IsoImage *img, int *mode, int *length)
{
*mode = img->truncate_mode;
*length = img->truncate_length;
return ISO_SUCCESS;
}
/* Warning: Not thread-safe */
int iso_image_truncate_name(IsoImage *image, const char *name, char **namept,
int flag)
{
int ret;
if (name == NULL)
return ISO_NULL_POINTER;
if ((int) strlen(name) <= image->truncate_length) {
*namept = (char *) name;
return ISO_SUCCESS;
}
*namept = image->truncate_buffer;
if (name != image->truncate_buffer)
strncpy(image->truncate_buffer, name, 4095);
image->truncate_buffer[4095] = 0;
ret = iso_truncate_rr_name(image->truncate_mode, image->truncate_length,
image->truncate_buffer, 0);
return ret;
}

View File

@ -160,6 +160,20 @@ struct Iso_Image
/* TODO
enum iso_replace_mode (*confirm_replace)(IsoFileSource *src, IsoNode *node);
*/
/**
* What to do in case of name longer than truncate_length:
* 0= throw FAILURE
* 1= truncate to truncate_length with MD5 of whole name at end
*/
int truncate_mode;
int truncate_length;
/**
* This is a convenience buffer for name truncation during image
* manipulation where libisofs is not thread-safe anyway.
*/
char truncate_buffer[4096];
/**
* When this is not NULL, it is a pointer to a function that will
@ -230,6 +244,14 @@ struct Iso_Image
};
/* Apply truncation mode to name, using image->truncate_buffer to perform
truncation if needed.
Warning: Not thread-safe !
*/
int iso_image_truncate_name(IsoImage *image, const char *name, char **namept,
int flag);
/* Collect the bitmap of used inode numbers in the range of
_ImageFsData.used_inodes_start + ISO_USED_INODE_RANGE

View File

@ -221,7 +221,7 @@ struct libiso_msgs_item;
*/
#define LIBISO_MSGS_SEV_ABORT 0x71000000
/** A severity to exclude resp. discard any possible message.
/** A severity to exclude or discard any possible message.
Do not use this severity for submitting.
*/
#define LIBISO_MSGS_SEV_NEVER 0x7fffffff
@ -510,7 +510,7 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
0x00020148 (SORRY,HIGH) = Cannot write desired amount of data
0x00020149 (SORRY,HIGH) = Unsuitable filetype for pseudo-drive
0x0002014a (SORRY,HIGH) = Cannot read desired amount of data
0x0002014b (SORRY,HIGH) = Drive is already registered resp. scanned
0x0002014b (SORRY,HIGH) = Drive is already registered and scanned
0x0002014c (FATAL,HIGH) = Emulated drive caught in SCSI function
0x0002014d (SORRY,HIGH) = Asynchromous SCSI error
0x0002014f (SORRY,HIGH) = Timeout with asynchromous SCSI command

View File

@ -31,7 +31,7 @@
* 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
* - or by defining the macros HAVE_STDINT_H or 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
@ -90,7 +90,7 @@
*/
#define iso_lib_header_version_major 1
#define iso_lib_header_version_minor 4
#define iso_lib_header_version_micro 0
#define iso_lib_header_version_micro 2
/**
* Get version of the libisofs library at runtime.
@ -985,7 +985,7 @@ struct IsoStream_Iface
* get_input_stream() added.
* A filter stream must have version 2 at least.
* Version 3 (since 0.6.20)
* compare() added.
* cmp_ino() added.
* A filter stream should have version 3 at least.
* Version 4 (since 1.0.2)
* clone_stream() added.
@ -1107,11 +1107,15 @@ struct IsoStream_Iface
* produce the same output. If in any doubt, then this comparison should
* indicate no match. A match might allow hardlinking of IsoFile objects.
*
* 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.
* A pointer value of NULL is permissible. In this case, function
* iso_stream_cmp_ino() will decide on its own.
*
* If not NULL, this function .cmp_ino() will be called by
* iso_stream_cmp_ino() if both compared streams point to it, and if not
* flag bit0 of iso_stream_cmp_ino() prevents it.
* So a .cmp_ino() function must be able to compare any pair of streams
* which name it as their .cmp_ino(). A fallback to iso_stream_cmp_ino(,,1)
* would endanger transitivity of iso_stream_cmp_ino(,,0).
*
* With filter streams, the decision whether the underlying chains of
* streams match, should be delegated to
@ -1123,16 +1127,9 @@ struct IsoStream_Iface
* cmp_ino(A,A) == 0
* cmp_ino(A,B) == -cmp_ino(B,A)
* if cmp_ino(A,B) == 0 && cmp_ino(B,C) == 0 then cmp_ino(A,C) == 0
* Most tricky is the demand for transitivity:
* if cmp_ino(A,B) < 0 && cmp_ino(B,C) < 0 then cmp_ino(A,C) < 0
*
* A big hazard to the last constraint are tests which do not apply to some
* types of streams.Thus it is mandatory to let iso_stream_cmp_ino(s1,s2,1)
* decide in this case.
*
* A function s1.(*cmp_ino)() must only accept stream s2 if function
* s2.(*cmp_ino)() would accept s1. Best is to accept only the own stream
* type or to have the same function for a family of similar stream types.
*
* @param s1
* The first stream to compare. Expect foreign stream types.
* @param s2
@ -2042,7 +2039,7 @@ int iso_write_opts_set_output_charset(IsoWriteOpts *opts, const char *charset);
* On the other side, an appended image is not self contained. It may refer
* to files that stay stored in the imported existing image.
* This usage model is inspired by CD multi-session. It demands that the
* appended image is finally written to the same media resp. disk file
* appended image is finally written to the same media or disk file
* as the imported image at an address behind the end of that imported image.
* The exact address may depend on media peculiarities and thus has to be
* announced by the application via iso_write_opts_set_ms_block().
@ -2312,7 +2309,7 @@ int iso_write_opts_set_pvd_times(IsoWriteOpts *opts,
* The additional volume descriptor set and trees will allow to mount the
* ISO image at the start of the first partition, while it is still possible
* to mount it via the normal first volume descriptor set and tree at the
* start of the image resp. storage device.
* start of the image or storage device.
* This makes few sense on optical media. But on USB sticks it creates a
* conventional partition table which makes it mountable on e.g. Linux via
* /dev/sdb and /dev/sdb1 alike.
@ -2855,6 +2852,28 @@ int iso_read_opts_set_new_inos(IsoReadOpts *opts, int new_inos);
*/
int iso_read_opts_set_preferjoliet(IsoReadOpts *opts, int preferjoliet);
/**
* How to convert file names if neither Rock Ridge nor Joliet names
* are present and acceptable.
*
* @param opts
* The option set to be manipulated
* @param ecma119_map
* The conversion mode to apply:
* 0 = unmapped: Take name as recorded in ECMA-119 directory record
* (not suitable for writing them to a new ISO filesystem)
* 1 = stripped: Like unmapped, but strip off trailing ";1" or ".;1"
* 2 = uppercase: Like stripped, but map {a-z} to {A-Z}
* 3 = lowercase: Like stripped, but map {A-Z} to {a-z}
* @return
* ISO_SUCCESS if ecma119_map was accepted
* 0 if the value was out of range
* < 0 if other error
*
* @since 1.4.2
*/
int iso_read_opts_set_ecma119_map(IsoReadOpts *opts, int ecma119_map);
/**
* Set default uid for files when RR extensions are not present.
*
@ -3070,9 +3089,93 @@ int iso_image_attach_data(IsoImage *image, void *data, void (*give_up)(void*));
*/
void *iso_image_get_attached_data(IsoImage *image);
/**
* Set the name truncation mode and the maximum name length for nodes from
* image importing, creation of new IsoNode objects, and name changing image
* manipulations.
*
* Truncated names are supposed to be nearly unique because they end by the MD5
* of the first 4095 characters of the untruncated name. One should treat them
* as if they were the untruncated original names.
*
* For proper processing of truncated names it is necessary to use
* iso_image_set_node_name() instead of iso_node_set_name()
* iso_image_add_new_dir() iso_tree_add_new_dir()
* iso_image_add_new_file() iso_tree_add_new_file()
* iso_image_add_new_special() iso_tree_add_new_special()
* iso_image_add_new_symlink() iso_tree_add_new_symlink()
* iso_image_tree_clone() iso_tree_clone()
* iso_image_dir_get_node() iso_dir_get_node()
* iso_image_path_to_node() iso_tree_path_to_node()
*
* Beware of ambiguities if both, the full name and the truncated name,
* exist in the same directory. Best is to only set truncation parameters
* once with an ISO filesystem and to never change them later.
*
* If writing of AAIP is enabled, then the mode and length are recorded in
* xattr "isofs.nt" of the root node.
* If reading of AAIP is enabled and "isofs.nt" is found, then it gets into
* effect if both, the truncate mode value from "isofs.nt" and the current
* truncate mode of the IsoImage are 1, and the length is between 64 and 255.
*
* @param image
* The image which shall be manipulated.
* @param mode
* 0= Do not truncate but throw error ISO_RR_NAME_TOO_LONG if a file name
* is longer than parameter length.
* 1= Truncate to length and overwrite the last 33 bytes of that length
* by a colon ':' and the hex representation of the MD5 of the first
* 4095 bytes of the whole oversized name.
* Potential incomplete UTF-8 characters will get their leading bytes
* replaced by '_'.
* Mode 1 is the default.
* @param length
* Maximum byte count of a file name. Permissible values are 64 to 255.
* Default is 255.
* @return
* ISO_SUCCESS or ISO_WRONG_ARG_VALUE
*
* @since 1.4.2
*/
int iso_image_set_truncate_mode(IsoImage *img, int mode, int length);
/**
* Inquire the current setting of iso_image_set_truncate_mode().
*
* @param image
* The image which shall be inquired.
* @param mode
* Returns the mode value.
* @param length
* Returns the length value.
* @return
* ISO_SUCCESS or <0 = error
*
* @since 1.4.2
*/
int iso_image_get_truncate_mode(IsoImage *img, int *mode, int *length);
/**
* Immediately apply the given truncate mode and length to the given string.
*
* @param mode
* See iso_image_set_truncate_mode()
* @param length
* See iso_image_set_truncate_mode()
* @param name
* The string to be inspected and truncated if mode says so.
* @param flag
* Bitfield for control purposes. Unused yet. Submit 0.
* @return
* ISO_SUCCESS, ISO_WRONG_ARG_VALUE, ISO_RR_NAME_TOO_LONG
*
* @since 1.4.2
*/
int iso_truncate_leaf_name(int mode, int length, char *name, int flag);
/**
* Get the root directory of the image.
* No extra ref is added to it, so you musn't unref it. Use iso_node_ref()
* No extra ref is added to it, so you must not unref it. Use iso_node_ref()
* if you want to get your own reference.
*
* @since 0.6.2
@ -3506,7 +3609,7 @@ int iso_image_set_boot_catalog_hidden(IsoImage *image, int hide_attrs);
/**
* Get the boot media type as of parameter "type" of iso_image_set_boot_image()
* resp. iso_image_add_boot_image().
* or iso_image_add_boot_image().
*
* @param bootimg
* The image to inquire
@ -3632,7 +3735,7 @@ void el_torito_set_no_bootable(ElToritoBootImage *bootimg);
int el_torito_get_bootable(ElToritoBootImage *bootimg);
/**
* Set the id_string of the Validation Entry resp. Sector Header Entry which
* Set the id_string of the Validation Entry or Sector Header Entry which
* will govern the boot image Section Entry in the El Torito Catalog.
*
* @param bootimg
@ -4613,10 +4716,36 @@ int iso_node_xinfo_make_clonable(iso_node_xinfo_func proc,
int iso_node_xinfo_get_cloner(iso_node_xinfo_func proc,
iso_node_xinfo_cloner *cloner, int flag);
/**
* Set the name of a node. Note that if the node is already added to a dir
* this can fail if dir already contains a node with the new name.
* The IsoImage context defines a maximum permissible name length and a mode
* how to react on oversized names. See iso_image_set_truncate_mode().
*
* @param image
* The image object to which the node belongs or shall belong in future.
* @param node
* The node of which you want to change the name. One cannot change the
* name of the root directory.
* @param name
* The new name for the node. It may not be empty. If it is oversized
* then it will be handled according to iso_image_set_truncate_mode().
* @param flag
* bit0= issue warning in case of truncation
* @return
* 1 on success, < 0 on error
*
* @since 1.4.2
*/
int iso_image_set_node_name(IsoImage *image, IsoNode *node, const char *name,
int flag);
/**
* *** Deprecated ***
* use iso_image_set_node_name() instead
*
* Set the name of a node without taking into respect name truncation mode of
* an IsoImage.
*
* @param node
* The node whose name you want to change. Note that you can't change
@ -4632,11 +4761,16 @@ int iso_node_xinfo_get_cloner(iso_node_xinfo_func proc,
*/
int iso_node_set_name(IsoNode *node, const char *name);
/**
* Get the name of a node.
* The returned string belongs to the node and must not be modified nor
* freed. Use strdup if you really need your own copy.
*
* Up to version 1.4.2 inquiry of the root directory name returned NULL,
* which is a bug in the light of above description.
* Since 1.4.2 the return value is an empty string.
*
* @since 0.6.2
*/
const char *iso_node_get_name(const IsoNode *node);
@ -4826,10 +4960,17 @@ int iso_dir_add_node(IsoDir *dir, IsoNode *child,
/**
* Locate a node inside a given dir.
*
* The IsoImage context defines a maximum permissible name length and a mode
* how to react on oversized names. See iso_image_set_truncate_mode().
* If the caller looks for an oversized name and image truncate mode is 1,
* then this call looks for the truncated name among the nodes of dir.
*
* @param image
* The image object to which dir belongs.
* @param dir
* The dir where to look for the node.
* @param name
* The name of the node
* The name of the node. (Will not be changed if truncation happens.)
* @param node
* Location for a pointer to the node, it will filled with NULL if the dir
* doesn't have a child with the given name.
@ -4837,6 +4978,33 @@ int iso_dir_add_node(IsoDir *dir, IsoNode *child,
* iso_node_ref() to get your own reference to the node.
* Note that you can pass NULL is the only thing you want to do is check
* if a node with such name already exists on dir.
* @param flag
* Bitfield for control purposes.
* bit0= do not truncate name but lookup exactly as given.
* @return
* 1 node found
* 0 no name truncation was needed, name not found in dir
* 2 name truncation happened, truncated name not found in dir
* < 0 error, see iso_dir_get_node().
*
* @since 1.4.2
*/
int iso_image_dir_get_node(IsoImage *image, IsoDir *dir,
const char *name, IsoNode **node, int flag);
/**
* *** Deprecated ***
* In most cases use iso_image_dir_get_node() instead.
*
* Locate a node inside a given dir without taking into respect name truncation
* mode of an IsoImage.
*
* @param dir
* The dir where to look for the node.
* @param name
* The name of the node
* @param node
* Location for a pointer to the node. See iso_image_get_node().
* @return
* 1 node found, 0 child has no such node, < 0 error
* Possible errors:
@ -5324,7 +5492,8 @@ int iso_file_get_old_image_lba(IsoFile *file, uint32_t *lba, int flag);
* @param section_count
* Returns the number of extent entries in sections array.
* @param sections
* Returns the array of file sections. Apply free() to dispose it.
* Returns the array of file sections if section_count > 0.
* In this case, apply free() to dispose it.
* @param flag
* Reserved for future usage, submit 0
* @return
@ -5354,11 +5523,15 @@ int iso_node_get_old_image_lba(IsoNode *node, uint32_t *lba, int flag);
* Add a new directory to the iso tree. Permissions, owner and hidden atts
* are taken from parent, you can modify them later.
*
* @param image
* The image object to which the new directory shall belong.
* @param parent
* the dir where the new directory will be created
* The directory node where the new directory will be grafted in.
* @param name
* name for the new dir. If a node with same name already exists on
* parent, this functions fails with ISO_NODE_NAME_NOT_UNIQUE.
* Name for the new directory. If truncation mode is set to 1,
* an oversized name gets truncated before further processing.
* If a node with same name already exists on parent, this function
* fails with ISO_NODE_NAME_NOT_UNIQUE.
* @param dir
* place where to store a pointer to the newly created dir. No extra
* ref is addded, so you will need to call iso_node_ref() if you really
@ -5370,6 +5543,33 @@ int iso_node_get_old_image_lba(IsoNode *node, uint32_t *lba, int flag);
* ISO_NULL_POINTER, if parent or name are NULL
* ISO_NODE_NAME_NOT_UNIQUE, a node with same name already exists
* ISO_OUT_OF_MEM
* ISO_RR_NAME_TOO_LONG
*
* @since 1.4.2
*/
int iso_image_add_new_dir(IsoImage *image, IsoDir *parent, const char *name,
IsoDir **dir);
/**
* *** Deprecated ***
* use iso_image_add_new_dir() instead
*
* Add a new directory to the iso tree without taking into respect name
* truncation mode of an IsoImage.
* For detailed description of parameters, see above iso_image_add_new_dir().
*
* @param parent
* the dir where the new directory will be created
* @param name
* name for the new dir.
* @param dir
* place where to store a pointer to the newly created dir.i
* @return
* number of nodes in parent if success, < 0 otherwise
* Possible errors:
* ISO_NULL_POINTER, if parent or name are NULL
* ISO_NODE_NAME_NOT_UNIQUE, a node with same name already exists
* ISO_OUT_OF_MEM
*
* @since 0.6.2
*/
@ -5380,11 +5580,15 @@ int iso_tree_add_new_dir(IsoDir *parent, const char *name, IsoDir **dir);
* owner and hidden atts are taken from parent. You can modify any of them
* later.
*
* @param parent
* the dir where the new file will be created
* @param image
* The image object to which the new file shall belong.
* @param parent
* The directory node where the new directory will be grafted in.
* @param name
* name for the new file. If a node with same name already exists on
* parent, this functions fails with ISO_NODE_NAME_NOT_UNIQUE.
* Name for the new file. If truncation mode is set to 1,
* an oversized name gets truncated before further processing.
* If a node with same name already exists on parent, this function
* fails with ISO_NODE_NAME_NOT_UNIQUE.
* @param stream
* IsoStream for the contents of the file. The reference will be taken
* by the newly created file, you will need to take an extra ref to it
@ -5400,6 +5604,35 @@ int iso_tree_add_new_dir(IsoDir *parent, const char *name, IsoDir **dir);
* ISO_NULL_POINTER, if parent, name or dest are NULL
* ISO_NODE_NAME_NOT_UNIQUE, a node with same name already exists
* ISO_OUT_OF_MEM
* ISO_RR_NAME_TOO_LONG
*
* @since 1.4.2
*/
int iso_image_add_new_file(IsoImage *image, IsoDir *parent, const char *name,
IsoStream *stream, IsoFile **file);
/**
* *** Deprecated ***
* use iso_image_add_new_file() instead
*
* Add a new regular file to the iso tree without taking into respect name
* truncation mode of an IsoImage.
* For detailed description of parameters, see above iso_image_add_new_file().
*
* @param parent
* the dir where the new file will be created
* @param name
* name for the new file.
* @param stream
* IsoStream for the contents of the file.
* @param file
* place where to store a pointer to the newly created file.
* @return
* number of nodes in parent if success, < 0 otherwise
* Possible errors:
* ISO_NULL_POINTER, if parent, name or dest are NULL
* ISO_NODE_NAME_NOT_UNIQUE, a node with same name already exists
* ISO_OUT_OF_MEM
*
* @since 0.6.4
*/
@ -5425,22 +5658,58 @@ int iso_tree_add_new_file(IsoDir *parent, const char *name, IsoStream *stream,
int iso_memory_stream_new(unsigned char *buf, size_t size, IsoStream **stream);
/**
* Add a new symlink to the directory tree. Permissions are set to 0777,
* Add a new symbolic link to the directory tree. Permissions are set to 0777,
* owner and hidden atts are taken from parent. You can modify any of them
* later.
*
* @param image
* The image object to which the new directory shall belong.
* @param parent
* The directory node where the new symlink will be grafted in.
* @param name
* Name for the new symlink. If truncation mode is set to 1,
* an oversized name gets truncated before further processing.
* If a node with same name already exists on parent, this function
* fails with ISO_NODE_NAME_NOT_UNIQUE.
* @param dest
* The destination path of the link. The components of this path are
* not checked for being oversized.
* @param link
* Place where to store a pointer to the newly created link. No extra
* ref is addded, so you will need to call iso_node_ref() if you really
* need it. You can pass NULL in this parameter if you don't need the
* pointer
* @return
* number of nodes in parent if success, < 0 otherwise
* Possible errors:
* ISO_NULL_POINTER, if parent, name or dest are NULL
* ISO_NODE_NAME_NOT_UNIQUE, a node with same name already exists
* ISO_OUT_OF_MEM
* ISO_RR_NAME_TOO_LONG
*
* @since 1.4.2
*/
int iso_image_add_new_symlink(IsoImage *image, IsoDir *parent,
const char *name, const char *dest,
IsoSymlink **link);
/**
* *** Deprecated ***
* use iso_image_add_new_symlink() instead
*
* Add a new symlink to the directory tree without taking into respect name
* truncation mode of an IsoImage.
* For detailed description of parameters, see above
* iso_image_add_new_isymlink().
*
* @param parent
* the dir where the new symlink will be created
* @param name
* name for the new symlink. If a node with same name already exists on
* parent, this functions fails with ISO_NODE_NAME_NOT_UNIQUE.
* name for the new symlink.
* @param dest
* destination of the link
* @param link
* place where to store a pointer to the newly created link. No extra
* ref is addded, so you will need to call iso_node_ref() if you really
* need it. You can pass NULL in this parameter if you don't need the
* pointer
* place where to store a pointer to the newly created link.
* @return
* number of nodes in parent if success, < 0 otherwise
* Possible errors:
@ -5455,7 +5724,7 @@ int iso_tree_add_new_symlink(IsoDir *parent, const char *name,
/**
* Add a new special file to the directory tree. As far as libisofs concerns,
* an special file is a block device, a character device, a FIFO (named pipe)
* a special file is a block device, a character device, a FIFO (named pipe)
* or a socket. You can choose the specific kind of file you want to add
* by setting mode propertly (see man 2 stat).
*
@ -5466,24 +5735,61 @@ int iso_tree_add_new_symlink(IsoDir *parent, const char *name,
* Owner and hidden atts are taken from parent. You can modify any of them
* later.
*
* @param image
* The image object to which the new special file shall belong.
* @param parent
* the dir where the new special file will be created
* The directory node where the new special file will be grafted in.
* @param name
* name for the new special file. If a node with same name already exists
* on parent, this functions fails with ISO_NODE_NAME_NOT_UNIQUE.
* Name for the new special file. If truncation mode is set to 1,
* an oversized name gets truncated before further processing.
* If a node with same name already exists on parent, this function
* fails with ISO_NODE_NAME_NOT_UNIQUE.
* @param mode
* file type and permissions for the new node. Note that you can't
* specify any kind of file here, only special types are allowed. i.e,
* S_IFSOCK, S_IFBLK, S_IFCHR and S_IFIFO are valid types; S_IFLNK,
* S_IFREG and S_IFDIR aren't.
* File type and permissions for the new node. Note that only the file
* types S_IFSOCK, S_IFBLK, S_IFCHR, and S_IFIFO are allowed.
* S_IFLNK, S_IFREG, or S_IFDIR are not.
* @param dev
* device ID, equivalent to the st_rdev field in man 2 stat.
* Device ID, equivalent to the st_rdev field in man 2 stat.
* @param special
* place where to store a pointer to the newly created special file. No
* Place where to store a pointer to the newly created special file. No
* extra ref is addded, so you will need to call iso_node_ref() if you
* really need it. You can pass NULL in this parameter if you don't need
* the pointer.
* @return
* Number of nodes in parent if success, < 0 otherwise
* Possible errors:
* ISO_NULL_POINTER, if parent, name or dest are NULL
* ISO_NODE_NAME_NOT_UNIQUE, a node with same name already exists
* ISO_WRONG_ARG_VALUE if you select a incorrect mode
* ISO_OUT_OF_MEM
* ISO_RR_NAME_TOO_LONG
*
* @since 1.4.2
*/
int iso_image_add_new_special(IsoImage *image, IsoDir *parent,
const char *name, mode_t mode,
dev_t dev, IsoSpecial **special);
/**
* *** Deprecated ***
* use iso_image_add_new_special() instead
*
* Add a new special file to the directory tree without taking into respect name
* truncation mode of an IsoImage.
* For detailed description of parameters, see above
* iso_image_add_new_special().
*
* @param parent
* the dir where the new special file will be created
* @param name
* name for the new special file.
* @param mode
* file type and permissions for the new node.
* @param dev
* device ID, equivalent to the st_rdev field in man 2 stat.
* @param special
* place where to store a pointer to the newly created special file.
* @return
* number of nodes in parent if success, < 0 otherwise
* Possible errors:
* ISO_NULL_POINTER, if parent, name or dest are NULL
@ -5594,7 +5900,7 @@ int iso_tree_get_ignore_special(IsoImage *image);
* iso_tree_add_dir_rec(image, root, "/home/user/data/private");
*
* the directory /home/user/data/private is added. On the other, side, and
* foollowing the the example above,
* following the example above,
*
* iso_tree_add_dir_rec(image, root, "/home/user");
*
@ -5606,8 +5912,8 @@ int iso_tree_get_ignore_special(IsoImage *image);
* iso_tree_add_exclude(image, "private");
* iso_tree_add_exclude(image, "user/data");
*
* to excluve, respectively, all files or dirs named private, and also all
* files or dirs named data that belong to a folder named "user". Not that the
* to exclude, respectively, all files or dirs named private, and also all
* files or dirs named data that belong to a folder named "user". Note that the
* above rule about deeper dirs is still valid. i.e., if you call
*
* iso_tree_add_dir_rec(image, root, "/home/user/data/music");
@ -5673,7 +5979,8 @@ void iso_tree_set_report_callback(IsoImage *image,
* The directory in the image tree where the node will be added.
* @param path
* The absolute path of the file in the local filesystem.
* The node will have the same leaf name as the file on disk.
* The node will have the same leaf name as the file on disk, possibly
* truncated according to iso_image_set_truncate_mode().
* Its directory path depends on the parent node.
* @param node
* place where to store a pointer to the newly added file. No
@ -5686,6 +5993,7 @@ void iso_tree_set_report_callback(IsoImage *image,
* ISO_NULL_POINTER, if image, parent or path are NULL
* ISO_NODE_NAME_NOT_UNIQUE, a node with same name already exists
* ISO_OUT_OF_MEM
* ISO_RR_NAME_TOO_LONG
*
* @since 0.6.2
*/
@ -5704,7 +6012,8 @@ int iso_tree_add_node(IsoImage *image, IsoDir *parent, const char *path,
* @param parent
* The directory in the image tree where the node will be added.
* @param name
* The leaf name that the node will have on image.
* The leaf name that the node will have on image, possibly truncated
* according to iso_image_set_truncate_mode().
* Its directory path depends on the parent node.
* @param path
* The absolute path of the file in the local filesystem.
@ -5719,6 +6028,7 @@ int iso_tree_add_node(IsoImage *image, IsoDir *parent, const char *path,
* ISO_NULL_POINTER, if image, parent or path are NULL
* ISO_NODE_NAME_NOT_UNIQUE, a node with same name already exists
* ISO_OUT_OF_MEM
* ISO_RR_NAME_TOO_LONG
*
* @since 0.6.4
*/
@ -5735,7 +6045,8 @@ int iso_tree_add_new_node(IsoImage *image, IsoDir *parent, const char *name,
* @param parent
* The directory in the image tree where the node will be added.
* @param name
* The leaf name that the node will have on image.
* The leaf name that the node will have on image, possibly truncated
* according to iso_image_set_truncate_mode().
* Its directory path depends on the parent node.
* @param path
* The absolute path of the file in the local filesystem. For now
@ -5756,6 +6067,7 @@ int iso_tree_add_new_node(IsoImage *image, IsoDir *parent, const char *name,
* ISO_NULL_POINTER, if image, parent or path are NULL
* ISO_NODE_NAME_NOT_UNIQUE, a node with same name already exists
* ISO_OUT_OF_MEM
* ISO_RR_NAME_TOO_LONG
*
* @since 0.6.4
*/
@ -5790,6 +6102,42 @@ int iso_tree_add_new_cut_out_node(IsoImage *image, IsoDir *parent,
* 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.
*
* The IsoImage context defines a maximum permissible name length and a mode
* how to react on oversized names. See iso_image_set_truncate_mode().
*
* @param image
* The image object to which the node belongs.
* @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.
* bit1= issue warning in case of new_name truncation
* @return
* <0 means error, 1 = new node created,
* 2 = if flag bit0 is set: new_node is a directory which already existed.
*
* @since 1.4.2
*/
int iso_image_tree_clone(IsoImage *image, IsoNode *node, IsoDir *new_parent,
char *new_name, IsoNode **new_node, int flag);
/**
* *** Deprecated ***
* use iso_image_tree_clone() instead
*
* Create a copy of the given node under a different path without taking
* into respect name truncation mode of an IsoImage.
*
* @param node
* The node to be cloned.
@ -5838,17 +6186,48 @@ int iso_tree_clone(IsoNode *node,
int iso_tree_add_dir_rec(IsoImage *image, IsoDir *parent, const char *dir);
/**
* Locate a node by its absolute path on image.
* Locate a node by its absolute path in the image.
* The IsoImage context defines a maximum permissible name length and a mode
* how to react on oversized names. See iso_image_set_truncate_mode().
*
* @param image
* The image to which the node belongs.
* @param path
* File path beginning at the root directory of image. If truncation mode
* is set to 1, oversized path components will be truncated before lookup.
* @param node
* Location for a pointer to the node, it will filled with NULL if the
* Location for a pointer to the node, it will be filled with NULL if the
* given path does not exists on image.
* The node will be owned by the image and shouldn't be unref(). Just call
* iso_node_ref() to get your own reference to the node.
* Note that you can pass NULL is the only thing you want to do is check
* if a node with such path really exists.
*
* @return
* 1 node found
* 0 no truncation was needed, path not found in image
* 2 truncation happened, truncated path component not found in parent dir
* < 0 error, see iso_dir_get_node().
*
* @since 1.4.2
*/
int iso_image_path_to_node(IsoImage *image, const char *path, IsoNode **node);
/**
* *** Deprecated ***
* In most cases use iso_image_path_to_node() instead
*
* Locate a node by its absolute path on image without taking into respect
* name truncation mode of the image.
*
* @param image
* The image to which the node belongs.
* @param path
* File path beginning at the root directory of image. No truncation will
* happen.
* @param node
* Location for a pointer to the node, it will be filled with NULL if the
* given path does not exists on image. See iso_image_path_to_node().
* @return
* 1 found, 0 not found, < 0 error
*
@ -6639,9 +7018,7 @@ char *iso_stream_get_source_path(IsoStream *stream, int flag);
* @return
* -1 if s1 is smaller s2 , 0 if s1 matches s2 , 1 if s1 is larger s2
* @param flag
* bit0= do not use s1->class->compare() even if available
* (e.g. because iso_stream_cmp_ino(0 is called as fallback
* from said stream->class->compare())
* bit0= do not use s1->class->cmp_ino() even if available
*
* @since 0.6.20
*/
@ -6678,7 +7055,7 @@ int iso_stream_clone(IsoStream *old_stream, IsoStream **new_stream, int flag);
*
* An AAIP string contains the Attribute List with the xattr and ACL of a node
* in the image tree. It is formatted according to libisofs specification
* AAIP-2.0 and ready to be written into the System Use Area resp. Continuation
* AAIP-2.0 and ready to be written into the System Use Area or Continuation
* Area of a directory entry in an ISO image.
*
* Applications are not supposed to manipulate AAIP strings directly.
@ -6699,14 +7076,14 @@ 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().
* by iso_init() or 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.
* The result will be in "long" text form as of man acl resp. acl_to_text().
* The result will be in "long" text form as of man acl and acl_to_text().
* Call this function with flag bit15 to finally release the memory
* occupied by an ACL inquiry.
*
@ -6920,7 +7297,7 @@ int iso_node_set_attrs(IsoNode *node, size_t num_attrs, char **names,
* It is permissibile to set them to 1 already now.
* bit8 and higher: reserved, submit 0
* @return
* Bitfield corresponding to flag. If bits are set, th
* Bitfield corresponding to flag.
* bit0= ACL adapter is enabled
* bit1= xattr adapter is enabled
* bit2 - bit7= Reserved for future types.
@ -6952,7 +7329,7 @@ int iso_local_attr_support(int flag);
* 0 no ACL manipulation adapter available / ACL not supported on fs
* -1 failure of system ACL service (see errno)
* -2 attempt to inquire ACL of a symbolic link without bit4 or bit5
* resp. with no suitable link target
* or with no suitable link target
*
* @since 0.6.14
*/
@ -6976,7 +7353,7 @@ int iso_local_get_acl_text(char *disk_path, char **text, int flag);
* 0 no ACL manipulation adapter available for desired ACL type
* -1 failure of system ACL service (see errno)
* -2 attempt to manipulate ACL of a symbolic link without bit5
* resp. with no suitable link target
* or with no suitable link target
*
* @since 0.6.14
*/
@ -6997,7 +7374,7 @@ int iso_local_set_acl_text(char *disk_path, char *text, int flag);
* Returns permission bits as of stat(2)
* @return
* 1 success
* -1 failure of lstat() resp. stat() (see errno)
* -1 failure of lstat() or stat() (see errno)
*
* @since 0.6.14
*/
@ -7205,7 +7582,7 @@ struct iso_external_filter_command
int behavior;
/* The eventual suffix which is supposed to be added to the IsoFile name
* resp. to be removed from the name.
* or to be removed from the name.
* (This is to be done by the application, not by calls
* iso_file_add_external_filter() or iso_file_remove_filter().
* The value recorded here serves only as reminder for the application.)
@ -8313,6 +8690,30 @@ int iso_conv_name_chars(IsoWriteOpts *opts, char *name, size_t name_len,
(WARNING, HIGH, -408) */
#define ISO_INTVL_READ_PROBLEM 0xD030FE68
/** Cannot arrange content of data files in surely reproducible way
(NOTE, HIGH, -409) */
#define ISO_NOT_REPRODUCIBLE 0xB030FE67
/** May not write boot info into filtered stream of boot image
(FAILURE, HIGH, -410) */
#define ISO_PATCH_FILTERED_BOOT 0xE830FE66
/** Boot image to large to buffer for writing boot info
(FAILURE, HIGH, -411) */
#define ISO_PATCH_OVERSIZED_BOOT 0xE830FE65
/** File name had to be truncated and MD5 marked (WARNING, HIGH, -412) */
#define ISO_RR_NAME_TRUNCATED 0xD030FE64
/** File name truncation length changed by loaded image info
(NOTE, HIGH, -413) */
#define ISO_TRUNCATE_ISOFSNT 0xB030FE63
/** General note (NOTE, HIGH, -414) */
#define ISO_GENERAL_NOTE 0xB030FE62
/** Unrecognized file type of IsoFileSrc object (SORRY, HIGH, -415) */
#define ISO_BAD_FSRC_FILETYPE 0xE030FE61
/* Internal developer note:
Place new error codes directly above this comment.
@ -8510,5 +8911,4 @@ struct burn_source {
#define Libisofs_with_rrip_rR yes
*/
#endif /*LIBISO_LIBISOFS_H_*/

View File

@ -75,6 +75,10 @@ iso_hfsplus_xinfo_func;
iso_hfsplus_xinfo_new;
iso_image_add_boot_image;
iso_image_add_mips_boot_file;
iso_image_add_new_dir;
iso_image_add_new_file;
iso_image_add_new_special;
iso_image_add_new_symlink;
iso_image_attach_data;
iso_image_create_burn_source;
iso_image_filesystem_new;
@ -99,6 +103,7 @@ iso_image_get_bootcat;
iso_image_get_boot_image;
iso_image_get_copyright_file_id;
iso_image_get_data_preparer_id;
iso_image_dir_get_node;
iso_image_get_hppa_palo;
iso_image_get_mips_boot_files;
iso_image_get_msg_id;
@ -109,6 +114,7 @@ iso_image_get_session_md5;
iso_image_get_sparc_core;
iso_image_get_system_area;
iso_image_get_system_id;
iso_image_get_truncate_mode;
iso_image_get_volset_id;
iso_image_get_volume_id;
iso_image_give_up_mips_boot;
@ -116,6 +122,7 @@ iso_image_hfsplus_bless;
iso_image_hfsplus_get_blessed;
iso_image_import;
iso_image_new;
iso_image_path_to_node;
iso_image_ref;
iso_image_remove_boot_image;
iso_image_report_el_torito;
@ -132,11 +139,14 @@ iso_image_set_copyright_file_id;
iso_image_set_data_preparer_id;
iso_image_set_hppa_palo;
iso_image_set_ignore_aclea;
iso_image_set_node_name;
iso_image_set_publisher_id;
iso_image_set_sparc_core;
iso_image_set_system_id;
iso_image_set_truncate_mode;
iso_image_set_volset_id;
iso_image_set_volume_id;
iso_image_tree_clone;
iso_image_unref;
iso_image_update_sizes;
iso_init;
@ -225,6 +235,7 @@ iso_read_opts_new;
iso_read_opts_set_default_gid;
iso_read_opts_set_default_permissions;
iso_read_opts_set_default_uid;
iso_read_opts_set_ecma119_map;
iso_read_opts_set_input_charset;
iso_read_opts_set_new_inos;
iso_read_opts_set_no_aaip;
@ -280,6 +291,7 @@ iso_tree_set_ignore_hidden;
iso_tree_set_ignore_special;
iso_tree_set_replace_mode;
iso_tree_set_report_callback;
iso_truncate_leaf_name;
iso_util_decode_md5_tag;
iso_write_opts_attach_jte;
iso_write_opts_detach_jte;

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2014 Thomas Schmitt
* Copyright (c) 2009 - 2015 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -38,6 +38,7 @@
#include "util.h"
#include "node.h"
#include "stream.h"
/*
@ -232,6 +233,7 @@ void iso_finish()
{
libiso_msgs_destroy(&libiso_msgr, 0);
iso_node_xinfo_dispose_cloners(0);
iso_stream_destroy_cmpranks(0);
}
int iso_set_abort_severity(char *severity)
@ -527,6 +529,20 @@ const char *iso_error_to_msg(int errcode)
return "Malformed description string for interval reader";
case ISO_INTVL_READ_PROBLEM:
return "Unreadable file, premature EOF, or failure to seek for interval reader";
case ISO_NOT_REPRODUCIBLE:
return "Cannot arrange content of data files in surely reproducible way";
case ISO_PATCH_FILTERED_BOOT:
return "May not write boot info into filtered stream of boot image";
case ISO_PATCH_OVERSIZED_BOOT:
return "Boot image to large to buffer for writing boot info";
case ISO_RR_NAME_TRUNCATED:
return "File name had to be truncated and MD5 marked";
case ISO_TRUNCATE_ISOFSNT:
return "File name truncation length changed by loaded image info";
case ISO_GENERAL_NOTE:
return "A general note message was issued";
case ISO_BAD_FSRC_FILETYPE:
return "Unrecognized file type of IsoFileSrc object";
default:
return "Unknown error";
}
@ -555,7 +571,8 @@ int iso_msg_submit(int imgid, int errcode, int causedby, const char *fmt, ...)
vsnprintf(msg, MAX_MSG_LEN, fmt, ap);
va_end(ap);
} else {
strncpy(msg, iso_error_to_msg(errcode), MAX_MSG_LEN);
strncpy(msg, iso_error_to_msg(errcode), MAX_MSG_LEN - 1);
msg[MAX_MSG_LEN - 1] = 0;
}
libiso_msgs_submit(libiso_msgr, imgid, ISO_ERR_CODE(errcode),

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2014 Thomas Schmitt
* Copyright (c) 2009 - 2015 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -327,32 +327,50 @@ enum IsoNodeType iso_node_get_type(IsoNode *node)
* Set the name of a node.
*
* @param name The name in UTF-8 encoding
* @param truncate_length (<64 = return on oversized name )
* @param flag bit0= issue warning in case of truncation
*/
int iso_node_set_name(IsoNode *node, const char *name)
int iso_node_set_name_trunc(IsoNode *node, const char *in_name,
int truncate_length, int flag)
{
char *new;
char *new, *name, *trunc = NULL;
int ret;
if ((IsoNode*)node->parent == node) {
/* you can't change name of the root node */
return ISO_WRONG_ARG_VALUE;
ret = ISO_WRONG_ARG_VALUE;
goto ex;
}
name = (char *) in_name;
if (truncate_length >= 64) {
trunc = strdup(name);
if (trunc == 0) {
ret = ISO_OUT_OF_MEM;
goto ex;
}
ret = iso_truncate_rr_name(1, truncate_length, trunc, !(flag & 1));
if (ret < 0)
goto ex;
name = trunc;
}
/* check if the name is valid */
ret = iso_node_is_valid_name(name);
if (ret < 0)
return ret;
goto ex;
if (node->parent != NULL) {
/* check if parent already has a node with same name */
if (iso_dir_get_node(node->parent, name, NULL) == 1) {
return ISO_NODE_NAME_NOT_UNIQUE;
ret = ISO_NODE_NAME_NOT_UNIQUE;
goto ex;
}
}
new = strdup(name);
if (new == NULL) {
return ISO_OUT_OF_MEM;
ret = ISO_OUT_OF_MEM;
goto ex;
}
free(node->name);
node->name = new;
@ -364,10 +382,29 @@ int iso_node_set_name(IsoNode *node, const char *name)
iso_node_take(node);
res = iso_dir_add_node(parent, node, 0);
if (res < 0) {
return res;
ret = res;
goto ex;
}
}
return ISO_SUCCESS;
ret = ISO_SUCCESS;
ex:
if (trunc != NULL)
free(trunc);
return ret;
}
int iso_node_set_name(IsoNode *node, const char *name)
{
return iso_node_set_name_trunc(node, name, 0, 0);
}
int iso_image_set_node_name(IsoImage *image, IsoNode *node, const char *name,
int flag)
{
if (image->truncate_mode == 0)
if ((int) strlen(name) > image->truncate_length)
return ISO_RR_NAME_TOO_LONG;
return iso_node_set_name_trunc(node, name, image->truncate_length, flag);
}
/**
@ -377,6 +414,10 @@ int iso_node_set_name(IsoNode *node, const char *name)
*/
const char *iso_node_get_name(const IsoNode *node)
{
static char *root = {""};
if (node->name == NULL)
return root;
return node->name;
}
@ -610,6 +651,43 @@ int iso_dir_get_node(IsoDir *dir, const char *name, IsoNode **node)
return 1;
}
int iso_dir_get_node_trunc(IsoDir *dir, int truncate_length,
const char *name, IsoNode **node)
{
int ret;
char *trunc = NULL;
if ((int) strlen(name) <= truncate_length) {
ret = iso_dir_get_node(dir, name, node);
return ret;
}
trunc = strdup(name);
if (trunc == NULL)
return ISO_OUT_OF_MEM;
ret = iso_truncate_rr_name(1, truncate_length, trunc, 1);
if (ret < 0)
goto ex;
ret = iso_dir_get_node(dir, trunc, node);
if (ret == 0)
ret = 2;
ex:;
LIBISO_FREE_MEM(trunc);
return ret;
}
/* API */
int iso_image_dir_get_node(IsoImage *image, IsoDir *dir,
const char *name, IsoNode **node, int flag)
{
int ret;
if (image->truncate_mode == 0 || (flag & 1))
ret = iso_dir_get_node(dir, name, node);
else
ret = iso_dir_get_node_trunc(dir, image->truncate_length, name, node);
return ret;
}
/**
* Get the number of children of a directory.
*
@ -1117,16 +1195,17 @@ int iso_file_get_old_image_lba(IsoFile *file, uint32_t *lba, int flag)
{
int ret;
int section_count;
struct iso_file_section *sections;
struct iso_file_section *sections = NULL;
if (file == NULL || lba == NULL) {
return ISO_NULL_POINTER;
}
ret = iso_file_get_old_image_sections(file, &section_count, &sections, flag);
if (ret <= 0) {
ret = iso_file_get_old_image_sections(file, &section_count, &sections, 0);
if (ret <= 0)
return ret;
}
if (section_count != 1) {
free(sections);
if (sections != NULL)
free(sections);
return ISO_WRONG_ARG_VALUE;
}
*lba = sections[0].block;
@ -1135,7 +1214,6 @@ int iso_file_get_old_image_lba(IsoFile *file, uint32_t *lba, int flag)
}
/*
* Like iso_file_get_old_image_lba(), but take an IsoNode.
*
@ -1531,11 +1609,17 @@ int attrs_cleanout_name(char *del_name, size_t *num_attrs, char **names,
size_t i, w;
for (w = i = 0; i < *num_attrs; i++) {
if ((strcmp(names[i], del_name) == 0) ^ (flag & 1))
continue;
if ((strcmp(names[i], del_name) == 0) ^ (flag & 1)) {
if (names[i] != NULL)
free(names[i]);
if (values[i] != NULL)
free(values[i]);
names[i] = values[i] = NULL;
continue;
}
if (w == i) {
w++;
continue;
continue;
}
names[w] = names[i];
value_lengths[w] = value_lengths[i];
@ -1881,8 +1965,9 @@ int iso_node_set_attrs(IsoNode *node, size_t num_attrs, char **names,
size_t *value_lengths, char **values, int flag)
{
int ret, acl_saved = 0;
size_t sret, result_len, m_num = 0, *m_value_lengths = NULL, i;
unsigned char *result;
ssize_t sret;
size_t result_len, m_num = 0, *m_value_lengths = NULL, i;
unsigned char *result = NULL;
char *a_acl = NULL, *d_acl = NULL, **m_names = NULL, **m_values = NULL;
if (!(flag & 8))
@ -1921,28 +2006,34 @@ int iso_node_set_attrs(IsoNode *node, size_t num_attrs, char **names,
}
sret = aaip_encode(num_attrs, names, value_lengths, values,
&result_len, &result, 0);
if (sret == 0) {
ret = ISO_OUT_OF_MEM;
if (sret < 0) {
ret = sret;
goto ex;
}
ret = iso_node_remove_xinfo(node, aaip_xinfo_func);
if (ret < 0)
goto ex;
ret = iso_node_add_xinfo(node, aaip_xinfo_func, result);
if (ret < 0)
goto ex;
if (ret == 0) {
/* >>> something is messed up with xinfo: an aa_string still exists */;
ret = ISO_ERROR;
if (ret < 0) {
if (result != NULL)
free(result);
goto ex;
}
if (acl_saved) {
ret = iso_node_set_acl_text(node, a_acl, d_acl, 0);
if (sret > 0) {
ret = iso_node_add_xinfo(node, aaip_xinfo_func, result);
if (ret < 0)
goto ex;
if (ret == 0) {
/* >>> something is messed up with xinfo:
an aa_string still exists */;
ret = ISO_ERROR;
goto ex;
}
if (acl_saved) {
ret = iso_node_set_acl_text(node, a_acl, d_acl, 0);
if (ret < 0)
goto ex;
}
}
ret = 1;
ex:;
@ -2160,10 +2251,8 @@ int iso_node_set_acl_text(IsoNode *node, char *access_text, char *default_text,
ret = ISO_AAIP_BAD_ACL_TEXT;
goto ex;
}
ret = 1;
if (a_text != NULL || d_text != NULL)
ret = aaip_encode_both_acl(a_text, d_text, st_mode,
&acl_len, &acl, 2 | 8);
ret = aaip_encode_both_acl(a_text, d_text, st_mode,
&acl_len, &acl, 2 | 8);
} else {
ret = 1;
if (access_text != NULL || default_text != NULL)
@ -2868,6 +2957,50 @@ ex:;
}
int iso_root_set_isofsnt(IsoNode *node, uint32_t truncate_mode,
uint32_t truncate_length, int flag)
{
char buffer[5 + 5], *wpt = buffer, *valuept = buffer;
int result_len, ret;
static char *names = "isofs.nt";
static size_t value_lengths[1];
iso_util_encode_len_bytes(truncate_mode, wpt, 0, &result_len, 0);
wpt += result_len;
iso_util_encode_len_bytes(truncate_length, wpt, 0, &result_len, 0);
wpt += result_len;
value_lengths[0] = wpt - buffer;
ret = iso_node_set_attrs(node, (size_t) 1,
&names, value_lengths, &valuept, 2 | 8);
return ret;
}
int iso_root_get_isofsnt(IsoNode *node, uint32_t *truncate_mode,
uint32_t *truncate_length, int flag)
{
int ret, len;
size_t value_len;
char *value = NULL, *rpt;
ret = iso_node_lookup_attr(node, "isofs.nt", &value_len, &value, 0);
if (ret <= 0)
goto ex;
rpt = value;
iso_util_decode_len_bytes(truncate_mode, rpt, &len,
value_len - (rpt - value), 0);
rpt += len + 1;
iso_util_decode_len_bytes(truncate_length, rpt, &len,
value_len - (rpt - value), 0);
ret= ISO_SUCCESS;
ex:;
if (value != NULL)
free(value);
return ret;
}
/* API */
int iso_file_get_md5(IsoImage *image, IsoFile *file, char md5[16], int flag)
{
@ -2921,21 +3054,23 @@ int iso_file_make_md5(IsoFile *file, int flag)
if (file->from_old_session)
dig = 1;
md5= calloc(16, 1);
md5 = calloc(16, 1);
if (md5 == NULL)
return ISO_OUT_OF_MEM;
ret = iso_stream_make_md5(file->stream, md5, dig);
if (ret < 0)
goto ex;
if (ret < 0) {
free(md5);
return ret;
}
iso_node_remove_xinfo((IsoNode *) file, checksum_md5_xinfo_func);
ret = iso_node_add_xinfo((IsoNode *) file, checksum_md5_xinfo_func, md5);
if (ret == 0)
ret = ISO_ERROR; /* should not happen after iso_node_remove_xinfo() */
if (ret < 0) {
free(md5);
goto ex;
return ret;
}
ret = 1;
ex:;
return ret;
return 1;
}

View File

@ -512,6 +512,16 @@ int iso_root_get_isofsca(IsoNode *node, uint32_t *start_lba, uint32_t *end_lba,
int flag);
/**
* Record and get truncation parameters as of iso_image_set_truncate_mode() by
* "isofs.nt".
*/
int iso_root_set_isofsnt(IsoNode *node, uint32_t truncate_mode,
uint32_t truncate_length, int flag);
int iso_root_get_isofsnt(IsoNode *node, uint32_t *truncate_mode,
uint32_t *truncate_length, int flag);
/**
* Copy the xinfo list from one node to the another.
*/
@ -543,4 +553,10 @@ int zisofs_zf_xinfo_func(void *data, int flag);
int zisofs_zf_xinfo_cloner(void *old_data, void **new_data, int flag);
/* Performing search for possibly truncated node name.
*/
int iso_dir_get_node_trunc(IsoDir *dir, int truncate_length,
const char *name, IsoNode **node);
#endif /*LIBISO_NODE_H_*/

View File

@ -383,9 +383,7 @@ int iso_get_rr_name(IsoWriteOpts *opts, char *input_charset,
iso_msg_submit(imgid, ISO_FILENAME_WRONG_CHARSET, ret,
"Charset conversion error. Cannot convert %s from %s to %s",
str, input_charset, output_charset);
/* use the original name, it's the best we can do */
ret = iso_clone_mem(str, name, 0);
*name = NULL;
return ISO_FILENAME_WRONG_CHARSET;
}
@ -579,12 +577,15 @@ int rrip_add_SL(Ecma119Image *t, struct susp_info *susp, uint8_t **comp,
* debug purposes
*/
if (ce == 0) {
free(SL);
return ISO_ASSERT_FAILURE;
}
ret = susp_append_ce(t, susp, SL);
if (ret < 0) {
free(SL);
return ret;
}
SL = NULL; /* now owned by susp */
written = i;
total_comp_len = comp[i][1] + 2;
}
@ -1179,9 +1180,12 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
}
}
namelen = 0;
name = get_rr_fname(t, n->node->name);
namelen = strlen(name);
free(name);
if (name != NULL) {
namelen = strlen(name);
free(name);
}
if (flag & 1) {
/* Account for 28 bytes of CE field */
@ -1741,9 +1745,15 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
uint8_t **comps= NULL; /* components of the SL field */
size_t n_comp = 0; /* number of components */
namelen = 0;
name = get_rr_fname(t, n->node->name);
if (name == NULL)
name = strdup("");
if (name == NULL) {
ret = ISO_OUT_OF_MEM;
goto add_susp_cleanup;
}
namelen = strlen(name);
sua_free = space - info->suf_len;
/* Try whether NM, SL, AL will fit into SUA */
@ -1787,6 +1797,13 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
int cew = (nm_type == 1); /* are we writing to CE? */
dest = get_rr_fname(t, ((IsoSymlink*)n->node)->dest);
if (dest == NULL)
dest = strdup("");
if (dest == NULL) {
ret = ISO_OUT_OF_MEM;
goto add_susp_cleanup;
}
prev = dest;
cur = strchr(prev, '/');
while (1) {
@ -2122,8 +2139,10 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
return ISO_SUCCESS;
add_susp_cleanup: ;
free(name);
free(dest);
if (name != NULL)
free(name);
if (dest != NULL)
free(dest);
susp_info_free(info);
return ret;
}

View File

@ -361,8 +361,7 @@ int read_zisofs_ZF(struct susp_sys_user_entry *zf, uint8_t algorithm[2],
uint32_t *uncompressed_size, int flag);
/**
* Convert a RR filename to the requested charset. On any conversion error,
* the original name will be used.
* Convert a RR filename to the requested charset.
* @param flag bit0= do not issue error messages
*/
int iso_get_rr_name(IsoWriteOpts *opts, char *input_charset,

View File

@ -211,10 +211,19 @@ int read_rr_TF(struct susp_sys_user_entry *tf, struct stat *st)
/* 1. Creation time */
if (tf->data.TF.flags[0] & (1 << 0)) {
/* the creation is the recording time. we ignore this */
/* TODO maybe it would be good to manage it in ms discs, where
* the recording time could be different than now!! */
/* Linux accepts ctime by Creation time and by Attributes time.
* If both are given, then Attribute time will win.
*/
if (tf->len_sue[0] < 5 + (nts+1) * s) {
/* RR TF entry too short. */
return ISO_WRONG_RR;
}
if (s == 7) {
time = iso_datetime_read_7(&tf->data.TF.t_stamps[nts*7]);
} else {
time = iso_datetime_read_17(&tf->data.TF.t_stamps[nts*17]);
}
st->st_ctime = time;
++nts;
}
@ -412,7 +421,7 @@ int read_rr_PN(struct susp_sys_user_entry *pn, struct stat *st)
{
int high_shift= 0;
if (pn == NULL || pn == NULL) {
if (pn == NULL || st == NULL) {
return ISO_NULL_POINTER;
}
if (pn->sig[0] != 'P' || pn->sig[1] != 'N') {

View File

@ -164,15 +164,6 @@ 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)
{
@ -227,7 +218,7 @@ IsoStreamIface fsrc_stream_class = {
fsrc_free,
fsrc_update_size,
fsrc_get_input_stream,
fsrc_cmp_ino,
NULL,
fsrc_clone_stream
};
@ -448,15 +439,6 @@ 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)
@ -517,7 +499,7 @@ IsoStreamIface cut_out_stream_class = {
cut_out_free,
cut_out_update_size,
cut_out_get_input_stream,
cut_out_cmp_ino,
NULL,
cut_out_clone_stream
};
@ -698,15 +680,6 @@ 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)
@ -763,7 +736,7 @@ IsoStreamIface mem_stream_class = {
mem_free,
mem_update_size,
mem_get_input_stream,
mem_cmp_ino,
NULL,
mem_clone_stream
};
@ -972,18 +945,99 @@ int iso_stream_cmp_ifs_sections(IsoStream *s1, IsoStream *s2, int *cmp_ret,
{
int ret;
FSrcStreamData *fssd1, *fssd2;
IsoFileSource *src1, *src2;
if (s1->class != &fsrc_stream_class || s2->class != &fsrc_stream_class)
/* Must keep any suspect in the game to preserve transitivity of the
calling function by ranking applicable streams lower than
non-applicable. ones.
*/
if (s1->class != &fsrc_stream_class && s2->class != &fsrc_stream_class)
return 0;
/* Compare eventual image data section LBA and sizes */
fssd1= (FSrcStreamData *) s1->data;
fssd2= (FSrcStreamData *) s2->data;
ret = iso_ifs_sections_cmp(fssd1->src, fssd2->src, cmp_ret, 0);
if (s1->class == &fsrc_stream_class) {
fssd1= (FSrcStreamData *) s1->data;
src1 = fssd1->src;
} else {
src1 = NULL;
}
if (s2->class == &fsrc_stream_class) {
fssd2= (FSrcStreamData *) s2->data;
src2 = fssd2->src;
} else {
src2 = NULL;
}
ret = iso_ifs_sections_cmp(src1, src2, cmp_ret, 1);
if (ret <= 0)
return 0;
return 1;
}
/* Maintain and exploit a list of stream compare functions seen by
iso_stream_cmp_ino(). This is needed to separate stream comparison
families in order to keep iso_stream_cmp_ino() transitive while
alternative stream->class->cmp_ino() decide inside the families.
*/
struct iso_streamcmprank {
int (*cmp_func)(IsoStream *s1, IsoStream *s2);
struct iso_streamcmprank *next;
};
static struct iso_streamcmprank *streamcmpranks = NULL;
static
int iso_get_streamcmprank(int (*cmp_func)(IsoStream *s1, IsoStream *s2),
int flag)
{
int idx;
struct iso_streamcmprank *cpr, *last_cpr = NULL;
idx = 0;
for (cpr = streamcmpranks; cpr != NULL; cpr = cpr->next) {
if (cpr->cmp_func == cmp_func)
break;
idx++;
last_cpr = cpr;
}
if (cpr != NULL)
return idx;
LIBISO_ALLOC_MEM_VOID(cpr, struct iso_streamcmprank, 1);
cpr->cmp_func = cmp_func;
cpr->next = NULL;
if (last_cpr != NULL)
last_cpr->next = cpr;
if (streamcmpranks == NULL)
streamcmpranks = cpr;
return idx;
ex:;
return -1;
}
static
int iso_cmp_streamcmpranks(int (*cf1)(IsoStream *s1, IsoStream *s2),
int (*cf2)(IsoStream *s1, IsoStream *s2))
{
int rank1, rank2;
rank1 = iso_get_streamcmprank(cf1, 0);
rank2 = iso_get_streamcmprank(cf2, 0);
return rank1 < rank2 ? -1 : 1;
}
int iso_stream_destroy_cmpranks(int flag)
{
struct iso_streamcmprank *cpr, *next;
for (cpr = streamcmpranks; cpr != NULL; cpr = next) {
next = cpr->next;
LIBISO_FREE_MEM(cpr);
}
streamcmpranks = NULL;
return ISO_SUCCESS;
}
/* API */
int iso_stream_cmp_ino(IsoStream *s1, IsoStream *s2, int flag)
{
@ -1008,13 +1062,72 @@ int iso_stream_cmp_ino(IsoStream *s1, IsoStream *s2, int flag)
if (s2 == NULL)
return 1;
/* This stays transitive by the fact that
iso_stream_cmp_ifs_sections() is transitive,
returns > 0 if s1 or s2 are applicable,
ret is -1 if s1 is applicable but s2 is not,
ret is 1 if s1 is not applicable but s2 is.
Proof:
Be A the set of applicable streams, S and G transitive and
antisymmetric relations in respect to outcome {-1, 0, 1}.
The combined relation R shall be defined by
I. R(a,b) = S(a,b) if a in A or b in A, else G(a,b)
Further S shall have the property
II. S(a,b) = -1 if a in A and b not in A
Then R can be proven to be transitive:
By enumerating the 8 combinations of a,b,c being in A or not, we get
5 cases of pure S or pure G. Three cases are mixed:
a,b not in A, c in A : G(a,b) == -1, S(b,c) == -1 -> S(a,c) == -1
Impossible because S(b,c) == -1 contradicts II.
a,c not in A, b in A : S(a,b) == -1, S(b,c) == -1 -> G(a,c) == -1
Impossible because S(a,b) == -1 contradicts II.
b,c not in A, a in A : S(a,b) == -1, G(b,c) == -1 -> S(a,c) == -1
Always true because S(a,c) == -1 by definition II.
*/
if (iso_stream_cmp_ifs_sections(s1, s2, &ret, 0) > 0)
return ret; /* Both are unfiltered from loaded ISO filesystem */
if (s1->class->version >= 3 && !(flag & 1)) {
/* Filters may have smarter methods to compare themselves with others */
ret = s1->class->cmp_ino(s1, s2);
return ret;
if (!(flag & 1)) {
/* Filters may have smarter methods to compare themselves with others.
Transitivity is ensured by ranking mixed pairs by the rank of their
comparison functions, and by ranking streams with .cmp_ino lower
than streams without.
(One could merge (class->version < 3) and (cmp_ino == NULL).)
Here we define S for "and" rather than "or"
I. R(a,b) = S(a,b) if a in A and b in A, else G(a,b)
and the function ranking in case of "exor" makes sure that
II. G(a,b) = -1 if a in A and b not in A
Again we get three mixed cases:
a not in A, b,c in A : G(a,b) == -1, S(b,c) == -1 -> G(a,c) == -1
Impossible because G(a,b) == -1 contradicts II.
b not in A, a,c in A : G(a,b) == -1, G(b,c) == -1 -> S(a,c) == -1
Impossible because G(b,c) == -1 contradicts II.
c not in A, a,b in A : S(a,b) == -1, G(b,c) == -1 -> G(a,c) == -1
Always true because G(a,c) == -1 by definition II.
*/
if ((s1->class->version >= 3) ^ (s2->class->version >= 3)) {
/* One of both has no own com_ino function. Rank it as larger. */
return s1->class->version >= 3 ? -1 : 1;
} else if (s1->class->version >= 3) {
if (s1->class->cmp_ino == s2->class->cmp_ino) {
if (s1->class->cmp_ino == NULL) {
/* Both are NULL. No decision by .cmp_ino(). */;
} else {
/* Both are compared by the same function */
ret = s1->class->cmp_ino(s1, s2);
return ret;
}
} else {
/* Not the same cmp_ino() function. Decide by list rank of
function while building the list on the fly.
*/
ret = iso_cmp_streamcmpranks(s1->class->cmp_ino,
s2->class->cmp_ino);
return ret;
}
}
}
iso_stream_get_id(s1, &fs_id1, &dev_id1, &ino_id1);

View File

@ -112,4 +112,13 @@ int iso_stream_clone_filter_common(IsoStream *old_stream,
IsoStream **new_stream,
IsoStream **new_input, int flag);
/**
* Dispose the internal list of stream class cmp_ino() functions. It is
* a static global of stream.c, created and used by iso_stream_cmp_ino().
* This function is supposed to be called by iso_finish() only.
*/
int iso_stream_destroy_cmpranks(int flag);
#endif /*STREAM_H_*/

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2011 - 2014 Thomas Schmitt
* Copyright (c) 2011 - 2015 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -100,6 +100,19 @@ int iso_tree_add_new_dir(IsoDir *parent, const char *name, IsoDir **dir)
return iso_dir_insert(parent, (IsoNode*)node, pos, ISO_REPLACE_NEVER);
}
int iso_image_add_new_dir(IsoImage *image, IsoDir *parent, const char *name,
IsoDir **dir)
{
int ret;
char *namept;
ret = iso_image_truncate_name(image, name, &namept, 0);
if (ret < 0)
return ret;
ret = iso_tree_add_new_dir(parent, namept, dir);
return ret;
}
/**
* Add a new symlink to the directory tree. Permissions are set to 0777,
* owner and hidden atts are taken from parent. You can modify any of them
@ -175,6 +188,20 @@ int iso_tree_add_new_symlink(IsoDir *parent, const char *name,
return iso_dir_insert(parent, (IsoNode*)node, pos, ISO_REPLACE_NEVER);
}
int iso_image_add_new_symlink(IsoImage *image, IsoDir *parent,
const char *name, const char *dest,
IsoSymlink **link)
{
int ret;
char *namept;
ret = iso_image_truncate_name(image, name, &namept, 0);
if (ret < 0)
return ret;
ret = iso_tree_add_new_symlink(parent, namept, dest, link);
return ret;
}
/**
* Add a new special file to the directory tree. As far as libisofs concerns,
* an special file is a block device, a character device, a FIFO (named pipe)
@ -264,6 +291,20 @@ int iso_tree_add_new_special(IsoDir *parent, const char *name, mode_t mode,
return iso_dir_insert(parent, (IsoNode*)node, pos, ISO_REPLACE_NEVER);
}
int iso_image_add_new_special(IsoImage *image, IsoDir *parent,
const char *name, mode_t mode,
dev_t dev, IsoSpecial **special)
{
int ret;
char *namept;
ret = iso_image_truncate_name(image, name, &namept, 0);
if (ret < 0)
return ret;
ret = iso_tree_add_new_special(parent, namept, mode, dev, special);
return ret;
}
/**
* Add a new regular file to the iso tree. Permissions are set to 0444,
* owner and hidden atts are taken from parent. You can modify any of them
@ -339,6 +380,19 @@ int iso_tree_add_new_file(IsoDir *parent, const char *name, IsoStream *stream,
return iso_dir_insert(parent, (IsoNode*)node, pos, ISO_REPLACE_NEVER);
}
int iso_image_add_new_file(IsoImage *image, IsoDir *parent, const char *name,
IsoStream *stream, IsoFile **file)
{
int ret;
char *namept;
ret = iso_image_truncate_name(image, name, &namept, 0);
if (ret < 0)
return ret;
ret = iso_tree_add_new_file(parent, namept, stream, file);
return ret;
}
/**
* Set whether to follow or not symbolic links when added a file from a source
* to IsoImage.
@ -503,7 +557,7 @@ int iso_tree_add_node_builder(IsoImage *image, IsoDir *parent,
int result;
IsoNode *new;
IsoNode **pos;
char *name = NULL;
char *name = NULL, *namept;
if (parent == NULL || src == NULL || builder == NULL) {
result = ISO_NULL_POINTER; goto ex;
@ -514,14 +568,18 @@ int iso_tree_add_node_builder(IsoImage *image, IsoDir *parent,
name = iso_file_source_get_name(src);
result = iso_image_truncate_name(image, name, &namept, 0);
if (result < 0)
return result;
/* find place where to insert */
result = iso_dir_exists(parent, name, &pos);
result = iso_dir_exists(parent, namept, &pos);
if (result) {
/* a node with same name already exists */
result = ISO_NODE_NAME_NOT_UNIQUE; goto ex;
}
result = builder->create_node(builder, image, src, name, &new);
result = builder->create_node(builder, image, src, namept, &new);
if (result < 0)
goto ex;
@ -568,6 +626,7 @@ int iso_tree_add_new_node(IsoImage *image, IsoDir *parent, const char *name,
IsoFileSource *file;
IsoNode *new;
IsoNode **pos;
char *namept;
if (image == NULL || parent == NULL || name == NULL || path == NULL) {
return ISO_NULL_POINTER;
@ -577,8 +636,12 @@ int iso_tree_add_new_node(IsoImage *image, IsoDir *parent, const char *name,
*node = NULL;
}
result = iso_image_truncate_name(image, name, &namept, 0);
if (result < 0)
return result;
/* find place where to insert */
result = iso_dir_exists(parent, name, &pos);
result = iso_dir_exists(parent, namept, &pos);
if (result) {
/* a node with same name already exists */
return ISO_NODE_NAME_NOT_UNIQUE;
@ -591,7 +654,7 @@ int iso_tree_add_new_node(IsoImage *image, IsoDir *parent, const char *name,
}
result = image->builder->create_node(image->builder, image, file,
(char *) name, &new);
namept, &new);
/* free the file */
iso_file_source_unref(file);
@ -620,6 +683,7 @@ int iso_tree_add_new_cut_out_node(IsoImage *image, IsoDir *parent,
IsoFile *new;
IsoNode **pos;
IsoStream *stream;
char *namept;
if (image == NULL || parent == NULL || name == NULL || path == NULL) {
return ISO_NULL_POINTER;
@ -629,8 +693,12 @@ int iso_tree_add_new_cut_out_node(IsoImage *image, IsoDir *parent,
*node = NULL;
}
result = iso_image_truncate_name(image, name, &namept, 0);
if (result < 0)
return result;
/* find place where to insert */
result = iso_dir_exists(parent, name, &pos);
result = iso_dir_exists(parent, namept, &pos);
if (result) {
/* a node with same name already exists */
return ISO_NODE_NAME_NOT_UNIQUE;
@ -673,7 +741,7 @@ int iso_tree_add_new_cut_out_node(IsoImage *image, IsoDir *parent,
iso_stream_unref(new->stream);
new->stream = stream;
result = iso_node_set_name((IsoNode*)new, name);
result = iso_node_set_name((IsoNode*)new, namept);
if (result < 0) {
iso_node_unref((IsoNode*)new);
return result;
@ -1106,7 +1174,10 @@ int iso_tree_add_dir_rec(IsoImage *image, IsoDir *parent, const char *dir)
return result;
}
int iso_tree_path_to_node(IsoImage *image, const char *path, IsoNode **node)
/* @param flag bit0= truncate according to image truncate mode and length
*/
int iso_tree_path_to_node_flag(IsoImage *image, const char *path,
IsoNode **node, int flag)
{
int result;
IsoNode *n;
@ -1128,6 +1199,8 @@ int iso_tree_path_to_node(IsoImage *image, const char *path, IsoNode **node)
}
ptr = strdup(path);
if (ptr == NULL)
return ISO_OUT_OF_MEM;
result = 0;
/* get the first component of the path */
@ -1140,7 +1213,12 @@ int iso_tree_path_to_node(IsoImage *image, const char *path, IsoNode **node)
}
dir = (IsoDir *)n;
result = iso_dir_get_node(dir, component, &n);
if ((flag & 1) && image->truncate_mode == 1) {
result = iso_dir_get_node_trunc(dir, image->truncate_length,
component, &n);
} else {
result = iso_dir_get_node(dir, component, &n);
}
if (result != 1) {
n = NULL;
break;
@ -1156,6 +1234,16 @@ int iso_tree_path_to_node(IsoImage *image, const char *path, IsoNode **node)
return result;
}
int iso_tree_path_to_node(IsoImage *image, const char *path, IsoNode **node)
{
return iso_tree_path_to_node_flag(image, path, node, 0);
}
int iso_image_path_to_node(IsoImage *image, const char *path, IsoNode **node)
{
return iso_tree_path_to_node_flag(image, path, node, 1);
}
char *iso_tree_get_node_path(IsoNode *node)
{
char *path = NULL, *parent_path = NULL;
@ -1397,18 +1485,36 @@ int iso_tree_clone_special(IsoSpecial *node,
return ISO_SUCCESS;
}
/* API */
int iso_tree_clone(IsoNode *node,
IsoDir *new_parent, char *new_name, IsoNode **new_node,
int flag)
/* @param flag bit0= Merge directories rather than ISO_NODE_NAME_NOT_UNIQUE.
bit1= issue warning in case of truncation
*/
int iso_tree_clone_trunc(IsoNode *node, IsoDir *new_parent,
char *new_name_in, IsoNode **new_node,
int truncate_length, int flag)
{
int ret = ISO_SUCCESS;
char *new_name, *trunc = NULL;
*new_node = NULL;
new_name = new_name_in;
if (truncate_length >= 64 && (int) strlen(new_name) > truncate_length) {
trunc = strdup(new_name);
if (trunc == 0) {
ret = ISO_OUT_OF_MEM;
goto ex;
}
ret = iso_truncate_rr_name(1, truncate_length, trunc, !(flag & 2));
if (ret < 0)
goto ex;
new_name = trunc;
}
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;
ret = ISO_NODE_NAME_NOT_UNIQUE;
goto ex;
}
} else
flag &= ~1;
@ -1429,10 +1535,42 @@ int iso_tree_clone(IsoNode *node,
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 */
goto ex;
if (flag & 1) {
ret = 2; /* merged two directories, *new_node is not new */
goto ex;
}
ret = iso_tree_copy_node_attr(node, *new_node, 0);
ex:;
if (trunc != NULL)
free(trunc);
return ret;
}
/* API */
int iso_tree_clone(IsoNode *node,
IsoDir *new_parent, char *new_name, IsoNode **new_node,
int flag)
{
return iso_tree_clone_trunc(node, new_parent, new_name, new_node, 0,
flag & 1);
}
/* API */
int iso_image_tree_clone(IsoImage *image, IsoNode *node, IsoDir *new_parent,
char *new_name, IsoNode **new_node, int flag)
{
int length, ret;
if (image->truncate_mode == 0)
length = 0;
else
length = image->truncate_length;
ret = iso_tree_clone_trunc(node, new_parent, new_name, new_node, length,
flag & 3);
return ret;
}

View File

@ -1,7 +1,7 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2007 Mario Danic
* Copyright (c) 2009 - 2012 Thomas Schmitt
* Copyright (c) 2009 - 2015 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -17,6 +17,7 @@
#include "libisofs.h"
#include "messages.h"
#include "joliet.h"
#include "node.h"
#include "../version.h"
#include <stdlib.h>
@ -435,6 +436,7 @@ int str2ascii(const char *icharset, const char *input, char **output)
ret_ = malloc(numchars + 1);
if (ret_ == NULL) {
free(wsrc_);
return ISO_OUT_OF_MEM;
}
outbytes = numchars;
@ -444,7 +446,9 @@ int str2ascii(const char *icharset, const char *input, char **output)
conv_ret = iso_iconv_open(&conv, "ASCII", "WCHAR_T", 0);
if (conv_ret <= 0) {
free(wsrc_);
wsrc_ = NULL;
free(ret_);
ret = ret_ = NULL;
}
} else if (result != (int) ISO_CHARSET_CONV_ERROR)
return result;
@ -593,8 +597,10 @@ int str2ucs(const char *icharset, const char *input, uint16_t **output)
loop_limit = inbytes + 3;
ret_ = malloc((numchars+1) * sizeof(uint16_t));
if (ret_ == NULL)
if (ret_ == NULL) {
free(wsrc_);
return ISO_OUT_OF_MEM;
}
outbytes = numchars * sizeof(uint16_t);
ret = ret_;
@ -602,7 +608,9 @@ int str2ucs(const char *icharset, const char *input, uint16_t **output)
conv_ret = iso_iconv_open(&conv, "UCS-2BE", "WCHAR_T", 0);
if (conv_ret <= 0) {
free(wsrc_);
wsrc_ = NULL;
free(ret_);
ret = ret_ = NULL;
}
} else if (result != (int) ISO_CHARSET_CONV_ERROR)
return result;
@ -723,8 +731,10 @@ int str2utf16be(const char *icharset, const char *input, uint16_t **output)
loop_limit = inbytes + 3;
ret_ = malloc((2 * numchars+1) * sizeof(uint16_t));
if (ret_ == NULL)
if (ret_ == NULL) {
free(wsrc_);
return ISO_OUT_OF_MEM;
}
outbytes = 2 * numchars * sizeof(uint16_t);
ret = ret_;
@ -1794,6 +1804,7 @@ time_t iso_datetime_read_7(const uint8_t *buf)
tm.tm_hour = buf[3];
tm.tm_min = buf[4];
tm.tm_sec = buf[5];
tm.tm_isdst = 0;
return timegm(&tm) - ((int8_t)buf[6]) * 60 * 15;
}
@ -1810,6 +1821,7 @@ time_t iso_datetime_read_17(const uint8_t *buf)
sscanf((char*)&buf[12], "%2d", &tm.tm_sec);
tm.tm_year -= 1900;
tm.tm_mon -= 1;
tm.tm_isdst = 0;
return timegm(&tm) - ((int8_t)buf[6]) * 60 * 15;
}
@ -2226,6 +2238,7 @@ unexpected_type:;
goto ex;
} else if (range_start != ctx_start_lba) {
ret = ISO_MD5_TAG_MISPLACED;
goto ex;
}
ret = iso_md5_clone(ctx, &cloned_ctx);
if (ret < 0)
@ -2294,7 +2307,7 @@ int iso_clone_mem(char *in, char **out, size_t size)
if (*out == NULL)
return ISO_OUT_OF_MEM;
memcpy(*out, in, size);
return 1;
return ISO_SUCCESS;
}
@ -2343,3 +2356,95 @@ off_t iso_scanf_io_size(char *text, int flag)
ret += fac - 1;
return ret;
}
/* Find backward from idx the start byte of a possible UTF-8 character.
https://en.wikipedia.org/wiki/UTF-8#Description
*/
static
int find_utf8_start(char *name, int idx, int flag)
{
unsigned char *uname, uch;
int i;
uname= (unsigned char *) name;
if ((uname[idx] & 0xc0) != 0x80)
return idx; /* not an UTF-8 tail byte */
for (i = 0; i < 5 && idx - 1 - i >= 0; i++) { /* up to deprecated 6-byte codes */
uch = uname[idx - 1 - i];
if ((uch & 0xe0) == 0xc0 || (uch & 0xf0) == 0xe0 ||
(uch & 0xf8) == 0xf0 || (uch & 0xfc) == 0xf8 ||
(uch & 0xfe) == 0xfc)
return (idx - 1 - i); /* UTF-8 start byte found */
if ((uch & 0xc0) != 0x80)
return idx; /* not an UTF-8 tail byte, so no UTF-8 */
}
return idx; /* no UTF-8 start found */
}
/* @param flag bit0= do not issue warning message
*/
int iso_truncate_rr_name(int truncate_mode, int truncate_length,
char *name, int flag)
{
int neck, goal, ret, l, i;
static int hash_size = 32;
void *ctx = NULL;
char hashval[16];
l = strlen(name);
if (l <= truncate_length)
return ISO_SUCCESS;
if (truncate_mode == 0)
return ISO_RR_NAME_TOO_LONG;
/* Compute hash */
ret = iso_md5_start(&ctx);
if (ret < 0)
goto ex;
ret = iso_md5_compute(ctx, name, l > 4095 ? 4095 : l);
if (ret < 0)
goto ex;
ret = iso_md5_end(&ctx, hashval);
if (ret < 0)
goto ex;
if (!(flag & 1))
iso_msg_submit(-1, ISO_RR_NAME_TRUNCATED, 0,
"File name had to be truncated and MD5 marked: %s", name);
/* Avoid to produce incomplete UTF-8 characters */
goal = truncate_length - hash_size - 1;
neck = find_utf8_start(name, goal, 0);
for (; neck < goal; neck++)
name[neck] = '_';
/* Write colon and hash text over end of truncated name */
name[goal] = ':';
goal++;
for (i = 0; goal < truncate_length - 1 && i < hash_size / 2; goal += 2) {
sprintf(name + goal, "%2.2x", *((unsigned char *) (hashval + i)));
i++;
}
name[truncate_length] = 0;
ret = ISO_SUCCESS;
ex:;
if (ctx != NULL)
iso_md5_end(&ctx, hashval);
return ret;
}
/* API */
int iso_truncate_leaf_name(int mode, int length, char *name, int flag)
{
int ret;
if (mode < 0 || mode > 1)
return ISO_WRONG_ARG_VALUE;
if (length < 64 || length > LIBISOFS_NODE_NAME_MAX)
return ISO_WRONG_ARG_VALUE;
ret = iso_truncate_rr_name(mode, length, name, 1);
return ret;
}

View File

@ -407,6 +407,12 @@ size_t iso_rbtree_get_size(IsoRBTree *tree);
void **iso_rbtree_to_array(IsoRBTree *tree, int (*include_item)(void *),
size_t *size);
/** Predict the size of the array which gets returned by iso_rbtree_to_array().
*/
size_t iso_rbtree_count_array(IsoRBTree *tree, size_t initial_count,
int (*include_item)(void *));
/**
* Create a new hash table.
*
@ -558,6 +564,8 @@ int iso_util_bin_to_hex(char *target, uint8_t *bytes, int num_bytes, int flag);
int iso_util_hex_to_bin(char *hex, char *bin, int bin_size, int *bin_count,
int flag);
int iso_truncate_rr_name(int truncate_mode, int truncate_length,
char *name, int flag);
/* ------------------------------------------------------------------------- */

View File

@ -308,3 +308,38 @@ void ** iso_rbtree_to_array(IsoRBTree *tree, int (*include_item)(void *),
return array;
}
static
size_t rbtree_count_array_aux(struct iso_rbnode *root, size_t pos,
int (*include_item)(void *))
{
if (root == NULL) {
return pos;
}
pos = rbtree_count_array_aux(root->ch[0], pos, include_item);
if (include_item == NULL || include_item(root->data)) {
/*
{
IsoFileSrc* src = (IsoFileSrc*) root->data;
fprintf(stderr, "libisofs_DEBUG: rbtree_count_array_aux : not taken : '%s'\n",
iso_stream_get_source_path(src->stream, 0));
}
*/
pos++;
}
pos = rbtree_count_array_aux(root->ch[1], pos, include_item);
return pos;
}
size_t iso_rbtree_count_array(IsoRBTree *tree, size_t initial_count,
int (*include_item)(void *))
{
size_t pos;
pos = rbtree_count_array_aux(tree->root, initial_count, include_item);
return pos;
}