From: Kern Sibbald Date: Wed, 14 Nov 2007 14:11:55 +0000 (+0000) Subject: Commit 0th cut of plugins X-Git-Tag: Release-3.0.0~2251 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=ab3173cecd7daf2874b577ecd606439b5e7d3d28;p=bacula%2Fbacula Commit 0th cut of plugins git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@5929 91ce42f0-d328-0410-95d8-f526ca767f89 --- diff --git a/bacula/src/plugins/Makefile b/bacula/src/plugins/Makefile new file mode 100644 index 0000000000..cd007a2531 --- /dev/null +++ b/bacula/src/plugins/Makefile @@ -0,0 +1,27 @@ +# +# Simple Makefile for building test plugins for Bacula +# + +first_rule: all +dummy: + +all: dir fd sd + +dir: dummy + (cd dir && make DESTDIR=$(DESTDIR) || exit 1) + @echo + +fd: dummy + (cd fd && make DESTDIR=$(DESTDIR) || exit 1) + @echo + +sd: dummy + (cd sd && make DESTDIR=$(DESTDIR) || exit 1) + @echo + + +clean: + (cd dir && make DESTDIR=$(DESTDIR) clean || exit 1) + (cd fd && make DESTDIR=$(DESTDIR) clean || exit 1) + (cd sd && make DESTDIR=$(DESTDIR) clean || exit 1) + diff --git a/bacula/src/plugins/README b/bacula/src/plugins/README new file mode 100644 index 0000000000..559a1f163e --- /dev/null +++ b/bacula/src/plugins/README @@ -0,0 +1,37 @@ + +This is a first cut of a plugins implementation for Bacula. +The current code is simply a test program named main, which +when executed will load the plugin named plugin.so and then +call it with a few calls, then exit. + +What is implemented: +- load a plugin +- get main entry points in plugin (two) +- pass plugin Bacula entry points +- get plugin's entry points +- keep list of plugins that are loaded +- The plugin currently only needs config.h and bc_types.h + in the Bacula src directory to be build. Otherwise, it is + totally independent of Bacula. +- The main test program is intended to be integrated into + Bacula (at least a number of the functions therein). + +What is not yet implemented: +- Search for all plugins in the plugin directory +- Implement Bacula context for plugin instances +- Implement plugin context for plugin instances +- Some better method to pass variables +- Pass Version information in plugin Initialize +- Define more functionality (Bacula entry points, ...) +- Integrate the code into Bacula +- Make libbac.a into a shared object and allow plugin + to call functions in directly so that plugins can use + the same "safe" system utilities that Bacula uses. +- Document the interface +- Document libbac.so (when implemented) +- Write a couple of plugins that really do something. +- Figure out a way to deal with 3 types of plugins (Director, + File daemon, Storage daemon). +- Error handling must be much improved and brought into Bacula + programming style. It currently just printf()s a message then + exits. diff --git a/bacula/src/plugins/dir/Makefile b/bacula/src/plugins/dir/Makefile new file mode 100644 index 0000000000..4988aede02 --- /dev/null +++ b/bacula/src/plugins/dir/Makefile @@ -0,0 +1,24 @@ +# +# Simple Makefile for building test plugins for Bacula +# + +# No optimization for now for easy debugging +CC = g++ -g -O0 -Wall + +.SUFFIXES: .c .o +.c.o: + $(CC) -I../.. -DTEST_PROGRAM -c $< + +all: main plugin-dir.so + +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 + $(CC) -shared plugin-dir.o -o plugin-dir.so + +clean: + rm -f main *.so *.o diff --git a/bacula/src/plugins/dir/main.c b/bacula/src/plugins/dir/main.c new file mode 100644 index 0000000000..a9b3ec3cd7 --- /dev/null +++ b/bacula/src/plugins/dir/main.c @@ -0,0 +1,257 @@ +/* + 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. +*/ +/* + * Main program to test loading and running Bacula plugins. + * Destined to become Bacula pluginloader, ... + * + * Kern Sibbald, October 2007 + */ +#include "bacula.h" +#include +#include "plugin-dir.h" +#ifdef HAVE_DIRENT_H +#include +#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 + +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); + +int main(int argc, char *argv[]) +{ + char plugin_dir[1000]; + bpContext ctx; + bEvent event; + Plugin *plugin; + + plugin_list = New(alist(10, not_owned_by_alist)); + + ctx.bContext = NULL; + ctx.pContext = NULL; + getcwd(plugin_dir, sizeof(plugin_dir)-1); + load_plugins(plugin_dir); + + foreach_alist(plugin, plugin_list) { + /* Start a new instance of the plugin */ + plugin->pfuncs.pNew(&ctx); + event.eventType = bEventNewVolume; + plugin->pfuncs.pHandleEvent(&ctx, &event); + /* Destroy the instance */ + plugin->pfuncs.pDestroy(&ctx); + + /* Start a new instance of the plugin */ + plugin->pfuncs.pNew(&ctx); + event.eventType = bEventNewVolume; + plugin->pfuncs.pHandleEvent(&ctx, &event); + /* Destroy the instance */ + plugin->pfuncs.pDestroy(&ctx); + } + + unload_plugins(); + + printf("bacula: OK ...\n"); + 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); + if (value) { + *((int *)value) = 100; + } + return 0; +} + +static bpError baculaSetValue(bpContext *ctx, bVariable var, void *value) +{ + printf("baculaSetValue var=%d\n", var); + return 0; +} diff --git a/bacula/src/plugins/dir/plugin-dir.c b/bacula/src/plugins/dir/plugin-dir.c new file mode 100644 index 0000000000..4e032d7e14 --- /dev/null +++ b/bacula/src/plugins/dir/plugin-dir.c @@ -0,0 +1,122 @@ +/* + 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. +*/ +/* + * Sample Plugin program + * + * Kern Sibbald, October 2007 + * + */ +#include +#include "plugin-dir.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* 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); + + +/* Pointers to Bacula functions */ +bpError (*p_bGetValue)(bpContext *ctx, bVariable var, void *value); +bpError (*p_bSetValue)(bpContext *ctx, bVariable var, void *value); + +pFuncs pluginFuncs = { + sizeof(pluginFuncs), + 1, + pNew, + pDestroy, + pGetValue, + pSetValue, + pHandleEvent +}; + +bpError bpInitialize(bFuncs *bfuncs, 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; + + return 0; +} + +bpError bpShutdown() +{ + printf("plugin: Shutting down\n"); + return 0; +} + +bpError pNew(bpContext *ctx) +{ + int JobId = 0; + p_bGetValue(ctx, bVarJobId, (void *)&JobId); + printf("plugin: New JobId=%d\n", JobId); + return 0; +} + +bpError pDestroy(bpContext *ctx) +{ + int JobId = 0; + p_bGetValue(ctx, bVarJobId, (void *)&JobId); + printf("plugin: Destroy JobId=%d\n", JobId); + return 0; +} + +bpError pGetValue(bpContext *ctx, pVariable var, void *value) +{ + printf("plugin: GetValue var=%d\n", var); + return 0; +} + +bpError pSetValue(bpContext *ctx, pVariable var, void *value) +{ + printf("plugin: PutValue var=%d\n", var); + return 0; +} + +bpError pHandleEvent(bpContext *ctx, bEvent *event) +{ + printf("plugin: HandleEvent Event=%d\n", event->eventType); + return 0; +} + +#ifdef __cplusplus +} +#endif diff --git a/bacula/src/plugins/dir/plugin-dir.h b/bacula/src/plugins/dir/plugin-dir.h new file mode 100644 index 0000000000..9fd2d530cc --- /dev/null +++ b/bacula/src/plugins/dir/plugin-dir.h @@ -0,0 +1,135 @@ +/* + 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. +*/ +/* + * Interface definition for Bacula Plugins + * + * Kern Sibbald, October 2007 + * + */ + +#ifndef __PLUGIN_H +#define __PLUGIN_H + +#include +#ifndef __CONFIG_H +#define __CONFIG_H +#include "config.h" +#endif +#include "bc_types.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 Variable Ids */ +typedef enum { + bVarJobId = 1 +} bVariable; + +typedef enum { + bEventJobStart = 1, + bEventJobInit = 2, + bEventJobRun = 3, + bEventJobEnd = 4, + bEventNewVolume = 5, + bEventVolumePurged = 6, + bEventReload = 7 +} bEventType; + +typedef struct s_bEvent { + uint32_t eventType; +} bEvent; + + +/* 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); +} bFuncs; + + +/**************************************************************************** + * * + * Plugin definitions * + * * + ****************************************************************************/ + +typedef enum { + pVarName = 1, + pVarDescription = 2 +} pVariable; + + +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); +} pFuncs; + +typedef bpError (*t_bpInitialize)(bFuncs *bfuncs, pFuncs *pfuncs); +typedef bpError (*t_bpShutdown)(void); + + +#ifdef __cplusplus +} +#endif + +#endif /* __PLUGIN_H */ diff --git a/bacula/src/plugins/fd/Makefile b/bacula/src/plugins/fd/Makefile new file mode 100644 index 0000000000..fee6491cf1 --- /dev/null +++ b/bacula/src/plugins/fd/Makefile @@ -0,0 +1,24 @@ +# +# Simple Makefile for building test plugin-fds for Bacula +# + +# No optimization for now for easy debugging +CC = g++ -g -O0 -Wall + +.SUFFIXES: .c .o +.c.o: + $(CC) -I../.. -DTEST_PROGRAM -c $< + +all: main plugin-fd.so + +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 + $(CC) -shared plugin-fd.o -o plugin-fd.so + +clean: + rm -f main *.so *.o diff --git a/bacula/src/plugins/fd/main.c b/bacula/src/plugins/fd/main.c new file mode 100644 index 0000000000..e15f8de2fd --- /dev/null +++ b/bacula/src/plugins/fd/main.c @@ -0,0 +1,257 @@ +/* + 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. +*/ +/* + * Main program to test loading and running Bacula plugins. + * Destined to become Bacula pluginloader, ... + * + * Kern Sibbald, October 2007 + */ +#include "bacula.h" +#include +#include "plugin-fd.h" +#ifdef HAVE_DIRENT_H +#include +#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 + +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); + +int main(int argc, char *argv[]) +{ + char plugin_dir[1000]; + bpContext ctx; + bEvent event; + Plugin *plugin; + + plugin_list = New(alist(10, not_owned_by_alist)); + + ctx.bContext = NULL; + ctx.pContext = NULL; + getcwd(plugin_dir, sizeof(plugin_dir)-1); + load_plugins(plugin_dir); + + foreach_alist(plugin, plugin_list) { + /* Start a new instance of the plugin */ + plugin->pfuncs.pNew(&ctx); + event.eventType = bEventNewVolume; + plugin->pfuncs.pHandleEvent(&ctx, &event); + /* Destroy the instance */ + plugin->pfuncs.pDestroy(&ctx); + + /* Start a new instance of the plugin */ + plugin->pfuncs.pNew(&ctx); + event.eventType = bEventNewVolume; + plugin->pfuncs.pHandleEvent(&ctx, &event); + /* Destroy the instance */ + plugin->pfuncs.pDestroy(&ctx); + } + + unload_plugins(); + + printf("bacula: OK ...\n"); + 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); + if (value) { + *((int *)value) = 100; + } + return 0; +} + +static bpError baculaSetValue(bpContext *ctx, bVariable var, void *value) +{ + printf("baculaSetValue var=%d\n", var); + return 0; +} diff --git a/bacula/src/plugins/fd/plugin-fd.c b/bacula/src/plugins/fd/plugin-fd.c new file mode 100644 index 0000000000..fb66ec921b --- /dev/null +++ b/bacula/src/plugins/fd/plugin-fd.c @@ -0,0 +1,122 @@ +/* + 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. +*/ +/* + * Sample Plugin program + * + * Kern Sibbald, October 2007 + * + */ +#include +#include "plugin-fd.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* 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); + + +/* Pointers to Bacula functions */ +bpError (*p_bGetValue)(bpContext *ctx, bVariable var, void *value); +bpError (*p_bSetValue)(bpContext *ctx, bVariable var, void *value); + +pFuncs pluginFuncs = { + sizeof(pluginFuncs), + 1, + pNew, + pDestroy, + pGetValue, + pSetValue, + pHandleEvent +}; + +bpError bpInitialize(bFuncs *bfuncs, 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; + + return 0; +} + +bpError bpShutdown() +{ + printf("plugin: Shutting down\n"); + return 0; +} + +bpError pNew(bpContext *ctx) +{ + int JobId = 0; + p_bGetValue(ctx, bVarJobId, (void *)&JobId); + printf("plugin: New JobId=%d\n", JobId); + return 0; +} + +bpError pDestroy(bpContext *ctx) +{ + int JobId = 0; + p_bGetValue(ctx, bVarJobId, (void *)&JobId); + printf("plugin: Destroy JobId=%d\n", JobId); + return 0; +} + +bpError pGetValue(bpContext *ctx, pVariable var, void *value) +{ + printf("plugin: GetValue var=%d\n", var); + return 0; +} + +bpError pSetValue(bpContext *ctx, pVariable var, void *value) +{ + printf("plugin: PutValue var=%d\n", var); + return 0; +} + +bpError pHandleEvent(bpContext *ctx, bEvent *event) +{ + printf("plugin: HandleEvent Event=%d\n", event->eventType); + return 0; +} + +#ifdef __cplusplus +} +#endif diff --git a/bacula/src/plugins/fd/plugin-fd.h b/bacula/src/plugins/fd/plugin-fd.h new file mode 100644 index 0000000000..9fd2d530cc --- /dev/null +++ b/bacula/src/plugins/fd/plugin-fd.h @@ -0,0 +1,135 @@ +/* + 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. +*/ +/* + * Interface definition for Bacula Plugins + * + * Kern Sibbald, October 2007 + * + */ + +#ifndef __PLUGIN_H +#define __PLUGIN_H + +#include +#ifndef __CONFIG_H +#define __CONFIG_H +#include "config.h" +#endif +#include "bc_types.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 Variable Ids */ +typedef enum { + bVarJobId = 1 +} bVariable; + +typedef enum { + bEventJobStart = 1, + bEventJobInit = 2, + bEventJobRun = 3, + bEventJobEnd = 4, + bEventNewVolume = 5, + bEventVolumePurged = 6, + bEventReload = 7 +} bEventType; + +typedef struct s_bEvent { + uint32_t eventType; +} bEvent; + + +/* 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); +} bFuncs; + + +/**************************************************************************** + * * + * Plugin definitions * + * * + ****************************************************************************/ + +typedef enum { + pVarName = 1, + pVarDescription = 2 +} pVariable; + + +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); +} pFuncs; + +typedef bpError (*t_bpInitialize)(bFuncs *bfuncs, pFuncs *pfuncs); +typedef bpError (*t_bpShutdown)(void); + + +#ifdef __cplusplus +} +#endif + +#endif /* __PLUGIN_H */ diff --git a/bacula/src/plugins/sd/Makefile b/bacula/src/plugins/sd/Makefile new file mode 100644 index 0000000000..dfb9346a8f --- /dev/null +++ b/bacula/src/plugins/sd/Makefile @@ -0,0 +1,24 @@ +# +# Simple Makefile for building test plugin-sds for Bacula +# + +# No optimization for now for easy debugging +CC = g++ -g -O0 -Wall + +.SUFFIXES: .c .o +.c.o: + $(CC) -I../.. -DTEST_PROGRAM -c $< + +all: main plugin-sd.so + +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 + $(CC) -shared plugin-sd.o -o plugin-sd.so + +clean: + rm -f main *.so *.o diff --git a/bacula/src/plugins/sd/main.c b/bacula/src/plugins/sd/main.c new file mode 100644 index 0000000000..7c66137134 --- /dev/null +++ b/bacula/src/plugins/sd/main.c @@ -0,0 +1,257 @@ +/* + 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. +*/ +/* + * Main program to test loading and running Bacula plugins. + * Destined to become Bacula pluginloader, ... + * + * Kern Sibbald, October 2007 + */ +#include "bacula.h" +#include +#include "plugin-sd.h" +#ifdef HAVE_DIRENT_H +#include +#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 + +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); + +int main(int argc, char *argv[]) +{ + char plugin_dir[1000]; + bpContext ctx; + bEvent event; + Plugin *plugin; + + plugin_list = New(alist(10, not_owned_by_alist)); + + ctx.bContext = NULL; + ctx.pContext = NULL; + getcwd(plugin_dir, sizeof(plugin_dir)-1); + load_plugins(plugin_dir); + + foreach_alist(plugin, plugin_list) { + /* Start a new instance of the plugin */ + plugin->pfuncs.pNew(&ctx); + event.eventType = bEventNewVolume; + plugin->pfuncs.pHandleEvent(&ctx, &event); + /* Destroy the instance */ + plugin->pfuncs.pDestroy(&ctx); + + /* Start a new instance of the plugin */ + plugin->pfuncs.pNew(&ctx); + event.eventType = bEventNewVolume; + plugin->pfuncs.pHandleEvent(&ctx, &event); + /* Destroy the instance */ + plugin->pfuncs.pDestroy(&ctx); + } + + unload_plugins(); + + printf("bacula: OK ...\n"); + 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); + if (value) { + *((int *)value) = 100; + } + return 0; +} + +static bpError baculaSetValue(bpContext *ctx, bVariable var, void *value) +{ + printf("baculaSetValue var=%d\n", var); + return 0; +} diff --git a/bacula/src/plugins/sd/plugin-sd.c b/bacula/src/plugins/sd/plugin-sd.c new file mode 100644 index 0000000000..bce4eda281 --- /dev/null +++ b/bacula/src/plugins/sd/plugin-sd.c @@ -0,0 +1,122 @@ +/* + 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. +*/ +/* + * Sample Plugin program + * + * Kern Sibbald, October 2007 + * + */ +#include +#include "plugin-sd.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* 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); + + +/* Pointers to Bacula functions */ +bpError (*p_bGetValue)(bpContext *ctx, bVariable var, void *value); +bpError (*p_bSetValue)(bpContext *ctx, bVariable var, void *value); + +pFuncs pluginFuncs = { + sizeof(pluginFuncs), + 1, + pNew, + pDestroy, + pGetValue, + pSetValue, + pHandleEvent +}; + +bpError bpInitialize(bFuncs *bfuncs, 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; + + return 0; +} + +bpError bpShutdown() +{ + printf("plugin: Shutting down\n"); + return 0; +} + +bpError pNew(bpContext *ctx) +{ + int JobId = 0; + p_bGetValue(ctx, bVarJobId, (void *)&JobId); + printf("plugin: New JobId=%d\n", JobId); + return 0; +} + +bpError pDestroy(bpContext *ctx) +{ + int JobId = 0; + p_bGetValue(ctx, bVarJobId, (void *)&JobId); + printf("plugin: Destroy JobId=%d\n", JobId); + return 0; +} + +bpError pGetValue(bpContext *ctx, pVariable var, void *value) +{ + printf("plugin: GetValue var=%d\n", var); + return 0; +} + +bpError pSetValue(bpContext *ctx, pVariable var, void *value) +{ + printf("plugin: PutValue var=%d\n", var); + return 0; +} + +bpError pHandleEvent(bpContext *ctx, bEvent *event) +{ + printf("plugin: HandleEvent Event=%d\n", event->eventType); + return 0; +} + +#ifdef __cplusplus +} +#endif diff --git a/bacula/src/plugins/sd/plugin-sd.h b/bacula/src/plugins/sd/plugin-sd.h new file mode 100644 index 0000000000..9fd2d530cc --- /dev/null +++ b/bacula/src/plugins/sd/plugin-sd.h @@ -0,0 +1,135 @@ +/* + 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. +*/ +/* + * Interface definition for Bacula Plugins + * + * Kern Sibbald, October 2007 + * + */ + +#ifndef __PLUGIN_H +#define __PLUGIN_H + +#include +#ifndef __CONFIG_H +#define __CONFIG_H +#include "config.h" +#endif +#include "bc_types.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 Variable Ids */ +typedef enum { + bVarJobId = 1 +} bVariable; + +typedef enum { + bEventJobStart = 1, + bEventJobInit = 2, + bEventJobRun = 3, + bEventJobEnd = 4, + bEventNewVolume = 5, + bEventVolumePurged = 6, + bEventReload = 7 +} bEventType; + +typedef struct s_bEvent { + uint32_t eventType; +} bEvent; + + +/* 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); +} bFuncs; + + +/**************************************************************************** + * * + * Plugin definitions * + * * + ****************************************************************************/ + +typedef enum { + pVarName = 1, + pVarDescription = 2 +} pVariable; + + +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); +} pFuncs; + +typedef bpError (*t_bpInitialize)(bFuncs *bfuncs, pFuncs *pfuncs); +typedef bpError (*t_bpShutdown)(void); + + +#ifdef __cplusplus +} +#endif + +#endif /* __PLUGIN_H */