ldb: Release ldb 2.2.1
[Samba.git] / ctdb / common / conf.c
blobe849ff4322f59ad91cde31c230a2bb856d6fec8f
1 /*
2 Configuration file handling on top of tini
4 Copyright (C) Amitay Isaacs 2017
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, see <http://www.gnu.org/licenses/>.
20 #include "replace.h"
21 #include "system/locale.h"
23 #include <talloc.h>
25 #include "lib/util/dlinklist.h"
26 #include "lib/util/tini.h"
27 #include "lib/util/debug.h"
29 #include "common/conf.h"
31 struct conf_value {
32 enum conf_type type;
33 union {
34 const char *string;
35 int integer;
36 bool boolean;
37 } data;
40 union conf_pointer {
41 const char **string;
42 int *integer;
43 bool *boolean;
46 struct conf_option {
47 struct conf_option *prev, *next;
49 const char *name;
50 enum conf_type type;
51 void *validate;
53 struct conf_value default_value;
54 bool default_set;
56 struct conf_value *value, *new_value;
57 union conf_pointer ptr;
58 bool temporary_modified;
61 struct conf_section {
62 struct conf_section *prev, *next;
64 const char *name;
65 conf_validate_section_fn validate;
66 struct conf_option *option;
69 struct conf_context {
70 const char *filename;
71 struct conf_section *section;
72 bool define_failed;
73 bool ignore_unknown;
74 bool reload;
75 bool validation_active;
79 * Functions related to conf_value
82 static int string_to_string(TALLOC_CTX *mem_ctx,
83 const char *str,
84 const char **str_val)
86 char *t;
88 if (str == NULL) {
89 return EINVAL;
92 t = talloc_strdup(mem_ctx, str);
93 if (t == NULL) {
94 return ENOMEM;
97 *str_val = t;
98 return 0;
101 static int string_to_integer(const char *str, int *int_val)
103 long t;
104 char *endptr = NULL;
106 if (str == NULL) {
107 return EINVAL;
110 t = strtol(str, &endptr, 0);
111 if (*str != '\0' || endptr == NULL) {
112 if (t < 0 || t > INT_MAX) {
113 return EINVAL;
116 *int_val = (int)t;
117 return 0;
120 return EINVAL;
123 static int string_to_boolean(const char *str, bool *bool_val)
125 if (strcasecmp(str, "true") == 0 || strcasecmp(str, "yes") == 0) {
126 *bool_val = true;
127 return 0;
130 if (strcasecmp(str, "false") == 0 || strcasecmp(str, "no") == 0) {
131 *bool_val = false;
132 return 0;
135 return EINVAL;
138 static int conf_value_from_string(TALLOC_CTX *mem_ctx,
139 const char *str,
140 struct conf_value *value)
142 int ret;
144 switch (value->type) {
145 case CONF_STRING:
146 ret = string_to_string(mem_ctx, str, &value->data.string);
147 break;
149 case CONF_INTEGER:
150 ret = string_to_integer(str, &value->data.integer);
151 break;
153 case CONF_BOOLEAN:
154 ret = string_to_boolean(str, &value->data.boolean);
155 break;
157 default:
158 return EINVAL;
161 return ret;
164 static bool conf_value_compare(struct conf_value *old, struct conf_value *new)
166 if (old == NULL || new == NULL) {
167 return false;
170 if (old->type != new->type) {
171 return false;
174 switch (old->type) {
175 case CONF_STRING:
176 if (old->data.string == NULL && new->data.string == NULL) {
177 return true;
179 if (old->data.string != NULL && new->data.string != NULL) {
180 if (strcmp(old->data.string, new->data.string) == 0) {
181 return true;
184 break;
186 case CONF_INTEGER:
187 if (old->data.integer == new->data.integer) {
188 return true;
190 break;
192 case CONF_BOOLEAN:
193 if (old->data.boolean == new->data.boolean) {
194 return true;
196 break;
199 return false;
202 static int conf_value_copy(TALLOC_CTX *mem_ctx,
203 struct conf_value *src,
204 struct conf_value *dst)
206 if (src->type != dst->type) {
207 return EINVAL;
210 switch (src->type) {
211 case CONF_STRING:
212 if (dst->data.string != NULL) {
213 talloc_free(discard_const(dst->data.string));
215 if (src->data.string == NULL) {
216 dst->data.string = NULL;
217 } else {
218 dst->data.string = talloc_strdup(
219 mem_ctx, src->data.string);
220 if (dst->data.string == NULL) {
221 return ENOMEM;
224 break;
226 case CONF_INTEGER:
227 dst->data.integer = src->data.integer;
228 break;
230 case CONF_BOOLEAN:
231 dst->data.boolean = src->data.boolean;
232 break;
234 default:
235 return EINVAL;
238 return 0;
241 static void conf_value_dump(const char *key,
242 struct conf_value *value,
243 bool is_default,
244 bool is_temporary,
245 FILE *fp)
247 if ((value->type == CONF_STRING && value->data.string == NULL) ||
248 is_default) {
249 fprintf(fp, "\t# %s = ", key);
250 } else {
251 fprintf(fp, "\t%s = ", key);
254 switch (value->type) {
255 case CONF_STRING:
256 if (value->data.string != NULL) {
257 fprintf(fp, "%s", value->data.string);
259 break;
261 case CONF_INTEGER:
262 fprintf(fp, "%d", value->data.integer);
263 break;
265 case CONF_BOOLEAN:
266 fprintf(fp, "%s", (value->data.boolean ? "true" : "false"));
267 break;
270 if (is_temporary) {
271 fprintf(fp, " # temporary");
274 fprintf(fp, "\n");
278 * Functions related to conf_option
281 static struct conf_option *conf_option_find(struct conf_section *s,
282 const char *key)
284 struct conf_option *opt;
286 for (opt = s->option; opt != NULL; opt = opt->next) {
287 if (strcmp(opt->name, key) == 0) {
288 return opt;
292 return NULL;
295 static void conf_option_set_ptr_value(struct conf_option *opt)
297 switch (opt->type) {
298 case CONF_STRING:
299 if (opt->ptr.string != NULL) {
300 *(opt->ptr.string) = opt->value->data.string;
302 break;
304 case CONF_INTEGER:
305 if (opt->ptr.integer != NULL) {
306 *(opt->ptr.integer) = opt->value->data.integer;
308 break;
310 case CONF_BOOLEAN:
311 if (opt->ptr.boolean != NULL) {
312 *(opt->ptr.boolean) = opt->value->data.boolean;
314 break;
318 static void conf_option_default(struct conf_option *opt);
320 static int conf_option_add(struct conf_section *s,
321 const char *key,
322 enum conf_type type,
323 void *validate,
324 struct conf_option **popt)
326 struct conf_option *opt;
328 opt = conf_option_find(s, key);
329 if (opt != NULL) {
330 D_ERR("conf: option \"%s\" already exists\n", key);
331 return EEXIST;
334 opt = talloc_zero(s, struct conf_option);
335 if (opt == NULL) {
336 return ENOMEM;
339 opt->name = talloc_strdup(opt, key);
340 if (opt->name == NULL) {
341 talloc_free(opt);
342 return ENOMEM;
345 opt->type = type;
346 opt->validate = validate;
348 DLIST_ADD_END(s->option, opt);
350 if (popt != NULL) {
351 *popt = opt;
354 return 0;
357 static int conf_option_set_default(struct conf_option *opt,
358 struct conf_value *default_value)
360 int ret;
362 opt->default_value.type = opt->type;
364 ret = conf_value_copy(opt, default_value, &opt->default_value);
365 if (ret != 0) {
366 return ret;
369 opt->default_set = true;
370 opt->temporary_modified = false;
372 return 0;
375 static void conf_option_set_ptr(struct conf_option *opt,
376 union conf_pointer *ptr)
378 opt->ptr = *ptr;
381 static bool conf_option_validate_string(struct conf_option *opt,
382 struct conf_value *value,
383 enum conf_update_mode mode)
385 conf_validate_string_option_fn validate =
386 (conf_validate_string_option_fn)opt->validate;
388 return validate(opt->name,
389 opt->value->data.string,
390 value->data.string,
391 mode);
394 static bool conf_option_validate_integer(struct conf_option *opt,
395 struct conf_value *value,
396 enum conf_update_mode mode)
398 conf_validate_integer_option_fn validate =
399 (conf_validate_integer_option_fn)opt->validate;
401 return validate(opt->name,
402 opt->value->data.integer,
403 value->data.integer,
404 mode);
407 static bool conf_option_validate_boolean(struct conf_option *opt,
408 struct conf_value *value,
409 enum conf_update_mode mode)
411 conf_validate_boolean_option_fn validate =
412 (conf_validate_boolean_option_fn)opt->validate;
414 return validate(opt->name,
415 opt->value->data.boolean,
416 value->data.boolean,
417 mode);
420 static bool conf_option_validate(struct conf_option *opt,
421 struct conf_value *value,
422 enum conf_update_mode mode)
424 int ret;
426 if (opt->validate == NULL) {
427 return true;
430 switch (opt->type) {
431 case CONF_STRING:
432 ret = conf_option_validate_string(opt, value, mode);
433 break;
435 case CONF_INTEGER:
436 ret = conf_option_validate_integer(opt, value, mode);
437 break;
439 case CONF_BOOLEAN:
440 ret = conf_option_validate_boolean(opt, value, mode);
441 break;
443 default:
444 ret = EINVAL;
447 return ret;
450 static bool conf_option_same_value(struct conf_option *opt,
451 struct conf_value *new_value)
453 return conf_value_compare(opt->value, new_value);
456 static int conf_option_new_value(struct conf_option *opt,
457 struct conf_value *new_value,
458 enum conf_update_mode mode)
460 int ret;
461 bool ok;
463 if (opt->new_value != &opt->default_value) {
464 TALLOC_FREE(opt->new_value);
467 if (new_value == &opt->default_value) {
469 * This happens only during load/reload. Set the value to
470 * default value, so if the config option is dropped from
471 * config file, then it get's reset to default.
473 opt->new_value = &opt->default_value;
474 } else {
475 ok = conf_option_validate(opt, new_value, mode);
476 if (!ok) {
477 D_ERR("conf: validation for option \"%s\" failed\n",
478 opt->name);
479 return EINVAL;
482 opt->new_value = talloc_zero(opt, struct conf_value);
483 if (opt->new_value == NULL) {
484 return ENOMEM;
487 opt->new_value->type = opt->value->type;
488 ret = conf_value_copy(opt, new_value, opt->new_value);
489 if (ret != 0) {
490 return ret;
494 conf_option_set_ptr_value(opt);
496 if (new_value != &opt->default_value) {
497 if (mode == CONF_MODE_API) {
498 opt->temporary_modified = true;
499 } else {
500 opt->temporary_modified = false;
504 return 0;
507 static int conf_option_new_default_value(struct conf_option *opt,
508 enum conf_update_mode mode)
510 return conf_option_new_value(opt, &opt->default_value, mode);
513 static void conf_option_default(struct conf_option *opt)
515 if (! opt->default_set) {
516 return;
519 if (opt->value != &opt->default_value) {
520 TALLOC_FREE(opt->value);
523 opt->value = &opt->default_value;
524 conf_option_set_ptr_value(opt);
527 static void conf_option_reset(struct conf_option *opt)
529 if (opt->new_value != &opt->default_value) {
530 TALLOC_FREE(opt->new_value);
533 conf_option_set_ptr_value(opt);
536 static void conf_option_update(struct conf_option *opt)
538 if (opt->new_value == NULL) {
539 return;
542 if (opt->value != &opt->default_value) {
543 TALLOC_FREE(opt->value);
546 opt->value = opt->new_value;
547 opt->new_value = NULL;
549 conf_option_set_ptr_value(opt);
552 static void conf_option_reset_temporary(struct conf_option *opt)
554 opt->temporary_modified = false;
557 static bool conf_option_is_default(struct conf_option *opt)
559 return (opt->value == &opt->default_value);
562 static void conf_option_dump(struct conf_option *opt, FILE *fp)
564 bool is_default;
566 is_default = conf_option_is_default(opt);
568 conf_value_dump(opt->name,
569 opt->value,
570 is_default,
571 opt->temporary_modified,
572 fp);
576 * Functions related to conf_section
579 static struct conf_section *conf_section_find(struct conf_context *conf,
580 const char *section)
582 struct conf_section *s;
584 for (s = conf->section; s != NULL; s = s->next) {
585 if (strcasecmp(s->name, section) == 0) {
586 return s;
590 return NULL;
593 static int conf_section_add(struct conf_context *conf,
594 const char *section,
595 conf_validate_section_fn validate)
597 struct conf_section *s;
599 s = conf_section_find(conf, section);
600 if (s != NULL) {
601 return EEXIST;
604 s = talloc_zero(conf, struct conf_section);
605 if (s == NULL) {
606 return ENOMEM;
609 s->name = talloc_strdup(s, section);
610 if (s->name == NULL) {
611 talloc_free(s);
612 return ENOMEM;
615 s->validate = validate;
617 DLIST_ADD_END(conf->section, s);
618 return 0;
621 static bool conf_section_validate(struct conf_context *conf,
622 struct conf_section *s,
623 enum conf_update_mode mode)
625 bool ok;
627 if (s->validate == NULL) {
628 return true;
631 ok = s->validate(conf, s->name, mode);
632 if (!ok) {
633 D_ERR("conf: validation for section [%s] failed\n", s->name);
636 return ok;
639 static void conf_section_dump(struct conf_section *s, FILE *fp)
641 fprintf(fp, "[%s]\n", s->name);
645 * Functions related to conf_context
648 static void conf_all_default(struct conf_context *conf)
650 struct conf_section *s;
651 struct conf_option *opt;
653 for (s = conf->section; s != NULL; s = s->next) {
654 for (opt = s->option; opt != NULL; opt = opt->next) {
655 conf_option_default(opt);
660 static int conf_all_temporary_default(struct conf_context *conf,
661 enum conf_update_mode mode)
663 struct conf_section *s;
664 struct conf_option *opt;
665 int ret;
667 for (s = conf->section; s != NULL; s = s->next) {
668 for (opt = s->option; opt != NULL; opt = opt->next) {
669 ret = conf_option_new_default_value(opt, mode);
670 if (ret != 0) {
671 return ret;
676 return 0;
679 static void conf_all_reset(struct conf_context *conf)
681 struct conf_section *s;
682 struct conf_option *opt;
684 for (s = conf->section; s != NULL; s = s->next) {
685 for (opt = s->option; opt != NULL; opt = opt->next) {
686 conf_option_reset(opt);
691 static void conf_all_update(struct conf_context *conf)
693 struct conf_section *s;
694 struct conf_option *opt;
696 for (s = conf->section; s != NULL; s = s->next) {
697 for (opt = s->option; opt != NULL; opt = opt->next) {
698 conf_option_update(opt);
699 conf_option_reset_temporary(opt);
705 * API functions
708 int conf_init(TALLOC_CTX *mem_ctx, struct conf_context **result)
710 struct conf_context *conf;
712 conf = talloc_zero(mem_ctx, struct conf_context);
713 if (conf == NULL) {
714 return ENOMEM;
717 conf->define_failed = false;
719 *result = conf;
720 return 0;
723 void conf_define_section(struct conf_context *conf,
724 const char *section,
725 conf_validate_section_fn validate)
727 int ret;
729 if (conf->define_failed) {
730 return;
733 if (section == NULL) {
734 conf->define_failed = true;
735 return;
738 ret = conf_section_add(conf, section, validate);
739 if (ret != 0) {
740 conf->define_failed = true;
741 return;
745 static struct conf_option *conf_define(struct conf_context *conf,
746 const char *section,
747 const char *key,
748 enum conf_type type,
749 conf_validate_string_option_fn validate)
751 struct conf_section *s;
752 struct conf_option *opt;
753 int ret;
755 s = conf_section_find(conf, section);
756 if (s == NULL) {
757 D_ERR("conf: unknown section [%s]\n", section);
758 return NULL;
761 if (key == NULL) {
762 D_ERR("conf: option name null in section [%s]\n", section);
763 return NULL;
766 ret = conf_option_add(s, key, type, validate, &opt);
767 if (ret != 0) {
768 return NULL;
771 return opt;
774 static void conf_define_post(struct conf_context *conf,
775 struct conf_option *opt,
776 struct conf_value *default_value)
778 int ret;
780 ret = conf_option_set_default(opt, default_value);
781 if (ret != 0) {
782 conf->define_failed = true;
783 return;
786 conf_option_default(opt);
789 void conf_define_string(struct conf_context *conf,
790 const char *section,
791 const char *key,
792 const char *default_str_val,
793 conf_validate_string_option_fn validate)
795 struct conf_option *opt;
796 struct conf_value default_value;
798 if (! conf_valid(conf)) {
799 return;
802 opt = conf_define(conf, section, key, CONF_STRING, validate);
803 if (opt == NULL) {
804 conf->define_failed = true;
805 return;
808 default_value.type = CONF_STRING;
809 default_value.data.string = default_str_val;
811 conf_define_post(conf, opt, &default_value);
814 void conf_define_integer(struct conf_context *conf,
815 const char *section,
816 const char *key,
817 const int default_int_val,
818 conf_validate_integer_option_fn validate)
820 struct conf_option *opt;
821 struct conf_value default_value;
823 if (! conf_valid(conf)) {
824 return;
827 opt = conf_define(conf, section, key, CONF_INTEGER, (void *)validate);
828 if (opt == NULL) {
829 conf->define_failed = true;
830 return;
833 default_value.type = CONF_INTEGER;
834 default_value.data.integer = default_int_val;
836 conf_define_post(conf, opt, &default_value);
840 void conf_define_boolean(struct conf_context *conf,
841 const char *section,
842 const char *key,
843 const bool default_bool_val,
844 conf_validate_boolean_option_fn validate)
846 struct conf_option *opt;
847 struct conf_value default_value;
849 if (! conf_valid(conf)) {
850 return;
853 opt = conf_define(conf, section, key, CONF_BOOLEAN, (void *)validate);
854 if (opt == NULL) {
855 conf->define_failed = true;
856 return;
859 default_value.type = CONF_BOOLEAN;
860 default_value.data.boolean = default_bool_val;
862 conf_define_post(conf, opt, &default_value);
865 static struct conf_option *_conf_option(struct conf_context *conf,
866 const char *section,
867 const char *key)
869 struct conf_section *s;
870 struct conf_option *opt;
872 s = conf_section_find(conf, section);
873 if (s == NULL) {
874 return NULL;
877 opt = conf_option_find(s, key);
878 return opt;
881 void conf_assign_string_pointer(struct conf_context *conf,
882 const char *section,
883 const char *key,
884 const char **str_ptr)
886 struct conf_option *opt;
887 union conf_pointer ptr;
889 opt = _conf_option(conf, section, key);
890 if (opt == NULL) {
891 D_ERR("conf: unknown option [%s] -> \"%s\"\n", section, key);
892 conf->define_failed = true;
893 return;
896 if (opt->type != CONF_STRING) {
897 conf->define_failed = true;
898 return;
901 ptr.string = str_ptr;
902 conf_option_set_ptr(opt, &ptr);
903 conf_option_set_ptr_value(opt);
906 void conf_assign_integer_pointer(struct conf_context *conf,
907 const char *section,
908 const char *key,
909 int *int_ptr)
911 struct conf_option *opt;
912 union conf_pointer ptr;
914 opt = _conf_option(conf, section, key);
915 if (opt == NULL) {
916 D_ERR("conf: unknown option [%s] -> \"%s\"\n", section, key);
917 conf->define_failed = true;
918 return;
921 if (opt->type != CONF_INTEGER) {
922 conf->define_failed = true;
923 return;
926 ptr.integer = int_ptr;
927 conf_option_set_ptr(opt, &ptr);
928 conf_option_set_ptr_value(opt);
931 void conf_assign_boolean_pointer(struct conf_context *conf,
932 const char *section,
933 const char *key,
934 bool *bool_ptr)
936 struct conf_option *opt;
937 union conf_pointer ptr;
939 opt = _conf_option(conf, section, key);
940 if (opt == NULL) {
941 D_ERR("conf: unknown option [%s] -> \"%s\"\n", section, key);
942 conf->define_failed = true;
943 return;
946 if (opt->type != CONF_BOOLEAN) {
947 conf->define_failed = true;
948 return;
951 ptr.boolean = bool_ptr;
952 conf_option_set_ptr(opt, &ptr);
953 conf_option_set_ptr_value(opt);
956 bool conf_query(struct conf_context *conf,
957 const char *section,
958 const char *key,
959 enum conf_type *type)
961 struct conf_section *s;
962 struct conf_option *opt;
964 if (! conf_valid(conf)) {
965 return false;
968 s = conf_section_find(conf, section);
969 if (s == NULL) {
970 return false;
973 opt = conf_option_find(s, key);
974 if (opt == NULL) {
975 return false;
978 if (type != NULL) {
979 *type = opt->type;
981 return true;
984 bool conf_valid(struct conf_context *conf)
986 if (conf->define_failed) {
987 return false;
990 return true;
993 void conf_set_defaults(struct conf_context *conf)
995 conf_all_default(conf);
998 struct conf_load_state {
999 struct conf_context *conf;
1000 struct conf_section *s;
1001 enum conf_update_mode mode;
1002 int err;
1005 static bool conf_load_section(const char *section, void *private_data);
1006 static bool conf_load_option(const char *name,
1007 const char *value_str,
1008 void *private_data);
1010 static int conf_load_internal(struct conf_context *conf)
1012 struct conf_load_state state;
1013 FILE *fp;
1014 int ret;
1015 bool ok;
1017 state = (struct conf_load_state) {
1018 .conf = conf,
1019 .mode = (conf->reload ? CONF_MODE_RELOAD : CONF_MODE_LOAD),
1022 ret = conf_all_temporary_default(conf, state.mode);
1023 if (ret != 0) {
1024 return ret;
1027 fp = fopen(conf->filename, "r");
1028 if (fp == NULL) {
1029 return errno;
1032 ok = tini_parse(fp,
1033 false,
1034 conf_load_section,
1035 conf_load_option,
1036 &state);
1037 fclose(fp);
1038 if (!ok) {
1039 goto fail;
1042 /* Process the last section */
1043 if (state.s != NULL) {
1044 ok = conf_section_validate(conf, state.s, state.mode);
1045 if (!ok) {
1046 state.err = EINVAL;
1047 goto fail;
1051 if (state.err != 0) {
1052 goto fail;
1055 conf_all_update(conf);
1056 return 0;
1058 fail:
1059 conf_all_reset(conf);
1060 return state.err;
1063 static bool conf_load_section(const char *section, void *private_data)
1065 struct conf_load_state *state =
1066 (struct conf_load_state *)private_data;
1067 bool ok;
1069 if (state->s != NULL) {
1070 ok = conf_section_validate(state->conf, state->s, state->mode);
1071 if (!ok) {
1072 state->err = EINVAL;
1073 return true;
1077 state->s = conf_section_find(state->conf, section);
1078 if (state->s == NULL) {
1079 if (state->conf->ignore_unknown) {
1080 D_DEBUG("conf: ignoring unknown section [%s]\n",
1081 section);
1082 } else {
1083 D_ERR("conf: unknown section [%s]\n", section);
1084 state->err = EINVAL;
1085 return true;
1089 return true;
1092 static bool conf_load_option(const char *name,
1093 const char *value_str,
1094 void *private_data)
1096 struct conf_load_state *state =
1097 (struct conf_load_state *)private_data;
1098 struct conf_option *opt;
1099 TALLOC_CTX *tmp_ctx;
1100 struct conf_value value;
1101 int ret;
1102 bool ok;
1104 if (state->s == NULL) {
1105 if (state->conf->ignore_unknown) {
1106 D_DEBUG("conf: unknown section for option \"%s\"\n",
1107 name);
1108 return true;
1109 } else {
1110 D_ERR("conf: unknown section for option \"%s\"\n",
1111 name);
1112 state->err = EINVAL;
1113 return true;
1117 opt = conf_option_find(state->s, name);
1118 if (opt == NULL) {
1119 if (state->conf->ignore_unknown) {
1120 D_DEBUG("conf: unknown option [%s] -> \"%s\"\n",
1121 state->s->name,
1122 name);
1123 return true;
1124 } else {
1125 D_ERR("conf: unknown option [%s] -> \"%s\"\n",
1126 state->s->name,
1127 name);
1128 state->err = EINVAL;
1129 return true;
1133 if (strlen(value_str) == 0) {
1134 D_ERR("conf: empty value [%s] -> \"%s\"\n",
1135 state->s->name,
1136 name);
1137 state->err = EINVAL;
1138 return true;
1141 tmp_ctx = talloc_new(state->conf);
1142 if (tmp_ctx == NULL) {
1143 state->err = ENOMEM;
1144 return false;
1147 value.type = opt->type;
1148 ret = conf_value_from_string(tmp_ctx, value_str, &value);
1149 if (ret != 0) {
1150 D_ERR("conf: invalid value [%s] -> \"%s\" = \"%s\"\n",
1151 state->s->name,
1152 name,
1153 value_str);
1154 talloc_free(tmp_ctx);
1155 state->err = ret;
1156 return true;
1159 ok = conf_option_same_value(opt, &value);
1160 if (ok) {
1161 goto done;
1164 ret = conf_option_new_value(opt, &value, state->mode);
1165 if (ret != 0) {
1166 talloc_free(tmp_ctx);
1167 state->err = ret;
1168 return true;
1171 done:
1172 talloc_free(tmp_ctx);
1173 return true;
1177 int conf_load(struct conf_context *conf,
1178 const char *filename,
1179 bool ignore_unknown)
1181 conf->filename = talloc_strdup(conf, filename);
1182 if (conf->filename == NULL) {
1183 return ENOMEM;
1186 conf->ignore_unknown = ignore_unknown;
1188 D_NOTICE("Reading config file %s\n", filename);
1190 return conf_load_internal(conf);
1193 int conf_reload(struct conf_context *conf)
1195 int ret;
1197 if (conf->filename == NULL) {
1198 return EPERM;
1201 D_NOTICE("Re-reading config file %s\n", conf->filename);
1203 conf->reload = true;
1204 ret = conf_load_internal(conf);
1205 conf->reload = false;
1207 return ret;
1210 static int conf_set(struct conf_context *conf,
1211 const char *section,
1212 const char *key,
1213 struct conf_value *value)
1215 struct conf_section *s;
1216 struct conf_option *opt;
1217 int ret;
1218 bool ok;
1220 s = conf_section_find(conf, section);
1221 if (s == NULL) {
1222 return EINVAL;
1225 opt = conf_option_find(s, key);
1226 if (opt == NULL) {
1227 return EINVAL;
1230 if (opt->type != value->type) {
1231 return EINVAL;
1234 ok = conf_option_same_value(opt, value);
1235 if (ok) {
1236 return 0;
1239 ret = conf_option_new_value(opt, value, CONF_MODE_API);
1240 if (ret != 0) {
1241 conf_option_reset(opt);
1242 return ret;
1245 ok = conf_section_validate(conf, s, CONF_MODE_API);
1246 if (!ok) {
1247 conf_option_reset(opt);
1248 return EINVAL;
1251 conf_option_update(opt);
1252 return 0;
1255 int conf_set_string(struct conf_context *conf,
1256 const char *section,
1257 const char *key,
1258 const char *str_val)
1260 struct conf_value value;
1262 value.type = CONF_STRING;
1263 value.data.string = str_val;
1265 return conf_set(conf, section, key, &value);
1268 int conf_set_integer(struct conf_context *conf,
1269 const char *section,
1270 const char *key,
1271 int int_val)
1273 struct conf_value value;
1275 value.type = CONF_INTEGER;
1276 value.data.integer = int_val;
1278 return conf_set(conf, section, key, &value);
1281 int conf_set_boolean(struct conf_context *conf,
1282 const char *section,
1283 const char *key,
1284 bool bool_val)
1286 struct conf_value value;
1288 value.type = CONF_BOOLEAN;
1289 value.data.boolean = bool_val;
1291 return conf_set(conf, section, key, &value);
1294 static int conf_get(struct conf_context *conf,
1295 const char *section,
1296 const char *key,
1297 enum conf_type type,
1298 const struct conf_value **value,
1299 bool *is_default)
1301 struct conf_section *s;
1302 struct conf_option *opt;
1304 s = conf_section_find(conf, section);
1305 if (s == NULL) {
1306 return EINVAL;
1309 opt = conf_option_find(s, key);
1310 if (opt == NULL) {
1311 return EINVAL;
1314 if (opt->type != type) {
1315 return EINVAL;
1318 *value = opt->value;
1319 if (is_default != NULL) {
1320 *is_default = conf_option_is_default(opt);
1323 return 0;
1326 int conf_get_string(struct conf_context *conf,
1327 const char *section,
1328 const char *key,
1329 const char **str_val,
1330 bool *is_default)
1332 const struct conf_value *value;
1333 int ret;
1335 ret = conf_get(conf, section, key, CONF_STRING, &value, is_default);
1336 if (ret != 0) {
1337 return ret;
1340 *str_val = value->data.string;
1341 return 0;
1344 int conf_get_integer(struct conf_context *conf,
1345 const char *section,
1346 const char *key,
1347 int *int_val,
1348 bool *is_default)
1350 const struct conf_value *value;
1351 int ret;
1353 ret = conf_get(conf, section, key, CONF_INTEGER, &value, is_default);
1354 if (ret != 0) {
1355 return ret;
1358 *int_val = value->data.integer;
1359 return 0;
1362 int conf_get_boolean(struct conf_context *conf,
1363 const char *section,
1364 const char *key,
1365 bool *bool_val,
1366 bool *is_default)
1368 const struct conf_value *value;
1369 int ret;
1371 ret = conf_get(conf, section, key, CONF_BOOLEAN, &value, is_default);
1372 if (ret != 0) {
1373 return ret;
1376 *bool_val = value->data.boolean;
1377 return 0;
1380 void conf_dump(struct conf_context *conf, FILE *fp)
1382 struct conf_section *s;
1383 struct conf_option *opt;
1385 for (s = conf->section; s != NULL; s = s->next) {
1386 conf_section_dump(s, fp);
1387 for (opt = s->option; opt != NULL; opt = opt->next) {
1388 conf_option_dump(opt, fp);