]> git.sur5r.net Git - bacula/bacula/commitdiff
First cut more complicated fileset options for plugins
authorKern Sibbald <kern@sibbald.com>
Sun, 18 Apr 2010 10:16:58 +0000 (12:16 +0200)
committerEric Bollengier <eric@eb.homelinux.org>
Mon, 2 Aug 2010 14:53:13 +0000 (16:53 +0200)
bacula/src/filed/fd_plugins.c
bacula/src/filed/fd_plugins.h
bacula/src/filed/job.c
bacula/src/filed/protos.h

index 65ec96b67ad80fd80bbbee43e2397b4d25d793ca..c2c69b073aebcff9030d5e6ffdd8965a244e0bd7 100644 (file)
@@ -65,6 +65,10 @@ 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 baculaAddIncludeOptions(bpContext *ctx, const char *opts);
+static bRC baculaAddRegexToInclude(bpContext *ctx, const char *item, int type);
+static bRC baculaAddWildToInclude(bpContext *ctx, const char *item, int type);
 static bool is_plugin_compatible(Plugin *plugin);
 
 /*
@@ -95,7 +99,11 @@ static bFuncs bfuncs = {
    baculaDebugMsg,
    baculaMalloc,
    baculaFree,
-   baculaAddExclude
+   baculaAddExclude,
+   baculaAddInclude,
+   baculaAddIncludeOptions,
+   baculaAddRegexToInclude,
+   baculaAddWildToInclude
 };
 
 /* 
@@ -105,7 +113,8 @@ 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)
@@ -1056,6 +1065,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.
@@ -1064,27 +1089,104 @@ 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);
+   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->include) {  
+      bctx->include = new_preinclude(jcr);
+      new_options(jcr, bctx->include);
+   }
+   set_incexe(jcr, bctx->include);
+   add_file_to_fileset(jcr, file, true);
+   return bRC_OK;
+}
+
+static bRC baculaAddIncludeOptions(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;
+   }
+   if (!bctx->include) {  
+      bctx->include = new_preinclude(jcr);
+      new_options(jcr, bctx->include);
+   }
+   set_incexe(jcr, bctx->include);
+   add_options_to_fileset(jcr, opts);
+   return bRC_OK;
+}
+
+static bRC baculaAddRegexToInclude(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;
    }
-   if (!bctx->fileset) {  
-      bctx->fileset = new_exclude(jcr);
+   if (!bctx->include) {  
+      bctx->include = new_preinclude(jcr);
+      new_options(jcr, bctx->include);
    }
-   add_file_to_fileset(jcr, file, bctx->fileset, true);
+   set_incexe(jcr, bctx->include);
+   add_regex_to_fileset(jcr, item, type);
    return bRC_OK;
 }
 
+static bRC baculaAddWildToInclude(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;
+   }
+   if (!bctx->include) {  
+      bctx->include = new_preinclude(jcr);
+      new_options(jcr, bctx->include);
+   }
+   set_incexe(jcr, bctx->include);
+   add_wild_to_fileset(jcr, item, type);
+   return bRC_OK;
+}
+
+
+
+
 
 #ifdef TEST_PROGRAM
 
index cbfe199e8019c33c35e21942ca46620f24a17c5e..c17e3bc695238afcc7564063bf656c9b08239a22 100644 (file)
@@ -195,6 +195,7 @@ typedef enum {
   bEventVssRestoreLoadComponentMetadata = 15,
   bEventVssRestoreSetComponentsSelected = 16,
   bEventRestoreObject                   = 17,
+  bEventEndFileSet                      = 18
 } bEventType;
 
 typedef struct s_bEvent {
@@ -244,6 +245,10 @@ typedef struct s_baculaFuncs {
        size_t size);
    void (*baculaFree)(bpContext *ctx, const char *file, int line, void *mem);
    bRC (*AddExclude)(bpContext *ctx, const char *file);
+   bRC (*baculaAddInclude)(bpContext *ctx, const char *file);
+   bRC (*baculaAddIncludeOptions)(bpContext *ctx, const char *opts);
+   bRC (*baculaAddRegexToInclude)(bpContext *ctx, const char *item, int type);
+   bRC (*baculaAddWildToInclude)(bpContext *ctx, const char *item, int type);
 } bFuncs;
 
 
index 0a265a3d856530e23adf15cc24fa1655db7fd1bb..b373c916a774756d92e9767a1de92dc454e5c338 100644 (file)
@@ -717,39 +717,14 @@ static bool init_fileset(JCR *jcr)
    return true;
 }
 
-static findFOPTS *start_options(FF_PKT *ff)
-{
-   int state = ff->fileset->state;
-   findINCEXE *incexe = ff->fileset->incexe;
-
-   if (state != state_options) {
-      ff->fileset->state = state_options;
-      findFOPTS *fo = (findFOPTS *)malloc(sizeof(findFOPTS));
-      memset(fo, 0, sizeof(findFOPTS));
-      fo->regex.init(1, true);
-      fo->regexdir.init(1, true);
-      fo->regexfile.init(1, true);
-      fo->wild.init(1, true);
-      fo->wilddir.init(1, true);
-      fo->wildfile.init(1, true);
-      fo->wildbase.init(1, true);
-      fo->base.init(1, true);
-      fo->fstype.init(1, true);
-      fo->drivetype.init(1, true);
-      incexe->current_opts = fo;
-      incexe->opts_list.append(fo);
-   }
-   return incexe->current_opts;
-
-}
 
 /**
  * Add fname to include/exclude fileset list. First check for
  * | and < and if necessary perform command.
  */
-void add_file_to_fileset(JCR *jcr, const char *fname, findFILESET *fileset,
-                         bool is_file)
+void add_file_to_fileset(JCR *jcr, const char *fname, bool is_file)
 {
+   findFILESET *fileset = jcr->ff->fileset;
    char *p;
    BPIPE *bpipe;
    POOLMEM *fn;
@@ -806,7 +781,7 @@ void add_file_to_fileset(JCR *jcr, const char *fname, findFILESET *fileset,
          } else {
             fileset->incexe->plugin_list.append(new_dlistString(buf));
          }
-      }
+   }
       fclose(ffd);
       break;
    default:
@@ -824,13 +799,19 @@ void add_file_to_fileset(JCR *jcr, const char *fname, findFILESET *fileset,
    }
 }
 
+void set_incexe(JCR *jcr, findINCEXE *incexe)
+{
+   findFILESET *fileset = jcr->ff->fileset;
+   fileset->incexe = incexe;
+}
+
+
 /**
  * Define a new Exclude block in the FileSet
  */
-findFILESET *new_exclude(JCR *jcr)
+findINCEXE *new_exclude(JCR *jcr)
 {
-   FF_PKT *ff = jcr->ff;
-   findFILESET *fileset = ff->fileset;
+   findFILESET *fileset = jcr->ff->fileset;
 
    /* New exclude */
    fileset->incexe = (findINCEXE *)malloc(sizeof(findINCEXE));
@@ -839,16 +820,15 @@ findFILESET *new_exclude(JCR *jcr)
    fileset->incexe->name_list.init();
    fileset->incexe->plugin_list.init();
    fileset->exclude_list.append(fileset->incexe);
-   return fileset;
+   return fileset->incexe;
 }
 
 /**
  * Define a new Include block in the FileSet
  */
-findFILESET *new_include(JCR *jcr)
+findINCEXE *new_include(JCR *jcr)
 {
-   FF_PKT *ff = jcr->ff;
-   findFILESET *fileset = ff->fileset;
+   findFILESET *fileset = jcr->ff->fileset;
 
    /* New include */
    fileset->incexe = (findINCEXE *)malloc(sizeof(findINCEXE));
@@ -857,22 +837,85 @@ findFILESET *new_include(JCR *jcr)
    fileset->incexe->name_list.init(); /* for dlist;  was 1,true for alist */
    fileset->incexe->plugin_list.init();
    fileset->include_list.append(fileset->incexe);
-   return fileset;
+   return fileset->incexe;
+}
+
+/**
+ * Define a new preInclude block in the FileSet
+ *   That is the include is prepended to the other
+ *   Includes.  This is used for plugin exclusions.
+ */
+findINCEXE *new_preinclude(JCR *jcr)
+{
+   findFILESET *fileset = jcr->ff->fileset;
+
+   /* New pre-include */
+   fileset->incexe = (findINCEXE *)malloc(sizeof(findINCEXE));
+   memset(fileset->incexe, 0, sizeof(findINCEXE));
+   fileset->incexe->opts_list.init(1, true);
+   fileset->incexe->name_list.init(); /* for dlist;  was 1,true for alist */
+   fileset->incexe->plugin_list.init();
+   fileset->include_list.prepend(fileset->incexe);
+   return fileset->incexe;
+}
+
+static findFOPTS *start_options(FF_PKT *ff)
+{
+   int state = ff->fileset->state;
+   findINCEXE *incexe = ff->fileset->incexe;
+
+   if (state != state_options) {
+      ff->fileset->state = state_options;
+      findFOPTS *fo = (findFOPTS *)malloc(sizeof(findFOPTS));
+      memset(fo, 0, sizeof(findFOPTS));
+      fo->regex.init(1, true);
+      fo->regexdir.init(1, true);
+      fo->regexfile.init(1, true);
+      fo->wild.init(1, true);
+      fo->wilddir.init(1, true);
+      fo->wildfile.init(1, true);
+      fo->wildbase.init(1, true);
+      fo->base.init(1, true);
+      fo->fstype.init(1, true);
+      fo->drivetype.init(1, true);
+      incexe->current_opts = fo;
+      incexe->opts_list.append(fo);
+   }
+   return incexe->current_opts;
+}
+
+/*
+ * Used by plugins to define a new options block
+ */
+void new_options(JCR *jcr, findINCEXE *incexe)
+{
+   findFOPTS *fo = (findFOPTS *)malloc(sizeof(findFOPTS));
+   memset(fo, 0, sizeof(findFOPTS));
+   fo->regex.init(1, true);
+   fo->regexdir.init(1, true);
+   fo->regexfile.init(1, true);
+   fo->wild.init(1, true);
+   fo->wilddir.init(1, true);
+   fo->wildfile.init(1, true);
+   fo->wildbase.init(1, true);
+   fo->base.init(1, true);
+   fo->fstype.init(1, true);
+   fo->drivetype.init(1, true);
+   incexe->current_opts = fo;
+   incexe->opts_list.append(fo);
+   jcr->ff->fileset->state = state_options;
 }
 
 /**
  * Add a regex to the current fileset
  */
-int add_regex_to_fileset(JCR *jcr, const char *item, int subcode)
+int add_regex_to_fileset(JCR *jcr, const char *item, int type)
 {
-   FF_PKT *ff = jcr->ff;
-   int state;
-   findFOPTS *current_opts;
+   findFOPTS *current_opts = start_options(jcr->ff);
    regex_t *preg;
    int rc;
    char prbuf[500];
 
-   current_opts = start_options(ff);
    preg = (regex_t *)malloc(sizeof(regex_t));
    if (current_opts->flags & FO_IGNORECASE) {
       rc = regcomp(preg, item, REG_EXTENDED|REG_ICASE);
@@ -884,22 +927,42 @@ int add_regex_to_fileset(JCR *jcr, const char *item, int subcode)
       regfree(preg);
       free(preg);
       Jmsg(jcr, M_FATAL, 0, _("REGEX %s compile error. ERR=%s\n"), item, prbuf);
-      state = state_error;
-      return state;
+      return state_error;
    }
-   state = state_options;
-   if (subcode == ' ') {
+   if (type == ' ') {
       current_opts->regex.append(preg);
-   } else if (subcode == 'D') {
+   } else if (type == 'D') {
       current_opts->regexdir.append(preg);
-   } else if (subcode == 'F') {
+   } else if (type == 'F') {
       current_opts->regexfile.append(preg);
    } else {
-      state = state_error;
+      return state_error;
    }
-   return state;
+   return state_options;
 }
 
+/**
+ * Add a wild card to the current fileset
+ */
+int add_wild_to_fileset(JCR *jcr, const char *item, int type)
+{
+   findFOPTS *current_opts = start_options(jcr->ff);
+
+   if (type == ' ') {
+      current_opts->wild.append(bstrdup(item));
+   } else if (type == 'D') {
+      current_opts->wilddir.append(bstrdup(item));
+   } else if (type == 'F') {
+      current_opts->wildfile.append(bstrdup(item));
+   } else if (type == 'B') {
+      current_opts->wildbase.append(bstrdup(item));
+   } else {
+      return state_error;
+   }
+   return state_options;
+}
+
+
 /**
  * Add options to the current fileset
  */
@@ -951,10 +1014,10 @@ static void add_fileset(JCR *jcr, const char *item)
    }
    switch (code) {
    case 'I':
-      fileset = new_include(jcr);
+      (void)new_include(jcr);
       break;
    case 'E':
-      fileset = new_exclude(jcr);
+      (void)new_exclude(jcr);
       break;
    case 'N':                             /* null */
       state = state_none;
@@ -962,12 +1025,12 @@ static void add_fileset(JCR *jcr, const char *item)
    case 'F':                             /* file = */
       /* File item to include or exclude list */
       state = state_include;
-      add_file_to_fileset(jcr, item, fileset, true);
+      add_file_to_fileset(jcr, item, true);
       break;
    case 'P':                              /* plugin */
       /* Plugin item to include list */
       state = state_include;
-      add_file_to_fileset(jcr, item, fileset, false);
+      add_file_to_fileset(jcr, item, false);
       break;
    case 'R':                              /* regex */
       state = add_regex_to_fileset(jcr, item, subcode);
@@ -989,19 +1052,7 @@ static void add_fileset(JCR *jcr, const char *item)
       }
       break;
    case 'W':                               /* wild cards */
-      current_opts = start_options(ff);
-      state = state_options;
-      if (subcode == ' ') {
-         current_opts->wild.append(bstrdup(item));
-      } else if (subcode == 'D') {
-         current_opts->wilddir.append(bstrdup(item));
-      } else if (subcode == 'F') {
-         current_opts->wildfile.append(bstrdup(item));
-      } else if (subcode == 'B') {
-         current_opts->wildbase.append(bstrdup(item));
-      } else {
-         state = state_error;
-      }
+      state = add_wild_to_fileset(jcr, item, subcode);
       break;
    case 'O':                                /* Options */
       state = add_options_to_fileset(jcr, item);
@@ -1303,6 +1354,7 @@ static int set_options(findFOPTS *fo, const char *opts)
 static int fileset_cmd(JCR *jcr)
 {
    BSOCK *dir = jcr->dir_bsock;
+   int rtnstat;
 
 #if defined(WIN32_VSS)
    int vss = 0;
@@ -1322,7 +1374,9 @@ static int fileset_cmd(JCR *jcr)
    if (!term_fileset(jcr)) {
       return 0;
    }
-   return dir->fsend(OKinc);
+   rtnstat = dir->fsend(OKinc);
+   generate_plugin_event(jcr, bEventEndFileSet);
+   return rtnstat;
 }
 
 static void free_bootstrap(JCR *jcr)
index 31cdfb3e0060d8ede47a419265ff50a5bc56e2ed..9def837dd9128c057decf6cd8c6d332eee2b8ded 100644 (file)
@@ -67,6 +67,11 @@ bxattr_exit_code build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt);
 bxattr_exit_code parse_xattr_streams(JCR *jcr, int stream);
 
 /* from job.c */
-findFILESET *new_exclude(JCR *jcr);
-void add_file_to_fileset(JCR *jcr, const char *fname, findFILESET *fileset,
-                         bool is_file); 
+findINCEXE *new_exclude(JCR *jcr);
+findINCEXE *new_preinclude(JCR *jcr);
+void set_incexe(JCR *jcr, findINCEXE *incexe);
+void new_options(JCR *jcr, findINCEXE *incexe);
+void add_file_to_fileset(JCR *jcr, const char *fname, bool is_file); 
+int add_options_to_fileset(JCR *jcr, const char *item);
+int add_wild_to_fileset(JCR *jcr, const char *item, int type);
+int add_regex_to_fileset(JCR *jcr, const char *item, int type);