Reorganise and rename new config code ready for integration

This commit is contained in:
Andrew Bettison 2012-11-29 14:33:32 +10:30
parent fdb3249522
commit 32debf57ef
3 changed files with 259 additions and 242 deletions

138
config.h
View File

@ -86,12 +86,12 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* Each STRUCT(NAME, ...) and ARRAY(NAME, ...) schema declaration generates the following API
* functions:
*
* - int dfl_config_NAME(struct config_NAME *dest);
* - int cf_dfl_config_NAME(struct config_NAME *dest);
*
* A C function which sets the entire contents of the given C structure to its default values
* as defined in the schema. This will only return CFOK or CFERROR; see below.
*
* - int opt_config_NAME(struct config_NAME *dest, const struct cf_om_node *node);
* - int cf_opt_config_NAME(struct config_NAME *dest, const struct cf_om_node *node);
*
* A C function which parses the given COM (configuration object model) and assigns the parsed
* result into the given C structure. See below for the return value. For arrays, this
@ -104,11 +104,11 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* - int VALIDATOR(struct config_NAME *dest, int orig_result);
*
* A C function which validates the contents of the given C structure (struct or array) as
* defined in the schema. This function is invoked by the opt_config_NAME() parser function
* defined in the schema. This function is invoked by the cf_opt_config_NAME() parser function
* just before it returns, so all the parse functions have already been called and the result
* is assembled. The validator function is passed a pointer to the (non-const) structure,
* which it may modify if desired, and the original CFxxx flags result code (not CFERROR) that
* would be returned by the opt_config_NAME() parser function. It returns a new CFxxx flags
* would be returned by the cf_opt_config_NAME() parser function. It returns a new CFxxx flags
* result (which may simply be the same as was passed).
*
* In the case arrays, validator() is passed a *dest containing elements that were successfully
@ -117,7 +117,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* (in which case the CFOVERFLOW flag is set). It is up to validator() to decide whether to
* return some, all or none of these elements (ie, alter dest->ac and/or dest->av), and whether
* to set or clear the CFARRAYOVERFLOW bit, or set other bits (like CFINVALID for example). If
* there is no validator function, then opt_config_NAME() will return an empty array (dest->ac
* there is no validator function, then cf_opt_config_NAME() will return an empty array (dest->ac
* == 0) in the case of CFARRAYOVERFLOW.
*
* All parse functions assign the result of their parsing into the struct given in their 'dest'
@ -133,7 +133,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* or no elements present in the COM).
*
* - CFUNSUPPORTED if the config item (array or struct) is not supported. This flag is not
* produced by the normal opt_config_NAME() parse functions, but a validation function could set
* produced by the normal cf_opt_config_NAME() parse functions, but a validation function could set
* it to indicate that a given option is not yet implemented or has been deprecated. In that
* case, the validation function should also log a message to that effect. The CFUNSUPPORTED
* flag is mainly used in its CFSUB(CFUNSUPPORTED) form (see below) to indicate that the COM
@ -170,7 +170,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* the whole struct or array itself may still be valid (in the case of a struct, the element's prior
* value may be retained, and in the case of an array, the failed element is simply omitted from the
* result). A validator function may wish to reflect any CFSUB() bit as a CFINVALID result, but the
* normal behaviour of opt_config_NAME() is to not return CFINVALID unless the validator function
* normal behaviour of cf_opt_config_NAME() is to not return CFINVALID unless the validator function
* sets it.
*
* The special value CFOK is zero (no bits set); in this case a valid result is produced and all of
@ -203,7 +203,57 @@ struct pattern_list {
};
#define PATTERN_LIST_EMPTY ((struct pattern_list){.patc = 0})
// Generate value structs, struct config_NAME.
/* The Configuration Object Model (COM). The config file is parsed into a tree of these structures
* first, then those structures are passed as arguments to the schema parsing functions.
*/
struct cf_om_node {
const char *source; // = parse_config() 'source' arg
unsigned int line_number;
const char *fullkey; // malloc()
const char *key; // points inside fullkey, do not free()
const char *text; // malloc()
size_t nodc;
struct cf_om_node *nodv[10]; // malloc()
};
struct cf_om_node *cf_parse_to_om(const char *source, const char *buf, size_t len);
void cf_free_node(struct cf_om_node *node);
void cf_dump_node(const struct cf_om_node *node, int indent);
void cf_warn_nodev(const char *file, unsigned line, const struct cf_om_node *node, const char *key, const char *fmt, va_list ap);
void cf_warn_childrenv(const char *file, unsigned line, const struct cf_om_node *parent, const char *fmt, va_list ap);
void cf_warn_node(const char *file, unsigned line, const struct cf_om_node *node, const char *key, const char *fmt, ...);
void cf_warn_children(const char *file, unsigned line, const struct cf_om_node *node, const char *fmt, ...);
void cf_warn_duplicate_node(const struct cf_om_node *parent, const char *key);
void cf_warn_missing_node(const struct cf_om_node *parent, const char *key);
void cf_warn_node_value(const struct cf_om_node *node, int reason);
void cf_warn_no_array(const struct cf_om_node *node, int reason);
void cf_warn_unsupported_node(const struct cf_om_node *node);
void cf_warn_unsupported_children(const struct cf_om_node *parent);
void cf_warn_list_overflow(const struct cf_om_node *node);
void cf_warn_spurious_children(const struct cf_om_node *parent);
void cf_warn_array_label(const struct cf_om_node *node, int reason);
void cf_warn_array_value(const struct cf_om_node *node, int reason);
/* Return bit flags for schema default cf_dfl_ and parsing cf_opt_ functions. */
#define CFERROR (~0) // all set
#define CFOK 0
#define CFEMPTY (1<<0)
#define CFARRAYOVERFLOW (1<<1)
#define CFSTRINGOVERFLOW (1<<2)
#define CFINCOMPLETE (1<<3)
#define CFINVALID (1<<4)
#define CFUNSUPPORTED (1<<5)
#define CF__SUB_SHIFT 16
#define CFSUB(f) ((f) << CF__SUB_SHIFT)
#define CF__SUBFLAGS CFSUB(~0)
#define CF__FLAGS (~0 & ~CF__SUBFLAGS)
strbuf strbuf_cf_flags(strbuf, int);
// Generate config struct definitions, struct config_NAME.
#define STRUCT(__name, __validator...) \
struct config_##__name {
#define NODE(__type, __element, __default, __parser, __flags, __comment) \
@ -257,27 +307,9 @@ struct pattern_list {
#undef VALUE_NODE_STRUCT
#undef END_ARRAY
/* Return bit flags for schema default dfl_ and parsing opt_ functions. */
#define CFERROR (~0) // all set
#define CFOK 0
#define CFEMPTY (1<<0)
#define CFARRAYOVERFLOW (1<<1)
#define CFSTRINGOVERFLOW (1<<2)
#define CFINCOMPLETE (1<<3)
#define CFINVALID (1<<4)
#define CFUNSUPPORTED (1<<5)
#define CF__SUB_SHIFT 16
#define CFSUB(f) ((f) << CF__SUB_SHIFT)
#define CF__SUBFLAGS CFSUB(~0)
#define CF__FLAGS (~0 & ~CF__SUBFLAGS)
strbuf strbuf_cf_flags(strbuf, int);
// Generate default functions, dfl_config_NAME().
// Generate config set-default functions, cf_dfl_config_NAME().
#define STRUCT(__name, __validator...) \
int dfl_config_##__name(struct config_##__name *s) {
int cf_dfl_config_##__name(struct config_##__name *s) {
#define NODE(__type, __element, __default, __parser, __flags, __comment) \
s->__element = (__default);
#define ATOM(__type, __element, __default, __parser, __flags, __comment) \
@ -285,14 +317,14 @@ strbuf strbuf_cf_flags(strbuf, int);
#define STRING(__size, __element, __default, __parser, __flags, __comment) \
strncpy(s->__element, (__default), (__size))[(__size)] = '\0';
#define SUB_STRUCT(__name, __element, __flags) \
dfl_config_##__name(&s->__element);
cf_dfl_config_##__name(&s->__element);
#define NODE_STRUCT(__name, __element, __parser, __flags) \
dfl_config_##__name(&s->__element);
cf_dfl_config_##__name(&s->__element);
#define END_STRUCT \
return CFOK; \
}
#define ARRAY(__name, __validator...) \
int dfl_config_##__name(struct config_##__name *a) { \
int cf_dfl_config_##__name(struct config_##__name *a) { \
a->ac = 0; \
return CFOK; \
}
@ -322,26 +354,12 @@ strbuf strbuf_cf_flags(strbuf, int);
#undef VALUE_NODE_STRUCT
#undef END_ARRAY
/* The Configuration Object Model (COM). The config file is parsed into a tree of these structures
* first, then those structures are passed as arguments to the schema parsing functions.
*/
struct cf_om_node {
const char *source; // = parse_config() 'source' arg
unsigned int line_number;
const char *fullkey; // malloc()
const char *key; // points inside fullkey, do not free()
const char *text; // malloc()
size_t nodc;
struct cf_om_node *nodv[10]; // malloc()
};
// Generate parser function prototypes.
// Generate config parser function prototypes.
#define __VALIDATOR(__name, __validator...) \
typedef int __validator_func__config_##__name##__t(const struct cf_om_node *, struct config_##__name *, int); \
__validator_func__config_##__name##__t __dummy__validator_func__config_##__name, ##__validator;
#define STRUCT(__name, __validator...) \
int opt_config_##__name(struct config_##__name *, const struct cf_om_node *); \
int cf_opt_config_##__name(struct config_##__name *, const struct cf_om_node *); \
__VALIDATOR(__name, ##__validator)
#define NODE(__type, __element, __default, __parser, __flags, __comment) \
int __parser(__type *, const struct cf_om_node *);
@ -350,12 +368,12 @@ struct cf_om_node {
#define STRING(__size, __element, __default, __parser, __flags, __comment) \
int __parser(char *, size_t, const char *);
#define SUB_STRUCT(__name, __element, __flags) \
int opt_config_##__name(struct config_##__name *, const struct cf_om_node *);
int cf_opt_config_##__name(struct config_##__name *, const struct cf_om_node *);
#define NODE_STRUCT(__name, __element, __parser, __flags) \
int __parser(struct config_##__name *, const struct cf_om_node *);
#define END_STRUCT
#define ARRAY(__name, __validator...) \
int opt_config_##__name(struct config_##__name *, const struct cf_om_node *); \
int cf_opt_config_##__name(struct config_##__name *, const struct cf_om_node *); \
__VALIDATOR(__name, ##__validator)
#define KEY_ATOM(__type, __eltparser, __cmpfunc...) \
int __eltparser(__type *, const char *);
@ -368,7 +386,7 @@ struct cf_om_node {
#define VALUE_NODE(__type, __eltparser) \
int __eltparser(__type *, const struct cf_om_node *);
#define VALUE_SUB_STRUCT(__structname) \
int opt_config_##__structname(struct config_##__structname *, const struct cf_om_node *);
int cf_opt_config_##__structname(struct config_##__structname *, const struct cf_om_node *);
#define VALUE_NODE_STRUCT(__structname, __eltparser) \
int __eltparser(struct config_##__structname *, const struct cf_om_node *);
#define END_ARRAY(__size)
@ -391,7 +409,7 @@ struct cf_om_node {
#undef VALUE_NODE_STRUCT
#undef END_ARRAY
// Generate array key comparison function prototypes.
// Generate config array key comparison function prototypes.
#define STRUCT(__name, __validator...)
#define NODE(__type, __element, __default, __parser, __flags, __comment)
#define ATOM(__type, __element, __default, __parser, __flags, __comment)
@ -439,4 +457,22 @@ struct cf_om_node {
#undef VALUE_NODE_STRUCT
#undef END_ARRAY
int cf_opt_boolean(int *booleanp, const char *text);
int cf_opt_absolute_path(char *str, size_t len, const char *text);
int cf_opt_debugflags(debugflags_t *flagsp, const struct cf_om_node *node);
int cf_opt_rhizome_peer(struct config_rhizomepeer *, const struct cf_om_node *node);
int cf_opt_str(char *str, size_t len, const char *text);
int cf_opt_str_nonempty(char *str, size_t len, const char *text);
int cf_opt_int(int *intp, const char *text);
int cf_opt_uint32_nonzero(uint32_t *intp, const char *text);
int cf_opt_uint64_scaled(uint64_t *intp, const char *text);
int cf_opt_protocol(char *str, size_t len, const char *text);
int cf_opt_in_addr(struct in_addr *addrp, const char *text);
int cf_opt_port(unsigned short *portp, const char *text);
int cf_opt_sid(sid_t *sidp, const char *text);
int cf_opt_rhizome_bk(rhizome_bk_t *bkp, const char *text);
int cf_opt_interface_type(short *typep, const char *text);
int cf_opt_pattern_list(struct pattern_list *listp, const char *text);
int cf_opt_interface_list(struct config_interface_list *listp, const struct cf_om_node *node);
#endif //__SERVALDNA_CONFIG_H

View File

@ -46,12 +46,12 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* the following schema would do:
*
* STRUCT(happy)
* ATOM(int32_t, element1, 0, opt_int32_nonnegative,, "An integer >= 0")
* STRING(80, element2, "boo!", opt_str_nonempty, MANDATORY, "A non-empty string")
* ATOM(int32_t, element1, 0, cf_opt_int32_nonnegative,, "An integer >= 0")
* STRING(80, element2, "boo!", cf_opt_str_nonempty, MANDATORY, "A non-empty string")
* END_STRUCT
*
* ARRAY(joy)
* KEY_STRING(3, happy, opt_str)
* KEY_STRING(3, happy, cf_opt_str)
* VALUE_SUB_STRUCT(happy)
* END_ARRAY(16)
*
@ -62,7 +62,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* STRUCT(main)
* SUB_STRUCT(love, some,)
* STRING(128, another_thing, "", opt_uri,, "URL; protocol://hostname[:port][/path]")
* STRING(128, another_thing, "", cf_opt_uri,, "URL; protocol://hostname[:port][/path]")
* END_STRUCT
*
* which would produce an API based on the following definitions (see "config.h" for more
@ -179,50 +179,50 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
STRUCT(log)
STRING(256, file, "", opt_absolute_path,, "Absolute path of log file")
ATOM(int, show_pid, 1, opt_boolean,, "If true, all log lines contain PID of logging process")
ATOM(int, show_time, 1, opt_boolean,, "If true, all log lines contain time stamp")
STRING(256, file, "", cf_opt_absolute_path,, "Absolute path of log file")
ATOM(int, show_pid, 1, cf_opt_boolean,, "If true, all log lines contain PID of logging process")
ATOM(int, show_time, 1, cf_opt_boolean,, "If true, all log lines contain time stamp")
END_STRUCT
STRUCT(server)
STRING(256, chdir, "/", opt_absolute_path,, "Absolute path of chdir(2) for server process")
STRING(256, dummy_interface_dir, "", opt_str_nonempty,, "Path of directory containing dummy interface files, either absolute or relative to instance directory")
ATOM(int, respawn_on_crash, 0, opt_boolean,, "If true, server will exec(2) itself on fatal signals, eg SEGV")
STRING(256, chdir, "/", cf_opt_absolute_path,, "Absolute path of chdir(2) for server process")
STRING(256, dummy_interface_dir, "", cf_opt_str_nonempty,, "Path of directory containing dummy interface files, either absolute or relative to instance directory")
ATOM(int, respawn_on_crash, 0, cf_opt_boolean,, "If true, server will exec(2) itself on fatal signals, eg SEGV")
END_STRUCT
STRUCT(monitor)
STRING(256, socket, DEFAULT_MONITOR_SOCKET_NAME, opt_str_nonempty,, "Name of socket for monitor interface")
ATOM(int, uid, -1, opt_int,, "Allowed UID for monitor socket client")
STRING(256, socket, DEFAULT_MONITOR_SOCKET_NAME, cf_opt_str_nonempty,, "Name of socket for monitor interface")
ATOM(int, uid, -1, cf_opt_int,, "Allowed UID for monitor socket client")
END_STRUCT
STRUCT(mdp_iftype)
ATOM(uint32_t, tick_ms, 0, opt_uint32_nonzero,, "Tick interval for this interface type")
ATOM(uint32_t, tick_ms, 0, cf_opt_uint32_nonzero,, "Tick interval for this interface type")
END_STRUCT
ARRAY(mdp_iftypelist)
KEY_ATOM(short, opt_interface_type, cmp_short)
KEY_ATOM(short, cf_opt_interface_type, cmp_short)
VALUE_SUB_STRUCT(mdp_iftype)
END_ARRAY(5)
STRUCT(mdp)
STRING(256, socket, DEFAULT_MDP_SOCKET_NAME, opt_str_nonempty,, "Name of socket for MDP client interface")
ATOM(uint32_t, ticks_per_full_address, 4, opt_uint32_nonzero,, "Ticks to elapse between announcing full SID")
STRING(256, socket, DEFAULT_MDP_SOCKET_NAME, cf_opt_str_nonempty,, "Name of socket for MDP client interface")
ATOM(uint32_t, ticks_per_full_address, 4, cf_opt_uint32_nonzero,, "Ticks to elapse between announcing full SID")
SUB_STRUCT(mdp_iftypelist, iftype,)
END_STRUCT
STRUCT(olsr)
ATOM(int, enable, 1, opt_boolean,, "If true, OLSR is used for mesh routing")
ATOM(uint16_t, remote_port,4130, opt_port,, "Remote port number")
ATOM(uint16_t, local_port, 4131, opt_port,, "Local port number")
ATOM(int, enable, 1, cf_opt_boolean,, "If true, OLSR is used for mesh routing")
ATOM(uint16_t, remote_port,4130, cf_opt_port,, "Remote port number")
ATOM(uint16_t, local_port, 4131, cf_opt_port,, "Local port number")
END_STRUCT
ARRAY(argv, vld_argv)
KEY_ATOM(unsigned short, opt_ushort_nonzero, cmp_ushort)
VALUE_STRING(128, opt_str)
KEY_ATOM(unsigned short, cf_opt_ushort_nonzero, cmp_ushort)
VALUE_STRING(128, cf_opt_str)
END_ARRAY(16)
STRUCT(executable)
STRING(256, executable, "", opt_absolute_path, MANDATORY, "Absolute path of dna helper executable")
STRING(256, executable, "", cf_opt_absolute_path, MANDATORY, "Absolute path of dna helper executable")
SUB_STRUCT(argv, argv,)
END_STRUCT
@ -231,14 +231,14 @@ SUB_STRUCT(executable, helper,)
END_STRUCT
STRUCT(rhizomepeer)
STRING(25, protocol, "http", opt_protocol,, "Protocol name")
STRING(256, host, "", opt_str_nonempty, MANDATORY, "Host name or IP address")
ATOM(uint16_t, port, RHIZOME_HTTP_PORT, opt_port,, "Port number")
STRING(25, protocol, "http", cf_opt_protocol,, "Protocol name")
STRING(256, host, "", cf_opt_str_nonempty, MANDATORY, "Host name or IP address")
ATOM(uint16_t, port, RHIZOME_HTTP_PORT, cf_opt_port,, "Port number")
END_STRUCT
ARRAY(peerlist)
KEY_STRING(15, opt_str)
VALUE_NODE(struct config_rhizomepeer, opt_rhizome_peer)
KEY_STRING(15, cf_opt_str)
VALUE_NODE(struct config_rhizomepeer, cf_opt_rhizome_peer)
END_ARRAY(10)
STRUCT(rhizome_direct)
@ -246,11 +246,11 @@ SUB_STRUCT(peerlist, peer,)
END_STRUCT
STRUCT(rhizome_api_addfile)
STRING(64, uri_path, "", opt_absolute_path,, "URI path for HTTP add-file request")
ATOM(struct in_addr, allow_host, (struct in_addr){htonl(INADDR_LOOPBACK)}, opt_in_addr,, "IP address of host allowed to make HTTP add-file request")
STRING(256, manifest_template_file, "", opt_str_nonempty,, "Path of manifest template file, either absolute or relative to instance directory")
ATOM(sid_t, default_author, SID_NONE, opt_sid,, "Author of add-file bundle if sender not given")
ATOM(rhizome_bk_t, bundle_secret_key, RHIZOME_BK_NONE, opt_rhizome_bk,, "Secret key of add-file bundle to try if sender not given")
STRING(64, uri_path, "", cf_opt_absolute_path,, "URI path for HTTP add-file request")
ATOM(struct in_addr, allow_host, (struct in_addr){htonl(INADDR_LOOPBACK)}, cf_opt_in_addr,, "IP address of host allowed to make HTTP add-file request")
STRING(256, manifest_template_file, "", cf_opt_str_nonempty,, "Path of manifest template file, either absolute or relative to instance directory")
ATOM(sid_t, default_author, SID_NONE, cf_opt_sid,, "Author of add-file bundle if sender not given")
ATOM(rhizome_bk_t, bundle_secret_key, RHIZOME_BK_NONE, cf_opt_rhizome_bk,, "Secret key of add-file bundle to try if sender not given")
END_STRUCT
STRUCT(rhizome_api)
@ -258,52 +258,52 @@ SUB_STRUCT(rhizome_api_addfile, addfile,)
END_STRUCT
STRUCT(rhizome)
ATOM(int, enable, 1, opt_boolean,, "If true, Rhizome HTTP server is started")
STRING(256, datastore_path, "", opt_absolute_path,, "Absolute path of rhizome storage directory")
ATOM(uint64_t, database_size, 1000000, opt_uint64_scaled,, "Size of database in bytes")
ATOM(uint32_t, fetch_delay_ms, 50, opt_uint32_nonzero,, "Delay from receiving first bundle advert to initiating fetch")
ATOM(int, enable, 1, cf_opt_boolean,, "If true, Rhizome HTTP server is started")
STRING(256, datastore_path, "", cf_opt_absolute_path,, "Absolute path of rhizome storage directory")
ATOM(uint64_t, database_size, 1000000, cf_opt_uint64_scaled,, "Size of database in bytes")
ATOM(uint32_t, fetch_delay_ms, 50, cf_opt_uint32_nonzero,, "Delay from receiving first bundle advert to initiating fetch")
SUB_STRUCT(rhizome_direct, direct,)
SUB_STRUCT(rhizome_api, api,)
END_STRUCT
STRUCT(directory)
ATOM(sid_t, service, SID_NONE, opt_sid,, "Subscriber ID of Serval Directory Service")
ATOM(sid_t, service, SID_NONE, cf_opt_sid,, "Subscriber ID of Serval Directory Service")
END_STRUCT
STRUCT(host)
STRING(INTERFACE_NAME_STRLEN, interface, "", opt_str_nonempty, MANDATORY, "Interface name")
ATOM(struct in_addr, address, (struct in_addr){htonl(INADDR_NONE)}, opt_in_addr, MANDATORY, "Host IP address")
ATOM(uint16_t, port, PORT_DNA, opt_port,, "Port number")
STRING(INTERFACE_NAME_STRLEN, interface, "", cf_opt_str_nonempty, MANDATORY, "Interface name")
ATOM(struct in_addr, address, (struct in_addr){htonl(INADDR_NONE)}, cf_opt_in_addr, MANDATORY, "Host IP address")
ATOM(uint16_t, port, PORT_DNA, cf_opt_port,, "Port number")
END_STRUCT
ARRAY(host_list)
KEY_ATOM(sid_t, opt_sid, cmp_sid)
KEY_ATOM(sid_t, cf_opt_sid, cmp_sid)
VALUE_SUB_STRUCT(host)
END_ARRAY(32)
STRUCT(network_interface)
ATOM(int, exclude, 0, opt_boolean,, "If true, do not use matching interfaces")
ATOM(struct pattern_list, match, PATTERN_LIST_EMPTY, opt_pattern_list, MANDATORY, "Names that match network interface")
ATOM(short, type, OVERLAY_INTERFACE_WIFI, opt_interface_type,, "Type of network interface")
ATOM(uint16_t, port, RHIZOME_HTTP_PORT, opt_port,, "Port number for network interface")
ATOM(uint64_t, speed, 1000000, opt_uint64_scaled,, "Speed in bits per second")
ATOM(uint32_t, mdp_tick_ms, 0, opt_uint32_nonzero,, "Override MDP tick interval for this interface")
ATOM(int, exclude, 0, cf_opt_boolean,, "If true, do not use matching interfaces")
ATOM(struct pattern_list, match, PATTERN_LIST_EMPTY, cf_opt_pattern_list, MANDATORY, "Names that match network interface")
ATOM(short, type, OVERLAY_INTERFACE_WIFI, cf_opt_interface_type,, "Type of network interface")
ATOM(uint16_t, port, RHIZOME_HTTP_PORT, cf_opt_port,, "Port number for network interface")
ATOM(uint64_t, speed, 1000000, cf_opt_uint64_scaled,, "Speed in bits per second")
ATOM(uint32_t, mdp_tick_ms, 0, cf_opt_uint32_nonzero,, "Override MDP tick interval for this interface")
END_STRUCT
ARRAY(interface_list)
KEY_STRING(15, opt_str)
KEY_STRING(15, cf_opt_str)
VALUE_SUB_STRUCT(network_interface)
END_ARRAY(10)
// The top level.
STRUCT(main)
NODE_STRUCT(interface_list, interfaces, opt_interface_list, MANDATORY)
NODE_STRUCT(interface_list, interfaces, cf_opt_interface_list, MANDATORY)
SUB_STRUCT(log, log,)
SUB_STRUCT(server, server,)
SUB_STRUCT(monitor, monitor,)
SUB_STRUCT(mdp, mdp,)
SUB_STRUCT(dna, dna,)
NODE(debugflags_t, debug, 0, opt_debugflags, USES_CHILDREN, "Debug flags")
NODE(debugflags_t, debug, 0, cf_opt_debugflags, USES_CHILDREN, "Debug flags")
SUB_STRUCT(rhizome, rhizome,)
SUB_STRUCT(directory, directory,)
SUB_STRUCT(host_list, hosts,)

View File

@ -21,22 +21,9 @@
#define WARNF(F,...) _WARNF("%s:%u " F, __FILE__, __LINE__, ##__VA_ARGS__)
#define WHYF(F,...) _WHYF("%s:%u " F, __FILE__, __LINE__, ##__VA_ARGS__)
#define WHYF_perror(F,...) _WHYF_perror("%s:%u " F, __FILE__, __LINE__, ##__VA_ARGS__)
#define alloca_str(s) ((s) ? alloca_str_toprint(s) : "NULL")
#include "config.h"
const char *find_keyend(const char *const key, const char *const fullkeyend)
{
const char *s = key;
if (s < fullkeyend && (isalpha(*s) || *s == '_'))
++s;
while (s < fullkeyend && (isalnum(*s) || *s == '_'))
++s;
if (s == key || (s < fullkeyend && *s != '.'))
return NULL;
return s;
}
void *emalloc(size_t len)
{
char *new = malloc(len + 1);
@ -62,7 +49,19 @@ char *str_emalloc(const char *str)
return strn_emalloc(str, strlen(str));
}
int make_child(struct cf_om_node **const parentp, const char *const fullkey, const char *const key, const char *const keyend)
static const char *cf_find_keyend(const char *const key, const char *const fullkeyend)
{
const char *s = key;
if (s < fullkeyend && (isalpha(*s) || *s == '_'))
++s;
while (s < fullkeyend && (isalnum(*s) || *s == '_'))
++s;
if (s == key || (s < fullkeyend && *s != '.'))
return NULL;
return s;
}
static int cf_om_make_child(struct cf_om_node **const parentp, const char *const fullkey, const char *const key, const char *const keyend)
{
size_t keylen = keyend - key;
//DEBUGF("%s key=%s", __FUNCTION__, alloca_toprint(-1, key, keylen));
@ -79,7 +78,7 @@ int make_child(struct cf_om_node **const parentp, const char *const fullkey, con
c = strncmp(key, child->key, keylen);
if (c == 0 && child->key[keylen])
c = -1;
//DEBUGF(" m=%d n=%d i=%d child->key=%s c=%d", m, n, i, alloca_str(child->key), c);
//DEBUGF(" m=%d n=%d i=%d child->key=%s c=%d", m, n, i, alloca_str_toprint(child->key), c);
if (c == 0) {
//DEBUGF(" found i=%d", i);
return i;
@ -113,10 +112,10 @@ int make_child(struct cf_om_node **const parentp, const char *const fullkey, con
return i;
}
void free_config_node(struct cf_om_node *node)
void cf_free_node(struct cf_om_node *node)
{
while (node->nodc)
free_config_node(node->nodv[--node->nodc]);
cf_free_node(node->nodv[--node->nodc]);
if (node->fullkey) {
free((char *)node->fullkey);
node->fullkey = node->key = NULL;
@ -128,7 +127,7 @@ void free_config_node(struct cf_om_node *node)
free(node);
}
struct cf_om_node *parse_config(const char *source, const char *buf, size_t len)
struct cf_om_node *cf_parse_to_om(const char *source, const char *buf, size_t len)
{
struct cf_om_node *root = emalloc(sizeof(struct cf_om_node));
if (root == NULL)
@ -165,7 +164,7 @@ struct cf_om_node *parse_config(const char *source, const char *buf, size_t len)
const char *key = fullkey;
const char *keyend = NULL;
int nodi = -1;
while (key <= fullkeyend && (keyend = find_keyend(key, fullkeyend)) && (nodi = make_child(nodep, fullkey, key, keyend)) != -1) {
while (key <= fullkeyend && (keyend = cf_find_keyend(key, fullkeyend)) && (nodi = cf_om_make_child(nodep, fullkey, key, keyend)) != -1) {
key = keyend + 1;
nodep = &(*nodep)->nodv[nodi];
}
@ -193,11 +192,11 @@ struct cf_om_node *parse_config(const char *source, const char *buf, size_t len)
}
return root;
error:
free_config_node(root);
cf_free_node(root);
return NULL;
}
void dump_config_node(const struct cf_om_node *node, int indent)
void cf_dump_node(const struct cf_om_node *node, int indent)
{
if (node == NULL)
DEBUGF("%*sNULL", indent * 3, "");
@ -205,17 +204,17 @@ void dump_config_node(const struct cf_om_node *node, int indent)
DEBUGF("%*s%s:%u fullkey=%s key=%s text=%s", indent * 3, "",
node->source ? node->source : "NULL",
node->line_number,
alloca_str(node->fullkey),
alloca_str(node->key),
alloca_str(node->text)
alloca_str_toprint(node->fullkey),
alloca_str_toprint(node->key),
alloca_str_toprint(node->text)
);
int i;
for (i = 0; i < node->nodc; ++i)
dump_config_node(node->nodv[i], indent + 1);
cf_dump_node(node->nodv[i], indent + 1);
}
}
int get_child(const struct cf_om_node *parent, const char *key)
static int cf_get_child(const struct cf_om_node *parent, const char *key)
{
int i;
for (i = 0; i < parent->nodc; ++i)
@ -224,7 +223,7 @@ int get_child(const struct cf_om_node *parent, const char *key)
return -1;
}
void warn_nodev(const char *file, unsigned line, const struct cf_om_node *node, const char *key, const char *fmt, va_list ap)
void cf_warn_nodev(const char *file, unsigned line, const struct cf_om_node *node, const char *key, const char *fmt, va_list ap)
{
strbuf b = strbuf_alloca(1024);
if (node) {
@ -242,39 +241,39 @@ void warn_nodev(const char *file, unsigned line, const struct cf_om_node *node,
_WARNF("%s:%u %s", file, line, strbuf_str(b));
}
void warn_childrenv(const char *file, unsigned line, const struct cf_om_node *parent, const char *fmt, va_list ap)
void cf_warn_childrenv(const char *file, unsigned line, const struct cf_om_node *parent, const char *fmt, va_list ap)
{
int i;
for (i = 0; i < parent->nodc; ++i) {
warn_nodev(file, line, parent->nodv[i], NULL, fmt, ap);
warn_childrenv(file, line, parent->nodv[i], fmt, ap);
cf_warn_nodev(file, line, parent->nodv[i], NULL, fmt, ap);
cf_warn_childrenv(file, line, parent->nodv[i], fmt, ap);
}
}
void warn_node(const char *file, unsigned line, const struct cf_om_node *node, const char *key, const char *fmt, ...)
void cf_warn_node(const char *file, unsigned line, const struct cf_om_node *node, const char *key, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
warn_nodev(file, line, node, key, fmt, ap);
cf_warn_nodev(file, line, node, key, fmt, ap);
va_end(ap);
}
void warn_children(const char *file, unsigned line, const struct cf_om_node *node, const char *fmt, ...)
void cf_warn_children(const char *file, unsigned line, const struct cf_om_node *node, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
warn_childrenv(file, line, node, fmt, ap);
cf_warn_childrenv(file, line, node, fmt, ap);
va_end(ap);
}
void warn_duplicate_node(const struct cf_om_node *parent, const char *key)
void cf_warn_duplicate_node(const struct cf_om_node *parent, const char *key)
{
warn_node(__FILE__, __LINE__, parent, key, "is duplicate");
cf_warn_node(__FILE__, __LINE__, parent, key, "is duplicate");
}
void warn_missing_node(const struct cf_om_node *parent, const char *key)
void cf_warn_missing_node(const struct cf_om_node *parent, const char *key)
{
warn_node(__FILE__, __LINE__, parent, key, "is missing");
cf_warn_node(__FILE__, __LINE__, parent, key, "is missing");
}
strbuf strbuf_cf_flags(strbuf sb, int flags)
@ -319,7 +318,7 @@ strbuf strbuf_cf_flags(strbuf sb, int flags)
return sb;
}
strbuf strbuf_cf_flag_reason(strbuf sb, int flags)
static strbuf strbuf_cf_flag_reason(strbuf sb, int flags)
{
if (flags == CFERROR)
return strbuf_puts(sb, "unrecoverable error");
@ -352,82 +351,64 @@ strbuf strbuf_cf_flag_reason(strbuf sb, int flags)
return sb;
}
void warn_node_value(const struct cf_om_node *node, int reason)
void cf_warn_node_value(const struct cf_om_node *node, int reason)
{
strbuf b = strbuf_alloca(180);
strbuf_cf_flag_reason(b, reason);
warn_node(__FILE__, __LINE__, node, NULL, "value %s %s", alloca_str(node->text), strbuf_str(b));
cf_warn_node(__FILE__, __LINE__, node, NULL, "value %s %s", alloca_str_toprint(node->text), strbuf_str(b));
}
void warn_no_array(const struct cf_om_node *node, int reason)
void cf_warn_no_array(const struct cf_om_node *node, int reason)
{
strbuf b = strbuf_alloca(180);
strbuf_cf_flag_reason(b, reason);
warn_node(__FILE__, __LINE__, node, NULL, "array discarded -- %s", strbuf_str(b));
cf_warn_node(__FILE__, __LINE__, node, NULL, "array discarded -- %s", strbuf_str(b));
}
void warn_unsupported_node(const struct cf_om_node *node)
void cf_warn_unsupported_node(const struct cf_om_node *node)
{
warn_node(__FILE__, __LINE__, node, NULL, "not supported");
cf_warn_node(__FILE__, __LINE__, node, NULL, "not supported");
}
void warn_unsupported_children(const struct cf_om_node *parent)
void cf_warn_unsupported_children(const struct cf_om_node *parent)
{
int i;
for (i = 0; i < parent->nodc; ++i) {
if (parent->nodv[i]->text)
warn_unsupported_node(parent->nodv[i]);
warn_unsupported_children(parent->nodv[i]);
cf_warn_unsupported_node(parent->nodv[i]);
cf_warn_unsupported_children(parent->nodv[i]);
}
}
void warn_list_overflow(const struct cf_om_node *node)
void cf_warn_list_overflow(const struct cf_om_node *node)
{
warn_node(__FILE__, __LINE__, node, NULL, "list overflow");
warn_children(__FILE__, __LINE__, node, "list overflow");
cf_warn_node(__FILE__, __LINE__, node, NULL, "list overflow");
cf_warn_children(__FILE__, __LINE__, node, "list overflow");
}
void warn_spurious_children(const struct cf_om_node *parent)
void cf_warn_spurious_children(const struct cf_om_node *parent)
{
warn_children(__FILE__, __LINE__, parent, "spurious");
cf_warn_children(__FILE__, __LINE__, parent, "spurious");
}
void warn_array_label(const struct cf_om_node *node, int reason)
void cf_warn_array_label(const struct cf_om_node *node, int reason)
{
strbuf b = strbuf_alloca(180);
strbuf_cf_flag_reason(b, reason);
warn_node(__FILE__, __LINE__, node, NULL, "array label %s -- %s", alloca_str(node->key), strbuf_str(b));
cf_warn_node(__FILE__, __LINE__, node, NULL, "array label %s -- %s", alloca_str_toprint(node->key), strbuf_str(b));
}
void warn_array_value(const struct cf_om_node *node, int reason)
void cf_warn_array_value(const struct cf_om_node *node, int reason)
{
strbuf b = strbuf_alloca(180);
strbuf_cf_flag_reason(b, reason);
if (node->text)
warn_node(__FILE__, __LINE__, node, NULL, "array value %s -- %s", alloca_str(node->text), strbuf_str(b));
cf_warn_node(__FILE__, __LINE__, node, NULL, "array value %s -- %s", alloca_str_toprint(node->text), strbuf_str(b));
else
warn_node(__FILE__, __LINE__, node, NULL, "array element -- %s", strbuf_str(b));
cf_warn_node(__FILE__, __LINE__, node, NULL, "array element -- %s", strbuf_str(b));
}
int opt_boolean(int *booleanp, const char *text);
int opt_absolute_path(char *str, size_t len, const char *text);
int opt_debugflags(debugflags_t *flagsp, const struct cf_om_node *node);
int opt_rhizome_peer(struct config_rhizomepeer *, const struct cf_om_node *node);
int opt_str(char *str, size_t len, const char *text);
int opt_str_nonempty(char *str, size_t len, const char *text);
int opt_int(int *intp, const char *text);
int opt_uint32_nonzero(uint32_t *intp, const char *text);
int opt_uint64_scaled(uint64_t *intp, const char *text);
int opt_protocol(char *str, size_t len, const char *text);
int opt_in_addr(struct in_addr *addrp, const char *text);
int opt_port(unsigned short *portp, const char *text);
int opt_sid(sid_t *sidp, const char *text);
int opt_rhizome_bk(rhizome_bk_t *bkp, const char *text);
int opt_interface_type(short *typep, const char *text);
int opt_pattern_list(struct pattern_list *listp, const char *text);
int opt_interface_list(struct config_interface_list *listp, const struct cf_om_node *node);
int opt_boolean(int *booleanp, const char *text)
int cf_opt_boolean(int *booleanp, const char *text)
{
if (!strcasecmp(text, "true") || !strcasecmp(text, "yes") || !strcasecmp(text, "on") || !strcasecmp(text, "1")) {
*booleanp = 1;
@ -440,7 +421,7 @@ int opt_boolean(int *booleanp, const char *text)
return CFINVALID;
}
int opt_absolute_path(char *str, size_t len, const char *text)
int cf_opt_absolute_path(char *str, size_t len, const char *text)
{
if (text[0] != '/')
return CFINVALID;
@ -485,10 +466,10 @@ debugflags_t debugFlagMask(const char *flagname)
return 0;
}
int opt_debugflags(debugflags_t *flagsp, const struct cf_om_node *node)
int cf_opt_debugflags(debugflags_t *flagsp, const struct cf_om_node *node)
{
//DEBUGF("%s", __FUNCTION__);
//dump_config_node(node, 1);
//cf_dump_node(node, 1);
debugflags_t setmask = 0;
debugflags_t clearmask = 0;
int setall = 0;
@ -497,13 +478,13 @@ int opt_debugflags(debugflags_t *flagsp, const struct cf_om_node *node)
int i;
for (i = 0; i < node->nodc; ++i) {
const struct cf_om_node *child = node->nodv[i];
warn_unsupported_children(child);
cf_warn_unsupported_children(child);
debugflags_t mask = debugFlagMask(child->key);
int flag = -1;
if (!mask)
warn_unsupported_node(child);
cf_warn_unsupported_node(child);
else if (child->text) {
int ret = opt_boolean(&flag, child->text);
int ret = cf_opt_boolean(&flag, child->text);
switch (ret) {
case CFERROR: return CFERROR;
case CFOK:
@ -521,7 +502,7 @@ int opt_debugflags(debugflags_t *flagsp, const struct cf_om_node *node)
}
break;
default:
warn_node_value(child, ret);
cf_warn_node_value(child, ret);
result |= ret;
break;
}
@ -536,7 +517,7 @@ int opt_debugflags(debugflags_t *flagsp, const struct cf_om_node *node)
return result;
}
int opt_protocol(char *str, size_t len, const char *text)
int cf_opt_protocol(char *str, size_t len, const char *text)
{
if (!str_is_uri_scheme(text))
return CFINVALID;
@ -547,11 +528,11 @@ int opt_protocol(char *str, size_t len, const char *text)
return CFOK;
}
int opt_rhizome_peer(struct config_rhizomepeer *rpeer, const struct cf_om_node *node)
int cf_opt_rhizome_peer(struct config_rhizomepeer *rpeer, const struct cf_om_node *node)
{
if (!node->text)
return opt_config_rhizomepeer(rpeer, node);
warn_spurious_children(node);
return cf_opt_config_rhizomepeer(rpeer, node);
cf_warn_spurious_children(node);
const char *protocol;
size_t protolen;
const char *auth;
@ -583,7 +564,7 @@ int opt_rhizome_peer(struct config_rhizomepeer *rpeer, const struct cf_om_node *
return CFOK;
}
int opt_str(char *str, size_t len, const char *text)
int cf_opt_str(char *str, size_t len, const char *text)
{
if (strlen(text) >= len)
return CFSTRINGOVERFLOW;
@ -592,14 +573,14 @@ int opt_str(char *str, size_t len, const char *text)
return CFOK;
}
int opt_str_nonempty(char *str, size_t len, const char *text)
int cf_opt_str_nonempty(char *str, size_t len, const char *text)
{
if (!text[0])
return CFINVALID;
return opt_str(str, len, text);
return cf_opt_str(str, len, text);
}
int opt_int(int *intp, const char *text)
int cf_opt_int(int *intp, const char *text)
{
const char *end = text;
long value = strtol(text, (char**)&end, 10);
@ -609,7 +590,7 @@ int opt_int(int *intp, const char *text)
return CFOK;
}
int opt_uint32_nonzero(uint32_t *intp, const char *text)
int cf_opt_uint32_nonzero(uint32_t *intp, const char *text)
{
const char *end = text;
long value = strtoul(text, (char**)&end, 10);
@ -619,7 +600,7 @@ int opt_uint32_nonzero(uint32_t *intp, const char *text)
return CFOK;
}
int opt_uint64_scaled(uint64_t *intp, const char *text)
int cf_opt_uint64_scaled(uint64_t *intp, const char *text)
{
uint64_t result;
const char *end;
@ -629,10 +610,10 @@ int opt_uint64_scaled(uint64_t *intp, const char *text)
return CFOK;
}
int opt_ushort_nonzero(unsigned short *ushortp, const char *text)
int cf_opt_ushort_nonzero(unsigned short *ushortp, const char *text)
{
uint32_t ui;
if (opt_uint32_nonzero(&ui, text) != CFOK || ui > 0xffff)
if (cf_opt_uint32_nonzero(&ui, text) != CFOK || ui > 0xffff)
return CFINVALID;
*ushortp = ui;
return CFOK;
@ -662,7 +643,7 @@ int vld_argv(const struct cf_om_node *parent, struct config_argv *array, int res
for (i = 1; i < array->ac; ++i) {
unsigned short key = array->av[i].key;
if (last_key > key) {
warn_node(__FILE__, __LINE__, parent, NULL, "array is not sorted");
cf_warn_node(__FILE__, __LINE__, parent, NULL, "array is not sorted");
return CFERROR;
}
last_key = key;
@ -675,13 +656,13 @@ int vld_argv(const struct cf_om_node *parent, struct config_argv *array, int res
if (last_key == key) {
char labelkey[12];
sprintf(labelkey, "%u", last_key);
warn_duplicate_node(parent, labelkey);
cf_warn_duplicate_node(parent, labelkey);
result |= CFINVALID;
}
while (++last_key < key && last_key <= sizeof(array->av)) {
char labelkey[12];
sprintf(labelkey, "%u", last_key);
warn_missing_node(parent, labelkey);
cf_warn_missing_node(parent, labelkey);
result |= CFINCOMPLETE;
}
last_key = key;
@ -689,7 +670,7 @@ int vld_argv(const struct cf_om_node *parent, struct config_argv *array, int res
return result;
}
int opt_in_addr(struct in_addr *addrp, const char *text)
int cf_opt_in_addr(struct in_addr *addrp, const char *text)
{
struct in_addr addr;
if (!inet_aton(text, &addr))
@ -698,7 +679,7 @@ int opt_in_addr(struct in_addr *addrp, const char *text)
return CFOK;
}
int opt_port(unsigned short *portp, const char *text)
int cf_opt_port(unsigned short *portp, const char *text)
{
unsigned short port = 0;
const char *p;
@ -714,7 +695,7 @@ int opt_port(unsigned short *portp, const char *text)
return CFOK;
}
int opt_sid(sid_t *sidp, const char *text)
int cf_opt_sid(sid_t *sidp, const char *text)
{
sid_t sid;
if (!str_is_subscriber_id(text))
@ -724,7 +705,7 @@ int opt_sid(sid_t *sidp, const char *text)
return CFOK;
}
int opt_rhizome_bk(rhizome_bk_t *bkp, const char *text)
int cf_opt_rhizome_bk(rhizome_bk_t *bkp, const char *text)
{
rhizome_bk_t sid;
if (!rhizome_str_is_bundle_key(text))
@ -734,7 +715,7 @@ int opt_rhizome_bk(rhizome_bk_t *bkp, const char *text)
return CFOK;
}
int opt_interface_type(short *typep, const char *text)
int cf_opt_interface_type(short *typep, const char *text)
{
if (strcasecmp(text, "ethernet") == 0) {
*typep = OVERLAY_INTERFACE_ETHERNET;
@ -755,7 +736,7 @@ int opt_interface_type(short *typep, const char *text)
return CFINVALID;
}
int opt_pattern_list(struct pattern_list *listp, const char *text)
int cf_opt_pattern_list(struct pattern_list *listp, const char *text)
{
struct pattern_list list;
memset(&list, 0, sizeof list);
@ -811,11 +792,11 @@ int opt_pattern_list(struct pattern_list *listp, const char *text)
*
* @author Andrew Bettison <andrew@servalproject.com>
*/
int opt_network_interface(struct config_network_interface *nifp, const char *text)
int cf_opt_network_interface(struct config_network_interface *nifp, const char *text)
{
//DEBUGF("%s text=%s", __FUNCTION__, alloca_str(text));
//DEBUGF("%s text=%s", __FUNCTION__, alloca_str_toprint(text));
struct config_network_interface nif;
dfl_config_network_interface(&nif);
cf_dfl_config_network_interface(&nif);
if (text[0] != '+' && text[0] != '-')
return CFINVALID; // "Sign must be + or -"
nif.exclude = (text[0] == '-');
@ -841,7 +822,7 @@ int opt_network_interface(struct config_network_interface *nifp, const char *tex
if (len) {
char buf[len + 1];
strncpy(buf, type, len)[len] = '\0';
int result = opt_interface_type(&nif.type, buf);
int result = cf_opt_interface_type(&nif.type, buf);
switch (result) {
case CFERROR: return CFERROR;
case CFOK: break;
@ -858,7 +839,7 @@ int opt_network_interface(struct config_network_interface *nifp, const char *tex
if (len) {
char buf[len + 1];
strncpy(buf, port, len)[len] = '\0';
int result = opt_port(&nif.port, buf);
int result = cf_opt_port(&nif.port, buf);
switch (result) {
case CFERROR: return CFERROR;
case CFOK: break;
@ -873,7 +854,7 @@ int opt_network_interface(struct config_network_interface *nifp, const char *tex
if (len) {
char buf[len + 1];
strncpy(buf, speed, len)[len] = '\0';
int result = opt_uint64_scaled(&nif.speed, buf);
int result = cf_opt_uint64_scaled(&nif.speed, buf);
switch (result) {
case CFERROR: return CFERROR;
case CFOK: break;
@ -890,15 +871,15 @@ int opt_network_interface(struct config_network_interface *nifp, const char *tex
}
/* Config parse function. Implements the original form of the 'interfaces' config option. Parses a
* comma-separated list of interface rules (see opt_network_interface() for the format of each
* comma-separated list of interface rules (see cf_opt_network_interface() for the format of each
* rule), then parses the regular config array-of-struct style interface option settings so that
* both forms are supported.
*
* @author Andrew Bettison <andrew@servalproject.com>
*/
int opt_interface_list(struct config_interface_list *listp, const struct cf_om_node *node)
int cf_opt_interface_list(struct config_interface_list *listp, const struct cf_om_node *node)
{
int result = opt_config_interface_list(listp, node);
int result = cf_opt_config_interface_list(listp, node);
if (result == CFERROR)
return CFERROR;
if (node->text) {
@ -915,7 +896,7 @@ int opt_interface_list(struct config_interface_list *listp, const struct cf_om_n
}
char buf[len + 1];
strncpy(buf, arg, len)[len] = '\0';
int ret = opt_network_interface(&listp->av[n].value, buf);
int ret = cf_opt_network_interface(&listp->av[n].value, buf);
switch (ret) {
case CFERROR: return CFERROR;
case CFOK:
@ -924,7 +905,7 @@ int opt_interface_list(struct config_interface_list *listp, const struct cf_om_n
++n;
break;
default:
warn_node(__FILE__, __LINE__, node, NULL, "invalid interface rule %s", alloca_str(buf)); \
cf_warn_node(__FILE__, __LINE__, node, NULL, "invalid interface rule %s", alloca_str_toprint(buf)); \
result |= CFSUB(ret);
break;
}
@ -1002,16 +983,16 @@ bye:
#define USES_TEXT |__TEXT
#define USES_CHILDREN |__CHILDREN
// Generate parsing functions, opt_config_SECTION()
// Generate parsing functions, cf_opt_config_SECTION()
#define STRUCT(__name, __validator...) \
int opt_config_##__name(struct config_##__name *strct, const struct cf_om_node *node) { \
int cf_opt_config_##__name(struct config_##__name *strct, const struct cf_om_node *node) { \
int (*validator)(const struct cf_om_node *, struct config_##__name *, int) = (NULL, ##__validator); \
int result = CFEMPTY; \
char used[node->nodc]; \
memset(used, 0, node->nodc * sizeof used[0]);
#define __ITEM(__element, __flags, __parseexpr) \
{ \
int i = get_child(node, #__element); \
int i = cf_get_child(node, #__element); \
const struct cf_om_node *child = (i != -1) ? node->nodv[i] : NULL; \
int ret = CFEMPTY; \
if (child) { \
@ -1025,13 +1006,13 @@ bye:
if (!(ret & CFEMPTY)) \
result &= ~CFEMPTY; \
else if ((__flags) & __MANDATORY) { \
warn_missing_node(node, #__element); \
cf_warn_missing_node(node, #__element); \
result |= CFINCOMPLETE; \
} \
if (ret & ~CFEMPTY) { \
assert(child != NULL); \
if (child->text) \
warn_node_value(child, ret); \
cf_warn_node_value(child, ret); \
result |= CFSUB(ret); \
} \
}
@ -1042,7 +1023,7 @@ bye:
#define STRING(__size, __element, __default, __parser, __flags, __comment) \
__ITEM(__element, ((0 __flags)|__TEXT)&~__CHILDREN, child->text ? __parser(strct->__element, (__size) + 1, child->text) : CFEMPTY)
#define SUB_STRUCT(__name, __element, __flags) \
__ITEM(__element, (0 __flags)|__CHILDREN, opt_config_##__name(&strct->__element, child))
__ITEM(__element, (0 __flags)|__CHILDREN, cf_opt_config_##__name(&strct->__element, child))
#define NODE_STRUCT(__name, __element, __parser, __flags) \
__ITEM(__element, (0 __flags)|__TEXT|__CHILDREN, __parser(&strct->__element, child))
#define END_STRUCT \
@ -1050,11 +1031,11 @@ bye:
int i; \
for (i = 0; i < node->nodc; ++i) { \
if (node->nodv[i]->text && !(used[i] & __TEXT)) { \
warn_unsupported_node(node->nodv[i]); \
cf_warn_unsupported_node(node->nodv[i]); \
result |= CFSUB(CFUNSUPPORTED); \
} \
if (node->nodv[i]->nodc && !(used[i] & __CHILDREN)) { \
warn_unsupported_children(node->nodv[i]); \
cf_warn_unsupported_children(node->nodv[i]); \
result |= CFSUB(CFUNSUPPORTED); \
} \
} \
@ -1065,7 +1046,7 @@ bye:
}
#define ARRAY(__name, __validator...) \
int opt_config_##__name(struct config_##__name *array, const struct cf_om_node *node) { \
int cf_opt_config_##__name(struct config_##__name *array, const struct cf_om_node *node) { \
__compare_func__config_##__name##__t *cmp = NULL; \
int (*eltcmp)(const struct config_##__name##__element *, const struct config_##__name##__element *) = __cmp_config_##__name; \
int (*validator)(const struct cf_om_node *, struct config_##__name *, int) = (NULL, ##__validator); \
@ -1082,7 +1063,7 @@ bye:
ret &= CF__FLAGS; \
result |= CFSUB(ret); \
if (ret != CFOK) \
warn_array_label(child, ret);
cf_warn_array_label(child, ret);
#define __ARRAY_VALUE(__parseexpr) \
if (ret == CFOK) { \
ret = (__parseexpr); \
@ -1094,7 +1075,7 @@ bye:
if (ret == CFOK) \
++n; \
else \
warn_array_value(child, ret); \
cf_warn_array_value(child, ret); \
}
#define END_ARRAY(__size) \
} \
@ -1102,7 +1083,7 @@ bye:
assert(n == NELS(array->av)); \
result |= CFARRAYOVERFLOW; \
for (; i < node->nodc; ++i) \
warn_list_overflow(node->nodv[i]); \
cf_warn_list_overflow(node->nodv[i]); \
} \
array->ac = n; \
if (cmp) \
@ -1110,7 +1091,7 @@ bye:
if (validator) \
result = (*validator)(node, array, result); \
if (result & ~CFEMPTY) { \
warn_no_array(node, result); \
cf_warn_no_array(node, result); \
array->ac = 0; \
} \
if (array->ac == 0) \
@ -1130,7 +1111,7 @@ bye:
#define VALUE_NODE(__type, __eltparser) \
__ARRAY_VALUE(__eltparser(&array->av[n].value, child))
#define VALUE_SUB_STRUCT(__structname) \
__ARRAY_VALUE(opt_config_##__structname(&array->av[n].value, child))
__ARRAY_VALUE(cf_opt_config_##__structname(&array->av[n].value, child))
#define VALUE_NODE_STRUCT(__structname, __eltparser) \
__ARRAY_VALUE(__eltparser(&array->av[n].value, child))
@ -1173,20 +1154,20 @@ int main(int argc, char **argv)
perror("read");
exit(1);
}
struct cf_om_node *root = parse_config(argv[i], buf, st.st_size);
struct cf_om_node *root = cf_parse_to_om(argv[i], buf, st.st_size);
close(fd);
//dump_config_node(root, 0);
//cf_dump_node(root, 0);
struct config_main config;
memset(&config, 0, sizeof config);
dfl_config_main(&config);
int result = opt_config_main(&config, root);
free_config_node(root);
cf_dfl_config_main(&config);
int result = cf_opt_config_main(&config, root);
cf_free_node(root);
free(buf);
DEBUGF("result = %s", strbuf_str(strbuf_cf_flags(strbuf_alloca(128), result)));
DEBUGF("config.log.file = %s", alloca_str(config.log.file));
DEBUGF("config.log.file = %s", alloca_str_toprint(config.log.file));
DEBUGF("config.log.show_pid = %d", config.log.show_pid);
DEBUGF("config.log.show_time = %d", config.log.show_time);
DEBUGF("config.server.chdir = %s", alloca_str(config.server.chdir));
DEBUGF("config.server.chdir = %s", alloca_str_toprint(config.server.chdir));
DEBUGF("config.debug = %llx", (unsigned long long) config.debug);
DEBUGF("config.directory.service = %s", alloca_tohex(config.directory.service.binary, SID_SIZE));
DEBUGF("config.rhizome.api.addfile.allow_host = %s", inet_ntoa(config.rhizome.api.addfile.allow_host));
@ -1200,8 +1181,8 @@ int main(int argc, char **argv)
}
for (j = 0; j < config.rhizome.direct.peer.ac; ++j) {
DEBUGF("config.rhizome.direct.peer.%s", config.rhizome.direct.peer.av[j].key);
DEBUGF(" .protocol = %s", alloca_str(config.rhizome.direct.peer.av[j].value.protocol));
DEBUGF(" .host = %s", alloca_str(config.rhizome.direct.peer.av[j].value.host));
DEBUGF(" .protocol = %s", alloca_str_toprint(config.rhizome.direct.peer.av[j].value.protocol));
DEBUGF(" .host = %s", alloca_str_toprint(config.rhizome.direct.peer.av[j].value.host));
DEBUGF(" .port = %u", config.rhizome.direct.peer.av[j].value.port);
}
for (j = 0; j < config.interfaces.ac; ++j) {
@ -1210,7 +1191,7 @@ int main(int argc, char **argv)
DEBUGF(" .match = [");
int k;
for (k = 0; k < config.interfaces.av[j].value.match.patc; ++k)
DEBUGF(" %s", alloca_str(config.interfaces.av[j].value.match.patv[k]));
DEBUGF(" %s", alloca_str_toprint(config.interfaces.av[j].value.match.patv[k]));
DEBUGF(" ]");
DEBUGF(" .type = %d", config.interfaces.av[j].value.type);
DEBUGF(" .port = %u", config.interfaces.av[j].value.port);
@ -1220,7 +1201,7 @@ int main(int argc, char **argv)
char sidhex[SID_STRLEN + 1];
tohex(sidhex, config.hosts.av[j].key.binary, SID_SIZE);
DEBUGF("config.hosts.%s", sidhex);
DEBUGF(" .interface = %s", alloca_str(config.hosts.av[j].value.interface));
DEBUGF(" .interface = %s", alloca_str_toprint(config.hosts.av[j].value.interface));
DEBUGF(" .address = %s", inet_ntoa(config.hosts.av[j].value.address));
DEBUGF(" .port = %u", config.hosts.av[j].value.port);
}