#include "bacula.h"
#include "jcr.h"
+#if !defined(HAVE_CONSOLE)
+#if defined(HAVE_CYGWIN) || defined(HAVE_WIN32)
+#include <windows.h>
+#endif
+#endif
+
#define FULL_LOCATION 1 /* set for file:line in Debug messages */
/*
* This is where we define "Globals" because all the
* daemons include this file.
*/
-char *working_directory = NULL; /* working directory path stored here */
+const char *working_directory = NULL; /* working directory path stored here */
int verbose = 0; /* increase User messages */
int debug_level = 0; /* debug level */
time_t daemon_start_time = 0; /* Daemon start time */
static MSGS *daemon_msgs; /* global messages */
+/* Define if e_msg must exit when M_ERROR_TERM is received */
+static int exit_on_error = 1;
+
/*
* Set daemon name. Also, find canonical execution
* path. Note, exepath has spare room for tacking on
daemon_msgs = (MSGS *)malloc(sizeof(MSGS));
memset(daemon_msgs, 0, sizeof(MSGS));
for (i=1; i<=M_MAX; i++) {
+#ifndef WIN32
add_msg_dest(daemon_msgs, MD_STDOUT, i, NULL, NULL);
+#endif
add_msg_dest(daemon_msgs, MD_SYSLOG, i, NULL, NULL);
}
Dmsg1(050, "Create daemon global message resource 0x%x\n", daemon_msgs);
/* Initialize so that the console (User Agent) can
* receive messages -- stored in a file.
*/
-void init_console_msg(char *wd)
+void init_console_msg(const char *wd)
{
int fd;
/*
* Create a unique filename for the mail command
*/
-static void make_unique_mail_filename(JCR *jcr, POOLMEM **name, DEST *d)
+static void make_unique_mail_filename(JCR *jcr, POOLMEM *&name, DEST *d)
{
if (jcr) {
Mmsg(name, "%s/%s.mail.%s.%d", working_directory, my_name,
/*
* Open a mail pipe
*/
-static BPIPE *open_mail_pipe(JCR *jcr, POOLMEM **cmd, DEST *d)
+static BPIPE *open_mail_pipe(JCR *jcr, POOLMEM *&cmd, DEST *d)
{
BPIPE *bpipe;
-
- if (d->mail_cmd && jcr) {
- *cmd = edit_job_codes(jcr, *cmd, d->mail_cmd, d->where);
+ int use_bsmtp = (d->mail_cmd && jcr);
+
+ if (use_bsmtp) {
+ cmd = edit_job_codes(jcr, cmd, d->mail_cmd, d->where);
} else {
+#if 1
+ Mmsg(cmd, "/usr/lib/sendmail -F Bacula %s", d->where);
+#else
Mmsg(cmd, "mail -s \"Bacula Message\" %s", d->where);
+#endif
}
fflush(stdout);
- if (!(bpipe = open_bpipe(*cmd, 120, "rw"))) {
+ if (!(bpipe = open_bpipe(cmd, 120, "rw"))) {
+ berrno be;
Jmsg(jcr, M_ERROR, 0, "open mail pipe %s failed: ERR=%s\n",
- *cmd, strerror(errno));
- }
+ cmd, be.strerror());
+ }
+
+#if 1
+ if (!use_bsmtp) {
+ fprintf(bpipe->wfd, "Subject: Bacula Message\r\n\r\n");
+ }
+#endif
+
return bpipe;
}
goto rem_temp_file;
}
- if (!(bpipe=open_mail_pipe(jcr, &cmd, d))) {
+ if (!(bpipe=open_mail_pipe(jcr, cmd, d))) {
Pmsg0(000, "open mail pipe failed.\n");
goto rem_temp_file;
}
stat = close_bpipe(bpipe);
if (stat != 0 && msgs != daemon_msgs) {
+ berrno be;
+ be.set_errno(stat);
Dmsg1(150, "Calling emsg. CMD=%s\n", cmd);
- Jmsg3(jcr, M_ERROR, 0, _("Mail program terminated in error. stat=%d\n"
+ Jmsg2(jcr, M_ERROR, 0, _("Mail program terminated in error.\n"
"CMD=%s\n"
- "ERR=%s\n"), stat, cmd, strerror(stat));
+ "ERR=%s\n"), cmd, be.strerror());
}
free_memory(line);
rem_temp_file:
Dmsg2(800, "Enter dispatch_msg type=%d msg=%s\n", type, msg);
if (type == M_ABORT || type == M_ERROR_TERM) {
+#ifndef HAVE_WIN32
fputs(msg, stdout); /* print this here to INSURE that it is printed */
fflush(stdout);
+#endif
+#if !defined(HAVE_CONSOLE)
#if defined(HAVE_CYGWIN) || defined(HAVE_WIN32)
- MessageBox(NULL, msg, "Bacula", MB_OK);
+ /* If we don't exit on error, error messages are parsed by UA */
+ if (exit_on_error) {
+ MessageBox(NULL, msg, "Bacula", MB_OK);
+ }
+#endif
#endif
}
case MD_OPERATOR:
Dmsg1(800, "OPERATOR for collowing msg: %s\n", msg);
mcmd = get_pool_memory(PM_MESSAGE);
- if ((bpipe=open_mail_pipe(jcr, &mcmd, d))) {
+ if ((bpipe=open_mail_pipe(jcr, mcmd, d))) {
int stat;
fputs(msg, bpipe->wfd);
/* Messages to the operator go one at a time */
stat = close_bpipe(bpipe);
if (stat != 0) {
+ berrno be;
+ be.set_errno(stat);
Jmsg2(jcr, M_ERROR, 0, _("Operator mail program terminated in error.\n"
"CMD=%s\n"
- "ERR=%s\n"), mcmd, strerror(stat));
+ "ERR=%s\n"), mcmd, be.strerror());
}
}
free_pool_memory(mcmd);
Dmsg1(800, "MAIL for following msg: %s", msg);
if (!d->fd) {
POOLMEM *name = get_pool_memory(PM_MESSAGE);
- make_unique_mail_filename(jcr, &mp_chr(name), d);
+ make_unique_mail_filename(jcr, name, d);
d->fd = fopen(mp_chr(name), "w+");
if (!d->fd) {
d->fd = stdout;
/* visual studio passes the whole path to the file as well
* which makes for very long lines
*/
- char *f = strrchr(file, '\\');
+ const char *f = strrchr(file, '\\');
if (f) file = f + 1;
len = bsnprintf(buf, sizeof(buf), "%s: %s:%d ", my_name, file, line);
} else {
char *p = 0;
p[0] = 0; /* generate segmentation violation */
}
- if (type == M_ERROR_TERM) {
+ if ((type == M_ERROR_TERM) && exit_on_error) {
exit(1);
}
}
char *p = 0;
p[0] = 0; /* generate segmentation violation */
}
- if (type == M_ERROR_TERM) {
+ if ((type == M_ERROR_TERM) && exit_on_error) {
exit(1);
}
}
POOLMEM *pool_buf;
pool_buf = get_pool_memory(PM_EMSG);
- i = Mmsg(&pool_buf, "%s:%d ", file, line);
+ i = Mmsg(pool_buf, "%s:%d ", file, line);
for (;;) {
maxlen = sizeof_pool_memory(pool_buf) - i - 1;
va_start(arg_ptr, fmt);
len = bvsnprintf(pool_buf+i, maxlen, fmt, arg_ptr);
va_end(arg_ptr);
- if (len < 0 || len >= maxlen) {
+ if (len < 0 || len >= (maxlen-5)) {
pool_buf = realloc_pool_memory(pool_buf, maxlen + i + maxlen/2);
continue;
}
/*
* Edit a message into a Pool memory buffer, with file:lineno
- */
+ */
int m_msg(const char *file, int line, POOLMEM **pool_buf, const char *fmt, ...)
{
va_list arg_ptr;
va_start(arg_ptr, fmt);
len = bvsnprintf(*pool_buf+i, maxlen, fmt, arg_ptr);
va_end(arg_ptr);
- if (len < 0 || len >= maxlen) {
+ if (len < 0 || len >= (maxlen-5)) {
*pool_buf = realloc_pool_memory(*pool_buf, maxlen + i + maxlen/2);
continue;
}
return len;
}
+int m_msg(const char *file, int line, POOLMEM *&pool_buf, const char *fmt, ...)
+{
+ va_list arg_ptr;
+ int i, len, maxlen;
+
+ i = sprintf(pool_buf, "%s:%d ", file, line);
+
+ for (;;) {
+ maxlen = sizeof_pool_memory(pool_buf) - i - 1;
+ va_start(arg_ptr, fmt);
+ len = bvsnprintf(pool_buf+i, maxlen, fmt, arg_ptr);
+ va_end(arg_ptr);
+ if (len < 0 || len >= (maxlen-5)) {
+ pool_buf = realloc_pool_memory(pool_buf, maxlen + i + maxlen/2);
+ continue;
+ }
+ break;
+ }
+ return len;
+}
+
+
/*
* Edit a message into a Pool Memory buffer NO file:lineno
* Returns: string length of what was edited.
va_start(arg_ptr, fmt);
len = bvsnprintf(*pool_buf, maxlen, fmt, arg_ptr);
va_end(arg_ptr);
- if (len < 0 || len >= maxlen) {
+ if (len < 0 || len >= (maxlen-5)) {
*pool_buf = realloc_pool_memory(*pool_buf, maxlen + maxlen/2);
continue;
}
return len;
}
+int Mmsg(POOLMEM *&pool_buf, const char *fmt, ...)
+{
+ va_list arg_ptr;
+ int len, maxlen;
+
+ for (;;) {
+ maxlen = sizeof_pool_memory(pool_buf) - 1;
+ va_start(arg_ptr, fmt);
+ len = bvsnprintf(pool_buf, maxlen, fmt, arg_ptr);
+ va_end(arg_ptr);
+ if (len < 0 || len >= (maxlen-5)) {
+ pool_buf = realloc_pool_memory(pool_buf, maxlen + maxlen/2);
+ continue;
+ }
+ break;
+ }
+ return len;
+}
+
+
static pthread_mutex_t msg_queue_mutex = PTHREAD_MUTEX_INITIALIZER;
/*
va_start(arg_ptr, fmt);
len = bvsnprintf(pool_buf, maxlen, fmt, arg_ptr);
va_end(arg_ptr);
- if (len < 0 || len >= maxlen) {
+ if (len < 0 || len >= (maxlen-5)) {
pool_buf = realloc_pool_memory(pool_buf, maxlen + maxlen/2);
continue;
}
} else {
/* Queue message for later sending */
jcr->msg_queue->append(item);
+// Dmsg1(000, "queue item=%lu\n", (long unsigned)item);
}
V(msg_queue_mutex);
free_memory(pool_buf);
P(msg_queue_mutex);
jcr->dequeuing = true;
foreach_dlist(item, jcr->msg_queue) {
+// Dmsg1(000, "dequeue item=%lu\n", (long unsigned)item);
Jmsg(jcr, item->type, item->level, "%s", item->msg);
}
jcr->msg_queue->destroy();
jcr->dequeuing = false;
V(msg_queue_mutex);
-}
+}
/*
POOLMEM *pool_buf;
pool_buf = get_pool_memory(PM_EMSG);
- i = Mmsg(&pool_buf, "%s:%d ", file, line);
+ i = Mmsg(pool_buf, "%s:%d ", file, line);
for (;;) {
maxlen = sizeof_pool_memory(pool_buf) - i - 1;
va_start(arg_ptr, fmt);
len = bvsnprintf(pool_buf+i, maxlen, fmt, arg_ptr);
va_end(arg_ptr);
- if (len < 0 || len >= maxlen) {
+ if (len < 0 || len >= (maxlen-5)) {
pool_buf = realloc_pool_memory(pool_buf, maxlen + i + maxlen/2);
continue;
}
Qmsg(jcr, type, level, "%s", pool_buf);
free_memory(pool_buf);
}
+
+/*
+ * Define if e_msg must exit when M_ERROR_TERM is received
+ */
+void set_exit_on_error(int value) {
+ exit_on_error = value;
+}