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