From 3e94dc8ebc677d8b7a42952a95d99e9793537d28 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Mon, 2 Jan 2012 10:52:46 +0100 Subject: [PATCH] Pull compiler warning cleanup code + other from master --- bacula/.gitignore | 5 +- bacula/src/bc_types.h | 9 +- bacula/src/cats/cats.h | 2 +- bacula/src/cats/mysql.c | 9 +- bacula/src/cats/sql.c | 30 +- bacula/src/cats/sql_cmds.c | 9 + bacula/src/cats/sql_cmds.h | 1 + bacula/src/console/authenticate.c | 3 - bacula/src/console/conio.c | 5 +- bacula/src/console/console.c | 16 +- bacula/src/dird/authenticate.c | 3 - bacula/src/dird/catreq.c | 6 +- bacula/src/dird/dir_plugins.c | 379 +++++++++++------- bacula/src/dird/dir_plugins.h | 130 +++--- bacula/src/dird/dird.c | 42 ++ bacula/src/dird/dird_conf.c | 21 +- bacula/src/dird/inc_conf.c | 15 +- bacula/src/dird/job.c | 8 +- bacula/src/dird/newvol.c | 2 +- bacula/src/dird/scheduler.c | 5 +- bacula/src/dird/ua.h | 1 + bacula/src/dird/ua_cmds.c | 4 - bacula/src/dird/ua_label.c | 3 +- bacula/src/dird/ua_purge.c | 2 +- bacula/src/dird/verify.c | 3 - bacula/src/filed/accurate.c | 6 +- bacula/src/filed/backup.c | 1 - bacula/src/jcr.h | 12 +- bacula/src/lib/bsnprintf.c | 13 +- bacula/src/lib/jcr.c | 32 +- bacula/src/lib/lex.c | 12 +- bacula/src/lib/lex.h | 1 + bacula/src/lib/parse_conf.c | 6 +- bacula/src/lib/plugins.c | 16 +- bacula/src/plugins/dir/example-plugin-dir.c | 82 ++-- bacula/src/plugins/fd/example-plugin-fd.c | 12 +- bacula/src/plugins/sd/example-plugin-sd.c | 106 +++-- bacula/src/plugins/sd/main.c | 2 +- bacula/src/qt-console/clients/clients.cpp | 2 +- bacula/src/qt-console/console/console.cpp | 3 +- bacula/src/qt-console/job/job.cpp | 1 - bacula/src/qt-console/mainwin.cpp | 3 +- bacula/src/qt-console/medialist/medialist.cpp | 6 +- bacula/src/qt-console/status/clientstat.cpp | 1 - bacula/src/qt-console/storage/content.cpp | 12 +- bacula/src/qt-console/storage/storage.cpp | 3 +- bacula/src/stored/Makefile.in | 10 +- bacula/src/stored/acquire.c | 40 +- bacula/src/stored/authenticate.c | 11 +- bacula/src/stored/block.c | 3 +- bacula/src/stored/btape.c | 5 +- bacula/src/stored/fd_cmds.c | 7 +- bacula/src/stored/job.c | 5 +- bacula/src/stored/mac.c | 9 +- bacula/src/stored/pythonsd.c | 8 +- bacula/src/stored/read.c | 5 +- bacula/src/stored/reserve.c | 23 +- bacula/src/stored/sd_plugins.c | 83 +++- bacula/src/stored/sd_plugins.h | 7 +- bacula/src/stored/spool.c | 9 +- bacula/src/stored/stored.c | 37 +- bacula/src/stored/stored.h | 3 +- bacula/src/stored/stored_conf.c | 4 +- bacula/src/stored/vtape.c | 4 +- bacula/src/tools/dbcheck.c | 10 + bacula/src/tools/ing_test.c | 9 +- bacula/src/tools/testls.c | 4 +- bacula/src/version.h | 12 +- 68 files changed, 819 insertions(+), 534 deletions(-) diff --git a/bacula/.gitignore b/bacula/.gitignore index 4e83c8baf1..07fc982dd5 100644 --- a/bacula/.gitignore +++ b/bacula/.gitignore @@ -171,7 +171,6 @@ po/*.gmo # scripts/ scripts/breload -scripts/storage-ctl scripts/make_catalog_backup.pl scripts/bacula_config scripts/wxconsole.console_apps @@ -199,6 +198,7 @@ scripts/startit scripts/startmysql scripts/stopit scripts/stopmysql +scripts/storage-ctl scripts/gnome-console.console_apps scripts/bacula.desktop.gnome2.xsu scripts/bacula.desktop.gnome2.consolehelper @@ -233,10 +233,10 @@ src/xqt-console src/TAGS # src/cats/ -src/cats/install-default-backend src/cats/1 src/cats/2 src/cats/3 +src/cats/install-default-backend src/cats/make_catalog_backup.pl src/cats/Makefile src/cats/make_catalog_backup @@ -479,7 +479,6 @@ src/qt-console/tray-monitor/Makefile.mingw32 src/qt-console/tray-monitor/Makefile.mingw32.Debug src/qt-console/tray-monitor/Makefile.mingw32.Release src/qt-console/tray-monitor/debug/ -src/qt-console/tray-monitor/release/ src/qt-console/tray-monitor/moc/ src/qt-console/tray-monitor/tray-monitor.conf src/qt-console/tray-monitor/tray-monitor.pro diff --git a/bacula/src/bc_types.h b/bacula/src/bc_types.h index 659ce1c58d..fe04718748 100644 --- a/bacula/src/bc_types.h +++ b/bacula/src/bc_types.h @@ -241,10 +241,11 @@ typedef float float32_t; * Used in findlib, filed, and plugins */ enum { - CF_SKIP = 1, /* skip file (not newer or something) */ - CF_ERROR, /* error creating file */ - CF_EXTRACT, /* file created, data to extract */ - CF_CREATED /* file created, no data to extract */ + CF_SKIP = 1, /* skip file (not newer or something) */ + CF_ERROR, /* error creating file */ + CF_EXTRACT, /* file created, data to extract */ + CF_CREATED, /* file created, no data to extract */ + CF_CORE /* let bacula core handle the file creation */ }; #ifndef MAX diff --git a/bacula/src/cats/cats.h b/bacula/src/cats/cats.h index e83287a560..a22878c375 100644 --- a/bacula/src/cats/cats.h +++ b/bacula/src/cats/cats.h @@ -566,7 +566,7 @@ public: * Some functions exported by sql.c for use within the cats directory. */ int list_result(void *vctx, int cols, char **row); -void list_result(JCR *jcr, B_DB *mdb, DB_LIST_HANDLER *send, void *ctx, e_list_type type); +int list_result(JCR *jcr, B_DB *mdb, DB_LIST_HANDLER *send, void *ctx, e_list_type type); void list_dashes(B_DB *mdb, DB_LIST_HANDLER *send, void *ctx); int get_sql_record_max(JCR *jcr, B_DB *mdb); bool check_tables_version(JCR *jcr, B_DB *mdb); diff --git a/bacula/src/cats/mysql.c b/bacula/src/cats/mysql.c index 8eec326d36..0cdf19d733 100644 --- a/bacula/src/cats/mysql.c +++ b/bacula/src/cats/mysql.c @@ -602,7 +602,6 @@ bool B_DB_MYSQL::sql_batch_end(JCR *jcr, const char *error) */ bool B_DB_MYSQL::sql_batch_insert(JCR *jcr, ATTR_DBR *ar) { - size_t len; const char *digest; char ed1[50]; @@ -618,10 +617,10 @@ bool B_DB_MYSQL::sql_batch_insert(JCR *jcr, ATTR_DBR *ar) digest = ar->Digest; } - len = Mmsg(cmd, "INSERT INTO batch VALUES " - "(%u,%s,'%s','%s','%s','%s',%u)", - ar->FileIndex, edit_int64(ar->JobId,ed1), esc_path, - esc_name, ar->attr, digest, ar->DeltaSeq); + Mmsg(cmd, "INSERT INTO batch VALUES " + "(%u,%s,'%s','%s','%s','%s',%u)", + ar->FileIndex, edit_int64(ar->JobId,ed1), esc_path, + esc_name, ar->attr, digest, ar->DeltaSeq); return sql_query(cmd); } diff --git a/bacula/src/cats/sql.c b/bacula/src/cats/sql.c index 5374b08910..2c4fa431ee 100644 --- a/bacula/src/cats/sql.c +++ b/bacula/src/cats/sql.c @@ -127,16 +127,16 @@ int db_list_handler(void *ctx, int num_fields, char **row) } /* - * * specific context passed from db_check_max_connections to db_max_connections_handler. - * */ + * specific context passed from db_check_max_connections to db_max_connections_handler. + */ struct max_connections_context { B_DB *db; uint32_t nr_connections; }; /* - * * Called here to retrieve an integer from the database - * */ + * Called here to retrieve an integer from the database + */ static inline int db_max_connections_handler(void *ctx, int num_fields, char **row) { struct max_connections_context *context; @@ -160,8 +160,8 @@ static inline int db_max_connections_handler(void *ctx, int num_fields, char **r } /* - * * Check catalog max_connections setting - * */ + * Check catalog max_connections setting + */ bool db_check_max_connections(JCR *jcr, B_DB *mdb, uint32_t max_concurrent_jobs) { struct max_connections_context context; @@ -300,7 +300,8 @@ UpdateDB(const char *file, int line, JCR *jcr, B_DB *mdb, char *cmd) return 1; } -/* Utility routine for deletes +/* + * Utility routine for deletes * * Returns: -1 on error * n number of rows affected @@ -350,8 +351,8 @@ int get_sql_record_max(JCR *jcr, B_DB *mdb) } /* - * * Return pre-edited error message - * */ + * Return pre-edited error message + */ char *db_strerror(B_DB *mdb) { return mdb->errmsg; @@ -586,9 +587,10 @@ vertical_list: /* * If full_list is set, we list vertically, otherwise, we - * list on one line horizontally. + * list on one line horizontally. + * Return number of rows */ -void list_result(JCR *jcr, B_DB *mdb, DB_LIST_HANDLER *send, void *ctx, e_list_type type) +int list_result(JCR *jcr, B_DB *mdb, DB_LIST_HANDLER *send, void *ctx, e_list_type type) { SQL_FIELD *field; SQL_ROW row; @@ -599,7 +601,7 @@ void list_result(JCR *jcr, B_DB *mdb, DB_LIST_HANDLER *send, void *ctx, e_list_t Dmsg0(800, "list_result starts\n"); if (sql_num_rows(mdb) == 0) { send(ctx, _("No results to list.\n")); - return; + return sql_num_rows(mdb); } num_fields = sql_num_fields(mdb); @@ -676,7 +678,7 @@ void list_result(JCR *jcr, B_DB *mdb, DB_LIST_HANDLER *send, void *ctx, e_list_t send(ctx, "\n"); } list_dashes(mdb, send, ctx); - return; + return sql_num_rows(mdb); vertical_list: @@ -700,7 +702,7 @@ vertical_list: } send(ctx, "\n"); } - return; + return sql_num_rows(mdb); } /* diff --git a/bacula/src/cats/sql_cmds.c b/bacula/src/cats/sql_cmds.c index d7b93211b3..9a21b28ee7 100644 --- a/bacula/src/cats/sql_cmds.c +++ b/bacula/src/cats/sql_cmds.c @@ -40,6 +40,15 @@ #include "bacula.h" +const char *get_restore_objects = + "SELECT JobId,ObjectLength,ObjectFullLength,ObjectIndex," + "ObjectType,ObjectCompression,FileIndex,ObjectName," + "RestoreObject,PluginName " + "FROM RestoreObject " + "WHERE JobId IN (%s) " + "AND ObjectType = %d " + "ORDER BY ObjectIndex ASC"; + const char *cleanup_created_job = "UPDATE Job SET JobStatus='f', StartTime=SchedTime, EndTime=SchedTime " "WHERE JobStatus = 'C'"; diff --git a/bacula/src/cats/sql_cmds.h b/bacula/src/cats/sql_cmds.h index 88db3d2c1b..884c0ec730 100644 --- a/bacula/src/cats/sql_cmds.h +++ b/bacula/src/cats/sql_cmds.h @@ -26,6 +26,7 @@ Switzerland, email:ftf@fsfeurope.org. */ +extern const char CATS_IMP_EXP *get_restore_objects; extern const char CATS_IMP_EXP *fill_jobhisto; extern const char CATS_IMP_EXP *client_backups; extern const char CATS_IMP_EXP *list_pool; diff --git a/bacula/src/console/authenticate.c b/bacula/src/console/authenticate.c index a47422b415..0f5e5b930f 100644 --- a/bacula/src/console/authenticate.c +++ b/bacula/src/console/authenticate.c @@ -62,7 +62,6 @@ int authenticate_director(JCR *jcr, DIRRES *director, CONRES *cons) BSOCK *dir = jcr->dir_bsock; int tls_local_need = BNET_TLS_NONE; int tls_remote_need = BNET_TLS_NONE; - bool tls_needed; bool tls_authenticate; int compatible = true; char bashed_name[MAX_NAME_LENGTH]; @@ -88,7 +87,6 @@ int authenticate_director(JCR *jcr, DIRRES *director, CONRES *cons) tls_local_need = BNET_TLS_REQUIRED; } tls_authenticate = cons->tls_authenticate; - tls_needed = cons->tls_enable || cons->tls_authenticate; tls_ctx = cons->tls_ctx; } else { bstrncpy(bashed_name, "*UserAgent*", sizeof(bashed_name)); @@ -106,7 +104,6 @@ int authenticate_director(JCR *jcr, DIRRES *director, CONRES *cons) tls_local_need = BNET_TLS_REQUIRED; } tls_authenticate = director->tls_authenticate; - tls_needed = director->tls_enable || director->tls_authenticate; tls_ctx = director->tls_ctx; } diff --git a/bacula/src/console/conio.c b/bacula/src/console/conio.c index c04779667c..8165444f2c 100755 --- a/bacula/src/console/conio.c +++ b/bacula/src/console/conio.c @@ -453,9 +453,8 @@ input_char() } /* if we got a screen size escape sequence, read height, width */ if (c == F_SCRSIZ) { - int y, x; - y = t_gnc() - 0x20; /* y */ - x = t_gnc() - 0x20; /* x */ + t_gnc(); /* - 0x20 = y */ + t_gnc(); /* - 0x20 = x */ c = input_char(); } return c; diff --git a/bacula/src/console/console.c b/bacula/src/console/console.c index a5a56064b3..999515fddf 100644 --- a/bacula/src/console/console.c +++ b/bacula/src/console/console.c @@ -598,7 +598,7 @@ static struct cpl_keywords_t cpl_keywords[] = { {"fileset=", ".fileset" }, {"client=", ".client" }, {"job=", ".jobs" }, - {"restorejob=",".jobs type=R" }, + {"restore_job=",".jobs type=R" }, {"level=", ".level" }, {"storage=", ".storage" }, {"schedule=", ".schedule" }, @@ -1342,6 +1342,7 @@ static int check_resources() return OK; } +/* @version */ static int versioncmd(FILE *input, BSOCK *UA_sock) { senditf("Version: " VERSION " (" BDATE ") %s %s %s\n", @@ -1349,6 +1350,7 @@ static int versioncmd(FILE *input, BSOCK *UA_sock) return 1; } +/* @input */ static int inputcmd(FILE *input, BSOCK *UA_sock) { FILE *fd; @@ -1373,13 +1375,15 @@ static int inputcmd(FILE *input, BSOCK *UA_sock) return 1; } -/* Send output to both termina and specified file */ +/* @tee */ +/* Send output to both terminal and specified file */ static int teecmd(FILE *input, BSOCK *UA_sock) { teeout = true; return do_outputcmd(input, UA_sock); } +/* @output */ /* Send output to specified "file" */ static int outputcmd(FILE *input, BSOCK *UA_sock) { @@ -1420,7 +1424,7 @@ static int do_outputcmd(FILE *input, BSOCK *UA_sock) } /* - * exec "some-command" [wait-seconds] + * @exec "some-command" [wait-seconds] */ static int execcmd(FILE *input, BSOCK *UA_sock) { @@ -1457,6 +1461,7 @@ static int execcmd(FILE *input, BSOCK *UA_sock) } +/* @echo xxx yyy */ static int echocmd(FILE *input, BSOCK *UA_sock) { for (int i=1; i < argc; i++) { @@ -1466,11 +1471,13 @@ static int echocmd(FILE *input, BSOCK *UA_sock) return 1; } +/* @quit */ static int quitcmd(FILE *input, BSOCK *UA_sock) { return 0; } +/* @help */ static int helpcmd(FILE *input, BSOCK *UA_sock) { int i; @@ -1481,6 +1488,7 @@ static int helpcmd(FILE *input, BSOCK *UA_sock) } +/* @sleep secs */ static int sleepcmd(FILE *input, BSOCK *UA_sock) { if (argc > 1) { @@ -1489,7 +1497,7 @@ static int sleepcmd(FILE *input, BSOCK *UA_sock) return 1; } - +/* @time */ static int timecmd(FILE *input, BSOCK *UA_sock) { char sdt[50]; diff --git a/bacula/src/dird/authenticate.c b/bacula/src/dird/authenticate.c index bae57343d5..a69b2779dc 100644 --- a/bacula/src/dird/authenticate.c +++ b/bacula/src/dird/authenticate.c @@ -290,7 +290,6 @@ int authenticate_user_agent(UAContext *uac) char name[MAX_NAME_LENGTH]; int tls_local_need = BNET_TLS_NONE; int tls_remote_need = BNET_TLS_NONE; - bool need_tls; bool tls_authenticate; int compatible = true; CONRES *cons = NULL; @@ -324,7 +323,6 @@ int authenticate_user_agent(UAContext *uac) } tls_authenticate = director->tls_authenticate; - need_tls = director->tls_enable || tls_authenticate; if (tls_authenticate) { tls_local_need = BNET_TLS_REQUIRED; @@ -351,7 +349,6 @@ int authenticate_user_agent(UAContext *uac) } tls_authenticate = cons->tls_authenticate; - need_tls = cons->tls_enable || tls_authenticate; if (tls_authenticate) { tls_local_need = BNET_TLS_REQUIRED; diff --git a/bacula/src/dird/catreq.c b/bacula/src/dird/catreq.c index 4b13108c64..14ef55d169 100644 --- a/bacula/src/dird/catreq.c +++ b/bacula/src/dird/catreq.c @@ -634,8 +634,7 @@ bool despool_attributes_from_file(JCR *jcr, const char *file) bool ret=false; int32_t pktsiz; size_t nbytes; - ssize_t last = 0, size = 0; - int count = 0; + ssize_t size = 0; int32_t msglen; /* message length */ POOLMEM *msg = get_pool_memory(PM_MESSAGE); FILE *spool_fd=NULL; @@ -673,9 +672,6 @@ bool despool_attributes_from_file(JCR *jcr, const char *file) goto bail_out; } size += nbytes; - if ((++count & 0x3F) == 0) { - last = size; - } } if (!jcr->is_job_canceled()) { update_attribute(jcr, msg, msglen); diff --git a/bacula/src/dird/dir_plugins.c b/bacula/src/dird/dir_plugins.c index 3c6761cfc4..6eb98f8a71 100644 --- a/bacula/src/dird/dir_plugins.c +++ b/bacula/src/dird/dir_plugins.c @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2007-2009 Free Software Foundation Europe e.V. + Copyright (C) 2007-2011 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. @@ -33,30 +33,32 @@ */ #include "bacula.h" #include "dird.h" +#include "dir_plugins.h" -const int dbglvl = 100; +const int dbglvl = 50; const char *plugin_type = "-dir.so"; /* Forward referenced functions */ -static bRC baculaGetValue(bpContext *ctx, brVariable var, void *value); -static bRC baculaSetValue(bpContext *ctx, bwVariable var, void *value); +static bRC baculaGetValue(bpContext *ctx, brDirVariable var, void *value); +static bRC baculaSetValue(bpContext *ctx, bwDirVariable var, void *value); static bRC baculaRegisterEvents(bpContext *ctx, ...); static bRC baculaJobMsg(bpContext *ctx, const char *file, int line, - int type, utime_t mtime, const char *fmt, ...); + int type, utime_t mtime, const char *fmt, ...); static bRC baculaDebugMsg(bpContext *ctx, const char *file, int line, - int level, const char *fmt, ...); + int level, const char *fmt, ...); +static bool is_plugin_compatible(Plugin *plugin); /* Bacula info */ -static bInfo binfo = { - sizeof(bFuncs), - DIR_PLUGIN_INTERFACE_VERSION, +static bDirInfo binfo = { + sizeof(bDirFuncs), + DIR_PLUGIN_INTERFACE_VERSION }; /* Bacula entry points */ -static bFuncs bfuncs = { - sizeof(bFuncs), +static bDirFuncs bfuncs = { + sizeof(bDirFuncs), DIR_PLUGIN_INTERFACE_VERSION, baculaRegisterEvents, baculaGetValue, @@ -65,41 +67,78 @@ static bFuncs bfuncs = { baculaDebugMsg }; +/* + * Bacula private context + */ +struct bacula_ctx { + JCR *jcr; /* jcr for plugin */ + bRC rc; /* last return code */ + bool disabled; /* set if plugin disabled */ +}; + +static bool is_plugin_disabled(bpContext *plugin_ctx) +{ + bacula_ctx *b_ctx; + if (!plugin_ctx) { + return true; + } + b_ctx = (bacula_ctx *)plugin_ctx->bContext; + return b_ctx->disabled; +} + +#ifdef needed +static bool is_plugin_disabled(JCR *jcr) +{ + return is_plugin_disabled(jcr->plugin_ctx); +} +#endif + /* * Create a plugin event */ -void generate_plugin_event(JCR *jcr, bEventType eventType, void *value) +int generate_plugin_event(JCR *jcr, bDirEventType eventType, void *value) { - bEvent event; + bpContext *plugin_ctx; + bDirEvent event; Plugin *plugin; int i = 0; + bRC rc = bRC_OK; if (!bplugin_list || !jcr || !jcr->plugin_ctx_list) { - return; + return bRC_OK; /* Return if no plugins loaded */ + } + if (jcr->is_job_canceled()) { + return bRC_Cancel; } bpContext *plugin_ctx_list = (bpContext *)jcr->plugin_ctx_list; - jcr->eventType = event.eventType = eventType; + event.eventType = eventType; - Dmsg2(dbglvl, "plugin_ctx_list=%p JobId=%d\n", jcr->plugin_ctx_list, jcr->JobId); + Dmsg2(dbglvl, "dir-plugin_ctx_list=%p JobId=%d\n", jcr->plugin_ctx_list, jcr->JobId); foreach_alist(plugin, bplugin_list) { - bRC rc; - rc = plug_func(plugin)->handlePluginEvent(&plugin_ctx_list[i++], &event, value); + plugin_ctx = &plugin_ctx_list[i++]; + if (is_plugin_disabled(plugin_ctx)) { + continue; + } + rc = dirplug_func(plugin)->handlePluginEvent(plugin_ctx, &event, value); if (rc != bRC_OK) { break; } } - return; + return rc; } -static void dump_dir_plugin(Plugin *plugin, FILE *fp) +/* + * Print to file the plugin info. + */ +void dump_dir_plugin(Plugin *plugin, FILE *fp) { if (!plugin) { return ; } - pInfo *info = (pInfo *) plugin->pinfo; + pDirInfo *info = (pDirInfo *) plugin->pinfo; fprintf(fp, "\tversion=%d\n", info->version); fprintf(fp, "\tdate=%s\n", NPRTB(info->plugin_date)); fprintf(fp, "\tmagic=%s\n", NPRTB(info->plugin_magic)); @@ -109,17 +148,89 @@ static void dump_dir_plugin(Plugin *plugin, FILE *fp) fprintf(fp, "\tdescription=%s\n", NPRTB(info->plugin_description)); } +/** + * This entry point is called internally by Bacula to ensure + * that the plugin IO calls come into this code. + */ void load_dir_plugins(const char *plugin_dir) { + Plugin *plugin; + + Dmsg0(dbglvl, "Load dir plugins\n"); if (!plugin_dir) { + Dmsg0(dbglvl, "No dir plugin dir!\n"); return; } - bplugin_list = New(alist(10, not_owned_by_alist)); - load_plugins((void *)&binfo, (void *)&bfuncs, plugin_dir, plugin_type, NULL); + if (!load_plugins((void *)&binfo, (void *)&bfuncs, plugin_dir, plugin_type, + is_plugin_compatible)) { + /* Either none found, or some error */ + if (bplugin_list->size() == 0) { + delete bplugin_list; + bplugin_list = NULL; + Dmsg0(dbglvl, "No plugins loaded\n"); + return; + } + } + /* + * Verify that the plugin is acceptable, and print information + * about it. + */ + foreach_alist(plugin, bplugin_list) { + Jmsg(NULL, M_INFO, 0, _("Loaded plugin: %s\n"), plugin->file); + Dmsg1(dbglvl, "Loaded plugin: %s\n", plugin->file); + } + + Dmsg1(dbglvl, "num plugins=%d\n", bplugin_list->size()); dbg_plugin_add_hook(dump_dir_plugin); } +/** + * Check if a plugin is compatible. Called by the load_plugin function + * to allow us to verify the plugin. + */ +static bool is_plugin_compatible(Plugin *plugin) +{ + pDirInfo *info = (pDirInfo *)plugin->pinfo; + Dmsg0(50, "is_plugin_compatible called\n"); + if (debug_level >= 50) { + dump_dir_plugin(plugin, stdin); + } + if (strcmp(info->plugin_magic, DIR_PLUGIN_MAGIC) != 0) { + Jmsg(NULL, M_ERROR, 0, _("Plugin magic wrong. Plugin=%s wanted=%s got=%s\n"), + plugin->file, DIR_PLUGIN_MAGIC, info->plugin_magic); + Dmsg3(50, "Plugin magic wrong. Plugin=%s wanted=%s got=%s\n", + plugin->file, DIR_PLUGIN_MAGIC, info->plugin_magic); + + return false; + } + if (info->version != DIR_PLUGIN_INTERFACE_VERSION) { + Jmsg(NULL, M_ERROR, 0, _("Plugin version incorrect. Plugin=%s wanted=%d got=%d\n"), + plugin->file, DIR_PLUGIN_INTERFACE_VERSION, info->version); + Dmsg3(50, "Plugin version incorrect. Plugin=%s wanted=%d got=%d\n", + plugin->file, DIR_PLUGIN_INTERFACE_VERSION, info->version); + return false; + } + if (strcmp(info->plugin_license, "Bacula AGPLv3") != 0 && + strcmp(info->plugin_license, "AGPLv3") != 0 && + strcmp(info->plugin_license, "Bacula Systems(R) SA") != 0) { + Jmsg(NULL, M_ERROR, 0, _("Plugin license incompatible. Plugin=%s license=%s\n"), + plugin->file, info->plugin_license); + Dmsg2(50, "Plugin license incompatible. Plugin=%s license=%s\n", + plugin->file, info->plugin_license); + return false; + } + if (info->size != sizeof(pDirInfo)) { + Jmsg(NULL, M_ERROR, 0, + _("Plugin size incorrect. Plugin=%s wanted=%d got=%d\n"), + plugin->file, sizeof(pDirInfo), info->size); + return false; + } + + return true; +} + + /* * Create a new instance of each plugin for this Job */ @@ -128,12 +239,18 @@ void new_plugins(JCR *jcr) Plugin *plugin; int i = 0; + Dmsg0(dbglvl, "=== enter new_plugins ===\n"); if (!bplugin_list) { + Dmsg0(dbglvl, "No dir plugin list!\n"); + return; + } + if (jcr->is_job_canceled()) { return; } int num = bplugin_list->size(); + Dmsg1(dbglvl, "dir-plugin-list size=%d\n", num); if (num == 0) { return; } @@ -141,12 +258,17 @@ void new_plugins(JCR *jcr) jcr->plugin_ctx_list = (bpContext *)malloc(sizeof(bpContext) * num); bpContext *plugin_ctx_list = jcr->plugin_ctx_list; - Dmsg2(dbglvl, "Instantiate plugin_ctx_list=%p JobId=%d\n", jcr->plugin_ctx_list, jcr->JobId); + Dmsg2(dbglvl, "Instantiate dir-plugin_ctx_list=%p JobId=%d\n", jcr->plugin_ctx_list, jcr->JobId); foreach_alist(plugin, bplugin_list) { /* Start a new instance of each plugin */ - plugin_ctx_list[i].bContext = (void *)jcr; + bacula_ctx *b_ctx = (bacula_ctx *)malloc(sizeof(bacula_ctx)); + memset(b_ctx, 0, sizeof(bacula_ctx)); + b_ctx->jcr = jcr; + plugin_ctx_list[i].bContext = (void *)b_ctx; plugin_ctx_list[i].pContext = NULL; - plug_func(plugin)->newPlugin(&plugin_ctx_list[i++]); + if (dirplug_func(plugin)->newPlugin(&plugin_ctx_list[i++]) != bRC_OK) { + b_ctx->disabled = true; + } } } @@ -163,63 +285,64 @@ void free_plugins(JCR *jcr) } bpContext *plugin_ctx_list = (bpContext *)jcr->plugin_ctx_list; - Dmsg2(dbglvl, "Free instance plugin_ctx_list=%p JobId=%d\n", jcr->plugin_ctx_list, jcr->JobId); + Dmsg2(dbglvl, "Free instance dir-plugin_ctx_list=%p JobId=%d\n", jcr->plugin_ctx_list, jcr->JobId); foreach_alist(plugin, bplugin_list) { /* Free the plugin instance */ - plug_func(plugin)->freePlugin(&plugin_ctx_list[i]); - plugin_ctx_list[i].bContext = NULL; - plugin_ctx_list[i].pContext = NULL; - i++; + dirplug_func(plugin)->freePlugin(&plugin_ctx_list[i]); + free(plugin_ctx_list[i++].bContext); /* free Bacula private context */ } free(plugin_ctx_list); jcr->plugin_ctx_list = NULL; } + /* ============================================================== * * Callbacks from the plugin * * ============================================================== */ -static bRC baculaGetValue(bpContext *ctx, brVariable var, void *value) +static bRC baculaGetValue(bpContext *ctx, brDirVariable var, void *value) { - bRC ret=bRC_OK; + JCR *jcr; + bRC ret = bRC_OK; if (!ctx) { return bRC_Error; } - JCR *jcr = (JCR *)(ctx->bContext); -// Dmsg1(dbglvl, "bacula: baculaGetValue var=%d\n", var); - if (!jcr || !value) { + jcr = ((bacula_ctx *)ctx->bContext)->jcr; + if (!jcr) { + return bRC_Error; + } + if (!value) { return bRC_Error; } -// Dmsg1(dbglvl, "Bacula: jcr=%p\n", jcr); switch (var) { - case bVarJobId: + case bDirVarJobId: *((int *)value) = jcr->JobId; - Dmsg1(dbglvl, "Bacula: return bVarJobId=%d\n", jcr->JobId); + Dmsg1(dbglvl, "dir-plugin: return bDirVarJobId=%d\n", jcr->JobId); break; - case bVarJobName: + case bDirVarJobName: *((char **)value) = jcr->Job; - Dmsg1(dbglvl, "Bacula: return bVarJobName=%s\n", jcr->Job); + Dmsg1(dbglvl, "Bacula: return Job name=%s\n", jcr->Job); break; - case bVarJob: + case bDirVarJob: *((char **)value) = jcr->job->hdr.name; - Dmsg1(dbglvl, "Bacula: return bVarJob=%s\n", jcr->job->hdr.name); + Dmsg1(dbglvl, "Bacula: return bDirVarJob=%s\n", jcr->job->hdr.name); break; - case bVarLevel: + case bDirVarLevel: *((int *)value) = jcr->getJobLevel(); - Dmsg1(dbglvl, "Bacula: return bVarLevel=%c\n", jcr->getJobLevel()); + Dmsg1(dbglvl, "Bacula: return bDirVarLevel=%c\n", jcr->getJobLevel()); break; - case bVarType: + case bDirVarType: *((int *)value) = jcr->getJobType(); - Dmsg1(dbglvl, "Bacula: return bVarType=%c\n", jcr->getJobType()); + Dmsg1(dbglvl, "Bacula: return bDirVarType=%c\n", jcr->getJobType()); break; - case bVarClient: + case bDirVarClient: *((char **)value) = jcr->client->hdr.name; - Dmsg1(dbglvl, "Bacula: return bVarClient=%s\n", jcr->client->hdr.name); + Dmsg1(dbglvl, "Bacula: return bDirVarClient=%s\n", jcr->client->hdr.name); break; - case bVarNumVols: + case bDirVarNumVols: POOL_DBR pr; memset(&pr, 0, sizeof(pr)); bstrncpy(pr.Name, jcr->pool->hdr.name, sizeof(pr.Name)); @@ -227,13 +350,13 @@ static bRC baculaGetValue(bpContext *ctx, brVariable var, void *value) ret=bRC_Error; } *((int *)value) = pr.NumVols; - Dmsg1(dbglvl, "Bacula: return bVarNumVols=%d\n", pr.NumVols); + Dmsg1(dbglvl, "Bacula: return bDirVarNumVols=%d\n", pr.NumVols); break; - case bVarPool: + case bDirVarPool: *((char **)value) = jcr->pool->hdr.name; - Dmsg1(dbglvl, "Bacula: return bVarPool=%s\n", jcr->pool->hdr.name); + Dmsg1(dbglvl, "Bacula: return bDirVarPool=%s\n", jcr->pool->hdr.name); break; - case bVarStorage: + case bDirVarStorage: if (jcr->wstore) { *((char **)value) = jcr->wstore->hdr.name; } else if (jcr->rstore) { @@ -242,31 +365,31 @@ static bRC baculaGetValue(bpContext *ctx, brVariable var, void *value) *((char **)value) = NULL; ret=bRC_Error; } - Dmsg1(dbglvl, "Bacula: return bVarStorage=%s\n", NPRT(*((char **)value))); + Dmsg1(dbglvl, "Bacula: return bDirVarStorage=%s\n", NPRT(*((char **)value))); break; - case bVarWriteStorage: + case bDirVarWriteStorage: if (jcr->wstore) { *((char **)value) = jcr->wstore->hdr.name; } else { *((char **)value) = NULL; ret=bRC_Error; } - Dmsg1(dbglvl, "Bacula: return bVarWriteStorage=%s\n", NPRT(*((char **)value))); + Dmsg1(dbglvl, "Bacula: return bDirVarWriteStorage=%s\n", NPRT(*((char **)value))); break; - case bVarReadStorage: + case bDirVarReadStorage: if (jcr->rstore) { *((char **)value) = jcr->rstore->hdr.name; } else { *((char **)value) = NULL; ret=bRC_Error; } - Dmsg1(dbglvl, "Bacula: return bVarReadStorage=%s\n", NPRT(*((char **)value))); + Dmsg1(dbglvl, "Bacula: return bDirVarReadStorage=%s\n", NPRT(*((char **)value))); break; - case bVarCatalog: + case bDirVarCatalog: *((char **)value) = jcr->catalog->hdr.name; - Dmsg1(dbglvl, "Bacula: return bVarCatalog=%s\n", jcr->catalog->hdr.name); + Dmsg1(dbglvl, "Bacula: return bDirVarCatalog=%s\n", jcr->catalog->hdr.name); break; - case bVarMediaType: + case bDirVarMediaType: if (jcr->wstore) { *((char **)value) = jcr->wstore->media_type; } else if (jcr->rstore) { @@ -275,118 +398,68 @@ static bRC baculaGetValue(bpContext *ctx, brVariable var, void *value) *((char **)value) = NULL; ret=bRC_Error; } - Dmsg1(dbglvl, "Bacula: return bVarMediaType=%s\n", NPRT(*((char **)value))); + Dmsg1(dbglvl, "Bacula: return bDirVarMediaType=%s\n", NPRT(*((char **)value))); break; - case bVarJobStatus: + case bDirVarJobStatus: *((int *)value) = jcr->JobStatus; - Dmsg1(dbglvl, "Bacula: return bVarJobStatus=%c\n", jcr->JobStatus); + Dmsg1(dbglvl, "Bacula: return bDirVarJobStatus=%c\n", jcr->JobStatus); break; - case bVarPriority: + case bDirVarPriority: *((int *)value) = jcr->JobPriority; - Dmsg1(dbglvl, "Bacula: return bVarPriority=%d\n", jcr->JobPriority); + Dmsg1(dbglvl, "Bacula: return bDirVarPriority=%d\n", jcr->JobPriority); break; - case bVarVolumeName: + case bDirVarVolumeName: *((char **)value) = jcr->VolumeName; - Dmsg1(dbglvl, "Bacula: return bVarVolumeName=%s\n", jcr->VolumeName); + Dmsg1(dbglvl, "Bacula: return bDirVarVolumeName=%s\n", jcr->VolumeName); break; - case bVarCatalogRes: + case bDirVarCatalogRes: ret = bRC_Error; break; - case bVarJobErrors: + case bDirVarJobErrors: *((int *)value) = jcr->JobErrors; - Dmsg1(dbglvl, "Bacula: return bVarErrors=%d\n", jcr->JobErrors); + Dmsg1(dbglvl, "Bacula: return bDirVarErrors=%d\n", jcr->JobErrors); break; - case bVarJobFiles: + case bDirVarJobFiles: *((int *)value) = jcr->JobFiles; - Dmsg1(dbglvl, "Bacula: return bVarFiles=%d\n", jcr->JobFiles); + Dmsg1(dbglvl, "Bacula: return bDirVarFiles=%d\n", jcr->JobFiles); break; - case bVarSDJobFiles: + case bDirVarSDJobFiles: *((int *)value) = jcr->SDJobFiles; - Dmsg1(dbglvl, "Bacula: return bVarSDFiles=%d\n", jcr->SDJobFiles); + Dmsg1(dbglvl, "Bacula: return bDirVarSDFiles=%d\n", jcr->SDJobFiles); break; - case bVarSDErrors: + case bDirVarSDErrors: *((int *)value) = jcr->SDErrors; - Dmsg1(dbglvl, "Bacula: return bVarSDErrors=%d\n", jcr->SDErrors); + Dmsg1(dbglvl, "Bacula: return bDirVarSDErrors=%d\n", jcr->SDErrors); break; - case bVarFDJobStatus: + case bDirVarFDJobStatus: *((int *)value) = jcr->FDJobStatus; - Dmsg1(dbglvl, "Bacula: return bVarFDJobStatus=%c\n", jcr->FDJobStatus); + Dmsg1(dbglvl, "Bacula: return bDirVarFDJobStatus=%c\n", jcr->FDJobStatus); break; - case bVarSDJobStatus: + case bDirVarSDJobStatus: *((int *)value) = jcr->SDJobStatus; - Dmsg1(dbglvl, "Bacula: return bVarSDJobStatus=%c\n", jcr->SDJobStatus); + Dmsg1(dbglvl, "Bacula: return bDirVarSDJobStatus=%c\n", jcr->SDJobStatus); break; default: - ret = bRC_Error; break; } return ret; } -extern struct s_jl joblevels[]; - -static bRC baculaSetValue(bpContext *ctx, bwVariable var, void *value) +static bRC baculaSetValue(bpContext *ctx, bwDirVariable var, void *value) { - bRC ret=bRC_OK; - - if (!ctx || !var || !value) { + JCR *jcr; + if (!value || !ctx) { return bRC_Error; } - - JCR *jcr = (JCR *)ctx->bContext; - int intval = *(int*)value; - char *strval = (char *)value; - bool ok; - - switch (var) { - case bwVarJobReport: - Jmsg(jcr, M_INFO, 0, "%s", (char *)value); - break; - - case bwVarVolumeName: - /* Make sure VolumeName is valid and we are in VolumeName event */ - if (jcr->eventType == bEventNewVolume && - is_volume_name_legal(NULL, strval)) - { - pm_strcpy(jcr->VolumeName, strval); - Dmsg1(100, "Set Vol=%s\n", strval); - } else { - jcr->VolumeName[0] = 0; - ret = bRC_Error; - } - break; - - case bwVarPriority: - Dmsg1(000, "Set priority=%d\n", intval); - if (intval >= 1 && intval <= 100) { - jcr->JobPriority = intval; - } else { - ret = bRC_Error; - } - break; - - case bwVarJobLevel: - ok=true; - if (jcr->eventType == bEventJobInit) { - for (int i=0; ok && joblevels[i].level_name; i++) { - if (strcasecmp(strval, joblevels[i].level_name) == 0) { - if (joblevels[i].job_type == jcr->getJobType()) { - jcr->setJobLevel(joblevels[i].level); - jcr->jr.JobLevel = jcr->getJobLevel(); - ok = false; - } - } - } - } else { - ret = bRC_Error; - } - break; - default: - ret = bRC_Error; - break; +// Dmsg1(dbglvl, "bacula: baculaGetValue var=%d\n", var); + jcr = ((bacula_ctx *)ctx->bContext)->jcr; + if (!jcr) { + return bRC_Error; } - Dmsg1(dbglvl, "bacula: baculaSetValue var=%d\n", var); - return ret; +// Dmsg1(dbglvl, "Bacula: jcr=%p\n", jcr); + /* Nothing implemented yet */ + Dmsg1(dbglvl, "dir-plugin: baculaSetValue var=%d\n", var); + return bRC_OK; } static bRC baculaRegisterEvents(bpContext *ctx, ...) @@ -396,21 +469,21 @@ static bRC baculaRegisterEvents(bpContext *ctx, ...) va_start(args, ctx); while ((event = va_arg(args, uint32_t))) { - Dmsg1(dbglvl, "Plugin wants event=%u\n", event); + Dmsg1(dbglvl, "dir-Plugin wants event=%u\n", event); } va_end(args); return bRC_OK; } static bRC baculaJobMsg(bpContext *ctx, const char *file, int line, - int type, utime_t mtime, const char *fmt, ...) + int type, utime_t mtime, const char *fmt, ...) { va_list arg_ptr; char buf[2000]; JCR *jcr; if (ctx) { - jcr = (JCR *)ctx->bContext; + jcr = ((bacula_ctx *)ctx->bContext)->jcr; } else { jcr = NULL; } @@ -423,7 +496,7 @@ static bRC baculaJobMsg(bpContext *ctx, const char *file, int line, } static bRC baculaDebugMsg(bpContext *ctx, const char *file, int line, - int level, const char *fmt, ...) + int level, const char *fmt, ...) { va_list arg_ptr; char buf[2000]; @@ -437,7 +510,6 @@ static bRC baculaDebugMsg(bpContext *ctx, const char *file, int line, #ifdef TEST_PROGRAM - int main(int argc, char *argv[]) { char plugin_dir[1000]; @@ -456,17 +528,16 @@ int main(int argc, char *argv[]) jcr2->JobId = 222; new_plugins(jcr2); - generate_plugin_event(jcr1, bEventJobStart, (void *)"Start Job 1"); - generate_plugin_event(jcr1, bEventJobEnd); - generate_plugin_event(jcr2, bEventJobInit, (void *)"Start Job 1"); - generate_plugin_event(jcr2, bEventJobStart, (void *)"Start Job 1"); + generate_plugin_event(jcr1, bDirEventJobStart, (void *)"Start Job 1"); + generate_plugin_event(jcr1, bDirEventJobEnd); + generate_plugin_event(jcr2, bDirEventJobStart, (void *)"Start Job 1"); free_plugins(jcr1); - generate_plugin_event(jcr2, bEventJobEnd); + generate_plugin_event(jcr2, bDirEventJobEnd); free_plugins(jcr2); unload_plugins(); - Dmsg0(dbglvl, "bacula: OK ...\n"); + Dmsg0(dbglvl, "dir-plugin: OK ...\n"); close_memory_pool(); sm_dump(false); return 0; diff --git a/bacula/src/dird/dir_plugins.h b/bacula/src/dird/dir_plugins.h index 1c22cf5b3a..f0f1b6204c 100644 --- a/bacula/src/dird/dir_plugins.h +++ b/bacula/src/dird/dir_plugins.h @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2007-2009 Free Software Foundation Europe e.V. + Copyright (C) 2007-2011 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. @@ -32,8 +32,8 @@ * */ -#ifndef __FD_PLUGINS_H -#define __FD_PLUGINS_H +#ifndef __DIR_PLUGINS_H +#define __DIR_PLUGINS_H #ifndef _BACULA_H #ifdef __cplusplus @@ -71,80 +71,80 @@ extern "C" { /* Bacula Variable Ids */ /* return value */ typedef enum { - bVarJob = 1, // string - bVarLevel = 2, // int - bVarType = 3, // int - bVarJobId = 4, // int - bVarClient = 5, // string - bVarNumVols = 6, // int - bVarPool = 7, // string - bVarStorage = 8, // string - bVarWriteStorage = 9, // string - bVarReadStorage = 10, // string - bVarCatalog = 11, // string - bVarMediaType = 12, // string - bVarJobName = 13, // string - bVarJobStatus = 14, // int - bVarPriority = 15, // int - bVarVolumeName = 16, // string - bVarCatalogRes = 17, // NYI - bVarJobErrors = 18, // int - bVarJobFiles = 19, // int - bVarSDJobFiles = 20, // int - bVarSDErrors = 21, // int - bVarFDJobStatus = 22, // int - bVarSDJobStatus = 23 // int -} brVariable; + bDirVarJob = 1, // string + bDirVarLevel = 2, // int + bDirVarType = 3, // int + bDirVarJobId = 4, // int + bDirVarClient = 5, // string + bDirVarNumVols = 6, // int + bDirVarPool = 7, // string + bDirVarStorage = 8, // string + bDirVarWriteStorage = 9, // string + bDirVarReadStorage = 10, // string + bDirVarCatalog = 11, // string + bDirVarMediaType = 12, // string + bDirVarJobName = 13, // string + bDirVarJobStatus = 14, // int + bDirVarPriority = 15, // int + bDirVarVolumeName = 16, // string + bDirVarCatalogRes = 17, // NYI + bDirVarJobErrors = 18, // int + bDirVarJobFiles = 19, // int + bDirVarSDJobFiles = 20, // int + bDirVarSDErrors = 21, // int + bDirVarFDJobStatus = 22, // int + bDirVarSDJobStatus = 23 // int +} brDirVariable; typedef enum { - bwVarJobReport = 1, - bwVarVolumeName = 2, - bwVarPriority = 3, - bwVarJobLevel = 4 -} bwVariable; + bwDirVarJobReport = 1, + bwDirVarVolumeName = 2, + bwDirVarPriority = 3, + bwDirVarJobLevel = 4 +} bwDirVariable; typedef enum { - bEventJobStart = 1, - bEventJobEnd = 2, - bEventJobInit = 3, - bEventJobRun = 4, - bEventVolumePurged = 5, - bEventNewVolume = 6, - bEventNeedVolume = 7, - bEventVolumeFull = 8, - bEventRecyle = 9, - bEventGetScratch = 10 -} bEventType; - -typedef struct s_bEvent { + bDirEventJobStart = 1, + bDirEventJobEnd = 2, + bDirEventJobInit = 3, + bDirEventJobRun = 4, + bDirEventVolumePurged = 5, + bDirEventNewVolume = 6, + bDirEventNeedVolume = 7, + bDirEventVolumeFull = 8, + bDirEventRecyle = 9, + bDirEventGetScratch = 10 +} bDirEventType; + +typedef struct s_bDirEvent { uint32_t eventType; -} bEvent; +} bDirEvent; -typedef struct s_baculaInfo { +typedef struct s_dirbaculaInfo { uint32_t size; uint32_t version; -} bInfo; +} bDirInfo; /* Bacula interface version and function pointers */ -typedef struct s_baculaFuncs { +typedef struct s_dirbaculaFuncs { uint32_t size; uint32_t version; bRC (*registerBaculaEvents)(bpContext *ctx, ...); - bRC (*getBaculaValue)(bpContext *ctx, brVariable var, void *value); - bRC (*setBaculaValue)(bpContext *ctx, bwVariable var, void *value); + bRC (*getBaculaValue)(bpContext *ctx, brDirVariable var, void *value); + bRC (*setBaculaValue)(bpContext *ctx, bwDirVariable var, void *value); bRC (*JobMessage)(bpContext *ctx, const char *file, int line, int type, utime_t mtime, const char *fmt, ...); bRC (*DebugMessage)(bpContext *ctx, const char *file, int line, int level, const char *fmt, ...); -} bFuncs; +} bDirFuncs; /* Bacula Core Routines -- not used within a plugin */ #ifdef DIRECTOR_DAEMON void load_dir_plugins(const char *plugin_dir); void new_plugins(JCR *jcr); void free_plugins(JCR *jcr); -void generate_plugin_event(JCR *jcr, bEventType event, void *value=NULL); +int generate_plugin_event(JCR *jcr, bDirEventType event, void *value=NULL); #endif @@ -155,15 +155,15 @@ void generate_plugin_event(JCR *jcr, bEventType event, void *value=NULL); ****************************************************************************/ typedef enum { - pVarName = 1, - pVarDescription = 2 -} pVariable; + pDirVarName = 1, + pDirVarDescription = 2 +} pDirVariable; #define DIR_PLUGIN_MAGIC "*DirPluginData*" #define DIR_PLUGIN_INTERFACE_VERSION 1 -typedef struct s_pluginInfo { +typedef struct s_dirpluginInfo { uint32_t size; uint32_t version; const char *plugin_magic; @@ -172,20 +172,20 @@ typedef struct s_pluginInfo { const char *plugin_date; const char *plugin_version; const char *plugin_description; -} pInfo; +} pDirInfo; -typedef struct s_pluginFuncs { +typedef struct s_dirpluginFuncs { uint32_t size; uint32_t version; bRC (*newPlugin)(bpContext *ctx); bRC (*freePlugin)(bpContext *ctx); - bRC (*getPluginValue)(bpContext *ctx, pVariable var, void *value); - bRC (*setPluginValue)(bpContext *ctx, pVariable var, void *value); - bRC (*handlePluginEvent)(bpContext *ctx, bEvent *event, void *value); -} pFuncs; + bRC (*getPluginValue)(bpContext *ctx, pDirVariable var, void *value); + bRC (*setPluginValue)(bpContext *ctx, pDirVariable var, void *value); + bRC (*handlePluginEvent)(bpContext *ctx, bDirEvent *event, void *value); +} pDirFuncs; -#define plug_func(plugin) ((pFuncs *)(plugin->pfuncs)) -#define plug_info(plugin) ((pInfo *)(plugin->pinfo)) +#define dirplug_func(plugin) ((pDirFuncs *)(plugin->pfuncs)) +#define dirplug_info(plugin) ((pDirInfo *)(plugin->pinfo)) #ifdef __cplusplus } diff --git a/bacula/src/dird/dird.c b/bacula/src/dird/dird.c index 6eff0089d8..c00ec5e532 100644 --- a/bacula/src/dird/dird.c +++ b/bacula/src/dird/dird.c @@ -53,6 +53,7 @@ extern int job_setattr(PyObject *self, char *attrname, PyObject *value); void terminate_dird(int sig); static bool check_resources(); static void dir_sql_query(JCR *jcr, const char *cmd); +static void cleanup_old_files(); /* Exported subroutines */ extern "C" void reload_config(int sig); @@ -282,6 +283,8 @@ int main (int argc, char *argv[]) drop(uid, gid, false); /* reduce privileges if requested */ + cleanup_old_files(); + /* If we are in testing mode, we don't try to fix the catalog */ cat_op mode=(test_config)?CHECK_CONNECTION:UPDATE_AND_FIX; @@ -1116,7 +1119,46 @@ static bool check_catalog(cat_op mode) /* Set type in global for debugging */ set_db_type(db_get_type(db)); +#ifdef BEEF_DEMO + /* + * Demo mode only allows SQLite3 + */ + if (!bstrcmp(db_get_type(db), "SQLite3")) { + Jmsg(NULL, M_FATAL, 0, _("Failed to initialize database backend\n")); + OK = false; + } +#endif + db_close_database(NULL, db); } return OK; } + +static void copy_base_name(POOLMEM *cleanup) +{ + int len = strlen(director->working_directory); +#if defined(HAVE_WIN32) + pm_strcpy(cleanup, "del /q "); +#else + pm_strcpy(cleanup, "/bin/rm -f "); +#endif + pm_strcat(cleanup, director->working_directory); + if (len > 0 && !IsPathSeparator(director->working_directory[len-1])) { + pm_strcat(cleanup, "/"); + } + pm_strcat(cleanup, my_name); +} + +static void cleanup_old_files() +{ + POOLMEM *cleanup = get_pool_memory(PM_MESSAGE); + POOLMEM *results = get_pool_memory(PM_MESSAGE); + copy_base_name(cleanup); + pm_strcat(cleanup, "*.bsr"); + run_program(cleanup, 0, results); + copy_base_name(cleanup); + pm_strcat(cleanup, "*.mail"); + run_program(cleanup, 0, results); + free_pool_memory(cleanup); + free_pool_memory(results); +} diff --git a/bacula/src/dird/dird_conf.c b/bacula/src/dird/dird_conf.c index 07984770b9..8cbd4d470b 100644 --- a/bacula/src/dird/dird_conf.c +++ b/bacula/src/dird/dird_conf.c @@ -1642,14 +1642,13 @@ static void store_actiononpurge(LEX *lc, RES_ITEM *item, int index, int pass) */ static void store_device(LEX *lc, RES_ITEM *item, int index, int pass) { - int token; URES *res; int rindex = R_DEVICE - r_first; int size = sizeof(DEVICE); bool found = false; if (pass == 1) { - token = lex_get_token(lc, T_NAME); + lex_get_token(lc, T_NAME); if (!res_head[rindex]) { res = (URES *)malloc(size); memset(res, 0, size); @@ -1689,9 +1688,9 @@ static void store_device(LEX *lc, RES_ITEM *item, int index, int pass) */ void store_migtype(LEX *lc, RES_ITEM *item, int index, int pass) { - int token, i; + int i; - token = lex_get_token(lc, T_NAME); + lex_get_token(lc, T_NAME); /* Store the type both pass 1 and pass 2 */ for (i=0; migtypes[i].type_name; i++) { if (strcasecmp(lc->str, migtypes[i].type_name) == 0) { @@ -1715,9 +1714,9 @@ void store_migtype(LEX *lc, RES_ITEM *item, int index, int pass) */ void store_jobtype(LEX *lc, RES_ITEM *item, int index, int pass) { - int token, i; + int i; - token = lex_get_token(lc, T_NAME); + lex_get_token(lc, T_NAME); /* Store the type both pass 1 and pass 2 */ for (i=0; jobtypes[i].type_name; i++) { if (strcasecmp(lc->str, jobtypes[i].type_name) == 0) { @@ -1739,9 +1738,9 @@ void store_jobtype(LEX *lc, RES_ITEM *item, int index, int pass) */ void store_level(LEX *lc, RES_ITEM *item, int index, int pass) { - int token, i; + int i; - token = lex_get_token(lc, T_NAME); + lex_get_token(lc, T_NAME); /* Store the level pass 2 so that type is defined */ for (i=0; joblevels[i].level_name; i++) { if (strcasecmp(lc->str, joblevels[i].level_name) == 0) { @@ -1760,8 +1759,8 @@ void store_level(LEX *lc, RES_ITEM *item, int index, int pass) void store_replace(LEX *lc, RES_ITEM *item, int index, int pass) { - int token, i; - token = lex_get_token(lc, T_NAME); + int i; + lex_get_token(lc, T_NAME); /* Scan Replacement options */ for (i=0; ReplaceOptions[i].name; i++) { if (strcasecmp(lc->str, ReplaceOptions[i].name) == 0) { @@ -1786,7 +1785,7 @@ void store_acl(LEX *lc, RES_ITEM *item, int index, int pass) int token; for (;;) { - token = lex_get_token(lc, T_STRING); + lex_get_token(lc, T_STRING); if (pass == 1) { if (((alist **)item->value)[item->code] == NULL) { ((alist **)item->value)[item->code] = New(alist(10, owned_by_alist)); diff --git a/bacula/src/dird/inc_conf.c b/bacula/src/dird/inc_conf.c index de91e7a862..7df0be1a49 100644 --- a/bacula/src/dird/inc_conf.c +++ b/bacula/src/dird/inc_conf.c @@ -281,14 +281,14 @@ static struct s_fs_opt FS_options[] = { */ static void scan_include_options(LEX *lc, int keyword, char *opts, int optlen) { - int token, i; + int i; char option[3]; int lcopts = lc->options; option[0] = 0; /* default option = none */ option[2] = 0; /* terminate options */ lc->options |= LOPT_STRING; /* force string */ - token = lex_get_token(lc, T_STRING); /* expect at least one option */ + lex_get_token(lc, T_STRING); /* expect at least one option */ if (keyword == INC_KW_VERIFY) { /* special case */ /* ***FIXME**** ensure these are in permitted set */ bstrncat(opts, "V", optlen); /* indicate Verify */ @@ -339,7 +339,7 @@ static void scan_include_options(LEX *lc, int keyword, char *opts, int optlen) /* If option terminated by comma, eat it */ if (lc->ch == ',') { - token = lex_get_token(lc, T_ALL); /* yes, eat comma */ + lex_get_token(lc, T_ALL); /* yes, eat comma */ } } @@ -491,9 +491,8 @@ static void store_regex(LEX *lc, RES_ITEM *item, int index, int pass) /* Store Base info */ static void store_base(LEX *lc, RES_ITEM *item, int index, int pass) { - int token; - token = lex_get_token(lc, T_NAME); + lex_get_token(lc, T_NAME); if (pass == 1) { /* * Pickup Base Job Name @@ -506,9 +505,8 @@ static void store_base(LEX *lc, RES_ITEM *item, int index, int pass) /* Store reader info */ static void store_plugin(LEX *lc, RES_ITEM *item, int index, int pass) { - int token; - token = lex_get_token(lc, T_NAME); + lex_get_token(lc, T_NAME); if (pass == 1) { /* * Pickup plugin command @@ -590,13 +588,12 @@ static void store_fstype(LEX *lc, RES_ITEM *item, int index, int pass) /* Store exclude directory containing info */ static void store_excludedir(LEX *lc, RES_ITEM2 *item, int index, int pass, bool exclude) { - int token; if (exclude) { scan_err0(lc, _("ExcludeDirContaining directive not permitted in Exclude.\n")); /* NOT REACHED */ } - token = lex_get_token(lc, T_NAME); + lex_get_token(lc, T_NAME); if (pass == 1) { res_incexe.ignoredir = bstrdup(lc->str); } diff --git a/bacula/src/dird/job.c b/bacula/src/dird/job.c index f850489cac..768b6cf1cf 100644 --- a/bacula/src/dird/job.c +++ b/bacula/src/dird/job.c @@ -172,7 +172,7 @@ bool setup_job(JCR *jcr) generate_daemon_event(jcr, "JobStart"); new_plugins(jcr); /* instantiate plugins for this jcr */ - generate_plugin_event(jcr, bEventJobStart); + generate_plugin_event(jcr, bDirEventJobStart); if (job_canceled(jcr)) { goto bail_out; @@ -233,7 +233,7 @@ bool setup_job(JCR *jcr) } generate_job_event(jcr, "JobInit"); - generate_plugin_event(jcr, bEventJobInit); + generate_plugin_event(jcr, bDirEventJobInit); Dsm_check(100); return true; @@ -306,7 +306,7 @@ static void *job_thread(void *arg) Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db)); } generate_job_event(jcr, "JobRun"); - generate_plugin_event(jcr, bEventJobRun); + generate_plugin_event(jcr, bDirEventJobRun); switch (jcr->getJobType()) { case JT_BACKUP: @@ -358,7 +358,7 @@ static void *job_thread(void *arg) } generate_daemon_event(jcr, "JobEnd"); - generate_plugin_event(jcr, bEventJobEnd); + generate_plugin_event(jcr, bDirEventJobEnd); Dmsg1(50, "======== End Job stat=%c ==========\n", jcr->JobStatus); Dsm_check(100); return NULL; diff --git a/bacula/src/dird/newvol.c b/bacula/src/dird/newvol.c index cac986ccd9..2037ff4464 100644 --- a/bacula/src/dird/newvol.c +++ b/bacula/src/dird/newvol.c @@ -72,7 +72,7 @@ bool newVolume(JCR *jcr, MEDIA_DBR *mr) jcr->VolumeName[0] = 0; bstrncpy(mr->MediaType, jcr->wstore->media_type, sizeof(mr->MediaType)); generate_job_event(jcr, "NewVolume"); /* return bool */ - generate_plugin_event(jcr, bEventNewVolume); /* return void... */ + generate_plugin_event(jcr, bDirEventNewVolume); /* return void... */ if (jcr->VolumeName[0] && is_volume_name_legal(NULL, jcr->VolumeName)) { bstrncpy(mr->VolumeName, jcr->VolumeName, sizeof(mr->VolumeName)); /* Check for special characters */ diff --git a/bacula/src/dird/scheduler.c b/bacula/src/dird/scheduler.c index 866194d3a3..a4b32ce126 100644 --- a/bacula/src/dird/scheduler.c +++ b/bacula/src/dird/scheduler.c @@ -260,10 +260,9 @@ static void find_runs() JOB *job; SCHED *sched; struct tm tm; - int minute; int hour, mday, wday, month, wom, woy; /* Items corresponding to above at the next hour */ - int nh_hour, nh_mday, nh_wday, nh_month, nh_wom, nh_woy, nh_year; + int nh_hour, nh_mday, nh_wday, nh_month, nh_wom, nh_woy; Dmsg0(dbglvl, "enter find_runs()\n"); @@ -272,7 +271,6 @@ static void find_runs() now = time(NULL); (void)localtime_r(&now, &tm); hour = tm.tm_hour; - minute = tm.tm_min; mday = tm.tm_mday - 1; wday = tm.tm_wday; month = tm.tm_mon; @@ -293,7 +291,6 @@ static void find_runs() nh_mday = tm.tm_mday - 1; nh_wday = tm.tm_wday; nh_month = tm.tm_mon; - nh_year = tm.tm_year; nh_wom = nh_mday / 7; nh_woy = tm_woy(next_hour); /* get week of year */ diff --git a/bacula/src/dird/ua.h b/bacula/src/dird/ua.h index e6ad35bb09..721adfee8e 100644 --- a/bacula/src/dird/ua.h +++ b/bacula/src/dird/ua.h @@ -53,6 +53,7 @@ public: int max_prompts; /* max size of list */ int num_prompts; /* current number in list */ int api; /* For programs want an API */ + int cmd_index; /* Index in command table */ bool force_mult_db_connections; /* overwrite cat.mult_db_connections */ bool auto_display_messages; /* if set, display messages */ bool user_notified_msg_pending; /* set when user notified */ diff --git a/bacula/src/dird/ua_cmds.c b/bacula/src/dird/ua_cmds.c index 3dd161a259..2ce9df6995 100644 --- a/bacula/src/dird/ua_cmds.c +++ b/bacula/src/dird/ua_cmds.c @@ -280,7 +280,6 @@ static int add_cmd(UAContext *ua, const char *cmd) POOL_DBR pr; MEDIA_DBR mr; int num, i, max, startnum; - int first_id = 0; char name[MAX_NAME_LENGTH]; STORE *store; int Slot = 0, InChanger = 0; @@ -406,9 +405,6 @@ static int add_cmd(UAContext *ua, const char *cmd) ua->error_msg("%s", db_strerror(ua->db)); return 1; } - if (i == startnum) { - first_id = mr.PoolId; - } } pr.NumVols += num; Dmsg0(200, "Update pool record.\n"); diff --git a/bacula/src/dird/ua_label.c b/bacula/src/dird/ua_label.c index 7e70ebad92..8cf3592355 100644 --- a/bacula/src/dird/ua_label.c +++ b/bacula/src/dird/ua_label.c @@ -1197,7 +1197,6 @@ void status_slots(UAContext *ua, STORE *store_r) MEDIA_DBR mr; char *slot_list; int max_slots; - int drive; int i=1; /* Slot | Volume | Status | MediaType | Pool */ const char *slot_hformat=" %4i%c| %16s | %9s | %20s | %18s |\n"; @@ -1214,7 +1213,7 @@ void status_slots(UAContext *ua, STORE *store_r) pm_strcpy(store.store_source, _("command line")); set_wstorage(ua->jcr, &store); - drive = get_storage_drive(ua, store.store); + get_storage_drive(ua, store.store); max_slots = get_num_slots_from_SD(ua); diff --git a/bacula/src/dird/ua_purge.c b/bacula/src/dird/ua_purge.c index 34856df34e..81c7ed493b 100644 --- a/bacula/src/dird/ua_purge.c +++ b/bacula/src/dird/ua_purge.c @@ -767,7 +767,7 @@ bool mark_media_purged(UAContext *ua, MEDIA_DBR *mr) } pm_strcpy(jcr->VolumeName, mr->VolumeName); generate_job_event(jcr, "VolumePurged"); - generate_plugin_event(jcr, bEventVolumePurged); + generate_plugin_event(jcr, bDirEventVolumePurged); /* * If the RecyclePool is defined, move the volume there */ diff --git a/bacula/src/dird/verify.c b/bacula/src/dird/verify.c index 386fcb0036..41fde6ac21 100644 --- a/bacula/src/dird/verify.c +++ b/bacula/src/dird/verify.c @@ -393,7 +393,6 @@ void verify_cleanup(JCR *jcr, int TermCode) char term_code[100], fd_term_msg[100], sd_term_msg[100]; const char *term_msg; int msg_type; - JobId_t JobId; const char *Name; // Dmsg1(100, "Enter verify_cleanup() TermCod=%d\n", TermCode); @@ -405,8 +404,6 @@ void verify_cleanup(JCR *jcr, int TermCode) TermCode = JS_ErrorTerminated; } - JobId = jcr->jr.JobId; - update_job_end(jcr, TermCode); if (job_canceled(jcr)) { diff --git a/bacula/src/filed/accurate.c b/bacula/src/filed/accurate.c index 1c50411ceb..404756aa6c 100644 --- a/bacula/src/filed/accurate.c +++ b/bacula/src/filed/accurate.c @@ -380,7 +380,9 @@ bool accurate_check_file(JCR *jcr, FF_PKT *ff_pkt) stat = true; } break; - + case 'A': /* Always backup a file */ + stat = true; + break; /* TODO: cleanup and factorise this function with verify.c */ case '5': /* compare MD5 */ case '1': /* compare SHA1 */ @@ -496,7 +498,7 @@ int accurate_cmd(JCR *jcr) BSOCK *dir = jcr->dir_bsock; int lstat_pos, chksum_pos; int32_t nb; - uint32_t delta_seq; + uint16_t delta_seq; if (job_canceled(jcr)) { return true; diff --git a/bacula/src/filed/backup.c b/bacula/src/filed/backup.c index 0f61e0f9de..c4c782a30b 100644 --- a/bacula/src/filed/backup.c +++ b/bacula/src/filed/backup.c @@ -1320,7 +1320,6 @@ bool encode_and_send_attributes(JCR *jcr, FF_PKT *ff_pkt, int &data_stream) ff_pkt->object_compression = 0; if (ff_pkt->object_len > 1000) { /* Big object, compress it */ - int stat; comp_len = ff_pkt->object_len + 1000; POOLMEM *comp_obj = get_memory(comp_len); stat = Zdeflate(ff_pkt->object, ff_pkt->object_len, comp_obj, comp_len); diff --git a/bacula/src/jcr.h b/bacula/src/jcr.h index 5c80e00111..4017933106 100644 --- a/bacula/src/jcr.h +++ b/bacula/src/jcr.h @@ -93,9 +93,11 @@ #define JS_DataDespooling 'l' /* Doing data despooling */ #define JS_WaitMedia 'm' /* waiting for new media */ #define JS_WaitPriority 'p' /* Waiting for higher priority jobs to finish */ +#define JS_WaitDevice 'q' /* Queued waiting for device */ #define JS_WaitStoreRes 's' /* Waiting for storage resource */ #define JS_WaitStartTime 't' /* Waiting for start time */ + /* Migration selection types */ enum { MT_SMALLEST_VOL = 1, @@ -127,6 +129,7 @@ enum { jcr->JobStatus == JS_WaitPriority || \ jcr->SDJobStatus == JS_WaitMedia || \ jcr->SDJobStatus == JS_WaitMount || \ + jcr->SDJobStatus == JS_WaitDevice || \ jcr->SDJobStatus == JS_WaitMaxJobs) @@ -141,6 +144,7 @@ enum { /* Forward referenced structures */ class JCR; +class BSOCK; struct FF_PKT; class B_DB; struct ATTR_DBR; @@ -204,7 +208,9 @@ public: }; const char *get_OperationName(); /* in lib/jcr.c */ const char *get_ActionName(bool past); /* in lib/jcr.c */ - void setJobStatus(int JobStatus); /* in lib/jcr.c */ + void setJobStatus(int newJobStatus); /* in lib/jcr.c */ + bool sendJobStatus(); /* in lib/jcr.c */ + bool sendJobStatus(int newJobStatus); /* in lib/jcr.c */ bool JobReads(); /* in lib/jcr.c */ void my_thread_send_signal(int sig); /* in lib/jcr.c */ void set_killable(bool killable); /* in lib/jcr.c */ @@ -262,6 +268,7 @@ public: bool cached_attribute; /* set if attribute is cached */ bool batch_started; /* is batch mode already started ? */ bool cmd_plugin; /* Set when processing a command Plugin = */ + bool opt_plugin; /* Set when processing an option Plugin = */ bool keep_path_list; /* Keep newly created path in a hash */ bool accurate; /* true if job is accurate */ bool HasBase; /* True if job use base jobs */ @@ -295,7 +302,6 @@ public: pthread_t SD_msg_chan; /* Message channel thread id */ pthread_cond_t term_wait; /* Wait for job termination */ workq_ele_t *work_item; /* Work queue item if scheduled */ - volatile bool sd_msg_thread_done; /* Set when Storage message thread done */ BSOCK *ua; /* User agent */ JOB *job; /* Job resource */ JOB *verify_job; /* Job resource of verify previous job */ @@ -343,6 +349,7 @@ public: int32_t reschedule_count; /* Number of times rescheduled */ int32_t FDVersion; /* File daemon version number */ int64_t spool_size; /* Spool size for this job */ + volatile bool sd_msg_thread_done; /* Set when Storage message thread done */ bool wasVirtualFull; /* set if job was VirtualFull */ bool IgnoreDuplicateJobChecking; /* set in migration jobs */ bool spool_data; /* Spool data in SD */ @@ -364,6 +371,7 @@ public: bool run_inc_pool_override; bool run_diff_pool_override; bool sd_canceled; /* set if SD canceled */ + bool RescheduleIncompleteJobs; /* set if incomplete can be rescheduled */ #endif /* DIRECTOR_DAEMON */ diff --git a/bacula/src/lib/bsnprintf.c b/bacula/src/lib/bsnprintf.c index 9572f31d99..afef57c1d9 100644 --- a/bacula/src/lib/bsnprintf.c +++ b/bacula/src/lib/bsnprintf.c @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2005-2011 Free Software Foundation Europe e.V. + Copyright (C) 2005-2012 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. @@ -372,33 +372,28 @@ int bvsnprintf(char *buffer, int32_t maxlen, const char *format, va_list args) } currlen = fmtint(buffer, currlen, maxlen, value, 16, min, max, flags); break; + +#ifdef SECURITY_PROBLEM case 'n': if (cflags == DP_C_INT16) { int16_t *num; num = va_arg(args, int16_t *); -#ifdef SECURITY_PROBLEM *num = currlen; -#endif } else if (cflags == DP_C_INT32) { int32_t *num; num = va_arg(args, int32_t *); -#ifdef SECURITY_PROBLEM *num = (int32_t)currlen; -#endif } else if (cflags == DP_C_INT64) { int64_t *num; num = va_arg(args, int64_t *); -#ifdef SECURITY_PROBLEM *num = (int64_t)currlen; -#endif } else { int32_t *num; num = va_arg(args, int32_t *); -#ifdef SECURITY_PROBLEM *num = (int32_t)currlen; -#endif } break; +#endif case '%': outch(ch); break; diff --git a/bacula/src/lib/jcr.c b/bacula/src/lib/jcr.c index 3f4106b9ff..d895ba13cc 100644 --- a/bacula/src/lib/jcr.c +++ b/bacula/src/lib/jcr.c @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2000-2011 Free Software Foundation Europe e.V. + Copyright (C) 2000-2012 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. @@ -87,6 +87,8 @@ static pthread_key_t jcr_key; /* Pointer to jcr for each thread */ pthread_once_t key_once = PTHREAD_ONCE_INIT; +static char Job_status[] = "Status Job=%s JobStatus=%d\n"; + void lock_jobs() { @@ -863,6 +865,34 @@ static int get_status_priority(int JobStatus) return priority; } +/* + * Send Job status to Director + */ +bool JCR::sendJobStatus() +{ + JCR *jcr = this; + if (jcr->dir_bsock) { + return jcr->dir_bsock->fsend(Job_status, jcr->Job, jcr->JobStatus); + } + return true; +} + +/* + * Set and send Job status to Director + */ +bool JCR::sendJobStatus(int newJobStatus) +{ + JCR *jcr = this; + if (!jcr->is_JobStatus(newJobStatus)) { + setJobStatus(newJobStatus); + if (jcr->dir_bsock) { + return jcr->dir_bsock->fsend(Job_status, jcr->Job, jcr->JobStatus); + } + } + return true; +} + + void JCR::setJobStatus(int newJobStatus) { JCR *jcr = this; diff --git a/bacula/src/lib/lex.c b/bacula/src/lib/lex.c index aaa177f2d7..4e2558a8b0 100644 --- a/bacula/src/lib/lex.c +++ b/bacula/src/lib/lex.c @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2000-2011 Free Software Foundation Europe e.V. + Copyright (C) 2000-2012 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. @@ -452,8 +452,14 @@ lex_get_token(LEX *lf, int expect) } break; case '@': - lf->state = lex_include; - begin_str(lf, 0); + /* In NO_EXTERN mode, @ is part of a string */ + if (lf->options & LOPT_NO_EXTERN) { + lf->state = lex_string; + begin_str(lf, ch); + } else { + lf->state = lex_include; + begin_str(lf, 0); + } break; case 0xEF: /* probably a UTF-8 BOM */ case 0xFF: /* probably a UTF-16le BOM */ diff --git a/bacula/src/lib/lex.h b/bacula/src/lib/lex.h index cd4065652f..115a60ac7f 100644 --- a/bacula/src/lib/lex.h +++ b/bacula/src/lib/lex.h @@ -96,6 +96,7 @@ enum lex_state { /* Lex scan options */ #define LOPT_NO_IDENT 0x1 /* No Identifiers -- use string */ #define LOPT_STRING 0x2 /* Force scan for string */ +#define LOPT_NO_EXTERN 0x4 /* Don't follow @ command */ class BPIPE; /* forward reference */ diff --git a/bacula/src/lib/parse_conf.c b/bacula/src/lib/parse_conf.c index 819442dfa8..b2a3a98f06 100644 --- a/bacula/src/lib/parse_conf.c +++ b/bacula/src/lib/parse_conf.c @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2000-2011 Free Software Foundation Europe e.V. + Copyright (C) 2000-2012 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. @@ -788,9 +788,9 @@ void store_bool(LEX *lc, RES_ITEM *item, int index, int pass) */ void store_label(LEX *lc, RES_ITEM *item, int index, int pass) { - int token, i; + int i; - token = lex_get_token(lc, T_NAME); + lex_get_token(lc, T_NAME); /* Store the label pass 2 so that type is defined */ for (i=0; tapelabels[i].name; i++) { if (strcasecmp(lc->str, tapelabels[i].name) == 0) { diff --git a/bacula/src/lib/plugins.c b/bacula/src/lib/plugins.c index 7b2fce7831..59aad3cdc9 100644 --- a/bacula/src/lib/plugins.c +++ b/bacula/src/lib/plugins.c @@ -1,5 +1,5 @@ /* - Bacula® - The Network Backup Solution + Bacula(R) - The Network Backup Solution Copyright (C) 2007-2011 Free Software Foundation Europe e.V. @@ -20,7 +20,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - Bacula® is a registered trademark of Kern Sibbald. + Bacula(R) is a registered trademark of Kern Sibbald. The licensor of Bacula is the Free Software Foundation Europe (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, Switzerland, email:ftf@fsfeurope.org. @@ -101,6 +101,7 @@ bool load_plugins(void *binfo, void *bfuncs, const char *plugin_dir, int len, type_len; + Dmsg0(dbglvl, "load_plugins\n"); name_max = pathconf(".", _PC_NAME_MAX); if (name_max < 1024) { name_max = 1024; @@ -142,7 +143,7 @@ bool load_plugins(void *binfo, void *bfuncs, const char *plugin_dir, Dmsg3(dbglvl, "Rejected plugin: want=%s name=%s len=%d\n", type, result->d_name, len); continue; } - Dmsg2(dbglvl, "Loaded plugin: name=%s len=%d\n", result->d_name, len); + Dmsg2(dbglvl, "Found plugin: name=%s len=%d\n", result->d_name, len); pm_strcpy(fname, plugin_dir); if (need_slash) { @@ -158,10 +159,11 @@ bool load_plugins(void *binfo, void *bfuncs, const char *plugin_dir, plugin->file_len = strstr(plugin->file, type) - plugin->file; plugin->pHandle = dlopen(fname.c_str(), RTLD_NOW); if (!plugin->pHandle) { - Jmsg(NULL, M_ERROR, 0, _("Plugin load %s failed: ERR=%s\n"), - fname.c_str(), NPRT(dlerror())); - Dmsg2(dbglvl, "Plugin load %s failed: ERR=%s\n", fname.c_str(), - NPRT(dlerror())); + char *error = dlerror(); + Jmsg(NULL, M_ERROR, 0, _("dlopen plugin %s failed: ERR=%s\n"), + fname.c_str(), NPRT(error)); + Dmsg2(dbglvl, "dlopen plugin %s failed: ERR=%s\n", fname.c_str(), + NPRT(error)); close_plugin(plugin); continue; } diff --git a/bacula/src/plugins/dir/example-plugin-dir.c b/bacula/src/plugins/dir/example-plugin-dir.c index dddf672c92..c307860aae 100644 --- a/bacula/src/plugins/dir/example-plugin-dir.c +++ b/bacula/src/plugins/dir/example-plugin-dir.c @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2007-2008 Free Software Foundation Europe e.V. + Copyright (C) 2007-2010 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. @@ -38,7 +38,7 @@ extern "C" { #endif -#define PLUGIN_LICENSE "GPL" +#define PLUGIN_LICENSE "Bacula AGPLv3" #define PLUGIN_AUTHOR "Kern Sibbald" #define PLUGIN_DATE "January 2008" #define PLUGIN_VERSION "1" @@ -47,16 +47,16 @@ extern "C" { /* Forward referenced functions */ static bRC newPlugin(bpContext *ctx); static bRC freePlugin(bpContext *ctx); -static bRC getPluginValue(bpContext *ctx, pVariable var, void *value); -static bRC setPluginValue(bpContext *ctx, pVariable var, void *value); -static bRC handlePluginEvent(bpContext *ctx, bEvent *event, void *value); +static bRC getPluginValue(bpContext *ctx, pDirVariable var, void *value); +static bRC setPluginValue(bpContext *ctx, pDirVariable var, void *value); +static bRC handlePluginEvent(bpContext *ctx, bDirEvent *event, void *value); /* Pointers to Bacula functions */ -static bFuncs *bfuncs = NULL; -static bInfo *binfo = NULL; +static bDirFuncs *bfuncs = NULL; +static bDirInfo *binfo = NULL; -static pInfo pluginInfo = { +static pDirInfo pluginInfo = { sizeof(pluginInfo), DIR_PLUGIN_INTERFACE_VERSION, DIR_PLUGIN_MAGIC, @@ -64,10 +64,10 @@ static pInfo pluginInfo = { PLUGIN_AUTHOR, PLUGIN_DATE, PLUGIN_VERSION, - PLUGIN_DESCRIPTION, + PLUGIN_DESCRIPTION }; -static pFuncs pluginFuncs = { +static pDirFuncs pluginFuncs = { sizeof(pluginFuncs), DIR_PLUGIN_INTERFACE_VERSION, @@ -79,7 +79,7 @@ static pFuncs pluginFuncs = { handlePluginEvent }; -bRC loadPlugin(bInfo *lbinfo, bFuncs *lbfuncs, pInfo **pinfo, pFuncs **pfuncs) +bRC loadPlugin(bDirInfo *lbinfo, bDirFuncs *lbfuncs, pDirInfo **pinfo, pDirFuncs **pfuncs) { bfuncs = lbfuncs; /* set Bacula funct pointers */ binfo = lbinfo; @@ -100,7 +100,7 @@ bRC unloadPlugin() static bRC newPlugin(bpContext *ctx) { int JobId = 0; - bfuncs->getBaculaValue(ctx, bVarJobId, (void *)&JobId); + bfuncs->getBaculaValue(ctx, bDirVarJobId, (void *)&JobId); printf("plugin: newPlugin JobId=%d\n", JobId); bfuncs->registerBaculaEvents(ctx, 1, 2, 0); return bRC_OK; @@ -109,59 +109,59 @@ static bRC newPlugin(bpContext *ctx) static bRC freePlugin(bpContext *ctx) { int JobId = 0; - bfuncs->getBaculaValue(ctx, bVarJobId, (void *)&JobId); + bfuncs->getBaculaValue(ctx, bDirVarJobId, (void *)&JobId); printf("plugin: freePlugin JobId=%d\n", JobId); return bRC_OK; } -static bRC getPluginValue(bpContext *ctx, pVariable var, void *value) +static bRC getPluginValue(bpContext *ctx, pDirVariable var, void *value) { printf("plugin: getPluginValue var=%d\n", var); return bRC_OK; } -static bRC setPluginValue(bpContext *ctx, pVariable var, void *value) +static bRC setPluginValue(bpContext *ctx, pDirVariable var, void *value) { printf("plugin: setPluginValue var=%d\n", var); return bRC_OK; } -static bRC handlePluginEvent(bpContext *ctx, bEvent *event, void *value) +static bRC handlePluginEvent(bpContext *ctx, bDirEvent *event, void *value) { char *name; int val; switch (event->eventType) { - case bEventJobStart: + case bDirEventJobStart: printf("plugin: HandleEvent JobStart\n"); break; - case bEventJobEnd: + case bDirEventJobEnd: printf("plugin: HandleEvent JobEnd\n"); - bfuncs->getBaculaValue(ctx, bVarJob, (void *)&name); - printf("plugin: bVarJob=%s\n", name); - bfuncs->getBaculaValue(ctx, bVarJobId, (void *)&val); - printf("plugin: bVarJobId=%d\n", val); - bfuncs->getBaculaValue(ctx, bVarType, (void *)&val); - printf("plugin: bVarType=%c\n", val); - bfuncs->getBaculaValue(ctx, bVarLevel, (void *)&val); - printf("plugin: bVarLevel=%c\n", val); - bfuncs->getBaculaValue(ctx, bVarClient, (void *)&name); - printf("plugin: bVarClient=%s\n", name); - bfuncs->getBaculaValue(ctx, bVarCatalog, (void *)&name); - printf("plugin: bVarCatalog=%s\n", name); - bfuncs->getBaculaValue(ctx, bVarPool, (void *)&name); - printf("plugin: bVarPool=%s\n", name); - bfuncs->getBaculaValue(ctx, bVarStorage, (void *)&name); - printf("plugin: bVarStorage=%s\n", name); - bfuncs->getBaculaValue(ctx, bVarJobErrors, (void *)&val); - printf("plugin: bVarJobErrors=%d\n", val); - bfuncs->getBaculaValue(ctx, bVarJobFiles, (void *)&val); - printf("plugin: bVarJobFiles=%d\n", val); - bfuncs->getBaculaValue(ctx, bVarNumVols, (void *)&val); - printf("plugin: bVarNumVols=%d\n", val); + bfuncs->getBaculaValue(ctx, bDirVarJob, (void *)&name); + printf("plugin: bDirVarJob=%s\n", name); + bfuncs->getBaculaValue(ctx, bDirVarJobId, (void *)&val); + printf("plugin: bDirVarJobId=%d\n", val); + bfuncs->getBaculaValue(ctx, bDirVarType, (void *)&val); + printf("plugin: bDirVarType=%c\n", val); + bfuncs->getBaculaValue(ctx, bDirVarLevel, (void *)&val); + printf("plugin: bDirVarLevel=%c\n", val); + bfuncs->getBaculaValue(ctx, bDirVarClient, (void *)&name); + printf("plugin: bDirVarClient=%s\n", name); + bfuncs->getBaculaValue(ctx, bDirVarCatalog, (void *)&name); + printf("plugin: bDirVarCatalog=%s\n", name); + bfuncs->getBaculaValue(ctx, bDirVarPool, (void *)&name); + printf("plugin: bDirVarPool=%s\n", name); + bfuncs->getBaculaValue(ctx, bDirVarStorage, (void *)&name); + printf("plugin: bDirVarStorage=%s\n", name); + bfuncs->getBaculaValue(ctx, bDirVarJobErrors, (void *)&val); + printf("plugin: bDirVarJobErrors=%d\n", val); + bfuncs->getBaculaValue(ctx, bDirVarJobFiles, (void *)&val); + printf("plugin: bDirVarJobFiles=%d\n", val); + bfuncs->getBaculaValue(ctx, bDirVarNumVols, (void *)&val); + printf("plugin: bDirVarNumVols=%d\n", val); break; } - bfuncs->getBaculaValue(ctx, bVarJobName, (void *)&name); + bfuncs->getBaculaValue(ctx, bDirVarJobName, (void *)&name); printf("Job Name=%s\n", name); bfuncs->JobMessage(ctx, __FILE__, __LINE__, M_INFO, 0, "JobMesssage message"); bfuncs->DebugMessage(ctx, __FILE__, __LINE__, 1, "DebugMesssage message"); diff --git a/bacula/src/plugins/fd/example-plugin-fd.c b/bacula/src/plugins/fd/example-plugin-fd.c index df56719149..dced30e274 100644 --- a/bacula/src/plugins/fd/example-plugin-fd.c +++ b/bacula/src/plugins/fd/example-plugin-fd.c @@ -9,6 +9,10 @@ the code in any way. */ + +#define BUILD_PLUGIN +#define BUILDING_DLL /* required for Windows plugin */ + #include "bacula.h" #include "fd_plugins.h" @@ -18,7 +22,7 @@ extern "C" { #define PLUGIN_LICENSE "AGPLv3" #define PLUGIN_AUTHOR "Your name" -#define PLUGIN_DATE "January 2008" +#define PLUGIN_DATE "January 2010" #define PLUGIN_VERSION "1" #define PLUGIN_DESCRIPTION "Test File Daemon Plugin" @@ -74,7 +78,8 @@ static pFuncs pluginFuncs = { /* * Plugin called here when it is first loaded */ -bRC loadPlugin(bInfo *lbinfo, bFuncs *lbfuncs, pInfo **pinfo, pFuncs **pfuncs) +bRC DLL_IMP_EXP +loadPlugin(bInfo *lbinfo, bFuncs *lbfuncs, pInfo **pinfo, pFuncs **pfuncs) { bfuncs = lbfuncs; /* set Bacula funct pointers */ binfo = lbinfo; @@ -90,7 +95,8 @@ bRC loadPlugin(bInfo *lbinfo, bFuncs *lbfuncs, pInfo **pinfo, pFuncs **pfuncs) * Plugin called here when it is unloaded, normally when * Bacula is going to exit. */ -bRC unloadPlugin() +bRC DLL_IMP_EXP +unloadPlugin() { printf("plugin: Unloaded\n"); return bRC_OK; diff --git a/bacula/src/plugins/sd/example-plugin-sd.c b/bacula/src/plugins/sd/example-plugin-sd.c index 0d747a78ca..9f6d8b38ee 100644 --- a/bacula/src/plugins/sd/example-plugin-sd.c +++ b/bacula/src/plugins/sd/example-plugin-sd.c @@ -1,7 +1,7 @@ /* - Bacula® - The Network Backup Solution + Bacula(R) - The Network Backup Solution - Copyright (C) 2007-2008 Free Software Foundation Europe e.V. + Copyright (C) 2007-2011 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. @@ -20,17 +20,18 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - Bacula® is a registered trademark of Kern Sibbald. + Bacula(R) is a registered trademark of Kern Sibbald. The licensor of Bacula is the Free Software Foundation Europe (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, Switzerland, email:ftf@fsfeurope.org. */ /* - * Sample Plugin program + * Sample Storage daemon Plugin program * * Kern Sibbald, October 2007 * */ +#ifdef working #include "bacula.h" #include "sd_plugins.h" @@ -38,25 +39,25 @@ extern "C" { #endif -#define PLUGIN_LICENSE "GPL" +#define PLUGIN_LICENSE "Bacula AGPLv3" #define PLUGIN_AUTHOR "Kern Sibbald" -#define PLUGIN_DATE "January 2008" -#define PLUGIN_VERSION "1" +#define PLUGIN_DATE "November 2011" +#define PLUGIN_VERSION "2" #define PLUGIN_DESCRIPTION "Test Storage Daemon Plugin" /* Forward referenced functions */ static bRC newPlugin(bpContext *ctx); static bRC freePlugin(bpContext *ctx); -static bRC getPluginValue(bpContext *ctx, pVariable var, void *value); -static bRC setPluginValue(bpContext *ctx, pVariable var, void *value); -static bRC handlePluginEvent(bpContext *ctx, bEvent *event, void *value); +static bRC getPluginValue(bpContext *ctx, psdVariable var, void *value); +static bRC setPluginValue(bpContext *ctx, psdVariable var, void *value); +static bRC handlePluginEvent(bpContext *ctx, bsdEvent *event, void *value); /* Pointers to Bacula functions */ -static bFuncs *bfuncs = NULL; -static bInfo *binfo = NULL; +static bsdFuncs *bfuncs = NULL; +static bsdInfo *binfo = NULL; -static pInfo pluginInfo = { +static psdInfo pluginInfo = { sizeof(pluginInfo), SD_PLUGIN_INTERFACE_VERSION, SD_PLUGIN_MAGIC, @@ -64,10 +65,10 @@ static pInfo pluginInfo = { PLUGIN_AUTHOR, PLUGIN_DATE, PLUGIN_VERSION, - PLUGIN_DESCRIPTION, + PLUGIN_DESCRIPTION }; -static pFuncs pluginFuncs = { +static psdFuncs pluginFuncs = { sizeof(pluginFuncs), SD_PLUGIN_INTERFACE_VERSION, @@ -79,65 +80,96 @@ static pFuncs pluginFuncs = { handlePluginEvent }; -bRC loadPlugin(bInfo *lbinfo, bFuncs *lbfuncs, pInfo **pinfo, pFuncs **pfuncs) +/* + * loadPlugin() and unloadPlugin() are entry points that are + * exported, so Bacula can directly call these two entry points + * they are common to all Bacula plugins. + * + * External entry point called by Bacula to "load the plugin + */ +bRC DLL_IMP_EXP +loadPlugin(bsdInfo *lbinfo, bsdFuncs *lbfuncs, psdInfo **pinfo, psdFuncs **pfuncs) { - bfuncs = lbfuncs; /* set Bacula funct pointers */ + bfuncs = lbfuncs; /* set Bacula funct pointers */ binfo = lbinfo; - printf("plugin: Loaded: size=%d version=%d\n", bfuncs->size, bfuncs->version); - + printf("example-plugin-sd: Loaded: size=%d version=%d\n", bfuncs->size, bfuncs->version); *pinfo = &pluginInfo; /* return pointer to our info */ *pfuncs = &pluginFuncs; /* return pointer to our functions */ - + printf("example-plugin-sd: Loaded\n"); return bRC_OK; } -bRC unloadPlugin() +/* + * External entry point to unload the plugin + */ +bRC DLL_IMP_EXP +unloadPlugin() { - printf("plugin: Unloaded\n"); + printf("example-plugin-sd: Unloaded\n"); return bRC_OK; } +/* + * The following entry points are accessed through the function + * pointers we supplied to Bacula. Each plugin type (dir, fd, sd) + * has its own set of entry points that the plugin must define. + */ +/* + * Create a new instance of the plugin i.e. allocate our private storage + */ static bRC newPlugin(bpContext *ctx) { int JobId = 0; - bfuncs->getBaculaValue(ctx, bVarJobId, (void *)&JobId); - printf("plugin: newPlugin JobId=%d\n", JobId); + bfuncs->getBaculaValue(ctx, bsdVarJobId, (void *)&JobId); + printf("example-plugin-sd: newPlugin JobId=%d\n", JobId); bfuncs->registerBaculaEvents(ctx, 1, 2, 0); return bRC_OK; } +/* + * Free a plugin instance, i.e. release our private storage + */ static bRC freePlugin(bpContext *ctx) { int JobId = 0; - bfuncs->getBaculaValue(ctx, bVarJobId, (void *)&JobId); - printf("plugin: freePlugin JobId=%d\n", JobId); + bfuncs->getBaculaValue(ctx, bsdVarJobId, (void *)&JobId); + printf("example-plugin-sd: freePlugin JobId=%d\n", JobId); return bRC_OK; } -static bRC getPluginValue(bpContext *ctx, pVariable var, void *value) +/* + * Return some plugin value (none defined) + */ +static bRC getPluginValue(bpContext *ctx, psdVariable var, void *value) { - printf("plugin: getPluginValue var=%d\n", var); + printf("example-plugin-sd: getPluginValue var=%d\n", var); return bRC_OK; } -static bRC setPluginValue(bpContext *ctx, pVariable var, void *value) +/* + * Set a plugin value (none defined) + */ +static bRC setPluginValue(bpContext *ctx, psdVariable var, void *value) { - printf("plugin: setPluginValue var=%d\n", var); + printf("example-plugin-sd: setPluginValue var=%d\n", var); return bRC_OK; } -static bRC handlePluginEvent(bpContext *ctx, bEvent *event, void *value) +/* + * Handle an event that was generated in Bacula + */ +static bRC handlePluginEvent(bpContext *ctx, bsdEvent *event, void *value) { char *name; switch (event->eventType) { - case bEventJobStart: - printf("plugin: HandleEvent JobStart\n"); + case bsdEventJobStart: + printf("example-plugin-sd: HandleEvent JobStart :%s:\n", (char *)value); break; - case bEventJobEnd: - printf("plugin: HandleEvent JobEnd\n"); + case bsdEventJobEnd: + printf("example-plugin-sd: HandleEvent JobEnd\n"); break; } - bfuncs->getBaculaValue(ctx, bVarJobName, (void *)&name); + bfuncs->getBaculaValue(ctx, bsdVarJobName, (void *)&name); printf("Job Name=%s\n", name); bfuncs->JobMessage(ctx, __FILE__, __LINE__, 1, 0, "JobMesssage message"); bfuncs->DebugMessage(ctx, __FILE__, __LINE__, 1, "DebugMesssage message"); @@ -147,3 +179,5 @@ static bRC handlePluginEvent(bpContext *ctx, bEvent *event, void *value) #ifdef __cplusplus } #endif + +#endif /* working */ diff --git a/bacula/src/plugins/sd/main.c b/bacula/src/plugins/sd/main.c index ffdd53d2ec..0b3fee559a 100644 --- a/bacula/src/plugins/sd/main.c +++ b/bacula/src/plugins/sd/main.c @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2007-2007 Free Software Foundation Europe e.V. + Copyright (C) 2007-2010 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. diff --git a/bacula/src/qt-console/clients/clients.cpp b/bacula/src/qt-console/clients/clients.cpp index bce43e164b..4726a1cb36 100644 --- a/bacula/src/qt-console/clients/clients.cpp +++ b/bacula/src/qt-console/clients/clients.cpp @@ -67,7 +67,7 @@ Clients::~Clients() } /* - * The main meat of the class!! The function that querries the director and + * The main meat of the class!! The function that queries the director and * creates the widgets with appropriate values. */ void Clients::populateTable() diff --git a/bacula/src/qt-console/console/console.cpp b/bacula/src/qt-console/console/console.cpp index a7a29eb394..d980fcf6ec 100644 --- a/bacula/src/qt-console/console/console.cpp +++ b/bacula/src/qt-console/console/console.cpp @@ -573,9 +573,8 @@ void Console::display_textf(const char *fmt, ...) { va_list arg_ptr; char buf[1000]; - int len; va_start(arg_ptr, fmt); - len = bvsnprintf(buf, sizeof(buf), fmt, arg_ptr); + bvsnprintf(buf, sizeof(buf), fmt, arg_ptr); va_end(arg_ptr); display_text(buf); } diff --git a/bacula/src/qt-console/job/job.cpp b/bacula/src/qt-console/job/job.cpp index bec19daa95..245ed7e72e 100644 --- a/bacula/src/qt-console/job/job.cpp +++ b/bacula/src/qt-console/job/job.cpp @@ -230,7 +230,6 @@ void Job::updateRunInfo() QStringList results; QStringList lst; bool parseit=false; - QChar equal = '='; cmd = QString(".status client=\"" + m_client + "\" running"); /* diff --git a/bacula/src/qt-console/mainwin.cpp b/bacula/src/qt-console/mainwin.cpp index 76b4b0bc13..ed9852e746 100644 --- a/bacula/src/qt-console/mainwin.cpp +++ b/bacula/src/qt-console/mainwin.cpp @@ -651,9 +651,8 @@ void MainWin::set_statusf(const char *fmt, ...) { va_list arg_ptr; char buf[1000]; - int len; va_start(arg_ptr, fmt); - len = bvsnprintf(buf, sizeof(buf), fmt, arg_ptr); + bvsnprintf(buf, sizeof(buf), fmt, arg_ptr); va_end(arg_ptr); set_status(buf); } diff --git a/bacula/src/qt-console/medialist/medialist.cpp b/bacula/src/qt-console/medialist/medialist.cpp index 09d1dff3ed..05cbda8367 100644 --- a/bacula/src/qt-console/medialist/medialist.cpp +++ b/bacula/src/qt-console/medialist/medialist.cpp @@ -74,8 +74,11 @@ MediaList::~MediaList() */ void MediaList::populateTree() { - if (m_populated) + QTreeWidgetItem *pooltreeitem = NULL; + + if (m_populated) { writeExpandedSettings(); + } m_populated = true; Freeze frz(*mp_treeWidget); /* disable updating*/ @@ -102,7 +105,6 @@ void MediaList::populateTree() settings.beginGroup("MediaListTreeExpanded"); QString query; - QTreeWidgetItem *pooltreeitem; /* Comma separated list of pools first */ bool first = true; diff --git a/bacula/src/qt-console/status/clientstat.cpp b/bacula/src/qt-console/status/clientstat.cpp index f38f7d2858..5794032aa4 100644 --- a/bacula/src/qt-console/status/clientstat.cpp +++ b/bacula/src/qt-console/status/clientstat.cpp @@ -26,7 +26,6 @@ Switzerland, email:ftf@fsfeurope.org. */ /* - * * Dirk Bartley, March 2007 */ diff --git a/bacula/src/qt-console/storage/content.cpp b/bacula/src/qt-console/storage/content.cpp index 10e615c439..e36c765324 100644 --- a/bacula/src/qt-console/storage/content.cpp +++ b/bacula/src/qt-console/storage/content.cpp @@ -179,7 +179,7 @@ void Content::statusStorageWindow() void Content::populateContent() { char buf[200]; - time_t t; + time_t tim; struct tm tm; QStringList results_all; @@ -244,16 +244,16 @@ void Content::populateContent() /* Pool */ slotitem.setTextFld(index++, fld.next()); - t = fld.next().toInt(); - if (t > 0) { + tim = fld.next().toInt(); + if (tim > 0) { /* LastW */ - localtime_r(&t, &tm); + localtime_r(&tim, &tm); strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &tm); slotitem.setTextFld(index++, QString(buf)); /* Expire */ - t = fld.next().toInt(); - localtime_r(&t, &tm); + tim = fld.next().toInt(); + localtime_r(&tim, &tm); strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &tm); slotitem.setTextFld(index++, QString(buf)); } diff --git a/bacula/src/qt-console/storage/storage.cpp b/bacula/src/qt-console/storage/storage.cpp index 8d5fd055eb..996d0eb107 100644 --- a/bacula/src/qt-console/storage/storage.cpp +++ b/bacula/src/qt-console/storage/storage.cpp @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2007-2009 Free Software Foundation Europe e.V. + Copyright (C) 2007-2010 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. @@ -27,7 +27,6 @@ */ /* - * Version $Id$ * * Storage Class * diff --git a/bacula/src/stored/Makefile.in b/bacula/src/stored/Makefile.in index bb5a9bbd46..27d68a5454 100644 --- a/bacula/src/stored/Makefile.in +++ b/bacula/src/stored/Makefile.in @@ -39,35 +39,35 @@ TAPEOBJS = btape.o block.o butil.o dev.o device.o label.o vtape.o \ lock.o ansi_label.o dvd.o ebcdic.o \ autochanger.o acquire.o mount.o record.o read_record.o \ reserve.o stored_conf.o match_bsr.o parse_bsr.o scan.o \ - spool.o vol_mgr.o wait.o + sd_plugins.o spool.o vol_mgr.o wait.o # bls BLSOBJS = bls.o block.o butil.o device.o dev.o label.o match_bsr.o vtape.o \ ansi_label.o dvd.o ebcdic.o lock.o \ autochanger.o acquire.o mount.o parse_bsr.o record.o \ read_record.o reserve.o scan.o stored_conf.o spool.o \ - vol_mgr.o wait.o + sd_plugins.o vol_mgr.o wait.o # bextract BEXTOBJS = bextract.o block.o device.o dev.o label.o record.o vtape.o \ ansi_label.o dvd.o ebcdic.o lock.o \ autochanger.o acquire.o mount.o match_bsr.o parse_bsr.o butil.o \ read_record.o reserve.o scan.o stored_conf.o spool.o \ - vol_mgr.o wait.o + sd_plugins.o vol_mgr.o wait.o # bscan SCNOBJS = bscan.o block.o device.o dev.o label.o vtape.o \ ansi_label.o dvd.o ebcdic.o lock.o \ autochanger.o acquire.o mount.o record.o match_bsr.o parse_bsr.o \ butil.o read_record.o scan.o reserve.o stored_conf.o spool.o \ - vol_mgr.o wait.o + sd_plugins.o vol_mgr.o wait.o # bcopy COPYOBJS = bcopy.o block.o device.o dev.o label.o vtape.o \ ansi_label.o dvd.o ebcdic.o lock.o \ autochanger.o acquire.o mount.o record.o match_bsr.o parse_bsr.o \ butil.o read_record.o reserve.o \ - scan.o stored_conf.o spool.o vol_mgr.o wait.o + sd_plugins.o scan.o stored_conf.o spool.o vol_mgr.o wait.o diff --git a/bacula/src/stored/acquire.c b/bacula/src/stored/acquire.c index 73f985ed06..fcd0f33b3a 100644 --- a/bacula/src/stored/acquire.c +++ b/bacula/src/stored/acquire.c @@ -1,7 +1,7 @@ /* - Bacula® - The Network Backup Solution + Bacula(R) - The Network Backup Solution - Copyright (C) 2002-2010 Free Software Foundation Europe e.V. + Copyright (C) 2002-2011 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. @@ -20,7 +20,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - Bacula® is a registered trademark of Kern Sibbald. + Bacula(R) is a registered trademark of Kern Sibbald. The licensor of Bacula is the Free Software Foundation Europe (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, Switzerland, email:ftf@fsfeurope.org. @@ -56,7 +56,6 @@ bool acquire_device_for_read(DCR *dcr) JCR *jcr = dcr->jcr; bool ok = false; bool tape_previously_mounted; - bool tape_initially_mounted; VOL_LIST *vol; bool try_autochanger = true; int i; @@ -92,6 +91,11 @@ bool acquire_device_for_read(DCR *dcr) } set_dcr_from_vol(dcr, vol); + if (generate_plugin_event(jcr, bsdEventDeviceOpen, dcr) != bRC_OK) { + Jmsg(jcr, M_FATAL, 0, _("generate_plugin_event(bsdEventDeviceOpen) Failed\n")); + goto get_out; + } + Dmsg2(100, "Want Vol=%s Slot=%d\n", vol->VolumeName, vol->Slot); /* @@ -119,6 +123,8 @@ bool acquire_device_for_read(DCR *dcr) " device=%s\n", dcr->media_type, dev->device->media_type, dev->print_name()); + generate_plugin_event(jcr, bsdEventDeviceClose, dcr); + dev->dunblock(DEV_UNLOCKED); lock_reservations(); @@ -148,11 +154,15 @@ bool acquire_device_for_read(DCR *dcr) if (stat == 1) { dev = dcr->dev; /* get new device pointer */ dev->dblock(BST_DOING_ACQUIRE); + dcr->VolumeName[0] = 0; Jmsg(jcr, M_INFO, 0, _("Media Type change. New read device %s chosen.\n"), dev->print_name()); Dmsg1(50, "Media Type change. New read device %s chosen.\n", dev->print_name()); - + if (generate_plugin_event(jcr, bsdEventDeviceOpen, dcr) != bRC_OK) { + Jmsg(jcr, M_FATAL, 0, _("generate_plugin_event(bsdEventDeviceOpen) Failed\n")); + goto get_out; + } bstrncpy(dcr->VolumeName, vol->VolumeName, sizeof(dcr->VolumeName)); dcr->setVolCatName(vol->VolumeName); bstrncpy(dcr->media_type, vol->MediaType, sizeof(dcr->media_type)); @@ -182,8 +192,7 @@ bool acquire_device_for_read(DCR *dcr) tape_previously_mounted = dev->can_read() || dev->can_append() || dev->is_labeled(); - tape_initially_mounted = tape_previously_mounted; - +// tape_initially_mounted = tape_previously_mounted; /* Volume info is always needed because of VolParts */ Dmsg1(150, "dir_get_volume_info vol=%s\n", dcr->VolumeName); @@ -317,13 +326,16 @@ default_path: dev->clear_append(); dev->set_read(); - jcr->setJobStatus(JS_Running); - dir_send_job_status(jcr); + jcr->sendJobStatus(JS_Running); Jmsg(jcr, M_INFO, 0, _("Ready to read from volume \"%s\" on device %s.\n"), dcr->VolumeName, dev->print_name()); get_out: dev->dlock(); + /* If failed and not writing plugin close device */ + if (!ok && dev->num_writers == 0) { + generate_plugin_event(jcr, bsdEventDeviceClose, dcr); + } dcr->clear_reserved(); /* * Normally we are blocked, but in at least one error case above @@ -363,6 +375,7 @@ DCR *acquire_device_for_append(DCR *dcr) Dmsg1(100, "acquire_append device is %s\n", dev->is_tape()?"tape": (dev->is_dvd()?"DVD":"disk")); + /* * With the reservation system, this should not happen */ @@ -414,6 +427,11 @@ DCR *acquire_device_for_append(DCR *dcr) unblock_device(dev); } + if (generate_plugin_event(jcr, bsdEventDeviceOpen, dcr) != bRC_OK) { + Jmsg(jcr, M_FATAL, 0, _("generate_plugin_event(bsdEventDeviceOpen) Failed\n")); + goto get_out; + } + dev->num_writers++; /* we are now a writer */ if (jcr->NumWriteVolumes == 0) { jcr->NumWriteVolumes = 1; @@ -426,6 +444,7 @@ DCR *acquire_device_for_append(DCR *dcr) ok = true; get_out: + /* Don't plugin close here, we might have multiple writers */ dcr->clear_reserved(); dev->dunlock(); V(dev->acquire_mutex); @@ -464,6 +483,7 @@ bool release_device(DCR *dcr) if (dev->can_read()) { VOLUME_CAT_INFO *vol = &dev->VolCatInfo; + generate_plugin_event(jcr, bsdEventDeviceClose, dcr); dev->clear_read(); /* clear read bit */ Dmsg2(150, "dir_update_vol_info. label=%d Vol=%s\n", dev->is_labeled(), vol->VolCatName); @@ -518,6 +538,7 @@ bool release_device(DCR *dcr) /* If no writers, close if file or !CAP_ALWAYS_OPEN */ if (dev->num_writers == 0 && (!dev->is_tape() || !dev->has_cap(CAP_ALWAYSOPEN))) { + generate_plugin_event(jcr, bsdEventDeviceClose, dcr); dvd_remove_empty_part(dcr); /* get rid of any empty spool part */ dev->close(); free_volume(dev); @@ -730,6 +751,7 @@ void free_dcr(DCR *dcr) P(dcr->m_mutex); jcr = dcr->jcr; + locked_detach_dcr_from_dev(dcr); if (dcr->block) { diff --git a/bacula/src/stored/authenticate.c b/bacula/src/stored/authenticate.c index cea939a2f9..0b7a97fa63 100644 --- a/bacula/src/stored/authenticate.c +++ b/bacula/src/stored/authenticate.c @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2000-2007 Free Software Foundation Europe e.V. + Copyright (C) 2000-2011 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. @@ -30,8 +30,6 @@ * * Kern Sibbald, October 2000 * - * Version $Id$ - * */ @@ -84,8 +82,9 @@ static int authenticate(int rcode, BSOCK *bs, JCR* jcr) director = NULL; unbash_spaces(dirname); foreach_res(director, rcode) { - if (strcmp(director->hdr.name, dirname) == 0) + if (strcmp(director->hdr.name, dirname) == 0) { break; + } } if (!director) { Dmsg2(dbglvl, "Connection from unknown Director %s at %s rejected.\n", @@ -230,10 +229,10 @@ int authenticate_filed(JCR *jcr) /* Respond to his challenge */ auth_success = cram_md5_respond(fd, jcr->sd_auth_key, &tls_remote_need, &compatible); if (!auth_success) { - Dmsg1(dbglvl, "cram-get-auth failed with %s\n", fd->who()); + Dmsg1(dbglvl, "Respond cram-get-auth failed with %s\n", fd->who()); } } else { - Dmsg1(dbglvl, "cram-auth failed with %s\n", fd->who()); + Dmsg1(dbglvl, "Challenge cram-auth failed with %s\n", fd->who()); } if (!auth_success) { diff --git a/bacula/src/stored/block.c b/bacula/src/stored/block.c index 8bde1b609d..e5ac2191a8 100644 --- a/bacula/src/stored/block.c +++ b/bacula/src/stored/block.c @@ -938,7 +938,6 @@ bool read_block_from_dev(DCR *dcr, bool check_block_numbers) { ssize_t stat; int looping; - uint32_t BlockNumber; int retry; JCR *jcr = dcr->jcr; DEVICE *dev = dcr->dev; @@ -1043,7 +1042,7 @@ reread: return false; /* return error */ } - BlockNumber = block->BlockNumber + 1; +// BlockNumber = block->BlockNumber + 1; if (!unser_block_header(jcr, dev, block)) { if (forge_on) { dev->file_addr += block->read_len; diff --git a/bacula/src/stored/btape.c b/bacula/src/stored/btape.c index 2b19e62e78..03c70b3c11 100644 --- a/bacula/src/stored/btape.c +++ b/bacula/src/stored/btape.c @@ -2650,7 +2650,10 @@ static bool quickie_cb(DCR *dcr, DEV_RECORD *rec) static bool compare_blocks(DEV_BLOCK *last_block, DEV_BLOCK *block) { char *p, *q; - uint32_t CheckSum, block_len; + union { + uint32_t CheckSum; + uint32_t block_len; + }; ser_declare; p = last_block->buf; diff --git a/bacula/src/stored/fd_cmds.c b/bacula/src/stored/fd_cmds.c index 09c9b881a0..a97f832a7a 100644 --- a/bacula/src/stored/fd_cmds.c +++ b/bacula/src/stored/fd_cmds.c @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2000-2009 Free Software Foundation Europe e.V. + Copyright (C) 2000-2011 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. @@ -118,16 +118,17 @@ void run_job(JCR *jcr) dir->fsend(Job_start, jcr->Job); jcr->start_time = time(NULL); jcr->run_time = jcr->start_time; - jcr->setJobStatus(JS_Running); - dir_send_job_status(jcr); /* update director */ + jcr->sendJobStatus(JS_Running); do_fd_commands(jcr); jcr->end_time = time(NULL); dequeue_messages(jcr); /* send any queued messages */ jcr->setJobStatus(JS_Terminated); generate_daemon_event(jcr, "JobEnd"); + generate_plugin_event(jcr, bsdEventJobEnd); dir->fsend(Job_end, jcr->Job, jcr->JobStatus, jcr->JobFiles, edit_uint64(jcr->JobBytes, ec1), jcr->JobErrors); dir->signal(BNET_EOD); /* send EOD to Director daemon */ + free_plugins(jcr); /* release instantiated plugins */ return; } diff --git a/bacula/src/stored/job.c b/bacula/src/stored/job.c index 959994a9bd..42f71230df 100644 --- a/bacula/src/stored/job.c +++ b/bacula/src/stored/job.c @@ -152,7 +152,9 @@ bool job_cmd(JCR *jcr) Dmsg2(50, ">dird jid=%u: %s", (uint32_t)jcr->JobId, dir->msg); jcr->sd_auth_key = bstrdup(auth_key); memset(auth_key, 0, sizeof(auth_key)); + new_plugins(jcr); /* instantiate the plugins */ generate_daemon_event(jcr, "JobStart"); + generate_plugin_event(jcr, bsdEventJobStart, (void *)"JobStart"); return true; } @@ -174,8 +176,7 @@ bool run_cmd(JCR *jcr) return false; } - jcr->setJobStatus(JS_WaitFD); /* wait for FD to connect */ - dir_send_job_status(jcr); + jcr->sendJobStatus(JS_WaitFD); /* wait for FD to connect */ gettimeofday(&tv, &tz); timeout.tv_nsec = tv.tv_usec * 1000; diff --git a/bacula/src/stored/mac.c b/bacula/src/stored/mac.c index d4de7c1241..0797b244e8 100644 --- a/bacula/src/stored/mac.c +++ b/bacula/src/stored/mac.c @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2006-2010 Free Software Foundation Europe e.V. + Copyright (C) 2006-2011 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. @@ -100,8 +100,7 @@ bool do_mac(JCR *jcr) Dmsg2(200, "===== After acquire pos %u:%u\n", jcr->dcr->dev->file, jcr->dcr->dev->block_num); - jcr->setJobStatus(JS_Running); - dir_send_job_status(jcr); + jcr->sendJobStatus(JS_Running); begin_data_spool(jcr->dcr); begin_attribute_spool(jcr); @@ -158,7 +157,7 @@ ok_out: } } - dir_send_job_status(jcr); /* update director */ + jcr->sendJobStatus(); /* update director */ Dmsg0(30, "Done reading.\n"); jcr->end_time = time(NULL); @@ -167,11 +166,13 @@ ok_out: jcr->setJobStatus(JS_Terminated); } generate_daemon_event(jcr, "JobEnd"); + generate_plugin_event(jcr, bsdEventJobEnd); dir->fsend(Job_end, jcr->Job, jcr->JobStatus, jcr->JobFiles, edit_uint64(jcr->JobBytes, ec1), jcr->JobErrors); Dmsg4(100, Job_end, jcr->Job, jcr->JobStatus, jcr->JobFiles, ec1); dir->signal(BNET_EOD); /* send EOD to Director daemon */ + free_plugins(jcr); /* release instantiated plugins */ return ok; } diff --git a/bacula/src/stored/pythonsd.c b/bacula/src/stored/pythonsd.c index d7cb486e13..978cc656d8 100644 --- a/bacula/src/stored/pythonsd.c +++ b/bacula/src/stored/pythonsd.c @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2005-2008 Free Software Foundation Europe e.V. + Copyright (C) 2005-2011 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. @@ -31,7 +31,7 @@ * * Kern Sibbald, January MMV * - * Version $Id$ + * SD Python interface removed 17 December 2011 (KES) * */ @@ -39,7 +39,7 @@ #include "bacula.h" #include "stored.h" -#ifdef HAVE_PYTHON +#ifdef xxxxHAVE_PYTHON #undef _POSIX_C_SOURCE #include @@ -279,4 +279,4 @@ int generate_job_event(JCR *jcr, const char *event) { return 1; } -#endif /* HAVE_PYTHON */ +#endif /* xxxxHAVE_PYTHON */ diff --git a/bacula/src/stored/read.c b/bacula/src/stored/read.c index c6f1c28edd..3f46f25884 100644 --- a/bacula/src/stored/read.c +++ b/bacula/src/stored/read.c @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2000-2010 Free Software Foundation Europe e.V. + Copyright (C) 2000-2011 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. @@ -78,8 +78,7 @@ bool do_read_data(JCR *jcr) /* Tell File daemon we will send data */ fd->fsend(OK_data); - jcr->setJobStatus(JS_Running); - dir_send_job_status(jcr); + jcr->sendJobStatus(JS_Running); ok = read_records(dcr, record_cb, mount_next_read_volume); /* Send end of data to FD */ diff --git a/bacula/src/stored/reserve.c b/bacula/src/stored/reserve.c index 8818f43278..41a4fd22b8 100644 --- a/bacula/src/stored/reserve.c +++ b/bacula/src/stored/reserve.c @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2000-2009 Free Software Foundation Europe e.V. + Copyright (C) 2000-2011 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. @@ -32,8 +32,6 @@ * * Split from job.c and acquire.c June 2005 * - * Version $Id$ - * */ #include "bacula.h" @@ -48,7 +46,7 @@ static int can_reserve_drive(DCR *dcr, RCTX &rctx); static int reserve_device(RCTX &rctx); static bool reserve_device_for_read(DCR *dcr); static bool reserve_device_for_append(DCR *dcr, RCTX &rctx); -static bool use_storage_cmd(JCR *jcr); +static bool use_device_cmd(JCR *jcr); static void queue_reserve_message(JCR *jcr); static void pop_reserve_messages(JCR *jcr); //void switch_device(DCR *dcr, DEVICE *dev); @@ -68,7 +66,7 @@ bool use_cmd(JCR *jcr) /* * Get the device, media, and pool information */ - if (!use_storage_cmd(jcr)) { + if (!use_device_cmd(jcr)) { jcr->setJobStatus(JS_ErrorTerminated); memset(jcr->sd_auth_key, 0, strlen(jcr->sd_auth_key)); return false; @@ -163,6 +161,7 @@ void DCR::unreserve_device() } } unlock_volumes(); + generate_plugin_event(jcr, bsdEventDeviceClose, this); dev->dunlock(); } @@ -177,7 +176,7 @@ void DCR::unreserve_device() * use device=bbb * */ -static bool use_storage_cmd(JCR *jcr) +static bool use_device_cmd(JCR *jcr) { POOL_MEM store_name, dev_name, media_type, pool_name, pool_type; BSOCK *dir = jcr->dir_bsock; @@ -793,10 +792,15 @@ static bool reserve_device_for_read(DCR *dcr) goto bail_out; } + /* Note: on failure this returns jcr->errmsg properly edited */ + if (generate_plugin_event(jcr, bsdEventDeviceTryOpen, dcr) != bRC_OK) { + queue_reserve_message(jcr); + goto bail_out; + } dev->clear_append(); dev->set_read(); - ok = true; dcr->set_reserved(); + ok = true; bail_out: dev->dunlock(); @@ -858,6 +862,11 @@ static bool reserve_device_for_append(DCR *dcr, RCTX &rctx) goto bail_out; } + /* Note: on failure this returns jcr->errmsg properly edited */ + if (generate_plugin_event(jcr, bsdEventDeviceTryOpen, dcr) != bRC_OK) { + queue_reserve_message(jcr); + goto bail_out; + } dcr->set_reserved(); ok = true; diff --git a/bacula/src/stored/sd_plugins.c b/bacula/src/stored/sd_plugins.c index 396d4d2ab9..02ae630b79 100644 --- a/bacula/src/stored/sd_plugins.c +++ b/bacula/src/stored/sd_plugins.c @@ -49,6 +49,7 @@ static bRC baculaDebugMsg(bpContext *ctx, const char *file, int line, int level, const char *fmt, ...); static char *baculaEditDeviceCodes(DCR *dcr, char *omsg, const char *imsg, const char *cmd); +static bool is_plugin_compatible(Plugin *plugin); /* Bacula info */ @@ -132,7 +133,10 @@ int generate_plugin_event(JCR *jcr, bsdEventType eventType, void *value) return rc; } -static void dump_sd_plugin(Plugin *plugin, FILE *fp) +/* + * Print to file the plugin info. + */ +void dump_sd_plugin(Plugin *plugin, FILE *fp) { if (!plugin) { return ; @@ -147,19 +151,89 @@ static void dump_sd_plugin(Plugin *plugin, FILE *fp) fprintf(fp, "\tdescription=%s\n", NPRTB(info->plugin_description)); } +/** + * This entry point is called internally by Bacula to ensure + * that the plugin IO calls come into this code. + */ void load_sd_plugins(const char *plugin_dir) { + Plugin *plugin; + Dmsg0(dbglvl, "Load sd plugins\n"); if (!plugin_dir) { Dmsg0(dbglvl, "No sd plugin dir!\n"); return; } bplugin_list = New(alist(10, not_owned_by_alist)); - load_plugins((void *)&binfo, (void *)&bfuncs, plugin_dir, plugin_type, NULL); + if (!load_plugins((void *)&binfo, (void *)&bfuncs, plugin_dir, plugin_type, + is_plugin_compatible)) { + /* Either none found, or some error */ + if (bplugin_list->size() == 0) { + delete bplugin_list; + bplugin_list = NULL; + Dmsg0(dbglvl, "No plugins loaded\n"); + return; + } + } + /* + * Verify that the plugin is acceptable, and print information + * about it. + */ + foreach_alist(plugin, bplugin_list) { + Jmsg(NULL, M_INFO, 0, _("Loaded plugin: %s\n"), plugin->file); + Dmsg1(dbglvl, "Loaded plugin: %s\n", plugin->file); + } + Dmsg1(dbglvl, "num plugins=%d\n", bplugin_list->size()); dbg_plugin_add_hook(dump_sd_plugin); } +/** + * Check if a plugin is compatible. Called by the load_plugin function + * to allow us to verify the plugin. + */ +static bool is_plugin_compatible(Plugin *plugin) +{ + psdInfo *info = (psdInfo *)plugin->pinfo; + Dmsg0(50, "is_plugin_compatible called\n"); + if (debug_level >= 50) { + dump_sd_plugin(plugin, stdin); + } + if (strcmp(info->plugin_magic, SD_PLUGIN_MAGIC) != 0) { + Jmsg(NULL, M_ERROR, 0, _("Plugin magic wrong. Plugin=%s wanted=%s got=%s\n"), + plugin->file, SD_PLUGIN_MAGIC, info->plugin_magic); + Dmsg3(50, "Plugin magic wrong. Plugin=%s wanted=%s got=%s\n", + plugin->file, SD_PLUGIN_MAGIC, info->plugin_magic); + + return false; + } + if (info->version != SD_PLUGIN_INTERFACE_VERSION) { + Jmsg(NULL, M_ERROR, 0, _("Plugin version incorrect. Plugin=%s wanted=%d got=%d\n"), + plugin->file, SD_PLUGIN_INTERFACE_VERSION, info->version); + Dmsg3(50, "Plugin version incorrect. Plugin=%s wanted=%d got=%d\n", + plugin->file, SD_PLUGIN_INTERFACE_VERSION, info->version); + return false; + } + if (strcmp(info->plugin_license, "Bacula AGPLv3") != 0 && + strcmp(info->plugin_license, "AGPLv3") != 0 && + strcmp(info->plugin_license, "Bacula Systems(R) SA") != 0) { + Jmsg(NULL, M_ERROR, 0, _("Plugin license incompatible. Plugin=%s license=%s\n"), + plugin->file, info->plugin_license); + Dmsg2(50, "Plugin license incompatible. Plugin=%s license=%s\n", + plugin->file, info->plugin_license); + return false; + } + if (info->size != sizeof(psdInfo)) { + Jmsg(NULL, M_ERROR, 0, + _("Plugin size incorrect. Plugin=%s wanted=%d got=%d\n"), + plugin->file, sizeof(psdInfo), info->size); + return false; + } + + return true; +} + + /* * Create a new instance of each plugin for this Job */ @@ -209,7 +283,7 @@ void free_plugins(JCR *jcr) Plugin *plugin; int i = 0; - if (!bplugin_list) { + if (!bplugin_list || !jcr->plugin_ctx_list) { return; } @@ -217,7 +291,8 @@ void free_plugins(JCR *jcr) Dmsg2(dbglvl, "Free instance sd-plugin_ctx_list=%p JobId=%d\n", jcr->plugin_ctx_list, jcr->JobId); foreach_alist(plugin, bplugin_list) { /* Free the plugin instance */ - sdplug_func(plugin)->freePlugin(&plugin_ctx_list[i++]); + sdplug_func(plugin)->freePlugin(&plugin_ctx_list[i]); + free(plugin_ctx_list[i++].bContext); /* free Bacula private context */ } free(plugin_ctx_list); jcr->plugin_ctx_list = NULL; diff --git a/bacula/src/stored/sd_plugins.h b/bacula/src/stored/sd_plugins.h index 1b7c044edb..0e41e8b4a7 100644 --- a/bacula/src/stored/sd_plugins.h +++ b/bacula/src/stored/sd_plugins.h @@ -105,9 +105,10 @@ typedef enum { typedef enum { bsdEventJobStart = 1, bsdEventJobEnd = 2, - bsdEventDeviceOpen = 3, - bsdEventDeviceTryOpen = 4, - bsdEventDeviceClose = 5 + bsdEventDeviceInit = 3, + bsdEventDeviceOpen = 4, + bsdEventDeviceTryOpen = 5, + bsdEventDeviceClose = 6 } bsdEventType; typedef struct s_bsdEvent { diff --git a/bacula/src/stored/spool.c b/bacula/src/stored/spool.c index f152ba1317..b4098b215f 100644 --- a/bacula/src/stored/spool.c +++ b/bacula/src/stored/spool.c @@ -240,8 +240,7 @@ static bool despool_data(DCR *dcr, bool commit) edit_uint64_with_commas(jcr->dcr->job_spool_size, ec1)); jcr->setJobStatus(JS_DataDespooling); } - jcr->setJobStatus(JS_DataDespooling); - dir_send_job_status(jcr); + jcr->sendJobStatus(JS_DataDespooling); dcr->despool_wait = true; dcr->spooling = false; /* @@ -378,8 +377,7 @@ static bool despool_data(DCR *dcr, bool commit) if (!commit) { dcr->dev->dunblock(); } - jcr->setJobStatus(JS_Running); - dir_send_job_status(jcr); + jcr->sendJobStatus(JS_Running); return ok; } @@ -737,8 +735,7 @@ bool commit_attribute_spool(JCR *jcr) } spool_stats.attr_size += size; V(mutex); - jcr->setJobStatus(JS_AttrDespooling); - dir_send_job_status(jcr); + jcr->sendJobStatus(JS_AttrDespooling); Jmsg(jcr, M_INFO, 0, _("Sending spooled attrs to the Director. Despooling %s bytes ...\n"), edit_uint64_with_commas(size, ec1)); diff --git a/bacula/src/stored/stored.c b/bacula/src/stored/stored.c index 4c485ad18b..05c108a9cc 100644 --- a/bacula/src/stored/stored.c +++ b/bacula/src/stored/stored.c @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2000-2010 Free Software Foundation Europe e.V. + Copyright (C) 2000-2011 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. @@ -46,19 +46,6 @@ */ #include "sd_plugins.h" -#ifdef HAVE_PYTHON - -#undef _POSIX_C_SOURCE -#include - -#include "lib/pythonlib.h" - -/* Imported Functions */ -extern PyObject *job_getattr(PyObject *self, char *attrname); -extern int job_setattr(PyObject *self, char *attrname, PyObject *value); - -#endif /* HAVE_PYTHON */ - /* Imported functions */ extern bool parse_sd_config(CONFIG *config, const char *configfile, int exit_code); @@ -133,9 +120,6 @@ int main (int argc, char *argv[]) pthread_t thid; char *uid = NULL; char *gid = NULL; -#ifdef HAVE_PYTHON - init_python_interpreter_args python_args; -#endif /* HAVE_PYTHON */ start_heap = sbrk(0); setlocale(LC_ALL, ""); @@ -284,21 +268,9 @@ int main (int argc, char *argv[]) Jmsg0(NULL, M_ABORT, 0, _("Volume Session Time is ZERO!\n")); } -#ifdef HAVE_PYTHON - python_args.progname = me->hdr.name; - python_args.scriptdir = me->scripts_directory; - python_args.modulename = "SDStartUp"; - python_args.configfile = configfile; - python_args.workingdir = me->working_directory; - python_args.job_getattr = job_getattr; - python_args.job_setattr = job_setattr; - - init_python_interpreter(&python_args); -#endif /* HAVE_PYTHON */ - - /* - * Start the device allocation thread - */ + /* + * Start the device allocation thread + */ create_volume_lists(); /* do before device_init */ if (pthread_create(&thid, NULL, device_initialization, NULL) != 0) { berrno be; @@ -541,6 +513,7 @@ void *device_initialization(void *arg) } jcr->dcr = dcr = new_dcr(jcr, NULL, dev); + generate_plugin_event(jcr, bsdEventDeviceInit, dcr); if (dev->is_autochanger()) { /* If autochanger set slot in dev sturcture */ get_autochanger_loaded_slot(dcr); diff --git a/bacula/src/stored/stored.h b/bacula/src/stored/stored.h index a15a36a73e..7d0fe50fb5 100644 --- a/bacula/src/stored/stored.h +++ b/bacula/src/stored/stored.h @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2000-2009 Free Software Foundation Europe e.V. + Copyright (C) 2000-2011 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. @@ -90,6 +90,7 @@ int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result); #endif #include "vtape.h" +#include "sd_plugins.h" /* Daemon globals from stored.c */ extern STORES *me; /* "Global" daemon resource */ diff --git a/bacula/src/stored/stored_conf.c b/bacula/src/stored/stored_conf.c index 41613d7646..f659d16b3b 100644 --- a/bacula/src/stored/stored_conf.c +++ b/bacula/src/stored/stored_conf.c @@ -226,9 +226,9 @@ static s_kw dev_types[] = { */ static void store_devtype(LEX *lc, RES_ITEM *item, int index, int pass) { - int token, i; + int i; - token = lex_get_token(lc, T_NAME); + lex_get_token(lc, T_NAME); /* Store the label pass 2 so that type is defined */ for (i=0; dev_types[i].name; i++) { if (strcasecmp(lc->str, dev_types[i].name) == 0) { diff --git a/bacula/src/stored/vtape.c b/bacula/src/stored/vtape.c index fc408a1acb..c7c9f9b3bb 100644 --- a/bacula/src/stored/vtape.c +++ b/bacula/src/stored/vtape.c @@ -567,7 +567,7 @@ int vtape::fsr(int count) ASSERT(fd >= 0); int i,nb, ret=0; - boffset_t where=0; +// boffset_t where=0; uint32_t s; Dmsg4(dbglevel, "fsr %i:%i EOF=%i c=%i\n", current_file,current_block,atEOF,count); @@ -592,7 +592,7 @@ int vtape::fsr(int count) nb = ::read(fd, &s, sizeof(uint32_t)); /* get size of next block */ if (nb == sizeof(uint32_t) && s) { current_block++; - where = lseek(fd, s, SEEK_CUR); /* seek after this block */ + lseek(fd, s, SEEK_CUR); /* seek after this block */ } else { Dmsg4(dbglevel, "read EOF %i:%i nb=%i s=%i\n", current_file, current_block, nb,s); diff --git a/bacula/src/tools/dbcheck.c b/bacula/src/tools/dbcheck.c index a61b1c70dc..55986665f8 100644 --- a/bacula/src/tools/dbcheck.c +++ b/bacula/src/tools/dbcheck.c @@ -882,6 +882,16 @@ static void eliminate_orphaned_file_records() static void eliminate_orphaned_path_records() { + db_int64_ctx lctx; + lctx.count=0; + db_sql_query(db, "SELECT 1 FROM Job WHERE HasCache=1 LIMIT 1", + db_int64_handler, &lctx); + + if (lctx.count == 1) { + printf(_("Pruning orphaned Path entries isn't possible when using BVFS.\n")); + return; + } + idx_tmp_name = NULL; /* * Check the existence of the required "one column" index diff --git a/bacula/src/tools/ing_test.c b/bacula/src/tools/ing_test.c index 076b559c88..90ab1e6324 100644 --- a/bacula/src/tools/ing_test.c +++ b/bacula/src/tools/ing_test.c @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2009-2010 Free Software Foundation Europe e.V. + Copyright (C) 2009-2011 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. @@ -36,6 +36,7 @@ * * */ +#ifdef needed #include "bacula.h" #include "cats/cats.h" #include "cats/sql_glue.h" @@ -330,3 +331,9 @@ int main (int argc, char *argv[]) return 0; } +#else /* needed */ +int main (int argc, char *argv[]) +{ + return 1; +} +#endif /* needed */ diff --git a/bacula/src/tools/testls.c b/bacula/src/tools/testls.c index b1d1f6c4bb..0e5481a531 100644 --- a/bacula/src/tools/testls.c +++ b/bacula/src/tools/testls.c @@ -84,7 +84,7 @@ int main(int argc, char *const *argv) FF_PKT *ff; char name[1000]; bool quiet = false; - int i, ch, hard_links; + int i, ch; char *inc = NULL; char *exc = NULL; FILE *fd; @@ -181,7 +181,7 @@ int main(int argc, char *const *argv) } printf(_("Files seen = %d\n"), num_files); term_include_exclude_files(ff); - hard_links = term_find_files(ff); + term_find_files(ff); free_jcr(jcr); term_last_jobs_list(); /* free jcr chain */ diff --git a/bacula/src/version.h b/bacula/src/version.h index d933c311d2..da34dd4490 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -1,16 +1,16 @@ #undef VERSION -#define VERSION "5.2.3" -#define BDATE "16 December 2011" -#define LSMDATE "16Dec11" +#define VERSION "5.2.4" +#define BDATE "02 January 2012" +#define LSMDATE "02Jan12" -#define PROG_COPYRIGHT "Copyright (C) %d-2011 Free Software Foundation Europe e.V.\n" -#define BYEAR "2011" /* year for copyright messages in progs */ +#define PROG_COPYRIGHT "Copyright (C) %d-2012 Free Software Foundation Europe e.V.\n" +#define BYEAR "2012" /* year for copyright messages in progs */ /* Bacula® - The Network Backup Solution - Copyright (C) 2000-2011 Free Software Foundation Europe e.V. + Copyright (C) 2000-2012 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. -- 2.39.5