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