Implement function to recursively add a dir to an iso tree.
This commit also to the following changes: - create_node() on builder never frees the IsoFileSource, it is responsability of the caller to free it. - Recursive addition options added to IsoImage (not exposed to public API yet) - create_node() takes care about follow_symlinks - Added little demo program to test it.
This commit is contained in:
parent
0306bb5daf
commit
d10ed353e2
@ -26,3 +26,4 @@ test/iso
|
|||||||
test/test
|
test/test
|
||||||
demo/lsl
|
demo/lsl
|
||||||
demo/cat
|
demo/cat
|
||||||
|
demo/tree
|
||||||
|
@ -35,7 +35,8 @@ libinclude_HEADERS = \
|
|||||||
## Build demo applications
|
## Build demo applications
|
||||||
noinst_PROGRAMS = \
|
noinst_PROGRAMS = \
|
||||||
demo/lsl \
|
demo/lsl \
|
||||||
demo/cat
|
demo/cat \
|
||||||
|
demo/tree
|
||||||
|
|
||||||
demo_lsl_CPPFLAGS = -Isrc
|
demo_lsl_CPPFLAGS = -Isrc
|
||||||
demo_lsl_LDADD = $(src_libisofs_la_OBJECTS) $(THREAD_LIBS)
|
demo_lsl_LDADD = $(src_libisofs_la_OBJECTS) $(THREAD_LIBS)
|
||||||
@ -45,6 +46,10 @@ demo_cat_CPPFLAGS = -Isrc
|
|||||||
demo_cat_LDADD = $(src_libisofs_la_OBJECTS) $(THREAD_LIBS)
|
demo_cat_LDADD = $(src_libisofs_la_OBJECTS) $(THREAD_LIBS)
|
||||||
demo_cat_SOURCES = demo/cat.c
|
demo_cat_SOURCES = demo/cat.c
|
||||||
|
|
||||||
|
demo_tree_CPPFLAGS = -Isrc
|
||||||
|
demo_tree_LDADD = $(src_libisofs_la_OBJECTS) $(THREAD_LIBS)
|
||||||
|
demo_tree_SOURCES = demo/tree.c
|
||||||
|
|
||||||
|
|
||||||
## Build unit test
|
## Build unit test
|
||||||
|
|
||||||
|
105
demo/tree.c
Normal file
105
demo/tree.c
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
* Little program that reads an existing ISO image and prints its
|
||||||
|
* contents to stdout.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "libisofs.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_permissions(mode_t mode)
|
||||||
|
{
|
||||||
|
char perm[10];
|
||||||
|
|
||||||
|
//TODO suid, sticky...
|
||||||
|
|
||||||
|
perm[9] = '\0';
|
||||||
|
perm[8] = mode & S_IXOTH ? 'x' : '-';
|
||||||
|
perm[7] = mode & S_IWOTH ? 'w' : '-';
|
||||||
|
perm[6] = mode & S_IROTH ? 'r' : '-';
|
||||||
|
perm[5] = mode & S_IXGRP ? 'x' : '-';
|
||||||
|
perm[4] = mode & S_IWGRP ? 'w' : '-';
|
||||||
|
perm[3] = mode & S_IRGRP ? 'r' : '-';
|
||||||
|
perm[2] = mode & S_IXUSR ? 'x' : '-';
|
||||||
|
perm[1] = mode & S_IWUSR ? 'w' : '-';
|
||||||
|
perm[0] = mode & S_IRUSR ? 'r' : '-';
|
||||||
|
printf("[%s]",perm);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_dir(IsoDir *dir, int level)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
IsoDirIter *iter;
|
||||||
|
IsoNode *node;
|
||||||
|
char sp[level * 2 + 1];
|
||||||
|
|
||||||
|
for (i = 0; i < level * 2; i += 2) {
|
||||||
|
sp[i] = '|';
|
||||||
|
sp[i+1] = ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
sp[level * 2-1] = '-';
|
||||||
|
sp[level * 2] = '\0';
|
||||||
|
|
||||||
|
iso_dir_get_children(dir, &iter);
|
||||||
|
while (iso_dir_iter_next(iter, &node) == 1) {
|
||||||
|
|
||||||
|
if (iso_node_get_type(node) == LIBISO_DIR) {
|
||||||
|
printf("%s+[D] ", sp);
|
||||||
|
print_permissions(iso_node_get_permissions(node));
|
||||||
|
printf(" %s\n", iso_node_get_name(node));
|
||||||
|
print_dir((IsoDir*)node, level+1);
|
||||||
|
} else if (iso_node_get_type(node) == LIBISO_FILE) {
|
||||||
|
printf("%s-[F] ", sp);
|
||||||
|
print_permissions(iso_node_get_permissions(node));
|
||||||
|
printf(" %s\n", iso_node_get_name(node) );
|
||||||
|
} else if (iso_node_get_type(node) == LIBISO_SYMLINK) {
|
||||||
|
printf("%s-[L] ", sp);
|
||||||
|
print_permissions(iso_node_get_permissions(node));
|
||||||
|
printf(" %s -> %s \n", iso_node_get_name(node),
|
||||||
|
iso_symlink_get_dest((IsoSymlink*)node) );
|
||||||
|
} else {
|
||||||
|
printf("%s-[C] ", sp);
|
||||||
|
print_permissions(iso_node_get_permissions(node));
|
||||||
|
printf(" %s\n", iso_node_get_name(node) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
iso_dir_iter_free(iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
IsoImage *image;
|
||||||
|
|
||||||
|
if (argc != 2) {
|
||||||
|
printf ("You need to specify a valid path\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
result = iso_image_new("volume_id", &image);
|
||||||
|
if (result < 0) {
|
||||||
|
printf ("Error creating image\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
iso_image_set_msgs_severities(image, "NEVER", "ALL", "");
|
||||||
|
|
||||||
|
result = iso_tree_add_dir_rec(image, iso_image_get_root(image), argv[1]);
|
||||||
|
if (result < 0) {
|
||||||
|
printf ("Error adding directory %d\n", result);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("================= IMAGE =================\n");
|
||||||
|
print_dir(iso_image_get_root(image), 0);
|
||||||
|
printf("\n\n");
|
||||||
|
|
||||||
|
iso_image_unref(image);
|
||||||
|
return 0;
|
||||||
|
}
|
@ -10,6 +10,7 @@
|
|||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
#include "fsource.h"
|
#include "fsource.h"
|
||||||
|
#include "image.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -98,7 +99,11 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
name = src->get_name(src);
|
name = src->get_name(src);
|
||||||
|
|
||||||
/* get info about source */
|
/* get info about source */
|
||||||
|
if (image->recOpts->follow_symlinks) {
|
||||||
|
result = src->stat(src, &info);
|
||||||
|
} else {
|
||||||
result = src->lstat(src, &info);
|
result = src->lstat(src, &info);
|
||||||
|
}
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -114,6 +119,8 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
/* take a ref to the src, as stream has taken our ref */
|
||||||
|
iso_file_source_ref(src);
|
||||||
file = calloc(1, sizeof(IsoFile));
|
file = calloc(1, sizeof(IsoFile));
|
||||||
if (file == NULL) {
|
if (file == NULL) {
|
||||||
iso_stream_unref(stream);
|
iso_stream_unref(stream);
|
||||||
@ -134,7 +141,6 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
return ISO_MEM_ERROR;
|
return ISO_MEM_ERROR;
|
||||||
}
|
}
|
||||||
new->type = LIBISO_DIR;
|
new->type = LIBISO_DIR;
|
||||||
iso_file_source_unref(src);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case S_IFLNK:
|
case S_IFLNK:
|
||||||
@ -154,7 +160,6 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
link->dest = strdup(dest);
|
link->dest = strdup(dest);
|
||||||
link->node.type = LIBISO_SYMLINK;
|
link->node.type = LIBISO_SYMLINK;
|
||||||
new = (IsoNode*) link;
|
new = (IsoNode*) link;
|
||||||
iso_file_source_unref(src);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case S_IFSOCK:
|
case S_IFSOCK:
|
||||||
@ -171,7 +176,6 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
special->dev = info.st_rdev;
|
special->dev = info.st_rdev;
|
||||||
special->node.type = LIBISO_SPECIAL;
|
special->node.type = LIBISO_SPECIAL;
|
||||||
new = (IsoNode*) special;
|
new = (IsoNode*) special;
|
||||||
iso_file_source_unref(src);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -48,8 +48,7 @@ struct Iso_Node_Builder
|
|||||||
* created is determined from the type of the file source. Name,
|
* created is determined from the type of the file source. Name,
|
||||||
* permissions and other attributes are taken from source file.
|
* permissions and other attributes are taken from source file.
|
||||||
*
|
*
|
||||||
* On sucess, the ref. to src will be owned by node, so you musn't
|
* Note that the src is never unref, so you need to free it.
|
||||||
* unref it.
|
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* 1 on success, < 0 on error
|
* 1 on success, < 0 on error
|
||||||
|
10
src/image.c
10
src/image.c
@ -77,6 +77,16 @@ int iso_image_new(const char *name, IsoImage **image)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
img->refcount = 1;
|
img->refcount = 1;
|
||||||
|
img->recOpts = calloc(1,sizeof(IsoImageRecOpts));
|
||||||
|
if (img->recOpts == NULL) {
|
||||||
|
libiso_msgs_destroy(&img->messenger, 0);
|
||||||
|
iso_node_builder_unref(img->builder);
|
||||||
|
iso_filesystem_unref(img->fs);
|
||||||
|
iso_node_unref((IsoNode*)img->root);
|
||||||
|
free(img);
|
||||||
|
return ISO_MEM_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
if (name != NULL) {
|
if (name != NULL) {
|
||||||
img->volset_id = strdup(name);
|
img->volset_id = strdup(name);
|
||||||
img->volume_id = strdup(name);
|
img->volume_id = strdup(name);
|
||||||
|
64
src/image.h
64
src/image.h
@ -22,6 +22,8 @@
|
|||||||
* [The stuff we have in init belongs really to image!]
|
* [The stuff we have in init belongs really to image!]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
typedef struct Iso_Image_Rec_Opts IsoImageRecOpts;
|
||||||
|
|
||||||
struct Iso_Image {
|
struct Iso_Image {
|
||||||
|
|
||||||
int refcount;
|
int refcount;
|
||||||
@ -51,6 +53,68 @@ struct Iso_Image {
|
|||||||
* Default builder to use when adding files to the image tree.
|
* Default builder to use when adding files to the image tree.
|
||||||
*/
|
*/
|
||||||
IsoNodeBuilder *builder;
|
IsoNodeBuilder *builder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Options for recursive directory addition
|
||||||
|
*/
|
||||||
|
IsoImageRecOpts *recOpts;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Options for recursive directory addition
|
||||||
|
*/
|
||||||
|
struct Iso_Image_Rec_Opts {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether to follow symlinks or just add them as symlinks
|
||||||
|
*/
|
||||||
|
unsigned int follow_symlinks;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether to skip hidden files
|
||||||
|
*/
|
||||||
|
unsigned int ignore_hidden;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether to stop on an error. Some errors, such as memory errors,
|
||||||
|
* always cause a stop
|
||||||
|
*/
|
||||||
|
unsigned int stop_on_error;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Files to exclude
|
||||||
|
* TODO add wildcard support
|
||||||
|
*/
|
||||||
|
char** excludes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* if the dir already contains a node with the same name, whether to
|
||||||
|
* replace or not the old node with the new.
|
||||||
|
* - 0 not replace
|
||||||
|
* - 1 replace
|
||||||
|
* TODO #00006 define more values
|
||||||
|
* to replace only if both are the same kind of file
|
||||||
|
* if both are dirs, add contents (and what to do with conflicts?)
|
||||||
|
*/
|
||||||
|
int replace;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When this is not NULL, it is a pointer to a function that will
|
||||||
|
* be called just before a file will be added, or when an error occurs.
|
||||||
|
* You can overwrite some of the above options by returning suitable
|
||||||
|
* values.
|
||||||
|
*
|
||||||
|
* @param action
|
||||||
|
* 1 file will be added
|
||||||
|
* 2 file will be skipped
|
||||||
|
* < 0 error adding file (return 3 to stop, 1 to continue)
|
||||||
|
* @param flag
|
||||||
|
* 0 no problem
|
||||||
|
* 1 file with same name already exists
|
||||||
|
* @return
|
||||||
|
* 1 add/continue, 2 skip, 3 stop
|
||||||
|
*/
|
||||||
|
int (*report)(IsoFileSource *src, int action, int flag);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /*LIBISO_IMAGE_H_*/
|
#endif /*LIBISO_IMAGE_H_*/
|
||||||
|
@ -638,6 +638,22 @@ int iso_tree_add_new_special(IsoDir *parent, const char *name, mode_t mode,
|
|||||||
int iso_tree_add_node(IsoImage *image, IsoDir *parent, const char *path,
|
int iso_tree_add_node(IsoImage *image, IsoDir *parent, const char *path,
|
||||||
IsoNode **node);
|
IsoNode **node);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the contents of a dir to a given directory of the iso tree.
|
||||||
|
*
|
||||||
|
* TODO comment Builder and Filesystem related issues when exposing both
|
||||||
|
*
|
||||||
|
* @param image
|
||||||
|
* TODO expose dir rec options and explain that here
|
||||||
|
* @param parent
|
||||||
|
* Directory on the image tree where to add the contents of the dir
|
||||||
|
* @param dir
|
||||||
|
* Path to a dir in the filesystem
|
||||||
|
* @return
|
||||||
|
* number of nodes in parent if success, < 0 otherwise
|
||||||
|
*/
|
||||||
|
int iso_tree_add_dir_rec(IsoImage *image, IsoDir *parent, const char *dir);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Locate a node by its path on image.
|
* Locate a node by its path on image.
|
||||||
*
|
*
|
||||||
|
215
src/tree.c
215
src/tree.c
@ -16,10 +16,13 @@
|
|||||||
#include "image.h"
|
#include "image.h"
|
||||||
#include "fsource.h"
|
#include "fsource.h"
|
||||||
#include "builder.h"
|
#include "builder.h"
|
||||||
|
#include "messages.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a new directory to the iso tree.
|
* Add a new directory to the iso tree.
|
||||||
@ -356,6 +359,218 @@ int iso_tree_add_node(IsoImage *image, IsoDir *parent, const char *path,
|
|||||||
}
|
}
|
||||||
result = iso_tree_add_node_builder(image, parent, file, image->builder,
|
result = iso_tree_add_node_builder(image, parent, file, image->builder,
|
||||||
node);
|
node);
|
||||||
|
/* free the file */
|
||||||
|
iso_file_source_unref(file);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int check_excludes(IsoImage *image, const char *path)
|
||||||
|
{
|
||||||
|
char **exclude;
|
||||||
|
if (image->recOpts->excludes == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
exclude = image->recOpts->excludes;
|
||||||
|
while (*exclude) {
|
||||||
|
if (strcmp(*exclude, path) == 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
++exclude;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int check_hidden(IsoImage *image, const char *name)
|
||||||
|
{
|
||||||
|
return (image->recOpts->ignore_hidden && name[0] == '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return
|
||||||
|
* 1 continue, 0 stop, < 0 error
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
int iso_add_dir_aux(IsoImage *image, IsoDir *parent, IsoFileSource *dir)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
int action; /* 1 add, 2 skip, 3 stop, < 0 error */
|
||||||
|
IsoNodeBuilder *builder;
|
||||||
|
IsoFileSource *file;
|
||||||
|
IsoNode **pos;
|
||||||
|
|
||||||
|
result = dir->open(dir);
|
||||||
|
if (result < 0) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
builder = image->builder;
|
||||||
|
action = 1;
|
||||||
|
while ( (result = dir->readdir(dir, &file)) == 1) {
|
||||||
|
int flag;
|
||||||
|
char *name;
|
||||||
|
IsoNode *new;
|
||||||
|
|
||||||
|
{
|
||||||
|
char msg[PATH_MAX];
|
||||||
|
sprintf(msg, "Adding file %s\n", file->get_path(file));
|
||||||
|
iso_msg_debug(image, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
name = file->get_name(file);
|
||||||
|
|
||||||
|
if (check_excludes(image, file->get_path(file))) {
|
||||||
|
action = 2;
|
||||||
|
} else if (check_hidden(image, name)) {
|
||||||
|
action = 2;
|
||||||
|
} else {
|
||||||
|
action = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* find place where to insert */
|
||||||
|
flag = 0;
|
||||||
|
pos = &(parent->children);
|
||||||
|
while (*pos != NULL && strcmp((*pos)->name, name) < 0) {
|
||||||
|
pos = &((*pos)->next);
|
||||||
|
}
|
||||||
|
if (*pos != NULL && !strcmp((*pos)->name, name)) {
|
||||||
|
flag = 1;
|
||||||
|
if (action == 1 && image->recOpts->replace == 0) {
|
||||||
|
action = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ask user if callback has been set */
|
||||||
|
if (image->recOpts->report) {
|
||||||
|
action = image->recOpts->report(file, action, flag);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action == 2) {
|
||||||
|
/* skip file */
|
||||||
|
iso_file_source_unref(file);
|
||||||
|
continue;
|
||||||
|
} else if (action == 3) {
|
||||||
|
/* stop */
|
||||||
|
iso_file_source_unref(file);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ok, file will be added */
|
||||||
|
result = builder->create_node(builder, image, file, &new);
|
||||||
|
if (result < 0) {
|
||||||
|
|
||||||
|
{
|
||||||
|
char msg[PATH_MAX];
|
||||||
|
sprintf(msg, "Error %d when adding file %s\n", result,
|
||||||
|
file->get_path(file));
|
||||||
|
iso_msg_debug(image, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (image->recOpts->report) {
|
||||||
|
action = image->recOpts->report(file, result, flag);
|
||||||
|
} else {
|
||||||
|
action = image->recOpts->stop_on_error ? 3 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* free file */
|
||||||
|
iso_file_source_unref(file);
|
||||||
|
|
||||||
|
if (action == 3) {
|
||||||
|
result = 1; /* prevent error to be passing up */
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
/* TODO check that action is 1!!! */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ok, node has correctly created, we need to add it */
|
||||||
|
if (flag) {
|
||||||
|
/* replace node */
|
||||||
|
new->next = (*pos)->next;
|
||||||
|
(*pos)->parent = NULL;
|
||||||
|
(*pos)->next = NULL;
|
||||||
|
iso_node_unref(*pos);
|
||||||
|
*pos = new;
|
||||||
|
new->parent = parent;
|
||||||
|
} else {
|
||||||
|
/* just add */
|
||||||
|
new->next = *pos;
|
||||||
|
*pos = new;
|
||||||
|
new->parent = parent;
|
||||||
|
++parent->nchildren;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* finally, if the node is a directory we need to recurse */
|
||||||
|
if (new->type == LIBISO_DIR) {
|
||||||
|
result = iso_add_dir_aux(image, (IsoDir*)new, file);
|
||||||
|
iso_file_source_unref(file);
|
||||||
|
if (result < 0) {
|
||||||
|
/* error */
|
||||||
|
if (image->recOpts->stop_on_error) {
|
||||||
|
action = 3; /* stop */
|
||||||
|
result = 1; /* prevent error to be passing up */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (result == 0) {
|
||||||
|
/* stop */
|
||||||
|
action = 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
iso_file_source_unref(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result < 0) {
|
||||||
|
// TODO printf message
|
||||||
|
action = result;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = dir->close(dir);
|
||||||
|
if (result < 0) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if (action < 0) {
|
||||||
|
return action; /* error */
|
||||||
|
} else if (action == 3) {
|
||||||
|
return 0; /* stop */
|
||||||
|
} else {
|
||||||
|
return 1; /* continue */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int iso_tree_add_dir_rec(IsoImage *image, IsoDir *parent, const char *dir)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
struct stat info;
|
||||||
|
IsoFilesystem *fs;
|
||||||
|
IsoFileSource *file;
|
||||||
|
|
||||||
|
if (image == NULL || parent == NULL || dir == NULL) {
|
||||||
|
return ISO_NULL_POINTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
fs = image->fs;
|
||||||
|
result = fs->get_by_path(fs, dir, &file);
|
||||||
|
if (result < 0) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we also allow dir path to be a symlink to a dir */
|
||||||
|
result = file->stat(file, &info);
|
||||||
|
if (result < 0) {
|
||||||
|
iso_file_source_unref(file);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!S_ISDIR(info.st_mode)) {
|
||||||
|
iso_file_source_unref(file);
|
||||||
|
return ISO_FILE_IS_NOT_DIR;
|
||||||
|
}
|
||||||
|
result = iso_add_dir_aux(image, parent, file);
|
||||||
|
iso_file_source_unref(file);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user