--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/server/config/conf.c Sun Jan 15 17:00:16 2012 +0100 @@ -0,0 +1,297 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2011 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "conf.h" + +#include <string.h> + +int cfg_parse_basic_file(ConfigParser *parser, FILE *in) { + parser->lines = NULL; + parser->mp = ucx_mempool_new(512); + + // one logical line over many lines + sstr_t mline; + mline.ptr = NULL; + mline.length = 0; + ConfigLine *start_line; + ConfigLine *end_line; + + // read file + sstr_t l; + while((l = cfg_readln(in)).ptr != NULL) { + // put the line to the list + ConfigLine *line = OBJ_NEW(parser->mp, ConfigLine); + line->line = sstrdub_mp(parser->mp, l); + line->object = NULL; + line->type = LINE_OTHER; + parser->lines = ucx_dlist_append(parser->lines, line); + + // check if the line contains something + l = cfg_trim_comment(l); + line->type = cfg_get_basic_type(l); + + if(line->type == LINE_OTHER) { + // check for multi line + if(mline.ptr != NULL) { + // concate lines + char *ptr = malloc(mline.length + l.length + 1); + memcpy(ptr, mline.ptr, mline.length); + memcpy(ptr + mline.length - 1, l.ptr, l.length); + mline.length += l.length; + free(mline.ptr); + mline.ptr = ptr; + mline.ptr[mline.length] = 0; + + end_line = line; + + line->type = LINE_MULTI; + } + if(l.ptr[l.length - 1] == '\\') { + if(mline.ptr == NULL) { + mline = sstrdub(l); + start_line = line; + } + } else { + // this line is complete so we can parse it + sstr_t ll; // we parse this line + + if(mline.ptr == NULL) { + // single line + ll = l; + start_line = line; + end_line = line; + } else { + ll = mline; + } + + // parse + int r = parser->parse(parser, start_line, end_line, ll); + + // clean up + if(mline.ptr != NULL) { + free(mline.ptr); + mline.ptr = NULL; + mline.length = 0; + start_line = NULL; + end_line = NULL; + } + + if(r != 0) { + return -1; + } + } + } + } + + return 0; +} + +sstr_t cfg_readln(FILE *file) { + sstr_t ns; + ns.ptr = NULL; + ns.length = 0; + + if(!feof(file)) { + char buf[512]; + buf[0] = 0; + int len = 512; + + if(fgets(buf, len, file) == NULL) { + return ns; + } + + if(*buf == 0) { + printf("???\n"); + return ns; + } + + char *ptr; + if((ptr = strrchr(buf, '\n'))) { + ptr[0] = 0; + } + + sstr_t line = sstr(buf); + return line; + } + + sstr_t s; + s.ptr = NULL; + s.length = 0; + return s; +} + +/* + * checks if the line contains only a comment or space + */ +int cfg_get_basic_type(sstr_t line) { + if(line.length == 0) { + return LINE_NOCONTENT; + } else if(line.ptr[0] == '#') { + return LINE_NOCONTENT; + } + return LINE_OTHER; +} + +/* + * removes a comment from the line + */ +sstr_t cfg_trim_comment(sstr_t line) { + sstr_t nl = line; + for(int i=0;i<line.length;i++) { + if(line.ptr[i] == '#') { + if(i > 0) { + nl.ptr = line.ptr + i - 1; + nl.length = i; + break; + } else { + nl.ptr = line.ptr; + nl.length = 0; + break; + } + } + } + return sstrtrim(nl); +} + +/* + * gets the first parameter in the params string and returns a new string + * containing the other parameters or an empty string, if there are no more + * parameters + */ +sstr_t cfg_param(sstr_t params, sstr_t *name, sstr_t *value) { + name->ptr = NULL; + name->length = 0; + value->ptr = NULL; + value->length = 0; + + // get name + int i; + for(i=0;i<params.length;i++) { + char c = params.ptr[i]; + if(c == '=') { + break; + } else if(c < 33) { + // no '=' means there is only a name, no value + name->ptr = params.ptr; + name->length = i; + + params.ptr = params.ptr + i; + params.length -= i; + return sstrtrim(params); + } + } + + name->ptr = params.ptr; + name->length = i; + i++; + + // get value + if(i>=params.length) { + sstr_t ns; + ns.ptr = NULL; + ns.length = 0; + return ns; + } + + int quote = 0; + value->ptr = params.ptr + i; + for(;i<params.length;i++) { + char c = params.ptr[i]; + if(c == '"') { + if(quote) { + break; // end of quoted value + } else { + quote = 1; + value->ptr++; + } + } else if(!quote && c < 33) { + break; // end of value + } + } + value->length = i - name->length - 2; + i++; + + if(value->length <= 0) { + value->length = 0; + value->ptr = NULL; + } + + // create new params string + params.ptr += i; + params.length -= i; + return sstrtrim(params); +} + +/* + * gets from a parameter list a value + */ +sstr_t cfg_param_get(UcxList *list, sstr_t name) { + while(list != NULL) { + ConfigParam *param = list->data; + if(!sstrcmp(param->name, name)) { + return param->value; + } + list = list->next; + } + sstr_t ns; + ns.ptr = NULL; + ns.length = 0; + return ns; +} + +/* + * gets the directive type number from a type string + * valid types are: + * AuthTrans 0 + * NameTrans 1 + * PathCheck 2 + * ObjectType 3 + * Service 4 + * AddLog 5 + * Init 6 + */ +int cfg_get_directive_type_num(sstr_t type) { + /* get nsapi function type */ + int dt = -1; + if(sstrcmp(type, sstr("AuthTrans")) == 0) { + dt = 0; + } else if(sstrcmp(type, sstr("NameTrans")) == 0) { + dt = 1; + } else if(sstrcmp(type, sstr("PathCheck")) == 0) { + dt = 2; + } else if(sstrcmp(type, sstr("ObjectType")) == 0) { + dt = 3; + } else if(sstrcmp(type, sstr("Service")) == 0) { + dt = 4; + } else if(sstrcmp(type, sstr("AddLog")) == 0) { + dt = 5; + } else if(sstrcmp(type, sstr("Init")) == 0) { + dt = 6; + } + return dt; +}