implemented port feature for listen setup; small memleak und config parser fixes
parent
e1504a252f
commit
5150637e13
|
@ -2,7 +2,7 @@
|
|||
#include "condition.h"
|
||||
#include "config_parser.h"
|
||||
|
||||
#if 1
|
||||
#if 0
|
||||
#define _printf(fmt, ...) g_print(fmt, __VA_ARGS__)
|
||||
#else
|
||||
#define _printf(fmt, ...) /* */
|
||||
|
@ -46,7 +46,7 @@
|
|||
|
||||
action integer {
|
||||
value *o;
|
||||
guint i = 0;
|
||||
gint64 i = 0;
|
||||
|
||||
for (gchar *c = ctx->mark; c < fpc; c++)
|
||||
i = i * 10 + *c - 48;
|
||||
|
@ -55,7 +55,7 @@
|
|||
/* push value onto stack */
|
||||
g_queue_push_head(ctx->option_stack, o);
|
||||
|
||||
_printf("got integer %d in line %zd\n", i, ctx->line);
|
||||
_printf("got integer %" G_GINT64_FORMAT " in line %zd\n", i, ctx->line);
|
||||
}
|
||||
|
||||
action integer_suffix {
|
||||
|
@ -69,10 +69,12 @@
|
|||
if (g_str_equal(str->str, "kbyte")) o->data.number *= 1024;
|
||||
else if (g_str_equal(str->str, "mbyte")) o->data.number *= 1024 * 1024;
|
||||
else if (g_str_equal(str->str, "gbyte")) o->data.number *= 1024 * 1024 * 1024;
|
||||
else if (g_str_equal(str->str, "tbyte")) o->data.number *= 1024 * 1024 * 1024 * G_GINT64_CONSTANT(1024);
|
||||
|
||||
else if (g_str_equal(str->str, "kbit")) o->data.number *= 1000;
|
||||
else if (g_str_equal(str->str, "mbit")) o->data.number *= 1000 * 1000;
|
||||
else if (g_str_equal(str->str, "gbit")) o->data.number *= 1000 * 1000 * 1000;
|
||||
else if (g_str_equal(str->str, "tbit")) o->data.number *= 1000 * 1000 * 1000 * G_GINT64_CONSTANT(1000);
|
||||
|
||||
else if (g_str_equal(str->str, "min")) o->data.number *= 60;
|
||||
else if (g_str_equal(str->str, "hours")) o->data.number *= 60 * 60;
|
||||
|
@ -81,12 +83,6 @@
|
|||
g_string_free(str, TRUE);
|
||||
|
||||
_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) {
|
||||
log_warning(srv, NULL, "integer value overflowed in line %zd of %s", ctx->line, ctx->filename);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
action string {
|
||||
|
@ -414,6 +410,7 @@
|
|||
|
||||
if (t == NULL) {
|
||||
log_warning(srv, NULL, "unknown variable '%s'", o->data.string->str);
|
||||
value_free(o);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -424,6 +421,7 @@
|
|||
gchar *env = getenv(o->data.string->str + 4);
|
||||
if (env == NULL) {
|
||||
log_error(srv, NULL, "unknown environment variable: %s", o->data.string->str + 4);
|
||||
value_free(o);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -532,6 +530,7 @@
|
|||
if (ctx->in_setup_block) {
|
||||
/* we are in the setup { } block, call setups and don't append to action list */
|
||||
if (!call_setup(srv, name->data.string->str, NULL)) {
|
||||
value_free(name);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -539,14 +538,16 @@
|
|||
al = g_queue_peek_head(ctx->action_list_stack);
|
||||
a = create_action(srv, name->data.string->str, NULL);
|
||||
|
||||
if (a == NULL)
|
||||
if (a == NULL) {
|
||||
value_free(name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_array_append_val(al->data.list, a);
|
||||
}
|
||||
|
||||
value_free(name);
|
||||
}
|
||||
|
||||
value_free(name);
|
||||
}
|
||||
|
||||
action function_param {
|
||||
|
@ -565,22 +566,32 @@
|
|||
if (g_str_equal(name->data.string->str, "include")) {
|
||||
if (val->type != VALUE_STRING) {
|
||||
log_warning(srv, NULL, "include directive takes a string as parameter, %s given", value_type_string(val->type));
|
||||
value_free(name);
|
||||
value_free(val);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!config_parser_file(srv, ctx_stack, val->data.string->str))
|
||||
if (!config_parser_file(srv, ctx_stack, val->data.string->str)) {
|
||||
value_free(name);
|
||||
value_free(val);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
value_free(val);
|
||||
}
|
||||
else if (g_str_equal(name->data.string->str, "include_shell")) {
|
||||
if (val->type != VALUE_STRING) {
|
||||
log_warning(srv, NULL, "include_shell directive takes a string as parameter, %s given", value_type_string(val->type));
|
||||
value_free(name);
|
||||
value_free(val);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!config_parser_shell(srv, ctx_stack, val->data.string->str))
|
||||
if (!config_parser_shell(srv, ctx_stack, val->data.string->str)) {
|
||||
value_free(name);
|
||||
value_free(val);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
value_free(val);
|
||||
}
|
||||
|
@ -599,6 +610,7 @@
|
|||
if (ctx->in_setup_block) {
|
||||
/* we are in the setup { } block, call setups and don't append to action list */
|
||||
if (!call_setup(srv, name->data.string->str, val)) {
|
||||
value_free(name);
|
||||
value_free(val);
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -609,8 +621,10 @@
|
|||
a = create_action(srv, name->data.string->str, val);
|
||||
value_free(val);
|
||||
|
||||
if (a == NULL)
|
||||
if (a == NULL) {
|
||||
value_free(name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_array_append_val(al->data.list, a);
|
||||
}
|
||||
|
@ -861,7 +875,7 @@
|
|||
# basic types
|
||||
boolean = ( 'true' | 'false' ) %boolean;
|
||||
integer_suffix_bytes = ( 'byte' | 'kbyte' | 'mbyte' | 'gbyte' | 'tbyte' | 'pbyte' );
|
||||
integer_suffix_bits = ( 'bit' | 'kbit' | 'mbit' | 'gbit' );
|
||||
integer_suffix_bits = ( 'bit' | 'kbit' | 'mbit' | 'gbit' | 'tbit' | 'pbit' );
|
||||
integer_suffix_seconds = ( 'sec' | 'min' | 'hours' | 'days' );
|
||||
integer_suffix = ( integer_suffix_bytes | integer_suffix_bits | integer_suffix_seconds ) >mark %integer_suffix;
|
||||
integer = ( ('0' | ( [1-9] [0-9]* )) %integer (ws? integer_suffix)? );
|
||||
|
|
|
@ -448,6 +448,8 @@ void log_thread_finish(server *srv) {
|
|||
}
|
||||
|
||||
void log_thread_wakeup(server *srv) {
|
||||
if (!g_atomic_int_get(&srv->logs.thread_alive))
|
||||
log_thread_start(srv);
|
||||
log_entry_t *e;
|
||||
|
||||
e = g_slice_new0(log_entry_t);
|
||||
|
|
|
@ -299,19 +299,46 @@ static action* core_blank(server *srv, plugin* p, value *val) {
|
|||
static gboolean core_listen(server *srv, plugin* p, value *val) {
|
||||
guint32 ipv4;
|
||||
guint8 ipv6[16];
|
||||
GString *ipstr;
|
||||
guint16 port = 80;
|
||||
UNUSED(p);
|
||||
|
||||
if (val->type != VALUE_STRING) {
|
||||
ERROR(srv, "%s", "listen expects a string as parameter");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (parse_ipv4(val->data.string->str, &ipv4, NULL)) {
|
||||
if (val->data.string->str[0] == '[') {
|
||||
/* ipv6 with port */
|
||||
gchar *pos = g_strrstr(val->data.string->str, "]");
|
||||
if (NULL == pos) {
|
||||
ERROR(srv, "%s", "listen: bogus ipv6 format");
|
||||
return FALSE;
|
||||
}
|
||||
if (pos[1] == ':') {
|
||||
port = atoi(&pos[2]);
|
||||
}
|
||||
ipstr = g_string_new_len(&val->data.string->str[1], pos - &val->data.string->str[1]);
|
||||
} else {
|
||||
/* no brackets, search for :port */
|
||||
gchar *pos = g_strrstr(val->data.string->str, ":");
|
||||
if (NULL != pos) {
|
||||
ipstr = g_string_new_len(val->data.string->str, pos - val->data.string->str);
|
||||
port = atoi(&pos[1]);
|
||||
} else {
|
||||
/* no port, just plain ipv4 or ipv6 address */
|
||||
ipstr = g_string_new_len(GSTR_LEN(val->data.string));
|
||||
}
|
||||
}
|
||||
|
||||
if (parse_ipv4(ipstr->str, &ipv4, NULL)) {
|
||||
int s, v;
|
||||
struct sockaddr_in addr;
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = ipv4;
|
||||
addr.sin_port = htons(8080);
|
||||
addr.sin_port = htons(port);
|
||||
g_string_free(ipstr, TRUE);
|
||||
if (-1 == (s = socket(AF_INET, SOCK_STREAM, 0))) {
|
||||
ERROR(srv, "Couldn't open socket: %s", g_strerror(errno));
|
||||
return FALSE;
|
||||
|
@ -333,19 +360,20 @@ static gboolean core_listen(server *srv, plugin* p, value *val) {
|
|||
return FALSE;
|
||||
}
|
||||
server_listen(srv, s);
|
||||
TRACE(srv, "listen to ipv4: '%s'", inet_ntoa(*(struct in_addr*)&ipv4));
|
||||
TRACE(srv, "listen to ipv4: '%s' port: %d", inet_ntoa(*(struct in_addr*)&ipv4), port);
|
||||
#ifdef HAVE_IPV6
|
||||
} else if (parse_ipv6(val->data.string->str, ipv6, NULL)) {
|
||||
} else if (parse_ipv6(ipstr->str, ipv6, NULL)) {
|
||||
/* TODO: IPv6 */
|
||||
g_string_free(ipstr, TRUE);
|
||||
ERROR(srv, "%s", "IPv6 not supported yet");
|
||||
return FALSE;
|
||||
#endif
|
||||
} else {
|
||||
ERROR(srv, "Invalid ip: '%s'", val->data.string->str);
|
||||
ERROR(srv, "Invalid ip: '%s'", ipstr->str);
|
||||
g_string_free(ipstr, TRUE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
TRACE(srv, "will listen to '%s'", val->data.string->str);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
12
src/server.c
12
src/server.c
|
@ -291,13 +291,13 @@ void server_stop(server *srv) {
|
|||
server_socket *sock = g_array_index(srv->sockets, server_socket*, i);
|
||||
ev_io_stop(srv->main_worker->loop, &sock->watcher);
|
||||
}
|
||||
}
|
||||
|
||||
/* stop all workers */
|
||||
for (i = 0; i < srv->worker_count; i++) {
|
||||
worker *wrk;
|
||||
wrk = g_array_index(srv->workers, worker*, i);
|
||||
worker_stop(srv->main_worker, wrk);
|
||||
/* stop all workers */
|
||||
for (i = 0; i < srv->worker_count; i++) {
|
||||
worker *wrk;
|
||||
wrk = g_array_index(srv->workers, worker*, i);
|
||||
worker_stop(srv->main_worker, wrk);
|
||||
}
|
||||
}
|
||||
|
||||
log_thread_wakeup(srv);
|
||||
|
|
Loading…
Reference in New Issue