Add new "config dump" command - not working yet

Add cf_fmt_xxx() functions for converting configuration structs into a
config object model tree.
This commit is contained in:
Andrew Bettison 2013-02-26 18:09:08 +10:30
parent aeeef0e972
commit 6eb08ae805
7 changed files with 524 additions and 43 deletions

View File

@ -1140,8 +1140,10 @@ int app_config_schema(const struct cli_parsed *parsed, void *context)
if (create_serval_instance_dir() == -1)
return -1;
struct cf_om_node *root = NULL;
if (cf_sch_config_main(&root) == -1)
if (cf_sch_config_main(&root) == -1) {
cf_om_free_node(&root);
return -1;
}
struct cf_om_iterator it;
for (cf_om_iter_start(&it, root); it.node; cf_om_iter_next(&it))
if (it.node->text || it.node->nodc == 0) {
@ -1151,9 +1153,34 @@ int app_config_schema(const struct cli_parsed *parsed, void *context)
cli_puts(it.node->text);
cli_delim("\n");
}
cf_om_free_node(&root);
return 0;
}
int app_config_dump(const struct cli_parsed *parsed, void *context)
{
if (config.debug.verbose)
DEBUG_cli_parsed(parsed);
if (create_serval_instance_dir() == -1)
return -1;
struct cf_om_node *root = NULL;
int ret = cf_fmt_config_main(&root, &config);
if (ret == CFERROR) {
cf_om_free_node(&root);
return -1;
}
struct cf_om_iterator it;
for (cf_om_iter_start(&it, root); it.node; cf_om_iter_next(&it))
if (it.node->text) {
cli_puts(it.node->fullkey);
cli_delim("=");
cli_puts(it.node->text);
cli_delim("\n");
}
cf_om_free_node(&root);
return ret == CFOK ? 0 : 1;
}
int app_config_set(const struct cli_parsed *parsed, void *context)
{
if (config.debug.verbose)
@ -2339,7 +2366,9 @@ struct cli_schema command_line_options[]={
{app_trace,{"mdp","trace","<SID>",NULL},0,
"Trace through the network to the specified node via MDP."},
{app_config_schema,{"config","schema",NULL},CLIFLAG_STANDALONE|CLIFLAG_PERMISSIVE_CONFIG,
"Dump configuration schema."},
"Display configuration schema."},
{app_config_dump,{"config","dump",NULL},CLIFLAG_STANDALONE|CLIFLAG_PERMISSIVE_CONFIG,
"Dump configuration settings."},
{app_config_set,{"config","set","<variable>","<value>","...",NULL},CLIFLAG_STANDALONE|CLIFLAG_PERMISSIVE_CONFIG,
"Set and del specified configuration variables."},
{app_config_set,{"config","del","<variable>","...",NULL},CLIFLAG_STANDALONE|CLIFLAG_PERMISSIVE_CONFIG,

96
conf.h
View File

@ -238,6 +238,7 @@ int cf_om_get_child(const struct cf_om_node *parent, const char *key, const char
const char *cf_om_get(const struct cf_om_node *root, const char *fullkey);
int cf_om_set(struct cf_om_node **nodep, const char *fullkey, const char *text);
int cf_om_add_child(struct cf_om_node **const parentp, const char *const key);
void cf_om_remove_child(struct cf_om_node **parent, unsigned n);
void cf_om_free_node(struct cf_om_node **nodep);
void cf_om_dump_node(const struct cf_om_node *node, int indent);
int cf_om_match(const char *pattern, const struct cf_om_node *node);
@ -393,46 +394,57 @@ struct pattern_list {
#undef VALUE_NODE_STRUCT
#undef END_ARRAY
// Generate config parser function prototypes.
// Generate config parser function prototypes: cf_opt_REPR(), cf_fmt_REPR(), cf_cmp_REPR()
#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 cf_opt_config_##__name(struct config_##__name *, const struct cf_om_node *); \
int cf_fmt_config_##__name(struct cf_om_node **, const struct config_##__name *); \
__VALIDATOR(__name, ##__validator)
#define NODE(__type, __element, __default, __repr, __flags, __comment) \
int cf_opt_##__repr(__type *, const struct cf_om_node *); \
char * cf_fmt_##__repr(const __type *);
int cf_fmt_##__repr(struct cf_om_node **, const __type *);
#define ATOM(__type, __element, __default, __repr, __flags, __comment) \
int cf_opt_##__repr(__type *, const char *); \
char * cf_fmt_##__repr(const __type *);
int cf_fmt_##__repr(const char **, const __type *);
#define STRING(__size, __element, __default, __repr, __flags, __comment) \
int cf_opt_##__repr(char *, size_t, const char *); \
char * cf_fmt_##__repr(const char *);
#define SUB_STRUCT(__name, __element, __flags) \
int cf_opt_config_##__name(struct config_##__name *, const struct cf_om_node *); \
struct cf_om_node * cf_fmt_config_##__name(struct config_##__name *);
#define NODE_STRUCT(__name, __element, __repr, __flags) \
int cf_opt_##__repr(struct config_##__name *, const struct cf_om_node *); \
struct cf_om_node * cf_fmt_##__repr(struct config_##__name *);
int cf_fmt_##__repr(const char **, const char *);
#define SUB_STRUCT(__structname, __element, __flags) \
int cf_opt_config_##__structname(struct config_##__structname *, const struct cf_om_node *); \
int cf_fmt_config_##__structname(struct cf_om_node **, const struct config_##__structname *);
#define NODE_STRUCT(__structname, __element, __repr, __flags) \
SUB_STRUCT(__structname, __element, __flags) \
int cf_opt_##__repr(struct config_##__structname *, const struct cf_om_node *); \
int cf_fmt_##__repr(struct cf_om_node **, const struct config_##__structname *);
#define END_STRUCT
#define ARRAY(__name, __flags, __validator...) \
int cf_opt_config_##__name(struct config_##__name *, const struct cf_om_node *); \
int cf_fmt_config_##__name(struct cf_om_node **, const struct config_##__name *); \
__VALIDATOR(__name, ##__validator)
#define KEY_ATOM(__type, __keyrepr, __cmpfunc...) \
int cf_opt_##__keyrepr(__type *, const char *);
int cf_opt_##__keyrepr(__type *, const char *); \
int cf_fmt_##__keyrepr(const char **, const __type *);
#define KEY_STRING(__strsize, __keyrepr, __cmpfunc...) \
int cf_opt_##__keyrepr(char *, size_t, const char *);
int cf_opt_##__keyrepr(char *, size_t, const char *); \
int cf_fmt_##__keyrepr(const char **, const char *);
#define VALUE_ATOM(__type, __eltrepr) \
int cf_opt_##__eltrepr(__type *, const char *);
int cf_opt_##__eltrepr(__type *, const char *); \
int cf_fmt_##__eltrepr(const char **, const __type *);
#define VALUE_STRING(__strsize, __eltrepr) \
int cf_opt_##__eltrepr(char *, size_t, const char *);
int cf_opt_##__eltrepr(char *, size_t, const char *); \
int cf_fmt_##__eltrepr(const char **, const char *);
#define VALUE_NODE(__type, __eltrepr) \
int cf_opt_##__eltrepr(__type *, const struct cf_om_node *);
int cf_opt_##__eltrepr(__type *, const struct cf_om_node *); \
int cf_fmt_##__eltrepr(struct cf_om_node **, const __type *);
#define VALUE_SUB_STRUCT(__structname) \
int cf_opt_config_##__structname(struct config_##__structname *, const struct cf_om_node *);
#define VALUE_NODE_STRUCT(__structname, __eltrepr) \
int cf_opt_##__eltrepr(struct config_##__structname *, const struct cf_om_node *);
int cf_opt_config_##__structname(struct config_##__structname *, const struct cf_om_node *); \
int cf_fmt_config_##__structname(struct cf_om_node **, const struct config_##__structname *);
#define VALUE_NODE_STRUCT(__structname, __repr) \
VALUE_SUB_STRUCT(__structname) \
int cf_opt_##__repr(struct config_##__structname *, const struct cf_om_node *); \
int cf_fmt_##__repr(struct cf_om_node **, const struct config_##__structname *);
#define END_ARRAY(__size)
#include "conf_schema.h"
#undef __VALIDATOR
@ -540,28 +552,72 @@ struct pattern_list {
#undef END_ARRAY
int cf_opt_char_boolean(char *booleanp, const char *text);
int cf_fmt_char_boolean(const char **, const char *booleanp);
int cf_opt_int_boolean(int *booleanp, const char *text);
int cf_fmt_int_boolean(const char **, const int *booleanp);
int cf_opt_absolute_path(char *str, size_t len, const char *text);
int cf_fmt_absolute_path(const char **, const char *path);
int cf_opt_rhizome_peer(struct config_rhizome_peer *, const struct cf_om_node *node);
int cf_fmt_rhizome_peer(struct cf_om_node **, const struct config_rhizome_peer *);
int cf_opt_rhizome_peer_from_uri(struct config_rhizome_peer *, const char *uri);
int cf_opt_str(char *str, size_t len, const char *text);
int cf_fmt_str(const char **, const char *str);
int cf_opt_str_nonempty(char *str, size_t len, const char *text);
int cf_fmt_str_nonempty(const char **, const char *str);
int cf_opt_int(int *intp, const char *text);
int cf_fmt_int(const char **, const int *intp);
int cf_opt_uint16(uint16_t *intp, const char *text);
int cf_fmt_int16(const char **, const int16_t *intp);
int cf_opt_uint16_nonzero(uint16_t *intp, const char *text);
int cf_fmt_int16_nonzero(const char **, const uint16_t *intp);
int cf_opt_int32_nonneg(int32_t *intp, const char *text);
int cf_fmt_int32_nonneg(const char **, const int32_t *intp);
int cf_opt_uint32_nonzero(uint32_t *intp, const char *text);
int cf_fmt_uint32_nonzero(const char **, const uint32_t *intp);
int cf_opt_uint64_scaled(uint64_t *intp, const char *text);
int cf_fmt_uint64_scaled(const char **, const uint64_t *intp);
int cf_opt_protocol(char *str, size_t len, const char *text);
int cf_fmt_protocol(const char **, const char *str);
int cf_opt_in_addr(struct in_addr *addrp, const char *text);
int cf_fmt_in_addr(const char **, const struct in_addr *addrp);
int cf_opt_sid(sid_t *sidp, const char *text);
int cf_fmt_sid(const char **, const sid_t *sidp);
int cf_opt_rhizome_bk(rhizome_bk_t *bkp, const char *text);
int cf_fmt_rhizome_bk(const char **, const rhizome_bk_t *bkp);
int cf_opt_interface_type(short *typep, const char *text);
int cf_fmt_interface_type(const char **, const short *typep);
int cf_opt_pattern_list(struct pattern_list *listp, const char *text);
int cf_fmt_pattern_list(const char **, const struct pattern_list *listp);
int cf_opt_network_interface(struct config_network_interface *nifp, const struct cf_om_node *node);
int cf_fmt_network_interface(struct cf_om_node **, const struct config_network_interface *nifp);
int cf_opt_interface_list(struct config_interface_list *listp, const struct cf_om_node *node);
int cf_opt_socket_type(int *typep, const char *text);
int cf_opt_encapsulation(int *typep, const char *text);
int cf_fmt_interface_list(struct cf_om_node **, const struct config_interface_list *listp);
int cf_opt_socket_type(short *typep, const char *text);
int cf_fmt_socket_type(const char **, const short *typep);
int cf_opt_encapsulation(short *encapp, const char *text);
int cf_fmt_encapsulation(const char **, const short *encapp);
extern int cf_limbo;
extern struct config_main config;

View File

@ -191,6 +191,16 @@ int cf_om_get_child(const struct cf_om_node *parent, const char *key, const char
return -1;
}
void cf_om_remove_child(struct cf_om_node **parentp, unsigned n)
{
if (n < (*parentp)->nodc && (*parentp)->nodv[n]) {
cf_om_free_node(&(*parentp)->nodv[n]);
--(*parentp)->nodc;
for (; n < (*parentp)->nodc; ++n)
(*parentp)->nodv[n] = (*parentp)->nodv[n+1];
}
}
int cf_om_parse(const char *source, const char *buf, size_t len, struct cf_om_node **rootp)
{
const char *end = buf + len;

View File

@ -415,3 +415,157 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#undef VALUE_NODE_STRUCT
#undef END_ARRAY
// Generate formatting functions, cf_fmt_config_SECTION()
#define STRUCT(__name, __validator...) \
int cf_fmt_config_##__name(struct cf_om_node **parentp, const struct config_##__name *strct) { \
DEBUGF("STRUCT(" #__name ", " #__validator ")"); \
int result = CFOK; \
int ret;
#define __HANDLE_TEXT(__elementstr) \
WHYF(" ret=%s", strbuf_str(strbuf_cf_flags(strbuf_alloca(300), ret))); \
if (ret == CFOK) { \
int n; \
if (text == NULL) { \
WHY(" text=NULL"); \
ret = CFERROR; \
} else if ((n = cf_om_add_child(parentp, __elementstr)) == -1) { \
WHY(" cf_om_add_child() returned -1"); \
ret = CFERROR; \
} else { \
(*parentp)->nodv[n]->text = text; \
text = NULL; \
} \
} \
if (text) { \
free((char *)text); \
text = NULL; \
}
#define __HANDLE_RET \
if (ret == CFERROR) \
return CFERROR; \
else if (ret != CFOK) \
result |= (ret & CF__SUBFLAGS) | CFSUB(ret & CF__FLAGS);
#define NODE(__type, __element, __default, __repr, __flags, __comment) \
DEBUGF(" NODE(" #__type ", " #__element ", " #__repr ")"); \
ret = cf_fmt_##__repr(parentp, &strct->__element); \
__HANDLE_RET
#define ATOM(__type, __element, __default, __repr, __flags, __comment) \
DEBUGF(" ATOM(" #__type ", " #__element ", " #__repr ")"); \
{ \
const char *text = NULL; \
ret = cf_fmt_##__repr(&text, &strct->__element);\
__HANDLE_TEXT(#__element) \
__HANDLE_RET \
}
#define STRING(__size, __element, __default, __repr, __flags, __comment) \
DEBUGF(" STRING(" #__size ", " #__element ", " #__repr ")"); \
{ \
const char *text = NULL; \
ret = cf_fmt_##__repr(&text, &strct->__element[0]);\
__HANDLE_TEXT(#__element) \
__HANDLE_RET \
}
#define SUB_STRUCT(__structname, __element, __flags) \
DEBUGF(" SUB_STRUCT(" #__structname ", " #__element ")"); \
ret = cf_fmt_config_##__structname(parentp, &strct->__element); \
__HANDLE_RET
#define NODE_STRUCT(__structname, __element, __repr, __flags) \
DEBUGF(" SUB_STRUCT(" #__structname ", " #__element ", " #__repr ")"); \
ret = cf_fmt_##__repr(parentp, &strct->__element); \
__HANDLE_RET
#define END_STRUCT \
if ((*parentp)->nodc == 0) \
cf_om_free_node(parentp); \
return result; \
}
#define ARRAY(__name, __flags, __validator...) \
int cf_fmt_config_##__name(struct cf_om_node **parentp, const struct config_##__name *array) { \
DEBUGF("ARRAY(" #__name ", " #__flags ", " #__validator ")"); \
int flags = (0 __flags); \
int (*eltcmp)(const struct config_##__name##__element *, const struct config_##__name##__element *) = __cmp_config_##__name; \
int result = CFOK; \
int i; \
for (i = 0; i < array->ac; ++i) { \
int ret; \
const char *key = NULL; \
int n = -1; \
struct cf_om_node *child = NULL;
#define __HANDLE_KEY \
if (key == NULL) \
ret = CFERROR; \
if (ret == CFOK) { \
if ((n = cf_om_add_child(parentp, key)) == -1) \
ret = CFERROR; \
else \
child = (*parentp)->nodv[n]; \
} \
if (key) { \
free((char *)key); \
key = NULL; \
} \
if (!child) \
continue;
#define __HANDLE_VALUE \
if (child->text == NULL) \
ret = CFERROR;
#define END_ARRAY(__size) \
if (child && child->nodc == 0) \
cf_om_remove_child(parentp, n); \
} \
if ((*parentp)->nodc == 0) \
cf_om_free_node(parentp); \
return result; \
}
#define KEY_ATOM(__type, __keyrepr, __cmpfunc...) \
DEBUGF(" KEY_ATOM(" #__type ", " #__keyrepr ", " #__cmpfunc ")"); \
ret = cf_fmt_##__keyrepr(&key, &array->av[i].key); \
__HANDLE_KEY \
__HANDLE_RET
#define KEY_STRING(__strsize, __keyrepr, __cmpfunc...) \
DEBUGF(" KEY_STRING(" #__strsize ", " #__keyrepr ", " #__cmpfunc ")"); \
ret = cf_fmt_##__keyrepr(&key, &array->av[i].key[0]); \
__HANDLE_KEY \
__HANDLE_RET
#define VALUE_ATOM(__type, __eltrepr) \
DEBUGF(" VALUE_ATOM(" #__type ", " #__eltrepr ")"); \
ret = cf_fmt_##__eltrepr(&child->text, &array->av[i].value); \
__HANDLE_VALUE \
__HANDLE_RET
#define VALUE_STRING(__strsize, __eltrepr) \
DEBUGF(" VALUE_STRING(" #__strsize ", " #__eltrepr ")"); \
ret = cf_fmt_##__eltrepr(&child->text, &array->av[i].value[0]); \
__HANDLE_VALUE \
__HANDLE_RET
#define VALUE_NODE(__type, __eltrepr) \
DEBUGF(" VALUE_NODE(" #__type ", " #__eltrepr ")"); \
ret = cf_fmt_##__eltrepr(&child, &array->av[i].value); \
__HANDLE_VALUE \
__HANDLE_RET
#define VALUE_SUB_STRUCT(__structname) \
DEBUGF(" VALUE_SUB_STRUCT(" #__structname ")"); \
ret = cf_fmt_config_##__structname(&child, &array->av[i].value); \
__HANDLE_VALUE \
__HANDLE_RET
#define VALUE_NODE_STRUCT(__structname, __eltrepr) \
DEBUGF(" VALUE_NODE_STRUCT(" #__structname ", " #__eltrepr ")"); \
ret = cf_fmt_##__eltrepr(&child, &array->av[i].value); \
__HANDLE_VALUE \
__HANDLE_RET
#include "conf_schema.h"
#undef STRUCT
#undef NODE
#undef ATOM
#undef STRING
#undef SUB_STRUCT
#undef NODE_STRUCT
#undef END_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

View File

@ -45,6 +45,19 @@ int cf_opt_char_boolean(char *booleanp, const char *text)
return CFINVALID;
}
int cf_fmt_char_boolean(const char **textp, const char *booleanp)
{
if (*booleanp == 1) {
*textp = str_edup("true");
return CFOK;
}
else if (*booleanp == 0) {
*textp = str_edup("false");
return CFOK;
}
return CFINVALID;
}
int cf_opt_int_boolean(int *booleanp, const char *text)
{
char b;
@ -54,6 +67,19 @@ int cf_opt_int_boolean(int *booleanp, const char *text)
return ret;
}
int cf_fmt_int_boolean(const char **textp, const int *booleanp)
{
if (*booleanp == 1) {
*textp = str_edup("true");
return CFOK;
}
else if (*booleanp == 0) {
*textp = str_edup("false");
return CFOK;
}
return CFINVALID;
}
int cf_opt_absolute_path(char *str, size_t len, const char *text)
{
if (text[0] != '/')
@ -65,6 +91,14 @@ int cf_opt_absolute_path(char *str, size_t len, const char *text)
return CFOK;
}
int cf_fmt_absolute_path(const char **textp, const char *str)
{
if (str[0] != '/')
return CFINVALID;
*textp = str_edup(str);
return CFOK;
}
int cf_opt_protocol(char *str, size_t len, const char *text)
{
if (!str_is_uri_scheme(text))
@ -76,6 +110,14 @@ int cf_opt_protocol(char *str, size_t len, const char *text)
return CFOK;
}
int cf_fmt_protocol(const char **textp, const char *str)
{
if (!str_is_uri_scheme(str))
return CFINVALID;
*textp = str_edup(str);
return CFOK;
}
int cf_opt_rhizome_peer(struct config_rhizome_peer *rpeer, const struct cf_om_node *node)
{
if (!node->text)
@ -87,6 +129,11 @@ int cf_opt_rhizome_peer(struct config_rhizome_peer *rpeer, const struct cf_om_no
return cf_opt_rhizome_peer_from_uri(rpeer, node->text);
}
int cf_fmt_rhizome_peer(struct cf_om_node **parentp, const struct config_rhizome_peer *rpeer)
{
return cf_fmt_config_rhizome_peer(parentp, rpeer);
}
int cf_opt_rhizome_peer_from_uri(struct config_rhizome_peer *rpeer, const char *text)
{
const char *protocol;
@ -129,6 +176,12 @@ int cf_opt_str(char *str, size_t len, const char *text)
return CFOK;
}
int cf_fmt_str(const char **textp, const char *str)
{
*textp = str_edup(str);
return CFOK;
}
int cf_opt_str_nonempty(char *str, size_t len, const char *text)
{
if (!text[0])
@ -136,6 +189,14 @@ int cf_opt_str_nonempty(char *str, size_t len, const char *text)
return cf_opt_str(str, len, text);
}
int cf_fmt_str_nonempty(const char **textp, const char *str)
{
if (!str[0])
return CFINVALID;
*textp = str_edup(str);
return CFOK;
}
int cf_opt_int(int *intp, const char *text)
{
const char *end = text;
@ -146,6 +207,14 @@ int cf_opt_int(int *intp, const char *text)
return CFOK;
}
int cf_fmt_int(const char **textp, const int *intp)
{
char buf[22];
sprintf(buf, "%d", *intp);
*textp = str_edup(buf);
return CFOK;
}
int cf_opt_uint(unsigned int *uintp, const char *text)
{
const char *end = text;
@ -156,6 +225,14 @@ int cf_opt_uint(unsigned int *uintp, const char *text)
return CFOK;
}
int cf_fmt_uint(const char **textp, const unsigned int *uintp)
{
char buf[22];
sprintf(buf, "%u", *uintp);
*textp = str_edup(buf);
return CFOK;
}
int cf_opt_int32_nonneg(int32_t *intp, const char *text)
{
const char *end = text;
@ -166,6 +243,29 @@ int cf_opt_int32_nonneg(int32_t *intp, const char *text)
return CFOK;
}
static int cf_fmt_int32(const char **textp, const int32_t *intp)
{
char buf[12];
sprintf(buf, "%d", *intp);
*textp = str_edup(buf);
return CFOK;
}
static int cf_fmt_uint32(const char **textp, const uint32_t *uintp)
{
char buf[12];
sprintf(buf, "%u", *uintp);
*textp = str_edup(buf);
return CFOK;
}
int cf_fmt_int32_nonneg(const char **textp, const int32_t *intp)
{
if (*intp < 0)
return CFINVALID;
return cf_fmt_int32(textp, intp);
}
int cf_opt_uint32_nonzero(uint32_t *intp, const char *text)
{
const char *end = text;
@ -176,6 +276,13 @@ int cf_opt_uint32_nonzero(uint32_t *intp, const char *text)
return CFOK;
}
int cf_fmt_uint32_nonzero(const char **textp, const uint32_t *uintp)
{
if (*uintp == 0)
return CFINVALID;
return cf_fmt_uint32(textp, uintp);
}
int cf_opt_uint64_scaled(uint64_t *intp, const char *text)
{
uint64_t result;
@ -186,6 +293,15 @@ int cf_opt_uint64_scaled(uint64_t *intp, const char *text)
return CFOK;
}
int cf_fmt_uint64_scaled(const char **textp, const uint64_t *uintp)
{
char buf[25];
int n = uint64_scaled_to_str(buf, sizeof buf, *uintp);
assert(n != 0);
*textp = str_edup(buf);
return CFOK;
}
int cf_opt_ushort_nonzero(unsigned short *ushortp, const char *text)
{
uint32_t ui;
@ -195,6 +311,21 @@ int cf_opt_ushort_nonzero(unsigned short *ushortp, const char *text)
return CFOK;
}
int cf_fmt_ushort(const char **textp, const unsigned short *ushortp)
{
char buf[12];
sprintf(buf, "%u", (unsigned int) *ushortp);
*textp = str_edup(buf);
return CFOK;
}
int cf_fmt_ushort_nonzero(const char **textp, const unsigned short *ushortp)
{
if (*ushortp == 0)
return CFINVALID;
return cf_fmt_ushort(textp, ushortp);
}
int cmp_short(const short *a, const short *b)
{
return *a < *b ? -1 : *a > *b ? 1 : 0;
@ -255,7 +386,13 @@ int cf_opt_in_addr(struct in_addr *addrp, const char *text)
return CFOK;
}
int cf_opt_uint16(uint16_t *intp, const char *text)
int cf_fmt_in_addr(const char **textp, const struct in_addr *addrp)
{
*textp = str_edup(inet_ntoa(*addrp));
return CFOK;
}
int cf_opt_uint16(uint16_t *uintp, const char *text)
{
uint16_t ui = 0;
const char *p;
@ -267,19 +404,34 @@ int cf_opt_uint16(uint16_t *intp, const char *text)
}
if (*p)
return CFINVALID;
*intp = ui;
*uintp = ui;
return CFOK;
}
int cf_opt_uint16_nonzero(uint16_t *intp, const char *text)
int cf_fmt_uint16(const char **textp, const uint16_t *uintp)
{
char buf[12];
sprintf(buf, "%u", (unsigned int) *uintp);
*textp = str_edup(buf);
return CFOK;
}
int cf_opt_uint16_nonzero(uint16_t *uintp, const char *text)
{
uint16_t ui;
if (cf_opt_uint16(&ui, text) != CFOK || ui == 0)
return CFINVALID;
*intp = ui;
*uintp = ui;
return CFOK;
}
int cf_fmt_uint16_nonzero(const char **textp, const uint16_t *uintp)
{
if (*uintp == 0)
return CFINVALID;
return cf_fmt_uint16(textp, uintp);
}
int cf_opt_sid(sid_t *sidp, const char *text)
{
if (!str_is_subscriber_id(text))
@ -289,6 +441,12 @@ int cf_opt_sid(sid_t *sidp, const char *text)
return CFOK;
}
int cf_fmt_sid(const char **textp, const sid_t *sidp)
{
*textp = str_edup(alloca_tohex_sid_t(*sidp));
return CFOK;
}
int cf_opt_rhizome_bk(rhizome_bk_t *bkp, const char *text)
{
if (!rhizome_str_is_bundle_key(text))
@ -298,6 +456,12 @@ int cf_opt_rhizome_bk(rhizome_bk_t *bkp, const char *text)
return CFOK;
}
int cf_fmt_rhizome_bk(const char **textp, const rhizome_bk_t *bkp)
{
*textp = str_edup(alloca_tohex_rhizome_bk_t(*bkp));
return CFOK;
}
int cf_opt_interface_type(short *typep, const char *text)
{
if (strcasecmp(text, "ethernet") == 0) {
@ -319,7 +483,22 @@ int cf_opt_interface_type(short *typep, const char *text)
return CFINVALID;
}
int cf_opt_socket_type(int *typep, const char *text)
int cf_fmt_interface_type(const char **textp, const short *typep)
{
const char *t = NULL;
switch (*typep) {
case OVERLAY_INTERFACE_ETHERNET: t = "ethernet"; break;
case OVERLAY_INTERFACE_WIFI: t = "wifi"; break;
case OVERLAY_INTERFACE_PACKETRADIO: t = "catear"; break;
case OVERLAY_INTERFACE_UNKNOWN: t = "other"; break;
}
if (!t)
return CFINVALID;
*textp = str_edup(t);
return CFOK;
}
int cf_opt_socket_type(short *typep, const char *text)
{
if (strcasecmp(text, "dgram") == 0) {
*typep = SOCK_DGRAM;
@ -336,19 +515,46 @@ int cf_opt_socket_type(int *typep, const char *text)
return CFINVALID;
}
int cf_opt_encapsulation(int *typep, const char *text)
int cf_fmt_socket_type(const char **textp, const short *typep)
{
const char *t = NULL;
switch (*typep) {
case SOCK_DGRAM: t = "dgram"; break;
case SOCK_STREAM: t = "stream"; break;
case SOCK_FILE: t = "file"; break;
}
if (!t)
return CFINVALID;
*textp = str_edup(t);
return CFOK;
}
int cf_opt_encapsulation(short *encapp, const char *text)
{
if (strcasecmp(text, "overlay") == 0) {
*typep = ENCAP_OVERLAY;
*encapp = ENCAP_OVERLAY;
return CFOK;
}
if (strcasecmp(text, "single") == 0) {
*typep = ENCAP_SINGLE;
*encapp = ENCAP_SINGLE;
return CFOK;
}
return CFINVALID;
}
int cf_fmt_encapsulation(const char **textp, const short *encapp)
{
const char *t = NULL;
switch (*encapp) {
case ENCAP_OVERLAY: t = "overlay"; break;
case ENCAP_SINGLE: t = "single"; break;
}
if (!t)
return CFINVALID;
*textp = str_edup(t);
return CFOK;
}
int cf_opt_pattern_list(struct pattern_list *listp, const char *text)
{
struct pattern_list list;
@ -374,6 +580,24 @@ int cf_opt_pattern_list(struct pattern_list *listp, const char *text)
return CFOK;
}
int cf_fmt_pattern_list(const char **textp, const struct pattern_list *listp)
{
char buf[sizeof listp->patv];
char *bufp = buf;
unsigned i;
for (i = 0; i < listp->patc; ++i) {
if (bufp != buf)
*bufp++ = ',';
const char *patvp = listp->patv[i];
const char *npatvp = listp->patv[i + 1];
while (bufp < &buf[sizeof buf - 1] && patvp < npatvp && (*bufp = *patvp))
++bufp, ++patvp;
if (bufp >= &buf[sizeof buf - 1] || patvp >= npatvp)
return CFINVALID;
}
*textp = str_edup(buf);
return CFOK;
}
/* Config parse function. Implements the original form of the 'interfaces' config option. Parses a
* single text string of the form:
@ -490,6 +714,11 @@ int cf_opt_network_interface(struct config_network_interface *nifp, const struct
return cf_opt_network_interface_legacy(nifp, node->text);
}
int cf_fmt_network_interface(struct cf_om_node **parentp, const struct config_network_interface *nifp)
{
return cf_fmt_config_network_interface(parentp, nifp);
}
int vld_network_interface(const struct cf_om_node *parent, struct config_network_interface *nifp, int result)
{
if (nifp->match.patc != 0 && nifp->file[0]) {
@ -500,19 +729,17 @@ int vld_network_interface(const struct cf_om_node *parent, struct config_network
cf_warn_incompatible(parent->nodv[nodei_match], parent->nodv[nodei_file]);
return result | CFSUB(CFINCOMPATIBLE);
}
if (nifp->socket_type == SOCK_UNSPECIFIED){
if (nifp->socket_type == SOCK_UNSPECIFIED) {
if (nifp->match.patc != 0)
nifp->socket_type=SOCK_DGRAM;
nifp->socket_type = SOCK_DGRAM;
else if (nifp->file[0])
nifp->socket_type=SOCK_FILE;
else{
nifp->socket_type = SOCK_FILE;
else {
cf_warn_missing_node(parent, "match");
return result | CFINCOMPLETE;
}
}else{
if (nifp->socket_type==SOCK_DGRAM && nifp->file[0]){
} else {
if (nifp->socket_type == SOCK_DGRAM && nifp->file[0]){
int nodei_socket_type = cf_om_get_child(parent, "socket_type", NULL);
int nodei_file = cf_om_get_child(parent, "file", NULL);
assert(nodei_socket_type != -1);
@ -520,13 +747,11 @@ int vld_network_interface(const struct cf_om_node *parent, struct config_network
cf_warn_incompatible(parent->nodv[nodei_socket_type], parent->nodv[nodei_file]);
return result | CFSUB(CFINCOMPATIBLE);
}
if (nifp->socket_type!=SOCK_DGRAM && !nifp->file[0]){
if (nifp->socket_type != SOCK_DGRAM && !nifp->file[0]){
cf_warn_missing_node(parent, "file");
return result | CFSUB(CFINCOMPATIBLE);
}
}
return result;
}
@ -592,3 +817,8 @@ bye:
result |= CFEMPTY;
return result;
}
int cf_fmt_interface_list(struct cf_om_node **parentp, const struct config_interface_list *listp)
{
return cf_fmt_config_interface_list(parentp, listp);
}

View File

@ -353,8 +353,8 @@ END_ARRAY(32)
STRUCT(network_interface, vld_network_interface)
ATOM(int, exclude, 0, int_boolean,, "If true, do not use matching interfaces")
ATOM(struct pattern_list, match, PATTERN_LIST_EMPTY, pattern_list,, "Names that match network interface")
ATOM(int, socket_type, SOCK_UNSPECIFIED, socket_type,, "Type of network socket")
ATOM(int, encapsulation, ENCAP_OVERLAY, encapsulation,, "Type of packet encapsulation")
ATOM(short, socket_type, SOCK_UNSPECIFIED, socket_type,, "Type of network socket")
ATOM(short, encapsulation, ENCAP_OVERLAY, encapsulation,, "Type of packet encapsulation")
STRING(256, file, "", str_nonempty,, "Path of interface file, absolute or relative to server.interface_path")
ATOM(struct in_addr, dummy_address, hton_in_addr(INADDR_LOOPBACK), in_addr,, "Dummy interface address")
ATOM(struct in_addr, dummy_netmask, hton_in_addr(0xFFFFFF00), in_addr,, "Dummy interface netmask")

View File

@ -61,6 +61,8 @@ __RHIZOME_INLINE int rhizome_is_bk_none(const rhizome_bk_t *bk) {
return is_all_matching(bk->binary, sizeof bk->binary, 0);
}
#define alloca_tohex_rhizome_bk_t(bk) alloca_tohex((bk).binary, sizeof (*(rhizome_bk_t*)0).binary)
extern time_ms_t rhizome_voice_timeout;
#define RHIZOME_PRIORITY_HIGHEST RHIZOME_PRIORITY_SERVAL_CORE