/*
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.
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- Bacula® is a registered trademark of John Walker.
+ Bacula® is a registered trademark of Kern Sibbald.
The licensor of Bacula is the Free Software Foundation Europe
(FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
Switzerland, email:ftf@fsfeurope.org.
#define MAX_PATH 1024
#endif
-/* Each daemon has a slightly different set of
- * resources, so it will define the following
- * global values.
+/*
+ * Define the Union of all the common resource structure definitions.
*/
-extern int r_first;
-extern int r_last;
-extern RES_TABLE resources[];
-extern RES **res_head;
+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;
extern brwlock_t res_lock; /* resource lock */
* 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;
items[i].default_value);
if (items[i].flags & ITEM_DEFAULT && items[i].default_value != 0) {
if (items[i].handler == store_bit) {
- *(int *)(items[i].value) |= items[i].code;
+ *(uint32_t *)(items[i].value) |= items[i].code;
} else if (items[i].handler == store_bool) {
*(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;
+ } else if (items[i].handler == store_pint32 ||
+ items[i].handler == store_int32) {
+ *(uint32_t *)(items[i].value) = items[i].default_value;
} else if (items[i].handler == store_int64) {
*(int64_t *)(items[i].value) = items[i].default_value;
} else if (items[i].handler == store_size) {
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);
/* Store an integer at specified address */
-void store_int(LEX *lc, RES_ITEM *item, int index, int pass)
+void store_int32(LEX *lc, RES_ITEM *item, int index, int pass)
{
lex_get_token(lc, T_INT32);
- *(int *)(item->value) = lc->int32_val;
+ *(uint32_t *)(item->value) = lc->int32_val;
scan_to_eol(lc);
set_bit(index, res_all.hdr.item_present);
}
/* Store a positive integer at specified address */
-void store_pint(LEX *lc, RES_ITEM *item, int index, int pass)
+void store_pint32(LEX *lc, RES_ITEM *item, int index, int pass)
{
lex_get_token(lc, T_PINT32);
- *(int *)(item->value) = lc->pint32_val;
+ *(uint32_t *)(item->value) = lc->pint32_val;
scan_to_eol(lc);
set_bit(index, res_all.hdr.item_present);
}
{
lex_get_token(lc, T_NAME);
if (strcasecmp(lc->str, "yes") == 0 || strcasecmp(lc->str, "true") == 0) {
- *(int *)(item->value) |= item->code;
+ *(uint32_t *)(item->value) |= item->code;
} else if (strcasecmp(lc->str, "no") == 0 || strcasecmp(lc->str, "false") == 0) {
- *(int *)(item->value) &= ~(item->code);
+ *(uint32_t *)(item->value) &= ~(item->code);
} else {
scan_err2(lc, _("Expect %s, got: %s"), "YES, NO, TRUE, or FALSE", lc->str); /* YES and NO must not be translated */
}
/* Store the label pass 2 so that type is defined */
for (i=0; tapelabels[i].name; i++) {
if (strcasecmp(lc->str, tapelabels[i].name) == 0) {
- *(int *)(item->value) = tapelabels[i].token;
+ *(uint32_t *)(item->value) = tapelabels[i].token;
i = 0;
break;
}
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
* Note, the default behavior unless you have set an alternate
* scan_error handler is to die on an error.
*/
+#ifdef xxx
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;
+}
+#endif
+
+
+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;
+
+ 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);
}
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) {
}
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;
}
}
}
if (debug_level >= 900 && pass == 2) {
int i;
- for (i=r_first; i<=r_last; i++) {
- dump_resource(i, res_head[i-r_first], prtmsg, NULL);
+ for (i=m_r_first; i<=m_r_last; i++) {
+ dump_resource(i, m_res_head[i-m_r_first], prtmsg, NULL);
}
}
lc = lex_close_file(lc);
#endif
}
-bool
+static bool
find_config_file(const char *config_file, char *full_path, int max_path)
{
if (first_path_separator(config_file) != NULL) {
* 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;
+}
+
+
+#ifdef xxx
void free_config_resources()
{
for (int i=r_first; i<=r_last; i++) {
memset(res, 0, size);
return res;
}
+#endif