2 * config.c : reading configuration information
4 * ====================================================================
5 * Licensed to the Apache Software Foundation (ASF) under one
6 * or more contributor license agreements. See the NOTICE file
7 * distributed with this work for additional information
8 * regarding copyright ownership. The ASF licenses this file
9 * to you under the Apache License, Version 2.0 (the
10 * "License"); you may not use this file except in compliance
11 * with the License. You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing,
16 * software distributed under the License is distributed on an
17 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18 * KIND, either express or implied. See the License for the
19 * specific language governing permissions and limitations
21 * ====================================================================
26 #define APR_WANT_STRFUNC
27 #define APR_WANT_MEMFUNC
30 #include <apr_general.h>
33 #include "svn_error.h"
34 #include "svn_pools.h"
35 #include "config_impl.h"
37 #include "svn_private_config.h"
38 #include "private/svn_dep_compat.h"
43 /* Section table entries. */
44 typedef struct cfg_section_t cfg_section_t;
47 /* The section name. */
50 /* Table of cfg_option_t's. */
55 /* Option table entries. */
56 typedef struct cfg_option_t cfg_option_t;
59 /* The option name. */
62 /* The option name, converted into a hash key. */
65 /* The unexpanded option value. */
68 /* The expanded option value. */
71 /* Expansion flag. If this is TRUE, this value has already been expanded.
72 In this case, if x_value is NULL, no expansions were necessary,
73 and value should be used directly. */
74 svn_boolean_t expanded;
80 svn_config_create2(svn_config_t **cfgp,
81 svn_boolean_t section_names_case_sensitive,
82 svn_boolean_t option_names_case_sensitive,
83 apr_pool_t *result_pool)
85 svn_config_t *cfg = apr_palloc(result_pool, sizeof(*cfg));
87 cfg->sections = apr_hash_make(result_pool);
88 cfg->pool = result_pool;
89 cfg->x_pool = svn_pool_create(result_pool);
90 cfg->x_values = FALSE;
91 cfg->tmp_key = svn_stringbuf_create_empty(result_pool);
92 cfg->tmp_value = svn_stringbuf_create_empty(result_pool);
93 cfg->section_names_case_sensitive = section_names_case_sensitive;
94 cfg->option_names_case_sensitive = option_names_case_sensitive;
101 svn_config_read3(svn_config_t **cfgp, const char *file,
102 svn_boolean_t must_exist,
103 svn_boolean_t section_names_case_sensitive,
104 svn_boolean_t option_names_case_sensitive,
105 apr_pool_t *result_pool)
110 SVN_ERR(svn_config_create2(&cfg,
111 section_names_case_sensitive,
112 option_names_case_sensitive,
115 /* Yes, this is platform-specific code in Subversion, but there's no
116 practical way to migrate it into APR, as it's simultaneously
117 Subversion-specific and Windows-specific. Even if we eventually
118 want to have APR offer a generic config-reading interface, it
119 makes sense to test it here first and migrate it later. */
121 if (0 == strncmp(file, SVN_REGISTRY_PREFIX, SVN_REGISTRY_PREFIX_LEN))
122 err = svn_config__parse_registry(cfg, file + SVN_REGISTRY_PREFIX_LEN,
123 must_exist, result_pool);
126 err = svn_config__parse_file(cfg, file, must_exist, result_pool);
128 if (err != SVN_NO_ERROR)
137 svn_config_parse(svn_config_t **cfgp, svn_stream_t *stream,
138 svn_boolean_t section_names_case_sensitive,
139 svn_boolean_t option_names_case_sensitive,
140 apr_pool_t *result_pool)
144 apr_pool_t *scratch_pool = svn_pool_create(result_pool);
146 err = svn_config_create2(&cfg,
147 section_names_case_sensitive,
148 option_names_case_sensitive,
151 if (err == SVN_NO_ERROR)
152 err = svn_config__parse_stream(cfg, stream, result_pool, scratch_pool);
154 if (err == SVN_NO_ERROR)
157 svn_pool_destroy(scratch_pool);
162 /* Read various configuration sources into *CFGP, in this order, with
163 * later reads overriding the results of earlier ones:
165 * 1. SYS_REGISTRY_PATH (only on Win32, but ignored if NULL)
167 * 2. SYS_FILE_PATH (everywhere, but ignored if NULL)
169 * 3. USR_REGISTRY_PATH (only on Win32, but ignored if NULL)
171 * 4. USR_FILE_PATH (everywhere, but ignored if NULL)
173 * Allocate *CFGP in POOL. Even if no configurations are read,
174 * allocate an empty *CFGP.
177 read_all(svn_config_t **cfgp,
178 const char *sys_registry_path,
179 const char *usr_registry_path,
180 const char *sys_file_path,
181 const char *usr_file_path,
184 svn_boolean_t red_config = FALSE; /* "red" is the past tense of "read" */
186 /*** Read system-wide configurations first... ***/
189 if (sys_registry_path)
191 SVN_ERR(svn_config_read2(cfgp, sys_registry_path, FALSE, FALSE, pool));
199 SVN_ERR(svn_config_merge(*cfgp, sys_file_path, FALSE));
202 SVN_ERR(svn_config_read3(cfgp, sys_file_path,
203 FALSE, FALSE, FALSE, pool));
208 /*** ...followed by per-user configurations. ***/
211 if (usr_registry_path)
214 SVN_ERR(svn_config_merge(*cfgp, usr_registry_path, FALSE));
217 SVN_ERR(svn_config_read2(cfgp, usr_registry_path,
218 FALSE, FALSE, pool));
227 SVN_ERR(svn_config_merge(*cfgp, usr_file_path, FALSE));
230 SVN_ERR(svn_config_read3(cfgp, usr_file_path,
231 FALSE, FALSE, FALSE, pool));
237 SVN_ERR(svn_config_create2(cfgp, FALSE, FALSE, pool));
243 /* CONFIG_DIR provides an override for the default behavior of reading
244 the default set of overlay files described by read_all()'s doc
247 get_category_config(svn_config_t **cfg,
248 const char *config_dir,
249 const char *category,
252 const char *usr_reg_path = NULL, *sys_reg_path = NULL;
253 const char *usr_cfg_path, *sys_cfg_path;
254 svn_error_t *err = NULL;
261 sys_reg_path = apr_pstrcat(pool, SVN_REGISTRY_SYS_CONFIG_PATH,
263 usr_reg_path = apr_pstrcat(pool, SVN_REGISTRY_USR_CONFIG_PATH,
267 err = svn_config__sys_config_path(&sys_cfg_path, category, pool);
268 if ((err) && (err->apr_err == SVN_ERR_BAD_FILENAME))
271 svn_error_clear(err);
279 SVN_ERR(svn_config_get_user_config_path(&usr_cfg_path, config_dir, category,
281 return read_all(cfg, sys_reg_path, usr_reg_path,
282 sys_cfg_path, usr_cfg_path, pool);
287 svn_config_get_config(apr_hash_t **cfg_hash,
288 const char *config_dir,
292 *cfg_hash = apr_hash_make(pool);
294 #define CATLEN (sizeof(SVN_CONFIG_CATEGORY_SERVERS) - 1)
295 SVN_ERR(get_category_config(&cfg, config_dir, SVN_CONFIG_CATEGORY_SERVERS,
298 apr_hash_set(*cfg_hash, SVN_CONFIG_CATEGORY_SERVERS, CATLEN, cfg);
301 #define CATLEN (sizeof(SVN_CONFIG_CATEGORY_CONFIG) - 1)
302 SVN_ERR(get_category_config(&cfg, config_dir, SVN_CONFIG_CATEGORY_CONFIG,
305 apr_hash_set(*cfg_hash, SVN_CONFIG_CATEGORY_CONFIG, CATLEN, cfg);
313 /* Iterate through CFG, passing BATON to CALLBACK for every (SECTION, OPTION)
314 pair. Stop if CALLBACK returns TRUE. Allocate from POOL. */
316 for_each_option(svn_config_t *cfg, void *baton, apr_pool_t *pool,
317 svn_boolean_t callback(void *same_baton,
318 cfg_section_t *section,
319 cfg_option_t *option))
321 apr_hash_index_t *sec_ndx;
322 for (sec_ndx = apr_hash_first(pool, cfg->sections);
324 sec_ndx = apr_hash_next(sec_ndx))
328 apr_hash_index_t *opt_ndx;
330 apr_hash_this(sec_ndx, NULL, NULL, &sec_ptr);
333 for (opt_ndx = apr_hash_first(pool, sec->options);
335 opt_ndx = apr_hash_next(opt_ndx))
340 apr_hash_this(opt_ndx, NULL, NULL, &opt_ptr);
343 if (callback(baton, sec, opt))
352 merge_callback(void *baton, cfg_section_t *section, cfg_option_t *option)
354 svn_config_set(baton, section->name, option->name, option->value);
359 svn_config_merge(svn_config_t *cfg, const char *file,
360 svn_boolean_t must_exist)
362 /* The original config hash shouldn't change if there's an error
363 while reading the confguration, so read into a temporary table.
364 ### We could use a tmp subpool for this, since merge_cfg is going
365 to be tossed afterwards. Premature optimization, though? */
366 svn_config_t *merge_cfg;
367 SVN_ERR(svn_config_read3(&merge_cfg, file, must_exist,
368 cfg->section_names_case_sensitive,
369 cfg->option_names_case_sensitive,
372 /* Now copy the new options into the original table. */
373 for_each_option(merge_cfg, cfg, merge_cfg->pool, merge_callback);
379 /* Remove variable expansions from CFG. Walk through the options tree,
380 killing all expanded values, then clear the expanded value pool. */
382 rmex_callback(void *baton, cfg_section_t *section, cfg_option_t *option)
384 /* Only clear the `expanded' flag if the value actually contains
385 variable expansions. */
386 if (option->expanded && option->x_value != NULL)
388 option->x_value = NULL;
389 option->expanded = FALSE;
396 remove_expansions(svn_config_t *cfg)
401 for_each_option(cfg, NULL, cfg->x_pool, rmex_callback);
402 svn_pool_clear(cfg->x_pool);
403 cfg->x_values = FALSE;
408 /* Canonicalize a string for hashing. Modifies KEY in place. */
409 static APR_INLINE char *
410 make_hash_key(char *key)
413 for (p = key; *p != 0; ++p)
414 *p = (char)apr_tolower(*p);
419 /* Return a pointer to an option in CFG, or NULL if it doesn't exist.
420 if SECTIONP is non-null, return a pointer to the option's section.
421 OPTION may be NULL. */
422 static cfg_option_t *
423 find_option(svn_config_t *cfg, const char *section, const char *option,
424 cfg_section_t **sectionp)
428 /* Canonicalize the hash key */
429 svn_stringbuf_set(cfg->tmp_key, section);
430 if (! cfg->section_names_case_sensitive)
431 make_hash_key(cfg->tmp_key->data);
433 sec_ptr = apr_hash_get(cfg->sections, cfg->tmp_key->data,
435 if (sectionp != NULL)
438 if (sec_ptr != NULL && option != NULL)
440 cfg_section_t *sec = sec_ptr;
443 /* Canonicalize the option key */
444 svn_stringbuf_set(cfg->tmp_key, option);
445 if (! cfg->option_names_case_sensitive)
446 make_hash_key(cfg->tmp_key->data);
448 opt = apr_hash_get(sec->options, cfg->tmp_key->data,
450 /* NOTE: ConfigParser's sections are case sensitive. */
452 && apr_strnatcasecmp(section, SVN_CONFIG__DEFAULT_SECTION) != 0)
453 /* Options which aren't found in the requested section are
454 also sought after in the default section. */
455 opt = find_option(cfg, SVN_CONFIG__DEFAULT_SECTION, option, &sec);
463 /* Has a bi-directional dependency with make_string_from_option(). */
465 expand_option_value(svn_config_t *cfg, cfg_section_t *section,
466 const char *opt_value, const char **opt_x_valuep,
470 /* Set *VALUEP according to the OPT's value. A value for X_POOL must
471 only ever be passed into this function by expand_option_value(). */
473 make_string_from_option(const char **valuep, svn_config_t *cfg,
474 cfg_section_t *section, cfg_option_t *opt,
477 /* Expand the option value if necessary. */
480 /* before attempting to expand an option, check for the placeholder.
481 * If none is there, there is no point in calling expand_option_value.
483 if (opt->value && strchr(opt->value, '%'))
485 apr_pool_t *tmp_pool = (x_pool ? x_pool : svn_pool_create(cfg->x_pool));
487 expand_option_value(cfg, section, opt->value, &opt->x_value, tmp_pool);
488 opt->expanded = TRUE;
490 if (x_pool != cfg->x_pool)
492 /* Grab the fully expanded value from tmp_pool before its
495 opt->x_value = apr_pstrmemdup(cfg->x_pool, opt->x_value,
496 strlen(opt->x_value));
498 svn_pool_destroy(tmp_pool);
503 opt->expanded = TRUE;
508 *valuep = opt->x_value;
510 *valuep = opt->value;
514 /* Start of variable-replacement placeholder */
515 #define FMT_START "%("
516 #define FMT_START_LEN (sizeof(FMT_START) - 1)
518 /* End of variable-replacement placeholder */
520 #define FMT_END_LEN (sizeof(FMT_END) - 1)
523 /* Expand OPT_VALUE (which may be NULL) in SECTION into *OPT_X_VALUEP.
524 If no variable replacements are done, set *OPT_X_VALUEP to
525 NULL. Allocate from X_POOL. */
527 expand_option_value(svn_config_t *cfg, cfg_section_t *section,
528 const char *opt_value, const char **opt_x_valuep,
531 svn_stringbuf_t *buf = NULL;
532 const char *parse_from = opt_value;
533 const char *copy_from = parse_from;
534 const char *name_start, *name_end;
536 while (parse_from != NULL
537 && *parse_from != '\0'
538 && (name_start = strstr(parse_from, FMT_START)) != NULL)
540 name_start += FMT_START_LEN;
541 if (*name_start == '\0')
542 /* FMT_START at end of opt_value. */
545 name_end = strstr(name_start, FMT_END);
546 if (name_end != NULL)
549 apr_size_t len = name_end - name_start;
550 char *name = apr_pstrmemdup(x_pool, name_start, len);
552 x_opt = find_option(cfg, section->name, name, NULL);
558 /* Pass back the sub-pool originally provided by
559 make_string_from_option() as an indication of when it
561 make_string_from_option(&cstring, cfg, section, x_opt, x_pool);
563 /* Append the plain text preceding the expansion. */
564 len = name_start - FMT_START_LEN - copy_from;
567 buf = svn_stringbuf_ncreate(copy_from, len, x_pool);
568 cfg->x_values = TRUE;
571 svn_stringbuf_appendbytes(buf, copy_from, len);
573 /* Append the expansion and adjust parse pointers. */
574 svn_stringbuf_appendcstr(buf, cstring);
575 parse_from = name_end + FMT_END_LEN;
576 copy_from = parse_from;
579 /* Though ConfigParser considers the failure to resolve
580 the requested expansion an exception condition, we
581 consider it to be plain text, and look for the start of
583 parse_from = name_end + FMT_END_LEN;
586 /* Though ConfigParser treats unterminated format specifiers
587 as an exception condition, we consider them to be plain
588 text. The fact that there are no more format specifier
589 endings means we're done parsing. */
595 /* Copy the remainder of the plain text. */
596 svn_stringbuf_appendcstr(buf, copy_from);
597 *opt_x_valuep = buf->data;
600 *opt_x_valuep = NULL;
603 static cfg_section_t *
604 svn_config_addsection(svn_config_t *cfg,
608 const char *hash_key;
610 s = apr_palloc(cfg->pool, sizeof(cfg_section_t));
611 s->name = apr_pstrdup(cfg->pool, section);
612 if(cfg->section_names_case_sensitive)
615 hash_key = make_hash_key(apr_pstrdup(cfg->pool, section));
616 s->options = apr_hash_make(cfg->pool);
617 svn_hash_sets(cfg->sections, hash_key, s);
623 svn_config_create_option(cfg_option_t **opt,
626 svn_boolean_t option_names_case_sensitive,
631 o = apr_palloc(pool, sizeof(cfg_option_t));
632 o->name = apr_pstrdup(pool, option);
633 if(option_names_case_sensitive)
634 o->hash_key = o->name;
636 o->hash_key = make_hash_key(apr_pstrdup(pool, option));
638 o->value = apr_pstrdup(pool, value);
647 svn_config_get(svn_config_t *cfg, const char **valuep,
648 const char *section, const char *option,
649 const char *default_value)
651 *valuep = default_value;
655 cfg_option_t *opt = find_option(cfg, section, option, &sec);
658 make_string_from_option(valuep, cfg, sec, opt, NULL);
661 /* before attempting to expand an option, check for the placeholder.
662 * If none is there, there is no point in calling expand_option_value.
664 if (default_value && strchr(default_value, '%'))
666 apr_pool_t *tmp_pool = svn_pool_create(cfg->x_pool);
667 const char *x_default;
668 expand_option_value(cfg, sec, default_value, &x_default, tmp_pool);
671 svn_stringbuf_set(cfg->tmp_value, x_default);
672 *valuep = cfg->tmp_value->data;
674 svn_pool_destroy(tmp_pool);
682 svn_config_set(svn_config_t *cfg,
683 const char *section, const char *option,
689 remove_expansions(cfg);
691 opt = find_option(cfg, section, option, &sec);
694 /* Replace the option's value. */
695 opt->value = apr_pstrdup(cfg->pool, value);
696 opt->expanded = FALSE;
700 /* Create a new option */
701 svn_config_create_option(&opt, option, value,
702 cfg->option_names_case_sensitive,
707 /* Even the section doesn't exist. Create it. */
708 sec = svn_config_addsection(cfg, section);
711 svn_hash_sets(sec->options, opt->hash_key, opt);
716 /* Set *BOOLP to true or false depending (case-insensitively) on INPUT.
717 If INPUT is null, set *BOOLP to DEFAULT_VALUE.
719 INPUT is a string indicating truth or falsehood in any of the usual
720 ways: "true"/"yes"/"on"/etc, "false"/"no"/"off"/etc.
722 If INPUT is neither NULL nor a recognized string, return an error
723 with code SVN_ERR_BAD_CONFIG_VALUE; use SECTION and OPTION in
724 constructing the error string. */
726 get_bool(svn_boolean_t *boolp, const char *input, svn_boolean_t default_value,
727 const char *section, const char *option)
729 svn_tristate_t value = svn_tristate__from_word(input);
731 if (value == svn_tristate_true)
733 else if (value == svn_tristate_false)
735 else if (input == NULL) /* no value provided */
736 *boolp = default_value;
738 else if (section) /* unrecognized value */
739 return svn_error_createf(SVN_ERR_BAD_CONFIG_VALUE, NULL,
740 _("Config error: invalid boolean "
741 "value '%s' for '[%s] %s'"),
742 input, section, option);
744 return svn_error_createf(SVN_ERR_BAD_CONFIG_VALUE, NULL,
745 _("Config error: invalid boolean "
746 "value '%s' for '%s'"),
754 svn_config_get_bool(svn_config_t *cfg, svn_boolean_t *valuep,
755 const char *section, const char *option,
756 svn_boolean_t default_value)
758 const char *tmp_value;
759 svn_config_get(cfg, &tmp_value, section, option, NULL);
760 return get_bool(valuep, tmp_value, default_value, section, option);
766 svn_config_set_bool(svn_config_t *cfg,
767 const char *section, const char *option,
770 svn_config_set(cfg, section, option,
771 (value ? SVN_CONFIG_TRUE : SVN_CONFIG_FALSE));
775 svn_config_get_int64(svn_config_t *cfg,
779 apr_int64_t default_value)
781 const char *tmp_value;
782 svn_config_get(cfg, &tmp_value, section, option, NULL);
784 return svn_cstring_strtoi64(valuep, tmp_value,
785 APR_INT64_MIN, APR_INT64_MAX, 10);
787 *valuep = default_value;
792 svn_config_set_int64(svn_config_t *cfg,
797 svn_config_set(cfg, section, option,
798 apr_psprintf(cfg->pool, "%" APR_INT64_T_FMT, value));
802 svn_config_get_yes_no_ask(svn_config_t *cfg, const char **valuep,
803 const char *section, const char *option,
804 const char* default_value)
806 const char *tmp_value;
808 svn_config_get(cfg, &tmp_value, section, option, NULL);
811 tmp_value = default_value;
813 if (tmp_value && (0 == svn_cstring_casecmp(tmp_value, SVN_CONFIG_ASK)))
815 *valuep = SVN_CONFIG_ASK;
819 svn_boolean_t bool_val;
820 /* We already incorporated default_value into tmp_value if
821 necessary, so the FALSE below will be ignored unless the
822 caller is doing something it shouldn't be doing. */
823 SVN_ERR(get_bool(&bool_val, tmp_value, FALSE, section, option));
824 *valuep = bool_val ? SVN_CONFIG_TRUE : SVN_CONFIG_FALSE;
831 svn_config_get_tristate(svn_config_t *cfg, svn_tristate_t *valuep,
832 const char *section, const char *option,
833 const char *unknown_value,
834 svn_tristate_t default_value)
836 const char *tmp_value;
838 svn_config_get(cfg, &tmp_value, section, option, NULL);
842 *valuep = default_value;
844 else if (0 == svn_cstring_casecmp(tmp_value, unknown_value))
846 *valuep = svn_tristate_unknown;
850 svn_boolean_t bool_val;
851 /* We already incorporated default_value into tmp_value if
852 necessary, so the FALSE below will be ignored unless the
853 caller is doing something it shouldn't be doing. */
854 SVN_ERR(get_bool(&bool_val, tmp_value, FALSE, section, option));
855 *valuep = bool_val ? svn_tristate_true : svn_tristate_false;
862 svn_config_enumerate_sections(svn_config_t *cfg,
863 svn_config_section_enumerator_t callback,
866 apr_hash_index_t *sec_ndx;
868 apr_pool_t *subpool = svn_pool_create(cfg->x_pool);
870 for (sec_ndx = apr_hash_first(subpool, cfg->sections);
872 sec_ndx = apr_hash_next(sec_ndx))
877 apr_hash_this(sec_ndx, NULL, NULL, &sec_ptr);
880 if (!callback(sec->name, baton))
884 svn_pool_destroy(subpool);
890 svn_config_enumerate_sections2(svn_config_t *cfg,
891 svn_config_section_enumerator2_t callback,
892 void *baton, apr_pool_t *pool)
894 apr_hash_index_t *sec_ndx;
895 apr_pool_t *iteration_pool;
898 iteration_pool = svn_pool_create(pool);
899 for (sec_ndx = apr_hash_first(pool, cfg->sections);
901 sec_ndx = apr_hash_next(sec_ndx))
906 apr_hash_this(sec_ndx, NULL, NULL, &sec_ptr);
909 svn_pool_clear(iteration_pool);
910 if (!callback(sec->name, baton, iteration_pool))
913 svn_pool_destroy(iteration_pool);
921 svn_config_enumerate(svn_config_t *cfg, const char *section,
922 svn_config_enumerator_t callback, void *baton)
925 apr_hash_index_t *opt_ndx;
929 find_option(cfg, section, NULL, &sec);
933 subpool = svn_pool_create(cfg->x_pool);
935 for (opt_ndx = apr_hash_first(subpool, sec->options);
937 opt_ndx = apr_hash_next(opt_ndx))
941 const char *temp_value;
943 apr_hash_this(opt_ndx, NULL, NULL, &opt_ptr);
947 make_string_from_option(&temp_value, cfg, sec, opt, NULL);
948 if (!callback(opt->name, temp_value, baton))
952 svn_pool_destroy(subpool);
958 svn_config_enumerate2(svn_config_t *cfg, const char *section,
959 svn_config_enumerator2_t callback, void *baton,
963 apr_hash_index_t *opt_ndx;
964 apr_pool_t *iteration_pool;
967 find_option(cfg, section, NULL, &sec);
971 iteration_pool = svn_pool_create(pool);
973 for (opt_ndx = apr_hash_first(pool, sec->options);
975 opt_ndx = apr_hash_next(opt_ndx))
979 const char *temp_value;
981 apr_hash_this(opt_ndx, NULL, NULL, &opt_ptr);
985 make_string_from_option(&temp_value, cfg, sec, opt, NULL);
986 svn_pool_clear(iteration_pool);
987 if (!callback(opt->name, temp_value, baton, iteration_pool))
990 svn_pool_destroy(iteration_pool);
997 /* Baton for search_groups() */
998 struct search_groups_baton
1000 const char *key; /* Provided by caller of svn_config_find_group */
1001 const char *match; /* Filled in by search_groups */
1006 /* This is an `svn_config_enumerator_t' function, and BATON is a
1007 * `struct search_groups_baton *'.
1009 static svn_boolean_t search_groups(const char *name,
1014 struct search_groups_baton *b = baton;
1015 apr_array_header_t *list;
1017 list = svn_cstring_split(value, ",", TRUE, pool);
1018 if (svn_cstring_match_glob_list(b->key, list))
1020 /* Fill in the match and return false, to stop enumerating. */
1021 b->match = apr_pstrdup(b->pool, name);
1029 const char *svn_config_find_group(svn_config_t *cfg, const char *key,
1030 const char *master_section,
1033 struct search_groups_baton gb;
1038 (void) svn_config_enumerate2(cfg, master_section, search_groups, &gb, pool);
1044 svn_config_get_server_setting(svn_config_t *cfg,
1045 const char* server_group,
1046 const char* option_name,
1047 const char* default_value)
1050 svn_config_get(cfg, &retval, SVN_CONFIG_SECTION_GLOBAL,
1051 option_name, default_value);
1054 svn_config_get(cfg, &retval, server_group, option_name, retval);
1061 svn_config_dup(svn_config_t **cfgp,
1065 apr_hash_index_t *sectidx;
1066 apr_hash_index_t *optidx;
1069 SVN_ERR(svn_config_create2(cfgp, FALSE, FALSE, pool));
1071 (*cfgp)->x_values = src->x_values;
1072 (*cfgp)->section_names_case_sensitive = src->section_names_case_sensitive;
1073 (*cfgp)->option_names_case_sensitive = src->option_names_case_sensitive;
1075 for (sectidx = apr_hash_first(pool, src->sections);
1077 sectidx = apr_hash_next(sectidx))
1079 const void *sectkey;
1081 apr_ssize_t sectkeyLength;
1082 cfg_section_t * srcsect;
1083 cfg_section_t * destsec;
1085 apr_hash_this(sectidx, §key, §keyLength, §val);
1088 destsec = svn_config_addsection(*cfgp, srcsect->name);
1090 for (optidx = apr_hash_first(pool, srcsect->options);
1092 optidx = apr_hash_next(optidx))
1096 apr_ssize_t optkeyLength;
1097 cfg_option_t *srcopt;
1098 cfg_option_t *destopt;
1100 apr_hash_this(optidx, &optkey, &optkeyLength, &optval);
1103 svn_config_create_option(&destopt, srcopt->name, srcopt->value,
1104 (*cfgp)->option_names_case_sensitive,
1107 destopt->value = apr_pstrdup(pool, srcopt->value);
1108 destopt->x_value = apr_pstrdup(pool, srcopt->x_value);
1109 destopt->expanded = srcopt->expanded;
1110 apr_hash_set(destsec->options,
1111 apr_pstrdup(pool, (const char*)optkey),
1112 optkeyLength, destopt);
1116 return SVN_NO_ERROR;
1120 svn_config_copy_config(apr_hash_t **cfg_hash,
1121 apr_hash_t *src_hash,
1124 apr_hash_index_t *cidx;
1126 *cfg_hash = apr_hash_make(pool);
1127 for (cidx = apr_hash_first(pool, src_hash);
1129 cidx = apr_hash_next(cidx))
1133 apr_ssize_t ckeyLength;
1134 svn_config_t * srcconfig;
1135 svn_config_t * destconfig;
1137 apr_hash_this(cidx, &ckey, &ckeyLength, &cval);
1140 SVN_ERR(svn_config_dup(&destconfig, srcconfig, pool));
1142 apr_hash_set(*cfg_hash,
1143 apr_pstrdup(pool, (const char*)ckey),
1144 ckeyLength, destconfig);
1147 return SVN_NO_ERROR;
1151 svn_config_get_server_setting_int(svn_config_t *cfg,
1152 const char *server_group,
1153 const char *option_name,
1154 apr_int64_t default_value,
1155 apr_int64_t *result_value,
1158 const char* tmp_value;
1161 tmp_value = svn_config_get_server_setting(cfg, server_group,
1163 if (tmp_value == NULL)
1164 *result_value = default_value;
1167 /* read tmp_value as an int now */
1168 *result_value = apr_strtoi64(tmp_value, &end_pos, 0);
1172 return svn_error_createf
1173 (SVN_ERR_BAD_CONFIG_VALUE, NULL,
1174 _("Config error: invalid integer value '%s'"),
1179 return SVN_NO_ERROR;
1183 svn_config_get_server_setting_bool(svn_config_t *cfg,
1184 svn_boolean_t *valuep,
1185 const char *server_group,
1186 const char *option_name,
1187 svn_boolean_t default_value)
1189 const char* tmp_value;
1190 tmp_value = svn_config_get_server_setting(cfg, server_group,
1192 return get_bool(valuep, tmp_value, default_value,
1193 server_group, option_name);
1198 svn_config_has_section(svn_config_t *cfg, const char *section)
1202 /* Canonicalize the hash key */
1203 svn_stringbuf_set(cfg->tmp_key, section);
1204 if (! cfg->section_names_case_sensitive)
1205 make_hash_key(cfg->tmp_key->data);
1207 sec = svn_hash_gets(cfg->sections, cfg->tmp_key->data);