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
+ modify it under the terms of version three of the GNU Affero General Public
License as published by the Free Software Foundation, which is
listed in the file LICENSE.
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
+ You should have received a copy of the GNU Affero 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.
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 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
baculaFree,
baculaAddExclude,
baculaAddInclude,
- baculaAddIncludeOptions,
- baculaAddRegexToInclude,
- baculaAddWildToInclude
+ baculaAddOptions,
+ baculaAddRegex,
+ baculaAddWild,
+ baculaNewOptions,
+ baculaNewInclude
};
/*
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;
}
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:
Plugin *plugin;
int i = 0;
int len;
- char *p;
char *cmd = ff_pkt->top_fname;
struct save_pkt sp;
bEvent event;
POOL_MEM link(PM_FNAME);
if (!plugin_list || !jcr->plugin_ctx_list || jcr->is_job_canceled()) {
- Jmsg1(jcr, M_FATAL, 0, "Command plugin \"%s\" not loaded.\n", cmd);
+ Jmsg1(jcr, M_FATAL, 0, "Command plugin \"%s\" requested, but is not loaded.\n", cmd);
return 1; /* Return if no plugins loaded */
}
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;
}
/*
* 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;
}
rc, attr->ofname);
return CF_ERROR;
}
+ if (rp.create_status == CF_SKIP) {
+ return CF_SKIP;
+ }
if (rp.create_status == CF_ERROR) {
Qmsg1(jcr, M_ERROR, 0, _("Plugin createFile call failed. Returned CF_ERROR file=%s\n"),
attr->ofname);
plugin->file, FD_PLUGIN_INTERFACE_VERSION, info->version);
return false;
}
- if (strcmp(info->plugin_license, "Bacula GPLv2") != 0 &&
- strcmp(info->plugin_license, "GPLv2") != 0) {
+ if (strcmp(info->plugin_license, "Bacula AGPLv3") != 0 &&
+ strcmp(info->plugin_license, "AGPLv3") != 0) {
Jmsg(NULL, M_ERROR, 0, _("Plugin license incompatible. Plugin=%s license=%s\n"),
plugin->file, info->plugin_license);
Dmsg2(50, "Plugin license incompatible. Plugin=%s license=%s\n",
}
set_incexe(jcr, bctx->exclude);
add_file_to_fileset(jcr, file, true);
+ Dmsg1(100, "Add exclude file=%s\n", file);
return bRC_OK;
}
}
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 baculaAddIncludeOptions(bpContext *ctx, const char *opts)
+static bRC baculaAddOptions(bpContext *ctx, const char *opts)
{
JCR *jcr;
bacula_ctx *bctx;
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);
+ Dmsg1(1000, "Add options=%s\n", opts);
return bRC_OK;
}
-static bRC baculaAddRegexToInclude(bpContext *ctx, const char *item, int type)
+static bRC baculaAddRegex(bpContext *ctx, const char *item, int type)
{
JCR *jcr;
bacula_ctx *bctx;
if (!item) {
return bRC_Error;
}
- if (!bctx->include) {
- bctx->include = new_preinclude(jcr);
- new_options(jcr, bctx->include);
- }
- set_incexe(jcr, bctx->include);
add_regex_to_fileset(jcr, item, type);
+ Dmsg1(100, "Add regex=%s\n", item);
return bRC_OK;
}
-static bRC baculaAddWildToInclude(bpContext *ctx, const char *item, int type)
+static bRC baculaAddWild(bpContext *ctx, const char *item, int type)
{
JCR *jcr;
bacula_ctx *bctx;
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);
+ 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;
+ }
+ (void)new_include(jcr);
+ return bRC_OK;
+}
#ifdef TEST_PROGRAM
Dmsg0(dbglvl, "bacula: OK ...\n");
close_memory_pool();
- sm_dump(false);
+ sm_dump(false); /* unit test */
return 0;
}