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