]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/message.c
Add temporary fix to avoid a deadlock after a reload command on an incorrect configur...
[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
838 /* Temporary fix for a deadlock in the reload command when
839  * the configuration has a problem. The JCR chain is locked
840  * during the reload, we cannot create a new JCR.
841  */
842 #if 0
843     if (!jcr) {
844        jcr = new_jcr(sizeof(JCR), NULL);
845        created_jcr = true;
846     }
847 #endif
848
849     if (jcr) {
850        msgs = jcr->jcr_msgs;
851     }
852     if (msgs == NULL) {
853        msgs = daemon_msgs;
854     }
855     /*
856      * If closing this message resource, print and send to syslog,
857      *   then get out.
858      */
859     if (msgs->is_closing()) {
860        fputs(dt, stdout);
861        fputs(msg, stdout);
862        fflush(stdout);
863        syslog(LOG_DAEMON|LOG_ERR, "%s", msg);
864        return;
865     }
866
867
868     for (d=msgs->dest_chain; d; d=d->next) {
869        if (bit_is_set(type, d->msg_types)) {
870           bool ok;
871           switch (d->dest_code) {
872              case MD_CATALOG:
873                 char ed1[50];
874                 if (!jcr || !jcr->db) { 
875                    break;
876                 }
877                 if (p_sql_query && p_sql_escape) {
878                    POOLMEM *cmd = get_pool_memory(PM_MESSAGE);
879                    POOLMEM *esc_msg = get_pool_memory(PM_MESSAGE);
880
881                    int len = strlen(msg) + 1;
882                    esc_msg = check_pool_memory_size(esc_msg, len*2+1);
883                    ok = p_sql_escape(jcr, jcr->db, esc_msg, msg, len);
884                    if (ok) {
885                       bstrutime(dt, sizeof(dt), mtime); 
886                       Mmsg(cmd, "INSERT INTO Log (JobId, Time, LogText) VALUES (%s,'%s','%s')", 
887                            edit_int64(jcr->JobId, ed1), dt, esc_msg);
888                       ok = p_sql_query(jcr, cmd);
889                    } 
890                    if (!ok) {
891                       delivery_error(_("Message delivery error: Unable to store data in database.\n"));
892                    } 
893                    free_pool_memory(cmd);
894                    free_pool_memory(esc_msg);
895                 }
896                 break;
897              case MD_CONSOLE:
898                 Dmsg1(850, "CONSOLE for following msg: %s", msg);
899                 if (!con_fd) {
900                    con_fd = bfopen(con_fname, "a+b");
901                    Dmsg0(850, "Console file not open.\n");
902                 }
903                 if (con_fd) {
904                    Pw(con_lock);      /* get write lock on console message file */
905                    errno = 0;
906                    if (dtlen) {
907                       (void)fwrite(dt, dtlen, 1, con_fd);
908                    }
909                    len = strlen(msg);
910                    if (len > 0) {
911                       (void)fwrite(msg, len, 1, con_fd);
912                       if (msg[len-1] != '\n') {
913                          (void)fwrite("\n", 2, 1, con_fd);
914                       }
915                    } else {
916                       (void)fwrite("\n", 2, 1, con_fd);
917                    }
918                    fflush(con_fd);
919                    console_msg_pending = true;
920                    Vw(con_lock);
921                 }
922                 break;
923              case MD_SYSLOG:
924                 Dmsg1(850, "SYSLOG for following msg: %s\n", msg);
925                 /*
926                  * We really should do an openlog() here.
927                  */
928                 send_to_syslog(LOG_DAEMON|LOG_ERR, msg);
929                 break;
930              case MD_OPERATOR:
931                 Dmsg1(850, "OPERATOR for following msg: %s\n", msg);
932                 mcmd = get_pool_memory(PM_MESSAGE);
933                 if ((bpipe=open_mail_pipe(jcr, mcmd, d))) {
934                    int stat;
935                    fputs(dt, bpipe->wfd);
936                    fputs(msg, bpipe->wfd);
937                    /* Messages to the operator go one at a time */
938                    stat = close_bpipe(bpipe);
939                    if (stat != 0) {
940                       berrno be;
941                       be.set_errno(stat);
942                       delivery_error(_("Msg delivery error: Operator mail program terminated in error.\n"
943                             "CMD=%s\n"
944                             "ERR=%s\n"), mcmd, be.bstrerror());
945                    }
946                 }
947                 free_pool_memory(mcmd);
948                 break;
949              case MD_MAIL:
950              case MD_MAIL_ON_ERROR:
951              case MD_MAIL_ON_SUCCESS:
952                 Dmsg1(850, "MAIL for following msg: %s", msg);
953                 if (msgs->is_closing()) {
954                    break;
955                 }
956                 msgs->set_in_use();
957                 if (!d->fd) {
958                    POOLMEM *name = get_pool_memory(PM_MESSAGE);
959                    make_unique_mail_filename(jcr, name, d);
960                    d->fd = bfopen(name, "w+b");
961                    if (!d->fd) {
962                       berrno be;
963                       delivery_error(_("Msg delivery error: fopen %s failed: ERR=%s\n"), name,
964                             be.bstrerror());
965                       free_pool_memory(name);
966                       msgs->clear_in_use();
967                       break;
968                    }
969                    d->mail_filename = name;
970                 }
971                 fputs(dt, d->fd);
972                 len = strlen(msg) + dtlen;;
973                 if (len > d->max_len) {
974                    d->max_len = len;      /* keep max line length */
975                 }
976                 fputs(msg, d->fd);
977                 msgs->clear_in_use();
978                 break;
979              case MD_APPEND:
980                 Dmsg1(850, "APPEND for following msg: %s", msg);
981                 mode = "ab";
982                 goto send_to_file;
983              case MD_FILE:
984                 Dmsg1(850, "FILE for following msg: %s", msg);
985                 mode = "w+b";
986 send_to_file:
987                 if (msgs->is_closing()) {
988                    break;
989                 }
990                 msgs->set_in_use();
991                 if (!d->fd && !open_dest_file(jcr, d, mode)) {
992                    msgs->clear_in_use();
993                    break;
994                 }
995                 fputs(dt, d->fd);
996                 fputs(msg, d->fd);
997                 /* On error, we close and reopen to handle log rotation */
998                 if (ferror(d->fd)) {
999                    fclose(d->fd);
1000                    d->fd = NULL;
1001                    if (open_dest_file(jcr, d, mode)) {
1002                       fputs(dt, d->fd);
1003                       fputs(msg, d->fd);
1004                    }
1005                 }
1006                 msgs->clear_in_use();
1007                 break;
1008              case MD_DIRECTOR:
1009                 Dmsg1(850, "DIRECTOR for following msg: %s", msg);
1010                 if (jcr && jcr->dir_bsock && !jcr->dir_bsock->errors) {
1011                    jcr->dir_bsock->fsend("Jmsg JobId=%ld type=%d level=%lld %s",
1012                       jcr->JobId, type, mtime, msg);
1013                 } else {
1014                    Dmsg1(800, "no jcr for following msg: %s", msg);
1015                 }
1016                 break;
1017              case MD_STDOUT:
1018                 Dmsg1(850, "STDOUT for following msg: %s", msg);
1019                 if (type != M_ABORT && type != M_ERROR_TERM) { /* already printed */
1020                    fputs(dt, stdout);
1021                    fputs(msg, stdout);
1022                    fflush(stdout);
1023                 }
1024                 break;
1025              case MD_STDERR:
1026                 Dmsg1(850, "STDERR for following msg: %s", msg);
1027                 fputs(dt, stderr);
1028                 fputs(msg, stderr);
1029                 fflush(stdout);
1030                 break;
1031              default:
1032                 break;
1033           }
1034        }
1035     }
1036     if (created_jcr) {
1037        free_jcr(jcr);
1038     }
1039 }
1040
1041 /*********************************************************************
1042  *
1043  *  This subroutine returns the filename portion of a path.
1044  *  It is used because some compilers set __FILE__
1045  *  to the full path.  Try to return base + next higher path.
1046  */
1047
1048 const char *get_basename(const char *pathname)
1049 {
1050    const char *basename;
1051
1052    if ((basename = bstrrpath(pathname, pathname+strlen(pathname))) == pathname) {
1053       /* empty */
1054    } else if ((basename = bstrrpath(pathname, basename-1)) == pathname) {
1055       /* empty */
1056    } else {
1057       basename++;
1058    }
1059    return basename;
1060 }
1061
1062 /*
1063  * print or write output to trace file
1064  */
1065 static void pt_out(char *buf)
1066 {
1067     /*
1068      * Used the "trace on" command in the console to turn on
1069      *  output to the trace file.  "trace off" will close the file.
1070      */
1071     if (trace) {
1072        if (!trace_fd) {
1073           char fn[200];
1074           bsnprintf(fn, sizeof(fn), "%s/%s.trace", working_directory ? working_directory : "./", my_name);
1075           trace_fd = bfopen(fn, "a+b");
1076        }
1077        if (trace_fd) {
1078           fputs(buf, trace_fd);
1079           fflush(trace_fd);
1080           return;
1081        } else {
1082           /* Some problem, turn off tracing */
1083           trace = false;
1084        }
1085     }
1086     /* not tracing */
1087     fputs(buf, stdout);
1088     fflush(stdout);
1089 }
1090
1091 /*********************************************************************
1092  *
1093  *  This subroutine prints a debug message if the level number
1094  *  is less than or equal the debug_level. File and line numbers
1095  *  are included for more detail if desired, but not currently
1096  *  printed.
1097  *
1098  *  If the level is negative, the details of file and line number
1099  *  are not printed.
1100  *
1101  */
1102 void
1103 vd_msg(const char *file, int line, int64_t level, const char *fmt, va_list arg_ptr)
1104 {
1105     char      buf[5000];
1106     int       len = 0; /* space used in buf */
1107     bool      details = true;
1108     utime_t   mtime;
1109
1110     if (level < 0) {
1111        details = false;
1112        level = -level;
1113     }
1114
1115     if (chk_dbglvl(level)) {
1116        if (dbg_timestamp) {
1117           mtime = time(NULL);
1118           bstrftimes(buf+len, sizeof(buf)-len, mtime);
1119           len = strlen(buf);
1120           buf[len++] = ' ';
1121        }
1122
1123 #ifdef FULL_LOCATION
1124        if (details) {
1125           if (dbg_thread) {
1126              len += bsnprintf(buf+len, sizeof(buf)-len, "%s[%lld]: %s:%d-%u ",
1127                              my_name, bthread_get_thread_id(),
1128                              get_basename(file), line, get_jobid_from_tsd());
1129           } else {
1130              len += bsnprintf(buf+len, sizeof(buf)-len, "%s: %s:%d-%u ",
1131                    my_name, get_basename(file), line, get_jobid_from_tsd());
1132           }
1133        }
1134 #endif
1135        bvsnprintf(buf+len, sizeof(buf)-len, (char *)fmt, arg_ptr);
1136
1137        pt_out(buf);
1138     }
1139 }
1140
1141 void
1142 d_msg(const char *file, int line, int64_t level, const char *fmt,...)
1143 {
1144    va_list arg_ptr;
1145    va_start(arg_ptr, fmt);
1146    vd_msg(file, line, level, fmt, arg_ptr); /* without tags */
1147    va_end(arg_ptr);
1148 }
1149
1150
1151 /*
1152  * Set trace flag on/off. If argument is negative, there is no change
1153  */
1154 void set_trace(int trace_flag)
1155 {
1156    if (trace_flag < 0) {
1157       return;
1158    } else if (trace_flag > 0) {
1159       trace = true;
1160    } else {
1161       trace = false;
1162    }
1163    if (!trace && trace_fd) {
1164       FILE *ltrace_fd = trace_fd;
1165       trace_fd = NULL;
1166       bmicrosleep(0, 100000);         /* yield to prevent seg faults */
1167       fclose(ltrace_fd);
1168    }
1169 }
1170
1171 void set_hangup(int hangup_value)
1172 {
1173    if (hangup_value != -1) {
1174       hangup = hangup_value;
1175    }
1176 }
1177
1178 int get_hangup(void)
1179 {
1180    return hangup;
1181 }
1182
1183 void set_blowup(int blowup_value)
1184 {
1185    if (blowup_value != -1) {
1186       blowup = blowup_value;
1187    }
1188 }
1189
1190 int get_blowup(void)
1191 {
1192    return blowup;
1193 }
1194
1195 bool handle_hangup_blowup(JCR *jcr, uint32_t file_count, uint64_t byte_count)
1196 {
1197    if (hangup == 0 && blowup == 0) {
1198       /* quick check */
1199       return false;
1200    }
1201    /* Debug code: check if we must hangup  or blowup */
1202    if ((hangup > 0 && (file_count > (uint32_t)hangup)) ||
1203        (hangup < 0 && (byte_count/1024 > (uint32_t)-hangup)))  {
1204       jcr->setJobStatus(JS_Incomplete);
1205       if (hangup > 0) {
1206          Jmsg1(jcr, M_FATAL, 0, "Debug hangup requested after %d files.\n", hangup);
1207       } else {
1208          Jmsg1(jcr, M_FATAL, 0, "Debug hangup requested after %d Kbytes.\n", -hangup);
1209       }
1210       set_hangup(0);
1211       return true;
1212    }
1213    if ((blowup > 0 && (file_count > (uint32_t)blowup)) ||
1214        (blowup < 0 && (byte_count/1024 > (uint32_t)-blowup)))  {
1215       if (blowup > 0) {
1216          Jmsg1(jcr, M_ABORT, 0, "Debug blowup requested after %d files.\n", blowup);
1217       } else {
1218          Jmsg1(jcr, M_ABORT, 0, "Debug blowup requested after %d Kbytes.\n", -blowup);
1219       }
1220       /* will never reach this line */
1221       return true;
1222    }
1223    return false;
1224 }
1225
1226 bool get_trace(void)
1227 {
1228    return trace;
1229 }
1230
1231 /*********************************************************************
1232  *
1233  *  This subroutine prints a message regardless of the debug level
1234  *
1235  *  If the level is negative, the details of file and line number
1236  *  are not printed.
1237  */
1238 void
1239 p_msg(const char *file, int line, int level, const char *fmt,...)
1240 {
1241     char      buf[5000];
1242     int       len = 0; /* space used in buf */
1243     va_list   arg_ptr;
1244
1245     if (dbg_timestamp) {
1246        utime_t mtime = time(NULL);
1247        bstrftimes(buf+len, sizeof(buf)-len, mtime);
1248        len = strlen(buf);
1249        buf[len++] = ' ';
1250     }
1251
1252 #ifdef FULL_LOCATION
1253     if (level >= 0) {
1254        len += bsnprintf(buf+len, sizeof(buf)-len, "%s: %s:%d-%u ",
1255              my_name, get_basename(file), line, get_jobid_from_tsd());
1256     }
1257 #endif
1258
1259     va_start(arg_ptr, fmt);
1260     bvsnprintf(buf+len, sizeof(buf)-len, (char *)fmt, arg_ptr);
1261     va_end(arg_ptr);
1262
1263     pt_out(buf);
1264 }
1265
1266
1267 /*********************************************************************
1268  *
1269  *  subroutine writes a debug message to the trace file if the level number
1270  *  is less than or equal the debug_level. File and line numbers
1271  *  are included for more detail if desired, but not currently
1272  *  printed.
1273  *
1274  *  If the level is negative, the details of file and line number
1275  *  are not printed.
1276  */
1277 void
1278 t_msg(const char *file, int line, int64_t level, const char *fmt,...)
1279 {
1280     char      buf[5000];
1281     int       len;
1282     va_list   arg_ptr;
1283     int       details = TRUE;
1284
1285     level = level & ~DT_ALL;    /* level should be tag free */
1286
1287     if (level < 0) {
1288        details = FALSE;
1289        level = -level;
1290     }
1291
1292     if (level <= debug_level) {
1293        if (!trace_fd) {
1294           bsnprintf(buf, sizeof(buf), "%s/%s.trace", working_directory ? working_directory : ".", my_name);
1295           trace_fd = bfopen(buf, "a+b");
1296        }
1297
1298 #ifdef FULL_LOCATION
1299        if (details) {
1300           len = bsnprintf(buf, sizeof(buf), "%s: %s:%d ", my_name, get_basename(file), line);
1301        } else {
1302           len = 0;
1303        }
1304 #else
1305        len = 0;
1306 #endif
1307        va_start(arg_ptr, fmt);
1308        bvsnprintf(buf+len, sizeof(buf)-len, (char *)fmt, arg_ptr);
1309        va_end(arg_ptr);
1310        if (trace_fd != NULL) {
1311            fputs(buf, trace_fd);
1312            fflush(trace_fd);
1313        }
1314    }
1315 }
1316
1317 /* *********************************************************
1318  *
1319  * print an error message
1320  *
1321  */
1322 void
1323 e_msg(const char *file, int line, int type, int level, const char *fmt,...)
1324 {
1325     char     buf[5000];
1326     va_list   arg_ptr;
1327     int len;
1328
1329     /*
1330      * Check if we have a message destination defined.
1331      * We always report M_ABORT and M_ERROR_TERM
1332      */
1333     if (!daemon_msgs || ((type != M_ABORT && type != M_ERROR_TERM) &&
1334                          !bit_is_set(type, daemon_msgs->send_msg))) {
1335        return;                        /* no destination */
1336     }
1337     switch (type) {
1338     case M_ABORT:
1339        len = bsnprintf(buf, sizeof(buf), _("%s: ABORTING due to ERROR in %s:%d\n"),
1340                my_name, get_basename(file), line);
1341        break;
1342     case M_ERROR_TERM:
1343        len = bsnprintf(buf, sizeof(buf), _("%s: ERROR TERMINATION at %s:%d\n"),
1344                my_name, get_basename(file), line);
1345        break;
1346     case M_FATAL:
1347        if (level == -1)            /* skip details */
1348           len = bsnprintf(buf, sizeof(buf), _("%s: Fatal Error because: "), my_name);
1349        else
1350           len = bsnprintf(buf, sizeof(buf), _("%s: Fatal Error at %s:%d because:\n"), my_name, get_basename(file), line);
1351        break;
1352     case M_ERROR:
1353        if (level == -1)            /* skip details */
1354           len = bsnprintf(buf, sizeof(buf), _("%s: ERROR: "), my_name);
1355        else
1356           len = bsnprintf(buf, sizeof(buf), _("%s: ERROR in %s:%d "), my_name, get_basename(file), line);
1357        break;
1358     case M_WARNING:
1359        len = bsnprintf(buf, sizeof(buf), _("%s: Warning: "), my_name);
1360        break;
1361     case M_SECURITY:
1362        len = bsnprintf(buf, sizeof(buf), _("%s: Security violation: "), my_name);
1363        break;
1364     default:
1365        len = bsnprintf(buf, sizeof(buf), "%s: ", my_name);
1366        break;
1367     }
1368
1369     va_start(arg_ptr, fmt);
1370     bvsnprintf(buf+len, sizeof(buf)-len, (char *)fmt, arg_ptr);
1371     va_end(arg_ptr);
1372
1373     pt_out(buf);
1374     dispatch_message(NULL, type, 0, buf);
1375
1376     if (type == M_ABORT) {
1377        char *p = 0;
1378        p[0] = 0;                      /* generate segmentation violation */
1379     }
1380     if (type == M_ERROR_TERM) {
1381        exit(1);
1382     }
1383 }
1384
1385 /* Check in the msgs resource if a given type is defined */
1386 bool is_message_type_set(JCR *jcr, int type)
1387 {
1388    MSGS *msgs = NULL;
1389    if (jcr) {
1390        msgs = jcr->jcr_msgs;
1391    }
1392    if (!msgs) {
1393       msgs = daemon_msgs;            /* if no jcr, we use daemon handler */
1394    }
1395    if (msgs && (type != M_ABORT && type != M_ERROR_TERM) &&
1396        !bit_is_set(type, msgs->send_msg)) {
1397       return false;                 /* no destination */
1398    }
1399    return true;
1400 }
1401
1402 /* *********************************************************
1403  *
1404  * Generate a Job message
1405  *
1406  */
1407 void
1408 Jmsg(JCR *jcr, int type, utime_t mtime, const char *fmt,...)
1409 {
1410     char     rbuf[5000];
1411     va_list   arg_ptr;
1412     int len;
1413     MSGS *msgs;
1414     uint32_t JobId = 0;
1415
1416
1417     Dmsg1(850, "Enter Jmsg type=%d\n", type);
1418
1419     /* Special case for the console, which has a dir_bsock and JobId==0,
1420      *  in that case, we send the message directly back to the
1421      *  dir_bsock.
1422      */
1423     if (jcr && jcr->JobId == 0 && jcr->dir_bsock) {
1424        BSOCK *dir = jcr->dir_bsock;
1425        va_start(arg_ptr, fmt);
1426        dir->msglen = bvsnprintf(dir->msg, sizeof_pool_memory(dir->msg),
1427                                 fmt, arg_ptr);
1428        va_end(arg_ptr);
1429        jcr->dir_bsock->send();
1430        return;
1431     }
1432
1433     /* The watchdog thread can't use Jmsg directly, we always queued it */
1434     if (is_watchdog()) {
1435        va_start(arg_ptr, fmt);
1436        bvsnprintf(rbuf,  sizeof(rbuf), fmt, arg_ptr);
1437        va_end(arg_ptr);
1438        Qmsg(jcr, type, mtime, "%s", rbuf);
1439        return;
1440     }
1441
1442     msgs = NULL;
1443     if (!jcr) {
1444        jcr = get_jcr_from_tsd();
1445     }
1446     if (jcr) {
1447        if (!jcr->dequeuing_msgs) { /* Avoid recursion */
1448           /* Dequeue messages to keep the original order  */
1449           dequeue_messages(jcr);
1450        }
1451        msgs = jcr->jcr_msgs;
1452        JobId = jcr->JobId;
1453     }
1454     if (!msgs) {
1455        msgs = daemon_msgs;            /* if no jcr, we use daemon handler */
1456     }
1457
1458     /*
1459      * Check if we have a message destination defined.
1460      * We always report M_ABORT and M_ERROR_TERM
1461      */
1462     if (msgs && (type != M_ABORT && type != M_ERROR_TERM) &&
1463          !bit_is_set(type, msgs->send_msg)) {
1464        return;                        /* no destination */
1465     }
1466     switch (type) {
1467     case M_ABORT:
1468        len = bsnprintf(rbuf, sizeof(rbuf), _("%s ABORTING due to ERROR\n"), my_name);
1469        break;
1470     case M_ERROR_TERM:
1471        len = bsnprintf(rbuf, sizeof(rbuf), _("%s ERROR TERMINATION\n"), my_name);
1472        break;
1473     case M_FATAL:
1474        len = bsnprintf(rbuf, sizeof(rbuf), _("%s JobId %u: Fatal error: "), my_name, JobId);
1475        if (jcr) {
1476           jcr->setJobStatus(JS_FatalError);
1477        }
1478        if (jcr && jcr->JobErrors == 0) {
1479           jcr->JobErrors = 1;
1480        }
1481        break;
1482     case M_ERROR:
1483        len = bsnprintf(rbuf, sizeof(rbuf), _("%s JobId %u: Error: "), my_name, JobId);
1484        if (jcr) {
1485           jcr->JobErrors++;
1486        }
1487        break;
1488     case M_WARNING:
1489        len = bsnprintf(rbuf, sizeof(rbuf), _("%s JobId %u: Warning: "), my_name, JobId);
1490        if (jcr) {
1491           jcr->JobWarnings++;
1492        }
1493        break;
1494     case M_SECURITY:
1495        len = bsnprintf(rbuf, sizeof(rbuf), _("%s JobId %u: Security violation: "),
1496                my_name, JobId);
1497        break;
1498     default:
1499        len = bsnprintf(rbuf, sizeof(rbuf), "%s JobId %u: ", my_name, JobId);
1500        break;
1501     }
1502
1503     va_start(arg_ptr, fmt);
1504     bvsnprintf(rbuf+len,  sizeof(rbuf)-len, fmt, arg_ptr);
1505     va_end(arg_ptr);
1506
1507     dispatch_message(jcr, type, mtime, rbuf);
1508
1509     if (type == M_ABORT){
1510        char *p = 0;
1511        printf("Bacula forced SEG FAULT to obtain traceback.\n");
1512        syslog(LOG_DAEMON|LOG_ERR, "Bacula forced SEG FAULT to obtain traceback.\n");
1513        p[0] = 0;                      /* generate segmentation violation */
1514     }
1515     if (type == M_ERROR_TERM) {
1516        exit(1);
1517     }
1518 }
1519
1520 /*
1521  * If we come here, prefix the message with the file:line-number,
1522  *  then pass it on to the normal Jmsg routine.
1523  */
1524 void j_msg(const char *file, int line, JCR *jcr, int type, utime_t mtime, const char *fmt,...)
1525 {
1526    va_list   arg_ptr;
1527    int i, len, maxlen;
1528    POOLMEM *pool_buf;
1529
1530    va_start(arg_ptr, fmt);
1531    vd_msg(file, line, 0, fmt, arg_ptr);
1532    va_end(arg_ptr);
1533
1534    pool_buf = get_pool_memory(PM_EMSG);
1535    i = Mmsg(pool_buf, "%s:%d ", get_basename(file), line);
1536
1537    for (;;) {
1538       maxlen = sizeof_pool_memory(pool_buf) - i - 1;
1539       va_start(arg_ptr, fmt);
1540       len = bvsnprintf(pool_buf+i, maxlen, fmt, arg_ptr);
1541       va_end(arg_ptr);
1542       if (len < 0 || len >= (maxlen-5)) {
1543          pool_buf = realloc_pool_memory(pool_buf, maxlen + i + maxlen/2);
1544          continue;
1545       }
1546       break;
1547    }
1548
1549    Jmsg(jcr, type, mtime, "%s", pool_buf);
1550    free_memory(pool_buf);
1551 }
1552
1553
1554 /*
1555  * Edit a message into a Pool memory buffer, with file:lineno
1556  */
1557 int m_msg(const char *file, int line, POOLMEM **pool_buf, const char *fmt, ...)
1558 {
1559    va_list   arg_ptr;
1560    int i, len, maxlen;
1561
1562    i = sprintf(*pool_buf, "%s:%d ", get_basename(file), line);
1563
1564    for (;;) {
1565       maxlen = sizeof_pool_memory(*pool_buf) - i - 1;
1566       va_start(arg_ptr, fmt);
1567       len = bvsnprintf(*pool_buf+i, maxlen, fmt, arg_ptr);
1568       va_end(arg_ptr);
1569       if (len < 0 || len >= (maxlen-5)) {
1570          *pool_buf = realloc_pool_memory(*pool_buf, maxlen + i + maxlen/2);
1571          continue;
1572       }
1573       break;
1574    }
1575    return len;
1576 }
1577
1578 int m_msg(const char *file, int line, POOLMEM *&pool_buf, const char *fmt, ...)
1579 {
1580    va_list   arg_ptr;
1581    int i, len, maxlen;
1582
1583    i = sprintf(pool_buf, "%s:%d ", get_basename(file), line);
1584
1585    for (;;) {
1586       maxlen = sizeof_pool_memory(pool_buf) - i - 1;
1587       va_start(arg_ptr, fmt);
1588       len = bvsnprintf(pool_buf+i, maxlen, fmt, arg_ptr);
1589       va_end(arg_ptr);
1590       if (len < 0 || len >= (maxlen-5)) {
1591          pool_buf = realloc_pool_memory(pool_buf, maxlen + i + maxlen/2);
1592          continue;
1593       }
1594       break;
1595    }
1596    return len;
1597 }
1598
1599
1600 /*
1601  * Edit a message into a Pool Memory buffer NO file:lineno
1602  *  Returns: string length of what was edited.
1603  */
1604 int Mmsg(POOLMEM **pool_buf, const char *fmt, ...)
1605 {
1606    va_list   arg_ptr;
1607    int len, maxlen;
1608
1609    for (;;) {
1610       maxlen = sizeof_pool_memory(*pool_buf) - 1;
1611       va_start(arg_ptr, fmt);
1612       len = bvsnprintf(*pool_buf, maxlen, fmt, arg_ptr);
1613       va_end(arg_ptr);
1614       if (len < 0 || len >= (maxlen-5)) {
1615          *pool_buf = realloc_pool_memory(*pool_buf, maxlen + maxlen/2);
1616          continue;
1617       }
1618       break;
1619    }
1620    return len;
1621 }
1622
1623 int Mmsg(POOLMEM *&pool_buf, const char *fmt, ...)
1624 {
1625    va_list   arg_ptr;
1626    int len, maxlen;
1627
1628    for (;;) {
1629       maxlen = sizeof_pool_memory(pool_buf) - 1;
1630       va_start(arg_ptr, fmt);
1631       len = bvsnprintf(pool_buf, maxlen, fmt, arg_ptr);
1632       va_end(arg_ptr);
1633       if (len < 0 || len >= (maxlen-5)) {
1634          pool_buf = realloc_pool_memory(pool_buf, maxlen + maxlen/2);
1635          continue;
1636       }
1637       break;
1638    }
1639    return len;
1640 }
1641
1642 int Mmsg(POOL_MEM &pool_buf, const char *fmt, ...)
1643 {
1644    va_list   arg_ptr;
1645    int len, maxlen;
1646
1647    for (;;) {
1648       maxlen = pool_buf.max_size() - 1;
1649       va_start(arg_ptr, fmt);
1650       len = bvsnprintf(pool_buf.c_str(), maxlen, fmt, arg_ptr);
1651       va_end(arg_ptr);
1652       if (len < 0 || len >= (maxlen-5)) {
1653          pool_buf.realloc_pm(maxlen + maxlen/2);
1654          continue;
1655       }
1656       break;
1657    }
1658    return len;
1659 }
1660
1661
1662 /*
1663  * We queue messages rather than print them directly. This
1664  *  is generally used in low level routines (msg handler, bnet)
1665  *  to prevent recursion (i.e. if you are in the middle of
1666  *  sending a message, it is a bit messy to recursively call
1667  *  yourself when the bnet packet is not reentrant).
1668  */
1669 void Qmsg(JCR *jcr, int type, utime_t mtime, const char *fmt,...)
1670 {
1671    va_list   arg_ptr;
1672    int len, maxlen;
1673    POOLMEM *pool_buf;
1674    MQUEUE_ITEM *item;
1675
1676    pool_buf = get_pool_memory(PM_EMSG);
1677
1678    for (;;) {
1679       maxlen = sizeof_pool_memory(pool_buf) - 1;
1680       va_start(arg_ptr, fmt);
1681       len = bvsnprintf(pool_buf, maxlen, fmt, arg_ptr);
1682       va_end(arg_ptr);
1683       if (len < 0 || len >= (maxlen-5)) {
1684          pool_buf = realloc_pool_memory(pool_buf, maxlen + maxlen/2);
1685          continue;
1686       }
1687       break;
1688    }
1689    item = (MQUEUE_ITEM *)malloc(sizeof(MQUEUE_ITEM) + strlen(pool_buf) + 1);
1690    item->type = type;
1691    item->mtime = time(NULL);
1692    strcpy(item->msg, pool_buf);
1693    if (!jcr) {
1694       jcr = get_jcr_from_tsd();
1695    }
1696
1697    if (jcr && type==M_FATAL) {
1698       jcr->setJobStatus(JS_FatalError);
1699     }
1700
1701    /* If no jcr or no queue or dequeuing send to syslog */
1702    if (!jcr || !jcr->msg_queue || jcr->dequeuing_msgs) {
1703       syslog(LOG_DAEMON|LOG_ERR, "%s", item->msg);
1704       P(daemon_msg_queue_mutex);
1705       if (daemon_msg_queue) {
1706          daemon_msg_queue->append(item);
1707       }
1708       V(daemon_msg_queue_mutex);
1709    } else {
1710       /* Queue message for later sending */
1711       P(jcr->msg_queue_mutex);
1712       jcr->msg_queue->append(item);
1713       V(jcr->msg_queue_mutex);
1714    }
1715    free_memory(pool_buf);
1716 }
1717
1718 /*
1719  * Dequeue messages
1720  */
1721 void dequeue_messages(JCR *jcr)
1722 {
1723    MQUEUE_ITEM *item;
1724    JobId_t JobId;
1725
1726    /* Avoid bad calls and recursion */
1727    if (!jcr || jcr->dequeuing_msgs) {
1728       return;
1729    }
1730
1731    /* Dequeue daemon messages */
1732    if (daemon_msg_queue && !dequeuing_daemon_msgs) {
1733       P(daemon_msg_queue_mutex);
1734       dequeuing_daemon_msgs = true;
1735       jcr->dequeuing_msgs = true;
1736       JobId = jcr->JobId;
1737       jcr->JobId = 0;       /* set daemon JobId == 0 */
1738       if (jcr->dir_bsock) jcr->dir_bsock->suppress_error_messages(true);
1739       foreach_dlist(item, daemon_msg_queue) {
1740          Jmsg(jcr, item->type, item->mtime, "%s", item->msg);
1741       }
1742       if (jcr->dir_bsock) jcr->dir_bsock->suppress_error_messages(false);
1743       /* Remove messages just sent */
1744       daemon_msg_queue->destroy();
1745       jcr->JobId = JobId;   /* restore JobId */
1746       jcr->dequeuing_msgs = false;
1747       dequeuing_daemon_msgs = false;
1748       V(daemon_msg_queue_mutex);
1749    }
1750
1751    /* Dequeue Job specific messages */
1752    if (!jcr->msg_queue || jcr->dequeuing_msgs) {
1753       return;
1754    }
1755    P(jcr->msg_queue_mutex);
1756    jcr->dequeuing_msgs = true;
1757    if (jcr->dir_bsock) jcr->dir_bsock->suppress_error_messages(true);
1758    foreach_dlist(item, jcr->msg_queue) {
1759       Jmsg(jcr, item->type, item->mtime, "%s", item->msg);
1760    }
1761    if (jcr->dir_bsock) jcr->dir_bsock->suppress_error_messages(false);
1762    /* Remove messages just sent */
1763    jcr->msg_queue->destroy();
1764    jcr->dequeuing_msgs = false;
1765    V(jcr->msg_queue_mutex);
1766 }
1767
1768
1769 /*
1770  * If we come here, prefix the message with the file:line-number,
1771  *  then pass it on to the normal Qmsg routine.
1772  */
1773 void q_msg(const char *file, int line, JCR *jcr, int type, utime_t mtime, const char *fmt,...)
1774 {
1775    va_list   arg_ptr;
1776    int i, len, maxlen;
1777    POOLMEM *pool_buf;
1778
1779    pool_buf = get_pool_memory(PM_EMSG);
1780    i = Mmsg(pool_buf, "%s:%d ", get_basename(file), line);
1781
1782    for (;;) {
1783       maxlen = sizeof_pool_memory(pool_buf) - i - 1;
1784       va_start(arg_ptr, fmt);
1785       len = bvsnprintf(pool_buf+i, maxlen, fmt, arg_ptr);
1786       va_end(arg_ptr);
1787       if (len < 0 || len >= (maxlen-5)) {
1788          pool_buf = realloc_pool_memory(pool_buf, maxlen + i + maxlen/2);
1789          continue;
1790       }
1791       break;
1792    }
1793
1794    Qmsg(jcr, type, mtime, "%s", pool_buf);
1795    free_memory(pool_buf);
1796 }
1797
1798
1799 /* not all in alphabetical order.  New commands are added after existing commands with similar letters
1800    to prevent breakage of existing user scripts.  */
1801 struct debugtags {
1802    const char *tag;             /* command */
1803    int64_t     bit;             /* bit to set */
1804    const char *help;            /* main purpose */
1805 };
1806
1807 /* setdebug tag=all,-plugin */
1808 static struct debugtags debug_tags[] = {
1809  { NT_("lock"),        DT_LOCK,     _("Debug lock information")},
1810  { NT_("network"),     DT_NETWORK,  _("Debug network information")},
1811  { NT_("plugin"),      DT_PLUGIN,   _("Debug plugin information")},
1812  { NT_("volume"),      DT_VOLUME,   _("Debug volume information")},
1813  { NT_("sql"),         DT_SQL,      _("Debug SQL queries")},
1814  { NT_("bvfs"),        DT_BVFS,     _("Debug BVFS queries")},
1815  { NT_("memory"),      DT_MEMORY,   _("Debug memory allocation")},
1816  { NT_("scheduler"),   DT_SCHEDULER,_("Debug scheduler information")},
1817  { NT_("protocol"),    DT_PROTOCOL, _("Debug protocol information")},
1818  { NT_("snapshot"),    DT_SNAPSHOT, _("Debug snapshots")},
1819  { NT_("asx"),         DT_ASX,      _("ASX personal's debugging")},
1820  { NT_("all"),         DT_ALL,      _("Debug all information")},
1821  { NULL,               0,   NULL}
1822 };
1823
1824 #define MAX_TAG (sizeof(debug_tags) / sizeof(struct debugtags))
1825
1826 const char *debug_get_tag(uint32_t pos, const char **desc)
1827 {
1828    if (pos < MAX_TAG) {
1829       if (desc) {
1830          *desc = debug_tags[pos].help;
1831       }
1832       return debug_tags[pos].tag;
1833    }
1834    return NULL;
1835 }
1836
1837 /* Allow +-, */
1838 bool debug_find_tag(const char *tagname, bool add, int64_t *current_level)
1839 {
1840    Dmsg3(010, "add=%d tag=%s level=%lld\n", add, tagname, *current_level);
1841    if (!*tagname) {
1842       /* Nothing in the buffer */
1843       return true;
1844    }
1845    for (int i=0; debug_tags[i].tag ; i++) {
1846       if (strcasecmp(debug_tags[i].tag, tagname) == 0) {
1847          if (add) {
1848             *current_level |= debug_tags[i].bit;
1849          } else {
1850             *current_level &= ~(debug_tags[i].bit);
1851          }
1852          return true;
1853       }
1854    }
1855    return false;
1856 }
1857
1858 bool debug_parse_tags(const char *options, int64_t *current_level)
1859 {
1860    bool operation;              /* + => true, - false */
1861    char *p, *t, tag[256];
1862    int max = sizeof(tag) - 1;
1863    bool ret=true;
1864    int64_t level= *current_level;
1865
1866    t = tag;
1867    *tag = 0;
1868    operation = true;            /* add by default */
1869
1870    if (!options) {
1871       Dmsg0(100, "No options for tags\n");
1872       return false;
1873    }
1874
1875    for (p = (char *)options; *p ; p++) {
1876       if (*p == ',' || *p == '+' || *p == '-' || *p == '!') {
1877          /* finish tag keyword */
1878          *t = 0;
1879          /* handle tag */
1880          ret &= debug_find_tag(tag, operation, &level);
1881
1882          if (*p == ',') {
1883             /* reset tag */
1884             t = tag;
1885             *tag = 0;
1886             operation = true;
1887
1888          } else {
1889             /* reset tag */
1890             t = tag;
1891             *tag = 0;
1892             operation = (*p == '+');
1893          }
1894
1895       } else if (isalpha(*p) && (t - tag) < max) {
1896          *t++ = *p;
1897
1898       } else {                  /* not isalpha or too long */
1899          Dmsg1(010, "invalid %c\n", *p);
1900          return false;
1901       }
1902    }
1903
1904    /* At the end, finish the string and look it */
1905    *t = 0;
1906    if (t > tag) {               /* something found */
1907       /* handle tag */
1908       ret &= debug_find_tag(tag, operation, &level);
1909    }
1910
1911    *current_level = level;
1912    return ret;
1913 }
1914
1915 int generate_daemon_event(JCR *jcr, const char *event) { return 0; }
1916
1917 void setup_daemon_message_queue()
1918 {
1919    static MQUEUE_ITEM *item = NULL;
1920    daemon_msg_queue = New(dlist(item, &item->link));
1921 }
1922
1923 void free_daemon_message_queue()
1924 {
1925    P(daemon_msg_queue_mutex);
1926    daemon_msg_queue->destroy();
1927    free(daemon_msg_queue);
1928    V(daemon_msg_queue_mutex);
1929 }