From 185a7010ae96c2e391d5f2c77fc42f14020621c4 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Mon, 7 Feb 2005 16:20:46 +0000 Subject: [PATCH] Added code to detect that no files were inserted into the tree for a restore. If a specific JobId was specified, the user has the option of restoring everything. - More progress in implementing 64 bit DB Ids. - Modified the daemon start messages for RH. - Implement update scripts for all database types. - First cut at implementing restore directory (it will not recurse). git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@1818 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/platforms/redhat/bacula-dir.in | 4 +- bacula/platforms/redhat/bacula-fd.in | 4 +- bacula/platforms/redhat/bacula-sd.in | 4 +- bacula/src/bacula.h | 2 +- bacula/src/bc_types.h | 2 +- bacula/src/cats/sql_delete.c | 7 +- bacula/src/cats/sql_find.c | 43 ++-- bacula/src/cats/sql_get.c | 23 +- bacula/src/cats/sql_list.c | 28 ++- bacula/src/cats/sql_update.c | 41 ++-- bacula/src/cats/update_mysql_tables.in | 37 ++- bacula/src/cats/update_postgresql_tables.in | 37 ++- bacula/src/cats/update_sqlite_tables.in | 37 ++- bacula/src/dird/bsr.c | 53 ++++ bacula/src/dird/bsr.h | 16 +- bacula/src/dird/protos.h | 1 + bacula/src/dird/recycle.c | 18 +- bacula/src/dird/sql_cmds.c | 32 ++- bacula/src/dird/ua.h | 3 +- bacula/src/dird/ua_cmds.c | 60 ++--- bacula/src/dird/ua_input.c | 3 +- bacula/src/dird/ua_label.c | 2 +- bacula/src/dird/ua_prune.c | 30 +-- bacula/src/dird/ua_purge.c | 31 +-- bacula/src/dird/ua_restore.c | 256 ++++++++++++++------ bacula/src/dird/ua_run.c | 11 +- bacula/src/dird/ua_select.c | 58 ++--- bacula/src/dird/ua_tree.c | 19 +- bacula/src/jcr.h | 3 +- bacula/src/stored/bcopy.c | 4 +- bacula/src/stored/bextract.c | 4 +- bacula/src/stored/bscan.c | 84 +++---- bacula/src/stored/btape.c | 4 +- bacula/src/stored/butil.c | 2 +- bacula/src/version.h | 4 +- 35 files changed, 653 insertions(+), 314 deletions(-) diff --git a/bacula/platforms/redhat/bacula-dir.in b/bacula/platforms/redhat/bacula-dir.in index 84cca2904a..ec9992f773 100755 --- a/bacula/platforms/redhat/bacula-dir.in +++ b/bacula/platforms/redhat/bacula-dir.in @@ -31,14 +31,14 @@ case "$1" in if [ "${DIR_GROUP}" != '' ]; then OPTIONS="${OPTIONS} -g ${DIR_GROUP}" fi - echo -n "Starting the Bacula Director: " + echo -n "Starting Bacula Director services: " daemon @sbindir@/bacula-dir $2 ${OPTIONS} -c @sysconfdir@/bacula-dir.conf RETVAL=$? echo [ $RETVAL -eq 0 ] && touch @subsysdir@/bacula-dir ;; stop) - echo -n "Stopping the Director daemon: " + echo -n "Stopping Bacula Director services: " killproc @sbindir@/bacula-dir RETVAL=$? echo diff --git a/bacula/platforms/redhat/bacula-fd.in b/bacula/platforms/redhat/bacula-fd.in index dc7bf27177..9e72008324 100755 --- a/bacula/platforms/redhat/bacula-fd.in +++ b/bacula/platforms/redhat/bacula-fd.in @@ -31,14 +31,14 @@ case "$1" in if [ "${FD_GROUP}" != '' ]; then OPTIONS="${OPTIONS} -g ${FD_GROUP}" fi - echo -n "Starting the Bacula File daemon: " + echo -n "Starting Bacula File services: " daemon @sbindir@/bacula-fd $2 ${OPTIONS} -c @sysconfdir@/bacula-fd.conf RETVAL=$? echo [ $RETVAL -eq 0 ] && touch @subsysdir@/bacula-fd ;; stop) - echo -n "Stopping the Bacula File daemon: " + echo -n "Stopping Bacula File services: " killproc @sbindir@/bacula-fd RETVAL=$? echo diff --git a/bacula/platforms/redhat/bacula-sd.in b/bacula/platforms/redhat/bacula-sd.in index cf8d1af373..3bfd6ed021 100755 --- a/bacula/platforms/redhat/bacula-sd.in +++ b/bacula/platforms/redhat/bacula-sd.in @@ -32,14 +32,14 @@ case "$1" in OPTIONS="${OPTIONS} -g ${SD_GROUP}" fi - echo -n "Starting the Bacula Storage daemon: " + echo -n "Starting Bacula Storage services: " daemon @sbindir@/bacula-sd $2 ${OPTIONS} -c @sysconfdir@/bacula-sd.conf RETVAL=$? echo [ $RETVAL -eq 0 ] && touch @subsysdir@/bacula-sd ;; stop) - echo -n "Stopping the Bacula Storage daemon: " + echo -n "Stopping Bacula Storage services: " killproc @sbindir@/bacula-sd RETVAL=$? echo diff --git a/bacula/src/bacula.h b/bacula/src/bacula.h index d40cdfb328..e662530756 100644 --- a/bacula/src/bacula.h +++ b/bacula/src/bacula.h @@ -5,7 +5,7 @@ */ /* - 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/bc_types.h b/bacula/src/bc_types.h index 3229b35d0e..632acd00e3 100644 --- a/bacula/src/bc_types.h +++ b/bacula/src/bc_types.h @@ -15,7 +15,7 @@ */ /* - 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/cats/sql_delete.c b/bacula/src/cats/sql_delete.c index 839c9b39e2..c24c786317 100644 --- a/bacula/src/cats/sql_delete.c +++ b/bacula/src/cats/sql_delete.c @@ -155,6 +155,7 @@ static int do_media_purge(B_DB *mdb, MEDIA_DBR *mr) { POOLMEM *query = get_pool_memory(PM_MESSAGE); struct s_del_ctx del; + char ed1[50]; int i; del.num_ids = 0; @@ -173,11 +174,11 @@ static int do_media_purge(B_DB *mdb, MEDIA_DBR *mr) for (i=0; i < del.num_ids; i++) { Dmsg1(400, "Delete JobId=%d\n", del.JobId[i]); - Mmsg(query, "DELETE FROM Job WHERE JobId=%u", del.JobId[i]); + Mmsg(query, "DELETE FROM Job WHERE JobId=%s", edit_int64(del.JobId[i], ed1)); db_sql_query(mdb, query, NULL, (void *)NULL); - Mmsg(query, "DELETE FROM File WHERE JobId=%u", del.JobId[i]); + Mmsg(query, "DELETE FROM File WHERE JobId=%s", edit_int64(del.JobId[i], ed1)); db_sql_query(mdb, query, NULL, (void *)NULL); - Mmsg(query, "DELETE FROM JobMedia WHERE JobId=%u", del.JobId[i]); + Mmsg(query, "DELETE FROM JobMedia WHERE JobId=%s", edit_int64(del.JobId[i], ed1)); db_sql_query(mdb, query, NULL, (void *)NULL); } free(del.JobId); diff --git a/bacula/src/cats/sql_find.c b/bacula/src/cats/sql_find.c index f364ca9141..6151fa1502 100644 --- a/bacula/src/cats/sql_find.c +++ b/bacula/src/cats/sql_find.c @@ -65,6 +65,7 @@ int db_find_job_start_time(JCR *jcr, B_DB *mdb, JOB_DBR *jr, POOLMEM **stime) { SQL_ROW row; + char ed1[50], ed2[50]; db_lock(mdb); @@ -74,9 +75,10 @@ db_find_job_start_time(JCR *jcr, B_DB *mdb, JOB_DBR *jr, POOLMEM **stime) /* Differential is since last Full backup */ Mmsg(mdb->cmd, "SELECT StartTime FROM Job WHERE JobStatus='T' AND Type='%c' AND " -"Level='%c' AND Name='%s' AND ClientId=%u AND FileSetId=%u " +"Level='%c' AND Name='%s' AND ClientId=%s AND FileSetId=%s " "ORDER BY StartTime DESC LIMIT 1", - jr->JobType, L_FULL, jr->Name, jr->ClientId, jr->FileSetId); + jr->JobType, L_FULL, jr->Name, + edit_int64(jr->ClientId, ed1), edit_int64(jr->FileSetId, ed2)); if (jr->JobLevel == L_DIFFERENTIAL) { /* SQL cmd for Differential backup already edited above */ @@ -105,10 +107,10 @@ db_find_job_start_time(JCR *jcr, B_DB *mdb, JOB_DBR *jr, POOLMEM **stime) /* Now edit SQL command for Incremental Job */ Mmsg(mdb->cmd, "SELECT StartTime FROM Job WHERE JobStatus='T' AND Type='%c' AND " -"Level IN ('%c','%c','%c') AND Name='%s' AND ClientId=%u " -"AND FileSetId=%u ORDER BY StartTime DESC LIMIT 1", +"Level IN ('%c','%c','%c') AND Name='%s' AND ClientId=%s " +"AND FileSetId=%s ORDER BY StartTime DESC LIMIT 1", jr->JobType, L_INCREMENTAL, L_DIFFERENTIAL, L_FULL, jr->Name, - jr->ClientId, jr->FileSetId); + edit_int64(jr->ClientId, ed1), edit_int64(jr->FileSetId, ed2)); } else { Mmsg1(&mdb->errmsg, _("Unknown level=%d\n"), jr->JobLevel); db_unlock(mdb); @@ -116,7 +118,8 @@ db_find_job_start_time(JCR *jcr, B_DB *mdb, JOB_DBR *jr, POOLMEM **stime) } } else { Dmsg1(100, "Submitting: %s\n", mdb->cmd); - Mmsg(mdb->cmd, "SELECT StartTime FROM Job WHERE Job.JobId=%u", jr->JobId); + Mmsg(mdb->cmd, "SELECT StartTime FROM Job WHERE Job.JobId=%s", + edit_int64(jr->JobId, ed1)); } if (!QUERY_DB(jcr, mdb, mdb->cmd)) { @@ -155,16 +158,18 @@ bool db_find_failed_job_since(JCR *jcr, B_DB *mdb, JOB_DBR *jr, POOLMEM *stime, int &JobLevel) { SQL_ROW row; + char ed1[50], ed2[50]; db_lock(mdb); /* Differential is since last Full backup */ Mmsg(mdb->cmd, "SELECT Level FROM Job WHERE JobStatus!='T' AND Type='%c' AND " -"Level IN ('%c','%c') AND Name='%s' AND ClientId=%u " -"AND FileSetId=%u AND StartTime>'%s' " +"Level IN ('%c','%c') AND Name='%s' AND ClientId=%s " +"AND FileSetId=%s AND StartTime>'%s' " "ORDER BY StartTime DESC LIMIT 1", jr->JobType, L_FULL, L_DIFFERENTIAL, jr->Name, - jr->ClientId, jr->FileSetId, stime); + edit_int64(jr->ClientId, ed1), edit_int64(jr->FileSetId, ed2), + stime); if (!QUERY_DB(jcr, mdb, mdb->cmd)) { db_unlock(mdb); @@ -196,6 +201,7 @@ int db_find_last_jobid(JCR *jcr, B_DB *mdb, const char *Name, JOB_DBR *jr) { SQL_ROW row; + char ed1[50]; /* Find last full */ db_lock(mdb); @@ -203,8 +209,9 @@ db_find_last_jobid(JCR *jcr, B_DB *mdb, const char *Name, JOB_DBR *jr) Mmsg(mdb->cmd, "SELECT JobId FROM Job WHERE Type='V' AND Level='%c' AND " " JobStatus='T' AND Name='%s' AND " -"ClientId=%u ORDER BY StartTime DESC LIMIT 1", - L_VERIFY_INIT, jr->Name, jr->ClientId); +"ClientId=%s ORDER BY StartTime DESC LIMIT 1", + L_VERIFY_INIT, jr->Name, + edit_int64(jr->ClientId, ed1)); } else if (jr->JobLevel == L_VERIFY_VOLUME_TO_CATALOG || jr->JobLevel == L_VERIFY_DISK_TO_CATALOG) { if (Name) { @@ -214,7 +221,8 @@ db_find_last_jobid(JCR *jcr, B_DB *mdb, const char *Name, JOB_DBR *jr) } else { Mmsg(mdb->cmd, "SELECT JobId FROM Job WHERE Type='B' AND JobStatus='T' AND " -"ClientId=%u ORDER BY StartTime DESC LIMIT 1", jr->ClientId); +"ClientId=%s ORDER BY StartTime DESC LIMIT 1", + edit_int64(jr->ClientId, ed1)); } } else { Mmsg1(&mdb->errmsg, _("Unknown Job level=%c\n"), jr->JobLevel); @@ -261,6 +269,7 @@ db_find_next_volume(JCR *jcr, B_DB *mdb, int item, bool InChanger, MEDIA_DBR *mr SQL_ROW row; int numrows; const char *changer, *order; + char ed1[50]; db_lock(mdb); if (item == -1) { /* find oldest volume */ @@ -270,9 +279,10 @@ db_find_next_volume(JCR *jcr, B_DB *mdb, int item, bool InChanger, MEDIA_DBR *mr "VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles,Recycle,Slot," "FirstWritten,LastWritten,VolStatus,InChanger,VolParts," "LabelType " - "FROM Media WHERE PoolId=%u AND MediaType='%s' AND VolStatus IN ('Full'," + "FROM Media WHERE PoolId=%s AND MediaType='%s' AND VolStatus IN ('Full'," "'Recycle','Purged','Used','Append') " - "ORDER BY LastWritten LIMIT 1", mr->PoolId, mr->MediaType); + "ORDER BY LastWritten LIMIT 1", + edit_int64(mr->PoolId, ed1), mr->MediaType); item = 1; } else { /* Find next available volume */ @@ -292,10 +302,11 @@ db_find_next_volume(JCR *jcr, B_DB *mdb, int item, bool InChanger, MEDIA_DBR *mr "VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles,Recycle,Slot," "FirstWritten,LastWritten,VolStatus,InChanger,VolParts," "LabelType " - "FROM Media WHERE PoolId=%u AND MediaType='%s' AND VolStatus='%s' " + "FROM Media WHERE PoolId=%s AND MediaType='%s' AND VolStatus='%s' " "%s " "%s LIMIT %d", - mr->PoolId, mr->MediaType, mr->VolStatus, changer, order, item); + edit_int64(mr->PoolId, ed1), mr->MediaType, + mr->VolStatus, changer, order, item); } if (!QUERY_DB(jcr, mdb, mdb->cmd)) { db_unlock(mdb); diff --git a/bacula/src/cats/sql_get.c b/bacula/src/cats/sql_get.c index 8e10b42f8d..9d707d71b2 100644 --- a/bacula/src/cats/sql_get.c +++ b/bacula/src/cats/sql_get.c @@ -117,8 +117,11 @@ int db_get_file_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr, FILE_DBR *fdbr) } else { Mmsg(mdb->cmd, -"SELECT FileId, LStat, MD5 FROM File WHERE File.JobId=%u AND File.PathId=%u AND " -"File.FilenameId=%u", fdbr->JobId, fdbr->PathId, fdbr->FilenameId); +"SELECT FileId, LStat, MD5 FROM File WHERE File.JobId=%s AND File.PathId=%s AND " +"File.FilenameId=%s", + edit_int64(fdbr->JobId, ed1), + edit_int64(fdbr->PathId, ed2), + edit_int64(fdbr->FilenameId,ed3)); } Dmsg3(050, "Get_file_record JobId=%u FilenameId=%u PathId=%u\n", fdbr->JobId, fdbr->FilenameId, fdbr->PathId); @@ -142,8 +145,9 @@ 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=%u FilenameId=%u not found.\n"), - fdbr->PathId, fdbr->FilenameId); + Mmsg2(&mdb->errmsg, _("File record for PathId=%s FilenameId=%s not found.\n"), + edit_int64(fdbr->PathId, ed1), + edit_int64(fdbr->FilenameId, ed2)); } sql_free_result(mdb); } else { @@ -233,8 +237,8 @@ static int db_get_path_record(JCR *jcr, B_DB *mdb) } else { PathId = atoi(row[0]); if (PathId <= 0) { - Mmsg2(&mdb->errmsg, _("Get DB path record %s found bad record: %u\n"), - mdb->cmd, PathId); + Mmsg2(&mdb->errmsg, _("Get DB path record %s found bad record: %s\n"), + mdb->cmd, edit_int64(PathId, ed1)); PathId = 0; } else { /* Cache path */ @@ -285,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 %u\n"), jr->JobId); + 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 */ @@ -844,9 +848,9 @@ int db_get_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr) } if (QUERY_DB(jcr, mdb, mdb->cmd)) { + char ed1[50]; mdb->num_rows = sql_num_rows(mdb); if (mdb->num_rows > 1) { - char ed1[30]; Mmsg1(&mdb->errmsg, _("More than one Volume!: %s\n"), edit_uint64(mdb->num_rows, ed1)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); @@ -889,7 +893,8 @@ int db_get_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr) } } else { if (mr->MediaId != 0) { - Mmsg1(&mdb->errmsg, _("Media record MediaId=%u not found.\n"), mr->MediaId); + 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"), mr->VolumeName); diff --git a/bacula/src/cats/sql_list.c b/bacula/src/cats/sql_list.c index c6672a288e..7a1d177311 100644 --- a/bacula/src/cats/sql_list.c +++ b/bacula/src/cats/sql_list.c @@ -133,6 +133,7 @@ void db_list_media_records(JCR *jcr, B_DB *mdb, MEDIA_DBR *mdbr, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type) { + char ed1[50]; db_lock(mdb); if (type == VERT_LIST) { if (mdbr->VolumeName[0] != 0) { @@ -150,7 +151,8 @@ db_list_media_records(JCR *jcr, B_DB *mdb, MEDIA_DBR *mdbr, "VolCapacityBytes,VolStatus,Recycle,VolRetention," "VolUseDuration,MaxVolJobs,MaxVolFiles,MaxVolBytes,InChanger," "EndFile,EndBlock,VolParts,LabelType" - " FROM Media WHERE Media.PoolId=%u ORDER BY MediaId", mdbr->PoolId); + " FROM Media WHERE Media.PoolId=%s ORDER BY MediaId", + edit_int64(mdbr->PoolId, ed1)); } } else { if (mdbr->VolumeName[0] != 0) { @@ -160,7 +162,8 @@ db_list_media_records(JCR *jcr, B_DB *mdb, MEDIA_DBR *mdbr, } else { Mmsg(mdb->cmd, "SELECT MediaId,VolumeName,VolStatus," "VolBytes,VolFiles,VolRetention,Recycle,Slot,InChanger,MediaType,LastWritten " - "FROM Media WHERE Media.PoolId=%u ORDER BY MediaId", mdbr->PoolId); + "FROM Media WHERE Media.PoolId=%s ORDER BY MediaId", + edit_int64(mdbr->PoolId, ed1)); } } @@ -178,6 +181,7 @@ db_list_media_records(JCR *jcr, B_DB *mdb, MEDIA_DBR *mdbr, void db_list_jobmedia_records(JCR *jcr, B_DB *mdb, uint32_t JobId, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type) { + char ed1[50]; db_lock(mdb); if (type == VERT_LIST) { if (JobId > 0) { /* do by JobId */ @@ -185,7 +189,7 @@ void db_list_jobmedia_records(JCR *jcr, B_DB *mdb, uint32_t JobId, "FirstIndex,LastIndex,StartFile,JobMedia.EndFile,StartBlock," "JobMedia.EndBlock " "FROM JobMedia,Media WHERE Media.MediaId=JobMedia.MediaId " - "AND JobMedia.JobId=%u", JobId); + "AND JobMedia.JobId=%s", edit_int64(JobId, ed1)); } else { Mmsg(mdb->cmd, "SELECT JobMediaId,JobId,Media.MediaId,Media.VolumeName," "FirstIndex,LastIndex,StartFile,JobMedia.EndFile,StartBlock," @@ -197,7 +201,7 @@ void db_list_jobmedia_records(JCR *jcr, B_DB *mdb, uint32_t JobId, if (JobId > 0) { /* do by JobId */ Mmsg(mdb->cmd, "SELECT JobId,Media.VolumeName,FirstIndex,LastIndex " "FROM JobMedia,Media WHERE Media.MediaId=JobMedia.MediaId " - "AND JobMedia.JobId=%u", JobId); + "AND JobMedia.JobId=%s", edit_int64(JobId, ed1)); } else { Mmsg(mdb->cmd, "SELECT JobId,Media.VolumeName,FirstIndex,LastIndex " "FROM JobMedia,Media WHERE Media.MediaId=JobMedia.MediaId"); @@ -226,6 +230,7 @@ void db_list_job_records(JCR *jcr, B_DB *mdb, JOB_DBR *jr, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type) { + char ed1[50]; db_lock(mdb); if (type == VERT_LIST) { if (jr->JobId == 0 && jr->Job[0] == 0) { @@ -245,9 +250,10 @@ db_list_job_records(JCR *jcr, B_DB *mdb, JOB_DBR *jr, DB_LIST_HANDLER *sendit, "StartTime,EndTime,JobTDate," "VolSessionId,VolSessionTime,JobFiles,JobErrors," "JobMissingFiles,Job.PoolId,Pool.Name,Job.FileSetId,FileSet.FileSet " - "FROM Job,Client,Pool,FileSet WHERE Job.JobId=%u AND " + "FROM Job,Client,Pool,FileSet WHERE Job.JobId=%s AND " "Client.ClientId=Job.ClientId AND Pool.PoolId=Job.PoolId " - "AND FileSet.FileSetId=Job.FileSetId", jr->JobId); + "AND FileSet.FileSetId=Job.FileSetId", + edit_int64(jr->JobId, ed1)); } } else { if (jr->JobId == 0 && jr->Job[0] == 0) { @@ -256,7 +262,8 @@ db_list_job_records(JCR *jcr, B_DB *mdb, JOB_DBR *jr, DB_LIST_HANDLER *sendit, "FROM Job ORDER BY StartTime"); } else { /* single record */ Mmsg(mdb->cmd, "SELECT JobId,Name,StartTime,Type,Level," - "JobFiles,JobBytes,JobStatus FROM Job WHERE JobId=%u", jr->JobId); + "JobFiles,JobBytes,JobStatus FROM Job WHERE JobId=%s", + edit_int64(jr->JobId, ed1)); } } if (!QUERY_DB(jcr, mdb, mdb->cmd)) { @@ -316,14 +323,15 @@ db_list_job_totals(JCR *jcr, B_DB *mdb, JOB_DBR *jr, DB_LIST_HANDLER *sendit, vo #endif void -db_list_files_for_job(JCR *jcr, B_DB *mdb, uint32_t jobid, DB_LIST_HANDLER *sendit, void *ctx) +db_list_files_for_job(JCR *jcr, B_DB *mdb, JobId_t jobid, DB_LIST_HANDLER *sendit, void *ctx) { + char ed1[50]; db_lock(mdb); Mmsg(mdb->cmd, "SELECT " FN " AS Filename FROM File," -"Filename,Path WHERE File.JobId=%u AND Filename.FilenameId=File.FilenameId " +"Filename,Path WHERE File.JobId=%s AND Filename.FilenameId=File.FilenameId " "AND Path.PathId=File.PathId", - jobid); + edit_int64(jobid, ed1)); if (!QUERY_DB(jcr, mdb, mdb->cmd)) { db_unlock(mdb); diff --git a/bacula/src/cats/sql_update.c b/bacula/src/cats/sql_update.c index 5c8b76f6cc..7557d5f759 100644 --- a/bacula/src/cats/sql_update.c +++ b/bacula/src/cats/sql_update.c @@ -59,9 +59,11 @@ db_add_SIG_to_file_record(JCR *jcr, B_DB *mdb, FileId_t FileId, char *SIG, int type) { int stat; + char ed1[50]; db_lock(mdb); - Mmsg(mdb->cmd, "UPDATE File SET MD5='%s' WHERE FileId=%u", SIG, FileId); + Mmsg(mdb->cmd, "UPDATE File SET MD5='%s' WHERE FileId=%s", SIG, + edit_int64(FileId, ed1)); stat = UPDATE_DB(jcr, mdb, mdb->cmd); db_unlock(mdb); return stat; @@ -73,9 +75,11 @@ db_add_SIG_to_file_record(JCR *jcr, B_DB *mdb, FileId_t FileId, char *SIG, int db_mark_file_record(JCR *jcr, B_DB *mdb, FileId_t FileId, JobId_t JobId) { int stat; + char ed1[50], ed2[50]; db_lock(mdb); - Mmsg(mdb->cmd, "UPDATE File SET MarkId=%u WHERE FileId=%u", JobId, FileId); + Mmsg(mdb->cmd, "UPDATE File SET MarkId=%s WHERE FileId=%s", + edit_int64(JobId, ed1), edit_int64(FileId, ed2)); stat = UPDATE_DB(jcr, mdb, mdb->cmd); db_unlock(mdb); return stat; @@ -95,7 +99,7 @@ db_update_job_start_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr) struct tm tm; btime_t JobTDate; int stat; - char ed1[30]; + char ed1[50], ed2[50], ed3[50]; stime = jr->StartTime; localtime_r(&stime, &tm); @@ -104,9 +108,12 @@ db_update_job_start_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr) db_lock(mdb); Mmsg(mdb->cmd, "UPDATE Job SET JobStatus='%c',Level='%c',StartTime='%s'," -"ClientId=%u,JobTDate=%s WHERE JobId=%u", +"ClientId=%s,JobTDate=%s WHERE JobId=%s", (char)(jcr->JobStatus), - (char)(jr->JobLevel), dt, jr->ClientId, edit_uint64(JobTDate, ed1), jr->JobId); + (char)(jr->JobLevel), dt, + edit_int64(jr->ClientId, ed1), + edit_uint64(JobTDate, ed2), + edit_int64(jr->JobId, ed3)); stat = UPDATE_DB(jcr, mdb, mdb->cmd); mdb->changes = 0; @@ -119,8 +126,9 @@ db_update_job_start_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr) * * */ -void edit_num_or_null(char *s, size_t n, uint32_t id) { - bsnprintf(s, n, id ? "%u" : "NULL", id); +static void edit_num_or_null(char *s, size_t n, uint64_t id) { + char ed1[50]; + bsnprintf(s, n, id ? "%s" : "NULL", edit_int64(id, ed1)); } @@ -137,7 +145,7 @@ db_update_job_end_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr) time_t ttime; struct tm tm; int stat; - char ed1[30], ed2[30]; + char ed1[30], ed2[30], ed3[50]; btime_t JobTDate; char PoolId [50]; char FileSetId [50]; @@ -158,10 +166,11 @@ db_update_job_end_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr) Mmsg(mdb->cmd, "UPDATE Job SET JobStatus='%c', EndTime='%s', " "ClientId=%s, JobBytes=%s, JobFiles=%u, JobErrors=%u, VolSessionId=%u, " -"VolSessionTime=%u, PoolId=%s, FileSetId=%s, JobTDate=%s WHERE JobId=%u", +"VolSessionTime=%u, PoolId=%s, FileSetId=%s, JobTDate=%s WHERE JobId=%s", (char)(jr->JobStatus), dt, ClientId, edit_uint64(jr->JobBytes, ed1), jr->JobFiles, jr->JobErrors, jr->VolSessionId, jr->VolSessionTime, - PoolId, FileSetId, edit_uint64(JobTDate, ed2), jr->JobId); + PoolId, FileSetId, edit_uint64(JobTDate, ed2), + edit_int64(jr->JobId, ed3)); stat = UPDATE_DB(jcr, mdb, mdb->cmd); db_unlock(mdb); @@ -350,7 +359,7 @@ int db_update_media_defaults(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr) { int stat; - char ed1[30], ed2[30], ed3[30]; + char ed1[50], ed2[50], ed3[50], ed4[50]; db_lock(mdb); @@ -368,12 +377,12 @@ db_update_media_defaults(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr) Mmsg(mdb->cmd, "UPDATE Media SET " "Recycle=%d,VolRetention=%s,VolUseDuration=%s," "MaxVolJobs=%u,MaxVolFiles=%u,MaxVolBytes=%s" - " WHERE PoolId=%u", + " WHERE PoolId=%s", mr->Recycle,edit_uint64(mr->VolRetention, ed1), edit_uint64(mr->VolUseDuration, ed2), mr->MaxVolJobs, mr->MaxVolFiles, edit_uint64(mr->VolBytes, ed3), - mr->PoolId); + edit_int64(mr->PoolId, ed4)); } Dmsg1(400, "%s\n", mdb->cmd); @@ -394,10 +403,12 @@ db_update_media_defaults(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr) void db_make_inchanger_unique(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr) { + char ed1[50], ed2[50]; if (mr->InChanger != 0 && mr->Slot != 0) { Mmsg(mdb->cmd, "UPDATE Media SET InChanger=0 WHERE " - "Slot=%d AND PoolId=%u AND MediaId!=%u", - mr->Slot, mr->PoolId, mr->MediaId); + "Slot=%d AND PoolId=%s AND MediaId!=%s", + mr->Slot, + edit_int64(mr->PoolId, ed1), edit_int64(mr->MediaId, ed2)); Dmsg1(400, "%s\n", mdb->cmd); UPDATE_DB(jcr, mdb, mdb->cmd); } diff --git a/bacula/src/cats/update_mysql_tables.in b/bacula/src/cats/update_mysql_tables.in index 7d6e579e86..0ff6b4146d 100755 --- a/bacula/src/cats/update_mysql_tables.in +++ b/bacula/src/cats/update_mysql_tables.in @@ -1,9 +1,9 @@ #!/bin/sh # -# Shell script to update MySQL tables from version 1.34 to 1.35.5 +# Shell script to update MySQL tables from version 1.36 to 1.37.3 # echo " " -echo "This script will update a Bacula MySQL database from version 7 to 8" +echo "This script will update a Bacula MySQL database from version 8 to 9" echo "Depending on the size of your database," echo "this script may take several minutes to run." echo " " @@ -16,6 +16,39 @@ ALTER TABLE Media ADD COLUMN LabelType INTEGER UNSIGNED NOT NULL DEFAULT 0; ALTER TABLE Pool ADD COLUMN LabelType INTEGER UNSIGNED NOT NULL DEFAULT 0; ALTER TABLE Media ADD COLUMN VolParts INTEGER UNSIGNED NOT NULL DEFAULT 0; +CREATE TABLE MediaType ( + MediaTypeId INTERGER UNSIGNED NOT NULL AUTO_INCREMENT, + MediaType VARCHAR(128) NOT NULL, + ReadOnly TINYINT DEFAULT 0, + PRIMARY KEY(MediaTypeId) + ); + +CREATE TABLE Device ( + DeviceId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, + Name VARCHAR(128) NOT NULL, + MediaTypeId INTEGER UNSIGNED REFERENCES MediaType NOT NULL, + StorageId INTEGER UNSIGNED REFERENCES Storage, + DevMounts INTEGER UNSIGNED DEFAULT 0, + DevReadBytes BIGINT UNSIGNED DEFAULT 0, + DevWriteBytes BIGINT UNSIGNED DEFAULT 0, + DevReadBytesSinceCleaning BIGINT UNSIGNED DEFAULT 0, + DevWriteBytesSinceCleaning BIGINT UNSIGNED DEFAULT 0, + DevReadTime BIGINT UNSIGNED DEFAULT 0, + DevWriteTime BIGINT UNSIGNED DEFAULT 0, + DevReadTimeSinceCleaning BIGINT UNSIGNED DEFAULT 0, + DevWriteTimeSinceCleaning BIGINT UNSIGNED DEFAULT 0, + CleaningDate DATETIME DEFAULT 0, + CleaningPeriod BIGINT UNSIGNED DEFAULT 0, + PRIMARY KEY(DeviceId) + ); + +CREATE TABLE Storage ( + StorageId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, + Name VARCHAR(128) NOT NULL, + AutoChanger TINYINT DEFAULT 0, + PRIMARY KEY(StorageId) + ); + END-OF-DATA then echo "Update of Bacula MySQL tables succeeded." diff --git a/bacula/src/cats/update_postgresql_tables.in b/bacula/src/cats/update_postgresql_tables.in index 5be47510e7..0c93be6062 100755 --- a/bacula/src/cats/update_postgresql_tables.in +++ b/bacula/src/cats/update_postgresql_tables.in @@ -1,9 +1,9 @@ #!/bin/sh # -# Shell script to update PostgreSQL tables from version 1.34 to 1.35.5 +# Shell script to update PostgreSQL tables from version 1.36 to 1.37.3 # echo " " -echo "This script will update a Bacula PostgreSQL database from version 7 to 8" +echo "This script will update a Bacula PostgreSQL database from version 8 to 9" echo "Depending on the size of your database," echo "this script may take several minutes to run." echo " " @@ -23,6 +23,39 @@ ALTER TABLE media ADD COLUMN volparts integer; UPDATE media SET volparts=0; ALTER TABLE media ALTER COLUMN volparts SET NOT NULL; +CREATE TABLE MediaType ( + MediaTypeId SERIAL, + MediaType TEXT NOT NULL, + ReadOnly INTEGER DEFAULT 0, + PRIMARY KEY(MediaTypeId) + ); + +CREATE TABLE Device ( + DeviceId SERIAL, + Name TEXT NOT NULL, + MediaTypeId INTEGER NOT NULL, + StorageId INTEGER UNSIGNED, + DevMounts INTEGER NOT NULL DEFAULT 0, + DevReadBytes BIGINT NOT NULL DEFAULT 0, + DevWriteBytes BIGINT NOT NULL DEFAULT 0, + DevReadBytesSinceCleaning BIGINT NOT NULL DEFAULT 0, + DevWriteBytesSinceCleaning BIGINT NOT NULL DEFAULT 0, + DevReadTime BIGINT NOT NULL DEFAULT 0, + DevWriteTime BIGINT NOT NULL DEFAULT 0, + DevReadTimeSinceCleaning BIGINT NOT NULL DEFAULT 0, + DevWriteTimeSinceCleaning BIGINT UNSIGNED DEFAULT 0, + CleaningDate TIMESTAMP WITHOUT TIME ZONE, + CleaningPeriod BIGINT NOT NULL DEFAULT 0, + PRIMARY KEY(DeviceId) + ); + +CREATE TABLE Storage ( + StorageId SERIAL, + Name TEXT NOT NULL, + AutoChanger INTEGER DEFAULT 0, + PRIMARY KEY(StorageId) + ); + vacuum; END-OF-DATA diff --git a/bacula/src/cats/update_sqlite_tables.in b/bacula/src/cats/update_sqlite_tables.in index f5cf32813f..4675ba1e31 100755 --- a/bacula/src/cats/update_sqlite_tables.in +++ b/bacula/src/cats/update_sqlite_tables.in @@ -1,9 +1,9 @@ #!/bin/sh # -# shell script to update SQLite from version 1.34 to 1.35.5 +# shell script to update SQLite from version 1.36 to 1.37.3 # echo " " -echo "This script will update a Bacula SQLite database from version 7 to 8" +echo "This script will update a Bacula SQLite database from version 8 to 9" echo "Depending on the size of your database," echo "this script may take several minutes to run." echo " " @@ -184,6 +184,39 @@ INSERT INTO Pool ( DROP TABLE Pool_backup; +CREATE TABLE MediaType ( + MediaTypeId INTERGER, + MediaType VARCHAR(128) NOT NULL, + ReadOnly TINYINT DEFAULT 0, + PRIMARY KEY(MediaTypeId) + ); + +CREATE TABLE Device ( + DeviceId INTEGER, + Name VARCHAR(128) NOT NULL, + MediaTypeId INTEGER UNSIGNED REFERENCES MediaType NOT NULL, + StorageId INTEGER UNSIGNED REFERENCES Storage, + DevMounts INTEGER UNSIGNED DEFAULT 0, + DevReadBytes BIGINT UNSIGNED DEFAULT 0, + DevWriteBytes BIGINT UNSIGNED DEFAULT 0, + DevReadBytesSinceCleaning BIGINT UNSIGNED DEFAULT 0, + DevWriteBytesSinceCleaning BIGINT UNSIGNED DEFAULT 0, + DevReadTime BIGINT UNSIGNED DEFAULT 0, + DevWriteTime BIGINT UNSIGNED DEFAULT 0, + DevReadTimeSinceCleaning BIGINT UNSIGNED DEFAULT 0, + DevWriteTimeSinceCleaning BIGINT UNSIGNED DEFAULT 0, + CleaningDate DATETIME DEFAULT 0, + CleaningPeriod BIGINT UNSIGNED DEFAULT 0, + PRIMARY KEY(DeviceId) + ); + +CREATE TABLE Storage ( + StorageId INTEGER, + Name VARCHAR(128) NOT NULL, + AutoChanger TINYINT DEFAULT 0, + PRIMARY KEY(StorageId) + ); + COMMIT; END-OF-DATA diff --git a/bacula/src/dird/bsr.c b/bacula/src/dird/bsr.c index 9554cf2db7..dd6f4b0a0e 100644 --- a/bacula/src/dird/bsr.c +++ b/bacula/src/dird/bsr.c @@ -310,6 +310,8 @@ void print_bsr(UAContext *ua, RBSR *bsr) } + + /* * Add a FileIndex to the list of BootStrap records. * Here we are only dealing with JobId's and the FileIndexes @@ -406,3 +408,54 @@ void add_findex(RBSR *bsr, uint32_t JobId, int32_t findex) lfi->next = fi; return; } + +/* + * Add all possible FileIndexes to the list of BootStrap records. + * Here we are only dealing with JobId's and the FileIndexes + * associated with those JobIds. + */ +void add_findex_all(RBSR *bsr, uint32_t JobId) +{ + RBSR *nbsr; + RBSR_FINDEX *fi; + + if (bsr->fi == NULL) { /* if no FI add one */ + /* This is the first FileIndex item in the chain */ + bsr->fi = new_findex(); + bsr->JobId = JobId; + bsr->fi->findex = 1; + bsr->fi->findex2 = INT32_MAX; + return; + } + /* Walk down list of bsrs until we find the JobId */ + if (bsr->JobId != JobId) { + for (nbsr=bsr->next; nbsr; nbsr=nbsr->next) { + if (nbsr->JobId == JobId) { + bsr = nbsr; + break; + } + } + + if (!nbsr) { /* Must add new JobId */ + /* Add new JobId at end of chain */ + for (nbsr=bsr; nbsr->next; nbsr=nbsr->next) + { } + nbsr->next = new_bsr(); + nbsr->next->JobId = JobId; + nbsr->next->fi = new_findex(); + nbsr->next->fi->findex = 1; + nbsr->next->fi->findex2 = INT32_MAX; + return; + } + } + + /* + * At this point, bsr points to bsr containing this JobId, + * and we are sure that there is at least one fi record. + */ + fi = bsr->fi; + fi->findex = 1; + fi->findex2 = INT32_MAX; + return; +} + diff --git a/bacula/src/dird/bsr.h b/bacula/src/dird/bsr.h index aea7e18af2..e89025e5f6 100644 --- a/bacula/src/dird/bsr.h +++ b/bacula/src/dird/bsr.h @@ -2,8 +2,8 @@ * * Bootstrap Record header file * - * BSR (bootstrap record) handling routines split from - * ua_restore.c July MMIII + * BSR (bootstrap record) handling routines split from + * ua_restore.c July MMIII * * Kern Sibbald, July MMII * @@ -11,7 +11,7 @@ */ /* - Copyright (C) 2002-2004 Kern Sibbald and John Walker + Copyright (C) 2002-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 @@ -47,11 +47,11 @@ struct RBSR_FINDEX { * on which the Job is stored to the BSR. */ struct RBSR { - RBSR *next; /* next JobId */ - uint32_t JobId; /* JobId this bsr */ + RBSR *next; /* next JobId */ + uint32_t JobId; /* JobId this bsr */ uint32_t VolSessionId; uint32_t VolSessionTime; - int VolCount; /* Volume parameter count */ - VOL_PARAMS *VolParams; /* Volume, start/end file/blocks */ - RBSR_FINDEX *fi; /* File indexes this JobId */ + int VolCount; /* Volume parameter count */ + VOL_PARAMS *VolParams; /* Volume, start/end file/blocks */ + RBSR_FINDEX *fi; /* File indexes this JobId */ }; diff --git a/bacula/src/dird/protos.h b/bacula/src/dird/protos.h index 07a3700353..e220d9eaf4 100644 --- a/bacula/src/dird/protos.h +++ b/bacula/src/dird/protos.h @@ -46,6 +46,7 @@ void free_bsr(RBSR *bsr); int complete_bsr(UAContext *ua, RBSR *bsr); uint32_t write_bsr_file(UAContext *ua, RBSR *bsr); void add_findex(RBSR *bsr, uint32_t JobId, int32_t findex); +void add_findex_all(RBSR *bsr, uint32_t JobId); RBSR_FINDEX *new_findex(); diff --git a/bacula/src/dird/recycle.c b/bacula/src/dird/recycle.c index 1b785dfbde..bb6c7987f9 100644 --- a/bacula/src/dird/recycle.c +++ b/bacula/src/dird/recycle.c @@ -70,19 +70,21 @@ int find_recycled_volume(JCR *jcr, bool InChanger, MEDIA_DBR *mr) int recycle_oldest_purged_volume(JCR *jcr, bool InChanger, MEDIA_DBR *mr) { struct s_oldest_ctx oldest; + char ed1[50]; POOLMEM *query = get_pool_memory(PM_EMSG); const char *select = - "SELECT MediaId,LastWritten FROM Media " - "WHERE PoolId=%u AND Recycle=1 AND VolStatus='Purged' " - "AND MediaType='%s' %s" - "ORDER BY LastWritten ASC,MediaId LIMIT 1"; + "SELECT MediaId,LastWritten FROM Media " + "WHERE PoolId=%s AND Recycle=1 AND VolStatus='Purged' " + "AND MediaType='%s' %s" + "ORDER BY LastWritten ASC,MediaId LIMIT 1"; Dmsg0(100, "Enter recycle_oldest_purged_volume\n"); oldest.MediaId = 0; if (InChanger) { - Mmsg(query, select, mr->PoolId, mr->MediaType, "AND InChanger=1 "); + Mmsg(query, select, edit_int64(mr->PoolId, ed1), mr->MediaType, + "AND InChanger=1 "); } else { - Mmsg(query, select, mr->PoolId, mr->MediaType, ""); + Mmsg(query, select, edit_int64(mr->PoolId, ed1), mr->MediaType, ""); } if (!db_sql_query(jcr->db, query, oldest_handler, (void *)&oldest)) { @@ -97,8 +99,8 @@ int recycle_oldest_purged_volume(JCR *jcr, bool InChanger, MEDIA_DBR *mr) mr->MediaId = oldest.MediaId; if (db_get_media_record(jcr, jcr->db, mr)) { if (recycle_volume(jcr, mr)) { - Jmsg(jcr, M_INFO, 0, "Recycled volume \"%s\"\n", mr->VolumeName); - Dmsg1(100, "return 1 recycle_oldest_purged_volume Vol=%s\n", mr->VolumeName); + Jmsg(jcr, M_INFO, 0, "Recycled volume \"%s\"\n", mr->VolumeName); + Dmsg1(100, "return 1 recycle_oldest_purged_volume Vol=%s\n", mr->VolumeName); return 1; } } diff --git a/bacula/src/dird/sql_cmds.c b/bacula/src/dird/sql_cmds.c index 98432c1c57..0aa0720ecd 100644 --- a/bacula/src/dird/sql_cmds.c +++ b/bacula/src/dird/sql_cmds.c @@ -220,6 +220,7 @@ const char *uar_create_temp = "ClientId INTEGER," "Level CHAR," "JobFiles INTEGER," + "JobBytes BIGINT," "StartTime TEXT," "VolumeName TEXT," "StartFile INTEGER," @@ -231,6 +232,7 @@ const char *uar_create_temp = "ClientId INTEGER UNSIGNED," "Level CHAR," "JobFiles INTEGER UNSIGNED," + "JobBytes BIGINT UNSIGNED," "StartTime TEXT," "VolumeName TEXT," "StartFile INTEGER UNSIGNED," @@ -263,8 +265,8 @@ const char *uar_last_full = const char *uar_full = "INSERT INTO temp SELECT Job.JobId,Job.JobTDate," - " Job.ClientId,Job.Level,Job.JobFiles," - " StartTime,VolumeName,JobMedia.StartFile,VolSessionId,VolSessionTime " + "Job.ClientId,Job.Level,Job.JobFiles,Job.JobBytes," + "StartTime,VolumeName,JobMedia.StartFile,VolSessionId,VolSessionTime " "FROM temp1,Job,JobMedia,Media WHERE temp1.JobId=Job.JobId " "AND Level='F' AND JobStatus='T' " "AND JobMedia.JobId=Job.JobId " @@ -272,7 +274,8 @@ const char *uar_full = const char *uar_dif = "INSERT INTO temp SELECT Job.JobId,Job.JobTDate,Job.ClientId," - "Job.Level,Job.JobFiles,Job.StartTime,Media.VolumeName,JobMedia.StartFile," + "Job.Level,Job.JobFiles,Job.JobBytes," + "Job.StartTime,Media.VolumeName,JobMedia.StartFile," "Job.VolSessionId,Job.VolSessionTime " "FROM Job,JobMedia,Media,FileSet " "WHERE Job.JobTDate>%s AND Job.StartTime<'%s' " @@ -287,7 +290,8 @@ const char *uar_dif = const char *uar_inc = "INSERT INTO temp SELECT Job.JobId,Job.JobTDate,Job.ClientId," - "Job.Level,Job.JobFiles,Job.StartTime,Media.VolumeName,JobMedia.StartFile," + "Job.Level,Job.JobFiles,Job.JobBytes," + "Job.StartTime,Media.VolumeName,JobMedia.StartFile," "Job.VolSessionId,Job.VolSessionTime " "FROM Job,JobMedia,Media,FileSet " "WHERE Job.JobTDate>%s AND Job.StartTime<'%s' " @@ -300,9 +304,9 @@ const char *uar_inc = "%s"; const char *uar_list_temp = - "SELECT JobId,Level,JobFiles,StartTime,VolumeName,StartFile," - "VolSessionId,VolSessionTime FROM temp " - "ORDER BY StartTime ASC"; + "SELECT JobId,Level,JobFiles,JobBytes,StartTime,VolumeName,StartFile" + " FROM temp" + " GROUP BY JobId ORDER BY StartTime,StartFile ASC"; const char *uar_sel_jobid_temp = "SELECT JobId FROM temp ORDER BY StartTime ASC"; @@ -353,3 +357,17 @@ const char *uar_jobids_fileindex = "AND Path.PathId=File.PathId " "AND Filename.FilenameId=File.FilenameId " "ORDER BY Job.StartTime DESC LIMIT 1"; + +/* Query to get all files in a directory -- no recursing */ +// cleanup needed -- add client, ... +const char *uar_jobid_fileindex_from_dir = + "SELECT Job.JobId,File.FileIndex FROM Job,File,Path,Filename,Client " + "WHERE Job.JobId IN (%s) " + "WHERE Job.JobId=File.JobId " + "AND Path.Path='%s' " + "AND Client.Name='%s' " + "AND Job.ClientId=Client.ClientId " + "AND Path.PathId=File.Pathid " + "AND Filename.FilenameId=File.FilenameId " + "GROUP BY File.FileIndex "; + diff --git a/bacula/src/dird/ua.h b/bacula/src/dird/ua.h index 0c07a1c872..43b79a08e7 100644 --- a/bacula/src/dird/ua.h +++ b/bacula/src/dird/ua.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 @@ -51,6 +51,7 @@ struct UAContext { bool batch; /* set for non-interactive mode */ uint32_t pint32_val; /* positive integer */ int32_t int32_val; /* positive/negative */ + int64_t int64_val; /* big int */ }; /* Context for insert_tree_handler() */ diff --git a/bacula/src/dird/ua_cmds.c b/bacula/src/dird/ua_cmds.c index b3c4279b28..0c0644488a 100644 --- a/bacula/src/dird/ua_cmds.c +++ b/bacula/src/dird/ua_cmds.c @@ -8,7 +8,7 @@ */ /* - 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 @@ -703,9 +703,10 @@ static void update_volstatus(UAContext *ua, const char *val, MEDIA_DBR *mr) if (!found) { bsendmsg(ua, _("Invalid VolStatus specified: %s\n"), val); } else { + char ed1[50]; bstrncpy(mr->VolStatus, kw[i], sizeof(mr->VolStatus)); - Mmsg(query, "UPDATE Media SET VolStatus='%s' WHERE MediaId=%u", - mr->VolStatus, mr->MediaId); + Mmsg(query, "UPDATE Media SET VolStatus='%s' WHERE MediaId=%s", + mr->VolStatus, edit_int64(mr->MediaId,ed1)); if (!db_sql_query(ua->db, query, NULL, NULL)) { bsendmsg(ua, "%s", db_strerror(ua->db)); } else { @@ -717,15 +718,15 @@ static void update_volstatus(UAContext *ua, const char *val, MEDIA_DBR *mr) static void update_volretention(UAContext *ua, char *val, MEDIA_DBR *mr) { - char ed1[150]; + char ed1[150], ed2[50]; POOLMEM *query; if (!duration_to_utime(val, &mr->VolRetention)) { bsendmsg(ua, _("Invalid retention period specified: %s\n"), val); return; } query = get_pool_memory(PM_MESSAGE); - Mmsg(query, "UPDATE Media SET VolRetention=%s WHERE MediaId=%u", - edit_uint64(mr->VolRetention, ed1), mr->MediaId); + Mmsg(query, "UPDATE Media SET VolRetention=%s WHERE MediaId=%s", + edit_uint64(mr->VolRetention, ed1), edit_int64(mr->MediaId,ed2)); if (!db_sql_query(ua->db, query, NULL, NULL)) { bsendmsg(ua, "%s", db_strerror(ua->db)); } else { @@ -737,7 +738,7 @@ static void update_volretention(UAContext *ua, char *val, MEDIA_DBR *mr) static void update_voluseduration(UAContext *ua, char *val, MEDIA_DBR *mr) { - char ed1[150]; + char ed1[150], ed2[50]; POOLMEM *query; if (!duration_to_utime(val, &mr->VolUseDuration)) { @@ -745,8 +746,8 @@ static void update_voluseduration(UAContext *ua, char *val, MEDIA_DBR *mr) return; } query = get_pool_memory(PM_MESSAGE); - Mmsg(query, "UPDATE Media SET VolUseDuration=%s WHERE MediaId=%u", - edit_uint64(mr->VolUseDuration, ed1), mr->MediaId); + Mmsg(query, "UPDATE Media SET VolUseDuration=%s WHERE MediaId=%s", + edit_uint64(mr->VolUseDuration, ed1), edit_int64(mr->MediaId,ed2)); if (!db_sql_query(ua->db, query, NULL, NULL)) { bsendmsg(ua, "%s", db_strerror(ua->db)); } else { @@ -759,8 +760,9 @@ static void update_voluseduration(UAContext *ua, char *val, MEDIA_DBR *mr) static void update_volmaxjobs(UAContext *ua, char *val, MEDIA_DBR *mr) { POOLMEM *query = get_pool_memory(PM_MESSAGE); - Mmsg(query, "UPDATE Media SET MaxVolJobs=%s WHERE MediaId=%u", - val, mr->MediaId); + char ed1[50]; + Mmsg(query, "UPDATE Media SET MaxVolJobs=%s WHERE MediaId=%s", + val, edit_int64(mr->MediaId,ed1)); if (!db_sql_query(ua->db, query, NULL, NULL)) { bsendmsg(ua, "%s", db_strerror(ua->db)); } else { @@ -772,8 +774,9 @@ static void update_volmaxjobs(UAContext *ua, char *val, MEDIA_DBR *mr) static void update_volmaxfiles(UAContext *ua, char *val, MEDIA_DBR *mr) { POOLMEM *query = get_pool_memory(PM_MESSAGE); - Mmsg(query, "UPDATE Media SET MaxVolFiles=%s WHERE MediaId=%u", - val, mr->MediaId); + char ed1[50]; + Mmsg(query, "UPDATE Media SET MaxVolFiles=%s WHERE MediaId=%s", + val, edit_int64(mr->MediaId, ed1)); if (!db_sql_query(ua->db, query, NULL, NULL)) { bsendmsg(ua, "%s", db_strerror(ua->db)); } else { @@ -785,7 +788,7 @@ static void update_volmaxfiles(UAContext *ua, char *val, MEDIA_DBR *mr) static void update_volmaxbytes(UAContext *ua, char *val, MEDIA_DBR *mr) { uint64_t maxbytes; - char ed1[50]; + char ed1[50], ed2[50]; POOLMEM *query; if (!size_to_uint64(val, strlen(val), &maxbytes)) { @@ -793,8 +796,8 @@ static void update_volmaxbytes(UAContext *ua, char *val, MEDIA_DBR *mr) return; } query = get_pool_memory(PM_MESSAGE); - Mmsg(query, "UPDATE Media SET MaxVolBytes=%s WHERE MediaId=%u", - edit_uint64(maxbytes, ed1), mr->MediaId); + Mmsg(query, "UPDATE Media SET MaxVolBytes=%s WHERE MediaId=%s", + edit_uint64(maxbytes, ed1), edit_int64(mr->MediaId, ed2)); if (!db_sql_query(ua->db, query, NULL, NULL)) { bsendmsg(ua, "%s", db_strerror(ua->db)); } else { @@ -806,6 +809,7 @@ static void update_volmaxbytes(UAContext *ua, char *val, MEDIA_DBR *mr) static void update_volrecycle(UAContext *ua, char *val, MEDIA_DBR *mr) { int recycle; + char ed1[50]; POOLMEM *query; if (strcasecmp(val, _("yes")) == 0) { recycle = 1; @@ -816,8 +820,8 @@ static void update_volrecycle(UAContext *ua, char *val, MEDIA_DBR *mr) return; } query = get_pool_memory(PM_MESSAGE); - Mmsg(query, "UPDATE Media SET Recycle=%d WHERE MediaId=%u", - recycle, mr->MediaId); + Mmsg(query, "UPDATE Media SET Recycle=%d WHERE MediaId=%s", + recycle, edit_int64(mr->MediaId, ed1)); if (!db_sql_query(ua->db, query, NULL, NULL)) { bsendmsg(ua, "%s", db_strerror(ua->db)); } else { @@ -832,6 +836,7 @@ static void update_vol_pool(UAContext *ua, char *val, MEDIA_DBR *mr, POOL_DBR *o { POOL_DBR pr; POOLMEM *query; + char ed1[50]; memset(&pr, 0, sizeof(pr)); bstrncpy(pr.Name, val, sizeof(pr.Name)); @@ -843,8 +848,8 @@ static void update_vol_pool(UAContext *ua, char *val, MEDIA_DBR *mr, POOL_DBR *o */ query = get_pool_memory(PM_MESSAGE); db_lock(ua->db); - Mmsg(query, "UPDATE Media SET PoolId=%d WHERE MediaId=%u", - mr->PoolId, mr->MediaId); + Mmsg(query, "UPDATE Media SET PoolId=%d WHERE MediaId=%s", + mr->PoolId, edit_int64(mr->MediaId, ed1)); if (!db_sql_query(ua->db, query, NULL, NULL)) { bsendmsg(ua, "%s", db_strerror(ua->db)); } else { @@ -1141,8 +1146,8 @@ static int update_volume(UAContext *ua) } } query = get_pool_memory(PM_MESSAGE); - Mmsg(query, "UPDATE Media SET VolFiles=%u WHERE MediaId=%u", - VolFiles, mr.MediaId); + 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)) { bsendmsg(ua, "%s", db_strerror(ua->db)); } else { @@ -1764,7 +1769,7 @@ static void delete_job(UAContext *ua) } else if (!get_pint(ua, _("Enter JobId to delete: "))) { return; } else { - JobId = ua->pint32_val; + JobId = ua->int64_val; do_job_delete(ua, JobId); } } @@ -1795,15 +1800,16 @@ static void delete_job_id_range(UAContext *ua, char *tok) static void do_job_delete(UAContext *ua, JobId_t JobId) { POOLMEM *query = get_pool_memory(PM_MESSAGE); + char ed1[50]; - Mmsg(query, "DELETE FROM Job WHERE JobId=%u", JobId); + Mmsg(query, "DELETE FROM Job WHERE JobId=%s", edit_int64(JobId, ed1)); db_sql_query(ua->db, query, NULL, (void *)NULL); - Mmsg(query, "DELETE FROM File WHERE JobId=%u", JobId); + Mmsg(query, "DELETE FROM File WHERE JobId=%s", edit_int64(JobId, ed1)); db_sql_query(ua->db, query, NULL, (void *)NULL); - Mmsg(query, "DELETE FROM JobMedia WHERE JobId=%u", JobId); + Mmsg(query, "DELETE FROM JobMedia WHERE JobId=%s", edit_int64(JobId, ed1)); db_sql_query(ua->db, query, NULL, (void *)NULL); free_pool_memory(query); - bsendmsg(ua, _("Job %u and associated records deleted from the catalog.\n"), JobId); + bsendmsg(ua, _("Job %s and associated records deleted from the catalog.\n"), edit_int64(JobId, ed1)); } /* diff --git a/bacula/src/dird/ua_input.c b/bacula/src/dird/ua_input.c index 99a74ae6aa..5f19b78139 100644 --- a/bacula/src/dird/ua_input.c +++ b/bacula/src/dird/ua_input.c @@ -78,6 +78,7 @@ bool get_pint(UAContext *ua, const char *prompt) { double dval; ua->pint32_val = 0; + ua->int64_val = 0; for (;;) { ua->cmd[0] = 0; if (!get_cmd(ua, prompt)) { @@ -85,7 +86,6 @@ bool get_pint(UAContext *ua, const char *prompt) } /* Kludge for slots blank line => 0 */ if (ua->cmd[0] == 0 && strncmp(prompt, "Enter slot", 10) == 0) { - ua->pint32_val = 0; return true; } if (!is_a_number(ua->cmd)) { @@ -99,6 +99,7 @@ bool get_pint(UAContext *ua, const char *prompt) continue; } ua->pint32_val = (uint32_t)dval; + ua->int64_val = (int64_t)dval; return true; } } diff --git a/bacula/src/dird/ua_label.c b/bacula/src/dird/ua_label.c index 14d653ba97..f73e192b68 100644 --- a/bacula/src/dird/ua_label.c +++ b/bacula/src/dird/ua_label.c @@ -8,7 +8,7 @@ */ /* - Copyright (C) 2000-2004 Kern Sibbald + 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/dird/ua_prune.c b/bacula/src/dird/ua_prune.c index 7f769c75d9..3de4babf02 100644 --- a/bacula/src/dird/ua_prune.c +++ b/bacula/src/dird/ua_prune.c @@ -9,7 +9,7 @@ */ /* - Copyright (C) 2002-2004 Kern Sibbald and John Walker + Copyright (C) 2002-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 @@ -89,7 +89,7 @@ static int count_handler(void *ctx, int num_fields, char **row) struct s_count_ctx *cnt = (struct s_count_ctx *)ctx; if (row[0]) { - cnt->count = atoi(row[0]); + cnt->count = str_to_int64(row[0]); } else { cnt->count = 0; } @@ -249,7 +249,7 @@ int prune_files(UAContext *ua, CLIENT *client) Dmsg1(050, "select sql=%s\n", query); if (!db_sql_query(ua->db, query, file_count_handler, (void *)&del)) { if (ua->verbose) { - bsendmsg(ua, "%s", db_strerror(ua->db)); + bsendmsg(ua, "%s", db_strerror(ua->db)); } Dmsg0(050, "Count failed\n"); goto bail_out; @@ -257,7 +257,7 @@ int prune_files(UAContext *ua, CLIENT *client) if (del.tot_ids == 0) { if (ua->verbose) { - bsendmsg(ua, _("No Files found to prune.\n")); + bsendmsg(ua, _("No Files found to prune.\n")); } goto bail_out; } @@ -322,8 +322,8 @@ static int create_temp_tables(UAContext *ua) /* Create temp tables and indicies */ for (i=0; create_deltabs[i]; i++) { 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"); + bsendmsg(ua, "%s", db_strerror(ua->db)); + Dmsg0(050, "create DelTables table failed\n"); return 0; } } @@ -382,7 +382,7 @@ int prune_jobs(UAContext *ua, CLIENT *client, int JobType) Mmsg(query, insert_delcand, (char)JobType, ed1, cr.ClientId); if (!db_sql_query(ua->db, query, NULL, (void *)NULL)) { if (ua->verbose) { - bsendmsg(ua, "%s", db_strerror(ua->db)); + bsendmsg(ua, "%s", db_strerror(ua->db)); } Dmsg0(050, "insert delcand failed\n"); goto bail_out; @@ -400,7 +400,7 @@ int prune_jobs(UAContext *ua, CLIENT *client, int JobType) if (cnt.count == 0) { if (ua->verbose) { - bsendmsg(ua, _("No Jobs found to prune.\n")); + bsendmsg(ua, _("No Jobs found to prune.\n")); } goto bail_out; } @@ -441,20 +441,20 @@ int prune_jobs(UAContext *ua, CLIENT *client, int JobType) if (!del.PurgedFiles[i]) { Mmsg(query, del_File, del.JobId[i]); if (!db_sql_query(ua->db, query, NULL, (void *)NULL)) { - bsendmsg(ua, "%s", db_strerror(ua->db)); + bsendmsg(ua, "%s", db_strerror(ua->db)); } - Dmsg1(050, "Del sql=%s\n", query); + Dmsg1(050, "Del sql=%s\n", query); } Mmsg(query, del_Job, del.JobId[i]); if (!db_sql_query(ua->db, query, NULL, (void *)NULL)) { - bsendmsg(ua, "%s", db_strerror(ua->db)); + bsendmsg(ua, "%s", db_strerror(ua->db)); } Dmsg1(050, "Del sql=%s\n", query); Mmsg(query, del_JobMedia, del.JobId[i]); if (!db_sql_query(ua->db, query, NULL, (void *)NULL)) { - bsendmsg(ua, "%s", db_strerror(ua->db)); + bsendmsg(ua, "%s", db_strerror(ua->db)); } Dmsg1(050, "Del sql=%s\n", query); } @@ -504,7 +504,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", + bsendmsg(ua, "There are no Jobs associated with Volume \"%s\". Marking it purged.\n", mr->VolumeName); } stat = mark_media_purged(ua, mr); @@ -525,7 +525,7 @@ int prune_volume(UAContext *ua, MEDIA_DBR *mr) Mmsg(query, sel_JobMedia, mr->MediaId); if (!db_sql_query(ua->db, query, file_delete_handler, (void *)&del)) { if (ua->verbose) { - bsendmsg(ua, "%s", db_strerror(ua->db)); + bsendmsg(ua, "%s", db_strerror(ua->db)); } Dmsg0(050, "Count failed\n"); goto bail_out; @@ -562,7 +562,7 @@ int prune_volume(UAContext *ua, MEDIA_DBR *mr) } if (ua->verbose && del.num_del != 0) { bsendmsg(ua, _("Pruned %d %s on Volume \"%s\" from catalog.\n"), del.num_del, - del.num_del == 1 ? "Job" : "Jobs", mr->VolumeName); + del.num_del == 1 ? "Job" : "Jobs", mr->VolumeName); } /* If purged, mark it so */ diff --git a/bacula/src/dird/ua_purge.c b/bacula/src/dird/ua_purge.c index 349fc68e2c..c6d98bee6b 100644 --- a/bacula/src/dird/ua_purge.c +++ b/bacula/src/dird/ua_purge.c @@ -12,7 +12,7 @@ */ /* - Copyright (C) 2002-2004 Kern Sibbald and John Walker + Copyright (C) 2002-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 @@ -86,7 +86,7 @@ static int count_handler(void *ctx, int num_fields, char **row) struct s_count_ctx *cnt = (struct s_count_ctx *)ctx; if (row[0]) { - cnt->count = atoi(row[0]); + cnt->count = str_to_int64(row[0]); } else { cnt->count = 0; } @@ -240,7 +240,7 @@ int purgecmd(UAContext *ua, const char *cmd) purge_jobs_from_volume(ua, &mr); } *ua->argk[i] = 0; /* zap keyword already seen */ - bsendmsg(ua, "\n"); + bsendmsg(ua, "\n"); } return 1; default: @@ -405,9 +405,9 @@ static int purge_jobs_from_client(UAContext *ua, CLIENT *client) for (i=0; i < del.num_ids; i++) { Dmsg1(050, "Delete JobId=%d\n", del.JobId[i]); if (!del.PurgedFiles[i]) { - Mmsg(query, "DELETE FROM File WHERE JobId=%d", del.JobId[i]); + Mmsg(query, "DELETE FROM File WHERE JobId=%d", del.JobId[i]); db_sql_query(ua->db, query, NULL, (void *)NULL); - Dmsg1(050, "Del sql=%s\n", query); + Dmsg1(050, "Del sql=%s\n", query); } Mmsg(query, "DELETE FROM Job WHERE JobId=%d", del.JobId[i]); @@ -435,11 +435,12 @@ bail_out: void purge_files_from_job(UAContext *ua, JOB_DBR *jr) { char *query = (char *)get_pool_memory(PM_MESSAGE); + char ed1[50]; - Mmsg(query, "DELETE FROM File WHERE JobId=%u", jr->JobId); + Mmsg(query, "DELETE FROM File WHERE JobId=%s", edit_int64(jr->JobId,ed1)); db_sql_query(ua->db, query, NULL, (void *)NULL); - Mmsg(query, "UPDATE Job Set PurgedFiles=1 WHERE JobId=%u", jr->JobId); + Mmsg(query, "UPDATE Job Set PurgedFiles=1 WHERE JobId=%s", edit_int64(jr->JobId,ed1)); db_sql_query(ua->db, query, NULL, (void *)NULL); free_pool_memory(query); @@ -461,13 +462,13 @@ int purge_jobs_from_volume(UAContext *ua, MEDIA_DBR *mr) JOB_DBR jr; stat = strcmp(mr->VolStatus, "Append") == 0 || - strcmp(mr->VolStatus, "Full") == 0 || - strcmp(mr->VolStatus, "Used") == 0 || - strcmp(mr->VolStatus, "Error") == 0; + strcmp(mr->VolStatus, "Full") == 0 || + strcmp(mr->VolStatus, "Used") == 0 || + strcmp(mr->VolStatus, "Error") == 0; if (!stat) { bsendmsg(ua, "\n"); bsendmsg(ua, _("Volume \"%s\" has VolStatus \"%s\" and cannot be purged.\n" - "The VolStatus must be: Append, Full, Used, or Error to be purged.\n"), + "The VolStatus must be: Append, Full, Used, or Error to be purged.\n"), mr->VolumeName, mr->VolStatus); goto bail_out; } @@ -486,7 +487,7 @@ int purge_jobs_from_volume(UAContext *ua, MEDIA_DBR *mr) bsendmsg(ua, "There are no Jobs associated with Volume \"%s\". Marking it purged.\n", mr->VolumeName); if (!mark_media_purged(ua, mr)) { - bsendmsg(ua, "%s", db_strerror(ua->db)); + bsendmsg(ua, "%s", db_strerror(ua->db)); goto bail_out; } goto bail_out; @@ -514,8 +515,8 @@ int purge_jobs_from_volume(UAContext *ua, MEDIA_DBR *mr) Mmsg(query, "SELECT JobId FROM JobMedia WHERE MediaId=%d", mr->MediaId); if (!db_sql_query(ua->db, query, file_delete_handler, (void *)&del)) { - bsendmsg(ua, "%s", db_strerror(ua->db)); - Dmsg0(050, "Count failed\n"); + bsendmsg(ua, "%s", db_strerror(ua->db)); + Dmsg0(050, "Count failed\n"); goto bail_out; } } @@ -550,7 +551,7 @@ int purge_jobs_from_volume(UAContext *ua, MEDIA_DBR *mr) bsendmsg(ua, "There are no more Jobs associated with Volume \"%s\". Marking it purged.\n", mr->VolumeName); if (!(stat = mark_media_purged(ua, mr))) { - bsendmsg(ua, "%s", db_strerror(ua->db)); + bsendmsg(ua, "%s", db_strerror(ua->db)); goto bail_out; } } diff --git a/bacula/src/dird/ua_restore.c b/bacula/src/dird/ua_restore.c index d4ca3b1b2a..3639758865 100644 --- a/bacula/src/dird/ua_restore.c +++ b/bacula/src/dird/ua_restore.c @@ -48,6 +48,7 @@ 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_from_dir; struct NAME_LIST { @@ -98,14 +99,16 @@ static void print_name_list(UAContext *ua, NAME_LIST *name_list); static int unique_name_list_handler(void *ctx, int num_fields, char **row); static void free_name_list(NAME_LIST *name_list); static void get_storage_from_mediatype(UAContext *ua, NAME_LIST *name_list, RESTORE_CTX *rx); -static int select_backups_before_date(UAContext *ua, RESTORE_CTX *rx, char *date); +static bool select_backups_before_date(UAContext *ua, RESTORE_CTX *rx, char *date); static bool build_directory_tree(UAContext *ua, RESTORE_CTX *rx); 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 int insert_file_into_findex_list(UAContext *ua, RESTORE_CTX *rx, char *file, +static bool insert_file_into_findex_list(UAContext *ua, RESTORE_CTX *rx, char *file, + char *date); +static bool insert_dir_into_findex_list(UAContext *ua, RESTORE_CTX *rx, char *dir, char *date); -static void insert_one_file(UAContext *ua, RESTORE_CTX *rx, 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); static int count_handler(void *ctx, int num_fields, char **row); @@ -149,8 +152,8 @@ int restore_cmd(UAContext *ua, const char *cmd) UnlockRes(); if (!rx.restore_jobs) { bsendmsg(ua, _( - "No Restore Job Resource found. You must create at least\n" - "one before running this command.\n")); + "No Restore Job Resource found in bacula-dir.conf.\n" + "You must create at least one before running this command.\n")); goto bail_out; } @@ -161,15 +164,15 @@ int restore_cmd(UAContext *ua, const char *cmd) * add_findex() */ switch (user_select_jobids_or_files(ua, &rx)) { - case 0: + case 0: /* error */ goto bail_out; - case 1: /* select by jobid */ + case 1: /* selected by jobid */ if (!build_directory_tree(ua, &rx)) { bsendmsg(ua, _("Restore not done.\n")); goto bail_out; } break; - case 2: /* select by filename, no tree needed */ + case 2: /* selected by filename, no tree needed */ break; } @@ -178,7 +181,8 @@ int restore_cmd(UAContext *ua, const char *cmd) bsendmsg(ua, _("Unable to construct a valid BSR. Cannot continue.\n")); goto bail_out; } - if (!write_bsr_file(ua, rx.bsr)) { + if (!(rx.selected_files = write_bsr_file(ua, rx.bsr))) { + bsendmsg(ua, _("No files selected to be restored.\n")); goto bail_out; } bsendmsg(ua, _("\n%u file%s selected to be restored.\n\n"), rx.selected_files, @@ -279,6 +283,10 @@ static int get_client_name(UAContext *ua, RESTORE_CTX *rx) * The first step in the restore process is for the user to * select a list of JobIds from which he will subsequently * select which files are to be restored. + * + * Returns: 2 if filename list made + * 1 if jobid list made + * 0 on error */ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx) { @@ -298,23 +306,28 @@ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx) "Select backup for a client before a specified time", "Enter a list of files to restore", "Enter a list of files to restore before a specified time", + "Enter a list of directories to restore for a given JobId", "Cancel", NULL }; const char *kw[] = { + /* These keywords are handled in a for loop */ "jobid", /* 0 */ "current", /* 1 */ "before", /* 2 */ "file", /* 3 */ - "select", /* 4 */ - "pool", /* 5 */ - "all", /* 6 */ - "client", /* 7 */ - "storage", /* 8 */ - "fileset", /* 9 */ - "where", /* 10 */ - "yes", /* 11 */ - "done", /* 12 */ + "directory", /* 4 */ + "select", /* 5 */ + "pool", /* 6 */ + "all", /* 7 */ + + /* The keyword below are handled by individual arg lookups */ + "client", /* 8 */ + "storage", /* 9 */ + "fileset", /* 10 */ + "where", /* 11 */ + "yes", /* 12 */ + "done", /* 13 */ NULL }; @@ -354,6 +367,7 @@ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx) have_date = true; break; case 3: /* file */ + case 4: /* dir */ if (!have_date) { bstrutime(date, sizeof(date), time(NULL)); } @@ -361,14 +375,14 @@ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx) return 0; } pm_strcpy(ua->cmd, ua->argv[i]); - insert_one_file(ua, rx, date); + 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 4: /* select */ + case 5: /* select */ if (!have_date) { bstrutime(date, sizeof(date), time(NULL)); } @@ -377,7 +391,7 @@ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx) } done = true; break; - case 5: /* pool specified */ + 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]); @@ -389,7 +403,7 @@ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx) return 0; } break; - case 6: /* all specified */ + case 7: /* all specified */ rx->all = true; break; /* @@ -492,7 +506,7 @@ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx) if (len == 0) { break; } - insert_one_file(ua, rx, date); + insert_one_file_or_dir(ua, rx, date, false); } /* Check MediaType and select storage that corresponds */ if (rx->name_list.num_ids) { @@ -517,7 +531,7 @@ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx) if (len == 0) { break; } - insert_one_file(ua, rx, date); + insert_one_file_or_dir(ua, rx, date, false); } /* Check MediaType and select storage that corresponds */ if (rx->name_list.num_ids) { @@ -525,8 +539,40 @@ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx) } return 2; + case 8: /* Enter directories */ + if (get_cmd(ua, _("Enter JobId(s), comma separated, to restore: "))) { + 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; + } + 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 ( ;; ) { + 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 8: /* Cancel or quit */ + case 9: /* Cancel or quit */ return 0; } } @@ -555,8 +601,9 @@ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx) } jr.JobId = JobId; if (!db_get_job_record(ua->jcr, ua->db, &jr)) { - bsendmsg(ua, _("Unable to get Job record for JobId=%u: ERR=%s\n"), - JobId, db_strerror(ua->db)); + 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; } if (!acl_access_ok(ua, Job_ACL, jr.Name)) { @@ -592,7 +639,7 @@ static int get_date(UAContext *ua, char *date, int date_len) /* * Insert a single file, or read a list of files from a file */ -static void insert_one_file(UAContext *ua, RESTORE_CTX *rx, char *date) +static void insert_one_file_or_dir(UAContext *ua, RESTORE_CTX *rx, char *date, bool dir) { FILE *ffd; char file[5000]; @@ -610,14 +657,24 @@ static void insert_one_file(UAContext *ua, RESTORE_CTX *rx, char *date) } while (fgets(file, sizeof(file), ffd)) { line++; - if (!insert_file_into_findex_list(ua, rx, file, date)) { - bsendmsg(ua, _("Error occurred on line %d of %s\n"), line, p); + 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)) { + bsendmsg(ua, _("Error occurred on line %d of %s\n"), line, p); + } } } fclose(ffd); break; default: - insert_file_into_findex_list(ua, rx, ua->cmd, date); + if (dir) { + insert_dir_into_findex_list(ua, rx, ua->cmd, date); + } else { + insert_file_into_findex_list(ua, rx, ua->cmd, date); + } break; } } @@ -627,13 +684,14 @@ static void insert_one_file(UAContext *ua, RESTORE_CTX *rx, char *date) * lookup the most recent backup in the catalog to get the JobId * and FileIndex, then insert them into the findex list. */ -static int insert_file_into_findex_list(UAContext *ua, RESTORE_CTX *rx, char *file, +static bool insert_file_into_findex_list(UAContext *ua, RESTORE_CTX *rx, char *file, char *date) { 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); + Mmsg(rx->query, uar_jobid_fileindex, date, rx->path, rx->fname, + rx->ClientName); } else { Mmsg(rx->query, uar_jobids_fileindex, rx->JobIds, date, rx->path, rx->fname, rx->ClientName); @@ -646,20 +704,56 @@ static int insert_file_into_findex_list(UAContext *ua, RESTORE_CTX *rx, char *fi } if (!rx->found) { bsendmsg(ua, _("No database record found for: %s\n"), file); - return 0; + return true; } - rx->selected_files++; /* * Find the MediaTypes for this JobId and add to the name_list */ Mmsg(rx->query, uar_mediatype, rx->JobId); if (!db_sql_query(ua->db, rx->query, unique_name_list_handler, (void *)&rx->name_list)) { bsendmsg(ua, "%s", db_strerror(ua->db)); - return 0; + return false; } - return 1; + return true; +} + +/* + * For a given path lookup the most recent backup in the catalog + * 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) +{ + strip_trailing_junk(dir); + if (*rx->JobIds == 0) { + bsendmsg(ua, _("No JobId specified cannot continue.\n")); + return false; + } else { + Mmsg(rx->query, uar_jobid_fileindex_from_dir, rx->JobIds, + 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)); + } + if (!rx->found) { + bsendmsg(ua, _("No database record found for: %s\n"), dir); + return true; + } + /* + * Find the MediaTypes for this JobId and add to the name_list + */ + Mmsg(rx->query, uar_mediatype, rx->JobId); + 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; + } + return true; } + static void split_path_and_filename(RESTORE_CTX *rx, char *name) { char *p, *f; @@ -744,12 +838,14 @@ static bool build_directory_tree(UAContext *ua, RESTORE_CTX *rx) } } for (p=rx->JobIds; get_next_jobid_from_list(&p, &JobId) > 0; ) { + char ed1[50]; if (JobId == last_JobId) { continue; /* eliminate duplicate JobIds */ } last_JobId = JobId; - bsendmsg(ua, _("\nBuilding directory tree for JobId %u ... "), JobId); + bsendmsg(ua, _("\nBuilding directory tree for JobId %s ... "), + edit_int64(JobId, ed1)); items++; /* * Find files for this JobId and insert them in the tree @@ -766,31 +862,48 @@ static bool build_directory_tree(UAContext *ua, RESTORE_CTX *rx) bsendmsg(ua, "%s", db_strerror(ua->db)); } } - char ec1[50]; - bsendmsg(ua, "\n%d Job%s, %s files inserted into the tree%s.\n", - items, items==1?"":"s", edit_uint64_with_commas(tree.FileCount, ec1), - tree.all?" and marked for extraction":""); + if (tree.FileCount == 0) { + 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; + } 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; + } + } else { + char ec1[50]; + bsendmsg(ua, "\n%d Job%s, %s files inserted into the tree%s.\n", + items, items==1?"":"s", edit_uint64_with_commas(tree.FileCount, ec1), + tree.all?" and marked for extraction":""); - /* Check MediaType and select storage that corresponds */ - get_storage_from_mediatype(ua, &rx->name_list, rx); + /* Check MediaType and select storage that corresponds */ + 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); - } + if (find_arg(ua, _("done")) < 0) { + /* Let the user interact in selecting which files to restore */ + OK = user_select_files_from_tree(&tree); + } - /* - * Walk down through the tree finding all files marked to be - * extracted making a bootstrap file. - */ - if (OK) { - 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) { - 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 */ + /* + * Walk down through the tree finding all files marked to be + * extracted making a bootstrap file. + */ + if (OK) { + 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) { + 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 */ + } } } } @@ -805,9 +918,9 @@ static bool build_directory_tree(UAContext *ua, RESTORE_CTX *rx) * This routine is used to get the current backup or a backup * before the specified date. */ -static int select_backups_before_date(UAContext *ua, RESTORE_CTX *rx, char *date) +static bool select_backups_before_date(UAContext *ua, RESTORE_CTX *rx, char *date) { - int stat = 0; + bool ok = false; FILESET_DBR fsr; CLIENT_DBR cr; char fileset_name[MAX_NAME_LENGTH]; @@ -870,10 +983,12 @@ static int select_backups_before_date(UAContext *ua, RESTORE_CTX *rx, char *date 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=%u ", pr.PoolId); + bsnprintf(pool_select, sizeof(pool_select), "AND Media.PoolId=%s ", + edit_int64(pr.PoolId, ed1)); } else { bsendmsg(ua, _("Pool \"%s\" not found, using any pool.\n"), pr.Name); } @@ -937,16 +1052,15 @@ static int select_backups_before_date(UAContext *ua, RESTORE_CTX *rx, char *date if (rx->JobIds[0] != 0) { /* Display a list of Jobs selected for this restore */ db_list_sql_query(ua->jcr, ua->db, uar_list_temp, prtit, ua, 1, HORZ_LIST); + ok = true; } else { bsendmsg(ua, _("No jobs found.\n")); } - stat = 1; - bail_out: db_sql_query(ua->db, uar_del_temp, NULL, NULL); db_sql_query(ua->db, uar_del_temp1, NULL, NULL); - return stat; + return ok; } @@ -958,15 +1072,19 @@ 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 == ',' || *q == 0) { + if (*q == 0) { + break; + } else if (*q == ',') { q++; break; } jobid[i] = *q++; jobid[i+1] = 0; } - if (jobid[0] == 0 || !is_a_number(jobid)) { + if (jobid[0] == 0) { return 0; + } else if (!is_a_number(jobid)) { + return -1; /* error */ } *p = q; *JobId = str_to_int64(jobid); @@ -983,6 +1101,7 @@ static int count_handler(void *ctx, int num_fields, char **row) /* * Callback handler to get JobId and FileIndex for files + * can insert more than one depending on the caller. */ static int jobid_fileindex_handler(void *ctx, int num_fields, char **row) { @@ -990,6 +1109,7 @@ static int jobid_fileindex_handler(void *ctx, int num_fields, char **row) rx->JobId = str_to_int64(row[0]); add_findex(rx->bsr, rx->JobId, str_to_int64(row[1])); rx->found = true; + rx->selected_files++; return 0; } diff --git a/bacula/src/dird/ua_run.c b/bacula/src/dird/ua_run.c index 2b770e173a..f757f8ba77 100644 --- a/bacula/src/dird/ua_run.c +++ b/bacula/src/dird/ua_run.c @@ -8,7 +8,7 @@ */ /* - Copyright (C) 2001-2004 Kern Sibbald + Copyright (C) 2001-20054 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 @@ -463,7 +463,7 @@ try_again: } } if (jid) { - jcr->RestoreJobId = atoi(jid); + jcr->RestoreJobId = str_to_int64(jid); } /* Run without prompting? */ @@ -549,12 +549,12 @@ try_again: case JT_RESTORE: if (jcr->RestoreJobId == 0 && !jcr->RestoreBootstrap) { if (jid) { - jcr->RestoreJobId = atoi(jid); + jcr->RestoreJobId = str_to_int64(jid); } else { if (!get_pint(ua, _("Please enter a JobId for restore: "))) { goto bail_out; } - jcr->RestoreJobId = ua->pint32_val; + jcr->RestoreJobId = ua->int64_val; } } jcr->JobLevel = L_FULL; /* default level */ @@ -852,7 +852,8 @@ start_job: if (JobId == 0) { bsendmsg(ua, _("Job failed.\n")); } else { - bsendmsg(ua, _("Job started. JobId=%u\n"), JobId); + char ed1[50]; + bsendmsg(ua, _("Job started. JobId=%s\n"), edit_int64(JobId,ed1)); } return JobId; } diff --git a/bacula/src/dird/ua_select.c b/bacula/src/dird/ua_select.c index eb8b21533e..c6e0731e86 100644 --- a/bacula/src/dird/ua_select.c +++ b/bacula/src/dird/ua_select.c @@ -48,11 +48,11 @@ int confirm_retention(UAContext *ua, utime_t *ret, const char *msg) return 0; } if (strcasecmp(ua->cmd, _("mod")) == 0) { - if (!get_cmd(ua, _("Enter new retention period: "))) { + if (!get_cmd(ua, _("Enter new retention period: "))) { return 0; } if (!duration_to_utime(ua->cmd, ret)) { - bsendmsg(ua, _("Invalid period.\n")); + bsendmsg(ua, _("Invalid period.\n")); continue; } continue; @@ -292,7 +292,7 @@ CLIENT *get_client_resource(UAContext *ua) for (i=1; iargc; i++) { if ((strcasecmp(ua->argk[i], _("client")) == 0 || - strcasecmp(ua->argk[i], _("fd")) == 0) && ua->argv[i]) { + strcasecmp(ua->argk[i], _("fd")) == 0) && ua->argv[i]) { if (!acl_access_ok(ua, Client_ACL, ua->argv[i])) { break; } @@ -300,7 +300,7 @@ CLIENT *get_client_resource(UAContext *ua) if (client) { return client; } - bsendmsg(ua, _("Error: Client resource %s does not exist.\n"), ua->argv[i]); + bsendmsg(ua, _("Error: Client resource %s does not exist.\n"), ua->argv[i]); break; } } @@ -329,13 +329,13 @@ int get_client_dbr(UAContext *ua, CLIENT_DBR *cr) } for (i=1; iargc; i++) { if ((strcasecmp(ua->argk[i], _("client")) == 0 || - strcasecmp(ua->argk[i], _("fd")) == 0) && ua->argv[i]) { + strcasecmp(ua->argk[i], _("fd")) == 0) && ua->argv[i]) { if (!acl_access_ok(ua, Client_ACL, ua->argv[i])) { break; } bstrncpy(cr->Name, ua->argv[i], sizeof(cr->Name)); if (!db_get_client_record(ua->jcr, ua->db, cr)) { - bsendmsg(ua, _("Could not find Client \"%s\": ERR=%s"), ua->argv[i], + bsendmsg(ua, _("Could not find Client \"%s\": ERR=%s"), ua->argv[i], db_strerror(ua->db)); cr->ClientId = 0; break; @@ -438,7 +438,7 @@ bool select_pool_dbr(UAContext *ua, POOL_DBR *pr) acl_access_ok(ua, Pool_ACL, ua->argv[i])) { bstrncpy(pr->Name, ua->argv[i], sizeof(pr->Name)); if (!db_get_pool_record(ua->jcr, ua->db, pr)) { - bsendmsg(ua, _("Could not find Pool \"%s\": ERR=%s"), ua->argv[i], + bsendmsg(ua, _("Could not find Pool \"%s\": ERR=%s"), ua->argv[i], db_strerror(ua->db)); pr->PoolId = 0; break; @@ -527,7 +527,7 @@ int select_media_dbr(UAContext *ua, MEDIA_DBR *mr) return 0; } if (is_a_number(ua->cmd)) { - mr->MediaId = atoi(ua->cmd); + mr->MediaId = str_to_int64(ua->cmd); } else { bstrncpy(mr->VolumeName, ua->cmd, sizeof(mr->VolumeName)); } @@ -593,7 +593,7 @@ int select_job_dbr(UAContext *ua, JOB_DBR *jr) if (!get_pint(ua, _("Enter the JobId to select: "))) { return 0; } - jr->JobId = ua->pint32_val; + jr->JobId = ua->int64_val; if (!db_get_job_record(ua->jcr, ua->db, jr)) { bsendmsg(ua, "%s", db_strerror(ua->db)); return 0; @@ -627,7 +627,7 @@ int get_job_dbr(UAContext *ua, JOB_DBR *jr) continue; } if (!db_get_job_record(ua->jcr, ua->db, jr)) { - bsendmsg(ua, _("Could not find Job \"%s\": ERR=%s"), ua->argv[i], + bsendmsg(ua, _("Could not find Job \"%s\": ERR=%s"), ua->argv[i], db_strerror(ua->db)); jr->JobId = 0; break; @@ -711,29 +711,29 @@ int do_prompt(UAContext *ua, const char *automsg, const char *msg, char *prompt, for ( ;; ) { /* First item is the prompt string, not the items */ if (ua->num_prompts == 1) { - bsendmsg(ua, _("Selection is empty!\n")); + bsendmsg(ua, _("Selection is empty!\n")); item = 0; /* list is empty ! */ break; } if (ua->num_prompts == 2) { item = 1; - bsendmsg(ua, _("Item 1 selected automatically.\n")); + bsendmsg(ua, _("Item 1 selected automatically.\n")); if (prompt) { bstrncpy(prompt, ua->prompt[1], max_prompt); } break; } else { - sprintf(pmsg, "%s (1-%d): ", msg, ua->num_prompts-1); + sprintf(pmsg, "%s (1-%d): ", msg, ua->num_prompts-1); } /* Either a . or an @ will get you out of the loop */ if (!get_pint(ua, pmsg)) { item = -1; /* error */ - bsendmsg(ua, _("Selection aborted, nothing done.\n")); + bsendmsg(ua, _("Selection aborted, nothing done.\n")); break; } item = ua->pint32_val; if (item < 1 || item >= ua->num_prompts) { - bsendmsg(ua, _("Please enter a number between 1 and %d\n"), ua->num_prompts-1); + bsendmsg(ua, _("Please enter a number between 1 and %d\n"), ua->num_prompts-1); continue; } if (prompt) { @@ -774,48 +774,48 @@ STORE *get_storage_resource(UAContext *ua, int use_default) for (i=1; iargc; i++) { if (use_default && !ua->argv[i]) { /* Ignore slots, scan and barcode(s) keywords */ - if (strncasecmp("scan", ua->argk[i], 4) == 0 || - strncasecmp("barcode", ua->argk[i], 7) == 0 || - strncasecmp("slots", ua->argk[i], 5) == 0) { + if (strncasecmp("scan", ua->argk[i], 4) == 0 || + strncasecmp("barcode", ua->argk[i], 7) == 0 || + strncasecmp("slots", ua->argk[i], 5) == 0) { continue; } /* Default argument is storage */ if (store_name) { - bsendmsg(ua, _("Storage name given twice.\n")); + bsendmsg(ua, _("Storage name given twice.\n")); return NULL; } store_name = ua->argk[i]; - if (*store_name == '?') { + if (*store_name == '?') { *store_name = 0; break; } } else { - if (strcasecmp(ua->argk[i], _("storage")) == 0 || - strcasecmp(ua->argk[i], _("sd")) == 0) { + if (strcasecmp(ua->argk[i], _("storage")) == 0 || + strcasecmp(ua->argk[i], _("sd")) == 0) { store_name = ua->argv[i]; break; - } else if (strcasecmp(ua->argk[i], _("jobid")) == 0) { + } else if (strcasecmp(ua->argk[i], _("jobid")) == 0) { jobid = str_to_int64(ua->argv[i]); if (jobid <= 0) { - bsendmsg(ua, _("Expecting jobid=nn command, got: %s\n"), ua->argk[i]); + bsendmsg(ua, _("Expecting jobid=nn command, got: %s\n"), ua->argk[i]); return NULL; } if (!(jcr=get_jcr_by_id(jobid))) { - bsendmsg(ua, _("JobId %d is not running.\n"), jobid); + bsendmsg(ua, _("JobId %d is not running.\n"), jobid); return NULL; } store = jcr->store; free_jcr(jcr); break; - } else if (strcasecmp(ua->argk[i], _("job")) == 0) { + } else if (strcasecmp(ua->argk[i], _("job")) == 0) { if (!ua->argv[i]) { - bsendmsg(ua, _("Expecting job=xxx, got: %s.\n"), ua->argk[i]); + bsendmsg(ua, _("Expecting job=xxx, got: %s.\n"), ua->argk[i]); return NULL; } if (!(jcr=get_jcr_by_partial_name(ua->argv[i]))) { - bsendmsg(ua, _("Job \"%s\" is not running.\n"), ua->argv[i]); + bsendmsg(ua, _("Job \"%s\" is not running.\n"), ua->argv[i]); return NULL; } store = jcr->store; @@ -831,7 +831,7 @@ STORE *get_storage_resource(UAContext *ua, int use_default) if (!store && store_name) { store = (STORE *)GetResWithName(R_STORAGE, store_name); if (!store) { - bsendmsg(ua, "Storage resource \"%s\": not found\n", store_name); + bsendmsg(ua, "Storage resource \"%s\": not found\n", store_name); } } if (store && !acl_access_ok(ua, Storage_ACL, store->hdr.name)) { diff --git a/bacula/src/dird/ua_tree.c b/bacula/src/dird/ua_tree.c index 5023002e54..3b5ae11428 100644 --- a/bacula/src/dird/ua_tree.c +++ b/bacula/src/dird/ua_tree.c @@ -62,20 +62,20 @@ struct cmdstruct { const char *key; int (*func)(UAContext *ua, TREE_CTX *tree); static struct cmdstruct commands[] = { { N_("cd"), cdcmd, _("change current directory")}, { N_("count"), countcmd, _("count marked files in and below the cd")}, - { N_("dir"), dircmd, _("list current directory")}, + { N_("dir"), dircmd, _("long list current directory, wildcards allowed")}, { N_("done"), donecmd, _("leave file selection mode")}, { N_("estimate"), estimatecmd, _("estimate restore size")}, - { N_("exit"), donecmd, _("exit = done")}, - { N_("find"), findcmd, _("find files -- wildcards allowed")}, + { N_("exit"), donecmd, _("same as done command")}, + { N_("find"), findcmd, _("find files, wildcards allowed")}, { N_("help"), helpcmd, _("print help")}, - { N_("ls"), lscmd, _("list current directory -- wildcards allowed")}, + { N_("ls"), lscmd, _("list current directory, wildcards allowed")}, { N_("lsmark"), lsmarkcmd, _("list the marked files in and below the cd")}, - { N_("mark"), markcmd, _("mark dir/file to be restored -- recursively in dirs")}, + { N_("mark"), markcmd, _("mark dir/file to be restored recursively in dirs")}, { N_("markdir"), markdircmd, _("mark directory name to be restored (no files)")}, { N_("pwd"), pwdcmd, _("print current working directory")}, - { N_("unmark"), unmarkcmd, _("unmark dir/file to be restored -- recursively in dir")}, - { N_("unmarkdir"), unmarkdircmd, _("unmark directory name only -- no recursion")}, - { N_("quit"), quitcmd, _("quit")}, + { N_("unmark"), unmarkcmd, _("unmark dir/file to be restored recursively in dir")}, + { N_("unmarkdir"), unmarkdircmd, _("unmark directory name only no recursion")}, + { N_("quit"), quitcmd, _("quit and do not do restore")}, { N_("?"), helpcmd, _("print help")}, }; #define comsize (sizeof(commands)/sizeof(struct cmdstruct)) @@ -173,7 +173,7 @@ int insert_tree_handler(void *ctx, int num_fields, char **row) } hard_link = (decode_LinkFI(row[4], &statp) != 0); node = insert_tree_node(row[0], row[1], type, tree->root, NULL); - JobId = (JobId_t)str_to_int64(row[3]); + JobId = str_to_int64(row[3]); FileIndex = str_to_int64(row[2]); /* * - The first time we see a file (node->inserted==true), we accept it. @@ -591,7 +591,6 @@ static int helpcmd(UAContext *ua, TREE_CTX *tree) { unsigned int i; -/* usage(); */ bsendmsg(ua, _(" Command Description\n ======= ===========\n")); for (i=0; i \n" " -b bootstrap specify a bootstrap file\n" diff --git a/bacula/src/stored/bextract.c b/bacula/src/stored/bextract.c index 420ce09c61..90e91e42d3 100644 --- a/bacula/src/stored/bextract.c +++ b/bacula/src/stored/bextract.c @@ -91,7 +91,7 @@ int main (int argc, char *argv[]) int ch; FILE *fd; char line[1000]; - int got_inc = FALSE; + bool got_inc = false; working_directory = "/tmp"; my_name_is(argc, argv, "bextract"); @@ -149,7 +149,7 @@ int main (int argc, char *argv[]) add_fname_to_include_list(ff, 0, line); } fclose(fd); - got_inc = TRUE; + got_inc = true; break; case 'p': diff --git a/bacula/src/stored/bscan.c b/bacula/src/stored/bscan.c index 5c95a3d69b..503dd9aa3a 100644 --- a/bacula/src/stored/bscan.c +++ b/bacula/src/stored/bscan.c @@ -10,7 +10,7 @@ * Version $Id$ */ /* - Copyright (C) 2001-2004 Kern Sibbald and John Walker + Copyright (C) 2001-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 @@ -106,7 +106,7 @@ bool forge_on = false; static void usage() { fprintf(stderr, _( -"Copyright (C) 2001-2004 Kern Sibbald and John Walker.\n" +"Copyright (C) 2001-2005 Kern Sibbald.\n" "\nVersion: " VERSION " (" BDATE ")\n\n" "Usage: bscan [ options ] \n" " -b bootstrap specify a bootstrap file\n" @@ -300,7 +300,7 @@ static bool bscan_mount_next_read_volume(DCR *dcr) continue; } if (verbose) { - Pmsg1(000, _("Create JobMedia for Job %s\n"), mjcr->Job); + Pmsg1(000, _("Create JobMedia for Job %s\n"), mjcr->Job); } if (dev->state & ST_TAPE) { mdcr->EndBlock = dev->EndBlock; @@ -310,7 +310,7 @@ static bool bscan_mount_next_read_volume(DCR *dcr) mdcr->EndFile = (uint32_t)(dev->file_addr >> 32); } if (!create_jobmedia_record(db, mjcr)) { - Pmsg2(000, _("Could not create JobMedia record for Volume=%s Job=%s\n"), + Pmsg2(000, _("Could not create JobMedia record for Volume=%s Job=%s\n"), dev->VolCatInfo.VolCatName, mjcr->Job); } } @@ -364,7 +364,7 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec) if (showProgress) { int64_t pct = (mr.VolBytes * 100) / currentVolumeSize; if (pct != last_pct) { - fprintf(stdout, "done: %" lld "\n", pct); + fprintf(stdout, "done: %" lld "\n", pct); fflush(stdout); last_pct = pct; } @@ -388,7 +388,7 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec) } switch (rec->FileIndex) { case PRE_LABEL: - Pmsg0(000, _("Volume is prelabeled. This tape cannot be scanned.\n")); + Pmsg0(000, _("Volume is prelabeled. This tape cannot be scanned.\n")); return false; break; @@ -400,21 +400,21 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec) num_pools++; if (db_get_pool_record(bjcr, db, &pr)) { if (verbose) { - Pmsg1(000, _("Pool record for %s found in DB.\n"), pr.Name); + Pmsg1(000, _("Pool record for %s found in DB.\n"), pr.Name); } } else { if (!update_db) { - Pmsg1(000, _("VOL_LABEL: Pool record not found for Pool: %s\n"), + Pmsg1(000, _("VOL_LABEL: Pool record not found for Pool: %s\n"), pr.Name); } create_pool_record(db, &pr); } if (strcmp(pr.PoolType, dev->VolHdr.PoolType) != 0) { - Pmsg2(000, _("VOL_LABEL: PoolType mismatch. DB=%s Vol=%s\n"), + Pmsg2(000, _("VOL_LABEL: PoolType mismatch. DB=%s Vol=%s\n"), pr.PoolType, dev->VolHdr.PoolType); return true; } else if (verbose) { - Pmsg1(000, _("Pool type \"%s\" is OK.\n"), pr.PoolType); + Pmsg1(000, _("Pool type \"%s\" is OK.\n"), pr.PoolType); } /* Check Media Info */ @@ -424,25 +424,25 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec) num_media++; if (db_get_media_record(bjcr, db, &mr)) { if (verbose) { - Pmsg1(000, _("Media record for %s found in DB.\n"), mr.VolumeName); + Pmsg1(000, _("Media record for %s found in DB.\n"), mr.VolumeName); } /* Clear out some volume statistics that will be updated */ mr.VolJobs = mr.VolFiles = mr.VolBlocks = 0; mr.VolBytes = rec->data_len + 20; } else { if (!update_db) { - Pmsg1(000, _("VOL_LABEL: Media record not found for Volume: %s\n"), + Pmsg1(000, _("VOL_LABEL: Media record not found for Volume: %s\n"), mr.VolumeName); } bstrncpy(mr.MediaType, dev->VolHdr.MediaType, sizeof(mr.MediaType)); create_media_record(db, &mr, &dev->VolHdr); } if (strcmp(mr.MediaType, dev->VolHdr.MediaType) != 0) { - Pmsg2(000, _("VOL_LABEL: MediaType mismatch. DB=%s Vol=%s\n"), + Pmsg2(000, _("VOL_LABEL: MediaType mismatch. DB=%s Vol=%s\n"), mr.MediaType, dev->VolHdr.MediaType); return true; /* ignore error */ } else if (verbose) { - Pmsg1(000, _("Media type \"%s\" is OK.\n"), mr.MediaType); + Pmsg1(000, _("Media type \"%s\" is OK.\n"), mr.MediaType); } /* Reset some JCR variables */ foreach_dlist(dcr, dev->attached_dcrs) { @@ -451,14 +451,14 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec) dcr->StartFile = dcr->EndFile = 0; } - Pmsg1(000, _("VOL_LABEL: OK for Volume: %s\n"), mr.VolumeName); + Pmsg1(000, _("VOL_LABEL: OK for Volume: %s\n"), mr.VolumeName); break; case SOS_LABEL: mr.VolJobs++; num_jobs++; if (ignored_msgs > 0) { - Pmsg1(000, _("%d \"errors\" ignored before first Start of Session record.\n"), + Pmsg1(000, _("%d \"errors\" ignored before first Start of Session record.\n"), ignored_msgs); ignored_msgs = 0; } @@ -467,14 +467,14 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec) bstrncpy(jr.Job, label.Job, sizeof(jr.Job)); if (db_get_job_record(bjcr, db, &jr)) { /* Job record already exists in DB */ - update_db = false; /* don't change db in create_job_record */ + update_db = false; /* don't change db in create_job_record */ if (verbose) { - Pmsg1(000, _("SOS_LABEL: Found Job record for JobId: %d\n"), jr.JobId); + Pmsg1(000, _("SOS_LABEL: Found Job record for JobId: %d\n"), jr.JobId); } } else { /* Must create a Job record in DB */ if (!update_db) { - Pmsg1(000, _("SOS_LABEL: Job record not found for JobId: %d\n"), + Pmsg1(000, _("SOS_LABEL: Job record not found for JobId: %d\n"), jr.JobId); } } @@ -483,7 +483,7 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec) create_client_record(db, &cr); jr.ClientId = cr.ClientId; - /* process label, if Job record exists don't update db */ + /* process label, if Job record exists don't update db */ mjcr = create_job_record(db, &jr, &label, rec); dcr = mjcr->dcr; update_db = save_update_db; @@ -512,19 +512,19 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec) bstrncpy(dcr->pool_name, label.PoolName, sizeof(dcr->pool_name)); if (rec->VolSessionId != jr.VolSessionId) { - Pmsg3(000, _("SOS_LABEL: VolSessId mismatch for JobId=%u. DB=%d Vol=%d\n"), + Pmsg3(000, _("SOS_LABEL: VolSessId mismatch for JobId=%u. DB=%d Vol=%d\n"), jr.JobId, jr.VolSessionId, rec->VolSessionId); return true; /* ignore error */ } if (rec->VolSessionTime != jr.VolSessionTime) { - Pmsg3(000, _("SOS_LABEL: VolSessTime mismatch for JobId=%u. DB=%d Vol=%d\n"), + Pmsg3(000, _("SOS_LABEL: VolSessTime mismatch for JobId=%u. DB=%d Vol=%d\n"), jr.JobId, jr.VolSessionTime, rec->VolSessionTime); return true; /* ignore error */ } if (jr.PoolId != pr.PoolId) { - Pmsg3(000, _("SOS_LABEL: PoolId mismatch for JobId=%u. DB=%d Vol=%d\n"), + Pmsg3(000, _("SOS_LABEL: PoolId mismatch for JobId=%u. DB=%d Vol=%d\n"), jr.JobId, jr.PoolId, pr.PoolId); return true; /* ignore error */ @@ -542,7 +542,7 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec) mjcr = get_jcr_by_session(rec->VolSessionId, rec->VolSessionTime); if (!mjcr) { - Pmsg2(000, _("Could not find SessId=%d SessTime=%d for EOS record.\n"), + Pmsg2(000, _("Could not find SessId=%d SessTime=%d for EOS record.\n"), rec->VolSessionId, rec->VolSessionTime); break; } @@ -585,7 +585,7 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec) jr.JobTDate = (utime_t)mjcr->start_time; jr.ClientId = mjcr->ClientId; if (!db_update_job_end_record(bjcr, db, &jr)) { - Pmsg1(0, _("Could not update job record. ERR=%s\n"), db_strerror(db)); + Pmsg1(0, _("Could not update job record. ERR=%s\n"), db_strerror(db)); } mjcr->dcr = NULL; free_jcr(mjcr); @@ -596,7 +596,7 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec) mr.VolBytes += mr.VolBlocks * WRITE_BLKHDR_LENGTH; /* approx. */ mr.VolMounts++; update_media_record(db, &mr); - Pmsg3(0, _("End of all Volumes. VolFiles=%u VolBlocks=%u VolBytes=%s\n"), mr.VolFiles, + Pmsg3(0, _("End of all Volumes. VolFiles=%u VolBlocks=%u VolBytes=%s\n"), mr.VolFiles, mr.VolBlocks, edit_uint64_with_commas(mr.VolBytes, ec1)); break; default: @@ -608,7 +608,7 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec) mjcr = get_jcr_by_session(rec->VolSessionId, rec->VolSessionTime); if (!mjcr) { if (mr.VolJobs > 0) { - Pmsg2(000, _("Could not find Job for SessId=%d SessTime=%d record.\n"), + Pmsg2(000, _("Could not find Job for SessId=%d SessTime=%d record.\n"), rec->VolSessionId, rec->VolSessionTime); } else { ignored_msgs++; @@ -626,11 +626,11 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec) case STREAM_UNIX_ATTRIBUTES_EX: if (!unpack_attributes_record(bjcr, rec->Stream, rec->data, attr)) { - Emsg0(M_ERROR_TERM, 0, _("Cannot continue.\n")); + Emsg0(M_ERROR_TERM, 0, _("Cannot continue.\n")); } if (attr->file_index != rec->FileIndex) { - Emsg2(M_ERROR_TERM, 0, _("Record header file index %ld not equal record index %ld\n"), + Emsg2(M_ERROR_TERM, 0, _("Record header file index %ld not equal record index %ld\n"), rec->FileIndex, attr->file_index); } @@ -644,7 +644,7 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec) num_files++; if (verbose && (num_files & 0x7FFF) == 0) { char ed1[30], ed2[30], ed3[30], ed4[30]; - Pmsg4(000, _("%s file records. At file:blk=%s:%s bytes=%s\n"), + Pmsg4(000, _("%s file records. At file:blk=%s:%s bytes=%s\n"), edit_uint64_with_commas(num_files, ed1), edit_uint64_with_commas(rec->File, ed2), edit_uint64_with_commas(rec->Block, ed3), @@ -687,7 +687,7 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec) char MD5buf[50]; bin_to_base64(MD5buf, (char *)rec->data, 16); /* encode 16 bytes */ if (verbose > 1) { - Pmsg1(000, _("Got MD5 record: %s\n"), MD5buf); + Pmsg1(000, _("Got MD5 record: %s\n"), MD5buf); } update_SIG_record(db, MD5buf, rec, MD5_SIG); break; @@ -696,7 +696,7 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec) char SIGbuf[50]; bin_to_base64(SIGbuf, (char *)rec->data, 20); /* encode 20 bytes */ if (verbose > 1) { - Pmsg1(000, _("Got SHA1 record: %s\n"), SIGbuf); + Pmsg1(000, _("Got SHA1 record: %s\n"), SIGbuf); } update_SIG_record(db, SIGbuf, rec, SHA1_SIG); break; @@ -704,13 +704,13 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec) case STREAM_PROGRAM_NAMES: if (verbose) { - Pmsg1(000, _("Got Prog Names Stream: %s\n"), rec->data); + Pmsg1(000, _("Got Prog Names Stream: %s\n"), rec->data); } break; case STREAM_PROGRAM_DATA: if (verbose > 1) { - Pmsg0(000, _("Got Prog Data Stream record.\n")); + Pmsg0(000, _("Got Prog Data Stream record.\n")); } break; default: @@ -904,16 +904,16 @@ static int create_fileset_record(B_DB *db, FILESET_DBR *fsr) } if (db_get_fileset_record(bjcr, db, fsr)) { if (verbose) { - Pmsg1(000, _("Fileset \"%s\" already exists.\n"), fsr->FileSet); + Pmsg1(000, _("Fileset \"%s\" already exists.\n"), fsr->FileSet); } } else { if (!db_create_fileset_record(bjcr, db, fsr)) { - Pmsg2(0, _("Could not create FileSet record \"%s\". ERR=%s\n"), + Pmsg2(0, _("Could not create FileSet record \"%s\". ERR=%s\n"), fsr->FileSet, db_strerror(db)); return 0; } if (verbose) { - Pmsg1(000, _("Created FileSet record \"%s\"\n"), fsr->FileSet); + Pmsg1(000, _("Created FileSet record \"%s\"\n"), fsr->FileSet); } } return 1; @@ -1035,18 +1035,18 @@ static int update_job_record(B_DB *db, JOB_DBR *jr, SESSION_LABEL *elabel, switch (mjcr->JobStatus) { case JS_Terminated: - term_msg = _("Backup OK"); + term_msg = _("Backup OK"); break; case JS_FatalError: case JS_ErrorTerminated: - term_msg = _("*** Backup Error ***"); + term_msg = _("*** Backup Error ***"); break; case JS_Canceled: - term_msg = _("Backup Canceled"); + term_msg = _("Backup Canceled"); break; default: term_msg = term_code; - sprintf(term_code, _("Job Termination code: %d"), mjcr->JobStatus); + sprintf(term_code, _("Job Termination code: %d"), mjcr->JobStatus); break; } bstrftime(sdt, sizeof(sdt), mjcr->start_time); @@ -1133,7 +1133,7 @@ static int update_SIG_record(B_DB *db, char *SIGbuf, DEV_RECORD *rec, int type) mjcr = get_jcr_by_session(rec->VolSessionId, rec->VolSessionTime); if (!mjcr) { if (mr.VolJobs > 0) { - Pmsg2(000, _("Could not find SessId=%d SessTime=%d for MD5/SHA1 record.\n"), + Pmsg2(000, _("Could not find SessId=%d SessTime=%d for MD5/SHA1 record.\n"), rec->VolSessionId, rec->VolSessionTime); } else { ignored_msgs++; diff --git a/bacula/src/stored/btape.c b/bacula/src/stored/btape.c index 460c0ae937..dad98ef739 100644 --- a/bacula/src/stored/btape.c +++ b/bacula/src/stored/btape.c @@ -14,7 +14,7 @@ * */ /* - 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 @@ -2535,7 +2535,7 @@ static void helpcmd() static void usage() { fprintf(stderr, _( -"Copyright (C) 2000-2004 Kern Sibbald and John Walker.\n" +"Copyright (C) 2000-2005 Kern Sibbald.\n" "\nVersion: " VERSION " (" BDATE ")\n\n" "Usage: btape \n" " -b specify bootstrap file\n" diff --git a/bacula/src/stored/butil.c b/bacula/src/stored/butil.c index a63dd2829d..4e52652fad 100644 --- a/bacula/src/stored/butil.c +++ b/bacula/src/stored/butil.c @@ -12,7 +12,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/version.h b/bacula/src/version.h index 7a381691bc..6175c6a35e 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -1,8 +1,8 @@ /* */ #undef VERSION #define VERSION "1.37.3" -#define BDATE "04 February 2005" -#define LSMDATE "04Feb05" +#define BDATE "07 February 2005" +#define LSMDATE "07Feb05" /* Debug flags */ #undef DEBUG -- 2.39.5