#include "bacula.h"
+#if defined(HAVE_WIN32)
+#include "shlobj.h"
+#else
+#define MAX_PATH 1024
+#endif
+
/* Each daemon has a slightly different set of
* resources, so it will define the following
* global values.
extern RES **res_head;
#if defined(_MSC_VER)
-// work around visual studio name manling preventing external linkage since res_all
+// work around visual studio name mangling preventing external linkage since res_all
// is declared as a different type when instantiated.
extern "C" CURES res_all;
#else
/* Forward referenced subroutines */
static void scan_types(LEX *lc, MSGS *msg, int dest, char *where, char *cmd);
-
+static const char *get_default_configdir();
+static bool find_config_file(const char *config_file, char *full_path);
/* Common Resource definitions */
{"director", store_msgs, ITEM(res_msgs), MD_DIRECTOR, 0, 0},
{"console", store_msgs, ITEM(res_msgs), MD_CONSOLE, 0, 0},
{"operator", store_msgs, ITEM(res_msgs), MD_OPERATOR, 0, 0},
+ {"catalog", store_msgs, ITEM(res_msgs), MD_CATALOG, 0, 0},
{NULL, NULL, {0}, 0, 0, 0}
};
{"restored", M_RESTORED},
{"security", M_SECURITY},
{"alert", M_ALERT},
+ {"volmgmt", M_VOLMGMT},
{"all", M_MAX+1},
{NULL, 0}
};
if (items[i].handler == store_bit) {
*(int *)(items[i].value) |= items[i].code;
} else if (items[i].handler == store_bool) {
- *(bool *)(items[i].value) = items[i].default_value;
+ *(bool *)(items[i].value) = items[i].default_value != 0;
} else if (items[i].handler == store_pint ||
items[i].handler == store_int) {
*(int *)(items[i].value) = items[i].default_value;
case MD_STDERR:
case MD_SYSLOG: /* syslog */
case MD_CONSOLE:
+ case MD_CATALOG:
scan_types(lc, (MSGS *)(item->value), item->code, NULL, NULL);
break;
case MD_OPERATOR: /* send to operator */
RES_ITEM *items = NULL;
int level = 0;
+ char *full_path = (char *)alloca(MAX_PATH);
+
+ if (find_config_file(cf, full_path)) {
+ cf = full_path;
+ }
+
/* Make two passes. The first builds the name symbol table,
* and the second picks up the items.
*/
if (token == T_EOL) {
break;
}
+ if (token == T_UNICODE_MARK) {
+ break;
+ }
if (token != T_IDENTIFIER) {
scan_err1(lc, _("Expected a Resource name identifier, got: %s"), lc->str);
return 0;
}
if (state == p_none) {
scan_err1(lc, _("expected resource name, got: %s"), lc->str);
- return 0;
+ return 0;
}
break;
case p_resource:
return 1;
}
+const char *get_default_configdir()
+{
+#if defined(HAVE_WIN32)
+#define DEFAULT_CONFIGDIR "C:\\Documents and Settings\\All Users\\Application Data\\Bacula"
+
+ HRESULT hr;
+ static char szConfigDir[MAX_PATH + 1] = { 0 };
+
+ if (szConfigDir[0] == '\0') {
+ hr = SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL, 0, szConfigDir);
+
+ if (SUCCEEDED(hr)) {
+ bstrncat(szConfigDir, "\\Bacula", sizeof(szConfigDir));
+ } else {
+ bstrncpy(szConfigDir, DEFAULT_CONFIGDIR, sizeof(szConfigDir));
+ }
+ }
+ return szConfigDir;
+#else
+ return "/etc/bacula";
+#endif
+}
+
+bool
+find_config_file(const char *config_file, char *full_path)
+{
+#if defined(HAVE_WIN32)
+ if (strpbrk(config_file, ":/\\") != NULL) {
+ return false;
+ }
+#else
+ if (strchr(config_file, '/') != NULL) {
+ return false;
+ }
+#endif
+
+ struct stat st;
+
+ if (stat(config_file, &st) == 0) {
+ return false;
+ }
+
+ const char *config_dir = get_default_configdir();
+ size_t dir_length = strlen(config_dir);
+ size_t file_length = strlen(config_file);
+
+ if ((dir_length + 1 + file_length + 1) > MAX_PATH) {
+ return false;
+ }
+
+ memcpy(full_path, config_dir, dir_length + 1);
+
+ if (full_path[dir_length - 1] != '/' &&
+ full_path[dir_length - 1] != '\\') {
+ full_path[dir_length++] = '/';
+ }
+
+ memcpy(&full_path[dir_length], config_file, file_length + 1);
+
+ return true;
+}
+
/*********************************************************************
*
* Free configuration resources