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