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