/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- config_fgets
- get_entry
- parse_section
- parse_list
- parse_binding
- krb5_config_parse_debug
- krb5_config_parse_string_multi
- krb5_config_parse_file_multi
- krb5_config_parse_file
- free_binding
- krb5_config_file_free
- _krb5_config_copy
- krb5_config_get_next
- vget_next
- krb5_config_vget_next
- krb5_config_get
- krb5_config_vget
- krb5_config_get_list
- krb5_config_vget_list
- krb5_config_get_string
- krb5_config_vget_string
- krb5_config_vget_string_default
- krb5_config_get_string_default
- krb5_config_vget_strings
- krb5_config_get_strings
- krb5_config_free_strings
- krb5_config_vget_bool_default
- krb5_config_vget_bool
- krb5_config_get_bool_default
- krb5_config_get_bool
- krb5_config_vget_time_default
- krb5_config_vget_time
- krb5_config_get_time_default
- krb5_config_get_time
- krb5_config_vget_int_default
- krb5_config_vget_int
- krb5_config_get_int_default
- krb5_config_get_int
1 /*
2 * Copyright (c) 1997 - 2004 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34 #include "krb5_locl.h"
35 RCSID("$Id$");
36
37 #ifndef HAVE_NETINFO
38
39 /* Gaah! I want a portable funopen */
40 struct fileptr {
41 const char *s;
42 FILE *f;
43 };
44
45 static char *
46 config_fgets(char *str, size_t len, struct fileptr *ptr)
/* [<][>][^][v][top][bottom][index][help] */
47 {
48 /* XXX this is not correct, in that they don't do the same if the
49 line is longer than len */
50 if(ptr->f != NULL)
51 return fgets(str, len, ptr->f);
52 else {
53 /* this is almost strsep_copy */
54 const char *p;
55 ssize_t l;
56 if(*ptr->s == '\0')
57 return NULL;
58 p = ptr->s + strcspn(ptr->s, "\n");
59 if(*p == '\n')
60 p++;
61 l = min(len, p - ptr->s);
62 if(len > 0) {
63 memcpy(str, ptr->s, l);
64 str[l] = '\0';
65 }
66 ptr->s = p;
67 return str;
68 }
69 }
70
71 static krb5_error_code parse_section(char *p, krb5_config_section **s,
72 krb5_config_section **res,
73 const char **error_message);
74 static krb5_error_code parse_binding(struct fileptr *f, unsigned *lineno, char *p,
75 krb5_config_binding **b,
76 krb5_config_binding **parent,
77 const char **error_message);
78 static krb5_error_code parse_list(struct fileptr *f, unsigned *lineno,
79 krb5_config_binding **parent,
80 const char **error_message);
81
82 static krb5_config_section *
83 get_entry(krb5_config_section **parent, const char *name, int type)
/* [<][>][^][v][top][bottom][index][help] */
84 {
85 krb5_config_section **q;
86
87 for(q = parent; *q != NULL; q = &(*q)->next)
88 if(type == krb5_config_list &&
89 type == (*q)->type &&
90 strcmp(name, (*q)->name) == 0)
91 return *q;
92 *q = calloc(1, sizeof(**q));
93 if(*q == NULL)
94 return NULL;
95 (*q)->name = strdup(name);
96 (*q)->type = type;
97 if((*q)->name == NULL) {
98 free(*q);
99 *q = NULL;
100 return NULL;
101 }
102 return *q;
103 }
104
105 /*
106 * Parse a section:
107 *
108 * [section]
109 * foo = bar
110 * b = {
111 * a
112 * }
113 * ...
114 *
115 * starting at the line in `p', storing the resulting structure in
116 * `s' and hooking it into `parent'.
117 * Store the error message in `error_message'.
118 */
119
120 static krb5_error_code
121 parse_section(char *p, krb5_config_section **s, krb5_config_section **parent,
/* [<][>][^][v][top][bottom][index][help] */
122 const char **error_message)
123 {
124 char *p1;
125 krb5_config_section *tmp;
126
127 p1 = strchr (p + 1, ']');
128 if (p1 == NULL) {
129 *error_message = "missing ]";
130 return KRB5_CONFIG_BADFORMAT;
131 }
132 *p1 = '\0';
133 tmp = get_entry(parent, p + 1, krb5_config_list);
134 if(tmp == NULL) {
135 *error_message = "out of memory";
136 return KRB5_CONFIG_BADFORMAT;
137 }
138 *s = tmp;
139 return 0;
140 }
141
142 /*
143 * Parse a brace-enclosed list from `f', hooking in the structure at
144 * `parent'.
145 * Store the error message in `error_message'.
146 */
147
148 static krb5_error_code
149 parse_list(struct fileptr *f, unsigned *lineno, krb5_config_binding **parent,
/* [<][>][^][v][top][bottom][index][help] */
150 const char **error_message)
151 {
152 char buf[BUFSIZ];
153 krb5_error_code ret;
154 krb5_config_binding *b = NULL;
155 unsigned beg_lineno = *lineno;
156
157 while(config_fgets(buf, sizeof(buf), f) != NULL) {
158 char *p;
159
160 ++*lineno;
161 buf[strcspn(buf, "\r\n")] = '\0';
162 p = buf;
163 while(isspace((unsigned char)*p))
164 ++p;
165 if (*p == '#' || *p == ';' || *p == '\0')
166 continue;
167 while(isspace((unsigned char)*p))
168 ++p;
169 if (*p == '}')
170 return 0;
171 if (*p == '\0')
172 continue;
173 ret = parse_binding (f, lineno, p, &b, parent, error_message);
174 if (ret)
175 return ret;
176 }
177 *lineno = beg_lineno;
178 *error_message = "unclosed {";
179 return KRB5_CONFIG_BADFORMAT;
180 }
181
182 /*
183 *
184 */
185
186 static krb5_error_code
187 parse_binding(struct fileptr *f, unsigned *lineno, char *p,
/* [<][>][^][v][top][bottom][index][help] */
188 krb5_config_binding **b, krb5_config_binding **parent,
189 const char **error_message)
190 {
191 krb5_config_binding *tmp;
192 char *p1, *p2;
193 krb5_error_code ret = 0;
194
195 p1 = p;
196 while (*p && *p != '=' && !isspace((unsigned char)*p))
197 ++p;
198 if (*p == '\0') {
199 *error_message = "missing =";
200 return KRB5_CONFIG_BADFORMAT;
201 }
202 p2 = p;
203 while (isspace((unsigned char)*p))
204 ++p;
205 if (*p != '=') {
206 *error_message = "missing =";
207 return KRB5_CONFIG_BADFORMAT;
208 }
209 ++p;
210 while(isspace((unsigned char)*p))
211 ++p;
212 *p2 = '\0';
213 if (*p == '{') {
214 tmp = get_entry(parent, p1, krb5_config_list);
215 if (tmp == NULL) {
216 *error_message = "out of memory";
217 return KRB5_CONFIG_BADFORMAT;
218 }
219 ret = parse_list (f, lineno, &tmp->u.list, error_message);
220 } else {
221 tmp = get_entry(parent, p1, krb5_config_string);
222 if (tmp == NULL) {
223 *error_message = "out of memory";
224 return KRB5_CONFIG_BADFORMAT;
225 }
226 p1 = p;
227 p = p1 + strlen(p1);
228 while(p > p1 && isspace((unsigned char)*(p-1)))
229 --p;
230 *p = '\0';
231 tmp->u.string = strdup(p1);
232 }
233 *b = tmp;
234 return ret;
235 }
236
237 /*
238 * Parse the config file `fname', generating the structures into `res'
239 * returning error messages in `error_message'
240 */
241
242 static krb5_error_code
243 krb5_config_parse_debug (struct fileptr *f,
/* [<][>][^][v][top][bottom][index][help] */
244 krb5_config_section **res,
245 unsigned *lineno,
246 const char **error_message)
247 {
248 krb5_config_section *s = NULL;
249 krb5_config_binding *b = NULL;
250 char buf[BUFSIZ];
251 krb5_error_code ret;
252
253 while (config_fgets(buf, sizeof(buf), f) != NULL) {
254 char *p;
255
256 ++*lineno;
257 buf[strcspn(buf, "\r\n")] = '\0';
258 p = buf;
259 while(isspace((unsigned char)*p))
260 ++p;
261 if (*p == '#' || *p == ';')
262 continue;
263 if (*p == '[') {
264 ret = parse_section(p, &s, res, error_message);
265 if (ret)
266 return ret;
267 b = NULL;
268 } else if (*p == '}') {
269 *error_message = "unmatched }";
270 return EINVAL; /* XXX */
271 } else if(*p != '\0') {
272 if (s == NULL) {
273 *error_message = "binding before section";
274 return EINVAL;
275 }
276 ret = parse_binding(f, lineno, p, &b, &s->u.list, error_message);
277 if (ret)
278 return ret;
279 }
280 }
281 return 0;
282 }
283
284 krb5_error_code KRB5_LIB_FUNCTION
285 krb5_config_parse_string_multi(krb5_context context,
/* [<][>][^][v][top][bottom][index][help] */
286 const char *string,
287 krb5_config_section **res)
288 {
289 const char *str;
290 unsigned lineno = 0;
291 krb5_error_code ret;
292 struct fileptr f;
293 f.f = NULL;
294 f.s = string;
295
296 ret = krb5_config_parse_debug (&f, res, &lineno, &str);
297 if (ret) {
298 krb5_set_error_message (context, ret, "%s:%u: %s",
299 "<constant>", lineno, str);
300 return ret;
301 }
302 return 0;
303 }
304
305 krb5_error_code KRB5_LIB_FUNCTION
306 krb5_config_parse_file_multi (krb5_context context,
/* [<][>][^][v][top][bottom][index][help] */
307 const char *fname,
308 krb5_config_section **res)
309 {
310 const char *str;
311 unsigned lineno = 0;
312 krb5_error_code ret;
313 struct fileptr f;
314 f.f = fopen(fname, "r");
315 f.s = NULL;
316 if(f.f == NULL) {
317 ret = errno;
318 krb5_set_error_message (context, ret, "open %s: %s",
319 fname, strerror(ret));
320 return ret;
321 }
322
323 ret = krb5_config_parse_debug (&f, res, &lineno, &str);
324 fclose(f.f);
325 if (ret) {
326 krb5_set_error_message (context, ret, "%s:%u: %s", fname, lineno, str);
327 return ret;
328 }
329 return 0;
330 }
331
332 krb5_error_code KRB5_LIB_FUNCTION
333 krb5_config_parse_file (krb5_context context,
/* [<][>][^][v][top][bottom][index][help] */
334 const char *fname,
335 krb5_config_section **res)
336 {
337 *res = NULL;
338 return krb5_config_parse_file_multi(context, fname, res);
339 }
340
341 #endif /* !HAVE_NETINFO */
342
343 static void
344 free_binding (krb5_context context, krb5_config_binding *b)
/* [<][>][^][v][top][bottom][index][help] */
345 {
346 krb5_config_binding *next_b;
347
348 while (b) {
349 free (b->name);
350 if (b->type == krb5_config_string)
351 free (b->u.string);
352 else if (b->type == krb5_config_list)
353 free_binding (context, b->u.list);
354 else
355 krb5_abortx(context, "unknown binding type (%d) in free_binding",
356 b->type);
357 next_b = b->next;
358 free (b);
359 b = next_b;
360 }
361 }
362
363 krb5_error_code KRB5_LIB_FUNCTION
364 krb5_config_file_free (krb5_context context, krb5_config_section *s)
/* [<][>][^][v][top][bottom][index][help] */
365 {
366 free_binding (context, s);
367 return 0;
368 }
369
370 krb5_error_code
371 _krb5_config_copy(krb5_context context,
/* [<][>][^][v][top][bottom][index][help] */
372 krb5_config_section *c,
373 krb5_config_section **head)
374 {
375 krb5_config_binding *d, *previous = NULL;
376
377 *head = NULL;
378
379 while (c) {
380 d = calloc(1, sizeof(*d));
381
382 if (*head == NULL)
383 *head = d;
384
385 d->name = strdup(c->name);
386 d->type = c->type;
387 if (d->type == krb5_config_string)
388 d->u.string = strdup(c->u.string);
389 else if (d->type == krb5_config_list)
390 _krb5_config_copy (context, c->u.list, &d->u.list);
391 else
392 krb5_abortx(context,
393 "unknown binding type (%d) in krb5_config_copy",
394 d->type);
395 if (previous)
396 previous->next = d;
397
398 previous = d;
399 c = c->next;
400 }
401 return 0;
402 }
403
404
405
406 const void *
407 krb5_config_get_next (krb5_context context,
/* [<][>][^][v][top][bottom][index][help] */
408 const krb5_config_section *c,
409 const krb5_config_binding **pointer,
410 int type,
411 ...)
412 {
413 const char *ret;
414 va_list args;
415
416 va_start(args, type);
417 ret = krb5_config_vget_next (context, c, pointer, type, args);
418 va_end(args);
419 return ret;
420 }
421
422 static const void *
423 vget_next(krb5_context context,
/* [<][>][^][v][top][bottom][index][help] */
424 const krb5_config_binding *b,
425 const krb5_config_binding **pointer,
426 int type,
427 const char *name,
428 va_list args)
429 {
430 const char *p = va_arg(args, const char *);
431 while(b != NULL) {
432 if(strcmp(b->name, name) == 0) {
433 if(b->type == type && p == NULL) {
434 *pointer = b;
435 return b->u.generic;
436 } else if(b->type == krb5_config_list && p != NULL) {
437 return vget_next(context, b->u.list, pointer, type, p, args);
438 }
439 }
440 b = b->next;
441 }
442 return NULL;
443 }
444
445 const void *
446 krb5_config_vget_next (krb5_context context,
/* [<][>][^][v][top][bottom][index][help] */
447 const krb5_config_section *c,
448 const krb5_config_binding **pointer,
449 int type,
450 va_list args)
451 {
452 const krb5_config_binding *b;
453 const char *p;
454
455 if(c == NULL)
456 c = context->cf;
457
458 if (c == NULL)
459 return NULL;
460
461 if (*pointer == NULL) {
462 /* first time here, walk down the tree looking for the right
463 section */
464 p = va_arg(args, const char *);
465 if (p == NULL)
466 return NULL;
467 return vget_next(context, c, pointer, type, p, args);
468 }
469
470 /* we were called again, so just look for more entries with the
471 same name and type */
472 for (b = (*pointer)->next; b != NULL; b = b->next) {
473 if(strcmp(b->name, (*pointer)->name) == 0 && b->type == type) {
474 *pointer = b;
475 return b->u.generic;
476 }
477 }
478 return NULL;
479 }
480
481 const void *
482 krb5_config_get (krb5_context context,
/* [<][>][^][v][top][bottom][index][help] */
483 const krb5_config_section *c,
484 int type,
485 ...)
486 {
487 const void *ret;
488 va_list args;
489
490 va_start(args, type);
491 ret = krb5_config_vget (context, c, type, args);
492 va_end(args);
493 return ret;
494 }
495
496 const void *
497 krb5_config_vget (krb5_context context,
/* [<][>][^][v][top][bottom][index][help] */
498 const krb5_config_section *c,
499 int type,
500 va_list args)
501 {
502 const krb5_config_binding *foo = NULL;
503
504 return krb5_config_vget_next (context, c, &foo, type, args);
505 }
506
507 const krb5_config_binding *
508 krb5_config_get_list (krb5_context context,
/* [<][>][^][v][top][bottom][index][help] */
509 const krb5_config_section *c,
510 ...)
511 {
512 const krb5_config_binding *ret;
513 va_list args;
514
515 va_start(args, c);
516 ret = krb5_config_vget_list (context, c, args);
517 va_end(args);
518 return ret;
519 }
520
521 const krb5_config_binding *
522 krb5_config_vget_list (krb5_context context,
/* [<][>][^][v][top][bottom][index][help] */
523 const krb5_config_section *c,
524 va_list args)
525 {
526 return krb5_config_vget (context, c, krb5_config_list, args);
527 }
528
529 const char* KRB5_LIB_FUNCTION
530 krb5_config_get_string (krb5_context context,
/* [<][>][^][v][top][bottom][index][help] */
531 const krb5_config_section *c,
532 ...)
533 {
534 const char *ret;
535 va_list args;
536
537 va_start(args, c);
538 ret = krb5_config_vget_string (context, c, args);
539 va_end(args);
540 return ret;
541 }
542
543 const char* KRB5_LIB_FUNCTION
544 krb5_config_vget_string (krb5_context context,
/* [<][>][^][v][top][bottom][index][help] */
545 const krb5_config_section *c,
546 va_list args)
547 {
548 return krb5_config_vget (context, c, krb5_config_string, args);
549 }
550
551 const char* KRB5_LIB_FUNCTION
552 krb5_config_vget_string_default (krb5_context context,
/* [<][>][^][v][top][bottom][index][help] */
553 const krb5_config_section *c,
554 const char *def_value,
555 va_list args)
556 {
557 const char *ret;
558
559 ret = krb5_config_vget_string (context, c, args);
560 if (ret == NULL)
561 ret = def_value;
562 return ret;
563 }
564
565 const char* KRB5_LIB_FUNCTION
566 krb5_config_get_string_default (krb5_context context,
/* [<][>][^][v][top][bottom][index][help] */
567 const krb5_config_section *c,
568 const char *def_value,
569 ...)
570 {
571 const char *ret;
572 va_list args;
573
574 va_start(args, def_value);
575 ret = krb5_config_vget_string_default (context, c, def_value, args);
576 va_end(args);
577 return ret;
578 }
579
580 char ** KRB5_LIB_FUNCTION
581 krb5_config_vget_strings(krb5_context context,
/* [<][>][^][v][top][bottom][index][help] */
582 const krb5_config_section *c,
583 va_list args)
584 {
585 char **strings = NULL;
586 int nstr = 0;
587 const krb5_config_binding *b = NULL;
588 const char *p;
589
590 while((p = krb5_config_vget_next(context, c, &b,
591 krb5_config_string, args))) {
592 char *tmp = strdup(p);
593 char *pos = NULL;
594 char *s;
595 if(tmp == NULL)
596 goto cleanup;
597 s = strtok_r(tmp, " \t", &pos);
598 while(s){
599 char **tmp2 = realloc(strings, (nstr + 1) * sizeof(*strings));
600 if(tmp2 == NULL)
601 goto cleanup;
602 strings = tmp2;
603 strings[nstr] = strdup(s);
604 nstr++;
605 if(strings[nstr-1] == NULL)
606 goto cleanup;
607 s = strtok_r(NULL, " \t", &pos);
608 }
609 free(tmp);
610 }
611 if(nstr){
612 char **tmp = realloc(strings, (nstr + 1) * sizeof(*strings));
613 if(tmp == NULL)
614 goto cleanup;
615 strings = tmp;
616 strings[nstr] = NULL;
617 }
618 return strings;
619 cleanup:
620 while(nstr--)
621 free(strings[nstr]);
622 free(strings);
623 return NULL;
624
625 }
626
627 char**
628 krb5_config_get_strings(krb5_context context,
/* [<][>][^][v][top][bottom][index][help] */
629 const krb5_config_section *c,
630 ...)
631 {
632 va_list ap;
633 char **ret;
634 va_start(ap, c);
635 ret = krb5_config_vget_strings(context, c, ap);
636 va_end(ap);
637 return ret;
638 }
639
640 void KRB5_LIB_FUNCTION
641 krb5_config_free_strings(char **strings)
/* [<][>][^][v][top][bottom][index][help] */
642 {
643 char **s = strings;
644 while(s && *s){
645 free(*s);
646 s++;
647 }
648 free(strings);
649 }
650
651 krb5_boolean KRB5_LIB_FUNCTION
652 krb5_config_vget_bool_default (krb5_context context,
/* [<][>][^][v][top][bottom][index][help] */
653 const krb5_config_section *c,
654 krb5_boolean def_value,
655 va_list args)
656 {
657 const char *str;
658 str = krb5_config_vget_string (context, c, args);
659 if(str == NULL)
660 return def_value;
661 if(strcasecmp(str, "yes") == 0 ||
662 strcasecmp(str, "true") == 0 ||
663 atoi(str)) return TRUE;
664 return FALSE;
665 }
666
667 krb5_boolean KRB5_LIB_FUNCTION
668 krb5_config_vget_bool (krb5_context context,
/* [<][>][^][v][top][bottom][index][help] */
669 const krb5_config_section *c,
670 va_list args)
671 {
672 return krb5_config_vget_bool_default (context, c, FALSE, args);
673 }
674
675 krb5_boolean KRB5_LIB_FUNCTION
676 krb5_config_get_bool_default (krb5_context context,
/* [<][>][^][v][top][bottom][index][help] */
677 const krb5_config_section *c,
678 krb5_boolean def_value,
679 ...)
680 {
681 va_list ap;
682 krb5_boolean ret;
683 va_start(ap, def_value);
684 ret = krb5_config_vget_bool_default(context, c, def_value, ap);
685 va_end(ap);
686 return ret;
687 }
688
689 krb5_boolean KRB5_LIB_FUNCTION
690 krb5_config_get_bool (krb5_context context,
/* [<][>][^][v][top][bottom][index][help] */
691 const krb5_config_section *c,
692 ...)
693 {
694 va_list ap;
695 krb5_boolean ret;
696 va_start(ap, c);
697 ret = krb5_config_vget_bool (context, c, ap);
698 va_end(ap);
699 return ret;
700 }
701
702 int KRB5_LIB_FUNCTION
703 krb5_config_vget_time_default (krb5_context context,
/* [<][>][^][v][top][bottom][index][help] */
704 const krb5_config_section *c,
705 int def_value,
706 va_list args)
707 {
708 const char *str;
709 krb5_deltat t;
710
711 str = krb5_config_vget_string (context, c, args);
712 if(str == NULL)
713 return def_value;
714 if (krb5_string_to_deltat(str, &t))
715 return def_value;
716 return t;
717 }
718
719 int KRB5_LIB_FUNCTION
720 krb5_config_vget_time (krb5_context context,
/* [<][>][^][v][top][bottom][index][help] */
721 const krb5_config_section *c,
722 va_list args)
723 {
724 return krb5_config_vget_time_default (context, c, -1, args);
725 }
726
727 int KRB5_LIB_FUNCTION
728 krb5_config_get_time_default (krb5_context context,
/* [<][>][^][v][top][bottom][index][help] */
729 const krb5_config_section *c,
730 int def_value,
731 ...)
732 {
733 va_list ap;
734 int ret;
735 va_start(ap, def_value);
736 ret = krb5_config_vget_time_default(context, c, def_value, ap);
737 va_end(ap);
738 return ret;
739 }
740
741 int KRB5_LIB_FUNCTION
742 krb5_config_get_time (krb5_context context,
/* [<][>][^][v][top][bottom][index][help] */
743 const krb5_config_section *c,
744 ...)
745 {
746 va_list ap;
747 int ret;
748 va_start(ap, c);
749 ret = krb5_config_vget_time (context, c, ap);
750 va_end(ap);
751 return ret;
752 }
753
754
755 int KRB5_LIB_FUNCTION
756 krb5_config_vget_int_default (krb5_context context,
/* [<][>][^][v][top][bottom][index][help] */
757 const krb5_config_section *c,
758 int def_value,
759 va_list args)
760 {
761 const char *str;
762 str = krb5_config_vget_string (context, c, args);
763 if(str == NULL)
764 return def_value;
765 else {
766 char *endptr;
767 long l;
768 l = strtol(str, &endptr, 0);
769 if (endptr == str)
770 return def_value;
771 else
772 return l;
773 }
774 }
775
776 int KRB5_LIB_FUNCTION
777 krb5_config_vget_int (krb5_context context,
/* [<][>][^][v][top][bottom][index][help] */
778 const krb5_config_section *c,
779 va_list args)
780 {
781 return krb5_config_vget_int_default (context, c, -1, args);
782 }
783
784 int KRB5_LIB_FUNCTION
785 krb5_config_get_int_default (krb5_context context,
/* [<][>][^][v][top][bottom][index][help] */
786 const krb5_config_section *c,
787 int def_value,
788 ...)
789 {
790 va_list ap;
791 int ret;
792 va_start(ap, def_value);
793 ret = krb5_config_vget_int_default(context, c, def_value, ap);
794 va_end(ap);
795 return ret;
796 }
797
798 int KRB5_LIB_FUNCTION
799 krb5_config_get_int (krb5_context context,
/* [<][>][^][v][top][bottom][index][help] */
800 const krb5_config_section *c,
801 ...)
802 {
803 va_list ap;
804 int ret;
805 va_start(ap, c);
806 ret = krb5_config_vget_int (context, c, ap);
807 va_end(ap);
808 return ret;
809 }