2 * Amanda, The Advanced Maryland Automatic Network Disk Archiver
3 * Copyright (c) 1991-2000 University of Maryland at College Park
6 * Permission to use, copy, modify, distribute, and sell this software and its
7 * documentation for any purpose is hereby granted without fee, provided that
8 * the above copyright notice appear in all copies and that both that
9 * copyright notice and this permission notice appear in supporting
10 * documentation, and that the name of U.M. not be used in advertising or
11 * publicity pertaining to distribution of the software without specific,
12 * written prior permission. U.M. makes no representations about the
13 * suitability of this software for any purpose. It is provided "as is"
14 * without express or implied warranty.
16 * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
18 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
20 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 * Author: James da Silva, Systems Design and Analysis Group
24 * Computer Science Department
25 * University of Maryland at College Park
28 * $Id: conffile.c,v 1.156 2006/07/26 15:17:37 martinea Exp $
30 * read configuration file
44 /* This module implements its own quixotic lexer and parser, present for historical
45 * reasons. If this were written from scratch, it would use flex/bison. */
47 /* An enumeration of the various tokens that might appear in a configuration file.
49 * - CONF_UNKNOWN has special meaning as an unrecognized token.
50 * - CONF_ANY can be used to request any token, rather than requiring a specific
54 CONF_UNKNOWN, CONF_ANY, CONF_COMMA,
55 CONF_LBRACE, CONF_RBRACE, CONF_NL,
56 CONF_END, CONF_IDENT, CONF_INT,
57 CONF_INT64, CONF_BOOL, CONF_REAL,
58 CONF_STRING, CONF_TIME, CONF_SIZE,
60 /* config parameters */
61 CONF_INCLUDEFILE, CONF_ORG, CONF_MAILTO,
62 CONF_DUMPUSER, CONF_TAPECYCLE, CONF_TAPEDEV,
63 CONF_CHANGERDEV, CONF_CHANGERFILE, CONF_LABELSTR,
64 CONF_BUMPPERCENT, CONF_BUMPSIZE, CONF_BUMPDAYS,
65 CONF_BUMPMULT, CONF_ETIMEOUT, CONF_DTIMEOUT,
66 CONF_CTIMEOUT, CONF_TAPEBUFS, CONF_TAPELIST,
67 CONF_DEVICE_OUTPUT_BUFFER_SIZE,
68 CONF_DISKFILE, CONF_INFOFILE, CONF_LOGDIR,
69 CONF_LOGFILE, CONF_DISKDIR, CONF_DISKSIZE,
70 CONF_INDEXDIR, CONF_NETUSAGE, CONF_INPARALLEL,
71 CONF_DUMPORDER, CONF_TIMEOUT, CONF_TPCHANGER,
72 CONF_RUNTAPES, CONF_DEFINE, CONF_DUMPTYPE,
73 CONF_TAPETYPE, CONF_INTERFACE, CONF_PRINTER,
75 CONF_AUTOFLUSH, CONF_RESERVE, CONF_MAXDUMPSIZE,
76 CONF_COLUMNSPEC, CONF_AMRECOVER_DO_FSF, CONF_AMRECOVER_CHECK_LABEL,
77 CONF_AMRECOVER_CHANGER, CONF_LABEL_NEW_TAPES, CONF_USETIMESTAMPS,
80 CONF_TAPERALGO, CONF_FIRST, CONF_FIRSTFIT,
81 CONF_LARGEST, CONF_LARGESTFIT, CONF_SMALLEST,
82 CONF_LAST, CONF_DISPLAYUNIT, CONF_RESERVED_UDP_PORT,
83 CONF_RESERVED_TCP_PORT, CONF_UNRESERVED_TCP_PORT,
85 CONF_FLUSH_THRESHOLD_DUMPED,
86 CONF_FLUSH_THRESHOLD_SCHEDULED,
87 CONF_DEVICE_PROPERTY, CONF_PROPERTY, CONF_PLUGIN,
88 CONF_APPLICATION, CONF_APPLICATION_TOOL,
89 CONF_SCRIPT, CONF_SCRIPT_TOOL,
90 CONF_EXECUTE_ON, CONF_EXECUTE_WHERE, CONF_SEND_AMREPORT_ON,
91 CONF_DEVICE, CONF_ORDER,
92 CONF_DATA_PATH, CONF_AMANDA, CONF_DIRECTTCP,
95 CONF_PRE_DLE_AMCHECK, CONF_PRE_HOST_AMCHECK,
96 CONF_POST_DLE_AMCHECK, CONF_POST_HOST_AMCHECK,
97 CONF_PRE_DLE_ESTIMATE, CONF_PRE_HOST_ESTIMATE,
98 CONF_POST_DLE_ESTIMATE, CONF_POST_HOST_ESTIMATE,
99 CONF_PRE_DLE_BACKUP, CONF_PRE_HOST_BACKUP,
100 CONF_POST_DLE_BACKUP, CONF_POST_HOST_BACKUP,
101 CONF_PRE_RECOVER, CONF_POST_RECOVER,
102 CONF_PRE_LEVEL_RECOVER, CONF_POST_LEVEL_RECOVER,
103 CONF_INTER_LEVEL_RECOVER,
106 CONF_KRB5KEYTAB, CONF_KRB5PRINCIPAL,
109 CONF_COMMENT, CONF_DIRECTORY, CONF_USE,
113 /*COMMENT,*/ CONF_PROGRAM, CONF_DUMPCYCLE,
114 CONF_RUNSPERCYCLE, CONF_MAXCYCLE, CONF_MAXDUMPS,
115 CONF_OPTIONS, CONF_PRIORITY, CONF_FREQUENCY,
116 CONF_INDEX, CONF_MAXPROMOTEDAY, CONF_STARTTIME,
117 CONF_COMPRESS, CONF_ENCRYPT, CONF_AUTH,
118 CONF_STRATEGY, CONF_ESTIMATE, CONF_SKIP_INCR,
119 CONF_SKIP_FULL, CONF_RECORD, CONF_HOLDING,
120 CONF_EXCLUDE, CONF_INCLUDE, CONF_KENCRYPT,
121 CONF_IGNORE, CONF_COMPRATE, CONF_TAPE_SPLITSIZE,
122 CONF_SPLIT_DISKBUFFER, CONF_FALLBACK_SPLITSIZE,CONF_SRVCOMPPROG,
123 CONF_CLNTCOMPPROG, CONF_SRV_ENCRYPT, CONF_CLNT_ENCRYPT,
124 CONF_SRV_DECRYPT_OPT, CONF_CLNT_DECRYPT_OPT, CONF_AMANDAD_PATH,
125 CONF_CLIENT_USERNAME, CONF_CLIENT_PORT,
128 /*COMMENT,*/ CONF_BLOCKSIZE, CONF_FILE_PAD,
129 CONF_LBL_TEMPL, CONF_FILEMARK, CONF_LENGTH,
130 CONF_SPEED, CONF_READBLOCKSIZE,
133 CONF_CONF, CONF_INDEX_SERVER, CONF_TAPE_SERVER,
134 CONF_SSH_KEYS, CONF_GNUTAR_LIST_DIR, CONF_AMANDATES,
136 /* protocol config */
137 CONF_REP_TRIES, CONF_CONNECT_TRIES, CONF_REQ_TRIES,
141 CONF_DEBUG_AMANDAD, CONF_DEBUG_AMIDXTAPED, CONF_DEBUG_AMINDEXD,
142 CONF_DEBUG_AMRECOVER, CONF_DEBUG_AUTH, CONF_DEBUG_EVENT,
143 CONF_DEBUG_HOLDING, CONF_DEBUG_PROTOCOL, CONF_DEBUG_PLANNER,
144 CONF_DEBUG_DRIVER, CONF_DEBUG_DUMPER, CONF_DEBUG_CHUNKER,
145 CONF_DEBUG_TAPER, CONF_DEBUG_SELFCHECK, CONF_DEBUG_SENDSIZE,
146 CONF_DEBUG_SENDBACKUP, CONF_DEBUG_RECOVERY,
148 /* network interface */
149 /* COMMENT, */ /* USE, */
151 /* dump options (obsolete) */
152 CONF_EXCLUDE_FILE, CONF_EXCLUDE_LIST,
154 /* compress, estimate, encryption */
155 CONF_NONE, CONF_FAST, CONF_BEST,
156 CONF_SERVER, CONF_CLIENT, CONF_CALCSIZE,
160 CONF_AUTOLABEL, CONF_ANY_VOLUME, CONF_OTHER_CONFIG,
161 CONF_NON_AMANDA, CONF_VOLUME_ERROR, CONF_EMPTY,
164 CONF_NEVER, CONF_AUTO, CONF_REQUIRED,
167 CONF_ALL, CONF_STRANGE, CONF_ERROR,
170 CONF_LOW, CONF_MEDIUM, CONF_HIGH,
173 CONF_SKIP, CONF_STANDARD, CONF_NOFULL,
174 CONF_NOINC, CONF_HANOI, CONF_INCRONLY,
177 CONF_LIST, CONF_EFILE, CONF_APPEND,
181 CONF_AMINFINITY, CONF_MULT1, CONF_MULT7,
182 CONF_MULT1K, CONF_MULT1M, CONF_MULT1G,
186 CONF_ATRUE, CONF_AFALSE
189 /* A keyword table entry, mapping the given keyword to the given token.
190 * Note that punctuation, integers, and quoted strings are handled
191 * internally to the lexer, so they do not appear here. */
197 /* The current keyword table, used by all token-related functions */
198 static keytab_t *keytable = NULL;
200 /* Has a token been "ungotten", and if so, what was it? */
201 static int token_pushed;
202 static tok_t pushed_tok;
204 /* The current token and its value. Note that, unlike most other val_t*,
205 * tokenval's v.s points to statically allocated memory which cannot be
208 static val_t tokenval;
210 /* The current input information: file, filename, line, and character
211 * (which points somewhere within current_line) */
212 static FILE *current_file = NULL;
213 static char *current_filename = NULL;
214 static char *current_line = NULL;
215 static char *current_char = NULL;
216 static int current_line_num = 0; /* (technically, managed by the parser) */
218 /* A static buffer for storing tokens while they are being scanned. */
219 static char tkbuf[4096];
221 /* Look up the name of the given token in the current keytable */
222 static char *get_token_name(tok_t);
224 /* Look up a token in keytable, given a string, returning CONF_UNKNOWN
225 * for unrecognized strings. Search is case-insensitive. */
226 static tok_t lookup_keyword(char *str);
228 /* Get the next token. If exp is anything but CONF_ANY, and the next token
229 * does not match, then a parse error is flagged. This function reads from the
230 * current_* static variables, recognizes keywords against the keytable static
231 * variable, and places its result in tok and tokenval. */
232 static void get_conftoken(tok_t exp);
234 /* "Unget" the current token; this supports a 1-token lookahead. */
235 static void unget_conftoken(void);
237 /* Tokenizer character-by-character access. */
238 static int conftoken_getc(void);
239 static int conftoken_ungetc(int c);
241 static void merge_proplist_foreach_fn(gpointer key_p,
243 gpointer user_data_p);
244 static void copy_proplist_foreach_fn(gpointer key_p,
246 gpointer user_data_p);
252 /* A parser table entry. Read as "<token> introduces parameter <parm>,
253 * the data for which will be read by <read_function> and validated by
254 * <validate_function> (if not NULL). <type> is only used in formatting
255 * config overwrites. */
256 typedef struct conf_var_s {
259 void (*read_function) (struct conf_var_s *, val_t*);
261 void (*validate_function) (struct conf_var_s *, val_t *);
264 /* This is a list of filenames that are used in 'seen_t' structs. */
265 static GSList *seen_filenames = NULL;
267 /* get a copy of filename that's stored in seen_filenames so that it won't go
268 * away until config_uninit. */
269 static char *get_seen_filename(char *filename);
271 /* If allow_overwrites is true, the a parameter which has already been
272 * seen will simply overwrite the old value, rather than triggering an
273 * error. Note that this does not apply to all parameters, e.g.,
275 static int allow_overwrites;
277 /* subsection structs
279 * The 'seen' fields in these structs are useless outside this module;
280 * they are only used to generate error messages for multiply defined
284 struct tapetype_s *next;
288 val_t value[TAPETYPE_TAPETYPE];
292 struct dumptype_s *next;
296 val_t value[DUMPTYPE_DUMPTYPE];
300 struct interface_s *next;
304 val_t value[INTER_INTER];
307 struct holdingdisk_s {
311 val_t value[HOLDING_HOLDING];
314 struct application_s {
315 struct application_s *next;
319 val_t value[APPLICATION_APPLICATION];
323 struct pp_script_s *next;
327 val_t value[PP_SCRIPT_PP_SCRIPT];
330 struct device_config_s {
331 struct device_config_s *next;
335 val_t value[DEVICE_CONFIG_DEVICE_CONFIG];
338 struct changer_config_s {
339 struct changer_config_s *next;
343 val_t value[CHANGER_CONFIG_CHANGER_CONFIG];
346 /* The current parser table */
347 static conf_var_t *parsetable = NULL;
349 /* Read and parse a configuration file, recursively reading any included
350 * files. This function sets the keytable and parsetable appropriately
351 * according to is_client.
353 * @param filename: configuration file to read
354 * @param is_client: true if this is a client
355 * @param missing_ok: is it OK if the file is missing?
357 static void read_conffile(char *filename,
359 gboolean missing_ok);
361 /* Read and process a line of input from the current file, using the
362 * current keytable and parsetable. For blocks, this recursively
363 * reads the entire block.
365 * @param is_client: true if this is a client
366 * @returns: true on success, false on EOF
368 static gboolean read_confline(gboolean is_client);
370 /* Handle an invalid token, recognizing deprecated tokens as such,
371 * and producing an appropriate error message.
373 * @param token: the identifier
375 static void handle_invalid_keyword(const char * token);
377 /* Check whether token is deprecated, and issue a warning if it
378 * is. This consults the global variables 'tok' and 'tokenval'
380 static void handle_deprecated_keyword(void);
382 /* Read a brace-delimited block using the given parse table. This
383 * function is used to read brace-delimited subsections in the config
384 * files and also (via read_dumptype) to read dumptypes from
387 * This function implements "inheritance" as follows: if a bare
388 * identifier occurs within the braces, it calls copy_function (if
389 * not NULL), which looks up an existing subsection using the
390 * identifier from tokenval and copies any values not already seen
393 * @param read_var: the parse table to use
394 * @param valarray: the (pre-initialized) val_t array to fill in
395 * @param errormsg: error message to display for unrecognized keywords
396 * @param read_brace: if true, read the opening brace
397 * @param copy_function: function to copy configuration from
398 * another subsection into this one.
400 static void read_block(conf_var_t *read_var, val_t *valarray,
401 char *errormsg, int read_brace,
402 void (*copy_function)(void),
403 char *type, char *name);
405 /* For each subsection type, we have a global and four functions:
406 * - foocur is a temporary struct used to assemble new subsections
407 * - get_foo is called after reading "DEFINE FOO", and
408 * is responsible for reading the entire block, using
410 * - init_foo_defaults initializes a new subsection struct
411 * to its default values
412 * - save_foo copies foocur to a newly allocated struct and
413 * inserts that into the relevant list.
414 * - copy_foo implements inheritance as described in read_block()
416 static holdingdisk_t hdcur;
417 static void get_holdingdisk(int is_define);
418 static void init_holdingdisk_defaults(void);
419 static void save_holdingdisk(void);
420 static void copy_holdingdisk(void);
422 static dumptype_t dpcur;
423 static void get_dumptype(void);
424 static void init_dumptype_defaults(void);
425 static void save_dumptype(void);
426 static void copy_dumptype(void);
428 static tapetype_t tpcur;
429 static void get_tapetype(void);
430 static void init_tapetype_defaults(void);
431 static void save_tapetype(void);
432 static void copy_tapetype(void);
434 static interface_t ifcur;
435 static void get_interface(void);
436 static void init_interface_defaults(void);
437 static void save_interface(void);
438 static void copy_interface(void);
440 static application_t apcur;
441 static void get_application(void);
442 static void init_application_defaults(void);
443 static void save_application(void);
444 static void copy_application(void);
446 static pp_script_t pscur;
447 static void get_pp_script(void);
448 static void init_pp_script_defaults(void);
449 static void save_pp_script(void);
450 static void copy_pp_script(void);
452 static device_config_t dccur;
453 static void get_device_config(void);
454 static void init_device_config_defaults(void);
455 static void save_device_config(void);
456 static void copy_device_config(void);
458 static changer_config_t cccur;
459 static void get_changer_config(void);
460 static void init_changer_config_defaults(void);
461 static void save_changer_config(void);
462 static void copy_changer_config(void);
464 /* read_functions -- these fit into the read_function slot in a parser
465 * table entry, and are responsible for calling getconf_token as necessary
466 * to consume their arguments, and setting their second argument with the
467 * result. The first argument is a copy of the parser table entry, if
469 static void read_int(conf_var_t *, val_t *);
470 static void read_int64(conf_var_t *, val_t *);
471 static void read_real(conf_var_t *, val_t *);
472 static void read_str(conf_var_t *, val_t *);
473 static void read_ident(conf_var_t *, val_t *);
474 static void read_time(conf_var_t *, val_t *);
475 static void read_size(conf_var_t *, val_t *);
476 static void read_bool(conf_var_t *, val_t *);
477 static void read_compress(conf_var_t *, val_t *);
478 static void read_encrypt(conf_var_t *, val_t *);
479 static void read_holding(conf_var_t *, val_t *);
480 static void read_estimatelist(conf_var_t *, val_t *);
481 static void read_strategy(conf_var_t *, val_t *);
482 static void read_taperalgo(conf_var_t *, val_t *);
483 static void read_send_amreport_on(conf_var_t *, val_t *);
484 static void read_data_path(conf_var_t *, val_t *);
485 static void read_priority(conf_var_t *, val_t *);
486 static void read_rate(conf_var_t *, val_t *);
487 static void read_exinclude(conf_var_t *, val_t *);
488 static void read_intrange(conf_var_t *, val_t *);
489 static void read_dapplication(conf_var_t *, val_t *);
490 static void read_dpp_script(conf_var_t *, val_t *);
491 static void read_property(conf_var_t *, val_t *);
492 static void read_execute_on(conf_var_t *, val_t *);
493 static void read_execute_where(conf_var_t *, val_t *);
494 static void read_holdingdisk(conf_var_t *, val_t *);
495 static void read_int_or_str(conf_var_t *, val_t *);
496 static void read_autolabel(conf_var_t *, val_t *);
498 /* Functions to get various types of values. These are called by
499 * read_functions to take care of any variations in the way that these
500 * values can be written: integers can have units, boolean values can be
501 * specified with a number of names, etc. They form utility functions
502 * for the read_functions, below. */
503 static time_t get_time(void);
504 static int get_int(void);
505 static ssize_t get_size(void);
506 static gint64 get_int64(void);
507 static int get_bool(void);
509 /* Check the given 'seen', flagging an error if this value has already
510 * been seen and allow_overwrites is false. Also marks the value as
511 * seen on the current line.
513 * @param seen: (in/out) seen value to adjust
515 static void ckseen(seen_t *seen);
517 /* validate_functions -- these fit into the validate_function solt in
518 * a parser table entry. They call conf_parserror if the value in their
519 * second argument is invalid. */
520 static void validate_nonnegative(conf_var_t *, val_t *);
521 static void validate_positive(conf_var_t *, val_t *);
522 static void validate_runspercycle(conf_var_t *, val_t *);
523 static void validate_bumppercent(conf_var_t *, val_t *);
524 static void validate_bumpmult(conf_var_t *, val_t *);
525 static void validate_inparallel(conf_var_t *, val_t *);
526 static void validate_displayunit(conf_var_t *, val_t *);
527 static void validate_reserve(conf_var_t *, val_t *);
528 static void validate_use(conf_var_t *, val_t *);
529 static void validate_chunksize(conf_var_t *, val_t *);
530 static void validate_blocksize(conf_var_t *, val_t *);
531 static void validate_debug(conf_var_t *, val_t *);
532 static void validate_port_range(val_t *, int, int);
533 static void validate_reserved_port_range(conf_var_t *, val_t *);
534 static void validate_unreserved_port_range(conf_var_t *, val_t *);
535 static void validate_program(conf_var_t *, val_t *);
536 gint compare_pp_script_order(gconstpointer a, gconstpointer b);
542 /* The name of the configuration under which this application is running.
543 * This variable is initialized by config_init.
545 static char *config_name = NULL;
547 /* The directory containing the configuration for this application. This
548 * variable is initialized by config_init
550 static char *config_dir = NULL;
552 /* The most recently read top-level configuration file. This variable is
553 * initialized by config_init
555 static char *config_filename = NULL;
557 /* Has the config been initialized? */
558 static gboolean config_initialized = FALSE;
560 /* Are we running a client? (true if last init was
561 * with CONFIG_INIT_CLIENT) */
562 static gboolean config_client = FALSE;
564 /* What config overwrites to use? */
565 static config_overrides_t *config_overrides = NULL;
567 /* All global parameters */
568 static val_t conf_data[CNF_CNF];
570 /* Linked list of holding disks */
571 static GSList *holdinglist = NULL;
572 static dumptype_t *dumplist = NULL;
573 static tapetype_t *tapelist = NULL;
574 static interface_t *interface_list = NULL;
575 static application_t *application_list = NULL;
576 static pp_script_t *pp_script_list = NULL;
577 static device_config_t *device_config_list = NULL;
578 static changer_config_t *changer_config_list = NULL;
580 /* storage for derived values */
581 static long int unit_divisor = 1;
583 int debug_amandad = 0;
584 int debug_recovery = 0;
585 int debug_amidxtaped = 0;
586 int debug_amindexd = 0;
587 int debug_amrecover = 0;
590 int debug_holding = 0;
591 int debug_protocol = 0;
592 int debug_planner = 0;
593 int debug_driver = 0;
594 int debug_dumper = 0;
595 int debug_chunker = 0;
597 int debug_selfcheck = 0;
598 int debug_sendsize = 0;
599 int debug_sendbackup = 0;
601 /* Reset all configuration values to their defaults (which, in many
602 * cases, come from --with-foo options at build time) */
603 static void init_defaults(void);
605 /* Update all dervied values based on the current configuration. This
606 * function can be called multiple times, once after each adjustment
607 * to the current configuration.
609 * @param is_client: are we running a client?
611 static void update_derived_values(gboolean is_client);
613 static cfgerr_level_t apply_config_overrides(config_overrides_t *co,
616 /* per-type conf_init functions, used as utilities for init_defaults
617 * and for each subsection's init_foo_defaults.
619 * These set the value's type and seen flags, as well as copying
620 * the relevant value into the 'v' field.
622 static void conf_init_int(val_t *val, int i);
623 static void conf_init_int64(val_t *val, gint64 l);
624 static void conf_init_real(val_t *val, float r);
625 static void conf_init_str(val_t *val, char *s);
626 static void conf_init_ident(val_t *val, char *s);
627 static void conf_init_identlist(val_t *val, char *s);
628 static void conf_init_time(val_t *val, time_t t);
629 static void conf_init_size(val_t *val, ssize_t sz);
630 static void conf_init_bool(val_t *val, int i);
631 static void conf_init_compress(val_t *val, comp_t i);
632 static void conf_init_encrypt(val_t *val, encrypt_t i);
633 static void conf_init_data_path(val_t *val, data_path_t i);
634 static void conf_init_holding(val_t *val, dump_holdingdisk_t i);
635 static void conf_init_estimatelist(val_t *val, estimate_t i);
636 static void conf_init_execute_on(val_t *, int);
637 static void conf_init_execute_where(val_t *, int);
638 static void conf_init_send_amreport(val_t *val, send_amreport_t i);
639 static void conf_init_strategy(val_t *val, strategy_t);
640 static void conf_init_taperalgo(val_t *val, taperalgo_t i);
641 static void conf_init_priority(val_t *val, int i);
642 static void conf_init_rate(val_t *val, float r1, float r2);
643 static void conf_init_exinclude(val_t *val); /* to empty list */
644 static void conf_init_intrange(val_t *val, int i1, int i2);
645 static void conf_init_proplist(val_t *val); /* to empty list */
646 static void conf_init_application(val_t *val);
647 static void conf_init_autolabel(val_t *val);
650 * Command-line Handling
653 typedef struct config_override_s {
659 struct config_overrides_s {
662 config_override_t *ovr;
669 static void merge_val_t(val_t *, val_t *);
670 static void copy_val_t(val_t *, val_t *);
671 static void free_val_t(val_t *);
677 /* memory handling */
678 void free_property_t(gpointer p);
680 /* Utility functions/structs for val_t_display_strs */
681 static char *exinclude_display_str(val_t *val, int file);
682 static void proplist_display_str_foreach_fn(gpointer key_p, gpointer value_p, gpointer user_data_p);
683 static void val_t_print_token(FILE *output, char *prefix, char *format, keytab_t *kt, val_t *val);
685 /* Given a key name as used in config overwrites, return a pointer to the corresponding
686 * conf_var_t in the current parsetable, and the val_t representing that value. This
687 * function will access subsections if key has the form TYPE:SUBSEC:KEYWORD. Returns
688 * false if the value does not exist.
690 * Assumes keytable and parsetable are set correctly, which is generally OK after
691 * config_init has been called.
693 * @param key: the key to look up
694 * @param parm: (result) the parse table entry
695 * @param val: (result) the parameter value
696 * @returns: true on success
698 static int parm_key_info(char *key, conf_var_t **parm, val_t **val);
704 /* Have we seen a parse error yet? Parsing continues after an error, so this
705 * flag is checked after the parse is complete.
707 static cfgerr_level_t cfgerr_level;
708 static GSList *cfgerr_errors = NULL;
710 static void conf_error_common(cfgerr_level_t level, const char * format, va_list argp);
711 static void conf_parserror(const char *format, ...)
712 __attribute__ ((format (printf, 1, 2)));
714 static void conf_parswarn(const char *format, ...)
715 __attribute__ ((format (printf, 1, 2)));
721 /* First, the keyword tables for client and server */
722 keytab_t client_keytab[] = {
723 { "CONF", CONF_CONF },
724 { "INDEX_SERVER", CONF_INDEX_SERVER },
725 { "TAPE_SERVER", CONF_TAPE_SERVER },
726 { "TAPEDEV", CONF_TAPEDEV },
727 { "AUTH", CONF_AUTH },
728 { "SSH_KEYS", CONF_SSH_KEYS },
729 { "AMANDAD_PATH", CONF_AMANDAD_PATH },
730 { "CLIENT_USERNAME", CONF_CLIENT_USERNAME },
731 { "CLIENT_PORT", CONF_CLIENT_PORT },
732 { "GNUTAR_LIST_DIR", CONF_GNUTAR_LIST_DIR },
733 { "AMANDATES", CONF_AMANDATES },
734 { "KRB5KEYTAB", CONF_KRB5KEYTAB },
735 { "KRB5PRINCIPAL", CONF_KRB5PRINCIPAL },
736 { "INCLUDEFILE", CONF_INCLUDEFILE },
737 { "CONNECT_TRIES", CONF_CONNECT_TRIES },
738 { "REP_TRIES", CONF_REP_TRIES },
739 { "REQ_TRIES", CONF_REQ_TRIES },
740 { "CLIENT", CONF_CLIENT },
741 { "DEBUG_DAYS", CONF_DEBUG_DAYS },
742 { "DEBUG_AMANDAD", CONF_DEBUG_AMANDAD },
743 { "DEBUG_RECOVERY", CONF_DEBUG_RECOVERY },
744 { "DEBUG_AMIDXTAPED", CONF_DEBUG_AMIDXTAPED },
745 { "DEBUG_AMINDEXD", CONF_DEBUG_AMINDEXD },
746 { "DEBUG_AMRECOVER", CONF_DEBUG_AMRECOVER },
747 { "DEBUG_AUTH", CONF_DEBUG_AUTH },
748 { "DEBUG_EVENT", CONF_DEBUG_EVENT },
749 { "DEBUG_HOLDING", CONF_DEBUG_HOLDING },
750 { "DEBUG_PROTOCOL", CONF_DEBUG_PROTOCOL },
751 { "DEBUG_PLANNER", CONF_DEBUG_PLANNER },
752 { "DEBUG_DRIVER", CONF_DEBUG_DRIVER },
753 { "DEBUG_DUMPER", CONF_DEBUG_DUMPER },
754 { "DEBUG_CHUNKER", CONF_DEBUG_CHUNKER },
755 { "DEBUG_TAPER", CONF_DEBUG_TAPER },
756 { "DEBUG_SELFCHECK", CONF_DEBUG_SELFCHECK },
757 { "DEBUG_SENDSIZE", CONF_DEBUG_SENDSIZE },
758 { "DEBUG_SENDBACKUP", CONF_DEBUG_SENDBACKUP },
759 { "EXECUTE_ON", CONF_EXECUTE_ON },
760 { "EXECUTE_WHERE", CONF_EXECUTE_WHERE },
761 { "RESERVED_UDP_PORT", CONF_RESERVED_UDP_PORT },
762 { "RESERVED_TCP_PORT", CONF_RESERVED_TCP_PORT },
763 { "UNRESERVED_TCP_PORT", CONF_UNRESERVED_TCP_PORT },
764 { "DEFINE", CONF_DEFINE },
765 { "COMMENT", CONF_COMMENT },
766 { "MAILER", CONF_MAILER },
767 { "ORDER", CONF_ORDER },
768 { "SCRIPT", CONF_SCRIPT },
769 { "SCRIPT_TOOL", CONF_SCRIPT_TOOL },
770 { "PLUGIN", CONF_PLUGIN },
771 { "PRE_DLE_AMCHECK", CONF_PRE_DLE_AMCHECK },
772 { "PRE_HOST_AMCHECK", CONF_PRE_HOST_AMCHECK },
773 { "POST_DLE_AMCHECK", CONF_POST_DLE_AMCHECK },
774 { "POST_HOST_AMCHECK", CONF_POST_HOST_AMCHECK },
775 { "PRE_DLE_ESTIMATE", CONF_PRE_DLE_ESTIMATE },
776 { "PRE_HOST_ESTIMATE", CONF_PRE_HOST_ESTIMATE },
777 { "POST_DLE_ESTIMATE", CONF_POST_DLE_ESTIMATE },
778 { "POST_HOST_ESTIMATE", CONF_POST_HOST_ESTIMATE },
779 { "POST_DLE_BACKUP", CONF_POST_DLE_BACKUP },
780 { "POST_HOST_BACKUP", CONF_POST_HOST_BACKUP },
781 { "PRE_DLE_BACKUP", CONF_PRE_DLE_BACKUP },
782 { "PRE_HOST_BACKUP", CONF_PRE_HOST_BACKUP },
783 { "PRE_RECOVER", CONF_PRE_RECOVER },
784 { "POST_RECOVER", CONF_POST_RECOVER },
785 { "PRE_LEVEL_RECOVER", CONF_PRE_LEVEL_RECOVER },
786 { "POST_LEVEL_RECOVER", CONF_POST_LEVEL_RECOVER },
787 { "INTER_LEVEL_RECOVER", CONF_INTER_LEVEL_RECOVER },
788 { "PRIORITY", CONF_PRIORITY },
789 { "PROPERTY", CONF_PROPERTY },
790 { "APPLICATION", CONF_APPLICATION },
791 { "APPLICATION_TOOL", CONF_APPLICATION_TOOL },
792 { "SERVER", CONF_SERVER },
793 { "APPEND", CONF_APPEND },
794 { NULL, CONF_IDENT },
795 { NULL, CONF_UNKNOWN }
798 keytab_t server_keytab[] = {
800 { "AMANDA", CONF_AMANDA },
801 { "AMANDAD_PATH", CONF_AMANDAD_PATH },
802 { "AMRECOVER_CHANGER", CONF_AMRECOVER_CHANGER },
803 { "AMRECOVER_CHECK_LABEL", CONF_AMRECOVER_CHECK_LABEL },
804 { "AMRECOVER_DO_FSF", CONF_AMRECOVER_DO_FSF },
805 { "ANY", CONF_ANY_VOLUME },
806 { "APPEND", CONF_APPEND },
807 { "AUTH", CONF_AUTH },
808 { "AUTO", CONF_AUTO },
809 { "AUTOFLUSH", CONF_AUTOFLUSH },
810 { "AUTOLABEL", CONF_AUTOLABEL },
811 { "APPLICATION", CONF_APPLICATION },
812 { "APPLICATION_TOOL", CONF_APPLICATION_TOOL },
813 { "BEST", CONF_BEST },
814 { "BLOCKSIZE", CONF_BLOCKSIZE },
815 { "BUMPDAYS", CONF_BUMPDAYS },
816 { "BUMPMULT", CONF_BUMPMULT },
817 { "BUMPPERCENT", CONF_BUMPPERCENT },
818 { "BUMPSIZE", CONF_BUMPSIZE },
819 { "CALCSIZE", CONF_CALCSIZE },
820 { "CHANGER", CONF_CHANGER },
821 { "CHANGERDEV", CONF_CHANGERDEV },
822 { "CHANGERFILE", CONF_CHANGERFILE },
823 { "CHUNKSIZE", CONF_CHUNKSIZE },
824 { "CLIENT", CONF_CLIENT },
825 { "CLIENT_CUSTOM_COMPRESS", CONF_CLNTCOMPPROG },
826 { "CLIENT_DECRYPT_OPTION", CONF_CLNT_DECRYPT_OPT },
827 { "CLIENT_ENCRYPT", CONF_CLNT_ENCRYPT },
828 { "CLIENT_USERNAME", CONF_CLIENT_USERNAME },
829 { "COLUMNSPEC", CONF_COLUMNSPEC },
830 { "COMMENT", CONF_COMMENT },
831 { "COMPRATE", CONF_COMPRATE },
832 { "COMPRESS", CONF_COMPRESS },
833 { "CONNECT_TRIES", CONF_CONNECT_TRIES },
834 { "CTIMEOUT", CONF_CTIMEOUT },
835 { "CUSTOM", CONF_CUSTOM },
836 { "DATA_PATH", CONF_DATA_PATH },
837 { "DEBUG_DAYS" , CONF_DEBUG_DAYS },
838 { "DEBUG_AMANDAD" , CONF_DEBUG_AMANDAD },
839 { "DEBUG_RECOVERY" , CONF_DEBUG_RECOVERY },
840 { "DEBUG_AMIDXTAPED" , CONF_DEBUG_AMIDXTAPED },
841 { "DEBUG_AMINDEXD" , CONF_DEBUG_AMINDEXD },
842 { "DEBUG_AMRECOVER" , CONF_DEBUG_AMRECOVER },
843 { "DEBUG_AUTH" , CONF_DEBUG_AUTH },
844 { "DEBUG_EVENT" , CONF_DEBUG_EVENT },
845 { "DEBUG_HOLDING" , CONF_DEBUG_HOLDING },
846 { "DEBUG_PROTOCOL" , CONF_DEBUG_PROTOCOL },
847 { "DEBUG_PLANNER" , CONF_DEBUG_PLANNER },
848 { "DEBUG_DRIVER" , CONF_DEBUG_DRIVER },
849 { "DEBUG_DUMPER" , CONF_DEBUG_DUMPER },
850 { "DEBUG_CHUNKER" , CONF_DEBUG_CHUNKER },
851 { "DEBUG_TAPER" , CONF_DEBUG_TAPER },
852 { "DEBUG_SELFCHECK" , CONF_DEBUG_SELFCHECK },
853 { "DEBUG_SENDSIZE" , CONF_DEBUG_SENDSIZE },
854 { "DEBUG_SENDBACKUP" , CONF_DEBUG_SENDBACKUP },
855 { "DEFINE", CONF_DEFINE },
856 { "DEVICE", CONF_DEVICE },
857 { "DEVICE_PROPERTY", CONF_DEVICE_PROPERTY },
858 { "DIRECTORY", CONF_DIRECTORY },
859 { "DIRECTTCP", CONF_DIRECTTCP },
860 { "DISKFILE", CONF_DISKFILE },
861 { "DISPLAYUNIT", CONF_DISPLAYUNIT },
862 { "DTIMEOUT", CONF_DTIMEOUT },
863 { "DUMPCYCLE", CONF_DUMPCYCLE },
864 { "DUMPORDER", CONF_DUMPORDER },
865 { "DUMPTYPE", CONF_DUMPTYPE },
866 { "DUMPUSER", CONF_DUMPUSER },
867 { "EMPTY", CONF_EMPTY },
868 { "ENCRYPT", CONF_ENCRYPT },
869 { "ERROR", CONF_ERROR },
870 { "ESTIMATE", CONF_ESTIMATE },
871 { "ETIMEOUT", CONF_ETIMEOUT },
872 { "EXCLUDE", CONF_EXCLUDE },
873 { "EXCLUDE_FILE", CONF_EXCLUDE_FILE },
874 { "EXCLUDE_LIST", CONF_EXCLUDE_LIST },
875 { "EXECUTE_ON", CONF_EXECUTE_ON },
876 { "EXECUTE_WHERE", CONF_EXECUTE_WHERE },
877 { "FALLBACK_SPLITSIZE", CONF_FALLBACK_SPLITSIZE },
878 { "FAST", CONF_FAST },
879 { "FILE", CONF_EFILE },
880 { "FILE_PAD", CONF_FILE_PAD },
881 { "FILEMARK", CONF_FILEMARK },
882 { "FIRST", CONF_FIRST },
883 { "FIRSTFIT", CONF_FIRSTFIT },
884 { "HANOI", CONF_HANOI },
885 { "HIGH", CONF_HIGH },
886 { "HOLDINGDISK", CONF_HOLDING },
887 { "IGNORE", CONF_IGNORE },
888 { "INCLUDE", CONF_INCLUDE },
889 { "INCLUDEFILE", CONF_INCLUDEFILE },
890 { "INCRONLY", CONF_INCRONLY },
891 { "INDEX", CONF_INDEX },
892 { "INDEXDIR", CONF_INDEXDIR },
893 { "INFOFILE", CONF_INFOFILE },
894 { "INPARALLEL", CONF_INPARALLEL },
895 { "INTERFACE", CONF_INTERFACE },
896 { "KENCRYPT", CONF_KENCRYPT },
897 { "KRB5KEYTAB", CONF_KRB5KEYTAB },
898 { "KRB5PRINCIPAL", CONF_KRB5PRINCIPAL },
899 { "LABELSTR", CONF_LABELSTR },
900 { "LABEL_NEW_TAPES", CONF_LABEL_NEW_TAPES },
901 { "LARGEST", CONF_LARGEST },
902 { "LARGESTFIT", CONF_LARGESTFIT },
903 { "LAST", CONF_LAST },
904 { "LBL_TEMPL", CONF_LBL_TEMPL },
905 { "LENGTH", CONF_LENGTH },
906 { "LIST", CONF_LIST },
907 { "LOGDIR", CONF_LOGDIR },
909 { "MAILER", CONF_MAILER },
910 { "MAILTO", CONF_MAILTO },
911 { "READBLOCKSIZE", CONF_READBLOCKSIZE },
912 { "MAXDUMPS", CONF_MAXDUMPS },
913 { "MAXDUMPSIZE", CONF_MAXDUMPSIZE },
914 { "MAXPROMOTEDAY", CONF_MAXPROMOTEDAY },
915 { "MEDIUM", CONF_MEDIUM },
916 { "NETUSAGE", CONF_NETUSAGE },
917 { "NEVER", CONF_NEVER },
918 { "NOFULL", CONF_NOFULL },
919 { "NOINC", CONF_NOINC },
920 { "NONE", CONF_NONE },
921 { "NON_AMANDA", CONF_NON_AMANDA },
922 { "OPTIONAL", CONF_OPTIONAL },
923 { "ORDER", CONF_ORDER },
925 { "OTHER_CONFIG", CONF_OTHER_CONFIG },
926 { "PLUGIN", CONF_PLUGIN },
927 { "PRE_DLE_AMCHECK", CONF_PRE_DLE_AMCHECK },
928 { "PRE_HOST_AMCHECK", CONF_PRE_HOST_AMCHECK },
929 { "POST_DLE_AMCHECK", CONF_POST_DLE_AMCHECK },
930 { "POST_HOST_AMCHECK", CONF_POST_HOST_AMCHECK },
931 { "PRE_DLE_ESTIMATE", CONF_PRE_DLE_ESTIMATE },
932 { "PRE_HOST_ESTIMATE", CONF_PRE_HOST_ESTIMATE },
933 { "POST_DLE_ESTIMATE", CONF_POST_DLE_ESTIMATE },
934 { "POST_HOST_ESTIMATE", CONF_POST_HOST_ESTIMATE },
935 { "POST_DLE_BACKUP", CONF_POST_DLE_BACKUP },
936 { "POST_HOST_BACKUP", CONF_POST_HOST_BACKUP },
937 { "PRE_DLE_BACKUP", CONF_PRE_DLE_BACKUP },
938 { "PRE_HOST_BACKUP", CONF_PRE_HOST_BACKUP },
939 { "PRE_RECOVER", CONF_PRE_RECOVER },
940 { "POST_RECOVER", CONF_POST_RECOVER },
941 { "PRE_LEVEL_RECOVER", CONF_PRE_LEVEL_RECOVER },
942 { "POST_LEVEL_RECOVER", CONF_POST_LEVEL_RECOVER },
943 { "INTER_LEVEL_RECOVER", CONF_INTER_LEVEL_RECOVER },
944 { "PRINTER", CONF_PRINTER },
945 { "PRIORITY", CONF_PRIORITY },
946 { "PROGRAM", CONF_PROGRAM },
947 { "PROPERTY", CONF_PROPERTY },
948 { "RECORD", CONF_RECORD },
949 { "REP_TRIES", CONF_REP_TRIES },
950 { "REQ_TRIES", CONF_REQ_TRIES },
951 { "REQUIRED", CONF_REQUIRED },
952 { "RESERVE", CONF_RESERVE },
953 { "RESERVED_UDP_PORT", CONF_RESERVED_UDP_PORT },
954 { "RESERVED_TCP_PORT", CONF_RESERVED_TCP_PORT },
955 { "RUNSPERCYCLE", CONF_RUNSPERCYCLE },
956 { "RUNTAPES", CONF_RUNTAPES },
957 { "SCRIPT", CONF_SCRIPT },
958 { "SCRIPT_TOOL", CONF_SCRIPT_TOOL },
959 { "SEND_AMREPORT_ON", CONF_SEND_AMREPORT_ON },
960 { "CLIENT_PORT", CONF_CLIENT_PORT },
961 { "SERVER", CONF_SERVER },
962 { "SERVER_CUSTOM_COMPRESS", CONF_SRVCOMPPROG },
963 { "SERVER_DECRYPT_OPTION", CONF_SRV_DECRYPT_OPT },
964 { "SERVER_ENCRYPT", CONF_SRV_ENCRYPT },
965 { "SKIP", CONF_SKIP },
966 { "SKIP_FULL", CONF_SKIP_FULL },
967 { "SKIP_INCR", CONF_SKIP_INCR },
968 { "SMALLEST", CONF_SMALLEST },
969 { "SPEED", CONF_SPEED },
970 { "SPLIT_DISKBUFFER", CONF_SPLIT_DISKBUFFER },
971 { "SSH_KEYS", CONF_SSH_KEYS },
972 { "STANDARD", CONF_STANDARD },
973 { "STARTTIME", CONF_STARTTIME },
974 { "STRANGE", CONF_STRANGE },
975 { "STRATEGY", CONF_STRATEGY },
976 { "TAPEBUFS", CONF_TAPEBUFS },
977 { "DEVICE_OUTPUT_BUFFER_SIZE", CONF_DEVICE_OUTPUT_BUFFER_SIZE },
978 { "TAPECYCLE", CONF_TAPECYCLE },
979 { "TAPEDEV", CONF_TAPEDEV },
980 { "TAPELIST", CONF_TAPELIST },
981 { "TAPERALGO", CONF_TAPERALGO },
982 { "FLUSH_THRESHOLD_DUMPED", CONF_FLUSH_THRESHOLD_DUMPED },
983 { "FLUSH_THRESHOLD_SCHEDULED", CONF_FLUSH_THRESHOLD_SCHEDULED },
984 { "TAPERFLUSH", CONF_TAPERFLUSH },
985 { "TAPETYPE", CONF_TAPETYPE },
986 { "TAPE_SPLITSIZE", CONF_TAPE_SPLITSIZE },
987 { "TPCHANGER", CONF_TPCHANGER },
988 { "UNRESERVED_TCP_PORT", CONF_UNRESERVED_TCP_PORT },
990 { "USETIMESTAMPS", CONF_USETIMESTAMPS },
991 { "VOLUME_ERROR", CONF_VOLUME_ERROR },
992 { NULL, CONF_IDENT },
993 { NULL, CONF_UNKNOWN }
996 /* A keyword table for recognizing unit suffixes. No distinction is made for kinds
997 * of suffixes: 1024 weeks = 7 k. */
998 keytab_t numb_keytable[] = {
1000 { "BPS", CONF_MULT1 },
1001 { "BYTE", CONF_MULT1 },
1002 { "BYTES", CONF_MULT1 },
1003 { "DAY", CONF_MULT1 },
1004 { "DAYS", CONF_MULT1 },
1005 { "INF", CONF_AMINFINITY },
1006 { "K", CONF_MULT1K },
1007 { "KB", CONF_MULT1K },
1008 { "KBPS", CONF_MULT1K },
1009 { "KBYTE", CONF_MULT1K },
1010 { "KBYTES", CONF_MULT1K },
1011 { "KILOBYTE", CONF_MULT1K },
1012 { "KILOBYTES", CONF_MULT1K },
1013 { "KPS", CONF_MULT1K },
1014 { "M", CONF_MULT1M },
1015 { "MB", CONF_MULT1M },
1016 { "MBPS", CONF_MULT1M },
1017 { "MBYTE", CONF_MULT1M },
1018 { "MBYTES", CONF_MULT1M },
1019 { "MEG", CONF_MULT1M },
1020 { "MEGABYTE", CONF_MULT1M },
1021 { "MEGABYTES", CONF_MULT1M },
1022 { "G", CONF_MULT1G },
1023 { "GB", CONF_MULT1G },
1024 { "GBPS", CONF_MULT1G },
1025 { "GBYTE", CONF_MULT1G },
1026 { "GBYTES", CONF_MULT1G },
1027 { "GIG", CONF_MULT1G },
1028 { "GIGABYTE", CONF_MULT1G },
1029 { "GIGABYTES", CONF_MULT1G },
1030 { "T", CONF_MULT1T },
1031 { "TB", CONF_MULT1T },
1032 { "TBPS", CONF_MULT1T },
1033 { "TBYTE", CONF_MULT1T },
1034 { "TBYTES", CONF_MULT1T },
1035 { "TERA", CONF_MULT1T },
1036 { "TERABYTE", CONF_MULT1T },
1037 { "TERABYTES", CONF_MULT1T },
1038 { "MPS", CONF_MULT1M },
1039 { "TAPE", CONF_MULT1 },
1040 { "TAPES", CONF_MULT1 },
1041 { "WEEK", CONF_MULT7 },
1042 { "WEEKS", CONF_MULT7 },
1043 { NULL, CONF_IDENT }
1046 /* Boolean keywords -- all the ways to say "true" and "false" in amanda.conf */
1047 keytab_t bool_keytable[] = {
1048 { "Y", CONF_ATRUE },
1049 { "YES", CONF_ATRUE },
1050 { "T", CONF_ATRUE },
1051 { "TRUE", CONF_ATRUE },
1052 { "ON", CONF_ATRUE },
1053 { "N", CONF_AFALSE },
1054 { "NO", CONF_AFALSE },
1055 { "F", CONF_AFALSE },
1056 { "FALSE", CONF_AFALSE },
1057 { "OFF", CONF_AFALSE },
1058 { NULL, CONF_IDENT }
1061 /* Now, the parser tables for client and server global parameters, and for
1062 * each of the server subsections */
1063 conf_var_t client_var [] = {
1064 { CONF_CONF , CONFTYPE_STR , read_str , CNF_CONF , NULL },
1065 { CONF_INDEX_SERVER , CONFTYPE_STR , read_str , CNF_INDEX_SERVER , NULL },
1066 { CONF_TAPE_SERVER , CONFTYPE_STR , read_str , CNF_TAPE_SERVER , NULL },
1067 { CONF_TAPEDEV , CONFTYPE_STR , read_str , CNF_TAPEDEV , NULL },
1068 { CONF_AUTH , CONFTYPE_STR , read_str , CNF_AUTH , NULL },
1069 { CONF_SSH_KEYS , CONFTYPE_STR , read_str , CNF_SSH_KEYS , NULL },
1070 { CONF_AMANDAD_PATH , CONFTYPE_STR , read_str , CNF_AMANDAD_PATH , NULL },
1071 { CONF_CLIENT_USERNAME , CONFTYPE_STR , read_str , CNF_CLIENT_USERNAME , NULL },
1072 { CONF_CLIENT_PORT , CONFTYPE_STR , read_int_or_str, CNF_CLIENT_PORT , NULL },
1073 { CONF_GNUTAR_LIST_DIR , CONFTYPE_STR , read_str , CNF_GNUTAR_LIST_DIR , NULL },
1074 { CONF_AMANDATES , CONFTYPE_STR , read_str , CNF_AMANDATES , NULL },
1075 { CONF_MAILER , CONFTYPE_STR , read_str , CNF_MAILER , NULL },
1076 { CONF_KRB5KEYTAB , CONFTYPE_STR , read_str , CNF_KRB5KEYTAB , NULL },
1077 { CONF_KRB5PRINCIPAL , CONFTYPE_STR , read_str , CNF_KRB5PRINCIPAL , NULL },
1078 { CONF_CONNECT_TRIES , CONFTYPE_INT , read_int , CNF_CONNECT_TRIES , validate_positive },
1079 { CONF_REP_TRIES , CONFTYPE_INT , read_int , CNF_REP_TRIES , validate_positive },
1080 { CONF_REQ_TRIES , CONFTYPE_INT , read_int , CNF_REQ_TRIES , validate_positive },
1081 { CONF_DEBUG_DAYS , CONFTYPE_INT , read_int , CNF_DEBUG_DAYS , NULL },
1082 { CONF_DEBUG_AMANDAD , CONFTYPE_INT , read_int , CNF_DEBUG_AMANDAD , validate_debug },
1083 { CONF_DEBUG_RECOVERY , CONFTYPE_INT , read_int , CNF_DEBUG_RECOVERY , validate_debug },
1084 { CONF_DEBUG_AMIDXTAPED , CONFTYPE_INT , read_int , CNF_DEBUG_AMIDXTAPED , validate_debug },
1085 { CONF_DEBUG_AMINDEXD , CONFTYPE_INT , read_int , CNF_DEBUG_AMINDEXD , validate_debug },
1086 { CONF_DEBUG_AMRECOVER , CONFTYPE_INT , read_int , CNF_DEBUG_AMRECOVER , validate_debug },
1087 { CONF_DEBUG_AUTH , CONFTYPE_INT , read_int , CNF_DEBUG_AUTH , validate_debug },
1088 { CONF_DEBUG_EVENT , CONFTYPE_INT , read_int , CNF_DEBUG_EVENT , validate_debug },
1089 { CONF_DEBUG_HOLDING , CONFTYPE_INT , read_int , CNF_DEBUG_HOLDING , validate_debug },
1090 { CONF_DEBUG_PROTOCOL , CONFTYPE_INT , read_int , CNF_DEBUG_PROTOCOL , validate_debug },
1091 { CONF_DEBUG_PLANNER , CONFTYPE_INT , read_int , CNF_DEBUG_PLANNER , validate_debug },
1092 { CONF_DEBUG_DRIVER , CONFTYPE_INT , read_int , CNF_DEBUG_DRIVER , validate_debug },
1093 { CONF_DEBUG_DUMPER , CONFTYPE_INT , read_int , CNF_DEBUG_DUMPER , validate_debug },
1094 { CONF_DEBUG_CHUNKER , CONFTYPE_INT , read_int , CNF_DEBUG_CHUNKER , validate_debug },
1095 { CONF_DEBUG_TAPER , CONFTYPE_INT , read_int , CNF_DEBUG_TAPER , validate_debug },
1096 { CONF_DEBUG_SELFCHECK , CONFTYPE_INT , read_int , CNF_DEBUG_SELFCHECK , validate_debug },
1097 { CONF_DEBUG_SENDSIZE , CONFTYPE_INT , read_int , CNF_DEBUG_SENDSIZE , validate_debug },
1098 { CONF_DEBUG_SENDBACKUP , CONFTYPE_INT , read_int , CNF_DEBUG_SENDBACKUP , validate_debug },
1099 { CONF_RESERVED_UDP_PORT , CONFTYPE_INTRANGE, read_intrange, CNF_RESERVED_UDP_PORT , validate_reserved_port_range },
1100 { CONF_RESERVED_TCP_PORT , CONFTYPE_INTRANGE, read_intrange, CNF_RESERVED_TCP_PORT , validate_reserved_port_range },
1101 { CONF_UNRESERVED_TCP_PORT, CONFTYPE_INTRANGE, read_intrange, CNF_UNRESERVED_TCP_PORT, validate_unreserved_port_range },
1102 { CONF_PROPERTY , CONFTYPE_PROPLIST, read_property, CNF_PROPERTY , NULL },
1103 { CONF_APPLICATION , CONFTYPE_STR , read_dapplication, DUMPTYPE_APPLICATION, NULL },
1104 { CONF_SCRIPT , CONFTYPE_STR , read_dpp_script, DUMPTYPE_SCRIPTLIST, NULL },
1105 { CONF_UNKNOWN , CONFTYPE_INT , NULL , CNF_CNF , NULL }
1108 conf_var_t server_var [] = {
1109 { CONF_ORG , CONFTYPE_STR , read_str , CNF_ORG , NULL },
1110 { CONF_MAILTO , CONFTYPE_STR , read_str , CNF_MAILTO , NULL },
1111 { CONF_DUMPUSER , CONFTYPE_STR , read_str , CNF_DUMPUSER , NULL },
1112 { CONF_PRINTER , CONFTYPE_STR , read_str , CNF_PRINTER , NULL },
1113 { CONF_MAILER , CONFTYPE_STR , read_str , CNF_MAILER , NULL },
1114 { CONF_TAPEDEV , CONFTYPE_STR , read_str , CNF_TAPEDEV , NULL },
1115 { CONF_DEVICE_PROPERTY , CONFTYPE_PROPLIST , read_property , CNF_DEVICE_PROPERTY , NULL },
1116 { CONF_PROPERTY , CONFTYPE_PROPLIST , read_property , CNF_PROPERTY , NULL },
1117 { CONF_TPCHANGER , CONFTYPE_STR , read_str , CNF_TPCHANGER , NULL },
1118 { CONF_CHANGERDEV , CONFTYPE_STR , read_str , CNF_CHANGERDEV , NULL },
1119 { CONF_CHANGERFILE , CONFTYPE_STR , read_str , CNF_CHANGERFILE , NULL },
1120 { CONF_LABELSTR , CONFTYPE_STR , read_str , CNF_LABELSTR , NULL },
1121 { CONF_TAPELIST , CONFTYPE_STR , read_str , CNF_TAPELIST , NULL },
1122 { CONF_DISKFILE , CONFTYPE_STR , read_str , CNF_DISKFILE , NULL },
1123 { CONF_INFOFILE , CONFTYPE_STR , read_str , CNF_INFOFILE , NULL },
1124 { CONF_LOGDIR , CONFTYPE_STR , read_str , CNF_LOGDIR , NULL },
1125 { CONF_INDEXDIR , CONFTYPE_STR , read_str , CNF_INDEXDIR , NULL },
1126 { CONF_TAPETYPE , CONFTYPE_IDENT , read_ident , CNF_TAPETYPE , NULL },
1127 { CONF_HOLDING , CONFTYPE_IDENTLIST, read_holdingdisk , CNF_HOLDINGDISK , NULL },
1128 { CONF_DUMPCYCLE , CONFTYPE_INT , read_int , CNF_DUMPCYCLE , validate_nonnegative },
1129 { CONF_RUNSPERCYCLE , CONFTYPE_INT , read_int , CNF_RUNSPERCYCLE , validate_runspercycle },
1130 { CONF_RUNTAPES , CONFTYPE_INT , read_int , CNF_RUNTAPES , validate_nonnegative },
1131 { CONF_TAPECYCLE , CONFTYPE_INT , read_int , CNF_TAPECYCLE , validate_positive },
1132 { CONF_BUMPDAYS , CONFTYPE_INT , read_int , CNF_BUMPDAYS , validate_positive },
1133 { CONF_BUMPSIZE , CONFTYPE_INT64 , read_int64 , CNF_BUMPSIZE , validate_positive },
1134 { CONF_BUMPPERCENT , CONFTYPE_INT , read_int , CNF_BUMPPERCENT , validate_bumppercent },
1135 { CONF_BUMPMULT , CONFTYPE_REAL , read_real , CNF_BUMPMULT , validate_bumpmult },
1136 { CONF_NETUSAGE , CONFTYPE_INT , read_int , CNF_NETUSAGE , validate_positive },
1137 { CONF_INPARALLEL , CONFTYPE_INT , read_int , CNF_INPARALLEL , validate_inparallel },
1138 { CONF_DUMPORDER , CONFTYPE_STR , read_str , CNF_DUMPORDER , NULL },
1139 { CONF_MAXDUMPS , CONFTYPE_INT , read_int , CNF_MAXDUMPS , validate_positive },
1140 { CONF_ETIMEOUT , CONFTYPE_INT , read_int , CNF_ETIMEOUT , validate_positive },
1141 { CONF_DTIMEOUT , CONFTYPE_INT , read_int , CNF_DTIMEOUT , validate_positive },
1142 { CONF_CTIMEOUT , CONFTYPE_INT , read_int , CNF_CTIMEOUT , validate_positive },
1143 { CONF_TAPEBUFS , CONFTYPE_INT , read_int , CNF_TAPEBUFS , validate_positive },
1144 { CONF_DEVICE_OUTPUT_BUFFER_SIZE, CONFTYPE_SIZE , read_size , CNF_DEVICE_OUTPUT_BUFFER_SIZE, validate_positive },
1145 { CONF_COLUMNSPEC , CONFTYPE_STR , read_str , CNF_COLUMNSPEC , NULL },
1146 { CONF_TAPERALGO , CONFTYPE_TAPERALGO, read_taperalgo , CNF_TAPERALGO , NULL },
1147 { CONF_SEND_AMREPORT_ON , CONFTYPE_SEND_AMREPORT_ON, read_send_amreport_on, CNF_SEND_AMREPORT_ON , NULL },
1148 { CONF_FLUSH_THRESHOLD_DUMPED, CONFTYPE_INT , read_int , CNF_FLUSH_THRESHOLD_DUMPED, validate_nonnegative },
1149 { CONF_FLUSH_THRESHOLD_SCHEDULED, CONFTYPE_INT , read_int , CNF_FLUSH_THRESHOLD_SCHEDULED, validate_nonnegative },
1150 { CONF_TAPERFLUSH , CONFTYPE_INT , read_int , CNF_TAPERFLUSH , validate_nonnegative },
1151 { CONF_DISPLAYUNIT , CONFTYPE_STR , read_str , CNF_DISPLAYUNIT , validate_displayunit },
1152 { CONF_AUTOFLUSH , CONFTYPE_BOOLEAN , read_bool , CNF_AUTOFLUSH , NULL },
1153 { CONF_RESERVE , CONFTYPE_INT , read_int , CNF_RESERVE , validate_reserve },
1154 { CONF_MAXDUMPSIZE , CONFTYPE_INT64 , read_int64 , CNF_MAXDUMPSIZE , NULL },
1155 { CONF_KRB5KEYTAB , CONFTYPE_STR , read_str , CNF_KRB5KEYTAB , NULL },
1156 { CONF_KRB5PRINCIPAL , CONFTYPE_STR , read_str , CNF_KRB5PRINCIPAL , NULL },
1157 { CONF_LABEL_NEW_TAPES , CONFTYPE_STR , read_str , CNF_LABEL_NEW_TAPES , NULL },
1158 { CONF_AUTOLABEL , CONFTYPE_AUTOLABEL, read_autolabel , CNF_AUTOLABEL , NULL },
1159 { CONF_USETIMESTAMPS , CONFTYPE_BOOLEAN , read_bool , CNF_USETIMESTAMPS , NULL },
1160 { CONF_AMRECOVER_DO_FSF , CONFTYPE_BOOLEAN , read_bool , CNF_AMRECOVER_DO_FSF , NULL },
1161 { CONF_AMRECOVER_CHANGER , CONFTYPE_STR , read_str , CNF_AMRECOVER_CHANGER , NULL },
1162 { CONF_AMRECOVER_CHECK_LABEL, CONFTYPE_BOOLEAN , read_bool , CNF_AMRECOVER_CHECK_LABEL, NULL },
1163 { CONF_CONNECT_TRIES , CONFTYPE_INT , read_int , CNF_CONNECT_TRIES , validate_positive },
1164 { CONF_REP_TRIES , CONFTYPE_INT , read_int , CNF_REP_TRIES , validate_positive },
1165 { CONF_REQ_TRIES , CONFTYPE_INT , read_int , CNF_REQ_TRIES , validate_positive },
1166 { CONF_DEBUG_DAYS , CONFTYPE_INT , read_int , CNF_DEBUG_DAYS , NULL },
1167 { CONF_DEBUG_AMANDAD , CONFTYPE_INT , read_int , CNF_DEBUG_AMANDAD , validate_debug },
1168 { CONF_DEBUG_RECOVERY , CONFTYPE_INT , read_int , CNF_DEBUG_RECOVERY , validate_debug },
1169 { CONF_DEBUG_AMIDXTAPED , CONFTYPE_INT , read_int , CNF_DEBUG_AMIDXTAPED , validate_debug },
1170 { CONF_DEBUG_AMINDEXD , CONFTYPE_INT , read_int , CNF_DEBUG_AMINDEXD , validate_debug },
1171 { CONF_DEBUG_AMRECOVER , CONFTYPE_INT , read_int , CNF_DEBUG_AMRECOVER , validate_debug },
1172 { CONF_DEBUG_AUTH , CONFTYPE_INT , read_int , CNF_DEBUG_AUTH , validate_debug },
1173 { CONF_DEBUG_EVENT , CONFTYPE_INT , read_int , CNF_DEBUG_EVENT , validate_debug },
1174 { CONF_DEBUG_HOLDING , CONFTYPE_INT , read_int , CNF_DEBUG_HOLDING , validate_debug },
1175 { CONF_DEBUG_PROTOCOL , CONFTYPE_INT , read_int , CNF_DEBUG_PROTOCOL , validate_debug },
1176 { CONF_DEBUG_PLANNER , CONFTYPE_INT , read_int , CNF_DEBUG_PLANNER , validate_debug },
1177 { CONF_DEBUG_DRIVER , CONFTYPE_INT , read_int , CNF_DEBUG_DRIVER , validate_debug },
1178 { CONF_DEBUG_DUMPER , CONFTYPE_INT , read_int , CNF_DEBUG_DUMPER , validate_debug },
1179 { CONF_DEBUG_CHUNKER , CONFTYPE_INT , read_int , CNF_DEBUG_CHUNKER , validate_debug },
1180 { CONF_DEBUG_TAPER , CONFTYPE_INT , read_int , CNF_DEBUG_TAPER , validate_debug },
1181 { CONF_DEBUG_SELFCHECK , CONFTYPE_INT , read_int , CNF_DEBUG_SELFCHECK , validate_debug },
1182 { CONF_DEBUG_SENDSIZE , CONFTYPE_INT , read_int , CNF_DEBUG_SENDSIZE , validate_debug },
1183 { CONF_DEBUG_SENDBACKUP , CONFTYPE_INT , read_int , CNF_DEBUG_SENDBACKUP , validate_debug },
1184 { CONF_RESERVED_UDP_PORT , CONFTYPE_INTRANGE , read_intrange , CNF_RESERVED_UDP_PORT , validate_reserved_port_range },
1185 { CONF_RESERVED_TCP_PORT , CONFTYPE_INTRANGE , read_intrange , CNF_RESERVED_TCP_PORT , validate_reserved_port_range },
1186 { CONF_UNRESERVED_TCP_PORT , CONFTYPE_INTRANGE , read_intrange , CNF_UNRESERVED_TCP_PORT , validate_unreserved_port_range },
1187 { CONF_UNKNOWN , CONFTYPE_INT , NULL , CNF_CNF , NULL }
1190 conf_var_t tapetype_var [] = {
1191 { CONF_COMMENT , CONFTYPE_STR , read_str , TAPETYPE_COMMENT , NULL },
1192 { CONF_LBL_TEMPL , CONFTYPE_STR , read_str , TAPETYPE_LBL_TEMPL , NULL },
1193 { CONF_BLOCKSIZE , CONFTYPE_SIZE , read_size , TAPETYPE_BLOCKSIZE , validate_blocksize },
1194 { CONF_READBLOCKSIZE , CONFTYPE_SIZE , read_size , TAPETYPE_READBLOCKSIZE, validate_blocksize },
1195 { CONF_LENGTH , CONFTYPE_INT64 , read_int64 , TAPETYPE_LENGTH , validate_nonnegative },
1196 { CONF_FILEMARK , CONFTYPE_INT64 , read_int64 , TAPETYPE_FILEMARK , NULL },
1197 { CONF_SPEED , CONFTYPE_INT , read_int , TAPETYPE_SPEED , validate_nonnegative },
1198 { CONF_FILE_PAD , CONFTYPE_BOOLEAN , read_bool , TAPETYPE_FILE_PAD , NULL },
1199 { CONF_UNKNOWN , CONFTYPE_INT , NULL , TAPETYPE_TAPETYPE , NULL }
1202 conf_var_t dumptype_var [] = {
1203 { CONF_COMMENT , CONFTYPE_STR , read_str , DUMPTYPE_COMMENT , NULL },
1204 { CONF_AUTH , CONFTYPE_STR , read_str , DUMPTYPE_AUTH , NULL },
1205 { CONF_BUMPDAYS , CONFTYPE_INT , read_int , DUMPTYPE_BUMPDAYS , NULL },
1206 { CONF_BUMPMULT , CONFTYPE_REAL , read_real , DUMPTYPE_BUMPMULT , NULL },
1207 { CONF_BUMPSIZE , CONFTYPE_INT64 , read_int64 , DUMPTYPE_BUMPSIZE , NULL },
1208 { CONF_BUMPPERCENT , CONFTYPE_INT , read_int , DUMPTYPE_BUMPPERCENT , NULL },
1209 { CONF_COMPRATE , CONFTYPE_REAL , read_rate , DUMPTYPE_COMPRATE , NULL },
1210 { CONF_COMPRESS , CONFTYPE_INT , read_compress , DUMPTYPE_COMPRESS , NULL },
1211 { CONF_ENCRYPT , CONFTYPE_INT , read_encrypt , DUMPTYPE_ENCRYPT , NULL },
1212 { CONF_DUMPCYCLE , CONFTYPE_INT , read_int , DUMPTYPE_DUMPCYCLE , validate_nonnegative },
1213 { CONF_EXCLUDE , CONFTYPE_EXINCLUDE, read_exinclude, DUMPTYPE_EXCLUDE , NULL },
1214 { CONF_INCLUDE , CONFTYPE_EXINCLUDE, read_exinclude, DUMPTYPE_INCLUDE , NULL },
1215 { CONF_IGNORE , CONFTYPE_BOOLEAN , read_bool , DUMPTYPE_IGNORE , NULL },
1216 { CONF_HOLDING , CONFTYPE_HOLDING , read_holding , DUMPTYPE_HOLDINGDISK , NULL },
1217 { CONF_INDEX , CONFTYPE_BOOLEAN , read_bool , DUMPTYPE_INDEX , NULL },
1218 { CONF_KENCRYPT , CONFTYPE_BOOLEAN , read_bool , DUMPTYPE_KENCRYPT , NULL },
1219 { CONF_MAXDUMPS , CONFTYPE_INT , read_int , DUMPTYPE_MAXDUMPS , validate_positive },
1220 { CONF_MAXPROMOTEDAY , CONFTYPE_INT , read_int , DUMPTYPE_MAXPROMOTEDAY , validate_nonnegative },
1221 { CONF_PRIORITY , CONFTYPE_PRIORITY , read_priority , DUMPTYPE_PRIORITY , NULL },
1222 { CONF_PROGRAM , CONFTYPE_STR , read_str , DUMPTYPE_PROGRAM , validate_program },
1223 { CONF_PROPERTY , CONFTYPE_PROPLIST , read_property , DUMPTYPE_PROPERTY , NULL },
1224 { CONF_RECORD , CONFTYPE_BOOLEAN , read_bool , DUMPTYPE_RECORD , NULL },
1225 { CONF_SKIP_FULL , CONFTYPE_BOOLEAN , read_bool , DUMPTYPE_SKIP_FULL , NULL },
1226 { CONF_SKIP_INCR , CONFTYPE_BOOLEAN , read_bool , DUMPTYPE_SKIP_INCR , NULL },
1227 { CONF_STARTTIME , CONFTYPE_TIME , read_time , DUMPTYPE_STARTTIME , NULL },
1228 { CONF_STRATEGY , CONFTYPE_INT , read_strategy , DUMPTYPE_STRATEGY , NULL },
1229 { CONF_TAPE_SPLITSIZE , CONFTYPE_INT64 , read_int64 , DUMPTYPE_TAPE_SPLITSIZE , validate_nonnegative },
1230 { CONF_SPLIT_DISKBUFFER , CONFTYPE_STR , read_str , DUMPTYPE_SPLIT_DISKBUFFER , NULL },
1231 { CONF_ESTIMATE , CONFTYPE_ESTIMATELIST, read_estimatelist , DUMPTYPE_ESTIMATELIST , NULL },
1232 { CONF_SRV_ENCRYPT , CONFTYPE_STR , read_str , DUMPTYPE_SRV_ENCRYPT , NULL },
1233 { CONF_CLNT_ENCRYPT , CONFTYPE_STR , read_str , DUMPTYPE_CLNT_ENCRYPT , NULL },
1234 { CONF_AMANDAD_PATH , CONFTYPE_STR , read_str , DUMPTYPE_AMANDAD_PATH , NULL },
1235 { CONF_CLIENT_USERNAME , CONFTYPE_STR , read_str , DUMPTYPE_CLIENT_USERNAME , NULL },
1236 { CONF_CLIENT_PORT , CONFTYPE_STR , read_int_or_str, DUMPTYPE_CLIENT_PORT , NULL },
1237 { CONF_SSH_KEYS , CONFTYPE_STR , read_str , DUMPTYPE_SSH_KEYS , NULL },
1238 { CONF_SRVCOMPPROG , CONFTYPE_STR , read_str , DUMPTYPE_SRVCOMPPROG , NULL },
1239 { CONF_CLNTCOMPPROG , CONFTYPE_STR , read_str , DUMPTYPE_CLNTCOMPPROG , NULL },
1240 { CONF_FALLBACK_SPLITSIZE, CONFTYPE_INT64 , read_int64 , DUMPTYPE_FALLBACK_SPLITSIZE, NULL },
1241 { CONF_SRV_DECRYPT_OPT , CONFTYPE_STR , read_str , DUMPTYPE_SRV_DECRYPT_OPT , NULL },
1242 { CONF_CLNT_DECRYPT_OPT , CONFTYPE_STR , read_str , DUMPTYPE_CLNT_DECRYPT_OPT , NULL },
1243 { CONF_APPLICATION , CONFTYPE_STR , read_dapplication, DUMPTYPE_APPLICATION , NULL },
1244 { CONF_SCRIPT , CONFTYPE_STR , read_dpp_script, DUMPTYPE_SCRIPTLIST , NULL },
1245 { CONF_DATA_PATH , CONFTYPE_DATA_PATH, read_data_path, DUMPTYPE_DATA_PATH , NULL },
1246 { CONF_UNKNOWN , CONFTYPE_INT , NULL , DUMPTYPE_DUMPTYPE , NULL }
1249 conf_var_t holding_var [] = {
1250 { CONF_DIRECTORY, CONFTYPE_STR , read_str , HOLDING_DISKDIR , NULL },
1251 { CONF_COMMENT , CONFTYPE_STR , read_str , HOLDING_COMMENT , NULL },
1252 { CONF_USE , CONFTYPE_INT64 , read_int64 , HOLDING_DISKSIZE , validate_use },
1253 { CONF_CHUNKSIZE, CONFTYPE_INT64 , read_int64 , HOLDING_CHUNKSIZE, validate_chunksize },
1254 { CONF_UNKNOWN , CONFTYPE_INT , NULL , HOLDING_HOLDING , NULL }
1257 conf_var_t interface_var [] = {
1258 { CONF_COMMENT, CONFTYPE_STR , read_str , INTER_COMMENT , NULL },
1259 { CONF_USE , CONFTYPE_INT , read_int , INTER_MAXUSAGE, validate_positive },
1260 { CONF_UNKNOWN, CONFTYPE_INT , NULL , INTER_INTER , NULL }
1264 conf_var_t application_var [] = {
1265 { CONF_COMMENT , CONFTYPE_STR , read_str , APPLICATION_COMMENT , NULL },
1266 { CONF_PLUGIN , CONFTYPE_STR , read_str , APPLICATION_PLUGIN , NULL },
1267 { CONF_PROPERTY , CONFTYPE_PROPLIST, read_property, APPLICATION_PROPERTY , NULL },
1268 { CONF_UNKNOWN , CONFTYPE_INT , NULL , APPLICATION_APPLICATION, NULL }
1271 conf_var_t pp_script_var [] = {
1272 { CONF_COMMENT , CONFTYPE_STR , read_str , PP_SCRIPT_COMMENT , NULL },
1273 { CONF_PLUGIN , CONFTYPE_STR , read_str , PP_SCRIPT_PLUGIN , NULL },
1274 { CONF_PROPERTY , CONFTYPE_PROPLIST, read_property, PP_SCRIPT_PROPERTY , NULL },
1275 { CONF_EXECUTE_ON , CONFTYPE_EXECUTE_ON , read_execute_on , PP_SCRIPT_EXECUTE_ON , NULL },
1276 { CONF_EXECUTE_WHERE, CONFTYPE_EXECUTE_WHERE , read_execute_where , PP_SCRIPT_EXECUTE_WHERE, NULL },
1277 { CONF_ORDER , CONFTYPE_INT , read_int , PP_SCRIPT_ORDER , NULL },
1278 { CONF_UNKNOWN , CONFTYPE_INT , NULL , PP_SCRIPT_PP_SCRIPT , NULL }
1281 conf_var_t device_config_var [] = {
1282 { CONF_COMMENT , CONFTYPE_STR , read_str , DEVICE_CONFIG_COMMENT , NULL },
1283 { CONF_DEVICE_PROPERTY , CONFTYPE_PROPLIST , read_property , DEVICE_CONFIG_DEVICE_PROPERTY, NULL },
1284 { CONF_TAPEDEV , CONFTYPE_STR , read_str , DEVICE_CONFIG_TAPEDEV , NULL },
1285 { CONF_UNKNOWN , CONFTYPE_INT , NULL , DEVICE_CONFIG_DEVICE_CONFIG , NULL }
1288 conf_var_t changer_config_var [] = {
1289 { CONF_COMMENT , CONFTYPE_STR , read_str , CHANGER_CONFIG_COMMENT , NULL },
1290 { CONF_TAPEDEV , CONFTYPE_STR , read_str , CHANGER_CONFIG_TAPEDEV , NULL },
1291 { CONF_TPCHANGER , CONFTYPE_STR , read_str , CHANGER_CONFIG_TPCHANGER , NULL },
1292 { CONF_CHANGERDEV , CONFTYPE_STR , read_str , CHANGER_CONFIG_CHANGERDEV , NULL },
1293 { CONF_CHANGERFILE , CONFTYPE_STR , read_str , CHANGER_CONFIG_CHANGERFILE , NULL },
1294 { CONF_PROPERTY , CONFTYPE_PROPLIST , read_property , CHANGER_CONFIG_PROPERTY , NULL },
1295 { CONF_DEVICE_PROPERTY , CONFTYPE_PROPLIST , read_property , CHANGER_CONFIG_DEVICE_PROPERTY, NULL },
1296 { CONF_UNKNOWN , CONFTYPE_INT , NULL , CHANGER_CONFIG_CHANGER_CONFIG , NULL }
1300 * Lexical Analysis Implementation
1309 if (keytable == NULL) {
1310 error(_("keytable == NULL"));
1314 for(kt = keytable; kt->token != CONF_UNKNOWN; kt++)
1315 if(kt->token == token) break;
1317 if(kt->token == CONF_UNKNOWN)
1319 return(kt->keyword);
1327 char *str1 = stralloc(str);
1330 /* Fold '-' to '_' in the token. Note that this modifies str1
1333 if (*p == '-') *p = '_';
1337 for(kwp = keytable; kwp->keyword != NULL; kwp++) {
1338 if (strcasecmp(kwp->keyword, str1) == 0) break;
1363 ** If it looked like a keyword before then look it
1364 ** up again in the current keyword table.
1367 case CONF_INT64: case CONF_SIZE:
1368 case CONF_INT: case CONF_REAL: case CONF_STRING:
1369 case CONF_LBRACE: case CONF_RBRACE: case CONF_COMMA:
1370 case CONF_NL: case CONF_END: case CONF_UNKNOWN:
1372 break; /* not a keyword */
1375 if (exp == CONF_IDENT)
1378 tok = lookup_keyword(tokenval.v.s);
1383 ch = conftoken_getc();
1385 /* note that we're explicitly assuming this file is ASCII. Someday
1386 * maybe we'll support UTF-8? */
1387 while(ch != EOF && ch != '\n' && g_ascii_isspace(ch))
1388 ch = conftoken_getc();
1389 if (ch == '#') { /* comment - eat everything but eol/eof */
1390 while((ch = conftoken_getc()) != EOF && ch != '\n') {
1391 (void)ch; /* Quiet empty loop complaints */
1395 if (isalpha(ch)) { /* identifier */
1399 if (buf < tkbuf+sizeof(tkbuf)-1) {
1403 if (!token_overflow) {
1404 conf_parserror(_("token too long: %.20s..."), tkbuf);
1408 ch = conftoken_getc();
1409 } while(isalnum(ch) || ch == '_' || ch == '-');
1411 if (ch != EOF && conftoken_ungetc(ch) == EOF) {
1412 if (ferror(current_file)) {
1413 conf_parserror(_("Pushback of '%c' failed: %s"),
1414 ch, strerror(ferror(current_file)));
1416 conf_parserror(_("Pushback of '%c' failed: EOF"), ch);
1421 tokenval.v.s = tkbuf;
1423 if (token_overflow) tok = CONF_UNKNOWN;
1424 else if (exp == CONF_IDENT) tok = CONF_IDENT;
1425 else tok = lookup_keyword(tokenval.v.s);
1427 else if (isdigit(ch)) { /* integer */
1430 negative_number: /* look for goto negative_number below sign is set there */
1433 int64 = int64 * 10 + (ch - '0');
1434 ch = conftoken_getc();
1435 } while (isdigit(ch));
1438 if (exp == CONF_INT) {
1440 tokenval.v.i = sign * (int)int64;
1441 } else if (exp != CONF_REAL) {
1443 tokenval.v.int64 = (gint64)sign * int64;
1445 /* automatically convert to real when expected */
1446 tokenval.v.r = (double)sign * (double)int64;
1450 /* got a real number, not an int */
1451 tokenval.v.r = sign * (double) int64;
1454 ch = conftoken_getc();
1455 while (isdigit(ch)) {
1456 int64 = int64 * 10 + (ch - '0');
1458 ch = conftoken_getc();
1460 tokenval.v.r += sign * ((double)int64) / d;
1464 if (ch != EOF && conftoken_ungetc(ch) == EOF) {
1465 if (ferror(current_file)) {
1466 conf_parserror(_("Pushback of '%c' failed: %s"),
1467 ch, strerror(ferror(current_file)));
1469 conf_parserror(_("Pushback of '%c' failed: EOF"), ch);
1473 case '"': /* string */
1478 while (inquote && ((ch = conftoken_getc()) != EOF)) {
1483 buf--; /* Consume escape in buffer */
1484 } else if (ch == '\\' && !escape) {
1494 if(buf >= &tkbuf[sizeof(tkbuf) - 1]) {
1495 if (!token_overflow) {
1496 conf_parserror(_("string too long: %.20s..."), tkbuf);
1506 * A little manuver to leave a fully unquoted, unallocated string
1509 tmps = unquote_string(tkbuf);
1510 strncpy(tkbuf, tmps, sizeof(tkbuf));
1512 tokenval.v.s = tkbuf;
1514 tok = (token_overflow) ? CONF_UNKNOWN :
1515 (exp == CONF_IDENT) ? CONF_IDENT : CONF_STRING;
1519 ch = conftoken_getc();
1522 goto negative_number;
1525 if (ch != EOF && conftoken_ungetc(ch) == EOF) {
1526 if (ferror(current_file)) {
1527 conf_parserror(_("Pushback of '%c' failed: %s"),
1528 ch, strerror(ferror(current_file)));
1530 conf_parserror(_("Pushback of '%c' failed: EOF"), ch);
1563 if (exp != CONF_ANY && tok != exp) {
1581 str = _("end of line");
1585 str = _("end of file");
1589 str = _("an integer");
1593 str = _("a real number");
1597 str = _("a quoted string");
1601 str = _("an identifier");
1605 for(kwp = keytable; kwp->keyword != NULL; kwp++) {
1606 if (exp == kwp->token)
1609 if (kwp->keyword == NULL)
1610 str = _("token not");
1615 conf_parserror(_("%s is expected"), str);
1617 if (tok == CONF_INT)
1625 unget_conftoken(void)
1627 assert(!token_pushed);
1634 conftoken_getc(void)
1636 if(current_line == NULL)
1637 return getc(current_file);
1638 if(*current_char == '\0')
1640 return(*current_char++);
1647 if(current_line == NULL)
1648 return ungetc(c, current_file);
1649 else if(current_char > current_line) {
1653 if(*current_char != c) {
1654 error(_("*current_char != c : %c %c"), *current_char, c);
1658 error(_("current_char == current_line"));
1665 * Parser Implementation
1672 gboolean missing_ok)
1674 /* Save global locations. */
1675 FILE *save_file = current_file;
1676 char *save_filename = current_filename;
1677 int save_line_num = current_line_num;
1681 keytable = client_keytab;
1682 parsetable = client_var;
1684 keytable = server_keytab;
1685 parsetable = server_var;
1687 filename = config_dir_relative(filename);
1688 current_filename = get_seen_filename(filename);
1691 if ((current_file = fopen(current_filename, "r")) == NULL) {
1693 conf_parserror(_("could not open conf file \"%s\": %s"),
1694 current_filename, strerror(errno));
1698 current_line_num = 0;
1701 /* read_confline() can invoke us recursively via "includefile" */
1702 rc = read_confline(is_client);
1705 afclose(current_file);
1709 /* Restore servers */
1710 current_line_num = save_line_num;
1711 current_file = save_file;
1712 current_filename = save_filename;
1721 current_line_num += 1;
1722 get_conftoken(CONF_ANY);
1723 handle_deprecated_keyword();
1726 case CONF_INCLUDEFILE:
1727 get_conftoken(CONF_STRING);
1728 read_conffile(tokenval.v.s, is_client, FALSE);
1733 get_conftoken(CONF_ANY);
1734 /* accept application-tool here, too, for backward compatibility */
1735 if(tok == CONF_APPLICATION_TOOL || tok == CONF_APPLICATION) get_application();
1736 else if(tok == CONF_SCRIPT_TOOL || tok == CONF_SCRIPT) get_pp_script();
1737 else conf_parserror(_("APPLICATION-TOOL or SCRIPT-TOOL expected"));
1739 get_conftoken(CONF_ANY);
1740 if(tok == CONF_DUMPTYPE) get_dumptype();
1741 else if(tok == CONF_TAPETYPE) get_tapetype();
1742 else if(tok == CONF_INTERFACE) get_interface();
1743 else if(tok == CONF_APPLICATION_TOOL || tok == CONF_APPLICATION) get_application();
1744 else if(tok == CONF_SCRIPT_TOOL || tok == CONF_SCRIPT) get_pp_script();
1745 else if(tok == CONF_DEVICE) get_device_config();
1746 else if(tok == CONF_CHANGER) get_changer_config();
1747 else if(tok == CONF_HOLDING) get_holdingdisk(1);
1748 else conf_parserror(_("DUMPTYPE, INTERFACE, TAPETYPE, HOLDINGDISK, APPLICATION-TOOL, SCRIPT-TOOL, DEVICE, or CHANGER expected"));
1752 case CONF_NL: /* empty line */
1755 case CONF_END: /* end of file */
1758 /* if it's not a known punctuation mark, then check the parse table and use the
1759 * read_function we find there. */
1762 for(np = parsetable; np->token != CONF_UNKNOWN; np++)
1763 if(np->token == tok) break;
1765 if(np->token == CONF_UNKNOWN) {
1766 handle_invalid_keyword(tokenval.v.s);
1768 np->read_function(np, &conf_data[np->parm]);
1769 if(np->validate_function)
1770 np->validate_function(np, &conf_data[np->parm]);
1775 get_conftoken(CONF_NL);
1780 handle_deprecated_keyword(void)
1783 /* Procedure for deprecated keywords:
1784 * 1) At time of deprecation, add to warning_deprecated below.
1785 * Note the date of deprecation. The keyword will still be
1786 * parsed, and can still be used from other parts of Amanda,
1788 * 2) After two years, move the keyword (as a string) to
1789 * error_deprecated below. Remove the token (CONF_XXX) and
1790 * config parameter (CNF_XXX) from the rest of the module.
1791 * Note the date of the move.
1794 static tok_t warning_deprecated[] = {
1795 CONF_TAPEBUFS, /* 2007-10-15 */
1796 CONF_FILE_PAD, /* 2008-07-01 */
1797 CONF_LABEL_NEW_TAPES, /* 2010-02-05 */
1801 for (dep = warning_deprecated; *dep; dep++) {
1803 conf_parswarn(_("warning: Keyword %s is deprecated."),
1810 handle_invalid_keyword(
1813 static const char * error_deprecated[] = {
1819 for (s = error_deprecated; *s != NULL; s ++) {
1820 if (g_ascii_strcasecmp(*s, token) == 0) {
1821 conf_parserror(_("error: Keyword %s is deprecated."),
1827 conf_parserror(_("configuration keyword expected"));
1831 char c = conftoken_getc();
1832 if (c == '\n' || c == -1) {
1833 conftoken_ungetc(c);
1838 g_assert_not_reached();
1848 for (iter = seen_filenames; iter; iter = iter->next) {
1850 if (istr == filename || 0 == strcmp(istr, filename))
1854 istr = stralloc(filename);
1855 seen_filenames = g_slist_prepend(seen_filenames, istr);
1861 conf_var_t *read_var,
1865 void (*copy_function)(void),
1875 get_conftoken(CONF_LBRACE);
1876 get_conftoken(CONF_NL);
1881 current_line_num += 1;
1882 get_conftoken(CONF_ANY);
1887 case CONF_NL: /* empty line */
1889 case CONF_END: /* end of file */
1893 /* inherit from a "parent" */
1899 conf_parserror(_("ident not expected"));
1903 for(np = read_var; np->token != CONF_UNKNOWN; np++)
1904 if(np->token == tok) break;
1906 if(np->token == CONF_UNKNOWN)
1907 conf_parserror("%s", errormsg);
1909 np->read_function(np, &valarray[np->parm]);
1910 if(np->validate_function)
1911 np->validate_function(np, &valarray[np->parm]);
1915 if(tok != CONF_NL && tok != CONF_END && tok != CONF_RBRACE)
1916 get_conftoken(CONF_NL);
1919 if (!config_overrides)
1922 key_ovr = vstralloc(type, ":", name, NULL);
1923 for (i = 0; i < config_overrides->n_used; i++) {
1924 config_override_t *co = &config_overrides->ovr[i];
1925 char *key = co->key;
1930 if (key_ovr && strncasecmp(key_ovr, key, strlen(key_ovr)) != 0)
1933 if (strlen(key) <= strlen(key_ovr) + 1)
1936 keyword = key + strlen(key_ovr) + 1;
1939 /* find the token in keytable */
1940 for (kt = keytable; kt->token != CONF_UNKNOWN; kt++) {
1941 if (kt->keyword && strcasecmp(kt->keyword, keyword) == 0)
1944 if (kt->token == CONF_UNKNOWN)
1947 /* find the var in read_var */
1948 for (np = read_var; np->token != CONF_UNKNOWN; np++)
1949 if (np->token == kt->token) break;
1950 if (np->token == CONF_UNKNOWN)
1953 /* now set up a fake line and use the relevant read_function to
1954 * parse it. This is sneaky! */
1955 if (np->type == CONFTYPE_STR) {
1956 current_line = quote_string_always(value);
1958 current_line = stralloc(value);
1961 current_char = current_line;
1963 current_line_num = -2;
1964 allow_overwrites = 1;
1967 np->read_function(np, &valarray[np->parm]);
1968 if (np->validate_function)
1969 np->validate_function(np, &valarray[np->parm]);
1971 amfree(current_line);
1972 current_char = NULL;
1980 conf_var_t *np G_GNUC_UNUSED,
1981 val_t *val G_GNUC_UNUSED)
1983 assert (val == &conf_data[CNF_HOLDINGDISK]);
1991 int save_overwrites;
1993 save_overwrites = allow_overwrites;
1994 allow_overwrites = 1;
1996 init_holdingdisk_defaults();
1998 get_conftoken(CONF_IDENT);
1999 hdcur.name = stralloc(tokenval.v.s);
2000 hdcur.seen.filename = current_filename;
2001 hdcur.seen.linenum = current_line_num;
2003 get_conftoken(CONF_ANY);
2004 if (tok == CONF_LBRACE) {
2006 hd = lookup_holdingdisk(hdcur.name);
2008 conf_parserror(_("holding disk '%s' already defined"),
2012 read_block(holding_var, hdcur.value,
2013 _("holding disk parameter expected"), 1, copy_holdingdisk,
2014 "HOLDINGDISK", hdcur.name);
2015 get_conftoken(CONF_NL);
2018 conf_data[CNF_HOLDINGDISK].v.identlist = g_slist_append(
2019 conf_data[CNF_HOLDINGDISK].v.identlist,
2020 stralloc(hdcur.name));
2023 } else { /* use the already defined holding disk */
2026 conf_parserror(_("holdingdisk definition must specify holdingdisk parameters"));
2031 for (il = conf_data[CNF_HOLDINGDISK].v.identlist; il != NULL;
2033 if (strcmp((char *)il->data, hdcur.name) == 0) {
2038 conf_parserror(_("holding disk '%s' already in use"),
2041 conf_data[CNF_HOLDINGDISK].v.identlist = g_slist_append(
2042 conf_data[CNF_HOLDINGDISK].v.identlist,
2043 stralloc(hdcur.name));
2046 get_conftoken(CONF_ANY);
2047 if (tok == CONF_IDENT || tok == CONF_STRING) {
2048 hdcur.name = stralloc(tokenval.v.s);
2049 } else if (tok != CONF_NL) {
2050 conf_parserror(_("IDENT or NL expected"));
2052 } while (tok == CONF_IDENT || tok == CONF_STRING);
2055 allow_overwrites = save_overwrites;
2059 init_holdingdisk_defaults(
2062 conf_init_str(&hdcur.value[HOLDING_COMMENT] , "");
2063 conf_init_str(&hdcur.value[HOLDING_DISKDIR] , "");
2064 conf_init_int64(&hdcur.value[HOLDING_DISKSIZE] , (gint64)0);
2065 /* 1 Gb = 1M counted in 1Kb blocks */
2066 conf_init_int64(&hdcur.value[HOLDING_CHUNKSIZE], (gint64)1024*1024);
2075 hp = alloc(sizeof(holdingdisk_t));
2077 holdinglist = g_slist_append(holdinglist, hp);
2087 hp = lookup_holdingdisk(tokenval.v.s);
2090 conf_parserror(_("holdingdisk parameter expected"));
2094 for(i=0; i < HOLDING_HOLDING; i++) {
2095 if(hp->value[i].seen.linenum) {
2096 merge_val_t(&hdcur.value[i], &hp->value[i]);
2104 * This function is called both from this module and from diskfile.c. Modify
2113 int save_overwrites;
2114 FILE *saved_conf = NULL;
2115 char *saved_fname = NULL;
2118 saved_conf = current_file;
2119 current_file = from;
2123 saved_fname = current_filename;
2124 current_filename = get_seen_filename(fname);
2128 current_line_num = *linenum;
2130 save_overwrites = allow_overwrites;
2131 allow_overwrites = 1;
2133 init_dumptype_defaults();
2137 get_conftoken(CONF_IDENT);
2138 dpcur.name = stralloc(tokenval.v.s);
2140 dpcur.seen.filename = current_filename;
2141 dpcur.seen.linenum = current_line_num;
2143 read_block(dumptype_var, dpcur.value,
2144 _("dumptype parameter expected"),
2145 (name == NULL), copy_dumptype,
2146 "DUMPTYPE", dpcur.name);
2148 if(!name) /* !name => reading disklist, not conffile */
2149 get_conftoken(CONF_NL);
2151 /* XXX - there was a stupidity check in here for skip-incr and
2152 ** skip-full. This check should probably be somewhere else. */
2156 allow_overwrites = save_overwrites;
2159 *linenum = current_line_num;
2162 current_filename = saved_fname;
2165 current_file = saved_conf;
2167 return lookup_dumptype(dpcur.name);
2173 read_dumptype(NULL, NULL, NULL, NULL);
2177 init_dumptype_defaults(void)
2180 conf_init_str (&dpcur.value[DUMPTYPE_COMMENT] , "");
2181 conf_init_str (&dpcur.value[DUMPTYPE_PROGRAM] , "DUMP");
2182 conf_init_str (&dpcur.value[DUMPTYPE_SRVCOMPPROG] , "");
2183 conf_init_str (&dpcur.value[DUMPTYPE_CLNTCOMPPROG] , "");
2184 conf_init_str (&dpcur.value[DUMPTYPE_SRV_ENCRYPT] , "");
2185 conf_init_str (&dpcur.value[DUMPTYPE_CLNT_ENCRYPT] , "");
2186 conf_init_str (&dpcur.value[DUMPTYPE_AMANDAD_PATH] , "");
2187 conf_init_str (&dpcur.value[DUMPTYPE_CLIENT_USERNAME] , "");
2188 conf_init_str (&dpcur.value[DUMPTYPE_CLIENT_PORT] , "");
2189 conf_init_str (&dpcur.value[DUMPTYPE_SSH_KEYS] , "");
2190 conf_init_str (&dpcur.value[DUMPTYPE_AUTH] , "BSD");
2191 conf_init_exinclude(&dpcur.value[DUMPTYPE_EXCLUDE]);
2192 conf_init_exinclude(&dpcur.value[DUMPTYPE_INCLUDE]);
2193 conf_init_priority (&dpcur.value[DUMPTYPE_PRIORITY] , 1);
2194 conf_init_int (&dpcur.value[DUMPTYPE_DUMPCYCLE] , conf_data[CNF_DUMPCYCLE].v.i);
2195 conf_init_int (&dpcur.value[DUMPTYPE_MAXDUMPS] , conf_data[CNF_MAXDUMPS].v.i);
2196 conf_init_int (&dpcur.value[DUMPTYPE_MAXPROMOTEDAY] , 10000);
2197 conf_init_int (&dpcur.value[DUMPTYPE_BUMPPERCENT] , conf_data[CNF_BUMPPERCENT].v.i);
2198 conf_init_int64 (&dpcur.value[DUMPTYPE_BUMPSIZE] , conf_data[CNF_BUMPSIZE].v.int64);
2199 conf_init_int (&dpcur.value[DUMPTYPE_BUMPDAYS] , conf_data[CNF_BUMPDAYS].v.i);
2200 conf_init_real (&dpcur.value[DUMPTYPE_BUMPMULT] , conf_data[CNF_BUMPMULT].v.r);
2201 conf_init_time (&dpcur.value[DUMPTYPE_STARTTIME] , (time_t)0);
2202 conf_init_strategy (&dpcur.value[DUMPTYPE_STRATEGY] , DS_STANDARD);
2203 conf_init_estimatelist(&dpcur.value[DUMPTYPE_ESTIMATELIST] , ES_CLIENT);
2204 conf_init_compress (&dpcur.value[DUMPTYPE_COMPRESS] , COMP_FAST);
2205 conf_init_encrypt (&dpcur.value[DUMPTYPE_ENCRYPT] , ENCRYPT_NONE);
2206 conf_init_data_path(&dpcur.value[DUMPTYPE_DATA_PATH] , DATA_PATH_AMANDA);
2207 conf_init_str (&dpcur.value[DUMPTYPE_SRV_DECRYPT_OPT] , "-d");
2208 conf_init_str (&dpcur.value[DUMPTYPE_CLNT_DECRYPT_OPT] , "-d");
2209 conf_init_rate (&dpcur.value[DUMPTYPE_COMPRATE] , 0.50, 0.50);
2210 conf_init_int64 (&dpcur.value[DUMPTYPE_TAPE_SPLITSIZE] , (gint64)0);
2211 conf_init_int64 (&dpcur.value[DUMPTYPE_FALLBACK_SPLITSIZE], (gint64)10 * 1024);
2212 conf_init_str (&dpcur.value[DUMPTYPE_SPLIT_DISKBUFFER] , NULL);
2213 conf_init_bool (&dpcur.value[DUMPTYPE_RECORD] , 1);
2214 conf_init_bool (&dpcur.value[DUMPTYPE_SKIP_INCR] , 0);
2215 conf_init_bool (&dpcur.value[DUMPTYPE_SKIP_FULL] , 0);
2216 conf_init_holding (&dpcur.value[DUMPTYPE_HOLDINGDISK] , HOLD_AUTO);
2217 conf_init_bool (&dpcur.value[DUMPTYPE_KENCRYPT] , 0);
2218 conf_init_bool (&dpcur.value[DUMPTYPE_IGNORE] , 0);
2219 conf_init_bool (&dpcur.value[DUMPTYPE_INDEX] , 1);
2220 conf_init_application(&dpcur.value[DUMPTYPE_APPLICATION]);
2221 conf_init_identlist(&dpcur.value[DUMPTYPE_SCRIPTLIST], NULL);
2222 conf_init_proplist(&dpcur.value[DUMPTYPE_PROPERTY]);
2228 dumptype_t *dp, *dp1;;
2230 dp = lookup_dumptype(dpcur.name);
2232 if(dp != (dumptype_t *)0) {
2233 if (dp->seen.linenum == -1) {
2234 conf_parserror(_("dumptype %s is defined by default and cannot be redefined"), dp->name);
2236 conf_parserror(_("dumptype %s already defined at %s:%d"), dp->name,
2237 dp->seen.filename, dp->seen.linenum);
2242 dp = alloc(sizeof(dumptype_t));
2245 /* add at end of list */
2250 while (dp1->next != NULL) {
2263 dt = lookup_dumptype(tokenval.v.s);
2266 conf_parserror(_("dumptype parameter expected"));
2270 for(i=0; i < DUMPTYPE_DUMPTYPE; i++) {
2271 if(dt->value[i].seen.linenum) {
2272 merge_val_t(&dpcur.value[i], &dt->value[i]);
2273 if (i == DUMPTYPE_SCRIPTLIST) {
2274 /* sort in 'order' */
2275 dpcur.value[i].v.identlist = g_slist_sort(dpcur.value[i].v.identlist, &compare_pp_script_order);
2284 int save_overwrites;
2286 save_overwrites = allow_overwrites;
2287 allow_overwrites = 1;
2289 init_tapetype_defaults();
2291 get_conftoken(CONF_IDENT);
2292 tpcur.name = stralloc(tokenval.v.s);
2293 tpcur.seen.filename = current_filename;
2294 tpcur.seen.linenum = current_line_num;
2296 read_block(tapetype_var, tpcur.value,
2297 _("tapetype parameter expected"), 1, copy_tapetype,
2298 "TAPETYPE", tpcur.name);
2299 get_conftoken(CONF_NL);
2301 if (tapetype_get_readblocksize(&tpcur) <
2302 tapetype_get_blocksize(&tpcur)) {
2303 conf_init_size(&tpcur.value[TAPETYPE_READBLOCKSIZE],
2304 tapetype_get_blocksize(&tpcur));
2308 allow_overwrites = save_overwrites;
2312 init_tapetype_defaults(void)
2314 conf_init_str(&tpcur.value[TAPETYPE_COMMENT] , "");
2315 conf_init_str(&tpcur.value[TAPETYPE_LBL_TEMPL] , "");
2316 conf_init_size (&tpcur.value[TAPETYPE_BLOCKSIZE] , DISK_BLOCK_KB);
2317 conf_init_size (&tpcur.value[TAPETYPE_READBLOCKSIZE], DISK_BLOCK_KB);
2318 conf_init_int64 (&tpcur.value[TAPETYPE_LENGTH] , ((gint64)2000));
2319 conf_init_int64 (&tpcur.value[TAPETYPE_FILEMARK] , (gint64)1);
2320 conf_init_int (&tpcur.value[TAPETYPE_SPEED] , 200);
2321 conf_init_bool (&tpcur.value[TAPETYPE_FILE_PAD] , 1);
2327 tapetype_t *tp, *tp1;
2329 tp = lookup_tapetype(tpcur.name);
2331 if(tp != (tapetype_t *)0) {
2333 conf_parserror(_("tapetype %s already defined at %s:%d"),
2334 tp->name, tp->seen.filename, tp->seen.linenum);
2338 tp = alloc(sizeof(tapetype_t));
2340 /* add at end of list */
2345 while (tp1->next != NULL) {
2358 tp = lookup_tapetype(tokenval.v.s);
2361 conf_parserror(_("tape type parameter expected"));
2365 for(i=0; i < TAPETYPE_TAPETYPE; i++) {
2366 if(tp->value[i].seen.linenum) {
2367 merge_val_t(&tpcur.value[i], &tp->value[i]);
2375 int save_overwrites;
2377 save_overwrites = allow_overwrites;
2378 allow_overwrites = 1;
2380 init_interface_defaults();
2382 get_conftoken(CONF_IDENT);
2383 ifcur.name = stralloc(tokenval.v.s);
2384 ifcur.seen.filename = current_filename;
2385 ifcur.seen.linenum = current_line_num;
2387 read_block(interface_var, ifcur.value,
2388 _("interface parameter expected"), 1, copy_interface,
2389 "INTERFACE", ifcur.name);
2390 get_conftoken(CONF_NL);
2394 allow_overwrites = save_overwrites;
2400 init_interface_defaults(void)
2402 conf_init_str(&ifcur.value[INTER_COMMENT] , "");
2403 conf_init_int (&ifcur.value[INTER_MAXUSAGE], 8000);
2407 save_interface(void)
2409 interface_t *ip, *ip1;
2411 ip = lookup_interface(ifcur.name);
2413 if(ip != (interface_t *)0) {
2414 conf_parserror(_("interface %s already defined at %s:%d"),
2415 ip->name, ip->seen.filename, ip->seen.linenum);
2419 ip = alloc(sizeof(interface_t));
2421 /* add at end of list */
2422 if(!interface_list) {
2423 interface_list = ip;
2425 ip1 = interface_list;
2426 while (ip1->next != NULL) {
2434 copy_interface(void)
2439 ip = lookup_interface(tokenval.v.s);
2442 conf_parserror(_("interface parameter expected"));
2446 for(i=0; i < INTER_INTER; i++) {
2447 if(ip->value[i].seen.linenum) {
2448 merge_val_t(&ifcur.value[i], &ip->value[i]);
2461 int save_overwrites;
2462 FILE *saved_conf = NULL;
2463 char *saved_fname = NULL;
2466 saved_conf = current_file;
2467 current_file = from;
2471 saved_fname = current_filename;
2472 current_filename = get_seen_filename(fname);
2476 current_line_num = *linenum;
2478 save_overwrites = allow_overwrites;
2479 allow_overwrites = 1;
2481 init_application_defaults();
2485 get_conftoken(CONF_IDENT);
2486 apcur.name = stralloc(tokenval.v.s);
2488 apcur.seen.filename = current_filename;
2489 apcur.seen.linenum = current_line_num;
2491 read_block(application_var, apcur.value,
2492 _("application parameter expected"),
2493 (name == NULL), *copy_application,
2494 "APPLICATION", apcur.name);
2496 get_conftoken(CONF_NL);
2500 allow_overwrites = save_overwrites;
2503 *linenum = current_line_num;
2506 current_filename = saved_fname;
2509 current_file = saved_conf;
2511 return lookup_application(apcur.name);
2518 read_application(NULL, NULL, NULL, NULL);
2522 init_application_defaults(
2526 conf_init_str(&apcur.value[APPLICATION_COMMENT] , "");
2527 conf_init_str(&apcur.value[APPLICATION_PLUGIN] , "");
2528 conf_init_proplist(&apcur.value[APPLICATION_PROPERTY]);
2535 application_t *ap, *ap1;
2537 ap = lookup_application(apcur.name);
2539 if(ap != (application_t *)0) {
2540 conf_parserror(_("application %s already defined at %s:%d"),
2541 ap->name, ap->seen.filename, ap->seen.linenum);
2545 ap = alloc(sizeof(application_t));
2548 /* add at end of list */
2549 if (!application_list)
2550 application_list = ap;
2552 ap1 = application_list;
2553 while (ap1->next != NULL) {
2561 copy_application(void)
2566 ap = lookup_application(tokenval.v.s);
2569 conf_parserror(_("application parameter expected"));
2573 for(i=0; i < APPLICATION_APPLICATION; i++) {
2574 if(ap->value[i].seen.linenum) {
2575 merge_val_t(&apcur.value[i], &ap->value[i]);
2587 int save_overwrites;
2588 FILE *saved_conf = NULL;
2589 char *saved_fname = NULL;
2592 saved_conf = current_file;
2593 current_file = from;
2597 saved_fname = current_filename;
2598 current_filename = get_seen_filename(fname);
2602 current_line_num = *linenum;
2604 save_overwrites = allow_overwrites;
2605 allow_overwrites = 1;
2607 init_pp_script_defaults();
2611 get_conftoken(CONF_IDENT);
2612 pscur.name = stralloc(tokenval.v.s);
2614 pscur.seen.filename = current_filename;
2615 pscur.seen.linenum = current_line_num;
2617 read_block(pp_script_var, pscur.value,
2618 _("script parameter expected"),
2619 (name == NULL), *copy_pp_script,
2620 "SCRIPT", pscur.name);
2622 get_conftoken(CONF_NL);
2626 allow_overwrites = save_overwrites;
2629 *linenum = current_line_num;
2632 current_filename = saved_fname;
2635 current_file = saved_conf;
2637 return lookup_pp_script(pscur.name);
2644 read_pp_script(NULL, NULL, NULL, NULL);
2648 init_pp_script_defaults(
2652 conf_init_str(&pscur.value[PP_SCRIPT_COMMENT] , "");
2653 conf_init_str(&pscur.value[PP_SCRIPT_PLUGIN] , "");
2654 conf_init_proplist(&pscur.value[PP_SCRIPT_PROPERTY]);
2655 conf_init_execute_on(&pscur.value[PP_SCRIPT_EXECUTE_ON], 0);
2656 conf_init_execute_where(&pscur.value[PP_SCRIPT_EXECUTE_WHERE], ES_CLIENT);
2657 conf_init_int(&pscur.value[PP_SCRIPT_ORDER], 5000);
2664 pp_script_t *ps, *ps1;
2666 ps = lookup_pp_script(pscur.name);
2668 if(ps != (pp_script_t *)0) {
2669 conf_parserror(_("script %s already defined at %s:%d"),
2670 ps->name, ps->seen.filename, ps->seen.linenum);
2674 ps = alloc(sizeof(pp_script_t));
2677 /* add at end of list */
2678 if (!pp_script_list)
2679 pp_script_list = ps;
2681 ps1 = pp_script_list;
2682 while (ps1->next != NULL) {
2690 copy_pp_script(void)
2695 ps = lookup_pp_script(tokenval.v.s);
2698 conf_parserror(_("script parameter expected"));
2702 for(i=0; i < PP_SCRIPT_PP_SCRIPT; i++) {
2703 if(ps->value[i].seen.linenum) {
2704 merge_val_t(&pscur.value[i], &ps->value[i]);
2716 int save_overwrites;
2717 FILE *saved_conf = NULL;
2718 char *saved_fname = NULL;
2721 saved_conf = current_file;
2722 current_file = from;
2726 saved_fname = current_filename;
2727 current_filename = get_seen_filename(fname);
2731 current_line_num = *linenum;
2733 save_overwrites = allow_overwrites;
2734 allow_overwrites = 1;
2736 init_device_config_defaults();
2740 get_conftoken(CONF_IDENT);
2741 dccur.name = stralloc(tokenval.v.s);
2743 dccur.seen.filename = current_filename;
2744 dccur.seen.linenum = current_line_num;
2746 read_block(device_config_var, dccur.value,
2747 _("device parameter expected"),
2748 (name == NULL), *copy_device_config,
2749 "DEVICE", dccur.name);
2751 get_conftoken(CONF_NL);
2753 save_device_config();
2755 allow_overwrites = save_overwrites;
2758 *linenum = current_line_num;
2761 current_filename = saved_fname;
2764 current_file = saved_conf;
2766 return lookup_device_config(dccur.name);
2773 read_device_config(NULL, NULL, NULL, NULL);
2777 init_device_config_defaults(
2781 conf_init_str(&dccur.value[DEVICE_CONFIG_COMMENT] , "");
2782 conf_init_str(&dccur.value[DEVICE_CONFIG_TAPEDEV] , "");
2783 conf_init_proplist(&dccur.value[DEVICE_CONFIG_DEVICE_PROPERTY]);
2790 device_config_t *dc, *dc1;
2792 dc = lookup_device_config(dccur.name);
2794 if(dc != (device_config_t *)0) {
2795 conf_parserror(_("device %s already defined at %s:%d"),
2796 dc->name, dc->seen.filename, dc->seen.linenum);
2800 dc = alloc(sizeof(device_config_t));
2803 /* add at end of list */
2804 if (!device_config_list)
2805 device_config_list = dc;
2807 dc1 = device_config_list;
2808 while (dc1->next != NULL) {
2816 copy_device_config(void)
2818 device_config_t *dc;
2821 dc = lookup_device_config(tokenval.v.s);
2824 conf_parserror(_("device parameter expected"));
2828 for(i=0; i < DEVICE_CONFIG_DEVICE_CONFIG; i++) {
2829 if(dc->value[i].seen.linenum) {
2830 merge_val_t(&dccur.value[i], &dc->value[i]);
2836 read_changer_config(
2842 int save_overwrites;
2843 FILE *saved_conf = NULL;
2844 char *saved_fname = NULL;
2847 saved_conf = current_file;
2848 current_file = from;
2852 saved_fname = current_filename;
2853 current_filename = fname;
2857 current_line_num = *linenum;
2859 save_overwrites = allow_overwrites;
2860 allow_overwrites = 1;
2862 init_changer_config_defaults();
2866 get_conftoken(CONF_IDENT);
2867 cccur.name = stralloc(tokenval.v.s);
2869 cccur.seen = current_line_num;
2871 read_block(changer_config_var, cccur.value,
2872 _("changer parameter expected"),
2873 (name == NULL), *copy_changer_config,
2874 "CHANGER", cccur.name);
2876 get_conftoken(CONF_NL);
2878 save_changer_config();
2880 allow_overwrites = save_overwrites;
2883 *linenum = current_line_num;
2886 current_filename = saved_fname;
2889 current_file = saved_conf;
2891 return lookup_changer_config(cccur.name);
2898 read_changer_config(NULL, NULL, NULL, NULL);
2902 init_changer_config_defaults(
2906 conf_init_str(&cccur.value[CHANGER_CONFIG_COMMENT] , "");
2907 conf_init_str(&cccur.value[CHANGER_CONFIG_TAPEDEV] , "");
2908 conf_init_str(&cccur.value[CHANGER_CONFIG_TPCHANGER] , "");
2909 conf_init_str(&cccur.value[CHANGER_CONFIG_CHANGERDEV] , "");
2910 conf_init_str(&cccur.value[CHANGER_CONFIG_CHANGERFILE] , "");
2911 conf_init_proplist(&cccur.value[CHANGER_CONFIG_PROPERTY]);
2912 conf_init_proplist(&cccur.value[CHANGER_CONFIG_DEVICE_PROPERTY]);
2916 save_changer_config(
2919 changer_config_t *dc, *dc1;
2921 dc = lookup_changer_config(cccur.name);
2923 if(dc != (changer_config_t *)0) {
2924 conf_parserror(_("changer %s already defined on line %d"),
2925 dc->name, dc->seen);
2929 dc = alloc(sizeof(changer_config_t));
2932 /* add at end of list */
2933 if (!changer_config_list)
2934 changer_config_list = dc;
2936 dc1 = changer_config_list;
2937 while (dc1->next != NULL) {
2945 copy_changer_config(void)
2947 changer_config_t *dc;
2950 dc = lookup_changer_config(tokenval.v.s);
2953 conf_parserror(_("changer parameter expected"));
2957 for(i=0; i < CHANGER_CONFIG_CHANGER_CONFIG; i++) {
2958 if(dc->value[i].seen.linenum) {
2959 merge_val_t(&cccur.value[i], &dc->value[i]);
2964 /* Read functions */
2968 conf_var_t *np G_GNUC_UNUSED,
2972 val_t__int(val) = get_int();
2977 conf_var_t *np G_GNUC_UNUSED,
2981 val_t__int64(val) = get_int64();
2986 conf_var_t *np G_GNUC_UNUSED,
2990 get_conftoken(CONF_REAL);
2991 val_t__real(val) = tokenval.v.r;
2996 conf_var_t *np G_GNUC_UNUSED,
3000 get_conftoken(CONF_STRING);
3001 val->v.s = newstralloc(val->v.s, tokenval.v.s);
3006 conf_var_t *np G_GNUC_UNUSED,
3010 get_conftoken(CONF_IDENT);
3011 val->v.s = newstralloc(val->v.s, tokenval.v.s);
3016 conf_var_t *np G_GNUC_UNUSED,
3020 val_t__time(val) = get_time();
3025 conf_var_t *np G_GNUC_UNUSED,
3029 val_t__size(val) = get_size();
3034 conf_var_t *np G_GNUC_UNUSED,
3038 val_t__boolean(val) = get_bool();
3043 conf_var_t *np G_GNUC_UNUSED,
3046 int serv, clie, none, fast, best, custom;
3052 serv = clie = none = fast = best = custom = 0;
3056 get_conftoken(CONF_ANY);
3058 case CONF_NONE: none = 1; break;
3059 case CONF_FAST: fast = 1; break;
3060 case CONF_BEST: best = 1; break;
3061 case CONF_CLIENT: clie = 1; break;
3062 case CONF_SERVER: serv = 1; break;
3063 case CONF_CUSTOM: custom=1; break;
3064 case CONF_NL: done = 1; break;
3065 case CONF_END: done = 1; break;
3068 serv = clie = 1; /* force an error */
3072 if(serv + clie == 0) clie = 1; /* default to client */
3073 if(none + fast + best + custom == 0) fast = 1; /* default to fast */
3078 if(none && !fast && !best && !custom) comp = COMP_NONE;
3079 if(!none && fast && !best && !custom) comp = COMP_FAST;
3080 if(!none && !fast && best && !custom) comp = COMP_BEST;
3081 if(!none && !fast && !best && custom) comp = COMP_CUST;
3085 if(none && !fast && !best && !custom) comp = COMP_NONE;
3086 if(!none && fast && !best && !custom) comp = COMP_SERVER_FAST;
3087 if(!none && !fast && best && !custom) comp = COMP_SERVER_BEST;
3088 if(!none && !fast && !best && custom) comp = COMP_SERVER_CUST;
3091 if((int)comp == -1) {
3092 conf_parserror(_("NONE, CLIENT FAST, CLIENT BEST, CLIENT CUSTOM, SERVER FAST, SERVER BEST or SERVER CUSTOM expected"));
3096 val_t__compress(val) = (int)comp;
3101 conf_var_t *np G_GNUC_UNUSED,
3108 get_conftoken(CONF_ANY);
3111 encrypt = ENCRYPT_NONE;
3115 encrypt = ENCRYPT_CUST;
3119 encrypt = ENCRYPT_SERV_CUST;
3123 conf_parserror(_("NONE, CLIENT or SERVER expected"));
3124 encrypt = ENCRYPT_NONE;
3128 val_t__encrypt(val) = (int)encrypt;
3133 conf_var_t *np G_GNUC_UNUSED,
3136 dump_holdingdisk_t holding;
3140 get_conftoken(CONF_ANY);
3143 holding = HOLD_NEVER;
3147 holding = HOLD_AUTO;
3151 holding = HOLD_REQUIRED;
3154 default: /* can be a BOOLEAN */
3156 holding = (dump_holdingdisk_t)get_bool();
3158 holding = HOLD_NEVER;
3159 else if (holding == 1 || holding == 2)
3160 holding = HOLD_AUTO;
3162 conf_parserror(_("NEVER, AUTO or REQUIRED expected"));
3166 val_t__holding(val) = (int)holding;
3171 conf_var_t *np G_GNUC_UNUSED,
3174 estimatelist_t estimates = NULL;
3178 get_conftoken(CONF_ANY);
3182 estimates = g_slist_append(estimates, GINT_TO_POINTER(ES_CLIENT));
3185 estimates = g_slist_append(estimates, GINT_TO_POINTER(ES_SERVER));
3188 estimates = g_slist_append(estimates, GINT_TO_POINTER(ES_CALCSIZE));
3191 conf_parserror(_("CLIENT, SERVER or CALCSIZE expected"));
3193 get_conftoken(CONF_ANY);
3197 val_t__estimatelist(val) = estimates;
3202 conf_var_t *np G_GNUC_UNUSED,
3209 get_conftoken(CONF_ANY);
3215 strat = DS_STANDARD;
3227 strat = DS_INCRONLY;
3230 conf_parserror(_("dump strategy expected"));
3231 strat = DS_STANDARD;
3233 val_t__strategy(val) = strat;
3238 conf_var_t *np G_GNUC_UNUSED,
3243 get_conftoken(CONF_ANY);
3245 case CONF_FIRST: val_t__taperalgo(val) = ALGO_FIRST; break;
3246 case CONF_FIRSTFIT: val_t__taperalgo(val) = ALGO_FIRSTFIT; break;
3247 case CONF_LARGEST: val_t__taperalgo(val) = ALGO_LARGEST; break;
3248 case CONF_LARGESTFIT: val_t__taperalgo(val) = ALGO_LARGESTFIT; break;
3249 case CONF_SMALLEST: val_t__taperalgo(val) = ALGO_SMALLEST; break;
3250 case CONF_LAST: val_t__taperalgo(val) = ALGO_LAST; break;
3252 conf_parserror(_("FIRST, FIRSTFIT, LARGEST, LARGESTFIT, SMALLEST or LAST expected"));
3257 read_send_amreport_on(
3258 conf_var_t *np G_GNUC_UNUSED,
3263 get_conftoken(CONF_ANY);
3265 case CONF_ALL: val_t__send_amreport(val) = SEND_AMREPORT_ALL; break;
3266 case CONF_STRANGE: val_t__send_amreport(val) = SEND_AMREPORT_STRANGE; break;
3267 case CONF_ERROR: val_t__send_amreport(val) = SEND_AMREPORT_ERROR; break;
3268 case CONF_NEVER: val_t__send_amreport(val) = SEND_AMREPORT_NEVER; break;
3270 conf_parserror(_("ALL, STRANGE, ERROR or NEVER expected"));
3276 conf_var_t *np G_GNUC_UNUSED,
3281 get_conftoken(CONF_ANY);
3283 case CONF_AMANDA : val_t__send_amreport(val) = DATA_PATH_AMANDA ; break;
3284 case CONF_DIRECTTCP: val_t__send_amreport(val) = DATA_PATH_DIRECTTCP; break;
3286 conf_parserror(_("AMANDA or DIRECTTCP expected"));
3292 conf_var_t *np G_GNUC_UNUSED,
3299 get_conftoken(CONF_ANY);
3301 case CONF_LOW: pri = 0; break;
3302 case CONF_MEDIUM: pri = 1; break;
3303 case CONF_HIGH: pri = 2; break;
3304 case CONF_INT: pri = tokenval.v.i; break;
3306 conf_parserror(_("LOW, MEDIUM, HIGH or integer expected"));
3309 val_t__priority(val) = pri;
3314 conf_var_t *np G_GNUC_UNUSED,
3317 get_conftoken(CONF_REAL);
3318 val_t__rate(val)[0] = tokenval.v.r;
3319 val_t__rate(val)[1] = tokenval.v.r;
3320 val->seen = tokenval.seen;
3321 if(tokenval.v.r < 0) {
3322 conf_parserror(_("full compression rate must be >= 0"));
3325 get_conftoken(CONF_ANY);
3340 get_conftoken(CONF_REAL);
3341 val_t__rate(val)[1] = tokenval.v.r;
3342 if(tokenval.v.r < 0) {
3343 conf_parserror(_("incremental compression rate must be >= 0"));
3349 conf_var_t *np G_GNUC_UNUSED,
3352 int file, got_one = 0;
3356 get_conftoken(CONF_ANY);
3357 if(tok == CONF_LIST) {
3359 get_conftoken(CONF_ANY);
3360 exclude = val_t__exinclude(val).sl_list;
3364 if(tok == CONF_EFILE) get_conftoken(CONF_ANY);
3365 exclude = val_t__exinclude(val).sl_file;
3369 if(tok == CONF_OPTIONAL) {
3370 get_conftoken(CONF_ANY);
3374 if(tok == CONF_APPEND) {
3375 get_conftoken(CONF_ANY);
3382 while(tok == CONF_STRING) {
3383 exclude = append_sl(exclude, tokenval.v.s);
3385 get_conftoken(CONF_ANY);
3389 if(got_one == 0) { free_sl(exclude); exclude = NULL; }
3392 val_t__exinclude(val).sl_list = exclude;
3394 val_t__exinclude(val).sl_file = exclude;
3395 val_t__exinclude(val).optional = optional;
3400 conf_var_t *np G_GNUC_UNUSED,
3403 get_conftoken(CONF_INT);
3404 val_t__intrange(val)[0] = tokenval.v.i;
3405 val_t__intrange(val)[1] = tokenval.v.i;
3406 val->seen = tokenval.seen;
3408 get_conftoken(CONF_ANY);
3423 get_conftoken(CONF_INT);
3424 val_t__intrange(val)[1] = tokenval.v.i;
3429 conf_var_t *np G_GNUC_UNUSED,
3433 property_t *property = malloc(sizeof(property_t));
3434 property_t *old_property;
3435 property->append = 0;
3436 property->priority = 0;
3437 property->values = NULL;
3439 get_conftoken(CONF_ANY);
3440 if (tok == CONF_PRIORITY) {
3441 property->priority = 1;
3442 get_conftoken(CONF_ANY);
3444 if (tok == CONF_APPEND) {
3445 property->append = 1;
3446 get_conftoken(CONF_ANY);
3448 if (tok != CONF_STRING) {
3449 conf_parserror(_("key expected"));
3452 key = g_ascii_strdown(tokenval.v.s, -1);
3454 get_conftoken(CONF_ANY);
3455 if (tok == CONF_NL || tok == CONF_END) {
3456 g_hash_table_remove(val->v.proplist, key);
3460 if (tok != CONF_STRING) {
3461 conf_parserror(_("value expected"));
3465 if(val->seen.linenum == 0) {
3466 val->seen.filename = current_filename;
3467 val->seen.linenum = current_line_num;
3470 old_property = g_hash_table_lookup(val->v.proplist, key);
3471 if (property->append) {
3472 /* old_property will be freed by g_hash_table_insert, so
3473 * steal its values */
3475 if (old_property->priority)
3476 property->priority = 1;
3477 property->values = old_property->values;
3478 old_property->values = NULL;
3481 while(tok == CONF_STRING) {
3482 property->values = g_slist_append(property->values,
3483 strdup(tokenval.v.s));
3484 get_conftoken(CONF_ANY);
3487 g_hash_table_insert(val->v.proplist, key, property);
3493 conf_var_t *np G_GNUC_UNUSED,
3496 application_t *application;
3498 get_conftoken(CONF_ANY);
3499 if (tok == CONF_LBRACE) {
3500 current_line_num -= 1;
3501 application = read_application(vstralloc("custom(DUMPTYPE:",
3502 dpcur.name, ")", ".",
3503 anonymous_value(),NULL),
3505 current_line_num -= 1;
3506 } else if (tok == CONF_STRING) {
3507 application = lookup_application(tokenval.v.s);
3508 if (application == NULL) {
3509 conf_parserror(_("Unknown application named: %s"), tokenval.v.s);
3513 conf_parserror(_("application name expected: %d %d"), tok, CONF_STRING);
3517 val->v.s = stralloc(application->name);
3523 conf_var_t *np G_GNUC_UNUSED,
3526 pp_script_t *pp_script;
3527 get_conftoken(CONF_ANY);
3528 if (tok == CONF_LBRACE) {
3529 current_line_num -= 1;
3530 pp_script = read_pp_script(vstralloc("custom(DUMPTYPE:", dpcur.name,
3531 ")", ".", anonymous_value(),NULL),
3533 current_line_num -= 1;
3534 val->v.identlist = g_slist_insert_sorted(val->v.identlist,
3535 stralloc(pp_script->name), &compare_pp_script_order);
3536 } else if (tok == CONF_STRING || tok == CONF_IDENT) {
3537 while (tok == CONF_STRING || tok == CONF_IDENT) {
3538 pp_script = lookup_pp_script(tokenval.v.s);
3539 if (pp_script == NULL) {
3540 conf_parserror(_("Unknown pp_script named: %s"), tokenval.v.s);
3543 val->v.identlist = g_slist_insert_sorted(val->v.identlist,
3544 stralloc(pp_script->name), &compare_pp_script_order);
3545 get_conftoken(CONF_ANY);
3549 conf_parserror(_("pp_script name expected: %d %d"), tok, CONF_STRING);
3556 conf_var_t *np G_GNUC_UNUSED,
3561 get_conftoken(CONF_ANY);
3565 case CONF_PRE_DLE_AMCHECK: val->v.i |= EXECUTE_ON_PRE_DLE_AMCHECK; break;
3566 case CONF_PRE_HOST_AMCHECK: val->v.i |= EXECUTE_ON_PRE_HOST_AMCHECK; break;
3567 case CONF_POST_DLE_AMCHECK: val->v.i |= EXECUTE_ON_POST_DLE_AMCHECK; break;
3568 case CONF_POST_HOST_AMCHECK: val->v.i |= EXECUTE_ON_POST_HOST_AMCHECK; break;
3569 case CONF_PRE_DLE_ESTIMATE: val->v.i |= EXECUTE_ON_PRE_DLE_ESTIMATE; break;
3570 case CONF_PRE_HOST_ESTIMATE: val->v.i |= EXECUTE_ON_PRE_HOST_ESTIMATE; break;
3571 case CONF_POST_DLE_ESTIMATE: val->v.i |= EXECUTE_ON_POST_DLE_ESTIMATE; break;
3572 case CONF_POST_HOST_ESTIMATE: val->v.i |= EXECUTE_ON_POST_HOST_ESTIMATE; break;
3573 case CONF_PRE_DLE_BACKUP: val->v.i |= EXECUTE_ON_PRE_DLE_BACKUP; break;
3574 case CONF_PRE_HOST_BACKUP: val->v.i |= EXECUTE_ON_PRE_HOST_BACKUP; break;
3575 case CONF_POST_DLE_BACKUP: val->v.i |= EXECUTE_ON_POST_DLE_BACKUP; break;
3576 case CONF_POST_HOST_BACKUP: val->v.i |= EXECUTE_ON_POST_HOST_BACKUP; break;
3577 case CONF_PRE_RECOVER: val->v.i |= EXECUTE_ON_PRE_RECOVER; break;
3578 case CONF_POST_RECOVER: val->v.i |= EXECUTE_ON_POST_RECOVER; break;
3579 case CONF_PRE_LEVEL_RECOVER: val->v.i |= EXECUTE_ON_PRE_LEVEL_RECOVER; break;
3580 case CONF_POST_LEVEL_RECOVER: val->v.i |= EXECUTE_ON_POST_LEVEL_RECOVER; break;
3581 case CONF_INTER_LEVEL_RECOVER: val->v.i |= EXECUTE_ON_INTER_LEVEL_RECOVER; break;
3583 conf_parserror(_("Execute_on expected"));
3585 get_conftoken(CONF_ANY);
3586 if (tok != CONF_COMMA) {
3590 get_conftoken(CONF_ANY);
3596 conf_var_t *np G_GNUC_UNUSED,
3601 get_conftoken(CONF_ANY);
3603 case CONF_CLIENT: val->v.i = ES_CLIENT; break;
3604 case CONF_SERVER: val->v.i = ES_SERVER; break;
3606 conf_parserror(_("CLIENT or SERVER expected"));
3612 conf_var_t *np G_GNUC_UNUSED,
3617 get_conftoken(CONF_ANY);
3621 val->v.s = g_strdup_printf("%d", tokenval.v.i);
3626 val->v.s = g_strdup_printf("%zu", tokenval.v.size);
3631 val->v.s = g_strdup_printf("%jd", (intmax_t)tokenval.v.int64);
3635 val->v.s = newstralloc(val->v.s, tokenval.v.s);
3638 conf_parserror(_("CLIENT or SERVER expected"));
3644 conf_var_t *np G_GNUC_UNUSED,
3650 get_conftoken(CONF_ANY);
3651 if (tok == CONF_STRING) {
3653 val->v.autolabel.template = newstralloc(val->v.autolabel.template,
3655 get_conftoken(CONF_ANY);
3657 val->v.autolabel.autolabel = 0;
3658 while (tok != CONF_NL && tok != CONF_END) {
3660 if (tok == CONF_ANY_VOLUME)
3661 val->v.autolabel.autolabel |= AL_OTHER_CONFIG | AL_NON_AMANDA |
3662 AL_VOLUME_ERROR | AL_EMPTY;
3663 else if (tok == CONF_OTHER_CONFIG)
3664 val->v.autolabel.autolabel |= AL_OTHER_CONFIG;
3665 else if (tok == CONF_NON_AMANDA)
3666 val->v.autolabel.autolabel |= AL_NON_AMANDA;
3667 else if (tok == CONF_VOLUME_ERROR)
3668 val->v.autolabel.autolabel |= AL_VOLUME_ERROR;
3669 else if (tok == CONF_EMPTY)
3670 val->v.autolabel.autolabel |= AL_EMPTY;
3672 conf_parserror(_("ANY-VOLUME, NEW-VOLUME, OTHER-CONFIG, NON-AMANDA, VOLUME-ERROR or EMPTY is expected"));
3674 get_conftoken(CONF_ANY);
3677 amfree(val->v.autolabel.template);
3678 val->v.autolabel.autolabel = 0;
3679 } else if (val->v.autolabel.autolabel == 0) {
3680 val->v.autolabel.autolabel = AL_VOLUME_ERROR | AL_EMPTY;
3684 /* get_* functions */
3686 /* these functions use precompiler conditionals to skip useless size checks
3687 * when casting from one type to another. SIZEOF_GINT64 is pretty simple to
3688 * calculate; the others are calculated by configure. */
3690 #define SIZEOF_GINT64 8
3697 get_conftoken(CONF_ANY);
3700 #if SIZEOF_TIME_T < SIZEOF_INT
3701 if ((gint64)tokenval.v.i >= (gint64)TIME_MAX)
3702 conf_parserror(_("value too large"));
3704 hhmm = (time_t)tokenval.v.i;
3708 #if SIZEOF_TIME_T < SIZEOF_SSIZE_T
3709 if ((gint64)tokenval.v.size >= (gint64)TIME_MAX)
3710 conf_parserror(_("value too large"));
3712 hhmm = (time_t)tokenval.v.size;
3716 #if SIZEOF_TIME_T < SIZEOF_GINT64
3717 if ((gint64)tokenval.v.int64 >= (gint64)TIME_MAX)
3718 conf_parserror(_("value too large"));
3720 hhmm = (time_t)tokenval.v.int64;
3723 case CONF_AMINFINITY:
3728 conf_parserror(_("a time is expected"));
3742 keytable = numb_keytable;
3744 get_conftoken(CONF_ANY);
3751 #if SIZEOF_INT < SIZEOF_SSIZE_T
3752 if ((gint64)tokenval.v.size > (gint64)INT_MAX)
3753 conf_parserror(_("value too large"));
3754 if ((gint64)tokenval.v.size < (gint64)INT_MIN)
3755 conf_parserror(_("value too small"));
3757 val = (int)tokenval.v.size;
3761 #if SIZEOF_INT < SIZEOF_GINT64
3762 if (tokenval.v.int64 > (gint64)INT_MAX)
3763 conf_parserror(_("value too large"));
3764 if (tokenval.v.int64 < (gint64)INT_MIN)
3765 conf_parserror(_("value too small"));
3767 val = (int)tokenval.v.int64;
3770 case CONF_AMINFINITY:
3775 conf_parserror(_("an integer is expected"));
3780 /* get multiplier, if any */
3781 get_conftoken(CONF_ANY);
3783 case CONF_NL: /* multiply by one */
3790 if (val > (INT_MAX / 7))
3791 conf_parserror(_("value too large"));
3792 if (val < (INT_MIN / 7))
3793 conf_parserror(_("value too small"));
3798 if (val > (INT_MAX / 1024))
3799 conf_parserror(_("value too large"));
3800 if (val < (INT_MIN / 1024))
3801 conf_parserror(_("value too small"));
3806 if (val > (INT_MAX / (1024 * 1024)))
3807 conf_parserror(_("value too large"));
3808 if (val < (INT_MIN / (1024 * 1024)))
3809 conf_parserror(_("value too small"));
3814 if (val > (INT_MAX / (1024 * 1024 * 1024)))
3815 conf_parserror(_("value too large"));
3816 if (val < (INT_MIN / (1024 * 1024 * 1024)))
3817 conf_parserror(_("value too small"));
3818 val *= 1024 * 1024 * 1024;
3821 default: /* it was not a multiplier */
3837 keytable = numb_keytable;
3839 get_conftoken(CONF_ANY);
3843 val = tokenval.v.size;
3847 #if SIZEOF_SIZE_T < SIZEOF_INT
3848 if ((gint64)tokenval.v.i > (gint64)SSIZE_MAX)
3849 conf_parserror(_("value too large"));
3850 if ((gint64)tokenval.v.i < (gint64)SSIZE_MIN)
3851 conf_parserror(_("value too small"));
3853 val = (ssize_t)tokenval.v.i;
3857 #if SIZEOF_SIZE_T < SIZEOF_GINT64
3858 if (tokenval.v.int64 > (gint64)SSIZE_MAX)
3859 conf_parserror(_("value too large"));
3860 if (tokenval.v.int64 < (gint64)SSIZE_MIN)
3861 conf_parserror(_("value too small"));
3863 val = (ssize_t)tokenval.v.int64;
3866 case CONF_AMINFINITY:
3867 val = (ssize_t)SSIZE_MAX;
3871 conf_parserror(_("an integer is expected"));
3876 /* get multiplier, if any */
3877 get_conftoken(CONF_ANY);
3880 case CONF_NL: /* multiply by one */
3886 if (val > (ssize_t)(SSIZE_MAX / 7))
3887 conf_parserror(_("value too large"));
3888 if (val < (ssize_t)(SSIZE_MIN / 7))
3889 conf_parserror(_("value too small"));
3894 if (val > (ssize_t)(SSIZE_MAX / (ssize_t)1024))
3895 conf_parserror(_("value too large"));
3896 if (val < (ssize_t)(SSIZE_MIN / (ssize_t)1024))
3897 conf_parserror(_("value too small"));
3898 val *= (ssize_t)1024;
3902 if (val > (ssize_t)(SSIZE_MAX / (1024 * 1024)))
3903 conf_parserror(_("value too large"));
3904 if (val < (ssize_t)(SSIZE_MIN / (1024 * 1024)))
3905 conf_parserror(_("value too small"));
3906 val *= (ssize_t)(1024 * 1024);
3910 if (val > (INT_MAX / (1024 * 1024 * 1024)))
3911 conf_parserror(_("value too large"));
3912 if (val < (INT_MIN / (1024 * 1024 * 1024)))
3913 conf_parserror(_("value too small"));
3914 val *= 1024 * 1024 * 1024;
3917 default: /* it was not a multiplier */
3933 keytable = numb_keytable;
3935 get_conftoken(CONF_ANY);
3939 val = (gint64)tokenval.v.i;
3943 val = (gint64)tokenval.v.size;
3947 val = tokenval.v.int64;
3950 case CONF_AMINFINITY:
3955 conf_parserror(_("an integer is expected"));
3960 /* get multiplier, if any */
3961 get_conftoken(CONF_ANY);
3964 case CONF_NL: /* multiply by one */
3970 if (val > G_MAXINT64/7 || val < ((gint64)G_MININT64)/7)
3971 conf_parserror(_("value too large"));
3976 if (val > G_MAXINT64/1024 || val < ((gint64)G_MININT64)/1024)
3977 conf_parserror(_("value too large"));
3982 if (val > G_MAXINT64/(1024*1024) || val < ((gint64)G_MININT64)/(1024*1024))
3983 conf_parserror(_("value too large"));
3988 if (val > G_MAXINT64/(1024*1024*1024) || val < ((gint64)G_MININT64)/(1024*1024*1024))
3989 conf_parserror(_("value too large"));
3990 val *= 1024*1024*1024;
3993 default: /* it was not a multiplier */
4010 keytable = bool_keytable;
4012 get_conftoken(CONF_ANY);
4016 if (tokenval.v.i != 0)
4023 if (tokenval.v.size != (size_t)0)
4030 if (tokenval.v.int64 != (gint64)0)
4046 val = 2; /* no argument - most likely TRUE */
4050 val = 3; /* a bad argument - most likely TRUE */
4051 conf_parserror(_("YES, NO, TRUE, FALSE, ON, OFF, 0, 1 expected"));
4063 if (seen->linenum && !allow_overwrites && current_line_num != -2) {
4064 conf_parserror(_("duplicate parameter; previous definition %s:%d"),
4065 seen->filename, seen->linenum);
4067 seen->filename = current_filename;
4068 seen->linenum = current_line_num;
4071 /* Validation functions */
4074 validate_nonnegative(
4075 struct conf_var_s *np,
4080 if(val_t__int(val) < 0)
4081 conf_parserror(_("%s must be nonnegative"), get_token_name(np->token));
4083 case CONFTYPE_INT64:
4084 if(val_t__int64(val) < 0)
4085 conf_parserror(_("%s must be nonnegative"), get_token_name(np->token));
4088 if(val_t__size(val) < 0)
4089 conf_parserror(_("%s must be positive"), get_token_name(np->token));
4092 conf_parserror(_("validate_nonnegative invalid type %d\n"), val->type);
4098 struct conf_var_s *np,
4103 if(val_t__int(val) < 1)
4104 conf_parserror(_("%s must be positive"), get_token_name(np->token));
4106 case CONFTYPE_INT64:
4107 if(val_t__int64(val) < 1)
4108 conf_parserror(_("%s must be positive"), get_token_name(np->token));
4111 if(val_t__time(val) < 1)
4112 conf_parserror(_("%s must be positive"), get_token_name(np->token));
4115 if(val_t__size(val) < 1)
4116 conf_parserror(_("%s must be positive"), get_token_name(np->token));
4119 conf_parserror(_("validate_positive invalid type %d\n"), val->type);
4124 validate_runspercycle(
4125 struct conf_var_s *np G_GNUC_UNUSED,
4128 if(val_t__int(val) < -1)
4129 conf_parserror(_("runspercycle must be >= -1"));
4133 validate_bumppercent(
4134 struct conf_var_s *np G_GNUC_UNUSED,
4137 if(val_t__int(val) < 0 || val_t__int(val) > 100)
4138 conf_parserror(_("bumppercent must be between 0 and 100"));
4142 validate_inparallel(
4143 struct conf_var_s *np G_GNUC_UNUSED,
4146 if(val_t__int(val) < 1 || val_t__int(val) >MAX_DUMPERS)
4147 conf_parserror(_("inparallel must be between 1 and MAX_DUMPERS (%d)"),
4153 struct conf_var_s *np G_GNUC_UNUSED,
4156 if(val_t__real(val) < 0.999) {
4157 conf_parserror(_("bumpmult must one or more"));
4162 validate_displayunit(
4163 struct conf_var_s *np G_GNUC_UNUSED,
4164 val_t *val G_GNUC_UNUSED)
4166 char *s = val_t__str(val);
4167 if (strlen(s) == 1) {
4173 return; /* all good */
4175 /* lower-case values should get folded to upper case */
4180 s[0] = toupper(s[0]);
4187 conf_parserror(_("displayunit must be k,m,g or t."));
4192 struct conf_var_s *np G_GNUC_UNUSED,
4195 if(val_t__int(val) < 0 || val_t__int(val) > 100)
4196 conf_parserror(_("reserve must be between 0 and 100"));
4201 struct conf_var_s *np G_GNUC_UNUSED,
4204 val_t__int64(val) = am_floor(val_t__int64(val), DISK_BLOCK_KB);
4209 struct conf_var_s *np G_GNUC_UNUSED,
4212 /* NOTE: this function modifies the target value (rounding) */
4213 if(val_t__int64(val) == 0) {
4214 val_t__int64(val) = ((G_MAXINT64 / 1024) - (2 * DISK_BLOCK_KB));
4216 else if(val_t__int64(val) < 0) {
4217 conf_parserror(_("Negative chunksize (%lld) is no longer supported"), (long long)val_t__int64(val));
4219 val_t__int64(val) = am_floor(val_t__int64(val), (gint64)DISK_BLOCK_KB);
4220 if (val_t__int64(val) < 2*DISK_BLOCK_KB) {
4221 conf_parserror("chunksize must be at least %dkb", 2*DISK_BLOCK_KB);
4227 struct conf_var_s *np G_GNUC_UNUSED,
4230 if(val_t__size(val) < DISK_BLOCK_KB) {
4231 conf_parserror(_("Tape blocksize must be at least %d KBytes"),
4238 struct conf_var_s *np G_GNUC_UNUSED,
4241 if(val_t__int(val) < 0 || val_t__int(val) > 9) {
4242 conf_parserror(_("Debug must be between 0 and 9"));
4247 validate_port_range(
4253 /* check both values are in range */
4254 for (i = 0; i < 2; i++) {
4255 if(val_t__intrange(val)[0] < smallest || val_t__intrange(val)[0] > largest) {
4256 conf_parserror(_("portrange must be in the range %d to %d, inclusive"), smallest, largest);
4260 /* and check they're in the right order and not equal */
4261 if (val_t__intrange(val)[0] > val_t__intrange(val)[1]) {
4262 conf_parserror(_("portranges must be in order from low to high"));
4267 validate_reserved_port_range(
4268 struct conf_var_s *np G_GNUC_UNUSED,
4271 validate_port_range(val, 1, IPPORT_RESERVED-1);
4275 validate_unreserved_port_range(
4276 struct conf_var_s *np G_GNUC_UNUSED,
4279 validate_port_range(val, IPPORT_RESERVED, 65535);
4283 * Initialization Implementation
4288 config_init_flags flags,
4289 char *arg_config_name)
4291 if (!(flags & CONFIG_INIT_OVERLAY)) {
4292 /* Clear out anything that's already in there */
4295 /* and set everything to default values */
4298 allow_overwrites = FALSE;
4300 if (!config_initialized) {
4301 error(_("Attempt to overlay configuration with no existing configuration"));
4305 allow_overwrites = TRUE;
4308 /* store away our client-ness for later reference */
4309 config_client = flags & CONFIG_INIT_CLIENT;
4311 /* if we're using an explicit name, but the name is '.', then we're using the
4312 * current directory */
4313 if ((flags & CONFIG_INIT_EXPLICIT_NAME) && arg_config_name) {
4314 if (0 == strcmp(arg_config_name, "."))
4315 flags = (flags & (~CONFIG_INIT_EXPLICIT_NAME)) | CONFIG_INIT_USE_CWD;
4318 if ((flags & CONFIG_INIT_EXPLICIT_NAME) && arg_config_name) {
4319 config_name = newstralloc(config_name, arg_config_name);
4320 config_dir = newvstralloc(config_dir, CONFIG_DIR, "/", arg_config_name, NULL);
4321 } else if (flags & CONFIG_INIT_USE_CWD) {
4324 cwd = get_original_cwd();
4326 /* (this isn't a config error, so it's always fatal) */
4327 error(_("Cannot determine current working directory"));
4331 config_dir = stralloc2(cwd, "/");
4332 if ((config_name = strrchr(cwd, '/')) != NULL) {
4333 config_name = stralloc(config_name + 1);
4337 } else if (flags & CONFIG_INIT_CLIENT) {
4338 amfree(config_name);
4339 config_dir = newstralloc(config_dir, CONFIG_DIR);
4341 /* ok, then, we won't read anything (for e.g., amrestore) */
4342 amfree(config_name);
4346 /* setup for apply_config_overrides */
4347 if (flags & CONFIG_INIT_CLIENT) {
4348 keytable = client_keytab;
4349 parsetable = client_var;
4351 keytable = server_keytab;
4352 parsetable = server_var;
4355 if (config_overrides) {
4357 for (i = 0; i < config_overrides->n_used; i++) {
4358 config_overrides->ovr[i].applied = FALSE;
4362 /* apply config overrides to default setting */
4363 apply_config_overrides(config_overrides, NULL);
4365 /* If we have a config_dir, we can try reading something */
4367 if (flags & CONFIG_INIT_CLIENT) {
4368 config_filename = newvstralloc(config_filename, config_dir, "/amanda-client.conf", NULL);
4370 config_filename = newvstralloc(config_filename, config_dir, "/amanda.conf", NULL);
4373 read_conffile(config_filename,
4374 flags & CONFIG_INIT_CLIENT,
4375 flags & CONFIG_INIT_CLIENT);
4377 amfree(config_filename);
4380 /* apply config overrides to default setting */
4381 apply_config_overrides(config_overrides, NULL);
4383 if (config_overrides) {
4385 for (i = 0; i < config_overrides->n_used; i++) {
4386 if (config_overrides->ovr[i].applied == FALSE) {
4387 conf_parserror(_("unknown parameter '%s'"),
4388 config_overrides->ovr[i].key);
4393 update_derived_values(flags & CONFIG_INIT_CLIENT);
4395 return cfgerr_level;
4403 dumptype_t *dp, *dpnext;
4404 tapetype_t *tp, *tpnext;
4405 interface_t *ip, *ipnext;
4406 application_t *ap, *apnext;
4407 pp_script_t *pp, *ppnext;
4408 device_config_t *dc, *dcnext;
4409 changer_config_t *cc, *ccnext;
4412 if (!config_initialized) return;
4414 for(hp=holdinglist; hp != NULL; hp = hp->next) {
4417 for(i=0; i<HOLDING_HOLDING; i++) {
4418 free_val_t(&hd->value[i]);
4421 g_slist_free_full(holdinglist);
4424 for(dp=dumplist; dp != NULL; dp = dpnext) {
4426 for(i=0; i<DUMPTYPE_DUMPTYPE; i++) {
4427 free_val_t(&dp->value[i]);
4434 for(tp=tapelist; tp != NULL; tp = tpnext) {
4436 for(i=0; i<TAPETYPE_TAPETYPE; i++) {
4437 free_val_t(&tp->value[i]);
4444 for(ip=interface_list; ip != NULL; ip = ipnext) {
4446 for(i=0; i<INTER_INTER; i++) {
4447 free_val_t(&ip->value[i]);
4452 interface_list = NULL;
4454 for(ap=application_list; ap != NULL; ap = apnext) {
4456 for(i=0; i<APPLICATION_APPLICATION; i++) {
4457 free_val_t(&ap->value[i]);
4462 application_list = NULL;
4464 for(pp=pp_script_list; pp != NULL; pp = ppnext) {
4466 for(i=0; i<PP_SCRIPT_PP_SCRIPT; i++) {
4467 free_val_t(&pp->value[i]);
4472 pp_script_list = NULL;
4474 for(dc=device_config_list; dc != NULL; dc = dcnext) {
4476 for(i=0; i<DEVICE_CONFIG_DEVICE_CONFIG; i++) {
4477 free_val_t(&dc->value[i]);
4482 device_config_list = NULL;
4484 for(cc=changer_config_list; cc != NULL; cc = ccnext) {
4486 for(i=0; i<CHANGER_CONFIG_CHANGER_CONFIG; i++) {
4487 free_val_t(&cc->value[i]);
4493 changer_config_list = NULL;
4495 for(i=0; i<CNF_CNF; i++)
4496 free_val_t(&conf_data[i]);
4498 if (config_overrides) {
4499 free_config_overrides(config_overrides);
4500 config_overrides = NULL;
4503 amfree(config_name);
4505 amfree(config_filename);
4507 g_slist_free_full(seen_filenames);
4508 seen_filenames = NULL;
4510 config_client = FALSE;
4512 config_clear_errors();
4513 config_initialized = FALSE;
4520 assert(!config_initialized);
4522 /* defaults for exported variables */
4523 conf_init_str(&conf_data[CNF_ORG], DEFAULT_CONFIG);
4524 conf_init_str(&conf_data[CNF_CONF], DEFAULT_CONFIG);
4525 conf_init_str(&conf_data[CNF_INDEX_SERVER], DEFAULT_SERVER);
4526 conf_init_str(&conf_data[CNF_TAPE_SERVER], DEFAULT_TAPE_SERVER);
4527 conf_init_str(&conf_data[CNF_AUTH], "bsd");
4528 conf_init_str(&conf_data[CNF_SSH_KEYS], "");
4529 conf_init_str(&conf_data[CNF_AMANDAD_PATH], "");
4530 conf_init_str(&conf_data[CNF_CLIENT_USERNAME], "");
4531 conf_init_str(&conf_data[CNF_CLIENT_PORT], "");
4532 conf_init_str(&conf_data[CNF_GNUTAR_LIST_DIR], GNUTAR_LISTED_INCREMENTAL_DIR);
4533 conf_init_str(&conf_data[CNF_AMANDATES], DEFAULT_AMANDATES_FILE);
4534 conf_init_str(&conf_data[CNF_MAILTO], "");
4535 conf_init_str(&conf_data[CNF_DUMPUSER], CLIENT_LOGIN);
4536 conf_init_str(&conf_data[CNF_TAPEDEV], DEFAULT_TAPE_DEVICE);
4537 conf_init_proplist(&conf_data[CNF_DEVICE_PROPERTY]);
4538 conf_init_proplist(&conf_data[CNF_PROPERTY]);
4539 conf_init_str(&conf_data[CNF_CHANGERDEV], NULL);
4540 conf_init_str(&conf_data[CNF_CHANGERFILE] , "changer");
4541 conf_init_str (&conf_data[CNF_LABELSTR] , ".*");
4542 conf_init_str (&conf_data[CNF_TAPELIST] , "tapelist");
4543 conf_init_str (&conf_data[CNF_DISKFILE] , "disklist");
4544 conf_init_str (&conf_data[CNF_INFOFILE] , "/usr/adm/amanda/curinfo");
4545 conf_init_str (&conf_data[CNF_LOGDIR] , "/usr/adm/amanda");
4546 conf_init_str (&conf_data[CNF_INDEXDIR] , "/usr/adm/amanda/index");
4547 conf_init_ident (&conf_data[CNF_TAPETYPE] , "DEFAULT_TAPE");
4548 conf_init_identlist(&conf_data[CNF_HOLDINGDISK] , NULL);
4549 conf_init_int (&conf_data[CNF_DUMPCYCLE] , 10);
4550 conf_init_int (&conf_data[CNF_RUNSPERCYCLE] , 0);
4551 conf_init_int (&conf_data[CNF_TAPECYCLE] , 15);
4552 conf_init_int (&conf_data[CNF_NETUSAGE] , 8000);
4553 conf_init_int (&conf_data[CNF_INPARALLEL] , 10);
4554 conf_init_str (&conf_data[CNF_DUMPORDER] , "ttt");
4555 conf_init_int (&conf_data[CNF_BUMPPERCENT] , 0);
4556 conf_init_int64 (&conf_data[CNF_BUMPSIZE] , (gint64)10*1024);
4557 conf_init_real (&conf_data[CNF_BUMPMULT] , 1.5);
4558 conf_init_int (&conf_data[CNF_BUMPDAYS] , 2);
4559 conf_init_str (&conf_data[CNF_TPCHANGER] , "");
4560 conf_init_int (&conf_data[CNF_RUNTAPES] , 1);
4561 conf_init_int (&conf_data[CNF_MAXDUMPS] , 1);
4562 conf_init_int (&conf_data[CNF_ETIMEOUT] , 300);
4563 conf_init_int (&conf_data[CNF_DTIMEOUT] , 1800);
4564 conf_init_int (&conf_data[CNF_CTIMEOUT] , 30);
4565 conf_init_int (&conf_data[CNF_TAPEBUFS] , 20);
4566 conf_init_size (&conf_data[CNF_DEVICE_OUTPUT_BUFFER_SIZE], 40*32768);
4567 conf_init_str (&conf_data[CNF_PRINTER] , "");
4568 conf_init_str (&conf_data[CNF_MAILER] , DEFAULT_MAILER);
4569 conf_init_bool (&conf_data[CNF_AUTOFLUSH] , 0);
4570 conf_init_int (&conf_data[CNF_RESERVE] , 100);
4571 conf_init_int64 (&conf_data[CNF_MAXDUMPSIZE] , (gint64)-1);
4572 conf_init_str (&conf_data[CNF_COLUMNSPEC] , "");
4573 conf_init_bool (&conf_data[CNF_AMRECOVER_DO_FSF] , 1);
4574 conf_init_str (&conf_data[CNF_AMRECOVER_CHANGER] , "");
4575 conf_init_bool (&conf_data[CNF_AMRECOVER_CHECK_LABEL], 1);
4576 conf_init_taperalgo(&conf_data[CNF_TAPERALGO] , 0);
4577 conf_init_int (&conf_data[CNF_FLUSH_THRESHOLD_DUMPED] , 0);
4578 conf_init_int (&conf_data[CNF_FLUSH_THRESHOLD_SCHEDULED], 0);
4579 conf_init_int (&conf_data[CNF_TAPERFLUSH] , 0);
4580 conf_init_str (&conf_data[CNF_DISPLAYUNIT] , "k");
4581 conf_init_str (&conf_data[CNF_KRB5KEYTAB] , "/.amanda-v5-keytab");
4582 conf_init_str (&conf_data[CNF_KRB5PRINCIPAL] , "service/amanda");
4583 conf_init_str (&conf_data[CNF_LABEL_NEW_TAPES] , "");
4584 conf_init_bool (&conf_data[CNF_USETIMESTAMPS] , 1);
4585 conf_init_int (&conf_data[CNF_CONNECT_TRIES] , 3);
4586 conf_init_int (&conf_data[CNF_REP_TRIES] , 5);
4587 conf_init_int (&conf_data[CNF_REQ_TRIES] , 3);
4588 conf_init_int (&conf_data[CNF_DEBUG_DAYS] , AMANDA_DEBUG_DAYS);
4589 conf_init_int (&conf_data[CNF_DEBUG_AMANDAD] , 0);
4590 conf_init_int (&conf_data[CNF_DEBUG_RECOVERY] , 0);
4591 conf_init_int (&conf_data[CNF_DEBUG_AMIDXTAPED] , 0);
4592 conf_init_int (&conf_data[CNF_DEBUG_AMINDEXD] , 0);
4593 conf_init_int (&conf_data[CNF_DEBUG_AMRECOVER] , 0);
4594 conf_init_int (&conf_data[CNF_DEBUG_AUTH] , 0);
4595 conf_init_int (&conf_data[CNF_DEBUG_EVENT] , 0);
4596 conf_init_int (&conf_data[CNF_DEBUG_HOLDING] , 0);
4597 conf_init_int (&conf_data[CNF_DEBUG_PROTOCOL] , 0);
4598 conf_init_int (&conf_data[CNF_DEBUG_PLANNER] , 0);
4599 conf_init_int (&conf_data[CNF_DEBUG_DRIVER] , 0);
4600 conf_init_int (&conf_data[CNF_DEBUG_DUMPER] , 0);
4601 conf_init_int (&conf_data[CNF_DEBUG_CHUNKER] , 0);
4602 conf_init_int (&conf_data[CNF_DEBUG_TAPER] , 0);
4603 conf_init_int (&conf_data[CNF_DEBUG_SELFCHECK] , 0);
4604 conf_init_int (&conf_data[CNF_DEBUG_SENDSIZE] , 0);
4605 conf_init_int (&conf_data[CNF_DEBUG_SENDBACKUP] , 0);
4607 conf_init_intrange (&conf_data[CNF_RESERVED_UDP_PORT] , UDPPORTRANGE);
4609 conf_init_intrange (&conf_data[CNF_RESERVED_UDP_PORT] , 512, IPPORT_RESERVED-1);
4611 #ifdef LOW_TCPPORTRANGE
4612 conf_init_intrange (&conf_data[CNF_RESERVED_TCP_PORT] , LOW_TCPPORTRANGE);
4614 conf_init_intrange (&conf_data[CNF_RESERVED_TCP_PORT] , 512, IPPORT_RESERVED-1);
4617 conf_init_intrange (&conf_data[CNF_UNRESERVED_TCP_PORT] , TCPPORTRANGE);
4619 conf_init_intrange (&conf_data[CNF_UNRESERVED_TCP_PORT] , IPPORT_RESERVED, 65535);
4621 conf_init_send_amreport (&conf_data[CNF_SEND_AMREPORT_ON], SEND_AMREPORT_ALL);
4622 conf_init_autolabel(&conf_data[CNF_AUTOLABEL]);
4624 /* reset internal variables */
4625 config_clear_errors();
4626 cfgerr_level = CFGERR_OK;
4627 allow_overwrites = 0;
4630 /* create some predefined dumptypes for backwards compatability */
4631 init_dumptype_defaults();
4632 dpcur.name = stralloc("NO-COMPRESS");
4633 dpcur.seen.linenum = -1;
4634 free_val_t(&dpcur.value[DUMPTYPE_COMPRESS]);
4635 val_t__compress(&dpcur.value[DUMPTYPE_COMPRESS]) = COMP_NONE;
4636 val_t__seen(&dpcur.value[DUMPTYPE_COMPRESS]).linenum = -1;
4639 init_dumptype_defaults();
4640 dpcur.name = stralloc("COMPRESS-FAST");
4641 dpcur.seen.linenum = -1;
4642 free_val_t(&dpcur.value[DUMPTYPE_COMPRESS]);
4643 val_t__compress(&dpcur.value[DUMPTYPE_COMPRESS]) = COMP_FAST;
4644 val_t__seen(&dpcur.value[DUMPTYPE_COMPRESS]).linenum = -1;
4647 init_dumptype_defaults();
4648 dpcur.name = stralloc("COMPRESS-BEST");
4649 dpcur.seen.linenum = -1;
4650 free_val_t(&dpcur.value[DUMPTYPE_COMPRESS]);
4651 val_t__compress(&dpcur.value[DUMPTYPE_COMPRESS]) = COMP_BEST;
4652 val_t__seen(&dpcur.value[DUMPTYPE_COMPRESS]).linenum = -1;
4655 init_dumptype_defaults();
4656 dpcur.name = stralloc("COMPRESS-CUST");
4657 dpcur.seen.linenum = -1;
4658 free_val_t(&dpcur.value[DUMPTYPE_COMPRESS]);
4659 val_t__compress(&dpcur.value[DUMPTYPE_COMPRESS]) = COMP_CUST;
4660 val_t__seen(&dpcur.value[DUMPTYPE_COMPRESS]).linenum = -1;
4663 init_dumptype_defaults();
4664 dpcur.name = stralloc("SRVCOMPRESS");
4665 dpcur.seen.linenum = -1;
4666 free_val_t(&dpcur.value[DUMPTYPE_COMPRESS]);
4667 val_t__compress(&dpcur.value[DUMPTYPE_COMPRESS]) = COMP_SERVER_FAST;
4668 val_t__seen(&dpcur.value[DUMPTYPE_COMPRESS]).linenum = -1;
4671 init_dumptype_defaults();
4672 dpcur.name = stralloc("BSD-AUTH");
4673 dpcur.seen.linenum = -1;
4674 free_val_t(&dpcur.value[DUMPTYPE_AUTH]);
4675 val_t__str(&dpcur.value[DUMPTYPE_AUTH]) = stralloc("BSD");
4676 val_t__seen(&dpcur.value[DUMPTYPE_AUTH]).linenum = -1;
4679 init_dumptype_defaults();
4680 dpcur.name = stralloc("NO-RECORD");
4681 dpcur.seen.linenum = -1;
4682 free_val_t(&dpcur.value[DUMPTYPE_RECORD]);
4683 val_t__int(&dpcur.value[DUMPTYPE_RECORD]) = 0;
4684 val_t__seen(&dpcur.value[DUMPTYPE_RECORD]).linenum = -1;
4687 init_dumptype_defaults();
4688 dpcur.name = stralloc("NO-HOLD");
4689 dpcur.seen.linenum = -1;
4690 free_val_t(&dpcur.value[DUMPTYPE_HOLDINGDISK]);
4691 val_t__holding(&dpcur.value[DUMPTYPE_HOLDINGDISK]) = HOLD_NEVER;
4692 val_t__seen(&dpcur.value[DUMPTYPE_HOLDINGDISK]).linenum = -1;
4695 init_dumptype_defaults();
4696 dpcur.name = stralloc("NO-FULL");
4697 dpcur.seen.linenum = -1;
4698 free_val_t(&dpcur.value[DUMPTYPE_STRATEGY]);
4699 val_t__strategy(&dpcur.value[DUMPTYPE_STRATEGY]) = DS_NOFULL;
4700 val_t__seen(&dpcur.value[DUMPTYPE_STRATEGY]).linenum = -1;
4703 /* And we're initialized! */
4704 config_initialized = 1;
4711 char **config_options;
4712 char **config_option;
4713 int n_config_overrides = 0;
4716 if (config_overrides)
4717 n_config_overrides = config_overrides->n_used;
4719 config_options = alloc((first+n_config_overrides+1)*SIZEOF(char *));
4720 config_option = config_options + first;
4722 for (i = 0; i < n_config_overrides; i++) {
4723 char *key = config_overrides->ovr[i].key;
4724 char *value = config_overrides->ovr[i].value;
4725 *config_option = vstralloc("-o", key, "=", value, NULL);
4729 *config_option = NULL; /* add terminating sentinel */
4731 return config_options;
4735 update_derived_values(
4743 /* Add a 'default' interface if one doesn't already exist */
4744 if (!(ip = lookup_interface("default"))) {
4745 init_interface_defaults();
4746 ifcur.name = stralloc("default");
4747 ifcur.seen = val_t__seen(getconf(CNF_NETUSAGE));
4750 ip = lookup_interface("default");
4753 /* .. and set its maxusage from 'netusage' */
4754 if (!interface_seen(ip, INTER_MAXUSAGE)) {
4757 v = interface_getconf(ip, INTER_COMMENT);
4759 val_t__str(v) = stralloc(_("implicit from NETUSAGE"));
4760 val_t__seen(v) = val_t__seen(getconf(CNF_NETUSAGE));
4762 v = interface_getconf(ip, INTER_MAXUSAGE);
4764 val_t__int(v) = getconf_int(CNF_NETUSAGE);
4765 val_t__seen(v) = val_t__seen(getconf(CNF_NETUSAGE));
4768 /* Check the tapetype is defined */
4769 if (lookup_tapetype(getconf_str(CNF_TAPETYPE)) == NULL) {
4770 /* Create a default tapetype so that other code has
4771 * something to refer to, but don't pretend it's real */
4772 if (!getconf_seen(CNF_TAPETYPE) &&
4773 strcmp(getconf_str(CNF_TAPETYPE), "DEFAULT_TAPE") == 0 &&
4774 !lookup_tapetype("DEFAULT_TAPE")) {
4775 init_tapetype_defaults();
4776 tpcur.name = stralloc("DEFAULT_TAPE");
4777 tpcur.seen = val_t__seen(getconf(CNF_TAPETYPE));
4780 conf_parserror(_("tapetype %s is not defined"),
4781 getconf_str(CNF_TAPETYPE));
4785 /* Check the holdingdisk are defined */
4786 for (il = getconf_identlist(CNF_HOLDINGDISK);
4787 il != NULL; il = il->next) {
4788 hd = lookup_holdingdisk(il->data);
4790 conf_parserror(_("holdingdisk %s is not defined"),
4795 if ((getconf_seen(CNF_LABEL_NEW_TAPES) > 0 &&
4796 getconf_seen(CNF_AUTOLABEL) > 0) ||
4797 (getconf_seen(CNF_LABEL_NEW_TAPES) < 0 &&
4798 getconf_seen(CNF_AUTOLABEL) < 0)) {
4799 conf_parserror(_("Can't specify both label_new_tapes and autolabel"));
4801 if ((getconf_seen(CNF_LABEL_NEW_TAPES) != 0 &&
4802 getconf_seen(CNF_AUTOLABEL) == 0) ||
4803 (getconf_seen(CNF_LABEL_NEW_TAPES) < 0 &&
4804 getconf_seen(CNF_AUTOLABEL) >= 0)) {
4805 autolabel_t *autolabel = &(conf_data[CNF_AUTOLABEL].v.autolabel);
4806 autolabel->template = g_strdup(getconf_str(CNF_LABEL_NEW_TAPES));
4807 if (!autolabel->template || autolabel->template == '\0') {
4808 autolabel->template = NULL;
4809 autolabel->autolabel = 0;
4811 autolabel->autolabel = AL_VOLUME_ERROR | AL_EMPTY;
4816 /* fill in the debug_* values */
4817 debug_amandad = getconf_int(CNF_DEBUG_AMANDAD);
4818 debug_recovery = getconf_int(CNF_DEBUG_RECOVERY);
4819 debug_amidxtaped = getconf_int(CNF_DEBUG_AMIDXTAPED);
4820 debug_amindexd = getconf_int(CNF_DEBUG_AMINDEXD);
4821 debug_amrecover = getconf_int(CNF_DEBUG_AMRECOVER);
4822 debug_auth = getconf_int(CNF_DEBUG_AUTH);
4823 debug_event = getconf_int(CNF_DEBUG_EVENT);
4824 debug_holding = getconf_int(CNF_DEBUG_HOLDING);
4825 debug_protocol = getconf_int(CNF_DEBUG_PROTOCOL);
4826 debug_planner = getconf_int(CNF_DEBUG_PLANNER);
4827 debug_driver = getconf_int(CNF_DEBUG_DRIVER);
4828 debug_dumper = getconf_int(CNF_DEBUG_DUMPER);
4829 debug_chunker = getconf_int(CNF_DEBUG_CHUNKER);
4830 debug_taper = getconf_int(CNF_DEBUG_TAPER);
4831 debug_selfcheck = getconf_int(CNF_DEBUG_SELFCHECK);
4832 debug_sendsize = getconf_int(CNF_DEBUG_SENDSIZE);
4833 debug_sendbackup = getconf_int(CNF_DEBUG_SENDBACKUP);
4835 /* And finally, display unit */
4836 switch (getconf_str(CNF_DISPLAYUNIT)[0]) {
4844 unit_divisor = 1024;
4849 unit_divisor = 1024*1024;
4854 unit_divisor = 1024*1024*1024;
4858 error(_("Invalid displayunit missed by validate_displayunit"));
4868 val->seen.linenum = 0;
4869 val->seen.filename = NULL;
4870 val->type = CONFTYPE_INT;
4871 val_t__int(val) = i;
4879 val->seen.linenum = 0;
4880 val->seen.filename = NULL;
4881 val->type = CONFTYPE_INT64;
4882 val_t__int64(val) = l;
4890 val->seen.linenum = 0;
4891 val->seen.filename = NULL;
4892 val->type = CONFTYPE_REAL;
4893 val_t__real(val) = r;
4901 val->seen.linenum = 0;
4902 val->seen.filename = NULL;
4903 val->type = CONFTYPE_STR;
4905 val->v.s = stralloc(s);
4915 val->seen.linenum = 0;
4916 val->seen.filename = NULL;
4917 val->type = CONFTYPE_IDENT;
4919 val->v.s = stralloc(s);
4925 conf_init_identlist(
4929 val->seen.linenum = 0;
4930 val->seen.filename = NULL;
4931 val->type = CONFTYPE_IDENTLIST;
4932 val->v.identlist = NULL;
4934 val->v.identlist = g_slist_append(val->v.identlist, stralloc(s));
4942 val->seen.linenum = 0;
4943 val->seen.filename = NULL;
4944 val->type = CONFTYPE_TIME;
4945 val_t__time(val) = t;
4953 val->seen.linenum = 0;
4954 val->seen.filename = NULL;
4955 val->type = CONFTYPE_SIZE;
4956 val_t__size(val) = sz;
4964 val->seen.linenum = 0;
4965 val->seen.filename = NULL;
4966 val->type = CONFTYPE_BOOLEAN;
4967 val_t__boolean(val) = i;
4975 val->seen.linenum = 0;
4976 val->seen.filename = NULL;
4977 val->type = CONFTYPE_COMPRESS;
4978 val_t__compress(val) = (int)i;
4986 val->seen.linenum = 0;
4987 val->seen.filename = NULL;
4988 val->type = CONFTYPE_ENCRYPT;
4989 val_t__encrypt(val) = (int)i;
4993 conf_init_data_path(
4997 val->seen.linenum = 0;
4998 val->seen.filename = NULL;
4999 val->type = CONFTYPE_DATA_PATH;
5000 val_t__encrypt(val) = (int)i;
5006 dump_holdingdisk_t i)
5008 val->seen.linenum = 0;
5009 val->seen.filename = NULL;
5010 val->type = CONFTYPE_HOLDING;
5011 val_t__holding(val) = (int)i;
5015 conf_init_estimatelist(
5019 GSList *estimates = NULL;
5020 val->seen.linenum = 0;
5021 val->seen.filename = NULL;
5022 val->type = CONFTYPE_ESTIMATELIST;
5023 estimates = g_slist_append(estimates, GINT_TO_POINTER(i));
5024 val_t__estimatelist(val) = estimates;
5032 val->seen.linenum = 0;
5033 val->seen.filename = NULL;
5034 val->type = CONFTYPE_STRATEGY;
5035 val_t__strategy(val) = i;
5039 conf_init_taperalgo(
5043 val->seen.linenum = 0;
5044 val->seen.filename = NULL;
5045 val->type = CONFTYPE_TAPERALGO;
5046 val_t__taperalgo(val) = i;
5054 val->seen.linenum = 0;
5055 val->seen.filename = NULL;
5056 val->type = CONFTYPE_PRIORITY;
5057 val_t__priority(val) = i;
5066 val->seen.linenum = 0;
5067 val->seen.filename = NULL;
5068 val->type = CONFTYPE_RATE;
5069 val_t__rate(val)[0] = r1;
5070 val_t__rate(val)[1] = r2;
5074 conf_init_exinclude(
5077 val->seen.linenum = 0;
5078 val->seen.filename = NULL;
5079 val->type = CONFTYPE_EXINCLUDE;
5080 val_t__exinclude(val).optional = 0;
5081 val_t__exinclude(val).sl_list = NULL;
5082 val_t__exinclude(val).sl_file = NULL;
5091 val->seen.linenum = 0;
5092 val->seen.filename = NULL;
5093 val->type = CONFTYPE_INTRANGE;
5094 val_t__intrange(val)[0] = i1;
5095 val_t__intrange(val)[1] = i2;
5099 conf_init_autolabel(
5101 val->seen.linenum = 0;
5102 val->seen.filename = NULL;
5103 val->type = CONFTYPE_AUTOLABEL;
5104 val->v.autolabel.template = NULL;
5105 val->v.autolabel.autolabel = 0;
5112 property_t *propery = (property_t *)p;
5113 g_slist_free_full(propery->values);
5121 val->seen.linenum = 0;
5122 val->seen.filename = NULL;
5123 val->type = CONFTYPE_PROPLIST;
5124 val_t__proplist(val) =
5125 g_hash_table_new_full(g_str_hash, g_str_equal, &g_free, &free_property_t);
5129 conf_init_execute_on(
5133 val->seen.linenum = 0;
5134 val->seen.filename = NULL;
5135 val->type = CONFTYPE_EXECUTE_ON;
5140 conf_init_execute_where(
5144 val->seen.linenum = 0;
5145 val->seen.filename = NULL;
5146 val->type = CONFTYPE_EXECUTE_WHERE;
5151 conf_init_send_amreport(
5155 val->seen.linenum = 0;
5156 val->seen.filename = NULL;
5157 val->type = CONFTYPE_SEND_AMREPORT_ON;
5161 static void conf_init_application(val_t *val) {
5162 val->seen.linenum = 0;
5163 val->seen.filename = NULL;
5164 val->type = CONFTYPE_APPLICATION;
5170 * Config access implementation
5174 getconf(confparm_key key)
5176 assert(key < CNF_CNF);
5177 return &conf_data[key];
5191 device_config_t *dc;
5192 changer_config_t *cc;
5195 if (strcasecmp(listname,"tapetype") == 0) {
5196 for(tp = tapelist; tp != NULL; tp=tp->next) {
5197 rv = g_slist_append(rv, tp->name);
5199 } else if (strcasecmp(listname,"dumptype") == 0) {
5200 for(dp = dumplist; dp != NULL; dp=dp->next) {
5201 rv = g_slist_append(rv, dp->name);
5203 } else if (strcasecmp(listname,"holdingdisk") == 0) {
5204 for(hp = holdinglist; hp != NULL; hp=hp->next) {
5206 rv = g_slist_append(rv, hd->name);
5208 } else if (strcasecmp(listname,"interface") == 0) {
5209 for(ip = interface_list; ip != NULL; ip=ip->next) {
5210 rv = g_slist_append(rv, ip->name);
5212 } else if (strcasecmp(listname,"application_tool") == 0
5213 || strcasecmp(listname,"application-tool") == 0
5214 || strcasecmp(listname,"application") == 0) {
5215 for(ap = application_list; ap != NULL; ap=ap->next) {
5216 rv = g_slist_append(rv, ap->name);
5218 } else if (strcasecmp(listname,"script_tool") == 0
5219 || strcasecmp(listname,"script-tool") == 0
5220 || strcasecmp(listname,"script") == 0) {
5221 for(pp = pp_script_list; pp != NULL; pp=pp->next) {
5222 rv = g_slist_append(rv, pp->name);
5224 } else if (strcasecmp(listname,"device") == 0) {
5225 for(dc = device_config_list; dc != NULL; dc=dc->next) {
5226 rv = g_slist_append(rv, dc->name);
5228 } else if (strcasecmp(listname,"changer") == 0) {
5229 for(cc = changer_config_list; cc != NULL; cc=cc->next) {
5230 rv = g_slist_append(rv, cc->name);
5242 if (!parm_key_info(key, NULL, &rv))
5254 for(p = tapelist; p != NULL; p = p->next) {
5255 if(strcasecmp(p->name, str) == 0) return p;
5265 assert(ttyp != NULL);
5266 assert(key < TAPETYPE_TAPETYPE);
5267 return &ttyp->value[key];
5272 conf_var_t *np G_GNUC_UNUSED,
5275 if (strcmp(val->v.s, "DUMP") != 0 &&
5276 strcmp(val->v.s, "GNUTAR") != 0 &&
5277 strcmp(val->v.s, "STAR") != 0 &&
5278 strcmp(val->v.s, "APPLICATION") != 0)
5279 conf_parserror("program must be \"DUMP\", \"GNUTAR\", \"STAR\" or \"APPLICATION\"");
5286 assert(ttyp != NULL);
5296 for(p = dumplist; p != NULL; p = p->next) {
5297 if(strcasecmp(p->name, str) == 0) return p;
5307 assert(dtyp != NULL);
5308 assert(key < DUMPTYPE_DUMPTYPE);
5309 return &dtyp->value[key];
5316 assert(dtyp != NULL);
5326 for(p = interface_list; p != NULL; p = p->next) {
5327 if(strcasecmp(p->name, str) == 0) return p;
5337 assert(iface != NULL);
5338 assert(key < INTER_INTER);
5339 return &iface->value[key];
5346 assert(iface != NULL);
5357 for (hp = holdinglist; hp != NULL; hp = hp->next) {
5359 if (strcasecmp(hd->name, str) == 0) return hd;
5365 getconf_holdingdisks(
5372 holdingdisk_getconf(
5373 holdingdisk_t *hdisk,
5374 holdingdisk_key key)
5376 assert(hdisk != NULL);
5377 assert(key < HOLDING_HOLDING);
5378 return &hdisk->value[key];
5383 holdingdisk_t *hdisk)
5385 assert(hdisk != NULL);
5395 for(p = application_list; p != NULL; p = p->next) {
5396 if(strcasecmp(p->name, str) == 0) return p;
5402 application_getconf(
5404 application_key key)
5407 assert(key < APPLICATION_APPLICATION);
5408 return &ap->value[key];
5425 for(pps = pp_script_list; pps != NULL; pps = pps->next) {
5426 if(strcasecmp(pps->name, str) == 0) return pps;
5436 assert(pps != NULL);
5437 assert(key < PP_SCRIPT_PP_SCRIPT);
5438 return &pps->value[key];
5445 assert(pps != NULL);
5450 lookup_device_config(
5453 device_config_t *devconf;
5455 for(devconf = device_config_list; devconf != NULL; devconf = devconf->next) {
5456 if(strcasecmp(devconf->name, str) == 0) return devconf;
5462 device_config_getconf(
5463 device_config_t *devconf,
5464 device_config_key key)
5466 assert(devconf != NULL);
5467 assert(key < DEVICE_CONFIG_DEVICE_CONFIG);
5468 return &devconf->value[key];
5473 device_config_t *devconf)
5475 assert(devconf != NULL);
5476 return devconf->name;
5480 lookup_changer_config(
5483 changer_config_t *devconf;
5485 for(devconf = changer_config_list; devconf != NULL; devconf = devconf->next) {
5486 if(strcasecmp(devconf->name, str) == 0) return devconf;
5492 changer_config_getconf(
5493 changer_config_t *devconf,
5494 changer_config_key key)
5496 assert(devconf != NULL);
5497 assert(key < CHANGER_CONFIG_CHANGER_CONFIG);
5498 return &devconf->value[key];
5502 changer_config_name(
5503 changer_config_t *devconf)
5505 assert(devconf != NULL);
5506 return devconf->name;
5510 getconf_unit_divisor(void)
5512 return unit_divisor;
5516 * Command-line Handling Implementation
5519 config_overrides_t *
5520 new_config_overrides(
5523 config_overrides_t *co;
5525 if (size_estimate <= 0)
5528 co = alloc(sizeof(*co));
5529 co->ovr = alloc(sizeof(*co->ovr) * size_estimate);
5530 co->n_allocated = size_estimate;
5537 free_config_overrides(
5538 config_overrides_t *co)
5543 for (i = 0; i < co->n_used; i++) {
5544 amfree(co->ovr[i].key);
5545 amfree(co->ovr[i].value);
5551 void add_config_override(
5552 config_overrides_t *co,
5556 /* reallocate if necessary */
5557 if (co->n_used == co->n_allocated) {
5558 co->n_allocated *= 2;
5559 co->ovr = realloc(co->ovr, co->n_allocated * sizeof(*co->ovr));
5561 error(_("Cannot realloc; out of memory"));
5566 co->ovr[co->n_used].key = stralloc(key);
5567 co->ovr[co->n_used].value = stralloc(value);
5572 add_config_override_opt(
5573 config_overrides_t *co,
5577 assert(optarg != NULL);
5579 value = strchr(optarg, '=');
5580 if (value == NULL) {
5581 error(_("Must specify a value for %s."), optarg);
5586 add_config_override(co, optarg, value+1);
5590 config_overrides_t *
5591 extract_commandline_config_overrides(
5596 config_overrides_t *co = new_config_overrides(*argc/2);
5600 if(strncmp((*argv)[i],"-o",2) == 0) {
5601 if(strlen((*argv)[i]) > 2) {
5602 add_config_override_opt(co, (*argv)[i]+2);
5606 if (i+1 >= *argc) error(_("expect something after -o"));
5607 add_config_override_opt(co, (*argv)[i+1]);
5611 /* move up remaining argment array */
5612 for (j = i; j+moveup<*argc; j++) {
5613 (*argv)[j] = (*argv)[j+moveup];
5625 set_config_overrides(
5626 config_overrides_t *co)
5630 config_overrides = co;
5632 for (i = 0; i < co->n_used; i++) {
5633 g_debug("config_overrides: %s %s", co->ovr[i].key, co->ovr[i].value);
5639 static cfgerr_level_t
5640 apply_config_overrides(
5641 config_overrides_t *co,
5646 if(!co) return cfgerr_level;
5647 assert(keytable != NULL);
5648 assert(parsetable != NULL);
5650 for (i = 0; i < co->n_used; i++) {
5651 char *key = co->ovr[i].key;
5652 char *value = co->ovr[i].value;
5654 conf_var_t *key_parm;
5656 if (key_ovr && strncasecmp(key_ovr, key, strlen(key_ovr)) != 0) {
5660 if (!parm_key_info(key, &key_parm, &key_val)) {
5661 /* not an error, only default config is loaded */
5665 /* now set up a fake line and use the relevant read_function to
5666 * parse it. This is sneaky! */
5667 if (key_parm->type == CONFTYPE_STR) {
5668 current_line = quote_string_always(value);
5670 current_line = stralloc(value);
5673 current_char = current_line;
5675 current_line_num = -2;
5676 allow_overwrites = 1;
5677 co->ovr[i].applied = TRUE;
5679 key_parm->read_function(key_parm, key_val);
5680 if ((key_parm)->validate_function)
5681 key_parm->validate_function(key_parm, key_val);
5683 amfree(current_line);
5684 current_char = NULL;
5687 return cfgerr_level;
5691 * val_t Management Implementation
5698 assert(config_initialized);
5699 if (val->type != CONFTYPE_INT) {
5700 error(_("val_t_to_int: val.type is not CONFTYPE_INT"));
5703 return val_t__int(val);
5710 assert(config_initialized);
5711 if (val->type != CONFTYPE_INT64) {
5712 error(_("val_t_to_int64: val.type is not CONFTYPE_INT64"));
5715 return val_t__int64(val);
5722 assert(config_initialized);
5723 if (val->type != CONFTYPE_REAL) {
5724 error(_("val_t_to_real: val.type is not CONFTYPE_REAL"));
5727 return val_t__real(val);
5734 assert(config_initialized);
5735 /* support CONFTYPE_IDENT, too */
5736 if (val->type != CONFTYPE_STR && val->type != CONFTYPE_IDENT) {
5737 error(_("val_t_to_str: val.type is not CONFTYPE_STR nor CONFTYPE_IDENT"));
5740 return val_t__str(val);
5747 assert(config_initialized);
5748 /* support CONFTYPE_STR, too */
5749 if (val->type != CONFTYPE_STR && val->type != CONFTYPE_IDENT) {
5750 error(_("val_t_to_ident: val.type is not CONFTYPE_IDENT nor CONFTYPE_STR"));
5753 return val_t__str(val);
5760 assert(config_initialized);
5761 if (val->type != CONFTYPE_IDENTLIST) {
5762 error(_("val_t_to_ident: val.type is not CONFTYPE_IDENTLIST"));
5765 return val_t__identlist(val);
5772 assert(config_initialized);
5773 if (val->type != CONFTYPE_TIME) {
5774 error(_("val_t_to_time: val.type is not CONFTYPE_TIME"));
5777 return val_t__time(val);
5784 assert(config_initialized);
5785 if (val->type != CONFTYPE_SIZE) {
5786 error(_("val_t_to_size: val.type is not CONFTYPE_SIZE"));
5789 return val_t__size(val);
5796 assert(config_initialized);
5797 if (val->type != CONFTYPE_BOOLEAN) {
5798 error(_("val_t_to_bool: val.type is not CONFTYPE_BOOLEAN"));
5801 return val_t__boolean(val);
5808 assert(config_initialized);
5809 if (val->type != CONFTYPE_COMPRESS) {
5810 error(_("val_t_to_compress: val.type is not CONFTYPE_COMPRESS"));
5813 return val_t__compress(val);
5820 assert(config_initialized);
5821 if (val->type != CONFTYPE_ENCRYPT) {
5822 error(_("val_t_to_encrypt: val.type is not CONFTYPE_ENCRYPT"));
5825 return val_t__encrypt(val);
5832 assert(config_initialized);
5833 if (val->type != CONFTYPE_HOLDING) {
5834 error(_("val_t_to_hold: val.type is not CONFTYPE_HOLDING"));
5837 return val_t__holding(val);
5841 val_t_to_estimatelist(
5844 assert(config_initialized);
5845 if (val->type != CONFTYPE_ESTIMATELIST) {
5846 error(_("val_t_to_estimatelist: val.type is not CONFTYPE_ESTIMATELIST"));
5849 return val_t__estimatelist(val);
5856 assert(config_initialized);
5857 if (val->type != CONFTYPE_STRATEGY) {
5858 error(_("val_t_to_strategy: val.type is not CONFTYPE_STRATEGY"));
5861 return val_t__strategy(val);
5868 assert(config_initialized);
5869 if (val->type != CONFTYPE_TAPERALGO) {
5870 error(_("val_t_to_taperalgo: val.type is not CONFTYPE_TAPERALGO"));
5873 return val_t__taperalgo(val);
5877 val_t_to_send_amreport(
5880 assert(config_initialized);
5881 if (val->type != CONFTYPE_SEND_AMREPORT_ON) {
5882 error(_("val_t_to_send_amreport: val.type is not CONFTYPE_SEND_AMREPORT_ON"));
5885 return val_t__send_amreport(val);
5892 assert(config_initialized);
5893 if (val->type != CONFTYPE_DATA_PATH) {
5894 error(_("val_t_to_data_path: val.type is not CONFTYPE_DATA_PATH"));
5897 return val_t__data_path(val);
5904 assert(config_initialized);
5905 if (val->type != CONFTYPE_PRIORITY) {
5906 error(_("val_t_to_priority: val.type is not CONFTYPE_PRIORITY"));
5909 return val_t__priority(val);
5916 assert(config_initialized);
5917 if (val->type != CONFTYPE_RATE) {
5918 error(_("val_t_to_rate: val.type is not CONFTYPE_RATE"));
5921 return val_t__rate(val);
5928 assert(config_initialized);
5929 if (val->type != CONFTYPE_EXINCLUDE) {
5930 error(_("val_t_to_exinclude: val.type is not CONFTYPE_EXINCLUDE"));
5933 return val_t__exinclude(val);
5941 assert(config_initialized);
5942 if (val->type != CONFTYPE_INTRANGE) {
5943 error(_("val_t_to_intrange: val.type is not CONFTYPE_INTRANGE"));
5946 return val_t__intrange(val);
5953 assert(config_initialized);
5954 if (val->type != CONFTYPE_PROPLIST) {
5955 error(_("val_t_to_proplist: val.type is not CONFTYPE_PROPLIST"));
5958 return val_t__proplist(val);
5965 assert(config_initialized);
5966 if (val->type != CONFTYPE_AUTOLABEL) {
5967 error(_("val_t_to_autolabel: val.type is not CONFTYPE_AUTOLABEL"));
5970 return val_t__autolabel(val);
5978 if (valsrc->type == CONFTYPE_PROPLIST) {
5979 if (valsrc->v.proplist) {
5980 if (valdst->v.proplist == NULL) {
5981 valdst->v.proplist = g_hash_table_new_full(g_str_hash,
5985 g_hash_table_foreach(valsrc->v.proplist,
5986 ©_proplist_foreach_fn,
5987 valdst->v.proplist);
5989 g_hash_table_foreach(valsrc->v.proplist,
5990 &merge_proplist_foreach_fn,
5991 valdst->v.proplist);
5994 } else if (valsrc->type == CONFTYPE_IDENTLIST) {
5995 if (valsrc->v.identlist) {
5997 for (il = valsrc->v.identlist; il != NULL; il = il->next) {
5998 valdst->v.identlist = g_slist_append(valdst->v.identlist,
5999 stralloc((char *)il->data));
6004 copy_val_t(valdst, valsrc);
6015 if(valsrc->seen.linenum) {
6016 valdst->type = valsrc->type;
6017 valdst->seen = valsrc->seen;
6018 switch(valsrc->type) {
6020 case CONFTYPE_BOOLEAN:
6021 case CONFTYPE_COMPRESS:
6022 case CONFTYPE_ENCRYPT:
6023 case CONFTYPE_HOLDING:
6024 case CONFTYPE_EXECUTE_ON:
6025 case CONFTYPE_EXECUTE_WHERE:
6026 case CONFTYPE_SEND_AMREPORT_ON:
6027 case CONFTYPE_DATA_PATH:
6028 case CONFTYPE_STRATEGY:
6029 case CONFTYPE_TAPERALGO:
6030 case CONFTYPE_PRIORITY:
6031 valdst->v.i = valsrc->v.i;
6035 valdst->v.size = valsrc->v.size;
6038 case CONFTYPE_INT64:
6039 valdst->v.int64 = valsrc->v.int64;
6043 valdst->v.r = valsrc->v.r;
6047 valdst->v.rate[0] = valsrc->v.rate[0];
6048 valdst->v.rate[1] = valsrc->v.rate[1];
6051 case CONFTYPE_IDENT:
6053 valdst->v.s = stralloc(valsrc->v.s);
6056 case CONFTYPE_IDENTLIST:
6057 valdst->v.identlist = NULL;
6058 for (ia = valsrc->v.identlist; ia != NULL; ia = ia->next) {
6059 valdst->v.identlist = g_slist_append(valdst->v.identlist,
6060 stralloc(ia->data));
6065 valdst->v.t = valsrc->v.t;
6068 case CONFTYPE_ESTIMATELIST: {
6069 estimatelist_t estimates = valsrc->v.estimatelist;
6070 estimatelist_t dst_estimates = NULL;
6071 while (estimates != NULL) {
6072 dst_estimates = g_slist_append(dst_estimates, estimates->data);
6073 estimates = estimates->next;
6075 valdst->v.estimatelist = dst_estimates;
6079 case CONFTYPE_EXINCLUDE:
6080 valdst->v.exinclude.optional = valsrc->v.exinclude.optional;
6081 valdst->v.exinclude.sl_list = duplicate_sl(valsrc->v.exinclude.sl_list);
6082 valdst->v.exinclude.sl_file = duplicate_sl(valsrc->v.exinclude.sl_file);
6085 case CONFTYPE_INTRANGE:
6086 valdst->v.intrange[0] = valsrc->v.intrange[0];
6087 valdst->v.intrange[1] = valsrc->v.intrange[1];
6090 case CONFTYPE_PROPLIST:
6091 if (valsrc->v.proplist) {
6092 valdst->v.proplist = g_hash_table_new_full(g_str_hash,
6097 g_hash_table_foreach(valsrc->v.proplist,
6098 ©_proplist_foreach_fn,
6099 valdst->v.proplist);
6101 valdst->v.proplist = NULL;
6105 case CONFTYPE_APPLICATION:
6106 valdst->v.s = stralloc(valsrc->v.s);
6109 case CONFTYPE_AUTOLABEL:
6110 valdst->v.autolabel.template = stralloc(valsrc->v.autolabel.template);
6111 valdst->v.autolabel.autolabel = valsrc->v.autolabel.autolabel;
6118 merge_proplist_foreach_fn(
6121 gpointer user_data_p)
6123 char *property_s = key_p;
6124 property_t *property = value_p;
6125 proplist_t proplist = user_data_p;
6126 GSList *elem = NULL;
6128 property_t *new_property = g_hash_table_lookup(proplist, property_s);
6129 if (new_property && !property->append) {
6130 g_hash_table_remove(proplist, property_s);
6131 new_property = NULL;
6133 if (!new_property) {
6134 new_property = malloc(sizeof(property_t));
6135 new_property->append = property->append;
6136 new_property->priority = property->priority;
6137 new_property->values = NULL;
6141 for(elem = property->values;elem != NULL; elem=elem->next) {
6142 new_property->values = g_slist_append(new_property->values,
6143 stralloc(elem->data));
6146 g_hash_table_insert(proplist, stralloc(property_s), new_property);
6150 copy_proplist_foreach_fn(
6153 gpointer user_data_p)
6155 char *property_s = key_p;
6156 property_t *property = value_p;
6157 proplist_t proplist = user_data_p;
6158 GSList *elem = NULL;
6159 property_t *new_property = malloc(sizeof(property_t));
6160 new_property->append = property->append;
6161 new_property->priority = property->priority;
6162 new_property->values = NULL;
6164 for(elem = property->values;elem != NULL; elem=elem->next) {
6165 new_property->values = g_slist_append(new_property->values,
6166 stralloc(elem->data));
6168 g_hash_table_insert(proplist, stralloc(property_s), new_property);
6177 case CONFTYPE_BOOLEAN:
6178 case CONFTYPE_COMPRESS:
6179 case CONFTYPE_ENCRYPT:
6180 case CONFTYPE_HOLDING:
6181 case CONFTYPE_EXECUTE_WHERE:
6182 case CONFTYPE_EXECUTE_ON:
6183 case CONFTYPE_SEND_AMREPORT_ON:
6184 case CONFTYPE_DATA_PATH:
6185 case CONFTYPE_STRATEGY:
6187 case CONFTYPE_TAPERALGO:
6188 case CONFTYPE_PRIORITY:
6189 case CONFTYPE_INT64:
6192 case CONFTYPE_INTRANGE:
6195 case CONFTYPE_IDENT:
6197 case CONFTYPE_APPLICATION:
6201 case CONFTYPE_IDENTLIST:
6202 g_slist_free_full(val->v.identlist);
6208 case CONFTYPE_ESTIMATELIST:
6209 g_slist_free(val->v.estimatelist);
6212 case CONFTYPE_EXINCLUDE:
6213 free_sl(val_t__exinclude(val).sl_list);
6214 free_sl(val_t__exinclude(val).sl_file);
6217 case CONFTYPE_PROPLIST:
6218 g_hash_table_destroy(val_t__proplist(val));
6221 case CONFTYPE_AUTOLABEL:
6222 amfree(val->v.autolabel.template);
6225 val->seen.linenum = 0;
6226 val->seen.filename = NULL;
6230 * Utilities Implementation
6234 generic_get_security_conf(
6239 if(!string || !*string)
6242 if(strcmp(string, "krb5principal")==0) {
6243 return(getconf_str(CNF_KRB5PRINCIPAL));
6244 } else if(strcmp(string, "krb5keytab")==0) {
6245 return(getconf_str(CNF_KRB5KEYTAB));
6251 generic_client_get_security_conf(
6255 (void)arg; /* Quiet unused parameter warning */
6257 if(!string || !*string)
6260 if(strcmp(string, "conf")==0) {
6261 return(getconf_str(CNF_CONF));
6262 } else if(strcmp(string, "index_server")==0) {
6263 return(getconf_str(CNF_INDEX_SERVER));
6264 } else if(strcmp(string, "tape_server")==0) {
6265 return(getconf_str(CNF_TAPE_SERVER));
6266 } else if(strcmp(string, "tapedev")==0) {
6267 return(getconf_str(CNF_TAPEDEV));
6268 } else if(strcmp(string, "auth")==0) {
6269 return(getconf_str(CNF_AUTH));
6270 } else if(strcmp(string, "ssh_keys")==0) {
6271 return(getconf_str(CNF_SSH_KEYS));
6272 } else if(strcmp(string, "amandad_path")==0) {
6273 return(getconf_str(CNF_AMANDAD_PATH));
6274 } else if(strcmp(string, "client_username")==0) {
6275 return(getconf_str(CNF_CLIENT_USERNAME));
6276 } else if(strcmp(string, "client_port")==0) {
6277 return(getconf_str(CNF_CLIENT_PORT));
6278 } else if(strcmp(string, "gnutar_list_dir")==0) {
6279 return(getconf_str(CNF_GNUTAR_LIST_DIR));
6280 } else if(strcmp(string, "amandates")==0) {
6281 return(getconf_str(CNF_AMANDATES));
6282 } else if(strcmp(string, "krb5principal")==0) {
6283 return(getconf_str(CNF_KRB5PRINCIPAL));
6284 } else if(strcmp(string, "krb5keytab")==0) {
6285 return(getconf_str(CNF_KRB5KEYTAB));
6291 dump_configuration(void)
6300 device_config_t *dc;
6301 changer_config_t *cc;
6307 if (config_client) {
6308 error(_("Don't know how to dump client configurations."));
6312 g_printf(_("# AMANDA CONFIGURATION FROM FILE \"%s\":\n\n"), config_filename);
6314 for(np=server_var; np->token != CONF_UNKNOWN; np++) {
6315 for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
6316 if (np->token == kt->token) break;
6318 if(kt->token == CONF_UNKNOWN)
6319 error(_("server bad token"));
6321 val_t_print_token(stdout, NULL, "%-21s ", kt, &conf_data[np->parm]);
6324 for(hp = holdinglist; hp != NULL; hp = hp->next) {
6326 g_printf("\nDEFINE HOLDINGDISK %s {\n", hd->name);
6327 for(i=0; i < HOLDING_HOLDING; i++) {
6328 for(np=holding_var; np->token != CONF_UNKNOWN; np++) {
6332 if(np->token == CONF_UNKNOWN)
6333 error(_("holding bad value"));
6335 for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++) {
6336 if(kt->token == np->token)
6339 if(kt->token == CONF_UNKNOWN)
6340 error(_("holding bad token"));
6342 val_t_print_token(stdout, NULL, " %-9s ", kt, &hd->value[i]);
6347 for(tp = tapelist; tp != NULL; tp = tp->next) {
6348 if(tp->seen.linenum == -1)
6352 g_printf("\n%sDEFINE TAPETYPE %s {\n", prefix, tp->name);
6353 for(i=0; i < TAPETYPE_TAPETYPE; i++) {
6354 for(np=tapetype_var; np->token != CONF_UNKNOWN; np++)
6355 if(np->parm == i) break;
6356 if(np->token == CONF_UNKNOWN)
6357 error(_("tapetype bad value"));
6359 for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
6360 if(kt->token == np->token) break;
6361 if(kt->token == CONF_UNKNOWN)
6362 error(_("tapetype bad token"));
6364 val_t_print_token(stdout, prefix, " %-9s ", kt, &tp->value[i]);
6366 g_printf("%s}\n", prefix);
6369 for(dp = dumplist; dp != NULL; dp = dp->next) {
6370 if (strncmp_const(dp->name, "custom(") != 0) { /* don't dump disklist-derived dumptypes */
6371 if(dp->seen.linenum == -1)
6375 g_printf("\n%sDEFINE DUMPTYPE %s {\n", prefix, dp->name);
6376 for(i=0; i < DUMPTYPE_DUMPTYPE; i++) {
6377 for(np=dumptype_var; np->token != CONF_UNKNOWN; np++)
6378 if(np->parm == i) break;
6379 if(np->token == CONF_UNKNOWN)
6380 error(_("dumptype bad value"));
6382 for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
6383 if(kt->token == np->token) break;
6384 if(kt->token == CONF_UNKNOWN)
6385 error(_("dumptype bad token"));
6387 val_t_print_token(stdout, prefix, " %-19s ", kt, &dp->value[i]);
6389 g_printf("%s}\n", prefix);
6393 for(ip = interface_list; ip != NULL; ip = ip->next) {
6394 seen_t *netusage_seen = &val_t__seen(getconf(CNF_NETUSAGE));
6395 if (ip->seen.linenum == netusage_seen->linenum &&
6396 ip->seen.filename && netusage_seen->filename &&
6397 0 == strcmp(ip->seen.filename, netusage_seen->filename))
6401 g_printf("\n%sDEFINE INTERFACE %s {\n", prefix, ip->name);
6402 for(i=0; i < INTER_INTER; i++) {
6403 for(np=interface_var; np->token != CONF_UNKNOWN; np++)
6404 if(np->parm == i) break;
6405 if(np->token == CONF_UNKNOWN)
6406 error(_("interface bad value"));
6408 for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
6409 if(kt->token == np->token) break;
6410 if(kt->token == CONF_UNKNOWN)
6411 error(_("interface bad token"));
6413 val_t_print_token(stdout, prefix, " %-19s ", kt, &ip->value[i]);
6415 g_printf("%s}\n",prefix);
6418 for(ap = application_list; ap != NULL; ap = ap->next) {
6419 if(strcmp(ap->name,"default") == 0)
6423 g_printf("\n%sDEFINE APPLICATION %s {\n", prefix, ap->name);
6424 for(i=0; i < APPLICATION_APPLICATION; i++) {
6425 for(np=application_var; np->token != CONF_UNKNOWN; np++)
6426 if(np->parm == i) break;
6427 if(np->token == CONF_UNKNOWN)
6428 error(_("application bad value"));
6430 for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
6431 if(kt->token == np->token) break;
6432 if(kt->token == CONF_UNKNOWN)
6433 error(_("application bad token"));
6435 val_t_print_token(stdout, prefix, " %-19s ", kt, &ap->value[i]);
6437 g_printf("%s}\n",prefix);
6440 for(ps = pp_script_list; ps != NULL; ps = ps->next) {
6441 if(strcmp(ps->name,"default") == 0)
6445 g_printf("\n%sDEFINE SCRIPT %s {\n", prefix, ps->name);
6446 for(i=0; i < PP_SCRIPT_PP_SCRIPT; i++) {
6447 for(np=pp_script_var; np->token != CONF_UNKNOWN; np++)
6448 if(np->parm == i) break;
6449 if(np->token == CONF_UNKNOWN)
6450 error(_("script bad value"));
6452 for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
6453 if(kt->token == np->token) break;
6454 if(kt->token == CONF_UNKNOWN)
6455 error(_("script bad token"));
6457 val_t_print_token(stdout, prefix, " %-19s ", kt, &ps->value[i]);
6459 g_printf("%s}\n",prefix);
6462 for(dc = device_config_list; dc != NULL; dc = dc->next) {
6464 g_printf("\n%sDEFINE DEVICE %s {\n", prefix, dc->name);
6465 for(i=0; i < DEVICE_CONFIG_DEVICE_CONFIG; i++) {
6466 for(np=device_config_var; np->token != CONF_UNKNOWN; np++)
6467 if(np->parm == i) break;
6468 if(np->token == CONF_UNKNOWN)
6469 error(_("device bad value"));
6471 for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
6472 if(kt->token == np->token) break;
6473 if(kt->token == CONF_UNKNOWN)
6474 error(_("device bad token"));
6476 val_t_print_token(stdout, prefix, " %-19s ", kt, &dc->value[i]);
6478 g_printf("%s}\n",prefix);
6481 for(cc = changer_config_list; cc != NULL; cc = cc->next) {
6483 g_printf("\n%sDEFINE CHANGER %s {\n", prefix, cc->name);
6484 for(i=0; i < CHANGER_CONFIG_CHANGER_CONFIG; i++) {
6485 for(np=changer_config_var; np->token != CONF_UNKNOWN; np++)
6486 if(np->parm == i) break;
6487 if(np->token == CONF_UNKNOWN)
6488 error(_("changer bad value"));
6490 for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
6491 if(kt->token == np->token) break;
6492 if(kt->token == CONF_UNKNOWN)
6493 error(_("changer bad token"));
6495 val_t_print_token(stdout, prefix, " %-19s ", kt, &cc->value[i]);
6497 g_printf("%s}\n",prefix);
6509 char **dispstrs, **dispstr;
6510 dispstrs = val_t_display_strs(val, 1);
6512 /* For most configuration types, this outputs
6513 * PREFIX KEYWORD DISPSTR
6514 * for each of the display strings. For identifiers, however, it
6515 * simply prints the first line of the display string.
6518 /* Print the keyword for anything that is not itself an identifier */
6519 if (kt->token != CONF_IDENT) {
6520 for(dispstr=dispstrs; *dispstr!=NULL; dispstr++) {
6522 g_fprintf(output, "%s", prefix);
6523 g_fprintf(output, format, kt->keyword);
6524 g_fprintf(output, "%s\n", *dispstr);
6527 /* for identifiers, assume there's at most one display string */
6528 assert(g_strv_length(dispstrs) <= 1);
6530 g_fprintf(output, "%s\n", *dispstrs);
6534 g_strfreev(dispstrs);
6543 buf = malloc(3*SIZEOF(char *));
6550 buf[0] = vstrallocf("%d", val_t__int(val));
6554 buf[0] = vstrallocf("%zd", (ssize_t)val_t__size(val));
6557 case CONFTYPE_INT64:
6558 buf[0] = vstrallocf("%lld", (long long)val_t__int64(val));
6562 buf[0] = vstrallocf("%0.5f", val_t__real(val));
6566 buf[0] = vstrallocf("%0.5f %0.5f", val_t__rate(val)[0], val_t__rate(val)[1]);
6569 case CONFTYPE_INTRANGE:
6570 buf[0] = vstrallocf("%d,%d", val_t__intrange(val)[0], val_t__intrange(val)[1]);
6573 case CONFTYPE_IDENT:
6575 buf[0] = stralloc(val->v.s);
6577 buf[0] = stralloc("");
6581 case CONFTYPE_IDENTLIST:
6587 for (ia = val->v.identlist; ia != NULL; ia = ia->next) {
6589 buf[0] = stralloc(ia->data);
6592 strappend(buf[0], " ");
6593 strappend(buf[0], ia->data);
6600 if(str_need_quote) {
6602 buf[0] = quote_string_always(val->v.s);
6604 buf[0] = stralloc("\"\"");
6608 buf[0] = stralloc(val->v.s);
6610 buf[0] = stralloc("");
6615 case CONFTYPE_AUTOLABEL:
6617 buf[0] = quote_string_always(val->v.autolabel.template);
6618 if (val->v.autolabel.autolabel & AL_OTHER_CONFIG) {
6619 buf[0] = vstrextend(&buf[0], " OTHER-CONFIG", NULL);
6621 if (val->v.autolabel.autolabel & AL_NON_AMANDA) {
6622 buf[0] = vstrextend(&buf[0], " NON-AMANDA", NULL);
6624 if (val->v.autolabel.autolabel & AL_VOLUME_ERROR) {
6625 buf[0] = vstrextend(&buf[0], " VOLUME-ERROR", NULL);
6627 if (val->v.autolabel.autolabel & AL_EMPTY) {
6628 buf[0] = vstrextend(&buf[0], " EMPTY", NULL);
6634 buf[0] = vstrallocf("%2d%02d",
6635 (int)val_t__time(val)/100, (int)val_t__time(val) % 100);
6638 case CONFTYPE_EXINCLUDE: {
6639 buf[0] = exinclude_display_str(val, 0);
6640 buf[1] = exinclude_display_str(val, 1);
6644 case CONFTYPE_BOOLEAN:
6645 if(val_t__boolean(val))
6646 buf[0] = stralloc("yes");
6648 buf[0] = stralloc("no");
6651 case CONFTYPE_STRATEGY:
6652 switch(val_t__strategy(val)) {
6654 buf[0] = vstrallocf("SKIP");
6658 buf[0] = vstrallocf("STANDARD");
6662 buf[0] = vstrallocf("NOFULL");
6666 buf[0] = vstrallocf("NOINC");
6670 buf[0] = vstrallocf("HANOI");
6674 buf[0] = vstrallocf("INCRONLY");
6679 case CONFTYPE_COMPRESS:
6680 switch(val_t__compress(val)) {
6682 buf[0] = vstrallocf("NONE");
6686 buf[0] = vstrallocf("CLIENT FAST");
6690 buf[0] = vstrallocf("CLIENT BEST");
6694 buf[0] = vstrallocf("CLIENT CUSTOM");
6697 case COMP_SERVER_FAST:
6698 buf[0] = vstrallocf("SERVER FAST");
6701 case COMP_SERVER_BEST:
6702 buf[0] = vstrallocf("SERVER BEST");
6705 case COMP_SERVER_CUST:
6706 buf[0] = vstrallocf("SERVER CUSTOM");
6711 case CONFTYPE_ESTIMATELIST: {
6712 estimatelist_t es = val_t__estimatelist(val);
6713 buf[0] = stralloc("");
6715 switch((estimate_t)GPOINTER_TO_INT(es->data)) {
6717 strappend(buf[0], "CLIENT");
6721 strappend(buf[0], "SERVER");
6725 strappend(buf[0], "CALCSIZE");
6733 strappend(buf[0], " ");
6738 case CONFTYPE_EXECUTE_WHERE:
6741 buf[0] = vstrallocf("CLIENT");
6745 buf[0] = vstrallocf("SERVER");
6750 case CONFTYPE_SEND_AMREPORT_ON:
6752 case SEND_AMREPORT_ALL:
6753 buf[0] = vstrallocf("ALL");
6755 case SEND_AMREPORT_STRANGE:
6756 buf[0] = vstrallocf("STRANGE");
6758 case SEND_AMREPORT_ERROR:
6759 buf[0] = vstrallocf("ERROR");
6761 case SEND_AMREPORT_NEVER:
6762 buf[0] = vstrallocf("NEVER");
6767 case CONFTYPE_DATA_PATH:
6768 buf[0] = g_strdup(data_path_to_string(val->v.i));
6771 case CONFTYPE_ENCRYPT:
6772 switch(val_t__encrypt(val)) {
6774 buf[0] = vstrallocf("NONE");
6778 buf[0] = vstrallocf("CLIENT");
6781 case ENCRYPT_SERV_CUST:
6782 buf[0] = vstrallocf("SERVER");
6787 case CONFTYPE_HOLDING:
6788 switch(val_t__holding(val)) {
6790 buf[0] = vstrallocf("NEVER");
6794 buf[0] = vstrallocf("AUTO");
6798 buf[0] = vstrallocf("REQUIRED");
6803 case CONFTYPE_TAPERALGO:
6804 buf[0] = vstrallocf("%s", taperalgo2str(val_t__taperalgo(val)));
6807 case CONFTYPE_PRIORITY:
6808 switch(val_t__priority(val)) {
6810 buf[0] = vstrallocf("LOW");
6814 buf[0] = vstrallocf("MEDIUM");
6818 buf[0] = vstrallocf("HIGH");
6823 case CONFTYPE_PROPLIST: {
6827 nb_property = g_hash_table_size(val_t__proplist(val));
6829 buf = malloc((nb_property+1)*SIZEOF(char*));
6830 buf[nb_property] = NULL;
6832 g_hash_table_foreach(val_t__proplist(val),
6833 proplist_display_str_foreach_fn,
6838 case CONFTYPE_APPLICATION: {
6840 buf[0] = quote_string_always(val->v.s);
6842 buf[0] = stralloc("");
6847 case CONFTYPE_EXECUTE_ON:
6848 buf[0] = stralloc("");
6849 if (val->v.i != 0) {
6851 if (val->v.i & EXECUTE_ON_PRE_DLE_AMCHECK) {
6852 buf[0] = vstrextend(&buf[0], sep, "PRE-DLE-AMCHECK", NULL);
6855 if (val->v.i & EXECUTE_ON_PRE_HOST_AMCHECK) {
6856 buf[0] = vstrextend(&buf[0], sep, "PRE-HOST-AMCHECK", NULL);
6859 if (val->v.i & EXECUTE_ON_POST_DLE_AMCHECK) {
6860 buf[0] = vstrextend(&buf[0], sep, "POST-DLE-AMCHECK", NULL);
6863 if (val->v.i & EXECUTE_ON_POST_HOST_AMCHECK) {
6864 buf[0] = vstrextend(&buf[0], sep, "POST-HOST-AMCHECK", NULL);
6867 if (val->v.i & EXECUTE_ON_PRE_DLE_ESTIMATE) {
6868 buf[0] = vstrextend(&buf[0], sep, "PRE-DLE-ESTIMATE", NULL);
6871 if (val->v.i & EXECUTE_ON_PRE_HOST_ESTIMATE) {
6872 buf[0] = vstrextend(&buf[0], sep, "PRE-HOST-ESTIMATE", NULL);
6875 if (val->v.i & EXECUTE_ON_POST_DLE_ESTIMATE) {
6876 buf[0] = vstrextend(&buf[0], sep, "POST-DLE-ESTIMATE", NULL);
6879 if (val->v.i & EXECUTE_ON_POST_HOST_ESTIMATE) {
6880 buf[0] = vstrextend(&buf[0], sep, "POST-HOST-ESTIMATE", NULL);
6883 if (val->v.i & EXECUTE_ON_PRE_DLE_BACKUP) {
6884 buf[0] = vstrextend(&buf[0], sep, "PRE-DLE-BACKUP", NULL);
6887 if (val->v.i & EXECUTE_ON_PRE_HOST_BACKUP) {
6888 buf[0] = vstrextend(&buf[0], sep, "PRE-HOST-BACKUP", NULL);
6891 if (val->v.i & EXECUTE_ON_POST_DLE_BACKUP) {
6892 buf[0] = vstrextend(&buf[0], sep, "POST-DLE-BACKUP", NULL);
6895 if (val->v.i & EXECUTE_ON_POST_HOST_BACKUP) {
6896 buf[0] = vstrextend(&buf[0], sep, "POST-HOST-BACKUP", NULL);
6899 if (val->v.i & EXECUTE_ON_PRE_RECOVER) {
6900 buf[0] = vstrextend(&buf[0], sep, "PRE-RECOVER", NULL);
6903 if (val->v.i & EXECUTE_ON_POST_RECOVER) {
6904 buf[0] = vstrextend(&buf[0], sep, "POST-RECOVER", NULL);
6907 if (val->v.i & EXECUTE_ON_PRE_LEVEL_RECOVER) {
6908 buf[0] = vstrextend(&buf[0], sep, "PRE-LEVEL-RECOVER", NULL);
6911 if (val->v.i & EXECUTE_ON_POST_LEVEL_RECOVER) {
6912 buf[0] = vstrextend(&buf[0], sep, "POST-LEVEL-RECOVER", NULL);
6915 if (val->v.i & EXECUTE_ON_INTER_LEVEL_RECOVER) {
6916 buf[0] = vstrextend(&buf[0], sep, "INTER-LEVEL-RECOVER", NULL);
6927 val_t_to_execute_on(
6930 if (val->type != CONFTYPE_EXECUTE_ON) {
6931 error(_("get_conftype_execute_on: val.type is not CONFTYPE_EXECUTE_ON"));
6934 return val_t__execute_on(val);
6938 val_t_to_execute_where(
6941 if (val->type != CONFTYPE_EXECUTE_WHERE) {
6942 error(_("get_conftype_execute_where: val.type is not CONFTYPE_EXECUTE_WHERE"));
6949 val_t_to_application(
6952 if (val->type != CONFTYPE_APPLICATION) {
6953 error(_("get_conftype_applicaiton: val.type is not CONFTYPE_APPLICATION"));
6961 proplist_display_str_foreach_fn(
6964 gpointer user_data_p)
6966 char *property_s = quote_string_always(key_p);
6967 property_t *property = value_p;
6969 char ***msg = (char ***)user_data_p;
6971 /* What to do with property->append? it should be printed only on client */
6972 if (property->priority) {
6973 **msg = vstralloc("priority ", property_s, NULL);
6979 for(value=property->values; value != NULL; value = value->next) {
6980 char *qstr = quote_string_always((char *)value->data);
6981 **msg = vstrextend(*msg, " ", qstr, NULL);
6988 exinclude_display_str(
6996 assert(val->type == CONFTYPE_EXINCLUDE);
6998 rval = stralloc("");
7001 sl = val_t__exinclude(val).sl_list;
7002 strappend(rval, "LIST");
7004 sl = val_t__exinclude(val).sl_file;
7005 strappend(rval, "FILE");
7008 if (val_t__exinclude(val).optional == 1) {
7009 strappend(rval, " OPTIONAL");
7013 for(excl = sl->first; excl != NULL; excl = excl->next) {
7014 char *qstr = quote_string_always(excl->name);
7015 vstrextend(&rval, " ", qstr, NULL);
7025 taperalgo_t taperalgo)
7027 if(taperalgo == ALGO_FIRST) return "FIRST";
7028 if(taperalgo == ALGO_FIRSTFIT) return "FIRSTFIT";
7029 if(taperalgo == ALGO_LARGEST) return "LARGEST";
7030 if(taperalgo == ALGO_LARGESTFIT) return "LARGESTFIT";
7031 if(taperalgo == ALGO_SMALLEST) return "SMALLEST";
7032 if(taperalgo == ALGO_LAST) return "LAST";
7037 config_dir_relative(
7040 if (*filename == '/' || config_dir == NULL) {
7041 return stralloc(filename);
7043 if (config_dir[strlen(config_dir)-1] == '/') {
7044 return vstralloc(config_dir, filename, NULL);
7046 return vstralloc(config_dir, "/", filename, NULL);
7070 device_config_t *dc;
7071 changer_config_t *cc;
7072 int success = FALSE;
7074 /* WARNING: assumes globals keytable and parsetable are set correctly. */
7075 assert(keytable != NULL);
7076 assert(parsetable != NULL);
7078 /* make a copy we can stomp on */
7079 key = stralloc(key);
7081 /* uppercase the key */
7082 for (s = key; (ch = *s) != 0; s++) {
7083 if (islower((int)ch))
7084 *s = (char)toupper(ch);
7087 subsec_name = strchr(key, ':');
7091 *subsec_name = '\0';
7094 /* convert subsec_type '-' to '_' */
7095 for (s = subsec_type; (ch = *s) != 0; s++) {
7096 if (*s == '-') *s = '_';
7099 subsec_key = strchr(subsec_name,':');
7100 if(!subsec_key) goto out; /* failure */
7105 /* convert subsec_key '-' to '_' */
7106 for (s = subsec_key; (ch = *s) != 0; s++) {
7107 if (*s == '-') *s = '_';
7110 /* If the keyword doesn't exist, there's no need to look up the
7111 * subsection -- we know it's invalid */
7112 for(kt = keytable; kt->token != CONF_UNKNOWN; kt++) {
7113 if(kt->keyword && strcmp(kt->keyword, subsec_key) == 0)
7116 if(kt->token == CONF_UNKNOWN) goto out;
7118 /* Otherwise, figure out which kind of subsection we're dealing with,
7119 * and parse against that. */
7120 if (strcmp(subsec_type, "TAPETYPE") == 0) {
7121 tp = lookup_tapetype(subsec_name);
7123 for(np = tapetype_var; np->token != CONF_UNKNOWN; np++) {
7124 if(np->token == kt->token)
7127 if (np->token == CONF_UNKNOWN) goto out;
7129 if (val) *val = &tp->value[np->parm];
7130 if (parm) *parm = np;
7132 } else if (strcmp(subsec_type, "DUMPTYPE") == 0) {
7133 dp = lookup_dumptype(subsec_name);
7135 for(np = dumptype_var; np->token != CONF_UNKNOWN; np++) {
7136 if(np->token == kt->token)
7139 if (np->token == CONF_UNKNOWN) goto out;
7141 if (val) *val = &dp->value[np->parm];
7142 if (parm) *parm = np;
7144 } else if (strcmp(subsec_type, "HOLDINGDISK") == 0) {
7145 hp = lookup_holdingdisk(subsec_name);
7147 for(np = holding_var; np->token != CONF_UNKNOWN; np++) {
7148 if(np->token == kt->token)
7151 if (np->token == CONF_UNKNOWN) goto out;
7153 if (val) *val = &hp->value[np->parm];
7154 if (parm) *parm = np;
7156 } else if (strcmp(subsec_type, "INTERFACE") == 0) {
7157 ip = lookup_interface(subsec_name);
7159 for(np = interface_var; np->token != CONF_UNKNOWN; np++) {
7160 if(np->token == kt->token)
7163 if (np->token == CONF_UNKNOWN) goto out;
7165 if (val) *val = &ip->value[np->parm];
7166 if (parm) *parm = np;
7168 /* accept the old name here, too */
7169 } else if (strcmp(subsec_type, "APPLICATION_TOOL") == 0
7170 || strcmp(subsec_type, "APPLICATION") == 0) {
7171 ap = lookup_application(subsec_name);
7173 for(np = application_var; np->token != CONF_UNKNOWN; np++) {
7174 if(np->token == kt->token)
7177 if (np->token == CONF_UNKNOWN) goto out;
7179 if (val) *val = &ap->value[np->parm];
7180 if (parm) *parm = np;
7182 /* accept the old name here, too */
7183 } else if (strcmp(subsec_type, "SCRIPT_TOOL") == 0
7184 || strcmp(subsec_type, "SCRIPT") == 0) {
7185 pp = lookup_pp_script(subsec_name);
7187 for(np = pp_script_var; np->token != CONF_UNKNOWN; np++) {
7188 if(np->token == kt->token)
7191 if (np->token == CONF_UNKNOWN) goto out;
7193 if (val) *val = &pp->value[np->parm];
7194 if (parm) *parm = np;
7196 } else if (strcmp(subsec_type, "DEVICE") == 0) {
7197 dc = lookup_device_config(subsec_name);
7199 for(np = device_config_var; np->token != CONF_UNKNOWN; np++) {
7200 if(np->token == kt->token)
7203 if (np->token == CONF_UNKNOWN) goto out;
7205 if (val) *val = &dc->value[np->parm];
7206 if (parm) *parm = np;
7208 } else if (strcmp(subsec_type, "CHANGER") == 0) {
7209 cc = lookup_changer_config(subsec_name);
7211 for(np = changer_config_var; np->token != CONF_UNKNOWN; np++) {
7212 if(np->token == kt->token)
7215 if (np->token == CONF_UNKNOWN) goto out;
7217 if (val) *val = &cc->value[np->parm];
7218 if (parm) *parm = np;
7222 /* No delimiters -- we're referencing a global config parameter */
7224 /* convert key '-' to '_' */
7225 for (s = key; (ch = *s) != 0; s++) {
7226 if (*s == '-') *s = '_';
7229 /* look up the keyword */
7230 for(kt = keytable; kt->token != CONF_UNKNOWN; kt++) {
7231 if(kt->keyword && strcmp(kt->keyword, key) == 0)
7234 if(kt->token == CONF_UNKNOWN) goto out;
7236 /* and then look that up in the parse table */
7237 for(np = parsetable; np->token != CONF_UNKNOWN; np++) {
7238 if(np->token == kt->token)
7241 if(np->token == CONF_UNKNOWN) goto out;
7243 if (val) *val = &conf_data[np->parm];
7244 if (parm) *parm = np;
7257 keytab_t * table_entry;
7259 str = g_strdup(str);
7267 for (table_entry = numb_keytable; table_entry->keyword != NULL;
7269 if (strcasecmp(str, table_entry->keyword) == 0) {
7271 switch (table_entry->token) {
7277 return 1024*1024*1024;
7279 return (gint64)1024*1024*1024*1024;
7282 case CONF_AMINFINITY:
7288 /* Should not happen. */
7294 /* None found; this is an error. */
7303 keytab_t * table_entry;
7305 if (str == NULL || *str == '\0') {
7309 /* 0 and 1 are not in the table, as they are parsed as ints */
7310 if (0 == strcmp(str, "0"))
7312 if (0 == strcmp(str, "1"))
7315 for (table_entry = bool_keytable; table_entry->keyword != NULL;
7317 if (strcasecmp(str, table_entry->keyword) == 0) {
7318 switch (table_entry->token) {
7333 * Error Handling Implementaiton
7336 void config_add_error(
7337 cfgerr_level_t level,
7340 cfgerr_level = max(cfgerr_level, level);
7342 g_debug("%s", errmsg);
7343 cfgerr_errors = g_slist_append(cfgerr_errors, errmsg);
7346 static void conf_error_common(
7347 cfgerr_level_t level,
7348 const char * format,
7351 char *msg = g_strdup_vprintf(format, argp);
7352 char *errstr = NULL;
7355 errstr = g_strdup_printf(_("argument \"%s\": %s"),
7357 else if (current_filename && current_line_num > 0)
7358 errstr = g_strdup_printf(_("\"%s\", line %d: %s"),
7359 current_filename, current_line_num, msg);
7361 errstr = g_strdup_printf(_("parse error: %s"), msg);
7364 config_add_error(level, errstr);
7367 printf_arglist_function(void conf_parserror, const char *, format)
7371 arglist_start(argp, format);
7372 conf_error_common(CFGERR_ERRORS, format, argp);
7376 printf_arglist_function(void conf_parswarn, const char *, format) {
7379 arglist_start(argp, format);
7380 conf_error_common(CFGERR_WARNINGS, format, argp);
7385 config_errors(GSList **errstr)
7388 *errstr = cfgerr_errors;
7389 return cfgerr_level;
7393 config_clear_errors(void)
7395 g_slist_free_full(cfgerr_errors);
7397 cfgerr_errors = NULL;
7398 cfgerr_level = CFGERR_OK;
7402 config_print_errors(void)
7406 for (iter = cfgerr_errors; iter; iter = g_slist_next(iter)) {
7407 g_fprintf(stderr, "%s\n", (char *)iter->data);
7411 /* Get the config name */
7412 char *get_config_name(void)
7417 /* Get the config directory */
7418 char *get_config_dir(void)
7423 /* Get the config filename */
7424 char *get_config_filename(void)
7426 return config_filename;
7430 property_add_to_argv(
7431 GPtrArray *argv_ptr,
7432 proplist_t proplist)
7434 g_hash_table_foreach(proplist, &proplist_add_to_argv, argv_ptr);
7439 anonymous_value(void)
7441 static char number[NUM_STR_SIZE];
7444 g_snprintf(number, sizeof(number), "%d", value);
7450 gint compare_pp_script_order(
7454 return pp_script_get_order(lookup_pp_script((char *)a)) > pp_script_get_order(lookup_pp_script((char *)b));
7458 data_path_to_string(
7459 data_path_t data_path)
7461 switch (data_path) {
7462 case DATA_PATH_AMANDA : return "AMANDA";
7463 case DATA_PATH_DIRECTTCP: return "DIRECTTCP";
7465 error(_("data_path is not DATA_PATH_AMANDA or DATA_PATH_DIRECTTCP"));
7470 data_path_from_string(
7473 if (strcmp(data, "AMANDA") == 0)
7474 return DATA_PATH_AMANDA;
7475 if (strcmp(data, "DIRECTTCP") == 0)
7476 return DATA_PATH_DIRECTTCP;
7477 error(_("data_path is not AMANDA or DIRECTTCP :%s:"), data);
7482 amandaify_property_name(
7487 if (!name) return NULL;
7489 ret = g_malloc0(strlen(name)+1);
7491 for (cur_o = name; *cur_o; cur_o++) {
7495 *cur_r = g_ascii_tolower(*cur_o);