]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/message.c
Fix Qmsg race condition reported by Eric
[bacula/bacula] / bacula / src / lib / message.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2000-2009 Free Software Foundation Europe e.V.
5
6    The main author of Bacula is Kern Sibbald, with contributions from
7    many others, a complete list can be found in the file AUTHORS.
8    This program is Free Software; you can redistribute it and/or
9    modify it under the terms of version two of the GNU General Public
10    License as published by the Free Software Foundation and included
11    in the file LICENSE.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23    Bacula® is a registered trademark of Kern Sibbald.
24    The licensor of Bacula is the Free Software Foundation Europe
25    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26    Switzerland, email:ftf@fsfeurope.org.
27 */
28 /*
29  * Bacula message handling routines
30  *
31  *   Kern Sibbald, April 2000
32  *
33  */
34
35 #include "bacula.h"
36 #include "jcr.h"
37
38 sql_query p_sql_query = NULL;
39 sql_escape p_sql_escape = NULL;
40
41 #define FULL_LOCATION 1               /* set for file:line in Debug messages */
42
43 /*
44  *  This is where we define "Globals" because all the
45  *    daemons include this file.
46  */
47 const char *working_directory = NULL;       /* working directory path stored here */
48 int verbose = 0;                      /* increase User messages */
49 int debug_level = 0;                  /* debug level */
50 bool dbg_timestamp = false;           /* print timestamp in debug output */
51 utime_t daemon_start_time = 0;        /* Daemon start time */
52 const char *version = VERSION " (" BDATE ")";
53 char my_name[30];                     /* daemon name is stored here */
54 char host_name[50];                   /* host machine name */
55 char *exepath = (char *)NULL;
56 char *exename = (char *)NULL;
57 int console_msg_pending = false;
58 char con_fname[500];                  /* Console filename */
59 FILE *con_fd = NULL;                  /* Console file descriptor */
60 brwlock_t con_lock;                   /* Console lock structure */
61
62 /* Forward referenced functions */
63
64 /* Imported functions */
65 void create_jcr_key();
66
67 /* Static storage */
68
69 /* Allow only one thread to tweak d->fd at a time */
70 static pthread_mutex_t fides_mutex = PTHREAD_MUTEX_INITIALIZER;
71 static MSGS *daemon_msgs;              /* global messages */
72 static char *catalog_db = NULL;       /* database type */
73 static void (*message_callback)(int type, char *msg) = NULL;
74 static FILE *trace_fd = NULL;
75 #if defined(HAVE_WIN32)
76 static bool trace = true;
77 #else
78 static bool trace = false;
79 #endif
80
81 /* Constants */
82 const char *host_os = HOST_OS;
83 const char *distname = DISTNAME;
84 const char *distver = DISTVER;
85
86
87 void register_message_callback(void msg_callback(int type, char *msg))
88 {
89    message_callback = msg_callback;
90 }
91
92
93 /*
94  * Set daemon name. Also, find canonical execution
95  *  path.  Note, exepath has spare room for tacking on
96  *  the exename so that we can reconstruct the full name.
97  *
98  * Note, this routine can get called multiple times
99  *  The second time is to put the name as found in the
100  *  Resource record. On the second call, generally,
101  *  argv is NULL to avoid doing the path code twice.
102  */
103 void my_name_is(int argc, char *argv[], const char *name)
104 {
105    char *l, *p, *q;
106    char cpath[1024];
107    int len;
108
109    if (gethostname(host_name, sizeof(host_name)) != 0) {
110       bstrncpy(host_name, "Hostname unknown", sizeof(host_name));
111    }
112    bstrncpy(my_name, name, sizeof(my_name));
113    if (argc>0 && argv && argv[0]) {
114       /* strip trailing filename and save exepath */
115       for (l=p=argv[0]; *p; p++) {
116          if (IsPathSeparator(*p)) {
117             l = p;                       /* set pos of last slash */
118          }
119       }
120       if (IsPathSeparator(*l)) {
121          l++;
122       } else {
123          l = argv[0];
124 #if defined(HAVE_WIN32)
125          /* On Windows allow c: junk */
126          if (l[1] == ':') {
127             l += 2;
128          }
129 #endif
130       }
131       len = strlen(l) + 1;
132       if (exename) {
133          free(exename);
134       }
135       exename = (char *)malloc(len);
136       strcpy(exename, l);
137
138       if (exepath) {
139          free(exepath);
140       }
141       exepath = (char *)malloc(strlen(argv[0]) + 1 + len);
142       for (p=argv[0],q=exepath; p < l; ) {
143          *q++ = *p++;
144       }
145       *q = 0;
146       if (strchr(exepath, '.') || !IsPathSeparator(exepath[0])) {
147          if (getcwd(cpath, sizeof(cpath))) {
148             free(exepath);
149             exepath = (char *)malloc(strlen(cpath) + 1 + len);
150             strcpy(exepath, cpath);
151          }
152       }
153       Dmsg2(500, "exepath=%s\nexename=%s\n", exepath, exename);
154    }
155 }
156
157 const char *
158 get_db_type(void)
159 {
160    return catalog_db != NULL ? catalog_db : "unknown";
161 }
162
163 void
164 set_db_type(const char *name)
165 {
166    if (catalog_db != NULL) {
167       free(catalog_db);
168    }
169    catalog_db = bstrdup(name);
170 }
171
172 /*
173  * Initialize message handler for a daemon or a Job
174  *   We make a copy of the MSGS resource passed, so it belows
175  *   to the job or daemon and thus can be modified.
176  *
177  *   NULL for jcr -> initialize global messages for daemon
178  *   non-NULL     -> initialize jcr using Message resource
179  */
180 void
181 init_msg(JCR *jcr, MSGS *msg)
182 {
183    DEST *d, *dnew, *temp_chain = NULL;
184    int i;
185
186    if (jcr == NULL && msg == NULL) {
187       init_last_jobs_list();
188       /* Create a daemon key then set invalid jcr */
189       /* Maybe we should give the daemon a jcr??? */
190       create_jcr_key();
191       set_jcr_in_tsd(INVALID_JCR);
192    }
193
194 #if !defined(HAVE_WIN32)
195    /*
196     * Make sure we have fd's 0, 1, 2 open
197     *  If we don't do this one of our sockets may open
198     *  there and if we then use stdout, it could
199     *  send total garbage to our socket.
200     *
201     */
202    int fd;
203    fd = open("/dev/null", O_RDONLY, 0644);
204    if (fd > 2) {
205       close(fd);
206    } else {
207       for(i=1; fd + i <= 2; i++) {
208          dup2(fd, fd+i);
209       }
210    }
211
212 #endif
213    /*
214     * If msg is NULL, initialize global chain for STDOUT and syslog
215     */
216    if (msg == NULL) {
217       daemon_msgs = (MSGS *)malloc(sizeof(MSGS));
218       memset(daemon_msgs, 0, sizeof(MSGS));
219       for (i=1; i<=M_MAX; i++) {
220          add_msg_dest(daemon_msgs, MD_STDOUT, i, NULL, NULL);
221       }
222       Dmsg1(050, "Create daemon global message resource %p\n", daemon_msgs);
223       return;
224    }
225
226    /*
227     * Walk down the message resource chain duplicating it
228     * for the current Job.
229     */
230    for (d=msg->dest_chain; d; d=d->next) {
231       dnew = (DEST *)malloc(sizeof(DEST));
232       memcpy(dnew, d, sizeof(DEST));
233       dnew->next = temp_chain;
234       dnew->fd = NULL;
235       dnew->mail_filename = NULL;
236       if (d->mail_cmd) {
237          dnew->mail_cmd = bstrdup(d->mail_cmd);
238       }
239       if (d->where) {
240          dnew->where = bstrdup(d->where);
241       }
242       temp_chain = dnew;
243    }
244
245    if (jcr) {
246       jcr->jcr_msgs = (MSGS *)malloc(sizeof(MSGS));
247       memset(jcr->jcr_msgs, 0, sizeof(MSGS));
248       jcr->jcr_msgs->dest_chain = temp_chain;
249       memcpy(jcr->jcr_msgs->send_msg, msg->send_msg, sizeof(msg->send_msg));
250    } else {
251       /* If we have default values, release them now */
252       if (daemon_msgs) {
253          free_msgs_res(daemon_msgs);
254       }
255       daemon_msgs = (MSGS *)malloc(sizeof(MSGS));
256       memset(daemon_msgs, 0, sizeof(MSGS));
257       daemon_msgs->dest_chain = temp_chain;
258       memcpy(daemon_msgs->send_msg, msg->send_msg, sizeof(msg->send_msg));
259    }
260    Dmsg2(250, "Copy message resource %p to %p\n", msg, temp_chain);
261
262 }
263
264 /* Initialize so that the console (User Agent) can
265  * receive messages -- stored in a file.
266  */
267 void init_console_msg(const char *wd)
268 {
269    int fd;
270
271    bsnprintf(con_fname, sizeof(con_fname), "%s%c%s.conmsg", wd, PathSeparator, my_name);
272    fd = open(con_fname, O_CREAT|O_RDWR|O_BINARY, 0600);
273    if (fd == -1) {
274       berrno be;
275       Emsg2(M_ERROR_TERM, 0, _("Could not open console message file %s: ERR=%s\n"),
276           con_fname, be.bstrerror());
277    }
278    if (lseek(fd, 0, SEEK_END) > 0) {
279       console_msg_pending = 1;
280    }
281    close(fd);
282    con_fd = fopen(con_fname, "a+b");
283    if (!con_fd) {
284       berrno be;
285       Emsg2(M_ERROR, 0, _("Could not open console message file %s: ERR=%s\n"),
286           con_fname, be.bstrerror());
287    }
288    if (rwl_init(&con_lock) != 0) {
289       berrno be;
290       Emsg1(M_ERROR_TERM, 0, _("Could not get con mutex: ERR=%s\n"),
291          be.bstrerror());
292    }
293 }
294
295 /*
296  * Called only during parsing of the config file.
297  *
298  * Add a message destination. I.e. associate a message type with
299  *  a destination (code).
300  * Note, where in the case of dest_code FILE is a filename,
301  *  but in the case of MAIL is a space separated list of
302  *  email addresses, ...
303  */
304 void add_msg_dest(MSGS *msg, int dest_code, int msg_type, char *where, char *mail_cmd)
305 {
306    DEST *d;
307    /*
308     * First search the existing chain and see if we
309     * can simply add this msg_type to an existing entry.
310     */
311    for (d=msg->dest_chain; d; d=d->next) {
312       if (dest_code == d->dest_code && ((where == NULL && d->where == NULL) ||
313                      (strcmp(where, d->where) == 0))) {
314          Dmsg4(850, "Add to existing d=%p msgtype=%d destcode=%d where=%s\n",
315              d, msg_type, dest_code, NPRT(where));
316          set_bit(msg_type, d->msg_types);
317          set_bit(msg_type, msg->send_msg);  /* set msg_type bit in our local */
318          return;
319       }
320    }
321    /* Not found, create a new entry */
322    d = (DEST *)malloc(sizeof(DEST));
323    memset(d, 0, sizeof(DEST));
324    d->next = msg->dest_chain;
325    d->dest_code = dest_code;
326    set_bit(msg_type, d->msg_types);      /* set type bit in structure */
327    set_bit(msg_type, msg->send_msg);     /* set type bit in our local */
328    if (where) {
329       d->where = bstrdup(where);
330    }
331    if (mail_cmd) {
332       d->mail_cmd = bstrdup(mail_cmd);
333    }
334    Dmsg5(850, "add new d=%p msgtype=%d destcode=%d where=%s mailcmd=%s\n",
335           d, msg_type, dest_code, NPRT(where), NPRT(d->mail_cmd));
336    msg->dest_chain = d;
337 }
338
339 /*
340  * Called only during parsing of the config file.
341  *
342  * Remove a message destination
343  */
344 void rem_msg_dest(MSGS *msg, int dest_code, int msg_type, char *where)
345 {
346    DEST *d;
347
348    for (d=msg->dest_chain; d; d=d->next) {
349       Dmsg2(850, "Remove_msg_dest d=%p where=%s\n", d, NPRT(d->where));
350       if (bit_is_set(msg_type, d->msg_types) && (dest_code == d->dest_code) &&
351           ((where == NULL && d->where == NULL) ||
352                      (strcmp(where, d->where) == 0))) {
353          Dmsg3(850, "Found for remove d=%p msgtype=%d destcode=%d\n",
354                d, msg_type, dest_code);
355          clear_bit(msg_type, d->msg_types);
356          Dmsg0(850, "Return rem_msg_dest\n");
357          return;
358       }
359    }
360 }
361
362
363 /*
364  * Create a unique filename for the mail command
365  */
366 static void make_unique_mail_filename(JCR *jcr, POOLMEM *&name, DEST *d)
367 {
368    if (jcr) {
369       Mmsg(name, "%s/%s.%s.%d.mail", working_directory, my_name,
370                  jcr->Job, (int)(intptr_t)d);
371    } else {
372       Mmsg(name, "%s/%s.%s.%d.mail", working_directory, my_name,
373                  my_name, (int)(intptr_t)d);
374    }
375    Dmsg1(850, "mailname=%s\n", name);
376 }
377
378 /*
379  * Open a mail pipe
380  */
381 static BPIPE *open_mail_pipe(JCR *jcr, POOLMEM *&cmd, DEST *d)
382 {
383    BPIPE *bpipe;
384
385    if (d->mail_cmd) {
386       cmd = edit_job_codes(jcr, cmd, d->mail_cmd, d->where);
387    } else {
388       Mmsg(cmd, "/usr/lib/sendmail -F Bacula %s", d->where);
389    }
390    fflush(stdout);
391
392    if ((bpipe = open_bpipe(cmd, 120, "rw"))) {
393       /* If we had to use sendmail, add subject */
394       if (!d->mail_cmd) {
395          fprintf(bpipe->wfd, "Subject: %s\r\n\r\n", _("Bacula Message"));
396       }
397    } else {
398       berrno be;
399       Jmsg(jcr, M_ERROR, 0, _("open mail pipe %s failed: ERR=%s\n"),
400          cmd, be.bstrerror());
401    }
402    return bpipe;
403 }
404
405 /*
406  * Close the messages for this Messages resource, which means to close
407  *  any open files, and dispatch any pending email messages.
408  */
409 void close_msg(JCR *jcr)
410 {
411    MSGS *msgs;
412    DEST *d;
413    BPIPE *bpipe;
414    POOLMEM *cmd, *line;
415    int len, stat;
416
417    Dmsg1(580, "Close_msg jcr=%p\n", jcr);
418
419    if (jcr == NULL) {                /* NULL -> global chain */
420       msgs = daemon_msgs;
421    } else {
422       msgs = jcr->jcr_msgs;
423       jcr->jcr_msgs = NULL;
424    }
425    if (msgs == NULL) {
426       return;
427    }
428    P(fides_mutex);
429    Dmsg1(850, "===Begin close msg resource at %p\n", msgs);
430    cmd = get_pool_memory(PM_MESSAGE);
431    for (d=msgs->dest_chain; d; ) {
432       if (d->fd) {
433          switch (d->dest_code) {
434          case MD_FILE:
435          case MD_APPEND:
436             if (d->fd) {
437                fclose(d->fd);            /* close open file descriptor */
438                d->fd = NULL;
439             }
440             break;
441          case MD_MAIL:
442          case MD_MAIL_ON_ERROR:
443          case MD_MAIL_ON_SUCCESS:
444             Dmsg0(850, "Got MD_MAIL, MD_MAIL_ON_ERROR or MD_MAIL_ON_SUCCESS\n");
445             if (!d->fd) {
446                break;
447             }
448             if (
449                 (d->dest_code == MD_MAIL_ON_ERROR && jcr &&
450                   (jcr->JobStatus == JS_Terminated || jcr->JobStatus == JS_Warnings)) 
451                 ||
452                 (d->dest_code == MD_MAIL_ON_SUCCESS && jcr &&
453                  jcr->JobStatus == JS_ErrorTerminated)
454                 ) {
455                goto rem_temp_file;
456             }
457
458             if (!(bpipe=open_mail_pipe(jcr, cmd, d))) {
459                Pmsg0(000, _("open mail pipe failed.\n"));
460                goto rem_temp_file;
461             }
462             Dmsg0(850, "Opened mail pipe\n");
463             len = d->max_len+10;
464             line = get_memory(len);
465             rewind(d->fd);
466             while (fgets(line, len, d->fd)) {
467                fputs(line, bpipe->wfd);
468             }
469             if (!close_wpipe(bpipe)) {       /* close write pipe sending mail */
470                berrno be;
471                Pmsg1(000, _("close error: ERR=%s\n"), be.bstrerror());
472             }
473
474             /*
475              * Since we are closing all messages, before "recursing"
476              * make sure we are not closing the daemon messages, otherwise
477              * kaboom.
478              */
479             if (msgs != daemon_msgs) {
480                /* read what mail prog returned -- should be nothing */
481                while (fgets(line, len, bpipe->rfd)) {
482                   Jmsg1(jcr, M_INFO, 0, _("Mail prog: %s"), line);
483                }
484             }
485
486             stat = close_bpipe(bpipe);
487             if (stat != 0 && msgs != daemon_msgs) {
488                berrno be;
489                be.set_errno(stat);
490                Dmsg1(850, "Calling emsg. CMD=%s\n", cmd);
491                Jmsg2(jcr, M_ERROR, 0, _("Mail program terminated in error.\n"
492                                         "CMD=%s\n"
493                                         "ERR=%s\n"), cmd, be.bstrerror());
494             }
495             free_memory(line);
496 rem_temp_file:
497             /* Remove temp file */
498             fclose(d->fd);
499             d->fd = NULL;
500             unlink(d->mail_filename);
501             free_pool_memory(d->mail_filename);
502             d->mail_filename = NULL;
503             Dmsg0(850, "end mail or mail on error\n");
504             break;
505          default:
506             break;
507          }
508          d->fd = NULL;
509       }
510       d = d->next;                    /* point to next buffer */
511    }
512    V(fides_mutex);
513    free_pool_memory(cmd);
514    Dmsg0(850, "Done walking message chain.\n");
515    if (jcr) {
516       free_msgs_res(msgs);
517       msgs = NULL;
518    }
519    Dmsg0(850, "===End close msg resource\n");
520 }
521
522 /*
523  * Free memory associated with Messages resource
524  */
525 void free_msgs_res(MSGS *msgs)
526 {
527    DEST *d, *old;
528
529    /* Walk down the message chain releasing allocated buffers */
530    for (d=msgs->dest_chain; d; ) {
531       if (d->where) {
532          free(d->where);
533       }
534       if (d->mail_cmd) {
535          free(d->mail_cmd);
536       }
537       old = d;                        /* save pointer to release */
538       d = d->next;                    /* point to next buffer */
539       free(old);                      /* free the destination item */
540    }
541    msgs->dest_chain = NULL;
542    free(msgs);                        /* free the head */
543 }
544
545
546 /*
547  * Terminate the message handler for good.
548  * Release the global destination chain.
549  *
550  * Also, clean up a few other items (cons, exepath). Note,
551  *   these really should be done elsewhere.
552  */
553 void term_msg()
554 {
555    Dmsg0(850, "Enter term_msg\n");
556    close_msg(NULL);                   /* close global chain */
557    free_msgs_res(daemon_msgs);        /* free the resources */
558    daemon_msgs = NULL;
559    if (con_fd) {
560       fflush(con_fd);
561       fclose(con_fd);
562       con_fd = NULL;
563    }
564    if (exepath) {
565       free(exepath);
566       exepath = NULL;
567    }
568    if (exename) {
569       free(exename);
570       exename = NULL;
571    }
572    if (trace_fd) {
573       fclose(trace_fd);
574       trace_fd = NULL;
575    }
576    if (catalog_db) {
577       free(catalog_db);
578       catalog_db = NULL;
579    }
580    term_last_jobs_list();
581 }
582
583 static bool open_dest_file(JCR *jcr, DEST *d, const char *mode) 
584 {
585    d->fd = fopen(d->where, mode);
586    if (!d->fd) {
587       berrno be;
588       d->fd = stdout;
589       Qmsg2(jcr, M_ERROR, 0, _("fopen %s failed: ERR=%s\n"), d->where, be.bstrerror());
590       d->fd = NULL;
591       return false;
592    }
593    return true;
594 }
595
596 /*
597  * Handle sending the message to the appropriate place
598  */
599 void dispatch_message(JCR *jcr, int type, utime_t mtime, char *msg)
600 {
601     DEST *d;
602     char dt[MAX_TIME_LENGTH];
603     POOLMEM *mcmd;
604     int len, dtlen;
605     MSGS *msgs;
606     BPIPE *bpipe;
607     const char *mode;
608
609     Dmsg2(850, "Enter dispatch_msg type=%d msg=%s", type, msg);
610
611     /*
612      * Most messages are prefixed by a date and time. If mtime is
613      *  zero, then we use the current time.  If mtime is 1 (special
614      *  kludge), we do not prefix the date and time. Otherwise,
615      *  we assume mtime is a utime_t and use it.
616      */
617     if (mtime == 0) {
618        mtime = time(NULL);
619     }
620     if (mtime == 1) {
621        *dt = 0;
622        dtlen = 0;
623        mtime = time(NULL);      /* get time for SQL log */
624     } else {
625        bstrftime_ny(dt, sizeof(dt), mtime);
626        dtlen = strlen(dt);
627        dt[dtlen++] = ' ';
628        dt[dtlen] = 0;
629     }
630
631     /* If the program registered a callback, send it there */
632     if (message_callback) {
633        message_callback(type, msg);
634        return;
635     }
636
637     if (type == M_ABORT || type == M_ERROR_TERM) {
638        fputs(dt, stdout);
639        fputs(msg, stdout);         /* print this here to INSURE that it is printed */
640        fflush(stdout);
641     }
642
643
644     /* Now figure out where to send the message */
645     msgs = NULL;
646     if (!jcr) {
647        jcr = get_jcr_from_tsd();
648     }
649     if (jcr) {
650        msgs = jcr->jcr_msgs;
651     }
652     if (msgs == NULL) {
653        msgs = daemon_msgs;
654     }
655     for (d=msgs->dest_chain; d; d=d->next) {
656        if (bit_is_set(type, d->msg_types)) {
657           switch (d->dest_code) {
658              case MD_CATALOG:
659                 char ed1[50];
660                 if (!jcr || !jcr->db) {
661                    break;
662                 }
663                 if (p_sql_query && p_sql_escape) {
664                    POOLMEM *cmd = get_pool_memory(PM_MESSAGE);
665                    POOLMEM *esc_msg = get_pool_memory(PM_MESSAGE);
666                    
667                    int len = strlen(msg) + 1;
668                    esc_msg = check_pool_memory_size(esc_msg, len*2+1);
669                    p_sql_escape(jcr, jcr->db, esc_msg, msg, len);
670
671                    bstrutime(dt, sizeof(dt), mtime);
672                    Mmsg(cmd, "INSERT INTO Log (JobId, Time, LogText) VALUES (%s,'%s','%s')",
673                          edit_int64(jcr->JobId, ed1), dt, esc_msg);
674                    p_sql_query(jcr, cmd);
675                    
676                    free_pool_memory(cmd);
677                    free_pool_memory(esc_msg);
678                 }
679                 break;
680              case MD_CONSOLE:
681                 Dmsg1(850, "CONSOLE for following msg: %s", msg);
682                 if (!con_fd) {
683                    con_fd = fopen(con_fname, "a+b");
684                    Dmsg0(850, "Console file not open.\n");
685                 }
686                 if (con_fd) {
687                    Pw(con_lock);      /* get write lock on console message file */
688                    errno = 0;
689                    if (dtlen) {
690                       (void)fwrite(dt, dtlen, 1, con_fd);
691                    }
692                    len = strlen(msg);
693                    if (len > 0) {
694                       (void)fwrite(msg, len, 1, con_fd);
695                       if (msg[len-1] != '\n') {
696                          (void)fwrite("\n", 2, 1, con_fd);
697                       }
698                    } else {
699                       (void)fwrite("\n", 2, 1, con_fd);
700                    }
701                    fflush(con_fd);
702                    console_msg_pending = true;
703                    Vw(con_lock);
704                 }
705                 break;
706              case MD_SYSLOG:
707                 Dmsg1(850, "SYSLOG for following msg: %s\n", msg);
708                 /*
709                  * We really should do an openlog() here.
710                  */
711                 syslog(LOG_DAEMON|LOG_ERR, "%s", msg);
712                 break;
713              case MD_OPERATOR:
714                 Dmsg1(850, "OPERATOR for following msg: %s\n", msg);
715                 mcmd = get_pool_memory(PM_MESSAGE);
716                 if ((bpipe=open_mail_pipe(jcr, mcmd, d))) {
717                    int stat;
718                    fputs(dt, bpipe->wfd);
719                    fputs(msg, bpipe->wfd);
720                    /* Messages to the operator go one at a time */
721                    stat = close_bpipe(bpipe);
722                    if (stat != 0) {
723                       berrno be;
724                       be.set_errno(stat);
725                       Qmsg2(jcr, M_ERROR, 0, _("Operator mail program terminated in error.\n"
726                             "CMD=%s\n"
727                             "ERR=%s\n"), mcmd, be.bstrerror());
728                    }
729                 }
730                 free_pool_memory(mcmd);
731                 break;
732              case MD_MAIL:
733              case MD_MAIL_ON_ERROR:
734              case MD_MAIL_ON_SUCCESS:
735                 Dmsg1(850, "MAIL for following msg: %s", msg);
736                 P(fides_mutex);
737                 if (!d->fd) {
738                    POOLMEM *name = get_pool_memory(PM_MESSAGE);
739                    make_unique_mail_filename(jcr, name, d);
740                    d->fd = fopen(name, "w+b");
741                    if (!d->fd) {
742                       berrno be;
743                       d->fd = stdout;
744                       Qmsg2(jcr, M_ERROR, 0, _("fopen %s failed: ERR=%s\n"), name,
745                             be.bstrerror());
746                       d->fd = NULL;
747                       free_pool_memory(name);
748                       V(fides_mutex);
749                       break;
750                    }
751                    d->mail_filename = name;
752                 }
753                 fputs(dt, d->fd);
754                 len = strlen(msg) + dtlen;;
755                 if (len > d->max_len) {
756                    d->max_len = len;      /* keep max line length */
757                 }
758                 fputs(msg, d->fd);
759                 V(fides_mutex);
760                 break;
761              case MD_APPEND:
762                 Dmsg1(850, "APPEND for following msg: %s", msg);
763                 mode = "ab";
764                 goto send_to_file;
765              case MD_FILE:
766                 Dmsg1(850, "FILE for following msg: %s", msg);
767                 mode = "w+b";
768 send_to_file:
769                 P(fides_mutex);
770                 if (!d->fd && !open_dest_file(jcr, d, mode)) {
771                    V(fides_mutex);
772                    break;
773                 }
774                 fputs(dt, d->fd);
775                 fputs(msg, d->fd);
776                 /* On error, we close and reopen to handle log rotation */
777                 if (ferror(d->fd)) {
778                    fclose(d->fd);
779                    d->fd = NULL;
780                    if (open_dest_file(jcr, d, mode)) {
781                       fputs(dt, d->fd);
782                       fputs(msg, d->fd);
783                    }
784                 }
785                 V(fides_mutex);
786                 break;
787              case MD_DIRECTOR:
788                 Dmsg1(850, "DIRECTOR for following msg: %s", msg);
789                 if (jcr && jcr->dir_bsock && !jcr->dir_bsock->errors) {
790                    jcr->dir_bsock->fsend("Jmsg Job=%s type=%d level=%lld %s",
791                       jcr->Job, type, mtime, msg);
792                 } else {
793                    Dmsg1(800, "no jcr for following msg: %s", msg);
794                 }
795                 break;
796              case MD_STDOUT:
797                 Dmsg1(850, "STDOUT for following msg: %s", msg);
798                 if (type != M_ABORT && type != M_ERROR_TERM) { /* already printed */
799                    fputs(dt, stdout);
800                    fputs(msg, stdout);
801                    fflush(stdout);
802                 }
803                 break;
804              case MD_STDERR:
805                 Dmsg1(850, "STDERR for following msg: %s", msg);
806                 fputs(dt, stderr);
807                 fputs(msg, stderr);
808                 fflush(stdout);
809                 break;
810              default:
811                 break;
812           }
813        }
814     }
815 }
816
817 /*********************************************************************
818  *
819  *  This subroutine returns the filename portion of a Windows 
820  *  path.  It is used because Microsoft Visual Studio sets __FILE__ 
821  *  to the full path.
822  */
823
824 inline const char *
825 get_basename(const char *pathname)
826 {
827 #if defined(_MSC_VER)
828    const char *basename;
829    
830    if ((basename = strrchr(pathname, '\\')) == NULL) {
831       basename = pathname;
832    } else {
833       basename++;
834    }
835
836    return basename;
837 #else
838    return pathname;
839 #endif
840 }
841
842 /*********************************************************************
843  *
844  *  This subroutine prints a debug message if the level number
845  *  is less than or equal the debug_level. File and line numbers
846  *  are included for more detail if desired, but not currently
847  *  printed.
848  *
849  *  If the level is negative, the details of file and line number
850  *  are not printed.
851  */
852 void
853 d_msg(const char *file, int line, int level, const char *fmt,...)
854 {
855     char      buf[5000];
856     int       len;
857     va_list   arg_ptr;
858     bool      details = true;
859     utime_t   mtime;
860
861     if (level < 0) {
862        details = false;
863        level = -level;
864     }
865
866     if (level <= debug_level) {
867        if (dbg_timestamp) {
868           mtime = time(NULL);
869           bstrftimes(buf, sizeof(buf), mtime);
870           len = strlen(buf);
871           buf[len++] = ' ';
872           buf[len] = 0;
873           fputs(buf, stdout);
874        }
875     
876 #ifdef FULL_LOCATION
877        if (details) {
878           len = bsnprintf(buf, sizeof(buf), "%s: %s:%d-%u ", 
879                 my_name, get_basename(file), line, get_jobid_from_tsd());
880        } else {
881           len = 0;
882        }
883 #else
884        len = 0;
885 #endif
886        va_start(arg_ptr, fmt);
887        bvsnprintf(buf+len, sizeof(buf)-len, (char *)fmt, arg_ptr);
888        va_end(arg_ptr);
889
890        /*
891         * Used the "trace on" command in the console to turn on
892         *  output to the trace file.  "trace off" will close the file.
893         */
894        if (trace) {
895           if (!trace_fd) {
896              char fn[200];
897              bsnprintf(fn, sizeof(fn), "%s/%s.trace", working_directory ? working_directory : "./", my_name);
898              trace_fd = fopen(fn, "a+b");
899           }
900           if (trace_fd) {
901              fputs(buf, trace_fd);
902              fflush(trace_fd);
903           } else {
904              /* Some problem, turn off tracing */
905              trace = false;
906           }
907        } else {   /* not tracing */
908           fputs(buf, stdout);
909           fflush(stdout);
910        }
911     }
912 }
913
914 /*
915  * Set trace flag on/off. If argument is negative, there is no change
916  */
917 void set_trace(int trace_flag)
918 {
919    if (trace_flag < 0) {
920       return;
921    } else if (trace_flag > 0) {
922       trace = true;
923    } else {
924       trace = false;
925    }
926    if (!trace && trace_fd) {
927       FILE *ltrace_fd = trace_fd;
928       trace_fd = NULL;
929       bmicrosleep(0, 100000);         /* yield to prevent seg faults */
930       fclose(ltrace_fd);
931    }
932 }
933
934 bool get_trace(void)
935 {
936    return trace;
937 }
938
939 /*********************************************************************
940  *
941  *  This subroutine prints a message regardless of the debug level
942  *
943  *  If the level is negative, the details of file and line number
944  *  are not printed.
945  */
946 void
947 p_msg(const char *file, int line, int level, const char *fmt,...)
948 {
949     char      buf[5000];
950     int       len;
951     va_list   arg_ptr;
952
953 #ifdef FULL_LOCATION
954     if (level >= 0) {
955        len = bsnprintf(buf, sizeof(buf), "%s: %s:%d ", my_name, get_basename(file), line);
956     } else {
957        len = 0;
958     }
959 #else
960     len = 0;
961 #endif
962     va_start(arg_ptr, fmt);
963     bvsnprintf(buf+len, sizeof(buf)-len, (char *)fmt, arg_ptr);
964     va_end(arg_ptr);
965     fputs(buf, stdout);
966     fflush(stdout);
967 }
968
969
970 /*********************************************************************
971  *
972  *  subroutine writes a debug message to the trace file if the level number
973  *  is less than or equal the debug_level. File and line numbers
974  *  are included for more detail if desired, but not currently
975  *  printed.
976  *
977  *  If the level is negative, the details of file and line number
978  *  are not printed.
979  */
980 void
981 t_msg(const char *file, int line, int level, const char *fmt,...)
982 {
983     char      buf[5000];
984     int       len;
985     va_list   arg_ptr;
986     int       details = TRUE;
987
988     if (level < 0) {
989        details = FALSE;
990        level = -level;
991     }
992
993     if (level <= debug_level) {
994        if (!trace_fd) {
995           bsnprintf(buf, sizeof(buf), "%s/%s.trace", working_directory ? working_directory : ".", my_name);
996           trace_fd = fopen(buf, "a+b");
997        }
998
999 #ifdef FULL_LOCATION
1000        if (details) {
1001           len = bsnprintf(buf, sizeof(buf), "%s: %s:%d ", my_name, get_basename(file), line);
1002        } else {
1003           len = 0;
1004        }
1005 #else
1006        len = 0;
1007 #endif
1008        va_start(arg_ptr, fmt);
1009        bvsnprintf(buf+len, sizeof(buf)-len, (char *)fmt, arg_ptr);
1010        va_end(arg_ptr);
1011        if (trace_fd != NULL) {
1012            fputs(buf, trace_fd);
1013            fflush(trace_fd);
1014        }
1015    }
1016 }
1017
1018 /* *********************************************************
1019  *
1020  * print an error message
1021  *
1022  */
1023 void
1024 e_msg(const char *file, int line, int type, int level, const char *fmt,...)
1025 {
1026     char     buf[5000];
1027     va_list   arg_ptr;
1028     int len;
1029
1030     /*
1031      * Check if we have a message destination defined.
1032      * We always report M_ABORT and M_ERROR_TERM
1033      */
1034     if (!daemon_msgs || ((type != M_ABORT && type != M_ERROR_TERM) &&
1035                          !bit_is_set(type, daemon_msgs->send_msg))) {
1036        return;                        /* no destination */
1037     }
1038     switch (type) {
1039     case M_ABORT:
1040        len = bsnprintf(buf, sizeof(buf), _("%s: ABORTING due to ERROR in %s:%d\n"),
1041                my_name, get_basename(file), line);
1042        break;
1043     case M_ERROR_TERM:
1044        len = bsnprintf(buf, sizeof(buf), _("%s: ERROR TERMINATION at %s:%d\n"),
1045                my_name, get_basename(file), line);
1046        break;
1047     case M_FATAL:
1048        if (level == -1)            /* skip details */
1049           len = bsnprintf(buf, sizeof(buf), _("%s: Fatal Error because: "), my_name);
1050        else
1051           len = bsnprintf(buf, sizeof(buf), _("%s: Fatal Error at %s:%d because:\n"), my_name, get_basename(file), line);
1052        break;
1053     case M_ERROR:
1054        if (level == -1)            /* skip details */
1055           len = bsnprintf(buf, sizeof(buf), _("%s: ERROR: "), my_name);
1056        else
1057           len = bsnprintf(buf, sizeof(buf), _("%s: ERROR in %s:%d "), my_name, get_basename(file), line);
1058        break;
1059     case M_WARNING:
1060        len = bsnprintf(buf, sizeof(buf), _("%s: Warning: "), my_name);
1061        break;
1062     case M_SECURITY:
1063        len = bsnprintf(buf, sizeof(buf), _("%s: Security violation: "), my_name);
1064        break;
1065     default:
1066        len = bsnprintf(buf, sizeof(buf), "%s: ", my_name);
1067        break;
1068     }
1069
1070     va_start(arg_ptr, fmt);
1071     bvsnprintf(buf+len, sizeof(buf)-len, (char *)fmt, arg_ptr);
1072     va_end(arg_ptr);
1073
1074     dispatch_message(NULL, type, 0, buf);
1075
1076     if (type == M_ABORT) {
1077        char *p = 0;
1078        p[0] = 0;                      /* generate segmentation violation */
1079     }
1080     if (type == M_ERROR_TERM) {
1081        exit(1);
1082     }
1083 }
1084
1085 /* *********************************************************
1086  *
1087  * Generate a Job message
1088  *
1089  */
1090 void
1091 Jmsg(JCR *jcr, int type, utime_t mtime, const char *fmt,...)
1092 {
1093     char     rbuf[5000];
1094     va_list   arg_ptr;
1095     int len;
1096     MSGS *msgs;
1097     uint32_t JobId = 0;
1098
1099
1100     Dmsg1(850, "Enter Jmsg type=%d\n", type);
1101
1102     /* Special case for the console, which has a dir_bsock and JobId==0,
1103      *  in that case, we send the message directly back to the
1104      *  dir_bsock.
1105      */
1106     if (jcr && jcr->JobId == 0 && jcr->dir_bsock) {
1107        BSOCK *dir = jcr->dir_bsock;
1108        va_start(arg_ptr, fmt);
1109        dir->msglen = bvsnprintf(dir->msg, sizeof_pool_memory(dir->msg),
1110                                 fmt, arg_ptr);
1111        va_end(arg_ptr);
1112        jcr->dir_bsock->send();
1113        return;
1114     }
1115
1116     msgs = NULL;
1117     if (!jcr) {
1118        jcr = get_jcr_from_tsd();
1119     }
1120     if (jcr) {
1121        msgs = jcr->jcr_msgs;
1122        JobId = jcr->JobId;
1123     }
1124     if (!msgs) {
1125        msgs = daemon_msgs;            /* if no jcr, we use daemon handler */
1126     }
1127
1128     /*
1129      * Check if we have a message destination defined.
1130      * We always report M_ABORT and M_ERROR_TERM
1131      */
1132     if (msgs && (type != M_ABORT && type != M_ERROR_TERM) &&
1133          !bit_is_set(type, msgs->send_msg)) {
1134        return;                        /* no destination */
1135     }
1136     switch (type) {
1137     case M_ABORT:
1138        len = bsnprintf(rbuf, sizeof(rbuf), _("%s ABORTING due to ERROR\n"), my_name);
1139        break;
1140     case M_ERROR_TERM:
1141        len = bsnprintf(rbuf, sizeof(rbuf), _("%s ERROR TERMINATION\n"), my_name);
1142        break;
1143     case M_FATAL:
1144        len = bsnprintf(rbuf, sizeof(rbuf), _("%s JobId %u: Fatal error: "), my_name, JobId);
1145        if (jcr) {
1146           set_jcr_job_status(jcr, JS_FatalError);
1147        }
1148        break;
1149     case M_ERROR:
1150        len = bsnprintf(rbuf, sizeof(rbuf), _("%s JobId %u: Error: "), my_name, JobId);
1151        if (jcr) {
1152           jcr->JobErrors++;
1153        }
1154        break;
1155     case M_WARNING:
1156        len = bsnprintf(rbuf, sizeof(rbuf), _("%s JobId %u: Warning: "), my_name, JobId);
1157        if (jcr) {
1158           jcr->JobWarnings++;
1159        }
1160        break;
1161     case M_SECURITY:
1162        len = bsnprintf(rbuf, sizeof(rbuf), _("%s JobId %u: Security violation: "), 
1163                my_name, JobId);
1164        break;
1165     default:
1166        len = bsnprintf(rbuf, sizeof(rbuf), "%s JobId %u: ", my_name, JobId);
1167        break;
1168     }
1169
1170     va_start(arg_ptr, fmt);
1171     bvsnprintf(rbuf+len,  sizeof(rbuf)-len, fmt, arg_ptr);
1172     va_end(arg_ptr);
1173
1174     dispatch_message(jcr, type, mtime, rbuf);
1175
1176     if (type == M_ABORT){
1177        char *p = 0;
1178        printf("Bacula forced SEG FAULT to obtain traceback.\n");
1179        syslog(LOG_DAEMON|LOG_ERR, "Bacula forced SEG FAULT to obtain traceback.\n");
1180        p[0] = 0;                      /* generate segmentation violation */
1181     }
1182     if (type == M_ERROR_TERM) {
1183        exit(1);
1184     }
1185 }
1186
1187 /*
1188  * If we come here, prefix the message with the file:line-number,
1189  *  then pass it on to the normal Jmsg routine.
1190  */
1191 void j_msg(const char *file, int line, JCR *jcr, int type, utime_t mtime, const char *fmt,...)
1192 {
1193    va_list   arg_ptr;
1194    int i, len, maxlen;
1195    POOLMEM *pool_buf;
1196
1197    pool_buf = get_pool_memory(PM_EMSG);
1198    i = Mmsg(pool_buf, "%s:%d ", get_basename(file), line);
1199
1200    for (;;) {
1201       maxlen = sizeof_pool_memory(pool_buf) - i - 1;
1202       va_start(arg_ptr, fmt);
1203       len = bvsnprintf(pool_buf+i, maxlen, fmt, arg_ptr);
1204       va_end(arg_ptr);
1205       if (len < 0 || len >= (maxlen-5)) {
1206          pool_buf = realloc_pool_memory(pool_buf, maxlen + i + maxlen/2);
1207          continue;
1208       }
1209       break;
1210    }
1211
1212    Jmsg(jcr, type, mtime, "%s", pool_buf);
1213    free_memory(pool_buf);
1214 }
1215
1216
1217 /*
1218  * Edit a message into a Pool memory buffer, with file:lineno
1219  */
1220 int m_msg(const char *file, int line, POOLMEM **pool_buf, const char *fmt, ...)
1221 {
1222    va_list   arg_ptr;
1223    int i, len, maxlen;
1224
1225    i = sprintf(*pool_buf, "%s:%d ", get_basename(file), line);
1226
1227    for (;;) {
1228       maxlen = sizeof_pool_memory(*pool_buf) - i - 1;
1229       va_start(arg_ptr, fmt);
1230       len = bvsnprintf(*pool_buf+i, maxlen, fmt, arg_ptr);
1231       va_end(arg_ptr);
1232       if (len < 0 || len >= (maxlen-5)) {
1233          *pool_buf = realloc_pool_memory(*pool_buf, maxlen + i + maxlen/2);
1234          continue;
1235       }
1236       break;
1237    }
1238    return len;
1239 }
1240
1241 int m_msg(const char *file, int line, POOLMEM *&pool_buf, const char *fmt, ...)
1242 {
1243    va_list   arg_ptr;
1244    int i, len, maxlen;
1245
1246    i = sprintf(pool_buf, "%s:%d ", get_basename(file), line);
1247
1248    for (;;) {
1249       maxlen = sizeof_pool_memory(pool_buf) - i - 1;
1250       va_start(arg_ptr, fmt);
1251       len = bvsnprintf(pool_buf+i, maxlen, fmt, arg_ptr);
1252       va_end(arg_ptr);
1253       if (len < 0 || len >= (maxlen-5)) {
1254          pool_buf = realloc_pool_memory(pool_buf, maxlen + i + maxlen/2);
1255          continue;
1256       }
1257       break;
1258    }
1259    return len;
1260 }
1261
1262
1263 /*
1264  * Edit a message into a Pool Memory buffer NO file:lineno
1265  *  Returns: string length of what was edited.
1266  */
1267 int Mmsg(POOLMEM **pool_buf, const char *fmt, ...)
1268 {
1269    va_list   arg_ptr;
1270    int len, maxlen;
1271
1272    for (;;) {
1273       maxlen = sizeof_pool_memory(*pool_buf) - 1;
1274       va_start(arg_ptr, fmt);
1275       len = bvsnprintf(*pool_buf, maxlen, fmt, arg_ptr);
1276       va_end(arg_ptr);
1277       if (len < 0 || len >= (maxlen-5)) {
1278          *pool_buf = realloc_pool_memory(*pool_buf, maxlen + maxlen/2);
1279          continue;
1280       }
1281       break;
1282    }
1283    return len;
1284 }
1285
1286 int Mmsg(POOLMEM *&pool_buf, const char *fmt, ...)
1287 {
1288    va_list   arg_ptr;
1289    int len, maxlen;
1290
1291    for (;;) {
1292       maxlen = sizeof_pool_memory(pool_buf) - 1;
1293       va_start(arg_ptr, fmt);
1294       len = bvsnprintf(pool_buf, maxlen, fmt, arg_ptr);
1295       va_end(arg_ptr);
1296       if (len < 0 || len >= (maxlen-5)) {
1297          pool_buf = realloc_pool_memory(pool_buf, maxlen + maxlen/2);
1298          continue;
1299       }
1300       break;
1301    }
1302    return len;
1303 }
1304
1305 int Mmsg(POOL_MEM &pool_buf, const char *fmt, ...)
1306 {
1307    va_list   arg_ptr;
1308    int len, maxlen;
1309
1310    for (;;) {
1311       maxlen = pool_buf.max_size() - 1;
1312       va_start(arg_ptr, fmt);
1313       len = bvsnprintf(pool_buf.c_str(), maxlen, fmt, arg_ptr);
1314       va_end(arg_ptr);
1315       if (len < 0 || len >= (maxlen-5)) {
1316          pool_buf.realloc_pm(maxlen + maxlen/2);
1317          continue;
1318       }
1319       break;
1320    }
1321    return len;
1322 }
1323
1324
1325 /*
1326  * We queue messages rather than print them directly. This
1327  *  is generally used in low level routines (msg handler, bnet)
1328  *  to prevent recursion (i.e. if you are in the middle of
1329  *  sending a message, it is a bit messy to recursively call
1330  *  yourself when the bnet packet is not reentrant).
1331  */
1332 void Qmsg(JCR *jcr, int type, utime_t mtime, const char *fmt,...)
1333 {
1334    va_list   arg_ptr;
1335    int len, maxlen;
1336    POOLMEM *pool_buf;
1337    MQUEUE_ITEM *item;
1338
1339    pool_buf = get_pool_memory(PM_EMSG);
1340
1341    for (;;) {
1342       maxlen = sizeof_pool_memory(pool_buf) - 1;
1343       va_start(arg_ptr, fmt);
1344       len = bvsnprintf(pool_buf, maxlen, fmt, arg_ptr);
1345       va_end(arg_ptr);
1346       if (len < 0 || len >= (maxlen-5)) {
1347          pool_buf = realloc_pool_memory(pool_buf, maxlen + maxlen/2);
1348          continue;
1349       }
1350       break;
1351    }
1352    item = (MQUEUE_ITEM *)malloc(sizeof(MQUEUE_ITEM) + strlen(pool_buf) + 1);
1353    item->type = type;
1354    item->mtime = time(NULL);
1355    strcpy(item->msg, pool_buf);
1356    if (!jcr) {
1357       jcr = get_jcr_from_tsd();
1358    }
1359    /* If no jcr or no queue send to daemon */
1360    if ((jcr && !jcr->msg_queue) || !jcr) {
1361       /* jcr==NULL => daemon message, safe to send now */
1362       Jmsg(jcr, item->type, item->mtime, "%s", item->msg);
1363       free(item);
1364    } else {
1365       /* Queue message for later sending */
1366       P(jcr->msg_queue_mutex);
1367       jcr->msg_queue->append(item);
1368       V(jcr->msg_queue_mutex);
1369    }
1370    free_memory(pool_buf);
1371 }
1372
1373 /*
1374  * Dequeue messages
1375  */
1376 void dequeue_messages(JCR *jcr)
1377 {
1378    MQUEUE_ITEM *item;
1379    if (!jcr->msg_queue) {
1380       return;
1381    }
1382    P(jcr->msg_queue_mutex);
1383    foreach_dlist(item, jcr->msg_queue) {
1384       Jmsg(jcr, item->type, item->mtime, "%s", item->msg);
1385    }
1386    /* Remove messages just sent */
1387    jcr->msg_queue->destroy();
1388    V(jcr->msg_queue_mutex);
1389 }
1390
1391
1392 /*
1393  * If we come here, prefix the message with the file:line-number,
1394  *  then pass it on to the normal Qmsg routine.
1395  */
1396 void q_msg(const char *file, int line, JCR *jcr, int type, utime_t mtime, const char *fmt,...)
1397 {
1398    va_list   arg_ptr;
1399    int i, len, maxlen;
1400    POOLMEM *pool_buf;
1401
1402    pool_buf = get_pool_memory(PM_EMSG);
1403    i = Mmsg(pool_buf, "%s:%d ", file, line);
1404
1405    for (;;) {
1406       maxlen = sizeof_pool_memory(pool_buf) - i - 1;
1407       va_start(arg_ptr, fmt);
1408       len = bvsnprintf(pool_buf+i, maxlen, fmt, arg_ptr);
1409       va_end(arg_ptr);
1410       if (len < 0 || len >= (maxlen-5)) {
1411          pool_buf = realloc_pool_memory(pool_buf, maxlen + i + maxlen/2);
1412          continue;
1413       }
1414       break;
1415    }
1416
1417    Qmsg(jcr, type, mtime, "%s", pool_buf);
1418    free_memory(pool_buf);
1419 }