src/server/daemon/config.c

changeset 415
d938228c382e
parent 409
62aad4d94d5d
child 418
b7dcc9c4f270
equal deleted inserted replaced
414:99a34860c105 415:d938228c382e
35 #include <sys/types.h> 35 #include <sys/types.h>
36 #include <sys/file.h> 36 #include <sys/file.h>
37 #include <sys/stat.h> 37 #include <sys/stat.h>
38 #include <sys/mman.h> 38 #include <sys/mman.h>
39 39
40 #include <ucx/string.h> 40 #include <cx/string.h>
41 #include <ucx/utils.h> 41 #include <cx/utils.h>
42 #include <cx/hash_map.h>
43 #include <cx/linked_list.h>
44 #include <cx/compare.h>
42 45
43 #include "httplistener.h" 46 #include "httplistener.h"
44 #include "config.h" 47 #include "config.h"
45 #include "func.h" 48 #include "func.h"
46 #include "log.h" 49 #include "log.h"
52 55
53 #include "vserver.h" 56 #include "vserver.h"
54 #include "../util/pblock.h" 57 #include "../util/pblock.h"
55 #include "../util/util.h" 58 #include "../util/util.h"
56 #include "../util/atomic.h" 59 #include "../util/atomic.h"
57 #include "ucx/buffer.h" 60 #include "cx/buffer.h"
58 61
59 pool_handle_t *init_pool; 62 pool_handle_t *init_pool;
60 63
61 char* cfg_config_file_path(const char *file) { 64 char* cfg_config_file_path(const char *file) {
62 sstr_t base = ST("config/"); 65 cxstring base = CX_STR("config/");
63 sstr_t path = sstrcat(2, base, scstr(file)); 66 cxmutstr path = cx_strcat(2, base, cx_str(file));
64 return path.ptr; 67 return path.ptr;
65 } 68 }
66 69
67 int load_init_conf(char *file) { 70 int load_init_conf(char *file) {
68 log_ereport(LOG_VERBOSE, "load_init_conf"); 71 log_ereport(LOG_VERBOSE, "load_init_conf");
70 InitConfig *cfg = load_init_config(file); 73 InitConfig *cfg = load_init_config(file);
71 if(cfg == NULL) { 74 if(cfg == NULL) {
72 log_ereport(LOG_FAILURE, "Cannot load init.conf"); 75 log_ereport(LOG_FAILURE, "Cannot load init.conf");
73 return 1; 76 return 1;
74 } 77 }
75 UcxAllocator *mp = cfg->parser.mp; 78 CxAllocator *mp = cfg->parser.mp;
76 79
77 init_pool = pool_create(); // one pool for one Configuration 80 init_pool = pool_create(); // one pool for one Configuration
78 UcxList *dirs = cfg->directives; 81 ConfigDirectiveList *dirs = cfg->directives;
79 while(dirs != NULL) { 82 while(dirs != NULL) {
80 ConfigDirective *dir = dirs->data; 83 ConfigDirective *dir = dirs->directive;
81 84
82 /* create NSAPI directive */ 85 /* create NSAPI directive */
83 directive *d = malloc(sizeof(directive)); 86 directive *d = malloc(sizeof(directive));
84 d->param = pblock_create_pool(init_pool, 8); 87 d->param = pblock_create_pool(init_pool, 8);
85 UcxList *param = cfg_param_list(dir->value, mp); 88 ConfigParam *param = cfg_param_list(dir->value, mp);
86 while(param != NULL) { 89 while(param != NULL) {
87 ConfigParam *p = param->data;
88 pblock_nvlinsert( 90 pblock_nvlinsert(
89 p->name.ptr, 91 param->name.ptr,
90 p->name.length, 92 param->name.length,
91 p->value.ptr, 93 param->value.ptr,
92 p->value.length, 94 param->value.length,
93 d->param); 95 d->param);
94 96
95 param = param->next; 97 param = param->next;
96 } 98 }
97 99
146 148
147 ServerConfiguration *serverconfig = pool_calloc(pool, 1, sizeof(ServerConfiguration)); 149 ServerConfiguration *serverconfig = pool_calloc(pool, 1, sizeof(ServerConfiguration));
148 serverconfig->ref = 1; 150 serverconfig->ref = 1;
149 serverconfig->pool = pool; 151 serverconfig->pool = pool;
150 152
151 UcxAllocator allocator = util_pool_allocator(serverconfig->pool); 153 CxAllocator *allocator = pool_allocator(serverconfig->pool);
152 serverconfig->a = pool_malloc(pool, sizeof(UcxAllocator)); 154 serverconfig->a = allocator;
153 *serverconfig->a = allocator; 155
154 156 serverconfig->listeners = cxPointerLinkedListCreate(serverconfig->a, cx_cmp_ptr);
155 serverconfig->listeners = NULL; 157 serverconfig->logfiles = cxPointerLinkedListCreate(serverconfig->a, cx_cmp_ptr);
156 serverconfig->host_vs = ucx_map_new_a(serverconfig->a, 16); 158 serverconfig->host_vs = cxHashMapCreate(serverconfig->a, 16);
157 serverconfig->authdbs = ucx_map_new_a(serverconfig->a, 16); 159 serverconfig->authdbs = cxHashMapCreate(serverconfig->a, 16);
158 serverconfig->resources = ucx_map_new_a(serverconfig->a, 16); 160 serverconfig->resources = cxHashMapCreate(serverconfig->a, 16);
159 serverconfig->dav = ucx_map_new_a(serverconfig->a, 16); 161 serverconfig->dav = cxHashMapCreate(serverconfig->a, 16);
160 162
161 // STAGE 1 load_server_conf: 163 // STAGE 1 load_server_conf:
162 // At stage 1 we load the file and get the Runtime infos for changing 164 // At stage 1 we load the file and get the Runtime infos for changing
163 // the uid, which must be done before most steps. 165 // the uid, which must be done before most steps.
164 // Before the uid can be changed, we also need to bind listeners, 166 // Before the uid can be changed, we also need to bind listeners,
166 // 168 //
167 // Runtime 169 // Runtime
168 // Listener (dependencies: Threadpool, EventHandler) 170 // Listener (dependencies: Threadpool, EventHandler)
169 171
170 // load Runtime config 172 // load Runtime config
171 UcxList *list = serverconfig_get_node_list(serverconf->root, CONFIG_NODE_OBJECT, SC("Runtime")); 173 CxList *list = serverconfig_get_node_list(serverconf->root, CONFIG_NODE_OBJECT, cx_str("Runtime"));
172 UCX_FOREACH(elm, list) { 174 CxIterator iter = cxListIterator(list, 0);
173 ConfigNode *runtimeobj = elm->data; 175 cx_foreach(ConfigNode *, runtimeobj, iter) {
174 if(cfg_handle_runtime(serverconfig, runtimeobj)) { 176 if(cfg_handle_runtime(serverconfig, runtimeobj)) {
175 // error 177 // error
176 return NULL; 178 return NULL;
177 } 179 }
178 } 180 }
179 ucx_list_free(list); 181 cxListDestroy(list);
180 182
181 // load threadpool config 183 // load threadpool config
182 log_ereport(LOG_DEBUG, "apply config: Threadpool"); 184 log_ereport(LOG_DEBUG, "apply config: Threadpool");
183 list = serverconfig_get_node_list(serverconf->root, CONFIG_NODE_OBJECT, SC("Threadpool")); 185 list = serverconfig_get_node_list(serverconf->root, CONFIG_NODE_OBJECT, cx_str("Threadpool"));
184 UCX_FOREACH(elm, list) { 186 iter = cxListIterator(list, 0);
185 if(cfg_handle_threadpool(serverconfig, elm->data)) { 187 cx_foreach(ConfigNode *, elm, iter) {
188 if(cfg_handle_threadpool(serverconfig, elm)) {
186 return NULL; 189 return NULL;
187 } 190 }
188 } 191 }
189 ucx_list_free(list); 192 cxListDestroy(list);
190 // check thread pool config 193 // check thread pool config
191 if(check_thread_pool_cfg() != 0) { 194 if(check_thread_pool_cfg() != 0) {
192 /* critical error */ 195 /* critical error */
193 return NULL; 196 return NULL;
194 } 197 }
195 198
196 // load eventhandler config 199 // load eventhandler config
197 log_ereport(LOG_DEBUG, "apply config: EventHandler"); 200 log_ereport(LOG_DEBUG, "apply config: EventHandler");
198 list = serverconfig_get_node_list(serverconf->root, CONFIG_NODE_OBJECT, SC("EventHandler")); 201 list = serverconfig_get_node_list(serverconf->root, CONFIG_NODE_OBJECT, cx_str("EventHandler"));
199 UCX_FOREACH(elm, list) { 202 iter = cxListIterator(list, 0);
200 if(cfg_handle_eventhandler(serverconfig, elm->data)) { 203 cx_foreach(ConfigNode *, elm, iter) {
204 if(cfg_handle_eventhandler(serverconfig, elm)) {
201 // error 205 // error
202 return NULL; 206 return NULL;
203 } 207 }
204 } 208 }
205 // check event handler config 209 // check event handler config
206 if(check_event_handler_cfg() != 0) { 210 if(check_event_handler_cfg() != 0) {
207 /* critical error */ 211 /* critical error */
208 return NULL; 212 return NULL;
209 } 213 }
210 ucx_list_free(list); 214 cxListDestroy(list);
211 215
212 // load Listener config 216 // load Listener config
213 log_ereport(LOG_DEBUG, "apply config: Listener"); 217 log_ereport(LOG_DEBUG, "apply config: Listener");
214 list = serverconfig_get_node_list(serverconf->root, CONFIG_NODE_OBJECT, SC("Listener")); 218 list = serverconfig_get_node_list(serverconf->root, CONFIG_NODE_OBJECT, cx_str("Listener"));
215 UCX_FOREACH(elm, list) { 219 iter = cxListIterator(list, 0);
216 ConfigNode *scfgobj = elm->data; 220 cx_foreach(ConfigNode *, scfgobj, iter) {
217 if(cfg_handle_listener(serverconfig, scfgobj)) { 221 if(cfg_handle_listener(serverconfig, scfgobj)) {
218 return NULL; 222 return NULL;
219 } 223 }
220 } 224 }
221 ucx_list_free(list); 225 cxListDestroy(list);
222 226
223 // we return here, to let the webserver use the runtime info to 227 // we return here, to let the webserver use the runtime info to
224 // change the uid if needed 228 // change the uid if needed
225 return serverconfig; 229 return serverconfig;
226 } 230 }
240 * Listener (we set the VirtualServer later) 244 * Listener (we set the VirtualServer later)
241 * VirtualServer (dependencies: Listener) 245 * VirtualServer (dependencies: Listener)
242 */ 246 */
243 247
244 // init logfile first 248 // init logfile first
245 UcxList *list; 249 CxList *list;
246 250
247 log_ereport(LOG_DEBUG, "apply config: LogFile"); 251 log_ereport(LOG_DEBUG, "apply config: LogFile");
248 list = serverconfig_get_node_list(serverconf->root, CONFIG_NODE_OBJECT, SC("LogFile")); 252 list = serverconfig_get_node_list(serverconf->root, CONFIG_NODE_OBJECT, cx_str("LogFile"));
249 if(list) { 253 CxIterator iter = cxListIterator(list, 0);
250 ConfigNode *logobj = list->data; 254 cx_foreach(ConfigNode *, logobj, iter) {
251 if(!logobj) { 255 if(!logobj) {
252 // error 256 // error
253 return NULL; // TODO: fix memory leak 257 cxListDestroy(list);
258 return NULL;
254 } 259 }
255 260
256 int ret = cfg_handle_logfile(serverconfig, logobj); 261 int ret = cfg_handle_logfile(serverconfig, logobj);
257 if(ret != 0) { 262 if(ret != 0) {
258 // cannot initialize log file 263 // cannot initialize log file
259 return NULL; // TODO: fix memory leak 264 cxListDestroy(list);
260 } 265 return NULL;
261 } else { 266 }
262 // horrible error 267 }
263 return NULL; 268 cxListDestroy(list);
264 }
265 ucx_list_free(list);
266 269
267 log_ereport(LOG_DEBUG, "apply config: AccessLog"); 270 log_ereport(LOG_DEBUG, "apply config: AccessLog");
268 list = serverconfig_get_node_list(serverconf->root, CONFIG_NODE_OBJECT, SC("AccessLog")); 271 list = serverconfig_get_node_list(serverconf->root, CONFIG_NODE_OBJECT, cx_str("AccessLog"));
269 UCX_FOREACH(elm, list) { 272 iter = cxListIterator(list, 0);
270 ConfigNode *scfgobj = elm->data; 273 cx_foreach(ConfigNode *, scfgobj, iter) {
271 if(cfg_handle_accesslog(serverconfig, scfgobj)) { 274 if(cfg_handle_accesslog(serverconfig, scfgobj)) {
272 return NULL; 275 return NULL;
273 } 276 }
274 } 277 }
275 ucx_list_free(list); 278 cxListDestroy(list);
276 279
277 log_ereport(LOG_DEBUG, "apply config: AuthDB"); 280 log_ereport(LOG_DEBUG, "apply config: AuthDB");
278 list = serverconfig_get_node_list(serverconf->root, CONFIG_NODE_OBJECT, SC("AuthDB")); 281 list = serverconfig_get_node_list(serverconf->root, CONFIG_NODE_OBJECT, cx_str("AuthDB"));
279 UCX_FOREACH(elm, list) { 282 iter = cxListIterator(list, 0);
280 ConfigNode *scfgobj = elm->data; 283 cx_foreach(ConfigNode *, scfgobj, iter) {
281 if(cfg_handle_authdb(serverconfig, scfgobj)) { 284 if(cfg_handle_authdb(serverconfig, scfgobj)) {
282 return NULL; 285 return NULL;
283 } 286 }
284 } 287 }
285 ucx_list_free(list); 288 cxListDestroy(list);
286 289
287 log_ereport(LOG_DEBUG, "apply config: VirtualServer"); 290 log_ereport(LOG_DEBUG, "apply config: VirtualServer");
288 list = serverconfig_get_node_list(serverconf->root, CONFIG_NODE_OBJECT, SC("VirtualServer")); 291 list = serverconfig_get_node_list(serverconf->root, CONFIG_NODE_OBJECT, cx_str("VirtualServer"));
289 UCX_FOREACH(elm, list) { 292 iter = cxListIterator(list, 0);
290 ConfigNode *scfgobj = elm->data; 293 cx_foreach(ConfigNode *, scfgobj, iter) {
291 if(cfg_handle_vs(serverconfig, scfgobj)) { 294 if(cfg_handle_vs(serverconfig, scfgobj)) {
292 return NULL; 295 return NULL;
293 } 296 }
294 } 297 }
295 ucx_list_free(list); 298 cxListDestroy(list);
296 299
297 log_ereport(LOG_DEBUG, "apply config: ResourcePool"); 300 log_ereport(LOG_DEBUG, "apply config: ResourcePool");
298 list = serverconfig_get_node_list(serverconf->root, CONFIG_NODE_OBJECT, SC("ResourcePool")); 301 list = serverconfig_get_node_list(serverconf->root, CONFIG_NODE_OBJECT, cx_str("ResourcePool"));
299 UCX_FOREACH(elm, list) { 302 iter = cxListIterator(list, 0);
300 ConfigNode *scfgobj = elm->data; 303 cx_foreach(ConfigNode *, scfgobj, iter) {
301 if(cfg_handle_resourcepool(serverconfig, scfgobj)) { 304 if(cfg_handle_resourcepool(serverconfig, scfgobj)) {
302 return NULL; 305 return NULL;
303 } 306 }
304 } 307 }
308 cxListDestroy(list);
305 309
306 log_ereport(LOG_DEBUG, "apply config: Dav"); 310 log_ereport(LOG_DEBUG, "apply config: Dav");
307 list = serverconfig_get_node_list(serverconf->root, CONFIG_NODE_OBJECT, SC("Dav")); 311 list = serverconfig_get_node_list(serverconf->root, CONFIG_NODE_OBJECT, cx_str("Dav"));
308 UCX_FOREACH(elm, list) { 312 iter = cxListIterator(list, 0);
309 ConfigNode *scfgobj = elm->data; 313 cx_foreach(ConfigNode *, scfgobj, iter) {
310 if(cfg_handle_dav(serverconfig, scfgobj)) { 314 if(cfg_handle_dav(serverconfig, scfgobj)) {
311 return NULL; 315 return NULL;
312 } 316 }
313 } 317 }
318 cxListDestroy(list);
314 319
315 // set VirtualServer for all listeners 320 // set VirtualServer for all listeners
316 UcxList *ls = serverconfig->listeners; 321 CxList *ls = serverconfig->listeners;
317 while(ls) { 322 iter = cxListIterator(ls, 0);
318 HttpListener *listener = ls->data; 323 cx_foreach(HttpListener *, listener, iter) {
319 324 cxstring vsname = cx_str(listener->default_vs.vs_name);
320 sstr_t vsname = sstr(listener->default_vs.vs_name);
321 325
322 // search for VirtualServer 326 // search for VirtualServer
323 //int b = 0; 327 //int b = 0;
324 UcxMapIterator iter = ucx_map_iterator(serverconfig->host_vs); 328 CxIterator map_iter = cxMapIteratorValues(serverconfig->host_vs);
325 VirtualServer *vs; 329 cx_foreach(VirtualServer *, vs, map_iter) {
326 UCX_MAP_FOREACH(key, vs, iter) { 330 if(!cx_strcmp(vsname, (cxstring){vs->name.ptr, vs->name.length})) {
327 if(!sstrcmp(vsname, vs->name)) {
328 listener->default_vs.vs = vs; 331 listener->default_vs.vs = vs;
329 break; 332 break;
330 } 333 }
331 } 334 }
332
333 ls = ls->next;
334 } 335 }
335 336
336 serverconfig_free(serverconf); 337 serverconfig_free(serverconf);
337 338
338 return serverconfig; 339 return serverconfig;
353 void init_server_config_parser() { 354 void init_server_config_parser() {
354 355
355 } 356 }
356 357
357 int cfg_handle_runtime(ServerConfiguration *cfg, ConfigNode *obj) { 358 int cfg_handle_runtime(ServerConfiguration *cfg, ConfigNode *obj) {
358 scstr_t user = serverconfig_directive_value(obj, SC("User")); 359 cxstring user = serverconfig_directive_value(obj, cx_str("User"));
359 if(user.ptr) { 360 if(user.ptr) {
360 cfg->user = sstrdup_a(cfg->a, user); 361 cfg->user = cx_strdup_a(cfg->a, user);
361 } 362 }
362 scstr_t tmp = serverconfig_directive_value(obj, SC("Temp")); 363 cxstring tmp = serverconfig_directive_value(obj, cx_str("Temp"));
363 if(tmp.ptr) { 364 if(tmp.ptr) {
364 cfg->tmp = sstrdup_a(cfg->a, tmp); 365 cfg->tmp = cx_strdup_a(cfg->a, tmp);
365 } else { 366 } else {
366 // TODO: do this check after all config loading is done 367 // TODO: do this check after all config loading is done
367 log_ereport(LOG_MISCONFIG, "no temporary directory specified"); 368 log_ereport(LOG_MISCONFIG, "no temporary directory specified");
368 return -1; 369 return -1;
369 } 370 }
370 371
371 // mime file 372 // mime file
372 scstr_t mf = serverconfig_directive_value(obj, SC("MimeFile")); 373 cxstring mf = serverconfig_directive_value(obj, cx_str("MimeFile"));
373 scstr_t base = SC("config/"); 374 cxstring base = cx_str("config/");
374 sstr_t file = sstrcat(2, base, mf); 375 cxmutstr file = cx_strcat(2, base, mf);
375 376
376 if(mime_conf_load(cfg, file)) { 377 if(mime_conf_load(cfg, file)) {
377 return -1; 378 return -1;
378 } 379 }
379 380
380 free(file.ptr); 381 free(file.ptr);
381 return 0; 382 return 0;
382 } 383 }
383 384
384 int cfg_handle_logfile(ServerConfiguration *cfg, ConfigNode *obj) { 385 int cfg_handle_logfile(ServerConfiguration *cfg, ConfigNode *obj) {
385 scstr_t file = serverconfig_directive_value(obj, SC("File")); 386 cxstring file = serverconfig_directive_value(obj, cx_str("File"));
386 scstr_t lvl = serverconfig_directive_value(obj, SC("Level")); 387 cxstring lvl = serverconfig_directive_value(obj, cx_str("Level"));
387 388
388 int err = 0; 389 int err = 0;
389 if(file.ptr == NULL) { 390 if(file.ptr == NULL) {
390 err = 1; 391 err = 1;
391 log_ereport(LOG_MISCONFIG, "LogFile: parameter missing: File"); 392 log_ereport(LOG_MISCONFIG, "LogFile: parameter missing: File");
416 poolcfg.min_threads = 4; 417 poolcfg.min_threads = 4;
417 poolcfg.max_threads = 8; 418 poolcfg.max_threads = 8;
418 poolcfg.queue_size = 64; 419 poolcfg.queue_size = 64;
419 poolcfg.stack_size = 262144; 420 poolcfg.stack_size = 262144;
420 421
421 scstr_t name = serverconfig_directive_value(obj, SC("Name")); 422 cxstring name = serverconfig_directive_value(obj, cx_str("Name"));
422 scstr_t min = serverconfig_directive_value(obj, SC("MinThreads")); 423 cxstring min = serverconfig_directive_value(obj, cx_str("MinThreads"));
423 scstr_t max = serverconfig_directive_value(obj, SC("MaxThreads")); 424 cxstring max = serverconfig_directive_value(obj, cx_str("MaxThreads"));
424 scstr_t stack = serverconfig_directive_value(obj, SC("StackSize")); 425 cxstring stack = serverconfig_directive_value(obj, cx_str("StackSize"));
425 scstr_t queue = serverconfig_directive_value(obj, SC("QueueSize")); 426 cxstring queue = serverconfig_directive_value(obj, cx_str("QueueSize"));
426 // TODO: Type 427 // TODO: Type
427 428
428 if(name.length == 0) { 429 if(name.length == 0) {
429 // TODO: log error 430 // TODO: log error
430 return 1; 431 return 1;
475 476
476 #define EV_MAX_THREADS 2048 477 #define EV_MAX_THREADS 2048
477 int cfg_handle_eventhandler(ServerConfiguration *c, ConfigNode *obj) { 478 int cfg_handle_eventhandler(ServerConfiguration *c, ConfigNode *obj) {
478 EventHandlerConfig evcfg; 479 EventHandlerConfig evcfg;
479 480
480 scstr_t name = serverconfig_directive_value(obj, SC("Name")); 481 cxstring name = serverconfig_directive_value(obj, cx_str("Name"));
481 scstr_t threads = serverconfig_directive_value(obj, SC("Threads")); 482 cxstring threads = serverconfig_directive_value(obj, cx_str("Threads"));
482 scstr_t isdefault = serverconfig_directive_value(obj, SC("Default")); 483 cxstring isdefault = serverconfig_directive_value(obj, cx_str("Default"));
483 484
484 evcfg.name = name; 485 evcfg.name = name;
485 486
486 int64_t value; 487 int64_t value;
487 if(!util_strtoint(threads.ptr, &value)) { 488 if(!util_strtoint(threads.ptr, &value)) {
499 500
500 return create_event_handler(&evcfg); 501 return create_event_handler(&evcfg);
501 } 502 }
502 503
503 int cfg_handle_resourcepool(ServerConfiguration *cfg, ConfigNode *obj) { 504 int cfg_handle_resourcepool(ServerConfiguration *cfg, ConfigNode *obj) {
504 scstr_t name = serverconfig_directive_value(obj, SC("Name")); 505 cxstring name = serverconfig_directive_value(obj, cx_str("Name"));
505 scstr_t type = serverconfig_directive_value(obj, SC("Type")); 506 cxstring type = serverconfig_directive_value(obj, cx_str("Type"));
506 507
507 int ret = 0; 508 int ret = 0;
508 if(resourcepool_new(cfg, type, name, obj)) { 509 if(resourcepool_new(cfg, type, name, obj)) {
509 ret = 1; 510 ret = 1;
510 } 511 }
513 } 514 }
514 515
515 int cfg_handle_accesslog(ServerConfiguration *cfg, ConfigNode *obj) { 516 int cfg_handle_accesslog(ServerConfiguration *cfg, ConfigNode *obj) {
516 // TODO: use a name to identify the log file 517 // TODO: use a name to identify the log file
517 518
518 scstr_t file = serverconfig_directive_value(obj, SC("File")); 519 cxstring file = serverconfig_directive_value(obj, cx_str("File"));
519 if(file.ptr == NULL) { 520 if(file.ptr == NULL) {
520 return 0; 521 return 0;
521 } 522 }
522 sstr_t format; 523 cxmutstr format;
523 format.ptr = NULL; 524 format.ptr = NULL;
524 format.length = 0; 525 format.length = 0;
525 526
526 //AccessLog *log = get_access_log(file, format); 527 //AccessLog *log = get_access_log(file, format);
527 LogFile *log_file = get_access_log_file(file); 528 LogFile *log_file = get_access_log_file(file);
528 if(!log_file) { 529 if(!log_file) {
529 // TODO: error/warning 530 // TODO: error/warning
530 return 0; 531 return 0;
531 } 532 }
532 AccessLog *log = pool_malloc(cfg->pool, sizeof(AccessLog)); 533 AccessLog *log = pool_malloc(cfg->pool, sizeof(AccessLog));
533 log->file = sstrdup_a(cfg->a, file); 534 log->file = cx_strdup_a(cfg->a, file);
534 log->format = format; 535 log->format = format;
535 log->log = log_file; 536 log->log = log_file;
536 cfg->logfiles = ucx_list_append_a(cfg->a, cfg->logfiles, log); 537 cxListAdd(cfg->logfiles, log);
537 538
538 if(!cfg->default_log) { 539 if(!cfg->default_log) {
539 cfg->default_log = log; 540 cfg->default_log = log;
540 } 541 }
541 542
542 return 0; 543 return 0;
543 } 544 }
544 545
545 int cfg_handle_authdb(ServerConfiguration *cfg, ConfigNode *obj) { 546 int cfg_handle_authdb(ServerConfiguration *cfg, ConfigNode *obj) {
546 scstr_t name = serverconfig_directive_value(obj, SC("Name")); 547 cxstring name = serverconfig_directive_value(obj, cx_str("Name"));
547 scstr_t type = serverconfig_directive_value(obj, SC("Type")); 548 cxstring type = serverconfig_directive_value(obj, cx_str("Type"));
548 549
549 AuthDB *authdb = NULL; 550 AuthDB *authdb = NULL;
550 551
551 if(!sstrcmp(type, sstr("ldap"))) { 552 if(!cx_strcmp(type, cx_str("ldap"))) {
552 LDAPConfig conf; 553 LDAPConfig conf;
553 554
554 scstr_t host = serverconfig_directive_value(obj, SC("Host")); 555 cxstring host = serverconfig_directive_value(obj, cx_str("Host"));
555 scstr_t port = serverconfig_directive_value( obj, SC("Port")); 556 cxstring port = serverconfig_directive_value( obj, cx_str("Port"));
556 scstr_t basedn = serverconfig_directive_value(obj, SC("BaseDN")); 557 cxstring basedn = serverconfig_directive_value(obj, cx_str("BaseDN"));
557 scstr_t binddn = serverconfig_directive_value(obj, SC("BindDN")); 558 cxstring binddn = serverconfig_directive_value(obj, cx_str("BindDN"));
558 scstr_t basepw = serverconfig_directive_value(obj, SC("BindPW")); 559 cxstring basepw = serverconfig_directive_value(obj, cx_str("BindPW"));
559 560
560 conf.hostname = sstrdup_a(cfg->a, host).ptr; 561 conf.hostname = cx_strdup_a(cfg->a, host).ptr;
561 conf.port = atoi(port.ptr); 562 conf.port = atoi(port.ptr);
562 conf.basedn = sstrdup_a(cfg->a, basedn).ptr; 563 conf.basedn = cx_strdup_a(cfg->a, basedn).ptr;
563 conf.binddn = sstrdup_a(cfg->a, binddn).ptr; 564 conf.binddn = cx_strdup_a(cfg->a, binddn).ptr;
564 conf.bindpw = sstrdup_a(cfg->a, basepw).ptr; 565 conf.bindpw = cx_strdup_a(cfg->a, basepw).ptr;
565 566
566 authdb = create_ldap_authdb(cfg, name.ptr, &conf); 567 authdb = create_ldap_authdb(cfg, name.ptr, &conf);
567 } else if(!sstrcmp(type, sstr("keyfile"))) { 568 } else if(!cx_strcmp(type, cx_str("keyfile"))) {
568 // we only need the file parameter 569 // we only need the file parameter
569 scstr_t file = serverconfig_directive_value(obj, SC("File")); 570 cxstring file = serverconfig_directive_value(obj, cx_str("File"));
570 if(file.length == 0) { 571 if(file.length == 0) {
571 log_ereport( 572 log_ereport(
572 LOG_MISCONFIG, 573 LOG_MISCONFIG,
573 "missing File parameter for keyfile authdb"); 574 "missing File parameter for keyfile authdb");
574 return 1; 575 return 1;
577 // load keyfile 578 // load keyfile
578 authdb = keyfile_load(cfg, file); 579 authdb = keyfile_load(cfg, file);
579 } 580 }
580 581
581 if(authdb) { 582 if(authdb) {
582 if(ucx_map_sstr_put(cfg->authdbs, name, authdb)) { 583 if(cxMapPut(cfg->authdbs, cx_hash_key_bytes((const unsigned char*)name.ptr, name.length), authdb)) {
583 return -1; 584 return -1;
584 } 585 }
585 } 586 }
586 587
587 return 0; 588 return 0;
592 ZERO(&lc, sizeof(ListenerConfig)); 593 ZERO(&lc, sizeof(ListenerConfig));
593 lc.cfg = cfg; 594 lc.cfg = cfg;
594 lc.port = 8080; 595 lc.port = 8080;
595 lc.nacceptors = 1; 596 lc.nacceptors = 1;
596 597
597 scstr_t name = serverconfig_directive_value(obj, SC("Name")); 598 cxstring name = serverconfig_directive_value(obj, cx_str("Name"));
598 scstr_t port = serverconfig_directive_value(obj, SC("Port")); 599 cxstring port = serverconfig_directive_value(obj, cx_str("Port"));
599 scstr_t vs = serverconfig_directive_value(obj, SC("DefaultVS")); 600 cxstring vs = serverconfig_directive_value(obj, cx_str("DefaultVS"));
600 scstr_t thrp = serverconfig_directive_value(obj, SC("Threadpool")); 601 cxstring thrp = serverconfig_directive_value(obj, cx_str("Threadpool"));
601 scstr_t blck = serverconfig_directive_value(obj, SC("BlockingIO")); 602 cxstring blck = serverconfig_directive_value(obj, cx_str("BlockingIO"));
602 603
603 // TODO: use sstrdup_pool? 604 // TODO: use cx_strdup_pool?
604 int64_t port_value; 605 int64_t port_value;
605 if(!util_strtoint(port.ptr, &port_value)) { 606 if(!util_strtoint(port.ptr, &port_value)) {
606 log_ereport(LOG_MISCONFIG, "Listener: Invalid argument for parameter 'Port': '%s'", port.ptr); 607 log_ereport(LOG_MISCONFIG, "Listener: Invalid argument for parameter 'Port': '%s'", port.ptr);
607 return 1; 608 return 1;
608 } 609 }
609 if(port_value < 1 || port_value > 65535) { 610 if(port_value < 1 || port_value > 65535) {
610 log_ereport(LOG_MISCONFIG, "Listener: Port number out of range (1 .. 65535)"); 611 log_ereport(LOG_MISCONFIG, "Listener: Port number out of range (1 .. 65535)");
611 return 1; 612 return 1;
612 } 613 }
613 614
614 lc.name = sstrdup(name); 615 lc.name = cx_strdup(name);
615 lc.port = port_value; 616 lc.port = port_value;
616 lc.vs = sstrdup(vs); 617 lc.vs = cx_strdup(vs);
617 lc.threadpool = sstrdup(thrp); 618 lc.threadpool = cx_strdup(thrp);
618 619
619 lc.blockingio = util_getboolean_s(blck, WS_FALSE); 620 lc.blockingio = util_getboolean_s(blck, WS_FALSE);
620 621
621 scstr_t ssl = serverconfig_directive_value(obj, SC("SSL")); 622 cxstring ssl = serverconfig_directive_value(obj, cx_str("SSL"));
622 if(util_getboolean_s(ssl, WS_FALSE)) { 623 if(util_getboolean_s(ssl, WS_FALSE)) {
623 scstr_t cert = serverconfig_directive_value(obj, SC("Cert")); 624 cxstring cert = serverconfig_directive_value(obj, cx_str("Cert"));
624 scstr_t privkey = serverconfig_directive_value(obj, SC("Key")); 625 cxstring privkey = serverconfig_directive_value(obj, cx_str("Key"));
625 scstr_t chain = serverconfig_directive_value(obj, SC("CertChain")); 626 cxstring chain = serverconfig_directive_value(obj, cx_str("CertChain"));
626 scstr_t disableprot = serverconfig_directive_value(obj, SC("SSLDisableProtocol")); 627 cxstring disableprot = serverconfig_directive_value(obj, cx_str("SSLDisableProtocol"));
627 628
628 WSBool config_ok = WS_TRUE; 629 WSBool config_ok = WS_TRUE;
629 // TODO: log error 630 // TODO: log error
630 if(!cert.ptr && !chain.ptr) { 631 if(!cert.ptr && !chain.ptr) {
631 log_ereport( 632 log_ereport(
658 HttpListener *listener = http_listener_create(&lc); 659 HttpListener *listener = http_listener_create(&lc);
659 if(!listener) { 660 if(!listener) {
660 return 1; 661 return 1;
661 } 662 }
662 663
663 listener->default_vs.vs_name = sstrdup_a(cfg->a, lc.vs).ptr; 664 listener->default_vs.vs_name = cx_strdup_a(cfg->a, (cxstring){lc.vs.ptr, lc.vs.length}).ptr;
664 cfg->listeners = ucx_list_append_a(cfg->a, cfg->listeners, listener); 665 cxListAdd(cfg->listeners, listener);
665 666
666 return 0; 667 return 0;
667 } 668 }
668 669
669 int cfg_handle_vs(ServerConfiguration *cfg, ConfigNode *obj) { 670 int cfg_handle_vs(ServerConfiguration *cfg, ConfigNode *obj) {
670 VirtualServer *vs = vs_new(); 671 VirtualServer *vs = vs_new();
671 672
672 vs->name = sstrdup_a(cfg->a, serverconfig_directive_value(obj, SC("Name"))); 673 vs->name = cx_strdup_a(cfg->a, serverconfig_directive_value(obj, cx_str("Name")));
673 vs->host = sstrdup_a(cfg->a, serverconfig_directive_value(obj, SC("Host"))); 674 vs->host = cx_strdup_a(cfg->a, serverconfig_directive_value(obj, cx_str("Host")));
674 vs->document_root = sstrdup_a(cfg->a, serverconfig_directive_value(obj, SC("DocRoot"))); 675 vs->document_root = cx_strdup_a(cfg->a, serverconfig_directive_value(obj, cx_str("DocRoot")));
675 676
676 scstr_t objfile = serverconfig_directive_value(obj, SC("ObjectFile")); 677 cxstring objfile = serverconfig_directive_value(obj, cx_str("ObjectFile"));
677 scstr_t aclfile = serverconfig_directive_value(obj, SC("ACLFile")); 678 cxstring aclfile = serverconfig_directive_value(obj, cx_str("ACLFile"));
678 679
679 // load the object config file 680 // load the object config file
680 sstr_t base = sstr("config/"); 681 cxstring base = cx_str("config/");
681 sstr_t file = sstrcat(2, base, objfile); 682 // cx_strcat with allocator because we want to keep the string
682 // sstrcat with allocator because we want to keep the string 683 cxmutstr file = cx_strcat_a(cfg->a, 2, base, objfile);
683 file = sstrcat_a(cfg->a, 2, base, objfile);
684 684
685 HTTPObjectConfig *httpobj = objconf_load(cfg, file); 685 HTTPObjectConfig *httpobj = objconf_load(cfg, file);
686 if(!httpobj) { 686 if(!httpobj) {
687 return -1; 687 return -1;
688 } 688 }
689 vs->objectfile = file; 689 vs->objectfile = file;
690 vs->objects = httpobj; 690 vs->objects = httpobj;
691 691
692 692
693 // load acl config file 693 // load acl config file
694 file = sstrcat(2, base, aclfile); 694 cxmutstr acl_filepath = cx_strcat(2, base, aclfile);
695 695
696 ACLData *acldata = acl_conf_load(cfg, file); 696 ACLData *acldata = acl_conf_load(cfg, acl_filepath.ptr);
697 free(acl_filepath.ptr);
697 if(!acldata) { 698 if(!acldata) {
698 return -1; 699 return -1;
699 } 700 }
700 vs->acls = acldata; 701 vs->acls = acldata;
701
702 free(file.ptr);
703 702
704 703
705 // set the access log for the virtual server 704 // set the access log for the virtual server
706 // TODO: don't always use the default 705 // TODO: don't always use the default
707 vs->log = cfg->default_log; 706 vs->log = cfg->default_log;
708 707
709 ucx_map_sstr_put(cfg->host_vs, vs->host, vs); 708 cxMapPut(cfg->host_vs, cx_hash_key_bytes((unsigned const char*)vs->host.ptr, vs->host.length), vs);
710 709
711 return 0; 710 return 0;
712 } 711 }
713 712
714 int cfg_handle_dav(ServerConfiguration *cfg, ConfigNode *obj) { 713 int cfg_handle_dav(ServerConfiguration *cfg, ConfigNode *obj) {
715 UcxList *backends = NULL; // list of ConfigArg* 714 CxAllocator *a = pool_allocator(cfg->pool);
716 UcxAllocator a = util_pool_allocator(cfg->pool); 715 CxList *backends = cxPointerLinkedListCreate(a, cx_cmp_ptr); // list of ConfigParam*
717 int init_error; 716 int init_error;
718 717
719 // parse args 718 // parse args
720 char *uri = NULL; 719 char *uri = NULL;
721 char *ppath = NULL; 720 char *ppath = NULL;
722 char *name = NULL; 721 char *name = NULL;
723 UCX_FOREACH(elm, obj->args) { 722 for(ConfigParam *arg=obj->args;arg;arg=arg->next) {
724 ConfigArg *arg = elm->data; 723 cxstring arg_name = (cxstring){ arg->name.ptr, arg->name.length };
725 if(arg->name.ptr == NULL) { 724 if(arg->name.ptr == NULL) {
726 // default: uri 725 // default: uri
727 uri = arg->value.ptr; 726 uri = arg->value.ptr;
728 } else if(!sstrcasecmp(arg->name, SC("uri"))) { 727 } else if(!cx_strcasecmp(arg_name, cx_str("uri"))) {
729 uri = arg->value.ptr; 728 uri = arg->value.ptr;
730 } else if(!sstrcasecmp(arg->name, SC("ppath"))) { 729 } else if(!cx_strcasecmp(arg_name, cx_str("ppath"))) {
731 ppath = arg->value.ptr; 730 ppath = arg->value.ptr;
732 } else if(!sstrcasecmp(arg->name, SC("name"))) { 731 } else if(!cx_strcasecmp(arg_name, cx_str("name"))) {
733 name = arg->value.ptr; 732 name = arg->value.ptr;
734 } 733 }
735 } 734 }
736 if(!uri && !ppath && !name) { 735 if(!uri && !ppath && !name) {
737 return 1; 736 return 1;
738 } 737 }
739 738
740 // get a list of all DavBackends 739 // get a list of all DavBackends
741 UCX_FOREACH(elm, obj->children) { 740 for(ConfigNode *node=obj->children_begin;node;node=node->next) {
742 ConfigNode *node = elm->data; 741 cxstring node_name = cx_strn(node->name.ptr, node->name.length);
743 if(!sstrcasecmp(node->name, SC("DavBackend"))) { 742 if(!cx_strcasecmp(node_name, cx_str("DavBackend"))) {
744 if(node->type == CONFIG_NODE_DIRECTIVE) { 743 if(node->type == CONFIG_NODE_DIRECTIVE) {
745 if(ucx_list_size(node->args) == 1) { 744 if(CFG_NUM_PARAMS(node->args) == 1) {
746 ConfigArg *arg = node->args->data; 745 cxListAdd(backends, node->args);
747 backends = ucx_list_append(backends, arg);
748 } else { 746 } else {
749 log_ereport(LOG_MISCONFIG, "DavBackend must have only one value"); 747 log_ereport(LOG_MISCONFIG, "DavBackend must have only one value");
750 ucx_list_free(backends); 748 cxListDestroy(backends);
751 return 1; 749 return 1;
752 } 750 }
753 } else { 751 } else {
754 log_ereport(LOG_MISCONFIG, "DavBackend must be a directive"); 752 log_ereport(LOG_MISCONFIG, "DavBackend must be a directive");
755 ucx_list_free(backends); 753 cxListDestroy(backends);
756 return 1; 754 return 1;
757 } 755 }
758 } 756 }
759 } 757 }
760 758
761 int ret = 0; 759 int ret = 0;
762 WebdavRepository *repository = pool_malloc(cfg->pool, sizeof(WebdavRepository)); 760 WebdavRepository *repository = pool_malloc(cfg->pool, sizeof(WebdavRepository));
763 repository->vfs = NULL; 761 repository->vfs = NULL;
764 repository->vfsInitData = NULL; 762 repository->vfsInitData = NULL;
765 repository->davBackends = NULL; 763 repository->davBackends = cxPointerLinkedListCreate(a, cx_cmp_ptr); // value type: WebdavBackendInitData*
766 764
767 // initialize backends 765 // initialize backends
768 UCX_FOREACH(elm, backends) { 766 CxIterator i = cxListIterator(backends, 0);
767 cx_foreach(ConfigParam *, backendArg, i) {
769 // the DavBackend value should contain the dav class name 768 // the DavBackend value should contain the dav class name
770 ConfigArg *backendArg = elm->data; 769
771 770 WebdavType *dav = webdav_get_type((cxstring){backendArg->value.ptr, backendArg->value.length});
772 WebdavType *dav = webdav_get_type((scstr_t){backendArg->value.ptr, backendArg->value.length});
773 if(!dav) { 771 if(!dav) {
774 log_ereport(LOG_MISCONFIG, "Unknown webdav backend type '%s'", backendArg->value.ptr); 772 log_ereport(LOG_MISCONFIG, "Unknown webdav backend type '%s'", backendArg->value.ptr);
775 ret = 1; 773 ret = 1;
776 break; 774 break;
777 } 775 }
792 break; 790 break;
793 } 791 }
794 davInit->davType = dav; 792 davInit->davType = dav;
795 davInit->davInitData = init_data; 793 davInit->davInitData = init_data;
796 794
797 repository->davBackends = ucx_list_append_a(&a, repository->davBackends, davInit); 795 cxListAdd(repository->davBackends, davInit);
798 } 796 }
797 cxListDestroy(backends);
799 798
800 // initialize vfs 799 // initialize vfs
801 scstr_t vfs_class = serverconfig_directive_value(obj, SC("VFS")); 800 cxstring vfs_class = serverconfig_directive_value(obj, cx_str("VFS"));
802 if(vfs_class.length > 0) { 801 if(vfs_class.length > 0) {
803 VfsType *vfs = vfs_get_type((scstr_t){vfs_class.ptr, vfs_class.length}); 802 VfsType *vfs = vfs_get_type((cxstring){vfs_class.ptr, vfs_class.length});
804 if(vfs) { 803 if(vfs) {
805 repository->vfs = vfs; 804 repository->vfs = vfs;
806 repository->vfsInitData = vfs_init_backend(cfg, cfg->pool, vfs, obj, &init_error); 805 repository->vfsInitData = vfs_init_backend(cfg, cfg->pool, vfs, obj, &init_error);
807 if(!ret) { 806 if(!ret) {
808 ret = init_error; 807 ret = init_error;
811 log_ereport(LOG_FAILURE, "Unknown vfs type '%s'", vfs_class.ptr); 810 log_ereport(LOG_FAILURE, "Unknown vfs type '%s'", vfs_class.ptr);
812 ret = 1; 811 ret = 1;
813 } 812 }
814 } 813 }
815 814
816 scstr_t object = serverconfig_directive_value(obj, SC("Object")); 815 cxstring object = serverconfig_directive_value(obj, cx_str("Object"));
817 if(object.length > 0) { 816 if(object.length > 0) {
818 repository->object = sstrdup_a(&a, object); 817 repository->object = cx_strdup_a(a, object);
819 if(repository->object.length != object.length) { 818 if(repository->object.length != object.length) {
820 // OOM 819 // OOM
821 log_ereport(LOG_FAILURE, "Cannot create webdav repository: OOM"); 820 log_ereport(LOG_FAILURE, "Cannot create webdav repository: OOM");
822 ret = 1; 821 ret = 1;
823 } 822 }
824 } 823 }
825 824
826 if(!ret) { 825 if(!ret) {
827 if(name) { 826 if(name) {
828 ucx_map_cstr_put(cfg->dav, name, repository); 827 cxMapPut(cfg->dav, cx_hash_key_str(name), repository);
829 } else { 828 } else {
830 log_ereport(LOG_FAILURE, "TODO: location based dav repositories not implemented"); 829 log_ereport(LOG_FAILURE, "TODO: location based dav repositories not implemented");
831 ret = 1; 830 ret = 1;
832 } 831 }
833 } 832 }
834 833
835 return ret; 834 return ret;
836 } 835 }
837 836
838 static int convert_objconf(ServerConfiguration *scfg, ObjectConfig *cfg, HTTPObjectConfig *conf, sstr_t file) { 837 static int convert_objconf(ServerConfiguration *scfg, ObjectConfig *cfg, HTTPObjectConfig *conf, cxmutstr file) {
839 pool_handle_t *pool = conf->pool; 838 pool_handle_t *pool = conf->pool;
840 839
841 UcxList *objlist = cfg->objects; 840 CxList *objlist = cfg->objects;
841 CxIterator iter = cxListIterator(objlist, 0);
842 int i = 0; 842 int i = 0;
843 while(objlist != NULL) { 843 cx_foreach(ConfigObject*, cob, iter) {
844 ConfigObject *cob = objlist->data;
845
846 // get name and ppath 844 // get name and ppath
847 char *name = NULL; 845 char *name = NULL;
848 char *ppath = NULL; 846 char *ppath = NULL;
849 if(cob->name.length > 0) { 847 if(cob->name.length > 0) {
850 name = sstrdup_pool(pool, cob->name).ptr; 848 name = cx_strdup_pool(pool, cob->name).ptr;
851 if(!name) return -1; 849 if(!name) return -1;
852 } 850 }
853 if(cob->ppath.length > 0) { 851 if(cob->ppath.length > 0) {
854 ppath = sstrdup_pool(pool, cob->ppath).ptr; 852 ppath = cx_strdup_pool(pool, cob->ppath).ptr;
855 if(!ppath) return -1; 853 if(!ppath) return -1;
856 } 854 }
857 855
858 // create and add object 856 // create and add object
859 httpd_object *obj = object_new(pool, name); 857 httpd_object *obj = object_new(pool, name);
862 860
863 conf->objects[i] = obj; 861 conf->objects[i] = obj;
864 862
865 // add directives 863 // add directives
866 for(int j=0;j<NUM_NSAPI_TYPES-1;j++) { 864 for(int j=0;j<NUM_NSAPI_TYPES-1;j++) {
867 UcxList *dirs = cob->directives[j]; 865 ConfigDirectiveList *dirs = cob->directives[j];
868 while(dirs != NULL) { 866 while(dirs != NULL) {
869 ConfigDirective *cfgdir = dirs->data; 867 ConfigDirective *cfgdir = dirs->directive;
870 868
871 directive *d = pool_malloc(pool, sizeof(directive)); 869 directive *d = pool_malloc(pool, sizeof(directive));
872 if(!d) return -1; 870 if(!d) return -1;
873 if(cfgdir->condition) { 871 if(cfgdir->condition) {
874 sstr_t expr = cfgdir->condition->param_str; 872 cxmutstr expr = cfgdir->condition->param_str;
875 d->cond = condition_from_str(pool, expr.ptr, expr.length); 873 d->cond = condition_from_str(pool, expr.ptr, expr.length);
876 } else { 874 } else {
877 d->cond = NULL; 875 d->cond = NULL;
878 } 876 }
879 d->param = pblock_create_pool(pool, 8); 877 d->param = pblock_create_pool(pool, 8);
880 878
881 // add params 879 // add params
882 UcxList *param = cfg_param_list(cfgdir->value, scfg->a); 880 ConfigParam *param = cfg_param_list(cfgdir->value, scfg->a);
883 while(param != NULL) { 881 while(param != NULL) {
884 ConfigParam *p = param->data;
885 pblock_nvlinsert( 882 pblock_nvlinsert(
886 p->name.ptr, 883 param->name.ptr,
887 p->name.length, 884 param->name.length,
888 p->value.ptr, 885 param->value.ptr,
889 p->value.length, 886 param->value.length,
890 d->param); 887 d->param);
891 param = param->next; 888 param = param->next;
892 } 889 }
893 890
894 // get function 891 // get function
910 } 907 }
911 } 908 }
912 909
913 // next 910 // next
914 i++; 911 i++;
915 objlist = objlist->next;
916 } 912 }
917 913
918 return 0; 914 return 0;
919 } 915 }
920 916
921 HTTPObjectConfig* objconf_load(ServerConfiguration *scfg, sstr_t file) { 917 HTTPObjectConfig* objconf_load(ServerConfiguration *scfg, cxmutstr file) {
922 log_ereport(LOG_VERBOSE, "load_obj_conf"); 918 log_ereport(LOG_VERBOSE, "load_obj_conf");
923 919
924 int ret = 0; 920 int ret = 0;
925 921
926 // create object config 922 // create object config
938 } 934 }
939 935
940 // convert ObjectConfig to HTTPObjectConfig 936 // convert ObjectConfig to HTTPObjectConfig
941 937
942 // add objects 938 // add objects
943 conf->nobj = ucx_list_size(cfg->objects); 939 conf->nobj = cfg->objects->size;
944 conf->objects = pool_calloc(pool, conf->nobj, sizeof(httpd_object*)); 940 conf->objects = pool_calloc(pool, conf->nobj, sizeof(httpd_object*));
945 if(conf->objects) { 941 if(conf->objects) {
946 ret = convert_objconf(scfg, cfg, conf, file); 942 ret = convert_objconf(scfg, cfg, conf, file);
947 } else { 943 } else {
948 ret = -1; 944 ret = -1;
951 free_object_config(cfg); 947 free_object_config(cfg);
952 948
953 return !ret ? conf : NULL; 949 return !ret ? conf : NULL;
954 } 950 }
955 951
956 int mime_conf_load(ServerConfiguration *cfg, sstr_t file) { 952 int mime_conf_load(ServerConfiguration *cfg, cxmutstr file) {
957 MimeConfig *mimecfg = load_mime_config(file.ptr); 953 MimeConfig *mimecfg = load_mime_config(file.ptr);
958 if(!mimecfg) { 954 if(!mimecfg) {
959 return -1; 955 return -1;
960 } 956 }
961 957
962 int ret = 0; 958 int ret = 0;
963 959
964 // cleanup in case of errors is done by the allocator 960 // cleanup in case of errors is done by the allocator
965 MimeMap *mimemap = almalloc(cfg->a, sizeof(MimeMap)); 961 MimeMap *mimemap = cxMalloc(cfg->a, sizeof(MimeMap));
966 UcxMap *map = ucx_map_new_a(cfg->a, (mimecfg->ntypes * 3) / 2); 962 CxMap *map = cxHashMapCreate(cfg->a, (mimecfg->ntypes * 3) / 2);
967 963
968 if(mimemap && map) { 964 if(mimemap && map) {
969 mimemap->map = map; 965 mimemap->map = map;
970 966
971 // add ext type pairs 967 // add ext type pairs
972 UCX_FOREACH(md, mimecfg->directives) { 968 for(MimeDirective *d=mimecfg->directives_begin;d;d=d->next) {
973 MimeDirective *d = md->data;
974 // add the type for each extension to the map 969 // add the type for each extension to the map
975 UCX_FOREACH(xl, d->exts) { 970 for(int i=0;i<d->nextensions;i++) {
976 sstr_t ext = sstr(xl->data); 971 cxstring ext = d->extensions[i];
977 sstr_t value = sstrdup(d->type); 972 cxmutstr value = cx_strdup(cx_strn(d->type.ptr, d->type.length));
978 if(ucx_map_sstr_put(map, ext, value.ptr)) { 973 if(cxMapPut(map, cx_hash_key_bytes((const unsigned char *)ext.ptr, ext.length), value.ptr)) {
979 log_ereport(LOG_CATASTROPHE, "OOM"); 974 log_ereport(LOG_CATASTROPHE, "OOM");
980 ret = -1; 975 ret = -1;
981 break; 976 break;
982 } 977 }
983 } 978 }
996 return ret; 991 return ret;
997 } 992 }
998 993
999 994
1000 995
1001 ACLData* acl_conf_load(ServerConfiguration *cfg, sstr_t file) { 996 ACLData* acl_conf_load(ServerConfiguration *cfg, const char *file) {
1002 ACLFile *aclfile = load_acl_file(file.ptr); 997 ACLFile *aclfile = load_acl_file(file);
998 if(!aclfile) {
999 log_ereport(LOG_FAILURE, "Cannot load acl file %s", file);
1000 return NULL;
1001 }
1003 1002
1004 // TODO: malloc return checks 1003 // TODO: malloc return checks
1005 1004
1006 ACLData *acldata = acl_data_new(cfg->a); 1005 ACLData *acldata = acl_data_new(cfg->a);
1007 UCX_FOREACH(elm, aclfile->namedACLs) { 1006 CxIterator iter = cxListIterator(aclfile->namedACLs, 0);
1008 ACLConfig *ac = elm->data; 1007 cx_foreach(ACLConfig *, ac, iter) {
1009 ACLList *acl = acl_config_convert(cfg, ac); 1008 ACLList *acl = acl_config_convert(cfg, ac);
1010 log_ereport(LOG_VERBOSE, "add acl: %.*s", (int)ac->id.length, ac->id.ptr); 1009 log_ereport(LOG_VERBOSE, "add acl: %.*s", (int)ac->id.length, ac->id.ptr);
1011 ucx_map_sstr_put(acldata->namedACLs, ac->id, acl); 1010 cxMapPut(acldata->namedACLs, cx_hash_key(ac->id.ptr, ac->id.length), acl);
1012 } 1011 }
1013 free_acl_file(aclfile); 1012 free_acl_file(aclfile);
1014 1013
1015 return acldata; 1014 return acldata;
1016 } 1015 }
1017 1016
1018 ACLList* acl_config_convert(ServerConfiguration *cfg, ACLConfig *acl) { 1017 ACLList* acl_config_convert(ServerConfiguration *cfg, ACLConfig *acl) {
1019 UcxAllocator *a = cfg->a; 1018 CxAllocator *a = cfg->a;
1020 1019
1021 WSAcl *acllist = almalloc(cfg->a, sizeof(WSAcl)); 1020 WSAcl *acllist = cxMalloc(cfg->a, sizeof(WSAcl));
1022 acllist->acl.check = (acl_check_f)wsacl_check; 1021 acllist->acl.check = (acl_check_f)wsacl_check;
1023 acllist->acl.authdb = NULL; 1022 acllist->acl.authdb = NULL;
1024 acllist->acl.authprompt = NULL; 1023 acllist->acl.authprompt = NULL;
1025 acllist->acl.isextern = 0; 1024 acllist->acl.isextern = 0;
1026 acllist->ace = NULL; 1025 acllist->ace = NULL;
1027 acllist->ece = NULL; 1026 acllist->ece = NULL;
1028 1027
1029 if(acl->type.ptr && !sstrcmp(acl->type, sstr("fs"))) { 1028 if(acl->type.ptr && !cx_strcmp(cx_strn(acl->type.ptr, acl->type.length), cx_str("fs"))) {
1030 acllist->acl.isextern = 1; 1029 acllist->acl.isextern = 1;
1031 } 1030 }
1032 1031
1033 size_t s = ucx_list_size(acl->entries); 1032 size_t s = CFG_ACE_LIST_SIZE(acl->entries);
1034 WSAce **tmp_aces = calloc(s, sizeof(WSAce*)); 1033 WSAce **tmp_aces = calloc(s, sizeof(WSAce*));
1035 WSAce **tmp_eces = calloc(s, sizeof(WSAce*)); 1034 WSAce **tmp_eces = calloc(s, sizeof(WSAce*));
1036 int ai = 0; 1035 int ai = 0;
1037 int ei = 0; 1036 int ei = 0;
1038 1037
1039 // convert entries 1038 // convert entries
1040 UCX_FOREACH(elm, acl->entries) { 1039 for(ACEConfig *acecfg=acl->entries;acecfg;acecfg=acecfg->next) {
1041 ACEConfig *acecfg = elm->data;
1042
1043 // copy data 1040 // copy data
1044 WSAce *ace = almalloc(a, sizeof(WSAce)); 1041 WSAce *ace = cxMalloc(a, sizeof(WSAce));
1045 ace->access_mask = acecfg->access_mask; 1042 ace->access_mask = acecfg->access_mask;
1046 ace->flags = acecfg->flags; 1043 ace->flags = acecfg->flags;
1047 ace->type = acecfg->type; 1044 ace->type = acecfg->type;
1048 ace->who = sstrdup_a(a, acecfg->who).ptr; 1045 ace->who = cx_strdup_a(a, cx_strcast(acecfg->who)).ptr;
1049 1046
1050 // add the entry to the correct array 1047 // add the entry to the correct array
1051 if(ace->type >= ACL_TYPE_AUDIT) { 1048 if(ace->type >= ACL_TYPE_AUDIT) {
1052 tmp_eces[ei] = ace; 1049 tmp_eces[ei] = ace;
1053 ei++; 1050 ei++;
1057 } 1054 }
1058 } 1055 }
1059 1056
1060 // create new entrie arrays with perfect fitting size 1057 // create new entrie arrays with perfect fitting size
1061 if(ai > 0) { 1058 if(ai > 0) {
1062 acllist->ace = alcalloc(a, ai, sizeof(WSAce*)); 1059 acllist->ace = cxCalloc(a, ai, sizeof(WSAce*));
1063 } 1060 }
1064 if(ei > 0) { 1061 if(ei > 0) {
1065 acllist->ece = alcalloc(a, ei, sizeof(WSAce*)); 1062 acllist->ece = cxCalloc(a, ei, sizeof(WSAce*));
1066 } 1063 }
1067 memcpy(acllist->ace, tmp_aces, ai*sizeof(WSAce*)); 1064 memcpy(acllist->ace, tmp_aces, ai*sizeof(WSAce*));
1068 memcpy(acllist->ece, tmp_eces, ei*sizeof(WSAce*)); 1065 memcpy(acllist->ece, tmp_eces, ei*sizeof(WSAce*));
1069 acllist->acenum = ai; 1066 acllist->acenum = ai;
1070 acllist->ecenum = ei; 1067 acllist->ecenum = ei;
1072 free(tmp_aces); 1069 free(tmp_aces);
1073 free(tmp_eces); 1070 free(tmp_eces);
1074 1071
1075 // get authentication information 1072 // get authentication information
1076 if(acl->authparam) { 1073 if(acl->authparam) {
1077 sstr_t authdb_str = cfg_param_get(acl->authparam, sstr("authdb")); 1074 cxmutstr authdb_str = cfg_param_get(acl->authparam, cx_str("authdb"));
1078 sstr_t prompt_str = cfg_param_get(acl->authparam, sstr("prompt")); 1075 cxmutstr prompt_str = cfg_param_get(acl->authparam, cx_str("prompt"));
1079 1076
1080 if(authdb_str.ptr) { 1077 if(authdb_str.ptr) {
1081 AuthDB *authdb = ucx_map_sstr_get(cfg->authdbs, authdb_str); 1078 AuthDB *authdb = cxMapGet(cfg->authdbs, cx_hash_key(authdb_str.ptr, authdb_str.length));
1082 acllist->acl.authdb = authdb; 1079 acllist->acl.authdb = authdb;
1083 if(authdb && prompt_str.ptr) { 1080 if(authdb && prompt_str.ptr) {
1084 acllist->acl.authprompt = sstrdup_a(a, prompt_str).ptr; 1081 acllist->acl.authprompt = cx_strdup_a(a, cx_strcast(prompt_str)).ptr;
1085 } 1082 }
1086 } 1083 }
1087 } 1084 }
1088 1085
1089 return &acllist->acl; 1086 return &acllist->acl;
1090 } 1087 }
1091 1088
1092 AuthDB* keyfile_load(ServerConfiguration *cfg, scstr_t file) { 1089 AuthDB* keyfile_load(ServerConfiguration *cfg, cxstring file) {
1093 Keyfile *keyfile = keyfile_new(cfg->a); 1090 Keyfile *keyfile = keyfile_new(cfg->a);
1094 if(!keyfile) { 1091 if(!keyfile) {
1095 return NULL; 1092 return NULL;
1096 } 1093 }
1097 1094
1100 return NULL; 1097 return NULL;
1101 } 1098 }
1102 1099
1103 AuthDB *ret = &keyfile->authdb; 1100 AuthDB *ret = &keyfile->authdb;
1104 1101
1105 UCX_FOREACH(elm, conf->users) { 1102 for(KeyfileEntry *user=conf->users_begin;user;user=user->next) {
1106 KeyfileEntry *user = elm->data;
1107 if(keyfile_add_user( 1103 if(keyfile_add_user(
1108 keyfile, 1104 keyfile,
1109 user->name, 1105 user->name,
1110 user->hashtype, 1106 user->hashtype,
1111 user->hashdata, 1107 user->hashdata,
1122 return ret; 1118 return ret;
1123 } 1119 }
1124 1120
1125 pblock* config_obj2pblock(pool_handle_t *pool, ConfigNode *obj) { 1121 pblock* config_obj2pblock(pool_handle_t *pool, ConfigNode *obj) {
1126 pblock *pb = pblock_create_pool(pool, 8); 1122 pblock *pb = pblock_create_pool(pool, 8);
1127 UCX_FOREACH(elm, obj->children) { 1123 for(ConfigNode *d=obj->children_begin;d;d=d->next) {
1128 ConfigNode *d = elm->data; 1124 if(d->type == CONFIG_NODE_DIRECTIVE && d->name.length > 0 && CFG_NUM_PARAMS(d->args) == 1) {
1129 if(d->type == CONFIG_NODE_DIRECTIVE && d->name.length > 0 && ucx_list_size(d->args) == 1) { 1125 ConfigParam *arg = d->args;
1130 ConfigArg *arg = d->args->data;
1131 pblock_nvlinsert(d->name.ptr, d->name.length, arg->value.ptr, arg->value.length, pb); 1126 pblock_nvlinsert(d->name.ptr, d->name.length, arg->value.ptr, arg->value.length, pb);
1132 } 1127 }
1133 } 1128 }
1134 return pb; 1129 return pb;
1135 } 1130 }

mercurial