diff options
Diffstat (limited to 'src/configfile.c')
-rw-r--r-- | src/configfile.c | 135 |
1 files changed, 103 insertions, 32 deletions
diff --git a/src/configfile.c b/src/configfile.c index 0597eb3a..a58de1a1 100644 --- a/src/configfile.c +++ b/src/configfile.c @@ -19,6 +19,7 @@ #include "configparser.h" #include "configfile.h" +#include "proc_open.h" static int config_insert(server *srv) { @@ -225,11 +226,6 @@ static int config_insert(server *srv) { #define PATCH(x) con->conf.x = s->x int config_setup_connection(server *srv, connection *con) { specific_config *s = srv->config_storage[0]; - int i; - - for (i = srv->config_context->used - 1; i >= 0; i --) { - con->cond_results_cache[i] = COND_RESULT_UNSET; - } PATCH(allow_http11); PATCH(mimetypes); @@ -351,12 +347,12 @@ int config_patch_connection(server *srv, connection *con, comp_key_t comp) { return 0; } #undef PATCH + typedef struct { int foo; int bar; - buffer *file; - stream s; + const buffer *source; const char *input; size_t offset; size_t size; @@ -369,6 +365,7 @@ typedef struct { int in_cond; } tokenizer_t; +#if 0 static int tokenizer_open(server *srv, tokenizer_t *t, buffer *basedir, const char *fn) { if (buffer_is_empty(basedir) && (fn[0] == '/' || fn[0] == '\\') && @@ -404,7 +401,7 @@ static int tokenizer_close(server *srv, tokenizer_t *t) { buffer_free(t->file); return stream_close(&(t->s)); } - +#endif static int config_skip_newline(tokenizer_t *t) { int skipped = 1; assert(t->input[t->offset] == '\r' || t->input[t->offset] == '\n'); @@ -445,7 +442,7 @@ static int config_tokenizer(server *srv, tokenizer_t *t, int *token_id, buffer * tid = TK_ARRAY_ASSIGN; } else { log_error_write(srv, __FILE__, __LINE__, "sbsdsds", - "file:", t->file, + "source:", t->source, "line:", t->line, "pos:", t->line_pos, "use => for assignments in arrays"); return -1; @@ -465,7 +462,7 @@ static int config_tokenizer(server *srv, tokenizer_t *t, int *token_id, buffer * tid = TK_MATCH; } else { log_error_write(srv, __FILE__, __LINE__, "sbsdsds", - "file:", t->file, + "source:", t->source, "line:", t->line, "pos:", t->line_pos, "only =~ and == are allow in the condition"); return -1; @@ -481,7 +478,7 @@ static int config_tokenizer(server *srv, tokenizer_t *t, int *token_id, buffer * t->line_pos++; } else { log_error_write(srv, __FILE__, __LINE__, "sbsdsds", - "file:", t->file, + "source:", t->source, "line:", t->line, "pos:", t->line_pos, "unexpected equal-sign: ="); return -1; @@ -504,7 +501,7 @@ static int config_tokenizer(server *srv, tokenizer_t *t, int *token_id, buffer * tid = TK_NOMATCH; } else { log_error_write(srv, __FILE__, __LINE__, "sbsdsds", - "file:", t->file, + "source:", t->source, "line:", t->line, "pos:", t->line_pos, "only !~ and != are allow in the condition"); return -1; @@ -513,7 +510,7 @@ static int config_tokenizer(server *srv, tokenizer_t *t, int *token_id, buffer * t->in_cond = 0; } else { log_error_write(srv, __FILE__, __LINE__, "sbsdsds", - "file:", t->file, + "source:", t->source, "line:", t->line, "pos:", t->line_pos, "unexpected exclamation-marks: !"); return -1; @@ -603,7 +600,7 @@ static int config_tokenizer(server *srv, tokenizer_t *t, int *token_id, buffer * /* ERROR */ log_error_write(srv, __FILE__, __LINE__, "sbsdsds", - "file:", t->file, + "source:", t->source, "line:", t->line, "pos:", t->line_pos, "missing closing quote"); @@ -646,8 +643,7 @@ static int config_tokenizer(server *srv, tokenizer_t *t, int *token_id, buffer * t->offset += 2; buffer_copy_string(token, "+="); tid = TK_APPEND; - } - else { + } else { t->offset++; tid = TK_PLUS; buffer_copy_string(token, "+"); @@ -708,7 +704,7 @@ static int config_tokenizer(server *srv, tokenizer_t *t, int *token_id, buffer * } else { /* ERROR */ log_error_write(srv, __FILE__, __LINE__, "sbsdsds", - "file:", t->file, + "source:", t->source, "line:", t->line, "pos:", t->line_pos, "invalid character in condition"); return -1; @@ -728,7 +724,7 @@ static int config_tokenizer(server *srv, tokenizer_t *t, int *token_id, buffer * } else { /* ERROR */ log_error_write(srv, __FILE__, __LINE__, "sbsdsds", - "file:", t->file, + "source:", t->source, "line:", t->line, "pos:", t->line_pos, "unexpected EOF"); @@ -748,6 +744,8 @@ static int config_tokenizer(server *srv, tokenizer_t *t, int *token_id, buffer * if (strcmp(token->ptr, "include") == 0) { tid = TK_INCLUDE; + } else if (strcmp(token->ptr, "include_shell") == 0) { + tid = TK_INCLUDE_SHELL; } else if (strcmp(token->ptr, "else") == 0) { tid = TK_ELSE; } else { @@ -759,7 +757,7 @@ static int config_tokenizer(server *srv, tokenizer_t *t, int *token_id, buffer * } else { /* ERROR */ log_error_write(srv, __FILE__, __LINE__, "sbsdsds", - "file:", t->file, + "source:", t->source, "line:", t->line, "pos:", t->line_pos, "invalid character in variable name"); return -1; @@ -773,7 +771,7 @@ static int config_tokenizer(server *srv, tokenizer_t *t, int *token_id, buffer * *token_id = tid; #if 0 log_error_write(srv, __FILE__, __LINE__, "sbsdsdbdd", - "file:", t->file, + "source:", t->source, "line:", t->line, "pos:", t->line_pos, token, token->used - 1, tid); #endif @@ -787,21 +785,16 @@ static int config_tokenizer(server *srv, tokenizer_t *t, int *token_id, buffer * return 0; } -int config_parse_file(server *srv, config_t *context, const char *fn) { - tokenizer_t t; +static int config_parse(server *srv, config_t *context, tokenizer_t *t) { void *pParser; int token_id; buffer *token, *lasttoken; int ret; - if (tokenizer_open(srv, &t, context->basedir, fn) == -1) { - return -1; - } - pParser = configparserAlloc( malloc ); lasttoken = buffer_init(); token = buffer_init(); - while((1 == (ret = config_tokenizer(srv, &t, &token_id, token))) && context->ok) { + while((1 == (ret = config_tokenizer(srv, t, &token_id, token))) && context->ok) { buffer_copy_string_buffer(lasttoken, token); configparser(pParser, token_id, token, context); @@ -821,20 +814,98 @@ int config_parse_file(server *srv, config_t *context, const char *fn) { if (ret == -1) { log_error_write(srv, __FILE__, __LINE__, "sb", "configfile parser failed:", lasttoken); - } - else if (context->ok == 0) { + } else if (context->ok == 0) { log_error_write(srv, __FILE__, __LINE__, "sbsdsdsb", - "file:", t.file, - "line:", t.line, "pos:", t.line_pos, + "source:", t->source, + "line:", t->line, "pos:", t->line_pos, "parser failed somehow near here:", lasttoken); ret = -1; } buffer_free(lasttoken); - tokenizer_close(srv, &t); return ret == -1 ? -1 : 0; } +static int tokenizer_init(tokenizer_t *t, const buffer *source, const char *input, size_t size) { + + t->source = source; + t->input = input; + t->size = size; + t->offset = 0; + t->line = 1; + t->line_pos = 1; + + t->in_key = 1; + t->in_brace = 0; + t->in_cond = 0; + return 0; +} + +int config_parse_file(server *srv, config_t *context, const char *fn) { + tokenizer_t t; + stream s; + int ret; + buffer *filename; + + if (buffer_is_empty(context->basedir) && + (fn[0] == '/' || fn[0] == '\\') && + (fn[0] == '.' && (fn[1] == '/' || fn[1] == '\\'))) { + filename = buffer_init_string(fn); + } else { + filename = buffer_init_buffer(context->basedir); + buffer_append_string(filename, fn); + } + + if (0 != stream_open(&s, filename)) { + log_error_write(srv, __FILE__, __LINE__, "sbss", + "opening configfile ", filename, "failed:", strerror(errno)); + ret = -1; + } else { + tokenizer_init(&t, filename, s.start, s.size); + ret = config_parse(srv, context, &t); + } + + stream_close(&s); + buffer_free(filename); + return ret; +} + +int config_parse_cmd(server *srv, config_t *context, const char *cmd) { + proc_handler_t proc; + tokenizer_t t; + int ret; + buffer *source; + buffer *out; + char oldpwd[PATH_MAX]; + + if (NULL == getcwd(oldpwd, sizeof(oldpwd))) { + log_error_write(srv, __FILE__, __LINE__, "s", + "cannot get cwd", strerror(errno)); + return -1; + } + + source = buffer_init_string(cmd); + out = buffer_init(); + + if (!buffer_is_empty(context->basedir)) { + chdir(context->basedir->ptr); + } + + if (0 != proc_open_buffer(&proc, cmd, NULL, out, NULL)) { + log_error_write(srv, __FILE__, __LINE__, "sbss", + "opening", source, "failed:", strerror(errno)); + ret = -1; + } else { + tokenizer_init(&t, source, out->ptr, out->used); + ret = config_parse(srv, context, &t); + } + + buffer_free(source); + buffer_free(out); + chdir(oldpwd); + return ret; +} + static void context_init(server *srv, config_t *context) { context->srv = srv; context->ok = 1; |