/*
Configuration file handling on top of tini
Copyright (C) Amitay Isaacs 2017
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, see .
*/
#ifndef __CTDB_CONF_H__
#define __CTDB_CONF_H__
#include
#include
#include
/**
* @file conf.h
*
* @brief Configuration file handling with sections and key-value pairs
*
* CTDB settings can be written in a configuration file ctdb.conf (similar to
* samba's smb.conf). Various daemons and tools will consult the configuration
* file for runtime settings.
*
* The configuration will be organized in sections depending on various
* components. Each section will have various configuration options in the form
* of key-value pairs.
*
* [section1]
* key1 = value1
* ...
*
* [section2]
* key2 = value2
* ...
*
* ...
*
*/
/**
* @brief Abstract data structure holding the configuration options
*/
struct conf_context;
/**
* @brief configuration option update mode
*
* When a value of configuration option is changed, update mode is set
* appropriately.
*
* CONF_MODE_API - value modified using set functions
* CONF_MODE_LOAD - value modified via conf_load
* CONF_MODE_RELOAD - value modified via conf_reload
*/
enum conf_update_mode {
CONF_MODE_API,
CONF_MODE_LOAD,
CONF_MODE_RELOAD,
};
/**
* @brief configuration option type
*/
enum conf_type {
CONF_STRING,
CONF_INTEGER,
CONF_BOOLEAN,
};
/**
* @brief Configuration section validation function
*
* Check if all the configuration options are consistent with each-other
*/
typedef bool (*conf_validate_section_fn)(struct conf_context *conf,
const char *section,
enum conf_update_mode mode);
/**
* @brief Configuration option validation function for string
*
* Check if a configuration option value is valid
*/
typedef bool (*conf_validate_string_option_fn)(const char *key,
const char *old_value,
const char *new_value,
enum conf_update_mode mode);
/**
* @brief Configuration option validation function for integer
*
* Check if a configuration option value is valid
*/
typedef bool (*conf_validate_integer_option_fn)(const char *key,
int old_value,
int new_value,
enum conf_update_mode mode);
/**
* @brief Configuration option validation function for boolean
*
* Check if a configuration option value is valid
*/
typedef bool (*conf_validate_boolean_option_fn)(const char *key,
bool old_value,
bool new_value,
enum conf_update_mode mode);
/**
* @brief Initialize configuration option database
*
* This return a new configuration options context. Freeing this context will
* free up all the memory associated with the configuration options.
*
* @param[in] mem_ctx Talloc memory context
* @param[in] result The new configuration options context
* @return 0 on success, errno on failure
*/
int conf_init(TALLOC_CTX *mem_ctx, struct conf_context **result);
/**
* @brief Define a section for organizing configuration options
*
* This functions creates a section to organize configuration option. The
* section names are case-insensitive and are always stored in lower case.
*
* @param[in] conf The configuration options context
* @param[in] section The name of the section
* @param[in] validate The validation function for configuration options
*/
void conf_define_section(struct conf_context *conf,
const char *section,
conf_validate_section_fn validate);
/**
* @brief Define a configuration option which has a string value
*
* This functions adds a new configuration option organized under a given
* section. Configuration options are case-insensitive and are always stored
* in lower case.
*
* @param[in] conf The configuration options context
* @param[in] section The name of the section
* @param[in] key The name of the configuration option
* @param[in] default_value The default value for the configuration option
* @param[in] validate The validation function for the configuration option
*/
void conf_define_string(struct conf_context *conf,
const char *section,
const char *key,
const char *default_value,
conf_validate_string_option_fn validate);
/**
* @brief Define a configuration option which has an integer value
*
* This functions adds a new configuration option organized under a given
* section. Configuration options are case-insensitive and are always stored
* in lower case.
*
* @param[in] conf The configuration options context
* @param[in] section The name of the section
* @param[in] key The name of the configuration option
* @param[in] default_value The default value for the configuration option
* @param[in] validate The validation function for the configuration option
*/
void conf_define_integer(struct conf_context *conf,
const char *section,
const char *key,
const int default_value,
conf_validate_integer_option_fn validate);
/**
* @brief Define a configuration option which has an boolean value
*
* This functions adds a new configuration option organized under a given
* section. Configuration options are case-insensitive and are always stored
* in lower case.
*
* @param[in] conf The configuration options context
* @param[in] section The name of the section
* @param[in] key The name of the configuration option
* @param[in] default_value The default value for the configuration option
* @param[in] validate The validation function for the configuration option
*/
void conf_define_boolean(struct conf_context *conf,
const char *section,
const char *key,
const bool default_value,
conf_validate_boolean_option_fn validate);
/**
* @brief Assign user-accessible pointer for string option
*
* This pointer can be used for accessing the value of configuration option
* directly without requiring a function call.
*
* @param[in] conf The configuration options context
* @param[in] section The name of the section
* @param[in] key The name of the configuration option
* @param[in] ptr User-accessible pointer to the value
*/
void conf_assign_string_pointer(struct conf_context *conf,
const char *section,
const char *key,
const char **ptr);
/**
* @brief Assign user-accessible pointer for integer option
*
* This pointer can be used for accessing the value of configuration option
* directly without requiring a function call.
*
* @param[in] conf The configuration options context
* @param[in] section The name of the section
* @param[in] key The name of the configuration option
* @param[in] ptr User-accessible pointer to the value
*/
void conf_assign_integer_pointer(struct conf_context *conf,
const char *section,
const char *key,
int *ptr);
/**
* @brief Assign user-accessible pointer for boolean option
*
* This pointer can be used for accessing the value of configuration option
* directly without requiring a function call.
*
* @param[in] conf The configuration options context
* @param[in] section The name of the section
* @param[in] key The name of the configuration option
* @param[in] ptr User-accessible pointer to the value
* @return true on success, false on failure
*/
void conf_assign_boolean_pointer(struct conf_context *conf,
const char *section,
const char *key,
bool *ptr);
/**
* @brief Query a configuration option
*
* This function checks if a configuration option is defined or not.
*
* @param[in] conf The configuration options context
* @param[in] section The name of the section
* @param[in] key The name of the configuration option
* @param[out] type The type of the configuration option
* @return true on success, false if section/option is not defined
*/
bool conf_query(struct conf_context *conf,
const char *section,
const char *key,
enum conf_type *type);
/**
* @brief Check if the defined configuration options are valid
*
* This function must be called after creating configuration options
* to confirm that all the option definitions are valid.
*
* @param[in] conf The configuration options context
* @return true on success, false on failure
*/
bool conf_valid(struct conf_context *conf);
/**
* @brief Set the default values for all configuration options
*
* This function resets all the configuration options to their default values.
*
* @param[in] conf The connfiguration options context
*/
void conf_set_defaults(struct conf_context *conf);
/**
* @brief Load the values for configuration option values from a file
*
* This function will update the values of the configuration options from those
* specified in a file. This function will fail in case it encounters an
* undefined option. Any sections which are not defined, will be ignored.
*
* This function will call validation function (if specified) before updating
* the value of a configuration option. After updating all the values for a
* section, the validation for section (if specified) will be called. If any
* of the validation functions return error, then all the configuration
* options will be reset to their previous values.
*
* @param[in] conf The configuration options context
* @param[in] filename The configuration file
* @param[in] skip_unknown Whether unknown config options should be ignored
* @return 0 on success, errno on failure
*/
int conf_load(struct conf_context *conf,
const char *filename,
bool ignore_unknown);
/**
* @brief Reload the values for configuration options
*
* This function will re-load the values of the configuration options. This
* function can be called only after successful call to conf_load().
*
* @see conf_load
*
* @param[in] conf The configuration options context
* @return 0 on success, errno on failure.
*/
int conf_reload(struct conf_context *conf);
/**
* @brief Set the string value of a configuration option
*
* This function can be used to update the value of a configuration option.
* This will call the validation function for that option (if defined) and
* the section validation function (if defined).
*
* If a user-defined storage pointer is provided, then the value of a
* configuration option should not be changed via that pointer.
*
* @param[in] conf The configuration options context
* @param[in] section The name of a section
* @param[in] key The name of a configuration option
* @param[in] str_val The string value
* @return 0 on success, errno in case of failure
*/
int conf_set_string(struct conf_context *conf,
const char *section,
const char *key,
const char *str_val);
/**
* @brief Set the integer value of a configuration option
*
* This function can be used to update the value of a configuration option.
* This will call the validation function for that option (if defined) and
* the section validation function (if defined).
*
* If a user-defined storage pointer is provided, then the value of a
* configuration option should not be changed via that pointer.
*
* @param[in] conf The configuration options context
* @param[in] section The name of a section
* @param[in] key The name of a configuration option
* @param[in] int_val The integer value
* @return 0 on success, errno in case of failure
*/
int conf_set_integer(struct conf_context *conf,
const char *section,
const char *key,
int int_val);
/**
* @brief Set the boolean value of a configuration option
*
* This function can be used to update the value of a configuration option.
* This will call the validation function for that option (if defined) and
* the section validation function (if defined).
*
* If a user-defined storage pointer is provided, then the value of a
* configuration option should not be changed via that pointer.
*
* @param[in] conf The configuration options context
* @param[in] section The name of a section
* @param[in] key The name of a configuration option
* @param[in] bool_val The boolean value
* @return 0 on success, errno in case of failure
*/
int conf_set_boolean(struct conf_context *conf,
const char *section,
const char *key,
bool bool_val);
/**
* @brief Get the string value of a configuration option
*
* This function can be used to fetch the current value of a configuration
* option.
*
* If a user-defined storage pointer is provided, then the value of a
* configuration option can be accessed directly via that pointer.
*
* @param[in] conf The configuration options context
* @param[in] section The name of a section
* @param[in] key The name of a configuration option
* @param[out] str_val The string value of the configuration option
* @param[out] is_default True if the value is default value
* @return 0 on success, errno in case of failure
*/
int conf_get_string(struct conf_context *conf,
const char *section,
const char *key,
const char **str_val,
bool *is_default);
/**
* @brief Get the integer value of a configuration option
*
* This function can be used to fetch the current value of a configuration
* option.
*
* If a user-defined storage pointer is provided, then the value of a
* configuration option can be accessed directly via that pointer.
*
* @param[in] conf The configuration options context
* @param[in] section The name of a section
* @param[in] key The name of a configuration option
* @param[out] int_val The integer value of the configuration option
* @param[out] is_default True if the value is default value
* @return 0 on success, errno in case of failure
*/
int conf_get_integer(struct conf_context *conf,
const char *section,
const char *key,
int *int_val,
bool *is_default);
/**
* @brief Get the boolean value of a configuration option
*
* This function can be used to fetch the current value of a configuration
* option.
*
* If a user-defined storage pointer is provided, then the value of a
* configuration option can be accessed directly via that pointer.
*
* @param[in] conf The configuration options context
* @param[in] section The name of a section
* @param[in] key The name of a configuration option
* @param[out] bool_val The boolean value of the configuration option
* @param[out] is_default True if the value is default value
* @return 0 on success, errno in case of failure
*/
int conf_get_boolean(struct conf_context *conf,
const char *section,
const char *key,
bool *bool_val,
bool *is_default);
/**
* @brief Dump the configuration in a file
*
* All the configuration options are dumped with their current values.
* If an option has a default value, then it is commented.
*
* Here is a sample output:
*
* [section1]
* key1 = value1
* key2 = value2
* # key3 = default_value3
* [section2]
* key4 = value4
*
* @param[in] conf The configuration options context
* @param[in] fp File pointer
*/
void conf_dump(struct conf_context *conf, FILE *fp);
#endif /* __CTDB_CONF_H__ */