]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/message.c
Use Qmsg instead of Jmsg when fides_mutex is locked in close_msg()
[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                   Qmsg1(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                Qmsg2(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        syslog(LOG_DAEMON|LOG_ERR, "%s", msg);
642     }
643
644
645     /* Now figure out where to send the message */
646     msgs = NULL;
647     if (!jcr) {
648        jcr = get_jcr_from_tsd();
649     }
650     if (jcr) {
651        msgs = jcr->jcr_msgs;
652     }
653     if (msgs == NULL) {
654        msgs = daemon_msgs;
655     }
656     for (d=msgs->dest_chain; d; d=d->next) {
657        if (bit_is_set(type, d->msg_types)) {
658           switch (d->dest_code) {
659              case MD_CATALOG:
660                 char ed1[50];
661                 if (!jcr || !jcr->db) {
662                    break;
663                 }
664                 if (p_sql_query && p_sql_escape) {
665                    POOLMEM *cmd = get_pool_memory(PM_MESSAGE);
666                    POOLMEM *esc_msg = get_pool_memory(PM_MESSAGE);
667                    
668                    int len = strlen(msg) + 1;
669                    esc_msg = check_pool_memory_size(esc_msg, len*2+1);
670                    p_sql_escape(jcr, jcr->db, esc_msg, msg, len);
671
672                    bstrutime(dt, sizeof(dt), mtime);
673                    Mmsg(cmd, "INSERT INTO Log (JobId, Time, LogText) VALUES (%s,'%s','%s')",
674                          edit_int64(jcr->JobId, ed1), dt, esc_msg);
675                    p_sql_query(jcr, cmd);
676                    
677                    free_pool_memory(cmd);
678                    free_pool_memory(esc_msg);
679                 }
680                 break;
681              case MD_CONSOLE:
682                 Dmsg1(850, "CONSOLE for following msg: %s", msg);
683                 if (!con_fd) {
684                    con_fd = fopen(con_fname, "a+b");
685                    Dmsg0(850, "Console file not open.\n");
686                 }
687                 if (con_fd) {
688                    Pw(con_lock);      /* get write lock on console message file */
689                    errno = 0;
690                    if (dtlen) {
691                       (void)fwrite(dt, dtlen, 1, con_fd);
692                    }
693                    len = strlen(msg);
694                    if (len > 0) {
695                       (void)fwrite(msg, len, 1, con_fd);
696                       if (msg[len-1] != '\n') {
697                          (void)fwrite("\n", 2, 1, con_fd);
698                       }
699                    } else {
700                       (void)fwrite("\n", 2, 1, con_fd);
701                    }
702                    fflush(con_fd);
703                    console_msg_pending = true;
704                    Vw(con_lock);
705                 }
706                 break;
707              case MD_SYSLOG:
708                 Dmsg1(850, "SYSLOG for following msg: %s\n", msg);
709                 /*
710                  * We really should do an openlog() here.
711                  */
712                 syslog(LOG_DAEMON|LOG_ERR, "%s", msg);
713                 break;
714              case MD_OPERATOR:
715                 Dmsg1(850, "OPERATOR for following msg: %s\n", msg);
716                 mcmd = get_pool_memory(PM_MESSAGE);
717                 if ((bpipe=open_mail_pipe(jcr, mcmd, d))) {
718                    int stat;
719                    fputs(dt, bpipe->wfd);
720                    fputs(msg, bpipe->wfd);
721                    /* Messages to the operator go one at a time */
722                    stat = close_bpipe(bpipe);
723                    if (stat != 0) {
724                       berrno be;
725                       be.set_errno(stat);
726                       Qmsg2(jcr, M_ERROR, 0, _("Operator mail program terminated in error.\n"
727                             "CMD=%s\n"
728                             "ERR=%s\n"), mcmd, be.bstrerror());
729                    }
730                 }
731                 free_pool_memory(mcmd);
732                 break;
733              case MD_MAIL:
734              case MD_MAIL_ON_ERROR:
735              case MD_MAIL_ON_SUCCESS:
736                 Dmsg1(850, "MAIL for following msg: %s", msg);
737                 P(fides_mutex);
738                 if (!d->fd) {
739                    POOLMEM *name = get_pool_memory(PM_MESSAGE);
740                    make_unique_mail_filename(jcr, name, d);
741                    d->fd = fopen(name, "w+b");
742                    if (!d->fd) {
743                       berrno be;
744                       d->fd = stdout;
745                       Qmsg2(jcr, M_ERROR, 0, _("fopen %s failed: ERR=%s\n"), name,
746                             be.bstrerror());
747                       d->fd = NULL;
748                       free_pool_memory(name);
749                       V(fides_mutex);
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                 V(fides_mutex);
761                 break;
762              case MD_APPEND:
763                 Dmsg1(850, "APPEND for following msg: %s", msg);
764                 mode = "ab";
765                 goto send_to_file;
766              case MD_FILE:
767                 Dmsg1(850, "FILE for following msg: %s", msg);
768                 mode = "w+b";
769 send_to_file:
770                 P(fides_mutex);
771                 if (!d->fd && !open_dest_file(jcr, d, mode)) {
772                    V(fides_mutex);
773                    break;
774                 }
775                 fputs(dt, d->fd);
776                 fputs(msg, d->fd);
777                 /* On error, we close and reopen to handle log rotation */
778                 if (ferror(d->fd)) {
779                    fclose(d->fd);
780                    d->fd = NULL;
781                    if (open_dest_file(jcr, d, mode)) {
782                       fputs(dt, d->fd);
783                       fputs(msg, d->fd);
784                    }
785                 }
786                 V(fides_mutex);
787                 break;
788              case MD_DIRECTOR:
789                 Dmsg1(850, "DIRECTOR for following msg: %s", msg);
790                 if (jcr && jcr->dir_bsock && !jcr->dir_bsock->errors) {
791                    jcr->dir_bsock->fsend("Jmsg Job=%s type=%d level=%lld %s",
792                       jcr->Job, type, mtime, msg);
793                 } else {
794                    Dmsg1(800, "no jcr for following msg: %s", msg);
795                 }
796                 break;
797              case MD_STDOUT:
798                 Dmsg1(850, "STDOUT for following msg: %s", msg);
799                 if (type != M_ABORT && type != M_ERROR_TERM) { /* already printed */
800                    fputs(dt, stdout);
801                    fputs(msg, stdout);
802                    fflush(stdout);
803                 }
804                 break;
805              case MD_STDERR:
806                 Dmsg1(850, "STDERR for following msg: %s", msg);
807                 fputs(dt, stderr);
808                 fputs(msg, stderr);
809                 fflush(stdout);
810                 break;
811              default:
812                 break;
813           }
814        }
815     }
816 }
817
818 /*********************************************************************
819  *
820  *  This subroutine returns the filename portion of a Windows 
821  *  path.  It is used because Microsoft Visual Studio sets __FILE__ 
822  *  to the full path.
823  */
824
825 inline const char *
826 get_basename(const char *pathname)
827 {
828 #if defined(_MSC_VER)
829    const char *basename;
830    
831    if ((basename = strrchr(pathname, '\\')) == NULL) {
832       basename = pathname;
833    } else {
834       basename++;
835    }
836
837    return basename;
838 #else
839    return pathname;
840 #endif
841 }
842
843 /*********************************************************************
844  *
845  *  This subroutine prints a debug message if the level number
846  *  is less than or equal the debug_level. File and line numbers
847  *  are included for more detail if desired, but not currently
848  *  printed.
849  *
850  *  If the level is negative, the details of file and line number
851  *  are not printed.
852  */
853 void
854 d_msg(const char *file, int line, int level, const char *fmt,...)
855 {
856     char      buf[5000];
857     int       len;
858     va_list   arg_ptr;
859     bool      details = true;
860     utime_t   mtime;
861
862     if (level < 0) {
863        details = false;
864        level = -level;
865     }
866
867     if (level <= debug_level) {
868        if (dbg_timestamp) {
869           mtime = time(NULL);
870           bstrftimes(buf, sizeof(buf), mtime);
871           len = strlen(buf);
872           buf[len++] = ' ';
873           buf[len] = 0;
874           fputs(buf, stdout);
875        }
876     
877 #ifdef FULL_LOCATION
878        if (details) {
879           len = bsnprintf(buf, sizeof(buf), "%s: %s:%d-%u ", 
880                 my_name, get_basename(file), line, get_jobid_from_tsd());
881        } else {
882           len = 0;
883        }
884 #else
885        len = 0;
886 #endif
887        va_start(arg_ptr, fmt);
888        bvsnprintf(buf+len, sizeof(buf)-len, (char *)fmt, arg_ptr);
889        va_end(arg_ptr);
890
891        /*
892         * Used the "trace on" command in the console to turn on
893         *  output to the trace file.  "trace off" will close the file.
894         */
895        if (trace) {
896           if (!trace_fd) {
897              char fn[200];
898              bsnprintf(fn, sizeof(fn), "%s/%s.trace", working_directory ? working_directory : "./", my_name);
899              trace_fd = fopen(fn, "a+b");
900           }
901           if (trace_fd) {
902              fputs(buf, trace_fd);
903              fflush(trace_fd);
904           } else {
905              /* Some problem, turn off tracing */
906              trace = false;
907           }
908        } else {   /* not tracing */
909           fputs(buf, stdout);
910           fflush(stdout);
911        }
912     }
913 }
914
915 /*
916  * Set trace flag on/off. If argument is negative, there is no change
917  */
918 void set_trace(int trace_flag)
919 {
920    if (trace_flag < 0) {
921       return;
922    } else if (trace_flag > 0) {
923       trace = true;
924    } else {
925       trace = false;
926    }
927    if (!trace && trace_fd) {
928       FILE *ltrace_fd = trace_fd;
929       trace_fd = NULL;
930       bmicrosleep(0, 100000);         /* yield to prevent seg faults */
931       fclose(ltrace_fd);
932    }
933 }
934
935 bool get_trace(void)
936 {
937    return trace;
938 }
939
940 /*********************************************************************
941  *
942  *  This subroutine prints a message regardless of the debug level
943  *
944  *  If the level is negative, the details of file and line number
945  *  are not printed.
946  */
947 void
948 p_msg(const char *file, int line, int level, const char *fmt,...)
949 {
950     char      buf[5000];
951     int       len;
952     va_list   arg_ptr;
953
954 #ifdef FULL_LOCATION
955     if (level >= 0) {
956        len = bsnprintf(buf, sizeof(buf), "%s: %s:%d ", my_name, get_basename(file), line);
957     } else {
958        len = 0;
959     }
960 #else
961     len = 0;
962 #endif
963     va_start(arg_ptr, fmt);
964     bvsnprintf(buf+len, sizeof(buf)-len, (char *)fmt, arg_ptr);
965     va_end(arg_ptr);
966     fputs(buf, stdout);
967     fflush(stdout);
968 }
969
970
971 /*********************************************************************
972  *
973  *  subroutine writes a debug message to the trace file if the level number
974  *  is less than or equal the debug_level. File and line numbers
975  *  are included for more detail if desired, but not currently
976  *  printed.
977  *
978  *  If the level is negative, the details of file and line number
979  *  are not printed.
980  */
981 void
982 t_msg(const char *file, int line, int level, const char *fmt,...)
983 {
984     char      buf[5000];
985     int       len;
986     va_list   arg_ptr;
987     int       details = TRUE;
988
989     if (level < 0) {
990        details = FALSE;
991        level = -level;
992     }
993
994     if (level <= debug_level) {
995        if (!trace_fd) {
996           bsnprintf(buf, sizeof(buf), "%s/%s.trace", working_directory ? working_directory : ".", my_name);
997           trace_fd = fopen(buf, "a+b");
998        }
999
1000 #ifdef FULL_LOCATION
1001        if (details) {
1002           len = bsnprintf(buf, sizeof(buf), "%s: %s:%d ", my_name, get_basename(file), line);
1003        } else {
1004           len = 0;
1005        }
1006 #else
1007        len = 0;
1008 #endif
1009        va_start(arg_ptr, fmt);
1010        bvsnprintf(buf+len, sizeof(buf)-len, (char *)fmt, arg_ptr);
1011        va_end(arg_ptr);
1012        if (trace_fd != NULL) {
1013            fputs(buf, trace_fd);
1014            fflush(trace_fd);
1015        }
1016    }
1017 }
1018
1019 /* *********************************************************
1020  *
1021  * print an error message
1022  *
1023  */
1024 void
1025 e_msg(const char *file, int line, int type, int level, const char *fmt,...)
1026 {
1027     char     buf[5000];
1028     va_list   arg_ptr;
1029     int len;
1030
1031     /*
1032      * Check if we have a message destination defined.
1033      * We always report M_ABORT and M_ERROR_TERM
1034      */
1035     if (!daemon_msgs || ((type != M_ABORT && type != M_ERROR_TERM) &&
1036                          !bit_is_set(type, daemon_msgs->send_msg))) {
1037        return;                        /* no destination */
1038     }
1039     switch (type) {
1040     case M_ABORT:
1041        len = bsnprintf(buf, sizeof(buf), _("%s: ABORTING due to ERROR in %s:%d\n"),
1042                my_name, get_basename(file), line);
1043        break;
1044     case M_ERROR_TERM:
1045        len = bsnprintf(buf, sizeof(buf), _("%s: ERROR TERMINATION at %s:%d\n"),
1046                my_name, get_basename(file), line);
1047        break;
1048     case M_FATAL:
1049        if (level == -1)            /* skip details */
1050           len = bsnprintf(buf, sizeof(buf), _("%s: Fatal Error because: "), my_name);
1051        else
1052           len = bsnprintf(buf, sizeof(buf), _("%s: Fatal Error at %s:%d because:\n"), my_name, get_basename(file), line);
1053        break;
1054     case M_ERROR:
1055        if (level == -1)            /* skip details */
1056           len = bsnprintf(buf, sizeof(buf), _("%s: ERROR: "), my_name);
1057        else
1058           len = bsnprintf(buf, sizeof(buf), _("%s: ERROR in %s:%d "), my_name, get_basename(file), line);
1059        break;
1060     case M_WARNING:
1061        len = bsnprintf(buf, sizeof(buf), _("%s: Warning: "), my_name);
1062        break;
1063     case M_SECURITY:
1064        len = bsnprintf(buf, sizeof(buf), _("%s: Security violation: "), my_name);
1065        break;
1066     default:
1067        len = bsnprintf(buf, sizeof(buf), "%s: ", my_name);
1068        break;
1069     }
1070
1071     va_start(arg_ptr, fmt);
1072     bvsnprintf(buf+len, sizeof(buf)-len, (char *)fmt, arg_ptr);
1073     va_end(arg_ptr);
1074
1075     dispatch_message(NULL, type, 0, buf);
1076
1077     if (type == M_ABORT) {
1078        char *p = 0;
1079        p[0] = 0;                      /* generate segmentation violation */
1080     }
1081     if (type == M_ERROR_TERM) {
1082        exit(1);
1083     }
1084 }
1085
1086 /* *********************************************************
1087  *
1088  * Generate a Job message
1089  *
1090  */
1091 void
1092 Jmsg(JCR *jcr, int type, utime_t mtime, const char *fmt,...)
1093 {
1094     char     rbuf[5000];
1095     va_list   arg_ptr;
1096     int len;
1097     MSGS *msgs;
1098     uint32_t JobId = 0;
1099
1100
1101     Dmsg1(850, "Enter Jmsg type=%d\n", type);
1102
1103     /* Special case for the console, which has a dir_bsock and JobId==0,
1104      *  in that case, we send the message directly back to the
1105      *  dir_bsock.
1106      */
1107     if (jcr && jcr->JobId == 0 && jcr->dir_bsock) {
1108        BSOCK *dir = jcr->dir_bsock;
1109        va_start(arg_ptr, fmt);
1110        dir->msglen = bvsnprintf(dir->msg, sizeof_pool_memory(dir->msg),
1111                                 fmt, arg_ptr);
1112        va_end(arg_ptr);
1113        jcr->dir_bsock->send();
1114        return;
1115     }
1116
1117     msgs = NULL;
1118     if (!jcr) {
1119        jcr = get_jcr_from_tsd();
1120     }
1121     if (jcr) {
1122        msgs = jcr->jcr_msgs;
1123        JobId = jcr->JobId;
1124     }
1125     if (!msgs) {
1126        msgs = daemon_msgs;            /* if no jcr, we use daemon handler */
1127     }
1128
1129     /*
1130      * Check if we have a message destination defined.
1131      * We always report M_ABORT and M_ERROR_TERM
1132      */
1133     if (msgs && (type != M_ABORT && type != M_ERROR_TERM) &&
1134          !bit_is_set(type, msgs->send_msg)) {
1135        return;                        /* no destination */
1136     }
1137     switch (type) {
1138     case M_ABORT:
1139        len = bsnprintf(rbuf, sizeof(rbuf), _("%s ABORTING due to ERROR\n"), my_name);
1140        break;
1141     case M_ERROR_TERM:
1142        len = bsnprintf(rbuf, sizeof(rbuf), _("%s ERROR TERMINATION\n"), my_name);
1143        break;
1144     case M_FATAL:
1145        len = bsnprintf(rbuf, sizeof(rbuf), _("%s JobId %u: Fatal error: "), my_name, JobId);
1146        if (jcr) {
1147           set_jcr_job_status(jcr, JS_FatalError);
1148        }
1149        break;
1150     case M_ERROR:
1151        len = bsnprintf(rbuf, sizeof(rbuf), _("%s JobId %u: Error: "), my_name, JobId);
1152        if (jcr) {
1153           jcr->JobErrors++;
1154        }
1155        break;
1156     case M_WARNING:
1157        len = bsnprintf(rbuf, sizeof(rbuf), _("%s JobId %u: Warning: "), my_name, JobId);
1158        if (jcr) {
1159           jcr->JobWarnings++;
1160        }
1161        break;
1162     case M_SECURITY:
1163        len = bsnprintf(rbuf, sizeof(rbuf), _("%s JobId %u: Security violation: "), 
1164                my_name, JobId);
1165        break;
1166     default:
1167        len = bsnprintf(rbuf, sizeof(rbuf), "%s JobId %u: ", my_name, JobId);
1168        break;
1169     }
1170
1171     va_start(arg_ptr, fmt);
1172     bvsnprintf(rbuf+len,  sizeof(rbuf)-len, fmt, arg_ptr);
1173     va_end(arg_ptr);
1174
1175     dispatch_message(jcr, type, mtime, rbuf);
1176
1177     if (type == M_ABORT){
1178        char *p = 0;
1179        printf("Bacula forced SEG FAULT to obtain traceback.\n");
1180        syslog(LOG_DAEMON|LOG_ERR, "Bacula forced SEG FAULT to obtain traceback.\n");
1181        p[0] = 0;                      /* generate segmentation violation */
1182     }
1183     if (type == M_ERROR_TERM) {
1184        exit(1);
1185     }
1186 }
1187
1188 /*
1189  * If we come here, prefix the message with the file:line-number,
1190  *  then pass it on to the normal Jmsg routine.
1191  */
1192 void j_msg(const char *file, int line, JCR *jcr, int type, utime_t mtime, const char *fmt,...)
1193 {
1194    va_list   arg_ptr;
1195    int i, len, maxlen;
1196    POOLMEM *pool_buf;
1197
1198    pool_buf = get_pool_memory(PM_EMSG);
1199    i = Mmsg(pool_buf, "%s:%d ", get_basename(file), line);
1200
1201    for (;;) {
1202       maxlen = sizeof_pool_memory(pool_buf) - i - 1;
1203       va_start(arg_ptr, fmt);
1204       len = bvsnprintf(pool_buf+i, maxlen, fmt, arg_ptr);
1205       va_end(arg_ptr);
1206       if (len < 0 || len >= (maxlen-5)) {
1207          pool_buf = realloc_pool_memory(pool_buf, maxlen + i + maxlen/2);
1208          continue;
1209       }
1210       break;
1211    }
1212
1213    Jmsg(jcr, type, mtime, "%s", pool_buf);
1214    free_memory(pool_buf);
1215 }
1216
1217
1218 /*
1219  * Edit a message into a Pool memory buffer, with file:lineno
1220  */
1221 int m_msg(const char *file, int line, POOLMEM **pool_buf, const char *fmt, ...)
1222 {
1223    va_list   arg_ptr;
1224    int i, len, maxlen;
1225
1226    i = sprintf(*pool_buf, "%s:%d ", get_basename(file), line);
1227
1228    for (;;) {
1229       maxlen = sizeof_pool_memory(*pool_buf) - i - 1;
1230       va_start(arg_ptr, fmt);
1231       len = bvsnprintf(*pool_buf+i, maxlen, fmt, arg_ptr);
1232       va_end(arg_ptr);
1233       if (len < 0 || len >= (maxlen-5)) {
1234          *pool_buf = realloc_pool_memory(*pool_buf, maxlen + i + maxlen/2);
1235          continue;
1236       }
1237       break;
1238    }
1239    return len;
1240 }
1241
1242 int m_msg(const char *file, int line, POOLMEM *&pool_buf, const char *fmt, ...)
1243 {
1244    va_list   arg_ptr;
1245    int i, len, maxlen;
1246
1247    i = sprintf(pool_buf, "%s:%d ", get_basename(file), line);
1248
1249    for (;;) {
1250       maxlen = sizeof_pool_memory(pool_buf) - i - 1;
1251       va_start(arg_ptr, fmt);
1252       len = bvsnprintf(pool_buf+i, maxlen, fmt, arg_ptr);
1253       va_end(arg_ptr);
1254       if (len < 0 || len >= (maxlen-5)) {
1255          pool_buf = realloc_pool_memory(pool_buf, maxlen + i + maxlen/2);
1256          continue;
1257       }
1258       break;
1259    }
1260    return len;
1261 }
1262
1263
1264 /*
1265  * Edit a message into a Pool Memory buffer NO file:lineno
1266  *  Returns: string length of what was edited.
1267  */
1268 int Mmsg(POOLMEM **pool_buf, const char *fmt, ...)
1269 {
1270    va_list   arg_ptr;
1271    int len, maxlen;
1272
1273    for (;;) {
1274       maxlen = sizeof_pool_memory(*pool_buf) - 1;
1275       va_start(arg_ptr, fmt);
1276       len = bvsnprintf(*pool_buf, maxlen, fmt, arg_ptr);
1277       va_end(arg_ptr);
1278       if (len < 0 || len >= (maxlen-5)) {
1279          *pool_buf = realloc_pool_memory(*pool_buf, maxlen + maxlen/2);
1280          continue;
1281       }
1282       break;
1283    }
1284    return len;
1285 }
1286
1287 int Mmsg(POOLMEM *&pool_buf, const char *fmt, ...)
1288 {
1289    va_list   arg_ptr;
1290    int len, maxlen;
1291
1292    for (;;) {
1293       maxlen = sizeof_pool_memory(pool_buf) - 1;
1294       va_start(arg_ptr, fmt);
1295       len = bvsnprintf(pool_buf, maxlen, fmt, arg_ptr);
1296       va_end(arg_ptr);
1297       if (len < 0 || len >= (maxlen-5)) {
1298          pool_buf = realloc_pool_memory(pool_buf, maxlen + maxlen/2);
1299          continue;
1300       }
1301       break;
1302    }
1303    return len;
1304 }
1305
1306 int Mmsg(POOL_MEM &pool_buf, const char *fmt, ...)
1307 {
1308    va_list   arg_ptr;
1309    int len, maxlen;
1310
1311    for (;;) {
1312       maxlen = pool_buf.max_size() - 1;
1313       va_start(arg_ptr, fmt);
1314       len = bvsnprintf(pool_buf.c_str(), maxlen, fmt, arg_ptr);
1315       va_end(arg_ptr);
1316       if (len < 0 || len >= (maxlen-5)) {
1317          pool_buf.realloc_pm(maxlen + maxlen/2);
1318          continue;
1319       }
1320       break;
1321    }
1322    return len;
1323 }
1324
1325
1326 /*
1327  * We queue messages rather than print them directly. This
1328  *  is generally used in low level routines (msg handler, bnet)
1329  *  to prevent recursion (i.e. if you are in the middle of
1330  *  sending a message, it is a bit messy to recursively call
1331  *  yourself when the bnet packet is not reentrant).
1332  */
1333 void Qmsg(JCR *jcr, int type, utime_t mtime, const char *fmt,...)
1334 {
1335    va_list   arg_ptr;
1336    int len, maxlen;
1337    POOLMEM *pool_buf;
1338    MQUEUE_ITEM *item;
1339
1340    pool_buf = get_pool_memory(PM_EMSG);
1341
1342    for (;;) {
1343       maxlen = sizeof_pool_memory(pool_buf) - 1;
1344       va_start(arg_ptr, fmt);
1345       len = bvsnprintf(pool_buf, maxlen, fmt, arg_ptr);
1346       va_end(arg_ptr);
1347       if (len < 0 || len >= (maxlen-5)) {
1348          pool_buf = realloc_pool_memory(pool_buf, maxlen + maxlen/2);
1349          continue;
1350       }
1351       break;
1352    }
1353    item = (MQUEUE_ITEM *)malloc(sizeof(MQUEUE_ITEM) + strlen(pool_buf) + 1);
1354    item->type = type;
1355    item->mtime = time(NULL);
1356    strcpy(item->msg, pool_buf);
1357    if (!jcr) {
1358       jcr = get_jcr_from_tsd();
1359    }
1360    /* If no jcr or no queue send to daemon */
1361    if ((jcr && !jcr->msg_queue) || !jcr) {
1362       /* jcr==NULL => daemon message, safe to send now */
1363       Jmsg(jcr, item->type, item->mtime, "%s", item->msg);
1364       free(item);
1365    /*
1366     * If we are dequeuing, we cannot queue another item,
1367     * so as a last resort send it to the syslog 
1368     */
1369    } else if (jcr->dequeuing_msgs) {
1370       syslog(LOG_DAEMON|LOG_ERR, "%s", item->msg);
1371       free(item);
1372    } else {
1373       /* Queue message for later sending */
1374       P(jcr->msg_queue_mutex);
1375       jcr->msg_queue->append(item);
1376       V(jcr->msg_queue_mutex);
1377    }
1378    free_memory(pool_buf);
1379 }
1380
1381 /*
1382  * Dequeue messages
1383  */
1384 void dequeue_messages(JCR *jcr)
1385 {
1386    MQUEUE_ITEM *item;
1387    if (!jcr->msg_queue) {
1388       return;
1389    }
1390    P(jcr->msg_queue_mutex);
1391    jcr->dequeuing_msgs = true;
1392    foreach_dlist(item, jcr->msg_queue) {
1393       Jmsg(jcr, item->type, item->mtime, "%s", item->msg);
1394    }
1395    /* Remove messages just sent */
1396    jcr->msg_queue->destroy();
1397    jcr->dequeuing_msgs = false;
1398    V(jcr->msg_queue_mutex);
1399 }
1400
1401
1402 /*
1403  * If we come here, prefix the message with the file:line-number,
1404  *  then pass it on to the normal Qmsg routine.
1405  */
1406 void q_msg(const char *file, int line, JCR *jcr, int type, utime_t mtime, const char *fmt,...)
1407 {
1408    va_list   arg_ptr;
1409    int i, len, maxlen;
1410    POOLMEM *pool_buf;
1411
1412    pool_buf = get_pool_memory(PM_EMSG);
1413    i = Mmsg(pool_buf, "%s:%d ", file, line);
1414
1415    for (;;) {
1416       maxlen = sizeof_pool_memory(pool_buf) - i - 1;
1417       va_start(arg_ptr, fmt);
1418       len = bvsnprintf(pool_buf+i, maxlen, fmt, arg_ptr);
1419       va_end(arg_ptr);
1420       if (len < 0 || len >= (maxlen-5)) {
1421          pool_buf = realloc_pool_memory(pool_buf, maxlen + i + maxlen/2);
1422          continue;
1423       }
1424       break;
1425    }
1426
1427    Qmsg(jcr, type, mtime, "%s", pool_buf);
1428    free_memory(pool_buf);
1429 }