X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=common-src%2Fconffile.c;h=4d48220ae02cbd47b0c6acdc07d259eb5ae33aa8;hb=949b8910a5e23c4285d0b1aedacfc82a14dc97a5;hp=19d87da4718f099fa7caf5cc50f1491cf607672e;hpb=b116e9366c7b2ea2c2eb53b0a13df4090e176235;p=debian%2Famanda diff --git a/common-src/conffile.c b/common-src/conffile.c index 19d87da..4d48220 100644 --- a/common-src/conffile.c +++ b/common-src/conffile.c @@ -88,15 +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_TAPER_PARALLEL_WRITE, CONF_INTERACTIVITY, CONF_TAPERSCAN, + CONF_MAX_DLE_BY_VOLUME, CONF_EJECT_VOLUME, CONF_TMPDIR, /* 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, @@ -124,6 +128,7 @@ typedef enum { 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_ALLOW_SPLIT, + CONF_MAX_WARNINGS, /* tape type */ /*COMMENT,*/ CONF_BLOCKSIZE, @@ -133,6 +138,7 @@ typedef enum { /* 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, @@ -160,13 +166,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, - /* recovery-limit */ - CONF_RECOVERY_LIMIT, CONF_SAME_HOST, + /* host-limit */ + CONF_RECOVERY_LIMIT, CONF_SAME_HOST, CONF_DUMP_LIMIT, /* holdingdisk */ CONF_NEVER, CONF_AUTO, CONF_REQUIRED, @@ -191,7 +198,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. @@ -221,11 +230,16 @@ static FILE *current_file = NULL; static char *current_filename = NULL; static char *current_line = NULL; static char *current_char = NULL; +static char *current_block = NULL; static int current_line_num = 0; /* (technically, managed by the parser) */ /* A static buffer for storing tokens while they are being scanned. */ static char tkbuf[4096]; +/* 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); @@ -345,12 +359,28 @@ struct device_config_s { struct changer_config_s { struct changer_config_s *next; - int seen; + seen_t seen; char *name; 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; @@ -469,6 +499,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 @@ -481,8 +523,8 @@ 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 *); @@ -496,6 +538,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 *); @@ -504,19 +548,32 @@ 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_recovery_limit(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 * specified with a number of names, etc. They form utility functions * for the read_functions, below. */ +static gint64 get_multiplier(gint64 val, confunit_t unit); 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_int(confunit_t unit); +static ssize_t get_size(confunit_t unit); +static gint64 get_int64(confunit_t unit); 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 @@ -546,6 +603,9 @@ 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 *); +static void validate_tmpdir(conf_var_t *, val_t *); + gint compare_pp_script_order(gconstpointer a, gconstpointer b); /* @@ -589,6 +649,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; @@ -632,15 +694,16 @@ static cfgerr_level_t apply_config_overrides(config_overrides_t *co, * These set the value's type and seen flags, as well as copying * the relevant value into the 'v' field. */ -static void conf_init_int(val_t *val, int i); -static void conf_init_int64(val_t *val, gint64 l); +static void conf_init_int(val_t *val, confunit_t unit, int i); +static void conf_init_int64(val_t *val, confunit_t unit, gint64 l); static void conf_init_real(val_t *val, float r); static void conf_init_str(val_t *val, char *s); static void conf_init_ident(val_t *val, char *s); 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_size(val_t *val, confunit_t unit, 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); @@ -659,7 +722,8 @@ 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_recovery_limit(val_t *val); +static void conf_init_host_limit(val_t *val); +static void conf_init_host_limit_server(val_t *val); /* * Command-line Handling @@ -695,7 +759,7 @@ void free_property_t(gpointer p); /* Utility functions/structs for val_t_display_strs */ static char *exinclude_display_str(val_t *val, int file); static void proplist_display_str_foreach_fn(gpointer key_p, gpointer value_p, gpointer user_data_p); -static void val_t_print_token(FILE *output, char *prefix, char *format, keytab_t *kt, val_t *val); +static void val_t_print_token(gboolean print_default, gboolean print_source, FILE *output, char *prefix, char *format, keytab_t *kt, val_t *val); /* Given a key name as used in config overwrites, return a pointer to the corresponding * conf_var_t in the current parsetable, and the val_t representing that value. This @@ -736,12 +800,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 }, @@ -783,16 +849,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 }, @@ -841,6 +913,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 }, @@ -881,6 +954,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 }, @@ -908,6 +983,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 }, @@ -925,11 +1001,14 @@ 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 }, + { "MAX_WARNINGS", CONF_MAX_WARNINGS }, { "MEMORY", CONF_MEMORY }, { "MEDIUM", CONF_MEDIUM }, + { "META_AUTOLABEL", CONF_META_AUTOLABEL }, { "NETUSAGE", CONF_NETUSAGE }, { "NEVER", CONF_NEVER }, { "NOFULL", CONF_NOFULL }, @@ -945,16 +1024,22 @@ keytab_t server_keytab[] = { { "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 }, @@ -988,6 +1073,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 }, @@ -1001,12 +1087,14 @@ keytab_t server_keytab[] = { { "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 }, { "TAPETYPE", CONF_TAPETYPE }, { "TAPE_SPLITSIZE", CONF_TAPE_SPLITSIZE }, + { "TMPDIR", CONF_TMPDIR }, { "TPCHANGER", CONF_TPCHANGER }, { "UNRESERVED_TCP_PORT", CONF_UNRESERVED_TCP_PORT }, { "USE", CONF_USE }, @@ -1081,10 +1169,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 }, @@ -1160,10 +1265,11 @@ 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_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_DEVICE_OUTPUT_BUFFER_SIZE, CONFTYPE_SIZE , read_size_byte , CNF_DEVICE_OUTPUT_BUFFER_SIZE, validate_positive }, + { CONF_DEVICE_OUTPUT_BUFFER_SIZE, CONFTYPE_SIZE , read_size , 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 }, @@ -1172,13 +1278,16 @@ conf_var_t server_var [] = { { 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_TMPDIR , CONFTYPE_STR , read_str , CNF_TMPDIR , validate_tmpdir }, { 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 }, @@ -1207,7 +1316,9 @@ 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_RECOVERY_LIMIT, read_recovery_limit, CNF_RECOVERY_LIMIT, NULL }, + { 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 } }; @@ -1270,8 +1381,10 @@ conf_var_t dumptype_var [] = { { 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_ALLOW_SPLIT , CONFTYPE_BOOLEAN , read_bool , DUMPTYPE_ALLOW_SPLIT , NULL }, - { CONF_RECOVERY_LIMIT , CONFTYPE_RECOVERY_LIMIT, read_recovery_limit, DUMPTYPE_RECOVERY_LIMIT, NULL }, + { CONF_ALLOW_SPLIT , CONFTYPE_BOOLEAN , read_bool , DUMPTYPE_ALLOW_SPLIT , NULL }, + { CONF_MAX_WARNINGS , CONFTYPE_INT , read_int , DUMPTYPE_MAX_WARNINGS , validate_nonnegative }, + { 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 } }; @@ -1294,6 +1407,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 } }; @@ -1304,6 +1418,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 } }; @@ -1325,6 +1441,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 */ @@ -1506,8 +1636,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) { @@ -1638,7 +1771,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); @@ -1774,7 +1907,10 @@ 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")); + current_block = NULL; } break; @@ -1784,6 +1920,20 @@ read_confline( case CONF_END: /* end of file */ return 0; + /* These should never be at the begining of a line */ + case CONF_LBRACE: + case CONF_RBRACE: + case CONF_IDENT: + case CONF_INT: + case CONF_INT64: + case CONF_BOOL: + case CONF_REAL: + case CONF_STRING: + case CONF_TIME: + case CONF_SIZE: + conf_parserror("error: not a keyword."); + break; + /* if it's not a known punctuation mark, then check the parse table and use the * read_function we find there. */ default: @@ -2047,6 +2197,8 @@ get_holdingdisk( get_conftoken(CONF_IDENT); hdcur.name = stralloc(tokenval.v.s); + current_block = g_strconcat("holdingdisk ", hdcur.name, NULL); + hdcur.seen.block = current_block; hdcur.seen.filename = current_filename; hdcur.seen.linenum = current_line_num; @@ -2111,9 +2263,9 @@ init_holdingdisk_defaults( { conf_init_str(&hdcur.value[HOLDING_COMMENT] , ""); conf_init_str(&hdcur.value[HOLDING_DISKDIR] , ""); - conf_init_int64(&hdcur.value[HOLDING_DISKSIZE] , (gint64)0); + conf_init_int64(&hdcur.value[HOLDING_DISKSIZE] , CONF_UNIT_K, (gint64)0); /* 1 Gb = 1M counted in 1Kb blocks */ - conf_init_int64(&hdcur.value[HOLDING_CHUNKSIZE], (gint64)1024*1024); + conf_init_int64(&hdcur.value[HOLDING_CHUNKSIZE], CONF_UNIT_K, (gint64)1024*1024); } static void @@ -2187,6 +2339,8 @@ read_dumptype( get_conftoken(CONF_IDENT); dpcur.name = stralloc(tokenval.v.s); } + current_block = g_strconcat("dumptype ", dpcur.name, NULL); + dpcur.seen.block = current_block; dpcur.seen.filename = current_filename; dpcur.seen.linenum = current_line_num; @@ -2237,16 +2391,16 @@ 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); - conf_init_int (&dpcur.value[DUMPTYPE_DUMPCYCLE] , conf_data[CNF_DUMPCYCLE].v.i); - conf_init_int (&dpcur.value[DUMPTYPE_MAXDUMPS] , conf_data[CNF_MAXDUMPS].v.i); - conf_init_int (&dpcur.value[DUMPTYPE_MAXPROMOTEDAY] , 10000); - conf_init_int (&dpcur.value[DUMPTYPE_BUMPPERCENT] , conf_data[CNF_BUMPPERCENT].v.i); - conf_init_int64 (&dpcur.value[DUMPTYPE_BUMPSIZE] , conf_data[CNF_BUMPSIZE].v.int64); - conf_init_int (&dpcur.value[DUMPTYPE_BUMPDAYS] , conf_data[CNF_BUMPDAYS].v.i); + conf_init_int (&dpcur.value[DUMPTYPE_DUMPCYCLE] , CONF_UNIT_NONE, conf_data[CNF_DUMPCYCLE].v.i); + conf_init_int (&dpcur.value[DUMPTYPE_MAXDUMPS] , CONF_UNIT_NONE, conf_data[CNF_MAXDUMPS].v.i); + conf_init_int (&dpcur.value[DUMPTYPE_MAXPROMOTEDAY] , CONF_UNIT_NONE, 10000); + conf_init_int (&dpcur.value[DUMPTYPE_BUMPPERCENT] , CONF_UNIT_NONE, conf_data[CNF_BUMPPERCENT].v.i); + conf_init_int64 (&dpcur.value[DUMPTYPE_BUMPSIZE] , CONF_UNIT_K , conf_data[CNF_BUMPSIZE].v.int64); + conf_init_int (&dpcur.value[DUMPTYPE_BUMPDAYS] , CONF_UNIT_NONE, conf_data[CNF_BUMPDAYS].v.i); conf_init_real (&dpcur.value[DUMPTYPE_BUMPMULT] , conf_data[CNF_BUMPMULT].v.r); conf_init_time (&dpcur.value[DUMPTYPE_STARTTIME] , (time_t)0); conf_init_strategy (&dpcur.value[DUMPTYPE_STRATEGY] , DS_STANDARD); @@ -2257,8 +2411,8 @@ init_dumptype_defaults(void) conf_init_str (&dpcur.value[DUMPTYPE_SRV_DECRYPT_OPT] , "-d"); conf_init_str (&dpcur.value[DUMPTYPE_CLNT_DECRYPT_OPT] , "-d"); conf_init_rate (&dpcur.value[DUMPTYPE_COMPRATE] , 0.50, 0.50); - conf_init_int64 (&dpcur.value[DUMPTYPE_TAPE_SPLITSIZE] , (gint64)0); - conf_init_int64 (&dpcur.value[DUMPTYPE_FALLBACK_SPLITSIZE], (gint64)10 * 1024); + conf_init_int64 (&dpcur.value[DUMPTYPE_TAPE_SPLITSIZE] , CONF_UNIT_K, (gint64)0); + conf_init_int64 (&dpcur.value[DUMPTYPE_FALLBACK_SPLITSIZE], CONF_UNIT_K, (gint64)10 * 1024); conf_init_str (&dpcur.value[DUMPTYPE_SPLIT_DISKBUFFER] , NULL); conf_init_bool (&dpcur.value[DUMPTYPE_RECORD] , 1); conf_init_bool (&dpcur.value[DUMPTYPE_SKIP_INCR] , 0); @@ -2271,7 +2425,9 @@ init_dumptype_defaults(void) 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_recovery_limit(&dpcur.value[DUMPTYPE_RECOVERY_LIMIT]); + conf_init_int (&dpcur.value[DUMPTYPE_MAX_WARNINGS] , CONF_UNIT_NONE, 20); + conf_init_host_limit(&dpcur.value[DUMPTYPE_RECOVERY_LIMIT]); + conf_init_host_limit_server(&dpcur.value[DUMPTYPE_DUMP_LIMIT]); } static void @@ -2342,6 +2498,8 @@ get_tapetype(void) get_conftoken(CONF_IDENT); tpcur.name = stralloc(tokenval.v.s); + current_block = g_strconcat("tapetype ", tpcur.name, NULL); + tpcur.seen.block = current_block; tpcur.seen.filename = current_filename; tpcur.seen.linenum = current_line_num; @@ -2352,7 +2510,7 @@ get_tapetype(void) if (tapetype_get_readblocksize(&tpcur) < tapetype_get_blocksize(&tpcur)) { - conf_init_size(&tpcur.value[TAPETYPE_READBLOCKSIZE], + conf_init_size(&tpcur.value[TAPETYPE_READBLOCKSIZE], CONF_UNIT_K, tapetype_get_blocksize(&tpcur)); } save_tapetype(); @@ -2365,15 +2523,15 @@ init_tapetype_defaults(void) { conf_init_str(&tpcur.value[TAPETYPE_COMMENT] , ""); conf_init_str(&tpcur.value[TAPETYPE_LBL_TEMPL] , ""); - conf_init_size (&tpcur.value[TAPETYPE_BLOCKSIZE] , DISK_BLOCK_KB); - conf_init_size (&tpcur.value[TAPETYPE_READBLOCKSIZE], DISK_BLOCK_KB); - 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_int64(&tpcur.value[TAPETYPE_PART_SIZE], 0); + conf_init_size (&tpcur.value[TAPETYPE_BLOCKSIZE] , CONF_UNIT_K, DISK_BLOCK_KB); + conf_init_size (&tpcur.value[TAPETYPE_READBLOCKSIZE], CONF_UNIT_K, DISK_BLOCK_KB); + conf_init_int64 (&tpcur.value[TAPETYPE_LENGTH] , CONF_UNIT_K, ((gint64)2000)); + conf_init_int64 (&tpcur.value[TAPETYPE_FILEMARK] , CONF_UNIT_K, (gint64)1); + conf_init_int (&tpcur.value[TAPETYPE_SPEED] , CONF_UNIT_NONE, 200); + conf_init_int64(&tpcur.value[TAPETYPE_PART_SIZE], CONF_UNIT_K, 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); + conf_init_int64(&tpcur.value[TAPETYPE_PART_CACHE_MAX_SIZE], CONF_UNIT_K, 0); } static void @@ -2437,6 +2595,8 @@ get_interface(void) get_conftoken(CONF_IDENT); ifcur.name = stralloc(tokenval.v.s); + current_block = g_strconcat("interface ", ifcur.name, NULL); + ifcur.seen.block = current_block; ifcur.seen.filename = current_filename; ifcur.seen.linenum = current_line_num; @@ -2456,7 +2616,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], CONF_UNIT_K, 80000); } static void @@ -2507,7 +2667,7 @@ copy_interface(void) } -application_t * +static application_t * read_application( char *name, FILE *from, @@ -2541,6 +2701,8 @@ read_application( get_conftoken(CONF_IDENT); apcur.name = stralloc(tokenval.v.s); } + current_block = g_strconcat("application ", apcur.name, NULL); + apcur.seen.block = current_block; apcur.seen.filename = current_filename; apcur.seen.linenum = current_line_num; @@ -2582,6 +2744,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 @@ -2633,7 +2796,263 @@ 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); + } + current_block = g_strconcat("interactivity ", ivcur.name, NULL); + ivcur.seen.block = current_block; + 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); + } + current_block = g_strconcat("taperscan ", tscur.name, NULL); + tscur.seen.block = current_block; + 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, @@ -2667,6 +3086,8 @@ read_pp_script( get_conftoken(CONF_IDENT); pscur.name = stralloc(tokenval.v.s); } + current_block = g_strconcat("script ", pscur.name, NULL); + pscur.seen.block = current_block; pscur.seen.filename = current_filename; pscur.seen.linenum = current_line_num; @@ -2710,7 +3131,9 @@ init_pp_script_defaults( conf_init_proplist(&pscur.value[PP_SCRIPT_PROPERTY]); 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_int(&pscur.value[PP_SCRIPT_ORDER], CONF_UNIT_NONE, 5000); + conf_init_bool(&pscur.value[PP_SCRIPT_SINGLE_EXECUTION], 0); + conf_init_str(&pscur.value[PP_SCRIPT_CLIENT_NAME], ""); } static void @@ -2762,7 +3185,7 @@ copy_pp_script(void) } } -device_config_t * +static device_config_t * read_device_config( char *name, FILE *from, @@ -2796,6 +3219,8 @@ read_device_config( get_conftoken(CONF_IDENT); dccur.name = stralloc(tokenval.v.s); } + current_block = g_strconcat("device ", dccur.name, NULL); + dccur.seen.block = current_block; dccur.seen.filename = current_filename; dccur.seen.linenum = current_line_num; @@ -2888,7 +3313,7 @@ copy_device_config(void) } } -changer_config_t * +static changer_config_t * read_changer_config( char *name, FILE *from, @@ -2922,7 +3347,10 @@ read_changer_config( get_conftoken(CONF_IDENT); cccur.name = stralloc(tokenval.v.s); } - cccur.seen = current_line_num; + current_block = g_strconcat("changer ", cccur.name, NULL); + cccur.seen.block = current_block; + cccur.seen.filename = current_filename; + cccur.seen.linenum = current_line_num; read_block(changer_config_var, cccur.value, _("changer parameter expected"), @@ -2977,8 +3405,8 @@ save_changer_config( dc = lookup_changer_config(cccur.name); if(dc != (changer_config_t *)0) { - conf_parserror(_("changer %s already defined on line %d"), - dc->name, dc->seen); + conf_parserror(_("changer %s already defined at %s:%d"), + dc->name, dc->seen.filename, dc->seen.linenum); return; } @@ -3025,7 +3453,7 @@ read_int( val_t *val) { ckseen(&val->seen); - val_t__int(val) = get_int(); + val_t__int(val) = get_int(val->unit); } static void @@ -3034,7 +3462,7 @@ read_int64( val_t *val) { ckseen(&val->seen); - val_t__int64(val) = get_int64(); + val_t__int64(val) = get_int64(val->unit); } static void @@ -3082,25 +3510,25 @@ read_size( val_t *val) { ckseen(&val->seen); - val_t__size(val) = get_size(); + val_t__size(val) = get_size(val->unit); } static void -read_size_byte( +read_bool( conf_var_t *np G_GNUC_UNUSED, val_t *val) { ckseen(&val->seen); - val_t__size(val) = get_size_byte(); + val_t__boolean(val) = get_bool(); } static void -read_bool( +read_no_yes_all( conf_var_t *np G_GNUC_UNUSED, val_t *val) { ckseen(&val->seen); - val_t__boolean(val) = get_bool(); + val_t__int(val) = get_no_yes_all(); } static void @@ -3345,8 +3773,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")); } @@ -3415,7 +3843,7 @@ read_exinclude( val_t *val) { int file, got_one = 0; - sl_t *exclude; + am_sl_t *exclude; int optional = 0; get_conftoken(CONF_ANY); @@ -3495,6 +3923,7 @@ read_property( val_t *val) { char *key; + gboolean set_seen = TRUE; property_t *property = malloc(sizeof(property_t)); property_t *old_property; property->append = 0; @@ -3528,8 +3957,7 @@ read_property( } if(val->seen.linenum == 0) { - val->seen.filename = current_filename; - val->seen.linenum = current_line_num; + ckseen(&val->seen); // first property } old_property = g_hash_table_lookup(val->v.proplist, key); @@ -3541,6 +3969,7 @@ read_property( property->priority = 1; property->values = old_property->values; old_property->values = NULL; + set_seen = FALSE; } } while(tok == CONF_STRING) { @@ -3550,6 +3979,12 @@ read_property( } unget_conftoken(); g_hash_table_insert(val->v.proplist, key, property); + if (set_seen) { + property->seen.linenum = 0; + property->seen.filename = NULL; + property->seen.block = NULL; + ckseen(&property->seen); + } } @@ -3583,6 +4018,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, @@ -3627,16 +4120,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; @@ -3645,7 +4144,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) { @@ -3700,7 +4199,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")); } } @@ -3779,13 +4278,17 @@ read_part_cache_type( } static void -read_recovery_limit( +read_host_limit( conf_var_t *np G_GNUC_UNUSED, val_t *val) { - recovery_limit_t *rl = &val_t__recovery_limit(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) { @@ -3796,6 +4299,10 @@ read_recovery_limit( rl->same_host = TRUE; break; + case CONF_SERVER: + rl->server = TRUE; + break; + case CONF_NL: case CONF_END: return; @@ -3859,7 +4366,8 @@ get_time(void) } static int -get_int(void) +get_int( + confunit_t unit) { int val; keytab_t *save_kt; @@ -3904,153 +4412,15 @@ get_int(void) } /* get multiplier, if any */ - get_conftoken(CONF_ANY); - switch(tok) { - case CONF_NL: /* multiply by one */ - case CONF_END: - case CONF_MULT1: - case CONF_MULT1K: - break; - - case CONF_MULT7: - if (val > (INT_MAX / 7)) - conf_parserror(_("value too large")); - if (val < (INT_MIN / 7)) - conf_parserror(_("value too small")); - val *= 7; - break; - - case CONF_MULT1M: - if (val > (INT_MAX / 1024)) - conf_parserror(_("value too large")); - if (val < (INT_MIN / 1024)) - conf_parserror(_("value too small")); - val *= 1024; - break; - - case CONF_MULT1G: - if (val > (INT_MAX / (1024 * 1024))) - conf_parserror(_("value too large")); - if (val < (INT_MIN / (1024 * 1024))) - conf_parserror(_("value too small")); - val *= 1024 * 1024; - break; - - case CONF_MULT1T: - if (val > (INT_MAX / (1024 * 1024 * 1024))) - conf_parserror(_("value too large")); - if (val < (INT_MIN / (1024 * 1024 * 1024))) - conf_parserror(_("value too small")); - val *= 1024 * 1024 * 1024; - break; - - default: /* it was not a multiplier */ - unget_conftoken(); - break; - } - - keytable = save_kt; - return val; -} - -static ssize_t -get_size(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: - case CONF_MULT1K: - break; - - 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)) - conf_parserror(_("value too large")); - if (val < (ssize_t)(SSIZE_MIN / (ssize_t)1024)) - conf_parserror(_("value too small")); - val *= (ssize_t)1024; - break; - - case CONF_MULT1G: - if (val > (ssize_t)(SSIZE_MAX / (1024 * 1024))) - conf_parserror(_("value too large")); - if (val < (ssize_t)(SSIZE_MIN / (1024 * 1024))) - conf_parserror(_("value too small")); - val *= (ssize_t)(1024 * 1024); - break; - - case CONF_MULT1T: - if (val > (INT_MAX / (1024 * 1024 * 1024))) - conf_parserror(_("value too large")); - if (val < (INT_MIN / (1024 * 1024 * 1024))) - conf_parserror(_("value too small")); - val *= 1024 * 1024 * 1024; - break; - - default: /* it was not a multiplier */ - unget_conftoken(); - break; - } + val = get_multiplier(val, unit); keytable = save_kt; return val; } static ssize_t -get_size_byte(void) +get_size( + confunit_t unit) { ssize_t val; keytab_t *save_kt; @@ -4096,58 +4466,15 @@ get_size_byte(void) } /* 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; - } + val = get_multiplier(val, unit); keytable = save_kt; return val; } static gint64 -get_int64(void) +get_int64( + confunit_t unit) { gint64 val; keytab_t *save_kt; @@ -4181,45 +4508,54 @@ get_int64(void) } /* get multiplier, if any */ - get_conftoken(CONF_ANY); + val = get_multiplier(val, unit); - switch(tok) { - case CONF_NL: /* multiply by one */ - case CONF_MULT1: - case CONF_MULT1K: - break; + keytable = save_kt; + + return val; +} + +gint64 +get_multiplier( + gint64 val, + confunit_t unit) +{ + /* get multiplier, if any */ + get_conftoken(CONF_ANY); - case CONF_MULT7: + if (tok == CONF_MULT1 && unit == CONF_UNIT_K) { + val /= 1024; + } else if (tok == CONF_NL || tok == CONF_MULT1 || + (tok == CONF_MULT1K && unit == CONF_UNIT_K)) { + val *= 1; /* multiply by one */ + } else if (tok == CONF_MULT7) { if (val > G_MAXINT64/7 || val < ((gint64)G_MININT64)/7) conf_parserror(_("value too large")); val *= 7; - break; - - case CONF_MULT1M: + } else if (tok == CONF_MULT1K || + (tok == CONF_MULT1M && unit == CONF_UNIT_K)) { if (val > G_MAXINT64/1024 || val < ((gint64)G_MININT64)/1024) conf_parserror(_("value too large")); val *= 1024; - break; - - case CONF_MULT1G: + } else if (tok == CONF_MULT1M || + (tok == CONF_MULT1G && unit == CONF_UNIT_K)) { if (val > G_MAXINT64/(1024*1024) || val < ((gint64)G_MININT64)/(1024*1024)) conf_parserror(_("value too large")); val *= 1024*1024; - break; - - case CONF_MULT1T: + } else if (tok == CONF_MULT1G || + (tok == CONF_MULT1T && unit == CONF_UNIT_K)) { if (val > G_MAXINT64/(1024*1024*1024) || val < ((gint64)G_MININT64)/(1024*1024*1024)) conf_parserror(_("value too large")); val *= 1024*1024*1024; - break; - - default: /* it was not a multiplier */ + } else if (tok == CONF_MULT1T) { + if (val > G_MAXINT64/(1024*1024*1024*1024LL) || val < ((gint64)G_MININT64)/(1024*1024*1024*1024LL)) + conf_parserror(_("value too large")); + val *= 1024*1024*1024*1024LL; + } else { + val *= 1; unget_conftoken(); - break; } - keytable = save_kt; - return val; } @@ -4279,6 +4615,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) @@ -4287,6 +4676,7 @@ ckseen( conf_parserror(_("duplicate parameter; previous definition %s:%d"), seen->filename, seen->linenum); } + seen->block = current_block; seen->filename = current_filename; seen->linenum = current_line_num; } @@ -4529,6 +4919,31 @@ validate_unreserved_port_range( validate_port_range(val, IPPORT_RESERVED, 65535); } +/* + * Validate tmpdir, the directory must exist and be writable by the user. + */ + +static void validate_tmpdir(conf_var_t *var G_GNUC_UNUSED, val_t *value) +{ + struct stat stat_buf; + gchar *tmpdir = val_t_to_str(value); + + if (stat(tmpdir, &stat_buf)) { + conf_parserror(_("invalid TMPDIR: directory '%s': %s."), + tmpdir, strerror(errno)); + } else if (!S_ISDIR(stat_buf.st_mode)) { + conf_parserror(_("invalid TMPDIR: '%s' is not a directory."), + tmpdir); + } else { + gchar *dir = g_strconcat(tmpdir, "/.", NULL); + if (access(dir, R_OK|W_OK) == -1) { + conf_parserror(_("invalid TMPDIR: '%s': can not read/write: %s."), + tmpdir, strerror(errno)); + } + g_free(dir); + } +} + /* * Initialization Implementation */ @@ -4583,7 +4998,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); @@ -4657,6 +5071,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; @@ -4668,7 +5084,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) { @@ -4739,9 +5155,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; iseen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_INT; + val->unit = unit; val_t__int(val) = i; } static void conf_init_int64( val_t *val, + confunit_t unit, gint64 l) { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_INT64; + val->unit = unit; val_t__int64(val) = l; } @@ -5140,7 +5596,9 @@ conf_init_real( { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_REAL; + val->unit = CONF_UNIT_NONE; val_t__real(val) = r; } @@ -5151,7 +5609,9 @@ conf_init_str( { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_STR; + val->unit = CONF_UNIT_NONE; if(s) val->v.s = stralloc(s); else @@ -5165,7 +5625,9 @@ conf_init_ident( { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_IDENT; + val->unit = CONF_UNIT_NONE; if(s) val->v.s = stralloc(s); else @@ -5179,7 +5641,9 @@ conf_init_identlist( { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_IDENTLIST; + val->unit = CONF_UNIT_NONE; val->v.identlist = NULL; if (s) val->v.identlist = g_slist_append(val->v.identlist, stralloc(s)); @@ -5192,18 +5656,23 @@ conf_init_time( { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_TIME; + val->unit = CONF_UNIT_NONE; val_t__time(val) = t; } static void conf_init_size( val_t *val, + confunit_t unit, ssize_t sz) { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_SIZE; + val->unit = unit; val_t__size(val) = sz; } @@ -5214,10 +5683,25 @@ conf_init_bool( { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_BOOLEAN; + val->unit = CONF_UNIT_NONE; 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->seen.block = NULL; + val->type = CONFTYPE_NO_YES_ALL; + val->unit = CONF_UNIT_NONE; + val_t__int(val) = i; +} + static void conf_init_compress( val_t *val, @@ -5225,7 +5709,9 @@ conf_init_compress( { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_COMPRESS; + val->unit = CONF_UNIT_NONE; val_t__compress(val) = (int)i; } @@ -5236,7 +5722,9 @@ conf_init_encrypt( { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_ENCRYPT; + val->unit = CONF_UNIT_NONE; val_t__encrypt(val) = (int)i; } @@ -5247,19 +5735,32 @@ conf_init_part_cache_type( { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_PART_CACHE_TYPE; + val->unit = CONF_UNIT_NONE; val_t__part_cache_type(val) = (int)i; } static void -conf_init_recovery_limit( +conf_init_host_limit( val_t *val) { val->seen.linenum = 0; val->seen.filename = NULL; - val->type = CONFTYPE_RECOVERY_LIMIT; - val_t__recovery_limit(val).match_pats = NULL; - val_t__recovery_limit(val).same_host = FALSE; + val->seen.block = NULL; + val->type = CONFTYPE_HOST_LIMIT; + val->unit = CONF_UNIT_NONE; + 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 @@ -5269,7 +5770,9 @@ conf_init_data_path( { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_DATA_PATH; + val->unit = CONF_UNIT_NONE; val_t__data_path(val) = (int)i; } @@ -5280,7 +5783,9 @@ conf_init_holding( { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_HOLDING; + val->unit = CONF_UNIT_NONE; val_t__holding(val) = (int)i; } @@ -5292,7 +5797,9 @@ conf_init_estimatelist( GSList *estimates = NULL; val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_ESTIMATELIST; + val->unit = CONF_UNIT_NONE; estimates = g_slist_append(estimates, GINT_TO_POINTER(i)); val_t__estimatelist(val) = estimates; } @@ -5304,6 +5811,8 @@ conf_init_strategy( { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; + val->unit = CONF_UNIT_NONE; val->type = CONFTYPE_STRATEGY; val_t__strategy(val) = i; } @@ -5315,7 +5824,9 @@ conf_init_taperalgo( { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_TAPERALGO; + val->unit = CONF_UNIT_NONE; val_t__taperalgo(val) = i; } @@ -5326,7 +5837,9 @@ conf_init_priority( { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_PRIORITY; + val->unit = CONF_UNIT_NONE; val_t__priority(val) = i; } @@ -5338,7 +5851,9 @@ conf_init_rate( { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_RATE; + val->unit = CONF_UNIT_NONE; val_t__rate(val)[0] = r1; val_t__rate(val)[1] = r2; } @@ -5349,7 +5864,9 @@ conf_init_exinclude( { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_EXINCLUDE; + val->unit = CONF_UNIT_NONE; val_t__exinclude(val).optional = 0; val_t__exinclude(val).sl_list = NULL; val_t__exinclude(val).sl_file = NULL; @@ -5363,7 +5880,9 @@ conf_init_intrange( { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_INTRANGE; + val->unit = CONF_UNIT_NONE; val_t__intrange(val)[0] = i1; val_t__intrange(val)[1] = i2; } @@ -5373,7 +5892,9 @@ conf_init_autolabel( val_t *val) { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_AUTOLABEL; + val->unit = CONF_UNIT_NONE; val->v.autolabel.template = NULL; val->v.autolabel.autolabel = 0; } @@ -5383,7 +5904,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); } @@ -5393,7 +5914,9 @@ conf_init_proplist( { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_PROPLIST; + val->unit = CONF_UNIT_NONE; val_t__proplist(val) = g_hash_table_new_full(g_str_amanda_hash, g_str_amanda_equal, &g_free, &free_property_t); @@ -5406,7 +5929,9 @@ conf_init_execute_on( { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_EXECUTE_ON; + val->unit = CONF_UNIT_NONE; val->v.i = i; } @@ -5417,7 +5942,9 @@ conf_init_execute_where( { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_EXECUTE_WHERE; + val->unit = CONF_UNIT_NONE; val->v.i = i; } @@ -5428,14 +5955,18 @@ conf_init_send_amreport( { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_SEND_AMREPORT_ON; + val->unit = CONF_UNIT_NONE; val->v.i = i; } static void conf_init_application(val_t *val) { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_APPLICATION; + val->unit = CONF_UNIT_NONE; val->v.s = NULL; } @@ -5464,6 +5995,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) { @@ -5503,6 +6036,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; } @@ -5553,6 +6094,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) @@ -5690,6 +6241,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) @@ -6075,6 +6686,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) @@ -6111,16 +6734,16 @@ val_t_to_part_cache_type( return val_t__part_cache_type(val); } -recovery_limit_t * -val_t_to_recovery_limit( +host_limit_t * +val_t_to_host_limit( val_t *val) { assert(config_initialized); - if (val->type != CONFTYPE_RECOVERY_LIMIT) { - error(_("val_t_to_recovery_limit: val.type is not CONFTYPE_RECOVERY_LIMIT")); + if (val->type != CONFTYPE_HOST_LIMIT) { + error(_("val_t_to_host_limit: val.type is not CONFTYPE_HOST_LIMIT")); /*NOTREACHED*/ } - return &val_t__recovery_limit(val); + return &val_t__host_limit(val); } dump_holdingdisk_t @@ -6275,6 +6898,12 @@ merge_val_t( { if (valsrc->type == CONFTYPE_PROPLIST) { if (valsrc->v.proplist) { + if (valdst->v.proplist == NULL || + g_hash_table_size(valdst->v.proplist) == 0) { + valdst->seen.block = current_block; + valdst->seen.filename = current_filename; + valdst->seen.linenum = current_line_num; + } if (valdst->v.proplist == NULL) { valdst->v.proplist = g_hash_table_new_full(g_str_amanda_hash, g_str_amanda_equal, @@ -6316,6 +6945,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: @@ -6360,12 +6990,12 @@ copy_val_t( } break; - case CONFTYPE_RECOVERY_LIMIT: - valdst->v.recovery_limit = valsrc->v.recovery_limit; - valdst->v.recovery_limit.match_pats = NULL; - for (ia = valsrc->v.recovery_limit.match_pats; ia != NULL; ia = ia->next) { - valdst->v.recovery_limit.match_pats = - g_slist_append(valdst->v.recovery_limit.match_pats, g_strdup(ia->data)); + 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; @@ -6440,6 +7070,7 @@ merge_proplist_foreach_fn( } if (!new_property) { new_property = malloc(sizeof(property_t)); + new_property->seen = property->seen; new_property->append = property->append; new_property->priority = property->priority; new_property->values = NULL; @@ -6467,6 +7098,7 @@ copy_proplist_foreach_fn( property_t *new_property = malloc(sizeof(property_t)); new_property->append = property->append; new_property->priority = property->priority; + new_property->seen = property->seen; new_property->values = NULL; for(elem = property->values;elem != NULL; elem=elem->next) { @@ -6483,6 +7115,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: @@ -6508,11 +7141,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_RECOVERY_LIMIT: - g_slist_free_full(val->v.recovery_limit.match_pats); + case CONFTYPE_HOST_LIMIT: + slist_free_full(val->v.host_limit.match_pats, g_free); break; case CONFTYPE_TIME: @@ -6537,6 +7170,7 @@ free_val_t( } val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; } /* @@ -6572,6 +7206,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) { @@ -6601,7 +7237,9 @@ generic_client_get_security_conf( } void -dump_configuration(void) +dump_configuration( + gboolean print_default, + gboolean print_source) { tapetype_t *tp; dumptype_t *dp; @@ -6612,6 +7250,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; @@ -6631,7 +7271,7 @@ dump_configuration(void) if(kt->token == CONF_UNKNOWN) error(_("server bad token")); - val_t_print_token(stdout, NULL, "%-21s ", kt, &conf_data[np->parm]); + val_t_print_token(print_default, print_source, stdout, NULL, "%-21s ", kt, &conf_data[np->parm]); } for(hp = holdinglist; hp != NULL; hp = hp->next) { @@ -6652,7 +7292,7 @@ dump_configuration(void) if(kt->token == CONF_UNKNOWN) error(_("holding bad token")); - val_t_print_token(stdout, NULL, " %-9s ", kt, &hd->value[i]); + val_t_print_token(print_default, print_source, stdout, NULL, " %-9s ", kt, &hd->value[i]); } g_printf("}\n"); } @@ -6674,7 +7314,7 @@ dump_configuration(void) if(kt->token == CONF_UNKNOWN) error(_("tapetype bad token")); - val_t_print_token(stdout, prefix, " %-9s ", kt, &tp->value[i]); + val_t_print_token(print_default, print_source, stdout, prefix, " %-9s ", kt, &tp->value[i]); } g_printf("%s}\n", prefix); } @@ -6697,7 +7337,7 @@ dump_configuration(void) if(kt->token == CONF_UNKNOWN) error(_("dumptype bad token")); - val_t_print_token(stdout, prefix, " %-19s ", kt, &dp->value[i]); + val_t_print_token(print_default, print_source, stdout, prefix, " %-19s ", kt, &dp->value[i]); } g_printf("%s}\n", prefix); } @@ -6723,7 +7363,7 @@ dump_configuration(void) if(kt->token == CONF_UNKNOWN) error(_("interface bad token")); - val_t_print_token(stdout, prefix, " %-19s ", kt, &ip->value[i]); + val_t_print_token(print_default, print_source, stdout, prefix, " %-19s ", kt, &ip->value[i]); } g_printf("%s}\n",prefix); } @@ -6745,7 +7385,7 @@ dump_configuration(void) if(kt->token == CONF_UNKNOWN) error(_("application bad token")); - val_t_print_token(stdout, prefix, " %-19s ", kt, &ap->value[i]); + val_t_print_token(print_default, print_source, stdout, prefix, " %-19s ", kt, &ap->value[i]); } g_printf("%s}\n",prefix); } @@ -6767,7 +7407,7 @@ dump_configuration(void) if(kt->token == CONF_UNKNOWN) error(_("script bad token")); - val_t_print_token(stdout, prefix, " %-19s ", kt, &ps->value[i]); + val_t_print_token(print_default, print_source, stdout, prefix, " %-19s ", kt, &ps->value[i]); } g_printf("%s}\n",prefix); } @@ -6786,7 +7426,7 @@ dump_configuration(void) if(kt->token == CONF_UNKNOWN) error(_("device bad token")); - val_t_print_token(stdout, prefix, " %-19s ", kt, &dc->value[i]); + val_t_print_token(print_default, print_source, stdout, prefix, " %-19s ", kt, &dc->value[i]); } g_printf("%s}\n",prefix); } @@ -6805,14 +7445,79 @@ dump_configuration(void) if(kt->token == CONF_UNKNOWN) error(_("changer bad token")); - val_t_print_token(stdout, prefix, " %-19s ", kt, &cc->value[i]); + val_t_print_token(print_default, print_source, stdout, prefix, " %-19s ", kt, &cc->value[i]); + } + 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(print_default, print_source, 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(print_default, print_source, stdout, prefix, " %-19s ", kt, &ts->value[i]); } g_printf("%s}\n",prefix); } } +void dump_dumptype( + dumptype_t *dp, + char *prefix, + gboolean print_default, + gboolean print_source) +{ + int i; + conf_var_t *np; + keytab_t *kt; + + 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")); + + val_t_print_token(print_default, print_source, stdout, prefix, " %-19s ", kt, &dp->value[i]); + } +} + static void val_t_print_token( + gboolean print_default, + gboolean print_source, FILE *output, char *prefix, char *format, @@ -6820,7 +7525,12 @@ val_t_print_token( val_t *val) { char **dispstrs, **dispstr; - dispstrs = val_t_display_strs(val, 1); + + if (print_default == 0 && !val_t_seen(val)) { + return; + } + + dispstrs = val_t_display_strs(val, 1, print_source, TRUE); /* For most configuration types, this outputs * PREFIX KEYWORD DISPSTR @@ -6833,7 +7543,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 { @@ -6847,11 +7557,40 @@ val_t_print_token( g_strfreev(dispstrs); } +typedef struct proplist_display_str_foreach_user_data { + char **msg; + gboolean print_source; +} proplist_display_str_foreach_user_data; + +char *source_string(seen_t *seen); +char *source_string( + seen_t *seen) +{ + char *buf; + + if (seen->linenum) { + if (seen->block) { + buf = g_strdup_printf(" (%s file %s line %d)", + seen->block, seen->filename, seen->linenum); + } else { + buf = g_strdup_printf(" (file %s line %d)", + seen->filename, seen->linenum); + } + } else { + buf = g_strdup(" (default)"); + } + return buf; +} + char ** val_t_display_strs( val_t *val, - int str_need_quote) + int str_need_quote, + gboolean print_source, + gboolean print_unit) { + gboolean add_source = TRUE; + int i; char **buf; buf = malloc(3*SIZEOF(char *)); buf[0] = NULL; @@ -6860,15 +7599,33 @@ val_t_display_strs( switch(val->type) { case CONFTYPE_INT: - buf[0] = vstrallocf("%d", val_t__int(val)); + buf[0] = vstrallocf("%d ", val_t__int(val)); + i = strlen(buf[0]) - 1; + if (print_unit && val->unit == CONF_UNIT_K) { + buf[0][i] = 'K'; + } else { + buf[0][i] = '\0'; + } break; case CONFTYPE_SIZE: - buf[0] = vstrallocf("%zd", (ssize_t)val_t__size(val)); + buf[0] = vstrallocf("%zd ", (ssize_t)val_t__size(val)); + i = strlen(buf[0]) - 1; + if (print_unit && val->unit == CONF_UNIT_K) { + buf[0][i] = 'K'; + } else { + buf[0][i] = '\0'; + } break; case CONFTYPE_INT64: - buf[0] = vstrallocf("%lld", (long long)val_t__int64(val)); + buf[0] = vstrallocf("%lld ", (long long)val_t__int64(val)); + i = strlen(buf[0]) - 1; + if (print_unit && val->unit == CONF_UNIT_K) { + buf[0][i] = 'K'; + } else { + buf[0][i] = '\0'; + } break; case CONFTYPE_REAL: @@ -6961,6 +7718,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: @@ -7113,16 +7884,19 @@ val_t_display_strs( } break; - case CONFTYPE_RECOVERY_LIMIT: { - GSList *iter = val_t__recovery_limit(val).match_pats; + case CONFTYPE_HOST_LIMIT: { + GSList *iter = val_t__host_limit(val).match_pats; - if(val_t__recovery_limit(val).same_host) + 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], (char *)iter->data); + strappend(buf[0], quote_string_always((char *)iter->data)); strappend(buf[0], " "); iter = iter->next; } @@ -7167,16 +7941,18 @@ val_t_display_strs( case CONFTYPE_PROPLIST: { int nb_property; - char **mybuf; + proplist_display_str_foreach_user_data user_data; nb_property = g_hash_table_size(val_t__proplist(val)); - amfree(buf); + g_free(buf); buf = malloc((nb_property+1)*SIZEOF(char*)); buf[nb_property] = NULL; - mybuf = buf; + user_data.msg = buf; + user_data.print_source = print_source; g_hash_table_foreach(val_t__proplist(val), proplist_display_str_foreach_fn, - &mybuf); + &user_data); + add_source = FALSE; break; } @@ -7193,6 +7969,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 = ", "; @@ -7209,6 +7989,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 = ", "; @@ -7225,6 +8013,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 = ", "; @@ -7233,6 +8029,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 = ", "; @@ -7265,6 +8065,16 @@ val_t_display_strs( break; } + + /* add source */ + if (print_source && add_source) { + char **buf1; + for (buf1 = buf; *buf1 != NULL; buf1++) { + char *buf2 = g_strjoin("", *buf1, source_string(&val->seen), NULL); + g_free(*buf1); + *buf1 = buf2; + } + } return buf; } @@ -7311,7 +8121,8 @@ proplist_display_str_foreach_fn( char *property_s = quote_string_always(key_p); property_t *property = value_p; GSList *value; - char ***msg = (char ***)user_data_p; + proplist_display_str_foreach_user_data *user_data = user_data_p; + char ***msg = (char ***)&user_data->msg; /* What to do with property->append? it should be printed only on client */ if (property->priority) { @@ -7326,6 +8137,9 @@ proplist_display_str_foreach_fn( **msg = vstrextend(*msg, " ", qstr, NULL); amfree(qstr); } + if (user_data->print_source) { + **msg = vstrextend(*msg, source_string(&property->seen)); + } (*msg)++; } @@ -7334,7 +8148,7 @@ exinclude_display_str( val_t *val, int file) { - sl_t *sl; + am_sl_t *sl; sle_t *excl; char *rval; @@ -7414,6 +8228,8 @@ parm_key_info( pp_script_t *pp; device_config_t *dc; changer_config_t *cc; + taperscan_t *ts; + interactivity_t *iv; int success = FALSE; /* WARNING: assumes globals keytable and parsetable are set correctly. */ @@ -7441,7 +8257,7 @@ parm_key_info( if (*s == '-') *s = '_'; } - subsec_key = strchr(subsec_name,':'); + subsec_key = strrchr(subsec_name,':'); if(!subsec_key) goto out; /* failure */ *subsec_key = '\0'; @@ -7562,6 +8378,30 @@ parm_key_info( if (val) *val = &cc->value[np->parm]; if (parm) *parm = np; success = TRUE; + } else if (g_str_equal(subsec_type, "INTERACTIVITY")) { + iv = lookup_interactivity(subsec_name); + if (!iv) goto out; + for(np = interactivity_var; np->token != CONF_UNKNOWN; np++) { + if(np->token == kt->token) + break; + } + if (np->token == CONF_UNKNOWN) goto out; + + if (val) *val = &iv->value[np->parm]; + if (parm) *parm = np; + success = TRUE; + } else if (g_str_equal(subsec_type, "TAPERSCAN")) { + ts = lookup_taperscan(subsec_name); + if (!ts) goto out; + for(np = taperscan_var; np->token != CONF_UNKNOWN; np++) { + if(np->token == kt->token) + break; + } + if (np->token == CONF_UNKNOWN) goto out; + + if (val) *val = &ts->value[np->parm]; + if (parm) *parm = np; + success = TRUE; } /* No delimiters -- we're referencing a global config parameter */ @@ -7737,7 +8577,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; @@ -7836,3 +8676,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; +}