From 27c6094b93454811a6e966558ec187f8ad5a229c Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Sun, 17 Apr 2005 21:35:16 +0000 Subject: [PATCH] - First cut of new Python implementation. - Doc updates - Correct SuSE autostart installation directory name -- supplied by a user. - Fix director crash if Name directive not supplied in a Job. - More cleanup of changing %u to %s for DB IDs. - Replace dev_can_write(dev) with dev->can_write(). git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@1933 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/kernstodo | 8 +- bacula/platforms/suse/Makefile.in | 25 +- bacula/src/cats/sql_get.c | 58 +-- bacula/src/dird/dird.c | 410 +++++++++--------- bacula/src/dird/dird_conf.c | 698 +++++++++++++++--------------- bacula/src/dird/job.c | 4 +- bacula/src/dird/newvol.c | 52 +-- bacula/src/dird/protos.h | 4 + bacula/src/dird/python.c | 111 ++++- bacula/src/dird/sql_cmds.c | 44 +- bacula/src/dird/ua_cmds.c | 370 ++++++++-------- bacula/src/dird/ua_prune.c | 89 ++-- bacula/src/dird/ua_restore.c | 654 ++++++++++++++-------------- bacula/src/dird/ua_update.c | 321 +++++++------- bacula/src/filed/backup.c | 4 +- bacula/src/filed/filed.c | 2 +- bacula/src/filed/filed.h | 2 +- bacula/src/filed/python.c | 115 ++++- bacula/src/findlib/Makefile.in | 6 +- bacula/src/findlib/bfile.c | 132 +++--- bacula/src/findlib/bfile.h | 39 +- bacula/src/jcr.h | 8 +- bacula/src/lib/Makefile.in | 34 +- bacula/src/lib/jcr.c | 203 ++++----- bacula/src/lib/protos.h | 5 +- bacula/src/lib/python.c | 205 ++++++++- bacula/src/stored/Makefile.in | 33 +- bacula/src/stored/acquire.c | 2 +- bacula/src/stored/append.c | 2 +- bacula/src/stored/bextract.c | 326 +++++++------- bacula/src/stored/bls.c | 211 ++++----- bacula/src/stored/bscan.c | 1 + bacula/src/stored/dev.c | 17 - bacula/src/stored/dev.h | 7 + bacula/src/stored/protos.h | 1 - bacula/src/stored/python.c | 75 +++- bacula/src/stored/stored.c | 2 +- bacula/src/tools/Makefile.in | 6 +- 38 files changed, 2354 insertions(+), 1932 deletions(-) diff --git a/bacula/kernstodo b/bacula/kernstodo index c64a47047a..3e97c0ef47 100644 --- a/bacula/kernstodo +++ b/bacula/kernstodo @@ -28,8 +28,9 @@ Autochangers: all Volumes from other drives. "update slots all-drives"? For 1.37: -- Add disk seeking on restore; turn off seek on tapes. - stored/match_bsr.c +- Implement some way to turn off automatic pruning in Jobs. +- Implement a way an Admin Job can prune, possibly multiple + clients -- Python script? - Implement "NewVolumeEachJob = yes|no" in Dir. - FD Python - Python script to save with Python, not save, save with Bacula. @@ -1299,3 +1300,6 @@ Block Position: 0 Client, Storage, JobStatus (error), ... - SD Python - Solicit Events +- Add disk seeking on restore; turn off seek on tapes. + stored/match_bsr.c + diff --git a/bacula/platforms/suse/Makefile.in b/bacula/platforms/suse/Makefile.in index 6a6225fb96..9e54418e7c 100644 --- a/bacula/platforms/suse/Makefile.in +++ b/bacula/platforms/suse/Makefile.in @@ -17,10 +17,10 @@ install-autostart: install-autostart-fd install-autostart-sd install-autostart-d install-autostart-fd: - @if test x$(DESTDIR) = x -a -f /etc/rc.d/init.d/bacula-fd; then \ + @if test x$(DESTDIR) = x -a -f /etc/init.d/bacula-fd; then \ /sbin/chkconfig --del bacula-fd; \ fi - @$(INSTALL_PROGRAM) -m 744 bacula-fd $(DESTDIR)/etc/rc.d/init.d/bacula-fd + @$(INSTALL_PROGRAM) -m 744 bacula-fd $(DESTDIR)/etc/init.d/bacula-fd # set symlinks for script at startup and shutdown @if test x$(DESTDIR) = x ; then \ /sbin/chkconfig --add bacula-fd; \ @@ -28,10 +28,10 @@ install-autostart-fd: install-autostart-sd: - @if test x$(DESTDIR) = x -a -f /etc/rc.d/init.d/bacula-sd; then \ + @if test x$(DESTDIR) = x -a -f /etc/init.d/bacula-sd; then \ /sbin/chkconfig --del bacula-sd; \ fi - @$(INSTALL_PROGRAM) -m 744 bacula-sd $(DESTDIR)/etc/rc.d/init.d/bacula-sd + @$(INSTALL_PROGRAM) -m 744 bacula-sd $(DESTDIR)/etc/init.d/bacula-sd # set symlinks for script at startup and shutdown @if test x$(DESTDIR) = x ; then \ /sbin/chkconfig --add bacula-sd; \ @@ -39,10 +39,10 @@ install-autostart-sd: install-autostart-dir: - @if test x$(DESTDIR) = x -a -f /etc/rc.d/init.d/bacula-dir; then \ + @if test x$(DESTDIR) = x -a -f /etc/init.d/bacula-dir; then \ /sbin/chkconfig --del bacula-dir; \ fi - @$(INSTALL_PROGRAM) -m 744 bacula-dir $(DESTDIR)/etc/rc.d/init.d/bacula-dir + @$(INSTALL_PROGRAM) -m 744 bacula-dir $(DESTDIR)/etc/init.d/bacula-dir # set symlinks for script at startup and shutdown @if test x$(DESTDIR) = x ; then \ /sbin/chkconfig --add bacula-dir; \ @@ -54,23 +54,23 @@ uninstall: uninstall-autostart uninstall-autostart: uninstall-autostart-fd uninstall-autostart-sd uninstall-autostart-dir uninstall-autostart-fd: - @if test x$(DESTDIR) = x -a -f /etc/rc.d/init.d/bacula-fd; then \ + @if test x$(DESTDIR) = x -a -f /etc/init.d/bacula-fd; then \ /sbin/chkconfig --del bacula-fd; \ fi - @rm -f $(DESTDIR)/etc/rc.d/init.d/bacula-fd + @rm -f $(DESTDIR)/etc/init.d/bacula-fd uninstall-autostart-sd: - @if test x$(DESTDIR) = x -a -f /etc/rc.d/init.d/bacula-sd; then \ + @if test x$(DESTDIR) = x -a -f /etc/init.d/bacula-sd; then \ /sbin/chkconfig --del bacula-sd; \ fi - @rm -f $(DESTDIR)/etc/rc.d/init.d/bacula-sd + @rm -f $(DESTDIR)/etc/init.d/bacula-sd uninstall-autostart-dir: - @if test x$(DESTDIR) = x -a -f /etc/rc.d/init.d/bacula-dir; then \ + @if test x$(DESTDIR) = x -a -f /etc/init.d/bacula-dir; then \ /sbin/chkconfig --del bacula-dir; \ fi - @rm -f $(DESTDIR)/etc/rc.d/init.d/bacula-dir + @rm -f $(DESTDIR)/etc/init.d/bacula-dir clean: @rm -f 1 2 3 @@ -83,4 +83,3 @@ distclean: clean devclean: clean @rm -f Makefile bacula-*.spec bacula.*.spec bacula.spec @rm -f bacula-sd bacula-fd bacula-dir - diff --git a/bacula/src/cats/sql_get.c b/bacula/src/cats/sql_get.c index 596adc6312..857927ac34 100644 --- a/bacula/src/cats/sql_get.c +++ b/bacula/src/cats/sql_get.c @@ -132,12 +132,12 @@ int db_get_file_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr, FILE_DBR *fdbr) mdb->num_rows = sql_num_rows(mdb); Dmsg1(050, "get_file_record num_rows=%d\n", (int)mdb->num_rows); if (mdb->num_rows > 1) { - Mmsg1(&mdb->errmsg, _("get_file_record want 1 got rows=%d\n"), + Mmsg1(mdb->errmsg, _("get_file_record want 1 got rows=%d\n"), mdb->num_rows); } if (mdb->num_rows >= 1) { if ((row = sql_fetch_row(mdb)) == NULL) { - Mmsg1(&mdb->errmsg, _("Error fetching row: %s\n"), sql_strerror(mdb)); + Mmsg1(mdb->errmsg, _("Error fetching row: %s\n"), sql_strerror(mdb)); } else { fdbr->FileId = (FileId_t)str_to_int64(row[0]); bstrncpy(fdbr->LStat, row[1], sizeof(fdbr->LStat)); @@ -145,7 +145,7 @@ int db_get_file_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr, FILE_DBR *fdbr) stat = 1; } } else { - Mmsg2(&mdb->errmsg, _("File record for PathId=%s FilenameId=%s not found.\n"), + Mmsg2(mdb->errmsg, _("File record for PathId=%s FilenameId=%s not found.\n"), edit_int64(fdbr->PathId, ed1), edit_int64(fdbr->FilenameId, ed2)); } @@ -176,23 +176,23 @@ static int db_get_filename_record(JCR *jcr, B_DB *mdb) char ed1[30]; mdb->num_rows = sql_num_rows(mdb); if (mdb->num_rows > 1) { - Mmsg2(&mdb->errmsg, _("More than one Filename!: %s for file: %s\n"), + Mmsg2(mdb->errmsg, _("More than one Filename!: %s for file: %s\n"), edit_uint64(mdb->num_rows, ed1), mdb->fname); Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg); } if (mdb->num_rows >= 1) { if ((row = sql_fetch_row(mdb)) == NULL) { - Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb)); + Mmsg1(mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb)); } else { FilenameId = str_to_int64(row[0]); if (FilenameId <= 0) { - Mmsg2(&mdb->errmsg, _("Get DB Filename record %s found bad record: %d\n"), + Mmsg2(mdb->errmsg, _("Get DB Filename record %s found bad record: %d\n"), mdb->cmd, FilenameId); FilenameId = 0; } } } else { - Mmsg1(&mdb->errmsg, _("Filename record: %s not found.\n"), mdb->fname); + Mmsg1(mdb->errmsg, _("Filename record: %s not found.\n"), mdb->fname); } sql_free_result(mdb); } else { @@ -226,18 +226,18 @@ static int db_get_path_record(JCR *jcr, B_DB *mdb) char ed1[30]; mdb->num_rows = sql_num_rows(mdb); if (mdb->num_rows > 1) { - Mmsg2(&mdb->errmsg, _("More than one Path!: %s for path: %s\n"), + Mmsg2(mdb->errmsg, _("More than one Path!: %s for path: %s\n"), edit_uint64(mdb->num_rows, ed1), mdb->path); Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg); } /* Even if there are multiple paths, take the first one */ if (mdb->num_rows >= 1) { if ((row = sql_fetch_row(mdb)) == NULL) { - Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb)); + Mmsg1(mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb)); } else { PathId = str_to_int64(row[0]); if (PathId <= 0) { - Mmsg2(&mdb->errmsg, _("Get DB path record %s found bad record: %s\n"), + Mmsg2(mdb->errmsg, _("Get DB path record %s found bad record: %s\n"), mdb->cmd, edit_int64(PathId, ed1)); PathId = 0; } else { @@ -245,12 +245,12 @@ static int db_get_path_record(JCR *jcr, B_DB *mdb) if (PathId != mdb->cached_path_id) { mdb->cached_path_id = PathId; mdb->cached_path_len = mdb->pnl; - pm_strcpy(&mdb->cached_path, mdb->path); + pm_strcpy(mdb->cached_path, mdb->path); } } } } else { - Mmsg1(&mdb->errmsg, _("Path record: %s not found.\n"), mdb->path); + Mmsg1(mdb->errmsg, _("Path record: %s not found.\n"), mdb->path); } sql_free_result(mdb); } else { @@ -289,7 +289,7 @@ int db_get_job_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr) return 0; /* failed */ } if ((row = sql_fetch_row(mdb)) == NULL) { - Mmsg1(&mdb->errmsg, _("No Job found for JobId %s\n"), edit_int64(jr->JobId, ed1)); + Mmsg1(mdb->errmsg, _("No Job found for JobId %s\n"), edit_int64(jr->JobId, ed1)); sql_free_result(mdb); db_unlock(mdb); return 0; /* failed */ @@ -345,13 +345,13 @@ int db_get_job_volume_names(JCR *jcr, B_DB *mdb, JobId_t JobId, POOLMEM **Volume mdb->num_rows = sql_num_rows(mdb); Dmsg1(130, "Num rows=%d\n", mdb->num_rows); if (mdb->num_rows <= 0) { - Mmsg1(&mdb->errmsg, _("No volumes found for JobId=%d\n"), JobId); + Mmsg1(mdb->errmsg, _("No volumes found for JobId=%d\n"), JobId); stat = 0; } else { stat = mdb->num_rows; for (i=0; i < stat; i++) { if ((row = sql_fetch_row(mdb)) == NULL) { - Mmsg2(&mdb->errmsg, _("Error fetching row %d: ERR=%s\n"), i, sql_strerror(mdb)); + Mmsg2(mdb->errmsg, _("Error fetching row %d: ERR=%s\n"), i, sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); stat = 0; break; @@ -400,7 +400,7 @@ int db_get_job_volume_parameters(JCR *jcr, B_DB *mdb, JobId_t JobId, VOL_PARAMS mdb->num_rows = sql_num_rows(mdb); Dmsg1(130, "Num rows=%d\n", mdb->num_rows); if (mdb->num_rows <= 0) { - Mmsg1(&mdb->errmsg, _("No volumes found for JobId=%d\n"), JobId); + Mmsg1(mdb->errmsg, _("No volumes found for JobId=%d\n"), JobId); stat = 0; } else { stat = mdb->num_rows; @@ -409,7 +409,7 @@ int db_get_job_volume_parameters(JCR *jcr, B_DB *mdb, JobId_t JobId, VOL_PARAMS } for (i=0; i < stat; i++) { if ((row = sql_fetch_row(mdb)) == NULL) { - Mmsg2(&mdb->errmsg, _("Error fetching row %d: ERR=%s\n"), i, sql_strerror(mdb)); + Mmsg2(mdb->errmsg, _("Error fetching row %d: ERR=%s\n"), i, sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); stat = 0; break; @@ -560,12 +560,12 @@ bool db_get_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pdbr) mdb->num_rows = sql_num_rows(mdb); if (mdb->num_rows > 1) { char ed1[30]; - Mmsg1(&mdb->errmsg, _("More than one Pool!: %s\n"), + Mmsg1(mdb->errmsg, _("More than one Pool!: %s\n"), edit_uint64(mdb->num_rows, ed1)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); } else if (mdb->num_rows == 1) { if ((row = sql_fetch_row(mdb)) == NULL) { - Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb)); + Mmsg1(mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); } else { pdbr->PoolId = str_to_int64(row[0]); @@ -630,12 +630,12 @@ int db_get_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cdbr) if (QUERY_DB(jcr, mdb, mdb->cmd)) { mdb->num_rows = sql_num_rows(mdb); if (mdb->num_rows > 1) { - Mmsg1(&mdb->errmsg, _("More than one Client!: %s\n"), + Mmsg1(mdb->errmsg, _("More than one Client!: %s\n"), edit_uint64(mdb->num_rows, ed1)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); } else if (mdb->num_rows == 1) { if ((row = sql_fetch_row(mdb)) == NULL) { - Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb)); + Mmsg1(mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); } else { cdbr->ClientId = str_to_int64(row[0]); @@ -676,12 +676,12 @@ int db_get_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr) /* If more than one, report error, but return first row */ if (mdb->num_rows > 1) { - Mmsg1(&mdb->errmsg, _("More than one Counter!: %d\n"), (int)(mdb->num_rows)); + Mmsg1(mdb->errmsg, _("More than one Counter!: %d\n"), (int)(mdb->num_rows)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); } if (mdb->num_rows >= 1) { if ((row = sql_fetch_row(mdb)) == NULL) { - Mmsg1(&mdb->errmsg, _("error fetching Counter row: %s\n"), sql_strerror(mdb)); + Mmsg1(mdb->errmsg, _("error fetching Counter row: %s\n"), sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); sql_free_result(mdb); db_unlock(mdb); @@ -737,12 +737,12 @@ int db_get_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr) mdb->num_rows = sql_num_rows(mdb); if (mdb->num_rows > 1) { char ed1[30]; - Mmsg1(&mdb->errmsg, _("Error got %s FileSets but expected only one!\n"), + Mmsg1(mdb->errmsg, _("Error got %s FileSets but expected only one!\n"), edit_uint64(mdb->num_rows, ed1)); sql_data_seek(mdb, mdb->num_rows-1); } if ((row = sql_fetch_row(mdb)) == NULL) { - Mmsg1(&mdb->errmsg, _("FileSet record \"%s\" not found.\n"), fsr->FileSet); + Mmsg1(mdb->errmsg, _("FileSet record \"%s\" not found.\n"), fsr->FileSet); } else { fsr->FileSetId = str_to_int64(row[0]); bstrncpy(fsr->FileSet, row[1]!=NULL?row[1]:"", sizeof(fsr->FileSet)); @@ -857,12 +857,12 @@ int db_get_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr) char ed1[50]; mdb->num_rows = sql_num_rows(mdb); if (mdb->num_rows > 1) { - Mmsg1(&mdb->errmsg, _("More than one Volume!: %s\n"), + Mmsg1(mdb->errmsg, _("More than one Volume!: %s\n"), edit_uint64(mdb->num_rows, ed1)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); } else if (mdb->num_rows == 1) { if ((row = sql_fetch_row(mdb)) == NULL) { - Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb)); + Mmsg1(mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); } else { /* return values */ @@ -902,10 +902,10 @@ int db_get_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr) } } else { if (mr->MediaId != 0) { - Mmsg1(&mdb->errmsg, _("Media record MediaId=%s not found.\n"), + Mmsg1(mdb->errmsg, _("Media record MediaId=%s not found.\n"), edit_int64(mr->MediaId, ed1)); } else { - Mmsg1(&mdb->errmsg, _("Media record for Volume \"%s\" not found.\n"), + Mmsg1(mdb->errmsg, _("Media record for Volume \"%s\" not found.\n"), mr->VolumeName); } } diff --git a/bacula/src/dird/dird.c b/bacula/src/dird/dird.c index 6d7af10e52..a6f072d8b7 100644 --- a/bacula/src/dird/dird.c +++ b/bacula/src/dird/dird.c @@ -56,12 +56,12 @@ static int background = 1; static void init_reload(void); /* Globals Exported */ -DIRRES *director; /* Director resource */ +DIRRES *director; /* Director resource */ int FDConnectTimeout; int SDConnectTimeout; /* Globals Imported */ -extern int r_first, r_last; /* first and last resources */ +extern int r_first, r_last; /* first and last resources */ extern RES_TABLE resources[]; extern RES **res_head; extern RES_ITEM job_items[]; @@ -94,7 +94,7 @@ static void usage() /********************************************************************* * - * Main Bacula Server program + * Main Bacula Server program * */ int main (int argc, char *argv[]) @@ -109,63 +109,63 @@ int main (int argc, char *argv[]) init_stack_dump(); my_name_is(argc, argv, "bacula-dir"); textdomain("bacula"); - init_msg(NULL, NULL); /* initialize message handler */ + init_msg(NULL, NULL); /* initialize message handler */ init_reload(); daemon_start_time = time(NULL); while ((ch = getopt(argc, argv, "c:d:fg:r:stu:v?")) != -1) { switch (ch) { case 'c': /* specify config file */ - if (configfile != NULL) { - free(configfile); - } - configfile = bstrdup(optarg); - break; + if (configfile != NULL) { + free(configfile); + } + configfile = bstrdup(optarg); + break; case 'd': /* set debug level */ - debug_level = atoi(optarg); - if (debug_level <= 0) { - debug_level = 1; - } + debug_level = atoi(optarg); + if (debug_level <= 0) { + debug_level = 1; + } Dmsg1(0, "Debug level = %d\n", debug_level); - break; + break; case 'f': /* run in foreground */ - background = FALSE; - break; + background = FALSE; + break; case 'g': /* set group id */ - gid = optarg; - break; + gid = optarg; + break; case 'r': /* run job */ - if (runjob != NULL) { - free(runjob); - } - if (optarg) { - runjob = bstrdup(optarg); - } - break; + if (runjob != NULL) { + free(runjob); + } + if (optarg) { + runjob = bstrdup(optarg); + } + break; case 's': /* turn off signals */ - no_signals = TRUE; - break; + no_signals = TRUE; + break; case 't': /* test config */ - test_config = TRUE; - break; + test_config = TRUE; + break; case 'u': /* set uid */ - uid = optarg; - break; + uid = optarg; + break; case 'v': /* verbose */ - verbose++; - break; + verbose++; + break; case '?': default: - usage(); + usage(); } } @@ -178,7 +178,7 @@ int main (int argc, char *argv[]) if (argc) { if (configfile != NULL) { - free(configfile); + free(configfile); } configfile = bstrdup(*argv); argc--; @@ -209,21 +209,21 @@ int main (int argc, char *argv[]) if (background) { daemon_start(); - init_stack_dump(); /* grab new pid */ + init_stack_dump(); /* grab new pid */ } /* Create pid must come after we are a daemon -- so we have our final pid */ create_pid_file(director->pid_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs)); read_state_file(director->working_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs)); - drop(uid, gid); /* reduce priveleges if requested */ + drop(uid, gid); /* reduce priveleges if requested */ signal(SIGHUP, reload_config); init_console_msg(working_directory); init_python_interpreter(director->hdr.name, director->scripts_directory ? - director->scripts_directory : "."); + director->scripts_directory : ".", "DirStartUp"); set_thread_concurrency(director->MaxConcurrentJobs * 2 + 4 /* UA */ + 4 /* sched+watchdog+jobsvr+misc */); @@ -231,9 +231,9 @@ int main (int argc, char *argv[]) Dmsg0(200, "Start UA server\n"); start_UA_server(director->DIRaddrs); - start_watchdog(); /* start network watchdog thread */ + start_watchdog(); /* start network watchdog thread */ - init_jcr_subsystem(); /* start JCR watchdogs etc. */ + init_jcr_subsystem(); /* start JCR watchdogs etc. */ init_job_server(director->MaxConcurrentJobs); @@ -242,10 +242,10 @@ int main (int argc, char *argv[]) Dmsg0(200, "wait for next job\n"); /* Main loop -- call scheduler to get next job to run */ while ((jcr = wait_for_next_job(runjob))) { - run_job(jcr); /* run job */ - free_jcr(jcr); /* release jcr */ - if (runjob) { /* command line, run a single job? */ - break; /* yes, terminate */ + run_job(jcr); /* run job */ + free_jcr(jcr); /* release jcr */ + if (runjob) { /* command line, run a single job? */ + break; /* yes, terminate */ } } @@ -257,7 +257,7 @@ static void terminate_dird(int sig) { static int already_here = FALSE; - if (already_here) { /* avoid recursive temination problems */ + if (already_here) { /* avoid recursive temination problems */ exit(1); } already_here = TRUE; @@ -277,9 +277,9 @@ static void terminate_dird(int sig) } free_config_resources(); term_ua_server(); - term_msg(); /* terminate message handler */ + term_msg(); /* terminate message handler */ stop_watchdog(); - close_memory_pool(); /* release free memory in pool */ + close_memory_pool(); /* release free memory in pool */ sm_dump(false); exit(sig); } @@ -342,8 +342,8 @@ static int find_free_reload_table_entry() int table = -1; for (int i=0; i < max_reloads; i++) { if (reload_table[i].res_table == NULL) { - table = i; - break; + table = i; + break; } } return table; @@ -374,12 +374,12 @@ void reload_config(int sig) static bool already_here = false; sigset_t set; JCR *jcr; - int njobs = 0; /* number of running jobs */ + int njobs = 0; /* number of running jobs */ int table, rtable; - bool ok; + bool ok; if (already_here) { - abort(); /* Oops, recursion -> die */ + abort(); /* Oops, recursion -> die */ } already_here = true; sigemptyset(&set); @@ -405,7 +405,7 @@ void reload_config(int sig) Dmsg0(100, "Reloaded config file\n"); if (!ok || !check_resources()) { - rtable = find_free_reload_table_entry(); /* save new, bad table */ + rtable = find_free_reload_table_entry(); /* save new, bad table */ if (rtable < 0) { Jmsg(NULL, M_ERROR, 0, _("Please correct configuration file: %s\n"), configfile); Jmsg(NULL, M_ERROR_TERM, 0, _("Out of reload table entries. Giving up.\n")); @@ -418,20 +418,20 @@ void reload_config(int sig) int num = r_last - r_first + 1; RES **res_tab = reload_table[table].res_table; for (int i=0; iJobType != JT_SYSTEM) { - reload_table[table].job_count++; - job_end_push(jcr, reload_job_end_cb, (void *)((long int)table)); - njobs++; - } - free_locked_jcr(jcr); + if (jcr->JobType != JT_SYSTEM) { + reload_table[table].job_count++; + job_end_push(jcr, reload_job_end_cb, (void *)((long int)table)); + njobs++; + } + free_locked_jcr(jcr); } } @@ -441,7 +441,7 @@ void reload_config(int sig) SDConnectTimeout = director->SDConnectTimeout; Dmsg0(0, "Director's configuration file reread.\n"); -// init_device_resources(); /* Update Device resources */ +// init_device_resources(); /* Update Device resources */ /* Now release saved resources, if no jobs using the resources */ if (njobs == 0) { @@ -479,16 +479,16 @@ static int check_resources() } else { set_working_directory(director->working_directory); if (!director->messages) { /* If message resource not specified */ - director->messages = (MSGS *)GetNextRes(R_MSGS, NULL); - if (!director->messages) { + director->messages = (MSGS *)GetNextRes(R_MSGS, NULL); + if (!director->messages) { Jmsg(NULL, M_FATAL, 0, _("No Messages resource defined in %s\n"), configfile); - OK = false; - } + OK = false; + } } if (GetNextRes(R_DIRECTOR, (RES *)director) != NULL) { Jmsg(NULL, M_FATAL, 0, _("Only one Director resource permitted in %s\n"), - configfile); - OK = false; + configfile); + OK = false; } } @@ -500,114 +500,114 @@ static int check_resources() int i; if (job->jobdefs) { - /* Handle Storage alists specifically */ - JOB *jobdefs = job->jobdefs; - if (jobdefs->storage && !job->storage) { - STORE *st; - job->storage = New(alist(10, not_owned_by_alist)); - foreach_alist(st, jobdefs->storage) { - job->storage->append(st); - } - } - - /* Transfer default items from JobDefs Resource */ - for (i=0; job_items[i].name; i++) { - char **def_svalue, **svalue; /* string value */ - int *def_ivalue, *ivalue; /* integer value */ - int64_t *def_lvalue, *lvalue; /* 64 bit values */ - uint32_t offset; + /* Handle Storage alists specifically */ + JOB *jobdefs = job->jobdefs; + if (jobdefs->storage && !job->storage) { + STORE *st; + job->storage = New(alist(10, not_owned_by_alist)); + foreach_alist(st, jobdefs->storage) { + job->storage->append(st); + } + } + + /* Transfer default items from JobDefs Resource */ + for (i=0; job_items[i].name; i++) { + char **def_svalue, **svalue; /* string value */ + int *def_ivalue, *ivalue; /* integer value */ + int64_t *def_lvalue, *lvalue; /* 64 bit values */ + uint32_t offset; Dmsg4(1400, "Job \"%s\", field \"%s\" bit=%d def=%d\n", - job->hdr.name, job_items[i].name, - bit_is_set(i, job->hdr.item_present), - bit_is_set(i, job->jobdefs->hdr.item_present)); + job->hdr.name, job_items[i].name, + bit_is_set(i, job->hdr.item_present), + bit_is_set(i, job->jobdefs->hdr.item_present)); - if (!bit_is_set(i, job->hdr.item_present) && - bit_is_set(i, job->jobdefs->hdr.item_present)) { + if (!bit_is_set(i, job->hdr.item_present) && + bit_is_set(i, job->jobdefs->hdr.item_present)) { Dmsg2(400, "Job \"%s\", field \"%s\": getting default.\n", - job->hdr.name, job_items[i].name); - offset = (char *)(job_items[i].value) - (char *)&res_all; - /* - * Handle strings and directory strings - */ - if (job_items[i].handler == store_str || - job_items[i].handler == store_dir) { - def_svalue = (char **)((char *)(job->jobdefs) + offset); + job->hdr.name, job_items[i].name); + offset = (char *)(job_items[i].value) - (char *)&res_all; + /* + * Handle strings and directory strings + */ + if (job_items[i].handler == store_str || + job_items[i].handler == store_dir) { + def_svalue = (char **)((char *)(job->jobdefs) + offset); Dmsg5(400, "Job \"%s\", field \"%s\" def_svalue=%s item %d offset=%u\n", - job->hdr.name, job_items[i].name, *def_svalue, i, offset); - svalue = (char **)((char *)job + offset); - if (*svalue) { + job->hdr.name, job_items[i].name, *def_svalue, i, offset); + svalue = (char **)((char *)job + offset); + if (*svalue) { Pmsg1(000, "Hey something is wrong. p=0x%lu\n", *svalue); - } - *svalue = bstrdup(*def_svalue); - set_bit(i, job->hdr.item_present); - /* - * Handle resources - */ - } else if (job_items[i].handler == store_res) { - def_svalue = (char **)((char *)(job->jobdefs) + offset); + } + *svalue = bstrdup(*def_svalue); + set_bit(i, job->hdr.item_present); + /* + * Handle resources + */ + } else if (job_items[i].handler == store_res) { + def_svalue = (char **)((char *)(job->jobdefs) + offset); Dmsg4(400, "Job \"%s\", field \"%s\" item %d offset=%u\n", - job->hdr.name, job_items[i].name, i, offset); - svalue = (char **)((char *)job + offset); - if (*svalue) { + job->hdr.name, job_items[i].name, i, offset); + svalue = (char **)((char *)job + offset); + if (*svalue) { Pmsg1(000, "Hey something is wrong. p=0x%lu\n", *svalue); - } - *svalue = *def_svalue; - set_bit(i, job->hdr.item_present); - /* - * Handle alist resources - */ - } else if (job_items[i].handler == store_alist_res) { - if (bit_is_set(i, job->jobdefs->hdr.item_present)) { - set_bit(i, job->hdr.item_present); - } - /* - * Handle integer fields - * Note, our store_yesno does not handle bitmaped fields - */ - } else if (job_items[i].handler == store_yesno || - job_items[i].handler == store_pint || - job_items[i].handler == store_jobtype || - job_items[i].handler == store_level || - job_items[i].handler == store_pint || - job_items[i].handler == store_replace) { - def_ivalue = (int *)((char *)(job->jobdefs) + offset); + } + *svalue = *def_svalue; + set_bit(i, job->hdr.item_present); + /* + * Handle alist resources + */ + } else if (job_items[i].handler == store_alist_res) { + if (bit_is_set(i, job->jobdefs->hdr.item_present)) { + set_bit(i, job->hdr.item_present); + } + /* + * Handle integer fields + * Note, our store_yesno does not handle bitmaped fields + */ + } else if (job_items[i].handler == store_yesno || + job_items[i].handler == store_pint || + job_items[i].handler == store_jobtype || + job_items[i].handler == store_level || + job_items[i].handler == store_pint || + job_items[i].handler == store_replace) { + def_ivalue = (int *)((char *)(job->jobdefs) + offset); Dmsg5(400, "Job \"%s\", field \"%s\" def_ivalue=%d item %d offset=%u\n", - job->hdr.name, job_items[i].name, *def_ivalue, i, offset); - ivalue = (int *)((char *)job + offset); - *ivalue = *def_ivalue; - set_bit(i, job->hdr.item_present); - /* - * Handle 64 bit integer fields - */ - } else if (job_items[i].handler == store_time || - job_items[i].handler == store_size || - job_items[i].handler == store_int64) { - def_lvalue = (int64_t *)((char *)(job->jobdefs) + offset); + job->hdr.name, job_items[i].name, *def_ivalue, i, offset); + ivalue = (int *)((char *)job + offset); + *ivalue = *def_ivalue; + set_bit(i, job->hdr.item_present); + /* + * Handle 64 bit integer fields + */ + } else if (job_items[i].handler == store_time || + job_items[i].handler == store_size || + job_items[i].handler == store_int64) { + def_lvalue = (int64_t *)((char *)(job->jobdefs) + offset); Dmsg5(400, "Job \"%s\", field \"%s\" def_lvalue=%" lld " item %d offset=%u\n", - job->hdr.name, job_items[i].name, *def_lvalue, i, offset); - lvalue = (int64_t *)((char *)job + offset); - *lvalue = *def_lvalue; - set_bit(i, job->hdr.item_present); - } - } - } + job->hdr.name, job_items[i].name, *def_lvalue, i, offset); + lvalue = (int64_t *)((char *)job + offset); + *lvalue = *def_lvalue; + set_bit(i, job->hdr.item_present); + } + } + } } /* * Ensure that all required items are present */ for (i=0; job_items[i].name; i++) { - if (job_items[i].flags & ITEM_REQUIRED) { - if (!bit_is_set(i, job->hdr.item_present)) { + if (job_items[i].flags & ITEM_REQUIRED) { + if (!bit_is_set(i, job->hdr.item_present)) { Jmsg(NULL, M_FATAL, 0, "\"%s\" directive in Job \"%s\" resource is required, but not found.\n", - job_items[i].name, job->hdr.name); - OK = false; - } - } - /* If this triggers, take a look at lib/parse_conf.h */ - if (i >= MAX_RES_ITEMS) { + job_items[i].name, job->hdr.name); + OK = false; + } + } + /* If this triggers, take a look at lib/parse_conf.h */ + if (i >= MAX_RES_ITEMS) { Emsg0(M_ERROR_TERM, 0, "Too many items in Job resource\n"); - } + } } } /* End loop over Job res */ @@ -620,77 +620,77 @@ static int check_resources() * message because the server is probably not running. */ db = db_init_database(NULL, catalog->db_name, catalog->db_user, - catalog->db_password, catalog->db_address, - catalog->db_port, catalog->db_socket, - catalog->mult_db_connections); + catalog->db_password, catalog->db_address, + catalog->db_port, catalog->db_socket, + catalog->mult_db_connections); if (!db || !db_open_database(NULL, db)) { Jmsg(NULL, M_FATAL, 0, _("Could not open database \"%s\".\n"), - catalog->db_name); - if (db) { + catalog->db_name); + if (db) { Jmsg(NULL, M_FATAL, 0, _("%s"), db_strerror(db)); - } - OK = false; - continue; + } + OK = false; + continue; } /* Loop over all pools, defining/updating them in each database */ POOL *pool; foreach_res(pool, R_POOL) { - create_pool(NULL, db, pool, POOL_OP_UPDATE); /* update request */ + create_pool(NULL, db, pool, POOL_OP_UPDATE); /* update request */ } STORE *store; foreach_res(store, R_STORAGE) { - STORAGE_DBR sr; - MEDIATYPE_DBR mr; - if (store->media_type) { - bstrncpy(mr.MediaType, store->media_type, sizeof(mr.MediaType)); - mr.ReadOnly = 0; - db_create_mediatype_record(NULL, db, &mr); - } else { - mr.MediaTypeId = 0; - } - bstrncpy(sr.Name, store->name(), sizeof(sr.Name)); - sr.AutoChanger = store->autochanger; - db_create_storage_record(NULL, db, &sr); - store->StorageId = sr.StorageId; /* set storage Id */ - if (!sr.created) { /* if not created, update it */ - db_update_storage_record(NULL, db, &sr); - } + STORAGE_DBR sr; + MEDIATYPE_DBR mr; + if (store->media_type) { + bstrncpy(mr.MediaType, store->media_type, sizeof(mr.MediaType)); + mr.ReadOnly = 0; + db_create_mediatype_record(NULL, db, &mr); + } else { + mr.MediaTypeId = 0; + } + bstrncpy(sr.Name, store->name(), sizeof(sr.Name)); + sr.AutoChanger = store->autochanger; + db_create_storage_record(NULL, db, &sr); + store->StorageId = sr.StorageId; /* set storage Id */ + if (!sr.created) { /* if not created, update it */ + db_update_storage_record(NULL, db, &sr); + } } /* Loop over all counters, defining them in each database */ /* Set default value in all counters */ COUNTER *counter; foreach_res(counter, R_COUNTER) { - /* Write to catalog? */ - if (!counter->created && counter->Catalog == catalog) { - COUNTER_DBR cr; - bstrncpy(cr.Counter, counter->hdr.name, sizeof(cr.Counter)); - cr.MinValue = counter->MinValue; - cr.MaxValue = counter->MaxValue; - cr.CurrentValue = counter->MinValue; - if (counter->WrapCounter) { - bstrncpy(cr.WrapCounter, counter->WrapCounter->hdr.name, sizeof(cr.WrapCounter)); - } else { - cr.WrapCounter[0] = 0; /* empty string */ - } - if (db_create_counter_record(NULL, db, &cr)) { - counter->CurrentValue = cr.CurrentValue; - counter->created = true; + /* Write to catalog? */ + if (!counter->created && counter->Catalog == catalog) { + COUNTER_DBR cr; + bstrncpy(cr.Counter, counter->hdr.name, sizeof(cr.Counter)); + cr.MinValue = counter->MinValue; + cr.MaxValue = counter->MaxValue; + cr.CurrentValue = counter->MinValue; + if (counter->WrapCounter) { + bstrncpy(cr.WrapCounter, counter->WrapCounter->hdr.name, sizeof(cr.WrapCounter)); + } else { + cr.WrapCounter[0] = 0; /* empty string */ + } + if (db_create_counter_record(NULL, db, &cr)) { + counter->CurrentValue = cr.CurrentValue; + counter->created = true; Dmsg2(100, "Create counter %s val=%d\n", counter->hdr.name, counter->CurrentValue); - } - } - if (!counter->created) { - counter->CurrentValue = counter->MinValue; /* default value */ - } + } + } + if (!counter->created) { + counter->CurrentValue = counter->MinValue; /* default value */ + } } db_close_database(NULL, db); } UnlockRes(); if (OK) { - close_msg(NULL); /* close temp message handler */ + close_msg(NULL); /* close temp message handler */ init_msg(NULL, director->messages); /* open daemon message handler */ } return OK; diff --git a/bacula/src/dird/dird_conf.c b/bacula/src/dird/dird_conf.c index 5830f20eaa..75867b8c58 100644 --- a/bacula/src/dird/dird_conf.c +++ b/bacula/src/dird/dird_conf.c @@ -8,14 +8,14 @@ * 1. The generic lexical scanner in lib/lex.c and lib/lex.h * * 2. The generic config scanner in lib/parse_config.c and - * lib/parse_config.h. - * These files contain the parser code, some utility - * routines, and the common store routines (name, int, - * string). + * lib/parse_config.h. + * These files contain the parser code, some utility + * routines, and the common store routines (name, int, + * string). * * 3. The daemon specific file, which contains the Resource - * definitions as well as any specific store routines - * for the resource records. + * definitions as well as any specific store routines + * for the resource records. * * Kern Sibbald, January MM * @@ -84,7 +84,7 @@ int res_all_size = sizeof(res_all); /* * Director Resource * - * name handler value code flags default_value + * name handler value code flags default_value */ static RES_ITEM dir_items[] = { {"name", store_name, ITEM(res_dir.hdr.name), 0, ITEM_REQUIRED, 0}, @@ -110,7 +110,7 @@ static RES_ITEM dir_items[] = { /* * Console Resource * - * name handler value code flags default_value + * name handler value code flags default_value */ static RES_ITEM con_items[] = { {"name", store_name, ITEM(res_con.hdr.name), 0, ITEM_REQUIRED, 0}, @@ -133,7 +133,7 @@ static RES_ITEM con_items[] = { /* * Client or File daemon resource * - * name handler value code flags default_value + * name handler value code flags default_value */ static RES_ITEM cli_items[] = { @@ -155,7 +155,7 @@ static RES_ITEM cli_items[] = { /* Storage daemon resource * - * name handler value code flags default_value + * name handler value code flags default_value */ static RES_ITEM store_items[] = { {"name", store_name, ITEM(res_store.hdr.name), 0, ITEM_REQUIRED, 0}, @@ -177,7 +177,7 @@ static RES_ITEM store_items[] = { /* * Catalog Resource Directives * - * name handler value code flags default_value + * name handler value code flags default_value */ static RES_ITEM cat_items[] = { {"name", store_name, ITEM(res_cat.hdr.name), 0, ITEM_REQUIRED, 0}, @@ -199,7 +199,7 @@ static RES_ITEM cat_items[] = { /* * Job Resource Directives * - * name handler value code flags default_value + * name handler value code flags default_value */ RES_ITEM job_items[] = { {"name", store_name, ITEM(res_job.hdr.name), 0, ITEM_REQUIRED, 0}, @@ -253,7 +253,7 @@ RES_ITEM job_items[] = { /* FileSet resource * - * name handler value code flags default_value + * name handler value code flags default_value */ static RES_ITEM fs_items[] = { {"name", store_name, ITEM(res_fs.hdr.name), 0, ITEM_REQUIRED, 0}, @@ -261,13 +261,13 @@ static RES_ITEM fs_items[] = { {"include", store_inc, NULL, 0, ITEM_NO_EQUALS, 0}, {"exclude", store_inc, NULL, 1, ITEM_NO_EQUALS, 0}, {"ignorefilesetchanges", store_yesno, ITEM(res_fs.ignore_fs_changes), 1, ITEM_DEFAULT, 0}, - {NULL, NULL, NULL, 0, 0, 0} + {NULL, NULL, NULL, 0, 0, 0} }; /* Schedule -- see run_conf.c */ /* Schedule * - * name handler value code flags default_value + * name handler value code flags default_value */ static RES_ITEM sch_items[] = { {"name", store_name, ITEM(res_sch.hdr.name), 0, ITEM_REQUIRED, 0}, @@ -278,7 +278,7 @@ static RES_ITEM sch_items[] = { /* Pool resource * - * name handler value code flags default_value + * name handler value code flags default_value */ static RES_ITEM pool_items[] = { {"name", store_name, ITEM(res_pool.hdr.name), 0, ITEM_REQUIRED, 0}, @@ -307,7 +307,7 @@ static RES_ITEM pool_items[] = { /* * Counter Resource - * name handler value code flags default_value + * name handler value code flags default_value */ static RES_ITEM counter_items[] = { {"name", store_name, ITEM(res_counter.hdr.name), 0, ITEM_REQUIRED, 0}, @@ -330,7 +330,7 @@ extern RES_ITEM msgs_items[]; * NOTE!!! keep it in the same order as the R_codes * or eliminate all resources[rindex].name * - * name items rcode res_head + * name items rcode res_head */ RES_TABLE resources[] = { {"director", dir_items, R_DIRECTOR}, @@ -346,13 +346,13 @@ RES_TABLE resources[] = { {"console", con_items, R_CONSOLE}, {"jobdefs", job_items, R_JOBDEFS}, {"device", NULL, R_DEVICE}, /* info obtained from SD */ - {NULL, NULL, 0} + {NULL, NULL, 0} }; /* Keywords (RHS) permitted in Job Level records * - * level_name level job_type + * level_name level job_type */ struct s_jl joblevels[] = { {"Full", L_FULL, JT_BACKUP}, @@ -367,19 +367,19 @@ struct s_jl joblevels[] = { {"Data", L_VERIFY_DATA, JT_VERIFY}, {" ", L_NONE, JT_ADMIN}, {" ", L_NONE, JT_RESTORE}, - {NULL, 0, 0} + {NULL, 0, 0} }; /* Keywords (RHS) permitted in Job type records * - * type_name job_type + * type_name job_type */ struct s_jt jobtypes[] = { {"backup", JT_BACKUP}, {"admin", JT_ADMIN}, {"verify", JT_VERIFY}, {"restore", JT_RESTORE}, - {NULL, 0} + {NULL, 0} }; @@ -389,7 +389,7 @@ struct s_kw ReplaceOptions[] = { {"ifnewer", REPLACE_IFNEWER}, {"ifolder", REPLACE_IFOLDER}, {"never", REPLACE_NEVER}, - {NULL, 0} + {NULL, 0} }; const char *level_to_str(int level) @@ -401,8 +401,8 @@ const char *level_to_str(int level) bsnprintf(level_no, sizeof(level_no), "%c (%d)", level, level); /* default if not found */ for (i=0; joblevels[i].level_name; i++) { if (level == joblevels[i].level) { - str = joblevels[i].level_name; - break; + str = joblevels[i].level_name; + break; } } return str; @@ -420,56 +420,56 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, const char *fm sendit(sock, "No %s resource defined\n", res_to_str(type)); return; } - if (type < 0) { /* no recursion */ + if (type < 0) { /* no recursion */ type = - type; recurse = false; } switch (type) { case R_DIRECTOR: sendit(sock, "Director: name=%s MaxJobs=%d FDtimeout=%s SDtimeout=%s\n", - reshdr->name, res->res_dir.MaxConcurrentJobs, - edit_uint64(res->res_dir.FDConnectTimeout, ed1), - edit_uint64(res->res_dir.SDConnectTimeout, ed2)); + reshdr->name, res->res_dir.MaxConcurrentJobs, + edit_uint64(res->res_dir.FDConnectTimeout, ed1), + edit_uint64(res->res_dir.SDConnectTimeout, ed2)); if (res->res_dir.query_file) { sendit(sock, " query_file=%s\n", res->res_dir.query_file); } if (res->res_dir.messages) { sendit(sock, " --> "); - dump_resource(-R_MSGS, (RES *)res->res_dir.messages, sendit, sock); + dump_resource(-R_MSGS, (RES *)res->res_dir.messages, sendit, sock); } break; case R_CONSOLE: sendit(sock, "Console: name=%s SSL=%d\n", - res->res_con.hdr.name, res->res_con.enable_ssl); + res->res_con.hdr.name, res->res_con.enable_ssl); break; case R_COUNTER: if (res->res_counter.WrapCounter) { sendit(sock, "Counter: name=%s min=%d max=%d cur=%d wrapcntr=%s\n", - res->res_counter.hdr.name, res->res_counter.MinValue, - res->res_counter.MaxValue, res->res_counter.CurrentValue, - res->res_counter.WrapCounter->hdr.name); + res->res_counter.hdr.name, res->res_counter.MinValue, + res->res_counter.MaxValue, res->res_counter.CurrentValue, + res->res_counter.WrapCounter->hdr.name); } else { sendit(sock, "Counter: name=%s min=%d max=%d\n", - res->res_counter.hdr.name, res->res_counter.MinValue, - res->res_counter.MaxValue); + res->res_counter.hdr.name, res->res_counter.MinValue, + res->res_counter.MaxValue); } if (res->res_counter.Catalog) { sendit(sock, " --> "); - dump_resource(-R_CATALOG, (RES *)res->res_counter.Catalog, sendit, sock); + dump_resource(-R_CATALOG, (RES *)res->res_counter.Catalog, sendit, sock); } break; case R_CLIENT: sendit(sock, "Client: name=%s address=%s FDport=%d MaxJobs=%u\n", - res->res_client.hdr.name, res->res_client.address, res->res_client.FDport, - res->res_client.MaxConcurrentJobs); + res->res_client.hdr.name, res->res_client.address, res->res_client.FDport, + res->res_client.MaxConcurrentJobs); sendit(sock, " JobRetention=%s FileRetention=%s AutoPrune=%d\n", - edit_utime(res->res_client.JobRetention, ed1, sizeof(ed1)), - edit_utime(res->res_client.FileRetention, ed2, sizeof(ed2)), - res->res_client.AutoPrune); + edit_utime(res->res_client.JobRetention, ed1, sizeof(ed1)), + edit_utime(res->res_client.FileRetention, ed2, sizeof(ed2)), + res->res_client.AutoPrune); if (res->res_client.catalog) { sendit(sock, " --> "); - dump_resource(-R_CATALOG, (RES *)res->res_client.catalog, sendit, sock); + dump_resource(-R_CATALOG, (RES *)res->res_client.catalog, sendit, sock); } break; case R_DEVICE: @@ -478,50 +478,50 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, const char *fm sendit(sock, "Device: name=%s ok=%d num_writers=%d max_writers=%d\n" " reserved=%d open=%d append=%d read=%d labeled=%d offline=%d autochgr=%d\n" " poolid=%s volname=%s MediaType=%s\n", - dev->hdr.name, dev->found, dev->num_writers, dev->max_writers, - dev->reserved, dev->open, dev->append, dev->read, dev->labeled, - dev->offline, dev->autochanger, - edit_uint64(dev->PoolId, ed1), - dev->VolumeName, dev->MediaType); + dev->hdr.name, dev->found, dev->num_writers, dev->max_writers, + dev->reserved, dev->open, dev->append, dev->read, dev->labeled, + dev->offline, dev->autochanger, + edit_uint64(dev->PoolId, ed1), + dev->VolumeName, dev->MediaType); break; case R_STORAGE: sendit(sock, "Storage: name=%s address=%s SDport=%d MaxJobs=%u\n" " DeviceName=%s MediaType=%s StorageId=%s\n", - res->res_store.hdr.name, res->res_store.address, res->res_store.SDport, - res->res_store.MaxConcurrentJobs, - res->res_store.dev_name(), - res->res_store.media_type, - edit_int64(res->res_store.StorageId, ed1)); + res->res_store.hdr.name, res->res_store.address, res->res_store.SDport, + res->res_store.MaxConcurrentJobs, + res->res_store.dev_name(), + res->res_store.media_type, + edit_int64(res->res_store.StorageId, ed1)); break; case R_CATALOG: sendit(sock, "Catalog: name=%s address=%s DBport=%d db_name=%s\n" " db_user=%s MutliDBConn=%d\n", - res->res_cat.hdr.name, NPRT(res->res_cat.db_address), - res->res_cat.db_port, res->res_cat.db_name, NPRT(res->res_cat.db_user), - res->res_cat.mult_db_connections); + res->res_cat.hdr.name, NPRT(res->res_cat.db_address), + res->res_cat.db_port, res->res_cat.db_name, NPRT(res->res_cat.db_user), + res->res_cat.mult_db_connections); break; case R_JOB: case R_JOBDEFS: sendit(sock, "%s: name=%s JobType=%d level=%s Priority=%d MaxJobs=%u\n", type == R_JOB ? "Job" : "JobDefs", - res->res_job.hdr.name, res->res_job.JobType, - level_to_str(res->res_job.JobLevel), res->res_job.Priority, - res->res_job.MaxConcurrentJobs); + res->res_job.hdr.name, res->res_job.JobType, + level_to_str(res->res_job.JobLevel), res->res_job.Priority, + res->res_job.MaxConcurrentJobs); sendit(sock, " Resched=%d Times=%d Interval=%s Spool=%d WritePartAfterJob=%d\n", - res->res_job.RescheduleOnError, res->res_job.RescheduleTimes, - edit_uint64_with_commas(res->res_job.RescheduleInterval, ed1), - res->res_job.spool_data, res->res_job.write_part_after_job); + res->res_job.RescheduleOnError, res->res_job.RescheduleTimes, + edit_uint64_with_commas(res->res_job.RescheduleInterval, ed1), + res->res_job.spool_data, res->res_job.write_part_after_job); if (res->res_job.client) { sendit(sock, " --> "); - dump_resource(-R_CLIENT, (RES *)res->res_job.client, sendit, sock); + dump_resource(-R_CLIENT, (RES *)res->res_job.client, sendit, sock); } if (res->res_job.fileset) { sendit(sock, " --> "); - dump_resource(-R_FILESET, (RES *)res->res_job.fileset, sendit, sock); + dump_resource(-R_FILESET, (RES *)res->res_job.fileset, sendit, sock); } if (res->res_job.schedule) { sendit(sock, " --> "); - dump_resource(-R_SCHEDULE, (RES *)res->res_job.schedule, sendit, sock); + dump_resource(-R_SCHEDULE, (RES *)res->res_job.schedule, sendit, sock); } if (res->res_job.RestoreWhere) { sendit(sock, " --> Where=%s\n", NPRT(res->res_job.RestoreWhere)); @@ -542,41 +542,41 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, const char *fm sendit(sock, " --> WriteBootstrap=%s\n", NPRT(res->res_job.WriteBootstrap)); } if (res->res_job.storage) { - STORE *store; - foreach_alist(store, res->res_job.storage) { + STORE *store; + foreach_alist(store, res->res_job.storage) { sendit(sock, " --> "); - dump_resource(-R_STORAGE, (RES *)store, sendit, sock); - } + dump_resource(-R_STORAGE, (RES *)store, sendit, sock); + } } if (res->res_job.pool) { sendit(sock, " --> "); - dump_resource(-R_POOL, (RES *)res->res_job.pool, sendit, sock); + dump_resource(-R_POOL, (RES *)res->res_job.pool, sendit, sock); } if (res->res_job.full_pool) { sendit(sock, " --> "); - dump_resource(-R_POOL, (RES *)res->res_job.full_pool, sendit, sock); + dump_resource(-R_POOL, (RES *)res->res_job.full_pool, sendit, sock); } if (res->res_job.inc_pool) { sendit(sock, " --> "); - dump_resource(-R_POOL, (RES *)res->res_job.inc_pool, sendit, sock); + dump_resource(-R_POOL, (RES *)res->res_job.inc_pool, sendit, sock); } if (res->res_job.dif_pool) { sendit(sock, " --> "); - dump_resource(-R_POOL, (RES *)res->res_job.dif_pool, sendit, sock); + dump_resource(-R_POOL, (RES *)res->res_job.dif_pool, sendit, sock); } if (res->res_job.verify_job) { sendit(sock, " --> "); - dump_resource(-type, (RES *)res->res_job.verify_job, sendit, sock); + dump_resource(-type, (RES *)res->res_job.verify_job, sendit, sock); } if (res->res_job.run_cmds) { - char *runcmd; - foreach_alist(runcmd, res->res_job.run_cmds) { + char *runcmd; + foreach_alist(runcmd, res->res_job.run_cmds) { sendit(sock, " --> Run=%s\n", runcmd); - } + } } if (res->res_job.messages) { sendit(sock, " --> "); - dump_resource(-R_MSGS, (RES *)res->res_job.messages, sendit, sock); + dump_resource(-R_MSGS, (RES *)res->res_job.messages, sendit, sock); } break; case R_FILESET: @@ -584,167 +584,167 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, const char *fm int i, j, k; sendit(sock, "FileSet: name=%s\n", res->res_fs.hdr.name); for (i=0; ires_fs.num_includes; i++) { - INCEXE *incexe = res->res_fs.include_items[i]; - for (j=0; jnum_opts; j++) { - FOPTS *fo = incexe->opts_list[j]; + INCEXE *incexe = res->res_fs.include_items[i]; + for (j=0; jnum_opts; j++) { + FOPTS *fo = incexe->opts_list[j]; sendit(sock, " O %s\n", fo->opts); - for (k=0; kregex.size(); k++) { + for (k=0; kregex.size(); k++) { sendit(sock, " R %s\n", fo->regex.get(k)); - } - for (k=0; kregexdir.size(); k++) { + } + for (k=0; kregexdir.size(); k++) { sendit(sock, " RD %s\n", fo->regexdir.get(k)); - } - for (k=0; kregexfile.size(); k++) { + } + for (k=0; kregexfile.size(); k++) { sendit(sock, " RF %s\n", fo->regexfile.get(k)); - } - for (k=0; kwild.size(); k++) { + } + for (k=0; kwild.size(); k++) { sendit(sock, " W %s\n", fo->wild.get(k)); - } - for (k=0; kwilddir.size(); k++) { + } + for (k=0; kwilddir.size(); k++) { sendit(sock, " WD %s\n", fo->wilddir.get(k)); - } - for (k=0; kwildfile.size(); k++) { + } + for (k=0; kwildfile.size(); k++) { sendit(sock, " WF %s\n", fo->wildfile.get(k)); - } - for (k=0; kbase.size(); k++) { + } + for (k=0; kbase.size(); k++) { sendit(sock, " B %s\n", fo->base.get(k)); - } - for (k=0; kfstype.size(); k++) { + } + for (k=0; kfstype.size(); k++) { sendit(sock, " X %s\n", fo->fstype.get(k)); - } - if (fo->reader) { + } + if (fo->reader) { sendit(sock, " D %s\n", fo->reader); - } - if (fo->writer) { + } + if (fo->writer) { sendit(sock, " T %s\n", fo->writer); - } + } sendit(sock, " N\n"); - } - for (j=0; jname_list.size(); j++) { + } + for (j=0; jname_list.size(); j++) { sendit(sock, " I %s\n", incexe->name_list.get(j)); - } - if (incexe->name_list.size()) { + } + if (incexe->name_list.size()) { sendit(sock, " N\n"); - } + } } for (i=0; ires_fs.num_excludes; i++) { - INCEXE *incexe = res->res_fs.exclude_items[i]; - for (j=0; jname_list.size(); j++) { + INCEXE *incexe = res->res_fs.exclude_items[i]; + for (j=0; jname_list.size(); j++) { sendit(sock, " E %s\n", incexe->name_list.get(j)); - } - if (incexe->name_list.size()) { + } + if (incexe->name_list.size()) { sendit(sock, " N\n"); - } + } } break; } case R_SCHEDULE: if (res->res_sch.run) { - int i; - RUN *run = res->res_sch.run; - char buf[1000], num[30]; + int i; + RUN *run = res->res_sch.run; + char buf[1000], num[30]; sendit(sock, "Schedule: name=%s\n", res->res_sch.hdr.name); - if (!run) { - break; - } + if (!run) { + break; + } next_run: sendit(sock, " --> Run Level=%s\n", level_to_str(run->level)); bstrncpy(buf, " hour=", sizeof(buf)); - for (i=0; i<24; i++) { - if (bit_is_set(i, run->hour)) { + for (i=0; i<24; i++) { + if (bit_is_set(i, run->hour)) { bsnprintf(num, sizeof(num), "%d ", i); - bstrncat(buf, num, sizeof(buf)); - } - } + bstrncat(buf, num, sizeof(buf)); + } + } bstrncat(buf, "\n", sizeof(buf)); - sendit(sock, buf); + sendit(sock, buf); bstrncpy(buf, " mday=", sizeof(buf)); - for (i=0; i<31; i++) { - if (bit_is_set(i, run->mday)) { + for (i=0; i<31; i++) { + if (bit_is_set(i, run->mday)) { bsnprintf(num, sizeof(num), "%d ", i); - bstrncat(buf, num, sizeof(buf)); - } - } + bstrncat(buf, num, sizeof(buf)); + } + } bstrncat(buf, "\n", sizeof(buf)); - sendit(sock, buf); + sendit(sock, buf); bstrncpy(buf, " month=", sizeof(buf)); - for (i=0; i<12; i++) { - if (bit_is_set(i, run->month)) { + for (i=0; i<12; i++) { + if (bit_is_set(i, run->month)) { bsnprintf(num, sizeof(num), "%d ", i); - bstrncat(buf, num, sizeof(buf)); - } - } + bstrncat(buf, num, sizeof(buf)); + } + } bstrncat(buf, "\n", sizeof(buf)); - sendit(sock, buf); + sendit(sock, buf); bstrncpy(buf, " wday=", sizeof(buf)); - for (i=0; i<7; i++) { - if (bit_is_set(i, run->wday)) { + for (i=0; i<7; i++) { + if (bit_is_set(i, run->wday)) { bsnprintf(num, sizeof(num), "%d ", i); - bstrncat(buf, num, sizeof(buf)); - } - } + bstrncat(buf, num, sizeof(buf)); + } + } bstrncat(buf, "\n", sizeof(buf)); - sendit(sock, buf); + sendit(sock, buf); bstrncpy(buf, " wom=", sizeof(buf)); - for (i=0; i<5; i++) { - if (bit_is_set(i, run->wom)) { + for (i=0; i<5; i++) { + if (bit_is_set(i, run->wom)) { bsnprintf(num, sizeof(num), "%d ", i); - bstrncat(buf, num, sizeof(buf)); - } - } + bstrncat(buf, num, sizeof(buf)); + } + } bstrncat(buf, "\n", sizeof(buf)); - sendit(sock, buf); + sendit(sock, buf); bstrncpy(buf, " woy=", sizeof(buf)); - for (i=0; i<54; i++) { - if (bit_is_set(i, run->woy)) { + for (i=0; i<54; i++) { + if (bit_is_set(i, run->woy)) { bsnprintf(num, sizeof(num), "%d ", i); - bstrncat(buf, num, sizeof(buf)); - } - } + bstrncat(buf, num, sizeof(buf)); + } + } bstrncat(buf, "\n", sizeof(buf)); - sendit(sock, buf); + sendit(sock, buf); sendit(sock, " mins=%d\n", run->minute); - if (run->pool) { + if (run->pool) { sendit(sock, " --> "); - dump_resource(-R_POOL, (RES *)run->pool, sendit, sock); - } - if (run->storage) { + dump_resource(-R_POOL, (RES *)run->pool, sendit, sock); + } + if (run->storage) { sendit(sock, " --> "); - dump_resource(-R_STORAGE, (RES *)run->storage, sendit, sock); - } - if (run->msgs) { + dump_resource(-R_STORAGE, (RES *)run->storage, sendit, sock); + } + if (run->msgs) { sendit(sock, " --> "); - dump_resource(-R_MSGS, (RES *)run->msgs, sendit, sock); - } - /* If another Run record is chained in, go print it */ - if (run->next) { - run = run->next; - goto next_run; - } + dump_resource(-R_MSGS, (RES *)run->msgs, sendit, sock); + } + /* If another Run record is chained in, go print it */ + if (run->next) { + run = run->next; + goto next_run; + } } else { sendit(sock, "Schedule: name=%s\n", res->res_sch.hdr.name); } break; case R_POOL: sendit(sock, "Pool: name=%s PoolType=%s\n", res->res_pool.hdr.name, - res->res_pool.pool_type); + res->res_pool.pool_type); sendit(sock, " use_cat=%d use_once=%d acpt_any=%d cat_files=%d\n", - res->res_pool.use_catalog, res->res_pool.use_volume_once, - res->res_pool.accept_any_volume, res->res_pool.catalog_files); + res->res_pool.use_catalog, res->res_pool.use_volume_once, + res->res_pool.accept_any_volume, res->res_pool.catalog_files); sendit(sock, " max_vols=%d auto_prune=%d VolRetention=%s\n", - res->res_pool.max_volumes, res->res_pool.AutoPrune, - edit_utime(res->res_pool.VolRetention, ed1, sizeof(ed1))); + res->res_pool.max_volumes, res->res_pool.AutoPrune, + edit_utime(res->res_pool.VolRetention, ed1, sizeof(ed1))); sendit(sock, " VolUse=%s recycle=%d LabelFormat=%s\n", - edit_utime(res->res_pool.VolUseDuration, ed1, sizeof(ed1)), - res->res_pool.Recycle, - NPRT(res->res_pool.label_format)); + edit_utime(res->res_pool.VolUseDuration, ed1, sizeof(ed1)), + res->res_pool.Recycle, + NPRT(res->res_pool.label_format)); sendit(sock, " CleaningPrefix=%s LabelType=%d\n", - NPRT(res->res_pool.cleaning_prefix), res->res_pool.LabelType); + NPRT(res->res_pool.cleaning_prefix), res->res_pool.LabelType); sendit(sock, " RecyleOldest=%d PurgeOldest=%d MaxVolJobs=%d MaxVolFiles=%d\n", - res->res_pool.recycle_oldest_volume, - res->res_pool.purge_oldest_volume, - res->res_pool.MaxVolJobs, res->res_pool.MaxVolFiles); + res->res_pool.recycle_oldest_volume, + res->res_pool.purge_oldest_volume, + res->res_pool.MaxVolJobs, res->res_pool.MaxVolFiles); break; case R_MSGS: sendit(sock, "Messages: name=%s\n", res->res_msgs.hdr.name); @@ -779,10 +779,10 @@ static void free_incexe(INCEXE *incexe) fopt->base.destroy(); fopt->fstype.destroy(); if (fopt->reader) { - free(fopt->reader); + free(fopt->reader); } if (fopt->writer) { - free(fopt->writer); + free(fopt->writer); } free(fopt); } @@ -802,7 +802,7 @@ static void free_incexe(INCEXE *incexe) void free_resource(RES *sres, int type) { int num; - RES *nres; /* next resource if linked */ + RES *nres; /* next resource if linked */ URES *res = (URES *)sres; if (res == NULL) @@ -820,25 +820,25 @@ void free_resource(RES *sres, int type) switch (type) { case R_DIRECTOR: if (res->res_dir.working_directory) { - free(res->res_dir.working_directory); + free(res->res_dir.working_directory); } if (res->res_dir.scripts_directory) { - free((char *)res->res_dir.scripts_directory); + free((char *)res->res_dir.scripts_directory); } if (res->res_dir.pid_directory) { - free(res->res_dir.pid_directory); + free(res->res_dir.pid_directory); } if (res->res_dir.subsys_directory) { - free(res->res_dir.subsys_directory); + free(res->res_dir.subsys_directory); } if (res->res_dir.password) { - free(res->res_dir.password); + free(res->res_dir.password); } if (res->res_dir.query_file) { - free(res->res_dir.query_file); + free(res->res_dir.query_file); } if (res->res_dir.DIRaddrs) { - free_addresses(res->res_dir.DIRaddrs); + free_addresses(res->res_dir.DIRaddrs); } break; case R_DEVICE: @@ -846,131 +846,131 @@ void free_resource(RES *sres, int type) break; case R_CONSOLE: if (res->res_con.password) { - free(res->res_con.password); + free(res->res_con.password); } for (int i=0; ires_con.ACL_lists[i]) { - delete res->res_con.ACL_lists[i]; - res->res_con.ACL_lists[i] = NULL; - } + if (res->res_con.ACL_lists[i]) { + delete res->res_con.ACL_lists[i]; + res->res_con.ACL_lists[i] = NULL; + } } break; case R_CLIENT: if (res->res_client.address) { - free(res->res_client.address); + free(res->res_client.address); } if (res->res_client.password) { - free(res->res_client.password); + free(res->res_client.password); } break; case R_STORAGE: if (res->res_store.address) { - free(res->res_store.address); + free(res->res_store.address); } if (res->res_store.password) { - free(res->res_store.password); + free(res->res_store.password); } if (res->res_store.media_type) { - free(res->res_store.media_type); + free(res->res_store.media_type); } if (res->res_store.device) { - delete res->res_store.device; + delete res->res_store.device; } break; case R_CATALOG: if (res->res_cat.db_address) { - free(res->res_cat.db_address); + free(res->res_cat.db_address); } if (res->res_cat.db_socket) { - free(res->res_cat.db_socket); + free(res->res_cat.db_socket); } if (res->res_cat.db_user) { - free(res->res_cat.db_user); + free(res->res_cat.db_user); } if (res->res_cat.db_name) { - free(res->res_cat.db_name); + free(res->res_cat.db_name); } if (res->res_cat.db_password) { - free(res->res_cat.db_password); + free(res->res_cat.db_password); } break; case R_FILESET: if ((num=res->res_fs.num_includes)) { - while (--num >= 0) { - free_incexe(res->res_fs.include_items[num]); - } - free(res->res_fs.include_items); + while (--num >= 0) { + free_incexe(res->res_fs.include_items[num]); + } + free(res->res_fs.include_items); } res->res_fs.num_includes = 0; if ((num=res->res_fs.num_excludes)) { - while (--num >= 0) { - free_incexe(res->res_fs.exclude_items[num]); - } - free(res->res_fs.exclude_items); + while (--num >= 0) { + free_incexe(res->res_fs.exclude_items[num]); + } + free(res->res_fs.exclude_items); } res->res_fs.num_excludes = 0; break; case R_POOL: if (res->res_pool.pool_type) { - free(res->res_pool.pool_type); + free(res->res_pool.pool_type); } if (res->res_pool.label_format) { - free(res->res_pool.label_format); + free(res->res_pool.label_format); } if (res->res_pool.cleaning_prefix) { - free(res->res_pool.cleaning_prefix); + free(res->res_pool.cleaning_prefix); } break; case R_SCHEDULE: if (res->res_sch.run) { - RUN *nrun, *next; - nrun = res->res_sch.run; - while (nrun) { - next = nrun->next; - free(nrun); - nrun = next; - } + RUN *nrun, *next; + nrun = res->res_sch.run; + while (nrun) { + next = nrun->next; + free(nrun); + nrun = next; + } } break; case R_JOB: case R_JOBDEFS: if (res->res_job.RestoreWhere) { - free(res->res_job.RestoreWhere); + free(res->res_job.RestoreWhere); } if (res->res_job.RestoreBootstrap) { - free(res->res_job.RestoreBootstrap); + free(res->res_job.RestoreBootstrap); } if (res->res_job.WriteBootstrap) { - free(res->res_job.WriteBootstrap); + free(res->res_job.WriteBootstrap); } if (res->res_job.RunBeforeJob) { - free(res->res_job.RunBeforeJob); + free(res->res_job.RunBeforeJob); } if (res->res_job.RunAfterJob) { - free(res->res_job.RunAfterJob); + free(res->res_job.RunAfterJob); } if (res->res_job.RunAfterFailedJob) { - free(res->res_job.RunAfterFailedJob); + free(res->res_job.RunAfterFailedJob); } if (res->res_job.ClientRunBeforeJob) { - free(res->res_job.ClientRunBeforeJob); + free(res->res_job.ClientRunBeforeJob); } if (res->res_job.ClientRunAfterJob) { - free(res->res_job.ClientRunAfterJob); + free(res->res_job.ClientRunAfterJob); } if (res->res_job.run_cmds) { - delete res->res_job.run_cmds; + delete res->res_job.run_cmds; } if (res->res_job.storage) { - delete res->res_job.storage; + delete res->res_job.storage; } break; case R_MSGS: if (res->res_msgs.mail_cmd) { - free(res->res_msgs.mail_cmd); + free(res->res_msgs.mail_cmd); } if (res->res_msgs.operator_cmd) { - free(res->res_msgs.operator_cmd); + free(res->res_msgs.operator_cmd); } free_msgs_res((MSGS *)res); /* free message resource */ res = NULL; @@ -1006,16 +1006,26 @@ void save_resource(int type, RES_ITEM *items, int pass) * Ensure that all required items are present */ for (i=0; items[i].name; i++) { - if (items[i].flags & ITEM_REQUIRED) { - if (!bit_is_set(i, res_all.res_dir.hdr.item_present)) { - Emsg2(M_ERROR_TERM, 0, "%s item is required in %s resource, but not found.\n", - items[i].name, resources[rindex]); - } - } - /* If this triggers, take a look at lib/parse_conf.h */ - if (i >= MAX_RES_ITEMS) { + if (items[i].flags & ITEM_REQUIRED) { + if (!bit_is_set(i, res_all.res_dir.hdr.item_present)) { + Emsg2(M_ERROR_TERM, 0, "%s item is required in %s resource, but not found.\n", + items[i].name, resources[rindex]); + } + } + /* If this triggers, take a look at lib/parse_conf.h */ + if (i >= MAX_RES_ITEMS) { Emsg1(M_ERROR_TERM, 0, "Too many items in %s resource\n", resources[rindex]); - } + } + } + } else if (type == R_JOB) { + /* + * Ensure that the name item is present + */ + if (items[0].flags & ITEM_REQUIRED) { + if (!bit_is_set(0, res_all.res_dir.hdr.item_present)) { + Emsg2(M_ERROR_TERM, 0, "%s item is required in %s resource, but not found.\n", + items[0].name, resources[rindex]); + } } } @@ -1034,83 +1044,83 @@ void save_resource(int type, RES_ITEM *items, int pass) case R_MSGS: case R_FILESET: case R_DEVICE: - break; + break; /* Resources containing another resource or alist */ case R_DIRECTOR: - if ((res = (URES *)GetResWithName(R_DIRECTOR, res_all.res_dir.hdr.name)) == NULL) { + if ((res = (URES *)GetResWithName(R_DIRECTOR, res_all.res_dir.hdr.name)) == NULL) { Emsg1(M_ERROR_TERM, 0, "Cannot find Director resource %s\n", res_all.res_dir.hdr.name); - } - res->res_dir.messages = res_all.res_dir.messages; - break; + } + res->res_dir.messages = res_all.res_dir.messages; + break; case R_STORAGE: - if ((res = (URES *)GetResWithName(type, res_all.res_store.hdr.name)) == NULL) { + if ((res = (URES *)GetResWithName(type, res_all.res_store.hdr.name)) == NULL) { Emsg1(M_ERROR_TERM, 0, "Cannot find Storage resource %s\n", - res_all.res_dir.hdr.name); - } - /* we must explicitly copy the device alist pointer */ - res->res_store.device = res_all.res_store.device; - break; + res_all.res_dir.hdr.name); + } + /* we must explicitly copy the device alist pointer */ + res->res_store.device = res_all.res_store.device; + break; case R_JOB: case R_JOBDEFS: - if ((res = (URES *)GetResWithName(type, res_all.res_dir.hdr.name)) == NULL) { + if ((res = (URES *)GetResWithName(type, res_all.res_dir.hdr.name)) == NULL) { Emsg1(M_ERROR_TERM, 0, "Cannot find Job resource %s\n", - res_all.res_dir.hdr.name); - } - res->res_job.messages = res_all.res_job.messages; - res->res_job.schedule = res_all.res_job.schedule; - res->res_job.client = res_all.res_job.client; - res->res_job.fileset = res_all.res_job.fileset; - res->res_job.storage = res_all.res_job.storage; - res->res_job.pool = res_all.res_job.pool; - res->res_job.full_pool = res_all.res_job.full_pool; - res->res_job.inc_pool = res_all.res_job.inc_pool; - res->res_job.dif_pool = res_all.res_job.dif_pool; - res->res_job.verify_job = res_all.res_job.verify_job; - res->res_job.jobdefs = res_all.res_job.jobdefs; - res->res_job.run_cmds = res_all.res_job.run_cmds; - break; + res_all.res_dir.hdr.name); + } + res->res_job.messages = res_all.res_job.messages; + res->res_job.schedule = res_all.res_job.schedule; + res->res_job.client = res_all.res_job.client; + res->res_job.fileset = res_all.res_job.fileset; + res->res_job.storage = res_all.res_job.storage; + res->res_job.pool = res_all.res_job.pool; + res->res_job.full_pool = res_all.res_job.full_pool; + res->res_job.inc_pool = res_all.res_job.inc_pool; + res->res_job.dif_pool = res_all.res_job.dif_pool; + res->res_job.verify_job = res_all.res_job.verify_job; + res->res_job.jobdefs = res_all.res_job.jobdefs; + res->res_job.run_cmds = res_all.res_job.run_cmds; + break; case R_COUNTER: - if ((res = (URES *)GetResWithName(R_COUNTER, res_all.res_counter.hdr.name)) == NULL) { + if ((res = (URES *)GetResWithName(R_COUNTER, res_all.res_counter.hdr.name)) == NULL) { Emsg1(M_ERROR_TERM, 0, "Cannot find Counter resource %s\n", res_all.res_counter.hdr.name); - } - res->res_counter.Catalog = res_all.res_counter.Catalog; - res->res_counter.WrapCounter = res_all.res_counter.WrapCounter; - break; + } + res->res_counter.Catalog = res_all.res_counter.Catalog; + res->res_counter.WrapCounter = res_all.res_counter.WrapCounter; + break; case R_CLIENT: - if ((res = (URES *)GetResWithName(R_CLIENT, res_all.res_client.hdr.name)) == NULL) { + if ((res = (URES *)GetResWithName(R_CLIENT, res_all.res_client.hdr.name)) == NULL) { Emsg1(M_ERROR_TERM, 0, "Cannot find Client resource %s\n", res_all.res_client.hdr.name); - } - res->res_client.catalog = res_all.res_client.catalog; - break; + } + res->res_client.catalog = res_all.res_client.catalog; + break; case R_SCHEDULE: - /* - * Schedule is a bit different in that it contains a RUN record + /* + * Schedule is a bit different in that it contains a RUN record * chain which isn't a "named" resource. This chain was linked - * in by run_conf.c during pass 2, so here we jam the pointer - * into the Schedule resource. - */ - if ((res = (URES *)GetResWithName(R_SCHEDULE, res_all.res_client.hdr.name)) == NULL) { + * in by run_conf.c during pass 2, so here we jam the pointer + * into the Schedule resource. + */ + if ((res = (URES *)GetResWithName(R_SCHEDULE, res_all.res_client.hdr.name)) == NULL) { Emsg1(M_ERROR_TERM, 0, "Cannot find Schedule resource %s\n", res_all.res_client.hdr.name); - } - res->res_sch.run = res_all.res_sch.run; - break; + } + res->res_sch.run = res_all.res_sch.run; + break; default: Emsg1(M_ERROR, 0, "Unknown resource type %d in save_resource.\n", type); - error = true; - break; + error = true; + break; } /* Note, the resource name was already saved during pass 1, * so here, we can just release it. */ if (res_all.res_dir.hdr.name) { - free(res_all.res_dir.hdr.name); - res_all.res_dir.hdr.name = NULL; + free(res_all.res_dir.hdr.name); + res_all.res_dir.hdr.name = NULL; } if (res_all.res_dir.hdr.desc) { - free(res_all.res_dir.hdr.desc); - res_all.res_dir.hdr.desc = NULL; + free(res_all.res_dir.hdr.desc); + res_all.res_dir.hdr.desc = NULL; } return; } @@ -1166,22 +1176,26 @@ void save_resource(int type, RES_ITEM *items, int pass) res = (URES *)malloc(size); memcpy(res, &res_all, size); if (!res_head[rindex]) { - res_head[rindex] = (RES *)res; /* store first entry */ + res_head[rindex] = (RES *)res; /* store first entry */ Dmsg3(900, "Inserting first %s res: %s index=%d\n", res_to_str(type), - res->res_dir.hdr.name, rindex); + res->res_dir.hdr.name, rindex); } else { - RES *next; - /* Add new res to end of chain */ - for (next=res_head[rindex]; next->next; next=next->next) { - if (strcmp(next->name, res->res_dir.hdr.name) == 0) { - Emsg2(M_ERROR_TERM, 0, + RES *next; + if (res->res_dir.hdr.name == NULL) { + Emsg1(M_ERROR_TERM, 0, "Name item is required in %s resource, but not found.\n", + resources[rindex]); + } + /* Add new res to end of chain */ + for (next=res_head[rindex]; next->next; next=next->next) { + if (strcmp(next->name, res->res_dir.hdr.name) == 0) { + Emsg2(M_ERROR_TERM, 0, _("Attempt to define second %s resource named \"%s\" is not permitted.\n"), - resources[rindex].name, res->res_dir.hdr.name); - } - } - next->next = (RES *)res; + resources[rindex].name, res->res_dir.hdr.name); + } + } + next->next = (RES *)res; Dmsg4(900, "Inserting %s res: %s index=%d pass=%d\n", res_to_str(type), - res->res_dir.hdr.name, rindex, pass); + res->res_dir.hdr.name, rindex, pass); } } } @@ -1202,29 +1216,29 @@ static void store_device(LEX *lc, RES_ITEM *item, int index, int pass) if (pass == 1) { token = lex_get_token(lc, T_NAME); if (!res_head[rindex]) { - res = (URES *)malloc(size); - memset(res, 0, size); - res->res_dev.hdr.name = bstrdup(lc->str); - res_head[rindex] = (RES *)res; /* store first entry */ + res = (URES *)malloc(size); + memset(res, 0, size); + res->res_dev.hdr.name = bstrdup(lc->str); + res_head[rindex] = (RES *)res; /* store first entry */ Dmsg3(900, "Inserting first %s res: %s index=%d\n", res_to_str(R_DEVICE), - res->res_dir.hdr.name, rindex); + res->res_dir.hdr.name, rindex); } else { - RES *next; - /* See if it is already defined */ - for (next=res_head[rindex]; next->next; next=next->next) { - if (strcmp(next->name, lc->str) == 0) { - found = true; - break; - } - } - if (!found) { - res = (URES *)malloc(size); - memset(res, 0, size); - res->res_dev.hdr.name = bstrdup(lc->str); - next->next = (RES *)res; + RES *next; + /* See if it is already defined */ + for (next=res_head[rindex]; next->next; next=next->next) { + if (strcmp(next->name, lc->str) == 0) { + found = true; + break; + } + } + if (!found) { + res = (URES *)malloc(size); + memset(res, 0, size); + res->res_dev.hdr.name = bstrdup(lc->str); + next->next = (RES *)res; Dmsg4(900, "Inserting %s res: %s index=%d pass=%d\n", res_to_str(R_DEVICE), - res->res_dir.hdr.name, rindex, pass); - } + res->res_dir.hdr.name, rindex, pass); + } } scan_to_eol(lc); @@ -1247,9 +1261,9 @@ void store_jobtype(LEX *lc, RES_ITEM *item, int index, int pass) /* 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) { - *(int *)(item->value) = jobtypes[i].job_type; - i = 0; - break; + *(int *)(item->value) = jobtypes[i].job_type; + i = 0; + break; } } if (i != 0) { @@ -1271,9 +1285,9 @@ void store_level(LEX *lc, RES_ITEM *item, int index, int pass) /* 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) { - *(int *)(item->value) = joblevels[i].level; - i = 0; - break; + *(int *)(item->value) = joblevels[i].level; + i = 0; + break; } } if (i != 0) { @@ -1291,9 +1305,9 @@ void store_replace(LEX *lc, RES_ITEM *item, int index, int pass) /* Scan Replacement options */ for (i=0; ReplaceOptions[i].name; i++) { if (strcasecmp(lc->str, ReplaceOptions[i].name) == 0) { - *(int *)(item->value) = ReplaceOptions[i].token; - i = 0; - break; + *(int *)(item->value) = ReplaceOptions[i].token; + i = 0; + break; } } if (i != 0) { @@ -1314,16 +1328,16 @@ void store_acl(LEX *lc, RES_ITEM *item, int index, int pass) for (;;) { token = lex_get_token(lc, T_NAME); if (pass == 1) { - if (((alist **)item->value)[item->code] == NULL) { - ((alist **)item->value)[item->code] = New(alist(10, owned_by_alist)); + if (((alist **)item->value)[item->code] == NULL) { + ((alist **)item->value)[item->code] = New(alist(10, owned_by_alist)); Dmsg1(900, "Defined new ACL alist at %d\n", item->code); - } - ((alist **)item->value)[item->code]->append(bstrdup(lc->str)); + } + ((alist **)item->value)[item->code]->append(bstrdup(lc->str)); Dmsg2(900, "Appended to %d %s\n", item->code, lc->str); } token = lex_get_token(lc, T_ALL); if (token == T_COMMA) { - continue; /* get another ACL */ + continue; /* get another ACL */ } break; } diff --git a/bacula/src/dird/job.c b/bacula/src/dird/job.c index 0ff1adbae5..bf9a4ea8e4 100644 --- a/bacula/src/dird/job.c +++ b/bacula/src/dird/job.c @@ -93,6 +93,8 @@ JobId_t run_job(JCR *jcr) } jcr->term_wait_inited = true; + generate_daemon_event(jcr, "StartJob"); + /* * Open database */ @@ -230,7 +232,6 @@ static void *job_thread(void *arg) } else { /* Run Job */ - generate_event(jcr, "StartJob"); if (jcr->job->RunBeforeJob) { POOLMEM *before = get_pool_memory(PM_FNAME); int status; @@ -325,7 +326,6 @@ static void *job_thread(void *arg) } } } - generate_event(jcr, "EndJob"); /* Send off any queued messages */ if (jcr->msg_queue->size() > 0) { dequeue_messages(jcr); diff --git a/bacula/src/dird/newvol.c b/bacula/src/dird/newvol.c index 7038aae3a7..1d8d04b979 100644 --- a/bacula/src/dird/newvol.c +++ b/bacula/src/dird/newvol.c @@ -8,7 +8,7 @@ * This routine runs as a thread and must be thread reentrant. * * Basic tasks done here: - * If possible create a new Media entry + * If possible create a new Media entry * * Version $Id$ */ @@ -63,35 +63,35 @@ bool newVolume(JCR *jcr, MEDIA_DBR *mr) set_pool_dbr_defaults_in_media_dbr(mr, &pr); jcr->VolumeName[0] = 0; bstrncpy(mr->MediaType, jcr->store->media_type, sizeof(mr->MediaType)); - if (generate_event(jcr, "NewVolume") == 1 && jcr->VolumeName[0] && - is_volume_name_legal(NULL, jcr->VolumeName)) { - bstrncpy(mr->VolumeName, jcr->VolumeName, sizeof(mr->VolumeName)); + if (generate_job_event(jcr, "NewVolume") == 1 && jcr->VolumeName[0] && + is_volume_name_legal(NULL, jcr->VolumeName)) { + bstrncpy(mr->VolumeName, jcr->VolumeName, sizeof(mr->VolumeName)); /* Check for special characters */ } else if (pr.LabelFormat[0] && pr.LabelFormat[0] != '*') { - if (is_volume_name_legal(NULL, pr.LabelFormat)) { - /* No special characters, so apply simple algorithm */ - if (!create_simple_name(jcr, mr, &pr)) { - goto bail_out; - } - } else { /* try full substitution */ - /* Found special characters, so try substitution */ - if (!perform_full_name_substitution(jcr, mr, &pr)) { - goto bail_out; - } - if (!is_volume_name_legal(NULL, mr->VolumeName)) { + if (is_volume_name_legal(NULL, pr.LabelFormat)) { + /* No special characters, so apply simple algorithm */ + if (!create_simple_name(jcr, mr, &pr)) { + goto bail_out; + } + } else { /* try full substitution */ + /* Found special characters, so try substitution */ + if (!perform_full_name_substitution(jcr, mr, &pr)) { + goto bail_out; + } + if (!is_volume_name_legal(NULL, mr->VolumeName)) { Jmsg(jcr, M_ERROR, 0, _("Illegal character in Volume name \"%s\"\n"), - mr->VolumeName); - goto bail_out; - } - } + mr->VolumeName); + goto bail_out; + } + } } pr.NumVols++; if (db_create_media_record(jcr, jcr->db, mr) && - db_update_pool_record(jcr, jcr->db, &pr)) { - db_unlock(jcr->db); + db_update_pool_record(jcr, jcr->db, &pr)) { + db_unlock(jcr->db); Jmsg(jcr, M_INFO, 0, _("Created new Volume \"%s\" in catalog.\n"), mr->VolumeName); Dmsg1(90, "Created new Volume=%s\n", mr->VolumeName); - return true; + return true; } else { Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db)); } @@ -116,14 +116,14 @@ static bool create_simple_name(JCR *jcr, MEDIA_DBR *mr, POOL_DBR *pr) bstrncpy(tmr.VolumeName, name, sizeof(tmr.VolumeName)); bstrncat(tmr.VolumeName, num, sizeof(tmr.VolumeName)); if (db_get_media_record(jcr, jcr->db, &tmr)) { - Jmsg(jcr, M_WARNING, 0, + Jmsg(jcr, M_WARNING, 0, _("Wanted to create Volume \"%s\", but it already exists. Trying again.\n"), - tmr.VolumeName); - continue; + tmr.VolumeName); + continue; } bstrncpy(mr->VolumeName, name, sizeof(mr->VolumeName)); bstrncat(mr->VolumeName, num, sizeof(mr->VolumeName)); - break; /* Got good name */ + break; /* Got good name */ } if (mr->VolumeName[0] == 0) { Jmsg(jcr, M_ERROR, 0, _("Too many failures. Giving up creating Volume name.\n")); diff --git a/bacula/src/dird/protos.h b/bacula/src/dird/protos.h index a6c82691f5..402d456146 100644 --- a/bacula/src/dird/protos.h +++ b/bacula/src/dird/protos.h @@ -128,6 +128,10 @@ void check_if_volume_valid_or_recyclable(JCR *jcr, MEDIA_DBR *mr, const char **r /* newvol.c */ bool newVolume(JCR *jcr, MEDIA_DBR *mr); +/* python.c */ +int generate_job_event(JCR *jcr, const char *event); + + /* restore.c */ extern bool do_restore(JCR *jcr); extern bool do_restore_init(JCR *jcr); diff --git a/bacula/src/dird/python.c b/bacula/src/dird/python.c index 353fd273fc..926c877e42 100644 --- a/bacula/src/dird/python.c +++ b/bacula/src/dird/python.c @@ -36,29 +36,41 @@ #include extern JCR *get_jcr_from_PyObject(PyObject *self); +extern PyObject *find_method(PyObject *eventsObject, PyObject *method, char *name); + +static PyObject *jcr_get(PyObject *self, PyObject *args); +static PyObject *jcr_write(PyObject *self, PyObject *args); +static PyObject *jcr_set(PyObject *self, PyObject *args, PyObject *keyw); +static PyObject *set_jcr_events(PyObject *self, PyObject *args); -PyObject *bacula_get(PyObject *self, PyObject *args); -PyObject *bacula_set(PyObject *self, PyObject *args, PyObject *keyw); PyObject *bacula_run(PyObject *self, PyObject *args); -/* Define Bacula entry points */ -PyMethodDef BaculaMethods[] = { - {"get", bacula_get, METH_VARARGS, "Get Bacula variables."}, - {"set", (PyCFunction)bacula_set, METH_VARARGS|METH_KEYWORDS, - "Set Bacula variables."}, - {"run", (PyCFunction)bacula_run, METH_VARARGS, "Run a Bacula command."}, +/* Define Job entry points */ +PyMethodDef JobMethods[] = { + {"get", jcr_get, METH_VARARGS, "Get Job variables."}, + {"set", (PyCFunction)jcr_set, METH_VARARGS|METH_KEYWORDS, + "Set Job variables."}, + {"set_events", set_jcr_events, METH_VARARGS, "Define Job events."}, + {"write", jcr_write, METH_VARARGS, "Write output."}, +// {"run", (PyCFunction)bacula_run, METH_VARARGS, "Run a Bacula command."}, {NULL, NULL, 0, NULL} /* last item */ }; +static PyObject *open_method = NULL; +static PyObject *read_method = NULL; +static PyObject *close_method = NULL; +static PyObject *volname_method = NULL; + struct s_vars { const char *name; char *fmt; }; +/* Read-only variables */ static struct s_vars vars[] = { { N_("Job"), "s"}, - { N_("Dir"), "s"}, + { N_("DirName"), "s"}, { N_("Level"), "s"}, { N_("Type"), "s"}, { N_("JobId"), "i"}, @@ -74,8 +86,8 @@ static struct s_vars vars[] = { { NULL, NULL} }; -/* Return Bacula variables */ -PyObject *bacula_get(PyObject *self, PyObject *args) +/* Return Job variables */ +static PyObject *jcr_get(PyObject *self, PyObject *args) { JCR *jcr; char *item; @@ -129,8 +141,8 @@ PyObject *bacula_get(PyObject *self, PyObject *args) return NULL; } -/* Set Bacula variables */ -PyObject *bacula_set(PyObject *self, PyObject *args, PyObject *keyw) +/* Set Job variables */ +static PyObject *jcr_set(PyObject *self, PyObject *args, PyObject *keyw) { JCR *jcr; char *msg = NULL; @@ -145,16 +157,73 @@ PyObject *bacula_set(PyObject *self, PyObject *args, PyObject *keyw) if (msg) { Jmsg(jcr, M_INFO, 0, "%s", msg); } - if (VolumeName) { - if (is_volume_name_legal(NULL, VolumeName)) { - pm_strcpy(jcr->VolumeName, VolumeName); - } else { - return Py_BuildValue("i", 0); /* invalid volume name */ - } + /* Make sure VolumeName is valid and we are in VolumeName event */ + if (VolumeName && strcmp("VolumeName", jcr->event) == 0 && + is_volume_name_legal(NULL, VolumeName)) { + pm_strcpy(jcr->VolumeName, VolumeName); + } else { + jcr->VolumeName[0] = 0; + return Py_BuildValue("i", 0); /* invalid volume name */ } return Py_BuildValue("i", 1); } +static PyObject *set_jcr_events(PyObject *self, PyObject *args) +{ + PyObject *eObject; + if (!PyArg_ParseTuple(args, "O:set_events_hook", &eObject)) { + return NULL; + } + Py_XINCREF(eObject); + open_method = find_method(eObject, open_method, "open"); + read_method = find_method(eObject, read_method, "read"); + close_method = find_method(eObject, close_method, "close"); + volname_method = find_method(eObject, volname_method, "VolumeName"); + Py_INCREF(Py_None); + return Py_None; +} + +/* Write text to job output */ +static PyObject *jcr_write(PyObject *self, PyObject *args) +{ + char *text; + if (!PyArg_ParseTuple(args, "s:write", &text)) { + return NULL; + } + if (text) { + JCR *jcr = get_jcr_from_PyObject(self); + Jmsg(jcr, M_INFO, 0, "%s", text); + } + + Py_INCREF(Py_None); + return Py_None; +} + +int generate_job_event(JCR *jcr, const char *event) +{ + PyEval_AcquireLock(); + + PyObject *result = PyObject_CallFunction(open_method, "s", "m.py"); + if (result == NULL) { + PyErr_Print(); + PyErr_Clear(); + } + Py_XDECREF(result); + + PyEval_ReleaseLock(); + return 1; +} + +#else + +/* Dummy if Python not configured */ +int generate_job_event(JCR *jcr, const char *event) +{ return 1; } + + +#endif /* HAVE_PYTHON */ + +#ifdef xxx /* Run a Bacula command */ PyObject *bacula_run(PyObject *self, PyObject *args) { @@ -174,6 +243,4 @@ PyObject *bacula_run(PyObject *self, PyObject *args) free_ua_context(ua); return Py_BuildValue("i", stat); } - - -#endif /* HAVE_PYTHON */ +#endif diff --git a/bacula/src/dird/sql_cmds.c b/bacula/src/dird/sql_cmds.c index a4913ab887..5970758fe6 100644 --- a/bacula/src/dird/sql_cmds.c +++ b/bacula/src/dird/sql_cmds.c @@ -31,7 +31,7 @@ #include "dird.h" /* For ua_cmds.c */ -const char *list_pool = "SELECT * FROM Pool WHERE PoolId=%u"; +const char *list_pool = "SELECT * FROM Pool WHERE PoolId=%s"; /* For ua_dotcmds.c */ const char *client_backups = @@ -47,20 +47,20 @@ const char *client_backups = /* ====== ua_prune.c */ -const char *cnt_File = "SELECT count(*) FROM File WHERE JobId=%u"; -const char *del_File = "DELETE FROM File WHERE JobId=%u"; -const char *upd_Purged = "UPDATE Job Set PurgedFiles=1 WHERE JobId=%u"; +const char *cnt_File = "SELECT count(*) FROM File WHERE JobId=%s"; +const char *del_File = "DELETE FROM File WHERE JobId=%s"; +const char *upd_Purged = "UPDATE Job Set PurgedFiles=1 WHERE JobId=%s"; const char *cnt_DelCand = "SELECT count(*) FROM DelCandidates"; -const char *del_Job = "DELETE FROM Job WHERE JobId=%u"; -const char *del_JobMedia = "DELETE FROM JobMedia WHERE JobId=%u"; -const char *cnt_JobMedia = "SELECT count(*) FROM JobMedia WHERE MediaId=%u"; -const char *sel_JobMedia = "SELECT JobId FROM JobMedia WHERE MediaId=%u"; +const char *del_Job = "DELETE FROM Job WHERE JobId=%s"; +const char *del_JobMedia = "DELETE FROM JobMedia WHERE JobId=%s"; +const char *cnt_JobMedia = "SELECT count(*) FROM JobMedia WHERE MediaId=%s"; +const char *sel_JobMedia = "SELECT JobId FROM JobMedia WHERE MediaId=%s"; /* Select JobIds for File deletion. */ const char *select_job = "SELECT JobId from Job " "WHERE JobTDate<%s " - "AND ClientId=%u " + "AND ClientId=%s " "AND PurgedFiles=0"; /* Delete temp tables and indexes */ @@ -105,7 +105,7 @@ const char *insert_delcand = "SELECT JobId,PurgedFiles,FileSetId,JobFiles,JobStatus FROM Job " "WHERE Type='%c' " "AND JobTDate<%s " - "AND ClientId=%u"; + "AND ClientId=%s"; /* Select Jobs from the DelCandidates table that have a * more recent backup -- i.e. are not the only backup. @@ -119,7 +119,7 @@ const char *select_backup_del = "WHERE (Job.JobTDate<%s AND ((DelCandidates.JobFiles=0) OR " "(DelCandidates.JobStatus!='T'))) OR " "(Job.JobTDate>%s " - "AND Job.ClientId=%u " + "AND Job.ClientId=%s " "AND Job.Type='B' " "AND Job.Level='F' " "AND Job.JobStatus='T' " @@ -134,7 +134,7 @@ const char *select_verify_del = "FROM Job,DelCandidates " "WHERE (Job.JobTdate<%s AND DelCandidates.JobStatus!='T') OR " "(Job.JobTDate>%s " - "AND Job.ClientId=%u " + "AND Job.ClientId=%s " "AND Job.Type='V' " "AND Job.Level='V' " "AND Job.JobStatus='T' " @@ -149,7 +149,7 @@ const char *select_restore_del = "FROM Job,DelCandidates " "WHERE (Job.JobTdate<%s AND DelCandidates.JobStatus!='T') OR " "(Job.JobTDate>%s " - "AND Job.ClientId=%u " + "AND Job.ClientId=%s " "AND Job.Type='R')"; /* Select Jobs from the DelCandidates table. @@ -160,13 +160,13 @@ const char *select_admin_del = "FROM Job,DelCandidates " "WHERE (Job.JobTdate<%s AND DelCandidates.JobStatus!='T') OR " "(Job.JobTDate>%s " - "AND Job.ClientId=%u " + "AND Job.ClientId=%s " "AND Job.Type='D')"; /* ======= ua_restore.c */ const char *uar_count_files = - "SELECT JobFiles FROM Job WHERE JobId=%u"; + "SELECT JobFiles FROM Job WHERE JobId=%s"; /* List last 20 Jobs */ const char *uar_list_jobs = @@ -206,7 +206,7 @@ const char *uar_file = const char *uar_sel_files = "SELECT Path.Path,Filename.Name,FileIndex,JobId,LStat " "FROM File,Filename,Path " - "WHERE File.JobId=%u AND Filename.FilenameId=File.FilenameId " + "WHERE File.JobId=%s AND Filename.FilenameId=File.FilenameId " "AND Path.PathId=File.PathId"; const char *uar_del_temp = "DROP TABLE temp"; @@ -252,8 +252,8 @@ const char *uar_create_temp1 = const char *uar_last_full = "INSERT INTO temp1 SELECT Job.JobId,JobTdate " - "FROM Client,Job,JobMedia,Media,FileSet WHERE Client.ClientId=%u " - "AND Job.ClientId=%u " + "FROM Client,Job,JobMedia,Media,FileSet WHERE Client.ClientId=%s " + "AND Job.ClientId=%s " "AND Job.StartTime<'%s' " "AND Level='F' AND JobStatus='T' " "AND JobMedia.JobId=Job.JobId " @@ -279,7 +279,7 @@ const char *uar_dif = "Job.VolSessionId,Job.VolSessionTime " "FROM Job,JobMedia,Media,FileSet " "WHERE Job.JobTDate>%s AND Job.StartTime<'%s' " - "AND Job.ClientId=%u " + "AND Job.ClientId=%s " "AND JobMedia.JobId=Job.JobId " "AND JobMedia.MediaId=Media.MediaId " "AND Job.Level='D' AND JobStatus='T' " @@ -295,7 +295,7 @@ const char *uar_inc = "Job.VolSessionId,Job.VolSessionTime " "FROM Job,JobMedia,Media,FileSet " "WHERE Job.JobTDate>%s AND Job.StartTime<'%s' " - "AND Job.ClientId=%u " + "AND Job.ClientId=%s " "AND JobMedia.JobId=Job.JobId " "AND JobMedia.MediaId=Media.MediaId " "AND Job.Level='I' AND JobStatus='T' " @@ -321,12 +321,12 @@ const char *uar_sel_all_temp = "SELECT * FROM temp"; const char *uar_sel_fileset = "SELECT DISTINCT FileSet.FileSet FROM Job," "Client,FileSet WHERE Job.FileSetId=FileSet.FileSetId " - "AND Job.ClientId=%u AND Client.ClientId=%u " + "AND Job.ClientId=%s AND Client.ClientId=%s " "ORDER BY FileSet.FileSet"; /* Find MediaType used by this Job */ const char *uar_mediatype = - "SELECT MediaType FROM JobMedia,Media WHERE JobMedia.JobId=%u " + "SELECT MediaType FROM JobMedia,Media WHERE JobMedia.JobId=%s" "AND JobMedia.MediaId=Media.MediaId"; /* diff --git a/bacula/src/dird/ua_cmds.c b/bacula/src/dird/ua_cmds.c index d0844f9d10..7125d4e57f 100644 --- a/bacula/src/dird/ua_cmds.c +++ b/bacula/src/dird/ua_cmds.c @@ -37,7 +37,7 @@ extern int r_first; extern int r_last; extern struct s_res resources[]; extern char my_name[]; -extern jobq_t job_queue; /* job queue */ +extern jobq_t job_queue; /* job queue */ /* Imported functions */ @@ -130,7 +130,7 @@ static struct cmdstruct commands[] = { { N_("var"), var_cmd, _("does variable expansion")}, { N_("version"), version_cmd, _("print Director version")}, { N_("wait"), wait_cmd, _("wait until no jobs are running")}, - }; + }; #define comsize (sizeof(commands)/sizeof(struct cmdstruct)) /* @@ -150,14 +150,14 @@ int do_a_command(UAContext *ua, const char *cmd) } len = strlen(ua->argk[0]); - for (i=0; iargk[0], _(commands[i].key), len) == 0) { - if (!acl_access_ok(ua, Command_ACL, ua->argk[0], len)) { - break; - } - stat = (*commands[i].func)(ua, cmd); /* go execute command */ - found = true; - break; + if (!acl_access_ok(ua, Command_ACL, ua->argk[0], len)) { + break; + } + stat = (*commands[i].func)(ua, cmd); /* go execute command */ + found = true; + break; } } if (!found) { @@ -221,9 +221,9 @@ static int add_cmd(UAContext *ua, const char *cmd) bsendmsg(ua, _("Pool already has maximum volumes = %d\n"), pr.MaxVols); for (;;) { if (!get_pint(ua, _("Enter new maximum (zero for unlimited): "))) { - return 1; - } - pr.MaxVols = ua->pint32_val; + return 1; + } + pr.MaxVols = ua->pint32_val; } } @@ -243,23 +243,23 @@ static int add_cmd(UAContext *ua, const char *cmd) char buf[100]; bsnprintf(buf, sizeof(buf), _("Enter number of Volumes to create. 0=>fixed name. Max=%d: "), max); if (!get_pint(ua, buf)) { - return 1; + return 1; } num = ua->pint32_val; if (num < 0 || num > max) { bsendmsg(ua, _("The number must be between 0 and %d\n"), max); - continue; + continue; } break; } getVolName: if (num == 0) { if (!get_cmd(ua, _("Enter Volume name: "))) { - return 1; + return 1; } } else { if (!get_cmd(ua, _("Enter base volume name: "))) { - return 1; + return 1; } } /* Don't allow | in Volume name because it is the volume separator character */ @@ -281,14 +281,14 @@ getVolName: for (;;) { if (!get_pint(ua, _("Enter the starting number: "))) { - return 1; - } - startnum = ua->pint32_val; - if (startnum < 1) { + return 1; + } + startnum = ua->pint32_val; + if (startnum < 1) { bsendmsg(ua, _("Start number must be greater than zero.\n")); - continue; - } - break; + continue; + } + break; } } else { startnum = 1; @@ -297,11 +297,11 @@ getVolName: if (store && store->autochanger) { if (!get_pint(ua, _("Enter slot (0 for none): "))) { - return 1; + return 1; } Slot = ua->pint32_val; if (!get_yesno(ua, _("InChanger? yes/no: "))) { - return 1; + return 1; } InChanger = ua->pint32_val; } @@ -315,10 +315,10 @@ getVolName: Dmsg1(200, "Create Volume %s\n", mr.VolumeName); if (!db_create_media_record(ua->jcr, ua->db, &mr)) { bsendmsg(ua, "%s", db_strerror(ua->db)); - return 1; + return 1; } if (i == startnum) { - first_id = mr.PoolId; + first_id = mr.PoolId; } } pr.NumVols += num; @@ -344,7 +344,7 @@ int automount_cmd(UAContext *ua, const char *cmd) if (ua->argc != 2) { if (!get_cmd(ua, _("Turn on or off? "))) { - return 1; + return 1; } onoff = ua->cmd; } else { @@ -372,75 +372,75 @@ static int cancel_cmd(UAContext *ua, const char *cmd) for (i=1; iargc; i++) { if (strcasecmp(ua->argk[i], _("jobid")) == 0) { - uint32_t JobId; - if (!ua->argv[i]) { - break; - } - JobId = str_to_int64(ua->argv[i]); - if (!(jcr=get_jcr_by_id(JobId))) { + uint32_t JobId; + if (!ua->argv[i]) { + break; + } + JobId = str_to_int64(ua->argv[i]); + if (!(jcr=get_jcr_by_id(JobId))) { bsendmsg(ua, _("JobId %d is not running.\n"), JobId); - return 1; - } - break; + return 1; + } + break; } else if (strcasecmp(ua->argk[i], _("job")) == 0) { - if (!ua->argv[i]) { - break; - } - if (!(jcr=get_jcr_by_partial_name(ua->argv[i]))) { + if (!ua->argv[i]) { + break; + } + if (!(jcr=get_jcr_by_partial_name(ua->argv[i]))) { bsendmsg(ua, _("Job %s is not running.\n"), ua->argv[i]); - return 1; - } - break; + return 1; + } + break; } } /* If we still do not have a jcr, - * throw up a list and ask the user to select one. + * throw up a list and ask the user to select one. */ if (!jcr) { char buf[1000]; /* Count Jobs running */ lock_jcr_chain(); foreach_jcr(jcr) { - if (jcr->JobId == 0) { /* this is us */ - free_locked_jcr(jcr); - continue; - } - free_locked_jcr(jcr); - njobs++; + if (jcr->JobId == 0) { /* this is us */ + free_locked_jcr(jcr); + continue; + } + free_locked_jcr(jcr); + njobs++; } unlock_jcr_chain(); if (njobs == 0) { bsendmsg(ua, _("No Jobs running.\n")); - return 1; + return 1; } start_prompt(ua, _("Select Job:\n")); lock_jcr_chain(); foreach_jcr(jcr) { - if (jcr->JobId == 0) { /* this is us */ - free_locked_jcr(jcr); - continue; - } + if (jcr->JobId == 0) { /* this is us */ + free_locked_jcr(jcr); + continue; + } bsnprintf(buf, sizeof(buf), "JobId=%d Job=%s", jcr->JobId, jcr->Job); - add_prompt(ua, buf); - free_locked_jcr(jcr); + add_prompt(ua, buf); + free_locked_jcr(jcr); } unlock_jcr_chain(); if (do_prompt(ua, _("Job"), _("Choose Job to cancel"), buf, sizeof(buf)) < 0) { - return 1; + return 1; } if (njobs == 1) { if (!get_yesno(ua, _("Confirm cancel (yes/no): ")) || ua->pint32_val == 0) { - return 1; - } + return 1; + } } /* NOTE! This increments the ref_count */ sscanf(buf, "JobId=%d Job=%127s", &njobs, JobName); jcr = get_jcr_by_full_name(JobName); if (!jcr) { bsendmsg(ua, _("Job %s not found.\n"), JobName); - return 1; + return 1; } } @@ -463,12 +463,12 @@ void set_pooldbr_from_poolres(POOL_DBR *pr, POOL *pool, e_pool_op op) if (op == POOL_OP_CREATE) { pr->MaxVols = pool->max_volumes; pr->NumVols = 0; - } else { /* update pool */ + } else { /* update pool */ if (pr->MaxVols != pool->max_volumes) { - pr->MaxVols = pool->max_volumes; + pr->MaxVols = pool->max_volumes; } if (pr->MaxVols != 0 && pr->MaxVols < pr->NumVols) { - pr->MaxVols = pr->NumVols; + pr->MaxVols = pr->NumVols; } } pr->LabelType = pool->LabelType; @@ -494,9 +494,9 @@ void set_pooldbr_from_poolres(POOL_DBR *pr, POOL *pool, e_pool_op op) /* * Create a pool record from a given Pool resource * Also called from backup.c - * Returns: -1 on error - * 0 record already exists - * 1 record created + * Returns: -1 on error + * 0 record already exists + * 1 record created */ int create_pool(JCR *jcr, B_DB *db, POOL *pool, e_pool_op op) @@ -510,16 +510,16 @@ int create_pool(JCR *jcr, B_DB *db, POOL *pool, e_pool_op op) if (db_get_pool_record(jcr, db, &pr)) { /* Pool Exists */ if (op == POOL_OP_UPDATE) { /* update request */ - set_pooldbr_from_poolres(&pr, pool, op); - db_update_pool_record(jcr, db, &pr); + set_pooldbr_from_poolres(&pr, pool, op); + db_update_pool_record(jcr, db, &pr); } - return 0; /* exists */ + return 0; /* exists */ } set_pooldbr_from_poolres(&pr, pool, op); if (!db_create_pool_record(jcr, db, &pr)) { - return -1; /* error */ + return -1; /* error */ } return 1; } @@ -572,7 +572,7 @@ static int python_cmd(UAContext *ua, const char *cmd) if (strcasecmp(ua->argk[1], _("restart")) == 0) { term_python_interpreter(); init_python_interpreter(director->hdr.name, director->scripts_directory ? - director->scripts_directory : "."); + director->scripts_directory : ".", "DirStartUp"); bsendmsg(ua, _("Python interpreter restarted.\n")); } else { bsendmsg(ua, _("Nothing done.\n")); @@ -608,7 +608,7 @@ static int setip_cmd(UAContext *ua, const char *cmd) sockaddr_to_ascii(&(ua->UA_sock->client_addr), buf, sizeof(buf)); client->address = bstrdup(buf); bsendmsg(ua, _("Client \"%s\" address set to %s\n"), - client->hdr.name, client->address); + client->hdr.name, client->address); get_out: UnlockRes(); return 1; @@ -691,14 +691,14 @@ static void do_all_setdebug(UAContext *ua, int level, int trace_flag) while ((store = (STORE *)GetNextRes(R_STORAGE, (RES *)store))) { found = 0; for (j=0; jaddress, store->address) == 0 && - unique_store[j]->SDport == store->SDport) { - found = 1; - break; - } + if (strcmp(unique_store[j]->address, store->address) == 0 && + unique_store[j]->SDport == store->SDport) { + found = 1; + break; + } } if (!found) { - unique_store[i++] = store; + unique_store[i++] = store; Dmsg2(140, "Stuffing: %s:%d\n", store->address, store->SDport); } } @@ -725,14 +725,14 @@ static void do_all_setdebug(UAContext *ua, int level, int trace_flag) while ((client = (CLIENT *)GetNextRes(R_CLIENT, (RES *)client))) { found = 0; for (j=0; jaddress, client->address) == 0 && - unique_client[j]->FDport == client->FDport) { - found = 1; - break; - } + if (strcmp(unique_client[j]->address, client->address) == 0 && + unique_client[j]->FDport == client->FDport) { + found = 1; + break; + } } if (!found) { - unique_client[i++] = client; + unique_client[i++] = client; Dmsg2(140, "Stuffing: %s:%d\n", client->address, client->FDport); } } @@ -768,7 +768,7 @@ static int setdebug_cmd(UAContext *ua, const char *cmd) } if (level < 0) { if (!get_pint(ua, _("Enter new debug level: "))) { - return 1; + return 1; } level = ua->pint32_val; } @@ -778,55 +778,55 @@ static int setdebug_cmd(UAContext *ua, const char *cmd) if (i >= 0) { trace_flag = atoi(ua->argv[i]); if (trace_flag > 0) { - trace_flag = 1; + trace_flag = 1; } } /* General debug? */ for (i=1; iargc; i++) { if (strcasecmp(ua->argk[i], _("all")) == 0) { - do_all_setdebug(ua, level, trace_flag); - return 1; + do_all_setdebug(ua, level, trace_flag); + return 1; } if (strcasecmp(ua->argk[i], _("dir")) == 0 || strcasecmp(ua->argk[i], _("director")) == 0) { - debug_level = level; - set_trace(trace_flag); - return 1; + debug_level = level; + set_trace(trace_flag); + return 1; } if (strcasecmp(ua->argk[i], _("client")) == 0 || strcasecmp(ua->argk[i], _("fd")) == 0) { - client = NULL; - if (ua->argv[i]) { - client = (CLIENT *)GetResWithName(R_CLIENT, ua->argv[i]); - if (client) { - do_client_setdebug(ua, client, level, trace_flag); - return 1; - } - } - client = select_client_resource(ua); - if (client) { - do_client_setdebug(ua, client, level, trace_flag); - return 1; - } + client = NULL; + if (ua->argv[i]) { + client = (CLIENT *)GetResWithName(R_CLIENT, ua->argv[i]); + if (client) { + do_client_setdebug(ua, client, level, trace_flag); + return 1; + } + } + client = select_client_resource(ua); + if (client) { + do_client_setdebug(ua, client, level, trace_flag); + return 1; + } } if (strcasecmp(ua->argk[i], _("store")) == 0 || strcasecmp(ua->argk[i], _("storage")) == 0 || strcasecmp(ua->argk[i], _("sd")) == 0) { - store = NULL; - if (ua->argv[i]) { - store = (STORE *)GetResWithName(R_STORAGE, ua->argv[i]); - if (store) { - do_storage_setdebug(ua, store, level, trace_flag); - return 1; - } - } - store = get_storage_resource(ua, 0); - if (store) { - do_storage_setdebug(ua, store, level, trace_flag); - return 1; - } + store = NULL; + if (ua->argv[i]) { + store = (STORE *)GetResWithName(R_STORAGE, ua->argv[i]); + if (store) { + do_storage_setdebug(ua, store, level, trace_flag); + return 1; + } + } + store = get_storage_resource(ua, 0); + if (store) { + do_storage_setdebug(ua, store, level, trace_flag); + return 1; + } } } /* @@ -839,20 +839,20 @@ static int setdebug_cmd(UAContext *ua, const char *cmd) add_prompt(ua, _("Client")); add_prompt(ua, _("All")); switch(do_prompt(ua, "", _("Select daemon type to set debug level"), NULL, 0)) { - case 0: /* Director */ + case 0: /* Director */ debug_level = level; set_trace(trace_flag); break; case 1: store = get_storage_resource(ua, 0); if (store) { - do_storage_setdebug(ua, store, level, trace_flag); + do_storage_setdebug(ua, store, level, trace_flag); } break; case 2: client = select_client_resource(ua); if (client) { - do_client_setdebug(ua, client, level, trace_flag); + do_client_setdebug(ua, client, level, trace_flag); } break; case 3: @@ -873,7 +873,7 @@ static int trace_cmd(UAContext *ua, const char *cmd) if (ua->argc != 2) { if (!get_cmd(ua, _("Turn on or off? "))) { - return 1; + return 1; } onoff = ua->cmd; } else { @@ -920,44 +920,44 @@ static int estimate_cmd(UAContext *ua, const char *cmd) for (int i=1; iargc; i++) { if (strcasecmp(ua->argk[i], _("client")) == 0 || strcasecmp(ua->argk[i], _("fd")) == 0) { - if (ua->argv[i]) { - client = (CLIENT *)GetResWithName(R_CLIENT, ua->argv[i]); - continue; - } + if (ua->argv[i]) { + client = (CLIENT *)GetResWithName(R_CLIENT, ua->argv[i]); + continue; + } } if (strcasecmp(ua->argk[i], _("job")) == 0) { - if (ua->argv[i]) { - job = (JOB *)GetResWithName(R_JOB, ua->argv[i]); - continue; - } + if (ua->argv[i]) { + job = (JOB *)GetResWithName(R_JOB, ua->argv[i]); + continue; + } } if (strcasecmp(ua->argk[i], _("fileset")) == 0) { - if (ua->argv[i]) { - fileset = (FILESET *)GetResWithName(R_FILESET, ua->argv[i]); - continue; - } + if (ua->argv[i]) { + fileset = (FILESET *)GetResWithName(R_FILESET, ua->argv[i]); + continue; + } } if (strcasecmp(ua->argk[i], _("listing")) == 0) { - listing = 1; - continue; + listing = 1; + continue; } if (strcasecmp(ua->argk[i], _("level")) == 0) { - if (!get_level_from_name(ua->jcr, ua->argv[i])) { + if (!get_level_from_name(ua->jcr, ua->argv[i])) { bsendmsg(ua, _("Level %s not valid.\n"), ua->argv[i]); - } - continue; + } + continue; } } if (!job && !(client && fileset)) { if (!(job = select_job_resource(ua))) { - return 1; + return 1; } } if (!job) { job = (JOB *)GetResWithName(R_JOB, ua->argk[1]); if (!job) { bsendmsg(ua, _("No job specified.\n")); - return 1; + return 1; } } if (!client) { @@ -1080,8 +1080,8 @@ static int delete_cmd(UAContext *ua, const char *cmd) case 3: int i; while ((i=find_arg(ua, _("jobid"))) > 0) { - delete_job(ua); - *ua->argk[i] = 0; /* zap keyword already visited */ + delete_job(ua); + *ua->argk[i] = 0; /* zap keyword already visited */ } return 1; default: @@ -1126,39 +1126,39 @@ static void delete_job(UAContext *ua) int i = find_arg_with_value(ua, _("jobid")); if (i >= 0) { if (strchr(ua->argv[i], ',') != NULL || strchr(ua->argv[i], '-') != NULL) { - s = bstrdup(ua->argv[i]); - tok = s; - /* + s = bstrdup(ua->argv[i]); + tok = s; + /* * We could use strtok() here. But we're not going to, because: - * (a) strtok() is deprecated, having been replaced by strsep(); - * (b) strtok() is broken in significant ways. + * (a) strtok() is deprecated, having been replaced by strsep(); + * (b) strtok() is broken in significant ways. * we could use strsep() instead, but it's not universally available. - * so we grow our own using strchr(). - */ + * so we grow our own using strchr(). + */ sep = strchr(tok, ','); - while (sep != NULL) { + while (sep != NULL) { *sep = '\0'; if (strchr(tok, '-')) { - delete_job_id_range(ua, tok); - } else { - JobId = str_to_int64(tok); - do_job_delete(ua, JobId); - } - tok = ++sep; + delete_job_id_range(ua, tok); + } else { + JobId = str_to_int64(tok); + do_job_delete(ua, JobId); + } + tok = ++sep; sep = strchr(tok, ','); - } - /* pick up the last token */ + } + /* pick up the last token */ if (strchr(tok, '-')) { - delete_job_id_range(ua, tok); - } else { - JobId = str_to_int64(tok); - do_job_delete(ua, JobId); - } + delete_job_id_range(ua, tok); + } else { + JobId = str_to_int64(tok); + do_job_delete(ua, JobId); + } - free(s); + free(s); } else { - JobId = str_to_int64(ua->argv[i]); - do_job_delete(ua, JobId); + JobId = str_to_int64(ua->argv[i]); + do_job_delete(ua, JobId); } } else if (!get_pint(ua, _("Enter JobId to delete: "))) { return; @@ -1327,7 +1327,7 @@ static int use_cmd(UAContext *ua, const char *cmd) CAT *oldcatalog, *catalog; - close_db(ua); /* close any previously open db */ + close_db(ua); /* close any previously open db */ oldcatalog = ua->catalog; if (!(catalog = get_catalog_resource(ua))) { @@ -1337,7 +1337,7 @@ static int use_cmd(UAContext *ua, const char *cmd) } if (open_db(ua)) { bsendmsg(ua, _("Using Catalog name=%s DB=%s\n"), - ua->catalog->hdr.name, ua->catalog->db_name); + ua->catalog->hdr.name, ua->catalog->db_name); } return 1; } @@ -1354,21 +1354,21 @@ int quit_cmd(UAContext *ua, const char *cmd) int wait_cmd(UAContext *ua, const char *cmd) { JCR *jcr; - bmicrosleep(0, 200000); /* let job actually start */ + bmicrosleep(0, 200000); /* let job actually start */ for (bool running=true; running; ) { running = false; lock_jcr_chain(); foreach_jcr(jcr) { - if (jcr->JobId != 0) { - running = true; - free_locked_jcr(jcr); - break; - } - free_locked_jcr(jcr); + if (jcr->JobId != 0) { + running = true; + free_locked_jcr(jcr); + break; + } + free_locked_jcr(jcr); } unlock_jcr_chain(); if (running) { - bmicrosleep(1, 0); + bmicrosleep(1, 0); } } return 1; @@ -1419,10 +1419,10 @@ int open_db(UAContext *ua) UnlockRes(); if (!ua->catalog) { bsendmsg(ua, _("Could not find a Catalog resource\n")); - return 0; + return 0; } else { bsendmsg(ua, _("Using default Catalog name=%s DB=%s\n"), - ua->catalog->hdr.name, ua->catalog->db_name); + ua->catalog->hdr.name, ua->catalog->db_name); } } @@ -1430,12 +1430,12 @@ int open_db(UAContext *ua) Dmsg0(150, "Open database\n"); ua->db = db_init_database(ua->jcr, ua->catalog->db_name, ua->catalog->db_user, - ua->catalog->db_password, ua->catalog->db_address, - ua->catalog->db_port, ua->catalog->db_socket, - ua->catalog->mult_db_connections); + ua->catalog->db_password, ua->catalog->db_address, + ua->catalog->db_port, ua->catalog->db_socket, + ua->catalog->mult_db_connections); if (!ua->db || !db_open_database(ua->jcr, ua->db)) { bsendmsg(ua, _("Could not open database \"%s\".\n"), - ua->catalog->db_name); + ua->catalog->db_name); if (ua->db) { bsendmsg(ua, "%s", db_strerror(ua->db)); } @@ -1453,7 +1453,7 @@ void close_db(UAContext *ua) db_close_database(ua->jcr, ua->db); ua->db = NULL; if (ua->jcr) { - ua->jcr->db = NULL; + ua->jcr->db = NULL; } } } diff --git a/bacula/src/dird/ua_prune.c b/bacula/src/dird/ua_prune.c index 3de4babf02..239424993b 100644 --- a/bacula/src/dird/ua_prune.c +++ b/bacula/src/dird/ua_prune.c @@ -1,7 +1,7 @@ /* * * Bacula Director -- User Agent Database prune Command - * Applies retention periods + * Applies retention periods * * Kern Sibbald, February MMII * @@ -61,19 +61,19 @@ extern char *sel_JobMedia; /* In memory list of JobIds */ struct s_file_del_ctx { JobId_t *JobId; - int num_ids; /* ids stored */ - int max_ids; /* size of array */ - int num_del; /* number deleted */ - int tot_ids; /* total to process */ + int num_ids; /* ids stored */ + int max_ids; /* size of array */ + int num_del; /* number deleted */ + int tot_ids; /* total to process */ }; struct s_job_del_ctx { - JobId_t *JobId; /* array of JobIds */ - char *PurgedFiles; /* Array of PurgedFile flags */ - int num_ids; /* ids stored */ - int max_ids; /* size of array */ - int num_del; /* number deleted */ - int tot_ids; /* total to process */ + JobId_t *JobId; /* array of JobIds */ + char *PurgedFiles; /* Array of PurgedFile flags */ + int num_ids; /* ids stored */ + int max_ids; /* size of array */ + int num_del; /* number deleted */ + int tot_ids; /* total to process */ }; struct s_count_ctx { @@ -143,7 +143,7 @@ static int file_delete_handler(void *ctx, int num_fields, char **row) if (del->num_ids == del->max_ids) { del->max_ids = (del->max_ids * 3) / 2; del->JobId = (JobId_t *)brealloc(del->JobId, sizeof(JobId_t) * - del->max_ids); + del->max_ids); } del->JobId[del->num_ids++] = (JobId_t)str_to_int64(row[0]); return 0; @@ -184,24 +184,24 @@ int prunecmd(UAContext *ua, const char *cmd) case 0: /* prune files */ client = get_client_resource(ua); if (!client || !confirm_retention(ua, &client->FileRetention, "File")) { - return 0; + return 0; } prune_files(ua, client); return 1; case 1: /* prune jobs */ client = get_client_resource(ua); if (!client || !confirm_retention(ua, &client->JobRetention, "Job")) { - return 0; + return 0; } /* ****FIXME**** allow user to select JobType */ prune_jobs(ua, client, JT_BACKUP); return 1; case 2: /* prune volume */ if (!select_pool_and_media_dbr(ua, &pr, &mr)) { - return 0; + return 0; } if (!confirm_retention(ua, &mr.VolRetention, "Volume")) { - return 0; + return 0; } prune_volume(ua, &mr); return 1; @@ -245,7 +245,8 @@ int prune_files(UAContext *ua, CLIENT *client) now = (utime_t)time(NULL); /* Select Jobs -- for counting */ - Mmsg(query, select_job, edit_uint64(now - period, ed1), cr.ClientId); + Mmsg(query, select_job, edit_uint64(now - period, ed1), + edit_int64(cr.ClientId, ed1)); Dmsg1(050, "select sql=%s\n", query); if (!db_sql_query(ua->db, query, file_count_handler, (void *)&del)) { if (ua->verbose) { @@ -276,12 +277,12 @@ int prune_files(UAContext *ua, CLIENT *client) for (i=0; i < del.num_ids; i++) { struct s_count_ctx cnt; - Dmsg1(050, "Delete JobId=%d\n", del.JobId[i]); - Mmsg(query, cnt_File, del.JobId[i]); + Dmsg1(050, "Delete JobId=%u\n", del.JobId[i]); + Mmsg(query, cnt_File, edit_int64(del.JobId[i], ed1)); cnt.count = 0; db_sql_query(ua->db, query, count_handler, (void *)&cnt); del.tot_ids += cnt.count; - Mmsg(query, del_File, del.JobId[i]); + Mmsg(query, del_File, edit_int64(del.JobId[i], ed1)); db_sql_query(ua->db, query, NULL, (void *)NULL); /* * Now mark Job as having files purged. This is necessary to @@ -289,7 +290,7 @@ int prune_files(UAContext *ua, CLIENT *client) * we don't do this, the number of JobId's in our in memory list * could grow very large. */ - Mmsg(query, upd_Purged, del.JobId[i]); + Mmsg(query, upd_Purged, edit_int64(del.JobId[i], ed1)); db_sql_query(ua->db, query, NULL, (void *)NULL); Dmsg1(050, "Del sql=%s\n", query); } @@ -324,7 +325,7 @@ static int create_temp_tables(UAContext *ua) if (!db_sql_query(ua->db, create_deltabs[i], NULL, (void *)NULL)) { bsendmsg(ua, "%s", db_strerror(ua->db)); Dmsg0(050, "create DelTables table failed\n"); - return 0; + return 0; } } return 1; @@ -352,7 +353,7 @@ int prune_jobs(UAContext *ua, CLIENT *client, int JobType) int i; utime_t now, period; CLIENT_DBR cr; - char ed1[50]; + char ed1[50], ed2[50]; db_lock(ua->db); memset(&cr, 0, sizeof(cr)); @@ -379,7 +380,8 @@ int prune_jobs(UAContext *ua, CLIENT *client, int JobType) * and stuff them into the "DeletionCandidates" table. */ edit_uint64(now - period, ed1); - Mmsg(query, insert_delcand, (char)JobType, ed1, cr.ClientId); + Mmsg(query, insert_delcand, (char)JobType, ed1, + edit_int64(cr.ClientId, ed2)); if (!db_sql_query(ua->db, query, NULL, (void *)NULL)) { if (ua->verbose) { bsendmsg(ua, "%s", db_strerror(ua->db)); @@ -413,18 +415,20 @@ int prune_jobs(UAContext *ua, CLIENT *client, int JobType) del.JobId = (JobId_t *)malloc(sizeof(JobId_t) * del.max_ids); del.PurgedFiles = (char *)malloc(del.max_ids); + /* ed1 = JobTDate */ + edit_int64(cr.ClientId, ed2); switch (JobType) { case JT_BACKUP: - Mmsg(query, select_backup_del, ed1, ed1, cr.ClientId); + Mmsg(query, select_backup_del, ed1, ed1, ed2); break; case JT_RESTORE: - Mmsg(query, select_restore_del, ed1, ed1, cr.ClientId); + Mmsg(query, select_restore_del, ed1, ed1, ed2); break; case JT_VERIFY: - Mmsg(query, select_verify_del, ed1, ed1, cr.ClientId); + Mmsg(query, select_verify_del, ed1, ed1, ed2); break; case JT_ADMIN: - Mmsg(query, select_admin_del, ed1, ed1, cr.ClientId); + Mmsg(query, select_admin_del, ed1, ed1, ed2); break; } if (!db_sql_query(ua->db, query, job_delete_handler, (void *)&del)) { @@ -439,20 +443,20 @@ int prune_jobs(UAContext *ua, CLIENT *client, int JobType) for (i=0; i < del.num_ids; i++) { Dmsg1(050, "Delete JobId=%d\n", del.JobId[i]); if (!del.PurgedFiles[i]) { - Mmsg(query, del_File, del.JobId[i]); - if (!db_sql_query(ua->db, query, NULL, (void *)NULL)) { + Mmsg(query, del_File, edit_int64(del.JobId[i], ed1)); + if (!db_sql_query(ua->db, query, NULL, (void *)NULL)) { bsendmsg(ua, "%s", db_strerror(ua->db)); - } + } Dmsg1(050, "Del sql=%s\n", query); } - Mmsg(query, del_Job, del.JobId[i]); + Mmsg(query, del_Job, edit_int64(del.JobId[i], ed1)); if (!db_sql_query(ua->db, query, NULL, (void *)NULL)) { bsendmsg(ua, "%s", db_strerror(ua->db)); } Dmsg1(050, "Del sql=%s\n", query); - Mmsg(query, del_JobMedia, del.JobId[i]); + Mmsg(query, del_JobMedia, edit_int64(del.JobId[i], ed1)); if (!db_sql_query(ua->db, query, NULL, (void *)NULL)) { bsendmsg(ua, "%s", db_strerror(ua->db)); } @@ -485,6 +489,7 @@ int prune_volume(UAContext *ua, MEDIA_DBR *mr) int i, stat = 0; JOB_DBR jr; utime_t now, period; + char ed1[50]; db_lock(ua->db); memset(&jr, 0, sizeof(jr)); @@ -495,7 +500,7 @@ int prune_volume(UAContext *ua, MEDIA_DBR *mr) * counting the JobMedia records. */ cnt.count = 0; - Mmsg(query, cnt_JobMedia, mr->MediaId); + Mmsg(query, cnt_JobMedia, edit_int64(mr->MediaId, ed1)); if (!db_sql_query(ua->db, query, count_handler, (void *)&cnt)) { bsendmsg(ua, "%s", db_strerror(ua->db)); Dmsg0(050, "Count failed\n"); @@ -505,7 +510,7 @@ int prune_volume(UAContext *ua, MEDIA_DBR *mr) if (cnt.count == 0) { if (strcmp(mr->VolStatus, "Purged") != 0 && verbose) { bsendmsg(ua, "There are no Jobs associated with Volume \"%s\". Marking it purged.\n", - mr->VolumeName); + mr->VolumeName); } stat = mark_media_purged(ua, mr); goto bail_out; @@ -519,10 +524,10 @@ int prune_volume(UAContext *ua, MEDIA_DBR *mr) /* * Now get a list of JobIds for Jobs written to this Volume - * Could optimize here by adding JobTDate > (now - period). + * Could optimize here by adding JobTDate > (now - period). */ del.JobId = (JobId_t *)malloc(sizeof(JobId_t) * del.max_ids); - Mmsg(query, sel_JobMedia, mr->MediaId); + Mmsg(query, sel_JobMedia, edit_int64(mr->MediaId, ed1)); if (!db_sql_query(ua->db, query, file_delete_handler, (void *)&del)) { if (ua->verbose) { bsendmsg(ua, "%s", db_strerror(ua->db)); @@ -541,18 +546,18 @@ int prune_volume(UAContext *ua, MEDIA_DBR *mr) for (i=0; i < del.num_ids; i++) { jr.JobId = del.JobId[i]; if (!db_get_job_record(ua->jcr, ua->db, &jr)) { - continue; + continue; } Dmsg2(200, "Looking at %s JobTdate=%d\n", jr.Job, (int)jr.JobTDate); if (jr.JobTDate >= (now - period)) { - continue; + continue; } Dmsg2(200, "Delete JobId=%d Job=%s\n", del.JobId[i], jr.Job); - Mmsg(query, del_File, del.JobId[i]); + Mmsg(query, del_File, edit_int64(del.JobId[i], ed1)); db_sql_query(ua->db, query, NULL, (void *)NULL); - Mmsg(query, del_Job, del.JobId[i]); + Mmsg(query, del_Job, edit_int64(del.JobId[i], ed1)); db_sql_query(ua->db, query, NULL, (void *)NULL); - Mmsg(query, del_JobMedia, del.JobId[i]); + Mmsg(query, del_JobMedia, edit_int64(del.JobId[i], ed1)); db_sql_query(ua->db, query, NULL, (void *)NULL); Dmsg1(050, "Del sql=%s\n", query); del.num_del++; diff --git a/bacula/src/dird/ua_restore.c b/bacula/src/dird/ua_restore.c index 3639758865..0c958af04d 100644 --- a/bacula/src/dird/ua_restore.c +++ b/bacula/src/dird/ua_restore.c @@ -1,12 +1,12 @@ /* * * Bacula Director -- User Agent Database restore Command - * Creates a bootstrap file for restoring files and - * starts the restore job. + * Creates a bootstrap file for restoring files and + * starts the restore job. * - * Tree handling routines split into ua_tree.c July MMIII. - * BSR (bootstrap record) handling routines split into - * bsr.c July MMIII + * Tree handling routines split into ua_tree.c July MMIII. + * BSR (bootstrap record) handling routines split into + * bsr.c July MMIII * * Kern Sibbald, July MMII * @@ -41,22 +41,22 @@ extern void print_bsr(UAContext *ua, RBSR *bsr); /* Imported variables */ -extern char *uar_list_jobs, *uar_file, *uar_sel_files; -extern char *uar_del_temp, *uar_del_temp1, *uar_create_temp; -extern char *uar_create_temp1, *uar_last_full, *uar_full; -extern char *uar_inc, *uar_list_temp, *uar_sel_jobid_temp; +extern char *uar_list_jobs, *uar_file, *uar_sel_files; +extern char *uar_del_temp, *uar_del_temp1, *uar_create_temp; +extern char *uar_create_temp1, *uar_last_full, *uar_full; +extern char *uar_inc, *uar_list_temp, *uar_sel_jobid_temp; extern char *uar_sel_all_temp1, *uar_sel_fileset, *uar_mediatype; -extern char *uar_jobid_fileindex, *uar_dif, *uar_sel_all_temp; -extern char *uar_count_files, *uar_jobids_fileindex; +extern char *uar_jobid_fileindex, *uar_dif, *uar_sel_all_temp; +extern char *uar_count_files, *uar_jobids_fileindex; extern char *uar_jobid_fileindex_from_dir; struct NAME_LIST { - char **name; /* list of names */ - int num_ids; /* ids stored */ - int max_ids; /* size of array */ - int num_del; /* number deleted */ - int tot_ids; /* total to process */ + char **name; /* list of names */ + int num_ids; /* ids stored */ + int max_ids; /* size of array */ + int num_del; /* number deleted */ + int tot_ids; /* total to process */ }; @@ -67,7 +67,7 @@ struct RESTORE_CTX { uint32_t JobId; char ClientName[MAX_NAME_LENGTH]; char last_jobid[10]; - POOLMEM *JobIds; /* User entered string of JobIds */ + POOLMEM *JobIds; /* User entered string of JobIds */ STORE *store; JOB *restore_job; POOL *pool; @@ -75,13 +75,13 @@ struct RESTORE_CTX { uint32_t selected_files; char *where; RBSR *bsr; - POOLMEM *fname; /* filename only */ - POOLMEM *path; /* path only */ + POOLMEM *fname; /* filename only */ + POOLMEM *path; /* path only */ POOLMEM *query; - int fnl; /* filename length */ - int pnl; /* path length */ + int fnl; /* filename length */ + int pnl; /* path length */ bool found; - bool all; /* mark all as default */ + bool all; /* mark all as default */ NAME_LIST name_list; }; @@ -105,9 +105,9 @@ static void free_rx(RESTORE_CTX *rx); static void split_path_and_filename(RESTORE_CTX *rx, char *fname); static int jobid_fileindex_handler(void *ctx, int num_fields, char **row); static bool insert_file_into_findex_list(UAContext *ua, RESTORE_CTX *rx, char *file, - char *date); + char *date); static bool insert_dir_into_findex_list(UAContext *ua, RESTORE_CTX *rx, char *dir, - char *date); + char *date); static void insert_one_file_or_dir(UAContext *ua, RESTORE_CTX *rx, char *date, bool dir); static int get_client_name(UAContext *ua, RESTORE_CTX *rx); static int get_date(UAContext *ua, char *date, int date_len); @@ -119,7 +119,7 @@ static int count_handler(void *ctx, int num_fields, char **row); */ int restore_cmd(UAContext *ua, const char *cmd) { - RESTORE_CTX rx; /* restore context */ + RESTORE_CTX rx; /* restore context */ JOB *job; int i; @@ -143,10 +143,10 @@ int restore_cmd(UAContext *ua, const char *cmd) LockRes(); foreach_res(job, R_JOB) { if (job->JobType == JT_RESTORE) { - if (!rx.restore_job) { - rx.restore_job = job; - } - rx.restore_jobs++; + if (!rx.restore_job) { + rx.restore_job = job; + } + rx.restore_jobs++; } } UnlockRes(); @@ -164,26 +164,26 @@ int restore_cmd(UAContext *ua, const char *cmd) * add_findex() */ switch (user_select_jobids_or_files(ua, &rx)) { - case 0: /* error */ + case 0: /* error */ goto bail_out; - case 1: /* selected by jobid */ + case 1: /* selected by jobid */ if (!build_directory_tree(ua, &rx)) { bsendmsg(ua, _("Restore not done.\n")); - goto bail_out; + goto bail_out; } break; - case 2: /* selected by filename, no tree needed */ + case 2: /* selected by filename, no tree needed */ break; } if (rx.bsr->JobId) { - if (!complete_bsr(ua, rx.bsr)) { /* find Vol, SessId, SessTime from JobIds */ + if (!complete_bsr(ua, rx.bsr)) { /* find Vol, SessId, SessTime from JobIds */ bsendmsg(ua, _("Unable to construct a valid BSR. Cannot continue.\n")); - goto bail_out; + goto bail_out; } if (!(rx.selected_files = write_bsr_file(ua, rx.bsr))) { bsendmsg(ua, _("No files selected to be restored.\n")); - goto bail_out; + goto bail_out; } bsendmsg(ua, _("\n%u file%s selected to be restored.\n\n"), rx.selected_files, rx.selected_files==1?"":"s"); @@ -213,13 +213,13 @@ int restore_cmd(UAContext *ua, const char *cmd) "run job=\"%s\" client=\"%s\" storage=\"%s\" bootstrap=\"%s/restore.bsr\"" " where=\"%s\" files=%d catalog=\"%s\"", job->hdr.name, rx.ClientName, rx.store?rx.store->hdr.name:"", - working_directory, rx.where, rx.selected_files, ua->catalog->hdr.name); + working_directory, rx.where, rx.selected_files, ua->catalog->hdr.name); } else { Mmsg(ua->cmd, "run job=\"%s\" client=\"%s\" storage=\"%s\" bootstrap=\"%s/restore.bsr\"" " files=%d catalog=\"%s\"", job->hdr.name, rx.ClientName, rx.store?rx.store->hdr.name:"", - working_directory, rx.selected_files, ua->catalog->hdr.name); + working_directory, rx.selected_files, ua->catalog->hdr.name); } if (find_arg(ua, _("yes")) > 0) { pm_strcat(ua->cmd, " yes"); /* pass it on to the run command */ @@ -267,12 +267,12 @@ static int get_client_name(UAContext *ua, RESTORE_CTX *rx) /* try command line argument */ int i = find_arg_with_value(ua, _("client")); if (i >= 0) { - bstrncpy(rx->ClientName, ua->argv[i], sizeof(rx->ClientName)); - return 1; + bstrncpy(rx->ClientName, ua->argv[i], sizeof(rx->ClientName)); + return 1; } memset(&cr, 0, sizeof(cr)); if (!get_client_dbr(ua, &cr)) { - return 0; + return 0; } bstrncpy(rx->ClientName, cr.Name, sizeof(rx->ClientName)); } @@ -285,8 +285,8 @@ static int get_client_name(UAContext *ua, RESTORE_CTX *rx) * select which files are to be restored. * * Returns: 2 if filename list made - * 1 if jobid list made - * 0 on error + * 1 if jobid list made + * 0 on error */ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx) { @@ -335,86 +335,86 @@ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx) for (i=1; iargc; i++) { /* loop through arguments */ bool found_kw = false; - for (j=0; kw[j]; j++) { /* loop through keywords */ - if (strcasecmp(kw[j], ua->argk[i]) == 0) { - found_kw = true; - break; - } + for (j=0; kw[j]; j++) { /* loop through keywords */ + if (strcasecmp(kw[j], ua->argk[i]) == 0) { + found_kw = true; + break; + } } if (!found_kw) { bsendmsg(ua, _("Unknown keyword: %s\n"), ua->argk[i]); - return 0; + return 0; } /* Found keyword in kw[] list, process it */ switch (j) { - case 0: /* jobid */ - if (*rx->JobIds != 0) { + case 0: /* jobid */ + if (*rx->JobIds != 0) { pm_strcat(rx->JobIds, ","); - } - pm_strcat(rx->JobIds, ua->argv[i]); - done = true; - break; - case 1: /* current */ - bstrutime(date, sizeof(date), time(NULL)); - have_date = true; - break; - case 2: /* before */ - if (str_to_utime(ua->argv[i]) == 0) { + } + pm_strcat(rx->JobIds, ua->argv[i]); + done = true; + break; + case 1: /* current */ + bstrutime(date, sizeof(date), time(NULL)); + have_date = true; + break; + case 2: /* before */ + if (str_to_utime(ua->argv[i]) == 0) { bsendmsg(ua, _("Improper date format: %s\n"), ua->argv[i]); - return 0; - } - bstrncpy(date, ua->argv[i], sizeof(date)); - have_date = true; - break; - case 3: /* file */ - case 4: /* dir */ - if (!have_date) { - bstrutime(date, sizeof(date), time(NULL)); - } - if (!get_client_name(ua, rx)) { - return 0; - } - pm_strcpy(ua->cmd, ua->argv[i]); - insert_one_file_or_dir(ua, rx, date, j==4); - if (rx->name_list.num_ids) { - /* Check MediaType and select storage that corresponds */ - get_storage_from_mediatype(ua, &rx->name_list, rx); - done = true; - } - break; - case 5: /* select */ - if (!have_date) { - bstrutime(date, sizeof(date), time(NULL)); - } - if (!select_backups_before_date(ua, rx, date)) { - return 0; - } - done = true; - break; - case 6: /* pool specified */ - rx->pool = (POOL *)GetResWithName(R_POOL, ua->argv[i]); - if (!rx->pool) { + return 0; + } + bstrncpy(date, ua->argv[i], sizeof(date)); + have_date = true; + break; + case 3: /* file */ + case 4: /* dir */ + if (!have_date) { + bstrutime(date, sizeof(date), time(NULL)); + } + if (!get_client_name(ua, rx)) { + return 0; + } + pm_strcpy(ua->cmd, ua->argv[i]); + insert_one_file_or_dir(ua, rx, date, j==4); + if (rx->name_list.num_ids) { + /* Check MediaType and select storage that corresponds */ + get_storage_from_mediatype(ua, &rx->name_list, rx); + done = true; + } + break; + case 5: /* select */ + if (!have_date) { + bstrutime(date, sizeof(date), time(NULL)); + } + if (!select_backups_before_date(ua, rx, date)) { + return 0; + } + done = true; + break; + case 6: /* pool specified */ + rx->pool = (POOL *)GetResWithName(R_POOL, ua->argv[i]); + if (!rx->pool) { bsendmsg(ua, _("Error: Pool resource \"%s\" does not exist.\n"), ua->argv[i]); - return 0; - } - if (!acl_access_ok(ua, Pool_ACL, ua->argv[i])) { - rx->pool = NULL; + return 0; + } + if (!acl_access_ok(ua, Pool_ACL, ua->argv[i])) { + rx->pool = NULL; bsendmsg(ua, _("Error: Pool resource \"%s\" access not allowed.\n"), ua->argv[i]); - return 0; - } - break; - case 7: /* all specified */ - rx->all = true; - break; + return 0; + } + break; + case 7: /* all specified */ + rx->all = true; + break; /* * All keywords 7 or greater are ignored or handled by a select prompt */ default: - break; + break; } } if (rx->name_list.num_ids) { - return 2; /* filename list made */ + return 2; /* filename list made */ } if (!done) { @@ -432,148 +432,148 @@ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx) start_prompt(ua, _("To select the JobIds, you have the following choices:\n")); for (int i=0; list[i]; i++) { - add_prompt(ua, list[i]); + add_prompt(ua, list[i]); } done = true; switch (do_prompt(ua, "", _("Select item: "), NULL, 0)) { - case -1: /* error */ - return 0; - case 0: /* list last 20 Jobs run */ - gui_save = ua->jcr->gui; - ua->jcr->gui = true; - db_list_sql_query(ua->jcr, ua->db, uar_list_jobs, prtit, ua, 1, HORZ_LIST); - ua->jcr->gui = gui_save; - done = false; - break; - case 1: /* list where a file is saved */ + case -1: /* error */ + return 0; + case 0: /* list last 20 Jobs run */ + gui_save = ua->jcr->gui; + ua->jcr->gui = true; + db_list_sql_query(ua->jcr, ua->db, uar_list_jobs, prtit, ua, 1, HORZ_LIST); + ua->jcr->gui = gui_save; + done = false; + break; + case 1: /* list where a file is saved */ if (!get_cmd(ua, _("Enter Filename (no path):"))) { - return 0; - } - len = strlen(ua->cmd); - fname = (char *)malloc(len * 2 + 1); - db_escape_string(fname, ua->cmd, len); - Mmsg(rx->query, uar_file, fname); - free(fname); - gui_save = ua->jcr->gui; - ua->jcr->gui = true; - db_list_sql_query(ua->jcr, ua->db, rx->query, prtit, ua, 1, HORZ_LIST); - ua->jcr->gui = gui_save; - done = false; - break; - case 2: /* enter a list of JobIds */ + return 0; + } + len = strlen(ua->cmd); + fname = (char *)malloc(len * 2 + 1); + db_escape_string(fname, ua->cmd, len); + Mmsg(rx->query, uar_file, fname); + free(fname); + gui_save = ua->jcr->gui; + ua->jcr->gui = true; + db_list_sql_query(ua->jcr, ua->db, rx->query, prtit, ua, 1, HORZ_LIST); + ua->jcr->gui = gui_save; + done = false; + break; + case 2: /* enter a list of JobIds */ if (!get_cmd(ua, _("Enter JobId(s), comma separated, to restore: "))) { - return 0; - } - pm_strcpy(rx->JobIds, ua->cmd); - break; - case 3: /* Enter an SQL list command */ + return 0; + } + pm_strcpy(rx->JobIds, ua->cmd); + break; + case 3: /* Enter an SQL list command */ if (!get_cmd(ua, _("Enter SQL list command: "))) { - return 0; - } - gui_save = ua->jcr->gui; - ua->jcr->gui = true; - db_list_sql_query(ua->jcr, ua->db, ua->cmd, prtit, ua, 1, HORZ_LIST); - ua->jcr->gui = gui_save; - done = false; - break; - case 4: /* Select the most recent backups */ - bstrutime(date, sizeof(date), time(NULL)); - if (!select_backups_before_date(ua, rx, date)) { - return 0; - } - break; - case 5: /* select backup at specified time */ - if (!get_date(ua, date, sizeof(date))) { - return 0; - } - if (!select_backups_before_date(ua, rx, date)) { - return 0; - } - break; - case 6: /* Enter files */ - bstrutime(date, sizeof(date), time(NULL)); - if (!get_client_name(ua, rx)) { - return 0; - } + return 0; + } + gui_save = ua->jcr->gui; + ua->jcr->gui = true; + db_list_sql_query(ua->jcr, ua->db, ua->cmd, prtit, ua, 1, HORZ_LIST); + ua->jcr->gui = gui_save; + done = false; + break; + case 4: /* Select the most recent backups */ + bstrutime(date, sizeof(date), time(NULL)); + if (!select_backups_before_date(ua, rx, date)) { + return 0; + } + break; + case 5: /* select backup at specified time */ + if (!get_date(ua, date, sizeof(date))) { + return 0; + } + if (!select_backups_before_date(ua, rx, date)) { + return 0; + } + break; + case 6: /* Enter files */ + bstrutime(date, sizeof(date), time(NULL)); + if (!get_client_name(ua, rx)) { + return 0; + } bsendmsg(ua, _("Enter file names with paths, or < to enter a filename\n" "containg a list of file names with paths, and terminate\n" "them with a blank line.\n")); - for ( ;; ) { + for ( ;; ) { if (!get_cmd(ua, _("Enter full filename: "))) { - return 0; - } - len = strlen(ua->cmd); - if (len == 0) { - break; - } - insert_one_file_or_dir(ua, rx, date, false); - } - /* Check MediaType and select storage that corresponds */ - if (rx->name_list.num_ids) { - get_storage_from_mediatype(ua, &rx->name_list, rx); - } - return 2; - case 7: /* enter files backed up before specified time */ - if (!get_date(ua, date, sizeof(date))) { - return 0; - } - if (!get_client_name(ua, rx)) { - return 0; - } + return 0; + } + len = strlen(ua->cmd); + if (len == 0) { + break; + } + insert_one_file_or_dir(ua, rx, date, false); + } + /* Check MediaType and select storage that corresponds */ + if (rx->name_list.num_ids) { + get_storage_from_mediatype(ua, &rx->name_list, rx); + } + return 2; + case 7: /* enter files backed up before specified time */ + if (!get_date(ua, date, sizeof(date))) { + return 0; + } + if (!get_client_name(ua, rx)) { + return 0; + } bsendmsg(ua, _("Enter file names with paths, or < to enter a filename\n" "containg a list of file names with paths, and terminate\n" "them with a blank line.\n")); - for ( ;; ) { + for ( ;; ) { if (!get_cmd(ua, _("Enter full filename: "))) { - return 0; - } - len = strlen(ua->cmd); - if (len == 0) { - break; - } - insert_one_file_or_dir(ua, rx, date, false); - } - /* Check MediaType and select storage that corresponds */ - if (rx->name_list.num_ids) { - get_storage_from_mediatype(ua, &rx->name_list, rx); - } - return 2; - - case 8: /* Enter directories */ + return 0; + } + len = strlen(ua->cmd); + if (len == 0) { + break; + } + insert_one_file_or_dir(ua, rx, date, false); + } + /* Check MediaType and select storage that corresponds */ + if (rx->name_list.num_ids) { + get_storage_from_mediatype(ua, &rx->name_list, rx); + } + return 2; + + case 8: /* Enter directories */ if (get_cmd(ua, _("Enter JobId(s), comma separated, to restore: "))) { - if (*rx->JobIds != 0) { + if (*rx->JobIds != 0) { pm_strcat(rx->JobIds, ","); - } - pm_strcpy(rx->JobIds, ua->cmd); - } - if (*rx->JobIds != 0) { - return 0; - } - bstrutime(date, sizeof(date), time(NULL)); - if (!get_client_name(ua, rx)) { - return 0; - } + } + pm_strcpy(rx->JobIds, ua->cmd); + } + if (*rx->JobIds != 0) { + return 0; + } + bstrutime(date, sizeof(date), time(NULL)); + if (!get_client_name(ua, rx)) { + return 0; + } bsendmsg(ua, _("Enter directory names with a trailing /, or < to enter a filename\n" "containg a list of directories and terminate\n" "them with a blank line.\n")); - for ( ;; ) { + for ( ;; ) { if (!get_cmd(ua, _("Enter full filename: "))) { - return 0; - } - len = strlen(ua->cmd); - if (len == 0) { - break; - } - insert_one_file_or_dir(ua, rx, date, true); - } - /* Check MediaType and select storage that corresponds */ - if (rx->name_list.num_ids) { - get_storage_from_mediatype(ua, &rx->name_list, rx); - } - return 2; - - case 9: /* Cancel or quit */ - return 0; + return 0; + } + len = strlen(ua->cmd); + if (len == 0) { + break; + } + insert_one_file_or_dir(ua, rx, date, true); + } + /* Check MediaType and select storage that corresponds */ + if (rx->name_list.num_ids) { + get_storage_from_mediatype(ua, &rx->name_list, rx); + } + return 2; + + case 9: /* Cancel or quit */ + return 0; } } @@ -591,25 +591,25 @@ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx) int stat = get_next_jobid_from_list(&p, &JobId); if (stat < 0) { bsendmsg(ua, _("Invalid JobId in list.\n")); - return 0; + return 0; } if (stat == 0) { - break; + break; } if (jr.JobId == JobId) { - continue; /* duplicate of last JobId */ + continue; /* duplicate of last JobId */ } jr.JobId = JobId; if (!db_get_job_record(ua->jcr, ua->db, &jr)) { - char ed1[50]; + char ed1[50]; bsendmsg(ua, _("Unable to get Job record for JobId=%s: ERR=%s\n"), - edit_int64(JobId, ed1), db_strerror(ua->db)); - return 0; + edit_int64(JobId, ed1), db_strerror(ua->db)); + return 0; } if (!acl_access_ok(ua, Job_ACL, jr.Name)) { bsendmsg(ua, _("No authorization. Job \"%s\" not selected.\n"), - jr.Name); - continue; + jr.Name); + continue; } rx->TotalFiles += jr.JobFiles; } @@ -625,10 +625,10 @@ static int get_date(UAContext *ua, char *date, int date_len) "BEFORE the date you specify below.\n\n")); for ( ;; ) { if (!get_cmd(ua, _("Enter date as YYYY-MM-DD HH:MM:SS :"))) { - return 0; + return 0; } if (str_to_utime(ua->cmd) != 0) { - break; + break; } bsendmsg(ua, _("Improper date format.\n")); } @@ -650,30 +650,30 @@ static void insert_one_file_or_dir(UAContext *ua, RESTORE_CTX *rx, char *date, b case '<': p++; if ((ffd = fopen(p, "r")) == NULL) { - berrno be; + berrno be; bsendmsg(ua, _("Cannot open file %s: ERR=%s\n"), - p, be.strerror()); - break; + p, be.strerror()); + break; } while (fgets(file, sizeof(file), ffd)) { - line++; - if (dir) { - if (!insert_dir_into_findex_list(ua, rx, file, date)) { + line++; + if (dir) { + if (!insert_dir_into_findex_list(ua, rx, file, date)) { bsendmsg(ua, _("Error occurred on line %d of %s\n"), line, p); - } - } else { - if (!insert_file_into_findex_list(ua, rx, file, date)) { + } + } else { + if (!insert_file_into_findex_list(ua, rx, file, date)) { bsendmsg(ua, _("Error occurred on line %d of %s\n"), line, p); - } - } + } + } } fclose(ffd); break; default: if (dir) { - insert_dir_into_findex_list(ua, rx, ua->cmd, date); + insert_dir_into_findex_list(ua, rx, ua->cmd, date); } else { - insert_file_into_findex_list(ua, rx, ua->cmd, date); + insert_file_into_findex_list(ua, rx, ua->cmd, date); } break; } @@ -685,22 +685,24 @@ static void insert_one_file_or_dir(UAContext *ua, RESTORE_CTX *rx, char *date, b * and FileIndex, then insert them into the findex list. */ static bool insert_file_into_findex_list(UAContext *ua, RESTORE_CTX *rx, char *file, - char *date) + char *date) { + char ed1[50]; + strip_trailing_junk(file); split_path_and_filename(rx, file); if (*rx->JobIds == 0) { Mmsg(rx->query, uar_jobid_fileindex, date, rx->path, rx->fname, - rx->ClientName); + rx->ClientName); } else { Mmsg(rx->query, uar_jobids_fileindex, rx->JobIds, date, - rx->path, rx->fname, rx->ClientName); + rx->path, rx->fname, rx->ClientName); } rx->found = false; /* Find and insert jobid and File Index */ if (!db_sql_query(ua->db, rx->query, jobid_fileindex_handler, (void *)rx)) { bsendmsg(ua, _("Query failed: %s. ERR=%s\n"), - rx->query, db_strerror(ua->db)); + rx->query, db_strerror(ua->db)); } if (!rx->found) { bsendmsg(ua, _("No database record found for: %s\n"), file); @@ -709,7 +711,7 @@ static bool insert_file_into_findex_list(UAContext *ua, RESTORE_CTX *rx, char *f /* * Find the MediaTypes for this JobId and add to the name_list */ - Mmsg(rx->query, uar_mediatype, rx->JobId); + Mmsg(rx->query, uar_mediatype, edit_int64(rx->JobId, ed1)); if (!db_sql_query(ua->db, rx->query, unique_name_list_handler, (void *)&rx->name_list)) { bsendmsg(ua, "%s", db_strerror(ua->db)); return false; @@ -722,7 +724,7 @@ static bool insert_file_into_findex_list(UAContext *ua, RESTORE_CTX *rx, char *f * to get the JobId and FileIndexes of all files in that directory. */ static bool insert_dir_into_findex_list(UAContext *ua, RESTORE_CTX *rx, char *dir, - char *date) + char *date) { strip_trailing_junk(dir); if (*rx->JobIds == 0) { @@ -730,13 +732,13 @@ static bool insert_dir_into_findex_list(UAContext *ua, RESTORE_CTX *rx, char *di return false; } else { Mmsg(rx->query, uar_jobid_fileindex_from_dir, rx->JobIds, - dir, rx->ClientName); + dir, rx->ClientName); } rx->found = false; /* Find and insert jobid and File Index */ if (!db_sql_query(ua->db, rx->query, jobid_fileindex_handler, (void *)rx)) { bsendmsg(ua, _("Query failed: %s. ERR=%s\n"), - rx->query, db_strerror(ua->db)); + rx->query, db_strerror(ua->db)); } if (!rx->found) { bsendmsg(ua, _("No database record found for: %s\n"), dir); @@ -766,12 +768,12 @@ static void split_path_and_filename(RESTORE_CTX *rx, char *name) */ for (p=f=name; *p; p++) { if (*p == '/') { - f = p; /* set pos of last slash */ + f = p; /* set pos of last slash */ } } if (*f == '/') { /* did we find a slash? */ - f++; /* yes, point to filename */ - } else { /* no, whole thing must be path name */ + f++; /* yes, point to filename */ + } else { /* no, whole thing must be path name */ f = p; } @@ -783,7 +785,7 @@ static void split_path_and_filename(RESTORE_CTX *rx, char *name) rx->fnl = p - f; if (rx->fnl > 0) { rx->fname = check_pool_memory_size(rx->fname, rx->fnl+1); - memcpy(rx->fname, f, rx->fnl); /* copy filename */ + memcpy(rx->fname, f, rx->fnl); /* copy filename */ rx->fname[rx->fnl] = 0; } else { rx->fname[0] = 0; @@ -809,6 +811,7 @@ static bool build_directory_tree(UAContext *ua, RESTORE_CTX *rx) JobId_t JobId, last_JobId; char *p; bool OK = true; + char ed1[50]; memset(&tree, 0, sizeof(TREE_CTX)); /* @@ -827,37 +830,37 @@ static bool build_directory_tree(UAContext *ua, RESTORE_CTX *rx) tree.FileEstimate = 0; if (get_next_jobid_from_list(&p, &JobId) > 0) { /* Use first JobId as estimate of the number of files to restore */ - Mmsg(rx->query, uar_count_files, JobId); + Mmsg(rx->query, uar_count_files, edit_int64(JobId, ed1)); if (!db_sql_query(ua->db, rx->query, count_handler, (void *)rx)) { bsendmsg(ua, "%s\n", db_strerror(ua->db)); } if (rx->found) { - /* Add about 25% more than this job for over estimate */ - tree.FileEstimate = rx->JobId + (rx->JobId >> 2); - tree.DeltaCount = rx->JobId/50; /* print 50 ticks */ + /* Add about 25% more than this job for over estimate */ + tree.FileEstimate = rx->JobId + (rx->JobId >> 2); + tree.DeltaCount = rx->JobId/50; /* print 50 ticks */ } } for (p=rx->JobIds; get_next_jobid_from_list(&p, &JobId) > 0; ) { char ed1[50]; if (JobId == last_JobId) { - continue; /* eliminate duplicate JobIds */ + continue; /* eliminate duplicate JobIds */ } last_JobId = JobId; bsendmsg(ua, _("\nBuilding directory tree for JobId %s ... "), - edit_int64(JobId, ed1)); + edit_int64(JobId, ed1)); items++; /* * Find files for this JobId and insert them in the tree */ - Mmsg(rx->query, uar_sel_files, JobId); + Mmsg(rx->query, uar_sel_files, edit_int64(JobId, ed1)); if (!db_sql_query(ua->db, rx->query, insert_tree_handler, (void *)&tree)) { bsendmsg(ua, "%s", db_strerror(ua->db)); } /* * Find the MediaTypes for this JobId and add to the name_list */ - Mmsg(rx->query, uar_mediatype, JobId); + Mmsg(rx->query, uar_mediatype, edit_int64(JobId, ed1)); if (!db_sql_query(ua->db, rx->query, unique_name_list_handler, (void *)&rx->name_list)) { bsendmsg(ua, "%s", db_strerror(ua->db)); } @@ -866,16 +869,16 @@ static bool build_directory_tree(UAContext *ua, RESTORE_CTX *rx) bsendmsg(ua, "\nThere were no files inserted into the tree, so file selection\n" "is not possible.\n"); if (!get_yesno(ua, _("Do you want to restore all the files? (yes|no): "))) { - OK = false; + OK = false; } else { - last_JobId = 0; - for (p=rx->JobIds; get_next_jobid_from_list(&p, &JobId) > 0; ) { - if (JobId == last_JobId) { - continue; /* eliminate duplicate JobIds */ - } - add_findex_all(rx->bsr, JobId); - } - OK = true; + last_JobId = 0; + for (p=rx->JobIds; get_next_jobid_from_list(&p, &JobId) > 0; ) { + if (JobId == last_JobId) { + continue; /* eliminate duplicate JobIds */ + } + add_findex_all(rx->bsr, JobId); + } + OK = true; } } else { char ec1[50]; @@ -887,8 +890,8 @@ static bool build_directory_tree(UAContext *ua, RESTORE_CTX *rx) get_storage_from_mediatype(ua, &rx->name_list, rx); if (find_arg(ua, _("done")) < 0) { - /* Let the user interact in selecting which files to restore */ - OK = user_select_files_from_tree(&tree); + /* Let the user interact in selecting which files to restore */ + OK = user_select_files_from_tree(&tree); } /* @@ -896,20 +899,20 @@ static bool build_directory_tree(UAContext *ua, RESTORE_CTX *rx) * extracted making a bootstrap file. */ if (OK) { - for (TREE_NODE *node=first_tree_node(tree.root); node; node=next_tree_node(node)) { + for (TREE_NODE *node=first_tree_node(tree.root); node; node=next_tree_node(node)) { Dmsg2(400, "FI=%d node=0x%x\n", node->FileIndex, node); - if (node->extract || node->extract_dir) { + if (node->extract || node->extract_dir) { Dmsg2(400, "type=%d FI=%d\n", node->type, node->FileIndex); - add_findex(rx->bsr, node->JobId, node->FileIndex); - if (node->extract && node->type != TN_NEWDIR) { - rx->selected_files++; /* count only saved files */ - } - } - } + add_findex(rx->bsr, node->JobId, node->FileIndex); + if (node->extract && node->type != TN_NEWDIR) { + rx->selected_files++; /* count only saved files */ + } + } + } } } - free_tree(tree.root); /* free the directory tree */ + free_tree(tree.root); /* free the directory tree */ return OK; } @@ -924,7 +927,7 @@ static bool select_backups_before_date(UAContext *ua, RESTORE_CTX *rx, char *dat FILESET_DBR fsr; CLIENT_DBR cr; char fileset_name[MAX_NAME_LENGTH]; - char ed1[50]; + char ed1[50], ed2[50]; char pool_select[MAX_NAME_LENGTH]; int i; @@ -956,19 +959,20 @@ static bool select_backups_before_date(UAContext *ua, RESTORE_CTX *rx, char *dat bstrncpy(fsr.FileSet, ua->argv[i], sizeof(fsr.FileSet)); if (!db_get_fileset_record(ua->jcr, ua->db, &fsr)) { bsendmsg(ua, _("Error getting FileSet \"%s\": ERR=%s\n"), fsr.FileSet, - db_strerror(ua->db)); - i = -1; + db_strerror(ua->db)); + i = -1; } } - if (i < 0) { /* fileset not found */ - Mmsg(rx->query, uar_sel_fileset, cr.ClientId, cr.ClientId); + if (i < 0) { /* fileset not found */ + edit_int64(cr.ClientId, ed1); + Mmsg(rx->query, uar_sel_fileset, ed1, ed1); start_prompt(ua, _("The defined FileSet resources are:\n")); if (!db_sql_query(ua->db, rx->query, fileset_handler, (void *)ua)) { bsendmsg(ua, "%s\n", db_strerror(ua->db)); } if (do_prompt(ua, _("FileSet"), _("Select FileSet resource"), - fileset_name, sizeof(fileset_name)) < 0) { - goto bail_out; + fileset_name, sizeof(fileset_name)) < 0) { + goto bail_out; } bstrncpy(fsr.FileSet, fileset_name, sizeof(fsr.FileSet)); @@ -983,20 +987,20 @@ static bool select_backups_before_date(UAContext *ua, RESTORE_CTX *rx, char *dat pool_select[0] = 0; if (rx->pool) { POOL_DBR pr; - char ed1[50]; memset(&pr, 0, sizeof(pr)); bstrncpy(pr.Name, rx->pool->hdr.name, sizeof(pr.Name)); if (db_get_pool_record(ua->jcr, ua->db, &pr)) { bsnprintf(pool_select, sizeof(pool_select), "AND Media.PoolId=%s ", - edit_int64(pr.PoolId, ed1)); + edit_int64(pr.PoolId, ed1)); } else { bsendmsg(ua, _("Pool \"%s\" not found, using any pool.\n"), pr.Name); } } /* Find JobId of last Full backup for this client, fileset */ - Mmsg(rx->query, uar_last_full, cr.ClientId, cr.ClientId, date, fsr.FileSet, - pool_select); + edit_int64(cr.ClientId, ed1); + Mmsg(rx->query, uar_last_full, ed1, ed1, date, fsr.FileSet, + pool_select); if (!db_sql_query(ua->db, rx->query, NULL, NULL)) { bsendmsg(ua, "%s\n", db_strerror(ua->db)); goto bail_out; @@ -1021,7 +1025,7 @@ static bool select_backups_before_date(UAContext *ua, RESTORE_CTX *rx, char *dat /* Now find most recent Differental Job after Full save, if any */ Mmsg(rx->query, uar_dif, edit_uint64(rx->JobTDate, ed1), date, - cr.ClientId, fsr.FileSet, pool_select); + edit_int64(cr.ClientId, ed2), fsr.FileSet, pool_select); if (!db_sql_query(ua->db, rx->query, NULL, NULL)) { bsendmsg(ua, "%s\n", db_strerror(ua->db)); } @@ -1037,7 +1041,7 @@ static bool select_backups_before_date(UAContext *ua, RESTORE_CTX *rx, char *dat /* Now find all Incremental Jobs after Full/dif save */ Mmsg(rx->query, uar_inc, edit_uint64(rx->JobTDate, ed1), date, - cr.ClientId, fsr.FileSet, pool_select); + edit_int64(cr.ClientId, ed2), fsr.FileSet, pool_select); if (!db_sql_query(ua->db, rx->query, NULL, NULL)) { bsendmsg(ua, "%s\n", db_strerror(ua->db)); } @@ -1073,10 +1077,10 @@ static int get_next_jobid_from_list(char **p, uint32_t *JobId) jobid[0] = 0; for (int i=0; i<(int)sizeof(jobid); i++) { if (*q == 0) { - break; + break; } else if (*q == ',') { - q++; - break; + q++; + break; } jobid[i] = *q++; jobid[i+1] = 0; @@ -1084,7 +1088,7 @@ static int get_next_jobid_from_list(char **p, uint32_t *JobId) if (jobid[0] == 0) { return 0; } else if (!is_a_number(jobid)) { - return -1; /* error */ + return -1; /* error */ } *p = q; *JobId = str_to_int64(jobid); @@ -1121,7 +1125,7 @@ static int jobid_handler(void *ctx, int num_fields, char **row) RESTORE_CTX *rx = (RESTORE_CTX *)ctx; if (strcmp(rx->last_jobid, row[0]) == 0) { - return 0; /* duplicate id */ + return 0; /* duplicate id */ } bstrncpy(rx->last_jobid, row[0], sizeof(rx->last_jobid)); if (rx->JobIds[0] != 0) { @@ -1170,16 +1174,16 @@ static int unique_name_list_handler(void *ctx, int num_fields, char **row) } if (name->num_ids == name->max_ids) { if (name->max_ids == 0) { - name->max_ids = 1000; - name->name = (char **)bmalloc(sizeof(char *) * name->max_ids); + name->max_ids = 1000; + name->name = (char **)bmalloc(sizeof(char *) * name->max_ids); } else { - name->max_ids = (name->max_ids * 3) / 2; - name->name = (char **)brealloc(name->name, sizeof(char *) * name->max_ids); + name->max_ids = (name->max_ids * 3) / 2; + name->name = (char **)brealloc(name->name, sizeof(char *) * name->max_ids); } } for (int i=0; inum_ids; i++) { if (strcmp(name->name[i], row[0]) == 0) { - return 0; /* already in list, return */ + return 0; /* already in list, return */ } } /* Add new name to list */ @@ -1241,10 +1245,10 @@ static void get_storage_from_mediatype(UAContext *ua, NAME_LIST *name_list, REST LockRes(); foreach_res(store, R_STORAGE) { if (strcmp(name_list->name[0], store->media_type) == 0) { - if (acl_access_ok(ua, Storage_ACL, store->hdr.name)) { - rx->store = store; - } - break; + if (acl_access_ok(ua, Storage_ACL, store->hdr.name)) { + rx->store = store; + } + break; } } UnlockRes(); @@ -1254,15 +1258,15 @@ static void get_storage_from_mediatype(UAContext *ua, NAME_LIST *name_list, REST store = NULL; int i = find_arg_with_value(ua, "storage"); if (i > 0) { - store = (STORE *)GetResWithName(R_STORAGE, ua->argv[i]); - if (store && !acl_access_ok(ua, Storage_ACL, store->hdr.name)) { - store = NULL; - } + store = (STORE *)GetResWithName(R_STORAGE, ua->argv[i]); + if (store && !acl_access_ok(ua, Storage_ACL, store->hdr.name)) { + store = NULL; + } } if (store && (store != rx->store)) { bsendmsg(ua, _("Warning default storage overridden by %s on command line.\n"), - store->hdr.name); - rx->store = store; + store->hdr.name); + rx->store = store; } return; } @@ -1274,6 +1278,6 @@ static void get_storage_from_mediatype(UAContext *ua, NAME_LIST *name_list, REST bsendmsg(ua, _("\nWarning. Unable to find Storage resource for\n" "MediaType \"%s\", needed by the Jobs you selected.\n" "You will be allowed to select a Storage device later.\n"), - name_list->name[0]); + name_list->name[0]); } } diff --git a/bacula/src/dird/ua_update.c b/bacula/src/dird/ua_update.c index 558fcf2402..a9b0567015 100644 --- a/bacula/src/dird/ua_update.c +++ b/bacula/src/dird/ua_update.c @@ -32,7 +32,7 @@ #include "dird.h" /* External variables */ -extern char *list_pool; /* in sql_cmds.c */ +extern char *list_pool; /* in sql_cmds.c */ /* Imported functions */ void set_pooldbr_from_poolres(POOL_DBR *pr, POOL *pool, e_pool_op op); @@ -48,11 +48,11 @@ static int update_pool(UAContext *ua); * It is always updated from the Resource record. * * update pool= - * updates pool from Pool resource + * updates pool from Pool resource * update media pool= volume= - * changes pool info for volume + * changes pool info for volume * update slots [scan=...] - * updates autochanger slots + * updates autochanger slots */ int update_cmd(UAContext *ua, const char *cmd) { @@ -120,8 +120,8 @@ static void update_volstatus(UAContext *ua, const char *val, MEDIA_DBR *mr) for (i=0; kw[i]; i++) { if (strcasecmp(val, kw[i]) == 0) { - found = true; - break; + found = true; + break; } } if (!found) { @@ -130,7 +130,7 @@ static void update_volstatus(UAContext *ua, const char *val, MEDIA_DBR *mr) char ed1[50]; bstrncpy(mr->VolStatus, kw[i], sizeof(mr->VolStatus)); Mmsg(query, "UPDATE Media SET VolStatus='%s' WHERE MediaId=%s", - mr->VolStatus, edit_int64(mr->MediaId,ed1)); + mr->VolStatus, edit_int64(mr->MediaId,ed1)); if (!db_sql_query(ua->db, query, NULL, NULL)) { bsendmsg(ua, "%s", db_strerror(ua->db)); } else { @@ -155,7 +155,7 @@ static void update_volretention(UAContext *ua, char *val, MEDIA_DBR *mr) bsendmsg(ua, "%s", db_strerror(ua->db)); } else { bsendmsg(ua, _("New retention period is: %s\n"), - edit_utime(mr->VolRetention, ed1, sizeof(ed1))); + edit_utime(mr->VolRetention, ed1, sizeof(ed1))); } free_pool_memory(query); } @@ -176,7 +176,7 @@ static void update_voluseduration(UAContext *ua, char *val, MEDIA_DBR *mr) bsendmsg(ua, "%s", db_strerror(ua->db)); } else { bsendmsg(ua, _("New use duration is: %s\n"), - edit_utime(mr->VolUseDuration, ed1, sizeof(ed1))); + edit_utime(mr->VolUseDuration, ed1, sizeof(ed1))); } free_pool_memory(query); } @@ -267,7 +267,7 @@ static void update_vol_pool(UAContext *ua, char *val, MEDIA_DBR *mr, POOL_DBR *o if (!get_pool_dbr(ua, &pr)) { return; } - mr->PoolId = pr.PoolId; /* set new PoolId */ + mr->PoolId = pr.PoolId; /* set new PoolId */ /* */ query = get_pool_memory(PM_MESSAGE); @@ -310,7 +310,7 @@ static void update_volfrompool(UAContext *ua, MEDIA_DBR *mr) bsendmsg(ua, _("Error updating Volume record: ERR=%s"), db_strerror(ua->db)); } else { bsendmsg(ua, _("Volume defaults updated from \"%s\" Pool record.\n"), - pr.Name); + pr.Name); } } @@ -368,54 +368,54 @@ static int update_volume(UAContext *ua) int j; POOL_DBR pr; if ((j=find_arg_with_value(ua, kw[i])) > 0) { - if (i != 9 && !select_media_dbr(ua, &mr)) { - return 0; - } - switch (i) { - case 0: - update_volstatus(ua, ua->argv[j], &mr); - break; - case 1: - update_volretention(ua, ua->argv[j], &mr); - break; - case 2: - update_voluseduration(ua, ua->argv[j], &mr); - break; - case 3: - update_volmaxjobs(ua, ua->argv[j], &mr); - break; - case 4: - update_volmaxfiles(ua, ua->argv[j], &mr); - break; - case 5: - update_volmaxbytes(ua, ua->argv[j], &mr); - break; - case 6: - update_volrecycle(ua, ua->argv[j], &mr); - break; - case 7: - memset(&pr, 0, sizeof(POOL_DBR)); - pr.PoolId = mr.PoolId; - if (!db_get_pool_record(ua->jcr, ua->db, &pr)) { + if (i != 9 && !select_media_dbr(ua, &mr)) { + return 0; + } + switch (i) { + case 0: + update_volstatus(ua, ua->argv[j], &mr); + break; + case 1: + update_volretention(ua, ua->argv[j], &mr); + break; + case 2: + update_voluseduration(ua, ua->argv[j], &mr); + break; + case 3: + update_volmaxjobs(ua, ua->argv[j], &mr); + break; + case 4: + update_volmaxfiles(ua, ua->argv[j], &mr); + break; + case 5: + update_volmaxbytes(ua, ua->argv[j], &mr); + break; + case 6: + update_volrecycle(ua, ua->argv[j], &mr); + break; + case 7: + memset(&pr, 0, sizeof(POOL_DBR)); + pr.PoolId = mr.PoolId; + if (!db_get_pool_record(ua->jcr, ua->db, &pr)) { bsendmsg(ua, "%s", db_strerror(ua->db)); - break; - } - update_vol_pool(ua, ua->argv[j], &mr, &pr); - break; - case 8: - update_volfrompool(ua, &mr); - return 1; - case 9: - update_all_vols_from_pool(ua); - return 1; - } - done = true; + break; + } + update_vol_pool(ua, ua->argv[j], &mr, &pr); + break; + case 8: + update_volfrompool(ua, &mr); + return 1; + case 9: + update_all_vols_from_pool(ua); + return 1; + } + done = true; } } for ( ; !done; ) { if (!select_media_dbr(ua, &mr)) { - return 0; + return 0; } bsendmsg(ua, _("Updating Volume \"%s\"\n"), mr.VolumeName); start_prompt(ua, _("Parameters to modify:\n")); @@ -434,8 +434,8 @@ static int update_volume(UAContext *ua) add_prompt(ua, _("All Volumes from Pool")); add_prompt(ua, _("Done")); switch (do_prompt(ua, "", _("Select parameter to modify"), NULL, 0)) { - case 0: /* Volume Status */ - /* Modify Volume Status */ + case 0: /* Volume Status */ + /* Modify Volume Status */ bsendmsg(ua, _("Current Volume status is: %s\n"), mr.VolStatus); start_prompt(ua, _("Possible Values are:\n")); add_prompt(ua, "Append"); /* Better not translate these as */ @@ -446,163 +446,163 @@ static int update_volume(UAContext *ua) add_prompt(ua, "Cleaning"); if (strcmp(mr.VolStatus, "Purged") == 0) { add_prompt(ua, "Recycle"); - } + } add_prompt(ua, "Read-Only"); if (do_prompt(ua, "", _("Choose new Volume Status"), ua->cmd, sizeof(mr.VolStatus)) < 0) { - return 1; - } - update_volstatus(ua, ua->cmd, &mr); - break; - case 1: /* Retention */ + return 1; + } + update_volstatus(ua, ua->cmd, &mr); + break; + case 1: /* Retention */ bsendmsg(ua, _("Current retention period is: %s\n"), - edit_utime(mr.VolRetention, ed1, sizeof(ed1))); + edit_utime(mr.VolRetention, ed1, sizeof(ed1))); if (!get_cmd(ua, _("Enter Volume Retention period: "))) { - return 0; - } - update_volretention(ua, ua->cmd, &mr); - break; + return 0; + } + update_volretention(ua, ua->cmd, &mr); + break; - case 2: /* Use Duration */ + case 2: /* Use Duration */ bsendmsg(ua, _("Current use duration is: %s\n"), - edit_utime(mr.VolUseDuration, ed1, sizeof(ed1))); + edit_utime(mr.VolUseDuration, ed1, sizeof(ed1))); if (!get_cmd(ua, _("Enter Volume Use Duration: "))) { - return 0; - } - update_voluseduration(ua, ua->cmd, &mr); - break; + return 0; + } + update_voluseduration(ua, ua->cmd, &mr); + break; - case 3: /* Max Jobs */ + case 3: /* Max Jobs */ bsendmsg(ua, _("Current max jobs is: %u\n"), mr.MaxVolJobs); if (!get_pint(ua, _("Enter new Maximum Jobs: "))) { - return 0; - } - update_volmaxjobs(ua, ua->cmd, &mr); - break; + return 0; + } + update_volmaxjobs(ua, ua->cmd, &mr); + break; - case 4: /* Max Files */ + case 4: /* Max Files */ bsendmsg(ua, _("Current max files is: %u\n"), mr.MaxVolFiles); if (!get_pint(ua, _("Enter new Maximum Files: "))) { - return 0; - } - update_volmaxfiles(ua, ua->cmd, &mr); - break; + return 0; + } + update_volmaxfiles(ua, ua->cmd, &mr); + break; - case 5: /* Max Bytes */ + case 5: /* Max Bytes */ bsendmsg(ua, _("Current value is: %s\n"), edit_uint64(mr.MaxVolBytes, ed1)); if (!get_cmd(ua, _("Enter new Maximum Bytes: "))) { - return 0; - } - update_volmaxbytes(ua, ua->cmd, &mr); - break; + return 0; + } + update_volmaxbytes(ua, ua->cmd, &mr); + break; - case 6: /* Recycle */ + case 6: /* Recycle */ bsendmsg(ua, _("Current recycle flag is: %s\n"), mr.Recycle==1?_("yes"):_("no")); if (!get_yesno(ua, _("Enter new Recycle status: "))) { - return 0; - } - update_volrecycle(ua, ua->cmd, &mr); - break; + return 0; + } + update_volrecycle(ua, ua->cmd, &mr); + break; - case 7: /* Slot */ - int Slot; + case 7: /* Slot */ + int Slot; - memset(&pr, 0, sizeof(POOL_DBR)); - pr.PoolId = mr.PoolId; - if (!db_get_pool_record(ua->jcr, ua->db, &pr)) { + memset(&pr, 0, sizeof(POOL_DBR)); + pr.PoolId = mr.PoolId; + if (!db_get_pool_record(ua->jcr, ua->db, &pr)) { bsendmsg(ua, "%s", db_strerror(ua->db)); - return 0; - } + return 0; + } bsendmsg(ua, _("Current Slot is: %d\n"), mr.Slot); if (!get_pint(ua, _("Enter new Slot: "))) { - return 0; - } - Slot = ua->pint32_val; - if (pr.MaxVols > 0 && Slot > (int)pr.MaxVols) { + return 0; + } + Slot = ua->pint32_val; + if (pr.MaxVols > 0 && Slot > (int)pr.MaxVols) { bsendmsg(ua, _("Invalid slot, it must be between 0 and %d\n"), - pr.MaxVols); - break; - } - mr.Slot = Slot; - /* - * Make sure to use db_update... rather than doing this directly, - * so that any Slot is handled correctly. - */ - if (!db_update_media_record(ua->jcr, ua->db, &mr)) { + pr.MaxVols); + break; + } + mr.Slot = Slot; + /* + * Make sure to use db_update... rather than doing this directly, + * so that any Slot is handled correctly. + */ + if (!db_update_media_record(ua->jcr, ua->db, &mr)) { bsendmsg(ua, _("Error updating media record Slot: ERR=%s"), db_strerror(ua->db)); - } else { + } else { bsendmsg(ua, _("New Slot is: %d\n"), mr.Slot); - } - break; + } + break; - case 8: /* InChanger */ + case 8: /* InChanger */ bsendmsg(ua, _("Current InChanger flag is: %d\n"), mr.InChanger); if (!get_yesno(ua, _("Set InChanger flag? yes/no: "))) { - return 0; - } - mr.InChanger = ua->pint32_val; - /* - * Make sure to use db_update... rather than doing this directly, - * so that any Slot is handled correctly. - */ - if (!db_update_media_record(ua->jcr, ua->db, &mr)) { + return 0; + } + mr.InChanger = ua->pint32_val; + /* + * Make sure to use db_update... rather than doing this directly, + * so that any Slot is handled correctly. + */ + if (!db_update_media_record(ua->jcr, ua->db, &mr)) { bsendmsg(ua, _("Error updating media record Slot: ERR=%s"), db_strerror(ua->db)); - } else { + } else { bsendmsg(ua, _("New InChanger flag is: %d\n"), mr.InChanger); - } - break; + } + break; - case 9: /* Volume Files */ - int32_t VolFiles; + case 9: /* Volume Files */ + int32_t VolFiles; bsendmsg(ua, _("Warning changing Volume Files can result\n" "in loss of data on your Volume\n\n")); bsendmsg(ua, _("Current Volume Files is: %u\n"), mr.VolFiles); if (!get_pint(ua, _("Enter new number of Files for Volume: "))) { - return 0; - } - VolFiles = ua->pint32_val; - if (VolFiles != (int)(mr.VolFiles + 1)) { + return 0; + } + VolFiles = ua->pint32_val; + if (VolFiles != (int)(mr.VolFiles + 1)) { bsendmsg(ua, _("Normally, you should only increase Volume Files by one!\n")); if (!get_yesno(ua, _("Continue? (yes/no): ")) || ua->pint32_val == 0) { - break; - } - } - query = get_pool_memory(PM_MESSAGE); + break; + } + } + query = get_pool_memory(PM_MESSAGE); Mmsg(query, "UPDATE Media SET VolFiles=%u WHERE MediaId=%s", - VolFiles, edit_int64(mr.MediaId, ed1)); - if (!db_sql_query(ua->db, query, NULL, NULL)) { + VolFiles, edit_int64(mr.MediaId, ed1)); + if (!db_sql_query(ua->db, query, NULL, NULL)) { bsendmsg(ua, "%s", db_strerror(ua->db)); - } else { + } else { bsendmsg(ua, _("New Volume Files is: %u\n"), VolFiles); - } - free_pool_memory(query); - break; + } + free_pool_memory(query); + break; case 10: /* Volume's Pool */ - memset(&pr, 0, sizeof(POOL_DBR)); - pr.PoolId = mr.PoolId; - if (!db_get_pool_record(ua->jcr, ua->db, &pr)) { + memset(&pr, 0, sizeof(POOL_DBR)); + pr.PoolId = mr.PoolId; + if (!db_get_pool_record(ua->jcr, ua->db, &pr)) { bsendmsg(ua, "%s", db_strerror(ua->db)); - return 0; - } + return 0; + } bsendmsg(ua, _("Current Pool is: %s\n"), pr.Name); if (!get_cmd(ua, _("Enter new Pool name: "))) { - return 0; - } - update_vol_pool(ua, ua->cmd, &mr, &pr); - return 1; + return 0; + } + update_vol_pool(ua, ua->cmd, &mr, &pr); + return 1; case 11: - update_volfrompool(ua, &mr); - return 1; + update_volfrompool(ua, &mr); + return 1; case 12: - update_all_vols_from_pool(ua); - return 1; - default: /* Done or error */ + update_all_vols_from_pool(ua); + return 1; + default: /* Done or error */ bsendmsg(ua, "Selection done.\n"); - return 1; + return 1; } } return 1; @@ -617,6 +617,7 @@ static int update_pool(UAContext *ua) int id; POOL *pool; POOLMEM *query; + char ed1[50]; pool = get_pool_resource(ua); if (!pool) { @@ -634,10 +635,10 @@ static int update_pool(UAContext *ua) id = db_update_pool_record(ua->jcr, ua->db, &pr); if (id <= 0) { bsendmsg(ua, _("db_update_pool_record returned %d. ERR=%s\n"), - id, db_strerror(ua->db)); + id, db_strerror(ua->db)); } query = get_pool_memory(PM_MESSAGE); - Mmsg(query, list_pool, pr.PoolId); + Mmsg(query, list_pool, edit_int64(pr.PoolId, ed1)); db_list_sql_query(ua->jcr, ua->db, query, prtit, ua, 1, HORZ_LIST); free_pool_memory(query); bsendmsg(ua, _("Pool DB record updated from resource.\n")); diff --git a/bacula/src/filed/backup.c b/bacula/src/filed/backup.c index 542a032fa6..3fbc4ea19a 100644 --- a/bacula/src/filed/backup.c +++ b/bacula/src/filed/backup.c @@ -240,7 +240,9 @@ static int save_file(FF_PKT *ff_pkt, void *vjcr, bool top_level) set_portable_backup(&ff_pkt->bfd); /* disable Win32 BackupRead() */ } if (ff_pkt->reader) { - set_prog(&ff_pkt->bfd, ff_pkt->reader, jcr); + if (!set_prog(&ff_pkt->bfd, ff_pkt->reader, jcr)) { + return 0; + } } /* diff --git a/bacula/src/filed/filed.c b/bacula/src/filed/filed.c index 49a3350aae..9fdd1983f7 100644 --- a/bacula/src/filed/filed.c +++ b/bacula/src/filed/filed.c @@ -231,7 +231,7 @@ int main (int argc, char *argv[]) #endif init_python_interpreter(me->hdr.name, me->scripts_directory ? - me->scripts_directory : "."); + me->scripts_directory : ".", "FDStartUp"); set_thread_concurrency(10); diff --git a/bacula/src/filed/filed.h b/bacula/src/filed/filed.h index 7902f45df9..4137317ee9 100644 --- a/bacula/src/filed/filed.h +++ b/bacula/src/filed/filed.h @@ -6,7 +6,7 @@ * Version $Id$ */ /* - Copyright (C) 2000-2004 Kern Sibbald and John Walker + Copyright (C) 2000-2005 Kern Sibbald This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/bacula/src/filed/python.c b/bacula/src/filed/python.c index 4619cfa2c3..c63a7c4c1c 100644 --- a/bacula/src/filed/python.c +++ b/bacula/src/filed/python.c @@ -36,24 +36,36 @@ #include extern JCR *get_jcr_from_PyObject(PyObject *self); +extern PyObject *find_method(PyObject *eventsObject, PyObject *method, char *name); -PyObject *bacula_get(PyObject *self, PyObject *args); -PyObject *bacula_set(PyObject *self, PyObject *args, PyObject *keyw); +static PyObject *jcr_get(PyObject *self, PyObject *args); +static PyObject *jcr_write(PyObject *self, PyObject *args); +static PyObject *jcr_set(PyObject *self, PyObject *args, PyObject *keyw); +static PyObject *set_jcr_events(PyObject *self, PyObject *args); -/* Define Bacula entry points */ -PyMethodDef BaculaMethods[] = { - {"get", bacula_get, METH_VARARGS, "Get Bacula FD variables."}, - {"set", (PyCFunction)bacula_set, METH_VARARGS|METH_KEYWORDS, - "Set FD Bacula variables."}, + +/* Define Job entry points */ +PyMethodDef JobMethods[] = { + {"get", jcr_get, METH_VARARGS, "Get Job variables."}, + {"set", (PyCFunction)jcr_set, METH_VARARGS|METH_KEYWORDS, + "Set Job variables."}, + {"set_events", set_jcr_events, METH_VARARGS, "Define Job events."}, + {"write", jcr_write, METH_VARARGS, "Write output."}, {NULL, NULL, 0, NULL} /* last item */ }; +static PyObject *open_method = NULL; +static PyObject *read_method = NULL; +static PyObject *close_method = NULL; + + struct s_vars { const char *name; char *fmt; }; +/* Read-only variables */ static struct s_vars vars[] = { { N_("FDName"), "s"}, /* 0 */ { N_("Level"), "s"}, /* 1 */ @@ -66,8 +78,8 @@ static struct s_vars vars[] = { { NULL, NULL} }; -/* Return Bacula variables */ -PyObject *bacula_get(PyObject *self, PyObject *args) +/* Return Job variables */ +PyObject *jcr_get(PyObject *self, PyObject *args) { JCR *jcr; char *item; @@ -109,24 +121,97 @@ PyObject *bacula_get(PyObject *self, PyObject *args) return NULL; } -/* Set Bacula variables */ -PyObject *bacula_set(PyObject *self, PyObject *args, PyObject *keyw) +/* Set Job variables */ +PyObject *jcr_set(PyObject *self, PyObject *args, PyObject *keyw) { JCR *jcr; char *msg = NULL; - static char *kwlist[] = {"JobReport", NULL}; + PyObject *fo = NULL, *fr = NULL, *fc = NULL; + static char *kwlist[] = {"JobReport", + "FileOpen", "FileRead", "FileClose", + NULL}; - if (!PyArg_ParseTupleAndKeywords(args, keyw, "|s:set", kwlist, - &msg)) { + if (!PyArg_ParseTupleAndKeywords(args, keyw, "|sOOO:set", kwlist, + &msg, &fo, &fr, &fc)) { return NULL; } jcr = get_jcr_from_PyObject(self); - if (msg) { Jmsg(jcr, M_INFO, 0, "%s", msg); } + if (strcmp("Reader", jcr->event) == 0) { + if (fo) { + if (PyCallable_Check(fo)) { + jcr->ff->bfd.pio.fo = fo; + } else { + Jmsg(jcr, M_ERROR, 0, _("Python FileOpen object not callable.\n")); + } + } + if (fr) { + if (PyCallable_Check(fo)) { + jcr->ff->bfd.pio.fr = fr; + } else { + Jmsg(jcr, M_ERROR, 0, _("Python FileRead object not callable.\n")); + } + } + if (fc) { + if (PyCallable_Check(fc)) { + jcr->ff->bfd.pio.fc = fc; + } else { + Jmsg(jcr, M_ERROR, 0, _("Python FileClose object not callable.\n")); + } + } + } return Py_BuildValue("i", 1); } + +static PyObject *set_jcr_events(PyObject *self, PyObject *args) +{ + PyObject *eObject; + JCR *jcr; + if (!PyArg_ParseTuple(args, "O:set_events_hook", &eObject)) { + return NULL; + } + Py_XINCREF(eObject); + jcr = get_jcr_from_PyObject(self); + jcr->ff->bfd.pio.fo = find_method(eObject, open_method, "open"); + jcr->ff->bfd.pio.fr = find_method(eObject, read_method, "read"); + jcr->ff->bfd.pio.fc = find_method(eObject, close_method, "close"); + Py_INCREF(Py_None); + return Py_None; +} + +/* Write text to job output */ +static PyObject *jcr_write(PyObject *self, PyObject *args) +{ + char *text; + if (!PyArg_ParseTuple(args, "s:write", &text)) { + return NULL; + } + if (text) { + JCR *jcr = get_jcr_from_PyObject(self); + Jmsg(jcr, M_INFO, 0, "%s", text); + } + + Py_INCREF(Py_None); + return Py_None; +} + +int generate_job_event(JCR *jcr, const char *event) +{ + PyEval_AcquireLock(); + + PyObject *result = PyObject_CallFunction(open_method, "s", "m.py"); + if (result == NULL) { + PyErr_Print(); + PyErr_Clear(); + } + Py_XDECREF(result); + + PyEval_ReleaseLock(); + return 1; +} + #endif /* HAVE_PYTHON */ diff --git a/bacula/src/findlib/Makefile.in b/bacula/src/findlib/Makefile.in index 00bad4adf7..a9c5c44103 100644 --- a/bacula/src/findlib/Makefile.in +++ b/bacula/src/findlib/Makefile.in @@ -3,6 +3,8 @@ # @MCOMMON@ +python = @PYTHON_INCDIR@ + srcdir = . VPATH = . .PATH: . @@ -31,7 +33,7 @@ LIBOBJS = find.o match.o find_one.o attribs.o create_file.o \ # inference rules .c.o: - $(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) -I$(srcdir) -I$(basedir) $(DINCLUDE) $(CFLAGS) $< + $(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(PYTHON_INC) -I$(srcdir) -I$(basedir) $(DINCLUDE) $(CFLAGS) $< #------------------------------------------------------------------------- all: Makefile libfind.a ../lib/libbac.a @echo "==== Make of findlib is good ====" @@ -81,7 +83,7 @@ depend: @$(MV) Makefile Makefile.bak @$(SED) "/^# DO NOT DELETE:/,$$ d" Makefile.bak > Makefile @$(ECHO) "# DO NOT DELETE: nice dependency list follows" >> Makefile - @$(CXX) -S -M $(CPPFLAGS) $(XINC) -I$(srcdir) -I$(basedir) $(SQL_INC) *.c >> Makefile + @$(CXX) -S -M $(CPPFLAGS) $(XINC) $(PYTHON_INC) -I$(srcdir) -I$(basedir) $(SQL_INC) *.c >> Makefile @if test -f Makefile ; then \ $(RMF) Makefile.bak; \ else \ diff --git a/bacula/src/findlib/bfile.c b/bacula/src/findlib/bfile.c index 66da2eb80e..3ddc1d88bb 100644 --- a/bacula/src/findlib/bfile.c +++ b/bacula/src/findlib/bfile.c @@ -31,6 +31,8 @@ #include "bacula.h" #include "find.h" +extern int generate_job_event(JCR *jcr, const char *event); + #ifdef HAVE_DARWIN_OS #include #endif @@ -42,14 +44,14 @@ * =============================================================== */ -int is_win32_stream(int stream) +bool is_win32_stream(int stream) { switch (stream) { case STREAM_WIN32_DATA: case STREAM_WIN32_GZIP_DATA: - return 1; + return true; } - return 0; + return false; } const char *stream_to_ascii(int stream) @@ -120,7 +122,7 @@ void binit(BFILE *bfd) * Returns 1 if function worked * Returns 0 if failed (i.e. do not have Backup API on this machine) */ -int set_win32_backup(BFILE *bfd) +bool set_win32_backup(BFILE *bfd) { /* We enable if possible here */ bfd->use_backup_api = have_win32_api(); @@ -128,28 +130,29 @@ int set_win32_backup(BFILE *bfd) } -int set_portable_backup(BFILE *bfd) +bool set_portable_backup(BFILE *bfd) { - bfd->use_backup_api = 0; - return 1; + bfd->use_backup_api = false; + return true; } -void set_prog(BFILE *bfd, char *prog, JCR *jcr) +bool set_prog(BFILE *bfd, char *prog, JCR *jcr) { bfd->prog = prog; bfd->jcr = jcr; + return false; } /* * Return 1 if we are NOT using Win32 BackupWrite() * return 0 if are */ -int is_portable_backup(BFILE *bfd) +bool is_portable_backup(BFILE *bfd) { return !bfd->use_backup_api; } -int have_win32_api() +bool have_win32_api() { return p_BackupRead && p_BackupWrite; } @@ -160,7 +163,7 @@ int have_win32_api() * Return 1 if we support the stream * 0 if we do not support the stream */ -int is_stream_supported(int stream) +bool is_stream_supported(int stream) { /* No Win32 backup on this machine */ switch (stream) { @@ -173,6 +176,10 @@ int is_stream_supported(int stream) case STREAM_WIN32_GZIP_DATA: return have_win32_api(); + case STREAM_MACOS_FORK_DATA: + case STREAM_HFSPLUS_ATTRIBUTES: + return false; + /* Known streams */ #ifdef HAVE_LIBZ case STREAM_GZIP_DATA: @@ -186,14 +193,10 @@ int is_stream_supported(int stream) case STREAM_PROGRAM_NAMES: case STREAM_PROGRAM_DATA: case STREAM_SHA1_SIGNATURE: -#ifdef HAVE_DARWIN_OS - case STREAM_MACOS_FORK_DATA: - case STREAM_HFSPLUS_ATTRIBUTES: -#endif case 0: /* compatibility with old tapes */ - return 1; + return true; } - return 0; + return false; } HANDLE bget_handle(BFILE *bfd) @@ -394,7 +397,7 @@ ssize_t bwrite(BFILE *bfd, void *buf, size_t count) return (ssize_t)bfd->rw_bytes; } -int is_bopen(BFILE *bfd) +bool is_bopen(BFILE *bfd) { return bfd->mode != BF_CLOSED; } @@ -419,44 +422,54 @@ void binit(BFILE *bfd) bfd->fid = -1; } -int have_win32_api() +bool have_win32_api() { - return 0; /* no can do */ + return false; /* no can do */ } /* * Enables using the Backup API (win32_data). - * Returns 1 if function worked - * Returns 0 if failed (i.e. do not have Backup API on this machine) + * Returns true if function worked + * Returns false if failed (i.e. do not have Backup API on this machine) */ -int set_win32_backup(BFILE *bfd) +bool set_win32_backup(BFILE *bfd) { - return 0; /* no can do */ + return false; /* no can do */ } -int set_portable_backup(BFILE *bfd) +bool set_portable_backup(BFILE *bfd) { - return 1; /* no problem */ + return true; /* no problem */ } /* - * Return 1 if we are writing in portable format - * return 0 if not + * Return true if we are writing in portable format + * return false if not */ -int is_portable_backup(BFILE *bfd) +bool is_portable_backup(BFILE *bfd) { - return 1; /* portable by definition */ + return true; /* portable by definition */ } -void set_prog(BFILE *bfd, char *prog, JCR *jcr) +bool set_prog(BFILE *bfd, char *prog, JCR *jcr) { - bfd->prog = prog; - bfd->jcr = jcr; + if (bfd->prog && strcmp(prog, bfd->prog) == 0) { + return true; /* already setup */ + } + int stat = generate_job_event(jcr, "Reader"); + if (stat == 1 && bfd->pio.fo && bfd->pio.fr && bfd->pio.fc) { + bfd->prog = prog; + bfd->jcr = jcr; + return true; + } + bfd->prog = NULL; + return false; + } -int is_stream_supported(int stream) +bool is_stream_supported(int stream) { /* No Win32 backup on this machine */ switch (stream) { @@ -466,7 +479,11 @@ int is_stream_supported(int stream) #endif case STREAM_WIN32_DATA: case STREAM_WIN32_GZIP_DATA: - return 0; +#ifndef HAVE_DARWIN_OS + case STREAM_MACOS_FORK_DATA: + case STREAM_HFSPLUS_ATTRIBUTES: +#endif + return false; /* Known streams */ #ifdef HAVE_LIBZ @@ -486,15 +503,13 @@ int is_stream_supported(int stream) case STREAM_HFSPLUS_ATTRIBUTES: #endif case 0: /* compatibility with old tapes */ - return 1; + return true; } return 0; } -int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode) -{ - /* Open reader/writer program */ +/* Old file reader code */ #ifdef xxx if (bfd->prog) { POOLMEM *ecmd = get_pool_memory(PM_FNAME); @@ -523,6 +538,15 @@ int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode) } #endif + +int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode) +{ + /* Open reader/writer program */ + if (bfd->prog) { + errno = 0; + return 1; + } + /* Normal file open */ bfd->fid = open(fname, flags, mode); bfd->berrno = errno; @@ -549,14 +573,7 @@ int bopen_rsrc(BFILE *bfd, const char *fname, int flags, mode_t mode) } #endif -int bclose(BFILE *bfd) -{ - int stat; - Dmsg1(400, "Close file %d\n", bfd->fid); - if (bfd->fid == -1) { - return 0; - } - /* Close reader/writer program */ +/* Old prog close code */ #ifdef xxx if (bfd->prog && bfd->bpipe) { stat = close_bpipe(bfd->bpipe); @@ -567,6 +584,19 @@ int bclose(BFILE *bfd) } #endif + +int bclose(BFILE *bfd) +{ + int stat; + Dmsg1(400, "Close file %d\n", bfd->fid); + if (bfd->fid == -1) { + return 0; + } + /* Close reader/writer program */ + if (bfd->prog) { + return 0; + } + /* Close normal file */ stat = close(bfd->fid); bfd->berrno = errno; @@ -590,7 +620,7 @@ ssize_t bwrite(BFILE *bfd, void *buf, size_t count) return stat; } -int is_bopen(BFILE *bfd) +bool is_bopen(BFILE *bfd) { return bfd->fid >= 0; } @@ -603,10 +633,4 @@ off_t blseek(BFILE *bfd, off_t offset, int whence) return pos; } -/* DO NOT USE */ -char *xberror(BFILE *bfd) -{ - return strerror(bfd->berrno); -} - #endif diff --git a/bacula/src/findlib/bfile.h b/bacula/src/findlib/bfile.h index 4d4c25b555..544b596311 100644 --- a/bacula/src/findlib/bfile.h +++ b/bacula/src/findlib/bfile.h @@ -6,7 +6,7 @@ * Kern Sibbald May MMIII */ /* - Copyright (C) 2000-2004 Kern Sibbald and John Walker + Copyright (C) 2000-2005 Kern Sibbald This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -28,6 +28,19 @@ #ifndef __BFILE_H #define __BFILE_H +#ifdef HAVE_PYTHON +#undef _POSIX_C_SOURCE +#include +struct Python_IO { + PyObject *fo; + PyObject *fr; + PyObject *fc; +}; +#else +struct Python_IO { +}; +#endif + /* ======================================================= * * W I N D O W S @@ -47,7 +60,7 @@ enum { /* In bfile.c */ -/* Basic low level I/O file packet */ +/* Basic Win32 low level I/O file packet */ struct BFILE { int use_backup_api; /* set if using BackupRead/Write */ int mode; /* set if file is open */ @@ -59,8 +72,8 @@ struct BFILE { DWORD lerror; /* Last error code */ int berrno; /* errno */ char *prog; /* reader/writer program if any */ - BPIPE *bpipe; /* pipe for reader */ JCR *jcr; /* jcr for editing job codes */ + Python_IO pio; /* Python I/O routines */ }; HANDLE bget_handle(BFILE *bfd); @@ -74,26 +87,26 @@ HANDLE bget_handle(BFILE *bfd); * ======================================================= */ -/* Basic low level I/O file packet */ +/* Basic Unix low level I/O file packet */ struct BFILE { int fid; /* file id on Unix */ int berrno; char *prog; /* reader/writer program if any */ - BPIPE *bpipe; /* pipe for reader */ JCR *jcr; /* jcr for editing job codes */ + Python_IO pio; /* Python I/O routines */ }; #endif void binit(BFILE *bfd); -int is_bopen(BFILE *bfd); -int set_win32_backup(BFILE *bfd); -int set_portable_backup(BFILE *bfd); -void set_prog(BFILE *bfd, char *prog, JCR *jcr); -int have_win32_api(); -int is_portable_backup(BFILE *bfd); -int is_stream_supported(int stream); -int is_win32_stream(int stream); +bool is_bopen(BFILE *bfd); +bool set_win32_backup(BFILE *bfd); +bool set_portable_backup(BFILE *bfd); +bool set_prog(BFILE *bfd, char *prog, JCR *jcr); +bool have_win32_api(); +bool is_portable_backup(BFILE *bfd); +bool is_stream_supported(int stream); +bool is_win32_stream(int stream); char *xberror(BFILE *bfd); /* DO NOT USE -- use berrno class */ int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode); #ifdef HAVE_DARWIN_OS diff --git a/bacula/src/jcr.h b/bacula/src/jcr.h index 5accb7efb6..6cccbdcd02 100644 --- a/bacula/src/jcr.h +++ b/bacula/src/jcr.h @@ -90,8 +90,10 @@ #define SD_APPEND 1 #define SD_READ 0 - +/* Forward referenced structures */ struct JCR; +struct FF_PKT; + typedef void (JCR_free_HANDLER)(JCR *jcr); /* Job Control Record (JCR) */ @@ -112,6 +114,7 @@ struct JCR { POOLMEM *VolumeName; /* Volume name desired -- pool_memory */ POOLMEM *errmsg; /* edited error message */ char Job[MAX_NAME_LENGTH]; /* Unique name of this Job */ + char event[MAX_NAME_LENGTH]; /* Current event */ uint32_t JobId; /* Director's JobId */ uint32_t VolSessionId; uint32_t VolSessionTime; @@ -140,6 +143,7 @@ struct JCR { bool prefix_links; /* Prefix links with Where path */ bool gui; /* set if gui using console */ bool authenticated; /* set when client authenticated */ + void *Python_jcr; /* Python Job Object */ /* Daemon specific part of JCR */ /* This should be empty in the library */ @@ -209,7 +213,7 @@ struct JCR { int32_t compress_buf_size; /* Length of compression buffer */ int replace; /* Replace options */ int buf_size; /* length of buffer */ - void *ff; /* Find Files packet */ + FF_PKT *ff; /* Find Files packet */ char stored_addr[MAX_NAME_LENGTH]; /* storage daemon address */ uint32_t StartFile; uint32_t EndFile; diff --git a/bacula/src/lib/Makefile.in b/bacula/src/lib/Makefile.in index 9aa98beb0d..47b9c2d2d0 100644 --- a/bacula/src/lib/Makefile.in +++ b/bacula/src/lib/Makefile.in @@ -1,17 +1,6 @@ # $Id$ @MCOMMON@ -CWEB = @CWEB@ -CTANGLE = $(CWEB)/ctangle -CWEAVE = $(CWEB)/cweave -TEXINPUTS = TEXINPUTS=.:$(CWEB): - -# FIXME -- These should be found by autoconf -TEX = tex -PDFTEX = pdftex -XDVI = xdvi -DVIPS = dvips - python = @PYTHON_INCDIR@ srcdir = . @@ -28,8 +17,6 @@ thisdir = src/lib DEBUG=@DEBUG@ -GMP_INC=@GMP_INC@ - first_rule: all dummy: @@ -66,25 +53,10 @@ EXTRAOBJS = @OBJLIST@ # inference rules .c.o: - $(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) -I$(srcdir) -I$(basedir) $(DINCLUDE) $(CFLAGS) $< + $(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(PYTHON_INC) -I$(srcdir) -I$(basedir) $(DINCLUDE) $(CFLAGS) $< .cc.o: - $(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) -I$(srcdir) -I$(basedir) $(DINCLUDE) $(CFLAGS) $< - -.w.c: - $(CTANGLE) $< - -.w.tex: - $(CWEAVE) $< - -.tex.dvi: - ( $(TEXINPUTS) ; export TEXINPUTS; $(TEX) $< ) - -.tex.pdf: - ( $(TEXINPUTS) ; export TEXINPUTS; $(PDFTEX) $< ) - -.dvi.view: - $(XDVI) -s 0 $< + $(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(PYTHON_INC) -I$(srcdir) -I$(basedir) $(DINCLUDE) $(CFLAGS) $< #------------------------------------------------------------------------- all: Makefile libbac.a @@ -149,7 +121,7 @@ depend: @$(MV) Makefile Makefile.bak @$(SED) "/^# DO NOT DELETE:/,$$ d" Makefile.bak > Makefile @$(ECHO) "# DO NOT DELETE: nice dependency list follows" >> Makefile - @$(CXX) -S -M $(CPPFLAGS) $(XINC) $(python) -I$(srcdir) -I$(basedir) $(SQL_INC) *.c >> Makefile + @$(CXX) -S -M $(CPPFLAGS) $(XINC) $(PYTHON_INC) -I$(srcdir) -I$(basedir) $(SQL_INC) *.c >> Makefile @if test -f Makefile ; then \ $(RMF) Makefile.bak; \ else \ diff --git a/bacula/src/lib/jcr.c b/bacula/src/lib/jcr.c index 01b8c85bff..44a0e48488 100755 --- a/bacula/src/lib/jcr.c +++ b/bacula/src/lib/jcr.c @@ -43,8 +43,8 @@ int num_jobs_run; dlist *last_jobs = NULL; const int max_last_jobs = 10; -JCR *jobs = NULL; /* pointer to JCR chain */ -static brwlock_t lock; /* lock for last jobs and JCR chain */ +JCR *jobs = NULL; /* pointer to JCR chain */ +static brwlock_t lock; /* lock for last jobs and JCR chain */ void init_last_jobs_list() { @@ -54,7 +54,7 @@ void init_last_jobs_list() last_jobs = New(dlist(job_entry, &job_entry->link)); if ((errstat=rwl_init(&lock)) != 0) { Emsg1(M_ABORT, 0, _("Unable to initialize jcr_chain lock. ERR=%s\n"), - strerror(errstat)); + strerror(errstat)); } } @@ -64,9 +64,9 @@ void term_last_jobs_list() { if (last_jobs) { while (!last_jobs->empty()) { - void *je = last_jobs->first(); - last_jobs->remove(je); - free(je); + void *je = last_jobs->first(); + last_jobs->remove(je); + free(je); } delete last_jobs; last_jobs = NULL; @@ -93,20 +93,20 @@ void read_last_jobs_list(int fd, uint64_t addr) for ( ; num; num--) { if (read(fd, &job, sizeof(job)) != sizeof(job)) { Dmsg1(000, "Read job entry. ERR=%s\n", strerror(errno)); - return; + return; } if (job.JobId > 0) { - je = (struct s_last_job *)malloc(sizeof(struct s_last_job)); - memcpy((char *)je, (char *)&job, sizeof(job)); - if (!last_jobs) { - init_last_jobs_list(); - } - last_jobs->append(je); - if (last_jobs->size() > max_last_jobs) { - je = (struct s_last_job *)last_jobs->first(); - last_jobs->remove(je); - free(je); - } + je = (struct s_last_job *)malloc(sizeof(struct s_last_job)); + memcpy((char *)je, (char *)&job, sizeof(job)); + if (!last_jobs) { + init_last_jobs_list(); + } + last_jobs->append(je); + if (last_jobs->size() > max_last_jobs) { + je = (struct s_last_job *)last_jobs->first(); + last_jobs->remove(je); + free(je); + } } } } @@ -125,13 +125,13 @@ uint64_t write_last_jobs_list(int fd, uint64_t addr) num = last_jobs->size(); if (write(fd, &num, sizeof(num)) != sizeof(num)) { Dmsg1(000, "Error writing num_items: ERR=%s\n", strerror(errno)); - return 0; + return 0; } foreach_dlist(je, last_jobs) { - if (write(fd, je, sizeof(struct s_last_job)) != sizeof(struct s_last_job)) { + if (write(fd, je, sizeof(struct s_last_job)) != sizeof(struct s_last_job)) { Dmsg1(000, "Error writing job: ERR=%s\n", strerror(errno)); - return 0; - } + return 0; + } } } /* Return current address */ @@ -206,7 +206,7 @@ JCR *new_jcr(int size, JCR_free_HANDLER *daemon_free_jcr) /* Setup some dummy values */ bstrncpy(jcr->Job, "*System*", sizeof(jcr->Job)); jcr->JobId = 0; - jcr->JobType = JT_SYSTEM; /* internal job until defined */ + jcr->JobType = JT_SYSTEM; /* internal job until defined */ jcr->JobLevel = L_NONE; jcr->JobStatus = JS_Created; @@ -230,7 +230,7 @@ JCR *new_jcr(int size, JCR_free_HANDLER *daemon_free_jcr) /* * Remove a JCR from the chain * NOTE! The chain must be locked prior to calling - * this routine. + * this routine. */ static void remove_jcr(JCR *jcr) { @@ -238,8 +238,8 @@ static void remove_jcr(JCR *jcr) if (!jcr) { Emsg0(M_ABORT, 0, "NULL jcr.\n"); } - if (!jcr->prev) { /* if no prev */ - jobs = jcr->next; /* set new head */ + if (!jcr->prev) { /* if no prev */ + jobs = jcr->next; /* set new head */ } else { jcr->prev->next = jcr->next; /* update prev */ } @@ -278,17 +278,17 @@ static void free_common_jcr(JCR *jcr) last_job.end_time = time(NULL); /* Keep list of last jobs, but not Console where JobId==0 */ if (last_job.JobId > 0) { - je = (struct s_last_job *)malloc(sizeof(struct s_last_job)); - memcpy((char *)je, (char *)&last_job, sizeof(last_job)); - if (!last_jobs) { - init_last_jobs_list(); - } - last_jobs->append(je); - if (last_jobs->size() > max_last_jobs) { - je = (struct s_last_job *)last_jobs->first(); - last_jobs->remove(je); - free(je); - } + je = (struct s_last_job *)malloc(sizeof(struct s_last_job)); + memcpy((char *)je, (char *)&last_job, sizeof(last_job)); + if (!last_jobs) { + init_last_jobs_list(); + } + last_jobs->append(je); + if (last_jobs->size() > max_last_jobs) { + je = (struct s_last_job *)last_jobs->first(); + last_jobs->remove(je); + free(je); + } } break; default: @@ -297,7 +297,7 @@ static void free_common_jcr(JCR *jcr) pthread_mutex_destroy(&jcr->mutex); delete jcr->msg_queue; - close_msg(jcr); /* close messages for this job */ + close_msg(jcr); /* close messages for this job */ /* do this after closing messages */ if (jcr->client_name) { @@ -354,29 +354,32 @@ void free_jcr(JCR *jcr) #endif dequeue_messages(jcr); + if (jcr->JobId != 0) { + generate_daemon_event(jcr, "JobEnd"); + } lock_jcr_chain(); - jcr->use_count--; /* decrement use count */ + jcr->use_count--; /* decrement use count */ if (jcr->use_count < 0) { Emsg2(M_ERROR, 0, _("JCR use_count=%d JobId=%d\n"), - jcr->use_count, jcr->JobId); + jcr->use_count, jcr->JobId); } Dmsg3(3400, "Dec free_jcr 0x%x use_count=%d jobid=%d\n", jcr, jcr->use_count, jcr->JobId); - if (jcr->use_count > 0) { /* if in use */ + if (jcr->use_count > 0) { /* if in use */ unlock_jcr_chain(); Dmsg2(3400, "free_jcr 0x%x use_count=%d\n", jcr, jcr->use_count); return; } - remove_jcr(jcr); /* remove Jcr from chain */ + remove_jcr(jcr); /* remove Jcr from chain */ unlock_jcr_chain(); - job_end_pop(jcr); /* pop and call hooked routines */ + job_end_pop(jcr); /* pop and call hooked routines */ Dmsg1(3400, "End job=%d\n", jcr->JobId); if (jcr->daemon_free_jcr) { jcr->daemon_free_jcr(jcr); /* call daemon free routine */ } free_common_jcr(jcr); - close_msg(NULL); /* flush any daemon messages */ + close_msg(NULL); /* flush any daemon messages */ Dmsg0(3400, "Exit free_jcr\n"); } @@ -387,13 +390,13 @@ void free_jcr(JCR *jcr) */ void free_locked_jcr(JCR *jcr) { - jcr->use_count--; /* decrement use count */ + jcr->use_count--; /* decrement use count */ Dmsg2(3400, "Dec free_locked_jcr 0x%x use_count=%d\n", jcr, jcr->use_count); - if (jcr->use_count > 0) { /* if in use */ + if (jcr->use_count > 0) { /* if in use */ return; } remove_jcr(jcr); - jcr->daemon_free_jcr(jcr); /* call daemon free routine */ + jcr->daemon_free_jcr(jcr); /* call daemon free routine */ free_common_jcr(jcr); } @@ -402,20 +405,20 @@ void free_locked_jcr(JCR *jcr) /* * Given a JobId, find the JCR * Returns: jcr on success - * NULL on failure + * NULL on failure */ JCR *get_jcr_by_id(uint32_t JobId) { JCR *jcr; - lock_jcr_chain(); /* lock chain */ + lock_jcr_chain(); /* lock chain */ for (jcr = jobs; jcr; jcr=jcr->next) { if (jcr->JobId == JobId) { - P(jcr->mutex); - jcr->use_count++; - V(jcr->mutex); + P(jcr->mutex); + jcr->use_count++; + V(jcr->mutex); Dmsg2(3400, "Inc get_jcr 0x%x use_count=%d\n", jcr, jcr->use_count); - break; + break; } } unlock_jcr_chain(); @@ -425,7 +428,7 @@ JCR *get_jcr_by_id(uint32_t JobId) /* * Given a SessionId and SessionTime, find the JCR * Returns: jcr on success - * NULL on failure + * NULL on failure */ JCR *get_jcr_by_session(uint32_t SessionId, uint32_t SessionTime) { @@ -434,12 +437,12 @@ JCR *get_jcr_by_session(uint32_t SessionId, uint32_t SessionTime) lock_jcr_chain(); for (jcr = jobs; jcr; jcr=jcr->next) { if (jcr->VolSessionId == SessionId && - jcr->VolSessionTime == SessionTime) { - P(jcr->mutex); - jcr->use_count++; - V(jcr->mutex); + jcr->VolSessionTime == SessionTime) { + P(jcr->mutex); + jcr->use_count++; + V(jcr->mutex); Dmsg2(3400, "Inc get_jcr 0x%x use_count=%d\n", jcr, jcr->use_count); - break; + break; } } unlock_jcr_chain(); @@ -452,7 +455,7 @@ JCR *get_jcr_by_session(uint32_t SessionId, uint32_t SessionTime) * compares on the number of characters in Job * thus allowing partial matches. * Returns: jcr on success - * NULL on failure + * NULL on failure */ JCR *get_jcr_by_partial_name(char *Job) { @@ -466,11 +469,11 @@ JCR *get_jcr_by_partial_name(char *Job) len = strlen(Job); for (jcr = jobs; jcr; jcr=jcr->next) { if (strncmp(Job, jcr->Job, len) == 0) { - P(jcr->mutex); - jcr->use_count++; - V(jcr->mutex); + P(jcr->mutex); + jcr->use_count++; + V(jcr->mutex); Dmsg2(3400, "Inc get_jcr 0x%x use_count=%d\n", jcr, jcr->use_count); - break; + break; } } unlock_jcr_chain(); @@ -482,7 +485,7 @@ JCR *get_jcr_by_partial_name(char *Job) * Given a Job, find the JCR * requires an exact match of names. * Returns: jcr on success - * NULL on failure + * NULL on failure */ JCR *get_jcr_by_full_name(char *Job) { @@ -494,11 +497,11 @@ JCR *get_jcr_by_full_name(char *Job) lock_jcr_chain(); for (jcr = jobs; jcr; jcr=jcr->next) { if (strcmp(jcr->Job, Job) == 0) { - P(jcr->mutex); - jcr->use_count++; - V(jcr->mutex); + P(jcr->mutex); + jcr->use_count++; + V(jcr->mutex); Dmsg2(3400, "Inc get_jcr 0x%x use_count=%d\n", jcr, jcr->use_count); - break; + break; } } unlock_jcr_chain(); @@ -543,7 +546,7 @@ void lock_jcr_chain() #endif if ((errstat=rwl_writelock(&lock)) != 0) { Emsg1(M_ABORT, 0, "rwl_writelock failure. ERR=%s\n", - strerror(errstat)); + strerror(errstat)); } } @@ -563,7 +566,7 @@ void unlock_jcr_chain() #endif if ((errstat=rwl_writeunlock(&lock)) != 0) { Emsg1(M_ABORT, 0, "rwl_writeunlock failure. ERR=%s\n", - strerror(errstat)); + strerror(errstat)); } } @@ -591,8 +594,8 @@ bool init_jcr_subsystem(void) watchdog_t *wd = new_watchdog(); wd->one_shot = false; - wd->interval = 30; /* FIXME: should be configurable somewhere, even - if only with a #define */ + wd->interval = 30; /* FIXME: should be configurable somewhere, even + if only with a #define */ wd->callback = jcr_timeout_check; register_watchdog(wd); @@ -613,45 +616,45 @@ static void jcr_timeout_check(watchdog_t *self) */ lock_jcr_chain(); foreach_jcr(jcr) { - free_locked_jcr(jcr); /* OK to free now cuz chain is locked */ + free_locked_jcr(jcr); /* OK to free now cuz chain is locked */ if (jcr->JobId == 0) { - continue; + continue; } fd = jcr->store_bsock; if (fd) { - timer_start = fd->timer_start; - if (timer_start && (watchdog_time - timer_start) > fd->timeout) { - fd->timer_start = 0; /* turn off timer */ - fd->timed_out = TRUE; - Jmsg(jcr, M_ERROR, 0, _( + timer_start = fd->timer_start; + if (timer_start && (watchdog_time - timer_start) > fd->timeout) { + fd->timer_start = 0; /* turn off timer */ + fd->timed_out = TRUE; + Jmsg(jcr, M_ERROR, 0, _( "Watchdog sending kill after %d secs to thread stalled reading Storage daemon.\n"), - watchdog_time - timer_start); - pthread_kill(jcr->my_thread_id, TIMEOUT_SIGNAL); - } + watchdog_time - timer_start); + pthread_kill(jcr->my_thread_id, TIMEOUT_SIGNAL); + } } fd = jcr->file_bsock; if (fd) { - timer_start = fd->timer_start; - if (timer_start && (watchdog_time - timer_start) > fd->timeout) { - fd->timer_start = 0; /* turn off timer */ - fd->timed_out = TRUE; - Jmsg(jcr, M_ERROR, 0, _( + timer_start = fd->timer_start; + if (timer_start && (watchdog_time - timer_start) > fd->timeout) { + fd->timer_start = 0; /* turn off timer */ + fd->timed_out = TRUE; + Jmsg(jcr, M_ERROR, 0, _( "Watchdog sending kill after %d secs to thread stalled reading File daemon.\n"), - watchdog_time - timer_start); - pthread_kill(jcr->my_thread_id, TIMEOUT_SIGNAL); - } + watchdog_time - timer_start); + pthread_kill(jcr->my_thread_id, TIMEOUT_SIGNAL); + } } fd = jcr->dir_bsock; if (fd) { - timer_start = fd->timer_start; - if (timer_start && (watchdog_time - timer_start) > fd->timeout) { - fd->timer_start = 0; /* turn off timer */ - fd->timed_out = TRUE; - Jmsg(jcr, M_ERROR, 0, _( + timer_start = fd->timer_start; + if (timer_start && (watchdog_time - timer_start) > fd->timeout) { + fd->timer_start = 0; /* turn off timer */ + fd->timed_out = TRUE; + Jmsg(jcr, M_ERROR, 0, _( "Watchdog sending kill after %d secs to thread stalled reading Director.\n"), - watchdog_time - timer_start); - pthread_kill(jcr->my_thread_id, TIMEOUT_SIGNAL); - } + watchdog_time - timer_start); + pthread_kill(jcr->my_thread_id, TIMEOUT_SIGNAL); + } } } @@ -665,5 +668,5 @@ static void jcr_timeout_check(watchdog_t *self) */ extern "C" void timeout_handler(int sig) { - return; /* thus interrupting the function */ + return; /* thus interrupting the function */ } diff --git a/bacula/src/lib/protos.h b/bacula/src/lib/protos.h index f73f1a395e..81a9a3e26d 100644 --- a/bacula/src/lib/protos.h +++ b/bacula/src/lib/protos.h @@ -176,9 +176,10 @@ void free_getgroup_cache(); /* python.c */ typedef int (EVENT_HANDLER)(JCR *jcr, const char *event); -void init_python_interpreter(const char *progname, const char *scripts); +void init_python_interpreter(const char *progname, const char *scripts, + const char *module); void term_python_interpreter(); -extern EVENT_HANDLER *generate_event; +extern EVENT_HANDLER *generate_daemon_event; /* signal.c */ void init_signals (void terminate(int sig)); diff --git a/bacula/src/lib/python.c b/bacula/src/lib/python.c index 81c81bb236..fd7f23725f 100644 --- a/bacula/src/lib/python.c +++ b/bacula/src/lib/python.c @@ -29,32 +29,57 @@ */ #include "bacula.h" +#include "jcr.h" -EVENT_HANDLER *generate_event; +EVENT_HANDLER *generate_daemon_event; #ifdef HAVE_PYTHON #undef _POSIX_C_SOURCE #include +static PyObject *bacula_module = NULL; /* We create this */ +static PyObject *StartUp_module = NULL; /* We import this */ + +/* These are the daemon events or methods that are defined */ +static PyObject *JobStart_method = NULL; +static PyObject *JobEnd_method = NULL; +static PyObject *Exit_method = NULL; + + +static PyObject *set_bacula_events(PyObject *self, PyObject *args); +static PyObject *bacula_write(PyObject *self, PyObject *args); +int _generate_daemon_event(JCR *jcr, const char *event); + +PyObject *find_method(PyObject *eventsObject, PyObject *method, char *name); + +/* Define Bacula daemon method entry points */ +static PyMethodDef BaculaMethods[] = { + {"set_events", set_bacula_events, METH_VARARGS, "Define Bacula events."}, + {"write", bacula_write, METH_VARARGS, "Write output."}, + {NULL, NULL, 0, NULL} /* last item */ +}; -PyObject *bacula_get(PyObject *self, PyObject *args); -PyObject *bacula_set(PyObject *self, PyObject *args, PyObject *keyw); -int _generate_event(JCR *jcr, const char *event); /* Pull in Bacula entry points */ -extern PyMethodDef BaculaMethods[]; +extern PyMethodDef JobMethods[]; + -typedef struct bJCRObject { +/* + * This is a Bacula Job type as defined in Python. We store a pointer + * to the jcr. That is all we need, but the user's script may keep + * local data attached to this. + */ +typedef struct JCRObject { PyObject_HEAD JCR *jcr; -} bJCRObject; +} JCRObject; static PyTypeObject JCRType = { PyObject_HEAD_INIT(NULL) 0, /*ob_size*/ "bacula.jcr", /*tp_name*/ - sizeof(bJCRObject), /*tp_basicsize*/ + sizeof(JCRObject), /*tp_basicsize*/ 0, /*tp_itemsize*/ 0, /*tp_dealloc*/ 0, /*tp_print*/ @@ -92,33 +117,102 @@ static PyTypeObject JCRType = { 0, /* tp_new */ }; +/* Return the JCR pointer from the JCRObject */ JCR *get_jcr_from_PyObject(PyObject *self) { - return ((bJCRObject *)self)->jcr; + return ((JCRObject *)self)->jcr; } + /* Start the interpreter */ -void init_python_interpreter(const char *progname, const char *scripts) +void init_python_interpreter(const char *progname, const char *scripts, + const char *module) { char buf[MAXSTRING]; Py_SetProgramName((char *)progname); Py_Initialize(); PyEval_InitThreads(); - Py_InitModule("bacula", BaculaMethods); + bacula_module = Py_InitModule("bacula", BaculaMethods); + if (!bacula_module) { + Jmsg(NULL, M_ERROR_TERM, 0, "Could not initialize Python\n"); + } bsnprintf(buf, sizeof(buf), "import sys\n" "sys.path.append('%s')\n", scripts); - PyRun_SimpleString(buf); + if (PyRun_SimpleString(buf) != 0) { + Jmsg(NULL, M_ERROR_TERM, 0, "Could not Run Python string %s\n", buf); + } JCRType.tp_methods = BaculaMethods; - PyType_Ready(&JCRType); + if(PyType_Ready(&JCRType) != 0) { + Jmsg(NULL, M_ERROR_TERM, 0, "Could not initialize Python Job type.\n"); + PyErr_Print(); + } + StartUp_module = PyImport_ImportModule((char *)module); + if (!StartUp_module) { + Jmsg(NULL, M_ERROR_TERM, 0, "Could not import script %s/%s.\n", + scripts, module); + PyErr_Clear(); + } PyEval_ReleaseLock(); - generate_event = _generate_event; + generate_daemon_event = _generate_daemon_event; } + + void term_python_interpreter() { + Py_XDECREF(StartUp_module); Py_Finalize(); } +static PyObject *set_bacula_events(PyObject *self, PyObject *args) +{ + PyObject *eObject; + if (!PyArg_ParseTuple(args, "O:set_bacula_events", &eObject)) { + return NULL; + } + JobStart_method = find_method(eObject, JobStart_method, "JobStart"); + JobEnd_method = find_method(eObject, JobEnd_method, "JobEnd"); + Exit_method = find_method(eObject, Exit_method, "Exit"); + + Py_XINCREF(eObject); + Py_INCREF(Py_None); + return Py_None; +} + +/* Write text to daemon output */ +static PyObject *bacula_write(PyObject *self, PyObject *args) +{ + char *text; + if (!PyArg_ParseTuple(args, "s:write", &text)) { + return NULL; + } + if (text) { + Jmsg(NULL, M_INFO, 0, "%s", text); + } + Py_INCREF(Py_None); + return Py_None; +} + + +/* + * Check that a method exists and is callable. + */ +PyObject *find_method(PyObject *eventsObject, PyObject *method, char *name) +{ + Py_XDECREF(method); /* release old method if any */ + method = PyObject_GetAttrString(eventsObject, name); + if (method == NULL) { + Dmsg1(000, "Python method %s not found\n", name); + } else if (PyCallable_Check(method) == 0) { + Dmsg1(000, "Python object %s found but not a method.\n", name); + Py_XDECREF(method); + method = NULL; + } else { + Dmsg1(000, "Got method %s\n", name); + } + return method; +} + /* * Generate and process a Bacula event by importing a Python @@ -128,8 +222,69 @@ void term_python_interpreter() * -1 on Python error * 1 OK */ -int _generate_event(JCR *jcr, const char *event) +int _generate_daemon_event(JCR *jcr, const char *event) { + PyObject *pJCR; + int stat = -1; + PyObject *result = NULL; + + PyEval_AcquireLock(); + if (strcmp(event, "JobStart") == 0) { + if (!JobStart_method) { + stat = 0; + goto bail_out; + } + /* Create JCR argument to send to function */ + pJCR = (PyObject *)PyObject_New(JCRObject, &JCRType); + if (!pJCR) { + Jmsg(jcr, M_ERROR, 0, "Could not create JCR Python Object.\n"); + goto bail_out; + } + ((JCRObject *)pJCR)->jcr = jcr; + bstrncpy(jcr->event, event, sizeof(jcr->event)); + result = PyObject_CallFunction(JobStart_method, "O", pJCR); + jcr->event[0] = 0; /* no event in progress */ + if (result == NULL) { + JobStart_method = NULL; + if (PyErr_Occurred()) { + PyErr_Print(); + } + Jmsg(jcr, M_ERROR, 0, "Python function \"%s\" not found.\n", event); + Py_XDECREF(pJCR); + goto bail_out; + } + jcr->Python_jcr = (void *)pJCR; + stat = 1; /* OK */ + + } else if (strcmp(event, "JobEnd") == 0) { + if (!JobEnd_method) { + Py_XDECREF((PyObject *)jcr->Python_jcr); + stat = 0; + goto bail_out; + } + bstrncpy(jcr->event, event, sizeof(jcr->event)); + result = PyObject_CallFunction(JobEnd_method, "O", jcr->Python_jcr); + jcr->event[0] = 0; /* no event in progress */ + if (result == NULL) { + JobEnd_method = NULL; + if (PyErr_Occurred()) { + PyErr_Print(); + } + Jmsg(jcr, M_ERROR, 0, "Python function \"%s\" not found.\n", event); + Py_XDECREF((PyObject *)jcr->Python_jcr); + goto bail_out; + } + Py_XDECREF((PyObject *)jcr->Python_jcr); + stat = 1; /* OK */ + } + +bail_out: + Py_XDECREF(result); + PyEval_ReleaseLock(); + return stat; +} + +#ifdef xxx PyObject *pName, *pModule, *pDict, *pFunc; PyObject *pArgs, *pJCR, *pCall; @@ -153,9 +308,8 @@ int _generate_event(JCR *jcr, const char *event) if (pFunc && PyCallable_Check(pFunc)) { /* Create JCR argument to send to function */ pArgs = PyTuple_New(1); - pJCR = (PyObject *)PyObject_New(bJCRObject, &JCRType); - ((bJCRObject *)pJCR)->jcr = jcr; -// pValue = PyCObject_FromVoidPtr((void *)jcr, NULL); + pJCR = (PyObject *)PyObject_New(JCRObject, &JCRType); + ((JCRObject *)pJCR)->jcr = jcr; if (!pJCR) { Py_DECREF(pArgs); Py_DECREF(pModule); @@ -167,7 +321,9 @@ int _generate_event(JCR *jcr, const char *event) PyTuple_SetItem(pArgs, 0, pJCR); /* Finally, we call the module here */ + bstrncpy(jcr->event, event, sizeof(jcr->event)); pCall = PyObject_CallObject(pFunc, pArgs); + jcr->event[0] = 0; /* no event in progress */ Py_DECREF(pArgs); Py_DECREF(pJCR); if (pCall != NULL) { @@ -193,17 +349,22 @@ int _generate_event(JCR *jcr, const char *event) Dmsg0(100, "Generate event OK\n"); return 1; } +#endif #else /* - * No Python configured + * No Python configured -- create external entry points and + * dummy routines so that library code can call this without + * problems even if it is not configured. + */ -int _generate_event(JCR *jcr, const char *event) { return 0; } -void init_python_interpreter(const char *progname, const char *scripts) +int _generate_daemon_event(JCR *jcr, const char *event) { return 0; } +void init_python_interpreter(const char *progname, const char *scripts, + const char *module) { - generate_event = _generate_event; + generate_daemon_event = _generate_daemon_event; } void term_python_interpreter() { } diff --git a/bacula/src/stored/Makefile.in b/bacula/src/stored/Makefile.in index f791977444..b3bb074517 100644 --- a/bacula/src/stored/Makefile.in +++ b/bacula/src/stored/Makefile.in @@ -57,6 +57,7 @@ BLSOBJS = bls.o block.o butil.o device.o dev.o label.o match_bsr.o \ BEXTOBJS = bextract.o block.o device.o dev.o label.o record.o \ ansi_label.o dvd.o ebcdic.o \ autochanger.o acquire.o mount.o match_bsr.o parse_bsr.o butil.o \ + python.o \ read_record.o stored_conf.o spool.o wait.o # bscan @@ -98,38 +99,48 @@ bacula-sd: $(SVROBJS) ../lib/libbac.a static-bacula-sd: $(SVROBJS) ../lib/libbac.a $(CXX) $(WLDFLAGS) $(LDFLAGS) -static -L../lib -o $@ $(SVROBJS) $(FDLIBS) \ - -lbac -lm $(PYTHON_LIBS) $(DLIB) $(LIBS) + -lbac -lm $(PYTHON_LIBS) $(DLIB) $(LIBS) strip $@ btape.o: btape.c - $(CXX) $(DEFS) $(DEBUG) -c $(CPPFLAGS) -I$(srcdir) -I$(basedir) $(DINCLUDE) $(CFLAGS) $< + $(CXX) $(DEFS) $(DEBUG) -c $(CPPFLAGS) -I$(srcdir) \ + -I$(basedir) $(DINCLUDE) $(CFLAGS) $< btape: $(TAPEOBJS) ../lib/libbac.a ../cats/libsql.a - $(CXX) $(TTOOL_LDFLAGS) $(LDFLAGS) -L../lib -L../cats -o $@ $(TAPEOBJS) -lsql $(DLIB) -lbac -lm $(LIBS) + $(CXX) $(TTOOL_LDFLAGS) $(LDFLAGS) -L../lib -L../cats -o $@ $(TAPEOBJS) \ + -lsql $(DLIB) -lbac -lm $(PYTHON_LIBS) $(LIBS) bls.o: bls.c - $(CXX) $(DEFS) $(DEBUG) -c $(CPPFLAGS) -I$(srcdir) -I$(basedir) $(DINCLUDE) $(CFLAGS) $< + $(CXX) $(DEFS) $(DEBUG) -c $(CPPFLAGS) $(PYTHON_INC) -I$(srcdir) \ + -I$(basedir) $(DINCLUDE) $(CFLAGS) $< bls: ../findlib/libfind.a $(BLSOBJS) ../lib/libbac.a - $(CXX) $(TTOOL_LDFLAGS) $(LDFLAGS) -L../lib -L../findlib -o $@ $(BLSOBJS) $(DLIB) -lfind -lbac -lm $(LIBS) + $(CXX) $(TTOOL_LDFLAGS) $(LDFLAGS) -L../lib -L../findlib -o $@ $(BLSOBJS) $(DLIB) -lfind \ + -lbac -lm $(PYTHON_LIBS) $(LIBS) bextract.o: bextract.c - $(CXX) $(DEFS) $(DEBUG) -c $(CPPFLAGS) -I$(srcdir) -I$(basedir) $(DINCLUDE) $(CFLAGS) $< + $(CXX) $(DEFS) $(DEBUG) -c $(CPPFLAGS) $(PYTHON_INC) -I$(srcdir) \ + -I$(basedir) $(DINCLUDE) $(CFLAGS) $< bextract: ../findlib/libfind.a $(BEXTOBJS) ../lib/libbac.a - $(CXX) $(TTOOL_LDFLAGS) $(LDFLAGS) -L../lib -L../findlib -o $@ $(BEXTOBJS) $(DLIB) $(FDLIBS) -lfind -lbac -lm $(LIBS) + $(CXX) $(TTOOL_LDFLAGS) $(LDFLAGS) -L../lib -L../findlib -o $@ $(BEXTOBJS) $(DLIB) $(FDLIBS) \ + -lfind -lbac -lm $(PYTHON_LIBS) $(LIBS) bscan.o: bscan.c - $(CXX) $(DEFS) $(DEBUG) -c $(CPPFLAGS) -I$(srcdir) -I$(basedir) $(DINCLUDE) $(CFLAGS) $< + $(CXX) $(DEFS) $(DEBUG) -c $(CPPFLAGS) $(PYTHON_INC) -I$(srcdir) \ + -I$(basedir) $(DINCLUDE) $(CFLAGS) $< bscan: ../findlib/libfind.a $(SCNOBJS) ../cats/libsql.a - $(CXX) $(TTOOL_LDFLAGS) $(LDFLAGS) -L../lib -L../cats -L../findlib -o $@ $(SCNOBJS) -lsql $(DB_LIBS) $(FDLIBS) -lfind -lbac -lm $(LIBS) + $(CXX) $(TTOOL_LDFLAGS) $(LDFLAGS) -L../lib -L../cats -L../findlib -o $@ $(SCNOBJS) \ + -lsql $(DB_LIBS) $(FDLIBS) -lfind -lbac -lm $(PYTHON_LIBS) $(LIBS) bcopy.o: bcopy.c - $(CXX) $(DEFS) $(DEBUG) -c $(CPPFLAGS) -I$(srcdir) -I$(basedir) $(DINCLUDE) $(CFLAGS) $< + $(CXX) $(DEFS) $(DEBUG) -c $(CPPFLAGS) $(PYTHON_INC) -I$(srcdir) \ + -I$(basedir) $(DINCLUDE) $(CFLAGS) $< bcopy: $(COPYOBJS) ../findlib/libfind.a ../lib/libbac.a - $(CXX) $(TTOOL_LDFLAGS) $(LDFLAGS) -L../lib -L../findlib -o $@ $(COPYOBJS) $(DB_LIBS) $(FDLIBS) -lfind -lbac -lm $(LIBS) + $(CXX) $(TTOOL_LDFLAGS) $(LDFLAGS) -L../lib -L../findlib -o $@ $(COPYOBJS) \ + $(DB_LIBS) $(FDLIBS) -lfind -lbac -lm $(PYTHON_LIBS) $(LIBS) Makefile: $(srcdir)/Makefile.in $(topdir)/config.status diff --git a/bacula/src/stored/acquire.c b/bacula/src/stored/acquire.c index 9e2d4a9fee..1f47fc372d 100644 --- a/bacula/src/stored/acquire.c +++ b/bacula/src/stored/acquire.c @@ -640,7 +640,7 @@ bool release_device(DCR *dcr) dcr->VolCatInfo.VolCatName, jcr->Job); } /* If no more writers, write an EOF */ - if (!dev->num_writers && dev_can_write(dev)) { + if (!dev->num_writers && dev->can_write()) { weof_dev(dev, 1); write_ansi_ibm_labels(dcr, ANSI_EOF_LABEL, dev->VolHdr.VolName); Dmsg0(100, "==== write ansi eof label \n"); diff --git a/bacula/src/stored/append.c b/bacula/src/stored/append.c index 95d9bdf0e5..862629af21 100644 --- a/bacula/src/stored/append.c +++ b/bacula/src/stored/append.c @@ -253,7 +253,7 @@ bool do_append_data(JCR *jcr) * If !OK, check if we can still write. This may not be the case * if we are at the end of the tape or we got a fatal I/O error. */ - if (ok || dev_can_write(dev)) { + if (ok || dev->can_write()) { if (!write_session_label(dcr, EOS_LABEL)) { Jmsg1(jcr, M_FATAL, 0, _("Error writting end session label. ERR=%s\n"), strerror_dev(dev)); diff --git a/bacula/src/stored/bextract.c b/bacula/src/stored/bextract.c index 34e446022c..99a9438bd7 100644 --- a/bacula/src/stored/bextract.c +++ b/bacula/src/stored/bextract.c @@ -58,13 +58,13 @@ static int prog_name_msg = 0; static int win32_data_msg = 0; static char *VolumeName = NULL; -static char *wbuf; /* write buffer address */ -static uint32_t wsize; /* write size */ -static uint64_t fileAddr = 0; /* file write address */ +static char *wbuf; /* write buffer address */ +static uint32_t wsize; /* write size */ +static uint64_t fileAddr = 0; /* file write address */ #define CONFIG_FILE "bacula-sd.conf" char *configfile; -STORES *me = NULL; /* our Global resource */ +STORES *me = NULL; /* our Global resource */ bool forge_on = false; pthread_mutex_t device_release_mutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t wait_device_release = PTHREAD_COND_INITIALIZER; @@ -97,7 +97,7 @@ int main (int argc, char *argv[]) working_directory = "/tmp"; my_name_is(argc, argv, "bextract"); - init_msg(NULL, NULL); /* setup message handler */ + init_msg(NULL, NULL); /* setup message handler */ ff = init_find_files(); binit(&bfd); @@ -105,69 +105,69 @@ int main (int argc, char *argv[]) while ((ch = getopt(argc, argv, "b:c:d:e:i:pvV:?")) != -1) { switch (ch) { case 'b': /* bootstrap file */ - bsr = parse_bsr(NULL, optarg); -// dump_bsr(bsr, true); - break; + bsr = parse_bsr(NULL, optarg); +// dump_bsr(bsr, true); + break; case 'c': /* specify config file */ - if (configfile != NULL) { - free(configfile); - } - configfile = bstrdup(optarg); - break; + if (configfile != NULL) { + free(configfile); + } + configfile = bstrdup(optarg); + break; case 'd': /* debug level */ - debug_level = atoi(optarg); - if (debug_level <= 0) - debug_level = 1; - break; + debug_level = atoi(optarg); + if (debug_level <= 0) + debug_level = 1; + break; case 'e': /* exclude list */ if ((fd = fopen(optarg, "r")) == NULL) { - berrno be; + berrno be; Pmsg2(0, "Could not open exclude file: %s, ERR=%s\n", - optarg, be.strerror()); - exit(1); - } - while (fgets(line, sizeof(line), fd) != NULL) { - strip_trailing_junk(line); + optarg, be.strerror()); + exit(1); + } + while (fgets(line, sizeof(line), fd) != NULL) { + strip_trailing_junk(line); Dmsg1(900, "add_exclude %s\n", line); - add_fname_to_exclude_list(ff, line); - } - fclose(fd); - break; + add_fname_to_exclude_list(ff, line); + } + fclose(fd); + break; case 'i': /* include list */ if ((fd = fopen(optarg, "r")) == NULL) { - berrno be; + berrno be; Pmsg2(0, "Could not open include file: %s, ERR=%s\n", - optarg, be.strerror()); - exit(1); - } - while (fgets(line, sizeof(line), fd) != NULL) { - strip_trailing_junk(line); + optarg, be.strerror()); + exit(1); + } + while (fgets(line, sizeof(line), fd) != NULL) { + strip_trailing_junk(line); Dmsg1(900, "add_include %s\n", line); - add_fname_to_include_list(ff, 0, line); - } - fclose(fd); - got_inc = true; - break; + add_fname_to_include_list(ff, 0, line); + } + fclose(fd); + got_inc = true; + break; case 'p': - forge_on = true; - break; + forge_on = true; + break; case 'v': - verbose++; - break; + verbose++; + break; case 'V': /* Volume name */ - VolumeName = optarg; - break; + VolumeName = optarg; + break; case '?': default: - usage(); + usage(); } /* end switch */ } /* end while */ @@ -185,7 +185,7 @@ int main (int argc, char *argv[]) parse_config(configfile); - if (!got_inc) { /* If no include file, */ + if (!got_inc) { /* If no include file, */ add_fname_to_include_list(ff, 0, "/"); /* include everything */ } @@ -197,11 +197,11 @@ int main (int argc, char *argv[]) } if (prog_name_msg) { Pmsg1(000, "%d Program Name and/or Program Data Stream records ignored.\n", - prog_name_msg); + prog_name_msg); } if (win32_data_msg) { Pmsg1(000, "%d Win32 data or Win32 gzip data stream records. Ignored.\n", - win32_data_msg); + win32_data_msg); } term_include_exclude_files(ff); term_find_files(ff); @@ -225,7 +225,7 @@ static void do_extract(char *devname) if (stat(where, &statp) < 0) { berrno be; Emsg2(M_ERROR_TERM, 0, "Cannot stat %s. It must exist. ERR=%s\n", - where, be.strerror()); + where, be.strerror()); } if (!S_ISDIR(statp.st_mode)) { Emsg1(M_ERROR_TERM, 0, "%s must be a directory.\n", where); @@ -275,11 +275,11 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec) * close the output file. */ if (extract) { - if (!is_bopen(&bfd)) { + if (!is_bopen(&bfd)) { Emsg0(M_ERROR, 0, _("Logic error output file should be open but is not.\n")); - } - set_attributes(jcr, attr, &bfd); - extract = false; + } + set_attributes(jcr, attr, &bfd); + extract = false; } if (!unpack_attributes_record(jcr, rec->Stream, rec->data, attr)) { @@ -288,43 +288,43 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec) if (attr->file_index != rec->FileIndex) { Emsg2(M_ERROR_TERM, 0, _("Record header file index %ld not equal record index %ld\n"), - rec->FileIndex, attr->file_index); + rec->FileIndex, attr->file_index); } if (file_is_included(ff, attr->fname) && !file_is_excluded(ff, attr->fname)) { - attr->data_stream = decode_stat(attr->attr, &attr->statp, &attr->LinkFI); - if (!is_stream_supported(attr->data_stream)) { - if (!non_support_data++) { + attr->data_stream = decode_stat(attr->attr, &attr->statp, &attr->LinkFI); + if (!is_stream_supported(attr->data_stream)) { + if (!non_support_data++) { Jmsg(jcr, M_ERROR, 0, _("%s stream not supported on this Client.\n"), - stream_to_ascii(attr->data_stream)); - } - extract = false; - return true; - } - - - build_attr_output_fnames(jcr, attr); - - extract = false; - stat = create_file(jcr, attr, &bfd, REPLACE_ALWAYS); - switch (stat) { - case CF_ERROR: - case CF_SKIP: - break; - case CF_EXTRACT: - extract = true; - print_ls_output(jcr, attr); - num_files++; - fileAddr = 0; - break; - case CF_CREATED: - set_attributes(jcr, attr, &bfd); - print_ls_output(jcr, attr); - num_files++; - fileAddr = 0; - break; - } + stream_to_ascii(attr->data_stream)); + } + extract = false; + return true; + } + + + build_attr_output_fnames(jcr, attr); + + extract = false; + stat = create_file(jcr, attr, &bfd, REPLACE_ALWAYS); + switch (stat) { + case CF_ERROR: + case CF_SKIP: + break; + case CF_EXTRACT: + extract = true; + print_ls_output(jcr, attr); + num_files++; + fileAddr = 0; + break; + case CF_CREATED: + set_attributes(jcr, attr, &bfd); + print_ls_output(jcr, attr); + num_files++; + fileAddr = 0; + break; + } } break; @@ -334,33 +334,33 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec) case STREAM_WIN32_DATA: if (extract) { - if (rec->Stream == STREAM_SPARSE_DATA) { - ser_declare; - uint64_t faddr; - wbuf = rec->data + SPARSE_FADDR_SIZE; - wsize = rec->data_len - SPARSE_FADDR_SIZE; - ser_begin(rec->data, SPARSE_FADDR_SIZE); - unser_uint64(faddr); - if (fileAddr != faddr) { - fileAddr = faddr; - if (blseek(&bfd, (off_t)fileAddr, SEEK_SET) < 0) { - berrno be; + if (rec->Stream == STREAM_SPARSE_DATA) { + ser_declare; + uint64_t faddr; + wbuf = rec->data + SPARSE_FADDR_SIZE; + wsize = rec->data_len - SPARSE_FADDR_SIZE; + ser_begin(rec->data, SPARSE_FADDR_SIZE); + unser_uint64(faddr); + if (fileAddr != faddr) { + fileAddr = faddr; + if (blseek(&bfd, (off_t)fileAddr, SEEK_SET) < 0) { + berrno be; Emsg2(M_ERROR_TERM, 0, _("Seek error on %s: %s\n"), - attr->ofname, be.strerror()); - } - } - } else { - wbuf = rec->data; - wsize = rec->data_len; - } - total += wsize; + attr->ofname, be.strerror()); + } + } + } else { + wbuf = rec->data; + wsize = rec->data_len; + } + total += wsize; Dmsg2(8, "Write %u bytes, total=%u\n", wsize, total); - if ((uint32_t)bwrite(&bfd, wbuf, wsize) != wsize) { - berrno be; + if ((uint32_t)bwrite(&bfd, wbuf, wsize) != wsize) { + berrno be; Emsg2(M_ERROR_TERM, 0, _("Write error on %s: %s\n"), - attr->ofname, be.strerror()); - } - fileAddr += wsize; + attr->ofname, be.strerror()); + } + fileAddr += wsize; } break; @@ -370,58 +370,58 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec) case STREAM_WIN32_GZIP_DATA: #ifdef HAVE_LIBZ if (extract) { - uLong compress_len; - int stat; - - if (rec->Stream == STREAM_SPARSE_GZIP_DATA) { - ser_declare; - uint64_t faddr; - char ec1[50]; - wbuf = rec->data + SPARSE_FADDR_SIZE; - wsize = rec->data_len - SPARSE_FADDR_SIZE; - ser_begin(rec->data, SPARSE_FADDR_SIZE); - unser_uint64(faddr); - if (fileAddr != faddr) { - fileAddr = faddr; - if (blseek(&bfd, (off_t)fileAddr, SEEK_SET) < 0) { - berrno be; + uLong compress_len; + int stat; + + if (rec->Stream == STREAM_SPARSE_GZIP_DATA) { + ser_declare; + uint64_t faddr; + char ec1[50]; + wbuf = rec->data + SPARSE_FADDR_SIZE; + wsize = rec->data_len - SPARSE_FADDR_SIZE; + ser_begin(rec->data, SPARSE_FADDR_SIZE); + unser_uint64(faddr); + if (fileAddr != faddr) { + fileAddr = faddr; + if (blseek(&bfd, (off_t)fileAddr, SEEK_SET) < 0) { + berrno be; Emsg3(M_ERROR, 0, _("Seek to %s error on %s: ERR=%s\n"), - edit_uint64(fileAddr, ec1), attr->ofname, be.strerror()); - extract = false; - return true; - } - } - } else { - wbuf = rec->data; - wsize = rec->data_len; - } - compress_len = compress_buf_size; - if ((stat=uncompress((Bytef *)compress_buf, &compress_len, - (const Bytef *)wbuf, (uLong)wsize) != Z_OK)) { + edit_uint64(fileAddr, ec1), attr->ofname, be.strerror()); + extract = false; + return true; + } + } + } else { + wbuf = rec->data; + wsize = rec->data_len; + } + compress_len = compress_buf_size; + if ((stat=uncompress((Bytef *)compress_buf, &compress_len, + (const Bytef *)wbuf, (uLong)wsize) != Z_OK)) { Emsg1(M_ERROR, 0, _("Uncompression error. ERR=%d\n"), stat); - extract = false; - return true; - } + extract = false; + return true; + } Dmsg2(100, "Write uncompressed %d bytes, total before write=%d\n", compress_len, total); - if ((uLongf)bwrite(&bfd, compress_buf, (size_t)compress_len) != compress_len) { - berrno be; + if ((uLongf)bwrite(&bfd, compress_buf, (size_t)compress_len) != compress_len) { + berrno be; Pmsg0(0, "===Write error===\n"); Emsg2(M_ERROR, 0, _("Write error on %s: %s\n"), - attr->ofname, be.strerror()); - extract = false; - return true; - } - total += compress_len; - fileAddr += compress_len; + attr->ofname, be.strerror()); + extract = false; + return true; + } + total += compress_len; + fileAddr += compress_len; Dmsg2(100, "Compress len=%d uncompressed=%d\n", rec->data_len, - compress_len); + compress_len); } #else if (extract) { Emsg0(M_ERROR, 0, "GZIP data stream found, but GZIP not configured!\n"); - extract = false; - return true; + extract = false; + return true; } #endif break; @@ -434,21 +434,21 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec) case STREAM_PROGRAM_DATA: if (!prog_name_msg) { Pmsg0(000, "Got Program Name or Data Stream. Ignored.\n"); - prog_name_msg++; + prog_name_msg++; } break; default: /* If extracting, wierd stream (not 1 or 2), close output file anyway */ if (extract) { - if (!is_bopen(&bfd)) { + if (!is_bopen(&bfd)) { Emsg0(M_ERROR, 0, "Logic error output file should be open but is not.\n"); - } - set_attributes(jcr, attr, &bfd); - extract = false; + } + set_attributes(jcr, attr, &bfd); + extract = false; } Jmsg(jcr, M_ERROR, 0, _("Unknown stream=%d ignored. This shouldn't happen!\n"), - rec->Stream); + rec->Stream); break; } /* end switch */ @@ -456,13 +456,13 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec) } /* Dummies to replace askdir.c */ -bool dir_get_volume_info(DCR *dcr, enum get_vol_info_rw writing) { return 1;} -bool dir_find_next_appendable_volume(DCR *dcr) { return 1;} -bool dir_update_volume_info(DCR *dcr, bool relabel) { return 1; } -bool dir_create_jobmedia_record(DCR *dcr) { return 1; } -bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr) { return 1; } -bool dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec) { return 1;} -bool dir_send_job_status(JCR *jcr) {return 1;} +bool dir_get_volume_info(DCR *dcr, enum get_vol_info_rw writing) { return 1;} +bool dir_find_next_appendable_volume(DCR *dcr) { return 1;} +bool dir_update_volume_info(DCR *dcr, bool relabel) { return 1; } +bool dir_create_jobmedia_record(DCR *dcr) { return 1; } +bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr) { return 1; } +bool dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec) { return 1;} +bool dir_send_job_status(JCR *jcr) {return 1;} bool dir_ask_sysop_to_mount_volume(DCR *dcr) diff --git a/bacula/src/stored/bls.c b/bacula/src/stored/bls.c index 4bf26f8ccf..70b2e5701b 100644 --- a/bacula/src/stored/bls.c +++ b/bacula/src/stored/bls.c @@ -55,7 +55,7 @@ static ATTR *attr; #define CONFIG_FILE "bacula-sd.conf" char *configfile; -STORES *me = NULL; /* our Global resource */ +STORES *me = NULL; /* our Global resource */ bool forge_on = false; pthread_mutex_t device_release_mutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t wait_device_release = PTHREAD_COND_INITIALIZER; @@ -99,85 +99,85 @@ int main (int argc, char *argv[]) working_directory = "/tmp"; my_name_is(argc, argv, "bls"); - init_msg(NULL, NULL); /* initialize message handler */ + init_msg(NULL, NULL); /* initialize message handler */ ff = init_find_files(); while ((ch = getopt(argc, argv, "b:c:d:e:i:jkLpvV:?")) != -1) { switch (ch) { case 'b': - bsrName = optarg; - break; + bsrName = optarg; + break; case 'c': /* specify config file */ - if (configfile != NULL) { - free(configfile); - } - configfile = bstrdup(optarg); - break; + if (configfile != NULL) { + free(configfile); + } + configfile = bstrdup(optarg); + break; case 'd': /* debug level */ - debug_level = atoi(optarg); - if (debug_level <= 0) - debug_level = 1; - break; + debug_level = atoi(optarg); + if (debug_level <= 0) + debug_level = 1; + break; case 'e': /* exclude list */ if ((fd = fopen(optarg, "r")) == NULL) { Pmsg2(0, _("Could not open exclude file: %s, ERR=%s\n"), - optarg, strerror(errno)); - exit(1); - } - while (fgets(line, sizeof(line), fd) != NULL) { - strip_trailing_junk(line); + optarg, strerror(errno)); + exit(1); + } + while (fgets(line, sizeof(line), fd) != NULL) { + strip_trailing_junk(line); Dmsg1(100, "add_exclude %s\n", line); - add_fname_to_exclude_list(ff, line); - } - fclose(fd); - break; + add_fname_to_exclude_list(ff, line); + } + fclose(fd); + break; case 'i': /* include list */ if ((fd = fopen(optarg, "r")) == NULL) { Pmsg2(0, "Could not open include file: %s, ERR=%s\n", - optarg, strerror(errno)); - exit(1); - } - while (fgets(line, sizeof(line), fd) != NULL) { - strip_trailing_junk(line); + optarg, strerror(errno)); + exit(1); + } + while (fgets(line, sizeof(line), fd) != NULL) { + strip_trailing_junk(line); Dmsg1(100, "add_include %s\n", line); - add_fname_to_include_list(ff, 0, line); - } - fclose(fd); - break; + add_fname_to_include_list(ff, 0, line); + } + fclose(fd); + break; case 'j': - list_jobs = true; - break; + list_jobs = true; + break; case 'k': - list_blocks = true; - break; + list_blocks = true; + break; case 'L': - dump_label = true; - break; + dump_label = true; + break; case 'p': - ignore_label_errors = true; - forge_on = true; - break; + ignore_label_errors = true; + forge_on = true; + break; case 'v': - verbose++; - break; + verbose++; + break; case 'V': /* Volume name */ - VolumeName = optarg; - break; + VolumeName = optarg; + break; case '?': default: - usage(); + usage(); } /* end switch */ } /* end while */ @@ -201,16 +201,16 @@ int main (int argc, char *argv[]) for (i=0; i < argc; i++) { if (bsrName) { - bsr = parse_bsr(NULL, bsrName); + bsr = parse_bsr(NULL, bsrName); } jcr = setup_jcr("bls", argv[i], bsr, VolumeName, 1); /* acquire for read */ if (!jcr) { - exit(1); + exit(1); } jcr->ignore_label_errors = ignore_label_errors; dev = jcr->dcr->dev; if (!dev) { - exit(1); + exit(1); } dcr = jcr->dcr; rec = new_record(); @@ -223,15 +223,15 @@ int main (int argc, char *argv[]) if (dev->VolHdr.PrevVolName[0] != 0) { /* second volume */ Pmsg1(0, "\n" "Warning, this Volume is a continuation of Volume %s\n", - dev->VolHdr.PrevVolName); + dev->VolHdr.PrevVolName); } if (list_blocks) { - do_blocks(argv[i]); + do_blocks(argv[i]); } else if (list_jobs) { - do_jobs(argv[i]); + do_jobs(argv[i]); } else { - do_ls(argv[i]); + do_ls(argv[i]); } do_close(jcr); } @@ -261,51 +261,51 @@ static void do_blocks(char *infname) for ( ;; ) { if (!read_block_from_device(dcr, NO_BLOCK_NUMBER_CHECK)) { Dmsg1(100, "!read_block(): ERR=%s\n", dev->strerror()); - if (dev->at_eot()) { - if (!mount_next_read_volume(dcr)) { + if (dev->at_eot()) { + if (!mount_next_read_volume(dcr)) { Jmsg(jcr, M_INFO, 0, _("Got EOM at file %u on device %s, Volume \"%s\"\n"), - dev->file, dev->print_name(), dcr->VolumeName); - break; - } - /* Read and discard Volume label */ - DEV_RECORD *record; - record = new_record(); - read_block_from_device(dcr, NO_BLOCK_NUMBER_CHECK); - read_record_from_block(block, record); - get_session_record(dev, record, &sessrec); - free_record(record); + dev->file, dev->print_name(), dcr->VolumeName); + break; + } + /* Read and discard Volume label */ + DEV_RECORD *record; + record = new_record(); + read_block_from_device(dcr, NO_BLOCK_NUMBER_CHECK); + read_record_from_block(block, record); + get_session_record(dev, record, &sessrec); + free_record(record); Jmsg(jcr, M_INFO, 0, _("Mounted Volume \"%s\".\n"), dcr->VolumeName); - } else if (dev->at_eof()) { + } else if (dev->at_eof()) { Jmsg(jcr, M_INFO, 0, _("Got EOF at file %u on device %s, Volume \"%s\"\n"), - dev->file, dev->print_name(), dcr->VolumeName); + dev->file, dev->print_name(), dcr->VolumeName); Dmsg0(20, "read_record got eof. try again\n"); - continue; - } else if (dev->state & ST_SHORT) { + continue; + } else if (dev->state & ST_SHORT) { Jmsg(jcr, M_INFO, 0, "%s", dev->errmsg); - continue; - } else { - /* I/O error */ - display_tape_error_status(jcr, dev); - break; - } + continue; + } else { + /* I/O error */ + display_tape_error_status(jcr, dev); + break; + } } if (!match_bsr_block(bsr, block)) { Dmsg5(100, "reject Blk=%u blen=%u bVer=%d SessId=%u SessTim=%u\n", - block->BlockNumber, block->block_len, block->BlockVer, - block->VolSessionId, block->VolSessionTime); - continue; + block->BlockNumber, block->block_len, block->BlockVer, + block->VolSessionId, block->VolSessionTime); + continue; } Dmsg5(100, "Blk=%u blen=%u bVer=%d SessId=%u SessTim=%u\n", - block->BlockNumber, block->block_len, block->BlockVer, - block->VolSessionId, block->VolSessionTime); + block->BlockNumber, block->block_len, block->BlockVer, + block->VolSessionId, block->VolSessionTime); if (verbose == 1) { - read_record_from_block(block, rec); + read_record_from_block(block, rec); Pmsg9(-1, "File:blk=%u:%u blk_num=%u blen=%u First rec FI=%s SessId=%u SessTim=%u Strm=%s rlen=%d\n", - dev->file, dev->block_num, - block->BlockNumber, block->block_len, - FI_to_ascii(rec->FileIndex), rec->VolSessionId, rec->VolSessionTime, - stream_to_ascii(rec->Stream, rec->FileIndex), rec->data_len); - rec->remainder = 0; + dev->file, dev->block_num, + block->BlockNumber, block->block_len, + FI_to_ascii(rec->FileIndex), rec->VolSessionId, rec->VolSessionTime, + stream_to_ascii(rec->Stream, rec->FileIndex), rec->data_len); + rec->remainder = 0; } else if (verbose > 1) { dump_block(block, ""); } else { @@ -359,28 +359,28 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec) rec->Stream == STREAM_UNIX_ATTRIBUTES_EX) { if (!unpack_attributes_record(jcr, rec->Stream, rec->data, attr)) { - if (!forge_on) { + if (!forge_on) { Emsg0(M_ERROR_TERM, 0, _("Cannot continue.\n")); - } - num_files++; - return true; + } + num_files++; + return true; } if (attr->file_index != rec->FileIndex) { Emsg2(forge_on?M_WARNING:M_ERROR_TERM, 0, _("Record header file index %ld not equal record index %ld\n"), - rec->FileIndex, attr->file_index); + rec->FileIndex, attr->file_index); } attr->data_stream = decode_stat(attr->attr, &attr->statp, &attr->LinkFI); build_attr_output_fnames(jcr, attr); if (file_is_included(ff, attr->fname) && !file_is_excluded(ff, attr->fname)) { - if (verbose) { + if (verbose) { Pmsg5(-1, "FileIndex=%d VolSessionId=%d VolSessionTime=%d Stream=%d DataLen=%d\n", - rec->FileIndex, rec->VolSessionId, rec->VolSessionTime, rec->Stream, rec->data_len); - } - print_ls_output(jcr, attr); - num_files++; + rec->FileIndex, rec->VolSessionId, rec->VolSessionTime, rec->Stream, rec->data_len); + } + print_ls_output(jcr, attr); + num_files++; } } return true; @@ -414,23 +414,24 @@ static void get_session_record(DEVICE *dev, DEV_RECORD *rec, SESSION_LABEL *sess break; } Dmsg5(10, "%s Record: VolSessionId=%d VolSessionTime=%d JobId=%d DataLen=%d\n", - rtype, rec->VolSessionId, rec->VolSessionTime, rec->Stream, rec->data_len); + rtype, rec->VolSessionId, rec->VolSessionTime, rec->Stream, rec->data_len); if (verbose) { Pmsg5(-1, "%s Record: VolSessionId=%d VolSessionTime=%d JobId=%d DataLen=%d\n", - rtype, rec->VolSessionId, rec->VolSessionTime, rec->Stream, rec->data_len); + rtype, rec->VolSessionId, rec->VolSessionTime, rec->Stream, rec->data_len); } } /* Dummies to replace askdir.c */ -bool dir_get_volume_info(DCR *dcr, enum get_vol_info_rw writing) { return 1;} -bool dir_find_next_appendable_volume(DCR *dcr) { return 1;} -bool dir_update_volume_info(DCR *dcr, bool relabel) { return 1; } -bool dir_create_jobmedia_record(DCR *dcr) { return 1; } -bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr) { return 1; } -bool dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec) { return 1;} -bool dir_send_job_status(JCR *jcr) {return 1;} - +bool dir_get_volume_info(DCR *dcr, enum get_vol_info_rw writing) { return 1;} +bool dir_find_next_appendable_volume(DCR *dcr) { return 1;} +bool dir_update_volume_info(DCR *dcr, bool relabel) { return 1; } +bool dir_create_jobmedia_record(DCR *dcr) { return 1; } +bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr) { return 1; } +bool dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec) { return 1;} +bool dir_send_job_status(JCR *jcr) {return 1;} +int generate_job_event(JCR *jcr, const char *event) { return 1; } + bool dir_ask_sysop_to_mount_volume(DCR *dcr) { diff --git a/bacula/src/stored/bscan.c b/bacula/src/stored/bscan.c index 65278ca54c..8abda6a5e2 100644 --- a/bacula/src/stored/bscan.c +++ b/bacula/src/stored/bscan.c @@ -1201,6 +1201,7 @@ bool dir_create_jobmedia_record(DCR *dcr) { return 1; } bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr) { return 1; } bool dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec) { return 1;} bool dir_send_job_status(JCR *jcr) {return 1;} +int generate_job_event(JCR *jcr, const char *event) { return 1; } bool dir_ask_sysop_to_mount_volume(DCR *dcr) diff --git a/bacula/src/stored/dev.c b/bacula/src/stored/dev.c index b8e81317fd..a6fbbe17aa 100644 --- a/bacula/src/stored/dev.c +++ b/bacula/src/stored/dev.c @@ -1629,23 +1629,6 @@ bool truncate_dev(DEVICE *dev) return true; } -/* - * return 1 if the device is read for write, and 0 otherwise - * This is meant for checking at the end of a job to see - * if we still have a tape (perhaps not if at end of tape - * and the job is canceled). - */ -bool -dev_can_write(DEVICE *dev) -{ - if (dev->is_open() && dev->can_append() && - dev->is_labeled() && !(dev->state & ST_WEOT)) { - return true; - } else { - return false; - } -} - /* Return the resource name for the device */ const char *DEVICE::name() const { diff --git a/bacula/src/stored/dev.h b/bacula/src/stored/dev.h index d4ce1f6874..9439d781ca 100644 --- a/bacula/src/stored/dev.h +++ b/bacula/src/stored/dev.h @@ -267,6 +267,13 @@ public: int at_eot() const { return state & ST_EOT; } int at_weot() const { return state & ST_WEOT; } int can_append() const { return state & ST_APPEND; } + /* + * can_write() is meant for checking at the end of a job to see + * if we still have a tape (perhaps not if at end of tape + * and the job is canceled). + */ + int can_write() const { return is_open() && can_append() && + is_labeled() && !at_weot(); } int can_read() const { return state & ST_READ; } bool can_steal_lock() const { return dev_blocked && (dev_blocked == BST_UNMOUNTED || diff --git a/bacula/src/stored/protos.h b/bacula/src/stored/protos.h index eab06c0d00..6fee3a0e8a 100644 --- a/bacula/src/stored/protos.h +++ b/bacula/src/stored/protos.h @@ -114,7 +114,6 @@ bool bsr_dev(DEVICE *dev, int num); void attach_jcr_to_device(DEVICE *dev, JCR *jcr); void detach_jcr_from_device(DEVICE *dev, JCR *jcr); JCR *next_attached_jcr(DEVICE *dev, JCR *jcr); -bool dev_can_write(DEVICE *dev); bool offline_or_rewind_dev(DEVICE *dev); bool reposition_dev(DEVICE *dev, uint32_t file, uint32_t block); void init_device_wait_timers(DCR *dcr); diff --git a/bacula/src/stored/python.c b/bacula/src/stored/python.c index c193219078..ea40ba4dfc 100644 --- a/bacula/src/stored/python.c +++ b/bacula/src/stored/python.c @@ -36,15 +36,21 @@ #include extern JCR *get_jcr_from_PyObject(PyObject *self); +extern PyObject *find_method(PyObject *eventsObject, PyObject *method, char *name); -PyObject *bacula_get(PyObject *self, PyObject *args); -PyObject *bacula_set(PyObject *self, PyObject *args, PyObject *keyw); +static PyObject *jcr_get(PyObject *self, PyObject *args); +static PyObject *jcr_write(PyObject *self, PyObject *args); +static PyObject *jcr_set(PyObject *self, PyObject *args, PyObject *keyw); +static PyObject *set_jcr_events(PyObject *self, PyObject *args); -/* Define Bacula entry points */ -PyMethodDef BaculaMethods[] = { - {"get", bacula_get, METH_VARARGS, "Get Bacula variables."}, - {"set", (PyCFunction)bacula_set, METH_VARARGS|METH_KEYWORDS, - "Set Bacula variables."}, + +/* Define Job entry points */ +PyMethodDef JobMethods[] = { + {"get", jcr_get, METH_VARARGS, "Get Job variables."}, + {"set", (PyCFunction)jcr_set, METH_VARARGS|METH_KEYWORDS, + "Set Job variables."}, + {"set_events", set_jcr_events, METH_VARARGS, "Define Job events."}, + {"write", jcr_write, METH_VARARGS, "Write output."}, {NULL, NULL, 0, NULL} /* last item */ }; @@ -71,8 +77,8 @@ static struct s_vars vars[] = { { NULL, NULL} }; -/* Return Bacula variables */ -PyObject *bacula_get(PyObject *self, PyObject *args) +/* Return Job variables */ +PyObject *jcr_get(PyObject *self, PyObject *args) { JCR *jcr; char *item; @@ -125,8 +131,8 @@ PyObject *bacula_get(PyObject *self, PyObject *args) return NULL; } -/* Set Bacula variables */ -PyObject *bacula_set(PyObject *self, PyObject *args, PyObject *keyw) +/* Set Job variables */ +PyObject *jcr_set(PyObject *self, PyObject *args, PyObject *keyw) { JCR *jcr; char *msg = NULL; @@ -144,4 +150,51 @@ PyObject *bacula_set(PyObject *self, PyObject *args, PyObject *keyw) return Py_BuildValue("i", 1); } +static PyObject *set_jcr_events(PyObject *self, PyObject *args) +{ + PyObject *eObject; + JCR *jcr; + if (!PyArg_ParseTuple(args, "O:set_events_hook", &eObject)) { + return NULL; + } + Py_XINCREF(eObject); + jcr = get_jcr_from_PyObject(self); +// jcr->ff->bfd.pio.fc = find_method(eObject, close_method, "close"); + Py_INCREF(Py_None); + return Py_None; +} + +/* Write text to job output */ +static PyObject *jcr_write(PyObject *self, PyObject *args) +{ + char *text; + if (!PyArg_ParseTuple(args, "s:write", &text)) { + return NULL; + } + if (text) { + JCR *jcr = get_jcr_from_PyObject(self); + Jmsg(jcr, M_INFO, 0, "%s", text); + } + + Py_INCREF(Py_None); + return Py_None; +} + +int generate_job_event(JCR *jcr, const char *event) +{ +#ifdef implemented + PyEval_AcquireLock(); + + PyObject *result = PyObject_CallFunction(open_method, "s", "m.py"); + if (result == NULL) { + PyErr_Print(); + PyErr_Clear(); + } + Py_XDECREF(result); + + PyEval_ReleaseLock(); +#endif + return 1; +} + #endif /* HAVE_PYTHON */ diff --git a/bacula/src/stored/stored.c b/bacula/src/stored/stored.c index e6149b4a49..d45ca8b0d3 100644 --- a/bacula/src/stored/stored.c +++ b/bacula/src/stored/stored.c @@ -209,7 +209,7 @@ int main (int argc, char *argv[]) } init_python_interpreter(me->hdr.name, me->scripts_directory ? - me->scripts_directory : "."); + me->scripts_directory : ".", "SDStartUp"); /* Make sure on Solaris we can run concurrent, watch dog + servers + misc */ set_thread_concurrency(me->max_concurrent_jobs * 2 + 4); diff --git a/bacula/src/tools/Makefile.in b/bacula/src/tools/Makefile.in index 0c912213d6..64d14f56af 100644 --- a/bacula/src/tools/Makefile.in +++ b/bacula/src/tools/Makefile.in @@ -5,6 +5,8 @@ # @MCOMMON@ +PYTHON_INC = @PYTHON_INCDIR@ + srcdir = . VPATH = . .PATH: . @@ -36,7 +38,7 @@ DIRCONFOBJS = ../dird/dird_conf.o ../dird/run_conf.o ../dird/inc_conf.o # inference rules .c.o: - $(CXX) $(DEFS) $(DEBUG) -c $(CPPFLAGS) -I$(srcdir) -I$(basedir) $(DINCLUDE) $(CFLAGS) $< + $(CXX) $(DEFS) $(DEBUG) -c $(CPPFLAGS) $(PYTHON_INC) -I$(srcdir) -I$(basedir) $(DINCLUDE) $(CFLAGS) $< #------------------------------------------------------------------------- all: Makefile bsmtp dbcheck fstype testfind testls @echo "==== Make of tools is good ====" @@ -99,7 +101,7 @@ depend: @$(MV) Makefile Makefile.bak @$(SED) "/^# DO NOT DELETE:/,$$ d" Makefile.bak > Makefile @$(ECHO) "# DO NOT DELETE: nice dependency list follows" >> Makefile - @$(CXX) -S -M $(CPPFLAGS) -I$(srcdir) -I$(basedir) $(SQL_INC) *.c >> Makefile + @$(CXX) -S -M $(CPPFLAGS) $(PYTHON_INC) -I$(srcdir) -I$(basedir) $(SQL_INC) *.c >> Makefile @if test -f Makefile ; then \ $(RMF) Makefile.bak; \ else \ -- 2.39.5