Added a csync_errno function to provide more info for clients.

This commit is contained in:
Klaas Freitag 2012-03-30 15:33:13 +02:00
parent bf53697664
commit cc87c0629a
2 changed files with 148 additions and 15 deletions

View File

@ -50,6 +50,7 @@
#define CSYNC_LOG_CATEGORY_NAME "csync.api"
#include "csync_log.h"
static enum csync_error_codes_e _csync_errno;
static int _key_cmp(const void *key, const void *data) {
uint64_t a;
@ -88,8 +89,11 @@ int csync_create(CSYNC **csync, const char *local, const char *remote) {
char *home;
int rc;
_csync_errno = CSYNC_ERR_NONE;
ctx = c_malloc(sizeof(CSYNC));
if (ctx == NULL) {
_csync_errno = CSYNC_ERR_MEM;
return -1;
}
@ -99,6 +103,7 @@ int csync_create(CSYNC **csync, const char *local, const char *remote) {
ctx->local.uri = c_strndup(local, len);
if (ctx->local.uri == NULL) {
_csync_errno = CSYNC_ERR_MEM;
return -1;
}
@ -109,6 +114,7 @@ int csync_create(CSYNC **csync, const char *local, const char *remote) {
ctx->remote.uri = c_strndup(remote, len);
if (ctx->remote.uri == NULL) {
SAFE_FREE(ctx->remote.uri);
_csync_errno = CSYNC_ERR_MEM;
return -1;
}
@ -127,6 +133,7 @@ int csync_create(CSYNC **csync, const char *local, const char *remote) {
SAFE_FREE(ctx->remote.uri);
SAFE_FREE(ctx);
errno = ENOMEM;
_csync_errno = CSYNC_ERR_MEM;
return -1;
}
@ -137,6 +144,7 @@ int csync_create(CSYNC **csync, const char *local, const char *remote) {
SAFE_FREE(ctx->remote.uri);
SAFE_FREE(ctx);
errno = ENOMEM;
_csync_errno = CSYNC_ERR_MEM;
return -1;
}
@ -154,7 +162,10 @@ int csync_init(CSYNC *ctx) {
#ifndef _WIN32
char errbuf[256] = {0};
#endif
_csync_errno = CSYNC_ERR_NONE;
if (ctx == NULL) {
_csync_errno = CSYNC_ERR_UNSPEC;
errno = EBADF;
return -1;
}
@ -166,6 +177,7 @@ int csync_init(CSYNC *ctx) {
/* load log file */
if (csync_log_init() < 0) {
_csync_errno = CSYNC_ERR_LOG;
fprintf(stderr, "csync_init: logger init failed\n");
return -1;
}
@ -176,6 +188,7 @@ int csync_init(CSYNC *ctx) {
}
if (asprintf(&log, "%s/%s", ctx->options.config_dir, CSYNC_LOG_FILE) < 0) {
_csync_errno = CSYNC_ERR_UNSPEC;
rc = -1;
goto out;
}
@ -193,12 +206,14 @@ int csync_init(CSYNC *ctx) {
/* create lock file */
if (asprintf(&lock, "%s/%s", ctx->options.config_dir, CSYNC_LOCK_FILE) < 0) {
_csync_errno = CSYNC_ERR_UNSPEC;
rc = -1;
goto out;
}
#ifndef _WIN32
if (csync_lock(lock) < 0) {
_csync_errno = CSYNC_ERR_LOCK;
rc = -1;
goto out;
}
@ -217,6 +232,7 @@ int csync_init(CSYNC *ctx) {
#ifndef _WIN32
/* load global exclude list */
if (asprintf(&exclude, "%s/csync/%s", SYSCONFDIR, CSYNC_EXCLUDE_FILE) < 0) {
_csync_errno = CSYNC_ERR_UNSPEC;
rc = -1;
goto out;
}
@ -229,8 +245,8 @@ int csync_init(CSYNC *ctx) {
SAFE_FREE(exclude);
/* load exclude list */
if (asprintf(&exclude, "%s/%s", ctx->options.config_dir,
CSYNC_EXCLUDE_FILE) < 0) {
if (asprintf(&exclude, "%s/%s", ctx->options.config_dir, CSYNC_EXCLUDE_FILE) < 0) {
_csync_errno = CSYNC_ERR_UNSPEC;
rc = -1;
goto out;
}
@ -247,6 +263,7 @@ int csync_init(CSYNC *ctx) {
uint64_t h = csync_create_statedb_hash(ctx);
if (asprintf(&ctx->statedb.file, "%s/csync_statedb_%llu.db",
ctx->options.config_dir, (long long unsigned int) h) < 0) {
_csync_errno = CSYNC_ERR_UNSPEC;
rc = -1;
goto out;
}
@ -254,6 +271,7 @@ int csync_init(CSYNC *ctx) {
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Statedb: %s", ctx->statedb.file);
if (csync_statedb_load(ctx, ctx->statedb.file) < 0) {
_csync_errno = CSYNC_ERR_STATEDB_LOAD;
rc = -1;
goto out;
}
@ -271,6 +289,7 @@ int csync_init(CSYNC *ctx) {
/* module name */
module = c_strndup(ctx->remote.uri, len);
if (module == NULL) {
_csync_errno = CSYNC_ERR_MODULE;
rc = -1;
goto out;
}
@ -301,27 +320,32 @@ retry_vio_init:
CSYNC_LOG(CSYNC_LOG_PRIORITY_FATAL,
"Clock skew detected. The time difference is greater than %d seconds!",
ctx->options.max_time_difference);
_csync_errno = CSYNC_ERR_TIMESKEW;
rc = -1;
goto out;
} else if (timediff < 0) {
CSYNC_LOG(CSYNC_LOG_PRIORITY_FATAL, "Synchronisation is not possible!");
_csync_errno = CSYNC_ERR_TIMESKEW;
rc = -1;
goto out;
}
if (csync_unix_extensions(ctx) < 0) {
CSYNC_LOG(CSYNC_LOG_PRIORITY_FATAL, "Could not detect filesystem type.");
_csync_errno = CSYNC_ERR_FILESYSTEM;
rc = -1;
goto out;
}
}
if (c_rbtree_create(&ctx->local.tree, _key_cmp, _data_cmp) < 0) {
_csync_errno = CSYNC_ERR_TREE;
rc = -1;
goto out;
}
if (c_rbtree_create(&ctx->remote.tree, _key_cmp, _data_cmp) < 0) {
_csync_errno = CSYNC_ERR_TREE;
rc = -1;
goto out;
}
@ -341,9 +365,11 @@ out:
int csync_update(CSYNC *ctx) {
int rc = -1;
struct timespec start, finish;
_csync_errno = CSYNC_ERR_NONE;
if (ctx == NULL) {
errno = EBADF;
_csync_errno = CSYNC_ERR_PARAM;
return -1;
}
@ -364,6 +390,7 @@ int csync_update(CSYNC *ctx) {
csync_memstat_check();
if (rc < 0) {
_csync_errno = CSYNC_ERR_TREE;
return -1;
}
@ -384,6 +411,7 @@ int csync_update(CSYNC *ctx) {
csync_memstat_check();
if (rc < 0) {
_csync_errno = CSYNC_ERR_TREE;
return -1;
}
}
@ -396,7 +424,10 @@ int csync_reconcile(CSYNC *ctx) {
int rc = -1;
struct timespec start, finish;
_csync_errno = CSYNC_ERR_NONE;
if (ctx == NULL) {
_csync_errno = CSYNC_ERR_PARAM;
errno = EBADF;
return -1;
}
@ -416,6 +447,7 @@ int csync_reconcile(CSYNC *ctx) {
c_secdiff(finish, start), c_rbtree_size(ctx->local.tree));
if (rc < 0) {
_csync_errno = CSYNC_ERR_RECONCILE;
return -1;
}
@ -434,6 +466,7 @@ int csync_reconcile(CSYNC *ctx) {
c_secdiff(finish, start), c_rbtree_size(ctx->remote.tree));
if (rc < 0) {
_csync_errno = CSYNC_ERR_RECONCILE;
return -1;
}
@ -446,7 +479,10 @@ int csync_propagate(CSYNC *ctx) {
int rc = -1;
struct timespec start, finish;
_csync_errno = CSYNC_ERR_NONE;
if (ctx == NULL) {
_csync_errno = CSYNC_ERR_PARAM;
errno = EBADF;
return -1;
}
@ -466,6 +502,7 @@ int csync_propagate(CSYNC *ctx) {
c_secdiff(finish, start), c_rbtree_size(ctx->local.tree));
if (rc < 0) {
_csync_errno = CSYNC_ERR_PROPAGATE;
return -1;
}
@ -484,6 +521,7 @@ int csync_propagate(CSYNC *ctx) {
c_secdiff(finish, start), c_rbtree_size(ctx->remote.tree));
if (rc < 0) {
_csync_errno = CSYNC_ERR_PROPAGATE;
return -1;
}
@ -496,12 +534,14 @@ int csync_propagate(CSYNC *ctx) {
* 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_file_stat_t *cur = NULL;
CSYNC *ctx = NULL;
c_rbtree_visit_func *visitor = NULL;
_csync_treewalk_context *twctx = NULL;
TREE_WALK_FILE trav;
_csync_errno = CSYNC_ERR_NONE;
cur = (csync_file_stat_t *) obj;
ctx = (CSYNC *) data;
if( ctx )
@ -524,6 +564,7 @@ static int _csync_treewalk_visitor( void *obj, void *data ) {
return (*visitor)(&trav, twctx->userdata);
}
}
_csync_errno = CSYNC_ERR_TREE;
return -1;
}
@ -539,9 +580,13 @@ static int _csync_walk_tree(CSYNC *ctx, c_rbtree_t *tree, csync_treewalk_visit_f
{
_csync_treewalk_context tw_ctx;
int rc = -1;
if( !(visitor && tree && ctx)) return rc;
_csync_errno = CSYNC_ERR_NONE;
if( !(visitor && tree && ctx)) {
_csync_errno = CSYNC_ERR_PARAM;
return rc;
}
tw_ctx.userdata = ctx->userdata;
tw_ctx.user_visitor = visitor;
tw_ctx.instruction_filter = filter;
@ -549,7 +594,9 @@ static int _csync_walk_tree(CSYNC *ctx, c_rbtree_t *tree, csync_treewalk_visit_f
ctx->userdata = &tw_ctx;
rc = c_rbtree_walk(tree, (void*) ctx, _csync_treewalk_visitor);
if( rc < 0 )
_csync_errno = CSYNC_ERR_TREE;
ctx->userdata = tw_ctx.userdata;
return rc;
@ -561,11 +608,17 @@ static int _csync_walk_tree(CSYNC *ctx, c_rbtree_t *tree, csync_treewalk_visit_f
int csync_walk_remote_tree(CSYNC *ctx, csync_treewalk_visit_func *visitor, int filter)
{
c_rbtree_t *tree = NULL;
if( ctx ) {
int rc = -1;
_csync_errno = CSYNC_ERR_NONE;
if(ctx) {
tree = ctx->remote.tree;
}
return _csync_walk_tree(ctx, tree, visitor, filter);
rc = _csync_walk_tree(ctx, tree, visitor, filter);
if(rc < 0)
_csync_errno = CSYNC_ERR_TREE;
return rc;
}
/*
@ -574,15 +627,21 @@ int csync_walk_remote_tree(CSYNC *ctx, csync_treewalk_visit_func *visitor, int
int csync_walk_local_tree(CSYNC *ctx, csync_treewalk_visit_func *visitor, int filter)
{
c_rbtree_t *tree = NULL;
int rc = -1;
_csync_errno = CSYNC_ERR_NONE;
if( ctx ) {
if(ctx) {
tree = ctx->local.tree;
}
return _csync_walk_tree(ctx, tree, visitor, filter);
rc = _csync_walk_tree(ctx, tree, visitor, filter);
if(rc < 0)
_csync_errno = CSYNC_ERR_TREE;
return rc;
}
static void _tree_destructor(void *data) {
csync_file_stat_t *freedata = NULL;
_csync_errno = CSYNC_ERR_NONE;
freedata = (csync_file_stat_t *) data;
SAFE_FREE(freedata);
@ -594,7 +653,10 @@ int csync_destroy(CSYNC *ctx) {
char errbuf[256] = {0};
int jwritten = 0;
_csync_errno = CSYNC_ERR_NONE;
if (ctx == NULL) {
_csync_errno = CSYNC_ERR_PARAM;
errno = EBADF;
return -1;
}
@ -670,6 +732,8 @@ int csync_destroy(CSYNC *ctx) {
/* Check if csync is the required version or get the version string. */
const char *csync_version(int req_version) {
_csync_errno = CSYNC_ERR_NONE;
if (req_version <= LIBCSYNC_VERSION_INT) {
return CSYNC_STRINGIFY(LIBCSYNC_VERSION);
}
@ -678,6 +742,8 @@ const char *csync_version(int req_version) {
}
int csync_add_exclude_list(CSYNC *ctx, const char *path) {
_csync_errno = CSYNC_ERR_NONE;
if (ctx == NULL || path == NULL) {
return -1;
}
@ -686,6 +752,8 @@ int csync_add_exclude_list(CSYNC *ctx, const char *path) {
}
const char *csync_get_config_dir(CSYNC *ctx) {
_csync_errno = CSYNC_ERR_NONE;
if (ctx == NULL) {
return NULL;
}
@ -694,13 +762,17 @@ const char *csync_get_config_dir(CSYNC *ctx) {
}
int csync_set_config_dir(CSYNC *ctx, const char *path) {
_csync_errno = CSYNC_ERR_NONE;
if (ctx == NULL || path == NULL) {
_csync_errno = CSYNC_ERR_PARAM;
return -1;
}
SAFE_FREE(ctx->options.config_dir);
ctx->options.config_dir = c_strdup(path);
if (ctx->options.config_dir == NULL) {
_csync_errno = CSYNC_ERR_MEM;
return -1;
}
@ -708,11 +780,14 @@ int csync_set_config_dir(CSYNC *ctx, const char *path) {
}
int csync_enable_statedb(CSYNC *ctx) {
_csync_errno = CSYNC_ERR_NONE;
if (ctx == NULL) {
_csync_errno = CSYNC_ERR_MEM;
return -1;
}
if (ctx->status & CSYNC_STATUS_INIT) {
_csync_errno = CSYNC_ERR_UNSPEC;
fprintf(stderr, "This function must be called before initialization.");
return -1;
}
@ -723,11 +798,14 @@ int csync_enable_statedb(CSYNC *ctx) {
}
int csync_disable_statedb(CSYNC *ctx) {
_csync_errno = CSYNC_ERR_NONE;
if (ctx == NULL) {
_csync_errno = CSYNC_ERR_PARAM;
return -1;
}
if (ctx->status & CSYNC_STATUS_INIT) {
_csync_errno = CSYNC_ERR_UNSPEC;
fprintf(stderr, "This function must be called before initialization.");
return -1;
}
@ -738,7 +816,9 @@ int csync_disable_statedb(CSYNC *ctx) {
}
int csync_is_statedb_disabled(CSYNC *ctx) {
_csync_errno = CSYNC_ERR_NONE;
if (ctx == NULL) {
_csync_errno = CSYNC_ERR_PARAM;
return -1;
}
@ -746,12 +826,15 @@ int csync_is_statedb_disabled(CSYNC *ctx) {
}
int csync_set_auth_callback(CSYNC *ctx, csync_auth_callback cb) {
_csync_errno = CSYNC_ERR_NONE;
if (ctx == NULL || cb == NULL) {
_csync_errno = CSYNC_ERR_PARAM;
return -1;
}
if (ctx->status & CSYNC_STATUS_INIT) {
fprintf(stderr, "This function must be called before initialization.");
_csync_errno = CSYNC_ERR_UNSPEC;
return -1;
}
@ -761,7 +844,9 @@ int csync_set_auth_callback(CSYNC *ctx, csync_auth_callback cb) {
}
const char *csync_get_statedb_file(CSYNC *ctx) {
_csync_errno = CSYNC_ERR_NONE;
if (ctx == NULL) {
_csync_errno = CSYNC_ERR_PARAM;
return NULL;
}
@ -769,7 +854,9 @@ const char *csync_get_statedb_file(CSYNC *ctx) {
}
void *csync_get_userdata(CSYNC *ctx) {
_csync_errno = CSYNC_ERR_NONE;
if (ctx == NULL) {
_csync_errno = CSYNC_ERR_PARAM;
return NULL;
}
@ -777,7 +864,9 @@ void *csync_get_userdata(CSYNC *ctx) {
}
int csync_set_userdata(CSYNC *ctx, void *userdata) {
_csync_errno = CSYNC_ERR_NONE;
if (ctx == NULL) {
_csync_errno = CSYNC_ERR_PARAM;
return -1;
}
@ -787,7 +876,9 @@ int csync_set_userdata(CSYNC *ctx, void *userdata) {
}
csync_auth_callback csync_get_auth_callback(CSYNC *ctx) {
_csync_errno = CSYNC_ERR_NONE;
if (ctx == NULL) {
_csync_errno = CSYNC_ERR_PARAM;
return NULL;
}
@ -795,7 +886,9 @@ csync_auth_callback csync_get_auth_callback(CSYNC *ctx) {
}
int csync_set_status(CSYNC *ctx, int status) {
_csync_errno = CSYNC_ERR_NONE;
if (ctx == NULL || status < 0) {
_csync_errno = CSYNC_ERR_PARAM;
return -1;
}
@ -805,7 +898,9 @@ int csync_set_status(CSYNC *ctx, int status) {
}
int csync_get_status(CSYNC *ctx) {
_csync_errno = CSYNC_ERR_NONE;
if (ctx == NULL) {
_csync_errno = CSYNC_ERR_PARAM;
return -1;
}
@ -813,12 +908,15 @@ int csync_get_status(CSYNC *ctx) {
}
int csync_enable_conflictcopys(CSYNC* ctx){
_csync_errno = CSYNC_ERR_NONE;
if (ctx == NULL) {
_csync_errno = CSYNC_ERR_PARAM;
return -1;
}
if (ctx->status & CSYNC_STATUS_INIT) {
fprintf(stderr, "This function must be called before initialization.");
_csync_errno = CSYNC_ERR_UNSPEC;
return -1;
}
@ -828,12 +926,15 @@ int csync_enable_conflictcopys(CSYNC* ctx){
}
int csync_set_local_only( CSYNC *ctx, bool local_only ) {
_csync_errno = CSYNC_ERR_NONE;
if (ctx == NULL) {
_csync_errno = CSYNC_ERR_PARAM;
return -1;
}
if (ctx->status & CSYNC_STATUS_INIT) {
fprintf(stderr, "This function must be called before initialization.");
_csync_errno = CSYNC_ERR_UNSPEC;
return -1;
}
@ -843,11 +944,17 @@ int csync_set_local_only( CSYNC *ctx, bool local_only ) {
}
bool csync_get_local_only( CSYNC *ctx ) {
_csync_errno = CSYNC_ERR_NONE;
if (ctx == NULL) {
_csync_errno = CSYNC_ERR_PARAM;
return -1;
}
return ctx->options.local_only_mode;
}
CSYNC_ERROR_CODE csync_errno(void) {
return _csync_errno;
}
/* vim: set ts=8 sw=2 et cindent: */

View File

@ -71,6 +71,24 @@ extern "C" {
typedef int (*csync_auth_callback) (const char *prompt, char *buf, size_t len,
int echo, int verify, void *userdata);
enum csync_error_codes_e {
CSYNC_ERR_NONE = 0,
CSYNC_ERR_LOG,
CSYNC_ERR_LOCK,
CSYNC_ERR_STATEDB_LOAD,
CSYNC_ERR_MODULE,
CSYNC_ERR_TIMESKEW,
CSYNC_ERR_FILESYSTEM,
CSYNC_ERR_TREE,
CSYNC_ERR_MEM,
CSYNC_ERR_PARAM,
CSYNC_ERR_RECONCILE,
CSYNC_ERR_PROPAGATE,
CSYNC_ERR_UNSPEC,
};
typedef enum csync_error_codes_e CSYNC_ERROR_CODE;
/**
* Instruction enum. In the file traversal structure, it describes
* the csync state of a file.
@ -382,6 +400,14 @@ int csync_walk_local_tree(CSYNC *ctx, csync_treewalk_visit_func *visitor, int fi
*/
int csync_walk_remote_tree(CSYNC *ctx, csync_treewalk_visit_func *visitor, int filter);
/**
* @brief Get the error code from the last operation.
*
* @return An error code defined by structure CSYNC_ERROR_CODE
*/
CSYNC_ERROR_CODE csync_errno(void);
#ifdef __cplusplus
}
#endif