]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/lib/message.c
Add jobid to Pmsg output
[bacula/bacula] / bacula / src / lib / message.c
index 87f739f58f2a069c4352bae9c2b73c2000873ab5..53f72c98a33195847992e3fa152bfed5ae5c32db 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2000-2011 Free Software Foundation Europe e.V.
+   Copyright (C) 2000-2012 Free Software Foundation Europe e.V.
 
    The main author of Bacula is Kern Sibbald, with contributions from
    many others, a complete list can be found in the file AUTHORS.
@@ -57,7 +57,7 @@ bool prt_kaboom = false;              /* Print kaboom output */
 utime_t daemon_start_time = 0;        /* Daemon start time */
 const char *version = VERSION " (" BDATE ")";
 const char *dist_name = DISTNAME " " DISTVER;
-const int beef = BEEF;
+int beef = BEEF;
 char my_name[30] = {0};               /* daemon name is stored here */
 char host_name[50] = {0};             /* host machine name */
 char *exepath = (char *)NULL;
@@ -74,6 +74,9 @@ void create_jcr_key();
 
 /* Static storage */
 
+/* Exclude spaces but require .mail at end */
+#define MAIL_REGEX "^[^ ]+\\.mail$"
+
 /* Allow only one thread to tweak d->fd at a time */
 static pthread_mutex_t fides_mutex = PTHREAD_MUTEX_INITIALIZER;
 static MSGS *daemon_msgs;              /* global messages */
@@ -92,6 +95,24 @@ const char *host_os = HOST_OS;
 const char *distname = DISTNAME;
 const char *distver = DISTVER;
 
+/*
+ * Walk back in a string from end looking for a
+ *  path separator.  
+ *  This routine is passed the start of the string and
+ *  the end of the string, it returns either the beginning
+ *  of the string or where it found a path separator.
+ */
+static const char *bstrrpath(const char *start, const char *end)
+{
+   while ( end > start ) {
+      end--;   
+      if (IsPathSeparator(*end)) {
+         break;
+      }
+   }
+   return end;
+}
+
 /* Some message class methods */
 void MSGS::lock()
 {
@@ -109,7 +130,7 @@ void MSGS::unlock()
 void MSGS::wait_not_in_use()     /* leaves fides_mutex set */
 {
    lock();
-   while (m_in_use) {
+   while (m_in_use || m_closing) {
       unlock();
       bmicrosleep(0, 200);         /* wait */
       lock();
@@ -496,6 +517,11 @@ void close_msg(JCR *jcr)
       return;
    }
    msgs->wait_not_in_use();          /* leaves fides_mutex set */
+   /* Note get_closing() does not lock because we are already locked */
+   if (msgs->get_closing()) {
+      msgs->unlock();
+      return;
+   }
    msgs->set_closing();
    msgs->unlock();
 
@@ -518,20 +544,39 @@ void close_msg(JCR *jcr)
             if (!d->fd) {
                break;
             }
-            if (
-                (d->dest_code == MD_MAIL_ON_ERROR && jcr &&
-                  (jcr->JobStatus == JS_Terminated || jcr->JobStatus == JS_Warnings)) 
-                ||
-                (d->dest_code == MD_MAIL_ON_SUCCESS && jcr &&
-                 jcr->JobStatus == JS_ErrorTerminated)
-                ) {
-               goto rem_temp_file;
+
+            switch (d->dest_code) {
+            case MD_MAIL_ON_ERROR:
+               if (jcr) {
+                  switch (jcr->JobStatus) {
+                  case JS_Terminated:
+                  case JS_Warnings:
+                     goto rem_temp_file;
+                  default:
+                     break;
+                  }
+               }
+               break;
+            case MD_MAIL_ON_SUCCESS:
+               if (jcr) {
+                  switch (jcr->JobStatus) {
+                  case JS_Terminated:
+                  case JS_Warnings:
+                     break;
+                  default:
+                     goto rem_temp_file;
+                  }
+               }
+               break;
+            default:
+               break;
             }
 
             if (!(bpipe=open_mail_pipe(jcr, cmd, d))) {
                Pmsg0(000, _("open mail pipe failed.\n"));
                goto rem_temp_file;
             }
+
             Dmsg0(850, "Opened mail pipe\n");
             len = d->max_len+10;
             line = get_memory(len);
@@ -568,11 +613,16 @@ void close_msg(JCR *jcr)
             free_memory(line);
 rem_temp_file:
             /* Remove temp file */
-            fclose(d->fd);
-            d->fd = NULL;
-            unlink(d->mail_filename);
-            free_pool_memory(d->mail_filename);
-            d->mail_filename = NULL;
+            if (d->fd) {
+               fclose(d->fd);
+               d->fd = NULL;
+            }
+            if (d->mail_filename) {
+               /* Exclude spaces in mail_filename */
+               safer_unlink(d->mail_filename, MAIL_REGEX);
+               free_pool_memory(d->mail_filename);
+               d->mail_filename = NULL;
+            }
             Dmsg0(850, "end mail or mail on error\n");
             break;
          default:
@@ -665,6 +715,28 @@ static bool open_dest_file(JCR *jcr, DEST *d, const char *mode)
    return true;
 }
 
+/* Split the output for syslog (it converts \n to ' ' and is
+ *   limited to 1024 characters per syslog message
+ */
+static void send_to_syslog(int mode, const char *msg)
+{
+   int len;
+   char buf[1024];
+   const char *p2;
+   const char *p = msg;
+
+   while (*p && ((p2 = strchr(p, '\n')) != NULL)) {
+      len = MIN((int)sizeof(buf) - 1, p2 - p + 1); /* Add 1 to keep \n */
+      strncpy(buf, p, len);
+      buf[len] = 0;
+      syslog(mode, "%s", buf);
+      p = p2+1;                 /* skip \n */
+   }
+   if (*p != 0) {               /* no \n at the end ? */
+      syslog(mode, "%s", p);
+   }
+}
+
 /*
  * Handle sending the message to the appropriate place
  */
@@ -753,13 +825,17 @@ void dispatch_message(JCR *jcr, int type, utime_t mtime, char *msg)
                    POOLMEM *esc_msg = get_pool_memory(PM_MESSAGE);
                    
                    int len = strlen(msg) + 1;
-                   esc_msg = check_pool_memory_size(esc_msg, len*2+1);
-                   p_sql_escape(jcr, jcr->db, esc_msg, msg, len);
-
-                   bstrutime(dt, sizeof(dt), mtime);
-                   Mmsg(cmd, "INSERT INTO Log (JobId, Time, LogText) VALUES (%s,'%s','%s')",
-                         edit_int64(jcr->JobId, ed1), dt, esc_msg);
-                   p_sql_query(jcr, cmd);
+                   esc_msg = check_pool_memory_size(esc_msg, len * 2 + 1);
+                   if (p_sql_escape(jcr, jcr->db, esc_msg, msg, len)) {
+                      bstrutime(dt, sizeof(dt), mtime);
+                      Mmsg(cmd, "INSERT INTO Log (JobId, Time, LogText) VALUES (%s,'%s','%s')",
+                            edit_int64(jcr->JobId, ed1), dt, esc_msg);
+                      if (!p_sql_query(jcr, cmd)) {
+                         delivery_error(_("Msg delivery error: Unable to store data in database.\n"));
+                      }
+                   } else {
+                      delivery_error(_("Msg delivery error: Unable to store data in database.\n"));
+                   }
                    
                    free_pool_memory(cmd);
                    free_pool_memory(esc_msg);
@@ -796,7 +872,7 @@ void dispatch_message(JCR *jcr, int type, utime_t mtime, char *msg)
                 /*
                  * We really should do an openlog() here.
                  */
-                syslog(LOG_DAEMON|LOG_ERR, "%s", msg);
+                send_to_syslog(LOG_DAEMON|LOG_ERR, msg);
                 break;
              case MD_OPERATOR:
                 Dmsg1(850, "OPERATOR for following msg: %s\n", msg);
@@ -834,7 +910,7 @@ void dispatch_message(JCR *jcr, int type, utime_t mtime, char *msg)
                       delivery_error(_("Msg delivery error: fopen %s failed: ERR=%s\n"), name,
                             be.bstrerror());
                       free_pool_memory(name);
-                      V(fides_mutex);
+                      msgs->clear_in_use();
                       break;
                    }
                    d->mail_filename = name;
@@ -913,20 +989,17 @@ send_to_file:
  *  to the full path.  Try to return base + next higher path.
  */
 
-const char *
-get_basename(const char *pathname)
+const char *get_basename(const char *pathname)
 {
-   const char *basename, *basename2;
+   const char *basename;
    
-   if ((basename = strrchr(pathname, PathSeparator)) == NULL) {
-      basename = pathname;
-      if ((basename2 = strrchr(pathname, PathSeparator)) != NULL) {
-         basename = basename2 + 1;
-      }
+   if ((basename = bstrrpath(pathname, pathname+strlen(pathname))) == pathname) {
+      /* empty */
+   } else if ((basename = bstrrpath(pathname, basename-1)) == pathname) {
+      /* empty */
    } else {
       basename++;
    }
-
    return basename;
 }
 
@@ -990,7 +1063,7 @@ d_msg(const char *file, int line, int level, const char *fmt,...)
           len = strlen(buf);
           buf[len++] = ' ';
           buf[len] = 0;
-          fputs(buf, stdout);
+          pt_out(buf);
        }
     
 #ifdef FULL_LOCATION
@@ -1066,13 +1139,15 @@ p_msg(const char *file, int line, int level, const char *fmt,...)
 
 #ifdef FULL_LOCATION
     if (level >= 0) {
-       len = bsnprintf(buf, sizeof(buf), "%s: %s:%d ", my_name, get_basename(file), line);
+       len = bsnprintf(buf, sizeof(buf), "%s: %s:%d-%u ", 
+             my_name, get_basename(file), line, get_jobid_from_tsd());
     } else {
        len = 0;
     }
 #else
-    len = 0;
+       len = 0;
 #endif
+
     va_start(arg_ptr, fmt);
     bvsnprintf(buf+len, sizeof(buf)-len, (char *)fmt, arg_ptr);
     va_end(arg_ptr);
@@ -1270,7 +1345,7 @@ Jmsg(JCR *jcr, int type, utime_t mtime, const char *fmt,...)
     case M_FATAL:
        len = bsnprintf(rbuf, sizeof(rbuf), _("%s JobId %u: Fatal error: "), my_name, JobId);
        if (jcr) {
-          set_jcr_job_status(jcr, JS_FatalError);
+          jcr->setJobStatus(JS_FatalError);
        }
        if (jcr && jcr->JobErrors == 0) {
           jcr->JobErrors = 1;