--- /dev/null
+/*
+ Bacula(R) - The Network Backup Solution
+
+ Copyright (C) 2000-2020 Kern Sibbald
+
+ The original author of Bacula is Kern Sibbald, with contributions
+ from many others, a complete list can be found in the file AUTHORS.
+
+ You may use this file and others of this release according to the
+ license defined in the LICENSE file, which includes the Affero General
+ Public License, v3.0 ("AGPLv3") and some additional permissions and
+ terms pursuant to its AGPLv3 Section 7.
+
+ This notice must be preserved when any source code is
+ conveyed and/or propagated.
+
+ Bacula(R) is a registered trademark of Kern Sibbald.
+*/
+/**
+ * @file commctx.h
+ * @author Radosław Korzeniewski (radoslaw@korzeniewski.net)
+ * @brief This is a Bacula plugin command context switcher template.
+ * @version 1.1.0
+ * @date 2020-12-23
+ *
+ * @copyright Copyright (c) 2020 All rights reserved. IP transferred to Bacula Systems according to agreement.
+ */
+
+#ifndef COMMCTX_H
+#define COMMCTX_H
+
+#include "pluginlib.h"
+#include "smartalist.h"
+
+
+template<typename T>
+class COMMCTX : public SMARTALLOC
+{
+ struct CMD : public SMARTALLOC
+ {
+ POOL_MEM cmd;
+ T * ptr;
+ CMD(const char * command) : cmd(PM_FNAME), ptr(New(T(command))) { pm_strcpy(cmd, command); };
+#if __cplusplus > 201103L
+ CMD() = delete;
+ CMD(CMD &) = delete;
+ CMD(CMD &&) = delete;
+#endif
+ ~CMD() { delete ptr; };
+ };
+
+ /** The command context list for multiple config execution for a single job */
+ smart_alist<CMD> _command_list;
+
+public:
+ T * ctx;
+
+ COMMCTX() : ctx(NULL) {};
+#if __cplusplus > 201103L
+ COMMCTX(COMMCTX &) = delete;
+ COMMCTX(COMMCTX &&) = delete;
+ ~COMMCTX() = default;
+#else
+ ~COMMCTX() {};
+#endif
+
+ T * switch_command(const char *command);
+ bool check_command(const char *command);
+ void foreach_command(void (*func)(T *, void *), void *param);
+};
+
+
+/**
+ * @brief Switches current command context to requested.
+ *
+ * @tparam T is command context type.
+ * @param command is command context string to switch into.
+ * @return T* is command context pointer.
+ */
+template<typename T>
+T * COMMCTX<T>::switch_command(const char * command)
+{
+ CMD * cmdctx;
+ foreach_alist(cmdctx, &_command_list)
+ {
+ if (bstrcmp(cmdctx->cmd.c_str(), command))
+ {
+ ctx = cmdctx->ptr;
+ return ctx;
+ }
+ }
+
+ cmdctx = New(CMD(command));
+ _command_list.append(cmdctx);
+ ctx = cmdctx->ptr;
+
+ return ctx;
+}
+
+/**
+ * @brief Checks if command context is already defined on list.
+ *
+ * @tparam T is command context type.
+ * @param command is command context string to check.
+ * @return true when command context already exist.
+ * @return false when command context does not exist yet.
+ */
+template<typename T>
+bool COMMCTX<T>::check_command(const char *command)
+{
+ CMD * cmdctx;
+ foreach_alist(cmdctx, &_command_list)
+ {
+ if (bstrcmp(cmdctx->cmd.c_str(), command))
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ * @brief Iterate on all command context to execute function.
+ *
+ * @tparam T is command context type.
+ * @param param is the execution function param.
+ */
+template<typename T>
+void COMMCTX<T>::foreach_command(void(*func)(T*, void*), void* param)
+{
+ CMD * cmdctx;
+ foreach_alist(cmdctx, &_command_list)
+ {
+ ctx = cmdctx->ptr;
+ func(ctx, param);
+ }
+}
+
+#endif /* COMMCTX_H */
--- /dev/null
+/*
+ Bacula(R) - The Network Backup Solution
+
+ Copyright (C) 2000-2020 Kern Sibbald
+
+ The original author of Bacula is Kern Sibbald, with contributions
+ from many others, a complete list can be found in the file AUTHORS.
+
+ You may use this file and others of this release according to the
+ license defined in the LICENSE file, which includes the Affero General
+ Public License, v3.0 ("AGPLv3") and some additional permissions and
+ terms pursuant to its AGPLv3 Section 7.
+
+ This notice must be preserved when any source code is
+ conveyed and/or propagated.
+
+ Bacula(R) is a registered trademark of Kern Sibbald.
+*/
+/**
+ * @file commctx_test.cpp
+ * @author Radosław Korzeniewski (radoslaw@korzeniewski.net)
+ * @brief A Bacula plugin command context switcher template - unittest.
+ * @version 1.1.0
+ * @date 2020-12-23
+ *
+ * @copyright Copyright (c) 2020 All rights reserved. IP transferred to Bacula Systems according to agreement.
+ */
+
+#include "pluginlib.h"
+#include "commctx.h"
+#include "unittests.h"
+
+bFuncs *bfuncs;
+bInfo *binfo;
+
+static int referencenumber = 0;
+
+struct testctx : public SMARTALLOC
+{
+ const char * cmd;
+ testctx(const char *command) : cmd(command) { referencenumber++; };
+ ~testctx() { referencenumber--; };;
+};
+
+int main()
+{
+ Unittests pluglib_test("commctx_test");
+
+ // Pmsg0(0, "Initialize tests ...\n");
+
+#define TEST1 "TEST1"
+#define TEST2 "TEST2"
+
+ {
+ COMMCTX<testctx> ctx;
+
+ nok(ctx.check_command("TEST1"), "test empty ctx list");
+ ok(referencenumber == 0, "check no allocation yet");
+
+ auto testctx1 = ctx.switch_command(TEST1);
+ ok(testctx1 != nullptr, "test first command");
+ ok(referencenumber == 1, "check allocation");
+
+ auto testctx2 = ctx.switch_command(TEST2);
+ ok(testctx2 != nullptr, "test next command");
+ ok(referencenumber == 2, "check allocation");
+
+ auto currentctx = ctx.switch_command(TEST1);
+ ok(currentctx != nullptr, "test switch command");
+ ok(currentctx == testctx1, "test switch command to proper");
+ ok(referencenumber == 2, "check allocation");
+
+ ok(ctx.check_command(TEST2), "test check command");
+ }
+
+ ok(referencenumber == 0, "check smart free");
+
+ return report();
+}