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