2 Bacula® - The Network Backup Solution
4 Copyright (C) 2000-2009 Free Software Foundation Europe e.V.
6 The main author of Bacula is Kern Sibbald, with contributions from
7 many others, a complete list can be found in the file AUTHORS.
8 This program is Free Software; you can redistribute it and/or
9 modify it under the terms of version two of the GNU General Public
10 License as published by the Free Software Foundation and included
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 Bacula® is a registered trademark of Kern Sibbald.
24 The licensor of Bacula is the Free Software Foundation Europe
25 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26 Switzerland, email:ftf@fsfeurope.org.
29 * Master Configuration routines.
31 * This file contains the common parts of the Bacula
32 * configuration routines.
34 * Note, the configuration file parser consists of three parts
36 * 1. The generic lexical scanner in lib/lex.c and lib/lex.h
38 * 2. The generic config scanner in lib/parse_conf.c and
40 * These files contain the parser code, some utility
41 * routines, and the common store routines (name, int,
42 * string, time, int64, size, ...).
44 * 3. The daemon specific file, which contains the Resource
45 * definitions as well as any specific store routines
46 * for the resource records.
48 * N.B. This is a two pass parser, so if you malloc() a string
49 * in a "store" routine, you must ensure to do it during
50 * only one of the two passes, or to free it between.
51 * Also, note that the resource record is malloced and
52 * saved in save_resource() during pass 1. Anything that
53 * you want saved after pass two (e.g. resource pointers)
54 * must explicitly be done in save_resource. Take a look
55 * at the Job resource in src/dird/dird_conf.c to see how
58 * Kern Sibbald, January MM
66 #if defined(HAVE_WIN32)
73 * Define the Union of all the common resource structure definitions.
81 // work around visual studio name mangling preventing external linkage since res_all
82 // is declared as a different type when instantiated.
83 extern "C" URES res_all;
88 extern brwlock_t res_lock; /* resource lock */
91 /* Forward referenced subroutines */
92 static void scan_types(LEX *lc, MSGS *msg, int dest, char *where, char *cmd);
93 static const char *get_default_configdir();
94 static bool find_config_file(const char *config_file, char *full_path, int max_path);
96 /* Common Resource definitions */
98 /* Message resource directives
99 * name handler value code flags default_value
101 RES_ITEM msgs_items[] = {
102 {"name", store_name, ITEM(res_msgs.hdr.name), 0, 0, 0},
103 {"description", store_str, ITEM(res_msgs.hdr.desc), 0, 0, 0},
104 {"mailcommand", store_str, ITEM(res_msgs.mail_cmd), 0, 0, 0},
105 {"operatorcommand", store_str, ITEM(res_msgs.operator_cmd), 0, 0, 0},
106 {"syslog", store_msgs, ITEM(res_msgs), MD_SYSLOG, 0, 0},
107 {"mail", store_msgs, ITEM(res_msgs), MD_MAIL, 0, 0},
108 {"mailonerror", store_msgs, ITEM(res_msgs), MD_MAIL_ON_ERROR, 0, 0},
109 {"mailonsuccess", store_msgs, ITEM(res_msgs), MD_MAIL_ON_SUCCESS, 0, 0},
110 {"file", store_msgs, ITEM(res_msgs), MD_FILE, 0, 0},
111 {"append", store_msgs, ITEM(res_msgs), MD_APPEND, 0, 0},
112 {"stdout", store_msgs, ITEM(res_msgs), MD_STDOUT, 0, 0},
113 {"stderr", store_msgs, ITEM(res_msgs), MD_STDERR, 0, 0},
114 {"director", store_msgs, ITEM(res_msgs), MD_DIRECTOR, 0, 0},
115 {"console", store_msgs, ITEM(res_msgs), MD_CONSOLE, 0, 0},
116 {"operator", store_msgs, ITEM(res_msgs), MD_OPERATOR, 0, 0},
117 {"catalog", store_msgs, ITEM(res_msgs), MD_CATALOG, 0, 0},
118 {NULL, NULL, {0}, 0, 0, 0}
125 /* Various message types */
126 static struct s_mtypes msg_types[] = {
131 {"warning", M_WARNING},
134 {"notsaved", M_NOTSAVED},
135 {"skipped", M_SKIPPED},
137 {"terminate", M_TERM},
138 {"restored", M_RESTORED},
139 {"security", M_SECURITY},
141 {"volmgmt", M_VOLMGMT},
146 /* Used for certain KeyWord tables */
153 * Tape Label types permitted in Pool records
155 * tape label label code = token
157 static s_kw tapelabels[] = {
158 {"bacula", B_BACULA_LABEL},
159 {"ansi", B_ANSI_LABEL},
160 {"ibm", B_IBM_LABEL},
165 /* Simply print a message */
166 static void prtmsg(void *sock, const char *fmt, ...)
170 va_start(arg_ptr, fmt);
171 vfprintf(stdout, fmt, arg_ptr);
175 const char *res_to_str(int rcode)
177 if (rcode < r_first || rcode > r_last) {
178 return _("***UNKNOWN***");
180 return resources[rcode-r_first].name;
186 * Initialize the static structure to zeros, then
187 * apply all the default values.
189 static void init_resource(CONFIG *config, int type, RES_ITEM *items, int pass)
192 int rindex = type - r_first;
194 memset(config->m_res_all, 0, config->m_res_all_size);
195 res_all.hdr.rcode = type;
196 res_all.hdr.refcnt = 1;
198 /* Set defaults in each item */
199 for (i=0; items[i].name; i++) {
200 Dmsg3(900, "Item=%s def=%s defval=%d\n", items[i].name,
201 (items[i].flags & ITEM_DEFAULT) ? "yes" : "no",
202 items[i].default_value);
203 if (items[i].flags & ITEM_DEFAULT && items[i].default_value != 0) {
204 if (items[i].handler == store_bit) {
205 *(uint32_t *)(items[i].value) |= items[i].code;
206 } else if (items[i].handler == store_bool) {
207 *(bool *)(items[i].value) = items[i].default_value != 0;
208 } else if (items[i].handler == store_pint32 ||
209 items[i].handler == store_int32 ||
210 items[i].handler == store_size32) {
211 *(uint32_t *)(items[i].value) = items[i].default_value;
212 } else if (items[i].handler == store_int64) {
213 *(int64_t *)(items[i].value) = items[i].default_value;
214 } else if (items[i].handler == store_size64) {
215 *(uint64_t *)(items[i].value) = (uint64_t)items[i].default_value;
216 } else if (items[i].handler == store_time) {
217 *(utime_t *)(items[i].value) = (utime_t)items[i].default_value;
218 } else if (pass == 1 && items[i].handler == store_addresses) {
219 init_default_addresses((dlist**)items[i].value, items[i].default_value);
222 /* If this triggers, take a look at lib/parse_conf.h */
223 if (i >= MAX_RES_ITEMS) {
224 Emsg1(M_ERROR_TERM, 0, _("Too many items in %s resource\n"), resources[rindex]);
230 /* Store Messages Destination information */
231 void store_msgs(LEX *lc, RES_ITEM *item, int index, int pass)
238 Dmsg2(900, "store_msgs pass=%d code=%d\n", pass, item->code);
240 switch (item->code) {
243 case MD_SYSLOG: /* syslog */
246 scan_types(lc, (MSGS *)(item->value), item->code, NULL, NULL);
248 case MD_OPERATOR: /* send to operator */
249 case MD_DIRECTOR: /* send to Director */
250 case MD_MAIL: /* mail */
251 case MD_MAIL_ON_ERROR: /* mail if Job errors */
252 case MD_MAIL_ON_SUCCESS: /* mail if Job succeeds */
253 if (item->code == MD_OPERATOR) {
254 cmd = res_all.res_msgs.operator_cmd;
256 cmd = res_all.res_msgs.mail_cmd;
258 dest = get_pool_memory(PM_MESSAGE);
261 /* Pick up comma separated list of destinations */
263 token = lex_get_token(lc, T_NAME); /* scan destination */
264 dest = check_pool_memory_size(dest, dest_len + lc->str_len + 2);
266 pm_strcat(dest, " "); /* separate multiple destinations with space */
269 pm_strcat(dest, lc->str);
270 dest_len += lc->str_len;
271 Dmsg2(900, "store_msgs newdest=%s: dest=%s:\n", lc->str, NPRT(dest));
272 token = lex_get_token(lc, T_SKIP_EOL);
273 if (token == T_COMMA) {
274 continue; /* get another destination */
276 if (token != T_EQUALS) {
277 scan_err1(lc, _("expected an =, got: %s"), lc->str);
282 Dmsg1(900, "mail_cmd=%s\n", NPRT(cmd));
283 scan_types(lc, (MSGS *)(item->value), item->code, dest, cmd);
284 free_pool_memory(dest);
285 Dmsg0(900, "done with dest codes\n");
288 case MD_FILE: /* file */
289 case MD_APPEND: /* append */
290 dest = get_pool_memory(PM_MESSAGE);
291 /* Pick up a single destination */
292 token = lex_get_token(lc, T_NAME); /* scan destination */
293 pm_strcpy(dest, lc->str);
294 dest_len = lc->str_len;
295 token = lex_get_token(lc, T_SKIP_EOL);
296 Dmsg1(900, "store_msgs dest=%s:\n", NPRT(dest));
297 if (token != T_EQUALS) {
298 scan_err1(lc, _("expected an =, got: %s"), lc->str);
301 scan_types(lc, (MSGS *)(item->value), item->code, dest, NULL);
302 free_pool_memory(dest);
303 Dmsg0(900, "done with dest codes\n");
307 scan_err1(lc, _("Unknown item code: %d\n"), item->code);
312 set_bit(index, res_all.hdr.item_present);
313 Dmsg0(900, "Done store_msgs\n");
317 * Scan for message types and add them to the message
318 * destination. The basic job here is to connect message types
319 * (WARNING, ERROR, FATAL, INFO, ...) with an appropriate
320 * destination (MAIL, FILE, OPERATOR, ...)
322 static void scan_types(LEX *lc, MSGS *msg, int dest_code, char *where, char *cmd)
330 lex_get_token(lc, T_NAME); /* expect at least one type */
332 if (lc->str[0] == '!') {
339 for (i=0; msg_types[i].name; i++) {
340 if (strcasecmp(str, msg_types[i].name) == 0) {
341 msg_type = msg_types[i].token;
347 scan_err1(lc, _("message type: %s not found"), str);
351 if (msg_type == M_MAX+1) { /* all? */
352 for (i=1; i<=M_MAX; i++) { /* yes set all types */
353 add_msg_dest(msg, dest_code, i, where, cmd);
356 rem_msg_dest(msg, dest_code, msg_type, where);
358 add_msg_dest(msg, dest_code, msg_type, where, cmd);
363 Dmsg0(900, "call lex_get_token() to eat comma\n");
364 lex_get_token(lc, T_ALL); /* eat comma */
366 Dmsg0(900, "Done scan_types()\n");
371 * This routine is ONLY for resource names
372 * Store a name at specified address.
374 void store_name(LEX *lc, RES_ITEM *item, int index, int pass)
376 POOLMEM *msg = get_pool_memory(PM_EMSG);
377 lex_get_token(lc, T_NAME);
378 if (!is_name_valid(lc->str, &msg)) {
379 scan_err1(lc, "%s\n", msg);
382 free_pool_memory(msg);
383 /* Store the name both pass 1 and pass 2 */
384 if (*(item->value)) {
385 scan_err2(lc, _("Attempt to redefine name \"%s\" to \"%s\"."),
386 *(item->value), lc->str);
389 *(item->value) = bstrdup(lc->str);
391 set_bit(index, res_all.hdr.item_present);
396 * Store a name string at specified address
397 * A name string is limited to MAX_RES_NAME_LENGTH
399 void store_strname(LEX *lc, RES_ITEM *item, int index, int pass)
401 lex_get_token(lc, T_NAME);
404 *(item->value) = bstrdup(lc->str);
407 set_bit(index, res_all.hdr.item_present);
410 /* Store a string at specified address */
411 void store_str(LEX *lc, RES_ITEM *item, int index, int pass)
413 lex_get_token(lc, T_STRING);
415 *(item->value) = bstrdup(lc->str);
418 set_bit(index, res_all.hdr.item_present);
422 * Store a directory name at specified address. Note, we do
423 * shell expansion except if the string begins with a vertical
424 * bar (i.e. it will likely be passed to the shell later).
426 void store_dir(LEX *lc, RES_ITEM *item, int index, int pass)
428 lex_get_token(lc, T_STRING);
430 if (lc->str[0] != '|') {
431 do_shell_expansion(lc->str, sizeof(lc->str));
433 *(item->value) = bstrdup(lc->str);
436 set_bit(index, res_all.hdr.item_present);
440 /* Store a password specified address in MD5 coding */
441 void store_password(LEX *lc, RES_ITEM *item, int index, int pass)
444 struct MD5Context md5c;
445 unsigned char digest[CRYPTO_DIGEST_MD5_SIZE];
449 lex_get_token(lc, T_STRING);
452 MD5Update(&md5c, (unsigned char *) (lc->str), lc->str_len);
453 MD5Final(digest, &md5c);
454 for (i = j = 0; i < sizeof(digest); i++) {
455 sprintf(&sig[j], "%02x", digest[i]);
458 *(item->value) = bstrdup(sig);
461 set_bit(index, res_all.hdr.item_present);
465 /* Store a resource at specified address.
466 * If we are in pass 2, do a lookup of the
469 void store_res(LEX *lc, RES_ITEM *item, int index, int pass)
473 lex_get_token(lc, T_NAME);
475 res = GetResWithName(item->code, lc->str);
477 scan_err3(lc, _("Could not find config Resource %s referenced on line %d : %s\n"),
478 lc->str, lc->line_no, lc->line);
481 if (*(item->value)) {
482 scan_err3(lc, _("Attempt to redefine resource \"%s\" referenced on line %d : %s\n"),
483 item->name, lc->line_no, lc->line);
486 *(item->value) = (char *)res;
489 set_bit(index, res_all.hdr.item_present);
493 * Store a resource pointer in an alist. default_value indicates how many
494 * times this routine can be called -- i.e. how many alists
496 * If we are in pass 2, do a lookup of the
499 void store_alist_res(LEX *lc, RES_ITEM *item, int index, int pass)
502 int count = item->default_value;
507 if (count == 0) { /* always store in item->value */
509 if ((item->value)[i] == NULL) {
510 list = New(alist(10, not_owned_by_alist));
512 list = (alist *)(item->value)[i];
515 /* Find empty place to store this directive */
516 while ((item->value)[i] != NULL && i++ < count) { }
518 scan_err4(lc, _("Too many %s directives. Max. is %d. line %d: %s\n"),
519 lc->str, count, lc->line_no, lc->line);
522 list = New(alist(10, not_owned_by_alist));
526 lex_get_token(lc, T_NAME); /* scan next item */
527 res = GetResWithName(item->code, lc->str);
529 scan_err3(lc, _("Could not find config Resource \"%s\" referenced on line %d : %s\n"),
530 item->name, lc->line_no, lc->line);
533 Dmsg5(900, "Append %p to alist %p size=%d i=%d %s\n",
534 res, list, list->size(), i, item->name);
536 (item->value)[i] = (char *)list;
537 if (lc->ch != ',') { /* if no other item follows */
540 lex_get_token(lc, T_ALL); /* eat comma */
544 set_bit(index, res_all.hdr.item_present);
549 * Store a string in an alist.
551 void store_alist_str(LEX *lc, RES_ITEM *item, int index, int pass)
556 if (*(item->value) == NULL) {
557 list = New(alist(10, owned_by_alist));
559 list = (alist *)(*(item->value));
562 lex_get_token(lc, T_STRING); /* scan next item */
563 Dmsg4(900, "Append %s to alist %p size=%d %s\n",
564 lc->str, list, list->size(), item->name);
565 list->append(bstrdup(lc->str));
566 *(item->value) = (char *)list;
569 set_bit(index, res_all.hdr.item_present);
575 * Store default values for Resource from xxxDefs
576 * If we are in pass 2, do a lookup of the
577 * resource and store everything not explicitly set
580 * Note, here item points to the main resource (e.g. Job, not
581 * the jobdefs, which we look up).
583 void store_defs(LEX *lc, RES_ITEM *item, int index, int pass)
587 lex_get_token(lc, T_NAME);
589 Dmsg2(900, "Code=%d name=%s\n", item->code, lc->str);
590 res = GetResWithName(item->code, lc->str);
592 scan_err3(lc, _("Missing config Resource \"%s\" referenced on line %d : %s\n"),
593 lc->str, lc->line_no, lc->line);
602 /* Store an integer at specified address */
603 void store_int32(LEX *lc, RES_ITEM *item, int index, int pass)
605 lex_get_token(lc, T_INT32);
606 *(uint32_t *)(item->value) = lc->int32_val;
608 set_bit(index, res_all.hdr.item_present);
611 /* Store a positive integer at specified address */
612 void store_pint32(LEX *lc, RES_ITEM *item, int index, int pass)
614 lex_get_token(lc, T_PINT32);
615 *(uint32_t *)(item->value) = lc->pint32_val;
617 set_bit(index, res_all.hdr.item_present);
621 /* Store an 64 bit integer at specified address */
622 void store_int64(LEX *lc, RES_ITEM *item, int index, int pass)
624 lex_get_token(lc, T_INT64);
625 *(int64_t *)(item->value) = lc->int64_val;
627 set_bit(index, res_all.hdr.item_present);
630 /* Store a size in bytes */
631 static void store_size(LEX *lc, RES_ITEM *item, int index, int pass, bool size32)
637 Dmsg0(900, "Enter store_size\n");
638 token = lex_get_token(lc, T_SKIP_EOL);
643 case T_UNQUOTED_STRING:
644 bstrncpy(bsize, lc->str, sizeof(bsize)); /* save first part */
645 /* if terminated by space, scan and get modifier */
646 while (lc->ch == ' ') {
647 token = lex_get_token(lc, T_ALL);
651 case T_UNQUOTED_STRING:
652 bstrncat(bsize, lc->str, sizeof(bsize));
656 if (!size_to_uint64(bsize, strlen(bsize), &uvalue)) {
657 scan_err1(lc, _("expected a size number, got: %s"), lc->str);
661 *(uint32_t *)(item->value) = (uint32_t)uvalue;
663 *(uint64_t *)(item->value) = uvalue;
667 scan_err1(lc, _("expected a size, got: %s"), lc->str);
670 if (token != T_EOL) {
673 set_bit(index, res_all.hdr.item_present);
674 Dmsg0(900, "Leave store_size\n");
677 /* Store a size in bytes */
678 void store_size32(LEX *lc, RES_ITEM *item, int index, int pass)
680 store_size(lc, item, index, pass, true /* 32 bit */);
683 /* Store a size in bytes */
684 void store_size64(LEX *lc, RES_ITEM *item, int index, int pass)
686 store_size(lc, item, index, pass, false /* not 32 bit */);
690 /* Store a time period in seconds */
691 void store_time(LEX *lc, RES_ITEM *item, int index, int pass)
697 token = lex_get_token(lc, T_SKIP_EOL);
702 case T_UNQUOTED_STRING:
703 bstrncpy(period, lc->str, sizeof(period)); /* get first part */
704 /* if terminated by space, scan and get modifier */
705 while (lc->ch == ' ') {
706 token = lex_get_token(lc, T_ALL);
710 case T_UNQUOTED_STRING:
711 bstrncat(period, lc->str, sizeof(period));
715 if (!duration_to_utime(period, &utime)) {
716 scan_err1(lc, _("expected a time period, got: %s"), period);
719 *(utime_t *)(item->value) = utime;
722 scan_err1(lc, _("expected a time period, got: %s"), lc->str);
725 if (token != T_EOL) {
728 set_bit(index, res_all.hdr.item_present);
732 /* Store a yes/no in a bit field */
733 void store_bit(LEX *lc, RES_ITEM *item, int index, int pass)
735 lex_get_token(lc, T_NAME);
736 if (strcasecmp(lc->str, "yes") == 0 || strcasecmp(lc->str, "true") == 0) {
737 *(uint32_t *)(item->value) |= item->code;
738 } else if (strcasecmp(lc->str, "no") == 0 || strcasecmp(lc->str, "false") == 0) {
739 *(uint32_t *)(item->value) &= ~(item->code);
741 scan_err2(lc, _("Expect %s, got: %s"), "YES, NO, TRUE, or FALSE", lc->str); /* YES and NO must not be translated */
745 set_bit(index, res_all.hdr.item_present);
748 /* Store a bool in a bit field */
749 void store_bool(LEX *lc, RES_ITEM *item, int index, int pass)
751 lex_get_token(lc, T_NAME);
752 if (strcasecmp(lc->str, "yes") == 0 || strcasecmp(lc->str, "true") == 0) {
753 *(bool *)(item->value) = true;
754 } else if (strcasecmp(lc->str, "no") == 0 || strcasecmp(lc->str, "false") == 0) {
755 *(bool *)(item->value) = false;
757 scan_err2(lc, _("Expect %s, got: %s"), "YES, NO, TRUE, or FALSE", lc->str); /* YES and NO must not be translated */
761 set_bit(index, res_all.hdr.item_present);
766 * Store Tape Label Type (Bacula, ANSI, IBM)
769 void store_label(LEX *lc, RES_ITEM *item, int index, int pass)
773 token = lex_get_token(lc, T_NAME);
774 /* Store the label pass 2 so that type is defined */
775 for (i=0; tapelabels[i].name; i++) {
776 if (strcasecmp(lc->str, tapelabels[i].name) == 0) {
777 *(uint32_t *)(item->value) = tapelabels[i].token;
783 scan_err1(lc, _("Expected a Tape Label keyword, got: %s"), lc->str);
787 set_bit(index, res_all.hdr.item_present);
797 CONFIG *new_config_parser()
800 config = (CONFIG *)malloc(sizeof(CONFIG));
801 memset(config, 0, sizeof(CONFIG));
807 LEX_ERROR_HANDLER *scan_error,
810 int32_t res_all_size,
813 RES_TABLE *resources,
817 m_scan_error = scan_error;
818 m_err_type = err_type;
819 m_res_all = vres_all;
820 m_res_all_size = res_all_size;
823 m_resources = resources;
824 m_res_head = res_head;
827 /*********************************************************************
829 * Parse configuration file
831 * Return 0 if reading failed, 1 otherwise
832 * Note, the default behavior unless you have set an alternate
833 * scan_error handler is to die on an error.
837 parse_config(const char *cf, LEX_ERROR_HANDLER *scan_error, int err_type)
840 CONFIG *config = new_config_parser();
841 config->init(cf, scan_error, err_type, (void *)&res_all, res_all_size,
842 r_first, r_last, resources, res_head);
843 ok = config->parse_config();
850 bool CONFIG::parse_config()
855 enum parse_state state = p_none;
856 RES_ITEM *items = NULL;
858 static bool first = true;
860 const char *cf = m_cf;
861 LEX_ERROR_HANDLER *scan_error = m_scan_error;
862 int err_type = m_err_type;
864 if (first && (errstat=rwl_init(&res_lock)) != 0) {
866 Jmsg1(NULL, M_ABORT, 0, _("Unable to initialize resource lock. ERR=%s\n"),
867 be.bstrerror(errstat));
871 char *full_path = (char *)alloca(MAX_PATH + 1);
873 if (!find_config_file(cf, full_path, MAX_PATH +1)) {
874 Jmsg0(NULL, M_ABORT, 0, _("Config filename too long.\n"));
878 /* Make two passes. The first builds the name symbol table,
879 * and the second picks up the items.
881 Dmsg0(900, "Enter parse_config()\n");
882 for (pass=1; pass <= 2; pass++) {
883 Dmsg1(900, "parse_config pass %d\n", pass);
884 if ((lc = lex_open_file(lc, cf, scan_error)) == NULL) {
886 /* We must create a lex packet to print the error */
887 lc = (LEX *)malloc(sizeof(LEX));
888 memset(lc, 0, sizeof(LEX));
890 lc->scan_error = scan_error;
892 lex_set_default_error_handler(lc);
894 lex_set_error_handler_error_type(lc, err_type) ;
895 bstrncpy(lc->str, cf, sizeof(lc->str));
897 scan_err2(lc, _("Cannot open config file \"%s\": %s\n"),
898 lc->str, be.bstrerror());
902 lex_set_error_handler_error_type(lc, err_type) ;
903 while ((token=lex_get_token(lc, T_ALL)) != T_EOF) {
904 Dmsg3(900, "parse state=%d pass=%d got token=%s\n", state, pass,
905 lex_tok_to_str(token));
908 if (token == T_EOL) {
910 } else if (token == T_UTF8_BOM) {
911 /* We can assume the file is UTF-8 as we have seen a UTF-8 BOM */
913 } else if (token == T_UTF16_BOM) {
914 scan_err0(lc, _("Currently we cannot handle UTF-16 source files. "
915 "Please convert the conf file to UTF-8\n"));
917 } else if (token != T_IDENTIFIER) {
918 scan_err1(lc, _("Expected a Resource name identifier, got: %s"), lc->str);
921 for (i=0; resources[i].name; i++) {
922 if (strcasecmp(resources[i].name, lc->str) == 0) {
923 items = resources[i].items;
928 res_type = resources[i].rcode;
929 init_resource(this, res_type, items, pass);
933 if (state == p_none) {
934 scan_err1(lc, _("expected resource name, got: %s"), lc->str);
945 scan_err1(lc, _("not in resource definition: %s"), lc->str);
948 for (i=0; items[i].name; i++) {
949 if (strcasecmp(items[i].name, lc->str) == 0) {
950 /* If the ITEM_NO_EQUALS flag is set we do NOT
951 * scan for = after the keyword */
952 if (!(items[i].flags & ITEM_NO_EQUALS)) {
953 token = lex_get_token(lc, T_SKIP_EOL);
954 Dmsg1 (900, "in T_IDENT got token=%s\n", lex_tok_to_str(token));
955 if (token != T_EQUALS) {
956 scan_err1(lc, _("expected an equals, got: %s"), lc->str);
960 Dmsg1(800, "calling handler for %s\n", items[i].name);
961 /* Call item handler */
962 items[i].handler(lc, &items[i], i, pass);
968 Dmsg2(900, "level=%d id=%s\n", level, lc->str);
969 Dmsg1(900, "Keyword = %s\n", lc->str);
970 scan_err1(lc, _("Keyword \"%s\" not permitted in this resource.\n"
971 "Perhaps you left the trailing brace off of the previous resource."), lc->str);
979 Dmsg0(900, "T_EOB => define new resource\n");
980 if (res_all.hdr.name == NULL) {
981 scan_err0(lc, _("Name not specified for resource"));
984 save_resource(res_type, items, pass); /* save resource */
991 scan_err2(lc, _("unexpected token %d %s in resource definition"),
992 token, lex_tok_to_str(token));
997 scan_err1(lc, _("Unknown parser state %d\n"), state);
1001 if (state != p_none) {
1002 scan_err0(lc, _("End of conf file reached with unclosed resource."));
1005 if (debug_level >= 900 && pass == 2) {
1007 for (i=m_r_first; i<=m_r_last; i++) {
1008 dump_resource(i, m_res_head[i-m_r_first], prtmsg, NULL);
1011 lc = lex_close_file(lc);
1013 Dmsg0(900, "Leave parse_config()\n");
1017 const char *get_default_configdir()
1019 #if defined(HAVE_WIN32)
1021 static char szConfigDir[MAX_PATH + 1] = { 0 };
1023 if (!p_SHGetFolderPath) {
1024 bstrncpy(szConfigDir, DEFAULT_CONFIGDIR, sizeof(szConfigDir));
1028 if (szConfigDir[0] == '\0') {
1029 hr = p_SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL, 0, szConfigDir);
1031 if (SUCCEEDED(hr)) {
1032 bstrncat(szConfigDir, "\\Bacula", sizeof(szConfigDir));
1034 bstrncpy(szConfigDir, DEFAULT_CONFIGDIR, sizeof(szConfigDir));
1044 * Returns false on error
1045 * true on OK, with full_path set to where config file should be
1048 find_config_file(const char *config_file, char *full_path, int max_path)
1050 int file_length = strlen(config_file) + 1;
1052 /* If a full path specified, use it */
1053 if (first_path_separator(config_file) != NULL) {
1054 if (file_length > max_path) {
1057 bstrncpy(full_path, config_file, file_length);
1061 /* config_file is default file name, now find default dir */
1062 const char *config_dir = get_default_configdir();
1063 int dir_length = strlen(config_dir);
1065 if ((dir_length + 1 + file_length) > max_path) {
1069 memcpy(full_path, config_dir, dir_length + 1);
1071 if (!IsPathSeparator(full_path[dir_length - 1])) {
1072 full_path[dir_length++] = '/';
1075 memcpy(&full_path[dir_length], config_file, file_length);
1080 /*********************************************************************
1082 * Free configuration resources
1085 void CONFIG::free_resources()
1087 for (int i=m_r_first; i<=m_r_last; i++) {
1088 free_resource(m_res_head[i-m_r_first], i);
1089 m_res_head[i-m_r_first] = NULL;
1093 RES **CONFIG::save_resources()
1095 int num = m_r_last - m_r_first + 1;
1096 RES **res = (RES **)malloc(num*sizeof(RES *));
1097 for (int i=0; i<num; i++) {
1098 res[i] = m_res_head[i];
1099 m_res_head[i] = NULL;
1104 RES **CONFIG::new_res_head()
1106 int size = (m_r_last - m_r_first + 1) * sizeof(RES *);
1107 RES **res = (RES **)malloc(size);
1108 memset(res, 0, size);
1114 void free_config_resources()
1116 for (int i=r_first; i<=r_last; i++) {
1117 free_resource(res_head[i-r_first], i);
1118 res_head[i-r_first] = NULL;
1122 RES **save_config_resources()
1124 int num = r_last - r_first + 1;
1125 RES **res = (RES **)malloc(num*sizeof(RES *));
1126 for (int i=0; i<num; i++) {
1127 res[i] = res_head[i];
1133 RES **new_res_head()
1135 int size = (r_last - r_first + 1) * sizeof(RES *);
1136 RES **res = (RES **)malloc(size);
1137 memset(res, 0, size);