]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/message.c
Backport from BEE
[bacula/bacula] / bacula / src / lib / message.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2000-2014 Free Software Foundation Europe e.V.
5
6    The main author of Bacula is Kern Sibbald, with contributions from many
7    others, a complete list can be found in the file AUTHORS.
8
9    You may use this file and others of this release according to the
10    license defined in the LICENSE file, which includes the Affero General
11    Public License, v3.0 ("AGPLv3") and some additional permissions and
12    terms pursuant to its AGPLv3 Section 7.
13
14    Bacula® is a registered trademark of Kern Sibbald.
15 */
16 /*
17  * Bacula message handling routines
18  *
19  * NOTE: don't use any Jmsg or Qmsg calls within this file,
20  *   except in q_msg or j_msg (setup routines),
21  *   otherwise you may get into recursive calls if there are
22  *   errors, and that can lead to looping or deadlocks.
23  *
24  *   Written by Kern Sibbald, April 2000
25  *
26  */
27
28 #include "bacula.h"
29 #include "jcr.h"
30
31 sql_query_func p_sql_query = NULL;
32 sql_escape_func p_sql_escape = NULL;
33
34 #define FULL_LOCATION 1               /* set for file:line in Debug messages */
35
36 /*
37  *  This is where we define "Globals" because all the
38  *    daemons include this file.
39  */
40 const char *working_directory = NULL; /* working directory path stored here */
41 const char *assert_msg = NULL;        /* ASSERT2 error message */
42 const char *version = VERSION " (" BDATE ")";
43 const char *dist_name = DISTNAME " " DISTVER;
44 char *exepath = (char *)NULL;
45 char *exename = (char *)NULL;
46 char *catalog_db = NULL;              /* database type */
47 char con_fname[500];                  /* Console filename */
48 char my_name[30] = {0};               /* daemon name is stored here */
49 char host_name[50] = {0};             /* host machine name */
50 char fail_time[30] = {0};             /* Time of failure */
51 int verbose = 0;                      /* increase User messages */
52 int64_t debug_level = 0;              /* debug level */
53 int32_t debug_flags = 0;              /* debug flags */
54 int beef = BEEF;
55 int console_msg_pending = false;
56 utime_t daemon_start_time = 0;        /* Daemon start time */
57 FILE *con_fd = NULL;                  /* Console file descriptor */
58 brwlock_t con_lock;                   /* Console lock structure */
59 bool dbg_timestamp = false;           /* print timestamp in debug output */
60 bool prt_kaboom = false;              /* Print kaboom output */
61 job_code_callback_t message_job_code_callback = NULL;   /* Job code callback. Only used by director. */
62
63 /* Forward referenced functions */
64
65 /* Imported functions */
66 void create_jcr_key();
67
68 /* Static storage */
69
70 /* Exclude spaces but require .mail at end */
71 #define MAIL_REGEX "^[^ ]+\\.mail$"
72
73 /* Allow only one thread to tweak d->fd at a time */
74 static pthread_mutex_t fides_mutex = PTHREAD_MUTEX_INITIALIZER;
75 static MSGS *daemon_msgs;              /* global messages */
76 static void (*message_callback)(int type, char *msg) = NULL;
77 static FILE *trace_fd = NULL;
78 #if defined(HAVE_WIN32)
79 static bool trace = true;
80 #else
81 static bool trace = false;
82 #endif
83 static int hangup = 0;
84
85 /* Constants */
86 const char *host_os = HOST_OS;
87 const char *distname = DISTNAME;
88 const char *distver = DISTVER;
89
90 /*
91  * Walk back in a string from end looking for a
92  *  path separator.
93  *  This routine is passed the start of the string and
94  *  the end of the string, it returns either the beginning
95  *  of the string or where it found a path separator.
96  */
97 static const char *bstrrpath(const char *start, const char *end)
98 {
99    while ( end > start ) {
100       end--;
101       if (IsPathSeparator(*end)) {
102          break;
103       }
104    }
105    return end;
106 }
107
108 /*
109  * Returns: 0 if not configured
110  *         -1 on error
111  *          1 OK
112  */
113 int generate_daemon_event(JCR *jcr, const char *event)
114 {
115    return 0;
116 }
117
118 /* Some message class methods */
119 void MSGS::lock()
120 {
121    P(fides_mutex);
122 }
123
124 void MSGS::unlock()
125 {
126    V(fides_mutex);
127 }
128
129 /*
130  * Wait for not in use variable to be clear
131  */
132 void MSGS::wait_not_in_use()     /* leaves fides_mutex set */
133 {
134    lock();
135    while (m_in_use || m_closing) {
136       unlock();
137       bmicrosleep(0, 200);         /* wait */
138       lock();
139    }
140 }
141
142 /*
143  * Handle message delivery errors
144  */
145 static void delivery_error(const char *fmt,...)
146 {
147    va_list   arg_ptr;
148    int i, len, maxlen;
149    POOLMEM *pool_buf;
150    char dt[MAX_TIME_LENGTH];
151    int dtlen;
152
153    pool_buf = get_pool_memory(PM_EMSG);
154
155    bstrftime_ny(dt, sizeof(dt), time(NULL));
156    dtlen = strlen(dt);
157    dt[dtlen++] = ' ';
158    dt[dtlen] = 0;
159
160    i = Mmsg(pool_buf, "%s Message delivery ERROR: ", dt);
161
162    for (;;) {
163       maxlen = sizeof_pool_memory(pool_buf) - i - 1;
164       va_start(arg_ptr, fmt);
165       len = bvsnprintf(pool_buf+i, maxlen, fmt, arg_ptr);
166       va_end(arg_ptr);
167       if (len < 0 || len >= (maxlen-5)) {
168          pool_buf = realloc_pool_memory(pool_buf, maxlen + i + maxlen/2);
169          continue;
170       }
171       break;
172    }
173
174    fputs(pool_buf, stdout);  /* print this here to INSURE that it is printed */
175    fflush(stdout);
176    syslog(LOG_DAEMON|LOG_ERR, "%s", pool_buf);
177    free_memory(pool_buf);
178 }
179
180 void set_debug_flags(char *options)
181 {
182    for (char *p = options; *p ; p++) {
183       switch(*p) {
184       case '0':                 /* clear flags */
185          debug_flags = 0;
186          break;
187
188       case 'i':                 /* used by FD */
189       case 'd':                 /* used by FD */
190          break;
191
192       case 't':
193          dbg_timestamp = true;
194          break;
195
196       case 'T':
197          dbg_timestamp = false;
198          break;
199
200       case 'c':
201          /* truncate the trace file */
202          if (trace && trace_fd) {
203             ftruncate(fileno(trace_fd), 0);
204          }
205          break;
206
207       case 'l':
208          /* Turn on/off add_events for P()/V() */
209          debug_flags |= DEBUG_MUTEX_EVENT;
210          break;
211
212       case 'p':
213          /* Display event stack during lockdump */
214          debug_flags |= DEBUG_PRINT_EVENT;
215          break;
216
217       default:
218          Dmsg1(000, "Unknown debug flag %c\n", *p);
219       }
220    }
221 }
222
223 void register_message_callback(void msg_callback(int type, char *msg))
224 {
225    message_callback = msg_callback;
226 }
227
228
229 /*
230  * Set daemon name. Also, find canonical execution
231  *  path.  Note, exepath has spare room for tacking on
232  *  the exename so that we can reconstruct the full name.
233  *
234  * Note, this routine can get called multiple times
235  *  The second time is to put the name as found in the
236  *  Resource record. On the second call, generally,
237  *  argv is NULL to avoid doing the path code twice.
238  */
239 void my_name_is(int argc, char *argv[], const char *name)
240 {
241    char *l, *p, *q;
242    char cpath[1024];
243    int len;
244
245    if (gethostname(host_name, sizeof(host_name)) != 0) {
246       bstrncpy(host_name, "Hostname unknown", sizeof(host_name));
247    }
248    bstrncpy(my_name, name, sizeof(my_name));
249    if (argc>0 && argv && argv[0]) {
250       /* strip trailing filename and save exepath */
251       for (l=p=argv[0]; *p; p++) {
252          if (IsPathSeparator(*p)) {
253             l = p;                       /* set pos of last slash */
254          }
255       }
256       if (IsPathSeparator(*l)) {
257          l++;
258       } else {
259          l = argv[0];
260 #if defined(HAVE_WIN32)
261          /* On Windows allow c: drive specification */
262          if (l[1] == ':') {
263             l += 2;
264          }
265 #endif
266       }
267       len = strlen(l) + 1;
268       if (exename) {
269          free(exename);
270       }
271       exename = (char *)malloc(len);
272       strcpy(exename, l);
273
274       if (exepath) {
275          free(exepath);
276       }
277       exepath = (char *)malloc(strlen(argv[0]) + 1 + len);
278       for (p=argv[0],q=exepath; p < l; ) {
279          *q++ = *p++;
280       }
281       *q = 0;
282       if (strchr(exepath, '.') || !IsPathSeparator(exepath[0])) {
283          if (getcwd(cpath, sizeof(cpath))) {
284             free(exepath);
285             exepath = (char *)malloc(strlen(cpath) + 1 + len);
286             strcpy(exepath, cpath);
287          }
288       }
289       Dmsg2(500, "exepath=%s\nexename=%s\n", exepath, exename);
290    }
291 }
292
293 /* Set special ASSERT2 message where debugger can find it */
294 void
295 set_assert_msg(const char *file, int line, const char *msg)
296 {
297    char buf[2000];
298    bsnprintf(buf, sizeof(buf), "ASSERT at %s:%d-%u ERR=%s",
299       get_basename(file), line, get_jobid_from_tsd(), msg);
300    assert_msg = bstrdup(buf);
301 }
302
303 void
304 set_db_type(const char *name)
305 {
306    if (catalog_db != NULL) {
307       free(catalog_db);
308    }
309    catalog_db = bstrdup(name);
310 }
311
312 /*
313  * Initialize message handler for a daemon or a Job
314  *   We make a copy of the MSGS resource passed, so it belows
315  *   to the job or daemon and thus can be modified.
316  *
317  *   NULL for jcr -> initialize global messages for daemon
318  *   non-NULL     -> initialize jcr using Message resource
319  */
320 void
321 init_msg(JCR *jcr, MSGS *msg, job_code_callback_t job_code_callback)
322 {
323    DEST *d, *dnew, *temp_chain = NULL;
324    int i;
325
326    if (jcr == NULL && msg == NULL) {
327       init_last_jobs_list();
328       /* Create a daemon key then set invalid jcr */
329       /* Maybe we should give the daemon a jcr??? */
330       create_jcr_key();
331       set_jcr_in_tsd(INVALID_JCR);
332    }
333
334    message_job_code_callback = job_code_callback;
335
336 #if !defined(HAVE_WIN32)
337    /*
338     * Make sure we have fd's 0, 1, 2 open
339     *  If we don't do this one of our sockets may open
340     *  there and if we then use stdout, it could
341     *  send total garbage to our socket.
342     *
343     */
344    int fd;
345    fd = open("/dev/null", O_RDONLY, 0644);
346    if (fd > 2) {
347       close(fd);
348    } else {
349       for(i=1; fd + i <= 2; i++) {
350          dup2(fd, fd+i);
351       }
352    }
353
354 #endif
355    /*
356     * If msg is NULL, initialize global chain for STDOUT and syslog
357     */
358    if (msg == NULL) {
359       daemon_msgs = (MSGS *)malloc(sizeof(MSGS));
360       memset(daemon_msgs, 0, sizeof(MSGS));
361       for (i=1; i<=M_MAX; i++) {
362          add_msg_dest(daemon_msgs, MD_STDOUT, i, NULL, NULL);
363       }
364       Dmsg1(050, "Create daemon global message resource %p\n", daemon_msgs);
365       return;
366    }
367
368    /*
369     * Walk down the message resource chain duplicating it
370     * for the current Job.
371     */
372    for (d=msg->dest_chain; d; d=d->next) {
373       dnew = (DEST *)malloc(sizeof(DEST));
374       memcpy(dnew, d, sizeof(DEST));
375       dnew->next = temp_chain;
376       dnew->fd = NULL;
377       dnew->mail_filename = NULL;
378       if (d->mail_cmd) {
379          dnew->mail_cmd = bstrdup(d->mail_cmd);
380       }
381       if (d->where) {
382          dnew->where = bstrdup(d->where);
383       }
384       temp_chain = dnew;
385    }
386
387    if (jcr) {
388       jcr->jcr_msgs = (MSGS *)malloc(sizeof(MSGS));
389       memset(jcr->jcr_msgs, 0, sizeof(MSGS));
390       jcr->jcr_msgs->dest_chain = temp_chain;
391       memcpy(jcr->jcr_msgs->send_msg, msg->send_msg, sizeof(msg->send_msg));
392    } else {
393       /* If we have default values, release them now */
394       if (daemon_msgs) {
395          free_msgs_res(daemon_msgs);
396       }
397       daemon_msgs = (MSGS *)malloc(sizeof(MSGS));
398       memset(daemon_msgs, 0, sizeof(MSGS));
399       daemon_msgs->dest_chain = temp_chain;
400       memcpy(daemon_msgs->send_msg, msg->send_msg, sizeof(msg->send_msg));
401    }
402
403    Dmsg2(250, "Copy message resource %p to %p\n", msg, temp_chain);
404 }
405
406 /* Initialize so that the console (User Agent) can
407  * receive messages -- stored in a file.
408  */
409 void init_console_msg(const char *wd)
410 {
411    int fd;
412
413    bsnprintf(con_fname, sizeof(con_fname), "%s%c%s.conmsg", wd, PathSeparator, my_name);
414    fd = open(con_fname, O_CREAT|O_RDWR|O_BINARY, 0600);
415    if (fd == -1) {
416       berrno be;
417       Emsg2(M_ERROR_TERM, 0, _("Could not open console message file %s: ERR=%s\n"),
418           con_fname, be.bstrerror());
419    }
420    if (lseek(fd, 0, SEEK_END) > 0) {
421       console_msg_pending = 1;
422    }
423    close(fd);
424    con_fd = fopen(con_fname, "a+b");
425    if (!con_fd) {
426       berrno be;
427       Emsg2(M_ERROR, 0, _("Could not open console message file %s: ERR=%s\n"),
428           con_fname, be.bstrerror());
429    }
430    if (rwl_init(&con_lock) != 0) {
431       berrno be;
432       Emsg1(M_ERROR_TERM, 0, _("Could not get con mutex: ERR=%s\n"),
433          be.bstrerror());
434    }
435 }
436
437 /*
438  * Called only during parsing of the config file.
439  *
440  * Add a message destination. I.e. associate a message type with
441  *  a destination (code).
442  * Note, where in the case of dest_code FILE is a filename,
443  *  but in the case of MAIL is a space separated list of
444  *  email addresses, ...
445  */
446 void add_msg_dest(MSGS *msg, int dest_code, int msg_type, char *where, char *mail_cmd)
447 {
448    DEST *d;
449    /*
450     * First search the existing chain and see if we
451     * can simply add this msg_type to an existing entry.
452     */
453    for (d=msg->dest_chain; d; d=d->next) {
454       if (dest_code == d->dest_code && ((where == NULL && d->where == NULL) ||
455                      (strcmp(where, d->where) == 0))) {
456          Dmsg4(850, "Add to existing d=%p msgtype=%d destcode=%d where=%s\n",
457              d, msg_type, dest_code, NPRT(where));
458          set_bit(msg_type, d->msg_types);
459          set_bit(msg_type, msg->send_msg);  /* set msg_type bit in our local */
460          return;
461       }
462    }
463    /* Not found, create a new entry */
464    d = (DEST *)malloc(sizeof(DEST));
465    memset(d, 0, sizeof(DEST));
466    d->next = msg->dest_chain;
467    d->dest_code = dest_code;
468    set_bit(msg_type, d->msg_types);      /* set type bit in structure */
469    set_bit(msg_type, msg->send_msg);     /* set type bit in our local */
470    if (where) {
471       d->where = bstrdup(where);
472    }
473    if (mail_cmd) {
474       d->mail_cmd = bstrdup(mail_cmd);
475    }
476    Dmsg5(850, "add new d=%p msgtype=%d destcode=%d where=%s mailcmd=%s\n",
477           d, msg_type, dest_code, NPRT(where), NPRT(d->mail_cmd));
478    msg->dest_chain = d;
479 }
480
481 /*
482  * Called only during parsing of the config file.
483  *
484  * Remove a message destination
485  */
486 void rem_msg_dest(MSGS *msg, int dest_code, int msg_type, char *where)
487 {
488    DEST *d;
489
490    for (d=msg->dest_chain; d; d=d->next) {
491       Dmsg2(850, "Remove_msg_dest d=%p where=%s\n", d, NPRT(d->where));
492       if (bit_is_set(msg_type, d->msg_types) && (dest_code == d->dest_code) &&
493           ((where == NULL && d->where == NULL) ||
494                      (strcmp(where, d->where) == 0))) {
495          Dmsg3(850, "Found for remove d=%p msgtype=%d destcode=%d\n",
496                d, msg_type, dest_code);
497          clear_bit(msg_type, d->msg_types);
498          Dmsg0(850, "Return rem_msg_dest\n");
499          return;
500       }
501    }
502 }
503
504
505 /*
506  * Create a unique filename for the mail command
507  */
508 static void make_unique_mail_filename(JCR *jcr, POOLMEM *&name, DEST *d)
509 {
510    if (jcr) {
511       Mmsg(name, "%s/%s.%s.%d.mail", working_directory, my_name,
512                  jcr->Job, (int)(intptr_t)d);
513    } else {
514       Mmsg(name, "%s/%s.%s.%d.mail", working_directory, my_name,
515                  my_name, (int)(intptr_t)d);
516    }
517    Dmsg1(850, "mailname=%s\n", name);
518 }
519
520 /*
521  * Open a mail pipe
522  */
523 static BPIPE *open_mail_pipe(JCR *jcr, POOLMEM *&cmd, DEST *d)
524 {
525    BPIPE *bpipe;
526
527    if (d->mail_cmd) {
528       cmd = edit_job_codes(jcr, cmd, d->mail_cmd, d->where, message_job_code_callback);
529    } else {
530       Mmsg(cmd, "/usr/lib/sendmail -F Bacula %s", d->where);
531    }
532    fflush(stdout);
533
534    if ((bpipe = open_bpipe(cmd, 120, "rw"))) {
535       /* If we had to use sendmail, add subject */
536       if (!d->mail_cmd) {
537          fprintf(bpipe->wfd, "Subject: %s\r\n\r\n", _("Bacula Message"));
538       }
539    } else {
540       berrno be;
541       delivery_error(_("open mail pipe %s failed: ERR=%s\n"),
542          cmd, be.bstrerror());
543    }
544    return bpipe;
545 }
546
547 /*
548  * Close the messages for this Messages resource, which means to close
549  *  any open files, and dispatch any pending email messages.
550  */
551 void close_msg(JCR *jcr)
552 {
553    MSGS *msgs;
554    DEST *d;
555    BPIPE *bpipe;
556    POOLMEM *cmd, *line;
557    int len, stat;
558
559    Dmsg1(580, "Close_msg jcr=%p\n", jcr);
560
561    if (jcr == NULL) {                /* NULL -> global chain */
562       msgs = daemon_msgs;
563    } else {
564       msgs = jcr->jcr_msgs;
565       jcr->jcr_msgs = NULL;
566    }
567    if (msgs == NULL) {
568       return;
569    }
570
571    /* Wait for item to be not in use, then mark closing */
572    if (msgs->is_closing()) {
573       return;
574    }
575    msgs->wait_not_in_use();          /* leaves fides_mutex set */
576    /* Note get_closing() does not lock because we are already locked */
577    if (msgs->get_closing()) {
578       msgs->unlock();
579       return;
580    }
581    msgs->set_closing();
582    msgs->unlock();
583
584    Dmsg1(850, "===Begin close msg resource at %p\n", msgs);
585    cmd = get_pool_memory(PM_MESSAGE);
586    for (d=msgs->dest_chain; d; ) {
587       if (d->fd) {
588          switch (d->dest_code) {
589          case MD_FILE:
590          case MD_APPEND:
591             if (d->fd) {
592                fclose(d->fd);            /* close open file descriptor */
593                d->fd = NULL;
594             }
595             break;
596          case MD_MAIL:
597          case MD_MAIL_ON_ERROR:
598          case MD_MAIL_ON_SUCCESS:
599             Dmsg0(850, "Got MD_MAIL, MD_MAIL_ON_ERROR or MD_MAIL_ON_SUCCESS\n");
600             if (!d->fd) {
601                break;
602             }
603
604             switch (d->dest_code) {
605             case MD_MAIL_ON_ERROR:
606                if (jcr) {
607                   switch (jcr->JobStatus) {
608                   case JS_Terminated:
609                   case JS_Warnings:
610                      goto rem_temp_file;
611                   default:
612                      break;
613                   }
614                }
615                break;
616             case MD_MAIL_ON_SUCCESS:
617                if (jcr) {
618                   switch (jcr->JobStatus) {
619                   case JS_Terminated:
620                   case JS_Warnings:
621                      break;
622                   default:
623                      goto rem_temp_file;
624                   }
625                }
626                break;
627             default:
628                break;
629             }
630
631             if (!(bpipe=open_mail_pipe(jcr, cmd, d))) {
632                Pmsg0(000, _("open mail pipe failed.\n"));
633                goto rem_temp_file;
634             }
635
636             Dmsg0(850, "Opened mail pipe\n");
637             len = d->max_len+10;
638             line = get_memory(len);
639             rewind(d->fd);
640             while (fgets(line, len, d->fd)) {
641                fputs(line, bpipe->wfd);
642             }
643             if (!close_wpipe(bpipe)) {       /* close write pipe sending mail */
644                berrno be;
645                Pmsg1(000, _("close error: ERR=%s\n"), be.bstrerror());
646             }
647
648             /*
649              * Since we are closing all messages, before "recursing"
650              * make sure we are not closing the daemon messages, otherwise
651              * kaboom.
652              */
653             if (msgs != daemon_msgs) {
654                /* read what mail prog returned -- should be nothing */
655                while (fgets(line, len, bpipe->rfd)) {
656                   delivery_error(_("Mail prog: %s"), line);
657                }
658             }
659
660             stat = close_bpipe(bpipe);
661             if (stat != 0 && msgs != daemon_msgs) {
662                berrno be;
663                be.set_errno(stat);
664                Dmsg1(850, "Calling emsg. CMD=%s\n", cmd);
665                delivery_error(_("Mail program terminated in error.\n"
666                                  "CMD=%s\n"
667                                  "ERR=%s\n"), cmd, be.bstrerror());
668             }
669             free_memory(line);
670 rem_temp_file:
671             /* Remove temp mail file */
672             if (d->fd) {
673               fclose(d->fd);
674               d->fd = NULL;
675             }
676             /* Exclude spaces in mail_filename */
677             if (d->mail_filename) {
678                safer_unlink(d->mail_filename, MAIL_REGEX);
679                free_pool_memory(d->mail_filename);
680                d->mail_filename = NULL;
681             }
682             Dmsg0(850, "end mail or mail on error\n");
683             break;
684          default:
685             break;
686          }
687          d->fd = NULL;
688       }
689       d = d->next;                    /* point to next buffer */
690    }
691    free_pool_memory(cmd);
692    Dmsg0(850, "Done walking message chain.\n");
693    if (jcr) {
694       free_msgs_res(msgs);
695       msgs = NULL;
696    } else {
697       msgs->clear_closing();
698    }
699    Dmsg0(850, "===End close msg resource\n");
700 }
701
702 /*
703  * Free memory associated with Messages resource
704  */
705 void free_msgs_res(MSGS *msgs)
706 {
707    DEST *d, *old;
708
709    /* Walk down the message chain releasing allocated buffers */
710    for (d=msgs->dest_chain; d; ) {
711       if (d->where) {
712          free(d->where);
713          d->where = NULL;
714       }
715       if (d->mail_cmd) {
716          free(d->mail_cmd);
717          d->mail_cmd = NULL;
718       }
719       old = d;                        /* save pointer to release */
720       d = d->next;                    /* point to next buffer */
721       free(old);                      /* free the destination item */
722    }
723    msgs->dest_chain = NULL;
724    free(msgs);                        /* free the head */
725 }
726
727
728 /*
729  * Terminate the message handler for good.
730  * Release the global destination chain.
731  *
732  * Also, clean up a few other items (cons, exepath). Note,
733  *   these really should be done elsewhere.
734  */
735 void term_msg()
736 {
737    Dmsg0(850, "Enter term_msg\n");
738    close_msg(NULL);                   /* close global chain */
739    free_msgs_res(daemon_msgs);        /* free the resources */
740    daemon_msgs = NULL;
741    if (con_fd) {
742       fflush(con_fd);
743       fclose(con_fd);
744       con_fd = NULL;
745    }
746    if (exepath) {
747       free(exepath);
748       exepath = NULL;
749    }
750    if (exename) {
751       free(exename);
752       exename = NULL;
753    }
754    if (trace_fd) {
755       fclose(trace_fd);
756       trace_fd = NULL;
757    }
758    if (catalog_db) {
759       free(catalog_db);
760       catalog_db = NULL;
761    }
762    term_last_jobs_list();
763 }
764
765 static bool open_dest_file(JCR *jcr, DEST *d, const char *mode)
766 {
767    d->fd = fopen(d->where, mode);
768    if (!d->fd) {
769       berrno be;
770       delivery_error(_("fopen %s failed: ERR=%s\n"), d->where, be.bstrerror());
771       return false;
772    }
773    return true;
774 }
775
776 /* Split the output for syslog (it converts \n to ' ' and is
777  *   limited to 1024 characters per syslog message
778  */
779 static void send_to_syslog(int mode, const char *msg)
780 {
781    int len;
782    char buf[1024];
783    const char *p2;
784    const char *p = msg;
785
786    while (*p && ((p2 = strchr(p, '\n')) != NULL)) {
787       len = MIN((int)sizeof(buf) - 1, p2 - p + 1); /* Add 1 to keep \n */
788       strncpy(buf, p, len);
789       buf[len] = 0;
790       syslog(mode, "%s", buf);
791       p = p2+1;                 /* skip \n */
792    }
793    if (*p != 0) {               /* no \n at the end ? */
794       syslog(mode, "%s", p);
795    }
796 }
797
798 /*
799  * Handle sending the message to the appropriate place
800  */
801 void dispatch_message(JCR *jcr, int type, utime_t mtime, char *msg)
802 {
803     DEST *d;
804     char dt[MAX_TIME_LENGTH];
805     POOLMEM *mcmd;
806     int len, dtlen;
807     MSGS *msgs;
808     BPIPE *bpipe;
809     const char *mode;
810
811     Dmsg2(850, "Enter dispatch_msg type=%d msg=%s", type, msg);
812
813     /*
814      * Most messages are prefixed by a date and time. If mtime is
815      *  zero, then we use the current time.  If mtime is 1 (special
816      *  kludge), we do not prefix the date and time. Otherwise,
817      *  we assume mtime is a utime_t and use it.
818      */
819     if (mtime == 0) {
820        mtime = time(NULL);
821     }
822     if (mtime == 1) {
823        *dt = 0;
824        dtlen = 0;
825        mtime = time(NULL);      /* get time for SQL log */
826     } else {
827        bstrftime_ny(dt, sizeof(dt), mtime);
828        dtlen = strlen(dt);
829        dt[dtlen++] = ' ';
830        dt[dtlen] = 0;
831     }
832
833     /* If the program registered a callback, send it there */
834     if (message_callback) {
835        message_callback(type, msg);
836        return;
837     }
838
839     /* For serious errors make sure message is printed or logged */
840     if (type == M_ABORT || type == M_ERROR_TERM) {
841        fputs(dt, stdout);
842        fputs(msg, stdout);
843        fflush(stdout);
844        if (type == M_ABORT) {
845           syslog(LOG_DAEMON|LOG_ERR, "%s", msg);
846        }
847     }
848
849
850     /* Now figure out where to send the message */
851     msgs = NULL;
852     if (!jcr) {
853        jcr = get_jcr_from_tsd();
854     }
855     if (jcr) {
856        msgs = jcr->jcr_msgs;
857     }
858     if (msgs == NULL) {
859        msgs = daemon_msgs;
860     }
861     /*
862      * If closing this message resource, print and send to syslog,
863      *   then get out.
864      */
865     if (msgs->is_closing()) {
866        fputs(dt, stdout);
867        fputs(msg, stdout);
868        fflush(stdout);
869        syslog(LOG_DAEMON|LOG_ERR, "%s", msg);
870        return;
871     }
872
873     for (d=msgs->dest_chain; d; d=d->next) {
874        if (bit_is_set(type, d->msg_types)) {
875           switch (d->dest_code) {
876              case MD_CATALOG:
877                 char ed1[50];
878                 if (!jcr || !jcr->db) {
879                    break;
880                 }
881                 if (p_sql_query && p_sql_escape) {
882                    POOLMEM *cmd = get_pool_memory(PM_MESSAGE);
883                    POOLMEM *esc_msg = get_pool_memory(PM_MESSAGE);
884
885                    int len = strlen(msg) + 1;
886                    esc_msg = check_pool_memory_size(esc_msg, len * 2 + 1);
887                    if (p_sql_escape(jcr, jcr->db, esc_msg, msg, len)) {
888                       bstrutime(dt, sizeof(dt), mtime);
889                       Mmsg(cmd, "INSERT INTO Log (JobId, Time, LogText) VALUES (%s,'%s','%s')",
890                             edit_int64(jcr->JobId, ed1), dt, esc_msg);
891                       if (!p_sql_query(jcr, cmd)) {
892                          delivery_error(_("Msg delivery error: Unable to store data in database.\n"));
893                       }
894                    } else {
895                       delivery_error(_("Msg delivery error: Unable to store data in database.\n"));
896                    }
897
898                    free_pool_memory(cmd);
899                    free_pool_memory(esc_msg);
900                 }
901                 break;
902              case MD_CONSOLE:
903                 Dmsg1(850, "CONSOLE for following msg: %s", msg);
904                 if (!con_fd) {
905                    con_fd = fopen(con_fname, "a+b");
906                    Dmsg0(850, "Console file not open.\n");
907                 }
908                 if (con_fd) {
909                    Pw(con_lock);      /* get write lock on console message file */
910                    errno = 0;
911                    if (dtlen) {
912                       (void)fwrite(dt, dtlen, 1, con_fd);
913                    }
914                    len = strlen(msg);
915                    if (len > 0) {
916                       (void)fwrite(msg, len, 1, con_fd);
917                       if (msg[len-1] != '\n') {
918                          (void)fwrite("\n", 2, 1, con_fd);
919                       }
920                    } else {
921                       (void)fwrite("\n", 2, 1, con_fd);
922                    }
923                    fflush(con_fd);
924                    console_msg_pending = true;
925                    Vw(con_lock);
926                 }
927                 break;
928              case MD_SYSLOG:
929                 Dmsg1(850, "SYSLOG for following msg: %s\n", msg);
930                 /*
931                  * We really should do an openlog() here.
932                  */
933                 send_to_syslog(LOG_DAEMON|LOG_ERR, msg);
934                 break;
935              case MD_OPERATOR:
936                 Dmsg1(850, "OPERATOR for following msg: %s\n", msg);
937                 mcmd = get_pool_memory(PM_MESSAGE);
938                 if ((bpipe=open_mail_pipe(jcr, mcmd, d))) {
939                    int stat;
940                    fputs(dt, bpipe->wfd);
941                    fputs(msg, bpipe->wfd);
942                    /* Messages to the operator go one at a time */
943                    stat = close_bpipe(bpipe);
944                    if (stat != 0) {
945                       berrno be;
946                       be.set_errno(stat);
947                       delivery_error(_("Msg delivery error: Operator mail program terminated in error.\n"
948                             "CMD=%s\n"
949                             "ERR=%s\n"), mcmd, be.bstrerror());
950                    }
951                 }
952                 free_pool_memory(mcmd);
953                 break;
954              case MD_MAIL:
955              case MD_MAIL_ON_ERROR:
956              case MD_MAIL_ON_SUCCESS:
957                 Dmsg1(850, "MAIL for following msg: %s", msg);
958                 if (msgs->is_closing()) {
959                    break;
960                 }
961                 msgs->set_in_use();
962                 if (!d->fd) {
963                    POOLMEM *name = get_pool_memory(PM_MESSAGE);
964                    make_unique_mail_filename(jcr, name, d);
965                    d->fd = fopen(name, "w+b");
966                    if (!d->fd) {
967                       berrno be;
968                       delivery_error(_("Msg delivery error: fopen %s failed: ERR=%s\n"), name,
969                             be.bstrerror());
970                       free_pool_memory(name);
971                       msgs->clear_in_use();
972                       break;
973                    }
974                    d->mail_filename = name;
975                 }
976                 fputs(dt, d->fd);
977                 len = strlen(msg) + dtlen;;
978                 if (len > d->max_len) {
979                    d->max_len = len;      /* keep max line length */
980                 }
981                 fputs(msg, d->fd);
982                 msgs->clear_in_use();
983                 break;
984              case MD_APPEND:
985                 Dmsg1(850, "APPEND for following msg: %s", msg);
986                 mode = "ab";
987                 goto send_to_file;
988              case MD_FILE:
989                 Dmsg1(850, "FILE for following msg: %s", msg);
990                 mode = "w+b";
991 send_to_file:
992                 if (msgs->is_closing()) {
993                    break;
994                 }
995                 msgs->set_in_use();
996                 if (!d->fd && !open_dest_file(jcr, d, mode)) {
997                    msgs->clear_in_use();
998                    break;
999                 }
1000                 fputs(dt, d->fd);
1001                 fputs(msg, d->fd);
1002                 /* On error, we close and reopen to handle log rotation */
1003                 if (ferror(d->fd)) {
1004                    fclose(d->fd);
1005                    d->fd = NULL;
1006                    if (open_dest_file(jcr, d, mode)) {
1007                       fputs(dt, d->fd);
1008                       fputs(msg, d->fd);
1009                    }
1010                 }
1011                 msgs->clear_in_use();
1012                 break;
1013              case MD_DIRECTOR:
1014                 Dmsg1(850, "DIRECTOR for following msg: %s", msg);
1015                 if (jcr && jcr->dir_bsock && !jcr->dir_bsock->errors) {
1016                    jcr->dir_bsock->fsend("Jmsg Job=%s type=%d level=%lld %s",
1017                       jcr->Job, type, mtime, msg);
1018                 } else {
1019                    Dmsg1(800, "no jcr for following msg: %s", msg);
1020                 }
1021                 break;
1022              case MD_STDOUT:
1023                 Dmsg1(850, "STDOUT for following msg: %s", msg);
1024                 if (type != M_ABORT && type != M_ERROR_TERM) { /* already printed */
1025                    fputs(dt, stdout);
1026                    fputs(msg, stdout);
1027                    fflush(stdout);
1028                 }
1029                 break;
1030              case MD_STDERR:
1031                 Dmsg1(850, "STDERR for following msg: %s", msg);
1032                 fputs(dt, stderr);
1033                 fputs(msg, stderr);
1034                 fflush(stdout);
1035                 break;
1036              default:
1037                 break;
1038           }
1039        }
1040     }
1041 }
1042
1043 /*********************************************************************
1044  *
1045  *  This subroutine returns the filename portion of a path.
1046  *  It is used because some compilers set __FILE__
1047  *  to the full path.  Try to return base + next higher path.
1048  */
1049
1050 const char *get_basename(const char *pathname)
1051 {
1052    const char *basename;
1053
1054    if ((basename = bstrrpath(pathname, pathname+strlen(pathname))) == pathname) {
1055       /* empty */
1056    } else if ((basename = bstrrpath(pathname, basename-1)) == pathname) {
1057       /* empty */
1058    } else {
1059       basename++;
1060    }
1061    return basename;
1062 }
1063
1064 /*
1065  * print or write output to trace file
1066  */
1067 static void pt_out(char *buf)
1068 {
1069     /*
1070      * Used the "trace on" command in the console to turn on
1071      *  output to the trace file.  "trace off" will close the file.
1072      */
1073     if (trace) {
1074        if (!trace_fd) {
1075           char fn[200];
1076           bsnprintf(fn, sizeof(fn), "%s/%s.trace", working_directory ? working_directory : "./", my_name);
1077           trace_fd = fopen(fn, "a+b");
1078        }
1079        if (trace_fd) {
1080           fputs(buf, trace_fd);
1081           fflush(trace_fd);
1082           return;
1083        } else {
1084           /* Some problem, turn off tracing */
1085           trace = false;
1086        }
1087     }
1088     /* not tracing */
1089     fputs(buf, stdout);
1090     fflush(stdout);
1091 }
1092
1093 /*********************************************************************
1094  *
1095  *  This subroutine prints a debug message if the level number
1096  *  is less than or equal the debug_level. File and line numbers
1097  *  are included for more detail if desired, but not currently
1098  *  printed.
1099  *
1100  *  If the level is negative, the details of file and line number
1101  *  are not printed.
1102  */
1103 void
1104 d_msg(const char *file, int line, int64_t level, const char *fmt,...)
1105 {
1106     char      buf[5000];
1107     int       len;
1108     va_list   arg_ptr;
1109     bool      details = true;
1110     utime_t   mtime;
1111
1112     if (level < 0) {
1113        details = false;
1114        level = -level;
1115     }
1116
1117     if (chk_dbglvl(level)) {
1118        if (dbg_timestamp) {
1119           mtime = time(NULL);
1120           bstrftimes(buf, sizeof(buf), mtime);
1121           len = strlen(buf);
1122           buf[len++] = ' ';
1123           buf[len] = 0;
1124           pt_out(buf);
1125        }
1126
1127 #ifdef FULL_LOCATION
1128        if (details) {
1129           len = bsnprintf(buf, sizeof(buf), "%s: %s:%d-%u ",
1130                 my_name, get_basename(file), line, get_jobid_from_tsd());
1131        } else {
1132           len = 0;
1133        }
1134 #else
1135        len = 0;
1136 #endif
1137        va_start(arg_ptr, fmt);
1138        bvsnprintf(buf+len, sizeof(buf)-len, (char *)fmt, arg_ptr);
1139        va_end(arg_ptr);
1140
1141        pt_out(buf);
1142     }
1143 }
1144
1145 /*
1146  * Set trace flag on/off. If argument is negative, there is no change
1147  */
1148 void set_trace(int trace_flag)
1149 {
1150    if (trace_flag < 0) {
1151       return;
1152    } else if (trace_flag > 0) {
1153       trace = true;
1154    } else {
1155       trace = false;
1156    }
1157    if (!trace && trace_fd) {
1158       FILE *ltrace_fd = trace_fd;
1159       trace_fd = NULL;
1160       bmicrosleep(0, 100000);         /* yield to prevent seg faults */
1161       fclose(ltrace_fd);
1162    }
1163 }
1164
1165 void set_hangup(int hangup_value)
1166 {
1167    if (hangup_value < 0) {
1168       return;
1169    } else {
1170       hangup = hangup_value;
1171    }
1172 }
1173
1174 int get_hangup(void)
1175 {
1176    return hangup;
1177 }
1178
1179 bool get_trace(void)
1180 {
1181    return trace;
1182 }
1183
1184 /*********************************************************************
1185  *
1186  *  This subroutine prints a message regardless of the debug level
1187  *
1188  *  If the level is negative, the details of file and line number
1189  *  are not printed.
1190  */
1191 void
1192 p_msg(const char *file, int line, int level, const char *fmt,...)
1193 {
1194     char      buf[5000];
1195     int       len;
1196     va_list   arg_ptr;
1197
1198 #ifdef FULL_LOCATION
1199     if (level >= 0) {
1200        len = bsnprintf(buf, sizeof(buf), "%s: %s:%d-%u ",
1201              my_name, get_basename(file), line, get_jobid_from_tsd());
1202     } else {
1203        len = 0;
1204     }
1205 #else
1206        len = 0;
1207 #endif
1208
1209     va_start(arg_ptr, fmt);
1210     bvsnprintf(buf+len, sizeof(buf)-len, (char *)fmt, arg_ptr);
1211     va_end(arg_ptr);
1212
1213     pt_out(buf);
1214 }
1215
1216
1217 /*********************************************************************
1218  *
1219  *  subroutine writes a debug message to the trace file if the level number
1220  *  is less than or equal the debug_level. File and line numbers
1221  *  are included for more detail if desired, but not currently
1222  *  printed.
1223  *
1224  *  If the level is negative, the details of file and line number
1225  *  are not printed.
1226  */
1227 void
1228 t_msg(const char *file, int line, int64_t level, const char *fmt,...)
1229 {
1230     char      buf[5000];
1231     int       len;
1232     va_list   arg_ptr;
1233     int       details = TRUE;
1234
1235     if (level < 0) {
1236        details = FALSE;
1237        level = -level;
1238     }
1239
1240     if (chk_dbglvl(level)) {
1241        if (!trace_fd) {
1242           bsnprintf(buf, sizeof(buf), "%s/%s.trace", working_directory ? working_directory : ".", my_name);
1243           trace_fd = fopen(buf, "a+b");
1244        }
1245
1246 #ifdef FULL_LOCATION
1247        if (details) {
1248           len = bsnprintf(buf, sizeof(buf), "%s: %s:%d ", my_name, get_basename(file), line);
1249        } else {
1250           len = 0;
1251        }
1252 #else
1253        len = 0;
1254 #endif
1255        va_start(arg_ptr, fmt);
1256        bvsnprintf(buf+len, sizeof(buf)-len, (char *)fmt, arg_ptr);
1257        va_end(arg_ptr);
1258        if (trace_fd != NULL) {
1259            fputs(buf, trace_fd);
1260            fflush(trace_fd);
1261        }
1262    }
1263 }
1264
1265 /* *********************************************************
1266  *
1267  * print an error message
1268  *
1269  */
1270 void
1271 e_msg(const char *file, int line, int type, int level, const char *fmt,...)
1272 {
1273     char     buf[5000];
1274     va_list   arg_ptr;
1275     int len;
1276
1277     /*
1278      * Check if we have a message destination defined.
1279      * We always report M_ABORT and M_ERROR_TERM
1280      */
1281     if (!daemon_msgs || ((type != M_ABORT && type != M_ERROR_TERM) &&
1282                          !bit_is_set(type, daemon_msgs->send_msg))) {
1283        return;                        /* no destination */
1284     }
1285     switch (type) {
1286     case M_ABORT:
1287        len = bsnprintf(buf, sizeof(buf), _("%s: ABORTING due to ERROR in %s:%d\n"),
1288                my_name, get_basename(file), line);
1289        break;
1290     case M_ERROR_TERM:
1291        len = bsnprintf(buf, sizeof(buf), _("%s: ERROR TERMINATION at %s:%d\n"),
1292                my_name, get_basename(file), line);
1293        break;
1294     case M_FATAL:
1295        if (level == -1)            /* skip details */
1296           len = bsnprintf(buf, sizeof(buf), _("%s: Fatal Error because: "), my_name);
1297        else
1298           len = bsnprintf(buf, sizeof(buf), _("%s: Fatal Error at %s:%d because:\n"), my_name, get_basename(file), line);
1299        break;
1300     case M_ERROR:
1301        if (level == -1)            /* skip details */
1302           len = bsnprintf(buf, sizeof(buf), _("%s: ERROR: "), my_name);
1303        else
1304           len = bsnprintf(buf, sizeof(buf), _("%s: ERROR in %s:%d "), my_name, get_basename(file), line);
1305        break;
1306     case M_WARNING:
1307        len = bsnprintf(buf, sizeof(buf), _("%s: Warning: "), my_name);
1308        break;
1309     case M_SECURITY:
1310        len = bsnprintf(buf, sizeof(buf), _("%s: Security violation: "), my_name);
1311        break;
1312     default:
1313        len = bsnprintf(buf, sizeof(buf), "%s: ", my_name);
1314        break;
1315     }
1316
1317     va_start(arg_ptr, fmt);
1318     bvsnprintf(buf+len, sizeof(buf)-len, (char *)fmt, arg_ptr);
1319     va_end(arg_ptr);
1320
1321     dispatch_message(NULL, type, 0, buf);
1322
1323     if (type == M_ABORT) {
1324        char *p = 0;
1325        p[0] = 0;                      /* generate segmentation violation */
1326     }
1327     if (type == M_ERROR_TERM) {
1328        exit(1);
1329     }
1330 }
1331
1332 /* *********************************************************
1333  *
1334  * Generate a Job message
1335  *
1336  */
1337 void
1338 Jmsg(JCR *jcr, int type, utime_t mtime, const char *fmt,...)
1339 {
1340     char     rbuf[5000];
1341     va_list   arg_ptr;
1342     int len;
1343     MSGS *msgs;
1344     uint32_t JobId = 0;
1345
1346
1347     Dmsg1(850, "Enter Jmsg type=%d\n", type);
1348
1349     /* Special case for the console, which has a dir_bsock and JobId==0,
1350      *  in that case, we send the message directly back to the
1351      *  dir_bsock.
1352      */
1353     if (jcr && jcr->JobId == 0 && jcr->dir_bsock) {
1354        BSOCK *dir = jcr->dir_bsock;
1355        va_start(arg_ptr, fmt);
1356        dir->msglen = bvsnprintf(dir->msg, sizeof_pool_memory(dir->msg),
1357                                 fmt, arg_ptr);
1358        va_end(arg_ptr);
1359        jcr->dir_bsock->send();
1360        return;
1361     }
1362
1363     /* The watchdog thread can't use Jmsg directly, we always queued it */
1364     if (is_watchdog()) {
1365        va_start(arg_ptr, fmt);
1366        bvsnprintf(rbuf,  sizeof(rbuf), fmt, arg_ptr);
1367        va_end(arg_ptr);
1368        Qmsg(jcr, type, mtime, "%s", rbuf);
1369        return;
1370     }
1371
1372     msgs = NULL;
1373     if (!jcr) {
1374        jcr = get_jcr_from_tsd();
1375     }
1376     if (jcr) {
1377        if (!jcr->dequeuing_msgs) { /* Avoid recursion */
1378           /* Dequeue messages to keep the original order  */
1379           dequeue_messages(jcr);
1380        }
1381        msgs = jcr->jcr_msgs;
1382        JobId = jcr->JobId;
1383     }
1384     if (!msgs) {
1385        msgs = daemon_msgs;            /* if no jcr, we use daemon handler */
1386     }
1387
1388     /*
1389      * Check if we have a message destination defined.
1390      * We always report M_ABORT and M_ERROR_TERM
1391      */
1392     if (msgs && (type != M_ABORT && type != M_ERROR_TERM) &&
1393          !bit_is_set(type, msgs->send_msg)) {
1394        return;                        /* no destination */
1395     }
1396     switch (type) {
1397     case M_ABORT:
1398        len = bsnprintf(rbuf, sizeof(rbuf), _("%s ABORTING due to ERROR\n"), my_name);
1399        break;
1400     case M_ERROR_TERM:
1401        len = bsnprintf(rbuf, sizeof(rbuf), _("%s ERROR TERMINATION\n"), my_name);
1402        break;
1403     case M_FATAL:
1404        len = bsnprintf(rbuf, sizeof(rbuf), _("%s JobId %u: Fatal error: "), my_name, JobId);
1405        if (jcr) {
1406           jcr->setJobStatus(JS_FatalError);
1407        }
1408        if (jcr && jcr->JobErrors == 0) {
1409           jcr->JobErrors = 1;
1410        }
1411        break;
1412     case M_ERROR:
1413        len = bsnprintf(rbuf, sizeof(rbuf), _("%s JobId %u: Error: "), my_name, JobId);
1414        if (jcr) {
1415           jcr->JobErrors++;
1416        }
1417        break;
1418     case M_WARNING:
1419        len = bsnprintf(rbuf, sizeof(rbuf), _("%s JobId %u: Warning: "), my_name, JobId);
1420        if (jcr) {
1421           jcr->JobWarnings++;
1422        }
1423        break;
1424     case M_SECURITY:
1425        len = bsnprintf(rbuf, sizeof(rbuf), _("%s JobId %u: Security violation: "),
1426                my_name, JobId);
1427        break;
1428     default:
1429        len = bsnprintf(rbuf, sizeof(rbuf), "%s JobId %u: ", my_name, JobId);
1430        break;
1431     }
1432
1433     va_start(arg_ptr, fmt);
1434     bvsnprintf(rbuf+len,  sizeof(rbuf)-len, fmt, arg_ptr);
1435     va_end(arg_ptr);
1436
1437     dispatch_message(jcr, type, mtime, rbuf);
1438
1439     if (type == M_ABORT){
1440        char *p = 0;
1441        printf("Bacula forced SEG FAULT to obtain traceback.\n");
1442        syslog(LOG_DAEMON|LOG_ERR, "Bacula forced SEG FAULT to obtain traceback.\n");
1443        p[0] = 0;                      /* generate segmentation violation */
1444     }
1445     if (type == M_ERROR_TERM) {
1446        exit(1);
1447     }
1448 }
1449
1450 /*
1451  * If we come here, prefix the message with the file:line-number,
1452  *  then pass it on to the normal Jmsg routine.
1453  */
1454 void j_msg(const char *file, int line, JCR *jcr, int type, utime_t mtime, const char *fmt,...)
1455 {
1456    va_list   arg_ptr;
1457    int i, len, maxlen;
1458    POOLMEM *pool_buf;
1459
1460    pool_buf = get_pool_memory(PM_EMSG);
1461    i = Mmsg(pool_buf, "%s:%d ", get_basename(file), line);
1462
1463    for (;;) {
1464       maxlen = sizeof_pool_memory(pool_buf) - i - 1;
1465       va_start(arg_ptr, fmt);
1466       len = bvsnprintf(pool_buf+i, maxlen, fmt, arg_ptr);
1467       va_end(arg_ptr);
1468       if (len < 0 || len >= (maxlen-5)) {
1469          pool_buf = realloc_pool_memory(pool_buf, maxlen + i + maxlen/2);
1470          continue;
1471       }
1472       break;
1473    }
1474
1475    Jmsg(jcr, type, mtime, "%s", pool_buf);
1476    free_memory(pool_buf);
1477 }
1478
1479
1480 /*
1481  * Edit a message into a Pool memory buffer, with file:lineno
1482  */
1483 int m_msg(const char *file, int line, POOLMEM **pool_buf, const char *fmt, ...)
1484 {
1485    va_list   arg_ptr;
1486    int i, len, maxlen;
1487
1488    i = sprintf(*pool_buf, "%s:%d ", get_basename(file), line);
1489
1490    for (;;) {
1491       maxlen = sizeof_pool_memory(*pool_buf) - i - 1;
1492       va_start(arg_ptr, fmt);
1493       len = bvsnprintf(*pool_buf+i, maxlen, fmt, arg_ptr);
1494       va_end(arg_ptr);
1495       if (len < 0 || len >= (maxlen-5)) {
1496          *pool_buf = realloc_pool_memory(*pool_buf, maxlen + i + maxlen/2);
1497          continue;
1498       }
1499       break;
1500    }
1501    return len;
1502 }
1503
1504 int m_msg(const char *file, int line, POOLMEM *&pool_buf, const char *fmt, ...)
1505 {
1506    va_list   arg_ptr;
1507    int i, len, maxlen;
1508
1509    i = sprintf(pool_buf, "%s:%d ", get_basename(file), line);
1510
1511    for (;;) {
1512       maxlen = sizeof_pool_memory(pool_buf) - i - 1;
1513       va_start(arg_ptr, fmt);
1514       len = bvsnprintf(pool_buf+i, maxlen, fmt, arg_ptr);
1515       va_end(arg_ptr);
1516       if (len < 0 || len >= (maxlen-5)) {
1517          pool_buf = realloc_pool_memory(pool_buf, maxlen + i + maxlen/2);
1518          continue;
1519       }
1520       break;
1521    }
1522    return len;
1523 }
1524
1525
1526 /*
1527  * Edit a message into a Pool Memory buffer NO file:lineno
1528  *  Returns: string length of what was edited.
1529  */
1530 int Mmsg(POOLMEM **pool_buf, const char *fmt, ...)
1531 {
1532    va_list   arg_ptr;
1533    int len, maxlen;
1534
1535    for (;;) {
1536       maxlen = sizeof_pool_memory(*pool_buf) - 1;
1537       va_start(arg_ptr, fmt);
1538       len = bvsnprintf(*pool_buf, maxlen, fmt, arg_ptr);
1539       va_end(arg_ptr);
1540       if (len < 0 || len >= (maxlen-5)) {
1541          *pool_buf = realloc_pool_memory(*pool_buf, maxlen + maxlen/2);
1542          continue;
1543       }
1544       break;
1545    }
1546    return len;
1547 }
1548
1549 int Mmsg(POOLMEM *&pool_buf, const char *fmt, ...)
1550 {
1551    va_list   arg_ptr;
1552    int len, maxlen;
1553
1554    for (;;) {
1555       maxlen = sizeof_pool_memory(pool_buf) - 1;
1556       va_start(arg_ptr, fmt);
1557       len = bvsnprintf(pool_buf, maxlen, fmt, arg_ptr);
1558       va_end(arg_ptr);
1559       if (len < 0 || len >= (maxlen-5)) {
1560          pool_buf = realloc_pool_memory(pool_buf, maxlen + maxlen/2);
1561          continue;
1562       }
1563       break;
1564    }
1565    return len;
1566 }
1567
1568 int Mmsg(POOL_MEM &pool_buf, const char *fmt, ...)
1569 {
1570    va_list   arg_ptr;
1571    int len, maxlen;
1572
1573    for (;;) {
1574       maxlen = pool_buf.max_size() - 1;
1575       va_start(arg_ptr, fmt);
1576       len = bvsnprintf(pool_buf.c_str(), maxlen, fmt, arg_ptr);
1577       va_end(arg_ptr);
1578       if (len < 0 || len >= (maxlen-5)) {
1579          pool_buf.realloc_pm(maxlen + maxlen/2);
1580          continue;
1581       }
1582       break;
1583    }
1584    return len;
1585 }
1586
1587
1588 /*
1589  * We queue messages rather than print them directly. This
1590  *  is generally used in low level routines (msg handler, bnet)
1591  *  to prevent recursion (i.e. if you are in the middle of
1592  *  sending a message, it is a bit messy to recursively call
1593  *  yourself when the bnet packet is not reentrant).
1594  */
1595 void Qmsg(JCR *jcr, int type, utime_t mtime, const char *fmt,...)
1596 {
1597    va_list   arg_ptr;
1598    int len, maxlen;
1599    POOLMEM *pool_buf;
1600    MQUEUE_ITEM *item;
1601
1602    pool_buf = get_pool_memory(PM_EMSG);
1603
1604    for (;;) {
1605       maxlen = sizeof_pool_memory(pool_buf) - 1;
1606       va_start(arg_ptr, fmt);
1607       len = bvsnprintf(pool_buf, maxlen, fmt, arg_ptr);
1608       va_end(arg_ptr);
1609       if (len < 0 || len >= (maxlen-5)) {
1610          pool_buf = realloc_pool_memory(pool_buf, maxlen + maxlen/2);
1611          continue;
1612       }
1613       break;
1614    }
1615    item = (MQUEUE_ITEM *)malloc(sizeof(MQUEUE_ITEM) + strlen(pool_buf) + 1);
1616    item->type = type;
1617    item->mtime = time(NULL);
1618    strcpy(item->msg, pool_buf);
1619    if (!jcr) {
1620       jcr = get_jcr_from_tsd();
1621    }
1622    /* If no jcr or no queue or dequeuing send to syslog */
1623    if (!jcr || !jcr->msg_queue || jcr->dequeuing_msgs) {
1624       syslog(LOG_DAEMON|LOG_ERR, "%s", item->msg);
1625       free(item);
1626    } else {
1627       /* Queue message for later sending */
1628       P(jcr->msg_queue_mutex);
1629       jcr->msg_queue->append(item);
1630       V(jcr->msg_queue_mutex);
1631    }
1632    free_memory(pool_buf);
1633 }
1634
1635 /*
1636  * Dequeue messages
1637  */
1638 void dequeue_messages(JCR *jcr)
1639 {
1640    MQUEUE_ITEM *item;
1641    if (!jcr->msg_queue) {
1642       return;
1643    }
1644    P(jcr->msg_queue_mutex);
1645    jcr->dequeuing_msgs = true;
1646    foreach_dlist(item, jcr->msg_queue) {
1647       Jmsg(jcr, item->type, item->mtime, "%s", item->msg);
1648    }
1649    /* Remove messages just sent */
1650    jcr->msg_queue->destroy();
1651    jcr->dequeuing_msgs = false;
1652    V(jcr->msg_queue_mutex);
1653 }
1654
1655
1656 /*
1657  * If we come here, prefix the message with the file:line-number,
1658  *  then pass it on to the normal Qmsg routine.
1659  */
1660 void q_msg(const char *file, int line, JCR *jcr, int type, utime_t mtime, const char *fmt,...)
1661 {
1662    va_list   arg_ptr;
1663    int i, len, maxlen;
1664    POOLMEM *pool_buf;
1665
1666    pool_buf = get_pool_memory(PM_EMSG);
1667    i = Mmsg(pool_buf, "%s:%d ", get_basename(file), line);
1668
1669    for (;;) {
1670       maxlen = sizeof_pool_memory(pool_buf) - i - 1;
1671       va_start(arg_ptr, fmt);
1672       len = bvsnprintf(pool_buf+i, maxlen, fmt, arg_ptr);
1673       va_end(arg_ptr);
1674       if (len < 0 || len >= (maxlen-5)) {
1675          pool_buf = realloc_pool_memory(pool_buf, maxlen + i + maxlen/2);
1676          continue;
1677       }
1678       break;
1679    }
1680
1681    Qmsg(jcr, type, mtime, "%s", pool_buf);
1682    free_memory(pool_buf);
1683 }
1684
1685
1686 /* not all in alphabetical order.  New commands are added after existing commands with similar letters
1687    to prevent breakage of existing user scripts.  */
1688 struct debugtags {
1689    const char *tag;             /* command */
1690    int64_t     bit;             /* bit to set */
1691    const char *help;            /* main purpose */
1692 };
1693
1694 /* setdebug tag=all,-plugin */
1695 static struct debugtags debug_tags[] = {
1696  { NT_("lock"),        DT_LOCK,     _("Debug lock information")},
1697  { NT_("network"),     DT_NETWORK,  _("Debug network information")},
1698  { NT_("plugin"),      DT_PLUGIN,   _("Debug plugin information")},
1699  { NT_("volume"),      DT_VOLUME,   _("Debug volume information")},
1700  { NT_("sql"),         DT_SQL,      _("Debug SQL queries")},
1701  { NT_("bvfs"),        DT_BVFS,     _("Debug BVFS queries")},
1702  { NT_("memory"),      DT_MEMORY,   _("Debug memory allocation")},
1703  { NT_("scheduler"),   DT_SCHEDULER,_("Debug scheduler information")},
1704  { NT_("protocol"),    DT_PROTOCOL, _("Debug protocol information")},
1705  { NT_("all"),         DT_ALL,      _("Debug all information")},
1706  { NULL,               0,   NULL}
1707 };
1708
1709 /* Allow +-, */
1710 bool debug_find_tag(const char *tagname, bool add, int64_t *current_level)
1711 {
1712    Dmsg3(010, "add=%d tag=%s level=%lld\n", add, tagname, *current_level);
1713    if (!*tagname) {
1714       /* Nothing in the buffer */
1715       return true;
1716    }
1717    for (int i=0; debug_tags[i].tag ; i++) {
1718       if (strcasecmp(debug_tags[i].tag, tagname) == 0) {
1719          if (add) {
1720             *current_level |= debug_tags[i].bit;
1721          } else {
1722             *current_level &= ~(debug_tags[i].bit);
1723          }
1724          return true;
1725       }
1726    }
1727    return false;
1728 }
1729
1730 bool debug_parse_tags(const char *options, int64_t *current_level)
1731 {
1732    bool operation;              /* + => true, - false */
1733    char *p, *t, tag[256];
1734    int max = sizeof(tag) - 1;
1735    bool ret=true;
1736    int64_t level= *current_level;
1737
1738    t = tag;
1739    *tag = 0;
1740    operation = true;            /* add by default */
1741
1742    if (!options) {
1743       Dmsg0(100, "No options for tags\n");
1744       return false;
1745    }
1746
1747    for (p = (char *)options; *p ; p++) {
1748       if (*p == ',' || *p == '+' || *p == '-' || *p == '!') {
1749          /* finish tag keyword */
1750          *t = 0;
1751          /* handle tag */
1752          ret &= debug_find_tag(tag, operation, &level);
1753
1754          if (*p == ',') {
1755             /* reset tag */
1756             t = tag;
1757             *tag = 0;
1758             operation = true;
1759
1760          } else {
1761             /* reset tag */
1762             t = tag;
1763             *tag = 0;
1764             operation = (*p == '+');
1765          }
1766
1767       } else if (isalpha(*p) && (t - tag) < max) {
1768          *t++ = *p;
1769
1770       } else {                  /* not isalpha or too long */
1771          Dmsg1(010, "invalid %c\n", *p);
1772          return false;
1773       }
1774    }
1775
1776    /* At the end, finish the string and look it */
1777    *t = 0;
1778    if (t > tag) {               /* something found */
1779       /* handle tag */
1780       ret &= debug_find_tag(tag, operation, &level);
1781    }
1782
1783    *current_level = level;
1784    return ret;
1785 }