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 *(uint32_t *)(items[i].value) = items[i].default_value;
211 } else if (items[i].handler == store_int64) {
212 *(int64_t *)(items[i].value) = items[i].default_value;
213 } else if (items[i].handler == store_size) {
214 *(uint64_t *)(items[i].value) = (uint64_t)items[i].default_value;
215 } else if (items[i].handler == store_time) {
216 *(utime_t *)(items[i].value) = (utime_t)items[i].default_value;
217 } else if (pass == 1 && items[i].handler == store_addresses) {
218 init_default_addresses((dlist**)items[i].value, items[i].default_value);
221 /* If this triggers, take a look at lib/parse_conf.h */
222 if (i >= MAX_RES_ITEMS) {
223 Emsg1(M_ERROR_TERM, 0, _("Too many items in %s resource\n"), resources[rindex]);
229 /* Store Messages Destination information */
230 void store_msgs(LEX *lc, RES_ITEM *item, int index, int pass)
237 Dmsg2(900, "store_msgs pass=%d code=%d\n", pass, item->code);
239 switch (item->code) {
242 case MD_SYSLOG: /* syslog */
245 scan_types(lc, (MSGS *)(item->value), item->code, NULL, NULL);
247 case MD_OPERATOR: /* send to operator */
248 case MD_DIRECTOR: /* send to Director */
249 case MD_MAIL: /* mail */
250 case MD_MAIL_ON_ERROR: /* mail if Job errors */
251 case MD_MAIL_ON_SUCCESS: /* mail if Job succeeds */
252 if (item->code == MD_OPERATOR) {
253 cmd = res_all.res_msgs.operator_cmd;
255 cmd = res_all.res_msgs.mail_cmd;
257 dest = get_pool_memory(PM_MESSAGE);
260 /* Pick up comma separated list of destinations */
262 token = lex_get_token(lc, T_NAME); /* scan destination */
263 dest = check_pool_memory_size(dest, dest_len + lc->str_len + 2);
265 pm_strcat(dest, " "); /* separate multiple destinations with space */
268 pm_strcat(dest, lc->str);
269 dest_len += lc->str_len;
270 Dmsg2(900, "store_msgs newdest=%s: dest=%s:\n", lc->str, NPRT(dest));
271 token = lex_get_token(lc, T_SKIP_EOL);
272 if (token == T_COMMA) {
273 continue; /* get another destination */
275 if (token != T_EQUALS) {
276 scan_err1(lc, _("expected an =, got: %s"), lc->str);
281 Dmsg1(900, "mail_cmd=%s\n", NPRT(cmd));
282 scan_types(lc, (MSGS *)(item->value), item->code, dest, cmd);
283 free_pool_memory(dest);
284 Dmsg0(900, "done with dest codes\n");
287 case MD_FILE: /* file */
288 case MD_APPEND: /* append */
289 dest = get_pool_memory(PM_MESSAGE);
290 /* Pick up a single destination */
291 token = lex_get_token(lc, T_NAME); /* scan destination */
292 pm_strcpy(dest, lc->str);
293 dest_len = lc->str_len;
294 token = lex_get_token(lc, T_SKIP_EOL);
295 Dmsg1(900, "store_msgs dest=%s:\n", NPRT(dest));
296 if (token != T_EQUALS) {
297 scan_err1(lc, _("expected an =, got: %s"), lc->str);
300 scan_types(lc, (MSGS *)(item->value), item->code, dest, NULL);
301 free_pool_memory(dest);
302 Dmsg0(900, "done with dest codes\n");
306 scan_err1(lc, _("Unknown item code: %d\n"), item->code);
311 set_bit(index, res_all.hdr.item_present);
312 Dmsg0(900, "Done store_msgs\n");
316 * Scan for message types and add them to the message
317 * destination. The basic job here is to connect message types
318 * (WARNING, ERROR, FATAL, INFO, ...) with an appropriate
319 * destination (MAIL, FILE, OPERATOR, ...)
321 static void scan_types(LEX *lc, MSGS *msg, int dest_code, char *where, char *cmd)
329 lex_get_token(lc, T_NAME); /* expect at least one type */
331 if (lc->str[0] == '!') {
338 for (i=0; msg_types[i].name; i++) {
339 if (strcasecmp(str, msg_types[i].name) == 0) {
340 msg_type = msg_types[i].token;
346 scan_err1(lc, _("message type: %s not found"), str);
350 if (msg_type == M_MAX+1) { /* all? */
351 for (i=1; i<=M_MAX; i++) { /* yes set all types */
352 add_msg_dest(msg, dest_code, i, where, cmd);
355 rem_msg_dest(msg, dest_code, msg_type, where);
357 add_msg_dest(msg, dest_code, msg_type, where, cmd);
362 Dmsg0(900, "call lex_get_token() to eat comma\n");
363 lex_get_token(lc, T_ALL); /* eat comma */
365 Dmsg0(900, "Done scan_types()\n");
370 * This routine is ONLY for resource names
371 * Store a name at specified address.
373 void store_name(LEX *lc, RES_ITEM *item, int index, int pass)
375 POOLMEM *msg = get_pool_memory(PM_EMSG);
376 lex_get_token(lc, T_NAME);
377 if (!is_name_valid(lc->str, &msg)) {
378 scan_err1(lc, "%s\n", msg);
381 free_pool_memory(msg);
382 /* Store the name both pass 1 and pass 2 */
383 if (*(item->value)) {
384 scan_err2(lc, _("Attempt to redefine name \"%s\" to \"%s\"."),
385 *(item->value), lc->str);
388 *(item->value) = bstrdup(lc->str);
390 set_bit(index, res_all.hdr.item_present);
395 * Store a name string at specified address
396 * A name string is limited to MAX_RES_NAME_LENGTH
398 void store_strname(LEX *lc, RES_ITEM *item, int index, int pass)
400 lex_get_token(lc, T_NAME);
403 *(item->value) = bstrdup(lc->str);
406 set_bit(index, res_all.hdr.item_present);
409 /* Store a string at specified address */
410 void store_str(LEX *lc, RES_ITEM *item, int index, int pass)
412 lex_get_token(lc, T_STRING);
414 *(item->value) = bstrdup(lc->str);
417 set_bit(index, res_all.hdr.item_present);
421 * Store a directory name at specified address. Note, we do
422 * shell expansion except if the string begins with a vertical
423 * bar (i.e. it will likely be passed to the shell later).
425 void store_dir(LEX *lc, RES_ITEM *item, int index, int pass)
427 lex_get_token(lc, T_STRING);
429 if (lc->str[0] != '|') {
430 do_shell_expansion(lc->str, sizeof(lc->str));
432 *(item->value) = bstrdup(lc->str);
435 set_bit(index, res_all.hdr.item_present);
439 /* Store a password specified address in MD5 coding */
440 void store_password(LEX *lc, RES_ITEM *item, int index, int pass)
443 struct MD5Context md5c;
444 unsigned char digest[CRYPTO_DIGEST_MD5_SIZE];
448 lex_get_token(lc, T_STRING);
451 MD5Update(&md5c, (unsigned char *) (lc->str), lc->str_len);
452 MD5Final(digest, &md5c);
453 for (i = j = 0; i < sizeof(digest); i++) {
454 sprintf(&sig[j], "%02x", digest[i]);
457 *(item->value) = bstrdup(sig);
460 set_bit(index, res_all.hdr.item_present);
464 /* Store a resource at specified address.
465 * If we are in pass 2, do a lookup of the
468 void store_res(LEX *lc, RES_ITEM *item, int index, int pass)
472 lex_get_token(lc, T_NAME);
474 res = GetResWithName(item->code, lc->str);
476 scan_err3(lc, _("Could not find config Resource %s referenced on line %d : %s\n"),
477 lc->str, lc->line_no, lc->line);
480 if (*(item->value)) {
481 scan_err3(lc, _("Attempt to redefine resource \"%s\" referenced on line %d : %s\n"),
482 item->name, lc->line_no, lc->line);
485 *(item->value) = (char *)res;
488 set_bit(index, res_all.hdr.item_present);
492 * Store a resource pointer in an alist. default_value indicates how many
493 * times this routine can be called -- i.e. how many alists
495 * If we are in pass 2, do a lookup of the
498 void store_alist_res(LEX *lc, RES_ITEM *item, int index, int pass)
501 int count = item->default_value;
506 if (count == 0) { /* always store in item->value */
508 if ((item->value)[i] == NULL) {
509 list = New(alist(10, not_owned_by_alist));
511 list = (alist *)(item->value)[i];
514 /* Find empty place to store this directive */
515 while ((item->value)[i] != NULL && i++ < count) { }
517 scan_err4(lc, _("Too many %s directives. Max. is %d. line %d: %s\n"),
518 lc->str, count, lc->line_no, lc->line);
521 list = New(alist(10, not_owned_by_alist));
525 lex_get_token(lc, T_NAME); /* scan next item */
526 res = GetResWithName(item->code, lc->str);
528 scan_err3(lc, _("Could not find config Resource \"%s\" referenced on line %d : %s\n"),
529 item->name, lc->line_no, lc->line);
532 Dmsg5(900, "Append %p to alist %p size=%d i=%d %s\n",
533 res, list, list->size(), i, item->name);
535 (item->value)[i] = (char *)list;
536 if (lc->ch != ',') { /* if no other item follows */
539 lex_get_token(lc, T_ALL); /* eat comma */
543 set_bit(index, res_all.hdr.item_present);
548 * Store a string in an alist.
550 void store_alist_str(LEX *lc, RES_ITEM *item, int index, int pass)
555 if (*(item->value) == NULL) {
556 list = New(alist(10, owned_by_alist));
558 list = (alist *)(*(item->value));
561 lex_get_token(lc, T_STRING); /* scan next item */
562 Dmsg4(900, "Append %s to alist %p size=%d %s\n",
563 lc->str, list, list->size(), item->name);
564 list->append(bstrdup(lc->str));
565 *(item->value) = (char *)list;
568 set_bit(index, res_all.hdr.item_present);
574 * Store default values for Resource from xxxDefs
575 * If we are in pass 2, do a lookup of the
576 * resource and store everything not explicitly set
579 * Note, here item points to the main resource (e.g. Job, not
580 * the jobdefs, which we look up).
582 void store_defs(LEX *lc, RES_ITEM *item, int index, int pass)
586 lex_get_token(lc, T_NAME);
588 Dmsg2(900, "Code=%d name=%s\n", item->code, lc->str);
589 res = GetResWithName(item->code, lc->str);
591 scan_err3(lc, _("Missing config Resource \"%s\" referenced on line %d : %s\n"),
592 lc->str, lc->line_no, lc->line);
601 /* Store an integer at specified address */
602 void store_int32(LEX *lc, RES_ITEM *item, int index, int pass)
604 lex_get_token(lc, T_INT32);
605 *(uint32_t *)(item->value) = lc->int32_val;
607 set_bit(index, res_all.hdr.item_present);
610 /* Store a positive integer at specified address */
611 void store_pint32(LEX *lc, RES_ITEM *item, int index, int pass)
613 lex_get_token(lc, T_PINT32);
614 *(uint32_t *)(item->value) = lc->pint32_val;
616 set_bit(index, res_all.hdr.item_present);
620 /* Store an 64 bit integer at specified address */
621 void store_int64(LEX *lc, RES_ITEM *item, int index, int pass)
623 lex_get_token(lc, T_INT64);
624 *(int64_t *)(item->value) = lc->int64_val;
626 set_bit(index, res_all.hdr.item_present);
629 /* Store a size in bytes */
630 void store_size(LEX *lc, RES_ITEM *item, int index, int pass)
636 Dmsg0(900, "Enter store_size\n");
637 token = lex_get_token(lc, T_SKIP_EOL);
642 case T_UNQUOTED_STRING:
643 bstrncpy(bsize, lc->str, sizeof(bsize)); /* save first part */
644 /* if terminated by space, scan and get modifier */
645 while (lc->ch == ' ') {
646 token = lex_get_token(lc, T_ALL);
650 case T_UNQUOTED_STRING:
651 bstrncat(bsize, lc->str, sizeof(bsize));
655 if (!size_to_uint64(bsize, strlen(bsize), &uvalue)) {
656 scan_err1(lc, _("expected a size number, got: %s"), lc->str);
659 *(uint64_t *)(item->value) = uvalue;
662 scan_err1(lc, _("expected a size, got: %s"), lc->str);
665 if (token != T_EOL) {
668 set_bit(index, res_all.hdr.item_present);
669 Dmsg0(900, "Leave store_size\n");
673 /* Store a time period in seconds */
674 void store_time(LEX *lc, RES_ITEM *item, int index, int pass)
680 token = lex_get_token(lc, T_SKIP_EOL);
685 case T_UNQUOTED_STRING:
686 bstrncpy(period, lc->str, sizeof(period)); /* get first part */
687 /* if terminated by space, scan and get modifier */
688 while (lc->ch == ' ') {
689 token = lex_get_token(lc, T_ALL);
693 case T_UNQUOTED_STRING:
694 bstrncat(period, lc->str, sizeof(period));
698 if (!duration_to_utime(period, &utime)) {
699 scan_err1(lc, _("expected a time period, got: %s"), period);
702 *(utime_t *)(item->value) = utime;
705 scan_err1(lc, _("expected a time period, got: %s"), lc->str);
708 if (token != T_EOL) {
711 set_bit(index, res_all.hdr.item_present);
715 /* Store a yes/no in a bit field */
716 void store_bit(LEX *lc, RES_ITEM *item, int index, int pass)
718 lex_get_token(lc, T_NAME);
719 if (strcasecmp(lc->str, "yes") == 0 || strcasecmp(lc->str, "true") == 0) {
720 *(uint32_t *)(item->value) |= item->code;
721 } else if (strcasecmp(lc->str, "no") == 0 || strcasecmp(lc->str, "false") == 0) {
722 *(uint32_t *)(item->value) &= ~(item->code);
724 scan_err2(lc, _("Expect %s, got: %s"), "YES, NO, TRUE, or FALSE", lc->str); /* YES and NO must not be translated */
728 set_bit(index, res_all.hdr.item_present);
731 /* Store a bool in a bit field */
732 void store_bool(LEX *lc, RES_ITEM *item, int index, int pass)
734 lex_get_token(lc, T_NAME);
735 if (strcasecmp(lc->str, "yes") == 0 || strcasecmp(lc->str, "true") == 0) {
736 *(bool *)(item->value) = true;
737 } else if (strcasecmp(lc->str, "no") == 0 || strcasecmp(lc->str, "false") == 0) {
738 *(bool *)(item->value) = false;
740 scan_err2(lc, _("Expect %s, got: %s"), "YES, NO, TRUE, or FALSE", lc->str); /* YES and NO must not be translated */
744 set_bit(index, res_all.hdr.item_present);
749 * Store Tape Label Type (Bacula, ANSI, IBM)
752 void store_label(LEX *lc, RES_ITEM *item, int index, int pass)
756 token = lex_get_token(lc, T_NAME);
757 /* Store the label pass 2 so that type is defined */
758 for (i=0; tapelabels[i].name; i++) {
759 if (strcasecmp(lc->str, tapelabels[i].name) == 0) {
760 *(uint32_t *)(item->value) = tapelabels[i].token;
766 scan_err1(lc, _("Expected a Tape Label keyword, got: %s"), lc->str);
770 set_bit(index, res_all.hdr.item_present);
780 CONFIG *new_config_parser()
783 config = (CONFIG *)malloc(sizeof(CONFIG));
784 memset(config, 0, sizeof(CONFIG));
790 LEX_ERROR_HANDLER *scan_error,
793 int32_t res_all_size,
796 RES_TABLE *resources,
800 m_scan_error = scan_error;
801 m_err_type = err_type;
802 m_res_all = vres_all;
803 m_res_all_size = res_all_size;
806 m_resources = resources;
807 m_res_head = res_head;
810 /*********************************************************************
812 * Parse configuration file
814 * Return 0 if reading failed, 1 otherwise
815 * Note, the default behavior unless you have set an alternate
816 * scan_error handler is to die on an error.
820 parse_config(const char *cf, LEX_ERROR_HANDLER *scan_error, int err_type)
823 CONFIG *config = new_config_parser();
824 config->init(cf, scan_error, err_type, (void *)&res_all, res_all_size,
825 r_first, r_last, resources, res_head);
826 ok = config->parse_config();
833 bool CONFIG::parse_config()
838 enum parse_state state = p_none;
839 RES_ITEM *items = NULL;
841 static bool first = true;
843 const char *cf = m_cf;
844 LEX_ERROR_HANDLER *scan_error = m_scan_error;
845 int err_type = m_err_type;
847 if (first && (errstat=rwl_init(&res_lock)) != 0) {
849 Jmsg1(NULL, M_ABORT, 0, _("Unable to initialize resource lock. ERR=%s\n"),
850 be.bstrerror(errstat));
854 char *full_path = (char *)alloca(MAX_PATH + 1);
856 if (!find_config_file(cf, full_path, MAX_PATH +1)) {
857 Jmsg0(NULL, M_ABORT, 0, _("Config filename too long.\n"));
861 /* Make two passes. The first builds the name symbol table,
862 * and the second picks up the items.
864 Dmsg0(900, "Enter parse_config()\n");
865 for (pass=1; pass <= 2; pass++) {
866 Dmsg1(900, "parse_config pass %d\n", pass);
867 if ((lc = lex_open_file(lc, cf, scan_error)) == NULL) {
869 /* We must create a lex packet to print the error */
870 lc = (LEX *)malloc(sizeof(LEX));
871 memset(lc, 0, sizeof(LEX));
873 lc->scan_error = scan_error;
875 lex_set_default_error_handler(lc);
877 lex_set_error_handler_error_type(lc, err_type) ;
878 bstrncpy(lc->str, cf, sizeof(lc->str));
880 scan_err2(lc, _("Cannot open config file \"%s\": %s\n"),
881 lc->str, be.bstrerror());
885 lex_set_error_handler_error_type(lc, err_type) ;
886 while ((token=lex_get_token(lc, T_ALL)) != T_EOF) {
887 Dmsg3(900, "parse state=%d pass=%d got token=%s\n", state, pass,
888 lex_tok_to_str(token));
891 if (token == T_EOL) {
893 } else if (token == T_UTF8_BOM) {
894 /* We can assume the file is UTF-8 as we have seen a UTF-8 BOM */
896 } else if (token == T_UTF16_BOM) {
897 scan_err0(lc, _("Currently we cannot handle UTF-16 source files. "
898 "Please convert the conf file to UTF-8\n"));
900 } else if (token != T_IDENTIFIER) {
901 scan_err1(lc, _("Expected a Resource name identifier, got: %s"), lc->str);
904 for (i=0; resources[i].name; i++) {
905 if (strcasecmp(resources[i].name, lc->str) == 0) {
906 items = resources[i].items;
911 res_type = resources[i].rcode;
912 init_resource(this, res_type, items, pass);
916 if (state == p_none) {
917 scan_err1(lc, _("expected resource name, got: %s"), lc->str);
928 scan_err1(lc, _("not in resource definition: %s"), lc->str);
931 for (i=0; items[i].name; i++) {
932 if (strcasecmp(items[i].name, lc->str) == 0) {
933 /* If the ITEM_NO_EQUALS flag is set we do NOT
934 * scan for = after the keyword */
935 if (!(items[i].flags & ITEM_NO_EQUALS)) {
936 token = lex_get_token(lc, T_SKIP_EOL);
937 Dmsg1 (900, "in T_IDENT got token=%s\n", lex_tok_to_str(token));
938 if (token != T_EQUALS) {
939 scan_err1(lc, _("expected an equals, got: %s"), lc->str);
943 Dmsg1(800, "calling handler for %s\n", items[i].name);
944 /* Call item handler */
945 items[i].handler(lc, &items[i], i, pass);
951 Dmsg2(900, "level=%d id=%s\n", level, lc->str);
952 Dmsg1(900, "Keyword = %s\n", lc->str);
953 scan_err1(lc, _("Keyword \"%s\" not permitted in this resource.\n"
954 "Perhaps you left the trailing brace off of the previous resource."), lc->str);
962 Dmsg0(900, "T_EOB => define new resource\n");
963 if (res_all.hdr.name == NULL) {
964 scan_err0(lc, _("Name not specified for resource"));
967 save_resource(res_type, items, pass); /* save resource */
974 scan_err2(lc, _("unexpected token %d %s in resource definition"),
975 token, lex_tok_to_str(token));
980 scan_err1(lc, _("Unknown parser state %d\n"), state);
984 if (state != p_none) {
985 scan_err0(lc, _("End of conf file reached with unclosed resource."));
988 if (debug_level >= 900 && pass == 2) {
990 for (i=m_r_first; i<=m_r_last; i++) {
991 dump_resource(i, m_res_head[i-m_r_first], prtmsg, NULL);
994 lc = lex_close_file(lc);
996 Dmsg0(900, "Leave parse_config()\n");
1000 const char *get_default_configdir()
1002 #if defined(HAVE_WIN32)
1004 static char szConfigDir[MAX_PATH + 1] = { 0 };
1006 if (!p_SHGetFolderPath) {
1007 bstrncpy(szConfigDir, DEFAULT_CONFIGDIR, sizeof(szConfigDir));
1011 if (szConfigDir[0] == '\0') {
1012 hr = p_SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL, 0, szConfigDir);
1014 if (SUCCEEDED(hr)) {
1015 bstrncat(szConfigDir, "\\Bacula", sizeof(szConfigDir));
1017 bstrncpy(szConfigDir, DEFAULT_CONFIGDIR, sizeof(szConfigDir));
1027 * Returns false on error
1028 * true on OK, with full_path set to where config file should be
1031 find_config_file(const char *config_file, char *full_path, int max_path)
1033 int file_length = strlen(config_file) + 1;
1035 /* If a full path specified, use it */
1036 if (first_path_separator(config_file) != NULL) {
1037 if (file_length > max_path) {
1040 bstrncpy(full_path, config_file, file_length);
1044 /* config_file is default file name, now find default dir */
1045 const char *config_dir = get_default_configdir();
1046 int dir_length = strlen(config_dir);
1048 if ((dir_length + 1 + file_length) > max_path) {
1052 memcpy(full_path, config_dir, dir_length + 1);
1054 if (!IsPathSeparator(full_path[dir_length - 1])) {
1055 full_path[dir_length++] = '/';
1058 memcpy(&full_path[dir_length], config_file, file_length);
1063 /*********************************************************************
1065 * Free configuration resources
1068 void CONFIG::free_resources()
1070 for (int i=m_r_first; i<=m_r_last; i++) {
1071 free_resource(m_res_head[i-m_r_first], i);
1072 m_res_head[i-m_r_first] = NULL;
1076 RES **CONFIG::save_resources()
1078 int num = m_r_last - m_r_first + 1;
1079 RES **res = (RES **)malloc(num*sizeof(RES *));
1080 for (int i=0; i<num; i++) {
1081 res[i] = m_res_head[i];
1082 m_res_head[i] = NULL;
1087 RES **CONFIG::new_res_head()
1089 int size = (m_r_last - m_r_first + 1) * sizeof(RES *);
1090 RES **res = (RES **)malloc(size);
1091 memset(res, 0, size);
1097 void free_config_resources()
1099 for (int i=r_first; i<=r_last; i++) {
1100 free_resource(res_head[i-r_first], i);
1101 res_head[i-r_first] = NULL;
1105 RES **save_config_resources()
1107 int num = r_last - r_first + 1;
1108 RES **res = (RES **)malloc(num*sizeof(RES *));
1109 for (int i=0; i<num; i++) {
1110 res[i] = res_head[i];
1116 RES **new_res_head()
1118 int size = (r_last - r_first + 1) * sizeof(RES *);
1119 RES **res = (RES **)malloc(size);
1120 memset(res, 0, size);