X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=server-src%2Fconffile.c;fp=server-src%2Fconffile.c;h=502287d05ceec8a9f9f156b1e971a5089446b662;hb=12179dea039515c06168c0037d048566a3f623de;hp=f80137263e7113ce14f64f53eeacce33b2efb846;hpb=94c03cae686e4196a345d72452fda2a5203768ce;p=debian%2Famanda diff --git a/server-src/conffile.c b/server-src/conffile.c index f801372..502287d 100644 --- a/server-src/conffile.c +++ b/server-src/conffile.c @@ -25,19 +25,14 @@ * University of Maryland at College Park */ /* - * $Id: conffile.c,v 1.127 2006/03/15 16:26:13 martinea Exp $ + * $Id: conffile.c,v 1.156 2006/07/26 15:17:37 martinea Exp $ * * read configuration file */ -/* - * - * XXX - I'm not happy *at all* with this implementation, but I don't - * think YACC would be any easier. A more table based implementation - * would be better. Also clean up memory leaks. - */ + #include "amanda.h" #include "arglist.h" - +#include "util.h" #include "conffile.h" #include "diskfile.h" #include "driverio.h" @@ -51,91 +46,6 @@ #define INT_MAX 2147483647 #endif -#define BIGINT 1000000000 /* 2 million yrs @ 1 per day */ - -/* internal types and variables */ - -typedef enum { - UNKNOWN, ANY, COMMA, LBRACE, RBRACE, NL, END, - IDENT, INT, LONG, AM64, BOOL, REAL, STRING, TIME, - - /* config parameters */ - INCLUDEFILE, - ORG, MAILTO, DUMPUSER, - TAPECYCLE, TAPEDEV, CHNGRDEV, CHNGRFILE, LABELSTR, - BUMPPERCENT, BUMPSIZE, BUMPDAYS, BUMPMULT, ETIMEOUT, DTIMEOUT, CTIMEOUT, - TAPEBUFS, TAPELIST, DISKFILE, INFOFILE, LOGDIR, LOGFILE, - DISKDIR, DISKSIZE, INDEXDIR, NETUSAGE, INPARALLEL, DUMPORDER, TIMEOUT, - TPCHANGER, RUNTAPES, - DEFINE, DUMPTYPE, TAPETYPE, INTERFACE, - PRINTER, AUTOFLUSH, RESERVE, MAXDUMPSIZE, - COLUMNSPEC, - AMRECOVER_DO_FSF, AMRECOVER_CHECK_LABEL, AMRECOVER_CHANGER, - LABEL_NEW_TAPES, - - TAPERALGO, FIRST, FIRSTFIT, LARGEST, LARGESTFIT, SMALLEST, LAST, - DISPLAYUNIT, - - /* kerberos 5 */ - KRB5KEYTAB, KRB5PRINCIPAL, - - /* holding disk */ - COMMENT, DIRECTORY, USE, CHUNKSIZE, - - /* dump type */ - /*COMMENT,*/ PROGRAM, DUMPCYCLE, RUNSPERCYCLE, MAXCYCLE, MAXDUMPS, - OPTIONS, PRIORITY, FREQUENCY, INDEX, MAXPROMOTEDAY, - STARTTIME, COMPRESS, ENCRYPT, AUTH, STRATEGY, ESTIMATE, - SKIP_INCR, SKIP_FULL, RECORD, HOLDING, - EXCLUDE, INCLUDE, KENCRYPT, IGNORE, COMPRATE, TAPE_SPLITSIZE, - SPLIT_DISKBUFFER, FALLBACK_SPLITSIZE, SRVCOMPPROG, CLNTCOMPPROG, - SRV_ENCRYPT, CLNT_ENCRYPT, SRV_DECRYPT_OPT, CLNT_DECRYPT_OPT, - - /* tape type */ - /*COMMENT,*/ BLOCKSIZE, FILE_PAD, LBL_TEMPL, FILEMARK, LENGTH, SPEED, - - /* network interface */ - /*COMMENT, USE,*/ - - /* dump options (obsolete) */ - EXCLUDE_FILE, EXCLUDE_LIST, - - /* compress, estimate, encryption */ - NONE, FAST, BEST, SERVER, CLIENT, CALCSIZE, CUSTOM, - - /* priority */ - LOW, MEDIUM, HIGH, - - /* dump strategy */ - SKIP, STANDARD, NOFULL, NOINC, HANOI, INCRONLY, - - /* exclude list */ - LIST, EFILE, APPEND, OPTIONAL, - - /* numbers */ - INFINITY, MULT1, MULT7, MULT1K, MULT1M, MULT1G, - - /* boolean */ - ATRUE, AFALSE, - - RAWTAPEDEV -} tok_t; - -typedef struct { /* token table entry */ - char *keyword; - tok_t token; -} keytab_t; - -keytab_t *keytable; - -typedef union { - int i; - long l; - am64_t am64; - double r; - char *s; -} val_t; - /* this corresponds to the normal output of amanda, but may * be adapted to any spacing as you like. */ @@ -143,13 +53,13 @@ ColumnInfo ColumnData[] = { { "HostName", 0, 12, 12, 0, "%-*.*s", "HOSTNAME" }, { "Disk", 1, 11, 11, 0, "%-*.*s", "DISK" }, { "Level", 1, 1, 1, 0, "%*.*d", "L" }, - { "OrigKB", 1, 7, 0, 0, "%*.*f", "ORIG-KB" }, - { "OutKB", 1, 7, 0, 0, "%*.*f", "OUT-KB" }, - { "Compress", 1, 6, 1, 0, "%*.*f", "COMP%" }, + { "OrigKB", 1, 7, 0, 0, "%*.*lf", "ORIG-KB" }, + { "OutKB", 1, 7, 0, 0, "%*.*lf", "OUT-KB" }, + { "Compress", 1, 6, 1, 0, "%*.*lf", "COMP%" }, { "DumpTime", 1, 7, 7, 0, "%*.*s", "MMM:SS" }, - { "DumpRate", 1, 6, 1, 0, "%*.*f", "KB/s" }, + { "DumpRate", 1, 6, 1, 0, "%*.*lf", "KB/s" }, { "TapeTime", 1, 6, 6, 0, "%*.*s", "MMM:SS" }, - { "TapeRate", 1, 6, 1, 0, "%*.*f", "KB/s" }, + { "TapeRate", 1, 6, 1, 0, "%*.*lf", "KB/s" }, { NULL, 0, 0, 0, 0, NULL, NULL } }; @@ -165,59 +75,9 @@ long int unit_divisor = 1; /* configuration parameters */ -/* strings */ -static val_t conf_org; -static val_t conf_mailto; -static val_t conf_dumpuser; -static val_t conf_printer; -static val_t conf_tapedev; -static val_t conf_rawtapedev; -static val_t conf_tpchanger; -static val_t conf_chngrdev; -static val_t conf_chngrfile; -static val_t conf_labelstr; -static val_t conf_tapelist; -static val_t conf_infofile; -static val_t conf_logdir; -static val_t conf_diskfile; -static val_t conf_diskdir; -static val_t conf_tapetype; -static val_t conf_indexdir; -static val_t conf_columnspec; -static val_t conf_dumporder; -static val_t conf_amrecover_changer; - -/* ints */ -static val_t conf_dumpcycle; -static val_t conf_runspercycle; -static val_t conf_maxcycle; -static val_t conf_tapecycle; -static val_t conf_runtapes; -static val_t conf_disksize; -static val_t conf_netusage; -static val_t conf_inparallel; -static val_t conf_timeout; -static val_t conf_maxdumps; -static val_t conf_bumppercent; -static val_t conf_bumpsize; -static val_t conf_bumpdays; -static val_t conf_etimeout; -static val_t conf_dtimeout; -static val_t conf_ctimeout; -static val_t conf_tapebufs; -static val_t conf_autoflush; -static val_t conf_reserve; -static val_t conf_maxdumpsize; -static val_t conf_amrecover_do_fsf; -static val_t conf_amrecover_check_label; -static val_t conf_taperalgo; -static val_t conf_displayunit; -static val_t conf_krb5keytab; -static val_t conf_krb5principal; -static val_t conf_label_new_tapes; - -/* reals */ -static val_t conf_bumpmult; +val_t server_conf[CNF_CNF]; + +command_option_t *server_options = NULL; /* other internal variables */ static holdingdisk_t hdcur; @@ -228,150 +88,272 @@ static dumptype_t dpcur; static interface_t ifcur; -static int seen_org; -static int seen_mailto; -static int seen_dumpuser; -static int seen_rawtapedev; -static int seen_printer; -static int seen_tapedev; -static int seen_tpchanger; -static int seen_chngrdev; -static int seen_chngrfile; -static int seen_labelstr; -static int seen_runtapes; -static int seen_maxdumps; -static int seen_tapelist; -static int seen_infofile; -static int seen_diskfile; -static int seen_diskdir; -static int seen_logdir; -static int seen_bumppercent; -static int seen_bumpsize; -static int seen_bumpmult; -static int seen_bumpdays; -static int seen_tapetype; -static int seen_dumpcycle; -static int seen_runspercycle; -static int seen_maxcycle; -static int seen_tapecycle; -static int seen_disksize; -static int seen_netusage; -static int seen_inparallel; -static int seen_dumporder; -static int seen_timeout; -static int seen_indexdir; -static int seen_etimeout; -static int seen_dtimeout; -static int seen_ctimeout; -static int seen_tapebufs; -static int seen_autoflush; -static int seen_reserve; -static int seen_maxdumpsize; -static int seen_columnspec; -static int seen_amrecover_do_fsf; -static int seen_amrecover_check_label; -static int seen_amrecover_changer; -static int seen_taperalgo; -static int seen_displayunit; -static int seen_krb5keytab; -static int seen_krb5principal; -static int seen_label_new_tapes; - -static int allow_overwrites; -static int token_pushed; - -static tok_t tok, pushed_tok; -static val_t tokenval; - -static int line_num, got_parserror; static dumptype_t *dumplist = NULL; static tapetype_t *tapelist = NULL; static interface_t *interface_list = NULL; -static FILE *conf = (FILE *)NULL; -static char *confname = NULL; /* predeclare local functions */ -static void init_defaults P((void)); -static void read_conffile_recursively P((char *filename)); - -static int read_confline P((void)); -static void get_holdingdisk P((void)); -static void init_holdingdisk_defaults P((void)); -static void save_holdingdisk P((void)); -static void get_dumptype P((void)); -static void init_dumptype_defaults P((void)); -static void save_dumptype P((void)); -static void copy_dumptype P((void)); -static void get_tapetype P((void)); -static void init_tapetype_defaults P((void)); -static void save_tapetype P((void)); -static void copy_tapetype P((void)); -static void get_interface P((void)); -static void init_interface_defaults P((void)); -static void save_interface P((void)); -static void copy_interface P((void)); -static void get_dumpopts P((void)); -static void get_comprate P((void)); -static void get_compress P((void)); -static void get_encrypt P((void)); -static void get_priority P((void)); -static void get_strategy P((void)); -static void get_estimate P((void)); -static void get_exclude P((void)); -static void get_include P((void)); -static void get_taperalgo P((val_t *c_taperalgo, int *s_taperalgo)); - -static void get_simple P((val_t *var, int *seen, tok_t type)); -static int get_time P((void)); -static int get_int P((void)); -static long get_long P((void)); -static am64_t get_am64_t P((void)); -static int get_bool P((void)); -static void ckseen P((int *seen)); -static void parserror P((char *format, ...)) - __attribute__ ((format (printf, 1, 2))); -static tok_t lookup_keyword P((char *str)); -static void unget_conftoken P((void)); -static void get_conftoken P((tok_t exp)); +char *get_token_name(tok_t); + + +void validate_positive0 (t_conf_var *, val_t *); +void validate_positive1 (t_conf_var *, val_t *); +void validate_runspercycle(t_conf_var *, val_t *); +void validate_bumppercent (t_conf_var *, val_t *); +void validate_bumpmult (t_conf_var *, val_t *); +void validate_inparallel (t_conf_var *, val_t *); +void validate_displayunit (t_conf_var *, val_t *); +void validate_reserve (t_conf_var *, val_t *); +void validate_use (t_conf_var *, val_t *); +void validate_chunksize (t_conf_var *, val_t *); +void validate_blocksize (t_conf_var *, val_t *); + +static void init_defaults(void); +static void read_conffile_recursively(char *filename); + +static int read_confline(void); +static void get_holdingdisk(void); +static void init_holdingdisk_defaults(void); +static void save_holdingdisk(void); +static void get_dumptype(void); +static void init_dumptype_defaults(void); +static void save_dumptype(void); +static void copy_dumptype(void); +static void get_tapetype(void); +static void init_tapetype_defaults(void); +static void save_tapetype(void); +static void copy_tapetype(void); +static void get_interface(void); +static void init_interface_defaults(void); +static void save_interface(void); +static void copy_interface(void); +static void get_comprate(t_conf_var *, val_t *); +static void get_compress(t_conf_var *, val_t *); +static void get_encrypt (t_conf_var *, val_t *); +static void get_holding (t_conf_var *, val_t *); +static void get_priority(t_conf_var *, val_t *); +static void get_strategy(t_conf_var *, val_t *); +static void get_estimate(t_conf_var *, val_t *); +static void get_exclude (t_conf_var *, val_t *); +/*static void get_include(t_conf_var *, val_t *);*/ +static void get_taperalgo(t_conf_var *, val_t *); + +keytab_t server_keytab[] = { + { "AMANDAD_PATH", CONF_AMANDAD_PATH }, + { "AMRECOVER_CHANGER", CONF_AMRECOVER_CHANGER }, + { "AMRECOVER_CHECK_LABEL", CONF_AMRECOVER_CHECK_LABEL }, + { "AMRECOVER_DO_FSF", CONF_AMRECOVER_DO_FSF }, + { "APPEND", CONF_APPEND }, + { "AUTH", CONF_AUTH }, + { "AUTO", CONF_AUTO }, + { "AUTOFLUSH", CONF_AUTOFLUSH }, + { "BEST", CONF_BEST }, + { "BLOCKSIZE", CONF_BLOCKSIZE }, + { "BUMPDAYS", CONF_BUMPDAYS }, + { "BUMPMULT", CONF_BUMPMULT }, + { "BUMPPERCENT", CONF_BUMPPERCENT }, + { "BUMPSIZE", CONF_BUMPSIZE }, + { "CALCSIZE", CONF_CALCSIZE }, + { "CHANGERDEV", CONF_CHNGRDEV }, + { "CHANGERFILE", CONF_CHNGRFILE }, + { "CHUNKSIZE", CONF_CHUNKSIZE }, + { "CLIENT", CONF_CLIENT }, + { "CLIENT_CUSTOM_COMPRESS", CONF_CLNTCOMPPROG }, + { "CLIENT_DECRYPT_OPTION", CONF_CLNT_DECRYPT_OPT }, + { "CLIENT_ENCRYPT", CONF_CLNT_ENCRYPT }, + { "CLIENT_USERNAME", CONF_CLIENT_USERNAME }, + { "COLUMNSPEC", CONF_COLUMNSPEC }, + { "COMMENT", CONF_COMMENT }, + { "COMPRATE", CONF_COMPRATE }, + { "COMPRESS", CONF_COMPRESS }, + { "CTIMEOUT", CONF_CTIMEOUT }, + { "CUSTOM", CONF_CUSTOM }, + { "DEFINE", CONF_DEFINE }, + { "DIRECTORY", CONF_DIRECTORY }, + { "DISKFILE", CONF_DISKFILE }, + { "DISPLAYUNIT", CONF_DISPLAYUNIT }, + { "DTIMEOUT", CONF_DTIMEOUT }, + { "DUMPCYCLE", CONF_DUMPCYCLE }, + { "DUMPORDER", CONF_DUMPORDER }, + { "DUMPTYPE", CONF_DUMPTYPE }, + { "DUMPUSER", CONF_DUMPUSER }, + { "ENCRYPT", CONF_ENCRYPT }, + { "ESTIMATE", CONF_ESTIMATE }, + { "ETIMEOUT", CONF_ETIMEOUT }, + { "EXCLUDE", CONF_EXCLUDE }, + { "EXCLUDE-FILE", CONF_EXCLUDE_FILE }, + { "EXCLUDE-LIST", CONF_EXCLUDE_LIST }, + { "FALLBACK_SPLITSIZE", CONF_FALLBACK_SPLITSIZE }, + { "FAST", CONF_FAST }, + { "FILE", CONF_EFILE }, + { "FILE-PAD", CONF_FILE_PAD }, + { "FILEMARK", CONF_FILEMARK }, + { "FIRST", CONF_FIRST }, + { "FIRSTFIT", CONF_FIRSTFIT }, + { "HANOI", CONF_HANOI }, + { "HIGH", CONF_HIGH }, + { "HOLDINGDISK", CONF_HOLDING }, + { "IGNORE", CONF_IGNORE }, + { "INCLUDE", CONF_INCLUDE }, + { "INCLUDEFILE", CONF_INCLUDEFILE }, + { "INCRONLY", CONF_INCRONLY }, + { "INDEX", CONF_INDEX }, + { "INDEXDIR", CONF_INDEXDIR }, + { "INFOFILE", CONF_INFOFILE }, + { "INPARALLEL", CONF_INPARALLEL }, + { "INTERFACE", CONF_INTERFACE }, + { "KENCRYPT", CONF_KENCRYPT }, + { "KRB5KEYTAB", CONF_KRB5KEYTAB }, + { "KRB5PRINCIPAL", CONF_KRB5PRINCIPAL }, + { "LABELSTR", CONF_LABELSTR }, + { "LABEL_NEW_TAPES", CONF_LABEL_NEW_TAPES }, + { "LARGEST", CONF_LARGEST }, + { "LARGESTFIT", CONF_LARGESTFIT }, + { "LAST", CONF_LAST }, + { "LBL-TEMPL", CONF_LBL_TEMPL }, + { "LENGTH", CONF_LENGTH }, + { "LIST", CONF_LIST }, + { "LOGDIR", CONF_LOGDIR }, + { "LOW", CONF_LOW }, + { "MAILTO", CONF_MAILTO }, + { "MAXDUMPS", CONF_MAXDUMPS }, + { "MAXDUMPSIZE", CONF_MAXDUMPSIZE }, + { "MAXPROMOTEDAY", CONF_MAXPROMOTEDAY }, + { "MEDIUM", CONF_MEDIUM }, + { "NETUSAGE", CONF_NETUSAGE }, /* XXX - historical */ + { "NEVER", CONF_NEVER }, + { "NOFULL", CONF_NOFULL }, + { "NOINC", CONF_NOINC }, + { "NONE", CONF_NONE }, + { "OPTIONAL", CONF_OPTIONAL }, + { "ORG", CONF_ORG }, + { "PRINTER", CONF_PRINTER }, + { "PRIORITY", CONF_PRIORITY }, + { "PROGRAM", CONF_PROGRAM }, + { "RAWTAPEDEV", CONF_RAWTAPEDEV }, + { "RECORD", CONF_RECORD }, + { "REQUIRED", CONF_REQUIRED }, + { "RESERVE", CONF_RESERVE }, + { "RUNSPERCYCLE", CONF_RUNSPERCYCLE }, + { "RUNTAPES", CONF_RUNTAPES }, + { "SERVER", CONF_SERVER }, + { "SERVER_CUSTOM_COMPRESS", CONF_SRVCOMPPROG }, + { "SERVER_DECRYPT_OPTION", CONF_SRV_DECRYPT_OPT }, + { "SERVER_ENCRYPT", CONF_SRV_ENCRYPT }, + { "SKIP", CONF_SKIP }, + { "SKIP-FULL", CONF_SKIP_FULL }, + { "SKIP-INCR", CONF_SKIP_INCR }, + { "SMALLEST", CONF_SMALLEST }, + { "SPEED", CONF_SPEED }, + { "SPLIT_DISKBUFFER", CONF_SPLIT_DISKBUFFER }, + { "SSH_KEYS", CONF_SSH_KEYS }, + { "STANDARD", CONF_STANDARD }, + { "STARTTIME", CONF_STARTTIME }, + { "STRATEGY", CONF_STRATEGY }, + { "TAPEBUFS", CONF_TAPEBUFS }, + { "TAPECYCLE", CONF_TAPECYCLE }, + { "TAPEDEV", CONF_TAPEDEV }, + { "TAPELIST", CONF_TAPELIST }, + { "TAPERALGO", CONF_TAPERALGO }, + { "TAPETYPE", CONF_TAPETYPE }, + { "TAPE_SPLITSIZE", CONF_TAPE_SPLITSIZE }, + { "TPCHANGER", CONF_TPCHANGER }, + { "USE", CONF_USE }, + { "USETIMESTAMPS", CONF_USETIMESTAMPS }, + { NULL, CONF_IDENT }, + { NULL, CONF_UNKNOWN } +}; +t_conf_var server_var [] = { + { CONF_ORG , CONFTYPE_STRING , read_string , CNF_ORG , NULL }, + { CONF_MAILTO , CONFTYPE_STRING , read_string , CNF_MAILTO , NULL }, + { CONF_DUMPUSER , CONFTYPE_STRING , read_string , CNF_DUMPUSER , NULL }, + { CONF_PRINTER , CONFTYPE_STRING , read_string , CNF_PRINTER , NULL }, + { CONF_TAPEDEV , CONFTYPE_STRING , read_string , CNF_TAPEDEV , NULL }, + { CONF_TPCHANGER , CONFTYPE_STRING , read_string , CNF_TPCHANGER , NULL }, + { CONF_CHNGRDEV , CONFTYPE_STRING , read_string , CNF_CHNGRDEV , NULL }, + { CONF_CHNGRFILE , CONFTYPE_STRING , read_string , CNF_CHNGRFILE , NULL }, + { CONF_LABELSTR , CONFTYPE_STRING , read_string , CNF_LABELSTR , NULL }, + { CONF_TAPELIST , CONFTYPE_STRING , read_string , CNF_TAPELIST , NULL }, + { CONF_DISKFILE , CONFTYPE_STRING , read_string , CNF_DISKFILE , NULL }, + { CONF_INFOFILE , CONFTYPE_STRING , read_string , CNF_INFOFILE , NULL }, + { CONF_LOGDIR , CONFTYPE_STRING , read_string , CNF_LOGDIR , NULL }, + { CONF_INDEXDIR , CONFTYPE_STRING , read_string , CNF_INDEXDIR , NULL }, + { CONF_TAPETYPE , CONFTYPE_IDENT , read_ident , CNF_TAPETYPE , NULL }, + { CONF_DUMPCYCLE , CONFTYPE_INT , read_int , CNF_DUMPCYCLE , validate_positive0 }, + { CONF_RUNSPERCYCLE , CONFTYPE_INT , read_int , CNF_RUNSPERCYCLE , validate_runspercycle }, + { CONF_RUNTAPES , CONFTYPE_INT , read_int , CNF_RUNTAPES , validate_positive0 }, + { CONF_TAPECYCLE , CONFTYPE_INT , read_int , CNF_TAPECYCLE , validate_positive1 }, + { CONF_BUMPDAYS , CONFTYPE_INT , read_int , CNF_BUMPDAYS , validate_positive1 }, + { CONF_BUMPSIZE , CONFTYPE_AM64 , read_am64 , CNF_BUMPSIZE , validate_positive1 }, + { CONF_BUMPPERCENT , CONFTYPE_INT , read_int , CNF_BUMPPERCENT , validate_bumppercent }, + { CONF_BUMPMULT , CONFTYPE_REAL , read_real , CNF_BUMPMULT , validate_bumpmult }, + { CONF_NETUSAGE , CONFTYPE_INT , read_int , CNF_NETUSAGE , validate_positive1 }, + { CONF_INPARALLEL , CONFTYPE_INT , read_int , CNF_INPARALLEL , validate_inparallel }, + { CONF_DUMPORDER , CONFTYPE_STRING , read_string , CNF_DUMPORDER , NULL }, + { CONF_MAXDUMPS , CONFTYPE_INT , read_int , CNF_MAXDUMPS , validate_positive1 }, + { CONF_ETIMEOUT , CONFTYPE_TIME , read_time , CNF_ETIMEOUT , NULL }, + { CONF_DTIMEOUT , CONFTYPE_TIME , read_time , CNF_DTIMEOUT , validate_positive1 }, + { CONF_CTIMEOUT , CONFTYPE_TIME , read_time , CNF_CTIMEOUT , validate_positive1 }, + { CONF_TAPEBUFS , CONFTYPE_INT , read_int , CNF_TAPEBUFS , validate_positive1 }, + { CONF_RAWTAPEDEV , CONFTYPE_STRING , read_string , CNF_RAWTAPEDEV , NULL }, + { CONF_COLUMNSPEC , CONFTYPE_STRING , read_string , CNF_COLUMNSPEC , NULL }, + { CONF_TAPERALGO , CONFTYPE_TAPERALGO, get_taperalgo, CNF_TAPERALGO , NULL }, + { CONF_DISPLAYUNIT , CONFTYPE_STRING , read_string , CNF_DISPLAYUNIT , validate_displayunit }, + { CONF_AUTOFLUSH , CONFTYPE_BOOL , read_bool , CNF_AUTOFLUSH , NULL }, + { CONF_RESERVE , CONFTYPE_INT , read_int , CNF_RESERVE , validate_reserve }, + { CONF_MAXDUMPSIZE , CONFTYPE_AM64 , read_am64 , CNF_MAXDUMPSIZE , NULL }, + { CONF_KRB5KEYTAB , CONFTYPE_STRING , read_string , CNF_KRB5KEYTAB , NULL }, + { CONF_KRB5PRINCIPAL , CONFTYPE_STRING , read_string , CNF_KRB5PRINCIPAL , NULL }, + { CONF_LABEL_NEW_TAPES , CONFTYPE_STRING , read_string , CNF_LABEL_NEW_TAPES , NULL }, + { CONF_USETIMESTAMPS , CONFTYPE_BOOL , read_bool , CNF_USETIMESTAMPS , NULL }, + { CONF_AMRECOVER_DO_FSF , CONFTYPE_BOOL , read_bool , CNF_AMRECOVER_DO_FSF , NULL }, + { CONF_AMRECOVER_CHANGER , CONFTYPE_STRING , read_string , CNF_AMRECOVER_CHANGER , NULL }, + { CONF_AMRECOVER_CHECK_LABEL, CONFTYPE_BOOL , read_bool , CNF_AMRECOVER_CHECK_LABEL, NULL }, + { CONF_UNKNOWN , CONFTYPE_INT , NULL , CNF_CNF , NULL } +}; /* ** ------------------------ ** External entry points ** ------------------------ */ -int read_conffile(filename) -char *filename; +int +read_conffile( + char *filename) { interface_t *ip; init_defaults(); - /* We assume that confname & conf are initialized to NULL above */ + /* We assume that conf_confname & conf are initialized to NULL above */ read_conffile_recursively(filename); + /* overwrite with command line option */ + command_overwrite(server_options, server_var, server_keytab, server_conf, + ""); + if(got_parserror != -1 ) { - if(lookup_tapetype(conf_tapetype.s) == NULL) { - char *save_confname = confname; + if(lookup_tapetype(server_conf[CNF_TAPETYPE].v.s) == NULL) { + char *save_confname = conf_confname; - confname = filename; - if(!seen_tapetype) - parserror("default tapetype %s not defined", conf_tapetype.s); + conf_confname = filename; + if(!server_conf[CNF_TAPETYPE].seen) + conf_parserror("default tapetype %s not defined", server_conf[CNF_TAPETYPE].v.s); else { - line_num = seen_tapetype; - parserror("tapetype %s not defined", conf_tapetype.s); + conf_line_num = server_conf[CNF_TAPETYPE].seen; + conf_parserror("tapetype %s not defined", server_conf[CNF_TAPETYPE].v.s); } - confname = save_confname; + conf_confname = save_confname; } } - ip = alloc(sizeof(interface_t)); - malloc_mark(ip); - ip->name = ""; - ip->seen = seen_netusage; - ip->comment = "implicit from NETUSAGE"; - ip->maxusage = conf_netusage.i; + ip = alloc(SIZEOF(interface_t)); + ip->name = stralloc("default"); + ip->seen = server_conf[CNF_NETUSAGE].seen; + conf_init_string(&ip->value[INTER_COMMENT], "implicit from NETUSAGE"); + conf_init_int(&ip->value[INTER_MAXUSAGE], server_conf[CNF_NETUSAGE].v.i); ip->curusage = 0; ip->next = interface_list; interface_list = ip; @@ -379,95 +361,225 @@ char *filename; return got_parserror; } -struct byname { - char *name; - confparm_t parm; - tok_t typ; -} byname_table [] = { - { "ORG", CNF_ORG, STRING }, - { "MAILTO", CNF_MAILTO, STRING }, - { "DUMPUSER", CNF_DUMPUSER, STRING }, - { "PRINTER", CNF_PRINTER, STRING }, - { "TAPEDEV", CNF_TAPEDEV, STRING }, - { "TPCHANGER", CNF_TPCHANGER, STRING }, - { "CHANGERDEV", CNF_CHNGRDEV, STRING }, - { "CHANGERFILE", CNF_CHNGRFILE, STRING }, - { "LABELSTR", CNF_LABELSTR, STRING }, - { "TAPELIST", CNF_TAPELIST, STRING }, - { "DISKFILE", CNF_DISKFILE, STRING }, - { "INFOFILE", CNF_INFOFILE, STRING }, - { "LOGDIR", CNF_LOGDIR, STRING }, - /*{ "LOGFILE", CNF_LOGFILE, STRING },*/ - /*{ "DISKDIR", CNF_DISKDIR, STRING },*/ - { "INDEXDIR", CNF_INDEXDIR, STRING }, - { "TAPETYPE", CNF_TAPETYPE, STRING }, - { "DUMPCYCLE", CNF_DUMPCYCLE, INT }, - { "RUNSPERCYCLE", CNF_RUNSPERCYCLE, INT }, - { "MINCYCLE", CNF_DUMPCYCLE, INT }, - { "RUNTAPES", CNF_RUNTAPES, INT }, - { "TAPECYCLE", CNF_TAPECYCLE, INT }, - /*{ "DISKSIZE", CNF_DISKSIZE, INT },*/ - { "BUMPDAYS", CNF_BUMPDAYS, INT }, - { "BUMPSIZE", CNF_BUMPSIZE, INT }, - { "BUMPPERCENT", CNF_BUMPPERCENT, INT }, - { "BUMPMULT", CNF_BUMPMULT, REAL }, - { "NETUSAGE", CNF_NETUSAGE, INT }, - { "INPARALLEL", CNF_INPARALLEL, INT }, - { "DUMPORDER", CNF_DUMPORDER, STRING }, - /*{ "TIMEOUT", CNF_TIMEOUT, INT },*/ - { "MAXDUMPS", CNF_MAXDUMPS, INT }, - { "ETIMEOUT", CNF_ETIMEOUT, INT }, - { "DTIMEOUT", CNF_DTIMEOUT, INT }, - { "CTIMEOUT", CNF_CTIMEOUT, INT }, - { "TAPEBUFS", CNF_TAPEBUFS, INT }, - { "RAWTAPEDEV", CNF_RAWTAPEDEV, STRING }, - { "COLUMNSPEC", CNF_COLUMNSPEC, STRING }, - { "AMRECOVER_DO_FSF", CNF_AMRECOVER_DO_FSF, BOOL }, - { "AMRECOVER_CHECK_LABEL", CNF_AMRECOVER_CHECK_LABEL, BOOL }, - { "AMRECOVER_CHANGER", CNF_AMRECOVER_CHANGER, STRING }, - { "TAPERALGO", CNF_TAPERALGO, INT }, - { "DISPLAYUNIT", CNF_DISPLAYUNIT, STRING }, - { "AUTOFLUSH", CNF_AUTOFLUSH, BOOL }, - { "RESERVE", CNF_RESERVE, INT }, - { "MAXDUMPSIZE", CNF_MAXDUMPSIZE, AM64 }, - { "KRB5KEYTAB", CNF_KRB5KEYTAB, STRING }, - { "KRB5PRINCIPAL", CNF_KRB5PRINCIPAL, STRING }, - { "LABEL_NEW_TAPES", CNF_LABEL_NEW_TAPES, STRING }, - { NULL } -}; +void +validate_positive0( + struct s_conf_var *np, + val_t *val) +{ + switch(val->type) { + case CONFTYPE_INT: + if(val->v.i < 0) + conf_parserror("%s must be positive", get_token_name(np->token)); + break; + case CONFTYPE_LONG: + if(val->v.l < 0) + conf_parserror("%s must be positive", get_token_name(np->token)); + break; + case CONFTYPE_AM64: + if(val->v.am64 < 0) + conf_parserror("%s must be positive", get_token_name(np->token)); + break; + default: + conf_parserror("validate_positive0 invalid type %d\n", val->type); + } +} + +void +validate_positive1( + struct s_conf_var *np, + val_t *val) +{ + switch(val->type) { + case CONFTYPE_INT: + if(val->v.i < 1) + conf_parserror("%s must be positive", get_token_name(np->token)); + break; + case CONFTYPE_LONG: + if(val->v.l < 1) + conf_parserror("%s must be positive", get_token_name(np->token)); + break; + case CONFTYPE_AM64: + if(val->v.am64 < 1) + conf_parserror("%s must be positive", get_token_name(np->token)); + break; + case CONFTYPE_TIME: + if(val->v.t < 1) + conf_parserror("%s must be positive", get_token_name(np->token)); + break; + default: + conf_parserror("validate_positive1 invalid type %d\n", val->type); + } +} + +void +validate_runspercycle( + struct s_conf_var *np, + val_t *val) +{ + np = np; + if(val->v.i < -1) + conf_parserror("runspercycle must be >= -1"); +} + +void +validate_bumppercent( + struct s_conf_var *np, + val_t *val) +{ + np = np; + if(val->v.i < 0 || val->v.i > 100) + conf_parserror("bumppercent must be between 0 and 100"); +} + +void +validate_inparallel( + struct s_conf_var *np, + val_t *val) +{ + np = np; + if(val->v.i < 1 || val->v.i >MAX_DUMPERS) + conf_parserror("inparallel must be between 1 and MAX_DUMPERS (%d)", + MAX_DUMPERS); +} + +void +validate_bumpmult( + struct s_conf_var *np, + val_t *val) +{ + np = np; + if(val->v.r < 0.999) { + conf_parserror("bumpmult must be positive"); + } +} + +void +validate_displayunit( + struct s_conf_var *np, + val_t *val) +{ + np = np; + if(strcmp(val->v.s, "k") == 0 || + strcmp(val->v.s, "K") == 0) { + val->v.s[0] = (char)toupper(val->v.s[0]); + unit_divisor=1; + } + else if(strcmp(val->v.s, "m") == 0 || + strcmp(val->v.s, "M") == 0) { + val->v.s[0] = (char)toupper(val->v.s[0]); + unit_divisor=1024; + } + else if(strcmp(val->v.s, "g") == 0 || + strcmp(val->v.s, "G") == 0) { + val->v.s[0] = (char)toupper(val->v.s[0]); + unit_divisor=1024*1024; + } + else if(strcmp(val->v.s, "t") == 0 || + strcmp(val->v.s, "T") == 0) { + val->v.s[0] = (char)toupper(val->v.s[0]); + unit_divisor=1024*1024*1024; + } + else { + conf_parserror("displayunit must be k,m,g or t."); + } +} + +void +validate_reserve( + struct s_conf_var *np, + val_t *val) +{ + np = np; + if(val->v.i < 0 || val->v.i > 100) + conf_parserror("reserve must be between 0 and 100"); +} + +void +validate_use( + struct s_conf_var *np, + val_t *val) +{ + np = np; + val->v.am64 = am_floor(val->v.am64, DISK_BLOCK_KB); +} + +void +validate_chunksize( + struct s_conf_var *np, + val_t *val) +{ + np = np; + if(val->v.am64 == 0) { + val->v.am64 = ((AM64_MAX / 1024) - (2 * DISK_BLOCK_KB)); + } + else if(val->v.am64 < 0) { + conf_parserror("Negative chunksize (%lld) is no longer supported", val->v.am64); + } + val->v.am64 = am_floor(val->v.am64, (off_t)DISK_BLOCK_KB); +} + +void +validate_blocksize( + struct s_conf_var *np, + val_t *val) +{ + np = np; + if(val->v.l < DISK_BLOCK_KB) { + conf_parserror("Tape blocksize must be at least %d KBytes", + DISK_BLOCK_KB); + } else if(val->v.l > MAX_TAPE_BLOCK_KB) { + conf_parserror("Tape blocksize must not be larger than %d KBytes", + MAX_TAPE_BLOCK_KB); + } +} -char *getconf_byname(str) -char *str; +char * +getconf_byname( + char *str) { static char *tmpstr; char number[NUM_STR_SIZE]; - struct byname *np; + t_conf_var *np; + keytab_t *kt; char *s; char ch; tmpstr = stralloc(str); s = tmpstr; while((ch = *s++) != '\0') { - if(islower((int)ch)) s[-1] = toupper(ch); + if(islower((int)ch)) + s[-1] = (char)toupper(ch); + } + for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++) { + if(kt->keyword && strcmp(kt->keyword, tmpstr) == 0) + break; } - for(np = byname_table; np->name != NULL; np++) - if(strcmp(np->name, tmpstr) == 0) break; + if(kt->token == CONF_UNKNOWN) + return NULL; + + for(np = server_var; np->token != CONF_UNKNOWN; np++) { + if(np->token == kt->token) + break; + } - if(np->name == NULL) return NULL; + if(np->token == CONF_UNKNOWN) return NULL; - if(np->typ == INT) { - snprintf(number, sizeof(number), "%d", getconf_int(np->parm)); + if(np->type == CONFTYPE_INT) { + snprintf(number, sizeof(number), "%d", server_conf[np->parm].v.i); tmpstr = newstralloc(tmpstr, number); - } else if(np->typ == BOOL) { - if(getconf_int(np->parm) == 0) { + } else if(np->type == CONFTYPE_BOOL) { + if(getconf_boolean(np->parm) == 0) { tmpstr = newstralloc(tmpstr, "off"); - } - else { + } else { tmpstr = newstralloc(tmpstr, "on"); } - } else if(np->typ == REAL) { - snprintf(number, sizeof(number), "%f", getconf_real(np->parm)); + } else if(np->type == CONFTYPE_REAL) { + snprintf(number, sizeof(number), "%lf", server_conf[np->parm].v.r); + tmpstr = newstralloc(tmpstr, number); + } else if(np->type == CONFTYPE_AM64){ + snprintf(number, sizeof(number), OFF_T_FMT, + (OFF_T_FMT_TYPE)server_conf[np->parm].v.am64); tmpstr = newstralloc(tmpstr, number); } else { tmpstr = newstralloc(tmpstr, getconf_str(np->parm)); @@ -476,205 +588,180 @@ char *str; return tmpstr; } -int getconf_seen(parm) -confparm_t parm; -{ - switch(parm) { - case CNF_ORG: return seen_org; - case CNF_MAILTO: return seen_mailto; - case CNF_DUMPUSER: return seen_dumpuser; - case CNF_PRINTER: return seen_printer; - case CNF_TAPEDEV: return seen_tapedev; - case CNF_TPCHANGER: return seen_tpchanger; - case CNF_CHNGRDEV: return seen_chngrdev; - case CNF_CHNGRFILE: return seen_chngrfile; - case CNF_LABELSTR: return seen_labelstr; - case CNF_RUNTAPES: return seen_runtapes; - case CNF_MAXDUMPS: return seen_maxdumps; - case CNF_TAPELIST: return seen_tapelist; - case CNF_INFOFILE: return seen_infofile; - case CNF_DISKFILE: return seen_diskfile; - /*case CNF_DISKDIR: return seen_diskdir;*/ - case CNF_LOGDIR: return seen_logdir; - /*case CNF_LOGFILE: return seen_logfile;*/ - case CNF_BUMPPERCENT: return seen_bumppercent; - case CNF_BUMPSIZE: return seen_bumpsize; - case CNF_BUMPMULT: return seen_bumpmult; - case CNF_BUMPDAYS: return seen_bumpdays; - case CNF_TAPETYPE: return seen_tapetype; - case CNF_DUMPCYCLE: return seen_dumpcycle; - case CNF_RUNSPERCYCLE: return seen_runspercycle; - /*case CNF_MAXCYCLE: return seen_maxcycle;*/ - case CNF_TAPECYCLE: return seen_tapecycle; - /*case CNF_DISKSIZE: return seen_disksize;*/ - case CNF_NETUSAGE: return seen_netusage; - case CNF_INPARALLEL: return seen_inparallel; - case CNF_DUMPORDER: return seen_dumporder; - /*case CNF_TIMEOUT: return seen_timeout;*/ - case CNF_INDEXDIR: return seen_indexdir; - case CNF_ETIMEOUT: return seen_etimeout; - case CNF_DTIMEOUT: return seen_dtimeout; - case CNF_CTIMEOUT: return seen_ctimeout; - case CNF_TAPEBUFS: return seen_tapebufs; - case CNF_RAWTAPEDEV: return seen_rawtapedev; - case CNF_AUTOFLUSH: return seen_autoflush; - case CNF_RESERVE: return seen_reserve; - case CNF_MAXDUMPSIZE: return seen_maxdumpsize; - case CNF_AMRECOVER_DO_FSF: return seen_amrecover_do_fsf; - case CNF_AMRECOVER_CHECK_LABEL: return seen_amrecover_check_label; - case CNF_AMRECOVER_CHANGER: return seen_amrecover_changer; - case CNF_TAPERALGO: return seen_taperalgo; - case CNF_DISPLAYUNIT: return seen_displayunit; - case CNF_KRB5KEYTAB: return seen_krb5keytab; - case CNF_KRB5PRINCIPAL: return seen_krb5principal; - case CNF_LABEL_NEW_TAPES: return seen_label_new_tapes; - default: return 0; - } -} - -int getconf_int(parm) -confparm_t parm; -{ - int r = 0; - - switch(parm) { - - case CNF_DUMPCYCLE: r = conf_dumpcycle.i; break; - case CNF_RUNSPERCYCLE: r = conf_runspercycle.i; break; - case CNF_TAPECYCLE: r = conf_tapecycle.i; break; - case CNF_RUNTAPES: r = conf_runtapes.i; break; - /*case CNF_DISKSIZE: r = conf_disksize.i; break;*/ - case CNF_BUMPPERCENT: r = conf_bumppercent.i; break; - case CNF_BUMPSIZE: r = conf_bumpsize.i; break; - case CNF_BUMPDAYS: r = conf_bumpdays.i; break; - case CNF_NETUSAGE: r = conf_netusage.i; break; - case CNF_INPARALLEL: r = conf_inparallel.i; break; - /*case CNF_TIMEOUT: r = conf_timeout.i; break;*/ - case CNF_MAXDUMPS: r = conf_maxdumps.i; break; - case CNF_ETIMEOUT: r = conf_etimeout.i; break; - case CNF_DTIMEOUT: r = conf_dtimeout.i; break; - case CNF_CTIMEOUT: r = conf_ctimeout.i; break; - case CNF_TAPEBUFS: r = conf_tapebufs.i; break; - case CNF_AUTOFLUSH: r = conf_autoflush.i; break; - case CNF_RESERVE: r = conf_reserve.i; break; - case CNF_AMRECOVER_DO_FSF: r = conf_amrecover_do_fsf.i; break; - case CNF_AMRECOVER_CHECK_LABEL: r = conf_amrecover_check_label.i; break; - case CNF_TAPERALGO: r = conf_taperalgo.i; break; +int +getconf_seen( + confparm_t parm) +{ + t_conf_var *np; + np = get_np(server_var, parm); + return(server_conf[np->parm].seen); +} - default: - error("error [unknown getconf_int parm: %d]", parm); - /* NOTREACHED */ +int +getconf_boolean( + confparm_t parm) +{ + t_conf_var *np; + np = get_np(server_var, parm); + if (np->type != CONFTYPE_BOOL) { + error("getconf_boolean: np is not a CONFTYPE_BOOL"); + /*NOTREACHED*/ } - return r; + return(server_conf[np->parm].v.i != 0); } -am64_t getconf_am64(parm) -confparm_t parm; +int +getconf_int( + confparm_t parm) { - am64_t r = 0; + t_conf_var *np; + np = get_np(server_var, parm); + if (np->type != CONFTYPE_INT) { + error("getconf_int: np is not a CONFTYPE_INT"); + /*NOTREACHED*/ + } + return(server_conf[np->parm].v.i); +} - switch(parm) { - case CNF_MAXDUMPSIZE: r = conf_maxdumpsize.am64; break; +long +getconf_long( + confparm_t parm) +{ + t_conf_var *np; + np = get_np(server_var, parm); + if (np->type != CONFTYPE_LONG) { + error("getconf_long: np is not a CONFTYPE_LONG"); + /*NOTREACHED*/ + } + return(server_conf[np->parm].v.l); +} - default: - error("error [unknown getconf_am64 parm: %d]", parm); - /* NOTREACHED */ +time_t +getconf_time( + confparm_t parm) +{ + t_conf_var *np; + np = get_np(server_var, parm); + if (np->type != CONFTYPE_TIME) { + error("getconf_time: np is not a CONFTYPE_TIME"); + /*NOTREACHED*/ } - return r; + return(server_conf[np->parm].v.t); } -double getconf_real(parm) -confparm_t parm; +ssize_t +getconf_size( + confparm_t parm) { - double r = 0; + t_conf_var *np; + np = get_np(server_var, parm); + if (np->type != CONFTYPE_SIZE) { + error("getconf_size: np is not a CONFTYPE_SIZE"); + /*NOTREACHED*/ + } + return(server_conf[np->parm].v.size); +} - switch(parm) { +off_t +getconf_am64( + confparm_t parm) +{ + t_conf_var *np; + np = get_np(server_var, parm); + if (np->type != CONFTYPE_AM64) { + error("getconf_am64: np is not a CONFTYPE_AM64"); + /*NOTREACHED*/ + } + return(server_conf[np->parm].v.am64); +} - case CNF_BUMPMULT: r = conf_bumpmult.r; break; +double +getconf_real( + confparm_t parm) +{ + t_conf_var *np; + np = get_np(server_var, parm); + if (np->type != CONFTYPE_REAL) { + error("getconf_real: np is not a CONFTYPE_REAL"); + /*NOTREACHED*/ + } + return(server_conf[np->parm].v.r); +} - default: - error("error [unknown getconf_real parm: %d]", parm); - /* NOTREACHED */ - } - return r; -} - -char *getconf_str(parm) -confparm_t parm; -{ - char *r = 0; - - switch(parm) { - - case CNF_ORG: r = conf_org.s; break; - case CNF_MAILTO: r = conf_mailto.s; break; - case CNF_DUMPUSER: r = conf_dumpuser.s; break; - case CNF_PRINTER: r = conf_printer.s; break; - case CNF_TAPEDEV: r = conf_tapedev.s; break; - case CNF_TPCHANGER: r = conf_tpchanger.s; break; - case CNF_CHNGRDEV: r = conf_chngrdev.s; break; - case CNF_CHNGRFILE: r = conf_chngrfile.s; break; - case CNF_LABELSTR: r = conf_labelstr.s; break; - case CNF_TAPELIST: r = conf_tapelist.s; break; - case CNF_INFOFILE: r = conf_infofile.s; break; - case CNF_DUMPORDER: r = conf_dumporder.s; break; - case CNF_LOGDIR: r = conf_logdir.s; break; - /*case CNF_LOGFILE: r = conf_logfile.s; break;*/ - case CNF_DISKFILE: r = conf_diskfile.s; break; - /*case CNF_DISKDIR: r = conf_diskdir.s; break;*/ - case CNF_TAPETYPE: r = conf_tapetype.s; break; - case CNF_INDEXDIR: r = conf_indexdir.s; break; - case CNF_RAWTAPEDEV: r = conf_rawtapedev.s; break; - case CNF_COLUMNSPEC: r = conf_columnspec.s; break; - case CNF_AMRECOVER_CHANGER: r = conf_amrecover_changer.s; break; - case CNF_DISPLAYUNIT: r = conf_displayunit.s; break; - case CNF_KRB5PRINCIPAL: r = conf_krb5principal.s; break; - case CNF_KRB5KEYTAB: r = conf_krb5keytab.s; break; - case CNF_LABEL_NEW_TAPES: r = conf_label_new_tapes.s; break; +char * +getconf_str( + confparm_t parm) +{ + t_conf_var *np; + np = get_np(server_var, parm); + if (np->type != CONFTYPE_STRING && np->type != CONFTYPE_IDENT) { + error("getconf_str: np is not a CONFTYPE_STRING|CONFTYPE_IDENT: %d", parm); + /*NOTREACHED*/ + } + return(server_conf[np->parm].v.s); +} - default: - error("error [unknown getconf_str parm: %d]", parm); - /* NOTREACHED */ +int +getconf_taperalgo( + confparm_t parm) +{ + t_conf_var *np; + np = get_np(server_var, parm); + if (np->type != CONFTYPE_TAPERALGO) { + error("getconf_taperalgo: np is not a CONFTYPE_TAPERALGO"); + /*NOTREACHED*/ } - return r; + return(server_conf[np->parm].v.i); } -holdingdisk_t *getconf_holdingdisks() +holdingdisk_t * +getconf_holdingdisks( + void) { return holdingdisks; } -dumptype_t *lookup_dumptype(str) -char *str; +dumptype_t * +lookup_dumptype( + char *str) { dumptype_t *p; for(p = dumplist; p != NULL; p = p->next) { - if(strcmp(p->name, str) == 0) return p; + if(strcasecmp(p->name, str) == 0) return p; } return NULL; } -tapetype_t *lookup_tapetype(str) -char *str; +tapetype_t * +lookup_tapetype( + char *str) { tapetype_t *p; for(p = tapelist; p != NULL; p = p->next) { - if(strcmp(p->name, str) == 0) return p; + if(strcasecmp(p->name, str) == 0) return p; } return NULL; } -interface_t *lookup_interface(str) -char *str; +interface_t * +lookup_interface( + char *str) { +#ifndef __lint interface_t *p; +#endif - if(str == NULL) return interface_list; - for(p = interface_list; p != NULL; p = p->next) { - if(strcmp(p->name, str) == 0) return p; + if (str == NULL) + return interface_list; + +#ifndef __lint + for (p = interface_list; p != NULL; p = p->next) { + if (strcasecmp(p->name, str) == 0) + return p; } +#endif return NULL; } @@ -686,7 +773,9 @@ char *str; */ -static void init_defaults() +static void +init_defaults( + void) { char *s; @@ -697,141 +786,70 @@ static void init_defaults() #else s = "YOUR ORG"; #endif - conf_org.s = stralloc(s); - malloc_mark(conf_org.s); - conf_mailto.s = stralloc("operators"); - malloc_mark(conf_mailto.s); - conf_dumpuser.s = stralloc(CLIENT_LOGIN); - malloc_mark(conf_dumpuser.s); + conf_init_string(&server_conf[CNF_ORG], s); + conf_init_string(&server_conf[CNF_MAILTO], "operators"); + conf_init_string(&server_conf[CNF_DUMPUSER], CLIENT_LOGIN); #ifdef DEFAULT_TAPE_DEVICE s = DEFAULT_TAPE_DEVICE; #else s = "/dev/rmt8"; #endif - conf_tapedev.s = stralloc(s); - malloc_mark(conf_tapedev.s); -#ifdef DEFAULT_RAW_TAPE_DEVICE - s = DEFAULT_RAW_TAPE_DEVICE; -#else - s = "/dev/rawft0"; -#endif - conf_rawtapedev.s = stralloc(s); - malloc_mark(conf_rawtapedev.s); - conf_tpchanger.s = stralloc(""); - malloc_mark(conf_tpchanger.s); + conf_init_string(&server_conf[CNF_TAPEDEV], s); #ifdef DEFAULT_CHANGER_DEVICE s = DEFAULT_CHANGER_DEVICE; #else s = "/dev/null"; #endif - conf_chngrdev.s = stralloc(s); - malloc_mark(conf_chngrdev.s); - conf_chngrfile.s = stralloc("/usr/adm/amanda/changer-status"); - malloc_mark(conf_chngrfile.s); - conf_labelstr.s = stralloc(".*"); - malloc_mark(conf_labelstr.s); - conf_tapelist.s = stralloc("tapelist"); - malloc_mark(conf_tapelist.s); - conf_infofile.s = stralloc("/usr/adm/amanda/curinfo"); - malloc_mark(conf_infofile.s); - conf_logdir.s = stralloc("/usr/adm/amanda"); - malloc_mark(conf_logdir.s); - conf_diskfile.s = stralloc("disklist"); - malloc_mark(conf_diskfile.s); - conf_diskdir.s = stralloc("/dumps/amanda"); - malloc_mark(conf_diskdir.s); - conf_tapetype.s = stralloc("EXABYTE"); - malloc_mark(conf_tapetype.s); - conf_indexdir.s = stralloc("/usr/adm/amanda/index"); - malloc_mark(conf_indexdir.s); - conf_columnspec.s = stralloc(""); - malloc_mark(conf_columnspec.s); - conf_dumporder.s = stralloc("ttt"); - malloc_mark(conf_dumporder.s); - conf_amrecover_changer.s = stralloc(""); - conf_printer.s = stralloc(""); - conf_displayunit.s = stralloc("k"); - conf_label_new_tapes.s = stralloc(""); - - conf_krb5keytab.s = stralloc("/.amanda-v5-keytab"); - conf_krb5principal.s = stralloc("service/amanda"); - - conf_dumpcycle.i = 10; - conf_runspercycle.i = 0; - conf_tapecycle.i = 15; - conf_runtapes.i = 1; - conf_disksize.i = 0; - conf_netusage.i = 300; - conf_inparallel.i = 10; - conf_maxdumps.i = 1; - conf_timeout.i = 2; - conf_bumppercent.i = 0; - conf_bumpsize.i = 10*1024; - conf_bumpdays.i = 2; - conf_bumpmult.r = 1.5; - conf_etimeout.i = 300; - conf_dtimeout.i = 1800; - conf_ctimeout.i = 30; - conf_tapebufs.i = 20; - conf_autoflush.i = 0; - conf_reserve.i = 100; - conf_maxdumpsize.am64 = -1; - conf_amrecover_do_fsf.i = 1; - conf_amrecover_check_label.i = 1; - conf_taperalgo.i = 0; + conf_init_string(&server_conf[CNF_CHNGRDEV], s); + conf_init_string(&server_conf[CNF_CHNGRFILE], "/usr/adm/amanda/changer-status"); +#ifdef DEFAULT_RAW_TAPE_DEVICE + s = DEFAULT_RAW_TAPE_DEVICE; +#else + s = "/dev/rawft0"; +#endif + conf_init_string (&server_conf[CNF_LABELSTR] , ".*"); + conf_init_string (&server_conf[CNF_TAPELIST] , "tapelist"); + conf_init_string (&server_conf[CNF_DISKFILE] , "disklist"); + conf_init_string (&server_conf[CNF_INFOFILE] , "/usr/adm/amanda/curinfo"); + conf_init_string (&server_conf[CNF_LOGDIR] , "/usr/adm/amanda"); + conf_init_string (&server_conf[CNF_INDEXDIR] , "/usr/adm/amanda/index"); + conf_init_ident (&server_conf[CNF_TAPETYPE] , "EXABYTE"); + conf_init_int (&server_conf[CNF_DUMPCYCLE] , 10); + conf_init_int (&server_conf[CNF_RUNSPERCYCLE] , 0); + conf_init_int (&server_conf[CNF_TAPECYCLE] , 15); + conf_init_int (&server_conf[CNF_NETUSAGE] , 300); + conf_init_int (&server_conf[CNF_INPARALLEL] , 10); + conf_init_string (&server_conf[CNF_DUMPORDER] , "ttt"); + conf_init_int (&server_conf[CNF_BUMPPERCENT] , 0); + conf_init_am64 (&server_conf[CNF_BUMPSIZE] , (off_t)10*1024); + conf_init_real (&server_conf[CNF_BUMPMULT] , 1.5); + conf_init_int (&server_conf[CNF_BUMPDAYS] , 2); + conf_init_string (&server_conf[CNF_TPCHANGER] , ""); + conf_init_int (&server_conf[CNF_RUNTAPES] , 1); + conf_init_int (&server_conf[CNF_MAXDUMPS] , 1); + conf_init_time (&server_conf[CNF_ETIMEOUT] , (time_t)300); + conf_init_time (&server_conf[CNF_DTIMEOUT] , (time_t)1800); + conf_init_time (&server_conf[CNF_CTIMEOUT] , (time_t)30); + conf_init_int (&server_conf[CNF_TAPEBUFS] , 20); + conf_init_string (&server_conf[CNF_RAWTAPEDEV] , s); + conf_init_string (&server_conf[CNF_PRINTER] , ""); + conf_init_bool (&server_conf[CNF_AUTOFLUSH] , 0); + conf_init_int (&server_conf[CNF_RESERVE] , 100); + conf_init_am64 (&server_conf[CNF_MAXDUMPSIZE] , (off_t)-1); + conf_init_string (&server_conf[CNF_COLUMNSPEC] , ""); + conf_init_bool (&server_conf[CNF_AMRECOVER_DO_FSF] , 1); + conf_init_string (&server_conf[CNF_AMRECOVER_CHANGER] , ""); + conf_init_bool (&server_conf[CNF_AMRECOVER_CHECK_LABEL], 1); + conf_init_taperalgo(&server_conf[CNF_TAPERALGO] , 0); + conf_init_string (&server_conf[CNF_DISPLAYUNIT] , "k"); + conf_init_string (&server_conf[CNF_KRB5KEYTAB] , "/.amanda-v5-keytab"); + conf_init_string (&server_conf[CNF_KRB5PRINCIPAL] , "service/amanda"); + conf_init_string (&server_conf[CNF_LABEL_NEW_TAPES] , ""); + conf_init_bool (&server_conf[CNF_USETIMESTAMPS] , 0); /* defaults for internal variables */ - seen_org = 0; - seen_mailto = 0; - seen_dumpuser = 0; - seen_tapedev = 0; - seen_rawtapedev = 0; - seen_printer = 0; - seen_tpchanger = 0; - seen_chngrdev = 0; - seen_chngrfile = 0; - seen_labelstr = 0; - seen_runtapes = 0; - seen_maxdumps = 0; - seen_tapelist = 0; - seen_infofile = 0; - seen_diskfile = 0; - seen_diskdir = 0; - seen_logdir = 0; - seen_bumppercent = 0; - seen_bumpsize = 0; - seen_bumpmult = 0; - seen_bumpdays = 0; - seen_tapetype = 0; - seen_dumpcycle = 0; - seen_runspercycle = 0; - seen_maxcycle = 0; - seen_tapecycle = 0; - seen_disksize = 0; - seen_netusage = 0; - seen_inparallel = 0; - seen_dumporder = 0; - seen_timeout = 0; - seen_indexdir = 0; - seen_etimeout = 0; - seen_dtimeout = 0; - seen_ctimeout = 0; - seen_tapebufs = 0; - seen_autoflush = 0; - seen_reserve = 0; - seen_maxdumpsize = 0; - seen_columnspec = 0; - seen_amrecover_do_fsf = 0; - seen_amrecover_check_label = 0; - seen_amrecover_changer = 0; - seen_taperalgo = 0; - seen_displayunit = 0; - seen_krb5keytab = 0; - seen_krb5principal = 0; - seen_label_new_tapes = 0; - - line_num = got_parserror = 0; + conf_line_num = got_parserror = 0; allow_overwrites = 0; token_pushed = 0; @@ -870,488 +888,238 @@ static void init_defaults() /* create some predefined dumptypes for backwards compatability */ init_dumptype_defaults(); - dpcur.name = "NO-COMPRESS"; dpcur.seen = -1; - dpcur.compress = COMP_NONE; dpcur.s_compress = -1; + dpcur.name = stralloc("NO-COMPRESS"); + dpcur.seen = -1; + conf_set_compress(&dpcur.value[DUMPTYPE_COMPRESS], COMP_NONE); save_dumptype(); init_dumptype_defaults(); - dpcur.name = "COMPRESS-FAST"; dpcur.seen = -1; - dpcur.compress = COMP_FAST; dpcur.s_compress = -1; + dpcur.name = stralloc("COMPRESS-FAST"); + dpcur.seen = -1; + conf_set_compress(&dpcur.value[DUMPTYPE_COMPRESS], COMP_FAST); save_dumptype(); init_dumptype_defaults(); - dpcur.name = "COMPRESS-BEST"; dpcur.seen = -1; - dpcur.compress = COMP_BEST; dpcur.s_compress = -1; + dpcur.name = stralloc("COMPRESS-BEST"); + dpcur.seen = -1; + conf_set_compress(&dpcur.value[DUMPTYPE_COMPRESS], COMP_BEST); save_dumptype(); init_dumptype_defaults(); - dpcur.name = "COMPRESS-CUST"; dpcur.seen = -1; - dpcur.compress = COMP_CUST; dpcur.s_compress = -1; + dpcur.name = stralloc("COMPRESS-CUST"); + dpcur.seen = -1; + conf_set_compress(&dpcur.value[DUMPTYPE_COMPRESS], COMP_CUST); save_dumptype(); init_dumptype_defaults(); - dpcur.name = "SRVCOMPRESS"; dpcur.seen = -1; - dpcur.compress = COMP_SERV_FAST; dpcur.s_compress = -1; + dpcur.name = stralloc("SRVCOMPRESS"); + dpcur.seen = -1; + conf_set_compress(&dpcur.value[DUMPTYPE_COMPRESS], COMP_SERV_FAST); save_dumptype(); init_dumptype_defaults(); - dpcur.name = "BSD-AUTH"; dpcur.seen = -1; - amfree(dpcur.security_driver); - dpcur.security_driver = stralloc("BSD"); dpcur.s_security_driver = -1; + dpcur.name = stralloc("BSD-AUTH"); + dpcur.seen = -1; + conf_set_string(&dpcur.value[DUMPTYPE_SECURITY_DRIVER], "BSD"); save_dumptype(); init_dumptype_defaults(); - dpcur.name = "KRB4-AUTH"; dpcur.seen = -1; - amfree(dpcur.security_driver); - dpcur.security_driver = stralloc("KRB4"); dpcur.s_security_driver = -1; + dpcur.name = stralloc("KRB4-AUTH"); + dpcur.seen = -1; + conf_set_string(&dpcur.value[DUMPTYPE_SECURITY_DRIVER], "KRB4"); save_dumptype(); init_dumptype_defaults(); - dpcur.name = "NO-RECORD"; dpcur.seen = -1; - dpcur.record = 0; dpcur.s_record = -1; + dpcur.name = stralloc("NO-RECORD"); + dpcur.seen = -1; + conf_set_bool(&dpcur.value[DUMPTYPE_RECORD], 0); save_dumptype(); init_dumptype_defaults(); - dpcur.name = "NO-HOLD"; dpcur.seen = -1; - dpcur.no_hold = 1; dpcur.s_no_hold = -1; + dpcur.name = stralloc("NO-HOLD"); + dpcur.seen = -1; + conf_set_holding(&dpcur.value[DUMPTYPE_HOLDINGDISK], HOLD_NEVER); save_dumptype(); init_dumptype_defaults(); - dpcur.name = "NO-FULL"; dpcur.seen = -1; - dpcur.strategy = DS_NOFULL; dpcur.s_strategy = -1; + dpcur.name = stralloc("NO-FULL"); + dpcur.seen = -1; + conf_set_strategy(&dpcur.value[DUMPTYPE_STRATEGY], DS_NOFULL); save_dumptype(); } -static void read_conffile_recursively(filename) -char *filename; +static void +read_conffile_recursively( + char *filename) { - extern int errno; - /* Save globals used in read_confline(), elsewhere. */ - int save_line_num = line_num; - FILE *save_conf = conf; - char *save_confname = confname; + int save_line_num = conf_line_num; + FILE *save_conf = conf_conf; + char *save_confname = conf_confname; + int rc; if (*filename == '/' || config_dir == NULL) { - confname = stralloc(filename); + conf_confname = stralloc(filename); } else { - confname = stralloc2(config_dir, filename); + conf_confname = stralloc2(config_dir, filename); } - if((conf = fopen(confname, "r")) == NULL) { - fprintf(stderr, "could not open conf file \"%s\": %s\n", confname, + if((conf_conf = fopen(conf_confname, "r")) == NULL) { + fprintf(stderr, "could not open conf file \"%s\": %s\n", conf_confname, strerror(errno)); - amfree(confname); + amfree(conf_confname); got_parserror = -1; return; } - line_num = 0; + conf_line_num = 0; /* read_confline() can invoke us recursively via "includefile" */ - while(read_confline()); - afclose(conf); + do { + rc = read_confline(); + } while (rc != 0); + afclose(conf_conf); - amfree(confname); + amfree(conf_confname); - /* Restore globals */ - line_num = save_line_num; - conf = save_conf; - confname = save_confname; + /* Restore servers */ + conf_line_num = save_line_num; + conf_conf = save_conf; + conf_confname = save_confname; } /* ------------------------ */ -keytab_t main_keytable[] = { - { "BUMPDAYS", BUMPDAYS }, - { "BUMPMULT", BUMPMULT }, - { "BUMPSIZE", BUMPSIZE }, - { "BUMPPERCENT", BUMPPERCENT }, - { "DEFINE", DEFINE }, - { "DISKDIR", DISKDIR }, /* XXX - historical */ - { "DISKFILE", DISKFILE }, - { "DISKSIZE", DISKSIZE }, /* XXX - historical */ - { "DUMPCYCLE", DUMPCYCLE }, - { "RUNSPERCYCLE", RUNSPERCYCLE }, - { "DUMPTYPE", DUMPTYPE }, - { "DUMPUSER", DUMPUSER }, - { "PRINTER", PRINTER }, - { "HOLDINGDISK", HOLDING }, - { "INCLUDEFILE", INCLUDEFILE }, - { "INDEXDIR", INDEXDIR }, - { "INFOFILE", INFOFILE }, - { "INPARALLEL", INPARALLEL }, - { "DUMPORDER", DUMPORDER }, - { "INTERFACE", INTERFACE }, - { "LABELSTR", LABELSTR }, - { "LOGDIR", LOGDIR }, - { "LOGFILE", LOGFILE }, /* XXX - historical */ - { "MAILTO", MAILTO }, - { "MAXCYCLE", MAXCYCLE }, /* XXX - historical */ - { "MAXDUMPS", MAXDUMPS }, - { "MINCYCLE", DUMPCYCLE }, /* XXX - historical */ - { "NETUSAGE", NETUSAGE }, /* XXX - historical */ - { "ORG", ORG }, - { "RUNTAPES", RUNTAPES }, - { "TAPECYCLE", TAPECYCLE }, - { "TAPEDEV", TAPEDEV }, - { "TAPELIST", TAPELIST }, - { "TAPETYPE", TAPETYPE }, - { "TIMEOUT", TIMEOUT }, /* XXX - historical */ - { "TPCHANGER", TPCHANGER }, - { "CHANGERDEV", CHNGRDEV }, - { "CHANGERFILE", CHNGRFILE }, - { "ETIMEOUT", ETIMEOUT }, - { "DTIMEOUT", DTIMEOUT }, - { "CTIMEOUT", CTIMEOUT }, - { "TAPEBUFS", TAPEBUFS }, - { "RAWTAPEDEV", RAWTAPEDEV }, - { "AUTOFLUSH", AUTOFLUSH }, - { "RESERVE", RESERVE }, - { "MAXDUMPSIZE", MAXDUMPSIZE }, - { "COLUMNSPEC", COLUMNSPEC }, - { "AMRECOVER_DO_FSF", AMRECOVER_DO_FSF }, - { "AMRECOVER_CHECK_LABEL", AMRECOVER_CHECK_LABEL }, - { "AMRECOVER_CHANGER", AMRECOVER_CHANGER }, - { "TAPERALGO", TAPERALGO }, - { "DISPLAYUNIT", DISPLAYUNIT }, - { "KRB5KEYTAB", KRB5KEYTAB }, - { "KRB5PRINCIPAL", KRB5PRINCIPAL }, - { "LABEL_NEW_TAPES", LABEL_NEW_TAPES }, - { NULL, IDENT } -}; - -static int read_confline() +static int +read_confline( + void) { - keytable = main_keytable; + t_conf_var *np; - line_num += 1; - get_conftoken(ANY); + keytable = server_keytab; + + conf_line_num += 1; + get_conftoken(CONF_ANY); switch(tok) { - case INCLUDEFILE: + case CONF_INCLUDEFILE: { char *fn; + char *cname; - get_conftoken(STRING); - fn = tokenval.s; - read_conffile_recursively(fn); - } - break; - - case ORG: get_simple(&conf_org, &seen_org, STRING); break; - case MAILTO: get_simple(&conf_mailto, &seen_mailto, STRING); break; - case DUMPUSER: get_simple(&conf_dumpuser, &seen_dumpuser, STRING); break; - case PRINTER: get_simple(&conf_printer, &seen_printer, STRING); break; - case DUMPCYCLE: get_simple(&conf_dumpcycle, &seen_dumpcycle, INT); - if(conf_dumpcycle.i < 0) { - parserror("dumpcycle must be positive"); - } - break; - case RUNSPERCYCLE: get_simple(&conf_runspercycle, &seen_runspercycle, INT); - if(conf_runspercycle.i < -1) { - parserror("runspercycle must be >= -1"); - } - break; - case MAXCYCLE: get_simple(&conf_maxcycle, &seen_maxcycle, INT); break; - case TAPECYCLE: get_simple(&conf_tapecycle, &seen_tapecycle, INT); - if(conf_tapecycle.i < 1) { - parserror("tapecycle must be positive"); - } - break; - case RUNTAPES: get_simple(&conf_runtapes, &seen_runtapes, INT); - if(conf_runtapes.i < 0) { - parserror("runtapes must be positive"); - } - break; - case TAPEDEV: get_simple(&conf_tapedev, &seen_tapedev, STRING); break; - case RAWTAPEDEV:get_simple(&conf_rawtapedev,&seen_rawtapedev,STRING); break; - case TPCHANGER: get_simple(&conf_tpchanger, &seen_tpchanger, STRING); break; - case CHNGRDEV: get_simple(&conf_chngrdev, &seen_chngrdev, STRING); break; - case CHNGRFILE: get_simple(&conf_chngrfile, &seen_chngrfile, STRING); break; - case LABELSTR: get_simple(&conf_labelstr, &seen_labelstr, STRING); break; - case TAPELIST: get_simple(&conf_tapelist, &seen_tapelist, STRING); break; - case INFOFILE: get_simple(&conf_infofile, &seen_infofile, STRING); break; - case LOGDIR: get_simple(&conf_logdir, &seen_logdir, STRING); break; - case DISKFILE: get_simple(&conf_diskfile, &seen_diskfile, STRING); break; - case BUMPMULT: get_simple(&conf_bumpmult, &seen_bumpmult, REAL); - if(conf_bumpmult.r < 0.999) { - parserror("bumpmult must be positive"); - } - break; - case BUMPPERCENT: get_simple(&conf_bumppercent, &seen_bumppercent, INT); - if(conf_bumppercent.i < 0 || conf_bumppercent.i > 100) { - parserror("bumppercent must be between 0 and 100"); - } - break; - case BUMPSIZE: get_simple(&conf_bumpsize, &seen_bumpsize, INT); - if(conf_bumpsize.i < 1) { - parserror("bumpsize must be positive"); - } - break; - case BUMPDAYS: get_simple(&conf_bumpdays, &seen_bumpdays, INT); - if(conf_bumpdays.i < 1) { - parserror("bumpdays must be positive"); - } - break; - case NETUSAGE: get_simple(&conf_netusage, &seen_netusage, INT); - if(conf_netusage.i < 1) { - parserror("netusage must be positive"); - } - break; - case INPARALLEL:get_simple(&conf_inparallel,&seen_inparallel,INT); - if(conf_inparallel.i < 1 || conf_inparallel.i >MAX_DUMPERS){ - parserror( - "inparallel must be between 1 and MAX_DUMPERS (%d)", - MAX_DUMPERS); - } - break; - case DUMPORDER: get_simple(&conf_dumporder, &seen_dumporder, STRING); break; - case TIMEOUT: get_simple(&conf_timeout, &seen_timeout, INT); break; - case MAXDUMPS: get_simple(&conf_maxdumps, &seen_maxdumps, INT); - if(conf_maxdumps.i < 1) { - parserror("maxdumps must be positive"); - } - break; - case TAPETYPE: get_simple(&conf_tapetype, &seen_tapetype, IDENT); break; - case INDEXDIR: get_simple(&conf_indexdir, &seen_indexdir, STRING); break; - case ETIMEOUT: get_simple(&conf_etimeout, &seen_etimeout, INT); break; - case DTIMEOUT: get_simple(&conf_dtimeout, &seen_dtimeout, INT); - if(conf_dtimeout.i < 1) { - parserror("dtimeout must be positive"); - } - break; - case CTIMEOUT: get_simple(&conf_ctimeout, &seen_ctimeout, INT); - if(conf_ctimeout.i < 1) { - parserror("ctimeout must be positive"); - } - break; - case TAPEBUFS: get_simple(&conf_tapebufs, &seen_tapebufs, INT); - if(conf_tapebufs.i < 1) { - parserror("tapebufs must be positive"); - } - break; - case AUTOFLUSH: get_simple(&conf_autoflush, &seen_autoflush, BOOL); break; - case RESERVE: get_simple(&conf_reserve, &seen_reserve, INT); - if(conf_reserve.i < 0 || conf_reserve.i > 100) { - parserror("reserve must be between 0 and 100"); - } - break; - case MAXDUMPSIZE:get_simple(&conf_maxdumpsize,&seen_maxdumpsize,AM64); break; - case COLUMNSPEC:get_simple(&conf_columnspec,&seen_columnspec,STRING); break; - - case AMRECOVER_DO_FSF: get_simple(&conf_amrecover_do_fsf,&seen_amrecover_do_fsf, BOOL); break; - case AMRECOVER_CHECK_LABEL: get_simple(&conf_amrecover_check_label,&seen_amrecover_check_label, BOOL); break; - case AMRECOVER_CHANGER: get_simple(&conf_amrecover_changer,&seen_amrecover_changer, STRING); break; - - case TAPERALGO: get_taperalgo(&conf_taperalgo,&seen_taperalgo); break; - case DISPLAYUNIT: get_simple(&conf_displayunit,&seen_displayunit, STRING); - if(strcmp(conf_displayunit.s,"k") == 0 || - strcmp(conf_displayunit.s,"K") == 0) { - conf_displayunit.s[0] = toupper(conf_displayunit.s[0]); - unit_divisor=1; - } - else if(strcmp(conf_displayunit.s,"m") == 0 || - strcmp(conf_displayunit.s,"M") == 0) { - conf_displayunit.s[0] = toupper(conf_displayunit.s[0]); - unit_divisor=1024; - } - else if(strcmp(conf_displayunit.s,"g") == 0 || - strcmp(conf_displayunit.s,"G") == 0) { - conf_displayunit.s[0] = toupper(conf_displayunit.s[0]); - unit_divisor=1024*1024; - } - else if(strcmp(conf_displayunit.s,"t") == 0 || - strcmp(conf_displayunit.s,"T") == 0) { - conf_displayunit.s[0] = toupper(conf_displayunit.s[0]); - unit_divisor=1024*1024*1024; - } - else { - parserror("displayunit must be k,m,g or t."); - } - break; - - /* kerberos 5 bits. only useful when kerberos 5 built in... */ - case KRB5KEYTAB: get_simple(&conf_krb5keytab, &seen_krb5keytab, STRING); break; - case KRB5PRINCIPAL: get_simple(&conf_krb5principal,&seen_krb5principal,STRING); break; - - case LOGFILE: /* XXX - historical */ - /* truncate the filename part and pretend he said "logdir" */ - { - char *p; - - get_simple(&conf_logdir, &seen_logdir, STRING); - - p = strrchr(conf_logdir.s, '/'); - if (p != (char *)0) *p = '\0'; - } - break; - - case DISKDIR: - { - char *s; - - get_conftoken(STRING); - s = tokenval.s; - - if(!seen_diskdir) { - conf_diskdir.s = newstralloc(conf_diskdir.s, s); - seen_diskdir = line_num; + get_conftoken(CONF_STRING); + fn = tokenval.v.s; + if (*fn == '/' || config_dir == NULL) { + cname = stralloc(fn); + } else { + cname = stralloc2(config_dir, fn); } - - init_holdingdisk_defaults(); - hdcur.name = "default from DISKDIR"; - hdcur.seen = line_num; - hdcur.diskdir = stralloc(s); - hdcur.s_disk = line_num; - hdcur.disksize = conf_disksize.i; - hdcur.s_size = seen_disksize; - save_holdingdisk(); - } - break; - - case DISKSIZE: - { - int i; - - i = get_int(); - i = (i / DISK_BLOCK_KB) * DISK_BLOCK_KB; - - if(!seen_disksize) { - conf_disksize.i = i; - seen_disksize = line_num; + if ( cname != NULL && (access(cname, R_OK) == 0)) { + read_conffile_recursively(cname); + amfree(cname); + } else { + conf_parserror("cannot open %s: %s\n", fn, strerror(errno)); } - - if(holdingdisks != NULL) - holdingdisks->disksize = i; + amfree(cname); + } - break; - case HOLDING: + case CONF_HOLDING: get_holdingdisk(); break; - case DEFINE: - get_conftoken(ANY); - if(tok == DUMPTYPE) get_dumptype(); - else if(tok == TAPETYPE) get_tapetype(); - else if(tok == INTERFACE) get_interface(); - else parserror("DUMPTYPE, INTERFACE or TAPETYPE expected"); + case CONF_DEFINE: + get_conftoken(CONF_ANY); + if(tok == CONF_DUMPTYPE) get_dumptype(); + else if(tok == CONF_TAPETYPE) get_tapetype(); + else if(tok == CONF_INTERFACE) get_interface(); + else conf_parserror("DUMPTYPE, INTERFACE or TAPETYPE expected"); break; - case LABEL_NEW_TAPES: - get_simple(&conf_label_new_tapes, &seen_label_new_tapes, STRING); - break; - case NL: /* empty line */ + case CONF_NL: /* empty line */ break; - case END: /* end of file */ + + case CONF_END: /* end of file */ return 0; + default: - parserror("configuration keyword expected"); + { + for(np = server_var; np->token != CONF_UNKNOWN; np++) + if(np->token == tok) break; + + if(np->token == CONF_UNKNOWN) { + conf_parserror("configuration keyword expected"); + } else { + np->read_function(np, &server_conf[np->parm]); + if(np->validate) + np->validate(np, &server_conf[np->parm]); + } + } } - if(tok != NL) get_conftoken(NL); + if(tok != CONF_NL) + get_conftoken(CONF_NL); return 1; } -keytab_t holding_keytable[] = { - { "DIRECTORY", DIRECTORY }, - { "COMMENT", COMMENT }, - { "USE", USE }, - { "CHUNKSIZE", CHUNKSIZE }, - { NULL, IDENT } +t_conf_var holding_var [] = { + { CONF_DIRECTORY, CONFTYPE_STRING, read_string, HOLDING_DISKDIR , NULL }, + { CONF_COMMENT , CONFTYPE_STRING, read_string, HOLDING_COMMENT , NULL }, + { CONF_USE , CONFTYPE_AM64 , read_am64 , HOLDING_DISKSIZE , validate_use }, + { CONF_CHUNKSIZE, CONFTYPE_AM64 , read_am64 , HOLDING_CHUNKSIZE, validate_chunksize }, + { CONF_UNKNOWN , CONFTYPE_INT , NULL , HOLDING_HOLDING , NULL } }; -static void get_holdingdisk() +static void +get_holdingdisk( + void) { - int done; + char *prefix; int save_overwrites; - keytab_t *save_kt; save_overwrites = allow_overwrites; allow_overwrites = 1; - save_kt = keytable; - keytable = holding_keytable; - init_holdingdisk_defaults(); - get_conftoken(IDENT); - hdcur.name = stralloc(tokenval.s); - malloc_mark(hdcur.name); - hdcur.seen = line_num; + get_conftoken(CONF_IDENT); + hdcur.name = stralloc(tokenval.v.s); + hdcur.seen = conf_line_num; - get_conftoken(LBRACE); - get_conftoken(NL); - - done = 0; - do { - line_num += 1; - get_conftoken(ANY); - switch(tok) { - - case COMMENT: - get_simple((val_t *)&hdcur.comment, &hdcur.s_comment, STRING); - break; - case DIRECTORY: - get_simple((val_t *)&hdcur.diskdir, &hdcur.s_disk, STRING); - break; - case USE: - get_simple((val_t *)&hdcur.disksize, &hdcur.s_size, LONG); - hdcur.disksize = am_floor(hdcur.disksize, DISK_BLOCK_KB); - break; - case CHUNKSIZE: - get_simple((val_t *)&hdcur.chunksize, &hdcur.s_csize, LONG); - if(hdcur.chunksize == 0) { - hdcur.chunksize = ((INT_MAX / 1024) - (2 * DISK_BLOCK_KB)); - } else if(hdcur.chunksize < 0) { - parserror("Negative chunksize (%ld) is no longer supported", - hdcur.chunksize); - } - hdcur.chunksize = am_floor(hdcur.chunksize, DISK_BLOCK_KB); - break; - case RBRACE: - done = 1; - break; - case NL: /* empty line */ - break; - case END: /* end of file */ - done = 1; - default: - parserror("holding disk parameter expected"); - } - if(tok != NL && tok != END) get_conftoken(NL); - } while(!done); + prefix = vstralloc( "HOLDINGDISK:", hdcur.name, ":", NULL); + read_block(server_options, holding_var, server_keytab, hdcur.value, prefix, + "holding disk parameter expected", 1, NULL); + amfree(prefix); + get_conftoken(CONF_NL); + hdcur.disksize = holdingdisk_get_disksize(&hdcur); save_holdingdisk(); allow_overwrites = save_overwrites; - keytable = save_kt; } -static void init_holdingdisk_defaults() +static void +init_holdingdisk_defaults( + void) { - hdcur.comment = stralloc(""); - hdcur.diskdir = stralloc(conf_diskdir.s); - malloc_mark(hdcur.diskdir); - hdcur.disksize = 0; - hdcur.chunksize = 1024*1024/**1024*/; /* 1 Gb = 1M counted in 1Kb blocks */ - - hdcur.s_comment = 0; - hdcur.s_disk = 0; - hdcur.s_size = 0; - hdcur.s_csize = 0; + conf_init_string(&hdcur.value[HOLDING_COMMENT] , ""); + conf_init_string(&hdcur.value[HOLDING_DISKDIR] , ""); + conf_init_am64(&hdcur.value[HOLDING_DISKSIZE] , (off_t)0); + /* 1 Gb = 1M counted in 1Kb blocks */ + conf_init_am64(&hdcur.value[HOLDING_CHUNKSIZE], (off_t)1024*1024); hdcur.up = (void *)0; + hdcur.disksize = 0LL; } -static void save_holdingdisk() +static void +save_holdingdisk( + void) { holdingdisk_t *hp; hp = alloc(sizeof(holdingdisk_t)); - malloc_mark(hp); *hp = hdcur; hp->next = holdingdisks; holdingdisks = hp; @@ -1360,902 +1128,467 @@ static void save_holdingdisk() } -keytab_t dumptype_keytable[] = { - { "AUTH", AUTH }, - { "BUMPDAYS", BUMPDAYS }, - { "BUMPMULT", BUMPMULT }, - { "BUMPSIZE", BUMPSIZE }, - { "BUMPPERCENT", BUMPPERCENT }, - { "COMMENT", COMMENT }, - { "COMPRATE", COMPRATE }, - { "COMPRESS", COMPRESS }, - { "ENCRYPT", ENCRYPT }, - { "SERVER_DECRYPT_OPTION", SRV_DECRYPT_OPT }, - { "CLIENT_DECRYPT_OPTION", CLNT_DECRYPT_OPT }, - { "DUMPCYCLE", DUMPCYCLE }, - { "EXCLUDE", EXCLUDE }, - { "FREQUENCY", FREQUENCY }, /* XXX - historical */ - { "HOLDINGDISK", HOLDING }, - { "IGNORE", IGNORE }, - { "INCLUDE", INCLUDE }, - { "INDEX", INDEX }, - { "KENCRYPT", KENCRYPT }, - { "MAXCYCLE", MAXCYCLE }, /* XXX - historical */ - { "MAXDUMPS", MAXDUMPS }, - { "MAXPROMOTEDAY", MAXPROMOTEDAY }, - { "OPTIONS", OPTIONS }, /* XXX - historical */ - { "PRIORITY", PRIORITY }, - { "PROGRAM", PROGRAM }, - { "RECORD", RECORD }, - { "SKIP-FULL", SKIP_FULL }, - { "SKIP-INCR", SKIP_INCR }, - { "STARTTIME", STARTTIME }, - { "STRATEGY", STRATEGY }, - { "TAPE_SPLITSIZE", TAPE_SPLITSIZE }, - { "SPLIT_DISKBUFFER", SPLIT_DISKBUFFER }, - { "FALLBACK_SPLITSIZE", FALLBACK_SPLITSIZE }, - { "ESTIMATE", ESTIMATE }, - { "SERVER_CUSTOM_COMPRESS", SRVCOMPPROG }, - { "CLIENT_CUSTOM_COMPRESS", CLNTCOMPPROG }, - { "SERVER_ENCRYPT", SRV_ENCRYPT }, - { "CLIENT_ENCRYPT", CLNT_ENCRYPT }, - { NULL, IDENT } +t_conf_var dumptype_var [] = { + { CONF_COMMENT , CONFTYPE_STRING , read_string , DUMPTYPE_COMMENT , NULL }, + { CONF_AUTH , CONFTYPE_STRING , read_string , DUMPTYPE_SECURITY_DRIVER , NULL }, + { CONF_BUMPDAYS , CONFTYPE_INT , read_int , DUMPTYPE_BUMPDAYS , NULL }, + { CONF_BUMPMULT , CONFTYPE_REAL , read_real , DUMPTYPE_BUMPMULT , NULL }, + { CONF_BUMPSIZE , CONFTYPE_AM64 , read_am64 , DUMPTYPE_BUMPSIZE , NULL }, + { CONF_BUMPPERCENT , CONFTYPE_INT , read_int , DUMPTYPE_BUMPPERCENT , NULL }, + { CONF_COMPRATE , CONFTYPE_REAL , get_comprate, DUMPTYPE_COMPRATE , NULL }, + { CONF_COMPRESS , CONFTYPE_INT , get_compress, DUMPTYPE_COMPRESS , NULL }, + { CONF_ENCRYPT , CONFTYPE_INT , get_encrypt , DUMPTYPE_ENCRYPT , NULL }, + { CONF_DUMPCYCLE , CONFTYPE_INT , read_int , DUMPTYPE_DUMPCYCLE , validate_positive0 }, + { CONF_EXCLUDE , CONFTYPE_EXINCLUDE, get_exclude , DUMPTYPE_EXCLUDE , NULL }, + { CONF_INCLUDE , CONFTYPE_EXINCLUDE, get_exclude , DUMPTYPE_INCLUDE , NULL }, + { CONF_IGNORE , CONFTYPE_BOOL , read_bool , DUMPTYPE_IGNORE , NULL }, + { CONF_HOLDING , CONFTYPE_HOLDING , get_holding , DUMPTYPE_HOLDINGDISK , NULL }, + { CONF_INDEX , CONFTYPE_BOOL , read_bool , DUMPTYPE_INDEX , NULL }, + { CONF_KENCRYPT , CONFTYPE_BOOL , read_bool , DUMPTYPE_KENCRYPT , NULL }, + { CONF_MAXDUMPS , CONFTYPE_INT , read_int , DUMPTYPE_MAXDUMPS , validate_positive1 }, + { CONF_MAXPROMOTEDAY , CONFTYPE_INT , read_int , DUMPTYPE_MAXPROMOTEDAY , validate_positive0 }, + { CONF_PRIORITY , CONFTYPE_PRIORITY , get_priority, DUMPTYPE_PRIORITY , NULL }, + { CONF_PROGRAM , CONFTYPE_STRING , read_string , DUMPTYPE_PROGRAM , NULL }, + { CONF_RECORD , CONFTYPE_BOOL , read_bool , DUMPTYPE_RECORD , NULL }, + { CONF_SKIP_FULL , CONFTYPE_BOOL , read_bool , DUMPTYPE_SKIP_FULL , NULL }, + { CONF_SKIP_INCR , CONFTYPE_BOOL , read_bool , DUMPTYPE_SKIP_INCR , NULL }, + { CONF_STARTTIME , CONFTYPE_TIME , read_time , DUMPTYPE_START_T , NULL }, + { CONF_STRATEGY , CONFTYPE_INT , get_strategy, DUMPTYPE_STRATEGY , NULL }, + { CONF_TAPE_SPLITSIZE , CONFTYPE_AM64 , read_am64 , DUMPTYPE_TAPE_SPLITSIZE , validate_positive0 }, + { CONF_SPLIT_DISKBUFFER , CONFTYPE_STRING , read_string , DUMPTYPE_SPLIT_DISKBUFFER , NULL }, + { CONF_ESTIMATE , CONFTYPE_INT , get_estimate, DUMPTYPE_ESTIMATE , NULL }, + { CONF_SRV_ENCRYPT , CONFTYPE_STRING , read_string , DUMPTYPE_SRV_ENCRYPT , NULL }, + { CONF_CLNT_ENCRYPT , CONFTYPE_STRING , read_string , DUMPTYPE_CLNT_ENCRYPT , NULL }, + { CONF_AMANDAD_PATH , CONFTYPE_STRING , read_string , DUMPTYPE_AMANDAD_PATH , NULL }, + { CONF_CLIENT_USERNAME , CONFTYPE_STRING , read_string , DUMPTYPE_CLIENT_USERNAME , NULL }, + { CONF_SSH_KEYS , CONFTYPE_STRING , read_string , DUMPTYPE_SSH_KEYS , NULL }, + { CONF_SRVCOMPPROG , CONFTYPE_STRING , read_string , DUMPTYPE_SRVCOMPPROG , NULL }, + { CONF_CLNTCOMPPROG , CONFTYPE_STRING , read_string , DUMPTYPE_CLNTCOMPPROG , NULL }, + { CONF_FALLBACK_SPLITSIZE, CONFTYPE_AM64 , read_am64 , DUMPTYPE_FALLBACK_SPLITSIZE, NULL }, + { CONF_SRV_DECRYPT_OPT , CONFTYPE_STRING , read_string , DUMPTYPE_SRV_DECRYPT_OPT , NULL }, + { CONF_CLNT_DECRYPT_OPT , CONFTYPE_STRING , read_string , DUMPTYPE_CLNT_DECRYPT_OPT , NULL }, + { CONF_UNKNOWN , CONFTYPE_INT , NULL , DUMPTYPE_DUMPTYPE , NULL } }; -dumptype_t *read_dumptype(name, from, fname, linenum) - char *name; - FILE *from; - char *fname; - int *linenum; +dumptype_t * +read_dumptype( + char *name, + FILE *from, + char *fname, + int *linenum) { - int done; int save_overwrites; - keytab_t *save_kt; - val_t tmpval; FILE *saved_conf = NULL; char *saved_fname = NULL; + char *prefix; if (from) { - saved_conf = conf; - conf = from; + saved_conf = conf_conf; + conf_conf = from; } if (fname) { - saved_fname = confname; - confname = fname; + saved_fname = conf_confname; + conf_confname = fname; } if (linenum) - line_num = *linenum; + conf_line_num = *linenum; save_overwrites = allow_overwrites; allow_overwrites = 1; - save_kt = keytable; - keytable = dumptype_keytable; - init_dumptype_defaults(); - if (name) { dpcur.name = name; } else { - get_conftoken(IDENT); - dpcur.name = stralloc(tokenval.s); - malloc_mark(dpcur.name); + get_conftoken(CONF_IDENT); + dpcur.name = stralloc(tokenval.v.s); } + dpcur.seen = conf_line_num; - dpcur.seen = line_num; + prefix = vstralloc( "DUMPTYPE:", dpcur.name, ":", NULL); + read_block(server_options, dumptype_var, server_keytab, dpcur.value, + prefix, "dumptype parameter expected", + (name == NULL), *copy_dumptype); + amfree(prefix); + if(!name) + get_conftoken(CONF_NL); - if (! name) { - get_conftoken(LBRACE); - get_conftoken(NL); - } + /* XXX - there was a stupidity check in here for skip-incr and + ** skip-full. This check should probably be somewhere else. */ - done = 0; - do { - line_num += 1; - get_conftoken(ANY); - switch(tok) { - - case AUTH: - get_simple((val_t *)&dpcur.security_driver, - &dpcur.s_security_driver, STRING); - break; - case COMMENT: - get_simple((val_t *)&dpcur.comment, &dpcur.s_comment, STRING); - break; - case COMPRATE: - get_comprate(); - break; - case COMPRESS: - get_compress(); - break; - case ENCRYPT: - get_encrypt(); - break; - case SRV_DECRYPT_OPT: - get_simple((val_t *)&dpcur.srv_decrypt_opt, &dpcur.s_srv_decrypt_opt, STRING); - break; - case CLNT_DECRYPT_OPT: - get_simple((val_t *)&dpcur.clnt_decrypt_opt, &dpcur.s_clnt_decrypt_opt, STRING); - break; - case DUMPCYCLE: - get_simple((val_t *)&dpcur.dumpcycle, &dpcur.s_dumpcycle, INT); - if(dpcur.dumpcycle < 0) { - parserror("dumpcycle must be positive"); - } - break; - case EXCLUDE: - get_exclude(); - break; - case FREQUENCY: - get_simple((val_t *)&dpcur.frequency, &dpcur.s_frequency, INT); - break; - case HOLDING: - get_simple(&tmpval, &dpcur.s_no_hold, BOOL); - dpcur.no_hold = (tmpval.i == 0); - break; - case IGNORE: - get_simple(&tmpval, &dpcur.s_ignore, BOOL); - dpcur.ignore = (tmpval.i != 0); - break; - case INCLUDE: - get_include(); - break; - case INDEX: - get_simple(&tmpval, &dpcur.s_index, BOOL); - dpcur.index = (tmpval.i != 0); - break; - case KENCRYPT: - get_simple(&tmpval, &dpcur.s_kencrypt, BOOL); - dpcur.kencrypt = (tmpval.i != 0); - break; - case MAXCYCLE: - get_simple((val_t *)&conf_maxcycle, &dpcur.s_maxcycle, INT); - break; - case MAXDUMPS: - get_simple((val_t *)&dpcur.maxdumps, &dpcur.s_maxdumps, INT); - if(dpcur.maxdumps < 1) { - parserror("maxdumps must be positive"); - } - break; - case MAXPROMOTEDAY: - get_simple((val_t *)&dpcur.maxpromoteday, &dpcur.s_maxpromoteday, INT); - if(dpcur.maxpromoteday < 0) { - parserror("dpcur.maxpromoteday must be >= 0"); - } - break; - case BUMPPERCENT: - get_simple((val_t *)&dpcur.bumppercent, &dpcur.s_bumppercent, INT); - if(dpcur.bumppercent < 0 || dpcur.bumppercent > 100) { - parserror("bumppercent must be between 0 and 100"); - } - break; - case BUMPSIZE: - get_simple((val_t *)&dpcur.bumpsize, &dpcur.s_bumpsize, INT); - if(dpcur.bumpsize < 1) { - parserror("bumpsize must be positive"); - } - break; - case BUMPDAYS: - get_simple((val_t *)&dpcur.bumpdays, &dpcur.s_bumpdays, INT); - if(dpcur.bumpdays < 1) { - parserror("bumpdays must be positive"); - } - break; - case BUMPMULT: - get_simple((val_t *)&dpcur.bumpmult, &dpcur.s_bumpmult, REAL); - if(dpcur.bumpmult < 0.999) { - parserror("bumpmult must be positive (%f)",dpcur.bumpmult); - } - break; - case OPTIONS: - get_dumpopts(); - break; - case PRIORITY: - get_priority(); - break; - case PROGRAM: - get_simple((val_t *)&dpcur.program, &dpcur.s_program, STRING); - break; - case RECORD: - get_simple(&tmpval, &dpcur.s_record, BOOL); - dpcur.record = (tmpval.i != 0); - break; - case SKIP_FULL: - get_simple(&tmpval, &dpcur.s_skip_full, BOOL); - dpcur.skip_full = (tmpval.i != 0); - break; - case SKIP_INCR: - get_simple(&tmpval, &dpcur.s_skip_incr, BOOL); - dpcur.skip_incr = (tmpval.i != 0); - break; - case STARTTIME: - get_simple((val_t *)&dpcur.start_t, &dpcur.s_start_t, TIME); - break; - case STRATEGY: - get_strategy(); - break; - case ESTIMATE: - get_estimate(); - break; - case IDENT: - copy_dumptype(); - break; - case TAPE_SPLITSIZE: - get_simple((val_t *)&dpcur.tape_splitsize, &dpcur.s_tape_splitsize, INT); - if(dpcur.tape_splitsize < 0) { - parserror("tape_splitsize must be >= 0"); - } - break; - case SPLIT_DISKBUFFER: - get_simple((val_t *)&dpcur.split_diskbuffer, &dpcur.s_split_diskbuffer, STRING); - break; - case FALLBACK_SPLITSIZE: - get_simple((val_t *)&dpcur.fallback_splitsize, &dpcur.s_fallback_splitsize, INT); - if(dpcur.fallback_splitsize < 0) { - parserror("fallback_splitsize must be >= 0"); - } - break; - case SRVCOMPPROG: - get_simple((val_t *)&dpcur.srvcompprog, &dpcur.s_srvcompprog, STRING); - break; - case CLNTCOMPPROG: - get_simple((val_t *)&dpcur.clntcompprog, &dpcur.s_clntcompprog, STRING); - break; - case SRV_ENCRYPT: - get_simple((val_t *)&dpcur.srv_encrypt, &dpcur.s_srv_encrypt, STRING); - break; - case CLNT_ENCRYPT: - get_simple((val_t *)&dpcur.clnt_encrypt, &dpcur.s_clnt_encrypt, STRING); - break; - case RBRACE: - done = 1; - break; - case NL: /* empty line */ - break; - case END: /* end of file */ - done = 1; - default: - parserror("dump type parameter expected"); - } - if(tok != NL && tok != END && - /* When a name is specified, we shouldn't consume the NL - after the RBRACE. */ - (tok != RBRACE || name == 0)) - get_conftoken(NL); - } while(!done); - - /* XXX - there was a stupidity check in here for skip-incr and - ** skip-full. This check should probably be somewhere else. */ - - save_dumptype(); + save_dumptype(); allow_overwrites = save_overwrites; - keytable = save_kt; if (linenum) - *linenum = line_num; + *linenum = conf_line_num; if (fname) - confname = saved_fname; + conf_confname = saved_fname; if (from) - conf = saved_conf; + conf_conf = saved_conf; return lookup_dumptype(dpcur.name); } -static void get_dumptype() +static void +get_dumptype(void) { read_dumptype(NULL, NULL, NULL, NULL); } -static void init_dumptype_defaults() -{ - dpcur.comment = stralloc(""); - dpcur.program = stralloc("DUMP"); - dpcur.srvcompprog = stralloc(""); - dpcur.clntcompprog = stralloc(""); - dpcur.srv_encrypt = stralloc(""); - dpcur.clnt_encrypt = stralloc(""); - dpcur.exclude_file = NULL; - dpcur.exclude_list = NULL; - dpcur.include_file = NULL; - dpcur.include_list = NULL; - dpcur.priority = 1; - dpcur.dumpcycle = conf_dumpcycle.i; - dpcur.maxcycle = conf_maxcycle.i; - dpcur.frequency = 1; - dpcur.maxdumps = conf_maxdumps.i; - dpcur.maxpromoteday = 10000; - dpcur.bumppercent = conf_bumppercent.i; - dpcur.bumpsize = conf_bumpsize.i; - dpcur.bumpdays = conf_bumpdays.i; - dpcur.bumpmult = conf_bumpmult.r; - dpcur.start_t = 0; - dpcur.security_driver = stralloc("BSD"); - - /* options */ - dpcur.record = 1; - dpcur.strategy = DS_STANDARD; - dpcur.estimate = ES_CLIENT; - dpcur.compress = COMP_FAST; - dpcur.encrypt = ENCRYPT_NONE; - dpcur.srv_decrypt_opt = stralloc("-d"); - dpcur.clnt_decrypt_opt = stralloc("-d"); - dpcur.comprate[0] = dpcur.comprate[1] = 0.50; - dpcur.skip_incr = dpcur.skip_full = 0; - dpcur.no_hold = 0; - dpcur.kencrypt = 0; - dpcur.ignore = 0; - dpcur.index = 0; - dpcur.tape_splitsize = 0; - dpcur.split_diskbuffer = NULL; - dpcur.fallback_splitsize = 10 * 1024; - - dpcur.s_comment = 0; - dpcur.s_program = 0; - dpcur.s_srvcompprog = 0; - dpcur.s_clntcompprog = 0; - dpcur.s_clnt_encrypt= 0; - dpcur.s_srv_encrypt= 0; - - dpcur.s_exclude_file = 0; - dpcur.s_exclude_list = 0; - dpcur.s_include_file = 0; - dpcur.s_include_list = 0; - dpcur.s_priority = 0; - dpcur.s_dumpcycle = 0; - dpcur.s_maxcycle = 0; - dpcur.s_frequency = 0; - dpcur.s_maxdumps = 0; - dpcur.s_maxpromoteday = 0; - dpcur.s_bumppercent = 0; - dpcur.s_bumpsize = 0; - dpcur.s_bumpdays = 0; - dpcur.s_bumpmult = 0; - dpcur.s_start_t = 0; - dpcur.s_security_driver = 0; - dpcur.s_record = 0; - dpcur.s_strategy = 0; - dpcur.s_estimate = 0; - dpcur.s_compress = 0; - dpcur.s_encrypt = 0; - dpcur.s_srv_decrypt_opt = 0; - dpcur.s_clnt_decrypt_opt = 0; - dpcur.s_comprate = 0; - dpcur.s_skip_incr = 0; - dpcur.s_skip_full = 0; - dpcur.s_no_hold = 0; - dpcur.s_kencrypt = 0; - dpcur.s_ignore = 0; - dpcur.s_index = 0; - dpcur.s_tape_splitsize = 0; - dpcur.s_split_diskbuffer = 0; - dpcur.s_fallback_splitsize = 0; -} - -static void save_dumptype() +static void +init_dumptype_defaults(void) { - dumptype_t *dp; + dpcur.name = NULL; + conf_init_string (&dpcur.value[DUMPTYPE_COMMENT] , ""); + conf_init_string (&dpcur.value[DUMPTYPE_PROGRAM] , "DUMP"); + conf_init_string (&dpcur.value[DUMPTYPE_SRVCOMPPROG] , ""); + conf_init_string (&dpcur.value[DUMPTYPE_CLNTCOMPPROG] , ""); + conf_init_string (&dpcur.value[DUMPTYPE_SRV_ENCRYPT] , ""); + conf_init_string (&dpcur.value[DUMPTYPE_CLNT_ENCRYPT] , ""); + conf_init_string (&dpcur.value[DUMPTYPE_AMANDAD_PATH] , "X"); + conf_init_string (&dpcur.value[DUMPTYPE_CLIENT_USERNAME] , "X"); + conf_init_string (&dpcur.value[DUMPTYPE_SSH_KEYS] , "X"); + conf_init_string (&dpcur.value[DUMPTYPE_SECURITY_DRIVER] , "BSD"); + conf_init_exinclude(&dpcur.value[DUMPTYPE_EXCLUDE]); + conf_init_exinclude(&dpcur.value[DUMPTYPE_INCLUDE]); + conf_init_priority (&dpcur.value[DUMPTYPE_PRIORITY] , 1); + conf_init_int (&dpcur.value[DUMPTYPE_DUMPCYCLE] , server_conf[CNF_DUMPCYCLE].v.i); + conf_init_int (&dpcur.value[DUMPTYPE_MAXDUMPS] , server_conf[CNF_MAXDUMPS].v.i); + conf_init_int (&dpcur.value[DUMPTYPE_MAXPROMOTEDAY] , 10000); + conf_init_int (&dpcur.value[DUMPTYPE_BUMPPERCENT] , server_conf[CNF_BUMPPERCENT].v.i); + conf_init_am64 (&dpcur.value[DUMPTYPE_BUMPSIZE] , server_conf[CNF_BUMPSIZE].v.am64); + conf_init_int (&dpcur.value[DUMPTYPE_BUMPDAYS] , server_conf[CNF_BUMPDAYS].v.i); + conf_init_real (&dpcur.value[DUMPTYPE_BUMPMULT] , server_conf[CNF_BUMPMULT].v.r); + conf_init_time (&dpcur.value[DUMPTYPE_START_T] , (time_t)0); + conf_init_strategy (&dpcur.value[DUMPTYPE_STRATEGY] , DS_STANDARD); + conf_init_estimate (&dpcur.value[DUMPTYPE_ESTIMATE] , ES_CLIENT); + conf_init_compress (&dpcur.value[DUMPTYPE_COMPRESS] , COMP_FAST); + conf_init_encrypt (&dpcur.value[DUMPTYPE_ENCRYPT] , ENCRYPT_NONE); + conf_init_string (&dpcur.value[DUMPTYPE_SRV_DECRYPT_OPT] , "-d"); + conf_init_string (&dpcur.value[DUMPTYPE_CLNT_DECRYPT_OPT] , "-d"); + conf_init_rate (&dpcur.value[DUMPTYPE_COMPRATE] , 0.50, 0.50); + conf_init_am64 (&dpcur.value[DUMPTYPE_TAPE_SPLITSIZE] , (off_t)0); + conf_init_am64 (&dpcur.value[DUMPTYPE_FALLBACK_SPLITSIZE], (off_t)10 * 1024); + conf_init_string (&dpcur.value[DUMPTYPE_SPLIT_DISKBUFFER] , NULL); + conf_init_bool (&dpcur.value[DUMPTYPE_RECORD] , 1); + conf_init_bool (&dpcur.value[DUMPTYPE_SKIP_INCR] , 0); + conf_init_bool (&dpcur.value[DUMPTYPE_SKIP_FULL] , 0); + conf_init_holding (&dpcur.value[DUMPTYPE_HOLDINGDISK] , HOLD_AUTO); + conf_init_bool (&dpcur.value[DUMPTYPE_KENCRYPT] , 0); + conf_init_bool (&dpcur.value[DUMPTYPE_IGNORE] , 0); + conf_init_bool (&dpcur.value[DUMPTYPE_INDEX] , 1); +} + +static void +save_dumptype(void) +{ + dumptype_t *dp, *dp1;; dp = lookup_dumptype(dpcur.name); if(dp != (dumptype_t *)0) { - parserror("dumptype %s already defined on line %d", dp->name, dp->seen); + conf_parserror("dumptype %s already defined on line %d", dp->name, dp->seen); return; } dp = alloc(sizeof(dumptype_t)); - malloc_mark(dp); *dp = dpcur; - dp->next = dumplist; - dumplist = dp; + dp->next = NULL; + /* add at end of list */ + if(!dumplist) + dumplist = dp; + else { + dp1 = dumplist; + while (dp1->next != NULL) { + dp1 = dp1->next; + } + dp1->next = dp; + } } -static void copy_dumptype() +static void +copy_dumptype(void) { dumptype_t *dt; + int i; - dt = lookup_dumptype(tokenval.s); + dt = lookup_dumptype(tokenval.v.s); if(dt == NULL) { - parserror("dump type parameter expected"); + conf_parserror("dumptype parameter expected"); return; } -#define dtcopy(v,s) if(dt->s) { dpcur.v = dt->v; dpcur.s = dt->s; } - - if(dt->s_comment) { - dpcur.comment = newstralloc(dpcur.comment, dt->comment); - dpcur.s_comment = dt->s_comment; - } - if(dt->s_program) { - dpcur.program = newstralloc(dpcur.program, dt->program); - dpcur.s_program = dt->s_program; - } - if(dt->s_security_driver) { - dpcur.security_driver = newstralloc(dpcur.security_driver, - dt->security_driver); - dpcur.s_security_driver = dt->s_security_driver; - } - if(dt->s_srvcompprog) { - dpcur.srvcompprog = newstralloc(dpcur.srvcompprog, dt->srvcompprog); - dpcur.s_srvcompprog = dt->s_srvcompprog; - } - if(dt->s_clntcompprog) { - dpcur.clntcompprog = newstralloc(dpcur.clntcompprog, dt->clntcompprog); - dpcur.s_clntcompprog = dt->s_clntcompprog; - } - if(dt->s_srv_encrypt) { - dpcur.srv_encrypt = newstralloc(dpcur.srv_encrypt, dt->srv_encrypt); - dpcur.s_srv_encrypt = dt->s_srv_encrypt; - } - if(dt->s_clnt_encrypt) { - dpcur.clnt_encrypt = newstralloc(dpcur.clnt_encrypt, dt->clnt_encrypt); - dpcur.s_clnt_encrypt = dt->s_clnt_encrypt; - } - if(dt->s_srv_decrypt_opt) { - dpcur.srv_decrypt_opt = newstralloc(dpcur.srv_decrypt_opt, dt->srv_decrypt_opt); - dpcur.s_srv_decrypt_opt = dt->s_srv_decrypt_opt; - } - if(dt->s_clnt_decrypt_opt) { - dpcur.clnt_decrypt_opt = newstralloc(dpcur.clnt_decrypt_opt, dt->clnt_decrypt_opt); - dpcur.s_clnt_decrypt_opt = dt->s_clnt_decrypt_opt; - } - - if(dt->s_exclude_file) { - dpcur.exclude_file = duplicate_sl(dt->exclude_file); - dpcur.s_exclude_file = dt->s_exclude_file; - } - if(dt->s_exclude_list) { - dpcur.exclude_list = duplicate_sl(dt->exclude_list); - dpcur.s_exclude_list = dt->s_exclude_list; - } - if(dt->s_include_file) { - dpcur.include_file = duplicate_sl(dt->include_file); - dpcur.s_include_file = dt->s_include_file; - } - if(dt->s_include_list) { - dpcur.include_list = duplicate_sl(dt->include_list); - dpcur.s_include_list = dt->s_include_list; - } - dtcopy(priority, s_priority); - dtcopy(dumpcycle, s_dumpcycle); - dtcopy(maxcycle, s_maxcycle); - dtcopy(frequency, s_frequency); - dtcopy(maxdumps, s_maxdumps); - dtcopy(maxpromoteday, s_maxpromoteday); - dtcopy(bumppercent, s_bumppercent); - dtcopy(bumpsize, s_bumpsize); - dtcopy(bumpdays, s_bumpdays); - dtcopy(bumpmult, s_bumpmult); - dtcopy(start_t, s_start_t); - dtcopy(record, s_record); - dtcopy(strategy, s_strategy); - dtcopy(estimate, s_estimate); - dtcopy(compress, s_compress); - dtcopy(encrypt, s_encrypt); - dtcopy(comprate[0], s_comprate); - dtcopy(comprate[1], s_comprate); - dtcopy(skip_incr, s_skip_incr); - dtcopy(skip_full, s_skip_full); - dtcopy(no_hold, s_no_hold); - dtcopy(kencrypt, s_kencrypt); - dtcopy(ignore, s_ignore); - dtcopy(index, s_index); - dtcopy(tape_splitsize, s_tape_splitsize); - dtcopy(split_diskbuffer, s_split_diskbuffer); - dtcopy(fallback_splitsize, s_fallback_splitsize); -} - -keytab_t tapetype_keytable[] = { - { "COMMENT", COMMENT }, - { "LBL-TEMPL", LBL_TEMPL }, - { "BLOCKSIZE", BLOCKSIZE }, - { "FILE-PAD", FILE_PAD }, - { "FILEMARK", FILEMARK }, - { "LENGTH", LENGTH }, - { "SPEED", SPEED }, - { NULL, IDENT } + for(i=0; i < DUMPTYPE_DUMPTYPE; i++) { + if(dt->value[i].seen) { + free_val_t(&dpcur.value[i]); + copy_val_t(&dpcur.value[i], &dt->value[i]); + } + } +} + +t_conf_var tapetype_var [] = { + { CONF_COMMENT , CONFTYPE_STRING, read_string, TAPETYPE_COMMENT , NULL }, + { CONF_LBL_TEMPL, CONFTYPE_STRING, read_string, TAPETYPE_LBL_TEMPL, NULL }, + { CONF_BLOCKSIZE, CONFTYPE_SIZE , read_size , TAPETYPE_BLOCKSIZE, validate_blocksize }, + { CONF_LENGTH , CONFTYPE_AM64 , read_am64 , TAPETYPE_LENGTH , validate_positive0 }, + { CONF_FILEMARK , CONFTYPE_AM64 , read_am64 , TAPETYPE_FILEMARK , NULL }, + { CONF_SPEED , CONFTYPE_INT , read_int , TAPETYPE_SPEED , validate_positive0 }, + { CONF_FILE_PAD , CONFTYPE_BOOL , read_bool , TAPETYPE_FILE_PAD , NULL }, + { CONF_UNKNOWN , CONFTYPE_INT , NULL , TAPETYPE_TAPETYPE , NULL } }; -static void get_tapetype() +static void +get_tapetype(void) { - int done; int save_overwrites; - val_t value; - - keytab_t *save_kt; + char *prefix; save_overwrites = allow_overwrites; allow_overwrites = 1; - save_kt = keytable; - keytable = tapetype_keytable; - init_tapetype_defaults(); - get_conftoken(IDENT); - tpcur.name = stralloc(tokenval.s); - malloc_mark(tpcur.name); - tpcur.seen = line_num; - - get_conftoken(LBRACE); - get_conftoken(NL); - - done = 0; - do { - line_num += 1; - get_conftoken(ANY); - switch(tok) { + get_conftoken(CONF_IDENT); + tpcur.name = stralloc(tokenval.v.s); + tpcur.seen = conf_line_num; - case RBRACE: - done = 1; - break; - case COMMENT: - get_simple((val_t *)&tpcur.comment, &tpcur.s_comment, STRING); - break; - case LBL_TEMPL: - get_simple((val_t *)&tpcur.lbl_templ, &tpcur.s_lbl_templ, STRING); - break; - case BLOCKSIZE: - get_simple((val_t *)&tpcur.blocksize, &tpcur.s_blocksize, LONG); - if(tpcur.blocksize < DISK_BLOCK_KB) { - parserror("Tape blocksize must be at least %d KBytes", - DISK_BLOCK_KB); - } else if(tpcur.blocksize > MAX_TAPE_BLOCK_KB) { - parserror("Tape blocksize must not be larger than %d KBytes", - MAX_TAPE_BLOCK_KB); - } - break; - case FILE_PAD: - get_simple(&value, &tpcur.s_file_pad, BOOL); - tpcur.file_pad = (value.i != 0); - break; - case LENGTH: - get_simple(&value, &tpcur.s_length, LONG); - if(value.l < 0) { - parserror("Tape length must be positive"); - } - else { - tpcur.length = (unsigned long) value.l; - } - break; - case FILEMARK: - get_simple(&value, &tpcur.s_filemark, LONG); - if(value.l < 0) { - parserror("Tape file mark size must be positive"); - } - else { - tpcur.filemark = (unsigned long) value.l; - } - break; - case SPEED: - get_simple((val_t *)&tpcur.speed, &tpcur.s_speed, INT); - if(tpcur.speed < 0) { - parserror("Speed must be positive"); - } - break; - case IDENT: - copy_tapetype(); - break; - case NL: /* empty line */ - break; - case END: /* end of file */ - done = 1; - default: - parserror("tape type parameter expected"); - } - if(tok != NL && tok != END) get_conftoken(NL); - } while(!done); + prefix = vstralloc( "TAPETYPE:", tpcur.name, ":", NULL); + read_block(server_options, tapetype_var, server_keytab, tpcur.value, + prefix, "tapetype parameter expected", 1, ©_tapetype); + amfree(prefix); + get_conftoken(CONF_NL); save_tapetype(); allow_overwrites = save_overwrites; - keytable = save_kt; } -static void init_tapetype_defaults() +static void +init_tapetype_defaults(void) { - tpcur.comment = stralloc(""); - tpcur.lbl_templ = stralloc(""); - tpcur.blocksize = (DISK_BLOCK_KB); - tpcur.file_pad = 1; - tpcur.length = 2000 * 1024; - tpcur.filemark = 1000; - tpcur.speed = 200; - - tpcur.s_comment = 0; - tpcur.s_lbl_templ = 0; - tpcur.s_blocksize = 0; - tpcur.s_file_pad = 0; - tpcur.s_length = 0; - tpcur.s_filemark = 0; - tpcur.s_speed = 0; + conf_init_string(&tpcur.value[TAPETYPE_COMMENT] , ""); + conf_init_string(&tpcur.value[TAPETYPE_LBL_TEMPL], ""); + conf_init_size (&tpcur.value[TAPETYPE_BLOCKSIZE], DISK_BLOCK_KB); + conf_init_am64 (&tpcur.value[TAPETYPE_LENGTH] , (off_t)2000 * 1024); + conf_init_am64 (&tpcur.value[TAPETYPE_FILEMARK] , (off_t)1000); + conf_init_int (&tpcur.value[TAPETYPE_SPEED] , 200); + conf_init_bool (&tpcur.value[TAPETYPE_FILE_PAD] , 1); } -static void save_tapetype() +static void +save_tapetype(void) { - tapetype_t *tp; + tapetype_t *tp, *tp1; tp = lookup_tapetype(tpcur.name); if(tp != (tapetype_t *)0) { amfree(tpcur.name); - parserror("tapetype %s already defined on line %d", tp->name, tp->seen); + conf_parserror("tapetype %s already defined on line %d", tp->name, tp->seen); return; } tp = alloc(sizeof(tapetype_t)); - malloc_mark(tp); *tp = tpcur; - tp->next = tapelist; - tapelist = tp; + /* add at end of list */ + if(!tapelist) + tapelist = tp; + else { + tp1 = tapelist; + while (tp1->next != NULL) { + tp1 = tp1->next; + } + tp1->next = tp; + } } -static void copy_tapetype() +static void +copy_tapetype(void) { tapetype_t *tp; + int i; - tp = lookup_tapetype(tokenval.s); + tp = lookup_tapetype(tokenval.v.s); if(tp == NULL) { - parserror("tape type parameter expected"); + conf_parserror("tape type parameter expected"); return; } -#define ttcopy(v,s) if(tp->s) { tpcur.v = tp->v; tpcur.s = tp->s; } - - if(tp->s_comment) { - tpcur.comment = newstralloc(tpcur.comment, tp->comment); - tpcur.s_comment = tp->s_comment; - } - if(tp->s_lbl_templ) { - tpcur.lbl_templ = newstralloc(tpcur.lbl_templ, tp->lbl_templ); - tpcur.s_lbl_templ = tp->s_lbl_templ; + for(i=0; i < TAPETYPE_TAPETYPE; i++) { + if(tp->value[i].seen) { + free_val_t(&tpcur.value[i]); + copy_val_t(&tpcur.value[i], &tp->value[i]); + } } - ttcopy(blocksize, s_blocksize); - ttcopy(file_pad, s_file_pad); - ttcopy(length, s_length); - ttcopy(filemark, s_filemark); - ttcopy(speed, s_speed); } -keytab_t interface_keytable[] = { - { "COMMENT", COMMENT }, - { "USE", USE }, - { NULL, IDENT } +t_conf_var interface_var [] = { + { CONF_COMMENT, CONFTYPE_STRING, read_string, INTER_COMMENT , NULL }, + { CONF_USE , CONFTYPE_INT , read_int , INTER_MAXUSAGE, validate_positive1 }, + { CONF_UNKNOWN, CONFTYPE_INT , NULL , INTER_INTER , NULL } }; -static void get_interface() +static void +get_interface(void) { - int done; int save_overwrites; - keytab_t *save_kt; + char *prefix; save_overwrites = allow_overwrites; allow_overwrites = 1; - save_kt = keytable; - keytable = interface_keytable; - init_interface_defaults(); - get_conftoken(IDENT); - ifcur.name = stralloc(tokenval.s); - malloc_mark(ifcur.name); - ifcur.seen = line_num; + get_conftoken(CONF_IDENT); + ifcur.name = stralloc(tokenval.v.s); + ifcur.seen = conf_line_num; - get_conftoken(LBRACE); - get_conftoken(NL); - - done = 0; - do { - line_num += 1; - get_conftoken(ANY); - switch(tok) { - - case RBRACE: - done = 1; - break; - case COMMENT: - get_simple((val_t *)&ifcur.comment, &ifcur.s_comment, STRING); - break; - case USE: - get_simple((val_t *)&ifcur.maxusage, &ifcur.s_maxusage, INT); - if(ifcur.maxusage <1) { - parserror("use must bbe positive"); - } - break; - case IDENT: - copy_interface(); - break; - case NL: /* empty line */ - break; - case END: /* end of file */ - done = 1; - default: - parserror("interface parameter expected"); - } - if(tok != NL && tok != END) get_conftoken(NL); - } while(!done); + prefix = vstralloc( "INTERFACE:", ifcur.name, ":", NULL); + read_block(server_options, interface_var, server_keytab, ifcur.value, + prefix, "interface parameter expected", 1, ©_interface); + amfree(prefix); + get_conftoken(CONF_NL); save_interface(); allow_overwrites = save_overwrites; - keytable = save_kt; return; } -static void init_interface_defaults() +static void +init_interface_defaults(void) { - ifcur.comment = stralloc(""); - ifcur.maxusage = 300; - - ifcur.s_comment = 0; - ifcur.s_maxusage = 0; + conf_init_string(&ifcur.value[INTER_COMMENT] , ""); + conf_init_int (&ifcur.value[INTER_MAXUSAGE], 300); ifcur.curusage = 0; } -static void save_interface() +static void +save_interface(void) { - interface_t *ip; + interface_t *ip, *ip1; ip = lookup_interface(ifcur.name); if(ip != (interface_t *)0) { - parserror("interface %s already defined on line %d", ip->name, ip->seen); + conf_parserror("interface %s already defined on line %d", ip->name, + ip->seen); return; } ip = alloc(sizeof(interface_t)); - malloc_mark(ip); *ip = ifcur; - ip->next = interface_list; - interface_list = ip; + /* add at end of list */ + if(!interface_list) { + interface_list = ip; + } else { + ip1 = interface_list; + while (ip1->next != NULL) { + ip1 = ip1->next; + } + ip1->next = ip; + } } -static void copy_interface() +static void +copy_interface(void) { +/* + int i; + t_xxx *np; + keytab_t *kt; + + val_t val; +*/ interface_t *ip; + int i; - ip = lookup_interface(tokenval.s); + ip = lookup_interface(tokenval.v.s); if(ip == NULL) { - parserror("interface parameter expected"); + conf_parserror("interface parameter expected"); return; } -#define ifcopy(v,s) if(ip->s) { ifcur.v = ip->v; ifcur.s = ip->s; } - - if(ip->s_comment) { - ifcur.comment = newstralloc(ifcur.comment, ip->comment); - ifcur.s_comment = ip->s_comment; - } - ifcopy(maxusage, s_maxusage); -} - -keytab_t dumpopts_keytable[] = { - { "COMPRESS", COMPRESS }, - { "ENCRYPT", ENCRYPT }, - { "INDEX", INDEX }, - { "EXCLUDE-FILE", EXCLUDE_FILE }, - { "EXCLUDE-LIST", EXCLUDE_LIST }, - { "KENCRYPT", KENCRYPT }, - { "SKIP-FULL", SKIP_FULL }, - { "SKIP-INCR", SKIP_INCR }, - { NULL, IDENT } -}; - -static void get_dumpopts() /* XXX - for historical compatability */ -{ - int done; - keytab_t *save_kt; - - save_kt = keytable; - keytable = dumpopts_keytable; - - done = 0; - do { - get_conftoken(ANY); - switch(tok) { - case COMPRESS: ckseen(&dpcur.s_compress); dpcur.compress = COMP_FAST; break; - case ENCRYPT: ckseen(&dpcur.s_encrypt); dpcur.encrypt = ENCRYPT_NONE; break; - case EXCLUDE_FILE: - ckseen(&dpcur.s_exclude_file); - get_conftoken(STRING); - dpcur.exclude_file = append_sl(dpcur.exclude_file, tokenval.s); - break; - case EXCLUDE_LIST: - ckseen(&dpcur.s_exclude_list); - get_conftoken(STRING); - dpcur.exclude_list = append_sl(dpcur.exclude_list, tokenval.s); - break; - case KENCRYPT: ckseen(&dpcur.s_kencrypt); dpcur.kencrypt = 1; break; - case SKIP_INCR: ckseen(&dpcur.s_skip_incr); dpcur.skip_incr= 1; break; - case SKIP_FULL: ckseen(&dpcur.s_skip_full); dpcur.skip_full= 1; break; - case INDEX: ckseen(&dpcur.s_index); dpcur.index = 1; break; - case IDENT: - copy_dumptype(); - break; - case NL: done = 1; break; - case COMMA: break; - case END: - done = 1; - default: - parserror("dump option expected"); + for(i=0; i < INTER_INTER; i++) { + if(ip->value[i].seen) { + free_val_t(&ifcur.value[i]); + copy_val_t(&ifcur.value[i], &ip->value[i]); } - } while(!done); - - keytable = save_kt; + } } -static void get_comprate() +static void +get_comprate( + t_conf_var *np, + val_t *val) { - val_t var; - - get_simple(&var, &dpcur.s_comprate, REAL); - dpcur.comprate[0] = dpcur.comprate[1] = var.r; - if(dpcur.comprate[0] < 0) { - parserror("full compression rate must be >= 0"); + np = np; + get_conftoken(CONF_REAL); + val->v.rate[0] = tokenval.v.r; + val->v.rate[1] = tokenval.v.r; + val->seen = tokenval.seen; + if(tokenval.v.r < 0) { + conf_parserror("full compression rate must be >= 0"); } - get_conftoken(ANY); + get_conftoken(CONF_ANY); switch(tok) { - case NL: + case CONF_NL: + return; + + case CONF_END: return; - case COMMA: + + case CONF_COMMA: break; + default: unget_conftoken(); } - get_conftoken(REAL); - dpcur.comprate[1] = tokenval.r; - if(dpcur.comprate[1] < 0) { - parserror("incremental compression rate must be >= 0"); + get_conftoken(CONF_REAL); + val->v.rate[1] = tokenval.v.r; + if(tokenval.v.r < 0) { + conf_parserror("incremental compression rate must be >= 0"); } } -keytab_t compress_keytable[] = { - { "BEST", BEST }, - { "CLIENT", CLIENT }, - { "FAST", FAST }, - { "NONE", NONE }, - { "SERVER", SERVER }, - { "CUSTOM", CUSTOM }, - { NULL, IDENT } -}; - -static void get_compress() +static void +get_compress( + t_conf_var *np, + val_t *val) { - keytab_t *save_kt; int serv, clie, none, fast, best, custom; int done; - int comp; - - save_kt = keytable; - keytable = compress_keytable; + comp_t comp; - ckseen(&dpcur.s_compress); + np = np; + ckseen(&val->seen); serv = clie = none = fast = best = custom = 0; done = 0; do { - get_conftoken(ANY); + get_conftoken(CONF_ANY); switch(tok) { - case NONE: none = 1; break; - case FAST: fast = 1; break; - case BEST: best = 1; break; - case CLIENT: clie = 1; break; - case SERVER: serv = 1; break; - case CUSTOM: custom=1; break; - case NL: done = 1; break; + case CONF_NONE: none = 1; break; + case CONF_FAST: fast = 1; break; + case CONF_BEST: best = 1; break; + case CONF_CLIENT: clie = 1; break; + case CONF_SERVER: serv = 1; break; + case CONF_CUSTOM: custom=1; break; + case CONF_NL: done = 1; break; + case CONF_END: done = 1; break; default: done = 1; serv = clie = 1; /* force an error */ @@ -2281,307 +1614,275 @@ static void get_compress() if(!none && !fast && !best && custom) comp = COMP_SERV_CUST; } - if(comp == -1) { - parserror("NONE, CLIENT FAST, CLIENT BEST, CLIENT CUSTOM, SERVER FAST, SERVER BEST or SERVER CUSTOM expected"); + if((int)comp == -1) { + conf_parserror("NONE, CLIENT FAST, CLIENT BEST, CLIENT CUSTOM, SERVER FAST, SERVER BEST or SERVER CUSTOM expected"); comp = COMP_NONE; } - dpcur.compress = comp; - - keytable = save_kt; + val->v.i = (int)comp; } -keytab_t encrypt_keytable[] = { - { "NONE", NONE }, - { "CLIENT", CLIENT }, - { "SERVER", SERVER }, - { NULL, IDENT } -}; - -static void get_encrypt() +static void +get_encrypt( + t_conf_var *np, + val_t *val) { - keytab_t *save_kt; - int encrypt; - - save_kt = keytable; - keytable = encrypt_keytable; + encrypt_t encrypt; - ckseen(&dpcur.s_encrypt); + np = np; + ckseen(&val->seen); - get_conftoken(ANY); + get_conftoken(CONF_ANY); switch(tok) { - case NONE: + case CONF_NONE: encrypt = ENCRYPT_NONE; break; - case CLIENT: + + case CONF_CLIENT: encrypt = ENCRYPT_CUST; break; - case SERVER: + + case CONF_SERVER: encrypt = ENCRYPT_SERV_CUST; break; + default: - parserror("NONE, CLIENT or SERVER expected"); + conf_parserror("NONE, CLIENT or SERVER expected"); encrypt = ENCRYPT_NONE; + break; } - dpcur.encrypt = encrypt; - keytable = save_kt; + val->v.i = (int)encrypt; } -keytab_t taperalgo_keytable[] = { - { "FIRST", FIRST }, - { "FIRSTFIT", FIRSTFIT }, - { "LARGEST", LARGEST }, - { "LARGESTFIT", LARGESTFIT }, - { "SMALLEST", SMALLEST }, - { "LAST", LAST }, - { NULL, IDENT } -}; - -static void get_taperalgo(c_taperalgo, s_taperalgo) -val_t *c_taperalgo; -int *s_taperalgo; +static void +get_holding( + t_conf_var *np, + val_t *val) { - keytab_t *save_kt; + dump_holdingdisk_t holding; - save_kt = keytable; - keytable = taperalgo_keytable; + np = np; + ckseen(&val->seen); - ckseen(s_taperalgo); + get_conftoken(CONF_ANY); + switch(tok) { + case CONF_NEVER: + holding = HOLD_NEVER; + break; - get_conftoken(ANY); + case CONF_AUTO: + holding = HOLD_AUTO; + break; + + case CONF_REQUIRED: + holding = HOLD_REQUIRED; + break; + + default: /* can be a BOOLEAN */ + unget_conftoken(); + holding = (dump_holdingdisk_t)get_bool(); + if (holding == 0) + holding = HOLD_NEVER; + else if (holding == 1 || holding == 2) + holding = HOLD_AUTO; + else + conf_parserror("NEVER, AUTO or REQUIRED expected"); + break; + } + + val->v.i = (int)holding; +} + +static void +get_taperalgo( + t_conf_var *np, + val_t *val) +{ + np = np; + ckseen(&val->seen); + + get_conftoken(CONF_ANY); switch(tok) { - case FIRST: c_taperalgo->i = ALGO_FIRST; break; - case FIRSTFIT: c_taperalgo->i = ALGO_FIRSTFIT; break; - case LARGEST: c_taperalgo->i = ALGO_LARGEST; break; - case LARGESTFIT: c_taperalgo->i = ALGO_LARGESTFIT; break; - case SMALLEST: c_taperalgo->i = ALGO_SMALLEST; break; - case LAST: c_taperalgo->i = ALGO_LAST; break; + case CONF_FIRST: val->v.i = ALGO_FIRST; break; + case CONF_FIRSTFIT: val->v.i = ALGO_FIRSTFIT; break; + case CONF_LARGEST: val->v.i = ALGO_LARGEST; break; + case CONF_LARGESTFIT: val->v.i = ALGO_LARGESTFIT; break; + case CONF_SMALLEST: val->v.i = ALGO_SMALLEST; break; + case CONF_LAST: val->v.i = ALGO_LAST; break; default: - parserror("FIRST, FIRSTFIT, LARGEST, LARGESTFIT, SMALLEST or LAST expected"); + conf_parserror("FIRST, FIRSTFIT, LARGEST, LARGESTFIT, SMALLEST or LAST expected"); } - - keytable = save_kt; } -keytab_t priority_keytable[] = { - { "HIGH", HIGH }, - { "LOW", LOW }, - { "MEDIUM", MEDIUM }, - { NULL, IDENT } -}; - -static void get_priority() +static void +get_priority( + t_conf_var *np, + val_t *val) { int pri; - keytab_t *save_kt; - - save_kt = keytable; - keytable = priority_keytable; - ckseen(&dpcur.s_priority); + np = np; + ckseen(&val->seen); - get_conftoken(ANY); + get_conftoken(CONF_ANY); switch(tok) { - case LOW: pri = 0; break; - case MEDIUM: pri = 1; break; - case HIGH: pri = 2; break; - case INT: pri = tokenval.i; break; + case CONF_LOW: pri = 0; break; + case CONF_MEDIUM: pri = 1; break; + case CONF_HIGH: pri = 2; break; + case CONF_INT: pri = tokenval.v.i; break; default: - parserror("LOW, MEDIUM, HIGH or integer expected"); + conf_parserror("LOW, MEDIUM, HIGH or integer expected"); pri = 0; } - dpcur.priority = pri; - - keytable = save_kt; + val->v.i = pri; } -keytab_t strategy_keytable[] = { - { "HANOI", HANOI }, - { "NOFULL", NOFULL }, - { "NOINC", NOINC }, - { "SKIP", SKIP }, - { "STANDARD", STANDARD }, - { "INCRONLY", INCRONLY }, - { NULL, IDENT } -}; - -static void get_strategy() +static void +get_strategy( + t_conf_var *np, + val_t *val) { int strat; - keytab_t *save_kt; - - save_kt = keytable; - keytable = strategy_keytable; - ckseen(&dpcur.s_strategy); + np = np; + ckseen(&val->seen); - get_conftoken(ANY); + get_conftoken(CONF_ANY); switch(tok) { - case SKIP: + case CONF_SKIP: strat = DS_SKIP; break; - case STANDARD: + case CONF_STANDARD: strat = DS_STANDARD; break; - case NOFULL: + case CONF_NOFULL: strat = DS_NOFULL; break; - case NOINC: + case CONF_NOINC: strat = DS_NOINC; break; - case HANOI: + case CONF_HANOI: strat = DS_HANOI; break; - case INCRONLY: + case CONF_INCRONLY: strat = DS_INCRONLY; break; default: - parserror("STANDARD or NOFULL expected"); + conf_parserror("STANDARD or NOFULL expected"); strat = DS_STANDARD; } - dpcur.strategy = strat; - - keytable = save_kt; + val->v.i = strat; } -keytab_t estimate_keytable[] = { - { "CLIENT", CLIENT }, - { "SERVER", SERVER }, - { "CALCSIZE", CALCSIZE } -}; - -static void get_estimate() +static void +get_estimate( + t_conf_var *np, + val_t *val) { int estime; - keytab_t *save_kt; - save_kt = keytable; - keytable = estimate_keytable; + np = np; + ckseen(&val->seen); - ckseen(&dpcur.s_estimate); - - get_conftoken(ANY); + get_conftoken(CONF_ANY); switch(tok) { - case CLIENT: + case CONF_CLIENT: estime = ES_CLIENT; break; - case SERVER: + case CONF_SERVER: estime = ES_SERVER; break; - case CALCSIZE: + case CONF_CALCSIZE: estime = ES_CALCSIZE; break; default: - parserror("CLIENT, SERVER or CALCSIZE expected"); + conf_parserror("CLIENT, SERVER or CALCSIZE expected"); estime = ES_CLIENT; } - dpcur.estimate = estime; - - keytable = save_kt; + val->v.i = estime; } -keytab_t exclude_keytable[] = { - { "LIST", LIST }, - { "FILE", EFILE }, - { "APPEND", APPEND }, - { "OPTIONAL", OPTIONAL }, - { NULL, IDENT } -}; - -static void get_exclude() +static void +get_exclude( + t_conf_var *np, + val_t *val) { - int list, got_one = 0; - keytab_t *save_kt; + int file, got_one = 0; sl_t *exclude; int optional = 0; - int append = 0; - save_kt = keytable; - keytable = exclude_keytable; - - get_conftoken(ANY); - if(tok == LIST) { - list = 1; - exclude = dpcur.exclude_list; - ckseen(&dpcur.s_exclude_list); - get_conftoken(ANY); + np = np; + get_conftoken(CONF_ANY); + if(tok == CONF_LIST) { + file = 0; + get_conftoken(CONF_ANY); } else { - list = 0; - exclude = dpcur.exclude_file; - ckseen(&dpcur.s_exclude_file); - if(tok == EFILE) get_conftoken(ANY); + file = 1; + if(tok == CONF_EFILE) get_conftoken(CONF_ANY); } + val->v.exinclude.type = file; + exclude = val->v.exinclude.sl; + ckseen(&val->seen); - if(tok == OPTIONAL) { - get_conftoken(ANY); + if(tok == CONF_OPTIONAL) { + get_conftoken(CONF_ANY); optional = 1; } - if(tok == APPEND) { - get_conftoken(ANY); - append = 1; + if(tok == CONF_APPEND) { + get_conftoken(CONF_ANY); } else { free_sl(exclude); exclude = NULL; - append = 0; } - while(tok == STRING) { - exclude = append_sl(exclude, tokenval.s); + while(tok == CONF_STRING) { + exclude = append_sl(exclude, tokenval.v.s); got_one = 1; - get_conftoken(ANY); + get_conftoken(CONF_ANY); } unget_conftoken(); if(got_one == 0) { free_sl(exclude); exclude = NULL; } - if(list == 0) - dpcur.exclude_file = exclude; - else { - dpcur.exclude_list = exclude; - if(!append || optional) - dpcur.exclude_optional = optional; - } - - keytable = save_kt; + val->v.exinclude.sl = exclude; + val->v.exinclude.optional = optional; } - -static void get_include() +/* +static void get_include(np, val) + t_conf_var *np; + val_t *val; { int list, got_one = 0; - keytab_t *save_kt; sl_t *include; int optional = 0; int append = 0; - save_kt = keytable; - keytable = exclude_keytable; - - get_conftoken(ANY); - if(tok == LIST) { + get_conftoken(CONF_ANY); + if(tok == CONF_LIST) { list = 1; - include = dpcur.include_list; - ckseen(&dpcur.s_include_list); - get_conftoken(ANY); + include = dpcur.value[DUMPTYPE_INCLUDE_LIST].v.sl; + ckseen(&dpcur.value[DUMPTYPE_INCLUDE_LIST].seen); + get_conftoken(CONF_ANY); } else { list = 0; - include = dpcur.include_file; - ckseen(&dpcur.s_include_file); - if(tok == EFILE) get_conftoken(ANY); + include = dpcur.value[DUMPTYPE_INCLUDE_FILE].v.sl; + ckseen(&dpcur.value[DUMPTYPE_INCLUDE_FILE].seen); + if(tok == CONF_EFILE) get_conftoken(CONF_ANY); } - if(tok == OPTIONAL) { - get_conftoken(ANY); + if(tok == CONF_OPTIONAL) { + get_conftoken(CONF_ANY); optional = 1; } - if(tok == APPEND) { - get_conftoken(ANY); + if(tok == CONF_APPEND) { + get_conftoken(CONF_ANY); append = 1; } else { @@ -2590,581 +1891,38 @@ static void get_include() append = 0; } - while(tok == STRING) { - include = append_sl(include, tokenval.s); + while(tok == CONF_STRING) { + include = append_sl(include, tokenval.v.s); got_one = 1; - get_conftoken(ANY); + get_conftoken(CONF_ANY); } unget_conftoken(); if(got_one == 0) { free_sl(include); include = NULL; } if(list == 0) - dpcur.include_file = include; + dpcur.value[DUMPTYPE_INCLUDE_FILE].v.sl = include; else { - dpcur.include_list = include; + dpcur.value[DUMPTYPE_INCLUDE_LIST].v.sl = include; if(!append || optional) - dpcur.include_optional = optional; + dpcur.value[DUMPTYPE_INCLUDE_OPTIONAL].v.i = optional; } - - keytable = save_kt; } - +*/ /* ------------------------ */ - -static void get_simple(var, seen, type) -val_t *var; -int *seen; -tok_t type; -{ - ckseen(seen); - - switch(type) { - case STRING: - case IDENT: - get_conftoken(type); - var->s = newstralloc(var->s, tokenval.s); - malloc_mark(var->s); - break; - case INT: - var->i = get_int(); - break; - case LONG: - var->l = get_long(); - break; - case AM64: - var->am64 = get_am64_t(); - break; - case BOOL: - var->i = get_bool(); - break; - case REAL: - get_conftoken(REAL); - var->r = tokenval.r; - break; - case TIME: - var->i = get_time(); - break; - default: - error("error [unknown get_simple type: %d]", type); - /* NOTREACHED */ - } - return; -} - -static int get_time() -{ - time_t st = start_time.r.tv_sec; - struct tm *stm; - int hhmm; - - get_conftoken(INT); - hhmm = tokenval.i; - - stm = localtime(&st); - st -= stm->tm_sec + 60 * (stm->tm_min + 60 * stm->tm_hour); - st += ((hhmm/100*60) + hhmm%100)*60; - - if (st-start_time.r.tv_sec<-43200) - st += 86400; - - return st; -} - -keytab_t numb_keytable[] = { - { "B", MULT1 }, - { "BPS", MULT1 }, - { "BYTE", MULT1 }, - { "BYTES", MULT1 }, - { "DAY", MULT1 }, - { "DAYS", MULT1 }, - { "INF", INFINITY }, - { "K", MULT1K }, - { "KB", MULT1K }, - { "KBPS", MULT1K }, - { "KBYTE", MULT1K }, - { "KBYTES", MULT1K }, - { "KILOBYTE", MULT1K }, - { "KILOBYTES", MULT1K }, - { "KPS", MULT1K }, - { "M", MULT1M }, - { "MB", MULT1M }, - { "MBPS", MULT1M }, - { "MBYTE", MULT1M }, - { "MBYTES", MULT1M }, - { "MEG", MULT1M }, - { "MEGABYTE", MULT1M }, - { "MEGABYTES", MULT1M }, - { "G", MULT1G }, - { "GB", MULT1G }, - { "GBPS", MULT1G }, - { "GBYTE", MULT1G }, - { "GBYTES", MULT1G }, - { "GIG", MULT1G }, - { "GIGABYTE", MULT1G }, - { "GIGABYTES", MULT1G }, - { "MPS", MULT1M }, - { "TAPE", MULT1 }, - { "TAPES", MULT1 }, - { "WEEK", MULT7 }, - { "WEEKS", MULT7 }, - { NULL, IDENT } -}; - -static int get_int() -{ - int val; - keytab_t *save_kt; - - save_kt = keytable; - keytable = numb_keytable; - - get_conftoken(ANY); - - switch(tok) { - case AM64: - if(abs(tokenval.am64) > INT_MAX) - parserror("value too large"); - val = (int) tokenval.am64; - break; - case INFINITY: - val = (int) BIGINT; - break; - default: - parserror("an integer expected"); - val = 0; - } - - /* get multiplier, if any */ - get_conftoken(ANY); - - switch(tok) { - case NL: /* multiply by one */ - case MULT1: - case MULT1K: - break; - case MULT7: - if(abs(val) > INT_MAX/7) - parserror("value too large"); - val *= 7; - break; - case MULT1M: - if(abs(val) > INT_MAX/1024) - parserror("value too large"); - val *= 1024; - break; - case MULT1G: - if(abs(val) > INT_MAX/(1024*1024)) - parserror("value too large"); - val *= 1024*1024; - break; - default: /* it was not a multiplier */ - unget_conftoken(); - } - - keytable = save_kt; - - return val; -} - -static long get_long() -{ - long val; - keytab_t *save_kt; - - save_kt = keytable; - keytable = numb_keytable; - - get_conftoken(ANY); - - switch(tok) { - case AM64: - if(tokenval.am64 > LONG_MAX || tokenval.am64 < LONG_MIN) - parserror("value too large"); - val = (long) tokenval.am64; - break; - case INFINITY: - val = (long) LONG_MAX; - break; - default: - parserror("a long expected"); - val = 0; - } - - /* get multiplier, if any */ - get_conftoken(ANY); - - switch(tok) { - case NL: /* multiply by one */ - case MULT1: - case MULT1K: - break; - case MULT7: - if(val > LONG_MAX/7 || val < LONG_MIN/7) - parserror("value too large"); - val *= 7; - break; - case MULT1M: - if(val > LONG_MAX/1024 || val < LONG_MIN/7) - parserror("value too large"); - val *= 1024; - break; - case MULT1G: - if(val > LONG_MAX/(1024*1024) || val < LONG_MIN/(1024*1024)) - parserror("value too large"); - val *= 1024*1024; - break; - default: /* it was not a multiplier */ - unget_conftoken(); - } - - keytable = save_kt; - - return val; -} - -static am64_t get_am64_t() -{ - am64_t val; - keytab_t *save_kt; - - save_kt = keytable; - keytable = numb_keytable; - - get_conftoken(ANY); - - switch(tok) { - case AM64: - val = tokenval.am64; - break; - case INFINITY: - val = AM64_MAX; - break; - default: - parserror("a am64 expected %d", tok); - val = 0; - } - - /* get multiplier, if any */ - get_conftoken(ANY); - - switch(tok) { - case NL: /* multiply by one */ - case MULT1: - case MULT1K: - break; - case MULT7: - if(val > AM64_MAX/7 || val < AM64_MIN/7) - parserror("value too large"); - val *= 7; - break; - case MULT1M: - if(val > AM64_MAX/1024 || val < AM64_MIN/1024) - parserror("value too large"); - val *= 1024; - break; - case MULT1G: - if(val > AM64_MAX/(1024*1024) || val < AM64_MIN/(1024*1024)) - parserror("value too large"); - val *= 1024*1024; - break; - default: /* it was not a multiplier */ - unget_conftoken(); - } - - keytable = save_kt; - - return val; -} - -keytab_t bool_keytable[] = { - { "Y", ATRUE }, - { "YES", ATRUE }, - { "T", ATRUE }, - { "TRUE", ATRUE }, - { "ON", ATRUE }, - { "N", AFALSE }, - { "NO", AFALSE }, - { "F", AFALSE }, - { "FALSE", AFALSE }, - { "OFF", AFALSE }, - { NULL, IDENT } -}; - -static int get_bool() -{ - int val; - keytab_t *save_kt; - - save_kt = keytable; - keytable = bool_keytable; - - get_conftoken(ANY); - - switch(tok) { - case INT: - val = tokenval.i ? 1 : 0; - break; - case ATRUE: - val = 1; - break; - case AFALSE: - val = 0; - break; - case NL: - default: - unget_conftoken(); - val = 2; /* no argument - most likely TRUE */ - } - - keytable = save_kt; - - return val; -} - -static void ckseen(seen) -int *seen; -{ - if(*seen && !allow_overwrites) { - parserror("duplicate parameter, prev def on line %d", *seen); - } - *seen = line_num; -} - -printf_arglist_function(static void parserror, char *, format) -{ - va_list argp; - - /* print error message */ - - fprintf(stderr, "\"%s\", line %d: ", confname, line_num); - arglist_start(argp, format); - vfprintf(stderr, format, argp); - arglist_end(argp); - fputc('\n', stderr); - - got_parserror = 1; -} - -static tok_t lookup_keyword(str) -char *str; -{ - keytab_t *kwp; - - /* switch to binary search if performance warrants */ - - for(kwp = keytable; kwp->keyword != NULL; kwp++) { - if(strcmp(kwp->keyword, str) == 0) break; - } - return kwp->token; -} - -static char tkbuf[4096]; - -/* push the last token back (can only unget ANY tokens) */ -static void unget_conftoken() -{ - token_pushed = 1; - pushed_tok = tok; - tok = UNKNOWN; - return; -} - -static void get_conftoken(exp) -tok_t exp; -{ - int ch, d; - am64_t am64; - char *buf; - int token_overflow; - - if(token_pushed) { - token_pushed = 0; - tok = pushed_tok; - - /* If it looked like a key word before then look it - ** up again in the current keyword table. */ - switch(tok) { - case LONG: case AM64: - case INT: case REAL: case STRING: - case LBRACE: case RBRACE: case COMMA: - case NL: case END: case UNKNOWN: - break; - default: - if(exp == IDENT) tok = IDENT; - else tok = lookup_keyword(tokenval.s); - } - } - else { - ch = getc(conf); - - while(ch != EOF && ch != '\n' && isspace(ch)) ch = getc(conf); - if(ch == '#') { /* comment - eat everything but eol/eof */ - while((ch = getc(conf)) != EOF && ch != '\n') {} - } - - if(isalpha(ch)) { /* identifier */ - buf = tkbuf; - token_overflow = 0; - do { - if(islower(ch)) ch = toupper(ch); - if(buf < tkbuf+sizeof(tkbuf)-1) { - *buf++ = ch; - } else { - *buf = '\0'; - if(!token_overflow) { - parserror("token too long: %.20s...", tkbuf); - } - token_overflow = 1; - } - ch = getc(conf); - } while(isalnum(ch) || ch == '_' || ch == '-'); - - ungetc(ch, conf); - *buf = '\0'; - - tokenval.s = tkbuf; - - if(token_overflow) tok = UNKNOWN; - else if(exp == IDENT) tok = IDENT; - else tok = lookup_keyword(tokenval.s); - } - else if(isdigit(ch)) { /* integer */ - int sign; - if (1) { - sign = 1; - } else { - negative_number: /* look for goto negative_number below */ - sign = -1; - } - tokenval.am64 = 0; - do { - tokenval.am64 = tokenval.am64 * 10 + (ch - '0'); - ch = getc(conf); - } while(isdigit(ch)); - if(ch != '.') { - if(exp == INT) { - tok = INT; - tokenval.i *= sign; - } - else if(exp == LONG) { - tok = LONG; - tokenval.l *= sign; - } - else if(exp != REAL) { - tok = AM64; - tokenval.am64 *= sign; - } else { - /* automatically convert to real when expected */ - am64 = tokenval.am64; - tokenval.r = sign * (double) am64; - tok = REAL; - } - } - else { - /* got a real number, not an int */ - am64 = tokenval.am64; - tokenval.r = sign * (double) am64; - am64=0; d=1; - ch = getc(conf); - while(isdigit(ch)) { - am64 = am64 * 10 + (ch - '0'); - d = d * 10; - ch = getc(conf); - } - tokenval.r += sign * ((double)am64)/d; - tok = REAL; - } - ungetc(ch,conf); - } - else switch(ch) { - - case '"': /* string */ - buf = tkbuf; - token_overflow = 0; - ch = getc(conf); - while(ch != '"' && ch != '\n' && ch != EOF) { - if(buf < tkbuf+sizeof(tkbuf)-1) { - *buf++ = ch; - } else { - *buf = '\0'; - if(!token_overflow) { - parserror("string too long: %.20s...", tkbuf); - } - token_overflow = 1; - } - ch = getc(conf); - } - if(ch != '"') { - parserror("missing end quote"); - ungetc(ch, conf); - } - *buf = '\0'; - tokenval.s = tkbuf; - if(token_overflow) tok = UNKNOWN; - else tok = STRING; - break; - - case '-': - ch = getc(conf); - if (isdigit(ch)) - goto negative_number; - else { - ungetc(ch, conf); - tok = UNKNOWN; - } - break; - case ',': tok = COMMA; break; - case '{': tok = LBRACE; break; - case '}': tok = RBRACE; break; - case '\n': tok = NL; break; - case EOF: tok = END; break; - default: tok = UNKNOWN; - } - } - - if(exp != ANY && tok != exp) { - char *str; - keytab_t *kwp; - - switch(exp) { - case LBRACE: str = "\"{\""; break; - case RBRACE: str = "\"}\""; break; - case COMMA: str = "\",\""; break; - - case NL: str = "end of line"; break; - case END: str = "end of file"; break; - case INT: str = "an integer"; break; - case REAL: str = "a real number"; break; - case STRING: str = "a quoted string"; break; - case IDENT: str = "an identifier"; break; - default: - for(kwp = keytable; kwp->keyword != NULL; kwp++) - if(exp == kwp->token) break; - if(kwp->keyword == NULL) str = "token not"; - else str = kwp->keyword; - } - parserror("%s expected", str); - tok = exp; - if(tok == INT) tokenval.i = 0; - else tokenval.s = ""; - } - - return; -} - -int ColumnDataCount() +int +ColumnDataCount(void ) { - return sizeof(ColumnData) / sizeof(ColumnData[0]); + return (int)(SIZEOF(ColumnData) / SIZEOF(ColumnData[0])); } /* conversion from string to table index */ int -StringToColumn(s) - char *s; +StringToColumn( + char *s) { int cn; @@ -3177,18 +1935,23 @@ StringToColumn(s) } char -LastChar(s) - char *s; +LastChar( + char *s) { return s[strlen(s)-1]; } int -SetColumDataFromString(ci, s, errstr) - ColumnInfo* ci; - char *s; - char **errstr; +SetColumDataFromString( + ColumnInfo* ci, + char *s, + char **errstr) { +#ifdef TEST + char *myname= "SetColumDataFromString"; +#endif + ci = ci; + /* Convert from a Columspec string to our internal format * of columspec. The purpose is to provide this string * as configuration paramter in the amanda.conf file or @@ -3214,9 +1977,6 @@ SetColumDataFromString(ci, s, errstr) * output as it was all the time. * ElB, 1999-02-24. */ -#ifdef TEST - char *myname= "SetColumDataFromString"; -#endif while (s && *s) { int Space, Width; @@ -3247,7 +2007,7 @@ SetColumDataFromString(ci, s, errstr) return -1; } ColumnData[cn].Width= Width; - ColumnData[cn].PrefixSpace= Space; + ColumnData[cn].PrefixSpace = Space; if (LastChar(ColumnData[cn].Format) == 's') { if (Width < 0) ColumnData[cn].MaxWidth= 1; @@ -3256,7 +2016,7 @@ SetColumDataFromString(ci, s, errstr) ColumnData[cn].Precision= Width; } else if (Width < ColumnData[cn].Precision) - ColumnData[cn].Precision= Width; + ColumnData[cn].Precision = Width; s= strchr(eon+1, ','); if (s != NULL) s++; @@ -3265,19 +2025,8 @@ SetColumDataFromString(ci, s, errstr) } -char *taperalgo2str(taperalgo) -int taperalgo; -{ - if(taperalgo == ALGO_FIRST) return "FIRST"; - if(taperalgo == ALGO_FIRSTFIT) return "FIRSTFIT"; - if(taperalgo == ALGO_LARGEST) return "LARGEST"; - if(taperalgo == ALGO_LARGESTFIT) return "LARGESTFIT"; - if(taperalgo == ALGO_SMALLEST) return "SMALLEST"; - if(taperalgo == ALGO_LAST) return "LAST"; - return "UNKNOWN"; -} - -long int getconf_unit_divisor() +long int +getconf_unit_divisor(void) { return unit_divisor; } @@ -3285,242 +2034,129 @@ long int getconf_unit_divisor() /* ------------------------ */ -#ifdef TEST - void -dump_configuration(filename) - char *filename; +dump_configuration( + char *filename) { tapetype_t *tp; dumptype_t *dp; interface_t *ip; holdingdisk_t *hp; - time_t st; - struct tm *stm; + int i; + t_conf_var *np; + keytab_t *kt; + char *prefix; printf("AMANDA CONFIGURATION FROM FILE \"%s\":\n\n", filename); - printf("conf_org = \"%s\"\n", getconf_str(CNF_ORG)); - printf("conf_mailto = \"%s\"\n", getconf_str(CNF_MAILTO)); - printf("conf_dumpuser = \"%s\"\n", getconf_str(CNF_DUMPUSER)); - printf("conf_printer = \"%s\"\n", getconf_str(CNF_PRINTER)); - printf("conf_tapedev = \"%s\"\n", getconf_str(CNF_TAPEDEV)); - printf("conf_rawtapedev = \"%s\"\n", getconf_str(CNF_RAWTAPEDEV)); - printf("conf_tpchanger = \"%s\"\n", getconf_str(CNF_TPCHANGER)); - printf("conf_chngrdev = \"%s\"\n", getconf_str(CNF_CHNGRDEV)); - printf("conf_chngrfile = \"%s\"\n", getconf_str(CNF_CHNGRFILE)); - printf("conf_labelstr = \"%s\"\n", getconf_str(CNF_LABELSTR)); - printf("conf_tapelist = \"%s\"\n", getconf_str(CNF_TAPELIST)); - printf("conf_infofile = \"%s\"\n", getconf_str(CNF_INFOFILE)); - printf("conf_logdir = \"%s\"\n", getconf_str(CNF_LOGDIR)); - printf("conf_diskfile = \"%s\"\n", getconf_str(CNF_DISKFILE)); - printf("conf_tapetype = \"%s\"\n", getconf_str(CNF_TAPETYPE)); - - printf("conf_dumpcycle = %d\n", getconf_int(CNF_DUMPCYCLE)); - printf("conf_runspercycle = %d\n", getconf_int(CNF_RUNSPERCYCLE)); - printf("conf_runtapes = %d\n", getconf_int(CNF_RUNTAPES)); - printf("conf_tapecycle = %d\n", getconf_int(CNF_TAPECYCLE)); - printf("conf_bumppercent = %d\n", getconf_int(CNF_BUMPPERCENT)); - printf("conf_bumpsize = %d\n", getconf_int(CNF_BUMPSIZE)); - printf("conf_bumpdays = %d\n", getconf_int(CNF_BUMPDAYS)); - printf("conf_bumpmult = %f\n", getconf_real(CNF_BUMPMULT)); - printf("conf_netusage = %d\n", getconf_int(CNF_NETUSAGE)); - printf("conf_inparallel = %d\n", getconf_int(CNF_INPARALLEL)); - printf("conf_dumporder = \"%s\"\n", getconf_str(CNF_DUMPORDER)); - /*printf("conf_timeout = %d\n", getconf_int(CNF_TIMEOUT));*/ - printf("conf_maxdumps = %d\n", getconf_int(CNF_MAXDUMPS)); - printf("conf_etimeout = %d\n", getconf_int(CNF_ETIMEOUT)); - printf("conf_dtimeout = %d\n", getconf_int(CNF_DTIMEOUT)); - printf("conf_ctimeout = %d\n", getconf_int(CNF_CTIMEOUT)); - printf("conf_tapebufs = %d\n", getconf_int(CNF_TAPEBUFS)); - printf("conf_autoflush = %d\n", getconf_int(CNF_AUTOFLUSH)); - printf("conf_reserve = %d\n", getconf_int(CNF_RESERVE)); - printf("conf_maxdumpsize = " AM64_FMT "\n", getconf_am64(CNF_MAXDUMPSIZE)); - printf("conf_amrecover_do_fsf = %d\n", getconf_int(CNF_AMRECOVER_DO_FSF)); - printf("conf_amrecover_check_label = %d\n", getconf_int(CNF_AMRECOVER_CHECK_LABEL)); - printf("conf_amrecover_changer = \"%s\"\n", getconf_str(CNF_AMRECOVER_CHANGER)); - printf("conf_taperalgo = %s\n", taperalgo2str(getconf_int(CNF_TAPERALGO))); - printf("conf_displayunit = %s\n", getconf_str(CNF_DISPLAYUNIT)); - - /*printf("conf_diskdir = \"%s\"\n", getconf_str(CNF_DISKDIR));*/ - /*printf("conf_disksize = %d\n", getconf_int(CNF_DISKSIZE));*/ - printf("conf_columnspec = \"%s\"\n", getconf_str(CNF_COLUMNSPEC)); - printf("conf_indexdir = \"%s\"\n", getconf_str(CNF_INDEXDIR)); - printf("num_holdingdisks = %d\n", num_holdingdisks); - printf("conf_krb5keytab = \"%s\"\n", getconf_str(CNF_KRB5KEYTAB)); - printf("conf_krb5principal = \"%s\"\n", getconf_str(CNF_KRB5PRINCIPAL)); - printf("conf_label_new_tapes = \"%s\"\n", getconf_str(CNF_LABEL_NEW_TAPES)); - for(hp = holdingdisks; hp != NULL; hp = hp->next) { - printf("\nHOLDINGDISK %s:\n", hp->name); - printf(" COMMENT \"%s\"\n", hp->comment); - printf(" DISKDIR \"%s\"\n", hp->diskdir); - printf(" SIZE %ld\n", (long)hp->disksize); - printf(" CHUNKSIZE %ld\n", (long)hp->chunksize); - } + for(i=0; i < CNF_CNF; i++) { + for(np=server_var; np->token != CONF_UNKNOWN; np++) { + if(np->parm == i) + break; + } + if(np->token == CONF_UNKNOWN) + error("server bad value"); - for(tp = tapelist; tp != NULL; tp = tp->next) { - printf("\nTAPETYPE %s:\n", tp->name); - printf(" COMMENT \"%s\"\n", tp->comment); - printf(" LBL_TEMPL %s\n", tp->lbl_templ); - printf(" BLOCKSIZE %ld\n", (long)tp->blocksize); - printf(" FILE_PAD %s\n", (tp->file_pad) ? "YES" : "NO"); - printf(" LENGTH %lu\n", (unsigned long)tp->length); - printf(" FILEMARK %lu\n", (unsigned long)tp->filemark); - printf(" SPEED %ld\n", (long)tp->speed); + for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++) + if(kt->token == np->token) break; + if(kt->token == CONF_UNKNOWN) + error("server bad token"); + + printf("%-21s %s\n", kt->keyword, conf_print(&server_conf[i])); } - for(dp = dumplist; dp != NULL; dp = dp->next) { - printf("\nDUMPTYPE %s:\n", dp->name); - printf(" COMMENT \"%s\"\n", dp->comment); - printf(" PROGRAM \"%s\"\n", dp->program); - printf(" SERVER_CUSTOM_COMPRESS \"%s\"\n", dp->srvcompprog); - printf(" CLIENT_CUSTOM_COMPRESS \"%s\"\n", dp->clntcompprog); - printf(" SERVER_ENCRYPT \"%s\"\n", dp->srv_encrypt); - printf(" CLIENT_ENCRYPT \"%s\"\n", dp->clnt_encrypt); - printf(" SERVER_DECRYPT_OPTION \"%s\"\n", dp->srv_decrypt_opt); - printf(" CLIENT_DECRYPT_OPTION \"%s\"\n", dp->clnt_decrypt_opt); - printf(" PRIORITY %ld\n", (long)dp->priority); - printf(" DUMPCYCLE %ld\n", (long)dp->dumpcycle); - st = dp->start_t; - if(st) { - stm = localtime(&st); - printf(" STARTTIME %d:%02d:%02d\n", - stm->tm_hour, stm->tm_min, stm->tm_sec); - } - if(dp->exclude_file) { - sle_t *excl; - printf(" EXCLUDE FILE"); - for(excl = dp->exclude_file->first; excl != NULL; excl =excl->next){ - printf(" \"%s\"", excl->name); - } - printf("\n"); - } - if(dp->exclude_list) { - sle_t *excl; - printf(" EXCLUDE LIST"); - for(excl = dp->exclude_list->first; excl != NULL; excl =excl->next){ - printf(" \"%s\"", excl->name); - } - printf("\n"); - } - if(dp->include_file) { - sle_t *incl; - printf(" INCLUDE FILE"); - for(incl = dp->include_file->first; incl != NULL; incl =incl->next){ - printf(" \"%s\"", incl->name); - } - printf("\n"); - } - if(dp->include_list) { - sle_t *incl; - printf(" INCLUDE LIST"); - for(incl = dp->include_list->first; incl != NULL; incl =incl->next){ - printf(" \"%s\"", incl->name); + for(hp = holdingdisks; hp != NULL; hp = hp->next) { + printf("\nHOLDINGDISK %s {\n", hp->name); + for(i=0; i < HOLDING_HOLDING; i++) { + for(np=holding_var; np->token != CONF_UNKNOWN; np++) { + if(np->parm == i) + break; } - printf("\n"); - } - printf(" FREQUENCY %ld\n", (long)dp->frequency); - printf(" MAXDUMPS %d\n", dp->maxdumps); - printf(" MAXPROMOTEDAY %d\n", dp->maxpromoteday); - printf(" STRATEGY "); - switch(dp->strategy) { - case DS_SKIP: - printf("SKIP"); - break; - case DS_STANDARD: - printf("STANDARD"); - break; - case DS_NOFULL: - printf("NOFULL"); - break; - case DS_NOINC: - printf("NOINC"); - break; - case DS_HANOI: - printf("HANOI"); - break; - case DS_INCRONLY: - printf("INCRONLY"); - break; - } - putchar('\n'); - printf(" ESTIMATE "); - switch(dp->estimate) { - case ES_CLIENT: - printf("CLIENT"); - break; - case ES_SERVER: - printf("SERVER"); - break; - case ES_CALCSIZE: - printf("CALCSIZE"); - break; - } - putchar('\n'); - printf(" COMPRATE %f, %f\n", dp->comprate[0], dp->comprate[1]); + if(np->token == CONF_UNKNOWN) + error("holding bad value"); - printf(" OPTIONS: "); + for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++) { + if(kt->token == np->token) + break; + } + if(kt->token == CONF_UNKNOWN) + error("holding bad token"); - switch(dp->compress) { - case COMP_NONE: - printf("NO-COMPRESS "); - break; - case COMP_FAST: - printf("COMPRESS-FAST "); - break; - case COMP_BEST: - printf("COMPRESS-BEST "); - break; - case COMP_CUST: - printf("COMPRESS-CUST "); - break; - case COMP_SERV_FAST: - printf("SRVCOMP-FAST "); - break; - case COMP_SERV_BEST: - printf("SRVCOMP-BEST "); - break; - case COMP_SERV_CUST: - printf("SRVCOMP-CUST "); - break; + printf(" %-9s %s\n", kt->keyword, conf_print(&hp->value[i])); } + printf("}\n"); + } - switch(dp->encrypt) { - case ENCRYPT_NONE: - printf("ENCRYPT-NONE "); - break; - case ENCRYPT_CUST: - printf("ENCRYPT-CUST "); - break; - case ENCRYPT_SERV_CUST: - printf("ENCRYPT-SERV-CUST "); - break; + for(tp = tapelist; tp != NULL; tp = tp->next) { + printf("\nDEFINE TAPETYPE %s {\n", tp->name); + for(i=0; i < TAPETYPE_TAPETYPE; i++) { + for(np=tapetype_var; np->token != CONF_UNKNOWN; np++) + if(np->parm == i) break; + if(np->token == CONF_UNKNOWN) + error("tapetype bad value"); + + for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++) + if(kt->token == np->token) break; + if(kt->token == CONF_UNKNOWN) + error("tapetype bad token"); + + printf(" %-9s %s\n", kt->keyword, conf_print(&tp->value[i])); } + printf("}\n"); + } - if(!dp->record) printf("NO-"); - printf("RECORD"); - printf(" %s-AUTH", dp->security_driver); - if(dp->skip_incr) printf(" SKIP-INCR"); - if(dp->skip_full) printf(" SKIP-FULL"); - if(dp->no_hold) printf(" NO-HOLD"); - if(dp->kencrypt) printf(" KENCRYPT"); - /* an ignored disk will never reach this point */ - assert(!dp->ignore); - if(dp->index) printf(" INDEX"); - putchar('\n'); + for(dp = dumplist; dp != NULL; dp = dp->next) { + if(dp->seen == -1) + prefix = "#"; + else + prefix = ""; + printf("\n%sDEFINE DUMPTYPE %s {\n", prefix, dp->name); + for(i=0; i < DUMPTYPE_DUMPTYPE; i++) { + for(np=dumptype_var; np->token != CONF_UNKNOWN; np++) + if(np->parm == i) break; + if(np->token == CONF_UNKNOWN) + error("dumptype bad value"); + + for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++) + if(kt->token == np->token) break; + if(kt->token == CONF_UNKNOWN) + error("dumptype bad token"); + + printf("%s %-19s %s\n", prefix, kt->keyword, conf_print(&dp->value[i])); + } + printf("%s}\n", prefix); } for(ip = interface_list; ip != NULL; ip = ip->next) { - printf("\nINTERFACE %s:\n", ip->name); - printf(" COMMENT \"%s\"\n", ip->comment); - printf(" USE %d\n", ip->maxusage); + if(strcmp(ip->name,"default") == 0) + prefix = "#"; + else + prefix = ""; + printf("\n%sDEFINE INTERFACE %s {\n", prefix, ip->name); + for(i=0; i < INTER_INTER; i++) { + for(np=interface_var; np->token != CONF_UNKNOWN; np++) + if(np->parm == i) break; + if(np->token == CONF_UNKNOWN) + error("interface bad value"); + + for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++) + if(kt->token == np->token) break; + if(kt->token == CONF_UNKNOWN) + error("interface bad token"); + + printf("%s %-9s %s\n", prefix, kt->keyword, conf_print(&ip->value[i])); + } + printf("%s}\n",prefix); } + } +#ifdef TEST + int -main(argc, argv) - int argc; - char *argv[]; +main( + int argc, + char *argv[]) { char *conffile; char *diskfile; @@ -3585,10 +2221,11 @@ main(argc, argv) #endif /* TEST */ char * -generic_get_security_conf(string, arg) - char *string; - void *arg; +generic_get_security_conf( + char *string, + void *arg) { + arg = arg; if(!string || !*string) return(NULL); @@ -3599,3 +2236,141 @@ generic_get_security_conf(string, arg) } return(NULL); } + +char * +get_token_name( + tok_t token) +{ + keytab_t *kt; + + for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++) + if(kt->token == token) break; + + if(kt->token == CONF_UNKNOWN) + return(""); + return(kt->keyword); +} + +void +parse_server_conf( + int parse_argc, + char **parse_argv, + int *new_argc, + char ***new_argv) +{ + int i; + char **my_argv; + char *myarg, *value; + command_option_t *server_option; + + server_options = alloc((size_t)(parse_argc+1) * SIZEOF(*server_options)); + server_option = server_options; + server_option->name = NULL; + + my_argv = alloc((size_t)parse_argc * SIZEOF(char *)); + *new_argv = my_argv; + *new_argc = 0; + i=0; + while(i 2) + myarg = &parse_argv[i][2]; + else { + i++; + if(i >= parse_argc) + error("expect something after -o"); + myarg = parse_argv[i]; + } + value = index(myarg,'='); + if (value == NULL) { + conf_parserror("Must specify a value for %s.\n", myarg); + } else { + *value = '\0'; + value++; + server_option->used = 0; + server_option->name = stralloc(myarg); + server_option->value = stralloc(value); + server_option++; + server_option->name = NULL; + } + } + else { + my_argv[*new_argc] = stralloc(parse_argv[i]); + *new_argc += 1; + } + i++; + } +} + +void +report_bad_conf_arg(void) +{ + command_option_t *command_option; + + for(command_option = server_options; command_option->name != NULL; + command_option++) { + if(command_option->used == 0) { + fprintf(stderr,"argument -o%s=%s not used\n", + command_option->name, command_option->value); + } + } +} + +void +free_server_config(void) +{ + holdingdisk_t *hp, *hpnext; + dumptype_t *dp, *dpnext; + tapetype_t *tp, *tpnext; + interface_t *ip, *ipnext; + command_option_t *server_option; + int i; + + for(hp=holdingdisks; hp != NULL; hp = hpnext) { + amfree(hp->name); + for(i=0; ivalue[i]); + } + hpnext = hp->next; + amfree(hp); + } + + for(dp=dumplist; dp != NULL; dp = dpnext) { + amfree(dp->name); + for(i=0; ivalue[i]); + } + dpnext = dp->next; + amfree(dp); + } + + for(tp=tapelist; tp != NULL; tp = tpnext) { + amfree(tp->name); + for(i=0; ivalue[i]); + } + tpnext = tp->next; + amfree(tp); + } + + for(ip=interface_list; ip != NULL; ip = ipnext) { + amfree(ip->name); + for(i=0; ivalue[i]); + } + ipnext = ip->next; + amfree(ip); + } + + if(server_options) { + for(server_option = server_options; server_option->name != NULL; + server_option++) { + amfree(server_option->name); + amfree(server_option->value); + } + amfree(server_options); + } + + for(i=0; i