]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/parse_conf.c
More changes to ensure that during thread switches the jcr
[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             }
278             break;
279          }
280          Dmsg1(900, "mail_cmd=%s\n", NPRT(cmd));
281          scan_types(lc, (MSGS *)(item->value), item->code, dest, cmd);
282          free_pool_memory(dest);
283          Dmsg0(900, "done with dest codes\n");
284          break;
285
286       case MD_FILE:                /* file */
287       case MD_APPEND:              /* append */
288          dest = get_pool_memory(PM_MESSAGE);
289          /* Pick up a single destination */
290          token = lex_get_token(lc, T_NAME);   /* scan destination */
291          pm_strcpy(dest, lc->str);
292          dest_len = lc->str_len;
293          token = lex_get_token(lc, T_SKIP_EOL);
294          Dmsg1(900, "store_msgs dest=%s:\n", NPRT(dest));
295          if (token != T_EQUALS) {
296             scan_err1(lc, _("expected an =, got: %s"), lc->str);
297          }
298          scan_types(lc, (MSGS *)(item->value), item->code, dest, NULL);
299          free_pool_memory(dest);
300          Dmsg0(900, "done with dest codes\n");
301          break;
302
303       default:
304          scan_err1(lc, _("Unknown item code: %d\n"), item->code);
305          break;
306       }
307    }
308    scan_to_eol(lc);
309    set_bit(index, res_all.hdr.item_present);
310    Dmsg0(900, "Done store_msgs\n");
311 }
312
313 /*
314  * Scan for message types and add them to the message
315  * destination. The basic job here is to connect message types
316  *  (WARNING, ERROR, FATAL, INFO, ...) with an appropriate
317  *  destination (MAIL, FILE, OPERATOR, ...)
318  */
319 static void scan_types(LEX *lc, MSGS *msg, int dest_code, char *where, char *cmd)
320 {
321    int i; 
322    bool found, is_not;
323    int msg_type = 0;
324    char *str;
325
326    for ( ;; ) {
327       lex_get_token(lc, T_NAME);            /* expect at least one type */
328       found = false;
329       if (lc->str[0] == '!') {
330          is_not = true;
331          str = &lc->str[1];
332       } else {
333          is_not = false;
334          str = &lc->str[0];
335       }
336       for (i=0; msg_types[i].name; i++) {
337          if (strcasecmp(str, msg_types[i].name) == 0) {
338             msg_type = msg_types[i].token;
339             found = true;
340             break;
341          }
342       }
343       if (!found) {
344          scan_err1(lc, _("message type: %s not found"), str);
345          /* NOT REACHED */
346       }
347
348       if (msg_type == M_MAX+1) {         /* all? */
349          for (i=1; i<=M_MAX; i++) {      /* yes set all types */
350             add_msg_dest(msg, dest_code, i, where, cmd);
351          }
352       } else if (is_not) {
353          rem_msg_dest(msg, dest_code, msg_type, where);
354       } else {
355          add_msg_dest(msg, dest_code, msg_type, where, cmd);
356       }
357       if (lc->ch != ',') {
358          break;
359       }
360       Dmsg0(900, "call lex_get_token() to eat comma\n");
361       lex_get_token(lc, T_ALL);          /* eat comma */
362    }
363    Dmsg0(900, "Done scan_types()\n");
364 }
365
366
367 /*
368  * This routine is ONLY for resource names
369  *  Store a name at specified address.
370  */
371 void store_name(LEX *lc, RES_ITEM *item, int index, int pass)
372 {
373    POOLMEM *msg = get_pool_memory(PM_EMSG);
374    lex_get_token(lc, T_NAME);
375    if (!is_name_valid(lc->str, &msg)) {
376       scan_err1(lc, "%s\n", msg);
377    }
378    free_pool_memory(msg);
379    /* Store the name both pass 1 and pass 2 */
380    if (*(item->value)) {
381       scan_err2(lc, _("Attempt to redefine name \"%s\" to \"%s\"."),
382          *(item->value), lc->str);
383    }
384    *(item->value) = bstrdup(lc->str);
385    scan_to_eol(lc);
386    set_bit(index, res_all.hdr.item_present);
387 }
388
389
390 /*
391  * Store a name string at specified address
392  * A name string is limited to MAX_RES_NAME_LENGTH
393  */
394 void store_strname(LEX *lc, RES_ITEM *item, int index, int pass)
395 {
396    lex_get_token(lc, T_NAME);
397    /* Store the name */
398    if (pass == 1) {
399       *(item->value) = bstrdup(lc->str);
400    }
401    scan_to_eol(lc);
402    set_bit(index, res_all.hdr.item_present);
403 }
404
405 /* Store a string at specified address */
406 void store_str(LEX *lc, RES_ITEM *item, int index, int pass)
407 {
408    lex_get_token(lc, T_STRING);
409    if (pass == 1) {
410       *(item->value) = bstrdup(lc->str);
411    }
412    scan_to_eol(lc);
413    set_bit(index, res_all.hdr.item_present);
414 }
415
416 /*
417  * Store a directory name at specified address. Note, we do
418  *   shell expansion except if the string begins with a vertical
419  *   bar (i.e. it will likely be passed to the shell later).
420  */
421 void store_dir(LEX *lc, RES_ITEM *item, int index, int pass)
422 {
423    lex_get_token(lc, T_STRING);
424    if (pass == 1) {
425       if (lc->str[0] != '|') {
426          do_shell_expansion(lc->str, sizeof(lc->str));
427       }
428       *(item->value) = bstrdup(lc->str);
429    }
430    scan_to_eol(lc);
431    set_bit(index, res_all.hdr.item_present);
432 }
433
434
435 /* Store a password specified address in MD5 coding */
436 void store_password(LEX *lc, RES_ITEM *item, int index, int pass)
437 {
438    unsigned int i, j;
439    struct MD5Context md5c;
440    unsigned char digest[CRYPTO_DIGEST_MD5_SIZE];
441    char sig[100];
442
443
444    lex_get_token(lc, T_STRING);
445    if (pass == 1) {
446       MD5Init(&md5c);
447       MD5Update(&md5c, (unsigned char *) (lc->str), lc->str_len);
448       MD5Final(digest, &md5c);
449       for (i = j = 0; i < sizeof(digest); i++) {
450          sprintf(&sig[j], "%02x", digest[i]);
451          j += 2;
452       }
453       *(item->value) = bstrdup(sig);
454    }
455    scan_to_eol(lc);
456    set_bit(index, res_all.hdr.item_present);
457 }
458
459
460 /* Store a resource at specified address.
461  * If we are in pass 2, do a lookup of the
462  * resource.
463  */
464 void store_res(LEX *lc, RES_ITEM *item, int index, int pass)
465 {
466    RES *res;
467
468    lex_get_token(lc, T_NAME);
469    if (pass == 2) {
470       res = GetResWithName(item->code, lc->str);
471       if (res == NULL) {
472          scan_err3(lc, _("Could not find config Resource %s referenced on line %d : %s\n"),
473             lc->str, lc->line_no, lc->line);
474       }
475       if (*(item->value)) {
476          scan_err3(lc, _("Attempt to redefine resource \"%s\" referenced on line %d : %s\n"),
477             item->name, lc->line_no, lc->line);
478       }
479       *(item->value) = (char *)res;
480    }
481    scan_to_eol(lc);
482    set_bit(index, res_all.hdr.item_present);
483 }
484
485 /*
486  * Store a resource pointer in an alist. default_value indicates how many
487  *   times this routine can be called -- i.e. how many alists
488  *   there are.
489  * If we are in pass 2, do a lookup of the
490  *   resource.
491  */
492 void store_alist_res(LEX *lc, RES_ITEM *item, int index, int pass)
493 {
494    RES *res;
495    int count = item->default_value;
496    int i = 0;
497    alist *list;
498
499    if (pass == 2) {
500       if (count == 0) {               /* always store in item->value */
501          i = 0;
502          if ((item->value)[i] == NULL) {
503             list = New(alist(10, not_owned_by_alist));
504          } else {
505             list = (alist *)(item->value)[i];
506          }
507       } else {
508          /* Find empty place to store this directive */
509          while ((item->value)[i] != NULL && i++ < count) { }
510          if (i >= count) {
511             scan_err4(lc, _("Too many %s directives. Max. is %d. line %d: %s\n"),
512                lc->str, count, lc->line_no, lc->line);
513          }
514          list = New(alist(10, not_owned_by_alist));
515       }
516
517       for (;;) {
518          lex_get_token(lc, T_NAME);   /* scan next item */
519          res = GetResWithName(item->code, lc->str);
520          if (res == NULL) {
521             scan_err3(lc, _("Could not find config Resource \"%s\" referenced on line %d : %s\n"),
522                item->name, lc->line_no, lc->line);
523          }
524          Dmsg5(900, "Append %p to alist %p size=%d i=%d %s\n", 
525                res, list, list->size(), i, item->name);
526          list->append(res);
527          (item->value)[i] = (char *)list;
528          if (lc->ch != ',') {         /* if no other item follows */
529             break;                    /* get out */
530          }
531          lex_get_token(lc, T_ALL);    /* eat comma */
532       }
533    }
534    scan_to_eol(lc);
535    set_bit(index, res_all.hdr.item_present);
536 }
537
538
539 /*
540  * Store a string in an alist.
541  */
542 void store_alist_str(LEX *lc, RES_ITEM *item, int index, int pass)
543 {
544    alist *list;
545
546    if (pass == 2) {
547       if (*(item->value) == NULL) {
548          list = New(alist(10, owned_by_alist));
549       } else {
550          list = (alist *)(*(item->value));    
551       }
552
553       lex_get_token(lc, T_STRING);   /* scan next item */
554       Dmsg4(900, "Append %s to alist %p size=%d %s\n", 
555          lc->str, list, list->size(), item->name);
556       list->append(bstrdup(lc->str));
557       *(item->value) = (char *)list;
558    }
559    scan_to_eol(lc);
560    set_bit(index, res_all.hdr.item_present);
561 }
562
563
564
565 /*
566  * Store default values for Resource from xxxDefs
567  * If we are in pass 2, do a lookup of the
568  * resource and store everything not explicitly set
569  * in main resource.
570  *
571  * Note, here item points to the main resource (e.g. Job, not
572  *  the jobdefs, which we look up).
573  */
574 void store_defs(LEX *lc, RES_ITEM *item, int index, int pass)
575 {
576    RES *res;
577
578    lex_get_token(lc, T_NAME);
579    if (pass == 2) {
580      Dmsg2(900, "Code=%d name=%s\n", item->code, lc->str);
581      res = GetResWithName(item->code, lc->str);
582      if (res == NULL) {
583         scan_err3(lc, _("Missing config Resource \"%s\" referenced on line %d : %s\n"),
584            lc->str, lc->line_no, lc->line);
585      }
586    }
587    scan_to_eol(lc);
588 }
589
590
591
592 /* Store an integer at specified address */
593 void store_int32(LEX *lc, RES_ITEM *item, int index, int pass)
594 {
595    lex_get_token(lc, T_INT32);
596    *(uint32_t *)(item->value) = lc->int32_val;
597    scan_to_eol(lc);
598    set_bit(index, res_all.hdr.item_present);
599 }
600
601 /* Store a positive integer at specified address */
602 void store_pint32(LEX *lc, RES_ITEM *item, int index, int pass)
603 {
604    lex_get_token(lc, T_PINT32);
605    *(uint32_t *)(item->value) = lc->pint32_val;
606    scan_to_eol(lc);
607    set_bit(index, res_all.hdr.item_present);
608 }
609
610
611 /* Store an 64 bit integer at specified address */
612 void store_int64(LEX *lc, RES_ITEM *item, int index, int pass)
613 {
614    lex_get_token(lc, T_INT64);
615    *(int64_t *)(item->value) = lc->int64_val;
616    scan_to_eol(lc);
617    set_bit(index, res_all.hdr.item_present);
618 }
619
620 /* Store a size in bytes */
621 void store_size(LEX *lc, RES_ITEM *item, int index, int pass)
622 {
623    int token;
624    uint64_t uvalue;
625    char bsize[500];
626
627    Dmsg0(900, "Enter store_size\n");
628    token = lex_get_token(lc, T_SKIP_EOL);
629    errno = 0;
630    switch (token) {
631    case T_NUMBER:
632    case T_IDENTIFIER:
633    case T_UNQUOTED_STRING:
634       bstrncpy(bsize, lc->str, sizeof(bsize));  /* save first part */
635       /* if terminated by space, scan and get modifier */
636       while (lc->ch == ' ') {
637          token = lex_get_token(lc, T_ALL);
638          switch (token) {
639          case T_NUMBER:
640          case T_IDENTIFIER:
641          case T_UNQUOTED_STRING:
642             bstrncat(bsize, lc->str, sizeof(bsize));
643             break;
644          }
645       }
646       if (!size_to_uint64(bsize, strlen(bsize), &uvalue)) {
647          scan_err1(lc, _("expected a size number, got: %s"), lc->str);
648       }
649       *(uint64_t *)(item->value) = uvalue;
650       break;
651    default:
652       scan_err1(lc, _("expected a size, got: %s"), lc->str);
653       break;
654    }
655    if (token != T_EOL) {
656       scan_to_eol(lc);
657    }
658    set_bit(index, res_all.hdr.item_present);
659    Dmsg0(900, "Leave store_size\n");
660 }
661
662
663 /* Store a time period in seconds */
664 void store_time(LEX *lc, RES_ITEM *item, int index, int pass)
665 {
666    int token;
667    utime_t utime;
668    char period[500];
669
670    token = lex_get_token(lc, T_SKIP_EOL);
671    errno = 0;
672    switch (token) {
673    case T_NUMBER:
674    case T_IDENTIFIER:
675    case T_UNQUOTED_STRING:
676       bstrncpy(period, lc->str, sizeof(period));  /* get first part */
677       /* if terminated by space, scan and get modifier */
678       while (lc->ch == ' ') {
679          token = lex_get_token(lc, T_ALL);
680          switch (token) {
681          case T_NUMBER:
682          case T_IDENTIFIER:
683          case T_UNQUOTED_STRING:
684             bstrncat(period, lc->str, sizeof(period));
685             break;
686          }
687       }
688       if (!duration_to_utime(period, &utime)) {
689          scan_err1(lc, _("expected a time period, got: %s"), period);
690       }
691       *(utime_t *)(item->value) = utime;
692       break;
693    default:
694       scan_err1(lc, _("expected a time period, got: %s"), lc->str);
695       break;
696    }
697    if (token != T_EOL) {
698       scan_to_eol(lc);
699    }
700    set_bit(index, res_all.hdr.item_present);
701 }
702
703
704 /* Store a yes/no in a bit field */
705 void store_bit(LEX *lc, RES_ITEM *item, int index, int pass)
706 {
707    lex_get_token(lc, T_NAME);
708    if (strcasecmp(lc->str, "yes") == 0 || strcasecmp(lc->str, "true") == 0) {
709       *(uint32_t *)(item->value) |= item->code;
710    } else if (strcasecmp(lc->str, "no") == 0 || strcasecmp(lc->str, "false") == 0) {
711       *(uint32_t *)(item->value) &= ~(item->code);
712    } else {
713       scan_err2(lc, _("Expect %s, got: %s"), "YES, NO, TRUE, or FALSE", lc->str); /* YES and NO must not be translated */
714    }
715    scan_to_eol(lc);
716    set_bit(index, res_all.hdr.item_present);
717 }
718
719 /* Store a bool in a bit field */
720 void store_bool(LEX *lc, RES_ITEM *item, int index, int pass)
721 {
722    lex_get_token(lc, T_NAME);
723    if (strcasecmp(lc->str, "yes") == 0 || strcasecmp(lc->str, "true") == 0) {
724       *(bool *)(item->value) = true;
725    } else if (strcasecmp(lc->str, "no") == 0 || strcasecmp(lc->str, "false") == 0) {
726       *(bool *)(item->value) = false;
727    } else {
728       scan_err2(lc, _("Expect %s, got: %s"), "YES, NO, TRUE, or FALSE", lc->str); /* YES and NO must not be translated */
729    }
730    scan_to_eol(lc);
731    set_bit(index, res_all.hdr.item_present);
732 }
733
734
735 /*
736  * Store Tape Label Type (Bacula, ANSI, IBM)
737  *
738  */
739 void store_label(LEX *lc, RES_ITEM *item, int index, int pass)
740 {
741    int token, i;
742
743    token = lex_get_token(lc, T_NAME);
744    /* Store the label pass 2 so that type is defined */
745    for (i=0; tapelabels[i].name; i++) {
746       if (strcasecmp(lc->str, tapelabels[i].name) == 0) {
747          *(uint32_t *)(item->value) = tapelabels[i].token;
748          i = 0;
749          break;
750       }
751    }
752    if (i != 0) {
753       scan_err1(lc, _("Expected a Tape Label keyword, got: %s"), lc->str);
754    }
755    scan_to_eol(lc);
756    set_bit(index, res_all.hdr.item_present);
757 }
758
759
760 /* Parser state */
761 enum parse_state {
762    p_none,
763    p_resource
764 };
765
766 CONFIG *new_config_parser()
767 {
768    CONFIG *config;
769    config = (CONFIG *)malloc(sizeof(CONFIG));
770    memset(config, 0, sizeof(CONFIG));
771    return config;
772 }
773
774 void CONFIG::init(
775    const char *cf,
776    LEX_ERROR_HANDLER *scan_error,
777    int err_type,
778    void *vres_all,
779    int res_all_size,
780    int r_first,
781    int r_last,
782    RES_TABLE *resources,
783    RES **res_head)
784 {
785    m_cf = cf;
786    m_scan_error = scan_error;
787    m_err_type = err_type;
788    m_res_all = vres_all;
789    m_res_all_size = res_all_size;
790    m_r_first = r_first;
791    m_r_last = r_last;
792    m_resources = resources;
793    m_res_head = res_head;
794 }
795
796 /*********************************************************************
797  *
798  * Parse configuration file
799  *
800  * Return 0 if reading failed, 1 otherwise
801  *  Note, the default behavior unless you have set an alternate
802  *  scan_error handler is to die on an error.
803  */
804 #ifdef xxx
805 int
806 parse_config(const char *cf, LEX_ERROR_HANDLER *scan_error, int err_type)
807 {
808    int ok;
809    CONFIG *config = new_config_parser();
810    config->init(cf, scan_error, err_type, (void *)&res_all, res_all_size,    
811                 r_first, r_last, resources, res_head);
812    ok = config->parse_config();
813    free(config);
814    return ok;
815 }
816 #endif
817       
818    
819 bool CONFIG::parse_config()
820 {
821    LEX *lc = NULL;
822    int token, i, pass;
823    int res_type = 0;
824    enum parse_state state = p_none;
825    RES_ITEM *items = NULL;
826    int level = 0;
827    static bool first = true;
828    int errstat;
829    const char *cf = m_cf;
830    LEX_ERROR_HANDLER *scan_error = m_scan_error;
831    int err_type = m_err_type;
832
833    if (first && (errstat=rwl_init(&res_lock)) != 0) {
834       berrno be;
835       Emsg1(M_ABORT, 0, _("Unable to initialize resource lock. ERR=%s\n"),
836             be.bstrerror(errstat));
837    }
838    first = false;
839
840    char *full_path = (char *)alloca(MAX_PATH + 1);
841
842    if (find_config_file(cf, full_path, MAX_PATH +1)) {
843       cf = full_path;
844    }
845
846    /* Make two passes. The first builds the name symbol table,
847     * and the second picks up the items.
848     */
849    Dmsg0(900, "Enter parse_config()\n");
850    for (pass=1; pass <= 2; pass++) {
851       Dmsg1(900, "parse_config pass %d\n", pass);
852       if ((lc = lex_open_file(lc, cf, scan_error)) == NULL) {
853          berrno be;
854          /* We must create a lex packet to print the error */
855          lc = (LEX *)malloc(sizeof(LEX));
856          memset(lc, 0, sizeof(LEX));
857          if (scan_error) {
858             lc->scan_error = scan_error;
859          } else {
860             lex_set_default_error_handler(lc);
861          }
862          lex_set_error_handler_error_type(lc, err_type) ;
863          bstrncpy(lc->str, cf, sizeof(lc->str));
864          lc->fname = lc->str;
865          scan_err2(lc, _("Cannot open config file \"%s\": %s\n"),
866             lc->str, be.bstrerror());
867          free(lc);
868          return 0;
869       }
870       lex_set_error_handler_error_type(lc, err_type) ;
871       while ((token=lex_get_token(lc, T_ALL)) != T_EOF) {
872          Dmsg3(900, "parse state=%d pass=%d got token=%s\n", state, pass,
873               lex_tok_to_str(token));
874          switch (state) {
875          case p_none:
876             if (token == T_EOL) {
877                break;
878             } else if (token == T_UTF8_BOM) {
879                /* We can assume the file is UTF-8 as we have seen a UTF-8 BOM */
880                break;
881             } else if (token == T_UTF16_BOM) {
882                scan_err0(lc, _("Currently we cannot handle UTF-16 source files. "
883                    "Please convert the conf file to UTF-8\n"));
884                return 0;
885             } else if (token != T_IDENTIFIER) {
886                scan_err1(lc, _("Expected a Resource name identifier, got: %s"), lc->str);
887                return 0;
888             }
889             for (i=0; resources[i].name; i++) {
890                if (strcasecmp(resources[i].name, lc->str) == 0) {
891                   items = resources[i].items;
892                   if (!items) {
893                      break;
894                   }
895                   state = p_resource;
896                   res_type = resources[i].rcode;
897                   init_resource(this, res_type, items, pass);
898                   break;
899                }
900             }
901             if (state == p_none) {
902                scan_err1(lc, _("expected resource name, got: %s"), lc->str);
903                return 0;
904             }
905             break;
906          case p_resource:
907             switch (token) {
908             case T_BOB:
909                level++;
910                break;
911             case T_IDENTIFIER:
912                if (level != 1) {
913                   scan_err1(lc, _("not in resource definition: %s"), lc->str);
914                   return 0;
915                }
916                for (i=0; items[i].name; i++) {
917                   if (strcasecmp(items[i].name, lc->str) == 0) {
918                      /* If the ITEM_NO_EQUALS flag is set we do NOT
919                       *   scan for = after the keyword  */
920                      if (!(items[i].flags & ITEM_NO_EQUALS)) {
921                         token = lex_get_token(lc, T_SKIP_EOL);
922                         Dmsg1 (900, "in T_IDENT got token=%s\n", lex_tok_to_str(token));
923                         if (token != T_EQUALS) {
924                            scan_err1(lc, _("expected an equals, got: %s"), lc->str);
925                            return 0;
926                         }
927                      }
928                      Dmsg1(800, "calling handler for %s\n", items[i].name);
929                      /* Call item handler */
930                      items[i].handler(lc, &items[i], i, pass);
931                      i = -1;
932                      break;
933                   }
934                }
935                if (i >= 0) {
936                   Dmsg2(900, "level=%d id=%s\n", level, lc->str);
937                   Dmsg1(900, "Keyword = %s\n", lc->str);
938                   scan_err1(lc, _("Keyword \"%s\" not permitted in this resource.\n"
939                      "Perhaps you left the trailing brace off of the previous resource."), lc->str);
940                   return 0;
941                }
942                break;
943
944             case T_EOB:
945                level--;
946                state = p_none;
947                Dmsg0(900, "T_EOB => define new resource\n");
948                if (res_all.hdr.name == NULL) {
949                   scan_err0(lc, _("Name not specified for resource"));
950                }
951                save_resource(res_type, items, pass);  /* save resource */
952                break;
953
954             case T_EOL:
955                break;
956
957             default:
958                scan_err2(lc, _("unexpected token %d %s in resource definition"),
959                   token, lex_tok_to_str(token));
960                return 0;
961             }
962             break;
963          default:
964             scan_err1(lc, _("Unknown parser state %d\n"), state);
965             return 0;
966          }
967       }
968       if (state != p_none) {
969          scan_err0(lc, _("End of conf file reached with unclosed resource."));
970          return 0;
971       }
972       if (debug_level >= 900 && pass == 2) {
973          int i;
974          for (i=m_r_first; i<=m_r_last; i++) {
975             dump_resource(i, m_res_head[i-m_r_first], prtmsg, NULL);
976          }
977       }
978       lc = lex_close_file(lc);
979    }
980    Dmsg0(900, "Leave parse_config()\n");
981    return 1;
982 }
983
984 const char *get_default_configdir()
985 {
986 #if defined(HAVE_WIN32)
987    HRESULT hr;
988    static char szConfigDir[MAX_PATH + 1] = { 0 };
989
990    if (!p_SHGetFolderPath) {
991       bstrncpy(szConfigDir, DEFAULT_CONFIGDIR, sizeof(szConfigDir));
992       return szConfigDir;
993    }
994
995    if (szConfigDir[0] == '\0') {
996       hr = p_SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL, 0, szConfigDir);
997
998       if (SUCCEEDED(hr)) {
999          bstrncat(szConfigDir, "\\Bacula", sizeof(szConfigDir));
1000       } else {
1001          bstrncpy(szConfigDir, DEFAULT_CONFIGDIR, sizeof(szConfigDir));
1002       }
1003    }
1004    return szConfigDir;
1005 #else
1006    return SYSCONFDIR;
1007 #endif
1008 }
1009
1010 static bool
1011 find_config_file(const char *config_file, char *full_path, int max_path)
1012 {
1013    if (first_path_separator(config_file) != NULL) {
1014       return false;
1015    }
1016
1017    struct stat st;
1018
1019    if (stat(config_file, &st) == 0) {
1020       return false;
1021    }
1022
1023    const char *config_dir = get_default_configdir();
1024    int dir_length = strlen(config_dir);
1025    int file_length = strlen(config_file);
1026
1027    if ((dir_length + 1 + file_length + 1) > max_path) {
1028       return false;
1029    }
1030
1031    memcpy(full_path, config_dir, dir_length + 1);
1032
1033    if (!IsPathSeparator(full_path[dir_length - 1])) {
1034       full_path[dir_length++] = '/';
1035    }
1036
1037    memcpy(&full_path[dir_length], config_file, file_length + 1);
1038
1039    return true;
1040 }
1041
1042 /*********************************************************************
1043  *
1044  *      Free configuration resources
1045  *
1046  */
1047 void CONFIG::free_resources()
1048 {
1049    for (int i=m_r_first; i<=m_r_last; i++) {
1050       free_resource(m_res_head[i-m_r_first], i);
1051       m_res_head[i-m_r_first] = NULL;
1052    }
1053 }
1054
1055 RES **CONFIG::save_resources()
1056 {
1057    int num = m_r_last - m_r_first + 1;
1058    RES **res = (RES **)malloc(num*sizeof(RES *));
1059    for (int i=0; i<num; i++) {
1060       res[i] = m_res_head[i];
1061       m_res_head[i] = NULL;
1062    }
1063    return res;
1064 }
1065
1066 RES **CONFIG::new_res_head()
1067 {
1068    int size = (m_r_last - m_r_first + 1) * sizeof(RES *);
1069    RES **res = (RES **)malloc(size);
1070    memset(res, 0, size);
1071    return res;
1072 }
1073
1074
1075 #ifdef xxx
1076 void free_config_resources()
1077 {
1078    for (int i=r_first; i<=r_last; i++) {
1079       free_resource(res_head[i-r_first], i);
1080       res_head[i-r_first] = NULL;
1081    }
1082 }
1083
1084 RES **save_config_resources()
1085 {
1086    int num = r_last - r_first + 1;
1087    RES **res = (RES **)malloc(num*sizeof(RES *));
1088    for (int i=0; i<num; i++) {
1089       res[i] = res_head[i];
1090       res_head[i] = NULL;
1091    }
1092    return res;
1093 }
1094
1095 RES **new_res_head()
1096 {
1097    int size = (r_last - r_first + 1) * sizeof(RES *);
1098    RES **res = (RES **)malloc(size);
1099    memset(res, 0, size);
1100    return res;
1101 }
1102 #endif