/*
Bacula® - The Network Backup Solution
- Copyright (C) 2000-2007 Free Software Foundation Europe e.V.
+ Copyright (C) 2000-2008 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.
This program is Free Software; you can redistribute it and/or
modify it under the terms of version two of the GNU General Public
- License as published by the Free Software Foundation plus additions
- that are listed in the file LICENSE.
+ License as published by the Free Software Foundation and included
+ in the file LICENSE.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
extern RES_TABLE resources[];
extern RES **res_head;
+/*
+ * Define the Union of all the common resource structure definitions.
+ */
+union URES {
+ MSGS res_msgs;
+ RES hdr;
+};
+
#if defined(_MSC_VER)
// 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;
+extern "C" URES res_all;
#else
-extern CURES res_all;
+extern URES res_all;
#endif
extern int res_all_size;
/* 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);
+static bool find_config_file(const char *config_file, char *full_path, int max_path);
/* Common Resource definitions */
* Initialize the static structure to zeros, then
* apply all the default values.
*/
-void init_resource(int type, RES_ITEM *items, int pass)
+static void init_resource(CONFIG *config, int type, RES_ITEM *items, int pass)
{
int i;
int rindex = type - r_first;
- static bool first = true;
- int errstat;
-
- if (first && (errstat=rwl_init(&res_lock)) != 0) {
- berrno be;
- Emsg1(M_ABORT, 0, _("Unable to initialize resource lock. ERR=%s\n"),
- be.bstrerror(errstat));
- }
- first = false;
- memset(&res_all, 0, res_all_size);
+ memset(config->m_res_all, 0, config->m_res_all_size);
res_all.hdr.rcode = type;
res_all.hdr.refcnt = 1;
free_pool_memory(dest);
Dmsg0(900, "done with dest codes\n");
break;
+
case MD_FILE: /* file */
case MD_APPEND: /* append */
dest = get_pool_memory(PM_MESSAGE);
p_resource
};
+CONFIG *new_config_parser()
+{
+ CONFIG *config;
+ config = (CONFIG *)malloc(sizeof(CONFIG));
+ memset(config, 0, sizeof(CONFIG));
+ return config;
+}
+
+void CONFIG::init(
+ const char *cf,
+ LEX_ERROR_HANDLER *scan_error,
+ int err_type,
+ void *vres_all,
+ int res_all_size,
+ int r_first,
+ int r_last,
+ RES_TABLE *resources,
+ RES **res_head)
+{
+ m_cf = cf;
+ m_scan_error = scan_error;
+ m_err_type = err_type;
+ m_res_all = vres_all;
+ m_res_all_size = res_all_size;
+ m_r_first = r_first;
+ m_r_last = r_last;
+ m_resources = resources;
+ m_res_head = res_head;
+}
+
/*********************************************************************
*
* Parse configuration file
*/
int
parse_config(const char *cf, LEX_ERROR_HANDLER *scan_error, int err_type)
+{
+ int ok;
+ CONFIG *config = new_config_parser();
+ config->init(cf, scan_error, err_type, (void *)&res_all, res_all_size,
+ r_first, r_last, resources, res_head);
+ ok = config->parse_config();
+ free(config);
+ return ok;
+}
+
+
+bool CONFIG::parse_config()
{
LEX *lc = NULL;
int token, i, pass;
enum parse_state state = p_none;
RES_ITEM *items = NULL;
int level = 0;
+ static bool first = true;
+ int errstat;
+ const char *cf = m_cf;
+ LEX_ERROR_HANDLER *scan_error = m_scan_error;
+ int err_type = m_err_type;
- char *full_path = (char *)alloca(MAX_PATH);
+ if (first && (errstat=rwl_init(&res_lock)) != 0) {
+ berrno be;
+ Emsg1(M_ABORT, 0, _("Unable to initialize resource lock. ERR=%s\n"),
+ be.bstrerror(errstat));
+ }
+ first = false;
+
+ char *full_path = (char *)alloca(MAX_PATH + 1);
- if (find_config_file(cf, full_path)) {
+ if (find_config_file(cf, full_path, MAX_PATH +1)) {
cf = full_path;
}
}
lex_set_error_handler_error_type(lc, err_type) ;
while ((token=lex_get_token(lc, T_ALL)) != T_EOF) {
- Dmsg1(900, "parse got token=%s\n", lex_tok_to_str(token));
+ Dmsg3(900, "parse state=%d pass=%d got token=%s\n", state, pass,
+ lex_tok_to_str(token));
switch (state) {
case p_none:
if (token == T_EOL) {
/* We can assume the file is UTF-8 as we have seen a UTF-8 BOM */
break;
} else if (token == T_UTF16_BOM) {
- scan_err0(lc, _("Currently we cannot handle UTF-16 source files. Please convert to UTF-16\n"));
+ scan_err0(lc, _("Currently we cannot handle UTF-16 source files. "
+ "Please convert the conf file to UTF-8\n"));
return 0;
} else if (token != T_IDENTIFIER) {
scan_err1(lc, _("Expected a Resource name identifier, got: %s"), lc->str);
}
for (i=0; resources[i].name; i++) {
if (strcasecmp(resources[i].name, lc->str) == 0) {
- state = p_resource;
items = resources[i].items;
+ if (!items) {
+ break;
+ }
+ state = p_resource;
res_type = resources[i].rcode;
- init_resource(res_type, items, pass);
+ init_resource(this, res_type, items, pass);
break;
}
}
#endif
}
-bool
-find_config_file(const char *config_file, char *full_path)
+static bool
+find_config_file(const char *config_file, char *full_path, int max_path)
{
if (first_path_separator(config_file) != NULL) {
return false;
}
const char *config_dir = get_default_configdir();
- size_t dir_length = strlen(config_dir);
- size_t file_length = strlen(config_file);
+ int dir_length = strlen(config_dir);
+ int file_length = strlen(config_file);
- if ((dir_length + 1 + file_length + 1) > MAX_PATH) {
+ if ((dir_length + 1 + file_length + 1) > max_path) {
return false;
}
* Free configuration resources
*
*/
+void CONFIG::free_resources()
+{
+ for (int i=m_r_first; i<=m_r_last; i++) {
+ free_resource(m_res_head[i-m_r_first], i);
+ m_res_head[i-m_r_first] = NULL;
+ }
+}
+
+RES **CONFIG::save_resources()
+{
+ int num = m_r_last - m_r_first + 1;
+ RES **res = (RES **)malloc(num*sizeof(RES *));
+ for (int i=0; i<num; i++) {
+ res[i] = m_res_head[i];
+ m_res_head[i] = NULL;
+ }
+ return res;
+}
+
+RES **CONFIG::new_res_head()
+{
+ int size = (m_r_last - m_r_first + 1) * sizeof(RES *);
+ RES **res = (RES **)malloc(size);
+ memset(res, 0, size);
+ return res;
+}
+
void free_config_resources()
{
for (int i=r_first; i<=r_last; i++) {
}
}
+#ifdef xxx
RES **save_config_resources()
{
int num = r_last - r_first + 1;
memset(res, 0, size);
return res;
}
+#endif