/*
Bacula® - The Network Backup Solution
- Copyright (C) 2000-2010 Free Software Foundation Europe e.V.
+ Copyright (C) 2000-2012 Free Software Foundation Europe e.V.
The main author of Bacula is Kern Sibbald, with contributions from
many others, a complete list can be found in the file AUTHORS.
#include "bacula.h"
#include "jcr.h"
-sql_query p_sql_query = NULL;
-sql_escape p_sql_escape = NULL;
+sql_query_func p_sql_query = NULL;
+sql_escape_func p_sql_escape = NULL;
#define FULL_LOCATION 1 /* set for file:line in Debug messages */
utime_t daemon_start_time = 0; /* Daemon start time */
const char *version = VERSION " (" BDATE ")";
const char *dist_name = DISTNAME " " DISTVER;
-const int beef = BEEF;
-char my_name[30]; /* daemon name is stored here */
-char host_name[50]; /* host machine name */
+int beef = BEEF;
+char my_name[30] = {0}; /* daemon name is stored here */
+char host_name[50] = {0}; /* host machine name */
char *exepath = (char *)NULL;
char *exename = (char *)NULL;
int console_msg_pending = false;
/* Static storage */
+/* Exclude spaces but require .mail at end */
+#define MAIL_REGEX "^[^ ]+\\.mail$"
+
/* Allow only one thread to tweak d->fd at a time */
static pthread_mutex_t fides_mutex = PTHREAD_MUTEX_INITIALIZER;
static MSGS *daemon_msgs; /* global messages */
#else
static bool trace = false;
#endif
+static int hangup = 0;
/* Constants */
const char *host_os = HOST_OS;
const char *distname = DISTNAME;
const char *distver = DISTVER;
+/*
+ * Walk back in a string from end looking for a
+ * path separator.
+ * This routine is passed the start of the string and
+ * the end of the string, it returns either the beginning
+ * of the string or where it found a path separator.
+ */
+static const char *bstrrpath(const char *start, const char *end)
+{
+ while ( end > start ) {
+ end--;
+ if (IsPathSeparator(*end)) {
+ break;
+ }
+ }
+ return end;
+}
+
/* Some message class methods */
void MSGS::lock()
{
} else {
l = argv[0];
#if defined(HAVE_WIN32)
- /* On Windows allow c: junk */
+ /* On Windows allow c: drive specification */
if (l[1] == ':') {
l += 2;
}
}
}
-const char *
-get_db_type(void)
-{
- return catalog_db != NULL ? catalog_db : "unknown";
-}
-
void
set_db_type(const char *name)
{
return;
}
msgs->wait_not_in_use(); /* leaves fides_mutex set */
+ /* Note get_closing() does not lock because we are already locked */
+ if (msgs->get_closing()) {
+ msgs->unlock();
+ return;
+ }
msgs->set_closing();
msgs->unlock();
free_memory(line);
rem_temp_file:
/* Remove temp file */
- fclose(d->fd);
- d->fd = NULL;
- unlink(d->mail_filename);
- free_pool_memory(d->mail_filename);
- d->mail_filename = NULL;
+ if (d->fd) {
+ fclose(d->fd);
+ d->fd = NULL;
+ }
+ if (d->mail_filename) {
+ /* Exclude spaces in mail_filename */
+ safer_unlink(d->mail_filename, MAIL_REGEX);
+ free_pool_memory(d->mail_filename);
+ d->mail_filename = NULL;
+ }
Dmsg0(850, "end mail or mail on error\n");
break;
default:
return true;
}
+/* Split the output for syslog (it converts \n to ' ' and is
+ * limited to 1024 characters per syslog message
+ */
+static void send_to_syslog(int mode, const char *msg)
+{
+ int len;
+ char buf[1024];
+ const char *p2;
+ const char *p = msg;
+
+ while (*p && ((p2 = strchr(p, '\n')) != NULL)) {
+ len = MIN((int)sizeof(buf) - 1, p2 - p + 1); /* Add 1 to keep \n */
+ strncpy(buf, p, len);
+ buf[len] = 0;
+ syslog(mode, "%s", buf);
+ p = p2+1; /* skip \n */
+ }
+ if (*p != 0) { /* no \n at the end ? */
+ syslog(mode, "%s", p);
+ }
+}
+
/*
* Handle sending the message to the appropriate place
*/
/*
* We really should do an openlog() here.
*/
- syslog(LOG_DAEMON|LOG_ERR, "%s", msg);
+ send_to_syslog(LOG_DAEMON|LOG_ERR, msg);
break;
case MD_OPERATOR:
Dmsg1(850, "OPERATOR for following msg: %s\n", msg);
delivery_error(_("Msg delivery error: fopen %s failed: ERR=%s\n"), name,
be.bstrerror());
free_pool_memory(name);
- V(fides_mutex);
+ msgs->clear_in_use();
break;
}
d->mail_filename = name;
/*********************************************************************
*
- * This subroutine returns the filename portion of a Windows
- * path. It is used because Microsoft Visual Studio sets __FILE__
- * to the full path.
+ * This subroutine returns the filename portion of a path.
+ * It is used because some compilers set __FILE__
+ * to the full path. Try to return base + next higher path.
*/
-inline const char *
-get_basename(const char *pathname)
+const char *get_basename(const char *pathname)
{
-#if defined(_MSC_VER)
const char *basename;
- if ((basename = strrchr(pathname, '\\')) == NULL) {
- basename = pathname;
+ if ((basename = bstrrpath(pathname, pathname+strlen(pathname))) == pathname) {
+ /* empty */
+ } else if ((basename = bstrrpath(pathname, basename-1)) == pathname) {
+ /* empty */
} else {
basename++;
}
-
return basename;
-#else
- return pathname;
-#endif
}
/*
if (trace_fd) {
fputs(buf, trace_fd);
fflush(trace_fd);
+ return;
} else {
/* Some problem, turn off tracing */
trace = false;
}
- } else { /* not tracing */
- fputs(buf, stdout);
- fflush(stdout);
}
+ /* not tracing */
+ fputs(buf, stdout);
+ fflush(stdout);
}
/*********************************************************************
len = strlen(buf);
buf[len++] = ' ';
buf[len] = 0;
- fputs(buf, stdout);
+ pt_out(buf);
}
#ifdef FULL_LOCATION
}
}
+void set_hangup(int hangup_value)
+{
+ if (hangup_value < 0) {
+ return;
+ } else {
+ hangup = hangup_value;
+ }
+}
+
+int get_hangup(void)
+{
+ return hangup;
+}
+
bool get_trace(void)
{
return trace;
case M_FATAL:
len = bsnprintf(rbuf, sizeof(rbuf), _("%s JobId %u: Fatal error: "), my_name, JobId);
if (jcr) {
- set_jcr_job_status(jcr, JS_FatalError);
+ jcr->setJobStatus(JS_FatalError);
+ }
+ if (jcr && jcr->JobErrors == 0) {
+ jcr->JobErrors = 1;
}
break;
case M_ERROR:
POOLMEM *pool_buf;
pool_buf = get_pool_memory(PM_EMSG);
- i = Mmsg(pool_buf, "%s:%d ", file, line);
+ i = Mmsg(pool_buf, "%s:%d ", get_basename(file), line);
for (;;) {
maxlen = sizeof_pool_memory(pool_buf) - i - 1;