From: Kern Sibbald Date: Thu, 22 May 2003 09:03:38 +0000 (+0000) Subject: lib/bmisc.c -> bsys.c cleanup error status a bit + working directory checks X-Git-Tag: Release-1.31~126 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=420a4c3ab9ec45cfc0122e6f7ce395cf3378597d;p=bacula%2Fbacula lib/bmisc.c -> bsys.c cleanup error status a bit + working directory checks git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@530 91ce42f0-d328-0410-95d8-f526ca767f89 --- diff --git a/bacula/kernstodo b/bacula/kernstodo index d2b826139f..2f86dc967a 100644 --- a/bacula/kernstodo +++ b/bacula/kernstodo @@ -25,6 +25,7 @@ Testing to do: (painful) - Figure out how to use ssh or stunnel to protect Bacula communications. For 1.31 release: +- Use switch() in backup.c and restore.c in FD instead of giant if statement. - Investigate doing RAW backup of Win32 partition. - Add JobName= to VerifyToCatalog so that all verifies can be done at the end. - Add thread specific data to hold the jcr -- send error messages from @@ -879,4 +880,3 @@ Done: (see kernsdone for more) - Put system type returned by FD into catalog. - Finish WIN32_DATA stream code (bextract, check if can handle stream) - Make SD keep track of Files, Bytes during restore. - diff --git a/bacula/src/dird/backup.c b/bacula/src/dird/backup.c index 7b746c0521..277537a856 100644 --- a/bacula/src/dird/backup.c +++ b/bacula/src/dird/backup.c @@ -47,7 +47,8 @@ static char levelcmd[] = "level = %s%s\n"; static char OKbackup[] = "2000 OK backup\n"; static char OKstore[] = "2000 OK storage\n"; static char OKlevel[] = "2000 OK level\n"; -static char EndBackup[] = "2801 End Backup Job TermCode=%d JobFiles=%u ReadBytes=%" lld " JobBytes=%" lld " Errors=%u\n"; +static char EndBackup[] = "2801 End Backup Job TermCode=%d JobFiles=%u " + "ReadBytes=%" lld " JobBytes=%" lld " Errors=%u\n"; /* Forward referenced functions */ @@ -279,6 +280,9 @@ static int wait_for_job_termination(JCR *jcr) fd_ok = TRUE; set_jcr_job_status(jcr, jcr->FDJobStatus); Dmsg1(100, "FDStatus=%c\n", (char)jcr->JobStatus); + } else { + Jmsg(jcr, M_WARNING, 0, _("Unexpected Client Job message: %s\n"), + fd->msg); } if (job_canceled(jcr)) { break; @@ -336,7 +340,8 @@ static void backup_cleanup(JCR *jcr, int TermCode, char *since) } /* Now update the bootstrap file if any */ - if (jcr->JobStatus == JS_Terminated && jcr->jr.JobBytes &&jcr->job->WriteBootstrap) { + if (jcr->JobStatus == JS_Terminated && jcr->jr.JobBytes && + jcr->job->WriteBootstrap) { FILE *fd; BPIPE *bpipe = NULL; int got_pipe = 0; diff --git a/bacula/src/dird/dird.c b/bacula/src/dird/dird.c index aafc5a72bf..a0da2955fb 100644 --- a/bacula/src/dird/dird.c +++ b/bacula/src/dird/dird.c @@ -291,7 +291,7 @@ static void reload_config(int sig) } /* Reset globals */ - working_directory = director->working_directory; + set_working_directory(director->working_directory); FDConnectTimeout = director->FDConnectTimeout; SDConnectTimeout = director->SDConnectTimeout; @@ -322,11 +322,7 @@ static int check_resources() Without that I don't know who I am :-(\n"), configfile); OK = FALSE; } else { - if (!director->working_directory) { - Jmsg(NULL, M_FATAL, 0, _("No working directory specified. Cannot continue.\n")); - OK = FALSE; - } - working_directory = director->working_directory; + set_working_directory(director->working_directory); if (!director->messages) { /* If message resource not specified */ director->messages = (MSGS *)GetNextRes(R_MSGS, NULL); if (!director->messages) { diff --git a/bacula/src/filed/filed.c b/bacula/src/filed/filed.c index 78b0de001d..ac74fa27fb 100644 --- a/bacula/src/filed/filed.c +++ b/bacula/src/filed/filed.c @@ -201,7 +201,8 @@ Without that I don't know who I am :-(\n"), configfile); close_msg(NULL); /* close temp message handler */ init_msg(NULL, me->messages); /* open user specified message handler */ } - working_directory = me->working_directory; + + set_working_directory(me->working_directory); if (test_config) { terminate_filed(0); diff --git a/bacula/src/filed/job.c b/bacula/src/filed/job.c index 131fca92ff..a3bb483034 100644 --- a/bacula/src/filed/job.c +++ b/bacula/src/filed/job.c @@ -531,7 +531,6 @@ static int backup_cmd(JCR *jcr) if (sd == NULL) { Jmsg(jcr, M_FATAL, 0, _("Cannot contact Storage daemon\n")); - set_jcr_job_status(jcr, JS_ErrorTerminated); goto cleanup; } @@ -550,13 +549,11 @@ static int backup_cmd(JCR *jcr) Dmsg1(110, "msg); if (sscanf(sd->msg, OK_open, &jcr->Ticket) != 1) { Jmsg(jcr, M_FATAL, 0, _("Bad response to append open: %s\n"), sd->msg); - set_jcr_job_status(jcr, JS_ErrorTerminated); goto cleanup; } Dmsg1(110, "Got Ticket=%d\n", jcr->Ticket); } else { Jmsg(jcr, M_FATAL, 0, _("Bad response from stored to open command\n")); - set_jcr_job_status(jcr, JS_ErrorTerminated); goto cleanup; } @@ -571,7 +568,6 @@ static int backup_cmd(JCR *jcr) */ Dmsg1(110, "msg); if (!response(jcr, sd, OK_data, "Append Data")) { - set_jcr_job_status(jcr, JS_ErrorTerminated); goto cleanup; } @@ -618,13 +614,11 @@ static int backup_cmd(JCR *jcr) } if (!ok) { Jmsg(jcr, M_FATAL, 0, _("Append Close with SD failed.\n")); - set_jcr_job_status(jcr, JS_ErrorTerminated); goto cleanup; } if (SDJobStatus != JS_Terminated) { Jmsg(jcr, M_FATAL, 0, _("Bad status %d returned from Storage Daemon.\n"), SDJobStatus); - set_jcr_job_status(jcr, JS_ErrorTerminated); } } diff --git a/bacula/src/filed/verify.c b/bacula/src/filed/verify.c index 0c5faec85d..211f62e9d7 100644 --- a/bacula/src/filed/verify.c +++ b/bacula/src/filed/verify.c @@ -109,12 +109,15 @@ static int verify_file(FF_PKT *ff_pkt, void *pkt) break; case FT_NOACCESS: Jmsg(jcr, M_NOTSAVED, -1, _(" Could not access %s: ERR=%s\n"), ff_pkt->fname, strerror(ff_pkt->ff_errno)); + jcr->Errors++; return 1; case FT_NOFOLLOW: Jmsg(jcr, M_NOTSAVED, -1, _(" Could not follow link %s: ERR=%s\n"), ff_pkt->fname, strerror(ff_pkt->ff_errno)); + jcr->Errors++; return 1; case FT_NOSTAT: Jmsg(jcr, M_NOTSAVED, -1, _(" Could not stat %s: ERR=%s\n"), ff_pkt->fname, strerror(ff_pkt->ff_errno)); + jcr->Errors++; return 1; case FT_DIRNOCHG: case FT_NOCHG: @@ -131,9 +134,11 @@ static int verify_file(FF_PKT *ff_pkt, void *pkt) return 1; case FT_NOOPEN: Jmsg(jcr, M_NOTSAVED, -1, _(" Could not open directory %s: ERR=%s\n"), ff_pkt->fname, strerror(ff_pkt->ff_errno)); + jcr->Errors++; return 1; default: Jmsg(jcr, M_NOTSAVED, 0, _(" Unknown file type %d: %s\n"), ff_pkt->type, ff_pkt->fname); + jcr->Errors++; return 1; } @@ -146,6 +151,7 @@ static int verify_file(FF_PKT *ff_pkt, void *pkt) ff_pkt->ff_errno = errno; Jmsg(jcr, M_NOTSAVED, -1, _(" Cannot open %s: ERR=%s.\n"), ff_pkt->fname, berror(&bfd)); + jcr->Errors++; return 1; } } @@ -197,7 +203,7 @@ static int verify_file(FF_PKT *ff_pkt, void *pkt) jcr->JobBytes += n; } if (n < 0) { - Jmsg(jcr, M_WARNING, -1, _("Error reading file %s: ERR=%s\n"), + Jmsg(jcr, M_ERROR, -1, _("Error reading file %s: ERR=%s\n"), ff_pkt->fname, berror(&bfd)); } MD5Final(signature, &md5c); @@ -215,7 +221,7 @@ static int verify_file(FF_PKT *ff_pkt, void *pkt) jcr->JobBytes += n; } if (n < 0) { - Jmsg(jcr, M_WARNING, -1, _("Error reading file %s: ERR=%s\n"), + Jmsg(jcr, M_ERROR, -1, _("Error reading file %s: ERR=%s\n"), ff_pkt->fname, berror(&bfd)); } SHA1Final(&sha1c, signature); diff --git a/bacula/src/filed/verify_vol.c b/bacula/src/filed/verify_vol.c index 4b9117f0b2..839874e633 100644 --- a/bacula/src/filed/verify_vol.c +++ b/bacula/src/filed/verify_vol.c @@ -100,7 +100,9 @@ void do_verify_volume(JCR *jcr) Dmsg1(30, "Got stream data, len=%d\n", sd->msglen); /* File Attributes stream */ - if (stream == STREAM_UNIX_ATTRIBUTES || stream == STREAM_WIN32_ATTRIBUTES) { + switch (stream) { + case STREAM_UNIX_ATTRIBUTES: + case STREAM_WIN32_ATTRIBUTES: char *ap, *lp, *fp; Dmsg0(400, "Stream=Unix Attributes.\n"); @@ -192,48 +194,48 @@ void do_verify_volume(JCR *jcr) Jmsg(jcr, M_FATAL, 0, _("Network error in send to Director: ERR=%s\n"), bnet_strerror(dir)); goto bail_out; } + break; - - /* Data stream */ - } else if (stream == STREAM_FILE_DATA || stream == STREAM_SPARSE_DATA) { - - /* Do nothing */ - - /* GZIP data stream */ - } else if (stream == STREAM_GZIP_DATA || stream == STREAM_SPARSE_GZIP_DATA) { - - /* Do nothing */ - - } else if (stream == STREAM_WIN32_DATA || stream == STREAM_WIN32_GZIP_DATA) { + /* Data streams to ignore */ + case STREAM_FILE_DATA: + case STREAM_SPARSE_DATA: + case STREAM_WIN32_DATA: + case STREAM_WIN32_GZIP_DATA: + case STREAM_GZIP_DATA: + case STREAM_SPARSE_GZIP_DATA: /* Do nothing */ + break; - /* If MD5 stream */ - } else if (stream == STREAM_MD5_SIGNATURE) { + case STREAM_MD5_SIGNATURE: char MD5buf[30]; bin_to_base64(MD5buf, (char *)sd->msg, 16); /* encode 16 bytes */ Dmsg2(400, "send inx=%d MD5=%s\n", jcr->JobFiles, MD5buf); bnet_fsend(dir, "%d %d %s *MD5-%d*", jcr->JobFiles, STREAM_MD5_SIGNATURE, MD5buf, jcr->JobFiles); Dmsg2(20, "bfiled>bdird: MD5 len=%d: msg=%s\n", dir->msglen, dir->msg); + break; - /* If SHA1 stream */ - } else if (stream == STREAM_SHA1_SIGNATURE) { + case STREAM_SHA1_SIGNATURE: char SHA1buf[30]; bin_to_base64(SHA1buf, (char *)sd->msg, 20); /* encode 20 bytes */ Dmsg2(400, "send inx=%d SHA1=%s\n", jcr->JobFiles, SHA1buf); bnet_fsend(dir, "%d %d %s *SHA1-%d*", jcr->JobFiles, STREAM_SHA1_SIGNATURE, SHA1buf, jcr->JobFiles); Dmsg2(20, "bfiled>bdird: SHA1 len=%d: msg=%s\n", dir->msglen, dir->msg); - } else { + break; + + default: Pmsg2(0, "None of above!!! stream=%d data=%s\n", stream,sd->msg); - } - } + break; + } /* end switch */ + } /* end while bnet_get */ set_jcr_job_status(jcr, JS_Terminated); goto ok_out; bail_out: set_jcr_job_status(jcr, JS_ErrorTerminated); + ok_out: if (jcr->compress_buf) { free(jcr->compress_buf); diff --git a/bacula/src/lib/Makefile.in b/bacula/src/lib/Makefile.in index e15e0af142..367b49e303 100644 --- a/bacula/src/lib/Makefile.in +++ b/bacula/src/lib/Makefile.in @@ -31,7 +31,7 @@ GMP_INC=@GMP_INC@ first_rule: all dummy: -LIBSRCS = alloc.c base64.c bmisc.c bget_msg.c \ +LIBSRCS = alloc.c base64.c bsys.c bget_msg.c \ bnet.c bnet_server.c \ bpipe.c bshm.c btime.c \ cram-md5.c crc32.c daemon.c edit.c fnmatch.c \ @@ -43,7 +43,7 @@ LIBSRCS = alloc.c base64.c bmisc.c bget_msg.c \ # immortal.c filesys.c -LIBOBJS = alloc.o base64.o bmisc.o bget_msg.o \ +LIBOBJS = alloc.o base64.o bsys.o bget_msg.o \ bnet.o bnet_server.o \ bpipe.o bshm.o btime.o \ cram-md5.o crc32.o daemon.o edit.o fnmatch.o \ diff --git a/bacula/src/lib/bsys.c b/bacula/src/lib/bsys.c new file mode 100644 index 0000000000..38b592f7eb --- /dev/null +++ b/bacula/src/lib/bsys.c @@ -0,0 +1,440 @@ +/* + * Miscellaneous Bacula memory and thread safe routines + * Generally, these are interfaces to system or standard + * library routines. + * + * Bacula utility functions are in util.c + * + * Version $Id$ + */ +/* + 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. + + */ + + +#include "bacula.h" +#ifdef HAVE_PWD_H +#include +#endif +#ifdef HAVE_GRP_H +#include +#endif + +/* + * Guarantee that the string is properly terminated */ +char *bstrncpy(char *dest, const char *src, int maxlen) +{ + strncpy(dest, src, maxlen-1); + dest[maxlen-1] = 0; + return dest; +} + +char *bstrncat(char *dest, const char *src, int maxlen) +{ + strncat(dest, src, maxlen-1); + dest[maxlen-1] = 0; + return dest; +} + + +#ifndef DEBUG +void *bmalloc(size_t size) +{ + void *buf; + + buf = malloc(size); + if (buf == NULL) { + Emsg1(M_ABORT, 0, _("Out of memory: ERR=%s\n"), strerror(errno)); + } + return buf; +} +#endif + +void *b_malloc(char *file, int line, size_t size) +{ + void *buf; + +#ifdef SMARTALLOC + buf = sm_malloc(file, line, size); +#else + buf = malloc(size); +#endif + if (buf == NULL) { + e_msg(file, line, M_ABORT, 0, _("Out of memory: ERR=%s\n"), strerror(errno)); + } + return buf; +} + + +void *brealloc (void *buf, size_t size) +{ + buf = realloc(buf, size); + if (buf == NULL) { + Emsg1(M_ABORT, 0, _("Out of memory: ERR=%s\n"), strerror(errno)); + } + return buf; +} + + +void *bcalloc (size_t size1, size_t size2) +{ + void *buf; + + buf = calloc(size1, size2); + if (buf == NULL) { + Emsg1(M_ABORT, 0, _("Out of memory: ERR=%s\n"), strerror(errno)); + } + return buf; +} + + +#define BIG_BUF 5000 +/* + * Implement snprintf + */ +int bsnprintf(char *str, size_t size, const char *fmt, ...) +{ +#ifdef HAVE_VSNPRINTF + va_list arg_ptr; + int len; + + va_start(arg_ptr, fmt); + len = vsnprintf(str, size, fmt, arg_ptr); + va_end(arg_ptr); + str[size-1] = 0; + return len; + +#else + + va_list arg_ptr; + int len; + char *buf; + + buf = get_memory(BIG_BUF); + va_start(arg_ptr, fmt); + len = vsprintf(buf, fmt, arg_ptr); + va_end(arg_ptr); + if (len >= BIG_BUF) { + Emsg0(M_ABORT, 0, _("Buffer overflow.\n")); + } + memcpy(str, buf, size); + str[size-1] = 0; + free_memory(buf); + return len; +#endif +} + +/* + * Implement vsnprintf() + */ +int bvsnprintf(char *str, size_t size, const char *format, va_list ap) +{ +#ifdef HAVE_VSNPRINTF + int len; + len = vsnprintf(str, size, format, ap); + str[size-1] = 0; + return len; + +#else + + int len; + char *buf; + buf = get_memory(BIG_BUF); + len = vsprintf(buf, format, ap); + if (len >= BIG_BUF) { + Emsg0(M_ABORT, 0, _("Buffer overflow.\n")); + } + memcpy(str, buf, size); + str[size-1] = 0; + free_memory(buf); + return len; +#endif +} + +#ifndef HAVE_LOCALTIME_R + +struct tm *localtime_r(const time_t *timep, struct tm *tm) +{ + static pthread_mutex_t mutex; + static int first = 1; + struct tm *ltm; + + if (first) { + pthread_mutex_init(&mutex, NULL); + first = 0; + } + P(mutex); + ltm = localtime(timep); + if (ltm) { + memcpy(tm, ltm, sizeof(struct tm)); + } + V(mutex); + return ltm ? tm : NULL; +} +#endif /* HAVE_LOCALTIME_R */ + +#ifndef HAVE_READDIR_R + +#include + +int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result) +{ + static pthread_mutex_t mutex; + static int first = 1; + struct dirent *ndir; + int stat; + + if (first) { + pthread_mutex_init(&mutex, NULL); + first = 0; + } + P(mutex); + errno = 0; + ndir = readdir(dirp); + stat = errno; + if (ndir) { + memcpy(entry, ndir, sizeof(struct dirent)); + strcpy(entry->d_name, ndir->d_name); + *result = entry; + } else { + *result = NULL; + } + V(mutex); + return stat; +} + +#endif /* HAVE_READDIR_R */ + +#ifdef xxxxxxxxxx_STRERROR_R +int strerror_r(int errnum, char *buf, size_t bufsiz) +{ + static pthread_mutex_t mutex; + static int first = 1; + int stat = 0; + char *msg; + + if (first) { + pthread_mutex_init(&mutex, NULL); + first = 0; + } + P(mutex); + + msg = strerror(errnum); + if (!msg) { + msg = _("Bad errno"); + stat = -1; + } + bstrncpy(buf, msg, bufsiz); + V(mutex); + return stat; +} +#endif /* HAVE_STRERROR_R */ + +/* + * These are mutex routines that do error checking + * for deadlock and such. Normally not turned on. + */ +#ifdef DEBUG_MUTEX +void _p(char *file, int line, pthread_mutex_t *m) +{ + int errstat; + if ((errstat = pthread_mutex_trylock(m))) { + e_msg(file, line, M_ERROR, 0, _("Possible mutex deadlock.\n")); + /* We didn't get the lock, so do it definitely now */ + if ((errstat=pthread_mutex_lock(m))) { + e_msg(file, line, M_ABORT, 0, _("Mutex lock failure. ERR=%s\n"), + strerror(errstat)); + } else { + e_msg(file, line, M_ERROR, 0, _("Possible mutex deadlock resolved.\n")); + } + + } +} + +void _v(char *file, int line, pthread_mutex_t *m) +{ + int errstat; + + if ((errstat=pthread_mutex_trylock(m)) == 0) { + e_msg(file, line, M_ERROR, 0, _("Mutex unlock not locked. ERR=%s\n"), + strerror(errstat)); + } + if ((errstat=pthread_mutex_unlock(m))) { + e_msg(file, line, M_ABORT, 0, _("Mutex unlock failure. ERR=%s\n"), + strerror(errstat)); + } +} +#endif /* DEBUG_MUTEX */ + +#ifndef HAVE_CYGWIN +static int del_pid_file_ok = FALSE; +#endif + +/* + * Create a standard "Unix" pid file. + */ +void create_pid_file(char *dir, char *progname, int port) +{ +#ifndef HAVE_CYGWIN + int pidfd, len; + int oldpid; + char pidbuf[20]; + POOLMEM *fname = get_pool_memory(PM_FNAME); + struct stat statp; + + Mmsg(&fname, "%s/%s.%d.pid", dir, progname, port); + if (stat(fname, &statp) == 0) { + /* File exists, see what we have */ + *pidbuf = 0; + if ((pidfd = open(fname, O_RDONLY)) < 0 || + read(pidfd, &pidbuf, sizeof(pidbuf)) < 0 || + sscanf(pidbuf, "%d", &oldpid) != 1) { + Emsg2(M_ERROR_TERM, 0, _("Cannot open pid file. %s ERR=%s\n"), fname, strerror(errno)); + } + /* See if other Bacula is still alive */ + if (kill(oldpid, 0) != -1 || errno != ESRCH) { + Emsg3(M_ERROR_TERM, 0, _("%s is already running. pid=%d\nCheck file %s\n"), + progname, oldpid, fname); + } + /* He is not alive, so take over file ownership */ + unlink(fname); /* remove stale pid file */ + } + /* Create new pid file */ + if ((pidfd = open(fname, O_CREAT | O_TRUNC | O_WRONLY, 0644)) >= 0) { + len = sprintf(pidbuf, "%d\n", (int)getpid()); + write(pidfd, pidbuf, len); + close(pidfd); + del_pid_file_ok = TRUE; /* we created it so we can delete it */ + } else { + Emsg2(M_ERROR_TERM, 0, _("Could not open pid file. %s ERR=%s\n"), fname, strerror(errno)); + } + free_pool_memory(fname); +#endif +} + +/* + * Delete the pid file if we created it + */ +int delete_pid_file(char *dir, char *progname, int port) +{ +#ifndef HAVE_CYGWIN + POOLMEM *fname = get_pool_memory(PM_FNAME); + + if (!del_pid_file_ok) { + free_pool_memory(fname); + return 0; + } + del_pid_file_ok = FALSE; + Mmsg(&fname, "%s/%s.%d.pid", dir, progname, port); + unlink(fname); + free_pool_memory(fname); +#endif + return 1; +} + +/* + * Drop to privilege new userid and new gid if non-NULL + */ +void drop(char *uid, char *gid) +{ +#ifdef HAVE_GRP_H + if (gid) { + struct group *group; + gid_t gr_list[1]; + + if ((group = getgrnam(gid)) == NULL) { + Emsg1(M_ERROR_TERM, 0, _("Could not find specified group: %s\n"), gid); + } + if (setgid(group->gr_gid)) { + Emsg1(M_ERROR_TERM, 0, _("Could not set specified group: %s\n"), gid); + } + gr_list[0] = group->gr_gid; + if (setgroups(1, gr_list)) { + Emsg1(M_ERROR_TERM, 0, _("Could not set specified group: %s\n"), gid); + } + } +#endif + +#ifdef HAVE_PWD_H + if (uid) { + struct passwd *passw; + if ((passw = getpwnam(uid)) == NULL) { + Emsg1(M_ERROR_TERM, 0, _("Could not find specified userid: %s\n"), uid); + } + if (setuid(passw->pw_uid)) { + Emsg1(M_ERROR_TERM, 0, _("Could not set specified userid: %s\n"), uid); + } + } +#endif + +} + +static pthread_mutex_t timer_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t timer = PTHREAD_COND_INITIALIZER; + +/* + * This routine will sleep (sec, msec). Note, however, that if a + * signal occurs, it will return early. It is up to the caller + * to recall this routine if he/she REALLY wants to sleep the + * requested time. + */ +int bmicrosleep(time_t sec, long msec) +{ + struct timespec timeout; + struct timeval tv; + struct timezone tz; + int stat; + + timeout.tv_sec = sec; + timeout.tv_nsec = msec * 1000; + +#ifdef HAVE_NANOSLEEP + stat = nanosleep(&timeout, NULL); + if (!(stat < 0 && errno == ENOSYS)) { + return stat; + } + /* If we reach here it is because nanosleep is not supported by the OS */ +#endif + + /* Do it the old way */ + gettimeofday(&tv, &tz); + timeout.tv_nsec += tv.tv_usec * 1000; + timeout.tv_sec += tv.tv_sec; + while (timeout.tv_nsec >= 1000000000) { + timeout.tv_nsec -= 1000000000; + timeout.tv_sec++; + } + + Dmsg1(200, "pthread_cond_timedwait sec=%d\n", timeout.tv_sec); + /* Note, this unlocks mutex during the sleep */ + P(timer_mutex); + stat = pthread_cond_timedwait(&timer, &timer_mutex, &timeout); + Dmsg1(200, "pthread_cond_timedwait stat=%d\n", stat); + V(timer_mutex); + return stat; +} + +/* BSDI does not have this. This is a *poor* simulation */ +#ifndef HAVE_STRTOLL +long long int +strtoll(const char *ptr, char **endptr, int base) +{ + return (long long int)strtod(ptr, endptr); +} +#endif diff --git a/bacula/src/lib/message.c b/bacula/src/lib/message.c index e47b407b8c..83283a52ce 100755 --- a/bacula/src/lib/message.c +++ b/bacula/src/lib/message.c @@ -920,7 +920,6 @@ Jmsg(void *vjcr, int type, int level, char *fmt,...) len = sprintf(rbuf, "%s: %s Fatal error: ", my_name, job); if (jcr) { set_jcr_job_status(jcr, JS_FatalError); - jcr->Errors++; } break; case M_ERROR: diff --git a/bacula/src/lib/parse_conf.c b/bacula/src/lib/parse_conf.c index f638764078..6a13469ded 100755 --- a/bacula/src/lib/parse_conf.c +++ b/bacula/src/lib/parse_conf.c @@ -368,7 +368,7 @@ void store_dir(LEX *lc, struct res_items *item, int index, int pass) lex_get_token(lc, T_STRING); if (pass == 1) { if (lc->str[0] != '|') { - do_shell_expansion(lc->str); + do_shell_expansion(lc->str, sizeof(lc->str)); } *(item->value) = bstrdup(lc->str); } diff --git a/bacula/src/lib/protos.h b/bacula/src/lib/protos.h index e8224b2d8b..24a617e77c 100644 --- a/bacula/src/lib/protos.h +++ b/bacula/src/lib/protos.h @@ -24,146 +24,146 @@ */ /* base64.c */ -void base64_init (void); -int to_base64 (intmax_t value, char *where); -int from_base64 (intmax_t *value, char *where); -int bin_to_base64 (char *buf, char *bin, int len); +void base64_init (void); +int to_base64 (intmax_t value, char *where); +int from_base64 (intmax_t *value, char *where); +int bin_to_base64 (char *buf, char *bin, int len); /* bmisc.c */ -char *bstrncpy (char *dest, const char *src, int maxlen); -char *bstrncat (char *dest, const char *src, int maxlen); -void *b_malloc (char *file, int line, size_t size); +char *bstrncpy (char *dest, const char *src, int maxlen); +char *bstrncat (char *dest, const char *src, int maxlen); +void *b_malloc (char *file, int line, size_t size); #ifndef DEBUG -void *bmalloc (size_t size); +void *bmalloc (size_t size); #endif -void *brealloc (void *buf, size_t size); -void *bcalloc (size_t size1, size_t size2); -int bsnprintf (char *str, size_t size, const char *format, ...); -int bvsnprintf (char *str, size_t size, const char *format, va_list ap); -int pool_sprintf (char *pool_buf, char *fmt, ...); -void create_pid_file (char *dir, char *progname, int port); -int delete_pid_file (char *dir, char *progname, int port); -void drop (char *uid, char *gid); -int bmicrosleep (time_t sec, long msec); +void *brealloc (void *buf, size_t size); +void *bcalloc (size_t size1, size_t size2); +int bsnprintf (char *str, size_t size, const char *format, ...); +int bvsnprintf (char *str, size_t size, const char *format, va_list ap); +int pool_sprintf (char *pool_buf, char *fmt, ...); +void create_pid_file (char *dir, char *progname, int port); +int delete_pid_file (char *dir, char *progname, int port); +void drop (char *uid, char *gid); +int bmicrosleep (time_t sec, long msec); #ifndef HAVE_STRTOLL long long int strtoll(const char *ptr, char **endptr, int base); #endif /* bnet.c */ -int32_t bnet_recv (BSOCK *bsock); -int bnet_send (BSOCK *bsock); -int bnet_fsend (BSOCK *bs, char *fmt, ...); -int bnet_set_buffer_size (BSOCK *bs, uint32_t size, int rw); -int bnet_sig (BSOCK *bs, int sig); -int bnet_ssl_server (BSOCK *bsock, char *password, int ssl_need, int ssl_has); -int bnet_ssl_client (BSOCK *bsock, char *password, int ssl_need); -BSOCK * bnet_connect (void *jcr, int retry_interval, - int max_retry_time, char *name, char *host, char *service, - int port, int verbose); -void bnet_close (BSOCK *bsock); -BSOCK * init_bsock (void *jcr, int sockfd, char *who, char *ip, int port); -BSOCK * dup_bsock (BSOCK *bsock); -void term_bsock (BSOCK *bsock); -char * bnet_strerror (BSOCK *bsock); -char * bnet_sig_to_ascii (BSOCK *bsock); -int bnet_wait_data (BSOCK *bsock, int sec); -int bnet_wait_data_intr (BSOCK *bsock, int sec); -int bnet_despool (BSOCK *bsock); -int is_bnet_stop (BSOCK *bsock); -int is_bnet_error (BSOCK *bsock); -void bnet_suppress_error_messages(BSOCK *bsock, int flag); +int32_t bnet_recv (BSOCK *bsock); +int bnet_send (BSOCK *bsock); +int bnet_fsend (BSOCK *bs, char *fmt, ...); +int bnet_set_buffer_size (BSOCK *bs, uint32_t size, int rw); +int bnet_sig (BSOCK *bs, int sig); +int bnet_ssl_server (BSOCK *bsock, char *password, int ssl_need, int ssl_has); +int bnet_ssl_client (BSOCK *bsock, char *password, int ssl_need); +BSOCK * bnet_connect (void *jcr, int retry_interval, + int max_retry_time, char *name, char *host, char *service, + int port, int verbose); +void bnet_close (BSOCK *bsock); +BSOCK * init_bsock (void *jcr, int sockfd, char *who, char *ip, int port); +BSOCK * dup_bsock (BSOCK *bsock); +void term_bsock (BSOCK *bsock); +char * bnet_strerror (BSOCK *bsock); +char * bnet_sig_to_ascii (BSOCK *bsock); +int bnet_wait_data (BSOCK *bsock, int sec); +int bnet_wait_data_intr (BSOCK *bsock, int sec); +int bnet_despool (BSOCK *bsock); +int is_bnet_stop (BSOCK *bsock); +int is_bnet_error (BSOCK *bsock); +void bnet_suppress_error_messages(BSOCK *bsock, int flag); /* bget_msg.c */ -int bget_msg(BSOCK *sock); +int bget_msg(BSOCK *sock); /* cram-md5.c */ int cram_md5_get_auth(BSOCK *bs, char *password, int ssl_need); int cram_md5_auth(BSOCK *bs, char *password, int ssl_need); void hmac_md5(uint8_t* text, int text_len, uint8_t* key, - int key_len, uint8_t *hmac); + int key_len, uint8_t *hmac); /* crc32.c */ uint32_t bcrc32(uint8_t *buf, int len); /* daemon.c */ -void daemon_start (); +void daemon_start (); /* edit.c */ -uint64_t str_to_uint64(char *str); -int64_t str_to_int64(char *str); -char * edit_uint64_with_commas (uint64_t val, char *buf); -char * add_commas (char *val, char *buf); -char * edit_uint64 (uint64_t val, char *buf); -int duration_to_utime (char *str, utime_t *value); -int size_to_uint64(char *str, int str_len, uint64_t *rtn_value); -char *edit_utime (utime_t val, char *buf); -int is_a_number (const char *num); -int is_an_integer (const char *n); +uint64_t str_to_uint64(char *str); +int64_t str_to_int64(char *str); +char * edit_uint64_with_commas (uint64_t val, char *buf); +char * add_commas (char *val, char *buf); +char * edit_uint64 (uint64_t val, char *buf); +int duration_to_utime (char *str, utime_t *value); +int size_to_uint64(char *str, int str_len, uint64_t *rtn_value); +char *edit_utime (utime_t val, char *buf); +int is_a_number (const char *num); +int is_an_integer (const char *n); /* lex.c */ -LEX * lex_close_file (LEX *lf); -LEX * lex_open_file (LEX *lf, char *fname, LEX_ERROR_HANDLER *scan_error); -int lex_get_char (LEX *lf); -void lex_unget_char (LEX *lf); -char * lex_tok_to_str (int token); -int lex_get_token (LEX *lf, int expect); +LEX * lex_close_file (LEX *lf); +LEX * lex_open_file (LEX *lf, char *fname, LEX_ERROR_HANDLER *scan_error); +int lex_get_char (LEX *lf); +void lex_unget_char (LEX *lf); +char * lex_tok_to_str (int token); +int lex_get_token (LEX *lf, int expect); /* message.c */ -void my_name_is (int argc, char *argv[], char *name); -void init_msg (void *jcr, MSGS *msg); -void term_msg (void); -void close_msg (void *jcr); -void add_msg_dest (MSGS *msg, int dest, int type, char *where, char *dest_code); -void rem_msg_dest (MSGS *msg, int dest, int type, char *where); -void Jmsg (void *jcr, int type, int level, char *fmt, ...); -void dispatch_message (void *jcr, int type, int level, char *buf); -void init_console_msg (char *wd); -void free_msgs_res (MSGS *msgs); -int open_spool_file (void *jcr, BSOCK *bs); -int close_spool_file (void *vjcr, BSOCK *bs); +void my_name_is (int argc, char *argv[], char *name); +void init_msg (void *jcr, MSGS *msg); +void term_msg (void); +void close_msg (void *jcr); +void add_msg_dest (MSGS *msg, int dest, int type, char *where, char *dest_code); +void rem_msg_dest (MSGS *msg, int dest, int type, char *where); +void Jmsg (void *jcr, int type, int level, char *fmt, ...); +void dispatch_message (void *jcr, int type, int level, char *buf); +void init_console_msg (char *wd); +void free_msgs_res (MSGS *msgs); +int open_spool_file (void *jcr, BSOCK *bs); +int close_spool_file (void *vjcr, BSOCK *bs); /* bnet_server.c */ -void bnet_thread_server(char *bind_addr, int port, int max_clients, workq_t *client_wq, - void *handle_client_request(void *bsock)); -void bnet_server (int port, void handle_client_request(BSOCK *bsock)); -int net_connect (int port); -BSOCK * bnet_bind (int port); -BSOCK * bnet_accept (BSOCK *bsock, char *who); +void bnet_thread_server(char *bind_addr, int port, int max_clients, workq_t *client_wq, + void *handle_client_request(void *bsock)); +void bnet_server (int port, void handle_client_request(BSOCK *bsock)); +int net_connect (int port); +BSOCK * bnet_bind (int port); +BSOCK * bnet_accept (BSOCK *bsock, char *who); /* signal.c */ -void init_signals (void terminate(int sig)); -void init_stack_dump (void); +void init_signals (void terminate(int sig)); +void init_stack_dump (void); /* util.c */ -void lcase (char *str); -void bash_spaces (char *str); -void unbash_spaces (char *str); -void strip_trailing_junk (char *str); -void strip_trailing_slashes (char *dir); -int skip_spaces (char **msg); -int skip_nonspaces (char **msg); -int fstrsch (char *a, char *b); -char * encode_time (time_t time, char *buf); -char * encode_mode (mode_t mode, char *buf); -int do_shell_expansion (char *name); -int is_buf_zero (char *buf, int len); -void jobstatus_to_ascii (int JobStatus, char *msg, int maxlen); -void pm_strcat (POOLMEM **pm, char *str); -void pm_strcpy (POOLMEM **pm, char *str); -int run_program (char *prog, int wait, POOLMEM *results); -char * job_type_to_str (int type); -char * job_status_to_str (int stat); -char * job_level_to_str (int level); -void makeSessionKey (char *key, char *seed, int mode); -BPIPE * open_bpipe(char *prog, int wait, char *mode); -int close_wpipe(BPIPE *bpipe); -int close_bpipe(BPIPE *bpipe); -POOLMEM *edit_job_codes(void *jcr, char *omsg, char *imsg, char *to); -void parse_command_args(POOLMEM *cmd, POOLMEM *args, int *argc, - char **argk, char **argv); -char *next_arg(char **s); - +void lcase (char *str); +void bash_spaces (char *str); +void unbash_spaces (char *str); +void strip_trailing_junk (char *str); +void strip_trailing_slashes (char *dir); +int skip_spaces (char **msg); +int skip_nonspaces (char **msg); +int fstrsch (char *a, char *b); +char * encode_time (time_t time, char *buf); +char * encode_mode (mode_t mode, char *buf); +int do_shell_expansion (char *name, int name_len); +int is_buf_zero (char *buf, int len); +void jobstatus_to_ascii (int JobStatus, char *msg, int maxlen); +void pm_strcat (POOLMEM **pm, char *str); +void pm_strcpy (POOLMEM **pm, char *str); +int run_program (char *prog, int wait, POOLMEM *results); +char * job_type_to_str (int type); +char * job_status_to_str (int stat); +char * job_level_to_str (int level); +void makeSessionKey (char *key, char *seed, int mode); +BPIPE * open_bpipe(char *prog, int wait, char *mode); +int close_wpipe(BPIPE *bpipe); +int close_bpipe(BPIPE *bpipe); +POOLMEM *edit_job_codes(void *jcr, char *omsg, char *imsg, char *to); +void parse_command_args(POOLMEM *cmd, POOLMEM *args, int *argc, + char **argk, char **argv); +char *next_arg(char **s); +void set_working_directory(char *wd); /* watchdog.c */ int start_watchdog(void); diff --git a/bacula/src/lib/util.c b/bacula/src/lib/util.c index 63a71911f4..b1e9e411a9 100644 --- a/bacula/src/lib/util.c +++ b/bacula/src/lib/util.c @@ -388,7 +388,7 @@ char *encode_mode(mode_t mode, char *buf) } -int do_shell_expansion(char *name) +int do_shell_expansion(char *name, int name_len) { /* ****FIXME***** this should work for Win32 too */ #define UNIX @@ -465,7 +465,10 @@ int do_shell_expansion(char *name) /* wait for child to exit */ while ((wpid = wait(&waitstatus)) != pid && wpid != -1) { ; } - strcpy(name, echout); + strip_trailing_junk(echout); + if (strlen(echout) > 0) { + bstrncpy(name, echout, name_len); + } stat = 1; break; } @@ -763,3 +766,21 @@ void parse_command_args(POOLMEM *cmd, POOLMEM *args, int *argc, } #endif } + +void set_working_directory(char *wd) +{ + struct stat stat_buf; + + if (wd == NULL) { + Emsg0(M_ERROR_TERM, 0, _("Working directory not defined. Cannot continue.\n")); + } + if (stat(wd, &stat_buf) != 0) { + Emsg1(M_ERROR_TERM, 0, _("Working Directory: \"%s\" not found. Cannot continue.\n"), + wd); + } + if (!S_ISDIR(stat_buf.st_mode)) { + Emsg1(M_ERROR_TERM, 0, _("Working Directory: \"%s\" is not a directory. Cannot continue.\n"), + wd); + } + working_directory = wd; /* set global */ +} diff --git a/bacula/src/stored/stored.c b/bacula/src/stored/stored.c index 37d69b540d..826b7fbd18 100644 --- a/bacula/src/stored/stored.c +++ b/bacula/src/stored/stored.c @@ -237,8 +237,6 @@ uint32_t newVolSessionId() /* Check Configuration file for necessary info */ static void check_config() { - struct stat stat_buf; - LockRes(); me = (STORES *)GetNextRes(R_STORAGE, NULL); if (!me) { @@ -280,15 +278,8 @@ static void check_config() Emsg1(M_ERROR_TERM, 0, _("No Working Directory defined in %s. Cannot continue.\n"), configfile); } - if (stat(me->working_directory, &stat_buf) != 0) { - Emsg1(M_ERROR_TERM, 0, _("Working Directory: %s not found. Cannot continue.\n"), - me->working_directory); - } - if (!S_ISDIR(stat_buf.st_mode)) { - Emsg1(M_ERROR_TERM, 0, _("Working Directory: %s is not a directory. Cannot continue.\n"), - me->working_directory); - } - working_directory = me->working_directory; + + set_working_directory(me->working_directory); } /* diff --git a/bacula/src/version.h b/bacula/src/version.h index 257a016be7..87157f7780 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -1,8 +1,8 @@ /* */ #define VERSION "1.31" #define VSTRING "1" -#define BDATE "20 May 2003" -#define LSMDATE "20May03" +#define BDATE "22 May 2003" +#define LSMDATE "22May03" /* Debug flags */ #define DEBUG 1