|
|
|
@ -2,7 +2,7 @@
|
|
|
|
|
#include "condition.h"
|
|
|
|
|
#include "config_parser.h"
|
|
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
#if 1
|
|
|
|
|
#define _printf(fmt, ...) g_print(fmt, __VA_ARGS__)
|
|
|
|
|
#else
|
|
|
|
|
#define _printf(fmt, ...) /* */
|
|
|
|
@ -80,7 +80,7 @@
|
|
|
|
|
|
|
|
|
|
g_string_free(str, TRUE);
|
|
|
|
|
|
|
|
|
|
_printf("got int with suffix: %d\n", o->data.number);
|
|
|
|
|
_printf("got int with suffix: %" G_GINT64_FORMAT "\n", o->data.number);
|
|
|
|
|
|
|
|
|
|
/* make sure there was no overflow that led to negative numbers */
|
|
|
|
|
if (o->data.number < 0) {
|
|
|
|
@ -306,7 +306,7 @@
|
|
|
|
|
|
|
|
|
|
if (r->type == VALUE_STRING && ctx->value_op == '+') {
|
|
|
|
|
/* str + str */
|
|
|
|
|
o->data.string = g_string_append_len(o->data.string, r->data.string->str, r->data.string->len);
|
|
|
|
|
o->data.string = g_string_append_len(o->data.string, GSTR_LEN(r->data.string));
|
|
|
|
|
}
|
|
|
|
|
else if (r->type == VALUE_NUMBER && ctx->value_op == '+') {
|
|
|
|
|
/* str + int */
|
|
|
|
@ -343,21 +343,11 @@
|
|
|
|
|
}
|
|
|
|
|
else if (ctx->value_op == '*') {
|
|
|
|
|
/* merge l and r */
|
|
|
|
|
//GArray *a;
|
|
|
|
|
//free_l = free_r = FALSE;
|
|
|
|
|
//o = l;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//a = g_array_sized_new(FALSE, FALSE, sizeof(value*), r->list->len);
|
|
|
|
|
//a = g_array_append_vals(a, r->list->data, r->list->len); /* copy old list from r to a */
|
|
|
|
|
//o->list = g_array_append_vals(o->list, a->data, a->len); /* append data from a to o */
|
|
|
|
|
//g_array_free(a, FALSE); /* free a but not the data because it is now in o */
|
|
|
|
|
|
|
|
|
|
if (r->type == VALUE_LIST) {
|
|
|
|
|
/* merge lists */
|
|
|
|
|
free_l = FALSE;
|
|
|
|
|
g_array_append_vals(l->data.list, r->data.list->data, r->data.list->len);
|
|
|
|
|
r->type = VALUE_NONE;
|
|
|
|
|
g_array_set_size(r->data.list, 0);
|
|
|
|
|
o = l;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -415,6 +405,8 @@
|
|
|
|
|
|
|
|
|
|
o = g_queue_pop_head(ctx->option_stack);
|
|
|
|
|
|
|
|
|
|
_printf("got actionref: %s in line %zd\n", o->data.string->str, ctx->line);
|
|
|
|
|
|
|
|
|
|
/* action refs starting with "var." are user defined variables */
|
|
|
|
|
if (g_str_has_prefix(o->data.string->str, "var.")) {
|
|
|
|
|
/* look up var in hashtable, copy and push value onto stack */
|
|
|
|
@ -486,15 +478,27 @@
|
|
|
|
|
|
|
|
|
|
assert(name->type == VALUE_STRING);
|
|
|
|
|
|
|
|
|
|
_printf("got assignment: %s = %s; in line %zd\n", name->string->str, value_type_string(val->type), ctx->line);
|
|
|
|
|
_printf("got assignment: %s = %s; in line %zd\n", name->data.string->str, value_type_string(val->type), ctx->line);
|
|
|
|
|
|
|
|
|
|
if (ctx->in_setup_block) {
|
|
|
|
|
/* in setup { } block => set default values for options */
|
|
|
|
|
/* todo name */
|
|
|
|
|
/* TODO */
|
|
|
|
|
}
|
|
|
|
|
else if (g_str_has_prefix(name->data.string->str, "var.")) {
|
|
|
|
|
/* assignment vor user defined variable, insert into hashtable */
|
|
|
|
|
g_hash_table_insert(ctx->uservars, name->data.string, val);
|
|
|
|
|
gpointer old_key;
|
|
|
|
|
gpointer old_val;
|
|
|
|
|
GString *str = value_extract(name).string;
|
|
|
|
|
|
|
|
|
|
/* free old key and value if we are overwriting it */
|
|
|
|
|
if (g_hash_table_lookup_extended(ctx->uservars, str, &old_key, &old_val)) {
|
|
|
|
|
g_hash_table_remove(ctx->uservars, str);
|
|
|
|
|
g_string_free(old_key, TRUE);
|
|
|
|
|
value_free(old_val);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_hash_table_insert(ctx->uservars, str, val);
|
|
|
|
|
val = NULL; /* prevent free */
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* normal assignment */
|
|
|
|
@ -505,8 +509,10 @@
|
|
|
|
|
|
|
|
|
|
al = g_queue_peek_head(ctx->action_list_stack);
|
|
|
|
|
g_array_append_val(al->data.list, a);
|
|
|
|
|
value_free(name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
value_free(name);
|
|
|
|
|
value_free(val);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
action function_noparam {
|
|
|
|
@ -517,7 +523,7 @@
|
|
|
|
|
|
|
|
|
|
assert(name->type == VALUE_STRING);
|
|
|
|
|
|
|
|
|
|
_printf("got function: %s; in line %zd\n", name->string->str, ctx->line);
|
|
|
|
|
_printf("got function: %s; in line %zd\n", name->data.string->str, ctx->line);
|
|
|
|
|
|
|
|
|
|
if (g_str_equal(name->data.string->str, "break")) {
|
|
|
|
|
}
|
|
|
|
@ -539,6 +545,8 @@
|
|
|
|
|
|
|
|
|
|
g_array_append_val(al->data.list, a);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
value_free(name);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -553,7 +561,7 @@
|
|
|
|
|
|
|
|
|
|
assert(name->type == VALUE_STRING);
|
|
|
|
|
|
|
|
|
|
_printf("got function: %s %s; in line %zd\n", name->string->str, value_type_string(val->type), ctx->line);
|
|
|
|
|
_printf("got function: %s %s; in line %zd\n", name->data.string->str, value_type_string(val->type), ctx->line);
|
|
|
|
|
|
|
|
|
|
if (g_str_equal(name->data.string->str, "include")) {
|
|
|
|
|
if (val->type != VALUE_STRING) {
|
|
|
|
@ -583,6 +591,7 @@
|
|
|
|
|
GString *tmpstr = value_to_string(val);
|
|
|
|
|
g_printerr("%s:%zd type: %s, value: %s\n", ctx->filename, ctx->line, value_type_string(val->type), tmpstr->str);
|
|
|
|
|
g_string_free(tmpstr, TRUE);
|
|
|
|
|
value_free(val);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* normal function action */
|
|
|
|
@ -624,7 +633,7 @@
|
|
|
|
|
|
|
|
|
|
assert(n->type == VALUE_STRING);
|
|
|
|
|
|
|
|
|
|
_printf("got condition: %s:%s %s %s in line %zd\n", n->string->str, ctx->condition_with_key ? k->string->str : "", comp_op_to_string(ctx->op), value_type_string(v->type), ctx->line);
|
|
|
|
|
_printf("got condition: %s:%s %s %s in line %zd\n", n->data.string->str, ctx->condition_with_key ? k->data.string->str : "", comp_op_to_string(ctx->op), value_type_string(v->type), ctx->line);
|
|
|
|
|
|
|
|
|
|
/* create condition lvalue */
|
|
|
|
|
str = n->data.string->str;
|
|
|
|
@ -655,7 +664,7 @@
|
|
|
|
|
log_warning(srv, NULL, "%s", "header conditional needs a key");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
lvalue = condition_lvalue_new(COMP_REQUEST_HEADER, k->data.string);
|
|
|
|
|
lvalue = condition_lvalue_new(COMP_REQUEST_HEADER, value_extract(k).string);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
log_warning(srv, NULL, "unkown lvalue for condition: %s", n->data.string->str);
|
|
|
|
@ -690,10 +699,10 @@
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (v->type == VALUE_STRING) {
|
|
|
|
|
cond = condition_new_string(srv, ctx->op, lvalue, v->data.string);
|
|
|
|
|
cond = condition_new_string(srv, ctx->op, lvalue, value_extract(v).string);
|
|
|
|
|
}
|
|
|
|
|
else if (v->type == VALUE_NUMBER)
|
|
|
|
|
cond = condition_new_int(srv, ctx->op, lvalue, (gint64) v->data.number);
|
|
|
|
|
cond = condition_new_int(srv, ctx->op, lvalue, value_extract_number(v));
|
|
|
|
|
else {
|
|
|
|
|
cond = NULL;
|
|
|
|
|
}
|
|
|
|
@ -709,6 +718,9 @@
|
|
|
|
|
g_queue_push_head(ctx->action_list_stack, action_new_list());
|
|
|
|
|
|
|
|
|
|
/* TODO: free stuff */
|
|
|
|
|
value_free(n);
|
|
|
|
|
value_free(k);
|
|
|
|
|
value_free(v);
|
|
|
|
|
ctx->condition_with_key = FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -806,7 +818,7 @@
|
|
|
|
|
else {
|
|
|
|
|
GString *str;
|
|
|
|
|
|
|
|
|
|
_printf("action block %s in line %zd\n", o->string->str, ctx->line);
|
|
|
|
|
_printf("action block %s in line %zd\n", o->data.string->str, ctx->line);
|
|
|
|
|
|
|
|
|
|
/* create new action list and put it on the stack */
|
|
|
|
|
al = action_new_list();
|
|
|
|
@ -904,7 +916,7 @@ GList *config_parser_init(server* srv) {
|
|
|
|
|
return g_list_append(NULL, ctx);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void config_parser_finish(server *srv, GList *ctx_stack) {
|
|
|
|
|
void config_parser_finish(server *srv, GList *ctx_stack, gboolean free_all) {
|
|
|
|
|
config_parser_context_t *ctx;
|
|
|
|
|
GHashTableIter iter;
|
|
|
|
|
gpointer key, val;
|
|
|
|
@ -912,37 +924,41 @@ void config_parser_finish(server *srv, GList *ctx_stack) {
|
|
|
|
|
_printf("ctx_stack size: %u\n", g_list_length(ctx_stack));
|
|
|
|
|
|
|
|
|
|
/* clear all contexts from the stack */
|
|
|
|
|
while ((ctx = g_list_nth_data(ctx_stack, 1)) != NULL) {
|
|
|
|
|
GList *l = g_list_nth(ctx_stack, 1);
|
|
|
|
|
while (l) {
|
|
|
|
|
ctx = l->data;
|
|
|
|
|
config_parser_context_free(srv, ctx, FALSE);
|
|
|
|
|
l = l->next;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ctx = (config_parser_context_t*) ctx_stack->data;
|
|
|
|
|
|
|
|
|
|
g_hash_table_iter_init(&iter, ctx->action_blocks);
|
|
|
|
|
if (free_all) {
|
|
|
|
|
ctx = (config_parser_context_t*) ctx_stack->data;
|
|
|
|
|
|
|
|
|
|
while (g_hash_table_iter_next(&iter, &key, &val)) {
|
|
|
|
|
g_hash_table_iter_steal(&iter);
|
|
|
|
|
g_string_free(key, TRUE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_hash_table_destroy(ctx->action_blocks);
|
|
|
|
|
g_hash_table_iter_init(&iter, ctx->action_blocks);
|
|
|
|
|
|
|
|
|
|
while (g_hash_table_iter_next(&iter, &key, &val)) {
|
|
|
|
|
action_release(srv, val);
|
|
|
|
|
g_string_free(key, TRUE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_hash_table_destroy(ctx->action_blocks);
|
|
|
|
|
|
|
|
|
|
g_hash_table_iter_init(&iter, ctx->uservars);
|
|
|
|
|
g_hash_table_iter_init(&iter, ctx->uservars);
|
|
|
|
|
|
|
|
|
|
while (g_hash_table_iter_next(&iter, &key, &val)) {
|
|
|
|
|
g_hash_table_iter_steal(&iter);
|
|
|
|
|
g_string_free(key, TRUE);
|
|
|
|
|
}
|
|
|
|
|
while (g_hash_table_iter_next(&iter, &key, &val)) {
|
|
|
|
|
value_free(val);
|
|
|
|
|
g_string_free(key, TRUE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_hash_table_destroy(ctx->uservars);
|
|
|
|
|
g_hash_table_destroy(ctx->uservars);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
config_parser_context_free(srv, ctx, TRUE);
|
|
|
|
|
config_parser_context_free(srv, ctx, TRUE);
|
|
|
|
|
|
|
|
|
|
g_list_free(ctx_stack);
|
|
|
|
|
g_list_free(ctx_stack);
|
|
|
|
|
srv->mainaction = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
config_parser_context_t *config_parser_context_new(server *srv, GList *ctx_stack) {
|
|
|
|
@ -1015,8 +1031,15 @@ void config_parser_context_free(server *srv, config_parser_context_t *ctx, gbool
|
|
|
|
|
value_free(o);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (g_queue_get_length(ctx->condition_stack) > 0) {
|
|
|
|
|
condition *c;
|
|
|
|
|
while ((c = g_queue_pop_head(ctx->condition_stack)))
|
|
|
|
|
condition_release(srv, c);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_queue_free(ctx->action_list_stack);
|
|
|
|
|
g_queue_free(ctx->option_stack);
|
|
|
|
|
g_queue_free(ctx->condition_stack);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_slice_free(config_parser_context_t, ctx);
|
|
|
|
|