Switch to Vreixo development branch 378
This commit is contained in:
parent
9f6b7e4e3f
commit
7cbbf97669
@ -16,6 +16,7 @@ libisofs_libisofs_la_SOURCES = \
|
|||||||
libisofs/node.c \
|
libisofs/node.c \
|
||||||
libisofs/tree.h \
|
libisofs/tree.h \
|
||||||
libisofs/tree.c \
|
libisofs/tree.c \
|
||||||
|
libisofs/find.c \
|
||||||
libisofs/image.h \
|
libisofs/image.h \
|
||||||
libisofs/image.c \
|
libisofs/image.c \
|
||||||
libisofs/fsource.h \
|
libisofs/fsource.h \
|
||||||
@ -28,6 +29,9 @@ libisofs_libisofs_la_SOURCES = \
|
|||||||
libisofs/libiso_msgs.c \
|
libisofs/libiso_msgs.c \
|
||||||
libisofs/stream.h \
|
libisofs/stream.h \
|
||||||
libisofs/stream.c \
|
libisofs/stream.c \
|
||||||
|
libisofs/filter.h \
|
||||||
|
libisofs/filter.c \
|
||||||
|
libisofs/filters/xor_encrypt.c \
|
||||||
libisofs/util.h \
|
libisofs/util.h \
|
||||||
libisofs/util.c \
|
libisofs/util.c \
|
||||||
libisofs/util_rbtree.c \
|
libisofs/util_rbtree.c \
|
||||||
@ -62,6 +66,7 @@ noinst_PROGRAMS = \
|
|||||||
demo/cat \
|
demo/cat \
|
||||||
demo/catbuffer \
|
demo/catbuffer \
|
||||||
demo/tree \
|
demo/tree \
|
||||||
|
demo/find \
|
||||||
demo/ecma119tree \
|
demo/ecma119tree \
|
||||||
demo/iso \
|
demo/iso \
|
||||||
demo/isoread \
|
demo/isoread \
|
||||||
@ -86,6 +91,10 @@ demo_tree_CPPFLAGS = -Ilibisofs
|
|||||||
demo_tree_LDADD = $(libisofs_libisofs_la_OBJECTS) $(THREAD_LIBS)
|
demo_tree_LDADD = $(libisofs_libisofs_la_OBJECTS) $(THREAD_LIBS)
|
||||||
demo_tree_SOURCES = demo/tree.c
|
demo_tree_SOURCES = demo/tree.c
|
||||||
|
|
||||||
|
demo_find_CPPFLAGS = -Ilibisofs
|
||||||
|
demo_find_LDADD = $(libisofs_libisofs_la_OBJECTS) $(THREAD_LIBS)
|
||||||
|
demo_find_SOURCES = demo/find.c
|
||||||
|
|
||||||
demo_ecma119tree_CPPFLAGS = -Ilibisofs
|
demo_ecma119tree_CPPFLAGS = -Ilibisofs
|
||||||
demo_ecma119tree_LDADD = $(libisofs_libisofs_la_OBJECTS) $(THREAD_LIBS)
|
demo_ecma119tree_LDADD = $(libisofs_libisofs_la_OBJECTS) $(THREAD_LIBS)
|
||||||
demo_ecma119tree_SOURCES = demo/ecma119_tree.c
|
demo_ecma119tree_SOURCES = demo/ecma119_tree.c
|
||||||
|
@ -57,7 +57,7 @@ int ds_open(IsoDataSource *src)
|
|||||||
|
|
||||||
data = (struct file_data_src*) src->data;
|
data = (struct file_data_src*) src->data;
|
||||||
if (data->fd != -1) {
|
if (data->fd != -1) {
|
||||||
return ISO_FILE_ALREADY_OPENNED;
|
return ISO_FILE_ALREADY_OPENED;
|
||||||
}
|
}
|
||||||
|
|
||||||
fd = open(data->path, O_RDONLY);
|
fd = open(data->path, O_RDONLY);
|
||||||
@ -81,7 +81,7 @@ int ds_close(IsoDataSource *src)
|
|||||||
|
|
||||||
data = (struct file_data_src*) src->data;
|
data = (struct file_data_src*) src->data;
|
||||||
if (data->fd == -1) {
|
if (data->fd == -1) {
|
||||||
return ISO_FILE_NOT_OPENNED;
|
return ISO_FILE_NOT_OPENED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* close can fail if fd is not valid, but that should never happen */
|
/* close can fail if fd is not valid, but that should never happen */
|
||||||
@ -102,7 +102,7 @@ static int ds_read_block(IsoDataSource *src, uint32_t lba, uint8_t *buffer)
|
|||||||
|
|
||||||
data = (struct file_data_src*) src->data;
|
data = (struct file_data_src*) src->data;
|
||||||
if (data->fd == -1) {
|
if (data->fd == -1) {
|
||||||
return ISO_FILE_NOT_OPENNED;
|
return ISO_FILE_NOT_OPENED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* goes to requested block */
|
/* goes to requested block */
|
||||||
|
@ -538,7 +538,7 @@ int catalog_open(IsoStream *stream)
|
|||||||
data = stream->data;
|
data = stream->data;
|
||||||
|
|
||||||
if (data->offset != -1) {
|
if (data->offset != -1) {
|
||||||
return ISO_FILE_ALREADY_OPENNED;
|
return ISO_FILE_ALREADY_OPENED;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(data->buffer, 0, BLOCK_SIZE);
|
memset(data->buffer, 0, BLOCK_SIZE);
|
||||||
@ -563,7 +563,7 @@ int catalog_close(IsoStream *stream)
|
|||||||
data = stream->data;
|
data = stream->data;
|
||||||
|
|
||||||
if (data->offset == -1) {
|
if (data->offset == -1) {
|
||||||
return ISO_FILE_NOT_OPENNED;
|
return ISO_FILE_NOT_OPENED;
|
||||||
}
|
}
|
||||||
data->offset = -1;
|
data->offset = -1;
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
@ -589,7 +589,7 @@ int catalog_read(IsoStream *stream, void *buf, size_t count)
|
|||||||
data = stream->data;
|
data = stream->data;
|
||||||
|
|
||||||
if (data->offset == -1) {
|
if (data->offset == -1) {
|
||||||
return ISO_FILE_NOT_OPENNED;
|
return ISO_FILE_NOT_OPENED;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = MIN(count, BLOCK_SIZE - data->offset);
|
len = MIN(count, BLOCK_SIZE - data->offset);
|
||||||
@ -617,12 +617,6 @@ void catalog_get_id(IsoStream *stream, unsigned int *fs_id, dev_t *dev_id,
|
|||||||
*ino_id = 0;
|
*ino_id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
|
||||||
char *catalog_get_name(IsoStream *stream)
|
|
||||||
{
|
|
||||||
return strdup("El-Torito Boot Catalog");
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
static
|
||||||
void catalog_free(IsoStream *stream)
|
void catalog_free(IsoStream *stream)
|
||||||
{
|
{
|
||||||
@ -630,13 +624,14 @@ void catalog_free(IsoStream *stream)
|
|||||||
}
|
}
|
||||||
|
|
||||||
IsoStreamIface catalog_stream_class = {
|
IsoStreamIface catalog_stream_class = {
|
||||||
|
0,
|
||||||
|
"boot",
|
||||||
catalog_open,
|
catalog_open,
|
||||||
catalog_close,
|
catalog_close,
|
||||||
catalog_get_size,
|
catalog_get_size,
|
||||||
catalog_read,
|
catalog_read,
|
||||||
catalog_is_repeatable,
|
catalog_is_repeatable,
|
||||||
catalog_get_id,
|
catalog_get_id,
|
||||||
catalog_get_name,
|
|
||||||
catalog_free
|
catalog_free
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
int iso_file_src_cmp(const void *n1, const void *n2)
|
int iso_file_src_cmp(const void *n1, const void *n2)
|
||||||
{
|
{
|
||||||
@ -243,7 +244,7 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
|
|||||||
Ecma119Image *t;
|
Ecma119Image *t;
|
||||||
IsoFileSrc *file;
|
IsoFileSrc *file;
|
||||||
IsoFileSrc **filelist;
|
IsoFileSrc **filelist;
|
||||||
char *name;
|
char name[PATH_MAX];
|
||||||
char buffer[BLOCK_SIZE];
|
char buffer[BLOCK_SIZE];
|
||||||
|
|
||||||
if (writer == NULL) {
|
if (writer == NULL) {
|
||||||
@ -266,16 +267,15 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
|
|||||||
uint32_t nblocks = DIV_UP(iso_file_src_get_size(file), BLOCK_SIZE);
|
uint32_t nblocks = DIV_UP(iso_file_src_get_size(file), BLOCK_SIZE);
|
||||||
|
|
||||||
res = filesrc_open(file);
|
res = filesrc_open(file);
|
||||||
|
iso_stream_get_file_name(file->stream, name);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
/*
|
/*
|
||||||
* UPS, very ugly error, the best we can do is just to write
|
* UPS, very ugly error, the best we can do is just to write
|
||||||
* 0's to image
|
* 0's to image
|
||||||
*/
|
*/
|
||||||
name = iso_stream_get_name(file->stream);
|
|
||||||
iso_report_errfile(name, ISO_FILE_CANT_WRITE, 0, 0);
|
iso_report_errfile(name, ISO_FILE_CANT_WRITE, 0, 0);
|
||||||
res = iso_msg_submit(t->image->id, ISO_FILE_CANT_WRITE, res,
|
res = iso_msg_submit(t->image->id, ISO_FILE_CANT_WRITE, res,
|
||||||
"File \"%s\" can't be opened. Filling with 0s.", name);
|
"File \"%s\" can't be opened. Filling with 0s.", name);
|
||||||
free(name);
|
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
return res; /* aborted due to error severity */
|
return res; /* aborted due to error severity */
|
||||||
}
|
}
|
||||||
@ -289,12 +289,10 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
|
|||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
} else if (res > 1) {
|
} else if (res > 1) {
|
||||||
name = iso_stream_get_name(file->stream);
|
|
||||||
iso_report_errfile(name, ISO_FILE_CANT_WRITE, 0, 0);
|
iso_report_errfile(name, ISO_FILE_CANT_WRITE, 0, 0);
|
||||||
res = iso_msg_submit(t->image->id, ISO_FILE_CANT_WRITE, 0,
|
res = iso_msg_submit(t->image->id, ISO_FILE_CANT_WRITE, 0,
|
||||||
"Size of file \"%s\" has changed. It will be %s", name,
|
"Size of file \"%s\" has changed. It will be %s", name,
|
||||||
(res == 2 ? "truncated" : "padded with 0's"));
|
(res == 2 ? "truncated" : "padded with 0's"));
|
||||||
free(name);
|
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
filesrc_close(file);
|
filesrc_close(file);
|
||||||
return res; /* aborted due to error severity */
|
return res; /* aborted due to error severity */
|
||||||
@ -302,9 +300,7 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
|
|||||||
}
|
}
|
||||||
#ifdef LIBISOFS_VERBOSE_DEBUG
|
#ifdef LIBISOFS_VERBOSE_DEBUG
|
||||||
else {
|
else {
|
||||||
name = iso_stream_get_name(file->stream);
|
|
||||||
iso_msg_debug(t->image->id, "Writing file %s", name);
|
iso_msg_debug(t->image->id, "Writing file %s", name);
|
||||||
free(name);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -328,7 +324,6 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
|
|||||||
|
|
||||||
if (b < nblocks) {
|
if (b < nblocks) {
|
||||||
/* premature end of file, due to error or eof */
|
/* premature end of file, due to error or eof */
|
||||||
char *name = iso_stream_get_name(file->stream);
|
|
||||||
iso_report_errfile(name, ISO_FILE_CANT_WRITE, 0, 0);
|
iso_report_errfile(name, ISO_FILE_CANT_WRITE, 0, 0);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
/* error */
|
/* error */
|
||||||
@ -339,7 +334,6 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
|
|||||||
res = iso_msg_submit(t->image->id, ISO_FILE_CANT_WRITE, 0,
|
res = iso_msg_submit(t->image->id, ISO_FILE_CANT_WRITE, 0,
|
||||||
"Premature end of file %s.", name);
|
"Premature end of file %s.", name);
|
||||||
}
|
}
|
||||||
free(name);
|
|
||||||
|
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
return res; /* aborted due error severity */
|
return res; /* aborted due error severity */
|
||||||
|
@ -474,7 +474,7 @@ int ifs_open(IsoFileSource *src)
|
|||||||
data = (ImageFileSourceData*)src->data;
|
data = (ImageFileSourceData*)src->data;
|
||||||
|
|
||||||
if (data->opened) {
|
if (data->opened) {
|
||||||
return ISO_FILE_ALREADY_OPENNED;
|
return ISO_FILE_ALREADY_OPENED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (S_ISDIR(data->info.st_mode)) {
|
if (S_ISDIR(data->info.st_mode)) {
|
||||||
@ -530,7 +530,7 @@ int ifs_close(IsoFileSource *src)
|
|||||||
data = (ImageFileSourceData*)src->data;
|
data = (ImageFileSourceData*)src->data;
|
||||||
|
|
||||||
if (!data->opened) {
|
if (!data->opened) {
|
||||||
return ISO_FILE_NOT_OPENNED;
|
return ISO_FILE_NOT_OPENED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data->opened == 2) {
|
if (data->opened == 2) {
|
||||||
@ -569,7 +569,7 @@ int ifs_close(IsoFileSource *src)
|
|||||||
* Error codes:
|
* Error codes:
|
||||||
* ISO_FILE_ERROR
|
* ISO_FILE_ERROR
|
||||||
* ISO_NULL_POINTER
|
* ISO_NULL_POINTER
|
||||||
* ISO_FILE_NOT_OPENNED
|
* ISO_FILE_NOT_OPENED
|
||||||
* ISO_FILE_IS_DIR
|
* ISO_FILE_IS_DIR
|
||||||
* ISO_OUT_OF_MEM
|
* ISO_OUT_OF_MEM
|
||||||
* ISO_INTERRUPTED
|
* ISO_INTERRUPTED
|
||||||
@ -590,7 +590,7 @@ int ifs_read(IsoFileSource *src, void *buf, size_t count)
|
|||||||
data = (ImageFileSourceData*)src->data;
|
data = (ImageFileSourceData*)src->data;
|
||||||
|
|
||||||
if (!data->opened) {
|
if (!data->opened) {
|
||||||
return ISO_FILE_NOT_OPENNED;
|
return ISO_FILE_NOT_OPENED;
|
||||||
} else if (data->opened != 1) {
|
} else if (data->opened != 1) {
|
||||||
return ISO_FILE_IS_DIR;
|
return ISO_FILE_IS_DIR;
|
||||||
}
|
}
|
||||||
@ -644,7 +644,7 @@ int ifs_readdir(IsoFileSource *src, IsoFileSource **child)
|
|||||||
data = (ImageFileSourceData*)src->data;
|
data = (ImageFileSourceData*)src->data;
|
||||||
|
|
||||||
if (!data->opened) {
|
if (!data->opened) {
|
||||||
return ISO_FILE_NOT_OPENNED;
|
return ISO_FILE_NOT_OPENED;
|
||||||
} else if (data->opened != 2) {
|
} else if (data->opened != 2) {
|
||||||
return ISO_FILE_IS_NOT_DIR;
|
return ISO_FILE_IS_NOT_DIR;
|
||||||
}
|
}
|
||||||
|
@ -190,7 +190,7 @@ int lfs_open(IsoFileSource *src)
|
|||||||
|
|
||||||
data = src->data;
|
data = src->data;
|
||||||
if (data->openned) {
|
if (data->openned) {
|
||||||
return ISO_FILE_ALREADY_OPENNED;
|
return ISO_FILE_ALREADY_OPENED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* is a file or a dir ? */
|
/* is a file or a dir ? */
|
||||||
@ -251,7 +251,7 @@ int lfs_close(IsoFileSource *src)
|
|||||||
ret = closedir(data->info.dir) == 0 ? ISO_SUCCESS : ISO_FILE_ERROR;
|
ret = closedir(data->info.dir) == 0 ? ISO_SUCCESS : ISO_FILE_ERROR;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ret = ISO_FILE_NOT_OPENNED;
|
ret = ISO_FILE_NOT_OPENED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (ret == ISO_SUCCESS) {
|
if (ret == ISO_SUCCESS) {
|
||||||
@ -300,7 +300,7 @@ int lfs_read(IsoFileSource *src, void *buf, size_t count)
|
|||||||
case 2: /* directory */
|
case 2: /* directory */
|
||||||
return ISO_FILE_IS_DIR;
|
return ISO_FILE_IS_DIR;
|
||||||
default:
|
default:
|
||||||
return ISO_FILE_NOT_OPENNED;
|
return ISO_FILE_NOT_OPENED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -341,7 +341,7 @@ int lfs_readdir(IsoFileSource *src, IsoFileSource **child)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return ISO_FILE_NOT_OPENNED;
|
return ISO_FILE_NOT_OPENED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#define ISO_IMAGE_FS_ID 2
|
#define ISO_IMAGE_FS_ID 2
|
||||||
#define ISO_ELTORITO_FS_ID 3
|
#define ISO_ELTORITO_FS_ID 3
|
||||||
#define ISO_MEM_FS_ID 4
|
#define ISO_MEM_FS_ID 4
|
||||||
|
#define ISO_FILTER_FS_ID 5
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new IsoFilesystem to deal with local filesystem.
|
* Create a new IsoFilesystem to deal with local filesystem.
|
||||||
|
@ -519,7 +519,7 @@ struct IsoFileSource_Iface
|
|||||||
* Opens the source.
|
* Opens the source.
|
||||||
* @return 1 on success, < 0 on error
|
* @return 1 on success, < 0 on error
|
||||||
* Error codes:
|
* Error codes:
|
||||||
* ISO_FILE_ALREADY_OPENNED
|
* ISO_FILE_ALREADY_OPENED
|
||||||
* ISO_FILE_ACCESS_DENIED
|
* ISO_FILE_ACCESS_DENIED
|
||||||
* ISO_FILE_BAD_PATH
|
* ISO_FILE_BAD_PATH
|
||||||
* ISO_FILE_DOESNT_EXIST
|
* ISO_FILE_DOESNT_EXIST
|
||||||
@ -535,7 +535,7 @@ struct IsoFileSource_Iface
|
|||||||
* Error codes:
|
* Error codes:
|
||||||
* ISO_FILE_ERROR
|
* ISO_FILE_ERROR
|
||||||
* ISO_NULL_POINTER
|
* ISO_NULL_POINTER
|
||||||
* ISO_FILE_NOT_OPENNED
|
* ISO_FILE_NOT_OPENED
|
||||||
*/
|
*/
|
||||||
int (*close)(IsoFileSource *src);
|
int (*close)(IsoFileSource *src);
|
||||||
|
|
||||||
@ -552,7 +552,7 @@ struct IsoFileSource_Iface
|
|||||||
* Error codes:
|
* Error codes:
|
||||||
* ISO_FILE_ERROR
|
* ISO_FILE_ERROR
|
||||||
* ISO_NULL_POINTER
|
* ISO_NULL_POINTER
|
||||||
* ISO_FILE_NOT_OPENNED
|
* ISO_FILE_NOT_OPENED
|
||||||
* ISO_WRONG_ARG_VALUE -> if count == 0
|
* ISO_WRONG_ARG_VALUE -> if count == 0
|
||||||
* ISO_FILE_IS_DIR
|
* ISO_FILE_IS_DIR
|
||||||
* ISO_OUT_OF_MEM
|
* ISO_OUT_OF_MEM
|
||||||
@ -578,7 +578,7 @@ struct IsoFileSource_Iface
|
|||||||
* Error codes:
|
* Error codes:
|
||||||
* ISO_FILE_ERROR
|
* ISO_FILE_ERROR
|
||||||
* ISO_NULL_POINTER
|
* ISO_NULL_POINTER
|
||||||
* ISO_FILE_NOT_OPENNED
|
* ISO_FILE_NOT_OPENED
|
||||||
* ISO_FILE_IS_NOT_DIR
|
* ISO_FILE_IS_NOT_DIR
|
||||||
* ISO_OUT_OF_MEM
|
* ISO_OUT_OF_MEM
|
||||||
*/
|
*/
|
||||||
@ -675,6 +675,18 @@ extern ino_t serial_id;
|
|||||||
*/
|
*/
|
||||||
struct IsoStream_Iface
|
struct IsoStream_Iface
|
||||||
{
|
{
|
||||||
|
/* reserved for future usage, set to 0 */
|
||||||
|
int version;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type of Stream.
|
||||||
|
* "fsrc" -> Read from file source
|
||||||
|
* "mem " -> Read from memory
|
||||||
|
* "boot" -> Boot catalog
|
||||||
|
* "user" -> User supplied stream
|
||||||
|
*/
|
||||||
|
char type[4];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens the stream.
|
* Opens the stream.
|
||||||
*
|
*
|
||||||
@ -727,14 +739,6 @@ struct IsoStream_Iface
|
|||||||
void (*get_id)(IsoStream *stream, unsigned int *fs_id, dev_t *dev_id,
|
void (*get_id)(IsoStream *stream, unsigned int *fs_id, dev_t *dev_id,
|
||||||
ino_t *ino_id);
|
ino_t *ino_id);
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a name that identifies the Stream contents. It is used only for
|
|
||||||
* informational or debug purposes, so you can return anything you
|
|
||||||
* consider suitable for identification of the source, such as the path
|
|
||||||
* of the file on disc.
|
|
||||||
*/
|
|
||||||
char *(*get_name)(IsoStream *stream);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Free implementation specific data. Should never be called by user.
|
* Free implementation specific data. Should never be called by user.
|
||||||
* Use iso_stream_unref() instead.
|
* Use iso_stream_unref() instead.
|
||||||
@ -2058,7 +2062,7 @@ IsoDir *iso_node_get_parent(IsoNode *node);
|
|||||||
* you should free the iterator with iso_dir_iter_free.
|
* you should free the iterator with iso_dir_iter_free.
|
||||||
* You musn't delete a child of the same dir, using iso_node_take() or
|
* You musn't delete a child of the same dir, using iso_node_take() or
|
||||||
* iso_node_remove(), while you're using the iterator. You can use
|
* iso_node_remove(), while you're using the iterator. You can use
|
||||||
* iso_node_take_iter() or iso_node_remove_iter() instead.
|
* iso_dir_iter_take() or iso_dir_iter_remove() instead.
|
||||||
*
|
*
|
||||||
* You can use the iterator in the way like this
|
* You can use the iterator in the way like this
|
||||||
*
|
*
|
||||||
@ -2160,6 +2164,191 @@ int iso_dir_iter_take(IsoDirIter *iter);
|
|||||||
*/
|
*/
|
||||||
int iso_dir_iter_remove(IsoDirIter *iter);
|
int iso_dir_iter_remove(IsoDirIter *iter);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 0.6.4
|
||||||
|
*/
|
||||||
|
typedef struct iso_find_condition IsoFindCondition;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new condition that checks if the node name matches the given
|
||||||
|
* wildcard.
|
||||||
|
*
|
||||||
|
* @param wildcard
|
||||||
|
* @result
|
||||||
|
* The created IsoFindCondition, NULL on error.
|
||||||
|
*
|
||||||
|
* @since 0.6.4
|
||||||
|
*/
|
||||||
|
IsoFindCondition *iso_new_find_conditions_name(const char *wildcard);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new condition that checks the node mode against a mode mask. It
|
||||||
|
* can be used to check both file type and permissions.
|
||||||
|
*
|
||||||
|
* For example:
|
||||||
|
*
|
||||||
|
* iso_new_find_conditions_mode(S_IFREG) : search for regular files
|
||||||
|
* iso_new_find_conditions_mode(S_IFCHR | S_IWUSR) : search for character
|
||||||
|
* devices where owner has write permissions.
|
||||||
|
*
|
||||||
|
* @param mask
|
||||||
|
* Mode mask to AND against node mode.
|
||||||
|
* @result
|
||||||
|
* The created IsoFindCondition, NULL on error.
|
||||||
|
*
|
||||||
|
* @since 0.6.4
|
||||||
|
*/
|
||||||
|
IsoFindCondition *iso_new_find_conditions_mode(mode_t mask);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new condition that checks the node gid.
|
||||||
|
*
|
||||||
|
* @param gid
|
||||||
|
* Desired Group Id.
|
||||||
|
* @result
|
||||||
|
* The created IsoFindCondition, NULL on error.
|
||||||
|
*
|
||||||
|
* @since 0.6.4
|
||||||
|
*/
|
||||||
|
IsoFindCondition *iso_new_find_conditions_gid(gid_t gid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new condition that checks the node uid.
|
||||||
|
*
|
||||||
|
* @param uid
|
||||||
|
* Desired User Id.
|
||||||
|
* @result
|
||||||
|
* The created IsoFindCondition, NULL on error.
|
||||||
|
*
|
||||||
|
* @since 0.6.4
|
||||||
|
*/
|
||||||
|
IsoFindCondition *iso_new_find_conditions_uid(uid_t uid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Possible comparison between IsoNode and given conditions.
|
||||||
|
*
|
||||||
|
* @since 0.6.4
|
||||||
|
*/
|
||||||
|
enum iso_find_comparisons {
|
||||||
|
ISO_FIND_COND_GREATER,
|
||||||
|
ISO_FIND_COND_GREATER_OR_EQUAL,
|
||||||
|
ISO_FIND_COND_EQUAL,
|
||||||
|
ISO_FIND_COND_LESS,
|
||||||
|
ISO_FIND_COND_LESS_OR_EQUAL
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new condition that checks the time of last access.
|
||||||
|
*
|
||||||
|
* @param time
|
||||||
|
* Time to compare against IsoNode atime.
|
||||||
|
* @param comparison
|
||||||
|
* Comparison to be done between IsoNode atime and submitted time.
|
||||||
|
* Note that ISO_FIND_COND_GREATER, for example, is true if the node
|
||||||
|
* time is greater than the submitted time.
|
||||||
|
* @result
|
||||||
|
* The created IsoFindCondition, NULL on error.
|
||||||
|
*
|
||||||
|
* @since 0.6.4
|
||||||
|
*/
|
||||||
|
IsoFindCondition *iso_new_find_conditions_atime(time_t time,
|
||||||
|
enum iso_find_comparisons comparison);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new condition that checks the time of last modification.
|
||||||
|
*
|
||||||
|
* @param time
|
||||||
|
* Time to compare against IsoNode mtime.
|
||||||
|
* @param comparison
|
||||||
|
* Comparison to be done between IsoNode mtime and submitted time.
|
||||||
|
* Note that ISO_FIND_COND_GREATER, for example, is true if the node
|
||||||
|
* time is greater than the submitted time.
|
||||||
|
* @result
|
||||||
|
* The created IsoFindCondition, NULL on error.
|
||||||
|
*
|
||||||
|
* @since 0.6.4
|
||||||
|
*/
|
||||||
|
IsoFindCondition *iso_new_find_conditions_mtime(time_t time,
|
||||||
|
enum iso_find_comparisons comparison);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new condition that checks the time of last status change.
|
||||||
|
*
|
||||||
|
* @param time
|
||||||
|
* Time to compare against IsoNode ctime.
|
||||||
|
* @param comparison
|
||||||
|
* Comparison to be done between IsoNode ctime and submitted time.
|
||||||
|
* Note that ISO_FIND_COND_GREATER, for example, is true if the node
|
||||||
|
* time is greater than the submitted time.
|
||||||
|
* @result
|
||||||
|
* The created IsoFindCondition, NULL on error.
|
||||||
|
*
|
||||||
|
* @since 0.6.4
|
||||||
|
*/
|
||||||
|
IsoFindCondition *iso_new_find_conditions_ctime(time_t time,
|
||||||
|
enum iso_find_comparisons comparison);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new condition that check if the two given conditions are
|
||||||
|
* valid.
|
||||||
|
*
|
||||||
|
* @param a
|
||||||
|
* @param b
|
||||||
|
* IsoFindCondition to compare
|
||||||
|
* @result
|
||||||
|
* The created IsoFindCondition, NULL on error.
|
||||||
|
*
|
||||||
|
* @since 0.6.4
|
||||||
|
*/
|
||||||
|
IsoFindCondition *iso_new_find_conditions_and(IsoFindCondition *a,
|
||||||
|
IsoFindCondition *b);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new condition that check if at least one the two given conditions
|
||||||
|
* is valid.
|
||||||
|
*
|
||||||
|
* @param a
|
||||||
|
* @param b
|
||||||
|
* IsoFindCondition to compare
|
||||||
|
* @result
|
||||||
|
* The created IsoFindCondition, NULL on error.
|
||||||
|
*
|
||||||
|
* @since 0.6.4
|
||||||
|
*/
|
||||||
|
IsoFindCondition *iso_new_find_conditions_or(IsoFindCondition *a,
|
||||||
|
IsoFindCondition *b);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new condition that check if the given conditions is false.
|
||||||
|
*
|
||||||
|
* @param negate
|
||||||
|
* @result
|
||||||
|
* The created IsoFindCondition, NULL on error.
|
||||||
|
*
|
||||||
|
* @since 0.6.4
|
||||||
|
*/
|
||||||
|
IsoFindCondition *iso_new_find_conditions_not(IsoFindCondition *negate);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find all directory children that match the given condition.
|
||||||
|
*
|
||||||
|
* @param dir
|
||||||
|
* Directory where we will search children.
|
||||||
|
* @param cond
|
||||||
|
* Condition that the children must match in order to be returned.
|
||||||
|
* It will be free together with the iterator. Remember to delete it
|
||||||
|
* if this function return error.
|
||||||
|
* @param iter
|
||||||
|
* Iterator that returns only the children that match condition.
|
||||||
|
* @return
|
||||||
|
* 1 on success, < 0 on error
|
||||||
|
*
|
||||||
|
* @since 0.6.4
|
||||||
|
*/
|
||||||
|
int iso_dir_find_children(IsoDir* dir, IsoFindCondition *cond,
|
||||||
|
IsoDirIter **iter);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the destination of a node.
|
* Get the destination of a node.
|
||||||
* The returned string belongs to the node and should not be modified nor
|
* The returned string belongs to the node and should not be modified nor
|
||||||
@ -2226,6 +2415,35 @@ off_t iso_file_get_size(IsoFile *file);
|
|||||||
*/
|
*/
|
||||||
IsoStream *iso_file_get_stream(IsoFile *file);
|
IsoStream *iso_file_get_stream(IsoFile *file);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the block lba of a file node, if it was imported from an old image.
|
||||||
|
*
|
||||||
|
* @param file
|
||||||
|
* The file
|
||||||
|
* @param lba
|
||||||
|
* Will be filled with the kba
|
||||||
|
* @param flag
|
||||||
|
* Reserved for future usage, submit 0
|
||||||
|
* @return
|
||||||
|
* 1 if lba is valid (file comes from old image), 0 if file was newly
|
||||||
|
* added, i.e. it does not come from an old image, < 0 error
|
||||||
|
*
|
||||||
|
* @since 0.6.4
|
||||||
|
*/
|
||||||
|
int iso_file_get_old_image_lba(IsoFile *file, uint32_t *lba, int flag);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Like iso_file_get_old_image_lba(), but take an IsoNode.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* 1 if lba is valid (file comes from old image), 0 if file was newly
|
||||||
|
* added, i.e. it does not come from an old image, 2 node type has no
|
||||||
|
* LBA (no regular file), < 0 error
|
||||||
|
*
|
||||||
|
* @since 0.6.4
|
||||||
|
*/
|
||||||
|
int iso_node_get_old_image_lba(IsoNode *node, uint32_t *lba, int flag);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a new directory to the iso tree. Permissions, owner and hidden atts
|
* Add a new directory to the iso tree. Permissions, owner and hidden atts
|
||||||
* are taken from parent, you can modify them later.
|
* are taken from parent, you can modify them later.
|
||||||
@ -2889,7 +3107,7 @@ int iso_file_source_stat(IsoFileSource *src, struct stat *info);
|
|||||||
* Opens the source.
|
* Opens the source.
|
||||||
* @return 1 on success, < 0 on error
|
* @return 1 on success, < 0 on error
|
||||||
* Error codes:
|
* Error codes:
|
||||||
* ISO_FILE_ALREADY_OPENNED
|
* ISO_FILE_ALREADY_OPENED
|
||||||
* ISO_FILE_ACCESS_DENIED
|
* ISO_FILE_ACCESS_DENIED
|
||||||
* ISO_FILE_BAD_PATH
|
* ISO_FILE_BAD_PATH
|
||||||
* ISO_FILE_DOESNT_EXIST
|
* ISO_FILE_DOESNT_EXIST
|
||||||
@ -2907,7 +3125,7 @@ int iso_file_source_open(IsoFileSource *src);
|
|||||||
* Error codes:
|
* Error codes:
|
||||||
* ISO_FILE_ERROR
|
* ISO_FILE_ERROR
|
||||||
* ISO_NULL_POINTER
|
* ISO_NULL_POINTER
|
||||||
* ISO_FILE_NOT_OPENNED
|
* ISO_FILE_NOT_OPENED
|
||||||
*
|
*
|
||||||
* @since 0.6.2
|
* @since 0.6.2
|
||||||
*/
|
*/
|
||||||
@ -2933,7 +3151,7 @@ int iso_file_source_close(IsoFileSource *src);
|
|||||||
* Error codes:
|
* Error codes:
|
||||||
* ISO_FILE_ERROR
|
* ISO_FILE_ERROR
|
||||||
* ISO_NULL_POINTER
|
* ISO_NULL_POINTER
|
||||||
* ISO_FILE_NOT_OPENNED
|
* ISO_FILE_NOT_OPENED
|
||||||
* ISO_WRONG_ARG_VALUE -> if count == 0
|
* ISO_WRONG_ARG_VALUE -> if count == 0
|
||||||
* ISO_FILE_IS_DIR
|
* ISO_FILE_IS_DIR
|
||||||
* ISO_OUT_OF_MEM
|
* ISO_OUT_OF_MEM
|
||||||
@ -2961,7 +3179,7 @@ int iso_file_source_read(IsoFileSource *src, void *buf, size_t count);
|
|||||||
* Error codes:
|
* Error codes:
|
||||||
* ISO_FILE_ERROR
|
* ISO_FILE_ERROR
|
||||||
* ISO_NULL_POINTER
|
* ISO_NULL_POINTER
|
||||||
* ISO_FILE_NOT_OPENNED
|
* ISO_FILE_NOT_OPENED
|
||||||
* ISO_FILE_IS_NOT_DIR
|
* ISO_FILE_IS_NOT_DIR
|
||||||
* ISO_OUT_OF_MEM
|
* ISO_OUT_OF_MEM
|
||||||
*
|
*
|
||||||
@ -3203,17 +3421,6 @@ int iso_stream_is_repeatable(IsoStream *stream);
|
|||||||
void iso_stream_get_id(IsoStream *stream, unsigned int *fs_id, dev_t *dev_id,
|
void iso_stream_get_id(IsoStream *stream, unsigned int *fs_id, dev_t *dev_id,
|
||||||
ino_t *ino_id);
|
ino_t *ino_id);
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a name that identifies the Stream contents. It is used only for
|
|
||||||
* informational or debug purposes, so you can return anything you
|
|
||||||
* consider suitable for identification of the source, such as the path
|
|
||||||
* of the file on disc.
|
|
||||||
* Returned string should be freed when no more needed.
|
|
||||||
*
|
|
||||||
* @since 0.6.4
|
|
||||||
*/
|
|
||||||
char *iso_stream_get_name(IsoStream *stream);
|
|
||||||
|
|
||||||
/************ Error codes and return values for libisofs ********************/
|
/************ Error codes and return values for libisofs ********************/
|
||||||
|
|
||||||
/** successfully execution */
|
/** successfully execution */
|
||||||
@ -3287,6 +3494,9 @@ char *iso_stream_get_name(IsoStream *stream);
|
|||||||
#define ISO_FILE_ERROR 0xE830FF80
|
#define ISO_FILE_ERROR 0xE830FF80
|
||||||
|
|
||||||
/** Trying to open an already openned file (FAILURE,HIGH, -129) */
|
/** Trying to open an already openned file (FAILURE,HIGH, -129) */
|
||||||
|
#define ISO_FILE_ALREADY_OPENED 0xE830FF7F
|
||||||
|
|
||||||
|
/* @deprecated use ISO_FILE_ALREADY_OPENED instead */
|
||||||
#define ISO_FILE_ALREADY_OPENNED 0xE830FF7F
|
#define ISO_FILE_ALREADY_OPENNED 0xE830FF7F
|
||||||
|
|
||||||
/** Access to file is not allowed (FAILURE,HIGH, -130) */
|
/** Access to file is not allowed (FAILURE,HIGH, -130) */
|
||||||
@ -3299,7 +3509,10 @@ char *iso_stream_get_name(IsoStream *stream);
|
|||||||
#define ISO_FILE_DOESNT_EXIST 0xE830FF7C
|
#define ISO_FILE_DOESNT_EXIST 0xE830FF7C
|
||||||
|
|
||||||
/** Trying to read or close a file not openned (FAILURE,HIGH, -133) */
|
/** Trying to read or close a file not openned (FAILURE,HIGH, -133) */
|
||||||
#define ISO_FILE_NOT_OPENNED 0xE830FF7B
|
#define ISO_FILE_NOT_OPENED 0xE830FF7B
|
||||||
|
|
||||||
|
/* @deprecated use ISO_FILE_NOT_OPENED instead */
|
||||||
|
#define ISO_FILE_NOT_OPENNED ISO_FILE_NOT_OPENED
|
||||||
|
|
||||||
/** Directory used where no dir is expected (FAILURE,HIGH, -134) */
|
/** Directory used where no dir is expected (FAILURE,HIGH, -134) */
|
||||||
#define ISO_FILE_IS_DIR 0xE830FF7A
|
#define ISO_FILE_IS_DIR 0xE830FF7A
|
||||||
|
@ -136,16 +136,16 @@ const char *iso_error_to_msg(int errcode)
|
|||||||
return "Trying to use an invalid file as boot image";
|
return "Trying to use an invalid file as boot image";
|
||||||
case ISO_FILE_ERROR:
|
case ISO_FILE_ERROR:
|
||||||
return "Error on file operation";
|
return "Error on file operation";
|
||||||
case ISO_FILE_ALREADY_OPENNED:
|
case ISO_FILE_ALREADY_OPENED:
|
||||||
return "Trying to open an already openned file";
|
return "Trying to open an already opened file";
|
||||||
case ISO_FILE_ACCESS_DENIED:
|
case ISO_FILE_ACCESS_DENIED:
|
||||||
return "Access to file is not allowed";
|
return "Access to file is not allowed";
|
||||||
case ISO_FILE_BAD_PATH:
|
case ISO_FILE_BAD_PATH:
|
||||||
return "Incorrect path to file";
|
return "Incorrect path to file";
|
||||||
case ISO_FILE_DOESNT_EXIST:
|
case ISO_FILE_DOESNT_EXIST:
|
||||||
return "The file does not exist in the filesystem";
|
return "The file does not exist in the filesystem";
|
||||||
case ISO_FILE_NOT_OPENNED:
|
case ISO_FILE_NOT_OPENED:
|
||||||
return "Trying to read or close a file not openned";
|
return "Trying to read or close a file not opened";
|
||||||
case ISO_FILE_IS_DIR:
|
case ISO_FILE_IS_DIR:
|
||||||
return "Directory used where no dir is expected";
|
return "Directory used where no dir is expected";
|
||||||
case ISO_FILE_READ_ERROR:
|
case ISO_FILE_READ_ERROR:
|
||||||
|
305
libisofs/node.c
305
libisofs/node.c
@ -15,6 +15,17 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
|
struct dir_iter_data
|
||||||
|
{
|
||||||
|
/* points to the last visited child, to NULL before start */
|
||||||
|
IsoNode *pos;
|
||||||
|
|
||||||
|
/* Some control flags.
|
||||||
|
* bit 0 -> 1 if next called, 0 reseted at start or on deletion
|
||||||
|
*/
|
||||||
|
int flag;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Increments the reference counting of the given node.
|
* Increments the reference counting of the given node.
|
||||||
*/
|
*/
|
||||||
@ -354,42 +365,53 @@ int iso_dir_get_children_count(IsoDir *dir)
|
|||||||
return dir->nchildren;
|
return dir->nchildren;
|
||||||
}
|
}
|
||||||
|
|
||||||
int iso_dir_get_children(const IsoDir *dir, IsoDirIter **iter)
|
static
|
||||||
|
int iter_next(IsoDirIter *iter, IsoNode **node)
|
||||||
{
|
{
|
||||||
IsoDirIter *it;
|
struct dir_iter_data *data;
|
||||||
|
|
||||||
if (dir == NULL || iter == NULL) {
|
|
||||||
return ISO_NULL_POINTER;
|
|
||||||
}
|
|
||||||
it = malloc(sizeof(IsoDirIter));
|
|
||||||
if (it == NULL) {
|
|
||||||
return ISO_OUT_OF_MEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
it->dir = dir;
|
|
||||||
it->pos = dir->children;
|
|
||||||
|
|
||||||
*iter = it;
|
|
||||||
return ISO_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
int iso_dir_iter_next(IsoDirIter *iter, IsoNode **node)
|
|
||||||
{
|
|
||||||
IsoNode *n;
|
|
||||||
if (iter == NULL || node == NULL) {
|
if (iter == NULL || node == NULL) {
|
||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
}
|
}
|
||||||
n = iter->pos;
|
|
||||||
if (n == NULL) {
|
data = iter->data;
|
||||||
|
|
||||||
|
/* clear next flag */
|
||||||
|
data->flag &= ~0x01;
|
||||||
|
|
||||||
|
if (data->pos == NULL) {
|
||||||
|
/* we are at the beginning */
|
||||||
|
data->pos = iter->dir->children;
|
||||||
|
if (data->pos == NULL) {
|
||||||
|
/* empty dir */
|
||||||
*node = NULL;
|
*node = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (n->parent != iter->dir) {
|
} else {
|
||||||
|
if (data->pos->parent != iter->dir) {
|
||||||
/* this can happen if the node has been moved to another dir */
|
/* this can happen if the node has been moved to another dir */
|
||||||
|
/* TODO specific error */
|
||||||
return ISO_ERROR;
|
return ISO_ERROR;
|
||||||
}
|
}
|
||||||
*node = n;
|
if (data->pos->next == NULL) {
|
||||||
iter->pos = n->next;
|
/* no more children */
|
||||||
|
*node = NULL;
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
/* free reference to current position */
|
||||||
|
iso_node_unref(data->pos); /* it is never last ref!! */
|
||||||
|
|
||||||
|
/* advance a position */
|
||||||
|
data->pos = data->pos->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ok, take a ref to the current position, to prevent internal errors
|
||||||
|
* if deleted somewhere */
|
||||||
|
iso_node_ref(data->pos);
|
||||||
|
data->flag |= 0x01; /* set next flag */
|
||||||
|
|
||||||
|
/* return pointed node */
|
||||||
|
*node = data->pos;
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -401,17 +423,30 @@ int iso_dir_iter_next(IsoDirIter *iter, IsoNode **node)
|
|||||||
* Possible errors:
|
* Possible errors:
|
||||||
* ISO_NULL_POINTER, if iter is NULL
|
* ISO_NULL_POINTER, if iter is NULL
|
||||||
*/
|
*/
|
||||||
int iso_dir_iter_has_next(IsoDirIter *iter)
|
static
|
||||||
|
int iter_has_next(IsoDirIter *iter)
|
||||||
{
|
{
|
||||||
|
struct dir_iter_data *data;
|
||||||
if (iter == NULL) {
|
if (iter == NULL) {
|
||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
}
|
}
|
||||||
return iter->pos == NULL ? 0 : 1;
|
data = iter->data;
|
||||||
|
if (data->pos == NULL) {
|
||||||
|
return iter->dir->children == NULL ? 0 : 1;
|
||||||
|
} else {
|
||||||
|
return data->pos->next == NULL ? 0 : 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void iso_dir_iter_free(IsoDirIter *iter)
|
static
|
||||||
|
void iter_free(IsoDirIter *iter)
|
||||||
{
|
{
|
||||||
free(iter);
|
struct dir_iter_data *data;
|
||||||
|
data = iter->data;
|
||||||
|
if (data->pos != NULL) {
|
||||||
|
iso_node_unref(data->pos);
|
||||||
|
}
|
||||||
|
free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static IsoNode** iso_dir_find_node(IsoDir *dir, IsoNode *node)
|
static IsoNode** iso_dir_find_node(IsoDir *dir, IsoNode *node)
|
||||||
@ -448,7 +483,7 @@ int iso_node_take(IsoNode *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 */
|
||||||
return ISO_ERROR;
|
return ISO_ASSERT_FAILURE;
|
||||||
}
|
}
|
||||||
*pos = node->next;
|
*pos = node->next;
|
||||||
node->parent = NULL;
|
node->parent = NULL;
|
||||||
@ -492,43 +527,161 @@ IsoDir *iso_node_get_parent(IsoNode *node)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* TODO #00005 optimize iso_dir_iter_take */
|
/* TODO #00005 optimize iso_dir_iter_take */
|
||||||
int iso_dir_iter_take(IsoDirIter *iter)
|
static
|
||||||
|
int iter_take(IsoDirIter *iter)
|
||||||
{
|
{
|
||||||
IsoNode *pos;
|
struct dir_iter_data *data;
|
||||||
|
IsoNode *pos, *pre;
|
||||||
if (iter == NULL) {
|
if (iter == NULL) {
|
||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
pos = iter->dir->children;
|
data = iter->data;
|
||||||
if (iter->pos == pos) {
|
|
||||||
return ISO_ERROR;
|
if (!(data->flag & 0x01)) {
|
||||||
|
return ISO_ERROR; /* next not called or end of dir */
|
||||||
}
|
}
|
||||||
while (pos != NULL && pos->next == iter->pos) {
|
|
||||||
|
if (data->pos == NULL) {
|
||||||
|
return ISO_ASSERT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* clear next flag */
|
||||||
|
data->flag &= ~0x01;
|
||||||
|
|
||||||
|
pos = iter->dir->children;
|
||||||
|
pre = NULL;
|
||||||
|
while (pos != NULL && pos != data->pos) {
|
||||||
|
pre = pos;
|
||||||
pos = pos->next;
|
pos = pos->next;
|
||||||
}
|
}
|
||||||
if (pos == NULL) {
|
if (pos == NULL) {
|
||||||
|
return ISO_ERROR; /* node not in dir */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pos != data->pos) {
|
||||||
|
return ISO_ASSERT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* dispose iterator reference */
|
||||||
|
iso_node_unref(data->pos);
|
||||||
|
|
||||||
|
if (pre == NULL) {
|
||||||
|
/* node is a first position */
|
||||||
|
iter->dir->children = pos->next;
|
||||||
|
data->pos = NULL;
|
||||||
|
} else {
|
||||||
|
pre->next = pos->next;
|
||||||
|
data->pos = pre;
|
||||||
|
iso_node_ref(pre); /* take iter ref */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* take pos */
|
||||||
|
pos->parent = NULL;
|
||||||
|
pos->next = NULL;
|
||||||
|
iter->dir->nchildren--;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int iter_remove(IsoDirIter *iter)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
IsoNode *pos;
|
||||||
|
struct dir_iter_data *data;
|
||||||
|
|
||||||
|
if (iter == NULL) {
|
||||||
|
return ISO_NULL_POINTER;
|
||||||
|
}
|
||||||
|
data = iter->data;
|
||||||
|
pos = data->pos;
|
||||||
|
|
||||||
|
ret = iter_take(iter);
|
||||||
|
if (ret == ISO_SUCCESS) {
|
||||||
|
/* remove node */
|
||||||
|
iso_node_unref(pos);
|
||||||
|
}
|
||||||
|
if (data->pos == pos) {
|
||||||
return ISO_ERROR;
|
return ISO_ERROR;
|
||||||
}
|
}
|
||||||
return iso_node_take(pos);
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
struct iso_dir_iter_iface iter_class = {
|
||||||
|
iter_next,
|
||||||
|
iter_has_next,
|
||||||
|
iter_free,
|
||||||
|
iter_take,
|
||||||
|
iter_remove
|
||||||
|
};
|
||||||
|
|
||||||
|
int iso_dir_get_children(const IsoDir *dir, IsoDirIter **iter)
|
||||||
|
{
|
||||||
|
IsoDirIter *it;
|
||||||
|
struct dir_iter_data *data;
|
||||||
|
|
||||||
|
if (dir == NULL || iter == NULL) {
|
||||||
|
return ISO_NULL_POINTER;
|
||||||
|
}
|
||||||
|
it = malloc(sizeof(IsoDirIter));
|
||||||
|
if (it == NULL) {
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
}
|
||||||
|
data = malloc(sizeof(struct dir_iter_data));
|
||||||
|
if (data == NULL) {
|
||||||
|
free(it);
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
it->class = &iter_class;
|
||||||
|
it->dir = (IsoDir*)dir;
|
||||||
|
data->pos = NULL;
|
||||||
|
data->flag = 0x00;
|
||||||
|
it->data = data;
|
||||||
|
|
||||||
|
*iter = it;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int iso_dir_iter_next(IsoDirIter *iter, IsoNode **node)
|
||||||
|
{
|
||||||
|
if (iter == NULL || node == NULL) {
|
||||||
|
return ISO_NULL_POINTER;
|
||||||
|
}
|
||||||
|
return iter->class->next(iter, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
int iso_dir_iter_has_next(IsoDirIter *iter)
|
||||||
|
{
|
||||||
|
if (iter == NULL) {
|
||||||
|
return ISO_NULL_POINTER;
|
||||||
|
}
|
||||||
|
return iter->class->has_next(iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
void iso_dir_iter_free(IsoDirIter *iter)
|
||||||
|
{
|
||||||
|
if (iter != NULL) {
|
||||||
|
iter->class->free(iter);
|
||||||
|
free(iter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int iso_dir_iter_take(IsoDirIter *iter)
|
||||||
|
{
|
||||||
|
if (iter == NULL) {
|
||||||
|
return ISO_NULL_POINTER;
|
||||||
|
}
|
||||||
|
return iter->class->take(iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
int iso_dir_iter_remove(IsoDirIter *iter)
|
int iso_dir_iter_remove(IsoDirIter *iter)
|
||||||
{
|
{
|
||||||
IsoNode *pos;
|
|
||||||
if (iter == NULL) {
|
if (iter == NULL) {
|
||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
}
|
}
|
||||||
pos = iter->dir->children;
|
return iter->class->remove(iter);
|
||||||
if (iter->pos == pos) {
|
|
||||||
return ISO_ERROR;
|
|
||||||
}
|
|
||||||
while (pos != NULL && pos->next == iter->pos) {
|
|
||||||
pos = pos->next;
|
|
||||||
}
|
|
||||||
if (pos == NULL) {
|
|
||||||
return ISO_ERROR;
|
|
||||||
}
|
|
||||||
return iso_node_remove(pos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -618,6 +771,58 @@ IsoStream *iso_file_get_stream(IsoFile *file)
|
|||||||
return file->stream;
|
return file->stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the block lba of a file node, if it was imported from an old image.
|
||||||
|
*
|
||||||
|
* @param file
|
||||||
|
* The file
|
||||||
|
* @param lba
|
||||||
|
* Will be filled with the kba
|
||||||
|
* @param flag
|
||||||
|
* Reserved for future usage, submit 0
|
||||||
|
* @return
|
||||||
|
* 1 if lba is valid (file comes from old image), 0 if file was newly
|
||||||
|
* added, i.e. it does not come from an old image, < 0 error
|
||||||
|
*
|
||||||
|
* @since 0.6.4
|
||||||
|
*/
|
||||||
|
int iso_file_get_old_image_lba(IsoFile *file, uint32_t *lba, int flag)
|
||||||
|
{
|
||||||
|
if (file == NULL || lba == NULL) {
|
||||||
|
return ISO_NULL_POINTER;
|
||||||
|
}
|
||||||
|
if (flag != 0) {
|
||||||
|
return ISO_WRONG_ARG_VALUE;
|
||||||
|
}
|
||||||
|
if (file->msblock != 0) {
|
||||||
|
*lba = file->msblock;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Like iso_file_get_old_image_lba(), but take an IsoNode.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* 1 if lba is valid (file comes from old image), 0 if file was newly
|
||||||
|
* added, i.e. it does not come from an old image, 2 node type has no
|
||||||
|
* LBA (no regular file), < 0 error
|
||||||
|
*
|
||||||
|
* @since 0.6.4
|
||||||
|
*/
|
||||||
|
int iso_node_get_old_image_lba(IsoNode *node, uint32_t *lba, int flag)
|
||||||
|
{
|
||||||
|
if (node == NULL) {
|
||||||
|
return ISO_NULL_POINTER;
|
||||||
|
}
|
||||||
|
if (ISO_NODE_IS_FILE(node)) {
|
||||||
|
return iso_file_get_old_image_lba((IsoFile*)node, lba, flag);
|
||||||
|
} else {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if a given name is valid for an iso node.
|
* Check if a given name is valid for an iso node.
|
||||||
*
|
*
|
||||||
|
@ -148,13 +148,32 @@ struct Iso_Special
|
|||||||
dev_t dev;
|
dev_t dev;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct iso_dir_iter_iface
|
||||||
|
{
|
||||||
|
|
||||||
|
int (*next)(IsoDirIter *iter, IsoNode **node);
|
||||||
|
|
||||||
|
int (*has_next)(IsoDirIter *iter);
|
||||||
|
|
||||||
|
void (*free)(IsoDirIter *iter);
|
||||||
|
|
||||||
|
int (*take)(IsoDirIter *iter);
|
||||||
|
|
||||||
|
int (*remove)(IsoDirIter *iter);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An iterator for directory children.
|
* An iterator for directory children.
|
||||||
*/
|
*/
|
||||||
struct Iso_Dir_Iter
|
struct Iso_Dir_Iter
|
||||||
{
|
{
|
||||||
const IsoDir *dir;
|
struct iso_dir_iter_iface *class;
|
||||||
IsoNode *pos;
|
|
||||||
|
/* the directory this iterator iterates over */
|
||||||
|
IsoDir *dir;
|
||||||
|
|
||||||
|
void *data;
|
||||||
};
|
};
|
||||||
|
|
||||||
int iso_node_new_root(IsoDir **root);
|
int iso_node_new_root(IsoDir **root);
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
ino_t serial_id = (ino_t)1;
|
ino_t serial_id = (ino_t)1;
|
||||||
ino_t mem_serial_id = (ino_t)1;
|
ino_t mem_serial_id = (ino_t)1;
|
||||||
@ -123,14 +124,6 @@ void fsrc_get_id(IsoStream *stream, unsigned int *fs_id, dev_t *dev_id,
|
|||||||
*ino_id = data->ino_id;
|
*ino_id = data->ino_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
|
||||||
char *fsrc_get_name(IsoStream *stream)
|
|
||||||
{
|
|
||||||
FSrcStreamData *data;
|
|
||||||
data = (FSrcStreamData*)stream->data;
|
|
||||||
return iso_file_source_get_path(data->src);
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
static
|
||||||
void fsrc_free(IsoStream *stream)
|
void fsrc_free(IsoStream *stream)
|
||||||
{
|
{
|
||||||
@ -141,13 +134,14 @@ void fsrc_free(IsoStream *stream)
|
|||||||
}
|
}
|
||||||
|
|
||||||
IsoStreamIface fsrc_stream_class = {
|
IsoStreamIface fsrc_stream_class = {
|
||||||
|
0,
|
||||||
|
"fsrc",
|
||||||
fsrc_open,
|
fsrc_open,
|
||||||
fsrc_close,
|
fsrc_close,
|
||||||
fsrc_get_size,
|
fsrc_get_size,
|
||||||
fsrc_read,
|
fsrc_read,
|
||||||
fsrc_is_repeatable,
|
fsrc_is_repeatable,
|
||||||
fsrc_get_id,
|
fsrc_get_id,
|
||||||
fsrc_get_name,
|
|
||||||
fsrc_free
|
fsrc_free
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -237,7 +231,7 @@ int mem_open(IsoStream *stream)
|
|||||||
}
|
}
|
||||||
data = (MemStreamData*)stream->data;
|
data = (MemStreamData*)stream->data;
|
||||||
if (data->offset != -1) {
|
if (data->offset != -1) {
|
||||||
return ISO_FILE_ALREADY_OPENNED;
|
return ISO_FILE_ALREADY_OPENED;
|
||||||
}
|
}
|
||||||
data->offset = 0;
|
data->offset = 0;
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
@ -252,7 +246,7 @@ int mem_close(IsoStream *stream)
|
|||||||
}
|
}
|
||||||
data = (MemStreamData*)stream->data;
|
data = (MemStreamData*)stream->data;
|
||||||
if (data->offset == -1) {
|
if (data->offset == -1) {
|
||||||
return ISO_FILE_NOT_OPENNED;
|
return ISO_FILE_NOT_OPENED;
|
||||||
}
|
}
|
||||||
data->offset = -1;
|
data->offset = -1;
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
@ -281,7 +275,7 @@ int mem_read(IsoStream *stream, void *buf, size_t count)
|
|||||||
data = stream->data;
|
data = stream->data;
|
||||||
|
|
||||||
if (data->offset == -1) {
|
if (data->offset == -1) {
|
||||||
return ISO_FILE_NOT_OPENNED;
|
return ISO_FILE_NOT_OPENED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data->offset >= data->size) {
|
if (data->offset >= data->size) {
|
||||||
@ -311,12 +305,6 @@ void mem_get_id(IsoStream *stream, unsigned int *fs_id, dev_t *dev_id,
|
|||||||
*ino_id = data->ino_id;
|
*ino_id = data->ino_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
|
||||||
char *mem_get_name(IsoStream *stream)
|
|
||||||
{
|
|
||||||
return strdup("[MEMORY SOURCE]");
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
static
|
||||||
void mem_free(IsoStream *stream)
|
void mem_free(IsoStream *stream)
|
||||||
{
|
{
|
||||||
@ -327,13 +315,14 @@ void mem_free(IsoStream *stream)
|
|||||||
}
|
}
|
||||||
|
|
||||||
IsoStreamIface mem_stream_class = {
|
IsoStreamIface mem_stream_class = {
|
||||||
|
0,
|
||||||
|
"mem ",
|
||||||
mem_open,
|
mem_open,
|
||||||
mem_close,
|
mem_close,
|
||||||
mem_get_size,
|
mem_get_size,
|
||||||
mem_read,
|
mem_read,
|
||||||
mem_is_repeatable,
|
mem_is_repeatable,
|
||||||
mem_get_id,
|
mem_get_id,
|
||||||
mem_get_name,
|
|
||||||
mem_free
|
mem_free
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -427,8 +416,19 @@ void iso_stream_get_id(IsoStream *stream, unsigned int *fs_id, dev_t *dev_id,
|
|||||||
stream->class->get_id(stream, fs_id, dev_id, ino_id);
|
stream->class->get_id(stream, fs_id, dev_id, ino_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
void iso_stream_get_file_name(IsoStream *stream, char *name)
|
||||||
char *iso_stream_get_name(IsoStream *stream)
|
|
||||||
{
|
{
|
||||||
return stream->class->get_name(stream);
|
char *type = stream->class->type;
|
||||||
|
|
||||||
|
if (!strncmp(type, "fsrc", 4)) {
|
||||||
|
FSrcStreamData *data = stream->data;
|
||||||
|
char *path = iso_file_source_get_path(data->src);
|
||||||
|
strncpy(name, path, PATH_MAX);
|
||||||
|
} else if (!strncmp(type, "boot", 4)) {
|
||||||
|
strcpy(name, "BOOT CATALOG");
|
||||||
|
} else if (!strncmp(type, "mem ", 4)) {
|
||||||
|
strcpy(name, "MEM SOURCE");
|
||||||
|
} else {
|
||||||
|
strcpy(name, "UNKNOWN SOURCE");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,12 +13,12 @@
|
|||||||
*/
|
*/
|
||||||
#include "fsource.h"
|
#include "fsource.h"
|
||||||
|
|
||||||
/* TODO consider removing this header */
|
/**
|
||||||
|
* Get an identifier for the file of the source, for debug purposes
|
||||||
/*
|
* @param name
|
||||||
* Some functions here will be moved to libisofs.h when we expose
|
* Should provide at least PATH_MAX bytes
|
||||||
* Streams.
|
|
||||||
*/
|
*/
|
||||||
|
void iso_stream_get_file_name(IsoStream *stream, char *name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a stream to read from a IsoFileSource.
|
* Create a stream to read from a IsoFileSource.
|
||||||
|
Loading…
Reference in New Issue
Block a user