Simplify function to recursively add a directory.
This commit is contained in:
parent
a86d6219ba
commit
a076ae9df2
@ -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:
|
||||||
{
|
{
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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) {
|
||||||
|
20
src/image.h
20
src/image.h
@ -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
|
||||||
|
210
src/tree.c
210
src/tree.c
@ -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)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user