eliminate gratuitious comment change in source code
[debian/amanda] / common-src / conffile.c
index 11ea02d1e060f222a46cd5460867e3bd2ca5602f..4d48220ae02cbd47b0c6acdc07d259eb5ae33aa8 100644 (file)
@@ -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,      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,
@@ -122,16 +127,18 @@ 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,
+    CONF_MAX_WARNINGS,
 
     /* 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 +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,
+
+    /* host-limit */
+    CONF_RECOVERY_LIMIT,       CONF_SAME_HOST,         CONF_DUMP_LIMIT,
 
     /* holdingdisk */
     CONF_NEVER,                        CONF_AUTO,              CONF_REQUIRED,
@@ -183,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.
@@ -213,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);
 
@@ -337,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;
 
@@ -461,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
@@ -474,6 +524,7 @@ 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_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 +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 *);
@@ -494,17 +547,33 @@ 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
  * 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 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
@@ -518,6 +587,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 +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);
 
 /*
@@ -576,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;
@@ -619,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);
@@ -645,6 +721,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
@@ -680,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
@@ -721,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 },
@@ -768,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 },
@@ -797,6 +884,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 +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 },
@@ -857,6 +946,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 +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 },
@@ -877,7 +969,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 +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 },
@@ -909,10 +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 },
@@ -923,17 +1019,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 +1052,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 +1061,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 +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 },
@@ -973,17 +1082,19 @@ 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 },
     { "TAPETYPE", CONF_TAPETYPE },
     { "TAPE_SPLITSIZE", CONF_TAPE_SPLITSIZE },
+    { "TMPDIR", CONF_TMPDIR },
     { "TPCHANGER", CONF_TPCHANGER },
     { "UNRESERVED_TCP_PORT", CONF_UNRESERVED_TCP_PORT },
     { "USE", CONF_USE },
@@ -1058,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 },
@@ -1137,25 +1265,29 @@ 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_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_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 },
@@ -1184,19 +1316,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 +1379,12 @@ 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_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 }
 };
 
@@ -1265,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 }
 };
 
@@ -1275,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 }
 };
 
@@ -1296,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
  */
@@ -1477,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) {
@@ -1609,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);
@@ -1745,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;
 
@@ -1755,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:
@@ -1779,29 +1958,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 +1998,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 +2078,8 @@ read_block(
     do {
        current_line_num += 1;
        get_conftoken(CONF_ANY);
+       handle_deprecated_keyword();
+
        switch(tok) {
        case CONF_RBRACE:
            done = 1;
@@ -1997,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;
 
@@ -2061,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
@@ -2137,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;
 
@@ -2187,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);
@@ -2207,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);
@@ -2220,6 +2424,10 @@ 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_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
@@ -2290,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;
 
@@ -2300,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();
@@ -2313,12 +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_bool  (&tpcur.value[TAPETYPE_FILE_PAD]     , 1);
+    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], CONF_UNIT_K, 0);
 }
 
 static void
@@ -2337,6 +2550,7 @@ save_tapetype(void)
 
     tp = alloc(sizeof(tapetype_t));
     *tp = tpcur;
+
     /* add at end of list */
     if(!tapelist)
        tapelist = tp;
@@ -2381,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;
 
@@ -2400,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
@@ -2451,7 +2667,7 @@ copy_interface(void)
 }
 
 
-application_t *
+static application_t *
 read_application(
     char *name,
     FILE *from,
@@ -2485,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;
 
@@ -2526,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
@@ -2577,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,
@@ -2611,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;
 
@@ -2654,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
@@ -2706,7 +3185,7 @@ copy_pp_script(void)
     }
 }
 
-device_config_t *
+static device_config_t *
 read_device_config(
     char *name,
     FILE *from,
@@ -2740,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;
 
@@ -2832,7 +3313,7 @@ copy_device_config(void)
     }
 }
 
-changer_config_t *
+static changer_config_t *
 read_changer_config(
     char *name,
     FILE *from,
@@ -2866,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"),
@@ -2921,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;
     }
 
@@ -2969,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
@@ -2978,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
@@ -3026,7 +3510,7 @@ read_size(
     val_t *val)
 {
     ckseen(&val->seen);
-    val_t__size(val) = get_size();
+    val_t__size(val) = get_size(val->unit);
 }
 
 static void
@@ -3038,6 +3522,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 +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"));
     }
@@ -3350,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);
@@ -3430,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; 
@@ -3449,7 +3943,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) {
@@ -3463,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);
@@ -3476,6 +3969,7 @@ read_property(
                property->priority = 1;
            property->values = old_property->values;
            old_property->values = NULL;
+           set_seen = FALSE;
        }
     }
     while(tok == CONF_STRING) {
@@ -3485,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);
+    }
 }
 
 
@@ -3518,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,
@@ -3562,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;
@@ -3580,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) {
@@ -3635,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"));
     }
 }
 
@@ -3669,7 +4233,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 +4245,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
@@ -3733,7 +4366,8 @@ get_time(void)
 }
 
 static int
-get_int(void)
+get_int(
+    confunit_t unit)
 {
     int val;
     keytab_t *save_kt;
@@ -3778,57 +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;
-    }
+    val = get_multiplier(val, unit);
 
     keytable = save_kt;
     return val;
 }
 
 static ssize_t
-get_size(void)
+get_size(
+    confunit_t unit)
 {
     ssize_t val;
     keytab_t *save_kt;
@@ -3874,57 +4466,15 @@ get_size(void)
     }
 
     /* 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 gint64
-get_int64(void)
+get_int64(
+    confunit_t unit)
 {
     gint64 val;
     keytab_t *save_kt;
@@ -3958,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;
 
-    case CONF_MULT7:
+    return val;
+}
+
+gint64
+get_multiplier(
+    gint64 val,
+    confunit_t unit)
+{
+    /* get multiplier, if any */
+    get_conftoken(CONF_ANY);
+
+    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;
 }
 
@@ -4056,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)
@@ -4064,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;
 }
@@ -4085,11 +4698,38 @@ validate_nonnegative(
            conf_parserror(_("%s must be nonnegative"), get_token_name(np->token));
        break;
     case CONFTYPE_SIZE:
-       if(val_t__size(val) < 0)
-           conf_parserror(_("%s must be positive"), get_token_name(np->token));
+       if(val_t__size(val) < 0)
+           conf_parserror(_("%s must be positive"), get_token_name(np->token));
+       break;
+    default:
+       conf_parserror(_("validate_nonnegative invalid type %d\n"), val->type);
+    }
+}
+
+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_nonnegative invalid type %d\n"), val->type);
+       conf_parserror(_("validate_non_zero invalid type %d\n"), val->type);
     }
 }
 
@@ -4279,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
  */
@@ -4333,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);
@@ -4407,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;
@@ -4418,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) {
@@ -4489,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; i<INTERACTIVITY_INTERACTIVITY; i++) {
+          free_val_t(&iv->value[i]);
+       }
+       ivnext = iv->next;
+       amfree(iv);
+    }
+    interactivity_list = NULL;
+
+    for(ts=taperscan_list; ts != NULL; ts = tsnext) {
+       amfree(ts->name);
+       for(i=0; i<TAPERSCAN_TAPERSCAN; i++) {
+          free_val_t(&ts->value[i]);
+       }
+       tsnext = ts->next;
+       amfree(ts);
+    }
+    taperscan_list = NULL;
+
     for(i=0; i<CNF_CNF; i++)
        free_val_t(&conf_data[i]);
 
@@ -4504,7 +5189,7 @@ config_uninit(void)
     amfree(config_dir);
     amfree(config_filename);
 
-    g_slist_free_full(seen_filenames);
+    slist_free_full(seen_filenames, g_free);
     seen_filenames = NULL;
 
     config_client = FALSE;
@@ -4522,9 +5207,10 @@ init_defaults(
     /* defaults for exported variables */
     conf_init_str(&conf_data[CNF_ORG], DEFAULT_CONFIG);
     conf_init_str(&conf_data[CNF_CONF], DEFAULT_CONFIG);
+    conf_init_str(&conf_data[CNF_AMDUMP_SERVER], DEFAULT_SERVER);
     conf_init_str(&conf_data[CNF_INDEX_SERVER], DEFAULT_SERVER);
     conf_init_str(&conf_data[CNF_TAPE_SERVER], DEFAULT_TAPE_SERVER);
-    conf_init_str(&conf_data[CNF_AUTH], "bsd");
+    conf_init_str(&conf_data[CNF_AUTH], "bsdtcp");
     conf_init_str(&conf_data[CNF_SSH_KEYS], "");
     conf_init_str(&conf_data[CNF_AMANDAD_PATH], "");
     conf_init_str(&conf_data[CNF_CLIENT_USERNAME], "");
@@ -4546,63 +5232,66 @@ init_defaults(
     conf_init_str   (&conf_data[CNF_INDEXDIR]             , "/usr/adm/amanda/index");
     conf_init_ident    (&conf_data[CNF_TAPETYPE]             , "DEFAULT_TAPE");
     conf_init_identlist(&conf_data[CNF_HOLDINGDISK]          , NULL);
-    conf_init_int      (&conf_data[CNF_DUMPCYCLE]            , 10);
-    conf_init_int      (&conf_data[CNF_RUNSPERCYCLE]         , 0);
-    conf_init_int      (&conf_data[CNF_TAPECYCLE]            , 15);
-    conf_init_int      (&conf_data[CNF_NETUSAGE]             , 8000);
-    conf_init_int      (&conf_data[CNF_INPARALLEL]           , 10);
+    conf_init_int      (&conf_data[CNF_DUMPCYCLE]            , CONF_UNIT_NONE, 10);
+    conf_init_int      (&conf_data[CNF_RUNSPERCYCLE]         , CONF_UNIT_NONE, 0);
+    conf_init_int      (&conf_data[CNF_TAPECYCLE]            , CONF_UNIT_NONE, 15);
+    conf_init_int      (&conf_data[CNF_NETUSAGE]             , CONF_UNIT_K   , 80000);
+    conf_init_int      (&conf_data[CNF_INPARALLEL]           , CONF_UNIT_NONE, 10);
     conf_init_str   (&conf_data[CNF_DUMPORDER]            , "ttt");
-    conf_init_int      (&conf_data[CNF_BUMPPERCENT]          , 0);
-    conf_init_int64    (&conf_data[CNF_BUMPSIZE]             , (gint64)10*1024);
+    conf_init_int      (&conf_data[CNF_BUMPPERCENT]          , CONF_UNIT_NONE, 0);
+    conf_init_int64    (&conf_data[CNF_BUMPSIZE]             , CONF_UNIT_K   , (gint64)10*1024);
     conf_init_real     (&conf_data[CNF_BUMPMULT]             , 1.5);
-    conf_init_int      (&conf_data[CNF_BUMPDAYS]             , 2);
+    conf_init_int      (&conf_data[CNF_BUMPDAYS]             , CONF_UNIT_NONE, 2);
     conf_init_str   (&conf_data[CNF_TPCHANGER]            , "");
-    conf_init_int      (&conf_data[CNF_RUNTAPES]             , 1);
-    conf_init_int      (&conf_data[CNF_MAXDUMPS]             , 1);
-    conf_init_int      (&conf_data[CNF_ETIMEOUT]             , 300);
-    conf_init_int      (&conf_data[CNF_DTIMEOUT]             , 1800);
-    conf_init_int      (&conf_data[CNF_CTIMEOUT]             , 30);
-    conf_init_int      (&conf_data[CNF_TAPEBUFS]             , 20);
-    conf_init_size     (&conf_data[CNF_DEVICE_OUTPUT_BUFFER_SIZE], 40*32768);
+    conf_init_int      (&conf_data[CNF_RUNTAPES]             , CONF_UNIT_NONE, 1);
+    conf_init_int      (&conf_data[CNF_MAXDUMPS]             , CONF_UNIT_NONE, 1);
+    conf_init_int      (&conf_data[CNF_MAX_DLE_BY_VOLUME]    , CONF_UNIT_NONE, 1000000000);
+    conf_init_int      (&conf_data[CNF_ETIMEOUT]             , CONF_UNIT_NONE, 300);
+    conf_init_int      (&conf_data[CNF_DTIMEOUT]             , CONF_UNIT_NONE, 1800);
+    conf_init_int      (&conf_data[CNF_CTIMEOUT]             , CONF_UNIT_NONE, 30);
+    conf_init_size     (&conf_data[CNF_DEVICE_OUTPUT_BUFFER_SIZE], CONF_UNIT_NONE, 40*32768);
     conf_init_str   (&conf_data[CNF_PRINTER]              , "");
     conf_init_str   (&conf_data[CNF_MAILER]               , DEFAULT_MAILER);
-    conf_init_bool     (&conf_data[CNF_AUTOFLUSH]            , 0);
-    conf_init_int      (&conf_data[CNF_RESERVE]              , 100);
-    conf_init_int64    (&conf_data[CNF_MAXDUMPSIZE]          , (gint64)-1);
+    conf_init_no_yes_all(&conf_data[CNF_AUTOFLUSH]            , 0);
+    conf_init_int      (&conf_data[CNF_RESERVE]              , CONF_UNIT_NONE, 100);
+    conf_init_int64    (&conf_data[CNF_MAXDUMPSIZE]          , CONF_UNIT_K   , (gint64)-1);
     conf_init_str   (&conf_data[CNF_COLUMNSPEC]           , "");
     conf_init_bool     (&conf_data[CNF_AMRECOVER_DO_FSF]     , 1);
     conf_init_str   (&conf_data[CNF_AMRECOVER_CHANGER]    , "");
     conf_init_bool     (&conf_data[CNF_AMRECOVER_CHECK_LABEL], 1);
     conf_init_taperalgo(&conf_data[CNF_TAPERALGO]            , 0);
-    conf_init_int      (&conf_data[CNF_FLUSH_THRESHOLD_DUMPED]   , 0);
-    conf_init_int      (&conf_data[CNF_FLUSH_THRESHOLD_SCHEDULED], 0);
-    conf_init_int      (&conf_data[CNF_TAPERFLUSH]               , 0);
+    conf_init_int      (&conf_data[CNF_TAPER_PARALLEL_WRITE]     , CONF_UNIT_NONE, 1);
+    conf_init_int      (&conf_data[CNF_FLUSH_THRESHOLD_DUMPED]   , CONF_UNIT_NONE, 0);
+    conf_init_int      (&conf_data[CNF_FLUSH_THRESHOLD_SCHEDULED], CONF_UNIT_NONE, 0);
+    conf_init_int      (&conf_data[CNF_TAPERFLUSH]               , CONF_UNIT_NONE, 0);
     conf_init_str   (&conf_data[CNF_DISPLAYUNIT]          , "k");
     conf_init_str   (&conf_data[CNF_KRB5KEYTAB]           , "/.amanda-v5-keytab");
     conf_init_str   (&conf_data[CNF_KRB5PRINCIPAL]        , "service/amanda");
     conf_init_str   (&conf_data[CNF_LABEL_NEW_TAPES]      , "");
+    conf_init_bool     (&conf_data[CNF_EJECT_VOLUME]         , 0);
+    conf_init_str      (&conf_data[CNF_TMPDIR]               , "");
     conf_init_bool     (&conf_data[CNF_USETIMESTAMPS]        , 1);
-    conf_init_int      (&conf_data[CNF_CONNECT_TRIES]        , 3);
-    conf_init_int      (&conf_data[CNF_REP_TRIES]            , 5);
-    conf_init_int      (&conf_data[CNF_REQ_TRIES]            , 3);
-    conf_init_int      (&conf_data[CNF_DEBUG_DAYS]           , AMANDA_DEBUG_DAYS);
-    conf_init_int      (&conf_data[CNF_DEBUG_AMANDAD]        , 0);
-    conf_init_int      (&conf_data[CNF_DEBUG_RECOVERY]       , 0);
-    conf_init_int      (&conf_data[CNF_DEBUG_AMIDXTAPED]     , 0);
-    conf_init_int      (&conf_data[CNF_DEBUG_AMINDEXD]       , 0);
-    conf_init_int      (&conf_data[CNF_DEBUG_AMRECOVER]      , 0);
-    conf_init_int      (&conf_data[CNF_DEBUG_AUTH]           , 0);
-    conf_init_int      (&conf_data[CNF_DEBUG_EVENT]          , 0);
-    conf_init_int      (&conf_data[CNF_DEBUG_HOLDING]        , 0);
-    conf_init_int      (&conf_data[CNF_DEBUG_PROTOCOL]       , 0);
-    conf_init_int      (&conf_data[CNF_DEBUG_PLANNER]        , 0);
-    conf_init_int      (&conf_data[CNF_DEBUG_DRIVER]         , 0);
-    conf_init_int      (&conf_data[CNF_DEBUG_DUMPER]         , 0);
-    conf_init_int      (&conf_data[CNF_DEBUG_CHUNKER]        , 0);
-    conf_init_int      (&conf_data[CNF_DEBUG_TAPER]          , 0);
-    conf_init_int      (&conf_data[CNF_DEBUG_SELFCHECK]      , 0);
-    conf_init_int      (&conf_data[CNF_DEBUG_SENDSIZE]       , 0);
-    conf_init_int      (&conf_data[CNF_DEBUG_SENDBACKUP]     , 0);
+    conf_init_int      (&conf_data[CNF_CONNECT_TRIES]        , CONF_UNIT_NONE, 3);
+    conf_init_int      (&conf_data[CNF_REP_TRIES]            , CONF_UNIT_NONE, 5);
+    conf_init_int      (&conf_data[CNF_REQ_TRIES]            , CONF_UNIT_NONE, 3);
+    conf_init_int      (&conf_data[CNF_DEBUG_DAYS]           , CONF_UNIT_NONE, AMANDA_DEBUG_DAYS);
+    conf_init_int      (&conf_data[CNF_DEBUG_AMANDAD]        , CONF_UNIT_NONE, 0);
+    conf_init_int      (&conf_data[CNF_DEBUG_RECOVERY]       , CONF_UNIT_NONE, 1);
+    conf_init_int      (&conf_data[CNF_DEBUG_AMIDXTAPED]     , CONF_UNIT_NONE, 0);
+    conf_init_int      (&conf_data[CNF_DEBUG_AMINDEXD]       , CONF_UNIT_NONE, 0);
+    conf_init_int      (&conf_data[CNF_DEBUG_AMRECOVER]      , CONF_UNIT_NONE, 0);
+    conf_init_int      (&conf_data[CNF_DEBUG_AUTH]           , CONF_UNIT_NONE, 0);
+    conf_init_int      (&conf_data[CNF_DEBUG_EVENT]          , CONF_UNIT_NONE, 0);
+    conf_init_int      (&conf_data[CNF_DEBUG_HOLDING]        , CONF_UNIT_NONE, 0);
+    conf_init_int      (&conf_data[CNF_DEBUG_PROTOCOL]       , CONF_UNIT_NONE, 0);
+    conf_init_int      (&conf_data[CNF_DEBUG_PLANNER]        , CONF_UNIT_NONE, 0);
+    conf_init_int      (&conf_data[CNF_DEBUG_DRIVER]         , CONF_UNIT_NONE, 0);
+    conf_init_int      (&conf_data[CNF_DEBUG_DUMPER]         , CONF_UNIT_NONE, 0);
+    conf_init_int      (&conf_data[CNF_DEBUG_CHUNKER]        , CONF_UNIT_NONE, 0);
+    conf_init_int      (&conf_data[CNF_DEBUG_TAPER]          , CONF_UNIT_NONE, 0);
+    conf_init_int      (&conf_data[CNF_DEBUG_SELFCHECK]      , CONF_UNIT_NONE, 0);
+    conf_init_int      (&conf_data[CNF_DEBUG_SENDSIZE]       , CONF_UNIT_NONE, 0);
+    conf_init_int      (&conf_data[CNF_DEBUG_SENDBACKUP]     , CONF_UNIT_NONE, 0);
 #ifdef UDPPORTRANGE
     conf_init_intrange (&conf_data[CNF_RESERVED_UDP_PORT]    , UDPPORTRANGE);
 #else
@@ -4620,6 +5309,10 @@ init_defaults(
 #endif
     conf_init_send_amreport (&conf_data[CNF_SEND_AMREPORT_ON], SEND_AMREPORT_ALL);
     conf_init_autolabel(&conf_data[CNF_AUTOLABEL]);
+    conf_init_str(&conf_data[CNF_META_AUTOLABEL], NULL);
+    conf_init_host_limit(&conf_data[CNF_RECOVERY_LIMIT]);
+    conf_init_str(&conf_data[CNF_INTERACTIVITY], NULL);
+    conf_init_str(&conf_data[CNF_TAPERSCAN], NULL);
 
     /* reset internal variables */
     config_clear_errors();
@@ -4676,6 +5369,14 @@ init_defaults(
     val_t__seen(&dpcur.value[DUMPTYPE_AUTH]).linenum = -1;
     save_dumptype();
 
+    init_dumptype_defaults();
+    dpcur.name = stralloc("BSDTCP-AUTH");
+    dpcur.seen.linenum = -1;
+    free_val_t(&dpcur.value[DUMPTYPE_AUTH]);
+    val_t__str(&dpcur.value[DUMPTYPE_AUTH]) = stralloc("BSDTCP");
+    val_t__seen(&dpcur.value[DUMPTYPE_AUTH]).linenum = -1;
+    save_dumptype();
+
     init_dumptype_defaults();
     dpcur.name = stralloc("NO-RECORD");
     dpcur.seen.linenum = -1;
@@ -4796,7 +5497,7 @@ update_derived_values(
             getconf_seen(CNF_AUTOLABEL) > 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) ||
@@ -4863,22 +5564,28 @@ update_derived_values(
 static void
 conf_init_int(
     val_t *val,
+    confunit_t unit,
     int    i)
 {
     val->seen.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;
 }
 
@@ -4889,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;
 }
 
@@ -4900,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
@@ -4914,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
@@ -4928,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));
@@ -4941,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;
 }
 
@@ -4963,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,
@@ -4974,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;
 }
 
@@ -4985,10 +5722,47 @@ 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;
 }
 
+static void
+conf_init_part_cache_type(
+    val_t *val,
+    part_cache_type_t    i)
+{
+    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_host_limit(
+    val_t *val)
+{
+    val->seen.linenum = 0;
+    val->seen.filename = NULL;
+    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
 conf_init_data_path(
     val_t *val,
@@ -4996,8 +5770,10 @@ conf_init_data_path(
 {
     val->seen.linenum = 0;
     val->seen.filename = NULL;
+    val->seen.block = NULL;
     val->type = CONFTYPE_DATA_PATH;
-    val_t__encrypt(val) = (int)i;
+    val->unit = CONF_UNIT_NONE;
+    val_t__data_path(val) = (int)i;
 }
 
 static void
@@ -5007,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;
 }
 
@@ -5019,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;
 }
@@ -5031,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;
 }
@@ -5042,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;
 }
 
@@ -5053,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;
 }
 
@@ -5065,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;
 }
@@ -5076,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;
@@ -5090,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;
 }
@@ -5100,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;
 }
@@ -5110,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);
 }
 
@@ -5120,9 +5914,12 @@ 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_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
@@ -5132,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;
 }
 
@@ -5143,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;
 }
 
@@ -5154,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;
 }
 
@@ -5190,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) {
@@ -5229,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;
 }
@@ -5279,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)
@@ -5416,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)
@@ -5801,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)
@@ -5825,6 +6722,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)
@@ -5977,9 +6898,15 @@ 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_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 +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:
@@ -6028,6 +6956,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 +6990,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 +7027,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);
 
@@ -6132,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;
@@ -6159,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) {
@@ -6175,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:
@@ -6190,6 +7131,7 @@ free_val_t(
        case CONFTYPE_REAL:
        case CONFTYPE_RATE:
        case CONFTYPE_INTRANGE:
+       case CONFTYPE_PART_CACHE_TYPE:
            break;
 
        case CONFTYPE_IDENT:
@@ -6199,7 +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_HOST_LIMIT:
+           slist_free_full(val->v.host_limit.match_pats, g_free);
            break;
 
        case CONFTYPE_TIME:
@@ -6224,6 +7170,7 @@ free_val_t(
     }
     val->seen.linenum = 0;
     val->seen.filename = NULL;
+    val->seen.block = NULL;
 }
 
 /*
@@ -6259,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) {
@@ -6288,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;
@@ -6299,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;
@@ -6318,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) {
@@ -6339,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");
     }
@@ -6361,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);
     }
@@ -6384,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);
        }
@@ -6410,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);
     }
@@ -6432,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);
     }
@@ -6454,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);
     }
@@ -6473,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);
     }
@@ -6492,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,
@@ -6507,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
@@ -6520,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 {
@@ -6534,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;
@@ -6547,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:
@@ -6648,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:
@@ -6784,6 +7868,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:
@@ -6822,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;
     }
 
@@ -6848,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 = ", ";
@@ -6864,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 = ", ";
@@ -6880,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 = ", ";
@@ -6888,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 = ", ";
@@ -6920,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;
 }
 
@@ -6966,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) {
@@ -6981,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)++;
 }
 
@@ -6989,7 +8148,7 @@ exinclude_display_str(
     val_t *val,
     int    file)
 {
-    sl_t  *sl;
+    am_sl_t  *sl;
     sle_t *excl;
     char *rval;
 
@@ -7069,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. */
@@ -7096,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';
@@ -7217,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 */
@@ -7392,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;
@@ -7426,15 +8611,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 +8638,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 +8650,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 +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;
+}