Imported Upstream version 3.2.0
[debian/amanda] / common-src / conffile.h
index 787f51495caf98aa88276a91a7cea45a4a04f79a..cedc4a7fcd8bb8cbe0ee3058fc21db317c68a466 100644 (file)
@@ -21,8 +21,8 @@
  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
  * Author: James da Silva, Systems Design and Analysis Group
- *                        Computer Science Department
- *                        University of Maryland at College Park
+ *                         Computer Science Department
+ *                         University of Maryland at College Park
  */
 /*
  * $Id: conffile.h,v 1.72 2006/07/26 15:17:37 martinea Exp $
 #define CONFFILE_H
 
 #include "amanda.h"
-#include "conffile.h"
 #include "util.h"
 
-#define CONFFILE_NAME "amanda.conf"
+/* Getting Configuration Values
+ * ============================
+ *
+ * Amanda configurations consist of a number of "global" parameters, as well as
+ * named subsections of several types.  The global parameters are fetched with
+ * the getconf_CONFTYPE functions, keyed by a confparam_t constant (with prefix
+ * CNF_).  The subsection parameters are fetched with SUBSEC_get_PARAM()
+ * macros, e.g., tapetype_get_blocksize(ttyp), where the argument comes from
+ * lookup_SUBSEC(), in this case lookup_tapetype(name).
+ *
+ * Types
+ * =====
+ *
+ * This module juggles two kinds of types: C types and conftypes.  Conftypes include
+ * everything from integers through property lists, and are specific to the needs of
+ * the configuration system.  Each conftype has a corresponding C type, which is of course
+ * necessary to actually use the data.
+ *
+ * The val_t__CONFTYPE macros represent the canonical correspondance of conftypes to C
+ * types, but in general the relationship is obvious: ints, strings, reals, and so forth
+ * are represented directly.  Enumerated conftypes are represented by the corresponding
+ * C enum type.  The 'rate' conftype is represented as a 2-element array of doubles, and
+ * the 'intrange' conftype is represented as a 2-element array of ints.  exincludes are
+ * a exinclude_t *, and a proplist is represented as a GHashTable *.
+ *
+ * Memory
+ * ======
+ * Note that, unless specified, all memory in this module is managed by the module
+ * itself; return strings should not be freed by the caller.
+ *
+ * Error Handling
+ * ==============
+ * All errors and warnings generated by this module are available from get_config_errors().
+ * It is up to the caller to route these messages to the user.  The function
+ * config_print_errors() will print the errors to stderr, as a convenience.
+ */
+
+/*
+ * Generic values
+ *
+ * This module uses a generic val_t type to hold values of various types -- it's basically
+ * a union with type information and a 'seen' flag.  In a way, it's a very simple equivalent
+ * to Glib's GValue.  It's worth considering rewriting this with GValue, but for the moment,
+ * this works and it's here.
+ */
+
+/* holdingdisk types */
+typedef enum {
+    HOLD_NEVER,                 /* Always direct to tape  */
+    HOLD_AUTO,                  /* If possible            */
+    HOLD_REQUIRED               /* Always to holding disk */
+} dump_holdingdisk_t;
+
+/* Compression types */
+typedef enum {
+    COMP_NONE,          /* No compression */
+    COMP_FAST,          /* Fast compression on client */
+    COMP_BEST,          /* Best compression on client */
+    COMP_CUST,          /* Custom compression on client */
+    COMP_SERVER_FAST,   /* Fast compression on server */
+    COMP_SERVER_BEST,   /* Best compression on server */
+    COMP_SERVER_CUST    /* Custom compression on server */
+} comp_t;
 
+/* Encryption types */
+typedef enum {
+    ENCRYPT_NONE,               /* No encryption */
+    ENCRYPT_CUST,               /* Custom encryption on client */
+    ENCRYPT_SERV_CUST           /* Custom encryption on server */
+} encrypt_t;
+
+/* Estimate strategies */
+typedef enum {
+    ES_CLIENT,          /* client estimate */
+    ES_SERVER,          /* server estimate */
+    ES_CALCSIZE,        /* calcsize estimate */
+    ES_ES               /* sentinel */
+} estimate_t;
+/* A GSlist where each element is a element_t */
+typedef GSList *estimatelist_t;
+
+typedef enum {
+    AL_OTHER_CONFIG = 1<<0,
+    AL_NON_AMANDA   = 1<<1,
+    AL_VOLUME_ERROR = 1<<2,
+    AL_EMPTY        = 1<<3,
+} autolabel_enum_t;
+typedef int autolabel_set_t;
+
+typedef struct autolabel_s {
+    char            *template;
+    autolabel_set_t  autolabel;
+} autolabel_t;
+
+/* Dump strategies */
+typedef enum {
+    DS_SKIP,        /* Don't do any dumps at all */
+    DS_STANDARD,    /* Standard (0 1 1 1 1 2 2 2 ...) */
+    DS_NOFULL,      /* No full's (1 1 1 ...) */
+    DS_NOINC,       /* No inc's (0 0 0 ...) */
+    DS_4,           /* ? (0 1 2 3 4 5 6 7 8 9 10 11 ...) */
+    DS_5,           /* ? (0 1 1 1 1 1 1 1 1 1 1 1 ...) */
+    DS_HANOI,       /* Tower of Hanoi (? ? ? ? ? ...) */
+    DS_INCRONLY,    /* Forced fulls (0 1 1 2 2 FORCE0 1 1 ...) */
+    DS_DS /* sentinel */
+} strategy_t;
+
+typedef enum {
+    ALGO_FIRST,
+    ALGO_FIRSTFIT,
+    ALGO_LARGEST,
+    ALGO_LARGESTFIT,
+    ALGO_SMALLEST,
+    ALGO_SMALLESTFIT,  /* for internal use */
+    ALGO_LAST,
+    ALGO_LASTFIT,      /* for internal use */
+    ALGO_ALGO /* sentinel */
+} taperalgo_t;
+
+/* execute_on types */
+#define EXECUTE_ON_PRE_DLE_AMCHECK     1<<0
+#define EXECUTE_ON_PRE_HOST_AMCHECK    1<<1
+#define EXECUTE_ON_POST_DLE_AMCHECK    1<<2
+#define EXECUTE_ON_POST_HOST_AMCHECK   1<<3
+#define EXECUTE_ON_PRE_DLE_ESTIMATE    1<<4
+#define EXECUTE_ON_PRE_HOST_ESTIMATE   1<<5
+#define EXECUTE_ON_POST_DLE_ESTIMATE   1<<6
+#define EXECUTE_ON_POST_HOST_ESTIMATE  1<<7
+#define EXECUTE_ON_PRE_DLE_BACKUP      1<<8
+#define EXECUTE_ON_PRE_HOST_BACKUP     1<<9
+#define EXECUTE_ON_POST_DLE_BACKUP     1<<10
+#define EXECUTE_ON_POST_HOST_BACKUP    1<<11
+#define EXECUTE_ON_PRE_RECOVER         1<<12
+#define EXECUTE_ON_POST_RECOVER        1<<13
+#define EXECUTE_ON_PRE_LEVEL_RECOVER   1<<14
+#define EXECUTE_ON_POST_LEVEL_RECOVER  1<<15
+#define EXECUTE_ON_INTER_LEVEL_RECOVER 1<<16
+typedef int execute_on_t;
+
+typedef int execute_where_t;
+
+typedef enum {
+    SEND_AMREPORT_ALL,
+    SEND_AMREPORT_STRANGE,
+    SEND_AMREPORT_ERROR,
+    SEND_AMREPORT_NEVER
+} send_amreport_t;
+
+typedef enum {
+    DATA_PATH_AMANDA    = 1<<0,
+    DATA_PATH_DIRECTTCP = 1<<1,
+} data_path_t;
+
+typedef struct exinclude_s {
+    sl_t *sl_list;
+    sl_t *sl_file;
+    int  optional;
+} exinclude_t;
+
+typedef struct {
+    int append;
+    int priority;
+    GSList* values;
+} property_t;
+
+typedef GHashTable* proplist_t;
+/* A GSlist where each element is a 'char*' */
+typedef GSList* identlist_t;
+
+/* part_cache_types */
+typedef enum {
+    PART_CACHE_TYPE_NONE,
+    PART_CACHE_TYPE_MEMORY,
+    PART_CACHE_TYPE_DISK,
+} part_cache_type_t;
+
+/* recovery_limit */
+typedef struct {
+    gboolean same_host;
+    GSList *match_pats;
+} recovery_limit_t;
+
+/* Names for the type of value in a val_t.  Mostly for internal use, but useful
+ * for wrapping val_t's, too. */
+typedef enum {
+    CONFTYPE_INT,
+    CONFTYPE_INT64,
+    CONFTYPE_REAL,
+    CONFTYPE_STR,
+    CONFTYPE_IDENT,
+    CONFTYPE_TIME,
+    CONFTYPE_SIZE,
+    CONFTYPE_BOOLEAN,
+    CONFTYPE_COMPRESS,
+    CONFTYPE_ENCRYPT,
+    CONFTYPE_HOLDING,
+    CONFTYPE_ESTIMATELIST,
+    CONFTYPE_STRATEGY,
+    CONFTYPE_TAPERALGO,
+    CONFTYPE_PRIORITY,
+    CONFTYPE_RATE,
+    CONFTYPE_INTRANGE,
+    CONFTYPE_EXINCLUDE,
+    CONFTYPE_PROPLIST,
+    CONFTYPE_APPLICATION,
+    CONFTYPE_EXECUTE_ON,
+    CONFTYPE_EXECUTE_WHERE,
+    CONFTYPE_SEND_AMREPORT_ON,
+    CONFTYPE_IDENTLIST,
+    CONFTYPE_DATA_PATH,
+    CONFTYPE_AUTOLABEL,
+    CONFTYPE_PART_CACHE_TYPE,
+    CONFTYPE_RECOVERY_LIMIT,
+} conftype_t;
+
+/* A "seen" struct.  Rather than allocate strings all over the place, this
+ * string is in the "parsed_filenames" GSList and will be freed when that
+ * GSList is freed.  This struct should be opaque to other modules. */
+typedef struct seen_s {
+    char *filename;
+    int linenum;
+} seen_t;
+
+/* This should be considered an opaque type for any other modules.  The complete
+ * struct is included here to allow quick access via macros. Access it *only* through
+ * those macros. */
+typedef struct val_s {
+    union {
+        int            i;
+        gint64         int64;
+        double         r;
+        char           *s;
+        ssize_t                size;
+        time_t         t;
+        float          rate[2];
+        exinclude_t    exinclude;
+        int            intrange[2];
+        proplist_t      proplist;
+       estimatelist_t  estimatelist;
+       identlist_t     identlist;
+        autolabel_t     autolabel;
+       recovery_limit_t recovery_limit;
+    } v;
+    seen_t seen;
+    conftype_t type;
+} val_t;
+
+/* Functions to typecheck and extract a particular type of
+ * value from a val_t.  All call error() if the type is incorrect,
+ * as this is a programming error.  */
+int                   val_t_to_int      (val_t *);
+gint64                val_t_to_int64    (val_t *);
+float                 val_t_to_real     (val_t *);
+char                 *val_t_to_str      (val_t *); /* (also converts CONFTYPE_IDENT) */
+char                 *val_t_to_ident    (val_t *); /* (also converts CONFTYPE_STR) */
+identlist_t           val_t_to_identlist(val_t *);
+time_t                val_t_to_time     (val_t *);
+ssize_t               val_t_to_size     (val_t *);
+int                   val_t_to_boolean  (val_t *);
+comp_t                val_t_to_compress (val_t *);
+encrypt_t             val_t_to_encrypt  (val_t *);
+dump_holdingdisk_t    val_t_to_holding  (val_t *);
+estimatelist_t        val_t_to_estimatelist (val_t *);
+strategy_t            val_t_to_strategy (val_t *);
+taperalgo_t           val_t_to_taperalgo(val_t *);
+int                   val_t_to_priority (val_t *);
+float                *val_t_to_rate     (val_t *); /* array of two floats */
+exinclude_t           val_t_to_exinclude(val_t *);
+int                  *val_t_to_intrange (val_t *); /* array of two ints */
+proplist_t            val_t_to_proplist (val_t *);
+char                 *val_t_to_application(val_t *);
+execute_on_t          val_t_to_execute_on(val_t *);
+execute_where_t       val_t_to_execute_where(val_t *);
+send_amreport_t       val_t_to_send_amreport(val_t *);
+data_path_t           val_t_to_data_path(val_t *);
+autolabel_t           val_t_to_autolabel(val_t *);
+part_cache_type_t     val_t_to_part_cache_type(val_t *);
+recovery_limit_t     *val_t_to_recovery_limit(val_t *);
+
+/* Has the given val_t been seen in a configuration file or config overwrite?
+ *
+ * @param val: val_t* to examine
+ * @returns: boolean
+ */
+#define val_t_seen(val) ((val)->seen.linenum)
+
+/* What is the underlying type of this val_t?
+ *
+ * @param val: val_t* to examine
+ * @returns: conftype_t
+ */
+#define val_t_type(val) ((val)->type)
+
+/* Macros to convert val_t's to a particular type without the benefit of
+ * a typecheck.  Use these only if you really know what you're doing!
+ *
+ * Implementation note: these macros encode the relationship of conftypes
+ * (in the macro name) to the corresponding union field.  The macros work
+ * as lvalues, too.
+ */
+#define val_t__seen(val)          ((val)->seen)
+#define val_t__int(val)           ((val)->v.i)
+#define val_t__int64(val)         ((val)->v.int64)
+#define val_t__real(val)          ((val)->v.r)
+#define val_t__str(val)           ((val)->v.s)
+#define val_t__ident(val)         ((val)->v.s)
+#define val_t__identlist(val)     ((val)->v.identlist)
+#define val_t__time(val)          ((val)->v.t)
+#define val_t__size(val)          ((val)->v.size)
+#define val_t__boolean(val)       ((val)->v.i)
+#define val_t__compress(val)      ((val)->v.i)
+#define val_t__encrypt(val)       ((val)->v.i)
+#define val_t__holding(val)       ((val)->v.i)
+#define val_t__estimatelist(val)  ((val)->v.estimatelist)
+#define val_t__strategy(val)      ((val)->v.i)
+#define val_t__taperalgo(val)     ((val)->v.i)
+#define val_t__send_amreport(val) ((val)->v.i)
+#define val_t__priority(val)      ((val)->v.i)
+#define val_t__rate(val)          ((val)->v.rate)
+#define val_t__exinclude(val)     ((val)->v.exinclude)
+#define val_t__intrange(val)      ((val)->v.intrange)
+#define val_t__proplist(val)      ((val)->v.proplist)
+#define val_t__application(val)   ((val)->v.application)
+#define val_t__execute_on(val)    ((val)->v.i)
+#define val_t__execute_where(val) ((val)->v.i)
+#define val_t__data_path(val)     ((val)->v.i)
+#define val_t__autolabel(val)     ((val)->v.autolabel)
+#define val_t__part_cache_type(val) ((val)->v.i)
+#define val_t__recovery_limit(val) ((val)->v.recovery_limit)
+
+/*
+ * Parameters
+ *
+ * Programs get val_t's by giving the index of the parameters they're interested in.
+ * For global parameters, these start with CNF; for subsections, they start with the
+ * name of the subsection.
+ */
+
+/*
+ * Global parameter access
+ */
 typedef enum {
     CNF_ORG,
     CNF_CONF,
@@ -47,13 +385,22 @@ typedef enum {
     CNF_SSH_KEYS,
     CNF_AMANDAD_PATH,
     CNF_CLIENT_USERNAME,
+    CNF_CLIENT_PORT,
     CNF_GNUTAR_LIST_DIR,
     CNF_AMANDATES,
     CNF_MAILTO,
     CNF_DUMPUSER,
     CNF_TAPEDEV,
-    CNF_CHNGRDEV,
-    CNF_CHNGRFILE,
+    CNF_DEVICE_PROPERTY,
+    CNF_PROPERTY,
+    CNF_APPLICATION,
+    CNF_APPLICATION_TOOL,
+    CNF_EXECUTE_ON,
+    CNF_PP_SCRIPT,
+    CNF_PP_SCRIPT_TOOL,
+    CNF_PLUGIN,
+    CNF_CHANGERDEV,
+    CNF_CHANGERFILE,
     CNF_LABELSTR,
     CNF_TAPELIST,
     CNF_DISKFILE,
@@ -77,9 +424,9 @@ typedef enum {
     CNF_ETIMEOUT,
     CNF_DTIMEOUT,
     CNF_CTIMEOUT,
-    CNF_TAPEBUFS,
-    CNF_RAWTAPEDEV,
+    CNF_DEVICE_OUTPUT_BUFFER_SIZE,
     CNF_PRINTER,
+    CNF_MAILER,
     CNF_AUTOFLUSH,
     CNF_RESERVE,
     CNF_MAXDUMPSIZE,
@@ -88,6 +435,10 @@ typedef enum {
     CNF_AMRECOVER_CHECK_LABEL,
     CNF_AMRECOVER_CHANGER,
     CNF_TAPERALGO,
+    CNF_SEND_AMREPORT_ON,
+    CNF_FLUSH_THRESHOLD_DUMPED,
+    CNF_FLUSH_THRESHOLD_SCHEDULED,
+    CNF_TAPERFLUSH,
     CNF_DISPLAYUNIT,
     CNF_KRB5KEYTAB,
     CNF_KRB5PRINCIPAL,
@@ -97,6 +448,7 @@ typedef enum {
     CNF_CONNECT_TRIES,
     CNF_REQ_TRIES,
     CNF_DEBUG_AMANDAD,
+    CNF_DEBUG_RECOVERY,
     CNF_DEBUG_AMIDXTAPED,
     CNF_DEBUG_AMINDEXD,
     CNF_DEBUG_AMRECOVER,
@@ -115,211 +467,118 @@ typedef enum {
     CNF_RESERVED_UDP_PORT,
     CNF_RESERVED_TCP_PORT,
     CNF_UNRESERVED_TCP_PORT,
-    CNF_CNF
-} confparm_t;
-
-typedef enum {
-    CONF_UNKNOWN,              CONF_ANY,               CONF_COMMA,
-    CONF_LBRACE,               CONF_RBRACE,            CONF_NL,
-    CONF_END,                  CONF_IDENT,             CONF_INT,
-    CONF_LONG,                 CONF_AM64,              CONF_BOOL,
-    CONF_REAL,                 CONF_STRING,            CONF_TIME,
-    CONF_SIZE,
-
-    /* config parameters */
-    CONF_INCLUDEFILE,          CONF_ORG,               CONF_MAILTO,
-    CONF_DUMPUSER,             CONF_TAPECYCLE,         CONF_TAPEDEV,
-    CONF_CHNGRDEV,             CONF_CHNGRFILE,         CONF_LABELSTR,
-    CONF_BUMPPERCENT,          CONF_BUMPSIZE,          CONF_BUMPDAYS,
-    CONF_BUMPMULT,             CONF_ETIMEOUT,          CONF_DTIMEOUT,
-    CONF_CTIMEOUT,             CONF_TAPEBUFS,          CONF_TAPELIST,
-    CONF_DISKFILE,             CONF_INFOFILE,          CONF_LOGDIR,
-    CONF_LOGFILE,              CONF_DISKDIR,           CONF_DISKSIZE,
-    CONF_INDEXDIR,             CONF_NETUSAGE,          CONF_INPARALLEL,
-    CONF_DUMPORDER,            CONF_TIMEOUT,           CONF_TPCHANGER,
-    CONF_RUNTAPES,             CONF_DEFINE,            CONF_DUMPTYPE,
-    CONF_TAPETYPE,             CONF_INTERFACE,         CONF_PRINTER,
-    CONF_AUTOFLUSH,            CONF_RESERVE,           CONF_MAXDUMPSIZE,
-    CONF_COLUMNSPEC,           CONF_AMRECOVER_DO_FSF,  CONF_AMRECOVER_CHECK_LABEL,
-    CONF_AMRECOVER_CHANGER,    CONF_LABEL_NEW_TAPES,   CONF_USETIMESTAMPS,
-
-    CONF_TAPERALGO,            CONF_FIRST,             CONF_FIRSTFIT,
-    CONF_LARGEST,              CONF_LARGESTFIT,        CONF_SMALLEST,
-    CONF_LAST,                 CONF_DISPLAYUNIT,       CONF_RESERVED_UDP_PORT,
-    CONF_RESERVED_TCP_PORT,    CONF_UNRESERVED_TCP_PORT,
-
-    /* kerberos 5 */
-    CONF_KRB5KEYTAB,           CONF_KRB5PRINCIPAL,
-
-    /* holding disk */
-    CONF_COMMENT,              CONF_DIRECTORY,         CONF_USE,
-    CONF_CHUNKSIZE,
-
-    /* dump type */
-    /*COMMENT,*/               CONF_PROGRAM,           CONF_DUMPCYCLE,
-    CONF_RUNSPERCYCLE,         CONF_MAXCYCLE,          CONF_MAXDUMPS,
-    CONF_OPTIONS,              CONF_PRIORITY,          CONF_FREQUENCY,
-    CONF_INDEX,                        CONF_MAXPROMOTEDAY,     CONF_STARTTIME,
-    CONF_COMPRESS,             CONF_ENCRYPT,           CONF_AUTH,
-    CONF_STRATEGY,             CONF_ESTIMATE,          CONF_SKIP_INCR,
-    CONF_SKIP_FULL,            CONF_RECORD,            CONF_HOLDING,
-    CONF_EXCLUDE,              CONF_INCLUDE,           CONF_KENCRYPT,
-    CONF_IGNORE,               CONF_COMPRATE,          CONF_TAPE_SPLITSIZE,
-    CONF_SPLIT_DISKBUFFER,     CONF_FALLBACK_SPLITSIZE,CONF_SRVCOMPPROG,
-    CONF_CLNTCOMPPROG,         CONF_SRV_ENCRYPT,       CONF_CLNT_ENCRYPT,
-    CONF_SRV_DECRYPT_OPT,      CONF_CLNT_DECRYPT_OPT,  CONF_AMANDAD_PATH,
-    CONF_CLIENT_USERNAME,
-
-    /* tape type */
-    /*COMMENT,*/               CONF_BLOCKSIZE,         CONF_FILE_PAD,
-    CONF_LBL_TEMPL,            CONF_FILEMARK,          CONF_LENGTH,
-    CONF_SPEED,                        CONF_READBLOCKSIZE,
-
-    /* client conf */
-    CONF_CONF,                 CONF_INDEX_SERVER,      CONF_TAPE_SERVER,
-    CONF_SSH_KEYS,             CONF_GNUTAR_LIST_DIR,   CONF_AMANDATES,
-
-    /* protocol config */
-    CONF_REP_TRIES,            CONF_CONNECT_TRIES,     CONF_REQ_TRIES,
-
-    /* debug config */
-    CONF_DEBUG_AMANDAD,                CONF_DEBUG_AMIDXTAPED,  CONF_DEBUG_AMINDEXD,
-    CONF_DEBUG_AMRECOVER,      CONF_DEBUG_AUTH,        CONF_DEBUG_EVENT,
-    CONF_DEBUG_HOLDING,                CONF_DEBUG_PROTOCOL,    CONF_DEBUG_PLANNER,
-    CONF_DEBUG_DRIVER,         CONF_DEBUG_DUMPER,      CONF_DEBUG_CHUNKER,
-    CONF_DEBUG_TAPER,          CONF_DEBUG_SELFCHECK,   CONF_DEBUG_SENDSIZE,
-    CONF_DEBUG_SENDBACKUP,
-
-    /* network interface */
-    /* COMMENT, */             /* USE, */
-
-    /* dump options (obsolete) */
-    CONF_EXCLUDE_FILE,         CONF_EXCLUDE_LIST,
-
-    /* compress, estimate, encryption */
-    CONF_NONE,                 CONF_FAST,              CONF_BEST,
-    CONF_SERVER,               CONF_CLIENT,            CONF_CALCSIZE,
-    CONF_CUSTOM,
-
-    /* holdingdisk */
-    CONF_NEVER,                        CONF_AUTO,              CONF_REQUIRED,
-
-    /* priority */
-    CONF_LOW,                  CONF_MEDIUM,            CONF_HIGH,
-
-    /* dump strategy */
-    CONF_SKIP,                 CONF_STANDARD,          CONF_NOFULL,
-    CONF_NOINC,                        CONF_HANOI,             CONF_INCRONLY,
-
-    /* exclude list */
-    CONF_LIST,                 CONF_EFILE,             CONF_APPEND,
-    CONF_OPTIONAL,
-
-    /* numbers */
-    CONF_AMINFINITY,           CONF_MULT1,             CONF_MULT7,
-    CONF_MULT1K,               CONF_MULT1M,            CONF_MULT1G,
-
-    /* boolean */
-    CONF_ATRUE,                        CONF_AFALSE,
-
-    CONF_RAWTAPEDEV
-} tok_t;
-
-/* internal types and variables */
-
-/* */
-typedef enum {
-    CONFTYPE_INT,
-    CONFTYPE_LONG,
-    CONFTYPE_AM64,
-    CONFTYPE_REAL,
-    CONFTYPE_STRING,
-    CONFTYPE_IDENT,
-    CONFTYPE_TIME,             /* hhmm */
-    CONFTYPE_SIZE,
-    CONFTYPE_SL,
-    CONFTYPE_BOOL,
-    CONFTYPE_COMPRESS,
-    CONFTYPE_ENCRYPT,
-    CONFTYPE_HOLDING,
-    CONFTYPE_ESTIMATE,
-    CONFTYPE_STRATEGY,
-    CONFTYPE_TAPERALGO,
-    CONFTYPE_PRIORITY,
-    CONFTYPE_RATE,
-    CONFTYPE_INTRANGE,
-    CONFTYPE_EXINCLUDE
-} conftype_t;
-
-/* Compression types */
-typedef enum {
-    COMP_NONE,          /* No compression */
-    COMP_FAST,          /* Fast compression on client */
-    COMP_BEST,          /* Best compression on client */
-    COMP_CUST,          /* Custom compression on client */
-    COMP_SERVER_FAST,   /* Fast compression on server */
-    COMP_SERVER_BEST,   /* Best compression on server */
-    COMP_SERVER_CUST    /* Custom compression on server */
-} comp_t;
+    CNF_HOLDINGDISK,
+    CNF_AUTOLABEL,
+    CNF_DEBUG_DAYS,
+    CNF_TAPER_PARALLEL_WRITE,
+    CNF_RECOVERY_LIMIT,
+    CNF_CNF /* sentinel */
+} confparm_key;
+
+/* Given a confparm_key, return a pointer to the corresponding val_t.
+ *
+ * @param key: confparm_key
+ * @returns: pointer to value
+ */
+val_t *getconf(confparm_key key);
 
-/* Encryption types */
-typedef enum {
-    ENCRYPT_NONE,               /* No encryption */
-    ENCRYPT_CUST,               /* Custom encryption on client */
-    ENCRYPT_SERV_CUST           /* Custom encryption on server */
-} encrypt_t;
+/* (convenience macro) has this global parameter been seen?
+ *
+ * @param key: confparm_key
+ * @returns: boolean
+ */
+#define getconf_seen(key)       (val_t_seen(getconf((key))))
+#define getconf_linenum(key)       (val_t_seen(getconf((key))))
+
+/* (convenience macros)
+ * Fetch a global parameter of a specific type.  Note that these
+ * convenience macros have a different form from those for the
+ * subsections: here you specify a type and a key, while for the
+ * subsections you specify only a key.  The difference is historical.
+ *
+ * @param key: confparm_key
+ * @returns: various
+ */
+#define getconf_int(key)          (val_t_to_int(getconf((key))))
+#define getconf_int64(key)        (val_t_to_int64(getconf((key))))
+#define getconf_real(key)         (val_t_to_real(getconf((key))))
+#define getconf_str(key)         (val_t_to_str(getconf((key))))
+#define getconf_ident(key)        (val_t_to_ident(getconf((key))))
+#define getconf_identlist(key)    (val_t_to_identlist(getconf((key))))
+#define getconf_time(key)         (val_t_to_time(getconf((key))))
+#define getconf_size(key)         (val_t_to_size(getconf((key))))
+#define getconf_boolean(key)      (val_t_to_boolean(getconf((key))))
+#define getconf_compress(key)     (val_t_to_compress(getconf((key))))
+#define getconf_encrypt(key)      (val_t_to_encrypt(getconf((key))))
+#define getconf_holding(key)      (val_t_to_holding(getconf((key))))
+#define getconf_estimatelist(key) (val_t_to_estimatelist(getconf((key))))
+#define getconf_strategy(key)     (val_t_to_strategy(getconf((key))))
+#define getconf_taperalgo(key)    (val_t_to_taperalgo(getconf((key))))
+#define getconf_priority(key)     (val_t_to_priority(getconf((key))))
+#define getconf_rate(key)         (val_t_to_rate(getconf((key))))
+#define getconf_exinclude(key)    (val_t_to_exinclude(getconf((key))))
+#define getconf_intrange(key)     (val_t_to_intrange(getconf((key))))
+#define getconf_proplist(key)     (val_t_to_proplist(getconf((key))))
+#define getconf_send_amreport(key) (val_t_to_send_amreport(getconf((key))))
+#define getconf_autolabel(key)    (val_t_to_autolabel(getconf((key))))
+#define getconf_part_cache_type(key) (val_t_to_part_cache_type(getconf((key))))
+#define getconf_recovery_limit(key) (val_t_to_recovery_limit(getconf((key))))
+
+/* Get a list of names for subsections of the given type
+ *
+ * @param listname: the desired type of subsection
+ * @returns: list of subsection names; caller is responsible for freeing
+ * this list, but not the strings it points to, using g_slist_free().
+ */
+GSList *getconf_list(char *listname);
 
-/* holdingdisk types */
-typedef enum {
-    HOLD_NEVER,                        /* Always direct to tape  */
-    HOLD_AUTO,                 /* If possible            */
-    HOLD_REQUIRED              /* Always to holding disk */
-} dump_holdingdisk_t;
+/* Get a configuration value by name, supporting the TYPE:SUBSEC:KEYWORD.
+ * Returns NULL if the configuration value doesnt exist.
+ */
+val_t *getconf_byname(char *key);
 
-typedef struct {        /* token table entry */
-    char *keyword;
-    tok_t token;
-} keytab_t;
+/*
+ * Derived values
+ *
+ * Values which aren't directly specified by the configuration, but which
+ * are derived from it.
+ */
 
-typedef struct {
-    char *name;
-    char *value;
-    int   used;
-} command_option_t;
+/* Return a divisor which will convert a value in units of kilo-whatevers
+ * to the user's selected display unit.
+ *
+ * @returns: long integer divisor
+ */
+long int getconf_unit_divisor(void);
 
-typedef struct exinclude_s {
-    sl_t *sl_list;
-    sl_t *sl_file;
-    int  optional;
-} exinclude_t;
+/* If any of these globals are true, the corresponding component will
+ * send verbose debugging output to the debug file.  The options are
+ * set during config_init, but can be modified at will after that if 
+ * desired.  */
 
-typedef struct val_s {
-    union {
-       int             i;
-       long            l;
-       off_t           am64;
-       double          r;
-       char            *s;
-       sl_t            *sl;
-       ssize_t         size;
-       time_t          t;
-       float           rate[2];
-       exinclude_t     exinclude;
-       int             intrange[2];
-    } v;
-    int seen;
-    conftype_t type;
-} val_t;
+extern int debug_amandad;
+extern int debug_recovery;
+extern int debug_amidxtaped;
+extern int debug_amindexd;
+extern int debug_amrecover;
+extern int debug_auth;
+extern int debug_event;
+extern int debug_holding;
+extern int debug_protocol;
+extern int debug_planner;
+extern int debug_driver;
+extern int debug_dumper;
+extern int debug_chunker;
+extern int debug_taper;
+extern int debug_selfcheck;
+extern int debug_sendsize;
+extern int debug_sendbackup;
 
-typedef struct s_conf_var {
-    tok_t      token;
-    conftype_t type;
-    void       (*read_function) (struct s_conf_var *, val_t*);
-    int                parm;
-    void       (*validate) (struct s_conf_var *, val_t *);
-} t_conf_var;
+/*
+ * Tapetype parameter access
+ */
 
-typedef enum tapetype_e  {
+typedef enum {
     TAPETYPE_COMMENT,
     TAPETYPE_LBL_TEMPL,
     TAPETYPE_BLOCKSIZE,
@@ -327,68 +586,87 @@ typedef enum tapetype_e  {
     TAPETYPE_LENGTH,
     TAPETYPE_FILEMARK,
     TAPETYPE_SPEED,
-    TAPETYPE_FILE_PAD,
-    TAPETYPE_TAPETYPE
-} tapetype_ee;
-
-typedef struct tapetype_s {
-    struct tapetype_s *next;
-    int seen;
-    char *name;
-
-    val_t value[TAPETYPE_TAPETYPE];
-} tapetype_t;
-
-#define tapetype_get(tapetype, field) (tapetype->field)
-#define tapetype_get_name(tapetype) tapetype->name
-#define tapetype_get_seen(tapetype) tapetype->seen
-#define tapetype_get_comment(tapetype)       get_conftype_string(&tapetype->value[TAPETYPE_COMMENT])
-#define tapetype_get_lbl_templ(tapetype)     get_conftype_string(&tapetype->value[TAPETYPE_LBL_TEMPL])
-#define tapetype_get_blocksize(tapetype)     get_conftype_size  (&tapetype->value[TAPETYPE_BLOCKSIZE])
-#define tapetype_get_readblocksize(tapetype) get_conftype_size  (&tapetype->value[TAPETYPE_READBLOCKSIZE])
-#define tapetype_get_length(tapetype)        get_conftype_am64  (&tapetype->value[TAPETYPE_LENGTH])
-#define tapetype_get_filemark(tapetype)      get_conftype_am64  (&tapetype->value[TAPETYPE_FILEMARK])
-#define tapetype_get_speed(tapetype)         get_conftype_int   (&tapetype->value[TAPETYPE_SPEED])
-#define tapetype_get_file_pad(tapetype)      get_conftype_bool  (&tapetype->value[TAPETYPE_FILE_PAD])
+    TAPETYPE_PART_SIZE,
+    TAPETYPE_PART_CACHE_TYPE,
+    TAPETYPE_PART_CACHE_DIR,
+    TAPETYPE_PART_CACHE_MAX_SIZE,
+    TAPETYPE_TAPETYPE /* sentinel */
+} tapetype_key;
+
+/* opaque object */
+typedef struct tapetype_s tapetype_t;
+
+/* Given the name of the tapetype, return a tapetype object.  Returns NULL
+ * if no matching tapetype exists.  Note that the match is case-insensitive.
+ *
+ * @param identifier: name of the desired tapetype
+ * @returns: object or NULL
+ */
+tapetype_t *lookup_tapetype(char *identifier);
 
-/* Dump strategies */
-#define DS_SKIP                0       /* Don't do any dumps at all */
-#define DS_STANDARD    1       /* Standard (0 1 1 1 1 2 2 2 ...) */
-#define DS_NOFULL      2       /* No full's (1 1 1 ...) */
-#define DS_NOINC       3       /* No inc's (0 0 0 ...) */
-#define DS_4           4       /* ? (0 1 2 3 4 5 6 7 8 9 10 11 ...) */
-#define DS_5           5       /* ? (0 1 1 1 1 1 1 1 1 1 1 1 ...) */
-#define DS_HANOI       6       /* Tower of Hanoi (? ? ? ? ? ...) */
-#define DS_INCRONLY    7       /* Forced fulls (0 1 1 2 2 FORCE0 1 1 ...) */
+/* Given a tapetype and a key, return a pointer to the corresponding val_t.
+ *
+ * @param ttyp: the tapetype to examine
+ * @param key: tapetype_key (one of the TAPETYPE_* constants)
+ * @returns: pointer to value
+ */
+val_t *tapetype_getconf(tapetype_t *ttyp, tapetype_key key);
 
-/* Estimate strategies */
-#define ES_CLIENT      0       /* client estimate */
-#define ES_SERVER      1       /* server estimate */
-#define ES_CALCSIZE    2       /* calcsize estimate */
-
-#define ALGO_FIRST     0
-#define ALGO_FIRSTFIT  1
-#define ALGO_LARGEST   2
-#define ALGO_LARGESTFIT        3
-#define ALGO_SMALLEST  4
-#define ALGO_LAST      5
-
-typedef enum dumptype_e  {
+/* Get the name of this tapetype.
+ *
+ * @param ttyp: the tapetype to examine
+ * @returns: name of the tapetype
+ */
+char *tapetype_name(tapetype_t *ttyp);
+
+/* (convenience macro) has this parameter been seen in this tapetype?  This
+ * applies to the specific parameter *within* the tapetype.
+ *
+ * @param key: tapetype_key
+ * @returns: boolean
+ */
+#define tapetype_seen(ttyp, key)       (val_t_seen(tapetype_getconf((ttyp), (key))))
+
+/* (convenience macros)
+ * fetch a particular parameter; caller must know the correct type.
+ *
+ * @param ttyp: the tapetype to examine
+ * @returns: various
+ */
+#define tapetype_get_comment(ttyp)             (val_t_to_str(tapetype_getconf((ttyp), TAPETYPE_COMMENT)))
+#define tapetype_get_lbl_templ(ttyp)           (val_t_to_str(tapetype_getconf((ttyp), TAPETYPE_LBL_TEMPL)))
+#define tapetype_get_blocksize(ttyp)           (val_t_to_size(tapetype_getconf((ttyp), TAPETYPE_BLOCKSIZE)))
+#define tapetype_get_readblocksize(ttyp)       (val_t_to_size(tapetype_getconf((ttyp), TAPETYPE_READBLOCKSIZE)))
+#define tapetype_get_length(ttyp)              (val_t_to_int64(tapetype_getconf((ttyp), TAPETYPE_LENGTH)))
+#define tapetype_get_filemark(ttyp)            (val_t_to_int64(tapetype_getconf((ttyp), TAPETYPE_FILEMARK)))
+#define tapetype_get_speed(ttyp)               (val_t_to_int(tapetype_getconf((ttyp), TAPETYPE_SPEED)))
+#define tapetype_get_part_size(ttyp)           (val_t_to_int64(tapetype_getconf((ttyp), TAPETYPE_PART_SIZE)))
+#define tapetype_get_part_cache_type(ttyp)     (val_t_to_part_cache_type(tapetype_getconf((ttyp), TAPETYPE_PART_CACHE_TYPE)))
+#define tapetype_get_part_cache_dir(ttyp)      (val_t_to_str(tapetype_getconf((ttyp), TAPETYPE_PART_CACHE_DIR)))
+#define tapetype_get_part_cache_max_size(ttyp) (val_t_to_int64(tapetype_getconf((ttyp), TAPETYPE_PART_CACHE_MAX_SIZE)))
+
+/*
+ * Dumptype parameter access
+ *
+ * Note that some parameters are generic to the host
+ */
+
+typedef enum {
     DUMPTYPE_COMMENT,
     DUMPTYPE_PROGRAM,
     DUMPTYPE_SRVCOMPPROG,
     DUMPTYPE_CLNTCOMPPROG,
     DUMPTYPE_SRV_ENCRYPT,
     DUMPTYPE_CLNT_ENCRYPT,
-    DUMPTYPE_AMANDAD_PATH,
-    DUMPTYPE_CLIENT_USERNAME,
-    DUMPTYPE_SSH_KEYS,
-    DUMPTYPE_SECURITY_DRIVER,
+    DUMPTYPE_AMANDAD_PATH,             /* host parameter */
+    DUMPTYPE_CLIENT_USERNAME,          /* host parameter */
+    DUMPTYPE_SSH_KEYS,                 /* host parameter */
+    DUMPTYPE_AUTH,                     /* host parameter */
     DUMPTYPE_EXCLUDE,
     DUMPTYPE_INCLUDE,
     DUMPTYPE_PRIORITY,
     DUMPTYPE_DUMPCYCLE,
-    DUMPTYPE_MAXDUMPS,
+    DUMPTYPE_MAXDUMPS,                 /* host parameter */
     DUMPTYPE_MAXPROMOTEDAY,
     DUMPTYPE_BUMPPERCENT,
     DUMPTYPE_BUMPSIZE,
@@ -396,7 +674,7 @@ typedef enum dumptype_e  {
     DUMPTYPE_BUMPMULT,
     DUMPTYPE_STARTTIME,
     DUMPTYPE_STRATEGY,
-    DUMPTYPE_ESTIMATE,
+    DUMPTYPE_ESTIMATELIST,
     DUMPTYPE_COMPRESS,
     DUMPTYPE_ENCRYPT,
     DUMPTYPE_SRV_DECRYPT_OPT,
@@ -412,226 +690,754 @@ typedef enum dumptype_e  {
     DUMPTYPE_KENCRYPT,
     DUMPTYPE_IGNORE,
     DUMPTYPE_INDEX,
-    DUMPTYPE_DUMPTYPE
-} dumptype_ee;
-
-typedef struct dumptype_s {
-    struct dumptype_s *next;
-    int seen;
-    char *name;
-
-    val_t value[DUMPTYPE_DUMPTYPE];
-} dumptype_t;
-
-#define dumptype_get_name(dumptype) dumptype->name
-#define dumptype_get_seen(dumptype) dumptype->seen
-#define dumptype_get_comment(dumptype)            get_conftype_string   (&dumptype->value[DUMPTYPE_COMMENT])
-#define dumptype_get_program(dumptype)            get_conftype_string   (&dumptype->value[DUMPTYPE_PROGRAM])
-#define dumptype_get_srvcompprog(dumptype)        get_conftype_string   (&dumptype->value[DUMPTYPE_SRVCOMPPROG])
-#define dumptype_get_clntcompprog(dumptype)       get_conftype_string   (&dumptype->value[DUMPTYPE_CLNTCOMPPROG])
-#define dumptype_get_srv_encrypt(dumptype)        get_conftype_string   (&dumptype->value[DUMPTYPE_SRV_ENCRYPT])
-#define dumptype_get_clnt_encrypt(dumptype)       get_conftype_string   (&dumptype->value[DUMPTYPE_CLNT_ENCRYPT])
-#define dumptype_get_amandad_path(dumptype)       get_conftype_string   (&dumptype->value[DUMPTYPE_AMANDAD_PATH])
-#define dumptype_get_client_username(dumptype)    get_conftype_string   (&dumptype->value[DUMPTYPE_CLIENT_USERNAME])
-#define dumptype_get_ssh_keys(dumptype)           get_conftype_string   (&dumptype->value[DUMPTYPE_SSH_KEYS])
-#define dumptype_get_security_driver(dumptype)    get_conftype_string   (&dumptype->value[DUMPTYPE_SECURITY_DRIVER])
-#define dumptype_get_exclude(dumptype)            get_conftype_exinclude(&dumptype->value[DUMPTYPE_EXCLUDE])
-#define dumptype_get_include(dumptype)            get_conftype_exinclude(&dumptype->value[DUMPTYPE_INCLUDE])
-#define dumptype_get_priority(dumptype)           get_conftype_priority (&dumptype->value[DUMPTYPE_PRIORITY])
-#define dumptype_get_dumpcycle(dumptype)          get_conftype_int      (&dumptype->value[DUMPTYPE_DUMPCYCLE])
-#define dumptype_get_maxcycle(dumptype)           get_conftype_int      (&dumptype->value[DUMPTYPE_MAXCYCLE])
-#define dumptype_get_frequency(dumptype)          get_conftype_int      (&dumptype->value[DUMPTYPE_FREQUENCY])
-#define dumptype_get_maxdumps(dumptype)           get_conftype_int      (&dumptype->value[DUMPTYPE_MAXDUMPS])
-#define dumptype_get_maxpromoteday(dumptype)      get_conftype_int      (&dumptype->value[DUMPTYPE_MAXPROMOTEDAY])
-#define dumptype_get_bumppercent(dumptype)        get_conftype_int      (&dumptype->value[DUMPTYPE_BUMPPERCENT])
-#define dumptype_get_bumpsize(dumptype)           get_conftype_am64     (&dumptype->value[DUMPTYPE_BUMPSIZE])
-#define dumptype_get_bumpdays(dumptype)           get_conftype_int      (&dumptype->value[DUMPTYPE_BUMPDAYS])
-#define dumptype_get_bumpmult(dumptype)           get_conftype_real     (&dumptype->value[DUMPTYPE_BUMPMULT])
-#define dumptype_get_starttime(dumptype)          get_conftype_time     (&dumptype->value[DUMPTYPE_STARTTIME])
-#define dumptype_get_strategy(dumptype)           get_conftype_strategy (&dumptype->value[DUMPTYPE_STRATEGY])
-#define dumptype_get_estimate(dumptype)           get_conftype_estimate (&dumptype->value[DUMPTYPE_ESTIMATE])
-#define dumptype_get_compress(dumptype)           get_conftype_compress (&dumptype->value[DUMPTYPE_COMPRESS])
-#define dumptype_get_encrypt(dumptype)            get_conftype_encrypt  (&dumptype->value[DUMPTYPE_ENCRYPT])
-#define dumptype_get_srv_decrypt_opt(dumptype)    get_conftype_string   (&dumptype->value[DUMPTYPE_SRV_DECRYPT_OPT])
-#define dumptype_get_clnt_decrypt_opt(dumptype)   get_conftype_string   (&dumptype->value[DUMPTYPE_CLNT_DECRYPT_OPT])
-#define dumptype_get_comprate(dumptype)                                   dumptype->value[DUMPTYPE_COMPRATE].v.rate
-#define dumptype_get_tape_splitsize(dumptype)     get_conftype_am64     (&dumptype->value[DUMPTYPE_TAPE_SPLITSIZE])
-#define dumptype_get_fallback_splitsize(dumptype) get_conftype_am64     (&dumptype->value[DUMPTYPE_FALLBACK_SPLITSIZE])
-#define dumptype_get_split_diskbuffer(dumptype)   get_conftype_string   (&dumptype->value[DUMPTYPE_SPLIT_DISKBUFFER])
-#define dumptype_get_record(dumptype)             get_conftype_bool     (&dumptype->value[DUMPTYPE_RECORD])
-#define dumptype_get_skip_incr(dumptype)          get_conftype_bool     (&dumptype->value[DUMPTYPE_SKIP_INCR])
-#define dumptype_get_skip_full(dumptype)          get_conftype_bool     (&dumptype->value[DUMPTYPE_SKIP_FULL])
-#define dumptype_get_to_holdingdisk(dumptype)     get_conftype_hold     (&dumptype->value[DUMPTYPE_HOLDINGDISK])
-#define dumptype_get_kencrypt(dumptype)           get_conftype_bool     (&dumptype->value[DUMPTYPE_KENCRYPT])
-#define dumptype_get_ignore(dumptype)             get_conftype_bool     (&dumptype->value[DUMPTYPE_IGNORE])
-#define dumptype_get_index(dumptype)              get_conftype_bool     (&dumptype->value[DUMPTYPE_INDEX])
-
-/* A network interface */
-typedef enum interface_e  {
+    DUMPTYPE_APPLICATION,
+    DUMPTYPE_SCRIPTLIST,
+    DUMPTYPE_PROPERTY,
+    DUMPTYPE_CLIENT_PORT,
+    DUMPTYPE_DATA_PATH,
+    DUMPTYPE_ALLOW_SPLIT,
+    DUMPTYPE_RECOVERY_LIMIT,
+    DUMPTYPE_DUMPTYPE /* sentinel */
+} dumptype_key;
+
+/* opaque object */
+typedef struct dumptype_s dumptype_t;
+
+/* Given the name of the dumptype, return a dumptype object.  Returns NULL
+ * if no matching dumptype exists.  Note that the match is case-insensitive.
+ *
+ * @param identifier: name of the desired dumptype
+ * @returns: object or NULL
+ */
+dumptype_t *lookup_dumptype(char *identifier);
+
+/* Given a dumptype and a key, return a pointer to the corresponding val_t.
+ *
+ * @param dtyp: the dumptype to examine
+ * @param key: dumptype_key (one of the TAPETYPE_* constants)
+ * @returns: pointer to value
+ */
+val_t *dumptype_getconf(dumptype_t *dtyp, dumptype_key key);
+
+/* Get the name of this dumptype.
+ *
+ * @param dtyp: the dumptype to examine
+ * @returns: name of the dumptype
+ */
+char *dumptype_name(dumptype_t *dtyp);
+
+/* (convenience macro) has this parameter been seen in this dumptype?  This
+ * applies to the specific parameter *within* the dumptype.
+ *
+ * @param key: dumptype_key
+ * @returns: boolean
+ */
+#define dumptype_seen(dtyp, key)       (val_t_seen(dumptype_getconf((dtyp), (key))))
+
+/* (convenience macros)
+ * fetch a particular parameter; caller must know the correct type.
+ *
+ * @param dtyp: the dumptype to examine
+ * @returns: various
+ */
+#define dumptype_get_comment(dtyp)             (val_t_to_str(dumptype_getconf((dtyp), DUMPTYPE_COMMENT)))
+#define dumptype_get_program(dtyp)             (val_t_to_str(dumptype_getconf((dtyp), DUMPTYPE_PROGRAM)))
+#define dumptype_get_srvcompprog(dtyp)         (val_t_to_str(dumptype_getconf((dtyp), DUMPTYPE_SRVCOMPPROG)))
+#define dumptype_get_clntcompprog(dtyp)        (val_t_to_str(dumptype_getconf((dtyp), DUMPTYPE_CLNTCOMPPROG)))
+#define dumptype_get_srv_encrypt(dtyp)         (val_t_to_str(dumptype_getconf((dtyp), DUMPTYPE_SRV_ENCRYPT)))
+#define dumptype_get_clnt_encrypt(dtyp)        (val_t_to_str(dumptype_getconf((dtyp), DUMPTYPE_CLNT_ENCRYPT)))
+#define dumptype_get_amandad_path(dtyp)        (val_t_to_str(dumptype_getconf((dtyp), DUMPTYPE_AMANDAD_PATH)))
+#define dumptype_get_client_username(dtyp)     (val_t_to_str(dumptype_getconf((dtyp), DUMPTYPE_CLIENT_USERNAME)))
+#define dumptype_get_ssh_keys(dtyp)            (val_t_to_str(dumptype_getconf((dtyp), DUMPTYPE_SSH_KEYS)))
+#define dumptype_get_auth(dtyp)                (val_t_to_str(dumptype_getconf((dtyp), DUMPTYPE_AUTH)))
+#define dumptype_get_exclude(dtyp)             (val_t_to_exinclude(dumptype_getconf((dtyp), DUMPTYPE_EXCLUDE)))
+#define dumptype_get_include(dtyp)             (val_t_to_exinclude(dumptype_getconf((dtyp), DUMPTYPE_INCLUDE)))
+#define dumptype_get_priority(dtyp)            (val_t_to_priority(dumptype_getconf((dtyp), DUMPTYPE_PRIORITY)))
+#define dumptype_get_dumpcycle(dtyp)           (val_t_to_int(dumptype_getconf((dtyp), DUMPTYPE_DUMPCYCLE)))
+#define dumptype_get_maxcycle(dtyp)            (val_t_to_int(dumptype_getconf((dtyp), DUMPTYPE_MAXCYCLE)))
+#define dumptype_get_frequency(dtyp)           (val_t_to_int(dumptype_getconf((dtyp), DUMPTYPE_FREQUENCY)))
+#define dumptype_get_maxdumps(dtyp)            (val_t_to_int(dumptype_getconf((dtyp), DUMPTYPE_MAXDUMPS)))
+#define dumptype_get_maxpromoteday(dtyp)       (val_t_to_int(dumptype_getconf((dtyp), DUMPTYPE_MAXPROMOTEDAY)))
+#define dumptype_get_bumppercent(dtyp)         (val_t_to_int(dumptype_getconf((dtyp), DUMPTYPE_BUMPPERCENT)))
+#define dumptype_get_bumpsize(dtyp)            (val_t_to_int64(dumptype_getconf((dtyp), DUMPTYPE_BUMPSIZE)))
+#define dumptype_get_bumpdays(dtyp)            (val_t_to_int(dumptype_getconf((dtyp), DUMPTYPE_BUMPDAYS)))
+#define dumptype_get_bumpmult(dtyp)            (val_t_to_real(dumptype_getconf((dtyp), DUMPTYPE_BUMPMULT)))
+#define dumptype_get_starttime(dtyp)           (val_t_to_time(dumptype_getconf((dtyp), DUMPTYPE_STARTTIME)))
+#define dumptype_get_strategy(dtyp)            (val_t_to_strategy(dumptype_getconf((dtyp), DUMPTYPE_STRATEGY)))
+#define dumptype_get_estimatelist(dtyp)        (val_t_to_estimatelist(dumptype_getconf((dtyp), DUMPTYPE_ESTIMATELIST)))
+#define dumptype_get_compress(dtyp)            (val_t_to_compress(dumptype_getconf((dtyp), DUMPTYPE_COMPRESS)))
+#define dumptype_get_encrypt(dtyp)             (val_t_to_encrypt(dumptype_getconf((dtyp), DUMPTYPE_ENCRYPT)))
+#define dumptype_get_srv_decrypt_opt(dtyp)     (val_t_to_str(dumptype_getconf((dtyp), DUMPTYPE_SRV_DECRYPT_OPT)))
+#define dumptype_get_clnt_decrypt_opt(dtyp)    (val_t_to_str(dumptype_getconf((dtyp), DUMPTYPE_CLNT_DECRYPT_OPT)))
+#define dumptype_get_comprate(dtyp)            (val_t_to_rate(dumptype_getconf((dtyp), DUMPTYPE_COMPRATE)))
+#define dumptype_get_tape_splitsize(dtyp)      (val_t_to_int64(dumptype_getconf((dtyp), DUMPTYPE_TAPE_SPLITSIZE)))
+#define dumptype_get_fallback_splitsize(dtyp)  (val_t_to_int64(dumptype_getconf((dtyp), DUMPTYPE_FALLBACK_SPLITSIZE)))
+#define dumptype_get_split_diskbuffer(dtyp)    (val_t_to_str(dumptype_getconf((dtyp), DUMPTYPE_SPLIT_DISKBUFFER)))
+#define dumptype_get_record(dtyp)              (val_t_to_boolean(dumptype_getconf((dtyp), DUMPTYPE_RECORD)))
+#define dumptype_get_skip_incr(dtyp)           (val_t_to_boolean(dumptype_getconf((dtyp), DUMPTYPE_SKIP_INCR)))
+#define dumptype_get_skip_full(dtyp)           (val_t_to_boolean(dumptype_getconf((dtyp), DUMPTYPE_SKIP_FULL)))
+#define dumptype_get_to_holdingdisk(dtyp)      (val_t_to_holding(dumptype_getconf((dtyp), DUMPTYPE_HOLDINGDISK)))
+#define dumptype_get_kencrypt(dtyp)            (val_t_to_boolean(dumptype_getconf((dtyp), DUMPTYPE_KENCRYPT)))
+#define dumptype_get_ignore(dtyp)              (val_t_to_boolean(dumptype_getconf((dtyp), DUMPTYPE_IGNORE)))
+#define dumptype_get_index(dtyp)               (val_t_to_boolean(dumptype_getconf((dtyp), DUMPTYPE_INDEX)))
+#define dumptype_get_application(dtyp)         (val_t_to_application(dumptype_getconf((dtyp), DUMPTYPE_APPLICATION)))
+#define dumptype_get_scriptlist(dtyp)          (val_t_to_identlist(dumptype_getconf((dtyp), DUMPTYPE_SCRIPTLIST)))
+#define dumptype_get_property(dtyp)            (val_t_to_proplist(dumptype_getconf((dtyp), DUMPTYPE_PROPERTY)))
+#define dumptype_get_client_port(dtyp)             (val_t_to_str(dumptype_getconf((dtyp), DUMPTYPE_CLIENT_PORT)))
+#define dumptype_get_data_path(dtyp)             (val_t_to_data_path(dumptype_getconf((dtyp), DUMPTYPE_DATA_PATH)))
+#define dumptype_get_allow_split(dtyp)         (val_t_to_boolean(dumptype_getconf((dtyp), DUMPTYPE_ALLOW_SPLIT)))
+#define dumptype_get_recovery_limit(dtyp)      (val_t_to_recovery_limit(dumptype_getconf((dtyp), DUMPTYPE_RECOVERY_LIMIT)))
+
+/*
+ * Interface parameter access
+ */
+
+typedef enum {
     INTER_COMMENT,
     INTER_MAXUSAGE,
-    INTER_INTER
-} interface_ee;
+    INTER_INTER /* sentinel */
+} interface_key;
 
+/* opaque object */
+typedef struct interface_s interface_t;
 
-typedef struct interface_s {
-    struct interface_s *next;
-    int seen;
-    char *name;
+/* Given the name of the interface, return a interface object.  Returns NULL
+ * if no matching interface exists.  Note that the match is case-insensitive.
+ *
+ * @param identifier: name of the desired interface
+ * @returns: object or NULL
+ */
+interface_t *lookup_interface(char *identifier);
+
+/* Given a interface and a key, return a pointer to the corresponding val_t.
+ *
+ * @param iface: the interface to examine
+ * @param key: interface_key (one of the TAPETYPE_* constants)
+ * @returns: pointer to value
+ */
+val_t *interface_getconf(interface_t *iface, interface_key key);
+
+/* Get the name of this interface.
+ *
+ * @param iface: the interface to examine
+ * @returns: name of the interface
+ */
+char *interface_name(interface_t *iface);
 
-    val_t value[INTER_INTER];
+/* (convenience macro) has this parameter been seen in this interface?  This
+ * applies to the specific parameter *within* the interface.
+ *
+ * @param key: interface_key
+ * @returns: boolean
+ */
+#define interface_seen(iface, key)       (val_t_seen(interface_getconf((iface), (key))))
 
-    unsigned long curusage;            /* current usage */
-} interface_t;
+/* (convenience macros)
+ * fetch a particular parameter; caller must know the correct type.
+ *
+ * @param iface: the interface to examine
+ * @returns: various
+ */
+#define interface_get_comment(iface)    (val_t_to_str(interface_getconf((iface), INTER_COMMENT)))
+#define interface_get_maxusage(iface)   (val_t_to_int(interface_getconf((iface), INTER_MAXUSAGE)))
 
-#define interface_get_name(interface) interface->name
-#define interface_get_seen(interface) interface->seen
-#define interface_get_comment(interface)  get_conftype_string(&interface->value[INTER_COMMENT])
-#define interface_get_maxusage(interface) get_conftype_int   (&interface->value[INTER_MAXUSAGE])
+/*
+ * Holdingdisk parameter access
+ */
 
-/* A holding disk */
-typedef enum holdingdisk_e  {
+typedef enum {
     HOLDING_COMMENT,
     HOLDING_DISKDIR,
     HOLDING_DISKSIZE,
     HOLDING_CHUNKSIZE,
-    HOLDING_HOLDING
-} holdingdisk_ee;
+    HOLDING_HOLDING /* sentinel */
+} holdingdisk_key;
 
-typedef struct holdingdisk_s {
-    struct holdingdisk_s *next;
-    int seen;
-    char *name;
+/* opaque object */
+typedef struct holdingdisk_s holdingdisk_t;
 
-    val_t value[HOLDING_HOLDING];
+/* Given the name of the holdingdisk, return a holdingdisk object.  Returns NULL
+ * if no matching holdingdisk exists.  Note that the match is case-insensitive.
+ *
+ * @param identifier: name of the desired holdingdisk
+ * @returns: object or NULL
+ */
+holdingdisk_t *lookup_holdingdisk(char *identifier);
 
-    void *up;                  /* generic user pointer */
-    off_t disksize;
-} holdingdisk_t;
+/* Return the whole linked list of holdingdisks.
+ *
+ * @returns: first holding disk
+ */
+GSList *getconf_holdingdisks(void);
 
-#define holdingdisk_get_name(holdingdisk) (holdingdisk)->name
-#define holdingdisk_get_seen(holdingdisk) (holdingdisk)->seen
-#define holdingdisk_get_comment(holdingdisk)   get_conftype_string(&(holdingdisk)->value[HOLDING_COMMENT])
-#define holdingdisk_get_diskdir(holdingdisk)   get_conftype_string(&(holdingdisk)->value[HOLDING_DISKDIR])
-#define holdingdisk_get_disksize(holdingdisk)  get_conftype_am64  (&(holdingdisk)->value[HOLDING_DISKSIZE])
-#define holdingdisk_get_chunksize(holdingdisk) get_conftype_am64  (&(holdingdisk)->value[HOLDING_CHUNKSIZE])
+/* Given a holdingdisk and a key, return a pointer to the corresponding val_t.
+ *
+ * @param hdisk: the holdingdisk to examine
+ * @param key: holdingdisk_key (one of the TAPETYPE_* constants)
+ * @returns: pointer to value
+ */
+val_t *holdingdisk_getconf(holdingdisk_t *hdisk, holdingdisk_key key);
 
-/* for each column we define some values on how to
- * format this column element
+/* Get the name of this holdingdisk.
+ *
+ * @param hdisk: the holdingdisk to examine
+ * @returns: name of the holdingdisk
  */
-typedef struct {
-    char *Name;                /* column name */
-    int PrefixSpace;   /* the blank space to print before this
-                        * column. It is used to get the space
-                        * between the colums
-                        */
-    int Width;         /* the width of the column itself */
-    int Precision;     /* the precision if its a float */
-    int MaxWidth;      /* if set, Width will be recalculated
-                        * to the space needed */
-    char *Format;      /* the printf format string for this
-                        * column element
-                        */
-    char *Title;       /* the title to use for this column */
-} ColumnInfo;
-
-
-/* predeclare local functions */
-
-int          get_conftype_int      (val_t *);
-long         get_conftype_long     (val_t *);
-off_t        get_conftype_am64     (val_t *);
-double       get_conftype_real     (val_t *);
-char        *get_conftype_string   (val_t *);
-char        *get_conftype_ident    (val_t *);
-time_t       get_conftype_time     (val_t *);
-ssize_t      get_conftype_size     (val_t *);
-sl_t        *get_conftype_sl       (val_t *);
-int          get_conftype_bool     (val_t *);
-int          get_conftype_hold     (val_t *);
-int          get_conftype_compress (val_t *);
-int          get_conftype_encrypt  (val_t *);
-int          get_conftype_estimate (val_t *);
-int          get_conftype_strategy (val_t *);
-int          get_conftype_taperalgo(val_t *);
-int          get_conftype_priority (val_t *);
-float       *get_conftype_rate     (val_t *);
-exinclude_t  get_conftype_exinclude(val_t *);
-int         *get_conftype_intrange (val_t *);
-
-void command_overwrite(command_option_t *command_options, t_conf_var *overwrite_var,
-                      keytab_t *keytab, val_t *valarray, char *prefix);
-
-void free_new_argv(int new_argc, char **new_argv);
-/* this corresponds to the normal output of amanda, but may
- * be adapted to any spacing as you like.
- */
-extern ColumnInfo ColumnData[];
-
-extern char *config_name;
-extern char *config_dir;
+char *holdingdisk_name(holdingdisk_t *hdisk);
 
-extern int debug_amandad;
-extern int debug_amidxtaped;
-extern int debug_amindexd;
-extern int debug_amrecover;
-extern int debug_auth;
-extern int debug_event;
-extern int debug_holding;
-extern int debug_protocol;
-extern int debug_planner;
-extern int debug_driver;
-extern int debug_dumper;
-extern int debug_chunker;
-extern int debug_taper;
-extern int debug_selfcheck;
-extern int debug_sendsize;
-extern int debug_sendbackup;
+/* (convenience macro) has this parameter been seen in this holdingdisk?  This
+ * applies to the specific parameter *within* the holdingdisk.
+ *
+ * @param key: holdingdisk_key
+ * @returns: boolean
+ */
+#define holdingdisk_seen(hdisk, key)       (val_t_seen(holdingdisk_getconf((hdisk), (key))))
+
+/* (convenience macros)
+ * fetch a particular parameter; caller must know the correct type.
+ *
+ * @param hdisk: the holdingdisk to examine
+ * @returns: various
+ */
+#define holdingdisk_get_comment(hdisk)   (val_t_to_str(holdingdisk_getconf((hdisk), HOLDING_COMMENT)))
+#define holdingdisk_get_diskdir(hdisk)   (val_t_to_str(holdingdisk_getconf((hdisk), HOLDING_DISKDIR)))
+#define holdingdisk_get_disksize(hdisk)  (val_t_to_int64(holdingdisk_getconf((hdisk), HOLDING_DISKSIZE)))
+#define holdingdisk_get_chunksize(hdisk) (val_t_to_int64(holdingdisk_getconf((hdisk), HOLDING_CHUNKSIZE)))
+
+/* A application-tool interface */
+typedef enum application_e  {
+    APPLICATION_COMMENT,
+    APPLICATION_PLUGIN,
+    APPLICATION_PROPERTY,
+    APPLICATION_APPLICATION
+} application_key;
+
+/* opaque object */
+typedef struct application_s application_t;
+
+/* Given the name of the application, return a application object.  Returns NULL
+ * if no matching application exists.  Note that the match is case-insensitive.
+ *
+ * @param identifier: name of the desired application
+ * @returns: object or NULL
+ */
+
+application_t *lookup_application(char *identifier);
+
+/* Given a application and a key, return a pointer to the corresponding val_t.
+ *
+ * @param ttyp: the application to examine
+ * @param key: application (one of the APPLICATION_* constants)
+ * @returns: pointer to value
+ */
+val_t *application_getconf(application_t *app, application_key key);
+
+/* Get the name of this application.
+ *
+ * @param ttyp: the application to examine
+ * @returns: name of the application
+ */
+char *application_name(application_t *app);
+
+/* (convenience macro) has this parameter been seen in this application?  This
+ * applies to the specific parameter *within* the application.
+ *
+ * @param key: application_key
+ * @returns: boolean
+ */
+#define application_seen(app, key)       (val_t_seen(application_getconf((app), (key))))
+
+/* (convenience macros)
+ * fetch a particular parameter; caller must know the correct type.
+ *
+ * @param ttyp: the application to examine
+ * @returns: various
+ */
+#define application_get_comment(application)  (val_t_to_str(application_getconf((application), APPLICATION_COMMENT))
+#define application_get_plugin(application)   (val_t_to_str(application_getconf((application), APPLICATION_PLUGIN)))
+#define application_get_property(application) (val_t_to_proplist(application_getconf((application), APPLICATION_PROPERTY)))
+
+application_t *read_application(char *name, FILE *from, char *fname, int *linenum);
+
+/* A pp-script-tool interface */
+typedef enum pp_script_e  {
+    PP_SCRIPT_COMMENT,
+    PP_SCRIPT_PLUGIN,
+    PP_SCRIPT_PROPERTY,
+    PP_SCRIPT_EXECUTE_ON,
+    PP_SCRIPT_EXECUTE_WHERE,
+    PP_SCRIPT_ORDER,
+    PP_SCRIPT_PP_SCRIPT
+} pp_script_key;
+
+/* opaque object */
+typedef struct pp_script_s pp_script_t;
+
+/* Given the name of the pp_script, return a pp_script object.  Returns NULL
+ * if no matching pp_script exists.  Note that the match is case-insensitive.
+ *
+ * @param identifier: name of the desired pp_script
+ * @returns: object or NULL
+ */
+
+pp_script_t *lookup_pp_script(char *identifier);
+
+/* Given a pp_script and a key, return a pointer to the corresponding val_t.
+ *
+ * @param ttyp: the pp_script to examine
+ * @param key: pp_script (one of the PP_SCRIPT_* constants)
+ * @returns: pointer to value
+ */
+val_t *pp_script_getconf(pp_script_t *pps, pp_script_key key);
+
+/* Get the name of this pp_script.
+ *
+ * @param ttyp: the pp_script to examine
+ * @returns: name of the pp_script
+ */
+char *pp_script_name(pp_script_t *pps);
+
+/* (convenience macro) has this parameter been seen in this pp_script?  This
+ * applies to the specific parameter *within* the pp_script.
+ *
+ * @param key: pp_script_key
+ * @returns: boolean
+ */
+#define pp_script_seen(pps, key)       (val_t_seen(pp_script_getconf((pps), (key))))
+
+/* (convenience macros)
+ * fetch a particular parameter; caller must know the correct type.
+ *
+ * @param ttyp: the pp_script to examine
+ * @returns: various
+ */
+
+#define pp_script_get_comment(pp_script)   (val_t_to_str(pp_script_getconf((pp_script), PP_SCRIPT_COMMENT)))
+#define pp_script_get_plugin(pp_script)   (val_t_to_str(pp_script_getconf((pp_script), PP_SCRIPT_PLUGIN)))
+#define pp_script_get_property(pp_script)   (val_t_to_proplist(pp_script_getconf((pp_script), PP_SCRIPT_PROPERTY)))
+#define pp_script_get_execute_on(pp_script)   (val_t_to_execute_on(pp_script_getconf((pp_script), PP_SCRIPT_EXECUTE_ON)))
+#define pp_script_get_execute_where(pp_script)   (val_t_to_execute_where(pp_script_getconf((pp_script), PP_SCRIPT_EXECUTE_WHERE)))
+#define pp_script_get_order(pp_script)   (val_t_to_int(pp_script_getconf((pp_script), PP_SCRIPT_ORDER)))
+
+pp_script_t *read_pp_script(char *name, FILE *from, char *fname, int *linenum);
+pp_script_t *lookup_pp_script(char *identifier);
+
+/* A device definition */
+typedef enum {
+    DEVICE_CONFIG_COMMENT,
+    DEVICE_CONFIG_TAPEDEV,
+    DEVICE_CONFIG_DEVICE_PROPERTY,
+    DEVICE_CONFIG_DEVICE_CONFIG
+} device_config_key;
+
+/* opaque object */
+typedef struct device_config_s device_config_t;
+
+/* Given the name of the device, return a device_config_t object.  Returns NULL
+ * if no matching device exists.  Note that the match is case-insensitive.
+ *
+ * @param identifier: name of the desired device
+ * @returns: object or NULL
+ */
+
+device_config_t *lookup_device_config(char *identifier);
+
+/* Given a device_config and a key, return a pointer to the corresponding val_t.
+ *
+ * @param ttyp: the device_config to examine
+ * @param key: device_config (one of the DEVICE_CONFIG_* constants)
+ * @returns: pointer to value
+ */
+val_t *device_config_getconf(device_config_t *devconf, device_config_key key);
+
+/* Get the name of this device_config.
+ *
+ * @param ttyp: the device_config to examine
+ * @returns: name of the device_config
+ */
+char *device_config_name(device_config_t *devconf);
+
+/* (convenience macro) has this parameter been seen in this device_config?  This
+ * applies to the specific parameter *within* the device_config.
+ *
+ * @param key: device_config_key
+ * @returns: boolean
+ */
+#define device_config_seen(devconf, key)       (val_t_seen(device_config_getconf((devconf), (key))))
+
+/* (convenience macros)
+ * fetch a particular parameter; caller must know the correct type.
+ *
+ * @param devconf: the device_config to examine
+ * @returns: various
+ */
+
+#define device_config_get_comment(devconf)   (val_t_to_str(device_config_getconf((devconf), DEVICE_CONFIG_COMMENT)))
+#define device_config_get_tapedev(devconf)   (val_t_to_str(device_config_getconf((devconf), DEVICE_CONFIG_TAPEDEV)))
+#define device_config_get_property(devconf)   (val_t_to_proplist(device_config_getconf((devconf), DEVICE_CONFIG_DEVICE_PROPERTY)))
+
+device_config_t *read_device_config(char *name, FILE *from, char *fname, int *linenum);
+device_config_t *lookup_device_config(char *identifier);
+
+/* A changer definition */
+typedef enum {
+    CHANGER_CONFIG_COMMENT,
+    CHANGER_CONFIG_TAPEDEV,
+    CHANGER_CONFIG_TPCHANGER,
+    CHANGER_CONFIG_CHANGERDEV,
+    CHANGER_CONFIG_CHANGERFILE,
+    CHANGER_CONFIG_PROPERTY,
+    CHANGER_CONFIG_DEVICE_PROPERTY,
+    CHANGER_CONFIG_CHANGER_CONFIG
+} changer_config_key;
+
+/* opaque object */
+typedef struct changer_config_s changer_config_t;
+
+/* Given the name of the changer, return a changer_config_t object.  Returns NULL
+ * if no matching changer exists.  Note that the match is case-insensitive.
+ *
+ * @param identifier: name of the desired changer
+ * @returns: object or NULL
+ */
+
+changer_config_t *lookup_changer_config(char *identifier);
+
+/* Given a changer_config and a key, return a pointer to the corresponding val_t.
+ *
+ * @param ttyp: the changer_config to examine
+ * @param key: changer_config (one of the DEVICE_CONFIG_* constants)
+ * @returns: pointer to value
+ */
+val_t *changer_config_getconf(changer_config_t *devconf, changer_config_key key);
+
+/* Get the name of this changer_config.
+ *
+ * @param ttyp: the changer_config to examine
+ * @returns: name of the changer_config
+ */
+char *changer_config_name(changer_config_t *devconf);
+
+/* (convenience macro) has this parameter been seen in this changer_config?  This
+ * applies to the specific parameter *within* the changer_config.
+ *
+ * @param key: changer_config_key
+ * @returns: boolean
+ */
+#define changer_config_seen(devconf, key)       (val_t_seen(changer_config_getconf((devconf), (key))))
+
+/* (convenience macros)
+ * fetch a particular parameter; caller must know the correct type.
+ *
+ * @param devconf: the changer_config to examine
+ * @returns: various
+ */
+
+#define changer_config_get_comment(devconf)   (val_t_to_str(changer_config_getconf((devconf), CHANGER_CONFIG_COMMENT)))
+#define changer_config_get_tapedev(devconf)   (val_t_to_str(changer_config_getconf((devconf), CHANGER_CONFIG_TAPEDEV)))
+#define changer_config_get_tpchanger(devconf)   (val_t_to_str(changer_config_getconf((devconf), CHANGER_CONFIG_TPCHANGER)))
+#define changer_config_get_changerdev(devconf)   (val_t_to_str(changer_config_getconf((devconf), CHANGER_CONFIG_CHANGERDEV)))
+#define changer_config_get_changerfile(devconf)   (val_t_to_str(changer_config_getconf((devconf), CHANGER_CONFIG_CHANGERFILE)))
+
+changer_config_t *read_changer_config(char *name, FILE *from, char *fname, int *linenum);
+changer_config_t *lookup_changer_config(char *identifier);
+
+/*
+ * Error Handling
+ */
+
+typedef enum {
+    /* No errors or warnings */
+    CFGERR_OK = 0,
 
-extern holdingdisk_t *holdingdisks;
-extern int num_holdingdisks;
+    /* warnings were encountered */
+    CFGERR_WARNINGS = 1,
 
-void parse_conf(int parse_argc, char **parse_argv, int *new_argc,
-                      char ***new_argv);
-char **get_config_options(int);
-void report_bad_conf_arg(void);
-void free_server_config(void);
+    /* errors (and maybe some warnings too, who knows) were encountered */
+    CFGERR_ERRORS = 2,
+} cfgerr_level_t;
 
-int read_conffile(char *filename);
+/*
+ * Errors
+ */
+
+/* Get a GSList of all error and warning messages accumulated so far.
+ *
+ * @param (output) errlist: pointer to the list of error strings; allocated
+ * memory remains the responsibility of the config module.  If errlist is
+ * NULL, the list is not returned.
+ * @returns: current error level
+ */
+cfgerr_level_t config_errors(GSList **errlist);
+
+/* Clear any error conditions.
+ */
+void config_clear_errors(void);
 
-#define CLIENTCONFFILE_NAME "client.conf"
+/* Print the list of current error and warning messages, one per line,
+ * to stderr. This is a convenience function for command-line
+ * applications.
+ */
+void config_print_errors(void);
+
+/* Add an error message to the list of errors, and make sure tha the
+ * error level is at least LEVEL.  This is used by the diskfile module
+ * to insert its errors into this module's error list.
+ *
+ * @param level: level for this error
+ * @param errmsg: error message; conffile takes responsibility for freeing
+ *   this string.
+ */
+void config_add_error(cfgerr_level_t level, char *errmsg);
+
+/*
+ * Command-line handling
+ */
+
+/* opaque type */
+typedef struct config_overrides_s config_overrides_t;
+
+/* Create a new, empty config_overrides object.
+ *
+ * @param size_estimate: a guess at the number of overwrites; argc/2 is a 
+ *  good estimate.
+ * @returns: new object
+ */
+config_overrides_t *new_config_overrides(int size_estimate);
+
+/* Free a config_overrides object.  This usually won't be needed, as
+ * apply_config_overrides takes ownership of the overwrites for you.
+ *
+ * @param co: config_overrides object
+ */
+void free_config_overrides(config_overrides_t *co);
+
+/* Add an overwrite to a config_overrides object.
+ *
+ * @param co: the config_overrides object
+ * @param key: the configuration parameter's key, possibly with the format
+ * SUBTYPE:NAME:KEYWORD
+ * @param value: the value for the parameter, as would be seen in amanda.conf
+ */
+void add_config_override(config_overrides_t *co,
+                        char *key,
+                        char *value);
+
+/* Add an overwrite option from the command line to a config_overrides
+ * object.  Calls error() with any errors
+ *
+ * @param co: the config_overrides object
+ * @param optarg: the value of the command-line option
+ */
+void add_config_override_opt(config_overrides_t *co,
+                             char *optarg);
+
+/* Given a command line, represented as argc/argv, extract any -o options
+ * as config overwrites.  This function modifies argc and argv in place.
+ *
+ * This is the deprecated way to extract config overwrites, for applications
+ * which do not use getopt.  The preferred method is to use getopt and
+ * call add_config_override_opt for any -o options.
+ *
+ * @param argc: (in/out) command-line length
+ * @param argv: (in/out) command-line strings
+ * @returns: newly allocated config_overrides object
+ */
+config_overrides_t *
+extract_commandline_config_overrides(int *argc,
+                                     char ***argv);
+
+/* Set configuration overwrites to the current configuration and take
+ * ownership of the config_overrides object.
+ *
+ * @param co: the config_overrides object
+ */
+void set_config_overrides(config_overrides_t *co);
+
+/*
+ * Initialization
+ */
+
+/* Constants for config_init */
+typedef enum {
+    /* Use arg_config_name, if not NULL */
+    CONFIG_INIT_EXPLICIT_NAME = 1 << 0,
+
+    /* Use the current working directory if an explicit name is not available */
+    CONFIG_INIT_USE_CWD = 1 << 1,
+
+    /* This is a client application (server is default) */
+    CONFIG_INIT_CLIENT = 1 << 2,
+
+    /* New configuration should "overlay" existing configuration; this
+     * is used by clients to load multiple amanda-client.conf files. */
+    CONFIG_INIT_OVERLAY = 1 << 3,
+} config_init_flags;
+
+/* Initialize this application's configuration, with the specific actions
+ * based on 'flags':
+ *  - if CONFIG_INIT_OVERLAY is not set, configuration values are reset
+ *    to their defaults
+ *  - if CONFIG_INIT_EXPLICIT_NAME and arg_config_name is not NULL,
+ *    use CONFIG_DIR/arg_config_name as config_dir arg_config_name as 
+ *    config_name.
+ *  - otherwise, if CONFIG_USE_CWD is set, use the directory in which 
+ *    the application was started as config_dir, and its filename as 
+ *    config_name.
+ *  - otherwise, for the client only, se config_dir to CONFIG_DIR and
+ *    config_name to NULL.
+ *  - depending on CONFIG_INIT_CLIENT, read amanda.conf or amanda-client.conf
+ *
+ * @param flags: flags indicating desired behavior, as above
+ * @param arg_config_name: config name to use (from e.g., argv[1])
+ * @returns: current error level
+ */
+cfgerr_level_t config_init(
+        config_init_flags flags,
+        char *arg_config_name);
 
-int  add_client_conf(confparm_t parm, char *value);
-int read_clientconf(char *filename);
+/* Free all memory allocated for the configuration.  This effectively
+ * reverses the effects of config_init().
+ */
+void config_uninit(void);
+
+/* Encode any applied config_overrides into a strv format suitale for
+ * executing another Amanda tool.
+ *
+ * The * result is dynamically allocated and NULL terminated.  There is no
+ * provision to free the result, as this function is always called just
+ * before execve(..).
+ *
+ * First gives the number of array elements to leave for the caller to
+ * fill in.  The usual calling pattern is this:
+ *   command_line = get_config_options(3);
+ *   command_line[0] = "appname";
+ *   command_line[1] = config_name;
+ *   command_line[2] = "--foo";
+ *   execve(command_line[0], command_line, safe_env());
+ *
+ * @param first: number of unused elements to leave at the beginning of
+ * the array.
+ * @returns: NULL-terminated string array suitable for execve
+ */
+char **get_config_options(int first);
+
+/* Get the config name */
+char *get_config_name(void);
+
+/* Get the config directory */
+char *get_config_dir(void);
+
+/* Get the config filename */
+char *get_config_filename(void);
+
+/*
+ * Utilities
+ */
+
+/* Security plugins get their configuration information through a callback
+ * with the signature:
+ *   char *callback(char *key, void *userpointer);
+ * where key is the name of the desired parameter, which may not match the
+ * name used in this module.  See the implementations of these functions
+ * to learn which keys they support, or to add new keys.
+ */
 char *generic_client_get_security_conf(char *, void *);
+char *generic_get_security_conf(char *, void *);
 
-int getconf_seen(confparm_t parameter);
-int getconf_boolean(confparm_t parameter);
-int getconf_int(confparm_t parameter);
-long getconf_long(confparm_t parameter);
-ssize_t getconf_size(confparm_t parameter);
-time_t getconf_time(confparm_t parameter);
-off_t getconf_am64(confparm_t parameter);
-double getconf_real(confparm_t parameter);
-char *getconf_str(confparm_t parameter);
-int getconf_taperalgo(confparm_t parameter);
-int *getconf_intrange(confparm_t parameter);
-char *getconf_byname(char *confname);
-char *getconf_list(char *listname);
-dumptype_t *lookup_dumptype(char *identifier);
+/* Dump the current configuration information to stdout, in a format 
+ * that can be re-read by this module.  The results will include any
+ * command-line overwrites.
+ *
+ * This function only dumps the server configuration, and will fail on
+ * clients.
+ */
+void dump_configuration(void);
+
+/* Return a sequence of strings giving the printable representation
+ * of the given val_t.  If str_needs_quotes is true and each string is
+ * prefixed by the relevant configuration keyword, these strings will
+ * be parseable by this module, and will reproduce exactly the same
+ * configuration value.  See the implementation of dump_configuration
+ * for details.
+ *
+ * If str_needs_quotes is provided, a CONFTYPE_STR value will be returned with 
+ * quotes.
+ *
+ * The result is a NULL-terminated strv, which can be freed with g_strfreev or
+ * joined with g_strjoinv.  Caller is responsible for freeing the memory.
+ *
+ * @param val: the value to analyze
+ * @param str_needs_quotes: add quotes to CONFTYPE_STR values?
+ * @returns: NULL-terminated string vector
+ */
+char **val_t_display_strs(val_t *val, int str_needs_quotes);
+
+/* Read a dumptype; this is used by this module as well as by diskfile.c to
+ * read the disklist.  The two are carefully balanced in their parsing process.
+ *
+ * Nobody else should use this function.  Seriously.
+ */
 dumptype_t *read_dumptype(char *name, FILE *from, char *fname, int *linenum);
-tapetype_t *lookup_tapetype(char *identifier);
-holdingdisk_t *lookup_holdingdisk(char *identifier);
-interface_t *lookup_interface(char *identifier);
-holdingdisk_t *getconf_holdingdisks(void);
-long int getconf_unit_divisor(void);
-void dump_configuration(char *filename);
-int ColumnDataCount(void);
-int StringToColumn(char *s);
-char LastChar(char *s);
-int SetColumDataFromString(ColumnInfo* ci, char *s, char **errstr);
-ssize_t getconf_readblocksize(void);
-
-/* this is in securityconf.h */
-char *generic_get_security_conf(char *, void *);
+
+/* Every call return a pointer to a string with an increasing number; this is
+ * used by this module as well as by diskfile.c to read the disklist.
+ *
+ * Nobody else should use this function.  Seriously.
+ *
+ * @returns: a pointer to a static string.
+ */
+char *anonymous_value(void);
+
+/* Extend a relative filename with the current config_dir; if filename is already
+ * absolute, this is equivalent to stralloc.
+ *
+ * @param filename: filename to extend
+ * @returns: newly allocated filename
+ */
+char *config_dir_relative(char *filename);
+
+/* Convert from a symbol back to a name for logging and for dumping
+ * config values
+ *
+ * @param taperalgo: the constant value
+ * @returns: statically allocated string
+ */
+char *taperalgo2str(taperalgo_t taperalgo);
+
+/* Looks for a unit value like b, byte, bytes, bps, etc. Technically
+ * the return value should never be < 1, but we return a signed value
+ * to help mitigate bad C promotion semantics. Returns 0 on error.
+ *
+ * This is here in this module because it uses the numb_keytable.
+ *
+ * @param casestr: the unit string
+ * @returns: the corresponding multiplier (e.g., 'M' => 1024*1024)
+ */
+gint64 find_multiplier(char * casestr);
+
+/* Converts a string matching any of Amanda's names for "true" or
+ * "false" to a boolean value.
+ *
+ * @param str: string to match
+ * @returns: 0 or 1 (boolean) or -1 (no match)
+ */
+int string_to_boolean(const char *str);
+
+/* Return a pointer to a static string for the data_path */
+char *data_path_to_string(data_path_t data_path);
+
+/* Return the data_path for the string */
+data_path_t data_path_from_string(char *data);
+
+void free_property_t(gpointer p);
+
+/* Converts a string into Amanda property name style.
+ *
+ * @param name: The name to convert.
+ * @returns: A newly allocated string, with name in lowercase and
+ * any instances of '_' replaced with '-'.
+ */
+gchar *amandaify_property_name(const gchar *name);
+
 #endif /* ! CONFFILE_H */