X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=common-src%2Fconffile.h;h=a61edd9d2f3c7c9ae5b53761bbc36a7146047bde;hb=2627875b7d18858bc1f9f7652811e4d8c15a23eb;hp=8873cec75292b3d659bae70148c72d098d6319c0;hpb=fb2bd066c2f8b34addafe48d62550e3033a59431;p=debian%2Famanda diff --git a/common-src/conffile.h b/common-src/conffile.h index 8873cec..a61edd9 100644 --- a/common-src/conffile.h +++ b/common-src/conffile.h @@ -38,12 +38,12 @@ /* Getting Configuration Values * ============================ * - * Amanda configurations consist of a number of "global" parameters, as well as named - * subsections of four types: dumptypes, interfaces, holdingdisks, and tapetypes. 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). + * 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 * ===== @@ -64,6 +64,12 @@ * ====== * 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. */ /* @@ -131,19 +137,55 @@ typedef enum { 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 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; +typedef GSList* pp_scriptlist_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_AM64, + CONFTYPE_INT64, CONFTYPE_REAL, CONFTYPE_STR, CONFTYPE_IDENT, @@ -160,16 +202,29 @@ typedef enum { CONFTYPE_RATE, CONFTYPE_INTRANGE, CONFTYPE_EXINCLUDE, - CONFTYPE_PROPLIST + CONFTYPE_PROPLIST, + CONFTYPE_APPLICATION, + CONFTYPE_EXECUTE_ON, + CONFTYPE_EXECUTE_WHERE, + CONFTYPE_SEND_AMREPORT_ON, + CONFTYPE_PP_SCRIPTLIST } 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; - off_t am64; + gint64 int64; double r; char *s; ssize_t size; @@ -178,40 +233,47 @@ typedef struct val_s { exinclude_t exinclude; int intrange[2]; proplist_t proplist; + struct application_s *application; + pp_scriptlist_t pp_scriptlist; } v; - int seen; + 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 *); -off_t val_t_to_am64 (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) */ -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 *); -estimate_t val_t_to_estimate (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 *); +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) */ +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 *); +estimate_t val_t_to_estimate (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 *); +struct application_s *val_t_to_application(val_t *); +pp_scriptlist_t val_t_to_pp_scriptlist(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 *); /* 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) +#define val_t_seen(val) ((val)->seen.linenum) /* What is the underlying type of this val_t? * @@ -227,26 +289,31 @@ proplist_t val_t_to_proplist (val_t *); * (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__am64(val) ((val)->v.am64) -#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__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__estimate(val) ((val)->v.i) -#define val_t__strategy(val) ((val)->v.i) -#define val_t__taperalgo(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__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__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__estimate(val) ((val)->v.i) +#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__pp_scriptlist(val) ((val)->v.pp_scriptlist) +#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) /* * Parameters * @@ -272,7 +339,15 @@ typedef enum { CNF_MAILTO, CNF_DUMPUSER, CNF_TAPEDEV, + CNF_RAWTAPEDEV, 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, @@ -301,6 +376,7 @@ typedef enum { CNF_TAPEBUFS, CNF_DEVICE_OUTPUT_BUFFER_SIZE, CNF_PRINTER, + CNF_MAILER, CNF_AUTOFLUSH, CNF_RESERVE, CNF_MAXDUMPSIZE, @@ -309,6 +385,7 @@ 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, @@ -366,7 +443,7 @@ val_t *getconf(confparm_key key); * @returns: various */ #define getconf_int(key) (val_t_to_int(getconf((key)))) -#define getconf_am64(key) (val_t_to_am64(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)))) @@ -384,6 +461,7 @@ val_t *getconf(confparm_key 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)))) /* Get a list of names for subsections of the given type * @@ -494,8 +572,8 @@ char *tapetype_name(tapetype_t *ttyp); #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_am64(tapetype_getconf((ttyp), TAPETYPE_LENGTH))) -#define tapetype_get_filemark(ttyp) (val_t_to_am64(tapetype_getconf((ttyp), TAPETYPE_FILEMARK))) +#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_file_pad(ttyp) (val_t_to_boolean(tapetype_getconf((ttyp), TAPETYPE_FILE_PAD))) @@ -542,6 +620,9 @@ typedef enum { DUMPTYPE_KENCRYPT, DUMPTYPE_IGNORE, DUMPTYPE_INDEX, + DUMPTYPE_APPLICATION, + DUMPTYPE_PP_SCRIPTLIST, + DUMPTYPE_PROPERTY, DUMPTYPE_DUMPTYPE /* sentinel */ } dumptype_key; @@ -604,7 +685,7 @@ char *dumptype_name(dumptype_t *dtyp); #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_am64(dumptype_getconf((dtyp), DUMPTYPE_BUMPSIZE))) +#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))) @@ -615,8 +696,8 @@ char *dumptype_name(dumptype_t *dtyp); #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_am64(dumptype_getconf((dtyp), DUMPTYPE_TAPE_SPLITSIZE))) -#define dumptype_get_fallback_splitsize(dtyp) (val_t_to_am64(dumptype_getconf((dtyp), DUMPTYPE_FALLBACK_SPLITSIZE))) +#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))) @@ -625,6 +706,9 @@ char *dumptype_name(dumptype_t *dtyp); #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_pp_scriptlist(dtyp) (val_t_to_pp_scriptlist(dumptype_getconf((dtyp), DUMPTYPE_PP_SCRIPTLIST))) +#define dumptype_get_property(dtyp) (val_t_to_proplist(dumptype_getconf((dtyp), DUMPTYPE_PROPERTY))) /* * Interface parameter access @@ -748,8 +832,290 @@ char *holdingdisk_name(holdingdisk_t *hdisk); */ #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_am64(holdingdisk_getconf((hdisk), HOLDING_DISKSIZE))) -#define holdingdisk_get_chunksize(hdisk) (val_t_to_am64(holdingdisk_getconf((hdisk), HOLDING_CHUNKSIZE))) +#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_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))) + +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_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), DEVICE_CONFIG_COMMENT))) +#define changer_config_get_tapedev(devconf) (val_t_to_str(changer_config_getconf((devconf), DEVICE_CONFIG_TAPEDEV))) +#define changer_config_get_tpchanger(devconf) (val_t_to_str(changer_config_getconf((devconf), DEVICE_CONFIG_TPCHANGER))) +#define changer_config_get_changerdev(devconf) (val_t_to_str(changer_config_getconf((devconf), DEVICE_CONFIG_CHANGERDEV))) +#define changer_config_get_changerfile(devconf) (val_t_to_str(changer_config_getconf((devconf), DEVICE_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, + + /* 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 @@ -809,15 +1175,13 @@ extract_commandline_config_overwrites(int *argc, char ***argv); /* Apply configuration overwrites to the current configuration and take - * ownership of the config_overwrites object. - * - * If any parameters are not matched in the current symbol table, or - * correspond to named subsections which do not exist, this function calls - * error() and does not return. + * ownership of the config_overwrites object. It is the caller's + * responsibility to handle any errors. * * @param co: the config_overwrites object + * @returns: current error level */ -void apply_config_overwrites(config_overwrites_t *co); +cfgerr_level_t apply_config_overwrites(config_overwrites_t *co); /* * Initialization @@ -837,9 +1201,6 @@ typedef enum { /* New configuration should "overlay" existing configuration; this * is used by clients to load multiple amanda-client.conf files. */ CONFIG_INIT_OVERLAY = 1 << 3, - - /* If the file doesn't exist, halt with an error. */ - CONFIG_INIT_FATAL = 1 << 4, } config_init_flags; /* Initialize this application's configuration, with the specific actions @@ -855,15 +1216,14 @@ typedef enum { * - 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 - * - in the event of an error, call error() if CONFIG_INIT_FATAL, otherwise - * record a message in the debug log and return false. * * @param flags: flags indicating desired behavior, as above * @param arg_config_name: config name to use (from e.g., argv[1]) - * @returns: true on success, false on failure, unless CONFIG_INIT_FATAL + * @returns: current error level */ -gboolean config_init(config_init_flags flags, - char *arg_config_name); +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(). @@ -891,21 +1251,14 @@ void config_uninit(void); */ char **get_config_options(int first); -/* The name of the configuration under which this application is running. - * This variable is initialized by config_init, and should be treated as - * read-only. - */ -extern char *config_name; +/* Get the config name */ +char *get_config_name(void); -/* The directory containing the configuration for this application. This - * variable is initialized by config_init, and should be treated as read-only. - */ -extern char *config_dir; +/* Get the config directory */ +char *get_config_dir(void); -/* The most recently read top-level configuration file. This variable is - * initialized by config_init, and should be treated as read-only. - */ -extern char *config_filename; +/* Get the config filename */ +char *get_config_filename(void); /* * Utilities @@ -956,6 +1309,15 @@ char **val_t_display_strs(val_t *val, int str_needs_quotes); */ dumptype_t *read_dumptype(char *name, FILE *from, char *fname, int *linenum); +/* 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. * @@ -983,4 +1345,18 @@ char *taperalgo2str(taperalgo_t taperalgo); */ gint64 find_multiplier(char * casestr); +/* Compute the size needed in an ARGV to pass all properties + * + * @param proplist: The property list + * @returns: The size required for an ARGV + */ +int property_argv_size(proplist_t proplist); + +/* Add all properties to an ARGV + * + * @param argvchild: Pointer to the ARGV. + * @param proplist: The property list + */ +int property_add_to_argv(char **argvchild, proplist_t proplist); + #endif /* ! CONFFILE_H */