2 * Amanda, The Advanced Maryland Automatic Network Disk Archiver
3 * Copyright (c) 1991-2000 University of Maryland at College Park
6 * Permission to use, copy, modify, distribute, and sell this software and its
7 * documentation for any purpose is hereby granted without fee, provided that
8 * the above copyright notice appear in all copies and that both that
9 * copyright notice and this permission notice appear in supporting
10 * documentation, and that the name of U.M. not be used in advertising or
11 * publicity pertaining to distribution of the software without specific,
12 * written prior permission. U.M. makes no representations about the
13 * suitability of this software for any purpose. It is provided "as is"
14 * without express or implied warranty.
16 * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
18 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
20 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 * Author: James da Silva, Systems Design and Analysis Group
24 * Computer Science Department
25 * University of Maryland at College Park
28 * $Id: conffile.c,v 1.156 2006/07/26 15:17:37 martinea Exp $
30 * read configuration file
44 /* This module implements its own quixotic lexer and parser, present for historical
45 * reasons. If this were written from scratch, it would use flex/bison. */
47 /* An enumeration of the various tokens that might appear in a configuration file.
49 * - CONF_UNKNOWN has special meaning as an unrecognized token.
50 * - CONF_ANY can be used to request any token, rather than requiring a specific
54 CONF_UNKNOWN, CONF_ANY, CONF_COMMA,
55 CONF_LBRACE, CONF_RBRACE, CONF_NL,
56 CONF_END, CONF_IDENT, CONF_INT,
57 CONF_INT64, CONF_BOOL, CONF_REAL,
58 CONF_STRING, CONF_TIME, CONF_SIZE,
60 /* config parameters */
61 CONF_INCLUDEFILE, CONF_ORG, CONF_MAILTO,
62 CONF_DUMPUSER, CONF_TAPECYCLE, CONF_TAPEDEV,
63 CONF_CHANGERDEV, CONF_CHANGERFILE, CONF_LABELSTR,
64 CONF_BUMPPERCENT, CONF_BUMPSIZE, CONF_BUMPDAYS,
65 CONF_BUMPMULT, CONF_ETIMEOUT, CONF_DTIMEOUT,
66 CONF_CTIMEOUT, CONF_TAPELIST,
67 CONF_DEVICE_OUTPUT_BUFFER_SIZE,
68 CONF_DISKFILE, CONF_INFOFILE, CONF_LOGDIR,
69 CONF_LOGFILE, CONF_DISKDIR, CONF_DISKSIZE,
70 CONF_INDEXDIR, CONF_NETUSAGE, CONF_INPARALLEL,
71 CONF_DUMPORDER, CONF_TIMEOUT, CONF_TPCHANGER,
72 CONF_RUNTAPES, CONF_DEFINE, CONF_DUMPTYPE,
73 CONF_TAPETYPE, CONF_INTERFACE, CONF_PRINTER,
75 CONF_AUTOFLUSH, CONF_RESERVE, CONF_MAXDUMPSIZE,
76 CONF_COLUMNSPEC, CONF_AMRECOVER_DO_FSF, CONF_AMRECOVER_CHECK_LABEL,
77 CONF_AMRECOVER_CHANGER, CONF_LABEL_NEW_TAPES, CONF_USETIMESTAMPS,
80 CONF_TAPERALGO, CONF_FIRST, CONF_FIRSTFIT,
81 CONF_LARGEST, CONF_LARGESTFIT, CONF_SMALLEST,
82 CONF_LAST, CONF_DISPLAYUNIT, CONF_RESERVED_UDP_PORT,
83 CONF_RESERVED_TCP_PORT, CONF_UNRESERVED_TCP_PORT,
85 CONF_FLUSH_THRESHOLD_DUMPED,
86 CONF_FLUSH_THRESHOLD_SCHEDULED,
87 CONF_DEVICE_PROPERTY, CONF_PROPERTY, CONF_PLUGIN,
88 CONF_APPLICATION, CONF_APPLICATION_TOOL,
89 CONF_SCRIPT, CONF_SCRIPT_TOOL,
90 CONF_EXECUTE_ON, CONF_EXECUTE_WHERE, CONF_SEND_AMREPORT_ON,
91 CONF_DEVICE, CONF_ORDER,
92 CONF_DATA_PATH, CONF_AMANDA, CONF_DIRECTTCP,
93 CONF_TAPER_PARALLEL_WRITE,
96 CONF_PRE_DLE_AMCHECK, CONF_PRE_HOST_AMCHECK,
97 CONF_POST_DLE_AMCHECK, CONF_POST_HOST_AMCHECK,
98 CONF_PRE_DLE_ESTIMATE, CONF_PRE_HOST_ESTIMATE,
99 CONF_POST_DLE_ESTIMATE, CONF_POST_HOST_ESTIMATE,
100 CONF_PRE_DLE_BACKUP, CONF_PRE_HOST_BACKUP,
101 CONF_POST_DLE_BACKUP, CONF_POST_HOST_BACKUP,
102 CONF_PRE_RECOVER, CONF_POST_RECOVER,
103 CONF_PRE_LEVEL_RECOVER, CONF_POST_LEVEL_RECOVER,
104 CONF_INTER_LEVEL_RECOVER,
107 CONF_KRB5KEYTAB, CONF_KRB5PRINCIPAL,
110 CONF_COMMENT, CONF_DIRECTORY, CONF_USE,
114 /*COMMENT,*/ CONF_PROGRAM, CONF_DUMPCYCLE,
115 CONF_RUNSPERCYCLE, CONF_MAXCYCLE, CONF_MAXDUMPS,
116 CONF_OPTIONS, CONF_PRIORITY, CONF_FREQUENCY,
117 CONF_INDEX, CONF_MAXPROMOTEDAY, CONF_STARTTIME,
118 CONF_COMPRESS, CONF_ENCRYPT, CONF_AUTH,
119 CONF_STRATEGY, CONF_ESTIMATE, CONF_SKIP_INCR,
120 CONF_SKIP_FULL, CONF_RECORD, CONF_HOLDING,
121 CONF_EXCLUDE, CONF_INCLUDE, CONF_KENCRYPT,
122 CONF_IGNORE, CONF_COMPRATE, CONF_TAPE_SPLITSIZE,
123 CONF_SPLIT_DISKBUFFER, CONF_FALLBACK_SPLITSIZE,CONF_SRVCOMPPROG,
124 CONF_CLNTCOMPPROG, CONF_SRV_ENCRYPT, CONF_CLNT_ENCRYPT,
125 CONF_SRV_DECRYPT_OPT, CONF_CLNT_DECRYPT_OPT, CONF_AMANDAD_PATH,
126 CONF_CLIENT_USERNAME, CONF_CLIENT_PORT, CONF_ALLOW_SPLIT,
129 /*COMMENT,*/ CONF_BLOCKSIZE,
130 CONF_LBL_TEMPL, CONF_FILEMARK, CONF_LENGTH,
131 CONF_SPEED, CONF_READBLOCKSIZE,
134 CONF_CONF, CONF_INDEX_SERVER, CONF_TAPE_SERVER,
135 CONF_SSH_KEYS, CONF_GNUTAR_LIST_DIR, CONF_AMANDATES,
137 /* protocol config */
138 CONF_REP_TRIES, CONF_CONNECT_TRIES, CONF_REQ_TRIES,
142 CONF_DEBUG_AMANDAD, CONF_DEBUG_AMIDXTAPED, CONF_DEBUG_AMINDEXD,
143 CONF_DEBUG_AMRECOVER, CONF_DEBUG_AUTH, CONF_DEBUG_EVENT,
144 CONF_DEBUG_HOLDING, CONF_DEBUG_PROTOCOL, CONF_DEBUG_PLANNER,
145 CONF_DEBUG_DRIVER, CONF_DEBUG_DUMPER, CONF_DEBUG_CHUNKER,
146 CONF_DEBUG_TAPER, CONF_DEBUG_SELFCHECK, CONF_DEBUG_SENDSIZE,
147 CONF_DEBUG_SENDBACKUP, CONF_DEBUG_RECOVERY,
149 /* network interface */
150 /* COMMENT, */ /* USE, */
152 /* dump options (obsolete) */
153 CONF_EXCLUDE_FILE, CONF_EXCLUDE_LIST,
155 /* compress, estimate, encryption */
156 CONF_NONE, CONF_FAST, CONF_BEST,
157 CONF_SERVER, CONF_CLIENT, CONF_CALCSIZE,
161 CONF_AUTOLABEL, CONF_ANY_VOLUME, CONF_OTHER_CONFIG,
162 CONF_NON_AMANDA, CONF_VOLUME_ERROR, CONF_EMPTY,
164 /* part_cache_type */
165 CONF_PART_SIZE, CONF_PART_CACHE_TYPE, CONF_PART_CACHE_DIR,
166 CONF_PART_CACHE_MAX_SIZE, CONF_DISK, CONF_MEMORY,
169 CONF_RECOVERY_LIMIT, CONF_SAME_HOST,
172 CONF_NEVER, CONF_AUTO, CONF_REQUIRED,
175 CONF_ALL, CONF_STRANGE, CONF_ERROR,
178 CONF_LOW, CONF_MEDIUM, CONF_HIGH,
181 CONF_SKIP, CONF_STANDARD, CONF_NOFULL,
182 CONF_NOINC, CONF_HANOI, CONF_INCRONLY,
185 CONF_LIST, CONF_EFILE, CONF_APPEND,
189 CONF_AMINFINITY, CONF_MULT1, CONF_MULT7,
190 CONF_MULT1K, CONF_MULT1M, CONF_MULT1G,
194 CONF_ATRUE, CONF_AFALSE
197 /* A keyword table entry, mapping the given keyword to the given token.
198 * Note that punctuation, integers, and quoted strings are handled
199 * internally to the lexer, so they do not appear here. */
205 /* The current keyword table, used by all token-related functions */
206 static keytab_t *keytable = NULL;
208 /* Has a token been "ungotten", and if so, what was it? */
209 static int token_pushed;
210 static tok_t pushed_tok;
212 /* The current token and its value. Note that, unlike most other val_t*,
213 * tokenval's v.s points to statically allocated memory which cannot be
216 static val_t tokenval;
218 /* The current input information: file, filename, line, and character
219 * (which points somewhere within current_line) */
220 static FILE *current_file = NULL;
221 static char *current_filename = NULL;
222 static char *current_line = NULL;
223 static char *current_char = NULL;
224 static int current_line_num = 0; /* (technically, managed by the parser) */
226 /* A static buffer for storing tokens while they are being scanned. */
227 static char tkbuf[4096];
229 /* Return a token formated for output */
230 static char *str_keyword(keytab_t *kt);
232 static char *str_keyword(keytab_t *kt);
233 /* Look up the name of the given token in the current keytable */
234 static char *get_token_name(tok_t);
236 /* Look up a token in keytable, given a string, returning CONF_UNKNOWN
237 * for unrecognized strings. Search is case-insensitive. */
238 static tok_t lookup_keyword(char *str);
240 /* Get the next token. If exp is anything but CONF_ANY, and the next token
241 * does not match, then a parse error is flagged. This function reads from the
242 * current_* static variables, recognizes keywords against the keytable static
243 * variable, and places its result in tok and tokenval. */
244 static void get_conftoken(tok_t exp);
246 /* "Unget" the current token; this supports a 1-token lookahead. */
247 static void unget_conftoken(void);
249 /* Tokenizer character-by-character access. */
250 static int conftoken_getc(void);
251 static int conftoken_ungetc(int c);
253 static void merge_proplist_foreach_fn(gpointer key_p,
255 gpointer user_data_p);
256 static void copy_proplist_foreach_fn(gpointer key_p,
258 gpointer user_data_p);
264 /* A parser table entry. Read as "<token> introduces parameter <parm>,
265 * the data for which will be read by <read_function> and validated by
266 * <validate_function> (if not NULL). <type> is only used in formatting
267 * config overwrites. */
268 typedef struct conf_var_s {
271 void (*read_function) (struct conf_var_s *, val_t*);
273 void (*validate_function) (struct conf_var_s *, val_t *);
276 /* This is a list of filenames that are used in 'seen_t' structs. */
277 static GSList *seen_filenames = NULL;
279 /* get a copy of filename that's stored in seen_filenames so that it won't go
280 * away until config_uninit. */
281 static char *get_seen_filename(char *filename);
283 /* If allow_overwrites is true, the a parameter which has already been
284 * seen will simply overwrite the old value, rather than triggering an
285 * error. Note that this does not apply to all parameters, e.g.,
287 static int allow_overwrites;
289 /* subsection structs
291 * The 'seen' fields in these structs are useless outside this module;
292 * they are only used to generate error messages for multiply defined
296 struct tapetype_s *next;
300 val_t value[TAPETYPE_TAPETYPE];
304 struct dumptype_s *next;
308 val_t value[DUMPTYPE_DUMPTYPE];
312 struct interface_s *next;
316 val_t value[INTER_INTER];
319 struct holdingdisk_s {
323 val_t value[HOLDING_HOLDING];
326 struct application_s {
327 struct application_s *next;
331 val_t value[APPLICATION_APPLICATION];
335 struct pp_script_s *next;
339 val_t value[PP_SCRIPT_PP_SCRIPT];
342 struct device_config_s {
343 struct device_config_s *next;
347 val_t value[DEVICE_CONFIG_DEVICE_CONFIG];
350 struct changer_config_s {
351 struct changer_config_s *next;
355 val_t value[CHANGER_CONFIG_CHANGER_CONFIG];
358 /* The current parser table */
359 static conf_var_t *parsetable = NULL;
361 /* Read and parse a configuration file, recursively reading any included
362 * files. This function sets the keytable and parsetable appropriately
363 * according to is_client.
365 * @param filename: configuration file to read
366 * @param is_client: true if this is a client
367 * @param missing_ok: is it OK if the file is missing?
369 static void read_conffile(char *filename,
371 gboolean missing_ok);
373 /* Read and process a line of input from the current file, using the
374 * current keytable and parsetable. For blocks, this recursively
375 * reads the entire block.
377 * @param is_client: true if this is a client
378 * @returns: true on success, false on EOF
380 static gboolean read_confline(gboolean is_client);
382 /* Handle an invalid token, recognizing deprecated tokens as such,
383 * and producing an appropriate error message.
385 * @param token: the identifier
387 static void handle_invalid_keyword(const char * token);
389 /* Check whether token is deprecated, and issue a warning if it
390 * is. This consults the global variables 'tok' and 'tokenval'
392 static void handle_deprecated_keyword(void);
394 /* Read a brace-delimited block using the given parse table. This
395 * function is used to read brace-delimited subsections in the config
396 * files and also (via read_dumptype) to read dumptypes from
399 * This function implements "inheritance" as follows: if a bare
400 * identifier occurs within the braces, it calls copy_function (if
401 * not NULL), which looks up an existing subsection using the
402 * identifier from tokenval and copies any values not already seen
405 * @param read_var: the parse table to use
406 * @param valarray: the (pre-initialized) val_t array to fill in
407 * @param errormsg: error message to display for unrecognized keywords
408 * @param read_brace: if true, read the opening brace
409 * @param copy_function: function to copy configuration from
410 * another subsection into this one.
412 static void read_block(conf_var_t *read_var, val_t *valarray,
413 char *errormsg, int read_brace,
414 void (*copy_function)(void),
415 char *type, char *name);
417 /* For each subsection type, we have a global and four functions:
418 * - foocur is a temporary struct used to assemble new subsections
419 * - get_foo is called after reading "DEFINE FOO", and
420 * is responsible for reading the entire block, using
422 * - init_foo_defaults initializes a new subsection struct
423 * to its default values
424 * - save_foo copies foocur to a newly allocated struct and
425 * inserts that into the relevant list.
426 * - copy_foo implements inheritance as described in read_block()
428 static holdingdisk_t hdcur;
429 static void get_holdingdisk(int is_define);
430 static void init_holdingdisk_defaults(void);
431 static void save_holdingdisk(void);
432 static void copy_holdingdisk(void);
434 static dumptype_t dpcur;
435 static void get_dumptype(void);
436 static void init_dumptype_defaults(void);
437 static void save_dumptype(void);
438 static void copy_dumptype(void);
440 static tapetype_t tpcur;
441 static void get_tapetype(void);
442 static void init_tapetype_defaults(void);
443 static void save_tapetype(void);
444 static void copy_tapetype(void);
446 static interface_t ifcur;
447 static void get_interface(void);
448 static void init_interface_defaults(void);
449 static void save_interface(void);
450 static void copy_interface(void);
452 static application_t apcur;
453 static void get_application(void);
454 static void init_application_defaults(void);
455 static void save_application(void);
456 static void copy_application(void);
458 static pp_script_t pscur;
459 static void get_pp_script(void);
460 static void init_pp_script_defaults(void);
461 static void save_pp_script(void);
462 static void copy_pp_script(void);
464 static device_config_t dccur;
465 static void get_device_config(void);
466 static void init_device_config_defaults(void);
467 static void save_device_config(void);
468 static void copy_device_config(void);
470 static changer_config_t cccur;
471 static void get_changer_config(void);
472 static void init_changer_config_defaults(void);
473 static void save_changer_config(void);
474 static void copy_changer_config(void);
476 /* read_functions -- these fit into the read_function slot in a parser
477 * table entry, and are responsible for calling getconf_token as necessary
478 * to consume their arguments, and setting their second argument with the
479 * result. The first argument is a copy of the parser table entry, if
481 static void read_int(conf_var_t *, val_t *);
482 static void read_int64(conf_var_t *, val_t *);
483 static void read_real(conf_var_t *, val_t *);
484 static void read_str(conf_var_t *, val_t *);
485 static void read_ident(conf_var_t *, val_t *);
486 static void read_time(conf_var_t *, val_t *);
487 static void read_size(conf_var_t *, val_t *);
488 static void read_size_byte(conf_var_t *, val_t *);
489 static void read_bool(conf_var_t *, val_t *);
490 static void read_compress(conf_var_t *, val_t *);
491 static void read_encrypt(conf_var_t *, val_t *);
492 static void read_holding(conf_var_t *, val_t *);
493 static void read_estimatelist(conf_var_t *, val_t *);
494 static void read_strategy(conf_var_t *, val_t *);
495 static void read_taperalgo(conf_var_t *, val_t *);
496 static void read_send_amreport_on(conf_var_t *, val_t *);
497 static void read_data_path(conf_var_t *, val_t *);
498 static void read_priority(conf_var_t *, val_t *);
499 static void read_rate(conf_var_t *, val_t *);
500 static void read_exinclude(conf_var_t *, val_t *);
501 static void read_intrange(conf_var_t *, val_t *);
502 static void read_dapplication(conf_var_t *, val_t *);
503 static void read_dpp_script(conf_var_t *, val_t *);
504 static void read_property(conf_var_t *, val_t *);
505 static void read_execute_on(conf_var_t *, val_t *);
506 static void read_execute_where(conf_var_t *, val_t *);
507 static void read_holdingdisk(conf_var_t *, val_t *);
508 static void read_int_or_str(conf_var_t *, val_t *);
509 static void read_autolabel(conf_var_t *, val_t *);
510 static void read_part_cache_type(conf_var_t *, val_t *);
511 static void read_recovery_limit(conf_var_t *, val_t *);
513 /* Functions to get various types of values. These are called by
514 * read_functions to take care of any variations in the way that these
515 * values can be written: integers can have units, boolean values can be
516 * specified with a number of names, etc. They form utility functions
517 * for the read_functions, below. */
518 static time_t get_time(void);
519 static int get_int(void);
520 static ssize_t get_size(void);
521 static ssize_t get_size_byte(void);
522 static gint64 get_int64(void);
523 static int get_bool(void);
525 /* Check the given 'seen', flagging an error if this value has already
526 * been seen and allow_overwrites is false. Also marks the value as
527 * seen on the current line.
529 * @param seen: (in/out) seen value to adjust
531 static void ckseen(seen_t *seen);
533 /* validate_functions -- these fit into the validate_function solt in
534 * a parser table entry. They call conf_parserror if the value in their
535 * second argument is invalid. */
536 static void validate_nonnegative(conf_var_t *, val_t *);
537 static void validate_non_zero(conf_var_t *, val_t *);
538 static void validate_positive(conf_var_t *, val_t *);
539 static void validate_runspercycle(conf_var_t *, val_t *);
540 static void validate_bumppercent(conf_var_t *, val_t *);
541 static void validate_bumpmult(conf_var_t *, val_t *);
542 static void validate_inparallel(conf_var_t *, val_t *);
543 static void validate_displayunit(conf_var_t *, val_t *);
544 static void validate_reserve(conf_var_t *, val_t *);
545 static void validate_use(conf_var_t *, val_t *);
546 static void validate_chunksize(conf_var_t *, val_t *);
547 static void validate_blocksize(conf_var_t *, val_t *);
548 static void validate_debug(conf_var_t *, val_t *);
549 static void validate_port_range(val_t *, int, int);
550 static void validate_reserved_port_range(conf_var_t *, val_t *);
551 static void validate_unreserved_port_range(conf_var_t *, val_t *);
552 static void validate_program(conf_var_t *, val_t *);
553 gint compare_pp_script_order(gconstpointer a, gconstpointer b);
559 /* The name of the configuration under which this application is running.
560 * This variable is initialized by config_init.
562 static char *config_name = NULL;
564 /* The directory containing the configuration for this application. This
565 * variable is initialized by config_init
567 static char *config_dir = NULL;
569 /* The most recently read top-level configuration file. This variable is
570 * initialized by config_init
572 static char *config_filename = NULL;
574 /* Has the config been initialized? */
575 static gboolean config_initialized = FALSE;
577 /* Are we running a client? (true if last init was
578 * with CONFIG_INIT_CLIENT) */
579 static gboolean config_client = FALSE;
581 /* What config overwrites to use? */
582 static config_overrides_t *config_overrides = NULL;
584 /* All global parameters */
585 static val_t conf_data[CNF_CNF];
587 /* Linked list of holding disks */
588 static GSList *holdinglist = NULL;
589 static dumptype_t *dumplist = NULL;
590 static tapetype_t *tapelist = NULL;
591 static interface_t *interface_list = NULL;
592 static application_t *application_list = NULL;
593 static pp_script_t *pp_script_list = NULL;
594 static device_config_t *device_config_list = NULL;
595 static changer_config_t *changer_config_list = NULL;
597 /* storage for derived values */
598 static long int unit_divisor = 1;
600 int debug_amandad = 0;
601 int debug_recovery = 0;
602 int debug_amidxtaped = 0;
603 int debug_amindexd = 0;
604 int debug_amrecover = 0;
607 int debug_holding = 0;
608 int debug_protocol = 0;
609 int debug_planner = 0;
610 int debug_driver = 0;
611 int debug_dumper = 0;
612 int debug_chunker = 0;
614 int debug_selfcheck = 0;
615 int debug_sendsize = 0;
616 int debug_sendbackup = 0;
618 /* Reset all configuration values to their defaults (which, in many
619 * cases, come from --with-foo options at build time) */
620 static void init_defaults(void);
622 /* Update all dervied values based on the current configuration. This
623 * function can be called multiple times, once after each adjustment
624 * to the current configuration.
626 * @param is_client: are we running a client?
628 static void update_derived_values(gboolean is_client);
630 static cfgerr_level_t apply_config_overrides(config_overrides_t *co,
633 /* per-type conf_init functions, used as utilities for init_defaults
634 * and for each subsection's init_foo_defaults.
636 * These set the value's type and seen flags, as well as copying
637 * the relevant value into the 'v' field.
639 static void conf_init_int(val_t *val, int i);
640 static void conf_init_int64(val_t *val, gint64 l);
641 static void conf_init_real(val_t *val, float r);
642 static void conf_init_str(val_t *val, char *s);
643 static void conf_init_ident(val_t *val, char *s);
644 static void conf_init_identlist(val_t *val, char *s);
645 static void conf_init_time(val_t *val, time_t t);
646 static void conf_init_size(val_t *val, ssize_t sz);
647 static void conf_init_bool(val_t *val, int i);
648 static void conf_init_compress(val_t *val, comp_t i);
649 static void conf_init_encrypt(val_t *val, encrypt_t i);
650 static void conf_init_data_path(val_t *val, data_path_t i);
651 static void conf_init_holding(val_t *val, dump_holdingdisk_t i);
652 static void conf_init_estimatelist(val_t *val, estimate_t i);
653 static void conf_init_execute_on(val_t *, int);
654 static void conf_init_execute_where(val_t *, int);
655 static void conf_init_send_amreport(val_t *val, send_amreport_t i);
656 static void conf_init_strategy(val_t *val, strategy_t);
657 static void conf_init_taperalgo(val_t *val, taperalgo_t i);
658 static void conf_init_priority(val_t *val, int i);
659 static void conf_init_rate(val_t *val, float r1, float r2);
660 static void conf_init_exinclude(val_t *val); /* to empty list */
661 static void conf_init_intrange(val_t *val, int i1, int i2);
662 static void conf_init_proplist(val_t *val); /* to empty list */
663 static void conf_init_application(val_t *val);
664 static void conf_init_autolabel(val_t *val);
665 static void conf_init_part_cache_type(val_t *val, part_cache_type_t i);
666 static void conf_init_recovery_limit(val_t *val);
669 * Command-line Handling
672 typedef struct config_override_s {
678 struct config_overrides_s {
681 config_override_t *ovr;
688 static void merge_val_t(val_t *, val_t *);
689 static void copy_val_t(val_t *, val_t *);
690 static void free_val_t(val_t *);
696 /* memory handling */
697 void free_property_t(gpointer p);
699 /* Utility functions/structs for val_t_display_strs */
700 static char *exinclude_display_str(val_t *val, int file);
701 static void proplist_display_str_foreach_fn(gpointer key_p, gpointer value_p, gpointer user_data_p);
702 static void val_t_print_token(FILE *output, char *prefix, char *format, keytab_t *kt, val_t *val);
704 /* Given a key name as used in config overwrites, return a pointer to the corresponding
705 * conf_var_t in the current parsetable, and the val_t representing that value. This
706 * function will access subsections if key has the form TYPE:SUBSEC:KEYWORD. Returns
707 * false if the value does not exist.
709 * Assumes keytable and parsetable are set correctly, which is generally OK after
710 * config_init has been called.
712 * @param key: the key to look up
713 * @param parm: (result) the parse table entry
714 * @param val: (result) the parameter value
715 * @returns: true on success
717 static int parm_key_info(char *key, conf_var_t **parm, val_t **val);
723 /* Have we seen a parse error yet? Parsing continues after an error, so this
724 * flag is checked after the parse is complete.
726 static cfgerr_level_t cfgerr_level;
727 static GSList *cfgerr_errors = NULL;
729 static void conf_error_common(cfgerr_level_t level, const char * format, va_list argp);
730 static void conf_parserror(const char *format, ...)
731 __attribute__ ((format (printf, 1, 2)));
733 static void conf_parswarn(const char *format, ...)
734 __attribute__ ((format (printf, 1, 2)));
740 /* First, the keyword tables for client and server */
741 keytab_t client_keytab[] = {
742 { "CONF", CONF_CONF },
743 { "INDEX_SERVER", CONF_INDEX_SERVER },
744 { "TAPE_SERVER", CONF_TAPE_SERVER },
745 { "TAPEDEV", CONF_TAPEDEV },
746 { "AUTH", CONF_AUTH },
747 { "SSH_KEYS", CONF_SSH_KEYS },
748 { "AMANDAD_PATH", CONF_AMANDAD_PATH },
749 { "CLIENT_USERNAME", CONF_CLIENT_USERNAME },
750 { "CLIENT_PORT", CONF_CLIENT_PORT },
751 { "GNUTAR_LIST_DIR", CONF_GNUTAR_LIST_DIR },
752 { "AMANDATES", CONF_AMANDATES },
753 { "KRB5KEYTAB", CONF_KRB5KEYTAB },
754 { "KRB5PRINCIPAL", CONF_KRB5PRINCIPAL },
755 { "INCLUDEFILE", CONF_INCLUDEFILE },
756 { "CONNECT_TRIES", CONF_CONNECT_TRIES },
757 { "REP_TRIES", CONF_REP_TRIES },
758 { "REQ_TRIES", CONF_REQ_TRIES },
759 { "CLIENT", CONF_CLIENT },
760 { "DEBUG_DAYS", CONF_DEBUG_DAYS },
761 { "DEBUG_AMANDAD", CONF_DEBUG_AMANDAD },
762 { "DEBUG_RECOVERY", CONF_DEBUG_RECOVERY },
763 { "DEBUG_AMIDXTAPED", CONF_DEBUG_AMIDXTAPED },
764 { "DEBUG_AMINDEXD", CONF_DEBUG_AMINDEXD },
765 { "DEBUG_AMRECOVER", CONF_DEBUG_AMRECOVER },
766 { "DEBUG_AUTH", CONF_DEBUG_AUTH },
767 { "DEBUG_EVENT", CONF_DEBUG_EVENT },
768 { "DEBUG_HOLDING", CONF_DEBUG_HOLDING },
769 { "DEBUG_PROTOCOL", CONF_DEBUG_PROTOCOL },
770 { "DEBUG_PLANNER", CONF_DEBUG_PLANNER },
771 { "DEBUG_DRIVER", CONF_DEBUG_DRIVER },
772 { "DEBUG_DUMPER", CONF_DEBUG_DUMPER },
773 { "DEBUG_CHUNKER", CONF_DEBUG_CHUNKER },
774 { "DEBUG_TAPER", CONF_DEBUG_TAPER },
775 { "DEBUG_SELFCHECK", CONF_DEBUG_SELFCHECK },
776 { "DEBUG_SENDSIZE", CONF_DEBUG_SENDSIZE },
777 { "DEBUG_SENDBACKUP", CONF_DEBUG_SENDBACKUP },
778 { "EXECUTE_ON", CONF_EXECUTE_ON },
779 { "EXECUTE_WHERE", CONF_EXECUTE_WHERE },
780 { "RESERVED_UDP_PORT", CONF_RESERVED_UDP_PORT },
781 { "RESERVED_TCP_PORT", CONF_RESERVED_TCP_PORT },
782 { "UNRESERVED_TCP_PORT", CONF_UNRESERVED_TCP_PORT },
783 { "DEFINE", CONF_DEFINE },
784 { "COMMENT", CONF_COMMENT },
785 { "MAILER", CONF_MAILER },
786 { "ORDER", CONF_ORDER },
787 { "SCRIPT", CONF_SCRIPT },
788 { "SCRIPT_TOOL", CONF_SCRIPT_TOOL },
789 { "PLUGIN", CONF_PLUGIN },
790 { "PRE_DLE_AMCHECK", CONF_PRE_DLE_AMCHECK },
791 { "PRE_HOST_AMCHECK", CONF_PRE_HOST_AMCHECK },
792 { "POST_DLE_AMCHECK", CONF_POST_DLE_AMCHECK },
793 { "POST_HOST_AMCHECK", CONF_POST_HOST_AMCHECK },
794 { "PRE_DLE_ESTIMATE", CONF_PRE_DLE_ESTIMATE },
795 { "PRE_HOST_ESTIMATE", CONF_PRE_HOST_ESTIMATE },
796 { "POST_DLE_ESTIMATE", CONF_POST_DLE_ESTIMATE },
797 { "POST_HOST_ESTIMATE", CONF_POST_HOST_ESTIMATE },
798 { "POST_DLE_BACKUP", CONF_POST_DLE_BACKUP },
799 { "POST_HOST_BACKUP", CONF_POST_HOST_BACKUP },
800 { "PRE_DLE_BACKUP", CONF_PRE_DLE_BACKUP },
801 { "PRE_HOST_BACKUP", CONF_PRE_HOST_BACKUP },
802 { "PRE_RECOVER", CONF_PRE_RECOVER },
803 { "POST_RECOVER", CONF_POST_RECOVER },
804 { "PRE_LEVEL_RECOVER", CONF_PRE_LEVEL_RECOVER },
805 { "POST_LEVEL_RECOVER", CONF_POST_LEVEL_RECOVER },
806 { "INTER_LEVEL_RECOVER", CONF_INTER_LEVEL_RECOVER },
807 { "PRIORITY", CONF_PRIORITY },
808 { "PROPERTY", CONF_PROPERTY },
809 { "APPLICATION", CONF_APPLICATION },
810 { "APPLICATION_TOOL", CONF_APPLICATION_TOOL },
811 { "SERVER", CONF_SERVER },
812 { "APPEND", CONF_APPEND },
813 { NULL, CONF_IDENT },
814 { NULL, CONF_UNKNOWN }
817 keytab_t server_keytab[] = {
819 { "ALLOW_SPLIT", CONF_ALLOW_SPLIT },
820 { "AMANDA", CONF_AMANDA },
821 { "AMANDAD_PATH", CONF_AMANDAD_PATH },
822 { "AMRECOVER_CHANGER", CONF_AMRECOVER_CHANGER },
823 { "AMRECOVER_CHECK_LABEL", CONF_AMRECOVER_CHECK_LABEL },
824 { "AMRECOVER_DO_FSF", CONF_AMRECOVER_DO_FSF },
825 { "ANY", CONF_ANY_VOLUME },
826 { "APPEND", CONF_APPEND },
827 { "AUTH", CONF_AUTH },
828 { "AUTO", CONF_AUTO },
829 { "AUTOFLUSH", CONF_AUTOFLUSH },
830 { "AUTOLABEL", CONF_AUTOLABEL },
831 { "APPLICATION", CONF_APPLICATION },
832 { "APPLICATION_TOOL", CONF_APPLICATION_TOOL },
833 { "BEST", CONF_BEST },
834 { "BLOCKSIZE", CONF_BLOCKSIZE },
835 { "BUMPDAYS", CONF_BUMPDAYS },
836 { "BUMPMULT", CONF_BUMPMULT },
837 { "BUMPPERCENT", CONF_BUMPPERCENT },
838 { "BUMPSIZE", CONF_BUMPSIZE },
839 { "CALCSIZE", CONF_CALCSIZE },
840 { "CHANGER", CONF_CHANGER },
841 { "CHANGERDEV", CONF_CHANGERDEV },
842 { "CHANGERFILE", CONF_CHANGERFILE },
843 { "CHUNKSIZE", CONF_CHUNKSIZE },
844 { "CLIENT", CONF_CLIENT },
845 { "CLIENT_CUSTOM_COMPRESS", CONF_CLNTCOMPPROG },
846 { "CLIENT_DECRYPT_OPTION", CONF_CLNT_DECRYPT_OPT },
847 { "CLIENT_ENCRYPT", CONF_CLNT_ENCRYPT },
848 { "CLIENT_USERNAME", CONF_CLIENT_USERNAME },
849 { "COLUMNSPEC", CONF_COLUMNSPEC },
850 { "COMMENT", CONF_COMMENT },
851 { "COMPRATE", CONF_COMPRATE },
852 { "COMPRESS", CONF_COMPRESS },
853 { "CONNECT_TRIES", CONF_CONNECT_TRIES },
854 { "CTIMEOUT", CONF_CTIMEOUT },
855 { "CUSTOM", CONF_CUSTOM },
856 { "DATA_PATH", CONF_DATA_PATH },
857 { "DEBUG_DAYS" , CONF_DEBUG_DAYS },
858 { "DEBUG_AMANDAD" , CONF_DEBUG_AMANDAD },
859 { "DEBUG_RECOVERY" , CONF_DEBUG_RECOVERY },
860 { "DEBUG_AMIDXTAPED" , CONF_DEBUG_AMIDXTAPED },
861 { "DEBUG_AMINDEXD" , CONF_DEBUG_AMINDEXD },
862 { "DEBUG_AMRECOVER" , CONF_DEBUG_AMRECOVER },
863 { "DEBUG_AUTH" , CONF_DEBUG_AUTH },
864 { "DEBUG_EVENT" , CONF_DEBUG_EVENT },
865 { "DEBUG_HOLDING" , CONF_DEBUG_HOLDING },
866 { "DEBUG_PROTOCOL" , CONF_DEBUG_PROTOCOL },
867 { "DEBUG_PLANNER" , CONF_DEBUG_PLANNER },
868 { "DEBUG_DRIVER" , CONF_DEBUG_DRIVER },
869 { "DEBUG_DUMPER" , CONF_DEBUG_DUMPER },
870 { "DEBUG_CHUNKER" , CONF_DEBUG_CHUNKER },
871 { "DEBUG_TAPER" , CONF_DEBUG_TAPER },
872 { "DEBUG_SELFCHECK" , CONF_DEBUG_SELFCHECK },
873 { "DEBUG_SENDSIZE" , CONF_DEBUG_SENDSIZE },
874 { "DEBUG_SENDBACKUP" , CONF_DEBUG_SENDBACKUP },
875 { "DEFINE", CONF_DEFINE },
876 { "DEVICE", CONF_DEVICE },
877 { "DEVICE_PROPERTY", CONF_DEVICE_PROPERTY },
878 { "DIRECTORY", CONF_DIRECTORY },
879 { "DIRECTTCP", CONF_DIRECTTCP },
880 { "DISK", CONF_DISK },
881 { "DISKFILE", CONF_DISKFILE },
882 { "DISPLAYUNIT", CONF_DISPLAYUNIT },
883 { "DTIMEOUT", CONF_DTIMEOUT },
884 { "DUMPCYCLE", CONF_DUMPCYCLE },
885 { "DUMPORDER", CONF_DUMPORDER },
886 { "DUMPTYPE", CONF_DUMPTYPE },
887 { "DUMPUSER", CONF_DUMPUSER },
888 { "EMPTY", CONF_EMPTY },
889 { "ENCRYPT", CONF_ENCRYPT },
890 { "ERROR", CONF_ERROR },
891 { "ESTIMATE", CONF_ESTIMATE },
892 { "ETIMEOUT", CONF_ETIMEOUT },
893 { "EXCLUDE", CONF_EXCLUDE },
894 { "EXCLUDE_FILE", CONF_EXCLUDE_FILE },
895 { "EXCLUDE_LIST", CONF_EXCLUDE_LIST },
896 { "EXECUTE_ON", CONF_EXECUTE_ON },
897 { "EXECUTE_WHERE", CONF_EXECUTE_WHERE },
898 { "FALLBACK_SPLITSIZE", CONF_FALLBACK_SPLITSIZE },
899 { "FAST", CONF_FAST },
900 { "FILE", CONF_EFILE },
901 { "FILEMARK", CONF_FILEMARK },
902 { "FIRST", CONF_FIRST },
903 { "FIRSTFIT", CONF_FIRSTFIT },
904 { "HANOI", CONF_HANOI },
905 { "HIGH", CONF_HIGH },
906 { "HOLDINGDISK", CONF_HOLDING },
907 { "IGNORE", CONF_IGNORE },
908 { "INCLUDE", CONF_INCLUDE },
909 { "INCLUDEFILE", CONF_INCLUDEFILE },
910 { "INCRONLY", CONF_INCRONLY },
911 { "INDEX", CONF_INDEX },
912 { "INDEXDIR", CONF_INDEXDIR },
913 { "INFOFILE", CONF_INFOFILE },
914 { "INPARALLEL", CONF_INPARALLEL },
915 { "INTERFACE", CONF_INTERFACE },
916 { "KENCRYPT", CONF_KENCRYPT },
917 { "KRB5KEYTAB", CONF_KRB5KEYTAB },
918 { "KRB5PRINCIPAL", CONF_KRB5PRINCIPAL },
919 { "LABELSTR", CONF_LABELSTR },
920 { "LABEL_NEW_TAPES", CONF_LABEL_NEW_TAPES },
921 { "LARGEST", CONF_LARGEST },
922 { "LARGESTFIT", CONF_LARGESTFIT },
923 { "LAST", CONF_LAST },
924 { "LBL_TEMPL", CONF_LBL_TEMPL },
925 { "LENGTH", CONF_LENGTH },
926 { "LIST", CONF_LIST },
927 { "LOGDIR", CONF_LOGDIR },
929 { "MAILER", CONF_MAILER },
930 { "MAILTO", CONF_MAILTO },
931 { "READBLOCKSIZE", CONF_READBLOCKSIZE },
932 { "MAXDUMPS", CONF_MAXDUMPS },
933 { "MAXDUMPSIZE", CONF_MAXDUMPSIZE },
934 { "MAXPROMOTEDAY", CONF_MAXPROMOTEDAY },
935 { "MEMORY", CONF_MEMORY },
936 { "MEDIUM", CONF_MEDIUM },
937 { "NETUSAGE", CONF_NETUSAGE },
938 { "NEVER", CONF_NEVER },
939 { "NOFULL", CONF_NOFULL },
940 { "NOINC", CONF_NOINC },
941 { "NONE", CONF_NONE },
942 { "NON_AMANDA", CONF_NON_AMANDA },
943 { "OPTIONAL", CONF_OPTIONAL },
944 { "ORDER", CONF_ORDER },
946 { "OTHER_CONFIG", CONF_OTHER_CONFIG },
947 { "PART_CACHE_DIR", CONF_PART_CACHE_DIR },
948 { "PART_CACHE_MAX_SIZE", CONF_PART_CACHE_MAX_SIZE },
949 { "PART_CACHE_TYPE", CONF_PART_CACHE_TYPE },
950 { "PART_SIZE", CONF_PART_SIZE },
951 { "PLUGIN", CONF_PLUGIN },
952 { "PRE_DLE_AMCHECK", CONF_PRE_DLE_AMCHECK },
953 { "PRE_HOST_AMCHECK", CONF_PRE_HOST_AMCHECK },
954 { "POST_DLE_AMCHECK", CONF_POST_DLE_AMCHECK },
955 { "POST_HOST_AMCHECK", CONF_POST_HOST_AMCHECK },
956 { "PRE_DLE_ESTIMATE", CONF_PRE_DLE_ESTIMATE },
957 { "PRE_HOST_ESTIMATE", CONF_PRE_HOST_ESTIMATE },
958 { "POST_DLE_ESTIMATE", CONF_POST_DLE_ESTIMATE },
959 { "POST_HOST_ESTIMATE", CONF_POST_HOST_ESTIMATE },
960 { "POST_DLE_BACKUP", CONF_POST_DLE_BACKUP },
961 { "POST_HOST_BACKUP", CONF_POST_HOST_BACKUP },
962 { "PRE_DLE_BACKUP", CONF_PRE_DLE_BACKUP },
963 { "PRE_HOST_BACKUP", CONF_PRE_HOST_BACKUP },
964 { "PRE_RECOVER", CONF_PRE_RECOVER },
965 { "POST_RECOVER", CONF_POST_RECOVER },
966 { "PRE_LEVEL_RECOVER", CONF_PRE_LEVEL_RECOVER },
967 { "POST_LEVEL_RECOVER", CONF_POST_LEVEL_RECOVER },
968 { "INTER_LEVEL_RECOVER", CONF_INTER_LEVEL_RECOVER },
969 { "PRINTER", CONF_PRINTER },
970 { "PRIORITY", CONF_PRIORITY },
971 { "PROGRAM", CONF_PROGRAM },
972 { "PROPERTY", CONF_PROPERTY },
973 { "RECORD", CONF_RECORD },
974 { "RECOVERY_LIMIT", CONF_RECOVERY_LIMIT },
975 { "REP_TRIES", CONF_REP_TRIES },
976 { "REQ_TRIES", CONF_REQ_TRIES },
977 { "REQUIRED", CONF_REQUIRED },
978 { "RESERVE", CONF_RESERVE },
979 { "RESERVED_UDP_PORT", CONF_RESERVED_UDP_PORT },
980 { "RESERVED_TCP_PORT", CONF_RESERVED_TCP_PORT },
981 { "RUNSPERCYCLE", CONF_RUNSPERCYCLE },
982 { "RUNTAPES", CONF_RUNTAPES },
983 { "SAME_HOST", CONF_SAME_HOST },
984 { "SCRIPT", CONF_SCRIPT },
985 { "SCRIPT_TOOL", CONF_SCRIPT_TOOL },
986 { "SEND_AMREPORT_ON", CONF_SEND_AMREPORT_ON },
987 { "CLIENT_PORT", CONF_CLIENT_PORT },
988 { "SERVER", CONF_SERVER },
989 { "SERVER_CUSTOM_COMPRESS", CONF_SRVCOMPPROG },
990 { "SERVER_DECRYPT_OPTION", CONF_SRV_DECRYPT_OPT },
991 { "SERVER_ENCRYPT", CONF_SRV_ENCRYPT },
992 { "SKIP", CONF_SKIP },
993 { "SKIP_FULL", CONF_SKIP_FULL },
994 { "SKIP_INCR", CONF_SKIP_INCR },
995 { "SMALLEST", CONF_SMALLEST },
996 { "SPEED", CONF_SPEED },
997 { "SPLIT_DISKBUFFER", CONF_SPLIT_DISKBUFFER },
998 { "SSH_KEYS", CONF_SSH_KEYS },
999 { "STANDARD", CONF_STANDARD },
1000 { "STARTTIME", CONF_STARTTIME },
1001 { "STRANGE", CONF_STRANGE },
1002 { "STRATEGY", CONF_STRATEGY },
1003 { "DEVICE_OUTPUT_BUFFER_SIZE", CONF_DEVICE_OUTPUT_BUFFER_SIZE },
1004 { "TAPECYCLE", CONF_TAPECYCLE },
1005 { "TAPEDEV", CONF_TAPEDEV },
1006 { "TAPELIST", CONF_TAPELIST },
1007 { "TAPERALGO", CONF_TAPERALGO },
1008 { "TAPER_PARALLEL_WRITE", CONF_TAPER_PARALLEL_WRITE },
1009 { "FLUSH_THRESHOLD_DUMPED", CONF_FLUSH_THRESHOLD_DUMPED },
1010 { "FLUSH_THRESHOLD_SCHEDULED", CONF_FLUSH_THRESHOLD_SCHEDULED },
1011 { "TAPERFLUSH", CONF_TAPERFLUSH },
1012 { "TAPETYPE", CONF_TAPETYPE },
1013 { "TAPE_SPLITSIZE", CONF_TAPE_SPLITSIZE },
1014 { "TPCHANGER", CONF_TPCHANGER },
1015 { "UNRESERVED_TCP_PORT", CONF_UNRESERVED_TCP_PORT },
1016 { "USE", CONF_USE },
1017 { "USETIMESTAMPS", CONF_USETIMESTAMPS },
1018 { "VOLUME_ERROR", CONF_VOLUME_ERROR },
1019 { NULL, CONF_IDENT },
1020 { NULL, CONF_UNKNOWN }
1023 /* A keyword table for recognizing unit suffixes. No distinction is made for kinds
1024 * of suffixes: 1024 weeks = 7 k. */
1025 keytab_t numb_keytable[] = {
1026 { "B", CONF_MULT1 },
1027 { "BPS", CONF_MULT1 },
1028 { "BYTE", CONF_MULT1 },
1029 { "BYTES", CONF_MULT1 },
1030 { "DAY", CONF_MULT1 },
1031 { "DAYS", CONF_MULT1 },
1032 { "INF", CONF_AMINFINITY },
1033 { "K", CONF_MULT1K },
1034 { "KB", CONF_MULT1K },
1035 { "KBPS", CONF_MULT1K },
1036 { "KBYTE", CONF_MULT1K },
1037 { "KBYTES", CONF_MULT1K },
1038 { "KILOBYTE", CONF_MULT1K },
1039 { "KILOBYTES", CONF_MULT1K },
1040 { "KPS", CONF_MULT1K },
1041 { "M", CONF_MULT1M },
1042 { "MB", CONF_MULT1M },
1043 { "MBPS", CONF_MULT1M },
1044 { "MBYTE", CONF_MULT1M },
1045 { "MBYTES", CONF_MULT1M },
1046 { "MEG", CONF_MULT1M },
1047 { "MEGABYTE", CONF_MULT1M },
1048 { "MEGABYTES", CONF_MULT1M },
1049 { "G", CONF_MULT1G },
1050 { "GB", CONF_MULT1G },
1051 { "GBPS", CONF_MULT1G },
1052 { "GBYTE", CONF_MULT1G },
1053 { "GBYTES", CONF_MULT1G },
1054 { "GIG", CONF_MULT1G },
1055 { "GIGABYTE", CONF_MULT1G },
1056 { "GIGABYTES", CONF_MULT1G },
1057 { "T", CONF_MULT1T },
1058 { "TB", CONF_MULT1T },
1059 { "TBPS", CONF_MULT1T },
1060 { "TBYTE", CONF_MULT1T },
1061 { "TBYTES", CONF_MULT1T },
1062 { "TERA", CONF_MULT1T },
1063 { "TERABYTE", CONF_MULT1T },
1064 { "TERABYTES", CONF_MULT1T },
1065 { "MPS", CONF_MULT1M },
1066 { "TAPE", CONF_MULT1 },
1067 { "TAPES", CONF_MULT1 },
1068 { "WEEK", CONF_MULT7 },
1069 { "WEEKS", CONF_MULT7 },
1070 { NULL, CONF_IDENT }
1073 /* Boolean keywords -- all the ways to say "true" and "false" in amanda.conf */
1074 keytab_t bool_keytable[] = {
1075 { "Y", CONF_ATRUE },
1076 { "YES", CONF_ATRUE },
1077 { "T", CONF_ATRUE },
1078 { "TRUE", CONF_ATRUE },
1079 { "ON", CONF_ATRUE },
1080 { "N", CONF_AFALSE },
1081 { "NO", CONF_AFALSE },
1082 { "F", CONF_AFALSE },
1083 { "FALSE", CONF_AFALSE },
1084 { "OFF", CONF_AFALSE },
1085 { NULL, CONF_IDENT }
1088 /* Now, the parser tables for client and server global parameters, and for
1089 * each of the server subsections */
1090 conf_var_t client_var [] = {
1091 { CONF_CONF , CONFTYPE_STR , read_str , CNF_CONF , NULL },
1092 { CONF_INDEX_SERVER , CONFTYPE_STR , read_str , CNF_INDEX_SERVER , NULL },
1093 { CONF_TAPE_SERVER , CONFTYPE_STR , read_str , CNF_TAPE_SERVER , NULL },
1094 { CONF_TAPEDEV , CONFTYPE_STR , read_str , CNF_TAPEDEV , NULL },
1095 { CONF_AUTH , CONFTYPE_STR , read_str , CNF_AUTH , NULL },
1096 { CONF_SSH_KEYS , CONFTYPE_STR , read_str , CNF_SSH_KEYS , NULL },
1097 { CONF_AMANDAD_PATH , CONFTYPE_STR , read_str , CNF_AMANDAD_PATH , NULL },
1098 { CONF_CLIENT_USERNAME , CONFTYPE_STR , read_str , CNF_CLIENT_USERNAME , NULL },
1099 { CONF_CLIENT_PORT , CONFTYPE_STR , read_int_or_str, CNF_CLIENT_PORT , NULL },
1100 { CONF_GNUTAR_LIST_DIR , CONFTYPE_STR , read_str , CNF_GNUTAR_LIST_DIR , NULL },
1101 { CONF_AMANDATES , CONFTYPE_STR , read_str , CNF_AMANDATES , NULL },
1102 { CONF_MAILER , CONFTYPE_STR , read_str , CNF_MAILER , NULL },
1103 { CONF_KRB5KEYTAB , CONFTYPE_STR , read_str , CNF_KRB5KEYTAB , NULL },
1104 { CONF_KRB5PRINCIPAL , CONFTYPE_STR , read_str , CNF_KRB5PRINCIPAL , NULL },
1105 { CONF_CONNECT_TRIES , CONFTYPE_INT , read_int , CNF_CONNECT_TRIES , validate_positive },
1106 { CONF_REP_TRIES , CONFTYPE_INT , read_int , CNF_REP_TRIES , validate_positive },
1107 { CONF_REQ_TRIES , CONFTYPE_INT , read_int , CNF_REQ_TRIES , validate_positive },
1108 { CONF_DEBUG_DAYS , CONFTYPE_INT , read_int , CNF_DEBUG_DAYS , NULL },
1109 { CONF_DEBUG_AMANDAD , CONFTYPE_INT , read_int , CNF_DEBUG_AMANDAD , validate_debug },
1110 { CONF_DEBUG_RECOVERY , CONFTYPE_INT , read_int , CNF_DEBUG_RECOVERY , validate_debug },
1111 { CONF_DEBUG_AMIDXTAPED , CONFTYPE_INT , read_int , CNF_DEBUG_AMIDXTAPED , validate_debug },
1112 { CONF_DEBUG_AMINDEXD , CONFTYPE_INT , read_int , CNF_DEBUG_AMINDEXD , validate_debug },
1113 { CONF_DEBUG_AMRECOVER , CONFTYPE_INT , read_int , CNF_DEBUG_AMRECOVER , validate_debug },
1114 { CONF_DEBUG_AUTH , CONFTYPE_INT , read_int , CNF_DEBUG_AUTH , validate_debug },
1115 { CONF_DEBUG_EVENT , CONFTYPE_INT , read_int , CNF_DEBUG_EVENT , validate_debug },
1116 { CONF_DEBUG_HOLDING , CONFTYPE_INT , read_int , CNF_DEBUG_HOLDING , validate_debug },
1117 { CONF_DEBUG_PROTOCOL , CONFTYPE_INT , read_int , CNF_DEBUG_PROTOCOL , validate_debug },
1118 { CONF_DEBUG_PLANNER , CONFTYPE_INT , read_int , CNF_DEBUG_PLANNER , validate_debug },
1119 { CONF_DEBUG_DRIVER , CONFTYPE_INT , read_int , CNF_DEBUG_DRIVER , validate_debug },
1120 { CONF_DEBUG_DUMPER , CONFTYPE_INT , read_int , CNF_DEBUG_DUMPER , validate_debug },
1121 { CONF_DEBUG_CHUNKER , CONFTYPE_INT , read_int , CNF_DEBUG_CHUNKER , validate_debug },
1122 { CONF_DEBUG_TAPER , CONFTYPE_INT , read_int , CNF_DEBUG_TAPER , validate_debug },
1123 { CONF_DEBUG_SELFCHECK , CONFTYPE_INT , read_int , CNF_DEBUG_SELFCHECK , validate_debug },
1124 { CONF_DEBUG_SENDSIZE , CONFTYPE_INT , read_int , CNF_DEBUG_SENDSIZE , validate_debug },
1125 { CONF_DEBUG_SENDBACKUP , CONFTYPE_INT , read_int , CNF_DEBUG_SENDBACKUP , validate_debug },
1126 { CONF_RESERVED_UDP_PORT , CONFTYPE_INTRANGE, read_intrange, CNF_RESERVED_UDP_PORT , validate_reserved_port_range },
1127 { CONF_RESERVED_TCP_PORT , CONFTYPE_INTRANGE, read_intrange, CNF_RESERVED_TCP_PORT , validate_reserved_port_range },
1128 { CONF_UNRESERVED_TCP_PORT, CONFTYPE_INTRANGE, read_intrange, CNF_UNRESERVED_TCP_PORT, validate_unreserved_port_range },
1129 { CONF_PROPERTY , CONFTYPE_PROPLIST, read_property, CNF_PROPERTY , NULL },
1130 { CONF_APPLICATION , CONFTYPE_STR , read_dapplication, DUMPTYPE_APPLICATION, NULL },
1131 { CONF_SCRIPT , CONFTYPE_STR , read_dpp_script, DUMPTYPE_SCRIPTLIST, NULL },
1132 { CONF_UNKNOWN , CONFTYPE_INT , NULL , CNF_CNF , NULL }
1135 conf_var_t server_var [] = {
1136 { CONF_ORG , CONFTYPE_STR , read_str , CNF_ORG , NULL },
1137 { CONF_MAILTO , CONFTYPE_STR , read_str , CNF_MAILTO , NULL },
1138 { CONF_DUMPUSER , CONFTYPE_STR , read_str , CNF_DUMPUSER , NULL },
1139 { CONF_PRINTER , CONFTYPE_STR , read_str , CNF_PRINTER , NULL },
1140 { CONF_MAILER , CONFTYPE_STR , read_str , CNF_MAILER , NULL },
1141 { CONF_TAPEDEV , CONFTYPE_STR , read_str , CNF_TAPEDEV , NULL },
1142 { CONF_DEVICE_PROPERTY , CONFTYPE_PROPLIST , read_property , CNF_DEVICE_PROPERTY , NULL },
1143 { CONF_PROPERTY , CONFTYPE_PROPLIST , read_property , CNF_PROPERTY , NULL },
1144 { CONF_TPCHANGER , CONFTYPE_STR , read_str , CNF_TPCHANGER , NULL },
1145 { CONF_CHANGERDEV , CONFTYPE_STR , read_str , CNF_CHANGERDEV , NULL },
1146 { CONF_CHANGERFILE , CONFTYPE_STR , read_str , CNF_CHANGERFILE , NULL },
1147 { CONF_LABELSTR , CONFTYPE_STR , read_str , CNF_LABELSTR , NULL },
1148 { CONF_TAPELIST , CONFTYPE_STR , read_str , CNF_TAPELIST , NULL },
1149 { CONF_DISKFILE , CONFTYPE_STR , read_str , CNF_DISKFILE , NULL },
1150 { CONF_INFOFILE , CONFTYPE_STR , read_str , CNF_INFOFILE , NULL },
1151 { CONF_LOGDIR , CONFTYPE_STR , read_str , CNF_LOGDIR , NULL },
1152 { CONF_INDEXDIR , CONFTYPE_STR , read_str , CNF_INDEXDIR , NULL },
1153 { CONF_TAPETYPE , CONFTYPE_IDENT , read_ident , CNF_TAPETYPE , NULL },
1154 { CONF_HOLDING , CONFTYPE_IDENTLIST, read_holdingdisk , CNF_HOLDINGDISK , NULL },
1155 { CONF_DUMPCYCLE , CONFTYPE_INT , read_int , CNF_DUMPCYCLE , validate_nonnegative },
1156 { CONF_RUNSPERCYCLE , CONFTYPE_INT , read_int , CNF_RUNSPERCYCLE , validate_runspercycle },
1157 { CONF_RUNTAPES , CONFTYPE_INT , read_int , CNF_RUNTAPES , validate_nonnegative },
1158 { CONF_TAPECYCLE , CONFTYPE_INT , read_int , CNF_TAPECYCLE , validate_positive },
1159 { CONF_BUMPDAYS , CONFTYPE_INT , read_int , CNF_BUMPDAYS , validate_positive },
1160 { CONF_BUMPSIZE , CONFTYPE_INT64 , read_int64 , CNF_BUMPSIZE , validate_positive },
1161 { CONF_BUMPPERCENT , CONFTYPE_INT , read_int , CNF_BUMPPERCENT , validate_bumppercent },
1162 { CONF_BUMPMULT , CONFTYPE_REAL , read_real , CNF_BUMPMULT , validate_bumpmult },
1163 { CONF_NETUSAGE , CONFTYPE_INT , read_int , CNF_NETUSAGE , validate_positive },
1164 { CONF_INPARALLEL , CONFTYPE_INT , read_int , CNF_INPARALLEL , validate_inparallel },
1165 { CONF_DUMPORDER , CONFTYPE_STR , read_str , CNF_DUMPORDER , NULL },
1166 { CONF_MAXDUMPS , CONFTYPE_INT , read_int , CNF_MAXDUMPS , validate_positive },
1167 { CONF_ETIMEOUT , CONFTYPE_INT , read_int , CNF_ETIMEOUT , validate_non_zero },
1168 { CONF_DTIMEOUT , CONFTYPE_INT , read_int , CNF_DTIMEOUT , validate_positive },
1169 { CONF_CTIMEOUT , CONFTYPE_INT , read_int , CNF_CTIMEOUT , validate_positive },
1170 { CONF_DEVICE_OUTPUT_BUFFER_SIZE, CONFTYPE_SIZE , read_size_byte , CNF_DEVICE_OUTPUT_BUFFER_SIZE, validate_positive },
1171 { CONF_COLUMNSPEC , CONFTYPE_STR , read_str , CNF_COLUMNSPEC , NULL },
1172 { CONF_TAPERALGO , CONFTYPE_TAPERALGO, read_taperalgo , CNF_TAPERALGO , NULL },
1173 { CONF_TAPER_PARALLEL_WRITE , CONFTYPE_INT , read_int , CNF_TAPER_PARALLEL_WRITE , NULL },
1174 { CONF_SEND_AMREPORT_ON , CONFTYPE_SEND_AMREPORT_ON, read_send_amreport_on, CNF_SEND_AMREPORT_ON , NULL },
1175 { CONF_FLUSH_THRESHOLD_DUMPED, CONFTYPE_INT , read_int , CNF_FLUSH_THRESHOLD_DUMPED, validate_nonnegative },
1176 { CONF_FLUSH_THRESHOLD_SCHEDULED, CONFTYPE_INT , read_int , CNF_FLUSH_THRESHOLD_SCHEDULED, validate_nonnegative },
1177 { CONF_TAPERFLUSH , CONFTYPE_INT , read_int , CNF_TAPERFLUSH , validate_nonnegative },
1178 { CONF_DISPLAYUNIT , CONFTYPE_STR , read_str , CNF_DISPLAYUNIT , validate_displayunit },
1179 { CONF_AUTOFLUSH , CONFTYPE_BOOLEAN , read_bool , CNF_AUTOFLUSH , NULL },
1180 { CONF_RESERVE , CONFTYPE_INT , read_int , CNF_RESERVE , validate_reserve },
1181 { CONF_MAXDUMPSIZE , CONFTYPE_INT64 , read_int64 , CNF_MAXDUMPSIZE , NULL },
1182 { CONF_KRB5KEYTAB , CONFTYPE_STR , read_str , CNF_KRB5KEYTAB , NULL },
1183 { CONF_KRB5PRINCIPAL , CONFTYPE_STR , read_str , CNF_KRB5PRINCIPAL , NULL },
1184 { CONF_LABEL_NEW_TAPES , CONFTYPE_STR , read_str , CNF_LABEL_NEW_TAPES , NULL },
1185 { CONF_AUTOLABEL , CONFTYPE_AUTOLABEL, read_autolabel , CNF_AUTOLABEL , NULL },
1186 { CONF_USETIMESTAMPS , CONFTYPE_BOOLEAN , read_bool , CNF_USETIMESTAMPS , NULL },
1187 { CONF_AMRECOVER_DO_FSF , CONFTYPE_BOOLEAN , read_bool , CNF_AMRECOVER_DO_FSF , NULL },
1188 { CONF_AMRECOVER_CHANGER , CONFTYPE_STR , read_str , CNF_AMRECOVER_CHANGER , NULL },
1189 { CONF_AMRECOVER_CHECK_LABEL, CONFTYPE_BOOLEAN , read_bool , CNF_AMRECOVER_CHECK_LABEL, NULL },
1190 { CONF_CONNECT_TRIES , CONFTYPE_INT , read_int , CNF_CONNECT_TRIES , validate_positive },
1191 { CONF_REP_TRIES , CONFTYPE_INT , read_int , CNF_REP_TRIES , validate_positive },
1192 { CONF_REQ_TRIES , CONFTYPE_INT , read_int , CNF_REQ_TRIES , validate_positive },
1193 { CONF_DEBUG_DAYS , CONFTYPE_INT , read_int , CNF_DEBUG_DAYS , NULL },
1194 { CONF_DEBUG_AMANDAD , CONFTYPE_INT , read_int , CNF_DEBUG_AMANDAD , validate_debug },
1195 { CONF_DEBUG_RECOVERY , CONFTYPE_INT , read_int , CNF_DEBUG_RECOVERY , validate_debug },
1196 { CONF_DEBUG_AMIDXTAPED , CONFTYPE_INT , read_int , CNF_DEBUG_AMIDXTAPED , validate_debug },
1197 { CONF_DEBUG_AMINDEXD , CONFTYPE_INT , read_int , CNF_DEBUG_AMINDEXD , validate_debug },
1198 { CONF_DEBUG_AMRECOVER , CONFTYPE_INT , read_int , CNF_DEBUG_AMRECOVER , validate_debug },
1199 { CONF_DEBUG_AUTH , CONFTYPE_INT , read_int , CNF_DEBUG_AUTH , validate_debug },
1200 { CONF_DEBUG_EVENT , CONFTYPE_INT , read_int , CNF_DEBUG_EVENT , validate_debug },
1201 { CONF_DEBUG_HOLDING , CONFTYPE_INT , read_int , CNF_DEBUG_HOLDING , validate_debug },
1202 { CONF_DEBUG_PROTOCOL , CONFTYPE_INT , read_int , CNF_DEBUG_PROTOCOL , validate_debug },
1203 { CONF_DEBUG_PLANNER , CONFTYPE_INT , read_int , CNF_DEBUG_PLANNER , validate_debug },
1204 { CONF_DEBUG_DRIVER , CONFTYPE_INT , read_int , CNF_DEBUG_DRIVER , validate_debug },
1205 { CONF_DEBUG_DUMPER , CONFTYPE_INT , read_int , CNF_DEBUG_DUMPER , validate_debug },
1206 { CONF_DEBUG_CHUNKER , CONFTYPE_INT , read_int , CNF_DEBUG_CHUNKER , validate_debug },
1207 { CONF_DEBUG_TAPER , CONFTYPE_INT , read_int , CNF_DEBUG_TAPER , validate_debug },
1208 { CONF_DEBUG_SELFCHECK , CONFTYPE_INT , read_int , CNF_DEBUG_SELFCHECK , validate_debug },
1209 { CONF_DEBUG_SENDSIZE , CONFTYPE_INT , read_int , CNF_DEBUG_SENDSIZE , validate_debug },
1210 { CONF_DEBUG_SENDBACKUP , CONFTYPE_INT , read_int , CNF_DEBUG_SENDBACKUP , validate_debug },
1211 { CONF_RESERVED_UDP_PORT , CONFTYPE_INTRANGE , read_intrange , CNF_RESERVED_UDP_PORT , validate_reserved_port_range },
1212 { CONF_RESERVED_TCP_PORT , CONFTYPE_INTRANGE , read_intrange , CNF_RESERVED_TCP_PORT , validate_reserved_port_range },
1213 { CONF_UNRESERVED_TCP_PORT , CONFTYPE_INTRANGE , read_intrange , CNF_UNRESERVED_TCP_PORT , validate_unreserved_port_range },
1214 { CONF_RECOVERY_LIMIT , CONFTYPE_RECOVERY_LIMIT, read_recovery_limit, CNF_RECOVERY_LIMIT, NULL },
1215 { CONF_UNKNOWN , CONFTYPE_INT , NULL , CNF_CNF , NULL }
1218 conf_var_t tapetype_var [] = {
1219 { CONF_COMMENT , CONFTYPE_STR , read_str , TAPETYPE_COMMENT , NULL },
1220 { CONF_LBL_TEMPL , CONFTYPE_STR , read_str , TAPETYPE_LBL_TEMPL , NULL },
1221 { CONF_BLOCKSIZE , CONFTYPE_SIZE , read_size , TAPETYPE_BLOCKSIZE , validate_blocksize },
1222 { CONF_READBLOCKSIZE , CONFTYPE_SIZE , read_size , TAPETYPE_READBLOCKSIZE , validate_blocksize },
1223 { CONF_LENGTH , CONFTYPE_INT64 , read_int64 , TAPETYPE_LENGTH , validate_nonnegative },
1224 { CONF_FILEMARK , CONFTYPE_INT64 , read_int64 , TAPETYPE_FILEMARK , NULL },
1225 { CONF_SPEED , CONFTYPE_INT , read_int , TAPETYPE_SPEED , validate_nonnegative },
1226 { CONF_PART_SIZE , CONFTYPE_INT64 , read_int64 , TAPETYPE_PART_SIZE , validate_nonnegative },
1227 { CONF_PART_CACHE_TYPE , CONFTYPE_PART_CACHE_TYPE, read_part_cache_type, TAPETYPE_PART_CACHE_TYPE, NULL },
1228 { CONF_PART_CACHE_DIR , CONFTYPE_STR , read_str , TAPETYPE_PART_CACHE_DIR , NULL },
1229 { CONF_PART_CACHE_MAX_SIZE , CONFTYPE_INT64 , read_int64 , TAPETYPE_PART_CACHE_MAX_SIZE, validate_nonnegative },
1230 { CONF_UNKNOWN , CONFTYPE_INT , NULL , TAPETYPE_TAPETYPE , NULL }
1233 conf_var_t dumptype_var [] = {
1234 { CONF_COMMENT , CONFTYPE_STR , read_str , DUMPTYPE_COMMENT , NULL },
1235 { CONF_AUTH , CONFTYPE_STR , read_str , DUMPTYPE_AUTH , NULL },
1236 { CONF_BUMPDAYS , CONFTYPE_INT , read_int , DUMPTYPE_BUMPDAYS , NULL },
1237 { CONF_BUMPMULT , CONFTYPE_REAL , read_real , DUMPTYPE_BUMPMULT , NULL },
1238 { CONF_BUMPSIZE , CONFTYPE_INT64 , read_int64 , DUMPTYPE_BUMPSIZE , NULL },
1239 { CONF_BUMPPERCENT , CONFTYPE_INT , read_int , DUMPTYPE_BUMPPERCENT , NULL },
1240 { CONF_COMPRATE , CONFTYPE_REAL , read_rate , DUMPTYPE_COMPRATE , NULL },
1241 { CONF_COMPRESS , CONFTYPE_INT , read_compress , DUMPTYPE_COMPRESS , NULL },
1242 { CONF_ENCRYPT , CONFTYPE_INT , read_encrypt , DUMPTYPE_ENCRYPT , NULL },
1243 { CONF_DUMPCYCLE , CONFTYPE_INT , read_int , DUMPTYPE_DUMPCYCLE , validate_nonnegative },
1244 { CONF_EXCLUDE , CONFTYPE_EXINCLUDE, read_exinclude, DUMPTYPE_EXCLUDE , NULL },
1245 { CONF_INCLUDE , CONFTYPE_EXINCLUDE, read_exinclude, DUMPTYPE_INCLUDE , NULL },
1246 { CONF_IGNORE , CONFTYPE_BOOLEAN , read_bool , DUMPTYPE_IGNORE , NULL },
1247 { CONF_HOLDING , CONFTYPE_HOLDING , read_holding , DUMPTYPE_HOLDINGDISK , NULL },
1248 { CONF_INDEX , CONFTYPE_BOOLEAN , read_bool , DUMPTYPE_INDEX , NULL },
1249 { CONF_KENCRYPT , CONFTYPE_BOOLEAN , read_bool , DUMPTYPE_KENCRYPT , NULL },
1250 { CONF_MAXDUMPS , CONFTYPE_INT , read_int , DUMPTYPE_MAXDUMPS , validate_positive },
1251 { CONF_MAXPROMOTEDAY , CONFTYPE_INT , read_int , DUMPTYPE_MAXPROMOTEDAY , validate_nonnegative },
1252 { CONF_PRIORITY , CONFTYPE_PRIORITY , read_priority , DUMPTYPE_PRIORITY , NULL },
1253 { CONF_PROGRAM , CONFTYPE_STR , read_str , DUMPTYPE_PROGRAM , validate_program },
1254 { CONF_PROPERTY , CONFTYPE_PROPLIST , read_property , DUMPTYPE_PROPERTY , NULL },
1255 { CONF_RECORD , CONFTYPE_BOOLEAN , read_bool , DUMPTYPE_RECORD , NULL },
1256 { CONF_SKIP_FULL , CONFTYPE_BOOLEAN , read_bool , DUMPTYPE_SKIP_FULL , NULL },
1257 { CONF_SKIP_INCR , CONFTYPE_BOOLEAN , read_bool , DUMPTYPE_SKIP_INCR , NULL },
1258 { CONF_STARTTIME , CONFTYPE_TIME , read_time , DUMPTYPE_STARTTIME , NULL },
1259 { CONF_STRATEGY , CONFTYPE_INT , read_strategy , DUMPTYPE_STRATEGY , NULL },
1260 { CONF_TAPE_SPLITSIZE , CONFTYPE_INT64 , read_int64 , DUMPTYPE_TAPE_SPLITSIZE , validate_nonnegative },
1261 { CONF_SPLIT_DISKBUFFER , CONFTYPE_STR , read_str , DUMPTYPE_SPLIT_DISKBUFFER , NULL },
1262 { CONF_ESTIMATE , CONFTYPE_ESTIMATELIST, read_estimatelist , DUMPTYPE_ESTIMATELIST , NULL },
1263 { CONF_SRV_ENCRYPT , CONFTYPE_STR , read_str , DUMPTYPE_SRV_ENCRYPT , NULL },
1264 { CONF_CLNT_ENCRYPT , CONFTYPE_STR , read_str , DUMPTYPE_CLNT_ENCRYPT , NULL },
1265 { CONF_AMANDAD_PATH , CONFTYPE_STR , read_str , DUMPTYPE_AMANDAD_PATH , NULL },
1266 { CONF_CLIENT_USERNAME , CONFTYPE_STR , read_str , DUMPTYPE_CLIENT_USERNAME , NULL },
1267 { CONF_CLIENT_PORT , CONFTYPE_STR , read_int_or_str, DUMPTYPE_CLIENT_PORT , NULL },
1268 { CONF_SSH_KEYS , CONFTYPE_STR , read_str , DUMPTYPE_SSH_KEYS , NULL },
1269 { CONF_SRVCOMPPROG , CONFTYPE_STR , read_str , DUMPTYPE_SRVCOMPPROG , NULL },
1270 { CONF_CLNTCOMPPROG , CONFTYPE_STR , read_str , DUMPTYPE_CLNTCOMPPROG , NULL },
1271 { CONF_FALLBACK_SPLITSIZE, CONFTYPE_INT64 , read_int64 , DUMPTYPE_FALLBACK_SPLITSIZE, NULL },
1272 { CONF_SRV_DECRYPT_OPT , CONFTYPE_STR , read_str , DUMPTYPE_SRV_DECRYPT_OPT , NULL },
1273 { CONF_CLNT_DECRYPT_OPT , CONFTYPE_STR , read_str , DUMPTYPE_CLNT_DECRYPT_OPT , NULL },
1274 { CONF_APPLICATION , CONFTYPE_STR , read_dapplication, DUMPTYPE_APPLICATION , NULL },
1275 { CONF_SCRIPT , CONFTYPE_STR , read_dpp_script, DUMPTYPE_SCRIPTLIST , NULL },
1276 { CONF_DATA_PATH , CONFTYPE_DATA_PATH, read_data_path, DUMPTYPE_DATA_PATH , NULL },
1277 { CONF_ALLOW_SPLIT , CONFTYPE_BOOLEAN , read_bool , DUMPTYPE_ALLOW_SPLIT , NULL },
1278 { CONF_RECOVERY_LIMIT , CONFTYPE_RECOVERY_LIMIT, read_recovery_limit, DUMPTYPE_RECOVERY_LIMIT, NULL },
1279 { CONF_UNKNOWN , CONFTYPE_INT , NULL , DUMPTYPE_DUMPTYPE , NULL }
1282 conf_var_t holding_var [] = {
1283 { CONF_DIRECTORY, CONFTYPE_STR , read_str , HOLDING_DISKDIR , NULL },
1284 { CONF_COMMENT , CONFTYPE_STR , read_str , HOLDING_COMMENT , NULL },
1285 { CONF_USE , CONFTYPE_INT64 , read_int64 , HOLDING_DISKSIZE , validate_use },
1286 { CONF_CHUNKSIZE, CONFTYPE_INT64 , read_int64 , HOLDING_CHUNKSIZE, validate_chunksize },
1287 { CONF_UNKNOWN , CONFTYPE_INT , NULL , HOLDING_HOLDING , NULL }
1290 conf_var_t interface_var [] = {
1291 { CONF_COMMENT, CONFTYPE_STR , read_str , INTER_COMMENT , NULL },
1292 { CONF_USE , CONFTYPE_INT , read_int , INTER_MAXUSAGE, validate_positive },
1293 { CONF_UNKNOWN, CONFTYPE_INT , NULL , INTER_INTER , NULL }
1297 conf_var_t application_var [] = {
1298 { CONF_COMMENT , CONFTYPE_STR , read_str , APPLICATION_COMMENT , NULL },
1299 { CONF_PLUGIN , CONFTYPE_STR , read_str , APPLICATION_PLUGIN , NULL },
1300 { CONF_PROPERTY , CONFTYPE_PROPLIST, read_property, APPLICATION_PROPERTY , NULL },
1301 { CONF_UNKNOWN , CONFTYPE_INT , NULL , APPLICATION_APPLICATION, NULL }
1304 conf_var_t pp_script_var [] = {
1305 { CONF_COMMENT , CONFTYPE_STR , read_str , PP_SCRIPT_COMMENT , NULL },
1306 { CONF_PLUGIN , CONFTYPE_STR , read_str , PP_SCRIPT_PLUGIN , NULL },
1307 { CONF_PROPERTY , CONFTYPE_PROPLIST, read_property, PP_SCRIPT_PROPERTY , NULL },
1308 { CONF_EXECUTE_ON , CONFTYPE_EXECUTE_ON , read_execute_on , PP_SCRIPT_EXECUTE_ON , NULL },
1309 { CONF_EXECUTE_WHERE, CONFTYPE_EXECUTE_WHERE , read_execute_where , PP_SCRIPT_EXECUTE_WHERE, NULL },
1310 { CONF_ORDER , CONFTYPE_INT , read_int , PP_SCRIPT_ORDER , NULL },
1311 { CONF_UNKNOWN , CONFTYPE_INT , NULL , PP_SCRIPT_PP_SCRIPT , NULL }
1314 conf_var_t device_config_var [] = {
1315 { CONF_COMMENT , CONFTYPE_STR , read_str , DEVICE_CONFIG_COMMENT , NULL },
1316 { CONF_DEVICE_PROPERTY , CONFTYPE_PROPLIST , read_property , DEVICE_CONFIG_DEVICE_PROPERTY, NULL },
1317 { CONF_TAPEDEV , CONFTYPE_STR , read_str , DEVICE_CONFIG_TAPEDEV , NULL },
1318 { CONF_UNKNOWN , CONFTYPE_INT , NULL , DEVICE_CONFIG_DEVICE_CONFIG , NULL }
1321 conf_var_t changer_config_var [] = {
1322 { CONF_COMMENT , CONFTYPE_STR , read_str , CHANGER_CONFIG_COMMENT , NULL },
1323 { CONF_TAPEDEV , CONFTYPE_STR , read_str , CHANGER_CONFIG_TAPEDEV , NULL },
1324 { CONF_TPCHANGER , CONFTYPE_STR , read_str , CHANGER_CONFIG_TPCHANGER , NULL },
1325 { CONF_CHANGERDEV , CONFTYPE_STR , read_str , CHANGER_CONFIG_CHANGERDEV , NULL },
1326 { CONF_CHANGERFILE , CONFTYPE_STR , read_str , CHANGER_CONFIG_CHANGERFILE , NULL },
1327 { CONF_PROPERTY , CONFTYPE_PROPLIST , read_property , CHANGER_CONFIG_PROPERTY , NULL },
1328 { CONF_DEVICE_PROPERTY , CONFTYPE_PROPLIST , read_property , CHANGER_CONFIG_DEVICE_PROPERTY, NULL },
1329 { CONF_UNKNOWN , CONFTYPE_INT , NULL , CHANGER_CONFIG_CHANGER_CONFIG , NULL }
1333 * Lexical Analysis Implementation
1342 if (keytable == NULL) {
1343 error(_("keytable == NULL"));
1347 for(kt = keytable; kt->token != CONF_UNKNOWN; kt++)
1348 if(kt->token == token) break;
1350 if(kt->token == CONF_UNKNOWN)
1352 return(kt->keyword);
1360 char *str1 = stralloc(str);
1363 /* Fold '-' to '_' in the token. Note that this modifies str1
1366 if (*p == '-') *p = '_';
1370 for(kwp = keytable; kwp->keyword != NULL; kwp++) {
1371 if (strcasecmp(kwp->keyword, str1) == 0) break;
1396 ** If it looked like a keyword before then look it
1397 ** up again in the current keyword table.
1400 case CONF_INT64: case CONF_SIZE:
1401 case CONF_INT: case CONF_REAL: case CONF_STRING:
1402 case CONF_LBRACE: case CONF_RBRACE: case CONF_COMMA:
1403 case CONF_NL: case CONF_END: case CONF_UNKNOWN:
1405 break; /* not a keyword */
1408 if (exp == CONF_IDENT)
1411 tok = lookup_keyword(tokenval.v.s);
1416 ch = conftoken_getc();
1418 /* note that we're explicitly assuming this file is ASCII. Someday
1419 * maybe we'll support UTF-8? */
1420 while(ch != EOF && ch != '\n' && g_ascii_isspace(ch))
1421 ch = conftoken_getc();
1422 if (ch == '#') { /* comment - eat everything but eol/eof */
1423 while((ch = conftoken_getc()) != EOF && ch != '\n') {
1424 (void)ch; /* Quiet empty loop complaints */
1428 if (isalpha(ch)) { /* identifier */
1432 if (buf < tkbuf+sizeof(tkbuf)-1) {
1436 if (!token_overflow) {
1437 conf_parserror(_("token too long: %.20s..."), tkbuf);
1441 ch = conftoken_getc();
1442 } while(isalnum(ch) || ch == '_' || ch == '-');
1444 if (ch != EOF && conftoken_ungetc(ch) == EOF) {
1445 if (ferror(current_file)) {
1446 conf_parserror(_("Pushback of '%c' failed: %s"),
1447 ch, strerror(ferror(current_file)));
1449 conf_parserror(_("Pushback of '%c' failed: EOF"), ch);
1454 tokenval.v.s = tkbuf;
1456 if (token_overflow) tok = CONF_UNKNOWN;
1457 else if (exp == CONF_IDENT) tok = CONF_IDENT;
1458 else tok = lookup_keyword(tokenval.v.s);
1460 else if (isdigit(ch)) { /* integer */
1463 negative_number: /* look for goto negative_number below sign is set there */
1466 int64 = int64 * 10 + (ch - '0');
1467 ch = conftoken_getc();
1468 } while (isdigit(ch));
1471 if (exp == CONF_INT) {
1473 tokenval.v.i = sign * (int)int64;
1474 } else if (exp != CONF_REAL) {
1476 tokenval.v.int64 = (gint64)sign * int64;
1478 /* automatically convert to real when expected */
1479 tokenval.v.r = (double)sign * (double)int64;
1483 /* got a real number, not an int */
1484 tokenval.v.r = sign * (double) int64;
1487 ch = conftoken_getc();
1488 while (isdigit(ch)) {
1489 int64 = int64 * 10 + (ch - '0');
1491 ch = conftoken_getc();
1493 tokenval.v.r += sign * ((double)int64) / d;
1497 if (ch != EOF && conftoken_ungetc(ch) == EOF) {
1498 if (ferror(current_file)) {
1499 conf_parserror(_("Pushback of '%c' failed: %s"),
1500 ch, strerror(ferror(current_file)));
1502 conf_parserror(_("Pushback of '%c' failed: EOF"), ch);
1506 case '"': /* string */
1511 while (inquote && ((ch = conftoken_getc()) != EOF)) {
1516 buf--; /* Consume escape in buffer */
1517 } else if (ch == '\\' && !escape) {
1527 if(buf >= &tkbuf[sizeof(tkbuf) - 1]) {
1528 if (!token_overflow) {
1529 conf_parserror(_("string too long: %.20s..."), tkbuf);
1539 * A little manuver to leave a fully unquoted, unallocated string
1542 tmps = unquote_string(tkbuf);
1543 strncpy(tkbuf, tmps, sizeof(tkbuf));
1545 tokenval.v.s = tkbuf;
1547 tok = (token_overflow) ? CONF_UNKNOWN :
1548 (exp == CONF_IDENT) ? CONF_IDENT : CONF_STRING;
1552 ch = conftoken_getc();
1555 goto negative_number;
1558 if (ch != EOF && conftoken_ungetc(ch) == EOF) {
1559 if (ferror(current_file)) {
1560 conf_parserror(_("Pushback of '%c' failed: %s"),
1561 ch, strerror(ferror(current_file)));
1563 conf_parserror(_("Pushback of '%c' failed: EOF"), ch);
1596 if (exp != CONF_ANY && tok != exp) {
1614 str = _("end of line");
1618 str = _("end of file");
1622 str = _("an integer");
1626 str = _("a real number");
1630 str = _("a quoted string");
1634 str = _("an identifier");
1638 for(kwp = keytable; kwp->keyword != NULL; kwp++) {
1639 if (exp == kwp->token)
1642 if (kwp->keyword == NULL)
1643 str = _("token not");
1645 str = str_keyword(kwp);
1648 conf_parserror(_("%s is expected"), str);
1650 if (tok == CONF_INT)
1658 unget_conftoken(void)
1660 assert(!token_pushed);
1667 conftoken_getc(void)
1669 if(current_line == NULL)
1670 return getc(current_file);
1671 if(*current_char == '\0')
1673 return(*current_char++);
1680 if(current_line == NULL)
1681 return ungetc(c, current_file);
1682 else if(current_char > current_line) {
1686 if(*current_char != c) {
1687 error(_("*current_char != c : %c %c"), *current_char, c);
1691 error(_("current_char == current_line"));
1698 * Parser Implementation
1705 gboolean missing_ok)
1707 /* Save global locations. */
1708 FILE *save_file = current_file;
1709 char *save_filename = current_filename;
1710 int save_line_num = current_line_num;
1714 keytable = client_keytab;
1715 parsetable = client_var;
1717 keytable = server_keytab;
1718 parsetable = server_var;
1720 filename = config_dir_relative(filename);
1721 current_filename = get_seen_filename(filename);
1724 if ((current_file = fopen(current_filename, "r")) == NULL) {
1726 conf_parserror(_("could not open conf file \"%s\": %s"),
1727 current_filename, strerror(errno));
1731 current_line_num = 0;
1734 /* read_confline() can invoke us recursively via "includefile" */
1735 rc = read_confline(is_client);
1738 afclose(current_file);
1742 /* Restore servers */
1743 current_line_num = save_line_num;
1744 current_file = save_file;
1745 current_filename = save_filename;
1754 current_line_num += 1;
1755 get_conftoken(CONF_ANY);
1756 handle_deprecated_keyword();
1759 case CONF_INCLUDEFILE:
1760 get_conftoken(CONF_STRING);
1761 read_conffile(tokenval.v.s, is_client, FALSE);
1766 get_conftoken(CONF_ANY);
1767 /* accept application-tool here, too, for backward compatibility */
1768 if(tok == CONF_APPLICATION_TOOL || tok == CONF_APPLICATION) get_application();
1769 else if(tok == CONF_SCRIPT_TOOL || tok == CONF_SCRIPT) get_pp_script();
1770 else conf_parserror(_("APPLICATION-TOOL or SCRIPT-TOOL expected"));
1772 get_conftoken(CONF_ANY);
1773 if(tok == CONF_DUMPTYPE) get_dumptype();
1774 else if(tok == CONF_TAPETYPE) get_tapetype();
1775 else if(tok == CONF_INTERFACE) get_interface();
1776 else if(tok == CONF_APPLICATION_TOOL || tok == CONF_APPLICATION) get_application();
1777 else if(tok == CONF_SCRIPT_TOOL || tok == CONF_SCRIPT) get_pp_script();
1778 else if(tok == CONF_DEVICE) get_device_config();
1779 else if(tok == CONF_CHANGER) get_changer_config();
1780 else if(tok == CONF_HOLDING) get_holdingdisk(1);
1781 else conf_parserror(_("DUMPTYPE, INTERFACE, TAPETYPE, HOLDINGDISK, APPLICATION-TOOL, SCRIPT-TOOL, DEVICE, or CHANGER expected"));
1785 case CONF_NL: /* empty line */
1788 case CONF_END: /* end of file */
1791 /* if it's not a known punctuation mark, then check the parse table and use the
1792 * read_function we find there. */
1795 for(np = parsetable; np->token != CONF_UNKNOWN; np++)
1796 if(np->token == tok) break;
1798 if(np->token == CONF_UNKNOWN) {
1799 handle_invalid_keyword(tokenval.v.s);
1801 np->read_function(np, &conf_data[np->parm]);
1802 if(np->validate_function)
1803 np->validate_function(np, &conf_data[np->parm]);
1808 get_conftoken(CONF_NL);
1813 handle_deprecated_keyword(void)
1815 /* Procedure for deprecated keywords:
1817 * 1) At time of deprecation, add to warning_deprecated below. Note the
1818 * version in which deprecation will expire. The keyword will still be
1819 * parsed, and can still be used from other parts of Amanda, during this
1821 * 2) After it has expired, move the keyword (as a string) to
1822 * error_deprecated below. Remove the token (CONF_XXX) and
1823 * config parameter (CNF_XXX) from the rest of the module.
1824 * Note the date of the move.
1827 static struct { tok_t tok; gboolean warned; }
1828 warning_deprecated[] = {
1829 { CONF_LABEL_NEW_TAPES, 0 }, /* exp in Amanda-3.2 */
1830 { CONF_AMRECOVER_DO_FSF, 0 }, /* exp in Amanda-3.3 */
1831 { CONF_AMRECOVER_CHECK_LABEL, 0 }, /* exp in Amanda-3.3 */
1832 { CONF_TAPE_SPLITSIZE, 0 }, /* exp. in Amanda-3.3 */
1833 { CONF_SPLIT_DISKBUFFER, 0 }, /* exp. in Amanda-3.3 */
1834 { CONF_FALLBACK_SPLITSIZE, 0 }, /* exp. in Amanda-3.3 */
1838 for (dep = warning_deprecated; dep->tok; dep++) {
1839 if (tok == dep->tok) {
1841 conf_parswarn(_("warning: Keyword %s is deprecated."),
1850 handle_invalid_keyword(
1853 static const char * error_deprecated[] = {
1855 "tapebufs", /* deprecated: 2007-10-15; invalid: 2010-04-14 */
1856 "file-pad", /* deprecated: 2008-07-01; invalid: 2010-04-14 */
1860 char *folded_token, *p;
1862 /* convert '_' to '-' in TOKEN */
1863 folded_token = g_strdup(token);
1864 for (p = folded_token; *p; p++) {
1865 if (*p == '_') *p = '-';
1868 for (s = error_deprecated; *s != NULL; s ++) {
1869 if (g_ascii_strcasecmp(*s, folded_token) == 0) {
1870 conf_parserror(_("error: Keyword %s is deprecated."),
1872 g_free(folded_token);
1876 g_free(folded_token);
1879 conf_parserror(_("configuration keyword expected"));
1883 char c = conftoken_getc();
1884 if (c == '\n' || c == -1) {
1885 conftoken_ungetc(c);
1890 g_assert_not_reached();
1900 for (iter = seen_filenames; iter; iter = iter->next) {
1902 if (istr == filename || 0 == strcmp(istr, filename))
1906 istr = stralloc(filename);
1907 seen_filenames = g_slist_prepend(seen_filenames, istr);
1913 conf_var_t *read_var,
1917 void (*copy_function)(void),
1927 get_conftoken(CONF_LBRACE);
1928 get_conftoken(CONF_NL);
1933 current_line_num += 1;
1934 get_conftoken(CONF_ANY);
1935 handle_deprecated_keyword();
1941 case CONF_NL: /* empty line */
1943 case CONF_END: /* end of file */
1947 /* inherit from a "parent" */
1953 conf_parserror(_("ident not expected"));
1957 for(np = read_var; np->token != CONF_UNKNOWN; np++)
1958 if(np->token == tok) break;
1960 if(np->token == CONF_UNKNOWN)
1961 conf_parserror("%s", errormsg);
1963 np->read_function(np, &valarray[np->parm]);
1964 if(np->validate_function)
1965 np->validate_function(np, &valarray[np->parm]);
1969 if(tok != CONF_NL && tok != CONF_END && tok != CONF_RBRACE)
1970 get_conftoken(CONF_NL);
1973 if (!config_overrides)
1976 key_ovr = vstralloc(type, ":", name, NULL);
1977 for (i = 0; i < config_overrides->n_used; i++) {
1978 config_override_t *co = &config_overrides->ovr[i];
1979 char *key = co->key;
1984 if (key_ovr && strncasecmp(key_ovr, key, strlen(key_ovr)) != 0)
1987 if (strlen(key) <= strlen(key_ovr) + 1)
1990 keyword = key + strlen(key_ovr) + 1;
1993 /* find the token in keytable */
1994 for (kt = keytable; kt->token != CONF_UNKNOWN; kt++) {
1995 if (kt->keyword && strcasecmp(kt->keyword, keyword) == 0)
1998 if (kt->token == CONF_UNKNOWN)
2001 /* find the var in read_var */
2002 for (np = read_var; np->token != CONF_UNKNOWN; np++)
2003 if (np->token == kt->token) break;
2004 if (np->token == CONF_UNKNOWN)
2007 /* now set up a fake line and use the relevant read_function to
2008 * parse it. This is sneaky! */
2009 if (np->type == CONFTYPE_STR) {
2010 current_line = quote_string_always(value);
2012 current_line = stralloc(value);
2015 current_char = current_line;
2017 current_line_num = -2;
2018 allow_overwrites = 1;
2021 np->read_function(np, &valarray[np->parm]);
2022 if (np->validate_function)
2023 np->validate_function(np, &valarray[np->parm]);
2025 amfree(current_line);
2026 current_char = NULL;
2034 conf_var_t *np G_GNUC_UNUSED,
2035 val_t *val G_GNUC_UNUSED)
2037 assert (val == &conf_data[CNF_HOLDINGDISK]);
2045 int save_overwrites;
2047 save_overwrites = allow_overwrites;
2048 allow_overwrites = 1;
2050 init_holdingdisk_defaults();
2052 get_conftoken(CONF_IDENT);
2053 hdcur.name = stralloc(tokenval.v.s);
2054 hdcur.seen.filename = current_filename;
2055 hdcur.seen.linenum = current_line_num;
2057 get_conftoken(CONF_ANY);
2058 if (tok == CONF_LBRACE) {
2060 hd = lookup_holdingdisk(hdcur.name);
2062 conf_parserror(_("holding disk '%s' already defined"),
2066 read_block(holding_var, hdcur.value,
2067 _("holding disk parameter expected"), 1, copy_holdingdisk,
2068 "HOLDINGDISK", hdcur.name);
2069 get_conftoken(CONF_NL);
2072 conf_data[CNF_HOLDINGDISK].v.identlist = g_slist_append(
2073 conf_data[CNF_HOLDINGDISK].v.identlist,
2074 stralloc(hdcur.name));
2077 } else { /* use the already defined holding disk */
2080 conf_parserror(_("holdingdisk definition must specify holdingdisk parameters"));
2085 for (il = conf_data[CNF_HOLDINGDISK].v.identlist; il != NULL;
2087 if (strcmp((char *)il->data, hdcur.name) == 0) {
2092 conf_parserror(_("holding disk '%s' already in use"),
2095 conf_data[CNF_HOLDINGDISK].v.identlist = g_slist_append(
2096 conf_data[CNF_HOLDINGDISK].v.identlist,
2097 stralloc(hdcur.name));
2100 get_conftoken(CONF_ANY);
2101 if (tok == CONF_IDENT || tok == CONF_STRING) {
2102 hdcur.name = stralloc(tokenval.v.s);
2103 } else if (tok != CONF_NL) {
2104 conf_parserror(_("IDENT or NL expected"));
2106 } while (tok == CONF_IDENT || tok == CONF_STRING);
2109 allow_overwrites = save_overwrites;
2113 init_holdingdisk_defaults(
2116 conf_init_str(&hdcur.value[HOLDING_COMMENT] , "");
2117 conf_init_str(&hdcur.value[HOLDING_DISKDIR] , "");
2118 conf_init_int64(&hdcur.value[HOLDING_DISKSIZE] , (gint64)0);
2119 /* 1 Gb = 1M counted in 1Kb blocks */
2120 conf_init_int64(&hdcur.value[HOLDING_CHUNKSIZE], (gint64)1024*1024);
2129 hp = alloc(sizeof(holdingdisk_t));
2131 holdinglist = g_slist_append(holdinglist, hp);
2141 hp = lookup_holdingdisk(tokenval.v.s);
2144 conf_parserror(_("holdingdisk parameter expected"));
2148 for(i=0; i < HOLDING_HOLDING; i++) {
2149 if(hp->value[i].seen.linenum) {
2150 merge_val_t(&hdcur.value[i], &hp->value[i]);
2158 * This function is called both from this module and from diskfile.c. Modify
2167 int save_overwrites;
2168 FILE *saved_conf = NULL;
2169 char *saved_fname = NULL;
2172 saved_conf = current_file;
2173 current_file = from;
2177 saved_fname = current_filename;
2178 current_filename = get_seen_filename(fname);
2182 current_line_num = *linenum;
2184 save_overwrites = allow_overwrites;
2185 allow_overwrites = 1;
2187 init_dumptype_defaults();
2191 get_conftoken(CONF_IDENT);
2192 dpcur.name = stralloc(tokenval.v.s);
2194 dpcur.seen.filename = current_filename;
2195 dpcur.seen.linenum = current_line_num;
2197 read_block(dumptype_var, dpcur.value,
2198 _("dumptype parameter expected"),
2199 (name == NULL), copy_dumptype,
2200 "DUMPTYPE", dpcur.name);
2202 if(!name) /* !name => reading disklist, not conffile */
2203 get_conftoken(CONF_NL);
2205 /* XXX - there was a stupidity check in here for skip-incr and
2206 ** skip-full. This check should probably be somewhere else. */
2210 allow_overwrites = save_overwrites;
2213 *linenum = current_line_num;
2216 current_filename = saved_fname;
2219 current_file = saved_conf;
2221 return lookup_dumptype(dpcur.name);
2227 read_dumptype(NULL, NULL, NULL, NULL);
2231 init_dumptype_defaults(void)
2234 conf_init_str (&dpcur.value[DUMPTYPE_COMMENT] , "");
2235 conf_init_str (&dpcur.value[DUMPTYPE_PROGRAM] , "DUMP");
2236 conf_init_str (&dpcur.value[DUMPTYPE_SRVCOMPPROG] , "");
2237 conf_init_str (&dpcur.value[DUMPTYPE_CLNTCOMPPROG] , "");
2238 conf_init_str (&dpcur.value[DUMPTYPE_SRV_ENCRYPT] , "");
2239 conf_init_str (&dpcur.value[DUMPTYPE_CLNT_ENCRYPT] , "");
2240 conf_init_str (&dpcur.value[DUMPTYPE_AMANDAD_PATH] , "");
2241 conf_init_str (&dpcur.value[DUMPTYPE_CLIENT_USERNAME] , "");
2242 conf_init_str (&dpcur.value[DUMPTYPE_CLIENT_PORT] , "");
2243 conf_init_str (&dpcur.value[DUMPTYPE_SSH_KEYS] , "");
2244 conf_init_str (&dpcur.value[DUMPTYPE_AUTH] , "BSD");
2245 conf_init_exinclude(&dpcur.value[DUMPTYPE_EXCLUDE]);
2246 conf_init_exinclude(&dpcur.value[DUMPTYPE_INCLUDE]);
2247 conf_init_priority (&dpcur.value[DUMPTYPE_PRIORITY] , 1);
2248 conf_init_int (&dpcur.value[DUMPTYPE_DUMPCYCLE] , conf_data[CNF_DUMPCYCLE].v.i);
2249 conf_init_int (&dpcur.value[DUMPTYPE_MAXDUMPS] , conf_data[CNF_MAXDUMPS].v.i);
2250 conf_init_int (&dpcur.value[DUMPTYPE_MAXPROMOTEDAY] , 10000);
2251 conf_init_int (&dpcur.value[DUMPTYPE_BUMPPERCENT] , conf_data[CNF_BUMPPERCENT].v.i);
2252 conf_init_int64 (&dpcur.value[DUMPTYPE_BUMPSIZE] , conf_data[CNF_BUMPSIZE].v.int64);
2253 conf_init_int (&dpcur.value[DUMPTYPE_BUMPDAYS] , conf_data[CNF_BUMPDAYS].v.i);
2254 conf_init_real (&dpcur.value[DUMPTYPE_BUMPMULT] , conf_data[CNF_BUMPMULT].v.r);
2255 conf_init_time (&dpcur.value[DUMPTYPE_STARTTIME] , (time_t)0);
2256 conf_init_strategy (&dpcur.value[DUMPTYPE_STRATEGY] , DS_STANDARD);
2257 conf_init_estimatelist(&dpcur.value[DUMPTYPE_ESTIMATELIST] , ES_CLIENT);
2258 conf_init_compress (&dpcur.value[DUMPTYPE_COMPRESS] , COMP_FAST);
2259 conf_init_encrypt (&dpcur.value[DUMPTYPE_ENCRYPT] , ENCRYPT_NONE);
2260 conf_init_data_path(&dpcur.value[DUMPTYPE_DATA_PATH] , DATA_PATH_AMANDA);
2261 conf_init_str (&dpcur.value[DUMPTYPE_SRV_DECRYPT_OPT] , "-d");
2262 conf_init_str (&dpcur.value[DUMPTYPE_CLNT_DECRYPT_OPT] , "-d");
2263 conf_init_rate (&dpcur.value[DUMPTYPE_COMPRATE] , 0.50, 0.50);
2264 conf_init_int64 (&dpcur.value[DUMPTYPE_TAPE_SPLITSIZE] , (gint64)0);
2265 conf_init_int64 (&dpcur.value[DUMPTYPE_FALLBACK_SPLITSIZE], (gint64)10 * 1024);
2266 conf_init_str (&dpcur.value[DUMPTYPE_SPLIT_DISKBUFFER] , NULL);
2267 conf_init_bool (&dpcur.value[DUMPTYPE_RECORD] , 1);
2268 conf_init_bool (&dpcur.value[DUMPTYPE_SKIP_INCR] , 0);
2269 conf_init_bool (&dpcur.value[DUMPTYPE_SKIP_FULL] , 0);
2270 conf_init_holding (&dpcur.value[DUMPTYPE_HOLDINGDISK] , HOLD_AUTO);
2271 conf_init_bool (&dpcur.value[DUMPTYPE_KENCRYPT] , 0);
2272 conf_init_bool (&dpcur.value[DUMPTYPE_IGNORE] , 0);
2273 conf_init_bool (&dpcur.value[DUMPTYPE_INDEX] , 1);
2274 conf_init_application(&dpcur.value[DUMPTYPE_APPLICATION]);
2275 conf_init_identlist(&dpcur.value[DUMPTYPE_SCRIPTLIST], NULL);
2276 conf_init_proplist(&dpcur.value[DUMPTYPE_PROPERTY]);
2277 conf_init_bool (&dpcur.value[DUMPTYPE_ALLOW_SPLIT] , 1);
2278 conf_init_recovery_limit(&dpcur.value[DUMPTYPE_RECOVERY_LIMIT]);
2284 dumptype_t *dp, *dp1;;
2286 dp = lookup_dumptype(dpcur.name);
2288 if(dp != (dumptype_t *)0) {
2289 if (dp->seen.linenum == -1) {
2290 conf_parserror(_("dumptype %s is defined by default and cannot be redefined"), dp->name);
2292 conf_parserror(_("dumptype %s already defined at %s:%d"), dp->name,
2293 dp->seen.filename, dp->seen.linenum);
2298 dp = alloc(sizeof(dumptype_t));
2301 /* add at end of list */
2306 while (dp1->next != NULL) {
2319 dt = lookup_dumptype(tokenval.v.s);
2322 conf_parserror(_("dumptype parameter expected"));
2326 for(i=0; i < DUMPTYPE_DUMPTYPE; i++) {
2327 if(dt->value[i].seen.linenum) {
2328 merge_val_t(&dpcur.value[i], &dt->value[i]);
2329 if (i == DUMPTYPE_SCRIPTLIST) {
2330 /* sort in 'order' */
2331 dpcur.value[i].v.identlist = g_slist_sort(dpcur.value[i].v.identlist, &compare_pp_script_order);
2340 int save_overwrites;
2342 save_overwrites = allow_overwrites;
2343 allow_overwrites = 1;
2345 init_tapetype_defaults();
2347 get_conftoken(CONF_IDENT);
2348 tpcur.name = stralloc(tokenval.v.s);
2349 tpcur.seen.filename = current_filename;
2350 tpcur.seen.linenum = current_line_num;
2352 read_block(tapetype_var, tpcur.value,
2353 _("tapetype parameter expected"), 1, copy_tapetype,
2354 "TAPETYPE", tpcur.name);
2355 get_conftoken(CONF_NL);
2357 if (tapetype_get_readblocksize(&tpcur) <
2358 tapetype_get_blocksize(&tpcur)) {
2359 conf_init_size(&tpcur.value[TAPETYPE_READBLOCKSIZE],
2360 tapetype_get_blocksize(&tpcur));
2364 allow_overwrites = save_overwrites;
2368 init_tapetype_defaults(void)
2370 conf_init_str(&tpcur.value[TAPETYPE_COMMENT] , "");
2371 conf_init_str(&tpcur.value[TAPETYPE_LBL_TEMPL] , "");
2372 conf_init_size (&tpcur.value[TAPETYPE_BLOCKSIZE] , DISK_BLOCK_KB);
2373 conf_init_size (&tpcur.value[TAPETYPE_READBLOCKSIZE], DISK_BLOCK_KB);
2374 conf_init_int64 (&tpcur.value[TAPETYPE_LENGTH] , ((gint64)2000));
2375 conf_init_int64 (&tpcur.value[TAPETYPE_FILEMARK] , (gint64)1);
2376 conf_init_int (&tpcur.value[TAPETYPE_SPEED] , 200);
2377 conf_init_int64(&tpcur.value[TAPETYPE_PART_SIZE], 0);
2378 conf_init_part_cache_type(&tpcur.value[TAPETYPE_PART_CACHE_TYPE], PART_CACHE_TYPE_NONE);
2379 conf_init_str(&tpcur.value[TAPETYPE_PART_CACHE_DIR], "");
2380 conf_init_int64(&tpcur.value[TAPETYPE_PART_CACHE_MAX_SIZE], 0);
2386 tapetype_t *tp, *tp1;
2388 tp = lookup_tapetype(tpcur.name);
2390 if(tp != (tapetype_t *)0) {
2392 conf_parserror(_("tapetype %s already defined at %s:%d"),
2393 tp->name, tp->seen.filename, tp->seen.linenum);
2397 tp = alloc(sizeof(tapetype_t));
2400 /* add at end of list */
2405 while (tp1->next != NULL) {
2418 tp = lookup_tapetype(tokenval.v.s);
2421 conf_parserror(_("tape type parameter expected"));
2425 for(i=0; i < TAPETYPE_TAPETYPE; i++) {
2426 if(tp->value[i].seen.linenum) {
2427 merge_val_t(&tpcur.value[i], &tp->value[i]);
2435 int save_overwrites;
2437 save_overwrites = allow_overwrites;
2438 allow_overwrites = 1;
2440 init_interface_defaults();
2442 get_conftoken(CONF_IDENT);
2443 ifcur.name = stralloc(tokenval.v.s);
2444 ifcur.seen.filename = current_filename;
2445 ifcur.seen.linenum = current_line_num;
2447 read_block(interface_var, ifcur.value,
2448 _("interface parameter expected"), 1, copy_interface,
2449 "INTERFACE", ifcur.name);
2450 get_conftoken(CONF_NL);
2454 allow_overwrites = save_overwrites;
2460 init_interface_defaults(void)
2462 conf_init_str(&ifcur.value[INTER_COMMENT] , "");
2463 conf_init_int (&ifcur.value[INTER_MAXUSAGE], 8000);
2467 save_interface(void)
2469 interface_t *ip, *ip1;
2471 ip = lookup_interface(ifcur.name);
2473 if(ip != (interface_t *)0) {
2474 conf_parserror(_("interface %s already defined at %s:%d"),
2475 ip->name, ip->seen.filename, ip->seen.linenum);
2479 ip = alloc(sizeof(interface_t));
2481 /* add at end of list */
2482 if(!interface_list) {
2483 interface_list = ip;
2485 ip1 = interface_list;
2486 while (ip1->next != NULL) {
2494 copy_interface(void)
2499 ip = lookup_interface(tokenval.v.s);
2502 conf_parserror(_("interface parameter expected"));
2506 for(i=0; i < INTER_INTER; i++) {
2507 if(ip->value[i].seen.linenum) {
2508 merge_val_t(&ifcur.value[i], &ip->value[i]);
2521 int save_overwrites;
2522 FILE *saved_conf = NULL;
2523 char *saved_fname = NULL;
2526 saved_conf = current_file;
2527 current_file = from;
2531 saved_fname = current_filename;
2532 current_filename = get_seen_filename(fname);
2536 current_line_num = *linenum;
2538 save_overwrites = allow_overwrites;
2539 allow_overwrites = 1;
2541 init_application_defaults();
2545 get_conftoken(CONF_IDENT);
2546 apcur.name = stralloc(tokenval.v.s);
2548 apcur.seen.filename = current_filename;
2549 apcur.seen.linenum = current_line_num;
2551 read_block(application_var, apcur.value,
2552 _("application parameter expected"),
2553 (name == NULL), *copy_application,
2554 "APPLICATION", apcur.name);
2556 get_conftoken(CONF_NL);
2560 allow_overwrites = save_overwrites;
2563 *linenum = current_line_num;
2566 current_filename = saved_fname;
2569 current_file = saved_conf;
2571 return lookup_application(apcur.name);
2578 read_application(NULL, NULL, NULL, NULL);
2582 init_application_defaults(
2586 conf_init_str(&apcur.value[APPLICATION_COMMENT] , "");
2587 conf_init_str(&apcur.value[APPLICATION_PLUGIN] , "");
2588 conf_init_proplist(&apcur.value[APPLICATION_PROPERTY]);
2595 application_t *ap, *ap1;
2597 ap = lookup_application(apcur.name);
2599 if(ap != (application_t *)0) {
2600 conf_parserror(_("application %s already defined at %s:%d"),
2601 ap->name, ap->seen.filename, ap->seen.linenum);
2605 ap = alloc(sizeof(application_t));
2608 /* add at end of list */
2609 if (!application_list)
2610 application_list = ap;
2612 ap1 = application_list;
2613 while (ap1->next != NULL) {
2621 copy_application(void)
2626 ap = lookup_application(tokenval.v.s);
2629 conf_parserror(_("application parameter expected"));
2633 for(i=0; i < APPLICATION_APPLICATION; i++) {
2634 if(ap->value[i].seen.linenum) {
2635 merge_val_t(&apcur.value[i], &ap->value[i]);
2647 int save_overwrites;
2648 FILE *saved_conf = NULL;
2649 char *saved_fname = NULL;
2652 saved_conf = current_file;
2653 current_file = from;
2657 saved_fname = current_filename;
2658 current_filename = get_seen_filename(fname);
2662 current_line_num = *linenum;
2664 save_overwrites = allow_overwrites;
2665 allow_overwrites = 1;
2667 init_pp_script_defaults();
2671 get_conftoken(CONF_IDENT);
2672 pscur.name = stralloc(tokenval.v.s);
2674 pscur.seen.filename = current_filename;
2675 pscur.seen.linenum = current_line_num;
2677 read_block(pp_script_var, pscur.value,
2678 _("script parameter expected"),
2679 (name == NULL), *copy_pp_script,
2680 "SCRIPT", pscur.name);
2682 get_conftoken(CONF_NL);
2686 allow_overwrites = save_overwrites;
2689 *linenum = current_line_num;
2692 current_filename = saved_fname;
2695 current_file = saved_conf;
2697 return lookup_pp_script(pscur.name);
2704 read_pp_script(NULL, NULL, NULL, NULL);
2708 init_pp_script_defaults(
2712 conf_init_str(&pscur.value[PP_SCRIPT_COMMENT] , "");
2713 conf_init_str(&pscur.value[PP_SCRIPT_PLUGIN] , "");
2714 conf_init_proplist(&pscur.value[PP_SCRIPT_PROPERTY]);
2715 conf_init_execute_on(&pscur.value[PP_SCRIPT_EXECUTE_ON], 0);
2716 conf_init_execute_where(&pscur.value[PP_SCRIPT_EXECUTE_WHERE], ES_CLIENT);
2717 conf_init_int(&pscur.value[PP_SCRIPT_ORDER], 5000);
2724 pp_script_t *ps, *ps1;
2726 ps = lookup_pp_script(pscur.name);
2728 if(ps != (pp_script_t *)0) {
2729 conf_parserror(_("script %s already defined at %s:%d"),
2730 ps->name, ps->seen.filename, ps->seen.linenum);
2734 ps = alloc(sizeof(pp_script_t));
2737 /* add at end of list */
2738 if (!pp_script_list)
2739 pp_script_list = ps;
2741 ps1 = pp_script_list;
2742 while (ps1->next != NULL) {
2750 copy_pp_script(void)
2755 ps = lookup_pp_script(tokenval.v.s);
2758 conf_parserror(_("script parameter expected"));
2762 for(i=0; i < PP_SCRIPT_PP_SCRIPT; i++) {
2763 if(ps->value[i].seen.linenum) {
2764 merge_val_t(&pscur.value[i], &ps->value[i]);
2776 int save_overwrites;
2777 FILE *saved_conf = NULL;
2778 char *saved_fname = NULL;
2781 saved_conf = current_file;
2782 current_file = from;
2786 saved_fname = current_filename;
2787 current_filename = get_seen_filename(fname);
2791 current_line_num = *linenum;
2793 save_overwrites = allow_overwrites;
2794 allow_overwrites = 1;
2796 init_device_config_defaults();
2800 get_conftoken(CONF_IDENT);
2801 dccur.name = stralloc(tokenval.v.s);
2803 dccur.seen.filename = current_filename;
2804 dccur.seen.linenum = current_line_num;
2806 read_block(device_config_var, dccur.value,
2807 _("device parameter expected"),
2808 (name == NULL), *copy_device_config,
2809 "DEVICE", dccur.name);
2811 get_conftoken(CONF_NL);
2813 save_device_config();
2815 allow_overwrites = save_overwrites;
2818 *linenum = current_line_num;
2821 current_filename = saved_fname;
2824 current_file = saved_conf;
2826 return lookup_device_config(dccur.name);
2833 read_device_config(NULL, NULL, NULL, NULL);
2837 init_device_config_defaults(
2841 conf_init_str(&dccur.value[DEVICE_CONFIG_COMMENT] , "");
2842 conf_init_str(&dccur.value[DEVICE_CONFIG_TAPEDEV] , "");
2843 conf_init_proplist(&dccur.value[DEVICE_CONFIG_DEVICE_PROPERTY]);
2850 device_config_t *dc, *dc1;
2852 dc = lookup_device_config(dccur.name);
2854 if(dc != (device_config_t *)0) {
2855 conf_parserror(_("device %s already defined at %s:%d"),
2856 dc->name, dc->seen.filename, dc->seen.linenum);
2860 dc = alloc(sizeof(device_config_t));
2863 /* add at end of list */
2864 if (!device_config_list)
2865 device_config_list = dc;
2867 dc1 = device_config_list;
2868 while (dc1->next != NULL) {
2876 copy_device_config(void)
2878 device_config_t *dc;
2881 dc = lookup_device_config(tokenval.v.s);
2884 conf_parserror(_("device parameter expected"));
2888 for(i=0; i < DEVICE_CONFIG_DEVICE_CONFIG; i++) {
2889 if(dc->value[i].seen.linenum) {
2890 merge_val_t(&dccur.value[i], &dc->value[i]);
2896 read_changer_config(
2902 int save_overwrites;
2903 FILE *saved_conf = NULL;
2904 char *saved_fname = NULL;
2907 saved_conf = current_file;
2908 current_file = from;
2912 saved_fname = current_filename;
2913 current_filename = fname;
2917 current_line_num = *linenum;
2919 save_overwrites = allow_overwrites;
2920 allow_overwrites = 1;
2922 init_changer_config_defaults();
2926 get_conftoken(CONF_IDENT);
2927 cccur.name = stralloc(tokenval.v.s);
2929 cccur.seen = current_line_num;
2931 read_block(changer_config_var, cccur.value,
2932 _("changer parameter expected"),
2933 (name == NULL), *copy_changer_config,
2934 "CHANGER", cccur.name);
2936 get_conftoken(CONF_NL);
2938 save_changer_config();
2940 allow_overwrites = save_overwrites;
2943 *linenum = current_line_num;
2946 current_filename = saved_fname;
2949 current_file = saved_conf;
2951 return lookup_changer_config(cccur.name);
2958 read_changer_config(NULL, NULL, NULL, NULL);
2962 init_changer_config_defaults(
2966 conf_init_str(&cccur.value[CHANGER_CONFIG_COMMENT] , "");
2967 conf_init_str(&cccur.value[CHANGER_CONFIG_TAPEDEV] , "");
2968 conf_init_str(&cccur.value[CHANGER_CONFIG_TPCHANGER] , "");
2969 conf_init_str(&cccur.value[CHANGER_CONFIG_CHANGERDEV] , "");
2970 conf_init_str(&cccur.value[CHANGER_CONFIG_CHANGERFILE] , "");
2971 conf_init_proplist(&cccur.value[CHANGER_CONFIG_PROPERTY]);
2972 conf_init_proplist(&cccur.value[CHANGER_CONFIG_DEVICE_PROPERTY]);
2976 save_changer_config(
2979 changer_config_t *dc, *dc1;
2981 dc = lookup_changer_config(cccur.name);
2983 if(dc != (changer_config_t *)0) {
2984 conf_parserror(_("changer %s already defined on line %d"),
2985 dc->name, dc->seen);
2989 dc = alloc(sizeof(changer_config_t));
2992 /* add at end of list */
2993 if (!changer_config_list)
2994 changer_config_list = dc;
2996 dc1 = changer_config_list;
2997 while (dc1->next != NULL) {
3005 copy_changer_config(void)
3007 changer_config_t *dc;
3010 dc = lookup_changer_config(tokenval.v.s);
3013 conf_parserror(_("changer parameter expected"));
3017 for(i=0; i < CHANGER_CONFIG_CHANGER_CONFIG; i++) {
3018 if(dc->value[i].seen.linenum) {
3019 merge_val_t(&cccur.value[i], &dc->value[i]);
3024 /* Read functions */
3028 conf_var_t *np G_GNUC_UNUSED,
3032 val_t__int(val) = get_int();
3037 conf_var_t *np G_GNUC_UNUSED,
3041 val_t__int64(val) = get_int64();
3046 conf_var_t *np G_GNUC_UNUSED,
3050 get_conftoken(CONF_REAL);
3051 val_t__real(val) = tokenval.v.r;
3056 conf_var_t *np G_GNUC_UNUSED,
3060 get_conftoken(CONF_STRING);
3061 val->v.s = newstralloc(val->v.s, tokenval.v.s);
3066 conf_var_t *np G_GNUC_UNUSED,
3070 get_conftoken(CONF_IDENT);
3071 val->v.s = newstralloc(val->v.s, tokenval.v.s);
3076 conf_var_t *np G_GNUC_UNUSED,
3080 val_t__time(val) = get_time();
3085 conf_var_t *np G_GNUC_UNUSED,
3089 val_t__size(val) = get_size();
3094 conf_var_t *np G_GNUC_UNUSED,
3098 val_t__size(val) = get_size_byte();
3103 conf_var_t *np G_GNUC_UNUSED,
3107 val_t__boolean(val) = get_bool();
3112 conf_var_t *np G_GNUC_UNUSED,
3115 int serv, clie, none, fast, best, custom;
3121 serv = clie = none = fast = best = custom = 0;
3125 get_conftoken(CONF_ANY);
3127 case CONF_NONE: none = 1; break;
3128 case CONF_FAST: fast = 1; break;
3129 case CONF_BEST: best = 1; break;
3130 case CONF_CLIENT: clie = 1; break;
3131 case CONF_SERVER: serv = 1; break;
3132 case CONF_CUSTOM: custom=1; break;
3133 case CONF_NL: done = 1; break;
3134 case CONF_END: done = 1; break;
3137 serv = clie = 1; /* force an error */
3141 if(serv + clie == 0) clie = 1; /* default to client */
3142 if(none + fast + best + custom == 0) fast = 1; /* default to fast */
3147 if(none && !fast && !best && !custom) comp = COMP_NONE;
3148 if(!none && fast && !best && !custom) comp = COMP_FAST;
3149 if(!none && !fast && best && !custom) comp = COMP_BEST;
3150 if(!none && !fast && !best && custom) comp = COMP_CUST;
3154 if(none && !fast && !best && !custom) comp = COMP_NONE;
3155 if(!none && fast && !best && !custom) comp = COMP_SERVER_FAST;
3156 if(!none && !fast && best && !custom) comp = COMP_SERVER_BEST;
3157 if(!none && !fast && !best && custom) comp = COMP_SERVER_CUST;
3160 if((int)comp == -1) {
3161 conf_parserror(_("NONE, CLIENT FAST, CLIENT BEST, CLIENT CUSTOM, SERVER FAST, SERVER BEST or SERVER CUSTOM expected"));
3165 val_t__compress(val) = (int)comp;
3170 conf_var_t *np G_GNUC_UNUSED,
3177 get_conftoken(CONF_ANY);
3180 encrypt = ENCRYPT_NONE;
3184 encrypt = ENCRYPT_CUST;
3188 encrypt = ENCRYPT_SERV_CUST;
3192 conf_parserror(_("NONE, CLIENT or SERVER expected"));
3193 encrypt = ENCRYPT_NONE;
3197 val_t__encrypt(val) = (int)encrypt;
3202 conf_var_t *np G_GNUC_UNUSED,
3205 dump_holdingdisk_t holding;
3209 get_conftoken(CONF_ANY);
3212 holding = HOLD_NEVER;
3216 holding = HOLD_AUTO;
3220 holding = HOLD_REQUIRED;
3223 default: /* can be a BOOLEAN */
3225 holding = (dump_holdingdisk_t)get_bool();
3227 holding = HOLD_NEVER;
3228 else if (holding == 1 || holding == 2)
3229 holding = HOLD_AUTO;
3231 conf_parserror(_("NEVER, AUTO or REQUIRED expected"));
3235 val_t__holding(val) = (int)holding;
3240 conf_var_t *np G_GNUC_UNUSED,
3243 estimatelist_t estimates = NULL;
3247 get_conftoken(CONF_ANY);
3251 estimates = g_slist_append(estimates, GINT_TO_POINTER(ES_CLIENT));
3254 estimates = g_slist_append(estimates, GINT_TO_POINTER(ES_SERVER));
3257 estimates = g_slist_append(estimates, GINT_TO_POINTER(ES_CALCSIZE));
3260 conf_parserror(_("CLIENT, SERVER or CALCSIZE expected"));
3262 get_conftoken(CONF_ANY);
3266 val_t__estimatelist(val) = estimates;
3271 conf_var_t *np G_GNUC_UNUSED,
3278 get_conftoken(CONF_ANY);
3284 strat = DS_STANDARD;
3296 strat = DS_INCRONLY;
3299 conf_parserror(_("dump strategy expected"));
3300 strat = DS_STANDARD;
3302 val_t__strategy(val) = strat;
3307 conf_var_t *np G_GNUC_UNUSED,
3312 get_conftoken(CONF_ANY);
3314 case CONF_FIRST: val_t__taperalgo(val) = ALGO_FIRST; break;
3315 case CONF_FIRSTFIT: val_t__taperalgo(val) = ALGO_FIRSTFIT; break;
3316 case CONF_LARGEST: val_t__taperalgo(val) = ALGO_LARGEST; break;
3317 case CONF_LARGESTFIT: val_t__taperalgo(val) = ALGO_LARGESTFIT; break;
3318 case CONF_SMALLEST: val_t__taperalgo(val) = ALGO_SMALLEST; break;
3319 case CONF_LAST: val_t__taperalgo(val) = ALGO_LAST; break;
3321 conf_parserror(_("FIRST, FIRSTFIT, LARGEST, LARGESTFIT, SMALLEST or LAST expected"));
3326 read_send_amreport_on(
3327 conf_var_t *np G_GNUC_UNUSED,
3332 get_conftoken(CONF_ANY);
3334 case CONF_ALL: val_t__send_amreport(val) = SEND_AMREPORT_ALL; break;
3335 case CONF_STRANGE: val_t__send_amreport(val) = SEND_AMREPORT_STRANGE; break;
3336 case CONF_ERROR: val_t__send_amreport(val) = SEND_AMREPORT_ERROR; break;
3337 case CONF_NEVER: val_t__send_amreport(val) = SEND_AMREPORT_NEVER; break;
3339 conf_parserror(_("ALL, STRANGE, ERROR or NEVER expected"));
3345 conf_var_t *np G_GNUC_UNUSED,
3350 get_conftoken(CONF_ANY);
3352 case CONF_AMANDA : val_t__send_amreport(val) = DATA_PATH_AMANDA ; break;
3353 case CONF_DIRECTTCP: val_t__send_amreport(val) = DATA_PATH_DIRECTTCP; break;
3355 conf_parserror(_("AMANDA or DIRECTTCP expected"));
3361 conf_var_t *np G_GNUC_UNUSED,
3368 get_conftoken(CONF_ANY);
3370 case CONF_LOW: pri = 0; break;
3371 case CONF_MEDIUM: pri = 1; break;
3372 case CONF_HIGH: pri = 2; break;
3373 case CONF_INT: pri = tokenval.v.i; break;
3375 conf_parserror(_("LOW, MEDIUM, HIGH or integer expected"));
3378 val_t__priority(val) = pri;
3383 conf_var_t *np G_GNUC_UNUSED,
3386 get_conftoken(CONF_REAL);
3387 val_t__rate(val)[0] = tokenval.v.r;
3388 val_t__rate(val)[1] = tokenval.v.r;
3389 val->seen = tokenval.seen;
3390 if(tokenval.v.r < 0) {
3391 conf_parserror(_("full compression rate must be >= 0"));
3394 get_conftoken(CONF_ANY);
3409 get_conftoken(CONF_REAL);
3410 val_t__rate(val)[1] = tokenval.v.r;
3411 if(tokenval.v.r < 0) {
3412 conf_parserror(_("incremental compression rate must be >= 0"));
3418 conf_var_t *np G_GNUC_UNUSED,
3421 int file, got_one = 0;
3425 get_conftoken(CONF_ANY);
3426 if(tok == CONF_LIST) {
3428 get_conftoken(CONF_ANY);
3429 exclude = val_t__exinclude(val).sl_list;
3433 if(tok == CONF_EFILE) get_conftoken(CONF_ANY);
3434 exclude = val_t__exinclude(val).sl_file;
3438 if(tok == CONF_OPTIONAL) {
3439 get_conftoken(CONF_ANY);
3443 if(tok == CONF_APPEND) {
3444 get_conftoken(CONF_ANY);
3451 while(tok == CONF_STRING) {
3452 exclude = append_sl(exclude, tokenval.v.s);
3454 get_conftoken(CONF_ANY);
3458 if(got_one == 0) { free_sl(exclude); exclude = NULL; }
3461 val_t__exinclude(val).sl_list = exclude;
3463 val_t__exinclude(val).sl_file = exclude;
3464 val_t__exinclude(val).optional = optional;
3469 conf_var_t *np G_GNUC_UNUSED,
3472 get_conftoken(CONF_INT);
3473 val_t__intrange(val)[0] = tokenval.v.i;
3474 val_t__intrange(val)[1] = tokenval.v.i;
3475 val->seen = tokenval.seen;
3477 get_conftoken(CONF_ANY);
3492 get_conftoken(CONF_INT);
3493 val_t__intrange(val)[1] = tokenval.v.i;
3498 conf_var_t *np G_GNUC_UNUSED,
3502 property_t *property = malloc(sizeof(property_t));
3503 property_t *old_property;
3504 property->append = 0;
3505 property->priority = 0;
3506 property->values = NULL;
3508 get_conftoken(CONF_ANY);
3509 if (tok == CONF_PRIORITY) {
3510 property->priority = 1;
3511 get_conftoken(CONF_ANY);
3513 if (tok == CONF_APPEND) {
3514 property->append = 1;
3515 get_conftoken(CONF_ANY);
3517 if (tok != CONF_STRING) {
3518 conf_parserror(_("key expected"));
3521 key = amandaify_property_name(tokenval.v.s);
3523 get_conftoken(CONF_ANY);
3524 if (tok == CONF_NL || tok == CONF_END) {
3525 g_hash_table_remove(val->v.proplist, key);
3529 if (tok != CONF_STRING) {
3530 conf_parserror(_("value expected"));
3534 if(val->seen.linenum == 0) {
3535 val->seen.filename = current_filename;
3536 val->seen.linenum = current_line_num;
3539 old_property = g_hash_table_lookup(val->v.proplist, key);
3540 if (property->append) {
3541 /* old_property will be freed by g_hash_table_insert, so
3542 * steal its values */
3544 if (old_property->priority)
3545 property->priority = 1;
3546 property->values = old_property->values;
3547 old_property->values = NULL;
3550 while(tok == CONF_STRING) {
3551 property->values = g_slist_append(property->values,
3552 strdup(tokenval.v.s));
3553 get_conftoken(CONF_ANY);
3556 g_hash_table_insert(val->v.proplist, key, property);
3562 conf_var_t *np G_GNUC_UNUSED,
3565 application_t *application;
3567 get_conftoken(CONF_ANY);
3568 if (tok == CONF_LBRACE) {
3569 current_line_num -= 1;
3570 application = read_application(vstralloc("custom(DUMPTYPE:",
3571 dpcur.name, ")", ".",
3572 anonymous_value(),NULL),
3574 current_line_num -= 1;
3575 } else if (tok == CONF_STRING) {
3576 application = lookup_application(tokenval.v.s);
3577 if (application == NULL) {
3578 conf_parserror(_("Unknown application named: %s"), tokenval.v.s);
3582 conf_parserror(_("application name expected: %d %d"), tok, CONF_STRING);
3586 val->v.s = stralloc(application->name);
3592 conf_var_t *np G_GNUC_UNUSED,
3595 pp_script_t *pp_script;
3596 get_conftoken(CONF_ANY);
3597 if (tok == CONF_LBRACE) {
3598 current_line_num -= 1;
3599 pp_script = read_pp_script(vstralloc("custom(DUMPTYPE:", dpcur.name,
3600 ")", ".", anonymous_value(),NULL),
3602 current_line_num -= 1;
3603 val->v.identlist = g_slist_insert_sorted(val->v.identlist,
3604 stralloc(pp_script->name), &compare_pp_script_order);
3605 } else if (tok == CONF_STRING || tok == CONF_IDENT) {
3606 while (tok == CONF_STRING || tok == CONF_IDENT) {
3607 pp_script = lookup_pp_script(tokenval.v.s);
3608 if (pp_script == NULL) {
3609 conf_parserror(_("Unknown pp_script named: %s"), tokenval.v.s);
3612 val->v.identlist = g_slist_insert_sorted(val->v.identlist,
3613 stralloc(pp_script->name), &compare_pp_script_order);
3614 get_conftoken(CONF_ANY);
3618 conf_parserror(_("pp_script name expected: %d %d"), tok, CONF_STRING);
3625 conf_var_t *np G_GNUC_UNUSED,
3630 get_conftoken(CONF_ANY);
3634 case CONF_PRE_DLE_AMCHECK: val->v.i |= EXECUTE_ON_PRE_DLE_AMCHECK; break;
3635 case CONF_PRE_HOST_AMCHECK: val->v.i |= EXECUTE_ON_PRE_HOST_AMCHECK; break;
3636 case CONF_POST_DLE_AMCHECK: val->v.i |= EXECUTE_ON_POST_DLE_AMCHECK; break;
3637 case CONF_POST_HOST_AMCHECK: val->v.i |= EXECUTE_ON_POST_HOST_AMCHECK; break;
3638 case CONF_PRE_DLE_ESTIMATE: val->v.i |= EXECUTE_ON_PRE_DLE_ESTIMATE; break;
3639 case CONF_PRE_HOST_ESTIMATE: val->v.i |= EXECUTE_ON_PRE_HOST_ESTIMATE; break;
3640 case CONF_POST_DLE_ESTIMATE: val->v.i |= EXECUTE_ON_POST_DLE_ESTIMATE; break;
3641 case CONF_POST_HOST_ESTIMATE: val->v.i |= EXECUTE_ON_POST_HOST_ESTIMATE; break;
3642 case CONF_PRE_DLE_BACKUP: val->v.i |= EXECUTE_ON_PRE_DLE_BACKUP; break;
3643 case CONF_PRE_HOST_BACKUP: val->v.i |= EXECUTE_ON_PRE_HOST_BACKUP; break;
3644 case CONF_POST_DLE_BACKUP: val->v.i |= EXECUTE_ON_POST_DLE_BACKUP; break;
3645 case CONF_POST_HOST_BACKUP: val->v.i |= EXECUTE_ON_POST_HOST_BACKUP; break;
3646 case CONF_PRE_RECOVER: val->v.i |= EXECUTE_ON_PRE_RECOVER; break;
3647 case CONF_POST_RECOVER: val->v.i |= EXECUTE_ON_POST_RECOVER; break;
3648 case CONF_PRE_LEVEL_RECOVER: val->v.i |= EXECUTE_ON_PRE_LEVEL_RECOVER; break;
3649 case CONF_POST_LEVEL_RECOVER: val->v.i |= EXECUTE_ON_POST_LEVEL_RECOVER; break;
3650 case CONF_INTER_LEVEL_RECOVER: val->v.i |= EXECUTE_ON_INTER_LEVEL_RECOVER; break;
3652 conf_parserror(_("Execute-on expected"));
3654 get_conftoken(CONF_ANY);
3655 if (tok != CONF_COMMA) {
3659 get_conftoken(CONF_ANY);
3665 conf_var_t *np G_GNUC_UNUSED,
3670 get_conftoken(CONF_ANY);
3672 case CONF_CLIENT: val->v.i = ES_CLIENT; break;
3673 case CONF_SERVER: val->v.i = ES_SERVER; break;
3675 conf_parserror(_("CLIENT or SERVER expected"));
3681 conf_var_t *np G_GNUC_UNUSED,
3686 get_conftoken(CONF_ANY);
3690 val->v.s = g_strdup_printf("%d", tokenval.v.i);
3695 val->v.s = g_strdup_printf("%zu", tokenval.v.size);
3700 val->v.s = g_strdup_printf("%jd", (intmax_t)tokenval.v.int64);
3704 val->v.s = newstralloc(val->v.s, tokenval.v.s);
3707 conf_parserror(_("CLIENT or SERVER expected"));
3713 conf_var_t *np G_GNUC_UNUSED,
3719 get_conftoken(CONF_ANY);
3720 if (tok == CONF_STRING) {
3722 val->v.autolabel.template = newstralloc(val->v.autolabel.template,
3724 get_conftoken(CONF_ANY);
3726 val->v.autolabel.autolabel = 0;
3727 while (tok != CONF_NL && tok != CONF_END) {
3729 if (tok == CONF_ANY_VOLUME)
3730 val->v.autolabel.autolabel |= AL_OTHER_CONFIG | AL_NON_AMANDA |
3731 AL_VOLUME_ERROR | AL_EMPTY;
3732 else if (tok == CONF_OTHER_CONFIG)
3733 val->v.autolabel.autolabel |= AL_OTHER_CONFIG;
3734 else if (tok == CONF_NON_AMANDA)
3735 val->v.autolabel.autolabel |= AL_NON_AMANDA;
3736 else if (tok == CONF_VOLUME_ERROR)
3737 val->v.autolabel.autolabel |= AL_VOLUME_ERROR;
3738 else if (tok == CONF_EMPTY)
3739 val->v.autolabel.autolabel |= AL_EMPTY;
3741 conf_parserror(_("ANY, NEW-VOLUME, OTHER-CONFIG, NON-AMANDA, VOLUME-ERROR or EMPTY is expected"));
3743 get_conftoken(CONF_ANY);
3746 amfree(val->v.autolabel.template);
3747 val->v.autolabel.autolabel = 0;
3748 } else if (val->v.autolabel.autolabel == 0) {
3749 val->v.autolabel.autolabel = AL_VOLUME_ERROR | AL_EMPTY;
3754 read_part_cache_type(
3755 conf_var_t *np G_GNUC_UNUSED,
3758 part_cache_type_t part_cache_type;
3762 get_conftoken(CONF_ANY);
3765 part_cache_type = PART_CACHE_TYPE_NONE;
3769 part_cache_type = PART_CACHE_TYPE_DISK;
3773 part_cache_type = PART_CACHE_TYPE_MEMORY;
3777 conf_parserror(_("NONE, DISK or MEMORY expected"));
3778 part_cache_type = PART_CACHE_TYPE_NONE;
3782 val_t__part_cache_type(val) = (int)part_cache_type;
3786 read_recovery_limit(
3787 conf_var_t *np G_GNUC_UNUSED,
3790 recovery_limit_t *rl = &val_t__recovery_limit(val);
3794 get_conftoken(CONF_ANY);
3797 rl->match_pats = g_slist_append(rl->match_pats, g_strdup(tokenval.v.s));
3799 case CONF_SAME_HOST:
3800 rl->same_host = TRUE;
3808 conf_parserror("SAME-HOST or a string expected");
3814 /* get_* functions */
3816 /* these functions use precompiler conditionals to skip useless size checks
3817 * when casting from one type to another. SIZEOF_GINT64 is pretty simple to
3818 * calculate; the others are calculated by configure. */
3820 #define SIZEOF_GINT64 8
3827 get_conftoken(CONF_ANY);
3830 #if SIZEOF_TIME_T < SIZEOF_INT
3831 if ((gint64)tokenval.v.i >= (gint64)TIME_MAX)
3832 conf_parserror(_("value too large"));
3834 hhmm = (time_t)tokenval.v.i;
3838 #if SIZEOF_TIME_T < SIZEOF_SSIZE_T
3839 if ((gint64)tokenval.v.size >= (gint64)TIME_MAX)
3840 conf_parserror(_("value too large"));
3842 hhmm = (time_t)tokenval.v.size;
3846 #if SIZEOF_TIME_T < SIZEOF_GINT64
3847 if ((gint64)tokenval.v.int64 >= (gint64)TIME_MAX)
3848 conf_parserror(_("value too large"));
3850 hhmm = (time_t)tokenval.v.int64;
3853 case CONF_AMINFINITY:
3858 conf_parserror(_("a time is expected"));
3872 keytable = numb_keytable;
3874 get_conftoken(CONF_ANY);
3881 #if SIZEOF_INT < SIZEOF_SSIZE_T
3882 if ((gint64)tokenval.v.size > (gint64)INT_MAX)
3883 conf_parserror(_("value too large"));
3884 if ((gint64)tokenval.v.size < (gint64)INT_MIN)
3885 conf_parserror(_("value too small"));
3887 val = (int)tokenval.v.size;
3891 #if SIZEOF_INT < SIZEOF_GINT64
3892 if (tokenval.v.int64 > (gint64)INT_MAX)
3893 conf_parserror(_("value too large"));
3894 if (tokenval.v.int64 < (gint64)INT_MIN)
3895 conf_parserror(_("value too small"));
3897 val = (int)tokenval.v.int64;
3900 case CONF_AMINFINITY:
3905 conf_parserror(_("an integer is expected"));
3910 /* get multiplier, if any */
3911 get_conftoken(CONF_ANY);
3913 case CONF_NL: /* multiply by one */
3920 if (val > (INT_MAX / 7))
3921 conf_parserror(_("value too large"));
3922 if (val < (INT_MIN / 7))
3923 conf_parserror(_("value too small"));
3928 if (val > (INT_MAX / 1024))
3929 conf_parserror(_("value too large"));
3930 if (val < (INT_MIN / 1024))
3931 conf_parserror(_("value too small"));
3936 if (val > (INT_MAX / (1024 * 1024)))
3937 conf_parserror(_("value too large"));
3938 if (val < (INT_MIN / (1024 * 1024)))
3939 conf_parserror(_("value too small"));
3944 if (val > (INT_MAX / (1024 * 1024 * 1024)))
3945 conf_parserror(_("value too large"));
3946 if (val < (INT_MIN / (1024 * 1024 * 1024)))
3947 conf_parserror(_("value too small"));
3948 val *= 1024 * 1024 * 1024;
3951 default: /* it was not a multiplier */
3967 keytable = numb_keytable;
3969 get_conftoken(CONF_ANY);
3973 val = tokenval.v.size;
3977 #if SIZEOF_SIZE_T < SIZEOF_INT
3978 if ((gint64)tokenval.v.i > (gint64)SSIZE_MAX)
3979 conf_parserror(_("value too large"));
3980 if ((gint64)tokenval.v.i < (gint64)SSIZE_MIN)
3981 conf_parserror(_("value too small"));
3983 val = (ssize_t)tokenval.v.i;
3987 #if SIZEOF_SIZE_T < SIZEOF_GINT64
3988 if (tokenval.v.int64 > (gint64)SSIZE_MAX)
3989 conf_parserror(_("value too large"));
3990 if (tokenval.v.int64 < (gint64)SSIZE_MIN)
3991 conf_parserror(_("value too small"));
3993 val = (ssize_t)tokenval.v.int64;
3996 case CONF_AMINFINITY:
3997 val = (ssize_t)SSIZE_MAX;
4001 conf_parserror(_("an integer is expected"));
4006 /* get multiplier, if any */
4007 get_conftoken(CONF_ANY);
4010 case CONF_NL: /* multiply by one */
4016 if (val > (ssize_t)(SSIZE_MAX / 7))
4017 conf_parserror(_("value too large"));
4018 if (val < (ssize_t)(SSIZE_MIN / 7))
4019 conf_parserror(_("value too small"));
4024 if (val > (ssize_t)(SSIZE_MAX / (ssize_t)1024))
4025 conf_parserror(_("value too large"));
4026 if (val < (ssize_t)(SSIZE_MIN / (ssize_t)1024))
4027 conf_parserror(_("value too small"));
4028 val *= (ssize_t)1024;
4032 if (val > (ssize_t)(SSIZE_MAX / (1024 * 1024)))
4033 conf_parserror(_("value too large"));
4034 if (val < (ssize_t)(SSIZE_MIN / (1024 * 1024)))
4035 conf_parserror(_("value too small"));
4036 val *= (ssize_t)(1024 * 1024);
4040 if (val > (INT_MAX / (1024 * 1024 * 1024)))
4041 conf_parserror(_("value too large"));
4042 if (val < (INT_MIN / (1024 * 1024 * 1024)))
4043 conf_parserror(_("value too small"));
4044 val *= 1024 * 1024 * 1024;
4047 default: /* it was not a multiplier */
4063 keytable = numb_keytable;
4065 get_conftoken(CONF_ANY);
4069 val = tokenval.v.size;
4073 #if SIZEOF_SIZE_T < SIZEOF_INT
4074 if ((gint64)tokenval.v.i > (gint64)SSIZE_MAX)
4075 conf_parserror(_("value too large"));
4076 if ((gint64)tokenval.v.i < (gint64)SSIZE_MIN)
4077 conf_parserror(_("value too small"));
4079 val = (ssize_t)tokenval.v.i;
4083 #if SIZEOF_SIZE_T < SIZEOF_GINT64
4084 if (tokenval.v.int64 > (gint64)SSIZE_MAX)
4085 conf_parserror(_("value too large"));
4086 if (tokenval.v.int64 < (gint64)SSIZE_MIN)
4087 conf_parserror(_("value too small"));
4089 val = (ssize_t)tokenval.v.int64;
4092 case CONF_AMINFINITY:
4093 val = (ssize_t)SSIZE_MAX;
4097 conf_parserror(_("an integer is expected"));
4102 /* get multiplier, if any */
4103 get_conftoken(CONF_ANY);
4106 case CONF_NL: /* multiply by one */
4110 if (val > (ssize_t)(SSIZE_MAX / (ssize_t)1024))
4111 conf_parserror(_("value too large"));
4112 if (val < (ssize_t)(SSIZE_MIN / (ssize_t)1024))
4113 conf_parserror(_("value too small"));
4114 val *= (ssize_t)1024;
4117 if (val > (ssize_t)(SSIZE_MAX / 7))
4118 conf_parserror(_("value too large"));
4119 if (val < (ssize_t)(SSIZE_MIN / 7))
4120 conf_parserror(_("value too small"));
4125 if (val > (ssize_t)(SSIZE_MAX / (ssize_t)1024 * 1024))
4126 conf_parserror(_("value too large"));
4127 if (val < (ssize_t)(SSIZE_MIN / (ssize_t)1024 * 1024))
4128 conf_parserror(_("value too small"));
4129 val *= (ssize_t)(1024 * 1024);
4133 if (val > (ssize_t)(SSIZE_MAX / (1024 * 1024 * 1024)))
4134 conf_parserror(_("value too large"));
4135 if (val < (ssize_t)(SSIZE_MIN / (1024 * 1024 * 1024)))
4136 conf_parserror(_("value too small"));
4137 val *= (ssize_t)(1024 * 1024 * 1024);
4141 conf_parserror(_("value too large"));
4144 default: /* it was not a multiplier */
4160 keytable = numb_keytable;
4162 get_conftoken(CONF_ANY);
4166 val = (gint64)tokenval.v.i;
4170 val = (gint64)tokenval.v.size;
4174 val = tokenval.v.int64;
4177 case CONF_AMINFINITY:
4182 conf_parserror(_("an integer is expected"));
4187 /* get multiplier, if any */
4188 get_conftoken(CONF_ANY);
4191 case CONF_NL: /* multiply by one */
4197 if (val > G_MAXINT64/7 || val < ((gint64)G_MININT64)/7)
4198 conf_parserror(_("value too large"));
4203 if (val > G_MAXINT64/1024 || val < ((gint64)G_MININT64)/1024)
4204 conf_parserror(_("value too large"));
4209 if (val > G_MAXINT64/(1024*1024) || val < ((gint64)G_MININT64)/(1024*1024))
4210 conf_parserror(_("value too large"));
4215 if (val > G_MAXINT64/(1024*1024*1024) || val < ((gint64)G_MININT64)/(1024*1024*1024))
4216 conf_parserror(_("value too large"));
4217 val *= 1024*1024*1024;
4220 default: /* it was not a multiplier */
4237 keytable = bool_keytable;
4239 get_conftoken(CONF_ANY);
4243 if (tokenval.v.i != 0)
4250 if (tokenval.v.size != (size_t)0)
4257 if (tokenval.v.int64 != (gint64)0)
4273 val = 2; /* no argument - most likely TRUE */
4277 val = 3; /* a bad argument - most likely TRUE */
4278 conf_parserror(_("YES, NO, TRUE, FALSE, ON, OFF, 0, 1 expected"));
4290 if (seen->linenum && !allow_overwrites && current_line_num != -2) {
4291 conf_parserror(_("duplicate parameter; previous definition %s:%d"),
4292 seen->filename, seen->linenum);
4294 seen->filename = current_filename;
4295 seen->linenum = current_line_num;
4298 /* Validation functions */
4301 validate_nonnegative(
4302 struct conf_var_s *np,
4307 if(val_t__int(val) < 0)
4308 conf_parserror(_("%s must be nonnegative"), get_token_name(np->token));
4310 case CONFTYPE_INT64:
4311 if(val_t__int64(val) < 0)
4312 conf_parserror(_("%s must be nonnegative"), get_token_name(np->token));
4315 if(val_t__size(val) < 0)
4316 conf_parserror(_("%s must be positive"), get_token_name(np->token));
4319 conf_parserror(_("validate_nonnegative invalid type %d\n"), val->type);
4325 struct conf_var_s *np,
4330 if(val_t__int(val) == 0)
4331 conf_parserror(_("%s must not be 0"), get_token_name(np->token));
4333 case CONFTYPE_INT64:
4334 if(val_t__int64(val) == 0)
4335 conf_parserror(_("%s must not be 0"), get_token_name(np->token));
4338 if(val_t__time(val) == 0)
4339 conf_parserror(_("%s must not be 0"), get_token_name(np->token));
4342 if(val_t__size(val) == 0)
4343 conf_parserror(_("%s must not be 0"), get_token_name(np->token));
4346 conf_parserror(_("validate_non_zero invalid type %d\n"), val->type);
4352 struct conf_var_s *np,
4357 if(val_t__int(val) < 1)
4358 conf_parserror(_("%s must be positive"), get_token_name(np->token));
4360 case CONFTYPE_INT64:
4361 if(val_t__int64(val) < 1)
4362 conf_parserror(_("%s must be positive"), get_token_name(np->token));
4365 if(val_t__time(val) < 1)
4366 conf_parserror(_("%s must be positive"), get_token_name(np->token));
4369 if(val_t__size(val) < 1)
4370 conf_parserror(_("%s must be positive"), get_token_name(np->token));
4373 conf_parserror(_("validate_positive invalid type %d\n"), val->type);
4378 validate_runspercycle(
4379 struct conf_var_s *np G_GNUC_UNUSED,
4382 if(val_t__int(val) < -1)
4383 conf_parserror(_("runspercycle must be >= -1"));
4387 validate_bumppercent(
4388 struct conf_var_s *np G_GNUC_UNUSED,
4391 if(val_t__int(val) < 0 || val_t__int(val) > 100)
4392 conf_parserror(_("bumppercent must be between 0 and 100"));
4396 validate_inparallel(
4397 struct conf_var_s *np G_GNUC_UNUSED,
4400 if(val_t__int(val) < 1 || val_t__int(val) >MAX_DUMPERS)
4401 conf_parserror(_("inparallel must be between 1 and MAX_DUMPERS (%d)"),
4407 struct conf_var_s *np G_GNUC_UNUSED,
4410 if(val_t__real(val) < 0.999) {
4411 conf_parserror(_("bumpmult must one or more"));
4416 validate_displayunit(
4417 struct conf_var_s *np G_GNUC_UNUSED,
4418 val_t *val G_GNUC_UNUSED)
4420 char *s = val_t__str(val);
4421 if (strlen(s) == 1) {
4427 return; /* all good */
4429 /* lower-case values should get folded to upper case */
4434 s[0] = toupper(s[0]);
4441 conf_parserror(_("displayunit must be k,m,g or t."));
4446 struct conf_var_s *np G_GNUC_UNUSED,
4449 if(val_t__int(val) < 0 || val_t__int(val) > 100)
4450 conf_parserror(_("reserve must be between 0 and 100"));
4455 struct conf_var_s *np G_GNUC_UNUSED,
4458 val_t__int64(val) = am_floor(val_t__int64(val), DISK_BLOCK_KB);
4463 struct conf_var_s *np G_GNUC_UNUSED,
4466 /* NOTE: this function modifies the target value (rounding) */
4467 if(val_t__int64(val) == 0) {
4468 val_t__int64(val) = ((G_MAXINT64 / 1024) - (2 * DISK_BLOCK_KB));
4470 else if(val_t__int64(val) < 0) {
4471 conf_parserror(_("Negative chunksize (%lld) is no longer supported"), (long long)val_t__int64(val));
4473 val_t__int64(val) = am_floor(val_t__int64(val), (gint64)DISK_BLOCK_KB);
4474 if (val_t__int64(val) < 2*DISK_BLOCK_KB) {
4475 conf_parserror("chunksize must be at least %dkb", 2*DISK_BLOCK_KB);
4481 struct conf_var_s *np G_GNUC_UNUSED,
4484 if(val_t__size(val) < DISK_BLOCK_KB) {
4485 conf_parserror(_("Tape blocksize must be at least %d KBytes"),
4492 struct conf_var_s *np G_GNUC_UNUSED,
4495 if(val_t__int(val) < 0 || val_t__int(val) > 9) {
4496 conf_parserror(_("Debug must be between 0 and 9"));
4501 validate_port_range(
4507 /* check both values are in range */
4508 for (i = 0; i < 2; i++) {
4509 if(val_t__intrange(val)[0] < smallest || val_t__intrange(val)[0] > largest) {
4510 conf_parserror(_("portrange must be in the range %d to %d, inclusive"), smallest, largest);
4514 /* and check they're in the right order and not equal */
4515 if (val_t__intrange(val)[0] > val_t__intrange(val)[1]) {
4516 conf_parserror(_("portranges must be in order from low to high"));
4521 validate_reserved_port_range(
4522 struct conf_var_s *np G_GNUC_UNUSED,
4525 validate_port_range(val, 1, IPPORT_RESERVED-1);
4529 validate_unreserved_port_range(
4530 struct conf_var_s *np G_GNUC_UNUSED,
4533 validate_port_range(val, IPPORT_RESERVED, 65535);
4537 * Initialization Implementation
4542 config_init_flags flags,
4543 char *arg_config_name)
4545 if (!(flags & CONFIG_INIT_OVERLAY)) {
4546 /* Clear out anything that's already in there */
4549 /* and set everything to default values */
4552 allow_overwrites = FALSE;
4554 if (!config_initialized) {
4555 error(_("Attempt to overlay configuration with no existing configuration"));
4559 allow_overwrites = TRUE;
4562 /* store away our client-ness for later reference */
4563 config_client = flags & CONFIG_INIT_CLIENT;
4565 /* if we're using an explicit name, but the name is '.', then we're using the
4566 * current directory */
4567 if ((flags & CONFIG_INIT_EXPLICIT_NAME) && arg_config_name) {
4568 if (0 == strcmp(arg_config_name, "."))
4569 flags = (flags & (~CONFIG_INIT_EXPLICIT_NAME)) | CONFIG_INIT_USE_CWD;
4572 if ((flags & CONFIG_INIT_EXPLICIT_NAME) && arg_config_name) {
4573 config_name = newstralloc(config_name, arg_config_name);
4574 config_dir = newvstralloc(config_dir, CONFIG_DIR, "/", arg_config_name, NULL);
4575 } else if (flags & CONFIG_INIT_USE_CWD) {
4578 cwd = get_original_cwd();
4580 /* (this isn't a config error, so it's always fatal) */
4581 error(_("Cannot determine current working directory"));
4585 config_dir = stralloc2(cwd, "/");
4586 if ((config_name = strrchr(cwd, '/')) != NULL) {
4587 config_name = stralloc(config_name + 1);
4591 } else if (flags & CONFIG_INIT_CLIENT) {
4592 amfree(config_name);
4593 config_dir = newstralloc(config_dir, CONFIG_DIR);
4595 /* ok, then, we won't read anything (for e.g., amrestore) */
4596 amfree(config_name);
4600 /* setup for apply_config_overrides */
4601 if (flags & CONFIG_INIT_CLIENT) {
4602 keytable = client_keytab;
4603 parsetable = client_var;
4605 keytable = server_keytab;
4606 parsetable = server_var;
4609 if (config_overrides) {
4611 for (i = 0; i < config_overrides->n_used; i++) {
4612 config_overrides->ovr[i].applied = FALSE;
4616 /* apply config overrides to default setting */
4617 apply_config_overrides(config_overrides, NULL);
4619 /* If we have a config_dir, we can try reading something */
4621 if (flags & CONFIG_INIT_CLIENT) {
4622 config_filename = newvstralloc(config_filename, config_dir, "/amanda-client.conf", NULL);
4624 config_filename = newvstralloc(config_filename, config_dir, "/amanda.conf", NULL);
4627 read_conffile(config_filename,
4628 flags & CONFIG_INIT_CLIENT,
4629 flags & CONFIG_INIT_CLIENT);
4631 amfree(config_filename);
4634 /* apply config overrides to default setting */
4635 apply_config_overrides(config_overrides, NULL);
4637 if (config_overrides) {
4639 for (i = 0; i < config_overrides->n_used; i++) {
4640 if (config_overrides->ovr[i].applied == FALSE) {
4641 conf_parserror(_("unknown parameter '%s'"),
4642 config_overrides->ovr[i].key);
4647 update_derived_values(flags & CONFIG_INIT_CLIENT);
4649 return cfgerr_level;
4657 dumptype_t *dp, *dpnext;
4658 tapetype_t *tp, *tpnext;
4659 interface_t *ip, *ipnext;
4660 application_t *ap, *apnext;
4661 pp_script_t *pp, *ppnext;
4662 device_config_t *dc, *dcnext;
4663 changer_config_t *cc, *ccnext;
4666 if (!config_initialized) return;
4668 for(hp=holdinglist; hp != NULL; hp = hp->next) {
4671 for(i=0; i<HOLDING_HOLDING; i++) {
4672 free_val_t(&hd->value[i]);
4675 slist_free_full(holdinglist, g_free);
4678 for(dp=dumplist; dp != NULL; dp = dpnext) {
4680 for(i=0; i<DUMPTYPE_DUMPTYPE; i++) {
4681 free_val_t(&dp->value[i]);
4688 for(tp=tapelist; tp != NULL; tp = tpnext) {
4690 for(i=0; i<TAPETYPE_TAPETYPE; i++) {
4691 free_val_t(&tp->value[i]);
4698 for(ip=interface_list; ip != NULL; ip = ipnext) {
4700 for(i=0; i<INTER_INTER; i++) {
4701 free_val_t(&ip->value[i]);
4706 interface_list = NULL;
4708 for(ap=application_list; ap != NULL; ap = apnext) {
4710 for(i=0; i<APPLICATION_APPLICATION; i++) {
4711 free_val_t(&ap->value[i]);
4716 application_list = NULL;
4718 for(pp=pp_script_list; pp != NULL; pp = ppnext) {
4720 for(i=0; i<PP_SCRIPT_PP_SCRIPT; i++) {
4721 free_val_t(&pp->value[i]);
4726 pp_script_list = NULL;
4728 for(dc=device_config_list; dc != NULL; dc = dcnext) {
4730 for(i=0; i<DEVICE_CONFIG_DEVICE_CONFIG; i++) {
4731 free_val_t(&dc->value[i]);
4736 device_config_list = NULL;
4738 for(cc=changer_config_list; cc != NULL; cc = ccnext) {
4740 for(i=0; i<CHANGER_CONFIG_CHANGER_CONFIG; i++) {
4741 free_val_t(&cc->value[i]);
4747 changer_config_list = NULL;
4749 for(i=0; i<CNF_CNF; i++)
4750 free_val_t(&conf_data[i]);
4752 if (config_overrides) {
4753 free_config_overrides(config_overrides);
4754 config_overrides = NULL;
4757 amfree(config_name);
4759 amfree(config_filename);
4761 slist_free_full(seen_filenames, g_free);
4762 seen_filenames = NULL;
4764 config_client = FALSE;
4766 config_clear_errors();
4767 config_initialized = FALSE;
4774 assert(!config_initialized);
4776 /* defaults for exported variables */
4777 conf_init_str(&conf_data[CNF_ORG], DEFAULT_CONFIG);
4778 conf_init_str(&conf_data[CNF_CONF], DEFAULT_CONFIG);
4779 conf_init_str(&conf_data[CNF_INDEX_SERVER], DEFAULT_SERVER);
4780 conf_init_str(&conf_data[CNF_TAPE_SERVER], DEFAULT_TAPE_SERVER);
4781 conf_init_str(&conf_data[CNF_AUTH], "bsd");
4782 conf_init_str(&conf_data[CNF_SSH_KEYS], "");
4783 conf_init_str(&conf_data[CNF_AMANDAD_PATH], "");
4784 conf_init_str(&conf_data[CNF_CLIENT_USERNAME], "");
4785 conf_init_str(&conf_data[CNF_CLIENT_PORT], "");
4786 conf_init_str(&conf_data[CNF_GNUTAR_LIST_DIR], GNUTAR_LISTED_INCREMENTAL_DIR);
4787 conf_init_str(&conf_data[CNF_AMANDATES], DEFAULT_AMANDATES_FILE);
4788 conf_init_str(&conf_data[CNF_MAILTO], "");
4789 conf_init_str(&conf_data[CNF_DUMPUSER], CLIENT_LOGIN);
4790 conf_init_str(&conf_data[CNF_TAPEDEV], DEFAULT_TAPE_DEVICE);
4791 conf_init_proplist(&conf_data[CNF_DEVICE_PROPERTY]);
4792 conf_init_proplist(&conf_data[CNF_PROPERTY]);
4793 conf_init_str(&conf_data[CNF_CHANGERDEV], NULL);
4794 conf_init_str(&conf_data[CNF_CHANGERFILE] , "changer");
4795 conf_init_str (&conf_data[CNF_LABELSTR] , ".*");
4796 conf_init_str (&conf_data[CNF_TAPELIST] , "tapelist");
4797 conf_init_str (&conf_data[CNF_DISKFILE] , "disklist");
4798 conf_init_str (&conf_data[CNF_INFOFILE] , "/usr/adm/amanda/curinfo");
4799 conf_init_str (&conf_data[CNF_LOGDIR] , "/usr/adm/amanda");
4800 conf_init_str (&conf_data[CNF_INDEXDIR] , "/usr/adm/amanda/index");
4801 conf_init_ident (&conf_data[CNF_TAPETYPE] , "DEFAULT_TAPE");
4802 conf_init_identlist(&conf_data[CNF_HOLDINGDISK] , NULL);
4803 conf_init_int (&conf_data[CNF_DUMPCYCLE] , 10);
4804 conf_init_int (&conf_data[CNF_RUNSPERCYCLE] , 0);
4805 conf_init_int (&conf_data[CNF_TAPECYCLE] , 15);
4806 conf_init_int (&conf_data[CNF_NETUSAGE] , 8000);
4807 conf_init_int (&conf_data[CNF_INPARALLEL] , 10);
4808 conf_init_str (&conf_data[CNF_DUMPORDER] , "ttt");
4809 conf_init_int (&conf_data[CNF_BUMPPERCENT] , 0);
4810 conf_init_int64 (&conf_data[CNF_BUMPSIZE] , (gint64)10*1024);
4811 conf_init_real (&conf_data[CNF_BUMPMULT] , 1.5);
4812 conf_init_int (&conf_data[CNF_BUMPDAYS] , 2);
4813 conf_init_str (&conf_data[CNF_TPCHANGER] , "");
4814 conf_init_int (&conf_data[CNF_RUNTAPES] , 1);
4815 conf_init_int (&conf_data[CNF_MAXDUMPS] , 1);
4816 conf_init_int (&conf_data[CNF_ETIMEOUT] , 300);
4817 conf_init_int (&conf_data[CNF_DTIMEOUT] , 1800);
4818 conf_init_int (&conf_data[CNF_CTIMEOUT] , 30);
4819 conf_init_size (&conf_data[CNF_DEVICE_OUTPUT_BUFFER_SIZE], 40*32768);
4820 conf_init_str (&conf_data[CNF_PRINTER] , "");
4821 conf_init_str (&conf_data[CNF_MAILER] , DEFAULT_MAILER);
4822 conf_init_bool (&conf_data[CNF_AUTOFLUSH] , 0);
4823 conf_init_int (&conf_data[CNF_RESERVE] , 100);
4824 conf_init_int64 (&conf_data[CNF_MAXDUMPSIZE] , (gint64)-1);
4825 conf_init_str (&conf_data[CNF_COLUMNSPEC] , "");
4826 conf_init_bool (&conf_data[CNF_AMRECOVER_DO_FSF] , 1);
4827 conf_init_str (&conf_data[CNF_AMRECOVER_CHANGER] , "");
4828 conf_init_bool (&conf_data[CNF_AMRECOVER_CHECK_LABEL], 1);
4829 conf_init_taperalgo(&conf_data[CNF_TAPERALGO] , 0);
4830 conf_init_int (&conf_data[CNF_TAPER_PARALLEL_WRITE] , 1);
4831 conf_init_int (&conf_data[CNF_FLUSH_THRESHOLD_DUMPED] , 0);
4832 conf_init_int (&conf_data[CNF_FLUSH_THRESHOLD_SCHEDULED], 0);
4833 conf_init_int (&conf_data[CNF_TAPERFLUSH] , 0);
4834 conf_init_str (&conf_data[CNF_DISPLAYUNIT] , "k");
4835 conf_init_str (&conf_data[CNF_KRB5KEYTAB] , "/.amanda-v5-keytab");
4836 conf_init_str (&conf_data[CNF_KRB5PRINCIPAL] , "service/amanda");
4837 conf_init_str (&conf_data[CNF_LABEL_NEW_TAPES] , "");
4838 conf_init_bool (&conf_data[CNF_USETIMESTAMPS] , 1);
4839 conf_init_int (&conf_data[CNF_CONNECT_TRIES] , 3);
4840 conf_init_int (&conf_data[CNF_REP_TRIES] , 5);
4841 conf_init_int (&conf_data[CNF_REQ_TRIES] , 3);
4842 conf_init_int (&conf_data[CNF_DEBUG_DAYS] , AMANDA_DEBUG_DAYS);
4843 conf_init_int (&conf_data[CNF_DEBUG_AMANDAD] , 0);
4844 conf_init_int (&conf_data[CNF_DEBUG_RECOVERY] , 1);
4845 conf_init_int (&conf_data[CNF_DEBUG_AMIDXTAPED] , 0);
4846 conf_init_int (&conf_data[CNF_DEBUG_AMINDEXD] , 0);
4847 conf_init_int (&conf_data[CNF_DEBUG_AMRECOVER] , 0);
4848 conf_init_int (&conf_data[CNF_DEBUG_AUTH] , 0);
4849 conf_init_int (&conf_data[CNF_DEBUG_EVENT] , 0);
4850 conf_init_int (&conf_data[CNF_DEBUG_HOLDING] , 0);
4851 conf_init_int (&conf_data[CNF_DEBUG_PROTOCOL] , 0);
4852 conf_init_int (&conf_data[CNF_DEBUG_PLANNER] , 0);
4853 conf_init_int (&conf_data[CNF_DEBUG_DRIVER] , 0);
4854 conf_init_int (&conf_data[CNF_DEBUG_DUMPER] , 0);
4855 conf_init_int (&conf_data[CNF_DEBUG_CHUNKER] , 0);
4856 conf_init_int (&conf_data[CNF_DEBUG_TAPER] , 0);
4857 conf_init_int (&conf_data[CNF_DEBUG_SELFCHECK] , 0);
4858 conf_init_int (&conf_data[CNF_DEBUG_SENDSIZE] , 0);
4859 conf_init_int (&conf_data[CNF_DEBUG_SENDBACKUP] , 0);
4861 conf_init_intrange (&conf_data[CNF_RESERVED_UDP_PORT] , UDPPORTRANGE);
4863 conf_init_intrange (&conf_data[CNF_RESERVED_UDP_PORT] , 512, IPPORT_RESERVED-1);
4865 #ifdef LOW_TCPPORTRANGE
4866 conf_init_intrange (&conf_data[CNF_RESERVED_TCP_PORT] , LOW_TCPPORTRANGE);
4868 conf_init_intrange (&conf_data[CNF_RESERVED_TCP_PORT] , 512, IPPORT_RESERVED-1);
4871 conf_init_intrange (&conf_data[CNF_UNRESERVED_TCP_PORT] , TCPPORTRANGE);
4873 conf_init_intrange (&conf_data[CNF_UNRESERVED_TCP_PORT] , IPPORT_RESERVED, 65535);
4875 conf_init_send_amreport (&conf_data[CNF_SEND_AMREPORT_ON], SEND_AMREPORT_ALL);
4876 conf_init_autolabel(&conf_data[CNF_AUTOLABEL]);
4877 conf_init_recovery_limit(&conf_data[CNF_RECOVERY_LIMIT]);
4879 /* reset internal variables */
4880 config_clear_errors();
4881 cfgerr_level = CFGERR_OK;
4882 allow_overwrites = 0;
4885 /* create some predefined dumptypes for backwards compatability */
4886 init_dumptype_defaults();
4887 dpcur.name = stralloc("NO-COMPRESS");
4888 dpcur.seen.linenum = -1;
4889 free_val_t(&dpcur.value[DUMPTYPE_COMPRESS]);
4890 val_t__compress(&dpcur.value[DUMPTYPE_COMPRESS]) = COMP_NONE;
4891 val_t__seen(&dpcur.value[DUMPTYPE_COMPRESS]).linenum = -1;
4894 init_dumptype_defaults();
4895 dpcur.name = stralloc("COMPRESS-FAST");
4896 dpcur.seen.linenum = -1;
4897 free_val_t(&dpcur.value[DUMPTYPE_COMPRESS]);
4898 val_t__compress(&dpcur.value[DUMPTYPE_COMPRESS]) = COMP_FAST;
4899 val_t__seen(&dpcur.value[DUMPTYPE_COMPRESS]).linenum = -1;
4902 init_dumptype_defaults();
4903 dpcur.name = stralloc("COMPRESS-BEST");
4904 dpcur.seen.linenum = -1;
4905 free_val_t(&dpcur.value[DUMPTYPE_COMPRESS]);
4906 val_t__compress(&dpcur.value[DUMPTYPE_COMPRESS]) = COMP_BEST;
4907 val_t__seen(&dpcur.value[DUMPTYPE_COMPRESS]).linenum = -1;
4910 init_dumptype_defaults();
4911 dpcur.name = stralloc("COMPRESS-CUST");
4912 dpcur.seen.linenum = -1;
4913 free_val_t(&dpcur.value[DUMPTYPE_COMPRESS]);
4914 val_t__compress(&dpcur.value[DUMPTYPE_COMPRESS]) = COMP_CUST;
4915 val_t__seen(&dpcur.value[DUMPTYPE_COMPRESS]).linenum = -1;
4918 init_dumptype_defaults();
4919 dpcur.name = stralloc("SRVCOMPRESS");
4920 dpcur.seen.linenum = -1;
4921 free_val_t(&dpcur.value[DUMPTYPE_COMPRESS]);
4922 val_t__compress(&dpcur.value[DUMPTYPE_COMPRESS]) = COMP_SERVER_FAST;
4923 val_t__seen(&dpcur.value[DUMPTYPE_COMPRESS]).linenum = -1;
4926 init_dumptype_defaults();
4927 dpcur.name = stralloc("BSD-AUTH");
4928 dpcur.seen.linenum = -1;
4929 free_val_t(&dpcur.value[DUMPTYPE_AUTH]);
4930 val_t__str(&dpcur.value[DUMPTYPE_AUTH]) = stralloc("BSD");
4931 val_t__seen(&dpcur.value[DUMPTYPE_AUTH]).linenum = -1;
4934 init_dumptype_defaults();
4935 dpcur.name = stralloc("NO-RECORD");
4936 dpcur.seen.linenum = -1;
4937 free_val_t(&dpcur.value[DUMPTYPE_RECORD]);
4938 val_t__int(&dpcur.value[DUMPTYPE_RECORD]) = 0;
4939 val_t__seen(&dpcur.value[DUMPTYPE_RECORD]).linenum = -1;
4942 init_dumptype_defaults();
4943 dpcur.name = stralloc("NO-HOLD");
4944 dpcur.seen.linenum = -1;
4945 free_val_t(&dpcur.value[DUMPTYPE_HOLDINGDISK]);
4946 val_t__holding(&dpcur.value[DUMPTYPE_HOLDINGDISK]) = HOLD_NEVER;
4947 val_t__seen(&dpcur.value[DUMPTYPE_HOLDINGDISK]).linenum = -1;
4950 init_dumptype_defaults();
4951 dpcur.name = stralloc("NO-FULL");
4952 dpcur.seen.linenum = -1;
4953 free_val_t(&dpcur.value[DUMPTYPE_STRATEGY]);
4954 val_t__strategy(&dpcur.value[DUMPTYPE_STRATEGY]) = DS_NOFULL;
4955 val_t__seen(&dpcur.value[DUMPTYPE_STRATEGY]).linenum = -1;
4958 /* And we're initialized! */
4959 config_initialized = 1;
4966 char **config_options;
4967 char **config_option;
4968 int n_config_overrides = 0;
4971 if (config_overrides)
4972 n_config_overrides = config_overrides->n_used;
4974 config_options = alloc((first+n_config_overrides+1)*SIZEOF(char *));
4975 config_option = config_options + first;
4977 for (i = 0; i < n_config_overrides; i++) {
4978 char *key = config_overrides->ovr[i].key;
4979 char *value = config_overrides->ovr[i].value;
4980 *config_option = vstralloc("-o", key, "=", value, NULL);
4984 *config_option = NULL; /* add terminating sentinel */
4986 return config_options;
4990 update_derived_values(
4998 /* Add a 'default' interface if one doesn't already exist */
4999 if (!(ip = lookup_interface("default"))) {
5000 init_interface_defaults();
5001 ifcur.name = stralloc("default");
5002 ifcur.seen = val_t__seen(getconf(CNF_NETUSAGE));
5005 ip = lookup_interface("default");
5008 /* .. and set its maxusage from 'netusage' */
5009 if (!interface_seen(ip, INTER_MAXUSAGE)) {
5012 v = interface_getconf(ip, INTER_COMMENT);
5014 val_t__str(v) = stralloc(_("implicit from NETUSAGE"));
5015 val_t__seen(v) = val_t__seen(getconf(CNF_NETUSAGE));
5017 v = interface_getconf(ip, INTER_MAXUSAGE);
5019 val_t__int(v) = getconf_int(CNF_NETUSAGE);
5020 val_t__seen(v) = val_t__seen(getconf(CNF_NETUSAGE));
5023 /* Check the tapetype is defined */
5024 if (lookup_tapetype(getconf_str(CNF_TAPETYPE)) == NULL) {
5025 /* Create a default tapetype so that other code has
5026 * something to refer to, but don't pretend it's real */
5027 if (!getconf_seen(CNF_TAPETYPE) &&
5028 strcmp(getconf_str(CNF_TAPETYPE), "DEFAULT_TAPE") == 0 &&
5029 !lookup_tapetype("DEFAULT_TAPE")) {
5030 init_tapetype_defaults();
5031 tpcur.name = stralloc("DEFAULT_TAPE");
5032 tpcur.seen = val_t__seen(getconf(CNF_TAPETYPE));
5035 conf_parserror(_("tapetype %s is not defined"),
5036 getconf_str(CNF_TAPETYPE));
5040 /* Check the holdingdisk are defined */
5041 for (il = getconf_identlist(CNF_HOLDINGDISK);
5042 il != NULL; il = il->next) {
5043 hd = lookup_holdingdisk(il->data);
5045 conf_parserror(_("holdingdisk %s is not defined"),
5050 if ((getconf_seen(CNF_LABEL_NEW_TAPES) > 0 &&
5051 getconf_seen(CNF_AUTOLABEL) > 0) ||
5052 (getconf_seen(CNF_LABEL_NEW_TAPES) < 0 &&
5053 getconf_seen(CNF_AUTOLABEL) < 0)) {
5054 conf_parserror(_("Can't specify both label-new-tapes and autolabel"));
5056 if ((getconf_seen(CNF_LABEL_NEW_TAPES) != 0 &&
5057 getconf_seen(CNF_AUTOLABEL) == 0) ||
5058 (getconf_seen(CNF_LABEL_NEW_TAPES) < 0 &&
5059 getconf_seen(CNF_AUTOLABEL) >= 0)) {
5060 autolabel_t *autolabel = &(conf_data[CNF_AUTOLABEL].v.autolabel);
5061 autolabel->template = g_strdup(getconf_str(CNF_LABEL_NEW_TAPES));
5062 if (!autolabel->template || autolabel->template == '\0') {
5063 autolabel->template = NULL;
5064 autolabel->autolabel = 0;
5066 autolabel->autolabel = AL_VOLUME_ERROR | AL_EMPTY;
5071 /* fill in the debug_* values */
5072 debug_amandad = getconf_int(CNF_DEBUG_AMANDAD);
5073 debug_recovery = getconf_int(CNF_DEBUG_RECOVERY);
5074 debug_amidxtaped = getconf_int(CNF_DEBUG_AMIDXTAPED);
5075 debug_amindexd = getconf_int(CNF_DEBUG_AMINDEXD);
5076 debug_amrecover = getconf_int(CNF_DEBUG_AMRECOVER);
5077 debug_auth = getconf_int(CNF_DEBUG_AUTH);
5078 debug_event = getconf_int(CNF_DEBUG_EVENT);
5079 debug_holding = getconf_int(CNF_DEBUG_HOLDING);
5080 debug_protocol = getconf_int(CNF_DEBUG_PROTOCOL);
5081 debug_planner = getconf_int(CNF_DEBUG_PLANNER);
5082 debug_driver = getconf_int(CNF_DEBUG_DRIVER);
5083 debug_dumper = getconf_int(CNF_DEBUG_DUMPER);
5084 debug_chunker = getconf_int(CNF_DEBUG_CHUNKER);
5085 debug_taper = getconf_int(CNF_DEBUG_TAPER);
5086 debug_selfcheck = getconf_int(CNF_DEBUG_SELFCHECK);
5087 debug_sendsize = getconf_int(CNF_DEBUG_SENDSIZE);
5088 debug_sendbackup = getconf_int(CNF_DEBUG_SENDBACKUP);
5090 /* And finally, display unit */
5091 switch (getconf_str(CNF_DISPLAYUNIT)[0]) {
5099 unit_divisor = 1024;
5104 unit_divisor = 1024*1024;
5109 unit_divisor = 1024*1024*1024;
5113 error(_("Invalid displayunit missed by validate_displayunit"));
5123 val->seen.linenum = 0;
5124 val->seen.filename = NULL;
5125 val->type = CONFTYPE_INT;
5126 val_t__int(val) = i;
5134 val->seen.linenum = 0;
5135 val->seen.filename = NULL;
5136 val->type = CONFTYPE_INT64;
5137 val_t__int64(val) = l;
5145 val->seen.linenum = 0;
5146 val->seen.filename = NULL;
5147 val->type = CONFTYPE_REAL;
5148 val_t__real(val) = r;
5156 val->seen.linenum = 0;
5157 val->seen.filename = NULL;
5158 val->type = CONFTYPE_STR;
5160 val->v.s = stralloc(s);
5170 val->seen.linenum = 0;
5171 val->seen.filename = NULL;
5172 val->type = CONFTYPE_IDENT;
5174 val->v.s = stralloc(s);
5180 conf_init_identlist(
5184 val->seen.linenum = 0;
5185 val->seen.filename = NULL;
5186 val->type = CONFTYPE_IDENTLIST;
5187 val->v.identlist = NULL;
5189 val->v.identlist = g_slist_append(val->v.identlist, stralloc(s));
5197 val->seen.linenum = 0;
5198 val->seen.filename = NULL;
5199 val->type = CONFTYPE_TIME;
5200 val_t__time(val) = t;
5208 val->seen.linenum = 0;
5209 val->seen.filename = NULL;
5210 val->type = CONFTYPE_SIZE;
5211 val_t__size(val) = sz;
5219 val->seen.linenum = 0;
5220 val->seen.filename = NULL;
5221 val->type = CONFTYPE_BOOLEAN;
5222 val_t__boolean(val) = i;
5230 val->seen.linenum = 0;
5231 val->seen.filename = NULL;
5232 val->type = CONFTYPE_COMPRESS;
5233 val_t__compress(val) = (int)i;
5241 val->seen.linenum = 0;
5242 val->seen.filename = NULL;
5243 val->type = CONFTYPE_ENCRYPT;
5244 val_t__encrypt(val) = (int)i;
5248 conf_init_part_cache_type(
5250 part_cache_type_t i)
5252 val->seen.linenum = 0;
5253 val->seen.filename = NULL;
5254 val->type = CONFTYPE_PART_CACHE_TYPE;
5255 val_t__part_cache_type(val) = (int)i;
5259 conf_init_recovery_limit(
5262 val->seen.linenum = 0;
5263 val->seen.filename = NULL;
5264 val->type = CONFTYPE_RECOVERY_LIMIT;
5265 val_t__recovery_limit(val).match_pats = NULL;
5266 val_t__recovery_limit(val).same_host = FALSE;
5270 conf_init_data_path(
5274 val->seen.linenum = 0;
5275 val->seen.filename = NULL;
5276 val->type = CONFTYPE_DATA_PATH;
5277 val_t__data_path(val) = (int)i;
5283 dump_holdingdisk_t i)
5285 val->seen.linenum = 0;
5286 val->seen.filename = NULL;
5287 val->type = CONFTYPE_HOLDING;
5288 val_t__holding(val) = (int)i;
5292 conf_init_estimatelist(
5296 GSList *estimates = NULL;
5297 val->seen.linenum = 0;
5298 val->seen.filename = NULL;
5299 val->type = CONFTYPE_ESTIMATELIST;
5300 estimates = g_slist_append(estimates, GINT_TO_POINTER(i));
5301 val_t__estimatelist(val) = estimates;
5309 val->seen.linenum = 0;
5310 val->seen.filename = NULL;
5311 val->type = CONFTYPE_STRATEGY;
5312 val_t__strategy(val) = i;
5316 conf_init_taperalgo(
5320 val->seen.linenum = 0;
5321 val->seen.filename = NULL;
5322 val->type = CONFTYPE_TAPERALGO;
5323 val_t__taperalgo(val) = i;
5331 val->seen.linenum = 0;
5332 val->seen.filename = NULL;
5333 val->type = CONFTYPE_PRIORITY;
5334 val_t__priority(val) = i;
5343 val->seen.linenum = 0;
5344 val->seen.filename = NULL;
5345 val->type = CONFTYPE_RATE;
5346 val_t__rate(val)[0] = r1;
5347 val_t__rate(val)[1] = r2;
5351 conf_init_exinclude(
5354 val->seen.linenum = 0;
5355 val->seen.filename = NULL;
5356 val->type = CONFTYPE_EXINCLUDE;
5357 val_t__exinclude(val).optional = 0;
5358 val_t__exinclude(val).sl_list = NULL;
5359 val_t__exinclude(val).sl_file = NULL;
5368 val->seen.linenum = 0;
5369 val->seen.filename = NULL;
5370 val->type = CONFTYPE_INTRANGE;
5371 val_t__intrange(val)[0] = i1;
5372 val_t__intrange(val)[1] = i2;
5376 conf_init_autolabel(
5378 val->seen.linenum = 0;
5379 val->seen.filename = NULL;
5380 val->type = CONFTYPE_AUTOLABEL;
5381 val->v.autolabel.template = NULL;
5382 val->v.autolabel.autolabel = 0;
5389 property_t *propery = (property_t *)p;
5390 slist_free_full(propery->values, g_free);
5398 val->seen.linenum = 0;
5399 val->seen.filename = NULL;
5400 val->type = CONFTYPE_PROPLIST;
5401 val_t__proplist(val) =
5402 g_hash_table_new_full(g_str_amanda_hash, g_str_amanda_equal,
5403 &g_free, &free_property_t);
5407 conf_init_execute_on(
5411 val->seen.linenum = 0;
5412 val->seen.filename = NULL;
5413 val->type = CONFTYPE_EXECUTE_ON;
5418 conf_init_execute_where(
5422 val->seen.linenum = 0;
5423 val->seen.filename = NULL;
5424 val->type = CONFTYPE_EXECUTE_WHERE;
5429 conf_init_send_amreport(
5433 val->seen.linenum = 0;
5434 val->seen.filename = NULL;
5435 val->type = CONFTYPE_SEND_AMREPORT_ON;
5439 static void conf_init_application(val_t *val) {
5440 val->seen.linenum = 0;
5441 val->seen.filename = NULL;
5442 val->type = CONFTYPE_APPLICATION;
5448 * Config access implementation
5452 getconf(confparm_key key)
5454 assert(key < CNF_CNF);
5455 return &conf_data[key];
5469 device_config_t *dc;
5470 changer_config_t *cc;
5473 if (strcasecmp(listname,"tapetype") == 0) {
5474 for(tp = tapelist; tp != NULL; tp=tp->next) {
5475 rv = g_slist_append(rv, tp->name);
5477 } else if (strcasecmp(listname,"dumptype") == 0) {
5478 for(dp = dumplist; dp != NULL; dp=dp->next) {
5479 rv = g_slist_append(rv, dp->name);
5481 } else if (strcasecmp(listname,"holdingdisk") == 0) {
5482 for(hp = holdinglist; hp != NULL; hp=hp->next) {
5484 rv = g_slist_append(rv, hd->name);
5486 } else if (strcasecmp(listname,"interface") == 0) {
5487 for(ip = interface_list; ip != NULL; ip=ip->next) {
5488 rv = g_slist_append(rv, ip->name);
5490 } else if (strcasecmp(listname,"application_tool") == 0
5491 || strcasecmp(listname,"application-tool") == 0
5492 || strcasecmp(listname,"application") == 0) {
5493 for(ap = application_list; ap != NULL; ap=ap->next) {
5494 rv = g_slist_append(rv, ap->name);
5496 } else if (strcasecmp(listname,"script_tool") == 0
5497 || strcasecmp(listname,"script-tool") == 0
5498 || strcasecmp(listname,"script") == 0) {
5499 for(pp = pp_script_list; pp != NULL; pp=pp->next) {
5500 rv = g_slist_append(rv, pp->name);
5502 } else if (strcasecmp(listname,"device") == 0) {
5503 for(dc = device_config_list; dc != NULL; dc=dc->next) {
5504 rv = g_slist_append(rv, dc->name);
5506 } else if (strcasecmp(listname,"changer") == 0) {
5507 for(cc = changer_config_list; cc != NULL; cc=cc->next) {
5508 rv = g_slist_append(rv, cc->name);
5520 if (!parm_key_info(key, NULL, &rv))
5532 for(p = tapelist; p != NULL; p = p->next) {
5533 if(strcasecmp(p->name, str) == 0) return p;
5543 assert(ttyp != NULL);
5544 assert(key < TAPETYPE_TAPETYPE);
5545 return &ttyp->value[key];
5550 conf_var_t *np G_GNUC_UNUSED,
5553 if (strcmp(val->v.s, "DUMP") != 0 &&
5554 strcmp(val->v.s, "GNUTAR") != 0 &&
5555 strcmp(val->v.s, "STAR") != 0 &&
5556 strcmp(val->v.s, "APPLICATION") != 0)
5557 conf_parserror("program must be \"DUMP\", \"GNUTAR\", \"STAR\" or \"APPLICATION\"");
5564 assert(ttyp != NULL);
5574 for(p = dumplist; p != NULL; p = p->next) {
5575 if(strcasecmp(p->name, str) == 0) return p;
5585 assert(dtyp != NULL);
5586 assert(key < DUMPTYPE_DUMPTYPE);
5587 return &dtyp->value[key];
5594 assert(dtyp != NULL);
5604 for(p = interface_list; p != NULL; p = p->next) {
5605 if(strcasecmp(p->name, str) == 0) return p;
5615 assert(iface != NULL);
5616 assert(key < INTER_INTER);
5617 return &iface->value[key];
5624 assert(iface != NULL);
5635 for (hp = holdinglist; hp != NULL; hp = hp->next) {
5637 if (strcasecmp(hd->name, str) == 0) return hd;
5643 getconf_holdingdisks(
5650 holdingdisk_getconf(
5651 holdingdisk_t *hdisk,
5652 holdingdisk_key key)
5654 assert(hdisk != NULL);
5655 assert(key < HOLDING_HOLDING);
5656 return &hdisk->value[key];
5661 holdingdisk_t *hdisk)
5663 assert(hdisk != NULL);
5673 for(p = application_list; p != NULL; p = p->next) {
5674 if(strcasecmp(p->name, str) == 0) return p;
5680 application_getconf(
5682 application_key key)
5685 assert(key < APPLICATION_APPLICATION);
5686 return &ap->value[key];
5703 for(pps = pp_script_list; pps != NULL; pps = pps->next) {
5704 if(strcasecmp(pps->name, str) == 0) return pps;
5714 assert(pps != NULL);
5715 assert(key < PP_SCRIPT_PP_SCRIPT);
5716 return &pps->value[key];
5723 assert(pps != NULL);
5728 lookup_device_config(
5731 device_config_t *devconf;
5733 for(devconf = device_config_list; devconf != NULL; devconf = devconf->next) {
5734 if(strcasecmp(devconf->name, str) == 0) return devconf;
5740 device_config_getconf(
5741 device_config_t *devconf,
5742 device_config_key key)
5744 assert(devconf != NULL);
5745 assert(key < DEVICE_CONFIG_DEVICE_CONFIG);
5746 return &devconf->value[key];
5751 device_config_t *devconf)
5753 assert(devconf != NULL);
5754 return devconf->name;
5758 lookup_changer_config(
5761 changer_config_t *devconf;
5763 for(devconf = changer_config_list; devconf != NULL; devconf = devconf->next) {
5764 if(strcasecmp(devconf->name, str) == 0) return devconf;
5770 changer_config_getconf(
5771 changer_config_t *devconf,
5772 changer_config_key key)
5774 assert(devconf != NULL);
5775 assert(key < CHANGER_CONFIG_CHANGER_CONFIG);
5776 return &devconf->value[key];
5780 changer_config_name(
5781 changer_config_t *devconf)
5783 assert(devconf != NULL);
5784 return devconf->name;
5788 getconf_unit_divisor(void)
5790 return unit_divisor;
5794 * Command-line Handling Implementation
5797 config_overrides_t *
5798 new_config_overrides(
5801 config_overrides_t *co;
5803 if (size_estimate <= 0)
5806 co = alloc(sizeof(*co));
5807 co->ovr = alloc(sizeof(*co->ovr) * size_estimate);
5808 co->n_allocated = size_estimate;
5815 free_config_overrides(
5816 config_overrides_t *co)
5821 for (i = 0; i < co->n_used; i++) {
5822 amfree(co->ovr[i].key);
5823 amfree(co->ovr[i].value);
5829 void add_config_override(
5830 config_overrides_t *co,
5834 /* reallocate if necessary */
5835 if (co->n_used == co->n_allocated) {
5836 co->n_allocated *= 2;
5837 co->ovr = realloc(co->ovr, co->n_allocated * sizeof(*co->ovr));
5839 error(_("Cannot realloc; out of memory"));
5844 co->ovr[co->n_used].key = stralloc(key);
5845 co->ovr[co->n_used].value = stralloc(value);
5850 add_config_override_opt(
5851 config_overrides_t *co,
5855 assert(optarg != NULL);
5857 value = strchr(optarg, '=');
5858 if (value == NULL) {
5859 error(_("Must specify a value for %s."), optarg);
5864 add_config_override(co, optarg, value+1);
5868 config_overrides_t *
5869 extract_commandline_config_overrides(
5874 config_overrides_t *co = new_config_overrides(*argc/2);
5878 if(strncmp((*argv)[i],"-o",2) == 0) {
5879 if(strlen((*argv)[i]) > 2) {
5880 add_config_override_opt(co, (*argv)[i]+2);
5884 if (i+1 >= *argc) error(_("expect something after -o"));
5885 add_config_override_opt(co, (*argv)[i+1]);
5889 /* move up remaining argment array */
5890 for (j = i; j+moveup<*argc; j++) {
5891 (*argv)[j] = (*argv)[j+moveup];
5903 set_config_overrides(
5904 config_overrides_t *co)
5908 config_overrides = co;
5910 for (i = 0; i < co->n_used; i++) {
5911 g_debug("config_overrides: %s %s", co->ovr[i].key, co->ovr[i].value);
5917 static cfgerr_level_t
5918 apply_config_overrides(
5919 config_overrides_t *co,
5924 if(!co) return cfgerr_level;
5925 assert(keytable != NULL);
5926 assert(parsetable != NULL);
5928 for (i = 0; i < co->n_used; i++) {
5929 char *key = co->ovr[i].key;
5930 char *value = co->ovr[i].value;
5932 conf_var_t *key_parm;
5934 if (key_ovr && strncasecmp(key_ovr, key, strlen(key_ovr)) != 0) {
5938 if (!parm_key_info(key, &key_parm, &key_val)) {
5939 /* not an error, only default config is loaded */
5943 /* now set up a fake line and use the relevant read_function to
5944 * parse it. This is sneaky! */
5945 if (key_parm->type == CONFTYPE_STR) {
5946 current_line = quote_string_always(value);
5948 current_line = stralloc(value);
5951 current_char = current_line;
5953 current_line_num = -2;
5954 allow_overwrites = 1;
5955 co->ovr[i].applied = TRUE;
5957 key_parm->read_function(key_parm, key_val);
5958 if ((key_parm)->validate_function)
5959 key_parm->validate_function(key_parm, key_val);
5961 amfree(current_line);
5962 current_char = NULL;
5965 return cfgerr_level;
5969 * val_t Management Implementation
5976 assert(config_initialized);
5977 if (val->type != CONFTYPE_INT) {
5978 error(_("val_t_to_int: val.type is not CONFTYPE_INT"));
5981 return val_t__int(val);
5988 assert(config_initialized);
5989 if (val->type != CONFTYPE_INT64) {
5990 error(_("val_t_to_int64: val.type is not CONFTYPE_INT64"));
5993 return val_t__int64(val);
6000 assert(config_initialized);
6001 if (val->type != CONFTYPE_REAL) {
6002 error(_("val_t_to_real: val.type is not CONFTYPE_REAL"));
6005 return val_t__real(val);
6012 assert(config_initialized);
6013 /* support CONFTYPE_IDENT, too */
6014 if (val->type != CONFTYPE_STR && val->type != CONFTYPE_IDENT) {
6015 error(_("val_t_to_str: val.type is not CONFTYPE_STR nor CONFTYPE_IDENT"));
6018 return val_t__str(val);
6025 assert(config_initialized);
6026 /* support CONFTYPE_STR, too */
6027 if (val->type != CONFTYPE_STR && val->type != CONFTYPE_IDENT) {
6028 error(_("val_t_to_ident: val.type is not CONFTYPE_IDENT nor CONFTYPE_STR"));
6031 return val_t__str(val);
6038 assert(config_initialized);
6039 if (val->type != CONFTYPE_IDENTLIST) {
6040 error(_("val_t_to_ident: val.type is not CONFTYPE_IDENTLIST"));
6043 return val_t__identlist(val);
6050 assert(config_initialized);
6051 if (val->type != CONFTYPE_TIME) {
6052 error(_("val_t_to_time: val.type is not CONFTYPE_TIME"));
6055 return val_t__time(val);
6062 assert(config_initialized);
6063 if (val->type != CONFTYPE_SIZE) {
6064 error(_("val_t_to_size: val.type is not CONFTYPE_SIZE"));
6067 return val_t__size(val);
6074 assert(config_initialized);
6075 if (val->type != CONFTYPE_BOOLEAN) {
6076 error(_("val_t_to_bool: val.type is not CONFTYPE_BOOLEAN"));
6079 return val_t__boolean(val);
6086 assert(config_initialized);
6087 if (val->type != CONFTYPE_COMPRESS) {
6088 error(_("val_t_to_compress: val.type is not CONFTYPE_COMPRESS"));
6091 return val_t__compress(val);
6098 assert(config_initialized);
6099 if (val->type != CONFTYPE_ENCRYPT) {
6100 error(_("val_t_to_encrypt: val.type is not CONFTYPE_ENCRYPT"));
6103 return val_t__encrypt(val);
6107 val_t_to_part_cache_type(
6110 assert(config_initialized);
6111 if (val->type != CONFTYPE_PART_CACHE_TYPE) {
6112 error(_("val_t_to_part_cache_type: val.type is not CONFTYPE_PART_CACHE_TYPE"));
6115 return val_t__part_cache_type(val);
6119 val_t_to_recovery_limit(
6122 assert(config_initialized);
6123 if (val->type != CONFTYPE_RECOVERY_LIMIT) {
6124 error(_("val_t_to_recovery_limit: val.type is not CONFTYPE_RECOVERY_LIMIT"));
6127 return &val_t__recovery_limit(val);
6134 assert(config_initialized);
6135 if (val->type != CONFTYPE_HOLDING) {
6136 error(_("val_t_to_hold: val.type is not CONFTYPE_HOLDING"));
6139 return val_t__holding(val);
6143 val_t_to_estimatelist(
6146 assert(config_initialized);
6147 if (val->type != CONFTYPE_ESTIMATELIST) {
6148 error(_("val_t_to_estimatelist: val.type is not CONFTYPE_ESTIMATELIST"));
6151 return val_t__estimatelist(val);
6158 assert(config_initialized);
6159 if (val->type != CONFTYPE_STRATEGY) {
6160 error(_("val_t_to_strategy: val.type is not CONFTYPE_STRATEGY"));
6163 return val_t__strategy(val);
6170 assert(config_initialized);
6171 if (val->type != CONFTYPE_TAPERALGO) {
6172 error(_("val_t_to_taperalgo: val.type is not CONFTYPE_TAPERALGO"));
6175 return val_t__taperalgo(val);
6179 val_t_to_send_amreport(
6182 assert(config_initialized);
6183 if (val->type != CONFTYPE_SEND_AMREPORT_ON) {
6184 error(_("val_t_to_send_amreport: val.type is not CONFTYPE_SEND_AMREPORT_ON"));
6187 return val_t__send_amreport(val);
6194 assert(config_initialized);
6195 if (val->type != CONFTYPE_DATA_PATH) {
6196 error(_("val_t_to_data_path: val.type is not CONFTYPE_DATA_PATH"));
6199 return val_t__data_path(val);
6206 assert(config_initialized);
6207 if (val->type != CONFTYPE_PRIORITY) {
6208 error(_("val_t_to_priority: val.type is not CONFTYPE_PRIORITY"));
6211 return val_t__priority(val);
6218 assert(config_initialized);
6219 if (val->type != CONFTYPE_RATE) {
6220 error(_("val_t_to_rate: val.type is not CONFTYPE_RATE"));
6223 return val_t__rate(val);
6230 assert(config_initialized);
6231 if (val->type != CONFTYPE_EXINCLUDE) {
6232 error(_("val_t_to_exinclude: val.type is not CONFTYPE_EXINCLUDE"));
6235 return val_t__exinclude(val);
6243 assert(config_initialized);
6244 if (val->type != CONFTYPE_INTRANGE) {
6245 error(_("val_t_to_intrange: val.type is not CONFTYPE_INTRANGE"));
6248 return val_t__intrange(val);
6255 assert(config_initialized);
6256 if (val->type != CONFTYPE_PROPLIST) {
6257 error(_("val_t_to_proplist: val.type is not CONFTYPE_PROPLIST"));
6260 return val_t__proplist(val);
6267 assert(config_initialized);
6268 if (val->type != CONFTYPE_AUTOLABEL) {
6269 error(_("val_t_to_autolabel: val.type is not CONFTYPE_AUTOLABEL"));
6272 return val_t__autolabel(val);
6280 if (valsrc->type == CONFTYPE_PROPLIST) {
6281 if (valsrc->v.proplist) {
6282 if (valdst->v.proplist == NULL) {
6283 valdst->v.proplist = g_hash_table_new_full(g_str_amanda_hash,
6287 g_hash_table_foreach(valsrc->v.proplist,
6288 ©_proplist_foreach_fn,
6289 valdst->v.proplist);
6291 g_hash_table_foreach(valsrc->v.proplist,
6292 &merge_proplist_foreach_fn,
6293 valdst->v.proplist);
6296 } else if (valsrc->type == CONFTYPE_IDENTLIST) {
6297 if (valsrc->v.identlist) {
6299 for (il = valsrc->v.identlist; il != NULL; il = il->next) {
6300 valdst->v.identlist = g_slist_append(valdst->v.identlist,
6301 stralloc((char *)il->data));
6306 copy_val_t(valdst, valsrc);
6317 if(valsrc->seen.linenum) {
6318 valdst->type = valsrc->type;
6319 valdst->seen = valsrc->seen;
6320 switch(valsrc->type) {
6322 case CONFTYPE_BOOLEAN:
6323 case CONFTYPE_COMPRESS:
6324 case CONFTYPE_ENCRYPT:
6325 case CONFTYPE_HOLDING:
6326 case CONFTYPE_EXECUTE_ON:
6327 case CONFTYPE_EXECUTE_WHERE:
6328 case CONFTYPE_SEND_AMREPORT_ON:
6329 case CONFTYPE_DATA_PATH:
6330 case CONFTYPE_STRATEGY:
6331 case CONFTYPE_TAPERALGO:
6332 case CONFTYPE_PRIORITY:
6333 case CONFTYPE_PART_CACHE_TYPE:
6334 valdst->v.i = valsrc->v.i;
6338 valdst->v.size = valsrc->v.size;
6341 case CONFTYPE_INT64:
6342 valdst->v.int64 = valsrc->v.int64;
6346 valdst->v.r = valsrc->v.r;
6350 valdst->v.rate[0] = valsrc->v.rate[0];
6351 valdst->v.rate[1] = valsrc->v.rate[1];
6354 case CONFTYPE_IDENT:
6356 valdst->v.s = stralloc(valsrc->v.s);
6359 case CONFTYPE_IDENTLIST:
6360 valdst->v.identlist = NULL;
6361 for (ia = valsrc->v.identlist; ia != NULL; ia = ia->next) {
6362 valdst->v.identlist = g_slist_append(valdst->v.identlist,
6363 stralloc(ia->data));
6367 case CONFTYPE_RECOVERY_LIMIT:
6368 valdst->v.recovery_limit = valsrc->v.recovery_limit;
6369 valdst->v.recovery_limit.match_pats = NULL;
6370 for (ia = valsrc->v.recovery_limit.match_pats; ia != NULL; ia = ia->next) {
6371 valdst->v.recovery_limit.match_pats =
6372 g_slist_append(valdst->v.recovery_limit.match_pats, g_strdup(ia->data));
6377 valdst->v.t = valsrc->v.t;
6380 case CONFTYPE_ESTIMATELIST: {
6381 estimatelist_t estimates = valsrc->v.estimatelist;
6382 estimatelist_t dst_estimates = NULL;
6383 while (estimates != NULL) {
6384 dst_estimates = g_slist_append(dst_estimates, estimates->data);
6385 estimates = estimates->next;
6387 valdst->v.estimatelist = dst_estimates;
6391 case CONFTYPE_EXINCLUDE:
6392 valdst->v.exinclude.optional = valsrc->v.exinclude.optional;
6393 valdst->v.exinclude.sl_list = duplicate_sl(valsrc->v.exinclude.sl_list);
6394 valdst->v.exinclude.sl_file = duplicate_sl(valsrc->v.exinclude.sl_file);
6397 case CONFTYPE_INTRANGE:
6398 valdst->v.intrange[0] = valsrc->v.intrange[0];
6399 valdst->v.intrange[1] = valsrc->v.intrange[1];
6402 case CONFTYPE_PROPLIST:
6403 if (valsrc->v.proplist) {
6404 valdst->v.proplist = g_hash_table_new_full(g_str_amanda_hash,
6409 g_hash_table_foreach(valsrc->v.proplist,
6410 ©_proplist_foreach_fn,
6411 valdst->v.proplist);
6413 valdst->v.proplist = NULL;
6417 case CONFTYPE_APPLICATION:
6418 valdst->v.s = stralloc(valsrc->v.s);
6421 case CONFTYPE_AUTOLABEL:
6422 valdst->v.autolabel.template = stralloc(valsrc->v.autolabel.template);
6423 valdst->v.autolabel.autolabel = valsrc->v.autolabel.autolabel;
6430 merge_proplist_foreach_fn(
6433 gpointer user_data_p)
6435 char *property_s = key_p;
6436 property_t *property = value_p;
6437 proplist_t proplist = user_data_p;
6438 GSList *elem = NULL;
6440 property_t *new_property = g_hash_table_lookup(proplist, property_s);
6441 if (new_property && !property->append) {
6442 g_hash_table_remove(proplist, property_s);
6443 new_property = NULL;
6445 if (!new_property) {
6446 new_property = malloc(sizeof(property_t));
6447 new_property->append = property->append;
6448 new_property->priority = property->priority;
6449 new_property->values = NULL;
6453 for(elem = property->values;elem != NULL; elem=elem->next) {
6454 new_property->values = g_slist_append(new_property->values,
6455 stralloc(elem->data));
6458 g_hash_table_insert(proplist, stralloc(property_s), new_property);
6462 copy_proplist_foreach_fn(
6465 gpointer user_data_p)
6467 char *property_s = key_p;
6468 property_t *property = value_p;
6469 proplist_t proplist = user_data_p;
6470 GSList *elem = NULL;
6471 property_t *new_property = malloc(sizeof(property_t));
6472 new_property->append = property->append;
6473 new_property->priority = property->priority;
6474 new_property->values = NULL;
6476 for(elem = property->values;elem != NULL; elem=elem->next) {
6477 new_property->values = g_slist_append(new_property->values,
6478 stralloc(elem->data));
6480 g_hash_table_insert(proplist, stralloc(property_s), new_property);
6489 case CONFTYPE_BOOLEAN:
6490 case CONFTYPE_COMPRESS:
6491 case CONFTYPE_ENCRYPT:
6492 case CONFTYPE_HOLDING:
6493 case CONFTYPE_EXECUTE_WHERE:
6494 case CONFTYPE_EXECUTE_ON:
6495 case CONFTYPE_SEND_AMREPORT_ON:
6496 case CONFTYPE_DATA_PATH:
6497 case CONFTYPE_STRATEGY:
6499 case CONFTYPE_TAPERALGO:
6500 case CONFTYPE_PRIORITY:
6501 case CONFTYPE_INT64:
6504 case CONFTYPE_INTRANGE:
6505 case CONFTYPE_PART_CACHE_TYPE:
6508 case CONFTYPE_IDENT:
6510 case CONFTYPE_APPLICATION:
6514 case CONFTYPE_IDENTLIST:
6515 slist_free_full(val->v.identlist, g_free);
6518 case CONFTYPE_RECOVERY_LIMIT:
6519 slist_free_full(val->v.recovery_limit.match_pats, g_free);
6525 case CONFTYPE_ESTIMATELIST:
6526 g_slist_free(val->v.estimatelist);
6529 case CONFTYPE_EXINCLUDE:
6530 free_sl(val_t__exinclude(val).sl_list);
6531 free_sl(val_t__exinclude(val).sl_file);
6534 case CONFTYPE_PROPLIST:
6535 g_hash_table_destroy(val_t__proplist(val));
6538 case CONFTYPE_AUTOLABEL:
6539 amfree(val->v.autolabel.template);
6542 val->seen.linenum = 0;
6543 val->seen.filename = NULL;
6547 * Utilities Implementation
6551 generic_get_security_conf(
6556 if(!string || !*string)
6559 if(strcmp(string, "krb5principal")==0) {
6560 return(getconf_str(CNF_KRB5PRINCIPAL));
6561 } else if(strcmp(string, "krb5keytab")==0) {
6562 return(getconf_str(CNF_KRB5KEYTAB));
6568 generic_client_get_security_conf(
6572 (void)arg; /* Quiet unused parameter warning */
6574 if(!string || !*string)
6577 if(strcmp(string, "conf")==0) {
6578 return(getconf_str(CNF_CONF));
6579 } else if(strcmp(string, "index_server")==0) {
6580 return(getconf_str(CNF_INDEX_SERVER));
6581 } else if(strcmp(string, "tape_server")==0) {
6582 return(getconf_str(CNF_TAPE_SERVER));
6583 } else if(strcmp(string, "tapedev")==0) {
6584 return(getconf_str(CNF_TAPEDEV));
6585 } else if(strcmp(string, "auth")==0) {
6586 return(getconf_str(CNF_AUTH));
6587 } else if(strcmp(string, "ssh_keys")==0) {
6588 return(getconf_str(CNF_SSH_KEYS));
6589 } else if(strcmp(string, "amandad_path")==0) {
6590 return(getconf_str(CNF_AMANDAD_PATH));
6591 } else if(strcmp(string, "client_username")==0) {
6592 return(getconf_str(CNF_CLIENT_USERNAME));
6593 } else if(strcmp(string, "client_port")==0) {
6594 return(getconf_str(CNF_CLIENT_PORT));
6595 } else if(strcmp(string, "gnutar_list_dir")==0) {
6596 return(getconf_str(CNF_GNUTAR_LIST_DIR));
6597 } else if(strcmp(string, "amandates")==0) {
6598 return(getconf_str(CNF_AMANDATES));
6599 } else if(strcmp(string, "krb5principal")==0) {
6600 return(getconf_str(CNF_KRB5PRINCIPAL));
6601 } else if(strcmp(string, "krb5keytab")==0) {
6602 return(getconf_str(CNF_KRB5KEYTAB));
6608 dump_configuration(void)
6617 device_config_t *dc;
6618 changer_config_t *cc;
6624 if (config_client) {
6625 error(_("Don't know how to dump client configurations."));
6629 g_printf(_("# AMANDA CONFIGURATION FROM FILE \"%s\":\n\n"), config_filename);
6631 for(np=server_var; np->token != CONF_UNKNOWN; np++) {
6632 for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
6633 if (np->token == kt->token) break;
6635 if(kt->token == CONF_UNKNOWN)
6636 error(_("server bad token"));
6638 val_t_print_token(stdout, NULL, "%-21s ", kt, &conf_data[np->parm]);
6641 for(hp = holdinglist; hp != NULL; hp = hp->next) {
6643 g_printf("\nDEFINE HOLDINGDISK %s {\n", hd->name);
6644 for(i=0; i < HOLDING_HOLDING; i++) {
6645 for(np=holding_var; np->token != CONF_UNKNOWN; np++) {
6649 if(np->token == CONF_UNKNOWN)
6650 error(_("holding bad value"));
6652 for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++) {
6653 if(kt->token == np->token)
6656 if(kt->token == CONF_UNKNOWN)
6657 error(_("holding bad token"));
6659 val_t_print_token(stdout, NULL, " %-9s ", kt, &hd->value[i]);
6664 for(tp = tapelist; tp != NULL; tp = tp->next) {
6665 if(tp->seen.linenum == -1)
6669 g_printf("\n%sDEFINE TAPETYPE %s {\n", prefix, tp->name);
6670 for(i=0; i < TAPETYPE_TAPETYPE; i++) {
6671 for(np=tapetype_var; np->token != CONF_UNKNOWN; np++)
6672 if(np->parm == i) break;
6673 if(np->token == CONF_UNKNOWN)
6674 error(_("tapetype bad value"));
6676 for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
6677 if(kt->token == np->token) break;
6678 if(kt->token == CONF_UNKNOWN)
6679 error(_("tapetype bad token"));
6681 val_t_print_token(stdout, prefix, " %-9s ", kt, &tp->value[i]);
6683 g_printf("%s}\n", prefix);
6686 for(dp = dumplist; dp != NULL; dp = dp->next) {
6687 if (strncmp_const(dp->name, "custom(") != 0) { /* don't dump disklist-derived dumptypes */
6688 if(dp->seen.linenum == -1)
6692 g_printf("\n%sDEFINE DUMPTYPE %s {\n", prefix, dp->name);
6693 for(i=0; i < DUMPTYPE_DUMPTYPE; i++) {
6694 for(np=dumptype_var; np->token != CONF_UNKNOWN; np++)
6695 if(np->parm == i) break;
6696 if(np->token == CONF_UNKNOWN)
6697 error(_("dumptype bad value"));
6699 for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
6700 if(kt->token == np->token) break;
6701 if(kt->token == CONF_UNKNOWN)
6702 error(_("dumptype bad token"));
6704 val_t_print_token(stdout, prefix, " %-19s ", kt, &dp->value[i]);
6706 g_printf("%s}\n", prefix);
6710 for(ip = interface_list; ip != NULL; ip = ip->next) {
6711 seen_t *netusage_seen = &val_t__seen(getconf(CNF_NETUSAGE));
6712 if (ip->seen.linenum == netusage_seen->linenum &&
6713 ip->seen.filename && netusage_seen->filename &&
6714 0 == strcmp(ip->seen.filename, netusage_seen->filename))
6718 g_printf("\n%sDEFINE INTERFACE %s {\n", prefix, ip->name);
6719 for(i=0; i < INTER_INTER; i++) {
6720 for(np=interface_var; np->token != CONF_UNKNOWN; np++)
6721 if(np->parm == i) break;
6722 if(np->token == CONF_UNKNOWN)
6723 error(_("interface bad value"));
6725 for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
6726 if(kt->token == np->token) break;
6727 if(kt->token == CONF_UNKNOWN)
6728 error(_("interface bad token"));
6730 val_t_print_token(stdout, prefix, " %-19s ", kt, &ip->value[i]);
6732 g_printf("%s}\n",prefix);
6735 for(ap = application_list; ap != NULL; ap = ap->next) {
6736 if(strcmp(ap->name,"default") == 0)
6740 g_printf("\n%sDEFINE APPLICATION %s {\n", prefix, ap->name);
6741 for(i=0; i < APPLICATION_APPLICATION; i++) {
6742 for(np=application_var; np->token != CONF_UNKNOWN; np++)
6743 if(np->parm == i) break;
6744 if(np->token == CONF_UNKNOWN)
6745 error(_("application bad value"));
6747 for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
6748 if(kt->token == np->token) break;
6749 if(kt->token == CONF_UNKNOWN)
6750 error(_("application bad token"));
6752 val_t_print_token(stdout, prefix, " %-19s ", kt, &ap->value[i]);
6754 g_printf("%s}\n",prefix);
6757 for(ps = pp_script_list; ps != NULL; ps = ps->next) {
6758 if(strcmp(ps->name,"default") == 0)
6762 g_printf("\n%sDEFINE SCRIPT %s {\n", prefix, ps->name);
6763 for(i=0; i < PP_SCRIPT_PP_SCRIPT; i++) {
6764 for(np=pp_script_var; np->token != CONF_UNKNOWN; np++)
6765 if(np->parm == i) break;
6766 if(np->token == CONF_UNKNOWN)
6767 error(_("script bad value"));
6769 for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
6770 if(kt->token == np->token) break;
6771 if(kt->token == CONF_UNKNOWN)
6772 error(_("script bad token"));
6774 val_t_print_token(stdout, prefix, " %-19s ", kt, &ps->value[i]);
6776 g_printf("%s}\n",prefix);
6779 for(dc = device_config_list; dc != NULL; dc = dc->next) {
6781 g_printf("\n%sDEFINE DEVICE %s {\n", prefix, dc->name);
6782 for(i=0; i < DEVICE_CONFIG_DEVICE_CONFIG; i++) {
6783 for(np=device_config_var; np->token != CONF_UNKNOWN; np++)
6784 if(np->parm == i) break;
6785 if(np->token == CONF_UNKNOWN)
6786 error(_("device bad value"));
6788 for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
6789 if(kt->token == np->token) break;
6790 if(kt->token == CONF_UNKNOWN)
6791 error(_("device bad token"));
6793 val_t_print_token(stdout, prefix, " %-19s ", kt, &dc->value[i]);
6795 g_printf("%s}\n",prefix);
6798 for(cc = changer_config_list; cc != NULL; cc = cc->next) {
6800 g_printf("\n%sDEFINE CHANGER %s {\n", prefix, cc->name);
6801 for(i=0; i < CHANGER_CONFIG_CHANGER_CONFIG; i++) {
6802 for(np=changer_config_var; np->token != CONF_UNKNOWN; np++)
6803 if(np->parm == i) break;
6804 if(np->token == CONF_UNKNOWN)
6805 error(_("changer bad value"));
6807 for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
6808 if(kt->token == np->token) break;
6809 if(kt->token == CONF_UNKNOWN)
6810 error(_("changer bad token"));
6812 val_t_print_token(stdout, prefix, " %-19s ", kt, &cc->value[i]);
6814 g_printf("%s}\n",prefix);
6826 char **dispstrs, **dispstr;
6827 dispstrs = val_t_display_strs(val, 1);
6829 /* For most configuration types, this outputs
6830 * PREFIX KEYWORD DISPSTR
6831 * for each of the display strings. For identifiers, however, it
6832 * simply prints the first line of the display string.
6835 /* Print the keyword for anything that is not itself an identifier */
6836 if (kt->token != CONF_IDENT) {
6837 for(dispstr=dispstrs; *dispstr!=NULL; dispstr++) {
6839 g_fprintf(output, "%s", prefix);
6840 g_fprintf(output, format, str_keyword(kt));
6841 g_fprintf(output, "%s\n", *dispstr);
6844 /* for identifiers, assume there's at most one display string */
6845 assert(g_strv_length(dispstrs) <= 1);
6847 g_fprintf(output, "%s\n", *dispstrs);
6851 g_strfreev(dispstrs);
6860 buf = malloc(3*SIZEOF(char *));
6867 buf[0] = vstrallocf("%d", val_t__int(val));
6871 buf[0] = vstrallocf("%zd", (ssize_t)val_t__size(val));
6874 case CONFTYPE_INT64:
6875 buf[0] = vstrallocf("%lld", (long long)val_t__int64(val));
6879 buf[0] = vstrallocf("%0.5f", val_t__real(val));
6883 buf[0] = vstrallocf("%0.5f %0.5f", val_t__rate(val)[0], val_t__rate(val)[1]);
6886 case CONFTYPE_INTRANGE:
6887 buf[0] = vstrallocf("%d,%d", val_t__intrange(val)[0], val_t__intrange(val)[1]);
6890 case CONFTYPE_IDENT:
6892 buf[0] = stralloc(val->v.s);
6894 buf[0] = stralloc("");
6898 case CONFTYPE_IDENTLIST:
6904 for (ia = val->v.identlist; ia != NULL; ia = ia->next) {
6906 buf[0] = stralloc(ia->data);
6909 strappend(buf[0], " ");
6910 strappend(buf[0], ia->data);
6917 if(str_need_quote) {
6919 buf[0] = quote_string_always(val->v.s);
6921 buf[0] = stralloc("\"\"");
6925 buf[0] = stralloc(val->v.s);
6927 buf[0] = stralloc("");
6932 case CONFTYPE_AUTOLABEL:
6934 buf[0] = quote_string_always(val->v.autolabel.template);
6935 if (val->v.autolabel.autolabel & AL_OTHER_CONFIG) {
6936 buf[0] = vstrextend(&buf[0], " OTHER-CONFIG", NULL);
6938 if (val->v.autolabel.autolabel & AL_NON_AMANDA) {
6939 buf[0] = vstrextend(&buf[0], " NON-AMANDA", NULL);
6941 if (val->v.autolabel.autolabel & AL_VOLUME_ERROR) {
6942 buf[0] = vstrextend(&buf[0], " VOLUME-ERROR", NULL);
6944 if (val->v.autolabel.autolabel & AL_EMPTY) {
6945 buf[0] = vstrextend(&buf[0], " EMPTY", NULL);
6951 buf[0] = vstrallocf("%2d%02d",
6952 (int)val_t__time(val)/100, (int)val_t__time(val) % 100);
6955 case CONFTYPE_EXINCLUDE: {
6956 buf[0] = exinclude_display_str(val, 0);
6957 buf[1] = exinclude_display_str(val, 1);
6961 case CONFTYPE_BOOLEAN:
6962 if(val_t__boolean(val))
6963 buf[0] = stralloc("yes");
6965 buf[0] = stralloc("no");
6968 case CONFTYPE_STRATEGY:
6969 switch(val_t__strategy(val)) {
6971 buf[0] = vstrallocf("SKIP");
6975 buf[0] = vstrallocf("STANDARD");
6979 buf[0] = vstrallocf("NOFULL");
6983 buf[0] = vstrallocf("NOINC");
6987 buf[0] = vstrallocf("HANOI");
6991 buf[0] = vstrallocf("INCRONLY");
6996 case CONFTYPE_COMPRESS:
6997 switch(val_t__compress(val)) {
6999 buf[0] = vstrallocf("NONE");
7003 buf[0] = vstrallocf("CLIENT FAST");
7007 buf[0] = vstrallocf("CLIENT BEST");
7011 buf[0] = vstrallocf("CLIENT CUSTOM");
7014 case COMP_SERVER_FAST:
7015 buf[0] = vstrallocf("SERVER FAST");
7018 case COMP_SERVER_BEST:
7019 buf[0] = vstrallocf("SERVER BEST");
7022 case COMP_SERVER_CUST:
7023 buf[0] = vstrallocf("SERVER CUSTOM");
7028 case CONFTYPE_ESTIMATELIST: {
7029 estimatelist_t es = val_t__estimatelist(val);
7030 buf[0] = stralloc("");
7032 switch((estimate_t)GPOINTER_TO_INT(es->data)) {
7034 strappend(buf[0], "CLIENT");
7038 strappend(buf[0], "SERVER");
7042 strappend(buf[0], "CALCSIZE");
7050 strappend(buf[0], " ");
7055 case CONFTYPE_EXECUTE_WHERE:
7058 buf[0] = vstrallocf("CLIENT");
7062 buf[0] = vstrallocf("SERVER");
7067 case CONFTYPE_SEND_AMREPORT_ON:
7069 case SEND_AMREPORT_ALL:
7070 buf[0] = vstrallocf("ALL");
7072 case SEND_AMREPORT_STRANGE:
7073 buf[0] = vstrallocf("STRANGE");
7075 case SEND_AMREPORT_ERROR:
7076 buf[0] = vstrallocf("ERROR");
7078 case SEND_AMREPORT_NEVER:
7079 buf[0] = vstrallocf("NEVER");
7084 case CONFTYPE_DATA_PATH:
7085 buf[0] = g_strdup(data_path_to_string(val->v.i));
7088 case CONFTYPE_ENCRYPT:
7089 switch(val_t__encrypt(val)) {
7091 buf[0] = vstrallocf("NONE");
7095 buf[0] = vstrallocf("CLIENT");
7098 case ENCRYPT_SERV_CUST:
7099 buf[0] = vstrallocf("SERVER");
7104 case CONFTYPE_PART_CACHE_TYPE:
7105 switch(val_t__part_cache_type(val)) {
7106 case PART_CACHE_TYPE_NONE:
7107 buf[0] = vstrallocf("NONE");
7110 case PART_CACHE_TYPE_DISK:
7111 buf[0] = vstrallocf("DISK");
7114 case PART_CACHE_TYPE_MEMORY:
7115 buf[0] = vstrallocf("MEMORY");
7120 case CONFTYPE_RECOVERY_LIMIT: {
7121 GSList *iter = val_t__recovery_limit(val).match_pats;
7123 if(val_t__recovery_limit(val).same_host)
7124 buf[0] = stralloc("SAME-HOST ");
7126 buf[0] = stralloc("");
7129 strappend(buf[0], quote_string_always((char *)iter->data));
7130 strappend(buf[0], " ");
7136 case CONFTYPE_HOLDING:
7137 switch(val_t__holding(val)) {
7139 buf[0] = vstrallocf("NEVER");
7143 buf[0] = vstrallocf("AUTO");
7147 buf[0] = vstrallocf("REQUIRED");
7152 case CONFTYPE_TAPERALGO:
7153 buf[0] = vstrallocf("%s", taperalgo2str(val_t__taperalgo(val)));
7156 case CONFTYPE_PRIORITY:
7157 switch(val_t__priority(val)) {
7159 buf[0] = vstrallocf("LOW");
7163 buf[0] = vstrallocf("MEDIUM");
7167 buf[0] = vstrallocf("HIGH");
7172 case CONFTYPE_PROPLIST: {
7176 nb_property = g_hash_table_size(val_t__proplist(val));
7178 buf = malloc((nb_property+1)*SIZEOF(char*));
7179 buf[nb_property] = NULL;
7181 g_hash_table_foreach(val_t__proplist(val),
7182 proplist_display_str_foreach_fn,
7187 case CONFTYPE_APPLICATION: {
7189 buf[0] = quote_string_always(val->v.s);
7191 buf[0] = stralloc("");
7196 case CONFTYPE_EXECUTE_ON:
7197 buf[0] = stralloc("");
7198 if (val->v.i != 0) {
7200 if (val->v.i & EXECUTE_ON_PRE_DLE_AMCHECK) {
7201 buf[0] = vstrextend(&buf[0], sep, "PRE-DLE-AMCHECK", NULL);
7204 if (val->v.i & EXECUTE_ON_PRE_HOST_AMCHECK) {
7205 buf[0] = vstrextend(&buf[0], sep, "PRE-HOST-AMCHECK", NULL);
7208 if (val->v.i & EXECUTE_ON_POST_DLE_AMCHECK) {
7209 buf[0] = vstrextend(&buf[0], sep, "POST-DLE-AMCHECK", NULL);
7212 if (val->v.i & EXECUTE_ON_POST_HOST_AMCHECK) {
7213 buf[0] = vstrextend(&buf[0], sep, "POST-HOST-AMCHECK", NULL);
7216 if (val->v.i & EXECUTE_ON_PRE_DLE_ESTIMATE) {
7217 buf[0] = vstrextend(&buf[0], sep, "PRE-DLE-ESTIMATE", NULL);
7220 if (val->v.i & EXECUTE_ON_PRE_HOST_ESTIMATE) {
7221 buf[0] = vstrextend(&buf[0], sep, "PRE-HOST-ESTIMATE", NULL);
7224 if (val->v.i & EXECUTE_ON_POST_DLE_ESTIMATE) {
7225 buf[0] = vstrextend(&buf[0], sep, "POST-DLE-ESTIMATE", NULL);
7228 if (val->v.i & EXECUTE_ON_POST_HOST_ESTIMATE) {
7229 buf[0] = vstrextend(&buf[0], sep, "POST-HOST-ESTIMATE", NULL);
7232 if (val->v.i & EXECUTE_ON_PRE_DLE_BACKUP) {
7233 buf[0] = vstrextend(&buf[0], sep, "PRE-DLE-BACKUP", NULL);
7236 if (val->v.i & EXECUTE_ON_PRE_HOST_BACKUP) {
7237 buf[0] = vstrextend(&buf[0], sep, "PRE-HOST-BACKUP", NULL);
7240 if (val->v.i & EXECUTE_ON_POST_DLE_BACKUP) {
7241 buf[0] = vstrextend(&buf[0], sep, "POST-DLE-BACKUP", NULL);
7244 if (val->v.i & EXECUTE_ON_POST_HOST_BACKUP) {
7245 buf[0] = vstrextend(&buf[0], sep, "POST-HOST-BACKUP", NULL);
7248 if (val->v.i & EXECUTE_ON_PRE_RECOVER) {
7249 buf[0] = vstrextend(&buf[0], sep, "PRE-RECOVER", NULL);
7252 if (val->v.i & EXECUTE_ON_POST_RECOVER) {
7253 buf[0] = vstrextend(&buf[0], sep, "POST-RECOVER", NULL);
7256 if (val->v.i & EXECUTE_ON_PRE_LEVEL_RECOVER) {
7257 buf[0] = vstrextend(&buf[0], sep, "PRE-LEVEL-RECOVER", NULL);
7260 if (val->v.i & EXECUTE_ON_POST_LEVEL_RECOVER) {
7261 buf[0] = vstrextend(&buf[0], sep, "POST-LEVEL-RECOVER", NULL);
7264 if (val->v.i & EXECUTE_ON_INTER_LEVEL_RECOVER) {
7265 buf[0] = vstrextend(&buf[0], sep, "INTER-LEVEL-RECOVER", NULL);
7276 val_t_to_execute_on(
7279 if (val->type != CONFTYPE_EXECUTE_ON) {
7280 error(_("get_conftype_execute_on: val.type is not CONFTYPE_EXECUTE_ON"));
7283 return val_t__execute_on(val);
7287 val_t_to_execute_where(
7290 if (val->type != CONFTYPE_EXECUTE_WHERE) {
7291 error(_("get_conftype_execute_where: val.type is not CONFTYPE_EXECUTE_WHERE"));
7298 val_t_to_application(
7301 if (val->type != CONFTYPE_APPLICATION) {
7302 error(_("get_conftype_applicaiton: val.type is not CONFTYPE_APPLICATION"));
7310 proplist_display_str_foreach_fn(
7313 gpointer user_data_p)
7315 char *property_s = quote_string_always(key_p);
7316 property_t *property = value_p;
7318 char ***msg = (char ***)user_data_p;
7320 /* What to do with property->append? it should be printed only on client */
7321 if (property->priority) {
7322 **msg = vstralloc("priority ", property_s, NULL);
7328 for(value=property->values; value != NULL; value = value->next) {
7329 char *qstr = quote_string_always((char *)value->data);
7330 **msg = vstrextend(*msg, " ", qstr, NULL);
7337 exinclude_display_str(
7345 assert(val->type == CONFTYPE_EXINCLUDE);
7347 rval = stralloc("");
7350 sl = val_t__exinclude(val).sl_list;
7351 strappend(rval, "LIST");
7353 sl = val_t__exinclude(val).sl_file;
7354 strappend(rval, "FILE");
7357 if (val_t__exinclude(val).optional == 1) {
7358 strappend(rval, " OPTIONAL");
7362 for(excl = sl->first; excl != NULL; excl = excl->next) {
7363 char *qstr = quote_string_always(excl->name);
7364 vstrextend(&rval, " ", qstr, NULL);
7374 taperalgo_t taperalgo)
7376 if(taperalgo == ALGO_FIRST) return "FIRST";
7377 if(taperalgo == ALGO_FIRSTFIT) return "FIRSTFIT";
7378 if(taperalgo == ALGO_LARGEST) return "LARGEST";
7379 if(taperalgo == ALGO_LARGESTFIT) return "LARGESTFIT";
7380 if(taperalgo == ALGO_SMALLEST) return "SMALLEST";
7381 if(taperalgo == ALGO_LAST) return "LAST";
7386 config_dir_relative(
7389 if (*filename == '/' || config_dir == NULL) {
7390 return stralloc(filename);
7392 if (config_dir[strlen(config_dir)-1] == '/') {
7393 return vstralloc(config_dir, filename, NULL);
7395 return vstralloc(config_dir, "/", filename, NULL);
7419 device_config_t *dc;
7420 changer_config_t *cc;
7421 int success = FALSE;
7423 /* WARNING: assumes globals keytable and parsetable are set correctly. */
7424 assert(keytable != NULL);
7425 assert(parsetable != NULL);
7427 /* make a copy we can stomp on */
7428 key = stralloc(key);
7430 /* uppercase the key */
7431 for (s = key; (ch = *s) != 0; s++) {
7432 if (islower((int)ch))
7433 *s = (char)toupper(ch);
7436 subsec_name = strchr(key, ':');
7440 *subsec_name = '\0';
7443 /* convert subsec_type '-' to '_' */
7444 for (s = subsec_type; (ch = *s) != 0; s++) {
7445 if (*s == '-') *s = '_';
7448 subsec_key = strchr(subsec_name,':');
7449 if(!subsec_key) goto out; /* failure */
7454 /* convert subsec_key '-' to '_' */
7455 for (s = subsec_key; (ch = *s) != 0; s++) {
7456 if (*s == '-') *s = '_';
7459 /* If the keyword doesn't exist, there's no need to look up the
7460 * subsection -- we know it's invalid */
7461 for(kt = keytable; kt->token != CONF_UNKNOWN; kt++) {
7462 if(kt->keyword && strcmp(kt->keyword, subsec_key) == 0)
7465 if(kt->token == CONF_UNKNOWN) goto out;
7467 /* Otherwise, figure out which kind of subsection we're dealing with,
7468 * and parse against that. */
7469 if (strcmp(subsec_type, "TAPETYPE") == 0) {
7470 tp = lookup_tapetype(subsec_name);
7472 for(np = tapetype_var; np->token != CONF_UNKNOWN; np++) {
7473 if(np->token == kt->token)
7476 if (np->token == CONF_UNKNOWN) goto out;
7478 if (val) *val = &tp->value[np->parm];
7479 if (parm) *parm = np;
7481 } else if (strcmp(subsec_type, "DUMPTYPE") == 0) {
7482 dp = lookup_dumptype(subsec_name);
7484 for(np = dumptype_var; np->token != CONF_UNKNOWN; np++) {
7485 if(np->token == kt->token)
7488 if (np->token == CONF_UNKNOWN) goto out;
7490 if (val) *val = &dp->value[np->parm];
7491 if (parm) *parm = np;
7493 } else if (strcmp(subsec_type, "HOLDINGDISK") == 0) {
7494 hp = lookup_holdingdisk(subsec_name);
7496 for(np = holding_var; np->token != CONF_UNKNOWN; np++) {
7497 if(np->token == kt->token)
7500 if (np->token == CONF_UNKNOWN) goto out;
7502 if (val) *val = &hp->value[np->parm];
7503 if (parm) *parm = np;
7505 } else if (strcmp(subsec_type, "INTERFACE") == 0) {
7506 ip = lookup_interface(subsec_name);
7508 for(np = interface_var; np->token != CONF_UNKNOWN; np++) {
7509 if(np->token == kt->token)
7512 if (np->token == CONF_UNKNOWN) goto out;
7514 if (val) *val = &ip->value[np->parm];
7515 if (parm) *parm = np;
7517 /* accept the old name here, too */
7518 } else if (strcmp(subsec_type, "APPLICATION_TOOL") == 0
7519 || strcmp(subsec_type, "APPLICATION") == 0) {
7520 ap = lookup_application(subsec_name);
7522 for(np = application_var; np->token != CONF_UNKNOWN; np++) {
7523 if(np->token == kt->token)
7526 if (np->token == CONF_UNKNOWN) goto out;
7528 if (val) *val = &ap->value[np->parm];
7529 if (parm) *parm = np;
7531 /* accept the old name here, too */
7532 } else if (strcmp(subsec_type, "SCRIPT_TOOL") == 0
7533 || strcmp(subsec_type, "SCRIPT") == 0) {
7534 pp = lookup_pp_script(subsec_name);
7536 for(np = pp_script_var; np->token != CONF_UNKNOWN; np++) {
7537 if(np->token == kt->token)
7540 if (np->token == CONF_UNKNOWN) goto out;
7542 if (val) *val = &pp->value[np->parm];
7543 if (parm) *parm = np;
7545 } else if (strcmp(subsec_type, "DEVICE") == 0) {
7546 dc = lookup_device_config(subsec_name);
7548 for(np = device_config_var; np->token != CONF_UNKNOWN; np++) {
7549 if(np->token == kt->token)
7552 if (np->token == CONF_UNKNOWN) goto out;
7554 if (val) *val = &dc->value[np->parm];
7555 if (parm) *parm = np;
7557 } else if (strcmp(subsec_type, "CHANGER") == 0) {
7558 cc = lookup_changer_config(subsec_name);
7560 for(np = changer_config_var; np->token != CONF_UNKNOWN; np++) {
7561 if(np->token == kt->token)
7564 if (np->token == CONF_UNKNOWN) goto out;
7566 if (val) *val = &cc->value[np->parm];
7567 if (parm) *parm = np;
7571 /* No delimiters -- we're referencing a global config parameter */
7573 /* convert key '-' to '_' */
7574 for (s = key; (ch = *s) != 0; s++) {
7575 if (*s == '-') *s = '_';
7578 /* look up the keyword */
7579 for(kt = keytable; kt->token != CONF_UNKNOWN; kt++) {
7580 if(kt->keyword && strcmp(kt->keyword, key) == 0)
7583 if(kt->token == CONF_UNKNOWN) goto out;
7585 /* and then look that up in the parse table */
7586 for(np = parsetable; np->token != CONF_UNKNOWN; np++) {
7587 if(np->token == kt->token)
7590 if(np->token == CONF_UNKNOWN) goto out;
7592 if (val) *val = &conf_data[np->parm];
7593 if (parm) *parm = np;
7606 keytab_t * table_entry;
7608 str = g_strdup(str);
7616 for (table_entry = numb_keytable; table_entry->keyword != NULL;
7618 if (strcasecmp(str, table_entry->keyword) == 0) {
7620 switch (table_entry->token) {
7626 return 1024*1024*1024;
7628 return (gint64)1024*1024*1024*1024;
7631 case CONF_AMINFINITY:
7637 /* Should not happen. */
7643 /* None found; this is an error. */
7652 keytab_t * table_entry;
7654 if (str == NULL || *str == '\0') {
7658 /* 0 and 1 are not in the table, as they are parsed as ints */
7659 if (0 == strcmp(str, "0"))
7661 if (0 == strcmp(str, "1"))
7664 for (table_entry = bool_keytable; table_entry->keyword != NULL;
7666 if (strcasecmp(str, table_entry->keyword) == 0) {
7667 switch (table_entry->token) {
7682 * Error Handling Implementaiton
7685 void config_add_error(
7686 cfgerr_level_t level,
7689 cfgerr_level = max(cfgerr_level, level);
7691 g_debug("%s", errmsg);
7692 cfgerr_errors = g_slist_append(cfgerr_errors, errmsg);
7695 static void conf_error_common(
7696 cfgerr_level_t level,
7697 const char * format,
7700 char *msg = g_strdup_vprintf(format, argp);
7701 char *errstr = NULL;
7704 errstr = g_strdup_printf(_("argument \"%s\": %s"),
7706 else if (current_filename && current_line_num > 0)
7707 errstr = g_strdup_printf(_("\"%s\", line %d: %s"),
7708 current_filename, current_line_num, msg);
7710 errstr = g_strdup_printf(_("parse error: %s"), msg);
7713 config_add_error(level, errstr);
7716 printf_arglist_function(void conf_parserror, const char *, format)
7720 arglist_start(argp, format);
7721 conf_error_common(CFGERR_ERRORS, format, argp);
7725 printf_arglist_function(void conf_parswarn, const char *, format) {
7728 arglist_start(argp, format);
7729 conf_error_common(CFGERR_WARNINGS, format, argp);
7734 config_errors(GSList **errstr)
7737 *errstr = cfgerr_errors;
7738 return cfgerr_level;
7742 config_clear_errors(void)
7744 slist_free_full(cfgerr_errors, g_free);
7746 cfgerr_errors = NULL;
7747 cfgerr_level = CFGERR_OK;
7751 config_print_errors(void)
7755 for (iter = cfgerr_errors; iter; iter = g_slist_next(iter)) {
7756 g_fprintf(stderr, "%s\n", (char *)iter->data);
7760 /* Get the config name */
7761 char *get_config_name(void)
7766 /* Get the config directory */
7767 char *get_config_dir(void)
7772 /* Get the config filename */
7773 char *get_config_filename(void)
7775 return config_filename;
7779 anonymous_value(void)
7781 static char number[NUM_STR_SIZE];
7784 g_snprintf(number, sizeof(number), "%d", value);
7790 gint compare_pp_script_order(
7794 return pp_script_get_order(lookup_pp_script((char *)a)) > pp_script_get_order(lookup_pp_script((char *)b));
7798 data_path_to_string(
7799 data_path_t data_path)
7801 switch (data_path) {
7802 case DATA_PATH_AMANDA : return "AMANDA";
7803 case DATA_PATH_DIRECTTCP: return "DIRECTTCP";
7805 error(_("datapath is not DATA_PATH_AMANDA or DATA_PATH_DIRECTTCP"));
7810 data_path_from_string(
7813 if (strcmp(data, "AMANDA") == 0)
7814 return DATA_PATH_AMANDA;
7815 if (strcmp(data, "DIRECTTCP") == 0)
7816 return DATA_PATH_DIRECTTCP;
7817 error(_("datapath is not AMANDA or DIRECTTCP :%s:"), data);
7822 amandaify_property_name(
7827 if (!name) return NULL;
7829 ret = g_malloc0(strlen(name)+1);
7831 for (cur_o = name; *cur_o; cur_o++) {
7835 *cur_r = g_ascii_tolower(*cur_o);
7843 static char keyword_str[1024];
7849 char *p = kt->keyword;
7850 char *s = keyword_str;