+/* (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,