Browse Source

implemented port feature for listen setup; small memleak und config parser fixes

personal/stbuehler/wip
Thomas Porzelt 14 years ago
parent
commit
5150637e13
  1. 46
      src/config_parser.rl
  2. 2
      src/log.c
  3. 40
      src/plugin_core.c
  4. 12
      src/server.c

46
src/config_parser.rl

@ -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)? );

2
src/log.c

@ -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);

40
src/plugin_core.c

@ -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

@ -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…
Cancel
Save