Switch to Vreixo development branch 378

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

View File

@ -16,6 +16,7 @@ libisofs_libisofs_la_SOURCES = \
libisofs/node.c \
libisofs/tree.h \
libisofs/tree.c \
libisofs/find.c \
libisofs/image.h \
libisofs/image.c \
libisofs/fsource.h \
@ -28,6 +29,9 @@ libisofs_libisofs_la_SOURCES = \
libisofs/libiso_msgs.c \
libisofs/stream.h \
libisofs/stream.c \
libisofs/filter.h \
libisofs/filter.c \
libisofs/filters/xor_encrypt.c \
libisofs/util.h \
libisofs/util.c \
libisofs/util_rbtree.c \
@ -62,6 +66,7 @@ noinst_PROGRAMS = \
demo/cat \
demo/catbuffer \
demo/tree \
demo/find \
demo/ecma119tree \
demo/iso \
demo/isoread \
@ -86,6 +91,10 @@ demo_tree_CPPFLAGS = -Ilibisofs
demo_tree_LDADD = $(libisofs_libisofs_la_OBJECTS) $(THREAD_LIBS)
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_LDADD = $(libisofs_libisofs_la_OBJECTS) $(THREAD_LIBS)
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;
if (data->fd != -1) {
return ISO_FILE_ALREADY_OPENNED;
return ISO_FILE_ALREADY_OPENED;
}
fd = open(data->path, O_RDONLY);
@ -81,7 +81,7 @@ int ds_close(IsoDataSource *src)
data = (struct file_data_src*) src->data;
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 */
@ -102,7 +102,7 @@ static int ds_read_block(IsoDataSource *src, uint32_t lba, uint8_t *buffer)
data = (struct file_data_src*) src->data;
if (data->fd == -1) {
return ISO_FILE_NOT_OPENNED;
return ISO_FILE_NOT_OPENED;
}
/* goes to requested block */

View File

@ -538,7 +538,7 @@ int catalog_open(IsoStream *stream)
data = stream->data;
if (data->offset != -1) {
return ISO_FILE_ALREADY_OPENNED;
return ISO_FILE_ALREADY_OPENED;
}
memset(data->buffer, 0, BLOCK_SIZE);
@ -563,7 +563,7 @@ int catalog_close(IsoStream *stream)
data = stream->data;
if (data->offset == -1) {
return ISO_FILE_NOT_OPENNED;
return ISO_FILE_NOT_OPENED;
}
data->offset = -1;
return ISO_SUCCESS;
@ -589,7 +589,7 @@ int catalog_read(IsoStream *stream, void *buf, size_t count)
data = stream->data;
if (data->offset == -1) {
return ISO_FILE_NOT_OPENNED;
return ISO_FILE_NOT_OPENED;
}
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;
}
static
char *catalog_get_name(IsoStream *stream)
{
return strdup("El-Torito Boot Catalog");
}
static
void catalog_free(IsoStream *stream)
{
@ -630,13 +624,14 @@ void catalog_free(IsoStream *stream)
}
IsoStreamIface catalog_stream_class = {
0,
"boot",
catalog_open,
catalog_close,
catalog_get_size,
catalog_read,
catalog_is_repeatable,
catalog_get_id,
catalog_get_name,
catalog_free
};

View File

@ -15,6 +15,7 @@
#include <stdlib.h>
#include <string.h>
#include <limits.h>
int iso_file_src_cmp(const void *n1, const void *n2)
{
@ -243,7 +244,7 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
Ecma119Image *t;
IsoFileSrc *file;
IsoFileSrc **filelist;
char *name;
char name[PATH_MAX];
char buffer[BLOCK_SIZE];
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);
res = filesrc_open(file);
iso_stream_get_file_name(file->stream, name);
if (res < 0) {
/*
* UPS, very ugly error, the best we can do is just to write
* 0's to image
*/
name = iso_stream_get_name(file->stream);
iso_report_errfile(name, ISO_FILE_CANT_WRITE, 0, 0);
res = iso_msg_submit(t->image->id, ISO_FILE_CANT_WRITE, res,
"File \"%s\" can't be opened. Filling with 0s.", name);
free(name);
if (res < 0) {
return res; /* aborted due to error severity */
}
@ -289,12 +289,10 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
}
continue;
} else if (res > 1) {
name = iso_stream_get_name(file->stream);
iso_report_errfile(name, ISO_FILE_CANT_WRITE, 0, 0);
res = iso_msg_submit(t->image->id, ISO_FILE_CANT_WRITE, 0,
"Size of file \"%s\" has changed. It will be %s", name,
(res == 2 ? "truncated" : "padded with 0's"));
free(name);
if (res < 0) {
filesrc_close(file);
return res; /* aborted due to error severity */
@ -302,9 +300,7 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
}
#ifdef LIBISOFS_VERBOSE_DEBUG
else {
name = iso_stream_get_name(file->stream);
iso_msg_debug(t->image->id, "Writing file %s", name);
free(name);
}
#endif
@ -328,7 +324,6 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
if (b < nblocks) {
/* 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);
if (res < 0) {
/* error */
@ -339,7 +334,6 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
res = iso_msg_submit(t->image->id, ISO_FILE_CANT_WRITE, 0,
"Premature end of file %s.", name);
}
free(name);
if (res < 0) {
return res; /* aborted due error severity */

View File

@ -474,7 +474,7 @@ int ifs_open(IsoFileSource *src)
data = (ImageFileSourceData*)src->data;
if (data->opened) {
return ISO_FILE_ALREADY_OPENNED;
return ISO_FILE_ALREADY_OPENED;
}
if (S_ISDIR(data->info.st_mode)) {
@ -530,7 +530,7 @@ int ifs_close(IsoFileSource *src)
data = (ImageFileSourceData*)src->data;
if (!data->opened) {
return ISO_FILE_NOT_OPENNED;
return ISO_FILE_NOT_OPENED;
}
if (data->opened == 2) {
@ -569,7 +569,7 @@ int ifs_close(IsoFileSource *src)
* Error codes:
* ISO_FILE_ERROR
* ISO_NULL_POINTER
* ISO_FILE_NOT_OPENNED
* ISO_FILE_NOT_OPENED
* ISO_FILE_IS_DIR
* ISO_OUT_OF_MEM
* ISO_INTERRUPTED
@ -590,7 +590,7 @@ int ifs_read(IsoFileSource *src, void *buf, size_t count)
data = (ImageFileSourceData*)src->data;
if (!data->opened) {
return ISO_FILE_NOT_OPENNED;
return ISO_FILE_NOT_OPENED;
} else if (data->opened != 1) {
return ISO_FILE_IS_DIR;
}
@ -644,7 +644,7 @@ int ifs_readdir(IsoFileSource *src, IsoFileSource **child)
data = (ImageFileSourceData*)src->data;
if (!data->opened) {
return ISO_FILE_NOT_OPENNED;
return ISO_FILE_NOT_OPENED;
} else if (data->opened != 2) {
return ISO_FILE_IS_NOT_DIR;
}

View File

@ -190,7 +190,7 @@ int lfs_open(IsoFileSource *src)
data = src->data;
if (data->openned) {
return ISO_FILE_ALREADY_OPENNED;
return ISO_FILE_ALREADY_OPENED;
}
/* 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;
break;
default:
ret = ISO_FILE_NOT_OPENNED;
ret = ISO_FILE_NOT_OPENED;
break;
}
if (ret == ISO_SUCCESS) {
@ -300,7 +300,7 @@ int lfs_read(IsoFileSource *src, void *buf, size_t count)
case 2: /* directory */
return ISO_FILE_IS_DIR;
default:
return ISO_FILE_NOT_OPENNED;
return ISO_FILE_NOT_OPENED;
}
}
@ -341,7 +341,7 @@ int lfs_readdir(IsoFileSource *src, IsoFileSource **child)
return ret;
}
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_ELTORITO_FS_ID 3
#define ISO_MEM_FS_ID 4
#define ISO_FILTER_FS_ID 5
/**
* Create a new IsoFilesystem to deal with local filesystem.

View File

@ -519,7 +519,7 @@ struct IsoFileSource_Iface
* Opens the source.
* @return 1 on success, < 0 on error
* Error codes:
* ISO_FILE_ALREADY_OPENNED
* ISO_FILE_ALREADY_OPENED
* ISO_FILE_ACCESS_DENIED
* ISO_FILE_BAD_PATH
* ISO_FILE_DOESNT_EXIST
@ -535,7 +535,7 @@ struct IsoFileSource_Iface
* Error codes:
* ISO_FILE_ERROR
* ISO_NULL_POINTER
* ISO_FILE_NOT_OPENNED
* ISO_FILE_NOT_OPENED
*/
int (*close)(IsoFileSource *src);
@ -552,7 +552,7 @@ struct IsoFileSource_Iface
* Error codes:
* ISO_FILE_ERROR
* ISO_NULL_POINTER
* ISO_FILE_NOT_OPENNED
* ISO_FILE_NOT_OPENED
* ISO_WRONG_ARG_VALUE -> if count == 0
* ISO_FILE_IS_DIR
* ISO_OUT_OF_MEM
@ -578,7 +578,7 @@ struct IsoFileSource_Iface
* Error codes:
* ISO_FILE_ERROR
* ISO_NULL_POINTER
* ISO_FILE_NOT_OPENNED
* ISO_FILE_NOT_OPENED
* ISO_FILE_IS_NOT_DIR
* ISO_OUT_OF_MEM
*/
@ -675,6 +675,18 @@ extern ino_t serial_id;
*/
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.
*
@ -727,14 +739,6 @@ struct IsoStream_Iface
void (*get_id)(IsoStream *stream, unsigned int *fs_id, dev_t *dev_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.
* 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 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_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
*
@ -2160,6 +2164,191 @@ int iso_dir_iter_take(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.
* 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);
/**
* 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
* 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.
* @return 1 on success, < 0 on error
* Error codes:
* ISO_FILE_ALREADY_OPENNED
* ISO_FILE_ALREADY_OPENED
* ISO_FILE_ACCESS_DENIED
* ISO_FILE_BAD_PATH
* ISO_FILE_DOESNT_EXIST
@ -2907,7 +3125,7 @@ int iso_file_source_open(IsoFileSource *src);
* Error codes:
* ISO_FILE_ERROR
* ISO_NULL_POINTER
* ISO_FILE_NOT_OPENNED
* ISO_FILE_NOT_OPENED
*
* @since 0.6.2
*/
@ -2933,7 +3151,7 @@ int iso_file_source_close(IsoFileSource *src);
* Error codes:
* ISO_FILE_ERROR
* ISO_NULL_POINTER
* ISO_FILE_NOT_OPENNED
* ISO_FILE_NOT_OPENED
* ISO_WRONG_ARG_VALUE -> if count == 0
* ISO_FILE_IS_DIR
* ISO_OUT_OF_MEM
@ -2961,7 +3179,7 @@ int iso_file_source_read(IsoFileSource *src, void *buf, size_t count);
* Error codes:
* ISO_FILE_ERROR
* ISO_NULL_POINTER
* ISO_FILE_NOT_OPENNED
* ISO_FILE_NOT_OPENED
* ISO_FILE_IS_NOT_DIR
* ISO_OUT_OF_MEM
*
@ -3202,17 +3420,6 @@ int iso_stream_is_repeatable(IsoStream *stream);
*/
void iso_stream_get_id(IsoStream *stream, unsigned int *fs_id, dev_t *dev_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 ********************/
@ -3287,6 +3494,9 @@ char *iso_stream_get_name(IsoStream *stream);
#define ISO_FILE_ERROR 0xE830FF80
/** 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
/** 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
/** 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) */
#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";
case ISO_FILE_ERROR:
return "Error on file operation";
case ISO_FILE_ALREADY_OPENNED:
return "Trying to open an already openned file";
case ISO_FILE_ALREADY_OPENED:
return "Trying to open an already opened file";
case ISO_FILE_ACCESS_DENIED:
return "Access to file is not allowed";
case ISO_FILE_BAD_PATH:
return "Incorrect path to file";
case ISO_FILE_DOESNT_EXIST:
return "The file does not exist in the filesystem";
case ISO_FILE_NOT_OPENNED:
return "Trying to read or close a file not openned";
case ISO_FILE_NOT_OPENED:
return "Trying to read or close a file not opened";
case ISO_FILE_IS_DIR:
return "Directory used where no dir is expected";
case ISO_FILE_READ_ERROR:

View File

@ -15,6 +15,17 @@
#include <time.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.
*/
@ -354,42 +365,53 @@ int iso_dir_get_children_count(IsoDir *dir)
return dir->nchildren;
}
int iso_dir_get_children(const IsoDir *dir, IsoDirIter **iter)
static
int iter_next(IsoDirIter *iter, IsoNode **node)
{
IsoDirIter *it;
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;
struct dir_iter_data *data;
if (iter == NULL || node == NULL) {
return ISO_NULL_POINTER;
}
n = iter->pos;
if (n == NULL) {
*node = NULL;
return 0;
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;
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 */
return ISO_ERROR;
}
*node = n;
iter->pos = n->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;
}
@ -401,17 +423,30 @@ int iso_dir_iter_next(IsoDirIter *iter, IsoNode **node)
* Possible errors:
* 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) {
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)
@ -448,7 +483,7 @@ int iso_node_take(IsoNode *node)
pos = iso_dir_find_node(dir, node);
if (pos == NULL) {
/* should never occur */
return ISO_ERROR;
return ISO_ASSERT_FAILURE;
}
*pos = node->next;
node->parent = NULL;
@ -492,43 +527,161 @@ IsoDir *iso_node_get_parent(IsoNode *node)
}
/* 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) {
return ISO_NULL_POINTER;
}
pos = iter->dir->children;
if (iter->pos == pos) {
return ISO_ERROR;
data = iter->data;
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;
}
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_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)
{
IsoNode *pos;
if (iter == NULL) {
return ISO_NULL_POINTER;
}
pos = iter->dir->children;
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);
return iter->class->remove(iter);
}
/**
@ -618,6 +771,58 @@ IsoStream *iso_file_get_stream(IsoFile *file)
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.
*

View File

@ -148,13 +148,32 @@ struct Iso_Special
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.
*/
struct Iso_Dir_Iter
{
const IsoDir *dir;
IsoNode *pos;
struct iso_dir_iter_iface *class;
/* the directory this iterator iterates over */
IsoDir *dir;
void *data;
};
int iso_node_new_root(IsoDir **root);

View File

@ -13,6 +13,7 @@
#include <stdlib.h>
#include <string.h>
#include <limits.h>
ino_t 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;
}
static
char *fsrc_get_name(IsoStream *stream)
{
FSrcStreamData *data;
data = (FSrcStreamData*)stream->data;
return iso_file_source_get_path(data->src);
}
static
void fsrc_free(IsoStream *stream)
{
@ -141,13 +134,14 @@ void fsrc_free(IsoStream *stream)
}
IsoStreamIface fsrc_stream_class = {
0,
"fsrc",
fsrc_open,
fsrc_close,
fsrc_get_size,
fsrc_read,
fsrc_is_repeatable,
fsrc_get_id,
fsrc_get_name,
fsrc_free
};
@ -237,7 +231,7 @@ int mem_open(IsoStream *stream)
}
data = (MemStreamData*)stream->data;
if (data->offset != -1) {
return ISO_FILE_ALREADY_OPENNED;
return ISO_FILE_ALREADY_OPENED;
}
data->offset = 0;
return ISO_SUCCESS;
@ -252,7 +246,7 @@ int mem_close(IsoStream *stream)
}
data = (MemStreamData*)stream->data;
if (data->offset == -1) {
return ISO_FILE_NOT_OPENNED;
return ISO_FILE_NOT_OPENED;
}
data->offset = -1;
return ISO_SUCCESS;
@ -281,7 +275,7 @@ int mem_read(IsoStream *stream, void *buf, size_t count)
data = stream->data;
if (data->offset == -1) {
return ISO_FILE_NOT_OPENNED;
return ISO_FILE_NOT_OPENED;
}
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;
}
static
char *mem_get_name(IsoStream *stream)
{
return strdup("[MEMORY SOURCE]");
}
static
void mem_free(IsoStream *stream)
{
@ -327,13 +315,14 @@ void mem_free(IsoStream *stream)
}
IsoStreamIface mem_stream_class = {
0,
"mem ",
mem_open,
mem_close,
mem_get_size,
mem_read,
mem_is_repeatable,
mem_get_id,
mem_get_name,
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);
}
inline
char *iso_stream_get_name(IsoStream *stream)
void iso_stream_get_file_name(IsoStream *stream, char *name)
{
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"
/* TODO consider removing this header */
/*
* Some functions here will be moved to libisofs.h when we expose
* Streams.
/**
* Get an identifier for the file of the source, for debug purposes
* @param name
* Should provide at least PATH_MAX bytes
*/
void iso_stream_get_file_name(IsoStream *stream, char *name);
/**
* Create a stream to read from a IsoFileSource.