Compare commits

...

29 Commits

Author SHA1 Message Date
1d44d931d0 Version leap to 0.6.20 2009-05-30 21:24:50 +02:00
5d5a0cbfd4 Removed change timestamps of 0.6.19 2009-05-30 18:00:21 +02:00
4353a35c59 Removed some development remarks 2009-05-30 16:36:54 +02:00
2f48297d25 Removed loud warning not to activate Libisofs_hardlink_matcheR 2009-05-28 13:25:21 +02:00
dfcb815480 Removed experimental code about inode number generation from LBA.
Obsoleted macros Libisofs_ino_from_lbA Libisofs_patch_ticket_144.
2009-05-26 18:47:23 +02:00
f370829717 Removed old code for AAIP 1.0 production.
Obsoleted macro Libisofs_aaip_2_0.
2009-05-26 18:41:51 +02:00
ef96f3588c Made use of iconv wrapper function unconditionally.
Obsoleted macro Libisofs_with_iso_iconV.
2009-05-26 18:23:59 +02:00
e8fc149423 Made centralized call of setlocale() unconditional.
Obsoleted macro Libisofs_setlocale_in_iniT.
2009-05-26 18:13:15 +02:00
e12d409b80 Made sure that IsoStream from old image are equivalent only if their
data extents have same LBAs and sizes.
2009-05-24 18:22:02 +02:00
b34fd35e62 Fixed bugs in iso_node_cmp_flag() introduced with revision 559
and clarified constraints for stream comparison functions in libisofs.h
2009-05-18 15:33:36 +02:00
714ee67472 New API call iso_node_cmp_ino()
and a bug fix about IsoSpecial and IsoSymlink in iso_node_cmp_flag()
2009-05-16 18:50:23 +02:00
8c4682ae92 IsoStream version 3 with cmp_ino(),
new API call iso_stream_cmp_ino() for proper comparison of filtered streams
2009-05-12 09:29:06 +02:00
5b073a2f29 New API call iso_write_opts_set_hardlinks() controls hardlink matching,
new API call iso_write_opts_set_rrip_1_10_px_ino() controls RRIP-1.10 PX size.
2009-05-09 20:45:14 +02:00
c6f1101e9d Fixed a severe inode number mash-up from revision 554
and a minor bug introduced with revision 547 (for ticket 147).
2009-05-06 16:18:45 +02:00
f8d3bca20a Registering fs,dev,ino of nodes which stem from outside the imported image
and using fs,dev,ino of IsoSymlink and IsoSpecial.
2009-05-05 22:03:44 +02:00
46a947b602 Created means to inquire ECMA119_SYMLINK and ECMA119_SPECIAL
for their original fs,dev,ino
2009-05-03 19:21:21 +02:00
56796ff55f Introduced hardlink unification at image generation time.
For now it works only with data files or with files from the imported image.
2009-05-03 17:08:29 +02:00
1cbae01f12 Outsourced stream comparison from iso_file_src_cmp() to iso_stream_cmp_ino() 2009-05-03 08:42:45 +02:00
da4634a593 Removed a redundant test expression 2009-05-02 19:57:39 +02:00
f18d5157dc Caused image root to memorize its eventual PX inode number. 2009-05-01 16:18:59 +02:00
1195614881 Removed a redundant line of code 2009-05-01 15:02:30 +02:00
1218e6e32d New API call iso_read_opts_set_new_inos() 2009-05-01 15:00:43 +02:00
95381ce258 Made directory inodes persistent during multi-session.
The reason is to produce a continued ino history for eventual incremental
backups from ISO images.
2009-05-01 12:49:37 +02:00
19fd87ef7b Small adjustments in new code after review. 2009-04-29 12:52:32 +02:00
d20da80767 Transfering inode numbers from PX entries to IsoNode during image import
and using these numbers in PX entries during next image generation.
This also answers the concerns about PX without ino in RRIP 1.12
and PX with ino in RRIP 1.10 images produced by mkisofs.
2009-04-28 22:40:15 +02:00
5009d1038d Made early preparations for implementation of hard link persistence 2009-04-26 12:57:17 +02:00
1ae2a39d1d Registered stream types "gzip" and "pizg" 2009-04-24 08:45:03 +02:00
70af4872c9 Clarification of iso_stream_get_source_path() result 2009-04-19 07:10:22 +02:00
71d491ed37 Version leap to 0.6.19 2009-04-17 14:35:30 +02:00
27 changed files with 1591 additions and 411 deletions

View File

@ -156,27 +156,31 @@ demo_isoms_SOURCES = demo/iso_ms.c
# demo_isogrow_SOURCES = demo/iso_grow.c
## Build unit test
## ts A90428 , ticket 147, The test code does not use the API and is totally
## outdated in its creation of mocked objects.
## A volunteer is needed to rewrite it using the API.
# ## Build unit test
check_PROGRAMS = \
test/test
test_test_CPPFLAGS = -Ilibisofs
test_test_LDADD = $(libisofs_libisofs_la_OBJECTS) \
$(libisofs_libisofs_la_LIBADD) -lcunit
test_test_LDFLAGS = -L.. -lm
test_test_SOURCES = \
test/test.h \
test/test.c \
test/test_node.c \
test/test_image.c \
test/test_tree.c \
test/test_util.c \
test/test_rockridge.c \
test/test_stream.c \
test/mocked_fsrc.h \
test/mocked_fsrc.c
# check_PROGRAMS = \
# test/test
#
# test_test_CPPFLAGS = -Ilibisofs
# test_test_LDADD = $(libisofs_libisofs_la_OBJECTS) \
# $(libisofs_libisofs_la_LIBADD) -lcunit
# test_test_LDFLAGS = -L.. -lm
#
# test_test_SOURCES = \
# test/test.h \
# test/test.c \
# test/test_node.c \
# test/test_image.c \
# test/test_tree.c \
# test/test_util.c \
# test/test_rockridge.c \
# test/test_stream.c \
# test/mocked_fsrc.h \
# test/mocked_fsrc.c
## ========================================================================= ##

View File

@ -1,4 +1,4 @@
AC_INIT([libisofs], [0.6.18], [http://libburnia-project.org])
AC_INIT([libisofs], [0.6.20], [http://libburnia-project.org])
AC_PREREQ([2.50])
dnl AC_CONFIG_HEADER([config.h])
@ -44,7 +44,7 @@ dnl If LIBISOFS_*_VERSION changes, be sure to change AC_INIT above to match.
dnl
LIBISOFS_MAJOR_VERSION=0
LIBISOFS_MINOR_VERSION=6
LIBISOFS_MICRO_VERSION=18
LIBISOFS_MICRO_VERSION=20
LIBISOFS_VERSION=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION.$LIBISOFS_MICRO_VERSION
AC_SUBST(LIBISOFS_MAJOR_VERSION)
@ -54,11 +54,11 @@ AC_SUBST(LIBISOFS_VERSION)
dnl Libtool versioning
LT_RELEASE=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION
# 2009.04.15: development jump has not yet happened
# SONAME = 20 - 14 = 6 . Library name = libisofs.6.14.0
LT_CURRENT=20
# 2009.05.30 development jump has not yet happened
# SONAME = 22 - 16 = 6 . Library name = libisofs.6.16.0
LT_CURRENT=22
LT_REVISION=0
LT_AGE=14
LT_AGE=16
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
AC_SUBST(LT_RELEASE)

View File

@ -128,13 +128,7 @@ size_t aaip_encode(size_t num_attrs, char **names,
/* write the field headers */
for(i= 0; i < number_of_fields; i++) {
(*result)[i * 255 + 0]= 'A';
#ifdef Libisofs_aaip_2_0
(*result)[i * 255 + 1]= 'L';
#else /* Libisofs_aaip_2_0 */
(*result)[i * 255 + 1]= 'A';
#endif /* ! Libisofs_aaip_2_0 */
if(i < number_of_fields - 1 || (mem_size % 255) == 0)
(*result)[i * 255 + 2]= 255;
else
@ -1186,16 +1180,9 @@ static int aaip_consume_aa_head(struct aaip_state *aaip,
aaip->aa_head_missing-= todo;
if(aaip->aa_head_missing == 0) {
aaip_read_from_recs(aaip, aaip->recs_fill - 5, aa_head, 5, 0);
#ifdef Libisofs_aaip_2_0
if(aa_head[0] != 'A' || (aa_head[1] != 'L' && aa_head[1] != 'A') ||
aa_head[3] != 1)
return(-1);
#else /* Libisofs_aaip_2_0 */
if(aa_head[0] != 'A' || aa_head[1] != 'A' || aa_head[3] != 1)
return(-1);
#endif /* ! Libisofs_aaip_2_0 */
aaip->aa_missing= aa_head[2];
aaip->aa_ends= !(aa_head[4] & 1);
aaip->recs_fill-= 5; /* AAIP field heads do not get delivered */

View File

@ -92,6 +92,7 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
int ret;
struct stat info;
IsoNode *new;
IsoFilesystem *fs;
char *name;
unsigned char *aa_string;
char *a_text = NULL, *d_text = NULL;
@ -111,6 +112,7 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
}
name = iso_file_source_get_name(src);
fs = iso_file_source_get_filesystem(src);
new = NULL;
switch (info.st_mode & S_IFMT) {
@ -154,6 +156,13 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
}
ret = iso_node_new_symlink(name, strdup(dest), &link);
new = (IsoNode*) link;
if (fs != NULL) {
link->fs_id = fs->get_id(fs);
if (link->fs_id != 0) {
link->st_ino = info.st_ino;
link->st_dev = info.st_dev;
}
}
}
break;
case S_IFSOCK:
@ -166,6 +175,13 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
ret = iso_node_new_special(name, info.st_mode, info.st_rdev,
&special);
new = (IsoNode*) special;
if (fs != NULL) {
special->fs_id = fs->get_id(fs);
if (special->fs_id != 0) {
special->st_ino = info.st_ino;
special->st_dev = info.st_dev;
}
}
}
break;
}

View File

@ -887,9 +887,14 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
target->rockridge = opts->rockridge;
target->joliet = opts->joliet;
target->iso1999 = opts->iso1999;
target->hardlinks = opts->hardlinks;
target->aaip = opts->aaip;
target->always_gmt = opts->always_gmt;
#ifndef Libisofs_hardlink_matcheR
target->ino = 0;
#endif
target->omit_version_numbers = opts->omit_version_numbers
| opts->max_37_char_filenames;
target->allow_deep_paths = opts->allow_deep_paths;
@ -901,6 +906,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
target->relaxed_vol_atts = opts->relaxed_vol_atts;
target->joliet_longer_paths = opts->joliet_longer_paths;
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;
target->dir_rec_mtime = opts->dir_rec_mtime;
target->sort_files = opts->sort_files;
@ -927,16 +933,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
target->eltorito = (src->bootcat == NULL ? 0 : 1);
target->catalog = src->bootcat;
#ifndef Libisofs_setlocale_in_iniT
/* default to locale charset */
/* ??? ts Nov 25 2008 :
Shouldn't this go to library initialization or even to app ?
*/
setlocale(LC_CTYPE, "");
#endif
target->input_charset = strdup(iso_get_local_charset(0));
if (target->input_charset == NULL) {
iso_image_unref(src);
free(target);
@ -1427,6 +1424,15 @@ int iso_write_opts_set_iso1999(IsoWriteOpts *opts, int enable)
return ISO_SUCCESS;
}
int iso_write_opts_set_hardlinks(IsoWriteOpts *opts, int enable)
{
if (opts == NULL) {
return ISO_NULL_POINTER;
}
opts->hardlinks = enable ? 1 : 0;
return ISO_SUCCESS;
}
int iso_write_opts_set_aaip(IsoWriteOpts *opts, int enable)
{
if (opts == NULL) {
@ -1526,6 +1532,15 @@ int iso_write_opts_set_rrip_version_1_10(IsoWriteOpts *opts, int oldvers)
return ISO_SUCCESS;
}
int iso_write_opts_set_rrip_1_10_px_ino(IsoWriteOpts *opts, int enable)
{
if (opts == NULL) {
return ISO_NULL_POINTER;
}
opts->rrip_1_10_px_ino = enable ? 1 : 0;
return ISO_SUCCESS;
}
int iso_write_opts_set_aaip_susp_1_10(IsoWriteOpts *opts, int oldvers)
{
if (opts == NULL) {

View File

@ -115,6 +115,16 @@ struct iso_write_opts {
*/
unsigned int rrip_version_1_10 :1;
/**
* Write field PX with file serial number even with RRIP-1.10
*/
unsigned int rrip_1_10_px_ino :1;
/**
* See iso_write_opts_set_hardlinks()
*/
unsigned int hardlinks:1;
/**
* Write AAIP as extension according to SUSP 1.10 rather than SUSP 1.12.
* I.e. without announcing it by an ER field and thus without the need
@ -269,7 +279,9 @@ struct ecma119_image
unsigned int eltorito :1;
unsigned int iso1999 :1;
unsigned int aaip :1; /* whether to write eventual ACLs and EAs */
unsigned int hardlinks:1; /* see iso_write_opts_set_hardlinks() */
unsigned int aaip :1; /* see iso_write_opts_set_aaip() */
/* allways write timestamps in GMT */
unsigned int always_gmt :1;
@ -291,6 +303,9 @@ struct ecma119_image
/** Write old fashioned RRIP-1.10 rather than RRIP-1.12 */
unsigned int rrip_version_1_10 :1;
/** Write field PX with file serial number even with RRIP-1.10 */
unsigned int rrip_1_10_px_ino :1;
/* Write AAIP as extension according to SUSP 1.10 rather than SUSP 1.12. */
unsigned int aaip_susp_1_10 :1;
@ -318,12 +333,18 @@ struct ecma119_image
*/
int sort_files;
#ifndef Libisofs_hardlink_matcheR
/* ts A90508 : <<< this is on its way out */
/**
* In the CD, each file must have an unique inode number. So each
* time we add a new file, this is incremented.
*/
ino_t ino;
#endif /* ! Libisofs_hardlink_matcheR */
char *input_charset;
char *output_charset;

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 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 as
@ -106,10 +107,38 @@ int create_ecma119_node(Ecma119Image *img, IsoNode *iso, Ecma119Node **node)
ecma->node = iso;
iso_node_ref(iso);
/* TODO #00009 : add true support for harlinks and inode numbers */
ecma->nlink = 1;
#ifndef Libisofs_hardlink_matcheR
/* ts A90503 : This is obsolete with Libisofs_hardlink_matcheR
which will later hand out image inode numbers for all. */
#ifdef Libisofs_hardlink_prooF
/* Looking only for valid ISO image inode numbers. */
{
unsigned int fs_id;
dev_t dev_id;
int ret;
ret = iso_node_get_id(iso, &fs_id, &dev_id, &(ecma->ino), 1);
if (ret < 0) {
return ret;
} else if (ret == 0) {
/* What has not got a valid ISO image inode yet, gets it now. */
ecma->ino = img_give_ino_number(img->image, 0);
}
}
#else /* Libisofs_hardlink_prooF */
/* TODO #00009 : add true support for harlinks and inode numbers */
ecma->ino = ++img->ino;
#endif /* ! Libisofs_hardlink_prooF */
#endif /* ! Libisofs_hardlink_matcheR */
*node = ecma;
return ISO_SUCCESS;
}
@ -811,6 +840,174 @@ int reorder_tree(Ecma119Image *img, Ecma119Node *dir, int level, int pathlen)
return ISO_SUCCESS;
}
/*
* @param flag
* bit0= recursion
* bit1= count nodes rather than fill them into *nodes
* @return
* <0 error
* bit0= saw ino == 0
* bit1= saw ino != 0
*/
static
int make_node_array(Ecma119Image *img, Ecma119Node *dir,
Ecma119Node **nodes, size_t nodes_size, size_t *node_count,
int flag)
{
int ret, result = 0;
size_t i;
Ecma119Node *child;
if (!(flag & 1)) {
*node_count = 0;
if (!(flag & 2)) {
/* Register the tree root node */
if (*node_count >= nodes_size) {
iso_msg_submit(img->image->id, ISO_ASSERT_FAILURE, 0,
"Programming error: Overflow of hardlink sort array");
return ISO_ASSERT_FAILURE;
}
nodes[*node_count] = dir;
}
result|= (dir->ino == 0 ? 1 : 2);
(*node_count)++;
}
for (i = 0; i < dir->info.dir->nchildren; i++) {
child = dir->info.dir->children[i];
if (!(flag & 2)) {
if (*node_count >= nodes_size) {
iso_msg_submit(img->image->id, ISO_ASSERT_FAILURE, 0,
"Programming error: Overflow of hardlink sort array");
return ISO_ASSERT_FAILURE;
}
nodes[*node_count] = child;
}
result|= (child->ino == 0 ? 1 : 2);
(*node_count)++;
if (child->type == ECMA119_DIR) {
ret = make_node_array(img, child,
nodes, nodes_size, node_count, flag | 1);
if (ret < 0)
return ret;
}
}
return result;
}
/*
* @param flag
* bit0= compare stat properties and attributes
* bit1= treat all nodes with image ino == 0 as unique
*/
static
int ecma119_node_cmp_flag(const void *v1, const void *v2, int flag)
{
int ret;
Ecma119Node *n1, *n2;
n1 = *((Ecma119Node **) v1);
n2 = *((Ecma119Node **) v2);
if (n1 == n2)
return 0;
ret = iso_node_cmp_flag(n1->node, n2->node, flag & (1 | 2));
return ret;
}
static
int ecma119_node_cmp_hard(const void *v1, const void *v2)
{
return ecma119_node_cmp_flag(v1, v2, 1);
}
static
int ecma119_node_cmp_nohard(const void *v1, const void *v2)
{
return ecma119_node_cmp_flag(v1, v2, 1 | 2);
}
static
int family_set_ino(Ecma119Image *img, Ecma119Node **nodes, size_t family_start,
size_t next_family, ino_t img_ino, ino_t prev_ino, int flag)
{
size_t i;
if (img_ino != 0) {
/* Check whether this is the same img_ino as in the previous
family (e.g. by property divergence of imported hardlink).
*/
if (img_ino == prev_ino)
img_ino = 0;
}
if (img_ino == 0) {
img_ino = img_give_ino_number(img->image, 0);
}
for (i = family_start; i < next_family; i++) {
nodes[i]->ino = img_ino;
nodes[i]->nlink = next_family - family_start;
}
return 1;
}
static
int match_hardlinks(Ecma119Image *img, Ecma119Node *dir, int flag)
{
int ret;
size_t nodes_size = 0, node_count = 0, i, family_start;
Ecma119Node **nodes = NULL;
unsigned int fs_id;
dev_t dev_id;
ino_t img_ino = 0, prev_ino = 0;
ret = make_node_array(img, dir, nodes, nodes_size, &node_count, 2);
if (ret < 0)
return ret;
nodes_size = node_count;
nodes = (Ecma119Node **) calloc(sizeof(Ecma119Node *), nodes_size);
if (nodes == NULL)
return ISO_OUT_OF_MEM;
ret = make_node_array(img, dir, nodes, nodes_size, &node_count, 0);
if (ret < 0)
goto ex;
/* Sort according to id tuples, IsoFileSrc identity, properties, xattr. */
if (img->hardlinks)
qsort(nodes, node_count, sizeof(Ecma119Node *), ecma119_node_cmp_hard);
else
qsort(nodes, node_count, sizeof(Ecma119Node *),
ecma119_node_cmp_nohard);
/* Hand out image inode numbers to all Ecma119Node.ino == 0 .
Same sorting rank gets same inode number.
Split those image inode number families where the sort criterion
differs.
*/
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) {
/* 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);
prev_ino = img_ino;
iso_node_get_id(nodes[i]->node, &fs_id, &dev_id, &img_ino, 1);
family_start = i;
}
family_set_ino(img, nodes, family_start, i, img_ino, prev_ino, 0);
ret = ISO_SUCCESS;
ex:;
if (nodes != NULL)
free((char *) nodes);
return ret;
}
int ecma119_tree_create(Ecma119Image *img)
{
int ret;
@ -826,6 +1023,16 @@ int ecma119_tree_create(Ecma119Image *img)
}
img->root = root;
#ifdef Libisofs_hardlink_matcheR
iso_msg_debug(img->image->id, "Matching hardlinks...");
ret = match_hardlinks(img, img->root, 0);
if (ret < 0) {
return ret;
}
#endif /* ! Libisofs_hardlink_matcheR */
iso_msg_debug(img->image->id, "Sorting the low level tree...");
sort_tree(root);

View File

@ -62,8 +62,10 @@ struct ecma119_node
IsoNode *node; /*< reference to the iso node */
/* TODO #00009 : add true support for harlinks and inode numbers */
/* >>> ts A90501 : Shouldn't this be uint32_t
as this is what PX will take ? */
ino_t ino;
nlink_t nlink;
/**< file, symlink, special, directory or placeholder */

View File

@ -12,49 +12,28 @@
#include "writer.h"
#include "messages.h"
#include "image.h"
#include "stream.h"
#include <stdlib.h>
#include <string.h>
#include <limits.h>
int iso_file_src_cmp(const void *n1, const void *n2)
{
int ret;
const IsoFileSrc *f1, *f2;
unsigned int fs_id1, fs_id2;
dev_t dev_id1, dev_id2;
ino_t ino_id1, ino_id2;
off_t size1, size2;
if (n1 == n2) {
return 0; /* Normally just a shortcut.
But important if Libisofs_file_src_cmp_non_zerO */
}
f1 = (const IsoFileSrc *)n1;
f2 = (const IsoFileSrc *)n2;
iso_stream_get_id(f1->stream, &fs_id1, &dev_id1, &ino_id1);
iso_stream_get_id(f2->stream, &fs_id2, &dev_id2, &ino_id2);
if (fs_id1 < fs_id2) {
return -1;
} else if (fs_id1 > fs_id2) {
return 1;
} else {
/* files belong to the same fs */
if (dev_id1 > dev_id2) {
return -1;
} else if (dev_id1 < dev_id2) {
return 1;
} else if (ino_id1 < ino_id2) {
return -1;
} else if (ino_id1 > ino_id2) {
return 1;
} else {
size1 = iso_stream_get_size(f1->stream);
size2 = iso_stream_get_size(f2->stream);
if (size1 < size2) {
return -1;
} else if (size1 > size2) {
return 1;
}
return 0;
}
}
ret = iso_stream_cmp_ino(f1->stream, f2->stream, 0);
return ret;
}
int iso_file_src_create(Ecma119Image *img, IsoFile *file, IsoFileSrc **src)

View File

@ -594,8 +594,13 @@ IsoStream *extf_get_input_stream(IsoStream *stream, int flag)
}
static
int extf_cmp_ino(IsoStream *s1, IsoStream *s2);
/* Function is defined after definition of extf_stream_class */
IsoStreamIface extf_stream_class = {
2,
3,
"extf",
extf_stream_open,
extf_stream_close,
@ -605,10 +610,28 @@ IsoStreamIface extf_stream_class = {
extf_stream_get_id,
extf_stream_free,
extf_update_size,
extf_get_input_stream
extf_get_input_stream,
extf_cmp_ino
};
static
int extf_cmp_ino(IsoStream *s1, IsoStream *s2)
{
ExternalFilterStreamData *data1, *data2;
if (s1->class != &extf_stream_class || s2->class != &extf_stream_class)
return iso_stream_cmp_ino(s1, s2, 1);
data1 = (ExternalFilterStreamData*) s1->data;
data2 = (ExternalFilterStreamData*) s2->data;
if (data1->cmd != data2->cmd)
return (data1->cmd < data2->cmd ? -1 : 1);
return iso_stream_cmp_ino(data1->orig, data2->orig, 0);
}
/* ------------------------------------------------------------------------- */
static
void extf_filter_free(FilterContext *filter)
{

View File

@ -521,8 +521,12 @@ IsoStream *gzip_get_input_stream(IsoStream *stream, int flag)
}
static
int gzip_cmp_ino(IsoStream *s1, IsoStream *s2);
IsoStreamIface gzip_stream_compress_class = {
2,
3,
"gzip",
gzip_stream_open,
gzip_stream_close,
@ -532,12 +536,13 @@ IsoStreamIface gzip_stream_compress_class = {
gzip_stream_get_id,
gzip_stream_free,
gzip_update_size,
gzip_get_input_stream
gzip_get_input_stream,
gzip_cmp_ino
};
IsoStreamIface gzip_stream_uncompress_class = {
2,
3,
"pizg",
gzip_stream_open,
gzip_stream_close,
@ -547,9 +552,24 @@ IsoStreamIface gzip_stream_uncompress_class = {
gzip_stream_get_id,
gzip_stream_free,
gzip_update_size,
gzip_get_input_stream
gzip_get_input_stream,
gzip_cmp_ino
};
static
int gzip_cmp_ino(IsoStream *s1, IsoStream *s2)
{
if (s1->class != s2->class || (s1->class != &gzip_stream_compress_class &&
s2->class != &gzip_stream_compress_class))
return iso_stream_cmp_ino(s1, s2, 1);
return iso_stream_cmp_ino(iso_stream_get_input_stream(s1, 0),
iso_stream_get_input_stream(s2, 0), 0);
}
/* ------------------------------------------------------------------------- */
static
void gzip_filter_free(FilterContext *filter)

View File

@ -775,8 +775,12 @@ IsoStream *ziso_get_input_stream(IsoStream *stream, int flag)
}
static
int ziso_cmp_ino(IsoStream *s1, IsoStream *s2);
IsoStreamIface ziso_stream_compress_class = {
2,
3,
"ziso",
ziso_stream_open,
ziso_stream_close,
@ -786,12 +790,13 @@ IsoStreamIface ziso_stream_compress_class = {
ziso_stream_get_id,
ziso_stream_free,
ziso_update_size,
ziso_get_input_stream
ziso_get_input_stream,
ziso_cmp_ino
};
IsoStreamIface ziso_stream_uncompress_class = {
2,
3,
"osiz",
ziso_stream_open,
ziso_stream_close,
@ -801,10 +806,25 @@ IsoStreamIface ziso_stream_uncompress_class = {
ziso_stream_get_id,
ziso_stream_free,
ziso_update_size,
ziso_get_input_stream
ziso_get_input_stream,
ziso_cmp_ino
};
static
int ziso_cmp_ino(IsoStream *s1, IsoStream *s2)
{
if (s1->class != s2->class || (s1->class != &ziso_stream_compress_class &&
s2->class != &ziso_stream_uncompress_class))
iso_stream_cmp_ino(s1, s2, 1);
return iso_stream_cmp_ino(iso_stream_get_input_stream(s1, 0),
iso_stream_get_input_stream(s2, 0), 0);
}
/* ------------------------------------------------------------------------- */
static
void ziso_filter_free(FilterContext *filter)
{

View File

@ -63,6 +63,12 @@ struct iso_read_opts
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 */
/**
* Hand out new inode numbers and overwrite eventually read PX inode
* numbers. This will split apart any hardlinks.
*/
unsigned int make_new_ino : 1 ;
/**
* When both Joliet and RR extensions are present, the RR tree is used.
* If you prefer using Joliet, set this to 1.
@ -88,6 +94,7 @@ struct iso_read_opts
* attribute "isofs.cs" of root directory
*/
int auto_input_charset;
};
/**
@ -137,6 +144,7 @@ enum read_rr_ext {
RR_EXT_112 = 2 /*< RR extensions conforming version 1.12 */
};
/**
* Private data for the image IsoFilesystem
*/
@ -261,9 +269,20 @@ typedef struct
uint32_t imgblock; /**< Block for El-Torito boot image */
uint32_t catblock; /**< Block for El-Torito catalog */
/* Whether inode numbers from PX entries shall be discarded */
unsigned int make_new_ino : 1 ;
/* Inode number generator counter */
ino_t inode_counter;
/* PX inode number status
bit0= there were nodes with PX inode numbers
bit1= there were nodes with PX but without inode numbers
bit2= there were nodes without PX
bit3= there were nodes with faulty PX
*/
int px_ino_status;
} _ImageFsData;
typedef struct image_fs_data ImageFileSourceData;
@ -1070,6 +1089,8 @@ char *get_name(_ImageFsData *fsdata, const char *str, size_t len)
}
#ifndef Libisofs_hardlink_prooF
/**
* A global counter for default inode numbers for the ISO image filesystem.
* @param fs The filesystem where the number shall be used
@ -1087,11 +1108,13 @@ ino_t fs_give_ino_number(IsoImageFilesystem *fs, int flag)
if (fsdata->inode_counter == 0) {
/* >>> raise alert because of inode rollover */;
}
return fsdata->inode_counter;
}
#endif /* ! Libisofs_hardlink_prooF */
/**
*
@ -1135,6 +1158,8 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
size_t cs_value_length = 0;
char msg[160];
int has_px = 0;
#ifdef Libisofs_with_zliB
uint8_t zisofs_alg[2], zisofs_hs4 = 0, zisofs_bsl2 = 0;
uint32_t zisofs_usize = 0;
@ -1147,6 +1172,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
fsdata = (_ImageFsData*)fs->data;
memset(&atts, 0, sizeof(struct stat));
atts.st_nlink = 1;
/*
* First of all, check for unsupported ECMA-119 features
@ -1275,12 +1301,22 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
continue;
if (SUSP_SIG(sue, 'P', 'X')) {
has_px = 1;
ret = read_rr_PX(sue, &atts);
if (ret < 0) {
/* notify and continue */
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR_WARN, ret,
"Invalid PX entry");
fsdata->px_ino_status |= 8;
} if (ret == 2) {
if (fsdata->inode_counter < atts.st_ino)
fsdata->inode_counter = atts.st_ino;
fsdata->px_ino_status |= 1;
} else {
fsdata->px_ino_status |= 2;
}
} else if (SUSP_SIG(sue, 'T', 'F')) {
ret = read_rr_TF(sue, &atts);
if (ret < 0) {
@ -1536,6 +1572,10 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
}
}
if (!has_px) {
fsdata->px_ino_status |= 4;
}
/*
* if we haven't RR extensions, or no NM entry is present,
* we use the name in directory record
@ -1596,9 +1636,18 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
/* but the real name is the name of the placeholder */
ifsdata = (ImageFileSourceData*) (*src)->data;
ifsdata->name = name;
return ISO_SUCCESS;
}
#ifdef Libisofs_hardlink_prooF
/* Production of missing inode numbers is delayed until the image is
complete. Then all nodes which shall get a new inode number will
be served.
*/
#else /* Libisofs_hardlink_prooF */
#ifdef Libisofs_new_fs_image_inO
@ -1611,6 +1660,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
#else /* Libisofs_new_fs_image_inO */
/* ts Nov 25 2008: TODO
This seems not fully consistent with read_rr_PX() which decides
by (px->len_sue[0] == 44) whether an inode number is present or not.
@ -1630,19 +1680,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
* to generate those serial numbers, and we use extend block instead.
* It BREAKS POSIX SEMANTICS, but its suitable for our needs
*/
#ifndef Libisofs_ino_from_lbA
#define Libisofs_patch_ticket_144 yes
#endif
#ifdef Libisofs_patch_ticket_144
atts.st_ino = fs_give_ino_number(fs, 0);
#else
/* Ticket 144: This produces duplicate numbers with empty files.
*/
atts.st_ino = (ino_t) iso_read_bb(record->block, 4, NULL);
#endif
if (fsdata->rr == 0) {
atts.st_nlink = 1;
}
@ -1650,6 +1688,8 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
#endif /* ! Libisofs_new_fs_image_inO */
#endif /* ! Libisofs_hardlink_prooF */
/*
* if we haven't RR extensions, or a needed TF time stamp is not present,
* we use plain iso recording time
@ -1974,7 +2014,6 @@ void ifs_fs_free(IsoFilesystem *fs)
free(data->copyright_file_id);
free(data->abstract_file_id);
free(data->biblio_file_id);
free(data->input_charset);
free(data->local_charset);
free(data);
@ -2273,13 +2312,9 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
data->msgid = msgid;
data->aaip_load = !opts->noaaip;
data->aaip_version = -1;
#ifndef Libisofs_setlocale_in_iniT
/* ??? ts Nov 25 2008 :
Shouldn't this go to library initialization or even to app ?
*/
setlocale(LC_CTYPE, "");
#endif
data->make_new_ino = opts->make_new_ino;
data->inode_counter = 0;
data->px_ino_status = 0;
data->local_charset = strdup(iso_get_local_charset(0));
if (data->local_charset == NULL) {
@ -2522,6 +2557,7 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
IsoNode *new;
char *name;
ImageFileSourceData *data;
_ImageFsData *fsdata;
#ifdef Libisofs_with_zliB
/* Intimate friendship with this function in filters/zisofs.c */
@ -2536,6 +2572,7 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
}
data = (ImageFileSourceData*)src->data;
fsdata = data->fs->data;
name = iso_file_source_get_name(src);
@ -2550,7 +2587,6 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
case S_IFREG:
{
/* source is a regular file */
_ImageFsData *fsdata = data->fs->data;
/* El-Torito images have only one section */
if (fsdata->eltorito && data->sections[0].block == fsdata->catblock) {
@ -2677,6 +2713,13 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
}
link->dest = strdup(dest);
link->node.type = LIBISO_SYMLINK;
#ifdef Libisofs_hardlink_matcheR
link->fs_id = ISO_IMAGE_FS_ID;
link->st_dev = info.st_dev;
link->st_ino = info.st_ino;
#endif
new = (IsoNode*) link;
new->refcount = 0;
}
@ -2695,6 +2738,13 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
}
special->dev = info.st_rdev;
special->node.type = LIBISO_SPECIAL;
#ifdef Libisofs_hardlink_matcheR
special->fs_id = ISO_IMAGE_FS_ID;
special->st_dev = info.st_dev;
special->st_ino = info.st_ino;
#endif
new = (IsoNode*) special;
new->refcount = 0;
}
@ -2718,15 +2768,30 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
ret = src_aa_to_node(src, new, 0);
if (ret < 0) {
/* todo: stuff any possible memory leak here */
if (name != NULL)
free(name);
free(new);
return ret;
goto failure;
}
#ifdef Libisofs_hardlink_prooF
/* Attach ino as xinfo if valid and no IsoStream is involved */
if (info.st_ino != 0 && (info.st_mode & S_IFMT) != S_IFREG &&
!fsdata->make_new_ino) {
ret = iso_node_set_ino(new, info.st_ino, 0);
if (ret < 0)
goto failure;
}
#endif /* Libisofs_hardlink_prooF */
*node = new;
return ISO_SUCCESS;
failure:;
/* todo: stuff any possible memory leak here */
if (name != NULL)
free(name);
free(new);
return ret;
}
/**
@ -2763,7 +2828,8 @@ int iso_image_builder_new(IsoNodeBuilder *old, IsoNodeBuilder **builder)
* accessible from the ISO filesystem.
*/
static
int create_boot_img_filesrc(IsoImageFilesystem *fs, IsoFileSource **src)
int create_boot_img_filesrc(IsoImageFilesystem *fs, IsoImage *image,
IsoFileSource **src)
{
int ret;
struct stat atts;
@ -2780,6 +2846,12 @@ int create_boot_img_filesrc(IsoImageFilesystem *fs, IsoFileSource **src)
memset(&atts, 0, sizeof(struct stat));
atts.st_mode = S_IFREG;
#ifdef Libisofs_hardlink_prooF
atts.st_ino = img_give_ino_number(image, 0);
#else /* Libisofs_hardlink_prooF */
#ifdef Libisofs_new_fs_image_inO
atts.st_ino = fs_give_ino_number(fs, 0);
@ -2790,6 +2862,8 @@ int create_boot_img_filesrc(IsoImageFilesystem *fs, IsoFileSource **src)
#endif /* ! Libisofs_new_fs_image_inO */
#endif /* ! Libisofs_hardlink_prooF */
atts.st_nlink = 1;
/*
@ -2852,7 +2926,7 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
struct iso_read_opts *opts,
IsoReadImageFeatures **features)
{
int ret;
int ret, hflag;
IsoImageFilesystem *fs;
IsoFilesystem *fsback;
IsoNodeBuilder *blback;
@ -2915,6 +2989,17 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
if (ret < 0)
goto import_revert;
#ifdef Libisofs_hardlink_prooF
/* Attach ino as xinfo if valid */
if (info.st_ino != 0 && !data->make_new_ino) {
ret = iso_node_set_ino(&(image->root->node), info.st_ino, 0);
if (ret < 0)
goto import_revert;
}
#endif /* Libisofs_hardlink_prooF */
}
/* if old image has el-torito, add a new catalog */
@ -2951,12 +3036,36 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
goto import_revert;
}
#ifdef Libisofs_hardlink_prooF
/* Take over inode management from IsoImageFilesystem.
data->inode_counter is supposed to hold the maximum PX inode number.
*/
image->inode_counter = data->inode_counter;
if ((data->px_ino_status & (2 | 4 | 8)) || opts->make_new_ino) {
/* Attach new inode numbers to any node which does not have one,
resp. to all nodes in case of opts->make_new_ino
*/
if (opts->make_new_ino)
hflag = 1; /* Equip all data files with new unique inos */
else
hflag = 2 | 4 | 8; /* Equip any file type if it has ino == 0 */
ret = img_make_inos(image, image->root, hflag);
if (ret < 0) {
iso_node_builder_unref(image->builder);
goto import_revert;
}
}
#endif /* ! Libisofs_hardlink_prooF */
if (data->eltorito) {
/* if catalog and image nodes were not filled, we create them here */
if (image->bootcat->image->image == NULL) {
IsoFileSource *src;
IsoNode *node;
ret = create_boot_img_filesrc(fs, &src);
ret = create_boot_img_filesrc(fs, image, &src);
if (ret < 0) {
iso_node_builder_unref(image->builder);
goto import_revert;
@ -3177,6 +3286,16 @@ int iso_read_opts_set_no_aaip(IsoReadOpts *opts, int noaaip)
return ISO_SUCCESS;
}
int iso_read_opts_set_new_inos(IsoReadOpts *opts, int new_inos)
{
if (opts == NULL) {
return ISO_NULL_POINTER;
}
opts->make_new_ino = new_inos ? 1 : 0;
return ISO_SUCCESS;
}
int iso_read_opts_set_preferjoliet(IsoReadOpts *opts, int preferjoliet)
{
if (opts == NULL) {
@ -3355,3 +3474,29 @@ int iso_file_get_old_image_sections(IsoFile *file, int *section_count,
}
return 0;
}
/* Rank two IsoFileSource by their eventual old image LBAs.
Other IsoFileSource classes will be ranked only roughly.
*/
int iso_ifs_sections_cmp(IsoFileSource *s1, IsoFileSource *s2, int flag)
{
int i;
ImageFileSourceData *d1, *d2;
if (s1->class != s2->class)
return (s1->class < s2->class ? -1 : 1);
if (s1->class != &ifs_class)
return(0);
d1= s1->data;
d2= s2->data;
for (i = 0; i < d1->nsections; i++) {
if (i >= d2->nsections)
return 1;
if (d1->sections[i].block != d2->sections[i].block)
return (d1->sections[i].block < d2->sections[i].block ? -1 : 1);
if (d1->sections[i].size != d2->sections[i].size)
return (d1->sections[i].size < d2->sections[i].size ? -1 : 1);
}
return(0);
}

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 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 as
@ -30,4 +31,10 @@
*/
int iso_local_filesystem_new(IsoFilesystem **fs);
/* Rank two IsoFileSource 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);
#endif /*LIBISO_FSOURCE_H_*/

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 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 as
@ -14,6 +15,7 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
/**
* Create a new image, empty.
@ -73,6 +75,9 @@ int iso_image_new(const char *name, IsoImage **image)
}
img->builder_ignore_acl = 1;
img->builder_ignore_ea = 1;
img->inode_counter = 0;
img->used_inodes = NULL;
img->used_inodes_start = 0;
*image = img;
return ISO_SUCCESS;
}
@ -119,6 +124,8 @@ void iso_image_unref(IsoImage *image)
free(image->copyright_file_id);
free(image->abstract_file_id);
free(image->biblio_file_id);
if (image->used_inodes != NULL)
free(image->used_inodes);
free(image);
}
}
@ -318,3 +325,207 @@ void iso_image_set_ignore_aclea(IsoImage *image, int what)
image->builder_ignore_ea = !!(what & 2);
}
static
int img_register_ino(IsoImage *image, IsoNode *node, int flag)
{
int ret;
ino_t ino;
unsigned int fs_id;
dev_t dev_id;
ret = iso_node_get_id(node, &fs_id, &dev_id, &ino, 1);
if (ret < 0)
return ret;
if (ret > 0 && ino >= image->used_inodes_start &&
ino <= image->used_inodes_start + (ISO_USED_INODE_RANGE - 1)) {
/* without -1 : rollover hazard on 32 bit */
image->used_inodes[(ino - image->used_inodes_start) / 8]
|= (1 << (ino % 8));
}
return 1;
}
/* Collect the bitmap of used inode numbers in the range of
_ImageFsData.used_inodes_start + ISO_USED_INODE_RANGE
@param flag bit0= recursion is active
*/
int img_collect_inos(IsoImage *image, IsoDir *dir, int flag)
{
int ret, register_dir = 1;
IsoDirIter *iter = NULL;
IsoNode *node;
IsoDir *subdir;
if (dir == NULL)
dir = image->root;
if (image->used_inodes == NULL) {
image->used_inodes = calloc(ISO_USED_INODE_RANGE / 8, 1);
if (image->used_inodes == NULL)
return ISO_OUT_OF_MEM;
} else if(!(flag & 1)) {
memset(image->used_inodes, 0, ISO_USED_INODE_RANGE / 8);
} else {
register_dir = 0;
}
if (register_dir) {
node = (IsoNode *) dir;
ret = img_register_ino(image, node, 0);
if (ret < 0)
return ret;
}
ret = iso_dir_get_children(dir, &iter);
if (ret < 0)
return ret;
while (iso_dir_iter_next(iter, &node) == 1 ) {
ret = img_register_ino(image, node, 0);
if (ret < 0)
goto ex;
if (iso_node_get_type(node) == LIBISO_DIR) {
subdir = (IsoDir *) node;
ret = img_collect_inos(image, subdir, flag | 1);
if (ret < 0)
goto ex;
}
}
ret = 1;
ex:;
if (iter != NULL)
iso_dir_iter_free(iter);
return ret;
}
/**
* A global counter for inode numbers for the ISO image filesystem.
* On image import it gets maxed by the eventual inode numbers from PX
* entries. Up to the first 32 bit rollover it simply increments the counter.
* After the first rollover it uses a look ahead bitmap which gets filled
* by a full tree traversal. It covers the next inode numbers to come
* (somewhere between 1 and ISO_USED_INODE_RANGE which is quite many)
* and advances when being exhausted.
* @param image The image where the number shall be used
* @param flag bit0= reset count (Caution: image must get new inos then)
* @return
* Since ino_t 0 is used as default and considered self-unique,
* the value 0 should only be returned in case of error.
*/
ino_t img_give_ino_number(IsoImage *image, int flag)
{
int ret;
ino_t new_ino, ino_idx;
static uint64_t limit = 0xffffffff;
if (flag & 1) {
image->inode_counter = 0;
if (image->used_inodes != NULL)
free(image->used_inodes);
image->used_inodes = NULL;
image->used_inodes_start = 0;
}
new_ino = image->inode_counter + 1;
if (image->used_inodes == NULL) {
if (new_ino > 0 && new_ino <= limit) {
image->inode_counter = new_ino;
return image->inode_counter;
}
}
/* Look for free number in used territory */
while (1) {
if (new_ino <= 0 || new_ino > limit ||
new_ino >= image->used_inodes_start + ISO_USED_INODE_RANGE ) {
/* Collect a bitmap of used inode numbers ahead */
image->used_inodes_start += ISO_USED_INODE_RANGE;
if (image->used_inodes_start > 0xffffffff ||
image->used_inodes_start <= 0)
image->used_inodes_start = 0;
ret = img_collect_inos(image, NULL, 0);
if (ret < 0)
goto return_result; /* >>> need error return value */
new_ino = image->used_inodes_start + !image->used_inodes_start;
}
ino_idx = (new_ino - image->used_inodes_start) / 8;
if (!(image->used_inodes[ino_idx] & (1 << (new_ino % 8)))) {
image->used_inodes[ino_idx] |= (1 << (new_ino % 8));
break;
}
new_ino++;
}
return_result:;
image->inode_counter = new_ino;
return image->inode_counter;
}
/* @param flag bit0= overwrite any ino, else only ino == 0
bit1= install inode with non-data, non-directory files
bit2= install inode with directories
*/
static
int img_update_ino(IsoImage *image, IsoNode *node, int flag)
{
int ret;
ino_t ino;
unsigned int fs_id;
dev_t dev_id;
ret = iso_node_get_id(node, &fs_id, &dev_id, &ino, 1);
if (ret < 0)
return ret;
if (ret == 0)
ino = 0;
if (((flag & 1) || ino == 0) &&
(iso_node_get_type(node) == LIBISO_FILE || (flag & (2 | 4))) &&
((flag & 4) || iso_node_get_type(node) != LIBISO_DIR)) {
ret = iso_node_set_unique_id(node, image, 0);
if (ret < 0)
return ret;
}
return 1;
}
/* @param flag bit0= overwrite any ino, else only ino == 0
bit1= install inode with non-data, non-directory files
bit2= install inode with directories
bit3= with bit2: install inode on parameter dir
*/
int img_make_inos(IsoImage *image, IsoDir *dir, int flag)
{
int ret;
IsoDirIter *iter = NULL;
IsoNode *node;
IsoDir *subdir;
if (flag & 8) {
node = (IsoNode *) dir;
ret = img_update_ino(image, node, flag & 7);
if (ret < 0)
goto ex;
}
ret = iso_dir_get_children(dir, &iter);
if (ret < 0)
return ret;
while (iso_dir_iter_next(iter, &node) == 1) {
ret = img_update_ino(image, node, flag & 7);
if (ret < 0)
goto ex;
if (iso_node_get_type(node) == LIBISO_DIR) {
subdir = (IsoDir *) node;
ret = img_make_inos(image, subdir, flag & ~8);
if (ret < 0)
goto ex;
}
}
ret = 1;
ex:;
if (iter != NULL)
iso_dir_iter_free(iter);
return ret;
}

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 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 as
@ -13,6 +14,14 @@
#include "fsource.h"
#include "builder.h"
/* Size of a inode recycling window. Each new window causes a tree traversal.
Window memory consumption is ISO_USED_INODE_RANGE / 8.
This must be a power of 2 smaller than 30 bit and larger than 8 bit.
Here: 32 kB memory for 256k inodes.
*/
#define ISO_USED_INODE_RANGE (1 << 18)
/*
* Image is a context for image manipulation.
* Global objects such as the message_queues must belogn to that
@ -121,6 +130,55 @@ struct Iso_Image
*/
void *user_data;
void (*user_data_free)(void *ptr);
/**
* Inode number management. inode_counter is taken over from
* IsoImageFilesystem._ImageFsData after image import.
* It is to be used with img_give_ino_number()
*/
ino_t inode_counter;
/*
* A bitmap of used inode numbers in an interval beginning at
* used_inodes_start and holding ISO_USED_INODE_RANGE bits.
* If a bit is set, then the corresponding inode number is occupied.
* This interval is kept around inode_counter and eventually gets
* advanced by ISO_USED_INODE_RANGE numbers in a tree traversal
* done by img_collect_inos().
*/
uint8_t *used_inodes;
ino_t used_inodes_start;
};
/* Collect the bitmap of used inode numbers in the range of
_ImageFsData.used_inodes_start + ISO_USED_INODE_RANGE
@param flag bit0= recursion is active
*/
int img_collect_inos(IsoImage *image, IsoDir *dir, int flag);
/**
* A global counter for inode numbers for the ISO image filesystem.
* On image import it gets maxed by the eventual inode numbers from PX
* entries. Up to the first 32 bit rollover it simply increments the counter.
* After the first rollover it uses a look ahead bitmap which gets filled
* by a full tree traversal. It covers the next inode numbers to come
* (somewhere between 1 and ISO_USED_INODE_RANGE which is quite many)
* and advances when being exhausted.
* @param image The image where the number shall be used
* @param flag bit0= reset count (Caution: image must get new inos then)
* @return
* Since ino_t 0 is used as default and considered self-unique,
* the value 0 should only be returned in case of error.
*/
ino_t img_give_ino_number(IsoImage *image, int flag);
/* @param flag bit0= overwrite any ino, else only ino == 0
bit1= install inode with non-data, non-directory files
bit2= install inode with directories
bit3= with bit2: install inode on parameter dir
*/
int img_make_inos(IsoImage *image, IsoDir *dir, int flag);
#endif /*LIBISO_IMAGE_H_*/

View File

@ -759,8 +759,11 @@ typedef struct IsoStream_Iface IsoStreamIface;
extern ino_t serial_id;
/**
* Interface definition for IsoStream methods.
*
* Interface definition for IsoStream methods. It is public to allow
* implementation of own stream types.
* The methods defined here typically make use of stream.data which points
* to the individual state data of stream instances.
*
* @since 0.6.4
*/
struct IsoStream_Iface
@ -772,7 +775,9 @@ struct IsoStream_Iface
* Version 1 (since 0.6.8)
* update_size() added.
* Version 2 (since 0.6.18)
* get_input_stream() added. A filter stream should have version 2.
* 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.
*/
int version;
@ -784,6 +789,8 @@ struct IsoStream_Iface
* "extf" -> External filter program
* "ziso" -> zisofs compression
* "osiz" -> zisofs uncompression
* "gzip" -> gzip compression
* "pizg" -> gzip uncompression (gunzip)
* "user" -> User supplied stream
*/
char type[4];
@ -854,7 +861,6 @@ struct IsoStream_Iface
void (*free)(IsoStream *stream);
/**
* Present if .version is 1 or higher:
* 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
@ -867,24 +873,70 @@ struct IsoStream_Iface
* 1 if ok, < 0 on error (has to be a valid libisofs error code)
*
* @since 0.6.8
* Present if .version is 1 or higher.
*/
int (*update_size)(IsoStream *stream);
/**
* Present if .version is 2 or higher:
* Obtains the eventual input stream of a filter stream.
*
* @param stream
* The eventual filter stream to be inquired.
* The eventual filter stream to be inquired.
* @param flag
* Bitfield for control purposes. Submit 0 for now.
* Bitfield for control purposes. Submit 0 for now.
* @return
* The input stream, if one exists. Elsewise NULL.
* No extra reference to the stream is taken by this call.
* The input stream, if one exists. Elsewise NULL.
* No extra reference to the stream is taken by this call.
*
* @since 0.6.18
* Present if .version is 2 or higher.
*/
IsoStream *(*get_input_stream)(IsoStream *stream, int flag);
/**
* Compare two streams whether they are based on the same input and will
* 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:
* 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.
*
* 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
* The second stream to compare. Expect foreign stream types.
* @return
* -1 if s1 is smaller s2 , 0 if s1 matches s2 , 1 if s1 is larger s2
*
* @since 0.6.20
* Present if .version is 3 or higher.
*/
int (*cmp_ino)(IsoStream *s1, IsoStream *s2);
};
/**
@ -1038,7 +1090,7 @@ int iso_lib_is_compatible(int major, int minor, int micro);
*/
#define iso_lib_header_version_major 0
#define iso_lib_header_version_minor 6
#define iso_lib_header_version_micro 18
#define iso_lib_header_version_micro 20
/**
* Usage discussion:
@ -1184,15 +1236,47 @@ int iso_write_opts_set_joliet(IsoWriteOpts *opts, int enable);
*/
int iso_write_opts_set_iso1999(IsoWriteOpts *opts, int enable);
/**
* Control generation of non-unique inode numbers for the emerging image.
* Inode numbers get written as "file serial number" with PX entries as of
* RRIP-1.12. They may mark families of hardlinks.
* RRIP-1.10 prescribes a PX entry without file serial number. If not overriden
* by iso_write_opts_set_rrip_1_10_px_ino() there will be no file serial
* written into RRIP-1.10 images.
*
* Inode number generation does not affect IsoNode objects which imported their
* inode numbers from the old ISO image (see iso_read_opts_set_new_inos())
* and which have not been altered since import. It rather applies to IsoNode
* objects which were newly added to the image, or to IsoNode which brought no
* inode number from the old image, or to IsoNode where certain properties
* have been altered since image import.
*
* If two IsoNode are found with same imported inode number but differing
* properties, then one of them will get assigned a new unique inode number.
* I.e. the hardlink relation between both IsoNode objects ends.
*
* @param enable
* 1 = Collect IsoNode objects which have identical data sources and
* properties.
* 0 = Generate unique inode numbers for all IsoNode objects which do not
* have a valid inode number from an imported ISO image.
* All other values are reserved.
*
* @since 0.6.20
*/
int iso_write_opts_set_hardlinks(IsoWriteOpts *opts, int enable);
/**
* Control writing of AAIP informations for ACL and xattr.
* For importing ACL and xattr when inserting nodes from external filesystems
* (e.g. the local POSIX filesystem) see iso_image_set_ignore_aclea().
* For loading of this information from images see iso_read_opts_set_no_aaip().
*
* @param enable 1 = write AAIP information from nodes into the image
* 0 = do not write AAIP information into the image
* All other values are reserved.
* @param enable
* 1 = write AAIP information from nodes into the image
* 0 = do not write AAIP information into the image
* All other values are reserved.
*
* @since 0.6.14
*/
int iso_write_opts_set_aaip(IsoWriteOpts *opts, int enable);
@ -1288,6 +1372,18 @@ int iso_write_opts_set_joliet_longer_paths(IsoWriteOpts *opts, int allow);
*/
int iso_write_opts_set_rrip_version_1_10(IsoWriteOpts *opts, int oldvers);
/**
* Write field PX with file serial number (i.e. inode number) even if
* iso_write_opts_set_rrip_version_1_10(,1) is in effect.
* This clearly violates the RRIP-1.10 specs. But it is done by mkisofs since
* a while and no widespread protest is visible in the web.
* If this option is not enabled, then iso_write_opts_set_hardlinks() will
* only have an effect with iso_write_opts_set_rrip_version_1_10(,0).
*
* @since 0.6.20
*/
int iso_write_opts_set_rrip_1_10_px_ino(IsoWriteOpts *opts, int enable);
/**
* Write AAIP as extension according to SUSP 1.10 rather than SUSP 1.12.
* I.e. without announcing it by an ER field and thus without the need
@ -1651,13 +1747,34 @@ int iso_read_opts_set_no_iso1999(IsoReadOpts *opts, int noiso1999);
* (e.g. the local POSIX filesystem) see iso_image_set_ignore_aclea().
* For eventual writing of this information see iso_write_opts_set_aaip().
*
* @param noaaip 1 = do not read AAIP information
* 0 = read AAIP information if available
* All other values are reserved.
* @param noaaip
* 1 = Do not read AAIP information
* 0 = Read AAIP information if available
* All other values are reserved.
* @since 0.6.14
*/
int iso_read_opts_set_no_aaip(IsoReadOpts *opts, int noaaip);
/**
* Control discarding of eventual inode numbers from existing images.
* Such numbers may come from RRIP 1.12 entries PX. If not discarded they
* get written unchanged when the file object gets written into an ISO image.
* If this inode number is missing with a file in the imported image,
* or if it has been discarded during image reading, then a unique inode number
* will be generated at some time before the file gets written into an ISO
* image.
* Two image nodes which have the same inode number represent two hardlinks
* of the same file object. So discarding the numbers splits hardlinks.
*
* @param new_inos
* 1 = Discard imported inode numbers and finally hand out a unique new
* one to each single file before it gets written into an ISO image.
* 0 = Keep eventual inode numbers from PX entries.
* All other values are reserved.
* @since 0.6.20
*/
int iso_read_opts_set_new_inos(IsoReadOpts *opts, int new_inos);
/**
* Whether to prefer Joliet over RR. libisofs usually prefers RR over
* Joliet, as it give us much more info about files. So, if both extensions
@ -2122,7 +2239,7 @@ void el_torito_set_load_size(ElToritoBootImage *bootimg, short sectors);
void el_torito_set_no_bootable(ElToritoBootImage *bootimg);
/**
* Specifies that this image needs to be patched. This involves the writting
* Specifies that this image needs to be patched. This involves the writing
* of a 56 bytes boot information table at offset 8 of the boot image file.
* The original boot image file won't be modified.
* This is needed for isolinux boot images.
@ -2384,7 +2501,7 @@ time_t iso_node_get_ctime(const IsoNode *node);
/**
* Set if the node will be hidden in RR/ISO tree, Joliet tree or both.
*
* If the file is setted as hidden in one tree, it won't be included there, so
* If the file is set as hidden in one tree, it won't be included there, so
* it won't be visible in a OS accessing CD using that tree. For example,
* GNU/Linux systems access to Rock Ridge / ISO9960 tree in order to see
* what is recorded on CD, while MS Windows make use of the Joliet tree. If a
@ -2402,6 +2519,22 @@ time_t iso_node_get_ctime(const IsoNode *node);
*/
void iso_node_set_hidden(IsoNode *node, int hide_attrs);
/**
* Compare two nodes whether they are based on the same input and
* can be considered as hardlinks to the same file objects.
*
* @param n1
* The first node to compare.
* @param n2
* The second node to compare.
* @return
* -1 if s1 is smaller s2 , 0 if s1 matches s2 , 1 if s1 is larger s2
* @param flag
* Bitfield for control purposes, unused yet, submit 0
* @since 0.6.20
*/
int iso_node_cmp_ino(IsoNode *n1, IsoNode *n2, int flag);
/**
* Add a new node to a dir. Note that this function don't add a new ref to
* the node, so you don't need to free it, it will be automatically freed
@ -2503,7 +2636,7 @@ int iso_node_remove(IsoNode *node);
* If node is the root node, the same node will be returned as its parent.
*
* This returns NULL if the node doesn't pertain to any tree
* (it was removed/take).
* (it was removed/taken).
*
* @since 0.6.2
*/
@ -4078,7 +4211,9 @@ void iso_stream_get_id(IsoStream *stream, unsigned int *fs_id, dev_t *dev_id,
/**
* Try to get eventual source path string of a stream. Meaning and availability
* of this string depends on the stream.class . Expect valid results with
* types "fsrc" and "cout".
* types "fsrc" and "cout". Result formats are
* fsrc: result of file_source_get_path()
* cout: result of file_source_get_path() " " offset " " size
* @param stream
* The stream to be inquired.
* @param flag
@ -4091,6 +4226,25 @@ void iso_stream_get_id(IsoStream *stream, unsigned int *fs_id, dev_t *dev_id,
*/
char *iso_stream_get_source_path(IsoStream *stream, int flag);
/**
* Compare two streams whether they are based on the same input and will
* produce the same output. If in any doubt, then this comparison will
* indicate no match.
*
* @param s1
* The first stream to compare.
* @param s2
* The second stream to compare.
* @return
* -1 if s1 is smaller s2 , 0 if s1 matches s2 , 1 if s1 is larger s2
* @param flag
* bit0= do not use s1->class->compare() even if available
* (e.g. because iso_stream_cmp_ino(0 is called as fallback
* from said stream->class->compare())
*
* @since 0.6.20
*/
int iso_stream_cmp_ino(IsoStream *s1, IsoStream *s2, int flag);
/* --------------------------------- AAIP --------------------------------- */
@ -4998,18 +5152,6 @@ int iso_gzip_get_refcounts(off_t *gzip_count, off_t *gunzip_count, int flag);
/** El-Torito image is hidden (WARNING,HIGH, -335) */
#define ISO_EL_TORITO_HIDDEN 0xD030FEB1
/** Read error occured with IsoDataSource (SORRY,HIGH, -513) */
#define ISO_DATA_SOURCE_SORRY 0xE030FCFF
/** Read error occured with IsoDataSource (MISHAP,HIGH, -513) */
#define ISO_DATA_SOURCE_MISHAP 0xE430FCFF
/** Read error occured with IsoDataSource (FAILURE,HIGH, -513) */
#define ISO_DATA_SOURCE_FAILURE 0xE830FCFF
/** Read error occured with IsoDataSource (FATAL,HIGH, -513) */
#define ISO_DATA_SOURCE_FATAL 0xF030FCFF
/** AAIP info with ACL or xattr in ISO image will be ignored
(NOTE, HIGH, -336) */
@ -5066,6 +5208,25 @@ int iso_gzip_get_refcounts(off_t *gzip_count, off_t *gunzip_count, int flag);
#define ISO_ZLIB_EARLY_EOF 0xE830FEA1
/* ! PLACE NEW ERROR CODES HERE ! */
/** Read error occured with IsoDataSource (SORRY,HIGH, -513) */
#define ISO_DATA_SOURCE_SORRY 0xE030FCFF
/** Read error occured with IsoDataSource (MISHAP,HIGH, -513) */
#define ISO_DATA_SOURCE_MISHAP 0xE430FCFF
/** Read error occured with IsoDataSource (FAILURE,HIGH, -513) */
#define ISO_DATA_SOURCE_FAILURE 0xE830FCFF
/** Read error occured with IsoDataSource (FATAL,HIGH, -513) */
#define ISO_DATA_SOURCE_FATAL 0xF030FCFF
/* ! PLACE NEW ERROR CODES ABOVE. NOT HERE ! */
/* ------------------------------------------------------------------------- */
#ifdef LIBISOFS_WITHOUT_LIBBURN
@ -5253,30 +5414,36 @@ struct burn_source {
/* ---------------------------- Improvements --------------------------- */
/* Cleanup : make call setlocale() at init time resp. never
*/
#define Libisofs_setlocale_in_iniT yes
/* Protocol Upgrade : change to AAIP-2.0 with field signature "AL"
*/
#define Libisofs_aaip_2_0 yes
/* currently none being tested */
/* ---------------------------- Experiments ---------------------------- */
/* Hardlinks : During image generation accompany the tree of IsoFileSrc
by a sorted array of Ecma119Node.
The sorting order shall bring together candidates for being
hardlink siblings resp. having identical content.
This is in sync with the IsoFileSrc unification by IsoRBTree
and iso_file_src_cmp().
That tree cannot be obsoleted because Joliet and ISO1999 depend
on it. On the other hand, the Ecma119Node array includes objects
which have no IsoFileSrc attached. So both, tree and array, are
needed.
*/
#define Libisofs_hardlink_matcheR yes
/* Hardlinks : Override Libisofs_new_fs_image_inO and preserve inode numbers
from session to session.
*/
#define Libisofs_hardlink_prooF yes
/* Experiment: Ignore PX inode numbers,
have boot image inode number counted by fs_give_ino_number()
*/
#define Libisofs_new_fs_image_inO yes
/* Experiment: Revoke Ticket 144, use data file LBAs again.
(will work only if not Libisofs_new_fs_image_inO)
#define Libisofs_ino_from_lbA yes
Overridden if Libisofs_hardlink_prooF is defined.
#define Libisofs_new_fs_image_inO yes
*/
@ -5288,12 +5455,5 @@ struct burn_source {
*/
/* Experiment: Use iso_iconv*() wrappers.
They can print errno messages and they
can avoid iconv() if the identical mapping is desired.
One could install own simple conversion capabilities.
*/
#define Libisofs_with_iso_iconV yes
#endif /*LIBISO_LIBISOFS_H_*/

View File

@ -65,12 +65,9 @@ struct libiso_msgs *libiso_msgr = NULL;
int iso_init_with_flag(int flag)
{
#ifdef Libisofs_setlocale_in_iniT
if (! (flag & 1)) {
iso_init_locale(0);
}
#endif
if (libiso_msgr == NULL) {
if (libiso_msgs_new(&libiso_msgr, 0) <= 0)
return ISO_FATAL_ERROR;

View File

@ -8,6 +8,7 @@
*/
#include "libisofs.h"
#include "image.h"
#include "node.h"
#include "stream.h"
#include "aaip_0_2.h"
@ -1308,6 +1309,13 @@ int iso_node_new_symlink(char *name, char *dest, IsoSymlink **link)
new->node.name = name;
new->dest = dest;
new->node.mode = S_IFLNK;
#ifdef Libisofs_hardlink_matcheR
new->fs_id = 0;
new->st_dev = 0;
new->st_ino = 0;
#endif
*link = new;
return ISO_SUCCESS;
}
@ -1340,6 +1348,12 @@ int iso_node_new_special(char *name, mode_t mode, dev_t dev,
new->node.mode = mode;
new->dev = dev;
#ifdef Libisofs_hardlink_matcheR
new->fs_id = 0;
new->st_dev = 0;
new->st_ino = 0;
#endif
*special = new;
return ISO_SUCCESS;
}
@ -2239,3 +2253,325 @@ int iso_node_zf_by_magic(IsoNode *node, int flag)
return total_ret;
}
int iso_px_ino_xinfo_func(void *data, int flag)
{
if (flag == 1) {
free(data);
}
return 1;
}
/*
* @param flag
* bit0= do only retrieve id if node is in imported ISO image
* or has an explicit xinfo inode number
* @return
* 1= reply is valid from stream, 2= reply is valid from xinfo
* 0= no id available, <0= error
* (fs_id, dev_id, ino_id) will be (0,0,0) in case of return <= 0
*/
int iso_node_get_id(IsoNode *node, unsigned int *fs_id, dev_t *dev_id,
ino_t *ino_id, int flag)
{
int ret;
IsoFile *file;
IsoSymlink *symlink;
IsoSpecial *special;
void *xipt;
ret = iso_node_get_xinfo(node, iso_px_ino_xinfo_func, &xipt);
if (ret < 0)
goto no_id;
if (ret == 1) {
*fs_id = ISO_IMAGE_FS_ID;
*dev_id = 0;
*ino_id = *((ino_t *) xipt);
return 2;
}
if (node->type == LIBISO_FILE) {
file= (IsoFile *) node;
iso_stream_get_id(file->stream, fs_id, dev_id, ino_id);
if (*fs_id != ISO_IMAGE_FS_ID && (flag & 1)) {
ret = 0;
goto no_id;
}
return 1;
#ifdef Libisofs_hardlink_matcheR
} else if (node->type == LIBISO_SYMLINK) {
symlink = (IsoSymlink *) node;
if (symlink->fs_id != ISO_IMAGE_FS_ID && (flag & 1)) {
ret = 0;
goto no_id;
}
*fs_id = symlink->fs_id;
*dev_id = symlink->st_dev;
*ino_id = symlink->st_ino;
return 1;
} else if (node->type == LIBISO_SPECIAL) {
special = (IsoSpecial *) node;
if (special->fs_id != ISO_IMAGE_FS_ID && (flag & 1)) {
ret = 0;
goto no_id;
}
*fs_id = special->fs_id;
*dev_id = special->st_dev;
*ino_id = special->st_ino;
return 1;
#endif
}
ret = 0;
no_id:;
*fs_id = 0;
*dev_id = 0;
*ino_id = 0;
return ret;
}
static
int iso_node_set_ino_xinfo(IsoNode *node, ino_t ino, int flag)
{
int ret;
void *xipt;
if (flag & 1) {
ret = iso_node_remove_xinfo(node, iso_px_ino_xinfo_func);
if (ret < 0)
return ret;
}
xipt = calloc(1, sizeof(ino_t));
if (xipt == NULL)
return ISO_OUT_OF_MEM;
memcpy(xipt, &ino, sizeof(ino_t));
ret = iso_node_add_xinfo(node, iso_px_ino_xinfo_func, xipt);
return ret;
}
int iso_node_set_ino(IsoNode *node, ino_t ino, int flag)
{
int ret;
IsoFile *file;
IsoSymlink *symlink;
IsoSpecial *special;
void *xipt;
ret = iso_node_get_xinfo(node, iso_px_ino_xinfo_func, &xipt);
if (ret < 0)
return ret;
if (ret == 1) {
ret = iso_node_set_ino_xinfo(node, ino, 1);
if (ret < 0)
return ret;
return 2;
}
if (node->type == LIBISO_FILE) {
file= (IsoFile *) node;
ret = iso_stream_set_image_ino(file->stream, ino, 0);
if (ret < 0 || ret == 1)
return ret;
#ifdef Libisofs_hardlink_matcheR
} else if (node->type == LIBISO_SYMLINK) {
symlink = (IsoSymlink *) node;
if (symlink->fs_id == ISO_IMAGE_FS_ID) {
symlink->st_ino = ino;
return 1;
}
} else if (node->type == LIBISO_SPECIAL) {
special = (IsoSpecial *) node;
if (special->fs_id == ISO_IMAGE_FS_ID) {
special->st_ino = ino;
return 1;
}
#endif
}
ret = iso_node_set_ino_xinfo(node, ino, 0);
if (ret < 0)
return ret;
return 2;
}
int iso_node_set_unique_id(IsoNode *node, IsoImage *image, int flag)
{
int ret;
ino_t ino;
ino = img_give_ino_number(image, 0);
ret = iso_node_set_ino(node, ino, 0);
return ret;
}
/*
* Note to programmers: It is crucial not to break the following constraints.
* Anti-symmetry: cmp(X,Y) == - cmp(Y,X)
* Transitivity : if cmp(A,B) < 0 && cmp(B,C) < 0 then cmp(A,C) < 0
* if cmp(A,B) == 0 && cmp(B,C) == 0 then cmp(A,C) == 0
* A big transitivity hazard are tests which do not apply to some nodes.
* In this case for any A that is applicable and any B that is not applicable
* the comparison must have the same non-zero result. I.e. a pair of applicable
* and non-applicable node must return that non-zero result before the test
* for a pair of applicable nodes would happen.
*
* @param flag
* bit0= compare stat properties and attributes
* bit1= treat all nodes with image ino == 0 as unique
*/
int iso_node_cmp_flag(IsoNode *n1, IsoNode *n2, int flag)
{
int ret1, ret2;
unsigned int fs_id1, fs_id2;
dev_t dev_id1, dev_id2;
ino_t ino_id1, ino_id2;
IsoFile *f1 = NULL, *f2 = NULL;
IsoSymlink *l1 = NULL, *l2 = NULL;
IsoSpecial *s1 = NULL, *s2 = NULL;
void *x1, *x2;
if (n1 == n2)
return 0;
if (n1->type != n2->type)
return (n1->type < n2->type ? -1 : 1);
/* Imported or explicite ISO image node id has priority */
ret1 = (iso_node_get_id(n1, &fs_id1, &dev_id1, &ino_id1, 1) > 0);
ret2 = (iso_node_get_id(n2, &fs_id2, &dev_id2, &ino_id2, 1) > 0);
if (ret1 != ret2)
return (ret1 < ret2 ? -1 : 1);
if (ret1) {
/* fs_id and dev_id do not matter here.
Both nodes have explicit inode numbers of the emerging image.
*/
if (ino_id1 != ino_id2)
return (ino_id1 < ino_id2 ? -1 : 1);
if (ino_id1 == 0) /* Image ino 0 is always unique */
return (n1 < n2 ? -1 : 1);
goto image_inode_match;
}
if (n1->type == LIBISO_FILE) {
f1 = (IsoFile *) n1;
f2 = (IsoFile *) n2;
ret1 = iso_stream_cmp_ino(f1->stream, f2->stream, 0);
if (ret1)
return ret1;
goto inode_match;
#ifdef Libisofs_hardlink_matcheR
} else if (n1->type == LIBISO_SYMLINK) {
l1 = (IsoSymlink *) n1;
l2 = (IsoSymlink *) n2;
fs_id1 = l1->fs_id;
dev_id1 = l1->st_dev;
ino_id1 = l1->st_ino;
fs_id2 = l2->fs_id;
dev_id2 = l2->st_dev;
ino_id2 = l2->st_ino;
} else if (n1->type == LIBISO_SPECIAL) {
s1 = (IsoSpecial *) n1;
s2 = (IsoSpecial *) n2;
fs_id1 = s1->fs_id;
dev_id1 = s1->st_dev;
ino_id1 = s1->st_ino;
fs_id2 = s2->fs_id;
dev_id2 = s2->st_dev;
ino_id2 = s2->st_ino;
#endif /* Libisofs_hardlink_matcheR */
} else {
return (n1 < n2 ? -1 : 1); /* case n1 == n2 is handled above */
}
if (fs_id1 != fs_id2)
return (fs_id1 < fs_id2 ? -1 : 1);
if (dev_id1 != dev_id2)
return (dev_id1 < dev_id2 ? -1 : 1);
if (ino_id1 != ino_id2)
return (ino_id1 < ino_id2 ? -1 : 1);
if (fs_id1 == 0 && dev_id1 == 0 && ino_id1 == 0)
return (n1 < n2 ? -1 : 1);
inode_match:;
if (flag & 2) {
/* What comes here has no predefined image ino resp. image_ino == 0 .
Regard this as not equal.
*/
return (n1 < n2 ? -1 : 1);
}
image_inode_match:;
if (!(flag & 1))
return 0;
if (n1->type == LIBISO_SYMLINK) {
l1 = (IsoSymlink *) n1;
l2 = (IsoSymlink *) n2;
ret1 = strcmp(l1->dest, l2->dest);
if (ret1)
return ret1;
} else if (n1->type == LIBISO_SPECIAL) {
s1 = (IsoSpecial *) n1;
s2 = (IsoSpecial *) n2;
if (s1->dev != s2->dev)
return (s1->dev < s2->dev ? -1 : 1);
}
if (n1->mode != n2->mode)
return (n1->mode < n2->mode ? -1 : 1);
if (n1->uid != n2->uid)
return (n1->uid < n2->uid ? -1 : 1);
if (n1->gid != n2->gid)
return (n1->gid < n2->gid ? -1 : 1);
if (n1->atime != n2->atime)
return (n1->atime < n2->atime ? -1 : 1);
if (n1->mtime != n2->mtime)
return (n1->mtime < n2->mtime ? -1 : 1);
if (n1->ctime != n2->ctime)
return (n1->ctime < n2->ctime ? -1 : 1);
/* Compare xinfo */
/* :( cannot compare general xinfo because data length is not known :( */
/* compare aa_string */
ret1 = iso_node_get_xinfo(n1, aaip_xinfo_func, &x1);
ret2 = iso_node_get_xinfo(n2, aaip_xinfo_func, &x2);
if (ret1 != ret2)
return (ret1 < ret2 ? -1 : 1);
if (ret1 == 1) {
ret1 = aaip_count_bytes((unsigned char *) x1, 0);
ret2 = aaip_count_bytes((unsigned char *) x2, 0);
if (ret1 != ret2)
return (ret1 < ret2 ? -1 : 1);
ret1 = memcmp(x1, x2, ret1);
if (ret1)
return ret1;
}
return 0;
}
/* API */
int iso_node_cmp_ino(IsoNode *n1, IsoNode *n2, int flag)
{
return iso_node_cmp_flag(n1, n2, 1);
}

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 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 as
@ -122,7 +123,7 @@ struct Iso_File
* Higher weighting files are written at the beginning of image
*/
int sort_weight;
IsoStream *stream;
IsoStream *stream; /* Knows fs_id, st_dev, and st_ino */
};
struct Iso_Symlink
@ -130,12 +131,34 @@ struct Iso_Symlink
IsoNode node;
char *dest;
#ifdef Libisofs_hardlink_matcheR
/* If the IsoNode represents an object in an existing filesystem then
the following three numbers should unique identify it.
(0,0,0) will always be taken as unique.
*/
unsigned int fs_id;
dev_t st_dev;
ino_t st_ino;
#endif
};
struct Iso_Special
{
IsoNode node;
dev_t dev;
#ifdef Libisofs_hardlink_matcheR
/* If the IsoNode represents an object in an existing filesystem then
the following three numbers should unique identify it.
(0,0,0) will always be taken as unique.
*/
unsigned int fs_id;
dev_t st_dev;
ino_t st_ino;
#endif
};
struct iso_dir_iter_iface
@ -398,5 +421,34 @@ struct zisofs_zf_info {
*/
int iso_file_zf_by_magic(IsoFile *file, int flag);
/*
* @param flag
* bit0= do only retrieve id if node is in imported ISO image
* or has an explicit xinfo inode number
* @return
* 1= reply is valid from stream, 2= reply is valid from xinfo
* 0= no id available, <0= error
* (fs_id, dev_id, ino_id) will be (0,0,0) in case of return <= 0
*/
int iso_node_get_id(IsoNode *node, unsigned int *fs_id, dev_t *dev_id,
ino_t *ino_id, int flag);
/* Set a new unique inode ISO image number to the given node.
* This number shall eventually persist during image generation.
*/
int iso_node_set_unique_id(IsoNode *node, IsoImage *image, int flag);
/* Use this with extreme care. Duplicate inode numbers will indicate hardlink
* relationship between the nodes.
*/
int iso_node_set_ino(IsoNode *node, ino_t ino, int flag);
/*
* @param flag
* bit0= compare stat properties and attributes
* bit1= treat all nodes with image ino == 0 as unique
* (those with 0,0,0 are treated as unique anyway)
*/
int iso_node_cmp_flag(IsoNode *n1, IsoNode *n2, int flag);
#endif /*LIBISO_NODE_H_*/

View File

@ -102,7 +102,7 @@ int rrip_add_PX(Ecma119Image *t, Ecma119Node *n, struct susp_info *susp)
PX[0] = 'P';
PX[1] = 'X';
if (!t->rrip_version_1_10) {
if (t->rrip_1_10_px_ino || !t->rrip_version_1_10 ) {
PX[2] = 44;
} else {
PX[2] = 36;
@ -112,7 +112,7 @@ int rrip_add_PX(Ecma119Image *t, Ecma119Node *n, struct susp_info *susp)
iso_bb(&PX[12], n->nlink, 4);
iso_bb(&PX[20], px_get_uid(t, n), 4);
iso_bb(&PX[28], px_get_gid(t, n), 4);
if (!t->rrip_version_1_10) {
if (t->rrip_1_10_px_ino || !t->rrip_version_1_10) {
iso_bb(&PX[36], n->ino, 4);
}
@ -662,9 +662,6 @@ int aaip_add_ER(Ecma119Image *t, struct susp_info *susp, int flag)
ER[5] = 81;
ER[6] = 62;
ER[7] = 1;
#ifdef Libisofs_aaip_2_0
memcpy(ER + 8, "AAIP_0200", 9);
memcpy(ER + 17,
"AL PROVIDES VIA AAIP 2.0 SUPPORT FOR ARBITRARY FILE ATTRIBUTES"
@ -673,18 +670,6 @@ int aaip_add_ER(Ecma119Image *t, struct susp_info *susp, int flag)
"PLEASE CONTACT THE LIBBURNIA PROJECT VIA LIBBURNIA-PROJECT.ORG",
62);
#else /* Libisofs_aaip_2_0 */
memcpy(ER + 8, "AAIP_0100", 9);
memcpy(ER + 17,
"AA PROVIDES VIA AAIP 1.0 SUPPORT FOR ARBITRARY FILE ATTRIBUTES"
" IN ISO 9660 IMAGES", 81);
memcpy(ER + 98,
"PLEASE CONTACT THE LIBBURNIA PROJECT VIA LIBBURNIA-PROJECT.ORG",
62);
#endif /* ! Libisofs_aaip_2_0 */
/** This always goes to continuation area */
return susp_append_ce(t, susp, ER);
}
@ -1144,7 +1129,7 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t space,
#endif
/* PX and TF, we are sure they always fit in SUA */
if (!t->rrip_version_1_10) {
if (t->rrip_1_10_px_ino || !t->rrip_version_1_10) {
su_size += 44 + 26;
} else {
su_size += 36 + 26;

View File

@ -263,7 +263,9 @@ void susp_iter_free(SuspIterator *iter);
* Fills a struct stat with the values of a Rock Ridge PX entry (RRIP, 4.1.1).
*
* @return
* 1 on success, < 0 on error
* < 0 on error
* 1 on success with no inode number,
* 2 on success with inode number,
*/
int read_rr_PX(struct susp_sys_user_entry *px, struct stat *st);

View File

@ -169,11 +169,14 @@ int read_rr_PX(struct susp_sys_user_entry *px, struct stat *st)
st->st_nlink = iso_read_bb(px->data.PX.links, 4, NULL);
st->st_uid = iso_read_bb(px->data.PX.uid, 4, NULL);
st->st_gid = iso_read_bb(px->data.PX.gid, 4, NULL);
st->st_ino = 0;
if (px->len_sue[0] == 44) {
/* this corresponds to RRIP 1.12, so we have inode serial number */
st->st_ino = iso_read_bb(px->data.PX.serial, 4, NULL);
/* Indicate that st_ino is valid */
return 2;
}
return ISO_SUCCESS;
return 1;
}
/**
@ -492,26 +495,14 @@ int read_aaip_AA(struct susp_sys_user_entry *sue,
aapt = *aa_string + *aa_len;
aapt[0] = 'A';
#ifdef Libisofs_aaip_2_0
aapt[1] = 'L';
#else /* Libisofs_aaip_2_0 */
aapt[1] = 'A';
#endif /* ! Libisofs_aaip_2_0 */
aapt[2] = sue->len_sue[0];
aapt[3] = 1;
aapt[4] = 0;
/* Append sue payload */
#ifdef Libisofs_aaip_2_0
/* Append sue payload */
memcpy(aapt + 5, sue->data.AL.comps, sue->len_sue[0] - 5);
*is_done = !(sue->data.AL.flags[0] & 1);
#else /* Libisofs_aaip_2_0 */
memcpy(aapt + 5, sue->data.AA.comps, sue->len_sue[0] - 5);
*is_done = !(sue->data.AA.flags[0] & 1);
#endif /* ! Libisofs_aaip_2_0 */
*aa_len += sue->len_sue[0];
return ISO_SUCCESS;
@ -554,26 +545,14 @@ int read_aaip_AL(struct susp_sys_user_entry *sue,
aapt = *aa_string + *aa_len;
aapt[0] = 'A';
#ifdef Libisofs_aaip_2_0
aapt[1] = 'L';
#else /* Libisofs_aaip_2_0 */
aapt[1] = 'A';
#endif /* ! Libisofs_aaip_2_0 */
aapt[2] = sue->len_sue[0];
aapt[3] = 1;
aapt[4] = 0;
/* Append sue payload */
#ifdef Libisofs_aaip_2_0
/* Append sue payload */
memcpy(aapt + 5, sue->data.AL.comps, sue->len_sue[0] - 5);
*is_done = !(sue->data.AL.flags[0] & 1);
#else /* Libisofs_aaip_2_0 */
memcpy(aapt + 5, sue->data.AA.comps, sue->len_sue[0] - 5);
*is_done = !(sue->data.AA.flags[0] & 1);
#endif /* ! Libisofs_aaip_2_0 */
*aa_len += sue->len_sue[0];
return ISO_SUCCESS;

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 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 as
@ -672,8 +673,12 @@ void iso_stream_get_file_name(IsoStream *stream, char *name)
IsoStream *iso_stream_get_input_stream(IsoStream *stream, int flag)
{
IsoStreamIface* class = stream->class;
IsoStreamIface* class;
if (stream == NULL) {
return NULL;
}
class = stream->class;
if (class->version < 2)
return NULL;
return class->get_input_stream(stream, 0);
@ -709,3 +714,119 @@ ex:;
return path;
}
/* @return 1 = ok , 0 = not an ISO image stream , <0 = error */
int iso_stream_set_image_ino(IsoStream *stream, ino_t ino, int flag)
{
if (stream == NULL) {
return ISO_NULL_POINTER;
}
if (stream->class == &fsrc_stream_class) {
FSrcStreamData *fsrc_data = stream->data;
fsrc_data->ino_id = ino;
return 1;
}
return 0;
}
/* API */
int iso_stream_cmp_ino(IsoStream *s1, IsoStream *s2, int flag)
{
int ret;
unsigned int fs_id1, fs_id2;
dev_t dev_id1, dev_id2;
ino_t ino_id1, ino_id2;
off_t size1, size2;
FSrcStreamData *fssd1, *fssd2;
/* <<<
#define Libisofs_stream_cmp_ino_debuG 1
*/
#ifdef Libisofs_stream_cmp_ino_debuG
static int report_counter = 0;
static int debug = 1;
#endif /* Libisofs_stream_cmp_ino_debuG */
if (s1 == s2)
return 0;
if (s1 == NULL)
return -1;
if (s2 == NULL)
return 1;
if (s1->class->version >= 3 && !(flag & 1)) {
/* Filters may have smarter methods to compare themselves with others */
ret = s1->class->cmp_ino(s1, s2);
return ret;
}
iso_stream_get_id(s1, &fs_id1, &dev_id1, &ino_id1);
iso_stream_get_id(s2, &fs_id2, &dev_id2, &ino_id2);
if (fs_id1 < fs_id2) {
return -1;
} else if (fs_id1 > fs_id2) {
return 1;
}
/* files belong to the same fs */
if (dev_id1 > dev_id2) {
return -1;
} else if (dev_id1 < dev_id2) {
return 1;
} else if (ino_id1 < ino_id2) {
return -1;
} else if (ino_id1 > ino_id2) {
return 1;
}
size1 = iso_stream_get_size(s1);
size2 = iso_stream_get_size(s2);
if (size1 < size2) {
#ifdef Libisofs_stream_cmp_ino_debuG
if (debug) {
if (report_counter < 5)
fprintf(stderr,
"\n\nlibisofs_DEBUG : Program error: same ino but differing size\n\n\n");
else if (report_counter == 5)
fprintf(stderr,
"\n\nlibisofs_DEBUG : Inode error: more of same ino but differing size\n\n\n");
report_counter++;
}
#endif /* Libisofs_stream_cmp_ino_debuG */
return -1;
} else if (size1 > size2) {
#ifdef Libisofs_stream_cmp_ino_debuG
if (debug) {
if (report_counter < 5)
fprintf(stderr,
"\n\nlibisofs_DEBUG : Inode error: same ino but differing size\n\n\n");
else if (report_counter == 5)
fprintf(stderr,
"\n\nlibisofs_DEBUG : Program error: more of same ino but differing size\n\n\n");
report_counter++;
}
#endif /* Libisofs_stream_cmp_ino_debuG */
return 1;
}
if (s1->class != s2->class)
return (s1->class < s2->class ? -1 : 1);
if (s1->class == &fsrc_stream_class) {
/* Compare eventual image data section LBA and sizes */
fssd1= (FSrcStreamData *) s1->data;
fssd2= (FSrcStreamData *) s2->data;
ret = iso_ifs_sections_cmp(fssd1->src, fssd2->src, 0);
if (ret != 0)
return ret;
}
#ifdef Libisofs_hardlink_matcheR
if (fs_id1 == 0 && dev_id1 == 0 && ino_id1 == 0) {
return (s1 < s2 ? -1 : 1);
}
#endif
return 0;
}

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 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 as
@ -74,4 +75,12 @@ int iso_stream_get_src_zf(IsoStream *stream, int *header_size_div4,
int *block_size_log2, uint32_t *uncompressed_size,
int flag);
/**
* Set the inode number of a stream that is based on FSrcStreamData, i.e.
* stems from the imported ISO image.
* @return 1 = ok , 0 = not an ISO image stream , <0 = error
*/
int iso_stream_set_image_ino(IsoStream *stream, ino_t ino, int flag);
#endif /*STREAM_H_*/

View File

@ -32,9 +32,6 @@
#endif
#ifdef Libisofs_with_iso_iconV
/* Produce possibly inflationary error messages directly to stderr */
static int iso_iconv_debug = 0;
@ -141,8 +138,6 @@ int iso_iconv_close(struct iso_iconv_handle *handle, int flag)
return ret;
}
#endif /* Libisofs_with_iso_iconV */
int int_pow(int base, int power)
{
@ -183,13 +178,8 @@ int strconv(const char *str, const char *icharset, const char *ocharset,
size_t inbytes;
size_t outbytes;
size_t n;
#ifdef Libisofs_with_iso_iconV
struct iso_iconv_handle conv;
int conv_ret;
#else
iconv_t conv;
#endif
char *out = NULL;
char *src;
@ -204,43 +194,22 @@ int strconv(const char *str, const char *icharset, const char *ocharset,
goto ex;
}
#ifdef Libisofs_with_iso_iconV
conv_ret = iso_iconv_open(&conv, (char *) ocharset, (char *) icharset, 0);
if (conv_ret <= 0) {
#else
conv = iconv_open(ocharset, icharset);
if (conv == (iconv_t)(-1)) {
#endif
retval = ISO_CHARSET_CONV_ERROR;
goto ex;
}
src = (char *)str;
ret = (char *)out;
#ifdef Libisofs_with_iso_iconV
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
if (n == -1) {
/* error */
iso_iconv_close(&conv, 0);
#else
n = iconv(conv, &src, &inbytes, &ret, &outbytes);
if (n == -1) {
/* error */
iconv_close(conv);
#endif
retval = ISO_CHARSET_CONV_ERROR;
goto ex;
}
*ret = '\0';
#ifdef Libisofs_with_iso_iconV
iso_iconv_close(&conv, 0);
#else
iconv_close(conv);
#endif
*output = malloc(ret - out + 1);
if (*output == NULL) {
@ -261,14 +230,8 @@ int strnconv(const char *str, const char *icharset, const char *ocharset,
size_t inbytes;
size_t outbytes;
size_t n;
#ifdef Libisofs_with_iso_iconV
struct iso_iconv_handle conv;
int conv_ret;
#else
iconv_t conv;
#endif
char *out = NULL;
char *src;
char *ret;
@ -281,43 +244,22 @@ int strnconv(const char *str, const char *icharset, const char *ocharset,
retval = ISO_OUT_OF_MEM;
goto ex;
}
#ifdef Libisofs_with_iso_iconV
conv_ret = iso_iconv_open(&conv, (char *) ocharset, (char *) icharset, 0);
if (conv_ret <= 0) {
#else
conv = iconv_open(ocharset, icharset);
if (conv == (iconv_t)(-1)) {
#endif
retval = ISO_CHARSET_CONV_ERROR;
goto ex;
}
src = (char *)str;
ret = (char *)out;
#ifdef Libisofs_with_iso_iconV
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
if (n == -1) {
/* error */
iso_iconv_close(&conv, 0);
#else
n = iconv(conv, &src, &inbytes, &ret, &outbytes);
if (n == -1) {
/* error */
iconv_close(conv);
#endif
retval = ISO_CHARSET_CONV_ERROR;
goto ex;
}
*ret = '\0';
#ifdef Libisofs_with_iso_iconV
iso_iconv_close(&conv, 0);
#else
iconv_close(conv);
#endif
*output = malloc(ret - out + 1);
if (*output == NULL) {
@ -342,13 +284,8 @@ ex:;
static
int str2wchar(const char *icharset, const char *input, wchar_t **output)
{
#ifdef Libisofs_with_iso_iconV
struct iso_iconv_handle conv;
int conv_ret;
#else
iconv_t conv;
#endif
/* That while loop smells like a potential show stopper */
size_t loop_counter = 0, loop_limit = 3;
@ -364,15 +301,8 @@ int str2wchar(const char *icharset, const char *input, wchar_t **output)
return ISO_NULL_POINTER;
}
#ifdef Libisofs_with_iso_iconV
conv_ret = iso_iconv_open(&conv, "WCHAR_T", (char *) icharset, 0);
if (conv_ret <= 0) {
#else
conv = iconv_open("WCHAR_T", icharset);
if (conv == (iconv_t)-1) {
#endif
return ISO_CHARSET_CONV_ERROR;
}
@ -388,13 +318,7 @@ int str2wchar(const char *icharset, const char *input, wchar_t **output)
ret = (char *)wstr;
src = (char *)input;
#ifdef Libisofs_with_iso_iconV
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
#else
n = iconv(conv, &src, &inbytes, &ret, &outbytes);
#endif
while (n == -1) {
if (errno == E2BIG) {
@ -424,34 +348,16 @@ int str2wchar(const char *icharset, const char *input, wchar_t **output)
loop_counter++;
if (loop_counter > loop_limit)
goto conv_error;
#ifdef Libisofs_with_iso_iconV
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
#else
n = iconv(conv, &src, &inbytes, &ret, &outbytes);
#endif
}
}
#ifdef Libisofs_with_iso_iconV
iso_iconv_close(&conv, 0);
#else
iconv_close(conv);
#endif
*( (wchar_t *)ret )='\0';
*output = wstr;
return ISO_SUCCESS;
conv_error:;
#ifdef Libisofs_with_iso_iconV
iso_iconv_close(&conv, 0);
#else
iconv_close(conv);
#endif
free(wstr);
return ISO_CHARSET_CONV_ERROR;
}
@ -463,13 +369,8 @@ int str2ascii(const char *icharset, const char *input, char **output)
char *ret;
char *ret_;
char *src;
#ifdef Libisofs_with_iso_iconV
struct iso_iconv_handle conv;
int conv_ret;
#else
iconv_t conv;
#endif
/* That while loop smells like a potential show stopper */
size_t loop_counter = 0, loop_limit = 3;
@ -509,27 +410,14 @@ int str2ascii(const char *icharset, const char *input, char **output)
ret = ret_;
/* initialize iconv */
#ifdef Libisofs_with_iso_iconV
conv_ret = iso_iconv_open(&conv, "ASCII", "WCHAR_T", 0);
if (conv_ret <= 0) {
#else
conv = iconv_open("ASCII", "WCHAR_T");
if (conv == (iconv_t)-1) {
#endif
free(wsrc_);
free(ret_);
goto fallback;
}
#ifdef Libisofs_with_iso_iconV
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
#else
n = iconv(conv, &src, &inbytes, &ret, &outbytes);
#endif
while (n == -1) {
/* The destination buffer is too small. Stops here. */
if (errno == E2BIG)
@ -563,21 +451,9 @@ int str2ascii(const char *icharset, const char *input, char **output)
loop_counter++;
if (loop_counter > loop_limit)
break;
#ifdef Libisofs_with_iso_iconV
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
#else
n = iconv(conv, &src, &inbytes, &ret, &outbytes);
#endif
}
#ifdef Libisofs_with_iso_iconV
iso_iconv_close(&conv, 0);
#else
iconv_close(conv);
#endif
*ret='\0';
free(wsrc_);
@ -628,13 +504,8 @@ int str2ucs(const char *icharset, const char *input, uint16_t **output)
char *src;
char *ret;
char *ret_;
#ifdef Libisofs_with_iso_iconV
struct iso_iconv_handle conv;
int conv_ret;
#else
iconv_t conv;
#endif
/* That while loop smells like a potential show stopper */
size_t loop_counter = 0, loop_limit = 3;
@ -670,27 +541,14 @@ int str2ucs(const char *icharset, const char *input, uint16_t **output)
ret = ret_;
/* initialize iconv */
#ifdef Libisofs_with_iso_iconV
conv_ret = iso_iconv_open(&conv, "UCS-2BE", "WCHAR_T", 0);
if (conv_ret <= 0) {
#else
conv = iconv_open("UCS-2BE", "WCHAR_T");
if (conv == (iconv_t)-1) {
#endif
free(wsrc_);
free(ret_);
return ISO_CHARSET_CONV_ERROR;
}
#ifdef Libisofs_with_iso_iconV
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
#else
n = iconv(conv, &src, &inbytes, &ret, &outbytes);
#endif
while (n == -1) {
/* The destination buffer is too small. Stops here. */
if (errno == E2BIG)
@ -724,20 +582,9 @@ int str2ucs(const char *icharset, const char *input, uint16_t **output)
loop_counter++;
if (loop_counter > loop_limit)
break;
#ifdef Libisofs_with_iso_iconV
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
#else
n = iconv(conv, &src, &inbytes, &ret, &outbytes);
#endif
}
#ifdef Libisofs_with_iso_iconV
iso_iconv_close(&conv, 0);
#else
iconv_close(conv);
#endif
/* close the ucs string */
set_ucsbe((uint16_t*) ret, '\0');
@ -1566,14 +1413,8 @@ char *ucs2str(const char *buf, size_t len)
{
size_t outbytes, inbytes;
char *str, *src, *out = NULL, *retval = NULL;
#ifdef Libisofs_with_iso_iconV
struct iso_iconv_handle conv;
int conv_ret;
#else
iconv_t conv;
#endif
size_t n;
inbytes = len;
@ -1584,36 +1425,15 @@ char *ucs2str(const char *buf, size_t len)
out = calloc(outbytes, 1);
/* convert to local charset */
#ifndef Libisofs_setlocale_in_iniT
/* ??? ts Nov 25 2008 :
Shouldn't this go to library initialization or even to app ?
*/
setlocale(LC_CTYPE, "");
#endif
#ifdef Libisofs_with_iso_iconV
conv_ret = iso_iconv_open(&conv, iso_get_local_charset(0), "UCS-2BE", 0);
if (conv_ret <= 0) {
#else
conv = iconv_open(iso_get_local_charset(0), "UCS-2BE");
if (conv == (iconv_t)(-1)) {
#endif
goto ex;
}
src = (char *)buf;
str = (char *)out;
#ifdef Libisofs_with_iso_iconV
n = iso_iconv(&conv, &src, &inbytes, &str, &outbytes, 0);
iso_iconv_close(&conv, 0);
#else
n = iconv(conv, &src, &inbytes, &str, &outbytes);
iconv_close(conv);
#endif
if (n == -1) {
/* error */
goto ex;

View File

@ -198,7 +198,11 @@ int iso_rbtree_insert(IsoRBTree *tree, void *data, void **item)
}
}
comp = tree->compare(q->data, data);
if (q->data == data) {
comp = 0;
} else {
comp = tree->compare(q->data, data);
}
/* Stop if found */
if (comp == 0) {