📄 conffile.c
字号:
/* * Amanda, The Advanced Maryland Automatic Network Disk Archiver * Copyright (c) 1991-2000 University of Maryland at College Park * All Rights Reserved. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of U.M. not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. U.M. makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. * * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M. * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Author: James da Silva, Systems Design and Analysis Group * Computer Science Department * University of Maryland at College Park *//* * $Id: conffile.c,v 1.156 2006/07/26 15:17:37 martinea Exp $ * * read configuration file */#include "amanda.h"#include "arglist.h"#include "util.h"#include "conffile.h"#include "clock.h"/* * Lexical analysis *//* This module implements its own quixotic lexer and parser, present for historical * reasons. If this were written from scratch, it would use flex/bison. *//* An enumeration of the various tokens that might appear in a configuration file. * * - CONF_UNKNOWN has special meaning as an unrecognized token. * - CONF_ANY can be used to request any token, rather than requiring a specific * token. */typedef enum { CONF_UNKNOWN, CONF_ANY, CONF_COMMA, CONF_LBRACE, CONF_RBRACE, CONF_NL, CONF_END, CONF_IDENT, CONF_INT, CONF_AM64, CONF_BOOL, CONF_REAL, CONF_STRING, CONF_TIME, CONF_SIZE, /* config parameters */ CONF_INCLUDEFILE, CONF_ORG, CONF_MAILTO, CONF_DUMPUSER, CONF_TAPECYCLE, CONF_TAPEDEV, CONF_CHANGERDEV, CONF_CHANGERFILE, CONF_LABELSTR, CONF_BUMPPERCENT, CONF_BUMPSIZE, CONF_BUMPDAYS, CONF_BUMPMULT, CONF_ETIMEOUT, CONF_DTIMEOUT, CONF_CTIMEOUT, CONF_TAPEBUFS, CONF_TAPELIST, CONF_DEVICE_OUTPUT_BUFFER_SIZE, CONF_DISKFILE, CONF_INFOFILE, CONF_LOGDIR, CONF_LOGFILE, CONF_DISKDIR, CONF_DISKSIZE, CONF_INDEXDIR, CONF_NETUSAGE, CONF_INPARALLEL, CONF_DUMPORDER, CONF_TIMEOUT, CONF_TPCHANGER, CONF_RUNTAPES, CONF_DEFINE, CONF_DUMPTYPE, CONF_TAPETYPE, CONF_INTERFACE, CONF_PRINTER, CONF_AUTOFLUSH, CONF_RESERVE, CONF_MAXDUMPSIZE, CONF_COLUMNSPEC, CONF_AMRECOVER_DO_FSF, CONF_AMRECOVER_CHECK_LABEL, CONF_AMRECOVER_CHANGER, CONF_LABEL_NEW_TAPES, CONF_USETIMESTAMPS, CONF_TAPERALGO, CONF_FIRST, CONF_FIRSTFIT, CONF_LARGEST, CONF_LARGESTFIT, CONF_SMALLEST, CONF_LAST, CONF_DISPLAYUNIT, CONF_RESERVED_UDP_PORT, CONF_RESERVED_TCP_PORT, CONF_UNRESERVED_TCP_PORT, CONF_TAPERFLUSH, CONF_FLUSH_THRESHOLD_DUMPED, CONF_FLUSH_THRESHOLD_SCHEDULED, CONF_DEVICE_PROPERTY, /* kerberos 5 */ CONF_KRB5KEYTAB, CONF_KRB5PRINCIPAL, /* holding disk */ CONF_COMMENT, CONF_DIRECTORY, CONF_USE, CONF_CHUNKSIZE, /* dump type */ /*COMMENT,*/ CONF_PROGRAM, CONF_DUMPCYCLE, CONF_RUNSPERCYCLE, CONF_MAXCYCLE, CONF_MAXDUMPS, CONF_OPTIONS, CONF_PRIORITY, CONF_FREQUENCY, CONF_INDEX, CONF_MAXPROMOTEDAY, CONF_STARTTIME, CONF_COMPRESS, CONF_ENCRYPT, CONF_AUTH, CONF_STRATEGY, CONF_ESTIMATE, CONF_SKIP_INCR, CONF_SKIP_FULL, CONF_RECORD, CONF_HOLDING, CONF_EXCLUDE, CONF_INCLUDE, CONF_KENCRYPT, CONF_IGNORE, CONF_COMPRATE, CONF_TAPE_SPLITSIZE, CONF_SPLIT_DISKBUFFER, CONF_FALLBACK_SPLITSIZE,CONF_SRVCOMPPROG, CONF_CLNTCOMPPROG, CONF_SRV_ENCRYPT, CONF_CLNT_ENCRYPT, CONF_SRV_DECRYPT_OPT, CONF_CLNT_DECRYPT_OPT, CONF_AMANDAD_PATH, CONF_CLIENT_USERNAME, /* tape type */ /*COMMENT,*/ CONF_BLOCKSIZE, CONF_FILE_PAD, CONF_LBL_TEMPL, CONF_FILEMARK, CONF_LENGTH, CONF_SPEED, CONF_READBLOCKSIZE, /* client conf */ CONF_CONF, CONF_INDEX_SERVER, CONF_TAPE_SERVER, CONF_SSH_KEYS, CONF_GNUTAR_LIST_DIR, CONF_AMANDATES, /* protocol config */ CONF_REP_TRIES, CONF_CONNECT_TRIES, CONF_REQ_TRIES, /* debug config */ CONF_DEBUG_AMANDAD, CONF_DEBUG_AMIDXTAPED, CONF_DEBUG_AMINDEXD, CONF_DEBUG_AMRECOVER, CONF_DEBUG_AUTH, CONF_DEBUG_EVENT, CONF_DEBUG_HOLDING, CONF_DEBUG_PROTOCOL, CONF_DEBUG_PLANNER, CONF_DEBUG_DRIVER, CONF_DEBUG_DUMPER, CONF_DEBUG_CHUNKER, CONF_DEBUG_TAPER, CONF_DEBUG_SELFCHECK, CONF_DEBUG_SENDSIZE, CONF_DEBUG_SENDBACKUP, /* network interface */ /* COMMENT, */ /* USE, */ /* dump options (obsolete) */ CONF_EXCLUDE_FILE, CONF_EXCLUDE_LIST, /* compress, estimate, encryption */ CONF_NONE, CONF_FAST, CONF_BEST, CONF_SERVER, CONF_CLIENT, CONF_CALCSIZE, CONF_CUSTOM, /* holdingdisk */ CONF_NEVER, CONF_AUTO, CONF_REQUIRED, /* priority */ CONF_LOW, CONF_MEDIUM, CONF_HIGH, /* dump strategy */ CONF_SKIP, CONF_STANDARD, CONF_NOFULL, CONF_NOINC, CONF_HANOI, CONF_INCRONLY, /* exclude list */ CONF_LIST, CONF_EFILE, CONF_APPEND, CONF_OPTIONAL, /* numbers */ CONF_AMINFINITY, CONF_MULT1, CONF_MULT7, CONF_MULT1K, CONF_MULT1M, CONF_MULT1G, /* boolean */ CONF_ATRUE, CONF_AFALSE} tok_t;/* A keyword table entry, mapping the given keyword to the given token. * Note that punctuation, integers, and quoted strings are handled * internally to the lexer, so they do not appear here. */typedef struct { char *keyword; tok_t token;} keytab_t;/* The current keyword table, used by all token-related functions */static keytab_t *keytable = NULL;/* Has a token been "ungotten", and if so, what was it? */static int token_pushed;static tok_t pushed_tok;/* The current token and its value. Note that, unlike most other val_t*, * tokenval's v.s points to statically allocated memory which cannot be * free()'d. */static tok_t tok;static val_t tokenval;/* The current input information: file, filename, line, and character * (which points somewhere within current_line) */static FILE *current_file = NULL;static char *current_filename = NULL;static char *current_line = NULL;static char *current_char = NULL;static int current_line_num = 0; /* (technically, managed by the parser) *//* A static buffer for storing tokens while they are being scanned. */static char tkbuf[4096];/* Look up the name of the given token in the current keytable */static char *get_token_name(tok_t);/* Look up a token in keytable, given a string, returning CONF_UNKNOWN * for unrecognized strings. Search is case-insensitive. */static tok_t lookup_keyword(char *str);/* Get the next token. If exp is anything but CONF_ANY, and the next token * does not match, then a parse error is flagged. This function reads from the * current_* static variables, recognizes keywords against the keytable static * variable, and places its result in tok and tokenval. */static void get_conftoken(tok_t exp);/* "Unget" the current token; this supports a 1-token lookahead. */static void unget_conftoken(void);/* Tokenizer character-by-character access. */static int conftoken_getc(void);static int conftoken_ungetc(int c);/* * Parser *//* A parser table entry. Read as "<token> introduces parameter <parm>, * the data for which will be read by <read_function> and validated by * <validate_function> (if not NULL). <type> is only used in formatting * config overwrites. */typedef struct conf_var_s { tok_t token; conftype_t type; void (*read_function) (struct conf_var_s *, val_t*); int parm; void (*validate_function) (struct conf_var_s *, val_t *);} conf_var_t;/* If allow_overwrites is true, the a parameter which has already been * seen will simply overwrite the old value, rather than triggering an * error. Note that this does not apply to all parameters, e.g., * device_property */static int allow_overwrites;/* subsection structs * * The 'seen' fields in these structs are useless outside this module; * they are only used to generate error messages for multiply defined * subsections. */struct tapetype_s { struct tapetype_s *next; int seen; char *name; val_t value[TAPETYPE_TAPETYPE];};struct dumptype_s { struct dumptype_s *next; int seen; char *name; val_t value[DUMPTYPE_DUMPTYPE];};struct interface_s { struct interface_s *next; int seen; char *name; val_t value[INTER_INTER];};struct holdingdisk_s { struct holdingdisk_s *next; int seen; char *name; val_t value[HOLDING_HOLDING];};/* The current parser table */static conf_var_t *parsetable = NULL;/* Read and parse a configuration file, recursively reading any included * files. This function sets the keytable and parsetable appropriately * according to is_client. * * @param filename: configuration file to read * @param is_client: true if this is a client * @returns: false if an error occurred */static gboolean read_conffile(char *filename, gboolean is_client);/* Read and process a line of input from the current file, using the * current keytable and parsetable. For blocks, this recursively * reads the entire block. * * @param is_client: true if this is a client * @returns: true on success, false on EOF or error */static gboolean read_confline(gboolean is_client);/* Handle an invalid token, by issuing a warning or an error, depending * on how long the token has been deprecated. * * @param token: the identifier */static void handle_invalid_keyword(const char * token);/* Read a brace-delimited block using the given parse table. This * function is used to read brace-delimited subsections in the config * files and also (via read_dumptype) to read dumptypes from * the disklist. * * This function implements "inheritance" as follows: if a bare * identifier occurs within the braces, it calls copy_function (if * not NULL), which looks up an existing subsection using the * identifier from tokenval and copies any values not already seen * into valarray. * * @param read_var: the parse table to use * @param valarray: the (pre-initialized) val_t array to fill in * @param errormsg: error message to display for unrecognized keywords * @param read_brace: if true, read the opening brace * @param copy_function: function to copy configuration from * another subsection into this one. */static void read_block(conf_var_t *read_var, val_t *valarray, char *errormsg, int read_brace, void (*copy_function)(void));/* For each subsection type, we have a global and four functions: * - foocur is a temporary struct used to assemble new subsections * - get_foo is called after reading "DEFINE FOO", and * is responsible for reading the entire block, using * read_block() * - init_foo_defaults initializes a new subsection struct * to its default values * - save_foo copies foocur to a newly allocated struct and * inserts that into the relevant list. * - copy_foo implements inheritance as described in read_block() */static holdingdisk_t hdcur;static void get_holdingdisk(void);static void init_holdingdisk_defaults(void);static void save_holdingdisk(void);/* (holdingdisks don't support inheritance) */static dumptype_t dpcur;static void get_dumptype(void);static void init_dumptype_defaults(void);static void save_dumptype(void);static void copy_dumptype(void);static tapetype_t tpcur;static void get_tapetype(void);static void init_tapetype_defaults(void);static void save_tapetype(void);static void copy_tapetype(void);static interface_t ifcur;static void get_interface(void);static void init_interface_defaults(void);static void save_interface(void);static void copy_interface(void);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -