# HG changeset patch # User Olaf Wintermann # Date 1667840384 -3600 # Node ID b7dcc9c4f27070490da72e91bfeb9a3b80769d28 # Parent 90805bb9fbd6811c5728bad603c805015c78aa67 use server.conf parser for init.conf as well diff -r 90805bb9fbd6 -r b7dcc9c4f270 src/server/config/initconf.c --- a/src/server/config/initconf.c Sun Nov 06 17:41:39 2022 +0100 +++ b/src/server/config/initconf.c Mon Nov 07 17:59:44 2022 +0100 @@ -32,53 +32,61 @@ #include "initconf.h" -InitConfig *load_init_config(char *file) { - FILE *in = fopen(file, "r"); - if(in == NULL) { +InitConfig *initconfig_load(const char *file) { + CxMempool *mp = cxBasicMempoolCreate(512); + if(!mp) { return NULL; } - InitConfig *conf = malloc(sizeof(InitConfig)); - conf->parser.parse = initconf_parse; - conf->file = file; - conf->directives = NULL; - - int r = cfg_parse_basic_file((ConfigParser*)conf, in); - if(r != 0) { - free_init_config(conf); + // setup parser + ConfigParser2 parser; + memset(&parser, 0, sizeof(ConfigParser2)); + parser.mp = mp; + parser.validateDirective = initconfig_validate_directive; + parser.allow_hierarchy = 0; + + ConfigNode *init_config = serverconfig_load_file(&parser, file); + if(!init_config) { + cxMempoolDestroy(mp); return NULL; } - fclose(in); + + InitConfig *conf = cxMalloc(mp->allocator, sizeof(InitConfig)); + if(!conf) { + cxMempoolDestroy(mp); + return NULL; + } + + conf->mp = mp; + conf->root = init_config; return conf; } -void free_init_config(InitConfig *conf) { - // TODO: fix - //ucx_mempool_destroy(conf->parser.mp->pool); - free(conf); +int initconfig_validate_directive(ConfigParser2 *parser, ConfigNode *node) { + // check directive type + // currently only Init is supported + const char *types[] = { "Init" }; + size_t typeindex; + if(serverconfig_validate_directive_name(node, types, 1, &typeindex)) { + return 1; + } + + // init directives must have parameter names + ConfigParam *param_err; + if(serverconfig_check_param_names(node, ¶m_err)) { + return 1; + } + + // check if the fn parameter exists + cxstring fn = serverconfig_directive_get_arg(node, cx_str("fn")); + if(fn.length == 0) { + return 1; + } + + return 0; } -int initconf_parse(void *p, ConfigLine *begin, ConfigLine *end, cxmutstr line) { - InitConfig *conf = p; - - // parse directive - ConfigDirective *d = cfg_parse_directive(line, conf->parser.mp); - if(d == NULL) { - log_ereport(LOG_FAILURE, "initconf_parse: directive is null"); - return 0; - } - d->begin = begin; - d->end = end; - if(d->type_num == INIT_DIRECTIVE) { - //conf->directives = ucx_list_append(conf->directives, d); - ConfigDirectiveList *dir_entry = cxMalloc(conf->parser.mp, sizeof(ConfigDirectiveList)); - dir_entry->directive = d; - dir_entry->next = NULL; - CFG_DIRECTIVES_ADD(&conf->directives, dir_entry); - } else { - log_ereport(LOG_WARN, "Non Init directive in init.conf"); - } - - return 0; +void initconfig_free(InitConfig *conf) { + cxMempoolDestroy(conf->mp); } diff -r 90805bb9fbd6 -r b7dcc9c4f270 src/server/config/initconf.h --- a/src/server/config/initconf.h Sun Nov 06 17:41:39 2022 +0100 +++ b/src/server/config/initconf.h Mon Nov 07 17:59:44 2022 +0100 @@ -31,21 +31,30 @@ #include "conf.h" +#include "serverconfig.h" + #ifdef __cplusplus extern "C" { #endif typedef struct _init_conf { - ConfigParser parser; - char *file; - ConfigDirectiveList *directives; + CxMempool *mp; + ConfigNode *root; } InitConfig; -InitConfig *load_init_config(char *file); +InitConfig *initconfig_load(const char *file); -void free_init_config(InitConfig *conf); +/* + * Validates a init.conf directive + * + * Basic syntax: + * + * Init fn="" param1="value1" param2="value" + */ +int initconfig_validate_directive(ConfigParser2 *parser, ConfigNode *node); -int initconf_parse(void *p, ConfigLine *begin, ConfigLine *end, cxmutstr line); +void initconfig_free(InitConfig *conf); + #ifdef __cplusplus } diff -r 90805bb9fbd6 -r b7dcc9c4f270 src/server/config/serverconfig.c --- a/src/server/config/serverconfig.c Sun Nov 06 17:41:39 2022 +0100 +++ b/src/server/config/serverconfig.c Mon Nov 07 17:59:44 2022 +0100 @@ -34,26 +34,52 @@ #include #include #include +#include #include #include ServerConfig* serverconfig_load(const char *file) { - FILE *in = fopen(file, "r"); - if(in == NULL) { + CxMempool *mp = cxBasicMempoolCreate(512); + if(!mp) { + return NULL; + } + + ConfigParser2 parser; + memset(&parser, 0, sizeof(ConfigParser2)); + parser.mp = mp; + parser.allow_hierarchy = true; + ConfigNode *root = serverconfig_load_file(&parser, file); + if(!root) { + cxMempoolDestroy(mp); return NULL; } - CxMempool *mp = cxBasicMempoolCreate(512); - if(!mp) { - fclose(in); + ServerConfig *scfg = cxMalloc(mp->allocator, sizeof(ServerConfig)); + if(!scfg) { + cxMempoolDestroy(mp); + return NULL; + } + scfg->root = root; + scfg->mp = mp; + scfg->tab = cx_str("\t"); + + return scfg; +} + +ConfigNode* serverconfig_load_file(ConfigParser2 *parser, const char *file) { + FILE *in = fopen(file, "r"); + if(in == NULL) { + parser->error = CONFIG_PARSER_IO_ERROR; + parser->io_errno = errno; return NULL; } + // temporary buffer to store the file content CxBuffer buf; if(cxBufferInit(&buf, NULL, 16384, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND|CX_BUFFER_FREE_CONTENTS)) { fclose(in); - cxMempoolDestroy(mp); + parser->error = CONFIG_PARSER_OOM; return NULL; } @@ -65,14 +91,9 @@ } fclose(in); - ConfigParser2 parser; - ZERO(&parser, sizeof(ConfigParser2)); - parser.mp = mp; - parser.allow_hierarchy = true; - ServerConfig *scfg = serverconfig_parse(&parser, cx_strn(buf.space, buf.size)); - + ConfigNode *root = serverconfig_parse(parser, cx_strn(buf.space, buf.size)); cxBufferDestroy(&buf); - return scfg; + return root; } @@ -204,17 +225,10 @@ return 0; } -ServerConfig* serverconfig_parse(ConfigParser2 *parser, cxstring content) { +ConfigNode* serverconfig_parse(ConfigParser2 *parser, cxstring content) { CxMempool *mp = parser->mp; CxAllocator *a = (CxAllocator*)mp->allocator; - ServerConfig *config = cxMalloc(a, sizeof(ServerConfig)); - if(!config) { - cxMempoolDestroy(mp); - return NULL; - } - config->mp = mp; - // PARSE: // first non space/comment token is directive/object name // following tokens are arguments @@ -280,7 +294,10 @@ obj->text_begin = new_textbegin; } else { // normal line containing a directive, space or comment - if(parser->validateDirective && parser->validateDirective(parser, current)) { + if(current->type == CONFIG_NODE_DIRECTIVE && + parser->validateDirective && + parser->validateDirective(parser, current)) + { err = 1; break; } @@ -379,10 +396,7 @@ } //test_print_config(&root_obj); - config->root = root_obj; - config->tab = cx_strdup_a(a, cx_str("\t")); - - return config; + return root_obj; } void serverconfig_free(ServerConfig *cfg) { @@ -410,7 +424,7 @@ return nodes; } -cxstring serverconfig_directive_value(ConfigNode *obj, cxstring name) { +cxstring serverconfig_object_directive_value(ConfigNode *obj, cxstring name) { ConfigNode *node = serverconfig_get_node(obj, CONFIG_NODE_DIRECTIVE, name); if(node && CFG_NUM_PARAMS(node->args) == 1) { ConfigParam *arg = node->args; @@ -419,19 +433,48 @@ return (cxstring){ NULL, 0 }; } -cxmutstr serverconfig_arg_name_value(CxAllocator *a, cxstring str, cxstring *name) { - int valstart = 0; - for(int i=0;iparser.mp; - - init_pool = pool_create(); // one pool for one Configuration - ConfigDirectiveList *dirs = cfg->directives; - while(dirs != NULL) { - ConfigDirective *dir = dirs->directive; - - /* create NSAPI directive */ - directive *d = malloc(sizeof(directive)); + CxAllocator *mp = cfg->mp; + init_pool = pool_create(); + + ConfigNode *dir = cfg->root->children_begin; + while(dir) { + if(dir->type != CONFIG_NODE_DIRECTIVE) { + // dir is just space/comment + dir = dir->next; + continue; + } + + // create NSAPI directive + + // The parser checks the directive name and makes sure it is "Init" + // if more than one init directive type is introduced, the parser + // must be extended and also dir->name must be checked here + + directive *d = pool_malloc(init_pool, sizeof(directive)); d->param = pblock_create_pool(init_pool, 8); - ConfigParam *param = cfg_param_list(dir->value, mp); + + ConfigParam *param = dir->args; while(param != NULL) { pblock_nvlinsert( param->name.ptr, @@ -96,39 +106,33 @@ param = param->next; } - - /* get function */ + + // get function + // the parser makes sure that an "fn" parameter always exists char *func_name = pblock_findval("fn", d->param); d->func = get_function(func_name); if(d->func == NULL) { - pblock_free(d->param); - free(d); - //dirs = dirs->next; log_ereport( LOG_MISCONFIG, "Cannot find Init function %s", func_name); return 1; } - - /* execute init directive */ + + // execute init directive int ret = d->func->func(d->param, NULL, NULL); if(ret != REQ_PROCEED && ret != REQ_NOACTION) { log_ereport( LOG_FAILURE, "Error running Init function %s", func_name); - pblock_free(d->param); - free(d); return 1; } - pblock_free(d->param); - free(d); - dirs = dirs->next; + dir = dir->next; } - free_init_config(cfg); + initconfig_free(cfg); return 0; } @@ -356,11 +360,11 @@ } int cfg_handle_runtime(ServerConfiguration *cfg, ConfigNode *obj) { - cxstring user = serverconfig_directive_value(obj, cx_str("User")); + cxstring user = serverconfig_object_directive_value(obj, cx_str("User")); if(user.ptr) { cfg->user = cx_strdup_a(cfg->a, user); } - cxstring tmp = serverconfig_directive_value(obj, cx_str("Temp")); + cxstring tmp = serverconfig_object_directive_value(obj, cx_str("Temp")); if(tmp.ptr) { cfg->tmp = cx_strdup_a(cfg->a, tmp); } else { @@ -370,7 +374,7 @@ } // mime file - cxstring mf = serverconfig_directive_value(obj, cx_str("MimeFile")); + cxstring mf = serverconfig_object_directive_value(obj, cx_str("MimeFile")); cxstring base = cx_str("config/"); cxmutstr file = cx_strcat(2, base, mf); @@ -383,8 +387,8 @@ } int cfg_handle_logfile(ServerConfiguration *cfg, ConfigNode *obj) { - cxstring file = serverconfig_directive_value(obj, cx_str("File")); - cxstring lvl = serverconfig_directive_value(obj, cx_str("Level")); + cxstring file = serverconfig_object_directive_value(obj, cx_str("File")); + cxstring lvl = serverconfig_object_directive_value(obj, cx_str("Level")); int err = 0; if(file.ptr == NULL) { @@ -419,11 +423,11 @@ poolcfg.queue_size = 64; poolcfg.stack_size = 262144; - cxstring name = serverconfig_directive_value(obj, cx_str("Name")); - cxstring min = serverconfig_directive_value(obj, cx_str("MinThreads")); - cxstring max = serverconfig_directive_value(obj, cx_str("MaxThreads")); - cxstring stack = serverconfig_directive_value(obj, cx_str("StackSize")); - cxstring queue = serverconfig_directive_value(obj, cx_str("QueueSize")); + cxstring name = serverconfig_object_directive_value(obj, cx_str("Name")); + cxstring min = serverconfig_object_directive_value(obj, cx_str("MinThreads")); + cxstring max = serverconfig_object_directive_value(obj, cx_str("MaxThreads")); + cxstring stack = serverconfig_object_directive_value(obj, cx_str("StackSize")); + cxstring queue = serverconfig_object_directive_value(obj, cx_str("QueueSize")); // TODO: Type if(name.length == 0) { @@ -478,9 +482,9 @@ int cfg_handle_eventhandler(ServerConfiguration *c, ConfigNode *obj) { EventHandlerConfig evcfg; - cxstring name = serverconfig_directive_value(obj, cx_str("Name")); - cxstring threads = serverconfig_directive_value(obj, cx_str("Threads")); - cxstring isdefault = serverconfig_directive_value(obj, cx_str("Default")); + cxstring name = serverconfig_object_directive_value(obj, cx_str("Name")); + cxstring threads = serverconfig_object_directive_value(obj, cx_str("Threads")); + cxstring isdefault = serverconfig_object_directive_value(obj, cx_str("Default")); evcfg.name = name; @@ -502,8 +506,8 @@ } int cfg_handle_resourcepool(ServerConfiguration *cfg, ConfigNode *obj) { - cxstring name = serverconfig_directive_value(obj, cx_str("Name")); - cxstring type = serverconfig_directive_value(obj, cx_str("Type")); + cxstring name = serverconfig_object_directive_value(obj, cx_str("Name")); + cxstring type = serverconfig_object_directive_value(obj, cx_str("Type")); int ret = 0; if(resourcepool_new(cfg, type, name, obj)) { @@ -516,7 +520,7 @@ int cfg_handle_accesslog(ServerConfiguration *cfg, ConfigNode *obj) { // TODO: use a name to identify the log file - cxstring file = serverconfig_directive_value(obj, cx_str("File")); + cxstring file = serverconfig_object_directive_value(obj, cx_str("File")); if(file.ptr == NULL) { return 0; } @@ -544,19 +548,19 @@ } int cfg_handle_authdb(ServerConfiguration *cfg, ConfigNode *obj) { - cxstring name = serverconfig_directive_value(obj, cx_str("Name")); - cxstring type = serverconfig_directive_value(obj, cx_str("Type")); + cxstring name = serverconfig_object_directive_value(obj, cx_str("Name")); + cxstring type = serverconfig_object_directive_value(obj, cx_str("Type")); AuthDB *authdb = NULL; if(!cx_strcmp(type, cx_str("ldap"))) { LDAPConfig conf; - cxstring host = serverconfig_directive_value(obj, cx_str("Host")); - cxstring port = serverconfig_directive_value( obj, cx_str("Port")); - cxstring basedn = serverconfig_directive_value(obj, cx_str("BaseDN")); - cxstring binddn = serverconfig_directive_value(obj, cx_str("BindDN")); - cxstring basepw = serverconfig_directive_value(obj, cx_str("BindPW")); + cxstring host = serverconfig_object_directive_value(obj, cx_str("Host")); + cxstring port = serverconfig_object_directive_value( obj, cx_str("Port")); + cxstring basedn = serverconfig_object_directive_value(obj, cx_str("BaseDN")); + cxstring binddn = serverconfig_object_directive_value(obj, cx_str("BindDN")); + cxstring basepw = serverconfig_object_directive_value(obj, cx_str("BindPW")); conf.hostname = cx_strdup_a(cfg->a, host).ptr; conf.port = atoi(port.ptr); @@ -567,7 +571,7 @@ authdb = create_ldap_authdb(cfg, name.ptr, &conf); } else if(!cx_strcmp(type, cx_str("keyfile"))) { // we only need the file parameter - cxstring file = serverconfig_directive_value(obj, cx_str("File")); + cxstring file = serverconfig_object_directive_value(obj, cx_str("File")); if(file.length == 0) { log_ereport( LOG_MISCONFIG, @@ -595,11 +599,11 @@ lc.port = 8080; lc.nacceptors = 1; - cxstring name = serverconfig_directive_value(obj, cx_str("Name")); - cxstring port = serverconfig_directive_value(obj, cx_str("Port")); - cxstring vs = serverconfig_directive_value(obj, cx_str("DefaultVS")); - cxstring thrp = serverconfig_directive_value(obj, cx_str("Threadpool")); - cxstring blck = serverconfig_directive_value(obj, cx_str("BlockingIO")); + cxstring name = serverconfig_object_directive_value(obj, cx_str("Name")); + cxstring port = serverconfig_object_directive_value(obj, cx_str("Port")); + cxstring vs = serverconfig_object_directive_value(obj, cx_str("DefaultVS")); + cxstring thrp = serverconfig_object_directive_value(obj, cx_str("Threadpool")); + cxstring blck = serverconfig_object_directive_value(obj, cx_str("BlockingIO")); // TODO: use cx_strdup_pool? int64_t port_value; @@ -619,12 +623,12 @@ lc.blockingio = util_getboolean_s(blck, WS_FALSE); - cxstring ssl = serverconfig_directive_value(obj, cx_str("SSL")); + cxstring ssl = serverconfig_object_directive_value(obj, cx_str("SSL")); if(util_getboolean_s(ssl, WS_FALSE)) { - cxstring cert = serverconfig_directive_value(obj, cx_str("Cert")); - cxstring privkey = serverconfig_directive_value(obj, cx_str("Key")); - cxstring chain = serverconfig_directive_value(obj, cx_str("CertChain")); - cxstring disableprot = serverconfig_directive_value(obj, cx_str("SSLDisableProtocol")); + cxstring cert = serverconfig_object_directive_value(obj, cx_str("Cert")); + cxstring privkey = serverconfig_object_directive_value(obj, cx_str("Key")); + cxstring chain = serverconfig_object_directive_value(obj, cx_str("CertChain")); + cxstring disableprot = serverconfig_object_directive_value(obj, cx_str("SSLDisableProtocol")); WSBool config_ok = WS_TRUE; // TODO: log error @@ -670,12 +674,12 @@ int cfg_handle_vs(ServerConfiguration *cfg, ConfigNode *obj) { VirtualServer *vs = vs_new(); - vs->name = cx_strdup_a(cfg->a, serverconfig_directive_value(obj, cx_str("Name"))); - vs->host = cx_strdup_a(cfg->a, serverconfig_directive_value(obj, cx_str("Host"))); - vs->document_root = cx_strdup_a(cfg->a, serverconfig_directive_value(obj, cx_str("DocRoot"))); + vs->name = cx_strdup_a(cfg->a, serverconfig_object_directive_value(obj, cx_str("Name"))); + vs->host = cx_strdup_a(cfg->a, serverconfig_object_directive_value(obj, cx_str("Host"))); + vs->document_root = cx_strdup_a(cfg->a, serverconfig_object_directive_value(obj, cx_str("DocRoot"))); - cxstring objfile = serverconfig_directive_value(obj, cx_str("ObjectFile")); - cxstring aclfile = serverconfig_directive_value(obj, cx_str("ACLFile")); + cxstring objfile = serverconfig_object_directive_value(obj, cx_str("ObjectFile")); + cxstring aclfile = serverconfig_object_directive_value(obj, cx_str("ACLFile")); // load the object config file cxstring base = cx_str("config/"); @@ -797,7 +801,7 @@ cxListDestroy(backends); // initialize vfs - cxstring vfs_class = serverconfig_directive_value(obj, cx_str("VFS")); + cxstring vfs_class = serverconfig_object_directive_value(obj, cx_str("VFS")); if(vfs_class.length > 0) { VfsType *vfs = vfs_get_type((cxstring){vfs_class.ptr, vfs_class.length}); if(vfs) { @@ -812,7 +816,7 @@ } } - cxstring object = serverconfig_directive_value(obj, cx_str("Object")); + cxstring object = serverconfig_object_directive_value(obj, cx_str("Object")); if(object.length > 0) { repository->object = cx_strdup_a(a, object); if(repository->object.length != object.length) { diff -r 90805bb9fbd6 -r b7dcc9c4f270 src/server/plugins/postgresql/config.c --- a/src/server/plugins/postgresql/config.c Sun Nov 06 17:41:39 2022 +0100 +++ b/src/server/plugins/postgresql/config.c Mon Nov 07 17:59:44 2022 +0100 @@ -95,10 +95,10 @@ return NULL; } - cxstring cfg_respool = serverconfig_directive_value(pg, cx_str("ResourcePool")); - cxstring cfg_rootid = serverconfig_directive_value(pg, cx_str("RootId")); - cxstring cfg_rootnode = serverconfig_directive_value(pg, cx_str("RootNode")); - cxstring cfg_dav = serverconfig_directive_value(pg, cx_str("PGDavConfig")); + cxstring cfg_respool = serverconfig_object_directive_value(pg, cx_str("ResourcePool")); + cxstring cfg_rootid = serverconfig_object_directive_value(pg, cx_str("RootId")); + cxstring cfg_rootnode = serverconfig_object_directive_value(pg, cx_str("RootNode")); + cxstring cfg_dav = serverconfig_object_directive_value(pg, cx_str("PGDavConfig")); // minimum requirement is a resource pool if(cfg_respool.length == 0) { diff -r 90805bb9fbd6 -r b7dcc9c4f270 src/tools/wstool.c --- a/src/tools/wstool.c Sun Nov 06 17:41:39 2022 +0100 +++ b/src/tools/wstool.c Mon Nov 07 17:59:44 2022 +0100 @@ -72,7 +72,7 @@ return -1; } ConfigNode *runtime = cxListAt(list, 0); - cxstring tmp = serverconfig_directive_value(runtime, cx_str("Temp")); + cxstring tmp = serverconfig_object_directive_value(runtime, cx_str("Temp")); cxListDestroy(list);