]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/parse_conf.c
85cb77d831cf03137215fc20c0bbbbb4b5468d54
[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(CONFIG *config, int type, RES_ITEM *items, int pass)
200 {
201    int i;
202    int rindex = type - r_first;
203
204    memset(config->m_res_all, 0, config->m_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 CONFIG *new_config_parser()
777 {
778    CONFIG *config;
779    config = (CONFIG *)malloc(sizeof(CONFIG));
780    memset(config, 0, sizeof(CONFIG));
781    return config;
782 }
783
784 void CONFIG::init(
785    const char *cf,
786    LEX_ERROR_HANDLER *scan_error,
787    int err_type,
788    void *vres_all,
789    int res_all_size,
790    int r_first,
791    int r_last,
792    RES_TABLE *resources,
793    RES **res_head)
794 {
795    m_cf = cf;
796    m_scan_error = scan_error;
797    m_err_type = err_type;
798    m_res_all = vres_all;
799    m_res_all_size = res_all_size;
800    m_r_first = r_first;
801    m_r_last = r_last;
802    m_resources = resources;
803    m_res_head = res_head;
804 }
805
806 /*********************************************************************
807  *
808  * Parse configuration file
809  *
810  * Return 0 if reading failed, 1 otherwise
811  *  Note, the default behavior unless you have set an alternate
812  *  scan_error handler is to die on an error.
813  */
814 int
815 parse_config(const char *cf, LEX_ERROR_HANDLER *scan_error, int err_type)
816 {
817    int ok;
818    CONFIG *config = new_config_parser();
819    config->init(cf, scan_error, err_type, (void *)&res_all, res_all_size,    
820                 r_first, r_last, resources, res_head);
821    ok = config->parse_config();
822    free(config);
823    return ok;
824 }
825       
826    
827 bool CONFIG::parse_config()
828 {
829    LEX *lc = NULL;
830    int token, i, pass;
831    int res_type = 0;
832    enum parse_state state = p_none;
833    RES_ITEM *items = NULL;
834    int level = 0;
835    static bool first = true;
836    int errstat;
837    const char *cf = m_cf;
838    LEX_ERROR_HANDLER *scan_error = m_scan_error;
839    int err_type = m_err_type;
840
841    if (first && (errstat=rwl_init(&res_lock)) != 0) {
842       berrno be;
843       Emsg1(M_ABORT, 0, _("Unable to initialize resource lock. ERR=%s\n"),
844             be.bstrerror(errstat));
845    }
846    first = false;
847
848    char *full_path = (char *)alloca(MAX_PATH + 1);
849
850    if (find_config_file(cf, full_path, MAX_PATH +1)) {
851       cf = full_path;
852    }
853
854    /* Make two passes. The first builds the name symbol table,
855     * and the second picks up the items.
856     */
857    Dmsg0(900, "Enter parse_config()\n");
858    for (pass=1; pass <= 2; pass++) {
859       Dmsg1(900, "parse_config pass %d\n", pass);
860       if ((lc = lex_open_file(lc, cf, scan_error)) == NULL) {
861          berrno be;
862          /* We must create a lex packet to print the error */
863          lc = (LEX *)malloc(sizeof(LEX));
864          memset(lc, 0, sizeof(LEX));
865          if (scan_error) {
866             lc->scan_error = scan_error;
867          } else {
868             lex_set_default_error_handler(lc);
869          }
870          lex_set_error_handler_error_type(lc, err_type) ;
871          bstrncpy(lc->str, cf, sizeof(lc->str));
872          lc->fname = lc->str;
873          scan_err2(lc, _("Cannot open config file \"%s\": %s\n"),
874             lc->str, be.bstrerror());
875          free(lc);
876          return 0;
877       }
878       lex_set_error_handler_error_type(lc, err_type) ;
879       while ((token=lex_get_token(lc, T_ALL)) != T_EOF) {
880          Dmsg3(900, "parse state=%d pass=%d got token=%s\n", state, pass,
881               lex_tok_to_str(token));
882          switch (state) {
883          case p_none:
884             if (token == T_EOL) {
885                break;
886             } else if (token == T_UTF8_BOM) {
887                /* We can assume the file is UTF-8 as we have seen a UTF-8 BOM */
888                break;
889             } else if (token == T_UTF16_BOM) {
890                scan_err0(lc, _("Currently we cannot handle UTF-16 source files. "
891                    "Please convert the conf file to UTF-8\n"));
892                return 0;
893             } else if (token != T_IDENTIFIER) {
894                scan_err1(lc, _("Expected a Resource name identifier, got: %s"), lc->str);
895                return 0;
896             }
897             for (i=0; resources[i].name; i++) {
898                if (strcasecmp(resources[i].name, lc->str) == 0) {
899                   items = resources[i].items;
900                   if (!items) {
901                      break;
902                   }
903                   state = p_resource;
904                   res_type = resources[i].rcode;
905                   init_resource(this, res_type, items, pass);
906                   break;
907                }
908             }
909             if (state == p_none) {
910                scan_err1(lc, _("expected resource name, got: %s"), lc->str);
911                return 0;
912             }
913             break;
914          case p_resource:
915             switch (token) {
916             case T_BOB:
917                level++;
918                break;
919             case T_IDENTIFIER:
920                if (level != 1) {
921                   scan_err1(lc, _("not in resource definition: %s"), lc->str);
922                   return 0;
923                }
924                for (i=0; items[i].name; i++) {
925                   if (strcasecmp(items[i].name, lc->str) == 0) {
926                      /* If the ITEM_NO_EQUALS flag is set we do NOT
927                       *   scan for = after the keyword  */
928                      if (!(items[i].flags & ITEM_NO_EQUALS)) {
929                         token = lex_get_token(lc, T_SKIP_EOL);
930                         Dmsg1 (900, "in T_IDENT got token=%s\n", lex_tok_to_str(token));
931                         if (token != T_EQUALS) {
932                            scan_err1(lc, _("expected an equals, got: %s"), lc->str);
933                            return 0;
934                         }
935                      }
936                      Dmsg1(800, "calling handler for %s\n", items[i].name);
937                      /* Call item handler */
938                      items[i].handler(lc, &items[i], i, pass);
939                      i = -1;
940                      break;
941                   }
942                }
943                if (i >= 0) {
944                   Dmsg2(900, "level=%d id=%s\n", level, lc->str);
945                   Dmsg1(900, "Keyword = %s\n", lc->str);
946                   scan_err1(lc, _("Keyword \"%s\" not permitted in this resource.\n"
947                      "Perhaps you left the trailing brace off of the previous resource."), lc->str);
948                   return 0;
949                }
950                break;
951
952             case T_EOB:
953                level--;
954                state = p_none;
955                Dmsg0(900, "T_EOB => define new resource\n");
956                if (res_all.hdr.name == NULL) {
957                   scan_err0(lc, _("Name not specified for resource"));
958                }
959                save_resource(res_type, items, pass);  /* save resource */
960                break;
961
962             case T_EOL:
963                break;
964
965             default:
966                scan_err2(lc, _("unexpected token %d %s in resource definition"),
967                   token, lex_tok_to_str(token));
968                return 0;
969             }
970             break;
971          default:
972             scan_err1(lc, _("Unknown parser state %d\n"), state);
973             return 0;
974          }
975       }
976       if (state != p_none) {
977          scan_err0(lc, _("End of conf file reached with unclosed resource."));
978          return 0;
979       }
980       if (debug_level >= 900 && pass == 2) {
981          int i;
982          for (i=r_first; i<=r_last; i++) {
983             dump_resource(i, res_head[i-r_first], prtmsg, NULL);
984          }
985       }
986       lc = lex_close_file(lc);
987    }
988    Dmsg0(900, "Leave parse_config()\n");
989    return 1;
990 }
991
992 const char *get_default_configdir()
993 {
994 #if defined(HAVE_WIN32)
995    HRESULT hr;
996    static char szConfigDir[MAX_PATH + 1] = { 0 };
997
998    if (!p_SHGetFolderPath) {
999       bstrncpy(szConfigDir, DEFAULT_CONFIGDIR, sizeof(szConfigDir));
1000       return szConfigDir;
1001    }
1002
1003    if (szConfigDir[0] == '\0') {
1004       hr = p_SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL, 0, szConfigDir);
1005
1006       if (SUCCEEDED(hr)) {
1007          bstrncat(szConfigDir, "\\Bacula", sizeof(szConfigDir));
1008       } else {
1009          bstrncpy(szConfigDir, DEFAULT_CONFIGDIR, sizeof(szConfigDir));
1010       }
1011    }
1012    return szConfigDir;
1013 #else
1014    return SYSCONFDIR;
1015 #endif
1016 }
1017
1018 static bool
1019 find_config_file(const char *config_file, char *full_path, int max_path)
1020 {
1021    if (first_path_separator(config_file) != NULL) {
1022       return false;
1023    }
1024
1025    struct stat st;
1026
1027    if (stat(config_file, &st) == 0) {
1028       return false;
1029    }
1030
1031    const char *config_dir = get_default_configdir();
1032    int dir_length = strlen(config_dir);
1033    int file_length = strlen(config_file);
1034
1035    if ((dir_length + 1 + file_length + 1) > max_path) {
1036       return false;
1037    }
1038
1039    memcpy(full_path, config_dir, dir_length + 1);
1040
1041    if (!IsPathSeparator(full_path[dir_length - 1])) {
1042       full_path[dir_length++] = '/';
1043    }
1044
1045    memcpy(&full_path[dir_length], config_file, file_length + 1);
1046
1047    return true;
1048 }
1049
1050 /*********************************************************************
1051  *
1052  *      Free configuration resources
1053  *
1054  */
1055 void CONFIG::free_resources()
1056 {
1057    for (int i=m_r_first; i<=m_r_last; i++) {
1058       free_resource(m_res_head[i-m_r_first], i);
1059       m_res_head[i-m_r_first] = NULL;
1060    }
1061 }
1062
1063 RES **CONFIG::save_resources()
1064 {
1065    int num = m_r_last - m_r_first + 1;
1066    RES **res = (RES **)malloc(num*sizeof(RES *));
1067    for (int i=0; i<num; i++) {
1068       res[i] = m_res_head[i];
1069       m_res_head[i] = NULL;
1070    }
1071    return res;
1072 }
1073
1074 RES **CONFIG::new_res_head()
1075 {
1076    int size = (m_r_last - m_r_first + 1) * sizeof(RES *);
1077    RES **res = (RES **)malloc(size);
1078    memset(res, 0, size);
1079    return res;
1080 }
1081
1082 void free_config_resources()
1083 {
1084    for (int i=r_first; i<=r_last; i++) {
1085       free_resource(res_head[i-r_first], i);
1086       res_head[i-r_first] = NULL;
1087    }
1088 }
1089
1090 #ifdef xxx
1091 RES **save_config_resources()
1092 {
1093    int num = r_last - r_first + 1;
1094    RES **res = (RES **)malloc(num*sizeof(RES *));
1095    for (int i=0; i<num; i++) {
1096       res[i] = res_head[i];
1097       res_head[i] = NULL;
1098    }
1099    return res;
1100 }
1101
1102 RES **new_res_head()
1103 {
1104    int size = (r_last - r_first + 1) * sizeof(RES *);
1105    RES **res = (RES **)malloc(size);
1106    memset(res, 0, size);
1107    return res;
1108 }
1109 #endif