From 4644c39f5a40c2bcb08f828b72b84e22780e1346 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Thu, 17 Apr 2008 18:02:41 +0200 Subject: [PATCH] Implement module init and shutdown functions. --- src/csync_private.h | 8 +++- src/vio/csync_vio.c | 78 +++++++++++++++++++++++++++++++++++++- src/vio/csync_vio.h | 4 +- src/vio/csync_vio_method.h | 4 ++ 4 files changed, 90 insertions(+), 4 deletions(-) diff --git a/src/csync_private.h b/src/csync_private.h index a338bcb60..9f04293b4 100644 --- a/src/csync_private.h +++ b/src/csync_private.h @@ -39,6 +39,7 @@ #include "c_lib.h" #include "csync.h" +#include "vio/csync_vio_method.h" #include "csync_macros.h" /** @@ -69,7 +70,12 @@ struct csync_s { c_rbtree_t *remote; c_strlist_t *excludes; sqlite3 *journal; - void *plugin_handle; + + struct { + void *handle; + csync_vio_method_t *method; + csync_vio_method_finish_fn finish_fn; + } module; struct { int max_depth; diff --git a/src/vio/csync_vio.c b/src/vio/csync_vio.c index 82d3d2796..19f5c7f3e 100644 --- a/src/vio/csync_vio.c +++ b/src/vio/csync_vio.c @@ -20,8 +20,84 @@ * vim: ts=2 sw=2 et cindent */ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#include +#include /* dlopen(), dlclose(), dlsym() ... */ + +#include "csync_private.h" #include "vio/csync_vio.h" -int csync_vfs_init(void) { +#define CSYNC_LOG_CATEGORY_NAME "csync.vio.main" +#include "csync_log.h" + +int csync_vio_init(CSYNC *ctx, const char *module, const char *args) { + char *path = NULL; + char *err = NULL; + csync_vio_method_t *m; + csync_vio_method_init_fn init_fn; + + if (asprintf(&path, "%s/csync_%s.so", PLUGINDIR, module) < 0) { + return -1; + } + if ((err = dlerror()) == NULL) { + CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "loading %s plugin failed - %s", + module, err); + } + + ctx->module.handle = dlopen(path, RTLD_LAZY); + + SAFE_FREE(path); + + init_fn = dlsym(ctx->module.handle, "vio_module_init"); + if ((err = dlerror()) == NULL) { + CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "loading function failed - %s", err); + return -1; + } + + ctx->module.finish_fn = dlsym(ctx->module.handle, "vio_module_finish"); + if ((err = dlerror()) == NULL) { + CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "loading function failed - %s", err); + return -1; + } + + /* get the method struct */ + m = (*init_fn)(module, args); + if (m == NULL) { + CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "module %s return a NULL method", module); + return -1; + } + + /* Some basic checks */ + if (m->method_table_size == 0) { + CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "module %s method table size is 0", module); + return -1; + } + + if (! VIO_METHOD_HAS_FUNC(m, open)) { + CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "module %s has no open fn", module); + return -1; + } + + if (! VIO_METHOD_HAS_FUNC(m, open)) { + CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "module %s has no stat fn", module); + return -1; + } + + ctx->module.method = m; + return 0; } + +void csync_vio_shutdown(CSYNC *ctx) { + if (ctx->module.handle != NULL) { + dlclose(ctx->module.handle); + ctx->module.handle = NULL; + + ctx->module.method = NULL; + ctx->module.finish_fn = NULL; + } +} + diff --git a/src/vio/csync_vio.h b/src/vio/csync_vio.h index 00498db73..79dc2bd31 100644 --- a/src/vio/csync_vio.h +++ b/src/vio/csync_vio.h @@ -26,8 +26,8 @@ #include "vio/csync_vio_handle.h" #include "vio/csync_vio_file_stat.h" -int csync_vio_init(void); -int csync_vio_shutdown(void); +int csync_vio_init(CSYNC *ctx, const char *module, const char *args); +void csync_vio_shutdown(CSYNC *ctx); csync_vio_handle_t *csync_vio_open(const char *uri, int flags, mode_t mode); csync_vio_handle_t *csync_vio_creat(const char *uri, mode_t mode); diff --git a/src/vio/csync_vio_method.h b/src/vio/csync_vio_method.h index 60f689e33..c65c78d7c 100644 --- a/src/vio/csync_vio_method.h +++ b/src/vio/csync_vio_method.h @@ -28,6 +28,10 @@ #include "vio/csync_vio_file_stat.h" #include "vio/csync_vio_handle.h" +#define VIO_METHOD_HAS_FUNC(method,func) \ + ((((char *)&((method)->func)) - ((char *)(method)) < (method)->method_table_size) \ + && method->func != NULL) + typedef struct csync_vio_method_s csync_vio_method_t; typedef csync_vio_method_t *(*csync_vio_method_init_fn)(const char *method_name, const char *config_args);