2 * Amanda, The Advanced Maryland Automatic Network Disk Archiver
3 * Copyright (c) 1991-2000 University of Maryland at College Park
6 * Permission to use, copy, modify, distribute, and sell this software and its
7 * documentation for any purpose is hereby granted without fee, provided that
8 * the above copyright notice appear in all copies and that both that
9 * copyright notice and this permission notice appear in supporting
10 * documentation, and that the name of U.M. not be used in advertising or
11 * publicity pertaining to distribution of the software without specific,
12 * written prior permission. U.M. makes no representations about the
13 * suitability of this software for any purpose. It is provided "as is"
14 * without express or implied warranty.
16 * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
18 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
20 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 * Author: James da Silva, Systems Design and Analysis Group
24 * Computer Science Department
25 * University of Maryland at College Park
28 * $Id: conffile.c,v 1.156 2006/07/26 15:17:37 martinea Exp $
30 * read configuration file
44 /* This module implements its own quixotic lexer and parser, present for historical
45 * reasons. If this were written from scratch, it would use flex/bison. */
47 /* An enumeration of the various tokens that might appear in a configuration file.
49 * - CONF_UNKNOWN has special meaning as an unrecognized token.
50 * - CONF_ANY can be used to request any token, rather than requiring a specific
54 CONF_UNKNOWN, CONF_ANY, CONF_COMMA,
55 CONF_LBRACE, CONF_RBRACE, CONF_NL,
56 CONF_END, CONF_IDENT, CONF_INT,
57 CONF_INT64, CONF_BOOL, CONF_REAL,
58 CONF_STRING, CONF_TIME, CONF_SIZE,
60 /* config parameters */
61 CONF_INCLUDEFILE, CONF_ORG, CONF_MAILTO,
62 CONF_DUMPUSER, CONF_TAPECYCLE, CONF_TAPEDEV,
63 CONF_CHANGERDEV, CONF_CHANGERFILE, CONF_LABELSTR,
64 CONF_BUMPPERCENT, CONF_BUMPSIZE, CONF_BUMPDAYS,
65 CONF_BUMPMULT, CONF_ETIMEOUT, CONF_DTIMEOUT,
66 CONF_CTIMEOUT, CONF_TAPEBUFS, CONF_TAPELIST,
67 CONF_DEVICE_OUTPUT_BUFFER_SIZE, CONF_RAWTAPEDEV,
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_PP_SCRIPT, CONF_PP_SCRIPT_TOOL,
90 CONF_EXECUTE_ON, CONF_EXECUTE_WHERE, CONF_SEND_AMREPORT_ON,
94 CONF_PRE_DLE_AMCHECK, CONF_PRE_HOST_AMCHECK,
95 CONF_POST_DLE_AMCHECK, CONF_POST_HOST_AMCHECK,
96 CONF_PRE_DLE_ESTIMATE, CONF_PRE_HOST_ESTIMATE,
97 CONF_POST_DLE_ESTIMATE, CONF_POST_HOST_ESTIMATE,
98 CONF_PRE_DLE_BACKUP, CONF_PRE_HOST_BACKUP,
99 CONF_POST_DLE_BACKUP, CONF_POST_HOST_BACKUP,
100 CONF_PRE_RECOVER, CONF_POST_RECOVER,
101 CONF_PRE_LEVEL_RECOVER, CONF_POST_LEVEL_RECOVER,
102 CONF_INTER_LEVEL_RECOVER,
105 CONF_KRB5KEYTAB, CONF_KRB5PRINCIPAL,
108 CONF_COMMENT, CONF_DIRECTORY, CONF_USE,
112 /*COMMENT,*/ CONF_PROGRAM, CONF_DUMPCYCLE,
113 CONF_RUNSPERCYCLE, CONF_MAXCYCLE, CONF_MAXDUMPS,
114 CONF_OPTIONS, CONF_PRIORITY, CONF_FREQUENCY,
115 CONF_INDEX, CONF_MAXPROMOTEDAY, CONF_STARTTIME,
116 CONF_COMPRESS, CONF_ENCRYPT, CONF_AUTH,
117 CONF_STRATEGY, CONF_ESTIMATE, CONF_SKIP_INCR,
118 CONF_SKIP_FULL, CONF_RECORD, CONF_HOLDING,
119 CONF_EXCLUDE, CONF_INCLUDE, CONF_KENCRYPT,
120 CONF_IGNORE, CONF_COMPRATE, CONF_TAPE_SPLITSIZE,
121 CONF_SPLIT_DISKBUFFER, CONF_FALLBACK_SPLITSIZE,CONF_SRVCOMPPROG,
122 CONF_CLNTCOMPPROG, CONF_SRV_ENCRYPT, CONF_CLNT_ENCRYPT,
123 CONF_SRV_DECRYPT_OPT, CONF_CLNT_DECRYPT_OPT, CONF_AMANDAD_PATH,
124 CONF_CLIENT_USERNAME,
127 /*COMMENT,*/ CONF_BLOCKSIZE, CONF_FILE_PAD,
128 CONF_LBL_TEMPL, CONF_FILEMARK, CONF_LENGTH,
129 CONF_SPEED, CONF_READBLOCKSIZE,
132 CONF_CONF, CONF_INDEX_SERVER, CONF_TAPE_SERVER,
133 CONF_SSH_KEYS, CONF_GNUTAR_LIST_DIR, CONF_AMANDATES,
135 /* protocol config */
136 CONF_REP_TRIES, CONF_CONNECT_TRIES, CONF_REQ_TRIES,
139 CONF_DEBUG_AMANDAD, CONF_DEBUG_AMIDXTAPED, CONF_DEBUG_AMINDEXD,
140 CONF_DEBUG_AMRECOVER, CONF_DEBUG_AUTH, CONF_DEBUG_EVENT,
141 CONF_DEBUG_HOLDING, CONF_DEBUG_PROTOCOL, CONF_DEBUG_PLANNER,
142 CONF_DEBUG_DRIVER, CONF_DEBUG_DUMPER, CONF_DEBUG_CHUNKER,
143 CONF_DEBUG_TAPER, CONF_DEBUG_SELFCHECK, CONF_DEBUG_SENDSIZE,
144 CONF_DEBUG_SENDBACKUP,
146 /* network interface */
147 /* COMMENT, */ /* USE, */
149 /* dump options (obsolete) */
150 CONF_EXCLUDE_FILE, CONF_EXCLUDE_LIST,
152 /* compress, estimate, encryption */
153 CONF_NONE, CONF_FAST, CONF_BEST,
154 CONF_SERVER, CONF_CLIENT, CONF_CALCSIZE,
158 CONF_NEVER, CONF_AUTO, CONF_REQUIRED,
161 CONF_ALL, CONF_STRANGE, CONF_ERROR,
164 CONF_LOW, CONF_MEDIUM, CONF_HIGH,
167 CONF_SKIP, CONF_STANDARD, CONF_NOFULL,
168 CONF_NOINC, CONF_HANOI, CONF_INCRONLY,
171 CONF_LIST, CONF_EFILE, CONF_APPEND,
175 CONF_AMINFINITY, CONF_MULT1, CONF_MULT7,
176 CONF_MULT1K, CONF_MULT1M, CONF_MULT1G,
179 CONF_ATRUE, CONF_AFALSE
182 /* A keyword table entry, mapping the given keyword to the given token.
183 * Note that punctuation, integers, and quoted strings are handled
184 * internally to the lexer, so they do not appear here. */
190 /* The current keyword table, used by all token-related functions */
191 static keytab_t *keytable = NULL;
193 /* Has a token been "ungotten", and if so, what was it? */
194 static int token_pushed;
195 static tok_t pushed_tok;
197 /* The current token and its value. Note that, unlike most other val_t*,
198 * tokenval's v.s points to statically allocated memory which cannot be
201 static val_t tokenval;
203 /* The current input information: file, filename, line, and character
204 * (which points somewhere within current_line) */
205 static FILE *current_file = NULL;
206 static char *current_filename = NULL;
207 static char *current_line = NULL;
208 static char *current_char = NULL;
209 static int current_line_num = 0; /* (technically, managed by the parser) */
211 /* A static buffer for storing tokens while they are being scanned. */
212 static char tkbuf[4096];
214 /* Look up the name of the given token in the current keytable */
215 static char *get_token_name(tok_t);
217 /* Look up a token in keytable, given a string, returning CONF_UNKNOWN
218 * for unrecognized strings. Search is case-insensitive. */
219 static tok_t lookup_keyword(char *str);
221 /* Get the next token. If exp is anything but CONF_ANY, and the next token
222 * does not match, then a parse error is flagged. This function reads from the
223 * current_* static variables, recognizes keywords against the keytable static
224 * variable, and places its result in tok and tokenval. */
225 static void get_conftoken(tok_t exp);
227 /* "Unget" the current token; this supports a 1-token lookahead. */
228 static void unget_conftoken(void);
230 /* Tokenizer character-by-character access. */
231 static int conftoken_getc(void);
232 static int conftoken_ungetc(int c);
234 static void copy_proplist(gpointer key_p,
236 gpointer user_data_p);
237 static void copy_pp_scriptlist(gpointer data_p,
238 gpointer user_data_p);
244 /* A parser table entry. Read as "<token> introduces parameter <parm>,
245 * the data for which will be read by <read_function> and validated by
246 * <validate_function> (if not NULL). <type> is only used in formatting
247 * config overwrites. */
248 typedef struct conf_var_s {
251 void (*read_function) (struct conf_var_s *, val_t*);
253 void (*validate_function) (struct conf_var_s *, val_t *);
256 /* This is a list of filenames that are used in 'seen_t' structs. */
257 static GSList *seen_filenames = NULL;
259 /* get a copy of filename that's stored in seen_filenames so that it won't go
260 * away until config_uninit. */
261 static char *get_seen_filename(char *filename);
263 /* If allow_overwrites is true, the a parameter which has already been
264 * seen will simply overwrite the old value, rather than triggering an
265 * error. Note that this does not apply to all parameters, e.g.,
267 static int allow_overwrites;
269 /* subsection structs
271 * The 'seen' fields in these structs are useless outside this module;
272 * they are only used to generate error messages for multiply defined
276 struct tapetype_s *next;
280 val_t value[TAPETYPE_TAPETYPE];
284 struct dumptype_s *next;
288 val_t value[DUMPTYPE_DUMPTYPE];
292 struct interface_s *next;
296 val_t value[INTER_INTER];
299 struct holdingdisk_s {
300 struct holdingdisk_s *next;
304 val_t value[HOLDING_HOLDING];
307 struct application_s {
308 struct application_s *next;
312 val_t value[APPLICATION_APPLICATION];
316 struct pp_script_s *next;
320 val_t value[PP_SCRIPT_PP_SCRIPT];
323 struct device_config_s {
324 struct device_config_s *next;
328 val_t value[DEVICE_CONFIG_DEVICE_CONFIG];
331 struct changer_config_s {
332 struct changer_config_s *next;
336 val_t value[CHANGER_CONFIG_CHANGER_CONFIG];
339 /* The current parser table */
340 static conf_var_t *parsetable = NULL;
342 /* Read and parse a configuration file, recursively reading any included
343 * files. This function sets the keytable and parsetable appropriately
344 * according to is_client.
346 * @param filename: configuration file to read
347 * @param is_client: true if this is a client
348 * @param missing_ok: is it OK if the file is missing?
350 static void read_conffile(char *filename,
352 gboolean missing_ok);
354 /* Read and process a line of input from the current file, using the
355 * current keytable and parsetable. For blocks, this recursively
356 * reads the entire block.
358 * @param is_client: true if this is a client
359 * @returns: true on success, false on EOF
361 static gboolean read_confline(gboolean is_client);
363 /* Handle an invalid token, recognizing deprecated tokens as such,
364 * and producing an appropriate error message.
366 * @param token: the identifier
368 static void handle_invalid_keyword(const char * token);
370 /* Check whether token is deprecated, and issue a warning if it
371 * is. This consults the global variables 'tok' and 'tokenval'
373 static void handle_deprecated_keyword(void);
375 /* Read a brace-delimited block using the given parse table. This
376 * function is used to read brace-delimited subsections in the config
377 * files and also (via read_dumptype) to read dumptypes from
380 * This function implements "inheritance" as follows: if a bare
381 * identifier occurs within the braces, it calls copy_function (if
382 * not NULL), which looks up an existing subsection using the
383 * identifier from tokenval and copies any values not already seen
386 * @param read_var: the parse table to use
387 * @param valarray: the (pre-initialized) val_t array to fill in
388 * @param errormsg: error message to display for unrecognized keywords
389 * @param read_brace: if true, read the opening brace
390 * @param copy_function: function to copy configuration from
391 * another subsection into this one.
393 static void read_block(conf_var_t *read_var, val_t *valarray,
394 char *errormsg, int read_brace,
395 void (*copy_function)(void));
397 /* For each subsection type, we have a global and four functions:
398 * - foocur is a temporary struct used to assemble new subsections
399 * - get_foo is called after reading "DEFINE FOO", and
400 * is responsible for reading the entire block, using
402 * - init_foo_defaults initializes a new subsection struct
403 * to its default values
404 * - save_foo copies foocur to a newly allocated struct and
405 * inserts that into the relevant list.
406 * - copy_foo implements inheritance as described in read_block()
408 static holdingdisk_t hdcur;
409 static void get_holdingdisk(void);
410 static void init_holdingdisk_defaults(void);
411 static void save_holdingdisk(void);
412 /* (holdingdisks don't support inheritance) */
414 static dumptype_t dpcur;
415 static void get_dumptype(void);
416 static void init_dumptype_defaults(void);
417 static void save_dumptype(void);
418 static void copy_dumptype(void);
420 static tapetype_t tpcur;
421 static void get_tapetype(void);
422 static void init_tapetype_defaults(void);
423 static void save_tapetype(void);
424 static void copy_tapetype(void);
426 static interface_t ifcur;
427 static void get_interface(void);
428 static void init_interface_defaults(void);
429 static void save_interface(void);
430 static void copy_interface(void);
432 static application_t apcur;
433 static void get_application(void);
434 static void init_application_defaults(void);
435 static void save_application(void);
436 static void copy_application(void);
438 static pp_script_t pscur;
439 static void get_pp_script(void);
440 static void init_pp_script_defaults(void);
441 static void save_pp_script(void);
442 static void copy_pp_script(void);
444 static device_config_t dccur;
445 static void get_device_config(void);
446 static void init_device_config_defaults(void);
447 static void save_device_config(void);
448 static void copy_device_config(void);
450 static changer_config_t cccur;
451 static void get_changer_config(void);
452 static void init_changer_config_defaults(void);
453 static void save_changer_config(void);
454 static void copy_changer_config(void);
456 /* read_functions -- these fit into the read_function slot in a parser
457 * table entry, and are responsible for calling getconf_token as necessary
458 * to consume their arguments, and setting their second argument with the
459 * result. The first argument is a copy of the parser table entry, if
461 static void read_int(conf_var_t *, val_t *);
462 static void read_int64(conf_var_t *, val_t *);
463 static void read_real(conf_var_t *, val_t *);
464 static void read_str(conf_var_t *, val_t *);
465 static void read_ident(conf_var_t *, val_t *);
466 static void read_time(conf_var_t *, val_t *);
467 static void read_size(conf_var_t *, val_t *);
468 static void read_bool(conf_var_t *, val_t *);
469 static void read_compress(conf_var_t *, val_t *);
470 static void read_encrypt(conf_var_t *, val_t *);
471 static void read_holding(conf_var_t *, val_t *);
472 static void read_estimate(conf_var_t *, val_t *);
473 static void read_strategy(conf_var_t *, val_t *);
474 static void read_taperalgo(conf_var_t *, val_t *);
475 static void read_send_amreport_on(conf_var_t *, val_t *);
476 static void read_priority(conf_var_t *, val_t *);
477 static void read_rate(conf_var_t *, val_t *);
478 static void read_exinclude(conf_var_t *, val_t *);
479 static void read_intrange(conf_var_t *, val_t *);
480 static void read_dapplication(conf_var_t *, val_t *);
481 static void read_dpp_script(conf_var_t *, val_t *);
482 static void read_property(conf_var_t *, val_t *);
483 static void read_execute_on(conf_var_t *, val_t *);
484 static void read_execute_where(conf_var_t *, val_t *);
486 /* Functions to get various types of values. These are called by
487 * read_functions to take care of any variations in the way that these
488 * values can be written: integers can have units, boolean values can be
489 * specified with a number of names, etc. They form utility functions
490 * for the read_functions, below. */
491 static time_t get_time(void);
492 static int get_int(void);
493 static ssize_t get_size(void);
494 static gint64 get_int64(void);
495 static int get_bool(void);
497 /* Check the given 'seen', flagging an error if this value has already
498 * been seen and allow_overwrites is false. Also marks the value as
499 * seen on the current line.
501 * @param seen: (in/out) seen value to adjust
503 static void ckseen(seen_t *seen);
505 /* validate_functions -- these fit into the validate_function solt in
506 * a parser table entry. They call conf_parserror if the value in their
507 * second argument is invalid. */
508 static void validate_nonnegative(conf_var_t *, val_t *);
509 static void validate_positive(conf_var_t *, val_t *);
510 static void validate_runspercycle(conf_var_t *, val_t *);
511 static void validate_bumppercent(conf_var_t *, val_t *);
512 static void validate_bumpmult(conf_var_t *, val_t *);
513 static void validate_inparallel(conf_var_t *, val_t *);
514 static void validate_displayunit(conf_var_t *, val_t *);
515 static void validate_reserve(conf_var_t *, val_t *);
516 static void validate_use(conf_var_t *, val_t *);
517 static void validate_chunksize(conf_var_t *, val_t *);
518 static void validate_blocksize(conf_var_t *, val_t *);
519 static void validate_debug(conf_var_t *, val_t *);
520 static void validate_port_range(val_t *, int, int);
521 static void validate_reserved_port_range(conf_var_t *, val_t *);
522 static void validate_unreserved_port_range(conf_var_t *, val_t *);
523 static void validate_program(conf_var_t *, val_t *);
529 /* The name of the configuration under which this application is running.
530 * This variable is initialized by config_init.
532 static char *config_name = NULL;
534 /* The directory containing the configuration for this application. This
535 * variable is initialized by config_init
537 static char *config_dir = NULL;
539 /* The most recently read top-level configuration file. This variable is
540 * initialized by config_init
542 static char *config_filename = NULL;
544 /* Has the config been initialized? */
545 static gboolean config_initialized = FALSE;
547 /* Are we running a client? (true if last init was
548 * with CONFIG_INIT_CLIENT) */
549 static gboolean config_client = FALSE;
551 /* What config overwrites are applied? */
552 static config_overwrites_t *applied_config_overwrites = NULL;
554 /* All global parameters */
555 static val_t conf_data[CNF_CNF];
557 /* Linked list of holding disks */
558 static holdingdisk_t *holdinglist = NULL;
559 static dumptype_t *dumplist = NULL;
560 static tapetype_t *tapelist = NULL;
561 static interface_t *interface_list = NULL;
562 static application_t *application_list = NULL;
563 static pp_script_t *pp_script_list = NULL;
564 static device_config_t *device_config_list = NULL;
565 static changer_config_t *changer_config_list = NULL;
567 /* storage for derived values */
568 static long int unit_divisor = 1;
570 int debug_amandad = 0;
571 int debug_amidxtaped = 0;
572 int debug_amindexd = 0;
573 int debug_amrecover = 0;
576 int debug_holding = 0;
577 int debug_protocol = 0;
578 int debug_planner = 0;
579 int debug_driver = 0;
580 int debug_dumper = 0;
581 int debug_chunker = 0;
583 int debug_selfcheck = 0;
584 int debug_sendsize = 0;
585 int debug_sendbackup = 0;
587 /* Reset all configuration values to their defaults (which, in many
588 * cases, come from --with-foo options at build time) */
589 static void init_defaults(void);
591 /* Update all dervied values based on the current configuration. This
592 * function can be called multiple times, once after each adjustment
593 * to the current configuration.
595 * @param is_client: are we running a client?
597 static void update_derived_values(gboolean is_client);
599 /* per-type conf_init functions, used as utilities for init_defaults
600 * and for each subsection's init_foo_defaults.
602 * These set the value's type and seen flags, as well as copying
603 * the relevant value into the 'v' field.
605 static void conf_init_int(val_t *val, int i);
606 static void conf_init_int64(val_t *val, gint64 l);
607 static void conf_init_real(val_t *val, float r);
608 static void conf_init_str(val_t *val, char *s);
609 static void conf_init_ident(val_t *val, char *s);
610 static void conf_init_time(val_t *val, time_t t);
611 static void conf_init_size(val_t *val, ssize_t sz);
612 static void conf_init_bool(val_t *val, int i);
613 static void conf_init_compress(val_t *val, comp_t i);
614 static void conf_init_encrypt(val_t *val, encrypt_t i);
615 static void conf_init_holding(val_t *val, dump_holdingdisk_t i);
616 static void conf_init_estimate(val_t *val, estimate_t i);
617 static void conf_init_execute_on(val_t *, int);
618 static void conf_init_execute_where(val_t *, int);
619 static void conf_init_send_amreport(val_t *val, send_amreport_t i);
620 static void conf_init_strategy(val_t *val, strategy_t);
621 static void conf_init_taperalgo(val_t *val, taperalgo_t i);
622 static void conf_init_priority(val_t *val, int i);
623 static void conf_init_rate(val_t *val, float r1, float r2);
624 static void conf_init_exinclude(val_t *val); /* to empty list */
625 static void conf_init_intrange(val_t *val, int i1, int i2);
626 static void conf_init_proplist(val_t *val); /* to empty list */
627 static void conf_init_pp_scriptlist(val_t *);
628 static void conf_init_application(val_t *val);
631 * Command-line Handling
634 typedef struct config_overwrite_s {
637 } config_overwrite_t;
639 struct config_overwrites_s {
642 config_overwrite_t *ovr;
649 static void copy_val_t(val_t *, val_t *);
650 static void free_val_t(val_t *);
657 /* Utility functions/structs for val_t_display_strs */
658 static char *exinclude_display_str(val_t *val, int file);
659 static void proplist_display_str_foreach_fn(gpointer key_p, gpointer value_p, gpointer user_data_p);
660 static void pp_scriptlist_display_str_foreach_fn(gpointer data_p, gpointer user_data_p);
661 static void val_t_print_token(FILE *output, char *prefix, char *format, keytab_t *kt, val_t *val);
663 /* Given a key name as used in config overwrites, return a pointer to the corresponding
664 * conf_var_t in the current parsetable, and the val_t representing that value. This
665 * function will access subsections if key has the form TYPE:SUBSEC:KEYWORD. Returns
666 * false if the value does not exist.
668 * Assumes keytable and parsetable are set correctly, which is generally OK after
669 * config_init has been called.
671 * @param key: the key to look up
672 * @param parm: (result) the parse table entry
673 * @param val: (result) the parameter value
674 * @returns: true on success
676 static int parm_key_info(char *key, conf_var_t **parm, val_t **val);
682 /* Have we seen a parse error yet? Parsing continues after an error, so this
683 * flag is checked after the parse is complete.
685 static cfgerr_level_t cfgerr_level;
686 static GSList *cfgerr_errors = NULL;
688 static void conf_error_common(cfgerr_level_t level, const char * format, va_list argp);
689 static void conf_parserror(const char *format, ...)
690 __attribute__ ((format (printf, 1, 2)));
692 static void conf_parswarn(const char *format, ...)
693 __attribute__ ((format (printf, 1, 2)));
699 /* First, the keyword tables for client and server */
700 keytab_t client_keytab[] = {
701 { "CONF", CONF_CONF },
702 { "INDEX_SERVER", CONF_INDEX_SERVER },
703 { "TAPE_SERVER", CONF_TAPE_SERVER },
704 { "TAPEDEV", CONF_TAPEDEV },
705 { "AUTH", CONF_AUTH },
706 { "SSH_KEYS", CONF_SSH_KEYS },
707 { "AMANDAD_PATH", CONF_AMANDAD_PATH },
708 { "CLIENT_USERNAME", CONF_CLIENT_USERNAME },
709 { "GNUTAR_LIST_DIR", CONF_GNUTAR_LIST_DIR },
710 { "AMANDATES", CONF_AMANDATES },
711 { "KRB5KEYTAB", CONF_KRB5KEYTAB },
712 { "KRB5PRINCIPAL", CONF_KRB5PRINCIPAL },
713 { "INCLUDEFILE", CONF_INCLUDEFILE },
714 { "CONNECT_TRIES", CONF_CONNECT_TRIES },
715 { "REP_TRIES", CONF_REP_TRIES },
716 { "REQ_TRIES", CONF_REQ_TRIES },
717 { "CLIENT", CONF_CLIENT },
718 { "DEBUG_AMANDAD", CONF_DEBUG_AMANDAD },
719 { "DEBUG_AMIDXTAPED", CONF_DEBUG_AMIDXTAPED },
720 { "DEBUG_AMINDEXD", CONF_DEBUG_AMINDEXD },
721 { "DEBUG_AMRECOVER", CONF_DEBUG_AMRECOVER },
722 { "DEBUG_AUTH", CONF_DEBUG_AUTH },
723 { "DEBUG_EVENT", CONF_DEBUG_EVENT },
724 { "DEBUG_HOLDING", CONF_DEBUG_HOLDING },
725 { "DEBUG_PROTOCOL", CONF_DEBUG_PROTOCOL },
726 { "DEBUG_PLANNER", CONF_DEBUG_PLANNER },
727 { "DEBUG_DRIVER", CONF_DEBUG_DRIVER },
728 { "DEBUG_DUMPER", CONF_DEBUG_DUMPER },
729 { "DEBUG_CHUNKER", CONF_DEBUG_CHUNKER },
730 { "DEBUG_TAPER", CONF_DEBUG_TAPER },
731 { "DEBUG_SELFCHECK", CONF_DEBUG_SELFCHECK },
732 { "DEBUG_SENDSIZE", CONF_DEBUG_SENDSIZE },
733 { "DEBUG_SENDBACKUP", CONF_DEBUG_SENDBACKUP },
734 { "EXECUTE_ON", CONF_EXECUTE_ON },
735 { "EXECUTE_WHERE", CONF_EXECUTE_WHERE },
736 { "RESERVED_UDP_PORT", CONF_RESERVED_UDP_PORT },
737 { "RESERVED_TCP_PORT", CONF_RESERVED_TCP_PORT },
738 { "UNRESERVED_TCP_PORT", CONF_UNRESERVED_TCP_PORT },
739 { "DEFINE", CONF_DEFINE },
740 { "COMMENT", CONF_COMMENT },
741 { "MAILER", CONF_MAILER },
742 { "SCRIPT", CONF_PP_SCRIPT },
743 { "SCRIPT_TOOL", CONF_PP_SCRIPT_TOOL },
744 { "PLUGIN", CONF_PLUGIN },
745 { "PRE_DLE_AMCHECK", CONF_PRE_DLE_AMCHECK },
746 { "PRE_HOST_AMCHECK", CONF_PRE_HOST_AMCHECK },
747 { "POST_DLE_AMCHECK", CONF_POST_DLE_AMCHECK },
748 { "POST_HOST_AMCHECK", CONF_POST_HOST_AMCHECK },
749 { "PRE_DLE_ESTIMATE", CONF_PRE_DLE_ESTIMATE },
750 { "PRE_HOST_ESTIMATE", CONF_PRE_HOST_ESTIMATE },
751 { "POST_DLE_ESTIMATE", CONF_POST_DLE_ESTIMATE },
752 { "POST_HOST_ESTIMATE", CONF_POST_HOST_ESTIMATE },
753 { "POST_DLE_BACKUP", CONF_POST_DLE_BACKUP },
754 { "POST_HOST_BACKUP", CONF_POST_HOST_BACKUP },
755 { "PRE_DLE_BACKUP", CONF_PRE_DLE_BACKUP },
756 { "PRE_HOST_BACKUP", CONF_PRE_HOST_BACKUP },
757 { "PRE_RECOVER", CONF_PRE_RECOVER },
758 { "POST_RECOVER", CONF_POST_RECOVER },
759 { "PRE_LEVEL_RECOVER", CONF_PRE_LEVEL_RECOVER },
760 { "POST_LEVEL_RECOVER", CONF_POST_LEVEL_RECOVER },
761 { "INTER_LEVEL_RECOVER", CONF_INTER_LEVEL_RECOVER },
762 { "PRIORITY", CONF_PRIORITY },
763 { "PROPERTY", CONF_PROPERTY },
764 { "APPLICATION", CONF_APPLICATION },
765 { "APPLICATION_TOOL", CONF_APPLICATION_TOOL },
766 { "SERVER", CONF_SERVER },
767 { "APPEND", CONF_APPEND },
768 { NULL, CONF_IDENT },
769 { NULL, CONF_UNKNOWN }
772 keytab_t server_keytab[] = {
774 { "AMANDAD_PATH", CONF_AMANDAD_PATH },
775 { "AMRECOVER_CHANGER", CONF_AMRECOVER_CHANGER },
776 { "AMRECOVER_CHECK_LABEL", CONF_AMRECOVER_CHECK_LABEL },
777 { "AMRECOVER_DO_FSF", CONF_AMRECOVER_DO_FSF },
778 { "APPEND", CONF_APPEND },
779 { "AUTH", CONF_AUTH },
780 { "AUTO", CONF_AUTO },
781 { "AUTOFLUSH", CONF_AUTOFLUSH },
782 { "APPLICATION", CONF_APPLICATION },
783 { "APPLICATION_TOOL", CONF_APPLICATION_TOOL },
784 { "BEST", CONF_BEST },
785 { "BLOCKSIZE", CONF_BLOCKSIZE },
786 { "BUMPDAYS", CONF_BUMPDAYS },
787 { "BUMPMULT", CONF_BUMPMULT },
788 { "BUMPPERCENT", CONF_BUMPPERCENT },
789 { "BUMPSIZE", CONF_BUMPSIZE },
790 { "CALCSIZE", CONF_CALCSIZE },
791 { "CHANGER", CONF_CHANGER },
792 { "CHANGERDEV", CONF_CHANGERDEV },
793 { "CHANGERFILE", CONF_CHANGERFILE },
794 { "CHUNKSIZE", CONF_CHUNKSIZE },
795 { "CLIENT", CONF_CLIENT },
796 { "CLIENT_CUSTOM_COMPRESS", CONF_CLNTCOMPPROG },
797 { "CLIENT_DECRYPT_OPTION", CONF_CLNT_DECRYPT_OPT },
798 { "CLIENT_ENCRYPT", CONF_CLNT_ENCRYPT },
799 { "CLIENT_USERNAME", CONF_CLIENT_USERNAME },
800 { "COLUMNSPEC", CONF_COLUMNSPEC },
801 { "COMMENT", CONF_COMMENT },
802 { "COMPRATE", CONF_COMPRATE },
803 { "COMPRESS", CONF_COMPRESS },
804 { "CONNECT_TRIES", CONF_CONNECT_TRIES },
805 { "CTIMEOUT", CONF_CTIMEOUT },
806 { "CUSTOM", CONF_CUSTOM },
807 { "DEBUG_AMANDAD" , CONF_DEBUG_AMANDAD },
808 { "DEBUG_AMIDXTAPED" , CONF_DEBUG_AMIDXTAPED },
809 { "DEBUG_AMINDEXD" , CONF_DEBUG_AMINDEXD },
810 { "DEBUG_AMRECOVER" , CONF_DEBUG_AMRECOVER },
811 { "DEBUG_AUTH" , CONF_DEBUG_AUTH },
812 { "DEBUG_EVENT" , CONF_DEBUG_EVENT },
813 { "DEBUG_HOLDING" , CONF_DEBUG_HOLDING },
814 { "DEBUG_PROTOCOL" , CONF_DEBUG_PROTOCOL },
815 { "DEBUG_PLANNER" , CONF_DEBUG_PLANNER },
816 { "DEBUG_DRIVER" , CONF_DEBUG_DRIVER },
817 { "DEBUG_DUMPER" , CONF_DEBUG_DUMPER },
818 { "DEBUG_CHUNKER" , CONF_DEBUG_CHUNKER },
819 { "DEBUG_TAPER" , CONF_DEBUG_TAPER },
820 { "DEBUG_SELFCHECK" , CONF_DEBUG_SELFCHECK },
821 { "DEBUG_SENDSIZE" , CONF_DEBUG_SENDSIZE },
822 { "DEBUG_SENDBACKUP" , CONF_DEBUG_SENDBACKUP },
823 { "DEFINE", CONF_DEFINE },
824 { "DEVICE", CONF_DEVICE },
825 { "DEVICE_PROPERTY", CONF_DEVICE_PROPERTY },
826 { "DIRECTORY", CONF_DIRECTORY },
827 { "DISKFILE", CONF_DISKFILE },
828 { "DISPLAYUNIT", CONF_DISPLAYUNIT },
829 { "DTIMEOUT", CONF_DTIMEOUT },
830 { "DUMPCYCLE", CONF_DUMPCYCLE },
831 { "DUMPORDER", CONF_DUMPORDER },
832 { "DUMPTYPE", CONF_DUMPTYPE },
833 { "DUMPUSER", CONF_DUMPUSER },
834 { "ENCRYPT", CONF_ENCRYPT },
835 { "ERROR", CONF_ERROR },
836 { "ESTIMATE", CONF_ESTIMATE },
837 { "ETIMEOUT", CONF_ETIMEOUT },
838 { "EXCLUDE", CONF_EXCLUDE },
839 { "EXCLUDE_FILE", CONF_EXCLUDE_FILE },
840 { "EXCLUDE_LIST", CONF_EXCLUDE_LIST },
841 { "EXECUTE_ON", CONF_EXECUTE_ON },
842 { "EXECUTE_WHERE", CONF_EXECUTE_WHERE },
843 { "FALLBACK_SPLITSIZE", CONF_FALLBACK_SPLITSIZE },
844 { "FAST", CONF_FAST },
845 { "FILE", CONF_EFILE },
846 { "FILE_PAD", CONF_FILE_PAD },
847 { "FILEMARK", CONF_FILEMARK },
848 { "FIRST", CONF_FIRST },
849 { "FIRSTFIT", CONF_FIRSTFIT },
850 { "HANOI", CONF_HANOI },
851 { "HIGH", CONF_HIGH },
852 { "HOLDINGDISK", CONF_HOLDING },
853 { "IGNORE", CONF_IGNORE },
854 { "INCLUDE", CONF_INCLUDE },
855 { "INCLUDEFILE", CONF_INCLUDEFILE },
856 { "INCRONLY", CONF_INCRONLY },
857 { "INDEX", CONF_INDEX },
858 { "INDEXDIR", CONF_INDEXDIR },
859 { "INFOFILE", CONF_INFOFILE },
860 { "INPARALLEL", CONF_INPARALLEL },
861 { "INTERFACE", CONF_INTERFACE },
862 { "KENCRYPT", CONF_KENCRYPT },
863 { "KRB5KEYTAB", CONF_KRB5KEYTAB },
864 { "KRB5PRINCIPAL", CONF_KRB5PRINCIPAL },
865 { "LABELSTR", CONF_LABELSTR },
866 { "LABEL_NEW_TAPES", CONF_LABEL_NEW_TAPES },
867 { "LARGEST", CONF_LARGEST },
868 { "LARGESTFIT", CONF_LARGESTFIT },
869 { "LAST", CONF_LAST },
870 { "LBL_TEMPL", CONF_LBL_TEMPL },
871 { "LENGTH", CONF_LENGTH },
872 { "LIST", CONF_LIST },
873 { "LOGDIR", CONF_LOGDIR },
875 { "MAILER", CONF_MAILER },
876 { "MAILTO", CONF_MAILTO },
877 { "READBLOCKSIZE", CONF_READBLOCKSIZE },
878 { "MAXDUMPS", CONF_MAXDUMPS },
879 { "MAXDUMPSIZE", CONF_MAXDUMPSIZE },
880 { "MAXPROMOTEDAY", CONF_MAXPROMOTEDAY },
881 { "MEDIUM", CONF_MEDIUM },
882 { "NETUSAGE", CONF_NETUSAGE },
883 { "NEVER", CONF_NEVER },
884 { "NOFULL", CONF_NOFULL },
885 { "NOINC", CONF_NOINC },
886 { "NONE", CONF_NONE },
887 { "OPTIONAL", CONF_OPTIONAL },
889 { "PLUGIN", CONF_PLUGIN },
890 { "PRE_DLE_AMCHECK", CONF_PRE_DLE_AMCHECK },
891 { "PRE_HOST_AMCHECK", CONF_PRE_HOST_AMCHECK },
892 { "POST_DLE_AMCHECK", CONF_POST_DLE_AMCHECK },
893 { "POST_HOST_AMCHECK", CONF_POST_HOST_AMCHECK },
894 { "PRE_DLE_ESTIMATE", CONF_PRE_DLE_ESTIMATE },
895 { "PRE_HOST_ESTIMATE", CONF_PRE_HOST_ESTIMATE },
896 { "POST_DLE_ESTIMATE", CONF_POST_DLE_ESTIMATE },
897 { "POST_HOST_ESTIMATE", CONF_POST_HOST_ESTIMATE },
898 { "POST_DLE_BACKUP", CONF_POST_DLE_BACKUP },
899 { "POST_HOST_BACKUP", CONF_POST_HOST_BACKUP },
900 { "PRE_DLE_BACKUP", CONF_PRE_DLE_BACKUP },
901 { "PRE_HOST_BACKUP", CONF_PRE_HOST_BACKUP },
902 { "PRE_RECOVER", CONF_PRE_RECOVER },
903 { "POST_RECOVER", CONF_POST_RECOVER },
904 { "PRE_LEVEL_RECOVER", CONF_PRE_LEVEL_RECOVER },
905 { "POST_LEVEL_RECOVER", CONF_POST_LEVEL_RECOVER },
906 { "INTER_LEVEL_RECOVER", CONF_INTER_LEVEL_RECOVER },
907 { "PRINTER", CONF_PRINTER },
908 { "PRIORITY", CONF_PRIORITY },
909 { "PROGRAM", CONF_PROGRAM },
910 { "PROPERTY", CONF_PROPERTY },
911 { "RECORD", CONF_RECORD },
912 { "REP_TRIES", CONF_REP_TRIES },
913 { "REQ_TRIES", CONF_REQ_TRIES },
914 { "REQUIRED", CONF_REQUIRED },
915 { "RESERVE", CONF_RESERVE },
916 { "RESERVED_UDP_PORT", CONF_RESERVED_UDP_PORT },
917 { "RESERVED_TCP_PORT", CONF_RESERVED_TCP_PORT },
918 { "RUNSPERCYCLE", CONF_RUNSPERCYCLE },
919 { "RUNTAPES", CONF_RUNTAPES },
920 { "SCRIPT", CONF_PP_SCRIPT },
921 { "SCRIPT_TOOL", CONF_PP_SCRIPT_TOOL },
922 { "SEND_AMREPORT_ON", CONF_SEND_AMREPORT_ON },
923 { "SERVER", CONF_SERVER },
924 { "SERVER_CUSTOM_COMPRESS", CONF_SRVCOMPPROG },
925 { "SERVER_DECRYPT_OPTION", CONF_SRV_DECRYPT_OPT },
926 { "SERVER_ENCRYPT", CONF_SRV_ENCRYPT },
927 { "SKIP", CONF_SKIP },
928 { "SKIP_FULL", CONF_SKIP_FULL },
929 { "SKIP_INCR", CONF_SKIP_INCR },
930 { "SMALLEST", CONF_SMALLEST },
931 { "SPEED", CONF_SPEED },
932 { "SPLIT_DISKBUFFER", CONF_SPLIT_DISKBUFFER },
933 { "SSH_KEYS", CONF_SSH_KEYS },
934 { "STANDARD", CONF_STANDARD },
935 { "STARTTIME", CONF_STARTTIME },
936 { "STRANGE", CONF_STRANGE },
937 { "STRATEGY", CONF_STRATEGY },
938 { "TAPEBUFS", CONF_TAPEBUFS },
939 { "DEVICE_OUTPUT_BUFFER_SIZE", CONF_DEVICE_OUTPUT_BUFFER_SIZE },
940 { "TAPECYCLE", CONF_TAPECYCLE },
941 { "TAPEDEV", CONF_TAPEDEV },
942 { "RAWTAPEDEV", CONF_RAWTAPEDEV },
943 { "TAPELIST", CONF_TAPELIST },
944 { "TAPERALGO", CONF_TAPERALGO },
945 { "FLUSH_THRESHOLD_DUMPED", CONF_FLUSH_THRESHOLD_DUMPED },
946 { "FLUSH_THRESHOLD_SCHEDULED", CONF_FLUSH_THRESHOLD_SCHEDULED },
947 { "TAPERFLUSH", CONF_TAPERFLUSH },
948 { "TAPETYPE", CONF_TAPETYPE },
949 { "TAPE_SPLITSIZE", CONF_TAPE_SPLITSIZE },
950 { "TPCHANGER", CONF_TPCHANGER },
951 { "UNRESERVED_TCP_PORT", CONF_UNRESERVED_TCP_PORT },
953 { "USETIMESTAMPS", CONF_USETIMESTAMPS },
954 { NULL, CONF_IDENT },
955 { NULL, CONF_UNKNOWN }
958 /* A keyword table for recognizing unit suffixes. No distinction is made for kinds
959 * of suffixes: 1024 weeks = 7 k. */
960 keytab_t numb_keytable[] = {
962 { "BPS", CONF_MULT1 },
963 { "BYTE", CONF_MULT1 },
964 { "BYTES", CONF_MULT1 },
965 { "DAY", CONF_MULT1 },
966 { "DAYS", CONF_MULT1 },
967 { "INF", CONF_AMINFINITY },
968 { "K", CONF_MULT1K },
969 { "KB", CONF_MULT1K },
970 { "KBPS", CONF_MULT1K },
971 { "KBYTE", CONF_MULT1K },
972 { "KBYTES", CONF_MULT1K },
973 { "KILOBYTE", CONF_MULT1K },
974 { "KILOBYTES", CONF_MULT1K },
975 { "KPS", CONF_MULT1K },
976 { "M", CONF_MULT1M },
977 { "MB", CONF_MULT1M },
978 { "MBPS", CONF_MULT1M },
979 { "MBYTE", CONF_MULT1M },
980 { "MBYTES", CONF_MULT1M },
981 { "MEG", CONF_MULT1M },
982 { "MEGABYTE", CONF_MULT1M },
983 { "MEGABYTES", CONF_MULT1M },
984 { "G", CONF_MULT1G },
985 { "GB", CONF_MULT1G },
986 { "GBPS", CONF_MULT1G },
987 { "GBYTE", CONF_MULT1G },
988 { "GBYTES", CONF_MULT1G },
989 { "GIG", CONF_MULT1G },
990 { "GIGABYTE", CONF_MULT1G },
991 { "GIGABYTES", CONF_MULT1G },
992 { "MPS", CONF_MULT1M },
993 { "TAPE", CONF_MULT1 },
994 { "TAPES", CONF_MULT1 },
995 { "WEEK", CONF_MULT7 },
996 { "WEEKS", CONF_MULT7 },
1000 /* Boolean keywords -- all the ways to say "true" and "false" in amanda.conf */
1001 keytab_t bool_keytable[] = {
1002 { "Y", CONF_ATRUE },
1003 { "YES", CONF_ATRUE },
1004 { "T", CONF_ATRUE },
1005 { "TRUE", CONF_ATRUE },
1006 { "ON", CONF_ATRUE },
1007 { "N", CONF_AFALSE },
1008 { "NO", CONF_AFALSE },
1009 { "F", CONF_AFALSE },
1010 { "FALSE", CONF_AFALSE },
1011 { "OFF", CONF_AFALSE },
1012 { NULL, CONF_IDENT }
1015 /* Now, the parser tables for client and server global parameters, and for
1016 * each of the server subsections */
1017 conf_var_t client_var [] = {
1018 { CONF_CONF , CONFTYPE_STR , read_str , CNF_CONF , NULL },
1019 { CONF_INDEX_SERVER , CONFTYPE_STR , read_str , CNF_INDEX_SERVER , NULL },
1020 { CONF_TAPE_SERVER , CONFTYPE_STR , read_str , CNF_TAPE_SERVER , NULL },
1021 { CONF_TAPEDEV , CONFTYPE_STR , read_str , CNF_TAPEDEV , NULL },
1022 { CONF_AUTH , CONFTYPE_STR , read_str , CNF_AUTH , NULL },
1023 { CONF_SSH_KEYS , CONFTYPE_STR , read_str , CNF_SSH_KEYS , NULL },
1024 { CONF_AMANDAD_PATH , CONFTYPE_STR , read_str , CNF_AMANDAD_PATH , NULL },
1025 { CONF_CLIENT_USERNAME , CONFTYPE_STR , read_str , CNF_CLIENT_USERNAME , NULL },
1026 { CONF_GNUTAR_LIST_DIR , CONFTYPE_STR , read_str , CNF_GNUTAR_LIST_DIR , NULL },
1027 { CONF_AMANDATES , CONFTYPE_STR , read_str , CNF_AMANDATES , NULL },
1028 { CONF_MAILER , CONFTYPE_STR , read_str , CNF_MAILER , NULL },
1029 { CONF_KRB5KEYTAB , CONFTYPE_STR , read_str , CNF_KRB5KEYTAB , NULL },
1030 { CONF_KRB5PRINCIPAL , CONFTYPE_STR , read_str , CNF_KRB5PRINCIPAL , NULL },
1031 { CONF_CONNECT_TRIES , CONFTYPE_INT , read_int , CNF_CONNECT_TRIES , validate_positive },
1032 { CONF_REP_TRIES , CONFTYPE_INT , read_int , CNF_REP_TRIES , validate_positive },
1033 { CONF_REQ_TRIES , CONFTYPE_INT , read_int , CNF_REQ_TRIES , validate_positive },
1034 { CONF_DEBUG_AMANDAD , CONFTYPE_INT , read_int , CNF_DEBUG_AMANDAD , validate_debug },
1035 { CONF_DEBUG_AMIDXTAPED , CONFTYPE_INT , read_int , CNF_DEBUG_AMIDXTAPED , validate_debug },
1036 { CONF_DEBUG_AMINDEXD , CONFTYPE_INT , read_int , CNF_DEBUG_AMINDEXD , validate_debug },
1037 { CONF_DEBUG_AMRECOVER , CONFTYPE_INT , read_int , CNF_DEBUG_AMRECOVER , validate_debug },
1038 { CONF_DEBUG_AUTH , CONFTYPE_INT , read_int , CNF_DEBUG_AUTH , validate_debug },
1039 { CONF_DEBUG_EVENT , CONFTYPE_INT , read_int , CNF_DEBUG_EVENT , validate_debug },
1040 { CONF_DEBUG_HOLDING , CONFTYPE_INT , read_int , CNF_DEBUG_HOLDING , validate_debug },
1041 { CONF_DEBUG_PROTOCOL , CONFTYPE_INT , read_int , CNF_DEBUG_PROTOCOL , validate_debug },
1042 { CONF_DEBUG_PLANNER , CONFTYPE_INT , read_int , CNF_DEBUG_PLANNER , validate_debug },
1043 { CONF_DEBUG_DRIVER , CONFTYPE_INT , read_int , CNF_DEBUG_DRIVER , validate_debug },
1044 { CONF_DEBUG_DUMPER , CONFTYPE_INT , read_int , CNF_DEBUG_DUMPER , validate_debug },
1045 { CONF_DEBUG_CHUNKER , CONFTYPE_INT , read_int , CNF_DEBUG_CHUNKER , validate_debug },
1046 { CONF_DEBUG_TAPER , CONFTYPE_INT , read_int , CNF_DEBUG_TAPER , validate_debug },
1047 { CONF_DEBUG_SELFCHECK , CONFTYPE_INT , read_int , CNF_DEBUG_SELFCHECK , validate_debug },
1048 { CONF_DEBUG_SENDSIZE , CONFTYPE_INT , read_int , CNF_DEBUG_SENDSIZE , validate_debug },
1049 { CONF_DEBUG_SENDBACKUP , CONFTYPE_INT , read_int , CNF_DEBUG_SENDBACKUP , validate_debug },
1050 { CONF_RESERVED_UDP_PORT , CONFTYPE_INTRANGE, read_intrange, CNF_RESERVED_UDP_PORT , validate_reserved_port_range },
1051 { CONF_RESERVED_TCP_PORT , CONFTYPE_INTRANGE, read_intrange, CNF_RESERVED_TCP_PORT , validate_reserved_port_range },
1052 { CONF_UNRESERVED_TCP_PORT, CONFTYPE_INTRANGE, read_intrange, CNF_UNRESERVED_TCP_PORT, validate_unreserved_port_range },
1053 { CONF_PROPERTY , CONFTYPE_PROPLIST, read_property, CNF_PROPERTY , NULL },
1054 { CONF_APPLICATION , CONFTYPE_STR , read_dapplication, DUMPTYPE_APPLICATION, NULL },
1055 { CONF_PP_SCRIPT , CONFTYPE_STR , read_dpp_script, DUMPTYPE_PP_SCRIPTLIST, NULL },
1056 { CONF_UNKNOWN , CONFTYPE_INT , NULL , CNF_CNF , NULL }
1059 conf_var_t server_var [] = {
1060 { CONF_ORG , CONFTYPE_STR , read_str , CNF_ORG , NULL },
1061 { CONF_MAILTO , CONFTYPE_STR , read_str , CNF_MAILTO , NULL },
1062 { CONF_DUMPUSER , CONFTYPE_STR , read_str , CNF_DUMPUSER , NULL },
1063 { CONF_PRINTER , CONFTYPE_STR , read_str , CNF_PRINTER , NULL },
1064 { CONF_MAILER , CONFTYPE_STR , read_str , CNF_MAILER , NULL },
1065 { CONF_TAPEDEV , CONFTYPE_STR , read_str , CNF_TAPEDEV , NULL },
1066 { CONF_RAWTAPEDEV , CONFTYPE_STR , read_str , CNF_RAWTAPEDEV , NULL },
1067 { CONF_DEVICE_PROPERTY , CONFTYPE_PROPLIST , read_property , CNF_DEVICE_PROPERTY , NULL },
1068 { CONF_PROPERTY , CONFTYPE_PROPLIST , read_property , CNF_PROPERTY , NULL },
1069 { CONF_TPCHANGER , CONFTYPE_STR , read_str , CNF_TPCHANGER , NULL },
1070 { CONF_CHANGERDEV , CONFTYPE_STR , read_str , CNF_CHANGERDEV , NULL },
1071 { CONF_CHANGERFILE , CONFTYPE_STR , read_str , CNF_CHANGERFILE , NULL },
1072 { CONF_LABELSTR , CONFTYPE_STR , read_str , CNF_LABELSTR , NULL },
1073 { CONF_TAPELIST , CONFTYPE_STR , read_str , CNF_TAPELIST , NULL },
1074 { CONF_DISKFILE , CONFTYPE_STR , read_str , CNF_DISKFILE , NULL },
1075 { CONF_INFOFILE , CONFTYPE_STR , read_str , CNF_INFOFILE , NULL },
1076 { CONF_LOGDIR , CONFTYPE_STR , read_str , CNF_LOGDIR , NULL },
1077 { CONF_INDEXDIR , CONFTYPE_STR , read_str , CNF_INDEXDIR , NULL },
1078 { CONF_TAPETYPE , CONFTYPE_IDENT , read_ident , CNF_TAPETYPE , NULL },
1079 { CONF_DUMPCYCLE , CONFTYPE_INT , read_int , CNF_DUMPCYCLE , validate_nonnegative },
1080 { CONF_RUNSPERCYCLE , CONFTYPE_INT , read_int , CNF_RUNSPERCYCLE , validate_runspercycle },
1081 { CONF_RUNTAPES , CONFTYPE_INT , read_int , CNF_RUNTAPES , validate_nonnegative },
1082 { CONF_TAPECYCLE , CONFTYPE_INT , read_int , CNF_TAPECYCLE , validate_positive },
1083 { CONF_BUMPDAYS , CONFTYPE_INT , read_int , CNF_BUMPDAYS , validate_positive },
1084 { CONF_BUMPSIZE , CONFTYPE_INT64 , read_int64 , CNF_BUMPSIZE , validate_positive },
1085 { CONF_BUMPPERCENT , CONFTYPE_INT , read_int , CNF_BUMPPERCENT , validate_bumppercent },
1086 { CONF_BUMPMULT , CONFTYPE_REAL , read_real , CNF_BUMPMULT , validate_bumpmult },
1087 { CONF_NETUSAGE , CONFTYPE_INT , read_int , CNF_NETUSAGE , validate_positive },
1088 { CONF_INPARALLEL , CONFTYPE_INT , read_int , CNF_INPARALLEL , validate_inparallel },
1089 { CONF_DUMPORDER , CONFTYPE_STR , read_str , CNF_DUMPORDER , NULL },
1090 { CONF_MAXDUMPS , CONFTYPE_INT , read_int , CNF_MAXDUMPS , validate_positive },
1091 { CONF_ETIMEOUT , CONFTYPE_INT , read_int , CNF_ETIMEOUT , NULL },
1092 { CONF_DTIMEOUT , CONFTYPE_INT , read_int , CNF_DTIMEOUT , validate_positive },
1093 { CONF_CTIMEOUT , CONFTYPE_INT , read_int , CNF_CTIMEOUT , validate_positive },
1094 { CONF_TAPEBUFS , CONFTYPE_INT , read_int , CNF_TAPEBUFS , validate_positive },
1095 { CONF_DEVICE_OUTPUT_BUFFER_SIZE, CONFTYPE_SIZE , read_size , CNF_DEVICE_OUTPUT_BUFFER_SIZE, validate_positive },
1096 { CONF_COLUMNSPEC , CONFTYPE_STR , read_str , CNF_COLUMNSPEC , NULL },
1097 { CONF_TAPERALGO , CONFTYPE_TAPERALGO, read_taperalgo , CNF_TAPERALGO , NULL },
1098 { CONF_SEND_AMREPORT_ON , CONFTYPE_SEND_AMREPORT_ON, read_send_amreport_on, CNF_SEND_AMREPORT_ON , NULL },
1099 { CONF_FLUSH_THRESHOLD_DUMPED, CONFTYPE_INT , read_int , CNF_FLUSH_THRESHOLD_DUMPED, validate_nonnegative },
1100 { CONF_FLUSH_THRESHOLD_SCHEDULED, CONFTYPE_INT , read_int , CNF_FLUSH_THRESHOLD_SCHEDULED, validate_nonnegative },
1101 { CONF_TAPERFLUSH , CONFTYPE_INT , read_int , CNF_TAPERFLUSH , validate_nonnegative },
1102 { CONF_DISPLAYUNIT , CONFTYPE_STR , read_str , CNF_DISPLAYUNIT , validate_displayunit },
1103 { CONF_AUTOFLUSH , CONFTYPE_BOOLEAN , read_bool , CNF_AUTOFLUSH , NULL },
1104 { CONF_RESERVE , CONFTYPE_INT , read_int , CNF_RESERVE , validate_reserve },
1105 { CONF_MAXDUMPSIZE , CONFTYPE_INT64 , read_int64 , CNF_MAXDUMPSIZE , NULL },
1106 { CONF_KRB5KEYTAB , CONFTYPE_STR , read_str , CNF_KRB5KEYTAB , NULL },
1107 { CONF_KRB5PRINCIPAL , CONFTYPE_STR , read_str , CNF_KRB5PRINCIPAL , NULL },
1108 { CONF_LABEL_NEW_TAPES , CONFTYPE_STR , read_str , CNF_LABEL_NEW_TAPES , NULL },
1109 { CONF_USETIMESTAMPS , CONFTYPE_BOOLEAN , read_bool , CNF_USETIMESTAMPS , NULL },
1110 { CONF_AMRECOVER_DO_FSF , CONFTYPE_BOOLEAN , read_bool , CNF_AMRECOVER_DO_FSF , NULL },
1111 { CONF_AMRECOVER_CHANGER , CONFTYPE_STR , read_str , CNF_AMRECOVER_CHANGER , NULL },
1112 { CONF_AMRECOVER_CHECK_LABEL, CONFTYPE_BOOLEAN , read_bool , CNF_AMRECOVER_CHECK_LABEL, NULL },
1113 { CONF_CONNECT_TRIES , CONFTYPE_INT , read_int , CNF_CONNECT_TRIES , validate_positive },
1114 { CONF_REP_TRIES , CONFTYPE_INT , read_int , CNF_REP_TRIES , validate_positive },
1115 { CONF_REQ_TRIES , CONFTYPE_INT , read_int , CNF_REQ_TRIES , validate_positive },
1116 { CONF_DEBUG_AMANDAD , CONFTYPE_INT , read_int , CNF_DEBUG_AMANDAD , validate_debug },
1117 { CONF_DEBUG_AMIDXTAPED , CONFTYPE_INT , read_int , CNF_DEBUG_AMIDXTAPED , validate_debug },
1118 { CONF_DEBUG_AMINDEXD , CONFTYPE_INT , read_int , CNF_DEBUG_AMINDEXD , validate_debug },
1119 { CONF_DEBUG_AMRECOVER , CONFTYPE_INT , read_int , CNF_DEBUG_AMRECOVER , validate_debug },
1120 { CONF_DEBUG_AUTH , CONFTYPE_INT , read_int , CNF_DEBUG_AUTH , validate_debug },
1121 { CONF_DEBUG_EVENT , CONFTYPE_INT , read_int , CNF_DEBUG_EVENT , validate_debug },
1122 { CONF_DEBUG_HOLDING , CONFTYPE_INT , read_int , CNF_DEBUG_HOLDING , validate_debug },
1123 { CONF_DEBUG_PROTOCOL , CONFTYPE_INT , read_int , CNF_DEBUG_PROTOCOL , validate_debug },
1124 { CONF_DEBUG_PLANNER , CONFTYPE_INT , read_int , CNF_DEBUG_PLANNER , validate_debug },
1125 { CONF_DEBUG_DRIVER , CONFTYPE_INT , read_int , CNF_DEBUG_DRIVER , validate_debug },
1126 { CONF_DEBUG_DUMPER , CONFTYPE_INT , read_int , CNF_DEBUG_DUMPER , validate_debug },
1127 { CONF_DEBUG_CHUNKER , CONFTYPE_INT , read_int , CNF_DEBUG_CHUNKER , validate_debug },
1128 { CONF_DEBUG_TAPER , CONFTYPE_INT , read_int , CNF_DEBUG_TAPER , validate_debug },
1129 { CONF_DEBUG_SELFCHECK , CONFTYPE_INT , read_int , CNF_DEBUG_SELFCHECK , validate_debug },
1130 { CONF_DEBUG_SENDSIZE , CONFTYPE_INT , read_int , CNF_DEBUG_SENDSIZE , validate_debug },
1131 { CONF_DEBUG_SENDBACKUP , CONFTYPE_INT , read_int , CNF_DEBUG_SENDBACKUP , validate_debug },
1132 { CONF_RESERVED_UDP_PORT , CONFTYPE_INTRANGE , read_intrange , CNF_RESERVED_UDP_PORT , validate_reserved_port_range },
1133 { CONF_RESERVED_TCP_PORT , CONFTYPE_INTRANGE , read_intrange , CNF_RESERVED_TCP_PORT , validate_reserved_port_range },
1134 { CONF_UNRESERVED_TCP_PORT , CONFTYPE_INTRANGE , read_intrange , CNF_UNRESERVED_TCP_PORT , validate_unreserved_port_range },
1135 { CONF_UNKNOWN , CONFTYPE_INT , NULL , CNF_CNF , NULL }
1138 conf_var_t tapetype_var [] = {
1139 { CONF_COMMENT , CONFTYPE_STR , read_str , TAPETYPE_COMMENT , NULL },
1140 { CONF_LBL_TEMPL , CONFTYPE_STR , read_str , TAPETYPE_LBL_TEMPL , NULL },
1141 { CONF_BLOCKSIZE , CONFTYPE_SIZE , read_size , TAPETYPE_BLOCKSIZE , validate_blocksize },
1142 { CONF_READBLOCKSIZE , CONFTYPE_SIZE , read_size , TAPETYPE_READBLOCKSIZE, validate_blocksize },
1143 { CONF_LENGTH , CONFTYPE_INT64 , read_int64 , TAPETYPE_LENGTH , validate_nonnegative },
1144 { CONF_FILEMARK , CONFTYPE_INT64 , read_int64 , TAPETYPE_FILEMARK , NULL },
1145 { CONF_SPEED , CONFTYPE_INT , read_int , TAPETYPE_SPEED , validate_nonnegative },
1146 { CONF_FILE_PAD , CONFTYPE_BOOLEAN , read_bool , TAPETYPE_FILE_PAD , NULL },
1147 { CONF_UNKNOWN , CONFTYPE_INT , NULL , TAPETYPE_TAPETYPE , NULL }
1150 conf_var_t dumptype_var [] = {
1151 { CONF_COMMENT , CONFTYPE_STR , read_str , DUMPTYPE_COMMENT , NULL },
1152 { CONF_AUTH , CONFTYPE_STR , read_str , DUMPTYPE_SECURITY_DRIVER , NULL },
1153 { CONF_BUMPDAYS , CONFTYPE_INT , read_int , DUMPTYPE_BUMPDAYS , NULL },
1154 { CONF_BUMPMULT , CONFTYPE_REAL , read_real , DUMPTYPE_BUMPMULT , NULL },
1155 { CONF_BUMPSIZE , CONFTYPE_INT64 , read_int64 , DUMPTYPE_BUMPSIZE , NULL },
1156 { CONF_BUMPPERCENT , CONFTYPE_INT , read_int , DUMPTYPE_BUMPPERCENT , NULL },
1157 { CONF_COMPRATE , CONFTYPE_REAL , read_rate , DUMPTYPE_COMPRATE , NULL },
1158 { CONF_COMPRESS , CONFTYPE_INT , read_compress , DUMPTYPE_COMPRESS , NULL },
1159 { CONF_ENCRYPT , CONFTYPE_INT , read_encrypt , DUMPTYPE_ENCRYPT , NULL },
1160 { CONF_DUMPCYCLE , CONFTYPE_INT , read_int , DUMPTYPE_DUMPCYCLE , validate_nonnegative },
1161 { CONF_EXCLUDE , CONFTYPE_EXINCLUDE, read_exinclude, DUMPTYPE_EXCLUDE , NULL },
1162 { CONF_INCLUDE , CONFTYPE_EXINCLUDE, read_exinclude, DUMPTYPE_INCLUDE , NULL },
1163 { CONF_IGNORE , CONFTYPE_BOOLEAN , read_bool , DUMPTYPE_IGNORE , NULL },
1164 { CONF_HOLDING , CONFTYPE_HOLDING , read_holding , DUMPTYPE_HOLDINGDISK , NULL },
1165 { CONF_INDEX , CONFTYPE_BOOLEAN , read_bool , DUMPTYPE_INDEX , NULL },
1166 { CONF_KENCRYPT , CONFTYPE_BOOLEAN , read_bool , DUMPTYPE_KENCRYPT , NULL },
1167 { CONF_MAXDUMPS , CONFTYPE_INT , read_int , DUMPTYPE_MAXDUMPS , validate_positive },
1168 { CONF_MAXPROMOTEDAY , CONFTYPE_INT , read_int , DUMPTYPE_MAXPROMOTEDAY , validate_nonnegative },
1169 { CONF_PRIORITY , CONFTYPE_PRIORITY , read_priority , DUMPTYPE_PRIORITY , NULL },
1170 { CONF_PROGRAM , CONFTYPE_STR , read_str , DUMPTYPE_PROGRAM , validate_program },
1171 { CONF_PROPERTY , CONFTYPE_PROPLIST , read_property , DUMPTYPE_PROPERTY , NULL },
1172 { CONF_RECORD , CONFTYPE_BOOLEAN , read_bool , DUMPTYPE_RECORD , NULL },
1173 { CONF_SKIP_FULL , CONFTYPE_BOOLEAN , read_bool , DUMPTYPE_SKIP_FULL , NULL },
1174 { CONF_SKIP_INCR , CONFTYPE_BOOLEAN , read_bool , DUMPTYPE_SKIP_INCR , NULL },
1175 { CONF_STARTTIME , CONFTYPE_TIME , read_time , DUMPTYPE_STARTTIME , NULL },
1176 { CONF_STRATEGY , CONFTYPE_INT , read_strategy , DUMPTYPE_STRATEGY , NULL },
1177 { CONF_TAPE_SPLITSIZE , CONFTYPE_INT64 , read_int64 , DUMPTYPE_TAPE_SPLITSIZE , validate_nonnegative },
1178 { CONF_SPLIT_DISKBUFFER , CONFTYPE_STR , read_str , DUMPTYPE_SPLIT_DISKBUFFER , NULL },
1179 { CONF_ESTIMATE , CONFTYPE_INT , read_estimate , DUMPTYPE_ESTIMATE , NULL },
1180 { CONF_SRV_ENCRYPT , CONFTYPE_STR , read_str , DUMPTYPE_SRV_ENCRYPT , NULL },
1181 { CONF_CLNT_ENCRYPT , CONFTYPE_STR , read_str , DUMPTYPE_CLNT_ENCRYPT , NULL },
1182 { CONF_AMANDAD_PATH , CONFTYPE_STR , read_str , DUMPTYPE_AMANDAD_PATH , NULL },
1183 { CONF_CLIENT_USERNAME , CONFTYPE_STR , read_str , DUMPTYPE_CLIENT_USERNAME , NULL },
1184 { CONF_SSH_KEYS , CONFTYPE_STR , read_str , DUMPTYPE_SSH_KEYS , NULL },
1185 { CONF_SRVCOMPPROG , CONFTYPE_STR , read_str , DUMPTYPE_SRVCOMPPROG , NULL },
1186 { CONF_CLNTCOMPPROG , CONFTYPE_STR , read_str , DUMPTYPE_CLNTCOMPPROG , NULL },
1187 { CONF_FALLBACK_SPLITSIZE, CONFTYPE_INT64 , read_int64 , DUMPTYPE_FALLBACK_SPLITSIZE, NULL },
1188 { CONF_SRV_DECRYPT_OPT , CONFTYPE_STR , read_str , DUMPTYPE_SRV_DECRYPT_OPT , NULL },
1189 { CONF_CLNT_DECRYPT_OPT , CONFTYPE_STR , read_str , DUMPTYPE_CLNT_DECRYPT_OPT , NULL },
1190 { CONF_APPLICATION , CONFTYPE_STR , read_dapplication, DUMPTYPE_APPLICATION , NULL },
1191 { CONF_PP_SCRIPT , CONFTYPE_STR , read_dpp_script, DUMPTYPE_PP_SCRIPTLIST , NULL },
1192 { CONF_UNKNOWN , CONFTYPE_INT , NULL , DUMPTYPE_DUMPTYPE , NULL }
1195 conf_var_t holding_var [] = {
1196 { CONF_DIRECTORY, CONFTYPE_STR , read_str , HOLDING_DISKDIR , NULL },
1197 { CONF_COMMENT , CONFTYPE_STR , read_str , HOLDING_COMMENT , NULL },
1198 { CONF_USE , CONFTYPE_INT64 , read_int64 , HOLDING_DISKSIZE , validate_use },
1199 { CONF_CHUNKSIZE, CONFTYPE_INT64 , read_int64 , HOLDING_CHUNKSIZE, validate_chunksize },
1200 { CONF_UNKNOWN , CONFTYPE_INT , NULL , HOLDING_HOLDING , NULL }
1203 conf_var_t interface_var [] = {
1204 { CONF_COMMENT, CONFTYPE_STR , read_str , INTER_COMMENT , NULL },
1205 { CONF_USE , CONFTYPE_INT , read_int , INTER_MAXUSAGE, validate_positive },
1206 { CONF_UNKNOWN, CONFTYPE_INT , NULL , INTER_INTER , NULL }
1210 conf_var_t application_var [] = {
1211 { CONF_COMMENT , CONFTYPE_STR , read_str , APPLICATION_COMMENT , NULL },
1212 { CONF_PLUGIN , CONFTYPE_STR , read_str , APPLICATION_PLUGIN , NULL },
1213 { CONF_PROPERTY , CONFTYPE_PROPLIST, read_property, APPLICATION_PROPERTY , NULL },
1214 { CONF_UNKNOWN , CONFTYPE_INT , NULL , APPLICATION_APPLICATION, NULL }
1217 conf_var_t pp_script_var [] = {
1218 { CONF_COMMENT , CONFTYPE_STR , read_str , PP_SCRIPT_COMMENT , NULL },
1219 { CONF_PLUGIN , CONFTYPE_STR , read_str , PP_SCRIPT_PLUGIN , NULL },
1220 { CONF_PROPERTY , CONFTYPE_PROPLIST, read_property, PP_SCRIPT_PROPERTY , NULL },
1221 { CONF_EXECUTE_ON , CONFTYPE_EXECUTE_ON , read_execute_on , PP_SCRIPT_EXECUTE_ON , NULL },
1222 { CONF_EXECUTE_WHERE, CONFTYPE_EXECUTE_WHERE , read_execute_where , PP_SCRIPT_EXECUTE_WHERE, NULL },
1223 { CONF_UNKNOWN , CONFTYPE_INT , NULL , PP_SCRIPT_PP_SCRIPT , NULL }
1226 conf_var_t device_config_var [] = {
1227 { CONF_COMMENT , CONFTYPE_STR , read_str , DEVICE_CONFIG_COMMENT , NULL },
1228 { CONF_DEVICE_PROPERTY , CONFTYPE_PROPLIST , read_property , DEVICE_CONFIG_DEVICE_PROPERTY, NULL },
1229 { CONF_TAPEDEV , CONFTYPE_STR , read_str , DEVICE_CONFIG_TAPEDEV , NULL },
1230 { CONF_UNKNOWN , CONFTYPE_INT , NULL , DEVICE_CONFIG_DEVICE_CONFIG , NULL }
1233 conf_var_t changer_config_var [] = {
1234 { CONF_COMMENT , CONFTYPE_STR , read_str , CHANGER_CONFIG_COMMENT , NULL },
1235 { CONF_TAPEDEV , CONFTYPE_STR , read_str , CHANGER_CONFIG_TAPEDEV , NULL },
1236 { CONF_TPCHANGER , CONFTYPE_STR , read_str , CHANGER_CONFIG_TPCHANGER , NULL },
1237 { CONF_CHANGERDEV , CONFTYPE_STR , read_str , CHANGER_CONFIG_CHANGERDEV , NULL },
1238 { CONF_CHANGERFILE , CONFTYPE_STR , read_str , CHANGER_CONFIG_CHANGERFILE , NULL },
1239 { CONF_UNKNOWN , CONFTYPE_INT , NULL , CHANGER_CONFIG_CHANGER_CONFIG , NULL }
1243 * Lexical Analysis Implementation
1252 if (keytable == NULL) {
1253 error(_("keytable == NULL"));
1257 for(kt = keytable; kt->token != CONF_UNKNOWN; kt++)
1258 if(kt->token == token) break;
1260 if(kt->token == CONF_UNKNOWN)
1262 return(kt->keyword);
1270 char *str1 = stralloc(str);
1273 /* Fold '-' to '_' in the token. Note that this modifies str1
1276 if (*p == '-') *p = '_';
1280 for(kwp = keytable; kwp->keyword != NULL; kwp++) {
1281 if (strcasecmp(kwp->keyword, str1) == 0) break;
1306 ** If it looked like a keyword before then look it
1307 ** up again in the current keyword table.
1310 case CONF_INT64: case CONF_SIZE:
1311 case CONF_INT: case CONF_REAL: case CONF_STRING:
1312 case CONF_LBRACE: case CONF_RBRACE: case CONF_COMMA:
1313 case CONF_NL: case CONF_END: case CONF_UNKNOWN:
1315 break; /* not a keyword */
1318 if (exp == CONF_IDENT)
1321 tok = lookup_keyword(tokenval.v.s);
1326 ch = conftoken_getc();
1328 /* note that we're explicitly assuming this file is ASCII. Someday
1329 * maybe we'll support UTF-8? */
1330 while(ch != EOF && ch != '\n' && g_ascii_isspace(ch))
1331 ch = conftoken_getc();
1332 if (ch == '#') { /* comment - eat everything but eol/eof */
1333 while((ch = conftoken_getc()) != EOF && ch != '\n') {
1334 (void)ch; /* Quiet empty loop complaints */
1338 if (isalpha(ch)) { /* identifier */
1342 if (buf < tkbuf+sizeof(tkbuf)-1) {
1346 if (!token_overflow) {
1347 conf_parserror(_("token too long: %.20s..."), tkbuf);
1351 ch = conftoken_getc();
1352 } while(isalnum(ch) || ch == '_' || ch == '-');
1354 if (ch != EOF && conftoken_ungetc(ch) == EOF) {
1355 if (ferror(current_file)) {
1356 conf_parserror(_("Pushback of '%c' failed: %s"),
1357 ch, strerror(ferror(current_file)));
1359 conf_parserror(_("Pushback of '%c' failed: EOF"), ch);
1364 tokenval.v.s = tkbuf;
1366 if (token_overflow) tok = CONF_UNKNOWN;
1367 else if (exp == CONF_IDENT) tok = CONF_IDENT;
1368 else tok = lookup_keyword(tokenval.v.s);
1370 else if (isdigit(ch)) { /* integer */
1373 negative_number: /* look for goto negative_number below sign is set there */
1376 int64 = int64 * 10 + (ch - '0');
1377 ch = conftoken_getc();
1378 } while (isdigit(ch));
1381 if (exp == CONF_INT) {
1383 tokenval.v.i = sign * (int)int64;
1384 } else if (exp != CONF_REAL) {
1386 tokenval.v.int64 = (gint64)sign * int64;
1388 /* automatically convert to real when expected */
1389 tokenval.v.r = (double)sign * (double)int64;
1393 /* got a real number, not an int */
1394 tokenval.v.r = sign * (double) int64;
1397 ch = conftoken_getc();
1398 while (isdigit(ch)) {
1399 int64 = int64 * 10 + (ch - '0');
1401 ch = conftoken_getc();
1403 tokenval.v.r += sign * ((double)int64) / d;
1407 if (ch != EOF && conftoken_ungetc(ch) == EOF) {
1408 if (ferror(current_file)) {
1409 conf_parserror(_("Pushback of '%c' failed: %s"),
1410 ch, strerror(ferror(current_file)));
1412 conf_parserror(_("Pushback of '%c' failed: EOF"), ch);
1416 case '"': /* string */
1421 while (inquote && ((ch = conftoken_getc()) != EOF)) {
1426 buf--; /* Consume escape in buffer */
1427 } else if (ch == '\\' && !escape) {
1437 if(buf >= &tkbuf[sizeof(tkbuf) - 1]) {
1438 if (!token_overflow) {
1439 conf_parserror(_("string too long: %.20s..."), tkbuf);
1449 * A little manuver to leave a fully unquoted, unallocated string
1452 tmps = unquote_string(tkbuf);
1453 strncpy(tkbuf, tmps, sizeof(tkbuf));
1455 tokenval.v.s = tkbuf;
1457 tok = (token_overflow) ? CONF_UNKNOWN :
1458 (exp == CONF_IDENT) ? CONF_IDENT : CONF_STRING;
1462 ch = conftoken_getc();
1465 goto negative_number;
1468 if (ch != EOF && conftoken_ungetc(ch) == EOF) {
1469 if (ferror(current_file)) {
1470 conf_parserror(_("Pushback of '%c' failed: %s"),
1471 ch, strerror(ferror(current_file)));
1473 conf_parserror(_("Pushback of '%c' failed: EOF"), ch);
1506 if (exp != CONF_ANY && tok != exp) {
1524 str = _("end of line");
1528 str = _("end of file");
1532 str = _("an integer");
1536 str = _("a real number");
1540 str = _("a quoted string");
1544 str = _("an identifier");
1548 for(kwp = keytable; kwp->keyword != NULL; kwp++) {
1549 if (exp == kwp->token)
1552 if (kwp->keyword == NULL)
1553 str = _("token not");
1558 conf_parserror(_("%s is expected"), str);
1560 if (tok == CONF_INT)
1568 unget_conftoken(void)
1570 assert(!token_pushed);
1577 conftoken_getc(void)
1579 if(current_line == NULL)
1580 return getc(current_file);
1581 if(*current_char == '\0')
1583 return(*current_char++);
1590 if(current_line == NULL)
1591 return ungetc(c, current_file);
1592 else if(current_char > current_line) {
1596 if(*current_char != c) {
1597 error(_("*current_char != c : %c %c"), *current_char, c);
1601 error(_("current_char == current_line"));
1608 * Parser Implementation
1615 gboolean missing_ok)
1617 /* Save global locations. */
1618 FILE *save_file = current_file;
1619 char *save_filename = current_filename;
1620 int save_line_num = current_line_num;
1624 keytable = client_keytab;
1625 parsetable = client_var;
1627 keytable = server_keytab;
1628 parsetable = server_var;
1630 filename = config_dir_relative(filename);
1631 current_filename = get_seen_filename(filename);
1634 if ((current_file = fopen(current_filename, "r")) == NULL) {
1636 conf_parserror(_("could not open conf file \"%s\": %s"),
1637 current_filename, strerror(errno));
1641 current_line_num = 0;
1644 /* read_confline() can invoke us recursively via "includefile" */
1645 rc = read_confline(is_client);
1648 afclose(current_file);
1652 /* Restore servers */
1653 current_line_num = save_line_num;
1654 current_file = save_file;
1655 current_filename = save_filename;
1664 current_line_num += 1;
1665 get_conftoken(CONF_ANY);
1666 handle_deprecated_keyword();
1669 case CONF_INCLUDEFILE:
1670 get_conftoken(CONF_STRING);
1671 read_conffile(tokenval.v.s, is_client, FALSE);
1676 handle_invalid_keyword(tokenval.v.s);
1684 get_conftoken(CONF_ANY);
1685 if(tok == CONF_APPLICATION_TOOL) get_application();
1686 else if(tok == CONF_PP_SCRIPT_TOOL) get_pp_script();
1687 else conf_parserror(_("APPLICATION-TOOL or SCRIPT-TOOL expected"));
1689 get_conftoken(CONF_ANY);
1690 if(tok == CONF_DUMPTYPE) get_dumptype();
1691 else if(tok == CONF_TAPETYPE) get_tapetype();
1692 else if(tok == CONF_INTERFACE) get_interface();
1693 else if(tok == CONF_APPLICATION_TOOL) get_application();
1694 else if(tok == CONF_PP_SCRIPT_TOOL) get_pp_script();
1695 else if(tok == CONF_DEVICE) get_device_config();
1696 else if(tok == CONF_CHANGER) get_changer_config();
1697 else conf_parserror(_("DUMPTYPE, INTERFACE, TAPETYPE, APPLICATION-TOOL, SCRIPT-TOOL, DEVICE, or CHANGER expected"));
1701 case CONF_NL: /* empty line */
1704 case CONF_END: /* end of file */
1707 /* if it's not a known punctuation mark, then check the parse table and use the
1708 * read_function we find there. */
1711 for(np = parsetable; np->token != CONF_UNKNOWN; np++)
1712 if(np->token == tok) break;
1714 if(np->token == CONF_UNKNOWN) {
1715 handle_invalid_keyword(tokenval.v.s);
1717 np->read_function(np, &conf_data[np->parm]);
1718 if(np->validate_function)
1719 np->validate_function(np, &conf_data[np->parm]);
1724 get_conftoken(CONF_NL);
1729 handle_deprecated_keyword(void)
1732 /* Procedure for deprecated keywords:
1733 * 1) At time of deprecation, add to warning_deprecated below.
1734 * Note the date of deprecation. The keyword will still be
1735 * parsed, and can still be used from other parts of Amanda,
1737 * 2) After two years, move the keyword (as a string) to
1738 * error_deprecated below. Remove the token (CONF_XXX) and
1739 * config parameter (CNF_XXX) from the rest of the module.
1740 * Note the date of the move.
1743 static tok_t warning_deprecated[] = {
1744 CONF_RAWTAPEDEV, /* 2007-01-23 */
1745 CONF_TAPEBUFS, /* 2007-10-15 */
1746 CONF_FILE_PAD, /* 2008-07-01 */
1750 for (dep = warning_deprecated; *dep; dep++) {
1752 conf_parswarn(_("warning: Keyword %s is deprecated."),
1759 handle_invalid_keyword(
1762 static const char * error_deprecated[] = {
1767 for (s = error_deprecated; *s != NULL; s ++) {
1768 if (strcmp(*s, token) == 0) {
1769 conf_parserror(_("error: Keyword %s is deprecated."),
1775 conf_parserror(_("configuration keyword expected"));
1779 char c = conftoken_getc();
1780 if (c == '\n' || c == -1) {
1781 conftoken_ungetc(c);
1786 g_assert_not_reached();
1796 for (iter = seen_filenames; iter; iter = iter->next) {
1798 if (istr == filename || 0 == strcmp(istr, filename))
1802 istr = stralloc(filename);
1803 seen_filenames = g_slist_prepend(seen_filenames, istr);
1809 conf_var_t *read_var,
1813 void (*copy_function)(void))
1819 get_conftoken(CONF_LBRACE);
1820 get_conftoken(CONF_NL);
1825 current_line_num += 1;
1826 get_conftoken(CONF_ANY);
1831 case CONF_NL: /* empty line */
1833 case CONF_END: /* end of file */
1837 /* inherit from a "parent" */
1843 conf_parserror(_("ident not expected"));
1847 for(np = read_var; np->token != CONF_UNKNOWN; np++)
1848 if(np->token == tok) break;
1850 if(np->token == CONF_UNKNOWN)
1851 conf_parserror("%s", errormsg);
1853 np->read_function(np, &valarray[np->parm]);
1854 if(np->validate_function)
1855 np->validate_function(np, &valarray[np->parm]);
1859 if(tok != CONF_NL && tok != CONF_END && tok != CONF_RBRACE)
1860 get_conftoken(CONF_NL);
1868 int save_overwrites;
1870 save_overwrites = allow_overwrites;
1871 allow_overwrites = 1;
1873 init_holdingdisk_defaults();
1875 get_conftoken(CONF_IDENT);
1876 hdcur.name = stralloc(tokenval.v.s);
1877 hdcur.seen.filename = current_filename;
1878 hdcur.seen.linenum = current_line_num;
1880 read_block(holding_var, hdcur.value,
1881 _("holding disk parameter expected"), 1, NULL);
1882 get_conftoken(CONF_NL);
1885 allow_overwrites = save_overwrites;
1889 init_holdingdisk_defaults(
1892 conf_init_str(&hdcur.value[HOLDING_COMMENT] , "");
1893 conf_init_str(&hdcur.value[HOLDING_DISKDIR] , "");
1894 conf_init_int64(&hdcur.value[HOLDING_DISKSIZE] , (gint64)0);
1895 /* 1 Gb = 1M counted in 1Kb blocks */
1896 conf_init_int64(&hdcur.value[HOLDING_CHUNKSIZE], (gint64)1024*1024);
1905 hp = alloc(sizeof(holdingdisk_t));
1907 hp->next = holdinglist;
1913 * This function is called both from this module and from diskfile.c. Modify
1922 int save_overwrites;
1923 FILE *saved_conf = NULL;
1924 char *saved_fname = NULL;
1927 saved_conf = current_file;
1928 current_file = from;
1932 saved_fname = current_filename;
1933 current_filename = get_seen_filename(fname);
1937 current_line_num = *linenum;
1939 save_overwrites = allow_overwrites;
1940 allow_overwrites = 1;
1942 init_dumptype_defaults();
1946 get_conftoken(CONF_IDENT);
1947 dpcur.name = stralloc(tokenval.v.s);
1949 dpcur.seen.filename = current_filename;
1950 dpcur.seen.linenum = current_line_num;
1952 read_block(dumptype_var, dpcur.value,
1953 _("dumptype parameter expected"),
1954 (name == NULL), copy_dumptype);
1956 if(!name) /* !name => reading disklist, not conffile */
1957 get_conftoken(CONF_NL);
1959 /* XXX - there was a stupidity check in here for skip-incr and
1960 ** skip-full. This check should probably be somewhere else. */
1964 allow_overwrites = save_overwrites;
1967 *linenum = current_line_num;
1970 current_filename = saved_fname;
1973 current_file = saved_conf;
1975 return lookup_dumptype(dpcur.name);
1981 read_dumptype(NULL, NULL, NULL, NULL);
1985 init_dumptype_defaults(void)
1988 conf_init_str (&dpcur.value[DUMPTYPE_COMMENT] , "");
1989 conf_init_str (&dpcur.value[DUMPTYPE_PROGRAM] , "DUMP");
1990 conf_init_str (&dpcur.value[DUMPTYPE_SRVCOMPPROG] , "");
1991 conf_init_str (&dpcur.value[DUMPTYPE_CLNTCOMPPROG] , "");
1992 conf_init_str (&dpcur.value[DUMPTYPE_SRV_ENCRYPT] , "");
1993 conf_init_str (&dpcur.value[DUMPTYPE_CLNT_ENCRYPT] , "");
1994 conf_init_str (&dpcur.value[DUMPTYPE_AMANDAD_PATH] , "X");
1995 conf_init_str (&dpcur.value[DUMPTYPE_CLIENT_USERNAME] , "X");
1996 conf_init_str (&dpcur.value[DUMPTYPE_SSH_KEYS] , "X");
1997 conf_init_str (&dpcur.value[DUMPTYPE_SECURITY_DRIVER] , "BSD");
1998 conf_init_exinclude(&dpcur.value[DUMPTYPE_EXCLUDE]);
1999 conf_init_exinclude(&dpcur.value[DUMPTYPE_INCLUDE]);
2000 conf_init_priority (&dpcur.value[DUMPTYPE_PRIORITY] , 1);
2001 conf_init_int (&dpcur.value[DUMPTYPE_DUMPCYCLE] , conf_data[CNF_DUMPCYCLE].v.i);
2002 conf_init_int (&dpcur.value[DUMPTYPE_MAXDUMPS] , conf_data[CNF_MAXDUMPS].v.i);
2003 conf_init_int (&dpcur.value[DUMPTYPE_MAXPROMOTEDAY] , 10000);
2004 conf_init_int (&dpcur.value[DUMPTYPE_BUMPPERCENT] , conf_data[CNF_BUMPPERCENT].v.i);
2005 conf_init_int64 (&dpcur.value[DUMPTYPE_BUMPSIZE] , conf_data[CNF_BUMPSIZE].v.int64);
2006 conf_init_int (&dpcur.value[DUMPTYPE_BUMPDAYS] , conf_data[CNF_BUMPDAYS].v.i);
2007 conf_init_real (&dpcur.value[DUMPTYPE_BUMPMULT] , conf_data[CNF_BUMPMULT].v.r);
2008 conf_init_time (&dpcur.value[DUMPTYPE_STARTTIME] , (time_t)0);
2009 conf_init_strategy (&dpcur.value[DUMPTYPE_STRATEGY] , DS_STANDARD);
2010 conf_init_estimate (&dpcur.value[DUMPTYPE_ESTIMATE] , ES_CLIENT);
2011 conf_init_compress (&dpcur.value[DUMPTYPE_COMPRESS] , COMP_FAST);
2012 conf_init_encrypt (&dpcur.value[DUMPTYPE_ENCRYPT] , ENCRYPT_NONE);
2013 conf_init_str (&dpcur.value[DUMPTYPE_SRV_DECRYPT_OPT] , "-d");
2014 conf_init_str (&dpcur.value[DUMPTYPE_CLNT_DECRYPT_OPT] , "-d");
2015 conf_init_rate (&dpcur.value[DUMPTYPE_COMPRATE] , 0.50, 0.50);
2016 conf_init_int64 (&dpcur.value[DUMPTYPE_TAPE_SPLITSIZE] , (gint64)0);
2017 conf_init_int64 (&dpcur.value[DUMPTYPE_FALLBACK_SPLITSIZE], (gint64)10 * 1024);
2018 conf_init_str (&dpcur.value[DUMPTYPE_SPLIT_DISKBUFFER] , NULL);
2019 conf_init_bool (&dpcur.value[DUMPTYPE_RECORD] , 1);
2020 conf_init_bool (&dpcur.value[DUMPTYPE_SKIP_INCR] , 0);
2021 conf_init_bool (&dpcur.value[DUMPTYPE_SKIP_FULL] , 0);
2022 conf_init_holding (&dpcur.value[DUMPTYPE_HOLDINGDISK] , HOLD_AUTO);
2023 conf_init_bool (&dpcur.value[DUMPTYPE_KENCRYPT] , 0);
2024 conf_init_bool (&dpcur.value[DUMPTYPE_IGNORE] , 0);
2025 conf_init_bool (&dpcur.value[DUMPTYPE_INDEX] , 1);
2026 conf_init_application(&dpcur.value[DUMPTYPE_APPLICATION]);
2027 conf_init_pp_scriptlist(&dpcur.value[DUMPTYPE_PP_SCRIPTLIST]);
2028 conf_init_proplist(&dpcur.value[DUMPTYPE_PROPERTY]);
2034 dumptype_t *dp, *dp1;;
2036 dp = lookup_dumptype(dpcur.name);
2038 if(dp != (dumptype_t *)0) {
2039 if (dp->seen.linenum == -1) {
2040 conf_parserror(_("dumptype %s is defined by default and cannot be redefined"), dp->name);
2042 conf_parserror(_("dumptype %s already defined at %s:%d"), dp->name,
2043 dp->seen.filename, dp->seen.linenum);
2048 dp = alloc(sizeof(dumptype_t));
2051 /* add at end of list */
2056 while (dp1->next != NULL) {
2069 dt = lookup_dumptype(tokenval.v.s);
2072 conf_parserror(_("dumptype parameter expected"));
2076 for(i=0; i < DUMPTYPE_DUMPTYPE; i++) {
2077 if(dt->value[i].seen.linenum) {
2078 free_val_t(&dpcur.value[i]);
2079 copy_val_t(&dpcur.value[i], &dt->value[i]);
2087 int save_overwrites;
2089 save_overwrites = allow_overwrites;
2090 allow_overwrites = 1;
2092 init_tapetype_defaults();
2094 get_conftoken(CONF_IDENT);
2095 tpcur.name = stralloc(tokenval.v.s);
2096 tpcur.seen.filename = current_filename;
2097 tpcur.seen.linenum = current_line_num;
2099 read_block(tapetype_var, tpcur.value,
2100 _("tapetype parameter expected"), 1, copy_tapetype);
2101 get_conftoken(CONF_NL);
2103 if (tapetype_get_readblocksize(&tpcur) <
2104 tapetype_get_blocksize(&tpcur)) {
2105 conf_init_size(&tpcur.value[TAPETYPE_READBLOCKSIZE],
2106 tapetype_get_blocksize(&tpcur));
2110 allow_overwrites = save_overwrites;
2114 init_tapetype_defaults(void)
2116 conf_init_str(&tpcur.value[TAPETYPE_COMMENT] , "");
2117 conf_init_str(&tpcur.value[TAPETYPE_LBL_TEMPL] , "");
2118 conf_init_size (&tpcur.value[TAPETYPE_BLOCKSIZE] , DISK_BLOCK_KB);
2119 conf_init_size (&tpcur.value[TAPETYPE_READBLOCKSIZE], DISK_BLOCK_KB);
2120 conf_init_int64 (&tpcur.value[TAPETYPE_LENGTH] , ((gint64)2000));
2121 conf_init_int64 (&tpcur.value[TAPETYPE_FILEMARK] , (gint64)1);
2122 conf_init_int (&tpcur.value[TAPETYPE_SPEED] , 200);
2123 conf_init_bool (&tpcur.value[TAPETYPE_FILE_PAD] , 1);
2129 tapetype_t *tp, *tp1;
2131 tp = lookup_tapetype(tpcur.name);
2133 if(tp != (tapetype_t *)0) {
2135 conf_parserror(_("tapetype %s already defined at %s:%d"),
2136 tp->name, tp->seen.filename, tp->seen.linenum);
2140 tp = alloc(sizeof(tapetype_t));
2142 /* add at end of list */
2147 while (tp1->next != NULL) {
2160 tp = lookup_tapetype(tokenval.v.s);
2163 conf_parserror(_("tape type parameter expected"));
2167 for(i=0; i < TAPETYPE_TAPETYPE; i++) {
2168 if(tp->value[i].seen.linenum) {
2169 free_val_t(&tpcur.value[i]);
2170 copy_val_t(&tpcur.value[i], &tp->value[i]);
2178 int save_overwrites;
2180 save_overwrites = allow_overwrites;
2181 allow_overwrites = 1;
2183 init_interface_defaults();
2185 get_conftoken(CONF_IDENT);
2186 ifcur.name = stralloc(tokenval.v.s);
2187 ifcur.seen.filename = current_filename;
2188 ifcur.seen.linenum = current_line_num;
2190 read_block(interface_var, ifcur.value,
2191 _("interface parameter expected"), 1, copy_interface);
2192 get_conftoken(CONF_NL);
2196 allow_overwrites = save_overwrites;
2202 init_interface_defaults(void)
2204 conf_init_str(&ifcur.value[INTER_COMMENT] , "");
2205 conf_init_int (&ifcur.value[INTER_MAXUSAGE], 8000);
2209 save_interface(void)
2211 interface_t *ip, *ip1;
2213 ip = lookup_interface(ifcur.name);
2215 if(ip != (interface_t *)0) {
2216 conf_parserror(_("interface %s already defined at %s:%d"),
2217 ip->name, ip->seen.filename, ip->seen.linenum);
2221 ip = alloc(sizeof(interface_t));
2223 /* add at end of list */
2224 if(!interface_list) {
2225 interface_list = ip;
2227 ip1 = interface_list;
2228 while (ip1->next != NULL) {
2236 copy_interface(void)
2241 ip = lookup_interface(tokenval.v.s);
2244 conf_parserror(_("interface parameter expected"));
2248 for(i=0; i < INTER_INTER; i++) {
2249 if(ip->value[i].seen.linenum) {
2250 free_val_t(&ifcur.value[i]);
2251 copy_val_t(&ifcur.value[i], &ip->value[i]);
2264 int save_overwrites;
2265 FILE *saved_conf = NULL;
2266 char *saved_fname = NULL;
2269 saved_conf = current_file;
2270 current_file = from;
2274 saved_fname = current_filename;
2275 current_filename = get_seen_filename(fname);
2279 current_line_num = *linenum;
2281 save_overwrites = allow_overwrites;
2282 allow_overwrites = 1;
2284 init_application_defaults();
2288 get_conftoken(CONF_IDENT);
2289 apcur.name = stralloc(tokenval.v.s);
2291 apcur.seen.filename = current_filename;
2292 apcur.seen.linenum = current_line_num;
2294 read_block(application_var, apcur.value,
2295 _("application-tool parameter expected"),
2296 (name == NULL), *copy_application);
2298 get_conftoken(CONF_NL);
2300 if (!application_get_plugin(&apcur) ||
2301 strlen(application_get_plugin(&apcur)) == 0) {
2302 conf_parserror("plugin not set for application");
2307 allow_overwrites = save_overwrites;
2310 *linenum = current_line_num;
2313 current_filename = saved_fname;
2316 current_file = saved_conf;
2318 return lookup_application(apcur.name);
2325 read_application(NULL, NULL, NULL, NULL);
2329 init_application_defaults(
2333 conf_init_str(&apcur.value[APPLICATION_COMMENT] , "");
2334 conf_init_str(&apcur.value[APPLICATION_PLUGIN] , "");
2335 conf_init_proplist(&apcur.value[APPLICATION_PROPERTY]);
2342 application_t *ap, *ap1;
2344 ap = lookup_application(apcur.name);
2346 if(ap != (application_t *)0) {
2347 conf_parserror(_("application-tool %s already defined at %s:%d"),
2348 ap->name, ap->seen.filename, ap->seen.linenum);
2352 ap = alloc(sizeof(application_t));
2355 /* add at end of list */
2356 if (!application_list)
2357 application_list = ap;
2359 ap1 = application_list;
2360 while (ap1->next != NULL) {
2368 copy_application(void)
2373 ap = lookup_application(tokenval.v.s);
2376 conf_parserror(_("application parameter expected"));
2380 for(i=0; i < APPLICATION_APPLICATION; i++) {
2381 if(ap->value[i].seen.linenum) {
2382 free_val_t(&apcur.value[i]);
2383 copy_val_t(&apcur.value[i], &ap->value[i]);
2395 int save_overwrites;
2396 FILE *saved_conf = NULL;
2397 char *saved_fname = NULL;
2400 saved_conf = current_file;
2401 current_file = from;
2405 saved_fname = current_filename;
2406 current_filename = get_seen_filename(fname);
2410 current_line_num = *linenum;
2412 save_overwrites = allow_overwrites;
2413 allow_overwrites = 1;
2415 init_pp_script_defaults();
2419 get_conftoken(CONF_IDENT);
2420 pscur.name = stralloc(tokenval.v.s);
2422 pscur.seen.filename = current_filename;
2423 pscur.seen.linenum = current_line_num;
2425 read_block(pp_script_var, pscur.value,
2426 _("script-tool parameter expected"),
2427 (name == NULL), *copy_pp_script);
2429 get_conftoken(CONF_NL);
2431 if (!pp_script_get_plugin(&pscur) ||
2432 strlen(pp_script_get_plugin(&pscur)) == 0) {
2433 conf_parserror("plugin not set for script");
2438 allow_overwrites = save_overwrites;
2441 *linenum = current_line_num;
2444 current_filename = saved_fname;
2447 current_file = saved_conf;
2449 return lookup_pp_script(pscur.name);
2456 read_pp_script(NULL, NULL, NULL, NULL);
2460 init_pp_script_defaults(
2464 conf_init_str(&pscur.value[PP_SCRIPT_COMMENT] , "");
2465 conf_init_str(&pscur.value[PP_SCRIPT_PLUGIN] , "");
2466 conf_init_proplist(&pscur.value[PP_SCRIPT_PROPERTY]);
2467 conf_init_execute_on(&pscur.value[PP_SCRIPT_EXECUTE_ON], 0);
2468 conf_init_execute_where(&pscur.value[PP_SCRIPT_EXECUTE_WHERE], ES_CLIENT);
2475 pp_script_t *ps, *ps1;
2477 ps = lookup_pp_script(pscur.name);
2479 if(ps != (pp_script_t *)0) {
2480 conf_parserror(_("script-tool %s already defined at %s:%d"),
2481 ps->name, ps->seen.filename, ps->seen.linenum);
2485 ps = alloc(sizeof(pp_script_t));
2488 /* add at end of list */
2489 if (!pp_script_list)
2490 pp_script_list = ps;
2492 ps1 = pp_script_list;
2493 while (ps1->next != NULL) {
2501 copy_pp_script(void)
2506 ps = lookup_pp_script(tokenval.v.s);
2509 conf_parserror(_("script parameter expected"));
2513 for(i=0; i < PP_SCRIPT_PP_SCRIPT; i++) {
2514 if(ps->value[i].seen.linenum) {
2515 free_val_t(&pscur.value[i]);
2516 copy_val_t(&pscur.value[i], &ps->value[i]);
2528 int save_overwrites;
2529 FILE *saved_conf = NULL;
2530 char *saved_fname = NULL;
2533 saved_conf = current_file;
2534 current_file = from;
2538 saved_fname = current_filename;
2539 current_filename = get_seen_filename(fname);
2543 current_line_num = *linenum;
2545 save_overwrites = allow_overwrites;
2546 allow_overwrites = 1;
2548 init_device_config_defaults();
2552 get_conftoken(CONF_IDENT);
2553 dccur.name = stralloc(tokenval.v.s);
2555 dccur.seen.filename = current_filename;
2556 dccur.seen.linenum = current_line_num;
2558 read_block(device_config_var, dccur.value,
2559 _("device parameter expected"),
2560 (name == NULL), *copy_device_config);
2562 get_conftoken(CONF_NL);
2564 save_device_config();
2566 allow_overwrites = save_overwrites;
2569 *linenum = current_line_num;
2572 current_filename = saved_fname;
2575 current_file = saved_conf;
2577 return lookup_device_config(dccur.name);
2584 read_device_config(NULL, NULL, NULL, NULL);
2588 init_device_config_defaults(
2592 conf_init_str(&dccur.value[DEVICE_CONFIG_COMMENT] , "");
2593 conf_init_str(&dccur.value[DEVICE_CONFIG_TAPEDEV] , "");
2594 conf_init_proplist(&dccur.value[DEVICE_CONFIG_DEVICE_PROPERTY]);
2601 device_config_t *dc, *dc1;
2603 dc = lookup_device_config(dccur.name);
2605 if(dc != (device_config_t *)0) {
2606 conf_parserror(_("device %s already defined at %s:%d"),
2607 dc->name, dc->seen.filename, dc->seen.linenum);
2611 dc = alloc(sizeof(device_config_t));
2614 /* add at end of list */
2615 if (!device_config_list)
2616 device_config_list = dc;
2618 dc1 = device_config_list;
2619 while (dc1->next != NULL) {
2627 copy_device_config(void)
2629 device_config_t *dc;
2632 dc = lookup_device_config(tokenval.v.s);
2635 conf_parserror(_("device parameter expected"));
2639 for(i=0; i < DEVICE_CONFIG_DEVICE_CONFIG; i++) {
2640 if(dc->value[i].seen.linenum) {
2641 free_val_t(&dccur.value[i]);
2642 copy_val_t(&dccur.value[i], &dc->value[i]);
2648 read_changer_config(
2654 int save_overwrites;
2655 FILE *saved_conf = NULL;
2656 char *saved_fname = NULL;
2659 saved_conf = current_file;
2660 current_file = from;
2664 saved_fname = current_filename;
2665 current_filename = fname;
2669 current_line_num = *linenum;
2671 save_overwrites = allow_overwrites;
2672 allow_overwrites = 1;
2674 init_changer_config_defaults();
2678 get_conftoken(CONF_IDENT);
2679 cccur.name = stralloc(tokenval.v.s);
2681 cccur.seen = current_line_num;
2683 read_block(changer_config_var, cccur.value,
2684 _("changer parameter expected"),
2685 (name == NULL), *copy_changer_config);
2687 get_conftoken(CONF_NL);
2689 save_changer_config();
2691 allow_overwrites = save_overwrites;
2694 *linenum = current_line_num;
2697 current_filename = saved_fname;
2700 current_file = saved_conf;
2702 return lookup_changer_config(cccur.name);
2709 read_changer_config(NULL, NULL, NULL, NULL);
2713 init_changer_config_defaults(
2717 conf_init_str(&cccur.value[CHANGER_CONFIG_COMMENT] , "");
2718 conf_init_str(&cccur.value[CHANGER_CONFIG_TAPEDEV] , "");
2719 conf_init_str(&cccur.value[CHANGER_CONFIG_TPCHANGER] , "");
2720 conf_init_str(&cccur.value[CHANGER_CONFIG_CHANGERDEV] , "");
2721 conf_init_str(&cccur.value[CHANGER_CONFIG_CHANGERFILE] , "");
2725 save_changer_config(
2728 changer_config_t *dc, *dc1;
2730 dc = lookup_changer_config(cccur.name);
2732 if(dc != (changer_config_t *)0) {
2733 conf_parserror(_("changer %s already defined on line %d"),
2734 dc->name, dc->seen);
2738 dc = alloc(sizeof(changer_config_t));
2741 /* add at end of list */
2742 if (!changer_config_list)
2743 changer_config_list = dc;
2745 dc1 = changer_config_list;
2746 while (dc1->next != NULL) {
2754 copy_changer_config(void)
2756 changer_config_t *dc;
2759 dc = lookup_changer_config(tokenval.v.s);
2762 conf_parserror(_("changer parameter expected"));
2766 for(i=0; i < CHANGER_CONFIG_CHANGER_CONFIG; i++) {
2767 if(dc->value[i].seen.linenum) {
2768 free_val_t(&cccur.value[i]);
2769 copy_val_t(&cccur.value[i], &dc->value[i]);
2774 /* Read functions */
2778 conf_var_t *np G_GNUC_UNUSED,
2782 val_t__int(val) = get_int();
2787 conf_var_t *np G_GNUC_UNUSED,
2791 val_t__int64(val) = get_int64();
2796 conf_var_t *np G_GNUC_UNUSED,
2800 get_conftoken(CONF_REAL);
2801 val_t__real(val) = tokenval.v.r;
2806 conf_var_t *np G_GNUC_UNUSED,
2810 get_conftoken(CONF_STRING);
2811 val->v.s = newstralloc(val->v.s, tokenval.v.s);
2816 conf_var_t *np G_GNUC_UNUSED,
2820 get_conftoken(CONF_IDENT);
2821 val->v.s = newstralloc(val->v.s, tokenval.v.s);
2826 conf_var_t *np G_GNUC_UNUSED,
2830 val_t__time(val) = get_time();
2835 conf_var_t *np G_GNUC_UNUSED,
2839 val_t__size(val) = get_size();
2844 conf_var_t *np G_GNUC_UNUSED,
2848 val_t__boolean(val) = get_bool();
2853 conf_var_t *np G_GNUC_UNUSED,
2856 int serv, clie, none, fast, best, custom;
2862 serv = clie = none = fast = best = custom = 0;
2866 get_conftoken(CONF_ANY);
2868 case CONF_NONE: none = 1; break;
2869 case CONF_FAST: fast = 1; break;
2870 case CONF_BEST: best = 1; break;
2871 case CONF_CLIENT: clie = 1; break;
2872 case CONF_SERVER: serv = 1; break;
2873 case CONF_CUSTOM: custom=1; break;
2874 case CONF_NL: done = 1; break;
2875 case CONF_END: done = 1; break;
2878 serv = clie = 1; /* force an error */
2882 if(serv + clie == 0) clie = 1; /* default to client */
2883 if(none + fast + best + custom == 0) fast = 1; /* default to fast */
2888 if(none && !fast && !best && !custom) comp = COMP_NONE;
2889 if(!none && fast && !best && !custom) comp = COMP_FAST;
2890 if(!none && !fast && best && !custom) comp = COMP_BEST;
2891 if(!none && !fast && !best && custom) comp = COMP_CUST;
2895 if(none && !fast && !best && !custom) comp = COMP_NONE;
2896 if(!none && fast && !best && !custom) comp = COMP_SERVER_FAST;
2897 if(!none && !fast && best && !custom) comp = COMP_SERVER_BEST;
2898 if(!none && !fast && !best && custom) comp = COMP_SERVER_CUST;
2901 if((int)comp == -1) {
2902 conf_parserror(_("NONE, CLIENT FAST, CLIENT BEST, CLIENT CUSTOM, SERVER FAST, SERVER BEST or SERVER CUSTOM expected"));
2906 val_t__compress(val) = (int)comp;
2911 conf_var_t *np G_GNUC_UNUSED,
2918 get_conftoken(CONF_ANY);
2921 encrypt = ENCRYPT_NONE;
2925 encrypt = ENCRYPT_CUST;
2929 encrypt = ENCRYPT_SERV_CUST;
2933 conf_parserror(_("NONE, CLIENT or SERVER expected"));
2934 encrypt = ENCRYPT_NONE;
2938 val_t__encrypt(val) = (int)encrypt;
2943 conf_var_t *np G_GNUC_UNUSED,
2946 dump_holdingdisk_t holding;
2950 get_conftoken(CONF_ANY);
2953 holding = HOLD_NEVER;
2957 holding = HOLD_AUTO;
2961 holding = HOLD_REQUIRED;
2964 default: /* can be a BOOLEAN */
2966 holding = (dump_holdingdisk_t)get_bool();
2968 holding = HOLD_NEVER;
2969 else if (holding == 1 || holding == 2)
2970 holding = HOLD_AUTO;
2972 conf_parserror(_("NEVER, AUTO or REQUIRED expected"));
2976 val_t__holding(val) = (int)holding;
2981 conf_var_t *np G_GNUC_UNUSED,
2988 get_conftoken(CONF_ANY);
2997 estime = ES_CALCSIZE;
3000 conf_parserror(_("CLIENT, SERVER or CALCSIZE expected"));
3003 val_t__estimate(val) = estime;
3008 conf_var_t *np G_GNUC_UNUSED,
3015 get_conftoken(CONF_ANY);
3021 strat = DS_STANDARD;
3033 strat = DS_INCRONLY;
3036 conf_parserror(_("dump strategy expected"));
3037 strat = DS_STANDARD;
3039 val_t__strategy(val) = strat;
3044 conf_var_t *np G_GNUC_UNUSED,
3049 get_conftoken(CONF_ANY);
3051 case CONF_FIRST: val_t__taperalgo(val) = ALGO_FIRST; break;
3052 case CONF_FIRSTFIT: val_t__taperalgo(val) = ALGO_FIRSTFIT; break;
3053 case CONF_LARGEST: val_t__taperalgo(val) = ALGO_LARGEST; break;
3054 case CONF_LARGESTFIT: val_t__taperalgo(val) = ALGO_LARGESTFIT; break;
3055 case CONF_SMALLEST: val_t__taperalgo(val) = ALGO_SMALLEST; break;
3056 case CONF_LAST: val_t__taperalgo(val) = ALGO_LAST; break;
3058 conf_parserror(_("FIRST, FIRSTFIT, LARGEST, LARGESTFIT, SMALLEST or LAST expected"));
3063 read_send_amreport_on(
3064 conf_var_t *np G_GNUC_UNUSED,
3069 get_conftoken(CONF_ANY);
3071 case CONF_ALL: val_t__send_amreport(val) = SEND_AMREPORT_ALL; break;
3072 case CONF_STRANGE: val_t__send_amreport(val) = SEND_AMREPORT_STRANGE; break;
3073 case CONF_ERROR: val_t__send_amreport(val) = SEND_AMREPORT_ERROR; break;
3074 case CONF_NEVER: val_t__send_amreport(val) = SEND_AMREPORT_NEVER; break;
3076 conf_parserror(_("ALL, STRANGE, ERROR or NEVER expected"));
3082 conf_var_t *np G_GNUC_UNUSED,
3089 get_conftoken(CONF_ANY);
3091 case CONF_LOW: pri = 0; break;
3092 case CONF_MEDIUM: pri = 1; break;
3093 case CONF_HIGH: pri = 2; break;
3094 case CONF_INT: pri = tokenval.v.i; break;
3096 conf_parserror(_("LOW, MEDIUM, HIGH or integer expected"));
3099 val_t__priority(val) = pri;
3104 conf_var_t *np G_GNUC_UNUSED,
3107 get_conftoken(CONF_REAL);
3108 val_t__rate(val)[0] = tokenval.v.r;
3109 val_t__rate(val)[1] = tokenval.v.r;
3110 val->seen = tokenval.seen;
3111 if(tokenval.v.r < 0) {
3112 conf_parserror(_("full compression rate must be >= 0"));
3115 get_conftoken(CONF_ANY);
3130 get_conftoken(CONF_REAL);
3131 val_t__rate(val)[1] = tokenval.v.r;
3132 if(tokenval.v.r < 0) {
3133 conf_parserror(_("incremental compression rate must be >= 0"));
3139 conf_var_t *np G_GNUC_UNUSED,
3142 int file, got_one = 0;
3146 get_conftoken(CONF_ANY);
3147 if(tok == CONF_LIST) {
3149 get_conftoken(CONF_ANY);
3150 exclude = val_t__exinclude(val).sl_list;
3154 if(tok == CONF_EFILE) get_conftoken(CONF_ANY);
3155 exclude = val_t__exinclude(val).sl_file;
3159 if(tok == CONF_OPTIONAL) {
3160 get_conftoken(CONF_ANY);
3164 if(tok == CONF_APPEND) {
3165 get_conftoken(CONF_ANY);
3172 while(tok == CONF_STRING) {
3173 exclude = append_sl(exclude, tokenval.v.s);
3175 get_conftoken(CONF_ANY);
3179 if(got_one == 0) { free_sl(exclude); exclude = NULL; }
3182 val_t__exinclude(val).sl_list = exclude;
3184 val_t__exinclude(val).sl_file = exclude;
3185 val_t__exinclude(val).optional = optional;
3190 conf_var_t *np G_GNUC_UNUSED,
3193 get_conftoken(CONF_INT);
3194 val_t__intrange(val)[0] = tokenval.v.i;
3195 val_t__intrange(val)[1] = tokenval.v.i;
3196 val->seen = tokenval.seen;
3198 get_conftoken(CONF_ANY);
3213 get_conftoken(CONF_INT);
3214 val_t__intrange(val)[1] = tokenval.v.i;
3219 conf_var_t *np G_GNUC_UNUSED,
3223 property_t *property = malloc(sizeof(property_t));
3224 property_t *old_property;
3225 property->append = 0;
3226 property->priority = 0;
3227 property->values = NULL;
3229 get_conftoken(CONF_ANY);
3230 if (tok == CONF_PRIORITY) {
3231 property->priority = 1;
3232 get_conftoken(CONF_ANY);
3234 if (tok == CONF_APPEND) {
3235 property->append = 1;
3236 get_conftoken(CONF_ANY);
3238 if (tok != CONF_STRING) {
3239 conf_parserror(_("key expected"));
3242 key = strdup(tokenval.v.s);
3244 get_conftoken(CONF_ANY);
3245 if (tok == CONF_NL || tok == CONF_END) {
3246 g_hash_table_remove(val->v.proplist, key);
3250 if (tok != CONF_STRING) {
3251 conf_parserror(_("value expected"));
3255 if(val->seen.linenum == 0) {
3256 val->seen.filename = current_filename;
3257 val->seen.linenum = current_line_num;
3260 old_property = g_hash_table_lookup(val->v.proplist, key);
3261 if (property->append) {
3263 if (old_property->priority)
3264 property->priority = 1;
3265 property->values = old_property->values;
3268 property->values = g_hash_table_lookup(val->v.proplist, key);
3270 g_slist_free(old_property->values);
3271 amfree(old_property);
3273 property->values = NULL;
3275 while(tok == CONF_STRING) {
3276 property->values = g_slist_append(property->values,
3277 strdup(tokenval.v.s));
3278 get_conftoken(CONF_ANY);
3281 g_hash_table_insert(val->v.proplist, key, property);
3287 conf_var_t *np G_GNUC_UNUSED,
3291 get_conftoken(CONF_ANY);
3292 if (tok == CONF_LBRACE) {
3293 val->v.application = read_application(vstralloc("custom(DUMPTYPE:",
3294 dpcur.name, ")", ".",
3295 anonymous_value(),NULL),
3298 } else if (tok == CONF_STRING) {
3299 val->v.application = lookup_application(tokenval.v.s);
3300 if (val->v.application == NULL) {
3301 conf_parserror(_("Unknown application named: %s"), tokenval.v.s);
3305 conf_parserror(_("application name expected: %d %d"), tok, CONF_STRING);
3313 conf_var_t *np G_GNUC_UNUSED,
3316 pp_script_t *pp_script;
3317 get_conftoken(CONF_ANY);
3318 if (tok == CONF_LBRACE) {
3319 pp_script = read_pp_script(vstralloc("custom(DUMPTYPE:", dpcur.name,
3320 ")", ".", anonymous_value(),NULL),
3322 } else if (tok == CONF_STRING) {
3323 pp_script = lookup_pp_script(tokenval.v.s);
3324 if (pp_script == NULL) {
3325 conf_parserror(_("Unknown pp_script named: %s"), tokenval.v.s);
3329 conf_parserror(_("pp_script name expected: %d %d"), tok, CONF_STRING);
3332 val->v.pp_scriptlist = g_slist_append(val->v.pp_scriptlist, pp_script);
3337 conf_var_t *np G_GNUC_UNUSED,
3342 get_conftoken(CONF_ANY);
3346 case CONF_PRE_DLE_AMCHECK: val->v.i |= EXECUTE_ON_PRE_DLE_AMCHECK; break;
3347 case CONF_PRE_HOST_AMCHECK: val->v.i |= EXECUTE_ON_PRE_HOST_AMCHECK; break;
3348 case CONF_POST_DLE_AMCHECK: val->v.i |= EXECUTE_ON_POST_DLE_AMCHECK; break;
3349 case CONF_POST_HOST_AMCHECK: val->v.i |= EXECUTE_ON_POST_HOST_AMCHECK; break;
3350 case CONF_PRE_DLE_ESTIMATE: val->v.i |= EXECUTE_ON_PRE_DLE_ESTIMATE; break;
3351 case CONF_PRE_HOST_ESTIMATE: val->v.i |= EXECUTE_ON_PRE_HOST_ESTIMATE; break;
3352 case CONF_POST_DLE_ESTIMATE: val->v.i |= EXECUTE_ON_POST_DLE_ESTIMATE; break;
3353 case CONF_POST_HOST_ESTIMATE: val->v.i |= EXECUTE_ON_POST_HOST_ESTIMATE; break;
3354 case CONF_PRE_DLE_BACKUP: val->v.i |= EXECUTE_ON_PRE_DLE_BACKUP; break;
3355 case CONF_PRE_HOST_BACKUP: val->v.i |= EXECUTE_ON_PRE_HOST_BACKUP; break;
3356 case CONF_POST_DLE_BACKUP: val->v.i |= EXECUTE_ON_POST_DLE_BACKUP; break;
3357 case CONF_POST_HOST_BACKUP: val->v.i |= EXECUTE_ON_POST_HOST_BACKUP; break;
3358 case CONF_PRE_RECOVER: val->v.i |= EXECUTE_ON_PRE_RECOVER; break;
3359 case CONF_POST_RECOVER: val->v.i |= EXECUTE_ON_POST_RECOVER; break;
3360 case CONF_PRE_LEVEL_RECOVER: val->v.i |= EXECUTE_ON_PRE_LEVEL_RECOVER; break;
3361 case CONF_POST_LEVEL_RECOVER: val->v.i |= EXECUTE_ON_POST_LEVEL_RECOVER; break;
3362 case CONF_INTER_LEVEL_RECOVER: val->v.i |= EXECUTE_ON_INTER_LEVEL_RECOVER; break;
3364 conf_parserror(_("Execute_on expected"));
3366 get_conftoken(CONF_ANY);
3367 if (tok != CONF_COMMA) {
3371 get_conftoken(CONF_ANY);
3377 conf_var_t *np G_GNUC_UNUSED,
3382 get_conftoken(CONF_ANY);
3384 case CONF_CLIENT: val->v.i = ES_CLIENT; break;
3385 case CONF_SERVER: val->v.i = ES_SERVER; break;
3387 conf_parserror(_("CLIENT or SERVER expected"));
3391 /* get_* functions */
3393 /* these functions use precompiler conditionals to skip useless size checks
3394 * when casting from one type to another. SIZEOF_GINT64 is pretty simple to
3395 * calculate; the others are calculated by configure. */
3397 #define SIZEOF_GINT64 8
3404 get_conftoken(CONF_ANY);
3407 #if SIZEOF_TIME_T < SIZEOF_INT
3408 if ((gint64)tokenval.v.i >= (gint64)TIME_MAX)
3409 conf_parserror(_("value too large"));
3411 hhmm = (time_t)tokenval.v.i;
3415 #if SIZEOF_TIME_T < SIZEOF_SSIZE_T
3416 if ((gint64)tokenval.v.size >= (gint64)TIME_MAX)
3417 conf_parserror(_("value too large"));
3419 hhmm = (time_t)tokenval.v.size;
3423 #if SIZEOF_TIME_T < SIZEOF_GINT64
3424 if ((gint64)tokenval.v.int64 >= (gint64)TIME_MAX)
3425 conf_parserror(_("value too large"));
3427 hhmm = (time_t)tokenval.v.int64;
3430 case CONF_AMINFINITY:
3435 conf_parserror(_("a time is expected"));
3449 keytable = numb_keytable;
3451 get_conftoken(CONF_ANY);
3458 #if SIZEOF_INT < SIZEOF_SSIZE_T
3459 if ((gint64)tokenval.v.size > (gint64)INT_MAX)
3460 conf_parserror(_("value too large"));
3461 if ((gint64)tokenval.v.size < (gint64)INT_MIN)
3462 conf_parserror(_("value too small"));
3464 val = (int)tokenval.v.size;
3468 #if SIZEOF_INT < SIZEOF_GINT64
3469 if (tokenval.v.int64 > (gint64)INT_MAX)
3470 conf_parserror(_("value too large"));
3471 if (tokenval.v.int64 < (gint64)INT_MIN)
3472 conf_parserror(_("value too small"));
3474 val = (int)tokenval.v.int64;
3477 case CONF_AMINFINITY:
3482 conf_parserror(_("an integer is expected"));
3487 /* get multiplier, if any */
3488 get_conftoken(CONF_ANY);
3490 case CONF_NL: /* multiply by one */
3497 if (val > (INT_MAX / 7))
3498 conf_parserror(_("value too large"));
3499 if (val < (INT_MIN / 7))
3500 conf_parserror(_("value too small"));
3505 if (val > (INT_MAX / 1024))
3506 conf_parserror(_("value too large"));
3507 if (val < (INT_MIN / 1024))
3508 conf_parserror(_("value too small"));
3513 if (val > (INT_MAX / (1024 * 1024)))
3514 conf_parserror(_("value too large"));
3515 if (val < (INT_MIN / (1024 * 1024)))
3516 conf_parserror(_("value too small"));
3520 default: /* it was not a multiplier */
3536 keytable = numb_keytable;
3538 get_conftoken(CONF_ANY);
3542 val = tokenval.v.size;
3546 #if SIZEOF_SIZE_T < SIZEOF_INT
3547 if ((gint64)tokenval.v.i > (gint64)SSIZE_MAX)
3548 conf_parserror(_("value too large"));
3549 if ((gint64)tokenval.v.i < (gint64)SSIZE_MIN)
3550 conf_parserror(_("value too small"));
3552 val = (ssize_t)tokenval.v.i;
3556 #if SIZEOF_SIZE_T < SIZEOF_GINT64
3557 if (tokenval.v.int64 > (gint64)SSIZE_MAX)
3558 conf_parserror(_("value too large"));
3559 if (tokenval.v.int64 < (gint64)SSIZE_MIN)
3560 conf_parserror(_("value too small"));
3562 val = (ssize_t)tokenval.v.int64;
3565 case CONF_AMINFINITY:
3566 val = (ssize_t)SSIZE_MAX;
3570 conf_parserror(_("an integer is expected"));
3575 /* get multiplier, if any */
3576 get_conftoken(CONF_ANY);
3579 case CONF_NL: /* multiply by one */
3585 if (val > (ssize_t)(SSIZE_MAX / 7))
3586 conf_parserror(_("value too large"));
3587 if (val < (ssize_t)(SSIZE_MIN / 7))
3588 conf_parserror(_("value too small"));
3593 if (val > (ssize_t)(SSIZE_MAX / (ssize_t)1024))
3594 conf_parserror(_("value too large"));
3595 if (val < (ssize_t)(SSIZE_MIN / (ssize_t)1024))
3596 conf_parserror(_("value too small"));
3597 val *= (ssize_t)1024;
3601 if (val > (ssize_t)(SSIZE_MAX / (1024 * 1024)))
3602 conf_parserror(_("value too large"));
3603 if (val < (ssize_t)(SSIZE_MIN / (1024 * 1024)))
3604 conf_parserror(_("value too small"));
3605 val *= (ssize_t)(1024 * 1024);
3608 default: /* it was not a multiplier */
3624 keytable = numb_keytable;
3626 get_conftoken(CONF_ANY);
3630 val = (gint64)tokenval.v.i;
3634 val = (gint64)tokenval.v.size;
3638 val = tokenval.v.int64;
3641 case CONF_AMINFINITY:
3646 conf_parserror(_("an integer is expected"));
3651 /* get multiplier, if any */
3652 get_conftoken(CONF_ANY);
3655 case CONF_NL: /* multiply by one */
3661 if (val > G_MAXINT64/7 || val < ((gint64)G_MININT64)/7)
3662 conf_parserror(_("value too large"));
3667 if (val > G_MAXINT64/1024 || val < ((gint64)G_MININT64)/1024)
3668 conf_parserror(_("value too large"));
3673 if (val > G_MAXINT64/(1024*1024) || val < ((gint64)G_MININT64)/(1024*1024))
3674 conf_parserror(_("value too large"));
3678 default: /* it was not a multiplier */
3695 keytable = bool_keytable;
3697 get_conftoken(CONF_ANY);
3701 if (tokenval.v.i != 0)
3708 if (tokenval.v.size != (size_t)0)
3715 if (tokenval.v.int64 != (gint64)0)
3731 val = 2; /* no argument - most likely TRUE */
3735 val = 3; /* a bad argument - most likely TRUE */
3736 conf_parserror(_("YES, NO, TRUE, FALSE, ON, OFF expected"));
3748 if (seen->linenum && !allow_overwrites && current_line_num != -2) {
3749 conf_parserror(_("duplicate parameter; previous definition %s:%d"),
3750 seen->filename, seen->linenum);
3752 seen->filename = current_filename;
3753 seen->linenum = current_line_num;
3756 /* Validation functions */
3759 validate_nonnegative(
3760 struct conf_var_s *np,
3765 if(val_t__int(val) < 0)
3766 conf_parserror(_("%s must be nonnegative"), get_token_name(np->token));
3768 case CONFTYPE_INT64:
3769 if(val_t__int64(val) < 0)
3770 conf_parserror(_("%s must be nonnegative"), get_token_name(np->token));
3773 if(val_t__size(val) < 0)
3774 conf_parserror(_("%s must be positive"), get_token_name(np->token));
3777 conf_parserror(_("validate_nonnegative invalid type %d\n"), val->type);
3783 struct conf_var_s *np,
3788 if(val_t__int(val) < 1)
3789 conf_parserror(_("%s must be positive"), get_token_name(np->token));
3791 case CONFTYPE_INT64:
3792 if(val_t__int64(val) < 1)
3793 conf_parserror(_("%s must be positive"), get_token_name(np->token));
3796 if(val_t__time(val) < 1)
3797 conf_parserror(_("%s must be positive"), get_token_name(np->token));
3800 if(val_t__size(val) < 1)
3801 conf_parserror(_("%s must be positive"), get_token_name(np->token));
3804 conf_parserror(_("validate_positive invalid type %d\n"), val->type);
3809 validate_runspercycle(
3810 struct conf_var_s *np G_GNUC_UNUSED,
3813 if(val_t__int(val) < -1)
3814 conf_parserror(_("runspercycle must be >= -1"));
3818 validate_bumppercent(
3819 struct conf_var_s *np G_GNUC_UNUSED,
3822 if(val_t__int(val) < 0 || val_t__int(val) > 100)
3823 conf_parserror(_("bumppercent must be between 0 and 100"));
3827 validate_inparallel(
3828 struct conf_var_s *np G_GNUC_UNUSED,
3831 if(val_t__int(val) < 1 || val_t__int(val) >MAX_DUMPERS)
3832 conf_parserror(_("inparallel must be between 1 and MAX_DUMPERS (%d)"),
3838 struct conf_var_s *np G_GNUC_UNUSED,
3841 if(val_t__real(val) < 0.999) {
3842 conf_parserror(_("bumpmult must one or more"));
3847 validate_displayunit(
3848 struct conf_var_s *np G_GNUC_UNUSED,
3849 val_t *val G_GNUC_UNUSED)
3851 char *s = val_t__str(val);
3852 if (strlen(s) == 1) {
3858 return; /* all good */
3860 /* lower-case values should get folded to upper case */
3865 s[0] = toupper(s[0]);
3872 conf_parserror(_("displayunit must be k,m,g or t."));
3877 struct conf_var_s *np G_GNUC_UNUSED,
3880 if(val_t__int(val) < 0 || val_t__int(val) > 100)
3881 conf_parserror(_("reserve must be between 0 and 100"));
3886 struct conf_var_s *np G_GNUC_UNUSED,
3889 val_t__int64(val) = am_floor(val_t__int64(val), DISK_BLOCK_KB);
3894 struct conf_var_s *np G_GNUC_UNUSED,
3897 /* NOTE: this function modifies the target value (rounding) */
3898 if(val_t__int64(val) == 0) {
3899 val_t__int64(val) = ((G_MAXINT64 / 1024) - (2 * DISK_BLOCK_KB));
3901 else if(val_t__int64(val) < 0) {
3902 conf_parserror(_("Negative chunksize (%lld) is no longer supported"), (long long)val_t__int64(val));
3904 val_t__int64(val) = am_floor(val_t__int64(val), (gint64)DISK_BLOCK_KB);
3905 if (val_t__int64(val) < 2*DISK_BLOCK_KB) {
3906 conf_parserror("chunksize must be at least %dkb", 2*DISK_BLOCK_KB);
3912 struct conf_var_s *np G_GNUC_UNUSED,
3915 if(val_t__size(val) < DISK_BLOCK_KB) {
3916 conf_parserror(_("Tape blocksize must be at least %d KBytes"),
3923 struct conf_var_s *np G_GNUC_UNUSED,
3926 if(val_t__int(val) < 0 || val_t__int(val) > 9) {
3927 conf_parserror(_("Debug must be between 0 and 9"));
3932 validate_port_range(
3938 /* check both values are in range */
3939 for (i = 0; i < 2; i++) {
3940 if(val_t__intrange(val)[0] < smallest || val_t__intrange(val)[0] > largest) {
3941 conf_parserror(_("portrange must be in the range %d to %d, inclusive"), smallest, largest);
3945 /* and check they're in the right order and not equal */
3946 if (val_t__intrange(val)[0] > val_t__intrange(val)[1]) {
3947 conf_parserror(_("portranges must be in order from low to high"));
3952 validate_reserved_port_range(
3953 struct conf_var_s *np G_GNUC_UNUSED,
3956 validate_port_range(val, 1, IPPORT_RESERVED-1);
3960 validate_unreserved_port_range(
3961 struct conf_var_s *np G_GNUC_UNUSED,
3964 validate_port_range(val, IPPORT_RESERVED, 65535);
3968 * Initialization Implementation
3973 config_init_flags flags,
3974 char *arg_config_name)
3976 if (!(flags & CONFIG_INIT_OVERLAY)) {
3977 /* Clear out anything that's already in there */
3980 /* and set everything to default values */
3983 allow_overwrites = FALSE;
3985 if (!config_initialized) {
3986 error(_("Attempt to overlay configuration with no existing configuration"));
3990 allow_overwrites = TRUE;
3993 /* store away our client-ness for later reference */
3994 config_client = flags & CONFIG_INIT_CLIENT;
3996 if ((flags & CONFIG_INIT_EXPLICIT_NAME) && arg_config_name) {
3997 config_name = newstralloc(config_name, arg_config_name);
3998 config_dir = newvstralloc(config_dir, CONFIG_DIR, "/", arg_config_name, NULL);
3999 } else if (flags & CONFIG_INIT_USE_CWD) {
4002 cwd = get_original_cwd();
4004 /* (this isn't a config error, so it's always fatal) */
4005 error(_("Cannot determine current working directory"));
4009 config_dir = stralloc2(cwd, "/");
4010 if ((config_name = strrchr(cwd, '/')) != NULL) {
4011 config_name = stralloc(config_name + 1);
4015 } else if (flags & CONFIG_INIT_CLIENT) {
4016 amfree(config_name);
4017 config_dir = newstralloc(config_dir, CONFIG_DIR);
4019 /* ok, then, we won't read anything (for e.g., amrestore), but
4020 * will set up for server-side config_overwrites */
4021 amfree(config_name);
4023 keytable = server_keytab;
4024 parsetable = server_var;
4027 /* If we have a config_dir, we can try reading something */
4029 if (flags & CONFIG_INIT_CLIENT) {
4030 config_filename = newvstralloc(config_filename, config_dir, "/amanda-client.conf", NULL);
4032 config_filename = newvstralloc(config_filename, config_dir, "/amanda.conf", NULL);
4035 read_conffile(config_filename,
4036 flags & CONFIG_INIT_CLIENT,
4037 flags & CONFIG_INIT_CLIENT);
4039 amfree(config_filename);
4042 update_derived_values(flags & CONFIG_INIT_CLIENT);
4044 return cfgerr_level;
4050 holdingdisk_t *hp, *hpnext;
4051 dumptype_t *dp, *dpnext;
4052 tapetype_t *tp, *tpnext;
4053 interface_t *ip, *ipnext;
4054 application_t *ap, *apnext;
4055 pp_script_t *pp, *ppnext;
4056 device_config_t *dc, *dcnext;
4057 changer_config_t *cc, *ccnext;
4060 if (!config_initialized) return;
4062 for(hp=holdinglist; hp != NULL; hp = hpnext) {
4064 for(i=0; i<HOLDING_HOLDING-1; i++) {
4065 free_val_t(&hp->value[i]);
4072 for(dp=dumplist; dp != NULL; dp = dpnext) {
4074 for(i=0; i<DUMPTYPE_DUMPTYPE-1; i++) {
4075 free_val_t(&dp->value[i]);
4082 for(tp=tapelist; tp != NULL; tp = tpnext) {
4084 for(i=0; i<TAPETYPE_TAPETYPE-1; i++) {
4085 free_val_t(&tp->value[i]);
4092 for(ip=interface_list; ip != NULL; ip = ipnext) {
4094 for(i=0; i<INTER_INTER-1; i++) {
4095 free_val_t(&ip->value[i]);
4100 interface_list = NULL;
4102 for(ap=application_list; ap != NULL; ap = apnext) {
4104 for(i=0; i<INTER_INTER-1; i++) {
4105 free_val_t(&ap->value[i]);
4110 application_list = NULL;
4112 for(pp=pp_script_list; pp != NULL; pp = ppnext) {
4114 for(i=0; i<INTER_INTER-1; i++) {
4115 free_val_t(&pp->value[i]);
4120 pp_script_list = NULL;
4122 for(dc=device_config_list; dc != NULL; dc = dcnext) {
4124 for(i=0; i<INTER_INTER-1; i++) {
4125 free_val_t(&dc->value[i]);
4130 device_config_list = NULL;
4132 for(cc=changer_config_list; cc != NULL; cc = ccnext) {
4134 for(i=0; i<INTER_INTER-1; i++) {
4135 free_val_t(&cc->value[i]);
4141 changer_config_list = NULL;
4143 for(i=0; i<CNF_CNF-1; i++)
4144 free_val_t(&conf_data[i]);
4146 if (applied_config_overwrites) {
4147 free_config_overwrites(applied_config_overwrites);
4148 applied_config_overwrites = NULL;
4151 amfree(config_name);
4154 g_slist_free_full(seen_filenames);
4155 seen_filenames = NULL;
4157 config_client = FALSE;
4159 config_clear_errors();
4160 config_initialized = FALSE;
4167 assert(!config_initialized);
4169 /* defaults for exported variables */
4170 conf_init_str(&conf_data[CNF_ORG], DEFAULT_CONFIG);
4171 conf_init_str(&conf_data[CNF_CONF], DEFAULT_CONFIG);
4172 conf_init_str(&conf_data[CNF_INDEX_SERVER], DEFAULT_SERVER);
4173 conf_init_str(&conf_data[CNF_TAPE_SERVER], DEFAULT_TAPE_SERVER);
4174 conf_init_str(&conf_data[CNF_AUTH], "bsd");
4175 conf_init_str(&conf_data[CNF_SSH_KEYS], "");
4176 conf_init_str(&conf_data[CNF_AMANDAD_PATH], "");
4177 conf_init_str(&conf_data[CNF_CLIENT_USERNAME], "");
4178 conf_init_str(&conf_data[CNF_GNUTAR_LIST_DIR], GNUTAR_LISTED_INCREMENTAL_DIR);
4179 conf_init_str(&conf_data[CNF_AMANDATES], DEFAULT_AMANDATES_FILE);
4180 conf_init_str(&conf_data[CNF_MAILTO], "operators");
4181 conf_init_str(&conf_data[CNF_DUMPUSER], CLIENT_LOGIN);
4182 conf_init_str(&conf_data[CNF_TAPEDEV], DEFAULT_TAPE_DEVICE);
4183 conf_init_str(&conf_data[CNF_RAWTAPEDEV], DEFAULT_TAPE_DEVICE);
4184 conf_init_proplist(&conf_data[CNF_DEVICE_PROPERTY]);
4185 conf_init_proplist(&conf_data[CNF_PROPERTY]);
4186 conf_init_str(&conf_data[CNF_CHANGERDEV], DEFAULT_CHANGER_DEVICE);
4187 conf_init_str(&conf_data[CNF_CHANGERFILE], "/usr/adm/amanda/changer-status");
4188 conf_init_str (&conf_data[CNF_LABELSTR] , ".*");
4189 conf_init_str (&conf_data[CNF_TAPELIST] , "tapelist");
4190 conf_init_str (&conf_data[CNF_DISKFILE] , "disklist");
4191 conf_init_str (&conf_data[CNF_INFOFILE] , "/usr/adm/amanda/curinfo");
4192 conf_init_str (&conf_data[CNF_LOGDIR] , "/usr/adm/amanda");
4193 conf_init_str (&conf_data[CNF_INDEXDIR] , "/usr/adm/amanda/index");
4194 conf_init_ident (&conf_data[CNF_TAPETYPE] , "EXABYTE");
4195 conf_init_int (&conf_data[CNF_DUMPCYCLE] , 10);
4196 conf_init_int (&conf_data[CNF_RUNSPERCYCLE] , 0);
4197 conf_init_int (&conf_data[CNF_TAPECYCLE] , 15);
4198 conf_init_int (&conf_data[CNF_NETUSAGE] , 8000);
4199 conf_init_int (&conf_data[CNF_INPARALLEL] , 10);
4200 conf_init_str (&conf_data[CNF_DUMPORDER] , "ttt");
4201 conf_init_int (&conf_data[CNF_BUMPPERCENT] , 0);
4202 conf_init_int64 (&conf_data[CNF_BUMPSIZE] , (gint64)10*1024);
4203 conf_init_real (&conf_data[CNF_BUMPMULT] , 1.5);
4204 conf_init_int (&conf_data[CNF_BUMPDAYS] , 2);
4205 conf_init_str (&conf_data[CNF_TPCHANGER] , "");
4206 conf_init_int (&conf_data[CNF_RUNTAPES] , 1);
4207 conf_init_int (&conf_data[CNF_MAXDUMPS] , 1);
4208 conf_init_int (&conf_data[CNF_ETIMEOUT] , 300);
4209 conf_init_int (&conf_data[CNF_DTIMEOUT] , 1800);
4210 conf_init_int (&conf_data[CNF_CTIMEOUT] , 30);
4211 conf_init_int (&conf_data[CNF_TAPEBUFS] , 20);
4212 conf_init_size (&conf_data[CNF_DEVICE_OUTPUT_BUFFER_SIZE], 40*32768);
4213 conf_init_str (&conf_data[CNF_PRINTER] , "");
4214 conf_init_str (&conf_data[CNF_MAILER] , DEFAULT_MAILER);
4215 conf_init_bool (&conf_data[CNF_AUTOFLUSH] , 0);
4216 conf_init_int (&conf_data[CNF_RESERVE] , 100);
4217 conf_init_int64 (&conf_data[CNF_MAXDUMPSIZE] , (gint64)-1);
4218 conf_init_str (&conf_data[CNF_COLUMNSPEC] , "");
4219 conf_init_bool (&conf_data[CNF_AMRECOVER_DO_FSF] , 1);
4220 conf_init_str (&conf_data[CNF_AMRECOVER_CHANGER] , "");
4221 conf_init_bool (&conf_data[CNF_AMRECOVER_CHECK_LABEL], 1);
4222 conf_init_taperalgo(&conf_data[CNF_TAPERALGO] , 0);
4223 conf_init_int (&conf_data[CNF_FLUSH_THRESHOLD_DUMPED] , 0);
4224 conf_init_int (&conf_data[CNF_FLUSH_THRESHOLD_SCHEDULED], 0);
4225 conf_init_int (&conf_data[CNF_TAPERFLUSH] , 0);
4226 conf_init_str (&conf_data[CNF_DISPLAYUNIT] , "k");
4227 conf_init_str (&conf_data[CNF_KRB5KEYTAB] , "/.amanda-v5-keytab");
4228 conf_init_str (&conf_data[CNF_KRB5PRINCIPAL] , "service/amanda");
4229 conf_init_str (&conf_data[CNF_LABEL_NEW_TAPES] , "");
4230 conf_init_bool (&conf_data[CNF_USETIMESTAMPS] , 1);
4231 conf_init_int (&conf_data[CNF_CONNECT_TRIES] , 3);
4232 conf_init_int (&conf_data[CNF_REP_TRIES] , 5);
4233 conf_init_int (&conf_data[CNF_REQ_TRIES] , 3);
4234 conf_init_int (&conf_data[CNF_DEBUG_AMANDAD] , 0);
4235 conf_init_int (&conf_data[CNF_DEBUG_AMIDXTAPED] , 0);
4236 conf_init_int (&conf_data[CNF_DEBUG_AMINDEXD] , 0);
4237 conf_init_int (&conf_data[CNF_DEBUG_AMRECOVER] , 0);
4238 conf_init_int (&conf_data[CNF_DEBUG_AUTH] , 0);
4239 conf_init_int (&conf_data[CNF_DEBUG_EVENT] , 0);
4240 conf_init_int (&conf_data[CNF_DEBUG_HOLDING] , 0);
4241 conf_init_int (&conf_data[CNF_DEBUG_PROTOCOL] , 0);
4242 conf_init_int (&conf_data[CNF_DEBUG_PLANNER] , 0);
4243 conf_init_int (&conf_data[CNF_DEBUG_DRIVER] , 0);
4244 conf_init_int (&conf_data[CNF_DEBUG_DUMPER] , 0);
4245 conf_init_int (&conf_data[CNF_DEBUG_CHUNKER] , 0);
4246 conf_init_int (&conf_data[CNF_DEBUG_TAPER] , 0);
4247 conf_init_int (&conf_data[CNF_DEBUG_SELFCHECK] , 0);
4248 conf_init_int (&conf_data[CNF_DEBUG_SENDSIZE] , 0);
4249 conf_init_int (&conf_data[CNF_DEBUG_SENDBACKUP] , 0);
4251 conf_init_intrange (&conf_data[CNF_RESERVED_UDP_PORT] , UDPPORTRANGE);
4253 conf_init_intrange (&conf_data[CNF_RESERVED_UDP_PORT] , 512, IPPORT_RESERVED-1);
4255 #ifdef LOW_TCPPORTRANGE
4256 conf_init_intrange (&conf_data[CNF_RESERVED_TCP_PORT] , LOW_TCPPORTRANGE);
4258 conf_init_intrange (&conf_data[CNF_RESERVED_TCP_PORT] , 512, IPPORT_RESERVED-1);
4261 conf_init_intrange (&conf_data[CNF_UNRESERVED_TCP_PORT] , TCPPORTRANGE);
4263 conf_init_intrange (&conf_data[CNF_UNRESERVED_TCP_PORT] , IPPORT_RESERVED, 65535);
4265 conf_init_send_amreport (&conf_data[CNF_SEND_AMREPORT_ON], SEND_AMREPORT_ALL);
4267 /* reset internal variables */
4268 config_clear_errors();
4269 cfgerr_level = CFGERR_OK;
4270 allow_overwrites = 0;
4273 /* create some predefined dumptypes for backwards compatability */
4274 init_dumptype_defaults();
4275 dpcur.name = stralloc("NO-COMPRESS");
4276 dpcur.seen.linenum = -1;
4277 free_val_t(&dpcur.value[DUMPTYPE_COMPRESS]);
4278 val_t__compress(&dpcur.value[DUMPTYPE_COMPRESS]) = COMP_NONE;
4279 val_t__seen(&dpcur.value[DUMPTYPE_COMPRESS]).linenum = -1;
4282 init_dumptype_defaults();
4283 dpcur.name = stralloc("COMPRESS-FAST");
4284 dpcur.seen.linenum = -1;
4285 free_val_t(&dpcur.value[DUMPTYPE_COMPRESS]);
4286 val_t__compress(&dpcur.value[DUMPTYPE_COMPRESS]) = COMP_FAST;
4287 val_t__seen(&dpcur.value[DUMPTYPE_COMPRESS]).linenum = -1;
4290 init_dumptype_defaults();
4291 dpcur.name = stralloc("COMPRESS-BEST");
4292 dpcur.seen.linenum = -1;
4293 free_val_t(&dpcur.value[DUMPTYPE_COMPRESS]);
4294 val_t__compress(&dpcur.value[DUMPTYPE_COMPRESS]) = COMP_BEST;
4295 val_t__seen(&dpcur.value[DUMPTYPE_COMPRESS]).linenum = -1;
4298 init_dumptype_defaults();
4299 dpcur.name = stralloc("COMPRESS-CUST");
4300 dpcur.seen.linenum = -1;
4301 free_val_t(&dpcur.value[DUMPTYPE_COMPRESS]);
4302 val_t__compress(&dpcur.value[DUMPTYPE_COMPRESS]) = COMP_CUST;
4303 val_t__seen(&dpcur.value[DUMPTYPE_COMPRESS]).linenum = -1;
4306 init_dumptype_defaults();
4307 dpcur.name = stralloc("SRVCOMPRESS");
4308 dpcur.seen.linenum = -1;
4309 free_val_t(&dpcur.value[DUMPTYPE_COMPRESS]);
4310 val_t__compress(&dpcur.value[DUMPTYPE_COMPRESS]) = COMP_SERVER_FAST;
4311 val_t__seen(&dpcur.value[DUMPTYPE_COMPRESS]).linenum = -1;
4314 init_dumptype_defaults();
4315 dpcur.name = stralloc("BSD-AUTH");
4316 dpcur.seen.linenum = -1;
4317 free_val_t(&dpcur.value[DUMPTYPE_SECURITY_DRIVER]);
4318 val_t__str(&dpcur.value[DUMPTYPE_SECURITY_DRIVER]) = stralloc("BSD");
4319 val_t__seen(&dpcur.value[DUMPTYPE_SECURITY_DRIVER]).linenum = -1;
4322 init_dumptype_defaults();
4323 dpcur.name = stralloc("KRB4-AUTH");
4324 dpcur.seen.linenum = -1;
4325 free_val_t(&dpcur.value[DUMPTYPE_SECURITY_DRIVER]);
4326 val_t__str(&dpcur.value[DUMPTYPE_SECURITY_DRIVER]) = stralloc("KRB4");
4327 val_t__seen(&dpcur.value[DUMPTYPE_SECURITY_DRIVER]).linenum = -1;
4330 init_dumptype_defaults();
4331 dpcur.name = stralloc("NO-RECORD");
4332 dpcur.seen.linenum = -1;
4333 free_val_t(&dpcur.value[DUMPTYPE_RECORD]);
4334 val_t__int(&dpcur.value[DUMPTYPE_RECORD]) = 0;
4335 val_t__seen(&dpcur.value[DUMPTYPE_RECORD]).linenum = -1;
4338 init_dumptype_defaults();
4339 dpcur.name = stralloc("NO-HOLD");
4340 dpcur.seen.linenum = -1;
4341 free_val_t(&dpcur.value[DUMPTYPE_HOLDINGDISK]);
4342 val_t__holding(&dpcur.value[DUMPTYPE_HOLDINGDISK]) = HOLD_NEVER;
4343 val_t__seen(&dpcur.value[DUMPTYPE_HOLDINGDISK]).linenum = -1;
4346 init_dumptype_defaults();
4347 dpcur.name = stralloc("NO-FULL");
4348 dpcur.seen.linenum = -1;
4349 free_val_t(&dpcur.value[DUMPTYPE_STRATEGY]);
4350 val_t__strategy(&dpcur.value[DUMPTYPE_STRATEGY]) = DS_NOFULL;
4351 val_t__seen(&dpcur.value[DUMPTYPE_STRATEGY]).linenum = -1;
4354 /* And we're initialized! */
4355 config_initialized = 1;
4362 char **config_options;
4363 char **config_option;
4364 int n_applied_config_overwrites = 0;
4367 if (applied_config_overwrites)
4368 n_applied_config_overwrites = applied_config_overwrites->n_used;
4370 config_options = alloc((first+n_applied_config_overwrites+1)*SIZEOF(char *));
4371 config_option = config_options + first;
4373 for (i = 0; i < n_applied_config_overwrites; i++) {
4374 char *key = applied_config_overwrites->ovr[i].key;
4375 char *value = applied_config_overwrites->ovr[i].value;
4376 *config_option = vstralloc("-o", key, "=", value, NULL);
4380 *config_option = NULL; /* add terminating sentinel */
4382 return config_options;
4386 update_derived_values(
4392 /* Add a 'default' interface if one doesn't already exist */
4393 if (!(ip = lookup_interface("default"))) {
4394 init_interface_defaults();
4395 ifcur.name = stralloc("default");
4396 ifcur.seen = val_t__seen(getconf(CNF_NETUSAGE));
4399 ip = lookup_interface("default");
4402 /* .. and set its maxusage from 'netusage' */
4403 if (!interface_seen(ip, INTER_MAXUSAGE)) {
4406 v = interface_getconf(ip, INTER_COMMENT);
4408 val_t__str(v) = stralloc(_("implicit from NETUSAGE"));
4409 val_t__seen(v) = val_t__seen(getconf(CNF_NETUSAGE));
4411 v = interface_getconf(ip, INTER_MAXUSAGE);
4413 val_t__int(v) = getconf_int(CNF_NETUSAGE);
4414 val_t__seen(v) = val_t__seen(getconf(CNF_NETUSAGE));
4417 /* Check the tapetype is defined */
4418 if (lookup_tapetype(getconf_str(CNF_TAPETYPE)) == NULL) {
4419 /* Create a default tapetype */
4420 if (!getconf_seen(CNF_TAPETYPE) &&
4421 strcmp(getconf_str(CNF_TAPETYPE), "EXABYTE") == 0 &&
4422 !lookup_tapetype("EXABYTE")) {
4423 init_tapetype_defaults();
4424 tpcur.name = stralloc("EXABYTE");
4425 tpcur.seen = val_t__seen(getconf(CNF_TAPETYPE));
4428 conf_parserror(_("tapetype %s is not defined"),
4429 getconf_str(CNF_TAPETYPE));
4434 /* fill in the debug_* values */
4435 debug_amandad = getconf_int(CNF_DEBUG_AMANDAD);
4436 debug_amidxtaped = getconf_int(CNF_DEBUG_AMIDXTAPED);
4437 debug_amindexd = getconf_int(CNF_DEBUG_AMINDEXD);
4438 debug_amrecover = getconf_int(CNF_DEBUG_AMRECOVER);
4439 debug_auth = getconf_int(CNF_DEBUG_AUTH);
4440 debug_event = getconf_int(CNF_DEBUG_EVENT);
4441 debug_holding = getconf_int(CNF_DEBUG_HOLDING);
4442 debug_protocol = getconf_int(CNF_DEBUG_PROTOCOL);
4443 debug_planner = getconf_int(CNF_DEBUG_PLANNER);
4444 debug_driver = getconf_int(CNF_DEBUG_DRIVER);
4445 debug_dumper = getconf_int(CNF_DEBUG_DUMPER);
4446 debug_chunker = getconf_int(CNF_DEBUG_CHUNKER);
4447 debug_taper = getconf_int(CNF_DEBUG_TAPER);
4448 debug_selfcheck = getconf_int(CNF_DEBUG_SELFCHECK);
4449 debug_sendsize = getconf_int(CNF_DEBUG_SENDSIZE);
4450 debug_sendbackup = getconf_int(CNF_DEBUG_SENDBACKUP);
4452 /* And finally, display unit */
4453 switch (getconf_str(CNF_DISPLAYUNIT)[0]) {
4461 unit_divisor = 1024;
4466 unit_divisor = 1024*1024;
4471 unit_divisor = 1024*1024*1024;
4475 error(_("Invalid displayunit missed by validate_displayunit"));
4485 val->seen.linenum = 0;
4486 val->seen.filename = NULL;
4487 val->type = CONFTYPE_INT;
4488 val_t__int(val) = i;
4496 val->seen.linenum = 0;
4497 val->seen.filename = NULL;
4498 val->type = CONFTYPE_INT64;
4499 val_t__int64(val) = l;
4507 val->seen.linenum = 0;
4508 val->seen.filename = NULL;
4509 val->type = CONFTYPE_REAL;
4510 val_t__real(val) = r;
4518 val->seen.linenum = 0;
4519 val->seen.filename = NULL;
4520 val->type = CONFTYPE_STR;
4522 val->v.s = stralloc(s);
4532 val->seen.linenum = 0;
4533 val->seen.filename = NULL;
4534 val->type = CONFTYPE_IDENT;
4536 val->v.s = stralloc(s);
4546 val->seen.linenum = 0;
4547 val->seen.filename = NULL;
4548 val->type = CONFTYPE_TIME;
4549 val_t__time(val) = t;
4557 val->seen.linenum = 0;
4558 val->seen.filename = NULL;
4559 val->type = CONFTYPE_SIZE;
4560 val_t__size(val) = sz;
4568 val->seen.linenum = 0;
4569 val->seen.filename = NULL;
4570 val->type = CONFTYPE_BOOLEAN;
4571 val_t__boolean(val) = i;
4579 val->seen.linenum = 0;
4580 val->seen.filename = NULL;
4581 val->type = CONFTYPE_COMPRESS;
4582 val_t__compress(val) = (int)i;
4590 val->seen.linenum = 0;
4591 val->seen.filename = NULL;
4592 val->type = CONFTYPE_ENCRYPT;
4593 val_t__encrypt(val) = (int)i;
4599 dump_holdingdisk_t i)
4601 val->seen.linenum = 0;
4602 val->seen.filename = NULL;
4603 val->type = CONFTYPE_HOLDING;
4604 val_t__holding(val) = (int)i;
4612 val->seen.linenum = 0;
4613 val->seen.filename = NULL;
4614 val->type = CONFTYPE_ESTIMATE;
4615 val_t__estimate(val) = i;
4623 val->seen.linenum = 0;
4624 val->seen.filename = NULL;
4625 val->type = CONFTYPE_STRATEGY;
4626 val_t__strategy(val) = i;
4630 conf_init_taperalgo(
4634 val->seen.linenum = 0;
4635 val->seen.filename = NULL;
4636 val->type = CONFTYPE_TAPERALGO;
4637 val_t__taperalgo(val) = i;
4645 val->seen.linenum = 0;
4646 val->seen.filename = NULL;
4647 val->type = CONFTYPE_PRIORITY;
4648 val_t__priority(val) = i;
4657 val->seen.linenum = 0;
4658 val->seen.filename = NULL;
4659 val->type = CONFTYPE_RATE;
4660 val_t__rate(val)[0] = r1;
4661 val_t__rate(val)[1] = r2;
4665 conf_init_exinclude(
4668 val->seen.linenum = 0;
4669 val->seen.filename = NULL;
4670 val->type = CONFTYPE_EXINCLUDE;
4671 val_t__exinclude(val).optional = 0;
4672 val_t__exinclude(val).sl_list = NULL;
4673 val_t__exinclude(val).sl_file = NULL;
4682 val->seen.linenum = 0;
4683 val->seen.filename = NULL;
4684 val->type = CONFTYPE_INTRANGE;
4685 val_t__intrange(val)[0] = i1;
4686 val_t__intrange(val)[1] = i2;
4693 val->seen.linenum = 0;
4694 val->seen.filename = NULL;
4695 val->type = CONFTYPE_PROPLIST;
4696 val_t__proplist(val) =
4697 g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL);
4701 conf_init_execute_on(
4705 val->seen.linenum = 0;
4706 val->seen.filename = NULL;
4707 val->type = CONFTYPE_EXECUTE_ON;
4712 conf_init_execute_where(
4716 val->seen.linenum = 0;
4717 val->seen.filename = NULL;
4718 val->type = CONFTYPE_EXECUTE_WHERE;
4723 conf_init_send_amreport(
4727 val->seen.linenum = 0;
4728 val->seen.filename = NULL;
4729 val->type = CONFTYPE_SEND_AMREPORT_ON;
4733 static void conf_init_pp_scriptlist(val_t *val) {
4734 val->seen.linenum = 0;
4735 val->seen.filename = NULL;
4736 val->type = CONFTYPE_PP_SCRIPTLIST;
4737 val->v.proplist = NULL;
4740 static void conf_init_application(val_t *val) {
4741 val->seen.linenum = 0;
4742 val->seen.filename = NULL;
4743 val->type = CONFTYPE_APPLICATION;
4744 val->v.application = NULL;
4749 * Config access implementation
4753 getconf(confparm_key key)
4755 assert(key < CNF_CNF);
4756 return &conf_data[key];
4769 device_config_t *dc;
4770 changer_config_t *cc;
4773 if (strcasecmp(listname,"tapetype") == 0) {
4774 for(tp = tapelist; tp != NULL; tp=tp->next) {
4775 rv = g_slist_append(rv, tp->name);
4777 } else if (strcasecmp(listname,"dumptype") == 0) {
4778 for(dp = dumplist; dp != NULL; dp=dp->next) {
4779 rv = g_slist_append(rv, dp->name);
4781 } else if (strcasecmp(listname,"holdingdisk") == 0) {
4782 for(hp = holdinglist; hp != NULL; hp=hp->next) {
4783 rv = g_slist_append(rv, hp->name);
4785 } else if (strcasecmp(listname,"interface") == 0) {
4786 for(ip = interface_list; ip != NULL; ip=ip->next) {
4787 rv = g_slist_append(rv, ip->name);
4789 } else if (strcasecmp(listname,"application_tool") == 0
4790 || strcasecmp(listname,"application-tool") == 0) {
4791 for(ap = application_list; ap != NULL; ap=ap->next) {
4792 rv = g_slist_append(rv, ap->name);
4794 } else if (strcasecmp(listname,"script_tool") == 0
4795 || strcasecmp(listname,"script-tool") == 0) {
4796 for(pp = pp_script_list; pp != NULL; pp=pp->next) {
4797 rv = g_slist_append(rv, pp->name);
4799 } else if (strcasecmp(listname,"device") == 0) {
4800 for(dc = device_config_list; dc != NULL; dc=dc->next) {
4801 rv = g_slist_append(rv, dc->name);
4803 } else if (strcasecmp(listname,"changer") == 0) {
4804 for(cc = changer_config_list; cc != NULL; cc=cc->next) {
4805 rv = g_slist_append(rv, cc->name);
4817 if (!parm_key_info(key, NULL, &rv))
4829 for(p = tapelist; p != NULL; p = p->next) {
4830 if(strcasecmp(p->name, str) == 0) return p;
4840 assert(ttyp != NULL);
4841 assert(key < TAPETYPE_TAPETYPE);
4842 return &ttyp->value[key];
4847 conf_var_t *np G_GNUC_UNUSED,
4850 if (strcmp(val->v.s, "DUMP") != 0 &&
4851 strcmp(val->v.s, "GNUTAR") != 0 &&
4852 strcmp(val->v.s, "STAR") != 0 &&
4853 strcmp(val->v.s, "APPLICATION") != 0)
4854 conf_parserror("program must be \"DUMP\", \"GNUTAR\", \"STAR\" or \"APPLICATION\"");
4862 assert(ttyp != NULL);
4872 for(p = dumplist; p != NULL; p = p->next) {
4873 if(strcasecmp(p->name, str) == 0) return p;
4883 assert(dtyp != NULL);
4884 assert(key < DUMPTYPE_DUMPTYPE);
4885 return &dtyp->value[key];
4892 assert(dtyp != NULL);
4902 for(p = interface_list; p != NULL; p = p->next) {
4903 if(strcasecmp(p->name, str) == 0) return p;
4913 assert(iface != NULL);
4914 assert(key < INTER_INTER);
4915 return &iface->value[key];
4922 assert(iface != NULL);
4932 for(p = holdinglist; p != NULL; p = p->next) {
4933 if(strcasecmp(p->name, str) == 0) return p;
4939 getconf_holdingdisks(
4947 holdingdisk_t *hdisk)
4949 if (hdisk) return hdisk->next;
4954 holdingdisk_getconf(
4955 holdingdisk_t *hdisk,
4956 holdingdisk_key key)
4958 assert(hdisk != NULL);
4959 assert(key < HOLDING_HOLDING);
4960 return &hdisk->value[key];
4965 holdingdisk_t *hdisk)
4967 assert(hdisk != NULL);
4977 for(p = application_list; p != NULL; p = p->next) {
4978 if(strcasecmp(p->name, str) == 0) return p;
4984 application_getconf(
4986 application_key key)
4989 assert(key < APPLICATION_APPLICATION);
4990 return &ap->value[key];
5007 for(pps = pp_script_list; pps != NULL; pps = pps->next) {
5008 if(strcasecmp(pps->name, str) == 0) return pps;
5018 assert(pps != NULL);
5019 assert(key < PP_SCRIPT_PP_SCRIPT);
5020 return &pps->value[key];
5027 assert(pps != NULL);
5032 lookup_device_config(
5035 device_config_t *devconf;
5037 for(devconf = device_config_list; devconf != NULL; devconf = devconf->next) {
5038 if(strcasecmp(devconf->name, str) == 0) return devconf;
5044 device_config_getconf(
5045 device_config_t *devconf,
5046 device_config_key key)
5048 assert(devconf != NULL);
5049 assert(key < DEVICE_CONFIG_DEVICE_CONFIG);
5050 return &devconf->value[key];
5055 device_config_t *devconf)
5057 assert(devconf != NULL);
5058 return devconf->name;
5062 lookup_changer_config(
5065 changer_config_t *devconf;
5067 for(devconf = changer_config_list; devconf != NULL; devconf = devconf->next) {
5068 if(strcasecmp(devconf->name, str) == 0) return devconf;
5074 changer_config_getconf(
5075 changer_config_t *devconf,
5076 changer_config_key key)
5078 assert(devconf != NULL);
5079 assert(key < CHANGER_CONFIG_CHANGER_CONFIG);
5080 return &devconf->value[key];
5084 changer_config_name(
5085 changer_config_t *devconf)
5087 assert(devconf != NULL);
5088 return devconf->name;
5092 getconf_unit_divisor(void)
5094 return unit_divisor;
5098 * Command-line Handling Implementation
5101 config_overwrites_t *
5102 new_config_overwrites(
5105 config_overwrites_t *co;
5107 if (size_estimate <= 0)
5110 co = alloc(sizeof(*co));
5111 co->ovr = alloc(sizeof(*co->ovr) * size_estimate);
5112 co->n_allocated = size_estimate;
5119 free_config_overwrites(
5120 config_overwrites_t *co)
5125 for (i = 0; i < co->n_used; i++) {
5126 amfree(co->ovr[i].key);
5127 amfree(co->ovr[i].value);
5133 void add_config_overwrite(
5134 config_overwrites_t *co,
5138 /* reallocate if necessary */
5139 if (co->n_used == co->n_allocated) {
5140 co->n_allocated *= 2;
5141 co->ovr = realloc(co->ovr, co->n_allocated * sizeof(*co->ovr));
5143 error(_("Cannot realloc; out of memory"));
5148 co->ovr[co->n_used].key = stralloc(key);
5149 co->ovr[co->n_used].value = stralloc(value);
5154 add_config_overwrite_opt(
5155 config_overwrites_t *co,
5159 assert(optarg != NULL);
5161 value = strchr(optarg, '=');
5162 if (value == NULL) {
5163 error(_("Must specify a value for %s."), optarg);
5168 add_config_overwrite(co, optarg, value+1);
5172 config_overwrites_t *
5173 extract_commandline_config_overwrites(
5178 config_overwrites_t *co = new_config_overwrites(*argc/2);
5182 if(strncmp((*argv)[i],"-o",2) == 0) {
5183 if(strlen((*argv)[i]) > 2) {
5184 add_config_overwrite_opt(co, (*argv)[i]+2);
5188 if (i+1 >= *argc) error(_("expect something after -o"));
5189 add_config_overwrite_opt(co, (*argv)[i+1]);
5193 /* move up remaining argment array */
5194 for (j = i; j+moveup<*argc; j++) {
5195 (*argv)[j] = (*argv)[j+moveup];
5207 apply_config_overwrites(
5208 config_overwrites_t *co)
5212 if(!co) return cfgerr_level;
5213 assert(keytable != NULL);
5214 assert(parsetable != NULL);
5216 for (i = 0; i < co->n_used; i++) {
5217 char *key = co->ovr[i].key;
5218 char *value = co->ovr[i].value;
5220 conf_var_t *key_parm;
5222 if (!parm_key_info(key, &key_parm, &key_val)) {
5223 conf_parserror(_("unknown parameter '%s'"), key);
5227 /* now set up a fake line and use the relevant read_function to
5228 * parse it. This is sneaky! */
5230 if (key_parm->type == CONFTYPE_STR) {
5231 current_line = vstralloc("\"", value, "\"", NULL);
5233 current_line = stralloc(value);
5236 current_char = current_line;
5238 current_line_num = -2;
5239 allow_overwrites = 1;
5241 key_parm->read_function(key_parm, key_val);
5242 if ((key_parm)->validate_function)
5243 key_parm->validate_function(key_parm, key_val);
5245 amfree(current_line);
5246 current_char = NULL;
5249 /* merge these overwrites with previous overwrites, if necessary */
5250 if (applied_config_overwrites) {
5251 for (i = 0; i < co->n_used; i++) {
5252 char *key = co->ovr[i].key;
5253 char *value = co->ovr[i].value;
5255 add_config_overwrite(applied_config_overwrites, key, value);
5257 free_config_overwrites(co);
5259 applied_config_overwrites = co;
5262 update_derived_values(config_client);
5264 return cfgerr_level;
5268 * val_t Management Implementation
5275 if (val->type != CONFTYPE_INT) {
5276 error(_("val_t_to_int: val.type is not CONFTYPE_INT"));
5279 return val_t__int(val);
5286 if (val->type != CONFTYPE_INT64) {
5287 error(_("val_t_to_int64: val.type is not CONFTYPE_INT64"));
5290 return val_t__int64(val);
5297 if (val->type != CONFTYPE_REAL) {
5298 error(_("val_t_to_real: val.type is not CONFTYPE_REAL"));
5301 return val_t__real(val);
5308 /* support CONFTYPE_IDENT, too */
5309 if (val->type != CONFTYPE_STR && val->type != CONFTYPE_IDENT) {
5310 error(_("val_t_to_str: val.type is not CONFTYPE_STR nor CONFTYPE_IDENT"));
5313 return val_t__str(val);
5320 /* support CONFTYPE_STR, too */
5321 if (val->type != CONFTYPE_STR && val->type != CONFTYPE_IDENT) {
5322 error(_("val_t_to_ident: val.type is not CONFTYPE_IDENT nor CONFTYPE_STR"));
5325 return val_t__str(val);
5332 if (val->type != CONFTYPE_TIME) {
5333 error(_("val_t_to_time: val.type is not CONFTYPE_TIME"));
5336 return val_t__time(val);
5343 if (val->type != CONFTYPE_SIZE) {
5344 error(_("val_t_to_size: val.type is not CONFTYPE_SIZE"));
5347 return val_t__size(val);
5354 if (val->type != CONFTYPE_BOOLEAN) {
5355 error(_("val_t_to_bool: val.type is not CONFTYPE_BOOLEAN"));
5358 return val_t__boolean(val);
5365 if (val->type != CONFTYPE_COMPRESS) {
5366 error(_("val_t_to_compress: val.type is not CONFTYPE_COMPRESS"));
5369 return val_t__compress(val);
5376 if (val->type != CONFTYPE_ENCRYPT) {
5377 error(_("val_t_to_encrypt: val.type is not CONFTYPE_ENCRYPT"));
5380 return val_t__encrypt(val);
5387 if (val->type != CONFTYPE_HOLDING) {
5388 error(_("val_t_to_hold: val.type is not CONFTYPE_HOLDING"));
5391 return val_t__holding(val);
5398 if (val->type != CONFTYPE_ESTIMATE) {
5399 error(_("val_t_to_estimate: val.type is not CONFTYPE_ESTIMATE"));
5402 return val_t__estimate(val);
5409 if (val->type != CONFTYPE_STRATEGY) {
5410 error(_("val_t_to_strategy: val.type is not CONFTYPE_STRATEGY"));
5413 return val_t__strategy(val);
5420 if (val->type != CONFTYPE_TAPERALGO) {
5421 error(_("val_t_to_taperalgo: val.type is not CONFTYPE_TAPERALGO"));
5424 return val_t__taperalgo(val);
5428 val_t_to_send_amreport(
5431 if (val->type != CONFTYPE_SEND_AMREPORT_ON) {
5432 error(_("val_t_to_send_amreport: val.type is not CONFTYPE_SEND_AMREPORT_ON"));
5435 return val_t__send_amreport(val);
5442 if (val->type != CONFTYPE_PRIORITY) {
5443 error(_("val_t_to_priority: val.type is not CONFTYPE_PRIORITY"));
5446 return val_t__priority(val);
5453 if (val->type != CONFTYPE_RATE) {
5454 error(_("val_t_to_rate: val.type is not CONFTYPE_RATE"));
5457 return val_t__rate(val);
5464 if (val->type != CONFTYPE_EXINCLUDE) {
5465 error(_("val_t_to_exinclude: val.type is not CONFTYPE_EXINCLUDE"));
5468 return val_t__exinclude(val);
5476 if (val->type != CONFTYPE_INTRANGE) {
5477 error(_("val_t_to_intrange: val.type is not CONFTYPE_INTRANGE"));
5480 return val_t__intrange(val);
5487 if (val->type != CONFTYPE_PROPLIST) {
5488 error(_("val_t_to_proplist: val.type is not CONFTYPE_PROPLIST"));
5491 return val_t__proplist(val);
5499 if(valsrc->seen.linenum) {
5500 valdst->type = valsrc->type;
5501 valdst->seen = valsrc->seen;
5502 switch(valsrc->type) {
5504 case CONFTYPE_BOOLEAN:
5505 case CONFTYPE_COMPRESS:
5506 case CONFTYPE_ENCRYPT:
5507 case CONFTYPE_HOLDING:
5508 case CONFTYPE_ESTIMATE:
5509 case CONFTYPE_EXECUTE_ON:
5510 case CONFTYPE_EXECUTE_WHERE:
5511 case CONFTYPE_SEND_AMREPORT_ON:
5512 case CONFTYPE_STRATEGY:
5513 case CONFTYPE_TAPERALGO:
5514 case CONFTYPE_PRIORITY:
5515 valdst->v.i = valsrc->v.i;
5519 valdst->v.size = valsrc->v.size;
5522 case CONFTYPE_INT64:
5523 valdst->v.int64 = valsrc->v.int64;
5527 valdst->v.r = valsrc->v.r;
5531 valdst->v.rate[0] = valsrc->v.rate[0];
5532 valdst->v.rate[1] = valsrc->v.rate[1];
5535 case CONFTYPE_IDENT:
5537 valdst->v.s = stralloc(valsrc->v.s);
5541 valdst->v.t = valsrc->v.t;
5544 case CONFTYPE_EXINCLUDE:
5545 valdst->v.exinclude.optional = valsrc->v.exinclude.optional;
5546 valdst->v.exinclude.sl_list = duplicate_sl(valsrc->v.exinclude.sl_list);
5547 valdst->v.exinclude.sl_file = duplicate_sl(valsrc->v.exinclude.sl_file);
5550 case CONFTYPE_INTRANGE:
5551 valdst->v.intrange[0] = valsrc->v.intrange[0];
5552 valdst->v.intrange[1] = valsrc->v.intrange[1];
5555 case CONFTYPE_PROPLIST:
5556 if (valsrc->v.proplist) {
5557 valdst->v.proplist = g_hash_table_new_full(g_str_hash,
5561 g_hash_table_foreach(valsrc->v.proplist, ©_proplist,
5562 valdst->v.proplist);
5564 valdst->v.proplist = NULL;
5568 case CONFTYPE_PP_SCRIPTLIST:
5569 valdst->v.pp_scriptlist = NULL;
5570 if (valsrc->v.pp_scriptlist) {
5571 g_slist_foreach(valsrc->v.pp_scriptlist, ©_pp_scriptlist,
5572 &valdst->v.pp_scriptlist);
5576 case CONFTYPE_APPLICATION:
5577 valdst->v.application = valsrc->v.application;
5587 gpointer user_data_p)
5589 char *property_s = key_p;
5590 property_t *property = value_p;
5591 proplist_t proplist = user_data_p;
5592 GSList *elem = NULL;
5593 property_t *new_property = malloc(sizeof(property_t));
5594 new_property->append = property->append;
5595 new_property->priority = property->priority;
5596 new_property->values = NULL;
5598 for(elem = property->values;elem != NULL; elem=elem->next) {
5599 new_property->values = g_slist_append(new_property->values,
5600 stralloc(elem->data));
5602 g_hash_table_insert(proplist, property_s, new_property);
5608 gpointer user_data_p)
5610 pp_script_t *pp_script = data_p;
5611 pp_scriptlist_t *pp_scriptlist = user_data_p;
5613 *pp_scriptlist = g_slist_append(*pp_scriptlist, pp_script);
5622 case CONFTYPE_BOOLEAN:
5623 case CONFTYPE_COMPRESS:
5624 case CONFTYPE_ENCRYPT:
5625 case CONFTYPE_HOLDING:
5626 case CONFTYPE_ESTIMATE:
5627 case CONFTYPE_EXECUTE_WHERE:
5628 case CONFTYPE_EXECUTE_ON:
5629 case CONFTYPE_SEND_AMREPORT_ON:
5630 case CONFTYPE_STRATEGY:
5632 case CONFTYPE_TAPERALGO:
5633 case CONFTYPE_PRIORITY:
5634 case CONFTYPE_INT64:
5637 case CONFTYPE_INTRANGE:
5640 case CONFTYPE_IDENT:
5648 case CONFTYPE_EXINCLUDE:
5649 free_sl(val_t__exinclude(val).sl_list);
5650 free_sl(val_t__exinclude(val).sl_file);
5653 case CONFTYPE_PROPLIST:
5654 g_hash_table_destroy(val_t__proplist(val));
5657 case CONFTYPE_PP_SCRIPTLIST:
5658 g_slist_free_full(val->v.pp_scriptlist);
5661 case CONFTYPE_APPLICATION:
5664 val->seen.linenum = 0;
5665 val->seen.filename = NULL;
5669 * Utilities Implementation
5673 generic_get_security_conf(
5678 if(!string || !*string)
5681 if(strcmp(string, "krb5principal")==0) {
5682 return(getconf_str(CNF_KRB5PRINCIPAL));
5683 } else if(strcmp(string, "krb5keytab")==0) {
5684 return(getconf_str(CNF_KRB5KEYTAB));
5690 generic_client_get_security_conf(
5694 (void)arg; /* Quiet unused parameter warning */
5696 if(!string || !*string)
5699 if(strcmp(string, "conf")==0) {
5700 return(getconf_str(CNF_CONF));
5701 } else if(strcmp(string, "index_server")==0) {
5702 return(getconf_str(CNF_INDEX_SERVER));
5703 } else if(strcmp(string, "tape_server")==0) {
5704 return(getconf_str(CNF_TAPE_SERVER));
5705 } else if(strcmp(string, "tapedev")==0) {
5706 return(getconf_str(CNF_TAPEDEV));
5707 } else if(strcmp(string, "auth")==0) {
5708 return(getconf_str(CNF_AUTH));
5709 } else if(strcmp(string, "ssh_keys")==0) {
5710 return(getconf_str(CNF_SSH_KEYS));
5711 } else if(strcmp(string, "amandad_path")==0) {
5712 return(getconf_str(CNF_AMANDAD_PATH));
5713 } else if(strcmp(string, "client_username")==0) {
5714 return(getconf_str(CNF_CLIENT_USERNAME));
5715 } else if(strcmp(string, "gnutar_list_dir")==0) {
5716 return(getconf_str(CNF_GNUTAR_LIST_DIR));
5717 } else if(strcmp(string, "amandates")==0) {
5718 return(getconf_str(CNF_AMANDATES));
5719 } else if(strcmp(string, "krb5principal")==0) {
5720 return(getconf_str(CNF_KRB5PRINCIPAL));
5721 } else if(strcmp(string, "krb5keytab")==0) {
5722 return(getconf_str(CNF_KRB5KEYTAB));
5728 dump_configuration(void)
5736 device_config_t *dc;
5737 changer_config_t *cc;
5743 if (config_client) {
5744 error(_("Don't know how to dump client configurations."));
5748 g_printf(_("# AMANDA CONFIGURATION FROM FILE \"%s\":\n\n"), config_filename);
5750 for(np=server_var; np->token != CONF_UNKNOWN; np++) {
5751 for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
5752 if (np->token == kt->token) break;
5754 if(kt->token == CONF_UNKNOWN)
5755 error(_("server bad token"));
5757 val_t_print_token(stdout, NULL, "%-21s ", kt, &conf_data[np->parm]);
5760 for(hp = holdinglist; hp != NULL; hp = hp->next) {
5761 g_printf("\nHOLDINGDISK %s {\n", hp->name);
5762 for(i=0; i < HOLDING_HOLDING; i++) {
5763 for(np=holding_var; np->token != CONF_UNKNOWN; np++) {
5767 if(np->token == CONF_UNKNOWN)
5768 error(_("holding bad value"));
5770 for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++) {
5771 if(kt->token == np->token)
5774 if(kt->token == CONF_UNKNOWN)
5775 error(_("holding bad token"));
5777 val_t_print_token(stdout, NULL, " %-9s ", kt, &hp->value[i]);
5782 for(tp = tapelist; tp != NULL; tp = tp->next) {
5783 if(tp->seen.linenum == -1)
5787 g_printf("\n%sDEFINE TAPETYPE %s {\n", prefix, tp->name);
5788 for(i=0; i < TAPETYPE_TAPETYPE; i++) {
5789 for(np=tapetype_var; np->token != CONF_UNKNOWN; np++)
5790 if(np->parm == i) break;
5791 if(np->token == CONF_UNKNOWN)
5792 error(_("tapetype bad value"));
5794 for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
5795 if(kt->token == np->token) break;
5796 if(kt->token == CONF_UNKNOWN)
5797 error(_("tapetype bad token"));
5799 val_t_print_token(stdout, prefix, " %-9s ", kt, &tp->value[i]);
5801 g_printf("%s}\n", prefix);
5804 for(dp = dumplist; dp != NULL; dp = dp->next) {
5805 if (strncmp_const(dp->name, "custom(") != 0) { /* don't dump disklist-derived dumptypes */
5806 if(dp->seen.linenum == -1)
5810 g_printf("\n%sDEFINE DUMPTYPE %s {\n", prefix, dp->name);
5811 for(i=0; i < DUMPTYPE_DUMPTYPE; i++) {
5812 for(np=dumptype_var; np->token != CONF_UNKNOWN; np++)
5813 if(np->parm == i) break;
5814 if(np->token == CONF_UNKNOWN)
5815 error(_("dumptype bad value"));
5817 for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
5818 if(kt->token == np->token) break;
5819 if(kt->token == CONF_UNKNOWN)
5820 error(_("dumptype bad token"));
5822 val_t_print_token(stdout, prefix, " %-19s ", kt, &dp->value[i]);
5824 g_printf("%s}\n", prefix);
5828 for(ip = interface_list; ip != NULL; ip = ip->next) {
5829 seen_t *netusage_seen = &val_t__seen(getconf(CNF_NETUSAGE));
5830 if (ip->seen.linenum == netusage_seen->linenum &&
5831 ip->seen.filename && netusage_seen->filename &&
5832 0 == strcmp(ip->seen.filename, netusage_seen->filename))
5836 g_printf("\n%sDEFINE INTERFACE %s {\n", prefix, ip->name);
5837 for(i=0; i < INTER_INTER; i++) {
5838 for(np=interface_var; np->token != CONF_UNKNOWN; np++)
5839 if(np->parm == i) break;
5840 if(np->token == CONF_UNKNOWN)
5841 error(_("interface bad value"));
5843 for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
5844 if(kt->token == np->token) break;
5845 if(kt->token == CONF_UNKNOWN)
5846 error(_("interface bad token"));
5848 val_t_print_token(stdout, prefix, " %-19s ", kt, &ip->value[i]);
5850 g_printf("%s}\n",prefix);
5853 for(ap = application_list; ap != NULL; ap = ap->next) {
5854 if(strcmp(ap->name,"default") == 0)
5858 g_printf("\n%sDEFINE APPLICATION-TOOL %s {\n", prefix, ap->name);
5859 for(i=0; i < APPLICATION_APPLICATION; i++) {
5860 for(np=application_var; np->token != CONF_UNKNOWN; np++)
5861 if(np->parm == i) break;
5862 if(np->token == CONF_UNKNOWN)
5863 error(_("application-tool bad value"));
5865 for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
5866 if(kt->token == np->token) break;
5867 if(kt->token == CONF_UNKNOWN)
5868 error(_("application bad token"));
5870 val_t_print_token(stdout, prefix, " %-19s ", kt, &ap->value[i]);
5872 g_printf("%s}\n",prefix);
5875 for(ps = pp_script_list; ps != NULL; ps = ps->next) {
5876 if(strcmp(ps->name,"default") == 0)
5880 g_printf("\n%sDEFINE SCRIPT-TOOL %s {\n", prefix, ps->name);
5881 for(i=0; i < PP_SCRIPT_PP_SCRIPT; i++) {
5882 for(np=pp_script_var; np->token != CONF_UNKNOWN; np++)
5883 if(np->parm == i) break;
5884 if(np->token == CONF_UNKNOWN)
5885 error(_("script-tool bad value"));
5887 for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
5888 if(kt->token == np->token) break;
5889 if(kt->token == CONF_UNKNOWN)
5890 error(_("script bad token"));
5892 val_t_print_token(stdout, prefix, " %-19s ", kt, &ps->value[i]);
5894 g_printf("%s}\n",prefix);
5897 for(dc = device_config_list; dc != NULL; dc = dc->next) {
5899 g_printf("\n%sDEFINE DEVICE %s {\n", prefix, dc->name);
5900 for(i=0; i < DEVICE_CONFIG_DEVICE_CONFIG; i++) {
5901 for(np=device_config_var; np->token != CONF_UNKNOWN; np++)
5902 if(np->parm == i) break;
5903 if(np->token == CONF_UNKNOWN)
5904 error(_("device bad value"));
5906 for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
5907 if(kt->token == np->token) break;
5908 if(kt->token == CONF_UNKNOWN)
5909 error(_("device bad token"));
5911 val_t_print_token(stdout, prefix, " %-19s ", kt, &dc->value[i]);
5913 g_printf("%s}\n",prefix);
5916 for(cc = changer_config_list; cc != NULL; cc = cc->next) {
5918 g_printf("\n%sDEFINE CHANGER %s {\n", prefix, cc->name);
5919 for(i=0; i < CHANGER_CONFIG_CHANGER_CONFIG; i++) {
5920 for(np=changer_config_var; np->token != CONF_UNKNOWN; np++)
5921 if(np->parm == i) break;
5922 if(np->token == CONF_UNKNOWN)
5923 error(_("changer bad value"));
5925 for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
5926 if(kt->token == np->token) break;
5927 if(kt->token == CONF_UNKNOWN)
5928 error(_("changer bad token"));
5930 val_t_print_token(stdout, prefix, " %-19s ", kt, &cc->value[i]);
5932 g_printf("%s}\n",prefix);
5944 char **dispstrs, **dispstr;
5945 dispstrs = val_t_display_strs(val, 1);
5947 /* For most configuration types, this outputs
5948 * PREFIX KEYWORD DISPSTR
5949 * for each of the display strings. For identifiers, however, it
5950 * simply prints the first line of the display string.
5953 /* Print the keyword for anything that is not itself an identifier */
5954 if (kt->token != CONF_IDENT) {
5955 for(dispstr=dispstrs; *dispstr!=NULL; dispstr++) {
5957 g_fprintf(output, "%s", prefix);
5958 g_fprintf(output, format, kt->keyword);
5959 g_fprintf(output, "%s\n", *dispstr);
5962 /* for identifiers, assume there's at most one display string */
5963 assert(g_strv_length(dispstrs) <= 1);
5965 g_fprintf(output, "%s\n", *dispstrs);
5969 g_strfreev(dispstrs);
5978 buf = malloc(3*SIZEOF(char *));
5985 buf[0] = vstrallocf("%d", val_t__int(val));
5989 buf[0] = vstrallocf("%zd", (ssize_t)val_t__size(val));
5992 case CONFTYPE_INT64:
5993 buf[0] = vstrallocf("%lld", (long long)val_t__int64(val));
5997 buf[0] = vstrallocf("%0.5f", val_t__real(val));
6001 buf[0] = vstrallocf("%0.5f %0.5f", val_t__rate(val)[0], val_t__rate(val)[1]);
6004 case CONFTYPE_INTRANGE:
6005 buf[0] = vstrallocf("%d,%d", val_t__intrange(val)[0], val_t__intrange(val)[1]);
6008 case CONFTYPE_IDENT:
6010 buf[0] = stralloc(val->v.s);
6012 buf[0] = stralloc("");
6017 if(str_need_quote) {
6019 buf[0] = vstrallocf("\"%s\"", val->v.s);
6021 buf[0] = stralloc("\"\"");
6025 buf[0] = stralloc(val->v.s);
6027 buf[0] = stralloc("");
6033 buf[0] = vstrallocf("%2d%02d",
6034 (int)val_t__time(val)/100, (int)val_t__time(val) % 100);
6037 case CONFTYPE_EXINCLUDE: {
6038 buf[0] = exinclude_display_str(val, 0);
6039 buf[1] = exinclude_display_str(val, 1);
6043 case CONFTYPE_BOOLEAN:
6044 if(val_t__boolean(val))
6045 buf[0] = stralloc("yes");
6047 buf[0] = stralloc("no");
6050 case CONFTYPE_STRATEGY:
6051 switch(val_t__strategy(val)) {
6053 buf[0] = vstrallocf("SKIP");
6057 buf[0] = vstrallocf("STANDARD");
6061 buf[0] = vstrallocf("NOFULL");
6065 buf[0] = vstrallocf("NOINC");
6069 buf[0] = vstrallocf("HANOI");
6073 buf[0] = vstrallocf("INCRONLY");
6078 case CONFTYPE_COMPRESS:
6079 switch(val_t__compress(val)) {
6081 buf[0] = vstrallocf("NONE");
6085 buf[0] = vstrallocf("CLIENT FAST");
6089 buf[0] = vstrallocf("CLIENT BEST");
6093 buf[0] = vstrallocf("CLIENT CUSTOM");
6096 case COMP_SERVER_FAST:
6097 buf[0] = vstrallocf("SERVER FAST");
6100 case COMP_SERVER_BEST:
6101 buf[0] = vstrallocf("SERVER BEST");
6104 case COMP_SERVER_CUST:
6105 buf[0] = vstrallocf("SERVER CUSTOM");
6110 case CONFTYPE_ESTIMATE:
6111 switch(val_t__estimate(val)) {
6113 buf[0] = vstrallocf("CLIENT");
6117 buf[0] = vstrallocf("SERVER");
6121 buf[0] = vstrallocf("CALCSIZE");
6126 case CONFTYPE_EXECUTE_WHERE:
6129 buf[0] = vstrallocf("CLIENT");
6133 buf[0] = vstrallocf("SERVER");
6138 case CONFTYPE_SEND_AMREPORT_ON:
6140 case SEND_AMREPORT_ALL:
6141 buf[0] = vstrallocf("ALL");
6143 case SEND_AMREPORT_STRANGE:
6144 buf[0] = vstrallocf("STRANGE");
6146 case SEND_AMREPORT_ERROR:
6147 buf[0] = vstrallocf("ERROR");
6149 case SEND_AMREPORT_NEVER:
6150 buf[0] = vstrallocf("NEVER");
6155 case CONFTYPE_ENCRYPT:
6156 switch(val_t__encrypt(val)) {
6158 buf[0] = vstrallocf("NONE");
6162 buf[0] = vstrallocf("CLIENT");
6165 case ENCRYPT_SERV_CUST:
6166 buf[0] = vstrallocf("SERVER");
6171 case CONFTYPE_HOLDING:
6172 switch(val_t__holding(val)) {
6174 buf[0] = vstrallocf("NEVER");
6178 buf[0] = vstrallocf("AUTO");
6182 buf[0] = vstrallocf("REQUIRED");
6187 case CONFTYPE_TAPERALGO:
6188 buf[0] = vstrallocf("%s", taperalgo2str(val_t__taperalgo(val)));
6191 case CONFTYPE_PRIORITY:
6192 switch(val_t__priority(val)) {
6194 buf[0] = vstrallocf("LOW");
6198 buf[0] = vstrallocf("MEDIUM");
6202 buf[0] = vstrallocf("HIGH");
6207 case CONFTYPE_PROPLIST: {
6211 nb_property = g_hash_table_size(val_t__proplist(val));
6213 buf = malloc((nb_property+1)*SIZEOF(char*));
6214 buf[nb_property] = NULL;
6216 g_hash_table_foreach(val_t__proplist(val),
6217 proplist_display_str_foreach_fn,
6222 case CONFTYPE_PP_SCRIPTLIST: {
6223 int nb_pp_scriplist;
6226 nb_pp_scriplist = g_slist_length(val_t__pp_scriptlist(val));
6228 buf = malloc((nb_pp_scriplist+1)*SIZEOF(char*));
6229 buf[nb_pp_scriplist] = NULL;
6231 g_slist_foreach(val_t__pp_scriptlist(val),
6232 pp_scriptlist_display_str_foreach_fn,
6237 case CONFTYPE_APPLICATION: {
6238 if (val->v.application) {
6239 buf[0] = vstrallocf("\"%s\"", val->v.application->name);
6241 buf[0] = stralloc("");
6246 case CONFTYPE_EXECUTE_ON:
6247 buf[0] = stralloc("");
6248 if (val->v.i != 0) {
6250 if (val->v.i & EXECUTE_ON_PRE_DLE_AMCHECK) {
6251 buf[0] = vstrextend(&buf[0], sep, "PRE-DLE-AMCHECK", NULL);
6254 if (val->v.i & EXECUTE_ON_PRE_HOST_AMCHECK) {
6255 buf[0] = vstrextend(&buf[0], sep, "PRE-HOST-AMCHECK", NULL);
6258 if (val->v.i & EXECUTE_ON_POST_DLE_AMCHECK) {
6259 buf[0] = vstrextend(&buf[0], sep, "POST-DLE-AMCHECK", NULL);
6262 if (val->v.i & EXECUTE_ON_POST_HOST_AMCHECK) {
6263 buf[0] = vstrextend(&buf[0], sep, "POST-HOST-AMCHECK", NULL);
6266 if (val->v.i & EXECUTE_ON_PRE_DLE_ESTIMATE) {
6267 buf[0] = vstrextend(&buf[0], sep, "PRE-DLE-ESTIMATE", NULL);
6270 if (val->v.i & EXECUTE_ON_PRE_HOST_ESTIMATE) {
6271 buf[0] = vstrextend(&buf[0], sep, "PRE-HOST-ESTIMATE", NULL);
6274 if (val->v.i & EXECUTE_ON_POST_DLE_ESTIMATE) {
6275 buf[0] = vstrextend(&buf[0], sep, "POST-DLE-ESTIMATE", NULL);
6278 if (val->v.i & EXECUTE_ON_POST_HOST_ESTIMATE) {
6279 buf[0] = vstrextend(&buf[0], sep, "POST-HOST-ESTIMATE", NULL);
6282 if (val->v.i & EXECUTE_ON_PRE_DLE_BACKUP) {
6283 buf[0] = vstrextend(&buf[0], sep, "PRE-DLE-BACKUP", NULL);
6286 if (val->v.i & EXECUTE_ON_PRE_HOST_BACKUP) {
6287 buf[0] = vstrextend(&buf[0], sep, "PRE-HOST-BACKUP", NULL);
6290 if (val->v.i & EXECUTE_ON_POST_DLE_BACKUP) {
6291 buf[0] = vstrextend(&buf[0], sep, "POST-DLE-BACKUP", NULL);
6294 if (val->v.i & EXECUTE_ON_POST_HOST_BACKUP) {
6295 buf[0] = vstrextend(&buf[0], sep, "POST-HOST-BACKUP", NULL);
6298 if (val->v.i & EXECUTE_ON_PRE_RECOVER) {
6299 buf[0] = vstrextend(&buf[0], sep, "PRE-RECOVER", NULL);
6302 if (val->v.i & EXECUTE_ON_POST_RECOVER) {
6303 buf[0] = vstrextend(&buf[0], sep, "POST-RECOVER", NULL);
6306 if (val->v.i & EXECUTE_ON_PRE_LEVEL_RECOVER) {
6307 buf[0] = vstrextend(&buf[0], sep, "PRE-LEVEL-RECOVER", NULL);
6310 if (val->v.i & EXECUTE_ON_POST_LEVEL_RECOVER) {
6311 buf[0] = vstrextend(&buf[0], sep, "POST-LEVEL-RECOVER", NULL);
6314 if (val->v.i & EXECUTE_ON_INTER_LEVEL_RECOVER) {
6315 buf[0] = vstrextend(&buf[0], sep, "INTER-LEVEL-RECOVER", NULL);
6326 val_t_to_execute_on(
6329 if (val->type != CONFTYPE_EXECUTE_ON) {
6330 error(_("get_conftype_execute_on: val.type is not CONFTYPE_EXECUTE_ON"));
6333 return val_t__execute_on(val);
6337 val_t_to_execute_where(
6340 if (val->type != CONFTYPE_EXECUTE_WHERE) {
6341 error(_("get_conftype_execute_where: val.type is not CONFTYPE_EXECUTE_WHERE"));
6348 val_t_to_pp_scriptlist(
6351 if (val->type != CONFTYPE_PP_SCRIPTLIST) {
6352 error(_("get_conftype_proplist: val.type is not CONFTYPE_PP_SCRIPTLIST"));
6355 return val->v.pp_scriptlist;
6360 val_t_to_application(
6363 if (val->type != CONFTYPE_APPLICATION) {
6364 error(_("get_conftype_applicaiton: val.type is not CONFTYPE_APPLICATION"));
6367 return val->v.application;
6372 proplist_display_str_foreach_fn(
6375 gpointer user_data_p)
6377 char *property_s = key_p;
6378 property_t *property = value_p;
6380 char ***msg = (char ***)user_data_p;
6382 /* What to do with property->append? it should be printed only on client */
6383 if (property->priority) {
6384 **msg = vstralloc("priority \"", property_s, "\"", NULL);
6386 **msg = vstralloc("\"", property_s, "\"", NULL);
6388 for(value=property->values; value != NULL; value = value->next) {
6389 **msg = vstrextend(*msg, " \"", value->data, "\"", NULL);
6395 pp_scriptlist_display_str_foreach_fn(
6397 gpointer user_data_p)
6399 pp_script_t *pp_script = data_p;
6400 char ***msg = (char ***)user_data_p;
6402 **msg = vstralloc("\"", pp_script->name, "\"", NULL);
6408 exinclude_display_str(
6416 assert(val->type == CONFTYPE_EXINCLUDE);
6418 rval = stralloc("");
6421 sl = val_t__exinclude(val).sl_list;
6422 strappend(rval, "LIST");
6424 sl = val_t__exinclude(val).sl_file;
6425 strappend(rval, "FILE");
6428 if (val_t__exinclude(val).optional == 1) {
6429 strappend(rval, " OPTIONAL");
6433 for(excl = sl->first; excl != NULL; excl = excl->next) {
6434 vstrextend(&rval, " \"", excl->name, "\"", NULL);
6443 taperalgo_t taperalgo)
6445 if(taperalgo == ALGO_FIRST) return "FIRST";
6446 if(taperalgo == ALGO_FIRSTFIT) return "FIRSTFIT";
6447 if(taperalgo == ALGO_LARGEST) return "LARGEST";
6448 if(taperalgo == ALGO_LARGESTFIT) return "LARGESTFIT";
6449 if(taperalgo == ALGO_SMALLEST) return "SMALLEST";
6450 if(taperalgo == ALGO_LAST) return "LAST";
6455 config_dir_relative(
6458 if (*filename == '/' || config_dir == NULL) {
6459 return stralloc(filename);
6461 if (config_dir[strlen(config_dir)-1] == '/') {
6462 return vstralloc(config_dir, filename, NULL);
6464 return vstralloc(config_dir, "/", filename, NULL);
6488 device_config_t *dc;
6489 changer_config_t *cc;
6490 int success = FALSE;
6492 /* WARNING: assumes globals keytable and parsetable are set correctly. */
6493 assert(keytable != NULL);
6494 assert(parsetable != NULL);
6496 /* make a copy we can stomp on */
6497 key = stralloc(key);
6499 /* uppercase the key */
6500 for (s = key; (ch = *s) != 0; s++) {
6501 if (islower((int)ch))
6502 *s = (char)toupper(ch);
6505 subsec_name = strchr(key, ':');
6509 *subsec_name = '\0';
6512 /* convert subsec_type '-' to '_' */
6513 for (s = subsec_type; (ch = *s) != 0; s++) {
6514 if (*s == '-') *s = '_';
6517 subsec_key = strchr(subsec_name,':');
6518 if(!subsec_key) goto out; /* failure */
6523 /* convert subsec_key '-' to '_' */
6524 for (s = subsec_key; (ch = *s) != 0; s++) {
6525 if (*s == '-') *s = '_';
6528 /* If the keyword doesn't exist, there's no need to look up the
6529 * subsection -- we know it's invalid */
6530 for(kt = keytable; kt->token != CONF_UNKNOWN; kt++) {
6531 if(kt->keyword && strcmp(kt->keyword, subsec_key) == 0)
6534 if(kt->token == CONF_UNKNOWN) goto out;
6536 /* Otherwise, figure out which kind of subsection we're dealing with,
6537 * and parse against that. */
6538 if (strcmp(subsec_type, "TAPETYPE") == 0) {
6539 tp = lookup_tapetype(subsec_name);
6541 for(np = tapetype_var; np->token != CONF_UNKNOWN; np++) {
6542 if(np->token == kt->token)
6545 if (np->token == CONF_UNKNOWN) goto out;
6547 if (val) *val = &tp->value[np->parm];
6548 if (parm) *parm = np;
6550 } else if (strcmp(subsec_type, "DUMPTYPE") == 0) {
6551 dp = lookup_dumptype(subsec_name);
6553 for(np = dumptype_var; np->token != CONF_UNKNOWN; np++) {
6554 if(np->token == kt->token)
6557 if (np->token == CONF_UNKNOWN) goto out;
6559 if (val) *val = &dp->value[np->parm];
6560 if (parm) *parm = np;
6562 } else if (strcmp(subsec_type, "HOLDINGDISK") == 0) {
6563 hp = lookup_holdingdisk(subsec_name);
6565 for(np = holding_var; np->token != CONF_UNKNOWN; np++) {
6566 if(np->token == kt->token)
6569 if (np->token == CONF_UNKNOWN) goto out;
6571 if (val) *val = &hp->value[np->parm];
6572 if (parm) *parm = np;
6574 } else if (strcmp(subsec_type, "INTERFACE") == 0) {
6575 ip = lookup_interface(subsec_name);
6577 for(np = interface_var; np->token != CONF_UNKNOWN; np++) {
6578 if(np->token == kt->token)
6581 if (np->token == CONF_UNKNOWN) goto out;
6583 if (val) *val = &ip->value[np->parm];
6584 if (parm) *parm = np;
6586 } else if (strcmp(subsec_type, "APPLICATION_TOOL") == 0) {
6587 ap = lookup_application(subsec_name);
6589 for(np = application_var; np->token != CONF_UNKNOWN; np++) {
6590 if(np->token == kt->token)
6593 if (np->token == CONF_UNKNOWN) goto out;
6595 if (val) *val = &ap->value[np->parm];
6596 if (parm) *parm = np;
6598 } else if (strcmp(subsec_type, "SCRIPT_TOOL") == 0) {
6599 pp = lookup_pp_script(subsec_name);
6601 for(np = pp_script_var; np->token != CONF_UNKNOWN; np++) {
6602 if(np->token == kt->token)
6605 if (np->token == CONF_UNKNOWN) goto out;
6607 if (val) *val = &pp->value[np->parm];
6608 if (parm) *parm = np;
6610 } else if (strcmp(subsec_type, "DEVICE") == 0) {
6611 dc = lookup_device_config(subsec_name);
6613 for(np = device_config_var; np->token != CONF_UNKNOWN; np++) {
6614 if(np->token == kt->token)
6617 if (np->token == CONF_UNKNOWN) goto out;
6619 if (val) *val = &dc->value[np->parm];
6620 if (parm) *parm = np;
6622 } else if (strcmp(subsec_type, "CHANGER") == 0) {
6623 cc = lookup_changer_config(subsec_name);
6625 for(np = changer_config_var; np->token != CONF_UNKNOWN; np++) {
6626 if(np->token == kt->token)
6629 if (np->token == CONF_UNKNOWN) goto out;
6631 if (val) *val = &cc->value[np->parm];
6632 if (parm) *parm = np;
6636 /* No delimiters -- we're referencing a global config parameter */
6638 /* convert key '-' to '_' */
6639 for (s = key; (ch = *s) != 0; s++) {
6640 if (*s == '-') *s = '_';
6643 /* look up the keyword */
6644 for(kt = keytable; kt->token != CONF_UNKNOWN; kt++) {
6645 if(kt->keyword && strcmp(kt->keyword, key) == 0)
6648 if(kt->token == CONF_UNKNOWN) goto out;
6650 /* and then look that up in the parse table */
6651 for(np = parsetable; np->token != CONF_UNKNOWN; np++) {
6652 if(np->token == kt->token)
6655 if(np->token == CONF_UNKNOWN) goto out;
6657 if (val) *val = &conf_data[np->parm];
6658 if (parm) *parm = np;
6671 keytab_t * table_entry;
6673 str = g_strdup(str);
6681 for (table_entry = numb_keytable; table_entry->keyword != NULL;
6683 if (strcasecmp(str, table_entry->keyword) == 0) {
6685 switch (table_entry->token) {
6691 return 1024*1024*1024;
6694 case CONF_AMINFINITY:
6700 /* Should not happen. */
6706 /* None found; this is an error. */
6712 * Error Handling Implementaiton
6715 void config_add_error(
6716 cfgerr_level_t level,
6719 cfgerr_level = max(cfgerr_level, level);
6721 g_debug("%s", errmsg);
6722 cfgerr_errors = g_slist_append(cfgerr_errors, errmsg);
6725 static void conf_error_common(
6726 cfgerr_level_t level,
6727 const char * format,
6730 char *msg = g_strdup_vprintf(format, argp);
6731 char *errstr = NULL;
6734 errstr = g_strdup_printf(_("argument \"%s\": %s"),
6736 else if (current_filename && current_line_num > 0)
6737 errstr = g_strdup_printf(_("\"%s\", line %d: %s"),
6738 current_filename, current_line_num, msg);
6740 errstr = g_strdup_printf(_("parse error: %s"), msg);
6743 config_add_error(level, errstr);
6746 printf_arglist_function(void conf_parserror, const char *, format)
6750 arglist_start(argp, format);
6751 conf_error_common(CFGERR_ERRORS, format, argp);
6755 printf_arglist_function(void conf_parswarn, const char *, format) {
6758 arglist_start(argp, format);
6759 conf_error_common(CFGERR_WARNINGS, format, argp);
6764 config_errors(GSList **errstr)
6767 *errstr = cfgerr_errors;
6768 return cfgerr_level;
6772 config_clear_errors(void)
6774 g_slist_free_full(cfgerr_errors);
6776 cfgerr_errors = NULL;
6777 cfgerr_level = CFGERR_OK;
6781 config_print_errors(void)
6785 for (iter = cfgerr_errors; iter; iter = g_slist_next(iter)) {
6786 g_fprintf(stderr, "%s\n", (char *)iter->data);
6790 /* Get the config name */
6791 char *get_config_name(void)
6796 /* Get the config directory */
6797 char *get_config_dir(void)
6802 /* Get the config filename */
6803 char *get_config_filename(void)
6805 return config_filename;
6809 property_argv_size(proplist_t proplist) {
6813 g_hash_table_foreach(proplist, &count_proplist, &nb);
6818 property_add_to_argv(
6820 proplist_t proplist)
6822 char **argv = argvchild;
6824 g_hash_table_foreach(proplist, &proplist_add_to_argv, &argv);
6825 return (argv - argvchild);
6829 anonymous_value(void)
6831 static char number[NUM_STR_SIZE];
6834 g_snprintf(number, sizeof(number), "%d", value);