Compare commits

...

48 Commits

Author SHA1 Message Date
8a752b50fa Version leap to 1.0.6 2011-04-08 19:47:18 +02:00
c38b1a3a3a Updated changelog 2011-04-08 19:00:33 +02:00
73c9c7f244 Removed inactive debugging code 2011-04-08 18:56:08 +02:00
0b9f03bb23 Fixed a typo in comments 2011-04-05 09:20:25 +02:00
d1c3a017e3 Cleaned up use of PATH_MAX (local filesystem) and LIBISOFS_NODE_PATH_MAX
(ISO filesystem).
2011-04-03 11:02:15 +02:00
b200feceed Requiring libjte version 1.0.0 (if libjte is to be linked at all). 2011-04-02 16:30:23 +02:00
7958b2ea22 Mentioned configure option to disable libjte 2011-03-31 18:26:23 +02:00
c0bdf4d3b5 Reacted on warning about theoretical memory leak. 2011-03-28 20:43:13 +02:00
71efc996e3 New error code ISO_RR_PATH_TOO_LONG. 2011-03-28 15:00:44 +02:00
61383dea2d New error codes ISO_RR_NAME_TOO_LONG and ISO_RR_NAME_RESERVED for
occasions which previously returned ISO_WRONG_ARG_VALUE.
2011-03-26 20:54:20 +01:00
270cd1cad5 Closed a memory leak found by valgrind. 2011-03-26 19:23:51 +01:00
559e9b564d New API call iso_write_opts_set_joliet_long_names() 2011-03-26 15:38:08 +01:00
d8a56f60ef Interpreting the return values of fwrite() in demo/demo.c 2011-03-11 09:09:39 +01:00
10e3b2939a Updated copyright year 2011-03-10 20:03:35 +01:00
ba67523278 Version leap to 1.0.5 2011-03-10 13:43:13 +01:00
f09964cf51 Version leap to 1.0.4 2011-03-10 09:22:57 +01:00
e4a70a823d Updated changelog 2011-03-10 08:36:03 +01:00
655d86b97a Bug fix: Compilation failed if --disable-zlib was configured 2011-03-09 21:24:47 +01:00
f2f780115b New no_md5 value 2 for API call iso_read_opts_set_no_md5() 2011-03-08 19:37:52 +01:00
b6be8457f7 Fixed a memory hog introduced with rev 775. 2011-03-07 11:11:58 +01:00
1238c19494 Changed message about cylinder alignment. 2011-03-04 15:14:11 +01:00
2caf527f67 Refusign cylinder alignment if it is impossible to do it exactly. 2011-03-04 11:24:36 +01:00
43eae7502b New option bits 8 and 9 with iso_write_opts_set_system_area(). 2011-03-03 19:14:40 +01:00
e035146e01 Bug fix: isohybrid image size was not aligned to cylinder boundary.
Now the cylinder size gets adjusted if the image does not fit into 1024 cyl.
2011-03-01 18:31:59 +01:00
de3e21629f Corrected little flaws detected by George Danchev with cpp. 2011-02-24 20:02:56 +01:00
d79a3fcec4 Incresed mismatch test severity to FATAL again. 2011-02-23 20:16:59 +01:00
de079cec42 Version leap to 1.0.3 2011-02-23 20:14:10 +01:00
b33d06eb0c Version leap to 1.0.2 2011-02-23 13:01:56 +01:00
dfdaa2902a Reduced size mismtach test severity to WARNING.
This shall avoid the risk of false positives as long as the test is new.
2011-02-23 12:11:57 +01:00
0173c51c23 Updated change log. 2011-02-22 20:54:39 +01:00
a118127e9c Re-enabled use of system provide function timegm(), if available. 2011-02-21 13:46:46 +01:00
1f24b39879 Corrected sequence of IsoNode xinfo list after cloning. 2011-02-21 12:35:50 +01:00
16863755be Installed a check for miscalculated ECMA-119 tree size. 2011-02-20 12:10:26 +01:00
b25ac0f52d Avoided to give directories the same PX inode number.
(Solaris believes in them.)
2011-02-18 18:59:00 +01:00
5c59295e72 Bug fix: With a probability of 2 to 5 percent, AAIP could spoil the image
by miscalculating the number of root directory's CE blocks.
This lead to fatal offset of all further data by one block.
All sub directories and all data file content is affected.
Quite obvious to see. The problem existed since March 2009.
AAIP is used for recording of ACL and xattr. The problem gets enabled by call
iso_write_opts_set_aaip(opts, 1).
2011-02-18 17:39:21 +01:00
85893bf58b Removed warning not to use iso_tree_clone(). 2011-02-15 15:24:31 +01:00
722327e4b8 Overwriting eventually existing cloner of iso_node_xinfo_func with
iso_node_xinfo_make_clonable().
2011-02-12 14:48:31 +01:00
ab0a981814 Added capability to merge directories of cloned tree with existing
target tree.
2011-02-12 13:52:17 +01:00
38483d894e Added missing iso_filesystem_ref() for cloned node from local filesystem. 2011-02-01 22:16:05 +01:00
1082e628d1 New API calls iso_tree_clone(), iso_stream_clone.
New IsoFileSourceIface version 2 with method clone_src().
New IsoStreamIface version 4 with method clone_stream().
New public function prototype iso_node_xinfo_cloner.
New API calls iso_node_xinfo_make_clonable(), iso_node_xinfo_get_cloner().
New public iso_node_xinfo_cloner instance aaip_xinfo_cloner().
New API calls iso_node_get_next_xinfo(), iso_node_remove_all_xinfo().
New API call iso_node_remove_tree().
2011-02-01 19:16:45 +01:00
74c68224c7 Changed name of freshly introduce API call iso_write_opts_set_high_empty_address
to iso_write_opts_set_old_empty, reverted the meaning and the default.
2011-01-26 19:38:50 +01:00
200697898d New API call iso_write_opts_set_high_empty_address(). 2011-01-26 14:24:18 +01:00
a3eeda3d23 Yet incomplete implementation of IsoNode cloning.
(Commited to avoid tangling with upcomming 
 iso_write_opts_set_no_dummy_block_adr())
2011-01-25 10:50:37 +01:00
92073c45ef Bug fix: Volume Descriptor Set Terminator contained non-zero bytes in
the reserved field (ECMA-119 8.3.4). The bytes stem from an uninitialized
local variable.
2011-01-24 15:03:09 +01:00
81cded618d Better hiding of a defunct #ifndef 2011-01-18 17:50:26 +01:00
84c0bd37ff Avoiding <stdint.h> if not available. Trying to use <inttypes.h> in that case. 2011-01-18 16:18:09 +01:00
4e60feaeab Avoiding the use of setenv() and unsetenv() which are not available
on Solaris 9.
2011-01-18 15:26:19 +01:00
d6e150a10e Version leap to 1.0.1 2011-01-16 13:35:07 +01:00
39 changed files with 2318 additions and 313 deletions

View File

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

View File

@ -1,6 +1,33 @@
bzr branch lp:libisofs/for-libisoburn (to become libisofs-1.0.2.tar.gz)
libisofs-1.0.6.tar.gz Sat Apr 09 2011
===============================================================================
- no novelties yet
* New API call iso_write_opts_set_joliet_long_names()
* New error codes for oversized file addresses
libisofs-1.0.4.tar.gz Thu Mar 10 2011
===============================================================================
* Bug fix: Compilation failed if --disable-zlib was configured
* Bug fix: isohybrid image size was not aligned to cylinder boundary.
* New no_md5 value 2 for API call iso_read_opts_set_no_md5()
* New option bits 8 and 9 with iso_write_opts_set_system_area()
libisofs-1.0.2.tar.gz Tue Feb 23 2011
===============================================================================
* Bug fix: iso_write_opts_set_aaip(opts, 1) could cause fatal miscalculation
of the root directory size. This eventually truncated directory
tree and spoiled all data file content.
* Bug fix: Volume Descriptor Set Terminator contained non-zero bytes in
the reserved field (ECMA-119 8.3.4). The bytes stem from the
previously written Volume Descriptor.
* New API calls iso_tree_clone(), iso_stream_clone.
* New IsoFileSourceIface version 2 with method clone_src().
* New IsoStreamIface version 4 with method clone_stream().
* New public function prototype iso_node_xinfo_cloner.
* New API calls iso_node_xinfo_make_clonable(), iso_node_xinfo_get_cloner().
* New public iso_node_xinfo_cloner instance aaip_xinfo_cloner().
* New API calls iso_node_get_next_xinfo(), iso_node_remove_all_xinfo().
* New API call iso_node_remove_tree().
* New API call iso_write_opts_set_old_empty().
libisofs-1.0.0.tar.gz Mon Jan 17 2011
===============================================================================

1
README
View File

@ -54,6 +54,7 @@ applications which use it. This dependency can be avoided by configure options
--disable-libacl avoid use of ACL functions like acl_to_text()
--disable-xattr avoid use of xattr functions like listxattr()
--disable-zlib avoid use of zlib functions like compress2()
--disable-libjte avoid use of libjte functions
See INSTALL file for general options of ./configure.

View File

@ -1,4 +1,4 @@
AC_INIT([libisofs], [1.0.0], [http://libburnia-project.org])
AC_INIT([libisofs], [1.0.6], [http://libburnia-project.org])
AC_PREREQ([2.50])
dnl AC_CONFIG_HEADER([config.h])
@ -40,7 +40,7 @@ dnl If LIBISOFS_*_VERSION changes, be sure to change AC_INIT above to match.
dnl
LIBISOFS_MAJOR_VERSION=1
LIBISOFS_MINOR_VERSION=0
LIBISOFS_MICRO_VERSION=0
LIBISOFS_MICRO_VERSION=6
LIBISOFS_VERSION=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION.$LIBISOFS_MICRO_VERSION
AC_SUBST(LIBISOFS_MAJOR_VERSION)
@ -50,10 +50,10 @@ AC_SUBST(LIBISOFS_VERSION)
dnl Libtool versioning
LT_RELEASE=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION
# 2011.01.16 development jump has not yet happened
# SONAME = 44 - 38 = 6 . Library name = libisofs.6.38.0
LT_CURRENT=44
LT_AGE=38
# 2011.04.09 development jump has not yet happened
# SONAME = 50 - 44 = 6 . Library name = libisofs.6.44.0
LT_CURRENT=50
LT_AGE=44
LT_REVISION=0
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`

View File

@ -50,6 +50,7 @@ static char helptext[][80] = {
#include <fcntl.h>
#include <err.h>
#include <limits.h>
#include <errno.h>
#ifndef PATH_MAX
@ -372,7 +373,11 @@ int gesture_iso(int argc, char **argv)
iso_write_opts_free(opts);
while (burn_src->read_xt(burn_src, buf, 2048) == 2048) {
fwrite(buf, 1, 2048, fp);
result = fwrite(buf, 1, 2048, fp);
if (result < 2048) {
printf ("Cannot write block. errno= %d\n", errno);
goto ex;
}
}
fclose(fp);
burn_src->free_data(burn_src);
@ -537,7 +542,7 @@ int gesture_iso_read(int argc, char **argv)
int gesture_iso_cat(int argc, char **argv)
{
int res;
int res, write_ret;
IsoFilesystem *fs;
IsoFileSource *file;
struct stat info;
@ -596,7 +601,11 @@ int gesture_iso_cat(int argc, char **argv)
return 1;
}
while ((res = iso_file_source_read(file, buf, 1024)) > 0) {
fwrite(buf, 1, res, stdout);
write_ret = fwrite(buf, 1, res, stdout);
if (write_ret < res) {
printf ("Cannot write block to stdout. errno= %d\n", errno);
return 1;
}
}
if (res < 0) {
fprintf(stderr, "Error reading, err = %d\n", res);
@ -700,7 +709,11 @@ int gesture_iso_modify(int argc, char **argv)
iso_write_opts_free(opts);
while (burn_src->read_xt(burn_src, buf, 2048) == 2048) {
fwrite(buf, 1, 2048, fp);
result = fwrite(buf, 1, 2048, fp);
if (result < 2048) {
printf ("Cannot write block. errno= %d\n", errno);
goto ex;
}
}
fclose(fp);
burn_src->free_data(burn_src);
@ -814,7 +827,11 @@ int gesture_iso_ms(int argc, char **argv)
iso_write_opts_free(opts);
while (burn_src->read_xt(burn_src, buf, 2048) == 2048) {
fwrite(buf, 1, 2048, fp);
result = fwrite(buf, 1, 2048, fp);
if (result < 2048) {
printf ("Cannot write block. errno= %d\n", errno);
goto ex;
}
}
fclose(fp);
burn_src->free_data(burn_src);

View File

@ -22,6 +22,8 @@ Purpose:
END is also the block address of the start of the checksum recording
area in the image.
See also isofs.cx .
This attribute shall eventually be attached to the root directory entry
and be global for the whole image.
Format of Value:
START_LEN | START_BYTES | END_LEN | END_BYTES |
@ -150,7 +152,7 @@ Registered:
-------------------------------------------------------------------------------
This text is under
Copyright (c) 2009 - 2010 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2009 - 2011 Thomas Schmitt <scdbackup@gmx.net>
It shall only be modified in sync with libisofs and other software which
makes use of AAIP. Please mail change requests to mailing list
<libburn-hackers@pykix.org> or to the copyright holder in private.

View File

@ -11,7 +11,14 @@
#define LIBISO_BUFFER_H_
#include <stdlib.h>
#ifdef HAVE_STDINT_H
#include <stdint.h>
#else
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#endif
#define BLOCK_SIZE 2048

View File

@ -26,10 +26,6 @@
#include <limits.h>
#include <stdio.h>
#ifndef PATH_MAX
#define PATH_MAX Libisofs_default_path_maX
#endif
void iso_node_builder_ref(IsoNodeBuilder *builder)
@ -75,6 +71,8 @@ int default_create_file(IsoNodeBuilder *builder, IsoImage *image,
iso_file_source_ref(src);
name = iso_file_source_get_name(src);
if (strlen(name) > LIBISOFS_NODE_NAME_MAX)
name[LIBISOFS_NODE_NAME_MAX] = 0;
ret = iso_node_new_file(name, stream, &node);
if (ret < 0) {
iso_stream_unref(stream);
@ -122,6 +120,8 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
}
name = iso_file_source_get_name(src);
if (strlen(name) > LIBISOFS_NODE_NAME_MAX)
name[LIBISOFS_NODE_NAME_MAX] = 0;
fs = iso_file_source_get_filesystem(src);
new = NULL;
@ -157,10 +157,10 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
case S_IFLNK:
{
/* source is a symbolic link */
char dest[PATH_MAX];
char dest[LIBISOFS_NODE_PATH_MAX];
IsoSymlink *link;
ret = iso_file_source_readlink(src, dest, PATH_MAX);
ret = iso_file_source_readlink(src, dest, LIBISOFS_NODE_PATH_MAX);
if (ret < 0) {
break;
}

View File

@ -1,7 +1,7 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2007 Mario Danic
* Copyright (c) 2009 - 2010 Thomas Schmitt
* Copyright (c) 2009 - 2011 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -329,6 +329,9 @@ int ecma119_writer_compute_data_blocks(IsoImageWriter *writer)
image start and not for the partition */;
}
target->tree_end_block = target->curblock;
return ISO_SUCCESS;
}
@ -380,11 +383,14 @@ void write_one_dir_record(Ecma119Image *t, Ecma119Node *node, int file_id,
multi_extend = (node->info.file->nsections - 1 == extent) ? 0 : 1;
} else {
/*
* for nodes other than files and dirs, we set both
* len and block to 0
* for nodes other than files and dirs, we set len to 0, and
* the content block address to a dummy value.
*/
len = 0;
block = 0;
if (! t->old_empty)
block = t->empty_file_block;
else
block = 0;
}
/*
@ -871,6 +877,7 @@ int ecma119_writer_write_data(IsoImageWriter *writer)
{
int ret;
Ecma119Image *t;
uint32_t curblock;
if (writer == NULL) {
return ISO_ASSERT_FAILURE;
@ -888,6 +895,20 @@ int ecma119_writer_write_data(IsoImageWriter *writer)
if (ret < 0)
return ret;
}
curblock = (t->bytes_written / 2048) + t->ms_block;
if (curblock != t->tree_end_block) {
char msg[100];
sprintf(msg,
"Calculated and written ECMA-119 tree end differ: %lu <> %lu",
(unsigned long) t->tree_end_block,
(unsigned long) curblock);
iso_msgs_submit(0, msg, 0, "WARNING", 0);
t->tree_end_block = 1;/* Mark for harsher reaction at end of writing */
}
return ISO_SUCCESS;
}
@ -1087,7 +1108,36 @@ int zero_writer_free_data(IsoImageWriter *writer)
}
static
int zero_writer_create(Ecma119Image *target, uint32_t num_blocks)
int tail_writer_compute_data_blocks(IsoImageWriter *writer)
{
int ret;
Ecma119Image *target;
struct iso_zero_writer_data_struct *data;
char msg[160];
target = writer->target;
ret = iso_align_isohybrid(target, 0);
if (ret < 0)
return ret;
data = (struct iso_zero_writer_data_struct *) writer->data;
if (data->num_blocks != target->tail_blocks) {
sprintf(msg, "Aligned image size to cylinder size by %d blocks",
target->tail_blocks - data->num_blocks);
iso_msgs_submit(0, msg, 0, "NOTE", 0);
data->num_blocks = target->tail_blocks;
}
if (target->tail_blocks <= 0)
return ISO_SUCCESS;
ret = zero_writer_compute_data_blocks(writer);
return ret;
}
/*
@param flag bit0= use tail_writer_compute_data_blocks rather than
zero_writer_compute_data_blocks
*/
static
int zero_writer_create(Ecma119Image *target, uint32_t num_blocks, int flag)
{
IsoImageWriter *writer;
struct iso_zero_writer_data_struct *data;
@ -1103,7 +1153,11 @@ int zero_writer_create(Ecma119Image *target, uint32_t num_blocks)
}
data->num_blocks = num_blocks;
writer->compute_data_blocks = zero_writer_compute_data_blocks;
if (flag & 1) {
writer->compute_data_blocks = tail_writer_compute_data_blocks;
} else {
writer->compute_data_blocks = zero_writer_compute_data_blocks;
}
writer->write_vol_desc = zero_writer_write_vol_desc;
writer->write_data = zero_writer_write_data;
writer->free_data = zero_writer_free_data;
@ -1135,6 +1189,8 @@ int write_vol_desc_terminator(Ecma119Image *target)
uint8_t buf[BLOCK_SIZE];
struct ecma119_vol_desc_terminator *vol;
memset(buf, 0, BLOCK_SIZE);
vol = (struct ecma119_vol_desc_terminator *) buf;
vol->vol_desc_type[0] = 255;
@ -1209,7 +1265,7 @@ int write_head_part2(Ecma119Image *target, int *write_count, int flag)
return ISO_SUCCESS;
/* Write multi-session padding up to target->partition_offset + 16 */
memset(buf, 0, 2048);
memset(buf, 0, BLOCK_SIZE);
for(; *write_count < target->partition_offset + 16; (*write_count)++) {
res = iso_write(target, buf, BLOCK_SIZE);
if (res < 0)
@ -1400,6 +1456,12 @@ void *write_function(void *arg)
Eventually free target */
ecma119_image_free(target);
if (target->tree_end_block == 1) {
iso_msgs_submit(0,
"Image is most likely damaged. Calculated/written block address mismatch.",
0, "FATAL", 0);
}
#ifdef Libisofs_with_pthread_exiT
pthread_exit(NULL);
#else
@ -1575,6 +1637,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
target->hardlinks = opts->hardlinks;
target->aaip = opts->aaip;
target->always_gmt = opts->always_gmt;
target->old_empty = opts->old_empty;
target->untranslated_name_len = opts->untranslated_name_len;
target->allow_dir_id_ext = opts->allow_dir_id_ext;
target->omit_version_numbers = opts->omit_version_numbers
@ -1587,6 +1650,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
target->allow_full_ascii = opts->allow_full_ascii;
target->relaxed_vol_atts = opts->relaxed_vol_atts;
target->joliet_longer_paths = opts->joliet_longer_paths;
target->joliet_long_names = opts->joliet_long_names;
target->rrip_version_1_10 = opts->rrip_version_1_10;
target->rrip_1_10_px_ino = opts->rrip_1_10_px_ino;
target->aaip_susp_1_10 = opts->aaip_susp_1_10;
@ -1636,7 +1700,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
system_area = src->system_area_data;
system_area_options = src->system_area_options;
} else {
system_area_options = opts->system_area_options & 0xfc;
system_area_options = opts->system_area_options & 0xfffffffc;
}
sa_type = (system_area_options >> 2) & 0x3f;
if (sa_type != 0 && sa_type != 3)
@ -1665,9 +1729,9 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
target->partition_secs_per_head = opts->partition_secs_per_head;
target->partition_heads_per_cyl = opts->partition_heads_per_cyl;
if (target->partition_secs_per_head == 0)
target->partition_secs_per_head = 63;
target->partition_secs_per_head = 32;
if (target->partition_heads_per_cyl == 0)
target->partition_heads_per_cyl = 255;
target->partition_heads_per_cyl = 64;
target->eff_partition_offset = 0;
target->partition_root = NULL;
target->partition_l_table_pos = 0;
@ -1733,6 +1797,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
target->mipsel_p_filesz = 0;
target->empty_file_block = 0;
target->tree_end_block = 0;
target->wthread_is_running = 0;
@ -1779,8 +1844,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
if (target->iso1999) {
nwriters++;
}
if (target->tail_blocks > 0)
nwriters++;
nwriters++; /* Tail padding writer */
if ((target->md5_file_checksums & 1) || target->md5_session_checksum) {
nwriters++;
image_checksums_mad = 1; /* from here on the loaded checksums are
@ -1862,11 +1926,9 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
/* IMPORTANT: This must be the last writer before the checksum writer */
if (target->tail_blocks > 0) {
ret = zero_writer_create(target, target->tail_blocks);
if (ret < 0)
goto target_cleanup;
}
ret = zero_writer_create(target, target->tail_blocks, 1);
if (ret < 0)
goto target_cleanup;
if ((target->md5_file_checksums & 1) || target->md5_session_checksum) {
ret = checksum_writer_create(target);
@ -1920,8 +1982,15 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
if (i == el_torito_writer_index)
continue;
/* Exposing address of data start to IsoWriteOpts */
/* Exposing address of data start to IsoWriteOpts and memorizing
this address for all files which have no block address:
symbolic links, device files, empty data files.
filesrc_writer_compute_data_blocks() and filesrc_writer_write_data()
will account resp. write this single block.
*/
if (i == file_src_writer_index) {
if (! target->old_empty)
target->empty_file_block = target->curblock;
opts->data_start_lba = target->curblock;
}
@ -2268,6 +2337,8 @@ int iso_write(Ecma119Image *target, void *buf, size_t count)
/* reader cancelled */
return ISO_CANCELED;
}
if (ret < 0)
return ret;
if (target->checksum_ctx != NULL) {
/* Add to image checksum */
target->checksum_counter += count;
@ -2279,7 +2350,7 @@ int iso_write(Ecma119Image *target, void *buf, size_t count)
return ret;
/* total size is 0 when writing the overwrite buffer */
if (ret > 0 && (target->total_size != (off_t) 0)){
if (target->total_size != (off_t) 0){
unsigned int kbw, kbt;
int percent;
@ -2296,7 +2367,7 @@ int iso_write(Ecma119Image *target, void *buf, size_t count)
}
}
return ret;
return ISO_SUCCESS;
}
int iso_write_opts_new(IsoWriteOpts **opts, int profile)
@ -2366,6 +2437,7 @@ int iso_write_opts_new(IsoWriteOpts **opts, int profile)
wopts->ascii_disc_label[0] = 0;
wopts->will_cancel = 0;
wopts->allow_dir_id_ext = 0;
wopts->old_empty = 0;
wopts->untranslated_name_len = 0;
*opts = wopts;
@ -2455,6 +2527,15 @@ int iso_write_opts_set_aaip(IsoWriteOpts *opts, int enable)
return ISO_SUCCESS;
}
int iso_write_opts_set_old_empty(IsoWriteOpts *opts, int enable)
{
if (opts == NULL) {
return ISO_NULL_POINTER;
}
opts->old_empty = enable ? 1 : 0;
return ISO_SUCCESS;
}
int iso_write_opts_set_untranslated_name_len(IsoWriteOpts *opts, int len)
{
if (opts == NULL) {
@ -2561,6 +2642,15 @@ int iso_write_opts_set_joliet_longer_paths(IsoWriteOpts *opts, int allow)
return ISO_SUCCESS;
}
int iso_write_opts_set_joliet_long_names(IsoWriteOpts *opts, int allow)
{
if (opts == NULL) {
return ISO_NULL_POINTER;
}
opts->joliet_long_names = allow ? 1 : 0;
return ISO_SUCCESS;
}
int iso_write_opts_set_rrip_version_1_10(IsoWriteOpts *opts, int oldvers)
{
if (opts == NULL) {
@ -2830,7 +2920,7 @@ int iso_write_opts_set_system_area(IsoWriteOpts *opts, char data[32768],
memcpy(opts->system_area_data, data, 32768);
}
if (!(flag & 4))
opts->system_area_options = options & 0xff;
opts->system_area_options = options & 0x3ff;
return ISO_SUCCESS;
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 Thomas Schmitt
* Copyright (c) 2009 - 2011 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -15,7 +15,14 @@
#include "util.h"
#include "buffer.h"
#ifdef HAVE_STDINT_H
#include <stdint.h>
#else
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#endif
#include <pthread.h>
#define BLOCK_SIZE 2048
@ -154,6 +161,11 @@ struct iso_write_opts {
*/
unsigned int joliet_longer_paths :1;
/**
* Allow Joliet names up to 103 characters rather than 64.
*/
unsigned int joliet_long_names :1;
/**
* Write Rock Ridge info as of specification RRIP-1.10 rather than
* RRIP-1.12: signature "RRIP_1991A" rather than "IEEE_1282",
@ -232,6 +244,16 @@ struct iso_write_opts {
unsigned int replace_uid :2;
unsigned int replace_gid :2;
mode_t dir_mode; /** Mode to use on dirs when replace_dir_mode == 2. */
mode_t file_mode; /** Mode to use on files when replace_file_mode == 2. */
uid_t uid; /** uid to use when replace_uid == 2. */
gid_t gid; /** gid to use when replace_gid == 2. */
/**
* See API call iso_write_opts_set_old_empty().
*/
unsigned int old_empty :1;
/**
* Extra Caution: This option breaks any assumptions about names that
* are supported by ECMA-119 specifications.
@ -247,11 +269,6 @@ struct iso_write_opts {
*/
unsigned int untranslated_name_len;
mode_t dir_mode; /** Mode to use on dirs when replace_dir_mode == 2. */
mode_t file_mode; /** Mode to use on files when replace_file_mode == 2. */
uid_t uid; /** uid to use when replace_uid == 2. */
gid_t gid; /** gid to use when replace_gid == 2. */
/**
* 0 to use IsoNode timestamps, 1 to use recording time, 2 to use
* values from timestamp field. This has only meaning if RR extensions
@ -447,6 +464,9 @@ struct ecma119_image
/** Allow paths on Joliet tree to be larger than 240 bytes */
unsigned int joliet_longer_paths :1;
/** Allow Joliet names up to 103 characters rather than 64 */
unsigned int joliet_long_names :1;
/** Write old fashioned RRIP-1.10 rather than RRIP-1.12 */
unsigned int rrip_version_1_10 :1;
@ -472,14 +492,15 @@ struct ecma119_image
unsigned int replace_dir_mode :1;
unsigned int replace_timestamps :1;
unsigned int untranslated_name_len;
uid_t uid;
gid_t gid;
mode_t file_mode;
mode_t dir_mode;
time_t timestamp;
unsigned int old_empty :1;
unsigned int untranslated_name_len;
/**
* if sort files or not. Sorting is based of the weight of each file
*/
@ -512,6 +533,12 @@ struct ecma119_image
*/
uint32_t empty_file_block;
/*
* The calculated block address after ECMA-119 tree and eventual
* tree checksum tag.
*/
uint32_t tree_end_block;
/*
* number of dirs in ECMA-119 tree, computed together with dir position,
* and needed for path table computation in a efficient way
@ -556,19 +583,27 @@ struct ecma119_image
*/
char *system_area_data;
/*
* bit0= Only with PC-BIOS DOS MBR
* bit0= Only with DOS MBR
* Make bytes 446 - 512 of the system area a partition
* table which reserves partition 1 from byte 63*512 to the
* end of the ISO image. Assumed are 63 secs/hed, 255 head/cyl.
* (GRUB protective msdos label.)
* This works with and without system_area_data.
* bit1= Only with PC-BIOS DOS MBR
* bit1= Only with DOS MBR
* Apply isohybrid MBR patching to the system area.
* This works only with system_area_data plus ISOLINUX boot image
* and only if not bit0 is set.
* bit2-7= System area type
* 0= DOS MBR
* 1= MIPS Big Endian Volume Header
* 2= DEC Boot Block for MIPS Little Endian
* 3= SUN Disk Label for SUN SPARC
* bit8-9= Only with DOS MBR
* Cylinder alignment mode eventually pads the image to make it
* end at a cylinder boundary.
* 0 = auto (align if bit1)
* 1 = always align to cylinder boundary
* 2 = never align to cylinder boundary
*/
int system_area_options;

View File

@ -1074,11 +1074,12 @@ int match_hardlinks(Ecma119Image *img, Ecma119Node *dir, int flag)
iso_node_get_id(nodes[0]->node, &fs_id, &dev_id, &img_ino, 1);
family_start = 0;
for (i = 1; i < node_count; i++) {
if (ecma119_node_cmp_hard(nodes + (i - 1), nodes + i) == 0) {
if (nodes[i]->type != ECMA119_DIR &&
ecma119_node_cmp_hard(nodes + (i - 1), nodes + i) == 0) {
/* Still in same ino family */
if (img_ino == 0) { /* Just in case any member knows its img_ino */
iso_node_get_id(nodes[0]->node, &fs_id, &dev_id, &img_ino, 1);
}
}
continue;
}
family_set_ino(img, nodes, family_start, i, img_ino, prev_ino, 0);

View File

@ -239,6 +239,7 @@ int iso_tree_add_boot_node(IsoDir *parent, const char *name, IsoBoot **boot)
IsoBoot *node;
IsoNode **pos;
time_t now;
int ret;
if (parent == NULL || name == NULL || boot == NULL) {
return ISO_NULL_POINTER;
@ -248,9 +249,9 @@ int iso_tree_add_boot_node(IsoDir *parent, const char *name, IsoBoot **boot)
}
/* check if the name is valid */
if (!iso_node_is_valid_name(name)) {
return ISO_WRONG_ARG_VALUE;
}
ret = iso_node_is_valid_name(name);
if (ret < 0)
return ret;
/* find place where to insert */
pos = &(parent->children);

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* 2010 Thomas Schmitt
* 2010 - 2011 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -232,6 +232,12 @@ int filesrc_writer_compute_data_blocks(IsoImageWriter *writer)
t = writer->target;
/* Normally reserve a single zeroed block for all files which have
no block address: symbolic links, device files, empty data files.
*/
if (! t->old_empty)
t->curblock++;
/* on appendable images, ms files shouldn't be included */
if (t->appendable) {
inc_item = is_ms_file;
@ -347,11 +353,22 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
return ISO_ASSERT_FAILURE;
}
memset(buffer, 0, BLOCK_SIZE);
t = writer->target;
filelist = writer->data;
iso_msg_debug(t->image->id, "Writing Files...");
/* Normally write a single zeroed block as block address target for all
files which have no block address:
symbolic links, device files, empty data files.
*/
if (! t->old_empty) {
ret = iso_write(t, buffer, BLOCK_SIZE);
if (ret < 0)
goto ex;
}
i = 0;
while ((file = filelist[i++]) != NULL) {
was_error = 0;

View File

@ -13,7 +13,13 @@
#include "stream.h"
#include "ecma119.h"
#ifdef HAVE_STDINT_H
#include <stdint.h>
#else
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#endif
struct Iso_File_Src
{

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009 Thomas Schmitt
* Copyright (c) 2009 - 2011 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -20,6 +20,7 @@
#include "../libisofs.h"
#include "../filter.h"
#include "../fsource.h"
#include "../stream.h"
#include <sys/types.h>
#include <sys/time.h>
@ -40,7 +41,7 @@
* for classical pipe filtering.
*/
/* IMPORTANT: Any change must be reflected by extf_clone_stream() */
/*
* Individual runtime properties exist only as long as the stream is opened.
*/
@ -598,6 +599,36 @@ IsoStream *extf_get_input_stream(IsoStream *stream, int flag)
return data->orig;
}
static
int extf_clone_stream(IsoStream *old_stream, IsoStream **new_stream, int flag)
{
int ret;
IsoStream *new_input_stream, *stream;
ExternalFilterStreamData *stream_data, *old_stream_data;
if (flag)
return ISO_STREAM_NO_CLONE; /* unknown option required */
stream_data = calloc(1, sizeof(ExternalFilterStreamData));
if (stream_data == NULL)
return ISO_OUT_OF_MEM;
ret = iso_stream_clone_filter_common(old_stream, &stream,
&new_input_stream, 0);
if (ret < 0) {
free((char *) stream_data);
return ret;
}
old_stream_data = (ExternalFilterStreamData *) old_stream->data;
stream_data->id = ++extf_ino_id;
stream_data->orig = new_input_stream;
stream_data->cmd = old_stream_data->cmd;
stream_data->cmd->refcount++;
stream_data->size = old_stream_data->size;
stream_data->running = NULL;
stream->data = stream_data;
*new_stream = stream;
return ISO_SUCCESS;
}
static
int extf_cmp_ino(IsoStream *s1, IsoStream *s2);
@ -605,7 +636,7 @@ int extf_cmp_ino(IsoStream *s1, IsoStream *s2);
IsoStreamIface extf_stream_class = {
3,
4,
"extf",
extf_stream_open,
extf_stream_close,
@ -616,7 +647,8 @@ IsoStreamIface extf_stream_class = {
extf_stream_free,
extf_update_size,
extf_get_input_stream,
extf_cmp_ino
extf_cmp_ino,
extf_clone_stream
};

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009 Thomas Schmitt
* Copyright (c) 2009 - 2011 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -25,6 +25,7 @@
#include "../filter.h"
#include "../fsource.h"
#include "../util.h"
#include "../stream.h"
#include <sys/types.h>
#include <sys/time.h>
@ -153,6 +154,7 @@ static int gzip_compression_level = 6;
/*
* The data payload of an individual Gzip Filter IsoStream
*/
/* IMPORTANT: Any change must be reflected by gzip_clone_stream() */
typedef struct
{
IsoStream *orig;
@ -529,12 +531,51 @@ IsoStream *gzip_get_input_stream(IsoStream *stream, int flag)
}
static
int gzip_clone_stream(IsoStream *old_stream, IsoStream **new_stream, int flag)
{
#ifdef Libisofs_with_zliB
int ret;
IsoStream *new_input_stream, *stream;
GzipFilterStreamData *stream_data, *old_stream_data;
if (flag)
return ISO_STREAM_NO_CLONE; /* unknown option required */
stream_data = calloc(1, sizeof(GzipFilterStreamData));
if (stream_data == NULL)
return ISO_OUT_OF_MEM;
ret = iso_stream_clone_filter_common(old_stream, &stream,
&new_input_stream, 0);
if (ret < 0) {
free((char *) stream_data);
return ret;
}
old_stream_data = (GzipFilterStreamData *) old_stream->data;
stream_data->orig = new_input_stream;
stream_data->size = old_stream_data->size;
stream_data->running = NULL;
stream_data->id = ++gzip_ino_id;
stream->data = stream_data;
*new_stream = stream;
return ISO_SUCCESS;
#else /* Libisofs_with_zliB */
return ISO_STREAM_NO_CLONE;
#endif /* ! Libisofs_with_zliB */
}
static
int gzip_cmp_ino(IsoStream *s1, IsoStream *s2);
IsoStreamIface gzip_stream_compress_class = {
3,
4,
"gzip",
gzip_stream_open,
gzip_stream_close,
@ -545,12 +586,13 @@ IsoStreamIface gzip_stream_compress_class = {
gzip_stream_free,
gzip_update_size,
gzip_get_input_stream,
gzip_cmp_ino
gzip_cmp_ino,
gzip_clone_stream
};
IsoStreamIface gzip_stream_uncompress_class = {
3,
4,
"pizg",
gzip_stream_open,
gzip_stream_close,
@ -561,7 +603,8 @@ IsoStreamIface gzip_stream_uncompress_class = {
gzip_stream_free,
gzip_update_size,
gzip_get_input_stream,
gzip_cmp_ino
gzip_cmp_ino,
gzip_clone_stream
};

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009 Thomas Schmitt
* Copyright (c) 2009 - 2011 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -22,6 +22,7 @@
#include "../filter.h"
#include "../fsource.h"
#include "../util.h"
#include "../stream.h"
#include <sys/types.h>
#include <sys/time.h>
@ -167,6 +168,7 @@ static int ziso_compression_level = 6;
/*
* The common data payload of an individual Zisofs Filter IsoStream
* IMPORTANT: Any change must be reflected by ziso_clone_stream().
*/
typedef struct
{
@ -183,6 +185,7 @@ typedef struct
/*
* The data payload of an individual Zisofs Filter Compressor IsoStream
* IMPORTANT: Any change must be reflected by ziso_clone_stream().
*/
typedef struct
{
@ -198,6 +201,7 @@ typedef struct
/*
* The data payload of an individual Zisofs Filter Uncompressor IsoStream
* IMPORTANT: Any change must be reflected by ziso_clone_stream().
*/
typedef struct
{
@ -779,13 +783,63 @@ IsoStream *ziso_get_input_stream(IsoStream *stream, int flag)
return data->orig;
}
static
int ziso_clone_stream(IsoStream *old_stream, IsoStream **new_stream, int flag)
{
int ret;
IsoStream *new_input_stream = NULL, *stream = NULL;
ZisofsFilterStreamData *stream_data, *old_stream_data;
ZisofsUncomprStreamData *uncompr, *old_uncompr;
ZisofsComprStreamData *compr, *old_compr;
if (flag)
return ISO_STREAM_NO_CLONE; /* unknown option required */
ret = iso_stream_clone_filter_common(old_stream, &stream,
&new_input_stream, 0);
if (ret < 0)
return ret;
if (old_stream->class->read == &ziso_stream_uncompress) {
uncompr = calloc(1, sizeof(ZisofsUncomprStreamData));
if (uncompr == NULL)
goto no_mem;
stream_data = (ZisofsFilterStreamData *) uncompr;
old_uncompr = (ZisofsUncomprStreamData *) old_stream->data;
uncompr->header_size_div4 = old_uncompr->header_size_div4;
uncompr->block_size_log2 = old_uncompr->block_size_log2;
} else {
compr = calloc(1, sizeof(ZisofsComprStreamData));
if (compr == NULL)
goto no_mem;
stream_data = (ZisofsFilterStreamData *) compr;
old_compr = (ZisofsComprStreamData *) old_stream->data;
compr->orig_size = old_compr->orig_size;
compr->block_pointers = NULL;
}
old_stream_data = (ZisofsFilterStreamData *) old_stream->data;
stream_data->orig = new_input_stream;
stream_data->size = old_stream_data->size;
stream_data->running = NULL;
stream_data->id = ++ziso_ino_id;
stream->data = stream_data;
*new_stream = stream;
return ISO_SUCCESS;
no_mem:
if (new_input_stream != NULL)
iso_stream_unref(new_input_stream);
if (stream != NULL)
iso_stream_unref(stream);
return ISO_OUT_OF_MEM;
}
static
int ziso_cmp_ino(IsoStream *s1, IsoStream *s2);
IsoStreamIface ziso_stream_compress_class = {
3,
4,
"ziso",
ziso_stream_open,
ziso_stream_close,
@ -796,12 +850,13 @@ IsoStreamIface ziso_stream_compress_class = {
ziso_stream_free,
ziso_update_size,
ziso_get_input_stream,
ziso_cmp_ino
ziso_cmp_ino,
ziso_clone_stream
};
IsoStreamIface ziso_stream_uncompress_class = {
3,
4,
"osiz",
ziso_stream_open,
ziso_stream_close,
@ -812,7 +867,8 @@ IsoStreamIface ziso_stream_uncompress_class = {
ziso_stream_free,
ziso_update_size,
ziso_get_input_stream,
ziso_cmp_ino
ziso_cmp_ino,
ziso_clone_stream
};

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2010 Thomas Schmitt
* Copyright (c) 2009 - 2011 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -35,11 +35,6 @@
#include <stdio.h>
#ifndef PATH_MAX
#define PATH_MAX Libisofs_default_path_maX
#endif
/**
* Options for image reading.
* There are four kind of options:
@ -72,7 +67,7 @@ struct iso_read_opts
unsigned int nojoliet : 1; /*< Do not read Joliet extensions */
unsigned int noiso1999 : 1; /*< Do not read ISO 9660:1999 enhanced tree */
unsigned int noaaip : 1; /* Do not read AAIP extension for xattr and ACL */
unsigned int nomd5 : 1; /* Do not read MD5 array */
unsigned int nomd5 : 2; /* Do not read MD5 array */
/**
* Hand out new inode numbers and overwrite eventually read PX inode
@ -267,7 +262,7 @@ typedef struct
int aaip_load;
/** Whether the MD5 array shall be read if available.
* 1 = yes , 0 = no
* 2 = yes, but do not check tags , 1 = yes , 0 = no
*/
int md5_load;
@ -317,6 +312,7 @@ typedef struct
typedef struct image_fs_data ImageFileSourceData;
/* IMPORTANT: Any change must be reflected by ifs_clone_src */
struct image_fs_data
{
IsoImageFilesystem *fs; /**< reference to the image it belongs to */
@ -952,6 +948,7 @@ int ifs_readlink(IsoFileSource *src, char *buf, size_t bufsiz)
{
char *dest;
size_t len;
int ret;
ImageFileSourceData *data;
if (src == NULL || buf == NULL || src->data == NULL) {
@ -970,14 +967,15 @@ int ifs_readlink(IsoFileSource *src, char *buf, size_t bufsiz)
dest = (char*)data->data.content;
len = strlen(dest);
if (bufsiz <= len) {
ret = ISO_SUCCESS;
if (len >= bufsiz) {
ret = ISO_RR_PATH_TOO_LONG;
len = bufsiz - 1;
}
strncpy(buf, dest, len);
buf[len] = '\0';
return ISO_SUCCESS;
return ret;
}
static
@ -1043,10 +1041,87 @@ int ifs_get_aa_string(IsoFileSource *src, unsigned char **aa_string, int flag)
return 1;
}
static
int ifs_clone_src(IsoFileSource *old_source,
IsoFileSource **new_source, int flag)
{
IsoFileSource *src = NULL;
ImageFileSourceData *old_data, *new_data = NULL;
char *new_name = NULL;
struct iso_file_section *new_sections = NULL;
void *new_aa_string = NULL;
int i, ret;
if (flag)
return ISO_STREAM_NO_CLONE; /* unknown option required */
old_data = (ImageFileSourceData *) old_source->data;
*new_source = NULL;
src = calloc(1, sizeof(IsoFileSource));
if (src == NULL)
goto no_mem;
new_name = strdup(old_data->name);
if (new_name == NULL)
goto no_mem;
new_data = calloc(1, sizeof(ImageFileSourceData));
if (new_data == NULL)
goto no_mem;
if (old_data->nsections > 0) {
new_sections = calloc(old_data->nsections,
sizeof(struct iso_file_section));
if (new_sections == NULL)
goto no_mem;
}
ret = aaip_xinfo_cloner(old_data->aa_string, &new_aa_string, 0);
if (ret < 0)
goto no_mem;
new_data->fs = old_data->fs;
new_data->parent = old_data->parent;
memcpy(&(new_data->info), &(old_data->info), sizeof(struct stat));
new_data->name = new_name;
new_data->sections = new_sections;
new_data->nsections = old_data->nsections;
for (i = 0; i < new_data->nsections; i++)
memcpy(new_data->sections + i, old_data->sections + i,
sizeof(struct iso_file_section));
new_data->opened = old_data->opened;
#ifdef Libisofs_with_zliB
new_data->header_size_div4 = old_data->header_size_div4;
new_data->block_size_log2 = old_data->block_size_log2;
new_data->uncompressed_size = old_data->uncompressed_size;
#endif
new_data->data.content = NULL;
new_data->aa_string = (unsigned char *) new_aa_string;
src->class = old_source->class;
src->refcount = 1;
src->data = new_data;
*new_source = src;
iso_file_source_ref(new_data->parent);
iso_filesystem_ref(new_data->fs);
return ISO_SUCCESS;
no_mem:;
if (src != NULL)
free((char *) src);
if (new_data != NULL)
free((char *) new_data);
if (new_name != NULL)
free(new_name);
if (new_sections != NULL)
free((char *) new_sections);
if (new_aa_string != NULL)
aaip_xinfo_func(new_aa_string, 1);
return ISO_OUT_OF_MEM;
}
IsoFileSourceIface ifs_class = {
1, /* version */
2, /* version */
ifs_get_path,
ifs_get_name,
ifs_lstat,
@ -1060,7 +1135,8 @@ IsoFileSourceIface ifs_class = {
ifs_get_filesystem,
ifs_free,
ifs_lseek,
ifs_get_aa_string
ifs_get_aa_string,
ifs_clone_src
};
@ -2339,6 +2415,10 @@ int iso_src_check_sb_tree(IsoDataSource *src, uint32_t start_lba, int flag)
ret = iso_util_eval_md5_tag(block, desired, start_lba + i,
ctx, start_lba, &tag_type, &next_tag, 0);
iso_md5_compute(ctx, block, 2048);
if (ret == ISO_MD5_TAG_COPIED) { /* growing without emulated TOC */
ret = 2;
goto ex;
}
if (ret == ISO_MD5_AREA_CORRUPTED || ret == ISO_MD5_TAG_MISMATCH)
ret = ISO_SB_TREE_CORRUPTED;
if (ret < 0)
@ -2425,7 +2505,12 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
data->dir_mode = opts->dir_mode & ~S_IFMT;
data->msgid = msgid;
data->aaip_load = !opts->noaaip;
data->md5_load = !opts->nomd5;
if (opts->nomd5 == 0)
data->md5_load = 1;
else if (opts->nomd5 == 2)
data->md5_load = 2;
else
data->md5_load = 0;
data->aaip_version = -1;
data->make_new_ino = opts->make_new_ino;
data->num_bootimgs = 0;
@ -2453,7 +2538,7 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
ifs->free = ifs_fs_free;
/* read Volume Descriptors and ensure it is a valid image */
if (data->md5_load) {
if (data->md5_load == 1) {
/* From opts->block on : check for superblock and tree tags */;
ret = iso_src_check_sb_tree(src, opts->block, 0);
if (ret < 0) {
@ -2838,10 +2923,10 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
case S_IFLNK:
{
/* source is a symbolic link */
char dest[PATH_MAX];
char dest[LIBISOFS_NODE_PATH_MAX];
IsoSymlink *link;
ret = iso_file_source_readlink(src, dest, PATH_MAX);
ret = iso_file_source_readlink(src, dest, LIBISOFS_NODE_PATH_MAX);
if (ret < 0) {
free(name);
return ret;
@ -3155,6 +3240,8 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
size_t size;
void *ctx = NULL;
char md5[16];
struct el_torito_boot_catalog *catalog = NULL;
ElToritoBootImage *boot_image = NULL;
if (image == NULL || src == NULL || opts == NULL) {
return ISO_NULL_POINTER;
@ -3242,8 +3329,6 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
/* if old image has el-torito, add a new catalog */
if (data->eltorito) {
struct el_torito_boot_catalog *catalog;
ElToritoBootImage *boot_image= NULL;
catalog = calloc(1, sizeof(struct el_torito_boot_catalog));
if (catalog == NULL) {
@ -3269,11 +3354,13 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
memcpy(boot_image->selection_crit, data->selection_crits, 20);
catalog->bootimages[catalog->num_bootimages] = boot_image;
boot_image = NULL;
catalog->num_bootimages++;
}
for ( ; idx < Libisofs_max_boot_imageS; idx++)
catalog->bootimages[idx] = NULL;
image->bootcat = catalog;
catalog = NULL; /* So it does not get freed */
}
/* recursively add image */
@ -3452,6 +3539,10 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
image->fs = fsback;
image->builder = blback;
if (catalog != NULL)
el_torito_boot_catalog_free(catalog);
if (boot_image != NULL)
free((char *) boot_image);
iso_file_source_unref(newroot);
fs->close(fs);
iso_filesystem_unref(fs);
@ -3603,7 +3694,7 @@ int iso_read_opts_set_no_md5(IsoReadOpts *opts, int no_md5)
if (opts == NULL) {
return ISO_NULL_POINTER;
}
opts->nomd5 = no_md5 ? 1 : 0;
opts->nomd5 = no_md5 == 2 ? 2 : no_md5 == 1 ? 1 : 0;
return ISO_SUCCESS;
}

View File

@ -39,7 +39,7 @@ int iso_file_source_new_lfs(IsoFileSource *parent, const char *name,
*/
IsoFilesystem *lfs= NULL;
/* IMPORTANT: Any change must be reflected by lfs_clone_src() */
typedef struct
{
/** reference to the parent (if root it points to itself) */
@ -412,7 +412,7 @@ int lfs_readdir(IsoFileSource *src, IsoFileSource **child)
static
int lfs_readlink(IsoFileSource *src, char *buf, size_t bufsiz)
{
int size;
int size, ret;
_LocalFsFileSource *data;
char *path;
@ -431,7 +431,7 @@ int lfs_readlink(IsoFileSource *src, char *buf, size_t bufsiz)
* invoke readlink, with bufsiz -1 to reserve an space for
* the NULL character
*/
size = readlink(path, buf, bufsiz - 1);
size = readlink(path, buf, bufsiz);
free(path);
if (size < 0) {
/* error */
@ -455,8 +455,13 @@ int lfs_readlink(IsoFileSource *src, char *buf, size_t bufsiz)
}
/* NULL-terminate the buf */
ret = ISO_SUCCESS;
if (size >= bufsiz) {
ret = ISO_RR_PATH_TOO_LONG;
size = bufsiz - 1;
}
buf[size] = '\0';
return ISO_SUCCESS;
return ret;
}
static
@ -534,10 +539,56 @@ ex:;
return ret;
}
static
int lfs_clone_src(IsoFileSource *old_source,
IsoFileSource **new_source, int flag)
{
IsoFileSource *src = NULL;
char *new_name = NULL;
_LocalFsFileSource *old_data, *new_data = NULL;
if (flag)
return ISO_STREAM_NO_CLONE; /* unknown option required */
old_data = (_LocalFsFileSource *) old_source->data;
*new_source = NULL;
src = calloc(1, sizeof(IsoFileSource));
if (src == NULL)
goto no_mem;
new_name = strdup(old_data->name);
if (new_name == NULL)
goto no_mem;
new_data = calloc(1, sizeof(_LocalFsFileSource));
if (new_data == NULL)
goto no_mem;
new_data->openned = 0;
new_data->info.fd = -1; /* the value does not matter with (openned == 0) */
new_data->name = new_name;
new_data->parent = old_data->parent;
src->class = old_source->class;
src->refcount = 1;
src->data = new_data;
*new_source = src;
iso_file_source_ref(new_data->parent);
iso_filesystem_ref(lfs);
return ISO_SUCCESS;
no_mem:;
if (src != NULL)
free((char *) src);
if (new_data != NULL)
free((char *) new_data);
if (new_name != NULL)
free(new_name);
return ISO_OUT_OF_MEM;
}
IsoFileSourceIface lfs_class = {
1, /* version */
2, /* version */
lfs_get_path,
lfs_get_name,
lfs_lstat,
@ -551,7 +602,8 @@ IsoFileSourceIface lfs_class = {
lfs_get_filesystem,
lfs_free,
lfs_lseek,
lfs_get_aa_string
lfs_get_aa_string,
lfs_clone_src
};

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 Thomas Schmitt
* Copyright (c) 2009 - 2011 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -33,9 +33,16 @@
int iso_local_filesystem_new(IsoFilesystem **fs);
/* Rank two IsoFileSource by their eventual old image LBAs.
/* Rank two IsoFileSource of ifs_class by their eventual old image LBAs.
Other IsoFileSource classes will be ranked only roughly.
*/
int iso_ifs_sections_cmp(IsoFileSource *s1, IsoFileSource *s2, int flag);
/* Create an independent copy of an ifs_class IsoFileSource.
*/
int iso_ifs_source_clone(IsoFileSource *old_source, IsoFileSource **new_source,
int flag);
#endif /*LIBISO_FSOURCE_H_*/

View File

@ -32,7 +32,7 @@
* @param image
* Location where the image pointer will be stored.
* @return
* 1 sucess, < 0 error
* 1 success, < 0 error
*/
int iso_image_new(const char *name, IsoImage **image)
{

View File

@ -19,6 +19,7 @@
#include "filesrc.h"
#include "eltorito.h"
#include "libisofs.h"
#include "util.h"
#include <stdlib.h>
@ -42,12 +43,11 @@ int get_joliet_name(Ecma119Image *t, IsoNode *iso, uint16_t **name)
iso_msg_debug(t->image->id, "Can't convert %s", iso->name);
return ret;
}
/* TODO #00022 : support relaxed constraints in joliet filenames */
if (iso->type == LIBISO_DIR) {
jname = iso_j_dir_id(ucs_name);
jname = iso_j_dir_id(ucs_name, t->joliet_long_names << 1);
} else {
jname = iso_j_file_id(ucs_name, !!(t->no_force_dots & 2));
jname = iso_j_file_id(ucs_name,
(t->joliet_long_names << 1) | !!(t->no_force_dots & 2));
}
free(ucs_name);
if (jname != NULL) {
@ -303,8 +303,15 @@ int joliet_create_mangled_name(uint16_t *dest, uint16_t *src, int digits,
int ret, pos;
uint16_t *ucsnumber;
char fmt[16];
char nstr[72]; /* The only caller of this function allocates dest with 66
elements and limits digits to < 8 */
char nstr[72];
/* was: The only caller of this function allocates dest
with 66 elements and limits digits to < 8
But this does not match the usage of nstr which has to take
the decimal representation of an int.
*/
if (digits >= 8)
return ISO_ASSERT_FAILURE;
sprintf(fmt, "%%0%dd", digits);
sprintf(nstr, fmt, number);
@ -337,7 +344,7 @@ static
int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
{
int ret;
int i, nchildren;
int i, nchildren, maxchar = 64;
JolietNode **children;
IsoHTable *table;
int need_sort = 0;
@ -345,6 +352,9 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
nchildren = dir->info.dir->nchildren;
children = dir->info.dir->children;
if (t->joliet_long_names)
maxchar = 103;
/* a hash table will temporary hold the names, for fast searching */
ret = iso_htable_create((nchildren * 100) / 80, iso_str_hash,
(compare_function_t)ucscmp, &table);
@ -361,7 +371,7 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
for (i = 0; i < nchildren; ++i) {
uint16_t *name, *ext;
uint16_t full_name[66];
uint16_t full_name[LIBISO_JOLIET_NAME_MAX];
int max; /* computed max len for name, without extension */
int j = i;
int digits = 1; /* characters to change per name */
@ -380,7 +390,7 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
* A max of 7 characters is good enought, it allows handling up to
* 9,999,999 files with same name.
*/
/* Important: joliet_create_mangled_name() relies on digits < 72 */
/* Important: joliet_create_mangled_name() relies on digits < 8 */
while (digits < 8) {
int ok, k;
@ -403,7 +413,7 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
ext = dot + 1;
extlen = ucslen(ext);
max = 65 - extlen - 1 - digits;
max = maxchar + 1 - extlen - 1 - digits;
if (max <= 0) {
/* this can happen if extension is too long */
if (extlen + max > 3) {
@ -413,7 +423,7 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
*/
extlen = extlen + max - 1;
ext[extlen] = 0;
max = 66 - extlen - 1 - digits;
max = maxchar + 2 - extlen - 1 - digits;
} else {
/*
* error, we don't support extensions < 3
@ -430,10 +440,10 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
} else {
/* Directory, or file without extension */
if (children[i]->type == JOLIET_DIR) {
max = 65 - digits;
max = maxchar + 1 - digits;
dot = NULL; /* dots have no meaning in dirs */
} else {
max = 65 - digits;
max = maxchar + 1 - digits;
}
name = full_name;
if (max < ucslen(name)) {
@ -446,7 +456,7 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
ok = 1;
/* change name of each file */
for (k = i; k <= j; ++k) {
uint16_t tmp[66];
uint16_t tmp[LIBISO_JOLIET_NAME_MAX];
while (1) {
ret = joliet_create_mangled_name(tmp, name, digits,
change, ext);

View File

@ -18,6 +18,10 @@
#include "libisofs.h"
#include "ecma119.h"
/* was formerly 66 = 64 + 2. Now 105 = 103 + 2.
*/
#define LIBISO_JOLIET_NAME_MAX 105
enum joliet_node_type {
JOLIET_FILE,
JOLIET_DIR

View File

@ -1,6 +1,10 @@
#ifndef LIBISO_LIBISOFS_H_
#define LIBISO_LIBISOFS_H_
/*
* Copyright (c) 2007-2008 Vreixo Formoso, Mario Danic
* Copyright (c) 2009-2010 Thomas Schmitt
* Copyright (c) 2009-2011 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -24,11 +28,28 @@
*
*/
#ifndef LIBISO_LIBISOFS_H_
#define LIBISO_LIBISOFS_H_
/*
* Normally this API is operated via public functions and opaque object
* handles. But it also exposes several C structures which may be used to
* provide custom functionality for the objects of the API. The same
* structures are used for internal objects of libisofs, too.
* You are not supposed to manipulate the entrails of such objects if they
* are not your own custom extensions.
*
* See for an example IsoStream = struct iso_stream below.
*/
#include <sys/stat.h>
#ifdef HAVE_STDINT_H
#include <stdint.h>
#else
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#endif
#include <stdlib.h>
struct burn_source;
@ -494,6 +515,8 @@ struct IsoFileSource_Iface
* @since 0.6.2
* Version 1 additionally provides function *(get_aa_string)().
* @since 0.6.14
* Version 2 additionally provides function *(clone_src)().
* @since 1.0.2
*/
int version;
@ -728,6 +751,24 @@ struct IsoFileSource_Iface
int (*get_aa_string)(IsoFileSource *src,
unsigned char **aa_string, int flag);
/**
* Produce a copy of a source. It must be possible to operate both source
* objects concurrently.
*
* @param old_src
* The existing source object to be copied
* @param new_stream
* Will return a pointer to the copy
* @param flag
* Bitfield for control purposes. Submit 0 for now.
* The function shall return ISO_STREAM_NO_CLONE on unknown flag bits.
*
* @since 1.0.2
* Present if .version is 2 or higher.
*/
int (*clone_src)(IsoFileSource *old_src, IsoFileSource **new_src,
int flag);
/*
* TODO #00004 Add a get_mime_type() function.
* This can be useful for GUI apps, to choose the icon of the file
@ -752,6 +793,31 @@ struct iso_file_source
#endif /* ! Libisofs_h_as_cpluspluS */
#endif /* ! __cplusplus */
/* A class of IsoStream is implemented by a class description
* IsoStreamIface = struct IsoStream_Iface
* and a structure of data storage for each instance of IsoStream.
* This structure shall be known to the functions of the IsoStreamIface.
* To create a custom IsoStream class:
* - Define the structure of the custom instance data.
* - Implement the methods which are described by the definition of
* struct IsoStream_Iface (see below),
* - Create a static instance of IsoStreamIface which lists the methods as
* C function pointers. (Example in libisofs/stream.c : fsrc_stream_class)
* To create an instance of that class:
* - Allocate sizeof(IsoStream) bytes of memory and initialize it as
* struct iso_stream :
* - Point to the custom IsoStreamIface by member .class .
* - Set member .refcount to 1.
* - Let member .data point to the custom instance data.
*
* Regrettably the choice of the structure member name "class" makes it
* impossible to implement this generic interface in C++ language directly.
* If C++ is absolutely necessary then you will have to make own copies
* of the public API structures. Use other names but take care to maintain
* the same memory layout.
*/
/**
* Representation of file contents. It is an stream of bytes, functionally
* like a pipe.
@ -787,6 +853,7 @@ extern ino_t serial_id;
*
* @since 0.6.4
*/
struct IsoStream_Iface
{
/*
@ -799,6 +866,8 @@ struct IsoStream_Iface
* get_input_stream() added. A filter stream must have version 2.
* Version 3 (since 0.6.20)
* compare() added. A filter stream should have version 3.
* Version 4 (since 1.0.2)
* clone_stream() added.
*/
int version;
@ -841,7 +910,7 @@ struct IsoStream_Iface
off_t (*get_size)(IsoStream *stream);
/**
* Attempts to read up to count bytes from the given stream into
* Attempt to read up to count bytes from the given stream into
* the buffer starting at buf. The implementation has to make sure that
* either the full desired count of bytes is delivered or that the
* next call to this function will return EOF or error.
@ -857,12 +926,9 @@ struct IsoStream_Iface
int (*read)(IsoStream *stream, void *buf, size_t count);
/**
* Whether this IsoStream can be read several times, with the same results.
* For example, a regular file is repeatable, you can read it as many
* times as you want. However, a pipe isn't.
*
* This function doesn't take into account if the file has been modified
* between the two reads.
* Tell whether this IsoStream can be read several times, with the same
* results. For example, a regular file is repeatable, you can read it
* as many times as you want. However, a pipe is not.
*
* @return
* 1 if stream is repeatable, 0 if not,
@ -883,13 +949,13 @@ struct IsoStream_Iface
void (*free)(IsoStream *stream);
/**
* Updates the size of the IsoStream with the current size of the
* underlying source. After calling this, get_size() will return
* the new size. This should never be called after
* iso_image_create_burn_source() was called and the image was not
* completely written. To update the size of all files before written the
* image, you may want to call iso_image_update_sizes() just before
* iso_image_create_burn_source().
* Update the size of the IsoStream with the current size of the underlying
* source, if the source is prone to size changes. After calling this,
* get_size() shall eventually return the new size.
* This will never be called after iso_image_create_burn_source() was
* called and before the image was completely written.
* (The API call to update the size of all files in the image is
* iso_image_update_sizes()).
*
* @return
* 1 if ok, < 0 on error (has to be a valid libisofs error code)
@ -900,15 +966,15 @@ struct IsoStream_Iface
int (*update_size)(IsoStream *stream);
/**
* Obtains the eventual input stream of a filter stream.
* Retrieve the eventual input stream of a filter stream.
*
* @param stream
* The eventual filter stream to be inquired.
* @param flag
* Bitfield for control purposes. Submit 0 for now.
* Bitfield for control purposes. 0 means normal behavior.
* @return
* The input stream, if one exists. Elsewise NULL.
* No extra reference to the stream is taken by this call.
* No extra reference to the stream shall be taken by this call.
*
* @since 0.6.18
* Present if .version is 2 or higher.
@ -920,33 +986,32 @@ struct IsoStream_Iface
* produce the same output. If in any doubt, then this comparison should
* indicate no match. A match might allow hardlinking of IsoFile objects.
*
* This function has to establish an equivalence and order relation:
* If this function cannot accept one of the given stream types, then
* the decision must be delegated to
* iso_stream_cmp_ino(s1, s2, 1);
* This is also appropriate if one has reason to implement stream.cmp_ino()
* without having an own special comparison algorithm.
*
* With filter streams the decision whether the underlying chains of
* streams match should be delegated to
* iso_stream_cmp_ino(iso_stream_get_input_stream(s1, 0),
* iso_stream_get_input_stream(s2, 0), 0);
*
* The stream.cmp_ino() function has to establish an equivalence and order
* relation:
* cmp_ino(A,A) == 0
* cmp_ino(A,B) == -cmp_ino(B,A)
* if cmp_ino(A,B) == 0 && cmp_ino(B,C) == 0 then cmp_ino(A,C) == 0
* if cmp_ino(A,B) < 0 && cmp_ino(B,C) < 0 then cmp_ino(A,C) < 0
*
* A big hazard to the last constraint are tests which do not apply to some
* types of streams. In this case for any A that is applicable and any B
* that is not applicable, cmp_ino(A,B) must have the same non-zero
* result. I.e. a pair of applicable and non-applicable streams must
* return that non-zero result before the test for a pair of applicable
* streams would happen.
* types of streams.Thus it is mandatory to let iso_stream_cmp_ino(s1,s2,1)
* decide in this case.
*
* A function s1.(*cmp_ino)() must only accept stream s2 if function
* s2.(*cmp_ino)() would accept s1. Best is to accept only the own stream
* type or to have the same function for a family of similar stream types.
*
* If the function cannot accept one of the given stream types, then
* the decision must be delegated to
* iso_stream_cmp_ino(s1, s2, 1);
* This is also appropriate if one has reason to implement stream.cmp_ino()
* without special comparison algorithm.
* With filter streams the decision whether the underlying chains of
* streams match should be delegated to
* iso_stream_cmp_ino(iso_stream_get_input_stream(s1, 0),
* iso_stream_get_input_stream(s2, 0), 0);
*
* @param s1
* The first stream to compare. Expect foreign stream types.
* @param s2
@ -959,6 +1024,26 @@ struct IsoStream_Iface
*/
int (*cmp_ino)(IsoStream *s1, IsoStream *s2);
/**
* Produce a copy of a stream. It must be possible to operate both stream
* objects concurrently.
*
* @param old_stream
* The existing stream object to be copied
* @param new_stream
* Will return a pointer to the copy
* @param flag
* Bitfield for control purposes. 0 means normal behavior.
* The function shall return ISO_STREAM_NO_CLONE on unknown flag bits.
* @return
* 1 in case of success, or an error code < 0
*
* @since 1.0.2
* Present if .version is 4 or higher.
*/
int (*clone_stream)(IsoStream *old_stream, IsoStream **new_stream,
int flag);
};
#ifndef __cplusplus
@ -1122,7 +1207,7 @@ int iso_lib_is_compatible(int major, int minor, int micro);
*/
#define iso_lib_header_version_major 1
#define iso_lib_header_version_minor 0
#define iso_lib_header_version_micro 0
#define iso_lib_header_version_micro 6
/**
* Usage discussion:
@ -1344,6 +1429,26 @@ int iso_write_opts_set_hardlinks(IsoWriteOpts *opts, int enable);
*/
int iso_write_opts_set_aaip(IsoWriteOpts *opts, int enable);
/**
* Use this only if you need to reproduce a suboptimal behavior of older
* versions of libisofs. They used address 0 for links and device files,
* and the address of the Volume Descriptor Set Terminator for empty data
* files.
* New versions let symbolic links, device files, and empty data files point
* to a dedicated block of zero-bytes after the end of the directory trees.
* (Single-pass reader libarchive needs to see all directory info before
* processing any data files.)
*
* @param opts
* The option set to be manipulated.
* @param enable
* 1 = use the suboptimal block addresses in the range of 0 to 115.
* 0 = use the address of a block after the directory tree. (Default)
*
* @since 1.0.2
*/
int iso_write_opts_set_old_empty(IsoWriteOpts *opts, int enable);
/**
* Caution: This option breaks any assumptions about names that
* are supported by ECMA-119 specifications.
@ -1480,6 +1585,15 @@ int iso_write_opts_set_relaxed_vol_atts(IsoWriteOpts *opts, int allow);
*/
int iso_write_opts_set_joliet_longer_paths(IsoWriteOpts *opts, int allow);
/**
* Allow leaf names in the Joliet tree to have up to 103 characters.
* Normal limit is 64.
* This breaks Joliet specification. Use with caution.
*
* @since 1.0.6
*/
int iso_write_opts_set_joliet_long_names(IsoWriteOpts *opts, int allow);
/**
* Write Rock Ridge info as of specification RRIP-1.10 rather than RRIP-1.12:
* signature "RRIP_1991A" rather than "IEEE_1282", field PX without file
@ -1854,7 +1968,13 @@ int iso_write_opts_set_fifo_size(IsoWriteOpts *opts, size_t fifo_size);
* iso_write_opts_set_partition_img() for partition numbers 2
* to 8.
* This will overwrite the first 512 bytes of the submitted
* data.
* bit8-9= Only with System area type 0 = MBR
* @since 1.0.4
* Cylinder alignment mode eventually pads the image to make it
* end at a cylinder boundary.
* 0 = auto (align if bit1)
* 1 = always align to cylinder boundary
* 2 = never align to cylinder boundary
* @param flag
* bit0 = invalidate any attached system area data. Same as data == NULL
* (This re-activates eventually loaded image System Area data.
@ -1964,9 +2084,9 @@ int iso_write_opts_set_part_offset(IsoWriteOpts *opts,
tests. It can be prevented by ./configure option --disable-libjte .
@since 0.6.38
*/
#define iso_libjte_req_major 0
#define iso_libjte_req_minor 1
#define iso_libjte_req_micro 1
#define iso_libjte_req_major 1
#define iso_libjte_req_minor 0
#define iso_libjte_req_micro 0
/**
* Associate a libjte environment object to the upcomming write run.
@ -2226,8 +2346,10 @@ int iso_read_opts_set_no_aaip(IsoReadOpts *opts, int noaaip);
* @param opts
* The option set to be manipulated
* @param no_md5
* 0 = Read MD5 array if available, refuse on non-matching MD5 tags
* 1 = Do not read MD5 checksum array
* 0 = Read Md% array if available
* 2 = Read MD5 array, but do not check MD5 tags
* @since 1.0.4
* All other values are reserved.
*
* @since 0.6.22
@ -3015,6 +3137,8 @@ int el_torito_seems_boot_info_table(ElToritoBootImage *bootimg, int flag);
* Specifies options for ISOLINUX or GRUB boot images. This should only be used
* if the type of boot image is known.
*
* @param bootimg
* The image to set options on
* @param options
* bitmask style flag. The following values are defined:
*
@ -3042,8 +3166,6 @@ int el_torito_seems_boot_info_table(ElToritoBootImage *bootimg, int flag);
* For that you need isolinux.bin from SYSLINUX 3.72 or later.
* IMPORTANT: The application has to take care that the image
* on media gets padded up to the next full MB.
* @param bootimg
* The image to set options on
* @param flag
* Reserved for future usage, set to 0.
* @return
@ -3176,9 +3298,9 @@ void iso_node_unref(IsoNode *node);
enum IsoNodeType iso_node_get_type(IsoNode *node);
/**
* Function to handle particular extended information. The function
* pointer acts as an identifier for the type of the information. Structs
* with same information type must use the same function.
* Class of functions to handle particular extended information. A function
* instance acts as an identifier for the type of the information. Structs
* with same information type must use a pointer to the same function.
*
* @param data
* Attached data
@ -3233,6 +3355,20 @@ int iso_node_add_xinfo(IsoNode *node, iso_node_xinfo_func proc, void *data);
*/
int iso_node_remove_xinfo(IsoNode *node, iso_node_xinfo_func proc);
/**
* Remove all extended information from the given node.
*
* @param node
* The node where to remove all extended info
* @param flag
* Bitfield for control purposes, unused yet, submit 0
* @return
* 1 on success, < 0 on error
*
* @since 1.0.2
*/
int iso_node_remove_all_xinfo(IsoNode *node, int flag);
/**
* Get the given extended info (defined by the proc function) from the
* given node.
@ -3252,6 +3388,102 @@ int iso_node_remove_xinfo(IsoNode *node, iso_node_xinfo_func proc);
*/
int iso_node_get_xinfo(IsoNode *node, iso_node_xinfo_func proc, void **data);
/**
* Get the next pair of function pointer and data of an iteration of the
* list of extended informations. Like:
* iso_node_xinfo_func proc;
* void *handle = NULL, *data;
* while (iso_node_get_next_xinfo(node, &handle, &proc, &data) == 1) {
* ... make use of proc and data ...
* }
* The iteration allocates no memory. So you may end it without any disposal
* action.
* IMPORTANT: Do not continue iterations after manipulating the extended
* information of a node. Memory corruption hazard !
* @param node
* The node to inquire
* @param handle
* The opaque iteration handle. Initialize iteration by submitting
* a pointer to a void pointer with value NULL.
* Do not alter its content until iteration has ended.
* @param proc
* The function pointer which serves as key
* @param data
* Will be filled with the extended info corresponding to the given proc
* function
* @return
* 1 on success
* 0 if iteration has ended (proc and data are invalid then)
* < 0 on error
*
* @since 1.0.2
*/
int iso_node_get_next_xinfo(IsoNode *node, void **handle,
iso_node_xinfo_func *proc, void **data);
/**
* Class of functions to clone extended information. A function instance gets
* associated to a particular iso_node_xinfo_func instance by function
* iso_node_xinfo_make_clonable(). This is a precondition to have IsoNode
* objects clonable which carry data for a particular iso_node_xinfo_func.
*
* @param old_data
* Data item to be cloned
* @param new_data
* Shall return the cloned data item
* @param flag
* Unused yet, submit 0
* The function shall return ISO_XINFO_NO_CLONE on unknown flag bits.
* @return
* > 0 number of allocated bytes
* 0 no size info is available
* < 0 error
*
* @since 1.0.2
*/
typedef int (*iso_node_xinfo_cloner)(void *old_data, void **new_data,int flag);
/**
* Associate a iso_node_xinfo_cloner to a particular class of extended
* information in order to make it clonable.
*
* @param proc
* The key and disposal function which identifies the particular
* extended information class.
* @param cloner
* The cloner function which shall be associated with proc.
* @param flag
* Unused yet, submit 0
* @return
* 1 success, < 0 error
*
* @since 1.0.2
*/
int iso_node_xinfo_make_clonable(iso_node_xinfo_func proc,
iso_node_xinfo_cloner cloner, int flag);
/**
* Inquire the registered cloner function for a particular class of
* extended information.
*
* @param proc
* The key and disposal function which identifies the particular
* extended information class.
* @param cloner
* Will return the cloner function which is associated with proc, or NULL.
* @param flag
* Unused yet, submit 0
* @return
* 1 success, 0 no cloner registered for proc, < 0 error
*
* @since 1.0.2
*/
int iso_node_xinfo_get_cloner(iso_node_xinfo_func proc,
iso_node_xinfo_cloner *cloner, int flag);
/**
* Set the name of a node. Note that if the node is already added to a dir
* this can fail if dir already contains a node with the new name.
@ -3631,23 +3863,39 @@ int iso_dir_iter_take(IsoDirIter *iter);
/**
* Removes a child from a directory during an iteration and unref() it.
* It's like iso_node_remove(), but to be used during a directory iteration.
* The node removed will be the last returned by the iteration.
* Like iso_node_remove(), but to be used during a directory iteration.
* The node removed will be the one returned by the previous iteration.
*
* If you call this function twice without calling iso_dir_iter_next between
* them is not allowed and you will get an ISO_ERROR in second call.
* It is not allowed to call this function twice without calling
* iso_dir_iter_next inbetween.
*
* @return
* 1 on succes, < 0 error
* Possible errors:
* ISO_NULL_POINTER, if iter is NULL
* ISO_ERROR, on wrong iter usage, for example by call this before
* ISO_ERROR, on wrong iter usage, for example by calling this before
* iso_dir_iter_next.
*
* @since 0.6.2
*/
int iso_dir_iter_remove(IsoDirIter *iter);
/**
* Removes a node by iso_node_remove() or iso_dir_iter_remove(). If the node
* is a directory then the whole tree of nodes underneath is removed too.
*
* @param node
* The node to be removed.
* @param iter
* If not NULL, then the node will be removed by iso_dir_iter_remove(iter)
* else it will be removed by iso_node_remove(node).
* @return
* 1 is success, <0 indicates error
*
* @since 1.0.2
*/
int iso_node_remove_tree(IsoNode *node, IsoDirIter *boss_iter);
/**
* @since 0.6.4
@ -4384,6 +4632,57 @@ int iso_tree_add_new_cut_out_node(IsoImage *image, IsoDir *parent,
off_t offset, off_t size,
IsoNode **node);
/**
* Create a copy of the given node under a different path. If the node is
* actually a directory then clone its whole subtree.
* This call may fail because an IsoFile is encountered which gets fed by an
* IsoStream which cannot be cloned. See also IsoStream_Iface method
* clone_stream().
* Surely clonable node types are:
* IsoDir,
* IsoSymlink,
* IsoSpecial,
* IsoFile from a loaded ISO image,
* IsoFile referring to local filesystem files,
* IsoFile created by iso_tree_add_new_file
* from a stream created by iso_memory_stream_new(),
* IsoFile created by iso_tree_add_new_cut_out_node()
* Silently ignored are nodes of type IsoBoot.
* An IsoFile node with IsoStream filters can be cloned if all those filters
* are clonable and the node would be clonable without filter.
* Clonable IsoStream filters are created by:
* iso_file_add_zisofs_filter()
* iso_file_add_gzip_filter()
* iso_file_add_external_filter()
* An IsoNode with extended information as of iso_node_add_xinfo() can only be
* cloned if each of the iso_node_xinfo_func instances is associated to a
* clone function. See iso_node_xinfo_make_clonable().
* All internally used classes of extended information are clonable.
*
* @param node
* The node to be cloned.
* @param new_parent
* The existing directory node where to insert the cloned node.
* @param new_name
* The name for the cloned node. It must not yet exist in new_parent,
* unless it is a directory and node is a directory and flag bit0 is set.
* @param new_node
* Will return a pointer (without reference) to the newly created clone.
* @param flag
* Bitfield for control purposes. Submit any undefined bits as 0.
* bit0= Merge directories rather than returning ISO_NODE_NAME_NOT_UNIQUE.
* This will not allow to overwrite any existing node.
* Attributes of existing directories will not be overwritten.
* @return
* <0 means error, 1 = new node created,
* 2 = if flag bit0 is set: new_node is a directory which already existed.
*
* @since 1.0.2
*/
int iso_tree_clone(IsoNode *node,
IsoDir *new_parent, char *new_name, IsoNode **new_node,
int flag);
/**
* Add the contents of a dir to a given directory of the iso tree.
*
@ -4882,11 +5181,12 @@ int iso_file_source_readdir(IsoFileSource *src, IsoFileSource **child);
* @param src
* An IsoFileSource corresponding to a symbolic link.
* @param buf
* allocated buffer of at least bufsiz bytes.
* The dest. will be copied there, and it will be NULL-terminated
* Allocated buffer of at least bufsiz bytes.
* The destination string will be copied there, and it will be 0-terminated
* if the return value indicates success or ISO_RR_PATH_TOO_LONG.
* @param bufsiz
* characters to be copied. Destination link will be truncated if
* it is larger than given size. This includes the 0x0 character.
* Maximum number of buf characters + 1. The string will be truncated if
* it is larger than bufsiz - 1 and ISO_RR_PATH_TOO_LONG. will be returned.
* @return
* 1 on success, < 0 on error
* Error codes:
@ -4897,6 +5197,7 @@ int iso_file_source_readdir(IsoFileSource *src, IsoFileSource **child);
* ISO_OUT_OF_MEM
* ISO_FILE_BAD_PATH
* ISO_FILE_DOESNT_EXIST
* ISO_RR_PATH_TOO_LONG (@since 1.0.6)
*
* @since 0.6.2
*/
@ -5183,6 +5484,30 @@ char *iso_stream_get_source_path(IsoStream *stream, int flag);
*/
int iso_stream_cmp_ino(IsoStream *s1, IsoStream *s2, int flag);
/**
* Produce a copy of a stream. It must be possible to operate both stream
* objects concurrently. The success of this function depends on the
* existence of a IsoStream_Iface.clone_stream() method with the stream
* and with its eventual subordinate streams.
* See iso_tree_clone() for a list of surely clonable built-in streams.
*
* @param old_stream
* The existing stream object to be copied
* @param new_stream
* Will return a pointer to the copy
* @param flag
* Bitfield for control purposes. Submit 0 for now.
* @return
* >0 means success
* ISO_STREAM_NO_CLONE is issued if no .clone_stream() exists
* other error return values < 0 may occur depending on kind of stream
*
* @since 1.0.2
*/
int iso_stream_clone(IsoStream *old_stream, IsoStream **new_stream, int flag);
/* --------------------------------- AAIP --------------------------------- */
/**
@ -5209,6 +5534,12 @@ int iso_stream_cmp_ino(IsoStream *s1, IsoStream *s2, int flag);
*/
int aaip_xinfo_func(void *data, int flag);
/**
* The iso_node_xinfo_cloner function which gets associated to aaip_xinfo_func
* by iso_init() resp. iso_init_with_flag() via iso_node_xinfo_make_clonable().
* @since 1.0.2
*/
int aaip_xinfo_cloner(void *old_data, void **new_data, int flag);
/**
* Get the eventual ACLs which are associated with the node.
@ -6488,6 +6819,27 @@ int iso_md5_match(char first_md5[16], char second_md5[16]);
(FAILURE, HIGH, -373) */
#define ISO_NAME_NEEDS_TRANSL 0xE830FE8B
/** Data file input stream object offers no cloning method
(FAILURE, HIGH, -374) */
#define ISO_STREAM_NO_CLONE 0xE830FE8A
/** Extended information class offers no cloning method
(FAILURE, HIGH, -375) */
#define ISO_XINFO_NO_CLONE 0xE830FE89
/** Found copied superblock checksum tag (WARNING, HIGH, -376) */
#define ISO_MD5_TAG_COPIED 0xD030FE88
/** Rock Ridge leaf name too long (FAILURE, HIGH, -377) */
#define ISO_RR_NAME_TOO_LONG 0xE830FE87
/** Reserved Rock Ridge leaf name (FAILURE, HIGH, -378) */
#define ISO_RR_NAME_RESERVED 0xE830FE86
/** Rock Ridge path too long (FAILURE, HIGH, -379) */
#define ISO_RR_PATH_TOO_LONG 0xE830FE85
/* Internal developer note:
Place new error codes directly above this comment.

View File

@ -1,5 +1,6 @@
LIBISOFS6 {
global:
aaip_xinfo_cloner;
aaip_xinfo_func;
el_torito_get_bootable;
el_torito_get_boot_media_type;
@ -156,6 +157,7 @@ iso_node_get_hidden;
iso_node_get_mode;
iso_node_get_mtime;
iso_node_get_name;
iso_node_get_next_xinfo;
iso_node_get_old_image_lba;
iso_node_get_parent;
iso_node_get_permissions;
@ -166,6 +168,8 @@ iso_node_get_xinfo;
iso_node_lookup_attr;
iso_node_ref;
iso_node_remove;
iso_node_remove_all_xinfo;
iso_node_remove_tree;
iso_node_remove_xinfo;
iso_node_set_acl_text;
iso_node_set_atime;
@ -180,6 +184,8 @@ iso_node_set_sort_weight;
iso_node_set_uid;
iso_node_take;
iso_node_unref;
iso_node_xinfo_get_cloner;
iso_node_xinfo_make_clonable;
iso_node_zf_by_magic;
iso_obtain_msgs;
iso_read_image_features_destroy;
@ -210,6 +216,7 @@ iso_set_local_charset;
iso_set_msgs_severities;
iso_sev_to_text;
iso_special_get_dev;
iso_stream_clone;
iso_stream_close;
iso_stream_cmp_ino;
iso_stream_get_external_filter;
@ -235,6 +242,7 @@ iso_tree_add_new_node;
iso_tree_add_new_special;
iso_tree_add_new_symlink;
iso_tree_add_node;
iso_tree_clone;
iso_tree_get_follow_symlinks;
iso_tree_get_ignore_hidden;
iso_tree_get_ignore_special;
@ -274,10 +282,12 @@ iso_write_opts_set_hardlinks;
iso_write_opts_set_iso1999;
iso_write_opts_set_iso_level;
iso_write_opts_set_joliet;
iso_write_opts_set_joliet_long_names;
iso_write_opts_set_joliet_longer_paths;
iso_write_opts_set_max_37_char_filenames;
iso_write_opts_set_ms_block;
iso_write_opts_set_no_force_dots;
iso_write_opts_set_old_empty;
iso_write_opts_set_omit_version_numbers;
iso_write_opts_set_output_charset;
iso_write_opts_set_overwrite_buf;

View File

@ -4,7 +4,15 @@
#endif
#include <ctype.h>
#ifdef HAVE_STDINT_H
#include <stdint.h>
#else
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#endif
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
@ -378,21 +386,19 @@ int make_isolinux_mbr(int32_t *img_blocks, uint32_t boot_lba,
int part_offset, int part_number, int fs_type,
uint8_t *buf, int flag)
{
uint32_t spc, id, part, nominal_part_size;
uint32_t id, part, nominal_part_size;
off_t hd_img_blocks, hd_boot_lba;
char *wpt;
/* For generating a weak random number */
struct timeval tv;
struct timezone tz;
/* Pad image_size to a multiple of sector_count*head_count
*/
spc = head_count * sector_count;
hd_img_blocks = ((off_t) *img_blocks) * (off_t) 4;
if (hd_img_blocks % spc) {
hd_img_blocks += spc - (hd_img_blocks % spc);
*img_blocks = hd_img_blocks / 4 + !!(hd_img_blocks % 4);
}
/* Padding of image_size to a multiple of sector_count*head_count
happens already at compute time and is implemented by
an appropriate increase of Ecma119Image->tail_blocks.
*/
wpt = (char *) buf + 432;

View File

@ -12,7 +12,14 @@
#include "../config.h"
#endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
#else
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#endif
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
@ -417,6 +424,22 @@ int checksum_cx_xinfo_func(void *data, int flag)
return 1;
}
/* The iso_node_xinfo_cloner function which gets associated to
* checksum_cx_xinfo_func by iso_init() resp. iso_init_with_flag() via
* iso_node_xinfo_make_clonable()
*/
int checksum_cx_xinfo_cloner(void *old_data, void **new_data, int flag)
{
*new_data = NULL;
if (flag)
return ISO_XINFO_NO_CLONE;
if (old_data == NULL)
return 0;
/* data is an int disguised as pointer. It does not point to memory. */
*new_data = old_data;
return 0;
}
/* Function to identify and manage md5 sums of unspecified providence stored
* directly in this xinfo.
@ -429,6 +452,24 @@ int checksum_md5_xinfo_func(void *data, int flag)
return 1;
}
/* The iso_node_xinfo_cloner function which gets associated to
* checksum_md5_xinfo_func by iso_init() resp. iso_init_with_flag() via
* iso_node_xinfo_make_clonable()
*/
int checksum_md5_xinfo_cloner(void *old_data, void **new_data, int flag)
{
*new_data = NULL;
if (flag)
return ISO_XINFO_NO_CLONE;
if (old_data == NULL)
return 0;
*new_data = calloc(1, 16);
if (*new_data == NULL)
return ISO_OUT_OF_MEM;
memcpy(*new_data, old_data, 16);
return 16;
}
/* ----------------------------------------------------------------------- */

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2011 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -36,6 +37,7 @@
#include "messages.h"
#include "util.h"
#include "node.h"
/*
@ -79,11 +81,76 @@ int abort_threshold = LIBISO_MSGS_SEV_FAILURE;
struct libiso_msgs *libiso_msgr = NULL;
/* ------------- List of xinfo clone functions ----------- */
struct iso_xinfo_cloner_assoc {
iso_node_xinfo_func proc;
iso_node_xinfo_cloner cloner;
struct iso_xinfo_cloner_assoc *next;
};
struct iso_xinfo_cloner_assoc *iso_xinfo_cloner_list = NULL;
/* API */
int iso_node_xinfo_make_clonable(iso_node_xinfo_func proc,
iso_node_xinfo_cloner cloner, int flag)
{
struct iso_xinfo_cloner_assoc *assoc;
/* Look for existing assoc of proc */
for (assoc = iso_xinfo_cloner_list; assoc != NULL; assoc = assoc->next)
if (assoc->proc == proc)
break;
if (assoc == NULL) {
assoc = calloc(1, sizeof(struct iso_xinfo_cloner_assoc));
if (assoc == NULL)
return ISO_OUT_OF_MEM;
assoc->proc = proc;
assoc->next = iso_xinfo_cloner_list;
iso_xinfo_cloner_list = assoc;
}
assoc->cloner = cloner;
return ISO_SUCCESS;
}
/* API */
int iso_node_xinfo_get_cloner(iso_node_xinfo_func proc,
iso_node_xinfo_cloner *cloner, int flag)
{
struct iso_xinfo_cloner_assoc *assoc;
*cloner = NULL;
for (assoc = iso_xinfo_cloner_list; assoc != NULL; assoc = assoc->next) {
if (assoc->proc != proc)
continue;
*cloner = assoc->cloner;
return 1;
}
return 0;
}
static
int iso_node_xinfo_dispose_cloners(int flag)
{
struct iso_xinfo_cloner_assoc *assoc, *next;
for (assoc = iso_xinfo_cloner_list; assoc != NULL; assoc = next) {
next = assoc->next;
free((char *) assoc);
}
return(1);
}
/* ------------- End of xinfo clone functions list ----------- */
/*
@param flag bit0= do not set up locale by LC_* environment variables
*/
int iso_init_with_flag(int flag)
{
int ret;
#ifdef Libisofs_with_libjtE
@ -119,7 +186,6 @@ LIBJTE_MISCONFIGURATION_ = 0;
#endif /* Libisofs_with_libjtE */
if (! (flag & 1)) {
iso_init_locale(0);
}
@ -129,10 +195,29 @@ LIBJTE_MISCONFIGURATION_ = 0;
}
libiso_msgs_set_severities(libiso_msgr, LIBISO_MSGS_SEV_NEVER,
LIBISO_MSGS_SEV_FATAL, "libisofs: ", 0);
ret = iso_node_xinfo_make_clonable(aaip_xinfo_func, aaip_xinfo_cloner, 0);
if (ret < 0)
return ret;
ret = iso_node_xinfo_make_clonable(checksum_cx_xinfo_func,
checksum_cx_xinfo_cloner, 0);
if (ret < 0)
return ret;
ret = iso_node_xinfo_make_clonable(checksum_md5_xinfo_func,
checksum_md5_xinfo_cloner, 0);
if (ret < 0)
return ret;
ret = iso_node_xinfo_make_clonable(zisofs_zf_xinfo_func,
zisofs_zf_xinfo_cloner, 0);
if (ret < 0)
return ret;
ret = iso_node_xinfo_make_clonable(iso_px_ino_xinfo_func,
iso_px_ino_xinfo_cloner, 0);
if (ret < 0)
return ret;
return 1;
}
int iso_init()
{
return iso_init_with_flag(0);
@ -141,6 +226,7 @@ int iso_init()
void iso_finish()
{
libiso_msgs_destroy(&libiso_msgr, 0);
iso_node_xinfo_dispose_cloners(0);
}
int iso_set_abort_severity(char *severity)
@ -363,6 +449,18 @@ const char *iso_error_to_msg(int errcode)
return "Displacement offset leads outside 32 bit range";
case ISO_NAME_NEEDS_TRANSL:
return "File name cannot be written into ECMA-119 untranslated";
case ISO_STREAM_NO_CLONE:
return "Data file input stream object offers no cloning method";
case ISO_XINFO_NO_CLONE:
return "Extended information class offers no cloning method";
case ISO_MD5_TAG_COPIED:
return "Found copied superblock checksum tag";
case ISO_RR_NAME_TOO_LONG:
return "Rock Ridge leaf name too long";
case ISO_RR_NAME_RESERVED:
return "Reserved Rock Ridge leaf name";
case ISO_RR_PATH_TOO_LONG:
return "Rock Ridge path too long";
default:
return "Unknown error";
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 Thomas Schmitt
* Copyright (c) 2009 - 2011 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -28,11 +28,6 @@
#include <stdio.h>
#ifndef PATH_MAX
#define PATH_MAX Libisofs_default_path_maX
#endif
struct dir_iter_data
{
/* points to the last visited child, to NULL before start */
@ -226,6 +221,89 @@ int iso_node_get_xinfo(IsoNode *node, iso_node_xinfo_func proc, void **data)
return 0;
}
/* API */
int iso_node_get_next_xinfo(IsoNode *node, void **handle,
iso_node_xinfo_func *proc, void **data)
{
IsoExtendedInfo *xinfo;
if (node == NULL || handle == NULL || proc == NULL || data == NULL)
return ISO_NULL_POINTER;
*proc = NULL;
*data = NULL;
xinfo = (IsoExtendedInfo *) *handle;
if (xinfo == NULL)
xinfo = node->xinfo;
else
xinfo = xinfo->next;
*handle = xinfo;
if (xinfo == NULL)
return 0;
*proc = xinfo->process;
*data = xinfo->data;
return ISO_SUCCESS;
}
int iso_node_remove_all_xinfo(IsoNode *node, int flag)
{
IsoExtendedInfo *pos, *next;
for (pos = node->xinfo; pos != NULL; pos = next) {
next = pos->next;
pos->process(pos->data, 1);
free((char *) pos);
}
node->xinfo = NULL;
return ISO_SUCCESS;
}
static
int iso_node_revert_xinfo_list(IsoNode *node, int flag)
{
IsoExtendedInfo *pos, *next, *prev = NULL;
for (pos = node->xinfo; pos != NULL; pos = next) {
next = pos->next;
pos->next = prev;
prev = pos;
}
node->xinfo = prev;
return ISO_SUCCESS;
}
int iso_node_clone_xinfo(IsoNode *from_node, IsoNode *to_node, int flag)
{
void *handle = NULL, *data, *new_data;
iso_node_xinfo_func proc;
iso_node_xinfo_cloner cloner;
int ret;
iso_node_remove_all_xinfo(to_node, 0);
while (1) {
ret = iso_node_get_next_xinfo(from_node, &handle, &proc, &data);
if (ret <= 0)
break;
ret = iso_node_xinfo_get_cloner(proc, &cloner, 0);
if (ret == 0)
return ISO_XINFO_NO_CLONE;
if (ret < 0)
return ret;
ret = (*cloner)(data, &new_data, 0);
if (ret < 0)
break;
ret = iso_node_add_xinfo(to_node, proc, new_data);
if (ret < 0)
break;
}
if (ret < 0) {
iso_node_remove_all_xinfo(to_node, 0);
} else {
ret = iso_node_revert_xinfo_list(to_node, 0);
}
return ret;
}
/**
* Get the type of an IsoNode.
*/
@ -242,6 +320,7 @@ enum IsoNodeType iso_node_get_type(IsoNode *node)
int iso_node_set_name(IsoNode *node, const char *name)
{
char *new;
int ret;
if ((IsoNode*)node->parent == node) {
/* you can't change name of the root node */
@ -249,9 +328,9 @@ int iso_node_set_name(IsoNode *node, const char *name)
}
/* check if the name is valid */
if (!iso_node_is_valid_name(name)) {
return ISO_WRONG_ARG_VALUE;
}
ret = iso_node_is_valid_name(name);
if (ret < 0)
return ret;
if (node->parent != NULL) {
/* check if parent already has a node with same name */
@ -651,6 +730,9 @@ int iso_node_take(IsoNode *node)
if (dir == NULL) {
return ISO_NODE_NOT_ADDED_TO_DIR;
}
/* >>> Do not take root directory ! (dir == node) ? */;
pos = iso_dir_find_node(dir, node);
if (pos == NULL) {
/* should never occur */
@ -686,6 +768,44 @@ int iso_node_remove(IsoNode *node)
return ret;
}
/* API */
int iso_node_remove_tree(IsoNode *node, IsoDirIter *boss_iter)
{
IsoDirIter *iter = NULL;
IsoNode *sub_node;
int ret;
if (node->type != LIBISO_DIR) {
/* >>> Do not remove root directory ! (node->parent == node) ? */;
ret = iso_dir_get_children((IsoDir *) node, &iter);
if (ret < 0)
goto ex;
while(1) {
ret = iso_dir_iter_next(iter, &sub_node);
if (ret == 0)
break;
ret = iso_node_remove_tree(sub_node, iter);
if (ret < 0)
goto ex;
}
if (node->parent == NULL) {
/* node is not grafted into a boss directory */
iso_node_unref(node);
goto ex;
}
}
if (boss_iter != NULL)
ret = iso_dir_iter_remove(boss_iter);
else
ret = iso_node_remove(node);
ex:;
if (iter != NULL)
iso_dir_iter_free(iter);
return ret;
}
/*
* Get the parent of the given iso tree node. No extra ref is added to the
* returned directory, you must take your ref. with iso_node_ref() if you
@ -881,10 +1001,11 @@ const char *iso_symlink_get_dest(const IsoSymlink *link)
int iso_symlink_set_dest(IsoSymlink *link, const char *dest)
{
char *d;
if (!iso_node_is_valid_link_dest(dest)) {
/* guard against null or empty dest */
return ISO_WRONG_ARG_VALUE;
}
int ret;
ret = iso_node_is_valid_link_dest(dest);
if (ret < 0)
return ret;
d = strdup(dest);
if (d == NULL) {
return ISO_OUT_OF_MEM;
@ -1035,22 +1156,23 @@ int iso_node_is_valid_name(const char *name)
{
/* a name can't be NULL */
if (name == NULL) {
return 0;
return ISO_NULL_POINTER;
}
/* guard against the empty string or big names... */
if (name[0] == '\0' || strlen(name) > 255) {
return 0;
}
if (name[0] == '\0')
return ISO_RR_NAME_RESERVED;
if (strlen(name) > LIBISOFS_NODE_NAME_MAX)
return ISO_RR_NAME_TOO_LONG;
/* ...against "." and ".." names... */
if (!strcmp(name, ".") || !strcmp(name, "..")) {
return 0;
return ISO_RR_NAME_RESERVED;
}
/* ...and against names with '/' */
if (strchr(name, '/') != NULL) {
return 0;
return ISO_RR_NAME_RESERVED;
}
return 1;
}
@ -1068,13 +1190,14 @@ int iso_node_is_valid_link_dest(const char *dest)
/* a dest can't be NULL */
if (dest == NULL) {
return 0;
return ISO_NULL_POINTER;
}
/* guard against the empty string or big dest... */
if (dest[0] == '\0' || strlen(dest) > PATH_MAX) {
return 0;
}
if (dest[0] == '\0')
return ISO_RR_NAME_RESERVED;
if (strlen(dest) > LIBISOFS_NODE_PATH_MAX)
return ISO_RR_PATH_TOO_LONG;
/* check that all components are valid */
if (!strcmp(dest, "/")) {
@ -1084,7 +1207,7 @@ int iso_node_is_valid_link_dest(const char *dest)
ptr = strdup(dest);
if (ptr == NULL) {
return 0;
return ISO_OUT_OF_MEM;
}
ret = 1;
@ -1092,7 +1215,7 @@ int iso_node_is_valid_link_dest(const char *dest)
while (component) {
if (strcmp(component, ".") && strcmp(component, "..")) {
ret = iso_node_is_valid_name(component);
if (ret == 0) {
if (ret < 0) {
break;
}
}
@ -1251,15 +1374,16 @@ int iso_node_new_root(IsoDir **root)
int iso_node_new_dir(char *name, IsoDir **dir)
{
IsoDir *new;
int ret;
if (dir == NULL || name == NULL) {
return ISO_NULL_POINTER;
}
/* check if the name is valid */
if (!iso_node_is_valid_name(name)) {
return ISO_WRONG_ARG_VALUE;
}
ret = iso_node_is_valid_name(name);
if (ret < 0)
return ret;
new = calloc(1, sizeof(IsoDir));
if (new == NULL) {
@ -1276,15 +1400,16 @@ int iso_node_new_dir(char *name, IsoDir **dir)
int iso_node_new_file(char *name, IsoStream *stream, IsoFile **file)
{
IsoFile *new;
int ret;
if (file == NULL || name == NULL || stream == NULL) {
return ISO_NULL_POINTER;
}
/* check if the name is valid */
if (!iso_node_is_valid_name(name)) {
return ISO_WRONG_ARG_VALUE;
}
ret = iso_node_is_valid_name(name);
if (ret < 0)
return ret;
new = calloc(1, sizeof(IsoFile));
if (new == NULL) {
@ -1304,21 +1429,21 @@ int iso_node_new_file(char *name, IsoStream *stream, IsoFile **file)
int iso_node_new_symlink(char *name, char *dest, IsoSymlink **link)
{
IsoSymlink *new;
int ret;
if (link == NULL || name == NULL || dest == NULL) {
return ISO_NULL_POINTER;
}
/* check if the name is valid */
if (!iso_node_is_valid_name(name)) {
return ISO_WRONG_ARG_VALUE;
}
ret = iso_node_is_valid_name(name);
if (ret < 0)
return ret;
/* check if destination is valid */
if (!iso_node_is_valid_link_dest(dest)) {
/* guard against null or empty dest */
return ISO_WRONG_ARG_VALUE;
}
ret = iso_node_is_valid_link_dest(dest);
if (ret < 0)
return ret;
new = calloc(1, sizeof(IsoSymlink));
if (new == NULL) {
@ -1340,6 +1465,7 @@ int iso_node_new_special(char *name, mode_t mode, dev_t dev,
IsoSpecial **special)
{
IsoSpecial *new;
int ret;
if (special == NULL || name == NULL) {
return ISO_NULL_POINTER;
@ -1349,9 +1475,9 @@ int iso_node_new_special(char *name, mode_t mode, dev_t dev,
}
/* check if the name is valid */
if (!iso_node_is_valid_name(name)) {
return ISO_WRONG_ARG_VALUE;
}
ret = iso_node_is_valid_name(name);
if (ret < 0)
return ret;
new = calloc(1, sizeof(IsoSpecial));
if (new == NULL) {
@ -2153,6 +2279,23 @@ int zisofs_zf_xinfo_func(void *data, int flag)
return 1;
}
/* The iso_node_xinfo_cloner function which gets associated to
* zisofs_zf_xinfo_func by iso_init() resp. iso_init_with_flag() via
* iso_node_xinfo_make_clonable()
*/
int zisofs_zf_xinfo_cloner(void *old_data, void **new_data, int flag)
{
*new_data = NULL;
if (flag)
return ISO_XINFO_NO_CLONE;
if (old_data == NULL)
return 0;
*new_data = calloc(1, sizeof(struct zisofs_zf_info));
if (*new_data == NULL)
return ISO_OUT_OF_MEM;
memcpy(*new_data, old_data, sizeof(struct zisofs_zf_info));
return (int) sizeof(struct zisofs_zf_info);
}
/* Checks whether a file effectively bears a zisofs file header and eventually
* marks this by a struct zisofs_zf_info as xinfo of the file node.
@ -2274,6 +2417,21 @@ int iso_px_ino_xinfo_func(void *data, int flag)
return 1;
}
/* The iso_node_xinfo_cloner function which gets associated to
* iso_px_ino_xinfo_func by iso_init() resp. iso_init_with_flag() via
* iso_node_xinfo_make_clonable()
*/
int iso_px_ino_xinfo_cloner(void *old_data, void **new_data, int flag)
{
*new_data = NULL;
if (flag)
return ISO_XINFO_NO_CLONE;
*new_data = calloc(1, sizeof(ino_t));
if (*new_data == NULL)
return ISO_OUT_OF_MEM;
memcpy(*new_data, old_data, sizeof(ino_t));
return (int) sizeof(ino_t);
}
/*
* @param flag
@ -2364,7 +2522,6 @@ int iso_node_set_ino_xinfo(IsoNode *node, ino_t ino, int flag)
return ret;
}
int iso_node_set_ino(IsoNode *node, ino_t ino, int flag)
{
int ret;

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 Thomas Schmitt
* Copyright (c) 2009 - 2011 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -20,7 +20,38 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#ifdef HAVE_STDINT_H
#include <stdint.h>
#else
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#endif
/* Maximum length of a leaf name in the libisofs node tree. This is currently
restricted by the implemented maximum length of a Rock Ridge name.
This might later become larger and may then be limited to smaller values.
Rock Ridge specs do not impose an explicit limit on name length.
But 255 is also specified by
http://pubs.opengroup.org/onlinepubs/009695399/basedefs/limits.h.html
which says
NAME_MAX >= _XOPEN_NAME_MAX = 255
*/
#define LIBISOFS_NODE_NAME_MAX 255
/* Maximum length of a path in the libisofs node tree.
Rock Ridge specs do not impose an explicit limit on path length.
http://pubs.opengroup.org/onlinepubs/009695399/basedefs/limits.h.html
says
PATH_MAX >= _XOPEN_PATH_MAX = 1024
*/
#define LIBISOFS_NODE_PATH_MAX 1024
/**
* The extended information is a way to attach additional information to each
@ -113,6 +144,7 @@ struct Iso_Dir
IsoNode *children; /**< list of children. ptr to first child */
};
/* IMPORTANT: Any change must be reflected by iso_tree_clone_file. */
struct Iso_File
{
IsoNode node;
@ -277,7 +309,7 @@ int iso_node_new_special(char *name, mode_t mode, dev_t dev,
* Check if a given name is valid for an iso node.
*
* @return
* 1 if yes, 0 if not
* 1 if yes, <0 if not. The value is a specific ISO_* error code.
*/
int iso_node_is_valid_name(const char *name);
@ -473,4 +505,35 @@ int iso_root_get_isofsca(IsoNode *node, uint32_t *start_lba, uint32_t *end_lba,
int flag);
/**
* Copy the xinfo list from one node to the another.
*/
int iso_node_clone_xinfo(IsoNode *from_node, IsoNode *to_node, int flag);
/**
* The iso_node_xinfo_func instance which governs the storing of the inode
* number from Rock Ridge field PX.
*/
int iso_px_ino_xinfo_func(void *data, int flag);
/* The iso_node_xinfo_cloner function which gets associated to
* iso_px_ino_xinfo_func by iso_init() resp. iso_init_with_flag() via
* iso_node_xinfo_make_clonable()
*/
int iso_px_ino_xinfo_cloner(void *old_data, void **new_data, int flag);
/* Function to identify and manage ZF parameters of zisofs compression.
* data is supposed to be a pointer to struct zisofs_zf_info
*/
int zisofs_zf_xinfo_func(void *data, int flag);
/* The iso_node_xinfo_cloner function which gets associated to
* zisofs_zf_xinfo_func by iso_init() resp. iso_init_with_flag() via
* iso_node_xinfo_make_clonable()
*/
int zisofs_zf_xinfo_cloner(void *old_data, void **new_data, int flag);
#endif /*LIBISO_NODE_H_*/

View File

@ -337,7 +337,12 @@ static
int rrip_add_NM(Ecma119Image *t, struct susp_info *susp, char *name, int size,
int flags, int ce)
{
uint8_t *NM = malloc(size + 5);
uint8_t *NM;
if (size > 250)
return ISO_ASSERT_FAILURE;
NM = malloc(size + 5);
if (NM == NULL) {
return ISO_OUT_OF_MEM;
}
@ -905,7 +910,7 @@ int add_zf_field(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
return 1;
}
/* API */
int aaip_xinfo_func(void *data, int flag)
{
if (flag & 1) {
@ -914,6 +919,23 @@ int aaip_xinfo_func(void *data, int flag)
return 1;
}
/* API */
int aaip_xinfo_cloner(void *old_data, void **new_data, int flag)
{
size_t aa_size;
*new_data = NULL;
if (old_data == NULL)
return 0;
aa_size = aaip_count_bytes((unsigned char *) old_data, 0);
if (aa_size <= 0)
return ISO_AAIP_BAD_AASTRING;
*new_data = calloc(1, aa_size);
if (*new_data == NULL)
return ISO_OUT_OF_MEM;
memcpy(*new_data, old_data, aa_size);
return (int) aa_size;
}
/**
* Compute SUA length and eventual Continuation Area length of field NM and
@ -928,6 +950,7 @@ int aaip_xinfo_func(void *data, int flag)
* (*su_size and *ce stay unaltered in this case)
* <0= error:
* -1= not enough SUA space for 28 bytes of CE entry
* -2= out of memory
*/
static
int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
@ -964,6 +987,9 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
if (!(flag & 1))
goto unannounced_ca;
namelen = namelen - (space - *su_size - 5);
/* >>> Need to handle lengths > 250 */;
*ce = 5 + namelen;
*su_size = space;
}
@ -976,6 +1002,8 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
int cew = (*ce != 0); /* are we writing to CA ? */
dest = get_rr_fname(t, ((IsoSymlink*)n->node)->dest);
if (dest == NULL)
return -2;
prev = dest;
cur = strchr(prev, '/');
while (1) {
@ -1004,8 +1032,10 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
* TODO this can be handled better, but for now SL
* will be completelly moved into the CA
*/
if (!(flag & 1))
if (!(flag & 1)) {
free(dest);
goto unannounced_ca;
}
cew = 1;
} else {
sl_len += clen;
@ -1105,6 +1135,44 @@ unannounced_ca:;
}
/* @param flag bit0= Do not add data but only count sua_free and ce_len
param info may be NULL in this case
*/
static
int add_aa_string(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
size_t *sua_free, size_t *ce_len, int flag)
{
int ret;
uint8_t *aapt;
void *xipt;
size_t num_aapt= 0;
if (!t->aaip)
return 1;
ret = iso_node_get_xinfo(n->node, aaip_xinfo_func, &xipt);
if (ret == 1) {
num_aapt = aaip_count_bytes((unsigned char *) xipt, 0);
if (num_aapt > 0) {
if (flag & 1) {
ret = aaip_add_AL(t, NULL,NULL, num_aapt, sua_free, ce_len, 1);
} else {
aapt = malloc(num_aapt);
if (aapt == NULL)
return ISO_OUT_OF_MEM;
memcpy(aapt, xipt, num_aapt);
ret = aaip_add_AL(t, info, &aapt, num_aapt, sua_free, ce_len,
0);
}
if (ret < 0)
return ret;
/* aapt is NULL now and the memory is owned by t */
}
}
return 1;
}
/**
* Compute the length needed for write all RR and SUSP entries for a given
* node.
@ -1124,6 +1192,7 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t used_up,
{
size_t su_size, space;
int ret;
size_t aaip_sua_free= 0, aaip_len= 0;
/* Directory record length must be even (ECMA-119, 9.1.13). Maximum is 254.
*/
@ -1180,7 +1249,9 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t used_up,
/* Try without CE */
ret = susp_calc_nm_sl_al(t, n, space, &su_size, ce, 0);
if (ret == 0) /* Retry with CE */
susp_calc_nm_sl_al(t, n, space, &su_size, ce, 1);
ret = susp_calc_nm_sl_al(t, n, space, &su_size, ce, 1);
if (ret == -2)
return ISO_OUT_OF_MEM;
} else {
@ -1201,9 +1272,15 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t used_up,
} else {
*ce = 182;
}
if (t->aaip) {
if (t->aaip && !t->aaip_susp_1_10) {
*ce += 160; /* ER of AAIP */
}
/* Compute length of AAIP string of root node */
aaip_sua_free= 0;
ret = add_aa_string(t, n, NULL, &aaip_sua_free, &aaip_len, 1);
if (ret < 0)
return ret;
*ce += aaip_len;
}
}
@ -1235,43 +1312,6 @@ void susp_info_free(struct susp_info* susp)
}
/* @param flag bit0= Do not add data but only count sua_free and ce_len
*/
static
int add_aa_string(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
size_t *sua_free, size_t *ce_len, int flag)
{
int ret;
uint8_t *aapt;
void *xipt;
size_t num_aapt= 0;
if (!t->aaip)
return 1;
ret = iso_node_get_xinfo(n->node, aaip_xinfo_func, &xipt);
if (ret == 1) {
num_aapt = aaip_count_bytes((unsigned char *) xipt, 0);
if (num_aapt > 0) {
if (flag & 1) {
ret = aaip_add_AL(t, NULL,NULL, num_aapt, sua_free, ce_len, 1);
} else {
aapt = malloc(num_aapt);
if (aapt == NULL)
return ISO_OUT_OF_MEM;
memcpy(aapt, xipt, num_aapt);
ret = aaip_add_AL(t, info, &aapt, num_aapt, sua_free, ce_len,
0);
}
if (ret < 0)
return ret;
/* aapt is NULL now and the memory is owned by t */
}
}
return 1;
}
/**
* Fill a struct susp_info with the RR/SUSP entries needed for a given
* node.
@ -1422,10 +1462,14 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
ce_len_pd = ce_len;
ret = susp_calc_nm_sl_al(t, n, space, &su_size_pd, &ce_len_pd, 0);
if (ret == 0) { /* Have to use CA. 28 bytes of CE are necessary */
susp_calc_nm_sl_al(t, n, space, &su_size_pd, &ce_len_pd, 1);
ret = susp_calc_nm_sl_al(t, n, space, &su_size_pd, &ce_len_pd, 1);
sua_free -= 28;
ce_is_predicted = 1;
}
if (ret == -2) {
ret = ISO_OUT_OF_MEM;
goto add_susp_cleanup;
}
/* NM entry */
if (5 + namelen <= sua_free) {
@ -1623,6 +1667,9 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
/*
* ..and the part that goes to continuation area.
*/
/* >>> Need a loop to handle lengths > 250 */;
ret = rrip_add_NM(t, info, name + namelen, strlen(name + namelen),
0, 1);
if (ret < 0) {
@ -1688,7 +1735,7 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
/* Compute length of AAIP string of root node */
aaip_sua_free= 0;
ret = add_aa_string(t, n, info, &aaip_sua_free, &aaip_len, 1);
ret = add_aa_string(t, n, NULL, &aaip_sua_free, &aaip_len, 1);
if (ret < 0)
goto add_susp_cleanup;

View File

@ -443,7 +443,7 @@ int read_rr_PN(struct susp_sys_user_entry *pn, struct stat *st)
}
/* AA is the field signature of AAIP versions < 2.0
/* AA is the obsolete field signature of AAIP versions < 2.0
*/
int read_aaip_AA(struct susp_sys_user_entry *sue,
unsigned char **aa_string, size_t *aa_size, size_t *aa_len,
@ -514,7 +514,7 @@ int read_aaip_AA(struct susp_sys_user_entry *sue,
}
/* AL is the obsolete field signature of AAIP versions >= 2.0
/* AL is the field signature of AAIP versions >= 2.0
*/
int read_aaip_AL(struct susp_sys_user_entry *sue,
unsigned char **aa_string, size_t *aa_size, size_t *aa_len,

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 Thomas Schmitt
* Copyright (c) 2009 - 2011 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -16,6 +16,7 @@
#include "stream.h"
#include "fsource.h"
#include "util.h"
#include "node.h"
#include <stdlib.h>
#include <string.h>
@ -157,8 +158,64 @@ int fsrc_update_size(IsoStream *stream)
return ISO_SUCCESS;
}
static
IsoStream *fsrc_get_input_stream(IsoStream *stream, int flag)
{
return NULL;
}
static
int fsrc_cmp_ino(IsoStream *s1, IsoStream *s2)
{
int ret;
ret = iso_stream_cmp_ino(s1, s2, 1);
return ret;
}
int fsrc_clone_stream(IsoStream *old_stream, IsoStream **new_stream,
int flag)
{
FSrcStreamData *data, *new_data;
IsoStream *stream;
int ret;
if (flag)
return ISO_STREAM_NO_CLONE; /* unknown option required */
data = (FSrcStreamData*) old_stream->data;
if (data->src->class->version < 2)
return ISO_STREAM_NO_CLONE; /* No clone_src() method available */
*new_stream = NULL;
stream = calloc(1, sizeof(IsoStream));
if (stream == NULL)
return ISO_OUT_OF_MEM;
new_data = calloc(1, sizeof(FSrcStreamData));
if (new_data == NULL) {
free((char *) stream);
return ISO_OUT_OF_MEM;
}
*new_stream = stream;
stream->class = old_stream->class;
stream->refcount = 1;
stream->data = new_data;
ret = data->src->class->clone_src(data->src, &(new_data->src), 0);
if (ret < 0) {
free((char *) stream);
free((char *) new_data);
return ret;
}
new_data->dev_id = data->dev_id;
new_data->ino_id = data->ino_id;
new_data->size = data->size;
return ISO_SUCCESS;
}
IsoStreamIface fsrc_stream_class = {
1, /* update_size is defined for this stream */
4, /* version */
"fsrc",
fsrc_open,
fsrc_close,
@ -167,7 +224,10 @@ IsoStreamIface fsrc_stream_class = {
fsrc_is_repeatable,
fsrc_get_id,
fsrc_free,
fsrc_update_size
fsrc_update_size,
fsrc_get_input_stream,
fsrc_cmp_ino,
fsrc_clone_stream
};
int iso_file_source_stream_new(IsoFileSource *src, IsoStream **stream)
@ -375,11 +435,76 @@ void cut_out_free(IsoStream *stream)
free(data);
}
static
int cut_out_update_size(IsoStream *stream)
{
return ISO_SUCCESS;
}
static
IsoStream* cut_out_get_input_stream(IsoStream *stream, int flag)
{
return NULL;
}
static
int cut_out_cmp_ino(IsoStream *s1, IsoStream *s2)
{
int ret;
ret = iso_stream_cmp_ino(s1, s2, 1);
return ret;
}
static
int cut_out_clone_stream(IsoStream *old_stream, IsoStream **new_stream,
int flag)
{
struct cut_out_stream *data, *new_data;
IsoStream *stream;
int ret;
if (flag)
return ISO_STREAM_NO_CLONE; /* unknown option required */
data = (struct cut_out_stream *) old_stream->data;
if (data->src->class->version < 2)
return ISO_STREAM_NO_CLONE; /* No clone_src() method available */
*new_stream = NULL;
stream = calloc(1, sizeof(IsoStream));
if (stream == NULL)
return ISO_OUT_OF_MEM;
stream->refcount = 1;
stream->class = old_stream->class;
new_data = calloc(1, sizeof(struct cut_out_stream));
if (new_data == NULL) {
free((char *) stream);
return ISO_OUT_OF_MEM;
}
ret = data->src->class->clone_src(data->src, &(new_data->src), 0);
if (ret < 0) {
free((char *) stream);
free((char *) new_data);
return ret;
}
new_data->dev_id = (dev_t) 0;
new_data->ino_id = cut_out_serial_id++;
new_data->offset = data->offset;
new_data->size = data->size;
new_data->pos = 0;
stream->data = new_data;
*new_stream = stream;
return ISO_SUCCESS;
}
/*
* TODO update cut out streams to deal with update_size(). Seems hard.
*/
IsoStreamIface cut_out_stream_class = {
0,
4, /* version */
"cout",
cut_out_open,
cut_out_close,
@ -387,7 +512,12 @@ IsoStreamIface cut_out_stream_class = {
cut_out_read,
cut_out_is_repeatable,
cut_out_get_id,
cut_out_free
cut_out_free,
cut_out_update_size,
cut_out_get_input_stream,
cut_out_cmp_ino,
cut_out_clone_stream
};
int iso_cut_out_stream_new(IsoFileSource *src, off_t offset, off_t size,
@ -549,12 +679,77 @@ void mem_free(IsoStream *stream)
{
MemStreamData *data;
data = (MemStreamData*)stream->data;
free(data->buf);
if (data->buf != NULL)
free(data->buf);
free(data);
}
static
int mem_update_size(IsoStream *stream)
{
return ISO_SUCCESS;
}
static
IsoStream* mem_get_input_stream(IsoStream *stream, int flag)
{
return NULL;
}
static
int mem_cmp_ino(IsoStream *s1, IsoStream *s2)
{
int ret;
ret = iso_stream_cmp_ino(s1, s2, 1);
return ret;
}
static
int mem_clone_stream(IsoStream *old_stream, IsoStream **new_stream,
int flag)
{
MemStreamData *data, *new_data;
IsoStream *stream;
uint8_t *new_buf = NULL;
if (flag)
return ISO_STREAM_NO_CLONE; /* unknown option required */
*new_stream = NULL;
stream = calloc(1, sizeof(IsoStream));
if (stream == NULL)
return ISO_OUT_OF_MEM;
stream->refcount = 1;
stream->class = old_stream->class;
new_data = calloc(1, sizeof(MemStreamData));
if (new_data == NULL) {
free((char *) stream);
return ISO_OUT_OF_MEM;
}
data = (MemStreamData *) old_stream->data;
if (data->size > 0) {
new_buf = calloc(1, data->size);
if (new_buf == NULL) {
free((char *) stream);
free((char *) new_data);
return ISO_OUT_OF_MEM;
}
memcpy(new_buf, data->buf, data->size);
}
new_data->buf = new_buf;
new_data->offset = -1;
new_data->ino_id = mem_serial_id++;
new_data->size = data->size;
stream->data = new_data;
*new_stream = stream;
return ISO_SUCCESS;
}
IsoStreamIface mem_stream_class = {
0,
4, /* version */
"mem ",
mem_open,
mem_close,
@ -562,7 +757,12 @@ IsoStreamIface mem_stream_class = {
mem_read,
mem_is_repeatable,
mem_get_id,
mem_free
mem_free,
mem_update_size,
mem_get_input_stream,
mem_cmp_ino,
mem_clone_stream
};
/**
@ -570,7 +770,7 @@ IsoStreamIface mem_stream_class = {
* When the Stream refcount reach 0, the buffer is free(3).
*
* @return
* 1 sucess, < 0 error
* 1 success, < 0 error
*/
int iso_memory_stream_new(unsigned char *buf, size_t size, IsoStream **stream)
{
@ -669,7 +869,8 @@ void iso_stream_get_file_name(IsoStream *stream, char *name)
if (!strncmp(type, "fsrc", 4)) {
FSrcStreamData *data = stream->data;
char *path = iso_file_source_get_path(data->src);
strncpy(name, path, PATH_MAX);
strncpy(name, path, PATH_MAX - 1);
name[PATH_MAX - 1] = 0;
free(path);
} else if (!strncmp(type, "boot", 4)) {
strcpy(name, "BOOT CATALOG");
@ -924,3 +1125,42 @@ ex:;
iso_md5_end(&ctx, md5);
return res;
}
/* API */
int iso_stream_clone(IsoStream *old_stream, IsoStream **new_stream, int flag)
{
int ret;
if (old_stream->class->version < 4)
return ISO_STREAM_NO_CLONE;
ret = old_stream->class->clone_stream(old_stream, new_stream, 0);
return ret;
}
int iso_stream_clone_filter_common(IsoStream *old_stream,
IsoStream **new_stream,
IsoStream **new_input, int flag)
{
IsoStream *stream, *input_stream;
int ret;
*new_stream = NULL;
*new_input = NULL;
input_stream = iso_stream_get_input_stream(old_stream, 0);
if (input_stream == NULL)
return ISO_STREAM_NO_CLONE;
stream = calloc(1, sizeof(IsoStream));
if (stream == NULL)
return ISO_OUT_OF_MEM;
ret = iso_stream_clone(input_stream, new_input, 0);
if (ret < 0) {
free((char *) stream);
return ret;
}
stream->class = old_stream->class;
stream->refcount = 1;
stream->data = NULL;
*new_stream = stream;
return ISO_SUCCESS;
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 Thomas Schmitt
* Copyright (c) 2009 - 2011 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -15,6 +15,7 @@
*/
#include "fsource.h"
/* IMPORTANT: Any change must be reflected by fsrc_clone_stream */
typedef struct
{
IsoFileSource *src;
@ -28,7 +29,8 @@ typedef struct
/**
* Get an identifier for the file of the source, for debug purposes
* @param name
* Should provide at least PATH_MAX bytes
* Must provide at least PATH_MAX bytes. If no PATH_MAX is defined
* then assume PATH_MAX = Libisofs_default_path_maX from libisofs.h
*/
void iso_stream_get_file_name(IsoStream *stream, char *name);
@ -94,5 +96,20 @@ int iso_stream_read_buffer(IsoStream *stream, char *buf, size_t count,
int iso_stream_make_md5(IsoStream *stream, char md5[16], int flag);
/**
* Create a clone of the input stream of old_stream and a roughly initialized
* clone of old_stream which has the same class and refcount 1. Its data
* pointer will be NULL and needs to be filled by an expert which knows how
* to clone the data of old_stream.
* @param old_stream The existing stream which is in process of cloning
* @param new_stream Will return the uninitialized memory object which shall
* later become the clone of old_stream.
* @param new_input The clone of the input stream of old stream.
* @param flag Submit 0 for now.
* @return ISO_SUCCESS or an error code <0
*/
int iso_stream_clone_filter_common(IsoStream *old_stream,
IsoStream **new_stream,
IsoStream **new_input, int flag);
#endif /*STREAM_H_*/

View File

@ -809,3 +809,118 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
return ISO_SUCCESS;
}
/* Choose *heads_per_cyl so that
- *heads_per_cyl * secs_per_head * 1024 >= imgsize / 512
- *heads_per_cyl * secs_per_head is divisible by 4
- it is as small as possible (to reduce aligment overhead)
- it is <= 255
@return 1= success , 0= cannot achieve goals
*/
static
int try_sph(off_t imgsize, int secs_per_head, int *heads_per_cyl, int flag)
{
off_t hd_blocks, hpc;
hd_blocks= imgsize / 512;
hpc = hd_blocks / secs_per_head / 1024;
if (hpc * secs_per_head * 1024 < hd_blocks)
hpc++;
if ((secs_per_head % 4) == 0) {
;
} else if ((secs_per_head % 2) == 0) {
hpc += (hpc % 2);
} else if(hpc % 4) {
hpc += 4 - (hpc % 4);
}
if (hpc > 255)
return 0;
*heads_per_cyl = hpc;
return 1;
}
int iso_align_isohybrid(Ecma119Image *t, int flag)
{
int sa_type, ret, always_align;
uint32_t img_blocks;
off_t imgsize, cylsize = 0, frac;
char msg[160];
sa_type = (t->system_area_options >> 2) & 0x3f;
if (sa_type != 0)
return ISO_SUCCESS;
always_align = (t->system_area_options >> 8) & 3;
img_blocks = t->curblock;
imgsize = ((off_t) img_blocks) * (off_t) 2048;
if (((t->system_area_options & 3) || always_align)
&& (off_t) (t->partition_heads_per_cyl * t->partition_secs_per_head
* 1024) * (off_t) 512 < imgsize) {
/* Choose small values which can represent the image size */
/* First try 32 sectors per head */
ret = try_sph(imgsize, 32, &(t->partition_heads_per_cyl), 0);
if (ret == 1) {
t->partition_secs_per_head = 32;
} else {
/* Did not work with 32. Try 63 */
t->partition_secs_per_head = 63;
ret = try_sph(imgsize, 63, &(t->partition_heads_per_cyl), 0);
if (ret != 1)
t->partition_heads_per_cyl = 255;
}
cylsize = t->partition_heads_per_cyl * t->partition_secs_per_head *512;
frac = imgsize % cylsize;
sprintf(msg, "Automatically adjusted MBR geometry to %d/%d/%d",
(int) (imgsize / cylsize + !!frac),
t->partition_heads_per_cyl, t->partition_secs_per_head);
iso_msgs_submit(0, msg, 0, "NOTE", 0);
}
if (always_align >= 2)
return ISO_SUCCESS;
cylsize = 0;
if (t->catalog != NULL &&
(t->catalog->bootimages[0]->isolinux_options & 0x0a) == 0x02) {
/* Check for isolinux image with magic number of 3.72 and produce
an MBR from our built-in template. (Deprecated since 31 Mar 2010)
*/
if (img_blocks >= 0x40000000)
return ISO_SUCCESS;
cylsize = 64 * 32 * 512;
} else if ((t->system_area_options & 2) || always_align) {
/* Patch externally provided system area as isohybrid MBR */
if (t->catalog == NULL || t->system_area_data == NULL) {
/* isohybrid makes only sense together with ISOLINUX boot image
and externally provided System Area.
*/
return ISO_ISOLINUX_CANT_PATCH;
}
cylsize = t->partition_heads_per_cyl * t->partition_secs_per_head
* 512;
}
if (cylsize == 0)
return ISO_SUCCESS;
if (((double) imgsize) / (double) cylsize > 1024.0) {
iso_msgs_submit(0,
"Image size exceeds 1024 cylinders. Cannot align partition.",
0, "WARNING", 0);
return ISO_SUCCESS;
}
frac = imgsize % cylsize;
imgsize += (frac > 0 ? cylsize - frac : 0);
frac = imgsize - ((off_t) img_blocks) * (off_t) 2048;
if (frac == 0)
return ISO_SUCCESS;
if (frac % 2048) {
sprintf(msg,
"Cylinder size %d not divisible by 2048. Cannot align partition.",
(int) cylsize);
iso_msgs_submit(0, msg, 0, "WARNING", 0);
} else {
t->tail_blocks += frac / 2048;
}
return ISO_SUCCESS;
}

View File

@ -46,6 +46,11 @@ int make_isohybrid_mbr(int bin_lba, int *img_blocks, char *mbr, int flag);
*/
int iso_write_system_area(Ecma119Image *t, uint8_t *buf);
/**
* Adjust t->tail_blocks to the eventual alignment needs of isohybrid booting.
*/
int iso_align_isohybrid(Ecma119Image *t, int flag);
/**
* Read the necessary ELF information from the first MIPS boot file.

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2011 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -31,11 +32,6 @@
#include <fnmatch.h>
#ifndef PATH_MAX
#define PATH_MAX Libisofs_default_path_maX
#endif
/**
* Add a new directory to the iso tree.
*
@ -979,17 +975,214 @@ char *iso_tree_get_node_path(IsoNode *node)
if ((IsoNode*)node->parent == node) {
return strdup("/");
} else {
char path[PATH_MAX];
char *parent_path = iso_tree_get_node_path((IsoNode*)node->parent);
char *path = NULL, *parent_path;
parent_path = iso_tree_get_node_path((IsoNode*)node->parent);
if (parent_path == NULL) {
return NULL;
}
if (strlen(parent_path) == 1) {
snprintf(path, PATH_MAX, "/%s", node->name);
path = calloc(1, strlen(node->name) + 2);
if (path == NULL)
return NULL;
sprintf(path, "/%s", node->name);
} else {
snprintf(path, PATH_MAX, "%s/%s", parent_path, node->name);
path = calloc(1, strlen(parent_path) + strlen(node->name) + 2);
if (path == NULL)
return NULL;
sprintf(path, "%s/%s", parent_path, node->name);
}
free(parent_path);
return strdup(path);
return path;
}
}
/* ------------------------- tree cloning ------------------------------ */
static
int iso_tree_copy_node_attr(IsoNode *old_node, IsoNode *new_node, int flag)
{
int ret;
new_node->mode = old_node->mode;
new_node->uid = old_node->uid;
new_node->gid = old_node->gid;
new_node->atime = old_node->atime;
new_node->mtime = old_node->mtime;
new_node->ctime = old_node->ctime;
new_node->hidden = old_node->hidden;
ret = iso_node_clone_xinfo(old_node, new_node, 0);
if (ret < 0)
return ret;
return ISO_SUCCESS;
}
/*
@param flag bit0= merge directory with *new_node
*/
static
int iso_tree_clone_dir(IsoDir *old_dir,
IsoDir *new_parent, char *new_name, IsoNode **new_node,
int flag)
{
IsoDir *new_dir = NULL;
IsoNode *sub_node = NULL, *new_sub_node = NULL;
IsoDirIter *iter = NULL;
int ret;
if (flag & 1) {
new_dir = (IsoDir *) *new_node;
} else {
*new_node = NULL;
ret = iso_tree_add_new_dir(new_parent, new_name, &new_dir);
if (ret < 0)
return ret;
}
/* Avoid traversal of target directory to allow cloning of old_dir to a
subordinate of old_dir.
*/
iso_node_take((IsoNode *) new_dir);
ret = iso_dir_get_children(old_dir, &iter);
if (ret < 0)
goto ex;
while(1) {
ret = iso_dir_iter_next(iter, &sub_node);
if (ret == 0)
break;
ret = iso_tree_clone(sub_node, new_dir, sub_node->name, &new_sub_node,
flag & 1);
if (ret < 0)
goto ex;
}
/* Now graft in the new tree resp. graft back the merged tree */
ret = iso_dir_add_node(new_parent, (IsoNode *) new_dir, 0);
if (ret < 0)
goto ex;
if (!(flag & 1))
*new_node = (IsoNode *) new_dir;
ret = ISO_SUCCESS;
ex:;
if (iter != NULL)
iso_dir_iter_free(iter);
if (ret < 0 && new_dir != NULL) {
if (flag & 1) {
/* graft back the merged tree (eventually with half copy) */
iso_dir_add_node(new_parent, (IsoNode *) new_dir, 0);
} else {
iso_node_remove_tree((IsoNode *) new_dir, NULL);
*new_node = NULL;
}
}
return ret;
}
static
int iso_tree_clone_file(IsoFile *old_file,
IsoDir *new_parent, char *new_name, IsoNode **new_node,
int flag)
{
IsoStream *new_stream = NULL;
IsoFile *new_file = NULL;
int ret;
*new_node = NULL;
ret = iso_stream_clone(old_file->stream, &new_stream, 0);
if (ret < 0)
return ret;
ret = iso_tree_add_new_file(new_parent, new_name, new_stream, &new_file);
if (ret < 0)
goto ex;
new_stream = NULL; /* now owned by new_file */
new_file->sort_weight = old_file->sort_weight;
*new_node = (IsoNode *) new_file;
ret = ISO_SUCCESS;
ex:;
if (new_stream != NULL)
iso_stream_unref(new_stream);
return ret;
}
static
int iso_tree_clone_symlink(IsoSymlink *node,
IsoDir *new_parent, char *new_name, IsoNode **new_node,
int flag)
{
IsoSymlink *new_sym;
int ret;
*new_node = NULL;
ret = iso_tree_add_new_symlink(new_parent, new_name, node->dest, &new_sym);
if (ret < 0)
return ret;
new_sym->fs_id = node->fs_id;
new_sym->st_dev = node->st_dev;
new_sym->st_ino = node->st_ino;
*new_node = (IsoNode *) new_sym;
return ISO_SUCCESS;
}
static
int iso_tree_clone_special(IsoSpecial *node,
IsoDir *new_parent, char *new_name, IsoNode **new_node,
int flag)
{
IsoSpecial *new_spec;
IsoNode *iso_node;
int ret;
iso_node = (IsoNode *) node;
ret = iso_tree_add_new_special(new_parent, new_name, iso_node->mode,
node->dev, &new_spec);
if (ret < 0)
return ret;
new_spec->fs_id = node->fs_id;
new_spec->st_dev = node->st_dev;
new_spec->st_ino = node->st_ino;
*new_node = (IsoNode *) new_spec;
return ISO_SUCCESS;
}
/* API */
int iso_tree_clone(IsoNode *node,
IsoDir *new_parent, char *new_name, IsoNode **new_node,
int flag)
{
int ret = ISO_SUCCESS;
if (iso_dir_get_node(new_parent, new_name, new_node) == 1) {
if (! (node->type == LIBISO_DIR && (*new_node)->type == LIBISO_DIR &&
(flag & 1))) {
*new_node = NULL;
return ISO_NODE_NAME_NOT_UNIQUE;
}
} else
flag &= ~1;
if (node->type == LIBISO_DIR) {
ret = iso_tree_clone_dir((IsoDir *) node, new_parent, new_name,
new_node, flag & 1);
} else if (node->type == LIBISO_FILE) {
ret = iso_tree_clone_file((IsoFile *) node, new_parent, new_name,
new_node, 0);
} else if (node->type == LIBISO_SYMLINK) {
ret = iso_tree_clone_symlink((IsoSymlink *) node, new_parent, new_name,
new_node, 0);
} else if (node->type == LIBISO_SPECIAL) {
ret = iso_tree_clone_special((IsoSpecial *) node, new_parent, new_name,
new_node, 0);
} else if (node->type == LIBISO_BOOT) {
ret = ISO_SUCCESS; /* API says they are silently ignored */
}
if (ret < 0)
return ret;
if (flag & 1)
return 2; /* merged two directories, *new_node is not new */
ret = iso_tree_copy_node_attr(node, *new_node, 0);
return ret;
}

View File

@ -1,7 +1,7 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2007 Mario Danic
* Copyright (c) 2009 Thomas Schmitt
* Copyright (c) 2009 - 2011 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -16,6 +16,7 @@
#include "util.h"
#include "libisofs.h"
#include "messages.h"
#include "joliet.h"
#include "../version.h"
#include <stdlib.h>
@ -916,16 +917,20 @@ ex:;
/*
bit0= no_force_dots
bit1= allow 103 characters rather than 64
*/
uint16_t *iso_j_file_id(const uint16_t *src, int flag)
{
uint16_t *dot;
size_t lname, lext, lnname, lnext, pos, i;
uint16_t dest[66]; /* 66 = 64 (name + ext) + 1 (.) + 1 (\0) */
size_t lname, lext, lnname, lnext, pos, i, maxchar = 64;
uint16_t dest[LIBISO_JOLIET_NAME_MAX];
/* was: 66 = 64 (name + ext) + 1 (.) + 1 (\0) */
if (src == NULL) {
return NULL;
}
if (flag & 2)
maxchar = 103;
dot = ucsrchr(src, '.');
@ -937,14 +942,15 @@ uint16_t *iso_j_file_id(const uint16_t *src, int flag)
*/
if (dot == NULL || cmp_ucsbe(dot + 1, '\0') == 0) {
lname = ucslen(src);
lnname = (lname > 64) ? 64 : lname;
lnname = (lname > maxchar) ? maxchar : lname;
lext = lnext = 0;
} else {
lext = ucslen(dot + 1);
lname = ucslen(src) - lext - 1;
lnext = (ucslen(src) > 65 && lext > 3) ? (lname < 61 ? 64 - lname : 3)
lnext = (ucslen(src) > maxchar + 1 && lext > 3)
? (lname < maxchar - 3 ? maxchar - lname : 3)
: lext;
lnname = (ucslen(src) > 65) ? 64 - lnext : lname;
lnname = (ucslen(src) > maxchar + 1) ? maxchar - lnext : lname;
}
if (lnname == 0 && lnext == 0) {
@ -986,18 +992,22 @@ is_done:;
return ucsdup(dest);
}
uint16_t *iso_j_dir_id(const uint16_t *src)
/* @param flag bit1= allow 103 characters rather than 64
*/
uint16_t *iso_j_dir_id(const uint16_t *src, int flag)
{
size_t len, i;
uint16_t dest[65]; /* 65 = 64 + 1 (\0) */
size_t len, i, maxchar = 64;
uint16_t dest[LIBISO_JOLIET_NAME_MAX]; /* was: 65 = 64 + 1 (\0) */
if (src == NULL) {
return NULL;
}
if (flag & 2)
maxchar = 103;
len = ucslen(src);
if (len > 64) {
len = 64;
if (len > maxchar) {
len = maxchar;
}
for (i = 0; i < len; i++) {
uint16_t c = src[i];
@ -1298,12 +1308,41 @@ void iso_datetime_17(unsigned char *buf, time_t t, int always_gmt)
}
#ifndef HAVE_TIMEGM
/* putenv is SVr4, POSIX.1-2001, 4.3BSD , setenv is 4.3BSD, POSIX.1-2001.
So putenv is more widely available.
Also, setenv spoils eventual putenv expectation of applications because
putenv installs the original string which then may be altered from
its owner. setenv installs a copy that may not be altered.
Both are slow.
Thus first try with a naive implementation that assumes no leap seconds.
If it fails a test with gmtime() then use the slow function with mktime().
*/
#define Libisofs_use_putenV yes
static
time_t timegm(struct tm *tm)
time_t env_timegm(struct tm *tm)
{
time_t ret;
char *tz;
#ifdef Libisofs_use_putenV
static char unset_name[] = {"TZ"};
tz = getenv("TZ");
putenv("TZ=");
tzset();
ret = mktime(tm);
if (tz != NULL) {
/* tz is a pointer to the value part in a string of form "TZ="value */
putenv(tz - 3);
} else
putenv(unset_name); /* not daring to submit constant */
tzset();
#else /* Libisofs_use_putenV */
tz = getenv("TZ");
setenv("TZ", "", 1);
tzset();
@ -1313,9 +1352,92 @@ time_t timegm(struct tm *tm)
else
unsetenv("TZ");
tzset();
#endif /* ! Libisofs_use_putenV */
return ret;
}
#endif
static
int ts_is_leapyear(int tm_year) /* years since 1900 */
{
return ((tm_year % 4) == 0 && ((tm_year % 100) != 0 ||
(tm_year % 400) == 100));
}
/* Fast implementation without leap seconds.
Inspired by but not copied from code by Kungliga Tekniska Hgskolan
(Royal Institute of Technology, Stockholm, Sweden),
which was modified by Andrew Tridgell for Samba4.
I claim own copyright 2011 Thomas Schmitt <scdbackup@gmx.net>.
*/
static
time_t ts_timegm(struct tm *tm)
{
time_t ret;
static int month_length_normal[12] =
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
static int month_length_leap[12] =
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int *month_length_pt;
int years, i;
ret = 0;
years = tm->tm_year - 70; /* Years since 1970 */
if (years < 0)
return ret;
for (i = 0; i < years; i++) {
ret += 365 * 86400;
if (ts_is_leapyear(70 + i))
ret += 86400;
}
if (ts_is_leapyear(tm->tm_year))
month_length_pt = month_length_leap;
else
month_length_pt = month_length_normal;
for (i = 0; i < tm->tm_mon; i++)
ret += month_length_pt[i] * 86400;
ret += (tm->tm_mday - 1) * 86400;
ret += tm->tm_hour * 3600;
ret += tm->tm_min * 60;
ret += tm->tm_sec;
return ret;
}
static
time_t timegm(struct tm *tm)
{
time_t raw_t, ret;
struct tm *test_tm, input_tm_copy;
/* Beware of ill effects if tm is result of gmtime() or alike */
memcpy(&input_tm_copy, tm, sizeof(struct tm));
/* Try without leapseconds (which are rarely implemented, as it seems) */
raw_t = ts_timegm(tm);
if (raw_t == 0)
return raw_t;
/* Check whether this translates back to the input values */
test_tm = gmtime(&raw_t);
if (input_tm_copy.tm_sec == test_tm->tm_sec &&
input_tm_copy.tm_min == test_tm->tm_min &&
input_tm_copy.tm_hour == test_tm->tm_hour &&
input_tm_copy.tm_mday == test_tm->tm_mday &&
input_tm_copy.tm_mon == test_tm->tm_mon &&
input_tm_copy.tm_year == test_tm->tm_year) {
ret = raw_t;
} else {
/* Mismatch. Use slow method around mktime() */
ret = env_timegm(&input_tm_copy);
}
return ret;
}
#endif /* ! HAVE_TIMEGM */
time_t iso_datetime_read_7(const uint8_t *buf)
{
@ -1327,6 +1449,7 @@ time_t iso_datetime_read_7(const uint8_t *buf)
tm.tm_hour = buf[3];
tm.tm_min = buf[4];
tm.tm_sec = buf[5];
return timegm(&tm) - ((int8_t)buf[6]) * 60 * 15;
}
@ -1727,10 +1850,24 @@ unexpected_type:;
iso_msg_submit(-1, ISO_MD5_TAG_UNEXPECTED, 0, NULL);
ret = 0;
goto ex;
} else if(pos != lba) {
} else if (pos != lba) {
if (*tag_type == 2) { /* Superblock tag */
if (lba < 32) {
/* Check whether this is a copied superblock */
range_start -= (off_t) pos - (off_t) lba;
if (range_start != ctx_start_lba) {
/* >>> check for matching MD5 ? */;
ret = ISO_MD5_TAG_MISPLACED;
} else
ret = ISO_MD5_TAG_COPIED;
goto ex;
}
}
ret = ISO_MD5_TAG_MISPLACED;
goto ex;
} else if(range_start != ctx_start_lba) {
} else if (range_start != ctx_start_lba) {
ret = ISO_MD5_TAG_MISPLACED;
}
ret = iso_md5_clone(ctx, &cloned_ctx);

View File

@ -11,7 +11,14 @@
#ifndef LIBISO_UTIL_H_
#define LIBISO_UTIL_H_
#ifdef HAVE_STDINT_H
#include <stdint.h>
#else
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#endif
#include <time.h>
#ifndef MAX
@ -146,13 +153,15 @@ char *iso_r_fileid(const char *src, size_t len, int relaxed, int forcedot);
/**
* Create a Joliet file identifier that consists of name and extension. The
* combined name and extension length will not exceed 128 bytes, and the
* name and extension will be separated (.). All characters consist of
* 2 bytes and the resulting string is NULL-terminated by a 2-byte NULL.
* combined name and extension length will normally not exceed 64 characters
* (= 128 bytes). The name and the extension will be separated (.).
* All characters consist of 2 bytes and the resulting string is
* NULL-terminated by a 2-byte NULL.
*
* Note that version number and (;1) is not appended.
* @param flag
* bit0= no_force_dots
* bit1= allow 103 characters rather than 64
* @return
* NULL if the original name and extension both are of length 0.
*/
@ -164,10 +173,12 @@ uint16_t *iso_j_file_id(const uint16_t *src, int flag);
* and the name and extension will be separated (.). All characters consist of
* 2 bytes and the resulting string is NULL-terminated by a 2-byte NULL.
*
* @param flag
* bit1= allow 103 characters rather than 64
* @return
* NULL if the original name and extension both are of length 0.
*/
uint16_t *iso_j_dir_id(const uint16_t *src);
uint16_t *iso_j_dir_id(const uint16_t *src, int flag);
/**
* Like strlen, but for Joliet strings.
@ -505,12 +516,26 @@ int iso_util_tag_magic(int tag_type, char **tag_magic, int *len, int flag);
*/
int checksum_cx_xinfo_func(void *data, int flag);
/* The iso_node_xinfo_cloner function which gets associated to
* checksum_cx_xinfo_func by iso_init() resp. iso_init_with_flag() via
* iso_node_xinfo_make_clonable()
*/
int checksum_cx_xinfo_cloner(void *old_data, void **new_data, int flag);
/* Function to identify and manage md5 sums of unspecified providence stored
* directly in this xinfo. This is supposed to override any other recorded
* MD5 of the node unless data get copied and checksummed during that copying.
*/
int checksum_md5_xinfo_func(void *data, int flag);
/* The iso_node_xinfo_cloner function which gets associated to
* checksum_md5_xinfo_func by iso_init() resp. iso_init_with_flag() via
* iso_node_xinfo_make_clonable()
*/
int checksum_md5_xinfo_cloner(void *old_data, void **new_data, int flag);
/* ------------------------------------------------------------------------- */