2 * Contributed in 2012 by Inteos sp. z o.o.
4 * Utility tool display various information about Bacula plugin,
5 * including but not limited to:
6 * - Name and Author of the plugin
10 * - Enabled functions, etc.
13 Bacula® - The Network Backup Solution
15 Copyright (C) 2006-2012 Free Software Foundation Europe e.V.
17 The main author of Bacula is Kern Sibbald, with contributions from
18 many others, a complete list can be found in the file AUTHORS.
19 This program is Free Software; you can redistribute it and/or
20 modify it under the terms of version three of the GNU Affero General Public
21 License as published by the Free Software Foundation and included
24 This program is distributed in the hope that it will be useful, but
25 WITHOUT ANY WARRANTY; without even the implied warranty of
26 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
27 General Public License for more details.
29 You should have received a copy of the GNU Affero General Public License
30 along with this program; if not, write to the Free Software
31 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
34 Bacula® is a registered trademark of Kern Sibbald.
35 The licensor of Bacula is the Free Software Foundation Europe
36 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
37 Switzerland, email:ftf@fsfeurope.org.
50 #include "fd_plugins.h"
51 #include "dir_plugins.h"
52 // I can't include sd_plugins.h here ...
54 #include "assert_macro.h"
57 typedef int (*loadPlugin) (void *binfo, void *bfuncs, void **pinfo,
59 typedef int (*unloadPlugin) (void);
61 #define DEFAULT_API_VERSION 1
74 typedef union _pluginfo pluginfo;
86 typedef union _plugfuncs plugfuncs;
99 * TODO: change to union
101 typedef union _baculafuncs baculafuncs;
108 typedef struct _baculafuncs baculafuncs;
109 struct _baculafuncs {
112 int (*registerBaculaEvents) (void *ctx, ...);
113 int (*getBaculaValue) (void *ctx, int var, void *value);
114 int (*setBaculaValue) (void *ctx, int var, void *value);
115 int (*JobMessage) (void *ctx, const char *file, int line, int type, int64_t mtime,
116 const char *fmt, ...);
117 int (*DebugMessage) (void *ctx, const char *file, int line, int level,
118 const char *fmt, ...);
119 void *(*baculaMalloc) (void *ctx, const char *file, int line, size_t size);
120 void (*baculaFree) (void *ctx, const char *file, int line, void *mem);
128 typedef union _baculainfos baculainfos;
136 typedef struct _baculainfos baculainfos;
137 struct _baculainfos {
143 typedef struct _progdata progdata;
156 /* memory allocation/deallocation */
157 #define MALLOC(size) \
158 (char *) bmalloc ( size );
160 #define ASSERT_MEMORY(m) \
162 printf ( "Error: memory allocation error!\n" ); \
167 if ( ptr != NULL ){ \
172 int registerBaculaEvents(void *ctx, ...)
177 int getBaculaValue(void *ctx, int var, void *value)
182 int setBaculaValue(void *ctx, int var, void *value)
187 int DebugMessage(void *ctx, const char *file, int line, int level, const char *fmt, ...)
190 printf("DG: %s:%d %s\n", file, line, fmt);
195 int JobMessage(void *ctx, const char *file, int line, int type, int64_t mtime,
196 const char *fmt, ...)
199 printf("JM: %s:%d <%d> %s\n", file, line, type, fmt);
204 void *baculaMalloc(void *ctx, const char *file, int line, size_t size)
209 void baculaFree(void *ctx, const char *file, int line, void *mem)
215 * displays a short help
217 void print_help(int argc, char *argv[])
221 "Usage: bpluginfo [options] <plugin_file.so>\n"
223 " -i list plugin header information only (default)\n"
224 " -f list plugin functions information only\n"
225 " -a <api> bacula api version (default %d)\n"
226 " -h help screen\n" "\n", DEFAULT_API_VERSION);
229 /* allocates and resets a main program data variable */
230 progdata *allocpdata(void)
235 pdata = (progdata *) bmalloc(sizeof(progdata));
236 ASSERT_MEMORY(pdata);
237 memset(pdata, 0, sizeof(progdata));
242 /* releases all allocated program data resources */
243 void freepdata(progdata * pdata)
246 if (pdata->pluginfile) {
247 FREE(pdata->pluginfile);
253 * parse execution arguments and fills required pdata structure fields
256 * pdata - pointer to program data structure
257 * argc, argv - execution envinroment variables
259 * pdata - required structure fields
263 * -i list plugin header info only (default)
264 * -f list implemented functions only
265 * -a bacula api version (default 1)
268 void parse_args(progdata * pdata, int argc, char *argv[])
278 /* TODO - add a real help screen */
279 printf("\nNot enough parameters!\n");
280 print_help(argc, argv);
285 /* TODO - add a real help screen */
286 printf("\nToo many parameters!\n");
287 print_help(argc, argv);
291 for (i = 1; i < argc; i++) {
292 if (strcmp(argv[i], "-h") == 0) {
294 print_help(argc, argv);
297 if (strcmp(argv[i], "-v") == 0) {
302 if (strcmp(argv[i], "-f") == 0) {
307 if (strcmp(argv[i], "-i") == 0) {
312 if (strcmp(argv[i], "-a") == 0) {
313 /* bacula api version */
315 s = sscanf(argv[i + 1], "%d", &api);
317 pdata->bapiversion = api;
322 printf("\nAPI version number required!\n");
323 print_help(argc, argv);
326 if (!pdata->pluginfile) {
327 if (argv[i][0] != '/') {
328 dirtmp = MALLOC(PATH_MAX);
329 ASSERT_MEMORY(dirtmp);
330 progdir = MALLOC(PATH_MAX);
331 ASSERT_MEMORY(progdir);
332 dirtmp = getcwd(dirtmp, PATH_MAX);
335 strcat(dirtmp, argv[i]);
337 if (realpath(dirtmp, progdir) == NULL) {
338 /* error in resolving path */
340 progdir = bstrdup(argv[i]);
342 pdata->pluginfile = bstrdup(progdir);
346 pdata->pluginfile = bstrdup(argv[i]);
354 * checks a plugin type based on a plugin magic string
357 * pdata - program data with plugin info structure
359 * int - enum plugintype
361 int getplugintype(progdata * pdata)
364 ASSERT_NVAL_RET_V(pdata, ERRORPLUGIN);
366 pluginfo *pinfo = pdata->pinfo;
368 ASSERT_NVAL_RET_V(pinfo, ERRORPLUGIN);
370 if (pinfo->pdirinfo.plugin_magic &&
371 strcmp(pinfo->pdirinfo.plugin_magic, DIR_PLUGIN_MAGIC) == 0) {
374 if (pinfo->pfdinfo.plugin_magic &&
375 strcmp(pinfo->pfdinfo.plugin_magic, FD_PLUGIN_MAGIC) == 0) {
378 if (pinfo->psdinfo.plugin_magic &&
379 strcmp(pinfo->psdinfo.plugin_magic, SD_PLUGIN_MAGIC) == 0) {
387 * prints any available information about a plugin
390 * pdata - program data with plugin info structure
394 void dump_pluginfo(progdata * pdata)
397 ASSERT_NVAL_RET(pdata);
399 pluginfo *pinfo = pdata->pinfo;
401 ASSERT_NVAL_RET(pinfo);
403 plugfuncs *pfuncs = pdata->pfuncs;
405 ASSERT_NVAL_RET(pfuncs);
407 switch (pdata->bplugtype) {
409 printf("\nPlugin type:\t\tBacula Director plugin\n");
410 if (pdata->verbose) {
411 printf("Plugin magic:\t\t%s\n", NPRT(pinfo->pdirinfo.plugin_magic));
413 printf("Plugin version:\t\t%s\n", pinfo->pdirinfo.plugin_version);
414 printf("Plugin release date:\t%s\n", NPRT(pinfo->pdirinfo.plugin_date));
415 printf("Plugin author:\t\t%s\n", NPRT(pinfo->pdirinfo.plugin_author));
416 printf("Plugin licence:\t\t%s\n", NPRT(pinfo->pdirinfo.plugin_license));
417 printf("Plugin description:\t%s\n", NPRT(pinfo->pdirinfo.plugin_description));
418 printf("Plugin API version:\t%d\n", pinfo->pdirinfo.version);
421 printf("\nPlugin type:\t\tFile Daemon plugin\n");
422 if (pdata->verbose) {
423 printf("Plugin magic:\t\t%s\n", NPRT(pinfo->pfdinfo.plugin_magic));
425 printf("Plugin version:\t\t%s\n", pinfo->pfdinfo.plugin_version);
426 printf("Plugin release date:\t%s\n", NPRT(pinfo->pfdinfo.plugin_date));
427 printf("Plugin author:\t\t%s\n", NPRT(pinfo->pfdinfo.plugin_author));
428 printf("Plugin licence:\t\t%s\n", NPRT(pinfo->pfdinfo.plugin_license));
429 printf("Plugin description:\t%s\n", NPRT(pinfo->pfdinfo.plugin_description));
430 printf("Plugin API version:\t%d\n", pinfo->pfdinfo.version);
433 printf("\nPlugin type:\t\tBacula Storage plugin\n");
434 if (pdata->verbose) {
435 printf("Plugin magic:\t\t%s\n", NPRT(pinfo->psdinfo.plugin_magic));
437 printf("Plugin version:\t\t%s\n", pinfo->psdinfo.plugin_version);
438 printf("Plugin release date:\t%s\n", NPRT(pinfo->psdinfo.plugin_date));
439 printf("Plugin author:\t\t%s\n", NPRT(pinfo->psdinfo.plugin_author));
440 printf("Plugin licence:\t\t%s\n", NPRT(pinfo->psdinfo.plugin_license));
441 printf("Plugin description:\t%s\n", NPRT(pinfo->psdinfo.plugin_description));
442 printf("Plugin API version:\t%d\n", pinfo->psdinfo.version);
445 printf("\nUnknown plugin type or other Error\n\n");
450 * prints any available information about plugin' functions
453 * pdata - program data with plugin info structure
457 void dump_plugfuncs(progdata * pdata)
460 ASSERT_NVAL_RET(pdata);
462 plugfuncs *pfuncs = pdata->pfuncs;
464 ASSERT_NVAL_RET(pfuncs);
466 printf("\nPlugin functions:\n");
468 switch (pdata->bplugtype) {
470 if (pdata->verbose) {
471 if (pfuncs->pdirfuncs.newPlugin) {
472 printf(" newPlugin()\n");
474 if (pfuncs->pdirfuncs.freePlugin) {
475 printf(" freePlugin()\n");
478 if (pfuncs->pdirfuncs.getPluginValue) {
479 printf(" getPluginValue()\n");
481 if (pfuncs->pdirfuncs.setPluginValue) {
482 printf(" setPluginValue()\n");
484 if (pfuncs->pdirfuncs.handlePluginEvent) {
485 printf(" handlePluginEvent()\n");
489 if (pdata->verbose) {
490 if (pfuncs->pfdfuncs.newPlugin) {
491 printf(" newPlugin()\n");
493 if (pfuncs->pfdfuncs.freePlugin) {
494 printf(" freePlugin()\n");
497 if (pfuncs->pfdfuncs.getPluginValue) {
498 printf(" getPluginValue()\n");
500 if (pfuncs->pfdfuncs.setPluginValue) {
501 printf(" setPluginValue()\n");
503 if (pfuncs->pfdfuncs.handlePluginEvent) {
504 printf(" handlePluginEvent()\n");
506 if (pfuncs->pfdfuncs.startBackupFile) {
507 printf(" startBackupFile()\n");
509 if (pfuncs->pfdfuncs.endBackupFile) {
510 printf(" endBackupFile()\n");
512 if (pfuncs->pfdfuncs.startRestoreFile) {
513 printf(" startRestoreFile()\n");
515 if (pfuncs->pfdfuncs.endRestoreFile) {
516 printf(" endRestoreFile()\n");
518 if (pfuncs->pfdfuncs.pluginIO) {
519 printf(" pluginIO()\n");
521 if (pfuncs->pfdfuncs.createFile) {
522 printf(" createFile()\n");
524 if (pfuncs->pfdfuncs.setFileAttributes) {
525 printf(" setFileAttributes()\n");
527 if (pfuncs->pfdfuncs.checkFile) {
528 printf(" checkFile()\n");
532 if (pdata->verbose) {
533 if (pfuncs->psdfuncs.newPlugin) {
534 printf(" newPlugin()\n");
536 if (pfuncs->psdfuncs.freePlugin) {
537 printf(" freePlugin()\n");
540 if (pfuncs->psdfuncs.getPluginValue) {
541 printf(" getPluginValue()\n");
543 if (pfuncs->psdfuncs.setPluginValue) {
544 printf(" setPluginValue()\n");
546 if (pfuncs->psdfuncs.handlePluginEvent) {
547 printf(" handlePluginEvent()\n");
551 printf("\nUnknown plugin type or other Error\n\n");
557 * argv[0] [options] <plugin_filename.so>
561 * 1 - cannot load a plugin
562 * 2 - cannot find a loadPlugin function
563 * 3 - cannot find an unloadPlugin function
564 * 10 - not enough memory
566 int main(int argc, char *argv[])
570 loadPlugin loadplugfunc;
571 unloadPlugin unloadplugfunc;
572 baculafuncs bfuncs = {
575 registerBaculaEvents,
585 pdata = allocpdata();
586 parse_args(pdata, argc, argv);
588 binfos.bfdinfo.size = sizeof(binfos);
589 binfos.bfdinfo.version = DEFAULT_API_VERSION;
591 pdata->pluginhandle = dlopen(pdata->pluginfile, RTLD_LAZY);
592 if (pdata->pluginhandle == NULL) {
593 printf("\nCannot load a plugin: %s\n\n", dlerror());
598 loadplugfunc = (loadPlugin) dlsym(pdata->pluginhandle, "loadPlugin");
599 if (loadplugfunc == NULL) {
600 printf("\nCannot find loadPlugin function: %s\n", dlerror());
601 printf("\nWhether the file is a really Bacula plugin?\n\n");
606 unloadplugfunc = (unloadPlugin) dlsym(pdata->pluginhandle, "unloadPlugin");
607 if (unloadplugfunc == NULL) {
608 printf("\nCannot find unloadPlugin function: %s\n", dlerror());
609 printf("\nWhether the file is a really Bacula plugin?\n\n");
614 if (pdata->bapiversion > 0) {
615 binfos.bdirinfo.version = pdata->bapiversion;
618 loadplugfunc(&binfos, &bfuncs, (void **)&pdata->pinfo, (void **)&pdata->pfuncs);
620 pdata->bplugtype = getplugintype(pdata);
622 if (!pdata->listfunc) {
623 dump_pluginfo(pdata);
625 if ((!pdata->listinfo && pdata->listfunc) || pdata->verbose) {
626 dump_plugfuncs(pdata);
632 dlclose(pdata->pluginhandle);