From: Kern Sibbald Date: Sat, 17 May 2003 21:54:35 +0000 (+0000) Subject: Use rentrant mysql lib, eliminate race in sql_list, Win32 streams, misc see kes-1.31 X-Git-Tag: Release-1.31~140 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=aeb32540d60ba5c23f0bca6be89a0268d0d07e74;p=bacula%2Fbacula Use rentrant mysql lib, eliminate race in sql_list, Win32 streams, misc see kes-1.31 git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@516 91ce42f0-d328-0410-95d8-f526ca767f89 --- diff --git a/bacula/autoconf/aclocal.m4 b/bacula/autoconf/aclocal.m4 index 5b69434fda..51ea4e8e69 100644 --- a/bacula/autoconf/aclocal.m4 +++ b/bacula/autoconf/aclocal.m4 @@ -387,7 +387,7 @@ Which DBMS do you want to use (please select only one): fi fi SQL_INCLUDE=-I$MYSQL_INCDIR - SQL_LFLAGS="-L$MYSQL_LIBDIR -lmysqlclient -lz" + SQL_LFLAGS="-L$MYSQL_LIBDIR -lmysqlclient_r -lz" SQL_BINDIR=$MYSQL_BINDIR AC_DEFINE(HAVE_MYSQL) diff --git a/bacula/autoconf/configure.in b/bacula/autoconf/configure.in index c927c8097f..3ff33476c9 100644 --- a/bacula/autoconf/configure.in +++ b/bacula/autoconf/configure.in @@ -1269,7 +1269,7 @@ openbsd) ;; redhat) DISTVER=`cat /etc/redhat-release | grep release |\ - cut -f 5 -d ' '` + cut -f 5 -d ' '` TAPEDRIVE="/dev/nst0" PSCMD="ps -e -o pid,command" PFILES="${PFILES} \ @@ -1314,7 +1314,7 @@ solaris) ;; suse) DISTVER=`cat /etc/SuSE-release |grep VERSION|\ - cut -f 3 -d ' '` + cut -f 3 -d ' '` TAPEDRIVE="/dev/nst0" PSCMD="ps -e -o pid,command" hostname=`hostname -s` @@ -1447,8 +1447,18 @@ if test "x$ac_cv_sys_largefile_CFLAGS" != "xno" ; then largefile_support="yes" fi -CCVERSION=`${CC} --version | cut -b-15` -CXXVERSION=`${CXX} --version | cut -b-15` +# +# A whole lot of hand springs to get the compiler version. +# This is because gcc changed the output in version 3.0 +# +CCVERSION=`${CC} --version | tr '\n' ' ' | cut -f 3 -d ' '` +if test "x${CCVERSION}" = "x" ; then + CCVERSION=`${CC} --version | tr '\n' ' ' | cut -f 1 -d ' '` +fi +CXXVERSION=`${CXX} --version | tr '\n' ' ' | cut -f 3 -d ' '` +if test x"${CXXVERSION}" = x ; then + CXXVERSION=`${CXX} --version | tr '\n' ' ' | cut -f 1 -d ' '` +fi if test "x${subsysdir}" = "x${sbindir}" ; then echo " " diff --git a/bacula/configure b/bacula/configure index 084e4fb941..8b54adeba8 100755 --- a/bacula/configure +++ b/bacula/configure @@ -3907,7 +3907,7 @@ if test "${with_mysql+set}" = set; then fi fi SQL_INCLUDE=-I$MYSQL_INCDIR - SQL_LFLAGS="-L$MYSQL_LIBDIR -lmysqlclient -lz" + SQL_LFLAGS="-L$MYSQL_LIBDIR -lmysqlclient_r -lz" SQL_BINDIR=$MYSQL_BINDIR cat >> confdefs.h <<\EOF @@ -9568,7 +9568,7 @@ openbsd) ;; redhat) DISTVER=`cat /etc/redhat-release | grep release |\ - cut -f 5 -d ' '` + cut -f 5 -d ' '` TAPEDRIVE="/dev/nst0" PSCMD="ps -e -o pid,command" PFILES="${PFILES} \ @@ -9616,7 +9616,7 @@ EOF ;; suse) DISTVER=`cat /etc/SuSE-release |grep VERSION|\ - cut -f 3 -d ' '` + cut -f 3 -d ' '` TAPEDRIVE="/dev/nst0" PSCMD="ps -e -o pid,command" hostname=`hostname -s` @@ -10300,8 +10300,18 @@ if test "x$ac_cv_sys_largefile_CFLAGS" != "xno" ; then largefile_support="yes" fi -CCVERSION=`${CC} --version | cut -b-15` -CXXVERSION=`${CXX} --version | cut -b-15` +# +# A whole lot of hand springs to get the compiler version. +# This is because gcc changed the output in version 3.0 +# +CCVERSION=`${CC} --version | tr '\n' ' ' | cut -f 3 -d ' '` +if test "x${CCVERSION}" = "x" ; then + CCVERSION=`${CC} --version | tr '\n' ' ' | cut -f 1 -d ' '` +fi +CXXVERSION=`${CXX} --version | tr '\n' ' ' | cut -f 3 -d ' '` +if test x"${CXXVERSION}" = x ; then + CXXVERSION=`${CXX} --version | tr '\n' ' ' | cut -f 1 -d ' '` +fi if test "x${subsysdir}" = "x${sbindir}" ; then echo " " diff --git a/bacula/kernstodo b/bacula/kernstodo index 9ad8906f17..8351a53da2 100644 --- a/bacula/kernstodo +++ b/bacula/kernstodo @@ -19,6 +19,17 @@ Testing to do: (painful) - Figure out how to use ssh or stunnel to protect Bacula communications. For 1.31 release: +- Cancel waiting for Client connect in SD if FD goes away. +- Testing Tibs job erred and hung director on Storage resource. +- Make restore more robust in counting error and not immediately bailing + out. Also print error message once, but try to continue. +- Make SD keep track of Files, Bytes during restore. +- Add code to check that blocks are sequential on restore. +- File the Automatically selected: xxx + to say Automatically selected Pool: xxx +- Should Bacula make an Append tape as Purged when purging? +- Shell expansion failes for working_directory in SD from time to tim. +- Possibly update all client records at startup. - Volume names with spaces get jammed into the catalog with 0x1 i.e. the SD bashes the Volume but they are not unbased by Dir. @@ -26,16 +37,6 @@ For 1.31 release: - Implement MTIOCERRSTAT on FreeBSD to clear tape error conditions. -- BSDI - cut: illegal option -- b - usage: cut -c list [file1 ...] - cut -f list [-s] [-d delim] [file ...] - cut: illegal option -- b - usage: cut -c list [file1 ...] - cut -f list [-s] [-d delim] [file ...] - - - - Add Progress command that periodically reports the progress of a job or all jobs. - Implement "Reschedule OnError=yes interval=nnn times=xxx" @@ -824,4 +825,7 @@ Done: (see kernsdone for more) - BSD does not have ioctl() MTEOM - BSD defines a number of MT_xxx variables which conflict with those defined by Bacula. - +- Make default duration days if no qualifier (e.g. s) is specified. +- BSDI fix finding gcc version +- When the FD errs (e.g. disk full) have a more graceful shutdown. + diff --git a/bacula/src/cats/bdb_create.c b/bacula/src/cats/bdb_create.c index 1c4e319058..0160abfb68 100644 --- a/bacula/src/cats/bdb_create.c +++ b/bacula/src/cats/bdb_create.c @@ -185,14 +185,15 @@ int db_create_media_record(void *jcr, B_DB *mdb, MEDIA_DBR *mr) int len; MEDIA_DBR mmr; + db_lock(mdb); memset(&mmr, 0, sizeof(mmr)); strcpy(mmr.VolumeName, mr->VolumeName); if (db_get_media_record(jcr, mdb, &mmr)) { Mmsg1(&mdb->errmsg, "Media record %s already exists\n", mmr.VolumeName); + db_unlock(mdb); return 0; } - db_lock(mdb); mdb->control.MediaId++; mr->MediaId = mdb->control.MediaId; @@ -221,13 +222,14 @@ int db_create_client_record(void *jcr, B_DB *mdb, CLIENT_DBR *cr) int len; CLIENT_DBR lcr; + db_lock(mdb); cr->ClientId = 0; if (db_get_client_record(jcr, mdb, cr)) { Mmsg1(&mdb->errmsg, "Client record %s already exists\n", cr->Name); + db_unlock(mdb); return 1; } - db_lock(mdb); if (!bdb_open_client_file(mdb)) { db_unlock(mdb); return 0; @@ -262,13 +264,14 @@ int db_create_fileset_record(void *jcr, B_DB *mdb, FILESET_DBR *fsr) int len; FILESET_DBR lfsr; + db_lock(mdb); fsr->FileSetId = 0; if (db_get_fileset_record(jcr, mdb, fsr)) { Mmsg1(&mdb->errmsg, "FileSet record %s already exists\n", fsr->FileSet); + db_unlock(mdb); return 1; } - db_lock(mdb); if (!bdb_open_fileset_file(mdb)) { db_unlock(mdb); return 0; diff --git a/bacula/src/cats/bdb_delete.c b/bacula/src/cats/bdb_delete.c index de43815f11..982e846318 100644 --- a/bacula/src/cats/bdb_delete.c +++ b/bacula/src/cats/bdb_delete.c @@ -66,12 +66,13 @@ int db_delete_pool_record(void *jcr, B_DB *mdb, POOL_DBR *pr) int stat; POOL_DBR opr; + db_lock(mdb); pr->PoolId = 0; /* Search on Pool Name */ if (!db_get_pool_record(jcr, mdb, pr)) { Mmsg1(&mdb->errmsg, "No pool record %s exists\n", pr->Name); + db_unlock(mdb); return 0; } - db_lock(mdb); fseek(mdb->poolfd, pr->rec_addr, SEEK_SET); memset(&opr, 0, sizeof(opr)); stat = fwrite(&opr, sizeof(opr), 1, mdb->poolfd); @@ -84,11 +85,12 @@ int db_delete_media_record(void *jcr, B_DB *mdb, MEDIA_DBR *mr) int stat; MEDIA_DBR omr; + db_lock(mdb); if (!db_get_media_record(jcr, mdb, mr)) { Mmsg0(&mdb->errmsg, "Media record not found.\n"); + db_unlock(mdb); return 0; } - db_lock(mdb); fseek(mdb->mediafd, mr->rec_addr, SEEK_SET); memset(&omr, 0, sizeof(omr)); stat = fwrite(&omr, sizeof(omr), 1, mdb->mediafd); diff --git a/bacula/src/cats/bdb_find.c b/bacula/src/cats/bdb_find.c index 56dbcefcbd..88bc895cea 100644 --- a/bacula/src/cats/bdb_find.c +++ b/bacula/src/cats/bdb_find.c @@ -75,8 +75,8 @@ int db_find_job_start_time(void *jcr, B_DB *mdb, JOB_DBR *jr, POOLMEM **stime) int found; long addr; - pm_strcpy(stime, "0000-00-00 00:00:00"); /* default */ db_lock(mdb); + pm_strcpy(stime, "0000-00-00 00:00:00"); /* default */ if (!bdb_open_jobs_file(mdb)) { db_unlock(mdb); return 0; diff --git a/bacula/src/cats/bdb_update.c b/bacula/src/cats/bdb_update.c index 5f496d0102..8ab9c56286 100755 --- a/bacula/src/cats/bdb_update.c +++ b/bacula/src/cats/bdb_update.c @@ -66,15 +66,17 @@ int db_update_job_start_record(void *jcr, B_DB *mdb, JOB_DBR *jr) int len, stat = 1; JOB_DBR ojr; + db_lock(mdb); + Dmsg0(200, "In db_update_job_start_record\n"); len = sizeof(ojr); memcpy(&ojr, jr, len); if (!db_get_job_record(jcr, mdb, &ojr)) { + db_unlock(mdb); return 0; } - db_lock(mdb); fseek(mdb->jobfd, ojr.rec_addr, SEEK_SET); if (fwrite(jr, len, 1, mdb->jobfd) != 1) { @@ -96,16 +98,17 @@ int db_update_job_end_record(void *jcr, B_DB *mdb, JOB_DBR *jr) int len, stat = 1; JOB_DBR ojr; + db_lock(mdb); + Dmsg0(200, "In db_update_job_start_record\n"); len = sizeof(ojr); memcpy(&ojr, jr, len); if (!db_get_job_record(jcr, mdb, &ojr)) { + db_unlock(mdb); return 0; } - db_lock(mdb); - fseek(mdb->jobfd, ojr.rec_addr, SEEK_SET); if (fwrite(jr, len, 1, mdb->jobfd) != 1) { Mmsg1(&mdb->errmsg, _("Error updating DB Job file. ERR=%s\n"), strerror(errno)); @@ -124,16 +127,17 @@ int db_update_media_record(void *jcr, B_DB *mdb, MEDIA_DBR *mr) MEDIA_DBR omr; int len; + db_lock(mdb); Dmsg0(200, "In db_update_media_record\n"); mr->MediaId = 0; len = sizeof(omr); memcpy(&omr, mr, len); if (!db_get_media_record(jcr, mdb, &omr)) { + db_unlock(mdb); return 0; } - db_lock(mdb); /* Don't allow some fields to change by copying from master record */ strcpy(mr->VolumeName, omr.VolumeName); @@ -161,15 +165,16 @@ int db_update_pool_record(void *jcr, B_DB *mdb, POOL_DBR *pr) POOL_DBR opr; int len; + db_lock(mdb); Dmsg0(200, "In db_update_pool_record\n"); len = sizeof(opr); memcpy(&opr, pr, len); if (!db_get_pool_record(jcr, mdb, &opr)) { + db_unlock(mdb); return 0; } - db_lock(mdb); /* Update specific fields */ opr.NumVols = pr->NumVols; diff --git a/bacula/src/cats/cats.h b/bacula/src/cats/cats.h index 992da96677..17aaec9146 100644 --- a/bacula/src/cats/cats.h +++ b/bacula/src/cats/cats.h @@ -120,12 +120,12 @@ typedef struct s_db { #define sql_free_result(x) my_sqlite_free_table(x) #define sql_fetch_row(x) my_sqlite_fetch_row(x) #define sql_query(x, y) my_sqlite_query(x, y) -#define sql_close(x) sqlite_close(x->db) -#define sql_strerror(x) x->sqlite_errmsg?x->sqlite_errmsg:"unknown" -#define sql_num_rows(x) x->nrow -#define sql_data_seek(x, i) x->row = i +#define sql_close(x) sqlite_close((x)->db) +#define sql_strerror(x) (x)->sqlite_errmsg?(x)->sqlite_errmsg:"unknown" +#define sql_num_rows(x) (x)->nrow +#define sql_data_seek(x, i) (x)->row = i #define sql_affected_rows(x) 1 -#define sql_insert_id(x) sqlite_last_insert_rowid(x->db) +#define sql_insert_id(x) sqlite_last_insert_rowid((x)->db) #define sql_field_seek(x, y) my_sqlite_field_seek(x, y) #define sql_fetch_field(x) my_sqlite_fetch_field(x) #define sql_num_fields(x) (unsigned)((x)->ncolumn) @@ -184,19 +184,19 @@ typedef struct s_db { /* "Generic" names for easier conversion */ -#define sql_store_result(x) mysql_store_result(x->db) -#define sql_free_result(x) mysql_free_result(x->result) -#define sql_fetch_row(x) mysql_fetch_row(x->result) -#define sql_query(x, y) mysql_query(x->db, y) -#define sql_close(x) mysql_close(x->db) -#define sql_strerror(x) mysql_error(x->db) -#define sql_num_rows(x) mysql_num_rows(x->result) -#define sql_data_seek(x, i) mysql_data_seek(x->result, i) -#define sql_affected_rows(x) mysql_affected_rows(x->db) -#define sql_insert_id(x) mysql_insert_id(x->db) -#define sql_field_seek(x, y) mysql_field_seek(x->result, y) -#define sql_fetch_field(x) mysql_fetch_field(x->result) -#define sql_num_fields(x) mysql_num_fields(x->result) +#define sql_store_result(x) mysql_store_result((x)->db) +#define sql_free_result(x) mysql_free_result((x)->result) +#define sql_fetch_row(x) mysql_fetch_row((x)->result) +#define sql_query(x, y) mysql_query((x)->db, y) +#define sql_close(x) mysql_close((x)->db) +#define sql_strerror(x) mysql_error((x)->db) +#define sql_num_rows(x) mysql_num_rows((x)->result) +#define sql_data_seek(x, i) mysql_data_seek((x)->result, i) +#define sql_affected_rows(x) mysql_affected_rows((x)->db) +#define sql_insert_id(x) mysql_insert_id((x)->db) +#define sql_field_seek(x, y) mysql_field_seek((x)->result, y) +#define sql_fetch_field(x) mysql_fetch_field((x)->result) +#define sql_num_fields(x) mysql_num_fields((x)->result) #define SQL_ROW MYSQL_ROW #define SQL_FIELD MYSQL_FIELD diff --git a/bacula/src/cats/mysql.c b/bacula/src/cats/mysql.c index 3ad7a84eb6..afa55b9f2c 100644 --- a/bacula/src/cats/mysql.c +++ b/bacula/src/cats/mysql.c @@ -166,9 +166,12 @@ It is probably not running or your password is incorrect.\n"), if (!check_tables_version(jcr, mdb)) { V(mutex); + db_close_database(jcr, mdb); return 0; } + my_thread_init(); + mdb->connected = TRUE; V(mutex); return 1; @@ -179,6 +182,7 @@ db_close_database(void *jcr, B_DB *mdb) { P(mutex); mdb->ref_count--; + my_thread_end(); if (mdb->ref_count == 0) { qdchain(&mdb->bq); if (mdb->connected && mdb->db) { @@ -187,7 +191,6 @@ db_close_database(void *jcr, B_DB *mdb) mysql_server_end(); #endif } -/* pthread_mutex_destroy(&mdb->mutex); */ rwl_destroy(&mdb->lock); free_pool_memory(mdb->errmsg); free_pool_memory(mdb->cmd); @@ -242,6 +245,10 @@ db_escape_string(char *snew, char *old, int len) mysql_escape_string(snew, old, len); #ifdef DO_IT_MYSELF + +/* Should use mysql_real_escape_string ! */ +unsigned long mysql_real_escape_string(MYSQL *mysql, char *to, const char *from, unsigned long length); + char *n, *o; n = snew; diff --git a/bacula/src/cats/sql.c b/bacula/src/cats/sql.c index cd9e10b101..55a168ac65 100644 --- a/bacula/src/cats/sql.c +++ b/bacula/src/cats/sql.c @@ -87,11 +87,12 @@ int check_tables_version(void *jcr, B_DB *mdb) return 1; } -/* Utility routine for queries */ +/* Utility routine for queries. The database MUST be locked before calling here. */ int QueryDB(char *file, int line, void *jcr, B_DB *mdb, char *cmd) { - if (sql_query(mdb, cmd)) { + int status; + if ((status=sql_query(mdb, cmd)) != 0) { m_msg(file, line, &mdb->errmsg, _("query %s failed:\n%s\n"), cmd, sql_strerror(mdb)); j_msg(file, line, jcr, M_FATAL, 0, "%s", mdb->errmsg); if (verbose) { @@ -99,8 +100,9 @@ QueryDB(char *file, int line, void *jcr, B_DB *mdb, char *cmd) } return 0; } + mdb->result = sql_store_result(mdb); - + return mdb->result != NULL; } diff --git a/bacula/src/cats/sql_create.c b/bacula/src/cats/sql_create.c index 2d78d31c36..a5bce1cd15 100644 --- a/bacula/src/cats/sql_create.c +++ b/bacula/src/cats/sql_create.c @@ -72,6 +72,8 @@ db_create_job_record(void *jcr, B_DB *mdb, JOB_DBR *jr) utime_t JobTDate; char ed1[30]; + db_lock(mdb); + stime = jr->SchedTime; ASSERT(stime != 0); @@ -79,7 +81,6 @@ db_create_job_record(void *jcr, B_DB *mdb, JOB_DBR *jr) strftime(dt, sizeof(dt), "%Y-%m-%d %T", &tm); JobTDate = (utime_t)stime; - db_lock(mdb); if (!db_next_index(jcr, mdb, "Job", JobId)) { jr->JobId = 0; db_unlock(mdb); diff --git a/bacula/src/cats/sql_find.c b/bacula/src/cats/sql_find.c index b0ed367f58..159a9b365f 100644 --- a/bacula/src/cats/sql_find.c +++ b/bacula/src/cats/sql_find.c @@ -65,8 +65,9 @@ db_find_job_start_time(void *jcr, B_DB *mdb, JOB_DBR *jr, POOLMEM **stime) SQL_ROW row; int JobId; - pm_strcpy(stime, "0000-00-00 00:00:00"); /* default */ db_lock(mdb); + + pm_strcpy(stime, "0000-00-00 00:00:00"); /* default */ /* If no Id given, we must find corresponding job */ if (jr->JobId == 0) { /* Differential is since last Full backup */ diff --git a/bacula/src/cats/sql_list.c b/bacula/src/cats/sql_list.c index 62498588b1..fce05c6997 100644 --- a/bacula/src/cats/sql_list.c +++ b/bacula/src/cats/sql_list.c @@ -77,6 +77,7 @@ int db_list_sql_query(void *jcr, B_DB *mdb, char *query, DB_LIST_HANDLER *sendit void db_list_pool_records(void *jcr, B_DB *mdb, DB_LIST_HANDLER *sendit, void *ctx, int full) { + db_lock(mdb); if (full) { Mmsg(&mdb->cmd, "SELECT PoolId,Name,NumVols,MaxVols,UseOnce,UseCatalog," "AcceptAnyVolume,VolRetention,VolUseDuration,MaxVolJobs,MaxVolBytes," @@ -87,7 +88,6 @@ db_list_pool_records(void *jcr, B_DB *mdb, DB_LIST_HANDLER *sendit, void *ctx, i "FROM Pool ORDER BY PoolId"); } - db_lock(mdb); if (!QUERY_DB(jcr, mdb, mdb->cmd)) { db_unlock(mdb); return; @@ -102,6 +102,7 @@ db_list_pool_records(void *jcr, B_DB *mdb, DB_LIST_HANDLER *sendit, void *ctx, i void db_list_client_records(void *jcr, B_DB *mdb, DB_LIST_HANDLER *sendit, void *ctx, int full) { + db_lock(mdb); if (full) { Mmsg(&mdb->cmd, "SELECT ClientId,Name,Uname,AutoPrune,FileRetention," "FileRetention,JobRetention " @@ -111,7 +112,6 @@ db_list_client_records(void *jcr, B_DB *mdb, DB_LIST_HANDLER *sendit, void *ctx, "FROM Client ORDER BY ClientId"); } - db_lock(mdb); if (!QUERY_DB(jcr, mdb, mdb->cmd)) { db_unlock(mdb); return; @@ -132,6 +132,7 @@ void db_list_media_records(void *jcr, B_DB *mdb, MEDIA_DBR *mdbr, DB_LIST_HANDLER *sendit, void *ctx, int full) { + db_lock(mdb); if (full) { if (mdbr->VolumeName[0] != 0) { Mmsg(&mdb->cmd, "SELECT MediaId,VolumeName,Slot,PoolId," @@ -160,7 +161,6 @@ db_list_media_records(void *jcr, B_DB *mdb, MEDIA_DBR *mdbr, } } - db_lock(mdb); if (!QUERY_DB(jcr, mdb, mdb->cmd)) { db_unlock(mdb); return; @@ -175,6 +175,7 @@ db_list_media_records(void *jcr, B_DB *mdb, MEDIA_DBR *mdbr, void db_list_jobmedia_records(void *jcr, B_DB *mdb, uint32_t JobId, DB_LIST_HANDLER *sendit, void *ctx, int full) { + db_lock(mdb); if (full) { if (JobId > 0) { /* do by JobId */ Mmsg(&mdb->cmd, "SELECT JobMediaId,JobId,MediaId,Media.VolumeName," @@ -197,7 +198,6 @@ void db_list_jobmedia_records(void *jcr, B_DB *mdb, uint32_t JobId, "FROM JobMedia,Media WHERE Media.MediaId=JobMedia.MediaId"); } } - db_lock(mdb); if (!QUERY_DB(jcr, mdb, mdb->cmd)) { db_unlock(mdb); return; @@ -221,6 +221,7 @@ void db_list_job_records(void *jcr, B_DB *mdb, JOB_DBR *jr, DB_LIST_HANDLER *sendit, void *ctx, int full) { + db_lock(mdb); if (full) { if (jr->JobId == 0 && jr->Job[0] == 0) { Mmsg(&mdb->cmd, @@ -253,12 +254,10 @@ db_list_job_records(void *jcr, B_DB *mdb, JOB_DBR *jr, DB_LIST_HANDLER *sendit, "JobFiles,JobBytes,JobStatus FROM Job WHERE JobId=%u", jr->JobId); } } - db_lock(mdb); if (!QUERY_DB(jcr, mdb, mdb->cmd)) { db_unlock(mdb); return; } - list_result(mdb, sendit, ctx, full); sql_free_result(mdb); @@ -306,13 +305,13 @@ AS Files,sum(JobBytes) As Bytes FROM Job"); void db_list_files_for_job(void *jcr, B_DB *mdb, uint32_t jobid, DB_LIST_HANDLER *sendit, void *ctx) { + db_lock(mdb); Mmsg(&mdb->cmd, "SELECT Path.Path,Filename.Name FROM File,\ Filename,Path WHERE File.JobId=%u AND Filename.FilenameId=File.FilenameId \ AND Path.PathId=File.PathId", jobid); - db_lock(mdb); if (!QUERY_DB(jcr, mdb, mdb->cmd)) { db_unlock(mdb); return; diff --git a/bacula/src/dird/backup.c b/bacula/src/dird/backup.c index e506c1b3dd..0281e422f3 100644 --- a/bacula/src/dird/backup.c +++ b/bacula/src/dird/backup.c @@ -285,7 +285,7 @@ static int wait_for_job_termination(JCR *jcr) } } if (is_bnet_error(fd)) { - Jmsg(jcr, M_FATAL, 0, _(" 0) { pthread_cond_broadcast(&resource_wait); } + jcr->acquired_resource_locks = 0; V(mutex); #endif } diff --git a/bacula/src/dird/ua_restore.c b/bacula/src/dird/ua_restore.c index 3a280fc135..c687b1b4e2 100644 --- a/bacula/src/dird/ua_restore.c +++ b/bacula/src/dird/ua_restore.c @@ -133,6 +133,13 @@ int restorecmd(UAContext *ua, char *cmd) int restore_jobs = 0; NAME_LIST name_list; uint32_t selected_files = 0; + char *where = NULL; + int i; + + i = find_arg_with_value(ua, "where"); + if (i >= 0) { + where = ua->argv[i]; + } if (!open_db(ua)) { return 0; @@ -263,12 +270,19 @@ int restorecmd(UAContext *ua, char *cmd) bstrncpy(ji.ClientName, cr.Name, sizeof(ji.ClientName)); } - /* Build run command */ - Mmsg(&ua->cmd, - "run job=\"%s\" client=\"%s\" storage=\"%s\" bootstrap=\"%s/restore.bsr\"", - job->hdr.name, ji.ClientName, ji.store?ji.store->hdr.name:"", - working_directory); - + /* Build run command */ + if (where) { + Mmsg(&ua->cmd, + "run job=\"%s\" client=\"%s\" storage=\"%s\" bootstrap=\"%s/restore.bsr\"" + "where=\"%s\"", + job->hdr.name, ji.ClientName, ji.store?ji.store->hdr.name:"", + working_directory, where); + } else { + Mmsg(&ua->cmd, + "run job=\"%s\" client=\"%s\" storage=\"%s\" bootstrap=\"%s/restore.bsr\"", + job->hdr.name, ji.ClientName, ji.store?ji.store->hdr.name:"", + working_directory); + } Dmsg1(400, "Submitting: %s\n", ua->cmd); parse_ua_args(ua); diff --git a/bacula/src/filed/backup.c b/bacula/src/filed/backup.c index 2029f4f45b..81ced4d798 100644 --- a/bacula/src/filed/backup.c +++ b/bacula/src/filed/backup.c @@ -286,7 +286,11 @@ static int save_file(FF_PKT *ff_pkt, void *vjcr) Dmsg1(100, "Saving data, type=%d\n", ff_pkt->type); - if (ff_pkt->flags & FO_SPARSE) { + /* Note, no sparse option for win32_data */ + if (is_win32_data(&ff_pkt->bfd)) { + stream = STREAM_WIN32_DATA; + ff_pkt->flags &= ~FO_SPARSE; + } else if (ff_pkt->flags & FO_SPARSE) { stream = STREAM_SPARSE_DATA; } else { stream = STREAM_FILE_DATA; @@ -297,7 +301,9 @@ static int save_file(FF_PKT *ff_pkt, void *vjcr) const Bytef *cbuf = NULL; if (ff_pkt->flags & FO_GZIP) { - if (stream == STREAM_FILE_DATA) { + if (stream == STREAM_WIN32_DATA) { + stream = STREAM_WIN32_GZIP_DATA; + } else if (stream == STREAM_FILE_DATA) { stream = STREAM_GZIP_DATA; } else { stream = STREAM_SPARSE_GZIP_DATA; @@ -395,7 +401,6 @@ static int save_file(FF_PKT *ff_pkt, void *vjcr) } #endif - /* #ifndef FD_NO_SEND_TEST */ /* Send the buffer to the Storage daemon */ if (!sparseBlock) { if (ff_pkt->flags & FO_SPARSE) { @@ -430,7 +435,6 @@ static int save_file(FF_PKT *ff_pkt, void *vjcr) } } - /* Terminate any MD5 signature and send it to Storage daemon and the Director */ if (gotMD5 && ff_pkt->flags & FO_MD5) { MD5Final(signature, &md5c); @@ -441,6 +445,7 @@ static int save_file(FF_PKT *ff_pkt, void *vjcr) bnet_send(sd); bnet_sig(sd, BNET_EOD); /* end of MD5 */ gotMD5 = 0; + } else if (gotSHA1 && ff_pkt->flags & FO_SHA1) { /* Terminate any SHA1 signature and send it to Storage daemon and the Director */ SHA1Final(&sha1c, signature); diff --git a/bacula/src/filed/job.c b/bacula/src/filed/job.c index 0a8510df01..8cb24a5672 100644 --- a/bacula/src/filed/job.c +++ b/bacula/src/filed/job.c @@ -195,6 +195,15 @@ void *handle_client_request(void *dirp) break; } } + + /* Inform Storage daemon that we are done */ + if (jcr->store_bsock) { + bnet_sig(jcr->store_bsock, BNET_TERMINATE); + } + + /* Inform Director that we are done */ + bnet_sig(dir, BNET_TERMINATE); + Dmsg0(100, "Calling term_find_files\n"); term_find_files((FF_PKT *)jcr->ff); Dmsg0(100, "Done with term_find_files\n"); @@ -613,16 +622,8 @@ static int backup_cmd(JCR *jcr) cleanup: - /* Inform Storage daemon that we are done */ - if (sd) { - bnet_sig(sd, BNET_TERMINATE); - } - bnet_fsend(dir, EndBackup, jcr->JobStatus, jcr->JobFiles, jcr->ReadBytes, jcr->JobBytes); - /* Inform Director that we are done */ - bnet_sig(dir, BNET_TERMINATE); - return 0; /* return and stop command loop */ } diff --git a/bacula/src/filed/restore.c b/bacula/src/filed/restore.c index 803b1ac75b..8f4e21cdf8 100644 --- a/bacula/src/filed/restore.c +++ b/bacula/src/filed/restore.c @@ -297,7 +297,8 @@ void do_restore(JCR *jcr) /* Data stream */ - } else if (stream == STREAM_FILE_DATA || stream == STREAM_SPARSE_DATA) { + } else if (stream == STREAM_FILE_DATA || stream == STREAM_SPARSE_DATA || + stream == STREAM_WIN32_DATA) { if (extract) { if (stream == STREAM_SPARSE_DATA) { ser_declare; @@ -323,7 +324,7 @@ void do_restore(JCR *jcr) Dmsg2(30, "Write %u bytes, total before write=%u\n", wsize, total); if ((uint32_t)bwrite(&bfd, wbuf, wsize) != wsize) { Dmsg0(0, "===Write error===\n"); - Jmsg2(jcr, M_ERROR, 0, _("Write error on %s: %s\n"), ofile, berror(&bfd)); + Jmsg2(jcr, M_ERROR, 0, _("Write error on %s: ERR=%s\n"), ofile, berror(&bfd)); goto bail_out; } total += wsize; @@ -332,7 +333,8 @@ void do_restore(JCR *jcr) } /* GZIP data stream */ - } else if (stream == STREAM_GZIP_DATA || stream == STREAM_SPARSE_GZIP_DATA) { + } else if (stream == STREAM_GZIP_DATA || stream == STREAM_SPARSE_GZIP_DATA || + stream == STREAM_WIN32_GZIP_DATA) { #ifdef HAVE_LIBZ if (extract) { ser_declare; diff --git a/bacula/src/filed/verify_vol.c b/bacula/src/filed/verify_vol.c index 306e4cf90e..4b9117f0b2 100644 --- a/bacula/src/filed/verify_vol.c +++ b/bacula/src/filed/verify_vol.c @@ -204,6 +204,10 @@ void do_verify_volume(JCR *jcr) /* Do nothing */ + } else if (stream == STREAM_WIN32_DATA || stream == STREAM_WIN32_GZIP_DATA) { + + /* Do nothing */ + /* If MD5 stream */ } else if (stream == STREAM_MD5_SIGNATURE) { char MD5buf[30]; diff --git a/bacula/src/filed/win32/winmain.cpp b/bacula/src/filed/win32/winmain.cpp index fa61af1bf5..4acbb3c2d0 100755 --- a/bacula/src/filed/win32/winmain.cpp +++ b/bacula/src/filed/win32/winmain.cpp @@ -317,7 +317,7 @@ int BaculaAppMain() HINSTANCE hLib = LoadLibrary("KERNEL32.DLL"); if (hLib) { p_GetFileAttributesEx = (t_GetFileAttributesEx) - GetProcAddress(hLib, "GetFileFileAttributesExA"); + GetProcAddress(hLib, "GetFileAttributesExA"); p_SetProcessShutdownParameters = (t_SetProcessShutdownParameters) GetProcAddress(hLib, "SetProcessShutdownParameters"); p_BackupRead = (t_BackupRead) @@ -337,9 +337,58 @@ int BaculaAppMain() FreeLibrary(hLib); } +#ifdef debug_xxx + char buf[1000]; + buf[0] = 0; + strcat(buf, "GetFileAttributesEx "); + if (p_GetFileAttributesEx) + strcat(buf, "OK\n"); + else + strcat(buf, "NO\n"); + + strcat(buf, "SetProcessShutdownParamaters "); + if (p_SetProcessShutdownParameters) + strcat(buf, "OK\n"); + else + strcat(buf, "NO\n"); + + strcat(buf, "BackupRead "); + if (p_BackupRead) + strcat(buf, "OK\n"); + else + strcat(buf, "NO\n"); + + strcat(buf, "BackupWrite "); + if (p_BackupWrite) + strcat(buf, "OK\n"); + else + strcat(buf, "NO\n"); + + strcat(buf, "OpenProcessToken "); + if (p_OpenProcessToken) + strcat(buf, "OK\n"); + else + strcat(buf, "NO\n"); + + strcat(buf, "AdjustTokenPrivileges "); + if (p_AdjustTokenPrivileges) + strcat(buf, "OK\n"); + else + strcat(buf, "NO\n"); + + strcat(buf, "LookupPrivilegeValue "); + if (p_LookupPrivilegeValue) + strcat(buf, "OK\n"); + else + strcat(buf, "NO\n"); + + MessageBox(NULL, buf, "APIs Available", MB_OK); +#endif // Set this process to be the last application to be shut down. - SetProcessShutdownParameters(0x100, 0); + if (p_SetProcessShutdownParameters) { + p_SetProcessShutdownParameters(0x100, 0); + } HWND hservwnd = FindWindow(MENU_CLASS_NAME, NULL); if (hservwnd != NULL) { diff --git a/bacula/src/findlib/attribs.c b/bacula/src/findlib/attribs.c index 4fb1070b87..fc137d6b91 100755 --- a/bacula/src/findlib/attribs.c +++ b/bacula/src/findlib/attribs.c @@ -30,7 +30,6 @@ #include "bacula.h" #include "find.h" -#include "jcr.h" #ifdef HAVE_CYGWIN diff --git a/bacula/src/findlib/bfile.c b/bacula/src/findlib/bfile.c index f3e8f02e1b..9f4ab897ef 100644 --- a/bacula/src/findlib/bfile.c +++ b/bacula/src/findlib/bfile.c @@ -41,12 +41,34 @@ void binit(BFILE *bfd) { bfd->fid = -1; bfd->mode = BF_CLOSED; - bfd->use_win_api = p_BackupRead && p_BackupWrite; + bfd->use_win_api = 1; + bfd->use_backup_api = p_BackupRead && p_BackupWrite; bfd->errmsg = NULL; bfd->lpContext = NULL; bfd->lerror = 0; } +/* + * Enables/disables using the Backup API (win32_data). + * Returns 1 if function worked + * Returns 0 if failed (i.e. do not have Backup API on this machine) + */ +int set_win32_data(BFILE *bfd, int enable) +{ + if (!enable) { + bfd->use_backup_api = 0; + return 1; + } + /* We enable if possible here */ + bfd->use_backup_api = p_BackupRead && p_BackupWrite; + return bfd->use_backup_api; +} + +int is_win32_data(BFILE *bfd) +{ + return bfd->use_backup_api; +} + HANDLE bget_handle(BFILE *bfd) { if (!bfd->use_win_api) { @@ -127,7 +149,7 @@ int bclose(BFILE *bfd) if (bfd->mode == BF_CLOSED) { return 0; } - if (bfd->mode == BF_READ) { + if (bfd->use_backup_api && bfd->mode == BF_READ) { BYTE buf[10]; if (!bfd->lpContext && !p_BackupRead(bfd->fh, buf, /* buffer */ @@ -138,7 +160,7 @@ int bclose(BFILE *bfd) &bfd->lpContext)) { /* Read context */ stat = -1; } - } else { + } else if (bfd->use_backup_api && bfd->mode == BF_WRITE) { BYTE buf[10]; if (!bfd->lpContext && !p_BackupWrite(bfd->fh, buf, /* buffer */ @@ -194,18 +216,30 @@ ssize_t bread(BFILE *bfd, void *buf, size_t count) if (!bfd->use_win_api) { return read(bfd->fid, buf, count); } - bfd->rw_bytes = 0; - if (!p_BackupRead(bfd->fh, - (BYTE *)buf, - count, - &bfd->rw_bytes, - 0, /* no Abort */ - 1, /* Process Security */ - &bfd->lpContext)) { /* Context */ - bfd->lerror = GetLastError(); - return -1; + + if (bfd->use_backup_api) { + if (!p_BackupRead(bfd->fh, + (BYTE *)buf, + count, + &bfd->rw_bytes, + 0, /* no Abort */ + 1, /* Process Security */ + &bfd->lpContext)) { /* Context */ + bfd->lerror = GetLastError(); + return -1; + } + } else { + if (!ReadFile(bfd->fh, + buf, + count, + &bfd->rw_bytes, + NULL)) { + bfd->lerror = GetLastError(); + return -1; + } } + return (ssize_t)bfd->rw_bytes; } @@ -214,17 +248,28 @@ ssize_t bwrite(BFILE *bfd, void *buf, size_t count) if (!bfd->use_win_api) { return write(bfd->fid, buf, count); } - bfd->rw_bytes = 0; - if (!p_BackupWrite(bfd->fh, - (BYTE *)buf, - count, - &bfd->rw_bytes, - 0, /* No abort */ - 1, /* Process Security */ - &bfd->lpContext)) { /* Context */ - bfd->lerror = GetLastError(); - return -1; + + if (bfd->use_backup_api) { + if (!p_BackupWrite(bfd->fh, + (BYTE *)buf, + count, + &bfd->rw_bytes, + 0, /* No abort */ + 1, /* Process Security */ + &bfd->lpContext)) { /* Context */ + bfd->lerror = GetLastError(); + return -1; + } + } else { + if (!WriteFile(bfd->fh, + buf, + count, + &bfd->rw_bytes, + NULL)) { + bfd->lerror = GetLastError(); + return -1; + } } return (ssize_t)bfd->rw_bytes; } @@ -255,26 +300,41 @@ void binit(BFILE *bfd) bfd->fid = -1; } +int is_win32_data(BFILE *bfd) +{ + return 0; +} + + int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode) { - return bfd->fid = open(fname, flags, mode); + bfd->fid = open(fname, flags, mode); + bfd->berrno = errno; + return bfd->fid; } int bclose(BFILE *bfd) { int stat = close(bfd->fid); + bfd->berrno = errno; bfd->fid = -1; return stat; } ssize_t bread(BFILE *bfd, void *buf, size_t count) { - return read(bfd->fid, buf, count); + ssize_t stat; + stat = read(bfd->fid, buf, count); + bfd->berrno = errno; + return stat; } ssize_t bwrite(BFILE *bfd, void *buf, size_t count) { - return write(bfd->fid, buf, count); + ssize_t stat; + stat = write(bfd->fid, buf, count); + bfd->berrno = errno; + return stat; } int is_bopen(BFILE *bfd) @@ -284,12 +344,15 @@ int is_bopen(BFILE *bfd) off_t blseek(BFILE *bfd, off_t offset, int whence) { - return lseek(bfd->fid, offset, whence); + off_t pos; + pos = lseek(bfd->fid, offset, whence); + bfd->berrno = errno; + return pos; } char *berror(BFILE *bfd) { - return strerror(errno); + return strerror(bfd->berrno); } #endif diff --git a/bacula/src/findlib/bfile.h b/bacula/src/findlib/bfile.h new file mode 100644 index 0000000000..3fced23ea5 --- /dev/null +++ b/bacula/src/findlib/bfile.h @@ -0,0 +1,77 @@ +/* + * Bacula low level File I/O routines. This routine simulates + * open(), read(), write(), and close(), but using native routines. + * I.e. on Windows, we use Windows APIs. + * + * Kern Sibbald May MMIII + */ +/* + Copyright (C) 2000-2003 Kern Sibbald and John Walker + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public + License along with this program; if not, write to the Free + Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + */ + +#ifndef __BFILE_H +#define __BFILE_H + +#ifdef HAVE_CYGWIN + +#include +#include "winapi.h" + +#define BF_CLOSED 0 +#define BF_READ 1 /* BackupRead */ +#define BF_WRITE 2 /* BackupWrite */ + +/* In bfile.c */ + +/* Basic low level I/O file packet */ +typedef struct s_bfile { + int use_win_api; /* set if using WinAPI */ + int use_backup_api; /* set if using BackupRead/Write */ + int mode; /* set if file is open */ + HANDLE fh; /* Win32 file handle */ + int fid; /* fd if doing Unix style */ + LPVOID lpContext; /* BackupRead/Write context */ + POOLMEM *errmsg; /* error message buffer */ + DWORD rw_bytes; /* Bytes read or written */ + DWORD lerror; /* Last error code */ +} BFILE; + +HANDLE bget_handle(BFILE *bfd); + +#else /* Linux/Unix systems */ + +/* Basic low level I/O file packet */ +typedef struct s_bfile { + int fid; /* file id on Unix */ + int berrno; +} BFILE; + +#endif + +void binit(BFILE *bfd); +int is_bopen(BFILE *bfd); +int is_win32_data(BFILE *bfd); +char *berror(BFILE *bfd); +int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode); +int bclose(BFILE *bfd); +ssize_t bread(BFILE *bfd, void *buf, size_t count); +ssize_t bwrite(BFILE *bfd, void *buf, size_t count); +off_t blseek(BFILE *bfd, off_t offset, int whence); + +#endif /* __BFILE_H */ diff --git a/bacula/src/findlib/find.h b/bacula/src/findlib/find.h index 0ae3042114..e0ed71836b 100755 --- a/bacula/src/findlib/find.h +++ b/bacula/src/findlib/find.h @@ -27,6 +27,7 @@ #define __FILES_H #include "jcr.h" +#include "bfile.h" #ifdef HAVE_DIRENT_H #include @@ -133,35 +134,6 @@ struct s_excluded_file { char fname[1]; }; -#ifdef HAVE_CYGWIN - -#include -#include "winapi.h" - -#define BF_CLOSED 0 -#define BF_READ 1 /* BackupRead */ -#define BF_WRITE 2 /* BackupWrite */ - -/* Basic low level I/O file packet */ -typedef struct s_bfile { - int use_win_api; /* set if using WinAPI */ - int mode; /* set if file is open */ - HANDLE fh; /* Win32 file handle */ - int fid; /* fd if doing Unix style */ - LPVOID lpContext; /* BackupRead/Write context */ - POOLMEM *errmsg; /* error message buffer */ - DWORD rw_bytes; /* Bytes read or written */ - DWORD lerror; /* Last error code */ -} BFILE; - -#else - -/* Basic low level I/O file packet */ -typedef struct s_bfile { - int fid; /* file id on Unix */ -} BFILE; - -#endif /* diff --git a/bacula/src/findlib/protos.h b/bacula/src/findlib/protos.h index 71e5a3f817..8fbec6d79f 100644 --- a/bacula/src/findlib/protos.h +++ b/bacula/src/findlib/protos.h @@ -67,13 +67,5 @@ int make_path(void *jcr, const char *argpath, int mode, int parent_mode, uid_t owner, gid_t group, int preserve_existing, char *verbose_fmt_string); -/* from file_io.c */ -ssize_t bread(BFILE *bfd, void *buf, size_t count); -int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode); -int bclose(BFILE *bfd); -ssize_t bread(BFILE *bfd, void *buf, size_t count); -ssize_t bwrite(BFILE *bfd, void *buf, size_t count); -off_t blseek(BFILE *bfd, off_t offset, int whence); -int is_bopen(BFILE *bfd); -void binit(BFILE *bfd); -char *berror(BFILE *bfd); +/* from bfile.c -- see bfile.h */ + diff --git a/bacula/src/findlib/winapi.h b/bacula/src/findlib/winapi.h index c758eeb017..0877bc4bc3 100644 --- a/bacula/src/findlib/winapi.h +++ b/bacula/src/findlib/winapi.h @@ -30,26 +30,26 @@ #ifdef HAVE_CYGWIN /* In ADVAPI32.DLL */ -typedef BOOL (*t_OpenProcessToken)(HANDLE, DWORD, PHANDLE); -typedef BOOL (*t_AdjustTokenPrivileges)(HANDLE, BOOL, - PTOKEN_PRIVILEGES, DWORD, PTOKEN_PRIVILEGES, PDWORD); -typedef BOOL (*t_LookupPrivilegeValue)(LPCTSTR, LPCTSTR, PLUID); +typedef BOOL WINAPI (*t_OpenProcessToken)(HANDLE, DWORD, PHANDLE); +typedef BOOL WINAPI (*t_AdjustTokenPrivileges)(HANDLE, BOOL, + PTOKEN_PRIVILEGES, DWORD, PTOKEN_PRIVILEGES, PDWORD); +typedef BOOL WINAPI (*t_LookupPrivilegeValue)(LPCTSTR, LPCTSTR, PLUID); extern t_OpenProcessToken p_OpenProcessToken; extern t_AdjustTokenPrivileges p_AdjustTokenPrivileges; extern t_LookupPrivilegeValue p_LookupPrivilegeValue; /* In KERNEL32.DLL */ -typedef BOOL (*t_GetFileAttributesEx)(LPCTSTR, GET_FILEEX_INFO_LEVELS, - LPVOID); -typedef BOOL (*t_SetProcessShutdownParameters)(DWORD, DWORD); -typedef BOOL (*t_BackupRead)(HANDLE,LPBYTE,DWORD,LPDWORD,BOOL,BOOL,LPVOID*); -typedef BOOL (*t_BackupWrite)(HANDLE,LPBYTE,DWORD,LPDWORD,BOOL,BOOL,LPVOID*); +typedef BOOL WINAPI (*t_GetFileAttributesEx)(LPCTSTR, GET_FILEEX_INFO_LEVELS, + LPVOID); +typedef BOOL WINAPI (*t_SetProcessShutdownParameters)(DWORD, DWORD); +typedef BOOL WINAPI (*t_BackupRead)(HANDLE,LPBYTE,DWORD,LPDWORD,BOOL,BOOL,LPVOID*); +typedef BOOL WINAPI (*t_BackupWrite)(HANDLE,LPBYTE,DWORD,LPDWORD,BOOL,BOOL,LPVOID*); extern t_GetFileAttributesEx p_GetFileAttributesEx; extern t_SetProcessShutdownParameters p_SetProcessShutdownParameters; -extern t_BackupRead p_BackupRead; -extern t_BackupWrite p_BackupWrite; +extern t_BackupRead p_BackupRead; +extern t_BackupWrite p_BackupWrite; #endif diff --git a/bacula/src/lib/bnet.c b/bacula/src/lib/bnet.c index f1d850ff1a..22b9af1b01 100644 --- a/bacula/src/lib/bnet.c +++ b/bacula/src/lib/bnet.c @@ -299,6 +299,10 @@ bnet_send(BSOCK *bsock) rc = write_nbytes(bsock, (char *)&pktsiz, sizeof(int32_t)); bsock->timer_start = 0; /* clear timer */ if (rc != sizeof(int32_t)) { + if (bsock->msglen == BNET_TERMINATE) { /* if we were terminating */ + bsock->terminated = 1; + return 0; /* ignore any errors */ + } bsock->errors++; if (errno == 0) { bsock->b_errno = EIO; diff --git a/bacula/src/lib/edit.c b/bacula/src/lib/edit.c index 28ea49bb4a..b601c53c06 100644 --- a/bacula/src/lib/edit.c +++ b/bacula/src/lib/edit.c @@ -103,8 +103,9 @@ int duration_to_utime(char *str, utime_t *value) { int i, ch, len; double val; - static int mod[] = {'*', 's', 'n', 'h', 'd', 'w', 'm', 'q', 'y', 0}; - static int mult[] = {1, 1, 60, 60*60, 60*60*24, 60*60*24*7, 60*60*24*30, + /* Default to 1 day if no modifier given */ + static int mod[] = {'*', 's', 'n', 'h', 'd', 'w', 'm', 'q', 'y', 0}; + static int mult[] = {60*60*24, 1, 60, 60*60, 60*60*24, 60*60*24*7, 60*60*24*30, 60*60*24*91, 60*60*24*365}; /* Look for modifier */ diff --git a/bacula/src/stored/Makefile.in b/bacula/src/stored/Makefile.in index 245fcddf7c..753f91b162 100644 --- a/bacula/src/stored/Makefile.in +++ b/bacula/src/stored/Makefile.in @@ -126,7 +126,7 @@ install: all $(INSTALL_PROGRAM) bacula-sd $(DESTDIR)$(sbindir)/bacula-sd $(INSTALL_PROGRAM) bls $(DESTDIR)$(sbindir)/bls $(INSTALL_PROGRAM) bextract $(DESTDIR)$(sbindir)/bextract -# $(INSTALL_PROGRAM) bcopy $(DESTDIR)$(sbindir)/bcopy + $(INSTALL_PROGRAM) bcopy $(DESTDIR)$(sbindir)/bcopy $(INSTALL_PROGRAM) bscan $(DESTDIR)$(sbindir)/bscan $(INSTALL_PROGRAM) btape $(DESTDIR)$(sbindir)/btape @srcconf=bacula-sd.conf; \ diff --git a/bacula/src/version.h b/bacula/src/version.h index 149f1f861a..85459f8637 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -1,8 +1,8 @@ /* */ #define VERSION "1.31" #define VSTRING "1" -#define BDATE "15 May 2003" -#define LSMDATE "15May03" +#define BDATE "18 May 2003" +#define LSMDATE "18May03" /* Debug flags */ #define DEBUG 1