Yet incomplete implementation of IsoNode cloning.
(Commited to avoid tangling with upcomming iso_write_opts_set_no_dummy_block_adr())
This commit is contained in:
parent
92073c45ef
commit
a3eeda3d23
@ -239,6 +239,11 @@ 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. */
|
||||
|
||||
/**
|
||||
* Extra Caution: This option breaks any assumptions about names that
|
||||
* are supported by ECMA-119 specifications.
|
||||
@ -254,11 +259,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
|
||||
@ -479,14 +479,14 @@ 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 untranslated_name_len;
|
||||
|
||||
/**
|
||||
* if sort files or not. Sorting is based of the weight of each 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>
|
||||
@ -598,6 +599,33 @@ 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;
|
||||
|
||||
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 +633,7 @@ int extf_cmp_ino(IsoStream *s1, IsoStream *s2);
|
||||
|
||||
|
||||
IsoStreamIface extf_stream_class = {
|
||||
3,
|
||||
4,
|
||||
"extf",
|
||||
extf_stream_open,
|
||||
extf_stream_close,
|
||||
@ -616,7 +644,8 @@ IsoStreamIface extf_stream_class = {
|
||||
extf_stream_free,
|
||||
extf_update_size,
|
||||
extf_get_input_stream,
|
||||
extf_cmp_ino
|
||||
extf_cmp_ino,
|
||||
extf_clone_stream
|
||||
};
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2011 Thomas Schmitt
|
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* 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 >>> _clone() */
|
||||
typedef struct
|
||||
{
|
||||
IsoStream *orig;
|
||||
@ -529,12 +531,38 @@ IsoStream *gzip_get_input_stream(IsoStream *stream, int flag)
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
int gzip_clone_stream(IsoStream *old_stream, IsoStream **new_stream, int flag)
|
||||
{
|
||||
int ret;
|
||||
IsoStream *new_input_stream, *stream;
|
||||
GzipFilterStreamData *stream_data, *old_stream_data;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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 +573,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 +590,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
|
||||
};
|
||||
|
||||
|
||||
|
@ -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,60 @@ 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;
|
||||
|
||||
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 +847,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 +864,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
|
||||
};
|
||||
|
||||
|
||||
|
@ -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
|
||||
@ -317,6 +317,7 @@ typedef struct
|
||||
|
||||
typedef struct image_fs_data ImageFileSourceData;
|
||||
|
||||
/* IMPORTANT: Any change must be reflected by iso_ifs_source_clone */
|
||||
struct image_fs_data
|
||||
{
|
||||
IsoImageFilesystem *fs; /**< reference to the image it belongs to */
|
||||
@ -1987,6 +1988,101 @@ void ifs_fs_free(IsoFilesystem *fs)
|
||||
free(data);
|
||||
}
|
||||
|
||||
int iso_ifs_source_clone(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;
|
||||
unsigned char *new_aa_string;
|
||||
size_t aa_size;
|
||||
int i, new_aa_length = 0;
|
||||
|
||||
old_data = (ImageFileSourceData *) old_source->data;
|
||||
*new_source = NULL;
|
||||
src = calloc(1, sizeof(IsoFileSource));
|
||||
if (src == NULL)
|
||||
goto no_mem;
|
||||
new_data = calloc(1, sizeof(ImageFileSourceData));
|
||||
if (new_data == NULL)
|
||||
goto no_mem;
|
||||
new_name = strdup(old_data->name);
|
||||
if (new_name == NULL) {
|
||||
free((char *) src);
|
||||
free((char *) new_data);
|
||||
return ISO_OUT_OF_MEM;
|
||||
}
|
||||
if (old_data->nsections > 0) {
|
||||
new_sections = calloc(old_data->nsections,
|
||||
sizeof(struct iso_file_section));
|
||||
if (new_sections == NULL)
|
||||
goto no_mem;
|
||||
}
|
||||
if (old_data->aa_string != NULL) {
|
||||
aa_size = aaip_count_bytes(old_data->aa_string, 0);
|
||||
if (aa_size > 0) {
|
||||
new_aa_string = calloc(1, aa_size);
|
||||
if (new_aa_string == NULL)
|
||||
goto no_mem;
|
||||
}
|
||||
}
|
||||
|
||||
new_data->fs = old_data->fs;
|
||||
iso_filesystem_ref(new_data->fs);
|
||||
|
||||
/* Re-using the directory structure of the original image tree is
|
||||
supposed to not spoil independence of the cloned IsoFileSource because
|
||||
that directory structure does not change as long as the loaded
|
||||
image exists.
|
||||
The .readdir() method of IsoFileSourceIface will not list the clones
|
||||
but rather the originals.
|
||||
It is unclear anyway, how it should work with the root of a cloned
|
||||
IsoNode tree which would need to be implanted fakely into the
|
||||
IsoFilesystem.
|
||||
|
||||
Currently there is the technical problem that a new parent would have
|
||||
to be passed through the IsoStream cloning call, which cannot have
|
||||
knowledge of a newly created IsoSource parent.
|
||||
*/
|
||||
new_data->parent = old_data->parent;
|
||||
iso_file_source_ref(new_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;
|
||||
if (new_aa_length > 0)
|
||||
memcpy(new_aa_string, old_data->aa_string, new_aa_length);
|
||||
new_data->aa_string = new_aa_string;
|
||||
|
||||
*new_source = src;
|
||||
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)
|
||||
free((char *) new_aa_string);
|
||||
return ISO_OUT_OF_MEM;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read the SUSP system user entries of the "." entry of the root directory,
|
||||
* indentifying when Rock Ridge extensions are being used.
|
||||
|
@ -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_*/
|
||||
|
@ -807,6 +807,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;
|
||||
|
||||
@ -913,7 +915,7 @@ struct IsoStream_Iface
|
||||
* @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.
|
||||
@ -928,33 +930,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
|
||||
@ -967,6 +968,23 @@ 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.
|
||||
*
|
||||
* @since 1.0.2
|
||||
* Present if .version is 4 or higher.
|
||||
*/
|
||||
int (*clone_stream)(IsoStream *old_stream, IsoStream **new_stream,
|
||||
int flag);
|
||||
|
||||
};
|
||||
|
||||
#ifndef __cplusplus
|
||||
@ -3639,23 +3657,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
|
||||
@ -4392,6 +4426,45 @@ int iso_tree_add_new_cut_out_node(IsoImage *image, IsoDir *parent,
|
||||
off_t offset, off_t size,
|
||||
IsoNode **node);
|
||||
|
||||
/**
|
||||
* >>> INCOMPLETLY IMPLEMENTED YET. DO NOT USE !
|
||||
*
|
||||
* 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 without filter streams,
|
||||
* >>> IsoFile referring to local filesystem files without filter streams.
|
||||
* Silently ignored are nodes of type IsoBoot.
|
||||
* An IsoFile node with filter streams can be cloned if all those filters
|
||||
* are clonable and the node would be clonable without filter.
|
||||
* Clonable filter streams are created by:
|
||||
* iso_file_add_zisofs_filter()
|
||||
* iso_file_add_gzip_filter()
|
||||
* iso_file_add_external_filter()
|
||||
*
|
||||
* @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.
|
||||
* @param new_node
|
||||
* Will return a reference to the newly created clone.
|
||||
* @param flag
|
||||
* Unused yet. Submit 0.
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
@ -5191,6 +5264,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 --------------------------------- */
|
||||
|
||||
/**
|
||||
@ -6496,6 +6593,9 @@ 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
|
||||
|
||||
/* Internal developer note:
|
||||
Place new error codes directly above this comment.
|
||||
|
@ -166,6 +166,7 @@ iso_node_get_xinfo;
|
||||
iso_node_lookup_attr;
|
||||
iso_node_ref;
|
||||
iso_node_remove;
|
||||
iso_node_remove_tree;
|
||||
iso_node_remove_xinfo;
|
||||
iso_node_set_acl_text;
|
||||
iso_node_set_atime;
|
||||
@ -210,6 +211,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 +237,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;
|
||||
|
@ -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
|
||||
@ -363,6 +364,8 @@ 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";
|
||||
default:
|
||||
return "Unknown error";
|
||||
}
|
||||
|
@ -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
|
||||
@ -686,6 +686,36 @@ 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) {
|
||||
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 (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
|
||||
|
@ -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
|
||||
@ -121,6 +121,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;
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
@ -157,8 +157,60 @@ int fsrc_update_size(IsoStream *stream)
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
IsoStream *fsrc_get_input_stream(IsoStream *stream, int flag)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int fsrc_cmp_ino(IsoStream *s1, IsoStream *s2)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* <<< provisory */
|
||||
ret = iso_stream_cmp_ino(s1, s2, 1);
|
||||
|
||||
/* >>> find out whether both streams point to the same image file */;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int fsrc_clone_stream(IsoStream *old_stream, IsoStream **new_stream,
|
||||
int flag)
|
||||
{
|
||||
FSrcStreamData *data, *new_data;
|
||||
IsoStream *stream;
|
||||
int ret;
|
||||
|
||||
*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;
|
||||
data = (FSrcStreamData*) old_stream->data;
|
||||
stream->class = old_stream->class;
|
||||
stream->refcount = 1;
|
||||
stream->data = new_data;
|
||||
|
||||
ret = iso_ifs_source_clone(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, /* .clone_stream() is defined for this stream */
|
||||
"fsrc",
|
||||
fsrc_open,
|
||||
fsrc_close,
|
||||
@ -167,7 +219,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)
|
||||
@ -924,3 +979,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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
@ -94,5 +95,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_*/
|
||||
|
@ -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
|
||||
@ -993,3 +994,100 @@ char *iso_tree_get_node_path(IsoNode *node)
|
||||
return strdup(path);
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------- tree cloning ------------------------------ */
|
||||
|
||||
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;
|
||||
|
||||
*new_node = NULL;
|
||||
|
||||
ret = iso_tree_add_new_dir(new_parent, new_name, &new_dir);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
*new_node = (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,
|
||||
0);
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
}
|
||||
ret = ISO_SUCCESS;
|
||||
ex:;
|
||||
if (iter != NULL)
|
||||
iso_dir_iter_free(iter);
|
||||
if (ret < 0 && new_dir != NULL) {
|
||||
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_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;
|
||||
}
|
||||
|
||||
/* 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, NULL) == 1)
|
||||
return ISO_NODE_NAME_NOT_UNIQUE;
|
||||
|
||||
/* >>> clone particular node types */;
|
||||
if (node->type == LIBISO_DIR) {
|
||||
ret = iso_tree_clone_dir((IsoDir *) node, new_parent, new_name,
|
||||
new_node, 0);
|
||||
} 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) {
|
||||
/* >>> */;
|
||||
} else if (node->type == LIBISO_SPECIAL) {
|
||||
/* >>> */;
|
||||
} else if (node->type == LIBISO_BOOT) {
|
||||
ret = ISO_SUCCESS; /* API says they are silently ignored */
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user