68 } |
68 } |
69 |
69 |
70 int load_init_conf(char *file) { |
70 int load_init_conf(char *file) { |
71 log_ereport(LOG_VERBOSE, "load_init_conf"); |
71 log_ereport(LOG_VERBOSE, "load_init_conf"); |
72 |
72 |
73 InitConfig *cfg = load_init_config(file); |
73 InitConfig *cfg = initconfig_load(file); |
74 if(cfg == NULL) { |
74 if(cfg == NULL) { |
75 log_ereport(LOG_FAILURE, "Cannot load init.conf"); |
75 log_ereport(LOG_FAILURE, "Cannot load init.conf"); |
76 return 1; |
76 return 1; |
77 } |
77 } |
78 CxAllocator *mp = cfg->parser.mp; |
78 CxAllocator *mp = cfg->mp; |
79 |
79 init_pool = pool_create(); |
80 init_pool = pool_create(); // one pool for one Configuration |
80 |
81 ConfigDirectiveList *dirs = cfg->directives; |
81 ConfigNode *dir = cfg->root->children_begin; |
82 while(dirs != NULL) { |
82 while(dir) { |
83 ConfigDirective *dir = dirs->directive; |
83 if(dir->type != CONFIG_NODE_DIRECTIVE) { |
84 |
84 // dir is just space/comment |
85 /* create NSAPI directive */ |
85 dir = dir->next; |
86 directive *d = malloc(sizeof(directive)); |
86 continue; |
|
87 } |
|
88 |
|
89 // create NSAPI directive |
|
90 |
|
91 // The parser checks the directive name and makes sure it is "Init" |
|
92 // if more than one init directive type is introduced, the parser |
|
93 // must be extended and also dir->name must be checked here |
|
94 |
|
95 directive *d = pool_malloc(init_pool, sizeof(directive)); |
87 d->param = pblock_create_pool(init_pool, 8); |
96 d->param = pblock_create_pool(init_pool, 8); |
88 ConfigParam *param = cfg_param_list(dir->value, mp); |
97 |
|
98 ConfigParam *param = dir->args; |
89 while(param != NULL) { |
99 while(param != NULL) { |
90 pblock_nvlinsert( |
100 pblock_nvlinsert( |
91 param->name.ptr, |
101 param->name.ptr, |
92 param->name.length, |
102 param->name.length, |
93 param->value.ptr, |
103 param->value.ptr, |
94 param->value.length, |
104 param->value.length, |
95 d->param); |
105 d->param); |
96 |
106 |
97 param = param->next; |
107 param = param->next; |
98 } |
108 } |
99 |
109 |
100 /* get function */ |
110 // get function |
|
111 // the parser makes sure that an "fn" parameter always exists |
101 char *func_name = pblock_findval("fn", d->param); |
112 char *func_name = pblock_findval("fn", d->param); |
102 d->func = get_function(func_name); |
113 d->func = get_function(func_name); |
103 if(d->func == NULL) { |
114 if(d->func == NULL) { |
104 pblock_free(d->param); |
|
105 free(d); |
|
106 //dirs = dirs->next; |
|
107 log_ereport( |
115 log_ereport( |
108 LOG_MISCONFIG, |
116 LOG_MISCONFIG, |
109 "Cannot find Init function %s", |
117 "Cannot find Init function %s", |
110 func_name); |
118 func_name); |
111 return 1; |
119 return 1; |
112 } |
120 } |
113 |
121 |
114 /* execute init directive */ |
122 // execute init directive |
115 int ret = d->func->func(d->param, NULL, NULL); |
123 int ret = d->func->func(d->param, NULL, NULL); |
116 if(ret != REQ_PROCEED && ret != REQ_NOACTION) { |
124 if(ret != REQ_PROCEED && ret != REQ_NOACTION) { |
117 log_ereport( |
125 log_ereport( |
118 LOG_FAILURE, |
126 LOG_FAILURE, |
119 "Error running Init function %s", |
127 "Error running Init function %s", |
120 func_name); |
128 func_name); |
121 pblock_free(d->param); |
|
122 free(d); |
|
123 return 1; |
129 return 1; |
124 } |
130 } |
125 |
131 |
126 pblock_free(d->param); |
132 dir = dir->next; |
127 free(d); |
133 } |
128 dirs = dirs->next; |
134 |
129 } |
135 initconfig_free(cfg); |
130 |
|
131 free_init_config(cfg); |
|
132 |
136 |
133 return 0; |
137 return 0; |
134 } |
138 } |
135 |
139 |
136 ServerConfiguration* load_server_conf(CfgManager *mgr, char *file) { |
140 ServerConfiguration* load_server_conf(CfgManager *mgr, char *file) { |
354 void init_server_config_parser() { |
358 void init_server_config_parser() { |
355 |
359 |
356 } |
360 } |
357 |
361 |
358 int cfg_handle_runtime(ServerConfiguration *cfg, ConfigNode *obj) { |
362 int cfg_handle_runtime(ServerConfiguration *cfg, ConfigNode *obj) { |
359 cxstring user = serverconfig_directive_value(obj, cx_str("User")); |
363 cxstring user = serverconfig_object_directive_value(obj, cx_str("User")); |
360 if(user.ptr) { |
364 if(user.ptr) { |
361 cfg->user = cx_strdup_a(cfg->a, user); |
365 cfg->user = cx_strdup_a(cfg->a, user); |
362 } |
366 } |
363 cxstring tmp = serverconfig_directive_value(obj, cx_str("Temp")); |
367 cxstring tmp = serverconfig_object_directive_value(obj, cx_str("Temp")); |
364 if(tmp.ptr) { |
368 if(tmp.ptr) { |
365 cfg->tmp = cx_strdup_a(cfg->a, tmp); |
369 cfg->tmp = cx_strdup_a(cfg->a, tmp); |
366 } else { |
370 } else { |
367 // TODO: do this check after all config loading is done |
371 // TODO: do this check after all config loading is done |
368 log_ereport(LOG_MISCONFIG, "no temporary directory specified"); |
372 log_ereport(LOG_MISCONFIG, "no temporary directory specified"); |
369 return -1; |
373 return -1; |
370 } |
374 } |
371 |
375 |
372 // mime file |
376 // mime file |
373 cxstring mf = serverconfig_directive_value(obj, cx_str("MimeFile")); |
377 cxstring mf = serverconfig_object_directive_value(obj, cx_str("MimeFile")); |
374 cxstring base = cx_str("config/"); |
378 cxstring base = cx_str("config/"); |
375 cxmutstr file = cx_strcat(2, base, mf); |
379 cxmutstr file = cx_strcat(2, base, mf); |
376 |
380 |
377 if(mime_conf_load(cfg, file)) { |
381 if(mime_conf_load(cfg, file)) { |
378 return -1; |
382 return -1; |
381 free(file.ptr); |
385 free(file.ptr); |
382 return 0; |
386 return 0; |
383 } |
387 } |
384 |
388 |
385 int cfg_handle_logfile(ServerConfiguration *cfg, ConfigNode *obj) { |
389 int cfg_handle_logfile(ServerConfiguration *cfg, ConfigNode *obj) { |
386 cxstring file = serverconfig_directive_value(obj, cx_str("File")); |
390 cxstring file = serverconfig_object_directive_value(obj, cx_str("File")); |
387 cxstring lvl = serverconfig_directive_value(obj, cx_str("Level")); |
391 cxstring lvl = serverconfig_object_directive_value(obj, cx_str("Level")); |
388 |
392 |
389 int err = 0; |
393 int err = 0; |
390 if(file.ptr == NULL) { |
394 if(file.ptr == NULL) { |
391 err = 1; |
395 err = 1; |
392 log_ereport(LOG_MISCONFIG, "LogFile: parameter missing: File"); |
396 log_ereport(LOG_MISCONFIG, "LogFile: parameter missing: File"); |
417 poolcfg.min_threads = 4; |
421 poolcfg.min_threads = 4; |
418 poolcfg.max_threads = 8; |
422 poolcfg.max_threads = 8; |
419 poolcfg.queue_size = 64; |
423 poolcfg.queue_size = 64; |
420 poolcfg.stack_size = 262144; |
424 poolcfg.stack_size = 262144; |
421 |
425 |
422 cxstring name = serverconfig_directive_value(obj, cx_str("Name")); |
426 cxstring name = serverconfig_object_directive_value(obj, cx_str("Name")); |
423 cxstring min = serverconfig_directive_value(obj, cx_str("MinThreads")); |
427 cxstring min = serverconfig_object_directive_value(obj, cx_str("MinThreads")); |
424 cxstring max = serverconfig_directive_value(obj, cx_str("MaxThreads")); |
428 cxstring max = serverconfig_object_directive_value(obj, cx_str("MaxThreads")); |
425 cxstring stack = serverconfig_directive_value(obj, cx_str("StackSize")); |
429 cxstring stack = serverconfig_object_directive_value(obj, cx_str("StackSize")); |
426 cxstring queue = serverconfig_directive_value(obj, cx_str("QueueSize")); |
430 cxstring queue = serverconfig_object_directive_value(obj, cx_str("QueueSize")); |
427 // TODO: Type |
431 // TODO: Type |
428 |
432 |
429 if(name.length == 0) { |
433 if(name.length == 0) { |
430 // TODO: log error |
434 // TODO: log error |
431 return 1; |
435 return 1; |
476 |
480 |
477 #define EV_MAX_THREADS 2048 |
481 #define EV_MAX_THREADS 2048 |
478 int cfg_handle_eventhandler(ServerConfiguration *c, ConfigNode *obj) { |
482 int cfg_handle_eventhandler(ServerConfiguration *c, ConfigNode *obj) { |
479 EventHandlerConfig evcfg; |
483 EventHandlerConfig evcfg; |
480 |
484 |
481 cxstring name = serverconfig_directive_value(obj, cx_str("Name")); |
485 cxstring name = serverconfig_object_directive_value(obj, cx_str("Name")); |
482 cxstring threads = serverconfig_directive_value(obj, cx_str("Threads")); |
486 cxstring threads = serverconfig_object_directive_value(obj, cx_str("Threads")); |
483 cxstring isdefault = serverconfig_directive_value(obj, cx_str("Default")); |
487 cxstring isdefault = serverconfig_object_directive_value(obj, cx_str("Default")); |
484 |
488 |
485 evcfg.name = name; |
489 evcfg.name = name; |
486 |
490 |
487 int64_t value; |
491 int64_t value; |
488 if(!util_strtoint(threads.ptr, &value)) { |
492 if(!util_strtoint(threads.ptr, &value)) { |
500 |
504 |
501 return create_event_handler(&evcfg); |
505 return create_event_handler(&evcfg); |
502 } |
506 } |
503 |
507 |
504 int cfg_handle_resourcepool(ServerConfiguration *cfg, ConfigNode *obj) { |
508 int cfg_handle_resourcepool(ServerConfiguration *cfg, ConfigNode *obj) { |
505 cxstring name = serverconfig_directive_value(obj, cx_str("Name")); |
509 cxstring name = serverconfig_object_directive_value(obj, cx_str("Name")); |
506 cxstring type = serverconfig_directive_value(obj, cx_str("Type")); |
510 cxstring type = serverconfig_object_directive_value(obj, cx_str("Type")); |
507 |
511 |
508 int ret = 0; |
512 int ret = 0; |
509 if(resourcepool_new(cfg, type, name, obj)) { |
513 if(resourcepool_new(cfg, type, name, obj)) { |
510 ret = 1; |
514 ret = 1; |
511 } |
515 } |
542 |
546 |
543 return 0; |
547 return 0; |
544 } |
548 } |
545 |
549 |
546 int cfg_handle_authdb(ServerConfiguration *cfg, ConfigNode *obj) { |
550 int cfg_handle_authdb(ServerConfiguration *cfg, ConfigNode *obj) { |
547 cxstring name = serverconfig_directive_value(obj, cx_str("Name")); |
551 cxstring name = serverconfig_object_directive_value(obj, cx_str("Name")); |
548 cxstring type = serverconfig_directive_value(obj, cx_str("Type")); |
552 cxstring type = serverconfig_object_directive_value(obj, cx_str("Type")); |
549 |
553 |
550 AuthDB *authdb = NULL; |
554 AuthDB *authdb = NULL; |
551 |
555 |
552 if(!cx_strcmp(type, cx_str("ldap"))) { |
556 if(!cx_strcmp(type, cx_str("ldap"))) { |
553 LDAPConfig conf; |
557 LDAPConfig conf; |
554 |
558 |
555 cxstring host = serverconfig_directive_value(obj, cx_str("Host")); |
559 cxstring host = serverconfig_object_directive_value(obj, cx_str("Host")); |
556 cxstring port = serverconfig_directive_value( obj, cx_str("Port")); |
560 cxstring port = serverconfig_object_directive_value( obj, cx_str("Port")); |
557 cxstring basedn = serverconfig_directive_value(obj, cx_str("BaseDN")); |
561 cxstring basedn = serverconfig_object_directive_value(obj, cx_str("BaseDN")); |
558 cxstring binddn = serverconfig_directive_value(obj, cx_str("BindDN")); |
562 cxstring binddn = serverconfig_object_directive_value(obj, cx_str("BindDN")); |
559 cxstring basepw = serverconfig_directive_value(obj, cx_str("BindPW")); |
563 cxstring basepw = serverconfig_object_directive_value(obj, cx_str("BindPW")); |
560 |
564 |
561 conf.hostname = cx_strdup_a(cfg->a, host).ptr; |
565 conf.hostname = cx_strdup_a(cfg->a, host).ptr; |
562 conf.port = atoi(port.ptr); |
566 conf.port = atoi(port.ptr); |
563 conf.basedn = cx_strdup_a(cfg->a, basedn).ptr; |
567 conf.basedn = cx_strdup_a(cfg->a, basedn).ptr; |
564 conf.binddn = cx_strdup_a(cfg->a, binddn).ptr; |
568 conf.binddn = cx_strdup_a(cfg->a, binddn).ptr; |
565 conf.bindpw = cx_strdup_a(cfg->a, basepw).ptr; |
569 conf.bindpw = cx_strdup_a(cfg->a, basepw).ptr; |
566 |
570 |
567 authdb = create_ldap_authdb(cfg, name.ptr, &conf); |
571 authdb = create_ldap_authdb(cfg, name.ptr, &conf); |
568 } else if(!cx_strcmp(type, cx_str("keyfile"))) { |
572 } else if(!cx_strcmp(type, cx_str("keyfile"))) { |
569 // we only need the file parameter |
573 // we only need the file parameter |
570 cxstring file = serverconfig_directive_value(obj, cx_str("File")); |
574 cxstring file = serverconfig_object_directive_value(obj, cx_str("File")); |
571 if(file.length == 0) { |
575 if(file.length == 0) { |
572 log_ereport( |
576 log_ereport( |
573 LOG_MISCONFIG, |
577 LOG_MISCONFIG, |
574 "missing File parameter for keyfile authdb"); |
578 "missing File parameter for keyfile authdb"); |
575 return 1; |
579 return 1; |
593 ZERO(&lc, sizeof(ListenerConfig)); |
597 ZERO(&lc, sizeof(ListenerConfig)); |
594 lc.cfg = cfg; |
598 lc.cfg = cfg; |
595 lc.port = 8080; |
599 lc.port = 8080; |
596 lc.nacceptors = 1; |
600 lc.nacceptors = 1; |
597 |
601 |
598 cxstring name = serverconfig_directive_value(obj, cx_str("Name")); |
602 cxstring name = serverconfig_object_directive_value(obj, cx_str("Name")); |
599 cxstring port = serverconfig_directive_value(obj, cx_str("Port")); |
603 cxstring port = serverconfig_object_directive_value(obj, cx_str("Port")); |
600 cxstring vs = serverconfig_directive_value(obj, cx_str("DefaultVS")); |
604 cxstring vs = serverconfig_object_directive_value(obj, cx_str("DefaultVS")); |
601 cxstring thrp = serverconfig_directive_value(obj, cx_str("Threadpool")); |
605 cxstring thrp = serverconfig_object_directive_value(obj, cx_str("Threadpool")); |
602 cxstring blck = serverconfig_directive_value(obj, cx_str("BlockingIO")); |
606 cxstring blck = serverconfig_object_directive_value(obj, cx_str("BlockingIO")); |
603 |
607 |
604 // TODO: use cx_strdup_pool? |
608 // TODO: use cx_strdup_pool? |
605 int64_t port_value; |
609 int64_t port_value; |
606 if(!util_strtoint(port.ptr, &port_value)) { |
610 if(!util_strtoint(port.ptr, &port_value)) { |
607 log_ereport(LOG_MISCONFIG, "Listener: Invalid argument for parameter 'Port': '%s'", port.ptr); |
611 log_ereport(LOG_MISCONFIG, "Listener: Invalid argument for parameter 'Port': '%s'", port.ptr); |
617 lc.vs = cx_strdup(vs); |
621 lc.vs = cx_strdup(vs); |
618 lc.threadpool = cx_strdup(thrp); |
622 lc.threadpool = cx_strdup(thrp); |
619 |
623 |
620 lc.blockingio = util_getboolean_s(blck, WS_FALSE); |
624 lc.blockingio = util_getboolean_s(blck, WS_FALSE); |
621 |
625 |
622 cxstring ssl = serverconfig_directive_value(obj, cx_str("SSL")); |
626 cxstring ssl = serverconfig_object_directive_value(obj, cx_str("SSL")); |
623 if(util_getboolean_s(ssl, WS_FALSE)) { |
627 if(util_getboolean_s(ssl, WS_FALSE)) { |
624 cxstring cert = serverconfig_directive_value(obj, cx_str("Cert")); |
628 cxstring cert = serverconfig_object_directive_value(obj, cx_str("Cert")); |
625 cxstring privkey = serverconfig_directive_value(obj, cx_str("Key")); |
629 cxstring privkey = serverconfig_object_directive_value(obj, cx_str("Key")); |
626 cxstring chain = serverconfig_directive_value(obj, cx_str("CertChain")); |
630 cxstring chain = serverconfig_object_directive_value(obj, cx_str("CertChain")); |
627 cxstring disableprot = serverconfig_directive_value(obj, cx_str("SSLDisableProtocol")); |
631 cxstring disableprot = serverconfig_object_directive_value(obj, cx_str("SSLDisableProtocol")); |
628 |
632 |
629 WSBool config_ok = WS_TRUE; |
633 WSBool config_ok = WS_TRUE; |
630 // TODO: log error |
634 // TODO: log error |
631 if(!cert.ptr && !chain.ptr) { |
635 if(!cert.ptr && !chain.ptr) { |
632 log_ereport( |
636 log_ereport( |
668 } |
672 } |
669 |
673 |
670 int cfg_handle_vs(ServerConfiguration *cfg, ConfigNode *obj) { |
674 int cfg_handle_vs(ServerConfiguration *cfg, ConfigNode *obj) { |
671 VirtualServer *vs = vs_new(); |
675 VirtualServer *vs = vs_new(); |
672 |
676 |
673 vs->name = cx_strdup_a(cfg->a, serverconfig_directive_value(obj, cx_str("Name"))); |
677 vs->name = cx_strdup_a(cfg->a, serverconfig_object_directive_value(obj, cx_str("Name"))); |
674 vs->host = cx_strdup_a(cfg->a, serverconfig_directive_value(obj, cx_str("Host"))); |
678 vs->host = cx_strdup_a(cfg->a, serverconfig_object_directive_value(obj, cx_str("Host"))); |
675 vs->document_root = cx_strdup_a(cfg->a, serverconfig_directive_value(obj, cx_str("DocRoot"))); |
679 vs->document_root = cx_strdup_a(cfg->a, serverconfig_object_directive_value(obj, cx_str("DocRoot"))); |
676 |
680 |
677 cxstring objfile = serverconfig_directive_value(obj, cx_str("ObjectFile")); |
681 cxstring objfile = serverconfig_object_directive_value(obj, cx_str("ObjectFile")); |
678 cxstring aclfile = serverconfig_directive_value(obj, cx_str("ACLFile")); |
682 cxstring aclfile = serverconfig_object_directive_value(obj, cx_str("ACLFile")); |
679 |
683 |
680 // load the object config file |
684 // load the object config file |
681 cxstring base = cx_str("config/"); |
685 cxstring base = cx_str("config/"); |
682 // cx_strcat with allocator because we want to keep the string |
686 // cx_strcat with allocator because we want to keep the string |
683 cxmutstr file = cx_strcat_a(cfg->a, 2, base, objfile); |
687 cxmutstr file = cx_strcat_a(cfg->a, 2, base, objfile); |
795 cxListAdd(repository->davBackends, davInit); |
799 cxListAdd(repository->davBackends, davInit); |
796 } |
800 } |
797 cxListDestroy(backends); |
801 cxListDestroy(backends); |
798 |
802 |
799 // initialize vfs |
803 // initialize vfs |
800 cxstring vfs_class = serverconfig_directive_value(obj, cx_str("VFS")); |
804 cxstring vfs_class = serverconfig_object_directive_value(obj, cx_str("VFS")); |
801 if(vfs_class.length > 0) { |
805 if(vfs_class.length > 0) { |
802 VfsType *vfs = vfs_get_type((cxstring){vfs_class.ptr, vfs_class.length}); |
806 VfsType *vfs = vfs_get_type((cxstring){vfs_class.ptr, vfs_class.length}); |
803 if(vfs) { |
807 if(vfs) { |
804 repository->vfs = vfs; |
808 repository->vfs = vfs; |
805 repository->vfsInitData = vfs_init_backend(cfg, cfg->pool, vfs, obj, &init_error); |
809 repository->vfsInitData = vfs_init_backend(cfg, cfg->pool, vfs, obj, &init_error); |
810 log_ereport(LOG_FAILURE, "Unknown vfs type '%s'", vfs_class.ptr); |
814 log_ereport(LOG_FAILURE, "Unknown vfs type '%s'", vfs_class.ptr); |
811 ret = 1; |
815 ret = 1; |
812 } |
816 } |
813 } |
817 } |
814 |
818 |
815 cxstring object = serverconfig_directive_value(obj, cx_str("Object")); |
819 cxstring object = serverconfig_object_directive_value(obj, cx_str("Object")); |
816 if(object.length > 0) { |
820 if(object.length > 0) { |
817 repository->object = cx_strdup_a(a, object); |
821 repository->object = cx_strdup_a(a, object); |
818 if(repository->object.length != object.length) { |
822 if(repository->object.length != object.length) { |
819 // OOM |
823 // OOM |
820 log_ereport(LOG_FAILURE, "Cannot create webdav repository: OOM"); |
824 log_ereport(LOG_FAILURE, "Cannot create webdav repository: OOM"); |