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