]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/parse_conf.c
Ignore UTF-8 marker at the start of .conf files.
[bacula/bacula] / bacula / src / lib / parse_conf.c
1 /*
2  *   Master Configuration routines.
3  *
4  *   This file contains the common parts of the Bacula
5  *   configuration routines.
6  *
7  *   Note, the configuration file parser consists of three parts
8  *
9  *   1. The generic lexical scanner in lib/lex.c and lib/lex.h
10  *
11  *   2. The generic config  scanner in lib/parse_conf.c and
12  *      lib/parse_conf.h.
13  *      These files contain the parser code, some utility
14  *      routines, and the common store routines (name, int,
15  *      string, time, int64, size, ...).
16  *
17  *   3. The daemon specific file, which contains the Resource
18  *      definitions as well as any specific store routines
19  *      for the resource records.
20  *
21  *    N.B. This is a two pass parser, so if you malloc() a string
22  *         in a "store" routine, you must ensure to do it during
23  *         only one of the two passes, or to free it between.
24  *         Also, note that the resource record is malloced and
25  *         saved in save_resource() during pass 1.  Anything that
26  *         you want saved after pass two (e.g. resource pointers)
27  *         must explicitly be done in save_resource. Take a look
28  *         at the Job resource in src/dird/dird_conf.c to see how
29  *         it is done.
30  *
31  *     Kern Sibbald, January MM
32  *
33  *   Version $Id$
34  */
35 /*
36    Copyright (C) 2000-2006 Kern Sibbald
37
38    This program is free software; you can redistribute it and/or
39    modify it under the terms of the GNU General Public License
40    version 2 as amended with additional clauses defined in the
41    file LICENSE in the main source directory.
42
43    This program is distributed in the hope that it will be useful,
44    but WITHOUT ANY WARRANTY; without even the implied warranty of
45    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
46    the file LICENSE for additional details.
47
48  */
49
50
51 #include "bacula.h"
52
53 #if defined(HAVE_WIN32)
54 #include "shlobj.h"
55 #else
56 #define MAX_PATH  1024
57 #endif
58
59 /* Each daemon has a slightly different set of
60  * resources, so it will define the following
61  * global values.
62  */
63 extern int r_first;
64 extern int r_last;
65 extern RES_TABLE resources[];
66 extern RES **res_head;
67
68 #if defined(_MSC_VER)
69 // work around visual studio name mangling preventing external linkage since res_all
70 // is declared as a different type when instantiated.
71 extern "C" CURES res_all;
72 #else
73 extern  CURES res_all;
74 #endif
75 extern int res_all_size;
76
77 extern brwlock_t res_lock;            /* resource lock */
78
79
80 /* Forward referenced subroutines */
81 static void scan_types(LEX *lc, MSGS *msg, int dest, char *where, char *cmd);
82 static const char *get_default_configdir();
83 static bool find_config_file(const char *config_file, char *full_path);
84
85 /* Common Resource definitions */
86
87 /* Message resource directives
88  *  name         handler      value       code   flags  default_value
89  */
90 RES_ITEM msgs_items[] = {
91    {"name",        store_name,    ITEM(res_msgs.hdr.name),  0, 0, 0},
92    {"description", store_str,     ITEM(res_msgs.hdr.desc),  0, 0, 0},
93    {"mailcommand", store_str,     ITEM(res_msgs.mail_cmd),  0, 0, 0},
94    {"operatorcommand", store_str, ITEM(res_msgs.operator_cmd), 0, 0, 0},
95    {"syslog",      store_msgs, ITEM(res_msgs), MD_SYSLOG,   0, 0},
96    {"mail",        store_msgs, ITEM(res_msgs), MD_MAIL,     0, 0},
97    {"mailonerror", store_msgs, ITEM(res_msgs), MD_MAIL_ON_ERROR, 0, 0},
98    {"file",        store_msgs, ITEM(res_msgs), MD_FILE,     0, 0},
99    {"append",      store_msgs, ITEM(res_msgs), MD_APPEND,   0, 0},
100    {"stdout",      store_msgs, ITEM(res_msgs), MD_STDOUT,   0, 0},
101    {"stderr",      store_msgs, ITEM(res_msgs), MD_STDERR,   0, 0},
102    {"director",    store_msgs, ITEM(res_msgs), MD_DIRECTOR, 0, 0},
103    {"console",     store_msgs, ITEM(res_msgs), MD_CONSOLE,  0, 0},
104    {"operator",    store_msgs, ITEM(res_msgs), MD_OPERATOR, 0, 0},
105    {"catalog",     store_msgs, ITEM(res_msgs), MD_CATALOG,  0, 0},
106    {NULL,          NULL,       {0},       0, 0, 0}
107 };
108
109 struct s_mtypes {
110    const char *name;
111    int token;
112 };
113 /* Various message types */
114 static struct s_mtypes msg_types[] = {
115    {"debug",         M_DEBUG},
116    {"abort",         M_ABORT},
117    {"fatal",         M_FATAL},
118    {"error",         M_ERROR},
119    {"warning",       M_WARNING},
120    {"info",          M_INFO},
121    {"saved",         M_SAVED},
122    {"notsaved",      M_NOTSAVED},
123    {"skipped",       M_SKIPPED},
124    {"mount",         M_MOUNT},
125    {"terminate",     M_TERM},
126    {"restored",      M_RESTORED},
127    {"security",      M_SECURITY},
128    {"alert",         M_ALERT},
129    {"volmgmt",       M_VOLMGMT},
130    {"all",           M_MAX+1},
131    {NULL,            0}
132 };
133
134 /* Used for certain KeyWord tables */
135 struct s_kw {
136    const char *name;
137    int token;
138 };
139
140 /*
141  * Tape Label types permitted in Pool records 
142  *
143  *   tape label      label code = token
144  */
145 static s_kw tapelabels[] = {
146    {"bacula",        B_BACULA_LABEL},
147    {"ansi",          B_ANSI_LABEL},
148    {"ibm",           B_IBM_LABEL},
149    {NULL,            0}
150 };
151
152
153 /* Simply print a message */
154 static void prtmsg(void *sock, const char *fmt, ...)
155 {
156    va_list arg_ptr;
157
158    va_start(arg_ptr, fmt);
159    vfprintf(stdout, fmt, arg_ptr);
160    va_end(arg_ptr);
161 }
162
163 const char *res_to_str(int rcode)
164 {
165    if (rcode < r_first || rcode > r_last) {
166       return _("***UNKNOWN***");
167    } else {
168       return resources[rcode-r_first].name;
169    }
170 }
171
172
173 /*
174  * Initialize the static structure to zeros, then
175  *  apply all the default values.
176  */
177 void init_resource(int type, RES_ITEM *items, int pass)
178 {
179    int i;
180    int rindex = type - r_first;
181    static bool first = true;
182    int errstat;
183
184    if (first && (errstat=rwl_init(&res_lock)) != 0) {
185       Emsg1(M_ABORT, 0, _("Unable to initialize resource lock. ERR=%s\n"),
186             strerror(errstat));
187    }
188    first = false;
189
190    memset(&res_all, 0, res_all_size);
191    res_all.hdr.rcode = type;
192    res_all.hdr.refcnt = 1;
193
194    /* Set defaults in each item */
195    for (i=0; items[i].name; i++) {
196       Dmsg3(900, "Item=%s def=%s defval=%d\n", items[i].name,
197             (items[i].flags & ITEM_DEFAULT) ? "yes" : "no",
198             items[i].default_value);
199       if (items[i].flags & ITEM_DEFAULT && items[i].default_value != 0) {
200          if (items[i].handler == store_bit) {
201             *(int *)(items[i].value) |= items[i].code;
202          } else if (items[i].handler == store_bool) {
203             *(bool *)(items[i].value) = items[i].default_value != 0;
204          } else if (items[i].handler == store_pint ||
205                     items[i].handler == store_int) {
206             *(int *)(items[i].value) = items[i].default_value;
207          } else if (items[i].handler == store_int64) {
208             *(int64_t *)(items[i].value) = items[i].default_value;
209          } else if (items[i].handler == store_size) {
210             *(uint64_t *)(items[i].value) = (uint64_t)items[i].default_value;
211          } else if (items[i].handler == store_time) {
212             *(utime_t *)(items[i].value) = (utime_t)items[i].default_value;
213          } else if (pass == 1 && items[i].handler == store_addresses) {
214             init_default_addresses((dlist**)items[i].value, items[i].default_value);
215          }
216       }
217       /* If this triggers, take a look at lib/parse_conf.h */
218       if (i >= MAX_RES_ITEMS) {
219          Emsg1(M_ERROR_TERM, 0, _("Too many items in %s resource\n"), resources[rindex]);
220       }
221    }
222 }
223
224
225 /* Store Messages Destination information */
226 void store_msgs(LEX *lc, RES_ITEM *item, int index, int pass)
227 {
228    int token;
229    char *cmd;
230    POOLMEM *dest;
231    int dest_len;
232
233    Dmsg2(900, "store_msgs pass=%d code=%d\n", pass, item->code);
234    if (pass == 1) {
235       switch (item->code) {
236       case MD_STDOUT:
237       case MD_STDERR:
238       case MD_SYSLOG:              /* syslog */
239       case MD_CONSOLE:
240       case MD_CATALOG:
241          scan_types(lc, (MSGS *)(item->value), item->code, NULL, NULL);
242          break;
243       case MD_OPERATOR:            /* send to operator */
244       case MD_DIRECTOR:            /* send to Director */
245       case MD_MAIL:                /* mail */
246       case MD_MAIL_ON_ERROR:       /* mail if Job errors */
247          if (item->code == MD_OPERATOR) {
248             cmd = res_all.res_msgs.operator_cmd;
249          } else {
250             cmd = res_all.res_msgs.mail_cmd;
251          }
252          dest = get_pool_memory(PM_MESSAGE);
253          dest[0] = 0;
254          dest_len = 0;
255          /* Pick up comma separated list of destinations */
256          for ( ;; ) {
257             token = lex_get_token(lc, T_NAME);   /* scan destination */
258             dest = check_pool_memory_size(dest, dest_len + lc->str_len + 2);
259             if (dest[0] != 0) {
260                pm_strcat(dest, " ");  /* separate multiple destinations with space */
261                dest_len++;
262             }
263             pm_strcat(dest, lc->str);
264             dest_len += lc->str_len;
265             Dmsg2(900, "store_msgs newdest=%s: dest=%s:\n", lc->str, NPRT(dest));
266             token = lex_get_token(lc, T_SKIP_EOL);
267             if (token == T_COMMA) {
268                continue;           /* get another destination */
269             }
270             if (token != T_EQUALS) {
271                scan_err1(lc, _("expected an =, got: %s"), lc->str);
272             }
273             break;
274          }
275          Dmsg1(900, "mail_cmd=%s\n", NPRT(cmd));
276          scan_types(lc, (MSGS *)(item->value), item->code, dest, cmd);
277          free_pool_memory(dest);
278          Dmsg0(900, "done with dest codes\n");
279          break;
280       case MD_FILE:                /* file */
281       case MD_APPEND:              /* append */
282          dest = get_pool_memory(PM_MESSAGE);
283          /* Pick up a single destination */
284          token = lex_get_token(lc, T_NAME);   /* scan destination */
285          pm_strcpy(dest, lc->str);
286          dest_len = lc->str_len;
287          token = lex_get_token(lc, T_SKIP_EOL);
288          Dmsg1(900, "store_msgs dest=%s:\n", NPRT(dest));
289          if (token != T_EQUALS) {
290             scan_err1(lc, _("expected an =, got: %s"), lc->str);
291          }
292          scan_types(lc, (MSGS *)(item->value), item->code, dest, NULL);
293          free_pool_memory(dest);
294          Dmsg0(900, "done with dest codes\n");
295          break;
296
297       default:
298          scan_err1(lc, _("Unknown item code: %d\n"), item->code);
299          break;
300       }
301    }
302    scan_to_eol(lc);
303    set_bit(index, res_all.hdr.item_present);
304    Dmsg0(900, "Done store_msgs\n");
305 }
306
307 /*
308  * Scan for message types and add them to the message
309  * destination. The basic job here is to connect message types
310  *  (WARNING, ERROR, FATAL, INFO, ...) with an appropriate
311  *  destination (MAIL, FILE, OPERATOR, ...)
312  */
313 static void scan_types(LEX *lc, MSGS *msg, int dest_code, char *where, char *cmd)
314 {
315    int i; 
316    bool found, is_not;
317    int msg_type = 0;
318    char *str;
319
320    for ( ;; ) {
321       lex_get_token(lc, T_NAME);            /* expect at least one type */
322       found = false;
323       if (lc->str[0] == '!') {
324          is_not = true;
325          str = &lc->str[1];
326       } else {
327          is_not = false;
328          str = &lc->str[0];
329       }
330       for (i=0; msg_types[i].name; i++) {
331          if (strcasecmp(str, msg_types[i].name) == 0) {
332             msg_type = msg_types[i].token;
333             found = true;
334             break;
335          }
336       }
337       if (!found) {
338          scan_err1(lc, _("message type: %s not found"), str);
339          /* NOT REACHED */
340       }
341
342       if (msg_type == M_MAX+1) {         /* all? */
343          for (i=1; i<=M_MAX; i++) {      /* yes set all types */
344             add_msg_dest(msg, dest_code, i, where, cmd);
345          }
346       } else if (is_not) {
347          rem_msg_dest(msg, dest_code, msg_type, where);
348       } else {
349          add_msg_dest(msg, dest_code, msg_type, where, cmd);
350       }
351       if (lc->ch != ',') {
352          break;
353       }
354       Dmsg0(900, "call lex_get_token() to eat comma\n");
355       lex_get_token(lc, T_ALL);          /* eat comma */
356    }
357    Dmsg0(900, "Done scan_types()\n");
358 }
359
360
361 /*
362  * This routine is ONLY for resource names
363  *  Store a name at specified address.
364  */
365 void store_name(LEX *lc, RES_ITEM *item, int index, int pass)
366 {
367    POOLMEM *msg = get_pool_memory(PM_EMSG);
368    lex_get_token(lc, T_NAME);
369    if (!is_name_valid(lc->str, &msg)) {
370       scan_err1(lc, "%s\n", msg);
371    }
372    free_pool_memory(msg);
373    /* Store the name both pass 1 and pass 2 */
374    if (*(item->value)) {
375       scan_err2(lc, _("Attempt to redefine name \"%s\" to \"%s\"."),
376          *(item->value), lc->str);
377    }
378    *(item->value) = bstrdup(lc->str);
379    scan_to_eol(lc);
380    set_bit(index, res_all.hdr.item_present);
381 }
382
383
384 /*
385  * Store a name string at specified address
386  * A name string is limited to MAX_RES_NAME_LENGTH
387  */
388 void store_strname(LEX *lc, RES_ITEM *item, int index, int pass)
389 {
390    lex_get_token(lc, T_NAME);
391    /* Store the name */
392    if (pass == 1) {
393       *(item->value) = bstrdup(lc->str);
394    }
395    scan_to_eol(lc);
396    set_bit(index, res_all.hdr.item_present);
397 }
398
399 /* Store a string at specified address */
400 void store_str(LEX *lc, RES_ITEM *item, int index, int pass)
401 {
402    lex_get_token(lc, T_STRING);
403    if (pass == 1) {
404       *(item->value) = bstrdup(lc->str);
405    }
406    scan_to_eol(lc);
407    set_bit(index, res_all.hdr.item_present);
408 }
409
410 /*
411  * Store a directory name at specified address. Note, we do
412  *   shell expansion except if the string begins with a vertical
413  *   bar (i.e. it will likely be passed to the shell later).
414  */
415 void store_dir(LEX *lc, RES_ITEM *item, int index, int pass)
416 {
417    lex_get_token(lc, T_STRING);
418    if (pass == 1) {
419       if (lc->str[0] != '|') {
420          do_shell_expansion(lc->str, sizeof(lc->str));
421       }
422       *(item->value) = bstrdup(lc->str);
423    }
424    scan_to_eol(lc);
425    set_bit(index, res_all.hdr.item_present);
426 }
427
428
429 /* Store a password specified address in MD5 coding */
430 void store_password(LEX *lc, RES_ITEM *item, int index, int pass)
431 {
432    unsigned int i, j;
433    struct MD5Context md5c;
434    unsigned char digest[CRYPTO_DIGEST_MD5_SIZE];
435    char sig[100];
436
437
438    lex_get_token(lc, T_STRING);
439    if (pass == 1) {
440       MD5Init(&md5c);
441       MD5Update(&md5c, (unsigned char *) (lc->str), lc->str_len);
442       MD5Final(digest, &md5c);
443       for (i = j = 0; i < sizeof(digest); i++) {
444          sprintf(&sig[j], "%02x", digest[i]);
445          j += 2;
446       }
447       *(item->value) = bstrdup(sig);
448    }
449    scan_to_eol(lc);
450    set_bit(index, res_all.hdr.item_present);
451 }
452
453
454 /* Store a resource at specified address.
455  * If we are in pass 2, do a lookup of the
456  * resource.
457  */
458 void store_res(LEX *lc, RES_ITEM *item, int index, int pass)
459 {
460    RES *res;
461
462    lex_get_token(lc, T_NAME);
463    if (pass == 2) {
464       res = GetResWithName(item->code, lc->str);
465       if (res == NULL) {
466          scan_err3(lc, _("Could not find config Resource %s referenced on line %d : %s\n"),
467             lc->str, lc->line_no, lc->line);
468       }
469       if (*(item->value)) {
470          scan_err3(lc, _("Attempt to redefine resource \"%s\" referenced on line %d : %s\n"),
471             item->name, lc->line_no, lc->line);
472       }
473       *(item->value) = (char *)res;
474    }
475    scan_to_eol(lc);
476    set_bit(index, res_all.hdr.item_present);
477 }
478
479 /*
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
482  *   there are.
483  * If we are in pass 2, do a lookup of the
484  *   resource.
485  */
486 void store_alist_res(LEX *lc, RES_ITEM *item, int index, int pass)
487 {
488    RES *res;
489    int count = item->default_value;
490    int i = 0;
491    alist *list;
492
493    if (pass == 2) {
494       if (count == 0) {               /* always store in item->value */
495          i = 0;
496          if ((item->value)[i] == NULL) {
497             list = New(alist(10, not_owned_by_alist));
498          } else {
499             list = (alist *)(item->value)[i];
500          }
501       } else {
502          /* Find empty place to store this directive */
503          while ((item->value)[i] != NULL && i++ < count) { }
504          if (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);
507          }
508          list = New(alist(10, not_owned_by_alist));
509       }
510
511       for (;;) {
512          lex_get_token(lc, T_NAME);   /* scan next item */
513          res = GetResWithName(item->code, lc->str);
514          if (res == NULL) {
515             scan_err3(lc, _("Could not find config Resource \"%s\" referenced on line %d : %s\n"),
516                item->name, lc->line_no, lc->line);
517          }
518          Dmsg5(900, "Append %p to alist %p size=%d i=%d %s\n", 
519                res, list, list->size(), i, item->name);
520          list->append(res);
521          (item->value)[i] = (char *)list;
522          if (lc->ch != ',') {         /* if no other item follows */
523             break;                    /* get out */
524          }
525          lex_get_token(lc, T_ALL);    /* eat comma */
526       }
527    }
528    scan_to_eol(lc);
529    set_bit(index, res_all.hdr.item_present);
530 }
531
532
533 /*
534  * Store a string in an alist.
535  */
536 void store_alist_str(LEX *lc, RES_ITEM *item, int index, int pass)
537 {
538    alist *list;
539
540    if (pass == 2) {
541       if (*(item->value) == NULL) {
542          list = New(alist(10, owned_by_alist));
543       } else {
544          list = (alist *)(*(item->value));    
545       }
546
547       lex_get_token(lc, T_STRING);   /* scan next item */
548       Dmsg4(900, "Append %s to alist %p size=%d %s\n", 
549          lc->str, list, list->size(), item->name);
550       list->append(bstrdup(lc->str));
551       *(item->value) = (char *)list;
552    }
553    scan_to_eol(lc);
554    set_bit(index, res_all.hdr.item_present);
555 }
556
557
558
559 /*
560  * Store default values for Resource from xxxDefs
561  * If we are in pass 2, do a lookup of the
562  * resource and store everything not explicitly set
563  * in main resource.
564  *
565  * Note, here item points to the main resource (e.g. Job, not
566  *  the jobdefs, which we look up).
567  */
568 void store_defs(LEX *lc, RES_ITEM *item, int index, int pass)
569 {
570    RES *res;
571
572    lex_get_token(lc, T_NAME);
573    if (pass == 2) {
574      Dmsg2(900, "Code=%d name=%s\n", item->code, lc->str);
575      res = GetResWithName(item->code, lc->str);
576      if (res == NULL) {
577         scan_err3(lc, _("Missing config Resource \"%s\" referenced on line %d : %s\n"),
578            lc->str, lc->line_no, lc->line);
579      }
580    }
581    scan_to_eol(lc);
582 }
583
584
585
586 /* Store an integer at specified address */
587 void store_int(LEX *lc, RES_ITEM *item, int index, int pass)
588 {
589    lex_get_token(lc, T_INT32);
590    *(int *)(item->value) = lc->int32_val;
591    scan_to_eol(lc);
592    set_bit(index, res_all.hdr.item_present);
593 }
594
595 /* Store a positive integer at specified address */
596 void store_pint(LEX *lc, RES_ITEM *item, int index, int pass)
597 {
598    lex_get_token(lc, T_PINT32);
599    *(int *)(item->value) = lc->pint32_val;
600    scan_to_eol(lc);
601    set_bit(index, res_all.hdr.item_present);
602 }
603
604
605 /* Store an 64 bit integer at specified address */
606 void store_int64(LEX *lc, RES_ITEM *item, int index, int pass)
607 {
608    lex_get_token(lc, T_INT64);
609    *(int64_t *)(item->value) = lc->int64_val;
610    scan_to_eol(lc);
611    set_bit(index, res_all.hdr.item_present);
612 }
613
614 /* Store a size in bytes */
615 void store_size(LEX *lc, RES_ITEM *item, int index, int pass)
616 {
617    int token;
618    uint64_t uvalue;
619    char bsize[500];
620
621    Dmsg0(900, "Enter store_size\n");
622    token = lex_get_token(lc, T_SKIP_EOL);
623    errno = 0;
624    switch (token) {
625    case T_NUMBER:
626    case T_IDENTIFIER:
627    case T_UNQUOTED_STRING:
628       bstrncpy(bsize, lc->str, sizeof(bsize));  /* save first part */
629       /* if terminated by space, scan and get modifier */
630       while (lc->ch == ' ') {
631          token = lex_get_token(lc, T_ALL);
632          switch (token) {
633          case T_NUMBER:
634          case T_IDENTIFIER:
635          case T_UNQUOTED_STRING:
636             bstrncat(bsize, lc->str, sizeof(bsize));
637             break;
638          }
639       }
640       if (!size_to_uint64(bsize, strlen(bsize), &uvalue)) {
641          scan_err1(lc, _("expected a size number, got: %s"), lc->str);
642       }
643       *(uint64_t *)(item->value) = uvalue;
644       break;
645    default:
646       scan_err1(lc, _("expected a size, got: %s"), lc->str);
647       break;
648    }
649    if (token != T_EOL) {
650       scan_to_eol(lc);
651    }
652    set_bit(index, res_all.hdr.item_present);
653    Dmsg0(900, "Leave store_size\n");
654 }
655
656
657 /* Store a time period in seconds */
658 void store_time(LEX *lc, RES_ITEM *item, int index, int pass)
659 {
660    int token;
661    utime_t utime;
662    char period[500];
663
664    token = lex_get_token(lc, T_SKIP_EOL);
665    errno = 0;
666    switch (token) {
667    case T_NUMBER:
668    case T_IDENTIFIER:
669    case T_UNQUOTED_STRING:
670       bstrncpy(period, lc->str, sizeof(period));  /* get first part */
671       /* if terminated by space, scan and get modifier */
672       while (lc->ch == ' ') {
673          token = lex_get_token(lc, T_ALL);
674          switch (token) {
675          case T_NUMBER:
676          case T_IDENTIFIER:
677          case T_UNQUOTED_STRING:
678             bstrncat(period, lc->str, sizeof(period));
679             break;
680          }
681       }
682       if (!duration_to_utime(period, &utime)) {
683          scan_err1(lc, _("expected a time period, got: %s"), period);
684       }
685       *(utime_t *)(item->value) = utime;
686       break;
687    default:
688       scan_err1(lc, _("expected a time period, got: %s"), lc->str);
689       break;
690    }
691    if (token != T_EOL) {
692       scan_to_eol(lc);
693    }
694    set_bit(index, res_all.hdr.item_present);
695 }
696
697
698 /* Store a yes/no in a bit field */
699 void store_bit(LEX *lc, RES_ITEM *item, int index, int pass)
700 {
701    lex_get_token(lc, T_NAME);
702    if (strcasecmp(lc->str, "yes") == 0 || strcasecmp(lc->str, "true") == 0) {
703       *(int *)(item->value) |= item->code;
704    } else if (strcasecmp(lc->str, "no") == 0 || strcasecmp(lc->str, "false") == 0) {
705       *(int *)(item->value) &= ~(item->code);
706    } else {
707       scan_err2(lc, _("Expect %s, got: %s"), "YES, NO, TRUE, or FALSE", lc->str); /* YES and NO must not be translated */
708    }
709    scan_to_eol(lc);
710    set_bit(index, res_all.hdr.item_present);
711 }
712
713 /* Store a bool in a bit field */
714 void store_bool(LEX *lc, RES_ITEM *item, int index, int pass)
715 {
716    lex_get_token(lc, T_NAME);
717    if (strcasecmp(lc->str, "yes") == 0 || strcasecmp(lc->str, "true") == 0) {
718       *(bool *)(item->value) = true;
719    } else if (strcasecmp(lc->str, "no") == 0 || strcasecmp(lc->str, "false") == 0) {
720       *(bool *)(item->value) = false;
721    } else {
722       scan_err2(lc, _("Expect %s, got: %s"), "YES, NO, TRUE, or FALSE", lc->str); /* YES and NO must not be translated */
723    }
724    scan_to_eol(lc);
725    set_bit(index, res_all.hdr.item_present);
726 }
727
728
729 /*
730  * Store Tape Label Type (Bacula, ANSI, IBM)
731  *
732  */
733 void store_label(LEX *lc, RES_ITEM *item, int index, int pass)
734 {
735    int token, i;
736
737    token = lex_get_token(lc, T_NAME);
738    /* Store the label pass 2 so that type is defined */
739    for (i=0; tapelabels[i].name; i++) {
740       if (strcasecmp(lc->str, tapelabels[i].name) == 0) {
741          *(int *)(item->value) = tapelabels[i].token;
742          i = 0;
743          break;
744       }
745    }
746    if (i != 0) {
747       scan_err1(lc, _("Expected a Tape Label keyword, got: %s"), lc->str);
748    }
749    scan_to_eol(lc);
750    set_bit(index, res_all.hdr.item_present);
751 }
752
753
754 /* Parser state */
755 enum parse_state {
756    p_none,
757    p_resource
758 };
759
760 /*********************************************************************
761  *
762  * Parse configuration file
763  *
764  * Return 0 if reading failed, 1 otherwise
765  *  Note, the default behavior unless you have set an alternate
766  *  scan_error handler is to die on an error.
767  */
768 int
769 parse_config(const char *cf, LEX_ERROR_HANDLER *scan_error, int err_type)
770 {
771    LEX *lc = NULL;
772    int token, i, pass;
773    int res_type = 0;
774    enum parse_state state = p_none;
775    RES_ITEM *items = NULL;
776    int level = 0;
777
778    char *full_path = (char *)alloca(MAX_PATH);
779
780    if (find_config_file(cf, full_path)) {
781       cf = full_path;
782    }
783
784    /* Make two passes. The first builds the name symbol table,
785     * and the second picks up the items.
786     */
787    Dmsg0(900, "Enter parse_config()\n");
788    for (pass=1; pass <= 2; pass++) {
789       Dmsg1(900, "parse_config pass %d\n", pass);
790       if ((lc = lex_open_file(lc, cf, scan_error)) == NULL) {
791          berrno be;
792          /* We must create a lex packet to print the error */
793          lc = (LEX *)malloc(sizeof(LEX));
794          memset(lc, 0, sizeof(LEX));
795          if (scan_error) {
796             lc->scan_error = scan_error;
797          } else {
798             lex_set_default_error_handler(lc);
799          }
800          lex_set_error_handler_error_type(lc, err_type) ;
801          bstrncpy(lc->str, cf, sizeof(lc->str));
802          lc->fname = lc->str;
803          scan_err2(lc, _("Cannot open config file \"%s\": %s\n"),
804             lc->str, be.strerror());
805          free(lc);
806          return 0;
807       }
808       lex_set_error_handler_error_type(lc, err_type) ;
809       while ((token=lex_get_token(lc, T_ALL)) != T_EOF) {
810          Dmsg1(900, "parse got token=%s\n", lex_tok_to_str(token));
811          switch (state) {
812          case p_none:
813             if (token == T_EOL) {
814                break;
815             }
816             if (token == T_UNICODE_MARK) {
817                break;
818             }
819             if (token != T_IDENTIFIER) {
820                scan_err1(lc, _("Expected a Resource name identifier, got: %s"), lc->str);
821                return 0;
822             }
823             for (i=0; resources[i].name; i++)
824                if (strcasecmp(resources[i].name, lc->str) == 0) {
825                   state = p_resource;
826                   items = resources[i].items;
827                   res_type = resources[i].rcode;
828                   init_resource(res_type, items, pass);
829                   break;
830                }
831             if (state == p_none) {
832                scan_err1(lc, _("expected resource name, got: %s"), lc->str);
833                return 0;
834             }
835             break;
836          case p_resource:
837             switch (token) {
838             case T_BOB:
839                level++;
840                break;
841             case T_IDENTIFIER:
842                if (level != 1) {
843                   scan_err1(lc, _("not in resource definition: %s"), lc->str);
844                   return 0;
845                }
846                for (i=0; items[i].name; i++) {
847                   if (strcasecmp(items[i].name, lc->str) == 0) {
848                      /* If the ITEM_NO_EQUALS flag is set we do NOT
849                       *   scan for = after the keyword  */
850                      if (!(items[i].flags & ITEM_NO_EQUALS)) {
851                         token = lex_get_token(lc, T_SKIP_EOL);
852                         Dmsg1 (900, "in T_IDENT got token=%s\n", lex_tok_to_str(token));
853                         if (token != T_EQUALS) {
854                            scan_err1(lc, _("expected an equals, got: %s"), lc->str);
855                            return 0;
856                         }
857                      }
858                      Dmsg1(800, "calling handler for %s\n", items[i].name);
859                      /* Call item handler */
860                      items[i].handler(lc, &items[i], i, pass);
861                      i = -1;
862                      break;
863                   }
864                }
865                if (i >= 0) {
866                   Dmsg2(900, "level=%d id=%s\n", level, lc->str);
867                   Dmsg1(900, "Keyword = %s\n", lc->str);
868                   scan_err1(lc, _("Keyword \"%s\" not permitted in this resource.\n"
869                      "Perhaps you left the trailing brace off of the previous resource."), lc->str);
870                   return 0;
871                }
872                break;
873
874             case T_EOB:
875                level--;
876                state = p_none;
877                Dmsg0(900, "T_EOB => define new resource\n");
878                if (res_all.hdr.name == NULL) {
879                   scan_err0(lc, _("Name not specified for resource"));
880                }
881                save_resource(res_type, items, pass);  /* save resource */
882                break;
883
884             case T_EOL:
885                break;
886
887             default:
888                scan_err2(lc, _("unexpected token %d %s in resource definition"),
889                   token, lex_tok_to_str(token));
890                return 0;
891             }
892             break;
893          default:
894             scan_err1(lc, _("Unknown parser state %d\n"), state);
895             return 0;
896          }
897       }
898       if (state != p_none) {
899          scan_err0(lc, _("End of conf file reached with unclosed resource."));
900          return 0;
901       }
902       if (debug_level >= 900 && pass == 2) {
903          int i;
904          for (i=r_first; i<=r_last; i++) {
905             dump_resource(i, res_head[i-r_first], prtmsg, NULL);
906          }
907       }
908       lc = lex_close_file(lc);
909    }
910    Dmsg0(900, "Leave parse_config()\n");
911    return 1;
912 }
913
914 const char *get_default_configdir()
915 {
916 #if defined(HAVE_WIN32)
917 #define DEFAULT_CONFIGDIR "C:\\Documents and Settings\\All Users\\Application Data\\Bacula"
918
919    HRESULT hr;
920    static char szConfigDir[MAX_PATH + 1] = { 0 };
921
922    if (szConfigDir[0] == '\0') {
923       hr = SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL, 0, szConfigDir);
924
925       if (SUCCEEDED(hr)) {
926          bstrncat(szConfigDir, "\\Bacula", sizeof(szConfigDir));
927       } else {
928          bstrncpy(szConfigDir, DEFAULT_CONFIGDIR, sizeof(szConfigDir));
929       }
930    }
931    return szConfigDir;
932 #else
933    return "/etc/bacula";
934 #endif
935 }
936
937 bool
938 find_config_file(const char *config_file, char *full_path)
939 {
940 #if defined(HAVE_WIN32)
941    if (strpbrk(config_file, ":/\\") != NULL) {
942       return false;
943    }
944 #else
945    if (strchr(config_file, '/') != NULL) {
946       return false;
947    }
948 #endif
949
950    struct stat st;
951
952    if (stat(config_file, &st) == 0) {
953       return false;
954    }
955
956    const char *config_dir = get_default_configdir();
957    size_t dir_length = strlen(config_dir);
958    size_t file_length = strlen(config_file);
959
960    if ((dir_length + 1 + file_length + 1) > MAX_PATH) {
961       return false;
962    }
963
964    memcpy(full_path, config_dir, dir_length + 1);
965
966    if (full_path[dir_length - 1] != '/' && 
967        full_path[dir_length - 1] != '\\') {
968       full_path[dir_length++] = '/';
969    }
970
971    memcpy(&full_path[dir_length], config_file, file_length + 1);
972
973    return true;
974 }
975
976 /*********************************************************************
977  *
978  *      Free configuration resources
979  *
980  */
981 void free_config_resources()
982 {
983    for (int i=r_first; i<=r_last; i++) {
984       free_resource(res_head[i-r_first], i);
985       res_head[i-r_first] = NULL;
986    }
987 }
988
989 RES **save_config_resources()
990 {
991    int num = r_last - r_first + 1;
992    RES **res = (RES **)malloc(num*sizeof(RES *));
993    for (int i=0; i<num; i++) {
994       res[i] = res_head[i];
995       res_head[i] = NULL;
996    }
997    return res;
998 }
999
1000 RES **new_res_head()
1001 {
1002    int size = (r_last - r_first + 1) * sizeof(RES *);
1003    RES **res = (RES **)malloc(size);
1004    memset(res, 0, size);
1005    return res;
1006 }