]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/filed/fd_plugins.c
Tweak add sm_dump comments in debug code
[bacula/bacula] / bacula / src / filed / fd_plugins.c
index 4d7abba2633867a7e274bb1ff02ebd4ca074c8a0..3b372c9b172361fda55d45acffa351d0d6af485d 100644 (file)
@@ -34,6 +34,8 @@
 #include "bacula.h"
 #include "filed.h"
 
+extern CLIENT *me;
+
 const int dbglvl = 150;
 #ifdef HAVE_WIN32
 const char *plugin_type = "-fd.dll";
@@ -63,7 +65,14 @@ static void *baculaMalloc(bpContext *ctx, const char *file, int line,
               size_t size);
 static void baculaFree(bpContext *ctx, const char *file, int line, void *mem);
 static bRC  baculaAddExclude(bpContext *ctx, const char *file);
+static bRC baculaAddInclude(bpContext *ctx, const char *file);
+static bRC baculaAddOptions(bpContext *ctx, const char *opts);
+static bRC baculaAddRegex(bpContext *ctx, const char *item, int type);
+static bRC baculaAddWild(bpContext *ctx, const char *item, int type);
+static bRC baculaNewOptions(bpContext *ctx);
+static bRC baculaNewInclude(bpContext *ctx);
 static bool is_plugin_compatible(Plugin *plugin);
+static bool get_plugin_name(JCR *jcr, char *cmd, int *ret);
 
 /*
  * These will be plugged into the global pointer structure for
@@ -93,7 +102,13 @@ static bFuncs bfuncs = {
    baculaDebugMsg,
    baculaMalloc,
    baculaFree,
-   baculaAddExclude
+   baculaAddExclude,
+   baculaAddInclude,
+   baculaAddOptions,
+   baculaAddRegex,
+   baculaAddWild,
+   baculaNewOptions,
+   baculaNewInclude
 };
 
 /* 
@@ -103,54 +118,75 @@ struct bacula_ctx {
    JCR *jcr;                             /* jcr for plugin */
    bRC  rc;                              /* last return code */
    bool disabled;                        /* set if plugin disabled */
-   findFILESET *fileset;                 /* pointer to exclude files */
+   findINCEXE *exclude;                  /* pointer to exclude files */
+   findINCEXE *include;                  /* pointer to include/exclude files */
 };
 
-static bool is_plugin_disabled(JCR *jcr)
+static bool is_plugin_disabled(bpContext *plugin_ctx)
 {
    bacula_ctx *b_ctx;
-   if (!jcr->plugin_ctx) {
+   if (!plugin_ctx) {
       return true;
    }
-   b_ctx = (bacula_ctx *)jcr->plugin_ctx->bContext;
+   b_ctx = (bacula_ctx *)plugin_ctx->bContext;
    return b_ctx->disabled;
 }
 
+static bool is_plugin_disabled(JCR *jcr)
+{
+   return is_plugin_disabled(jcr->plugin_ctx);
+}
 
 /**
  * Create a plugin event 
+ * When receiving bEventCancelCommand, this function is called by an other thread. 
  */
 void generate_plugin_event(JCR *jcr, bEventType eventType, void *value)     
 {
+   bpContext *plugin_ctx;
    bEvent event;
    Plugin *plugin;
    int i = 0;
+   char *name=NULL;
+   int len;
+   bRC rc;
 
    if (!plugin_list || !jcr || !jcr->plugin_ctx_list || jcr->is_job_canceled()) {
       return;                         /* Return if no plugins loaded */
    }
+   
+   /* Some events are sent to only a particular plugin */
+   switch(eventType) {
+   case bEventPluginCommand:
+      name = (char *)value;
+      if (!get_plugin_name(jcr, name, &len)) {
+         return;
+      }
+      break;
+   default:
+      break;
+   }
 
    bpContext *plugin_ctx_list = (bpContext *)jcr->plugin_ctx_list;
    event.eventType = eventType;
 
    Dmsg2(dbglvl, "plugin_ctx=%p JobId=%d\n", jcr->plugin_ctx_list, jcr->JobId);
 
-   /* Pass event to every plugin */
+   /* Pass event to every plugin (except if name is set) */
    foreach_alist(plugin, plugin_list) {
-      bRC rc;
-      jcr->plugin_ctx = &plugin_ctx_list[i++];
-      jcr->plugin = plugin;
-      if (is_plugin_disabled(jcr)) {
+      if (name && strncmp(plugin->file, name, len) != 0) {
+         i++;
          continue;
       }
-      rc = plug_func(plugin)->handlePluginEvent(jcr->plugin_ctx, &event, value);
+      plugin_ctx = &plugin_ctx_list[i++];
+      if (is_plugin_disabled(plugin_ctx)) {
+         continue;
+      }
+      rc = plug_func(plugin)->handlePluginEvent(plugin_ctx, &event, value);
       if (rc != bRC_OK) {
          break;
       }
    }
-
-   jcr->plugin = NULL;
-   jcr->plugin_ctx = NULL;
    return;
 }
 
@@ -192,6 +228,31 @@ bool plugin_check_file(JCR *jcr, char *fname)
    return rc == bRC_Seen;
 }
 
+/* Get the first part of the the plugin command
+ *  systemstate:/@SYSTEMSTATE/ 
+ * => ret = 11
+ * => can use strncmp(plugin_name, cmd, ret);
+ */
+static bool get_plugin_name(JCR *jcr, char *cmd, int *ret)
+{
+   char *p;
+   int len;
+   if (!cmd) {
+      return false;
+   }
+   /* Handle plugin command here backup */
+   Dmsg1(dbglvl, "plugin cmd=%s\n", cmd);
+   if (!(p = strchr(cmd, ':'))) {
+      Jmsg1(jcr, M_ERROR, 0, "Malformed plugin command: %s\n", cmd);
+      return false;
+   }
+   len = p - cmd;
+   if (len <= 0) {
+      return false;
+   }
+   *ret = len;
+   return true;
+}
 
 /**  
  * Sequence of calls for a backup:
@@ -213,7 +274,6 @@ int plugin_save(JCR *jcr, FF_PKT *ff_pkt, bool top_level)
    Plugin *plugin;
    int i = 0;
    int len;
-   char *p;
    char *cmd = ff_pkt->top_fname;
    struct save_pkt sp;
    bEvent event;
@@ -229,14 +289,7 @@ int plugin_save(JCR *jcr, FF_PKT *ff_pkt, bool top_level)
    bpContext *plugin_ctx_list = (bpContext *)jcr->plugin_ctx_list;
    event.eventType = bEventBackupCommand;
 
-   /* Handle plugin command here backup */
-   Dmsg1(dbglvl, "plugin cmd=%s\n", cmd);
-   if (!(p = strchr(cmd, ':'))) {
-      Jmsg1(jcr, M_ERROR, 0, "Malformed plugin command: %s\n", cmd);
-      goto bail_out;
-   }
-   len = p - cmd;
-   if (len <= 0) {
+   if (!get_plugin_name(jcr, cmd, &len)) {
       goto bail_out;
    }
 
@@ -433,15 +486,7 @@ bool plugin_name_stream(JCR *jcr, char *name)
    /*
     * After this point, we are dealing with a restore start
     */
-
-// Dmsg1(dbglvl, "plugin restore cmd=%s\n", cmd);
-   if (!(p = strchr(cmd, ':'))) {
-      Jmsg1(jcr, M_ERROR, 0,
-           _("Malformed plugin command. Name not terminated by colon: %s\n"), cmd);
-      goto bail_out;
-   }
-   len = p - cmd;
-   if (len <= 0) {
+   if (!get_plugin_name(jcr, cmd, &len)) {
       goto bail_out;
    }
 
@@ -954,6 +999,9 @@ static bRC baculaGetValue(bpContext *ctx, bVariable var, void *value)
        }
 #endif
        return bRC_Error;
+   case bVarWorkingDir:
+      *(void **)value = me->working_directory;
+      break;
    }
    return bRC_OK;
 }
@@ -1051,6 +1099,22 @@ static void baculaFree(bpContext *ctx, const char *file, int line, void *mem)
 #endif
 }
 
+static bool is_ctx_good(bpContext *ctx, JCR *&jcr, bacula_ctx *&bctx)
+{
+   if (!ctx) {
+      return false;
+   }
+   bctx = (bacula_ctx *)ctx->bContext;
+   if (!bctx) {
+      return false;
+   }
+   jcr = bctx->jcr;
+   if (!jcr) {
+      return false;
+   }
+   return true;
+}
+
 /**
  * Let the plugin define files/directories to be excluded
  *  from the main backup.
@@ -1059,24 +1123,110 @@ static bRC baculaAddExclude(bpContext *ctx, const char *file)
 {
    JCR *jcr;
    bacula_ctx *bctx;
-   if (!ctx) {
+   if (!is_ctx_good(ctx, jcr, bctx)) {
       return bRC_Error;
    }
    if (!file) {
       return bRC_Error;
    }
-   bctx = (bacula_ctx *)ctx->bContext;
-   if (!bctx) {
+   if (!bctx->exclude) {  
+      bctx->exclude = new_exclude(jcr);
+      new_options(jcr, bctx->exclude);
+   }
+   set_incexe(jcr, bctx->exclude);
+   add_file_to_fileset(jcr, file, true);
+   Dmsg1(100, "Add exclude file=%s\n", file);
+   return bRC_OK;
+}
+
+/**
+ * Let the plugin define files/directories to be excluded
+ *  from the main backup.
+ */
+static bRC baculaAddInclude(bpContext *ctx, const char *file)
+{
+   JCR *jcr;
+   bacula_ctx *bctx;
+   if (!is_ctx_good(ctx, jcr, bctx)) {
       return bRC_Error;
    }
-   jcr = bctx->jcr;
-   if (!jcr) {
+   if (!file) {
       return bRC_Error;
    }
-   if (!bctx->fileset) {  
-      bctx->fileset = new_exclude(jcr);
+   if (!bctx->include) {  
+      bctx->include = new_preinclude(jcr);
+      new_options(jcr, bctx->include);
+   }
+   set_incexe(jcr, bctx->include);
+   add_file_to_fileset(jcr, file, true);
+   Dmsg1(100, "Add include file=%s\n", file);
+   return bRC_OK;
+}
+
+static bRC baculaAddOptions(bpContext *ctx, const char *opts)
+{
+   JCR *jcr;
+   bacula_ctx *bctx;
+   if (!is_ctx_good(ctx, jcr, bctx)) {
+      return bRC_Error;
+   }
+   if (!opts) {
+      return bRC_Error;
+   }
+   add_options_to_fileset(jcr, opts);
+   Dmsg1(1000, "Add options=%s\n", opts);
+   return bRC_OK;
+}
+
+static bRC baculaAddRegex(bpContext *ctx, const char *item, int type)
+{
+   JCR *jcr;
+   bacula_ctx *bctx;
+   if (!is_ctx_good(ctx, jcr, bctx)) {
+      return bRC_Error;
+   }
+   if (!item) {
+      return bRC_Error;
+   }
+   add_regex_to_fileset(jcr, item, type);
+   Dmsg1(100, "Add regex=%s\n", item);
+   return bRC_OK;
+}
+
+static bRC baculaAddWild(bpContext *ctx, const char *item, int type)
+{
+   JCR *jcr;
+   bacula_ctx *bctx;
+   if (!is_ctx_good(ctx, jcr, bctx)) {
+      return bRC_Error;
+   }
+   if (!item) {
+      return bRC_Error;
+   }
+   add_wild_to_fileset(jcr, item, type);
+   Dmsg1(100, "Add wild=%s\n", item);
+   return bRC_OK;
+}
+
+static bRC baculaNewOptions(bpContext *ctx)
+{
+   JCR *jcr;
+   bacula_ctx *bctx;
+   if (!is_ctx_good(ctx, jcr, bctx)) {
+      return bRC_Error;
+   }
+   (void)new_options(jcr, NULL);
+   return bRC_OK;
+}
+
+static bRC baculaNewInclude(bpContext *ctx)
+{
+   JCR *jcr;
+   bacula_ctx *bctx;
+   if (!is_ctx_good(ctx, jcr, bctx)) {
+      return bRC_Error;
    }
-   add_file_to_fileset(jcr, file, bctx->fileset, true);
+   (void)new_include(jcr);
    return bRC_OK;
 }
 
@@ -1128,7 +1278,7 @@ int main(int argc, char *argv[])
 
    Dmsg0(dbglvl, "bacula: OK ...\n");
    close_memory_pool();
-   sm_dump(false);
+   sm_dump(false);     /* unit test */
    return 0;
 }