mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-04-19 16:20:53 +00:00
Improve new config prototype code
Rework ARRAYs, replacing label string with typed key, declaring KEY and VALUE independently. Implement dna.helper.argv array using key of type unsigned short. Implement mdp.iftype.<interfacetype>.tick_ms using key of type short for the interface type code.
This commit is contained in:
parent
58bf0e1752
commit
e2f6989fe8
143
config.h
143
config.h
@ -23,7 +23,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
/* This file defines the internal API to the configuration file. See "config_schema.h" for the
|
||||
* definition of the configuration schema, which is used to generate these API components.
|
||||
*
|
||||
* Each STRUCT(NAME, ...) schema declaration produces the following data declaration:
|
||||
* Each STRUCT(NAME, ...) schema declaration generates the following data declaration:
|
||||
*
|
||||
* struct config_NAME {
|
||||
* ...
|
||||
@ -47,35 +47,43 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* struct config_NAME bar;
|
||||
*
|
||||
* Each ARRAY_*(NAME, SIZE, LABELLEN, TYPE, ...) schema declaration produces the following data
|
||||
* Each ARRAY(NAME, ...) ... END_ARRAY(SIZE) schema declaration produces the following data
|
||||
* declaration:
|
||||
*
|
||||
* struct config_NAME {
|
||||
* unsigned ac;
|
||||
* struct config_NAME__element {
|
||||
* char label[LABELLEN+1];
|
||||
* TYPE value;
|
||||
* KEY-DECLARATION;
|
||||
* VALUE-DECLARATION;
|
||||
* } av[SIZE];
|
||||
* };
|
||||
*
|
||||
* A C struct definition containing a count 'ac' of the number of array elements [0..SIZE-1]
|
||||
* and 'av' an array of element values, each one consisting of a label and the value itself,
|
||||
* whose TYPE depends on the ARRAY_* declaration itself:
|
||||
* A C struct definition containing a count 'ac' of the number of array elements 0..SIZE-1,
|
||||
* and 'av' an array of element values, each one consisting of a key and a value:
|
||||
*
|
||||
* KEY_ATOM(TYPE, ...)
|
||||
*
|
||||
* TYPE key;
|
||||
*
|
||||
* ARRAY_ATOM(NAME, SIZE, LABELLEN, TYPE, ...)
|
||||
* ARRAY_NODE(NAME, SIZE, LABELLEN, TYPE, ...)
|
||||
* KEY_STRING(SIZE, ...)
|
||||
*
|
||||
* char key[SIZE+1];
|
||||
*
|
||||
* VALUE_ATOM(NAME, SIZE, LABELLEN, TYPE, ...)
|
||||
* VALUE_NODE(NAME, SIZE, LABELLEN, TYPE, ...)
|
||||
*
|
||||
* TYPE value;
|
||||
*
|
||||
* ARRAY_STRING(NAME, SIZE, LABELLEN, STRINGSIZE, ...)
|
||||
* VALUE_STRING(STRINGSIZE, ...)
|
||||
*
|
||||
* char value[STRINGSIZE];
|
||||
* char value[STRINGSIZE+1];
|
||||
*
|
||||
* ARRAY_STRUCT(NAME, SIZE, LABELLEN, STRUCTNAME, ...)
|
||||
* VALUE_SUB_STRUCT(STRUCTNAME)
|
||||
* VALUE_NODE_STRUCT(STRUCTNAME, ...)
|
||||
*
|
||||
* struct config_STRUCTNAME value;
|
||||
*
|
||||
* Each STRUCT(NAME, ...) and ARRAY_*(NAME, ...) schema declaration produces the following API
|
||||
* Each STRUCT(NAME, ...) and ARRAY(NAME, ...) schema declaration generates the following API
|
||||
* functions:
|
||||
*
|
||||
* - int dfl_config_NAME(struct config_NAME *dest);
|
||||
@ -90,8 +98,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* function is used to parse each individual array element, and the parsed result is only
|
||||
* appended to the array if it returns CFOK.
|
||||
*
|
||||
* If a STRUCT(NAME, VALIDATOR) or ARRAY(NAME, ..., VALIDATOR) schema declaration is given a validator
|
||||
* function, then the function must have the following signature:
|
||||
* If a STRUCT(NAME, VALIDATOR) or ARRAY(NAME, VALIDATOR) schema declaration is given a
|
||||
* validator function, then the function must have the following signature:
|
||||
*
|
||||
* - int VALIDATOR(struct config_NAME *dest, int orig_result);
|
||||
*
|
||||
@ -206,18 +214,27 @@ struct pattern_list {
|
||||
struct config_##__name __element;
|
||||
#define END_STRUCT \
|
||||
};
|
||||
#define __ARRAY(__name, __size, __lbllen, __decl) \
|
||||
#define ARRAY(__name, __validator...) \
|
||||
struct config_##__name { \
|
||||
unsigned ac; \
|
||||
struct config_##__name##__element { \
|
||||
char label[(__lbllen)+1]; \
|
||||
__decl; \
|
||||
struct config_##__name##__element {
|
||||
#define KEY_ATOM(__type, __eltparser) \
|
||||
__type key;
|
||||
#define KEY_STRING(__strsize, __eltparser) \
|
||||
char key[(__strsize) + 1];
|
||||
#define VALUE_ATOM(__type, __eltparser) \
|
||||
__type value;
|
||||
#define VALUE_STRING(__strsize, __eltparser) \
|
||||
char value[(__strsize) + 1];
|
||||
#define VALUE_NODE(__type, __eltparser) \
|
||||
__type value;
|
||||
#define VALUE_SUB_STRUCT(__structname) \
|
||||
struct config_##__structname value;
|
||||
#define VALUE_NODE_STRUCT(__structname, __eltparser) \
|
||||
struct config_##__structname value;
|
||||
#define END_ARRAY(__size) \
|
||||
} av[(__size)]; \
|
||||
};
|
||||
#define ARRAY_ATOM(__name, __size, __lbllen, __type, __lblparser, __eltparser, __validator...) __ARRAY(__name, __size, __lbllen, __type value)
|
||||
#define ARRAY_STRING(__name, __size, __lbllen, __strsize, __lblparser, __eltparser, __validator...) __ARRAY(__name, __size, __lbllen, char value[(__strsize) + 1])
|
||||
#define ARRAY_NODE(__name, __size, __lbllen, __type, __lblparser, __eltparser, __validator...) __ARRAY(__name, __size, __lbllen, __type value)
|
||||
#define ARRAY_STRUCT(__name, __size, __lbllen, __structname, __lblparser, __validator...) __ARRAY(__name, __size, __lbllen, struct config_##__structname value)
|
||||
#include "config_schema.h"
|
||||
#undef STRUCT
|
||||
#undef NODE
|
||||
@ -226,11 +243,15 @@ struct pattern_list {
|
||||
#undef SUB_STRUCT
|
||||
#undef NODE_STRUCT
|
||||
#undef END_STRUCT
|
||||
#undef __ARRAY
|
||||
#undef ARRAY_ATOM
|
||||
#undef ARRAY_STRING
|
||||
#undef ARRAY_NODE
|
||||
#undef ARRAY_STRUCT
|
||||
#undef ARRAY
|
||||
#undef KEY_ATOM
|
||||
#undef KEY_STRING
|
||||
#undef VALUE_ATOM
|
||||
#undef VALUE_STRING
|
||||
#undef VALUE_NODE
|
||||
#undef VALUE_SUB_STRUCT
|
||||
#undef VALUE_NODE_STRUCT
|
||||
#undef END_ARRAY
|
||||
|
||||
/* Return bit flags for schema default dfl_ and parsing opt_ functions. */
|
||||
|
||||
@ -266,15 +287,19 @@ strbuf strbuf_cf_flags(strbuf, int);
|
||||
#define END_STRUCT \
|
||||
return CFOK; \
|
||||
}
|
||||
#define __ARRAY(__name) \
|
||||
#define ARRAY(__name, __validator...) \
|
||||
int dfl_config_##__name(struct config_##__name *a) { \
|
||||
a->ac = 0; \
|
||||
return CFOK; \
|
||||
}
|
||||
#define ARRAY_ATOM(__name, __size, __lbllen, __type, __lblparser, __eltparser, __validator...) __ARRAY(__name)
|
||||
#define ARRAY_STRING(__name, __size, __lbllen, __strsize, __lblparser, __eltparser, __validator...) __ARRAY(__name)
|
||||
#define ARRAY_NODE(__name, __size, __lbllen, __type, __lblparser, __eltparser, __validator...) __ARRAY(__name)
|
||||
#define ARRAY_STRUCT(__name, __size, __lbllen, __structname, __lblparser, __validator...) __ARRAY(__name)
|
||||
#define KEY_ATOM(__type, __eltparser)
|
||||
#define KEY_STRING(__strsize, __eltparser)
|
||||
#define VALUE_ATOM(__type, __eltparser)
|
||||
#define VALUE_STRING(__strsize, __eltparser)
|
||||
#define VALUE_NODE(__type, __eltparser)
|
||||
#define VALUE_SUB_STRUCT(__structname)
|
||||
#define VALUE_NODE_STRUCT(__structname, __eltparser)
|
||||
#define END_ARRAY(__size)
|
||||
#include "config_schema.h"
|
||||
#undef STRUCT
|
||||
#undef NODE
|
||||
@ -283,11 +308,15 @@ strbuf strbuf_cf_flags(strbuf, int);
|
||||
#undef SUB_STRUCT
|
||||
#undef NODE_STRUCT
|
||||
#undef END_STRUCT
|
||||
#undef __ARRAY
|
||||
#undef ARRAY_ATOM
|
||||
#undef ARRAY_STRING
|
||||
#undef ARRAY_NODE
|
||||
#undef ARRAY_STRUCT
|
||||
#undef ARRAY
|
||||
#undef KEY_ATOM
|
||||
#undef KEY_STRING
|
||||
#undef VALUE_ATOM
|
||||
#undef VALUE_STRING
|
||||
#undef VALUE_NODE
|
||||
#undef VALUE_SUB_STRUCT
|
||||
#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.
|
||||
@ -321,22 +350,24 @@ 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, __lblparser, __validator...) \
|
||||
#define ARRAY(__name, __validator...) \
|
||||
int opt_config_##__name(struct config_##__name *, const struct cf_om_node *); \
|
||||
int __lblparser(char *, size_t, const char *); \
|
||||
__VALIDATOR(__name, ##__validator)
|
||||
#define ARRAY_ATOM(__name, __size, __lbllen, __type, __lblparser, __eltparser, __validator...) \
|
||||
__ARRAY(__name, __lblparser, ##__validator) \
|
||||
int __eltparser(__type *, const struct cf_om_node *);
|
||||
#define ARRAY_STRING(__name, __size, __lbllen, __strsize, __lblparser, __eltparser, __validator...) \
|
||||
__ARRAY(__name, __lblparser, ##__validator) \
|
||||
#define KEY_ATOM(__type, __eltparser) \
|
||||
int __eltparser(__type *, const char *);
|
||||
#define KEY_STRING(__strsize, __eltparser) \
|
||||
int __eltparser(char *, size_t, const char *);
|
||||
#define ARRAY_NODE(__name, __size, __lbllen, __type, __lblparser, __eltparser, __validator...) \
|
||||
__ARRAY(__name, __lblparser, ##__validator) \
|
||||
#define VALUE_ATOM(__type, __eltparser) \
|
||||
int __eltparser(__type *, const char *);
|
||||
#define VALUE_STRING(__strsize, __eltparser) \
|
||||
int __eltparser(char *, size_t, const char *);
|
||||
#define VALUE_NODE(__type, __eltparser) \
|
||||
int __eltparser(__type *, const struct cf_om_node *);
|
||||
#define ARRAY_STRUCT(__name, __size, __lbllen, __structname, __lblparser, __validator...) \
|
||||
__ARRAY(__name, __lblparser, ##__validator) \
|
||||
#define VALUE_SUB_STRUCT(__structname) \
|
||||
int 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)
|
||||
#include "config_schema.h"
|
||||
#undef STRUCT
|
||||
#undef NODE
|
||||
@ -345,10 +376,14 @@ struct cf_om_node {
|
||||
#undef SUB_STRUCT
|
||||
#undef NODE_STRUCT
|
||||
#undef END_STRUCT
|
||||
#undef __ARRAY
|
||||
#undef ARRAY_ATOM
|
||||
#undef ARRAY_STRING
|
||||
#undef ARRAY_NODE
|
||||
#undef ARRAY_STRUCT
|
||||
#undef ARRAY
|
||||
#undef KEY_ATOM
|
||||
#undef KEY_STRING
|
||||
#undef VALUE_ATOM
|
||||
#undef VALUE_STRING
|
||||
#undef VALUE_NODE
|
||||
#undef VALUE_SUB_STRUCT
|
||||
#undef VALUE_NODE_STRUCT
|
||||
#undef END_ARRAY
|
||||
|
||||
#endif //__SERVALDNA_CONFIG_H
|
||||
|
112
config_schema.h
112
config_schema.h
@ -50,7 +50,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* STRING(80, element2, "boo!", opt_str_nonempty, MANDATORY, "A non-empty string")
|
||||
* END_STRUCT
|
||||
*
|
||||
* ARRAY_STRUCT(joy, 16, 3, happy, opt_str, opt_str,)
|
||||
* ARRAY(joy)
|
||||
* KEY_STRING(3, happy, opt_str)
|
||||
* VALUE_SUB_STRUCT(happy)
|
||||
* END_ARRAY(16)
|
||||
*
|
||||
* STRUCT(love)
|
||||
* SUB_STRUCT(happy, thing,)
|
||||
@ -72,7 +75,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* struct config_joy {
|
||||
* unsigned ac;
|
||||
* struct config_joy__element {
|
||||
* char label[4];
|
||||
* char key[4];
|
||||
* struct config_happy value;
|
||||
* } av[16];
|
||||
* };
|
||||
@ -88,17 +91,36 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* A schema definition is composed from the following STRUCT and ARRAY definitions:
|
||||
*
|
||||
* STRUCT(name[, validatorfunc])
|
||||
* element-declaration
|
||||
* element-declaration
|
||||
* ...
|
||||
* END_STRUCT
|
||||
*
|
||||
* where each element-declaration is one of:
|
||||
*
|
||||
* ATOM(type, element, default, parsefunc, flags, comment)
|
||||
* NODE(type, element, default, parsefunc, flags, comment)
|
||||
* STRING(strlen, element, default, parsefunc, flags, comment)
|
||||
* SUB_STRUCT(structname, element, flags)
|
||||
* NODE_STRUCT(structname, element, parsefunc, flags)
|
||||
* END_STRUCT
|
||||
*
|
||||
* ARRAY_ATOM(name, size, labellen, type, labelparsefunc, valueparsefunc[, validatorfunc])
|
||||
* ARRAY_STRING(name, size, labellen, strlen, labelparsefunc, valueparsefunc[, validatorfunc])
|
||||
* ARRAY_NODE(name, size, type, labellen, labelparsefunc, valueparsefunc[, validatorfunc])
|
||||
* ARRAY_STRUCT(name, size, labellen, structname, labelparsefunc[, validatorfunc])
|
||||
* ARRAY(name[, validatorfunc])
|
||||
* key-declaration
|
||||
* value-declaration
|
||||
* END_ARRAY(size)
|
||||
*
|
||||
* where key-declaration is one of:
|
||||
*
|
||||
* KEY_ATOM(type, parsefunc)
|
||||
* KEY_STRING(strlen, parsefunc)
|
||||
*
|
||||
* and value-declaration is one of:
|
||||
*
|
||||
* VALUE_ATOM(type, parsefunc)
|
||||
* VALUE_STRING(strlen, parsefunc)
|
||||
* VALUE_NODE(type, parsefunc)
|
||||
* VALUE_SUB_STRUCT(structname)
|
||||
* VALUE_NODE_STRUCT(structname, parsefunc)
|
||||
*
|
||||
* The meanings of the parameters are:
|
||||
*
|
||||
@ -107,20 +129,16 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* arrays. This label does not appear anywhere in the config file itself; it is purely for
|
||||
* internal code-related purposes.
|
||||
* 'strlen'
|
||||
* For STRING elements and ARRAY_STRING arrays of strings, gives the maximum length of the
|
||||
* string. The struct is declared with an array of char[strlen+1] to leave room for a
|
||||
* terminating nul.
|
||||
* 'labellen'
|
||||
* For all ARRAYs, gives the maximum length of the label string. The struct is declared with
|
||||
* an array of char[labellen+1] to leave room for a terminating nul.
|
||||
* For STRING, LABEL_STRING and VALUE_STRING, gives the maximum length of the string. The
|
||||
* string is declared as an array of char[strlen+1] to leave room for a terminating nul.
|
||||
* 'size'
|
||||
* For all ARRAYs, gives the maximum size of the array.
|
||||
* 'type'
|
||||
* Only used for ATOM, NODE, ARRAY_ATOM and ARRAY_NODE declarations. Gives the C type of the
|
||||
* element. For STRING and ARRAY_STRING, this is implicitly (const char *).
|
||||
* Used for ATOM, NODE, LABEL_ATOM, VALUE_ATOM and VALUE_NODE declarations. Gives the C type
|
||||
* of the element. For STRING, KEY_STRING and VALUE_STRING this is implicitly a char[].
|
||||
* 'structname'
|
||||
* Only used for SUB_STRUCT, NODE_STRUCT and ARRAY_STRUCT declarations. Identifies a sub-
|
||||
* structure by 'name' to nest in the enclosing struct or array.
|
||||
* Only used for SUB_STRUCT, NODE_STRUCT, VALUE_SUB_STRUCT and VALUE_NODE_STRUCT declarations.
|
||||
* Identifies a sub- structure by 'name' to nest in the enclosing struct or array.
|
||||
* 'element'
|
||||
* The name of the struct element and the key in the configuration file. This name does appear
|
||||
* in the config file and also in the API, so that an option mamed "some.thing.element1" in the
|
||||
@ -131,20 +149,12 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Only used for ATOM and NODE struct elements. Gives the default value for the element if
|
||||
* absent from the config file.
|
||||
* 'parsefunc'
|
||||
* The function used to parse a VALUE from the config file for a STRUCT element. The and ATOM
|
||||
* and STRING parse functions take a string argument (const char *) which is the nul-terminated
|
||||
* text of the VALUE (excluding the trailing \n or \r\n). The NODE and NODE_STRUCT parse
|
||||
* functions take a pointer to a COM node (const struct cf_om_node *), which is the tree of all
|
||||
* lines starting with the same partial FULLKEY.
|
||||
* 'labelparsefunc'
|
||||
* The function used to parse a KEY from the config file (the ) for each ARRAY element value.
|
||||
* Takes a string argument (const char *). Returns a CFxxx result code as documented in
|
||||
* "config.h".
|
||||
* 'valueparsefunc'
|
||||
* The function used to parse a VALUE from the config file for each ARRAY element value. The
|
||||
* ARRAY_ATOM and ARRAY_STRING parse functions take a string argument (const char *). The
|
||||
* ARRAY_NODE and ARRAY_STRUCT parse functions take a pointer to a COM node (const struct
|
||||
* cf_om_node *). Returns a CFxxx result code as documented in "config.h".
|
||||
* The function used to parse a VALUE from the config file for a STRUCT element, or a KEY or
|
||||
* VALUE for an array element. Parse functions for ATOM, STRING, KEY_ATOM, KEY_STRING,
|
||||
* VALUE_ATOM and VALUE_STRING all take a string argument (const char *) which is a
|
||||
* nul-terminated text. The parse functions for NODE, NODE_STRUCT, VALUE_NODE and
|
||||
* VALUE_NODE_STRUCT take a pointer to a COM node (const struct cf_om_node *), and are
|
||||
* responsible for parsing the node's text and all of its descendents (children).
|
||||
* 'validatorfunc'
|
||||
* A function that is called after the struct/array is fully parsed and populated. This
|
||||
* function can perform validation checks on the whole struct/array that cannot be performed by
|
||||
@ -176,11 +186,28 @@ STRING(256, chdir, "/", opt_absolute_path,, "Absolute path
|
||||
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, opt_str_nonempty,, "Name of socket for monitor interface")
|
||||
ATOM(int, uid, -1, opt_int,, "Allowed UID for monitor socket client")
|
||||
END_STRUCT
|
||||
|
||||
ARRAY_STRING(argv, 16, 3, 128, opt_argv_label, opt_str, vld_argv)
|
||||
STRUCT(mdp_iftype)
|
||||
ATOM(uint32_t, tick_ms, 0, opt_uint32_nonzero,, "Tick interval for this interface type")
|
||||
END_STRUCT
|
||||
|
||||
ARRAY(mdp_iftypelist)
|
||||
KEY_ATOM(short, opt_interface_type)
|
||||
VALUE_SUB_STRUCT(mdp_iftype)
|
||||
END_ARRAY(5)
|
||||
|
||||
STRUCT(mdp)
|
||||
ATOM(uint32_t, ticks_per_full_address, 4, opt_uint32_nonzero,, "Ticks to elapse between announcing full SID")
|
||||
SUB_STRUCT(mdp_iftypelist, iftype,)
|
||||
END_STRUCT
|
||||
|
||||
ARRAY(argv, vld_argv)
|
||||
KEY_ATOM(unsigned short, opt_ushort_nonzero)
|
||||
VALUE_STRING(128, opt_str)
|
||||
END_ARRAY(16)
|
||||
|
||||
STRUCT(executable)
|
||||
STRING(256, executable, "", opt_absolute_path, MANDATORY, "Absolute path of dna helper executable")
|
||||
@ -197,7 +224,10 @@ STRING(256, host, "", opt_str_nonempty, MANDATORY, "Host n
|
||||
ATOM(uint16_t, port, RHIZOME_HTTP_PORT, opt_port,, "Port number")
|
||||
END_STRUCT
|
||||
|
||||
ARRAY_NODE(peerlist, 10, 15, struct config_rhizomepeer, opt_str, opt_rhizome_peer)
|
||||
ARRAY(peerlist)
|
||||
KEY_STRING(15, opt_str)
|
||||
VALUE_NODE(struct config_rhizomepeer, opt_rhizome_peer)
|
||||
END_ARRAY(10)
|
||||
|
||||
STRUCT(rhizomedirect)
|
||||
SUB_STRUCT(peerlist, peer,)
|
||||
@ -219,7 +249,10 @@ ATOM(struct in_addr, address, (struct in_addr){0}, opt_in_addr, MANDAT
|
||||
ATOM(uint16_t, port, PORT_DNA, opt_port,, "Port number")
|
||||
END_STRUCT
|
||||
|
||||
ARRAY_STRUCT(host_list, 32, SID_STRLEN, host, opt_str_hex_sid)
|
||||
ARRAY(host_list)
|
||||
KEY_ATOM(sid_t, opt_sid)
|
||||
VALUE_SUB_STRUCT(host)
|
||||
END_ARRAY(32)
|
||||
|
||||
STRUCT(network_interface)
|
||||
ATOM(int, exclude, 0, opt_boolean,, "If true, do not use matching interfaces")
|
||||
@ -227,15 +260,20 @@ ATOM(struct pattern_list, match, PATTERN_LIST_EMPTY, opt_pattern_list, MA
|
||||
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")
|
||||
END_STRUCT
|
||||
|
||||
ARRAY_STRUCT(interface_list, 10, 15, network_interface, opt_str)
|
||||
ARRAY(interface_list)
|
||||
KEY_STRING(15, opt_str)
|
||||
VALUE_SUB_STRUCT(network_interface)
|
||||
END_ARRAY(10)
|
||||
|
||||
STRUCT(main)
|
||||
NODE_STRUCT(interface_list, interfaces, 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")
|
||||
SUB_STRUCT(rhizome, rhizome,)
|
||||
|
168
config_test.c
168
config_test.c
@ -411,11 +411,11 @@ 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_str_hex_sid(char *sidhexp, size_t len, const char *text);
|
||||
int opt_sid(sid_t *sidp, const char *text);
|
||||
int opt_interface_type(short *typep, const char *text);
|
||||
int opt_pattern_list(struct pattern_list *listp, const char *text);
|
||||
@ -431,20 +431,15 @@ int opt_boolean(int *booleanp, const char *text)
|
||||
*booleanp = 0;
|
||||
return CFOK;
|
||||
}
|
||||
//invalid_text(node, "expecting true|yes|on|1|false|no|off|0");
|
||||
return CFINVALID;
|
||||
}
|
||||
|
||||
int opt_absolute_path(char *str, size_t len, const char *text)
|
||||
{
|
||||
if (text[0] != '/') {
|
||||
//invalid_text(node, "must start with '/'");
|
||||
if (text[0] != '/')
|
||||
return CFINVALID;
|
||||
}
|
||||
if (strlen(text) >= len) {
|
||||
//invalid_text(node, "string overflow");
|
||||
if (strlen(text) >= len)
|
||||
return CFSTRINGOVERFLOW;
|
||||
}
|
||||
strncpy(str, text, len);
|
||||
assert(str[len - 1] == '\0');
|
||||
return CFOK;
|
||||
@ -537,14 +532,10 @@ int opt_debugflags(debugflags_t *flagsp, const struct cf_om_node *node)
|
||||
|
||||
int opt_protocol(char *str, size_t len, const char *text)
|
||||
{
|
||||
if (!str_is_uri_scheme(text)) {
|
||||
//invalid_text(node, "contains invalid character");
|
||||
if (!str_is_uri_scheme(text))
|
||||
return CFINVALID;
|
||||
}
|
||||
if (strlen(text) >= len) {
|
||||
//invalid_text(node, "string overflow");
|
||||
if (strlen(text) >= len)
|
||||
return CFSTRINGOVERFLOW;
|
||||
}
|
||||
strncpy(str, text, len);
|
||||
assert(str[len - 1] == '\0');
|
||||
return CFOK;
|
||||
@ -564,7 +555,7 @@ int opt_rhizome_peer(struct config_rhizomepeer *rpeer, const struct cf_om_node *
|
||||
&& str_uri_hierarchical(node->text, &hier, NULL)
|
||||
&& str_uri_hierarchical_authority(hier, &auth, NULL))
|
||||
)
|
||||
goto invalid;
|
||||
return CFINVALID;
|
||||
} else {
|
||||
auth = node->text;
|
||||
protocol = "http";
|
||||
@ -574,23 +565,16 @@ int opt_rhizome_peer(struct config_rhizomepeer *rpeer, const struct cf_om_node *
|
||||
size_t hostlen;
|
||||
unsigned short port = 4110;
|
||||
if (!str_uri_authority_hostname(auth, &host, &hostlen))
|
||||
goto invalid;
|
||||
return CFINVALID;
|
||||
str_uri_authority_port(auth, &port);
|
||||
if (protolen >= sizeof rpeer->protocol) {
|
||||
//invalid_text(node, "protocol string overflow");
|
||||
if (protolen >= sizeof rpeer->protocol)
|
||||
return CFSTRINGOVERFLOW;
|
||||
}
|
||||
if (hostlen >= sizeof rpeer->host) {
|
||||
//invalid_text(node, "hostname string overflow");
|
||||
if (hostlen >= sizeof rpeer->host)
|
||||
return CFSTRINGOVERFLOW;
|
||||
}
|
||||
strncpy(rpeer->protocol, protocol, protolen)[protolen] = '\0';
|
||||
strncpy(rpeer->host, host, hostlen)[hostlen] = '\0';
|
||||
rpeer->port = port;
|
||||
return CFOK;
|
||||
invalid:
|
||||
//invalid_text(node, "malformed URL");
|
||||
return CFINVALID;
|
||||
}
|
||||
|
||||
int opt_str(char *str, size_t len, const char *text)
|
||||
@ -604,10 +588,8 @@ int opt_str(char *str, size_t len, const char *text)
|
||||
|
||||
int opt_str_nonempty(char *str, size_t len, const char *text)
|
||||
{
|
||||
if (!text[0]) {
|
||||
//invalid_text(node, "empty string");
|
||||
if (!text[0])
|
||||
return CFINVALID;
|
||||
}
|
||||
return opt_str(str, len, text);
|
||||
}
|
||||
|
||||
@ -621,56 +603,55 @@ int opt_int(int *intp, const char *text)
|
||||
return CFOK;
|
||||
}
|
||||
|
||||
int opt_uint32_nonzero(uint32_t *intp, const char *text)
|
||||
{
|
||||
const char *end = text;
|
||||
long value = strtoul(text, (char**)&end, 10);
|
||||
if (end == text || *end || value < 1 || value > 0xffffffffL)
|
||||
return CFINVALID;
|
||||
*intp = value;
|
||||
return CFOK;
|
||||
}
|
||||
|
||||
int opt_uint64_scaled(uint64_t *intp, const char *text)
|
||||
{
|
||||
uint64_t result;
|
||||
const char *end;
|
||||
if (!str_to_uint64_scaled(text, 10, &result, &end) || *end) {
|
||||
//invalid_text(node, "invalid scaled unsigned integer");
|
||||
if (!str_to_uint64_scaled(text, 10, &result, &end) || *end)
|
||||
return CFINVALID;
|
||||
}
|
||||
*intp = result;
|
||||
return CFOK;
|
||||
}
|
||||
|
||||
int opt_argv_label(char *labelp, size_t len, const char *text)
|
||||
int opt_ushort_nonzero(unsigned short *ushortp, const char *text)
|
||||
{
|
||||
const char *s = text;
|
||||
if (isdigit(*s) && *s != '0') {
|
||||
++s;
|
||||
while (isdigit(*s))
|
||||
++s;
|
||||
}
|
||||
if (s == text || *s)
|
||||
uint32_t ui;
|
||||
if (opt_uint32_nonzero(&ui, text) != CFOK || ui > 0xffff)
|
||||
return CFINVALID;
|
||||
if (s - text >= len)
|
||||
return CFSTRINGOVERFLOW;
|
||||
strncpy(labelp, text, len - 1)[len - 1] = '\0';
|
||||
*ushortp = ui;
|
||||
return CFOK;
|
||||
}
|
||||
|
||||
int cmp_argv(const struct config_argv__element *a, const struct config_argv__element *b)
|
||||
{
|
||||
int ai = atoi(a->label);
|
||||
int bi = atoi(b->label);
|
||||
return ai < bi ? -1 : ai > bi ? 1 : 0;
|
||||
return a->key < b->key ? -1 : a->key > b->key ? 1 : 0;
|
||||
}
|
||||
|
||||
int vld_argv(const struct cf_om_node *parent, struct config_argv *array, int result)
|
||||
{
|
||||
qsort(array->av, array->ac, sizeof array->av[0], (int (*)(const void *, const void *)) cmp_argv);
|
||||
int last_label = -1;
|
||||
unsigned short last_key = 0;
|
||||
int i;
|
||||
for (i = 0; i < array->ac; ++i) {
|
||||
int label = atoi(array->av[i].label);
|
||||
assert(label >= 1);
|
||||
while (last_label != -1 && ++last_label < label && last_label <= sizeof(array->av)) {
|
||||
unsigned short key = array->av[i].key;
|
||||
assert(key >= 1);
|
||||
while (last_key != -1 && ++last_key < key && last_key <= sizeof(array->av)) {
|
||||
char labelkey[12];
|
||||
sprintf(labelkey, "%u", last_label);
|
||||
sprintf(labelkey, "%u", last_key);
|
||||
warn_missing_node(parent, labelkey);
|
||||
result |= CFINCOMPLETE;
|
||||
}
|
||||
last_label = label;
|
||||
last_key = key;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -694,31 +675,17 @@ int opt_port(unsigned short *portp, const char *text)
|
||||
if (port / 10 != oport)
|
||||
break;
|
||||
}
|
||||
if (*p || port == 0) {
|
||||
//invalid_text(node, "invalid port number");
|
||||
if (*p || port == 0)
|
||||
return CFINVALID;
|
||||
}
|
||||
*portp = port;
|
||||
return CFOK;
|
||||
}
|
||||
|
||||
int opt_str_hex_sid(char *sidhexp, size_t len, const char *text)
|
||||
{
|
||||
if (!str_is_subscriber_id(text))
|
||||
return CFINVALID;
|
||||
if (len <= SID_STRLEN)
|
||||
return CFSTRINGOVERFLOW;
|
||||
strncpy(sidhexp, text, SID_STRLEN)[SID_STRLEN] = '\0';
|
||||
return CFOK;
|
||||
}
|
||||
|
||||
int opt_sid(sid_t *sidp, const char *text)
|
||||
{
|
||||
sid_t sid;
|
||||
if (!str_is_subscriber_id(text)) {
|
||||
//invalid_text(node, "invalid subscriber ID");
|
||||
if (!str_is_subscriber_id(text))
|
||||
return CFINVALID;
|
||||
}
|
||||
size_t n = fromhex(sidp->binary, text, SID_SIZE);
|
||||
assert(n == SID_SIZE);
|
||||
return CFOK;
|
||||
@ -742,7 +709,6 @@ int opt_interface_type(short *typep, const char *text)
|
||||
*typep = OVERLAY_INTERFACE_UNKNOWN;
|
||||
return CFOK;
|
||||
}
|
||||
//invalid_text(node, "invalid network interface type");
|
||||
return CFINVALID;
|
||||
}
|
||||
|
||||
@ -756,10 +722,8 @@ int opt_pattern_list(struct pattern_list *listp, const char *text)
|
||||
if (!*p || isspace(*p) || *p == ',') {
|
||||
if (word) {
|
||||
size_t len = p - word;
|
||||
if (list.patc >= NELS(list.patv) || len >= sizeof(list.patv[list.patc])) {
|
||||
//invalid_text(node, "string overflow");
|
||||
if (list.patc >= NELS(list.patv) || len >= sizeof(list.patv[list.patc]))
|
||||
return CFARRAYOVERFLOW;
|
||||
}
|
||||
strncpy(list.patv[list.patc++], word, len)[len] = '\0';
|
||||
word = NULL;
|
||||
}
|
||||
@ -912,8 +876,8 @@ int opt_interface_list(struct config_interface_list *listp, const struct cf_om_n
|
||||
switch (ret) {
|
||||
case CFERROR: return CFERROR;
|
||||
case CFOK:
|
||||
len = snprintf(listp->av[n].label, sizeof listp->av[n].label - 1, "%u", n);
|
||||
listp->av[n].label[len] = '\0';
|
||||
len = snprintf(listp->av[n].key, sizeof listp->av[n].key - 1, "%u", n);
|
||||
listp->av[n].key[len] = '\0';
|
||||
++n;
|
||||
break;
|
||||
default:
|
||||
@ -1015,22 +979,25 @@ bye:
|
||||
return result; \
|
||||
}
|
||||
|
||||
#define __ARRAY(__name, __lblparser, __parseexpr, __validator...) \
|
||||
#define ARRAY(__name, __validator...) \
|
||||
int opt_config_##__name(struct config_##__name *array, const struct cf_om_node *node) { \
|
||||
int (*validator)(const struct cf_om_node *, struct config_##__name *, int) = (NULL, ##__validator); \
|
||||
int result = CFOK; \
|
||||
int i, n; \
|
||||
for (n = 0, i = 0; i < node->nodc && n < NELS(array->av); ++i) { \
|
||||
const struct cf_om_node *child = node->nodv[i]; \
|
||||
int ret = __lblparser(array->av[n].label, sizeof array->av[n].label, child->key); \
|
||||
int ret = CFEMPTY;
|
||||
#define __ARRAY_KEY(__parseexpr) \
|
||||
ret = (__parseexpr); \
|
||||
if (ret == CFERROR) \
|
||||
return CFERROR; \
|
||||
result |= ret & CF__SUBFLAGS; \
|
||||
ret &= CF__FLAGS; \
|
||||
result |= CFSUB(ret); \
|
||||
if (ret != CFOK) \
|
||||
warn_array_label(child, ret); \
|
||||
else { \
|
||||
warn_array_label(child, ret);
|
||||
#define __ARRAY_VALUE(__parseexpr) \
|
||||
if (ret == CFOK) { \
|
||||
ret = (__parseexpr); \
|
||||
if (ret == CFERROR) \
|
||||
return CFERROR; \
|
||||
@ -1041,7 +1008,8 @@ bye:
|
||||
++n; \
|
||||
else \
|
||||
warn_array_value(child, ret); \
|
||||
} \
|
||||
}
|
||||
#define END_ARRAY(__size) \
|
||||
} \
|
||||
if (i < node->nodc) { \
|
||||
assert(n == NELS(array->av)); \
|
||||
@ -1060,14 +1028,13 @@ bye:
|
||||
result |= CFEMPTY; \
|
||||
return result; \
|
||||
}
|
||||
#define ARRAY_ATOM(__name, __size, __lbllen, __type, __lblparser, __eltparser, __validator...) \
|
||||
__ARRAY(__name, __lblparser, child->text ? __eltparser(&array->av[n].value, child->text) : CFEMPTY, ##__validator)
|
||||
#define ARRAY_STRING(__name, __size, __lbllen, __strsize, __lblparser, __eltparser, __validator...) \
|
||||
__ARRAY(__name, __lblparser, child->text ? __eltparser(array->av[n].value, sizeof array->av[n].value, child->text) : CFEMPTY, ##__validator)
|
||||
#define ARRAY_NODE(__name, __size, __lbllen, __type, __lblparser, __eltparser, __validator...) \
|
||||
__ARRAY(__name, __lblparser, __eltparser(&array->av[n].value, child), ##__validator)
|
||||
#define ARRAY_STRUCT(__name, __size, __lbllen, __structname, __lblparser, __validator...) \
|
||||
__ARRAY(__name, __lblparser, opt_config_##__structname(&array->av[n].value, child), ##__validator)
|
||||
#define KEY_ATOM(__type, __eltparser) __ARRAY_KEY(__eltparser(&array->av[n].key, child->key))
|
||||
#define KEY_STRING(__strsize, __eltparser) __ARRAY_KEY(__eltparser(array->av[n].key, sizeof array->av[n].key, child->key))
|
||||
#define VALUE_ATOM(__type, __eltparser) __ARRAY_VALUE(child->text ? __eltparser(&array->av[n].value, child->text) : CFEMPTY)
|
||||
#define VALUE_STRING(__strsize, __eltparser) __ARRAY_VALUE(child->text ? __eltparser(array->av[n].value, sizeof array->av[n].value, child->text) : CFEMPTY)
|
||||
#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))
|
||||
#define VALUE_NODE_STRUCT(__structname, __eltparser) __ARRAY_VALUE(__eltparser(&array->av[n].value, child))
|
||||
|
||||
#include "config_schema.h"
|
||||
|
||||
@ -1078,12 +1045,15 @@ bye:
|
||||
#undef SUB_STRUCT
|
||||
#undef NODE_STRUCT
|
||||
#undef END_STRUCT
|
||||
#undef __ARRAY
|
||||
|
||||
#undef ARRAY_ATOM
|
||||
#undef ARRAY_STRING
|
||||
#undef ARRAY_NODE
|
||||
#undef ARRAY_STRUCT
|
||||
#undef ARRAY
|
||||
#undef KEY_ATOM
|
||||
#undef KEY_STRING
|
||||
#undef VALUE_ATOM
|
||||
#undef VALUE_STRING
|
||||
#undef VALUE_NODE
|
||||
#undef VALUE_SUB_STRUCT
|
||||
#undef VALUE_NODE_STRUCT
|
||||
#undef END_ARRAY
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
@ -1122,17 +1092,21 @@ int main(int argc, char **argv)
|
||||
DEBUGF("config.debug = %llx", (unsigned long long) config.debug);
|
||||
DEBUGF("config.directory.service = %s", alloca_tohex(config.directory.service.binary, SID_SIZE));
|
||||
int j;
|
||||
for (j = 0; j < config.mdp.iftype.ac; ++j) {
|
||||
DEBUGF("config.mdp.iftype.%u", config.mdp.iftype.av[j].key);
|
||||
DEBUGF(" .tick_ms = %u", config.mdp.iftype.av[j].value.tick_ms);
|
||||
}
|
||||
for (j = 0; j < config.dna.helper.argv.ac; ++j) {
|
||||
DEBUGF("config.dna.helper.argv.%s=%s", config.dna.helper.argv.av[j].label, config.dna.helper.argv.av[j].value);
|
||||
DEBUGF("config.dna.helper.argv.%u=%s", config.dna.helper.argv.av[j].key, config.dna.helper.argv.av[j].value);
|
||||
}
|
||||
for (j = 0; j < config.rhizome.direct.peer.ac; ++j) {
|
||||
DEBUGF("config.rhizome.direct.peer.%s", config.rhizome.direct.peer.av[j].label);
|
||||
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(" .port = %u", config.rhizome.direct.peer.av[j].value.port);
|
||||
}
|
||||
for (j = 0; j < config.interfaces.ac; ++j) {
|
||||
DEBUGF("config.interfaces.%s", config.interfaces.av[j].label);
|
||||
DEBUGF("config.interfaces.%s", config.interfaces.av[j].key);
|
||||
DEBUGF(" .exclude = %d", config.interfaces.av[j].value.exclude);
|
||||
DEBUGF(" .match = [");
|
||||
int k;
|
||||
@ -1144,7 +1118,9 @@ int main(int argc, char **argv)
|
||||
DEBUGF(" .speed = %llu", (unsigned long long) config.interfaces.av[j].value.speed);
|
||||
}
|
||||
for (j = 0; j < config.hosts.ac; ++j) {
|
||||
DEBUGF("config.hosts.%s", config.hosts.av[j].label);
|
||||
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(" .address = %s", inet_ntoa(config.hosts.av[j].value.address));
|
||||
DEBUGF(" .port = %u", config.hosts.av[j].value.port);
|
||||
|
Loading…
x
Reference in New Issue
Block a user