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
43 /* This module implements its own quixotic lexer and parser, present for historical
44 * reasons. If this were written from scratch, it would use flex/bison. */
46 /* An enumeration of the various tokens that might appear in a configuration file.
48 * - CONF_UNKNOWN has special meaning as an unrecognized token.
49 * - CONF_ANY can be used to request any token, rather than requiring a specific
53 CONF_UNKNOWN, CONF_ANY, CONF_COMMA,
54 CONF_LBRACE, CONF_RBRACE, CONF_NL,
55 CONF_END, CONF_IDENT, CONF_INT,
56 CONF_AM64, CONF_BOOL, CONF_REAL,
57 CONF_STRING, CONF_TIME, CONF_SIZE,
59 /* config parameters */
60 CONF_INCLUDEFILE, CONF_ORG, CONF_MAILTO,
61 CONF_DUMPUSER, CONF_TAPECYCLE, CONF_TAPEDEV,
62 CONF_CHANGERDEV, CONF_CHANGERFILE, CONF_LABELSTR,
63 CONF_BUMPPERCENT, CONF_BUMPSIZE, CONF_BUMPDAYS,
64 CONF_BUMPMULT, CONF_ETIMEOUT, CONF_DTIMEOUT,
65 CONF_CTIMEOUT, CONF_TAPEBUFS, CONF_TAPELIST,
66 CONF_DEVICE_OUTPUT_BUFFER_SIZE,
67 CONF_DISKFILE, CONF_INFOFILE, CONF_LOGDIR,
68 CONF_LOGFILE, CONF_DISKDIR, CONF_DISKSIZE,
69 CONF_INDEXDIR, CONF_NETUSAGE, CONF_INPARALLEL,
70 CONF_DUMPORDER, CONF_TIMEOUT, CONF_TPCHANGER,
71 CONF_RUNTAPES, CONF_DEFINE, CONF_DUMPTYPE,
72 CONF_TAPETYPE, CONF_INTERFACE, CONF_PRINTER,
73 CONF_AUTOFLUSH, CONF_RESERVE, CONF_MAXDUMPSIZE,
74 CONF_COLUMNSPEC, CONF_AMRECOVER_DO_FSF, CONF_AMRECOVER_CHECK_LABEL,
75 CONF_AMRECOVER_CHANGER, CONF_LABEL_NEW_TAPES, CONF_USETIMESTAMPS,
77 CONF_TAPERALGO, CONF_FIRST, CONF_FIRSTFIT,
78 CONF_LARGEST, CONF_LARGESTFIT, CONF_SMALLEST,
79 CONF_LAST, CONF_DISPLAYUNIT, CONF_RESERVED_UDP_PORT,
80 CONF_RESERVED_TCP_PORT, CONF_UNRESERVED_TCP_PORT,
82 CONF_FLUSH_THRESHOLD_DUMPED,
83 CONF_FLUSH_THRESHOLD_SCHEDULED,
87 CONF_KRB5KEYTAB, CONF_KRB5PRINCIPAL,
90 CONF_COMMENT, CONF_DIRECTORY, CONF_USE,
94 /*COMMENT,*/ CONF_PROGRAM, CONF_DUMPCYCLE,
95 CONF_RUNSPERCYCLE, CONF_MAXCYCLE, CONF_MAXDUMPS,
96 CONF_OPTIONS, CONF_PRIORITY, CONF_FREQUENCY,
97 CONF_INDEX, CONF_MAXPROMOTEDAY, CONF_STARTTIME,
98 CONF_COMPRESS, CONF_ENCRYPT, CONF_AUTH,
99 CONF_STRATEGY, CONF_ESTIMATE, CONF_SKIP_INCR,
100 CONF_SKIP_FULL, CONF_RECORD, CONF_HOLDING,
101 CONF_EXCLUDE, CONF_INCLUDE, CONF_KENCRYPT,
102 CONF_IGNORE, CONF_COMPRATE, CONF_TAPE_SPLITSIZE,
103 CONF_SPLIT_DISKBUFFER, CONF_FALLBACK_SPLITSIZE,CONF_SRVCOMPPROG,
104 CONF_CLNTCOMPPROG, CONF_SRV_ENCRYPT, CONF_CLNT_ENCRYPT,
105 CONF_SRV_DECRYPT_OPT, CONF_CLNT_DECRYPT_OPT, CONF_AMANDAD_PATH,
106 CONF_CLIENT_USERNAME,
109 /*COMMENT,*/ CONF_BLOCKSIZE, CONF_FILE_PAD,
110 CONF_LBL_TEMPL, CONF_FILEMARK, CONF_LENGTH,
111 CONF_SPEED, CONF_READBLOCKSIZE,
114 CONF_CONF, CONF_INDEX_SERVER, CONF_TAPE_SERVER,
115 CONF_SSH_KEYS, CONF_GNUTAR_LIST_DIR, CONF_AMANDATES,
117 /* protocol config */
118 CONF_REP_TRIES, CONF_CONNECT_TRIES, CONF_REQ_TRIES,
121 CONF_DEBUG_AMANDAD, CONF_DEBUG_AMIDXTAPED, CONF_DEBUG_AMINDEXD,
122 CONF_DEBUG_AMRECOVER, CONF_DEBUG_AUTH, CONF_DEBUG_EVENT,
123 CONF_DEBUG_HOLDING, CONF_DEBUG_PROTOCOL, CONF_DEBUG_PLANNER,
124 CONF_DEBUG_DRIVER, CONF_DEBUG_DUMPER, CONF_DEBUG_CHUNKER,
125 CONF_DEBUG_TAPER, CONF_DEBUG_SELFCHECK, CONF_DEBUG_SENDSIZE,
126 CONF_DEBUG_SENDBACKUP,
128 /* network interface */
129 /* COMMENT, */ /* USE, */
131 /* dump options (obsolete) */
132 CONF_EXCLUDE_FILE, CONF_EXCLUDE_LIST,
134 /* compress, estimate, encryption */
135 CONF_NONE, CONF_FAST, CONF_BEST,
136 CONF_SERVER, CONF_CLIENT, CONF_CALCSIZE,
140 CONF_NEVER, CONF_AUTO, CONF_REQUIRED,
143 CONF_LOW, CONF_MEDIUM, CONF_HIGH,
146 CONF_SKIP, CONF_STANDARD, CONF_NOFULL,
147 CONF_NOINC, CONF_HANOI, CONF_INCRONLY,
150 CONF_LIST, CONF_EFILE, CONF_APPEND,
154 CONF_AMINFINITY, CONF_MULT1, CONF_MULT7,
155 CONF_MULT1K, CONF_MULT1M, CONF_MULT1G,
158 CONF_ATRUE, CONF_AFALSE
161 /* A keyword table entry, mapping the given keyword to the given token.
162 * Note that punctuation, integers, and quoted strings are handled
163 * internally to the lexer, so they do not appear here. */
169 /* The current keyword table, used by all token-related functions */
170 static keytab_t *keytable = NULL;
172 /* Has a token been "ungotten", and if so, what was it? */
173 static int token_pushed;
174 static tok_t pushed_tok;
176 /* The current token and its value. Note that, unlike most other val_t*,
177 * tokenval's v.s points to statically allocated memory which cannot be
180 static val_t tokenval;
182 /* The current input information: file, filename, line, and character
183 * (which points somewhere within current_line) */
184 static FILE *current_file = NULL;
185 static char *current_filename = NULL;
186 static char *current_line = NULL;
187 static char *current_char = NULL;
188 static int current_line_num = 0; /* (technically, managed by the parser) */
190 /* A static buffer for storing tokens while they are being scanned. */
191 static char tkbuf[4096];
193 /* Look up the name of the given token in the current keytable */
194 static char *get_token_name(tok_t);
196 /* Look up a token in keytable, given a string, returning CONF_UNKNOWN
197 * for unrecognized strings. Search is case-insensitive. */
198 static tok_t lookup_keyword(char *str);
200 /* Get the next token. If exp is anything but CONF_ANY, and the next token
201 * does not match, then a parse error is flagged. This function reads from the
202 * current_* static variables, recognizes keywords against the keytable static
203 * variable, and places its result in tok and tokenval. */
204 static void get_conftoken(tok_t exp);
206 /* "Unget" the current token; this supports a 1-token lookahead. */
207 static void unget_conftoken(void);
209 /* Tokenizer character-by-character access. */
210 static int conftoken_getc(void);
211 static int conftoken_ungetc(int c);
217 /* A parser table entry. Read as "<token> introduces parameter <parm>,
218 * the data for which will be read by <read_function> and validated by
219 * <validate_function> (if not NULL). <type> is only used in formatting
220 * config overwrites. */
221 typedef struct conf_var_s {
224 void (*read_function) (struct conf_var_s *, val_t*);
226 void (*validate_function) (struct conf_var_s *, val_t *);
229 /* If allow_overwrites is true, the a parameter which has already been
230 * seen will simply overwrite the old value, rather than triggering an
231 * error. Note that this does not apply to all parameters, e.g.,
233 static int allow_overwrites;
235 /* subsection structs
237 * The 'seen' fields in these structs are useless outside this module;
238 * they are only used to generate error messages for multiply defined
242 struct tapetype_s *next;
246 val_t value[TAPETYPE_TAPETYPE];
250 struct dumptype_s *next;
254 val_t value[DUMPTYPE_DUMPTYPE];
258 struct interface_s *next;
262 val_t value[INTER_INTER];
265 struct holdingdisk_s {
266 struct holdingdisk_s *next;
270 val_t value[HOLDING_HOLDING];
273 /* The current parser table */
274 static conf_var_t *parsetable = NULL;
276 /* Read and parse a configuration file, recursively reading any included
277 * files. This function sets the keytable and parsetable appropriately
278 * according to is_client.
280 * @param filename: configuration file to read
281 * @param is_client: true if this is a client
282 * @returns: false if an error occurred
284 static gboolean read_conffile(char *filename,
287 /* Read and process a line of input from the current file, using the
288 * current keytable and parsetable. For blocks, this recursively
289 * reads the entire block.
291 * @param is_client: true if this is a client
292 * @returns: true on success, false on EOF or error
294 static gboolean read_confline(gboolean is_client);
296 /* Handle an invalid token, by issuing a warning or an error, depending
297 * on how long the token has been deprecated.
299 * @param token: the identifier
301 static void handle_invalid_keyword(const char * token);
303 /* Read a brace-delimited block using the given parse table. This
304 * function is used to read brace-delimited subsections in the config
305 * files and also (via read_dumptype) to read dumptypes from
308 * This function implements "inheritance" as follows: if a bare
309 * identifier occurs within the braces, it calls copy_function (if
310 * not NULL), which looks up an existing subsection using the
311 * identifier from tokenval and copies any values not already seen
314 * @param read_var: the parse table to use
315 * @param valarray: the (pre-initialized) val_t array to fill in
316 * @param errormsg: error message to display for unrecognized keywords
317 * @param read_brace: if true, read the opening brace
318 * @param copy_function: function to copy configuration from
319 * another subsection into this one.
321 static void read_block(conf_var_t *read_var, val_t *valarray,
322 char *errormsg, int read_brace,
323 void (*copy_function)(void));
325 /* For each subsection type, we have a global and four functions:
326 * - foocur is a temporary struct used to assemble new subsections
327 * - get_foo is called after reading "DEFINE FOO", and
328 * is responsible for reading the entire block, using
330 * - init_foo_defaults initializes a new subsection struct
331 * to its default values
332 * - save_foo copies foocur to a newly allocated struct and
333 * inserts that into the relevant list.
334 * - copy_foo implements inheritance as described in read_block()
336 static holdingdisk_t hdcur;
337 static void get_holdingdisk(void);
338 static void init_holdingdisk_defaults(void);
339 static void save_holdingdisk(void);
340 /* (holdingdisks don't support inheritance) */
342 static dumptype_t dpcur;
343 static void get_dumptype(void);
344 static void init_dumptype_defaults(void);
345 static void save_dumptype(void);
346 static void copy_dumptype(void);
348 static tapetype_t tpcur;
349 static void get_tapetype(void);
350 static void init_tapetype_defaults(void);
351 static void save_tapetype(void);
352 static void copy_tapetype(void);
354 static interface_t ifcur;
355 static void get_interface(void);
356 static void init_interface_defaults(void);
357 static void save_interface(void);
358 static void copy_interface(void);
360 /* read_functions -- these fit into the read_function slot in a parser
361 * table entry, and are responsible for calling getconf_token as necessary
362 * to consume their arguments, and setting their second argument with the
363 * result. The first argument is a copy of the parser table entry, if
365 static void read_int(conf_var_t *, val_t *);
366 static void read_am64(conf_var_t *, val_t *);
367 static void read_real(conf_var_t *, val_t *);
368 static void read_str(conf_var_t *, val_t *);
369 static void read_ident(conf_var_t *, val_t *);
370 static void read_time(conf_var_t *, val_t *);
371 static void read_size(conf_var_t *, val_t *);
372 static void read_bool(conf_var_t *, val_t *);
373 static void read_compress(conf_var_t *, val_t *);
374 static void read_encrypt(conf_var_t *, val_t *);
375 static void read_holding(conf_var_t *, val_t *);
376 static void read_estimate(conf_var_t *, val_t *);
377 static void read_strategy(conf_var_t *, val_t *);
378 static void read_taperalgo(conf_var_t *, val_t *);
379 static void read_priority(conf_var_t *, val_t *);
380 static void read_rate(conf_var_t *, val_t *);
381 static void read_exinclude(conf_var_t *, val_t *);
382 static void read_intrange(conf_var_t *, val_t *);
383 static void read_property(conf_var_t *, val_t *);
385 /* Functions to get various types of values. These are called by
386 * read_functions to take care of any variations in the way that these
387 * values can be written: integers can have units, boolean values can be
388 * specified with a number of names, etc. They form utility functions
389 * for the read_functions, below. */
390 static time_t get_time(void);
391 static int get_int(void);
392 static ssize_t get_size(void);
393 static off_t get_am64_t(void);
394 static int get_bool(void);
396 /* Check the given 'seen', flagging an error if this value has already
397 * been seen and allow_overwrites is false. Also marks the value as
398 * seen on the current line.
400 * @param seen: (in/out) seen value to adjust
402 static void ckseen(int *seen);
404 /* validate_functions -- these fit into the validate_function solt in
405 * a parser table entry. They call conf_parserror if the value in their
406 * second argument is invalid. */
407 static void validate_nonnegative(conf_var_t *, val_t *);
408 static void validate_positive(conf_var_t *, val_t *);
409 static void validate_runspercycle(conf_var_t *, val_t *);
410 static void validate_bumppercent(conf_var_t *, val_t *);
411 static void validate_bumpmult(conf_var_t *, val_t *);
412 static void validate_inparallel(conf_var_t *, val_t *);
413 static void validate_displayunit(conf_var_t *, val_t *);
414 static void validate_reserve(conf_var_t *, val_t *);
415 static void validate_use(conf_var_t *, val_t *);
416 static void validate_chunksize(conf_var_t *, val_t *);
417 static void validate_blocksize(conf_var_t *, val_t *);
418 static void validate_debug(conf_var_t *, val_t *);
419 static void validate_port_range(val_t *, int, int);
420 static void validate_reserved_port_range(conf_var_t *, val_t *);
421 static void validate_unreserved_port_range(conf_var_t *, val_t *);
427 /* Name of the current configuration (part of API) */
428 char *config_name = NULL;
430 /* Current configuration directory (part of API) */
431 char *config_dir = NULL;
433 /* Current toplevel configuration file (part of API) */
434 char *config_filename = NULL;
436 /* Has the config been initialized? */
437 static gboolean config_initialized = FALSE;
439 /* Are we running a client? (true if last init was
440 * with CONFIG_INIT_CLIENT) */
441 static gboolean config_client = FALSE;
443 /* What config overwrites are applied? */
444 static config_overwrites_t *applied_config_overwrites = NULL;
446 /* All global parameters */
447 static val_t conf_data[CNF_CNF];
449 /* Linked list of holding disks */
450 static holdingdisk_t *holdinglist = NULL;
451 static dumptype_t *dumplist = NULL;
452 static tapetype_t *tapelist = NULL;
453 static interface_t *interface_list = NULL;
455 /* storage for derived values */
456 static long int unit_divisor = 1;
458 int debug_amandad = 0;
459 int debug_amidxtaped = 0;
460 int debug_amindexd = 0;
461 int debug_amrecover = 0;
464 int debug_holding = 0;
465 int debug_protocol = 0;
466 int debug_planner = 0;
467 int debug_driver = 0;
468 int debug_dumper = 0;
469 int debug_chunker = 0;
471 int debug_selfcheck = 0;
472 int debug_sendsize = 0;
473 int debug_sendbackup = 0;
475 /* Reset all configuration values to their defaults (which, in many
476 * cases, come from --with-foo options at build time) */
477 static void init_defaults(void);
479 /* Update all dervied values based on the current configuration. This
480 * function can be called multiple times, once after each adjustment
481 * to the current configuration.
483 * @param is_client: are we running a client?
485 static void update_derived_values(gboolean is_client);
487 /* per-type conf_init functions, used as utilities for init_defaults
488 * and for each subsection's init_foo_defaults.
490 * These set the value's type and seen flags, as well as copying
491 * the relevant value into the 'v' field.
493 static void conf_init_int(val_t *val, int i);
494 static void conf_init_am64(val_t *val, off_t l);
495 static void conf_init_real(val_t *val, float r);
496 static void conf_init_str(val_t *val, char *s);
497 static void conf_init_ident(val_t *val, char *s);
498 static void conf_init_time(val_t *val, time_t t);
499 static void conf_init_size(val_t *val, ssize_t sz);
500 static void conf_init_bool(val_t *val, int i);
501 static void conf_init_compress(val_t *val, comp_t i);
502 static void conf_init_encrypt(val_t *val, encrypt_t i);
503 static void conf_init_holding(val_t *val, dump_holdingdisk_t i);
504 static void conf_init_estimate(val_t *val, estimate_t i);
505 static void conf_init_strategy(val_t *val, strategy_t);
506 static void conf_init_taperalgo(val_t *val, taperalgo_t i);
507 static void conf_init_priority(val_t *val, int i);
508 static void conf_init_rate(val_t *val, float r1, float r2);
509 static void conf_init_exinclude(val_t *val); /* to empty list */
510 static void conf_init_intrange(val_t *val, int i1, int i2);
511 static void conf_init_proplist(val_t *val); /* to empty list */
514 * Command-line Handling
517 typedef struct config_overwrite_s {
520 } config_overwrite_t;
522 struct config_overwrites_s {
525 config_overwrite_t *ovr;
532 static void copy_val_t(val_t *, val_t *);
533 static void free_val_t(val_t *);
540 /* Utility functions/structs for val_t_display_strs */
541 static char *exinclude_display_str(val_t *val, int file);
542 static void proplist_display_str_foreach_fn(gpointer key_p, gpointer value_p, gpointer user_data_p);
543 static void val_t_print_token(FILE *output, char *prefix, char *format, keytab_t *kt, val_t *val);
545 /* Given a key name as used in config overwrites, return a pointer to the corresponding
546 * conf_var_t in the current parsetable, and the val_t representing that value. This
547 * function will access subsections if key has the form TYPE:SUBSEC:KEYWORD. Returns
548 * false if the value does not exist.
550 * Assumes keytable and parsetable are set correctly, which is generally OK after
551 * config_init has been called.
553 * @param key: the key to look up
554 * @param parm: (result) the parse table entry
555 * @param val: (result) the parameter value
556 * @returns: true on success
558 static int parm_key_info(char *key, conf_var_t **parm, val_t **val);
564 /* Have we seen a parse error yet? Parsing continues after an error, so this
565 * flag is checked after the parse is complete.
567 static gboolean got_parserror;
569 static void conf_parserror(const char *format, ...)
570 __attribute__ ((format (printf, 1, 2)));
572 static void conf_parswarn(const char *format, ...)
573 __attribute__ ((format (printf, 1, 2)));
579 /* First, the keyword tables for client and server */
580 keytab_t client_keytab[] = {
581 { "CONF", CONF_CONF },
582 { "INDEX_SERVER", CONF_INDEX_SERVER },
583 { "TAPE_SERVER", CONF_TAPE_SERVER },
584 { "TAPEDEV", CONF_TAPEDEV },
585 { "AUTH", CONF_AUTH },
586 { "SSH_KEYS", CONF_SSH_KEYS },
587 { "AMANDAD_PATH", CONF_AMANDAD_PATH },
588 { "CLIENT_USERNAME", CONF_CLIENT_USERNAME },
589 { "GNUTAR_LIST_DIR", CONF_GNUTAR_LIST_DIR },
590 { "AMANDATES", CONF_AMANDATES },
591 { "KRB5KEYTAB", CONF_KRB5KEYTAB },
592 { "KRB5PRINCIPAL", CONF_KRB5PRINCIPAL },
593 { "INCLUDEFILE", CONF_INCLUDEFILE },
594 { "CONNECT_TRIES", CONF_CONNECT_TRIES },
595 { "REP_TRIES", CONF_REP_TRIES },
596 { "REQ_TRIES", CONF_REQ_TRIES },
597 { "DEBUG_AMANDAD", CONF_DEBUG_AMANDAD },
598 { "DEBUG_AMIDXTAPED", CONF_DEBUG_AMIDXTAPED },
599 { "DEBUG_AMINDEXD", CONF_DEBUG_AMINDEXD },
600 { "DEBUG_AMRECOVER", CONF_DEBUG_AMRECOVER },
601 { "DEBUG_AUTH", CONF_DEBUG_AUTH },
602 { "DEBUG_EVENT", CONF_DEBUG_EVENT },
603 { "DEBUG_HOLDING", CONF_DEBUG_HOLDING },
604 { "DEBUG_PROTOCOL", CONF_DEBUG_PROTOCOL },
605 { "DEBUG_PLANNER", CONF_DEBUG_PLANNER },
606 { "DEBUG_DRIVER", CONF_DEBUG_DRIVER },
607 { "DEBUG_DUMPER", CONF_DEBUG_DUMPER },
608 { "DEBUG_CHUNKER", CONF_DEBUG_CHUNKER },
609 { "DEBUG_TAPER", CONF_DEBUG_TAPER },
610 { "DEBUG_SELFCHECK", CONF_DEBUG_SELFCHECK },
611 { "DEBUG_SENDSIZE", CONF_DEBUG_SENDSIZE },
612 { "DEBUG_SENDBACKUP", CONF_DEBUG_SENDBACKUP },
613 { "RESERVED-UDP-PORT", CONF_RESERVED_UDP_PORT },
614 { "RESERVED-TCP-PORT", CONF_RESERVED_TCP_PORT },
615 { "UNRESERVED-TCP-PORT", CONF_UNRESERVED_TCP_PORT },
616 { NULL, CONF_UNKNOWN },
619 keytab_t server_keytab[] = {
620 { "AMANDAD_PATH", CONF_AMANDAD_PATH },
621 { "AMRECOVER_CHANGER", CONF_AMRECOVER_CHANGER },
622 { "AMRECOVER_CHECK_LABEL", CONF_AMRECOVER_CHECK_LABEL },
623 { "AMRECOVER_DO_FSF", CONF_AMRECOVER_DO_FSF },
624 { "APPEND", CONF_APPEND },
625 { "AUTH", CONF_AUTH },
626 { "AUTO", CONF_AUTO },
627 { "AUTOFLUSH", CONF_AUTOFLUSH },
628 { "BEST", CONF_BEST },
629 { "BLOCKSIZE", CONF_BLOCKSIZE },
630 { "BUMPDAYS", CONF_BUMPDAYS },
631 { "BUMPMULT", CONF_BUMPMULT },
632 { "BUMPPERCENT", CONF_BUMPPERCENT },
633 { "BUMPSIZE", CONF_BUMPSIZE },
634 { "CALCSIZE", CONF_CALCSIZE },
635 { "CHANGERDEV", CONF_CHANGERDEV },
636 { "CHANGERFILE", CONF_CHANGERFILE },
637 { "CHUNKSIZE", CONF_CHUNKSIZE },
638 { "CLIENT", CONF_CLIENT },
639 { "CLIENT_CUSTOM_COMPRESS", CONF_CLNTCOMPPROG },
640 { "CLIENT_DECRYPT_OPTION", CONF_CLNT_DECRYPT_OPT },
641 { "CLIENT_ENCRYPT", CONF_CLNT_ENCRYPT },
642 { "CLIENT_USERNAME", CONF_CLIENT_USERNAME },
643 { "COLUMNSPEC", CONF_COLUMNSPEC },
644 { "COMMENT", CONF_COMMENT },
645 { "COMPRATE", CONF_COMPRATE },
646 { "COMPRESS", CONF_COMPRESS },
647 { "CONNECT_TRIES", CONF_CONNECT_TRIES },
648 { "CTIMEOUT", CONF_CTIMEOUT },
649 { "CUSTOM", CONF_CUSTOM },
650 { "DEBUG_AMANDAD" , CONF_DEBUG_AMANDAD },
651 { "DEBUG_AMIDXTAPED" , CONF_DEBUG_AMIDXTAPED },
652 { "DEBUG_AMINDEXD" , CONF_DEBUG_AMINDEXD },
653 { "DEBUG_AMRECOVER" , CONF_DEBUG_AMRECOVER },
654 { "DEBUG_AUTH" , CONF_DEBUG_AUTH },
655 { "DEBUG_EVENT" , CONF_DEBUG_EVENT },
656 { "DEBUG_HOLDING" , CONF_DEBUG_HOLDING },
657 { "DEBUG_PROTOCOL" , CONF_DEBUG_PROTOCOL },
658 { "DEBUG_PLANNER" , CONF_DEBUG_PLANNER },
659 { "DEBUG_DRIVER" , CONF_DEBUG_DRIVER },
660 { "DEBUG_DUMPER" , CONF_DEBUG_DUMPER },
661 { "DEBUG_CHUNKER" , CONF_DEBUG_CHUNKER },
662 { "DEBUG_TAPER" , CONF_DEBUG_TAPER },
663 { "DEBUG_SELFCHECK" , CONF_DEBUG_SELFCHECK },
664 { "DEBUG_SENDSIZE" , CONF_DEBUG_SENDSIZE },
665 { "DEBUG_SENDBACKUP" , CONF_DEBUG_SENDBACKUP },
666 { "DEFINE", CONF_DEFINE },
667 { "DEVICE_PROPERTY", CONF_DEVICE_PROPERTY },
668 { "DIRECTORY", CONF_DIRECTORY },
669 { "DISKFILE", CONF_DISKFILE },
670 { "DISPLAYUNIT", CONF_DISPLAYUNIT },
671 { "DTIMEOUT", CONF_DTIMEOUT },
672 { "DUMPCYCLE", CONF_DUMPCYCLE },
673 { "DUMPORDER", CONF_DUMPORDER },
674 { "DUMPTYPE", CONF_DUMPTYPE },
675 { "DUMPUSER", CONF_DUMPUSER },
676 { "ENCRYPT", CONF_ENCRYPT },
677 { "ESTIMATE", CONF_ESTIMATE },
678 { "ETIMEOUT", CONF_ETIMEOUT },
679 { "EXCLUDE", CONF_EXCLUDE },
680 { "EXCLUDE-FILE", CONF_EXCLUDE_FILE },
681 { "EXCLUDE-LIST", CONF_EXCLUDE_LIST },
682 { "FALLBACK_SPLITSIZE", CONF_FALLBACK_SPLITSIZE },
683 { "FAST", CONF_FAST },
684 { "FILE", CONF_EFILE },
685 { "FILE-PAD", CONF_FILE_PAD },
686 { "FILEMARK", CONF_FILEMARK },
687 { "FIRST", CONF_FIRST },
688 { "FIRSTFIT", CONF_FIRSTFIT },
689 { "HANOI", CONF_HANOI },
690 { "HIGH", CONF_HIGH },
691 { "HOLDINGDISK", CONF_HOLDING },
692 { "IGNORE", CONF_IGNORE },
693 { "INCLUDE", CONF_INCLUDE },
694 { "INCLUDEFILE", CONF_INCLUDEFILE },
695 { "INCRONLY", CONF_INCRONLY },
696 { "INDEX", CONF_INDEX },
697 { "INDEXDIR", CONF_INDEXDIR },
698 { "INFOFILE", CONF_INFOFILE },
699 { "INPARALLEL", CONF_INPARALLEL },
700 { "INTERFACE", CONF_INTERFACE },
701 { "KENCRYPT", CONF_KENCRYPT },
702 { "KRB5KEYTAB", CONF_KRB5KEYTAB },
703 { "KRB5PRINCIPAL", CONF_KRB5PRINCIPAL },
704 { "LABELSTR", CONF_LABELSTR },
705 { "LABEL_NEW_TAPES", CONF_LABEL_NEW_TAPES },
706 { "LARGEST", CONF_LARGEST },
707 { "LARGESTFIT", CONF_LARGESTFIT },
708 { "LAST", CONF_LAST },
709 { "LBL-TEMPL", CONF_LBL_TEMPL },
710 { "LENGTH", CONF_LENGTH },
711 { "LIST", CONF_LIST },
712 { "LOGDIR", CONF_LOGDIR },
714 { "MAILTO", CONF_MAILTO },
715 { "READBLOCKSIZE", CONF_READBLOCKSIZE },
716 { "MAXDUMPS", CONF_MAXDUMPS },
717 { "MAXDUMPSIZE", CONF_MAXDUMPSIZE },
718 { "MAXPROMOTEDAY", CONF_MAXPROMOTEDAY },
719 { "MEDIUM", CONF_MEDIUM },
720 { "NETUSAGE", CONF_NETUSAGE },
721 { "NEVER", CONF_NEVER },
722 { "NOFULL", CONF_NOFULL },
723 { "NOINC", CONF_NOINC },
724 { "NONE", CONF_NONE },
725 { "OPTIONAL", CONF_OPTIONAL },
727 { "PRINTER", CONF_PRINTER },
728 { "PRIORITY", CONF_PRIORITY },
729 { "PROGRAM", CONF_PROGRAM },
730 { "RECORD", CONF_RECORD },
731 { "REP_TRIES", CONF_REP_TRIES },
732 { "REQ_TRIES", CONF_REQ_TRIES },
733 { "REQUIRED", CONF_REQUIRED },
734 { "RESERVE", CONF_RESERVE },
735 { "RESERVED-UDP-PORT", CONF_RESERVED_UDP_PORT },
736 { "RESERVED-TCP-PORT", CONF_RESERVED_TCP_PORT },
737 { "RUNSPERCYCLE", CONF_RUNSPERCYCLE },
738 { "RUNTAPES", CONF_RUNTAPES },
739 { "SERVER", CONF_SERVER },
740 { "SERVER_CUSTOM_COMPRESS", CONF_SRVCOMPPROG },
741 { "SERVER_DECRYPT_OPTION", CONF_SRV_DECRYPT_OPT },
742 { "SERVER_ENCRYPT", CONF_SRV_ENCRYPT },
743 { "SKIP", CONF_SKIP },
744 { "SKIP-FULL", CONF_SKIP_FULL },
745 { "SKIP-INCR", CONF_SKIP_INCR },
746 { "SMALLEST", CONF_SMALLEST },
747 { "SPEED", CONF_SPEED },
748 { "SPLIT_DISKBUFFER", CONF_SPLIT_DISKBUFFER },
749 { "SSH_KEYS", CONF_SSH_KEYS },
750 { "STANDARD", CONF_STANDARD },
751 { "STARTTIME", CONF_STARTTIME },
752 { "STRATEGY", CONF_STRATEGY },
753 { "TAPEBUFS", CONF_TAPEBUFS },
754 { "DEVICE_OUTPUT_BUFFER_SIZE", CONF_DEVICE_OUTPUT_BUFFER_SIZE },
755 { "TAPECYCLE", CONF_TAPECYCLE },
756 { "TAPEDEV", CONF_TAPEDEV },
757 { "TAPELIST", CONF_TAPELIST },
758 { "TAPERALGO", CONF_TAPERALGO },
759 { "FLUSH-THRESHOLD-DUMPED", CONF_FLUSH_THRESHOLD_DUMPED },
760 { "FLUSH-THRESHOLD-SCHEDULED", CONF_FLUSH_THRESHOLD_SCHEDULED },
761 { "TAPERFLUSH", CONF_TAPERFLUSH },
762 { "TAPETYPE", CONF_TAPETYPE },
763 { "TAPE_SPLITSIZE", CONF_TAPE_SPLITSIZE },
764 { "TPCHANGER", CONF_TPCHANGER },
765 { "UNRESERVED-TCP-PORT", CONF_UNRESERVED_TCP_PORT },
767 { "USETIMESTAMPS", CONF_USETIMESTAMPS },
768 { NULL, CONF_IDENT },
769 { NULL, CONF_UNKNOWN }
772 /* A keyword table for recognizing unit suffixes. No distinction is made for kinds
773 * of suffixes: 1024 weeks = 7 k. */
774 keytab_t numb_keytable[] = {
776 { "BPS", CONF_MULT1 },
777 { "BYTE", CONF_MULT1 },
778 { "BYTES", CONF_MULT1 },
779 { "DAY", CONF_MULT1 },
780 { "DAYS", CONF_MULT1 },
781 { "INF", CONF_AMINFINITY },
782 { "K", CONF_MULT1K },
783 { "KB", CONF_MULT1K },
784 { "KBPS", CONF_MULT1K },
785 { "KBYTE", CONF_MULT1K },
786 { "KBYTES", CONF_MULT1K },
787 { "KILOBYTE", CONF_MULT1K },
788 { "KILOBYTES", CONF_MULT1K },
789 { "KPS", CONF_MULT1K },
790 { "M", CONF_MULT1M },
791 { "MB", CONF_MULT1M },
792 { "MBPS", CONF_MULT1M },
793 { "MBYTE", CONF_MULT1M },
794 { "MBYTES", CONF_MULT1M },
795 { "MEG", CONF_MULT1M },
796 { "MEGABYTE", CONF_MULT1M },
797 { "MEGABYTES", CONF_MULT1M },
798 { "G", CONF_MULT1G },
799 { "GB", CONF_MULT1G },
800 { "GBPS", CONF_MULT1G },
801 { "GBYTE", CONF_MULT1G },
802 { "GBYTES", CONF_MULT1G },
803 { "GIG", CONF_MULT1G },
804 { "GIGABYTE", CONF_MULT1G },
805 { "GIGABYTES", CONF_MULT1G },
806 { "MPS", CONF_MULT1M },
807 { "TAPE", CONF_MULT1 },
808 { "TAPES", CONF_MULT1 },
809 { "WEEK", CONF_MULT7 },
810 { "WEEKS", CONF_MULT7 },
814 /* Boolean keywords -- all the ways to say "true" and "false" in amanda.conf */
815 keytab_t bool_keytable[] = {
817 { "YES", CONF_ATRUE },
819 { "TRUE", CONF_ATRUE },
820 { "ON", CONF_ATRUE },
821 { "N", CONF_AFALSE },
822 { "NO", CONF_AFALSE },
823 { "F", CONF_AFALSE },
824 { "FALSE", CONF_AFALSE },
825 { "OFF", CONF_AFALSE },
829 /* Now, the parser tables for client and server global parameters, and for
830 * each of the server subsections */
831 conf_var_t client_var [] = {
832 { CONF_CONF , CONFTYPE_STR , read_str , CNF_CONF , NULL },
833 { CONF_INDEX_SERVER , CONFTYPE_STR , read_str , CNF_INDEX_SERVER , NULL },
834 { CONF_TAPE_SERVER , CONFTYPE_STR , read_str , CNF_TAPE_SERVER , NULL },
835 { CONF_TAPEDEV , CONFTYPE_STR , read_str , CNF_TAPEDEV , NULL },
836 { CONF_AUTH , CONFTYPE_STR , read_str , CNF_AUTH , NULL },
837 { CONF_SSH_KEYS , CONFTYPE_STR , read_str , CNF_SSH_KEYS , NULL },
838 { CONF_AMANDAD_PATH , CONFTYPE_STR , read_str , CNF_AMANDAD_PATH , NULL },
839 { CONF_CLIENT_USERNAME , CONFTYPE_STR , read_str , CNF_CLIENT_USERNAME , NULL },
840 { CONF_GNUTAR_LIST_DIR , CONFTYPE_STR , read_str , CNF_GNUTAR_LIST_DIR , NULL },
841 { CONF_AMANDATES , CONFTYPE_STR , read_str , CNF_AMANDATES , NULL },
842 { CONF_KRB5KEYTAB , CONFTYPE_STR , read_str , CNF_KRB5KEYTAB , NULL },
843 { CONF_KRB5PRINCIPAL , CONFTYPE_STR , read_str , CNF_KRB5PRINCIPAL , NULL },
844 { CONF_CONNECT_TRIES , CONFTYPE_INT , read_int , CNF_CONNECT_TRIES , validate_positive },
845 { CONF_REP_TRIES , CONFTYPE_INT , read_int , CNF_REP_TRIES , validate_positive },
846 { CONF_REQ_TRIES , CONFTYPE_INT , read_int , CNF_REQ_TRIES , validate_positive },
847 { CONF_DEBUG_AMANDAD , CONFTYPE_INT , read_int , CNF_DEBUG_AMANDAD , validate_debug },
848 { CONF_DEBUG_AMIDXTAPED , CONFTYPE_INT , read_int , CNF_DEBUG_AMIDXTAPED , validate_debug },
849 { CONF_DEBUG_AMINDEXD , CONFTYPE_INT , read_int , CNF_DEBUG_AMINDEXD , validate_debug },
850 { CONF_DEBUG_AMRECOVER , CONFTYPE_INT , read_int , CNF_DEBUG_AMRECOVER , validate_debug },
851 { CONF_DEBUG_AUTH , CONFTYPE_INT , read_int , CNF_DEBUG_AUTH , validate_debug },
852 { CONF_DEBUG_EVENT , CONFTYPE_INT , read_int , CNF_DEBUG_EVENT , validate_debug },
853 { CONF_DEBUG_HOLDING , CONFTYPE_INT , read_int , CNF_DEBUG_HOLDING , validate_debug },
854 { CONF_DEBUG_PROTOCOL , CONFTYPE_INT , read_int , CNF_DEBUG_PROTOCOL , validate_debug },
855 { CONF_DEBUG_PLANNER , CONFTYPE_INT , read_int , CNF_DEBUG_PLANNER , validate_debug },
856 { CONF_DEBUG_DRIVER , CONFTYPE_INT , read_int , CNF_DEBUG_DRIVER , validate_debug },
857 { CONF_DEBUG_DUMPER , CONFTYPE_INT , read_int , CNF_DEBUG_DUMPER , validate_debug },
858 { CONF_DEBUG_CHUNKER , CONFTYPE_INT , read_int , CNF_DEBUG_CHUNKER , validate_debug },
859 { CONF_DEBUG_TAPER , CONFTYPE_INT , read_int , CNF_DEBUG_TAPER , validate_debug },
860 { CONF_DEBUG_SELFCHECK , CONFTYPE_INT , read_int , CNF_DEBUG_SELFCHECK , validate_debug },
861 { CONF_DEBUG_SENDSIZE , CONFTYPE_INT , read_int , CNF_DEBUG_SENDSIZE , validate_debug },
862 { CONF_DEBUG_SENDBACKUP , CONFTYPE_INT , read_int , CNF_DEBUG_SENDBACKUP , validate_debug },
863 { CONF_RESERVED_UDP_PORT , CONFTYPE_INTRANGE, read_intrange, CNF_RESERVED_UDP_PORT , validate_reserved_port_range },
864 { CONF_RESERVED_TCP_PORT , CONFTYPE_INTRANGE, read_intrange, CNF_RESERVED_TCP_PORT , validate_reserved_port_range },
865 { CONF_UNRESERVED_TCP_PORT, CONFTYPE_INTRANGE, read_intrange, CNF_UNRESERVED_TCP_PORT, validate_unreserved_port_range },
866 { CONF_UNKNOWN , CONFTYPE_INT , NULL , CNF_CNF , NULL }
869 conf_var_t server_var [] = {
870 { CONF_ORG , CONFTYPE_STR , read_str , CNF_ORG , NULL },
871 { CONF_MAILTO , CONFTYPE_STR , read_str , CNF_MAILTO , NULL },
872 { CONF_DUMPUSER , CONFTYPE_STR , read_str , CNF_DUMPUSER , NULL },
873 { CONF_PRINTER , CONFTYPE_STR , read_str , CNF_PRINTER , NULL },
874 { CONF_TAPEDEV , CONFTYPE_STR , read_str , CNF_TAPEDEV , NULL },
875 { CONF_DEVICE_PROPERTY , CONFTYPE_PROPLIST , read_property , CNF_DEVICE_PROPERTY , NULL },
876 { CONF_TPCHANGER , CONFTYPE_STR , read_str , CNF_TPCHANGER , NULL },
877 { CONF_CHANGERDEV , CONFTYPE_STR , read_str , CNF_CHANGERDEV , NULL },
878 { CONF_CHANGERFILE , CONFTYPE_STR , read_str , CNF_CHANGERFILE , NULL },
879 { CONF_LABELSTR , CONFTYPE_STR , read_str , CNF_LABELSTR , NULL },
880 { CONF_TAPELIST , CONFTYPE_STR , read_str , CNF_TAPELIST , NULL },
881 { CONF_DISKFILE , CONFTYPE_STR , read_str , CNF_DISKFILE , NULL },
882 { CONF_INFOFILE , CONFTYPE_STR , read_str , CNF_INFOFILE , NULL },
883 { CONF_LOGDIR , CONFTYPE_STR , read_str , CNF_LOGDIR , NULL },
884 { CONF_INDEXDIR , CONFTYPE_STR , read_str , CNF_INDEXDIR , NULL },
885 { CONF_TAPETYPE , CONFTYPE_IDENT , read_ident , CNF_TAPETYPE , NULL },
886 { CONF_DUMPCYCLE , CONFTYPE_INT , read_int , CNF_DUMPCYCLE , validate_nonnegative },
887 { CONF_RUNSPERCYCLE , CONFTYPE_INT , read_int , CNF_RUNSPERCYCLE , validate_runspercycle },
888 { CONF_RUNTAPES , CONFTYPE_INT , read_int , CNF_RUNTAPES , validate_nonnegative },
889 { CONF_TAPECYCLE , CONFTYPE_INT , read_int , CNF_TAPECYCLE , validate_positive },
890 { CONF_BUMPDAYS , CONFTYPE_INT , read_int , CNF_BUMPDAYS , validate_positive },
891 { CONF_BUMPSIZE , CONFTYPE_AM64 , read_am64 , CNF_BUMPSIZE , validate_positive },
892 { CONF_BUMPPERCENT , CONFTYPE_INT , read_int , CNF_BUMPPERCENT , validate_bumppercent },
893 { CONF_BUMPMULT , CONFTYPE_REAL , read_real , CNF_BUMPMULT , validate_bumpmult },
894 { CONF_NETUSAGE , CONFTYPE_INT , read_int , CNF_NETUSAGE , validate_positive },
895 { CONF_INPARALLEL , CONFTYPE_INT , read_int , CNF_INPARALLEL , validate_inparallel },
896 { CONF_DUMPORDER , CONFTYPE_STR , read_str , CNF_DUMPORDER , NULL },
897 { CONF_MAXDUMPS , CONFTYPE_INT , read_int , CNF_MAXDUMPS , validate_positive },
898 { CONF_ETIMEOUT , CONFTYPE_INT , read_int , CNF_ETIMEOUT , NULL },
899 { CONF_DTIMEOUT , CONFTYPE_INT , read_int , CNF_DTIMEOUT , validate_positive },
900 { CONF_CTIMEOUT , CONFTYPE_INT , read_int , CNF_CTIMEOUT , validate_positive },
901 { CONF_TAPEBUFS , CONFTYPE_INT , read_int , CNF_TAPEBUFS , validate_positive },
902 { CONF_DEVICE_OUTPUT_BUFFER_SIZE, CONFTYPE_SIZE , read_size , CNF_DEVICE_OUTPUT_BUFFER_SIZE, validate_positive },
903 { CONF_COLUMNSPEC , CONFTYPE_STR , read_str , CNF_COLUMNSPEC , NULL },
904 { CONF_TAPERALGO , CONFTYPE_TAPERALGO, read_taperalgo , CNF_TAPERALGO , NULL },
905 { CONF_FLUSH_THRESHOLD_DUMPED, CONFTYPE_INT , read_int , CNF_FLUSH_THRESHOLD_DUMPED, validate_nonnegative },
906 { CONF_FLUSH_THRESHOLD_SCHEDULED, CONFTYPE_INT , read_int , CNF_FLUSH_THRESHOLD_SCHEDULED, validate_nonnegative },
907 { CONF_TAPERFLUSH , CONFTYPE_INT , read_int , CNF_TAPERFLUSH , validate_nonnegative },
908 { CONF_DISPLAYUNIT , CONFTYPE_STR , read_str , CNF_DISPLAYUNIT , validate_displayunit },
909 { CONF_AUTOFLUSH , CONFTYPE_BOOLEAN , read_bool , CNF_AUTOFLUSH , NULL },
910 { CONF_RESERVE , CONFTYPE_INT , read_int , CNF_RESERVE , validate_reserve },
911 { CONF_MAXDUMPSIZE , CONFTYPE_AM64 , read_am64 , CNF_MAXDUMPSIZE , NULL },
912 { CONF_KRB5KEYTAB , CONFTYPE_STR , read_str , CNF_KRB5KEYTAB , NULL },
913 { CONF_KRB5PRINCIPAL , CONFTYPE_STR , read_str , CNF_KRB5PRINCIPAL , NULL },
914 { CONF_LABEL_NEW_TAPES , CONFTYPE_STR , read_str , CNF_LABEL_NEW_TAPES , NULL },
915 { CONF_USETIMESTAMPS , CONFTYPE_BOOLEAN , read_bool , CNF_USETIMESTAMPS , NULL },
916 { CONF_AMRECOVER_DO_FSF , CONFTYPE_BOOLEAN , read_bool , CNF_AMRECOVER_DO_FSF , NULL },
917 { CONF_AMRECOVER_CHANGER , CONFTYPE_STR , read_str , CNF_AMRECOVER_CHANGER , NULL },
918 { CONF_AMRECOVER_CHECK_LABEL, CONFTYPE_BOOLEAN , read_bool , CNF_AMRECOVER_CHECK_LABEL, NULL },
919 { CONF_CONNECT_TRIES , CONFTYPE_INT , read_int , CNF_CONNECT_TRIES , validate_positive },
920 { CONF_REP_TRIES , CONFTYPE_INT , read_int , CNF_REP_TRIES , validate_positive },
921 { CONF_REQ_TRIES , CONFTYPE_INT , read_int , CNF_REQ_TRIES , validate_positive },
922 { CONF_DEBUG_AMANDAD , CONFTYPE_INT , read_int , CNF_DEBUG_AMANDAD , validate_debug },
923 { CONF_DEBUG_AMIDXTAPED , CONFTYPE_INT , read_int , CNF_DEBUG_AMIDXTAPED , validate_debug },
924 { CONF_DEBUG_AMINDEXD , CONFTYPE_INT , read_int , CNF_DEBUG_AMINDEXD , validate_debug },
925 { CONF_DEBUG_AMRECOVER , CONFTYPE_INT , read_int , CNF_DEBUG_AMRECOVER , validate_debug },
926 { CONF_DEBUG_AUTH , CONFTYPE_INT , read_int , CNF_DEBUG_AUTH , validate_debug },
927 { CONF_DEBUG_EVENT , CONFTYPE_INT , read_int , CNF_DEBUG_EVENT , validate_debug },
928 { CONF_DEBUG_HOLDING , CONFTYPE_INT , read_int , CNF_DEBUG_HOLDING , validate_debug },
929 { CONF_DEBUG_PROTOCOL , CONFTYPE_INT , read_int , CNF_DEBUG_PROTOCOL , validate_debug },
930 { CONF_DEBUG_PLANNER , CONFTYPE_INT , read_int , CNF_DEBUG_PLANNER , validate_debug },
931 { CONF_DEBUG_DRIVER , CONFTYPE_INT , read_int , CNF_DEBUG_DRIVER , validate_debug },
932 { CONF_DEBUG_DUMPER , CONFTYPE_INT , read_int , CNF_DEBUG_DUMPER , validate_debug },
933 { CONF_DEBUG_CHUNKER , CONFTYPE_INT , read_int , CNF_DEBUG_CHUNKER , validate_debug },
934 { CONF_DEBUG_TAPER , CONFTYPE_INT , read_int , CNF_DEBUG_TAPER , validate_debug },
935 { CONF_DEBUG_SELFCHECK , CONFTYPE_INT , read_int , CNF_DEBUG_SELFCHECK , validate_debug },
936 { CONF_DEBUG_SENDSIZE , CONFTYPE_INT , read_int , CNF_DEBUG_SENDSIZE , validate_debug },
937 { CONF_DEBUG_SENDBACKUP , CONFTYPE_INT , read_int , CNF_DEBUG_SENDBACKUP , validate_debug },
938 { CONF_RESERVED_UDP_PORT , CONFTYPE_INTRANGE , read_intrange , CNF_RESERVED_UDP_PORT , validate_reserved_port_range },
939 { CONF_RESERVED_TCP_PORT , CONFTYPE_INTRANGE , read_intrange , CNF_RESERVED_TCP_PORT , validate_reserved_port_range },
940 { CONF_UNRESERVED_TCP_PORT , CONFTYPE_INTRANGE , read_intrange , CNF_UNRESERVED_TCP_PORT , validate_unreserved_port_range },
941 { CONF_UNKNOWN , CONFTYPE_INT , NULL , CNF_CNF , NULL }
944 conf_var_t tapetype_var [] = {
945 { CONF_COMMENT , CONFTYPE_STR , read_str , TAPETYPE_COMMENT , NULL },
946 { CONF_LBL_TEMPL , CONFTYPE_STR , read_str , TAPETYPE_LBL_TEMPL , NULL },
947 { CONF_BLOCKSIZE , CONFTYPE_SIZE , read_size , TAPETYPE_BLOCKSIZE , validate_blocksize },
948 { CONF_READBLOCKSIZE , CONFTYPE_SIZE , read_size , TAPETYPE_READBLOCKSIZE, validate_blocksize },
949 { CONF_LENGTH , CONFTYPE_AM64 , read_am64 , TAPETYPE_LENGTH , validate_nonnegative },
950 { CONF_FILEMARK , CONFTYPE_AM64 , read_am64 , TAPETYPE_FILEMARK , NULL },
951 { CONF_SPEED , CONFTYPE_INT , read_int , TAPETYPE_SPEED , validate_nonnegative },
952 { CONF_FILE_PAD , CONFTYPE_BOOLEAN , read_bool , TAPETYPE_FILE_PAD , NULL },
953 { CONF_UNKNOWN , CONFTYPE_INT , NULL , TAPETYPE_TAPETYPE , NULL }
956 conf_var_t dumptype_var [] = {
957 { CONF_COMMENT , CONFTYPE_STR , read_str , DUMPTYPE_COMMENT , NULL },
958 { CONF_AUTH , CONFTYPE_STR , read_str , DUMPTYPE_SECURITY_DRIVER , NULL },
959 { CONF_BUMPDAYS , CONFTYPE_INT , read_int , DUMPTYPE_BUMPDAYS , NULL },
960 { CONF_BUMPMULT , CONFTYPE_REAL , read_real , DUMPTYPE_BUMPMULT , NULL },
961 { CONF_BUMPSIZE , CONFTYPE_AM64 , read_am64 , DUMPTYPE_BUMPSIZE , NULL },
962 { CONF_BUMPPERCENT , CONFTYPE_INT , read_int , DUMPTYPE_BUMPPERCENT , NULL },
963 { CONF_COMPRATE , CONFTYPE_REAL , read_rate , DUMPTYPE_COMPRATE , NULL },
964 { CONF_COMPRESS , CONFTYPE_INT , read_compress , DUMPTYPE_COMPRESS , NULL },
965 { CONF_ENCRYPT , CONFTYPE_INT , read_encrypt , DUMPTYPE_ENCRYPT , NULL },
966 { CONF_DUMPCYCLE , CONFTYPE_INT , read_int , DUMPTYPE_DUMPCYCLE , validate_nonnegative },
967 { CONF_EXCLUDE , CONFTYPE_EXINCLUDE, read_exinclude, DUMPTYPE_EXCLUDE , NULL },
968 { CONF_INCLUDE , CONFTYPE_EXINCLUDE, read_exinclude, DUMPTYPE_INCLUDE , NULL },
969 { CONF_IGNORE , CONFTYPE_BOOLEAN , read_bool , DUMPTYPE_IGNORE , NULL },
970 { CONF_HOLDING , CONFTYPE_HOLDING , read_holding , DUMPTYPE_HOLDINGDISK , NULL },
971 { CONF_INDEX , CONFTYPE_BOOLEAN , read_bool , DUMPTYPE_INDEX , NULL },
972 { CONF_KENCRYPT , CONFTYPE_BOOLEAN , read_bool , DUMPTYPE_KENCRYPT , NULL },
973 { CONF_MAXDUMPS , CONFTYPE_INT , read_int , DUMPTYPE_MAXDUMPS , validate_positive },
974 { CONF_MAXPROMOTEDAY , CONFTYPE_INT , read_int , DUMPTYPE_MAXPROMOTEDAY , validate_nonnegative },
975 { CONF_PRIORITY , CONFTYPE_PRIORITY , read_priority , DUMPTYPE_PRIORITY , NULL },
976 { CONF_PROGRAM , CONFTYPE_STR , read_str , DUMPTYPE_PROGRAM , NULL },
977 { CONF_RECORD , CONFTYPE_BOOLEAN , read_bool , DUMPTYPE_RECORD , NULL },
978 { CONF_SKIP_FULL , CONFTYPE_BOOLEAN , read_bool , DUMPTYPE_SKIP_FULL , NULL },
979 { CONF_SKIP_INCR , CONFTYPE_BOOLEAN , read_bool , DUMPTYPE_SKIP_INCR , NULL },
980 { CONF_STARTTIME , CONFTYPE_TIME , read_time , DUMPTYPE_STARTTIME , NULL },
981 { CONF_STRATEGY , CONFTYPE_INT , read_strategy , DUMPTYPE_STRATEGY , NULL },
982 { CONF_TAPE_SPLITSIZE , CONFTYPE_AM64 , read_am64 , DUMPTYPE_TAPE_SPLITSIZE , validate_nonnegative },
983 { CONF_SPLIT_DISKBUFFER , CONFTYPE_STR , read_str , DUMPTYPE_SPLIT_DISKBUFFER , NULL },
984 { CONF_ESTIMATE , CONFTYPE_INT , read_estimate , DUMPTYPE_ESTIMATE , NULL },
985 { CONF_SRV_ENCRYPT , CONFTYPE_STR , read_str , DUMPTYPE_SRV_ENCRYPT , NULL },
986 { CONF_CLNT_ENCRYPT , CONFTYPE_STR , read_str , DUMPTYPE_CLNT_ENCRYPT , NULL },
987 { CONF_AMANDAD_PATH , CONFTYPE_STR , read_str , DUMPTYPE_AMANDAD_PATH , NULL },
988 { CONF_CLIENT_USERNAME , CONFTYPE_STR , read_str , DUMPTYPE_CLIENT_USERNAME , NULL },
989 { CONF_SSH_KEYS , CONFTYPE_STR , read_str , DUMPTYPE_SSH_KEYS , NULL },
990 { CONF_SRVCOMPPROG , CONFTYPE_STR , read_str , DUMPTYPE_SRVCOMPPROG , NULL },
991 { CONF_CLNTCOMPPROG , CONFTYPE_STR , read_str , DUMPTYPE_CLNTCOMPPROG , NULL },
992 { CONF_FALLBACK_SPLITSIZE, CONFTYPE_AM64 , read_am64 , DUMPTYPE_FALLBACK_SPLITSIZE, NULL },
993 { CONF_SRV_DECRYPT_OPT , CONFTYPE_STR , read_str , DUMPTYPE_SRV_DECRYPT_OPT , NULL },
994 { CONF_CLNT_DECRYPT_OPT , CONFTYPE_STR , read_str , DUMPTYPE_CLNT_DECRYPT_OPT , NULL },
995 { CONF_UNKNOWN , CONFTYPE_INT , NULL , DUMPTYPE_DUMPTYPE , NULL }
998 conf_var_t holding_var [] = {
999 { CONF_DIRECTORY, CONFTYPE_STR , read_str , HOLDING_DISKDIR , NULL },
1000 { CONF_COMMENT , CONFTYPE_STR , read_str , HOLDING_COMMENT , NULL },
1001 { CONF_USE , CONFTYPE_AM64 , read_am64 , HOLDING_DISKSIZE , validate_use },
1002 { CONF_CHUNKSIZE, CONFTYPE_AM64 , read_am64 , HOLDING_CHUNKSIZE, validate_chunksize },
1003 { CONF_UNKNOWN , CONFTYPE_INT , NULL , HOLDING_HOLDING , NULL }
1006 conf_var_t interface_var [] = {
1007 { CONF_COMMENT, CONFTYPE_STR , read_str , INTER_COMMENT , NULL },
1008 { CONF_USE , CONFTYPE_INT , read_int , INTER_MAXUSAGE, validate_positive },
1009 { CONF_UNKNOWN, CONFTYPE_INT , NULL , INTER_INTER , NULL }
1014 * Lexical Analysis Implementation
1023 if (keytable == NULL) {
1024 error(_("keytable == NULL"));
1028 for(kt = keytable; kt->token != CONF_UNKNOWN; kt++)
1029 if(kt->token == token) break;
1031 if(kt->token == CONF_UNKNOWN)
1033 return(kt->keyword);
1042 for(kwp = keytable; kwp->keyword != NULL; kwp++) {
1043 if (strcasecmp(kwp->keyword, str) == 0) break;
1066 ** If it looked like a keyword before then look it
1067 ** up again in the current keyword table.
1070 case CONF_AM64: case CONF_SIZE:
1071 case CONF_INT: case CONF_REAL: case CONF_STRING:
1072 case CONF_LBRACE: case CONF_RBRACE: case CONF_COMMA:
1073 case CONF_NL: case CONF_END: case CONF_UNKNOWN:
1075 break; /* not a keyword */
1078 if (exp == CONF_IDENT)
1081 tok = lookup_keyword(tokenval.v.s);
1086 ch = conftoken_getc();
1088 while(ch != EOF && ch != '\n' && isspace(ch))
1089 ch = conftoken_getc();
1090 if (ch == '#') { /* comment - eat everything but eol/eof */
1091 while((ch = conftoken_getc()) != EOF && ch != '\n') {
1092 (void)ch; /* Quiet empty loop complaints */
1096 if (isalpha(ch)) { /* identifier */
1100 if (buf < tkbuf+sizeof(tkbuf)-1) {
1104 if (!token_overflow) {
1105 conf_parserror(_("token too long: %.20s..."), tkbuf);
1109 ch = conftoken_getc();
1110 } while(isalnum(ch) || ch == '_' || ch == '-');
1112 if (ch != EOF && conftoken_ungetc(ch) == EOF) {
1113 if (ferror(current_file)) {
1114 conf_parserror(_("Pushback of '%c' failed: %s"),
1115 ch, strerror(ferror(current_file)));
1117 conf_parserror(_("Pushback of '%c' failed: EOF"), ch);
1122 tokenval.v.s = tkbuf;
1124 if (token_overflow) tok = CONF_UNKNOWN;
1125 else if (exp == CONF_IDENT) tok = CONF_IDENT;
1126 else tok = lookup_keyword(tokenval.v.s);
1128 else if (isdigit(ch)) { /* integer */
1131 negative_number: /* look for goto negative_number below sign is set there */
1134 am64 = am64 * 10 + (ch - '0');
1135 ch = conftoken_getc();
1136 } while (isdigit(ch));
1139 if (exp == CONF_INT) {
1141 tokenval.v.i = sign * (int)am64;
1142 } else if (exp != CONF_REAL) {
1144 tokenval.v.am64 = (off_t)sign * am64;
1146 /* automatically convert to real when expected */
1147 tokenval.v.r = (double)sign * (double)am64;
1151 /* got a real number, not an int */
1152 tokenval.v.r = sign * (double) am64;
1155 ch = conftoken_getc();
1156 while (isdigit(ch)) {
1157 am64 = am64 * 10 + (ch - '0');
1159 ch = conftoken_getc();
1161 tokenval.v.r += sign * ((double)am64) / d;
1165 if (ch != EOF && conftoken_ungetc(ch) == EOF) {
1166 if (ferror(current_file)) {
1167 conf_parserror(_("Pushback of '%c' failed: %s"),
1168 ch, strerror(ferror(current_file)));
1170 conf_parserror(_("Pushback of '%c' failed: EOF"), ch);
1174 case '"': /* string */
1179 while (inquote && ((ch = conftoken_getc()) != EOF)) {
1184 buf--; /* Consume escape in buffer */
1185 } else if (ch == '\\') {
1195 if(buf >= &tkbuf[sizeof(tkbuf) - 1]) {
1196 if (!token_overflow) {
1197 conf_parserror(_("string too long: %.20s..."), tkbuf);
1207 * A little manuver to leave a fully unquoted, unallocated string
1210 tmps = unquote_string(tkbuf);
1211 strncpy(tkbuf, tmps, sizeof(tkbuf));
1213 tokenval.v.s = tkbuf;
1215 tok = (token_overflow) ? CONF_UNKNOWN :
1216 (exp == CONF_IDENT) ? CONF_IDENT : CONF_STRING;
1220 ch = conftoken_getc();
1223 goto negative_number;
1226 if (ch != EOF && conftoken_ungetc(ch) == EOF) {
1227 if (ferror(current_file)) {
1228 conf_parserror(_("Pushback of '%c' failed: %s"),
1229 ch, strerror(ferror(current_file)));
1231 conf_parserror(_("Pushback of '%c' failed: EOF"), ch);
1264 if (exp != CONF_ANY && tok != exp) {
1282 str = _("end of line");
1286 str = _("end of file");
1290 str = _("an integer");
1294 str = _("a real number");
1298 str = _("a quoted string");
1302 str = _("an identifier");
1306 for(kwp = keytable; kwp->keyword != NULL; kwp++) {
1307 if (exp == kwp->token)
1310 if (kwp->keyword == NULL)
1311 str = _("token not");
1316 conf_parserror(_("%s is expected"), str);
1318 if (tok == CONF_INT)
1326 unget_conftoken(void)
1328 assert(!token_pushed);
1335 conftoken_getc(void)
1337 if(current_line == NULL)
1338 return getc(current_file);
1339 if(*current_char == '\0')
1341 return(*current_char++);
1348 if(current_line == NULL)
1349 return ungetc(c, current_file);
1350 else if(current_char > current_line) {
1354 if(*current_char != c) {
1355 error(_("*current_char != c : %c %c"), *current_char, c);
1359 error(_("current_char == current_line"));
1366 * Parser Implementation
1374 /* Save global locations. */
1375 FILE *save_file = current_file;
1376 char *save_filename = current_filename;
1377 int save_line_num = current_line_num;
1381 keytable = client_keytab;
1382 parsetable = client_var;
1384 keytable = server_keytab;
1385 parsetable = server_var;
1387 current_filename = config_dir_relative(filename);
1389 if ((current_file = fopen(current_filename, "r")) == NULL) {
1390 /* client conf files are optional, and this fprintf ends up sending this message back
1391 * to the server without proper auth encapsulation, leading to "invalid size: could not
1392 * open .." This is fixed in TRUNK by completely rewriting this module's error-handling
1395 g_fprintf(stderr, _("could not open conf file \"%s\": %s\n"), current_filename,
1398 got_parserror = TRUE;
1402 current_line_num = 0;
1405 /* read_confline() can invoke us recursively via "includefile" */
1406 rc = read_confline(is_client);
1409 afclose(current_file);
1412 amfree(current_filename);
1414 /* Restore servers */
1415 current_line_num = save_line_num;
1416 current_file = save_file;
1417 current_filename = save_filename;
1419 return !got_parserror;
1428 current_line_num += 1;
1429 get_conftoken(CONF_ANY);
1431 case CONF_INCLUDEFILE:
1432 get_conftoken(CONF_STRING);
1433 if (!read_conffile(tokenval.v.s, is_client))
1439 handle_invalid_keyword(tokenval.v.s);
1447 handle_invalid_keyword(tokenval.v.s);
1449 get_conftoken(CONF_ANY);
1450 if(tok == CONF_DUMPTYPE) get_dumptype();
1451 else if(tok == CONF_TAPETYPE) get_tapetype();
1452 else if(tok == CONF_INTERFACE) get_interface();
1453 else conf_parserror(_("DUMPTYPE, INTERFACE or TAPETYPE expected"));
1457 case CONF_NL: /* empty line */
1460 case CONF_END: /* end of file */
1463 /* if it's not a known punctuation mark, then check the parse table and use the
1464 * read_function we find there. */
1467 for(np = parsetable; np->token != CONF_UNKNOWN; np++)
1468 if(np->token == tok) break;
1470 if(np->token == CONF_UNKNOWN) {
1471 handle_invalid_keyword(tokenval.v.s);
1473 np->read_function(np, &conf_data[np->parm]);
1474 if(np->validate_function)
1475 np->validate_function(np, &conf_data[np->parm]);
1480 get_conftoken(CONF_NL);
1485 handle_invalid_keyword(
1488 /* Procedure for deprecated keywords:
1489 * 1) At time of deprecation, add to warning_deprecated below.
1490 * Note the date of deprecation.
1491 * 2) After two years, move the keyword to error_deprecated below.
1492 * Note the date of the move.
1493 * 3) After two more years, drop the token entirely. */
1495 static const char * warning_deprecated[] = {
1496 "rawtapedev", /* 2007-01-23 */
1497 "tapebufs", /* 2007-10-15 */
1498 "netusage", /* historical since 1997-08-11, deprecated 2007-10-23 */
1501 static const char * error_deprecated[] = {
1506 for (s = warning_deprecated; *s != NULL; s ++) {
1507 if (strcmp(*s, token) == 0) {
1508 conf_parswarn(_("warning: Keyword %s is deprecated."),
1514 for (s = error_deprecated; *s != NULL; s ++) {
1515 if (strcmp(*s, token) == 0) {
1516 conf_parserror(_("error: Keyword %s is deprecated."),
1523 conf_parserror(_("configuration keyword expected"));
1527 char c = conftoken_getc();
1528 if (c == '\n' || c == -1) {
1529 conftoken_ungetc(c);
1534 g_assert_not_reached();
1539 conf_var_t *read_var,
1543 void (*copy_function)(void))
1549 get_conftoken(CONF_LBRACE);
1550 get_conftoken(CONF_NL);
1555 current_line_num += 1;
1556 get_conftoken(CONF_ANY);
1561 case CONF_NL: /* empty line */
1563 case CONF_END: /* end of file */
1567 /* inherit from a "parent" */
1573 conf_parserror(_("ident not expected"));
1577 for(np = read_var; np->token != CONF_UNKNOWN; np++)
1578 if(np->token == tok) break;
1580 if(np->token == CONF_UNKNOWN)
1581 conf_parserror("%s", errormsg);
1583 np->read_function(np, &valarray[np->parm]);
1584 if(np->validate_function)
1585 np->validate_function(np, &valarray[np->parm]);
1589 if(tok != CONF_NL && tok != CONF_END && tok != CONF_RBRACE)
1590 get_conftoken(CONF_NL);
1598 int save_overwrites;
1600 save_overwrites = allow_overwrites;
1601 allow_overwrites = 1;
1603 init_holdingdisk_defaults();
1605 get_conftoken(CONF_IDENT);
1606 hdcur.name = stralloc(tokenval.v.s);
1607 hdcur.seen = current_line_num;
1609 read_block(holding_var, hdcur.value,
1610 _("holding disk parameter expected"), 1, NULL);
1611 get_conftoken(CONF_NL);
1614 allow_overwrites = save_overwrites;
1618 init_holdingdisk_defaults(
1621 conf_init_str(&hdcur.value[HOLDING_COMMENT] , "");
1622 conf_init_str(&hdcur.value[HOLDING_DISKDIR] , "");
1623 conf_init_am64(&hdcur.value[HOLDING_DISKSIZE] , (off_t)0);
1624 /* 1 Gb = 1M counted in 1Kb blocks */
1625 conf_init_am64(&hdcur.value[HOLDING_CHUNKSIZE], (off_t)1024*1024);
1634 hp = alloc(sizeof(holdingdisk_t));
1636 hp->next = holdinglist;
1642 * This function is called both from this module and from diskfile.c. Modify
1651 int save_overwrites;
1652 FILE *saved_conf = NULL;
1653 char *saved_fname = NULL;
1656 saved_conf = current_file;
1657 current_file = from;
1661 saved_fname = current_filename;
1662 current_filename = fname;
1666 current_line_num = *linenum;
1668 save_overwrites = allow_overwrites;
1669 allow_overwrites = 1;
1671 init_dumptype_defaults();
1675 get_conftoken(CONF_IDENT);
1676 dpcur.name = stralloc(tokenval.v.s);
1678 dpcur.seen = current_line_num;
1680 read_block(dumptype_var, dpcur.value,
1681 _("dumptype parameter expected"),
1682 (name == NULL), copy_dumptype);
1684 if(!name) /* !name => reading disklist, not conffile */
1685 get_conftoken(CONF_NL);
1687 /* XXX - there was a stupidity check in here for skip-incr and
1688 ** skip-full. This check should probably be somewhere else. */
1692 allow_overwrites = save_overwrites;
1695 *linenum = current_line_num;
1698 current_filename = saved_fname;
1701 current_file = saved_conf;
1703 return lookup_dumptype(dpcur.name);
1709 read_dumptype(NULL, NULL, NULL, NULL);
1713 init_dumptype_defaults(void)
1716 conf_init_str (&dpcur.value[DUMPTYPE_COMMENT] , "");
1717 conf_init_str (&dpcur.value[DUMPTYPE_PROGRAM] , "DUMP");
1718 conf_init_str (&dpcur.value[DUMPTYPE_SRVCOMPPROG] , "");
1719 conf_init_str (&dpcur.value[DUMPTYPE_CLNTCOMPPROG] , "");
1720 conf_init_str (&dpcur.value[DUMPTYPE_SRV_ENCRYPT] , "");
1721 conf_init_str (&dpcur.value[DUMPTYPE_CLNT_ENCRYPT] , "");
1722 conf_init_str (&dpcur.value[DUMPTYPE_AMANDAD_PATH] , "X");
1723 conf_init_str (&dpcur.value[DUMPTYPE_CLIENT_USERNAME] , "X");
1724 conf_init_str (&dpcur.value[DUMPTYPE_SSH_KEYS] , "X");
1725 conf_init_str (&dpcur.value[DUMPTYPE_SECURITY_DRIVER] , "BSD");
1726 conf_init_exinclude(&dpcur.value[DUMPTYPE_EXCLUDE]);
1727 conf_init_exinclude(&dpcur.value[DUMPTYPE_INCLUDE]);
1728 conf_init_priority (&dpcur.value[DUMPTYPE_PRIORITY] , 1);
1729 conf_init_int (&dpcur.value[DUMPTYPE_DUMPCYCLE] , conf_data[CNF_DUMPCYCLE].v.i);
1730 conf_init_int (&dpcur.value[DUMPTYPE_MAXDUMPS] , conf_data[CNF_MAXDUMPS].v.i);
1731 conf_init_int (&dpcur.value[DUMPTYPE_MAXPROMOTEDAY] , 10000);
1732 conf_init_int (&dpcur.value[DUMPTYPE_BUMPPERCENT] , conf_data[CNF_BUMPPERCENT].v.i);
1733 conf_init_am64 (&dpcur.value[DUMPTYPE_BUMPSIZE] , conf_data[CNF_BUMPSIZE].v.am64);
1734 conf_init_int (&dpcur.value[DUMPTYPE_BUMPDAYS] , conf_data[CNF_BUMPDAYS].v.i);
1735 conf_init_real (&dpcur.value[DUMPTYPE_BUMPMULT] , conf_data[CNF_BUMPMULT].v.r);
1736 conf_init_time (&dpcur.value[DUMPTYPE_STARTTIME] , (time_t)0);
1737 conf_init_strategy (&dpcur.value[DUMPTYPE_STRATEGY] , DS_STANDARD);
1738 conf_init_estimate (&dpcur.value[DUMPTYPE_ESTIMATE] , ES_CLIENT);
1739 conf_init_compress (&dpcur.value[DUMPTYPE_COMPRESS] , COMP_FAST);
1740 conf_init_encrypt (&dpcur.value[DUMPTYPE_ENCRYPT] , ENCRYPT_NONE);
1741 conf_init_str (&dpcur.value[DUMPTYPE_SRV_DECRYPT_OPT] , "-d");
1742 conf_init_str (&dpcur.value[DUMPTYPE_CLNT_DECRYPT_OPT] , "-d");
1743 conf_init_rate (&dpcur.value[DUMPTYPE_COMPRATE] , 0.50, 0.50);
1744 conf_init_am64 (&dpcur.value[DUMPTYPE_TAPE_SPLITSIZE] , (off_t)0);
1745 conf_init_am64 (&dpcur.value[DUMPTYPE_FALLBACK_SPLITSIZE], (off_t)10 * 1024);
1746 conf_init_str (&dpcur.value[DUMPTYPE_SPLIT_DISKBUFFER] , NULL);
1747 conf_init_bool (&dpcur.value[DUMPTYPE_RECORD] , 1);
1748 conf_init_bool (&dpcur.value[DUMPTYPE_SKIP_INCR] , 0);
1749 conf_init_bool (&dpcur.value[DUMPTYPE_SKIP_FULL] , 0);
1750 conf_init_holding (&dpcur.value[DUMPTYPE_HOLDINGDISK] , HOLD_AUTO);
1751 conf_init_bool (&dpcur.value[DUMPTYPE_KENCRYPT] , 0);
1752 conf_init_bool (&dpcur.value[DUMPTYPE_IGNORE] , 0);
1753 conf_init_bool (&dpcur.value[DUMPTYPE_INDEX] , 1);
1759 dumptype_t *dp, *dp1;;
1761 dp = lookup_dumptype(dpcur.name);
1763 if(dp != (dumptype_t *)0) {
1764 conf_parserror(_("dumptype %s already defined on line %d"), dp->name, dp->seen);
1768 dp = alloc(sizeof(dumptype_t));
1771 /* add at end of list */
1776 while (dp1->next != NULL) {
1789 dt = lookup_dumptype(tokenval.v.s);
1792 conf_parserror(_("dumptype parameter expected"));
1796 for(i=0; i < DUMPTYPE_DUMPTYPE; i++) {
1797 if(dt->value[i].seen) {
1798 free_val_t(&dpcur.value[i]);
1799 copy_val_t(&dpcur.value[i], &dt->value[i]);
1807 int save_overwrites;
1809 save_overwrites = allow_overwrites;
1810 allow_overwrites = 1;
1812 init_tapetype_defaults();
1814 get_conftoken(CONF_IDENT);
1815 tpcur.name = stralloc(tokenval.v.s);
1816 tpcur.seen = current_line_num;
1818 read_block(tapetype_var, tpcur.value,
1819 _("tapetype parameter expected"), 1, copy_tapetype);
1820 get_conftoken(CONF_NL);
1822 if (tapetype_get_readblocksize(&tpcur) <
1823 tapetype_get_blocksize(&tpcur)) {
1824 conf_init_size(&tpcur.value[TAPETYPE_READBLOCKSIZE],
1825 tapetype_get_blocksize(&tpcur));
1829 allow_overwrites = save_overwrites;
1833 init_tapetype_defaults(void)
1835 conf_init_str(&tpcur.value[TAPETYPE_COMMENT] , "");
1836 conf_init_str(&tpcur.value[TAPETYPE_LBL_TEMPL] , "");
1837 conf_init_size (&tpcur.value[TAPETYPE_BLOCKSIZE] , DISK_BLOCK_KB);
1838 conf_init_size (&tpcur.value[TAPETYPE_READBLOCKSIZE], MAX_TAPE_BLOCK_KB);
1839 conf_init_am64 (&tpcur.value[TAPETYPE_LENGTH] , ((off_t)2000 * 1024));
1840 conf_init_am64 (&tpcur.value[TAPETYPE_FILEMARK] , (off_t)1000);
1841 conf_init_int (&tpcur.value[TAPETYPE_SPEED] , 200);
1842 conf_init_bool (&tpcur.value[TAPETYPE_FILE_PAD] , 1);
1848 tapetype_t *tp, *tp1;
1850 tp = lookup_tapetype(tpcur.name);
1852 if(tp != (tapetype_t *)0) {
1854 conf_parserror(_("tapetype %s already defined on line %d"), tp->name, tp->seen);
1858 tp = alloc(sizeof(tapetype_t));
1860 /* add at end of list */
1865 while (tp1->next != NULL) {
1878 tp = lookup_tapetype(tokenval.v.s);
1881 conf_parserror(_("tape type parameter expected"));
1885 for(i=0; i < TAPETYPE_TAPETYPE; i++) {
1886 if(tp->value[i].seen) {
1887 free_val_t(&tpcur.value[i]);
1888 copy_val_t(&tpcur.value[i], &tp->value[i]);
1896 int save_overwrites;
1898 save_overwrites = allow_overwrites;
1899 allow_overwrites = 1;
1901 init_interface_defaults();
1903 get_conftoken(CONF_IDENT);
1904 ifcur.name = stralloc(tokenval.v.s);
1905 ifcur.seen = current_line_num;
1907 read_block(interface_var, ifcur.value,
1908 _("interface parameter expected"), 1, copy_interface);
1909 get_conftoken(CONF_NL);
1913 allow_overwrites = save_overwrites;
1919 init_interface_defaults(void)
1921 conf_init_str(&ifcur.value[INTER_COMMENT] , "");
1922 conf_init_int (&ifcur.value[INTER_MAXUSAGE], 8000);
1926 save_interface(void)
1928 interface_t *ip, *ip1;
1930 ip = lookup_interface(ifcur.name);
1932 if(ip != (interface_t *)0) {
1933 conf_parserror(_("interface %s already defined on line %d"), ip->name,
1938 ip = alloc(sizeof(interface_t));
1940 /* add at end of list */
1941 if(!interface_list) {
1942 interface_list = ip;
1944 ip1 = interface_list;
1945 while (ip1->next != NULL) {
1953 copy_interface(void)
1958 ip = lookup_interface(tokenval.v.s);
1961 conf_parserror(_("interface parameter expected"));
1965 for(i=0; i < INTER_INTER; i++) {
1966 if(ip->value[i].seen) {
1967 free_val_t(&ifcur.value[i]);
1968 copy_val_t(&ifcur.value[i], &ip->value[i]);
1973 /* Read functions */
1977 conf_var_t *np G_GNUC_UNUSED,
1981 val_t__int(val) = get_int();
1986 conf_var_t *np G_GNUC_UNUSED,
1990 val_t__am64(val) = get_am64_t();
1995 conf_var_t *np G_GNUC_UNUSED,
1999 get_conftoken(CONF_REAL);
2000 val_t__real(val) = tokenval.v.r;
2005 conf_var_t *np G_GNUC_UNUSED,
2009 get_conftoken(CONF_STRING);
2010 val->v.s = newstralloc(val->v.s, tokenval.v.s);
2015 conf_var_t *np G_GNUC_UNUSED,
2019 get_conftoken(CONF_IDENT);
2020 val->v.s = newstralloc(val->v.s, tokenval.v.s);
2025 conf_var_t *np G_GNUC_UNUSED,
2029 val_t__time(val) = get_time();
2034 conf_var_t *np G_GNUC_UNUSED,
2038 val_t__size(val) = get_size();
2043 conf_var_t *np G_GNUC_UNUSED,
2047 val_t__boolean(val) = get_bool();
2052 conf_var_t *np G_GNUC_UNUSED,
2055 int serv, clie, none, fast, best, custom;
2061 serv = clie = none = fast = best = custom = 0;
2065 get_conftoken(CONF_ANY);
2067 case CONF_NONE: none = 1; break;
2068 case CONF_FAST: fast = 1; break;
2069 case CONF_BEST: best = 1; break;
2070 case CONF_CLIENT: clie = 1; break;
2071 case CONF_SERVER: serv = 1; break;
2072 case CONF_CUSTOM: custom=1; break;
2073 case CONF_NL: done = 1; break;
2074 case CONF_END: done = 1; break;
2077 serv = clie = 1; /* force an error */
2081 if(serv + clie == 0) clie = 1; /* default to client */
2082 if(none + fast + best + custom == 0) fast = 1; /* default to fast */
2087 if(none && !fast && !best && !custom) comp = COMP_NONE;
2088 if(!none && fast && !best && !custom) comp = COMP_FAST;
2089 if(!none && !fast && best && !custom) comp = COMP_BEST;
2090 if(!none && !fast && !best && custom) comp = COMP_CUST;
2094 if(none && !fast && !best && !custom) comp = COMP_NONE;
2095 if(!none && fast && !best && !custom) comp = COMP_SERVER_FAST;
2096 if(!none && !fast && best && !custom) comp = COMP_SERVER_BEST;
2097 if(!none && !fast && !best && custom) comp = COMP_SERVER_CUST;
2100 if((int)comp == -1) {
2101 conf_parserror(_("NONE, CLIENT FAST, CLIENT BEST, CLIENT CUSTOM, SERVER FAST, SERVER BEST or SERVER CUSTOM expected"));
2105 val_t__compress(val) = (int)comp;
2110 conf_var_t *np G_GNUC_UNUSED,
2117 get_conftoken(CONF_ANY);
2120 encrypt = ENCRYPT_NONE;
2124 encrypt = ENCRYPT_CUST;
2128 encrypt = ENCRYPT_SERV_CUST;
2132 conf_parserror(_("NONE, CLIENT or SERVER expected"));
2133 encrypt = ENCRYPT_NONE;
2137 val_t__encrypt(val) = (int)encrypt;
2142 conf_var_t *np G_GNUC_UNUSED,
2145 dump_holdingdisk_t holding;
2149 get_conftoken(CONF_ANY);
2152 holding = HOLD_NEVER;
2156 holding = HOLD_AUTO;
2160 holding = HOLD_REQUIRED;
2163 default: /* can be a BOOLEAN */
2165 holding = (dump_holdingdisk_t)get_bool();
2167 holding = HOLD_NEVER;
2168 else if (holding == 1 || holding == 2)
2169 holding = HOLD_AUTO;
2171 conf_parserror(_("NEVER, AUTO or REQUIRED expected"));
2175 val_t__holding(val) = (int)holding;
2180 conf_var_t *np G_GNUC_UNUSED,
2187 get_conftoken(CONF_ANY);
2196 estime = ES_CALCSIZE;
2199 conf_parserror(_("CLIENT, SERVER or CALCSIZE expected"));
2202 val_t__estimate(val) = estime;
2207 conf_var_t *np G_GNUC_UNUSED,
2214 get_conftoken(CONF_ANY);
2220 strat = DS_STANDARD;
2232 strat = DS_INCRONLY;
2235 conf_parserror(_("dump strategy expected"));
2236 strat = DS_STANDARD;
2238 val_t__strategy(val) = strat;
2243 conf_var_t *np G_GNUC_UNUSED,
2248 get_conftoken(CONF_ANY);
2250 case CONF_FIRST: val_t__taperalgo(val) = ALGO_FIRST; break;
2251 case CONF_FIRSTFIT: val_t__taperalgo(val) = ALGO_FIRSTFIT; break;
2252 case CONF_LARGEST: val_t__taperalgo(val) = ALGO_LARGEST; break;
2253 case CONF_LARGESTFIT: val_t__taperalgo(val) = ALGO_LARGESTFIT; break;
2254 case CONF_SMALLEST: val_t__taperalgo(val) = ALGO_SMALLEST; break;
2255 case CONF_LAST: val_t__taperalgo(val) = ALGO_LAST; break;
2257 conf_parserror(_("FIRST, FIRSTFIT, LARGEST, LARGESTFIT, SMALLEST or LAST expected"));
2263 conf_var_t *np G_GNUC_UNUSED,
2270 get_conftoken(CONF_ANY);
2272 case CONF_LOW: pri = 0; break;
2273 case CONF_MEDIUM: pri = 1; break;
2274 case CONF_HIGH: pri = 2; break;
2275 case CONF_INT: pri = tokenval.v.i; break;
2277 conf_parserror(_("LOW, MEDIUM, HIGH or integer expected"));
2280 val_t__priority(val) = pri;
2285 conf_var_t *np G_GNUC_UNUSED,
2288 get_conftoken(CONF_REAL);
2289 val_t__rate(val)[0] = tokenval.v.r;
2290 val_t__rate(val)[1] = tokenval.v.r;
2291 val->seen = tokenval.seen;
2292 if(tokenval.v.r < 0) {
2293 conf_parserror(_("full compression rate must be >= 0"));
2296 get_conftoken(CONF_ANY);
2311 get_conftoken(CONF_REAL);
2312 val_t__rate(val)[1] = tokenval.v.r;
2313 if(tokenval.v.r < 0) {
2314 conf_parserror(_("incremental compression rate must be >= 0"));
2320 conf_var_t *np G_GNUC_UNUSED,
2323 int file, got_one = 0;
2327 get_conftoken(CONF_ANY);
2328 if(tok == CONF_LIST) {
2330 get_conftoken(CONF_ANY);
2331 exclude = val_t__exinclude(val).sl_list;
2335 if(tok == CONF_EFILE) get_conftoken(CONF_ANY);
2336 exclude = val_t__exinclude(val).sl_file;
2340 if(tok == CONF_OPTIONAL) {
2341 get_conftoken(CONF_ANY);
2345 if(tok == CONF_APPEND) {
2346 get_conftoken(CONF_ANY);
2353 while(tok == CONF_STRING) {
2354 exclude = append_sl(exclude, tokenval.v.s);
2356 get_conftoken(CONF_ANY);
2360 if(got_one == 0) { free_sl(exclude); exclude = NULL; }
2363 val_t__exinclude(val).sl_list = exclude;
2365 val_t__exinclude(val).sl_file = exclude;
2366 val_t__exinclude(val).optional = optional;
2371 conf_var_t *np G_GNUC_UNUSED,
2374 get_conftoken(CONF_INT);
2375 val_t__intrange(val)[0] = tokenval.v.i;
2376 val_t__intrange(val)[1] = tokenval.v.i;
2377 val->seen = tokenval.seen;
2379 get_conftoken(CONF_ANY);
2394 get_conftoken(CONF_INT);
2395 val_t__intrange(val)[1] = tokenval.v.i;
2400 conf_var_t *np G_GNUC_UNUSED,
2404 get_conftoken(CONF_STRING);
2405 key = strdup(tokenval.v.s);
2406 get_conftoken(CONF_STRING);
2407 value = strdup(tokenval.v.s);
2409 g_hash_table_insert(val_t__proplist(val), key, value);
2412 /* get_* functions */
2419 get_conftoken(CONF_ANY);
2422 #if SIZEOF_TIME_T < SIZEOF_INT
2423 if ((off_t)tokenval.v.i >= (off_t)TIME_MAX)
2424 conf_parserror(_("value too large"));
2426 hhmm = (time_t)tokenval.v.i;
2430 #if SIZEOF_TIME_T < SIZEOF_SSIZE_T
2431 if ((off_t)tokenval.v.size >= (off_t)TIME_MAX)
2432 conf_parserror(_("value too large"));
2434 hhmm = (time_t)tokenval.v.size;
2438 #if SIZEOF_TIME_T < SIZEOF_LONG_LONG
2439 if ((off_t)tokenval.v.am64 >= (off_t)TIME_MAX)
2440 conf_parserror(_("value too large"));
2442 hhmm = (time_t)tokenval.v.am64;
2445 case CONF_AMINFINITY:
2450 conf_parserror(_("a time is expected"));
2464 keytable = numb_keytable;
2466 get_conftoken(CONF_ANY);
2473 #if SIZEOF_INT < SIZEOF_SSIZE_T
2474 if ((off_t)tokenval.v.size > (off_t)INT_MAX)
2475 conf_parserror(_("value too large"));
2476 if ((off_t)tokenval.v.size < (off_t)INT_MIN)
2477 conf_parserror(_("value too small"));
2479 val = (int)tokenval.v.size;
2483 #if SIZEOF_INT < SIZEOF_LONG_LONG
2484 if (tokenval.v.am64 > (off_t)INT_MAX)
2485 conf_parserror(_("value too large"));
2486 if (tokenval.v.am64 < (off_t)INT_MIN)
2487 conf_parserror(_("value too small"));
2489 val = (int)tokenval.v.am64;
2492 case CONF_AMINFINITY:
2497 conf_parserror(_("an integer is expected"));
2502 /* get multiplier, if any */
2503 get_conftoken(CONF_ANY);
2505 case CONF_NL: /* multiply by one */
2512 if (val > (INT_MAX / 7))
2513 conf_parserror(_("value too large"));
2514 if (val < (INT_MIN / 7))
2515 conf_parserror(_("value too small"));
2520 if (val > (INT_MAX / 1024))
2521 conf_parserror(_("value too large"));
2522 if (val < (INT_MIN / 1024))
2523 conf_parserror(_("value too small"));
2528 if (val > (INT_MAX / (1024 * 1024)))
2529 conf_parserror(_("value too large"));
2530 if (val < (INT_MIN / (1024 * 1024)))
2531 conf_parserror(_("value too small"));
2535 default: /* it was not a multiplier */
2551 keytable = numb_keytable;
2553 get_conftoken(CONF_ANY);
2557 val = tokenval.v.size;
2561 #if SIZEOF_SIZE_T < SIZEOF_INT
2562 if ((off_t)tokenval.v.i > (off_t)SSIZE_MAX)
2563 conf_parserror(_("value too large"));
2564 if ((off_t)tokenval.v.i < (off_t)SSIZE_MIN)
2565 conf_parserror(_("value too small"));
2567 val = (ssize_t)tokenval.v.i;
2571 #if SIZEOF_SIZE_T < SIZEOF_LONG_LONG
2572 if (tokenval.v.am64 > (off_t)SSIZE_MAX)
2573 conf_parserror(_("value too large"));
2574 if (tokenval.v.am64 < (off_t)SSIZE_MIN)
2575 conf_parserror(_("value too small"));
2577 val = (ssize_t)tokenval.v.am64;
2580 case CONF_AMINFINITY:
2581 val = (ssize_t)SSIZE_MAX;
2585 conf_parserror(_("an integer is expected"));
2590 /* get multiplier, if any */
2591 get_conftoken(CONF_ANY);
2594 case CONF_NL: /* multiply by one */
2600 if (val > (ssize_t)(SSIZE_MAX / 7))
2601 conf_parserror(_("value too large"));
2602 if (val < (ssize_t)(SSIZE_MIN / 7))
2603 conf_parserror(_("value too small"));
2608 if (val > (ssize_t)(SSIZE_MAX / (ssize_t)1024))
2609 conf_parserror(_("value too large"));
2610 if (val < (ssize_t)(SSIZE_MIN / (ssize_t)1024))
2611 conf_parserror(_("value too small"));
2612 val *= (ssize_t)1024;
2616 if (val > (ssize_t)(SSIZE_MAX / (1024 * 1024)))
2617 conf_parserror(_("value too large"));
2618 if (val < (ssize_t)(SSIZE_MIN / (1024 * 1024)))
2619 conf_parserror(_("value too small"));
2620 val *= (ssize_t)(1024 * 1024);
2623 default: /* it was not a multiplier */
2639 keytable = numb_keytable;
2641 get_conftoken(CONF_ANY);
2645 val = (off_t)tokenval.v.i;
2649 val = (off_t)tokenval.v.size;
2653 val = tokenval.v.am64;
2656 case CONF_AMINFINITY:
2661 conf_parserror(_("an integer is expected"));
2666 /* get multiplier, if any */
2667 get_conftoken(CONF_ANY);
2670 case CONF_NL: /* multiply by one */
2676 if (val > AM64_MAX/7 || val < AM64_MIN/7)
2677 conf_parserror(_("value too large"));
2682 if (val > AM64_MAX/1024 || val < AM64_MIN/1024)
2683 conf_parserror(_("value too large"));
2688 if (val > AM64_MAX/(1024*1024) || val < AM64_MIN/(1024*1024))
2689 conf_parserror(_("value too large"));
2693 default: /* it was not a multiplier */
2710 keytable = bool_keytable;
2712 get_conftoken(CONF_ANY);
2716 if (tokenval.v.i != 0)
2723 if (tokenval.v.size != (size_t)0)
2730 if (tokenval.v.am64 != (off_t)0)
2746 val = 2; /* no argument - most likely TRUE */
2750 val = 3; /* a bad argument - most likely TRUE */
2751 conf_parserror(_("YES, NO, TRUE, FALSE, ON, OFF expected"));
2763 if (*seen && !allow_overwrites && current_line_num != -2) {
2764 conf_parserror(_("duplicate parameter, prev def on line %d"), *seen);
2766 *seen = current_line_num;
2769 /* Validation functions */
2772 validate_nonnegative(
2773 struct conf_var_s *np,
2778 if(val_t__int(val) < 0)
2779 conf_parserror(_("%s must be nonnegative"), get_token_name(np->token));
2782 if(val_t__am64(val) < 0)
2783 conf_parserror(_("%s must be nonnegative"), get_token_name(np->token));
2786 if(val_t__size(val) < 0)
2787 conf_parserror(_("%s must be positive"), get_token_name(np->token));
2790 conf_parserror(_("validate_nonnegative invalid type %d\n"), val->type);
2796 struct conf_var_s *np,
2801 if(val_t__int(val) < 1)
2802 conf_parserror(_("%s must be positive"), get_token_name(np->token));
2805 if(val_t__am64(val) < 1)
2806 conf_parserror(_("%s must be positive"), get_token_name(np->token));
2809 if(val_t__time(val) < 1)
2810 conf_parserror(_("%s must be positive"), get_token_name(np->token));
2813 if(val_t__size(val) < 1)
2814 conf_parserror(_("%s must be positive"), get_token_name(np->token));
2817 conf_parserror(_("validate_positive invalid type %d\n"), val->type);
2822 validate_runspercycle(
2823 struct conf_var_s *np G_GNUC_UNUSED,
2826 if(val_t__int(val) < -1)
2827 conf_parserror(_("runspercycle must be >= -1"));
2831 validate_bumppercent(
2832 struct conf_var_s *np G_GNUC_UNUSED,
2835 if(val_t__int(val) < 0 || val_t__int(val) > 100)
2836 conf_parserror(_("bumppercent must be between 0 and 100"));
2840 validate_inparallel(
2841 struct conf_var_s *np G_GNUC_UNUSED,
2844 if(val_t__int(val) < 1 || val_t__int(val) >MAX_DUMPERS)
2845 conf_parserror(_("inparallel must be between 1 and MAX_DUMPERS (%d)"),
2851 struct conf_var_s *np G_GNUC_UNUSED,
2854 if(val_t__real(val) < 0.999) {
2855 conf_parserror(_("bumpmult must one or more"));
2860 validate_displayunit(
2861 struct conf_var_s *np G_GNUC_UNUSED,
2862 val_t *val G_GNUC_UNUSED)
2864 char *s = val_t__str(val);
2865 if (strlen(s) == 1) {
2871 return; /* all good */
2873 /* lower-case values should get folded to upper case */
2878 s[0] = toupper(s[0]);
2885 conf_parserror(_("displayunit must be k,m,g or t."));
2890 struct conf_var_s *np G_GNUC_UNUSED,
2893 if(val_t__int(val) < 0 || val_t__int(val) > 100)
2894 conf_parserror(_("reserve must be between 0 and 100"));
2899 struct conf_var_s *np G_GNUC_UNUSED,
2902 val_t__am64(val) = am_floor(val_t__am64(val), DISK_BLOCK_KB);
2907 struct conf_var_s *np G_GNUC_UNUSED,
2910 /* NOTE: this function modifies the target value (rounding) */
2911 if(val_t__am64(val) == 0) {
2912 val_t__am64(val) = ((AM64_MAX / 1024) - (2 * DISK_BLOCK_KB));
2914 else if(val_t__am64(val) < 0) {
2915 conf_parserror(_("Negative chunksize (%lld) is no longer supported"), (long long)val_t__am64(val));
2917 val_t__am64(val) = am_floor(val_t__am64(val), (off_t)DISK_BLOCK_KB);
2918 if (val_t__am64(val) < 2*DISK_BLOCK_KB) {
2919 conf_parserror("chunksize must be at least %dkb", 2*DISK_BLOCK_KB);
2925 struct conf_var_s *np G_GNUC_UNUSED,
2928 if(val_t__size(val) < DISK_BLOCK_KB) {
2929 conf_parserror(_("Tape blocksize must be at least %d KBytes"),
2936 struct conf_var_s *np G_GNUC_UNUSED,
2939 if(val_t__int(val) < 0 || val_t__int(val) > 9) {
2940 conf_parserror(_("Debug must be between 0 and 9"));
2945 validate_port_range(
2951 /* check both values are in range */
2952 for (i = 0; i < 2; i++) {
2953 if(val_t__intrange(val)[0] < smallest || val_t__intrange(val)[0] > largest) {
2954 conf_parserror(_("portrange must be in the range %d to %d, inclusive"), smallest, largest);
2958 /* and check they're in the right order and not equal */
2959 if (val_t__intrange(val)[0] > val_t__intrange(val)[1]) {
2960 conf_parserror(_("portranges must be in order from low to high"));
2965 validate_reserved_port_range(
2966 struct conf_var_s *np G_GNUC_UNUSED,
2969 validate_port_range(val, 1, IPPORT_RESERVED-1);
2973 validate_unreserved_port_range(
2974 struct conf_var_s *np G_GNUC_UNUSED,
2977 validate_port_range(val, IPPORT_RESERVED, 65535);
2981 * Initialization Implementation
2986 config_init_flags flags,
2987 char *arg_config_name)
2989 if (!(flags & CONFIG_INIT_OVERLAY)) {
2990 /* Clear out anything that's already in there */
2993 /* and set everything to default values */
2996 allow_overwrites = FALSE;
2998 if (!config_initialized) {
2999 error(_("Attempt to overlay configuration with no existing configuration"));
3003 allow_overwrites = TRUE;
3006 /* store away our client-ness for later reference */
3007 config_client = flags & CONFIG_INIT_CLIENT;
3009 if ((flags & CONFIG_INIT_EXPLICIT_NAME) && arg_config_name) {
3010 config_name = newstralloc(config_name, arg_config_name);
3011 config_dir = newvstralloc(config_dir, CONFIG_DIR, "/", arg_config_name, NULL);
3012 } else if (flags & CONFIG_INIT_USE_CWD) {
3015 cwd = get_original_cwd();
3017 /* (this isn't a config error, so it's always fatal) */
3018 error(_("Cannot determine current working directory"));
3022 config_dir = stralloc2(cwd, "/");
3023 if ((config_name = strrchr(cwd, '/')) != NULL) {
3024 config_name = stralloc(config_name + 1);
3028 } else if (flags & CONFIG_INIT_CLIENT) {
3029 amfree(config_name);
3030 config_dir = newstralloc(config_dir, CONFIG_DIR);
3032 /* ok, then, we won't read anything (for e.g., amrestore) */
3033 amfree(config_name);
3037 /* If we have a config_dir, we can try reading something */
3039 if (flags & CONFIG_INIT_CLIENT) {
3040 config_filename = newvstralloc(config_filename, config_dir, "/amanda-client.conf", NULL);
3042 config_filename = newvstralloc(config_filename, config_dir, "/amanda.conf", NULL);
3045 /* try to read the file, and handle parse errors */
3046 if (!read_conffile(config_filename, flags & CONFIG_INIT_CLIENT)) {
3047 if (flags & CONFIG_INIT_FATAL) {
3048 error(_("errors processing config file \"%s\""), config_filename);
3051 g_warning(_("errors processing config file \"%s\" (non-fatal)"), config_filename);
3056 amfree(config_filename);
3059 update_derived_values(flags & CONFIG_INIT_CLIENT);
3067 holdingdisk_t *hp, *hpnext;
3068 dumptype_t *dp, *dpnext;
3069 tapetype_t *tp, *tpnext;
3070 interface_t *ip, *ipnext;
3073 if (!config_initialized) return;
3075 for(hp=holdinglist; hp != NULL; hp = hpnext) {
3077 for(i=0; i<HOLDING_HOLDING-1; i++) {
3078 free_val_t(&hp->value[i]);
3085 for(dp=dumplist; dp != NULL; dp = dpnext) {
3087 for(i=0; i<DUMPTYPE_DUMPTYPE-1; i++) {
3088 free_val_t(&dp->value[i]);
3095 for(tp=tapelist; tp != NULL; tp = tpnext) {
3097 for(i=0; i<TAPETYPE_TAPETYPE-1; i++) {
3098 free_val_t(&tp->value[i]);
3105 for(ip=interface_list; ip != NULL; ip = ipnext) {
3107 for(i=0; i<INTER_INTER-1; i++) {
3108 free_val_t(&ip->value[i]);
3113 interface_list = NULL;
3115 for(i=0; i<CNF_CNF-1; i++)
3116 free_val_t(&conf_data[i]);
3118 if (applied_config_overwrites) {
3119 free_config_overwrites(applied_config_overwrites);
3120 applied_config_overwrites = NULL;
3123 amfree(config_name);
3126 config_client = FALSE;
3128 config_initialized = FALSE;
3135 assert(!config_initialized);
3137 /* defaults for exported variables */
3138 conf_init_str(&conf_data[CNF_ORG], DEFAULT_CONFIG);
3139 conf_init_str(&conf_data[CNF_CONF], DEFAULT_CONFIG);
3140 conf_init_str(&conf_data[CNF_INDEX_SERVER], DEFAULT_SERVER);
3141 conf_init_str(&conf_data[CNF_TAPE_SERVER], DEFAULT_TAPE_SERVER);
3142 conf_init_str(&conf_data[CNF_AUTH], "bsd");
3143 conf_init_str(&conf_data[CNF_SSH_KEYS], "");
3144 conf_init_str(&conf_data[CNF_AMANDAD_PATH], "");
3145 conf_init_str(&conf_data[CNF_CLIENT_USERNAME], "");
3146 conf_init_str(&conf_data[CNF_GNUTAR_LIST_DIR], GNUTAR_LISTED_INCREMENTAL_DIR);
3147 conf_init_str(&conf_data[CNF_AMANDATES], DEFAULT_AMANDATES_FILE);
3148 conf_init_str(&conf_data[CNF_MAILTO], "operators");
3149 conf_init_str(&conf_data[CNF_DUMPUSER], CLIENT_LOGIN);
3150 conf_init_str(&conf_data[CNF_TAPEDEV], DEFAULT_TAPE_DEVICE);
3151 conf_init_proplist(&conf_data[CNF_DEVICE_PROPERTY]);
3152 conf_init_str(&conf_data[CNF_CHANGERDEV], DEFAULT_CHANGER_DEVICE);
3153 conf_init_str(&conf_data[CNF_CHANGERFILE], "/usr/adm/amanda/changer-status");
3154 conf_init_str (&conf_data[CNF_LABELSTR] , ".*");
3155 conf_init_str (&conf_data[CNF_TAPELIST] , "tapelist");
3156 conf_init_str (&conf_data[CNF_DISKFILE] , "disklist");
3157 conf_init_str (&conf_data[CNF_INFOFILE] , "/usr/adm/amanda/curinfo");
3158 conf_init_str (&conf_data[CNF_LOGDIR] , "/usr/adm/amanda");
3159 conf_init_str (&conf_data[CNF_INDEXDIR] , "/usr/adm/amanda/index");
3160 conf_init_ident (&conf_data[CNF_TAPETYPE] , "EXABYTE");
3161 conf_init_int (&conf_data[CNF_DUMPCYCLE] , 10);
3162 conf_init_int (&conf_data[CNF_RUNSPERCYCLE] , 0);
3163 conf_init_int (&conf_data[CNF_TAPECYCLE] , 15);
3164 conf_init_int (&conf_data[CNF_NETUSAGE] , 8000);
3165 conf_init_int (&conf_data[CNF_INPARALLEL] , 10);
3166 conf_init_str (&conf_data[CNF_DUMPORDER] , "ttt");
3167 conf_init_int (&conf_data[CNF_BUMPPERCENT] , 0);
3168 conf_init_am64 (&conf_data[CNF_BUMPSIZE] , (off_t)10*1024);
3169 conf_init_real (&conf_data[CNF_BUMPMULT] , 1.5);
3170 conf_init_int (&conf_data[CNF_BUMPDAYS] , 2);
3171 conf_init_str (&conf_data[CNF_TPCHANGER] , "");
3172 conf_init_int (&conf_data[CNF_RUNTAPES] , 1);
3173 conf_init_int (&conf_data[CNF_MAXDUMPS] , 1);
3174 conf_init_int (&conf_data[CNF_ETIMEOUT] , 300);
3175 conf_init_int (&conf_data[CNF_DTIMEOUT] , 1800);
3176 conf_init_int (&conf_data[CNF_CTIMEOUT] , 30);
3177 conf_init_int (&conf_data[CNF_TAPEBUFS] , 20);
3178 conf_init_size (&conf_data[CNF_DEVICE_OUTPUT_BUFFER_SIZE], 40*32768);
3179 conf_init_str (&conf_data[CNF_PRINTER] , "");
3180 conf_init_bool (&conf_data[CNF_AUTOFLUSH] , 0);
3181 conf_init_int (&conf_data[CNF_RESERVE] , 100);
3182 conf_init_am64 (&conf_data[CNF_MAXDUMPSIZE] , (off_t)-1);
3183 conf_init_str (&conf_data[CNF_COLUMNSPEC] , "");
3184 conf_init_bool (&conf_data[CNF_AMRECOVER_DO_FSF] , 1);
3185 conf_init_str (&conf_data[CNF_AMRECOVER_CHANGER] , "");
3186 conf_init_bool (&conf_data[CNF_AMRECOVER_CHECK_LABEL], 1);
3187 conf_init_taperalgo(&conf_data[CNF_TAPERALGO] , 0);
3188 conf_init_int (&conf_data[CNF_FLUSH_THRESHOLD_DUMPED] , 0);
3189 conf_init_int (&conf_data[CNF_FLUSH_THRESHOLD_SCHEDULED], 0);
3190 conf_init_int (&conf_data[CNF_TAPERFLUSH] , 0);
3191 conf_init_str (&conf_data[CNF_DISPLAYUNIT] , "k");
3192 conf_init_str (&conf_data[CNF_KRB5KEYTAB] , "/.amanda-v5-keytab");
3193 conf_init_str (&conf_data[CNF_KRB5PRINCIPAL] , "service/amanda");
3194 conf_init_str (&conf_data[CNF_LABEL_NEW_TAPES] , "");
3195 conf_init_bool (&conf_data[CNF_USETIMESTAMPS] , 1);
3196 conf_init_int (&conf_data[CNF_CONNECT_TRIES] , 3);
3197 conf_init_int (&conf_data[CNF_REP_TRIES] , 5);
3198 conf_init_int (&conf_data[CNF_REQ_TRIES] , 3);
3199 conf_init_int (&conf_data[CNF_DEBUG_AMANDAD] , 0);
3200 conf_init_int (&conf_data[CNF_DEBUG_AMIDXTAPED] , 0);
3201 conf_init_int (&conf_data[CNF_DEBUG_AMINDEXD] , 0);
3202 conf_init_int (&conf_data[CNF_DEBUG_AMRECOVER] , 0);
3203 conf_init_int (&conf_data[CNF_DEBUG_AUTH] , 0);
3204 conf_init_int (&conf_data[CNF_DEBUG_EVENT] , 0);
3205 conf_init_int (&conf_data[CNF_DEBUG_HOLDING] , 0);
3206 conf_init_int (&conf_data[CNF_DEBUG_PROTOCOL] , 0);
3207 conf_init_int (&conf_data[CNF_DEBUG_PLANNER] , 0);
3208 conf_init_int (&conf_data[CNF_DEBUG_DRIVER] , 0);
3209 conf_init_int (&conf_data[CNF_DEBUG_DUMPER] , 0);
3210 conf_init_int (&conf_data[CNF_DEBUG_CHUNKER] , 0);
3211 conf_init_int (&conf_data[CNF_DEBUG_TAPER] , 0);
3212 conf_init_int (&conf_data[CNF_DEBUG_SELFCHECK] , 0);
3213 conf_init_int (&conf_data[CNF_DEBUG_SENDSIZE] , 0);
3214 conf_init_int (&conf_data[CNF_DEBUG_SENDBACKUP] , 0);
3216 conf_init_intrange (&conf_data[CNF_RESERVED_UDP_PORT] , UDPPORTRANGE);
3218 conf_init_intrange (&conf_data[CNF_RESERVED_UDP_PORT] , 512, IPPORT_RESERVED-1);
3220 #ifdef LOW_TCPPORTRANGE
3221 conf_init_intrange (&conf_data[CNF_RESERVED_TCP_PORT] , LOW_TCPPORTRANGE);
3223 conf_init_intrange (&conf_data[CNF_RESERVED_TCP_PORT] , 512, IPPORT_RESERVED-1);
3226 conf_init_intrange (&conf_data[CNF_UNRESERVED_TCP_PORT] , TCPPORTRANGE);
3228 conf_init_intrange (&conf_data[CNF_UNRESERVED_TCP_PORT] , IPPORT_RESERVED, 65535);
3231 /* reset internal variables */
3232 got_parserror = FALSE;
3233 allow_overwrites = 0;
3236 /* create some predefined dumptypes for backwards compatability */
3237 init_dumptype_defaults();
3238 dpcur.name = stralloc("NO-COMPRESS");
3240 free_val_t(&dpcur.value[DUMPTYPE_COMPRESS]);
3241 val_t__compress(&dpcur.value[DUMPTYPE_COMPRESS]) = COMP_NONE;
3242 val_t__seen(&dpcur.value[DUMPTYPE_COMPRESS]) = -1;
3245 init_dumptype_defaults();
3246 dpcur.name = stralloc("COMPRESS-FAST");
3248 free_val_t(&dpcur.value[DUMPTYPE_COMPRESS]);
3249 val_t__compress(&dpcur.value[DUMPTYPE_COMPRESS]) = COMP_FAST;
3250 val_t__seen(&dpcur.value[DUMPTYPE_COMPRESS]) = -1;
3253 init_dumptype_defaults();
3254 dpcur.name = stralloc("COMPRESS-BEST");
3256 free_val_t(&dpcur.value[DUMPTYPE_COMPRESS]);
3257 val_t__compress(&dpcur.value[DUMPTYPE_COMPRESS]) = COMP_BEST;
3258 val_t__seen(&dpcur.value[DUMPTYPE_COMPRESS]) = -1;
3261 init_dumptype_defaults();
3262 dpcur.name = stralloc("COMPRESS-CUST");
3264 free_val_t(&dpcur.value[DUMPTYPE_COMPRESS]);
3265 val_t__compress(&dpcur.value[DUMPTYPE_COMPRESS]) = COMP_CUST;
3266 val_t__seen(&dpcur.value[DUMPTYPE_COMPRESS]) = -1;
3269 init_dumptype_defaults();
3270 dpcur.name = stralloc("SRVCOMPRESS");
3272 free_val_t(&dpcur.value[DUMPTYPE_COMPRESS]);
3273 val_t__compress(&dpcur.value[DUMPTYPE_COMPRESS]) = COMP_SERVER_FAST;
3274 val_t__seen(&dpcur.value[DUMPTYPE_COMPRESS]) = -1;
3277 init_dumptype_defaults();
3278 dpcur.name = stralloc("BSD-AUTH");
3280 free_val_t(&dpcur.value[DUMPTYPE_SECURITY_DRIVER]);
3281 val_t__str(&dpcur.value[DUMPTYPE_SECURITY_DRIVER]) = stralloc("BSD");
3282 val_t__seen(&dpcur.value[DUMPTYPE_SECURITY_DRIVER]) = -1;
3285 init_dumptype_defaults();
3286 dpcur.name = stralloc("KRB4-AUTH");
3288 free_val_t(&dpcur.value[DUMPTYPE_SECURITY_DRIVER]);
3289 val_t__str(&dpcur.value[DUMPTYPE_SECURITY_DRIVER]) = stralloc("KRB4");
3290 val_t__seen(&dpcur.value[DUMPTYPE_SECURITY_DRIVER]) = -1;
3293 init_dumptype_defaults();
3294 dpcur.name = stralloc("NO-RECORD");
3296 free_val_t(&dpcur.value[DUMPTYPE_RECORD]);
3297 val_t__int(&dpcur.value[DUMPTYPE_RECORD]) = 0;
3298 val_t__seen(&dpcur.value[DUMPTYPE_RECORD]) = -1;
3301 init_dumptype_defaults();
3302 dpcur.name = stralloc("NO-HOLD");
3304 free_val_t(&dpcur.value[DUMPTYPE_HOLDINGDISK]);
3305 val_t__holding(&dpcur.value[DUMPTYPE_HOLDINGDISK]) = HOLD_NEVER;
3306 val_t__seen(&dpcur.value[DUMPTYPE_HOLDINGDISK]) = -1;
3309 init_dumptype_defaults();
3310 dpcur.name = stralloc("NO-FULL");
3312 free_val_t(&dpcur.value[DUMPTYPE_STRATEGY]);
3313 val_t__strategy(&dpcur.value[DUMPTYPE_STRATEGY]) = DS_NOFULL;
3314 val_t__seen(&dpcur.value[DUMPTYPE_STRATEGY]) = -1;
3317 /* And we're initialized! */
3318 config_initialized = 1;
3325 char **config_options;
3326 char **config_option;
3327 int n_applied_config_overwrites = 0;
3330 if (applied_config_overwrites)
3331 n_applied_config_overwrites = applied_config_overwrites->n_used;
3333 config_options = alloc((first+n_applied_config_overwrites+1)*SIZEOF(char *));
3334 config_option = config_options + first;
3336 for (i = 0; i < n_applied_config_overwrites; i++) {
3337 char *key = applied_config_overwrites->ovr[i].key;
3338 char *value = applied_config_overwrites->ovr[i].value;
3339 *config_option = vstralloc("-o", key, "=", value, NULL);
3343 *config_option = NULL; /* add terminating sentinel */
3345 return config_options;
3349 update_derived_values(
3355 /* Add a 'default' interface if one doesn't already exist */
3356 if (!(ip = lookup_interface("default"))) {
3357 init_interface_defaults();
3358 ifcur.name = stralloc("default");
3359 ifcur.seen = getconf_seen(CNF_NETUSAGE);
3362 ip = lookup_interface("default");
3365 /* .. and set its maxusage from 'netusage' */
3366 if (!interface_seen(ip, INTER_MAXUSAGE)) {
3369 v = interface_getconf(ip, INTER_COMMENT);
3371 val_t__str(v) = stralloc(_("implicit from NETUSAGE"));
3372 val_t__seen(v) = getconf_seen(CNF_NETUSAGE);
3374 v = interface_getconf(ip, INTER_MAXUSAGE);
3376 val_t__int(v) = getconf_int(CNF_NETUSAGE);
3377 val_t__seen(v) = getconf_seen(CNF_NETUSAGE);
3380 /* Check the tapetype is defined */
3381 if (lookup_tapetype(getconf_str(CNF_TAPETYPE)) == NULL) {
3382 /* Create a default tapetype */
3383 if (!getconf_seen(CNF_TAPETYPE) &&
3384 strcmp(getconf_str(CNF_TAPETYPE), "EXABYTE") == 0 &&
3385 !lookup_tapetype("EXABYTE")) {
3386 init_tapetype_defaults();
3387 tpcur.name = stralloc("EXABYTE");
3391 conf_parserror(_("tapetype %s is not defined"),
3392 getconf_str(CNF_TAPETYPE));
3397 /* fill in the debug_* values */
3398 debug_amandad = getconf_int(CNF_DEBUG_AMANDAD);
3399 debug_amidxtaped = getconf_int(CNF_DEBUG_AMIDXTAPED);
3400 debug_amindexd = getconf_int(CNF_DEBUG_AMINDEXD);
3401 debug_amrecover = getconf_int(CNF_DEBUG_AMRECOVER);
3402 debug_auth = getconf_int(CNF_DEBUG_AUTH);
3403 debug_event = getconf_int(CNF_DEBUG_EVENT);
3404 debug_holding = getconf_int(CNF_DEBUG_HOLDING);
3405 debug_protocol = getconf_int(CNF_DEBUG_PROTOCOL);
3406 debug_planner = getconf_int(CNF_DEBUG_PLANNER);
3407 debug_driver = getconf_int(CNF_DEBUG_DRIVER);
3408 debug_dumper = getconf_int(CNF_DEBUG_DUMPER);
3409 debug_chunker = getconf_int(CNF_DEBUG_CHUNKER);
3410 debug_taper = getconf_int(CNF_DEBUG_TAPER);
3411 debug_selfcheck = getconf_int(CNF_DEBUG_SELFCHECK);
3412 debug_sendsize = getconf_int(CNF_DEBUG_SENDSIZE);
3413 debug_sendbackup = getconf_int(CNF_DEBUG_SENDBACKUP);
3415 /* And finally, display unit */
3416 switch (getconf_str(CNF_DISPLAYUNIT)[0]) {
3424 unit_divisor = 1024;
3429 unit_divisor = 1024*1024;
3434 unit_divisor = 1024*1024*1024;
3438 error(_("Invalid displayunit missed by validate_displayunit"));
3449 val->type = CONFTYPE_INT;
3450 val_t__int(val) = i;
3459 val->type = CONFTYPE_AM64;
3460 val_t__am64(val) = l;
3469 val->type = CONFTYPE_REAL;
3470 val_t__real(val) = r;
3479 val->type = CONFTYPE_STR;
3481 val->v.s = stralloc(s);
3492 val->type = CONFTYPE_IDENT;
3494 val->v.s = stralloc(s);
3505 val->type = CONFTYPE_TIME;
3506 val_t__time(val) = t;
3515 val->type = CONFTYPE_SIZE;
3516 val_t__size(val) = sz;
3525 val->type = CONFTYPE_BOOLEAN;
3526 val_t__boolean(val) = i;
3535 val->type = CONFTYPE_COMPRESS;
3536 val_t__compress(val) = (int)i;
3545 val->type = CONFTYPE_ENCRYPT;
3546 val_t__encrypt(val) = (int)i;
3552 dump_holdingdisk_t i)
3555 val->type = CONFTYPE_HOLDING;
3556 val_t__holding(val) = (int)i;
3565 val->type = CONFTYPE_ESTIMATE;
3566 val_t__estimate(val) = i;
3575 val->type = CONFTYPE_STRATEGY;
3576 val_t__strategy(val) = i;
3580 conf_init_taperalgo(
3585 val->type = CONFTYPE_TAPERALGO;
3586 val_t__taperalgo(val) = i;
3595 val->type = CONFTYPE_PRIORITY;
3596 val_t__priority(val) = i;
3606 val->type = CONFTYPE_RATE;
3607 val_t__rate(val)[0] = r1;
3608 val_t__rate(val)[1] = r2;
3612 conf_init_exinclude(
3616 val->type = CONFTYPE_EXINCLUDE;
3617 val_t__exinclude(val).optional = 0;
3618 val_t__exinclude(val).sl_list = NULL;
3619 val_t__exinclude(val).sl_file = NULL;
3629 val->type = CONFTYPE_INTRANGE;
3630 val_t__intrange(val)[0] = i1;
3631 val_t__intrange(val)[1] = i2;
3639 val->type = CONFTYPE_PROPLIST;
3640 val_t__proplist(val) =
3641 g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
3645 * Config access implementation
3649 getconf(confparm_key key)
3651 assert(key < CNF_CNF);
3652 return &conf_data[key];
3665 if (strcasecmp(listname,"tapetype") == 0) {
3666 for(tp = tapelist; tp != NULL; tp=tp->next) {
3667 rv = g_slist_append(rv, tp->name);
3669 } else if (strcasecmp(listname,"dumptype") == 0) {
3670 for(dp = dumplist; dp != NULL; dp=dp->next) {
3671 rv = g_slist_append(rv, dp->name);
3673 } else if (strcasecmp(listname,"holdingdisk") == 0) {
3674 for(hp = holdinglist; hp != NULL; hp=hp->next) {
3675 rv = g_slist_append(rv, hp->name);
3677 } else if (strcasecmp(listname,"interface") == 0) {
3678 for(ip = interface_list; ip != NULL; ip=ip->next) {
3679 rv = g_slist_append(rv, ip->name);
3691 if (!parm_key_info(key, NULL, &rv))
3703 for(p = tapelist; p != NULL; p = p->next) {
3704 if(strcasecmp(p->name, str) == 0) return p;
3714 assert(ttyp != NULL);
3715 assert(key < TAPETYPE_TAPETYPE);
3716 return &ttyp->value[key];
3723 assert(ttyp != NULL);
3733 for(p = dumplist; p != NULL; p = p->next) {
3734 if(strcasecmp(p->name, str) == 0) return p;
3744 assert(dtyp != NULL);
3745 assert(key < DUMPTYPE_DUMPTYPE);
3746 return &dtyp->value[key];
3753 assert(dtyp != NULL);
3763 for(p = interface_list; p != NULL; p = p->next) {
3764 if(strcasecmp(p->name, str) == 0) return p;
3774 assert(iface != NULL);
3775 assert(key < INTER_INTER);
3776 return &iface->value[key];
3783 assert(iface != NULL);
3793 for(p = holdinglist; p != NULL; p = p->next) {
3794 if(strcasecmp(p->name, str) == 0) return p;
3800 getconf_holdingdisks(
3808 holdingdisk_t *hdisk)
3810 if (hdisk) return hdisk->next;
3815 holdingdisk_getconf(
3816 holdingdisk_t *hdisk,
3817 holdingdisk_key key)
3819 assert(hdisk != NULL);
3820 assert(key < HOLDING_HOLDING);
3821 return &hdisk->value[key];
3826 holdingdisk_t *hdisk)
3828 assert(hdisk != NULL);
3833 getconf_unit_divisor(void)
3835 return unit_divisor;
3839 * Command-line Handling Implementation
3842 config_overwrites_t *
3843 new_config_overwrites(
3846 config_overwrites_t *co;
3848 co = alloc(sizeof(*co));
3849 co->ovr = alloc(sizeof(*co->ovr) * size_estimate);
3850 co->n_allocated = size_estimate;
3857 free_config_overwrites(
3858 config_overwrites_t *co)
3863 for (i = 0; i < co->n_used; i++) {
3864 amfree(co->ovr[i].key);
3865 amfree(co->ovr[i].value);
3871 void add_config_overwrite(
3872 config_overwrites_t *co,
3876 /* reallocate if necessary */
3877 if (co->n_used == co->n_allocated) {
3878 co->n_allocated *= 2;
3879 co->ovr = realloc(co->ovr, co->n_allocated * sizeof(*co->ovr));
3881 error(_("Cannot realloc; out of memory"));
3886 co->ovr[co->n_used].key = stralloc(key);
3887 co->ovr[co->n_used].value = stralloc(value);
3892 add_config_overwrite_opt(
3893 config_overwrites_t *co,
3897 assert(optarg != NULL);
3899 value = index(optarg, '=');
3900 if (value == NULL) {
3901 error(_("Must specify a value for %s."), optarg);
3906 add_config_overwrite(co, optarg, value+1);
3910 config_overwrites_t *
3911 extract_commandline_config_overwrites(
3916 config_overwrites_t *co = new_config_overwrites(*argc/2);
3920 if(strncmp((*argv)[i],"-o",2) == 0) {
3921 if(strlen((*argv)[i]) > 2) {
3922 add_config_overwrite_opt(co, (*argv)[i]+2);
3926 if (i+1 >= *argc) error(_("expect something after -o"));
3927 add_config_overwrite_opt(co, (*argv)[i+1]);
3931 /* move up remaining argment array */
3932 for (j = i; j+moveup<*argc; j++) {
3933 (*argv)[j] = (*argv)[j+moveup];
3945 apply_config_overwrites(
3946 config_overwrites_t *co)
3951 assert(keytable != NULL);
3952 assert(parsetable != NULL);
3954 for (i = 0; i < co->n_used; i++) {
3955 char *key = co->ovr[i].key;
3956 char *value = co->ovr[i].value;
3958 conf_var_t *key_parm;
3960 if (!parm_key_info(key, &key_parm, &key_val)) {
3961 error(_("unknown parameter '%s'"), key);
3964 /* now set up a fake line and use the relevant read_function to
3965 * parse it. This is sneaky! */
3967 if (key_parm->type == CONFTYPE_STR) {
3968 current_line = vstralloc("\"", value, "\"", NULL);
3970 current_line = stralloc(value);
3973 current_char = current_line;
3975 current_line_num = -2;
3976 allow_overwrites = 1;
3979 key_parm->read_function(key_parm, key_val);
3980 if ((key_parm)->validate_function)
3981 key_parm->validate_function(key_parm, key_val);
3983 amfree(current_line);
3984 current_char = NULL;
3986 if (got_parserror) {
3987 error(_("parse error in configuration overwrites"));
3992 /* merge these overwrites with previous overwrites, if necessary */
3993 if (applied_config_overwrites) {
3994 for (i = 0; i < co->n_used; i++) {
3995 char *key = co->ovr[i].key;
3996 char *value = co->ovr[i].value;
3998 add_config_overwrite(applied_config_overwrites, key, value);
4000 free_config_overwrites(co);
4002 applied_config_overwrites = co;
4005 update_derived_values(config_client);
4009 * val_t Management Implementation
4016 if (val->type != CONFTYPE_INT) {
4017 error(_("val_t_to_int: val.type is not CONFTYPE_INT"));
4020 return val_t__int(val);
4027 if (val->type != CONFTYPE_AM64) {
4028 error(_("val_t_to_am64: val.type is not CONFTYPE_AM64"));
4031 return val_t__am64(val);
4038 if (val->type != CONFTYPE_REAL) {
4039 error(_("val_t_to_real: val.type is not CONFTYPE_REAL"));
4042 return val_t__real(val);
4049 /* support CONFTYPE_IDENT, too */
4050 if (val->type != CONFTYPE_STR && val->type != CONFTYPE_IDENT) {
4051 error(_("val_t_to_str: val.type is not CONFTYPE_STR nor CONFTYPE_IDENT"));
4054 return val_t__str(val);
4061 /* support CONFTYPE_STR, too */
4062 if (val->type != CONFTYPE_STR && val->type != CONFTYPE_IDENT) {
4063 error(_("val_t_to_ident: val.type is not CONFTYPE_IDENT nor CONFTYPE_STR"));
4066 return val_t__str(val);
4073 if (val->type != CONFTYPE_TIME) {
4074 error(_("val_t_to_time: val.type is not CONFTYPE_TIME"));
4077 return val_t__time(val);
4084 if (val->type != CONFTYPE_SIZE) {
4085 error(_("val_t_to_size: val.type is not CONFTYPE_SIZE"));
4088 return val_t__size(val);
4095 if (val->type != CONFTYPE_BOOLEAN) {
4096 error(_("val_t_to_bool: val.type is not CONFTYPE_BOOLEAN"));
4099 return val_t__boolean(val);
4106 if (val->type != CONFTYPE_COMPRESS) {
4107 error(_("val_t_to_compress: val.type is not CONFTYPE_COMPRESS"));
4110 return val_t__compress(val);
4117 if (val->type != CONFTYPE_ENCRYPT) {
4118 error(_("val_t_to_encrypt: val.type is not CONFTYPE_ENCRYPT"));
4121 return val_t__encrypt(val);
4128 if (val->type != CONFTYPE_HOLDING) {
4129 error(_("val_t_to_hold: val.type is not CONFTYPE_HOLDING"));
4132 return val_t__holding(val);
4139 if (val->type != CONFTYPE_ESTIMATE) {
4140 error(_("val_t_to_extimate: val.type is not CONFTYPE_ESTIMATE"));
4143 return val_t__estimate(val);
4150 if (val->type != CONFTYPE_STRATEGY) {
4151 error(_("val_t_to_strategy: val.type is not CONFTYPE_STRATEGY"));
4154 return val_t__strategy(val);
4161 if (val->type != CONFTYPE_TAPERALGO) {
4162 error(_("val_t_to_taperalgo: val.type is not CONFTYPE_TAPERALGO"));
4165 return val_t__taperalgo(val);
4172 if (val->type != CONFTYPE_PRIORITY) {
4173 error(_("val_t_to_priority: val.type is not CONFTYPE_PRIORITY"));
4176 return val_t__priority(val);
4183 if (val->type != CONFTYPE_RATE) {
4184 error(_("val_t_to_rate: val.type is not CONFTYPE_RATE"));
4187 return val_t__rate(val);
4194 if (val->type != CONFTYPE_EXINCLUDE) {
4195 error(_("val_t_to_exinclude: val.type is not CONFTYPE_EXINCLUDE"));
4198 return val_t__exinclude(val);
4206 if (val->type != CONFTYPE_INTRANGE) {
4207 error(_("val_t_to_intrange: val.type is not CONFTYPE_INTRANGE"));
4210 return val_t__intrange(val);
4217 if (val->type != CONFTYPE_PROPLIST) {
4218 error(_("val_t_to_proplist: val.type is not CONFTYPE_PROPLIST"));
4221 return val_t__proplist(val);
4230 valdst->type = valsrc->type;
4231 valdst->seen = valsrc->seen;
4232 switch(valsrc->type) {
4234 case CONFTYPE_BOOLEAN:
4235 case CONFTYPE_COMPRESS:
4236 case CONFTYPE_ENCRYPT:
4237 case CONFTYPE_HOLDING:
4238 case CONFTYPE_ESTIMATE:
4239 case CONFTYPE_STRATEGY:
4240 case CONFTYPE_TAPERALGO:
4241 case CONFTYPE_PRIORITY:
4242 valdst->v.i = valsrc->v.i;
4246 valdst->v.size = valsrc->v.size;
4250 valdst->v.am64 = valsrc->v.am64;
4254 valdst->v.r = valsrc->v.r;
4258 valdst->v.rate[0] = valsrc->v.rate[0];
4259 valdst->v.rate[1] = valsrc->v.rate[1];
4262 case CONFTYPE_IDENT:
4264 valdst->v.s = stralloc(valsrc->v.s);
4268 valdst->v.t = valsrc->v.t;
4271 case CONFTYPE_EXINCLUDE:
4272 valdst->v.exinclude.optional = valsrc->v.exinclude.optional;
4273 valdst->v.exinclude.sl_list = duplicate_sl(valsrc->v.exinclude.sl_list);
4274 valdst->v.exinclude.sl_file = duplicate_sl(valsrc->v.exinclude.sl_file);
4277 case CONFTYPE_INTRANGE:
4278 valdst->v.intrange[0] = valsrc->v.intrange[0];
4279 valdst->v.intrange[1] = valsrc->v.intrange[1];
4282 case CONFTYPE_PROPLIST:
4283 g_assert_not_reached();
4295 case CONFTYPE_BOOLEAN:
4296 case CONFTYPE_COMPRESS:
4297 case CONFTYPE_ENCRYPT:
4298 case CONFTYPE_HOLDING:
4299 case CONFTYPE_ESTIMATE:
4300 case CONFTYPE_STRATEGY:
4302 case CONFTYPE_TAPERALGO:
4303 case CONFTYPE_PRIORITY:
4307 case CONFTYPE_INTRANGE:
4310 case CONFTYPE_IDENT:
4318 case CONFTYPE_EXINCLUDE:
4319 free_sl(val_t__exinclude(val).sl_list);
4320 free_sl(val_t__exinclude(val).sl_file);
4323 case CONFTYPE_PROPLIST:
4324 g_hash_table_destroy(val_t__proplist(val));
4331 * Utilities Implementation
4335 generic_get_security_conf(
4340 if(!string || !*string)
4343 if(strcmp(string, "krb5principal")==0) {
4344 return(getconf_str(CNF_KRB5PRINCIPAL));
4345 } else if(strcmp(string, "krb5keytab")==0) {
4346 return(getconf_str(CNF_KRB5KEYTAB));
4352 generic_client_get_security_conf(
4356 (void)arg; /* Quiet unused parameter warning */
4358 if(!string || !*string)
4361 if(strcmp(string, "conf")==0) {
4362 return(getconf_str(CNF_CONF));
4363 } else if(strcmp(string, "index_server")==0) {
4364 return(getconf_str(CNF_INDEX_SERVER));
4365 } else if(strcmp(string, "tape_server")==0) {
4366 return(getconf_str(CNF_TAPE_SERVER));
4367 } else if(strcmp(string, "tapedev")==0) {
4368 return(getconf_str(CNF_TAPEDEV));
4369 } else if(strcmp(string, "auth")==0) {
4370 return(getconf_str(CNF_AUTH));
4371 } else if(strcmp(string, "ssh_keys")==0) {
4372 return(getconf_str(CNF_SSH_KEYS));
4373 } else if(strcmp(string, "amandad_path")==0) {
4374 return(getconf_str(CNF_AMANDAD_PATH));
4375 } else if(strcmp(string, "client_username")==0) {
4376 return(getconf_str(CNF_CLIENT_USERNAME));
4377 } else if(strcmp(string, "gnutar_list_dir")==0) {
4378 return(getconf_str(CNF_GNUTAR_LIST_DIR));
4379 } else if(strcmp(string, "amandates")==0) {
4380 return(getconf_str(CNF_AMANDATES));
4381 } else if(strcmp(string, "krb5principal")==0) {
4382 return(getconf_str(CNF_KRB5PRINCIPAL));
4383 } else if(strcmp(string, "krb5keytab")==0) {
4384 return(getconf_str(CNF_KRB5KEYTAB));
4390 dump_configuration(void)
4401 if (config_client) {
4402 error(_("Don't know how to dump client configurations."));
4406 g_printf(_("# AMANDA CONFIGURATION FROM FILE \"%s\":\n\n"), config_filename);
4408 for(np=server_var; np->token != CONF_UNKNOWN; np++) {
4409 for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
4410 if (np->token == kt->token) break;
4412 if(kt->token == CONF_UNKNOWN)
4413 error(_("server bad token"));
4415 val_t_print_token(stdout, NULL, "%-21s ", kt, &conf_data[np->parm]);
4418 for(hp = holdinglist; hp != NULL; hp = hp->next) {
4419 g_printf("\nHOLDINGDISK %s {\n", hp->name);
4420 for(i=0; i < HOLDING_HOLDING; i++) {
4421 for(np=holding_var; np->token != CONF_UNKNOWN; np++) {
4425 if(np->token == CONF_UNKNOWN)
4426 error(_("holding bad value"));
4428 for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++) {
4429 if(kt->token == np->token)
4432 if(kt->token == CONF_UNKNOWN)
4433 error(_("holding bad token"));
4435 val_t_print_token(stdout, NULL, " %-9s ", kt, &hp->value[i]);
4440 for(tp = tapelist; tp != NULL; tp = tp->next) {
4445 g_printf("\n%sDEFINE TAPETYPE %s {\n", prefix, tp->name);
4446 for(i=0; i < TAPETYPE_TAPETYPE; i++) {
4447 for(np=tapetype_var; np->token != CONF_UNKNOWN; np++)
4448 if(np->parm == i) break;
4449 if(np->token == CONF_UNKNOWN)
4450 error(_("tapetype bad value"));
4452 for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
4453 if(kt->token == np->token) break;
4454 if(kt->token == CONF_UNKNOWN)
4455 error(_("tapetype bad token"));
4457 val_t_print_token(stdout, prefix, " %-9s ", kt, &tp->value[i]);
4459 g_printf("%s}\n", prefix);
4462 for(dp = dumplist; dp != NULL; dp = dp->next) {
4463 if (strncmp_const(dp->name, "custom(") != 0) { /* don't dump disklist-derived dumptypes */
4468 g_printf("\n%sDEFINE DUMPTYPE %s {\n", prefix, dp->name);
4469 for(i=0; i < DUMPTYPE_DUMPTYPE; i++) {
4470 for(np=dumptype_var; np->token != CONF_UNKNOWN; np++)
4471 if(np->parm == i) break;
4472 if(np->token == CONF_UNKNOWN)
4473 error(_("dumptype bad value"));
4475 for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
4476 if(kt->token == np->token) break;
4477 if(kt->token == CONF_UNKNOWN)
4478 error(_("dumptype bad token"));
4480 val_t_print_token(stdout, prefix, " %-19s ", kt, &dp->value[i]);
4482 g_printf("%s}\n", prefix);
4486 for(ip = interface_list; ip != NULL; ip = ip->next) {
4487 if(strcmp(ip->name,"default") == 0)
4491 g_printf("\n%sDEFINE INTERFACE %s {\n", prefix, ip->name);
4492 for(i=0; i < INTER_INTER; i++) {
4493 for(np=interface_var; np->token != CONF_UNKNOWN; np++)
4494 if(np->parm == i) break;
4495 if(np->token == CONF_UNKNOWN)
4496 error(_("interface bad value"));
4498 for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
4499 if(kt->token == np->token) break;
4500 if(kt->token == CONF_UNKNOWN)
4501 error(_("interface bad token"));
4503 val_t_print_token(stdout, prefix, " %-19s ", kt, &ip->value[i]);
4505 g_printf("%s}\n",prefix);
4518 char **dispstrs, **dispstr;
4519 dispstrs = val_t_display_strs(val, 1);
4521 /* For most configuration types, this outputs
4522 * PREFIX KEYWORD DISPSTR
4523 * for each of the display strings. For identifiers, however, it
4524 * simply prints the first line of the display string.
4527 /* Print the keyword for anything that is not itself an identifier */
4528 if (kt->token != CONF_IDENT) {
4529 for(dispstr=dispstrs; *dispstr!=NULL; dispstr++) {
4531 g_fprintf(output, "%s", prefix);
4532 g_fprintf(output, format, kt->keyword);
4533 g_fprintf(output, "%s\n", *dispstr);
4536 /* for identifiers, assume there's at most one display string */
4537 assert(g_strv_length(dispstrs) <= 1);
4539 g_fprintf(output, "%s\n", *dispstrs);
4543 g_strfreev(dispstrs);
4552 buf = malloc(3*SIZEOF(char *));
4559 buf[0] = vstrallocf("%d", val_t__int(val));
4563 buf[0] = vstrallocf("%zd", (ssize_t)val_t__size(val));
4567 buf[0] = vstrallocf("%lld", (long long)val_t__am64(val));
4571 buf[0] = vstrallocf("%0.5f", val_t__real(val));
4575 buf[0] = vstrallocf("%0.5f %0.5f", val_t__rate(val)[0], val_t__rate(val)[1]);
4578 case CONFTYPE_INTRANGE:
4579 buf[0] = vstrallocf("%d,%d", val_t__intrange(val)[0], val_t__intrange(val)[1]);
4582 case CONFTYPE_IDENT:
4584 buf[0] = stralloc(val->v.s);
4586 buf[0] = stralloc("");
4591 if(str_need_quote) {
4593 buf[0] = vstrallocf("\"%s\"", val->v.s);
4595 buf[0] = stralloc("\"\"");
4599 buf[0] = stralloc(val->v.s);
4601 buf[0] = stralloc("");
4607 buf[0] = vstrallocf("%2d%02d",
4608 (int)val_t__time(val)/100, (int)val_t__time(val) % 100);
4611 case CONFTYPE_EXINCLUDE: {
4612 buf[0] = exinclude_display_str(val, 0);
4613 buf[1] = exinclude_display_str(val, 1);
4617 case CONFTYPE_BOOLEAN:
4618 if(val_t__boolean(val))
4619 buf[0] = stralloc("yes");
4621 buf[0] = stralloc("no");
4624 case CONFTYPE_STRATEGY:
4625 switch(val_t__strategy(val)) {
4627 buf[0] = vstrallocf("SKIP");
4631 buf[0] = vstrallocf("STANDARD");
4635 buf[0] = vstrallocf("NOFULL");
4639 buf[0] = vstrallocf("NOINC");
4643 buf[0] = vstrallocf("HANOI");
4647 buf[0] = vstrallocf("INCRONLY");
4652 case CONFTYPE_COMPRESS:
4653 switch(val_t__compress(val)) {
4655 buf[0] = vstrallocf("NONE");
4659 buf[0] = vstrallocf("CLIENT FAST");
4663 buf[0] = vstrallocf("CLIENT BEST");
4667 buf[0] = vstrallocf("CLIENT CUSTOM");
4670 case COMP_SERVER_FAST:
4671 buf[0] = vstrallocf("SERVER FAST");
4674 case COMP_SERVER_BEST:
4675 buf[0] = vstrallocf("SERVER BEST");
4678 case COMP_SERVER_CUST:
4679 buf[0] = vstrallocf("SERVER CUSTOM");
4684 case CONFTYPE_ESTIMATE:
4685 switch(val_t__estimate(val)) {
4687 buf[0] = vstrallocf("CLIENT");
4691 buf[0] = vstrallocf("SERVER");
4695 buf[0] = vstrallocf("CALCSIZE");
4700 case CONFTYPE_ENCRYPT:
4701 switch(val_t__encrypt(val)) {
4703 buf[0] = vstrallocf("NONE");
4707 buf[0] = vstrallocf("CLIENT");
4710 case ENCRYPT_SERV_CUST:
4711 buf[0] = vstrallocf("SERVER");
4716 case CONFTYPE_HOLDING:
4717 switch(val_t__holding(val)) {
4719 buf[0] = vstrallocf("NEVER");
4723 buf[0] = vstrallocf("AUTO");
4727 buf[0] = vstrallocf("REQUIRED");
4732 case CONFTYPE_TAPERALGO:
4733 buf[0] = vstrallocf("%s", taperalgo2str(val_t__taperalgo(val)));
4736 case CONFTYPE_PRIORITY:
4737 switch(val_t__priority(val)) {
4739 buf[0] = vstrallocf("LOW");
4743 buf[0] = vstrallocf("MEDIUM");
4747 buf[0] = vstrallocf("HIGH");
4752 case CONFTYPE_PROPLIST: {
4756 nb_property = g_hash_table_size(val_t__proplist(val));
4758 buf = malloc((nb_property+1)*SIZEOF(char*));
4759 buf[nb_property] = NULL;
4761 g_hash_table_foreach(val_t__proplist(val), proplist_display_str_foreach_fn, &mybuf);
4769 proplist_display_str_foreach_fn(
4772 gpointer user_data_p)
4774 char *property_s = key_p;
4775 char *value_s = value_p;
4776 char ***msg = (char ***)user_data_p;
4778 **msg = vstralloc("\"", property_s, "\" \"", value_s, "\"", NULL);
4783 exinclude_display_str(
4791 assert(val->type == CONFTYPE_EXINCLUDE);
4793 rval = stralloc("");
4796 sl = val_t__exinclude(val).sl_list;
4797 strappend(rval, "LIST");
4799 sl = val_t__exinclude(val).sl_file;
4800 strappend(rval, "FILE");
4803 if (val_t__exinclude(val).optional == 1) {
4804 strappend(rval, " OPTIONAL");
4808 for(excl = sl->first; excl != NULL; excl = excl->next) {
4809 vstrextend(&rval, " \"", excl->name, "\"", NULL);
4818 taperalgo_t taperalgo)
4820 if(taperalgo == ALGO_FIRST) return "FIRST";
4821 if(taperalgo == ALGO_FIRSTFIT) return "FIRSTFIT";
4822 if(taperalgo == ALGO_LARGEST) return "LARGEST";
4823 if(taperalgo == ALGO_LARGESTFIT) return "LARGESTFIT";
4824 if(taperalgo == ALGO_SMALLEST) return "SMALLEST";
4825 if(taperalgo == ALGO_LAST) return "LAST";
4830 config_dir_relative(
4833 if (*filename == '/' || config_dir == NULL) {
4834 return stralloc(filename);
4836 if (config_dir[strlen(config_dir)-1] == '/') {
4837 return vstralloc(config_dir, filename, NULL);
4839 return vstralloc(config_dir, "/", filename, NULL);
4861 int success = FALSE;
4863 /* WARNING: assumes globals keytable and parsetable are set correctly. */
4864 assert(keytable != NULL);
4865 assert(parsetable != NULL);
4867 /* make a copy we can stomp on */
4868 key = stralloc(key);
4870 /* uppercase the key */
4872 for (s = key; (ch = *s) != 0; s++) {
4873 if(islower((int)ch))
4874 *s = (char)toupper(ch);
4877 subsec_name = strchr(key, ':');
4881 *subsec_name = '\0';
4884 subsec_key = strchr(subsec_name,':');
4885 if(!subsec_key) goto out; /* failure */
4890 /* If the keyword doesn't exist, there's no need to look up the
4891 * subsection -- we know it's invalid */
4892 for(kt = keytable; kt->token != CONF_UNKNOWN; kt++) {
4893 if(kt->keyword && strcmp(kt->keyword, subsec_key) == 0)
4896 if(kt->token == CONF_UNKNOWN) goto out;
4898 /* Otherwise, figure out which kind of subsection we're dealing with,
4899 * and parse against that. */
4900 if (strcmp(subsec_type, "TAPETYPE") == 0) {
4901 tp = lookup_tapetype(subsec_name);
4903 for(np = tapetype_var; np->token != CONF_UNKNOWN; np++) {
4904 if(np->token == kt->token)
4907 if (np->token == CONF_UNKNOWN) goto out;
4909 if (val) *val = &tp->value[np->parm];
4910 if (parm) *parm = np;
4912 } else if (strcmp(subsec_type, "DUMPTYPE") == 0) {
4913 dp = lookup_dumptype(subsec_name);
4915 for(np = dumptype_var; np->token != CONF_UNKNOWN; np++) {
4916 if(np->token == kt->token)
4919 if (np->token == CONF_UNKNOWN) goto out;
4921 if (val) *val = &dp->value[np->parm];
4922 if (parm) *parm = np;
4924 } else if (strcmp(subsec_type, "HOLDINGDISK") == 0) {
4925 hp = lookup_holdingdisk(subsec_name);
4927 for(np = holding_var; np->token != CONF_UNKNOWN; np++) {
4928 if(np->token == kt->token)
4931 if (np->token == CONF_UNKNOWN) goto out;
4933 if (val) *val = &hp->value[np->parm];
4934 if (parm) *parm = np;
4936 } else if (strcmp(subsec_type, "INTERFACE") == 0) {
4937 ip = lookup_interface(subsec_name);
4939 for(np = interface_var; np->token != CONF_UNKNOWN; np++) {
4940 if(np->token == kt->token)
4943 if (np->token == CONF_UNKNOWN) goto out;
4945 if (val) *val = &ip->value[np->parm];
4946 if (parm) *parm = np;
4950 /* No delimiters -- we're referencing a global config parameter */
4952 /* look up the keyword */
4953 for(kt = keytable; kt->token != CONF_UNKNOWN; kt++) {
4954 if(kt->keyword && strcmp(kt->keyword, key) == 0)
4957 if(kt->token == CONF_UNKNOWN) goto out;
4959 /* and then look that up in the parse table */
4960 for(np = parsetable; np->token != CONF_UNKNOWN; np++) {
4961 if(np->token == kt->token)
4964 if(np->token == CONF_UNKNOWN) goto out;
4966 if (val) *val = &conf_data[np->parm];
4967 if (parm) *parm = np;
4980 keytab_t * table_entry;
4981 char * str = g_utf8_strup(casestr, -1);
4989 for (table_entry = numb_keytable; table_entry->keyword != NULL;
4991 if (strcmp(casestr, table_entry->keyword) == 0) {
4993 switch (table_entry->token) {
4999 return 1024*1024*1024;
5002 case CONF_AMINFINITY:
5008 /* Should not happen. */
5014 /* None found; this is an error. */
5020 * Error Handling Implementaiton
5023 static void print_parse_problem(const char * format, va_list argp) {
5024 const char *xlated_fmt = gettext(format);
5027 g_fprintf(stderr, _("argument \"%s\": "), current_line);
5028 else if (current_filename && current_line_num > 0)
5029 g_fprintf(stderr, "\"%s\", line %d: ", current_filename, current_line_num);
5031 g_fprintf(stderr, _("parse error: "));
5033 g_vfprintf(stderr, xlated_fmt, argp);
5034 fputc('\n', stderr);
5037 printf_arglist_function(void conf_parserror, const char *, format)
5041 arglist_start(argp, format);
5042 print_parse_problem(format, argp);
5045 got_parserror = TRUE;
5048 printf_arglist_function(void conf_parswarn, const char *, format) {
5051 arglist_start(argp, format);
5052 print_parse_problem(format, argp);