X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=common-src%2Fconffile.c;h=7277e481e87dde296c230d611f5bf93edc5cf738;hb=377e15b597bafb8e7c2a100f11a0166f7220fe1c;hp=11ea02d1e060f222a46cd5460867e3bd2ca5602f;hpb=d5853102f67d85d8e169f9dbe973ad573306c215;p=debian%2Famanda diff --git a/common-src/conffile.c b/common-src/conffile.c index 11ea02d..7277e48 100644 --- a/common-src/conffile.c +++ b/common-src/conffile.c @@ -63,7 +63,7 @@ typedef enum { CONF_CHANGERDEV, CONF_CHANGERFILE, CONF_LABELSTR, CONF_BUMPPERCENT, CONF_BUMPSIZE, CONF_BUMPDAYS, CONF_BUMPMULT, CONF_ETIMEOUT, CONF_DTIMEOUT, - CONF_CTIMEOUT, CONF_TAPEBUFS, CONF_TAPELIST, + CONF_CTIMEOUT, CONF_TAPELIST, CONF_DEVICE_OUTPUT_BUFFER_SIZE, CONF_DISKFILE, CONF_INFOFILE, CONF_LOGDIR, CONF_LOGFILE, CONF_DISKDIR, CONF_DISKSIZE, @@ -88,14 +88,19 @@ typedef enum { CONF_APPLICATION, CONF_APPLICATION_TOOL, CONF_SCRIPT, CONF_SCRIPT_TOOL, CONF_EXECUTE_ON, CONF_EXECUTE_WHERE, CONF_SEND_AMREPORT_ON, - CONF_DEVICE, CONF_ORDER, + CONF_DEVICE, CONF_ORDER, CONF_SINGLE_EXECUTION, CONF_DATA_PATH, CONF_AMANDA, CONF_DIRECTTCP, + CONF_TAPER_PARALLEL_WRITE, CONF_INTERACTIVITY, CONF_TAPERSCAN, + CONF_MAX_DLE_BY_VOLUME, CONF_EJECT_VOLUME, /* execute on */ + CONF_PRE_AMCHECK, CONF_POST_AMCHECK, CONF_PRE_DLE_AMCHECK, CONF_PRE_HOST_AMCHECK, CONF_POST_DLE_AMCHECK, CONF_POST_HOST_AMCHECK, + CONF_PRE_ESTIMATE, CONF_POST_ESTIMATE, CONF_PRE_DLE_ESTIMATE, CONF_PRE_HOST_ESTIMATE, CONF_POST_DLE_ESTIMATE, CONF_POST_HOST_ESTIMATE, + CONF_PRE_BACKUP, CONF_POST_BACKUP, CONF_PRE_DLE_BACKUP, CONF_PRE_HOST_BACKUP, CONF_POST_DLE_BACKUP, CONF_POST_HOST_BACKUP, CONF_PRE_RECOVER, CONF_POST_RECOVER, @@ -122,16 +127,17 @@ typedef enum { CONF_SPLIT_DISKBUFFER, CONF_FALLBACK_SPLITSIZE,CONF_SRVCOMPPROG, CONF_CLNTCOMPPROG, CONF_SRV_ENCRYPT, CONF_CLNT_ENCRYPT, CONF_SRV_DECRYPT_OPT, CONF_CLNT_DECRYPT_OPT, CONF_AMANDAD_PATH, - CONF_CLIENT_USERNAME, CONF_CLIENT_PORT, + CONF_CLIENT_USERNAME, CONF_CLIENT_PORT, CONF_ALLOW_SPLIT, /* tape type */ - /*COMMENT,*/ CONF_BLOCKSIZE, CONF_FILE_PAD, + /*COMMENT,*/ CONF_BLOCKSIZE, CONF_LBL_TEMPL, CONF_FILEMARK, CONF_LENGTH, CONF_SPEED, CONF_READBLOCKSIZE, /* client conf */ CONF_CONF, CONF_INDEX_SERVER, CONF_TAPE_SERVER, CONF_SSH_KEYS, CONF_GNUTAR_LIST_DIR, CONF_AMANDATES, + CONF_AMDUMP_SERVER, /* protocol config */ CONF_REP_TRIES, CONF_CONNECT_TRIES, CONF_REQ_TRIES, @@ -159,6 +165,14 @@ typedef enum { /* autolabel */ CONF_AUTOLABEL, CONF_ANY_VOLUME, CONF_OTHER_CONFIG, CONF_NON_AMANDA, CONF_VOLUME_ERROR, CONF_EMPTY, + CONF_META_AUTOLABEL, + + /* part_cache_type */ + CONF_PART_SIZE, CONF_PART_CACHE_TYPE, CONF_PART_CACHE_DIR, + CONF_PART_CACHE_MAX_SIZE, CONF_DISK, CONF_MEMORY, + + /* host-limit */ + CONF_RECOVERY_LIMIT, CONF_SAME_HOST, CONF_DUMP_LIMIT, /* holdingdisk */ CONF_NEVER, CONF_AUTO, CONF_REQUIRED, @@ -183,7 +197,9 @@ typedef enum { CONF_MULT1T, /* boolean */ - CONF_ATRUE, CONF_AFALSE + CONF_ATRUE, CONF_AFALSE, + + CONF_CLIENT_NAME, } tok_t; /* A keyword table entry, mapping the given keyword to the given token. @@ -218,6 +234,10 @@ static int current_line_num = 0; /* (technically, managed by the parser) */ /* A static buffer for storing tokens while they are being scanned. */ static char tkbuf[4096]; +/* Return a token formated for output */ +static char *str_keyword(keytab_t *kt); + +static char *str_keyword(keytab_t *kt); /* Look up the name of the given token in the current keytable */ static char *get_token_name(tok_t); @@ -343,6 +363,22 @@ struct changer_config_s { val_t value[CHANGER_CONFIG_CHANGER_CONFIG]; }; +struct interactivity_s { + struct interactivity_s *next; + seen_t seen; + char *name; + + val_t value[INTERACTIVITY_INTERACTIVITY]; +}; + +struct taperscan_s { + struct taperscan_s *next; + seen_t seen; + char *name; + + val_t value[TAPERSCAN_TAPERSCAN]; +}; + /* The current parser table */ static conf_var_t *parsetable = NULL; @@ -461,6 +497,18 @@ static void init_changer_config_defaults(void); static void save_changer_config(void); static void copy_changer_config(void); +static interactivity_t ivcur; +static void get_interactivity(void); +static void init_interactivity_defaults(void); +static void save_interactivity(void); +static void copy_interactivity(void); + +static taperscan_t tscur; +static void get_taperscan(void); +static void init_taperscan_defaults(void); +static void save_taperscan(void); +static void copy_taperscan(void); + /* read_functions -- these fit into the read_function slot in a parser * table entry, and are responsible for calling getconf_token as necessary * to consume their arguments, and setting their second argument with the @@ -473,7 +521,9 @@ static void read_str(conf_var_t *, val_t *); static void read_ident(conf_var_t *, val_t *); static void read_time(conf_var_t *, val_t *); static void read_size(conf_var_t *, val_t *); +static void read_size_byte(conf_var_t *, val_t *); static void read_bool(conf_var_t *, val_t *); +static void read_no_yes_all(conf_var_t *, val_t *); static void read_compress(conf_var_t *, val_t *); static void read_encrypt(conf_var_t *, val_t *); static void read_holding(conf_var_t *, val_t *); @@ -487,6 +537,8 @@ static void read_rate(conf_var_t *, val_t *); static void read_exinclude(conf_var_t *, val_t *); static void read_intrange(conf_var_t *, val_t *); static void read_dapplication(conf_var_t *, val_t *); +static void read_dinteractivity(conf_var_t *, val_t *); +static void read_dtaperscan(conf_var_t *, val_t *); static void read_dpp_script(conf_var_t *, val_t *); static void read_property(conf_var_t *, val_t *); static void read_execute_on(conf_var_t *, val_t *); @@ -494,7 +546,21 @@ static void read_execute_where(conf_var_t *, val_t *); static void read_holdingdisk(conf_var_t *, val_t *); static void read_int_or_str(conf_var_t *, val_t *); static void read_autolabel(conf_var_t *, val_t *); - +static void read_part_cache_type(conf_var_t *, val_t *); +static void read_host_limit(conf_var_t *, val_t *); + +static application_t *read_application(char *name, FILE *from, char *fname, + int *linenum); +static pp_script_t *read_pp_script(char *name, FILE *from, char *fname, + int *linenum); +static device_config_t *read_device_config(char *name, FILE *from, char *fname, + int *linenum); +static changer_config_t *read_changer_config(char *name, FILE *from, + char *fname, int *linenum); +static interactivity_t *read_interactivity(char *name, FILE *from, + char *fname, int *linenum); +static taperscan_t *read_taperscan(char *name, FILE *from, char *fname, + int *linenum); /* Functions to get various types of values. These are called by * read_functions to take care of any variations in the way that these * values can be written: integers can have units, boolean values can be @@ -503,8 +569,10 @@ static void read_autolabel(conf_var_t *, val_t *); static time_t get_time(void); static int get_int(void); static ssize_t get_size(void); +static ssize_t get_size_byte(void); static gint64 get_int64(void); static int get_bool(void); +static int get_no_yes_all(void); /* Check the given 'seen', flagging an error if this value has already * been seen and allow_overwrites is false. Also marks the value as @@ -518,6 +586,7 @@ static void ckseen(seen_t *seen); * a parser table entry. They call conf_parserror if the value in their * second argument is invalid. */ static void validate_nonnegative(conf_var_t *, val_t *); +static void validate_non_zero(conf_var_t *, val_t *); static void validate_positive(conf_var_t *, val_t *); static void validate_runspercycle(conf_var_t *, val_t *); static void validate_bumppercent(conf_var_t *, val_t *); @@ -533,6 +602,7 @@ static void validate_port_range(val_t *, int, int); static void validate_reserved_port_range(conf_var_t *, val_t *); static void validate_unreserved_port_range(conf_var_t *, val_t *); static void validate_program(conf_var_t *, val_t *); +static void validate_dump_limit(conf_var_t *, val_t *); gint compare_pp_script_order(gconstpointer a, gconstpointer b); /* @@ -576,6 +646,8 @@ static application_t *application_list = NULL; static pp_script_t *pp_script_list = NULL; static device_config_t *device_config_list = NULL; static changer_config_t *changer_config_list = NULL; +static interactivity_t *interactivity_list = NULL; +static taperscan_t *taperscan_list = NULL; /* storage for derived values */ static long int unit_divisor = 1; @@ -628,6 +700,7 @@ static void conf_init_identlist(val_t *val, char *s); static void conf_init_time(val_t *val, time_t t); static void conf_init_size(val_t *val, ssize_t sz); static void conf_init_bool(val_t *val, int i); +static void conf_init_no_yes_all(val_t *val, int i); static void conf_init_compress(val_t *val, comp_t i); static void conf_init_encrypt(val_t *val, encrypt_t i); static void conf_init_data_path(val_t *val, data_path_t i); @@ -645,6 +718,9 @@ static void conf_init_intrange(val_t *val, int i1, int i2); static void conf_init_proplist(val_t *val); /* to empty list */ static void conf_init_application(val_t *val); static void conf_init_autolabel(val_t *val); +static void conf_init_part_cache_type(val_t *val, part_cache_type_t i); +static void conf_init_host_limit(val_t *val); +static void conf_init_host_limit_server(val_t *val); /* * Command-line Handling @@ -721,12 +797,14 @@ static void conf_parswarn(const char *format, ...) /* First, the keyword tables for client and server */ keytab_t client_keytab[] = { { "CONF", CONF_CONF }, + { "AMDUMP_SERVER", CONF_AMDUMP_SERVER }, { "INDEX_SERVER", CONF_INDEX_SERVER }, { "TAPE_SERVER", CONF_TAPE_SERVER }, { "TAPEDEV", CONF_TAPEDEV }, { "AUTH", CONF_AUTH }, { "SSH_KEYS", CONF_SSH_KEYS }, { "AMANDAD_PATH", CONF_AMANDAD_PATH }, + { "CLIENT_NAME", CONF_CLIENT_NAME }, { "CLIENT_USERNAME", CONF_CLIENT_USERNAME }, { "CLIENT_PORT", CONF_CLIENT_PORT }, { "GNUTAR_LIST_DIR", CONF_GNUTAR_LIST_DIR }, @@ -768,16 +846,22 @@ keytab_t client_keytab[] = { { "SCRIPT", CONF_SCRIPT }, { "SCRIPT_TOOL", CONF_SCRIPT_TOOL }, { "PLUGIN", CONF_PLUGIN }, + { "PRE_AMCHECK", CONF_PRE_AMCHECK }, { "PRE_DLE_AMCHECK", CONF_PRE_DLE_AMCHECK }, { "PRE_HOST_AMCHECK", CONF_PRE_HOST_AMCHECK }, + { "POST_AMCHECK", CONF_POST_AMCHECK }, { "POST_DLE_AMCHECK", CONF_POST_DLE_AMCHECK }, { "POST_HOST_AMCHECK", CONF_POST_HOST_AMCHECK }, + { "PRE_ESTIMATE", CONF_PRE_ESTIMATE }, { "PRE_DLE_ESTIMATE", CONF_PRE_DLE_ESTIMATE }, { "PRE_HOST_ESTIMATE", CONF_PRE_HOST_ESTIMATE }, + { "POST_ESTIMATE", CONF_POST_ESTIMATE }, { "POST_DLE_ESTIMATE", CONF_POST_DLE_ESTIMATE }, { "POST_HOST_ESTIMATE", CONF_POST_HOST_ESTIMATE }, + { "POST_BACKUP", CONF_POST_BACKUP }, { "POST_DLE_BACKUP", CONF_POST_DLE_BACKUP }, { "POST_HOST_BACKUP", CONF_POST_HOST_BACKUP }, + { "PRE_BACKUP", CONF_PRE_BACKUP }, { "PRE_DLE_BACKUP", CONF_PRE_DLE_BACKUP }, { "PRE_HOST_BACKUP", CONF_PRE_HOST_BACKUP }, { "PRE_RECOVER", CONF_PRE_RECOVER }, @@ -797,6 +881,7 @@ keytab_t client_keytab[] = { keytab_t server_keytab[] = { { "ALL", CONF_ALL }, + { "ALLOW_SPLIT", CONF_ALLOW_SPLIT }, { "AMANDA", CONF_AMANDA }, { "AMANDAD_PATH", CONF_AMANDAD_PATH }, { "AMRECOVER_CHANGER", CONF_AMRECOVER_CHANGER }, @@ -825,6 +910,7 @@ keytab_t server_keytab[] = { { "CLIENT_CUSTOM_COMPRESS", CONF_CLNTCOMPPROG }, { "CLIENT_DECRYPT_OPTION", CONF_CLNT_DECRYPT_OPT }, { "CLIENT_ENCRYPT", CONF_CLNT_ENCRYPT }, + { "CLIENT_NAME", CONF_CLIENT_NAME }, { "CLIENT_USERNAME", CONF_CLIENT_USERNAME }, { "COLUMNSPEC", CONF_COLUMNSPEC }, { "COMMENT", CONF_COMMENT }, @@ -857,6 +943,7 @@ keytab_t server_keytab[] = { { "DEVICE_PROPERTY", CONF_DEVICE_PROPERTY }, { "DIRECTORY", CONF_DIRECTORY }, { "DIRECTTCP", CONF_DIRECTTCP }, + { "DISK", CONF_DISK }, { "DISKFILE", CONF_DISKFILE }, { "DISPLAYUNIT", CONF_DISPLAYUNIT }, { "DTIMEOUT", CONF_DTIMEOUT }, @@ -864,6 +951,8 @@ keytab_t server_keytab[] = { { "DUMPORDER", CONF_DUMPORDER }, { "DUMPTYPE", CONF_DUMPTYPE }, { "DUMPUSER", CONF_DUMPUSER }, + { "DUMP_LIMIT", CONF_DUMP_LIMIT }, + { "EJECT_VOLUME", CONF_EJECT_VOLUME }, { "EMPTY", CONF_EMPTY }, { "ENCRYPT", CONF_ENCRYPT }, { "ERROR", CONF_ERROR }, @@ -877,7 +966,6 @@ keytab_t server_keytab[] = { { "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 }, @@ -892,6 +980,7 @@ keytab_t server_keytab[] = { { "INDEXDIR", CONF_INDEXDIR }, { "INFOFILE", CONF_INFOFILE }, { "INPARALLEL", CONF_INPARALLEL }, + { "INTERACTIVITY", CONF_INTERACTIVITY }, { "INTERFACE", CONF_INTERFACE }, { "KENCRYPT", CONF_KENCRYPT }, { "KRB5KEYTAB", CONF_KRB5KEYTAB }, @@ -909,10 +998,13 @@ keytab_t server_keytab[] = { { "MAILER", CONF_MAILER }, { "MAILTO", CONF_MAILTO }, { "READBLOCKSIZE", CONF_READBLOCKSIZE }, + { "MAX_DLE_BY_VOLUME", CONF_MAX_DLE_BY_VOLUME }, { "MAXDUMPS", CONF_MAXDUMPS }, { "MAXDUMPSIZE", CONF_MAXDUMPSIZE }, { "MAXPROMOTEDAY", CONF_MAXPROMOTEDAY }, + { "MEMORY", CONF_MEMORY }, { "MEDIUM", CONF_MEDIUM }, + { "META_AUTOLABEL", CONF_META_AUTOLABEL }, { "NETUSAGE", CONF_NETUSAGE }, { "NEVER", CONF_NEVER }, { "NOFULL", CONF_NOFULL }, @@ -923,17 +1015,27 @@ keytab_t server_keytab[] = { { "ORDER", CONF_ORDER }, { "ORG", CONF_ORG }, { "OTHER_CONFIG", CONF_OTHER_CONFIG }, + { "PART_CACHE_DIR", CONF_PART_CACHE_DIR }, + { "PART_CACHE_MAX_SIZE", CONF_PART_CACHE_MAX_SIZE }, + { "PART_CACHE_TYPE", CONF_PART_CACHE_TYPE }, + { "PART_SIZE", CONF_PART_SIZE }, { "PLUGIN", CONF_PLUGIN }, + { "PRE_AMCHECK", CONF_PRE_AMCHECK }, { "PRE_DLE_AMCHECK", CONF_PRE_DLE_AMCHECK }, { "PRE_HOST_AMCHECK", CONF_PRE_HOST_AMCHECK }, + { "POST_AMCHECK", CONF_POST_AMCHECK }, { "POST_DLE_AMCHECK", CONF_POST_DLE_AMCHECK }, { "POST_HOST_AMCHECK", CONF_POST_HOST_AMCHECK }, + { "PRE_ESTIMATE", CONF_PRE_ESTIMATE }, { "PRE_DLE_ESTIMATE", CONF_PRE_DLE_ESTIMATE }, { "PRE_HOST_ESTIMATE", CONF_PRE_HOST_ESTIMATE }, + { "POST_ESTIMATE", CONF_POST_ESTIMATE }, { "POST_DLE_ESTIMATE", CONF_POST_DLE_ESTIMATE }, { "POST_HOST_ESTIMATE", CONF_POST_HOST_ESTIMATE }, + { "POST_BACKUP", CONF_POST_BACKUP }, { "POST_DLE_BACKUP", CONF_POST_DLE_BACKUP }, { "POST_HOST_BACKUP", CONF_POST_HOST_BACKUP }, + { "PRE_BACKUP", CONF_PRE_BACKUP }, { "PRE_DLE_BACKUP", CONF_PRE_DLE_BACKUP }, { "PRE_HOST_BACKUP", CONF_PRE_HOST_BACKUP }, { "PRE_RECOVER", CONF_PRE_RECOVER }, @@ -946,6 +1048,7 @@ keytab_t server_keytab[] = { { "PROGRAM", CONF_PROGRAM }, { "PROPERTY", CONF_PROPERTY }, { "RECORD", CONF_RECORD }, + { "RECOVERY_LIMIT", CONF_RECOVERY_LIMIT }, { "REP_TRIES", CONF_REP_TRIES }, { "REQ_TRIES", CONF_REQ_TRIES }, { "REQUIRED", CONF_REQUIRED }, @@ -954,6 +1057,7 @@ keytab_t server_keytab[] = { { "RESERVED_TCP_PORT", CONF_RESERVED_TCP_PORT }, { "RUNSPERCYCLE", CONF_RUNSPERCYCLE }, { "RUNTAPES", CONF_RUNTAPES }, + { "SAME_HOST", CONF_SAME_HOST }, { "SCRIPT", CONF_SCRIPT }, { "SCRIPT_TOOL", CONF_SCRIPT_TOOL }, { "SEND_AMREPORT_ON", CONF_SEND_AMREPORT_ON }, @@ -965,6 +1069,7 @@ keytab_t server_keytab[] = { { "SKIP", CONF_SKIP }, { "SKIP_FULL", CONF_SKIP_FULL }, { "SKIP_INCR", CONF_SKIP_INCR }, + { "SINGLE_EXECUTION", CONF_SINGLE_EXECUTION }, { "SMALLEST", CONF_SMALLEST }, { "SPEED", CONF_SPEED }, { "SPLIT_DISKBUFFER", CONF_SPLIT_DISKBUFFER }, @@ -973,12 +1078,13 @@ keytab_t server_keytab[] = { { "STARTTIME", CONF_STARTTIME }, { "STRANGE", CONF_STRANGE }, { "STRATEGY", CONF_STRATEGY }, - { "TAPEBUFS", CONF_TAPEBUFS }, { "DEVICE_OUTPUT_BUFFER_SIZE", CONF_DEVICE_OUTPUT_BUFFER_SIZE }, { "TAPECYCLE", CONF_TAPECYCLE }, { "TAPEDEV", CONF_TAPEDEV }, { "TAPELIST", CONF_TAPELIST }, { "TAPERALGO", CONF_TAPERALGO }, + { "TAPERSCAN", CONF_TAPERSCAN }, + { "TAPER_PARALLEL_WRITE", CONF_TAPER_PARALLEL_WRITE }, { "FLUSH_THRESHOLD_DUMPED", CONF_FLUSH_THRESHOLD_DUMPED }, { "FLUSH_THRESHOLD_SCHEDULED", CONF_FLUSH_THRESHOLD_SCHEDULED }, { "TAPERFLUSH", CONF_TAPERFLUSH }, @@ -1058,10 +1164,27 @@ keytab_t bool_keytable[] = { { NULL, CONF_IDENT } }; +/* no_yes_all keywords -- all the ways to say "true" and "false" in amanda.conf */ +keytab_t no_yes_all_keytable[] = { + { "Y", CONF_ATRUE }, + { "YES", CONF_ATRUE }, + { "T", CONF_ATRUE }, + { "TRUE", CONF_ATRUE }, + { "ON", CONF_ATRUE }, + { "N", CONF_AFALSE }, + { "NO", CONF_AFALSE }, + { "F", CONF_AFALSE }, + { "FALSE", CONF_AFALSE }, + { "OFF", CONF_AFALSE }, + { "ALL", CONF_ALL }, + { NULL, CONF_IDENT } +}; + /* Now, the parser tables for client and server global parameters, and for * each of the server subsections */ conf_var_t client_var [] = { { CONF_CONF , CONFTYPE_STR , read_str , CNF_CONF , NULL }, + { CONF_AMDUMP_SERVER , CONFTYPE_STR , read_str , CNF_AMDUMP_SERVER , NULL }, { CONF_INDEX_SERVER , CONFTYPE_STR , read_str , CNF_INDEX_SERVER , NULL }, { CONF_TAPE_SERVER , CONFTYPE_STR , read_str , CNF_TAPE_SERVER , NULL }, { CONF_TAPEDEV , CONFTYPE_STR , read_str , CNF_TAPEDEV , NULL }, @@ -1137,25 +1260,28 @@ conf_var_t server_var [] = { { CONF_INPARALLEL , CONFTYPE_INT , read_int , CNF_INPARALLEL , validate_inparallel }, { CONF_DUMPORDER , CONFTYPE_STR , read_str , CNF_DUMPORDER , NULL }, { CONF_MAXDUMPS , CONFTYPE_INT , read_int , CNF_MAXDUMPS , validate_positive }, - { CONF_ETIMEOUT , CONFTYPE_INT , read_int , CNF_ETIMEOUT , validate_positive }, + { CONF_MAX_DLE_BY_VOLUME , CONFTYPE_INT , read_int , CNF_MAX_DLE_BY_VOLUME , validate_positive }, + { CONF_ETIMEOUT , CONFTYPE_INT , read_int , CNF_ETIMEOUT , validate_non_zero }, { CONF_DTIMEOUT , CONFTYPE_INT , read_int , CNF_DTIMEOUT , validate_positive }, { CONF_CTIMEOUT , CONFTYPE_INT , read_int , CNF_CTIMEOUT , validate_positive }, - { CONF_TAPEBUFS , CONFTYPE_INT , read_int , CNF_TAPEBUFS , validate_positive }, - { CONF_DEVICE_OUTPUT_BUFFER_SIZE, CONFTYPE_SIZE , read_size , CNF_DEVICE_OUTPUT_BUFFER_SIZE, validate_positive }, + { CONF_DEVICE_OUTPUT_BUFFER_SIZE, CONFTYPE_SIZE , read_size_byte , CNF_DEVICE_OUTPUT_BUFFER_SIZE, validate_positive }, { CONF_COLUMNSPEC , CONFTYPE_STR , read_str , CNF_COLUMNSPEC , NULL }, { CONF_TAPERALGO , CONFTYPE_TAPERALGO, read_taperalgo , CNF_TAPERALGO , NULL }, + { CONF_TAPER_PARALLEL_WRITE , CONFTYPE_INT , read_int , CNF_TAPER_PARALLEL_WRITE , NULL }, { CONF_SEND_AMREPORT_ON , CONFTYPE_SEND_AMREPORT_ON, read_send_amreport_on, CNF_SEND_AMREPORT_ON , NULL }, { CONF_FLUSH_THRESHOLD_DUMPED, CONFTYPE_INT , read_int , CNF_FLUSH_THRESHOLD_DUMPED, validate_nonnegative }, { CONF_FLUSH_THRESHOLD_SCHEDULED, CONFTYPE_INT , read_int , CNF_FLUSH_THRESHOLD_SCHEDULED, validate_nonnegative }, { CONF_TAPERFLUSH , CONFTYPE_INT , read_int , CNF_TAPERFLUSH , validate_nonnegative }, { CONF_DISPLAYUNIT , CONFTYPE_STR , read_str , CNF_DISPLAYUNIT , validate_displayunit }, - { CONF_AUTOFLUSH , CONFTYPE_BOOLEAN , read_bool , CNF_AUTOFLUSH , NULL }, + { CONF_AUTOFLUSH , CONFTYPE_NO_YES_ALL,read_no_yes_all , CNF_AUTOFLUSH , NULL }, { CONF_RESERVE , CONFTYPE_INT , read_int , CNF_RESERVE , validate_reserve }, { CONF_MAXDUMPSIZE , CONFTYPE_INT64 , read_int64 , CNF_MAXDUMPSIZE , NULL }, { CONF_KRB5KEYTAB , CONFTYPE_STR , read_str , CNF_KRB5KEYTAB , NULL }, { CONF_KRB5PRINCIPAL , CONFTYPE_STR , read_str , CNF_KRB5PRINCIPAL , NULL }, { CONF_LABEL_NEW_TAPES , CONFTYPE_STR , read_str , CNF_LABEL_NEW_TAPES , NULL }, { CONF_AUTOLABEL , CONFTYPE_AUTOLABEL, read_autolabel , CNF_AUTOLABEL , NULL }, + { CONF_META_AUTOLABEL , CONFTYPE_STR , read_str , CNF_META_AUTOLABEL , NULL }, + { CONF_EJECT_VOLUME , CONFTYPE_BOOLEAN , read_bool , CNF_EJECT_VOLUME , NULL }, { CONF_USETIMESTAMPS , CONFTYPE_BOOLEAN , read_bool , CNF_USETIMESTAMPS , NULL }, { CONF_AMRECOVER_DO_FSF , CONFTYPE_BOOLEAN , read_bool , CNF_AMRECOVER_DO_FSF , NULL }, { CONF_AMRECOVER_CHANGER , CONFTYPE_STR , read_str , CNF_AMRECOVER_CHANGER , NULL }, @@ -1184,19 +1310,25 @@ conf_var_t server_var [] = { { CONF_RESERVED_UDP_PORT , CONFTYPE_INTRANGE , read_intrange , CNF_RESERVED_UDP_PORT , validate_reserved_port_range }, { CONF_RESERVED_TCP_PORT , CONFTYPE_INTRANGE , read_intrange , CNF_RESERVED_TCP_PORT , validate_reserved_port_range }, { CONF_UNRESERVED_TCP_PORT , CONFTYPE_INTRANGE , read_intrange , CNF_UNRESERVED_TCP_PORT , validate_unreserved_port_range }, + { CONF_RECOVERY_LIMIT , CONFTYPE_HOST_LIMIT, read_host_limit , CNF_RECOVERY_LIMIT , NULL }, + { CONF_INTERACTIVITY , CONFTYPE_STR , read_dinteractivity, CNF_INTERACTIVITY , NULL }, + { CONF_TAPERSCAN , CONFTYPE_STR , read_dtaperscan , CNF_TAPERSCAN , NULL }, { CONF_UNKNOWN , CONFTYPE_INT , NULL , CNF_CNF , NULL } }; conf_var_t tapetype_var [] = { - { CONF_COMMENT , CONFTYPE_STR , read_str , TAPETYPE_COMMENT , NULL }, - { CONF_LBL_TEMPL , CONFTYPE_STR , read_str , TAPETYPE_LBL_TEMPL , NULL }, - { CONF_BLOCKSIZE , CONFTYPE_SIZE , read_size , TAPETYPE_BLOCKSIZE , validate_blocksize }, - { CONF_READBLOCKSIZE , CONFTYPE_SIZE , read_size , TAPETYPE_READBLOCKSIZE, validate_blocksize }, - { CONF_LENGTH , CONFTYPE_INT64 , read_int64 , TAPETYPE_LENGTH , validate_nonnegative }, - { CONF_FILEMARK , CONFTYPE_INT64 , read_int64 , TAPETYPE_FILEMARK , NULL }, - { CONF_SPEED , CONFTYPE_INT , read_int , TAPETYPE_SPEED , validate_nonnegative }, - { CONF_FILE_PAD , CONFTYPE_BOOLEAN , read_bool , TAPETYPE_FILE_PAD , NULL }, - { CONF_UNKNOWN , CONFTYPE_INT , NULL , TAPETYPE_TAPETYPE , NULL } + { CONF_COMMENT , CONFTYPE_STR , read_str , TAPETYPE_COMMENT , NULL }, + { CONF_LBL_TEMPL , CONFTYPE_STR , read_str , TAPETYPE_LBL_TEMPL , NULL }, + { CONF_BLOCKSIZE , CONFTYPE_SIZE , read_size , TAPETYPE_BLOCKSIZE , validate_blocksize }, + { CONF_READBLOCKSIZE , CONFTYPE_SIZE , read_size , TAPETYPE_READBLOCKSIZE , validate_blocksize }, + { CONF_LENGTH , CONFTYPE_INT64 , read_int64 , TAPETYPE_LENGTH , validate_nonnegative }, + { CONF_FILEMARK , CONFTYPE_INT64 , read_int64 , TAPETYPE_FILEMARK , NULL }, + { CONF_SPEED , CONFTYPE_INT , read_int , TAPETYPE_SPEED , validate_nonnegative }, + { CONF_PART_SIZE , CONFTYPE_INT64 , read_int64 , TAPETYPE_PART_SIZE , validate_nonnegative }, + { CONF_PART_CACHE_TYPE , CONFTYPE_PART_CACHE_TYPE, read_part_cache_type, TAPETYPE_PART_CACHE_TYPE, NULL }, + { CONF_PART_CACHE_DIR , CONFTYPE_STR , read_str , TAPETYPE_PART_CACHE_DIR , NULL }, + { CONF_PART_CACHE_MAX_SIZE , CONFTYPE_INT64 , read_int64 , TAPETYPE_PART_CACHE_MAX_SIZE, validate_nonnegative }, + { CONF_UNKNOWN , CONFTYPE_INT , NULL , TAPETYPE_TAPETYPE , NULL } }; conf_var_t dumptype_var [] = { @@ -1241,8 +1373,11 @@ conf_var_t dumptype_var [] = { { CONF_SRV_DECRYPT_OPT , CONFTYPE_STR , read_str , DUMPTYPE_SRV_DECRYPT_OPT , NULL }, { CONF_CLNT_DECRYPT_OPT , CONFTYPE_STR , read_str , DUMPTYPE_CLNT_DECRYPT_OPT , NULL }, { CONF_APPLICATION , CONFTYPE_STR , read_dapplication, DUMPTYPE_APPLICATION , NULL }, - { CONF_SCRIPT , CONFTYPE_STR , read_dpp_script, DUMPTYPE_SCRIPTLIST , NULL }, - { CONF_DATA_PATH , CONFTYPE_DATA_PATH, read_data_path, DUMPTYPE_DATA_PATH , NULL }, + { CONF_SCRIPT , CONFTYPE_STR , read_dpp_script, DUMPTYPE_SCRIPTLIST , NULL }, + { CONF_DATA_PATH , CONFTYPE_DATA_PATH, read_data_path, DUMPTYPE_DATA_PATH , NULL }, + { CONF_ALLOW_SPLIT , CONFTYPE_BOOLEAN , read_bool , DUMPTYPE_ALLOW_SPLIT , NULL }, + { CONF_RECOVERY_LIMIT , CONFTYPE_HOST_LIMIT, read_host_limit, DUMPTYPE_RECOVERY_LIMIT , NULL }, + { CONF_DUMP_LIMIT , CONFTYPE_HOST_LIMIT, read_host_limit, DUMPTYPE_DUMP_LIMIT , validate_dump_limit }, { CONF_UNKNOWN , CONFTYPE_INT , NULL , DUMPTYPE_DUMPTYPE , NULL } }; @@ -1265,6 +1400,7 @@ conf_var_t application_var [] = { { CONF_COMMENT , CONFTYPE_STR , read_str , APPLICATION_COMMENT , NULL }, { CONF_PLUGIN , CONFTYPE_STR , read_str , APPLICATION_PLUGIN , NULL }, { CONF_PROPERTY , CONFTYPE_PROPLIST, read_property, APPLICATION_PROPERTY , NULL }, + { CONF_CLIENT_NAME, CONFTYPE_STR , read_str , APPLICATION_CLIENT_NAME, NULL }, { CONF_UNKNOWN , CONFTYPE_INT , NULL , APPLICATION_APPLICATION, NULL } }; @@ -1275,6 +1411,8 @@ conf_var_t pp_script_var [] = { { CONF_EXECUTE_ON , CONFTYPE_EXECUTE_ON , read_execute_on , PP_SCRIPT_EXECUTE_ON , NULL }, { CONF_EXECUTE_WHERE, CONFTYPE_EXECUTE_WHERE , read_execute_where , PP_SCRIPT_EXECUTE_WHERE, NULL }, { CONF_ORDER , CONFTYPE_INT , read_int , PP_SCRIPT_ORDER , NULL }, + { CONF_SINGLE_EXECUTION, CONFTYPE_BOOLEAN, read_bool , PP_SCRIPT_SINGLE_EXECUTION, NULL }, + { CONF_CLIENT_NAME , CONFTYPE_STR , read_str , PP_SCRIPT_CLIENT_NAME , NULL }, { CONF_UNKNOWN , CONFTYPE_INT , NULL , PP_SCRIPT_PP_SCRIPT , NULL } }; @@ -1296,6 +1434,20 @@ conf_var_t changer_config_var [] = { { CONF_UNKNOWN , CONFTYPE_INT , NULL , CHANGER_CONFIG_CHANGER_CONFIG , NULL } }; +conf_var_t interactivity_var [] = { + { CONF_COMMENT , CONFTYPE_STR , read_str , INTERACTIVITY_COMMENT , NULL }, + { CONF_PLUGIN , CONFTYPE_STR , read_str , INTERACTIVITY_PLUGIN , NULL }, + { CONF_PROPERTY , CONFTYPE_PROPLIST , read_property , INTERACTIVITY_PROPERTY , NULL }, + { CONF_UNKNOWN , CONFTYPE_INT , NULL , INTERACTIVITY_INTERACTIVITY , NULL } +}; + +conf_var_t taperscan_var [] = { + { CONF_COMMENT , CONFTYPE_STR , read_str , TAPERSCAN_COMMENT , NULL }, + { CONF_PLUGIN , CONFTYPE_STR , read_str , TAPERSCAN_PLUGIN , NULL }, + { CONF_PROPERTY , CONFTYPE_PROPLIST , read_property , TAPERSCAN_PROPERTY , NULL }, + { CONF_UNKNOWN , CONFTYPE_INT , NULL , TAPERSCAN_TAPERSCAN , NULL } +}; + /* * Lexical Analysis Implementation */ @@ -1477,8 +1629,11 @@ negative_number: /* look for goto negative_number below sign is set there */ *buf++ = (char)ch; while (inquote && ((ch = conftoken_getc()) != EOF)) { if (ch == '\n') { - if (!escape) + if (!escape) { + conf_parserror(_("string not terminated")); + conftoken_ungetc(ch); break; + } escape = 0; buf--; /* Consume escape in buffer */ } else if (ch == '\\' && !escape) { @@ -1609,7 +1764,7 @@ negative_number: /* look for goto negative_number below sign is set there */ if (kwp->keyword == NULL) str = _("token not"); else - str = kwp->keyword; + str = str_keyword(kwp); break; } conf_parserror(_("%s is expected"), str); @@ -1745,7 +1900,9 @@ read_confline( else if(tok == CONF_DEVICE) get_device_config(); else if(tok == CONF_CHANGER) get_changer_config(); else if(tok == CONF_HOLDING) get_holdingdisk(1); - else conf_parserror(_("DUMPTYPE, INTERFACE, TAPETYPE, HOLDINGDISK, APPLICATION-TOOL, SCRIPT-TOOL, DEVICE, or CHANGER expected")); + else if(tok == CONF_INTERACTIVITY) get_interactivity(); + else if(tok == CONF_TAPERSCAN) get_taperscan(); + else conf_parserror(_("DUMPTYPE, INTERFACE, TAPETYPE, HOLDINGDISK, APPLICATION, SCRIPT, DEVICE, CHANGER, INTERACTIVITY or TAPERSCAN expected")); } break; @@ -1779,29 +1936,36 @@ read_confline( static void handle_deprecated_keyword(void) { - tok_t *dep; /* Procedure for deprecated keywords: - * 1) At time of deprecation, add to warning_deprecated below. - * Note the date of deprecation. The keyword will still be - * parsed, and can still be used from other parts of Amanda, - * during this time. - * 2) After two years, move the keyword (as a string) to + * + * 1) At time of deprecation, add to warning_deprecated below. Note the + * version in which deprecation will expire. The keyword will still be + * parsed, and can still be used from other parts of Amanda, during this + * time. + * 2) After it has expired, move the keyword (as a string) to * error_deprecated below. Remove the token (CONF_XXX) and * config parameter (CNF_XXX) from the rest of the module. * Note the date of the move. */ - static tok_t warning_deprecated[] = { - CONF_TAPEBUFS, /* 2007-10-15 */ - CONF_FILE_PAD, /* 2008-07-01 */ - CONF_LABEL_NEW_TAPES, /* 2010-02-05 */ - 0 - }; - - for (dep = warning_deprecated; *dep; dep++) { - if (tok == *dep) { - conf_parswarn(_("warning: Keyword %s is deprecated."), - tokenval.v.s); + static struct { tok_t tok; gboolean warned; } + warning_deprecated[] = { + { CONF_LABEL_NEW_TAPES, 0 }, /* exp in Amanda-3.2 */ + { CONF_AMRECOVER_DO_FSF, 0 }, /* exp in Amanda-3.3 */ + { CONF_AMRECOVER_CHECK_LABEL, 0 }, /* exp in Amanda-3.3 */ + { CONF_TAPE_SPLITSIZE, 0 }, /* exp. in Amanda-3.3 */ + { CONF_SPLIT_DISKBUFFER, 0 }, /* exp. in Amanda-3.3 */ + { CONF_FALLBACK_SPLITSIZE, 0 }, /* exp. in Amanda-3.3 */ + { 0, 0 }, + }, *dep; + + for (dep = warning_deprecated; dep->tok; dep++) { + if (tok == dep->tok) { + if (!dep->warned) + conf_parswarn(_("warning: Keyword %s is deprecated."), + tokenval.v.s); + dep->warned = 1; + break; } } } @@ -1812,17 +1976,29 @@ handle_invalid_keyword( { static const char * error_deprecated[] = { "rawtapedev", + "tapebufs", /* deprecated: 2007-10-15; invalid: 2010-04-14 */ + "file-pad", /* deprecated: 2008-07-01; invalid: 2010-04-14 */ NULL }; const char ** s; + char *folded_token, *p; + + /* convert '_' to '-' in TOKEN */ + folded_token = g_strdup(token); + for (p = folded_token; *p; p++) { + if (*p == '_') *p = '-'; + } for (s = error_deprecated; *s != NULL; s ++) { - if (g_ascii_strcasecmp(*s, token) == 0) { + if (g_ascii_strcasecmp(*s, folded_token) == 0) { conf_parserror(_("error: Keyword %s is deprecated."), token); + g_free(folded_token); return; } } + g_free(folded_token); + if (*s == NULL) { conf_parserror(_("configuration keyword expected")); } @@ -1880,6 +2056,8 @@ read_block( do { current_line_num += 1; get_conftoken(CONF_ANY); + handle_deprecated_keyword(); + switch(tok) { case CONF_RBRACE: done = 1; @@ -2187,7 +2365,7 @@ init_dumptype_defaults(void) conf_init_str (&dpcur.value[DUMPTYPE_CLIENT_USERNAME] , ""); conf_init_str (&dpcur.value[DUMPTYPE_CLIENT_PORT] , ""); conf_init_str (&dpcur.value[DUMPTYPE_SSH_KEYS] , ""); - conf_init_str (&dpcur.value[DUMPTYPE_AUTH] , "BSD"); + conf_init_str (&dpcur.value[DUMPTYPE_AUTH] , "BSDTCP"); conf_init_exinclude(&dpcur.value[DUMPTYPE_EXCLUDE]); conf_init_exinclude(&dpcur.value[DUMPTYPE_INCLUDE]); conf_init_priority (&dpcur.value[DUMPTYPE_PRIORITY] , 1); @@ -2220,6 +2398,9 @@ init_dumptype_defaults(void) conf_init_application(&dpcur.value[DUMPTYPE_APPLICATION]); conf_init_identlist(&dpcur.value[DUMPTYPE_SCRIPTLIST], NULL); conf_init_proplist(&dpcur.value[DUMPTYPE_PROPERTY]); + conf_init_bool (&dpcur.value[DUMPTYPE_ALLOW_SPLIT] , 1); + conf_init_host_limit(&dpcur.value[DUMPTYPE_RECOVERY_LIMIT]); + conf_init_host_limit_server(&dpcur.value[DUMPTYPE_DUMP_LIMIT]); } static void @@ -2318,7 +2499,10 @@ init_tapetype_defaults(void) conf_init_int64 (&tpcur.value[TAPETYPE_LENGTH] , ((gint64)2000)); conf_init_int64 (&tpcur.value[TAPETYPE_FILEMARK] , (gint64)1); conf_init_int (&tpcur.value[TAPETYPE_SPEED] , 200); - conf_init_bool (&tpcur.value[TAPETYPE_FILE_PAD] , 1); + conf_init_int64(&tpcur.value[TAPETYPE_PART_SIZE], 0); + conf_init_part_cache_type(&tpcur.value[TAPETYPE_PART_CACHE_TYPE], PART_CACHE_TYPE_NONE); + conf_init_str(&tpcur.value[TAPETYPE_PART_CACHE_DIR], ""); + conf_init_int64(&tpcur.value[TAPETYPE_PART_CACHE_MAX_SIZE], 0); } static void @@ -2337,6 +2521,7 @@ save_tapetype(void) tp = alloc(sizeof(tapetype_t)); *tp = tpcur; + /* add at end of list */ if(!tapelist) tapelist = tp; @@ -2400,7 +2585,7 @@ static void init_interface_defaults(void) { conf_init_str(&ifcur.value[INTER_COMMENT] , ""); - conf_init_int (&ifcur.value[INTER_MAXUSAGE], 8000); + conf_init_int (&ifcur.value[INTER_MAXUSAGE], 80000); } static void @@ -2451,7 +2636,7 @@ copy_interface(void) } -application_t * +static application_t * read_application( char *name, FILE *from, @@ -2526,6 +2711,7 @@ init_application_defaults( conf_init_str(&apcur.value[APPLICATION_COMMENT] , ""); conf_init_str(&apcur.value[APPLICATION_PLUGIN] , ""); conf_init_proplist(&apcur.value[APPLICATION_PROPERTY]); + conf_init_str(&apcur.value[APPLICATION_CLIENT_NAME] , ""); } static void @@ -2577,7 +2763,259 @@ copy_application(void) } } -pp_script_t * +static interactivity_t * +read_interactivity( + char *name, + FILE *from, + char *fname, + int *linenum) +{ + int save_overwrites; + FILE *saved_conf = NULL; + char *saved_fname = NULL; + + if (from) { + saved_conf = current_file; + current_file = from; + } + + if (fname) { + saved_fname = current_filename; + current_filename = get_seen_filename(fname); + } + + if (linenum) + current_line_num = *linenum; + + save_overwrites = allow_overwrites; + allow_overwrites = 1; + + init_interactivity_defaults(); + if (name) { + ivcur.name = name; + } else { + get_conftoken(CONF_IDENT); + ivcur.name = stralloc(tokenval.v.s); + } + ivcur.seen.filename = current_filename; + ivcur.seen.linenum = current_line_num; + + read_block(interactivity_var, ivcur.value, + _("interactivity parameter expected"), + (name == NULL), *copy_interactivity, + "INTERACTIVITY", ivcur.name); + if(!name) + get_conftoken(CONF_NL); + + save_interactivity(); + + allow_overwrites = save_overwrites; + + if (linenum) + *linenum = current_line_num; + + if (fname) + current_filename = saved_fname; + + if (from) + current_file = saved_conf; + + return lookup_interactivity(ivcur.name); +} + +static void +get_interactivity( + void) +{ + read_interactivity(NULL, NULL, NULL, NULL); +} + +static void +init_interactivity_defaults( + void) +{ + ivcur.name = NULL; + conf_init_str(&ivcur.value[INTERACTIVITY_COMMENT] , ""); + conf_init_str(&ivcur.value[INTERACTIVITY_PLUGIN] , ""); + conf_init_proplist(&ivcur.value[INTERACTIVITY_PROPERTY]); +} + +static void +save_interactivity( + void) +{ + interactivity_t *iv, *iv1; + + iv = lookup_interactivity(ivcur.name); + + if (iv != (interactivity_t *)0) { + conf_parserror(_("interactivity %s already defined at %s:%d"), + iv->name, iv->seen.filename, iv->seen.linenum); + return; + } + + iv = alloc(sizeof(interactivity_t)); + *iv = ivcur; + iv->next = NULL; + /* add at end of list */ + if (!interactivity_list) + interactivity_list = iv; + else { + iv1 = interactivity_list; + while (iv1->next != NULL) { + iv1 = iv1->next; + } + iv1->next = iv; + } +} + +static void +copy_interactivity(void) +{ + interactivity_t *iv; + int i; + + iv = lookup_interactivity(tokenval.v.s); + + if (iv == NULL) { + conf_parserror(_("interactivity parameter expected")); + return; + } + + for (i=0; i < INTERACTIVITY_INTERACTIVITY; i++) { + if(iv->value[i].seen.linenum) { + merge_val_t(&ivcur.value[i], &iv->value[i]); + } + } +} + +static taperscan_t * +read_taperscan( + char *name, + FILE *from, + char *fname, + int *linenum) +{ + int save_overwrites; + FILE *saved_conf = NULL; + char *saved_fname = NULL; + + if (from) { + saved_conf = current_file; + current_file = from; + } + + if (fname) { + saved_fname = current_filename; + current_filename = get_seen_filename(fname); + } + + if (linenum) + current_line_num = *linenum; + + save_overwrites = allow_overwrites; + allow_overwrites = 1; + + init_taperscan_defaults(); + if (name) { + tscur.name = name; + } else { + get_conftoken(CONF_IDENT); + tscur.name = stralloc(tokenval.v.s); + } + tscur.seen.filename = current_filename; + tscur.seen.linenum = current_line_num; + + read_block(taperscan_var, tscur.value, + _("taperscan parameter expected"), + (name == NULL), *copy_taperscan, + "TAPERSCAN", tscur.name); + if(!name) + get_conftoken(CONF_NL); + + save_taperscan(); + + allow_overwrites = save_overwrites; + + if (linenum) + *linenum = current_line_num; + + if (fname) + current_filename = saved_fname; + + if (from) + current_file = saved_conf; + + return lookup_taperscan(tscur.name); +} + +static void +get_taperscan( + void) +{ + read_taperscan(NULL, NULL, NULL, NULL); +} + +static void +init_taperscan_defaults( + void) +{ + tscur.name = NULL; + conf_init_str(&tscur.value[TAPERSCAN_COMMENT] , ""); + conf_init_str(&tscur.value[TAPERSCAN_PLUGIN] , ""); + conf_init_proplist(&tscur.value[TAPERSCAN_PROPERTY]); +} + +static void +save_taperscan( + void) +{ + taperscan_t *ts, *ts1; + + ts = lookup_taperscan(tscur.name); + + if (ts != (taperscan_t *)0) { + conf_parserror(_("taperscan %s already defined at %s:%d"), + ts->name, ts->seen.filename, ts->seen.linenum); + return; + } + + ts = alloc(sizeof(taperscan_t)); + *ts = tscur; + ts->next = NULL; + /* add at end of list */ + if (!taperscan_list) + taperscan_list = ts; + else { + ts1 = taperscan_list; + while (ts1->next != NULL) { + ts1 = ts1->next; + } + ts1->next = ts; + } +} + +static void +copy_taperscan(void) +{ + taperscan_t *ts; + int i; + + ts = lookup_taperscan(tokenval.v.s); + + if (ts == NULL) { + conf_parserror(_("taperscan parameter expected")); + return; + } + + for (i=0; i < TAPERSCAN_TAPERSCAN; i++) { + if(ts->value[i].seen.linenum) { + merge_val_t(&tscur.value[i], &ts->value[i]); + } + } +} + +static pp_script_t * read_pp_script( char *name, FILE *from, @@ -2655,6 +3093,8 @@ init_pp_script_defaults( conf_init_execute_on(&pscur.value[PP_SCRIPT_EXECUTE_ON], 0); conf_init_execute_where(&pscur.value[PP_SCRIPT_EXECUTE_WHERE], ES_CLIENT); conf_init_int(&pscur.value[PP_SCRIPT_ORDER], 5000); + conf_init_bool(&pscur.value[PP_SCRIPT_SINGLE_EXECUTION], 0); + conf_init_str(&pscur.value[PP_SCRIPT_CLIENT_NAME], ""); } static void @@ -2706,7 +3146,7 @@ copy_pp_script(void) } } -device_config_t * +static device_config_t * read_device_config( char *name, FILE *from, @@ -2832,7 +3272,7 @@ copy_device_config(void) } } -changer_config_t * +static changer_config_t * read_changer_config( char *name, FILE *from, @@ -3029,6 +3469,15 @@ read_size( val_t__size(val) = get_size(); } +static void +read_size_byte( + conf_var_t *np G_GNUC_UNUSED, + val_t *val) +{ + ckseen(&val->seen); + val_t__size(val) = get_size_byte(); +} + static void read_bool( conf_var_t *np G_GNUC_UNUSED, @@ -3038,6 +3487,15 @@ read_bool( val_t__boolean(val) = get_bool(); } +static void +read_no_yes_all( + conf_var_t *np G_GNUC_UNUSED, + val_t *val) +{ + ckseen(&val->seen); + val_t__int(val) = get_no_yes_all(); +} + static void read_compress( conf_var_t *np G_GNUC_UNUSED, @@ -3280,8 +3738,8 @@ read_data_path( get_conftoken(CONF_ANY); switch(tok) { - case CONF_AMANDA : val_t__send_amreport(val) = DATA_PATH_AMANDA ; break; - case CONF_DIRECTTCP: val_t__send_amreport(val) = DATA_PATH_DIRECTTCP; break; + case CONF_AMANDA : val_t__data_path(val) = DATA_PATH_AMANDA ; break; + case CONF_DIRECTTCP: val_t__data_path(val) = DATA_PATH_DIRECTTCP; break; default: conf_parserror(_("AMANDA or DIRECTTCP expected")); } @@ -3449,7 +3907,7 @@ read_property( conf_parserror(_("key expected")); return; } - key = g_ascii_strdown(tokenval.v.s, -1); + key = amandaify_property_name(tokenval.v.s); get_conftoken(CONF_ANY); if (tok == CONF_NL || tok == CONF_END) { @@ -3518,6 +3976,64 @@ read_dapplication( ckseen(&val->seen); } +static void +read_dinteractivity( + conf_var_t *np G_GNUC_UNUSED, + val_t *val) +{ + interactivity_t *interactivity; + + get_conftoken(CONF_ANY); + if (tok == CONF_LBRACE) { + current_line_num -= 1; + interactivity = read_interactivity(vstralloc("custom(iv)", ".", + anonymous_value(),NULL), + NULL, NULL, NULL); + current_line_num -= 1; + } else if (tok == CONF_STRING) { + interactivity = lookup_interactivity(tokenval.v.s); + if (interactivity == NULL) { + conf_parserror(_("Unknown interactivity named: %s"), tokenval.v.s); + return; + } + } else { + conf_parserror(_("interactivity name expected: %d %d"), tok, CONF_STRING); + return; + } + amfree(val->v.s); + val->v.s = stralloc(interactivity->name); + ckseen(&val->seen); +} + +static void +read_dtaperscan( + conf_var_t *np G_GNUC_UNUSED, + val_t *val) +{ + taperscan_t *taperscan; + + get_conftoken(CONF_ANY); + if (tok == CONF_LBRACE) { + current_line_num -= 1; + taperscan = read_taperscan(vstralloc("custom(ts)", ".", + anonymous_value(),NULL), + NULL, NULL, NULL); + current_line_num -= 1; + } else if (tok == CONF_STRING) { + taperscan = lookup_taperscan(tokenval.v.s); + if (taperscan == NULL) { + conf_parserror(_("Unknown taperscan named: %s"), tokenval.v.s); + return; + } + } else { + conf_parserror(_("taperscan name expected: %d %d"), tok, CONF_STRING); + return; + } + amfree(val->v.s); + val->v.s = stralloc(taperscan->name); + ckseen(&val->seen); +} + static void read_dpp_script( conf_var_t *np G_GNUC_UNUSED, @@ -3562,16 +4078,22 @@ read_execute_on( val->v.i = 0; do { switch(tok) { + case CONF_PRE_AMCHECK: val->v.i |= EXECUTE_ON_PRE_AMCHECK; break; case CONF_PRE_DLE_AMCHECK: val->v.i |= EXECUTE_ON_PRE_DLE_AMCHECK; break; case CONF_PRE_HOST_AMCHECK: val->v.i |= EXECUTE_ON_PRE_HOST_AMCHECK; break; case CONF_POST_DLE_AMCHECK: val->v.i |= EXECUTE_ON_POST_DLE_AMCHECK; break; case CONF_POST_HOST_AMCHECK: val->v.i |= EXECUTE_ON_POST_HOST_AMCHECK; break; + case CONF_POST_AMCHECK: val->v.i |= EXECUTE_ON_POST_AMCHECK; break; + case CONF_PRE_ESTIMATE: val->v.i |= EXECUTE_ON_PRE_ESTIMATE; break; case CONF_PRE_DLE_ESTIMATE: val->v.i |= EXECUTE_ON_PRE_DLE_ESTIMATE; break; case CONF_PRE_HOST_ESTIMATE: val->v.i |= EXECUTE_ON_PRE_HOST_ESTIMATE; break; case CONF_POST_DLE_ESTIMATE: val->v.i |= EXECUTE_ON_POST_DLE_ESTIMATE; break; case CONF_POST_HOST_ESTIMATE: val->v.i |= EXECUTE_ON_POST_HOST_ESTIMATE; break; + case CONF_POST_ESTIMATE: val->v.i |= EXECUTE_ON_POST_ESTIMATE; break; + case CONF_PRE_BACKUP: val->v.i |= EXECUTE_ON_PRE_BACKUP; break; case CONF_PRE_DLE_BACKUP: val->v.i |= EXECUTE_ON_PRE_DLE_BACKUP; break; case CONF_PRE_HOST_BACKUP: val->v.i |= EXECUTE_ON_PRE_HOST_BACKUP; break; + case CONF_POST_BACKUP: val->v.i |= EXECUTE_ON_POST_BACKUP; break; case CONF_POST_DLE_BACKUP: val->v.i |= EXECUTE_ON_POST_DLE_BACKUP; break; case CONF_POST_HOST_BACKUP: val->v.i |= EXECUTE_ON_POST_HOST_BACKUP; break; case CONF_PRE_RECOVER: val->v.i |= EXECUTE_ON_PRE_RECOVER; break; @@ -3580,7 +4102,7 @@ read_execute_on( case CONF_POST_LEVEL_RECOVER: val->v.i |= EXECUTE_ON_POST_LEVEL_RECOVER; break; case CONF_INTER_LEVEL_RECOVER: val->v.i |= EXECUTE_ON_INTER_LEVEL_RECOVER; break; default: - conf_parserror(_("Execute_on expected")); + conf_parserror(_("Execute-on expected")); } get_conftoken(CONF_ANY); if (tok != CONF_COMMA) { @@ -3635,7 +4157,7 @@ read_int_or_str( val->v.s = newstralloc(val->v.s, tokenval.v.s); break; default: - conf_parserror(_("CLIENT or SERVER expected")); + conf_parserror(_("an integer or a quoted string is expected")); } } @@ -3669,7 +4191,7 @@ read_autolabel( else if (tok == CONF_EMPTY) val->v.autolabel.autolabel |= AL_EMPTY; else { - conf_parserror(_("ANY-VOLUME, NEW-VOLUME, OTHER-CONFIG, NON-AMANDA, VOLUME-ERROR or EMPTY is expected")); + conf_parserror(_("ANY, NEW-VOLUME, OTHER-CONFIG, NON-AMANDA, VOLUME-ERROR or EMPTY is expected")); } get_conftoken(CONF_ANY); } @@ -3681,6 +4203,75 @@ read_autolabel( } } +static void +read_part_cache_type( + conf_var_t *np G_GNUC_UNUSED, + val_t *val) +{ + part_cache_type_t part_cache_type; + + ckseen(&val->seen); + + get_conftoken(CONF_ANY); + switch(tok) { + case CONF_NONE: + part_cache_type = PART_CACHE_TYPE_NONE; + break; + + case CONF_DISK: + part_cache_type = PART_CACHE_TYPE_DISK; + break; + + case CONF_MEMORY: + part_cache_type = PART_CACHE_TYPE_MEMORY; + break; + + default: + conf_parserror(_("NONE, DISK or MEMORY expected")); + part_cache_type = PART_CACHE_TYPE_NONE; + break; + } + + val_t__part_cache_type(val) = (int)part_cache_type; +} + +static void +read_host_limit( + conf_var_t *np G_GNUC_UNUSED, + val_t *val) +{ + host_limit_t *rl = &val_t__host_limit(val); + ckseen(&val->seen); + + rl->match_pats = NULL; + rl->same_host = FALSE; + rl->server = FALSE; + + while (1) { + get_conftoken(CONF_ANY); + switch(tok) { + case CONF_STRING: + rl->match_pats = g_slist_append(rl->match_pats, g_strdup(tokenval.v.s)); + break; + case CONF_SAME_HOST: + rl->same_host = TRUE; + break; + + case CONF_SERVER: + rl->server = TRUE; + break; + + case CONF_NL: + case CONF_END: + return; + + default: + conf_parserror("SAME-HOST or a string expected"); + break; + } + } +} + /* get_* functions */ /* these functions use precompiler conditionals to skip useless size checks @@ -3923,6 +4514,103 @@ get_size(void) return val; } +static ssize_t +get_size_byte(void) +{ + ssize_t val; + keytab_t *save_kt; + + save_kt = keytable; + keytable = numb_keytable; + + get_conftoken(CONF_ANY); + + switch(tok) { + case CONF_SIZE: + val = tokenval.v.size; + break; + + case CONF_INT: +#if SIZEOF_SIZE_T < SIZEOF_INT + if ((gint64)tokenval.v.i > (gint64)SSIZE_MAX) + conf_parserror(_("value too large")); + if ((gint64)tokenval.v.i < (gint64)SSIZE_MIN) + conf_parserror(_("value too small")); +#endif + val = (ssize_t)tokenval.v.i; + break; + + case CONF_INT64: +#if SIZEOF_SIZE_T < SIZEOF_GINT64 + if (tokenval.v.int64 > (gint64)SSIZE_MAX) + conf_parserror(_("value too large")); + if (tokenval.v.int64 < (gint64)SSIZE_MIN) + conf_parserror(_("value too small")); +#endif + val = (ssize_t)tokenval.v.int64; + break; + + case CONF_AMINFINITY: + val = (ssize_t)SSIZE_MAX; + break; + + default: + conf_parserror(_("an integer is expected")); + val = 0; + break; + } + + /* get multiplier, if any */ + get_conftoken(CONF_ANY); + + switch(tok) { + case CONF_NL: /* multiply by one */ + case CONF_MULT1: + break; + case CONF_MULT1K: + if (val > (ssize_t)(SSIZE_MAX / (ssize_t)1024)) + conf_parserror(_("value too large")); + if (val < (ssize_t)(SSIZE_MIN / (ssize_t)1024)) + conf_parserror(_("value too small")); + val *= (ssize_t)1024; + + case CONF_MULT7: + if (val > (ssize_t)(SSIZE_MAX / 7)) + conf_parserror(_("value too large")); + if (val < (ssize_t)(SSIZE_MIN / 7)) + conf_parserror(_("value too small")); + val *= (ssize_t)7; + break; + + case CONF_MULT1M: + if (val > (ssize_t)(SSIZE_MAX / (ssize_t)1024 * 1024)) + conf_parserror(_("value too large")); + if (val < (ssize_t)(SSIZE_MIN / (ssize_t)1024 * 1024)) + conf_parserror(_("value too small")); + val *= (ssize_t)(1024 * 1024); + break; + + case CONF_MULT1G: + if (val > (ssize_t)(SSIZE_MAX / (1024 * 1024 * 1024))) + conf_parserror(_("value too large")); + if (val < (ssize_t)(SSIZE_MIN / (1024 * 1024 * 1024))) + conf_parserror(_("value too small")); + val *= (ssize_t)(1024 * 1024 * 1024); + break; + + case CONF_MULT1T: + conf_parserror(_("value too large")); + break; + + default: /* it was not a multiplier */ + unget_conftoken(); + break; + } + + keytable = save_kt; + return val; +} + static gint64 get_int64(void) { @@ -4056,6 +4744,59 @@ get_bool(void) return val; } +static int +get_no_yes_all(void) +{ + int val; + keytab_t *save_kt; + + save_kt = keytable; + keytable = no_yes_all_keytable; + + get_conftoken(CONF_ANY); + + switch(tok) { + case CONF_INT: + val = tokenval.v.i; + break; + + case CONF_SIZE: + val = tokenval.v.size; + break; + + case CONF_INT64: + val = tokenval.v.int64; + break; + + case CONF_ALL: + val = 2; + break; + + case CONF_ATRUE: + val = 1; + break; + + case CONF_AFALSE: + val = 0; + break; + + case CONF_NL: + unget_conftoken(); + val = 3; /* no argument - most likely TRUE */ + break; + default: + unget_conftoken(); + val = 3; /* a bad argument - most likely TRUE */ + conf_parserror(_("%d: YES, NO, ALL, TRUE, FALSE, ON, OFF, 0, 1, 2 expected"), tok); + break; + } + + if (val > 2 || val < 0) + val = 1; + keytable = save_kt; + return val; +} + void ckseen( seen_t *seen) @@ -4093,6 +4834,33 @@ validate_nonnegative( } } +static void +validate_non_zero( + struct conf_var_s *np, + val_t *val) +{ + switch(val->type) { + case CONFTYPE_INT: + if(val_t__int(val) == 0) + conf_parserror(_("%s must not be 0"), get_token_name(np->token)); + break; + case CONFTYPE_INT64: + if(val_t__int64(val) == 0) + conf_parserror(_("%s must not be 0"), get_token_name(np->token)); + break; + case CONFTYPE_TIME: + if(val_t__time(val) == 0) + conf_parserror(_("%s must not be 0"), get_token_name(np->token)); + break; + case CONFTYPE_SIZE: + if(val_t__size(val) == 0) + conf_parserror(_("%s must not be 0"), get_token_name(np->token)); + break; + default: + conf_parserror(_("validate_non_zero invalid type %d\n"), val->type); + } +} + static void validate_positive( struct conf_var_s *np, @@ -4333,7 +5101,6 @@ config_init( config_name = stralloc(config_name + 1); } - amfree(cwd); } else if (flags & CONFIG_INIT_CLIENT) { amfree(config_name); config_dir = newstralloc(config_dir, CONFIG_DIR); @@ -4407,6 +5174,8 @@ config_uninit(void) pp_script_t *pp, *ppnext; device_config_t *dc, *dcnext; changer_config_t *cc, *ccnext; + interactivity_t *iv, *ivnext; + taperscan_t *ts, *tsnext; int i; if (!config_initialized) return; @@ -4418,7 +5187,7 @@ config_uninit(void) free_val_t(&hd->value[i]); } } - g_slist_free_full(holdinglist); + slist_free_full(holdinglist, g_free); holdinglist = NULL; for(dp=dumplist; dp != NULL; dp = dpnext) { @@ -4489,9 +5258,28 @@ config_uninit(void) ccnext = cc->next; amfree(cc); } - changer_config_list = NULL; + for(iv=interactivity_list; iv != NULL; iv = ivnext) { + amfree(iv->name); + for(i=0; ivalue[i]); + } + ivnext = iv->next; + amfree(iv); + } + interactivity_list = NULL; + + for(ts=taperscan_list; ts != NULL; ts = tsnext) { + amfree(ts->name); + for(i=0; ivalue[i]); + } + tsnext = ts->next; + amfree(ts); + } + taperscan_list = NULL; + for(i=0; i 0) || (getconf_seen(CNF_LABEL_NEW_TAPES) < 0 && getconf_seen(CNF_AUTOLABEL) < 0)) { - conf_parserror(_("Can't specify both label_new_tapes and autolabel")); + conf_parserror(_("Can't specify both label-new-tapes and autolabel")); } if ((getconf_seen(CNF_LABEL_NEW_TAPES) != 0 && getconf_seen(CNF_AUTOLABEL) == 0) || @@ -4967,6 +5770,17 @@ conf_init_bool( val_t__boolean(val) = i; } +static void +conf_init_no_yes_all( + val_t *val, + int i) +{ + val->seen.linenum = 0; + val->seen.filename = NULL; + val->type = CONFTYPE_NO_YES_ALL; + val_t__int(val) = i; +} + static void conf_init_compress( val_t *val, @@ -4989,6 +5803,37 @@ conf_init_encrypt( val_t__encrypt(val) = (int)i; } +static void +conf_init_part_cache_type( + val_t *val, + part_cache_type_t i) +{ + val->seen.linenum = 0; + val->seen.filename = NULL; + val->type = CONFTYPE_PART_CACHE_TYPE; + val_t__part_cache_type(val) = (int)i; +} + +static void +conf_init_host_limit( + val_t *val) +{ + val->seen.linenum = 0; + val->seen.filename = NULL; + val->type = CONFTYPE_HOST_LIMIT; + val_t__host_limit(val).match_pats = NULL; + val_t__host_limit(val).same_host = FALSE; + val_t__host_limit(val).server = FALSE; +} + +static void +conf_init_host_limit_server( + val_t *val) +{ + conf_init_host_limit(val); + val_t__host_limit(val).server = TRUE; +} + static void conf_init_data_path( val_t *val, @@ -4997,7 +5842,7 @@ conf_init_data_path( val->seen.linenum = 0; val->seen.filename = NULL; val->type = CONFTYPE_DATA_PATH; - val_t__encrypt(val) = (int)i; + val_t__data_path(val) = (int)i; } static void @@ -5110,7 +5955,7 @@ free_property_t( gpointer p) { property_t *propery = (property_t *)p; - g_slist_free_full(propery->values); + slist_free_full(propery->values, g_free); amfree(propery); } @@ -5122,7 +5967,8 @@ conf_init_proplist( val->seen.filename = NULL; val->type = CONFTYPE_PROPLIST; val_t__proplist(val) = - g_hash_table_new_full(g_str_hash, g_str_equal, &g_free, &free_property_t); + g_hash_table_new_full(g_str_amanda_hash, g_str_amanda_equal, + &g_free, &free_property_t); } static void @@ -5190,6 +6036,8 @@ getconf_list( pp_script_t *pp; device_config_t *dc; changer_config_t *cc; + interactivity_t *iv; + taperscan_t *ts; GSList *rv = NULL; if (strcasecmp(listname,"tapetype") == 0) { @@ -5229,6 +6077,14 @@ getconf_list( for(cc = changer_config_list; cc != NULL; cc=cc->next) { rv = g_slist_append(rv, cc->name); } + } else if (strcasecmp(listname,"interactivity") == 0) { + for(iv = interactivity_list; iv != NULL; iv=iv->next) { + rv = g_slist_append(rv, iv->name); + } + } else if (strcasecmp(listname,"taperscan") == 0) { + for(ts = taperscan_list; ts != NULL; ts=ts->next) { + rv = g_slist_append(rv, ts->name); + } } return rv; } @@ -5279,6 +6135,16 @@ validate_program( conf_parserror("program must be \"DUMP\", \"GNUTAR\", \"STAR\" or \"APPLICATION\""); } +static void +validate_dump_limit( + conf_var_t *np G_GNUC_UNUSED, + val_t *val) +{ + if (val->v.host_limit.match_pats) { + conf_parserror("dump-limit can't specify hostname"); + } +} + char * tapetype_name( tapetype_t *ttyp) @@ -5416,6 +6282,66 @@ application_name( return ap->name; } +interactivity_t * +lookup_interactivity( + char *str) +{ + interactivity_t *p; + + for(p = interactivity_list; p != NULL; p = p->next) { + if(strcasecmp(p->name, str) == 0) return p; + } + return NULL; +} + +val_t * +interactivity_getconf( + interactivity_t *iv, + interactivity_key key) +{ + assert(iv != NULL); + assert(key < INTERACTIVITY_INTERACTIVITY); + return &iv->value[key]; +} + +char * +interactivity_name( + interactivity_t *iv) +{ + assert(iv != NULL); + return iv->name; +} + +taperscan_t * +lookup_taperscan( + char *str) +{ + taperscan_t *p; + + for(p = taperscan_list; p != NULL; p = p->next) { + if(strcasecmp(p->name, str) == 0) return p; + } + return NULL; +} + +val_t * +taperscan_getconf( + taperscan_t *ts, + taperscan_key key) +{ + assert(ts != NULL); + assert(key < TAPERSCAN_TAPERSCAN); + return &ts->value[key]; +} + +char * +taperscan_name( + taperscan_t *ts) +{ + assert(ts != NULL); + return ts->name; +} + pp_script_t * lookup_pp_script( char *str) @@ -5801,6 +6727,18 @@ val_t_to_boolean( return val_t__boolean(val); } +int +val_t_to_no_yes_all( + val_t *val) +{ + assert(config_initialized); + if (val->type != CONFTYPE_NO_YES_ALL) { + error(_("val_t_to_no_yes_all: val.type is not CONFTYPE_NO_YES_ALL")); + /*NOTREACHED*/ + } + return val_t__no_yes_all(val); +} + comp_t val_t_to_compress( val_t *val) @@ -5825,6 +6763,30 @@ val_t_to_encrypt( return val_t__encrypt(val); } +part_cache_type_t +val_t_to_part_cache_type( + val_t *val) +{ + assert(config_initialized); + if (val->type != CONFTYPE_PART_CACHE_TYPE) { + error(_("val_t_to_part_cache_type: val.type is not CONFTYPE_PART_CACHE_TYPE")); + /*NOTREACHED*/ + } + return val_t__part_cache_type(val); +} + +host_limit_t * +val_t_to_host_limit( + val_t *val) +{ + assert(config_initialized); + if (val->type != CONFTYPE_HOST_LIMIT) { + error(_("val_t_to_host_limit: val.type is not CONFTYPE_HOST_LIMIT")); + /*NOTREACHED*/ + } + return &val_t__host_limit(val); +} + dump_holdingdisk_t val_t_to_holding( val_t *val) @@ -5978,8 +6940,8 @@ merge_val_t( if (valsrc->type == CONFTYPE_PROPLIST) { if (valsrc->v.proplist) { if (valdst->v.proplist == NULL) { - valdst->v.proplist = g_hash_table_new_full(g_str_hash, - g_str_equal, + valdst->v.proplist = g_hash_table_new_full(g_str_amanda_hash, + g_str_amanda_equal, &g_free, &free_property_t); g_hash_table_foreach(valsrc->v.proplist, @@ -6018,6 +6980,7 @@ copy_val_t( switch(valsrc->type) { case CONFTYPE_INT: case CONFTYPE_BOOLEAN: + case CONFTYPE_NO_YES_ALL: case CONFTYPE_COMPRESS: case CONFTYPE_ENCRYPT: case CONFTYPE_HOLDING: @@ -6028,6 +6991,7 @@ copy_val_t( case CONFTYPE_STRATEGY: case CONFTYPE_TAPERALGO: case CONFTYPE_PRIORITY: + case CONFTYPE_PART_CACHE_TYPE: valdst->v.i = valsrc->v.i; break; @@ -6061,6 +7025,15 @@ copy_val_t( } break; + case CONFTYPE_HOST_LIMIT: + valdst->v.host_limit = valsrc->v.host_limit; + valdst->v.host_limit.match_pats = NULL; + for (ia = valsrc->v.host_limit.match_pats; ia != NULL; ia = ia->next) { + valdst->v.host_limit.match_pats = + g_slist_append(valdst->v.host_limit.match_pats, g_strdup(ia->data)); + } + break; + case CONFTYPE_TIME: valdst->v.t = valsrc->v.t; break; @@ -6089,8 +7062,8 @@ copy_val_t( case CONFTYPE_PROPLIST: if (valsrc->v.proplist) { - valdst->v.proplist = g_hash_table_new_full(g_str_hash, - g_str_equal, + valdst->v.proplist = g_hash_table_new_full(g_str_amanda_hash, + g_str_amanda_equal, &g_free, &free_property_t); @@ -6175,6 +7148,7 @@ free_val_t( switch(val->type) { case CONFTYPE_INT: case CONFTYPE_BOOLEAN: + case CONFTYPE_NO_YES_ALL: case CONFTYPE_COMPRESS: case CONFTYPE_ENCRYPT: case CONFTYPE_HOLDING: @@ -6190,6 +7164,7 @@ free_val_t( case CONFTYPE_REAL: case CONFTYPE_RATE: case CONFTYPE_INTRANGE: + case CONFTYPE_PART_CACHE_TYPE: break; case CONFTYPE_IDENT: @@ -6199,7 +7174,11 @@ free_val_t( break; case CONFTYPE_IDENTLIST: - g_slist_free_full(val->v.identlist); + slist_free_full(val->v.identlist, g_free); + break; + + case CONFTYPE_HOST_LIMIT: + slist_free_full(val->v.host_limit.match_pats, g_free); break; case CONFTYPE_TIME: @@ -6259,6 +7238,8 @@ generic_client_get_security_conf( if(strcmp(string, "conf")==0) { return(getconf_str(CNF_CONF)); + } else if(strcmp(string, "amdump_server")==0) { + return(getconf_str(CNF_AMDUMP_SERVER)); } else if(strcmp(string, "index_server")==0) { return(getconf_str(CNF_INDEX_SERVER)); } else if(strcmp(string, "tape_server")==0) { @@ -6299,6 +7280,8 @@ dump_configuration(void) pp_script_t *ps; device_config_t *dc; changer_config_t *cc; + interactivity_t *iv; + taperscan_t *ts; int i; conf_var_t *np; keytab_t *kt; @@ -6496,6 +7479,44 @@ dump_configuration(void) } g_printf("%s}\n",prefix); } + + for(iv = interactivity_list; iv != NULL; iv = iv->next) { + prefix = ""; + g_printf("\n%sDEFINE INTERACTIVITY %s {\n", prefix, iv->name); + for(i=0; i < INTERACTIVITY_INTERACTIVITY; i++) { + for(np=interactivity_var; np->token != CONF_UNKNOWN; np++) + if(np->parm == i) break; + if(np->token == CONF_UNKNOWN) + error(_("interactivity bad value")); + + for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++) + if(kt->token == np->token) break; + if(kt->token == CONF_UNKNOWN) + error(_("interactivity bad token")); + + val_t_print_token(stdout, prefix, " %-19s ", kt, &iv->value[i]); + } + g_printf("%s}\n",prefix); + } + + for(ts = taperscan_list; ts != NULL; ts = ts->next) { + prefix = ""; + g_printf("\n%sDEFINE TAPERSCAN %s {\n", prefix, ts->name); + for(i=0; i < TAPERSCAN_TAPERSCAN; i++) { + for(np=taperscan_var; np->token != CONF_UNKNOWN; np++) + if(np->parm == i) break; + if(np->token == CONF_UNKNOWN) + error(_("taperscan bad value")); + + for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++) + if(kt->token == np->token) break; + if(kt->token == CONF_UNKNOWN) + error(_("taperscan bad token")); + + val_t_print_token(stdout, prefix, " %-19s ", kt, &ts->value[i]); + } + g_printf("%s}\n",prefix); + } } static void @@ -6520,7 +7541,7 @@ val_t_print_token( for(dispstr=dispstrs; *dispstr!=NULL; dispstr++) { if (prefix) g_fprintf(output, "%s", prefix); - g_fprintf(output, format, kt->keyword); + g_fprintf(output, format, str_keyword(kt)); g_fprintf(output, "%s\n", *dispstr); } } else { @@ -6648,6 +7669,20 @@ val_t_display_strs( buf[0] = stralloc("no"); break; + case CONFTYPE_NO_YES_ALL: + switch(val_t__no_yes_all(val)) { + case 0: + buf[0] = stralloc("no"); + break; + case 1: + buf[0] = stralloc("yes"); + break; + case 2: + buf[0] = stralloc("all"); + break; + } + break; + case CONFTYPE_STRATEGY: switch(val_t__strategy(val)) { case DS_SKIP: @@ -6784,6 +7819,41 @@ val_t_display_strs( } break; + case CONFTYPE_PART_CACHE_TYPE: + switch(val_t__part_cache_type(val)) { + case PART_CACHE_TYPE_NONE: + buf[0] = vstrallocf("NONE"); + break; + + case PART_CACHE_TYPE_DISK: + buf[0] = vstrallocf("DISK"); + break; + + case PART_CACHE_TYPE_MEMORY: + buf[0] = vstrallocf("MEMORY"); + break; + } + break; + + case CONFTYPE_HOST_LIMIT: { + GSList *iter = val_t__host_limit(val).match_pats; + + if (val_t__host_limit(val).same_host) + buf[0] = stralloc("SAME-HOST "); + else + buf[0] = stralloc(""); + + if (val_t__host_limit(val).server) + strappend(buf[0], "SERVER "); + + while (iter) { + strappend(buf[0], quote_string_always((char *)iter->data)); + strappend(buf[0], " "); + iter = iter->next; + } + break; + } + case CONFTYPE_HOLDING: switch(val_t__holding(val)) { case HOLD_NEVER: @@ -6848,6 +7918,10 @@ val_t_display_strs( buf[0] = stralloc(""); if (val->v.i != 0) { char *sep = ""; + if (val->v.i & EXECUTE_ON_PRE_AMCHECK) { + buf[0] = vstrextend(&buf[0], sep, "PRE-AMCHECK", NULL); + sep = ", "; + } if (val->v.i & EXECUTE_ON_PRE_DLE_AMCHECK) { buf[0] = vstrextend(&buf[0], sep, "PRE-DLE-AMCHECK", NULL); sep = ", "; @@ -6864,6 +7938,14 @@ val_t_display_strs( buf[0] = vstrextend(&buf[0], sep, "POST-HOST-AMCHECK", NULL); sep = ", "; } + if (val->v.i & EXECUTE_ON_POST_AMCHECK) { + buf[0] = vstrextend(&buf[0], sep, "POST-AMCHECK", NULL); + sep = ", "; + } + if (val->v.i & EXECUTE_ON_PRE_ESTIMATE) { + buf[0] = vstrextend(&buf[0], sep, "PRE-ESTIMATE", NULL); + sep = ", "; + } if (val->v.i & EXECUTE_ON_PRE_DLE_ESTIMATE) { buf[0] = vstrextend(&buf[0], sep, "PRE-DLE-ESTIMATE", NULL); sep = ", "; @@ -6880,6 +7962,14 @@ val_t_display_strs( buf[0] = vstrextend(&buf[0], sep, "POST-HOST-ESTIMATE", NULL); sep = ", "; } + if (val->v.i & EXECUTE_ON_POST_ESTIMATE) { + buf[0] = vstrextend(&buf[0], sep, "POST-ESTIMATE", NULL); + sep = ", "; + } + if (val->v.i & EXECUTE_ON_PRE_BACKUP) { + buf[0] = vstrextend(&buf[0], sep, "PRE-BACKUP", NULL); + sep = ", "; + } if (val->v.i & EXECUTE_ON_PRE_DLE_BACKUP) { buf[0] = vstrextend(&buf[0], sep, "PRE-DLE-BACKUP", NULL); sep = ", "; @@ -6888,6 +7978,10 @@ val_t_display_strs( buf[0] = vstrextend(&buf[0], sep, "PRE-HOST-BACKUP", NULL); sep = ", "; } + if (val->v.i & EXECUTE_ON_POST_BACKUP) { + buf[0] = vstrextend(&buf[0], sep, "POST-BACKUP", NULL); + sep = ", "; + } if (val->v.i & EXECUTE_ON_POST_DLE_BACKUP) { buf[0] = vstrextend(&buf[0], sep, "POST-DLE-BACKUP", NULL); sep = ", "; @@ -7392,7 +8486,7 @@ config_errors(GSList **errstr) void config_clear_errors(void) { - g_slist_free_full(cfgerr_errors); + slist_free_full(cfgerr_errors, g_free); cfgerr_errors = NULL; cfgerr_level = CFGERR_OK; @@ -7426,15 +8520,6 @@ char *get_config_filename(void) return config_filename; } -void -property_add_to_argv( - GPtrArray *argv_ptr, - proplist_t proplist) -{ - g_hash_table_foreach(proplist, &proplist_add_to_argv, argv_ptr); - return; -} - char * anonymous_value(void) { @@ -7462,7 +8547,7 @@ data_path_to_string( case DATA_PATH_AMANDA : return "AMANDA"; case DATA_PATH_DIRECTTCP: return "DIRECTTCP"; } - error(_("data_path is not DATA_PATH_AMANDA or DATA_PATH_DIRECTTCP")); + error(_("datapath is not DATA_PATH_AMANDA or DATA_PATH_DIRECTTCP")); /* NOTREACHED */ } @@ -7474,7 +8559,7 @@ data_path_from_string( return DATA_PATH_AMANDA; if (strcmp(data, "DIRECTTCP") == 0) return DATA_PATH_DIRECTTCP; - error(_("data_path is not AMANDA or DIRECTTCP :%s:"), data); + error(_("datapath is not AMANDA or DIRECTTCP :%s:"), data); /* NOTREACHED */ } @@ -7500,3 +8585,25 @@ amandaify_property_name( return ret; } +static char keyword_str[1024]; + +static char * +str_keyword( + keytab_t *kt) +{ + char *p = kt->keyword; + char *s = keyword_str; + + while(*p != '\0') { + if (*p == '_') { + *s = '-'; + } else { + *s = *p; + } + p++; + s++; + } + *s = '\0'; + + return keyword_str; +}