New API calls iso_tree_clone(), iso_stream_clone.
New IsoFileSourceIface version 2 with method clone_src(). New IsoStreamIface version 4 with method clone_stream(). New public function prototype iso_node_xinfo_cloner. New API calls iso_node_xinfo_make_clonable(), iso_node_xinfo_get_cloner(). New public iso_node_xinfo_cloner instance aaip_xinfo_cloner(). New API calls iso_node_get_next_xinfo(), iso_node_remove_all_xinfo(). New API call iso_node_remove_tree().
This commit is contained in:
parent
74c68224c7
commit
1082e628d1
@ -41,7 +41,7 @@
|
|||||||
* for classical pipe filtering.
|
* for classical pipe filtering.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* IMPORTANT: Any change must be reflected by extf_clone_stream() */
|
||||||
/*
|
/*
|
||||||
* Individual runtime properties exist only as long as the stream is opened.
|
* Individual runtime properties exist only as long as the stream is opened.
|
||||||
*/
|
*/
|
||||||
@ -606,6 +606,9 @@ int extf_clone_stream(IsoStream *old_stream, IsoStream **new_stream, int flag)
|
|||||||
IsoStream *new_input_stream, *stream;
|
IsoStream *new_input_stream, *stream;
|
||||||
ExternalFilterStreamData *stream_data, *old_stream_data;
|
ExternalFilterStreamData *stream_data, *old_stream_data;
|
||||||
|
|
||||||
|
if (flag)
|
||||||
|
return ISO_STREAM_NO_CLONE; /* unknown option required */
|
||||||
|
|
||||||
stream_data = calloc(1, sizeof(ExternalFilterStreamData));
|
stream_data = calloc(1, sizeof(ExternalFilterStreamData));
|
||||||
if (stream_data == NULL)
|
if (stream_data == NULL)
|
||||||
return ISO_OUT_OF_MEM;
|
return ISO_OUT_OF_MEM;
|
||||||
|
@ -154,7 +154,7 @@ static int gzip_compression_level = 6;
|
|||||||
/*
|
/*
|
||||||
* The data payload of an individual Gzip Filter IsoStream
|
* The data payload of an individual Gzip Filter IsoStream
|
||||||
*/
|
*/
|
||||||
/* IMPORTANT: Any change must be reflected by >>> _clone() */
|
/* IMPORTANT: Any change must be reflected by gzip_clone_stream() */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
IsoStream *orig;
|
IsoStream *orig;
|
||||||
@ -538,6 +538,9 @@ int gzip_clone_stream(IsoStream *old_stream, IsoStream **new_stream, int flag)
|
|||||||
IsoStream *new_input_stream, *stream;
|
IsoStream *new_input_stream, *stream;
|
||||||
GzipFilterStreamData *stream_data, *old_stream_data;
|
GzipFilterStreamData *stream_data, *old_stream_data;
|
||||||
|
|
||||||
|
if (flag)
|
||||||
|
return ISO_STREAM_NO_CLONE; /* unknown option required */
|
||||||
|
|
||||||
stream_data = calloc(1, sizeof(GzipFilterStreamData));
|
stream_data = calloc(1, sizeof(GzipFilterStreamData));
|
||||||
if (stream_data == NULL)
|
if (stream_data == NULL)
|
||||||
return ISO_OUT_OF_MEM;
|
return ISO_OUT_OF_MEM;
|
||||||
|
@ -168,7 +168,7 @@ static int ziso_compression_level = 6;
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* The common data payload of an individual Zisofs Filter IsoStream
|
* The common data payload of an individual Zisofs Filter IsoStream
|
||||||
* IMPORTANT: Any change must be reflected by ziso_clone_stream.
|
* IMPORTANT: Any change must be reflected by ziso_clone_stream().
|
||||||
*/
|
*/
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@ -185,7 +185,7 @@ typedef struct
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* The data payload of an individual Zisofs Filter Compressor IsoStream
|
* The data payload of an individual Zisofs Filter Compressor IsoStream
|
||||||
* IMPORTANT: Any change must be reflected by ziso_clone_stream.
|
* IMPORTANT: Any change must be reflected by ziso_clone_stream().
|
||||||
*/
|
*/
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@ -201,7 +201,7 @@ typedef struct
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* The data payload of an individual Zisofs Filter Uncompressor IsoStream
|
* The data payload of an individual Zisofs Filter Uncompressor IsoStream
|
||||||
* IMPORTANT: Any change must be reflected by ziso_clone_stream.
|
* IMPORTANT: Any change must be reflected by ziso_clone_stream().
|
||||||
*/
|
*/
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@ -792,6 +792,9 @@ int ziso_clone_stream(IsoStream *old_stream, IsoStream **new_stream, int flag)
|
|||||||
ZisofsUncomprStreamData *uncompr, *old_uncompr;
|
ZisofsUncomprStreamData *uncompr, *old_uncompr;
|
||||||
ZisofsComprStreamData *compr, *old_compr;
|
ZisofsComprStreamData *compr, *old_compr;
|
||||||
|
|
||||||
|
if (flag)
|
||||||
|
return ISO_STREAM_NO_CLONE; /* unknown option required */
|
||||||
|
|
||||||
ret = iso_stream_clone_filter_common(old_stream, &stream,
|
ret = iso_stream_clone_filter_common(old_stream, &stream,
|
||||||
&new_input_stream, 0);
|
&new_input_stream, 0);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
|
@ -317,7 +317,7 @@ typedef struct
|
|||||||
|
|
||||||
typedef struct image_fs_data ImageFileSourceData;
|
typedef struct image_fs_data ImageFileSourceData;
|
||||||
|
|
||||||
/* IMPORTANT: Any change must be reflected by iso_ifs_source_clone */
|
/* IMPORTANT: Any change must be reflected by ifs_clone_src */
|
||||||
struct image_fs_data
|
struct image_fs_data
|
||||||
{
|
{
|
||||||
IsoImageFilesystem *fs; /**< reference to the image it belongs to */
|
IsoImageFilesystem *fs; /**< reference to the image it belongs to */
|
||||||
@ -1044,10 +1044,87 @@ int ifs_get_aa_string(IsoFileSource *src, unsigned char **aa_string, int flag)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int ifs_clone_src(IsoFileSource *old_source,
|
||||||
|
IsoFileSource **new_source, int flag)
|
||||||
|
{
|
||||||
|
IsoFileSource *src = NULL;
|
||||||
|
ImageFileSourceData *old_data, *new_data = NULL;
|
||||||
|
char *new_name = NULL;
|
||||||
|
struct iso_file_section *new_sections = NULL;
|
||||||
|
void *new_aa_string = NULL;
|
||||||
|
int i, ret;
|
||||||
|
|
||||||
|
if (flag)
|
||||||
|
return ISO_STREAM_NO_CLONE; /* unknown option required */
|
||||||
|
|
||||||
|
old_data = (ImageFileSourceData *) old_source->data;
|
||||||
|
*new_source = NULL;
|
||||||
|
src = calloc(1, sizeof(IsoFileSource));
|
||||||
|
if (src == NULL)
|
||||||
|
goto no_mem;
|
||||||
|
new_name = strdup(old_data->name);
|
||||||
|
if (new_name == NULL)
|
||||||
|
goto no_mem;
|
||||||
|
new_data = calloc(1, sizeof(ImageFileSourceData));
|
||||||
|
|
||||||
|
if (new_data == NULL)
|
||||||
|
goto no_mem;
|
||||||
|
if (old_data->nsections > 0) {
|
||||||
|
new_sections = calloc(old_data->nsections,
|
||||||
|
sizeof(struct iso_file_section));
|
||||||
|
if (new_sections == NULL)
|
||||||
|
goto no_mem;
|
||||||
|
}
|
||||||
|
ret = aaip_xinfo_cloner(old_data->aa_string, &new_aa_string, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
goto no_mem;
|
||||||
|
|
||||||
|
new_data->fs = old_data->fs;
|
||||||
|
iso_filesystem_ref(new_data->fs);
|
||||||
|
|
||||||
|
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;
|
||||||
|
new_data->aa_string = (unsigned char *) new_aa_string;
|
||||||
|
|
||||||
|
src->class = old_source->class;
|
||||||
|
src->refcount = 1;
|
||||||
|
src->data = new_data;
|
||||||
|
*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)
|
||||||
|
aaip_xinfo_func(new_aa_string, 1);
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
IsoFileSourceIface ifs_class = {
|
IsoFileSourceIface ifs_class = {
|
||||||
|
|
||||||
1, /* version */
|
2, /* version */
|
||||||
ifs_get_path,
|
ifs_get_path,
|
||||||
ifs_get_name,
|
ifs_get_name,
|
||||||
ifs_lstat,
|
ifs_lstat,
|
||||||
@ -1061,7 +1138,8 @@ IsoFileSourceIface ifs_class = {
|
|||||||
ifs_get_filesystem,
|
ifs_get_filesystem,
|
||||||
ifs_free,
|
ifs_free,
|
||||||
ifs_lseek,
|
ifs_lseek,
|
||||||
ifs_get_aa_string
|
ifs_get_aa_string,
|
||||||
|
ifs_clone_src
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1988,101 +2066,6 @@ void ifs_fs_free(IsoFilesystem *fs)
|
|||||||
free(data);
|
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,
|
* Read the SUSP system user entries of the "." entry of the root directory,
|
||||||
* indentifying when Rock Ridge extensions are being used.
|
* indentifying when Rock Ridge extensions are being used.
|
||||||
|
@ -39,7 +39,7 @@ int iso_file_source_new_lfs(IsoFileSource *parent, const char *name,
|
|||||||
*/
|
*/
|
||||||
IsoFilesystem *lfs= NULL;
|
IsoFilesystem *lfs= NULL;
|
||||||
|
|
||||||
|
/* IMPORTANT: Any change must be reflected by lfs_clone_src() */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
/** reference to the parent (if root it points to itself) */
|
/** reference to the parent (if root it points to itself) */
|
||||||
@ -534,10 +534,54 @@ ex:;
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int lfs_clone_src(IsoFileSource *old_source,
|
||||||
|
IsoFileSource **new_source, int flag)
|
||||||
|
{
|
||||||
|
IsoFileSource *src = NULL;
|
||||||
|
char *new_name = NULL;
|
||||||
|
_LocalFsFileSource *old_data, *new_data = NULL;
|
||||||
|
|
||||||
|
if (flag)
|
||||||
|
return ISO_STREAM_NO_CLONE; /* unknown option required */
|
||||||
|
|
||||||
|
old_data = (_LocalFsFileSource *) old_source->data;
|
||||||
|
*new_source = NULL;
|
||||||
|
src = calloc(1, sizeof(IsoFileSource));
|
||||||
|
if (src == NULL)
|
||||||
|
goto no_mem;
|
||||||
|
new_name = strdup(old_data->name);
|
||||||
|
if (new_name == NULL)
|
||||||
|
goto no_mem;
|
||||||
|
|
||||||
|
new_data = calloc(1, sizeof(_LocalFsFileSource));
|
||||||
|
if (new_data == NULL)
|
||||||
|
goto no_mem;
|
||||||
|
new_data->openned = 0;
|
||||||
|
new_data->info.fd = -1; /* the value does not matter with (openned == 0) */
|
||||||
|
new_data->name = new_name;
|
||||||
|
new_data->parent = old_data->parent;
|
||||||
|
iso_file_source_ref(new_data->parent);
|
||||||
|
|
||||||
|
src->class = old_source->class;
|
||||||
|
src->refcount = 1;
|
||||||
|
src->data = new_data;
|
||||||
|
*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);
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
IsoFileSourceIface lfs_class = {
|
IsoFileSourceIface lfs_class = {
|
||||||
|
|
||||||
1, /* version */
|
2, /* version */
|
||||||
lfs_get_path,
|
lfs_get_path,
|
||||||
lfs_get_name,
|
lfs_get_name,
|
||||||
lfs_lstat,
|
lfs_lstat,
|
||||||
@ -551,7 +595,8 @@ IsoFileSourceIface lfs_class = {
|
|||||||
lfs_get_filesystem,
|
lfs_get_filesystem,
|
||||||
lfs_free,
|
lfs_free,
|
||||||
lfs_lseek,
|
lfs_lseek,
|
||||||
lfs_get_aa_string
|
lfs_get_aa_string,
|
||||||
|
lfs_clone_src
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
|
||||||
|
#ifndef LIBISO_LIBISOFS_H_
|
||||||
|
#define LIBISO_LIBISOFS_H_
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007-2008 Vreixo Formoso, Mario Danic
|
* Copyright (c) 2007-2008 Vreixo Formoso, Mario Danic
|
||||||
* Copyright (c) 2009-2011 Thomas Schmitt
|
* Copyright (c) 2009-2011 Thomas Schmitt
|
||||||
@ -24,8 +28,17 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef LIBISO_LIBISOFS_H_
|
/*
|
||||||
#define LIBISO_LIBISOFS_H_
|
* Normally this API is operated via public functions and opaque object
|
||||||
|
* handles. But it also exposes several C structures which may be used to
|
||||||
|
* provide custom functionality for the objects of the API. The same
|
||||||
|
* structures are used for internal objects of libisofs, too.
|
||||||
|
* You are not supposed to manipulate the entrails of such objects if they
|
||||||
|
* are not your own custom extensions.
|
||||||
|
*
|
||||||
|
* See for an example IsoStream = struct iso_stream below.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
@ -502,6 +515,8 @@ struct IsoFileSource_Iface
|
|||||||
* @since 0.6.2
|
* @since 0.6.2
|
||||||
* Version 1 additionally provides function *(get_aa_string)().
|
* Version 1 additionally provides function *(get_aa_string)().
|
||||||
* @since 0.6.14
|
* @since 0.6.14
|
||||||
|
* Version 2 additionally provides function *(clone_src)().
|
||||||
|
* @since 1.0.2
|
||||||
*/
|
*/
|
||||||
int version;
|
int version;
|
||||||
|
|
||||||
@ -736,6 +751,24 @@ struct IsoFileSource_Iface
|
|||||||
int (*get_aa_string)(IsoFileSource *src,
|
int (*get_aa_string)(IsoFileSource *src,
|
||||||
unsigned char **aa_string, int flag);
|
unsigned char **aa_string, int flag);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Produce a copy of a source. It must be possible to operate both source
|
||||||
|
* objects concurrently.
|
||||||
|
*
|
||||||
|
* @param old_src
|
||||||
|
* The existing source object to be copied
|
||||||
|
* @param new_stream
|
||||||
|
* Will return a pointer to the copy
|
||||||
|
* @param flag
|
||||||
|
* Bitfield for control purposes. Submit 0 for now.
|
||||||
|
* The function shall return ISO_STREAM_NO_CLONE on unknown flag bits.
|
||||||
|
*
|
||||||
|
* @since 1.0.2
|
||||||
|
* Present if .version is 2 or higher.
|
||||||
|
*/
|
||||||
|
int (*clone_src)(IsoFileSource *old_src, IsoFileSource **new_src,
|
||||||
|
int flag);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TODO #00004 Add a get_mime_type() function.
|
* TODO #00004 Add a get_mime_type() function.
|
||||||
* This can be useful for GUI apps, to choose the icon of the file
|
* This can be useful for GUI apps, to choose the icon of the file
|
||||||
@ -760,6 +793,31 @@ struct iso_file_source
|
|||||||
#endif /* ! Libisofs_h_as_cpluspluS */
|
#endif /* ! Libisofs_h_as_cpluspluS */
|
||||||
#endif /* ! __cplusplus */
|
#endif /* ! __cplusplus */
|
||||||
|
|
||||||
|
|
||||||
|
/* A class of IsoStream is implemented by a class description
|
||||||
|
* IsoStreamIface = struct IsoStream_Iface
|
||||||
|
* and a structure of data storage for each instance of IsoStream.
|
||||||
|
* This structure shall be known to the functions of the IsoStreamIface.
|
||||||
|
* To create a custom IsoStream class:
|
||||||
|
* - Define the structure of the custom instance data.
|
||||||
|
* - Implement the methods which are described by the definition of
|
||||||
|
* struct IsoStream_Iface (see below),
|
||||||
|
* - Create a static instance of IsoStreamIface which lists the methods as
|
||||||
|
* C function pointers. (Example in libisofs/stream.c : fsrc_stream_class)
|
||||||
|
* To create an instance of that class:
|
||||||
|
* - Allocate sizeof(IsoStream) bytes of memory and initialize it as
|
||||||
|
* struct iso_stream :
|
||||||
|
* - Point to the custom IsoStreamIface by member .class .
|
||||||
|
* - Set member .refcount to 1.
|
||||||
|
* - Let member .data point to the custom instance data.
|
||||||
|
*
|
||||||
|
* Regrettably the choice of the structure member name "class" makes it
|
||||||
|
* impossible to implement this generic interface in C++ language directly.
|
||||||
|
* If C++ is absolutely necessary then you will have to make own copies
|
||||||
|
* of the public API structures. Use other names but take care to maintain
|
||||||
|
* the same memory layout.
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Representation of file contents. It is an stream of bytes, functionally
|
* Representation of file contents. It is an stream of bytes, functionally
|
||||||
* like a pipe.
|
* like a pipe.
|
||||||
@ -795,6 +853,7 @@ extern ino_t serial_id;
|
|||||||
*
|
*
|
||||||
* @since 0.6.4
|
* @since 0.6.4
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct IsoStream_Iface
|
struct IsoStream_Iface
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -851,7 +910,7 @@ struct IsoStream_Iface
|
|||||||
off_t (*get_size)(IsoStream *stream);
|
off_t (*get_size)(IsoStream *stream);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempts to read up to count bytes from the given stream into
|
* Attempt to read up to count bytes from the given stream into
|
||||||
* the buffer starting at buf. The implementation has to make sure that
|
* the buffer starting at buf. The implementation has to make sure that
|
||||||
* either the full desired count of bytes is delivered or that the
|
* either the full desired count of bytes is delivered or that the
|
||||||
* next call to this function will return EOF or error.
|
* next call to this function will return EOF or error.
|
||||||
@ -867,12 +926,9 @@ struct IsoStream_Iface
|
|||||||
int (*read)(IsoStream *stream, void *buf, size_t count);
|
int (*read)(IsoStream *stream, void *buf, size_t count);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether this IsoStream can be read several times, with the same results.
|
* Tell whether this IsoStream can be read several times, with the same
|
||||||
* For example, a regular file is repeatable, you can read it as many
|
* results. For example, a regular file is repeatable, you can read it
|
||||||
* times as you want. However, a pipe isn't.
|
* as many times as you want. However, a pipe is not.
|
||||||
*
|
|
||||||
* This function doesn't take into account if the file has been modified
|
|
||||||
* between the two reads.
|
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* 1 if stream is repeatable, 0 if not,
|
* 1 if stream is repeatable, 0 if not,
|
||||||
@ -893,13 +949,13 @@ struct IsoStream_Iface
|
|||||||
void (*free)(IsoStream *stream);
|
void (*free)(IsoStream *stream);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the size of the IsoStream with the current size of the
|
* Update the size of the IsoStream with the current size of the underlying
|
||||||
* underlying source. After calling this, get_size() will return
|
* source, if the source is prone to size changes. After calling this,
|
||||||
* the new size. This should never be called after
|
* get_size() shall eventually return the new size.
|
||||||
* iso_image_create_burn_source() was called and the image was not
|
* This will never be called after iso_image_create_burn_source() was
|
||||||
* completely written. To update the size of all files before written the
|
* called and before the image was completely written.
|
||||||
* image, you may want to call iso_image_update_sizes() just before
|
* (The API call to update the size of all files in the image is
|
||||||
* iso_image_create_burn_source().
|
* iso_image_update_sizes()).
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* 1 if ok, < 0 on error (has to be a valid libisofs error code)
|
* 1 if ok, < 0 on error (has to be a valid libisofs error code)
|
||||||
@ -910,7 +966,7 @@ struct IsoStream_Iface
|
|||||||
int (*update_size)(IsoStream *stream);
|
int (*update_size)(IsoStream *stream);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtains the eventual input stream of a filter stream.
|
* Retrieve the eventual input stream of a filter stream.
|
||||||
*
|
*
|
||||||
* @param stream
|
* @param stream
|
||||||
* The eventual filter stream to be inquired.
|
* The eventual filter stream to be inquired.
|
||||||
@ -918,7 +974,7 @@ struct IsoStream_Iface
|
|||||||
* Bitfield for control purposes. 0 means normal behavior.
|
* Bitfield for control purposes. 0 means normal behavior.
|
||||||
* @return
|
* @return
|
||||||
* The input stream, if one exists. Elsewise NULL.
|
* The input stream, if one exists. Elsewise NULL.
|
||||||
* No extra reference to the stream is taken by this call.
|
* No extra reference to the stream shall be taken by this call.
|
||||||
*
|
*
|
||||||
* @since 0.6.18
|
* @since 0.6.18
|
||||||
* Present if .version is 2 or higher.
|
* Present if .version is 2 or higher.
|
||||||
@ -978,6 +1034,9 @@ struct IsoStream_Iface
|
|||||||
* Will return a pointer to the copy
|
* Will return a pointer to the copy
|
||||||
* @param flag
|
* @param flag
|
||||||
* Bitfield for control purposes. 0 means normal behavior.
|
* Bitfield for control purposes. 0 means normal behavior.
|
||||||
|
* The function shall return ISO_STREAM_NO_CLONE on unknown flag bits.
|
||||||
|
* @return
|
||||||
|
* 1 in case of success, or an error code < 0
|
||||||
*
|
*
|
||||||
* @since 1.0.2
|
* @since 1.0.2
|
||||||
* Present if .version is 4 or higher.
|
* Present if .version is 4 or higher.
|
||||||
@ -3222,9 +3281,9 @@ void iso_node_unref(IsoNode *node);
|
|||||||
enum IsoNodeType iso_node_get_type(IsoNode *node);
|
enum IsoNodeType iso_node_get_type(IsoNode *node);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to handle particular extended information. The function
|
* Class of functions to handle particular extended information. A function
|
||||||
* pointer acts as an identifier for the type of the information. Structs
|
* instance acts as an identifier for the type of the information. Structs
|
||||||
* with same information type must use the same function.
|
* with same information type must use a pointer to the same function.
|
||||||
*
|
*
|
||||||
* @param data
|
* @param data
|
||||||
* Attached data
|
* Attached data
|
||||||
@ -3279,6 +3338,20 @@ int iso_node_add_xinfo(IsoNode *node, iso_node_xinfo_func proc, void *data);
|
|||||||
*/
|
*/
|
||||||
int iso_node_remove_xinfo(IsoNode *node, iso_node_xinfo_func proc);
|
int iso_node_remove_xinfo(IsoNode *node, iso_node_xinfo_func proc);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove all extended information from the given node.
|
||||||
|
*
|
||||||
|
* @param node
|
||||||
|
* The node where to remove all extended info
|
||||||
|
* @param flag
|
||||||
|
* Bitfield for control purposes, unused yet, submit 0
|
||||||
|
* @return
|
||||||
|
* 1 on success, < 0 on error
|
||||||
|
*
|
||||||
|
* @since 1.0.2
|
||||||
|
*/
|
||||||
|
int iso_node_remove_all_xinfo(IsoNode *node, int flag);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the given extended info (defined by the proc function) from the
|
* Get the given extended info (defined by the proc function) from the
|
||||||
* given node.
|
* given node.
|
||||||
@ -3298,6 +3371,102 @@ int iso_node_remove_xinfo(IsoNode *node, iso_node_xinfo_func proc);
|
|||||||
*/
|
*/
|
||||||
int iso_node_get_xinfo(IsoNode *node, iso_node_xinfo_func proc, void **data);
|
int iso_node_get_xinfo(IsoNode *node, iso_node_xinfo_func proc, void **data);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the next pair of function pointer and data of an iteration of the
|
||||||
|
* list of extended informations. Like:
|
||||||
|
* iso_node_xinfo_func proc;
|
||||||
|
* void *handle = NULL, *data;
|
||||||
|
* while (iso_node_get_next_xinfo(node, &handle, &proc, &data) == 1) {
|
||||||
|
* ... make use of proc and data ...
|
||||||
|
* }
|
||||||
|
* The iteration allocates no memory. So you may end it without any disposal
|
||||||
|
* action.
|
||||||
|
* IMPORTANT: Do not continue iterations after manipulating the extended
|
||||||
|
* information of a node. Memory corruption hazard !
|
||||||
|
* @param node
|
||||||
|
* The node to inquire
|
||||||
|
* @param handle
|
||||||
|
* The opaque iteration handle. Initialize iteration by submitting
|
||||||
|
* a pointer to a void pointer with value NULL.
|
||||||
|
* Do not alter its content until iteration has ended.
|
||||||
|
* @param proc
|
||||||
|
* The function pointer which serves as key
|
||||||
|
* @param data
|
||||||
|
* Will be filled with the extended info corresponding to the given proc
|
||||||
|
* function
|
||||||
|
* @return
|
||||||
|
* 1 on success
|
||||||
|
* 0 if iteration has ended (proc and data are invalid then)
|
||||||
|
* < 0 on error
|
||||||
|
*
|
||||||
|
* @since 1.0.2
|
||||||
|
*/
|
||||||
|
int iso_node_get_next_xinfo(IsoNode *node, void **handle,
|
||||||
|
iso_node_xinfo_func *proc, void **data);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class of functions to clone extended information. A function instance gets
|
||||||
|
* associated to a particular iso_node_xinfo_func instance by function
|
||||||
|
* iso_node_xinfo_make_clonable(). This is a precondition to have IsoNode
|
||||||
|
* objects clonable which carry data for a particular iso_node_xinfo_func.
|
||||||
|
*
|
||||||
|
* @param old_data
|
||||||
|
* Data item to be cloned
|
||||||
|
* @param new_data
|
||||||
|
* Shall return the cloned data item
|
||||||
|
* @param flag
|
||||||
|
* Unused yet, submit 0
|
||||||
|
* The function shall return ISO_XINFO_NO_CLONE on unknown flag bits.
|
||||||
|
* @return
|
||||||
|
* > 0 number of allocated bytes
|
||||||
|
* 0 no size info is available
|
||||||
|
* < 0 error
|
||||||
|
*
|
||||||
|
* @since 1.0.2
|
||||||
|
*/
|
||||||
|
typedef int (*iso_node_xinfo_cloner)(void *old_data, void **new_data,int flag);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Associate a iso_node_xinfo_cloner to a particular class of extended
|
||||||
|
* information in order to make it clonable.
|
||||||
|
*
|
||||||
|
* @param proc
|
||||||
|
* The key and disposal function which identifies the particular
|
||||||
|
* extended information class.
|
||||||
|
* @param cloner
|
||||||
|
* The cloner function which shall be associated with proc.
|
||||||
|
* @param flag
|
||||||
|
* Unused yet, submit 0
|
||||||
|
* @return
|
||||||
|
* 1 success, < 0 error
|
||||||
|
*
|
||||||
|
* @since 1.0.2
|
||||||
|
*/
|
||||||
|
int iso_node_xinfo_make_clonable(iso_node_xinfo_func proc,
|
||||||
|
iso_node_xinfo_cloner cloner, int flag);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inquire the registered cloner function for a particular class of
|
||||||
|
* extended information.
|
||||||
|
*
|
||||||
|
* @param proc
|
||||||
|
* The key and disposal function which identifies the particular
|
||||||
|
* extended information class.
|
||||||
|
* @param cloner
|
||||||
|
* Will return the cloner function which is associated with proc, or NULL.
|
||||||
|
* @param flag
|
||||||
|
* Unused yet, submit 0
|
||||||
|
* @return
|
||||||
|
* 1 success, 0 no cloner registered for proc, < 0 error
|
||||||
|
*
|
||||||
|
* @since 1.0.2
|
||||||
|
*/
|
||||||
|
int iso_node_xinfo_get_cloner(iso_node_xinfo_func proc,
|
||||||
|
iso_node_xinfo_cloner *cloner, int flag);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the name of a node. Note that if the node is already added to a dir
|
* Set the name of a node. Note that if the node is already added to a dir
|
||||||
* this can fail if dir already contains a node with the new name.
|
* this can fail if dir already contains a node with the new name.
|
||||||
@ -4456,17 +4625,24 @@ int iso_tree_add_new_cut_out_node(IsoImage *image, IsoDir *parent,
|
|||||||
* clone_stream().
|
* clone_stream().
|
||||||
* Surely clonable node types are:
|
* Surely clonable node types are:
|
||||||
* IsoDir,
|
* IsoDir,
|
||||||
* >>> IsoSymlink,
|
* IsoSymlink,
|
||||||
* >>> IsoSpecial,
|
* IsoSpecial,
|
||||||
* IsoFile from a loaded ISO image without filter streams,
|
* IsoFile from a loaded ISO image,
|
||||||
* >>> IsoFile referring to local filesystem files without filter streams.
|
* IsoFile referring to local filesystem files,
|
||||||
|
* IsoFile created by iso_tree_add_new_file
|
||||||
|
* from a stream created by iso_memory_stream_new(),
|
||||||
|
* IsoFile created by iso_tree_add_new_cut_out_node()
|
||||||
* Silently ignored are nodes of type IsoBoot.
|
* Silently ignored are nodes of type IsoBoot.
|
||||||
* An IsoFile node with filter streams can be cloned if all those filters
|
* An IsoFile node with IsoStream filters can be cloned if all those filters
|
||||||
* are clonable and the node would be clonable without filter.
|
* are clonable and the node would be clonable without filter.
|
||||||
* Clonable filter streams are created by:
|
* Clonable IsoStream filters are created by:
|
||||||
* iso_file_add_zisofs_filter()
|
* iso_file_add_zisofs_filter()
|
||||||
* iso_file_add_gzip_filter()
|
* iso_file_add_gzip_filter()
|
||||||
* iso_file_add_external_filter()
|
* iso_file_add_external_filter()
|
||||||
|
* An IsoNode with extended information as of iso_node_add_xinfo() can only be
|
||||||
|
* cloned if each of the iso_node_xinfo_func instances is associated to a
|
||||||
|
* clone function. See iso_node_xinfo_make_clonable().
|
||||||
|
* All internally used classes of extended information are clonable.
|
||||||
*
|
*
|
||||||
* @param node
|
* @param node
|
||||||
* The node to be cloned.
|
* The node to be cloned.
|
||||||
@ -5334,6 +5510,12 @@ int iso_stream_clone(IsoStream *old_stream, IsoStream **new_stream, int flag);
|
|||||||
*/
|
*/
|
||||||
int aaip_xinfo_func(void *data, int flag);
|
int aaip_xinfo_func(void *data, int flag);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The iso_node_xinfo_cloner function which gets associated to aaip_xinfo_func
|
||||||
|
* by iso_init() resp. iso_init_with_flag() via iso_node_xinfo_make_clonable().
|
||||||
|
* @since 1.0.2
|
||||||
|
*/
|
||||||
|
int aaip_xinfo_cloner(void *old_data, void **new_data, int flag);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the eventual ACLs which are associated with the node.
|
* Get the eventual ACLs which are associated with the node.
|
||||||
@ -6617,6 +6799,11 @@ int iso_md5_match(char first_md5[16], char second_md5[16]);
|
|||||||
(FAILURE, HIGH, -374) */
|
(FAILURE, HIGH, -374) */
|
||||||
#define ISO_STREAM_NO_CLONE 0xE830FE8A
|
#define ISO_STREAM_NO_CLONE 0xE830FE8A
|
||||||
|
|
||||||
|
/** Extended information class offers no cloning method
|
||||||
|
(FAILURE, HIGH, -375) */
|
||||||
|
#define ISO_XINFO_NO_CLONE 0xE830FE89
|
||||||
|
|
||||||
|
|
||||||
/* Internal developer note:
|
/* Internal developer note:
|
||||||
Place new error codes directly above this comment.
|
Place new error codes directly above this comment.
|
||||||
Newly introduced errors must get a message entry in
|
Newly introduced errors must get a message entry in
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
LIBISOFS6 {
|
LIBISOFS6 {
|
||||||
global:
|
global:
|
||||||
|
aaip_xinfo_cloner;
|
||||||
aaip_xinfo_func;
|
aaip_xinfo_func;
|
||||||
el_torito_get_bootable;
|
el_torito_get_bootable;
|
||||||
el_torito_get_boot_media_type;
|
el_torito_get_boot_media_type;
|
||||||
@ -156,6 +157,7 @@ iso_node_get_hidden;
|
|||||||
iso_node_get_mode;
|
iso_node_get_mode;
|
||||||
iso_node_get_mtime;
|
iso_node_get_mtime;
|
||||||
iso_node_get_name;
|
iso_node_get_name;
|
||||||
|
iso_node_get_next_xinfo;
|
||||||
iso_node_get_old_image_lba;
|
iso_node_get_old_image_lba;
|
||||||
iso_node_get_parent;
|
iso_node_get_parent;
|
||||||
iso_node_get_permissions;
|
iso_node_get_permissions;
|
||||||
@ -166,6 +168,7 @@ iso_node_get_xinfo;
|
|||||||
iso_node_lookup_attr;
|
iso_node_lookup_attr;
|
||||||
iso_node_ref;
|
iso_node_ref;
|
||||||
iso_node_remove;
|
iso_node_remove;
|
||||||
|
iso_node_remove_all_xinfo;
|
||||||
iso_node_remove_tree;
|
iso_node_remove_tree;
|
||||||
iso_node_remove_xinfo;
|
iso_node_remove_xinfo;
|
||||||
iso_node_set_acl_text;
|
iso_node_set_acl_text;
|
||||||
@ -181,6 +184,8 @@ iso_node_set_sort_weight;
|
|||||||
iso_node_set_uid;
|
iso_node_set_uid;
|
||||||
iso_node_take;
|
iso_node_take;
|
||||||
iso_node_unref;
|
iso_node_unref;
|
||||||
|
iso_node_xinfo_get_cloner;
|
||||||
|
iso_node_xinfo_make_clonable;
|
||||||
iso_node_zf_by_magic;
|
iso_node_zf_by_magic;
|
||||||
iso_obtain_msgs;
|
iso_obtain_msgs;
|
||||||
iso_read_image_features_destroy;
|
iso_read_image_features_destroy;
|
||||||
|
@ -424,6 +424,22 @@ int checksum_cx_xinfo_func(void *data, int flag)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The iso_node_xinfo_cloner function which gets associated to
|
||||||
|
* checksum_cx_xinfo_func by iso_init() resp. iso_init_with_flag() via
|
||||||
|
* iso_node_xinfo_make_clonable()
|
||||||
|
*/
|
||||||
|
int checksum_cx_xinfo_cloner(void *old_data, void **new_data, int flag)
|
||||||
|
{
|
||||||
|
*new_data = NULL;
|
||||||
|
if (flag)
|
||||||
|
return ISO_XINFO_NO_CLONE;
|
||||||
|
if (old_data == NULL)
|
||||||
|
return 0;
|
||||||
|
/* data is an int disguised as pointer. It does not point to memory. */
|
||||||
|
*new_data = old_data;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Function to identify and manage md5 sums of unspecified providence stored
|
/* Function to identify and manage md5 sums of unspecified providence stored
|
||||||
* directly in this xinfo.
|
* directly in this xinfo.
|
||||||
@ -436,6 +452,24 @@ int checksum_md5_xinfo_func(void *data, int flag)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The iso_node_xinfo_cloner function which gets associated to
|
||||||
|
* checksum_md5_xinfo_func by iso_init() resp. iso_init_with_flag() via
|
||||||
|
* iso_node_xinfo_make_clonable()
|
||||||
|
*/
|
||||||
|
int checksum_md5_xinfo_cloner(void *old_data, void **new_data, int flag)
|
||||||
|
{
|
||||||
|
*new_data = NULL;
|
||||||
|
if (flag)
|
||||||
|
return ISO_XINFO_NO_CLONE;
|
||||||
|
if (old_data == NULL)
|
||||||
|
return 0;
|
||||||
|
*new_data = calloc(1, 16);
|
||||||
|
if (*new_data == NULL)
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
memcpy(*new_data, old_data, 16);
|
||||||
|
return 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------- */
|
/* ----------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#include "messages.h"
|
#include "messages.h"
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "node.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -80,11 +81,69 @@ int abort_threshold = LIBISO_MSGS_SEV_FAILURE;
|
|||||||
struct libiso_msgs *libiso_msgr = NULL;
|
struct libiso_msgs *libiso_msgr = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------- List of xinfo clone functions ----------- */
|
||||||
|
|
||||||
|
struct iso_xinfo_cloner_assoc {
|
||||||
|
iso_node_xinfo_func proc;
|
||||||
|
iso_node_xinfo_cloner cloner;
|
||||||
|
struct iso_xinfo_cloner_assoc *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct iso_xinfo_cloner_assoc *iso_xinfo_cloner_list = NULL;
|
||||||
|
|
||||||
|
/* API */
|
||||||
|
int iso_node_xinfo_make_clonable(iso_node_xinfo_func proc,
|
||||||
|
iso_node_xinfo_cloner cloner, int flag)
|
||||||
|
{
|
||||||
|
struct iso_xinfo_cloner_assoc *assoc;
|
||||||
|
|
||||||
|
assoc = calloc(1, sizeof(struct iso_xinfo_cloner_assoc));
|
||||||
|
if (assoc == NULL)
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
assoc->proc = proc;
|
||||||
|
assoc->cloner = cloner;
|
||||||
|
assoc->next = iso_xinfo_cloner_list;
|
||||||
|
iso_xinfo_cloner_list = assoc;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* API */
|
||||||
|
int iso_node_xinfo_get_cloner(iso_node_xinfo_func proc,
|
||||||
|
iso_node_xinfo_cloner *cloner, int flag)
|
||||||
|
{
|
||||||
|
struct iso_xinfo_cloner_assoc *assoc;
|
||||||
|
|
||||||
|
*cloner = NULL;
|
||||||
|
for (assoc = iso_xinfo_cloner_list; assoc != NULL; assoc = assoc->next) {
|
||||||
|
if (assoc->proc != proc)
|
||||||
|
continue;
|
||||||
|
*cloner = assoc->cloner;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int iso_node_xinfo_dispose_cloners(int flag)
|
||||||
|
{
|
||||||
|
struct iso_xinfo_cloner_assoc *assoc, *next;
|
||||||
|
|
||||||
|
for (assoc = iso_xinfo_cloner_list; assoc != NULL; assoc = next) {
|
||||||
|
next = assoc->next;
|
||||||
|
free((char *) assoc);
|
||||||
|
}
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------- End of xinfo clone functions list ----------- */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@param flag bit0= do not set up locale by LC_* environment variables
|
@param flag bit0= do not set up locale by LC_* environment variables
|
||||||
*/
|
*/
|
||||||
int iso_init_with_flag(int flag)
|
int iso_init_with_flag(int flag)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
#ifdef Libisofs_with_libjtE
|
#ifdef Libisofs_with_libjtE
|
||||||
|
|
||||||
@ -120,7 +179,6 @@ LIBJTE_MISCONFIGURATION_ = 0;
|
|||||||
|
|
||||||
#endif /* Libisofs_with_libjtE */
|
#endif /* Libisofs_with_libjtE */
|
||||||
|
|
||||||
|
|
||||||
if (! (flag & 1)) {
|
if (! (flag & 1)) {
|
||||||
iso_init_locale(0);
|
iso_init_locale(0);
|
||||||
}
|
}
|
||||||
@ -130,10 +188,29 @@ LIBJTE_MISCONFIGURATION_ = 0;
|
|||||||
}
|
}
|
||||||
libiso_msgs_set_severities(libiso_msgr, LIBISO_MSGS_SEV_NEVER,
|
libiso_msgs_set_severities(libiso_msgr, LIBISO_MSGS_SEV_NEVER,
|
||||||
LIBISO_MSGS_SEV_FATAL, "libisofs: ", 0);
|
LIBISO_MSGS_SEV_FATAL, "libisofs: ", 0);
|
||||||
|
|
||||||
|
ret = iso_node_xinfo_make_clonable(aaip_xinfo_func, aaip_xinfo_cloner, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
ret = iso_node_xinfo_make_clonable(checksum_cx_xinfo_func,
|
||||||
|
checksum_cx_xinfo_cloner, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
ret = iso_node_xinfo_make_clonable(checksum_md5_xinfo_func,
|
||||||
|
checksum_md5_xinfo_cloner, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
ret = iso_node_xinfo_make_clonable(zisofs_zf_xinfo_func,
|
||||||
|
zisofs_zf_xinfo_cloner, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
ret = iso_node_xinfo_make_clonable(iso_px_ino_xinfo_func,
|
||||||
|
iso_px_ino_xinfo_cloner, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int iso_init()
|
int iso_init()
|
||||||
{
|
{
|
||||||
return iso_init_with_flag(0);
|
return iso_init_with_flag(0);
|
||||||
@ -142,6 +219,7 @@ int iso_init()
|
|||||||
void iso_finish()
|
void iso_finish()
|
||||||
{
|
{
|
||||||
libiso_msgs_destroy(&libiso_msgr, 0);
|
libiso_msgs_destroy(&libiso_msgr, 0);
|
||||||
|
iso_node_xinfo_dispose_cloners(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int iso_set_abort_severity(char *severity)
|
int iso_set_abort_severity(char *severity)
|
||||||
@ -366,6 +444,8 @@ const char *iso_error_to_msg(int errcode)
|
|||||||
return "File name cannot be written into ECMA-119 untranslated";
|
return "File name cannot be written into ECMA-119 untranslated";
|
||||||
case ISO_STREAM_NO_CLONE:
|
case ISO_STREAM_NO_CLONE:
|
||||||
return "Data file input stream object offers no cloning method";
|
return "Data file input stream object offers no cloning method";
|
||||||
|
case ISO_XINFO_NO_CLONE:
|
||||||
|
return "Extended information class offers no cloning method";
|
||||||
default:
|
default:
|
||||||
return "Unknown error";
|
return "Unknown error";
|
||||||
}
|
}
|
||||||
|
115
libisofs/node.c
115
libisofs/node.c
@ -226,6 +226,77 @@ int iso_node_get_xinfo(IsoNode *node, iso_node_xinfo_func proc, void **data)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* API */
|
||||||
|
int iso_node_get_next_xinfo(IsoNode *node, void **handle,
|
||||||
|
iso_node_xinfo_func *proc, void **data)
|
||||||
|
{
|
||||||
|
IsoExtendedInfo *xinfo;
|
||||||
|
|
||||||
|
if (node == NULL || handle == NULL || proc == NULL || data == NULL)
|
||||||
|
return ISO_NULL_POINTER;
|
||||||
|
*proc = NULL;
|
||||||
|
*data = NULL;
|
||||||
|
xinfo = (IsoExtendedInfo *) *handle;
|
||||||
|
if (xinfo == NULL)
|
||||||
|
xinfo = node->xinfo;
|
||||||
|
else
|
||||||
|
xinfo = xinfo->next;
|
||||||
|
*handle = xinfo;
|
||||||
|
if (xinfo == NULL)
|
||||||
|
return 0;
|
||||||
|
*proc = xinfo->process;
|
||||||
|
*data = xinfo->data;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int iso_node_remove_all_xinfo(IsoNode *node, int flag)
|
||||||
|
{
|
||||||
|
IsoExtendedInfo *pos, *next;
|
||||||
|
|
||||||
|
for (pos = node->xinfo; pos != NULL; pos = next) {
|
||||||
|
next = pos->next;
|
||||||
|
pos->process(pos->data, 1);
|
||||||
|
free((char *) pos);
|
||||||
|
}
|
||||||
|
node->xinfo = NULL;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int iso_node_clone_xinfo(IsoNode *from_node, IsoNode *to_node, int flag)
|
||||||
|
{
|
||||||
|
void *handle = NULL, *data, *new_data;
|
||||||
|
iso_node_xinfo_func proc;
|
||||||
|
iso_node_xinfo_cloner cloner;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
iso_node_remove_all_xinfo(to_node, 0);
|
||||||
|
while (1) {
|
||||||
|
ret = iso_node_get_next_xinfo(from_node, &handle, &proc, &data);
|
||||||
|
if (ret <= 0)
|
||||||
|
break;
|
||||||
|
ret = iso_node_xinfo_get_cloner(proc, &cloner, 0);
|
||||||
|
if (ret == 0)
|
||||||
|
return ISO_XINFO_NO_CLONE;
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
ret = (*cloner)(data, &new_data, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
break;
|
||||||
|
ret = iso_node_add_xinfo(to_node, proc, new_data);
|
||||||
|
if (ret < 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ret < 0) {
|
||||||
|
iso_node_remove_all_xinfo(to_node, 0);
|
||||||
|
return ret;
|
||||||
|
} else {
|
||||||
|
|
||||||
|
/* >>> revert order of xinfo list */;
|
||||||
|
|
||||||
|
}
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the type of an IsoNode.
|
* Get the type of an IsoNode.
|
||||||
*/
|
*/
|
||||||
@ -651,6 +722,9 @@ int iso_node_take(IsoNode *node)
|
|||||||
if (dir == NULL) {
|
if (dir == NULL) {
|
||||||
return ISO_NODE_NOT_ADDED_TO_DIR;
|
return ISO_NODE_NOT_ADDED_TO_DIR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* >>> Do not take root directory ! (dir == node) ? */;
|
||||||
|
|
||||||
pos = iso_dir_find_node(dir, node);
|
pos = iso_dir_find_node(dir, node);
|
||||||
if (pos == NULL) {
|
if (pos == NULL) {
|
||||||
/* should never occur */
|
/* should never occur */
|
||||||
@ -694,6 +768,9 @@ int iso_node_remove_tree(IsoNode *node, IsoDirIter *boss_iter)
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (node->type != LIBISO_DIR) {
|
if (node->type != LIBISO_DIR) {
|
||||||
|
|
||||||
|
/* >>> Do not remove root directory ! (node->parent == node) ? */;
|
||||||
|
|
||||||
ret = iso_dir_get_children((IsoDir *) node, &iter);
|
ret = iso_dir_get_children((IsoDir *) node, &iter);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto ex;
|
goto ex;
|
||||||
@ -705,6 +782,11 @@ int iso_node_remove_tree(IsoNode *node, IsoDirIter *boss_iter)
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
if (node->parent == NULL) {
|
||||||
|
/* node is not grafted into a boss directory */
|
||||||
|
iso_node_unref(node);
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (boss_iter != NULL)
|
if (boss_iter != NULL)
|
||||||
ret = iso_dir_iter_remove(boss_iter);
|
ret = iso_dir_iter_remove(boss_iter);
|
||||||
@ -2183,6 +2265,23 @@ int zisofs_zf_xinfo_func(void *data, int flag)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The iso_node_xinfo_cloner function which gets associated to
|
||||||
|
* zisofs_zf_xinfo_func by iso_init() resp. iso_init_with_flag() via
|
||||||
|
* iso_node_xinfo_make_clonable()
|
||||||
|
*/
|
||||||
|
int zisofs_zf_xinfo_cloner(void *old_data, void **new_data, int flag)
|
||||||
|
{
|
||||||
|
*new_data = NULL;
|
||||||
|
if (flag)
|
||||||
|
return ISO_XINFO_NO_CLONE;
|
||||||
|
if (old_data == NULL)
|
||||||
|
return 0;
|
||||||
|
*new_data = calloc(1, sizeof(struct zisofs_zf_info));
|
||||||
|
if (*new_data == NULL)
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
memcpy(*new_data, old_data, sizeof(struct zisofs_zf_info));
|
||||||
|
return (int) sizeof(struct zisofs_zf_info);
|
||||||
|
}
|
||||||
|
|
||||||
/* Checks whether a file effectively bears a zisofs file header and eventually
|
/* Checks whether a file effectively bears a zisofs file header and eventually
|
||||||
* marks this by a struct zisofs_zf_info as xinfo of the file node.
|
* marks this by a struct zisofs_zf_info as xinfo of the file node.
|
||||||
@ -2304,6 +2403,21 @@ int iso_px_ino_xinfo_func(void *data, int flag)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The iso_node_xinfo_cloner function which gets associated to
|
||||||
|
* iso_px_ino_xinfo_func by iso_init() resp. iso_init_with_flag() via
|
||||||
|
* iso_node_xinfo_make_clonable()
|
||||||
|
*/
|
||||||
|
int iso_px_ino_xinfo_cloner(void *old_data, void **new_data, int flag)
|
||||||
|
{
|
||||||
|
*new_data = NULL;
|
||||||
|
if (flag)
|
||||||
|
return ISO_XINFO_NO_CLONE;
|
||||||
|
*new_data = calloc(1, sizeof(ino_t));
|
||||||
|
if (*new_data == NULL)
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
memcpy(*new_data, old_data, sizeof(ino_t));
|
||||||
|
return (int) sizeof(ino_t);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @param flag
|
* @param flag
|
||||||
@ -2394,7 +2508,6 @@ int iso_node_set_ino_xinfo(IsoNode *node, ino_t ino, int flag)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int iso_node_set_ino(IsoNode *node, ino_t ino, int flag)
|
int iso_node_set_ino(IsoNode *node, ino_t ino, int flag)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -482,4 +482,35 @@ int iso_root_get_isofsca(IsoNode *node, uint32_t *start_lba, uint32_t *end_lba,
|
|||||||
int flag);
|
int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy the xinfo list from one node to the another.
|
||||||
|
*/
|
||||||
|
int iso_node_clone_xinfo(IsoNode *from_node, IsoNode *to_node, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The iso_node_xinfo_func instance which governs the storing of the inode
|
||||||
|
* number from Rock Ridge field PX.
|
||||||
|
*/
|
||||||
|
int iso_px_ino_xinfo_func(void *data, int flag);
|
||||||
|
|
||||||
|
/* The iso_node_xinfo_cloner function which gets associated to
|
||||||
|
* iso_px_ino_xinfo_func by iso_init() resp. iso_init_with_flag() via
|
||||||
|
* iso_node_xinfo_make_clonable()
|
||||||
|
*/
|
||||||
|
int iso_px_ino_xinfo_cloner(void *old_data, void **new_data, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/* Function to identify and manage ZF parameters of zisofs compression.
|
||||||
|
* data is supposed to be a pointer to struct zisofs_zf_info
|
||||||
|
*/
|
||||||
|
int zisofs_zf_xinfo_func(void *data, int flag);
|
||||||
|
|
||||||
|
/* The iso_node_xinfo_cloner function which gets associated to
|
||||||
|
* zisofs_zf_xinfo_func by iso_init() resp. iso_init_with_flag() via
|
||||||
|
* iso_node_xinfo_make_clonable()
|
||||||
|
*/
|
||||||
|
int zisofs_zf_xinfo_cloner(void *old_data, void **new_data, int flag);
|
||||||
|
|
||||||
|
|
||||||
#endif /*LIBISO_NODE_H_*/
|
#endif /*LIBISO_NODE_H_*/
|
||||||
|
@ -905,7 +905,7 @@ int add_zf_field(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* API */
|
||||||
int aaip_xinfo_func(void *data, int flag)
|
int aaip_xinfo_func(void *data, int flag)
|
||||||
{
|
{
|
||||||
if (flag & 1) {
|
if (flag & 1) {
|
||||||
@ -914,6 +914,23 @@ int aaip_xinfo_func(void *data, int flag)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* API */
|
||||||
|
int aaip_xinfo_cloner(void *old_data, void **new_data, int flag)
|
||||||
|
{
|
||||||
|
size_t aa_size;
|
||||||
|
|
||||||
|
*new_data = NULL;
|
||||||
|
if (old_data == NULL)
|
||||||
|
return 0;
|
||||||
|
aa_size = aaip_count_bytes((unsigned char *) old_data, 0);
|
||||||
|
if (aa_size <= 0)
|
||||||
|
return ISO_AAIP_BAD_AASTRING;
|
||||||
|
*new_data = calloc(1, aa_size);
|
||||||
|
if (*new_data == NULL)
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
memcpy(*new_data, old_data, aa_size);
|
||||||
|
return (int) aa_size;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compute SUA length and eventual Continuation Area length of field NM and
|
* Compute SUA length and eventual Continuation Area length of field NM and
|
||||||
|
@ -157,20 +157,18 @@ int fsrc_update_size(IsoStream *stream)
|
|||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
IsoStream *fsrc_get_input_stream(IsoStream *stream, int flag)
|
IsoStream *fsrc_get_input_stream(IsoStream *stream, int flag)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
int fsrc_cmp_ino(IsoStream *s1, IsoStream *s2)
|
int fsrc_cmp_ino(IsoStream *s1, IsoStream *s2)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* <<< provisory */
|
|
||||||
ret = iso_stream_cmp_ino(s1, s2, 1);
|
ret = iso_stream_cmp_ino(s1, s2, 1);
|
||||||
|
|
||||||
/* >>> find out whether both streams point to the same image file */;
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,6 +179,13 @@ int fsrc_clone_stream(IsoStream *old_stream, IsoStream **new_stream,
|
|||||||
IsoStream *stream;
|
IsoStream *stream;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (flag)
|
||||||
|
return ISO_STREAM_NO_CLONE; /* unknown option required */
|
||||||
|
|
||||||
|
data = (FSrcStreamData*) old_stream->data;
|
||||||
|
if (data->src->class->version < 2)
|
||||||
|
return ISO_STREAM_NO_CLONE; /* No clone_src() method available */
|
||||||
|
|
||||||
*new_stream = NULL;
|
*new_stream = NULL;
|
||||||
stream = calloc(1, sizeof(IsoStream));
|
stream = calloc(1, sizeof(IsoStream));
|
||||||
if (stream == NULL)
|
if (stream == NULL)
|
||||||
@ -191,12 +196,11 @@ int fsrc_clone_stream(IsoStream *old_stream, IsoStream **new_stream,
|
|||||||
return ISO_OUT_OF_MEM;
|
return ISO_OUT_OF_MEM;
|
||||||
}
|
}
|
||||||
*new_stream = stream;
|
*new_stream = stream;
|
||||||
data = (FSrcStreamData*) old_stream->data;
|
|
||||||
stream->class = old_stream->class;
|
stream->class = old_stream->class;
|
||||||
stream->refcount = 1;
|
stream->refcount = 1;
|
||||||
stream->data = new_data;
|
stream->data = new_data;
|
||||||
|
|
||||||
ret = iso_ifs_source_clone(data->src, &(new_data->src), 0);
|
ret = data->src->class->clone_src(data->src, &(new_data->src), 0);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
free((char *) stream);
|
free((char *) stream);
|
||||||
free((char *) new_data);
|
free((char *) new_data);
|
||||||
@ -210,7 +214,7 @@ int fsrc_clone_stream(IsoStream *old_stream, IsoStream **new_stream,
|
|||||||
}
|
}
|
||||||
|
|
||||||
IsoStreamIface fsrc_stream_class = {
|
IsoStreamIface fsrc_stream_class = {
|
||||||
4, /* .clone_stream() is defined for this stream */
|
4, /* version */
|
||||||
"fsrc",
|
"fsrc",
|
||||||
fsrc_open,
|
fsrc_open,
|
||||||
fsrc_close,
|
fsrc_close,
|
||||||
@ -430,11 +434,76 @@ void cut_out_free(IsoStream *stream)
|
|||||||
free(data);
|
free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int cut_out_update_size(IsoStream *stream)
|
||||||
|
{
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
IsoStream* cut_out_get_input_stream(IsoStream *stream, int flag)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int cut_out_cmp_ino(IsoStream *s1, IsoStream *s2)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = iso_stream_cmp_ino(s1, s2, 1);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int cut_out_clone_stream(IsoStream *old_stream, IsoStream **new_stream,
|
||||||
|
int flag)
|
||||||
|
{
|
||||||
|
struct cut_out_stream *data, *new_data;
|
||||||
|
IsoStream *stream;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (flag)
|
||||||
|
return ISO_STREAM_NO_CLONE; /* unknown option required */
|
||||||
|
|
||||||
|
data = (struct cut_out_stream *) old_stream->data;
|
||||||
|
if (data->src->class->version < 2)
|
||||||
|
return ISO_STREAM_NO_CLONE; /* No clone_src() method available */
|
||||||
|
|
||||||
|
*new_stream = NULL;
|
||||||
|
stream = calloc(1, sizeof(IsoStream));
|
||||||
|
if (stream == NULL)
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
stream->refcount = 1;
|
||||||
|
stream->class = old_stream->class;
|
||||||
|
new_data = calloc(1, sizeof(struct cut_out_stream));
|
||||||
|
if (new_data == NULL) {
|
||||||
|
free((char *) stream);
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
}
|
||||||
|
ret = data->src->class->clone_src(data->src, &(new_data->src), 0);
|
||||||
|
if (ret < 0) {
|
||||||
|
free((char *) stream);
|
||||||
|
free((char *) new_data);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
new_data->dev_id = (dev_t) 0;
|
||||||
|
new_data->ino_id = cut_out_serial_id++;
|
||||||
|
new_data->offset = data->offset;
|
||||||
|
new_data->size = data->size;
|
||||||
|
new_data->pos = 0;
|
||||||
|
|
||||||
|
stream->data = new_data;
|
||||||
|
*new_stream = stream;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TODO update cut out streams to deal with update_size(). Seems hard.
|
* TODO update cut out streams to deal with update_size(). Seems hard.
|
||||||
*/
|
*/
|
||||||
IsoStreamIface cut_out_stream_class = {
|
IsoStreamIface cut_out_stream_class = {
|
||||||
0,
|
4, /* version */
|
||||||
"cout",
|
"cout",
|
||||||
cut_out_open,
|
cut_out_open,
|
||||||
cut_out_close,
|
cut_out_close,
|
||||||
@ -442,7 +511,12 @@ IsoStreamIface cut_out_stream_class = {
|
|||||||
cut_out_read,
|
cut_out_read,
|
||||||
cut_out_is_repeatable,
|
cut_out_is_repeatable,
|
||||||
cut_out_get_id,
|
cut_out_get_id,
|
||||||
cut_out_free
|
cut_out_free,
|
||||||
|
cut_out_update_size,
|
||||||
|
cut_out_get_input_stream,
|
||||||
|
cut_out_cmp_ino,
|
||||||
|
cut_out_clone_stream
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int iso_cut_out_stream_new(IsoFileSource *src, off_t offset, off_t size,
|
int iso_cut_out_stream_new(IsoFileSource *src, off_t offset, off_t size,
|
||||||
@ -604,12 +678,77 @@ void mem_free(IsoStream *stream)
|
|||||||
{
|
{
|
||||||
MemStreamData *data;
|
MemStreamData *data;
|
||||||
data = (MemStreamData*)stream->data;
|
data = (MemStreamData*)stream->data;
|
||||||
free(data->buf);
|
if (data->buf != NULL)
|
||||||
|
free(data->buf);
|
||||||
free(data);
|
free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int mem_update_size(IsoStream *stream)
|
||||||
|
{
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
IsoStream* mem_get_input_stream(IsoStream *stream, int flag)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int mem_cmp_ino(IsoStream *s1, IsoStream *s2)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = iso_stream_cmp_ino(s1, s2, 1);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int mem_clone_stream(IsoStream *old_stream, IsoStream **new_stream,
|
||||||
|
int flag)
|
||||||
|
{
|
||||||
|
MemStreamData *data, *new_data;
|
||||||
|
IsoStream *stream;
|
||||||
|
uint8_t *new_buf = NULL;
|
||||||
|
|
||||||
|
if (flag)
|
||||||
|
return ISO_STREAM_NO_CLONE; /* unknown option required */
|
||||||
|
|
||||||
|
*new_stream = NULL;
|
||||||
|
stream = calloc(1, sizeof(IsoStream));
|
||||||
|
if (stream == NULL)
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
stream->refcount = 1;
|
||||||
|
stream->class = old_stream->class;
|
||||||
|
new_data = calloc(1, sizeof(MemStreamData));
|
||||||
|
if (new_data == NULL) {
|
||||||
|
free((char *) stream);
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
}
|
||||||
|
data = (MemStreamData *) old_stream->data;
|
||||||
|
if (data->size > 0) {
|
||||||
|
new_buf = calloc(1, data->size);
|
||||||
|
if (new_buf == NULL) {
|
||||||
|
free((char *) stream);
|
||||||
|
free((char *) new_data);
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
}
|
||||||
|
memcpy(new_buf, data->buf, data->size);
|
||||||
|
}
|
||||||
|
new_data->buf = new_buf;
|
||||||
|
new_data->offset = -1;
|
||||||
|
new_data->ino_id = mem_serial_id++;
|
||||||
|
new_data->size = data->size;
|
||||||
|
|
||||||
|
stream->data = new_data;
|
||||||
|
*new_stream = stream;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
IsoStreamIface mem_stream_class = {
|
IsoStreamIface mem_stream_class = {
|
||||||
0,
|
4, /* version */
|
||||||
"mem ",
|
"mem ",
|
||||||
mem_open,
|
mem_open,
|
||||||
mem_close,
|
mem_close,
|
||||||
@ -617,7 +756,12 @@ IsoStreamIface mem_stream_class = {
|
|||||||
mem_read,
|
mem_read,
|
||||||
mem_is_repeatable,
|
mem_is_repeatable,
|
||||||
mem_get_id,
|
mem_get_id,
|
||||||
mem_free
|
mem_free,
|
||||||
|
mem_update_size,
|
||||||
|
mem_get_input_stream,
|
||||||
|
mem_cmp_ino,
|
||||||
|
mem_clone_stream
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -997,6 +997,24 @@ char *iso_tree_get_node_path(IsoNode *node)
|
|||||||
|
|
||||||
/* ------------------------- tree cloning ------------------------------ */
|
/* ------------------------- tree cloning ------------------------------ */
|
||||||
|
|
||||||
|
static
|
||||||
|
int iso_tree_copy_node_attr(IsoNode *old_node, IsoNode *new_node, int flag)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
new_node->mode = old_node->mode;
|
||||||
|
new_node->uid = old_node->uid;
|
||||||
|
new_node->gid = old_node->gid;
|
||||||
|
new_node->atime = old_node->atime;
|
||||||
|
new_node->mtime = old_node->mtime;
|
||||||
|
new_node->ctime = old_node->ctime;
|
||||||
|
new_node->hidden = old_node->hidden;
|
||||||
|
ret = iso_node_clone_xinfo(old_node, new_node, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
int iso_tree_clone_dir(IsoDir *old_dir,
|
int iso_tree_clone_dir(IsoDir *old_dir,
|
||||||
IsoDir *new_parent, char *new_name, IsoNode **new_node,
|
IsoDir *new_parent, char *new_name, IsoNode **new_node,
|
||||||
@ -1012,7 +1030,10 @@ int iso_tree_clone_dir(IsoDir *old_dir,
|
|||||||
ret = iso_tree_add_new_dir(new_parent, new_name, &new_dir);
|
ret = iso_tree_add_new_dir(new_parent, new_name, &new_dir);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
*new_node = (IsoNode *) new_dir;
|
/* Avoid early grafting of directory to allow cloning of old_dir to a
|
||||||
|
subordinate of old_dir.
|
||||||
|
*/
|
||||||
|
iso_node_take((IsoNode *) new_dir);
|
||||||
|
|
||||||
ret = iso_dir_get_children(old_dir, &iter);
|
ret = iso_dir_get_children(old_dir, &iter);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
@ -1026,6 +1047,13 @@ int iso_tree_clone_dir(IsoDir *old_dir,
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Now really graft in the new tree */
|
||||||
|
ret = iso_dir_add_node(new_parent, (IsoNode *) new_dir, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
goto ex;
|
||||||
|
|
||||||
|
*new_node = (IsoNode *) new_dir;
|
||||||
ret = ISO_SUCCESS;
|
ret = ISO_SUCCESS;
|
||||||
ex:;
|
ex:;
|
||||||
if (iter != NULL)
|
if (iter != NULL)
|
||||||
@ -1055,6 +1083,7 @@ int iso_tree_clone_file(IsoFile *old_file,
|
|||||||
ret = iso_tree_add_new_file(new_parent, new_name, new_stream, &new_file);
|
ret = iso_tree_add_new_file(new_parent, new_name, new_stream, &new_file);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto ex;
|
goto ex;
|
||||||
|
new_stream = NULL; /* now owned by new_file */
|
||||||
new_file->sort_weight = old_file->sort_weight;
|
new_file->sort_weight = old_file->sort_weight;
|
||||||
*new_node = (IsoNode *) new_file;
|
*new_node = (IsoNode *) new_file;
|
||||||
ret = ISO_SUCCESS;
|
ret = ISO_SUCCESS;
|
||||||
@ -1064,6 +1093,47 @@ ex:;
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int iso_tree_clone_symlink(IsoSymlink *node,
|
||||||
|
IsoDir *new_parent, char *new_name, IsoNode **new_node,
|
||||||
|
int flag)
|
||||||
|
{
|
||||||
|
IsoSymlink *new_sym;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
*new_node = NULL;
|
||||||
|
|
||||||
|
ret = iso_tree_add_new_symlink(new_parent, new_name, node->dest, &new_sym);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
new_sym->fs_id = node->fs_id;
|
||||||
|
new_sym->st_dev = node->st_dev;
|
||||||
|
new_sym->st_ino = node->st_ino;
|
||||||
|
*new_node = (IsoNode *) new_sym;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int iso_tree_clone_special(IsoSpecial *node,
|
||||||
|
IsoDir *new_parent, char *new_name, IsoNode **new_node,
|
||||||
|
int flag)
|
||||||
|
{
|
||||||
|
IsoSpecial *new_spec;
|
||||||
|
IsoNode *iso_node;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
iso_node = (IsoNode *) node;
|
||||||
|
ret = iso_tree_add_new_special(new_parent, new_name, iso_node->mode,
|
||||||
|
node->dev, &new_spec);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
new_spec->fs_id = node->fs_id;
|
||||||
|
new_spec->st_dev = node->st_dev;
|
||||||
|
new_spec->st_ino = node->st_ino;
|
||||||
|
*new_node = (IsoNode *) new_spec;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/* API */
|
/* API */
|
||||||
int iso_tree_clone(IsoNode *node,
|
int iso_tree_clone(IsoNode *node,
|
||||||
IsoDir *new_parent, char *new_name, IsoNode **new_node,
|
IsoDir *new_parent, char *new_name, IsoNode **new_node,
|
||||||
@ -1074,7 +1144,6 @@ int iso_tree_clone(IsoNode *node,
|
|||||||
if (iso_dir_get_node(new_parent, new_name, NULL) == 1)
|
if (iso_dir_get_node(new_parent, new_name, NULL) == 1)
|
||||||
return ISO_NODE_NAME_NOT_UNIQUE;
|
return ISO_NODE_NAME_NOT_UNIQUE;
|
||||||
|
|
||||||
/* >>> clone particular node types */;
|
|
||||||
if (node->type == LIBISO_DIR) {
|
if (node->type == LIBISO_DIR) {
|
||||||
ret = iso_tree_clone_dir((IsoDir *) node, new_parent, new_name,
|
ret = iso_tree_clone_dir((IsoDir *) node, new_parent, new_name,
|
||||||
new_node, 0);
|
new_node, 0);
|
||||||
@ -1082,12 +1151,17 @@ int iso_tree_clone(IsoNode *node,
|
|||||||
ret = iso_tree_clone_file((IsoFile *) node, new_parent, new_name,
|
ret = iso_tree_clone_file((IsoFile *) node, new_parent, new_name,
|
||||||
new_node, 0);
|
new_node, 0);
|
||||||
} else if (node->type == LIBISO_SYMLINK) {
|
} else if (node->type == LIBISO_SYMLINK) {
|
||||||
/* >>> */;
|
ret = iso_tree_clone_symlink((IsoSymlink *) node, new_parent, new_name,
|
||||||
|
new_node, 0);
|
||||||
} else if (node->type == LIBISO_SPECIAL) {
|
} else if (node->type == LIBISO_SPECIAL) {
|
||||||
/* >>> */;
|
ret = iso_tree_clone_special((IsoSpecial *) node, new_parent, new_name,
|
||||||
|
new_node, 0);
|
||||||
} else if (node->type == LIBISO_BOOT) {
|
} else if (node->type == LIBISO_BOOT) {
|
||||||
ret = ISO_SUCCESS; /* API says they are silently ignored */
|
ret = ISO_SUCCESS; /* API says they are silently ignored */
|
||||||
}
|
}
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
ret = iso_tree_copy_node_attr(node, *new_node, 0);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -512,12 +512,26 @@ int iso_util_tag_magic(int tag_type, char **tag_magic, int *len, int flag);
|
|||||||
*/
|
*/
|
||||||
int checksum_cx_xinfo_func(void *data, int flag);
|
int checksum_cx_xinfo_func(void *data, int flag);
|
||||||
|
|
||||||
|
/* The iso_node_xinfo_cloner function which gets associated to
|
||||||
|
* checksum_cx_xinfo_func by iso_init() resp. iso_init_with_flag() via
|
||||||
|
* iso_node_xinfo_make_clonable()
|
||||||
|
*/
|
||||||
|
int checksum_cx_xinfo_cloner(void *old_data, void **new_data, int flag);
|
||||||
|
|
||||||
|
|
||||||
/* Function to identify and manage md5 sums of unspecified providence stored
|
/* Function to identify and manage md5 sums of unspecified providence stored
|
||||||
* directly in this xinfo. This is supposed to override any other recorded
|
* directly in this xinfo. This is supposed to override any other recorded
|
||||||
* MD5 of the node unless data get copied and checksummed during that copying.
|
* MD5 of the node unless data get copied and checksummed during that copying.
|
||||||
*/
|
*/
|
||||||
int checksum_md5_xinfo_func(void *data, int flag);
|
int checksum_md5_xinfo_func(void *data, int flag);
|
||||||
|
|
||||||
|
/* The iso_node_xinfo_cloner function which gets associated to
|
||||||
|
* checksum_md5_xinfo_func by iso_init() resp. iso_init_with_flag() via
|
||||||
|
* iso_node_xinfo_make_clonable()
|
||||||
|
*/
|
||||||
|
int checksum_md5_xinfo_cloner(void *old_data, void **new_data, int flag);
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user