Line data Source code
1 : /* crypto/conf/conf.c */
2 : /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 : * All rights reserved.
4 : *
5 : * This package is an SSL implementation written
6 : * by Eric Young (eay@cryptsoft.com).
7 : * The implementation was written so as to conform with Netscapes SSL.
8 : *
9 : * This library is free for commercial and non-commercial use as long as
10 : * the following conditions are aheared to. The following conditions
11 : * apply to all code found in this distribution, be it the RC4, RSA,
12 : * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 : * included with this distribution is covered by the same copyright terms
14 : * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 : *
16 : * Copyright remains Eric Young's, and as such any Copyright notices in
17 : * the code are not to be removed.
18 : * If this package is used in a product, Eric Young should be given attribution
19 : * as the author of the parts of the library used.
20 : * This can be in the form of a textual message at program startup or
21 : * in documentation (online or textual) provided with the package.
22 : *
23 : * Redistribution and use in source and binary forms, with or without
24 : * modification, are permitted provided that the following conditions
25 : * are met:
26 : * 1. Redistributions of source code must retain the copyright
27 : * notice, this list of conditions and the following disclaimer.
28 : * 2. Redistributions in binary form must reproduce the above copyright
29 : * notice, this list of conditions and the following disclaimer in the
30 : * documentation and/or other materials provided with the distribution.
31 : * 3. All advertising materials mentioning features or use of this software
32 : * must display the following acknowledgement:
33 : * "This product includes cryptographic software written by
34 : * Eric Young (eay@cryptsoft.com)"
35 : * The word 'cryptographic' can be left out if the rouines from the library
36 : * being used are not cryptographic related :-).
37 : * 4. If you include any Windows specific code (or a derivative thereof) from
38 : * the apps directory (application code) you must include an acknowledgement:
39 : * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 : *
41 : * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 : * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 : * SUCH DAMAGE.
52 : *
53 : * The licence and distribution terms for any publically available version or
54 : * derivative of this code cannot be changed. i.e. this code cannot simply be
55 : * copied and put under another distribution licence
56 : * [including the GNU Public Licence.]
57 : */
58 :
59 : /* Part of the code in here was originally in conf.c, which is now removed */
60 :
61 : #include <stdio.h>
62 : #include <string.h>
63 : #include "cryptlib.h"
64 : #include <openssl/stack.h>
65 : #include <openssl/lhash.h>
66 : #include <openssl/conf.h>
67 : #include <openssl/conf_api.h>
68 : #include "conf_def.h"
69 : #include <openssl/buffer.h>
70 : #include <openssl/err.h>
71 :
72 : static char *eat_ws(CONF *conf, char *p);
73 : static char *eat_alpha_numeric(CONF *conf, char *p);
74 : static void clear_comments(CONF *conf, char *p);
75 : static int str_copy(CONF *conf, char *section, char **to, char *from);
76 : static char *scan_quote(CONF *conf, char *p);
77 : static char *scan_dquote(CONF *conf, char *p);
78 : #define scan_esc(conf,p) (((IS_EOF((conf),(p)[1]))?((p)+1):((p)+2)))
79 :
80 : static CONF *def_create(CONF_METHOD *meth);
81 : static int def_init_default(CONF *conf);
82 : static int def_init_WIN32(CONF *conf);
83 : static int def_destroy(CONF *conf);
84 : static int def_destroy_data(CONF *conf);
85 : static int def_load(CONF *conf, const char *name, long *eline);
86 : static int def_load_bio(CONF *conf, BIO *bp, long *eline);
87 : static int def_dump(const CONF *conf, BIO *bp);
88 : static int def_is_number(const CONF *conf, char c);
89 : static int def_to_int(const CONF *conf, char c);
90 :
91 : const char CONF_def_version[] = "CONF_def" OPENSSL_VERSION_PTEXT;
92 :
93 : static CONF_METHOD default_method = {
94 : "OpenSSL default",
95 : def_create,
96 : def_init_default,
97 : def_destroy,
98 : def_destroy_data,
99 : def_load_bio,
100 : def_dump,
101 : def_is_number,
102 : def_to_int,
103 : def_load
104 : };
105 :
106 : static CONF_METHOD WIN32_method = {
107 : "WIN32",
108 : def_create,
109 : def_init_WIN32,
110 : def_destroy,
111 : def_destroy_data,
112 : def_load_bio,
113 : def_dump,
114 : def_is_number,
115 : def_to_int,
116 : def_load
117 : };
118 :
119 0 : CONF_METHOD *NCONF_default()
120 : {
121 0 : return &default_method;
122 : }
123 :
124 0 : CONF_METHOD *NCONF_WIN32()
125 : {
126 0 : return &WIN32_method;
127 : }
128 :
129 0 : static CONF *def_create(CONF_METHOD *meth)
130 : {
131 : CONF *ret;
132 :
133 0 : ret = OPENSSL_malloc(sizeof(CONF) + sizeof(unsigned short *));
134 0 : if (ret)
135 0 : if (meth->init(ret) == 0) {
136 0 : OPENSSL_free(ret);
137 : ret = NULL;
138 : }
139 0 : return ret;
140 : }
141 :
142 0 : static int def_init_default(CONF *conf)
143 : {
144 0 : if (conf == NULL)
145 : return 0;
146 :
147 0 : conf->meth = &default_method;
148 0 : conf->meth_data = CONF_type_default;
149 0 : conf->data = NULL;
150 :
151 0 : return 1;
152 : }
153 :
154 0 : static int def_init_WIN32(CONF *conf)
155 : {
156 0 : if (conf == NULL)
157 : return 0;
158 :
159 0 : conf->meth = &WIN32_method;
160 0 : conf->meth_data = (void *)CONF_type_win32;
161 0 : conf->data = NULL;
162 :
163 0 : return 1;
164 : }
165 :
166 0 : static int def_destroy(CONF *conf)
167 : {
168 0 : if (def_destroy_data(conf)) {
169 0 : OPENSSL_free(conf);
170 0 : return 1;
171 : }
172 : return 0;
173 : }
174 :
175 0 : static int def_destroy_data(CONF *conf)
176 : {
177 0 : if (conf == NULL)
178 : return 0;
179 0 : _CONF_free_data(conf);
180 0 : return 1;
181 : }
182 :
183 0 : static int def_load(CONF *conf, const char *name, long *line)
184 : {
185 : int ret;
186 : BIO *in = NULL;
187 :
188 : #ifdef OPENSSL_SYS_VMS
189 : in = BIO_new_file(name, "r");
190 : #else
191 0 : in = BIO_new_file(name, "rb");
192 : #endif
193 0 : if (in == NULL) {
194 0 : if (ERR_GET_REASON(ERR_peek_last_error()) == BIO_R_NO_SUCH_FILE)
195 0 : CONFerr(CONF_F_DEF_LOAD, CONF_R_NO_SUCH_FILE);
196 : else
197 0 : CONFerr(CONF_F_DEF_LOAD, ERR_R_SYS_LIB);
198 : return 0;
199 : }
200 :
201 0 : ret = def_load_bio(conf, in, line);
202 0 : BIO_free(in);
203 :
204 0 : return ret;
205 : }
206 :
207 0 : static int def_load_bio(CONF *conf, BIO *in, long *line)
208 : {
209 : /* The macro BUFSIZE conflicts with a system macro in VxWorks */
210 : #define CONFBUFSIZE 512
211 : int bufnum = 0, i, ii;
212 : BUF_MEM *buff = NULL;
213 : char *s, *p, *end;
214 : int again;
215 : long eline = 0;
216 : char btmp[DECIMAL_SIZE(eline) + 1];
217 : CONF_VALUE *v = NULL, *tv;
218 : CONF_VALUE *sv = NULL;
219 0 : char *section = NULL, *buf;
220 : char *start, *psection, *pname;
221 0 : void *h = (void *)(conf->data);
222 :
223 0 : if ((buff = BUF_MEM_new()) == NULL) {
224 0 : CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_BUF_LIB);
225 0 : goto err;
226 : }
227 :
228 0 : section = (char *)OPENSSL_malloc(10);
229 0 : if (section == NULL) {
230 0 : CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
231 0 : goto err;
232 : }
233 0 : BUF_strlcpy(section, "default", 10);
234 :
235 0 : if (_CONF_new_data(conf) == 0) {
236 0 : CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
237 0 : goto err;
238 : }
239 :
240 0 : sv = _CONF_new_section(conf, section);
241 0 : if (sv == NULL) {
242 0 : CONFerr(CONF_F_DEF_LOAD_BIO, CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
243 0 : goto err;
244 : }
245 :
246 : bufnum = 0;
247 : again = 0;
248 : for (;;) {
249 0 : if (!BUF_MEM_grow(buff, bufnum + CONFBUFSIZE)) {
250 0 : CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_BUF_LIB);
251 0 : goto err;
252 : }
253 0 : p = &(buff->data[bufnum]);
254 0 : *p = '\0';
255 0 : BIO_gets(in, p, CONFBUFSIZE - 1);
256 0 : p[CONFBUFSIZE - 1] = '\0';
257 0 : ii = i = strlen(p);
258 0 : if (i == 0 && !again)
259 : break;
260 : again = 0;
261 0 : while (i > 0) {
262 0 : if ((p[i - 1] != '\r') && (p[i - 1] != '\n'))
263 : break;
264 : else
265 0 : i--;
266 : }
267 : /*
268 : * we removed some trailing stuff so there is a new line on the end.
269 : */
270 0 : if (ii && i == ii)
271 : again = 1; /* long line */
272 : else {
273 0 : p[i] = '\0';
274 0 : eline++; /* another input line */
275 : }
276 :
277 : /* we now have a line with trailing \r\n removed */
278 :
279 : /* i is the number of bytes */
280 0 : bufnum += i;
281 :
282 : v = NULL;
283 : /* check for line continuation */
284 0 : if (bufnum >= 1) {
285 : /*
286 : * If we have bytes and the last char '\\' and second last char
287 : * is not '\\'
288 : */
289 0 : p = &(buff->data[bufnum - 1]);
290 0 : if (IS_ESC(conf, p[0]) && ((bufnum <= 1) || !IS_ESC(conf, p[-1]))) {
291 0 : bufnum--;
292 : again = 1;
293 : }
294 : }
295 0 : if (again)
296 0 : continue;
297 : bufnum = 0;
298 0 : buf = buff->data;
299 :
300 0 : clear_comments(conf, buf);
301 : s = eat_ws(conf, buf);
302 0 : if (IS_EOF(conf, *s))
303 0 : continue; /* blank line */
304 0 : if (*s == '[') {
305 : char *ss;
306 :
307 0 : s++;
308 : start = eat_ws(conf, s);
309 : ss = start;
310 : again:
311 0 : end = eat_alpha_numeric(conf, ss);
312 : p = eat_ws(conf, end);
313 0 : if (*p != ']') {
314 0 : if (*p != '\0' && ss != p) {
315 : ss = p;
316 : goto again;
317 : }
318 0 : CONFerr(CONF_F_DEF_LOAD_BIO,
319 : CONF_R_MISSING_CLOSE_SQUARE_BRACKET);
320 0 : goto err;
321 : }
322 0 : *end = '\0';
323 0 : if (!str_copy(conf, NULL, §ion, start))
324 : goto err;
325 0 : if ((sv = _CONF_get_section(conf, section)) == NULL)
326 0 : sv = _CONF_new_section(conf, section);
327 0 : if (sv == NULL) {
328 0 : CONFerr(CONF_F_DEF_LOAD_BIO,
329 : CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
330 0 : goto err;
331 : }
332 0 : continue;
333 : } else {
334 : pname = s;
335 : psection = NULL;
336 0 : end = eat_alpha_numeric(conf, s);
337 0 : if ((end[0] == ':') && (end[1] == ':')) {
338 0 : *end = '\0';
339 0 : end += 2;
340 : psection = pname;
341 : pname = end;
342 0 : end = eat_alpha_numeric(conf, end);
343 : }
344 : p = eat_ws(conf, end);
345 0 : if (*p != '=') {
346 0 : CONFerr(CONF_F_DEF_LOAD_BIO, CONF_R_MISSING_EQUAL_SIGN);
347 0 : goto err;
348 : }
349 0 : *end = '\0';
350 0 : p++;
351 : start = eat_ws(conf, p);
352 0 : while (!IS_EOF(conf, *p))
353 0 : p++;
354 0 : p--;
355 0 : while ((p != start) && (IS_WS(conf, *p)))
356 0 : p--;
357 : p++;
358 0 : *p = '\0';
359 :
360 0 : if (!(v = (CONF_VALUE *)OPENSSL_malloc(sizeof(CONF_VALUE)))) {
361 0 : CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
362 0 : goto err;
363 : }
364 0 : if (psection == NULL)
365 0 : psection = section;
366 0 : v->name = (char *)OPENSSL_malloc(strlen(pname) + 1);
367 0 : v->value = NULL;
368 0 : if (v->name == NULL) {
369 0 : CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
370 0 : goto err;
371 : }
372 0 : BUF_strlcpy(v->name, pname, strlen(pname) + 1);
373 0 : if (!str_copy(conf, psection, &(v->value), start))
374 : goto err;
375 :
376 0 : if (strcmp(psection, section) != 0) {
377 0 : if ((tv = _CONF_get_section(conf, psection))
378 : == NULL)
379 0 : tv = _CONF_new_section(conf, psection);
380 0 : if (tv == NULL) {
381 0 : CONFerr(CONF_F_DEF_LOAD_BIO,
382 : CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
383 0 : goto err;
384 : }
385 : } else
386 : tv = sv;
387 : #if 1
388 0 : if (_CONF_add_string(conf, tv, v) == 0) {
389 0 : CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
390 0 : goto err;
391 : }
392 : #else
393 : v->section = tv->section;
394 : if (!sk_CONF_VALUE_push(ts, v)) {
395 : CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
396 : goto err;
397 : }
398 : vv = (CONF_VALUE *)lh_insert(conf->data, v);
399 : if (vv != NULL) {
400 : sk_CONF_VALUE_delete_ptr(ts, vv);
401 : OPENSSL_free(vv->name);
402 : OPENSSL_free(vv->value);
403 : OPENSSL_free(vv);
404 : }
405 : #endif
406 : v = NULL;
407 : }
408 : }
409 0 : if (buff != NULL)
410 0 : BUF_MEM_free(buff);
411 0 : if (section != NULL)
412 0 : OPENSSL_free(section);
413 : return (1);
414 : err:
415 0 : if (buff != NULL)
416 0 : BUF_MEM_free(buff);
417 0 : if (section != NULL)
418 0 : OPENSSL_free(section);
419 0 : if (line != NULL)
420 0 : *line = eline;
421 0 : BIO_snprintf(btmp, sizeof btmp, "%ld", eline);
422 0 : ERR_add_error_data(2, "line ", btmp);
423 0 : if ((h != conf->data) && (conf->data != NULL)) {
424 0 : CONF_free(conf->data);
425 0 : conf->data = NULL;
426 : }
427 0 : if (v != NULL) {
428 0 : if (v->name != NULL)
429 0 : OPENSSL_free(v->name);
430 0 : if (v->value != NULL)
431 0 : OPENSSL_free(v->value);
432 0 : if (v != NULL)
433 0 : OPENSSL_free(v);
434 : }
435 : return (0);
436 : }
437 :
438 0 : static void clear_comments(CONF *conf, char *p)
439 : {
440 : for (;;) {
441 0 : if (IS_FCOMMENT(conf, *p)) {
442 0 : *p = '\0';
443 : return;
444 : }
445 0 : if (!IS_WS(conf, *p)) {
446 : break;
447 : }
448 0 : p++;
449 : }
450 :
451 : for (;;) {
452 0 : if (IS_COMMENT(conf, *p)) {
453 0 : *p = '\0';
454 : return;
455 : }
456 0 : if (IS_DQUOTE(conf, *p)) {
457 0 : p = scan_dquote(conf, p);
458 0 : continue;
459 : }
460 0 : if (IS_QUOTE(conf, *p)) {
461 0 : p = scan_quote(conf, p);
462 0 : continue;
463 : }
464 0 : if (IS_ESC(conf, *p)) {
465 0 : p = scan_esc(conf, p);
466 0 : continue;
467 : }
468 0 : if (IS_EOF(conf, *p))
469 : return;
470 : else
471 0 : p++;
472 : }
473 : }
474 :
475 0 : static int str_copy(CONF *conf, char *section, char **pto, char *from)
476 : {
477 : int q, r, rr = 0, to = 0, len = 0;
478 : char *s, *e, *rp, *p, *rrp, *np, *cp, v;
479 : BUF_MEM *buf;
480 :
481 0 : if ((buf = BUF_MEM_new()) == NULL)
482 : return (0);
483 :
484 0 : len = strlen(from) + 1;
485 0 : if (!BUF_MEM_grow(buf, len))
486 : goto err;
487 :
488 : for (;;) {
489 0 : if (IS_QUOTE(conf, *from)) {
490 0 : q = *from;
491 0 : from++;
492 0 : while (!IS_EOF(conf, *from) && (*from != q)) {
493 0 : if (IS_ESC(conf, *from)) {
494 0 : from++;
495 0 : if (IS_EOF(conf, *from))
496 : break;
497 : }
498 0 : buf->data[to++] = *(from++);
499 : }
500 0 : if (*from == q)
501 0 : from++;
502 0 : } else if (IS_DQUOTE(conf, *from)) {
503 0 : q = *from;
504 0 : from++;
505 0 : while (!IS_EOF(conf, *from)) {
506 0 : if (*from == q) {
507 0 : if (*(from + 1) == q) {
508 0 : from++;
509 : } else {
510 : break;
511 : }
512 : }
513 0 : buf->data[to++] = *(from++);
514 : }
515 0 : if (*from == q)
516 0 : from++;
517 0 : } else if (IS_ESC(conf, *from)) {
518 : from++;
519 0 : v = *(from++);
520 0 : if (IS_EOF(conf, v))
521 : break;
522 0 : else if (v == 'r')
523 : v = '\r';
524 0 : else if (v == 'n')
525 : v = '\n';
526 0 : else if (v == 'b')
527 : v = '\b';
528 0 : else if (v == 't')
529 : v = '\t';
530 0 : buf->data[to++] = v;
531 0 : } else if (IS_EOF(conf, *from))
532 : break;
533 0 : else if (*from == '$') {
534 : /* try to expand it */
535 : rrp = NULL;
536 0 : s = &(from[1]);
537 0 : if (*s == '{')
538 : q = '}';
539 0 : else if (*s == '(')
540 : q = ')';
541 : else
542 : q = 0;
543 :
544 0 : if (q)
545 0 : s++;
546 : cp = section;
547 : e = np = s;
548 0 : while (IS_ALPHA_NUMERIC(conf, *e))
549 0 : e++;
550 0 : if ((e[0] == ':') && (e[1] == ':')) {
551 : cp = np;
552 : rrp = e;
553 0 : rr = *e;
554 0 : *rrp = '\0';
555 0 : e += 2;
556 : np = e;
557 0 : while (IS_ALPHA_NUMERIC(conf, *e))
558 0 : e++;
559 : }
560 0 : r = *e;
561 0 : *e = '\0';
562 : rp = e;
563 0 : if (q) {
564 0 : if (r != q) {
565 0 : CONFerr(CONF_F_STR_COPY, CONF_R_NO_CLOSE_BRACE);
566 0 : goto err;
567 : }
568 0 : e++;
569 : }
570 : /*-
571 : * So at this point we have
572 : * np which is the start of the name string which is
573 : * '\0' terminated.
574 : * cp which is the start of the section string which is
575 : * '\0' terminated.
576 : * e is the 'next point after'.
577 : * r and rr are the chars replaced by the '\0'
578 : * rp and rrp is where 'r' and 'rr' came from.
579 : */
580 0 : p = _CONF_get_string(conf, cp, np);
581 0 : if (rrp != NULL)
582 0 : *rrp = rr;
583 0 : *rp = r;
584 0 : if (p == NULL) {
585 0 : CONFerr(CONF_F_STR_COPY, CONF_R_VARIABLE_HAS_NO_VALUE);
586 0 : goto err;
587 : }
588 0 : if (!BUF_MEM_grow_clean(buf,
589 0 : (strlen(p) + buf->length - (e - from)))) {
590 0 : CONFerr(CONF_F_STR_COPY, ERR_R_MALLOC_FAILURE);
591 0 : goto err;
592 : }
593 0 : while (*p)
594 0 : buf->data[to++] = *(p++);
595 :
596 : /*
597 : * Since we change the pointer 'from', we also have to change the
598 : * perceived length of the string it points at. /RL
599 : */
600 : len -= e - from;
601 : from = e;
602 :
603 : /*
604 : * In case there were no braces or parenthesis around the
605 : * variable reference, we have to put back the character that was
606 : * replaced with a '\0'. /RL
607 : */
608 0 : *rp = r;
609 : } else
610 0 : buf->data[to++] = *(from++);
611 : }
612 0 : buf->data[to] = '\0';
613 0 : if (*pto != NULL)
614 0 : OPENSSL_free(*pto);
615 0 : *pto = buf->data;
616 0 : OPENSSL_free(buf);
617 0 : return (1);
618 : err:
619 0 : if (buf != NULL)
620 0 : BUF_MEM_free(buf);
621 : return (0);
622 : }
623 :
624 : static char *eat_ws(CONF *conf, char *p)
625 : {
626 0 : while (IS_WS(conf, *p) && (!IS_EOF(conf, *p)))
627 0 : p++;
628 : return (p);
629 : }
630 :
631 0 : static char *eat_alpha_numeric(CONF *conf, char *p)
632 : {
633 : for (;;) {
634 0 : if (IS_ESC(conf, *p)) {
635 0 : p = scan_esc(conf, p);
636 0 : continue;
637 : }
638 0 : if (!IS_ALPHA_NUMERIC_PUNCT(conf, *p))
639 0 : return (p);
640 0 : p++;
641 : }
642 : }
643 :
644 0 : static char *scan_quote(CONF *conf, char *p)
645 : {
646 0 : int q = *p;
647 :
648 0 : p++;
649 0 : while (!(IS_EOF(conf, *p)) && (*p != q)) {
650 0 : if (IS_ESC(conf, *p)) {
651 0 : p++;
652 0 : if (IS_EOF(conf, *p))
653 : return (p);
654 : }
655 0 : p++;
656 : }
657 0 : if (*p == q)
658 0 : p++;
659 : return (p);
660 : }
661 :
662 0 : static char *scan_dquote(CONF *conf, char *p)
663 : {
664 0 : int q = *p;
665 :
666 0 : p++;
667 0 : while (!(IS_EOF(conf, *p))) {
668 0 : if (*p == q) {
669 0 : if (*(p + 1) == q) {
670 0 : p++;
671 : } else {
672 : break;
673 : }
674 : }
675 0 : p++;
676 : }
677 0 : if (*p == q)
678 0 : p++;
679 0 : return (p);
680 : }
681 :
682 0 : static void dump_value_doall_arg(CONF_VALUE *a, BIO *out)
683 : {
684 0 : if (a->name)
685 0 : BIO_printf(out, "[%s] %s=%s\n", a->section, a->name, a->value);
686 : else
687 0 : BIO_printf(out, "[[%s]]\n", a->section);
688 0 : }
689 :
690 0 : static IMPLEMENT_LHASH_DOALL_ARG_FN(dump_value, CONF_VALUE, BIO)
691 :
692 0 : static int def_dump(const CONF *conf, BIO *out)
693 : {
694 0 : lh_CONF_VALUE_doall_arg(conf->data, LHASH_DOALL_ARG_FN(dump_value),
695 : BIO, out);
696 0 : return 1;
697 : }
698 :
699 0 : static int def_is_number(const CONF *conf, char c)
700 : {
701 0 : return IS_NUMBER(conf, c);
702 : }
703 :
704 0 : static int def_to_int(const CONF *conf, char c)
705 : {
706 0 : return c - '0';
707 : }
|