cram-md5.c crc32.c crypto.c daemon.c edit.c fnmatch.c \
guid_to_name.c hmac.c jcr.c lex.c alist.c dlist.c \
md5.c message.c mem_pool.c openssl.c parse_conf.c \
- queue.c bregex.c \
+ plugin.c queue.c bregex.c \
res.c rwlock.c scan.c serial.c sha1.c \
signal.c smartall.c rblist.c tls.c tree.c \
util.c var.c watchdog.c workq.c btimers.c \
cram-md5.o crc32.o crypto.o daemon.o edit.o fnmatch.o \
guid_to_name.o hmac.o jcr.o lex.o alist.o dlist.o \
md5.o message.o mem_pool.o openssl.o parse_conf.o \
- queue.o bregex.o \
+ plugin.o queue.o bregex.o \
res.o rwlock.o scan.o serial.o sha1.o \
signal.o smartall.o rblist.o tls.o tree.o \
util.o var.o watchdog.o workq.o btimers.o \
$(CXX) $(LDFLAGS) -L. -o $@ bsnprintf.o $(LIBS) $(DLIB) -lbac $(OPENSSL_LIBS) -lm
rm -f bsnprintf.o
$(CXX) $(DEFS) $(DEBUG) -c $(CPPFLAGS) -I$(srcdir) -I$(basedir) $(DINCLUDE) $(CFLAGS) bsnprintf.c
-
+
+plugin.o: plugin.c
+ $(NO_ECHO)$(CXX) -fPIC $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) -I$(srcdir) -I$(basedir) $(DINCLUDE) $(CFLAGS) $<
+
install:
--- /dev/null
+/*
+ Bacula® - The Network Backup Solution
+
+ Copyright (C) 2007-2007 Free Software Foundation Europe e.V.
+
+ The main author of Bacula is Kern Sibbald, with contributions from
+ many others, a complete list can be found in the file AUTHORS.
+ This program is Free Software; you can redistribute it and/or
+ modify it under the terms of version two of the GNU General Public
+ License as published by the Free Software Foundation, which is
+ listed in the file LICENSE.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+ Bacula® is a registered trademark of John Walker.
+ The licensor of Bacula is the Free Software Foundation Europe
+ (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
+ Switzerland, email:ftf@fsfeurope.org.
+*/
+/*
+ * Plugin load/unloader for all Bacula daemons
+ *
+ * Kern Sibbald, October 2007
+ */
+#include "bacula.h"
+#include <dlfcn.h>
+#include "plugin.h"
+
+/* All loaded plugins */
+alist *plugin_list;
+
+/*
+ * Create a new plugin "class" entry and enter it in the
+ * list of plugins. Note, this is not the same as
+ * an instance of the plugin.
+ */
+Plugin *new_plugin()
+{
+ Plugin *plugin;
+
+ plugin = (Plugin *)malloc(sizeof(Plugin));
+ memset(plugin, 0, sizeof(Plugin));
+ plugin_list->append(plugin);
+ return plugin;
+}
+
+
+/*
+ * Load all the plugins in the specified directory.
+ */
+bool load_plugins(void *bfuncs, const char *plugin_dir, const char *type)
+{
+ t_loadPlugin loadPlugin;
+ Plugin *plugin;
+ char *error;
+ DIR* dp = NULL;
+ struct dirent *entry, *result;
+ int name_max;
+ struct stat statp;
+ bool found = false;
+ POOL_MEM fname(PM_FNAME);
+ bool need_slash = false;
+ int len, type_len;
+
+ plugin = new_plugin();
+
+ name_max = pathconf(".", _PC_NAME_MAX);
+ if (name_max < 1024) {
+ name_max = 1024;
+ }
+
+ if (!(dp = opendir(plugin_dir))) {
+ berrno be;
+ Dmsg2(29, "load_plugins: failed to open dir %s: ERR=%s\n",
+ plugin_dir, be.bstrerror());
+ goto get_out;
+ }
+
+ len = strlen(plugin_dir);
+ if (len > 0) {
+ need_slash = !IsPathSeparator(plugin_dir[len - 1]);
+ }
+ entry = (struct dirent *)malloc(sizeof(struct dirent) + name_max + 1000);
+ for ( ;; ) {
+ if ((readdir_r(dp, entry, &result) != 0) || (result == NULL)) {
+ Dmsg1(129, "load_plugins: failed to find suitable file in dir %s\n",
+ plugin_dir);
+ break;
+ }
+ if (strcmp(result->d_name, ".") == 0 ||
+ strcmp(result->d_name, "..") == 0) {
+ continue;
+ }
+
+ len = strlen(result->d_name);
+ type_len = strlen(type);
+ if (len < type_len+1 || strcmp(&result->d_name[len-type_len], type) != 0) {
+ continue;
+ }
+ printf("Got: name=%s len=%d\n", result->d_name, len);
+
+ pm_strcpy(fname, plugin_dir);
+ if (need_slash) {
+ pm_strcat(fname, "/");
+ }
+ pm_strcat(fname, result->d_name);
+ if (lstat(fname.c_str(), &statp) != 0 || !S_ISREG(statp.st_mode)) {
+ continue; /* ignore directories & special files */
+ }
+
+ plugin->file = bstrdup(result->d_name);
+ plugin->pHandle = dlopen(fname.c_str(), RTLD_NOW);
+ if (!plugin->pHandle) {
+ printf("dlopen of %s failed: ERR=%s\n", fname.c_str(), dlerror());
+ goto get_out;
+ }
+
+ /* Get two global entry points */
+ loadPlugin = (t_loadPlugin)dlsym(plugin->pHandle, "loadPlugin");
+ if ((error=dlerror()) != NULL) {
+ printf("dlsym failed: ERR=%s\n", error);
+ goto get_out;
+ }
+ plugin->unloadPlugin = (t_unloadPlugin)dlsym(plugin->pHandle, "unloadPlugin");
+ if ((error=dlerror()) != NULL) {
+ printf("dlsym failed: ERR=%s\n", error);
+ goto get_out;
+ }
+
+ /* Initialize the plugin */
+ loadPlugin(bfuncs, &plugin->pfuncs);
+
+ found = true; /* found a plugin */
+ }
+
+get_out:
+ free(entry);
+ if (dp) {
+ closedir(dp);
+ }
+ return found;
+}
+
+/*
+ * Unload all the loaded plugins
+ */
+void unload_plugins()
+{
+ Plugin *plugin;
+
+ foreach_alist(plugin, plugin_list) {
+ /* Shut it down and unload it */
+ plugin->unloadPlugin();
+ dlclose(plugin->pHandle);
+ if (plugin->file) {
+ free(plugin->file);
+ }
+ free(plugin);
+ }
+ delete plugin_list;
+ plugin_list = NULL;
+}
--- /dev/null
+/*
+ Bacula® - The Network Backup Solution
+
+ Copyright (C) 2007-2007 Free Software Foundation Europe e.V.
+
+ The main author of Bacula is Kern Sibbald, with contributions from
+ many others, a complete list can be found in the file AUTHORS.
+ This program is Free Software; you can redistribute it and/or
+ modify it under the terms of version two of the GNU General Public
+ License as published by the Free Software Foundation, which is
+ listed in the file LICENSE.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+ Bacula® is a registered trademark of John Walker.
+ The licensor of Bacula is the Free Software Foundation Europe
+ (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
+ Switzerland, email:ftf@fsfeurope.org.
+*/
+/*
+ * Bacula plugin loader/unloader
+ *
+ * Kern Sibbald, October 2007
+ */
+#ifndef __PLUGIN_H
+#define __PLUGIN_H
+
+#include "bacula.h"
+#include <dlfcn.h>
+#ifdef HAVE_DIRENT_H
+#include <dirent.h>
+#define NAMELEN(dirent) (strlen((dirent)->d_name))
+#endif
+#ifndef HAVE_READDIR_R
+int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result);
+#endif
+
+#ifndef RTLD_NOW
+#define RTLD_NOW 2
+#endif
+
+/****************************************************************************
+ * *
+ * Common definitions for all plugins *
+ * *
+ ****************************************************************************/
+
+extern alist *plugin_list;
+
+
+/* Universal return code from all functions */
+typedef int32_t bpError;
+
+/* Context packet as first argument of all functions */
+typedef struct s_bpContext {
+ void *bContext; /* Bacula private context */
+ void *pContext; /* Plugin private context */
+} bpContext;
+
+extern "C" {
+typedef bpError (*t_loadPlugin)(void *bfuncs, void **pfuncs);
+typedef bpError (*t_unloadPlugin)(void);
+}
+
+class Plugin {
+public:
+ char *file;
+ t_unloadPlugin unloadPlugin;
+ void *pfuncs;
+ void *pHandle;
+};
+
+/* Functions */
+extern Plugin *new_plugin();
+extern bool load_plugins(void *bfuncs, const char *plugin_dir, const char *type);
+extern void unload_plugins();
+
+
+#endif /* __PLUGIN_H */
all: main plugin-dir.so
-main: main.o plugin-dir.h
+main: main.o plugin-dir.h
$(CC) -L../../lib main.o -o main -lbac -lpthread -lssl -l crypto -ldl
plugin-dir.o: plugin-dir.c plugin-dir.h
$(CC) -fPIC -I../.. -c plugin-dir.c
-plugin-dir.so: plugin-dir.o
+plugin-dir.so: plugin-dir.o
$(CC) -shared plugin-dir.o -o plugin-dir.so
+
clean:
- rm -f main *.so *.o
+ rm -f main *.so *.o 1 2 3
*/
#include "bacula.h"
#include <dlfcn.h>
+#include "lib/plugin.h"
#include "plugin-dir.h"
-#ifdef HAVE_DIRENT_H
-#include <dirent.h>
-#define NAMELEN(dirent) (strlen((dirent)->d_name))
-#endif
-#ifndef HAVE_READDIR_R
-int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result);
-#endif
-#ifndef RTLD_NOW
-#define RTLD_NOW 2
-#endif
+const char *plugin_type = "-dir.so";
-class Plugin {
-public:
- char *file;
- t_bpShutdown p_bpShutdown;
- pFuncs pfuncs;
- void *pHandle;
-};
-
-/* All loaded plugins */
-alist *plugin_list;
/* Forward referenced functions */
-static Plugin *new_plugin();
-bool load_plugins(const char *plugin_dir);
-void unload_plugins();
static bpError baculaGetValue(bpContext *ctx, bVariable var, void *value);
static bpError baculaSetValue(bpContext *ctx, bVariable var, void *value);
+
+/* Bacula entry points */
+static bFuncs bfuncs = {
+ sizeof(bFuncs),
+ PLUGIN_INTERFACE,
+ baculaGetValue,
+ baculaSetValue,
+ NULL,
+ NULL
+};
+
+
+
+
int main(int argc, char *argv[])
{
char plugin_dir[1000];
ctx.bContext = NULL;
ctx.pContext = NULL;
getcwd(plugin_dir, sizeof(plugin_dir)-1);
- load_plugins(plugin_dir);
+
+ load_plugins((void *)&bfuncs, plugin_dir, plugin_type);
foreach_alist(plugin, plugin_list) {
+ printf("bacula: plugin_size=%d plugin_version=%d\n",
+ pref(plugin)->size, pref(plugin)->interface);
+ printf("License: %s\nAuthor: %s\nDate: %s\nVersion: %s\nDescription: %s\n",
+ pref(plugin)->plugin_license, pref(plugin)->plugin_author,
+ pref(plugin)->plugin_date, pref(plugin)->plugin_version,
+ pref(plugin)->plugin_description);
+
/* Start a new instance of the plugin */
- plugin->pfuncs.pNew(&ctx);
+ pref(plugin)->newPlugin(&ctx);
event.eventType = bEventNewVolume;
- plugin->pfuncs.pHandleEvent(&ctx, &event);
- /* Destroy the instance */
- plugin->pfuncs.pDestroy(&ctx);
+ pref(plugin)->handlePluginEvent(&ctx, &event);
+ /* Free the plugin instance */
+ pref(plugin)->freePlugin(&ctx);
/* Start a new instance of the plugin */
- plugin->pfuncs.pNew(&ctx);
+ pref(plugin)->newPlugin(&ctx);
event.eventType = bEventNewVolume;
- plugin->pfuncs.pHandleEvent(&ctx, &event);
- /* Destroy the instance */
- plugin->pfuncs.pDestroy(&ctx);
+ pref(plugin)->handlePluginEvent(&ctx, &event);
+ /* Free the plugin instance */
+ pref(plugin)->freePlugin(&ctx);
}
unload_plugins();
printf("bacula: OK ...\n");
+ close_memory_pool();
sm_dump(false);
return 0;
}
-/*
- * Create a new plugin "class" entry and enter it in the
- * list of plugins. Note, this is not the same as
- * an instance of the plugin.
- */
-static Plugin *new_plugin()
-{
- Plugin *plugin;
-
- plugin = (Plugin *)malloc(sizeof(Plugin));
- memset(plugin, 0, sizeof(Plugin));
- plugin_list->append(plugin);
- return plugin;
-}
-
-
-/*
- * Load all the plugins in the specified directory.
- */
-bool load_plugins(const char *plugin_dir)
-{
- t_bpInitialize p_bpInitialize;
- bFuncs bfuncs;
- Plugin *plugin;
- char *error;
- DIR* dp = NULL;
- struct dirent *entry, *result;
- int name_max;
- struct stat statp;
- bool found = false;
- POOL_MEM fname(PM_FNAME);
- bool need_slash = false;
- int len;
-
- /* Setup pointers to Bacula functions */
- bfuncs.size = sizeof(bFuncs);
- bfuncs.version = 1;
- bfuncs.bGetValue = baculaGetValue;
- bfuncs.bSetValue = baculaSetValue;
-
- plugin = new_plugin();
-
- name_max = pathconf(".", _PC_NAME_MAX);
- if (name_max < 1024) {
- name_max = 1024;
- }
-
- if (!(dp = opendir(plugin_dir))) {
- berrno be;
- Dmsg2(29, "load_plugins: failed to open dir %s: ERR=%s\n",
- plugin_dir, be.bstrerror());
- goto get_out;
- }
-
- len = strlen(plugin_dir);
- if (len > 0) {
- need_slash = !IsPathSeparator(plugin_dir[len - 1]);
- }
- entry = (struct dirent *)malloc(sizeof(struct dirent) + name_max + 1000);
- for ( ;; ) {
- if ((readdir_r(dp, entry, &result) != 0) || (result == NULL)) {
- Dmsg1(129, "load_plugins: failed to find suitable file in dir %s\n",
- plugin_dir);
- break;
- }
- if (strcmp(result->d_name, ".") == 0 ||
- strcmp(result->d_name, "..") == 0) {
- continue;
- }
-
- len = strlen(result->d_name);
- if (len < 8 || strcmp(&result->d_name[len-7], "-dir.so") != 0) {
- continue;
- }
- printf("Got: name=%s len=%d\n", result->d_name, len);
-
- pm_strcpy(fname, plugin_dir);
- if (need_slash) {
- pm_strcat(fname, "/");
- }
- pm_strcat(fname, result->d_name);
- if (lstat(fname.c_str(), &statp) != 0 || !S_ISREG(statp.st_mode)) {
- continue; /* ignore directories & special files */
- }
-
- plugin->file = bstrdup(result->d_name);
- plugin->pHandle = dlopen(fname.c_str(), RTLD_NOW);
- if (!plugin->pHandle) {
- printf("dlopen of %s failed: ERR=%s\n", fname.c_str(), dlerror());
- goto get_out;
- }
-
- /* Get two global entry points */
- p_bpInitialize = (t_bpInitialize)dlsym(plugin->pHandle, "bpInitialize");
- if ((error=dlerror()) != NULL) {
- printf("dlsym failed: ERR=%s\n", error);
- goto get_out;
- }
- plugin->p_bpShutdown = (t_bpShutdown)dlsym(plugin->pHandle, "bpShutdown");
- if ((error=dlerror()) != NULL) {
- printf("dlsym failed: ERR=%s\n", error);
- goto get_out;
- }
-
- /* Initialize the plugin */
- p_bpInitialize(&bfuncs, &plugin->pfuncs);
- printf("bacula: plugin_size=%d plugin_version=%d\n",
- plugin->pfuncs.size, plugin->pfuncs.version);
-
- found = true; /* found a plugin */
- }
-
-get_out:
- free(entry);
- if (dp) {
- closedir(dp);
- }
- return found;
-}
-
-/*
- * Unload all the loaded plugins
- */
-void unload_plugins()
-{
- Plugin *plugin;
-
- foreach_alist(plugin, plugin_list) {
- /* Shut it down and unload it */
- plugin->p_bpShutdown();
- dlclose(plugin->pHandle);
- if (plugin->file) {
- free(plugin->file);
- }
- free(plugin);
- }
- delete plugin_list;
- plugin_list = NULL;
-}
-
static bpError baculaGetValue(bpContext *ctx, bVariable var, void *value)
{
- printf("bacula: GetValue var=%d\n", var);
+ printf("bacula: baculaGetValue var=%d\n", var);
if (value) {
*((int *)value) = 100;
}
static bpError baculaSetValue(bpContext *ctx, bVariable var, void *value)
{
- printf("baculaSetValue var=%d\n", var);
+ printf("bacula: baculaSetValue var=%d\n", var);
return 0;
}
extern "C" {
#endif
+#define PLUGIN_LICENSE "GPL"
+#define PLUGIN_AUTHOR "Kern Sibbald"
+#define PLUGIN_DATE "November 2007"
+#define PLUGIN_VERSION "1"
+#define PLUGIN_DESCRIPTION "Test Director Plugin"
+
/* Forward referenced functions */
-bpError pNew(bpContext *ctx);
-bpError pDestroy(bpContext *ctx);
-bpError pGetValue(bpContext *ctx, pVariable var, void *value);
-bpError pSetValue(bpContext *ctx, pVariable var, void *value);
-bpError pHandleEvent(bpContext *ctx, bEvent *event);
+static bpError newPlugin(bpContext *ctx);
+static bpError freePlugin(bpContext *ctx);
+static bpError getPluginValue(bpContext *ctx, pVariable var, void *value);
+static bpError setPluginValue(bpContext *ctx, pVariable var, void *value);
+static bpError handlePluginEvent(bpContext *ctx, bEvent *event);
/* Pointers to Bacula functions */
-bpError (*p_bGetValue)(bpContext *ctx, bVariable var, void *value);
-bpError (*p_bSetValue)(bpContext *ctx, bVariable var, void *value);
+static bFuncs *bfuncs = NULL;
-pFuncs pluginFuncs = {
+static pFuncs pluginFuncs = {
sizeof(pluginFuncs),
- 1,
- pNew,
- pDestroy,
- pGetValue,
- pSetValue,
- pHandleEvent
+ PLUGIN_INTERFACE,
+ PLUGIN_MAGIC,
+ PLUGIN_LICENSE,
+ PLUGIN_AUTHOR,
+ PLUGIN_DATE,
+ PLUGIN_VERSION,
+ PLUGIN_DESCRIPTION,
+
+ /* Entry points into plugin */
+ newPlugin, /* new plugin instance */
+ freePlugin, /* free plugin instance */
+ getPluginValue,
+ setPluginValue,
+ handlePluginEvent
};
-bpError bpInitialize(bFuncs *bfuncs, pFuncs *pfuncs)
+bpError loadPlugin(bFuncs *lbfuncs, pFuncs **pfuncs)
{
- printf("plugin: Initializing. size=%d version=%d\n", bfuncs->size, bfuncs->version);
- p_bGetValue = bfuncs->bGetValue;
- p_bSetValue = bfuncs->bSetValue;
-
- pfuncs->pNew = pNew;
- pfuncs->pDestroy = pDestroy;
- pfuncs->pGetValue = pGetValue;
- pfuncs->pSetValue = pSetValue;
- pfuncs->pHandleEvent = pHandleEvent;
- pfuncs->size = sizeof(pFuncs);
- pfuncs->version = 1;
+ bfuncs = lbfuncs; /* set Bacula funct pointers */
+ printf("plugin: Loaded: size=%d version=%d\n", bfuncs->size, bfuncs->interface);
+
+ *pfuncs = &pluginFuncs; /* return pointer to our functions */
return 0;
}
-bpError bpShutdown()
+bpError unloadPlugin()
{
- printf("plugin: Shutting down\n");
+ printf("plugin: Unloaded\n");
return 0;
}
-bpError pNew(bpContext *ctx)
+static bpError newPlugin(bpContext *ctx)
{
int JobId = 0;
- p_bGetValue(ctx, bVarJobId, (void *)&JobId);
- printf("plugin: New JobId=%d\n", JobId);
+ bfuncs->getBaculaValue(ctx, bVarJobId, (void *)&JobId);
+ printf("plugin: newPlugin JobId=%d\n", JobId);
return 0;
}
-bpError pDestroy(bpContext *ctx)
+static bpError freePlugin(bpContext *ctx)
{
int JobId = 0;
- p_bGetValue(ctx, bVarJobId, (void *)&JobId);
- printf("plugin: Destroy JobId=%d\n", JobId);
+ bfuncs->getBaculaValue(ctx, bVarJobId, (void *)&JobId);
+ printf("plugin: freePlugin JobId=%d\n", JobId);
return 0;
}
-bpError pGetValue(bpContext *ctx, pVariable var, void *value)
+static bpError getPluginValue(bpContext *ctx, pVariable var, void *value)
{
- printf("plugin: GetValue var=%d\n", var);
+ printf("plugin: getPluginValue var=%d\n", var);
return 0;
}
-bpError pSetValue(bpContext *ctx, pVariable var, void *value)
+static bpError setPluginValue(bpContext *ctx, pVariable var, void *value)
{
- printf("plugin: PutValue var=%d\n", var);
+ printf("plugin: setPluginValue var=%d\n", var);
return 0;
}
-bpError pHandleEvent(bpContext *ctx, bEvent *event)
+static bpError handlePluginEvent(bpContext *ctx, bEvent *event)
{
printf("plugin: HandleEvent Event=%d\n", event->eventType);
return 0;
*
*/
-#ifndef __PLUGIN_H
-#define __PLUGIN_H
+#ifndef __PLUGIN_FD_H
+#define __PLUGIN_FD_H
#include <sys/types.h>
#ifndef __CONFIG_H
#include "config.h"
#endif
#include "bc_types.h"
+#include "lib/plugin.h"
#ifdef __cplusplus
extern "C" {
#endif
-/****************************************************************************
- * *
- * Common definitions *
- * *
- ****************************************************************************/
-
-/* Universal return code from all functions */
-typedef int32_t bpError;
-
-/* Context packet as first argument of all functions */
-typedef struct s_bpContext {
- void *bContext; /* Bacula private context */
- void *pContext; /* Plugin private context */
-} bpContext;
-
-
/****************************************************************************
* *
* Bacula definitions *
/* Bacula interface version and function pointers */
typedef struct s_baculaFuncs {
uint32_t size;
- uint32_t version;
- bpError (*bGetValue)(bpContext *ctx, bVariable var, void *value);
- bpError (*bSetValue)(bpContext *ctx, bVariable var, void *value);
- bpError (*bMemAlloc)(bpContext *ctx, uint32_t size, char *addr);
- bpError (*bMemFree)(bpContext *ctx, char *addr);
- bpError (*bMemFlush)(bpContext *ctx);
- bpError (*bVersion)(bVariable var, void *value);
+ uint32_t interface;
+ bpError (*getBaculaValue)(bpContext *ctx, bVariable var, void *value);
+ bpError (*setBaculaValue)(bpContext *ctx, bVariable var, void *value);
+ bpError (*allocBaculaMem)(bpContext *ctx, uint32_t size, char *addr);
+ bpError (*freeBaculaMem)(bpContext *ctx, char *addr);
} bFuncs;
} pVariable;
+#define PLUGIN_MAGIC "*PluginData*"
+#define PLUGIN_INTERFACE 1
+
typedef struct s_pluginFuncs {
uint32_t size;
- uint32_t version;
- bpError (*pNew)(bpContext *ctx);
- bpError (*pDestroy)(bpContext *ctx);
- bpError (*pGetValue)(bpContext *ctx, pVariable var, void *value);
- bpError (*pSetValue)(bpContext *ctx, pVariable var, void *value);
- bpError (*pHandleEvent)(bpContext *ctx, bEvent *event);
+ uint32_t interface;
+ char *plugin_magic;
+ char *plugin_license;
+ char *plugin_author;
+ char *plugin_date;
+ char *plugin_version;
+ char *plugin_description;
+ bpError (*newPlugin)(bpContext *ctx);
+ bpError (*freePlugin)(bpContext *ctx);
+ bpError (*getPluginValue)(bpContext *ctx, pVariable var, void *value);
+ bpError (*setPluginValue)(bpContext *ctx, pVariable var, void *value);
+ bpError (*handlePluginEvent)(bpContext *ctx, bEvent *event);
} pFuncs;
-typedef bpError (*t_bpInitialize)(bFuncs *bfuncs, pFuncs *pfuncs);
-typedef bpError (*t_bpShutdown)(void);
-
+#define pref(plugin) ((pFuncs *)(plugin->pfuncs))
#ifdef __cplusplus
}
#endif
-#endif /* __PLUGIN_H */
+#endif /* __PLUGIN_FD_H */
all: main plugin-fd.so
-main: main.o plugin-fd.h
+main: main.o plugin-fd.h
$(CC) -L../../lib main.o -o main -lbac -lpthread -lssl -l crypto -ldl
plugin-fd.o: plugin-fd.c plugin-fd.h
$(CC) -fPIC -I../.. -c plugin-fd.c
-plugin-fd.so: plugin-fd.o
+plugin.o: plugin.c plugin.h
+ $(CC) -fPIC -I../.. -c plugin.c
+
+
+plugin-fd.so: plugin-fd.o
$(CC) -shared plugin-fd.o -o plugin-fd.so
+
clean:
- rm -f main *.so *.o
+ rm -f main *.so *.o 1 2 3
*/
#include "bacula.h"
#include <dlfcn.h>
+#include "lib/plugin.h"
#include "plugin-fd.h"
-#ifdef HAVE_DIRENT_H
-#include <dirent.h>
-#define NAMELEN(dirent) (strlen((dirent)->d_name))
-#endif
-#ifndef HAVE_READDIR_R
-int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result);
-#endif
-#ifndef RTLD_NOW
-#define RTLD_NOW 2
-#endif
+const char *plugin_type = "-fd.so";
-class Plugin {
-public:
- char *file;
- t_bpShutdown p_bpShutdown;
- pFuncs pfuncs;
- void *pHandle;
-};
-
-/* All loaded plugins */
-alist *plugin_list;
/* Forward referenced functions */
-static Plugin *new_plugin();
-bool load_plugins(const char *plugin_dir);
-void unload_plugins();
static bpError baculaGetValue(bpContext *ctx, bVariable var, void *value);
static bpError baculaSetValue(bpContext *ctx, bVariable var, void *value);
+
+/* Bacula entry points */
+static bFuncs bfuncs = {
+ sizeof(bFuncs),
+ PLUGIN_INTERFACE,
+ baculaGetValue,
+ baculaSetValue,
+ NULL,
+ NULL
+};
+
+
+
+
int main(int argc, char *argv[])
{
char plugin_dir[1000];
ctx.bContext = NULL;
ctx.pContext = NULL;
getcwd(plugin_dir, sizeof(plugin_dir)-1);
- load_plugins(plugin_dir);
+
+ load_plugins((void *)&bfuncs, plugin_dir, plugin_type);
foreach_alist(plugin, plugin_list) {
+ printf("bacula: plugin_size=%d plugin_version=%d\n",
+ pref(plugin)->size, pref(plugin)->interface);
+ printf("License: %s\nAuthor: %s\nDate: %s\nVersion: %s\nDescription: %s\n",
+ pref(plugin)->plugin_license, pref(plugin)->plugin_author,
+ pref(plugin)->plugin_date, pref(plugin)->plugin_version,
+ pref(plugin)->plugin_description);
+
/* Start a new instance of the plugin */
- plugin->pfuncs.pNew(&ctx);
+ pref(plugin)->newPlugin(&ctx);
event.eventType = bEventNewVolume;
- plugin->pfuncs.pHandleEvent(&ctx, &event);
- /* Destroy the instance */
- plugin->pfuncs.pDestroy(&ctx);
+ pref(plugin)->handlePluginEvent(&ctx, &event);
+ /* Free the plugin instance */
+ pref(plugin)->freePlugin(&ctx);
/* Start a new instance of the plugin */
- plugin->pfuncs.pNew(&ctx);
+ pref(plugin)->newPlugin(&ctx);
event.eventType = bEventNewVolume;
- plugin->pfuncs.pHandleEvent(&ctx, &event);
- /* Destroy the instance */
- plugin->pfuncs.pDestroy(&ctx);
+ pref(plugin)->handlePluginEvent(&ctx, &event);
+ /* Free the plugin instance */
+ pref(plugin)->freePlugin(&ctx);
}
unload_plugins();
printf("bacula: OK ...\n");
+ close_memory_pool();
sm_dump(false);
return 0;
}
-/*
- * Create a new plugin "class" entry and enter it in the
- * list of plugins. Note, this is not the same as
- * an instance of the plugin.
- */
-static Plugin *new_plugin()
-{
- Plugin *plugin;
-
- plugin = (Plugin *)malloc(sizeof(Plugin));
- memset(plugin, 0, sizeof(Plugin));
- plugin_list->append(plugin);
- return plugin;
-}
-
-
-/*
- * Load all the plugins in the specified directory.
- */
-bool load_plugins(const char *plugin_dir)
-{
- t_bpInitialize p_bpInitialize;
- bFuncs bfuncs;
- Plugin *plugin;
- char *error;
- DIR* dp = NULL;
- struct dirent *entry, *result;
- int name_max;
- struct stat statp;
- bool found = false;
- POOL_MEM fname(PM_FNAME);
- bool need_slash = false;
- int len;
-
- /* Setup pointers to Bacula functions */
- bfuncs.size = sizeof(bFuncs);
- bfuncs.version = 1;
- bfuncs.bGetValue = baculaGetValue;
- bfuncs.bSetValue = baculaSetValue;
-
- plugin = new_plugin();
-
- name_max = pathconf(".", _PC_NAME_MAX);
- if (name_max < 1024) {
- name_max = 1024;
- }
-
- if (!(dp = opendir(plugin_dir))) {
- berrno be;
- Dmsg2(29, "load_plugins: failed to open dir %s: ERR=%s\n",
- plugin_dir, be.bstrerror());
- goto get_out;
- }
-
- len = strlen(plugin_dir);
- if (len > 0) {
- need_slash = !IsPathSeparator(plugin_dir[len - 1]);
- }
- entry = (struct dirent *)malloc(sizeof(struct dirent) + name_max + 1000);
- for ( ;; ) {
- if ((readdir_r(dp, entry, &result) != 0) || (result == NULL)) {
- Dmsg1(129, "load_plugins: failed to find suitable file in dir %s\n",
- plugin_dir);
- break;
- }
- if (strcmp(result->d_name, ".") == 0 ||
- strcmp(result->d_name, "..") == 0) {
- continue;
- }
-
- len = strlen(result->d_name);
- if (len < 7 || strcmp(&result->d_name[len-6], "-fd.so") != 0) {
- continue;
- }
- printf("Got: name=%s len=%d\n", result->d_name, len);
-
- pm_strcpy(fname, plugin_dir);
- if (need_slash) {
- pm_strcat(fname, "/");
- }
- pm_strcat(fname, result->d_name);
- if (lstat(fname.c_str(), &statp) != 0 || !S_ISREG(statp.st_mode)) {
- continue; /* ignore directories & special files */
- }
-
- plugin->file = bstrdup(result->d_name);
- plugin->pHandle = dlopen(fname.c_str(), RTLD_NOW);
- if (!plugin->pHandle) {
- printf("dlopen of %s failed: ERR=%s\n", fname.c_str(), dlerror());
- goto get_out;
- }
-
- /* Get two global entry points */
- p_bpInitialize = (t_bpInitialize)dlsym(plugin->pHandle, "bpInitialize");
- if ((error=dlerror()) != NULL) {
- printf("dlsym failed: ERR=%s\n", error);
- goto get_out;
- }
- plugin->p_bpShutdown = (t_bpShutdown)dlsym(plugin->pHandle, "bpShutdown");
- if ((error=dlerror()) != NULL) {
- printf("dlsym failed: ERR=%s\n", error);
- goto get_out;
- }
-
- /* Initialize the plugin */
- p_bpInitialize(&bfuncs, &plugin->pfuncs);
- printf("bacula: plugin_size=%d plugin_version=%d\n",
- plugin->pfuncs.size, plugin->pfuncs.version);
-
- found = true; /* found a plugin */
- }
-
-get_out:
- free(entry);
- if (dp) {
- closedir(dp);
- }
- return found;
-}
-
-/*
- * Unload all the loaded plugins
- */
-void unload_plugins()
-{
- Plugin *plugin;
-
- foreach_alist(plugin, plugin_list) {
- /* Shut it down and unload it */
- plugin->p_bpShutdown();
- dlclose(plugin->pHandle);
- if (plugin->file) {
- free(plugin->file);
- }
- free(plugin);
- }
- delete plugin_list;
- plugin_list = NULL;
-}
-
static bpError baculaGetValue(bpContext *ctx, bVariable var, void *value)
{
- printf("bacula: GetValue var=%d\n", var);
+ printf("bacula: baculaGetValue var=%d\n", var);
if (value) {
*((int *)value) = 100;
}
static bpError baculaSetValue(bpContext *ctx, bVariable var, void *value)
{
- printf("baculaSetValue var=%d\n", var);
+ printf("bacula: baculaSetValue var=%d\n", var);
return 0;
}
extern "C" {
#endif
+#define PLUGIN_LICENSE "GPL"
+#define PLUGIN_AUTHOR "Kern Sibbald"
+#define PLUGIN_DATE "November 2007"
+#define PLUGIN_VERSION "1"
+#define PLUGIN_DESCRIPTION "Test File Daemon Plugin"
+
/* Forward referenced functions */
-bpError pNew(bpContext *ctx);
-bpError pDestroy(bpContext *ctx);
-bpError pGetValue(bpContext *ctx, pVariable var, void *value);
-bpError pSetValue(bpContext *ctx, pVariable var, void *value);
-bpError pHandleEvent(bpContext *ctx, bEvent *event);
+static bpError newPlugin(bpContext *ctx);
+static bpError freePlugin(bpContext *ctx);
+static bpError getPluginValue(bpContext *ctx, pVariable var, void *value);
+static bpError setPluginValue(bpContext *ctx, pVariable var, void *value);
+static bpError handlePluginEvent(bpContext *ctx, bEvent *event);
/* Pointers to Bacula functions */
-bpError (*p_bGetValue)(bpContext *ctx, bVariable var, void *value);
-bpError (*p_bSetValue)(bpContext *ctx, bVariable var, void *value);
+static bFuncs *bfuncs = NULL;
-pFuncs pluginFuncs = {
+static pFuncs pluginFuncs = {
sizeof(pluginFuncs),
- 1,
- pNew,
- pDestroy,
- pGetValue,
- pSetValue,
- pHandleEvent
+ PLUGIN_INTERFACE,
+ PLUGIN_MAGIC,
+ PLUGIN_LICENSE,
+ PLUGIN_AUTHOR,
+ PLUGIN_DATE,
+ PLUGIN_VERSION,
+ PLUGIN_DESCRIPTION,
+
+ /* Entry points into plugin */
+ newPlugin, /* new plugin instance */
+ freePlugin, /* free plugin instance */
+ getPluginValue,
+ setPluginValue,
+ handlePluginEvent
};
-bpError bpInitialize(bFuncs *bfuncs, pFuncs *pfuncs)
+bpError loadPlugin(bFuncs *lbfuncs, pFuncs **pfuncs)
{
- printf("plugin: Initializing. size=%d version=%d\n", bfuncs->size, bfuncs->version);
- p_bGetValue = bfuncs->bGetValue;
- p_bSetValue = bfuncs->bSetValue;
-
- pfuncs->pNew = pNew;
- pfuncs->pDestroy = pDestroy;
- pfuncs->pGetValue = pGetValue;
- pfuncs->pSetValue = pSetValue;
- pfuncs->pHandleEvent = pHandleEvent;
- pfuncs->size = sizeof(pFuncs);
- pfuncs->version = 1;
+ bfuncs = lbfuncs; /* set Bacula funct pointers */
+ printf("plugin: Loaded: size=%d version=%d\n", bfuncs->size, bfuncs->interface);
+
+ *pfuncs = &pluginFuncs; /* return pointer to our functions */
return 0;
}
-bpError bpShutdown()
+bpError unloadPlugin()
{
- printf("plugin: Shutting down\n");
+ printf("plugin: Unloaded\n");
return 0;
}
-bpError pNew(bpContext *ctx)
+static bpError newPlugin(bpContext *ctx)
{
int JobId = 0;
- p_bGetValue(ctx, bVarJobId, (void *)&JobId);
- printf("plugin: New JobId=%d\n", JobId);
+ bfuncs->getBaculaValue(ctx, bVarJobId, (void *)&JobId);
+ printf("plugin: newPlugin JobId=%d\n", JobId);
return 0;
}
-bpError pDestroy(bpContext *ctx)
+static bpError freePlugin(bpContext *ctx)
{
int JobId = 0;
- p_bGetValue(ctx, bVarJobId, (void *)&JobId);
- printf("plugin: Destroy JobId=%d\n", JobId);
+ bfuncs->getBaculaValue(ctx, bVarJobId, (void *)&JobId);
+ printf("plugin: freePlugin JobId=%d\n", JobId);
return 0;
}
-bpError pGetValue(bpContext *ctx, pVariable var, void *value)
+static bpError getPluginValue(bpContext *ctx, pVariable var, void *value)
{
- printf("plugin: GetValue var=%d\n", var);
+ printf("plugin: getPluginValue var=%d\n", var);
return 0;
}
-bpError pSetValue(bpContext *ctx, pVariable var, void *value)
+static bpError setPluginValue(bpContext *ctx, pVariable var, void *value)
{
- printf("plugin: PutValue var=%d\n", var);
+ printf("plugin: setPluginValue var=%d\n", var);
return 0;
}
-bpError pHandleEvent(bpContext *ctx, bEvent *event)
+static bpError handlePluginEvent(bpContext *ctx, bEvent *event)
{
printf("plugin: HandleEvent Event=%d\n", event->eventType);
return 0;
*
*/
-#ifndef __PLUGIN_H
-#define __PLUGIN_H
+#ifndef __PLUGIN_FD_H
+#define __PLUGIN_FD_H
#include <sys/types.h>
#ifndef __CONFIG_H
#include "config.h"
#endif
#include "bc_types.h"
+#include "lib/plugin.h"
#ifdef __cplusplus
extern "C" {
#endif
-/****************************************************************************
- * *
- * Common definitions *
- * *
- ****************************************************************************/
-
-/* Universal return code from all functions */
-typedef int32_t bpError;
-
-/* Context packet as first argument of all functions */
-typedef struct s_bpContext {
- void *bContext; /* Bacula private context */
- void *pContext; /* Plugin private context */
-} bpContext;
-
-
/****************************************************************************
* *
* Bacula definitions *
/* Bacula interface version and function pointers */
typedef struct s_baculaFuncs {
uint32_t size;
- uint32_t version;
- bpError (*bGetValue)(bpContext *ctx, bVariable var, void *value);
- bpError (*bSetValue)(bpContext *ctx, bVariable var, void *value);
- bpError (*bMemAlloc)(bpContext *ctx, uint32_t size, char *addr);
- bpError (*bMemFree)(bpContext *ctx, char *addr);
- bpError (*bMemFlush)(bpContext *ctx);
- bpError (*bVersion)(bVariable var, void *value);
+ uint32_t interface;
+ bpError (*getBaculaValue)(bpContext *ctx, bVariable var, void *value);
+ bpError (*setBaculaValue)(bpContext *ctx, bVariable var, void *value);
+ bpError (*allocBaculaMem)(bpContext *ctx, uint32_t size, char *addr);
+ bpError (*freeBaculaMem)(bpContext *ctx, char *addr);
} bFuncs;
} pVariable;
+#define PLUGIN_MAGIC "*PluginData*"
+#define PLUGIN_INTERFACE 1
+
typedef struct s_pluginFuncs {
uint32_t size;
- uint32_t version;
- bpError (*pNew)(bpContext *ctx);
- bpError (*pDestroy)(bpContext *ctx);
- bpError (*pGetValue)(bpContext *ctx, pVariable var, void *value);
- bpError (*pSetValue)(bpContext *ctx, pVariable var, void *value);
- bpError (*pHandleEvent)(bpContext *ctx, bEvent *event);
+ uint32_t interface;
+ char *plugin_magic;
+ char *plugin_license;
+ char *plugin_author;
+ char *plugin_date;
+ char *plugin_version;
+ char *plugin_description;
+ bpError (*newPlugin)(bpContext *ctx);
+ bpError (*freePlugin)(bpContext *ctx);
+ bpError (*getPluginValue)(bpContext *ctx, pVariable var, void *value);
+ bpError (*setPluginValue)(bpContext *ctx, pVariable var, void *value);
+ bpError (*handlePluginEvent)(bpContext *ctx, bEvent *event);
} pFuncs;
-typedef bpError (*t_bpInitialize)(bFuncs *bfuncs, pFuncs *pfuncs);
-typedef bpError (*t_bpShutdown)(void);
-
+#define pref(plugin) ((pFuncs *)(plugin->pfuncs))
#ifdef __cplusplus
}
#endif
-#endif /* __PLUGIN_H */
+#endif /* __PLUGIN_FD_H */
all: main plugin-sd.so
-main: main.o plugin-sd.h
+main: main.o plugin-sd.h
$(CC) -L../../lib main.o -o main -lbac -lpthread -lssl -l crypto -ldl
plugin-sd.o: plugin-sd.c plugin-sd.h
$(CC) -fPIC -I../.. -c plugin-sd.c
-plugin-sd.so: plugin-sd.o
+plugin-sd.so: plugin-sd.o
$(CC) -shared plugin-sd.o -o plugin-sd.so
+
clean:
- rm -f main *.so *.o
+ rm -f main *.so *.o 1 2 3
*/
#include "bacula.h"
#include <dlfcn.h>
+#include "lib/plugin.h"
#include "plugin-sd.h"
-#ifdef HAVE_DIRENT_H
-#include <dirent.h>
-#define NAMELEN(dirent) (strlen((dirent)->d_name))
-#endif
-#ifndef HAVE_READDIR_R
-int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result);
-#endif
-#ifndef RTLD_NOW
-#define RTLD_NOW 2
-#endif
+const char *plugin_type = "-sd.so";
-class Plugin {
-public:
- char *file;
- t_bpShutdown p_bpShutdown;
- pFuncs pfuncs;
- void *pHandle;
-};
-
-/* All loaded plugins */
-alist *plugin_list;
/* Forward referenced functions */
-static Plugin *new_plugin();
-bool load_plugins(const char *plugin_dir);
-void unload_plugins();
static bpError baculaGetValue(bpContext *ctx, bVariable var, void *value);
static bpError baculaSetValue(bpContext *ctx, bVariable var, void *value);
+
+/* Bacula entry points */
+static bFuncs bfuncs = {
+ sizeof(bFuncs),
+ PLUGIN_INTERFACE,
+ baculaGetValue,
+ baculaSetValue,
+ NULL,
+ NULL
+};
+
+
+
+
int main(int argc, char *argv[])
{
char plugin_dir[1000];
ctx.bContext = NULL;
ctx.pContext = NULL;
getcwd(plugin_dir, sizeof(plugin_dir)-1);
- load_plugins(plugin_dir);
+
+ load_plugins((void *)&bfuncs, plugin_dir, plugin_type);
foreach_alist(plugin, plugin_list) {
+ printf("bacula: plugin_size=%d plugin_version=%d\n",
+ pref(plugin)->size, pref(plugin)->interface);
+ printf("License: %s\nAuthor: %s\nDate: %s\nVersion: %s\nDescription: %s\n",
+ pref(plugin)->plugin_license, pref(plugin)->plugin_author,
+ pref(plugin)->plugin_date, pref(plugin)->plugin_version,
+ pref(plugin)->plugin_description);
+
/* Start a new instance of the plugin */
- plugin->pfuncs.pNew(&ctx);
+ pref(plugin)->newPlugin(&ctx);
event.eventType = bEventNewVolume;
- plugin->pfuncs.pHandleEvent(&ctx, &event);
- /* Destroy the instance */
- plugin->pfuncs.pDestroy(&ctx);
+ pref(plugin)->handlePluginEvent(&ctx, &event);
+ /* Free the plugin instance */
+ pref(plugin)->freePlugin(&ctx);
/* Start a new instance of the plugin */
- plugin->pfuncs.pNew(&ctx);
+ pref(plugin)->newPlugin(&ctx);
event.eventType = bEventNewVolume;
- plugin->pfuncs.pHandleEvent(&ctx, &event);
- /* Destroy the instance */
- plugin->pfuncs.pDestroy(&ctx);
+ pref(plugin)->handlePluginEvent(&ctx, &event);
+ /* Free the plugin instance */
+ pref(plugin)->freePlugin(&ctx);
}
unload_plugins();
printf("bacula: OK ...\n");
+ close_memory_pool();
sm_dump(false);
return 0;
}
-/*
- * Create a new plugin "class" entry and enter it in the
- * list of plugins. Note, this is not the same as
- * an instance of the plugin.
- */
-static Plugin *new_plugin()
-{
- Plugin *plugin;
-
- plugin = (Plugin *)malloc(sizeof(Plugin));
- memset(plugin, 0, sizeof(Plugin));
- plugin_list->append(plugin);
- return plugin;
-}
-
-
-/*
- * Load all the plugins in the specified directory.
- */
-bool load_plugins(const char *plugin_dir)
-{
- t_bpInitialize p_bpInitialize;
- bFuncs bfuncs;
- Plugin *plugin;
- char *error;
- DIR* dp = NULL;
- struct dirent *entry, *result;
- int name_max;
- struct stat statp;
- bool found = false;
- POOL_MEM fname(PM_FNAME);
- bool need_slash = false;
- int len;
-
- /* Setup pointers to Bacula functions */
- bfuncs.size = sizeof(bFuncs);
- bfuncs.version = 1;
- bfuncs.bGetValue = baculaGetValue;
- bfuncs.bSetValue = baculaSetValue;
-
- plugin = new_plugin();
-
- name_max = pathconf(".", _PC_NAME_MAX);
- if (name_max < 1024) {
- name_max = 1024;
- }
-
- if (!(dp = opendir(plugin_dir))) {
- berrno be;
- Dmsg2(29, "load_plugins: failed to open dir %s: ERR=%s\n",
- plugin_dir, be.bstrerror());
- goto get_out;
- }
-
- len = strlen(plugin_dir);
- if (len > 0) {
- need_slash = !IsPathSeparator(plugin_dir[len - 1]);
- }
- entry = (struct dirent *)malloc(sizeof(struct dirent) + name_max + 1000);
- for ( ;; ) {
- if ((readdir_r(dp, entry, &result) != 0) || (result == NULL)) {
- Dmsg1(129, "load_plugins: failed to find suitable file in dir %s\n",
- plugin_dir);
- break;
- }
- if (strcmp(result->d_name, ".") == 0 ||
- strcmp(result->d_name, "..") == 0) {
- continue;
- }
-
- len = strlen(result->d_name);
- if (len < 7 || strcmp(&result->d_name[len-6], "-sd.so") != 0) {
- continue;
- }
- printf("Got: name=%s len=%d\n", result->d_name, len);
-
- pm_strcpy(fname, plugin_dir);
- if (need_slash) {
- pm_strcat(fname, "/");
- }
- pm_strcat(fname, result->d_name);
- if (lstat(fname.c_str(), &statp) != 0 || !S_ISREG(statp.st_mode)) {
- continue; /* ignore directories & special files */
- }
-
- plugin->file = bstrdup(result->d_name);
- plugin->pHandle = dlopen(fname.c_str(), RTLD_NOW);
- if (!plugin->pHandle) {
- printf("dlopen of %s failed: ERR=%s\n", fname.c_str(), dlerror());
- goto get_out;
- }
-
- /* Get two global entry points */
- p_bpInitialize = (t_bpInitialize)dlsym(plugin->pHandle, "bpInitialize");
- if ((error=dlerror()) != NULL) {
- printf("dlsym failed: ERR=%s\n", error);
- goto get_out;
- }
- plugin->p_bpShutdown = (t_bpShutdown)dlsym(plugin->pHandle, "bpShutdown");
- if ((error=dlerror()) != NULL) {
- printf("dlsym failed: ERR=%s\n", error);
- goto get_out;
- }
-
- /* Initialize the plugin */
- p_bpInitialize(&bfuncs, &plugin->pfuncs);
- printf("bacula: plugin_size=%d plugin_version=%d\n",
- plugin->pfuncs.size, plugin->pfuncs.version);
-
- found = true; /* found a plugin */
- }
-
-get_out:
- free(entry);
- if (dp) {
- closedir(dp);
- }
- return found;
-}
-
-/*
- * Unload all the loaded plugins
- */
-void unload_plugins()
-{
- Plugin *plugin;
-
- foreach_alist(plugin, plugin_list) {
- /* Shut it down and unload it */
- plugin->p_bpShutdown();
- dlclose(plugin->pHandle);
- if (plugin->file) {
- free(plugin->file);
- }
- free(plugin);
- }
- delete plugin_list;
- plugin_list = NULL;
-}
-
static bpError baculaGetValue(bpContext *ctx, bVariable var, void *value)
{
- printf("bacula: GetValue var=%d\n", var);
+ printf("bacula: baculaGetValue var=%d\n", var);
if (value) {
*((int *)value) = 100;
}
static bpError baculaSetValue(bpContext *ctx, bVariable var, void *value)
{
- printf("baculaSetValue var=%d\n", var);
+ printf("bacula: baculaSetValue var=%d\n", var);
return 0;
}
extern "C" {
#endif
+#define PLUGIN_LICENSE "GPL"
+#define PLUGIN_AUTHOR "Kern Sibbald"
+#define PLUGIN_DATE "November 2007"
+#define PLUGIN_VERSION "1"
+#define PLUGIN_DESCRIPTION "Test Storage Daemon Plugin"
+
/* Forward referenced functions */
-bpError pNew(bpContext *ctx);
-bpError pDestroy(bpContext *ctx);
-bpError pGetValue(bpContext *ctx, pVariable var, void *value);
-bpError pSetValue(bpContext *ctx, pVariable var, void *value);
-bpError pHandleEvent(bpContext *ctx, bEvent *event);
+static bpError newPlugin(bpContext *ctx);
+static bpError freePlugin(bpContext *ctx);
+static bpError getPluginValue(bpContext *ctx, pVariable var, void *value);
+static bpError setPluginValue(bpContext *ctx, pVariable var, void *value);
+static bpError handlePluginEvent(bpContext *ctx, bEvent *event);
/* Pointers to Bacula functions */
-bpError (*p_bGetValue)(bpContext *ctx, bVariable var, void *value);
-bpError (*p_bSetValue)(bpContext *ctx, bVariable var, void *value);
+static bFuncs *bfuncs = NULL;
-pFuncs pluginFuncs = {
+static pFuncs pluginFuncs = {
sizeof(pluginFuncs),
- 1,
- pNew,
- pDestroy,
- pGetValue,
- pSetValue,
- pHandleEvent
+ PLUGIN_INTERFACE,
+ PLUGIN_MAGIC,
+ PLUGIN_LICENSE,
+ PLUGIN_AUTHOR,
+ PLUGIN_DATE,
+ PLUGIN_VERSION,
+ PLUGIN_DESCRIPTION,
+
+ /* Entry points into plugin */
+ newPlugin, /* new plugin instance */
+ freePlugin, /* free plugin instance */
+ getPluginValue,
+ setPluginValue,
+ handlePluginEvent
};
-bpError bpInitialize(bFuncs *bfuncs, pFuncs *pfuncs)
+bpError loadPlugin(bFuncs *lbfuncs, pFuncs **pfuncs)
{
- printf("plugin: Initializing. size=%d version=%d\n", bfuncs->size, bfuncs->version);
- p_bGetValue = bfuncs->bGetValue;
- p_bSetValue = bfuncs->bSetValue;
-
- pfuncs->pNew = pNew;
- pfuncs->pDestroy = pDestroy;
- pfuncs->pGetValue = pGetValue;
- pfuncs->pSetValue = pSetValue;
- pfuncs->pHandleEvent = pHandleEvent;
- pfuncs->size = sizeof(pFuncs);
- pfuncs->version = 1;
+ bfuncs = lbfuncs; /* set Bacula funct pointers */
+ printf("plugin: Loaded: size=%d version=%d\n", bfuncs->size, bfuncs->interface);
+
+ *pfuncs = &pluginFuncs; /* return pointer to our functions */
return 0;
}
-bpError bpShutdown()
+bpError unloadPlugin()
{
- printf("plugin: Shutting down\n");
+ printf("plugin: Unloaded\n");
return 0;
}
-bpError pNew(bpContext *ctx)
+static bpError newPlugin(bpContext *ctx)
{
int JobId = 0;
- p_bGetValue(ctx, bVarJobId, (void *)&JobId);
- printf("plugin: New JobId=%d\n", JobId);
+ bfuncs->getBaculaValue(ctx, bVarJobId, (void *)&JobId);
+ printf("plugin: newPlugin JobId=%d\n", JobId);
return 0;
}
-bpError pDestroy(bpContext *ctx)
+static bpError freePlugin(bpContext *ctx)
{
int JobId = 0;
- p_bGetValue(ctx, bVarJobId, (void *)&JobId);
- printf("plugin: Destroy JobId=%d\n", JobId);
+ bfuncs->getBaculaValue(ctx, bVarJobId, (void *)&JobId);
+ printf("plugin: freePlugin JobId=%d\n", JobId);
return 0;
}
-bpError pGetValue(bpContext *ctx, pVariable var, void *value)
+static bpError getPluginValue(bpContext *ctx, pVariable var, void *value)
{
- printf("plugin: GetValue var=%d\n", var);
+ printf("plugin: getPluginValue var=%d\n", var);
return 0;
}
-bpError pSetValue(bpContext *ctx, pVariable var, void *value)
+static bpError setPluginValue(bpContext *ctx, pVariable var, void *value)
{
- printf("plugin: PutValue var=%d\n", var);
+ printf("plugin: setPluginValue var=%d\n", var);
return 0;
}
-bpError pHandleEvent(bpContext *ctx, bEvent *event)
+static bpError handlePluginEvent(bpContext *ctx, bEvent *event)
{
printf("plugin: HandleEvent Event=%d\n", event->eventType);
return 0;
*
*/
-#ifndef __PLUGIN_H
-#define __PLUGIN_H
+#ifndef __PLUGIN_FD_H
+#define __PLUGIN_FD_H
#include <sys/types.h>
#ifndef __CONFIG_H
#include "config.h"
#endif
#include "bc_types.h"
+#include "lib/plugin.h"
#ifdef __cplusplus
extern "C" {
#endif
-/****************************************************************************
- * *
- * Common definitions *
- * *
- ****************************************************************************/
-
-/* Universal return code from all functions */
-typedef int32_t bpError;
-
-/* Context packet as first argument of all functions */
-typedef struct s_bpContext {
- void *bContext; /* Bacula private context */
- void *pContext; /* Plugin private context */
-} bpContext;
-
-
/****************************************************************************
* *
* Bacula definitions *
/* Bacula interface version and function pointers */
typedef struct s_baculaFuncs {
uint32_t size;
- uint32_t version;
- bpError (*bGetValue)(bpContext *ctx, bVariable var, void *value);
- bpError (*bSetValue)(bpContext *ctx, bVariable var, void *value);
- bpError (*bMemAlloc)(bpContext *ctx, uint32_t size, char *addr);
- bpError (*bMemFree)(bpContext *ctx, char *addr);
- bpError (*bMemFlush)(bpContext *ctx);
- bpError (*bVersion)(bVariable var, void *value);
+ uint32_t interface;
+ bpError (*getBaculaValue)(bpContext *ctx, bVariable var, void *value);
+ bpError (*setBaculaValue)(bpContext *ctx, bVariable var, void *value);
+ bpError (*allocBaculaMem)(bpContext *ctx, uint32_t size, char *addr);
+ bpError (*freeBaculaMem)(bpContext *ctx, char *addr);
} bFuncs;
} pVariable;
+#define PLUGIN_MAGIC "*PluginData*"
+#define PLUGIN_INTERFACE 1
+
typedef struct s_pluginFuncs {
uint32_t size;
- uint32_t version;
- bpError (*pNew)(bpContext *ctx);
- bpError (*pDestroy)(bpContext *ctx);
- bpError (*pGetValue)(bpContext *ctx, pVariable var, void *value);
- bpError (*pSetValue)(bpContext *ctx, pVariable var, void *value);
- bpError (*pHandleEvent)(bpContext *ctx, bEvent *event);
+ uint32_t interface;
+ char *plugin_magic;
+ char *plugin_license;
+ char *plugin_author;
+ char *plugin_date;
+ char *plugin_version;
+ char *plugin_description;
+ bpError (*newPlugin)(bpContext *ctx);
+ bpError (*freePlugin)(bpContext *ctx);
+ bpError (*getPluginValue)(bpContext *ctx, pVariable var, void *value);
+ bpError (*setPluginValue)(bpContext *ctx, pVariable var, void *value);
+ bpError (*handlePluginEvent)(bpContext *ctx, bEvent *event);
} pFuncs;
-typedef bpError (*t_bpInitialize)(bFuncs *bfuncs, pFuncs *pfuncs);
-typedef bpError (*t_bpShutdown)(void);
-
+#define pref(plugin) ((pFuncs *)(plugin->pfuncs))
#ifdef __cplusplus
}
#endif
-#endif /* __PLUGIN_H */
+#endif /* __PLUGIN_FD_H */