diff --git a/src/builder.c b/src/builder.c index 1de35a1..3e33ea6 100644 --- a/src/builder.c +++ b/src/builder.c @@ -13,6 +13,7 @@ #include #include +#include void iso_node_builder_ref(IsoNodeBuilder *builder) { @@ -29,8 +30,8 @@ void iso_node_builder_unref(IsoNodeBuilder *builder) } static -int default_create_file(IsoNodeBuilder *builder, IsoFileSource *src, - IsoFile **file) +int default_create_file(IsoNodeBuilder *builder, IsoImage *image, + IsoFileSource *src, IsoFile **file) { int res; struct stat info; @@ -81,6 +82,120 @@ int default_create_file(IsoNodeBuilder *builder, IsoFileSource *src, return ISO_SUCCESS; } +static +int default_create_node(IsoNodeBuilder *builder, IsoImage *image, + IsoFileSource *src, IsoNode **node) +{ + int result; + struct stat info; + IsoNode *new; + char *name; + + if (builder == NULL || src == NULL || node == NULL) { + return ISO_NULL_POINTER; + } + + name = src->get_name(src); + + /* get info about source */ + result = src->lstat(src, &info); + if (result < 0) { + return result; + } + + new = NULL; + switch (info.st_mode & S_IFMT) { + case S_IFREG: + { + /* source is a regular file */ + IsoStream *stream; + IsoFile *file; + result = iso_file_source_stream_new(src, &stream); + if (result < 0) { + return result; + } + file = calloc(1, sizeof(IsoFile)); + if (file == NULL) { + iso_stream_unref(stream); + return ISO_MEM_ERROR; + } + file->msblock = 0; + file->sort_weight = 0; + file->stream = stream; + file->node.type = LIBISO_FILE; + new = (IsoNode*) file; + } + break; + case S_IFDIR: + { + /* source is a directory */ + new = calloc(1, sizeof(IsoDir)); + if (new == NULL) { + return ISO_MEM_ERROR; + } + new->type = LIBISO_DIR; + iso_file_source_unref(src); + } + break; + case S_IFLNK: + { + /* source is a symbolic link */ + char dest[PATH_MAX]; + IsoSymlink *link; + + result = src->readlink(src, dest, PATH_MAX); + if (result < 0) { + return result; + } + link = malloc(sizeof(IsoSymlink)); + if (link == NULL) { + return ISO_MEM_ERROR; + } + link->dest = strdup(dest); + link->node.type = LIBISO_SYMLINK; + new = (IsoNode*) link; + iso_file_source_unref(src); + } + break; + case S_IFSOCK: + case S_IFBLK: + case S_IFCHR: + case S_IFIFO: + { + /* source is an special file */ + IsoSpecial *special; + special = malloc(sizeof(IsoSpecial)); + if (special == NULL) { + return ISO_MEM_ERROR; + } + special->dev = info.st_rdev; + special->node.type = LIBISO_SPECIAL; + new = (IsoNode*) special; + iso_file_source_unref(src); + } + break; + } + + /* fill fields */ + new->refcount = 1; + new->name = strdup(name); + new->mode = info.st_mode; + new->uid = info.st_uid; + new->gid = info.st_gid; + new->atime = info.st_atime; + new->mtime = info.st_mtime; + new->ctime = info.st_ctime; + + new->hidden = 0; + + new->parent = NULL; + new->next = NULL; + + *node = new; + return ISO_SUCCESS; +} + +static void default_free(IsoNodeBuilder *builder) { return; @@ -100,8 +215,10 @@ int iso_node_basic_builder_new(IsoNodeBuilder **builder) } b->refcount = 1; - b->data = NULL; + b->create_file_data = NULL; + b->create_node_data = NULL; b->create_file = default_create_file; + b->create_node = default_create_node; b->free = default_free; *builder = b; diff --git a/src/builder.h b/src/builder.h index edd3d89..b951977 100644 --- a/src/builder.h +++ b/src/builder.h @@ -40,8 +40,22 @@ struct Iso_Node_Builder * @return * 1 on success, < 0 on error */ - int (*create_file)(IsoNodeBuilder *builder, IsoFileSource *src, - IsoFile **file); + int (*create_file)(IsoNodeBuilder *builder, IsoImage *image, + IsoFileSource *src, IsoFile **file); + + /** + * Create a new IsoNode from a IsoFileSource. The type of the node to be + * created is determined from the type of the file source. Name, + * permissions and other attributes are taken from source file. + * + * On sucess, the ref. to src will be owned by node, so you musn't + * unref it. + * + * @return + * 1 on success, < 0 on error + */ + int (*create_node)(IsoNodeBuilder *builder, IsoImage *image, + IsoFileSource *src, IsoNode **node); /** * Free implementation specific data. Should never be called by user. @@ -50,7 +64,8 @@ struct Iso_Node_Builder void (*free)(IsoNodeBuilder *builder); int refcount; - void *data; + void *create_file_data; + void *create_node_data; }; void iso_node_builder_ref(IsoNodeBuilder *builder); diff --git a/src/tree.c b/src/tree.c index ad752c0..38c78d9 100644 --- a/src/tree.c +++ b/src/tree.c @@ -20,7 +20,6 @@ #include #include #include -#include /** * Add a new directory to the iso tree. @@ -295,11 +294,11 @@ int iso_tree_add_new_special(IsoDir *parent, const char *name, mode_t mode, } static -int iso_tree_add_node_builder(IsoDir *parent, IsoFileSource *src, - IsoNodeBuilder *builder, IsoNode **node) +int iso_tree_add_node_builder(IsoImage *image, IsoDir *parent, + IsoFileSource *src, IsoNodeBuilder *builder, + IsoNode **node) { int result; - struct stat info; IsoNode *new; IsoNode **pos; char *name; @@ -323,94 +322,11 @@ int iso_tree_add_node_builder(IsoDir *parent, IsoFileSource *src, return ISO_NODE_NAME_NOT_UNIQUE; } - /* get info about source */ - result = src->lstat(src, &info); + result = builder->create_node(builder, image, src, &new); if (result < 0) { return result; } - new = NULL; - switch (info.st_mode & S_IFMT) { - case S_IFREG: - { - /* source is a regular file */ - IsoStream *stream; - IsoFile *file; - result = iso_file_source_stream_new(src, &stream); - if (result < 0) { - return result; - } - file = malloc(sizeof(IsoFile)); - if (file == NULL) { - iso_stream_unref(stream); - return ISO_MEM_ERROR; - } - file->msblock = 0; - file->sort_weight = 0; - file->stream = stream; - file->node.type = LIBISO_FILE; - new = (IsoNode*) file; - } - break; - case S_IFDIR: - { - /* source is a directory */ - new = calloc(1, sizeof(IsoDir)); - if (new == NULL) { - return ISO_MEM_ERROR; - } - new->type = LIBISO_DIR; - } - break; - case S_IFLNK: - { - /* source is a symbolic link */ - char dest[PATH_MAX]; - IsoSymlink *link; - - result = src->readlink(src, dest, PATH_MAX); - if (result < 0) { - return result; - } - link = malloc(sizeof(IsoSymlink)); - if (link == NULL) { - return ISO_MEM_ERROR; - } - link->dest = strdup(dest); - link->node.type = LIBISO_SYMLINK; - new = (IsoNode*) link; - } - break; - case S_IFSOCK: - case S_IFBLK: - case S_IFCHR: - case S_IFIFO: - { - /* source is an special file */ - IsoSpecial *special; - special = malloc(sizeof(IsoSpecial)); - if (special == NULL) { - return ISO_MEM_ERROR; - } - special->dev = info.st_rdev; - special->node.type = LIBISO_SPECIAL; - new = (IsoNode*) special; - } - break; - } - - /* fill fields */ - new->refcount = 1; - new->name = strdup(name); - new->mode = info.st_mode; - new->uid = info.st_uid; - new->gid = info.st_gid; - new->atime = info.st_atime; - new->mtime = info.st_mtime; - new->ctime = info.st_ctime; - - new->hidden = 0; - /* finally, add node to parent */ new->parent = parent; new->next = *pos; @@ -438,7 +354,8 @@ int iso_tree_add_node(IsoImage *image, IsoDir *parent, const char *path, if (result < 0) { return result; } - result = iso_tree_add_node_builder(parent, file, image->builder, node); + result = iso_tree_add_node_builder(image, parent, file, image->builder, + node); return result; }