Add new exported file tree traverse functions.

This commit is contained in:
Klaas Freitag 2012-03-19 16:05:23 +01:00 committed by Dominik Schmidt
parent 4a0713370e
commit 254045780a
5 changed files with 174 additions and 17 deletions

View file

@ -491,6 +491,95 @@ int csync_propagate(CSYNC *ctx) {
return 0;
}
/*
* local visitor which calls the user visitor with repacked stat info.
*/
static int _csync_treewalk_visitor( void *obj, void *data ) {
csync_file_stat_t *cur = NULL;
CSYNC *ctx = NULL;
c_rbtree_visit_func *visitor = NULL;
_csync_treewalk_context *twctx = NULL;
TREE_WALK_FILE trav;
cur = (csync_file_stat_t *) obj;
ctx = (CSYNC *) data;
if( ctx )
twctx = (_csync_treewalk_context*) ctx->userdata;
if( twctx->instruction_filter > 0 && !(twctx->instruction_filter & cur->instruction) ) {
return 0;
}
if(cur && twctx) {
visitor = (c_rbtree_visit_func*)(twctx->user_visitor);
if(visitor) {
trav.path = cur->path;
trav.modtime = cur->modtime;
trav.uid = cur->uid;
trav.gid = cur->gid;
trav.mode = cur->mode;
trav.type = cur->type;
trav.instruction = cur->instruction;
return (*visitor)(&trav, twctx->userdata);
}
}
return -1;
}
/*
* treewalk function, called from its wrappers below.
*
* it encapsulates the user visitor function, the filter and the userdata
* into a treewalk_context structure and calls the rb treewalk function,
* which calls the local _csync_treewalk_visitor in this module.
* The user visitor is called from there.
*/
static int _csync_walk_tree(CSYNC *ctx, c_rbtree_t *tree, csync_treewalk_visit_func *visitor, int filter)
{
_csync_treewalk_context tw_ctx;
int rc = -1;
if( !(visitor && tree && ctx)) return rc;
tw_ctx.userdata = ctx->userdata;
tw_ctx.user_visitor = visitor;
tw_ctx.instruction_filter = filter;
ctx->userdata = &tw_ctx;
rc = c_rbtree_walk(tree, (void*) ctx, _csync_treewalk_visitor);
ctx->userdata = tw_ctx.userdata;
return rc;
}
/*
* wrapper function for treewalk on the remote tree
*/
int csync_walk_remote_tree(CSYNC *ctx, csync_treewalk_visit_func *visitor, int filter)
{
c_rbtree_t *tree = NULL;
if( ctx ) {
tree = ctx->remote.tree;
}
return _csync_walk_tree(ctx, tree, visitor, filter);
}
/*
* wrapper function for treewalk on the local tree
*/
int csync_walk_local_tree(CSYNC *ctx, csync_treewalk_visit_func *visitor, int filter)
{
c_rbtree_t *tree = NULL;
if( ctx ) {
tree = ctx->local.tree;
}
return _csync_walk_tree(ctx, tree, visitor, filter);
}
static void _tree_destructor(void *data) {
csync_file_stat_t *freedata = NULL;

View file

@ -32,11 +32,15 @@
#define _CSYNC_H
#include <stdbool.h>
#include <unistd.h>
#include <sys/types.h>
#ifdef __cplusplus
extern "C" {
#endif
#include "std/c_rbtree.h"
#define CSYNC_STRINGIFY(s) CSYNC_TOSTRING(s)
#define CSYNC_TOSTRING(s) #s
@ -69,6 +73,50 @@ extern "C" {
typedef int (*csync_auth_callback) (const char *prompt, char *buf, size_t len,
int echo, int verify, void *userdata);
/**
* Instruction enum. In the file traversal structure, it describes
* the csync state of a file.
*/
enum csync_instructions_e {
CSYNC_INSTRUCTION_NONE = 0x00000000,
CSYNC_INSTRUCTION_EVAL = 0x00000001,
CSYNC_INSTRUCTION_REMOVE = 0x00000002,
CSYNC_INSTRUCTION_RENAME = 0x00000004,
CSYNC_INSTRUCTION_NEW = 0x00000008,
CSYNC_INSTRUCTION_CONFLICT = 0x00000010,
CSYNC_INSTRUCTION_IGNORE = 0x00000020,
CSYNC_INSTRUCTION_SYNC = 0x00000040,
CSYNC_INSTRUCTION_STAT_ERROR = 0x00000080,
CSYNC_INSTRUCTION_ERROR = 0x00000100,
/* instructions for the propagator */
CSYNC_INSTRUCTION_DELETED = 0x00000200,
CSYNC_INSTRUCTION_UPDATED = 0x00000400
};
/**
* CSync File Traversal structure.
*
* This structure is passed to the visitor function for every file
* which is seen.
* Note: The file size is missing here because type off_t is depending
* on the large file support in your build. Make sure to check
* that cmake and the callback app are compiled with the same
* setting for it, such as:
* -D_LARGEFILE64_SOURCE or -D_LARGEFILE_SOURCE
*
*/
struct csync_tree_walk_file_s {
const char *path;
/* off_t size; */
time_t modtime;
uid_t uid;
gid_t gid;
mode_t mode;
int type;
enum csync_instructions_e instruction;
};
typedef struct csync_tree_walk_file_s TREE_WALK_FILE;
/**
* csync handle
*/
@ -307,6 +355,30 @@ int csync_get_status(CSYNC *ctx);
/* Used for special modes or debugging */
int csync_set_status(CSYNC *ctx, int status);
typedef int csync_treewalk_visit_func(TREE_WALK_FILE* ,void*);
/**
* @brief Walk the local file tree and call a visitor function for each file.
*
* @param ctx The csync context.
* @param visitor A callback function to handle the file info.
* @param filter A filter, built from and'ed csync_instructions_e
*
* @return 0 on success, less than 0 if an error occured.
*/
int csync_walk_local_tree(CSYNC *ctx, csync_treewalk_visit_func *visitor, int filter);
/**
* @brief Walk the remote file tree and call a visitor function for each file.
*
* @param ctx The csync context.
* @param visitor A callback function to handle the file info.
* @param filter A filter, built from and'ed csync_instructions_e
*
* @return 0 on success, less than 0 if an error occured.
*/
int csync_walk_remote_tree(CSYNC *ctx, csync_treewalk_visit_func *visitor, int filter);
#ifdef __cplusplus
}
#endif

View file

@ -140,22 +140,6 @@ enum csync_ftw_type_e {
CSYNC_FTW_TYPE_DIR
};
enum csync_instructions_e {
CSYNC_INSTRUCTION_NONE,
CSYNC_INSTRUCTION_EVAL,
CSYNC_INSTRUCTION_REMOVE,
CSYNC_INSTRUCTION_RENAME,
CSYNC_INSTRUCTION_NEW,
CSYNC_INSTRUCTION_CONFLICT,
CSYNC_INSTRUCTION_IGNORE,
CSYNC_INSTRUCTION_SYNC,
CSYNC_INSTRUCTION_STAT_ERROR,
CSYNC_INSTRUCTION_ERROR,
/* instructions for the propagator */
CSYNC_INSTRUCTION_DELETED,
CSYNC_INSTRUCTION_UPDATED
};
#ifdef _MSC_VER
#pragma pack(1)
#endif
@ -183,6 +167,17 @@ __attribute__ ((packed))
typedef struct csync_file_stat_s csync_file_stat_t;
/*
* context for the treewalk function
*/
struct _csync_treewalk_context_s
{
csync_treewalk_visit_func *user_visitor;
int instruction_filter;
void *userdata;
};
typedef struct _csync_treewalk_context_s _csync_treewalk_context;
/**
* }@
*/

View file

@ -141,6 +141,7 @@ out:
st->phash = h;
st->pathlen = len;
memcpy(st->path, (len ? path : ""), len + 1);
printf("OOOO %s (%d)\n", path, len );
switch (ctx->current) {
case LOCAL_REPLICA:

View file

@ -103,7 +103,7 @@ typedef int c_rbtree_compare_func(const void *key, const void *data);
* @return 0 on success, < 0 on error. You should set errno.
*
*/
typedef int c_rbtree_visit_func(void *obj, void *data);
typedef int c_rbtree_visit_func(void *, void *);
/**
* Structure that represents a red-black tree