Index sequence items - allows us to store sequences of mappings in the configuration database.

remotes/origin/master-1.0.x
Jason Ish 16 years ago committed by Victor Julien
parent 0a85fd6787
commit 59ec05645f

@ -27,6 +27,11 @@
* values. */ * values. */
#define MAX_LEVELS 16 #define MAX_LEVELS 16
/* Sometimes we'll have to create a node name on the fly (integer
* conversion, etc), so this is a default length to allocate that will
* work most of the time. */
#define DEFAULT_NAME_LEN 16
/* Configuration processing states. */ /* Configuration processing states. */
enum conf_state { enum conf_state {
CONF_KEY = 0, CONF_KEY = 0,
@ -77,15 +82,15 @@ GetKeyName(char **key, int level)
* *
* \param parser A pointer to an active yaml_parser_t. * \param parser A pointer to an active yaml_parser_t.
* \param parent The parent configuration node. * \param parent The parent configuration node.
* \param init_state State to start off as.
*/ */
static void static void
ConfYamlParse2(yaml_parser_t *parser, ConfNode *parent, int init_state) ConfYamlParse2(yaml_parser_t *parser, ConfNode *parent, int inseq)
{ {
ConfNode *node = parent; ConfNode *node = parent;
yaml_event_t event; yaml_event_t event;
int done = 0; int done = 0;
int state = init_state; int state = 0;
int seq_idx = 0;
while (!done) { while (!done) {
if (!yaml_parser_parse(parser, &event)) { if (!yaml_parser_parse(parser, &event)) {
@ -95,41 +100,44 @@ ConfYamlParse2(yaml_parser_t *parser, ConfNode *parent, int init_state)
} }
if (event.type == YAML_SCALAR_EVENT) { if (event.type == YAML_SCALAR_EVENT) {
if (state) { char *value = (char *)event.data.scalar.value;
ConfNode *new; if (inseq) {
new = ConfNodeNew(); ConfNode *seq_node = ConfNodeNew();
if (new == NULL) { seq_node->name = calloc(1, DEFAULT_NAME_LEN);
SCLogError(SC_ERR_MEM_ALLOC, snprintf(seq_node->name, DEFAULT_NAME_LEN, "%d", seq_idx++);
"Failed to allocate memory for new configuration node."); seq_node->val = strdup(value);
exit(EXIT_FAILURE); TAILQ_INSERT_TAIL(&parent->head, seq_node, next);
}
new->val = strdup((char *)event.data.scalar.value);
TAILQ_INSERT_TAIL(&node->head, new, next);
} }
else { else {
node = ConfNodeNew(); if (state == CONF_KEY) {
if (node == NULL) { node = ConfNodeNew();
SCLogError(SC_ERR_MEM_ALLOC, node->name = strdup((char *)event.data.scalar.value);
"Failed to allocate memory for new configuration node."); TAILQ_INSERT_TAIL(&parent->head, node, next);
exit(EXIT_FAILURE); state = CONF_VAL;
}
else {
node->val = strdup((char *)event.data.scalar.value);
state = CONF_KEY;
} }
node->val = strdup((char *)event.data.scalar.value);
TAILQ_INSERT_TAIL(&parent->head, node, next);
} }
state ^= CONF_VAL;
} }
else if (event.type == YAML_SEQUENCE_START_EVENT) { else if (event.type == YAML_SEQUENCE_START_EVENT) {
state = CONF_SEQ; state = CONF_SEQ;
} }
else if (event.type == YAML_SEQUENCE_END_EVENT) { else if (event.type == YAML_SEQUENCE_END_EVENT) {
state = CONF_KEY; return;
/* Only b/c we called from the old parser... */
if (init_state != CONF_KEY)
return;
} }
else if (event.type == YAML_MAPPING_START_EVENT) { else if (event.type == YAML_MAPPING_START_EVENT) {
ConfYamlParse2(parser, node, 0); if (inseq) {
ConfNode *seq_node = ConfNodeNew();
seq_node->name = calloc(1, DEFAULT_NAME_LEN);
snprintf(seq_node->name, DEFAULT_NAME_LEN, "%d", seq_idx++);
TAILQ_INSERT_TAIL(&node->head, seq_node, next);
ConfYamlParse2(parser, seq_node, 0);
}
else {
ConfYamlParse2(parser, node, inseq);
}
state ^= CONF_VAL; state ^= CONF_VAL;
} }
else if (event.type == YAML_MAPPING_END_EVENT) { else if (event.type == YAML_MAPPING_END_EVENT) {
@ -187,13 +195,8 @@ ConfYamlParse(yaml_parser_t *parser)
case YAML_SEQUENCE_START_EVENT: { case YAML_SEQUENCE_START_EVENT: {
ConfNode *new; ConfNode *new;
new = ConfNodeNew(); new = ConfNodeNew();
if (new == NULL) {
SCLogError(SC_ERR_MEM_ALLOC,
"Failed to allocate new configuration node.");
exit(EXIT_FAILURE);
}
new->name = strdup(GetKeyName(key, level)); new->name = strdup(GetKeyName(key, level));
ConfYamlParse2(parser, new, CONF_SEQ); ConfYamlParse2(parser, new, 1);
ConfSetNode(new); ConfSetNode(new);
state = CONF_KEY; state = CONF_KEY;
break; break;
@ -292,9 +295,6 @@ static int
ConfYamlRuleFileTest(void) ConfYamlRuleFileTest(void)
{ {
char input[] = "\ char input[] = "\
some-other-list:\n\
- one\n\
- two\n\
rule-files:\n\ rule-files:\n\
- netbios.rules\n\ - netbios.rules\n\
- x11.rules\n\ - x11.rules\n\
@ -329,6 +329,73 @@ default-log-dir: /tmp\n\
return 1; return 1;
} }
static int
ConfYamlLoggingOutputTest(void)
{
char input[] = "\
logging:\n\
output:\n\
- interface: console\n\
log-level: error\n\
- interface: syslog\n\
facility: local4\n\
log-level: info\n\
";
ConfYamlLoadString(input, strlen(input));
ConfNode *outputs;
outputs = ConfGetNode("logging.output");
if (outputs == NULL)
return 0;
ConfNode *output;
ConfNode *output_param;
output = TAILQ_FIRST(&outputs->head);
if (output == NULL)
return 0;
if (strcmp(output->name, "0") != 0)
return 0;
output_param = TAILQ_FIRST(&output->head);
if (output_param == NULL)
return 0;
if (strcmp(output_param->name, "interface") != 0)
return 0;
if (strcmp(output_param->val, "console") != 0)
return 0;
output_param = TAILQ_NEXT(output_param, next);
if (strcmp(output_param->name, "log-level") != 0)
return 0;
if (strcmp(output_param->val, "error") != 0)
return 0;
output = TAILQ_NEXT(output, next);
if (output == NULL)
return 0;
if (strcmp(output->name, "1") != 0)
return 0;
output_param = TAILQ_FIRST(&output->head);
if (output_param == NULL)
return 0;
if (strcmp(output_param->name, "interface") != 0)
return 0;
if (strcmp(output_param->val, "syslog") != 0)
return 0;
output_param = TAILQ_NEXT(output_param, next);
if (strcmp(output_param->name, "facility") != 0)
return 0;
if (strcmp(output_param->val, "local4") != 0)
return 0;
output_param = TAILQ_NEXT(output_param, next);
if (strcmp(output_param->name, "log-level") != 0)
return 0;
if (strcmp(output_param->val, "info") != 0)
return 0;
return 1;
}
#endif /* UNITTESTS */ #endif /* UNITTESTS */
void void
@ -336,5 +403,6 @@ ConfYamlRegisterTests(void)
{ {
#ifdef UNITTESTS #ifdef UNITTESTS
UtRegisterTest("ConfYamlRuleFileTest", ConfYamlRuleFileTest, 1); UtRegisterTest("ConfYamlRuleFileTest", ConfYamlRuleFileTest, 1);
UtRegisterTest("ConfYamlLoggingOutputTest", ConfYamlLoggingOutputTest, 1);
#endif /* UNITTESTS */ #endif /* UNITTESTS */
} }

@ -125,8 +125,11 @@ ConfNodeNew(void)
ConfNode *new; ConfNode *new;
new = calloc(1, sizeof(*new)); new = calloc(1, sizeof(*new));
if (new == NULL) if (new == NULL) {
return NULL; SCLogError(SC_ERR_MEM_ALLOC,
"Error allocating memory for new configuration node");
exit(EXIT_FAILURE);
}
TAILQ_INIT(&new->head); TAILQ_INIT(&new->head);
return new; return new;
@ -393,6 +396,19 @@ ConfDeInit(void)
SCLogDebug("configuration module de-initialized"); SCLogDebug("configuration module de-initialized");
} }
void
ConfNodeDump(ConfNode *node)
{
ConfNode *child;
int idx = 0;
TAILQ_FOREACH(child, &node->head, next) {
printf("%s = %s\n", child->name, child->val);
if (child->val == NULL)
ConfNodeDump(child);
}
}
/** /**
* \brief Dump configuration to stdout. * \brief Dump configuration to stdout.
*/ */

Loading…
Cancel
Save