src/server/daemon/config.c

branch
config
changeset 255
b5d15a4a19f5
parent 254
4784c14aa639
child 256
19259b6c5cf7
equal deleted inserted replaced
254:4784c14aa639 255:b5d15a4a19f5
53 #include "../util/pblock.h" 53 #include "../util/pblock.h"
54 #include "../util/util.h" 54 #include "../util/util.h"
55 #include "../util/atomic.h" 55 #include "../util/atomic.h"
56 #include "ucx/buffer.h" 56 #include "ucx/buffer.h"
57 57
58 pool_handle_t *cfg_pool; 58 pool_handle_t *init_pool;
59 59
60 // TODO: Funktion für ConfigDirective -> directive
61 // TODO: Funktion für UcxList parameter list -> pblock
62 60
63 int load_init_conf(char *file) { 61 int load_init_conf(char *file) {
64 log_ereport(LOG_VERBOSE, "load_init_conf"); 62 log_ereport(LOG_VERBOSE, "load_init_conf");
65 63
66 InitConfig *cfg = load_init_config(file); 64 InitConfig *cfg = load_init_config(file);
68 log_ereport(LOG_FAILURE, "Cannot load init.conf"); 66 log_ereport(LOG_FAILURE, "Cannot load init.conf");
69 return 1; 67 return 1;
70 } 68 }
71 UcxAllocator *mp = cfg->parser.mp; 69 UcxAllocator *mp = cfg->parser.mp;
72 70
73 cfg_pool = pool_create(); // one pool for one Configuration 71 init_pool = pool_create(); // one pool for one Configuration
74 UcxList *dirs = cfg->directives; 72 UcxList *dirs = cfg->directives;
75 while(dirs != NULL) { 73 while(dirs != NULL) {
76 ConfigDirective *dir = dirs->data; 74 ConfigDirective *dir = dirs->data;
77 75
78 /* create NSAPI directive */ 76 /* create NSAPI directive */
79 directive *d = malloc(sizeof(directive)); 77 directive *d = malloc(sizeof(directive));
80 d->param = pblock_create_pool(cfg_pool, 8); 78 d->param = pblock_create_pool(init_pool, 8);
81 UcxList *param = cfg_param_list(dir->value, mp); 79 UcxList *param = cfg_param_list(dir->value, mp);
82 while(param != NULL) { 80 while(param != NULL) {
83 ConfigParam *p = param->data; 81 ConfigParam *p = param->data;
84 pblock_nvlinsert( 82 pblock_nvlinsert(
85 p->name.ptr, 83 p->name.ptr,
125 free_init_config(cfg); 123 free_init_config(cfg);
126 124
127 return 0; 125 return 0;
128 } 126 }
129 127
130 ServerConfiguration* load_server_conf(ServerConfiguration *old, char *file) { 128 ServerConfiguration* load_server_conf(char *file) {
131 log_ereport(LOG_VERBOSE, "load_server_conf"); 129 log_ereport(LOG_VERBOSE, "load_server_conf");
132 130
133 ServerConfig2 *serverconf = load_server_config(file); 131 ServerConfig2 *serverconf2 = load_server_config(file);
134 if(serverconf == NULL) { 132 if(serverconf2 == NULL) {
135 log_ereport(LOG_FAILURE, "Cannot load server.conf"); 133 log_ereport(LOG_FAILURE, "Cannot load server.conf");
136 } 134 }
137 ServerConfiguration *serverconfig = calloc(1, sizeof(ServerConfiguration)); 135 pool_handle_t *pool = pool_create();
136
137
138 ServerConfiguration *serverconfig = pool_calloc(pool, 1, sizeof(ServerConfiguration));
138 serverconfig->ref = 1; 139 serverconfig->ref = 1;
139 serverconfig->pool = pool_create(); 140 serverconfig->pool = pool;
140 serverconfig->listeners = NULL; 141 serverconfig->listeners = NULL;
141 serverconfig->host_vs = ucx_map_new(16); 142 serverconfig->host_vs = ucx_map_new(16);
142 serverconfig->authdbs = ucx_map_new(16); 143 serverconfig->authdbs = ucx_map_new(16);
144
145 UcxAllocator allocator = util_pool_allocator(serverconfig->pool);
146 serverconfig->a = pool_malloc(pool, sizeof(UcxAllocator));
147 *serverconfig->a = allocator;
148
143 // TODO: init serverconfig stuff 149 // TODO: init serverconfig stuff
144 150
145 151
146 /* 152 /*
147 * convert ServerConfig to ServerConfiguration 153 * convert ServerConfig to ServerConfiguration
159 /* 165 /*
160 * free stuff on error 166 * free stuff on error
161 */ 167 */
162 168
163 // init logfile first 169 // init logfile first
164 UcxList *lfl = ucx_map_sstr_get(serverconf->objects, sstrn("LogFile", 7)); 170 UcxList *lfl = ucx_map_sstr_get(serverconf2->objects, sstrn("LogFile", 7));
165 if(lfl != NULL) { 171 if(lfl != NULL) {
166 ServerConfigObject *logobj = lfl->data; 172 ServerConfigObject *logobj = lfl->data;
167 if(logobj == NULL) { 173 if(logobj == NULL) {
168 // error 174 // error
169 return NULL; 175 return NULL;
177 } else { 183 } else {
178 // horrible error 184 // horrible error
179 return NULL; 185 return NULL;
180 } 186 }
181 187
182 UcxList *list = ucx_map_sstr_get(serverconf->objects, sstrn("Runtime", 7)); 188 UcxList *list = ucx_map_sstr_get(serverconf2->objects, sstrn("Runtime", 7));
183 UCX_FOREACH(elm, list) { 189 UCX_FOREACH(elm, list) {
184 ServerConfigObject *scfgobj = elm->data; 190 ServerConfigObject *scfgobj = elm->data;
185 if(cfg_handle_runtime(serverconfig, scfgobj)) { 191 if(cfg_handle_runtime(serverconfig, scfgobj)) {
186 // error 192 // error
187 return NULL; 193 return NULL;
188 } 194 }
189 } 195 }
190 196
191 list = ucx_map_sstr_get(serverconf->objects, sstrn("Threadpool", 10)); 197 list = ucx_map_sstr_get(serverconf2->objects, sstrn("Threadpool", 10));
192 UCX_FOREACH(elm, list) { 198 UCX_FOREACH(elm, list) {
193 if(cfg_handle_threadpool(serverconfig, elm->data)) { 199 if(cfg_handle_threadpool(serverconfig, elm->data)) {
194 return NULL; 200 return NULL;
195 } 201 }
196 } 202 }
198 if(check_thread_pool_cfg() != 0) { 204 if(check_thread_pool_cfg() != 0) {
199 /* critical error */ 205 /* critical error */
200 return NULL; 206 return NULL;
201 } 207 }
202 208
203 list = ucx_map_sstr_get(serverconf->objects, sstrn("EventHandler", 12)); 209 list = ucx_map_sstr_get(serverconf2->objects, sstrn("EventHandler", 12));
204 UCX_FOREACH(elm, list) { 210 UCX_FOREACH(elm, list) {
205 if(cfg_handle_eventhandler( 211 if(cfg_handle_eventhandler(
206 serverconfig, (ServerConfigObject*)elm->data)) { 212 serverconfig, (ServerConfigObject*)elm->data)) {
207 // error 213 // error
208 return NULL; 214 return NULL;
212 if(check_event_handler_cfg() != 0) { 218 if(check_event_handler_cfg() != 0) {
213 /* critical error */ 219 /* critical error */
214 return NULL; 220 return NULL;
215 } 221 }
216 222
217 list = ucx_map_sstr_get(serverconf->objects, sstrn("AccessLog", 9)); 223 list = ucx_map_sstr_get(serverconf2->objects, sstrn("AccessLog", 9));
218 UCX_FOREACH(elm, list) { 224 UCX_FOREACH(elm, list) {
219 ServerConfigObject *scfgobj = elm->data; 225 ServerConfigObject *scfgobj = elm->data;
220 if(cfg_handle_accesslog(serverconfig, scfgobj)) { 226 if(cfg_handle_accesslog(serverconfig, scfgobj)) {
221 return NULL; 227 return NULL;
222 } 228 }
223 } 229 }
224 230
225 list = ucx_map_sstr_get(serverconf->objects, sstrn("AuthDB", 6)); 231 list = ucx_map_sstr_get(serverconf2->objects, sstrn("AuthDB", 6));
226 UCX_FOREACH(elm, list) { 232 UCX_FOREACH(elm, list) {
227 ServerConfigObject *scfgobj = elm->data; 233 ServerConfigObject *scfgobj = elm->data;
228 if(cfg_handle_authdb(serverconfig, scfgobj)) { 234 if(cfg_handle_authdb(serverconfig, scfgobj)) {
229 return NULL; 235 return NULL;
230 } 236 }
231 } 237 }
232 238
233 list = ucx_map_sstr_get(serverconf->objects, sstrn("Listener", 8)); 239 list = ucx_map_sstr_get(serverconf2->objects, sstrn("Listener", 8));
234 UCX_FOREACH(elm, list) { 240 UCX_FOREACH(elm, list) {
235 ServerConfigObject *scfgobj = elm->data; 241 ServerConfigObject *scfgobj = elm->data;
236 if(cfg_handle_listener(serverconfig, scfgobj)) { 242 if(cfg_handle_listener(serverconfig, scfgobj)) {
237 return NULL; 243 return NULL;
238 } 244 }
239 } 245 }
240 246
241 list = ucx_map_sstr_get(serverconf->objects, sstrn("VirtualServer", 13)); 247 list = ucx_map_sstr_get(serverconf2->objects, sstrn("VirtualServer", 13));
242 UCX_FOREACH(elm, list) { 248 UCX_FOREACH(elm, list) {
243 ServerConfigObject *scfgobj = elm->data; 249 ServerConfigObject *scfgobj = elm->data;
244 if(cfg_handle_vs(serverconfig, scfgobj)) { 250 if(cfg_handle_vs(serverconfig, scfgobj)) {
245 return NULL; 251 return NULL;
246 } 252 }
266 } 272 }
267 273
268 ls = ls->next; 274 ls = ls->next;
269 } 275 }
270 276
271 free_server_config(serverconf); 277 free_server_config(serverconf2);
272 return serverconfig; 278 return serverconfig;
273 } 279 }
274 280
275 void cfg_ref(ServerConfiguration *cfg) { 281 void cfg_ref(ServerConfiguration *cfg) {
276 ws_atomic_inc32(&cfg->ref); 282 ws_atomic_inc32(&cfg->ref);
277 } 283 }
278 284
279 void cfg_unref(ServerConfiguration *cfg) { 285 void cfg_unref(ServerConfiguration *cfg) {
280 uint32_t ref = ws_atomic_dec32(&cfg->ref); 286 uint32_t ref = ws_atomic_dec32(&cfg->ref);
281 if(ref == 0) { 287 if(ref == 0) {
282 // TODO: free configuration 288 pool_destroy(cfg->pool);
283 printf("free ServerConfiguration %"PRIxPTR"\n", (intptr_t)cfg);
284 } 289 }
285 } 290 }
286 291
287 292
288 void init_server_config_parser() { 293 void init_server_config_parser() {
305 // mime file 310 // mime file
306 sstr_t mf = cfg_directivelist_get_str(obj->directives, sstr("MimeFile")); 311 sstr_t mf = cfg_directivelist_get_str(obj->directives, sstr("MimeFile"));
307 sstr_t base = sstr("config/"); 312 sstr_t base = sstr("config/");
308 sstr_t file = sstrcat(2, base, mf); 313 sstr_t file = sstrcat(2, base, mf);
309 314
310 ConfigFile *f = cfgmgr_get_file(file); 315 if(mime_conf_load(cfg, file)) {
311 if(f == NULL) { 316 return -1;
312 f = malloc(sizeof(ConfigFile)); 317 }
313 f->data = NULL;
314 f->file = sstrdup(file);
315 f->reload = mime_conf_reload;
316 f->last_modified = 0;
317
318 // load the file content
319 //f->reload(f, cfg);
320 if(cfgmgr_reload_file(f, cfg, NULL)) {
321 free(f->file.ptr);
322 free(f);
323
324 free(file.ptr);
325 return -1;
326 }
327 cfgmgr_attach_file(f);
328 }
329
330 cfg->mimetypes = f->data;
331 318
332 free(file.ptr); 319 free(file.ptr);
333 return 0; 320 return 0;
334 } 321 }
335 322
469 } 456 }
470 457
471 int cfg_handle_authdb(ServerConfiguration *cfg, ServerConfigObject *obj) { 458 int cfg_handle_authdb(ServerConfiguration *cfg, ServerConfigObject *obj) {
472 sstr_t name = cfg_directivelist_get_str(obj->directives, sstr("Name")); 459 sstr_t name = cfg_directivelist_get_str(obj->directives, sstr("Name"));
473 sstr_t type = cfg_directivelist_get_str(obj->directives, sstr("Type")); 460 sstr_t type = cfg_directivelist_get_str(obj->directives, sstr("Type"));
461
462 AuthDB *authdb = NULL;
474 463
475 if(!sstrcmp(type, sstr("ldap"))) { 464 if(!sstrcmp(type, sstr("ldap"))) {
476 LDAPConfig conf; 465 LDAPConfig conf;
477 466
478 sstr_t host = cfg_directivelist_get_str( 467 sstr_t host = cfg_directivelist_get_str(
503 conf.binddn = binddn.ptr; 492 conf.binddn = binddn.ptr;
504 conf.bindpw = basepw.ptr; 493 conf.bindpw = basepw.ptr;
505 494
506 name = sstrdup(name); 495 name = sstrdup(name);
507 496
508 AuthDB *authdb = create_ldap_authdb(name.ptr, &conf); 497 authdb = create_ldap_authdb(name.ptr, &conf);
509 ucx_map_sstr_put(cfg->authdbs, name, authdb);
510 498
511 // TODO: create_ldap_authdb should copy the strings 499 // TODO: create_ldap_authdb should copy the strings
512 /* 500 /*
513 free(host.ptr); 501 free(host.ptr);
514 free(port.ptr); 502 free(port.ptr);
529 "missing File parameter for keyfile authdb"); 517 "missing File parameter for keyfile authdb");
530 return 1; 518 return 1;
531 } 519 }
532 520
533 // load keyfile 521 // load keyfile
534 ConfigFile *f = cfgmgr_get_file(file); 522 authdb = keyfile_load(cfg, file);
535 if(f == NULL) { 523 }
536 f = malloc(sizeof(ConfigFile)); 524
537 f->data = NULL; 525 if(authdb) {
538 f->file = sstrdup(file); 526 if(ucx_map_sstr_put(cfg->authdbs, name, authdb)) {
539 f->reload = keyfile_reload; 527 return -1;
540 f->last_modified = 0; 528 }
541 //f->reload(f, cfg); 529 }
542 if(cfgmgr_reload_file(f, cfg, NULL)) { 530
543 free(f->file.ptr);
544 free(f);
545 return -1;
546 }
547 cfgmgr_attach_file(f);
548 }
549
550 // add keyfile authdb
551 Keyfile *keyfile = f->data;
552 keyfile->authdb.name = sstrdup(name).ptr;
553 ucx_map_sstr_put(cfg->authdbs, name, keyfile);
554 }
555
556 return 0; 531 return 0;
557 } 532 }
558 533
559 int cfg_handle_listener(ServerConfiguration *cfg, ServerConfigObject *obj) { 534 int cfg_handle_listener(ServerConfiguration *cfg, ServerConfigObject *obj) {
560 ListenerConfig lc; 535 ListenerConfig lc;
654 sstr("ACLFile")); 629 sstr("ACLFile"));
655 630
656 // load the object config file 631 // load the object config file
657 sstr_t base = sstr("config/"); 632 sstr_t base = sstr("config/");
658 sstr_t file = sstrcat(2, base, objfile); 633 sstr_t file = sstrcat(2, base, objfile);
659 file = sstrcat(2, base, objfile); 634 // sstrcat with allocator because we want to keep the string
660 635 file = sstrcat_a(cfg->a, 2, base, objfile);
661 // the file is managed by the configuration manager 636
662 ConfigFile *f = cfgmgr_get_file(file); 637 HTTPObjectConfig *httpobj = objconf_load(cfg, file);
663 if(f == NULL) { 638 if(!httpobj) {
664 f = malloc(sizeof(ConfigFile)); 639 return -1;
665 f->data = NULL; 640 }
666 f->file = sstrdup(file); 641 vs->objectfile = file;
667 f->reload = object_conf_reload; 642 vs->objects = httpobj;
668 f->last_modified = 0;
669 //f->reload(f, cfg);
670 if(cfgmgr_reload_file(f, cfg, NULL)) {
671 free(f->file.ptr);
672 free(f);
673
674 free(file.ptr);
675 return -1;
676 }
677 cfgmgr_attach_file(f);
678 }
679 vs->objectfile = sstrdup(file);
680 vs->objects = (HTTPObjectConfig*)f->data;
681 free(file.ptr);
682 643
683 644
684 // load acl config file 645 // load acl config file
685 file = sstrcat(2, base, aclfile); 646 file = sstrcat(2, base, aclfile);
686 647
687 ConfigFile *aclf = cfgmgr_get_file(file); 648 ACLData *acldata = acl_conf_load(cfg, file);
688 if(aclf == NULL) { 649 if(!acldata) {
689 aclf = malloc(sizeof(ConfigFile)); 650 return -1;
690 aclf->data = NULL; 651 }
691 aclf->file = sstrdup(file); 652 vs->acls = acldata;
692 aclf->reload = acl_conf_reload; 653
693 aclf->last_modified = 0;
694 //aclf->reload(aclf, cfg);
695 if(cfgmgr_reload_file(aclf, cfg, NULL)) {
696 free(aclf->file.ptr);
697 free(aclf);
698
699 free(file.ptr);
700 return -1;
701 }
702 cfgmgr_attach_file(aclf);
703 }
704 vs->acls = aclf->data;
705 free(file.ptr); 654 free(file.ptr);
706 655
656
707 // set the access log for the virtual server 657 // set the access log for the virtual server
708 // TODO: don't use always the default 658 // TODO: don't always use the default
709 vs->log = cfg->default_log; 659 vs->log = cfg->default_log;
710 660
711 ucx_map_sstr_put(cfg->host_vs, vs->host, vs); 661 ucx_map_sstr_put(cfg->host_vs, vs->host, vs);
712 662
713 return 0; 663 return 0;
714 } 664 }
715 665
716 666
717 int object_conf_reload(ConfigFile *file, ServerConfiguration *cfg) { 667 static int convert_objconf(ServerConfiguration *scfg, ObjectConfig *cfg, HTTPObjectConfig *conf, sstr_t file) {
718 HTTPObjectConfig *old_conf = file->data; 668 pool_handle_t *pool = conf->pool;
719 file->data = load_obj_conf(file->file.ptr);
720 if(old_conf) {
721 object_conf_unref(old_conf);
722 }
723 if(file->data) {
724 return 0;
725 } else {
726 return 1;
727 }
728 }
729
730 void object_conf_ref(HTTPObjectConfig *conf) {
731 if(conf) {
732 ws_atomic_inc32(&conf->ref);
733 }
734 }
735
736 void object_conf_unref(HTTPObjectConfig *conf) {
737 uint32_t ref = ws_atomic_dec32(&conf->ref);
738 if(ref == 0) {
739 printf("free HTTPObjectConfig %"PRIxPTR"\n", (intptr_t)conf);
740 pool_destroy(conf->pool);
741 }
742 }
743
744 HTTPObjectConfig* load_obj_conf(char *file) {
745 log_ereport(LOG_VERBOSE, "load_obj_conf");
746
747 // new conf function test
748 ObjectConfig *cfg = load_object_config(file);
749 UcxAllocator *mp = cfg->parser.mp;
750 if(cfg == NULL) {
751 return NULL;
752 }
753
754 // create object config
755 pool_handle_t *pool = pool_create();
756 HTTPObjectConfig *conf = pool_calloc(pool, sizeof(HTTPObjectConfig), 1);
757 conf->pool = pool;
758
759 // convert ObjectConfig to HTTPObjectConfig
760
761 // add objects
762 conf->nobj = ucx_list_size(cfg->objects);
763 conf->objects = pool_calloc(pool, conf->nobj, sizeof(httpd_object*));
764 669
765 UcxList *objlist = cfg->objects; 670 UcxList *objlist = cfg->objects;
766 int i = 0; 671 int i = 0;
767 while(objlist != NULL) { 672 while(objlist != NULL) {
768 ConfigObject *cob = objlist->data; 673 ConfigObject *cob = objlist->data;
770 // get name and ppath 675 // get name and ppath
771 char *name = NULL; 676 char *name = NULL;
772 char *ppath = NULL; 677 char *ppath = NULL;
773 if(cob->name.length > 0) { 678 if(cob->name.length > 0) {
774 name = sstrdup_pool(pool, cob->name).ptr; 679 name = sstrdup_pool(pool, cob->name).ptr;
680 if(!name) return -1;
775 } 681 }
776 if(cob->ppath.length > 0) { 682 if(cob->ppath.length > 0) {
777 ppath = sstrdup_pool(pool, cob->ppath).ptr; 683 ppath = sstrdup_pool(pool, cob->ppath).ptr;
684 if(!ppath) return -1;
778 } 685 }
779 686
780 // create and add object 687 // create and add object
781 httpd_object *obj = object_new(pool, name); 688 httpd_object *obj = object_new(pool, name);
689 if(!obj) return -1;
782 obj->path = NULL; 690 obj->path = NULL;
783 691
784 conf->objects[i] = obj; 692 conf->objects[i] = obj;
785 693
786 // add directives 694 // add directives
787 for(int j=0;j<NUM_NSAPI_TYPES-1;j++) { 695 for(int j=0;j<NUM_NSAPI_TYPES-1;j++) {
788 UcxList *dirs = cob->directives[j]; 696 UcxList *dirs = cob->directives[j];
789 while(dirs != NULL) { 697 while(dirs != NULL) {
790 ConfigDirective *cfgdir = dirs->data; 698 ConfigDirective *cfgdir = dirs->data;
791 699
792 directive *d = pool_malloc(pool, sizeof(directive)); 700 directive *d = pool_malloc(pool, sizeof(directive));
701 if(!d) return -1;
793 if(cfgdir->condition) { 702 if(cfgdir->condition) {
794 sstr_t expr = cfgdir->condition->param_str; 703 sstr_t expr = cfgdir->condition->param_str;
795 d->cond = condition_from_str(pool, expr.ptr, expr.length); 704 d->cond = condition_from_str(pool, expr.ptr, expr.length);
796 } else { 705 } else {
797 d->cond = NULL; 706 d->cond = NULL;
798 } 707 }
799 d->param = pblock_create_pool(pool, 8); 708 d->param = pblock_create_pool(pool, 8);
800 709
801 // add params 710 // add params
802 UcxList *param = cfg_param_list(cfgdir->value, mp); 711 UcxList *param = cfg_param_list(cfgdir->value, scfg->a);
803 while(param != NULL) { 712 while(param != NULL) {
804 ConfigParam *p = param->data; 713 ConfigParam *p = param->data;
805 pblock_nvlinsert( 714 pblock_nvlinsert(
806 p->name.ptr, 715 p->name.ptr,
807 p->name.length, 716 p->name.length,
812 } 721 }
813 722
814 // get function 723 // get function
815 char *func_name = pblock_findval("fn", d->param); 724 char *func_name = pblock_findval("fn", d->param);
816 if(!func_name) { 725 if(!func_name) {
817 log_ereport(LOG_MISCONFIG, "%s: Missing fn parameter", file); 726 log_ereport(LOG_MISCONFIG, "%s: Missing fn parameter", file.ptr);
818 return NULL; 727 return -1;
819 } 728 }
820 d->func = get_function(func_name); 729 d->func = get_function(func_name);
821 if(!d->func) { 730 if(!d->func) {
822 log_ereport(LOG_MISCONFIG, "func %s not found", func_name); 731 log_ereport(LOG_MISCONFIG, "func %s not found", func_name);
823 return NULL; 732 return -1;
824 } 733 }
825 734
826 dirs = dirs->next; 735 dirs = dirs->next;
827 736
828 // add function to dtable 737 // add function to dtable
832 741
833 // next 742 // next
834 i++; 743 i++;
835 objlist = objlist->next; 744 objlist = objlist->next;
836 } 745 }
746
747 return 0;
748 }
749
750 HTTPObjectConfig* objconf_load(ServerConfiguration *scfg, sstr_t file) {
751 log_ereport(LOG_VERBOSE, "load_obj_conf");
752
753 int ret = 0;
754
755 // create object config
756 pool_handle_t *pool = scfg->pool;
757 HTTPObjectConfig *conf = pool_calloc(pool, sizeof(HTTPObjectConfig), 1);
758 if(!conf) {
759 return NULL;
760 }
761 conf->pool = pool;
762
763 // load obj config file
764 ObjectConfig *cfg = load_object_config(file.ptr);
765 if(!cfg) {
766 return NULL;
767 }
768
769 // convert ObjectConfig to HTTPObjectConfig
770
771 // add objects
772 conf->nobj = ucx_list_size(cfg->objects);
773 conf->objects = pool_calloc(pool, conf->nobj, sizeof(httpd_object*));
774 if(conf->objects) {
775 ret = convert_objconf(scfg, cfg, conf, file);
776 } else {
777 ret = -1;
778 }
837 779
838 free_object_config(cfg); 780 free_object_config(cfg);
839 781
840 return conf; 782 return !ret ? conf : NULL;
841 } 783 }
842 784
843 int mime_conf_reload(ConfigFile *file, ServerConfiguration *cfg) { 785 int mime_conf_load(ServerConfiguration *cfg, sstr_t file) {
844 MimeConfig *mimecfg = load_mime_config(file->file.ptr); 786 MimeConfig *mimecfg = load_mime_config(file.ptr);
845 MimeMap *old_conf = file->data; 787 if(!mimecfg) {
846 788 return -1;
847 MimeMap *mimemap = malloc(sizeof(MimeMap)); 789 }
848 mimemap->ref = 1; 790
849 UcxMap *map = ucx_map_new((mimecfg->ntypes * 3) / 2); 791 int ret = 0;
850 mimemap->map = map; 792
851 793 // cleanup in case of errors is done by the allocator
852 // add ext type pairs 794 MimeMap *mimemap = almalloc(cfg->a, sizeof(MimeMap));
853 UCX_FOREACH(md, mimecfg->directives) { 795 UcxMap *map = ucx_map_new_a(cfg->a, (mimecfg->ntypes * 3) / 2);
854 MimeDirective *d = md->data; 796
855 // add the type for each extension to the map 797 if(mimemap && map) {
856 UCX_FOREACH(xl, d->exts) { 798 mimemap->map = map;
857 sstr_t ext = sstr(xl->data); 799
858 sstr_t value = sstrdup(d->type); 800 // add ext type pairs
859 ucx_map_sstr_put(map, ext, value.ptr); 801 UCX_FOREACH(md, mimecfg->directives) {
860 } 802 MimeDirective *d = md->data;
861 } 803 // add the type for each extension to the map
862 804 UCX_FOREACH(xl, d->exts) {
863 file->data = mimemap; 805 sstr_t ext = sstr(xl->data);
864 806 sstr_t value = sstrdup(d->type);
865 if(old_conf) { 807 if(ucx_map_sstr_put(map, ext, value.ptr)) {
866 mime_conf_unref(old_conf); 808 ret = -1;
809 break;
810 }
811 }
812 if(ret) {
813 break;
814 }
815 }
816
817 cfg->mimetypes = mimemap;
818 } else {
819 ret = -1;
867 } 820 }
868 821
869 free_mime_config(mimecfg); 822 free_mime_config(mimecfg);
870 return 0; 823 return ret;
871 } 824 }
872 825
873 void mime_conf_ref(MimeMap *conf) { 826
874 if(conf) { 827
875 ws_atomic_inc32(&conf->ref); 828 ACLData* acl_conf_load(ServerConfiguration *cfg, sstr_t file) {
876 } 829 ACLFile *aclfile = load_acl_file(file.ptr);
877 } 830
878 831 // TODO: malloc return checks
879 void mime_conf_unref(MimeMap *conf) { 832
880 uint32_t ref = ws_atomic_dec32(&conf->ref); 833 ACLData *acldata = acl_data_new(cfg->a);
881 if(ref == 0) {
882 printf("free MimeConfig %"PRIxPTR"\n", (intptr_t)conf);
883 UcxMapIterator i = ucx_map_iterator(conf->map);
884 char *str;
885 UCX_MAP_FOREACH(key, str, i) {
886 free(str);
887 }
888 ucx_map_free(conf->map);
889 free(conf);
890 }
891 }
892
893 int acl_conf_reload(ConfigFile *file, ServerConfiguration *cfg) {
894 ACLFile *aclfile = load_acl_file(file->file.ptr);
895
896 ACLData *acldata = acl_data_new();
897 UCX_FOREACH(elm, aclfile->namedACLs) { 834 UCX_FOREACH(elm, aclfile->namedACLs) {
898 ACLConfig *ac = elm->data; 835 ACLConfig *ac = elm->data;
899 ACLList *acl = acl_config_convert(cfg, ac); 836 ACLList *acl = acl_config_convert(cfg, ac);
900 log_ereport(LOG_VERBOSE, "add acl: %.*s", (int)ac->id.length, ac->id.ptr); 837 log_ereport(LOG_VERBOSE, "add acl: %.*s", (int)ac->id.length, ac->id.ptr);
901 ucx_map_sstr_put(acldata->namedACLs, ac->id, acl); 838 ucx_map_sstr_put(acldata->namedACLs, ac->id, acl);
902 } 839 }
903 free_acl_file(aclfile); 840 free_acl_file(aclfile);
904 841
905 ACLData *old_data = file->data; 842 return acldata;
906 file->data = acldata;
907 if(old_data) {
908 acl_data_unref(old_data);
909 }
910
911 return 0;
912 } 843 }
913 844
914 ACLList* acl_config_convert(ServerConfiguration *cfg, ACLConfig *acl) { 845 ACLList* acl_config_convert(ServerConfiguration *cfg, ACLConfig *acl) {
915 WSAcl *acllist = malloc(sizeof(WSAcl)); 846 UcxAllocator *a = cfg->a;
847
848 WSAcl *acllist = almalloc(cfg->a, sizeof(WSAcl));
916 acllist->acl.check = (acl_check_f)wsacl_check; 849 acllist->acl.check = (acl_check_f)wsacl_check;
917 acllist->acl.authdb = NULL; 850 acllist->acl.authdb = NULL;
918 acllist->acl.authprompt = NULL; 851 acllist->acl.authprompt = NULL;
919 acllist->acl.isextern = 0; 852 acllist->acl.isextern = 0;
920 acllist->ace = NULL; 853 acllist->ace = NULL;
923 if(acl->type.ptr && !sstrcmp(acl->type, sstr("fs"))) { 856 if(acl->type.ptr && !sstrcmp(acl->type, sstr("fs"))) {
924 acllist->acl.isextern = 1; 857 acllist->acl.isextern = 1;
925 } 858 }
926 859
927 size_t s = ucx_list_size(acl->entries); 860 size_t s = ucx_list_size(acl->entries);
928 WSAce **aces = calloc(s, sizeof(WSAce*)); 861 WSAce **tmp_aces = calloc(s, sizeof(WSAce*));
929 WSAce **eces = calloc(s, sizeof(WSAce*)); 862 WSAce **tmp_eces = calloc(s, sizeof(WSAce*));
930 int ai = 0; 863 int ai = 0;
931 int ei = 0; 864 int ei = 0;
932 865
933 // convert entries 866 // convert entries
934 UCX_FOREACH(elm, acl->entries) { 867 UCX_FOREACH(elm, acl->entries) {
935 ACEConfig *acecfg = elm->data; 868 ACEConfig *acecfg = elm->data;
936 869
937 // copy data 870 // copy data
938 WSAce *ace = malloc(sizeof(WSAce)); 871 WSAce *ace = almalloc(a, sizeof(WSAce));
939 ace->access_mask = acecfg->access_mask; 872 ace->access_mask = acecfg->access_mask;
940 ace->flags = acecfg->flags; 873 ace->flags = acecfg->flags;
941 ace->type = acecfg->type; 874 ace->type = acecfg->type;
942 ace->who = sstrdup(acecfg->who).ptr; 875 ace->who = sstrdup_a(a, acecfg->who).ptr;
943 876
944 // add the entry to the correct array 877 // add the entry to the correct array
945 if(ace->type >= ACL_TYPE_AUDIT) { 878 if(ace->type >= ACL_TYPE_AUDIT) {
946 eces[ei] = ace; 879 tmp_eces[ei] = ace;
947 ei++; 880 ei++;
948 } else { 881 } else {
949 aces[ai] = ace; 882 tmp_aces[ai] = ace;
950 ai++; 883 ai++;
951 } 884 }
952 } 885 }
953 886
954 // create new entrie arrays with perfect fitting size 887 // create new entrie arrays with perfect fitting size
955 if(ai > 0) { 888 if(ai > 0) {
956 acllist->ace = calloc(ai, sizeof(WSAce*)); 889 acllist->ace = alcalloc(a, ai, sizeof(WSAce*));
957 } 890 }
958 if(ei > 0) { 891 if(ei > 0) {
959 acllist->ece = calloc(ei, sizeof(WSAce*)); 892 acllist->ece = alcalloc(a, ei, sizeof(WSAce*));
960 } 893 }
961 memcpy(acllist->ace, aces, ai*sizeof(WSAce*)); 894 memcpy(acllist->ace, tmp_aces, ai*sizeof(WSAce*));
962 memcpy(acllist->ece, eces, ei*sizeof(WSAce*)); 895 memcpy(acllist->ece, tmp_eces, ei*sizeof(WSAce*));
963 acllist->acenum = ai; 896 acllist->acenum = ai;
964 acllist->ecenum = ei; 897 acllist->ecenum = ei;
965 898
966 free(aces); 899 free(tmp_aces);
967 free(eces); 900 free(tmp_eces);
968 901
969 // get authentication information 902 // get authentication information
970 if(acl->authparam) { 903 if(acl->authparam) {
971 sstr_t authdb_str = cfg_param_get(acl->authparam, sstr("authdb")); 904 sstr_t authdb_str = cfg_param_get(acl->authparam, sstr("authdb"));
972 sstr_t prompt_str = cfg_param_get(acl->authparam, sstr("prompt")); 905 sstr_t prompt_str = cfg_param_get(acl->authparam, sstr("prompt"));
973 906
974 if(authdb_str.ptr) { 907 if(authdb_str.ptr) {
975 AuthDB *authdb = ucx_map_sstr_get(cfg->authdbs, authdb_str); 908 AuthDB *authdb = ucx_map_sstr_get(cfg->authdbs, authdb_str);
976 acllist->acl.authdb = authdb; 909 acllist->acl.authdb = authdb;
977 if(authdb && prompt_str.ptr) { 910 if(authdb && prompt_str.ptr) {
978 acllist->acl.authprompt = sstrdup(prompt_str).ptr; 911 acllist->acl.authprompt = sstrdup_a(a, prompt_str).ptr;
979 } 912 }
980 } 913 }
981 } 914 }
982 915
983 return &acllist->acl; 916 return &acllist->acl;
984 } 917 }
985 918
986 int keyfile_reload(ConfigFile *file, ServerConfiguration *cfg) { 919 AuthDB* keyfile_load(ServerConfiguration *cfg, sstr_t file) {
987 KeyfileConfig *conf = load_keyfile_config(file->file.ptr); 920 Keyfile *keyfile = keyfile_new(cfg->a);
921 if(!keyfile) {
922 return NULL;
923 }
924
925 KeyfileConfig *conf = load_keyfile_config(file.ptr);
988 if(!conf) { 926 if(!conf) {
989 return 1; 927 return NULL;
990 } 928 }
991 929
992 Keyfile *keyfile = keyfile_new(); 930 AuthDB *ret = &keyfile->authdb;
993 931
994 UCX_FOREACH(elm, conf->users) { 932 UCX_FOREACH(elm, conf->users) {
995 KeyfileEntry *user = elm->data; 933 KeyfileEntry *user = elm->data;
996 keyfile_add_user( 934 if(keyfile_add_user(
997 keyfile, 935 keyfile,
998 user->name, 936 user->name,
999 user->hashtype, 937 user->hashtype,
1000 user->hashdata, 938 user->hashdata,
1001 user->groups, 939 user->groups,
1002 user->numgroups); 940 user->numgroups))
941 {
942 ret = NULL;
943 break;
944 }
1003 } 945 }
1004 946
1005 free_keyfile_config(conf); 947 free_keyfile_config(conf);
1006 948
1007 Keyfile *old_data = file->data; 949 return ret;
1008 file->data = keyfile; 950 }
1009 if(old_data) {
1010 keyfile_unref(old_data);
1011 }
1012
1013 return 0;
1014 }
1015
1016
1017 sstr_t cfg_load_file(sstr_t file) {
1018 sstr_t r;
1019 r.ptr = NULL;
1020 r.length = 0;
1021
1022 if(!file.ptr) {
1023 return r;
1024 }
1025
1026 sstr_t f = sstrdup(file);
1027 FILE *in = fopen(f.ptr, "r");
1028 if(!in) {
1029 return r;
1030 }
1031
1032 UcxBuffer *buf = ucx_buffer_new(NULL, 4096, UCX_BUFFER_AUTOEXTEND);
1033 if(!buf) {
1034 fclose(in);
1035 return r;
1036 }
1037
1038 if(ucx_stream_copy(in, buf, (read_func)fread, (write_func)ucx_buffer_write) == 0) {
1039 fclose(in);
1040 ucx_buffer_free(buf);
1041 return r;
1042 }
1043
1044 r.ptr = buf->space;
1045 r.length = buf->pos;
1046
1047 free(buf);
1048 fclose(in);
1049
1050 return r;
1051 }

mercurial