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