]> git.sur5r.net Git - bacula/bacula/commitdiff
lib/bmisc.c -> bsys.c cleanup error status a bit + working directory checks
authorKern Sibbald <kern@sibbald.com>
Thu, 22 May 2003 09:03:38 +0000 (09:03 +0000)
committerKern Sibbald <kern@sibbald.com>
Thu, 22 May 2003 09:03:38 +0000 (09:03 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@530 91ce42f0-d328-0410-95d8-f526ca767f89

15 files changed:
bacula/kernstodo
bacula/src/dird/backup.c
bacula/src/dird/dird.c
bacula/src/filed/filed.c
bacula/src/filed/job.c
bacula/src/filed/verify.c
bacula/src/filed/verify_vol.c
bacula/src/lib/Makefile.in
bacula/src/lib/bsys.c [new file with mode: 0644]
bacula/src/lib/message.c
bacula/src/lib/parse_conf.c
bacula/src/lib/protos.h
bacula/src/lib/util.c
bacula/src/stored/stored.c
bacula/src/version.h

index d2b826139fe0d9a68fc79dc643be2b9357f169bc..2f86dc967ac0182bd606b64487dae03353289a97 100644 (file)
@@ -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.
-
index 7b746c0521c207adc0dd9de3548b8bc6941d0af5..277537a8569611a8c36f8eed97e1684da7a61406 100644 (file)
@@ -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;
index aafc5a72bf4a46d48f78f9a18594ad12cee25057..a0da2955fb14cdd347ae4b7842a7160a624d6ee9 100644 (file)
@@ -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) {
index 78b0de001dca7410b3e8220cb266a2ba8a3e1385..ac74fa27fb8332517bae597444dcd89f7151f793 100644 (file)
@@ -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);
index 131fca92ffb89d49c0275116d008c67ef9c308ed..a3bb4830346b4c80c196031e544b17fad8e0edc2 100644 (file)
@@ -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, "<stored: %s", sd->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, "<stored: %s", sd->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);
       }
    }
 
index 0c5faec85dc73dc9768457d0a42d6c97b801801f..211f62e9d7b6f93c049dbab13cf9b2f6c943f26b 100644 (file)
@@ -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);
index 4b9117f0b26ff7d8fabfc4eb68eb6541cd7b5bf6..839874e633b81ddffd394d30afe4804becd8b04c 100644 (file)
@@ -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);
index e15e0af142c20053e51d24be56749442e4624c6f..367b49e30354077b7a7dcd62f81e3472b2aa478f 100644 (file)
@@ -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 (file)
index 0000000..38b592f
--- /dev/null
@@ -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 <pwd.h>
+#endif
+#ifdef HAVE_GRP_H
+#include <grp.h>
+#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 <dirent.h>
+
+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
index e47b407b8c349ebf139ab77f7dc441e991162a5c..83283a52ceb97b92c526ccec8246aa56ab3ab713 100755 (executable)
@@ -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:
index f6387640785670eb0ab8b1c1319e46d208e01d8f..6a13469ded81ac30e95122d8c240590652965dc8 100755 (executable)
@@ -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);
    }
index e8224b2d8bf838ebce53f4df4a3cb9a4e1736c8f..24a617e77cefbfbf45443f2c1d33767be5803f4e 100644 (file)
  */
 
 /* 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);
index 63a71911f4ad3d2e941fee74cd9b1c4cdf53820a..b1e9e411a94cf307c152e409ac95390fa0996ac4 100644 (file)
@@ -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 */
+}
index 37d69b540d173d4384b9d41306dce83e4487ff2b..826b7fbd18b496758ea2ebe9d5cdb829109ee801 100644 (file)
@@ -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);
 }
 
 /*
index 257a016be70f095d56a0c47b845e798cef1c60bb..87157f7780d31266ed904bc0124d4c278ad1239a 100644 (file)
@@ -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