Switch to Vreixo development branch 378

This commit is contained in:
Thomas Schmitt 2008-03-04 17:07:29 +00:00
parent 9f6b7e4e3f
commit 7cbbf97669
13 changed files with 585 additions and 149 deletions

View File

@ -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

View File

@ -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 */

View File

@ -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
}; };

View File

@ -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 */

View File

@ -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;
} }

View File

@ -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;
} }
} }

View File

@ -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.

View File

@ -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

View File

@ -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:

View File

@ -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;
*node = NULL;
return 0; /* 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;
return 0;
}
} else {
if (data->pos->parent != iter->dir) {
/* this can happen if the node has been moved to another dir */
/* TODO specific error */
return ISO_ERROR;
}
if (data->pos->next == NULL) {
/* 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;
}
} }
if (n->parent != iter->dir) {
/* this can happen if the node has been moved to another dir */ /* ok, take a ref to the current position, to prevent internal errors
return ISO_ERROR; * if deleted somewhere */
} iso_node_ref(data->pos);
*node = n; data->flag |= 0x01; /* set next flag */
iter->pos = n->next;
/* 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.
* *

View File

@ -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);

View File

@ -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");
}
} }

View File

@ -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.