From 61a8245a2b7eba38053f93f738840b4698fa1313 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Mon, 19 Oct 2015 13:37:04 -0700 Subject: [PATCH] Remove installation of manpage for bplugininfo --- bacula/manpages/Makefile.in | 2 +- bacula/src/tools/bpluginfo.c | 625 +++++++++++++++++++++++++++++++++++ 2 files changed, 626 insertions(+), 1 deletion(-) create mode 100644 bacula/src/tools/bpluginfo.c diff --git a/bacula/manpages/Makefile.in b/bacula/manpages/Makefile.in index e4d107a2ab..db38f6497b 100644 --- a/bacula/manpages/Makefile.in +++ b/bacula/manpages/Makefile.in @@ -8,7 +8,7 @@ MAN8 = bacula.8 bacula-dir.8 bacula-fd.8 bacula-sd.8 \ bconsole.8 bcopy.8 bextract.8 bls.8 bscan.8 btape.8 \ - btraceback.8 dbcheck.8 bwild.8 bregex.8 bpluginfo.8 + btraceback.8 dbcheck.8 bwild.8 bregex.8 MAN1 = bsmtp.1 bat.1 diff --git a/bacula/src/tools/bpluginfo.c b/bacula/src/tools/bpluginfo.c new file mode 100644 index 0000000000..1655bd5bca --- /dev/null +++ b/bacula/src/tools/bpluginfo.c @@ -0,0 +1,625 @@ +/* + * Contributed in 2012 by Inteos sp. z o.o. + * + * Utility tool display various information about Bacula plugin, + * including but not limited to: + * - Name and Author of the plugin + * - Plugin License + * - Description + * - API version + * - Enabled functions, etc. + */ +/* + Bacula® - The Network Backup Solution + + Copyright (C) 2006-2014 Free Software Foundation Europe e.V. + + The main 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. + + Bacula® is a registered trademark of Kern Sibbald. +*/ + +#include +#include +#include +#include +#include +#include +#ifndef __WIN32__ +#include +#endif +#include "bacula.h" +#include "../filed/fd_plugins.h" +#include "../dird/dir_plugins.h" +// I can't include sd_plugins.h here ... +#include "../stored/stored.h" +#include "assert_macro.h" + +extern "C" { + typedef int (*loadPlugin) (void *binfo, void *bfuncs, void **pinfo, + void **pfuncs); + typedef int (*unloadPlugin) (void); +} +#define DEFAULT_API_VERSION 1 +enum plugintype { + DIRPLUGIN, + FDPLUGIN, + SDPLUGIN, + ERRORPLUGIN, +}; + +/* + * pDirInfo + * pInfo + * psdInfo + */ +typedef union _pluginfo pluginfo; +union _pluginfo { + pDirInfo pdirinfo; + pInfo pfdinfo; + psdInfo psdinfo; +}; + +/* + * pDirFuncs + * pFuncs + * psdFuncs + */ +typedef union _plugfuncs plugfuncs; +union _plugfuncs { + pDirFuncs pdirfuncs; + pFuncs pfdfuncs; + psdFuncs psdfuncs; +}; + +/* + * bDirFuncs + * bFuncs + * bsdFuncs + */ +/* + * TODO: change to union + * +typedef union _baculafuncs baculafuncs; +union _baculafuncs { + bDirFuncs bdirfuncs; + bFuncs bfdfuncs; + bsdFuncs bsdfuncs; +}; +*/ +typedef struct _baculafuncs baculafuncs; +struct _baculafuncs { + uint32_t size; + uint32_t version; + int (*registerBaculaEvents) (void *ctx, ...); + int (*getBaculaValue) (void *ctx, int var, void *value); + int (*setBaculaValue) (void *ctx, int var, void *value); + int (*JobMessage) (void *ctx, const char *file, int line, int type, int64_t mtime, + const char *fmt, ...); + int (*DebugMessage) (void *ctx, const char *file, int line, int level, + const char *fmt, ...); + void *(*baculaMalloc) (void *ctx, const char *file, int line, size_t size); + void (*baculaFree) (void *ctx, const char *file, int line, void *mem); +}; + +/* + * bDirInfo + * bInfo + * bsdInfo + */ +typedef union _baculainfos baculainfos; +union _baculainfos { + bDirInfo bdirinfo; + bInfo bfdinfo; + bsdInfo bsdinfo; +}; + +/* +typedef struct _baculainfos baculainfos; +struct _baculainfos { + uint32_t size; + uint32_t version; +}; +*/ + +typedef struct _progdata progdata; +struct _progdata { + int verbose; + int listinfo; + int listfunc; + char *pluginfile; + void *pluginhandle; + int bapiversion; + int bplugtype; + pluginfo *pinfo; + plugfuncs *pfuncs; +}; + +/* memory allocation/deallocation */ +#define MALLOC(size) \ + (char *) bmalloc ( size ); + +#define ASSERT_MEMORY(m) \ + if ( m == NULL ){ \ + printf ( "Error: memory allocation error!\n" ); \ + exit (10); \ + } + +#define FREE(ptr) \ + if ( ptr != NULL ){ \ + bfree ( ptr ); \ + ptr = NULL; \ + } + +int registerBaculaEvents(void *ctx, ...) +{ + return 0; +}; + +int getBaculaValue(void *ctx, int var, void *value) +{ + return 0; +}; + +int setBaculaValue(void *ctx, int var, void *value) +{ + return 0; +}; + +int DebugMessage(void *ctx, const char *file, int line, int level, const char *fmt, ...) +{ +#ifdef DEBUGMSG + printf("DG: %s:%d %s\n", file, line, fmt); +#endif + return 0; +}; + +int JobMessage(void *ctx, const char *file, int line, int type, int64_t mtime, + const char *fmt, ...) +{ +#ifdef DEBUGMSG + printf("JM: %s:%d <%d> %s\n", file, line, type, fmt); +#endif + return 0; +}; + +void *baculaMalloc(void *ctx, const char *file, int line, size_t size) +{ + return MALLOC(size); +}; + +void baculaFree(void *ctx, const char *file, int line, void *mem) +{ + FREE(mem); +}; + +/* + * displays a short help + */ +void print_help(int argc, char *argv[]) +{ + + printf("\n" + "Usage: bpluginfo [options] \n" + " -v verbose\n" + " -i list plugin header information only (default)\n" + " -f list plugin functions information only\n" + " -a bacula api version (default %d)\n" + " -h help screen\n" "\n", DEFAULT_API_VERSION); +} + +/* allocates and resets a main program data variable */ +progdata *allocpdata(void) +{ + + progdata *pdata; + + pdata = (progdata *) bmalloc(sizeof(progdata)); + ASSERT_MEMORY(pdata); + memset(pdata, 0, sizeof(progdata)); + + return pdata; +} + +/* releases all allocated program data resources */ +void freepdata(progdata * pdata) +{ + + if (pdata->pluginfile) { + FREE(pdata->pluginfile); + } + FREE(pdata); +} + +/* + * parse execution arguments and fills required pdata structure fields + * + * input: + * pdata - pointer to program data structure + * argc, argv - execution envinroment variables + * output: + * pdata - required structure fields + * + * supported options: + * -v verbose flag + * -i list plugin header info only (default) + * -f list implemented functions only + * -a bacula api version (default 1) + * -h help screen + */ +void parse_args(progdata * pdata, int argc, char *argv[]) +{ + + int i; + char *dirtmp; + char *progdir; + int api; + int s; + + if (argc < 2) { + /* TODO - add a real help screen */ + printf("\nNot enough parameters!\n"); + print_help(argc, argv); + exit(1); + } + + if (argc > 5) { + /* TODO - add a real help screen */ + printf("\nToo many parameters!\n"); + print_help(argc, argv); + exit(1); + } + + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-h") == 0) { + /* help screen */ + print_help(argc, argv); + exit(0); + } + if (strcmp(argv[i], "-v") == 0) { + /* verbose option */ + pdata->verbose = 1; + continue; + } + if (strcmp(argv[i], "-f") == 0) { + /* functions list */ + pdata->listfunc = 1; + continue; + } + if (strcmp(argv[i], "-i") == 0) { + /* header list */ + pdata->listinfo = 1; + continue; + } + if (strcmp(argv[i], "-a") == 0) { + /* bacula api version */ + if (i < argc - 1) { + s = sscanf(argv[i + 1], "%d", &api); + if (s == 1) { + pdata->bapiversion = api; + i++; + continue; + } + } + printf("\nAPI version number required!\n"); + print_help(argc, argv); + exit(1); + } + if (!pdata->pluginfile) { + if (argv[i][0] != '/') { + dirtmp = MALLOC(PATH_MAX); + ASSERT_MEMORY(dirtmp); + progdir = MALLOC(PATH_MAX); + ASSERT_MEMORY(progdir); + dirtmp = getcwd(dirtmp, PATH_MAX); + + strcat(dirtmp, "/"); + strcat(dirtmp, argv[i]); + + if (realpath(dirtmp, progdir) == NULL) { + /* error in resolving path */ + FREE(progdir); + progdir = bstrdup(argv[i]); + } + pdata->pluginfile = bstrdup(progdir); + FREE(dirtmp); + FREE(progdir); + } else { + pdata->pluginfile = bstrdup(argv[i]); + } + continue; + } + } +} + +/* + * checks a plugin type based on a plugin magic string + * + * input: + * pdata - program data with plugin info structure + * output: + * int - enum plugintype + */ +int getplugintype(progdata * pdata) +{ + + ASSERT_NVAL_RET_V(pdata, ERRORPLUGIN); + + pluginfo *pinfo = pdata->pinfo; + + ASSERT_NVAL_RET_V(pinfo, ERRORPLUGIN); + + if (pinfo->pdirinfo.plugin_magic && + strcmp(pinfo->pdirinfo.plugin_magic, DIR_PLUGIN_MAGIC) == 0) { + return DIRPLUGIN; + } else + if (pinfo->pfdinfo.plugin_magic && + strcmp(pinfo->pfdinfo.plugin_magic, FD_PLUGIN_MAGIC) == 0) { + return FDPLUGIN; + } else + if (pinfo->psdinfo.plugin_magic && + strcmp(pinfo->psdinfo.plugin_magic, SD_PLUGIN_MAGIC) == 0) { + return SDPLUGIN; + } else { + return ERRORPLUGIN; + } +} + +/* + * prints any available information about a plugin + * + * input: + * pdata - program data with plugin info structure + * output: + * printed info + */ +void dump_pluginfo(progdata * pdata) +{ + + ASSERT_NVAL_RET(pdata); + + pluginfo *pinfo = pdata->pinfo; + + ASSERT_NVAL_RET(pinfo); + + plugfuncs *pfuncs = pdata->pfuncs; + + ASSERT_NVAL_RET(pfuncs); + + switch (pdata->bplugtype) { + case DIRPLUGIN: + printf("\nPlugin type:\t\tBacula Director plugin\n"); + if (pdata->verbose) { + printf("Plugin magic:\t\t%s\n", NPRT(pinfo->pdirinfo.plugin_magic)); + } + printf("Plugin version:\t\t%s\n", pinfo->pdirinfo.plugin_version); + printf("Plugin release date:\t%s\n", NPRT(pinfo->pdirinfo.plugin_date)); + printf("Plugin author:\t\t%s\n", NPRT(pinfo->pdirinfo.plugin_author)); + printf("Plugin licence:\t\t%s\n", NPRT(pinfo->pdirinfo.plugin_license)); + printf("Plugin description:\t%s\n", NPRT(pinfo->pdirinfo.plugin_description)); + printf("Plugin API version:\t%d\n", pinfo->pdirinfo.version); + break; + case FDPLUGIN: + printf("\nPlugin type:\t\tFile Daemon plugin\n"); + if (pdata->verbose) { + printf("Plugin magic:\t\t%s\n", NPRT(pinfo->pfdinfo.plugin_magic)); + } + printf("Plugin version:\t\t%s\n", pinfo->pfdinfo.plugin_version); + printf("Plugin release date:\t%s\n", NPRT(pinfo->pfdinfo.plugin_date)); + printf("Plugin author:\t\t%s\n", NPRT(pinfo->pfdinfo.plugin_author)); + printf("Plugin licence:\t\t%s\n", NPRT(pinfo->pfdinfo.plugin_license)); + printf("Plugin description:\t%s\n", NPRT(pinfo->pfdinfo.plugin_description)); + printf("Plugin API version:\t%d\n", pinfo->pfdinfo.version); + break; + case SDPLUGIN: + printf("\nPlugin type:\t\tBacula Storage plugin\n"); + if (pdata->verbose) { + printf("Plugin magic:\t\t%s\n", NPRT(pinfo->psdinfo.plugin_magic)); + } + printf("Plugin version:\t\t%s\n", pinfo->psdinfo.plugin_version); + printf("Plugin release date:\t%s\n", NPRT(pinfo->psdinfo.plugin_date)); + printf("Plugin author:\t\t%s\n", NPRT(pinfo->psdinfo.plugin_author)); + printf("Plugin licence:\t\t%s\n", NPRT(pinfo->psdinfo.plugin_license)); + printf("Plugin description:\t%s\n", NPRT(pinfo->psdinfo.plugin_description)); + printf("Plugin API version:\t%d\n", pinfo->psdinfo.version); + break; + default: + printf("\nUnknown plugin type or other Error\n\n"); + } +} + +/* + * prints any available information about plugin' functions + * + * input: + * pdata - program data with plugin info structure + * output: + * printed info + */ +void dump_plugfuncs(progdata * pdata) +{ + + ASSERT_NVAL_RET(pdata); + + plugfuncs *pfuncs = pdata->pfuncs; + + ASSERT_NVAL_RET(pfuncs); + + printf("\nPlugin functions:\n"); + + switch (pdata->bplugtype) { + case DIRPLUGIN: + if (pdata->verbose) { + if (pfuncs->pdirfuncs.newPlugin) { + printf(" newPlugin()\n"); + } + if (pfuncs->pdirfuncs.freePlugin) { + printf(" freePlugin()\n"); + } + } + if (pfuncs->pdirfuncs.getPluginValue) { + printf(" getPluginValue()\n"); + } + if (pfuncs->pdirfuncs.setPluginValue) { + printf(" setPluginValue()\n"); + } + if (pfuncs->pdirfuncs.handlePluginEvent) { + printf(" handlePluginEvent()\n"); + } + break; + case FDPLUGIN: + if (pdata->verbose) { + if (pfuncs->pfdfuncs.newPlugin) { + printf(" newPlugin()\n"); + } + if (pfuncs->pfdfuncs.freePlugin) { + printf(" freePlugin()\n"); + } + } + if (pfuncs->pfdfuncs.getPluginValue) { + printf(" getPluginValue()\n"); + } + if (pfuncs->pfdfuncs.setPluginValue) { + printf(" setPluginValue()\n"); + } + if (pfuncs->pfdfuncs.handlePluginEvent) { + printf(" handlePluginEvent()\n"); + } + if (pfuncs->pfdfuncs.startBackupFile) { + printf(" startBackupFile()\n"); + } + if (pfuncs->pfdfuncs.endBackupFile) { + printf(" endBackupFile()\n"); + } + if (pfuncs->pfdfuncs.startRestoreFile) { + printf(" startRestoreFile()\n"); + } + if (pfuncs->pfdfuncs.endRestoreFile) { + printf(" endRestoreFile()\n"); + } + if (pfuncs->pfdfuncs.pluginIO) { + printf(" pluginIO()\n"); + } + if (pfuncs->pfdfuncs.createFile) { + printf(" createFile()\n"); + } + if (pfuncs->pfdfuncs.setFileAttributes) { + printf(" setFileAttributes()\n"); + } + if (pfuncs->pfdfuncs.checkFile) { + printf(" checkFile()\n"); + } + break; + case SDPLUGIN: + if (pdata->verbose) { + if (pfuncs->psdfuncs.newPlugin) { + printf(" newPlugin()\n"); + } + if (pfuncs->psdfuncs.freePlugin) { + printf(" freePlugin()\n"); + } + } + if (pfuncs->psdfuncs.getPluginValue) { + printf(" getPluginValue()\n"); + } + if (pfuncs->psdfuncs.setPluginValue) { + printf(" setPluginValue()\n"); + } + if (pfuncs->psdfuncs.handlePluginEvent) { + printf(" handlePluginEvent()\n"); + } + break; + default: + printf("\nUnknown plugin type or other Error\n\n"); + } +} + +/* + * input parameters: + * argv[0] [options] + * + * exit codes: + * 0 - success + * 1 - cannot load a plugin + * 2 - cannot find a loadPlugin function + * 3 - cannot find an unloadPlugin function + * 10 - not enough memory + */ +int main(int argc, char *argv[]) +{ + + progdata *pdata; + loadPlugin loadplugfunc; + unloadPlugin unloadplugfunc; + baculafuncs bfuncs = { + sizeof(bfuncs), + 1, + registerBaculaEvents, + getBaculaValue, + setBaculaValue, + JobMessage, + DebugMessage, + baculaMalloc, + baculaFree, + }; + baculainfos binfos; + + pdata = allocpdata(); + parse_args(pdata, argc, argv); + + binfos.bfdinfo.size = sizeof(binfos); + binfos.bfdinfo.version = DEFAULT_API_VERSION; + + pdata->pluginhandle = dlopen(pdata->pluginfile, RTLD_LAZY); + if (pdata->pluginhandle == NULL) { + printf("\nCannot load a plugin: %s\n\n", dlerror()); + freepdata(pdata); + exit(1); + } + + loadplugfunc = (loadPlugin) dlsym(pdata->pluginhandle, "loadPlugin"); + if (loadplugfunc == NULL) { + printf("\nCannot find loadPlugin function: %s\n", dlerror()); + printf("\nWhether the file is a really Bacula plugin?\n\n"); + freepdata(pdata); + exit(2); + } + + unloadplugfunc = (unloadPlugin) dlsym(pdata->pluginhandle, "unloadPlugin"); + if (unloadplugfunc == NULL) { + printf("\nCannot find unloadPlugin function: %s\n", dlerror()); + printf("\nWhether the file is a really Bacula plugin?\n\n"); + freepdata(pdata); + exit(3); + } + + if (pdata->bapiversion > 0) { + binfos.bdirinfo.version = pdata->bapiversion; + } + + loadplugfunc(&binfos, &bfuncs, (void **)&pdata->pinfo, (void **)&pdata->pfuncs); + + pdata->bplugtype = getplugintype(pdata); + + if (!pdata->listfunc) { + dump_pluginfo(pdata); + } + if ((!pdata->listinfo && pdata->listfunc) || pdata->verbose) { + dump_plugfuncs(pdata); + } + printf("\n"); + + unloadplugfunc(); + + dlclose(pdata->pluginhandle); + + freepdata(pdata); + + return 0; +} -- 2.39.2