/*
Bacula® - The Network Backup Solution
- Copyright (C) 2000-2008 Free Software Foundation Europe e.V.
+ Copyright (C) 2000-2009 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.
} else if (items[i].handler == store_bool) {
*(bool *)(items[i].value) = items[i].default_value != 0;
} else if (items[i].handler == store_pint32 ||
- items[i].handler == store_int32) {
+ items[i].handler == store_int32 ||
+ items[i].handler == store_size32) {
*(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) {
+ } else if (items[i].handler == store_size64) {
*(uint64_t *)(items[i].value) = (uint64_t)items[i].default_value;
} else if (items[i].handler == store_time) {
*(utime_t *)(items[i].value) = (utime_t)items[i].default_value;
}
/* Store a size in bytes */
-void store_size(LEX *lc, RES_ITEM *item, int index, int pass)
+static void store_size(LEX *lc, RES_ITEM *item, int index, int pass, bool size32)
{
int token;
uint64_t uvalue;
scan_err1(lc, _("expected a size number, got: %s"), lc->str);
return;
}
- *(uint64_t *)(item->value) = uvalue;
+ if (size32) {
+ *(uint32_t *)(item->value) = (uint32_t)uvalue;
+ } else {
+ *(uint64_t *)(item->value) = uvalue;
+ }
break;
default:
scan_err1(lc, _("expected a size, got: %s"), lc->str);
Dmsg0(900, "Leave store_size\n");
}
+/* Store a size in bytes */
+void store_size32(LEX *lc, RES_ITEM *item, int index, int pass)
+{
+ store_size(lc, item, index, pass, true /* 32 bit */);
+}
+
+/* Store a size in bytes */
+void store_size64(LEX *lc, RES_ITEM *item, int index, int pass)
+{
+ store_size(lc, item, index, pass, false /* not 32 bit */);
+}
+
/* Store a time period in seconds */
void store_time(LEX *lc, RES_ITEM *item, int index, int pass)
void CONFIG::init(
const char *cf,
LEX_ERROR_HANDLER *scan_error,
- int err_type,
+ int32_t err_type,
void *vres_all,
- int res_all_size,
- int r_first,
- int r_last,
+ int32_t res_all_size,
+ int32_t r_first,
+ int32_t r_last,
RES_TABLE *resources,
RES **res_head)
{
if (first && (errstat=rwl_init(&res_lock)) != 0) {
berrno be;
- Emsg1(M_ABORT, 0, _("Unable to initialize resource lock. ERR=%s\n"),
+ Jmsg1(NULL, 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, MAX_PATH +1)) {
- cf = full_path;
+ if (!find_config_file(cf, full_path, MAX_PATH +1)) {
+ Jmsg0(NULL, M_ABORT, 0, _("Config filename too long.\n"));
}
+ cf = full_path;
/* Make two passes. The first builds the name symbol table,
* and the second picks up the items.
} else if (token == T_UTF16_BOM) {
scan_err0(lc, _("Currently we cannot handle UTF-16 source files. "
"Please convert the conf file to UTF-8\n"));
- return 0;
+ goto bail_out;
} else if (token != T_IDENTIFIER) {
scan_err1(lc, _("Expected a Resource name identifier, got: %s"), lc->str);
- return 0;
+ goto bail_out;
}
for (i=0; resources[i].name; i++) {
if (strcasecmp(resources[i].name, lc->str) == 0) {
}
if (state == p_none) {
scan_err1(lc, _("expected resource name, got: %s"), lc->str);
- return 0;
+ goto bail_out;
}
break;
case p_resource:
case T_IDENTIFIER:
if (level != 1) {
scan_err1(lc, _("not in resource definition: %s"), lc->str);
- return 0;
+ goto bail_out;
}
for (i=0; items[i].name; i++) {
if (strcasecmp(items[i].name, lc->str) == 0) {
Dmsg1 (900, "in T_IDENT got token=%s\n", lex_tok_to_str(token));
if (token != T_EQUALS) {
scan_err1(lc, _("expected an equals, got: %s"), lc->str);
- return 0;
+ goto bail_out;
}
}
Dmsg1(800, "calling handler for %s\n", items[i].name);
Dmsg1(900, "Keyword = %s\n", lc->str);
scan_err1(lc, _("Keyword \"%s\" not permitted in this resource.\n"
"Perhaps you left the trailing brace off of the previous resource."), lc->str);
- return 0;
+ goto bail_out;
}
break;
Dmsg0(900, "T_EOB => define new resource\n");
if (res_all.hdr.name == NULL) {
scan_err0(lc, _("Name not specified for resource"));
- return 0;
+ goto bail_out;
}
save_resource(res_type, items, pass); /* save resource */
break;
default:
scan_err2(lc, _("unexpected token %d %s in resource definition"),
token, lex_tok_to_str(token));
- return 0;
+ goto bail_out;
}
break;
default:
scan_err1(lc, _("Unknown parser state %d\n"), state);
- return 0;
+ goto bail_out;
}
}
if (state != p_none) {
scan_err0(lc, _("End of conf file reached with unclosed resource."));
- return 0;
+ goto bail_out;
}
if (debug_level >= 900 && pass == 2) {
int i;
}
Dmsg0(900, "Leave parse_config()\n");
return 1;
+bail_out:
+ if (lc) {
+ lc = lex_close_file(lc);
+ }
+ return 0;
}
const char *get_default_configdir()
#endif
}
+/*
+ * Returns false on error
+ * true on OK, with full_path set to where config file should be
+ */
static bool
find_config_file(const char *config_file, char *full_path, int max_path)
{
- if (first_path_separator(config_file) != NULL) {
- return false;
- }
-
- struct stat st;
+ int file_length = strlen(config_file) + 1;
- if (stat(config_file, &st) == 0) {
- return false;
+ /* If a full path specified, use it */
+ if (first_path_separator(config_file) != NULL) {
+ if (file_length > max_path) {
+ return false;
+ }
+ bstrncpy(full_path, config_file, file_length);
+ return true;
}
+ /* config_file is default file name, now find default dir */
const char *config_dir = get_default_configdir();
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) > max_path) {
return false;
}
full_path[dir_length++] = '/';
}
- memcpy(&full_path[dir_length], config_file, file_length + 1);
+ memcpy(&full_path[dir_length], config_file, file_length);
return true;
}