2 Bacula(R) - The Network Backup Solution
4 Copyright (C) 2000-2016 Kern Sibbald
6 The original author of Bacula is Kern Sibbald, with contributions
7 from many others, a complete list can be found in the file AUTHORS.
9 You may use this file and others of this release according to the
10 license defined in the LICENSE file, which includes the Affero General
11 Public License, v3.0 ("AGPLv3") and some additional permissions and
12 terms pursuant to its AGPLv3 Section 7.
14 This notice must be preserved when any source code is
15 conveyed and/or propagated.
17 Bacula(R) is a registered trademark of Kern Sibbald.
20 * Master Configuration routines.
22 * This file contains the common parts of the Bacula
23 * configuration routines.
25 * Note, the configuration file parser consists of three parts
27 * 1. The generic lexical scanner in lib/lex.c and lib/lex.h
29 * 2. The generic config scanner in lib/parse_conf.c and
31 * These files contain the parser code, some utility
32 * routines, and the common store routines (name, int,
33 * string, time, int64, size, ...).
35 * 3. The daemon specific file, which contains the Resource
36 * definitions as well as any specific store routines
37 * for the resource records.
39 * N.B. This is a two pass parser, so if you malloc() a string
40 * in a "store" routine, you must ensure to do it during
41 * only one of the two passes, or to free it between.
42 * Also, note that the resource record is malloced and
43 * saved in save_resource() during pass 1. Anything that
44 * you want saved after pass two (e.g. resource pointers)
45 * must explicitly be done in save_resource. Take a look
46 * at the Job resource in src/dird/dird_conf.c to see how
49 * Kern Sibbald, January MM
56 #if defined(HAVE_WIN32)
63 * Define the Union of all the common resource structure definitions.
71 // work around visual studio name mangling preventing external linkage since res_all
72 // is declared as a different type when instantiated.
73 extern "C" URES res_all;
78 extern brwlock_t res_lock; /* resource lock */
81 /* Forward referenced subroutines */
82 static void scan_types(LEX *lc, MSGS *msg, int dest, char *where, char *cmd);
83 static const char *get_default_configdir();
84 static bool find_config_file(const char *config_file, char *full_path, int max_path);
86 /* Common Resource definitions */
88 /* Message resource directives
89 * name handler value code flags default_value
91 RES_ITEM msgs_items[] = {
92 {"Name", store_name, ITEM(res_msgs.hdr.name), 0, 0, 0},
93 {"Description", store_str, ITEM(res_msgs.hdr.desc), 0, 0, 0},
94 {"MailCommand", store_str, ITEM(res_msgs.mail_cmd), 0, 0, 0},
95 {"OperatorCommand", store_str, ITEM(res_msgs.operator_cmd), 0, 0, 0},
96 {"Syslog", store_msgs, ITEM(res_msgs), MD_SYSLOG, 0, 0},
97 {"Mail", store_msgs, ITEM(res_msgs), MD_MAIL, 0, 0},
98 {"MailOnError", store_msgs, ITEM(res_msgs), MD_MAIL_ON_ERROR, 0, 0},
99 {"MailOnSuccess", store_msgs, ITEM(res_msgs), MD_MAIL_ON_SUCCESS, 0, 0},
100 {"File", store_msgs, ITEM(res_msgs), MD_FILE, 0, 0},
101 {"Append", store_msgs, ITEM(res_msgs), MD_APPEND, 0, 0},
102 {"Stdout", store_msgs, ITEM(res_msgs), MD_STDOUT, 0, 0},
103 {"Stderr", store_msgs, ITEM(res_msgs), MD_STDERR, 0, 0},
104 {"Director", store_msgs, ITEM(res_msgs), MD_DIRECTOR, 0, 0},
105 {"Console", store_msgs, ITEM(res_msgs), MD_CONSOLE, 0, 0},
106 {"Operator", store_msgs, ITEM(res_msgs), MD_OPERATOR, 0, 0},
107 {"Catalog", store_msgs, ITEM(res_msgs), MD_CATALOG, ITEM_LAST, 0},
108 {NULL, NULL, {0}, 0, 0, 0}
115 /* Various message types */
116 static struct s_mtypes msg_types[] = {
121 {"Warning", M_WARNING},
124 {"NotSaved", M_NOTSAVED},
125 {"Skipped", M_SKIPPED},
127 {"Terminate", M_TERM},
128 {"Restored", M_RESTORED},
129 {"Security", M_SECURITY},
131 {"VolMgmt", M_VOLMGMT},
132 {"ErrorTerm", M_ERROR_TERM},
138 * Tape Label types permitted in Pool records
140 * tape label label code = token
142 s_kw tapelabels[] = {
143 {"Bacula", B_BACULA_LABEL},
144 {"ANSI", B_ANSI_LABEL},
145 {"IBM", B_IBM_LABEL},
150 /* Simply print a message */
151 static void prtmsg(void *sock, const char *fmt, ...)
155 va_start(arg_ptr, fmt);
156 vfprintf(stdout, fmt, arg_ptr);
160 const char *res_to_str(int rcode)
162 if (rcode < r_first || rcode > r_last) {
163 return _("***UNKNOWN***");
165 return resources[rcode-r_first].name;
171 * Initialize the static structure to zeros, then
172 * apply all the default values.
174 static void init_resource(CONFIG *config, int type, RES_ITEM *items, int pass)
177 int rindex = type - r_first;
179 memset(config->m_res_all, 0, config->m_res_all_size);
180 res_all.hdr.rcode = type;
181 res_all.hdr.refcnt = 1;
183 /* Set defaults in each item */
184 for (i=0; items[i].name; i++) {
185 Dmsg3(900, "Item=%s def=%s defval=%d\n", items[i].name,
186 (items[i].flags & ITEM_DEFAULT) ? "yes" : "no",
187 items[i].default_value);
188 if (items[i].flags & ITEM_DEFAULT && items[i].default_value != 0) {
189 if (items[i].handler == store_bit) {
190 *(uint32_t *)(items[i].value) |= items[i].code;
191 } else if (items[i].handler == store_bool) {
192 *(bool *)(items[i].value) = items[i].default_value != 0;
193 } else if (items[i].handler == store_pint32 ||
194 items[i].handler == store_int32 ||
195 items[i].handler == store_size32) {
196 *(uint32_t *)(items[i].value) = items[i].default_value;
197 } else if (items[i].handler == store_int64) {
198 *(int64_t *)(items[i].value) = items[i].default_value;
199 } else if (items[i].handler == store_size64) {
200 *(uint64_t *)(items[i].value) = (uint64_t)items[i].default_value;
201 } else if (items[i].handler == store_speed) {
202 *(uint64_t *)(items[i].value) = (uint64_t)items[i].default_value;
203 } else if (items[i].handler == store_time) {
204 *(utime_t *)(items[i].value) = (utime_t)items[i].default_value;
205 } else if (pass == 1 && items[i].handler == store_addresses) {
206 init_default_addresses((dlist**)items[i].value, items[i].default_value);
209 /* If this triggers, take a look at lib/parse_conf.h */
210 if (i >= MAX_RES_ITEMS) {
211 Emsg1(M_ERROR_TERM, 0, _("Too many items in %s resource\n"), resources[rindex]);
217 /* Store Messages Destination information */
218 void store_msgs(LEX *lc, RES_ITEM *item, int index, int pass)
225 Dmsg2(900, "store_msgs pass=%d code=%d\n", pass, item->code);
227 switch (item->code) {
230 case MD_SYSLOG: /* syslog */
233 scan_types(lc, (MSGS *)(item->value), item->code, NULL, NULL);
235 case MD_OPERATOR: /* send to operator */
236 case MD_DIRECTOR: /* send to Director */
237 case MD_MAIL: /* mail */
238 case MD_MAIL_ON_ERROR: /* mail if Job errors */
239 case MD_MAIL_ON_SUCCESS: /* mail if Job succeeds */
240 if (item->code == MD_OPERATOR) {
241 cmd = res_all.res_msgs.operator_cmd;
243 cmd = res_all.res_msgs.mail_cmd;
245 dest = get_pool_memory(PM_MESSAGE);
248 /* Pick up comma separated list of destinations */
250 token = lex_get_token(lc, T_NAME); /* scan destination */
251 dest = check_pool_memory_size(dest, dest_len + lc->str_len + 2);
253 pm_strcat(dest, " "); /* separate multiple destinations with space */
256 pm_strcat(dest, lc->str);
257 dest_len += lc->str_len;
258 Dmsg2(900, "store_msgs newdest=%s: dest=%s:\n", lc->str, NPRT(dest));
259 token = lex_get_token(lc, T_SKIP_EOL);
260 if (token == T_COMMA) {
261 continue; /* get another destination */
263 if (token != T_EQUALS) {
264 scan_err1(lc, _("expected an =, got: %s"), lc->str);
269 Dmsg1(900, "mail_cmd=%s\n", NPRT(cmd));
270 scan_types(lc, (MSGS *)(item->value), item->code, dest, cmd);
271 free_pool_memory(dest);
272 Dmsg0(900, "done with dest codes\n");
275 case MD_FILE: /* file */
276 case MD_APPEND: /* append */
277 dest = get_pool_memory(PM_MESSAGE);
278 /* Pick up a single destination */
279 token = lex_get_token(lc, T_NAME); /* scan destination */
280 pm_strcpy(dest, lc->str);
281 dest_len = lc->str_len;
282 token = lex_get_token(lc, T_SKIP_EOL);
283 Dmsg1(900, "store_msgs dest=%s:\n", NPRT(dest));
284 if (token != T_EQUALS) {
285 scan_err1(lc, _("expected an =, got: %s"), lc->str);
288 scan_types(lc, (MSGS *)(item->value), item->code, dest, NULL);
289 free_pool_memory(dest);
290 Dmsg0(900, "done with dest codes\n");
294 scan_err1(lc, _("Unknown item code: %d\n"), item->code);
299 set_bit(index, res_all.hdr.item_present);
300 Dmsg0(900, "Done store_msgs\n");
304 * Scan for message types and add them to the message
305 * destination. The basic job here is to connect message types
306 * (WARNING, ERROR, FATAL, INFO, ...) with an appropriate
307 * destination (MAIL, FILE, OPERATOR, ...)
309 static void scan_types(LEX *lc, MSGS *msg, int dest_code, char *where, char *cmd)
317 lex_get_token(lc, T_NAME); /* expect at least one type */
319 if (lc->str[0] == '!') {
326 for (i=0; msg_types[i].name; i++) {
327 if (strcasecmp(str, msg_types[i].name) == 0) {
328 msg_type = msg_types[i].token;
334 scan_err1(lc, _("message type: %s not found"), str);
338 if (msg_type == M_MAX+1) { /* all? */
339 for (i=1; i<=M_MAX; i++) { /* yes set all types */
340 add_msg_dest(msg, dest_code, i, where, cmd);
343 rem_msg_dest(msg, dest_code, msg_type, where);
345 add_msg_dest(msg, dest_code, msg_type, where, cmd);
350 Dmsg0(900, "call lex_get_token() to eat comma\n");
351 lex_get_token(lc, T_ALL); /* eat comma */
353 Dmsg0(900, "Done scan_types()\n");
358 * This routine is ONLY for resource names
359 * Store a name at specified address.
361 void store_name(LEX *lc, RES_ITEM *item, int index, int pass)
363 POOLMEM *msg = get_pool_memory(PM_EMSG);
364 lex_get_token(lc, T_NAME);
365 if (!is_name_valid(lc->str, &msg)) {
366 scan_err1(lc, "%s\n", msg);
369 free_pool_memory(msg);
370 /* Store the name both pass 1 and pass 2 */
371 if (*(item->value)) {
372 scan_err2(lc, _("Attempt to redefine name \"%s\" to \"%s\"."),
373 *(item->value), lc->str);
376 *(item->value) = bstrdup(lc->str);
378 set_bit(index, res_all.hdr.item_present);
383 * Store a name string at specified address
384 * A name string is limited to MAX_RES_NAME_LENGTH
386 void store_strname(LEX *lc, RES_ITEM *item, int index, int pass)
388 lex_get_token(lc, T_NAME);
391 *(item->value) = bstrdup(lc->str);
394 set_bit(index, res_all.hdr.item_present);
397 /* Store a string at specified address */
398 void store_str(LEX *lc, RES_ITEM *item, int index, int pass)
400 lex_get_token(lc, T_STRING);
402 *(item->value) = bstrdup(lc->str);
405 set_bit(index, res_all.hdr.item_present);
409 * Store a directory name at specified address. Note, we do
410 * shell expansion except if the string begins with a vertical
411 * bar (i.e. it will likely be passed to the shell later).
413 void store_dir(LEX *lc, RES_ITEM *item, int index, int pass)
415 lex_get_token(lc, T_STRING);
417 if (lc->str[0] != '|') {
418 do_shell_expansion(lc->str, sizeof_pool_memory(lc->str));
420 *(item->value) = bstrdup(lc->str);
423 set_bit(index, res_all.hdr.item_present);
427 /* Store a password specified address in MD5 coding */
428 void store_password(LEX *lc, RES_ITEM *item, int index, int pass)
431 struct MD5Context md5c;
432 unsigned char digest[CRYPTO_DIGEST_MD5_SIZE];
436 lex_get_token(lc, T_STRING);
439 MD5Update(&md5c, (unsigned char *) (lc->str), lc->str_len);
440 MD5Final(digest, &md5c);
441 for (i = j = 0; i < sizeof(digest); i++) {
442 sprintf(&sig[j], "%02x", digest[i]);
445 *(item->value) = bstrdup(sig);
448 set_bit(index, res_all.hdr.item_present);
452 /* Store a resource at specified address.
453 * If we are in pass 2, do a lookup of the
456 void store_res(LEX *lc, RES_ITEM *item, int index, int pass)
460 lex_get_token(lc, T_NAME);
462 res = GetResWithName(item->code, lc->str);
464 scan_err3(lc, _("Could not find config Resource %s referenced on line %d : %s\n"),
465 lc->str, lc->line_no, lc->line);
468 if (*(item->value)) {
469 scan_err3(lc, _("Attempt to redefine resource \"%s\" referenced on line %d : %s\n"),
470 item->name, lc->line_no, lc->line);
473 *(item->value) = (char *)res;
476 set_bit(index, res_all.hdr.item_present);
480 * Store a resource pointer in an alist. default_value indicates how many
481 * times this routine can be called -- i.e. how many alists
483 * If we are in pass 2, do a lookup of the
486 void store_alist_res(LEX *lc, RES_ITEM *item, int index, int pass)
489 int count = item->default_value;
494 if (count == 0) { /* always store in item->value */
496 if ((item->value)[i] == NULL) {
497 list = New(alist(10, not_owned_by_alist));
499 list = (alist *)(item->value)[i];
502 /* Find empty place to store this directive */
503 while ((item->value)[i] != NULL && i++ < count) { }
505 scan_err4(lc, _("Too many %s directives. Max. is %d. line %d: %s\n"),
506 lc->str, count, lc->line_no, lc->line);
509 list = New(alist(10, not_owned_by_alist));
513 lex_get_token(lc, T_NAME); /* scan next item */
514 res = GetResWithName(item->code, lc->str);
516 scan_err3(lc, _("Could not find config Resource \"%s\" referenced on line %d : %s\n"),
517 item->name, lc->line_no, lc->line);
520 Dmsg5(900, "Append %p to alist %p size=%d i=%d %s\n",
521 res, list, list->size(), i, item->name);
523 (item->value)[i] = (char *)list;
524 if (lc->ch != ',') { /* if no other item follows */
527 lex_get_token(lc, T_ALL); /* eat comma */
531 set_bit(index, res_all.hdr.item_present);
536 * Store a string in an alist.
538 void store_alist_str(LEX *lc, RES_ITEM *item, int index, int pass)
543 if (*(item->value) == NULL) {
544 list = New(alist(10, owned_by_alist));
545 *(item->value) = (char *)list;
547 list = (alist *)(*(item->value));
550 lex_get_token(lc, T_STRING); /* scan next item */
551 Dmsg4(900, "Append %s to alist 0x%p size=%d %s\n",
552 lc->str, list, list->size(), item->name);
553 list->append(bstrdup(lc->str));
554 if (lc->ch != ',') { /* if no other item follows */
557 lex_get_token(lc, T_ALL); /* eat comma */
561 set_bit(index, res_all.hdr.item_present);
567 * Store default values for Resource from xxxDefs
568 * If we are in pass 2, do a lookup of the
569 * resource and store everything not explicitly set
572 * Note, here item points to the main resource (e.g. Job, not
573 * the jobdefs, which we look up).
575 void store_defs(LEX *lc, RES_ITEM *item, int index, int pass)
579 lex_get_token(lc, T_NAME);
581 Dmsg2(900, "Code=%d name=%s\n", item->code, lc->str);
582 res = GetResWithName(item->code, lc->str);
584 scan_err3(lc, _("Missing config Resource \"%s\" referenced on line %d : %s\n"),
585 lc->str, lc->line_no, lc->line);
594 /* Store an integer at specified address */
595 void store_int32(LEX *lc, RES_ITEM *item, int index, int pass)
597 lex_get_token(lc, T_INT32);
598 *(uint32_t *)(item->value) = lc->int32_val;
600 set_bit(index, res_all.hdr.item_present);
603 /* Store a positive integer at specified address */
604 void store_pint32(LEX *lc, RES_ITEM *item, int index, int pass)
606 lex_get_token(lc, T_PINT32);
607 *(uint32_t *)(item->value) = lc->pint32_val;
609 set_bit(index, res_all.hdr.item_present);
613 /* Store an 64 bit integer at specified address */
614 void store_int64(LEX *lc, RES_ITEM *item, int index, int pass)
616 lex_get_token(lc, T_INT64);
617 *(int64_t *)(item->value) = lc->int64_val;
619 set_bit(index, res_all.hdr.item_present);
622 enum store_unit_type {
627 /* Store a size in bytes */
628 static void store_int_unit(LEX *lc, RES_ITEM *item, int index, int pass,
629 bool size32, enum store_unit_type type)
635 Dmsg0(900, "Enter store_unit\n");
636 token = lex_get_token(lc, T_SKIP_EOL);
641 case T_UNQUOTED_STRING:
642 bstrncpy(bsize, lc->str, sizeof(bsize)); /* save first part */
643 /* if terminated by space, scan and get modifier */
644 while (lc->ch == ' ') {
645 token = lex_get_token(lc, T_ALL);
649 case T_UNQUOTED_STRING:
650 bstrncat(bsize, lc->str, sizeof(bsize));
654 if (type == STORE_SIZE) {
655 if (!size_to_uint64(bsize, strlen(bsize), &uvalue)) {
656 scan_err1(lc, _("expected a size number, got: %s"), lc->str);
660 if (!speed_to_uint64(bsize, strlen(bsize), &uvalue)) {
661 scan_err1(lc, _("expected a speed number, got: %s"), lc->str);
666 *(uint32_t *)(item->value) = (uint32_t)uvalue;
668 *(uint64_t *)(item->value) = uvalue;
672 scan_err2(lc, _("expected a %s, got: %s"),
673 (type == STORE_SIZE)?_("size"):_("speed"), lc->str);
676 if (token != T_EOL) {
679 set_bit(index, res_all.hdr.item_present);
680 Dmsg0(900, "Leave store_unit\n");
683 /* Store a size in bytes */
684 void store_size32(LEX *lc, RES_ITEM *item, int index, int pass)
686 store_int_unit(lc, item, index, pass, true /* 32 bit */, STORE_SIZE);
689 /* Store a size in bytes */
690 void store_size64(LEX *lc, RES_ITEM *item, int index, int pass)
692 store_int_unit(lc, item, index, pass, false /* not 32 bit */, STORE_SIZE);
695 /* Store a speed in bytes/s */
696 void store_speed(LEX *lc, RES_ITEM *item, int index, int pass)
698 store_int_unit(lc, item, index, pass, false /* 64 bit */, STORE_SPEED);
701 /* Store a time period in seconds */
702 void store_time(LEX *lc, RES_ITEM *item, int index, int pass)
708 token = lex_get_token(lc, T_SKIP_EOL);
713 case T_UNQUOTED_STRING:
714 bstrncpy(period, lc->str, sizeof(period)); /* get first part */
715 /* if terminated by space, scan and get modifier */
716 while (lc->ch == ' ') {
717 token = lex_get_token(lc, T_ALL);
721 case T_UNQUOTED_STRING:
722 bstrncat(period, lc->str, sizeof(period));
726 if (!duration_to_utime(period, &utime)) {
727 scan_err1(lc, _("expected a time period, got: %s"), period);
730 *(utime_t *)(item->value) = utime;
733 scan_err1(lc, _("expected a time period, got: %s"), lc->str);
736 if (token != T_EOL) {
739 set_bit(index, res_all.hdr.item_present);
743 /* Store a yes/no in a bit field */
744 void store_bit(LEX *lc, RES_ITEM *item, int index, int pass)
746 lex_get_token(lc, T_NAME);
747 if (strcasecmp(lc->str, "yes") == 0 || strcasecmp(lc->str, "true") == 0) {
748 *(uint32_t *)(item->value) |= item->code;
749 } else if (strcasecmp(lc->str, "no") == 0 || strcasecmp(lc->str, "false") == 0) {
750 *(uint32_t *)(item->value) &= ~(item->code);
752 scan_err2(lc, _("Expect %s, got: %s"), "YES, NO, TRUE, or FALSE", lc->str); /* YES and NO must not be translated */
756 set_bit(index, res_all.hdr.item_present);
759 /* Store a bool in a bit field */
760 void store_bool(LEX *lc, RES_ITEM *item, int index, int pass)
762 lex_get_token(lc, T_NAME);
763 if (strcasecmp(lc->str, "yes") == 0 || strcasecmp(lc->str, "true") == 0) {
764 *(bool *)(item->value) = true;
765 } else if (strcasecmp(lc->str, "no") == 0 || strcasecmp(lc->str, "false") == 0) {
766 *(bool *)(item->value) = false;
768 scan_err2(lc, _("Expect %s, got: %s"), "YES, NO, TRUE, or FALSE", lc->str); /* YES and NO must not be translated */
772 set_bit(index, res_all.hdr.item_present);
777 * Store Tape Label Type (Bacula, ANSI, IBM)
780 void store_label(LEX *lc, RES_ITEM *item, int index, int pass)
784 lex_get_token(lc, T_NAME);
785 /* Store the label pass 2 so that type is defined */
786 for (i=0; tapelabels[i].name; i++) {
787 if (strcasecmp(lc->str, tapelabels[i].name) == 0) {
788 *(uint32_t *)(item->value) = tapelabels[i].token;
794 scan_err1(lc, _("Expected a Tape Label keyword, got: %s"), lc->str);
798 set_bit(index, res_all.hdr.item_present);
808 CONFIG *new_config_parser()
811 config = (CONFIG *)malloc(sizeof(CONFIG));
812 memset(config, 0, sizeof(CONFIG));
818 LEX_ERROR_HANDLER *scan_error,
821 int32_t res_all_size,
824 RES_TABLE *resources,
828 m_scan_error = scan_error;
829 m_err_type = err_type;
830 m_res_all = vres_all;
831 m_res_all_size = res_all_size;
834 m_resources = resources;
835 m_res_head = res_head;
838 /*********************************************************************
840 * Parse configuration file
842 * Return 0 if reading failed, 1 otherwise
843 * Note, the default behavior unless you have set an alternate
844 * scan_error handler is to die on an error.
846 bool CONFIG::parse_config()
851 enum parse_state state = p_none;
852 RES_ITEM *items = NULL;
854 static bool first = true;
856 const char *cf = m_cf;
857 LEX_ERROR_HANDLER *scan_error = m_scan_error;
858 int err_type = m_err_type;
860 if (first && (errstat=rwl_init(&res_lock)) != 0) {
862 Jmsg1(NULL, M_ABORT, 0, _("Unable to initialize resource lock. ERR=%s\n"),
863 be.bstrerror(errstat));
867 char *full_path = (char *)alloca(MAX_PATH + 1);
869 if (!find_config_file(cf, full_path, MAX_PATH +1)) {
870 Jmsg0(NULL, M_ABORT, 0, _("Config filename too long.\n"));
874 /* Make two passes. The first builds the name symbol table,
875 * and the second picks up the items.
877 Dmsg0(900, "Enter parse_config()\n");
878 for (pass=1; pass <= 2; pass++) {
879 Dmsg1(900, "parse_config pass %d\n", pass);
880 if ((lc = lex_open_file(lc, cf, scan_error)) == NULL) {
882 /* We must create a lex packet to print the error */
883 lc = (LEX *)malloc(sizeof(LEX));
884 memset(lc, 0, sizeof(LEX));
885 lc->str = get_memory(5000);
887 lc->scan_error = scan_error;
889 lex_set_default_error_handler(lc);
891 lex_set_error_handler_error_type(lc, err_type) ;
892 pm_strcpy(lc->str, cf);
894 scan_err2(lc, _("Cannot open config file \"%s\": %s\n"),
895 lc->str, be.bstrerror());
896 free_pool_memory(lc->str);
900 lex_set_error_handler_error_type(lc, err_type) ;
901 while ((token=lex_get_token(lc, T_ALL)) != T_EOF) {
902 Dmsg3(900, "parse state=%d pass=%d got token=%s\n", state, pass,
903 lex_tok_to_str(token));
906 if (token == T_EOL) {
908 } else if (token == T_UTF8_BOM) {
909 /* We can assume the file is UTF-8 as we have seen a UTF-8 BOM */
911 } else if (token == T_UTF16_BOM) {
912 scan_err0(lc, _("Currently we cannot handle UTF-16 source files. "
913 "Please convert the conf file to UTF-8\n"));
915 } else if (token != T_IDENTIFIER) {
916 scan_err1(lc, _("Expected a Resource name identifier, got: %s"), lc->str);
919 for (i=0; resources[i].name; i++) {
920 if (strcasecmp(resources[i].name, lc->str) == 0) {
921 items = resources[i].items;
926 res_type = resources[i].rcode;
927 init_resource(this, res_type, items, pass);
931 if (state == p_none) {
932 scan_err1(lc, _("expected resource name, got: %s"), lc->str);
943 scan_err1(lc, _("not in resource definition: %s"), lc->str);
946 for (i=0; items[i].name; i++) {
947 if (strcasecmp(items[i].name, lc->str) == 0) {
948 /* If the ITEM_NO_EQUALS flag is set we do NOT
949 * scan for = after the keyword */
950 if (!(items[i].flags & ITEM_NO_EQUALS)) {
951 token = lex_get_token(lc, T_SKIP_EOL);
952 Dmsg1 (900, "in T_IDENT got token=%s\n", lex_tok_to_str(token));
953 if (token != T_EQUALS) {
954 scan_err1(lc, _("expected an equals, got: %s"), lc->str);
958 Dmsg1(800, "calling handler for %s\n", items[i].name);
959 /* Call item handler */
960 items[i].handler(lc, &items[i], i, pass);
966 Dmsg2(900, "level=%d id=%s\n", level, lc->str);
967 Dmsg1(900, "Keyword = %s\n", lc->str);
968 scan_err1(lc, _("Keyword \"%s\" not permitted in this resource.\n"
969 "Perhaps you left the trailing brace off of the previous resource."), lc->str);
977 Dmsg0(900, "T_EOB => define new resource\n");
978 if (res_all.hdr.name == NULL) {
979 scan_err0(lc, _("Name not specified for resource"));
982 save_resource(res_type, items, pass); /* save resource */
989 scan_err2(lc, _("unexpected token %d %s in resource definition"),
990 token, lex_tok_to_str(token));
995 scan_err1(lc, _("Unknown parser state %d\n"), state);
999 if (state != p_none) {
1000 scan_err0(lc, _("End of conf file reached with unclosed resource."));
1003 if (debug_level >= 900 && pass == 2) {
1005 for (i=m_r_first; i<=m_r_last; i++) {
1006 dump_resource(i, m_res_head[i-m_r_first], prtmsg, NULL);
1009 lc = lex_close_file(lc);
1011 Dmsg0(900, "Leave parse_config()\n");
1015 lc = lex_close_file(lc);
1020 const char *get_default_configdir()
1026 * Returns false on error
1027 * true on OK, with full_path set to where config file should be
1030 find_config_file(const char *config_file, char *full_path, int max_path)
1032 int file_length = strlen(config_file) + 1;
1034 /* If a full path specified, use it */
1035 if (first_path_separator(config_file) != NULL) {
1036 if (file_length > max_path) {
1039 bstrncpy(full_path, config_file, file_length);
1043 /* config_file is default file name, now find default dir */
1044 const char *config_dir = get_default_configdir();
1045 int dir_length = strlen(config_dir);
1047 if ((dir_length + 1 + file_length) > max_path) {
1051 memcpy(full_path, config_dir, dir_length + 1);
1053 if (!IsPathSeparator(full_path[dir_length - 1])) {
1054 full_path[dir_length++] = '/';
1057 memcpy(&full_path[dir_length], config_file, file_length);
1062 /*********************************************************************
1064 * Free configuration resources
1067 void CONFIG::free_resources()
1069 for (int i=m_r_first; i<=m_r_last; i++) {
1070 free_resource(m_res_head[i-m_r_first], i);
1071 m_res_head[i-m_r_first] = NULL;
1075 RES **CONFIG::save_resources()
1077 int num = m_r_last - m_r_first + 1;
1078 RES **res = (RES **)malloc(num*sizeof(RES *));
1079 for (int i=0; i<num; i++) {
1080 res[i] = m_res_head[i];
1081 m_res_head[i] = NULL;
1086 RES **CONFIG::new_res_head()
1088 int size = (m_r_last - m_r_first + 1) * sizeof(RES *);
1089 RES **res = (RES **)malloc(size);
1090 memset(res, 0, size);
1096 void free_config_resources()
1098 for (int i=r_first; i<=r_last; i++) {
1099 free_resource(res_head[i-r_first], i);
1100 res_head[i-r_first] = NULL;
1104 RES **save_config_resources()
1106 int num = r_last - r_first + 1;
1107 RES **res = (RES **)malloc(num*sizeof(RES *));
1108 for (int i=0; i<num; i++) {
1109 res[i] = res_head[i];
1115 RES **new_res_head()
1117 int size = (r_last - r_first + 1) * sizeof(RES *);
1118 RES **res = (RES **)malloc(size);
1119 memset(res, 0, size);