]> git.sur5r.net Git - bacula/bacula/commitdiff
Zeroth integration of plugins
authorKern Sibbald <kern@sibbald.com>
Mon, 26 Nov 2007 17:01:24 +0000 (17:01 +0000)
committerKern Sibbald <kern@sibbald.com>
Mon, 26 Nov 2007 17:01:24 +0000 (17:01 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@5990 91ce42f0-d328-0410-95d8-f526ca767f89

15 files changed:
bacula/src/lib/Makefile.in
bacula/src/lib/plugin.c [new file with mode: 0644]
bacula/src/lib/plugin.h [new file with mode: 0644]
bacula/src/plugins/dir/Makefile
bacula/src/plugins/dir/main.c
bacula/src/plugins/dir/plugin-dir.c
bacula/src/plugins/dir/plugin-dir.h
bacula/src/plugins/fd/Makefile
bacula/src/plugins/fd/main.c
bacula/src/plugins/fd/plugin-fd.c
bacula/src/plugins/fd/plugin-fd.h
bacula/src/plugins/sd/Makefile
bacula/src/plugins/sd/main.c
bacula/src/plugins/sd/plugin-sd.c
bacula/src/plugins/sd/plugin-sd.h

index c32085f46045bbdd69db204be21f3ac3cea6746a..6da35951cf35e77c40c67cff3dc1738f4cfb6afb 100644 (file)
@@ -25,7 +25,7 @@ LIBSRCS = attr.c base64.c berrno.c bsys.c bget_msg.c \
          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 \
@@ -38,7 +38,7 @@ LIBOBJS = attr.o base64.o berrno.o bsys.o bget_msg.o \
          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 \
@@ -108,7 +108,10 @@ bsnprintf: bsnprintf.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:
 
diff --git a/bacula/src/lib/plugin.c b/bacula/src/lib/plugin.c
new file mode 100644 (file)
index 0000000..18704a6
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+   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;
+}
diff --git a/bacula/src/lib/plugin.h b/bacula/src/lib/plugin.h
new file mode 100644 (file)
index 0000000..0ff9399
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+   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 */
index 4988aede02bf77cecd82aa320e66ff74a6481ba8..f5c430e65553d0766f0ab32d1a27b4a52c8202ea 100644 (file)
@@ -11,14 +11,15 @@ CC = g++ -g -O0 -Wall
 
 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
index a9b3ec3cd7ffbf715f890cbb07ad80f112b5560f..387df2612825faacf2d3560435bb5ea2e5558701 100644 (file)
  */
 #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];
@@ -76,174 +69,43 @@ int main(int argc, char *argv[])
    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;
    }
@@ -252,6 +114,6 @@ static bpError baculaGetValue(bpContext *ctx, bVariable var, void *value)
 
 static bpError baculaSetValue(bpContext *ctx, bVariable var, void *value)
 {
-   printf("baculaSetValue var=%d\n", var);
+   printf("bacula: baculaSetValue var=%d\n", var);
    return 0;
 }
index 4e032d7e1455de9461afeef2cb098727e326c678..8d5e8e93b092cd1630d0307cb045acfec6dd113b 100644 (file)
 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;
index 9fd2d530cc077df7b95e9f7fb39ba5d6522318f3..cc78a42cb628c23a98ede3e091271b600b10b743 100644 (file)
@@ -32,8 +32,8 @@
  *
  */
  
-#ifndef __PLUGIN_H 
-#define __PLUGIN_H
+#ifndef __PLUGIN_FD_
+#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                                        *
@@ -92,13 +77,11 @@ typedef struct s_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);
+   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;
 
 
@@ -114,22 +97,29 @@ typedef enum {
 } 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 */
index fee6491cf1dc8488528b38b95a31f6621a2cf550..96776447bf3d1fc24be9977ce19d6c51cd6329a0 100644 (file)
@@ -11,14 +11,19 @@ CC = g++ -g -O0 -Wall
 
 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
index e15f8de2fddce04a68d96c87ba5caa46f4de5743..eae0a818df895d9b691b251ca155d6450cb71558 100644 (file)
  */
 #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];
@@ -76,174 +69,43 @@ int main(int argc, char *argv[])
    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;
    }
@@ -252,6 +114,6 @@ static bpError baculaGetValue(bpContext *ctx, bVariable var, void *value)
 
 static bpError baculaSetValue(bpContext *ctx, bVariable var, void *value)
 {
-   printf("baculaSetValue var=%d\n", var);
+   printf("bacula: baculaSetValue var=%d\n", var);
    return 0;
 }
index fb66ec921b6a4e2de0d7750897e5c3796a1d9f1f..3181d94a8dc4917ded08882f1f4bf3862756fe21 100644 (file)
 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;
index 9fd2d530cc077df7b95e9f7fb39ba5d6522318f3..cc78a42cb628c23a98ede3e091271b600b10b743 100644 (file)
@@ -32,8 +32,8 @@
  *
  */
  
-#ifndef __PLUGIN_H 
-#define __PLUGIN_H
+#ifndef __PLUGIN_FD_
+#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                                        *
@@ -92,13 +77,11 @@ typedef struct s_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);
+   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;
 
 
@@ -114,22 +97,29 @@ typedef enum {
 } 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 */
index dfb9346a8fc568d566404564ee426ceb9383e28a..fc79538f3a252462d1bde9bffc12c81fff8d61a0 100644 (file)
@@ -11,14 +11,15 @@ CC = g++ -g -O0 -Wall
 
 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
index 7c66137134b24425d157d721b7438c1f8caad9ae..a381c7ae24d68357a6088cc2c13aa6b221d5704c 100644 (file)
  */
 #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];
@@ -76,174 +69,43 @@ int main(int argc, char *argv[])
    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;
    }
@@ -252,6 +114,6 @@ static bpError baculaGetValue(bpContext *ctx, bVariable var, void *value)
 
 static bpError baculaSetValue(bpContext *ctx, bVariable var, void *value)
 {
-   printf("baculaSetValue var=%d\n", var);
+   printf("bacula: baculaSetValue var=%d\n", var);
    return 0;
 }
index bce4eda281ca5cfca654d087f34ea3e2e9f22207..17f74b06ee2e90c694403c052e7d19b418e89d9a 100644 (file)
 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;
index 9fd2d530cc077df7b95e9f7fb39ba5d6522318f3..cc78a42cb628c23a98ede3e091271b600b10b743 100644 (file)
@@ -32,8 +32,8 @@
  *
  */
  
-#ifndef __PLUGIN_H 
-#define __PLUGIN_H
+#ifndef __PLUGIN_FD_
+#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                                        *
@@ -92,13 +77,11 @@ typedef struct s_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);
+   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;
 
 
@@ -114,22 +97,29 @@ typedef enum {
 } 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 */