Simplify function to recursively add a directory.

This commit is contained in:
Vreixo Formoso 2008-01-20 16:56:41 +01:00
parent a86d6219ba
commit a076ae9df2
5 changed files with 108 additions and 136 deletions

View File

@ -10,7 +10,6 @@
#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>
@ -96,10 +95,8 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
return ISO_NULL_POINTER; return ISO_NULL_POINTER;
} }
name = iso_file_source_get_name(src);
/* get info about source */ /* get info about source */
if (image->recOpts.follow_symlinks) { if (iso_tree_get_follow_symlinks(image)) {
result = iso_file_source_stat(src, &info); result = iso_file_source_stat(src, &info);
} else { } else {
result = iso_file_source_lstat(src, &info); result = iso_file_source_lstat(src, &info);
@ -108,7 +105,9 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
return result; return result;
} }
name = iso_file_source_get_name(src);
new = NULL; new = NULL;
switch (info.st_mode & S_IFMT) { switch (info.st_mode & S_IFMT) {
case S_IFREG: case S_IFREG:
{ {

View File

@ -21,6 +21,9 @@
#define ISO_INTERRUPTED -5 #define ISO_INTERRUPTED -5
#define ISO_WRONG_ARG_VALUE -6 #define ISO_WRONG_ARG_VALUE -6
/* canceled by user */
#define ISO_ABORT -7
#define ISO_WRITE_ERROR -10 #define ISO_WRITE_ERROR -10
#define ISO_THREAD_ERROR -11 #define ISO_THREAD_ERROR -11

View File

@ -272,8 +272,8 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
* 0's to image * 0's to image
*/ */
char *name = iso_stream_get_name(file->stream); char *name = iso_stream_get_name(file->stream);
iso_msg_sorry(t->image->id, LIBISO_FILE_CANT_WRITE, iso_msg_sorry(t->image->id, LIBISO_FILE_CANT_WRITE, "File \"%s\" "
"File \"%s\" can't be opened. Filling with 0s.", name); "can't be opened (error %d). Filling with 0s.", name, res);
free(name); free(name);
memset(buffer, 0, BLOCK_SIZE); memset(buffer, 0, BLOCK_SIZE);
for (b = 0; b < nblocks; ++b) { for (b = 0; b < nblocks; ++b) {

View File

@ -68,23 +68,19 @@ struct Iso_Image_Rec_Opts
*/ */
enum iso_replace_mode replace; enum iso_replace_mode replace;
/* TODO
enum iso_replace_mode (*confirm_replace)(IsoFileSource *src, IsoNode *node);
*/
/** /**
* When this is not NULL, it is a pointer to a function that will * 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. * be called just before a file will be added. You can control where
* You can overwrite some of the above options by returning suitable * the file will be in fact added or ignored.
* 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 * @return
* 1 add/continue, 2 skip, 3 stop * 1 add, 0 ignore, < 0 cancel
*/ */
int (*report)(IsoFileSource *src, int action, int flag); int (*report)(IsoFileSource *src);
}; };
struct Iso_Image struct Iso_Image

View File

@ -468,16 +468,10 @@ int check_hidden(IsoImage *image, const char *name)
} }
static static
int check_special(IsoImage *image, IsoFileSource *file) int check_special(IsoImage *image, mode_t mode)
{ {
if (image->recOpts.ignore_special != 0) { if (image->recOpts.ignore_special != 0) {
struct stat info; switch(mode & S_IFMT) {
int ret;
ret = iso_file_source_lstat(file, &info);
if (ret < 0) {
return 0; /* TODO what to do here */
}
switch(info.st_mode & S_IFMT) {
case S_IFBLK: case S_IFBLK:
return image->recOpts.ignore_special & 0x08 ? 1 : 0; return image->recOpts.ignore_special & 0x08 ? 1 : 0;
case S_IFCHR: case S_IFCHR:
@ -501,140 +495,120 @@ int check_special(IsoImage *image, IsoFileSource *file)
*/ */
int iso_add_dir_src_rec(IsoImage *image, IsoDir *parent, IsoFileSource *dir) int iso_add_dir_src_rec(IsoImage *image, IsoDir *parent, IsoFileSource *dir)
{ {
int result; int ret;
int action; /* 1 add, 2 skip, 3 stop, < 0 error */
IsoNodeBuilder *builder; IsoNodeBuilder *builder;
IsoFileSource *file; IsoFileSource *file;
IsoNode **pos; IsoNode **pos;
struct stat info;
char *name, *path;
IsoNode *new;
enum iso_replace_mode replace;
result = iso_file_source_open(dir); ret = iso_file_source_open(dir);
if (result < 0) { if (ret < 0) {
char *path = iso_file_source_get_path(dir); char *path = iso_file_source_get_path(dir);
iso_msg_debug(image->id, "Can't open dir %s", path); iso_msg_debug(image->id, "Can't open dir %s", path);
free(path); free(path);
return result; return ret;
} }
builder = image->builder; builder = image->builder;
action = 1;
while ( (result = iso_file_source_readdir(dir, &file)) == 1) { /* iterate over all directory children */
int flag; while (1) {
char *name, *path; int skip = 0;
IsoNode *new;
name = iso_file_source_get_name(file); ret = iso_file_source_readdir(dir, &file);
path = iso_file_source_get_path(file); if (ret <= 0) {
if (ret < 0) {
if (check_excludes(image, path)) { /* error reading dir */
iso_msg_debug(image->id, "Skipping excluded file %s", path); iso_msg_sorry(image->id, LIBISO_CANT_READ_FILE,
action = 2; "Error reading dir");
} else if (check_hidden(image, name)) {
iso_msg_debug(image->id, "Skipping hidden file %s", path);
action = 2;
} else if (check_special(image, file)) {
iso_msg_debug(image->id, "Skipping special file %s", path);
action = 2;
} else {
iso_msg_debug(image->id, "Adding file %s", path);
action = 1;
}
free(path);
/* find place where to insert */
flag = 0;
if (iso_dir_exists(parent, name, &pos)) {
flag = 1;
if (action == 1 && image->recOpts.replace == ISO_REPLACE_NEVER) {
action = 2;
} }
}
/* name no more needed */
free(name);
/* 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; break;
} }
/* ok, file will be added */ path = iso_file_source_get_path(file);
result = builder->create_node(builder, image, file, &new); name = strrchr(path, '/') + 1;
if (result < 0) {
char *path = iso_file_source_get_path(file); if (image->recOpts.follow_symlinks) {
ret = iso_file_source_stat(file, &info);
} else {
ret = iso_file_source_lstat(file, &info);
}
if (ret < 0) {
goto dir_rec_continue;
}
if (check_excludes(image, path)) {
iso_msg_debug(image->id, "Skipping excluded file %s", path);
skip = 1;
} else if (check_hidden(image, name)) {
iso_msg_debug(image->id, "Skipping hidden file %s", path);
skip = 1;
} else if (check_special(image, info.st_mode)) {
iso_msg_debug(image->id, "Skipping special file %s", path);
skip = 1;
}
if (skip) {
goto dir_rec_continue;
}
replace = image->recOpts.replace;
/* find place where to insert */
ret = iso_dir_exists(parent, name, &pos);
/* TODO
* if (ret && replace == ISO_REPLACE_ASK) {
* replace = /....
* }
*/
/* chek if we must insert or not */
/* TODO check for other replace behavior */
if (ret && (replace == ISO_REPLACE_NEVER)) {
/* skip file */
goto dir_rec_continue;
}
/* if we are here we must insert. Give user a chance for cancel */
if (image->recOpts.report) {
int r = image->recOpts.report(file);
if (r <= 0) {
ret = (r < 0 ? ISO_ABORT : ISO_SUCCESS);
goto dir_rec_continue;
}
}
ret = builder->create_node(builder, image, file, &new);
if (ret < 0) {
iso_msg_note(image->id, LIBISO_FILE_IGNORED, iso_msg_note(image->id, LIBISO_FILE_IGNORED,
"Error %d when adding file %s", result, path); "Error %d when adding file %s", ret, path);
free(path); goto dir_rec_continue;
} else {
if (image->recOpts.report) { iso_msg_debug(image->id, "Adding file %s", path);
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 */ /* ok, node has correctly created, we need to add it */
iso_dir_insert(parent, new, pos, flag ? ISO_REPLACE_ALWAYS : iso_dir_insert(parent, new, pos, replace);
ISO_REPLACE_NEVER);
/* finally, if the node is a directory we need to recurse */ /* finally, if the node is a directory we need to recurse */
if (new->type == LIBISO_DIR) { if (new->type == LIBISO_DIR && S_ISDIR(info.st_mode)) {
result = iso_add_dir_src_rec(image, (IsoDir*)new, file); ret = iso_add_dir_src_rec(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) { dir_rec_continue:;
/* error reading dir, should never occur */ free(path);
iso_msg_sorry(image->id, LIBISO_CANT_READ_FILE, "Error reading dir"); iso_file_source_unref(file);
action = result;
} /* TODO check for error severity to decide what to do */
if (ret == ISO_ABORT || (ret < 0 && image->recOpts.stop_on_error)) {
break;
}
} /* while */
result = iso_file_source_close(dir); iso_file_source_close(dir);
if (result < 0) { return ret;
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 iso_tree_add_dir_rec(IsoImage *image, IsoDir *parent, const char *dir)