@echo "Compiling backend $< ..."
$(NO_ECHO)$(LIBTOOL_COMPILE) $(CXX) $(DEFS) $(DEBUG) $(CPPFLAGS) $(CFLAGS) -I${SRCDIR} -I${FDDIR} -DLOGDIR=\"$(DESTDIR)$(working_dir)\" -c $<
+test_metaplugin_backend_fd: $(TESTMETAPLUGINBACKENDOBJ) test_metaplugin_backend_fd.lo
+ @echo "Building $@ ..."
+ $(NO_ECHO)$(LIBTOOL_LINK) --silent $(CXX) $(LDFLAGS) test_metaplugin_backend_fd.lo $(TESTMETAPLUGINBACKENDOBJ) -o $@
+
+test_metaplugin-fd.la: $(PTCOMMOBJ) $(PLUGINLIBSOBJ) $(METAPLUGINOBJ) test_metaplugin-fd.lo
+ @echo "Linking $(@:.la=.so) ..."
+ $(NO_ECHO)$(LIBTOOL_LINK) --silent $(CXX) $(LDFLAGS) -shared $^ -o $@ -rpath $(plugindir) -module -export-dynamic -avoid-version
+
pluginlib_test: $(PLUGINLIBSTESTOBJ) $(PLUGINLIBSTEST) $(UNITTESTSOBJ) $(LIBBACOBJ)
@echo "Building $@ ..."
$(NO_ECHO)$(LIBTOOL_LINK) --silent $(CXX) $(LDFLAGS) -L$(LIBDIR) -lbac $(PLUGINLIBSTESTOBJ) -o $@
Bacula(R) is a registered trademark of Kern Sibbald.
*/
/**
- * @file metaplugin.h
+ * @file metaplugin.cpp
* @author Radosław Korzeniewski (radoslaw@korzeniewski.net)
* @brief This is a Bacula metaplugin interface.
* @version 2.1.0
}
/*
- * The PLUGIN is not using this callback to handle restore.
+ * The PLUGIN is using this callback to handle Core restore.
*/
bRC METAPLUGIN::startRestoreFile(bpContext *ctx, const char *cmd)
{
+ if (CORELOCALRESTORE && islocalpath(where)){
+ DMSG0(ctx, DDEBUG, "Forwarding restore to Core\n");
+ return bRC_Core;
+ }
return bRC_OK;
}
{
ASSERT_CTX;
- DMSG0(ctx, D1, "startRestoreFile.\n");
+ DMSG1(ctx, D1, "startRestoreFile: %s\n", NPRT(cmd));
METAPLUGIN *self = pluginclass(ctx);
return self->startRestoreFile(ctx, cmd);
}
#define PLUGINLIB_METAPLUGIN_H
+// custom checkFile() callback
+typedef bRC (*checkFile_t)(bpContext *ctx, char *fname);
+
+// metadata handling map
+struct metadataTypeMap
+{
+ const char *command;
+ metadata_type type;
+};
+extern const metadataTypeMap plugin_metadata_map[];
+
// Plugin Info definitions
extern const char *PLUGIN_LICENSE;
extern const char *PLUGIN_AUTHOR;
extern const char *PLUGIN_DESCRIPTION;
// Plugin linking time variables
-extern const char *PLUGINPREFIX;
-extern const char *PLUGINNAME;
-extern const char *PLUGINNAMESPACE;
-extern const bool CUSTOMNAMESPACE;
+extern const char *PLUGINPREFIX; /// is used for prefixing every Job and Debug messages generted by a plugin
+extern const char *PLUGINNAME; /// should match the backend $pluginname$ used for Handshake procedure
+extern const bool CUSTOMNAMESPACE; /// defines if metaplugin should send `Namespace=...` backend plugin parameter using PLUGINNAMESPACE variable
+extern const char *PLUGINNAMESPACE; /// custom backend plugin namespace used as file name prefix
extern const char *PLUGINAPI;
extern const char *BACKEND_CMD;
-// custom checkFile() callback
-typedef bRC (*checkFile_t)(bpContext *ctx, char *fname);
-extern checkFile_t checkFile;
+/// defines if metaplugin should handle local filesystem restore with Bacula Core functions
+/// `false` means metaplugin will redirect local restore to backend
+/// `true` means Bacula Core functions will handle local restore
+extern const bool CORELOCALRESTORE;
// The list of restore options saved to the RestoreObject.
extern struct ini_items plugin_items_dump[];
// the list of valid plugin options
extern const char *valid_params[];
-struct metadataTypeMap
-{
- const char *command;
- metadata_type type;
-};
-
-extern const metadataTypeMap plugin_metadata_map[];
+// custom checkFile() callback
+extern checkFile_t checkFile;
/*
* This is a main plugin API class. It manages a plugin context.
alist * plugutil_str_split_to_alist(const char * str, const char sep = '.');
+/**
+ * @brief Verifies if path is local except '/'
+ *
+ * @param path
+ * @return true
+ * @return false
+ */
+inline bool islocalpath(const char *path)
+{
+ bool result = path && strlen(path) > 1;
+ bool spath = path[0] == '/';
+#ifdef HAVE_WIN32
+ bool wpath = isalpha(path[0]) && path[1] == ':' ; // simple drive letter
+#else
+ bool wpath = false;
+#endif
+ return result && (spath || wpath);
+}
+
/* plugin parameters manipulation */
bool render_param(POOLMEM **param, const char *pname, const char *fmt, const char *name, const char *value);
bool render_param(POOLMEM **param, const char *pname, const char *fmt, const char *name, const int value);
bFuncs *bfuncs;
bInfo *binfo;
+struct vectstruct
+{
+ const char *path;
+ bool result;
+ const char *descr;
+};
+
int main()
{
Unittests pluglib_test("pluglib_test");
ok(bstrcmp(param.c_str(), fname1) , "check scan parameter for char* str param");
nok(scan_parameter_str(cmd2, "prefix", param), "check scan parameter for char* str not match");
+ const vectstruct testvect1[] = {
+ { "", false, "checking empty" },
+ { "/", false, "checking slash" },
+ { "other", false, "checking other" },
+ { "/tmp", true, "checking local" },
+ { "/tmp/restore", true, "checking local" },
+#ifdef HAVE_WIN32
+ { "c:", true, "checking local win32" },
+ { "d:/", true, "checking local win32" },
+ { "E:/", true, "checking local win32" },
+ { "F:/test", true, "checking local win32" },
+ { "g:/test/restore", true, "checking local win32" },
+#endif
+ { NULL, false, NULL },
+ };
+
+ for (int i = 0; testvect1[i].path != NULL; i++)
+ {
+ bool result = islocalpath(testvect1[i].path);
+ ok(result == testvect1[i].result, testvect1[i].descr);
+ }
+
return report();
}