+/* 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 *lookup_changer_config(char *identifier);
+
+/* A interacrtivity interface */
+typedef enum interactivity_e {
+ INTERACTIVITY_COMMENT,
+ INTERACTIVITY_PLUGIN,
+ INTERACTIVITY_PROPERTY,
+ INTERACTIVITY_INTERACTIVITY
+} interactivity_key;
+
+/* opaque object */
+typedef struct interactivity_s interactivity_t;
+
+/* Given the name of the interactivity, return a interactivity object.
+ * Returns NULL if no matching interactivity exists.
+ * Note that the match is case-insensitive.
+ *
+ * @param identifier: name of the desired interactivity
+ * @returns: object or NULL
+ */
+
+interactivity_t *lookup_interactivity(char *identifier);
+
+/* Given a interactivity and a key, return a pointer to the corresponding val_t.
+ *
+ * @param ttyp: the interactivity to examine
+ * @param key: interactivity (one of the INTERACTIVITY_* constants)
+ * @returns: pointer to value
+ */
+val_t *interactivity_getconf(interactivity_t *app, interactivity_key key);
+
+/* Get the name of this interactivity.
+ *
+ * @param ttyp: the interactivity to examine
+ * @returns: name of the interactivity
+ */
+char *interactivity_name(interactivity_t *app);
+
+/* (convenience macro) has this parameter been seen in this interactivity?
+ * This applies to the specific parameter *within* the interactivity.
+ *
+ * @param key: interactivity_key
+ * @returns: boolean
+ */
+#define interactivity_seen(app, key) (val_t_seen(interactivity_getconf((app), (key))))
+
+/* (convenience macros)
+ * fetch a particular parameter; caller must know the correct type.
+ *
+ * @param ttyp: the interactivity to examine
+ * @returns: various
+ */
+#define interactivity_get_comment(interactivity) (val_t_to_str(interactivity_getconf((interactivity), INTERACTIVITY_COMMENT))
+#define interactivity_get_plugin(interactivity) (val_t_to_str(interactivity_getconf((interactivity), INTERACTIVITY_PLUGIN)))
+#define interactivity_get_property(interactivity) (val_t_to_proplist(interactivity_getconf((interactivity), INTERACTIVITY_PROPERTY)))
+
+/* A taperscan interface */
+typedef enum taperscan_e {
+ TAPERSCAN_COMMENT,
+ TAPERSCAN_PLUGIN,
+ TAPERSCAN_PROPERTY,
+ TAPERSCAN_TAPERSCAN
+} taperscan_key;
+
+/* opaque object */
+typedef struct taperscan_s taperscan_t;
+
+/* Given the name of the taperscan, return a taperscan object.
+ * Returns NULL if no matching taperscan exists.
+ * Note that the match is case-insensitive.
+ *
+ * @param identifier: name of the desired taperscan
+ * @returns: object or NULL
+ */
+
+taperscan_t *lookup_taperscan(char *identifier);
+
+/* Given a taperscan and a key, return a pointer to the corresponding val_t.
+ *
+ * @param ttyp: the taperscan to examine
+ * @param key: taperscan (one of the TAPERSCAN_* constants)
+ * @returns: pointer to value
+ */
+val_t *taperscan_getconf(taperscan_t *app, taperscan_key key);
+
+/* Get the name of this taperscan.
+ *
+ * @param ttyp: the taperscan to examine
+ * @returns: name of the taperscan
+ */
+char *taperscan_name(taperscan_t *app);
+
+/* (convenience macro) has this parameter been seen in this taperscan?
+ * This applies to the specific parameter *within* the taperscan.
+ *
+ * @param key: taperscan_key
+ * @returns: boolean
+ */
+#define taperscan_seen(app, key) (val_t_seen(taperscan_getconf((app), (key))))
+
+/* (convenience macros)
+ * fetch a particular parameter; caller must know the correct type.
+ *
+ * @param ttyp: the taperscan to examine
+ * @returns: various
+ */
+#define taperscan_get_comment(taperscan) (val_t_to_str(taperscan_getconf((taperscan), TAPERSCAN_COMMENT))
+#define taperscan_get_plugin(taperscan) (val_t_to_str(taperscan_getconf((taperscan), TAPERSCAN_PLUGIN)))
+#define taperscan_get_property(taperscan) (val_t_to_proplist(taperscan_getconf((taperscan), TAPERSCAN_PROPERTY)))
+
+
+/*
+ * Error Handling
+ */
+
+typedef enum {
+ /* No errors or warnings */
+ CFGERR_OK = 0,
+
+ /* warnings were encountered */
+ CFGERR_WARNINGS = 1,
+
+ /* errors (and maybe some warnings too, who knows) were encountered */
+ CFGERR_ERRORS = 2,
+} cfgerr_level_t;
+
+/*
+ * 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);
+
+/* 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);
+
+/* 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.
+ */