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-2014 Free Software Foundation Europe e.V.
17 The main author of Bacula is Kern Sibbald, with contributions from many
18 others, a complete list can be found in the file AUTHORS.
20 You may use this file and others of this release according to the
21 license defined in the LICENSE file, which includes the Affero General
22 Public License, v3.0 ("AGPLv3") and some additional permissions and
23 terms pursuant to its AGPLv3 Section 7.
25 Bacula® is a registered trademark of Kern Sibbald.
38 #include "../filed/fd_plugins.h"
39 #include "../dird/dir_plugins.h"
40 // I can't include sd_plugins.h here ...
41 #include "../stored/stored.h"
42 #include "assert_macro.h"
45 typedef int (*loadPlugin) (void *binfo, void *bfuncs, void **pinfo,
47 typedef int (*unloadPlugin) (void);
49 #define DEFAULT_API_VERSION 1
62 typedef union _pluginfo pluginfo;
74 typedef union _plugfuncs plugfuncs;
87 * TODO: change to union
89 typedef union _baculafuncs baculafuncs;
96 typedef struct _baculafuncs baculafuncs;
100 int (*registerBaculaEvents) (void *ctx, ...);
101 int (*getBaculaValue) (void *ctx, int var, void *value);
102 int (*setBaculaValue) (void *ctx, int var, void *value);
103 int (*JobMessage) (void *ctx, const char *file, int line, int type, int64_t mtime,
104 const char *fmt, ...);
105 int (*DebugMessage) (void *ctx, const char *file, int line, int level,
106 const char *fmt, ...);
107 void *(*baculaMalloc) (void *ctx, const char *file, int line, size_t size);
108 void (*baculaFree) (void *ctx, const char *file, int line, void *mem);
116 typedef union _baculainfos baculainfos;
124 typedef struct _baculainfos baculainfos;
125 struct _baculainfos {
131 typedef struct _progdata progdata;
144 /* memory allocation/deallocation */
145 #define MALLOC(size) \
146 (char *) bmalloc ( size );
148 #define ASSERT_MEMORY(m) \
150 printf ( "Error: memory allocation error!\n" ); \
155 if ( ptr != NULL ){ \
160 int registerBaculaEvents(void *ctx, ...)
165 int getBaculaValue(void *ctx, int var, void *value)
170 int setBaculaValue(void *ctx, int var, void *value)
175 int DebugMessage(void *ctx, const char *file, int line, int level, const char *fmt, ...)
178 printf("DG: %s:%d %s\n", file, line, fmt);
183 int JobMessage(void *ctx, const char *file, int line, int type, int64_t mtime,
184 const char *fmt, ...)
187 printf("JM: %s:%d <%d> %s\n", file, line, type, fmt);
192 void *baculaMalloc(void *ctx, const char *file, int line, size_t size)
197 void baculaFree(void *ctx, const char *file, int line, void *mem)
203 * displays a short help
205 void print_help(int argc, char *argv[])
209 "Usage: bpluginfo [options] <plugin_file.so>\n"
211 " -i list plugin header information only (default)\n"
212 " -f list plugin functions information only\n"
213 " -a <api> bacula api version (default %d)\n"
214 " -h help screen\n" "\n", DEFAULT_API_VERSION);
217 /* allocates and resets a main program data variable */
218 progdata *allocpdata(void)
223 pdata = (progdata *) bmalloc(sizeof(progdata));
224 ASSERT_MEMORY(pdata);
225 memset(pdata, 0, sizeof(progdata));
230 /* releases all allocated program data resources */
231 void freepdata(progdata * pdata)
234 if (pdata->pluginfile) {
235 FREE(pdata->pluginfile);
241 * parse execution arguments and fills required pdata structure fields
244 * pdata - pointer to program data structure
245 * argc, argv - execution envinroment variables
247 * pdata - required structure fields
251 * -i list plugin header info only (default)
252 * -f list implemented functions only
253 * -a bacula api version (default 1)
256 void parse_args(progdata * pdata, int argc, char *argv[])
266 /* TODO - add a real help screen */
267 printf("\nNot enough parameters!\n");
268 print_help(argc, argv);
273 /* TODO - add a real help screen */
274 printf("\nToo many parameters!\n");
275 print_help(argc, argv);
279 for (i = 1; i < argc; i++) {
280 if (strcmp(argv[i], "-h") == 0) {
282 print_help(argc, argv);
285 if (strcmp(argv[i], "-v") == 0) {
290 if (strcmp(argv[i], "-f") == 0) {
295 if (strcmp(argv[i], "-i") == 0) {
300 if (strcmp(argv[i], "-a") == 0) {
301 /* bacula api version */
303 s = sscanf(argv[i + 1], "%d", &api);
305 pdata->bapiversion = api;
310 printf("\nAPI version number required!\n");
311 print_help(argc, argv);
314 if (!pdata->pluginfile) {
315 if (argv[i][0] != '/') {
316 dirtmp = MALLOC(PATH_MAX);
317 ASSERT_MEMORY(dirtmp);
318 progdir = MALLOC(PATH_MAX);
319 ASSERT_MEMORY(progdir);
320 dirtmp = getcwd(dirtmp, PATH_MAX);
323 strcat(dirtmp, argv[i]);
325 if (realpath(dirtmp, progdir) == NULL) {
326 /* error in resolving path */
328 progdir = bstrdup(argv[i]);
330 pdata->pluginfile = bstrdup(progdir);
334 pdata->pluginfile = bstrdup(argv[i]);
342 * checks a plugin type based on a plugin magic string
345 * pdata - program data with plugin info structure
347 * int - enum plugintype
349 int getplugintype(progdata * pdata)
352 ASSERT_NVAL_RET_V(pdata, ERRORPLUGIN);
354 pluginfo *pinfo = pdata->pinfo;
356 ASSERT_NVAL_RET_V(pinfo, ERRORPLUGIN);
358 if (pinfo->pdirinfo.plugin_magic &&
359 strcmp(pinfo->pdirinfo.plugin_magic, DIR_PLUGIN_MAGIC) == 0) {
362 if (pinfo->pfdinfo.plugin_magic &&
363 strcmp(pinfo->pfdinfo.plugin_magic, FD_PLUGIN_MAGIC) == 0) {
366 if (pinfo->psdinfo.plugin_magic &&
367 strcmp(pinfo->psdinfo.plugin_magic, SD_PLUGIN_MAGIC) == 0) {
375 * prints any available information about a plugin
378 * pdata - program data with plugin info structure
382 void dump_pluginfo(progdata * pdata)
385 ASSERT_NVAL_RET(pdata);
387 pluginfo *pinfo = pdata->pinfo;
389 ASSERT_NVAL_RET(pinfo);
391 plugfuncs *pfuncs = pdata->pfuncs;
393 ASSERT_NVAL_RET(pfuncs);
395 switch (pdata->bplugtype) {
397 printf("\nPlugin type:\t\tBacula Director plugin\n");
398 if (pdata->verbose) {
399 printf("Plugin magic:\t\t%s\n", NPRT(pinfo->pdirinfo.plugin_magic));
401 printf("Plugin version:\t\t%s\n", pinfo->pdirinfo.plugin_version);
402 printf("Plugin release date:\t%s\n", NPRT(pinfo->pdirinfo.plugin_date));
403 printf("Plugin author:\t\t%s\n", NPRT(pinfo->pdirinfo.plugin_author));
404 printf("Plugin licence:\t\t%s\n", NPRT(pinfo->pdirinfo.plugin_license));
405 printf("Plugin description:\t%s\n", NPRT(pinfo->pdirinfo.plugin_description));
406 printf("Plugin API version:\t%d\n", pinfo->pdirinfo.version);
409 printf("\nPlugin type:\t\tFile Daemon plugin\n");
410 if (pdata->verbose) {
411 printf("Plugin magic:\t\t%s\n", NPRT(pinfo->pfdinfo.plugin_magic));
413 printf("Plugin version:\t\t%s\n", pinfo->pfdinfo.plugin_version);
414 printf("Plugin release date:\t%s\n", NPRT(pinfo->pfdinfo.plugin_date));
415 printf("Plugin author:\t\t%s\n", NPRT(pinfo->pfdinfo.plugin_author));
416 printf("Plugin licence:\t\t%s\n", NPRT(pinfo->pfdinfo.plugin_license));
417 printf("Plugin description:\t%s\n", NPRT(pinfo->pfdinfo.plugin_description));
418 printf("Plugin API version:\t%d\n", pinfo->pfdinfo.version);
421 printf("\nPlugin type:\t\tBacula Storage plugin\n");
422 if (pdata->verbose) {
423 printf("Plugin magic:\t\t%s\n", NPRT(pinfo->psdinfo.plugin_magic));
425 printf("Plugin version:\t\t%s\n", pinfo->psdinfo.plugin_version);
426 printf("Plugin release date:\t%s\n", NPRT(pinfo->psdinfo.plugin_date));
427 printf("Plugin author:\t\t%s\n", NPRT(pinfo->psdinfo.plugin_author));
428 printf("Plugin licence:\t\t%s\n", NPRT(pinfo->psdinfo.plugin_license));
429 printf("Plugin description:\t%s\n", NPRT(pinfo->psdinfo.plugin_description));
430 printf("Plugin API version:\t%d\n", pinfo->psdinfo.version);
433 printf("\nUnknown plugin type or other Error\n\n");
438 * prints any available information about plugin' functions
441 * pdata - program data with plugin info structure
445 void dump_plugfuncs(progdata * pdata)
448 ASSERT_NVAL_RET(pdata);
450 plugfuncs *pfuncs = pdata->pfuncs;
452 ASSERT_NVAL_RET(pfuncs);
454 printf("\nPlugin functions:\n");
456 switch (pdata->bplugtype) {
458 if (pdata->verbose) {
459 if (pfuncs->pdirfuncs.newPlugin) {
460 printf(" newPlugin()\n");
462 if (pfuncs->pdirfuncs.freePlugin) {
463 printf(" freePlugin()\n");
466 if (pfuncs->pdirfuncs.getPluginValue) {
467 printf(" getPluginValue()\n");
469 if (pfuncs->pdirfuncs.setPluginValue) {
470 printf(" setPluginValue()\n");
472 if (pfuncs->pdirfuncs.handlePluginEvent) {
473 printf(" handlePluginEvent()\n");
477 if (pdata->verbose) {
478 if (pfuncs->pfdfuncs.newPlugin) {
479 printf(" newPlugin()\n");
481 if (pfuncs->pfdfuncs.freePlugin) {
482 printf(" freePlugin()\n");
485 if (pfuncs->pfdfuncs.getPluginValue) {
486 printf(" getPluginValue()\n");
488 if (pfuncs->pfdfuncs.setPluginValue) {
489 printf(" setPluginValue()\n");
491 if (pfuncs->pfdfuncs.handlePluginEvent) {
492 printf(" handlePluginEvent()\n");
494 if (pfuncs->pfdfuncs.startBackupFile) {
495 printf(" startBackupFile()\n");
497 if (pfuncs->pfdfuncs.endBackupFile) {
498 printf(" endBackupFile()\n");
500 if (pfuncs->pfdfuncs.startRestoreFile) {
501 printf(" startRestoreFile()\n");
503 if (pfuncs->pfdfuncs.endRestoreFile) {
504 printf(" endRestoreFile()\n");
506 if (pfuncs->pfdfuncs.pluginIO) {
507 printf(" pluginIO()\n");
509 if (pfuncs->pfdfuncs.createFile) {
510 printf(" createFile()\n");
512 if (pfuncs->pfdfuncs.setFileAttributes) {
513 printf(" setFileAttributes()\n");
515 if (pfuncs->pfdfuncs.checkFile) {
516 printf(" checkFile()\n");
520 if (pdata->verbose) {
521 if (pfuncs->psdfuncs.newPlugin) {
522 printf(" newPlugin()\n");
524 if (pfuncs->psdfuncs.freePlugin) {
525 printf(" freePlugin()\n");
528 if (pfuncs->psdfuncs.getPluginValue) {
529 printf(" getPluginValue()\n");
531 if (pfuncs->psdfuncs.setPluginValue) {
532 printf(" setPluginValue()\n");
534 if (pfuncs->psdfuncs.handlePluginEvent) {
535 printf(" handlePluginEvent()\n");
539 printf("\nUnknown plugin type or other Error\n\n");
545 * argv[0] [options] <plugin_filename.so>
549 * 1 - cannot load a plugin
550 * 2 - cannot find a loadPlugin function
551 * 3 - cannot find an unloadPlugin function
552 * 10 - not enough memory
554 int main(int argc, char *argv[])
558 loadPlugin loadplugfunc;
559 unloadPlugin unloadplugfunc;
560 baculafuncs bfuncs = {
563 registerBaculaEvents,
573 pdata = allocpdata();
574 parse_args(pdata, argc, argv);
576 binfos.bfdinfo.size = sizeof(binfos);
577 binfos.bfdinfo.version = DEFAULT_API_VERSION;
579 pdata->pluginhandle = dlopen(pdata->pluginfile, RTLD_LAZY);
580 if (pdata->pluginhandle == NULL) {
581 printf("\nCannot load a plugin: %s\n\n", dlerror());
586 loadplugfunc = (loadPlugin) dlsym(pdata->pluginhandle, "loadPlugin");
587 if (loadplugfunc == NULL) {
588 printf("\nCannot find loadPlugin function: %s\n", dlerror());
589 printf("\nWhether the file is a really Bacula plugin?\n\n");
594 unloadplugfunc = (unloadPlugin) dlsym(pdata->pluginhandle, "unloadPlugin");
595 if (unloadplugfunc == NULL) {
596 printf("\nCannot find unloadPlugin function: %s\n", dlerror());
597 printf("\nWhether the file is a really Bacula plugin?\n\n");
602 if (pdata->bapiversion > 0) {
603 binfos.bdirinfo.version = pdata->bapiversion;
606 loadplugfunc(&binfos, &bfuncs, (void **)&pdata->pinfo, (void **)&pdata->pfuncs);
608 pdata->bplugtype = getplugintype(pdata);
610 if (!pdata->listfunc) {
611 dump_pluginfo(pdata);
613 if ((!pdata->listinfo && pdata->listfunc) || pdata->verbose) {
614 dump_plugfuncs(pdata);
620 dlclose(pdata->pluginhandle);