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 { "DEVICE-PROPERTY", CONF_DEVICE_PROPERTY },
586 { "AUTH", CONF_AUTH },
587 { "SSH_KEYS", CONF_SSH_KEYS },
588 { "AMANDAD_PATH", CONF_AMANDAD_PATH },
589 { "CLIENT_USERNAME", CONF_CLIENT_USERNAME },
590 { "GNUTAR_LIST_DIR", CONF_GNUTAR_LIST_DIR },
591 { "AMANDATES", CONF_AMANDATES },
592 { "KRB5KEYTAB", CONF_KRB5KEYTAB },
593 { "KRB5PRINCIPAL", CONF_KRB5PRINCIPAL },
594 { "INCLUDEFILE", CONF_INCLUDEFILE },
595 { "CONNECT_TRIES", CONF_CONNECT_TRIES },
596 { "REP_TRIES", CONF_REP_TRIES },
597 { "REQ_TRIES", CONF_REQ_TRIES },
598 { "DEBUG_AMANDAD", CONF_DEBUG_AMANDAD },
599 { "DEBUG_AMIDXTAPED", CONF_DEBUG_AMIDXTAPED },
600 { "DEBUG_AMINDEXD", CONF_DEBUG_AMINDEXD },
601 { "DEBUG_AMRECOVER", CONF_DEBUG_AMRECOVER },
602 { "DEBUG_AUTH", CONF_DEBUG_AUTH },
603 { "DEBUG_EVENT", CONF_DEBUG_EVENT },
604 { "DEBUG_HOLDING", CONF_DEBUG_HOLDING },
605 { "DEBUG_PROTOCOL", CONF_DEBUG_PROTOCOL },
606 { "DEBUG_PLANNER", CONF_DEBUG_PLANNER },
607 { "DEBUG_DRIVER", CONF_DEBUG_DRIVER },
608 { "DEBUG_DUMPER", CONF_DEBUG_DUMPER },
609 { "DEBUG_CHUNKER", CONF_DEBUG_CHUNKER },
610 { "DEBUG_TAPER", CONF_DEBUG_TAPER },
611 { "DEBUG_SELFCHECK", CONF_DEBUG_SELFCHECK },
612 { "DEBUG_SENDSIZE", CONF_DEBUG_SENDSIZE },
613 { "DEBUG_SENDBACKUP", CONF_DEBUG_SENDBACKUP },
614 { "RESERVED-UDP-PORT", CONF_RESERVED_UDP_PORT },
615 { "RESERVED-TCP-PORT", CONF_RESERVED_TCP_PORT },
616 { "UNRESERVED-TCP-PORT", CONF_UNRESERVED_TCP_PORT },
617 { NULL, CONF_UNKNOWN },
620 keytab_t server_keytab[] = {
621 { "AMANDAD_PATH", CONF_AMANDAD_PATH },
622 { "AMRECOVER_CHANGER", CONF_AMRECOVER_CHANGER },
623 { "AMRECOVER_CHECK_LABEL", CONF_AMRECOVER_CHECK_LABEL },
624 { "AMRECOVER_DO_FSF", CONF_AMRECOVER_DO_FSF },
625 { "APPEND", CONF_APPEND },
626 { "AUTH", CONF_AUTH },
627 { "AUTO", CONF_AUTO },
628 { "AUTOFLUSH", CONF_AUTOFLUSH },
629 { "BEST", CONF_BEST },
630 { "BLOCKSIZE", CONF_BLOCKSIZE },
631 { "BUMPDAYS", CONF_BUMPDAYS },
632 { "BUMPMULT", CONF_BUMPMULT },
633 { "BUMPPERCENT", CONF_BUMPPERCENT },
634 { "BUMPSIZE", CONF_BUMPSIZE },
635 { "CALCSIZE", CONF_CALCSIZE },
636 { "CHANGERDEV", CONF_CHANGERDEV },
637 { "CHANGERFILE", CONF_CHANGERFILE },
638 { "CHUNKSIZE", CONF_CHUNKSIZE },
639 { "CLIENT", CONF_CLIENT },
640 { "CLIENT_CUSTOM_COMPRESS", CONF_CLNTCOMPPROG },
641 { "CLIENT_DECRYPT_OPTION", CONF_CLNT_DECRYPT_OPT },
642 { "CLIENT_ENCRYPT", CONF_CLNT_ENCRYPT },
643 { "CLIENT_USERNAME", CONF_CLIENT_USERNAME },
644 { "COLUMNSPEC", CONF_COLUMNSPEC },
645 { "COMMENT", CONF_COMMENT },
646 { "COMPRATE", CONF_COMPRATE },
647 { "COMPRESS", CONF_COMPRESS },
648 { "CONNECT_TRIES", CONF_CONNECT_TRIES },
649 { "CTIMEOUT", CONF_CTIMEOUT },
650 { "CUSTOM", CONF_CUSTOM },
651 { "DEBUG_AMANDAD" , CONF_DEBUG_AMANDAD },
652 { "DEBUG_AMIDXTAPED" , CONF_DEBUG_AMIDXTAPED },
653 { "DEBUG_AMINDEXD" , CONF_DEBUG_AMINDEXD },
654 { "DEBUG_AMRECOVER" , CONF_DEBUG_AMRECOVER },
655 { "DEBUG_AUTH" , CONF_DEBUG_AUTH },
656 { "DEBUG_EVENT" , CONF_DEBUG_EVENT },
657 { "DEBUG_HOLDING" , CONF_DEBUG_HOLDING },
658 { "DEBUG_PROTOCOL" , CONF_DEBUG_PROTOCOL },
659 { "DEBUG_PLANNER" , CONF_DEBUG_PLANNER },
660 { "DEBUG_DRIVER" , CONF_DEBUG_DRIVER },
661 { "DEBUG_DUMPER" , CONF_DEBUG_DUMPER },
662 { "DEBUG_CHUNKER" , CONF_DEBUG_CHUNKER },
663 { "DEBUG_TAPER" , CONF_DEBUG_TAPER },
664 { "DEBUG_SELFCHECK" , CONF_DEBUG_SELFCHECK },
665 { "DEBUG_SENDSIZE" , CONF_DEBUG_SENDSIZE },
666 { "DEBUG_SENDBACKUP" , CONF_DEBUG_SENDBACKUP },
667 { "DEFINE", CONF_DEFINE },
668 { "DEVICE_PROPERTY", CONF_DEVICE_PROPERTY },
669 { "DIRECTORY", CONF_DIRECTORY },
670 { "DISKFILE", CONF_DISKFILE },
671 { "DISPLAYUNIT", CONF_DISPLAYUNIT },
672 { "DTIMEOUT", CONF_DTIMEOUT },
673 { "DUMPCYCLE", CONF_DUMPCYCLE },
674 { "DUMPORDER", CONF_DUMPORDER },
675 { "DUMPTYPE", CONF_DUMPTYPE },
676 { "DUMPUSER", CONF_DUMPUSER },
677 { "ENCRYPT", CONF_ENCRYPT },
678 { "ESTIMATE", CONF_ESTIMATE },
679 { "ETIMEOUT", CONF_ETIMEOUT },
680 { "EXCLUDE", CONF_EXCLUDE },
681 { "EXCLUDE-FILE", CONF_EXCLUDE_FILE },
682 { "EXCLUDE-LIST", CONF_EXCLUDE_LIST },
683 { "FALLBACK_SPLITSIZE", CONF_FALLBACK_SPLITSIZE },
684 { "FAST", CONF_FAST },
685 { "FILE", CONF_EFILE },
686 { "FILE-PAD", CONF_FILE_PAD },
687 { "FILEMARK", CONF_FILEMARK },
688 { "FIRST", CONF_FIRST },
689 { "FIRSTFIT", CONF_FIRSTFIT },
690 { "HANOI", CONF_HANOI },
691 { "HIGH", CONF_HIGH },
692 { "HOLDINGDISK", CONF_HOLDING },
693 { "IGNORE", CONF_IGNORE },
694 { "INCLUDE", CONF_INCLUDE },
695 { "INCLUDEFILE", CONF_INCLUDEFILE },
696 { "INCRONLY", CONF_INCRONLY },
697 { "INDEX", CONF_INDEX },
698 { "INDEXDIR", CONF_INDEXDIR },
699 { "INFOFILE", CONF_INFOFILE },
700 { "INPARALLEL", CONF_INPARALLEL },
701 { "INTERFACE", CONF_INTERFACE },
702 { "KENCRYPT", CONF_KENCRYPT },
703 { "KRB5KEYTAB", CONF_KRB5KEYTAB },
704 { "KRB5PRINCIPAL", CONF_KRB5PRINCIPAL },
705 { "LABELSTR", CONF_LABELSTR },
706 { "LABEL_NEW_TAPES", CONF_LABEL_NEW_TAPES },
707 { "LARGEST", CONF_LARGEST },
708 { "LARGESTFIT", CONF_LARGESTFIT },
709 { "LAST", CONF_LAST },
710 { "LBL-TEMPL", CONF_LBL_TEMPL },
711 { "LENGTH", CONF_LENGTH },
712 { "LIST", CONF_LIST },
713 { "LOGDIR", CONF_LOGDIR },
715 { "MAILTO", CONF_MAILTO },
716 { "READBLOCKSIZE", CONF_READBLOCKSIZE },
717 { "MAXDUMPS", CONF_MAXDUMPS },
718 { "MAXDUMPSIZE", CONF_MAXDUMPSIZE },
719 { "MAXPROMOTEDAY", CONF_MAXPROMOTEDAY },
720 { "MEDIUM", CONF_MEDIUM },
721 { "NETUSAGE", CONF_NETUSAGE },
722 { "NEVER", CONF_NEVER },
723 { "NOFULL", CONF_NOFULL },
724 { "NOINC", CONF_NOINC },
725 { "NONE", CONF_NONE },
726 { "OPTIONAL", CONF_OPTIONAL },
728 { "PRINTER", CONF_PRINTER },
729 { "PRIORITY", CONF_PRIORITY },
730 { "PROGRAM", CONF_PROGRAM },
731 { "RECORD", CONF_RECORD },
732 { "REP_TRIES", CONF_REP_TRIES },
733 { "REQ_TRIES", CONF_REQ_TRIES },
734 { "REQUIRED", CONF_REQUIRED },
735 { "RESERVE", CONF_RESERVE },
736 { "RESERVED-UDP-PORT", CONF_RESERVED_UDP_PORT },
737 { "RESERVED-TCP-PORT", CONF_RESERVED_TCP_PORT },
738 { "RUNSPERCYCLE", CONF_RUNSPERCYCLE },
739 { "RUNTAPES", CONF_RUNTAPES },
740 { "SERVER", CONF_SERVER },
741 { "SERVER_CUSTOM_COMPRESS", CONF_SRVCOMPPROG },
742 { "SERVER_DECRYPT_OPTION", CONF_SRV_DECRYPT_OPT },
743 { "SERVER_ENCRYPT", CONF_SRV_ENCRYPT },
744 { "SKIP", CONF_SKIP },
745 { "SKIP-FULL", CONF_SKIP_FULL },
746 { "SKIP-INCR", CONF_SKIP_INCR },
747 { "SMALLEST", CONF_SMALLEST },
748 { "SPEED", CONF_SPEED },
749 { "SPLIT_DISKBUFFER", CONF_SPLIT_DISKBUFFER },
750 { "SSH_KEYS", CONF_SSH_KEYS },
751 { "STANDARD", CONF_STANDARD },
752 { "STARTTIME", CONF_STARTTIME },
753 { "STRATEGY", CONF_STRATEGY },
754 { "TAPEBUFS", CONF_TAPEBUFS },
755 { "DEVICE_OUTPUT_BUFFER_SIZE", CONF_DEVICE_OUTPUT_BUFFER_SIZE },
756 { "TAPECYCLE", CONF_TAPECYCLE },
757 { "TAPEDEV", CONF_TAPEDEV },
758 { "TAPELIST", CONF_TAPELIST },
759 { "TAPERALGO", CONF_TAPERALGO },
760 { "FLUSH-THRESHOLD-DUMPED", CONF_FLUSH_THRESHOLD_DUMPED },
761 { "FLUSH-THRESHOLD-SCHEDULED", CONF_FLUSH_THRESHOLD_SCHEDULED },
762 { "TAPERFLUSH", CONF_TAPERFLUSH },
763 { "TAPETYPE", CONF_TAPETYPE },
764 { "TAPE_SPLITSIZE", CONF_TAPE_SPLITSIZE },
765 { "TPCHANGER", CONF_TPCHANGER },
766 { "UNRESERVED-TCP-PORT", CONF_UNRESERVED_TCP_PORT },
768 { "USETIMESTAMPS", CONF_USETIMESTAMPS },
769 { NULL, CONF_IDENT },
770 { NULL, CONF_UNKNOWN }
773 /* A keyword table for recognizing unit suffixes. No distinction is made for kinds
774 * of suffixes: 1024 weeks = 7 k. */
775 keytab_t numb_keytable[] = {
777 { "BPS", CONF_MULT1 },
778 { "BYTE", CONF_MULT1 },
779 { "BYTES", CONF_MULT1 },
780 { "DAY", CONF_MULT1 },
781 { "DAYS", CONF_MULT1 },
782 { "INF", CONF_AMINFINITY },
783 { "K", CONF_MULT1K },
784 { "KB", CONF_MULT1K },
785 { "KBPS", CONF_MULT1K },
786 { "KBYTE", CONF_MULT1K },
787 { "KBYTES", CONF_MULT1K },
788 { "KILOBYTE", CONF_MULT1K },
789 { "KILOBYTES", CONF_MULT1K },
790 { "KPS", CONF_MULT1K },
791 { "M", CONF_MULT1M },
792 { "MB", CONF_MULT1M },
793 { "MBPS", CONF_MULT1M },
794 { "MBYTE", CONF_MULT1M },
795 { "MBYTES", CONF_MULT1M },
796 { "MEG", CONF_MULT1M },
797 { "MEGABYTE", CONF_MULT1M },
798 { "MEGABYTES", CONF_MULT1M },
799 { "G", CONF_MULT1G },
800 { "GB", CONF_MULT1G },
801 { "GBPS", CONF_MULT1G },
802 { "GBYTE", CONF_MULT1G },
803 { "GBYTES", CONF_MULT1G },
804 { "GIG", CONF_MULT1G },
805 { "GIGABYTE", CONF_MULT1G },
806 { "GIGABYTES", CONF_MULT1G },
807 { "MPS", CONF_MULT1M },
808 { "TAPE", CONF_MULT1 },
809 { "TAPES", CONF_MULT1 },
810 { "WEEK", CONF_MULT7 },
811 { "WEEKS", CONF_MULT7 },
815 /* Boolean keywords -- all the ways to say "true" and "false" in amanda.conf */
816 keytab_t bool_keytable[] = {
818 { "YES", CONF_ATRUE },
820 { "TRUE", CONF_ATRUE },
821 { "ON", CONF_ATRUE },
822 { "N", CONF_AFALSE },
823 { "NO", CONF_AFALSE },
824 { "F", CONF_AFALSE },
825 { "FALSE", CONF_AFALSE },
826 { "OFF", CONF_AFALSE },
830 /* Now, the parser tables for client and server global parameters, and for
831 * each of the server subsections */
832 conf_var_t client_var [] = {
833 { CONF_CONF , CONFTYPE_STR , read_str , CNF_CONF , NULL },
834 { CONF_INDEX_SERVER , CONFTYPE_STR , read_str , CNF_INDEX_SERVER , NULL },
835 { CONF_TAPE_SERVER , CONFTYPE_STR , read_str , CNF_TAPE_SERVER , NULL },
836 { CONF_TAPEDEV , CONFTYPE_STR , read_str , CNF_TAPEDEV , NULL },
837 { CONF_AUTH , CONFTYPE_STR , read_str , CNF_AUTH , NULL },
838 { CONF_SSH_KEYS , CONFTYPE_STR , read_str , CNF_SSH_KEYS , NULL },
839 { CONF_AMANDAD_PATH , CONFTYPE_STR , read_str , CNF_AMANDAD_PATH , NULL },
840 { CONF_CLIENT_USERNAME , CONFTYPE_STR , read_str , CNF_CLIENT_USERNAME , NULL },
841 { CONF_GNUTAR_LIST_DIR , CONFTYPE_STR , read_str , CNF_GNUTAR_LIST_DIR , NULL },
842 { CONF_AMANDATES , CONFTYPE_STR , read_str , CNF_AMANDATES , NULL },
843 { CONF_KRB5KEYTAB , CONFTYPE_STR , read_str , CNF_KRB5KEYTAB , NULL },
844 { CONF_KRB5PRINCIPAL , CONFTYPE_STR , read_str , CNF_KRB5PRINCIPAL , NULL },
845 { CONF_CONNECT_TRIES , CONFTYPE_INT , read_int , CNF_CONNECT_TRIES , validate_positive },
846 { CONF_REP_TRIES , CONFTYPE_INT , read_int , CNF_REP_TRIES , validate_positive },
847 { CONF_REQ_TRIES , CONFTYPE_INT , read_int , CNF_REQ_TRIES , validate_positive },
848 { CONF_DEBUG_AMANDAD , CONFTYPE_INT , read_int , CNF_DEBUG_AMANDAD , validate_debug },
849 { CONF_DEBUG_AMIDXTAPED , CONFTYPE_INT , read_int , CNF_DEBUG_AMIDXTAPED , validate_debug },
850 { CONF_DEBUG_AMINDEXD , CONFTYPE_INT , read_int , CNF_DEBUG_AMINDEXD , validate_debug },
851 { CONF_DEBUG_AMRECOVER , CONFTYPE_INT , read_int , CNF_DEBUG_AMRECOVER , validate_debug },
852 { CONF_DEBUG_AUTH , CONFTYPE_INT , read_int , CNF_DEBUG_AUTH , validate_debug },
853 { CONF_DEBUG_EVENT , CONFTYPE_INT , read_int , CNF_DEBUG_EVENT , validate_debug },
854 { CONF_DEBUG_HOLDING , CONFTYPE_INT , read_int , CNF_DEBUG_HOLDING , validate_debug },
855 { CONF_DEBUG_PROTOCOL , CONFTYPE_INT , read_int , CNF_DEBUG_PROTOCOL , validate_debug },
856 { CONF_DEBUG_PLANNER , CONFTYPE_INT , read_int , CNF_DEBUG_PLANNER , validate_debug },
857 { CONF_DEBUG_DRIVER , CONFTYPE_INT , read_int , CNF_DEBUG_DRIVER , validate_debug },
858 { CONF_DEBUG_DUMPER , CONFTYPE_INT , read_int , CNF_DEBUG_DUMPER , validate_debug },
859 { CONF_DEBUG_CHUNKER , CONFTYPE_INT , read_int , CNF_DEBUG_CHUNKER , validate_debug },
860 { CONF_DEBUG_TAPER , CONFTYPE_INT , read_int , CNF_DEBUG_TAPER , validate_debug },
861 { CONF_DEBUG_SELFCHECK , CONFTYPE_INT , read_int , CNF_DEBUG_SELFCHECK , validate_debug },
862 { CONF_DEBUG_SENDSIZE , CONFTYPE_INT , read_int , CNF_DEBUG_SENDSIZE , validate_debug },
863 { CONF_DEBUG_SENDBACKUP , CONFTYPE_INT , read_int , CNF_DEBUG_SENDBACKUP , validate_debug },
864 { CONF_RESERVED_UDP_PORT , CONFTYPE_INTRANGE, read_intrange, CNF_RESERVED_UDP_PORT , validate_reserved_port_range },
865 { CONF_RESERVED_TCP_PORT , CONFTYPE_INTRANGE, read_intrange, CNF_RESERVED_TCP_PORT , validate_reserved_port_range },
866 { CONF_UNRESERVED_TCP_PORT, CONFTYPE_INTRANGE, read_intrange, CNF_UNRESERVED_TCP_PORT, validate_unreserved_port_range },
867 { CONF_UNKNOWN , CONFTYPE_INT , NULL , CNF_CNF , NULL }
870 conf_var_t server_var [] = {
871 { CONF_ORG , CONFTYPE_STR , read_str , CNF_ORG , NULL },
872 { CONF_MAILTO , CONFTYPE_STR , read_str , CNF_MAILTO , NULL },
873 { CONF_DUMPUSER , CONFTYPE_STR , read_str , CNF_DUMPUSER , NULL },
874 { CONF_PRINTER , CONFTYPE_STR , read_str , CNF_PRINTER , NULL },
875 { CONF_TAPEDEV , CONFTYPE_STR , read_str , CNF_TAPEDEV , NULL },
876 { CONF_DEVICE_PROPERTY , CONFTYPE_PROPLIST , read_property , CNF_DEVICE_PROPERTY , NULL },
877 { CONF_TPCHANGER , CONFTYPE_STR , read_str , CNF_TPCHANGER , NULL },
878 { CONF_CHANGERDEV , CONFTYPE_STR , read_str , CNF_CHANGERDEV , NULL },
879 { CONF_CHANGERFILE , CONFTYPE_STR , read_str , CNF_CHANGERFILE , NULL },
880 { CONF_LABELSTR , CONFTYPE_STR , read_str , CNF_LABELSTR , NULL },
881 { CONF_TAPELIST , CONFTYPE_STR , read_str , CNF_TAPELIST , NULL },
882 { CONF_DISKFILE , CONFTYPE_STR , read_str , CNF_DISKFILE , NULL },
883 { CONF_INFOFILE , CONFTYPE_STR , read_str , CNF_INFOFILE , NULL },
884 { CONF_LOGDIR , CONFTYPE_STR , read_str , CNF_LOGDIR , NULL },
885 { CONF_INDEXDIR , CONFTYPE_STR , read_str , CNF_INDEXDIR , NULL },
886 { CONF_TAPETYPE , CONFTYPE_IDENT , read_ident , CNF_TAPETYPE , NULL },
887 { CONF_DUMPCYCLE , CONFTYPE_INT , read_int , CNF_DUMPCYCLE , validate_nonnegative },
888 { CONF_RUNSPERCYCLE , CONFTYPE_INT , read_int , CNF_RUNSPERCYCLE , validate_runspercycle },
889 { CONF_RUNTAPES , CONFTYPE_INT , read_int , CNF_RUNTAPES , validate_nonnegative },
890 { CONF_TAPECYCLE , CONFTYPE_INT , read_int , CNF_TAPECYCLE , validate_positive },
891 { CONF_BUMPDAYS , CONFTYPE_INT , read_int , CNF_BUMPDAYS , validate_positive },
892 { CONF_BUMPSIZE , CONFTYPE_AM64 , read_am64 , CNF_BUMPSIZE , validate_positive },
893 { CONF_BUMPPERCENT , CONFTYPE_INT , read_int , CNF_BUMPPERCENT , validate_bumppercent },
894 { CONF_BUMPMULT , CONFTYPE_REAL , read_real , CNF_BUMPMULT , validate_bumpmult },
895 { CONF_NETUSAGE , CONFTYPE_INT , read_int , CNF_NETUSAGE , validate_positive },
896 { CONF_INPARALLEL , CONFTYPE_INT , read_int , CNF_INPARALLEL , validate_inparallel },
897 { CONF_DUMPORDER , CONFTYPE_STR , read_str , CNF_DUMPORDER , NULL },
898 { CONF_MAXDUMPS , CONFTYPE_INT , read_int , CNF_MAXDUMPS , validate_positive },
899 { CONF_ETIMEOUT , CONFTYPE_INT , read_int , CNF_ETIMEOUT , NULL },
900 { CONF_DTIMEOUT , CONFTYPE_INT , read_int , CNF_DTIMEOUT , validate_positive },
901 { CONF_CTIMEOUT , CONFTYPE_INT , read_int , CNF_CTIMEOUT , validate_positive },
902 { CONF_TAPEBUFS , CONFTYPE_INT , read_int , CNF_TAPEBUFS , validate_positive },
903 { CONF_DEVICE_OUTPUT_BUFFER_SIZE, CONFTYPE_SIZE , read_size , CNF_DEVICE_OUTPUT_BUFFER_SIZE, validate_positive },
904 { CONF_COLUMNSPEC , CONFTYPE_STR , read_str , CNF_COLUMNSPEC , NULL },
905 { CONF_TAPERALGO , CONFTYPE_TAPERALGO, read_taperalgo , CNF_TAPERALGO , NULL },
906 { CONF_FLUSH_THRESHOLD_DUMPED, CONFTYPE_INT , read_int , CNF_FLUSH_THRESHOLD_DUMPED, validate_nonnegative },
907 { CONF_FLUSH_THRESHOLD_SCHEDULED, CONFTYPE_INT , read_int , CNF_FLUSH_THRESHOLD_SCHEDULED, validate_nonnegative },
908 { CONF_TAPERFLUSH , CONFTYPE_INT , read_int , CNF_TAPERFLUSH , validate_nonnegative },
909 { CONF_DISPLAYUNIT , CONFTYPE_STR , read_str , CNF_DISPLAYUNIT , validate_displayunit },
910 { CONF_AUTOFLUSH , CONFTYPE_BOOLEAN , read_bool , CNF_AUTOFLUSH , NULL },
911 { CONF_RESERVE , CONFTYPE_INT , read_int , CNF_RESERVE , validate_reserve },
912 { CONF_MAXDUMPSIZE , CONFTYPE_AM64 , read_am64 , CNF_MAXDUMPSIZE , NULL },
913 { CONF_KRB5KEYTAB , CONFTYPE_STR , read_str , CNF_KRB5KEYTAB , NULL },
914 { CONF_KRB5PRINCIPAL , CONFTYPE_STR , read_str , CNF_KRB5PRINCIPAL , NULL },
915 { CONF_LABEL_NEW_TAPES , CONFTYPE_STR , read_str , CNF_LABEL_NEW_TAPES , NULL },
916 { CONF_USETIMESTAMPS , CONFTYPE_BOOLEAN , read_bool , CNF_USETIMESTAMPS , NULL },
917 { CONF_AMRECOVER_DO_FSF , CONFTYPE_BOOLEAN , read_bool , CNF_AMRECOVER_DO_FSF , NULL },
918 { CONF_AMRECOVER_CHANGER , CONFTYPE_STR , read_str , CNF_AMRECOVER_CHANGER , NULL },
919 { CONF_AMRECOVER_CHECK_LABEL, CONFTYPE_BOOLEAN , read_bool , CNF_AMRECOVER_CHECK_LABEL, NULL },
920 { CONF_CONNECT_TRIES , CONFTYPE_INT , read_int , CNF_CONNECT_TRIES , validate_positive },
921 { CONF_REP_TRIES , CONFTYPE_INT , read_int , CNF_REP_TRIES , validate_positive },
922 { CONF_REQ_TRIES , CONFTYPE_INT , read_int , CNF_REQ_TRIES , validate_positive },
923 { CONF_DEBUG_AMANDAD , CONFTYPE_INT , read_int , CNF_DEBUG_AMANDAD , validate_debug },
924 { CONF_DEBUG_AMIDXTAPED , CONFTYPE_INT , read_int , CNF_DEBUG_AMIDXTAPED , validate_debug },
925 { CONF_DEBUG_AMINDEXD , CONFTYPE_INT , read_int , CNF_DEBUG_AMINDEXD , validate_debug },
926 { CONF_DEBUG_AMRECOVER , CONFTYPE_INT , read_int , CNF_DEBUG_AMRECOVER , validate_debug },
927 { CONF_DEBUG_AUTH , CONFTYPE_INT , read_int , CNF_DEBUG_AUTH , validate_debug },
928 { CONF_DEBUG_EVENT , CONFTYPE_INT , read_int , CNF_DEBUG_EVENT , validate_debug },
929 { CONF_DEBUG_HOLDING , CONFTYPE_INT , read_int , CNF_DEBUG_HOLDING , validate_debug },
930 { CONF_DEBUG_PROTOCOL , CONFTYPE_INT , read_int , CNF_DEBUG_PROTOCOL , validate_debug },
931 { CONF_DEBUG_PLANNER , CONFTYPE_INT , read_int , CNF_DEBUG_PLANNER , validate_debug },
932 { CONF_DEBUG_DRIVER , CONFTYPE_INT , read_int , CNF_DEBUG_DRIVER , validate_debug },
933 { CONF_DEBUG_DUMPER , CONFTYPE_INT , read_int , CNF_DEBUG_DUMPER , validate_debug },
934 { CONF_DEBUG_CHUNKER , CONFTYPE_INT , read_int , CNF_DEBUG_CHUNKER , validate_debug },
935 { CONF_DEBUG_TAPER , CONFTYPE_INT , read_int , CNF_DEBUG_TAPER , validate_debug },
936 { CONF_DEBUG_SELFCHECK , CONFTYPE_INT , read_int , CNF_DEBUG_SELFCHECK , validate_debug },
937 { CONF_DEBUG_SENDSIZE , CONFTYPE_INT , read_int , CNF_DEBUG_SENDSIZE , validate_debug },
938 { CONF_DEBUG_SENDBACKUP , CONFTYPE_INT , read_int , CNF_DEBUG_SENDBACKUP , validate_debug },
939 { CONF_RESERVED_UDP_PORT , CONFTYPE_INTRANGE , read_intrange , CNF_RESERVED_UDP_PORT , validate_reserved_port_range },
940 { CONF_RESERVED_TCP_PORT , CONFTYPE_INTRANGE , read_intrange , CNF_RESERVED_TCP_PORT , validate_reserved_port_range },
941 { CONF_UNRESERVED_TCP_PORT , CONFTYPE_INTRANGE , read_intrange , CNF_UNRESERVED_TCP_PORT , validate_unreserved_port_range },
942 { CONF_UNKNOWN , CONFTYPE_INT , NULL , CNF_CNF , NULL }
945 conf_var_t tapetype_var [] = {
946 { CONF_COMMENT , CONFTYPE_STR , read_str , TAPETYPE_COMMENT , NULL },
947 { CONF_LBL_TEMPL , CONFTYPE_STR , read_str , TAPETYPE_LBL_TEMPL , NULL },
948 { CONF_BLOCKSIZE , CONFTYPE_SIZE , read_size , TAPETYPE_BLOCKSIZE , validate_blocksize },
949 { CONF_READBLOCKSIZE , CONFTYPE_SIZE , read_size , TAPETYPE_READBLOCKSIZE, validate_blocksize },
950 { CONF_LENGTH , CONFTYPE_AM64 , read_am64 , TAPETYPE_LENGTH , validate_nonnegative },
951 { CONF_FILEMARK , CONFTYPE_AM64 , read_am64 , TAPETYPE_FILEMARK , NULL },
952 { CONF_SPEED , CONFTYPE_INT , read_int , TAPETYPE_SPEED , validate_nonnegative },
953 { CONF_FILE_PAD , CONFTYPE_BOOLEAN , read_bool , TAPETYPE_FILE_PAD , NULL },
954 { CONF_UNKNOWN , CONFTYPE_INT , NULL , TAPETYPE_TAPETYPE , NULL }
957 conf_var_t dumptype_var [] = {
958 { CONF_COMMENT , CONFTYPE_STR , read_str , DUMPTYPE_COMMENT , NULL },
959 { CONF_AUTH , CONFTYPE_STR , read_str , DUMPTYPE_SECURITY_DRIVER , NULL },
960 { CONF_BUMPDAYS , CONFTYPE_INT , read_int , DUMPTYPE_BUMPDAYS , NULL },
961 { CONF_BUMPMULT , CONFTYPE_REAL , read_real , DUMPTYPE_BUMPMULT , NULL },
962 { CONF_BUMPSIZE , CONFTYPE_AM64 , read_am64 , DUMPTYPE_BUMPSIZE , NULL },
963 { CONF_BUMPPERCENT , CONFTYPE_INT , read_int , DUMPTYPE_BUMPPERCENT , NULL },
964 { CONF_COMPRATE , CONFTYPE_REAL , read_rate , DUMPTYPE_COMPRATE , NULL },
965 { CONF_COMPRESS , CONFTYPE_INT , read_compress , DUMPTYPE_COMPRESS , NULL },
966 { CONF_ENCRYPT , CONFTYPE_INT , read_encrypt , DUMPTYPE_ENCRYPT , NULL },
967 { CONF_DUMPCYCLE , CONFTYPE_INT , read_int , DUMPTYPE_DUMPCYCLE , validate_nonnegative },
968 { CONF_EXCLUDE , CONFTYPE_EXINCLUDE, read_exinclude, DUMPTYPE_EXCLUDE , NULL },
969 { CONF_INCLUDE , CONFTYPE_EXINCLUDE, read_exinclude, DUMPTYPE_INCLUDE , NULL },
970 { CONF_IGNORE , CONFTYPE_BOOLEAN , read_bool , DUMPTYPE_IGNORE , NULL },
971 { CONF_HOLDING , CONFTYPE_HOLDING , read_holding , DUMPTYPE_HOLDINGDISK , NULL },
972 { CONF_INDEX , CONFTYPE_BOOLEAN , read_bool , DUMPTYPE_INDEX , NULL },
973 { CONF_KENCRYPT , CONFTYPE_BOOLEAN , read_bool , DUMPTYPE_KENCRYPT , NULL },
974 { CONF_MAXDUMPS , CONFTYPE_INT , read_int , DUMPTYPE_MAXDUMPS , validate_positive },
975 { CONF_MAXPROMOTEDAY , CONFTYPE_INT , read_int , DUMPTYPE_MAXPROMOTEDAY , validate_nonnegative },
976 { CONF_PRIORITY , CONFTYPE_PRIORITY , read_priority , DUMPTYPE_PRIORITY , NULL },
977 { CONF_PROGRAM , CONFTYPE_STR , read_str , DUMPTYPE_PROGRAM , NULL },
978 { CONF_RECORD , CONFTYPE_BOOLEAN , read_bool , DUMPTYPE_RECORD , NULL },
979 { CONF_SKIP_FULL , CONFTYPE_BOOLEAN , read_bool , DUMPTYPE_SKIP_FULL , NULL },
980 { CONF_SKIP_INCR , CONFTYPE_BOOLEAN , read_bool , DUMPTYPE_SKIP_INCR , NULL },
981 { CONF_STARTTIME , CONFTYPE_TIME , read_time , DUMPTYPE_STARTTIME , NULL },
982 { CONF_STRATEGY , CONFTYPE_INT , read_strategy , DUMPTYPE_STRATEGY , NULL },
983 { CONF_TAPE_SPLITSIZE , CONFTYPE_AM64 , read_am64 , DUMPTYPE_TAPE_SPLITSIZE , validate_nonnegative },
984 { CONF_SPLIT_DISKBUFFER , CONFTYPE_STR , read_str , DUMPTYPE_SPLIT_DISKBUFFER , NULL },
985 { CONF_ESTIMATE , CONFTYPE_INT , read_estimate , DUMPTYPE_ESTIMATE , NULL },
986 { CONF_SRV_ENCRYPT , CONFTYPE_STR , read_str , DUMPTYPE_SRV_ENCRYPT , NULL },
987 { CONF_CLNT_ENCRYPT , CONFTYPE_STR , read_str , DUMPTYPE_CLNT_ENCRYPT , NULL },
988 { CONF_AMANDAD_PATH , CONFTYPE_STR , read_str , DUMPTYPE_AMANDAD_PATH , NULL },
989 { CONF_CLIENT_USERNAME , CONFTYPE_STR , read_str , DUMPTYPE_CLIENT_USERNAME , NULL },
990 { CONF_SSH_KEYS , CONFTYPE_STR , read_str , DUMPTYPE_SSH_KEYS , NULL },
991 { CONF_SRVCOMPPROG , CONFTYPE_STR , read_str , DUMPTYPE_SRVCOMPPROG , NULL },
992 { CONF_CLNTCOMPPROG , CONFTYPE_STR , read_str , DUMPTYPE_CLNTCOMPPROG , NULL },
993 { CONF_FALLBACK_SPLITSIZE, CONFTYPE_AM64 , read_am64 , DUMPTYPE_FALLBACK_SPLITSIZE, NULL },
994 { CONF_SRV_DECRYPT_OPT , CONFTYPE_STR , read_str , DUMPTYPE_SRV_DECRYPT_OPT , NULL },
995 { CONF_CLNT_DECRYPT_OPT , CONFTYPE_STR , read_str , DUMPTYPE_CLNT_DECRYPT_OPT , NULL },
996 { CONF_UNKNOWN , CONFTYPE_INT , NULL , DUMPTYPE_DUMPTYPE , NULL }
999 conf_var_t holding_var [] = {
1000 { CONF_DIRECTORY, CONFTYPE_STR , read_str , HOLDING_DISKDIR , NULL },
1001 { CONF_COMMENT , CONFTYPE_STR , read_str , HOLDING_COMMENT , NULL },
1002 { CONF_USE , CONFTYPE_AM64 , read_am64 , HOLDING_DISKSIZE , validate_use },
1003 { CONF_CHUNKSIZE, CONFTYPE_AM64 , read_am64 , HOLDING_CHUNKSIZE, validate_chunksize },
1004 { CONF_UNKNOWN , CONFTYPE_INT , NULL , HOLDING_HOLDING , NULL }
1007 conf_var_t interface_var [] = {
1008 { CONF_COMMENT, CONFTYPE_STR , read_str , INTER_COMMENT , NULL },
1009 { CONF_USE , CONFTYPE_INT , read_int , INTER_MAXUSAGE, validate_positive },
1010 { CONF_UNKNOWN, CONFTYPE_INT , NULL , INTER_INTER , NULL }
1015 * Lexical Analysis Implementation
1024 if (keytable == NULL) {
1025 error(_("keytable == NULL"));
1029 for(kt = keytable; kt->token != CONF_UNKNOWN; kt++)
1030 if(kt->token == token) break;
1032 if(kt->token == CONF_UNKNOWN)
1034 return(kt->keyword);
1043 for(kwp = keytable; kwp->keyword != NULL; kwp++) {
1044 if (strcasecmp(kwp->keyword, str) == 0) break;
1067 ** If it looked like a keyword before then look it
1068 ** up again in the current keyword table.
1071 case CONF_AM64: case CONF_SIZE:
1072 case CONF_INT: case CONF_REAL: case CONF_STRING:
1073 case CONF_LBRACE: case CONF_RBRACE: case CONF_COMMA:
1074 case CONF_NL: case CONF_END: case CONF_UNKNOWN:
1076 break; /* not a keyword */
1079 if (exp == CONF_IDENT)
1082 tok = lookup_keyword(tokenval.v.s);
1087 ch = conftoken_getc();
1089 while(ch != EOF && ch != '\n' && isspace(ch))
1090 ch = conftoken_getc();
1091 if (ch == '#') { /* comment - eat everything but eol/eof */
1092 while((ch = conftoken_getc()) != EOF && ch != '\n') {
1093 (void)ch; /* Quiet empty loop complaints */
1097 if (isalpha(ch)) { /* identifier */
1101 if (buf < tkbuf+sizeof(tkbuf)-1) {
1105 if (!token_overflow) {
1106 conf_parserror(_("token too long: %.20s..."), tkbuf);
1110 ch = conftoken_getc();
1111 } while(isalnum(ch) || ch == '_' || ch == '-');
1113 if (ch != EOF && conftoken_ungetc(ch) == EOF) {
1114 if (ferror(current_file)) {
1115 conf_parserror(_("Pushback of '%c' failed: %s"),
1116 ch, strerror(ferror(current_file)));
1118 conf_parserror(_("Pushback of '%c' failed: EOF"), ch);
1123 tokenval.v.s = tkbuf;
1125 if (token_overflow) tok = CONF_UNKNOWN;
1126 else if (exp == CONF_IDENT) tok = CONF_IDENT;
1127 else tok = lookup_keyword(tokenval.v.s);
1129 else if (isdigit(ch)) { /* integer */
1132 negative_number: /* look for goto negative_number below sign is set there */
1135 am64 = am64 * 10 + (ch - '0');
1136 ch = conftoken_getc();
1137 } while (isdigit(ch));
1140 if (exp == CONF_INT) {
1142 tokenval.v.i = sign * (int)am64;
1143 } else if (exp != CONF_REAL) {
1145 tokenval.v.am64 = (off_t)sign * am64;
1147 /* automatically convert to real when expected */
1148 tokenval.v.r = (double)sign * (double)am64;
1152 /* got a real number, not an int */
1153 tokenval.v.r = sign * (double) am64;
1156 ch = conftoken_getc();
1157 while (isdigit(ch)) {
1158 am64 = am64 * 10 + (ch - '0');
1160 ch = conftoken_getc();
1162 tokenval.v.r += sign * ((double)am64) / d;
1166 if (ch != EOF && conftoken_ungetc(ch) == EOF) {
1167 if (ferror(current_file)) {
1168 conf_parserror(_("Pushback of '%c' failed: %s"),
1169 ch, strerror(ferror(current_file)));
1171 conf_parserror(_("Pushback of '%c' failed: EOF"), ch);
1175 case '"': /* string */
1180 while (inquote && ((ch = conftoken_getc()) != EOF)) {
1185 buf--; /* Consume escape in buffer */
1186 } else if (ch == '\\') {
1196 if(buf >= &tkbuf[sizeof(tkbuf) - 1]) {
1197 if (!token_overflow) {
1198 conf_parserror(_("string too long: %.20s..."), tkbuf);
1208 * A little manuver to leave a fully unquoted, unallocated string
1211 tmps = unquote_string(tkbuf);
1212 strncpy(tkbuf, tmps, sizeof(tkbuf));
1214 tokenval.v.s = tkbuf;
1216 tok = (token_overflow) ? CONF_UNKNOWN :
1217 (exp == CONF_IDENT) ? CONF_IDENT : CONF_STRING;
1221 ch = conftoken_getc();
1224 goto negative_number;
1227 if (ch != EOF && conftoken_ungetc(ch) == EOF) {
1228 if (ferror(current_file)) {
1229 conf_parserror(_("Pushback of '%c' failed: %s"),
1230 ch, strerror(ferror(current_file)));
1232 conf_parserror(_("Pushback of '%c' failed: EOF"), ch);
1265 if (exp != CONF_ANY && tok != exp) {
1283 str = _("end of line");
1287 str = _("end of file");
1291 str = _("an integer");
1295 str = _("a real number");
1299 str = _("a quoted string");
1303 str = _("an identifier");
1307 for(kwp = keytable; kwp->keyword != NULL; kwp++) {
1308 if (exp == kwp->token)
1311 if (kwp->keyword == NULL)
1312 str = _("token not");
1317 conf_parserror(_("%s is expected"), str);
1319 if (tok == CONF_INT)
1327 unget_conftoken(void)
1329 assert(!token_pushed);
1336 conftoken_getc(void)
1338 if(current_line == NULL)
1339 return getc(current_file);
1340 if(*current_char == '\0')
1342 return(*current_char++);
1349 if(current_line == NULL)
1350 return ungetc(c, current_file);
1351 else if(current_char > current_line) {
1355 if(*current_char != c) {
1356 error(_("*current_char != c : %c %c"), *current_char, c);
1360 error(_("current_char == current_line"));
1367 * Parser Implementation
1375 /* Save global locations. */
1376 FILE *save_file = current_file;
1377 char *save_filename = current_filename;
1378 int save_line_num = current_line_num;
1382 keytable = client_keytab;
1383 parsetable = client_var;
1385 keytable = server_keytab;
1386 parsetable = server_var;
1388 current_filename = config_dir_relative(filename);
1390 if ((current_file = fopen(current_filename, "r")) == NULL) {
1391 g_fprintf(stderr, _("could not open conf file \"%s\": %s\n"), current_filename,
1393 got_parserror = TRUE;
1397 current_line_num = 0;
1400 /* read_confline() can invoke us recursively via "includefile" */
1401 rc = read_confline(is_client);
1404 afclose(current_file);
1407 amfree(current_filename);
1409 /* Restore servers */
1410 current_line_num = save_line_num;
1411 current_file = save_file;
1412 current_filename = save_filename;
1414 return !got_parserror;
1423 current_line_num += 1;
1424 get_conftoken(CONF_ANY);
1426 case CONF_INCLUDEFILE:
1427 get_conftoken(CONF_STRING);
1428 if (!read_conffile(tokenval.v.s, is_client))
1434 handle_invalid_keyword(tokenval.v.s);
1442 handle_invalid_keyword(tokenval.v.s);
1444 get_conftoken(CONF_ANY);
1445 if(tok == CONF_DUMPTYPE) get_dumptype();
1446 else if(tok == CONF_TAPETYPE) get_tapetype();
1447 else if(tok == CONF_INTERFACE) get_interface();
1448 else conf_parserror(_("DUMPTYPE, INTERFACE or TAPETYPE expected"));
1452 case CONF_NL: /* empty line */
1455 case CONF_END: /* end of file */
1458 /* if it's not a known punctuation mark, then check the parse table and use the
1459 * read_function we find there. */
1462 for(np = parsetable; np->token != CONF_UNKNOWN; np++)
1463 if(np->token == tok) break;
1465 if(np->token == CONF_UNKNOWN) {
1466 handle_invalid_keyword(tokenval.v.s);
1468 np->read_function(np, &conf_data[np->parm]);
1469 if(np->validate_function)
1470 np->validate_function(np, &conf_data[np->parm]);
1475 get_conftoken(CONF_NL);
1480 handle_invalid_keyword(
1483 /* Procedure for deprecated keywords:
1484 * 1) At time of deprecation, add to warning_deprecated below.
1485 * Note the date of deprecation.
1486 * 2) After two years, move the keyword to error_deprecated below.
1487 * Note the date of the move.
1488 * 3) After two more years, drop the token entirely. */
1490 static const char * warning_deprecated[] = {
1491 "rawtapedev", /* 2007-01-23 */
1492 "tapebufs", /* 2007-10-15 */
1493 "netusage", /* historical since 1997-08-11, deprecated 2007-10-23 */
1496 static const char * error_deprecated[] = {
1501 for (s = warning_deprecated; *s != NULL; s ++) {
1502 if (strcmp(*s, token) == 0) {
1503 conf_parswarn(_("warning: Keyword %s is deprecated."),
1509 for (s = error_deprecated; *s != NULL; s ++) {
1510 if (strcmp(*s, token) == 0) {
1511 conf_parserror(_("error: Keyword %s is deprecated."),
1518 conf_parserror(_("configuration keyword expected"));
1522 char c = conftoken_getc();
1523 if (c == '\n' || c == -1) {
1524 conftoken_ungetc(c);
1529 g_assert_not_reached();
1534 conf_var_t *read_var,
1538 void (*copy_function)(void))
1544 get_conftoken(CONF_LBRACE);
1545 get_conftoken(CONF_NL);
1550 current_line_num += 1;
1551 get_conftoken(CONF_ANY);
1556 case CONF_NL: /* empty line */
1558 case CONF_END: /* end of file */
1562 /* inherit from a "parent" */
1568 conf_parserror(_("ident not expected"));
1572 for(np = read_var; np->token != CONF_UNKNOWN; np++)
1573 if(np->token == tok) break;
1575 if(np->token == CONF_UNKNOWN)
1576 conf_parserror(errormsg);
1578 np->read_function(np, &valarray[np->parm]);
1579 if(np->validate_function)
1580 np->validate_function(np, &valarray[np->parm]);
1584 if(tok != CONF_NL && tok != CONF_END && tok != CONF_RBRACE)
1585 get_conftoken(CONF_NL);
1593 int save_overwrites;
1595 save_overwrites = allow_overwrites;
1596 allow_overwrites = 1;
1598 init_holdingdisk_defaults();
1600 get_conftoken(CONF_IDENT);
1601 hdcur.name = stralloc(tokenval.v.s);
1602 hdcur.seen = current_line_num;
1604 read_block(holding_var, hdcur.value,
1605 _("holding disk parameter expected"), 1, NULL);
1606 get_conftoken(CONF_NL);
1609 allow_overwrites = save_overwrites;
1613 init_holdingdisk_defaults(
1616 conf_init_str(&hdcur.value[HOLDING_COMMENT] , "");
1617 conf_init_str(&hdcur.value[HOLDING_DISKDIR] , "");
1618 conf_init_am64(&hdcur.value[HOLDING_DISKSIZE] , (off_t)0);
1619 /* 1 Gb = 1M counted in 1Kb blocks */
1620 conf_init_am64(&hdcur.value[HOLDING_CHUNKSIZE], (off_t)1024*1024);
1629 hp = alloc(sizeof(holdingdisk_t));
1631 hp->next = holdinglist;
1637 * This function is called both from this module and from diskfile.c. Modify
1646 int save_overwrites;
1647 FILE *saved_conf = NULL;
1648 char *saved_fname = NULL;
1651 saved_conf = current_file;
1652 current_file = from;
1656 saved_fname = current_filename;
1657 current_filename = fname;
1661 current_line_num = *linenum;
1663 save_overwrites = allow_overwrites;
1664 allow_overwrites = 1;
1666 init_dumptype_defaults();
1670 get_conftoken(CONF_IDENT);
1671 dpcur.name = stralloc(tokenval.v.s);
1673 dpcur.seen = current_line_num;
1675 read_block(dumptype_var, dpcur.value,
1676 _("dumptype parameter expected"),
1677 (name == NULL), copy_dumptype);
1679 if(!name) /* !name => reading disklist, not conffile */
1680 get_conftoken(CONF_NL);
1682 /* XXX - there was a stupidity check in here for skip-incr and
1683 ** skip-full. This check should probably be somewhere else. */
1687 allow_overwrites = save_overwrites;
1690 *linenum = current_line_num;
1693 current_filename = saved_fname;
1696 current_file = saved_conf;
1698 return lookup_dumptype(dpcur.name);
1704 read_dumptype(NULL, NULL, NULL, NULL);
1708 init_dumptype_defaults(void)
1711 conf_init_str (&dpcur.value[DUMPTYPE_COMMENT] , "");
1712 conf_init_str (&dpcur.value[DUMPTYPE_PROGRAM] , "DUMP");
1713 conf_init_str (&dpcur.value[DUMPTYPE_SRVCOMPPROG] , "");
1714 conf_init_str (&dpcur.value[DUMPTYPE_CLNTCOMPPROG] , "");
1715 conf_init_str (&dpcur.value[DUMPTYPE_SRV_ENCRYPT] , "");
1716 conf_init_str (&dpcur.value[DUMPTYPE_CLNT_ENCRYPT] , "");
1717 conf_init_str (&dpcur.value[DUMPTYPE_AMANDAD_PATH] , "X");
1718 conf_init_str (&dpcur.value[DUMPTYPE_CLIENT_USERNAME] , "X");
1719 conf_init_str (&dpcur.value[DUMPTYPE_SSH_KEYS] , "X");
1720 conf_init_str (&dpcur.value[DUMPTYPE_SECURITY_DRIVER] , "BSD");
1721 conf_init_exinclude(&dpcur.value[DUMPTYPE_EXCLUDE]);
1722 conf_init_exinclude(&dpcur.value[DUMPTYPE_INCLUDE]);
1723 conf_init_priority (&dpcur.value[DUMPTYPE_PRIORITY] , 1);
1724 conf_init_int (&dpcur.value[DUMPTYPE_DUMPCYCLE] , conf_data[CNF_DUMPCYCLE].v.i);
1725 conf_init_int (&dpcur.value[DUMPTYPE_MAXDUMPS] , conf_data[CNF_MAXDUMPS].v.i);
1726 conf_init_int (&dpcur.value[DUMPTYPE_MAXPROMOTEDAY] , 10000);
1727 conf_init_int (&dpcur.value[DUMPTYPE_BUMPPERCENT] , conf_data[CNF_BUMPPERCENT].v.i);
1728 conf_init_am64 (&dpcur.value[DUMPTYPE_BUMPSIZE] , conf_data[CNF_BUMPSIZE].v.am64);
1729 conf_init_int (&dpcur.value[DUMPTYPE_BUMPDAYS] , conf_data[CNF_BUMPDAYS].v.i);
1730 conf_init_real (&dpcur.value[DUMPTYPE_BUMPMULT] , conf_data[CNF_BUMPMULT].v.r);
1731 conf_init_time (&dpcur.value[DUMPTYPE_STARTTIME] , (time_t)0);
1732 conf_init_strategy (&dpcur.value[DUMPTYPE_STRATEGY] , DS_STANDARD);
1733 conf_init_estimate (&dpcur.value[DUMPTYPE_ESTIMATE] , ES_CLIENT);
1734 conf_init_compress (&dpcur.value[DUMPTYPE_COMPRESS] , COMP_FAST);
1735 conf_init_encrypt (&dpcur.value[DUMPTYPE_ENCRYPT] , ENCRYPT_NONE);
1736 conf_init_str (&dpcur.value[DUMPTYPE_SRV_DECRYPT_OPT] , "-d");
1737 conf_init_str (&dpcur.value[DUMPTYPE_CLNT_DECRYPT_OPT] , "-d");
1738 conf_init_rate (&dpcur.value[DUMPTYPE_COMPRATE] , 0.50, 0.50);
1739 conf_init_am64 (&dpcur.value[DUMPTYPE_TAPE_SPLITSIZE] , (off_t)0);
1740 conf_init_am64 (&dpcur.value[DUMPTYPE_FALLBACK_SPLITSIZE], (off_t)10 * 1024);
1741 conf_init_str (&dpcur.value[DUMPTYPE_SPLIT_DISKBUFFER] , NULL);
1742 conf_init_bool (&dpcur.value[DUMPTYPE_RECORD] , 1);
1743 conf_init_bool (&dpcur.value[DUMPTYPE_SKIP_INCR] , 0);
1744 conf_init_bool (&dpcur.value[DUMPTYPE_SKIP_FULL] , 0);
1745 conf_init_holding (&dpcur.value[DUMPTYPE_HOLDINGDISK] , HOLD_AUTO);
1746 conf_init_bool (&dpcur.value[DUMPTYPE_KENCRYPT] , 0);
1747 conf_init_bool (&dpcur.value[DUMPTYPE_IGNORE] , 0);
1748 conf_init_bool (&dpcur.value[DUMPTYPE_INDEX] , 1);
1754 dumptype_t *dp, *dp1;;
1756 dp = lookup_dumptype(dpcur.name);
1758 if(dp != (dumptype_t *)0) {
1759 conf_parserror(_("dumptype %s already defined on line %d"), dp->name, dp->seen);
1763 dp = alloc(sizeof(dumptype_t));
1766 /* add at end of list */
1771 while (dp1->next != NULL) {
1784 dt = lookup_dumptype(tokenval.v.s);
1787 conf_parserror(_("dumptype parameter expected"));
1791 for(i=0; i < DUMPTYPE_DUMPTYPE; i++) {
1792 if(dt->value[i].seen) {
1793 free_val_t(&dpcur.value[i]);
1794 copy_val_t(&dpcur.value[i], &dt->value[i]);
1802 int save_overwrites;
1804 save_overwrites = allow_overwrites;
1805 allow_overwrites = 1;
1807 init_tapetype_defaults();
1809 get_conftoken(CONF_IDENT);
1810 tpcur.name = stralloc(tokenval.v.s);
1811 tpcur.seen = current_line_num;
1813 read_block(tapetype_var, tpcur.value,
1814 _("tapetype parameter expected"), 1, copy_tapetype);
1815 get_conftoken(CONF_NL);
1817 if (tapetype_get_readblocksize(&tpcur) <
1818 tapetype_get_blocksize(&tpcur)) {
1819 conf_init_size(&tpcur.value[TAPETYPE_READBLOCKSIZE],
1820 tapetype_get_blocksize(&tpcur));
1824 allow_overwrites = save_overwrites;
1828 init_tapetype_defaults(void)
1830 conf_init_str(&tpcur.value[TAPETYPE_COMMENT] , "");
1831 conf_init_str(&tpcur.value[TAPETYPE_LBL_TEMPL] , "");
1832 conf_init_size (&tpcur.value[TAPETYPE_BLOCKSIZE] , DISK_BLOCK_KB);
1833 conf_init_size (&tpcur.value[TAPETYPE_READBLOCKSIZE], MAX_TAPE_BLOCK_KB);
1834 conf_init_am64 (&tpcur.value[TAPETYPE_LENGTH] , ((off_t)2000 * 1024));
1835 conf_init_am64 (&tpcur.value[TAPETYPE_FILEMARK] , (off_t)1000);
1836 conf_init_int (&tpcur.value[TAPETYPE_SPEED] , 200);
1837 conf_init_bool (&tpcur.value[TAPETYPE_FILE_PAD] , 1);
1843 tapetype_t *tp, *tp1;
1845 tp = lookup_tapetype(tpcur.name);
1847 if(tp != (tapetype_t *)0) {
1849 conf_parserror(_("tapetype %s already defined on line %d"), tp->name, tp->seen);
1853 tp = alloc(sizeof(tapetype_t));
1855 /* add at end of list */
1860 while (tp1->next != NULL) {
1873 tp = lookup_tapetype(tokenval.v.s);
1876 conf_parserror(_("tape type parameter expected"));
1880 for(i=0; i < TAPETYPE_TAPETYPE; i++) {
1881 if(tp->value[i].seen) {
1882 free_val_t(&tpcur.value[i]);
1883 copy_val_t(&tpcur.value[i], &tp->value[i]);
1891 int save_overwrites;
1893 save_overwrites = allow_overwrites;
1894 allow_overwrites = 1;
1896 init_interface_defaults();
1898 get_conftoken(CONF_IDENT);
1899 ifcur.name = stralloc(tokenval.v.s);
1900 ifcur.seen = current_line_num;
1902 read_block(interface_var, ifcur.value,
1903 _("interface parameter expected"), 1, copy_interface);
1904 get_conftoken(CONF_NL);
1908 allow_overwrites = save_overwrites;
1914 init_interface_defaults(void)
1916 conf_init_str(&ifcur.value[INTER_COMMENT] , "");
1917 conf_init_int (&ifcur.value[INTER_MAXUSAGE], 8000);
1921 save_interface(void)
1923 interface_t *ip, *ip1;
1925 ip = lookup_interface(ifcur.name);
1927 if(ip != (interface_t *)0) {
1928 conf_parserror(_("interface %s already defined on line %d"), ip->name,
1933 ip = alloc(sizeof(interface_t));
1935 /* add at end of list */
1936 if(!interface_list) {
1937 interface_list = ip;
1939 ip1 = interface_list;
1940 while (ip1->next != NULL) {
1948 copy_interface(void)
1953 ip = lookup_interface(tokenval.v.s);
1956 conf_parserror(_("interface parameter expected"));
1960 for(i=0; i < INTER_INTER; i++) {
1961 if(ip->value[i].seen) {
1962 free_val_t(&ifcur.value[i]);
1963 copy_val_t(&ifcur.value[i], &ip->value[i]);
1968 /* Read functions */
1972 conf_var_t *np G_GNUC_UNUSED,
1976 val_t__int(val) = get_int();
1981 conf_var_t *np G_GNUC_UNUSED,
1985 val_t__am64(val) = get_am64_t();
1990 conf_var_t *np G_GNUC_UNUSED,
1994 get_conftoken(CONF_REAL);
1995 val_t__real(val) = tokenval.v.r;
2000 conf_var_t *np G_GNUC_UNUSED,
2004 get_conftoken(CONF_STRING);
2005 val->v.s = newstralloc(val->v.s, tokenval.v.s);
2010 conf_var_t *np G_GNUC_UNUSED,
2014 get_conftoken(CONF_IDENT);
2015 val->v.s = newstralloc(val->v.s, tokenval.v.s);
2020 conf_var_t *np G_GNUC_UNUSED,
2024 val_t__time(val) = get_time();
2029 conf_var_t *np G_GNUC_UNUSED,
2033 val_t__size(val) = get_size();
2038 conf_var_t *np G_GNUC_UNUSED,
2042 val_t__boolean(val) = get_bool();
2047 conf_var_t *np G_GNUC_UNUSED,
2050 int serv, clie, none, fast, best, custom;
2056 serv = clie = none = fast = best = custom = 0;
2060 get_conftoken(CONF_ANY);
2062 case CONF_NONE: none = 1; break;
2063 case CONF_FAST: fast = 1; break;
2064 case CONF_BEST: best = 1; break;
2065 case CONF_CLIENT: clie = 1; break;
2066 case CONF_SERVER: serv = 1; break;
2067 case CONF_CUSTOM: custom=1; break;
2068 case CONF_NL: done = 1; break;
2069 case CONF_END: done = 1; break;
2072 serv = clie = 1; /* force an error */
2076 if(serv + clie == 0) clie = 1; /* default to client */
2077 if(none + fast + best + custom == 0) fast = 1; /* default to fast */
2082 if(none && !fast && !best && !custom) comp = COMP_NONE;
2083 if(!none && fast && !best && !custom) comp = COMP_FAST;
2084 if(!none && !fast && best && !custom) comp = COMP_BEST;
2085 if(!none && !fast && !best && custom) comp = COMP_CUST;
2089 if(none && !fast && !best && !custom) comp = COMP_NONE;
2090 if(!none && fast && !best && !custom) comp = COMP_SERVER_FAST;
2091 if(!none && !fast && best && !custom) comp = COMP_SERVER_BEST;
2092 if(!none && !fast && !best && custom) comp = COMP_SERVER_CUST;
2095 if((int)comp == -1) {
2096 conf_parserror(_("NONE, CLIENT FAST, CLIENT BEST, CLIENT CUSTOM, SERVER FAST, SERVER BEST or SERVER CUSTOM expected"));
2100 val_t__compress(val) = (int)comp;
2105 conf_var_t *np G_GNUC_UNUSED,
2112 get_conftoken(CONF_ANY);
2115 encrypt = ENCRYPT_NONE;
2119 encrypt = ENCRYPT_CUST;
2123 encrypt = ENCRYPT_SERV_CUST;
2127 conf_parserror(_("NONE, CLIENT or SERVER expected"));
2128 encrypt = ENCRYPT_NONE;
2132 val_t__encrypt(val) = (int)encrypt;
2137 conf_var_t *np G_GNUC_UNUSED,
2140 dump_holdingdisk_t holding;
2144 get_conftoken(CONF_ANY);
2147 holding = HOLD_NEVER;
2151 holding = HOLD_AUTO;
2155 holding = HOLD_REQUIRED;
2158 default: /* can be a BOOLEAN */
2160 holding = (dump_holdingdisk_t)get_bool();
2162 holding = HOLD_NEVER;
2163 else if (holding == 1 || holding == 2)
2164 holding = HOLD_AUTO;
2166 conf_parserror(_("NEVER, AUTO or REQUIRED expected"));
2170 val_t__holding(val) = (int)holding;
2175 conf_var_t *np G_GNUC_UNUSED,
2182 get_conftoken(CONF_ANY);
2191 estime = ES_CALCSIZE;
2194 conf_parserror(_("CLIENT, SERVER or CALCSIZE expected"));
2197 val_t__estimate(val) = estime;
2202 conf_var_t *np G_GNUC_UNUSED,
2209 get_conftoken(CONF_ANY);
2215 strat = DS_STANDARD;
2227 strat = DS_INCRONLY;
2230 conf_parserror(_("dump strategy expected"));
2231 strat = DS_STANDARD;
2233 val_t__strategy(val) = strat;
2238 conf_var_t *np G_GNUC_UNUSED,
2243 get_conftoken(CONF_ANY);
2245 case CONF_FIRST: val_t__taperalgo(val) = ALGO_FIRST; break;
2246 case CONF_FIRSTFIT: val_t__taperalgo(val) = ALGO_FIRSTFIT; break;
2247 case CONF_LARGEST: val_t__taperalgo(val) = ALGO_LARGEST; break;
2248 case CONF_LARGESTFIT: val_t__taperalgo(val) = ALGO_LARGESTFIT; break;
2249 case CONF_SMALLEST: val_t__taperalgo(val) = ALGO_SMALLEST; break;
2250 case CONF_LAST: val_t__taperalgo(val) = ALGO_LAST; break;
2252 conf_parserror(_("FIRST, FIRSTFIT, LARGEST, LARGESTFIT, SMALLEST or LAST expected"));
2258 conf_var_t *np G_GNUC_UNUSED,
2265 get_conftoken(CONF_ANY);
2267 case CONF_LOW: pri = 0; break;
2268 case CONF_MEDIUM: pri = 1; break;
2269 case CONF_HIGH: pri = 2; break;
2270 case CONF_INT: pri = tokenval.v.i; break;
2272 conf_parserror(_("LOW, MEDIUM, HIGH or integer expected"));
2275 val_t__priority(val) = pri;
2280 conf_var_t *np G_GNUC_UNUSED,
2283 get_conftoken(CONF_REAL);
2284 val_t__rate(val)[0] = tokenval.v.r;
2285 val_t__rate(val)[1] = tokenval.v.r;
2286 val->seen = tokenval.seen;
2287 if(tokenval.v.r < 0) {
2288 conf_parserror(_("full compression rate must be >= 0"));
2291 get_conftoken(CONF_ANY);
2306 get_conftoken(CONF_REAL);
2307 val_t__rate(val)[1] = tokenval.v.r;
2308 if(tokenval.v.r < 0) {
2309 conf_parserror(_("incremental compression rate must be >= 0"));
2315 conf_var_t *np G_GNUC_UNUSED,
2318 int file, got_one = 0;
2322 get_conftoken(CONF_ANY);
2323 if(tok == CONF_LIST) {
2325 get_conftoken(CONF_ANY);
2326 exclude = val_t__exinclude(val).sl_list;
2330 if(tok == CONF_EFILE) get_conftoken(CONF_ANY);
2331 exclude = val_t__exinclude(val).sl_file;
2335 if(tok == CONF_OPTIONAL) {
2336 get_conftoken(CONF_ANY);
2340 if(tok == CONF_APPEND) {
2341 get_conftoken(CONF_ANY);
2348 while(tok == CONF_STRING) {
2349 exclude = append_sl(exclude, tokenval.v.s);
2351 get_conftoken(CONF_ANY);
2355 if(got_one == 0) { free_sl(exclude); exclude = NULL; }
2358 val_t__exinclude(val).sl_list = exclude;
2360 val_t__exinclude(val).sl_file = exclude;
2361 val_t__exinclude(val).optional = optional;
2366 conf_var_t *np G_GNUC_UNUSED,
2369 get_conftoken(CONF_INT);
2370 val_t__intrange(val)[0] = tokenval.v.i;
2371 val_t__intrange(val)[1] = tokenval.v.i;
2372 val->seen = tokenval.seen;
2374 get_conftoken(CONF_ANY);
2389 get_conftoken(CONF_INT);
2390 val_t__intrange(val)[1] = tokenval.v.i;
2395 conf_var_t *np G_GNUC_UNUSED,
2399 get_conftoken(CONF_STRING);
2400 key = strdup(tokenval.v.s);
2401 get_conftoken(CONF_STRING);
2402 value = strdup(tokenval.v.s);
2404 g_hash_table_insert(val_t__proplist(val), key, value);
2407 /* get_* functions */
2414 get_conftoken(CONF_ANY);
2417 #if SIZEOF_TIME_T < SIZEOF_INT
2418 if ((off_t)tokenval.v.i >= (off_t)TIME_MAX)
2419 conf_parserror(_("value too large"));
2421 hhmm = (time_t)tokenval.v.i;
2425 #if SIZEOF_TIME_T < SIZEOF_SSIZE_T
2426 if ((off_t)tokenval.v.size >= (off_t)TIME_MAX)
2427 conf_parserror(_("value too large"));
2429 hhmm = (time_t)tokenval.v.size;
2433 #if SIZEOF_TIME_T < SIZEOF_LONG_LONG
2434 if ((off_t)tokenval.v.am64 >= (off_t)TIME_MAX)
2435 conf_parserror(_("value too large"));
2437 hhmm = (time_t)tokenval.v.am64;
2440 case CONF_AMINFINITY:
2445 conf_parserror(_("a time is expected"));
2459 keytable = numb_keytable;
2461 get_conftoken(CONF_ANY);
2468 #if SIZEOF_INT < SIZEOF_SSIZE_T
2469 if ((off_t)tokenval.v.size > (off_t)INT_MAX)
2470 conf_parserror(_("value too large"));
2471 if ((off_t)tokenval.v.size < (off_t)INT_MIN)
2472 conf_parserror(_("value too small"));
2474 val = (int)tokenval.v.size;
2478 #if SIZEOF_INT < SIZEOF_LONG_LONG
2479 if (tokenval.v.am64 > (off_t)INT_MAX)
2480 conf_parserror(_("value too large"));
2481 if (tokenval.v.am64 < (off_t)INT_MIN)
2482 conf_parserror(_("value too small"));
2484 val = (int)tokenval.v.am64;
2487 case CONF_AMINFINITY:
2492 conf_parserror(_("an integer is expected"));
2497 /* get multiplier, if any */
2498 get_conftoken(CONF_ANY);
2500 case CONF_NL: /* multiply by one */
2507 if (val > (INT_MAX / 7))
2508 conf_parserror(_("value too large"));
2509 if (val < (INT_MIN / 7))
2510 conf_parserror(_("value too small"));
2515 if (val > (INT_MAX / 1024))
2516 conf_parserror(_("value too large"));
2517 if (val < (INT_MIN / 1024))
2518 conf_parserror(_("value too small"));
2523 if (val > (INT_MAX / (1024 * 1024)))
2524 conf_parserror(_("value too large"));
2525 if (val < (INT_MIN / (1024 * 1024)))
2526 conf_parserror(_("value too small"));
2530 default: /* it was not a multiplier */
2546 keytable = numb_keytable;
2548 get_conftoken(CONF_ANY);
2552 val = tokenval.v.size;
2556 #if SIZEOF_SIZE_T < SIZEOF_INT
2557 if ((off_t)tokenval.v.i > (off_t)SSIZE_MAX)
2558 conf_parserror(_("value too large"));
2559 if ((off_t)tokenval.v.i < (off_t)SSIZE_MIN)
2560 conf_parserror(_("value too small"));
2562 val = (ssize_t)tokenval.v.i;
2566 #if SIZEOF_SIZE_T < SIZEOF_LONG_LONG
2567 if (tokenval.v.am64 > (off_t)SSIZE_MAX)
2568 conf_parserror(_("value too large"));
2569 if (tokenval.v.am64 < (off_t)SSIZE_MIN)
2570 conf_parserror(_("value too small"));
2572 val = (ssize_t)tokenval.v.am64;
2575 case CONF_AMINFINITY:
2576 val = (ssize_t)SSIZE_MAX;
2580 conf_parserror(_("an integer is expected"));
2585 /* get multiplier, if any */
2586 get_conftoken(CONF_ANY);
2589 case CONF_NL: /* multiply by one */
2595 if (val > (ssize_t)(SSIZE_MAX / 7))
2596 conf_parserror(_("value too large"));
2597 if (val < (ssize_t)(SSIZE_MIN / 7))
2598 conf_parserror(_("value too small"));
2603 if (val > (ssize_t)(SSIZE_MAX / (ssize_t)1024))
2604 conf_parserror(_("value too large"));
2605 if (val < (ssize_t)(SSIZE_MIN / (ssize_t)1024))
2606 conf_parserror(_("value too small"));
2607 val *= (ssize_t)1024;
2611 if (val > (ssize_t)(SSIZE_MAX / (1024 * 1024)))
2612 conf_parserror(_("value too large"));
2613 if (val < (ssize_t)(SSIZE_MIN / (1024 * 1024)))
2614 conf_parserror(_("value too small"));
2615 val *= (ssize_t)(1024 * 1024);
2618 default: /* it was not a multiplier */
2634 keytable = numb_keytable;
2636 get_conftoken(CONF_ANY);
2640 val = (off_t)tokenval.v.i;
2644 val = (off_t)tokenval.v.size;
2648 val = tokenval.v.am64;
2651 case CONF_AMINFINITY:
2656 conf_parserror(_("an integer is expected"));
2661 /* get multiplier, if any */
2662 get_conftoken(CONF_ANY);
2665 case CONF_NL: /* multiply by one */
2671 if (val > AM64_MAX/7 || val < AM64_MIN/7)
2672 conf_parserror(_("value too large"));
2677 if (val > AM64_MAX/1024 || val < AM64_MIN/1024)
2678 conf_parserror(_("value too large"));
2683 if (val > AM64_MAX/(1024*1024) || val < AM64_MIN/(1024*1024))
2684 conf_parserror(_("value too large"));
2688 default: /* it was not a multiplier */
2705 keytable = bool_keytable;
2707 get_conftoken(CONF_ANY);
2711 if (tokenval.v.i != 0)
2718 if (tokenval.v.size != (size_t)0)
2725 if (tokenval.v.am64 != (off_t)0)
2741 val = 2; /* no argument - most likely TRUE */
2745 val = 3; /* a bad argument - most likely TRUE */
2746 conf_parserror(_("YES, NO, TRUE, FALSE, ON, OFF expected"));
2758 if (*seen && !allow_overwrites && current_line_num != -2) {
2759 conf_parserror(_("duplicate parameter, prev def on line %d"), *seen);
2761 *seen = current_line_num;
2764 /* Validation functions */
2767 validate_nonnegative(
2768 struct conf_var_s *np,
2773 if(val_t__int(val) < 0)
2774 conf_parserror(_("%s must be nonnegative"), get_token_name(np->token));
2777 if(val_t__am64(val) < 0)
2778 conf_parserror(_("%s must be nonnegative"), get_token_name(np->token));
2781 if(val_t__size(val) < 0)
2782 conf_parserror(_("%s must be positive"), get_token_name(np->token));
2785 conf_parserror(_("validate_nonnegative invalid type %d\n"), val->type);
2791 struct conf_var_s *np,
2796 if(val_t__int(val) < 1)
2797 conf_parserror(_("%s must be positive"), get_token_name(np->token));
2800 if(val_t__am64(val) < 1)
2801 conf_parserror(_("%s must be positive"), get_token_name(np->token));
2804 if(val_t__time(val) < 1)
2805 conf_parserror(_("%s must be positive"), get_token_name(np->token));
2808 if(val_t__size(val) < 1)
2809 conf_parserror(_("%s must be positive"), get_token_name(np->token));
2812 conf_parserror(_("validate_positive invalid type %d\n"), val->type);
2817 validate_runspercycle(
2818 struct conf_var_s *np G_GNUC_UNUSED,
2821 if(val_t__int(val) < -1)
2822 conf_parserror(_("runspercycle must be >= -1"));
2826 validate_bumppercent(
2827 struct conf_var_s *np G_GNUC_UNUSED,
2830 if(val_t__int(val) < 0 || val_t__int(val) > 100)
2831 conf_parserror(_("bumppercent must be between 0 and 100"));
2835 validate_inparallel(
2836 struct conf_var_s *np G_GNUC_UNUSED,
2839 if(val_t__int(val) < 1 || val_t__int(val) >MAX_DUMPERS)
2840 conf_parserror(_("inparallel must be between 1 and MAX_DUMPERS (%d)"),
2846 struct conf_var_s *np G_GNUC_UNUSED,
2849 if(val_t__real(val) < 0.999) {
2850 conf_parserror(_("bumpmult must one or more"));
2855 validate_displayunit(
2856 struct conf_var_s *np G_GNUC_UNUSED,
2857 val_t *val G_GNUC_UNUSED)
2859 char *s = val_t__str(val);
2860 if (strlen(s) == 1) {
2866 return; /* all good */
2868 /* lower-case values should get folded to upper case */
2873 s[0] = toupper(s[0]);
2880 conf_parserror(_("displayunit must be k,m,g or t."));
2885 struct conf_var_s *np G_GNUC_UNUSED,
2888 if(val_t__int(val) < 0 || val_t__int(val) > 100)
2889 conf_parserror(_("reserve must be between 0 and 100"));
2894 struct conf_var_s *np G_GNUC_UNUSED,
2897 val_t__am64(val) = am_floor(val_t__am64(val), DISK_BLOCK_KB);
2902 struct conf_var_s *np G_GNUC_UNUSED,
2905 /* NOTE: this function modifies the target value (rounding) */
2906 if(val_t__am64(val) == 0) {
2907 val_t__am64(val) = ((AM64_MAX / 1024) - (2 * DISK_BLOCK_KB));
2909 else if(val_t__am64(val) < 0) {
2910 conf_parserror(_("Negative chunksize (%lld) is no longer supported"), (long long)val_t__am64(val));
2912 val_t__am64(val) = am_floor(val_t__am64(val), (off_t)DISK_BLOCK_KB);
2913 if (val_t__am64(val) < 2*DISK_BLOCK_KB) {
2914 conf_parserror("chunksize must be at least %dkb", 2*DISK_BLOCK_KB);
2920 struct conf_var_s *np G_GNUC_UNUSED,
2923 if(val_t__size(val) < DISK_BLOCK_KB) {
2924 conf_parserror(_("Tape blocksize must be at least %d KBytes"),
2931 struct conf_var_s *np G_GNUC_UNUSED,
2934 if(val_t__int(val) < 0 || val_t__int(val) > 9) {
2935 conf_parserror(_("Debug must be between 0 and 9"));
2940 validate_port_range(
2946 /* check both values are in range */
2947 for (i = 0; i < 2; i++) {
2948 if(val_t__intrange(val)[0] < smallest || val_t__intrange(val)[0] > largest) {
2949 conf_parserror(_("portrange must be in the range %d to %d, inclusive"), smallest, largest);
2953 /* and check they're in the right order and not equal */
2954 if (val_t__intrange(val)[0] > val_t__intrange(val)[1]) {
2955 conf_parserror(_("portranges must be in order from low to high"));
2960 validate_reserved_port_range(
2961 struct conf_var_s *np G_GNUC_UNUSED,
2964 validate_port_range(val, 1, IPPORT_RESERVED-1);
2968 validate_unreserved_port_range(
2969 struct conf_var_s *np G_GNUC_UNUSED,
2972 validate_port_range(val, IPPORT_RESERVED, 65535);
2976 * Initialization Implementation
2981 config_init_flags flags,
2982 char *arg_config_name)
2984 if (!(flags & CONFIG_INIT_OVERLAY)) {
2985 /* Clear out anything that's already in there */
2988 /* and set everything to default values */
2991 allow_overwrites = FALSE;
2993 if (!config_initialized) {
2994 error(_("Attempt to overlay configuration with no existing configuration"));
2998 allow_overwrites = TRUE;
3001 /* store away our client-ness for later reference */
3002 config_client = flags & CONFIG_INIT_CLIENT;
3004 if ((flags & CONFIG_INIT_EXPLICIT_NAME) && arg_config_name) {
3005 config_name = newstralloc(config_name, arg_config_name);
3006 config_dir = newvstralloc(config_dir, CONFIG_DIR, "/", arg_config_name, NULL);
3007 } else if (flags & CONFIG_INIT_USE_CWD) {
3010 cwd = get_original_cwd();
3012 /* (this isn't a config error, so it's always fatal) */
3013 error(_("Cannot determine current working directory"));
3017 config_dir = stralloc2(cwd, "/");
3018 if ((config_name = strrchr(cwd, '/')) != NULL) {
3019 config_name = stralloc(config_name + 1);
3023 } else if (flags & CONFIG_INIT_CLIENT) {
3024 amfree(config_name);
3025 config_dir = newstralloc(config_dir, CONFIG_DIR);
3027 /* ok, then, we won't read anything (for e.g., amrestore) */
3028 amfree(config_name);
3032 /* If we have a config_dir, we can try reading something */
3034 if (flags & CONFIG_INIT_CLIENT) {
3035 config_filename = newvstralloc(config_filename, config_dir, "/amanda-client.conf", NULL);
3037 config_filename = newvstralloc(config_filename, config_dir, "/amanda.conf", NULL);
3040 /* try to read the file, and handle parse errors */
3041 if (!read_conffile(config_filename, flags & CONFIG_INIT_CLIENT)) {
3042 if (flags & CONFIG_INIT_FATAL) {
3043 error(_("errors processing config file \"%s\""), config_filename);
3046 g_warning(_("errors processing config file \"%s\" (non-fatal)"), config_filename);
3051 amfree(config_filename);
3054 update_derived_values(flags & CONFIG_INIT_CLIENT);
3062 holdingdisk_t *hp, *hpnext;
3063 dumptype_t *dp, *dpnext;
3064 tapetype_t *tp, *tpnext;
3065 interface_t *ip, *ipnext;
3068 if (!config_initialized) return;
3070 for(hp=holdinglist; hp != NULL; hp = hpnext) {
3072 for(i=0; i<HOLDING_HOLDING-1; i++) {
3073 free_val_t(&hp->value[i]);
3080 for(dp=dumplist; dp != NULL; dp = dpnext) {
3082 for(i=0; i<DUMPTYPE_DUMPTYPE-1; i++) {
3083 free_val_t(&dp->value[i]);
3090 for(tp=tapelist; tp != NULL; tp = tpnext) {
3092 for(i=0; i<TAPETYPE_TAPETYPE-1; i++) {
3093 free_val_t(&tp->value[i]);
3100 for(ip=interface_list; ip != NULL; ip = ipnext) {
3102 for(i=0; i<INTER_INTER-1; i++) {
3103 free_val_t(&ip->value[i]);
3108 interface_list = NULL;
3110 for(i=0; i<CNF_CNF-1; i++)
3111 free_val_t(&conf_data[i]);
3113 if (applied_config_overwrites) {
3114 free_config_overwrites(applied_config_overwrites);
3115 applied_config_overwrites = NULL;
3118 amfree(config_name);
3121 config_client = FALSE;
3123 config_initialized = FALSE;
3130 assert(!config_initialized);
3132 /* defaults for exported variables */
3133 conf_init_str(&conf_data[CNF_ORG], DEFAULT_CONFIG);
3134 conf_init_str(&conf_data[CNF_CONF], DEFAULT_CONFIG);
3135 conf_init_str(&conf_data[CNF_INDEX_SERVER], DEFAULT_SERVER);
3136 conf_init_str(&conf_data[CNF_TAPE_SERVER], DEFAULT_TAPE_SERVER);
3137 conf_init_str(&conf_data[CNF_AUTH], "bsd");
3138 conf_init_str(&conf_data[CNF_SSH_KEYS], "");
3139 conf_init_str(&conf_data[CNF_AMANDAD_PATH], "");
3140 conf_init_str(&conf_data[CNF_CLIENT_USERNAME], "");
3141 conf_init_str(&conf_data[CNF_GNUTAR_LIST_DIR], GNUTAR_LISTED_INCREMENTAL_DIR);
3142 conf_init_str(&conf_data[CNF_AMANDATES], DEFAULT_AMANDATES_FILE);
3143 conf_init_str(&conf_data[CNF_MAILTO], "operators");
3144 conf_init_str(&conf_data[CNF_DUMPUSER], CLIENT_LOGIN);
3145 conf_init_str(&conf_data[CNF_TAPEDEV], DEFAULT_TAPE_DEVICE);
3146 conf_init_proplist(&conf_data[CNF_DEVICE_PROPERTY]);
3147 conf_init_str(&conf_data[CNF_CHANGERDEV], DEFAULT_CHANGER_DEVICE);
3148 conf_init_str(&conf_data[CNF_CHANGERFILE], "/usr/adm/amanda/changer-status");
3149 conf_init_str (&conf_data[CNF_LABELSTR] , ".*");
3150 conf_init_str (&conf_data[CNF_TAPELIST] , "tapelist");
3151 conf_init_str (&conf_data[CNF_DISKFILE] , "disklist");
3152 conf_init_str (&conf_data[CNF_INFOFILE] , "/usr/adm/amanda/curinfo");
3153 conf_init_str (&conf_data[CNF_LOGDIR] , "/usr/adm/amanda");
3154 conf_init_str (&conf_data[CNF_INDEXDIR] , "/usr/adm/amanda/index");
3155 conf_init_ident (&conf_data[CNF_TAPETYPE] , "EXABYTE");
3156 conf_init_int (&conf_data[CNF_DUMPCYCLE] , 10);
3157 conf_init_int (&conf_data[CNF_RUNSPERCYCLE] , 0);
3158 conf_init_int (&conf_data[CNF_TAPECYCLE] , 15);
3159 conf_init_int (&conf_data[CNF_NETUSAGE] , 8000);
3160 conf_init_int (&conf_data[CNF_INPARALLEL] , 10);
3161 conf_init_str (&conf_data[CNF_DUMPORDER] , "ttt");
3162 conf_init_int (&conf_data[CNF_BUMPPERCENT] , 0);
3163 conf_init_am64 (&conf_data[CNF_BUMPSIZE] , (off_t)10*1024);
3164 conf_init_real (&conf_data[CNF_BUMPMULT] , 1.5);
3165 conf_init_int (&conf_data[CNF_BUMPDAYS] , 2);
3166 conf_init_str (&conf_data[CNF_TPCHANGER] , "");
3167 conf_init_int (&conf_data[CNF_RUNTAPES] , 1);
3168 conf_init_int (&conf_data[CNF_MAXDUMPS] , 1);
3169 conf_init_int (&conf_data[CNF_ETIMEOUT] , 300);
3170 conf_init_int (&conf_data[CNF_DTIMEOUT] , 1800);
3171 conf_init_int (&conf_data[CNF_CTIMEOUT] , 30);
3172 conf_init_int (&conf_data[CNF_TAPEBUFS] , 20);
3173 conf_init_size (&conf_data[CNF_DEVICE_OUTPUT_BUFFER_SIZE], 40*32768);
3174 conf_init_str (&conf_data[CNF_PRINTER] , "");
3175 conf_init_bool (&conf_data[CNF_AUTOFLUSH] , 0);
3176 conf_init_int (&conf_data[CNF_RESERVE] , 100);
3177 conf_init_am64 (&conf_data[CNF_MAXDUMPSIZE] , (off_t)-1);
3178 conf_init_str (&conf_data[CNF_COLUMNSPEC] , "");
3179 conf_init_bool (&conf_data[CNF_AMRECOVER_DO_FSF] , 1);
3180 conf_init_str (&conf_data[CNF_AMRECOVER_CHANGER] , "");
3181 conf_init_bool (&conf_data[CNF_AMRECOVER_CHECK_LABEL], 1);
3182 conf_init_taperalgo(&conf_data[CNF_TAPERALGO] , 0);
3183 conf_init_int (&conf_data[CNF_FLUSH_THRESHOLD_DUMPED] , 0);
3184 conf_init_int (&conf_data[CNF_FLUSH_THRESHOLD_SCHEDULED], 0);
3185 conf_init_int (&conf_data[CNF_TAPERFLUSH] , 0);
3186 conf_init_str (&conf_data[CNF_DISPLAYUNIT] , "k");
3187 conf_init_str (&conf_data[CNF_KRB5KEYTAB] , "/.amanda-v5-keytab");
3188 conf_init_str (&conf_data[CNF_KRB5PRINCIPAL] , "service/amanda");
3189 conf_init_str (&conf_data[CNF_LABEL_NEW_TAPES] , "");
3190 conf_init_bool (&conf_data[CNF_USETIMESTAMPS] , 1);
3191 conf_init_int (&conf_data[CNF_CONNECT_TRIES] , 3);
3192 conf_init_int (&conf_data[CNF_REP_TRIES] , 5);
3193 conf_init_int (&conf_data[CNF_REQ_TRIES] , 3);
3194 conf_init_int (&conf_data[CNF_DEBUG_AMANDAD] , 0);
3195 conf_init_int (&conf_data[CNF_DEBUG_AMIDXTAPED] , 0);
3196 conf_init_int (&conf_data[CNF_DEBUG_AMINDEXD] , 0);
3197 conf_init_int (&conf_data[CNF_DEBUG_AMRECOVER] , 0);
3198 conf_init_int (&conf_data[CNF_DEBUG_AUTH] , 0);
3199 conf_init_int (&conf_data[CNF_DEBUG_EVENT] , 0);
3200 conf_init_int (&conf_data[CNF_DEBUG_HOLDING] , 0);
3201 conf_init_int (&conf_data[CNF_DEBUG_PROTOCOL] , 0);
3202 conf_init_int (&conf_data[CNF_DEBUG_PLANNER] , 0);
3203 conf_init_int (&conf_data[CNF_DEBUG_DRIVER] , 0);
3204 conf_init_int (&conf_data[CNF_DEBUG_DUMPER] , 0);
3205 conf_init_int (&conf_data[CNF_DEBUG_CHUNKER] , 0);
3206 conf_init_int (&conf_data[CNF_DEBUG_TAPER] , 0);
3207 conf_init_int (&conf_data[CNF_DEBUG_SELFCHECK] , 0);
3208 conf_init_int (&conf_data[CNF_DEBUG_SENDSIZE] , 0);
3209 conf_init_int (&conf_data[CNF_DEBUG_SENDBACKUP] , 0);
3211 conf_init_intrange (&conf_data[CNF_RESERVED_UDP_PORT] , UDPPORTRANGE);
3213 conf_init_intrange (&conf_data[CNF_RESERVED_UDP_PORT] , 512, IPPORT_RESERVED-1);
3215 #ifdef LOW_TCPPORTRANGE
3216 conf_init_intrange (&conf_data[CNF_RESERVED_TCP_PORT] , LOW_TCPPORTRANGE);
3218 conf_init_intrange (&conf_data[CNF_RESERVED_TCP_PORT] , 512, IPPORT_RESERVED-1);
3221 conf_init_intrange (&conf_data[CNF_UNRESERVED_TCP_PORT] , TCPPORTRANGE);
3223 conf_init_intrange (&conf_data[CNF_UNRESERVED_TCP_PORT] , IPPORT_RESERVED, 65535);
3226 /* reset internal variables */
3227 got_parserror = FALSE;
3228 allow_overwrites = 0;
3231 /* create some predefined dumptypes for backwards compatability */
3232 init_dumptype_defaults();
3233 dpcur.name = stralloc("NO-COMPRESS");
3235 free_val_t(&dpcur.value[DUMPTYPE_COMPRESS]);
3236 val_t__compress(&dpcur.value[DUMPTYPE_COMPRESS]) = COMP_NONE;
3237 val_t__seen(&dpcur.value[DUMPTYPE_COMPRESS]) = -1;
3240 init_dumptype_defaults();
3241 dpcur.name = stralloc("COMPRESS-FAST");
3243 free_val_t(&dpcur.value[DUMPTYPE_COMPRESS]);
3244 val_t__compress(&dpcur.value[DUMPTYPE_COMPRESS]) = COMP_FAST;
3245 val_t__seen(&dpcur.value[DUMPTYPE_COMPRESS]) = -1;
3248 init_dumptype_defaults();
3249 dpcur.name = stralloc("COMPRESS-BEST");
3251 free_val_t(&dpcur.value[DUMPTYPE_COMPRESS]);
3252 val_t__compress(&dpcur.value[DUMPTYPE_COMPRESS]) = COMP_BEST;
3253 val_t__seen(&dpcur.value[DUMPTYPE_COMPRESS]) = -1;
3256 init_dumptype_defaults();
3257 dpcur.name = stralloc("COMPRESS-CUST");
3259 free_val_t(&dpcur.value[DUMPTYPE_COMPRESS]);
3260 val_t__compress(&dpcur.value[DUMPTYPE_COMPRESS]) = COMP_CUST;
3261 val_t__seen(&dpcur.value[DUMPTYPE_COMPRESS]) = -1;
3264 init_dumptype_defaults();
3265 dpcur.name = stralloc("SRVCOMPRESS");
3267 free_val_t(&dpcur.value[DUMPTYPE_COMPRESS]);
3268 val_t__compress(&dpcur.value[DUMPTYPE_COMPRESS]) = COMP_SERVER_FAST;
3269 val_t__seen(&dpcur.value[DUMPTYPE_COMPRESS]) = -1;
3272 init_dumptype_defaults();
3273 dpcur.name = stralloc("BSD-AUTH");
3275 free_val_t(&dpcur.value[DUMPTYPE_SECURITY_DRIVER]);
3276 val_t__str(&dpcur.value[DUMPTYPE_SECURITY_DRIVER]) = stralloc("BSD");
3277 val_t__seen(&dpcur.value[DUMPTYPE_SECURITY_DRIVER]) = -1;
3280 init_dumptype_defaults();
3281 dpcur.name = stralloc("KRB4-AUTH");
3283 free_val_t(&dpcur.value[DUMPTYPE_SECURITY_DRIVER]);
3284 val_t__str(&dpcur.value[DUMPTYPE_SECURITY_DRIVER]) = stralloc("KRB4");
3285 val_t__seen(&dpcur.value[DUMPTYPE_SECURITY_DRIVER]) = -1;
3288 init_dumptype_defaults();
3289 dpcur.name = stralloc("NO-RECORD");
3291 free_val_t(&dpcur.value[DUMPTYPE_RECORD]);
3292 val_t__int(&dpcur.value[DUMPTYPE_RECORD]) = 0;
3293 val_t__seen(&dpcur.value[DUMPTYPE_RECORD]) = -1;
3296 init_dumptype_defaults();
3297 dpcur.name = stralloc("NO-HOLD");
3299 free_val_t(&dpcur.value[DUMPTYPE_HOLDINGDISK]);
3300 val_t__holding(&dpcur.value[DUMPTYPE_HOLDINGDISK]) = HOLD_NEVER;
3301 val_t__seen(&dpcur.value[DUMPTYPE_HOLDINGDISK]) = -1;
3304 init_dumptype_defaults();
3305 dpcur.name = stralloc("NO-FULL");
3307 free_val_t(&dpcur.value[DUMPTYPE_STRATEGY]);
3308 val_t__strategy(&dpcur.value[DUMPTYPE_STRATEGY]) = DS_NOFULL;
3309 val_t__seen(&dpcur.value[DUMPTYPE_STRATEGY]) = -1;
3312 /* And we're initialized! */
3313 config_initialized = 1;
3320 char **config_options;
3321 char **config_option;
3322 int n_applied_config_overwrites = 0;
3325 if (applied_config_overwrites)
3326 n_applied_config_overwrites = applied_config_overwrites->n_used;
3328 config_options = alloc((first+n_applied_config_overwrites+1)*SIZEOF(char *));
3329 config_option = config_options + first;
3331 for (i = 0; i < n_applied_config_overwrites; i++) {
3332 char *key = applied_config_overwrites->ovr[i].key;
3333 char *value = applied_config_overwrites->ovr[i].value;
3334 *config_option = vstralloc("-o", key, "=", value, NULL);
3338 *config_option = NULL; /* add terminating sentinel */
3340 return config_options;
3344 update_derived_values(
3350 /* Add a 'default' interface if one doesn't already exist */
3351 if (!(ip = lookup_interface("default"))) {
3352 init_interface_defaults();
3353 ifcur.name = stralloc("default");
3354 ifcur.seen = getconf_seen(CNF_NETUSAGE);
3357 ip = lookup_interface("default");
3360 /* .. and set its maxusage from 'netusage' */
3361 if (!interface_seen(ip, INTER_MAXUSAGE)) {
3364 v = interface_getconf(ip, INTER_COMMENT);
3366 val_t__str(v) = stralloc(_("implicit from NETUSAGE"));
3367 val_t__seen(v) = getconf_seen(CNF_NETUSAGE);
3369 v = interface_getconf(ip, INTER_MAXUSAGE);
3371 val_t__int(v) = getconf_int(CNF_NETUSAGE);
3372 val_t__seen(v) = getconf_seen(CNF_NETUSAGE);
3375 /* Check the tapetype is defined */
3376 if (lookup_tapetype(getconf_str(CNF_TAPETYPE)) == NULL) {
3377 /* Create a default tapetype */
3378 if (!getconf_seen(CNF_TAPETYPE) &&
3379 strcmp(getconf_str(CNF_TAPETYPE), "EXABYTE") == 0 &&
3380 !lookup_tapetype("EXABYTE")) {
3381 init_tapetype_defaults();
3382 tpcur.name = stralloc("EXABYTE");
3386 conf_parserror(_("tapetype %s is not defined"),
3387 getconf_str(CNF_TAPETYPE));
3392 /* fill in the debug_* values */
3393 debug_amandad = getconf_int(CNF_DEBUG_AMANDAD);
3394 debug_amidxtaped = getconf_int(CNF_DEBUG_AMIDXTAPED);
3395 debug_amindexd = getconf_int(CNF_DEBUG_AMINDEXD);
3396 debug_amrecover = getconf_int(CNF_DEBUG_AMRECOVER);
3397 debug_auth = getconf_int(CNF_DEBUG_AUTH);
3398 debug_event = getconf_int(CNF_DEBUG_EVENT);
3399 debug_holding = getconf_int(CNF_DEBUG_HOLDING);
3400 debug_protocol = getconf_int(CNF_DEBUG_PROTOCOL);
3401 debug_planner = getconf_int(CNF_DEBUG_PLANNER);
3402 debug_driver = getconf_int(CNF_DEBUG_DRIVER);
3403 debug_dumper = getconf_int(CNF_DEBUG_DUMPER);
3404 debug_chunker = getconf_int(CNF_DEBUG_CHUNKER);
3405 debug_taper = getconf_int(CNF_DEBUG_TAPER);
3406 debug_selfcheck = getconf_int(CNF_DEBUG_SELFCHECK);
3407 debug_sendsize = getconf_int(CNF_DEBUG_SENDSIZE);
3408 debug_sendbackup = getconf_int(CNF_DEBUG_SENDBACKUP);
3410 /* And finally, display unit */
3411 switch (getconf_str(CNF_DISPLAYUNIT)[0]) {
3419 unit_divisor = 1024;
3424 unit_divisor = 1024*1024;
3429 unit_divisor = 1024*1024*1024;
3433 error(_("Invalid displayunit missed by validate_displayunit"));
3444 val->type = CONFTYPE_INT;
3445 val_t__int(val) = i;
3454 val->type = CONFTYPE_AM64;
3455 val_t__am64(val) = l;
3464 val->type = CONFTYPE_REAL;
3465 val_t__real(val) = r;
3474 val->type = CONFTYPE_STR;
3476 val->v.s = stralloc(s);
3487 val->type = CONFTYPE_IDENT;
3489 val->v.s = stralloc(s);
3500 val->type = CONFTYPE_TIME;
3501 val_t__time(val) = t;
3510 val->type = CONFTYPE_SIZE;
3511 val_t__size(val) = sz;
3520 val->type = CONFTYPE_BOOLEAN;
3521 val_t__boolean(val) = i;
3530 val->type = CONFTYPE_COMPRESS;
3531 val_t__compress(val) = (int)i;
3540 val->type = CONFTYPE_ENCRYPT;
3541 val_t__encrypt(val) = (int)i;
3547 dump_holdingdisk_t i)
3550 val->type = CONFTYPE_HOLDING;
3551 val_t__holding(val) = (int)i;
3560 val->type = CONFTYPE_ESTIMATE;
3561 val_t__estimate(val) = i;
3570 val->type = CONFTYPE_STRATEGY;
3571 val_t__strategy(val) = i;
3575 conf_init_taperalgo(
3580 val->type = CONFTYPE_TAPERALGO;
3581 val_t__taperalgo(val) = i;
3590 val->type = CONFTYPE_PRIORITY;
3591 val_t__priority(val) = i;
3601 val->type = CONFTYPE_RATE;
3602 val_t__rate(val)[0] = r1;
3603 val_t__rate(val)[1] = r2;
3607 conf_init_exinclude(
3611 val->type = CONFTYPE_EXINCLUDE;
3612 val_t__exinclude(val).optional = 0;
3613 val_t__exinclude(val).sl_list = NULL;
3614 val_t__exinclude(val).sl_file = NULL;
3624 val->type = CONFTYPE_INTRANGE;
3625 val_t__intrange(val)[0] = i1;
3626 val_t__intrange(val)[1] = i2;
3634 val->type = CONFTYPE_PROPLIST;
3635 val_t__proplist(val) =
3636 g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
3640 * Config access implementation
3644 getconf(confparm_key key)
3646 assert(key < CNF_CNF);
3647 return &conf_data[key];
3660 if (strcasecmp(listname,"tapetype") == 0) {
3661 for(tp = tapelist; tp != NULL; tp=tp->next) {
3662 rv = g_slist_append(rv, tp->name);
3664 } else if (strcasecmp(listname,"dumptype") == 0) {
3665 for(dp = dumplist; dp != NULL; dp=dp->next) {
3666 rv = g_slist_append(rv, dp->name);
3668 } else if (strcasecmp(listname,"holdingdisk") == 0) {
3669 for(hp = holdinglist; hp != NULL; hp=hp->next) {
3670 rv = g_slist_append(rv, hp->name);
3672 } else if (strcasecmp(listname,"interface") == 0) {
3673 for(ip = interface_list; ip != NULL; ip=ip->next) {
3674 rv = g_slist_append(rv, ip->name);
3686 if (!parm_key_info(key, NULL, &rv))
3698 for(p = tapelist; p != NULL; p = p->next) {
3699 if(strcasecmp(p->name, str) == 0) return p;
3709 assert(ttyp != NULL);
3710 assert(key < TAPETYPE_TAPETYPE);
3711 return &ttyp->value[key];
3718 assert(ttyp != NULL);
3728 for(p = dumplist; p != NULL; p = p->next) {
3729 if(strcasecmp(p->name, str) == 0) return p;
3739 assert(dtyp != NULL);
3740 assert(key < DUMPTYPE_DUMPTYPE);
3741 return &dtyp->value[key];
3748 assert(dtyp != NULL);
3758 for(p = interface_list; p != NULL; p = p->next) {
3759 if(strcasecmp(p->name, str) == 0) return p;
3769 assert(iface != NULL);
3770 assert(key < INTER_INTER);
3771 return &iface->value[key];
3778 assert(iface != NULL);
3788 for(p = holdinglist; p != NULL; p = p->next) {
3789 if(strcasecmp(p->name, str) == 0) return p;
3795 getconf_holdingdisks(
3803 holdingdisk_t *hdisk)
3805 if (hdisk) return hdisk->next;
3810 holdingdisk_getconf(
3811 holdingdisk_t *hdisk,
3812 holdingdisk_key key)
3814 assert(hdisk != NULL);
3815 assert(key < HOLDING_HOLDING);
3816 return &hdisk->value[key];
3821 holdingdisk_t *hdisk)
3823 assert(hdisk != NULL);
3828 getconf_unit_divisor(void)
3830 return unit_divisor;
3834 * Command-line Handling Implementation
3837 config_overwrites_t *
3838 new_config_overwrites(
3841 config_overwrites_t *co;
3843 co = alloc(sizeof(*co));
3844 co->ovr = alloc(sizeof(*co->ovr) * size_estimate);
3845 co->n_allocated = size_estimate;
3852 free_config_overwrites(
3853 config_overwrites_t *co)
3858 for (i = 0; i < co->n_used; i++) {
3859 amfree(co->ovr[i].key);
3860 amfree(co->ovr[i].value);
3866 void add_config_overwrite(
3867 config_overwrites_t *co,
3871 /* reallocate if necessary */
3872 if (co->n_used == co->n_allocated) {
3873 co->n_allocated *= 2;
3874 co->ovr = realloc(co->ovr, co->n_allocated * sizeof(*co->ovr));
3876 error(_("Cannot realloc; out of memory"));
3881 co->ovr[co->n_used].key = stralloc(key);
3882 co->ovr[co->n_used].value = stralloc(value);
3887 add_config_overwrite_opt(
3888 config_overwrites_t *co,
3892 assert(optarg != NULL);
3894 value = index(optarg, '=');
3895 if (value == NULL) {
3896 error(_("Must specify a value for %s."), optarg);
3901 add_config_overwrite(co, optarg, value+1);
3905 config_overwrites_t *
3906 extract_commandline_config_overwrites(
3911 config_overwrites_t *co = new_config_overwrites(*argc/2);
3915 if(strncmp((*argv)[i],"-o",2) == 0) {
3916 if(strlen((*argv)[i]) > 2) {
3917 add_config_overwrite_opt(co, (*argv)[i]+2);
3921 if (i+1 >= *argc) error(_("expect something after -o"));
3922 add_config_overwrite_opt(co, (*argv)[i+1]);
3926 /* move up remaining argment array */
3927 for (j = i; j+moveup<*argc; j++) {
3928 (*argv)[j] = (*argv)[j+moveup];
3940 apply_config_overwrites(
3941 config_overwrites_t *co)
3946 assert(keytable != NULL);
3947 assert(parsetable != NULL);
3949 for (i = 0; i < co->n_used; i++) {
3950 char *key = co->ovr[i].key;
3951 char *value = co->ovr[i].value;
3953 conf_var_t *key_parm;
3955 if (!parm_key_info(key, &key_parm, &key_val)) {
3956 error(_("unknown parameter '%s'"), key);
3959 /* now set up a fake line and use the relevant read_function to
3960 * parse it. This is sneaky! */
3962 if (key_parm->type == CONFTYPE_STR) {
3963 current_line = vstralloc("\"", value, "\"", NULL);
3965 current_line = stralloc("");
3968 current_char = current_line;
3970 current_line_num = -2;
3971 allow_overwrites = 1;
3974 key_parm->read_function(key_parm, key_val);
3975 if ((key_parm)->validate_function)
3976 key_parm->validate_function(key_parm, key_val);
3978 amfree(current_line);
3979 current_char = NULL;
3981 if (got_parserror) {
3982 error(_("parse error in configuration overwrites"));
3987 /* merge these overwrites with previous overwrites, if necessary */
3988 if (applied_config_overwrites) {
3989 for (i = 0; i < co->n_used; i++) {
3990 char *key = co->ovr[i].key;
3991 char *value = co->ovr[i].value;
3993 add_config_overwrite(applied_config_overwrites, key, value);
3995 free_config_overwrites(co);
3997 applied_config_overwrites = co;
4000 update_derived_values(config_client);
4004 * val_t Management Implementation
4011 if (val->type != CONFTYPE_INT) {
4012 error(_("val_t_to_int: val.type is not CONFTYPE_INT"));
4015 return val_t__int(val);
4022 if (val->type != CONFTYPE_AM64) {
4023 error(_("val_t_to_am64: val.type is not CONFTYPE_AM64"));
4026 return val_t__am64(val);
4033 if (val->type != CONFTYPE_REAL) {
4034 error(_("val_t_to_real: val.type is not CONFTYPE_REAL"));
4037 return val_t__real(val);
4044 /* support CONFTYPE_IDENT, too */
4045 if (val->type != CONFTYPE_STR && val->type != CONFTYPE_IDENT) {
4046 error(_("val_t_to_str: val.type is not CONFTYPE_STR nor CONFTYPE_IDENT"));
4049 return val_t__str(val);
4056 /* support CONFTYPE_STR, too */
4057 if (val->type != CONFTYPE_STR && val->type != CONFTYPE_IDENT) {
4058 error(_("val_t_to_ident: val.type is not CONFTYPE_IDENT nor CONFTYPE_STR"));
4061 return val_t__str(val);
4068 if (val->type != CONFTYPE_TIME) {
4069 error(_("val_t_to_time: val.type is not CONFTYPE_TIME"));
4072 return val_t__time(val);
4079 if (val->type != CONFTYPE_SIZE) {
4080 error(_("val_t_to_size: val.type is not CONFTYPE_SIZE"));
4083 return val_t__size(val);
4090 if (val->type != CONFTYPE_BOOLEAN) {
4091 error(_("val_t_to_bool: val.type is not CONFTYPE_BOOLEAN"));
4094 return val_t__boolean(val);
4101 if (val->type != CONFTYPE_COMPRESS) {
4102 error(_("val_t_to_compress: val.type is not CONFTYPE_COMPRESS"));
4105 return val_t__compress(val);
4112 if (val->type != CONFTYPE_ENCRYPT) {
4113 error(_("val_t_to_encrypt: val.type is not CONFTYPE_ENCRYPT"));
4116 return val_t__encrypt(val);
4123 if (val->type != CONFTYPE_HOLDING) {
4124 error(_("val_t_to_hold: val.type is not CONFTYPE_HOLDING"));
4127 return val_t__holding(val);
4134 if (val->type != CONFTYPE_ESTIMATE) {
4135 error(_("val_t_to_extimate: val.type is not CONFTYPE_ESTIMATE"));
4138 return val_t__estimate(val);
4145 if (val->type != CONFTYPE_STRATEGY) {
4146 error(_("val_t_to_strategy: val.type is not CONFTYPE_STRATEGY"));
4149 return val_t__strategy(val);
4156 if (val->type != CONFTYPE_TAPERALGO) {
4157 error(_("val_t_to_taperalgo: val.type is not CONFTYPE_TAPERALGO"));
4160 return val_t__taperalgo(val);
4167 if (val->type != CONFTYPE_PRIORITY) {
4168 error(_("val_t_to_priority: val.type is not CONFTYPE_PRIORITY"));
4171 return val_t__priority(val);
4178 if (val->type != CONFTYPE_RATE) {
4179 error(_("val_t_to_rate: val.type is not CONFTYPE_RATE"));
4182 return val_t__rate(val);
4189 if (val->type != CONFTYPE_EXINCLUDE) {
4190 error(_("val_t_to_exinclude: val.type is not CONFTYPE_EXINCLUDE"));
4193 return val_t__exinclude(val);
4201 if (val->type != CONFTYPE_INTRANGE) {
4202 error(_("val_t_to_intrange: val.type is not CONFTYPE_INTRANGE"));
4205 return val_t__intrange(val);
4212 if (val->type != CONFTYPE_PROPLIST) {
4213 error(_("val_t_to_proplist: val.type is not CONFTYPE_PROPLIST"));
4216 return val_t__proplist(val);
4225 valdst->type = valsrc->type;
4226 valdst->seen = valsrc->seen;
4227 switch(valsrc->type) {
4229 case CONFTYPE_BOOLEAN:
4230 case CONFTYPE_COMPRESS:
4231 case CONFTYPE_ENCRYPT:
4232 case CONFTYPE_HOLDING:
4233 case CONFTYPE_ESTIMATE:
4234 case CONFTYPE_STRATEGY:
4235 case CONFTYPE_TAPERALGO:
4236 case CONFTYPE_PRIORITY:
4237 valdst->v.i = valsrc->v.i;
4241 valdst->v.size = valsrc->v.size;
4245 valdst->v.am64 = valsrc->v.am64;
4249 valdst->v.r = valsrc->v.r;
4253 valdst->v.rate[0] = valsrc->v.rate[0];
4254 valdst->v.rate[1] = valsrc->v.rate[1];
4257 case CONFTYPE_IDENT:
4259 valdst->v.s = stralloc(valsrc->v.s);
4263 valdst->v.t = valsrc->v.t;
4266 case CONFTYPE_EXINCLUDE:
4267 valdst->v.exinclude.optional = valsrc->v.exinclude.optional;
4268 valdst->v.exinclude.sl_list = duplicate_sl(valsrc->v.exinclude.sl_list);
4269 valdst->v.exinclude.sl_file = duplicate_sl(valsrc->v.exinclude.sl_file);
4272 case CONFTYPE_INTRANGE:
4273 valdst->v.intrange[0] = valsrc->v.intrange[0];
4274 valdst->v.intrange[1] = valsrc->v.intrange[1];
4277 case CONFTYPE_PROPLIST:
4278 g_assert_not_reached();
4290 case CONFTYPE_BOOLEAN:
4291 case CONFTYPE_COMPRESS:
4292 case CONFTYPE_ENCRYPT:
4293 case CONFTYPE_HOLDING:
4294 case CONFTYPE_ESTIMATE:
4295 case CONFTYPE_STRATEGY:
4297 case CONFTYPE_TAPERALGO:
4298 case CONFTYPE_PRIORITY:
4302 case CONFTYPE_INTRANGE:
4305 case CONFTYPE_IDENT:
4313 case CONFTYPE_EXINCLUDE:
4314 free_sl(val_t__exinclude(val).sl_list);
4315 free_sl(val_t__exinclude(val).sl_file);
4318 case CONFTYPE_PROPLIST:
4319 g_hash_table_destroy(val_t__proplist(val));
4326 * Utilities Implementation
4330 generic_get_security_conf(
4335 if(!string || !*string)
4338 if(strcmp(string, "krb5principal")==0) {
4339 return(getconf_str(CNF_KRB5PRINCIPAL));
4340 } else if(strcmp(string, "krb5keytab")==0) {
4341 return(getconf_str(CNF_KRB5KEYTAB));
4347 generic_client_get_security_conf(
4351 (void)arg; /* Quiet unused parameter warning */
4353 if(!string || !*string)
4356 if(strcmp(string, "conf")==0) {
4357 return(getconf_str(CNF_CONF));
4358 } else if(strcmp(string, "index_server")==0) {
4359 return(getconf_str(CNF_INDEX_SERVER));
4360 } else if(strcmp(string, "tape_server")==0) {
4361 return(getconf_str(CNF_TAPE_SERVER));
4362 } else if(strcmp(string, "tapedev")==0) {
4363 return(getconf_str(CNF_TAPEDEV));
4364 } else if(strcmp(string, "auth")==0) {
4365 return(getconf_str(CNF_AUTH));
4366 } else if(strcmp(string, "ssh_keys")==0) {
4367 return(getconf_str(CNF_SSH_KEYS));
4368 } else if(strcmp(string, "amandad_path")==0) {
4369 return(getconf_str(CNF_AMANDAD_PATH));
4370 } else if(strcmp(string, "client_username")==0) {
4371 return(getconf_str(CNF_CLIENT_USERNAME));
4372 } else if(strcmp(string, "gnutar_list_dir")==0) {
4373 return(getconf_str(CNF_GNUTAR_LIST_DIR));
4374 } else if(strcmp(string, "amandates")==0) {
4375 return(getconf_str(CNF_AMANDATES));
4376 } else if(strcmp(string, "krb5principal")==0) {
4377 return(getconf_str(CNF_KRB5PRINCIPAL));
4378 } else if(strcmp(string, "krb5keytab")==0) {
4379 return(getconf_str(CNF_KRB5KEYTAB));
4385 dump_configuration(void)
4396 if (config_client) {
4397 error(_("Don't know how to dump client configurations."));
4401 g_printf(_("# AMANDA CONFIGURATION FROM FILE \"%s\":\n\n"), config_filename);
4403 for(np=server_var; np->token != CONF_UNKNOWN; np++) {
4404 for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
4405 if (np->token == kt->token) break;
4407 if(kt->token == CONF_UNKNOWN)
4408 error(_("server bad token"));
4410 val_t_print_token(stdout, NULL, "%-21s ", kt, &conf_data[np->parm]);
4413 for(hp = holdinglist; hp != NULL; hp = hp->next) {
4414 g_printf("\nHOLDINGDISK %s {\n", hp->name);
4415 for(i=0; i < HOLDING_HOLDING; i++) {
4416 for(np=holding_var; np->token != CONF_UNKNOWN; np++) {
4420 if(np->token == CONF_UNKNOWN)
4421 error(_("holding bad value"));
4423 for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++) {
4424 if(kt->token == np->token)
4427 if(kt->token == CONF_UNKNOWN)
4428 error(_("holding bad token"));
4430 val_t_print_token(stdout, NULL, " %-9s ", kt, &hp->value[i]);
4435 for(tp = tapelist; tp != NULL; tp = tp->next) {
4440 g_printf("\n%sDEFINE TAPETYPE %s {\n", prefix, tp->name);
4441 for(i=0; i < TAPETYPE_TAPETYPE; i++) {
4442 for(np=tapetype_var; np->token != CONF_UNKNOWN; np++)
4443 if(np->parm == i) break;
4444 if(np->token == CONF_UNKNOWN)
4445 error(_("tapetype bad value"));
4447 for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
4448 if(kt->token == np->token) break;
4449 if(kt->token == CONF_UNKNOWN)
4450 error(_("tapetype bad token"));
4452 val_t_print_token(stdout, prefix, " %-9s ", kt, &tp->value[i]);
4454 g_printf("%s}\n", prefix);
4457 for(dp = dumplist; dp != NULL; dp = dp->next) {
4458 if (strncmp_const(dp->name, "custom(") != 0) { /* don't dump disklist-derived dumptypes */
4463 g_printf("\n%sDEFINE DUMPTYPE %s {\n", prefix, dp->name);
4464 for(i=0; i < DUMPTYPE_DUMPTYPE; i++) {
4465 for(np=dumptype_var; np->token != CONF_UNKNOWN; np++)
4466 if(np->parm == i) break;
4467 if(np->token == CONF_UNKNOWN)
4468 error(_("dumptype bad value"));
4470 for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
4471 if(kt->token == np->token) break;
4472 if(kt->token == CONF_UNKNOWN)
4473 error(_("dumptype bad token"));
4475 val_t_print_token(stdout, prefix, " %-19s ", kt, &dp->value[i]);
4477 g_printf("%s}\n", prefix);
4481 for(ip = interface_list; ip != NULL; ip = ip->next) {
4482 if(strcmp(ip->name,"default") == 0)
4486 g_printf("\n%sDEFINE INTERFACE %s {\n", prefix, ip->name);
4487 for(i=0; i < INTER_INTER; i++) {
4488 for(np=interface_var; np->token != CONF_UNKNOWN; np++)
4489 if(np->parm == i) break;
4490 if(np->token == CONF_UNKNOWN)
4491 error(_("interface bad value"));
4493 for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
4494 if(kt->token == np->token) break;
4495 if(kt->token == CONF_UNKNOWN)
4496 error(_("interface bad token"));
4498 val_t_print_token(stdout, prefix, " %-19s ", kt, &ip->value[i]);
4500 g_printf("%s}\n",prefix);
4513 char **dispstrs, **dispstr;
4514 dispstrs = val_t_display_strs(val, 1);
4516 /* For most configuration types, this outputs
4517 * PREFIX KEYWORD DISPSTR
4518 * for each of the display strings. For identifiers, however, it
4519 * simply prints the first line of the display string.
4522 /* Print the keyword for anything that is not itself an identifier */
4523 if (kt->token != CONF_IDENT) {
4524 for(dispstr=dispstrs; *dispstr!=NULL; dispstr++) {
4526 g_fprintf(output, "%s", prefix);
4527 g_fprintf(output, format, kt->keyword);
4528 g_fprintf(output, "%s\n", *dispstr);
4531 /* for identifiers, assume there's at most one display string */
4532 assert(g_strv_length(dispstrs) <= 1);
4534 g_fprintf(output, "%s\n", *dispstrs);
4538 g_strfreev(dispstrs);
4547 buf = malloc(3*SIZEOF(char *));
4554 buf[0] = vstrallocf("%d", val_t__int(val));
4558 buf[0] = vstrallocf("%zd", (ssize_t)val_t__size(val));
4562 buf[0] = vstrallocf("%lld", (long long)val_t__am64(val));
4566 buf[0] = vstrallocf("%0.5f", val_t__real(val));
4570 buf[0] = vstrallocf("%0.5f %0.5f", val_t__rate(val)[0], val_t__rate(val)[1]);
4573 case CONFTYPE_INTRANGE:
4574 buf[0] = vstrallocf("%d,%d", val_t__intrange(val)[0], val_t__intrange(val)[1]);
4577 case CONFTYPE_IDENT:
4579 buf[0] = stralloc(val->v.s);
4581 buf[0] = stralloc("");
4586 if(str_need_quote) {
4588 buf[0] = vstrallocf("\"%s\"", val->v.s);
4590 buf[0] = stralloc("\"\"");
4594 buf[0] = stralloc(val->v.s);
4596 buf[0] = stralloc("");
4602 buf[0] = vstrallocf("%2d%02d",
4603 (int)val_t__time(val)/100, (int)val_t__time(val) % 100);
4606 case CONFTYPE_EXINCLUDE: {
4607 buf[0] = exinclude_display_str(val, 0);
4608 buf[1] = exinclude_display_str(val, 1);
4612 case CONFTYPE_BOOLEAN:
4613 if(val_t__boolean(val))
4614 buf[0] = stralloc("yes");
4616 buf[0] = stralloc("no");
4619 case CONFTYPE_STRATEGY:
4620 switch(val_t__strategy(val)) {
4622 buf[0] = vstrallocf("SKIP");
4626 buf[0] = vstrallocf("STANDARD");
4630 buf[0] = vstrallocf("NOFULL");
4634 buf[0] = vstrallocf("NOINC");
4638 buf[0] = vstrallocf("HANOI");
4642 buf[0] = vstrallocf("INCRONLY");
4647 case CONFTYPE_COMPRESS:
4648 switch(val_t__compress(val)) {
4650 buf[0] = vstrallocf("NONE");
4654 buf[0] = vstrallocf("CLIENT FAST");
4658 buf[0] = vstrallocf("CLIENT BEST");
4662 buf[0] = vstrallocf("CLIENT CUSTOM");
4665 case COMP_SERVER_FAST:
4666 buf[0] = vstrallocf("SERVER FAST");
4669 case COMP_SERVER_BEST:
4670 buf[0] = vstrallocf("SERVER BEST");
4673 case COMP_SERVER_CUST:
4674 buf[0] = vstrallocf("SERVER CUSTOM");
4679 case CONFTYPE_ESTIMATE:
4680 switch(val_t__estimate(val)) {
4682 buf[0] = vstrallocf("CLIENT");
4686 buf[0] = vstrallocf("SERVER");
4690 buf[0] = vstrallocf("CALCSIZE");
4695 case CONFTYPE_ENCRYPT:
4696 switch(val_t__encrypt(val)) {
4698 buf[0] = vstrallocf("NONE");
4702 buf[0] = vstrallocf("CLIENT");
4705 case ENCRYPT_SERV_CUST:
4706 buf[0] = vstrallocf("SERVER");
4711 case CONFTYPE_HOLDING:
4712 switch(val_t__holding(val)) {
4714 buf[0] = vstrallocf("NEVER");
4718 buf[0] = vstrallocf("AUTO");
4722 buf[0] = vstrallocf("REQUIRED");
4727 case CONFTYPE_TAPERALGO:
4728 buf[0] = vstrallocf("%s", taperalgo2str(val_t__taperalgo(val)));
4731 case CONFTYPE_PRIORITY:
4732 switch(val_t__priority(val)) {
4734 buf[0] = vstrallocf("LOW");
4738 buf[0] = vstrallocf("MEDIUM");
4742 buf[0] = vstrallocf("HIGH");
4747 case CONFTYPE_PROPLIST: {
4751 nb_property = g_hash_table_size(val_t__proplist(val));
4753 buf = malloc((nb_property+1)*SIZEOF(char*));
4754 buf[nb_property] = NULL;
4756 g_hash_table_foreach(val_t__proplist(val), proplist_display_str_foreach_fn, &mybuf);
4764 proplist_display_str_foreach_fn(
4767 gpointer user_data_p)
4769 char *property_s = key_p;
4770 char *value_s = value_p;
4771 char ***msg = (char ***)user_data_p;
4773 **msg = vstralloc("\"", property_s, "\" \"", value_s, "\"", NULL);
4778 exinclude_display_str(
4786 assert(val->type == CONFTYPE_EXINCLUDE);
4788 rval = stralloc("");
4791 sl = val_t__exinclude(val).sl_list;
4792 strappend(rval, "LIST");
4794 sl = val_t__exinclude(val).sl_file;
4795 strappend(rval, "FILE");
4798 if (val_t__exinclude(val).optional == 1) {
4799 strappend(rval, " OPTIONAL");
4803 for(excl = sl->first; excl != NULL; excl = excl->next) {
4804 vstrextend(&rval, " \"", excl->name, "\"", NULL);
4813 taperalgo_t taperalgo)
4815 if(taperalgo == ALGO_FIRST) return "FIRST";
4816 if(taperalgo == ALGO_FIRSTFIT) return "FIRSTFIT";
4817 if(taperalgo == ALGO_LARGEST) return "LARGEST";
4818 if(taperalgo == ALGO_LARGESTFIT) return "LARGESTFIT";
4819 if(taperalgo == ALGO_SMALLEST) return "SMALLEST";
4820 if(taperalgo == ALGO_LAST) return "LAST";
4825 config_dir_relative(
4828 if (*filename == '/' || config_dir == NULL) {
4829 return stralloc(filename);
4831 if (config_dir[strlen(config_dir)-1] == '/') {
4832 return vstralloc(config_dir, filename, NULL);
4834 return vstralloc(config_dir, "/", filename, NULL);
4856 int success = FALSE;
4858 /* WARNING: assumes globals keytable and parsetable are set correctly. */
4859 assert(keytable != NULL);
4860 assert(parsetable != NULL);
4862 /* make a copy we can stomp on */
4863 key = stralloc(key);
4865 /* uppercase the key */
4867 for (s = key; (ch = *s) != 0; s++) {
4868 if(islower((int)ch))
4869 *s = (char)toupper(ch);
4872 subsec_name = strchr(key, ':');
4876 *subsec_name = '\0';
4879 subsec_key = strchr(subsec_name,':');
4880 if(!subsec_key) goto out; /* failure */
4885 /* If the keyword doesn't exist, there's no need to look up the
4886 * subsection -- we know it's invalid */
4887 for(kt = keytable; kt->token != CONF_UNKNOWN; kt++) {
4888 if(kt->keyword && strcmp(kt->keyword, subsec_key) == 0)
4891 if(kt->token == CONF_UNKNOWN) goto out;
4893 /* Otherwise, figure out which kind of subsection we're dealing with,
4894 * and parse against that. */
4895 if (strcmp(subsec_type, "TAPETYPE") == 0) {
4896 tp = lookup_tapetype(subsec_name);
4898 for(np = tapetype_var; np->token != CONF_UNKNOWN; np++) {
4899 if(np->token == kt->token)
4902 if (np->token == CONF_UNKNOWN) goto out;
4904 if (val) *val = &tp->value[np->parm];
4905 if (parm) *parm = np;
4907 } else if (strcmp(subsec_type, "DUMPTYPE") == 0) {
4908 dp = lookup_dumptype(subsec_name);
4910 for(np = dumptype_var; np->token != CONF_UNKNOWN; np++) {
4911 if(np->token == kt->token)
4914 if (np->token == CONF_UNKNOWN) goto out;
4916 if (val) *val = &dp->value[np->parm];
4917 if (parm) *parm = np;
4919 } else if (strcmp(subsec_type, "HOLDINGDISK") == 0) {
4920 hp = lookup_holdingdisk(subsec_name);
4922 for(np = holding_var; np->token != CONF_UNKNOWN; np++) {
4923 if(np->token == kt->token)
4926 if (np->token == CONF_UNKNOWN) goto out;
4928 if (val) *val = &hp->value[np->parm];
4929 if (parm) *parm = np;
4931 } else if (strcmp(subsec_type, "INTERFACE") == 0) {
4932 ip = lookup_interface(subsec_name);
4934 for(np = interface_var; np->token != CONF_UNKNOWN; np++) {
4935 if(np->token == kt->token)
4938 if (np->token == CONF_UNKNOWN) goto out;
4940 if (val) *val = &ip->value[np->parm];
4941 if (parm) *parm = np;
4945 /* No delimiters -- we're referencing a global config parameter */
4947 /* look up the keyword */
4948 for(kt = keytable; kt->token != CONF_UNKNOWN; kt++) {
4949 if(kt->keyword && strcmp(kt->keyword, key) == 0)
4952 if(kt->token == CONF_UNKNOWN) goto out;
4954 /* and then look that up in the parse table */
4955 for(np = parsetable; np->token != CONF_UNKNOWN; np++) {
4956 if(np->token == kt->token)
4959 if(np->token == CONF_UNKNOWN) goto out;
4961 if (val) *val = &conf_data[np->parm];
4962 if (parm) *parm = np;
4975 keytab_t * table_entry;
4976 char * str = g_utf8_strup(casestr, -1);
4984 for (table_entry = numb_keytable; table_entry->keyword != NULL;
4986 if (strcmp(casestr, table_entry->keyword) == 0) {
4988 switch (table_entry->token) {
4994 return 1024*1024*1024;
4997 case CONF_AMINFINITY:
5003 /* Should not happen. */
5009 /* None found; this is an error. */
5015 * Error Handling Implementaiton
5018 static void print_parse_problem(const char * format, va_list argp) {
5019 const char *xlated_fmt = gettext(format);
5022 g_fprintf(stderr, _("argument \"%s\": "), current_line);
5023 else if (current_filename && current_line_num > 0)
5024 g_fprintf(stderr, "\"%s\", line %d: ", current_filename, current_line_num);
5026 g_fprintf(stderr, _("parse error: "));
5028 g_vfprintf(stderr, xlated_fmt, argp);
5029 fputc('\n', stderr);
5032 printf_arglist_function(void conf_parserror, const char *, format)
5036 arglist_start(argp, format);
5037 print_parse_problem(format, argp);
5040 got_parserror = TRUE;
5043 printf_arglist_function(void conf_parswarn, const char *, format) {
5046 arglist_start(argp, format);
5047 print_parse_problem(format, argp);