1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 #include "conf.h"
30 #include "logging.h"
31
32 #include <string.h>
33
34 int cfg_parse_basic_file(ConfigParser *parser,
FILE *in) {
35 parser->lines_begin =
NULL;
36 parser->lines_end =
NULL;
37 CxMempool *mp = cxBasicMempoolCreate(
512);
38 CxAllocator *a = (CxAllocator*)mp->allocator;
39 parser->mp = a;
40
41
42 cxmutstr mline;
43 mline.ptr =
NULL;
44 mline.length =
0;
45 ConfigLine *start_line =
NULL;
46 ConfigLine *end_line =
NULL;
47
48
49 cxmutstr l;
50 while((l = cfg_readln(in)).ptr !=
NULL) {
51 void *org_ptr = l.ptr;
52
53
54 ConfigLine *line =
OBJ_NEW(parser->mp, ConfigLine);
55 line->line = cx_strdup_a(parser->mp, cx_strcast(l));
56 line->object =
NULL;
57 line->type =
LINE_OTHER;
58 CFG_LINE_ADD(&parser->lines_begin, &parser->lines_end, line);
59
60
61 l = cfg_trim_comment(l);
62 line->type = cfg_get_basic_type(l);
63
64 if(line->type ==
LINE_OTHER) {
65
66 if(mline.ptr !=
NULL) {
67
68 char *ptr = cxMalloc(a, mline.length + l.length +
1);
69
70 memcpy(ptr, mline.ptr, mline.length);
71 memcpy(ptr + mline.length -
1, l.ptr, l.length);
72 mline.length += l.length;
73 free(mline.ptr);
74 mline.ptr = ptr;
75 mline.ptr[mline.length] =
0;
76
77 end_line = line;
78
79 line->type =
LINE_MULTI;
80 }
81 if(l.ptr[l.length -
1] ==
'\\') {
82 if(mline.ptr ==
NULL) {
83 mline = cx_strdup_a(parser->mp, cx_strcast(l));
84 start_line = line;
85 }
86 }
else {
87
88 cxmutstr ll;
89
90 if(mline.ptr ==
NULL) {
91
92 ll = l;
93 start_line = line;
94 end_line = line;
95 }
else {
96 ll = mline;
97 }
98
99
100 int r = parser->parse(parser, start_line, end_line, ll);
101
102
103 if(mline.ptr !=
NULL) {
104 free(mline.ptr);
105 mline.ptr =
NULL;
106 mline.length =
0;
107 start_line =
NULL;
108 end_line =
NULL;
109 }
110
111 if(r !=
0) {
112 free(org_ptr);
113 return -
1;
114 }
115 }
116 }
117
118 free(org_ptr);
119 }
120
121 return 0;
122 }
123
124 cxmutstr cfg_readln(
FILE *file) {
125 cxmutstr ns;
126 ns.ptr =
NULL;
127 ns.length =
0;
128
129 if(!feof(file)) {
130 char buf[
512];
131 buf[
0] =
0;
132 int len =
512;
133
134 if(fgets(buf, len, file) ==
NULL) {
135 return ns;
136 }
137
138 if(*buf ==
0) {
139 printf(
"???\n");
140 return ns;
141 }
142
143 char *ptr;
144 if((ptr = strrchr(buf,
'\n'))) {
145 ptr[
0] =
0;
146 }
147
148 cxmutstr line = cx_mutstr(buf);
149 return cx_strdup(cx_strcast(line));
150 }
151
152 cxmutstr s;
153 s.ptr =
NULL;
154 s.length =
0;
155 return s;
156 }
157
158
159
160
161
162 cxmutstr cfg_trim_comment(cxmutstr line) {
163 cxmutstr nl = line;
164 for(
int i=
0;i<line.length;i++) {
165 if(line.ptr[i] ==
'#') {
166 if(i >
0) {
167 nl.ptr = line.ptr + i -
1;
168 nl.length = i;
169 break;
170 }
else {
171 nl.ptr = line.ptr;
172 nl.length =
0;
173 break;
174 }
175 }
176 }
177 return cx_strtrim_m(nl);
178 }
179
180
181
182
183
184
185 cxmutstr cfg_param(cxmutstr params, cxmutstr *name, cxmutstr *value) {
186 name->ptr =
NULL;
187 name->length =
0;
188 value->ptr =
NULL;
189 value->length =
0;
190
191
192 int i;
193 for(i=
0;i<params.length;i++) {
194 char c = params.ptr[i];
195 if(c ==
'=') {
196 break;
197 }
else if(c <
33) {
198
199 name->ptr = params.ptr;
200 name->length = i;
201
202 params.ptr = params.ptr + i;
203 params.length -= i;
204 return cx_strtrim_m(params);
205 }
206 }
207
208 name->ptr = params.ptr;
209 name->length = i;
210 i++;
211
212
213 if(i>=params.length) {
214 cxmutstr ns;
215 ns.ptr =
NULL;
216 ns.length =
0;
217 return ns;
218 }
219
220 int quote =
0;
221 value->ptr = params.ptr + i;
222 for(;i<params.length;i++) {
223 char c = params.ptr[i];
224 if(c ==
'""') {
225 if(quote) {
226 break;
227 }
else {
228 quote =
1;
229 value->ptr++;
230 }
231 }
else if(!quote && c <
33) {
232 break;
233 }
234 }
235
236 if(quote) {
237
238 value->length = i - name->length -
2;
239 i++;
240 }
else {
241
242 value->length = i - name->length -
1;
243 }
244
245 if(value->length <=
0) {
246 value->length =
0;
247 value->ptr =
NULL;
248 }
249
250
251 params.ptr += i;
252 params.length -= i;
253 return cx_strtrim_m(params);
254 }
255
256
257
258
259 cxmutstr cfg_param_get(ConfigParam *param, cxstring name) {
260 while(param !=
NULL) {
261 if(!cx_strcmp((cxstring){param->name.ptr, param->name.length}, name)) {
262 return param->value;
263 }
264 param = param->next;
265 }
266 return (cxmutstr){
NULL,
0 };
267 }
268
269
270
271
272
273 ConfigDirective* cfg_parse_directive(cxmutstr line, CxAllocator *mp) {
274 if(line.length <
6) {
275 ws_cfg_log(
LOG_FAILURE,
"cfg_parse_directive: line too short");
276 return NULL;
277 }
278
279 cxstring name;
280
281 int i;
282 for(i=
0;i<line.length;i++) {
283 if(line.ptr[i] <
33) {
284 break;
285 }
286 }
287 name.ptr = line.ptr;
288 name.length = i;
289
290
291 ConfigDirective *directive =
OBJ_NEW(mp, ConfigDirective);
292 directive->directive_type = cx_strdup_a(mp, name);
293 directive->type_num = cfg_get_directive_type_num(name);
294 directive->condition =
NULL;
295
296
297 cxstring param_str;
298 param_str.ptr = name.ptr + i;
299 param_str.length = line.length - i;
300 param_str = cx_strtrim(param_str);
301 directive->value = cx_strdup_a(mp, param_str);
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330 return directive;
331 }
332
333 ConfigParam* cfg_param_list(cxmutstr param_str, CxAllocator *mp) {
334 cxmutstr pname;
335 cxmutstr pvalue;
336 ConfigParam *plist_begin =
NULL;
337 ConfigParam *plist_end =
NULL;
338 for(;;) {
339 param_str = cfg_param(param_str, &pname, &pvalue);
340 if(pname.length <=
0) {
341 break;
342 }
343
344
345 ConfigParam *param =
OBJ_NEW(mp, ConfigParam);
346 param->name = cx_strdup_a(mp, cx_strcast(pname));
347 param->next =
NULL;
348
349 if(pvalue.length >
0) {
350 param->value = cx_strdup_a(mp, cx_strcast(pvalue));
351 }
else {
352 param->value.ptr =
NULL;
353 param->value.length =
0;
354 }
355
356
357 CFG_PARAM_ADD(&plist_begin, &plist_end, param);
358 }
359 return plist_begin;
360 }
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375 int cfg_get_directive_type_num(cxstring type) {
376
377
378
379 int dt = -
1;
380 if(cx_strcmp(type, cx_str(
"AuthTrans")) ==
0) {
381 dt = NSAPIAuthTrans;
382 }
else if(cx_strcmp(type, cx_str(
"NameTrans")) ==
0) {
383 dt = NSAPINameTrans;
384 }
else if(cx_strcmp(type, cx_str(
"PathCheck")) ==
0) {
385 dt = NSAPIPathCheck;
386 }
else if(cx_strcmp(type, cx_str(
"ObjectType")) ==
0) {
387 dt = NSAPIObjectType;
388 }
else if(cx_strcmp(type, cx_str(
"Service")) ==
0) {
389 dt = NSAPIService;
390 }
else if(cx_strcmp(type, cx_str(
"Error")) ==
0) {
391 dt = NSAPIError;
392 }
else if(cx_strcmp(type, cx_str(
"AddLog")) ==
0) {
393 dt = NSAPIAddLog;
394 }
else if(cx_strcmp(type, cx_str(
"Init")) ==
0) {
395 dt =
INIT_DIRECTIVE;
396 }
397 return dt;
398 }
399
400
401
402
403 int cfg_get_basic_type(cxmutstr line) {
404 if(line.length ==
0) {
405 return LINE_NOCONTENT;
406 }
else if(line.ptr[
0] ==
'#') {
407 return LINE_NOCONTENT;
408 }
409 return LINE_OTHER;
410 }
411
412
413
414
415 int cfg_get_line_type(cxmutstr line) {
416 if(line.length <
3) {
417
418 return LINE_ERROR;
419 }
420
421 if(line.ptr[
0] ==
'<') {
422
423
424 if(line.ptr[
1] ==
'/') {
425 return LINE_END_TAG;
426 }
else {
427 return LINE_BEGIN_TAG;
428 }
429 }
else {
430 return LINE_DIRECTIVE;
431 }
432 }
433
434 int cfg_get_tag_type(cxstring tag) {
435 if(!cx_strcmp(tag, cx_str(
"Object"))) {
436 return TAG_OBJECT;
437 }
else if(!cx_strcmp(tag, cx_str(
"If"))) {
438 return TAG_IF;
439 }
else if(!cx_strcmp(tag, cx_str(
"ElseIf"))) {
440 return TAG_ELSEIF;
441 }
else if(!cx_strcmp(tag, cx_str(
"Else"))) {
442 return TAG_ELSE;
443 }
else if(!cx_strcmp(tag, cx_str(
"Client"))) {
444 return TAG_CLIENT;
445 }
446 return -
1;
447 }
448
449
450
451
452
453 cxmutstr cfg_get_end_tag_name(cxmutstr line) {
454 cxmutstr ns;
455 ns.ptr =
NULL;
456 ns.length =
0;
457
458 if(line.length <
4) {
459
460 return ns;
461 }
462
463 cxmutstr name;
464 name.ptr = line.ptr +
2;
465 name.length = line.length -
3;
466
467
468 if(line.ptr[
0] !=
'<'
469 || line.ptr[
1] !=
'/'
470 || line.ptr[line.length -
1] !=
'>')
471 {
472 return ns;
473 }
474
475 return cx_strtrim_m(name);
476 }
477
478 ConfigTag* cfg_parse_begin_tag(cxmutstr line, CxAllocator *mp) {
479 if(line.length <
4) {
480 return NULL;
481 }
482
483 if(line.ptr[
0] !=
'<' || line.ptr[line.length -
1] !=
'>') {
484 return NULL;
485 }
486
487 cxmutstr name;
488 name.ptr = line.ptr +
1;
489 int i;
490 for(i=
1;i<line.length -
1;i++) {
491 if(line.ptr[i] <
33) {
492 break;
493 }
494 }
495 name.length = i -
1;
496 if(name.length <
1) {
497 return NULL;
498 }
499
500
501 ConfigTag *tag =
OBJ_NEW(mp, ConfigTag);
502 tag->name = cx_strdup_a(mp, cx_strcast(name));
503 tag->param =
NULL;
504
505
506 cxmutstr param_str;
507 param_str.ptr = line.ptr + i;
508 param_str.length = line.length - name.length -
2;
509 param_str = cx_strtrim_m(param_str);
510 if(param_str.length ==
0) {
511 return tag;
512 }
513 tag->param_str = cx_strdup_a(mp, cx_strcast(param_str));
514
515 cxmutstr pname;
516 cxmutstr pvalue;
517 for(;;) {
518 param_str = cfg_param(param_str, &pname, &pvalue);
519 if(pname.length ==
0) {
520 break;
521 }
522
523
524 ConfigParam *param =
OBJ_NEW(mp, ConfigParam);
525 param->next =
NULL;
526 param->name = cx_strdup_a(mp, cx_strcast(pname));
527 if(pvalue.length >
0) {
528 param->value = cx_strdup_a(mp, cx_strcast(pvalue));
529 }
else {
530 param->value.ptr =
NULL;
531 param->value.length =
0;
532 }
533
534
535 CFG_PARAM_ADD(&tag->param,
NULL, param);
536 }
537
538 return tag;
539 }
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607