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);
/*
baculaDebugMsg,
baculaMalloc,
baculaFree,
- baculaAddExclude
+ baculaAddExclude,
+ baculaAddInclude,
+ baculaAddIncludeOptions,
+ baculaAddRegexToInclude,
+ baculaAddWildToInclude
};
/*
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)
#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.
{
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
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;
} else {
fileset->incexe->plugin_list.append(new_dlistString(buf));
}
- }
+ }
fclose(ffd);
break;
default:
}
}
+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));
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));
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);
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
*/
}
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;
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);
}
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);
static int fileset_cmd(JCR *jcr)
{
BSOCK *dir = jcr->dir_bsock;
+ int rtnstat;
#if defined(WIN32_VSS)
int vss = 0;
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)