2 Bacula® - The Network Backup Solution
4 Copyright (C) 2000-2014 Free Software Foundation Europe e.V.
6 The main author of Bacula is Kern Sibbald, with contributions from many
7 others, a complete list can be found in the file AUTHORS.
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.
14 Bacula® is a registered trademark of Kern Sibbald.
17 * Bacula message handling routines
19 * NOTE: don't use any Jmsg or Qmsg calls within this file,
20 * except in q_msg or j_msg (setup routines),
21 * otherwise you may get into recursive calls if there are
22 * errors, and that can lead to looping or deadlocks.
24 * Written by Kern Sibbald, April 2000
31 sql_query_func p_sql_query = NULL;
32 sql_escape_func p_sql_escape = NULL;
34 #define FULL_LOCATION 1 /* set for file:line in Debug messages */
37 * This is where we define "Globals" because all the
38 * daemons include this file.
40 const char *working_directory = NULL; /* working directory path stored here */
41 const char *assert_msg = NULL; /* ASSERT2 error message */
42 const char *version = VERSION " (" BDATE ")";
43 const char *dist_name = DISTNAME " " DISTVER;
44 char *exepath = (char *)NULL;
45 char *exename = (char *)NULL;
46 char *catalog_db = NULL; /* database type */
47 char con_fname[500]; /* Console filename */
48 char my_name[30] = {0}; /* daemon name is stored here */
49 char host_name[50] = {0}; /* host machine name */
50 char fail_time[30] = {0}; /* Time of failure */
51 int verbose = 0; /* increase User messages */
52 int64_t debug_level = 0; /* debug level */
53 int32_t debug_flags = 0; /* debug flags */
55 int console_msg_pending = false;
56 utime_t daemon_start_time = 0; /* Daemon start time */
57 FILE *con_fd = NULL; /* Console file descriptor */
58 brwlock_t con_lock; /* Console lock structure */
59 bool dbg_timestamp = false; /* print timestamp in debug output */
60 bool prt_kaboom = false; /* Print kaboom output */
61 job_code_callback_t message_job_code_callback = NULL; /* Job code callback. Only used by director. */
63 /* Forward referenced functions */
65 /* Imported functions */
66 void create_jcr_key();
70 /* Exclude spaces but require .mail at end */
71 #define MAIL_REGEX "^[^ ]+\\.mail$"
73 /* Allow only one thread to tweak d->fd at a time */
74 static pthread_mutex_t fides_mutex = PTHREAD_MUTEX_INITIALIZER;
75 static MSGS *daemon_msgs; /* global messages */
76 static void (*message_callback)(int type, char *msg) = NULL;
77 static FILE *trace_fd = NULL;
78 #if defined(HAVE_WIN32)
79 static bool trace = true;
81 static bool trace = false;
83 static int hangup = 0;
86 const char *host_os = HOST_OS;
87 const char *distname = DISTNAME;
88 const char *distver = DISTVER;
91 * Walk back in a string from end looking for a
93 * This routine is passed the start of the string and
94 * the end of the string, it returns either the beginning
95 * of the string or where it found a path separator.
97 static const char *bstrrpath(const char *start, const char *end)
99 while ( end > start ) {
101 if (IsPathSeparator(*end)) {
109 * Returns: 0 if not configured
113 int generate_daemon_event(JCR *jcr, const char *event)
118 /* Some message class methods */
130 * Wait for not in use variable to be clear
132 void MSGS::wait_not_in_use() /* leaves fides_mutex set */
135 while (m_in_use || m_closing) {
137 bmicrosleep(0, 200); /* wait */
143 * Handle message delivery errors
145 static void delivery_error(const char *fmt,...)
150 char dt[MAX_TIME_LENGTH];
153 pool_buf = get_pool_memory(PM_EMSG);
155 bstrftime_ny(dt, sizeof(dt), time(NULL));
160 i = Mmsg(pool_buf, "%s Message delivery ERROR: ", dt);
163 maxlen = sizeof_pool_memory(pool_buf) - i - 1;
164 va_start(arg_ptr, fmt);
165 len = bvsnprintf(pool_buf+i, maxlen, fmt, arg_ptr);
167 if (len < 0 || len >= (maxlen-5)) {
168 pool_buf = realloc_pool_memory(pool_buf, maxlen + i + maxlen/2);
174 fputs(pool_buf, stdout); /* print this here to INSURE that it is printed */
176 syslog(LOG_DAEMON|LOG_ERR, "%s", pool_buf);
177 free_memory(pool_buf);
180 void set_debug_flags(char *options)
182 for (char *p = options; *p ; p++) {
184 case '0': /* clear flags */
188 case 'i': /* used by FD */
189 case 'd': /* used by FD */
193 dbg_timestamp = true;
197 dbg_timestamp = false;
201 /* truncate the trace file */
202 if (trace && trace_fd) {
203 ftruncate(fileno(trace_fd), 0);
208 /* Turn on/off add_events for P()/V() */
209 debug_flags |= DEBUG_MUTEX_EVENT;
213 /* Display event stack during lockdump */
214 debug_flags |= DEBUG_PRINT_EVENT;
218 Dmsg1(000, "Unknown debug flag %c\n", *p);
223 void register_message_callback(void msg_callback(int type, char *msg))
225 message_callback = msg_callback;
230 * Set daemon name. Also, find canonical execution
231 * path. Note, exepath has spare room for tacking on
232 * the exename so that we can reconstruct the full name.
234 * Note, this routine can get called multiple times
235 * The second time is to put the name as found in the
236 * Resource record. On the second call, generally,
237 * argv is NULL to avoid doing the path code twice.
239 void my_name_is(int argc, char *argv[], const char *name)
245 if (gethostname(host_name, sizeof(host_name)) != 0) {
246 bstrncpy(host_name, "Hostname unknown", sizeof(host_name));
248 bstrncpy(my_name, name, sizeof(my_name));
249 if (argc>0 && argv && argv[0]) {
250 /* strip trailing filename and save exepath */
251 for (l=p=argv[0]; *p; p++) {
252 if (IsPathSeparator(*p)) {
253 l = p; /* set pos of last slash */
256 if (IsPathSeparator(*l)) {
260 #if defined(HAVE_WIN32)
261 /* On Windows allow c: drive specification */
271 exename = (char *)malloc(len);
277 exepath = (char *)malloc(strlen(argv[0]) + 1 + len);
278 for (p=argv[0],q=exepath; p < l; ) {
282 if (strchr(exepath, '.') || !IsPathSeparator(exepath[0])) {
283 if (getcwd(cpath, sizeof(cpath))) {
285 exepath = (char *)malloc(strlen(cpath) + 1 + len);
286 strcpy(exepath, cpath);
289 Dmsg2(500, "exepath=%s\nexename=%s\n", exepath, exename);
293 /* Set special ASSERT2 message where debugger can find it */
295 set_assert_msg(const char *file, int line, const char *msg)
298 bsnprintf(buf, sizeof(buf), "ASSERT at %s:%d-%u ERR=%s",
299 get_basename(file), line, get_jobid_from_tsd(), msg);
300 assert_msg = bstrdup(buf);
304 set_db_type(const char *name)
306 if (catalog_db != NULL) {
309 catalog_db = bstrdup(name);
313 * Initialize message handler for a daemon or a Job
314 * We make a copy of the MSGS resource passed, so it belows
315 * to the job or daemon and thus can be modified.
317 * NULL for jcr -> initialize global messages for daemon
318 * non-NULL -> initialize jcr using Message resource
321 init_msg(JCR *jcr, MSGS *msg, job_code_callback_t job_code_callback)
323 DEST *d, *dnew, *temp_chain = NULL;
326 if (jcr == NULL && msg == NULL) {
327 init_last_jobs_list();
328 /* Create a daemon key then set invalid jcr */
329 /* Maybe we should give the daemon a jcr??? */
331 set_jcr_in_tsd(INVALID_JCR);
334 message_job_code_callback = job_code_callback;
336 #if !defined(HAVE_WIN32)
338 * Make sure we have fd's 0, 1, 2 open
339 * If we don't do this one of our sockets may open
340 * there and if we then use stdout, it could
341 * send total garbage to our socket.
345 fd = open("/dev/null", O_RDONLY, 0644);
349 for(i=1; fd + i <= 2; i++) {
356 * If msg is NULL, initialize global chain for STDOUT and syslog
359 daemon_msgs = (MSGS *)malloc(sizeof(MSGS));
360 memset(daemon_msgs, 0, sizeof(MSGS));
361 for (i=1; i<=M_MAX; i++) {
362 add_msg_dest(daemon_msgs, MD_STDOUT, i, NULL, NULL);
364 Dmsg1(050, "Create daemon global message resource %p\n", daemon_msgs);
369 * Walk down the message resource chain duplicating it
370 * for the current Job.
372 for (d=msg->dest_chain; d; d=d->next) {
373 dnew = (DEST *)malloc(sizeof(DEST));
374 memcpy(dnew, d, sizeof(DEST));
375 dnew->next = temp_chain;
377 dnew->mail_filename = NULL;
379 dnew->mail_cmd = bstrdup(d->mail_cmd);
382 dnew->where = bstrdup(d->where);
388 jcr->jcr_msgs = (MSGS *)malloc(sizeof(MSGS));
389 memset(jcr->jcr_msgs, 0, sizeof(MSGS));
390 jcr->jcr_msgs->dest_chain = temp_chain;
391 memcpy(jcr->jcr_msgs->send_msg, msg->send_msg, sizeof(msg->send_msg));
393 /* If we have default values, release them now */
395 free_msgs_res(daemon_msgs);
397 daemon_msgs = (MSGS *)malloc(sizeof(MSGS));
398 memset(daemon_msgs, 0, sizeof(MSGS));
399 daemon_msgs->dest_chain = temp_chain;
400 memcpy(daemon_msgs->send_msg, msg->send_msg, sizeof(msg->send_msg));
403 Dmsg2(250, "Copy message resource %p to %p\n", msg, temp_chain);
406 /* Initialize so that the console (User Agent) can
407 * receive messages -- stored in a file.
409 void init_console_msg(const char *wd)
413 bsnprintf(con_fname, sizeof(con_fname), "%s%c%s.conmsg", wd, PathSeparator, my_name);
414 fd = open(con_fname, O_CREAT|O_RDWR|O_BINARY, 0600);
417 Emsg2(M_ERROR_TERM, 0, _("Could not open console message file %s: ERR=%s\n"),
418 con_fname, be.bstrerror());
420 if (lseek(fd, 0, SEEK_END) > 0) {
421 console_msg_pending = 1;
424 con_fd = fopen(con_fname, "a+b");
427 Emsg2(M_ERROR, 0, _("Could not open console message file %s: ERR=%s\n"),
428 con_fname, be.bstrerror());
430 if (rwl_init(&con_lock) != 0) {
432 Emsg1(M_ERROR_TERM, 0, _("Could not get con mutex: ERR=%s\n"),
438 * Called only during parsing of the config file.
440 * Add a message destination. I.e. associate a message type with
441 * a destination (code).
442 * Note, where in the case of dest_code FILE is a filename,
443 * but in the case of MAIL is a space separated list of
444 * email addresses, ...
446 void add_msg_dest(MSGS *msg, int dest_code, int msg_type, char *where, char *mail_cmd)
450 * First search the existing chain and see if we
451 * can simply add this msg_type to an existing entry.
453 for (d=msg->dest_chain; d; d=d->next) {
454 if (dest_code == d->dest_code && ((where == NULL && d->where == NULL) ||
455 (strcmp(where, d->where) == 0))) {
456 Dmsg4(850, "Add to existing d=%p msgtype=%d destcode=%d where=%s\n",
457 d, msg_type, dest_code, NPRT(where));
458 set_bit(msg_type, d->msg_types);
459 set_bit(msg_type, msg->send_msg); /* set msg_type bit in our local */
463 /* Not found, create a new entry */
464 d = (DEST *)malloc(sizeof(DEST));
465 memset(d, 0, sizeof(DEST));
466 d->next = msg->dest_chain;
467 d->dest_code = dest_code;
468 set_bit(msg_type, d->msg_types); /* set type bit in structure */
469 set_bit(msg_type, msg->send_msg); /* set type bit in our local */
471 d->where = bstrdup(where);
474 d->mail_cmd = bstrdup(mail_cmd);
476 Dmsg5(850, "add new d=%p msgtype=%d destcode=%d where=%s mailcmd=%s\n",
477 d, msg_type, dest_code, NPRT(where), NPRT(d->mail_cmd));
482 * Called only during parsing of the config file.
484 * Remove a message destination
486 void rem_msg_dest(MSGS *msg, int dest_code, int msg_type, char *where)
490 for (d=msg->dest_chain; d; d=d->next) {
491 Dmsg2(850, "Remove_msg_dest d=%p where=%s\n", d, NPRT(d->where));
492 if (bit_is_set(msg_type, d->msg_types) && (dest_code == d->dest_code) &&
493 ((where == NULL && d->where == NULL) ||
494 (strcmp(where, d->where) == 0))) {
495 Dmsg3(850, "Found for remove d=%p msgtype=%d destcode=%d\n",
496 d, msg_type, dest_code);
497 clear_bit(msg_type, d->msg_types);
498 Dmsg0(850, "Return rem_msg_dest\n");
506 * Create a unique filename for the mail command
508 static void make_unique_mail_filename(JCR *jcr, POOLMEM *&name, DEST *d)
511 Mmsg(name, "%s/%s.%s.%d.mail", working_directory, my_name,
512 jcr->Job, (int)(intptr_t)d);
514 Mmsg(name, "%s/%s.%s.%d.mail", working_directory, my_name,
515 my_name, (int)(intptr_t)d);
517 Dmsg1(850, "mailname=%s\n", name);
523 static BPIPE *open_mail_pipe(JCR *jcr, POOLMEM *&cmd, DEST *d)
528 cmd = edit_job_codes(jcr, cmd, d->mail_cmd, d->where, message_job_code_callback);
530 Mmsg(cmd, "/usr/lib/sendmail -F Bacula %s", d->where);
534 if ((bpipe = open_bpipe(cmd, 120, "rw"))) {
535 /* If we had to use sendmail, add subject */
537 fprintf(bpipe->wfd, "Subject: %s\r\n\r\n", _("Bacula Message"));
541 delivery_error(_("open mail pipe %s failed: ERR=%s\n"),
542 cmd, be.bstrerror());
548 * Close the messages for this Messages resource, which means to close
549 * any open files, and dispatch any pending email messages.
551 void close_msg(JCR *jcr)
559 Dmsg1(580, "Close_msg jcr=%p\n", jcr);
561 if (jcr == NULL) { /* NULL -> global chain */
564 msgs = jcr->jcr_msgs;
565 jcr->jcr_msgs = NULL;
571 /* Wait for item to be not in use, then mark closing */
572 if (msgs->is_closing()) {
575 msgs->wait_not_in_use(); /* leaves fides_mutex set */
576 /* Note get_closing() does not lock because we are already locked */
577 if (msgs->get_closing()) {
584 Dmsg1(850, "===Begin close msg resource at %p\n", msgs);
585 cmd = get_pool_memory(PM_MESSAGE);
586 for (d=msgs->dest_chain; d; ) {
588 switch (d->dest_code) {
592 fclose(d->fd); /* close open file descriptor */
597 case MD_MAIL_ON_ERROR:
598 case MD_MAIL_ON_SUCCESS:
599 Dmsg0(850, "Got MD_MAIL, MD_MAIL_ON_ERROR or MD_MAIL_ON_SUCCESS\n");
604 switch (d->dest_code) {
605 case MD_MAIL_ON_ERROR:
607 switch (jcr->JobStatus) {
616 case MD_MAIL_ON_SUCCESS:
618 switch (jcr->JobStatus) {
631 if (!(bpipe=open_mail_pipe(jcr, cmd, d))) {
632 Pmsg0(000, _("open mail pipe failed.\n"));
636 Dmsg0(850, "Opened mail pipe\n");
638 line = get_memory(len);
640 while (fgets(line, len, d->fd)) {
641 fputs(line, bpipe->wfd);
643 if (!close_wpipe(bpipe)) { /* close write pipe sending mail */
645 Pmsg1(000, _("close error: ERR=%s\n"), be.bstrerror());
649 * Since we are closing all messages, before "recursing"
650 * make sure we are not closing the daemon messages, otherwise
653 if (msgs != daemon_msgs) {
654 /* read what mail prog returned -- should be nothing */
655 while (fgets(line, len, bpipe->rfd)) {
656 delivery_error(_("Mail prog: %s"), line);
660 stat = close_bpipe(bpipe);
661 if (stat != 0 && msgs != daemon_msgs) {
664 Dmsg1(850, "Calling emsg. CMD=%s\n", cmd);
665 delivery_error(_("Mail program terminated in error.\n"
667 "ERR=%s\n"), cmd, be.bstrerror());
671 /* Remove temp mail file */
676 /* Exclude spaces in mail_filename */
677 if (d->mail_filename) {
678 safer_unlink(d->mail_filename, MAIL_REGEX);
679 free_pool_memory(d->mail_filename);
680 d->mail_filename = NULL;
682 Dmsg0(850, "end mail or mail on error\n");
689 d = d->next; /* point to next buffer */
691 free_pool_memory(cmd);
692 Dmsg0(850, "Done walking message chain.\n");
697 msgs->clear_closing();
699 Dmsg0(850, "===End close msg resource\n");
703 * Free memory associated with Messages resource
705 void free_msgs_res(MSGS *msgs)
709 /* Walk down the message chain releasing allocated buffers */
710 for (d=msgs->dest_chain; d; ) {
719 old = d; /* save pointer to release */
720 d = d->next; /* point to next buffer */
721 free(old); /* free the destination item */
723 msgs->dest_chain = NULL;
724 free(msgs); /* free the head */
729 * Terminate the message handler for good.
730 * Release the global destination chain.
732 * Also, clean up a few other items (cons, exepath). Note,
733 * these really should be done elsewhere.
737 Dmsg0(850, "Enter term_msg\n");
738 close_msg(NULL); /* close global chain */
739 free_msgs_res(daemon_msgs); /* free the resources */
762 term_last_jobs_list();
765 static bool open_dest_file(JCR *jcr, DEST *d, const char *mode)
767 d->fd = fopen(d->where, mode);
770 delivery_error(_("fopen %s failed: ERR=%s\n"), d->where, be.bstrerror());
776 /* Split the output for syslog (it converts \n to ' ' and is
777 * limited to 1024 characters per syslog message
779 static void send_to_syslog(int mode, const char *msg)
786 while (*p && ((p2 = strchr(p, '\n')) != NULL)) {
787 len = MIN((int)sizeof(buf) - 1, p2 - p + 1); /* Add 1 to keep \n */
788 strncpy(buf, p, len);
790 syslog(mode, "%s", buf);
791 p = p2+1; /* skip \n */
793 if (*p != 0) { /* no \n at the end ? */
794 syslog(mode, "%s", p);
799 * Handle sending the message to the appropriate place
801 void dispatch_message(JCR *jcr, int type, utime_t mtime, char *msg)
804 char dt[MAX_TIME_LENGTH];
811 Dmsg2(850, "Enter dispatch_msg type=%d msg=%s", type, msg);
814 * Most messages are prefixed by a date and time. If mtime is
815 * zero, then we use the current time. If mtime is 1 (special
816 * kludge), we do not prefix the date and time. Otherwise,
817 * we assume mtime is a utime_t and use it.
825 mtime = time(NULL); /* get time for SQL log */
827 bstrftime_ny(dt, sizeof(dt), mtime);
833 /* If the program registered a callback, send it there */
834 if (message_callback) {
835 message_callback(type, msg);
839 /* For serious errors make sure message is printed or logged */
840 if (type == M_ABORT || type == M_ERROR_TERM) {
844 if (type == M_ABORT) {
845 syslog(LOG_DAEMON|LOG_ERR, "%s", msg);
850 /* Now figure out where to send the message */
853 jcr = get_jcr_from_tsd();
856 msgs = jcr->jcr_msgs;
862 * If closing this message resource, print and send to syslog,
865 if (msgs->is_closing()) {
869 syslog(LOG_DAEMON|LOG_ERR, "%s", msg);
873 for (d=msgs->dest_chain; d; d=d->next) {
874 if (bit_is_set(type, d->msg_types)) {
875 switch (d->dest_code) {
878 if (!jcr || !jcr->db) {
881 if (p_sql_query && p_sql_escape) {
882 POOLMEM *cmd = get_pool_memory(PM_MESSAGE);
883 POOLMEM *esc_msg = get_pool_memory(PM_MESSAGE);
885 int len = strlen(msg) + 1;
886 esc_msg = check_pool_memory_size(esc_msg, len * 2 + 1);
887 if (p_sql_escape(jcr, jcr->db, esc_msg, msg, len)) {
888 bstrutime(dt, sizeof(dt), mtime);
889 Mmsg(cmd, "INSERT INTO Log (JobId, Time, LogText) VALUES (%s,'%s','%s')",
890 edit_int64(jcr->JobId, ed1), dt, esc_msg);
891 if (!p_sql_query(jcr, cmd)) {
892 delivery_error(_("Msg delivery error: Unable to store data in database.\n"));
895 delivery_error(_("Msg delivery error: Unable to store data in database.\n"));
898 free_pool_memory(cmd);
899 free_pool_memory(esc_msg);
903 Dmsg1(850, "CONSOLE for following msg: %s", msg);
905 con_fd = fopen(con_fname, "a+b");
906 Dmsg0(850, "Console file not open.\n");
909 Pw(con_lock); /* get write lock on console message file */
912 (void)fwrite(dt, dtlen, 1, con_fd);
916 (void)fwrite(msg, len, 1, con_fd);
917 if (msg[len-1] != '\n') {
918 (void)fwrite("\n", 2, 1, con_fd);
921 (void)fwrite("\n", 2, 1, con_fd);
924 console_msg_pending = true;
929 Dmsg1(850, "SYSLOG for following msg: %s\n", msg);
931 * We really should do an openlog() here.
933 send_to_syslog(LOG_DAEMON|LOG_ERR, msg);
936 Dmsg1(850, "OPERATOR for following msg: %s\n", msg);
937 mcmd = get_pool_memory(PM_MESSAGE);
938 if ((bpipe=open_mail_pipe(jcr, mcmd, d))) {
940 fputs(dt, bpipe->wfd);
941 fputs(msg, bpipe->wfd);
942 /* Messages to the operator go one at a time */
943 stat = close_bpipe(bpipe);
947 delivery_error(_("Msg delivery error: Operator mail program terminated in error.\n"
949 "ERR=%s\n"), mcmd, be.bstrerror());
952 free_pool_memory(mcmd);
955 case MD_MAIL_ON_ERROR:
956 case MD_MAIL_ON_SUCCESS:
957 Dmsg1(850, "MAIL for following msg: %s", msg);
958 if (msgs->is_closing()) {
963 POOLMEM *name = get_pool_memory(PM_MESSAGE);
964 make_unique_mail_filename(jcr, name, d);
965 d->fd = fopen(name, "w+b");
968 delivery_error(_("Msg delivery error: fopen %s failed: ERR=%s\n"), name,
970 free_pool_memory(name);
971 msgs->clear_in_use();
974 d->mail_filename = name;
977 len = strlen(msg) + dtlen;;
978 if (len > d->max_len) {
979 d->max_len = len; /* keep max line length */
982 msgs->clear_in_use();
985 Dmsg1(850, "APPEND for following msg: %s", msg);
989 Dmsg1(850, "FILE for following msg: %s", msg);
992 if (msgs->is_closing()) {
996 if (!d->fd && !open_dest_file(jcr, d, mode)) {
997 msgs->clear_in_use();
1002 /* On error, we close and reopen to handle log rotation */
1003 if (ferror(d->fd)) {
1006 if (open_dest_file(jcr, d, mode)) {
1011 msgs->clear_in_use();
1014 Dmsg1(850, "DIRECTOR for following msg: %s", msg);
1015 if (jcr && jcr->dir_bsock && !jcr->dir_bsock->errors) {
1016 jcr->dir_bsock->fsend("Jmsg Job=%s type=%d level=%lld %s",
1017 jcr->Job, type, mtime, msg);
1019 Dmsg1(800, "no jcr for following msg: %s", msg);
1023 Dmsg1(850, "STDOUT for following msg: %s", msg);
1024 if (type != M_ABORT && type != M_ERROR_TERM) { /* already printed */
1031 Dmsg1(850, "STDERR for following msg: %s", msg);
1043 /*********************************************************************
1045 * This subroutine returns the filename portion of a path.
1046 * It is used because some compilers set __FILE__
1047 * to the full path. Try to return base + next higher path.
1050 const char *get_basename(const char *pathname)
1052 const char *basename;
1054 if ((basename = bstrrpath(pathname, pathname+strlen(pathname))) == pathname) {
1056 } else if ((basename = bstrrpath(pathname, basename-1)) == pathname) {
1065 * print or write output to trace file
1067 static void pt_out(char *buf)
1070 * Used the "trace on" command in the console to turn on
1071 * output to the trace file. "trace off" will close the file.
1076 bsnprintf(fn, sizeof(fn), "%s/%s.trace", working_directory ? working_directory : "./", my_name);
1077 trace_fd = fopen(fn, "a+b");
1080 fputs(buf, trace_fd);
1084 /* Some problem, turn off tracing */
1093 /*********************************************************************
1095 * This subroutine prints a debug message if the level number
1096 * is less than or equal the debug_level. File and line numbers
1097 * are included for more detail if desired, but not currently
1100 * If the level is negative, the details of file and line number
1104 d_msg(const char *file, int line, int64_t level, const char *fmt,...)
1109 bool details = true;
1117 if (chk_dbglvl(level)) {
1118 if (dbg_timestamp) {
1120 bstrftimes(buf, sizeof(buf), mtime);
1127 #ifdef FULL_LOCATION
1129 len = bsnprintf(buf, sizeof(buf), "%s: %s:%d-%u ",
1130 my_name, get_basename(file), line, get_jobid_from_tsd());
1137 va_start(arg_ptr, fmt);
1138 bvsnprintf(buf+len, sizeof(buf)-len, (char *)fmt, arg_ptr);
1146 * Set trace flag on/off. If argument is negative, there is no change
1148 void set_trace(int trace_flag)
1150 if (trace_flag < 0) {
1152 } else if (trace_flag > 0) {
1157 if (!trace && trace_fd) {
1158 FILE *ltrace_fd = trace_fd;
1160 bmicrosleep(0, 100000); /* yield to prevent seg faults */
1165 void set_hangup(int hangup_value)
1167 if (hangup_value < 0) {
1170 hangup = hangup_value;
1174 int get_hangup(void)
1179 bool get_trace(void)
1184 /*********************************************************************
1186 * This subroutine prints a message regardless of the debug level
1188 * If the level is negative, the details of file and line number
1192 p_msg(const char *file, int line, int level, const char *fmt,...)
1198 #ifdef FULL_LOCATION
1200 len = bsnprintf(buf, sizeof(buf), "%s: %s:%d-%u ",
1201 my_name, get_basename(file), line, get_jobid_from_tsd());
1209 va_start(arg_ptr, fmt);
1210 bvsnprintf(buf+len, sizeof(buf)-len, (char *)fmt, arg_ptr);
1217 /*********************************************************************
1219 * subroutine writes a debug message to the trace file if the level number
1220 * is less than or equal the debug_level. File and line numbers
1221 * are included for more detail if desired, but not currently
1224 * If the level is negative, the details of file and line number
1228 t_msg(const char *file, int line, int64_t level, const char *fmt,...)
1240 if (chk_dbglvl(level)) {
1242 bsnprintf(buf, sizeof(buf), "%s/%s.trace", working_directory ? working_directory : ".", my_name);
1243 trace_fd = fopen(buf, "a+b");
1246 #ifdef FULL_LOCATION
1248 len = bsnprintf(buf, sizeof(buf), "%s: %s:%d ", my_name, get_basename(file), line);
1255 va_start(arg_ptr, fmt);
1256 bvsnprintf(buf+len, sizeof(buf)-len, (char *)fmt, arg_ptr);
1258 if (trace_fd != NULL) {
1259 fputs(buf, trace_fd);
1265 /* *********************************************************
1267 * print an error message
1271 e_msg(const char *file, int line, int type, int level, const char *fmt,...)
1278 * Check if we have a message destination defined.
1279 * We always report M_ABORT and M_ERROR_TERM
1281 if (!daemon_msgs || ((type != M_ABORT && type != M_ERROR_TERM) &&
1282 !bit_is_set(type, daemon_msgs->send_msg))) {
1283 return; /* no destination */
1287 len = bsnprintf(buf, sizeof(buf), _("%s: ABORTING due to ERROR in %s:%d\n"),
1288 my_name, get_basename(file), line);
1291 len = bsnprintf(buf, sizeof(buf), _("%s: ERROR TERMINATION at %s:%d\n"),
1292 my_name, get_basename(file), line);
1295 if (level == -1) /* skip details */
1296 len = bsnprintf(buf, sizeof(buf), _("%s: Fatal Error because: "), my_name);
1298 len = bsnprintf(buf, sizeof(buf), _("%s: Fatal Error at %s:%d because:\n"), my_name, get_basename(file), line);
1301 if (level == -1) /* skip details */
1302 len = bsnprintf(buf, sizeof(buf), _("%s: ERROR: "), my_name);
1304 len = bsnprintf(buf, sizeof(buf), _("%s: ERROR in %s:%d "), my_name, get_basename(file), line);
1307 len = bsnprintf(buf, sizeof(buf), _("%s: Warning: "), my_name);
1310 len = bsnprintf(buf, sizeof(buf), _("%s: Security violation: "), my_name);
1313 len = bsnprintf(buf, sizeof(buf), "%s: ", my_name);
1317 va_start(arg_ptr, fmt);
1318 bvsnprintf(buf+len, sizeof(buf)-len, (char *)fmt, arg_ptr);
1321 dispatch_message(NULL, type, 0, buf);
1323 if (type == M_ABORT) {
1325 p[0] = 0; /* generate segmentation violation */
1327 if (type == M_ERROR_TERM) {
1332 /* *********************************************************
1334 * Generate a Job message
1338 Jmsg(JCR *jcr, int type, utime_t mtime, const char *fmt,...)
1347 Dmsg1(850, "Enter Jmsg type=%d\n", type);
1349 /* Special case for the console, which has a dir_bsock and JobId==0,
1350 * in that case, we send the message directly back to the
1353 if (jcr && jcr->JobId == 0 && jcr->dir_bsock) {
1354 BSOCK *dir = jcr->dir_bsock;
1355 va_start(arg_ptr, fmt);
1356 dir->msglen = bvsnprintf(dir->msg, sizeof_pool_memory(dir->msg),
1359 jcr->dir_bsock->send();
1363 /* The watchdog thread can't use Jmsg directly, we always queued it */
1364 if (is_watchdog()) {
1365 va_start(arg_ptr, fmt);
1366 bvsnprintf(rbuf, sizeof(rbuf), fmt, arg_ptr);
1368 Qmsg(jcr, type, mtime, "%s", rbuf);
1374 jcr = get_jcr_from_tsd();
1377 if (!jcr->dequeuing_msgs) { /* Avoid recursion */
1378 /* Dequeue messages to keep the original order */
1379 dequeue_messages(jcr);
1381 msgs = jcr->jcr_msgs;
1385 msgs = daemon_msgs; /* if no jcr, we use daemon handler */
1389 * Check if we have a message destination defined.
1390 * We always report M_ABORT and M_ERROR_TERM
1392 if (msgs && (type != M_ABORT && type != M_ERROR_TERM) &&
1393 !bit_is_set(type, msgs->send_msg)) {
1394 return; /* no destination */
1398 len = bsnprintf(rbuf, sizeof(rbuf), _("%s ABORTING due to ERROR\n"), my_name);
1401 len = bsnprintf(rbuf, sizeof(rbuf), _("%s ERROR TERMINATION\n"), my_name);
1404 len = bsnprintf(rbuf, sizeof(rbuf), _("%s JobId %u: Fatal error: "), my_name, JobId);
1406 jcr->setJobStatus(JS_FatalError);
1408 if (jcr && jcr->JobErrors == 0) {
1413 len = bsnprintf(rbuf, sizeof(rbuf), _("%s JobId %u: Error: "), my_name, JobId);
1419 len = bsnprintf(rbuf, sizeof(rbuf), _("%s JobId %u: Warning: "), my_name, JobId);
1425 len = bsnprintf(rbuf, sizeof(rbuf), _("%s JobId %u: Security violation: "),
1429 len = bsnprintf(rbuf, sizeof(rbuf), "%s JobId %u: ", my_name, JobId);
1433 va_start(arg_ptr, fmt);
1434 bvsnprintf(rbuf+len, sizeof(rbuf)-len, fmt, arg_ptr);
1437 dispatch_message(jcr, type, mtime, rbuf);
1439 if (type == M_ABORT){
1441 printf("Bacula forced SEG FAULT to obtain traceback.\n");
1442 syslog(LOG_DAEMON|LOG_ERR, "Bacula forced SEG FAULT to obtain traceback.\n");
1443 p[0] = 0; /* generate segmentation violation */
1445 if (type == M_ERROR_TERM) {
1451 * If we come here, prefix the message with the file:line-number,
1452 * then pass it on to the normal Jmsg routine.
1454 void j_msg(const char *file, int line, JCR *jcr, int type, utime_t mtime, const char *fmt,...)
1460 pool_buf = get_pool_memory(PM_EMSG);
1461 i = Mmsg(pool_buf, "%s:%d ", get_basename(file), line);
1464 maxlen = sizeof_pool_memory(pool_buf) - i - 1;
1465 va_start(arg_ptr, fmt);
1466 len = bvsnprintf(pool_buf+i, maxlen, fmt, arg_ptr);
1468 if (len < 0 || len >= (maxlen-5)) {
1469 pool_buf = realloc_pool_memory(pool_buf, maxlen + i + maxlen/2);
1475 Jmsg(jcr, type, mtime, "%s", pool_buf);
1476 free_memory(pool_buf);
1481 * Edit a message into a Pool memory buffer, with file:lineno
1483 int m_msg(const char *file, int line, POOLMEM **pool_buf, const char *fmt, ...)
1488 i = sprintf(*pool_buf, "%s:%d ", get_basename(file), line);
1491 maxlen = sizeof_pool_memory(*pool_buf) - i - 1;
1492 va_start(arg_ptr, fmt);
1493 len = bvsnprintf(*pool_buf+i, maxlen, fmt, arg_ptr);
1495 if (len < 0 || len >= (maxlen-5)) {
1496 *pool_buf = realloc_pool_memory(*pool_buf, maxlen + i + maxlen/2);
1504 int m_msg(const char *file, int line, POOLMEM *&pool_buf, const char *fmt, ...)
1509 i = sprintf(pool_buf, "%s:%d ", get_basename(file), line);
1512 maxlen = sizeof_pool_memory(pool_buf) - i - 1;
1513 va_start(arg_ptr, fmt);
1514 len = bvsnprintf(pool_buf+i, maxlen, fmt, arg_ptr);
1516 if (len < 0 || len >= (maxlen-5)) {
1517 pool_buf = realloc_pool_memory(pool_buf, maxlen + i + maxlen/2);
1527 * Edit a message into a Pool Memory buffer NO file:lineno
1528 * Returns: string length of what was edited.
1530 int Mmsg(POOLMEM **pool_buf, const char *fmt, ...)
1536 maxlen = sizeof_pool_memory(*pool_buf) - 1;
1537 va_start(arg_ptr, fmt);
1538 len = bvsnprintf(*pool_buf, maxlen, fmt, arg_ptr);
1540 if (len < 0 || len >= (maxlen-5)) {
1541 *pool_buf = realloc_pool_memory(*pool_buf, maxlen + maxlen/2);
1549 int Mmsg(POOLMEM *&pool_buf, const char *fmt, ...)
1555 maxlen = sizeof_pool_memory(pool_buf) - 1;
1556 va_start(arg_ptr, fmt);
1557 len = bvsnprintf(pool_buf, maxlen, fmt, arg_ptr);
1559 if (len < 0 || len >= (maxlen-5)) {
1560 pool_buf = realloc_pool_memory(pool_buf, maxlen + maxlen/2);
1568 int Mmsg(POOL_MEM &pool_buf, const char *fmt, ...)
1574 maxlen = pool_buf.max_size() - 1;
1575 va_start(arg_ptr, fmt);
1576 len = bvsnprintf(pool_buf.c_str(), maxlen, fmt, arg_ptr);
1578 if (len < 0 || len >= (maxlen-5)) {
1579 pool_buf.realloc_pm(maxlen + maxlen/2);
1589 * We queue messages rather than print them directly. This
1590 * is generally used in low level routines (msg handler, bnet)
1591 * to prevent recursion (i.e. if you are in the middle of
1592 * sending a message, it is a bit messy to recursively call
1593 * yourself when the bnet packet is not reentrant).
1595 void Qmsg(JCR *jcr, int type, utime_t mtime, const char *fmt,...)
1602 pool_buf = get_pool_memory(PM_EMSG);
1605 maxlen = sizeof_pool_memory(pool_buf) - 1;
1606 va_start(arg_ptr, fmt);
1607 len = bvsnprintf(pool_buf, maxlen, fmt, arg_ptr);
1609 if (len < 0 || len >= (maxlen-5)) {
1610 pool_buf = realloc_pool_memory(pool_buf, maxlen + maxlen/2);
1615 item = (MQUEUE_ITEM *)malloc(sizeof(MQUEUE_ITEM) + strlen(pool_buf) + 1);
1617 item->mtime = time(NULL);
1618 strcpy(item->msg, pool_buf);
1620 jcr = get_jcr_from_tsd();
1622 /* If no jcr or no queue or dequeuing send to syslog */
1623 if (!jcr || !jcr->msg_queue || jcr->dequeuing_msgs) {
1624 syslog(LOG_DAEMON|LOG_ERR, "%s", item->msg);
1627 /* Queue message for later sending */
1628 P(jcr->msg_queue_mutex);
1629 jcr->msg_queue->append(item);
1630 V(jcr->msg_queue_mutex);
1632 free_memory(pool_buf);
1638 void dequeue_messages(JCR *jcr)
1641 if (!jcr->msg_queue) {
1644 P(jcr->msg_queue_mutex);
1645 jcr->dequeuing_msgs = true;
1646 foreach_dlist(item, jcr->msg_queue) {
1647 Jmsg(jcr, item->type, item->mtime, "%s", item->msg);
1649 /* Remove messages just sent */
1650 jcr->msg_queue->destroy();
1651 jcr->dequeuing_msgs = false;
1652 V(jcr->msg_queue_mutex);
1657 * If we come here, prefix the message with the file:line-number,
1658 * then pass it on to the normal Qmsg routine.
1660 void q_msg(const char *file, int line, JCR *jcr, int type, utime_t mtime, const char *fmt,...)
1666 pool_buf = get_pool_memory(PM_EMSG);
1667 i = Mmsg(pool_buf, "%s:%d ", get_basename(file), line);
1670 maxlen = sizeof_pool_memory(pool_buf) - i - 1;
1671 va_start(arg_ptr, fmt);
1672 len = bvsnprintf(pool_buf+i, maxlen, fmt, arg_ptr);
1674 if (len < 0 || len >= (maxlen-5)) {
1675 pool_buf = realloc_pool_memory(pool_buf, maxlen + i + maxlen/2);
1681 Qmsg(jcr, type, mtime, "%s", pool_buf);
1682 free_memory(pool_buf);
1686 /* not all in alphabetical order. New commands are added after existing commands with similar letters
1687 to prevent breakage of existing user scripts. */
1689 const char *tag; /* command */
1690 int64_t bit; /* bit to set */
1691 const char *help; /* main purpose */
1694 /* setdebug tag=all,-plugin */
1695 static struct debugtags debug_tags[] = {
1696 { NT_("lock"), DT_LOCK, _("Debug lock information")},
1697 { NT_("network"), DT_NETWORK, _("Debug network information")},
1698 { NT_("plugin"), DT_PLUGIN, _("Debug plugin information")},
1699 { NT_("volume"), DT_VOLUME, _("Debug volume information")},
1700 { NT_("sql"), DT_SQL, _("Debug SQL queries")},
1701 { NT_("bvfs"), DT_BVFS, _("Debug BVFS queries")},
1702 { NT_("memory"), DT_MEMORY, _("Debug memory allocation")},
1703 { NT_("scheduler"), DT_SCHEDULER,_("Debug scheduler information")},
1704 { NT_("protocol"), DT_PROTOCOL, _("Debug protocol information")},
1705 { NT_("all"), DT_ALL, _("Debug all information")},
1710 bool debug_find_tag(const char *tagname, bool add, int64_t *current_level)
1712 Dmsg3(010, "add=%d tag=%s level=%lld\n", add, tagname, *current_level);
1714 /* Nothing in the buffer */
1717 for (int i=0; debug_tags[i].tag ; i++) {
1718 if (strcasecmp(debug_tags[i].tag, tagname) == 0) {
1720 *current_level |= debug_tags[i].bit;
1722 *current_level &= ~(debug_tags[i].bit);
1730 bool debug_parse_tags(const char *options, int64_t *current_level)
1732 bool operation; /* + => true, - false */
1733 char *p, *t, tag[256];
1734 int max = sizeof(tag) - 1;
1736 int64_t level= *current_level;
1740 operation = true; /* add by default */
1743 Dmsg0(100, "No options for tags\n");
1747 for (p = (char *)options; *p ; p++) {
1748 if (*p == ',' || *p == '+' || *p == '-' || *p == '!') {
1749 /* finish tag keyword */
1752 ret &= debug_find_tag(tag, operation, &level);
1764 operation = (*p == '+');
1767 } else if (isalpha(*p) && (t - tag) < max) {
1770 } else { /* not isalpha or too long */
1771 Dmsg1(010, "invalid %c\n", *p);
1776 /* At the end, finish the string and look it */
1778 if (t > tag) { /* something found */
1780 ret &= debug_find_tag(tag, operation, &level);
1783 *current_level = level;