2 * Amanda, The Advanced Maryland Automatic Network Disk Archiver
3 * Copyright (c) 1991-2000 University of Maryland at College Park
4 * Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved.
7 * Permission to use, copy, modify, distribute, and sell this software and its
8 * documentation for any purpose is hereby granted without fee, provided that
9 * the above copyright notice appear in all copies and that both that
10 * copyright notice and this permission notice appear in supporting
11 * documentation, and that the name of U.M. not be used in advertising or
12 * publicity pertaining to distribution of the software without specific,
13 * written prior permission. U.M. makes no representations about the
14 * suitability of this software for any purpose. It is provided "as is"
15 * without express or implied warranty.
17 * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
19 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
20 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
21 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
22 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
24 * Author: James da Silva, Systems Design and Analysis Group
25 * Computer Science Department
26 * University of Maryland at College Park
29 * $Id: conffile.c,v 1.156 2006/07/26 15:17:37 martinea Exp $
31 * read configuration file
45 /* This module implements its own quixotic lexer and parser, present for historical
46 * reasons. If this were written from scratch, it would use flex/bison. */
48 /* An enumeration of the various tokens that might appear in a configuration file.
50 * - CONF_UNKNOWN has special meaning as an unrecognized token.
51 * - CONF_ANY can be used to request any token, rather than requiring a specific
55 CONF_UNKNOWN, CONF_ANY, CONF_COMMA,
56 CONF_LBRACE, CONF_RBRACE, CONF_NL,
57 CONF_END, CONF_IDENT, CONF_INT,
58 CONF_INT64, CONF_BOOL, CONF_REAL,
59 CONF_STRING, CONF_TIME, CONF_SIZE,
61 /* config parameters */
62 CONF_INCLUDEFILE, CONF_ORG, CONF_MAILTO,
63 CONF_DUMPUSER, CONF_TAPECYCLE, CONF_TAPEDEV,
64 CONF_CHANGERDEV, CONF_CHANGERFILE, CONF_LABELSTR,
65 CONF_BUMPPERCENT, CONF_BUMPSIZE, CONF_BUMPDAYS,
66 CONF_BUMPMULT, CONF_ETIMEOUT, CONF_DTIMEOUT,
67 CONF_CTIMEOUT, CONF_TAPELIST,
68 CONF_DEVICE_OUTPUT_BUFFER_SIZE,
69 CONF_DISKFILE, CONF_INFOFILE, CONF_LOGDIR,
70 CONF_LOGFILE, CONF_DISKDIR, CONF_DISKSIZE,
71 CONF_INDEXDIR, CONF_NETUSAGE, CONF_INPARALLEL,
72 CONF_DUMPORDER, CONF_TIMEOUT, CONF_TPCHANGER,
73 CONF_RUNTAPES, CONF_DEFINE, CONF_DUMPTYPE,
74 CONF_TAPETYPE, CONF_INTERFACE, CONF_PRINTER,
76 CONF_AUTOFLUSH, CONF_RESERVE, CONF_MAXDUMPSIZE,
77 CONF_COLUMNSPEC, CONF_AMRECOVER_DO_FSF, CONF_AMRECOVER_CHECK_LABEL,
78 CONF_AMRECOVER_CHANGER, CONF_LABEL_NEW_TAPES, CONF_USETIMESTAMPS,
81 CONF_TAPERALGO, CONF_FIRST, CONF_FIRSTFIT,
82 CONF_LARGEST, CONF_LARGESTFIT, CONF_SMALLEST,
83 CONF_LAST, CONF_DISPLAYUNIT, CONF_RESERVED_UDP_PORT,
84 CONF_RESERVED_TCP_PORT, CONF_UNRESERVED_TCP_PORT,
86 CONF_FLUSH_THRESHOLD_DUMPED,
87 CONF_FLUSH_THRESHOLD_SCHEDULED,
88 CONF_DEVICE_PROPERTY, CONF_PROPERTY, CONF_PLUGIN,
89 CONF_APPLICATION, CONF_APPLICATION_TOOL,
90 CONF_SCRIPT, CONF_SCRIPT_TOOL,
91 CONF_EXECUTE_ON, CONF_EXECUTE_WHERE, CONF_SEND_AMREPORT_ON,
92 CONF_DEVICE, CONF_ORDER, CONF_SINGLE_EXECUTION,
93 CONF_DATA_PATH, CONF_AMANDA, CONF_DIRECTTCP,
94 CONF_TAPER_PARALLEL_WRITE, CONF_INTERACTIVITY, CONF_TAPERSCAN,
95 CONF_MAX_DLE_BY_VOLUME, CONF_EJECT_VOLUME, CONF_TMPDIR,
96 CONF_REPORT_USE_MEDIA, CONF_REPORT_NEXT_MEDIA,
99 CONF_PRE_AMCHECK, CONF_POST_AMCHECK,
100 CONF_PRE_DLE_AMCHECK, CONF_PRE_HOST_AMCHECK,
101 CONF_POST_DLE_AMCHECK, CONF_POST_HOST_AMCHECK,
102 CONF_PRE_ESTIMATE, CONF_POST_ESTIMATE,
103 CONF_PRE_DLE_ESTIMATE, CONF_PRE_HOST_ESTIMATE,
104 CONF_POST_DLE_ESTIMATE, CONF_POST_HOST_ESTIMATE,
105 CONF_PRE_BACKUP, CONF_POST_BACKUP,
106 CONF_PRE_DLE_BACKUP, CONF_PRE_HOST_BACKUP,
107 CONF_POST_DLE_BACKUP, CONF_POST_HOST_BACKUP,
108 CONF_PRE_RECOVER, CONF_POST_RECOVER,
109 CONF_PRE_LEVEL_RECOVER, CONF_POST_LEVEL_RECOVER,
110 CONF_INTER_LEVEL_RECOVER,
113 CONF_KRB5KEYTAB, CONF_KRB5PRINCIPAL,
116 CONF_COMMENT, CONF_DIRECTORY, CONF_USE,
120 /*COMMENT,*/ CONF_PROGRAM, CONF_DUMPCYCLE,
121 CONF_RUNSPERCYCLE, CONF_MAXCYCLE, CONF_MAXDUMPS,
122 CONF_OPTIONS, CONF_PRIORITY, CONF_FREQUENCY,
123 CONF_INDEX, CONF_MAXPROMOTEDAY, CONF_STARTTIME,
124 CONF_COMPRESS, CONF_ENCRYPT, CONF_AUTH,
125 CONF_STRATEGY, CONF_ESTIMATE, CONF_SKIP_INCR,
126 CONF_SKIP_FULL, CONF_RECORD, CONF_HOLDING,
127 CONF_EXCLUDE, CONF_INCLUDE, CONF_KENCRYPT,
128 CONF_IGNORE, CONF_COMPRATE, CONF_TAPE_SPLITSIZE,
129 CONF_SPLIT_DISKBUFFER, CONF_FALLBACK_SPLITSIZE,CONF_SRVCOMPPROG,
130 CONF_CLNTCOMPPROG, CONF_SRV_ENCRYPT, CONF_CLNT_ENCRYPT,
131 CONF_SRV_DECRYPT_OPT, CONF_CLNT_DECRYPT_OPT, CONF_AMANDAD_PATH,
132 CONF_CLIENT_USERNAME, CONF_CLIENT_PORT, CONF_ALLOW_SPLIT,
136 /*COMMENT,*/ CONF_BLOCKSIZE,
137 CONF_LBL_TEMPL, CONF_FILEMARK, CONF_LENGTH,
138 CONF_SPEED, CONF_READBLOCKSIZE,
141 CONF_CONF, CONF_INDEX_SERVER, CONF_TAPE_SERVER,
142 CONF_SSH_KEYS, CONF_GNUTAR_LIST_DIR, CONF_AMANDATES,
145 /* protocol config */
146 CONF_REP_TRIES, CONF_CONNECT_TRIES, CONF_REQ_TRIES,
150 CONF_DEBUG_AMANDAD, CONF_DEBUG_AMIDXTAPED, CONF_DEBUG_AMINDEXD,
151 CONF_DEBUG_AMRECOVER, CONF_DEBUG_AUTH, CONF_DEBUG_EVENT,
152 CONF_DEBUG_HOLDING, CONF_DEBUG_PROTOCOL, CONF_DEBUG_PLANNER,
153 CONF_DEBUG_DRIVER, CONF_DEBUG_DUMPER, CONF_DEBUG_CHUNKER,
154 CONF_DEBUG_TAPER, CONF_DEBUG_SELFCHECK, CONF_DEBUG_SENDSIZE,
155 CONF_DEBUG_SENDBACKUP, CONF_DEBUG_RECOVERY,
157 /* network interface */
158 /* COMMENT, */ /* USE, */
160 /* dump options (obsolete) */
161 CONF_EXCLUDE_FILE, CONF_EXCLUDE_LIST,
163 /* compress, estimate, encryption */
164 CONF_NONE, CONF_FAST, CONF_BEST,
165 CONF_SERVER, CONF_CLIENT, CONF_CALCSIZE,
169 CONF_AUTOLABEL, CONF_ANY_VOLUME, CONF_OTHER_CONFIG,
170 CONF_NON_AMANDA, CONF_VOLUME_ERROR, CONF_EMPTY,
173 /* part_cache_type */
174 CONF_PART_SIZE, CONF_PART_CACHE_TYPE, CONF_PART_CACHE_DIR,
175 CONF_PART_CACHE_MAX_SIZE, CONF_DISK, CONF_MEMORY,
178 CONF_RECOVERY_LIMIT, CONF_SAME_HOST, CONF_DUMP_LIMIT,
181 CONF_NEVER, CONF_AUTO, CONF_REQUIRED,
184 CONF_ALL, CONF_STRANGE, CONF_ERROR,
187 CONF_LOW, CONF_MEDIUM, CONF_HIGH,
190 CONF_SKIP, CONF_STANDARD, CONF_NOFULL,
191 CONF_NOINC, CONF_HANOI, CONF_INCRONLY,
194 CONF_LIST, CONF_EFILE, CONF_APPEND,
198 CONF_AMINFINITY, CONF_MULT1, CONF_MULT7,
199 CONF_MULT1K, CONF_MULT1M, CONF_MULT1G,
203 CONF_ATRUE, CONF_AFALSE,
208 /* A keyword table entry, mapping the given keyword to the given token.
209 * Note that punctuation, integers, and quoted strings are handled
210 * internally to the lexer, so they do not appear here. */
216 /* The current keyword table, used by all token-related functions */
217 static keytab_t *keytable = NULL;
219 /* Has a token been "ungotten", and if so, what was it? */
220 static int token_pushed;
221 static tok_t pushed_tok;
223 /* The current token and its value. Note that, unlike most other val_t*,
224 * tokenval's v.s points to statically allocated memory which cannot be
227 static val_t tokenval;
229 /* The current input information: file, filename, line, and character
230 * (which points somewhere within current_line) */
231 static FILE *current_file = NULL;
232 static char *current_filename = NULL;
233 static char *current_line = NULL;
234 static char *current_char = NULL;
235 static char *current_block = NULL;
236 static int current_line_num = 0; /* (technically, managed by the parser) */
238 /* A static buffer for storing tokens while they are being scanned. */
239 static char tkbuf[4096];
241 /* Return a token formated for output */
242 static char *str_keyword(keytab_t *kt);
244 static char *str_keyword(keytab_t *kt);
245 /* Look up the name of the given token in the current keytable */
246 static char *get_token_name(tok_t);
248 /* Look up a token in keytable, given a string, returning CONF_UNKNOWN
249 * for unrecognized strings. Search is case-insensitive. */
250 static tok_t lookup_keyword(char *str);
252 /* Get the next token. If exp is anything but CONF_ANY, and the next token
253 * does not match, then a parse error is flagged. This function reads from the
254 * current_* static variables, recognizes keywords against the keytable static
255 * variable, and places its result in tok and tokenval. */
256 static void get_conftoken(tok_t exp);
258 /* "Unget" the current token; this supports a 1-token lookahead. */
259 static void unget_conftoken(void);
261 /* Tokenizer character-by-character access. */
262 static int conftoken_getc(void);
263 static int conftoken_ungetc(int c);
265 static void merge_proplist_foreach_fn(gpointer key_p,
267 gpointer user_data_p);
268 static void copy_proplist_foreach_fn(gpointer key_p,
270 gpointer user_data_p);
276 /* A parser table entry. Read as "<token> introduces parameter <parm>,
277 * the data for which will be read by <read_function> and validated by
278 * <validate_function> (if not NULL). <type> is only used in formatting
279 * config overwrites. */
280 typedef struct conf_var_s {
283 void (*read_function) (struct conf_var_s *, val_t*);
285 void (*validate_function) (struct conf_var_s *, val_t *);
288 /* This is a list of filenames that are used in 'seen_t' structs. */
289 static GSList *seen_filenames = NULL;
291 /* get a copy of filename that's stored in seen_filenames so that it won't go
292 * away until config_uninit. */
293 static char *get_seen_filename(char *filename);
295 /* If allow_overwrites is true, the a parameter which has already been
296 * seen will simply overwrite the old value, rather than triggering an
297 * error. Note that this does not apply to all parameters, e.g.,
299 static int allow_overwrites;
301 /* subsection structs
303 * The 'seen' fields in these structs are useless outside this module;
304 * they are only used to generate error messages for multiply defined
308 struct tapetype_s *next;
312 val_t value[TAPETYPE_TAPETYPE];
316 struct dumptype_s *next;
320 val_t value[DUMPTYPE_DUMPTYPE];
324 struct interface_s *next;
328 val_t value[INTER_INTER];
331 struct holdingdisk_s {
335 val_t value[HOLDING_HOLDING];
338 struct application_s {
339 struct application_s *next;
343 val_t value[APPLICATION_APPLICATION];
347 struct pp_script_s *next;
351 val_t value[PP_SCRIPT_PP_SCRIPT];
354 struct device_config_s {
355 struct device_config_s *next;
359 val_t value[DEVICE_CONFIG_DEVICE_CONFIG];
362 struct changer_config_s {
363 struct changer_config_s *next;
367 val_t value[CHANGER_CONFIG_CHANGER_CONFIG];
370 struct interactivity_s {
371 struct interactivity_s *next;
375 val_t value[INTERACTIVITY_INTERACTIVITY];
379 struct taperscan_s *next;
383 val_t value[TAPERSCAN_TAPERSCAN];
386 /* The current parser table */
387 static conf_var_t *parsetable = NULL;
389 /* Read and parse a configuration file, recursively reading any included
390 * files. This function sets the keytable and parsetable appropriately
391 * according to is_client.
393 * @param filename: configuration file to read
394 * @param is_client: true if this is a client
395 * @param missing_ok: is it OK if the file is missing?
397 static void read_conffile(char *filename,
399 gboolean missing_ok);
401 /* Read and process a line of input from the current file, using the
402 * current keytable and parsetable. For blocks, this recursively
403 * reads the entire block.
405 * @param is_client: true if this is a client
406 * @returns: true on success, false on EOF
408 static gboolean read_confline(gboolean is_client);
410 /* Handle an invalid token, recognizing deprecated tokens as such,
411 * and producing an appropriate error message.
413 * @param token: the identifier
415 static void handle_invalid_keyword(const char * token);
417 /* Check whether token is deprecated, and issue a warning if it
418 * is. This consults the global variables 'tok' and 'tokenval'
420 static void handle_deprecated_keyword(void);
422 /* Read a brace-delimited block using the given parse table. This
423 * function is used to read brace-delimited subsections in the config
424 * files and also (via read_dumptype) to read dumptypes from
427 * This function implements "inheritance" as follows: if a bare
428 * identifier occurs within the braces, it calls copy_function (if
429 * not NULL), which looks up an existing subsection using the
430 * identifier from tokenval and copies any values not already seen
433 * @param read_var: the parse table to use
434 * @param valarray: the (pre-initialized) val_t array to fill in
435 * @param errormsg: error message to display for unrecognized keywords
436 * @param read_brace: if true, read the opening brace
437 * @param copy_function: function to copy configuration from
438 * another subsection into this one.
440 static void read_block(conf_var_t *read_var, val_t *valarray,
441 char *errormsg, int read_brace,
442 void (*copy_function)(void),
443 char *type, char *name);
445 /* For each subsection type, we have a global and four functions:
446 * - foocur is a temporary struct used to assemble new subsections
447 * - get_foo is called after reading "DEFINE FOO", and
448 * is responsible for reading the entire block, using
450 * - init_foo_defaults initializes a new subsection struct
451 * to its default values
452 * - save_foo copies foocur to a newly allocated struct and
453 * inserts that into the relevant list.
454 * - copy_foo implements inheritance as described in read_block()
456 static holdingdisk_t hdcur;
457 static void get_holdingdisk(int is_define);
458 static void init_holdingdisk_defaults(void);
459 static void save_holdingdisk(void);
460 static void copy_holdingdisk(void);
462 static dumptype_t dpcur;
463 static void get_dumptype(void);
464 static void init_dumptype_defaults(void);
465 static void save_dumptype(void);
466 static void copy_dumptype(void);
468 static tapetype_t tpcur;
469 static void get_tapetype(void);
470 static void init_tapetype_defaults(void);
471 static void save_tapetype(void);
472 static void copy_tapetype(void);
474 static interface_t ifcur;
475 static void get_interface(void);
476 static void init_interface_defaults(void);
477 static void save_interface(void);
478 static void copy_interface(void);
480 static application_t apcur;
481 static void get_application(void);
482 static void init_application_defaults(void);
483 static void save_application(void);
484 static void copy_application(void);
486 static pp_script_t pscur;
487 static void get_pp_script(void);
488 static void init_pp_script_defaults(void);
489 static void save_pp_script(void);
490 static void copy_pp_script(void);
492 static device_config_t dccur;
493 static void get_device_config(void);
494 static void init_device_config_defaults(void);
495 static void save_device_config(void);
496 static void copy_device_config(void);
498 static changer_config_t cccur;
499 static void get_changer_config(void);
500 static void init_changer_config_defaults(void);
501 static void save_changer_config(void);
502 static void copy_changer_config(void);
504 static interactivity_t ivcur;
505 static void get_interactivity(void);
506 static void init_interactivity_defaults(void);
507 static void save_interactivity(void);
508 static void copy_interactivity(void);
510 static taperscan_t tscur;
511 static void get_taperscan(void);
512 static void init_taperscan_defaults(void);
513 static void save_taperscan(void);
514 static void copy_taperscan(void);
516 /* read_functions -- these fit into the read_function slot in a parser
517 * table entry, and are responsible for calling getconf_token as necessary
518 * to consume their arguments, and setting their second argument with the
519 * result. The first argument is a copy of the parser table entry, if
521 static void read_int(conf_var_t *, val_t *);
522 static void read_int64(conf_var_t *, val_t *);
523 static void read_real(conf_var_t *, val_t *);
524 static void read_str(conf_var_t *, val_t *);
525 static void read_ident(conf_var_t *, val_t *);
526 static void read_time(conf_var_t *, val_t *);
527 static void read_size(conf_var_t *, val_t *);
528 static void read_bool(conf_var_t *, val_t *);
529 static void read_no_yes_all(conf_var_t *, val_t *);
530 static void read_compress(conf_var_t *, val_t *);
531 static void read_encrypt(conf_var_t *, val_t *);
532 static void read_holding(conf_var_t *, val_t *);
533 static void read_estimatelist(conf_var_t *, val_t *);
534 static void read_strategy(conf_var_t *, val_t *);
535 static void read_taperalgo(conf_var_t *, val_t *);
536 static void read_send_amreport_on(conf_var_t *, val_t *);
537 static void read_data_path(conf_var_t *, val_t *);
538 static void read_priority(conf_var_t *, val_t *);
539 static void read_rate(conf_var_t *, val_t *);
540 static void read_exinclude(conf_var_t *, val_t *);
541 static void read_intrange(conf_var_t *, val_t *);
542 static void read_dapplication(conf_var_t *, val_t *);
543 static void read_dinteractivity(conf_var_t *, val_t *);
544 static void read_dtaperscan(conf_var_t *, val_t *);
545 static void read_dpp_script(conf_var_t *, val_t *);
546 static void read_property(conf_var_t *, val_t *);
547 static void read_execute_on(conf_var_t *, val_t *);
548 static void read_execute_where(conf_var_t *, val_t *);
549 static void read_holdingdisk(conf_var_t *, val_t *);
550 static void read_int_or_str(conf_var_t *, val_t *);
551 static void read_autolabel(conf_var_t *, val_t *);
552 static void read_part_cache_type(conf_var_t *, val_t *);
553 static void read_host_limit(conf_var_t *, val_t *);
555 static application_t *read_application(char *name, FILE *from, char *fname,
557 static pp_script_t *read_pp_script(char *name, FILE *from, char *fname,
559 static device_config_t *read_device_config(char *name, FILE *from, char *fname,
561 static changer_config_t *read_changer_config(char *name, FILE *from,
562 char *fname, int *linenum);
563 static interactivity_t *read_interactivity(char *name, FILE *from,
564 char *fname, int *linenum);
565 static taperscan_t *read_taperscan(char *name, FILE *from, char *fname,
567 /* Functions to get various types of values. These are called by
568 * read_functions to take care of any variations in the way that these
569 * values can be written: integers can have units, boolean values can be
570 * specified with a number of names, etc. They form utility functions
571 * for the read_functions, below. */
572 static gint64 get_multiplier(gint64 val, confunit_t unit);
573 static time_t get_time(void);
574 static int get_int(confunit_t unit);
575 static ssize_t get_size(confunit_t unit);
576 static gint64 get_int64(confunit_t unit);
577 static int get_bool(void);
578 static int get_no_yes_all(void);
580 /* Check the given 'seen', flagging an error if this value has already
581 * been seen and allow_overwrites is false. Also marks the value as
582 * seen on the current line.
584 * @param seen: (in/out) seen value to adjust
586 static void ckseen(seen_t *seen);
588 /* validate_functions -- these fit into the validate_function solt in
589 * a parser table entry. They call conf_parserror if the value in their
590 * second argument is invalid. */
591 static void validate_nonnegative(conf_var_t *, val_t *);
592 static void validate_non_zero(conf_var_t *, val_t *);
593 static void validate_positive(conf_var_t *, val_t *);
594 static void validate_runspercycle(conf_var_t *, val_t *);
595 static void validate_bumppercent(conf_var_t *, val_t *);
596 static void validate_bumpmult(conf_var_t *, val_t *);
597 static void validate_inparallel(conf_var_t *, val_t *);
598 static void validate_displayunit(conf_var_t *, val_t *);
599 static void validate_reserve(conf_var_t *, val_t *);
600 static void validate_use(conf_var_t *, val_t *);
601 static void validate_chunksize(conf_var_t *, val_t *);
602 static void validate_blocksize(conf_var_t *, val_t *);
603 static void validate_debug(conf_var_t *, val_t *);
604 static void validate_port_range(val_t *, int, int);
605 static void validate_reserved_port_range(conf_var_t *, val_t *);
606 static void validate_unreserved_port_range(conf_var_t *, val_t *);
607 static void validate_program(conf_var_t *, val_t *);
608 static void validate_dump_limit(conf_var_t *, val_t *);
609 static void validate_tmpdir(conf_var_t *, val_t *);
611 gint compare_pp_script_order(gconstpointer a, gconstpointer b);
617 /* The name of the configuration under which this application is running.
618 * This variable is initialized by config_init.
620 static char *config_name = NULL;
622 /* The directory containing the configuration for this application. This
623 * variable is initialized by config_init
625 static char *config_dir = NULL;
627 /* The most recently read top-level configuration file. This variable is
628 * initialized by config_init
630 static char *config_filename = NULL;
632 /* Has the config been initialized? */
633 static gboolean config_initialized = FALSE;
635 /* Are we running a client? (true if last init was
636 * with CONFIG_INIT_CLIENT) */
637 static gboolean config_client = FALSE;
639 /* What config overwrites to use? */
640 static config_overrides_t *config_overrides = NULL;
642 /* All global parameters */
643 static val_t conf_data[CNF_CNF];
645 /* Linked list of holding disks */
646 static GSList *holdinglist = NULL;
647 static dumptype_t *dumplist = NULL;
648 static tapetype_t *tapelist = NULL;
649 static interface_t *interface_list = NULL;
650 static application_t *application_list = NULL;
651 static pp_script_t *pp_script_list = NULL;
652 static device_config_t *device_config_list = NULL;
653 static changer_config_t *changer_config_list = NULL;
654 static interactivity_t *interactivity_list = NULL;
655 static taperscan_t *taperscan_list = NULL;
657 /* storage for derived values */
658 static long int unit_divisor = 1;
660 int debug_amandad = 0;
661 int debug_recovery = 0;
662 int debug_amidxtaped = 0;
663 int debug_amindexd = 0;
664 int debug_amrecover = 0;
667 int debug_holding = 0;
668 int debug_protocol = 0;
669 int debug_planner = 0;
670 int debug_driver = 0;
671 int debug_dumper = 0;
672 int debug_chunker = 0;
674 int debug_selfcheck = 0;
675 int debug_sendsize = 0;
676 int debug_sendbackup = 0;
678 /* Reset all configuration values to their defaults (which, in many
679 * cases, come from --with-foo options at build time) */
680 static void init_defaults(void);
682 /* Update all dervied values based on the current configuration. This
683 * function can be called multiple times, once after each adjustment
684 * to the current configuration.
686 * @param is_client: are we running a client?
688 static void update_derived_values(gboolean is_client);
690 static cfgerr_level_t apply_config_overrides(config_overrides_t *co,
693 /* per-type conf_init functions, used as utilities for init_defaults
694 * and for each subsection's init_foo_defaults.
696 * These set the value's type and seen flags, as well as copying
697 * the relevant value into the 'v' field.
699 static void conf_init_int(val_t *val, confunit_t unit, int i);
700 static void conf_init_int64(val_t *val, confunit_t unit, gint64 l);
701 static void conf_init_real(val_t *val, float r);
702 static void conf_init_str(val_t *val, char *s);
703 static void conf_init_ident(val_t *val, char *s);
704 static void conf_init_identlist(val_t *val, char *s);
705 static void conf_init_time(val_t *val, time_t t);
706 static void conf_init_size(val_t *val, confunit_t unit, ssize_t sz);
707 static void conf_init_bool(val_t *val, int i);
708 static void conf_init_no_yes_all(val_t *val, int i);
709 static void conf_init_compress(val_t *val, comp_t i);
710 static void conf_init_encrypt(val_t *val, encrypt_t i);
711 static void conf_init_data_path(val_t *val, data_path_t i);
712 static void conf_init_holding(val_t *val, dump_holdingdisk_t i);
713 static void conf_init_estimatelist(val_t *val, estimate_t i);
714 static void conf_init_execute_on(val_t *, int);
715 static void conf_init_execute_where(val_t *, int);
716 static void conf_init_send_amreport(val_t *val, send_amreport_t i);
717 static void conf_init_strategy(val_t *val, strategy_t);
718 static void conf_init_taperalgo(val_t *val, taperalgo_t i);
719 static void conf_init_priority(val_t *val, int i);
720 static void conf_init_rate(val_t *val, float r1, float r2);
721 static void conf_init_exinclude(val_t *val); /* to empty list */
722 static void conf_init_intrange(val_t *val, int i1, int i2);
723 static void conf_init_proplist(val_t *val); /* to empty list */
724 static void conf_init_application(val_t *val);
725 static void conf_init_autolabel(val_t *val);
726 static void conf_init_part_cache_type(val_t *val, part_cache_type_t i);
727 static void conf_init_host_limit(val_t *val);
728 static void conf_init_host_limit_server(val_t *val);
731 * Command-line Handling
734 typedef struct config_override_s {
740 struct config_overrides_s {
743 config_override_t *ovr;
750 static void merge_val_t(val_t *, val_t *);
751 static void copy_val_t(val_t *, val_t *);
752 static void free_val_t(val_t *);
758 /* memory handling */
759 void free_property_t(gpointer p);
761 /* Utility functions/structs for val_t_display_strs */
762 static char *exinclude_display_str(val_t *val, int file);
763 static void proplist_display_str_foreach_fn(gpointer key_p, gpointer value_p, gpointer user_data_p);
764 static void val_t_print_token(gboolean print_default, gboolean print_source, FILE *output, char *prefix, char *format, keytab_t *kt, val_t *val);
766 /* Given a key name as used in config overwrites, return a pointer to the corresponding
767 * conf_var_t in the current parsetable, and the val_t representing that value. This
768 * function will access subsections if key has the form TYPE:SUBSEC:KEYWORD. Returns
769 * false if the value does not exist.
771 * Assumes keytable and parsetable are set correctly, which is generally OK after
772 * config_init has been called.
774 * @param key: the key to look up
775 * @param parm: (result) the parse table entry
776 * @param val: (result) the parameter value
777 * @returns: true on success
779 static int parm_key_info(char *key, conf_var_t **parm, val_t **val);
785 /* Have we seen a parse error yet? Parsing continues after an error, so this
786 * flag is checked after the parse is complete.
788 static cfgerr_level_t cfgerr_level;
789 static GSList *cfgerr_errors = NULL;
791 static void conf_error_common(cfgerr_level_t level, const char * format, va_list argp);
792 static void conf_parserror(const char *format, ...)
793 __attribute__ ((format (printf, 1, 2)));
795 static void conf_parswarn(const char *format, ...)
796 __attribute__ ((format (printf, 1, 2)));
802 /* First, the keyword tables for client and server */
803 keytab_t client_keytab[] = {
804 { "CONF", CONF_CONF },
805 { "AMDUMP_SERVER", CONF_AMDUMP_SERVER },
806 { "INDEX_SERVER", CONF_INDEX_SERVER },
807 { "TAPE_SERVER", CONF_TAPE_SERVER },
808 { "TAPEDEV", CONF_TAPEDEV },
809 { "AUTH", CONF_AUTH },
810 { "SSH_KEYS", CONF_SSH_KEYS },
811 { "AMANDAD_PATH", CONF_AMANDAD_PATH },
812 { "CLIENT_NAME", CONF_CLIENT_NAME },
813 { "CLIENT_USERNAME", CONF_CLIENT_USERNAME },
814 { "CLIENT_PORT", CONF_CLIENT_PORT },
815 { "GNUTAR_LIST_DIR", CONF_GNUTAR_LIST_DIR },
816 { "AMANDATES", CONF_AMANDATES },
817 { "KRB5KEYTAB", CONF_KRB5KEYTAB },
818 { "KRB5PRINCIPAL", CONF_KRB5PRINCIPAL },
819 { "INCLUDEFILE", CONF_INCLUDEFILE },
820 { "CONNECT_TRIES", CONF_CONNECT_TRIES },
821 { "REP_TRIES", CONF_REP_TRIES },
822 { "REQ_TRIES", CONF_REQ_TRIES },
823 { "CLIENT", CONF_CLIENT },
824 { "DEBUG_DAYS", CONF_DEBUG_DAYS },
825 { "DEBUG_AMANDAD", CONF_DEBUG_AMANDAD },
826 { "DEBUG_RECOVERY", CONF_DEBUG_RECOVERY },
827 { "DEBUG_AMIDXTAPED", CONF_DEBUG_AMIDXTAPED },
828 { "DEBUG_AMINDEXD", CONF_DEBUG_AMINDEXD },
829 { "DEBUG_AMRECOVER", CONF_DEBUG_AMRECOVER },
830 { "DEBUG_AUTH", CONF_DEBUG_AUTH },
831 { "DEBUG_EVENT", CONF_DEBUG_EVENT },
832 { "DEBUG_HOLDING", CONF_DEBUG_HOLDING },
833 { "DEBUG_PROTOCOL", CONF_DEBUG_PROTOCOL },
834 { "DEBUG_PLANNER", CONF_DEBUG_PLANNER },
835 { "DEBUG_DRIVER", CONF_DEBUG_DRIVER },
836 { "DEBUG_DUMPER", CONF_DEBUG_DUMPER },
837 { "DEBUG_CHUNKER", CONF_DEBUG_CHUNKER },
838 { "DEBUG_TAPER", CONF_DEBUG_TAPER },
839 { "DEBUG_SELFCHECK", CONF_DEBUG_SELFCHECK },
840 { "DEBUG_SENDSIZE", CONF_DEBUG_SENDSIZE },
841 { "DEBUG_SENDBACKUP", CONF_DEBUG_SENDBACKUP },
842 { "EXECUTE_ON", CONF_EXECUTE_ON },
843 { "EXECUTE_WHERE", CONF_EXECUTE_WHERE },
844 { "RESERVED_UDP_PORT", CONF_RESERVED_UDP_PORT },
845 { "RESERVED_TCP_PORT", CONF_RESERVED_TCP_PORT },
846 { "UNRESERVED_TCP_PORT", CONF_UNRESERVED_TCP_PORT },
847 { "DEFINE", CONF_DEFINE },
848 { "COMMENT", CONF_COMMENT },
849 { "MAILER", CONF_MAILER },
850 { "ORDER", CONF_ORDER },
851 { "SCRIPT", CONF_SCRIPT },
852 { "SCRIPT_TOOL", CONF_SCRIPT_TOOL },
853 { "PLUGIN", CONF_PLUGIN },
854 { "PRE_AMCHECK", CONF_PRE_AMCHECK },
855 { "PRE_DLE_AMCHECK", CONF_PRE_DLE_AMCHECK },
856 { "PRE_HOST_AMCHECK", CONF_PRE_HOST_AMCHECK },
857 { "POST_AMCHECK", CONF_POST_AMCHECK },
858 { "POST_DLE_AMCHECK", CONF_POST_DLE_AMCHECK },
859 { "POST_HOST_AMCHECK", CONF_POST_HOST_AMCHECK },
860 { "PRE_ESTIMATE", CONF_PRE_ESTIMATE },
861 { "PRE_DLE_ESTIMATE", CONF_PRE_DLE_ESTIMATE },
862 { "PRE_HOST_ESTIMATE", CONF_PRE_HOST_ESTIMATE },
863 { "POST_ESTIMATE", CONF_POST_ESTIMATE },
864 { "POST_DLE_ESTIMATE", CONF_POST_DLE_ESTIMATE },
865 { "POST_HOST_ESTIMATE", CONF_POST_HOST_ESTIMATE },
866 { "POST_BACKUP", CONF_POST_BACKUP },
867 { "POST_DLE_BACKUP", CONF_POST_DLE_BACKUP },
868 { "POST_HOST_BACKUP", CONF_POST_HOST_BACKUP },
869 { "PRE_BACKUP", CONF_PRE_BACKUP },
870 { "PRE_DLE_BACKUP", CONF_PRE_DLE_BACKUP },
871 { "PRE_HOST_BACKUP", CONF_PRE_HOST_BACKUP },
872 { "PRE_RECOVER", CONF_PRE_RECOVER },
873 { "POST_RECOVER", CONF_POST_RECOVER },
874 { "PRE_LEVEL_RECOVER", CONF_PRE_LEVEL_RECOVER },
875 { "POST_LEVEL_RECOVER", CONF_POST_LEVEL_RECOVER },
876 { "INTER_LEVEL_RECOVER", CONF_INTER_LEVEL_RECOVER },
877 { "PRIORITY", CONF_PRIORITY },
878 { "PROPERTY", CONF_PROPERTY },
879 { "APPLICATION", CONF_APPLICATION },
880 { "APPLICATION_TOOL", CONF_APPLICATION_TOOL },
881 { "SERVER", CONF_SERVER },
882 { "APPEND", CONF_APPEND },
883 { NULL, CONF_IDENT },
884 { NULL, CONF_UNKNOWN }
887 keytab_t server_keytab[] = {
889 { "ALLOW_SPLIT", CONF_ALLOW_SPLIT },
890 { "AMANDA", CONF_AMANDA },
891 { "AMANDAD_PATH", CONF_AMANDAD_PATH },
892 { "AMRECOVER_CHANGER", CONF_AMRECOVER_CHANGER },
893 { "AMRECOVER_CHECK_LABEL", CONF_AMRECOVER_CHECK_LABEL },
894 { "AMRECOVER_DO_FSF", CONF_AMRECOVER_DO_FSF },
895 { "ANY", CONF_ANY_VOLUME },
896 { "APPEND", CONF_APPEND },
897 { "AUTH", CONF_AUTH },
898 { "AUTO", CONF_AUTO },
899 { "AUTOFLUSH", CONF_AUTOFLUSH },
900 { "AUTOLABEL", CONF_AUTOLABEL },
901 { "APPLICATION", CONF_APPLICATION },
902 { "APPLICATION_TOOL", CONF_APPLICATION_TOOL },
903 { "BEST", CONF_BEST },
904 { "BLOCKSIZE", CONF_BLOCKSIZE },
905 { "BUMPDAYS", CONF_BUMPDAYS },
906 { "BUMPMULT", CONF_BUMPMULT },
907 { "BUMPPERCENT", CONF_BUMPPERCENT },
908 { "BUMPSIZE", CONF_BUMPSIZE },
909 { "CALCSIZE", CONF_CALCSIZE },
910 { "CHANGER", CONF_CHANGER },
911 { "CHANGERDEV", CONF_CHANGERDEV },
912 { "CHANGERFILE", CONF_CHANGERFILE },
913 { "CHUNKSIZE", CONF_CHUNKSIZE },
914 { "CLIENT", CONF_CLIENT },
915 { "CLIENT_CUSTOM_COMPRESS", CONF_CLNTCOMPPROG },
916 { "CLIENT_DECRYPT_OPTION", CONF_CLNT_DECRYPT_OPT },
917 { "CLIENT_ENCRYPT", CONF_CLNT_ENCRYPT },
918 { "CLIENT_NAME", CONF_CLIENT_NAME },
919 { "CLIENT_USERNAME", CONF_CLIENT_USERNAME },
920 { "COLUMNSPEC", CONF_COLUMNSPEC },
921 { "COMMENT", CONF_COMMENT },
922 { "COMPRATE", CONF_COMPRATE },
923 { "COMPRESS", CONF_COMPRESS },
924 { "CONNECT_TRIES", CONF_CONNECT_TRIES },
925 { "CTIMEOUT", CONF_CTIMEOUT },
926 { "CUSTOM", CONF_CUSTOM },
927 { "DATA_PATH", CONF_DATA_PATH },
928 { "DEBUG_DAYS" , CONF_DEBUG_DAYS },
929 { "DEBUG_AMANDAD" , CONF_DEBUG_AMANDAD },
930 { "DEBUG_RECOVERY" , CONF_DEBUG_RECOVERY },
931 { "DEBUG_AMIDXTAPED" , CONF_DEBUG_AMIDXTAPED },
932 { "DEBUG_AMINDEXD" , CONF_DEBUG_AMINDEXD },
933 { "DEBUG_AMRECOVER" , CONF_DEBUG_AMRECOVER },
934 { "DEBUG_AUTH" , CONF_DEBUG_AUTH },
935 { "DEBUG_EVENT" , CONF_DEBUG_EVENT },
936 { "DEBUG_HOLDING" , CONF_DEBUG_HOLDING },
937 { "DEBUG_PROTOCOL" , CONF_DEBUG_PROTOCOL },
938 { "DEBUG_PLANNER" , CONF_DEBUG_PLANNER },
939 { "DEBUG_DRIVER" , CONF_DEBUG_DRIVER },
940 { "DEBUG_DUMPER" , CONF_DEBUG_DUMPER },
941 { "DEBUG_CHUNKER" , CONF_DEBUG_CHUNKER },
942 { "DEBUG_TAPER" , CONF_DEBUG_TAPER },
943 { "DEBUG_SELFCHECK" , CONF_DEBUG_SELFCHECK },
944 { "DEBUG_SENDSIZE" , CONF_DEBUG_SENDSIZE },
945 { "DEBUG_SENDBACKUP" , CONF_DEBUG_SENDBACKUP },
946 { "DEFINE", CONF_DEFINE },
947 { "DEVICE", CONF_DEVICE },
948 { "DEVICE_PROPERTY", CONF_DEVICE_PROPERTY },
949 { "DIRECTORY", CONF_DIRECTORY },
950 { "DIRECTTCP", CONF_DIRECTTCP },
951 { "DISK", CONF_DISK },
952 { "DISKFILE", CONF_DISKFILE },
953 { "DISPLAYUNIT", CONF_DISPLAYUNIT },
954 { "DTIMEOUT", CONF_DTIMEOUT },
955 { "DUMPCYCLE", CONF_DUMPCYCLE },
956 { "DUMPORDER", CONF_DUMPORDER },
957 { "DUMPTYPE", CONF_DUMPTYPE },
958 { "DUMPUSER", CONF_DUMPUSER },
959 { "DUMP_LIMIT", CONF_DUMP_LIMIT },
960 { "EJECT_VOLUME", CONF_EJECT_VOLUME },
961 { "EMPTY", CONF_EMPTY },
962 { "ENCRYPT", CONF_ENCRYPT },
963 { "ERROR", CONF_ERROR },
964 { "ESTIMATE", CONF_ESTIMATE },
965 { "ETIMEOUT", CONF_ETIMEOUT },
966 { "EXCLUDE", CONF_EXCLUDE },
967 { "EXCLUDE_FILE", CONF_EXCLUDE_FILE },
968 { "EXCLUDE_LIST", CONF_EXCLUDE_LIST },
969 { "EXECUTE_ON", CONF_EXECUTE_ON },
970 { "EXECUTE_WHERE", CONF_EXECUTE_WHERE },
971 { "FALLBACK_SPLITSIZE", CONF_FALLBACK_SPLITSIZE },
972 { "FAST", CONF_FAST },
973 { "FILE", CONF_EFILE },
974 { "FILEMARK", CONF_FILEMARK },
975 { "FIRST", CONF_FIRST },
976 { "FIRSTFIT", CONF_FIRSTFIT },
977 { "HANOI", CONF_HANOI },
978 { "HIGH", CONF_HIGH },
979 { "HOLDINGDISK", CONF_HOLDING },
980 { "IGNORE", CONF_IGNORE },
981 { "INCLUDE", CONF_INCLUDE },
982 { "INCLUDEFILE", CONF_INCLUDEFILE },
983 { "INCRONLY", CONF_INCRONLY },
984 { "INDEX", CONF_INDEX },
985 { "INDEXDIR", CONF_INDEXDIR },
986 { "INFOFILE", CONF_INFOFILE },
987 { "INPARALLEL", CONF_INPARALLEL },
988 { "INTERACTIVITY", CONF_INTERACTIVITY },
989 { "INTERFACE", CONF_INTERFACE },
990 { "KENCRYPT", CONF_KENCRYPT },
991 { "KRB5KEYTAB", CONF_KRB5KEYTAB },
992 { "KRB5PRINCIPAL", CONF_KRB5PRINCIPAL },
993 { "LABELSTR", CONF_LABELSTR },
994 { "LABEL_NEW_TAPES", CONF_LABEL_NEW_TAPES },
995 { "LARGEST", CONF_LARGEST },
996 { "LARGESTFIT", CONF_LARGESTFIT },
997 { "LAST", CONF_LAST },
998 { "LBL_TEMPL", CONF_LBL_TEMPL },
999 { "LENGTH", CONF_LENGTH },
1000 { "LIST", CONF_LIST },
1001 { "LOGDIR", CONF_LOGDIR },
1002 { "LOW", CONF_LOW },
1003 { "MAILER", CONF_MAILER },
1004 { "MAILTO", CONF_MAILTO },
1005 { "READBLOCKSIZE", CONF_READBLOCKSIZE },
1006 { "MAX_DLE_BY_VOLUME", CONF_MAX_DLE_BY_VOLUME },
1007 { "MAXDUMPS", CONF_MAXDUMPS },
1008 { "MAXDUMPSIZE", CONF_MAXDUMPSIZE },
1009 { "MAXPROMOTEDAY", CONF_MAXPROMOTEDAY },
1010 { "MAX_WARNINGS", CONF_MAX_WARNINGS },
1011 { "MEMORY", CONF_MEMORY },
1012 { "MEDIUM", CONF_MEDIUM },
1013 { "META_AUTOLABEL", CONF_META_AUTOLABEL },
1014 { "NETUSAGE", CONF_NETUSAGE },
1015 { "NEVER", CONF_NEVER },
1016 { "NOFULL", CONF_NOFULL },
1017 { "NOINC", CONF_NOINC },
1018 { "NONE", CONF_NONE },
1019 { "NON_AMANDA", CONF_NON_AMANDA },
1020 { "OPTIONAL", CONF_OPTIONAL },
1021 { "ORDER", CONF_ORDER },
1022 { "ORG", CONF_ORG },
1023 { "OTHER_CONFIG", CONF_OTHER_CONFIG },
1024 { "PART_CACHE_DIR", CONF_PART_CACHE_DIR },
1025 { "PART_CACHE_MAX_SIZE", CONF_PART_CACHE_MAX_SIZE },
1026 { "PART_CACHE_TYPE", CONF_PART_CACHE_TYPE },
1027 { "PART_SIZE", CONF_PART_SIZE },
1028 { "PLUGIN", CONF_PLUGIN },
1029 { "PRE_AMCHECK", CONF_PRE_AMCHECK },
1030 { "PRE_DLE_AMCHECK", CONF_PRE_DLE_AMCHECK },
1031 { "PRE_HOST_AMCHECK", CONF_PRE_HOST_AMCHECK },
1032 { "POST_AMCHECK", CONF_POST_AMCHECK },
1033 { "POST_DLE_AMCHECK", CONF_POST_DLE_AMCHECK },
1034 { "POST_HOST_AMCHECK", CONF_POST_HOST_AMCHECK },
1035 { "PRE_ESTIMATE", CONF_PRE_ESTIMATE },
1036 { "PRE_DLE_ESTIMATE", CONF_PRE_DLE_ESTIMATE },
1037 { "PRE_HOST_ESTIMATE", CONF_PRE_HOST_ESTIMATE },
1038 { "POST_ESTIMATE", CONF_POST_ESTIMATE },
1039 { "POST_DLE_ESTIMATE", CONF_POST_DLE_ESTIMATE },
1040 { "POST_HOST_ESTIMATE", CONF_POST_HOST_ESTIMATE },
1041 { "POST_BACKUP", CONF_POST_BACKUP },
1042 { "POST_DLE_BACKUP", CONF_POST_DLE_BACKUP },
1043 { "POST_HOST_BACKUP", CONF_POST_HOST_BACKUP },
1044 { "PRE_BACKUP", CONF_PRE_BACKUP },
1045 { "PRE_DLE_BACKUP", CONF_PRE_DLE_BACKUP },
1046 { "PRE_HOST_BACKUP", CONF_PRE_HOST_BACKUP },
1047 { "PRE_RECOVER", CONF_PRE_RECOVER },
1048 { "POST_RECOVER", CONF_POST_RECOVER },
1049 { "PRE_LEVEL_RECOVER", CONF_PRE_LEVEL_RECOVER },
1050 { "POST_LEVEL_RECOVER", CONF_POST_LEVEL_RECOVER },
1051 { "INTER_LEVEL_RECOVER", CONF_INTER_LEVEL_RECOVER },
1052 { "PRINTER", CONF_PRINTER },
1053 { "PRIORITY", CONF_PRIORITY },
1054 { "PROGRAM", CONF_PROGRAM },
1055 { "PROPERTY", CONF_PROPERTY },
1056 { "RECORD", CONF_RECORD },
1057 { "RECOVERY_LIMIT", CONF_RECOVERY_LIMIT },
1058 { "REP_TRIES", CONF_REP_TRIES },
1059 { "REPORT_USE_MEDIA", CONF_REPORT_USE_MEDIA },
1060 { "REPORT_NEXT_MEDIA", CONF_REPORT_NEXT_MEDIA },
1061 { "REQ_TRIES", CONF_REQ_TRIES },
1062 { "REQUIRED", CONF_REQUIRED },
1063 { "RESERVE", CONF_RESERVE },
1064 { "RESERVED_UDP_PORT", CONF_RESERVED_UDP_PORT },
1065 { "RESERVED_TCP_PORT", CONF_RESERVED_TCP_PORT },
1066 { "RUNSPERCYCLE", CONF_RUNSPERCYCLE },
1067 { "RUNTAPES", CONF_RUNTAPES },
1068 { "SAME_HOST", CONF_SAME_HOST },
1069 { "SCRIPT", CONF_SCRIPT },
1070 { "SCRIPT_TOOL", CONF_SCRIPT_TOOL },
1071 { "SEND_AMREPORT_ON", CONF_SEND_AMREPORT_ON },
1072 { "CLIENT_PORT", CONF_CLIENT_PORT },
1073 { "SERVER", CONF_SERVER },
1074 { "SERVER_CUSTOM_COMPRESS", CONF_SRVCOMPPROG },
1075 { "SERVER_DECRYPT_OPTION", CONF_SRV_DECRYPT_OPT },
1076 { "SERVER_ENCRYPT", CONF_SRV_ENCRYPT },
1077 { "SKIP", CONF_SKIP },
1078 { "SKIP_FULL", CONF_SKIP_FULL },
1079 { "SKIP_INCR", CONF_SKIP_INCR },
1080 { "SINGLE_EXECUTION", CONF_SINGLE_EXECUTION },
1081 { "SMALLEST", CONF_SMALLEST },
1082 { "SPEED", CONF_SPEED },
1083 { "SPLIT_DISKBUFFER", CONF_SPLIT_DISKBUFFER },
1084 { "SSH_KEYS", CONF_SSH_KEYS },
1085 { "STANDARD", CONF_STANDARD },
1086 { "STARTTIME", CONF_STARTTIME },
1087 { "STRANGE", CONF_STRANGE },
1088 { "STRATEGY", CONF_STRATEGY },
1089 { "DEVICE_OUTPUT_BUFFER_SIZE", CONF_DEVICE_OUTPUT_BUFFER_SIZE },
1090 { "TAPECYCLE", CONF_TAPECYCLE },
1091 { "TAPEDEV", CONF_TAPEDEV },
1092 { "TAPELIST", CONF_TAPELIST },
1093 { "TAPERALGO", CONF_TAPERALGO },
1094 { "TAPERSCAN", CONF_TAPERSCAN },
1095 { "TAPER_PARALLEL_WRITE", CONF_TAPER_PARALLEL_WRITE },
1096 { "FLUSH_THRESHOLD_DUMPED", CONF_FLUSH_THRESHOLD_DUMPED },
1097 { "FLUSH_THRESHOLD_SCHEDULED", CONF_FLUSH_THRESHOLD_SCHEDULED },
1098 { "TAPERFLUSH", CONF_TAPERFLUSH },
1099 { "TAPETYPE", CONF_TAPETYPE },
1100 { "TAPE_SPLITSIZE", CONF_TAPE_SPLITSIZE },
1101 { "TMPDIR", CONF_TMPDIR },
1102 { "TPCHANGER", CONF_TPCHANGER },
1103 { "UNRESERVED_TCP_PORT", CONF_UNRESERVED_TCP_PORT },
1104 { "USE", CONF_USE },
1105 { "USETIMESTAMPS", CONF_USETIMESTAMPS },
1106 { "VOLUME_ERROR", CONF_VOLUME_ERROR },
1107 { NULL, CONF_IDENT },
1108 { NULL, CONF_UNKNOWN }
1111 /* A keyword table for recognizing unit suffixes. No distinction is made for kinds
1112 * of suffixes: 1024 weeks = 7 k. */
1113 keytab_t numb_keytable[] = {
1114 { "B", CONF_MULT1 },
1115 { "BPS", CONF_MULT1 },
1116 { "BYTE", CONF_MULT1 },
1117 { "BYTES", CONF_MULT1 },
1118 { "DAY", CONF_MULT1 },
1119 { "DAYS", CONF_MULT1 },
1120 { "INF", CONF_AMINFINITY },
1121 { "K", CONF_MULT1K },
1122 { "KB", CONF_MULT1K },
1123 { "KBPS", CONF_MULT1K },
1124 { "KBYTE", CONF_MULT1K },
1125 { "KBYTES", CONF_MULT1K },
1126 { "KILOBYTE", CONF_MULT1K },
1127 { "KILOBYTES", CONF_MULT1K },
1128 { "KPS", CONF_MULT1K },
1129 { "M", CONF_MULT1M },
1130 { "MB", CONF_MULT1M },
1131 { "MBPS", CONF_MULT1M },
1132 { "MBYTE", CONF_MULT1M },
1133 { "MBYTES", CONF_MULT1M },
1134 { "MEG", CONF_MULT1M },
1135 { "MEGABYTE", CONF_MULT1M },
1136 { "MEGABYTES", CONF_MULT1M },
1137 { "G", CONF_MULT1G },
1138 { "GB", CONF_MULT1G },
1139 { "GBPS", CONF_MULT1G },
1140 { "GBYTE", CONF_MULT1G },
1141 { "GBYTES", CONF_MULT1G },
1142 { "GIG", CONF_MULT1G },
1143 { "GIGABYTE", CONF_MULT1G },
1144 { "GIGABYTES", CONF_MULT1G },
1145 { "T", CONF_MULT1T },
1146 { "TB", CONF_MULT1T },
1147 { "TBPS", CONF_MULT1T },
1148 { "TBYTE", CONF_MULT1T },
1149 { "TBYTES", CONF_MULT1T },
1150 { "TERA", CONF_MULT1T },
1151 { "TERABYTE", CONF_MULT1T },
1152 { "TERABYTES", CONF_MULT1T },
1153 { "MPS", CONF_MULT1M },
1154 { "TAPE", CONF_MULT1 },
1155 { "TAPES", CONF_MULT1 },
1156 { "WEEK", CONF_MULT7 },
1157 { "WEEKS", CONF_MULT7 },
1158 { NULL, CONF_IDENT }
1161 /* Boolean keywords -- all the ways to say "true" and "false" in amanda.conf */
1162 keytab_t bool_keytable[] = {
1163 { "Y", CONF_ATRUE },
1164 { "YES", CONF_ATRUE },
1165 { "T", CONF_ATRUE },
1166 { "TRUE", CONF_ATRUE },
1167 { "ON", CONF_ATRUE },
1168 { "N", CONF_AFALSE },
1169 { "NO", CONF_AFALSE },
1170 { "F", CONF_AFALSE },
1171 { "FALSE", CONF_AFALSE },
1172 { "OFF", CONF_AFALSE },
1173 { NULL, CONF_IDENT }
1176 /* no_yes_all keywords -- all the ways to say "true" and "false" in amanda.conf */
1177 keytab_t no_yes_all_keytable[] = {
1178 { "Y", CONF_ATRUE },
1179 { "YES", CONF_ATRUE },
1180 { "T", CONF_ATRUE },
1181 { "TRUE", CONF_ATRUE },
1182 { "ON", CONF_ATRUE },
1183 { "N", CONF_AFALSE },
1184 { "NO", CONF_AFALSE },
1185 { "F", CONF_AFALSE },
1186 { "FALSE", CONF_AFALSE },
1187 { "OFF", CONF_AFALSE },
1188 { "ALL", CONF_ALL },
1189 { NULL, CONF_IDENT }
1192 /* Now, the parser tables for client and server global parameters, and for
1193 * each of the server subsections */
1194 conf_var_t client_var [] = {
1195 { CONF_CONF , CONFTYPE_STR , read_str , CNF_CONF , NULL },
1196 { CONF_AMDUMP_SERVER , CONFTYPE_STR , read_str , CNF_AMDUMP_SERVER , NULL },
1197 { CONF_INDEX_SERVER , CONFTYPE_STR , read_str , CNF_INDEX_SERVER , NULL },
1198 { CONF_TAPE_SERVER , CONFTYPE_STR , read_str , CNF_TAPE_SERVER , NULL },
1199 { CONF_TAPEDEV , CONFTYPE_STR , read_str , CNF_TAPEDEV , NULL },
1200 { CONF_AUTH , CONFTYPE_STR , read_str , CNF_AUTH , NULL },
1201 { CONF_SSH_KEYS , CONFTYPE_STR , read_str , CNF_SSH_KEYS , NULL },
1202 { CONF_AMANDAD_PATH , CONFTYPE_STR , read_str , CNF_AMANDAD_PATH , NULL },
1203 { CONF_CLIENT_USERNAME , CONFTYPE_STR , read_str , CNF_CLIENT_USERNAME , NULL },
1204 { CONF_CLIENT_PORT , CONFTYPE_STR , read_int_or_str, CNF_CLIENT_PORT , NULL },
1205 { CONF_GNUTAR_LIST_DIR , CONFTYPE_STR , read_str , CNF_GNUTAR_LIST_DIR , NULL },
1206 { CONF_AMANDATES , CONFTYPE_STR , read_str , CNF_AMANDATES , NULL },
1207 { CONF_MAILER , CONFTYPE_STR , read_str , CNF_MAILER , NULL },
1208 { CONF_KRB5KEYTAB , CONFTYPE_STR , read_str , CNF_KRB5KEYTAB , NULL },
1209 { CONF_KRB5PRINCIPAL , CONFTYPE_STR , read_str , CNF_KRB5PRINCIPAL , NULL },
1210 { CONF_CONNECT_TRIES , CONFTYPE_INT , read_int , CNF_CONNECT_TRIES , validate_positive },
1211 { CONF_REP_TRIES , CONFTYPE_INT , read_int , CNF_REP_TRIES , validate_positive },
1212 { CONF_REQ_TRIES , CONFTYPE_INT , read_int , CNF_REQ_TRIES , validate_positive },
1213 { CONF_DEBUG_DAYS , CONFTYPE_INT , read_int , CNF_DEBUG_DAYS , NULL },
1214 { CONF_DEBUG_AMANDAD , CONFTYPE_INT , read_int , CNF_DEBUG_AMANDAD , validate_debug },
1215 { CONF_DEBUG_RECOVERY , CONFTYPE_INT , read_int , CNF_DEBUG_RECOVERY , validate_debug },
1216 { CONF_DEBUG_AMIDXTAPED , CONFTYPE_INT , read_int , CNF_DEBUG_AMIDXTAPED , validate_debug },
1217 { CONF_DEBUG_AMINDEXD , CONFTYPE_INT , read_int , CNF_DEBUG_AMINDEXD , validate_debug },
1218 { CONF_DEBUG_AMRECOVER , CONFTYPE_INT , read_int , CNF_DEBUG_AMRECOVER , validate_debug },
1219 { CONF_DEBUG_AUTH , CONFTYPE_INT , read_int , CNF_DEBUG_AUTH , validate_debug },
1220 { CONF_DEBUG_EVENT , CONFTYPE_INT , read_int , CNF_DEBUG_EVENT , validate_debug },
1221 { CONF_DEBUG_HOLDING , CONFTYPE_INT , read_int , CNF_DEBUG_HOLDING , validate_debug },
1222 { CONF_DEBUG_PROTOCOL , CONFTYPE_INT , read_int , CNF_DEBUG_PROTOCOL , validate_debug },
1223 { CONF_DEBUG_PLANNER , CONFTYPE_INT , read_int , CNF_DEBUG_PLANNER , validate_debug },
1224 { CONF_DEBUG_DRIVER , CONFTYPE_INT , read_int , CNF_DEBUG_DRIVER , validate_debug },
1225 { CONF_DEBUG_DUMPER , CONFTYPE_INT , read_int , CNF_DEBUG_DUMPER , validate_debug },
1226 { CONF_DEBUG_CHUNKER , CONFTYPE_INT , read_int , CNF_DEBUG_CHUNKER , validate_debug },
1227 { CONF_DEBUG_TAPER , CONFTYPE_INT , read_int , CNF_DEBUG_TAPER , validate_debug },
1228 { CONF_DEBUG_SELFCHECK , CONFTYPE_INT , read_int , CNF_DEBUG_SELFCHECK , validate_debug },
1229 { CONF_DEBUG_SENDSIZE , CONFTYPE_INT , read_int , CNF_DEBUG_SENDSIZE , validate_debug },
1230 { CONF_DEBUG_SENDBACKUP , CONFTYPE_INT , read_int , CNF_DEBUG_SENDBACKUP , validate_debug },
1231 { CONF_RESERVED_UDP_PORT , CONFTYPE_INTRANGE, read_intrange, CNF_RESERVED_UDP_PORT , validate_reserved_port_range },
1232 { CONF_RESERVED_TCP_PORT , CONFTYPE_INTRANGE, read_intrange, CNF_RESERVED_TCP_PORT , validate_reserved_port_range },
1233 { CONF_UNRESERVED_TCP_PORT, CONFTYPE_INTRANGE, read_intrange, CNF_UNRESERVED_TCP_PORT, validate_unreserved_port_range },
1234 { CONF_PROPERTY , CONFTYPE_PROPLIST, read_property, CNF_PROPERTY , NULL },
1235 { CONF_APPLICATION , CONFTYPE_STR , read_dapplication, DUMPTYPE_APPLICATION, NULL },
1236 { CONF_SCRIPT , CONFTYPE_STR , read_dpp_script, DUMPTYPE_SCRIPTLIST, NULL },
1237 { CONF_UNKNOWN , CONFTYPE_INT , NULL , CNF_CNF , NULL }
1240 conf_var_t server_var [] = {
1241 { CONF_ORG , CONFTYPE_STR , read_str , CNF_ORG , NULL },
1242 { CONF_MAILTO , CONFTYPE_STR , read_str , CNF_MAILTO , NULL },
1243 { CONF_DUMPUSER , CONFTYPE_STR , read_str , CNF_DUMPUSER , NULL },
1244 { CONF_PRINTER , CONFTYPE_STR , read_str , CNF_PRINTER , NULL },
1245 { CONF_MAILER , CONFTYPE_STR , read_str , CNF_MAILER , NULL },
1246 { CONF_TAPEDEV , CONFTYPE_STR , read_str , CNF_TAPEDEV , NULL },
1247 { CONF_DEVICE_PROPERTY , CONFTYPE_PROPLIST , read_property , CNF_DEVICE_PROPERTY , NULL },
1248 { CONF_PROPERTY , CONFTYPE_PROPLIST , read_property , CNF_PROPERTY , NULL },
1249 { CONF_TPCHANGER , CONFTYPE_STR , read_str , CNF_TPCHANGER , NULL },
1250 { CONF_CHANGERDEV , CONFTYPE_STR , read_str , CNF_CHANGERDEV , NULL },
1251 { CONF_CHANGERFILE , CONFTYPE_STR , read_str , CNF_CHANGERFILE , NULL },
1252 { CONF_LABELSTR , CONFTYPE_STR , read_str , CNF_LABELSTR , NULL },
1253 { CONF_TAPELIST , CONFTYPE_STR , read_str , CNF_TAPELIST , NULL },
1254 { CONF_DISKFILE , CONFTYPE_STR , read_str , CNF_DISKFILE , NULL },
1255 { CONF_INFOFILE , CONFTYPE_STR , read_str , CNF_INFOFILE , NULL },
1256 { CONF_LOGDIR , CONFTYPE_STR , read_str , CNF_LOGDIR , NULL },
1257 { CONF_INDEXDIR , CONFTYPE_STR , read_str , CNF_INDEXDIR , NULL },
1258 { CONF_TAPETYPE , CONFTYPE_IDENT , read_ident , CNF_TAPETYPE , NULL },
1259 { CONF_HOLDING , CONFTYPE_IDENTLIST, read_holdingdisk , CNF_HOLDINGDISK , NULL },
1260 { CONF_DUMPCYCLE , CONFTYPE_INT , read_int , CNF_DUMPCYCLE , validate_nonnegative },
1261 { CONF_RUNSPERCYCLE , CONFTYPE_INT , read_int , CNF_RUNSPERCYCLE , validate_runspercycle },
1262 { CONF_RUNTAPES , CONFTYPE_INT , read_int , CNF_RUNTAPES , validate_nonnegative },
1263 { CONF_TAPECYCLE , CONFTYPE_INT , read_int , CNF_TAPECYCLE , validate_positive },
1264 { CONF_BUMPDAYS , CONFTYPE_INT , read_int , CNF_BUMPDAYS , validate_positive },
1265 { CONF_BUMPSIZE , CONFTYPE_INT64 , read_int64 , CNF_BUMPSIZE , validate_positive },
1266 { CONF_BUMPPERCENT , CONFTYPE_INT , read_int , CNF_BUMPPERCENT , validate_bumppercent },
1267 { CONF_BUMPMULT , CONFTYPE_REAL , read_real , CNF_BUMPMULT , validate_bumpmult },
1268 { CONF_NETUSAGE , CONFTYPE_INT , read_int , CNF_NETUSAGE , validate_positive },
1269 { CONF_INPARALLEL , CONFTYPE_INT , read_int , CNF_INPARALLEL , validate_inparallel },
1270 { CONF_DUMPORDER , CONFTYPE_STR , read_str , CNF_DUMPORDER , NULL },
1271 { CONF_MAXDUMPS , CONFTYPE_INT , read_int , CNF_MAXDUMPS , validate_positive },
1272 { CONF_MAX_DLE_BY_VOLUME , CONFTYPE_INT , read_int , CNF_MAX_DLE_BY_VOLUME , validate_positive },
1273 { CONF_ETIMEOUT , CONFTYPE_INT , read_int , CNF_ETIMEOUT , validate_non_zero },
1274 { CONF_DTIMEOUT , CONFTYPE_INT , read_int , CNF_DTIMEOUT , validate_positive },
1275 { CONF_CTIMEOUT , CONFTYPE_INT , read_int , CNF_CTIMEOUT , validate_positive },
1276 { CONF_DEVICE_OUTPUT_BUFFER_SIZE, CONFTYPE_SIZE , read_size , CNF_DEVICE_OUTPUT_BUFFER_SIZE, validate_positive },
1277 { CONF_COLUMNSPEC , CONFTYPE_STR , read_str , CNF_COLUMNSPEC , NULL },
1278 { CONF_TAPERALGO , CONFTYPE_TAPERALGO, read_taperalgo , CNF_TAPERALGO , NULL },
1279 { CONF_TAPER_PARALLEL_WRITE , CONFTYPE_INT , read_int , CNF_TAPER_PARALLEL_WRITE , NULL },
1280 { CONF_SEND_AMREPORT_ON , CONFTYPE_SEND_AMREPORT_ON, read_send_amreport_on, CNF_SEND_AMREPORT_ON , NULL },
1281 { CONF_FLUSH_THRESHOLD_DUMPED, CONFTYPE_INT , read_int , CNF_FLUSH_THRESHOLD_DUMPED, validate_nonnegative },
1282 { CONF_FLUSH_THRESHOLD_SCHEDULED, CONFTYPE_INT , read_int , CNF_FLUSH_THRESHOLD_SCHEDULED, validate_nonnegative },
1283 { CONF_TAPERFLUSH , CONFTYPE_INT , read_int , CNF_TAPERFLUSH , validate_nonnegative },
1284 { CONF_DISPLAYUNIT , CONFTYPE_STR , read_str , CNF_DISPLAYUNIT , validate_displayunit },
1285 { CONF_AUTOFLUSH , CONFTYPE_NO_YES_ALL,read_no_yes_all , CNF_AUTOFLUSH , NULL },
1286 { CONF_RESERVE , CONFTYPE_INT , read_int , CNF_RESERVE , validate_reserve },
1287 { CONF_MAXDUMPSIZE , CONFTYPE_INT64 , read_int64 , CNF_MAXDUMPSIZE , NULL },
1288 { CONF_KRB5KEYTAB , CONFTYPE_STR , read_str , CNF_KRB5KEYTAB , NULL },
1289 { CONF_KRB5PRINCIPAL , CONFTYPE_STR , read_str , CNF_KRB5PRINCIPAL , NULL },
1290 { CONF_LABEL_NEW_TAPES , CONFTYPE_STR , read_str , CNF_LABEL_NEW_TAPES , NULL },
1291 { CONF_AUTOLABEL , CONFTYPE_AUTOLABEL, read_autolabel , CNF_AUTOLABEL , NULL },
1292 { CONF_META_AUTOLABEL , CONFTYPE_STR , read_str , CNF_META_AUTOLABEL , NULL },
1293 { CONF_EJECT_VOLUME , CONFTYPE_BOOLEAN , read_bool , CNF_EJECT_VOLUME , NULL },
1294 { CONF_TMPDIR , CONFTYPE_STR , read_str , CNF_TMPDIR , validate_tmpdir },
1295 { CONF_USETIMESTAMPS , CONFTYPE_BOOLEAN , read_bool , CNF_USETIMESTAMPS , NULL },
1296 { CONF_AMRECOVER_DO_FSF , CONFTYPE_BOOLEAN , read_bool , CNF_AMRECOVER_DO_FSF , NULL },
1297 { CONF_AMRECOVER_CHANGER , CONFTYPE_STR , read_str , CNF_AMRECOVER_CHANGER , NULL },
1298 { CONF_AMRECOVER_CHECK_LABEL, CONFTYPE_BOOLEAN , read_bool , CNF_AMRECOVER_CHECK_LABEL, NULL },
1299 { CONF_CONNECT_TRIES , CONFTYPE_INT , read_int , CNF_CONNECT_TRIES , validate_positive },
1300 { CONF_REP_TRIES , CONFTYPE_INT , read_int , CNF_REP_TRIES , validate_positive },
1301 { CONF_REQ_TRIES , CONFTYPE_INT , read_int , CNF_REQ_TRIES , validate_positive },
1302 { CONF_DEBUG_DAYS , CONFTYPE_INT , read_int , CNF_DEBUG_DAYS , NULL },
1303 { CONF_DEBUG_AMANDAD , CONFTYPE_INT , read_int , CNF_DEBUG_AMANDAD , validate_debug },
1304 { CONF_DEBUG_RECOVERY , CONFTYPE_INT , read_int , CNF_DEBUG_RECOVERY , validate_debug },
1305 { CONF_DEBUG_AMIDXTAPED , CONFTYPE_INT , read_int , CNF_DEBUG_AMIDXTAPED , validate_debug },
1306 { CONF_DEBUG_AMINDEXD , CONFTYPE_INT , read_int , CNF_DEBUG_AMINDEXD , validate_debug },
1307 { CONF_DEBUG_AMRECOVER , CONFTYPE_INT , read_int , CNF_DEBUG_AMRECOVER , validate_debug },
1308 { CONF_DEBUG_AUTH , CONFTYPE_INT , read_int , CNF_DEBUG_AUTH , validate_debug },
1309 { CONF_DEBUG_EVENT , CONFTYPE_INT , read_int , CNF_DEBUG_EVENT , validate_debug },
1310 { CONF_DEBUG_HOLDING , CONFTYPE_INT , read_int , CNF_DEBUG_HOLDING , validate_debug },
1311 { CONF_DEBUG_PROTOCOL , CONFTYPE_INT , read_int , CNF_DEBUG_PROTOCOL , validate_debug },
1312 { CONF_DEBUG_PLANNER , CONFTYPE_INT , read_int , CNF_DEBUG_PLANNER , validate_debug },
1313 { CONF_DEBUG_DRIVER , CONFTYPE_INT , read_int , CNF_DEBUG_DRIVER , validate_debug },
1314 { CONF_DEBUG_DUMPER , CONFTYPE_INT , read_int , CNF_DEBUG_DUMPER , validate_debug },
1315 { CONF_DEBUG_CHUNKER , CONFTYPE_INT , read_int , CNF_DEBUG_CHUNKER , validate_debug },
1316 { CONF_DEBUG_TAPER , CONFTYPE_INT , read_int , CNF_DEBUG_TAPER , validate_debug },
1317 { CONF_DEBUG_SELFCHECK , CONFTYPE_INT , read_int , CNF_DEBUG_SELFCHECK , validate_debug },
1318 { CONF_DEBUG_SENDSIZE , CONFTYPE_INT , read_int , CNF_DEBUG_SENDSIZE , validate_debug },
1319 { CONF_DEBUG_SENDBACKUP , CONFTYPE_INT , read_int , CNF_DEBUG_SENDBACKUP , validate_debug },
1320 { CONF_RESERVED_UDP_PORT , CONFTYPE_INTRANGE , read_intrange , CNF_RESERVED_UDP_PORT , validate_reserved_port_range },
1321 { CONF_RESERVED_TCP_PORT , CONFTYPE_INTRANGE , read_intrange , CNF_RESERVED_TCP_PORT , validate_reserved_port_range },
1322 { CONF_UNRESERVED_TCP_PORT , CONFTYPE_INTRANGE , read_intrange , CNF_UNRESERVED_TCP_PORT , validate_unreserved_port_range },
1323 { CONF_RECOVERY_LIMIT , CONFTYPE_HOST_LIMIT, read_host_limit , CNF_RECOVERY_LIMIT , NULL },
1324 { CONF_INTERACTIVITY , CONFTYPE_STR , read_dinteractivity, CNF_INTERACTIVITY , NULL },
1325 { CONF_TAPERSCAN , CONFTYPE_STR , read_dtaperscan , CNF_TAPERSCAN , NULL },
1326 { CONF_REPORT_USE_MEDIA , CONFTYPE_BOOLEAN , read_bool , CNF_REPORT_USE_MEDIA , NULL },
1327 { CONF_REPORT_NEXT_MEDIA , CONFTYPE_BOOLEAN , read_bool , CNF_REPORT_NEXT_MEDIA , NULL },
1328 { CONF_UNKNOWN , CONFTYPE_INT , NULL , CNF_CNF , NULL }
1331 conf_var_t tapetype_var [] = {
1332 { CONF_COMMENT , CONFTYPE_STR , read_str , TAPETYPE_COMMENT , NULL },
1333 { CONF_LBL_TEMPL , CONFTYPE_STR , read_str , TAPETYPE_LBL_TEMPL , NULL },
1334 { CONF_BLOCKSIZE , CONFTYPE_SIZE , read_size , TAPETYPE_BLOCKSIZE , validate_blocksize },
1335 { CONF_READBLOCKSIZE , CONFTYPE_SIZE , read_size , TAPETYPE_READBLOCKSIZE , validate_blocksize },
1336 { CONF_LENGTH , CONFTYPE_INT64 , read_int64 , TAPETYPE_LENGTH , validate_nonnegative },
1337 { CONF_FILEMARK , CONFTYPE_INT64 , read_int64 , TAPETYPE_FILEMARK , NULL },
1338 { CONF_SPEED , CONFTYPE_INT , read_int , TAPETYPE_SPEED , validate_nonnegative },
1339 { CONF_PART_SIZE , CONFTYPE_INT64 , read_int64 , TAPETYPE_PART_SIZE , validate_nonnegative },
1340 { CONF_PART_CACHE_TYPE , CONFTYPE_PART_CACHE_TYPE, read_part_cache_type, TAPETYPE_PART_CACHE_TYPE, NULL },
1341 { CONF_PART_CACHE_DIR , CONFTYPE_STR , read_str , TAPETYPE_PART_CACHE_DIR , NULL },
1342 { CONF_PART_CACHE_MAX_SIZE , CONFTYPE_INT64 , read_int64 , TAPETYPE_PART_CACHE_MAX_SIZE, validate_nonnegative },
1343 { CONF_UNKNOWN , CONFTYPE_INT , NULL , TAPETYPE_TAPETYPE , NULL }
1346 conf_var_t dumptype_var [] = {
1347 { CONF_COMMENT , CONFTYPE_STR , read_str , DUMPTYPE_COMMENT , NULL },
1348 { CONF_AUTH , CONFTYPE_STR , read_str , DUMPTYPE_AUTH , NULL },
1349 { CONF_BUMPDAYS , CONFTYPE_INT , read_int , DUMPTYPE_BUMPDAYS , NULL },
1350 { CONF_BUMPMULT , CONFTYPE_REAL , read_real , DUMPTYPE_BUMPMULT , NULL },
1351 { CONF_BUMPSIZE , CONFTYPE_INT64 , read_int64 , DUMPTYPE_BUMPSIZE , NULL },
1352 { CONF_BUMPPERCENT , CONFTYPE_INT , read_int , DUMPTYPE_BUMPPERCENT , NULL },
1353 { CONF_COMPRATE , CONFTYPE_REAL , read_rate , DUMPTYPE_COMPRATE , NULL },
1354 { CONF_COMPRESS , CONFTYPE_INT , read_compress , DUMPTYPE_COMPRESS , NULL },
1355 { CONF_ENCRYPT , CONFTYPE_INT , read_encrypt , DUMPTYPE_ENCRYPT , NULL },
1356 { CONF_DUMPCYCLE , CONFTYPE_INT , read_int , DUMPTYPE_DUMPCYCLE , validate_nonnegative },
1357 { CONF_EXCLUDE , CONFTYPE_EXINCLUDE, read_exinclude, DUMPTYPE_EXCLUDE , NULL },
1358 { CONF_INCLUDE , CONFTYPE_EXINCLUDE, read_exinclude, DUMPTYPE_INCLUDE , NULL },
1359 { CONF_IGNORE , CONFTYPE_BOOLEAN , read_bool , DUMPTYPE_IGNORE , NULL },
1360 { CONF_HOLDING , CONFTYPE_HOLDING , read_holding , DUMPTYPE_HOLDINGDISK , NULL },
1361 { CONF_INDEX , CONFTYPE_BOOLEAN , read_bool , DUMPTYPE_INDEX , NULL },
1362 { CONF_KENCRYPT , CONFTYPE_BOOLEAN , read_bool , DUMPTYPE_KENCRYPT , NULL },
1363 { CONF_MAXDUMPS , CONFTYPE_INT , read_int , DUMPTYPE_MAXDUMPS , validate_positive },
1364 { CONF_MAXPROMOTEDAY , CONFTYPE_INT , read_int , DUMPTYPE_MAXPROMOTEDAY , validate_nonnegative },
1365 { CONF_PRIORITY , CONFTYPE_PRIORITY , read_priority , DUMPTYPE_PRIORITY , NULL },
1366 { CONF_PROGRAM , CONFTYPE_STR , read_str , DUMPTYPE_PROGRAM , validate_program },
1367 { CONF_PROPERTY , CONFTYPE_PROPLIST , read_property , DUMPTYPE_PROPERTY , NULL },
1368 { CONF_RECORD , CONFTYPE_BOOLEAN , read_bool , DUMPTYPE_RECORD , NULL },
1369 { CONF_SKIP_FULL , CONFTYPE_BOOLEAN , read_bool , DUMPTYPE_SKIP_FULL , NULL },
1370 { CONF_SKIP_INCR , CONFTYPE_BOOLEAN , read_bool , DUMPTYPE_SKIP_INCR , NULL },
1371 { CONF_STARTTIME , CONFTYPE_TIME , read_time , DUMPTYPE_STARTTIME , NULL },
1372 { CONF_STRATEGY , CONFTYPE_INT , read_strategy , DUMPTYPE_STRATEGY , NULL },
1373 { CONF_TAPE_SPLITSIZE , CONFTYPE_INT64 , read_int64 , DUMPTYPE_TAPE_SPLITSIZE , validate_nonnegative },
1374 { CONF_SPLIT_DISKBUFFER , CONFTYPE_STR , read_str , DUMPTYPE_SPLIT_DISKBUFFER , NULL },
1375 { CONF_ESTIMATE , CONFTYPE_ESTIMATELIST, read_estimatelist , DUMPTYPE_ESTIMATELIST , NULL },
1376 { CONF_SRV_ENCRYPT , CONFTYPE_STR , read_str , DUMPTYPE_SRV_ENCRYPT , NULL },
1377 { CONF_CLNT_ENCRYPT , CONFTYPE_STR , read_str , DUMPTYPE_CLNT_ENCRYPT , NULL },
1378 { CONF_AMANDAD_PATH , CONFTYPE_STR , read_str , DUMPTYPE_AMANDAD_PATH , NULL },
1379 { CONF_CLIENT_USERNAME , CONFTYPE_STR , read_str , DUMPTYPE_CLIENT_USERNAME , NULL },
1380 { CONF_CLIENT_PORT , CONFTYPE_STR , read_int_or_str, DUMPTYPE_CLIENT_PORT , NULL },
1381 { CONF_SSH_KEYS , CONFTYPE_STR , read_str , DUMPTYPE_SSH_KEYS , NULL },
1382 { CONF_SRVCOMPPROG , CONFTYPE_STR , read_str , DUMPTYPE_SRVCOMPPROG , NULL },
1383 { CONF_CLNTCOMPPROG , CONFTYPE_STR , read_str , DUMPTYPE_CLNTCOMPPROG , NULL },
1384 { CONF_FALLBACK_SPLITSIZE, CONFTYPE_INT64 , read_int64 , DUMPTYPE_FALLBACK_SPLITSIZE, NULL },
1385 { CONF_SRV_DECRYPT_OPT , CONFTYPE_STR , read_str , DUMPTYPE_SRV_DECRYPT_OPT , NULL },
1386 { CONF_CLNT_DECRYPT_OPT , CONFTYPE_STR , read_str , DUMPTYPE_CLNT_DECRYPT_OPT , NULL },
1387 { CONF_APPLICATION , CONFTYPE_STR , read_dapplication, DUMPTYPE_APPLICATION , NULL },
1388 { CONF_SCRIPT , CONFTYPE_STR , read_dpp_script, DUMPTYPE_SCRIPTLIST , NULL },
1389 { CONF_DATA_PATH , CONFTYPE_DATA_PATH, read_data_path, DUMPTYPE_DATA_PATH , NULL },
1390 { CONF_ALLOW_SPLIT , CONFTYPE_BOOLEAN , read_bool , DUMPTYPE_ALLOW_SPLIT , NULL },
1391 { CONF_MAX_WARNINGS , CONFTYPE_INT , read_int , DUMPTYPE_MAX_WARNINGS , validate_nonnegative },
1392 { CONF_RECOVERY_LIMIT , CONFTYPE_HOST_LIMIT, read_host_limit, DUMPTYPE_RECOVERY_LIMIT , NULL },
1393 { CONF_DUMP_LIMIT , CONFTYPE_HOST_LIMIT, read_host_limit, DUMPTYPE_DUMP_LIMIT , validate_dump_limit },
1394 { CONF_UNKNOWN , CONFTYPE_INT , NULL , DUMPTYPE_DUMPTYPE , NULL }
1397 conf_var_t holding_var [] = {
1398 { CONF_DIRECTORY, CONFTYPE_STR , read_str , HOLDING_DISKDIR , NULL },
1399 { CONF_COMMENT , CONFTYPE_STR , read_str , HOLDING_COMMENT , NULL },
1400 { CONF_USE , CONFTYPE_INT64 , read_int64 , HOLDING_DISKSIZE , validate_use },
1401 { CONF_CHUNKSIZE, CONFTYPE_INT64 , read_int64 , HOLDING_CHUNKSIZE, validate_chunksize },
1402 { CONF_UNKNOWN , CONFTYPE_INT , NULL , HOLDING_HOLDING , NULL }
1405 conf_var_t interface_var [] = {
1406 { CONF_COMMENT, CONFTYPE_STR , read_str , INTER_COMMENT , NULL },
1407 { CONF_USE , CONFTYPE_INT , read_int , INTER_MAXUSAGE, validate_positive },
1408 { CONF_UNKNOWN, CONFTYPE_INT , NULL , INTER_INTER , NULL }
1412 conf_var_t application_var [] = {
1413 { CONF_COMMENT , CONFTYPE_STR , read_str , APPLICATION_COMMENT , NULL },
1414 { CONF_PLUGIN , CONFTYPE_STR , read_str , APPLICATION_PLUGIN , NULL },
1415 { CONF_PROPERTY , CONFTYPE_PROPLIST, read_property, APPLICATION_PROPERTY , NULL },
1416 { CONF_CLIENT_NAME, CONFTYPE_STR , read_str , APPLICATION_CLIENT_NAME, NULL },
1417 { CONF_UNKNOWN , CONFTYPE_INT , NULL , APPLICATION_APPLICATION, NULL }
1420 conf_var_t pp_script_var [] = {
1421 { CONF_COMMENT , CONFTYPE_STR , read_str , PP_SCRIPT_COMMENT , NULL },
1422 { CONF_PLUGIN , CONFTYPE_STR , read_str , PP_SCRIPT_PLUGIN , NULL },
1423 { CONF_PROPERTY , CONFTYPE_PROPLIST, read_property, PP_SCRIPT_PROPERTY , NULL },
1424 { CONF_EXECUTE_ON , CONFTYPE_EXECUTE_ON , read_execute_on , PP_SCRIPT_EXECUTE_ON , NULL },
1425 { CONF_EXECUTE_WHERE, CONFTYPE_EXECUTE_WHERE , read_execute_where , PP_SCRIPT_EXECUTE_WHERE, NULL },
1426 { CONF_ORDER , CONFTYPE_INT , read_int , PP_SCRIPT_ORDER , NULL },
1427 { CONF_SINGLE_EXECUTION, CONFTYPE_BOOLEAN, read_bool , PP_SCRIPT_SINGLE_EXECUTION, NULL },
1428 { CONF_CLIENT_NAME , CONFTYPE_STR , read_str , PP_SCRIPT_CLIENT_NAME , NULL },
1429 { CONF_UNKNOWN , CONFTYPE_INT , NULL , PP_SCRIPT_PP_SCRIPT , NULL }
1432 conf_var_t device_config_var [] = {
1433 { CONF_COMMENT , CONFTYPE_STR , read_str , DEVICE_CONFIG_COMMENT , NULL },
1434 { CONF_DEVICE_PROPERTY , CONFTYPE_PROPLIST , read_property , DEVICE_CONFIG_DEVICE_PROPERTY, NULL },
1435 { CONF_TAPEDEV , CONFTYPE_STR , read_str , DEVICE_CONFIG_TAPEDEV , NULL },
1436 { CONF_UNKNOWN , CONFTYPE_INT , NULL , DEVICE_CONFIG_DEVICE_CONFIG , NULL }
1439 conf_var_t changer_config_var [] = {
1440 { CONF_COMMENT , CONFTYPE_STR , read_str , CHANGER_CONFIG_COMMENT , NULL },
1441 { CONF_TAPEDEV , CONFTYPE_STR , read_str , CHANGER_CONFIG_TAPEDEV , NULL },
1442 { CONF_TPCHANGER , CONFTYPE_STR , read_str , CHANGER_CONFIG_TPCHANGER , NULL },
1443 { CONF_CHANGERDEV , CONFTYPE_STR , read_str , CHANGER_CONFIG_CHANGERDEV , NULL },
1444 { CONF_CHANGERFILE , CONFTYPE_STR , read_str , CHANGER_CONFIG_CHANGERFILE , NULL },
1445 { CONF_PROPERTY , CONFTYPE_PROPLIST , read_property , CHANGER_CONFIG_PROPERTY , NULL },
1446 { CONF_DEVICE_PROPERTY , CONFTYPE_PROPLIST , read_property , CHANGER_CONFIG_DEVICE_PROPERTY, NULL },
1447 { CONF_UNKNOWN , CONFTYPE_INT , NULL , CHANGER_CONFIG_CHANGER_CONFIG , NULL }
1450 conf_var_t interactivity_var [] = {
1451 { CONF_COMMENT , CONFTYPE_STR , read_str , INTERACTIVITY_COMMENT , NULL },
1452 { CONF_PLUGIN , CONFTYPE_STR , read_str , INTERACTIVITY_PLUGIN , NULL },
1453 { CONF_PROPERTY , CONFTYPE_PROPLIST , read_property , INTERACTIVITY_PROPERTY , NULL },
1454 { CONF_UNKNOWN , CONFTYPE_INT , NULL , INTERACTIVITY_INTERACTIVITY , NULL }
1457 conf_var_t taperscan_var [] = {
1458 { CONF_COMMENT , CONFTYPE_STR , read_str , TAPERSCAN_COMMENT , NULL },
1459 { CONF_PLUGIN , CONFTYPE_STR , read_str , TAPERSCAN_PLUGIN , NULL },
1460 { CONF_PROPERTY , CONFTYPE_PROPLIST , read_property , TAPERSCAN_PROPERTY , NULL },
1461 { CONF_UNKNOWN , CONFTYPE_INT , NULL , TAPERSCAN_TAPERSCAN , NULL }
1465 * Lexical Analysis Implementation
1474 if (keytable == NULL) {
1475 error(_("keytable == NULL"));
1479 for(kt = keytable; kt->token != CONF_UNKNOWN; kt++)
1480 if(kt->token == token) break;
1482 if(kt->token == CONF_UNKNOWN)
1484 return(kt->keyword);
1492 char *str1 = stralloc(str);
1495 /* Fold '-' to '_' in the token. Note that this modifies str1
1498 if (*p == '-') *p = '_';
1502 for(kwp = keytable; kwp->keyword != NULL; kwp++) {
1503 if (strcasecmp(kwp->keyword, str1) == 0) break;
1528 ** If it looked like a keyword before then look it
1529 ** up again in the current keyword table.
1532 case CONF_INT64: case CONF_SIZE:
1533 case CONF_INT: case CONF_REAL: case CONF_STRING:
1534 case CONF_LBRACE: case CONF_RBRACE: case CONF_COMMA:
1535 case CONF_NL: case CONF_END: case CONF_UNKNOWN:
1537 break; /* not a keyword */
1540 if (exp == CONF_IDENT)
1543 tok = lookup_keyword(tokenval.v.s);
1548 ch = conftoken_getc();
1550 /* note that we're explicitly assuming this file is ASCII. Someday
1551 * maybe we'll support UTF-8? */
1552 while(ch != EOF && ch != '\n' && g_ascii_isspace(ch))
1553 ch = conftoken_getc();
1554 if (ch == '#') { /* comment - eat everything but eol/eof */
1555 while((ch = conftoken_getc()) != EOF && ch != '\n') {
1556 (void)ch; /* Quiet empty loop complaints */
1560 if (isalpha(ch)) { /* identifier */
1564 if (buf < tkbuf+sizeof(tkbuf)-1) {
1568 if (!token_overflow) {
1569 conf_parserror(_("token too long: %.20s..."), tkbuf);
1573 ch = conftoken_getc();
1574 } while(isalnum(ch) || ch == '_' || ch == '-');
1576 if (ch != EOF && conftoken_ungetc(ch) == EOF) {
1577 if (ferror(current_file)) {
1578 conf_parserror(_("Pushback of '%c' failed: %s"),
1579 ch, strerror(ferror(current_file)));
1581 conf_parserror(_("Pushback of '%c' failed: EOF"), ch);
1586 tokenval.v.s = tkbuf;
1588 if (token_overflow) tok = CONF_UNKNOWN;
1589 else if (exp == CONF_IDENT) tok = CONF_IDENT;
1590 else tok = lookup_keyword(tokenval.v.s);
1592 else if (isdigit(ch)) { /* integer */
1595 negative_number: /* look for goto negative_number below sign is set there */
1598 int64 = int64 * 10 + (ch - '0');
1599 ch = conftoken_getc();
1600 } while (isdigit(ch));
1603 if (exp == CONF_INT) {
1605 tokenval.v.i = sign * (int)int64;
1606 } else if (exp != CONF_REAL) {
1608 tokenval.v.int64 = (gint64)sign * int64;
1610 /* automatically convert to real when expected */
1611 tokenval.v.r = (double)sign * (double)int64;
1615 /* got a real number, not an int */
1616 tokenval.v.r = sign * (double) int64;
1619 ch = conftoken_getc();
1620 while (isdigit(ch)) {
1621 int64 = int64 * 10 + (ch - '0');
1623 ch = conftoken_getc();
1625 tokenval.v.r += sign * ((double)int64) / d;
1629 if (ch != EOF && conftoken_ungetc(ch) == EOF) {
1630 if (ferror(current_file)) {
1631 conf_parserror(_("Pushback of '%c' failed: %s"),
1632 ch, strerror(ferror(current_file)));
1634 conf_parserror(_("Pushback of '%c' failed: EOF"), ch);
1638 case '"': /* string */
1643 while (inquote && ((ch = conftoken_getc()) != EOF)) {
1646 conf_parserror(_("string not terminated"));
1647 conftoken_ungetc(ch);
1651 buf--; /* Consume escape in buffer */
1652 } else if (ch == '\\' && !escape) {
1662 if(buf >= &tkbuf[sizeof(tkbuf) - 1]) {
1663 if (!token_overflow) {
1664 conf_parserror(_("string too long: %.20s..."), tkbuf);
1674 * A little manuver to leave a fully unquoted, unallocated string
1677 tmps = unquote_string(tkbuf);
1678 strncpy(tkbuf, tmps, sizeof(tkbuf));
1680 tokenval.v.s = tkbuf;
1682 tok = (token_overflow) ? CONF_UNKNOWN :
1683 (exp == CONF_IDENT) ? CONF_IDENT : CONF_STRING;
1687 ch = conftoken_getc();
1690 goto negative_number;
1693 if (ch != EOF && conftoken_ungetc(ch) == EOF) {
1694 if (ferror(current_file)) {
1695 conf_parserror(_("Pushback of '%c' failed: %s"),
1696 ch, strerror(ferror(current_file)));
1698 conf_parserror(_("Pushback of '%c' failed: EOF"), ch);
1731 if (exp != CONF_ANY && tok != exp) {
1749 str = _("end of line");
1753 str = _("end of file");
1757 str = _("an integer");
1761 str = _("a real number");
1765 str = _("a quoted string");
1769 str = _("an identifier");
1773 for(kwp = keytable; kwp->keyword != NULL; kwp++) {
1774 if (exp == kwp->token)
1777 if (kwp->keyword == NULL)
1778 str = _("token not");
1780 str = str_keyword(kwp);
1783 conf_parserror(_("%s is expected"), str);
1785 if (tok == CONF_INT)
1793 unget_conftoken(void)
1795 assert(!token_pushed);
1802 conftoken_getc(void)
1804 if(current_line == NULL)
1805 return getc(current_file);
1806 if(*current_char == '\0')
1808 return(*current_char++);
1815 if(current_line == NULL)
1816 return ungetc(c, current_file);
1817 else if(current_char > current_line) {
1821 if(*current_char != c) {
1822 error(_("*current_char != c : %c %c"), *current_char, c);
1826 error(_("current_char == current_line"));
1833 * Parser Implementation
1840 gboolean missing_ok)
1842 /* Save global locations. */
1843 FILE *save_file = current_file;
1844 char *save_filename = current_filename;
1845 int save_line_num = current_line_num;
1849 keytable = client_keytab;
1850 parsetable = client_var;
1852 keytable = server_keytab;
1853 parsetable = server_var;
1855 filename = config_dir_relative(filename);
1856 current_filename = get_seen_filename(filename);
1859 if ((current_file = fopen(current_filename, "r")) == NULL) {
1861 conf_parserror(_("could not open conf file \"%s\": %s"),
1862 current_filename, strerror(errno));
1866 current_line_num = 0;
1869 /* read_confline() can invoke us recursively via "includefile" */
1870 rc = read_confline(is_client);
1873 afclose(current_file);
1877 /* Restore servers */
1878 current_line_num = save_line_num;
1879 current_file = save_file;
1880 current_filename = save_filename;
1889 current_line_num += 1;
1890 get_conftoken(CONF_ANY);
1891 handle_deprecated_keyword();
1894 case CONF_INCLUDEFILE:
1895 get_conftoken(CONF_STRING);
1896 read_conffile(tokenval.v.s, is_client, FALSE);
1901 get_conftoken(CONF_ANY);
1902 /* accept application-tool here, too, for backward compatibility */
1903 if(tok == CONF_APPLICATION_TOOL || tok == CONF_APPLICATION) get_application();
1904 else if(tok == CONF_SCRIPT_TOOL || tok == CONF_SCRIPT) get_pp_script();
1905 else conf_parserror(_("APPLICATION-TOOL or SCRIPT-TOOL expected"));
1907 get_conftoken(CONF_ANY);
1908 if(tok == CONF_DUMPTYPE) get_dumptype();
1909 else if(tok == CONF_TAPETYPE) get_tapetype();
1910 else if(tok == CONF_INTERFACE) get_interface();
1911 else if(tok == CONF_APPLICATION_TOOL || tok == CONF_APPLICATION) get_application();
1912 else if(tok == CONF_SCRIPT_TOOL || tok == CONF_SCRIPT) get_pp_script();
1913 else if(tok == CONF_DEVICE) get_device_config();
1914 else if(tok == CONF_CHANGER) get_changer_config();
1915 else if(tok == CONF_HOLDING) get_holdingdisk(1);
1916 else if(tok == CONF_INTERACTIVITY) get_interactivity();
1917 else if(tok == CONF_TAPERSCAN) get_taperscan();
1918 else conf_parserror(_("DUMPTYPE, INTERFACE, TAPETYPE, HOLDINGDISK, APPLICATION, SCRIPT, DEVICE, CHANGER, INTERACTIVITY or TAPERSCAN expected"));
1919 current_block = NULL;
1923 case CONF_NL: /* empty line */
1926 case CONF_END: /* end of file */
1929 /* These should never be at the begining of a line */
1940 conf_parserror("error: not a keyword.");
1943 /* if it's not a known punctuation mark, then check the parse table and use the
1944 * read_function we find there. */
1947 for(np = parsetable; np->token != CONF_UNKNOWN; np++)
1948 if(np->token == tok) break;
1950 if(np->token == CONF_UNKNOWN) {
1951 handle_invalid_keyword(tokenval.v.s);
1953 np->read_function(np, &conf_data[np->parm]);
1954 if(np->validate_function)
1955 np->validate_function(np, &conf_data[np->parm]);
1960 get_conftoken(CONF_NL);
1965 handle_deprecated_keyword(void)
1967 /* Procedure for deprecated keywords:
1969 * 1) At time of deprecation, add to warning_deprecated below. Note the
1970 * version in which deprecation will expire. The keyword will still be
1971 * parsed, and can still be used from other parts of Amanda, during this
1973 * 2) After it has expired, move the keyword (as a string) to
1974 * error_deprecated below. Remove the token (CONF_XXX) and
1975 * config parameter (CNF_XXX) from the rest of the module.
1976 * Note the date of the move.
1979 static struct { tok_t tok; gboolean warned; }
1980 warning_deprecated[] = {
1981 { CONF_LABEL_NEW_TAPES, 0 }, /* exp in Amanda-3.2 */
1982 { CONF_AMRECOVER_DO_FSF, 0 }, /* exp in Amanda-3.3 */
1983 { CONF_AMRECOVER_CHECK_LABEL, 0 }, /* exp in Amanda-3.3 */
1984 { CONF_TAPE_SPLITSIZE, 0 }, /* exp. in Amanda-3.3 */
1985 { CONF_SPLIT_DISKBUFFER, 0 }, /* exp. in Amanda-3.3 */
1986 { CONF_FALLBACK_SPLITSIZE, 0 }, /* exp. in Amanda-3.3 */
1990 for (dep = warning_deprecated; dep->tok; dep++) {
1991 if (tok == dep->tok) {
1993 conf_parswarn(_("warning: Keyword %s is deprecated."),
2002 handle_invalid_keyword(
2005 static const char * error_deprecated[] = {
2007 "tapebufs", /* deprecated: 2007-10-15; invalid: 2010-04-14 */
2008 "file-pad", /* deprecated: 2008-07-01; invalid: 2010-04-14 */
2012 char *folded_token, *p;
2014 /* convert '_' to '-' in TOKEN */
2015 folded_token = g_strdup(token);
2016 for (p = folded_token; *p; p++) {
2017 if (*p == '_') *p = '-';
2020 for (s = error_deprecated; *s != NULL; s ++) {
2021 if (g_ascii_strcasecmp(*s, folded_token) == 0) {
2022 conf_parserror(_("error: Keyword %s is deprecated."),
2024 g_free(folded_token);
2028 g_free(folded_token);
2031 conf_parserror(_("configuration keyword expected"));
2035 char c = conftoken_getc();
2036 if (c == '\n' || c == -1) {
2037 conftoken_ungetc(c);
2042 g_assert_not_reached();
2052 for (iter = seen_filenames; iter; iter = iter->next) {
2054 if (istr == filename || 0 == strcmp(istr, filename))
2058 istr = stralloc(filename);
2059 seen_filenames = g_slist_prepend(seen_filenames, istr);
2065 conf_var_t *read_var,
2069 void (*copy_function)(void),
2079 get_conftoken(CONF_LBRACE);
2080 get_conftoken(CONF_NL);
2085 current_line_num += 1;
2086 get_conftoken(CONF_ANY);
2087 handle_deprecated_keyword();
2093 case CONF_NL: /* empty line */
2095 case CONF_END: /* end of file */
2099 /* inherit from a "parent" */
2105 conf_parserror(_("ident not expected"));
2109 for(np = read_var; np->token != CONF_UNKNOWN; np++)
2110 if(np->token == tok) break;
2112 if(np->token == CONF_UNKNOWN)
2113 conf_parserror("%s", errormsg);
2115 np->read_function(np, &valarray[np->parm]);
2116 if(np->validate_function)
2117 np->validate_function(np, &valarray[np->parm]);
2121 if(tok != CONF_NL && tok != CONF_END && tok != CONF_RBRACE)
2122 get_conftoken(CONF_NL);
2125 if (!config_overrides)
2128 key_ovr = vstralloc(type, ":", name, NULL);
2129 for (i = 0; i < config_overrides->n_used; i++) {
2130 config_override_t *co = &config_overrides->ovr[i];
2131 char *key = co->key;
2136 if (key_ovr && strncasecmp(key_ovr, key, strlen(key_ovr)) != 0)
2139 if (strlen(key) <= strlen(key_ovr) + 1)
2142 keyword = key + strlen(key_ovr) + 1;
2145 /* find the token in keytable */
2146 for (kt = keytable; kt->token != CONF_UNKNOWN; kt++) {
2147 if (kt->keyword && strcasecmp(kt->keyword, keyword) == 0)
2150 if (kt->token == CONF_UNKNOWN)
2153 /* find the var in read_var */
2154 for (np = read_var; np->token != CONF_UNKNOWN; np++)
2155 if (np->token == kt->token) break;
2156 if (np->token == CONF_UNKNOWN)
2159 /* now set up a fake line and use the relevant read_function to
2160 * parse it. This is sneaky! */
2161 if (np->type == CONFTYPE_STR) {
2162 current_line = quote_string_always(value);
2164 current_line = stralloc(value);
2167 current_char = current_line;
2169 current_line_num = -2;
2170 allow_overwrites = 1;
2173 np->read_function(np, &valarray[np->parm]);
2174 if (np->validate_function)
2175 np->validate_function(np, &valarray[np->parm]);
2177 amfree(current_line);
2178 current_char = NULL;
2186 conf_var_t *np G_GNUC_UNUSED,
2187 val_t *val G_GNUC_UNUSED)
2189 assert (val == &conf_data[CNF_HOLDINGDISK]);
2197 int save_overwrites;
2199 save_overwrites = allow_overwrites;
2200 allow_overwrites = 1;
2202 init_holdingdisk_defaults();
2204 get_conftoken(CONF_IDENT);
2205 hdcur.name = stralloc(tokenval.v.s);
2206 current_block = g_strconcat("holdingdisk ", hdcur.name, NULL);
2207 hdcur.seen.block = current_block;
2208 hdcur.seen.filename = current_filename;
2209 hdcur.seen.linenum = current_line_num;
2211 get_conftoken(CONF_ANY);
2212 if (tok == CONF_LBRACE) {
2214 hd = lookup_holdingdisk(hdcur.name);
2216 conf_parserror(_("holding disk '%s' already defined"),
2220 read_block(holding_var, hdcur.value,
2221 _("holding disk parameter expected"), 1, copy_holdingdisk,
2222 "HOLDINGDISK", hdcur.name);
2223 get_conftoken(CONF_NL);
2226 conf_data[CNF_HOLDINGDISK].v.identlist = g_slist_append(
2227 conf_data[CNF_HOLDINGDISK].v.identlist,
2228 stralloc(hdcur.name));
2231 } else { /* use the already defined holding disk */
2234 conf_parserror(_("holdingdisk definition must specify holdingdisk parameters"));
2239 for (il = conf_data[CNF_HOLDINGDISK].v.identlist; il != NULL;
2241 if (strcmp((char *)il->data, hdcur.name) == 0) {
2246 conf_parserror(_("holding disk '%s' already in use"),
2249 conf_data[CNF_HOLDINGDISK].v.identlist = g_slist_append(
2250 conf_data[CNF_HOLDINGDISK].v.identlist,
2251 stralloc(hdcur.name));
2254 get_conftoken(CONF_ANY);
2255 if (tok == CONF_IDENT || tok == CONF_STRING) {
2256 hdcur.name = stralloc(tokenval.v.s);
2257 } else if (tok != CONF_NL) {
2258 conf_parserror(_("IDENT or NL expected"));
2260 } while (tok == CONF_IDENT || tok == CONF_STRING);
2263 allow_overwrites = save_overwrites;
2267 init_holdingdisk_defaults(
2270 conf_init_str(&hdcur.value[HOLDING_COMMENT] , "");
2271 conf_init_str(&hdcur.value[HOLDING_DISKDIR] , "");
2272 conf_init_int64(&hdcur.value[HOLDING_DISKSIZE] , CONF_UNIT_K, (gint64)0);
2273 /* 1 Gb = 1M counted in 1Kb blocks */
2274 conf_init_int64(&hdcur.value[HOLDING_CHUNKSIZE], CONF_UNIT_K, (gint64)1024*1024);
2283 hp = alloc(sizeof(holdingdisk_t));
2285 holdinglist = g_slist_append(holdinglist, hp);
2295 hp = lookup_holdingdisk(tokenval.v.s);
2298 conf_parserror(_("holdingdisk parameter expected"));
2302 for(i=0; i < HOLDING_HOLDING; i++) {
2303 if(hp->value[i].seen.linenum) {
2304 merge_val_t(&hdcur.value[i], &hp->value[i]);
2312 * This function is called both from this module and from diskfile.c. Modify
2321 int save_overwrites;
2322 FILE *saved_conf = NULL;
2323 char *saved_fname = NULL;
2326 saved_conf = current_file;
2327 current_file = from;
2331 saved_fname = current_filename;
2332 current_filename = get_seen_filename(fname);
2336 current_line_num = *linenum;
2338 save_overwrites = allow_overwrites;
2339 allow_overwrites = 1;
2341 init_dumptype_defaults();
2345 get_conftoken(CONF_IDENT);
2346 dpcur.name = stralloc(tokenval.v.s);
2348 current_block = g_strconcat("dumptype ", dpcur.name, NULL);
2349 dpcur.seen.block = current_block;
2350 dpcur.seen.filename = current_filename;
2351 dpcur.seen.linenum = current_line_num;
2353 read_block(dumptype_var, dpcur.value,
2354 _("dumptype parameter expected"),
2355 (name == NULL), copy_dumptype,
2356 "DUMPTYPE", dpcur.name);
2358 if(!name) /* !name => reading disklist, not conffile */
2359 get_conftoken(CONF_NL);
2361 /* XXX - there was a stupidity check in here for skip-incr and
2362 ** skip-full. This check should probably be somewhere else. */
2366 allow_overwrites = save_overwrites;
2369 *linenum = current_line_num;
2372 current_filename = saved_fname;
2375 current_file = saved_conf;
2377 return lookup_dumptype(dpcur.name);
2383 read_dumptype(NULL, NULL, NULL, NULL);
2387 init_dumptype_defaults(void)
2390 conf_init_str (&dpcur.value[DUMPTYPE_COMMENT] , "");
2391 conf_init_str (&dpcur.value[DUMPTYPE_PROGRAM] , "DUMP");
2392 conf_init_str (&dpcur.value[DUMPTYPE_SRVCOMPPROG] , "");
2393 conf_init_str (&dpcur.value[DUMPTYPE_CLNTCOMPPROG] , "");
2394 conf_init_str (&dpcur.value[DUMPTYPE_SRV_ENCRYPT] , "");
2395 conf_init_str (&dpcur.value[DUMPTYPE_CLNT_ENCRYPT] , "");
2396 conf_init_str (&dpcur.value[DUMPTYPE_AMANDAD_PATH] , "");
2397 conf_init_str (&dpcur.value[DUMPTYPE_CLIENT_USERNAME] , "");
2398 conf_init_str (&dpcur.value[DUMPTYPE_CLIENT_PORT] , "");
2399 conf_init_str (&dpcur.value[DUMPTYPE_SSH_KEYS] , "");
2400 conf_init_str (&dpcur.value[DUMPTYPE_AUTH] , "BSDTCP");
2401 conf_init_exinclude(&dpcur.value[DUMPTYPE_EXCLUDE]);
2402 conf_init_exinclude(&dpcur.value[DUMPTYPE_INCLUDE]);
2403 conf_init_priority (&dpcur.value[DUMPTYPE_PRIORITY] , 1);
2404 conf_init_int (&dpcur.value[DUMPTYPE_DUMPCYCLE] , CONF_UNIT_NONE, conf_data[CNF_DUMPCYCLE].v.i);
2405 conf_init_int (&dpcur.value[DUMPTYPE_MAXDUMPS] , CONF_UNIT_NONE, conf_data[CNF_MAXDUMPS].v.i);
2406 conf_init_int (&dpcur.value[DUMPTYPE_MAXPROMOTEDAY] , CONF_UNIT_NONE, 10000);
2407 conf_init_int (&dpcur.value[DUMPTYPE_BUMPPERCENT] , CONF_UNIT_NONE, conf_data[CNF_BUMPPERCENT].v.i);
2408 conf_init_int64 (&dpcur.value[DUMPTYPE_BUMPSIZE] , CONF_UNIT_K , conf_data[CNF_BUMPSIZE].v.int64);
2409 conf_init_int (&dpcur.value[DUMPTYPE_BUMPDAYS] , CONF_UNIT_NONE, conf_data[CNF_BUMPDAYS].v.i);
2410 conf_init_real (&dpcur.value[DUMPTYPE_BUMPMULT] , conf_data[CNF_BUMPMULT].v.r);
2411 conf_init_time (&dpcur.value[DUMPTYPE_STARTTIME] , (time_t)0);
2412 conf_init_strategy (&dpcur.value[DUMPTYPE_STRATEGY] , DS_STANDARD);
2413 conf_init_estimatelist(&dpcur.value[DUMPTYPE_ESTIMATELIST] , ES_CLIENT);
2414 conf_init_compress (&dpcur.value[DUMPTYPE_COMPRESS] , COMP_FAST);
2415 conf_init_encrypt (&dpcur.value[DUMPTYPE_ENCRYPT] , ENCRYPT_NONE);
2416 conf_init_data_path(&dpcur.value[DUMPTYPE_DATA_PATH] , DATA_PATH_AMANDA);
2417 conf_init_str (&dpcur.value[DUMPTYPE_SRV_DECRYPT_OPT] , "-d");
2418 conf_init_str (&dpcur.value[DUMPTYPE_CLNT_DECRYPT_OPT] , "-d");
2419 conf_init_rate (&dpcur.value[DUMPTYPE_COMPRATE] , 0.50, 0.50);
2420 conf_init_int64 (&dpcur.value[DUMPTYPE_TAPE_SPLITSIZE] , CONF_UNIT_K, (gint64)0);
2421 conf_init_int64 (&dpcur.value[DUMPTYPE_FALLBACK_SPLITSIZE], CONF_UNIT_K, (gint64)10 * 1024);
2422 conf_init_str (&dpcur.value[DUMPTYPE_SPLIT_DISKBUFFER] , NULL);
2423 conf_init_bool (&dpcur.value[DUMPTYPE_RECORD] , 1);
2424 conf_init_bool (&dpcur.value[DUMPTYPE_SKIP_INCR] , 0);
2425 conf_init_bool (&dpcur.value[DUMPTYPE_SKIP_FULL] , 0);
2426 conf_init_holding (&dpcur.value[DUMPTYPE_HOLDINGDISK] , HOLD_AUTO);
2427 conf_init_bool (&dpcur.value[DUMPTYPE_KENCRYPT] , 0);
2428 conf_init_bool (&dpcur.value[DUMPTYPE_IGNORE] , 0);
2429 conf_init_bool (&dpcur.value[DUMPTYPE_INDEX] , 1);
2430 conf_init_application(&dpcur.value[DUMPTYPE_APPLICATION]);
2431 conf_init_identlist(&dpcur.value[DUMPTYPE_SCRIPTLIST], NULL);
2432 conf_init_proplist(&dpcur.value[DUMPTYPE_PROPERTY]);
2433 conf_init_bool (&dpcur.value[DUMPTYPE_ALLOW_SPLIT] , 1);
2434 conf_init_int (&dpcur.value[DUMPTYPE_MAX_WARNINGS] , CONF_UNIT_NONE, 20);
2435 conf_init_host_limit(&dpcur.value[DUMPTYPE_RECOVERY_LIMIT]);
2436 conf_init_host_limit_server(&dpcur.value[DUMPTYPE_DUMP_LIMIT]);
2442 dumptype_t *dp, *dp1;;
2444 dp = lookup_dumptype(dpcur.name);
2446 if(dp != (dumptype_t *)0) {
2447 if (dp->seen.linenum == -1) {
2448 conf_parserror(_("dumptype %s is defined by default and cannot be redefined"), dp->name);
2450 conf_parserror(_("dumptype %s already defined at %s:%d"), dp->name,
2451 dp->seen.filename, dp->seen.linenum);
2456 dp = alloc(sizeof(dumptype_t));
2459 /* add at end of list */
2464 while (dp1->next != NULL) {
2477 dt = lookup_dumptype(tokenval.v.s);
2480 conf_parserror(_("dumptype parameter expected"));
2484 for(i=0; i < DUMPTYPE_DUMPTYPE; i++) {
2485 if(dt->value[i].seen.linenum) {
2486 merge_val_t(&dpcur.value[i], &dt->value[i]);
2487 if (i == DUMPTYPE_SCRIPTLIST) {
2488 /* sort in 'order' */
2489 dpcur.value[i].v.identlist = g_slist_sort(dpcur.value[i].v.identlist, &compare_pp_script_order);
2498 int save_overwrites;
2500 save_overwrites = allow_overwrites;
2501 allow_overwrites = 1;
2503 init_tapetype_defaults();
2505 get_conftoken(CONF_IDENT);
2506 tpcur.name = stralloc(tokenval.v.s);
2507 current_block = g_strconcat("tapetype ", tpcur.name, NULL);
2508 tpcur.seen.block = current_block;
2509 tpcur.seen.filename = current_filename;
2510 tpcur.seen.linenum = current_line_num;
2512 read_block(tapetype_var, tpcur.value,
2513 _("tapetype parameter expected"), 1, copy_tapetype,
2514 "TAPETYPE", tpcur.name);
2515 get_conftoken(CONF_NL);
2517 if (tapetype_get_readblocksize(&tpcur) <
2518 tapetype_get_blocksize(&tpcur)) {
2519 conf_init_size(&tpcur.value[TAPETYPE_READBLOCKSIZE], CONF_UNIT_K,
2520 tapetype_get_blocksize(&tpcur));
2524 allow_overwrites = save_overwrites;
2528 init_tapetype_defaults(void)
2530 conf_init_str(&tpcur.value[TAPETYPE_COMMENT] , "");
2531 conf_init_str(&tpcur.value[TAPETYPE_LBL_TEMPL] , "");
2532 conf_init_size (&tpcur.value[TAPETYPE_BLOCKSIZE] , CONF_UNIT_K, DISK_BLOCK_KB);
2533 conf_init_size (&tpcur.value[TAPETYPE_READBLOCKSIZE], CONF_UNIT_K, DISK_BLOCK_KB);
2534 conf_init_int64 (&tpcur.value[TAPETYPE_LENGTH] , CONF_UNIT_K, ((gint64)2000));
2535 conf_init_int64 (&tpcur.value[TAPETYPE_FILEMARK] , CONF_UNIT_K, (gint64)1);
2536 conf_init_int (&tpcur.value[TAPETYPE_SPEED] , CONF_UNIT_NONE, 200);
2537 conf_init_int64(&tpcur.value[TAPETYPE_PART_SIZE], CONF_UNIT_K, 0);
2538 conf_init_part_cache_type(&tpcur.value[TAPETYPE_PART_CACHE_TYPE], PART_CACHE_TYPE_NONE);
2539 conf_init_str(&tpcur.value[TAPETYPE_PART_CACHE_DIR], "");
2540 conf_init_int64(&tpcur.value[TAPETYPE_PART_CACHE_MAX_SIZE], CONF_UNIT_K, 0);
2546 tapetype_t *tp, *tp1;
2548 tp = lookup_tapetype(tpcur.name);
2550 if(tp != (tapetype_t *)0) {
2552 conf_parserror(_("tapetype %s already defined at %s:%d"),
2553 tp->name, tp->seen.filename, tp->seen.linenum);
2557 tp = alloc(sizeof(tapetype_t));
2560 /* add at end of list */
2565 while (tp1->next != NULL) {
2578 tp = lookup_tapetype(tokenval.v.s);
2581 conf_parserror(_("tape type parameter expected"));
2585 for(i=0; i < TAPETYPE_TAPETYPE; i++) {
2586 if(tp->value[i].seen.linenum) {
2587 merge_val_t(&tpcur.value[i], &tp->value[i]);
2595 int save_overwrites;
2597 save_overwrites = allow_overwrites;
2598 allow_overwrites = 1;
2600 init_interface_defaults();
2602 get_conftoken(CONF_IDENT);
2603 ifcur.name = stralloc(tokenval.v.s);
2604 current_block = g_strconcat("interface ", ifcur.name, NULL);
2605 ifcur.seen.block = current_block;
2606 ifcur.seen.filename = current_filename;
2607 ifcur.seen.linenum = current_line_num;
2609 read_block(interface_var, ifcur.value,
2610 _("interface parameter expected"), 1, copy_interface,
2611 "INTERFACE", ifcur.name);
2612 get_conftoken(CONF_NL);
2616 allow_overwrites = save_overwrites;
2622 init_interface_defaults(void)
2624 conf_init_str(&ifcur.value[INTER_COMMENT] , "");
2625 conf_init_int (&ifcur.value[INTER_MAXUSAGE], CONF_UNIT_K, 80000);
2629 save_interface(void)
2631 interface_t *ip, *ip1;
2633 ip = lookup_interface(ifcur.name);
2635 if(ip != (interface_t *)0) {
2636 conf_parserror(_("interface %s already defined at %s:%d"),
2637 ip->name, ip->seen.filename, ip->seen.linenum);
2641 ip = alloc(sizeof(interface_t));
2643 /* add at end of list */
2644 if(!interface_list) {
2645 interface_list = ip;
2647 ip1 = interface_list;
2648 while (ip1->next != NULL) {
2656 copy_interface(void)
2661 ip = lookup_interface(tokenval.v.s);
2664 conf_parserror(_("interface parameter expected"));
2668 for(i=0; i < INTER_INTER; i++) {
2669 if(ip->value[i].seen.linenum) {
2670 merge_val_t(&ifcur.value[i], &ip->value[i]);
2676 static application_t *
2683 int save_overwrites;
2684 FILE *saved_conf = NULL;
2685 char *saved_fname = NULL;
2688 saved_conf = current_file;
2689 current_file = from;
2693 saved_fname = current_filename;
2694 current_filename = get_seen_filename(fname);
2698 current_line_num = *linenum;
2700 save_overwrites = allow_overwrites;
2701 allow_overwrites = 1;
2703 init_application_defaults();
2707 get_conftoken(CONF_IDENT);
2708 apcur.name = stralloc(tokenval.v.s);
2710 current_block = g_strconcat("application ", apcur.name, NULL);
2711 apcur.seen.block = current_block;
2712 apcur.seen.filename = current_filename;
2713 apcur.seen.linenum = current_line_num;
2715 read_block(application_var, apcur.value,
2716 _("application parameter expected"),
2717 (name == NULL), *copy_application,
2718 "APPLICATION", apcur.name);
2720 get_conftoken(CONF_NL);
2724 allow_overwrites = save_overwrites;
2727 *linenum = current_line_num;
2730 current_filename = saved_fname;
2733 current_file = saved_conf;
2735 return lookup_application(apcur.name);
2742 read_application(NULL, NULL, NULL, NULL);
2746 init_application_defaults(
2750 conf_init_str(&apcur.value[APPLICATION_COMMENT] , "");
2751 conf_init_str(&apcur.value[APPLICATION_PLUGIN] , "");
2752 conf_init_proplist(&apcur.value[APPLICATION_PROPERTY]);
2753 conf_init_str(&apcur.value[APPLICATION_CLIENT_NAME] , "");
2760 application_t *ap, *ap1;
2762 ap = lookup_application(apcur.name);
2764 if(ap != (application_t *)0) {
2765 conf_parserror(_("application %s already defined at %s:%d"),
2766 ap->name, ap->seen.filename, ap->seen.linenum);
2770 ap = alloc(sizeof(application_t));
2773 /* add at end of list */
2774 if (!application_list)
2775 application_list = ap;
2777 ap1 = application_list;
2778 while (ap1->next != NULL) {
2786 copy_application(void)
2791 ap = lookup_application(tokenval.v.s);
2794 conf_parserror(_("application parameter expected"));
2798 for(i=0; i < APPLICATION_APPLICATION; i++) {
2799 if(ap->value[i].seen.linenum) {
2800 merge_val_t(&apcur.value[i], &ap->value[i]);
2805 static interactivity_t *
2812 int save_overwrites;
2813 FILE *saved_conf = NULL;
2814 char *saved_fname = NULL;
2817 saved_conf = current_file;
2818 current_file = from;
2822 saved_fname = current_filename;
2823 current_filename = get_seen_filename(fname);
2827 current_line_num = *linenum;
2829 save_overwrites = allow_overwrites;
2830 allow_overwrites = 1;
2832 init_interactivity_defaults();
2836 get_conftoken(CONF_IDENT);
2837 ivcur.name = stralloc(tokenval.v.s);
2839 current_block = g_strconcat("interactivity ", ivcur.name, NULL);
2840 ivcur.seen.block = current_block;
2841 ivcur.seen.filename = current_filename;
2842 ivcur.seen.linenum = current_line_num;
2844 read_block(interactivity_var, ivcur.value,
2845 _("interactivity parameter expected"),
2846 (name == NULL), *copy_interactivity,
2847 "INTERACTIVITY", ivcur.name);
2849 get_conftoken(CONF_NL);
2851 save_interactivity();
2853 allow_overwrites = save_overwrites;
2856 *linenum = current_line_num;
2859 current_filename = saved_fname;
2862 current_file = saved_conf;
2864 return lookup_interactivity(ivcur.name);
2871 read_interactivity(NULL, NULL, NULL, NULL);
2875 init_interactivity_defaults(
2879 conf_init_str(&ivcur.value[INTERACTIVITY_COMMENT] , "");
2880 conf_init_str(&ivcur.value[INTERACTIVITY_PLUGIN] , "");
2881 conf_init_proplist(&ivcur.value[INTERACTIVITY_PROPERTY]);
2888 interactivity_t *iv, *iv1;
2890 iv = lookup_interactivity(ivcur.name);
2892 if (iv != (interactivity_t *)0) {
2893 conf_parserror(_("interactivity %s already defined at %s:%d"),
2894 iv->name, iv->seen.filename, iv->seen.linenum);
2898 iv = alloc(sizeof(interactivity_t));
2901 /* add at end of list */
2902 if (!interactivity_list)
2903 interactivity_list = iv;
2905 iv1 = interactivity_list;
2906 while (iv1->next != NULL) {
2914 copy_interactivity(void)
2916 interactivity_t *iv;
2919 iv = lookup_interactivity(tokenval.v.s);
2922 conf_parserror(_("interactivity parameter expected"));
2926 for (i=0; i < INTERACTIVITY_INTERACTIVITY; i++) {
2927 if(iv->value[i].seen.linenum) {
2928 merge_val_t(&ivcur.value[i], &iv->value[i]);
2933 static taperscan_t *
2940 int save_overwrites;
2941 FILE *saved_conf = NULL;
2942 char *saved_fname = NULL;
2945 saved_conf = current_file;
2946 current_file = from;
2950 saved_fname = current_filename;
2951 current_filename = get_seen_filename(fname);
2955 current_line_num = *linenum;
2957 save_overwrites = allow_overwrites;
2958 allow_overwrites = 1;
2960 init_taperscan_defaults();
2964 get_conftoken(CONF_IDENT);
2965 tscur.name = stralloc(tokenval.v.s);
2967 current_block = g_strconcat("taperscan ", tscur.name, NULL);
2968 tscur.seen.block = current_block;
2969 tscur.seen.filename = current_filename;
2970 tscur.seen.linenum = current_line_num;
2972 read_block(taperscan_var, tscur.value,
2973 _("taperscan parameter expected"),
2974 (name == NULL), *copy_taperscan,
2975 "TAPERSCAN", tscur.name);
2977 get_conftoken(CONF_NL);
2981 allow_overwrites = save_overwrites;
2984 *linenum = current_line_num;
2987 current_filename = saved_fname;
2990 current_file = saved_conf;
2992 return lookup_taperscan(tscur.name);
2999 read_taperscan(NULL, NULL, NULL, NULL);
3003 init_taperscan_defaults(
3007 conf_init_str(&tscur.value[TAPERSCAN_COMMENT] , "");
3008 conf_init_str(&tscur.value[TAPERSCAN_PLUGIN] , "");
3009 conf_init_proplist(&tscur.value[TAPERSCAN_PROPERTY]);
3016 taperscan_t *ts, *ts1;
3018 ts = lookup_taperscan(tscur.name);
3020 if (ts != (taperscan_t *)0) {
3021 conf_parserror(_("taperscan %s already defined at %s:%d"),
3022 ts->name, ts->seen.filename, ts->seen.linenum);
3026 ts = alloc(sizeof(taperscan_t));
3029 /* add at end of list */
3030 if (!taperscan_list)
3031 taperscan_list = ts;
3033 ts1 = taperscan_list;
3034 while (ts1->next != NULL) {
3042 copy_taperscan(void)
3047 ts = lookup_taperscan(tokenval.v.s);
3050 conf_parserror(_("taperscan parameter expected"));
3054 for (i=0; i < TAPERSCAN_TAPERSCAN; i++) {
3055 if(ts->value[i].seen.linenum) {
3056 merge_val_t(&tscur.value[i], &ts->value[i]);
3061 static pp_script_t *
3068 int save_overwrites;
3069 FILE *saved_conf = NULL;
3070 char *saved_fname = NULL;
3073 saved_conf = current_file;
3074 current_file = from;
3078 saved_fname = current_filename;
3079 current_filename = get_seen_filename(fname);
3083 current_line_num = *linenum;
3085 save_overwrites = allow_overwrites;
3086 allow_overwrites = 1;
3088 init_pp_script_defaults();
3092 get_conftoken(CONF_IDENT);
3093 pscur.name = stralloc(tokenval.v.s);
3095 current_block = g_strconcat("script ", pscur.name, NULL);
3096 pscur.seen.block = current_block;
3097 pscur.seen.filename = current_filename;
3098 pscur.seen.linenum = current_line_num;
3100 read_block(pp_script_var, pscur.value,
3101 _("script parameter expected"),
3102 (name == NULL), *copy_pp_script,
3103 "SCRIPT", pscur.name);
3105 get_conftoken(CONF_NL);
3109 allow_overwrites = save_overwrites;
3112 *linenum = current_line_num;
3115 current_filename = saved_fname;
3118 current_file = saved_conf;
3120 return lookup_pp_script(pscur.name);
3127 read_pp_script(NULL, NULL, NULL, NULL);
3131 init_pp_script_defaults(
3135 conf_init_str(&pscur.value[PP_SCRIPT_COMMENT] , "");
3136 conf_init_str(&pscur.value[PP_SCRIPT_PLUGIN] , "");
3137 conf_init_proplist(&pscur.value[PP_SCRIPT_PROPERTY]);
3138 conf_init_execute_on(&pscur.value[PP_SCRIPT_EXECUTE_ON], 0);
3139 conf_init_execute_where(&pscur.value[PP_SCRIPT_EXECUTE_WHERE], ES_CLIENT);
3140 conf_init_int(&pscur.value[PP_SCRIPT_ORDER], CONF_UNIT_NONE, 5000);
3141 conf_init_bool(&pscur.value[PP_SCRIPT_SINGLE_EXECUTION], 0);
3142 conf_init_str(&pscur.value[PP_SCRIPT_CLIENT_NAME], "");
3149 pp_script_t *ps, *ps1;
3151 ps = lookup_pp_script(pscur.name);
3153 if(ps != (pp_script_t *)0) {
3154 conf_parserror(_("script %s already defined at %s:%d"),
3155 ps->name, ps->seen.filename, ps->seen.linenum);
3159 ps = alloc(sizeof(pp_script_t));
3162 /* add at end of list */
3163 if (!pp_script_list)
3164 pp_script_list = ps;
3166 ps1 = pp_script_list;
3167 while (ps1->next != NULL) {
3175 copy_pp_script(void)
3180 ps = lookup_pp_script(tokenval.v.s);
3183 conf_parserror(_("script parameter expected"));
3187 for(i=0; i < PP_SCRIPT_PP_SCRIPT; i++) {
3188 if(ps->value[i].seen.linenum) {
3189 merge_val_t(&pscur.value[i], &ps->value[i]);
3194 static device_config_t *
3201 int save_overwrites;
3202 FILE *saved_conf = NULL;
3203 char *saved_fname = NULL;
3206 saved_conf = current_file;
3207 current_file = from;
3211 saved_fname = current_filename;
3212 current_filename = get_seen_filename(fname);
3216 current_line_num = *linenum;
3218 save_overwrites = allow_overwrites;
3219 allow_overwrites = 1;
3221 init_device_config_defaults();
3225 get_conftoken(CONF_IDENT);
3226 dccur.name = stralloc(tokenval.v.s);
3228 current_block = g_strconcat("device ", dccur.name, NULL);
3229 dccur.seen.block = current_block;
3230 dccur.seen.filename = current_filename;
3231 dccur.seen.linenum = current_line_num;
3233 read_block(device_config_var, dccur.value,
3234 _("device parameter expected"),
3235 (name == NULL), *copy_device_config,
3236 "DEVICE", dccur.name);
3238 get_conftoken(CONF_NL);
3240 save_device_config();
3242 allow_overwrites = save_overwrites;
3245 *linenum = current_line_num;
3248 current_filename = saved_fname;
3251 current_file = saved_conf;
3253 return lookup_device_config(dccur.name);
3260 read_device_config(NULL, NULL, NULL, NULL);
3264 init_device_config_defaults(
3268 conf_init_str(&dccur.value[DEVICE_CONFIG_COMMENT] , "");
3269 conf_init_str(&dccur.value[DEVICE_CONFIG_TAPEDEV] , "");
3270 conf_init_proplist(&dccur.value[DEVICE_CONFIG_DEVICE_PROPERTY]);
3277 device_config_t *dc, *dc1;
3279 dc = lookup_device_config(dccur.name);
3281 if(dc != (device_config_t *)0) {
3282 conf_parserror(_("device %s already defined at %s:%d"),
3283 dc->name, dc->seen.filename, dc->seen.linenum);
3287 dc = alloc(sizeof(device_config_t));
3290 /* add at end of list */
3291 if (!device_config_list)
3292 device_config_list = dc;
3294 dc1 = device_config_list;
3295 while (dc1->next != NULL) {
3303 copy_device_config(void)
3305 device_config_t *dc;
3308 dc = lookup_device_config(tokenval.v.s);
3311 conf_parserror(_("device parameter expected"));
3315 for(i=0; i < DEVICE_CONFIG_DEVICE_CONFIG; i++) {
3316 if(dc->value[i].seen.linenum) {
3317 merge_val_t(&dccur.value[i], &dc->value[i]);
3322 static changer_config_t *
3323 read_changer_config(
3329 int save_overwrites;
3330 FILE *saved_conf = NULL;
3331 char *saved_fname = NULL;
3334 saved_conf = current_file;
3335 current_file = from;
3339 saved_fname = current_filename;
3340 current_filename = fname;
3344 current_line_num = *linenum;
3346 save_overwrites = allow_overwrites;
3347 allow_overwrites = 1;
3349 init_changer_config_defaults();
3353 get_conftoken(CONF_IDENT);
3354 cccur.name = stralloc(tokenval.v.s);
3356 current_block = g_strconcat("changer ", cccur.name, NULL);
3357 cccur.seen.block = current_block;
3358 cccur.seen.filename = current_filename;
3359 cccur.seen.linenum = current_line_num;
3361 read_block(changer_config_var, cccur.value,
3362 _("changer parameter expected"),
3363 (name == NULL), *copy_changer_config,
3364 "CHANGER", cccur.name);
3366 get_conftoken(CONF_NL);
3368 save_changer_config();
3370 allow_overwrites = save_overwrites;
3373 *linenum = current_line_num;
3376 current_filename = saved_fname;
3379 current_file = saved_conf;
3381 return lookup_changer_config(cccur.name);
3388 read_changer_config(NULL, NULL, NULL, NULL);
3392 init_changer_config_defaults(
3396 conf_init_str(&cccur.value[CHANGER_CONFIG_COMMENT] , "");
3397 conf_init_str(&cccur.value[CHANGER_CONFIG_TAPEDEV] , "");
3398 conf_init_str(&cccur.value[CHANGER_CONFIG_TPCHANGER] , "");
3399 conf_init_str(&cccur.value[CHANGER_CONFIG_CHANGERDEV] , "");
3400 conf_init_str(&cccur.value[CHANGER_CONFIG_CHANGERFILE] , "");
3401 conf_init_proplist(&cccur.value[CHANGER_CONFIG_PROPERTY]);
3402 conf_init_proplist(&cccur.value[CHANGER_CONFIG_DEVICE_PROPERTY]);
3406 save_changer_config(
3409 changer_config_t *dc, *dc1;
3411 dc = lookup_changer_config(cccur.name);
3413 if(dc != (changer_config_t *)0) {
3414 conf_parserror(_("changer %s already defined at %s:%d"),
3415 dc->name, dc->seen.filename, dc->seen.linenum);
3419 dc = alloc(sizeof(changer_config_t));
3422 /* add at end of list */
3423 if (!changer_config_list)
3424 changer_config_list = dc;
3426 dc1 = changer_config_list;
3427 while (dc1->next != NULL) {
3435 copy_changer_config(void)
3437 changer_config_t *dc;
3440 dc = lookup_changer_config(tokenval.v.s);
3443 conf_parserror(_("changer parameter expected"));
3447 for(i=0; i < CHANGER_CONFIG_CHANGER_CONFIG; i++) {
3448 if(dc->value[i].seen.linenum) {
3449 merge_val_t(&cccur.value[i], &dc->value[i]);
3454 /* Read functions */
3458 conf_var_t *np G_GNUC_UNUSED,
3462 val_t__int(val) = get_int(val->unit);
3467 conf_var_t *np G_GNUC_UNUSED,
3471 val_t__int64(val) = get_int64(val->unit);
3476 conf_var_t *np G_GNUC_UNUSED,
3480 get_conftoken(CONF_REAL);
3481 val_t__real(val) = tokenval.v.r;
3486 conf_var_t *np G_GNUC_UNUSED,
3490 get_conftoken(CONF_STRING);
3491 val->v.s = newstralloc(val->v.s, tokenval.v.s);
3496 conf_var_t *np G_GNUC_UNUSED,
3500 get_conftoken(CONF_IDENT);
3501 val->v.s = newstralloc(val->v.s, tokenval.v.s);
3506 conf_var_t *np G_GNUC_UNUSED,
3510 val_t__time(val) = get_time();
3515 conf_var_t *np G_GNUC_UNUSED,
3519 val_t__size(val) = get_size(val->unit);
3524 conf_var_t *np G_GNUC_UNUSED,
3528 val_t__boolean(val) = get_bool();
3533 conf_var_t *np G_GNUC_UNUSED,
3537 val_t__int(val) = get_no_yes_all();
3542 conf_var_t *np G_GNUC_UNUSED,
3545 int serv, clie, none, fast, best, custom;
3551 serv = clie = none = fast = best = custom = 0;
3555 get_conftoken(CONF_ANY);
3557 case CONF_NONE: none = 1; break;
3558 case CONF_FAST: fast = 1; break;
3559 case CONF_BEST: best = 1; break;
3560 case CONF_CLIENT: clie = 1; break;
3561 case CONF_SERVER: serv = 1; break;
3562 case CONF_CUSTOM: custom=1; break;
3563 case CONF_NL: done = 1; break;
3564 case CONF_END: done = 1; break;
3567 serv = clie = 1; /* force an error */
3571 if(serv + clie == 0) clie = 1; /* default to client */
3572 if(none + fast + best + custom == 0) fast = 1; /* default to fast */
3577 if(none && !fast && !best && !custom) comp = COMP_NONE;
3578 if(!none && fast && !best && !custom) comp = COMP_FAST;
3579 if(!none && !fast && best && !custom) comp = COMP_BEST;
3580 if(!none && !fast && !best && custom) comp = COMP_CUST;
3584 if(none && !fast && !best && !custom) comp = COMP_NONE;
3585 if(!none && fast && !best && !custom) comp = COMP_SERVER_FAST;
3586 if(!none && !fast && best && !custom) comp = COMP_SERVER_BEST;
3587 if(!none && !fast && !best && custom) comp = COMP_SERVER_CUST;
3590 if((int)comp == -1) {
3591 conf_parserror(_("NONE, CLIENT FAST, CLIENT BEST, CLIENT CUSTOM, SERVER FAST, SERVER BEST or SERVER CUSTOM expected"));
3595 val_t__compress(val) = (int)comp;
3600 conf_var_t *np G_GNUC_UNUSED,
3607 get_conftoken(CONF_ANY);
3610 encrypt = ENCRYPT_NONE;
3614 encrypt = ENCRYPT_CUST;
3618 encrypt = ENCRYPT_SERV_CUST;
3622 conf_parserror(_("NONE, CLIENT or SERVER expected"));
3623 encrypt = ENCRYPT_NONE;
3627 val_t__encrypt(val) = (int)encrypt;
3632 conf_var_t *np G_GNUC_UNUSED,
3635 dump_holdingdisk_t holding;
3639 get_conftoken(CONF_ANY);
3642 holding = HOLD_NEVER;
3646 holding = HOLD_AUTO;
3650 holding = HOLD_REQUIRED;
3653 default: /* can be a BOOLEAN */
3655 holding = (dump_holdingdisk_t)get_bool();
3657 holding = HOLD_NEVER;
3658 else if (holding == 1 || holding == 2)
3659 holding = HOLD_AUTO;
3661 conf_parserror(_("NEVER, AUTO or REQUIRED expected"));
3665 val_t__holding(val) = (int)holding;
3670 conf_var_t *np G_GNUC_UNUSED,
3673 estimatelist_t estimates = NULL;
3677 get_conftoken(CONF_ANY);
3681 estimates = g_slist_append(estimates, GINT_TO_POINTER(ES_CLIENT));
3684 estimates = g_slist_append(estimates, GINT_TO_POINTER(ES_SERVER));
3687 estimates = g_slist_append(estimates, GINT_TO_POINTER(ES_CALCSIZE));
3690 conf_parserror(_("CLIENT, SERVER or CALCSIZE expected"));
3692 get_conftoken(CONF_ANY);
3696 val_t__estimatelist(val) = estimates;
3701 conf_var_t *np G_GNUC_UNUSED,
3708 get_conftoken(CONF_ANY);
3714 strat = DS_STANDARD;
3726 strat = DS_INCRONLY;
3729 conf_parserror(_("dump strategy expected"));
3730 strat = DS_STANDARD;
3732 val_t__strategy(val) = strat;
3737 conf_var_t *np G_GNUC_UNUSED,
3742 get_conftoken(CONF_ANY);
3744 case CONF_FIRST: val_t__taperalgo(val) = ALGO_FIRST; break;
3745 case CONF_FIRSTFIT: val_t__taperalgo(val) = ALGO_FIRSTFIT; break;
3746 case CONF_LARGEST: val_t__taperalgo(val) = ALGO_LARGEST; break;
3747 case CONF_LARGESTFIT: val_t__taperalgo(val) = ALGO_LARGESTFIT; break;
3748 case CONF_SMALLEST: val_t__taperalgo(val) = ALGO_SMALLEST; break;
3749 case CONF_LAST: val_t__taperalgo(val) = ALGO_LAST; break;
3751 conf_parserror(_("FIRST, FIRSTFIT, LARGEST, LARGESTFIT, SMALLEST or LAST expected"));
3756 read_send_amreport_on(
3757 conf_var_t *np G_GNUC_UNUSED,
3762 get_conftoken(CONF_ANY);
3764 case CONF_ALL: val_t__send_amreport(val) = SEND_AMREPORT_ALL; break;
3765 case CONF_STRANGE: val_t__send_amreport(val) = SEND_AMREPORT_STRANGE; break;
3766 case CONF_ERROR: val_t__send_amreport(val) = SEND_AMREPORT_ERROR; break;
3767 case CONF_NEVER: val_t__send_amreport(val) = SEND_AMREPORT_NEVER; break;
3769 conf_parserror(_("ALL, STRANGE, ERROR or NEVER expected"));
3775 conf_var_t *np G_GNUC_UNUSED,
3780 get_conftoken(CONF_ANY);
3782 case CONF_AMANDA : val_t__data_path(val) = DATA_PATH_AMANDA ; break;
3783 case CONF_DIRECTTCP: val_t__data_path(val) = DATA_PATH_DIRECTTCP; break;
3785 conf_parserror(_("AMANDA or DIRECTTCP expected"));
3791 conf_var_t *np G_GNUC_UNUSED,
3798 get_conftoken(CONF_ANY);
3800 case CONF_LOW: pri = 0; break;
3801 case CONF_MEDIUM: pri = 1; break;
3802 case CONF_HIGH: pri = 2; break;
3803 case CONF_INT: pri = tokenval.v.i; break;
3805 conf_parserror(_("LOW, MEDIUM, HIGH or integer expected"));
3808 val_t__priority(val) = pri;
3813 conf_var_t *np G_GNUC_UNUSED,
3816 get_conftoken(CONF_REAL);
3817 val_t__rate(val)[0] = tokenval.v.r;
3818 val_t__rate(val)[1] = tokenval.v.r;
3819 val->seen = tokenval.seen;
3820 if(tokenval.v.r < 0) {
3821 conf_parserror(_("full compression rate must be >= 0"));
3824 get_conftoken(CONF_ANY);
3839 get_conftoken(CONF_REAL);
3840 val_t__rate(val)[1] = tokenval.v.r;
3841 if(tokenval.v.r < 0) {
3842 conf_parserror(_("incremental compression rate must be >= 0"));
3848 conf_var_t *np G_GNUC_UNUSED,
3851 int file, got_one = 0;
3855 get_conftoken(CONF_ANY);
3856 if(tok == CONF_LIST) {
3858 get_conftoken(CONF_ANY);
3859 exclude = val_t__exinclude(val).sl_list;
3863 if(tok == CONF_EFILE) get_conftoken(CONF_ANY);
3864 exclude = val_t__exinclude(val).sl_file;
3868 if(tok == CONF_OPTIONAL) {
3869 get_conftoken(CONF_ANY);
3873 if(tok == CONF_APPEND) {
3874 get_conftoken(CONF_ANY);
3881 while(tok == CONF_STRING) {
3882 exclude = append_sl(exclude, tokenval.v.s);
3884 get_conftoken(CONF_ANY);
3888 if(got_one == 0) { free_sl(exclude); exclude = NULL; }
3891 val_t__exinclude(val).sl_list = exclude;
3893 val_t__exinclude(val).sl_file = exclude;
3894 val_t__exinclude(val).optional = optional;
3899 conf_var_t *np G_GNUC_UNUSED,
3902 get_conftoken(CONF_INT);
3903 val_t__intrange(val)[0] = tokenval.v.i;
3904 val_t__intrange(val)[1] = tokenval.v.i;
3905 val->seen = tokenval.seen;
3907 get_conftoken(CONF_ANY);
3922 get_conftoken(CONF_INT);
3923 val_t__intrange(val)[1] = tokenval.v.i;
3928 conf_var_t *np G_GNUC_UNUSED,
3932 gboolean set_seen = TRUE;
3933 property_t *property = malloc(sizeof(property_t));
3934 property_t *old_property;
3935 property->append = 0;
3936 property->priority = 0;
3937 property->values = NULL;
3939 get_conftoken(CONF_ANY);
3940 if (tok == CONF_PRIORITY) {
3941 property->priority = 1;
3942 get_conftoken(CONF_ANY);
3944 if (tok == CONF_APPEND) {
3945 property->append = 1;
3946 get_conftoken(CONF_ANY);
3948 if (tok != CONF_STRING) {
3949 conf_parserror(_("key expected"));
3952 key = amandaify_property_name(tokenval.v.s);
3954 get_conftoken(CONF_ANY);
3955 if (tok == CONF_NL || tok == CONF_END) {
3956 g_hash_table_remove(val->v.proplist, key);
3960 if (tok != CONF_STRING) {
3961 conf_parserror(_("value expected"));
3965 if(val->seen.linenum == 0) {
3966 ckseen(&val->seen); // first property
3969 old_property = g_hash_table_lookup(val->v.proplist, key);
3970 if (property->append) {
3971 /* old_property will be freed by g_hash_table_insert, so
3972 * steal its values */
3974 if (old_property->priority)
3975 property->priority = 1;
3976 property->values = old_property->values;
3977 old_property->values = NULL;
3981 while(tok == CONF_STRING) {
3982 property->values = g_slist_append(property->values,
3983 strdup(tokenval.v.s));
3984 get_conftoken(CONF_ANY);
3987 g_hash_table_insert(val->v.proplist, key, property);
3989 property->seen.linenum = 0;
3990 property->seen.filename = NULL;
3991 property->seen.block = NULL;
3992 ckseen(&property->seen);
3999 conf_var_t *np G_GNUC_UNUSED,
4002 application_t *application;
4004 get_conftoken(CONF_ANY);
4005 if (tok == CONF_LBRACE) {
4006 current_line_num -= 1;
4007 application = read_application(vstralloc("custom(DUMPTYPE:",
4008 dpcur.name, ")", ".",
4009 anonymous_value(),NULL),
4011 current_line_num -= 1;
4012 } else if (tok == CONF_STRING) {
4013 application = lookup_application(tokenval.v.s);
4014 if (application == NULL) {
4015 conf_parserror(_("Unknown application named: %s"), tokenval.v.s);
4019 conf_parserror(_("application name expected: %d %d"), tok, CONF_STRING);
4023 val->v.s = stralloc(application->name);
4028 read_dinteractivity(
4029 conf_var_t *np G_GNUC_UNUSED,
4032 interactivity_t *interactivity;
4034 get_conftoken(CONF_ANY);
4035 if (tok == CONF_LBRACE) {
4036 current_line_num -= 1;
4037 interactivity = read_interactivity(vstralloc("custom(iv)", ".",
4038 anonymous_value(),NULL),
4040 current_line_num -= 1;
4041 } else if (tok == CONF_STRING) {
4042 interactivity = lookup_interactivity(tokenval.v.s);
4043 if (interactivity == NULL) {
4044 conf_parserror(_("Unknown interactivity named: %s"), tokenval.v.s);
4048 conf_parserror(_("interactivity name expected: %d %d"), tok, CONF_STRING);
4052 val->v.s = stralloc(interactivity->name);
4058 conf_var_t *np G_GNUC_UNUSED,
4061 taperscan_t *taperscan;
4063 get_conftoken(CONF_ANY);
4064 if (tok == CONF_LBRACE) {
4065 current_line_num -= 1;
4066 taperscan = read_taperscan(vstralloc("custom(ts)", ".",
4067 anonymous_value(),NULL),
4069 current_line_num -= 1;
4070 } else if (tok == CONF_STRING) {
4071 taperscan = lookup_taperscan(tokenval.v.s);
4072 if (taperscan == NULL) {
4073 conf_parserror(_("Unknown taperscan named: %s"), tokenval.v.s);
4077 conf_parserror(_("taperscan name expected: %d %d"), tok, CONF_STRING);
4081 val->v.s = stralloc(taperscan->name);
4087 conf_var_t *np G_GNUC_UNUSED,
4090 pp_script_t *pp_script;
4091 get_conftoken(CONF_ANY);
4092 if (tok == CONF_LBRACE) {
4093 current_line_num -= 1;
4094 pp_script = read_pp_script(vstralloc("custom(DUMPTYPE:", dpcur.name,
4095 ")", ".", anonymous_value(),NULL),
4097 current_line_num -= 1;
4098 val->v.identlist = g_slist_insert_sorted(val->v.identlist,
4099 stralloc(pp_script->name), &compare_pp_script_order);
4100 } else if (tok == CONF_STRING || tok == CONF_IDENT) {
4101 while (tok == CONF_STRING || tok == CONF_IDENT) {
4102 pp_script = lookup_pp_script(tokenval.v.s);
4103 if (pp_script == NULL) {
4104 conf_parserror(_("Unknown pp_script named: %s"), tokenval.v.s);
4107 val->v.identlist = g_slist_insert_sorted(val->v.identlist,
4108 stralloc(pp_script->name), &compare_pp_script_order);
4109 get_conftoken(CONF_ANY);
4113 conf_parserror(_("pp_script name expected: %d %d"), tok, CONF_STRING);
4120 conf_var_t *np G_GNUC_UNUSED,
4125 get_conftoken(CONF_ANY);
4129 case CONF_PRE_AMCHECK: val->v.i |= EXECUTE_ON_PRE_AMCHECK; break;
4130 case CONF_PRE_DLE_AMCHECK: val->v.i |= EXECUTE_ON_PRE_DLE_AMCHECK; break;
4131 case CONF_PRE_HOST_AMCHECK: val->v.i |= EXECUTE_ON_PRE_HOST_AMCHECK; break;
4132 case CONF_POST_DLE_AMCHECK: val->v.i |= EXECUTE_ON_POST_DLE_AMCHECK; break;
4133 case CONF_POST_HOST_AMCHECK: val->v.i |= EXECUTE_ON_POST_HOST_AMCHECK; break;
4134 case CONF_POST_AMCHECK: val->v.i |= EXECUTE_ON_POST_AMCHECK; break;
4135 case CONF_PRE_ESTIMATE: val->v.i |= EXECUTE_ON_PRE_ESTIMATE; break;
4136 case CONF_PRE_DLE_ESTIMATE: val->v.i |= EXECUTE_ON_PRE_DLE_ESTIMATE; break;
4137 case CONF_PRE_HOST_ESTIMATE: val->v.i |= EXECUTE_ON_PRE_HOST_ESTIMATE; break;
4138 case CONF_POST_DLE_ESTIMATE: val->v.i |= EXECUTE_ON_POST_DLE_ESTIMATE; break;
4139 case CONF_POST_HOST_ESTIMATE: val->v.i |= EXECUTE_ON_POST_HOST_ESTIMATE; break;
4140 case CONF_POST_ESTIMATE: val->v.i |= EXECUTE_ON_POST_ESTIMATE; break;
4141 case CONF_PRE_BACKUP: val->v.i |= EXECUTE_ON_PRE_BACKUP; break;
4142 case CONF_PRE_DLE_BACKUP: val->v.i |= EXECUTE_ON_PRE_DLE_BACKUP; break;
4143 case CONF_PRE_HOST_BACKUP: val->v.i |= EXECUTE_ON_PRE_HOST_BACKUP; break;
4144 case CONF_POST_BACKUP: val->v.i |= EXECUTE_ON_POST_BACKUP; break;
4145 case CONF_POST_DLE_BACKUP: val->v.i |= EXECUTE_ON_POST_DLE_BACKUP; break;
4146 case CONF_POST_HOST_BACKUP: val->v.i |= EXECUTE_ON_POST_HOST_BACKUP; break;
4147 case CONF_PRE_RECOVER: val->v.i |= EXECUTE_ON_PRE_RECOVER; break;
4148 case CONF_POST_RECOVER: val->v.i |= EXECUTE_ON_POST_RECOVER; break;
4149 case CONF_PRE_LEVEL_RECOVER: val->v.i |= EXECUTE_ON_PRE_LEVEL_RECOVER; break;
4150 case CONF_POST_LEVEL_RECOVER: val->v.i |= EXECUTE_ON_POST_LEVEL_RECOVER; break;
4151 case CONF_INTER_LEVEL_RECOVER: val->v.i |= EXECUTE_ON_INTER_LEVEL_RECOVER; break;
4153 conf_parserror(_("Execute-on expected"));
4155 get_conftoken(CONF_ANY);
4156 if (tok != CONF_COMMA) {
4160 get_conftoken(CONF_ANY);
4166 conf_var_t *np G_GNUC_UNUSED,
4171 get_conftoken(CONF_ANY);
4173 case CONF_CLIENT: val->v.i = ES_CLIENT; break;
4174 case CONF_SERVER: val->v.i = ES_SERVER; break;
4176 conf_parserror(_("CLIENT or SERVER expected"));
4182 conf_var_t *np G_GNUC_UNUSED,
4187 get_conftoken(CONF_ANY);
4191 val->v.s = g_strdup_printf("%d", tokenval.v.i);
4196 val->v.s = g_strdup_printf("%zu", tokenval.v.size);
4201 val->v.s = g_strdup_printf("%jd", (intmax_t)tokenval.v.int64);
4205 val->v.s = newstralloc(val->v.s, tokenval.v.s);
4208 conf_parserror(_("an integer or a quoted string is expected"));
4214 conf_var_t *np G_GNUC_UNUSED,
4220 get_conftoken(CONF_ANY);
4221 if (tok == CONF_STRING) {
4223 val->v.autolabel.template = newstralloc(val->v.autolabel.template,
4225 get_conftoken(CONF_ANY);
4227 val->v.autolabel.autolabel = 0;
4228 while (tok != CONF_NL && tok != CONF_END) {
4230 if (tok == CONF_ANY_VOLUME)
4231 val->v.autolabel.autolabel |= AL_OTHER_CONFIG | AL_NON_AMANDA |
4232 AL_VOLUME_ERROR | AL_EMPTY;
4233 else if (tok == CONF_OTHER_CONFIG)
4234 val->v.autolabel.autolabel |= AL_OTHER_CONFIG;
4235 else if (tok == CONF_NON_AMANDA)
4236 val->v.autolabel.autolabel |= AL_NON_AMANDA;
4237 else if (tok == CONF_VOLUME_ERROR)
4238 val->v.autolabel.autolabel |= AL_VOLUME_ERROR;
4239 else if (tok == CONF_EMPTY)
4240 val->v.autolabel.autolabel |= AL_EMPTY;
4242 conf_parserror(_("ANY, NEW-VOLUME, OTHER-CONFIG, NON-AMANDA, VOLUME-ERROR or EMPTY is expected"));
4244 get_conftoken(CONF_ANY);
4247 amfree(val->v.autolabel.template);
4248 val->v.autolabel.autolabel = 0;
4249 } else if (val->v.autolabel.autolabel == 0) {
4250 val->v.autolabel.autolabel = AL_VOLUME_ERROR | AL_EMPTY;
4255 read_part_cache_type(
4256 conf_var_t *np G_GNUC_UNUSED,
4259 part_cache_type_t part_cache_type;
4263 get_conftoken(CONF_ANY);
4266 part_cache_type = PART_CACHE_TYPE_NONE;
4270 part_cache_type = PART_CACHE_TYPE_DISK;
4274 part_cache_type = PART_CACHE_TYPE_MEMORY;
4278 conf_parserror(_("NONE, DISK or MEMORY expected"));
4279 part_cache_type = PART_CACHE_TYPE_NONE;
4283 val_t__part_cache_type(val) = (int)part_cache_type;
4288 conf_var_t *np G_GNUC_UNUSED,
4291 host_limit_t *rl = &val_t__host_limit(val);
4294 rl->match_pats = NULL;
4295 rl->same_host = FALSE;
4299 get_conftoken(CONF_ANY);
4302 rl->match_pats = g_slist_append(rl->match_pats, g_strdup(tokenval.v.s));
4304 case CONF_SAME_HOST:
4305 rl->same_host = TRUE;
4317 conf_parserror("SAME-HOST or a string expected");
4323 /* get_* functions */
4325 /* these functions use precompiler conditionals to skip useless size checks
4326 * when casting from one type to another. SIZEOF_GINT64 is pretty simple to
4327 * calculate; the others are calculated by configure. */
4329 #define SIZEOF_GINT64 8
4336 get_conftoken(CONF_ANY);
4339 #if SIZEOF_TIME_T < SIZEOF_INT
4340 if ((gint64)tokenval.v.i >= (gint64)TIME_MAX)
4341 conf_parserror(_("value too large"));
4343 hhmm = (time_t)tokenval.v.i;
4347 #if SIZEOF_TIME_T < SIZEOF_SSIZE_T
4348 if ((gint64)tokenval.v.size >= (gint64)TIME_MAX)
4349 conf_parserror(_("value too large"));
4351 hhmm = (time_t)tokenval.v.size;
4355 #if SIZEOF_TIME_T < SIZEOF_GINT64
4356 if ((gint64)tokenval.v.int64 >= (gint64)TIME_MAX)
4357 conf_parserror(_("value too large"));
4359 hhmm = (time_t)tokenval.v.int64;
4362 case CONF_AMINFINITY:
4367 conf_parserror(_("a time is expected"));
4382 keytable = numb_keytable;
4384 get_conftoken(CONF_ANY);
4391 #if SIZEOF_INT < SIZEOF_SSIZE_T
4392 if ((gint64)tokenval.v.size > (gint64)INT_MAX)
4393 conf_parserror(_("value too large"));
4394 if ((gint64)tokenval.v.size < (gint64)INT_MIN)
4395 conf_parserror(_("value too small"));
4397 val = (int)tokenval.v.size;
4401 #if SIZEOF_INT < SIZEOF_GINT64
4402 if (tokenval.v.int64 > (gint64)INT_MAX)
4403 conf_parserror(_("value too large"));
4404 if (tokenval.v.int64 < (gint64)INT_MIN)
4405 conf_parserror(_("value too small"));
4407 val = (int)tokenval.v.int64;
4410 case CONF_AMINFINITY:
4415 conf_parserror(_("an integer is expected"));
4420 /* get multiplier, if any */
4421 val = get_multiplier(val, unit);
4435 keytable = numb_keytable;
4437 get_conftoken(CONF_ANY);
4441 val = tokenval.v.size;
4445 #if SIZEOF_SIZE_T < SIZEOF_INT
4446 if ((gint64)tokenval.v.i > (gint64)SSIZE_MAX)
4447 conf_parserror(_("value too large"));
4448 if ((gint64)tokenval.v.i < (gint64)SSIZE_MIN)
4449 conf_parserror(_("value too small"));
4451 val = (ssize_t)tokenval.v.i;
4455 #if SIZEOF_SIZE_T < SIZEOF_GINT64
4456 if (tokenval.v.int64 > (gint64)SSIZE_MAX)
4457 conf_parserror(_("value too large"));
4458 if (tokenval.v.int64 < (gint64)SSIZE_MIN)
4459 conf_parserror(_("value too small"));
4461 val = (ssize_t)tokenval.v.int64;
4464 case CONF_AMINFINITY:
4465 val = (ssize_t)SSIZE_MAX;
4469 conf_parserror(_("an integer is expected"));
4474 /* get multiplier, if any */
4475 val = get_multiplier(val, unit);
4489 keytable = numb_keytable;
4491 get_conftoken(CONF_ANY);
4495 val = (gint64)tokenval.v.i;
4499 val = (gint64)tokenval.v.size;
4503 val = tokenval.v.int64;
4506 case CONF_AMINFINITY:
4511 conf_parserror(_("an integer is expected"));
4516 /* get multiplier, if any */
4517 val = get_multiplier(val, unit);
4529 /* get multiplier, if any */
4530 get_conftoken(CONF_ANY);
4532 if (tok == CONF_NL || tok == CONF_END) { /* no multiplier */
4534 } else if (tok == CONF_MULT1 && unit == CONF_UNIT_K) {
4536 } else if (tok == CONF_MULT1 ||
4537 (tok == CONF_MULT1K && unit == CONF_UNIT_K)) {
4538 val *= 1; /* multiply by one */
4539 } else if (tok == CONF_MULT7) {
4540 if (val > G_MAXINT64/7 || val < ((gint64)G_MININT64)/7)
4541 conf_parserror(_("value too large"));
4543 } else if (tok == CONF_MULT1K ||
4544 (tok == CONF_MULT1M && unit == CONF_UNIT_K)) {
4545 if (val > G_MAXINT64/1024 || val < ((gint64)G_MININT64)/1024)
4546 conf_parserror(_("value too large"));
4548 } else if (tok == CONF_MULT1M ||
4549 (tok == CONF_MULT1G && unit == CONF_UNIT_K)) {
4550 if (val > G_MAXINT64/(1024*1024) || val < ((gint64)G_MININT64)/(1024*1024))
4551 conf_parserror(_("value too large"));
4553 } else if (tok == CONF_MULT1G ||
4554 (tok == CONF_MULT1T && unit == CONF_UNIT_K)) {
4555 if (val > G_MAXINT64/(1024*1024*1024) || val < ((gint64)G_MININT64)/(1024*1024*1024))
4556 conf_parserror(_("value too large"));
4557 val *= 1024*1024*1024;
4558 } else if (tok == CONF_MULT1T) {
4559 if (val > G_MAXINT64/(1024*1024*1024*1024LL) || val < ((gint64)G_MININT64)/(1024*1024*1024*1024LL))
4560 conf_parserror(_("value too large"));
4561 val *= 1024*1024*1024*1024LL;
4577 keytable = bool_keytable;
4579 get_conftoken(CONF_ANY);
4583 if (tokenval.v.i != 0)
4590 if (tokenval.v.size != (size_t)0)
4597 if (tokenval.v.int64 != (gint64)0)
4613 val = 2; /* no argument - most likely TRUE */
4617 val = 3; /* a bad argument - most likely TRUE */
4618 conf_parserror(_("YES, NO, TRUE, FALSE, ON, OFF, 0, 1 expected"));
4627 get_no_yes_all(void)
4633 keytable = no_yes_all_keytable;
4635 get_conftoken(CONF_ANY);
4643 val = tokenval.v.size;
4647 val = tokenval.v.int64;
4664 val = 3; /* no argument - most likely TRUE */
4668 val = 3; /* a bad argument - most likely TRUE */
4669 conf_parserror(_("%d: YES, NO, ALL, TRUE, FALSE, ON, OFF, 0, 1, 2 expected"), tok);
4673 if (val > 2 || val < 0)
4683 if (seen->linenum && !allow_overwrites && current_line_num != -2) {
4684 conf_parserror(_("duplicate parameter; previous definition %s:%d"),
4685 seen->filename, seen->linenum);
4687 seen->block = current_block;
4688 seen->filename = current_filename;
4689 seen->linenum = current_line_num;
4692 /* Validation functions */
4695 validate_nonnegative(
4696 struct conf_var_s *np,
4701 if(val_t__int(val) < 0)
4702 conf_parserror(_("%s must be nonnegative"), get_token_name(np->token));
4704 case CONFTYPE_INT64:
4705 if(val_t__int64(val) < 0)
4706 conf_parserror(_("%s must be nonnegative"), get_token_name(np->token));
4709 if(val_t__size(val) < 0)
4710 conf_parserror(_("%s must be positive"), get_token_name(np->token));
4713 conf_parserror(_("validate_nonnegative invalid type %d\n"), val->type);
4719 struct conf_var_s *np,
4724 if(val_t__int(val) == 0)
4725 conf_parserror(_("%s must not be 0"), get_token_name(np->token));
4727 case CONFTYPE_INT64:
4728 if(val_t__int64(val) == 0)
4729 conf_parserror(_("%s must not be 0"), get_token_name(np->token));
4732 if(val_t__time(val) == 0)
4733 conf_parserror(_("%s must not be 0"), get_token_name(np->token));
4736 if(val_t__size(val) == 0)
4737 conf_parserror(_("%s must not be 0"), get_token_name(np->token));
4740 conf_parserror(_("validate_non_zero invalid type %d\n"), val->type);
4746 struct conf_var_s *np,
4751 if(val_t__int(val) < 1)
4752 conf_parserror(_("%s must be positive"), get_token_name(np->token));
4754 case CONFTYPE_INT64:
4755 if(val_t__int64(val) < 1)
4756 conf_parserror(_("%s must be positive"), get_token_name(np->token));
4759 if(val_t__time(val) < 1)
4760 conf_parserror(_("%s must be positive"), get_token_name(np->token));
4763 if(val_t__size(val) < 1)
4764 conf_parserror(_("%s must be positive"), get_token_name(np->token));
4767 conf_parserror(_("validate_positive invalid type %d\n"), val->type);
4772 validate_runspercycle(
4773 struct conf_var_s *np G_GNUC_UNUSED,
4776 if(val_t__int(val) < -1)
4777 conf_parserror(_("runspercycle must be >= -1"));
4781 validate_bumppercent(
4782 struct conf_var_s *np G_GNUC_UNUSED,
4785 if(val_t__int(val) < 0 || val_t__int(val) > 100)
4786 conf_parserror(_("bumppercent must be between 0 and 100"));
4790 validate_inparallel(
4791 struct conf_var_s *np G_GNUC_UNUSED,
4794 if(val_t__int(val) < 1 || val_t__int(val) >MAX_DUMPERS)
4795 conf_parserror(_("inparallel must be between 1 and MAX_DUMPERS (%d)"),
4801 struct conf_var_s *np G_GNUC_UNUSED,
4804 if(val_t__real(val) < 0.999) {
4805 conf_parserror(_("bumpmult must one or more"));
4810 validate_displayunit(
4811 struct conf_var_s *np G_GNUC_UNUSED,
4812 val_t *val G_GNUC_UNUSED)
4814 char *s = val_t__str(val);
4815 if (strlen(s) == 1) {
4821 return; /* all good */
4823 /* lower-case values should get folded to upper case */
4828 s[0] = toupper(s[0]);
4835 conf_parserror(_("displayunit must be k,m,g or t."));
4840 struct conf_var_s *np G_GNUC_UNUSED,
4843 if(val_t__int(val) < 0 || val_t__int(val) > 100)
4844 conf_parserror(_("reserve must be between 0 and 100"));
4849 struct conf_var_s *np G_GNUC_UNUSED,
4852 val_t__int64(val) = am_floor(val_t__int64(val), DISK_BLOCK_KB);
4857 struct conf_var_s *np G_GNUC_UNUSED,
4860 /* NOTE: this function modifies the target value (rounding) */
4861 if(val_t__int64(val) == 0) {
4862 val_t__int64(val) = ((G_MAXINT64 / 1024) - (2 * DISK_BLOCK_KB));
4864 else if(val_t__int64(val) < 0) {
4865 conf_parserror(_("Negative chunksize (%lld) is no longer supported"), (long long)val_t__int64(val));
4867 val_t__int64(val) = am_floor(val_t__int64(val), (gint64)DISK_BLOCK_KB);
4868 if (val_t__int64(val) < 2*DISK_BLOCK_KB) {
4869 conf_parserror("chunksize must be at least %dkb", 2*DISK_BLOCK_KB);
4875 struct conf_var_s *np G_GNUC_UNUSED,
4878 if(val_t__size(val) < DISK_BLOCK_KB) {
4879 conf_parserror(_("Tape blocksize must be at least %d KBytes"),
4886 struct conf_var_s *np G_GNUC_UNUSED,
4889 if(val_t__int(val) < 0 || val_t__int(val) > 9) {
4890 conf_parserror(_("Debug must be between 0 and 9"));
4895 validate_port_range(
4901 /* check both values are in range */
4902 for (i = 0; i < 2; i++) {
4903 if(val_t__intrange(val)[0] < smallest || val_t__intrange(val)[0] > largest) {
4904 conf_parserror(_("portrange must be in the range %d to %d, inclusive"), smallest, largest);
4908 /* and check they're in the right order and not equal */
4909 if (val_t__intrange(val)[0] > val_t__intrange(val)[1]) {
4910 conf_parserror(_("portranges must be in order from low to high"));
4915 validate_reserved_port_range(
4916 struct conf_var_s *np G_GNUC_UNUSED,
4919 validate_port_range(val, 1, IPPORT_RESERVED-1);
4923 validate_unreserved_port_range(
4924 struct conf_var_s *np G_GNUC_UNUSED,
4927 validate_port_range(val, IPPORT_RESERVED, 65535);
4931 * Validate tmpdir, the directory must exist and be writable by the user.
4934 static void validate_tmpdir(conf_var_t *var G_GNUC_UNUSED, val_t *value)
4936 struct stat stat_buf;
4937 gchar *tmpdir = val_t_to_str(value);
4939 if (stat(tmpdir, &stat_buf)) {
4940 conf_parserror(_("invalid TMPDIR: directory '%s': %s."),
4941 tmpdir, strerror(errno));
4942 } else if (!S_ISDIR(stat_buf.st_mode)) {
4943 conf_parserror(_("invalid TMPDIR: '%s' is not a directory."),
4946 gchar *dir = g_strconcat(tmpdir, "/.", NULL);
4947 if (access(dir, R_OK|W_OK) == -1) {
4948 conf_parserror(_("invalid TMPDIR: '%s': can not read/write: %s."),
4949 tmpdir, strerror(errno));
4956 * Initialization Implementation
4961 config_init_flags flags,
4962 char *arg_config_name)
4964 if (!(flags & CONFIG_INIT_OVERLAY)) {
4965 /* Clear out anything that's already in there */
4968 /* and set everything to default values */
4971 allow_overwrites = FALSE;
4973 if (!config_initialized) {
4974 error(_("Attempt to overlay configuration with no existing configuration"));
4978 allow_overwrites = TRUE;
4981 /* store away our client-ness for later reference */
4982 config_client = flags & CONFIG_INIT_CLIENT;
4984 /* if we're using an explicit name, but the name is '.', then we're using the
4985 * current directory */
4986 if ((flags & CONFIG_INIT_EXPLICIT_NAME) && arg_config_name) {
4987 if (0 == strcmp(arg_config_name, "."))
4988 flags = (flags & (~CONFIG_INIT_EXPLICIT_NAME)) | CONFIG_INIT_USE_CWD;
4991 if ((flags & CONFIG_INIT_EXPLICIT_NAME) && arg_config_name) {
4992 config_name = newstralloc(config_name, arg_config_name);
4993 config_dir = newvstralloc(config_dir, CONFIG_DIR, "/", arg_config_name, NULL);
4994 } else if (flags & CONFIG_INIT_USE_CWD) {
4997 cwd = get_original_cwd();
4999 /* (this isn't a config error, so it's always fatal) */
5000 error(_("Cannot determine current working directory"));
5004 config_dir = stralloc2(cwd, "/");
5005 if ((config_name = strrchr(cwd, '/')) != NULL) {
5006 config_name = stralloc(config_name + 1);
5009 } else if (flags & CONFIG_INIT_CLIENT) {
5010 amfree(config_name);
5011 config_dir = newstralloc(config_dir, CONFIG_DIR);
5013 /* ok, then, we won't read anything (for e.g., amrestore) */
5014 amfree(config_name);
5018 /* setup for apply_config_overrides */
5019 if (flags & CONFIG_INIT_CLIENT) {
5020 keytable = client_keytab;
5021 parsetable = client_var;
5023 keytable = server_keytab;
5024 parsetable = server_var;
5027 if (config_overrides) {
5029 for (i = 0; i < config_overrides->n_used; i++) {
5030 config_overrides->ovr[i].applied = FALSE;
5034 /* apply config overrides to default setting */
5035 apply_config_overrides(config_overrides, NULL);
5037 /* If we have a config_dir, we can try reading something */
5039 if (flags & CONFIG_INIT_CLIENT) {
5040 config_filename = newvstralloc(config_filename, config_dir, "/amanda-client.conf", NULL);
5042 config_filename = newvstralloc(config_filename, config_dir, "/amanda.conf", NULL);
5045 read_conffile(config_filename,
5046 flags & CONFIG_INIT_CLIENT,
5047 flags & CONFIG_INIT_CLIENT);
5049 amfree(config_filename);
5052 /* apply config overrides to default setting */
5053 apply_config_overrides(config_overrides, NULL);
5055 if (config_overrides) {
5057 for (i = 0; i < config_overrides->n_used; i++) {
5058 if (config_overrides->ovr[i].applied == FALSE) {
5059 conf_parserror(_("unknown parameter '%s'"),
5060 config_overrides->ovr[i].key);
5065 update_derived_values(flags & CONFIG_INIT_CLIENT);
5067 return cfgerr_level;
5075 dumptype_t *dp, *dpnext;
5076 tapetype_t *tp, *tpnext;
5077 interface_t *ip, *ipnext;
5078 application_t *ap, *apnext;
5079 pp_script_t *pp, *ppnext;
5080 device_config_t *dc, *dcnext;
5081 changer_config_t *cc, *ccnext;
5082 interactivity_t *iv, *ivnext;
5083 taperscan_t *ts, *tsnext;
5086 if (!config_initialized) return;
5088 for(hp=holdinglist; hp != NULL; hp = hp->next) {
5091 for(i=0; i<HOLDING_HOLDING; i++) {
5092 free_val_t(&hd->value[i]);
5095 slist_free_full(holdinglist, g_free);
5098 for(dp=dumplist; dp != NULL; dp = dpnext) {
5100 for(i=0; i<DUMPTYPE_DUMPTYPE; i++) {
5101 free_val_t(&dp->value[i]);
5108 for(tp=tapelist; tp != NULL; tp = tpnext) {
5110 for(i=0; i<TAPETYPE_TAPETYPE; i++) {
5111 free_val_t(&tp->value[i]);
5118 for(ip=interface_list; ip != NULL; ip = ipnext) {
5120 for(i=0; i<INTER_INTER; i++) {
5121 free_val_t(&ip->value[i]);
5126 interface_list = NULL;
5128 for(ap=application_list; ap != NULL; ap = apnext) {
5130 for(i=0; i<APPLICATION_APPLICATION; i++) {
5131 free_val_t(&ap->value[i]);
5136 application_list = NULL;
5138 for(pp=pp_script_list; pp != NULL; pp = ppnext) {
5140 for(i=0; i<PP_SCRIPT_PP_SCRIPT; i++) {
5141 free_val_t(&pp->value[i]);
5146 pp_script_list = NULL;
5148 for(dc=device_config_list; dc != NULL; dc = dcnext) {
5150 for(i=0; i<DEVICE_CONFIG_DEVICE_CONFIG; i++) {
5151 free_val_t(&dc->value[i]);
5156 device_config_list = NULL;
5158 for(cc=changer_config_list; cc != NULL; cc = ccnext) {
5160 for(i=0; i<CHANGER_CONFIG_CHANGER_CONFIG; i++) {
5161 free_val_t(&cc->value[i]);
5166 changer_config_list = NULL;
5168 for(iv=interactivity_list; iv != NULL; iv = ivnext) {
5170 for(i=0; i<INTERACTIVITY_INTERACTIVITY; i++) {
5171 free_val_t(&iv->value[i]);
5176 interactivity_list = NULL;
5178 for(ts=taperscan_list; ts != NULL; ts = tsnext) {
5180 for(i=0; i<TAPERSCAN_TAPERSCAN; i++) {
5181 free_val_t(&ts->value[i]);
5186 taperscan_list = NULL;
5188 for(i=0; i<CNF_CNF; i++)
5189 free_val_t(&conf_data[i]);
5191 if (config_overrides) {
5192 free_config_overrides(config_overrides);
5193 config_overrides = NULL;
5196 amfree(config_name);
5198 amfree(config_filename);
5200 slist_free_full(seen_filenames, g_free);
5201 seen_filenames = NULL;
5203 config_client = FALSE;
5205 config_clear_errors();
5206 config_initialized = FALSE;
5213 assert(!config_initialized);
5215 /* defaults for exported variables */
5216 conf_init_str(&conf_data[CNF_ORG], DEFAULT_CONFIG);
5217 conf_init_str(&conf_data[CNF_CONF], DEFAULT_CONFIG);
5218 conf_init_str(&conf_data[CNF_AMDUMP_SERVER], DEFAULT_SERVER);
5219 conf_init_str(&conf_data[CNF_INDEX_SERVER], DEFAULT_SERVER);
5220 conf_init_str(&conf_data[CNF_TAPE_SERVER], DEFAULT_TAPE_SERVER);
5221 conf_init_str(&conf_data[CNF_AUTH], "bsdtcp");
5222 conf_init_str(&conf_data[CNF_SSH_KEYS], "");
5223 conf_init_str(&conf_data[CNF_AMANDAD_PATH], "");
5224 conf_init_str(&conf_data[CNF_CLIENT_USERNAME], "");
5225 conf_init_str(&conf_data[CNF_CLIENT_PORT], "");
5226 conf_init_str(&conf_data[CNF_GNUTAR_LIST_DIR], GNUTAR_LISTED_INCREMENTAL_DIR);
5227 conf_init_str(&conf_data[CNF_AMANDATES], DEFAULT_AMANDATES_FILE);
5228 conf_init_str(&conf_data[CNF_MAILTO], "");
5229 conf_init_str(&conf_data[CNF_DUMPUSER], CLIENT_LOGIN);
5230 conf_init_str(&conf_data[CNF_TAPEDEV], DEFAULT_TAPE_DEVICE);
5231 conf_init_proplist(&conf_data[CNF_DEVICE_PROPERTY]);
5232 conf_init_proplist(&conf_data[CNF_PROPERTY]);
5233 conf_init_str(&conf_data[CNF_CHANGERDEV], NULL);
5234 conf_init_str(&conf_data[CNF_CHANGERFILE] , "changer");
5235 conf_init_str (&conf_data[CNF_LABELSTR] , ".*");
5236 conf_init_str (&conf_data[CNF_TAPELIST] , "tapelist");
5237 conf_init_str (&conf_data[CNF_DISKFILE] , "disklist");
5238 conf_init_str (&conf_data[CNF_INFOFILE] , "/usr/adm/amanda/curinfo");
5239 conf_init_str (&conf_data[CNF_LOGDIR] , "/usr/adm/amanda");
5240 conf_init_str (&conf_data[CNF_INDEXDIR] , "/usr/adm/amanda/index");
5241 conf_init_ident (&conf_data[CNF_TAPETYPE] , "DEFAULT_TAPE");
5242 conf_init_identlist(&conf_data[CNF_HOLDINGDISK] , NULL);
5243 conf_init_int (&conf_data[CNF_DUMPCYCLE] , CONF_UNIT_NONE, 10);
5244 conf_init_int (&conf_data[CNF_RUNSPERCYCLE] , CONF_UNIT_NONE, 0);
5245 conf_init_int (&conf_data[CNF_TAPECYCLE] , CONF_UNIT_NONE, 15);
5246 conf_init_int (&conf_data[CNF_NETUSAGE] , CONF_UNIT_K , 80000);
5247 conf_init_int (&conf_data[CNF_INPARALLEL] , CONF_UNIT_NONE, 10);
5248 conf_init_str (&conf_data[CNF_DUMPORDER] , "ttt");
5249 conf_init_int (&conf_data[CNF_BUMPPERCENT] , CONF_UNIT_NONE, 0);
5250 conf_init_int64 (&conf_data[CNF_BUMPSIZE] , CONF_UNIT_K , (gint64)10*1024);
5251 conf_init_real (&conf_data[CNF_BUMPMULT] , 1.5);
5252 conf_init_int (&conf_data[CNF_BUMPDAYS] , CONF_UNIT_NONE, 2);
5253 conf_init_str (&conf_data[CNF_TPCHANGER] , "");
5254 conf_init_int (&conf_data[CNF_RUNTAPES] , CONF_UNIT_NONE, 1);
5255 conf_init_int (&conf_data[CNF_MAXDUMPS] , CONF_UNIT_NONE, 1);
5256 conf_init_int (&conf_data[CNF_MAX_DLE_BY_VOLUME] , CONF_UNIT_NONE, 1000000000);
5257 conf_init_int (&conf_data[CNF_ETIMEOUT] , CONF_UNIT_NONE, 300);
5258 conf_init_int (&conf_data[CNF_DTIMEOUT] , CONF_UNIT_NONE, 1800);
5259 conf_init_int (&conf_data[CNF_CTIMEOUT] , CONF_UNIT_NONE, 30);
5260 conf_init_size (&conf_data[CNF_DEVICE_OUTPUT_BUFFER_SIZE], CONF_UNIT_NONE, 40*32768);
5261 conf_init_str (&conf_data[CNF_PRINTER] , "");
5262 conf_init_str (&conf_data[CNF_MAILER] , DEFAULT_MAILER);
5263 conf_init_no_yes_all(&conf_data[CNF_AUTOFLUSH] , 0);
5264 conf_init_int (&conf_data[CNF_RESERVE] , CONF_UNIT_NONE, 100);
5265 conf_init_int64 (&conf_data[CNF_MAXDUMPSIZE] , CONF_UNIT_K , (gint64)-1);
5266 conf_init_str (&conf_data[CNF_COLUMNSPEC] , "");
5267 conf_init_bool (&conf_data[CNF_AMRECOVER_DO_FSF] , 1);
5268 conf_init_str (&conf_data[CNF_AMRECOVER_CHANGER] , "");
5269 conf_init_bool (&conf_data[CNF_AMRECOVER_CHECK_LABEL], 1);
5270 conf_init_taperalgo(&conf_data[CNF_TAPERALGO] , 0);
5271 conf_init_int (&conf_data[CNF_TAPER_PARALLEL_WRITE] , CONF_UNIT_NONE, 1);
5272 conf_init_int (&conf_data[CNF_FLUSH_THRESHOLD_DUMPED] , CONF_UNIT_NONE, 0);
5273 conf_init_int (&conf_data[CNF_FLUSH_THRESHOLD_SCHEDULED], CONF_UNIT_NONE, 0);
5274 conf_init_int (&conf_data[CNF_TAPERFLUSH] , CONF_UNIT_NONE, 0);
5275 conf_init_str (&conf_data[CNF_DISPLAYUNIT] , "k");
5276 conf_init_str (&conf_data[CNF_KRB5KEYTAB] , "/.amanda-v5-keytab");
5277 conf_init_str (&conf_data[CNF_KRB5PRINCIPAL] , "service/amanda");
5278 conf_init_str (&conf_data[CNF_LABEL_NEW_TAPES] , "");
5279 conf_init_bool (&conf_data[CNF_EJECT_VOLUME] , 0);
5280 conf_init_bool (&conf_data[CNF_REPORT_USE_MEDIA] , TRUE);
5281 conf_init_bool (&conf_data[CNF_REPORT_NEXT_MEDIA] , TRUE);
5282 conf_init_str (&conf_data[CNF_TMPDIR] , "");
5283 conf_init_bool (&conf_data[CNF_USETIMESTAMPS] , 1);
5284 conf_init_int (&conf_data[CNF_CONNECT_TRIES] , CONF_UNIT_NONE, 3);
5285 conf_init_int (&conf_data[CNF_REP_TRIES] , CONF_UNIT_NONE, 5);
5286 conf_init_int (&conf_data[CNF_REQ_TRIES] , CONF_UNIT_NONE, 3);
5287 conf_init_int (&conf_data[CNF_DEBUG_DAYS] , CONF_UNIT_NONE, AMANDA_DEBUG_DAYS);
5288 conf_init_int (&conf_data[CNF_DEBUG_AMANDAD] , CONF_UNIT_NONE, 0);
5289 conf_init_int (&conf_data[CNF_DEBUG_RECOVERY] , CONF_UNIT_NONE, 1);
5290 conf_init_int (&conf_data[CNF_DEBUG_AMIDXTAPED] , CONF_UNIT_NONE, 0);
5291 conf_init_int (&conf_data[CNF_DEBUG_AMINDEXD] , CONF_UNIT_NONE, 0);
5292 conf_init_int (&conf_data[CNF_DEBUG_AMRECOVER] , CONF_UNIT_NONE, 0);
5293 conf_init_int (&conf_data[CNF_DEBUG_AUTH] , CONF_UNIT_NONE, 0);
5294 conf_init_int (&conf_data[CNF_DEBUG_EVENT] , CONF_UNIT_NONE, 0);
5295 conf_init_int (&conf_data[CNF_DEBUG_HOLDING] , CONF_UNIT_NONE, 0);
5296 conf_init_int (&conf_data[CNF_DEBUG_PROTOCOL] , CONF_UNIT_NONE, 0);
5297 conf_init_int (&conf_data[CNF_DEBUG_PLANNER] , CONF_UNIT_NONE, 0);
5298 conf_init_int (&conf_data[CNF_DEBUG_DRIVER] , CONF_UNIT_NONE, 0);
5299 conf_init_int (&conf_data[CNF_DEBUG_DUMPER] , CONF_UNIT_NONE, 0);
5300 conf_init_int (&conf_data[CNF_DEBUG_CHUNKER] , CONF_UNIT_NONE, 0);
5301 conf_init_int (&conf_data[CNF_DEBUG_TAPER] , CONF_UNIT_NONE, 0);
5302 conf_init_int (&conf_data[CNF_DEBUG_SELFCHECK] , CONF_UNIT_NONE, 0);
5303 conf_init_int (&conf_data[CNF_DEBUG_SENDSIZE] , CONF_UNIT_NONE, 0);
5304 conf_init_int (&conf_data[CNF_DEBUG_SENDBACKUP] , CONF_UNIT_NONE, 0);
5306 conf_init_intrange (&conf_data[CNF_RESERVED_UDP_PORT] , UDPPORTRANGE);
5308 conf_init_intrange (&conf_data[CNF_RESERVED_UDP_PORT] , 512, IPPORT_RESERVED-1);
5310 #ifdef LOW_TCPPORTRANGE
5311 conf_init_intrange (&conf_data[CNF_RESERVED_TCP_PORT] , LOW_TCPPORTRANGE);
5313 conf_init_intrange (&conf_data[CNF_RESERVED_TCP_PORT] , 512, IPPORT_RESERVED-1);
5316 conf_init_intrange (&conf_data[CNF_UNRESERVED_TCP_PORT] , TCPPORTRANGE);
5318 conf_init_intrange (&conf_data[CNF_UNRESERVED_TCP_PORT] , IPPORT_RESERVED, 65535);
5320 conf_init_send_amreport (&conf_data[CNF_SEND_AMREPORT_ON], SEND_AMREPORT_ALL);
5321 conf_init_autolabel(&conf_data[CNF_AUTOLABEL]);
5322 conf_init_str(&conf_data[CNF_META_AUTOLABEL], NULL);
5323 conf_init_host_limit(&conf_data[CNF_RECOVERY_LIMIT]);
5324 conf_init_str(&conf_data[CNF_INTERACTIVITY], NULL);
5325 conf_init_str(&conf_data[CNF_TAPERSCAN], NULL);
5327 /* reset internal variables */
5328 config_clear_errors();
5329 cfgerr_level = CFGERR_OK;
5330 allow_overwrites = 0;
5333 /* create some predefined dumptypes for backwards compatability */
5334 init_dumptype_defaults();
5335 dpcur.name = stralloc("NO-COMPRESS");
5336 dpcur.seen.linenum = -1;
5337 free_val_t(&dpcur.value[DUMPTYPE_COMPRESS]);
5338 val_t__compress(&dpcur.value[DUMPTYPE_COMPRESS]) = COMP_NONE;
5339 val_t__seen(&dpcur.value[DUMPTYPE_COMPRESS]).linenum = -1;
5342 init_dumptype_defaults();
5343 dpcur.name = stralloc("COMPRESS-FAST");
5344 dpcur.seen.linenum = -1;
5345 free_val_t(&dpcur.value[DUMPTYPE_COMPRESS]);
5346 val_t__compress(&dpcur.value[DUMPTYPE_COMPRESS]) = COMP_FAST;
5347 val_t__seen(&dpcur.value[DUMPTYPE_COMPRESS]).linenum = -1;
5350 init_dumptype_defaults();
5351 dpcur.name = stralloc("COMPRESS-BEST");
5352 dpcur.seen.linenum = -1;
5353 free_val_t(&dpcur.value[DUMPTYPE_COMPRESS]);
5354 val_t__compress(&dpcur.value[DUMPTYPE_COMPRESS]) = COMP_BEST;
5355 val_t__seen(&dpcur.value[DUMPTYPE_COMPRESS]).linenum = -1;
5358 init_dumptype_defaults();
5359 dpcur.name = stralloc("COMPRESS-CUST");
5360 dpcur.seen.linenum = -1;
5361 free_val_t(&dpcur.value[DUMPTYPE_COMPRESS]);
5362 val_t__compress(&dpcur.value[DUMPTYPE_COMPRESS]) = COMP_CUST;
5363 val_t__seen(&dpcur.value[DUMPTYPE_COMPRESS]).linenum = -1;
5366 init_dumptype_defaults();
5367 dpcur.name = stralloc("SRVCOMPRESS");
5368 dpcur.seen.linenum = -1;
5369 free_val_t(&dpcur.value[DUMPTYPE_COMPRESS]);
5370 val_t__compress(&dpcur.value[DUMPTYPE_COMPRESS]) = COMP_SERVER_FAST;
5371 val_t__seen(&dpcur.value[DUMPTYPE_COMPRESS]).linenum = -1;
5374 init_dumptype_defaults();
5375 dpcur.name = stralloc("BSD-AUTH");
5376 dpcur.seen.linenum = -1;
5377 free_val_t(&dpcur.value[DUMPTYPE_AUTH]);
5378 val_t__str(&dpcur.value[DUMPTYPE_AUTH]) = stralloc("BSD");
5379 val_t__seen(&dpcur.value[DUMPTYPE_AUTH]).linenum = -1;
5382 init_dumptype_defaults();
5383 dpcur.name = stralloc("BSDTCP-AUTH");
5384 dpcur.seen.linenum = -1;
5385 free_val_t(&dpcur.value[DUMPTYPE_AUTH]);
5386 val_t__str(&dpcur.value[DUMPTYPE_AUTH]) = stralloc("BSDTCP");
5387 val_t__seen(&dpcur.value[DUMPTYPE_AUTH]).linenum = -1;
5390 init_dumptype_defaults();
5391 dpcur.name = stralloc("NO-RECORD");
5392 dpcur.seen.linenum = -1;
5393 free_val_t(&dpcur.value[DUMPTYPE_RECORD]);
5394 val_t__int(&dpcur.value[DUMPTYPE_RECORD]) = 0;
5395 val_t__seen(&dpcur.value[DUMPTYPE_RECORD]).linenum = -1;
5398 init_dumptype_defaults();
5399 dpcur.name = stralloc("NO-HOLD");
5400 dpcur.seen.linenum = -1;
5401 free_val_t(&dpcur.value[DUMPTYPE_HOLDINGDISK]);
5402 val_t__holding(&dpcur.value[DUMPTYPE_HOLDINGDISK]) = HOLD_NEVER;
5403 val_t__seen(&dpcur.value[DUMPTYPE_HOLDINGDISK]).linenum = -1;
5406 init_dumptype_defaults();
5407 dpcur.name = stralloc("NO-FULL");
5408 dpcur.seen.linenum = -1;
5409 free_val_t(&dpcur.value[DUMPTYPE_STRATEGY]);
5410 val_t__strategy(&dpcur.value[DUMPTYPE_STRATEGY]) = DS_NOFULL;
5411 val_t__seen(&dpcur.value[DUMPTYPE_STRATEGY]).linenum = -1;
5414 /* And we're initialized! */
5415 config_initialized = 1;
5422 char **config_options;
5423 char **config_option;
5424 int n_config_overrides = 0;
5427 if (config_overrides)
5428 n_config_overrides = config_overrides->n_used;
5430 config_options = alloc((first+n_config_overrides+1)*SIZEOF(char *));
5431 config_option = config_options + first;
5433 for (i = 0; i < n_config_overrides; i++) {
5434 char *key = config_overrides->ovr[i].key;
5435 char *value = config_overrides->ovr[i].value;
5436 *config_option = vstralloc("-o", key, "=", value, NULL);
5440 *config_option = NULL; /* add terminating sentinel */
5442 return config_options;
5446 update_derived_values(
5454 /* Add a 'default' interface if one doesn't already exist */
5455 if (!(ip = lookup_interface("default"))) {
5456 init_interface_defaults();
5457 ifcur.name = stralloc("default");
5458 ifcur.seen = val_t__seen(getconf(CNF_NETUSAGE));
5461 ip = lookup_interface("default");
5464 /* .. and set its maxusage from 'netusage' */
5465 if (!interface_seen(ip, INTER_MAXUSAGE)) {
5468 v = interface_getconf(ip, INTER_COMMENT);
5470 val_t__str(v) = stralloc(_("implicit from NETUSAGE"));
5471 val_t__seen(v) = val_t__seen(getconf(CNF_NETUSAGE));
5473 v = interface_getconf(ip, INTER_MAXUSAGE);
5475 val_t__int(v) = getconf_int(CNF_NETUSAGE);
5476 val_t__seen(v) = val_t__seen(getconf(CNF_NETUSAGE));
5479 /* Check the tapetype is defined */
5480 if (lookup_tapetype(getconf_str(CNF_TAPETYPE)) == NULL) {
5481 /* Create a default tapetype so that other code has
5482 * something to refer to, but don't pretend it's real */
5483 if (!getconf_seen(CNF_TAPETYPE) &&
5484 strcmp(getconf_str(CNF_TAPETYPE), "DEFAULT_TAPE") == 0 &&
5485 !lookup_tapetype("DEFAULT_TAPE")) {
5486 init_tapetype_defaults();
5487 tpcur.name = stralloc("DEFAULT_TAPE");
5488 tpcur.seen = val_t__seen(getconf(CNF_TAPETYPE));
5491 conf_parserror(_("tapetype %s is not defined"),
5492 getconf_str(CNF_TAPETYPE));
5496 /* Check the holdingdisk are defined */
5497 for (il = getconf_identlist(CNF_HOLDINGDISK);
5498 il != NULL; il = il->next) {
5499 hd = lookup_holdingdisk(il->data);
5501 conf_parserror(_("holdingdisk %s is not defined"),
5506 if ((getconf_seen(CNF_LABEL_NEW_TAPES) > 0 &&
5507 getconf_seen(CNF_AUTOLABEL) > 0) ||
5508 (getconf_seen(CNF_LABEL_NEW_TAPES) < 0 &&
5509 getconf_seen(CNF_AUTOLABEL) < 0)) {
5510 conf_parserror(_("Can't specify both label-new-tapes and autolabel"));
5512 if ((getconf_seen(CNF_LABEL_NEW_TAPES) != 0 &&
5513 getconf_seen(CNF_AUTOLABEL) == 0) ||
5514 (getconf_seen(CNF_LABEL_NEW_TAPES) < 0 &&
5515 getconf_seen(CNF_AUTOLABEL) >= 0)) {
5516 autolabel_t *autolabel = &(conf_data[CNF_AUTOLABEL].v.autolabel);
5517 autolabel->template = g_strdup(getconf_str(CNF_LABEL_NEW_TAPES));
5518 if (!autolabel->template || autolabel->template == '\0') {
5519 autolabel->template = NULL;
5520 autolabel->autolabel = 0;
5522 autolabel->autolabel = AL_VOLUME_ERROR | AL_EMPTY;
5526 if (!getconf_seen(CNF_REPORT_USE_MEDIA) &&
5527 getconf_seen(CNF_MAX_DLE_BY_VOLUME)) {
5528 conf_init_bool(&conf_data[CNF_REPORT_USE_MEDIA], FALSE);
5530 if (!getconf_seen(CNF_REPORT_NEXT_MEDIA) &&
5531 getconf_seen(CNF_MAX_DLE_BY_VOLUME)) {
5532 conf_init_bool(&conf_data[CNF_REPORT_NEXT_MEDIA], FALSE);
5536 /* fill in the debug_* values */
5537 debug_amandad = getconf_int(CNF_DEBUG_AMANDAD);
5538 debug_recovery = getconf_int(CNF_DEBUG_RECOVERY);
5539 debug_amidxtaped = getconf_int(CNF_DEBUG_AMIDXTAPED);
5540 debug_amindexd = getconf_int(CNF_DEBUG_AMINDEXD);
5541 debug_amrecover = getconf_int(CNF_DEBUG_AMRECOVER);
5542 debug_auth = getconf_int(CNF_DEBUG_AUTH);
5543 debug_event = getconf_int(CNF_DEBUG_EVENT);
5544 debug_holding = getconf_int(CNF_DEBUG_HOLDING);
5545 debug_protocol = getconf_int(CNF_DEBUG_PROTOCOL);
5546 debug_planner = getconf_int(CNF_DEBUG_PLANNER);
5547 debug_driver = getconf_int(CNF_DEBUG_DRIVER);
5548 debug_dumper = getconf_int(CNF_DEBUG_DUMPER);
5549 debug_chunker = getconf_int(CNF_DEBUG_CHUNKER);
5550 debug_taper = getconf_int(CNF_DEBUG_TAPER);
5551 debug_selfcheck = getconf_int(CNF_DEBUG_SELFCHECK);
5552 debug_sendsize = getconf_int(CNF_DEBUG_SENDSIZE);
5553 debug_sendbackup = getconf_int(CNF_DEBUG_SENDBACKUP);
5555 /* And finally, display unit */
5556 switch (getconf_str(CNF_DISPLAYUNIT)[0]) {
5564 unit_divisor = 1024;
5569 unit_divisor = 1024*1024;
5574 unit_divisor = 1024*1024*1024;
5578 error(_("Invalid displayunit missed by validate_displayunit"));
5589 val->seen.linenum = 0;
5590 val->seen.filename = NULL;
5591 val->seen.block = NULL;
5592 val->type = CONFTYPE_INT;
5594 val_t__int(val) = i;
5603 val->seen.linenum = 0;
5604 val->seen.filename = NULL;
5605 val->seen.block = NULL;
5606 val->type = CONFTYPE_INT64;
5608 val_t__int64(val) = l;
5616 val->seen.linenum = 0;
5617 val->seen.filename = NULL;
5618 val->seen.block = NULL;
5619 val->type = CONFTYPE_REAL;
5620 val->unit = CONF_UNIT_NONE;
5621 val_t__real(val) = r;
5629 val->seen.linenum = 0;
5630 val->seen.filename = NULL;
5631 val->seen.block = NULL;
5632 val->type = CONFTYPE_STR;
5633 val->unit = CONF_UNIT_NONE;
5635 val->v.s = stralloc(s);
5645 val->seen.linenum = 0;
5646 val->seen.filename = NULL;
5647 val->seen.block = NULL;
5648 val->type = CONFTYPE_IDENT;
5649 val->unit = CONF_UNIT_NONE;
5651 val->v.s = stralloc(s);
5657 conf_init_identlist(
5661 val->seen.linenum = 0;
5662 val->seen.filename = NULL;
5663 val->seen.block = NULL;
5664 val->type = CONFTYPE_IDENTLIST;
5665 val->unit = CONF_UNIT_NONE;
5666 val->v.identlist = NULL;
5668 val->v.identlist = g_slist_append(val->v.identlist, stralloc(s));
5676 val->seen.linenum = 0;
5677 val->seen.filename = NULL;
5678 val->seen.block = NULL;
5679 val->type = CONFTYPE_TIME;
5680 val->unit = CONF_UNIT_NONE;
5681 val_t__time(val) = t;
5690 val->seen.linenum = 0;
5691 val->seen.filename = NULL;
5692 val->seen.block = NULL;
5693 val->type = CONFTYPE_SIZE;
5695 val_t__size(val) = sz;
5703 val->seen.linenum = 0;
5704 val->seen.filename = NULL;
5705 val->seen.block = NULL;
5706 val->type = CONFTYPE_BOOLEAN;
5707 val->unit = CONF_UNIT_NONE;
5708 val_t__boolean(val) = i;
5712 conf_init_no_yes_all(
5716 val->seen.linenum = 0;
5717 val->seen.filename = NULL;
5718 val->seen.block = NULL;
5719 val->type = CONFTYPE_NO_YES_ALL;
5720 val->unit = CONF_UNIT_NONE;
5721 val_t__int(val) = i;
5729 val->seen.linenum = 0;
5730 val->seen.filename = NULL;
5731 val->seen.block = NULL;
5732 val->type = CONFTYPE_COMPRESS;
5733 val->unit = CONF_UNIT_NONE;
5734 val_t__compress(val) = (int)i;
5742 val->seen.linenum = 0;
5743 val->seen.filename = NULL;
5744 val->seen.block = NULL;
5745 val->type = CONFTYPE_ENCRYPT;
5746 val->unit = CONF_UNIT_NONE;
5747 val_t__encrypt(val) = (int)i;
5751 conf_init_part_cache_type(
5753 part_cache_type_t i)
5755 val->seen.linenum = 0;
5756 val->seen.filename = NULL;
5757 val->seen.block = NULL;
5758 val->type = CONFTYPE_PART_CACHE_TYPE;
5759 val->unit = CONF_UNIT_NONE;
5760 val_t__part_cache_type(val) = (int)i;
5764 conf_init_host_limit(
5767 val->seen.linenum = 0;
5768 val->seen.filename = NULL;
5769 val->seen.block = NULL;
5770 val->type = CONFTYPE_HOST_LIMIT;
5771 val->unit = CONF_UNIT_NONE;
5772 val_t__host_limit(val).match_pats = NULL;
5773 val_t__host_limit(val).same_host = FALSE;
5774 val_t__host_limit(val).server = FALSE;
5778 conf_init_host_limit_server(
5781 conf_init_host_limit(val);
5782 val_t__host_limit(val).server = TRUE;
5786 conf_init_data_path(
5790 val->seen.linenum = 0;
5791 val->seen.filename = NULL;
5792 val->seen.block = NULL;
5793 val->type = CONFTYPE_DATA_PATH;
5794 val->unit = CONF_UNIT_NONE;
5795 val_t__data_path(val) = (int)i;
5801 dump_holdingdisk_t i)
5803 val->seen.linenum = 0;
5804 val->seen.filename = NULL;
5805 val->seen.block = NULL;
5806 val->type = CONFTYPE_HOLDING;
5807 val->unit = CONF_UNIT_NONE;
5808 val_t__holding(val) = (int)i;
5812 conf_init_estimatelist(
5816 GSList *estimates = NULL;
5817 val->seen.linenum = 0;
5818 val->seen.filename = NULL;
5819 val->seen.block = NULL;
5820 val->type = CONFTYPE_ESTIMATELIST;
5821 val->unit = CONF_UNIT_NONE;
5822 estimates = g_slist_append(estimates, GINT_TO_POINTER(i));
5823 val_t__estimatelist(val) = estimates;
5831 val->seen.linenum = 0;
5832 val->seen.filename = NULL;
5833 val->seen.block = NULL;
5834 val->unit = CONF_UNIT_NONE;
5835 val->type = CONFTYPE_STRATEGY;
5836 val_t__strategy(val) = i;
5840 conf_init_taperalgo(
5844 val->seen.linenum = 0;
5845 val->seen.filename = NULL;
5846 val->seen.block = NULL;
5847 val->type = CONFTYPE_TAPERALGO;
5848 val->unit = CONF_UNIT_NONE;
5849 val_t__taperalgo(val) = i;
5857 val->seen.linenum = 0;
5858 val->seen.filename = NULL;
5859 val->seen.block = NULL;
5860 val->type = CONFTYPE_PRIORITY;
5861 val->unit = CONF_UNIT_NONE;
5862 val_t__priority(val) = i;
5871 val->seen.linenum = 0;
5872 val->seen.filename = NULL;
5873 val->seen.block = NULL;
5874 val->type = CONFTYPE_RATE;
5875 val->unit = CONF_UNIT_NONE;
5876 val_t__rate(val)[0] = r1;
5877 val_t__rate(val)[1] = r2;
5881 conf_init_exinclude(
5884 val->seen.linenum = 0;
5885 val->seen.filename = NULL;
5886 val->seen.block = NULL;
5887 val->type = CONFTYPE_EXINCLUDE;
5888 val->unit = CONF_UNIT_NONE;
5889 val_t__exinclude(val).optional = 0;
5890 val_t__exinclude(val).sl_list = NULL;
5891 val_t__exinclude(val).sl_file = NULL;
5900 val->seen.linenum = 0;
5901 val->seen.filename = NULL;
5902 val->seen.block = NULL;
5903 val->type = CONFTYPE_INTRANGE;
5904 val->unit = CONF_UNIT_NONE;
5905 val_t__intrange(val)[0] = i1;
5906 val_t__intrange(val)[1] = i2;
5910 conf_init_autolabel(
5912 val->seen.linenum = 0;
5913 val->seen.filename = NULL;
5914 val->seen.block = NULL;
5915 val->type = CONFTYPE_AUTOLABEL;
5916 val->unit = CONF_UNIT_NONE;
5917 val->v.autolabel.template = NULL;
5918 val->v.autolabel.autolabel = 0;
5925 property_t *propery = (property_t *)p;
5926 slist_free_full(propery->values, g_free);
5934 val->seen.linenum = 0;
5935 val->seen.filename = NULL;
5936 val->seen.block = NULL;
5937 val->type = CONFTYPE_PROPLIST;
5938 val->unit = CONF_UNIT_NONE;
5939 val_t__proplist(val) =
5940 g_hash_table_new_full(g_str_amanda_hash, g_str_amanda_equal,
5941 &g_free, &free_property_t);
5945 conf_init_execute_on(
5949 val->seen.linenum = 0;
5950 val->seen.filename = NULL;
5951 val->seen.block = NULL;
5952 val->type = CONFTYPE_EXECUTE_ON;
5953 val->unit = CONF_UNIT_NONE;
5958 conf_init_execute_where(
5962 val->seen.linenum = 0;
5963 val->seen.filename = NULL;
5964 val->seen.block = NULL;
5965 val->type = CONFTYPE_EXECUTE_WHERE;
5966 val->unit = CONF_UNIT_NONE;
5971 conf_init_send_amreport(
5975 val->seen.linenum = 0;
5976 val->seen.filename = NULL;
5977 val->seen.block = NULL;
5978 val->type = CONFTYPE_SEND_AMREPORT_ON;
5979 val->unit = CONF_UNIT_NONE;
5983 static void conf_init_application(val_t *val) {
5984 val->seen.linenum = 0;
5985 val->seen.filename = NULL;
5986 val->seen.block = NULL;
5987 val->type = CONFTYPE_APPLICATION;
5988 val->unit = CONF_UNIT_NONE;
5994 * Config access implementation
5998 getconf(confparm_key key)
6000 assert(key < CNF_CNF);
6001 return &conf_data[key];
6015 device_config_t *dc;
6016 changer_config_t *cc;
6017 interactivity_t *iv;
6021 if (strcasecmp(listname,"tapetype") == 0) {
6022 for(tp = tapelist; tp != NULL; tp=tp->next) {
6023 rv = g_slist_append(rv, tp->name);
6025 } else if (strcasecmp(listname,"dumptype") == 0) {
6026 for(dp = dumplist; dp != NULL; dp=dp->next) {
6027 rv = g_slist_append(rv, dp->name);
6029 } else if (strcasecmp(listname,"holdingdisk") == 0) {
6030 for(hp = holdinglist; hp != NULL; hp=hp->next) {
6032 rv = g_slist_append(rv, hd->name);
6034 } else if (strcasecmp(listname,"interface") == 0) {
6035 for(ip = interface_list; ip != NULL; ip=ip->next) {
6036 rv = g_slist_append(rv, ip->name);
6038 } else if (strcasecmp(listname,"application_tool") == 0
6039 || strcasecmp(listname,"application-tool") == 0
6040 || strcasecmp(listname,"application") == 0) {
6041 for(ap = application_list; ap != NULL; ap=ap->next) {
6042 rv = g_slist_append(rv, ap->name);
6044 } else if (strcasecmp(listname,"script_tool") == 0
6045 || strcasecmp(listname,"script-tool") == 0
6046 || strcasecmp(listname,"script") == 0) {
6047 for(pp = pp_script_list; pp != NULL; pp=pp->next) {
6048 rv = g_slist_append(rv, pp->name);
6050 } else if (strcasecmp(listname,"device") == 0) {
6051 for(dc = device_config_list; dc != NULL; dc=dc->next) {
6052 rv = g_slist_append(rv, dc->name);
6054 } else if (strcasecmp(listname,"changer") == 0) {
6055 for(cc = changer_config_list; cc != NULL; cc=cc->next) {
6056 rv = g_slist_append(rv, cc->name);
6058 } else if (strcasecmp(listname,"interactivity") == 0) {
6059 for(iv = interactivity_list; iv != NULL; iv=iv->next) {
6060 rv = g_slist_append(rv, iv->name);
6062 } else if (strcasecmp(listname,"taperscan") == 0) {
6063 for(ts = taperscan_list; ts != NULL; ts=ts->next) {
6064 rv = g_slist_append(rv, ts->name);
6076 if (!parm_key_info(key, NULL, &rv))
6088 for(p = tapelist; p != NULL; p = p->next) {
6089 if(strcasecmp(p->name, str) == 0) return p;
6099 assert(ttyp != NULL);
6100 assert(key < TAPETYPE_TAPETYPE);
6101 return &ttyp->value[key];
6106 conf_var_t *np G_GNUC_UNUSED,
6109 if (strcmp(val->v.s, "DUMP") != 0 &&
6110 strcmp(val->v.s, "GNUTAR") != 0 &&
6111 strcmp(val->v.s, "STAR") != 0 &&
6112 strcmp(val->v.s, "APPLICATION") != 0)
6113 conf_parserror("program must be \"DUMP\", \"GNUTAR\", \"STAR\" or \"APPLICATION\"");
6117 validate_dump_limit(
6118 conf_var_t *np G_GNUC_UNUSED,
6121 if (val->v.host_limit.match_pats) {
6122 conf_parserror("dump-limit can't specify hostname");
6130 assert(ttyp != NULL);
6140 for(p = dumplist; p != NULL; p = p->next) {
6141 if(strcasecmp(p->name, str) == 0) return p;
6151 assert(dtyp != NULL);
6152 assert(key < DUMPTYPE_DUMPTYPE);
6153 return &dtyp->value[key];
6160 assert(dtyp != NULL);
6170 for(p = interface_list; p != NULL; p = p->next) {
6171 if(strcasecmp(p->name, str) == 0) return p;
6181 assert(iface != NULL);
6182 assert(key < INTER_INTER);
6183 return &iface->value[key];
6190 assert(iface != NULL);
6201 for (hp = holdinglist; hp != NULL; hp = hp->next) {
6203 if (strcasecmp(hd->name, str) == 0) return hd;
6209 getconf_holdingdisks(
6216 holdingdisk_getconf(
6217 holdingdisk_t *hdisk,
6218 holdingdisk_key key)
6220 assert(hdisk != NULL);
6221 assert(key < HOLDING_HOLDING);
6222 return &hdisk->value[key];
6227 holdingdisk_t *hdisk)
6229 assert(hdisk != NULL);
6239 for(p = application_list; p != NULL; p = p->next) {
6240 if(strcasecmp(p->name, str) == 0) return p;
6246 application_getconf(
6248 application_key key)
6251 assert(key < APPLICATION_APPLICATION);
6252 return &ap->value[key];
6264 lookup_interactivity(
6269 for(p = interactivity_list; p != NULL; p = p->next) {
6270 if(strcasecmp(p->name, str) == 0) return p;
6276 interactivity_getconf(
6277 interactivity_t *iv,
6278 interactivity_key key)
6281 assert(key < INTERACTIVITY_INTERACTIVITY);
6282 return &iv->value[key];
6287 interactivity_t *iv)
6299 for(p = taperscan_list; p != NULL; p = p->next) {
6300 if(strcasecmp(p->name, str) == 0) return p;
6311 assert(key < TAPERSCAN_TAPERSCAN);
6312 return &ts->value[key];
6329 for(pps = pp_script_list; pps != NULL; pps = pps->next) {
6330 if(strcasecmp(pps->name, str) == 0) return pps;
6340 assert(pps != NULL);
6341 assert(key < PP_SCRIPT_PP_SCRIPT);
6342 return &pps->value[key];
6349 assert(pps != NULL);
6354 lookup_device_config(
6357 device_config_t *devconf;
6359 for(devconf = device_config_list; devconf != NULL; devconf = devconf->next) {
6360 if(strcasecmp(devconf->name, str) == 0) return devconf;
6366 device_config_getconf(
6367 device_config_t *devconf,
6368 device_config_key key)
6370 assert(devconf != NULL);
6371 assert(key < DEVICE_CONFIG_DEVICE_CONFIG);
6372 return &devconf->value[key];
6377 device_config_t *devconf)
6379 assert(devconf != NULL);
6380 return devconf->name;
6384 lookup_changer_config(
6387 changer_config_t *devconf;
6389 for(devconf = changer_config_list; devconf != NULL; devconf = devconf->next) {
6390 if(strcasecmp(devconf->name, str) == 0) return devconf;
6396 changer_config_getconf(
6397 changer_config_t *devconf,
6398 changer_config_key key)
6400 assert(devconf != NULL);
6401 assert(key < CHANGER_CONFIG_CHANGER_CONFIG);
6402 return &devconf->value[key];
6406 changer_config_name(
6407 changer_config_t *devconf)
6409 assert(devconf != NULL);
6410 return devconf->name;
6414 getconf_unit_divisor(void)
6416 return unit_divisor;
6420 * Command-line Handling Implementation
6423 config_overrides_t *
6424 new_config_overrides(
6427 config_overrides_t *co;
6429 if (size_estimate <= 0)
6432 co = alloc(sizeof(*co));
6433 co->ovr = alloc(sizeof(*co->ovr) * size_estimate);
6434 co->n_allocated = size_estimate;
6441 free_config_overrides(
6442 config_overrides_t *co)
6447 for (i = 0; i < co->n_used; i++) {
6448 amfree(co->ovr[i].key);
6449 amfree(co->ovr[i].value);
6455 void add_config_override(
6456 config_overrides_t *co,
6460 /* reallocate if necessary */
6461 if (co->n_used == co->n_allocated) {
6462 co->n_allocated *= 2;
6463 co->ovr = realloc(co->ovr, co->n_allocated * sizeof(*co->ovr));
6465 error(_("Cannot realloc; out of memory"));
6470 co->ovr[co->n_used].key = stralloc(key);
6471 co->ovr[co->n_used].value = stralloc(value);
6476 add_config_override_opt(
6477 config_overrides_t *co,
6481 assert(optarg != NULL);
6483 value = strchr(optarg, '=');
6484 if (value == NULL) {
6485 error(_("Must specify a value for %s."), optarg);
6490 add_config_override(co, optarg, value+1);
6494 config_overrides_t *
6495 extract_commandline_config_overrides(
6500 config_overrides_t *co = new_config_overrides(*argc/2);
6504 if(strncmp((*argv)[i],"-o",2) == 0) {
6505 if(strlen((*argv)[i]) > 2) {
6506 add_config_override_opt(co, (*argv)[i]+2);
6510 if (i+1 >= *argc) error(_("expect something after -o"));
6511 add_config_override_opt(co, (*argv)[i+1]);
6515 /* move up remaining argment array */
6516 for (j = i; j+moveup<*argc; j++) {
6517 (*argv)[j] = (*argv)[j+moveup];
6529 set_config_overrides(
6530 config_overrides_t *co)
6534 config_overrides = co;
6536 for (i = 0; i < co->n_used; i++) {
6537 g_debug("config_overrides: %s %s", co->ovr[i].key, co->ovr[i].value);
6543 static cfgerr_level_t
6544 apply_config_overrides(
6545 config_overrides_t *co,
6550 if(!co) return cfgerr_level;
6551 assert(keytable != NULL);
6552 assert(parsetable != NULL);
6554 for (i = 0; i < co->n_used; i++) {
6555 char *key = co->ovr[i].key;
6556 char *value = co->ovr[i].value;
6558 conf_var_t *key_parm;
6560 if (key_ovr && strncasecmp(key_ovr, key, strlen(key_ovr)) != 0) {
6564 if (!parm_key_info(key, &key_parm, &key_val)) {
6565 /* not an error, only default config is loaded */
6569 /* now set up a fake line and use the relevant read_function to
6570 * parse it. This is sneaky! */
6571 if (key_parm->type == CONFTYPE_STR) {
6572 current_line = quote_string_always(value);
6574 current_line = stralloc(value);
6577 current_char = current_line;
6579 current_line_num = -2;
6580 allow_overwrites = 1;
6581 co->ovr[i].applied = TRUE;
6583 key_parm->read_function(key_parm, key_val);
6584 if ((key_parm)->validate_function)
6585 key_parm->validate_function(key_parm, key_val);
6587 amfree(current_line);
6588 current_char = NULL;
6591 return cfgerr_level;
6595 * val_t Management Implementation
6602 assert(config_initialized);
6603 if (val->type != CONFTYPE_INT) {
6604 error(_("val_t_to_int: val.type is not CONFTYPE_INT"));
6607 return val_t__int(val);
6614 assert(config_initialized);
6615 if (val->type != CONFTYPE_INT64) {
6616 error(_("val_t_to_int64: val.type is not CONFTYPE_INT64"));
6619 return val_t__int64(val);
6626 assert(config_initialized);
6627 if (val->type != CONFTYPE_REAL) {
6628 error(_("val_t_to_real: val.type is not CONFTYPE_REAL"));
6631 return val_t__real(val);
6638 assert(config_initialized);
6639 /* support CONFTYPE_IDENT, too */
6640 if (val->type != CONFTYPE_STR && val->type != CONFTYPE_IDENT) {
6641 error(_("val_t_to_str: val.type is not CONFTYPE_STR nor CONFTYPE_IDENT"));
6644 return val_t__str(val);
6651 assert(config_initialized);
6652 /* support CONFTYPE_STR, too */
6653 if (val->type != CONFTYPE_STR && val->type != CONFTYPE_IDENT) {
6654 error(_("val_t_to_ident: val.type is not CONFTYPE_IDENT nor CONFTYPE_STR"));
6657 return val_t__str(val);
6664 assert(config_initialized);
6665 if (val->type != CONFTYPE_IDENTLIST) {
6666 error(_("val_t_to_ident: val.type is not CONFTYPE_IDENTLIST"));
6669 return val_t__identlist(val);
6676 assert(config_initialized);
6677 if (val->type != CONFTYPE_TIME) {
6678 error(_("val_t_to_time: val.type is not CONFTYPE_TIME"));
6681 return val_t__time(val);
6688 assert(config_initialized);
6689 if (val->type != CONFTYPE_SIZE) {
6690 error(_("val_t_to_size: val.type is not CONFTYPE_SIZE"));
6693 return val_t__size(val);
6700 assert(config_initialized);
6701 if (val->type != CONFTYPE_BOOLEAN) {
6702 error(_("val_t_to_bool: val.type is not CONFTYPE_BOOLEAN"));
6705 return val_t__boolean(val);
6709 val_t_to_no_yes_all(
6712 assert(config_initialized);
6713 if (val->type != CONFTYPE_NO_YES_ALL) {
6714 error(_("val_t_to_no_yes_all: val.type is not CONFTYPE_NO_YES_ALL"));
6717 return val_t__no_yes_all(val);
6724 assert(config_initialized);
6725 if (val->type != CONFTYPE_COMPRESS) {
6726 error(_("val_t_to_compress: val.type is not CONFTYPE_COMPRESS"));
6729 return val_t__compress(val);
6736 assert(config_initialized);
6737 if (val->type != CONFTYPE_ENCRYPT) {
6738 error(_("val_t_to_encrypt: val.type is not CONFTYPE_ENCRYPT"));
6741 return val_t__encrypt(val);
6745 val_t_to_part_cache_type(
6748 assert(config_initialized);
6749 if (val->type != CONFTYPE_PART_CACHE_TYPE) {
6750 error(_("val_t_to_part_cache_type: val.type is not CONFTYPE_PART_CACHE_TYPE"));
6753 return val_t__part_cache_type(val);
6757 val_t_to_host_limit(
6760 assert(config_initialized);
6761 if (val->type != CONFTYPE_HOST_LIMIT) {
6762 error(_("val_t_to_host_limit: val.type is not CONFTYPE_HOST_LIMIT"));
6765 return &val_t__host_limit(val);
6772 assert(config_initialized);
6773 if (val->type != CONFTYPE_HOLDING) {
6774 error(_("val_t_to_hold: val.type is not CONFTYPE_HOLDING"));
6777 return val_t__holding(val);
6781 val_t_to_estimatelist(
6784 assert(config_initialized);
6785 if (val->type != CONFTYPE_ESTIMATELIST) {
6786 error(_("val_t_to_estimatelist: val.type is not CONFTYPE_ESTIMATELIST"));
6789 return val_t__estimatelist(val);
6796 assert(config_initialized);
6797 if (val->type != CONFTYPE_STRATEGY) {
6798 error(_("val_t_to_strategy: val.type is not CONFTYPE_STRATEGY"));
6801 return val_t__strategy(val);
6808 assert(config_initialized);
6809 if (val->type != CONFTYPE_TAPERALGO) {
6810 error(_("val_t_to_taperalgo: val.type is not CONFTYPE_TAPERALGO"));
6813 return val_t__taperalgo(val);
6817 val_t_to_send_amreport(
6820 assert(config_initialized);
6821 if (val->type != CONFTYPE_SEND_AMREPORT_ON) {
6822 error(_("val_t_to_send_amreport: val.type is not CONFTYPE_SEND_AMREPORT_ON"));
6825 return val_t__send_amreport(val);
6832 assert(config_initialized);
6833 if (val->type != CONFTYPE_DATA_PATH) {
6834 error(_("val_t_to_data_path: val.type is not CONFTYPE_DATA_PATH"));
6837 return val_t__data_path(val);
6844 assert(config_initialized);
6845 if (val->type != CONFTYPE_PRIORITY) {
6846 error(_("val_t_to_priority: val.type is not CONFTYPE_PRIORITY"));
6849 return val_t__priority(val);
6856 assert(config_initialized);
6857 if (val->type != CONFTYPE_RATE) {
6858 error(_("val_t_to_rate: val.type is not CONFTYPE_RATE"));
6861 return val_t__rate(val);
6868 assert(config_initialized);
6869 if (val->type != CONFTYPE_EXINCLUDE) {
6870 error(_("val_t_to_exinclude: val.type is not CONFTYPE_EXINCLUDE"));
6873 return val_t__exinclude(val);
6881 assert(config_initialized);
6882 if (val->type != CONFTYPE_INTRANGE) {
6883 error(_("val_t_to_intrange: val.type is not CONFTYPE_INTRANGE"));
6886 return val_t__intrange(val);
6893 assert(config_initialized);
6894 if (val->type != CONFTYPE_PROPLIST) {
6895 error(_("val_t_to_proplist: val.type is not CONFTYPE_PROPLIST"));
6898 return val_t__proplist(val);
6905 assert(config_initialized);
6906 if (val->type != CONFTYPE_AUTOLABEL) {
6907 error(_("val_t_to_autolabel: val.type is not CONFTYPE_AUTOLABEL"));
6910 return val_t__autolabel(val);
6918 if (valsrc->type == CONFTYPE_PROPLIST) {
6919 if (valsrc->v.proplist) {
6920 if (valdst->v.proplist == NULL ||
6921 g_hash_table_size(valdst->v.proplist) == 0) {
6922 valdst->seen.block = current_block;
6923 valdst->seen.filename = current_filename;
6924 valdst->seen.linenum = current_line_num;
6926 if (valdst->v.proplist == NULL) {
6927 valdst->v.proplist = g_hash_table_new_full(g_str_amanda_hash,
6931 g_hash_table_foreach(valsrc->v.proplist,
6932 ©_proplist_foreach_fn,
6933 valdst->v.proplist);
6935 g_hash_table_foreach(valsrc->v.proplist,
6936 &merge_proplist_foreach_fn,
6937 valdst->v.proplist);
6940 } else if (valsrc->type == CONFTYPE_IDENTLIST) {
6941 if (valsrc->v.identlist) {
6943 for (il = valsrc->v.identlist; il != NULL; il = il->next) {
6944 valdst->v.identlist = g_slist_append(valdst->v.identlist,
6945 stralloc((char *)il->data));
6950 copy_val_t(valdst, valsrc);
6961 if(valsrc->seen.linenum) {
6962 valdst->type = valsrc->type;
6963 valdst->seen = valsrc->seen;
6964 switch(valsrc->type) {
6966 case CONFTYPE_BOOLEAN:
6967 case CONFTYPE_NO_YES_ALL:
6968 case CONFTYPE_COMPRESS:
6969 case CONFTYPE_ENCRYPT:
6970 case CONFTYPE_HOLDING:
6971 case CONFTYPE_EXECUTE_ON:
6972 case CONFTYPE_EXECUTE_WHERE:
6973 case CONFTYPE_SEND_AMREPORT_ON:
6974 case CONFTYPE_DATA_PATH:
6975 case CONFTYPE_STRATEGY:
6976 case CONFTYPE_TAPERALGO:
6977 case CONFTYPE_PRIORITY:
6978 case CONFTYPE_PART_CACHE_TYPE:
6979 valdst->v.i = valsrc->v.i;
6983 valdst->v.size = valsrc->v.size;
6986 case CONFTYPE_INT64:
6987 valdst->v.int64 = valsrc->v.int64;
6991 valdst->v.r = valsrc->v.r;
6995 valdst->v.rate[0] = valsrc->v.rate[0];
6996 valdst->v.rate[1] = valsrc->v.rate[1];
6999 case CONFTYPE_IDENT:
7001 valdst->v.s = stralloc(valsrc->v.s);
7004 case CONFTYPE_IDENTLIST:
7005 valdst->v.identlist = NULL;
7006 for (ia = valsrc->v.identlist; ia != NULL; ia = ia->next) {
7007 valdst->v.identlist = g_slist_append(valdst->v.identlist,
7008 stralloc(ia->data));
7012 case CONFTYPE_HOST_LIMIT:
7013 valdst->v.host_limit = valsrc->v.host_limit;
7014 valdst->v.host_limit.match_pats = NULL;
7015 for (ia = valsrc->v.host_limit.match_pats; ia != NULL; ia = ia->next) {
7016 valdst->v.host_limit.match_pats =
7017 g_slist_append(valdst->v.host_limit.match_pats, g_strdup(ia->data));
7022 valdst->v.t = valsrc->v.t;
7025 case CONFTYPE_ESTIMATELIST: {
7026 estimatelist_t estimates = valsrc->v.estimatelist;
7027 estimatelist_t dst_estimates = NULL;
7028 while (estimates != NULL) {
7029 dst_estimates = g_slist_append(dst_estimates, estimates->data);
7030 estimates = estimates->next;
7032 valdst->v.estimatelist = dst_estimates;
7036 case CONFTYPE_EXINCLUDE:
7037 valdst->v.exinclude.optional = valsrc->v.exinclude.optional;
7038 valdst->v.exinclude.sl_list = duplicate_sl(valsrc->v.exinclude.sl_list);
7039 valdst->v.exinclude.sl_file = duplicate_sl(valsrc->v.exinclude.sl_file);
7042 case CONFTYPE_INTRANGE:
7043 valdst->v.intrange[0] = valsrc->v.intrange[0];
7044 valdst->v.intrange[1] = valsrc->v.intrange[1];
7047 case CONFTYPE_PROPLIST:
7048 if (valsrc->v.proplist) {
7049 valdst->v.proplist = g_hash_table_new_full(g_str_amanda_hash,
7054 g_hash_table_foreach(valsrc->v.proplist,
7055 ©_proplist_foreach_fn,
7056 valdst->v.proplist);
7058 valdst->v.proplist = NULL;
7062 case CONFTYPE_APPLICATION:
7063 valdst->v.s = stralloc(valsrc->v.s);
7066 case CONFTYPE_AUTOLABEL:
7067 valdst->v.autolabel.template = stralloc(valsrc->v.autolabel.template);
7068 valdst->v.autolabel.autolabel = valsrc->v.autolabel.autolabel;
7075 merge_proplist_foreach_fn(
7078 gpointer user_data_p)
7080 char *property_s = key_p;
7081 property_t *property = value_p;
7082 proplist_t proplist = user_data_p;
7083 GSList *elem = NULL;
7085 property_t *new_property = g_hash_table_lookup(proplist, property_s);
7086 if (new_property && !property->append) {
7087 g_hash_table_remove(proplist, property_s);
7088 new_property = NULL;
7090 if (!new_property) {
7091 new_property = malloc(sizeof(property_t));
7092 new_property->seen = property->seen;
7093 new_property->append = property->append;
7094 new_property->priority = property->priority;
7095 new_property->values = NULL;
7099 for(elem = property->values;elem != NULL; elem=elem->next) {
7100 new_property->values = g_slist_append(new_property->values,
7101 stralloc(elem->data));
7104 g_hash_table_insert(proplist, stralloc(property_s), new_property);
7108 copy_proplist_foreach_fn(
7111 gpointer user_data_p)
7113 char *property_s = key_p;
7114 property_t *property = value_p;
7115 proplist_t proplist = user_data_p;
7116 GSList *elem = NULL;
7117 property_t *new_property = malloc(sizeof(property_t));
7118 new_property->append = property->append;
7119 new_property->priority = property->priority;
7120 new_property->seen = property->seen;
7121 new_property->values = NULL;
7123 for(elem = property->values;elem != NULL; elem=elem->next) {
7124 new_property->values = g_slist_append(new_property->values,
7125 stralloc(elem->data));
7127 g_hash_table_insert(proplist, stralloc(property_s), new_property);
7136 case CONFTYPE_BOOLEAN:
7137 case CONFTYPE_NO_YES_ALL:
7138 case CONFTYPE_COMPRESS:
7139 case CONFTYPE_ENCRYPT:
7140 case CONFTYPE_HOLDING:
7141 case CONFTYPE_EXECUTE_WHERE:
7142 case CONFTYPE_EXECUTE_ON:
7143 case CONFTYPE_SEND_AMREPORT_ON:
7144 case CONFTYPE_DATA_PATH:
7145 case CONFTYPE_STRATEGY:
7147 case CONFTYPE_TAPERALGO:
7148 case CONFTYPE_PRIORITY:
7149 case CONFTYPE_INT64:
7152 case CONFTYPE_INTRANGE:
7153 case CONFTYPE_PART_CACHE_TYPE:
7156 case CONFTYPE_IDENT:
7158 case CONFTYPE_APPLICATION:
7162 case CONFTYPE_IDENTLIST:
7163 slist_free_full(val->v.identlist, g_free);
7166 case CONFTYPE_HOST_LIMIT:
7167 slist_free_full(val->v.host_limit.match_pats, g_free);
7173 case CONFTYPE_ESTIMATELIST:
7174 g_slist_free(val->v.estimatelist);
7177 case CONFTYPE_EXINCLUDE:
7178 free_sl(val_t__exinclude(val).sl_list);
7179 free_sl(val_t__exinclude(val).sl_file);
7182 case CONFTYPE_PROPLIST:
7183 g_hash_table_destroy(val_t__proplist(val));
7186 case CONFTYPE_AUTOLABEL:
7187 amfree(val->v.autolabel.template);
7190 val->seen.linenum = 0;
7191 val->seen.filename = NULL;
7192 val->seen.block = NULL;
7196 * Utilities Implementation
7200 generic_get_security_conf(
7205 if(!string || !*string)
7208 if(strcmp(string, "krb5principal")==0) {
7209 return(getconf_str(CNF_KRB5PRINCIPAL));
7210 } else if(strcmp(string, "krb5keytab")==0) {
7211 return(getconf_str(CNF_KRB5KEYTAB));
7217 generic_client_get_security_conf(
7221 (void)arg; /* Quiet unused parameter warning */
7223 if(!string || !*string)
7226 if(strcmp(string, "conf")==0) {
7227 return(getconf_str(CNF_CONF));
7228 } else if(strcmp(string, "amdump_server")==0) {
7229 return(getconf_str(CNF_AMDUMP_SERVER));
7230 } else if(strcmp(string, "index_server")==0) {
7231 return(getconf_str(CNF_INDEX_SERVER));
7232 } else if(strcmp(string, "tape_server")==0) {
7233 return(getconf_str(CNF_TAPE_SERVER));
7234 } else if(strcmp(string, "tapedev")==0) {
7235 return(getconf_str(CNF_TAPEDEV));
7236 } else if(strcmp(string, "auth")==0) {
7237 return(getconf_str(CNF_AUTH));
7238 } else if(strcmp(string, "ssh_keys")==0) {
7239 return(getconf_str(CNF_SSH_KEYS));
7240 } else if(strcmp(string, "amandad_path")==0) {
7241 return(getconf_str(CNF_AMANDAD_PATH));
7242 } else if(strcmp(string, "client_username")==0) {
7243 return(getconf_str(CNF_CLIENT_USERNAME));
7244 } else if(strcmp(string, "client_port")==0) {
7245 return(getconf_str(CNF_CLIENT_PORT));
7246 } else if(strcmp(string, "gnutar_list_dir")==0) {
7247 return(getconf_str(CNF_GNUTAR_LIST_DIR));
7248 } else if(strcmp(string, "amandates")==0) {
7249 return(getconf_str(CNF_AMANDATES));
7250 } else if(strcmp(string, "krb5principal")==0) {
7251 return(getconf_str(CNF_KRB5PRINCIPAL));
7252 } else if(strcmp(string, "krb5keytab")==0) {
7253 return(getconf_str(CNF_KRB5KEYTAB));
7260 gboolean print_default,
7261 gboolean print_source)
7270 device_config_t *dc;
7271 changer_config_t *cc;
7272 interactivity_t *iv;
7279 if (config_client) {
7280 error(_("Don't know how to dump client configurations."));
7284 g_printf(_("# AMANDA CONFIGURATION FROM FILE \"%s\":\n\n"), config_filename);
7286 for(np=server_var; np->token != CONF_UNKNOWN; np++) {
7287 for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
7288 if (np->token == kt->token) break;
7290 if(kt->token == CONF_UNKNOWN)
7291 error(_("server bad token"));
7293 val_t_print_token(print_default, print_source, stdout, NULL, "%-21s ", kt, &conf_data[np->parm]);
7296 for(hp = holdinglist; hp != NULL; hp = hp->next) {
7298 g_printf("\nDEFINE HOLDINGDISK %s {\n", hd->name);
7299 for(i=0; i < HOLDING_HOLDING; i++) {
7300 for(np=holding_var; np->token != CONF_UNKNOWN; np++) {
7304 if(np->token == CONF_UNKNOWN)
7305 error(_("holding bad value"));
7307 for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++) {
7308 if(kt->token == np->token)
7311 if(kt->token == CONF_UNKNOWN)
7312 error(_("holding bad token"));
7314 val_t_print_token(print_default, print_source, stdout, NULL, " %-9s ", kt, &hd->value[i]);
7319 for(tp = tapelist; tp != NULL; tp = tp->next) {
7320 if(tp->seen.linenum == -1)
7324 g_printf("\n%sDEFINE TAPETYPE %s {\n", prefix, tp->name);
7325 for(i=0; i < TAPETYPE_TAPETYPE; i++) {
7326 for(np=tapetype_var; np->token != CONF_UNKNOWN; np++)
7327 if(np->parm == i) break;
7328 if(np->token == CONF_UNKNOWN)
7329 error(_("tapetype bad value"));
7331 for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
7332 if(kt->token == np->token) break;
7333 if(kt->token == CONF_UNKNOWN)
7334 error(_("tapetype bad token"));
7336 val_t_print_token(print_default, print_source, stdout, prefix, " %-9s ", kt, &tp->value[i]);
7338 g_printf("%s}\n", prefix);
7341 for(dp = dumplist; dp != NULL; dp = dp->next) {
7342 if (strncmp_const(dp->name, "custom(") != 0) { /* don't dump disklist-derived dumptypes */
7343 if(dp->seen.linenum == -1)
7347 g_printf("\n%sDEFINE DUMPTYPE %s {\n", prefix, dp->name);
7348 for(i=0; i < DUMPTYPE_DUMPTYPE; i++) {
7349 for(np=dumptype_var; np->token != CONF_UNKNOWN; np++)
7350 if(np->parm == i) break;
7351 if(np->token == CONF_UNKNOWN)
7352 error(_("dumptype bad value"));
7354 for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
7355 if(kt->token == np->token) break;
7356 if(kt->token == CONF_UNKNOWN)
7357 error(_("dumptype bad token"));
7359 val_t_print_token(print_default, print_source, stdout, prefix, " %-19s ", kt, &dp->value[i]);
7361 g_printf("%s}\n", prefix);
7365 for(ip = interface_list; ip != NULL; ip = ip->next) {
7366 seen_t *netusage_seen = &val_t__seen(getconf(CNF_NETUSAGE));
7367 if (ip->seen.linenum == netusage_seen->linenum &&
7368 ip->seen.filename && netusage_seen->filename &&
7369 0 == strcmp(ip->seen.filename, netusage_seen->filename))
7373 g_printf("\n%sDEFINE INTERFACE %s {\n", prefix, ip->name);
7374 for(i=0; i < INTER_INTER; i++) {
7375 for(np=interface_var; np->token != CONF_UNKNOWN; np++)
7376 if(np->parm == i) break;
7377 if(np->token == CONF_UNKNOWN)
7378 error(_("interface bad value"));
7380 for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
7381 if(kt->token == np->token) break;
7382 if(kt->token == CONF_UNKNOWN)
7383 error(_("interface bad token"));
7385 val_t_print_token(print_default, print_source, stdout, prefix, " %-19s ", kt, &ip->value[i]);
7387 g_printf("%s}\n",prefix);
7390 for(ap = application_list; ap != NULL; ap = ap->next) {
7391 if(strcmp(ap->name,"default") == 0)
7395 g_printf("\n%sDEFINE APPLICATION %s {\n", prefix, ap->name);
7396 for(i=0; i < APPLICATION_APPLICATION; i++) {
7397 for(np=application_var; np->token != CONF_UNKNOWN; np++)
7398 if(np->parm == i) break;
7399 if(np->token == CONF_UNKNOWN)
7400 error(_("application bad value"));
7402 for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
7403 if(kt->token == np->token) break;
7404 if(kt->token == CONF_UNKNOWN)
7405 error(_("application bad token"));
7407 val_t_print_token(print_default, print_source, stdout, prefix, " %-19s ", kt, &ap->value[i]);
7409 g_printf("%s}\n",prefix);
7412 for(ps = pp_script_list; ps != NULL; ps = ps->next) {
7413 if(strcmp(ps->name,"default") == 0)
7417 g_printf("\n%sDEFINE SCRIPT %s {\n", prefix, ps->name);
7418 for(i=0; i < PP_SCRIPT_PP_SCRIPT; i++) {
7419 for(np=pp_script_var; np->token != CONF_UNKNOWN; np++)
7420 if(np->parm == i) break;
7421 if(np->token == CONF_UNKNOWN)
7422 error(_("script bad value"));
7424 for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
7425 if(kt->token == np->token) break;
7426 if(kt->token == CONF_UNKNOWN)
7427 error(_("script bad token"));
7429 val_t_print_token(print_default, print_source, stdout, prefix, " %-19s ", kt, &ps->value[i]);
7431 g_printf("%s}\n",prefix);
7434 for(dc = device_config_list; dc != NULL; dc = dc->next) {
7436 g_printf("\n%sDEFINE DEVICE %s {\n", prefix, dc->name);
7437 for(i=0; i < DEVICE_CONFIG_DEVICE_CONFIG; i++) {
7438 for(np=device_config_var; np->token != CONF_UNKNOWN; np++)
7439 if(np->parm == i) break;
7440 if(np->token == CONF_UNKNOWN)
7441 error(_("device bad value"));
7443 for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
7444 if(kt->token == np->token) break;
7445 if(kt->token == CONF_UNKNOWN)
7446 error(_("device bad token"));
7448 val_t_print_token(print_default, print_source, stdout, prefix, " %-19s ", kt, &dc->value[i]);
7450 g_printf("%s}\n",prefix);
7453 for(cc = changer_config_list; cc != NULL; cc = cc->next) {
7455 g_printf("\n%sDEFINE CHANGER %s {\n", prefix, cc->name);
7456 for(i=0; i < CHANGER_CONFIG_CHANGER_CONFIG; i++) {
7457 for(np=changer_config_var; np->token != CONF_UNKNOWN; np++)
7458 if(np->parm == i) break;
7459 if(np->token == CONF_UNKNOWN)
7460 error(_("changer bad value"));
7462 for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
7463 if(kt->token == np->token) break;
7464 if(kt->token == CONF_UNKNOWN)
7465 error(_("changer bad token"));
7467 val_t_print_token(print_default, print_source, stdout, prefix, " %-19s ", kt, &cc->value[i]);
7469 g_printf("%s}\n",prefix);
7472 for(iv = interactivity_list; iv != NULL; iv = iv->next) {
7474 g_printf("\n%sDEFINE INTERACTIVITY %s {\n", prefix, iv->name);
7475 for(i=0; i < INTERACTIVITY_INTERACTIVITY; i++) {
7476 for(np=interactivity_var; np->token != CONF_UNKNOWN; np++)
7477 if(np->parm == i) break;
7478 if(np->token == CONF_UNKNOWN)
7479 error(_("interactivity bad value"));
7481 for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
7482 if(kt->token == np->token) break;
7483 if(kt->token == CONF_UNKNOWN)
7484 error(_("interactivity bad token"));
7486 val_t_print_token(print_default, print_source, stdout, prefix, " %-19s ", kt, &iv->value[i]);
7488 g_printf("%s}\n",prefix);
7491 for(ts = taperscan_list; ts != NULL; ts = ts->next) {
7493 g_printf("\n%sDEFINE TAPERSCAN %s {\n", prefix, ts->name);
7494 for(i=0; i < TAPERSCAN_TAPERSCAN; i++) {
7495 for(np=taperscan_var; np->token != CONF_UNKNOWN; np++)
7496 if(np->parm == i) break;
7497 if(np->token == CONF_UNKNOWN)
7498 error(_("taperscan bad value"));
7500 for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
7501 if(kt->token == np->token) break;
7502 if(kt->token == CONF_UNKNOWN)
7503 error(_("taperscan bad token"));
7505 val_t_print_token(print_default, print_source, stdout, prefix, " %-19s ", kt, &ts->value[i]);
7507 g_printf("%s}\n",prefix);
7514 gboolean print_default,
7515 gboolean print_source)
7521 for(i=0; i < DUMPTYPE_DUMPTYPE; i++) {
7522 for(np=dumptype_var; np->token != CONF_UNKNOWN; np++)
7523 if(np->parm == i) break;
7524 if(np->token == CONF_UNKNOWN)
7525 error(_("dumptype bad value"));
7527 for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
7528 if(kt->token == np->token) break;
7529 if(kt->token == CONF_UNKNOWN)
7530 error(_("dumptype bad token"));
7532 val_t_print_token(print_default, print_source, stdout, prefix, " %-19s ", kt, &dp->value[i]);
7538 gboolean print_default,
7539 gboolean print_source,
7546 char **dispstrs, **dispstr;
7548 if (print_default == 0 && !val_t_seen(val)) {
7552 dispstrs = val_t_display_strs(val, 1, print_source, TRUE);
7554 /* For most configuration types, this outputs
7555 * PREFIX KEYWORD DISPSTR
7556 * for each of the display strings. For identifiers, however, it
7557 * simply prints the first line of the display string.
7560 /* Print the keyword for anything that is not itself an identifier */
7561 if (kt->token != CONF_IDENT) {
7562 for(dispstr=dispstrs; *dispstr!=NULL; dispstr++) {
7564 g_fprintf(output, "%s", prefix);
7565 g_fprintf(output, format, str_keyword(kt));
7566 g_fprintf(output, "%s\n", *dispstr);
7569 /* for identifiers, assume there's at most one display string */
7570 assert(g_strv_length(dispstrs) <= 1);
7572 g_fprintf(output, "%s\n", *dispstrs);
7576 g_strfreev(dispstrs);
7579 typedef struct proplist_display_str_foreach_user_data {
7581 gboolean print_source;
7582 } proplist_display_str_foreach_user_data;
7584 char *source_string(seen_t *seen);
7585 char *source_string(
7590 if (seen->linenum) {
7592 buf = g_strdup_printf(" (%s file %s line %d)",
7593 seen->block, seen->filename, seen->linenum);
7595 buf = g_strdup_printf(" (file %s line %d)",
7596 seen->filename, seen->linenum);
7599 buf = g_strdup(" (default)");
7608 gboolean print_source,
7609 gboolean print_unit)
7611 gboolean add_source = TRUE;
7614 buf = malloc(3*SIZEOF(char *));
7621 buf[0] = vstrallocf("%d ", val_t__int(val));
7622 i = strlen(buf[0]) - 1;
7623 if (print_unit && val->unit == CONF_UNIT_K) {
7631 buf[0] = vstrallocf("%zd ", (ssize_t)val_t__size(val));
7632 i = strlen(buf[0]) - 1;
7633 if (print_unit && val->unit == CONF_UNIT_K) {
7640 case CONFTYPE_INT64:
7641 buf[0] = vstrallocf("%lld ", (long long)val_t__int64(val));
7642 i = strlen(buf[0]) - 1;
7643 if (print_unit && val->unit == CONF_UNIT_K) {
7651 buf[0] = vstrallocf("%0.5f", val_t__real(val));
7655 buf[0] = vstrallocf("%0.5f %0.5f", val_t__rate(val)[0], val_t__rate(val)[1]);
7658 case CONFTYPE_INTRANGE:
7659 buf[0] = vstrallocf("%d,%d", val_t__intrange(val)[0], val_t__intrange(val)[1]);
7662 case CONFTYPE_IDENT:
7664 buf[0] = stralloc(val->v.s);
7666 buf[0] = stralloc("");
7670 case CONFTYPE_IDENTLIST:
7676 for (ia = val->v.identlist; ia != NULL; ia = ia->next) {
7678 buf[0] = stralloc(ia->data);
7681 strappend(buf[0], " ");
7682 strappend(buf[0], ia->data);
7689 if(str_need_quote) {
7691 buf[0] = quote_string_always(val->v.s);
7693 buf[0] = stralloc("\"\"");
7697 buf[0] = stralloc(val->v.s);
7699 buf[0] = stralloc("");
7704 case CONFTYPE_AUTOLABEL:
7706 buf[0] = quote_string_always(val->v.autolabel.template);
7707 if (val->v.autolabel.autolabel & AL_OTHER_CONFIG) {
7708 buf[0] = vstrextend(&buf[0], " OTHER-CONFIG", NULL);
7710 if (val->v.autolabel.autolabel & AL_NON_AMANDA) {
7711 buf[0] = vstrextend(&buf[0], " NON-AMANDA", NULL);
7713 if (val->v.autolabel.autolabel & AL_VOLUME_ERROR) {
7714 buf[0] = vstrextend(&buf[0], " VOLUME-ERROR", NULL);
7716 if (val->v.autolabel.autolabel & AL_EMPTY) {
7717 buf[0] = vstrextend(&buf[0], " EMPTY", NULL);
7723 buf[0] = vstrallocf("%2d%02d",
7724 (int)val_t__time(val)/100, (int)val_t__time(val) % 100);
7727 case CONFTYPE_EXINCLUDE: {
7728 buf[0] = exinclude_display_str(val, 0);
7729 buf[1] = exinclude_display_str(val, 1);
7733 case CONFTYPE_BOOLEAN:
7734 if(val_t__boolean(val))
7735 buf[0] = stralloc("yes");
7737 buf[0] = stralloc("no");
7740 case CONFTYPE_NO_YES_ALL:
7741 switch(val_t__no_yes_all(val)) {
7743 buf[0] = stralloc("no");
7746 buf[0] = stralloc("yes");
7749 buf[0] = stralloc("all");
7754 case CONFTYPE_STRATEGY:
7755 switch(val_t__strategy(val)) {
7757 buf[0] = vstrallocf("SKIP");
7761 buf[0] = vstrallocf("STANDARD");
7765 buf[0] = vstrallocf("NOFULL");
7769 buf[0] = vstrallocf("NOINC");
7773 buf[0] = vstrallocf("HANOI");
7777 buf[0] = vstrallocf("INCRONLY");
7782 case CONFTYPE_COMPRESS:
7783 switch(val_t__compress(val)) {
7785 buf[0] = vstrallocf("NONE");
7789 buf[0] = vstrallocf("CLIENT FAST");
7793 buf[0] = vstrallocf("CLIENT BEST");
7797 buf[0] = vstrallocf("CLIENT CUSTOM");
7800 case COMP_SERVER_FAST:
7801 buf[0] = vstrallocf("SERVER FAST");
7804 case COMP_SERVER_BEST:
7805 buf[0] = vstrallocf("SERVER BEST");
7808 case COMP_SERVER_CUST:
7809 buf[0] = vstrallocf("SERVER CUSTOM");
7814 case CONFTYPE_ESTIMATELIST: {
7815 estimatelist_t es = val_t__estimatelist(val);
7816 buf[0] = stralloc("");
7818 switch((estimate_t)GPOINTER_TO_INT(es->data)) {
7820 strappend(buf[0], "CLIENT");
7824 strappend(buf[0], "SERVER");
7828 strappend(buf[0], "CALCSIZE");
7836 strappend(buf[0], " ");
7841 case CONFTYPE_EXECUTE_WHERE:
7844 buf[0] = vstrallocf("CLIENT");
7848 buf[0] = vstrallocf("SERVER");
7853 case CONFTYPE_SEND_AMREPORT_ON:
7855 case SEND_AMREPORT_ALL:
7856 buf[0] = vstrallocf("ALL");
7858 case SEND_AMREPORT_STRANGE:
7859 buf[0] = vstrallocf("STRANGE");
7861 case SEND_AMREPORT_ERROR:
7862 buf[0] = vstrallocf("ERROR");
7864 case SEND_AMREPORT_NEVER:
7865 buf[0] = vstrallocf("NEVER");
7870 case CONFTYPE_DATA_PATH:
7871 buf[0] = g_strdup(data_path_to_string(val->v.i));
7874 case CONFTYPE_ENCRYPT:
7875 switch(val_t__encrypt(val)) {
7877 buf[0] = vstrallocf("NONE");
7881 buf[0] = vstrallocf("CLIENT");
7884 case ENCRYPT_SERV_CUST:
7885 buf[0] = vstrallocf("SERVER");
7890 case CONFTYPE_PART_CACHE_TYPE:
7891 switch(val_t__part_cache_type(val)) {
7892 case PART_CACHE_TYPE_NONE:
7893 buf[0] = vstrallocf("NONE");
7896 case PART_CACHE_TYPE_DISK:
7897 buf[0] = vstrallocf("DISK");
7900 case PART_CACHE_TYPE_MEMORY:
7901 buf[0] = vstrallocf("MEMORY");
7906 case CONFTYPE_HOST_LIMIT: {
7907 GSList *iter = val_t__host_limit(val).match_pats;
7909 if (val_t__host_limit(val).same_host)
7910 buf[0] = stralloc("SAME-HOST ");
7912 buf[0] = stralloc("");
7914 if (val_t__host_limit(val).server)
7915 strappend(buf[0], "SERVER ");
7918 strappend(buf[0], quote_string_always((char *)iter->data));
7919 strappend(buf[0], " ");
7925 case CONFTYPE_HOLDING:
7926 switch(val_t__holding(val)) {
7928 buf[0] = vstrallocf("NEVER");
7932 buf[0] = vstrallocf("AUTO");
7936 buf[0] = vstrallocf("REQUIRED");
7941 case CONFTYPE_TAPERALGO:
7942 buf[0] = vstrallocf("%s", taperalgo2str(val_t__taperalgo(val)));
7945 case CONFTYPE_PRIORITY:
7946 switch(val_t__priority(val)) {
7948 buf[0] = vstrallocf("LOW");
7952 buf[0] = vstrallocf("MEDIUM");
7956 buf[0] = vstrallocf("HIGH");
7961 case CONFTYPE_PROPLIST: {
7963 proplist_display_str_foreach_user_data user_data;
7965 nb_property = g_hash_table_size(val_t__proplist(val));
7967 buf = malloc((nb_property+1)*SIZEOF(char*));
7968 buf[nb_property] = NULL;
7969 user_data.msg = buf;
7970 user_data.print_source = print_source;
7971 g_hash_table_foreach(val_t__proplist(val),
7972 proplist_display_str_foreach_fn,
7978 case CONFTYPE_APPLICATION: {
7980 buf[0] = quote_string_always(val->v.s);
7982 buf[0] = stralloc("");
7987 case CONFTYPE_EXECUTE_ON:
7988 buf[0] = stralloc("");
7989 if (val->v.i != 0) {
7991 if (val->v.i & EXECUTE_ON_PRE_AMCHECK) {
7992 buf[0] = vstrextend(&buf[0], sep, "PRE-AMCHECK", NULL);
7995 if (val->v.i & EXECUTE_ON_PRE_DLE_AMCHECK) {
7996 buf[0] = vstrextend(&buf[0], sep, "PRE-DLE-AMCHECK", NULL);
7999 if (val->v.i & EXECUTE_ON_PRE_HOST_AMCHECK) {
8000 buf[0] = vstrextend(&buf[0], sep, "PRE-HOST-AMCHECK", NULL);
8003 if (val->v.i & EXECUTE_ON_POST_DLE_AMCHECK) {
8004 buf[0] = vstrextend(&buf[0], sep, "POST-DLE-AMCHECK", NULL);
8007 if (val->v.i & EXECUTE_ON_POST_HOST_AMCHECK) {
8008 buf[0] = vstrextend(&buf[0], sep, "POST-HOST-AMCHECK", NULL);
8011 if (val->v.i & EXECUTE_ON_POST_AMCHECK) {
8012 buf[0] = vstrextend(&buf[0], sep, "POST-AMCHECK", NULL);
8015 if (val->v.i & EXECUTE_ON_PRE_ESTIMATE) {
8016 buf[0] = vstrextend(&buf[0], sep, "PRE-ESTIMATE", NULL);
8019 if (val->v.i & EXECUTE_ON_PRE_DLE_ESTIMATE) {
8020 buf[0] = vstrextend(&buf[0], sep, "PRE-DLE-ESTIMATE", NULL);
8023 if (val->v.i & EXECUTE_ON_PRE_HOST_ESTIMATE) {
8024 buf[0] = vstrextend(&buf[0], sep, "PRE-HOST-ESTIMATE", NULL);
8027 if (val->v.i & EXECUTE_ON_POST_DLE_ESTIMATE) {
8028 buf[0] = vstrextend(&buf[0], sep, "POST-DLE-ESTIMATE", NULL);
8031 if (val->v.i & EXECUTE_ON_POST_HOST_ESTIMATE) {
8032 buf[0] = vstrextend(&buf[0], sep, "POST-HOST-ESTIMATE", NULL);
8035 if (val->v.i & EXECUTE_ON_POST_ESTIMATE) {
8036 buf[0] = vstrextend(&buf[0], sep, "POST-ESTIMATE", NULL);
8039 if (val->v.i & EXECUTE_ON_PRE_BACKUP) {
8040 buf[0] = vstrextend(&buf[0], sep, "PRE-BACKUP", NULL);
8043 if (val->v.i & EXECUTE_ON_PRE_DLE_BACKUP) {
8044 buf[0] = vstrextend(&buf[0], sep, "PRE-DLE-BACKUP", NULL);
8047 if (val->v.i & EXECUTE_ON_PRE_HOST_BACKUP) {
8048 buf[0] = vstrextend(&buf[0], sep, "PRE-HOST-BACKUP", NULL);
8051 if (val->v.i & EXECUTE_ON_POST_BACKUP) {
8052 buf[0] = vstrextend(&buf[0], sep, "POST-BACKUP", NULL);
8055 if (val->v.i & EXECUTE_ON_POST_DLE_BACKUP) {
8056 buf[0] = vstrextend(&buf[0], sep, "POST-DLE-BACKUP", NULL);
8059 if (val->v.i & EXECUTE_ON_POST_HOST_BACKUP) {
8060 buf[0] = vstrextend(&buf[0], sep, "POST-HOST-BACKUP", NULL);
8063 if (val->v.i & EXECUTE_ON_PRE_RECOVER) {
8064 buf[0] = vstrextend(&buf[0], sep, "PRE-RECOVER", NULL);
8067 if (val->v.i & EXECUTE_ON_POST_RECOVER) {
8068 buf[0] = vstrextend(&buf[0], sep, "POST-RECOVER", NULL);
8071 if (val->v.i & EXECUTE_ON_PRE_LEVEL_RECOVER) {
8072 buf[0] = vstrextend(&buf[0], sep, "PRE-LEVEL-RECOVER", NULL);
8075 if (val->v.i & EXECUTE_ON_POST_LEVEL_RECOVER) {
8076 buf[0] = vstrextend(&buf[0], sep, "POST-LEVEL-RECOVER", NULL);
8079 if (val->v.i & EXECUTE_ON_INTER_LEVEL_RECOVER) {
8080 buf[0] = vstrextend(&buf[0], sep, "INTER-LEVEL-RECOVER", NULL);
8089 if (print_source && add_source) {
8091 for (buf1 = buf; *buf1 != NULL; buf1++) {
8092 char *buf2 = g_strjoin("", *buf1, source_string(&val->seen), NULL);
8101 val_t_to_execute_on(
8104 if (val->type != CONFTYPE_EXECUTE_ON) {
8105 error(_("get_conftype_execute_on: val.type is not CONFTYPE_EXECUTE_ON"));
8108 return val_t__execute_on(val);
8112 val_t_to_execute_where(
8115 if (val->type != CONFTYPE_EXECUTE_WHERE) {
8116 error(_("get_conftype_execute_where: val.type is not CONFTYPE_EXECUTE_WHERE"));
8123 val_t_to_application(
8126 if (val->type != CONFTYPE_APPLICATION) {
8127 error(_("get_conftype_applicaiton: val.type is not CONFTYPE_APPLICATION"));
8135 proplist_display_str_foreach_fn(
8138 gpointer user_data_p)
8140 char *property_s = quote_string_always(key_p);
8141 property_t *property = value_p;
8143 proplist_display_str_foreach_user_data *user_data = user_data_p;
8144 char ***msg = (char ***)&user_data->msg;
8146 /* What to do with property->append? it should be printed only on client */
8147 if (property->priority) {
8148 **msg = vstralloc("priority ", property_s, NULL);
8154 for(value=property->values; value != NULL; value = value->next) {
8155 char *qstr = quote_string_always((char *)value->data);
8156 **msg = vstrextend(*msg, " ", qstr, NULL);
8159 if (user_data->print_source) {
8160 **msg = vstrextend(*msg, source_string(&property->seen));
8166 exinclude_display_str(
8174 assert(val->type == CONFTYPE_EXINCLUDE);
8176 rval = stralloc("");
8179 sl = val_t__exinclude(val).sl_list;
8180 strappend(rval, "LIST");
8182 sl = val_t__exinclude(val).sl_file;
8183 strappend(rval, "FILE");
8186 if (val_t__exinclude(val).optional == 1) {
8187 strappend(rval, " OPTIONAL");
8191 for(excl = sl->first; excl != NULL; excl = excl->next) {
8192 char *qstr = quote_string_always(excl->name);
8193 vstrextend(&rval, " ", qstr, NULL);
8203 taperalgo_t taperalgo)
8205 if(taperalgo == ALGO_FIRST) return "FIRST";
8206 if(taperalgo == ALGO_FIRSTFIT) return "FIRSTFIT";
8207 if(taperalgo == ALGO_LARGEST) return "LARGEST";
8208 if(taperalgo == ALGO_LARGESTFIT) return "LARGESTFIT";
8209 if(taperalgo == ALGO_SMALLEST) return "SMALLEST";
8210 if(taperalgo == ALGO_LAST) return "LAST";
8215 config_dir_relative(
8218 if (*filename == '/' || config_dir == NULL) {
8219 return stralloc(filename);
8221 if (config_dir[strlen(config_dir)-1] == '/') {
8222 return vstralloc(config_dir, filename, NULL);
8224 return vstralloc(config_dir, "/", filename, NULL);
8248 device_config_t *dc;
8249 changer_config_t *cc;
8251 interactivity_t *iv;
8252 int success = FALSE;
8254 /* WARNING: assumes globals keytable and parsetable are set correctly. */
8255 assert(keytable != NULL);
8256 assert(parsetable != NULL);
8258 /* make a copy we can stomp on */
8259 key = stralloc(key);
8261 /* uppercase the key */
8262 for (s = key; (ch = *s) != 0; s++) {
8263 if (islower((int)ch))
8264 *s = (char)toupper(ch);
8267 subsec_name = strchr(key, ':');
8271 *subsec_name = '\0';
8274 /* convert subsec_type '-' to '_' */
8275 for (s = subsec_type; (ch = *s) != 0; s++) {
8276 if (*s == '-') *s = '_';
8279 subsec_key = strrchr(subsec_name,':');
8280 if(!subsec_key) goto out; /* failure */
8285 /* convert subsec_key '-' to '_' */
8286 for (s = subsec_key; (ch = *s) != 0; s++) {
8287 if (*s == '-') *s = '_';
8290 /* If the keyword doesn't exist, there's no need to look up the
8291 * subsection -- we know it's invalid */
8292 for(kt = keytable; kt->token != CONF_UNKNOWN; kt++) {
8293 if(kt->keyword && strcmp(kt->keyword, subsec_key) == 0)
8296 if(kt->token == CONF_UNKNOWN) goto out;
8298 /* Otherwise, figure out which kind of subsection we're dealing with,
8299 * and parse against that. */
8300 if (strcmp(subsec_type, "TAPETYPE") == 0) {
8301 tp = lookup_tapetype(subsec_name);
8303 for(np = tapetype_var; np->token != CONF_UNKNOWN; np++) {
8304 if(np->token == kt->token)
8307 if (np->token == CONF_UNKNOWN) goto out;
8309 if (val) *val = &tp->value[np->parm];
8310 if (parm) *parm = np;
8312 } else if (strcmp(subsec_type, "DUMPTYPE") == 0) {
8313 dp = lookup_dumptype(subsec_name);
8315 for(np = dumptype_var; np->token != CONF_UNKNOWN; np++) {
8316 if(np->token == kt->token)
8319 if (np->token == CONF_UNKNOWN) goto out;
8321 if (val) *val = &dp->value[np->parm];
8322 if (parm) *parm = np;
8324 } else if (strcmp(subsec_type, "HOLDINGDISK") == 0) {
8325 hp = lookup_holdingdisk(subsec_name);
8327 for(np = holding_var; np->token != CONF_UNKNOWN; np++) {
8328 if(np->token == kt->token)
8331 if (np->token == CONF_UNKNOWN) goto out;
8333 if (val) *val = &hp->value[np->parm];
8334 if (parm) *parm = np;
8336 } else if (strcmp(subsec_type, "INTERFACE") == 0) {
8337 ip = lookup_interface(subsec_name);
8339 for(np = interface_var; np->token != CONF_UNKNOWN; np++) {
8340 if(np->token == kt->token)
8343 if (np->token == CONF_UNKNOWN) goto out;
8345 if (val) *val = &ip->value[np->parm];
8346 if (parm) *parm = np;
8348 /* accept the old name here, too */
8349 } else if (strcmp(subsec_type, "APPLICATION_TOOL") == 0
8350 || strcmp(subsec_type, "APPLICATION") == 0) {
8351 ap = lookup_application(subsec_name);
8353 for(np = application_var; np->token != CONF_UNKNOWN; np++) {
8354 if(np->token == kt->token)
8357 if (np->token == CONF_UNKNOWN) goto out;
8359 if (val) *val = &ap->value[np->parm];
8360 if (parm) *parm = np;
8362 /* accept the old name here, too */
8363 } else if (strcmp(subsec_type, "SCRIPT_TOOL") == 0
8364 || strcmp(subsec_type, "SCRIPT") == 0) {
8365 pp = lookup_pp_script(subsec_name);
8367 for(np = pp_script_var; np->token != CONF_UNKNOWN; np++) {
8368 if(np->token == kt->token)
8371 if (np->token == CONF_UNKNOWN) goto out;
8373 if (val) *val = &pp->value[np->parm];
8374 if (parm) *parm = np;
8376 } else if (strcmp(subsec_type, "DEVICE") == 0) {
8377 dc = lookup_device_config(subsec_name);
8379 for(np = device_config_var; np->token != CONF_UNKNOWN; np++) {
8380 if(np->token == kt->token)
8383 if (np->token == CONF_UNKNOWN) goto out;
8385 if (val) *val = &dc->value[np->parm];
8386 if (parm) *parm = np;
8388 } else if (strcmp(subsec_type, "CHANGER") == 0) {
8389 cc = lookup_changer_config(subsec_name);
8391 for(np = changer_config_var; np->token != CONF_UNKNOWN; np++) {
8392 if(np->token == kt->token)
8395 if (np->token == CONF_UNKNOWN) goto out;
8397 if (val) *val = &cc->value[np->parm];
8398 if (parm) *parm = np;
8400 } else if (g_str_equal(subsec_type, "INTERACTIVITY")) {
8401 iv = lookup_interactivity(subsec_name);
8403 for(np = interactivity_var; np->token != CONF_UNKNOWN; np++) {
8404 if(np->token == kt->token)
8407 if (np->token == CONF_UNKNOWN) goto out;
8409 if (val) *val = &iv->value[np->parm];
8410 if (parm) *parm = np;
8412 } else if (g_str_equal(subsec_type, "TAPERSCAN")) {
8413 ts = lookup_taperscan(subsec_name);
8415 for(np = taperscan_var; np->token != CONF_UNKNOWN; np++) {
8416 if(np->token == kt->token)
8419 if (np->token == CONF_UNKNOWN) goto out;
8421 if (val) *val = &ts->value[np->parm];
8422 if (parm) *parm = np;
8426 /* No delimiters -- we're referencing a global config parameter */
8428 /* convert key '-' to '_' */
8429 for (s = key; (ch = *s) != 0; s++) {
8430 if (*s == '-') *s = '_';
8433 /* look up the keyword */
8434 for(kt = keytable; kt->token != CONF_UNKNOWN; kt++) {
8435 if(kt->keyword && strcmp(kt->keyword, key) == 0)
8438 if(kt->token == CONF_UNKNOWN) goto out;
8440 /* and then look that up in the parse table */
8441 for(np = parsetable; np->token != CONF_UNKNOWN; np++) {
8442 if(np->token == kt->token)
8445 if(np->token == CONF_UNKNOWN) goto out;
8447 if (val) *val = &conf_data[np->parm];
8448 if (parm) *parm = np;
8461 keytab_t * table_entry;
8463 str = g_strdup(str);
8471 for (table_entry = numb_keytable; table_entry->keyword != NULL;
8473 if (strcasecmp(str, table_entry->keyword) == 0) {
8475 switch (table_entry->token) {
8481 return 1024*1024*1024;
8483 return (gint64)1024*1024*1024*1024;
8486 case CONF_AMINFINITY:
8492 /* Should not happen. */
8498 /* None found; this is an error. */
8507 keytab_t * table_entry;
8509 if (str == NULL || *str == '\0') {
8513 /* 0 and 1 are not in the table, as they are parsed as ints */
8514 if (0 == strcmp(str, "0"))
8516 if (0 == strcmp(str, "1"))
8519 for (table_entry = bool_keytable; table_entry->keyword != NULL;
8521 if (strcasecmp(str, table_entry->keyword) == 0) {
8522 switch (table_entry->token) {
8537 * Error Handling Implementaiton
8540 void config_add_error(
8541 cfgerr_level_t level,
8544 cfgerr_level = max(cfgerr_level, level);
8546 g_debug("%s", errmsg);
8547 cfgerr_errors = g_slist_append(cfgerr_errors, errmsg);
8550 static void conf_error_common(
8551 cfgerr_level_t level,
8552 const char * format,
8555 char *msg = g_strdup_vprintf(format, argp);
8556 char *errstr = NULL;
8559 errstr = g_strdup_printf(_("argument \"%s\": %s"),
8561 else if (current_filename && current_line_num > 0)
8562 errstr = g_strdup_printf(_("\"%s\", line %d: %s"),
8563 current_filename, current_line_num, msg);
8565 errstr = g_strdup_printf(_("parse error: %s"), msg);
8568 config_add_error(level, errstr);
8571 printf_arglist_function(void conf_parserror, const char *, format)
8575 arglist_start(argp, format);
8576 conf_error_common(CFGERR_ERRORS, format, argp);
8580 printf_arglist_function(void conf_parswarn, const char *, format) {
8583 arglist_start(argp, format);
8584 conf_error_common(CFGERR_WARNINGS, format, argp);
8589 config_errors(GSList **errstr)
8592 *errstr = cfgerr_errors;
8593 return cfgerr_level;
8597 config_clear_errors(void)
8599 slist_free_full(cfgerr_errors, g_free);
8601 cfgerr_errors = NULL;
8602 cfgerr_level = CFGERR_OK;
8606 config_print_errors(void)
8610 for (iter = cfgerr_errors; iter; iter = g_slist_next(iter)) {
8611 g_fprintf(stderr, "%s\n", (char *)iter->data);
8615 /* Get the config name */
8616 char *get_config_name(void)
8621 /* Get the config directory */
8622 char *get_config_dir(void)
8627 /* Get the config filename */
8628 char *get_config_filename(void)
8630 return config_filename;
8634 anonymous_value(void)
8636 static char number[NUM_STR_SIZE];
8639 g_snprintf(number, sizeof(number), "%d", value);
8645 gint compare_pp_script_order(
8649 return pp_script_get_order(lookup_pp_script((char *)a)) > pp_script_get_order(lookup_pp_script((char *)b));
8653 data_path_to_string(
8654 data_path_t data_path)
8656 switch (data_path) {
8657 case DATA_PATH_AMANDA : return "AMANDA";
8658 case DATA_PATH_DIRECTTCP: return "DIRECTTCP";
8660 error(_("datapath is not DATA_PATH_AMANDA or DATA_PATH_DIRECTTCP"));
8665 data_path_from_string(
8668 if (strcmp(data, "AMANDA") == 0)
8669 return DATA_PATH_AMANDA;
8670 if (strcmp(data, "DIRECTTCP") == 0)
8671 return DATA_PATH_DIRECTTCP;
8672 error(_("datapath is not AMANDA or DIRECTTCP :%s:"), data);
8677 amandaify_property_name(
8682 if (!name) return NULL;
8684 ret = g_malloc0(strlen(name)+1);
8686 for (cur_o = name; *cur_o; cur_o++) {
8690 *cur_r = g_ascii_tolower(*cur_o);
8698 static char keyword_str[1024];
8704 char *p = kt->keyword;
8705 char *s = keyword_str;