Compare commits
82 Commits
release-1.
...
release-1.
Author | SHA1 | Date | |
---|---|---|---|
089982022c | |||
a6316ff05c | |||
02a972a2d7 | |||
da8ad0d2aa | |||
79e6312397 | |||
b3a183fceb | |||
355f1f7ea2 | |||
57fd669d1d | |||
6047464b6b | |||
e8b94e7b50 | |||
49dd9dc993 | |||
93e1fc52d0 | |||
4838cd59a7 | |||
d51b1738dd | |||
6252ae2065 | |||
cb1e56478a | |||
05d0ee4a37 | |||
c6aedc9eb5 | |||
505bf23aa4 | |||
ccef2f29da | |||
b904926443 | |||
7bdc4c96f5 | |||
fa5e27458a | |||
7c29a94ab6 | |||
a4c1e04820 | |||
50132d4ff7 | |||
4c1c1ea152 | |||
a16d4a28f4 | |||
4633ea3bc8 | |||
430c005666 | |||
af55722830 | |||
d1da5718c7 | |||
afb2878773 | |||
4e7432c20f | |||
7ef616f268 | |||
d5f1eb9c65 | |||
28b41bce2c | |||
5ac3216933 | |||
05a2171e04 | |||
188a41f041 | |||
fbe7f1e89d | |||
d04abdcfbd | |||
a6542e5fa9 | |||
78d2c02ad8 | |||
48453ef1da | |||
7928c4ec3f | |||
379e223a5c | |||
e4750907e3 | |||
8f76b59541 | |||
0433b7ea75 | |||
d8fb8b26a6 | |||
b9ccdeda72 | |||
d04f438ba1 | |||
e35cb88328 | |||
83fb614462 | |||
e5f6811795 | |||
f3b836194c | |||
3a870d23e3 | |||
06ea46c8d5 | |||
d427a03192 | |||
2b6071b445 | |||
fc448e09c9 | |||
7b7da47d86 | |||
01c7a0d5ec | |||
905f4f898f | |||
b9ec876c40 | |||
72ef369a40 | |||
218e26c974 | |||
395128ef5f | |||
7a3560035a | |||
7ac5b75748 | |||
6c3dc3ce4a | |||
bdbaf81e9c | |||
c8ed18695f | |||
d3fefe4735 | |||
6db3f6ca44 | |||
bf19f73ea6 | |||
6947bfe5ec | |||
94f8503b57 | |||
cb519e221e | |||
d09a317f51 | |||
2beb0d001b |
@ -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
|
||||
|
24
ChangeLog
24
ChangeLog
@ -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
4
README
@ -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
|
||||
|
12
configure.ac
12
configure.ac
@ -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`
|
||||
|
||||
|
299
demo/demo.c
299
demo/demo.c
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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.)
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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 |
|
||||
|
@ -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.
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 ------ */
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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, '.');
|
||||
|
@ -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);
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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)
|
||||
§ions, 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, §ion_count,
|
||||
§ions, 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, §ion_count,
|
||||
§ions, 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, §ion_count,
|
||||
§ions, 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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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_*/
|
||||
|
@ -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;
|
||||
|
@ -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),
|
||||
|
225
libisofs/node.c
225
libisofs/node.c
@ -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, §ion_count, §ions, flag);
|
||||
if (ret <= 0) {
|
||||
ret = iso_file_get_old_image_sections(file, §ion_count, §ions, 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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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_*/
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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') {
|
||||
|
@ -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);
|
||||
|
@ -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_*/
|
||||
|
174
libisofs/tree.c
174
libisofs/tree.c
@ -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;
|
||||
}
|
||||
|
||||
|
113
libisofs/util.c
113
libisofs/util.c
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user