Merge "CLI: Remove special handling of 'core set verbose' from rasterisk."
[asterisk/asterisk.git] / main / config_options.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2012, Digium, Inc.
5  *
6  * Mark Spencer <markster@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*! \file
20  * \brief Configuration Option-handling
21  * \author Terry Wilson <twilson@digium.com>
22  */
23
24 /*** MODULEINFO
25         <support_level>core</support_level>
26  ***/
27
28 #include "asterisk.h"
29
30 #include <regex.h>
31
32 #include "asterisk/_private.h"
33 #include "asterisk/config.h"
34 #include "asterisk/config_options.h"
35 #include "asterisk/stringfields.h"
36 #include "asterisk/acl.h"
37 #include "asterisk/app.h"
38 #include "asterisk/frame.h"
39 #include "asterisk/xmldoc.h"
40 #include "asterisk/cli.h"
41 #include "asterisk/term.h"
42 #include "asterisk/format_cap.h"
43
44 #ifdef LOW_MEMORY
45 #define CONFIG_OPT_BUCKETS 5
46 #else
47 #define CONFIG_OPT_BUCKETS 53
48 #endif /* LOW_MEMORY */
49
50 /*! \brief Bits of aco_info that shouldn't be assigned outside this file
51  * \internal
52  */
53 struct aco_info_internal {
54         void *pending;              /*!< The user-defined config object awaiting application */
55 };
56
57 struct aco_type_internal {
58         regex_t *regex;
59         struct ao2_container *opts; /*!< The container of options registered to the aco_info */
60 };
61
62 struct aco_option {
63         const char *name;
64         const char *aliased_to;
65         const char *default_val;
66         enum aco_matchtype match_type;
67         regex_t *name_regex;
68         struct aco_type **obj;
69         enum aco_option_type type;
70         aco_option_handler handler;
71         unsigned int flags;
72         unsigned int no_doc:1;
73 #ifdef AST_DEVMODE
74         unsigned int doc_unavailable:1;
75 #endif
76         unsigned char deprecated:1;
77         size_t argc;
78         intptr_t args[0];
79 };
80
81 #ifdef AST_XML_DOCS
82 static struct ao2_container *xmldocs;
83
84 /*! \brief Value of the aco_option_type enum as strings */
85 static char *aco_option_type_string[] = {
86         "ACL",                          /* OPT_ACL_T, */
87         "Boolean",                      /* OPT_BOOL_T, */
88         "Boolean",                      /* OPT_BOOLFLAG_T, */
89         "String",                       /* OPT_CHAR_ARRAY_T, */
90         "Codec",                        /* OPT_CODEC_T, */
91         "Custom",                       /* OPT_CUSTOM_T, */
92         "Double",                       /* OPT_DOUBLE_T, */
93         "Integer",                      /* OPT_INT_T, */
94         "None",                         /* OPT_NOOP_T, */
95         "IP Address",           /* OPT_SOCKADDR_T, */
96         "String",                       /* OPT_STRINGFIELD_T, */
97         "Unsigned Integer",     /* OPT_UINT_T, */
98         "Boolean",                      /* OPT_YESNO_T, */
99 };
100 #endif /* AST_XML_DOCS */
101
102 void *aco_pending_config(struct aco_info *info)
103 {
104         if (!(info && info->internal)) {
105                 ast_log(LOG_ERROR, "This may not be called without an initialized aco_info!\n");
106                 return NULL;
107         }
108         return info->internal->pending;
109 }
110
111 static void config_option_destroy(void *obj)
112 {
113         struct aco_option *opt = obj;
114         if (opt->match_type == ACO_REGEX && opt->name_regex) {
115                 regfree(opt->name_regex);
116                 ast_free(opt->name_regex);
117         }
118 }
119
120 static int int_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj);
121 static int uint_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj);
122 static int timelen_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj);
123 static int double_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj);
124 static int sockaddr_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj);
125 static int stringfield_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj);
126 static int bool_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj);
127 static int boolflag_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj);
128 static int acl_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj);
129 static int codec_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj);
130 static int noop_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj);
131 static int chararray_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj);
132
133 #ifdef AST_XML_DOCS
134 static int xmldoc_update_config_type(const char *module, const char *name, const char *category, const char *matchfield, const char *matchvalue, enum aco_category_op category_match);
135 static int xmldoc_update_config_option(struct aco_type **types, const char *module, const char *name, const char *object_name, const char *default_value, unsigned int regex, enum aco_option_type type);
136 #endif
137
138 static aco_option_handler ast_config_option_default_handler(enum aco_option_type type)
139 {
140         switch(type) {
141         case OPT_ACL_T: return acl_handler_fn;
142         case OPT_BOOL_T: return bool_handler_fn;
143         /* Reading from config files, BOOL and YESNO are handled exactly the
144          * same. Their difference is in how they are rendered to users
145          */
146         case OPT_YESNO_T: return bool_handler_fn;
147         case OPT_BOOLFLAG_T: return boolflag_handler_fn;
148         case OPT_CHAR_ARRAY_T: return chararray_handler_fn;
149         case OPT_CODEC_T: return codec_handler_fn;
150         case OPT_DOUBLE_T: return double_handler_fn;
151         case OPT_INT_T: return int_handler_fn;
152         case OPT_NOOP_T: return noop_handler_fn;
153         case OPT_SOCKADDR_T: return sockaddr_handler_fn;
154         case OPT_STRINGFIELD_T: return stringfield_handler_fn;
155         case OPT_UINT_T: return uint_handler_fn;
156         case OPT_TIMELEN_T: return timelen_handler_fn;
157
158         case OPT_CUSTOM_T: return NULL;
159         }
160
161         return NULL;
162 }
163
164 static regex_t *build_regex(const char *text)
165 {
166         int res;
167         regex_t *regex;
168
169         if (!(regex = ast_malloc(sizeof(*regex)))) {
170                 return NULL;
171         }
172
173         if ((res = regcomp(regex, text, REG_EXTENDED | REG_ICASE | REG_NOSUB))) {
174                 size_t len = regerror(res, regex, NULL, 0);
175                 char buf[len];
176                 regerror(res, regex, buf, len);
177                 ast_log(LOG_ERROR, "Could not compile regex '%s': %s\n", text, buf);
178                 ast_free(regex);
179                 return NULL;
180         }
181
182         return regex;
183 }
184
185 static int link_option_to_types(struct aco_info *info, struct aco_type **types, struct aco_option *opt)
186 {
187         size_t idx = 0;
188         struct aco_type *type;
189
190         while ((type = types[idx++])) {
191                 if (!type->internal) {
192                         ast_log(LOG_ERROR, "Attempting to register option using uninitialized type\n");
193                         return -1;
194                 }
195                 if (!ao2_link(type->internal->opts, opt)) {
196                         do {
197                                 ao2_unlink(types[idx - 1]->internal->opts, opt);
198                         } while (--idx);
199                         return -1;
200                 }
201 #ifdef AST_XML_DOCS
202                 if (!info->hidden && !opt->no_doc &&
203                         xmldoc_update_config_option(types, info->module, opt->name, type->name, opt->default_val, opt->match_type == ACO_REGEX, opt->type)) {
204 #ifdef AST_DEVMODE
205                         opt->doc_unavailable = 1;
206 #endif
207                 }
208 #endif
209         }
210         /* The container(s) should hold the only ref to opt */
211         ao2_ref(opt, -1);
212
213         return 0;
214 }
215
216 int aco_option_register_deprecated(struct aco_info *info, const char *name, struct aco_type **types, const char *aliased_to)
217 {
218         struct aco_option *opt;
219
220         if (!info || ast_strlen_zero(name) || ast_strlen_zero(aliased_to)) {
221                 return -1;
222         }
223
224         if (!(opt = ao2_alloc(sizeof(*opt), config_option_destroy))) {
225                 return -1;
226         }
227
228         opt->name = name;
229         opt->aliased_to = aliased_to;
230         opt->deprecated = 1;
231         opt->match_type = ACO_EXACT;
232
233         if (link_option_to_types(info, types, opt)) {
234                 ao2_ref(opt, -1);
235                 return -1;
236         }
237
238         return 0;
239 }
240
241 unsigned int aco_option_get_flags(const struct aco_option *option)
242 {
243         return option->flags;
244 }
245
246 intptr_t aco_option_get_argument(const struct aco_option *option, unsigned int position)
247 {
248         return option->args[position];
249 }
250
251 #ifdef AST_XML_DOCS
252 /*! \internal
253  * \brief Find a particular ast_xml_doc_item from it's parent config_info, types, and name
254  */
255 static struct ast_xml_doc_item *find_xmldoc_option(struct ast_xml_doc_item *config_info, struct aco_type **types, const char *name)
256 {
257         struct ast_xml_doc_item *iter = config_info;
258
259         if (!iter) {
260                 return NULL;
261         }
262         /* First is just the configInfo, we can skip it */
263         while ((iter = AST_LIST_NEXT(iter, next))) {
264                 size_t x;
265                 if (strcasecmp(iter->name, name)) {
266                         continue;
267                 }
268                 for (x = 0; types[x]; x++) {
269                         /* All we care about is that at least one type has the option */
270                         if (!strcasecmp(types[x]->name, iter->ref)) {
271                                 return iter;
272                         }
273                 }
274         }
275         return NULL;
276 }
277
278 /*! \internal
279  * \brief Find a particular ast_xml_doc_item from it's parent config_info and name
280  */
281 static struct ast_xml_doc_item *find_xmldoc_type(struct ast_xml_doc_item *config_info, const char *name)
282 {
283         struct ast_xml_doc_item *iter = config_info;
284         if (!iter) {
285                 return NULL;
286         }
287         /* First is just the config Info, skip it */
288         while ((iter = AST_LIST_NEXT(iter, next))) {
289                 if (!strcasecmp(iter->type, "configObject") && !strcasecmp(iter->name, name)) {
290                         break;
291                 }
292         }
293         return iter;
294 }
295
296 #endif /* AST_XML_DOCS */
297
298 int __aco_option_register(struct aco_info *info, const char *name, enum aco_matchtype matchtype, struct aco_type **types,
299         const char *default_val, enum aco_option_type kind, aco_option_handler handler, unsigned int flags,
300         unsigned int no_doc, size_t argc, ...)
301 {
302         struct aco_option *opt;
303         va_list ap;
304         int tmp;
305
306         /* Custom option types require a handler */
307         if (!handler && kind == OPT_CUSTOM_T) {
308                 return -1;
309         }
310
311         if (!(types && types[0])) {
312                 return -1;
313         }
314
315         if (!(opt = ao2_alloc(sizeof(*opt) + argc * sizeof(opt->args[0]), config_option_destroy))) {
316                 return -1;
317         }
318
319         if (matchtype == ACO_REGEX && !(opt->name_regex = build_regex(name))) {
320                 ao2_ref(opt, -1);
321                 return -1;
322         }
323
324         va_start(ap, argc);
325         for (tmp = 0; tmp < argc; tmp++) {
326                 opt->args[tmp] = va_arg(ap, size_t);
327         }
328         va_end(ap);
329
330         opt->name = name;
331         opt->match_type = matchtype;
332         opt->default_val = default_val;
333         opt->type = kind;
334         opt->handler = handler;
335         opt->flags = flags;
336         opt->argc = argc;
337         opt->no_doc = no_doc;
338
339         if (!opt->handler && !(opt->handler = ast_config_option_default_handler(opt->type))) {
340                 /* This should never happen */
341                 ast_log(LOG_ERROR, "No handler provided, and no default handler exists for type %u\n", opt->type);
342                 ao2_ref(opt, -1);
343                 return -1;
344         };
345
346         if (link_option_to_types(info, types, opt)) {
347                 ao2_ref(opt, -1);
348                 return -1;
349         }
350
351         return 0;
352 }
353
354 static int config_opt_hash(const void *obj, const int flags)
355 {
356         const struct aco_option *opt = obj;
357         const char *name = (flags & OBJ_KEY) ? obj : opt->name;
358         return ast_str_case_hash(name);
359 }
360
361 static int config_opt_cmp(void *obj, void *arg, int flags)
362 {
363         struct aco_option *opt1 = obj, *opt2 = arg;
364         const char *name = (flags & OBJ_KEY) ? arg : opt2->name;
365         return strcasecmp(opt1->name, name) ? 0 : CMP_MATCH | CMP_STOP;
366 }
367
368 static int find_option_cb(void *obj, void *arg, int flags)
369 {
370         struct aco_option *match = obj;
371         const char *name = arg;
372
373         switch (match->match_type) {
374         case ACO_EXACT:
375                 return strcasecmp(name, match->name) ? 0 : CMP_MATCH | CMP_STOP;
376         case ACO_PREFIX:
377                 return strncasecmp(name, match->name, strlen(match->name)) ? 0 : CMP_MATCH | CMP_STOP;
378         case ACO_REGEX:
379                 return regexec(match->name_regex, name, 0, NULL, 0) ? 0 : CMP_MATCH | CMP_STOP;
380         }
381         ast_log(LOG_ERROR, "Unknown match type. This should not be possible.\n");
382         return CMP_STOP;
383 }
384
385 static struct aco_option *aco_option_find(struct aco_type *type, const char *name)
386 {
387         struct aco_option *opt;
388
389         if (!type || !type->internal || !type->internal->opts) {
390                 ast_log(LOG_NOTICE, "Attempting to use NULL or unitialized config type\n");
391                 return NULL;
392         }
393
394         /* Try an exact match with OBJ_KEY for the common/fast case, then iterate through
395          * all options for the regex cases */
396         if (!(opt = ao2_callback(type->internal->opts, OBJ_KEY, find_option_cb, (void *) name))) {
397                 opt = ao2_callback(type->internal->opts, 0, find_option_cb, (void *) name);
398         }
399         return opt;
400 }
401
402 struct ao2_container *aco_option_container_alloc(void)
403 {
404         return ao2_container_alloc(CONFIG_OPT_BUCKETS, config_opt_hash, config_opt_cmp);
405 }
406
407 static int internal_aco_type_category_check(struct aco_type *match, const char *category)
408 {
409         const char **categories = (const char **)match->category;
410
411         switch (match->category_match) {
412         case ACO_WHITELIST:
413                 return regexec(match->internal->regex, category, 0, NULL, 0);
414
415         case ACO_BLACKLIST:
416                 return !regexec(match->internal->regex, category, 0, NULL, 0);
417
418         case ACO_WHITELIST_EXACT:
419                 return strcasecmp(match->category, category);
420
421         case ACO_BLACKLIST_EXACT:
422                 return !strcasecmp(match->category, category);
423
424         case ACO_WHITELIST_ARRAY:
425                 while (*categories) {
426                         if (!strcasecmp(*categories, category)) {
427                                 return 0;
428                         }
429                         categories++;
430                 }
431                 return -1;
432
433         case ACO_BLACKLIST_ARRAY:
434                 while (*categories) {
435                         if (!strcasecmp(*categories, category)) {
436                                 return -1;
437                         }
438                         categories++;
439                 }
440                 return 0;
441         }
442
443         return -1;
444 }
445
446 static struct aco_type *internal_aco_type_find(struct aco_file *file, struct ast_config *cfg, const char *category)
447 {
448         size_t x;
449         struct aco_type *match;
450         const char *val;
451
452         for (x = 0, match = file->types[x]; match; match = file->types[++x]) {
453                 /* First make sure we are an object that can service this category */
454                 if (internal_aco_type_category_check(match, category)) {
455                         continue;
456                 }
457
458                 /* Then, see if we need to match a particular field */
459                 if (!ast_strlen_zero(match->matchfield) && (!ast_strlen_zero(match->matchvalue) || match->matchfunc)) {
460                         if (!(val = ast_variable_retrieve(cfg, category, match->matchfield))) {
461                                 ast_log(LOG_ERROR, "Required match field '%s' not found\n", match->matchfield);
462                                 return NULL;
463                         }
464                         if (match->matchfunc) {
465                                 if (!match->matchfunc(val)) {
466                                         continue;
467                                 }
468                         } else if (strcasecmp(val, match->matchvalue)) {
469                                 continue;
470                         }
471                 }
472                 /* If we get this far, we're a match */
473                 break;
474         }
475
476         return match;
477 }
478
479 static int is_preload(struct aco_file *file, const char *cat)
480 {
481         int i;
482
483         if (!file->preload) {
484                 return 0;
485         }
486
487         for (i = 0; !ast_strlen_zero(file->preload[i]); i++) {
488                 if (!strcasecmp(cat, file->preload[i])) {
489                         return 1;
490                 }
491         }
492         return 0;
493 }
494
495 static int process_category(struct ast_config *cfg, struct aco_info *info, struct aco_file *file, const char *cat, int preload) {
496         RAII_VAR(void *, new_item, NULL, ao2_cleanup);
497         struct aco_type *type;
498         /* For global types, field is the global option struct. For non-global, it is the container for items.
499          * We do not grab a reference to these objects, as the info already holds references to them. This
500          * pointer is just a convenience. Do not actually store it somewhere. */
501         void **field;
502         regex_t *regex_skip;
503
504         /* Skip preloaded categories if we aren't preloading */
505         if (!preload && is_preload(file, cat)) {
506                 return 0;
507         }
508
509         /* Skip the category if we've been told to ignore it */
510         if (!ast_strlen_zero(file->skip_category)) {
511                 regex_skip = build_regex(file->skip_category);
512                 if (!regexec(regex_skip, cat, 0, NULL, 0)) {
513                         regfree(regex_skip);
514                         ast_free(regex_skip);
515                         return 0;
516                 }
517                 regfree(regex_skip);
518                 ast_free(regex_skip);
519         }
520
521         /* Find aco_type by category, if not found it is an error */
522         if (!(type = internal_aco_type_find(file, cfg, cat))) {
523                 ast_log(LOG_ERROR, "Could not find config type for category '%s' in '%s'\n", cat, file->filename);
524                 return -1;
525         }
526
527         if (type->type == ACO_IGNORE) {
528                 return 0;
529         }
530
531         field = info->internal->pending + type->item_offset;
532         if (!*field) {
533                 ast_log(LOG_ERROR, "In %s: %s - No object to update!\n", file->filename, cat);
534                 return -1;
535         }
536
537         if (type->type == ACO_GLOBAL && *field) {
538                 if (aco_process_category_options(type, cfg, cat, *field)) {
539                         ast_log(LOG_ERROR, "In %s: Processing options for %s failed\n", file->filename, cat);
540                         return -1;
541                 }
542         } else if (type->type == ACO_ITEM) {
543                 int new = 0;
544                 /* If we have multiple definitions of a category in a file, or can set the values from multiple
545                  * files, look up the entry if we've already added it so we can merge the values together.
546                  * Otherwise, alloc a new item. */
547                 if (*field) {
548                         if (!(new_item = type->item_find(*field, cat))) {
549                                 if (!(new_item = type->item_alloc(cat))) {
550                                         ast_log(LOG_ERROR, "In %s: Could not create item for %s\n", file->filename, cat);
551                                         return -1;
552                                 }
553                                 if (aco_set_defaults(type, cat, new_item)) {
554                                         ast_log(LOG_ERROR, "In %s: Setting defaults for %s failed\n", file->filename, cat);
555                                         return -1;
556                                 }
557                                 new = 1;
558                         }
559                 }
560
561                 if (type->item_pre_process && type->item_pre_process(new_item)) {
562                         ast_log(LOG_ERROR, "In %s: Preprocess callback for %s failed\n", file->filename, cat);
563                         return -1;
564                 }
565
566                 if (aco_process_category_options(type, cfg, cat, new_item)) {
567                         ast_log(LOG_ERROR, "In %s: Processing options for %s failed\n", file->filename, cat);
568                         return -1;
569                 }
570
571                 if (type->item_prelink && type->item_prelink(new_item)) {
572                         ast_log(LOG_ERROR, "In %s: Pre-link callback for %s failed\n", file->filename, cat);
573                         return -1;
574                 }
575
576                 if (new && !ao2_link(*field, new_item)) {
577                         ast_log(LOG_ERROR, "In %s: Linking config for %s failed\n", file->filename, cat);
578                         return -1;
579                 }
580         }
581         return 0;
582 }
583
584 static int apply_config(struct aco_info *info)
585 {
586         ao2_global_obj_replace_unref(*info->global_obj, info->internal->pending);
587
588         return 0;
589 }
590
591 static enum aco_process_status internal_process_ast_config(struct aco_info *info, struct aco_file *file, struct ast_config *cfg)
592 {
593         const char *cat = NULL;
594
595         if (file->preload) {
596                 int i;
597                 for (i = 0; !ast_strlen_zero(file->preload[i]); i++) {
598                         if (process_category(cfg, info, file, file->preload[i], 1)) {
599                                 return ACO_PROCESS_ERROR;
600                         }
601                 }
602         }
603
604         while ((cat = ast_category_browse(cfg, cat))) {
605                 if (process_category(cfg, info, file, cat, 0)) {
606                         return ACO_PROCESS_ERROR;
607                 }
608         }
609         return ACO_PROCESS_OK;
610 }
611
612 enum aco_process_status aco_process_ast_config(struct aco_info *info, struct aco_file *file, struct ast_config *cfg)
613 {
614         if (!info->internal) {
615                 ast_log(LOG_ERROR, "Attempt to process %s with uninitialized aco_info\n", file->filename);
616                 goto error;
617         }
618
619         if (!(info->internal->pending = info->snapshot_alloc())) {
620                 ast_log(LOG_ERROR, "In %s: Could not allocate temporary objects\n", file->filename);
621                 goto error;
622         }
623
624         if (internal_process_ast_config(info, file, cfg)) {
625                 goto error;
626         }
627
628         if (info->pre_apply_config && info->pre_apply_config()) {
629                 goto error;
630         }
631
632         if (apply_config(info)) {
633                 goto error;
634         };
635
636         ao2_cleanup(info->internal->pending);
637         info->internal->pending = NULL;
638         return ACO_PROCESS_OK;
639
640 error:
641         ao2_cleanup(info->internal->pending);
642         info->internal->pending = NULL;
643
644         return ACO_PROCESS_ERROR;
645 }
646
647 enum aco_process_status aco_process_config(struct aco_info *info, int reload)
648 {
649         struct ast_config *cfg;
650         struct ast_flags cfg_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0, };
651         int res = ACO_PROCESS_OK;
652         int file_count = 0;
653         struct aco_file *file;
654
655         if (!info->internal) {
656                 ast_log(LOG_ERROR, "Attempting to process uninitialized aco_info\n");
657                 return ACO_PROCESS_ERROR;
658         }
659
660         if (!(info->files[0])) {
661                 ast_log(LOG_ERROR, "No filename given, cannot proceed!\n");
662                 return ACO_PROCESS_ERROR;
663         }
664
665         if (!(info->internal->pending = info->snapshot_alloc())) {
666                 ast_log(LOG_ERROR, "In %s: Could not allocate temporary objects\n", info->module);
667                 return ACO_PROCESS_ERROR;
668         }
669
670         while (res != ACO_PROCESS_ERROR && (file = info->files[file_count++])) {
671                 const char *filename = file->filename;
672                 struct aco_type *match;
673                 int i;
674
675                 /* set defaults for global objects */
676                 for (i = 0, match = file->types[i]; match; match = file->types[++i]) {
677                         void **field = info->internal->pending + match->item_offset;
678
679                         if (match->type == ACO_IGNORE) {
680                                 continue;
681                         }
682
683                         if (match->type != ACO_GLOBAL || !*field) {
684                                 continue;
685                         }
686
687                         if (aco_set_defaults(match, match->category, *field)) {
688                                 ast_log(LOG_ERROR, "In %s: Setting defaults for %s failed\n", file->filename, match->category);
689                                 res = ACO_PROCESS_ERROR;
690                                 break;
691                         }
692                 }
693
694                 if (res == ACO_PROCESS_ERROR) {
695                         break;
696                 }
697
698 try_alias:
699                 cfg = ast_config_load(filename, cfg_flags);
700                 if (!cfg || cfg == CONFIG_STATUS_FILEMISSING) {
701                         if (file->alias && strcmp(file->alias, filename)) {
702                                 filename = file->alias;
703                                 goto try_alias;
704                         }
705                         ast_log(LOG_ERROR, "Unable to load config file '%s'\n", file->filename);
706                         res = ACO_PROCESS_ERROR;
707                         break;
708                 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
709                         ast_debug(1, "%s was unchanged\n", file->filename);
710                         res = ACO_PROCESS_UNCHANGED;
711                         continue;
712                 } else if (cfg == CONFIG_STATUS_FILEINVALID) {
713                         ast_log(LOG_ERROR, "Contents of %s are invalid and cannot be parsed\n",
714                                 file->filename);
715                         res = ACO_PROCESS_ERROR;
716                         break;
717                 }
718
719                 /* A file got loaded. */
720                 if (reload) {
721                         /* Must do any subsequent file loads unconditionally. */
722                         reload = 0;
723                         ast_clear_flag(&cfg_flags, CONFIG_FLAG_FILEUNCHANGED);
724
725                         if (file_count != 1) {
726                                 /*
727                                  * Must restart loading to load all config files since a file
728                                  * after the first one changed.
729                                  */
730                                 file_count = 0;
731                         } else {
732                                 res = internal_process_ast_config(info, file, cfg);
733                         }
734                 } else {
735                         res = internal_process_ast_config(info, file, cfg);
736                 }
737                 ast_config_destroy(cfg);
738         }
739
740         if (res != ACO_PROCESS_OK) {
741                 goto end;
742         }
743
744         if (info->pre_apply_config && info->pre_apply_config()) {
745                 res = ACO_PROCESS_ERROR;
746                 goto end;
747         }
748
749         if (apply_config(info)) {
750                 res = ACO_PROCESS_ERROR;
751                 goto end;
752         }
753
754         if (info->post_apply_config) {
755                 info->post_apply_config();
756         }
757
758 end:
759         ao2_cleanup(info->internal->pending);
760         info->internal->pending = NULL;
761
762         return res;
763 }
764 int aco_process_var(struct aco_type *type, const char *cat, struct ast_variable *var, void *obj)
765 {
766         RAII_VAR(struct aco_option *, opt, aco_option_find(type, var->name), ao2_cleanup);
767         if (opt && opt->deprecated && !ast_strlen_zero(opt->aliased_to)) {
768                 const char *alias = ast_strdupa(opt->aliased_to);
769                 ast_log(LOG_WARNING, "At line %d of %s option '%s' is deprecated. Use '%s' instead\n", var->lineno, var->file, var->name, alias);
770                 ao2_ref(opt, -1);
771                 opt = aco_option_find(type, alias);
772         }
773
774         if (!opt) {
775                 ast_log(LOG_ERROR, "Could not find option suitable for category '%s' named '%s' at line %d of %s\n", cat, var->name, var->lineno, var->file);
776                 return -1;
777         }
778
779         if (!opt->handler) {
780                 /* It should be impossible for an option to not have a handler */
781                 ast_log(LOG_ERROR, "BUG! Somehow a config option for %s/%s was created with no handler!\n", cat, var->name);
782                 return -1;
783         }
784
785 #ifdef AST_DEVMODE
786         if (opt->doc_unavailable) {
787                 ast_log(LOG_ERROR, "Config option '%s' of type '%s' is not completely documented and can not be set\n", var->name, type->name);
788                 return -1;
789         }
790 #endif
791
792         if (opt->handler(opt, var, obj)) {
793                 ast_log(LOG_ERROR, "Error parsing %s=%s at line %d of %s\n", var->name, var->value, var->lineno, var->file);
794                 return -1;
795         }
796
797         return 0;
798 }
799
800 int aco_process_category_options(struct aco_type *type, struct ast_config *cfg, const char *cat, void *obj)
801 {
802         struct ast_variable *var;
803
804         for (var = ast_variable_browse(cfg, cat); var; var = var->next) {
805                 if (aco_process_var(type, cat, var, obj)) {
806                         return -1;
807                 }
808         }
809
810         return 0;
811 }
812
813 static void internal_type_destroy(struct aco_type *type)
814 {
815         /* If we've already had all our internal data cleared out,
816          * then there's no need to proceed further
817          */
818         if (!type->internal) {
819                 return;
820         }
821
822         if (type->internal->regex) {
823                 regfree(type->internal->regex);
824                 ast_free(type->internal->regex);
825         }
826         ao2_cleanup(type->internal->opts);
827         type->internal->opts = NULL;
828         ast_free(type->internal);
829         type->internal = NULL;
830 }
831
832 static void internal_file_types_destroy(struct aco_file *file)
833 {
834         size_t x;
835         struct aco_type *t;
836
837         for (x = 0, t = file->types[x]; t; t = file->types[++x]) {
838                 internal_type_destroy(t);
839                 t = NULL;
840         }
841 }
842
843 static int internal_type_init(struct aco_type *type)
844 {
845         if (!(type->internal = ast_calloc(1, sizeof(*type->internal)))) {
846                 return -1;
847         }
848
849         switch (type->category_match) {
850         case ACO_BLACKLIST:
851         case ACO_WHITELIST:
852                 if (!(type->internal->regex = build_regex(type->category))) {
853                         internal_type_destroy(type);
854                         return -1;
855                 }
856                 break;
857         case ACO_BLACKLIST_EXACT:
858         case ACO_WHITELIST_EXACT:
859         case ACO_BLACKLIST_ARRAY:
860         case ACO_WHITELIST_ARRAY:
861                 break;
862         }
863
864         if (!(type->internal->opts = aco_option_container_alloc())) {
865                 internal_type_destroy(type);
866                 return -1;
867         }
868
869         return 0;
870 }
871
872 int aco_info_init(struct aco_info *info)
873 {
874         size_t x = 0, y = 0;
875         struct aco_file *file;
876         struct aco_type *type;
877
878         if (!(info->internal = ast_calloc(1, sizeof(*info->internal)))) {
879                 return -1;
880         }
881
882         while ((file = info->files[x++])) {
883                 while ((type = file->types[y++])) {
884                         if (internal_type_init(type)) {
885                                 goto error;
886                         }
887 #ifdef AST_XML_DOCS
888                         if (!info->hidden &&
889                                 !type->hidden &&
890                                 type->type != ACO_IGNORE &&
891                                 xmldoc_update_config_type(info->module, type->name, type->category, type->matchfield, type->matchvalue, type->category_match)) {
892                                 goto error;
893                         }
894 #endif /* AST_XML_DOCS */
895                 }
896                 y = 0;
897         }
898
899         return 0;
900 error:
901         aco_info_destroy(info);
902         return -1;
903 }
904
905 void aco_info_destroy(struct aco_info *info)
906 {
907         int x;
908         /* It shouldn't be possible for internal->pending to be in use when this is called because
909          * of the locks in loader.c around reloads and unloads and the fact that internal->pending
910          * only exists while those locks are held */
911         ast_free(info->internal);
912         info->internal = NULL;
913
914         for (x = 0; info->files[x]; x++) {
915                 internal_file_types_destroy(info->files[x]);
916         }
917 }
918
919 int aco_set_defaults(struct aco_type *type, const char *category, void *obj)
920 {
921         struct aco_option *opt;
922         struct ao2_iterator iter;
923
924         if (!type->internal) {
925                 return -1;
926         }
927
928         iter = ao2_iterator_init(type->internal->opts, 0);
929
930         while ((opt = ao2_iterator_next(&iter))) {
931                 RAII_VAR(struct ast_variable *, var, NULL, ast_variables_destroy);
932
933                 if (ast_strlen_zero(opt->default_val)) {
934                         ao2_ref(opt, -1);
935                         continue;
936                 }
937                 if (!(var = ast_variable_new(opt->name, opt->default_val, ""))) {
938                         ao2_ref(opt, -1);
939                         ao2_iterator_destroy(&iter);
940                         return -1;
941                 }
942                 if (opt->handler(opt, var, obj)) {
943                         ast_log(LOG_ERROR, "Unable to set default for %s, %s=%s\n", category, var->name, var->value);
944                         ao2_ref(opt, -1);
945                         ao2_iterator_destroy(&iter);
946                         return -1;
947                 }
948                 ao2_ref(opt, -1);
949         }
950         ao2_iterator_destroy(&iter);
951
952         return 0;
953 }
954
955 #ifdef AST_XML_DOCS
956
957 /*! \internal
958  * \brief Complete the name of the module the user is looking for
959  */
960 static char *complete_config_module(const char *word, int pos, int state)
961 {
962         char *c = NULL;
963         size_t wordlen = strlen(word);
964         int which = 0;
965         struct ao2_iterator i;
966         struct ast_xml_doc_item *cur;
967
968         if (pos != 3) {
969                 return NULL;
970         }
971
972         i = ao2_iterator_init(xmldocs, 0);
973         while ((cur = ao2_iterator_next(&i))) {
974                 if (!strncasecmp(word, cur->name, wordlen) && ++which > state) {
975                         c = ast_strdup(cur->name);
976                         ao2_ref(cur, -1);
977                         break;
978                 }
979                 ao2_ref(cur, -1);
980         }
981         ao2_iterator_destroy(&i);
982
983         return c;
984 }
985
986 /*! \internal
987  * \brief Complete the name of the configuration type the user is looking for
988  */
989 static char *complete_config_type(const char *module, const char *word, int pos, int state)
990 {
991         char *c = NULL;
992         size_t wordlen = strlen(word);
993         int which = 0;
994         RAII_VAR(struct ast_xml_doc_item *, info, NULL, ao2_cleanup);
995         struct ast_xml_doc_item *cur;
996
997         if (pos != 4) {
998                 return NULL;
999         }
1000
1001         if (!(info = ao2_find(xmldocs, module, OBJ_KEY))) {
1002                 return NULL;
1003         }
1004
1005         cur = info;
1006         while ((cur = AST_LIST_NEXT(cur, next))) {
1007                 if (!strcasecmp(cur->type, "configObject") && !strncasecmp(word, cur->name, wordlen) && ++which > state) {
1008                         c = ast_strdup(cur->name);
1009                         break;
1010                 }
1011         }
1012         return c;
1013 }
1014
1015 /*! \internal
1016  * \brief Complete the name of the configuration option the user is looking for
1017  */
1018 static char *complete_config_option(const char *module, const char *option, const char *word, int pos, int state)
1019 {
1020         char *c = NULL;
1021         size_t wordlen = strlen(word);
1022         int which = 0;
1023         RAII_VAR(struct ast_xml_doc_item *, info, NULL, ao2_cleanup);
1024         struct ast_xml_doc_item *cur;
1025
1026         if (pos != 5) {
1027                 return NULL;
1028         }
1029
1030         if (!(info = ao2_find(xmldocs, module, OBJ_KEY))) {
1031                 return NULL;
1032         }
1033
1034         cur = info;
1035         while ((cur = AST_LIST_NEXT(cur, next))) {
1036                 if (!strcasecmp(cur->type, "configOption") && !strcasecmp(cur->ref, option) && !strncasecmp(word, cur->name, wordlen) && ++which > state) {
1037                         c = ast_strdup(cur->name);
1038                         break;
1039                 }
1040         }
1041         return c;
1042 }
1043
1044 /* Define as 0 if we want to allow configurations to be registered without
1045  * documentation
1046  */
1047 #define XMLDOC_STRICT 1
1048
1049 /*! \internal
1050  * \brief Update the XML documentation for a config type based on its registration
1051  */
1052 static int xmldoc_update_config_type(const char *module, const char *name, const char *category, const char *matchfield, const char *matchvalue, enum aco_category_op category_match)
1053 {
1054         RAII_VAR(struct ast_xml_xpath_results *, results, NULL, ast_xml_xpath_results_free);
1055         RAII_VAR(struct ast_xml_doc_item *, config_info, ao2_find(xmldocs, module, OBJ_KEY), ao2_cleanup);
1056         struct ast_xml_doc_item *config_type;
1057         struct ast_xml_node *type, *syntax, *matchinfo, *tmp;
1058
1059         /* If we already have a syntax element, bail. This isn't an error, since we may unload a module which
1060          * has updated the docs and then load it again. */
1061         if ((results = ast_xmldoc_query("/docs/configInfo[@name='%s']/configFile/configObject[@name='%s']/syntax", module, name))) {
1062                 return 0;
1063         }
1064
1065         if (!(results = ast_xmldoc_query("/docs/configInfo[@name='%s']/configFile/configObject[@name='%s']", module, name))) {
1066                 ast_log(LOG_WARNING, "Cannot update type '%s' in module '%s' because it has no existing documentation!\n", name, module);
1067                 return XMLDOC_STRICT ? -1 : 0;
1068         }
1069
1070         if (!(type = ast_xml_xpath_get_first_result(results))) {
1071                 ast_log(LOG_WARNING, "Could not retrieve documentation for type '%s' in module '%s'\n", name, module);
1072                 return XMLDOC_STRICT ? -1 : 0;
1073         }
1074
1075         if (!(syntax = ast_xml_new_child(type, "syntax"))) {
1076                 ast_log(LOG_WARNING, "Could not create syntax node for type '%s' in module '%s'\n", name, module);
1077                 return XMLDOC_STRICT ? -1 : 0;
1078         }
1079
1080         if (!(matchinfo = ast_xml_new_child(syntax, "matchInfo"))) {
1081                 ast_log(LOG_WARNING, "Could not create matchInfo node for type '%s' in module '%s'\n", name, module);
1082                 return XMLDOC_STRICT ? -1 : 0;
1083         }
1084
1085         if (!(tmp = ast_xml_new_child(matchinfo, "category"))) {
1086                 ast_log(LOG_WARNING, "Could not create category node for type '%s' in module '%s'\n", name, module);
1087                 return XMLDOC_STRICT ? -1 : 0;
1088         }
1089
1090         ast_xml_set_text(tmp, category);
1091         switch (category_match) {
1092         case ACO_WHITELIST:
1093         case ACO_WHITELIST_EXACT:
1094         case ACO_WHITELIST_ARRAY:
1095                 ast_xml_set_attribute(tmp, "match", "true");
1096                 break;
1097         case ACO_BLACKLIST:
1098         case ACO_BLACKLIST_EXACT:
1099         case ACO_BLACKLIST_ARRAY:
1100                 ast_xml_set_attribute(tmp, "match", "false");
1101                 break;
1102         }
1103
1104         if (!ast_strlen_zero(matchfield) && !(tmp = ast_xml_new_child(matchinfo, "field"))) {
1105                 ast_log(LOG_WARNING, "Could not add %s attribute for type '%s' in module '%s'\n", matchfield, name, module);
1106                 return XMLDOC_STRICT ? -1 : 0;
1107         }
1108
1109         ast_xml_set_attribute(tmp, "name", matchfield);
1110         ast_xml_set_text(tmp, matchvalue);
1111
1112         if (!config_info || !(config_type = find_xmldoc_type(config_info, name))) {
1113                 ast_log(LOG_WARNING, "Could not obtain XML documentation item for config type %s\n", name);
1114                 return XMLDOC_STRICT ? -1 : 0;
1115         }
1116
1117         if (ast_xmldoc_regenerate_doc_item(config_type)) {
1118                 ast_log(LOG_WARNING, "Could not update type '%s' with values from config type registration\n", name);
1119                 return XMLDOC_STRICT ? -1 : 0;
1120         }
1121
1122         return 0;
1123 }
1124
1125 /*! \internal
1126  * \brief Update the XML documentation for a config option based on its registration
1127  */
1128 static int xmldoc_update_config_option(struct aco_type **types, const char *module, const char *name, const char *object_name, const char *default_value, unsigned int regex, enum aco_option_type type)
1129 {
1130         RAII_VAR(struct ast_xml_xpath_results *, results, NULL, ast_xml_xpath_results_free);
1131         RAII_VAR(struct ast_xml_doc_item *, config_info, ao2_find(xmldocs, module, OBJ_KEY), ao2_cleanup);
1132         struct ast_xml_doc_item * config_option;
1133         struct ast_xml_node *option;
1134
1135         ast_assert(ARRAY_LEN(aco_option_type_string) > type);
1136
1137         if (!config_info || !(config_option = find_xmldoc_option(config_info, types, name))) {
1138                 ast_log(LOG_ERROR, "XML Documentation for option '%s' in modules '%s' not found!\n", name, module);
1139                 return XMLDOC_STRICT ? -1 : 0;
1140         }
1141
1142         if (!(results = ast_xmldoc_query("/docs/configInfo[@name='%s']/configFile/configObject[@name='%s']/configOption[@name='%s']", module, object_name, name))) {
1143                 ast_log(LOG_WARNING, "Could not find option '%s' with type '%s' in module '%s'\n", name, object_name, module);
1144                 return XMLDOC_STRICT ? -1 : 0;
1145         }
1146
1147         if (!(option = ast_xml_xpath_get_first_result(results))) {
1148                 ast_log(LOG_WARNING, "Could not obtain results for option '%s' with type '%s' in module '%s'\n", name, object_name, module);
1149                 return XMLDOC_STRICT ? -1 : 0;
1150         }
1151         ast_xml_set_attribute(option, "regex", regex ? "true" : "false");
1152         ast_xml_set_attribute(option, "default", default_value);
1153         ast_xml_set_attribute(option, "type", aco_option_type_string[type]);
1154
1155         if (ast_xmldoc_regenerate_doc_item(config_option)) {
1156                 ast_log(LOG_WARNING, "Could not update option '%s' with values from config option registration\n", name);
1157                 return XMLDOC_STRICT ? -1 : 0;
1158         }
1159
1160         return 0;
1161 }
1162
1163 /*! \internal
1164  * \brief Show the modules with configuration information
1165  */
1166 static void cli_show_modules(struct ast_cli_args *a)
1167 {
1168         struct ast_xml_doc_item *item;
1169         struct ao2_iterator it_items;
1170
1171         ast_assert(a->argc == 3);
1172
1173         if (ao2_container_count(xmldocs) == 0) {
1174                 ast_cli(a->fd, "No modules found.\n");
1175                 return;
1176         }
1177
1178         it_items = ao2_iterator_init(xmldocs, 0);
1179         ast_cli(a->fd, "The following modules have configuration information:\n");
1180         while ((item = ao2_iterator_next(&it_items))) {
1181                 ast_cli(a->fd, "\t%s\n", item->name);
1182                 ao2_ref(item, -1);
1183         }
1184         ao2_iterator_destroy(&it_items);
1185 }
1186
1187 /*! \internal
1188  * \brief Show the configuration types for a module
1189  */
1190 static void cli_show_module_types(struct ast_cli_args *a)
1191 {
1192         RAII_VAR(struct ast_xml_doc_item *, item, NULL, ao2_cleanup);
1193         struct ast_xml_doc_item *tmp;
1194
1195         ast_assert(a->argc == 4);
1196
1197         if (!(item = ao2_find(xmldocs, a->argv[3], OBJ_KEY))) {
1198                 ast_cli(a->fd, "Module %s not found.\n", a->argv[3]);
1199                 return;
1200         }
1201
1202         if (ast_str_strlen(item->synopsis)) {
1203                 ast_cli(a->fd, "%s\n\n", ast_xmldoc_printable(ast_str_buffer(item->synopsis), 1));
1204         }
1205         if (ast_str_strlen(item->description)) {
1206                 ast_cli(a->fd, "%s\n\n", ast_xmldoc_printable(ast_str_buffer(item->description), 1));
1207         }
1208
1209         tmp = item;
1210         ast_cli(a->fd, "Configuration option types for %s:\n", tmp->name);
1211         while ((tmp = AST_LIST_NEXT(tmp, next))) {
1212                 if (!strcasecmp(tmp->type, "configObject")) {
1213                         ast_cli(a->fd, "%-25s -- %-65.65s\n", tmp->name,
1214                                 ast_str_buffer(tmp->synopsis));
1215                 }
1216         }
1217 }
1218
1219 /*! \internal
1220  * \brief Show the information for a configuration type
1221  */
1222 static void cli_show_module_type(struct ast_cli_args *a)
1223 {
1224         RAII_VAR(struct ast_xml_doc_item *, item, NULL, ao2_cleanup);
1225         struct ast_xml_doc_item *tmp;
1226         char option_type[64];
1227         int match = 0;
1228
1229         ast_assert(a->argc == 5);
1230
1231         if (!(item = ao2_find(xmldocs, a->argv[3], OBJ_KEY))) {
1232                 ast_cli(a->fd, "Unknown module %s\n", a->argv[3]);
1233                 return;
1234         }
1235
1236         tmp = item;
1237         while ((tmp = AST_LIST_NEXT(tmp, next))) {
1238                 if (!strcasecmp(tmp->type, "configObject") && !strcasecmp(tmp->name, a->argv[4])) {
1239                         match = 1;
1240                         term_color(option_type, tmp->name, COLOR_MAGENTA, COLOR_BLACK, sizeof(option_type));
1241                         ast_cli(a->fd, "%s", option_type);
1242                         if (ast_str_strlen(tmp->syntax)) {
1243                                 ast_cli(a->fd, ": [%s]\n\n", ast_xmldoc_printable(ast_str_buffer(tmp->syntax), 1));
1244                         } else {
1245                                 ast_cli(a->fd, "\n\n");
1246                         }
1247                         if (ast_str_strlen(tmp->synopsis)) {
1248                                 ast_cli(a->fd, "%s\n\n", ast_xmldoc_printable(ast_str_buffer(tmp->synopsis), 1));
1249                         }
1250                         if (ast_str_strlen(tmp->description)) {
1251                                 ast_cli(a->fd, "%s\n\n", ast_xmldoc_printable(ast_str_buffer(tmp->description), 1));
1252                         }
1253                 }
1254         }
1255
1256         if (!match) {
1257                 ast_cli(a->fd, "Unknown configuration type %s\n", a->argv[4]);
1258                 return;
1259         }
1260
1261         /* Now iterate over the options for the type */
1262         tmp = item;
1263         while ((tmp = AST_LIST_NEXT(tmp, next))) {
1264                 if (!strcasecmp(tmp->type, "configOption") && !strcasecmp(tmp->ref, a->argv[4])) {
1265                         ast_cli(a->fd, "%-25s -- %-65.65s\n", tmp->name,
1266                                         ast_str_buffer(tmp->synopsis));
1267                 }
1268         }
1269 }
1270
1271 /*! \internal
1272  * \brief Show detailed information for an option
1273  */
1274 static void cli_show_module_options(struct ast_cli_args *a)
1275 {
1276         RAII_VAR(struct ast_xml_doc_item *, item, NULL, ao2_cleanup);
1277         struct ast_xml_doc_item *tmp;
1278         char option_name[64];
1279         int match = 0;
1280
1281         ast_assert(a->argc == 6);
1282
1283         if (!(item = ao2_find(xmldocs, a->argv[3], OBJ_KEY))) {
1284                 ast_cli(a->fd, "Unknown module %s\n", a->argv[3]);
1285                 return;
1286         }
1287         tmp = item;
1288         while ((tmp = AST_LIST_NEXT(tmp, next))) {
1289                 if (!strcasecmp(tmp->type, "configOption") && !strcasecmp(tmp->ref, a->argv[4]) && !strcasecmp(tmp->name, a->argv[5])) {
1290                         if (match) {
1291                                 ast_cli(a->fd, "\n");
1292                         }
1293                         term_color(option_name, tmp->ref, COLOR_MAGENTA, COLOR_BLACK, sizeof(option_name));
1294                         ast_cli(a->fd, "[%s%s]\n", option_name, ast_term_reset());
1295                         if (ast_str_strlen(tmp->syntax)) {
1296                                 ast_cli(a->fd, "%s\n", ast_xmldoc_printable(ast_str_buffer(tmp->syntax), 1));
1297                         }
1298                         ast_cli(a->fd, "%s\n\n", ast_xmldoc_printable(AS_OR(tmp->synopsis, "No information available"), 1));
1299                         if (ast_str_strlen(tmp->description)) {
1300                                 ast_cli(a->fd, "%s\n\n", ast_xmldoc_printable(ast_str_buffer(tmp->description), 1));
1301                         }
1302
1303                         if (ast_str_strlen(tmp->seealso)) {
1304                                 ast_cli(a->fd, "See Also:\n");
1305                                 ast_cli(a->fd, "%s\n\n", ast_xmldoc_printable(ast_str_buffer(tmp->seealso), 1));
1306                         }
1307
1308                         match = 1;
1309                 }
1310         }
1311
1312         if (!match) {
1313                 ast_cli(a->fd, "No option %s found for %s:%s\n", a->argv[5], a->argv[3], a->argv[4]);
1314         }
1315 }
1316
1317 static char *cli_show_help(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1318 {
1319         switch (cmd) {
1320         case CLI_INIT:
1321                 e->command = "config show help";
1322                 e->usage =
1323                         "Usage: config show help [<module> [<type> [<option>]]]\n"
1324                         "   Display detailed information about module configuration.\n"
1325                         "     * If nothing is specified, the modules that have\n"
1326                         "       configuration information are listed.\n"
1327                         "     * If <module> is specified, the configuration types\n"
1328                         "       for that module will be listed, along with brief\n"
1329                         "       information about that type.\n"
1330                         "     * If <module> and <type> are specified, detailed\n"
1331                         "       information about the type is displayed, as well\n"
1332                         "       as the available options.\n"
1333                         "     * If <module>, <type>, and <option> are specified,\n"
1334                         "       detailed information will be displayed about that\n"
1335                         "       option.\n"
1336                         "   NOTE: the help documentation is partially generated at run\n"
1337                         "     time when a module is loaded. If a module is not loaded,\n"
1338                         "     configuration help for that module may be incomplete.\n";
1339                 return NULL;
1340         case CLI_GENERATE:
1341                 switch(a->pos) {
1342                 case 3: return complete_config_module(a->word, a->pos, a->n);
1343                 case 4: return complete_config_type(a->argv[3], a->word, a->pos, a->n);
1344                 case 5: return complete_config_option(a->argv[3], a->argv[4], a->word, a->pos, a->n);
1345                 default: return NULL;
1346                 }
1347         }
1348
1349         switch (a->argc) {
1350         case 3:
1351                 cli_show_modules(a);
1352                 break;
1353         case 4:
1354                 cli_show_module_types(a);
1355                 break;
1356         case 5:
1357                 cli_show_module_type(a);
1358                 break;
1359         case 6:
1360                 cli_show_module_options(a);
1361                 break;
1362         default:
1363                 return CLI_SHOWUSAGE;
1364         }
1365
1366         return CLI_SUCCESS;
1367 }
1368
1369 static struct ast_cli_entry cli_aco[] = {
1370         AST_CLI_DEFINE(cli_show_help, "Show configuration help for a module"),
1371 };
1372
1373 static void aco_deinit(void)
1374 {
1375         ast_cli_unregister(cli_aco);
1376         ao2_cleanup(xmldocs);
1377 }
1378 #endif /* AST_XML_DOCS */
1379
1380 int aco_init(void)
1381 {
1382 #ifdef AST_XML_DOCS
1383         ast_register_cleanup(aco_deinit);
1384         if (!(xmldocs = ast_xmldoc_build_documentation("configInfo"))) {
1385                 ast_log(LOG_ERROR, "Couldn't build config documentation\n");
1386                 return -1;
1387         }
1388         ast_cli_register_multiple(cli_aco, ARRAY_LEN(cli_aco));
1389 #endif /* AST_XML_DOCS */
1390         return 0;
1391 }
1392
1393 /* Default config option handlers */
1394
1395 /*! \brief Default option handler for signed integers
1396  * \note For a description of the opt->flags and opt->args values, see the documentation for
1397  * enum aco_option_type in config_options.h
1398  */
1399 static int int_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj) {
1400         int *field = (int *)(obj + opt->args[0]);
1401         unsigned int flags = PARSE_INT32 | opt->flags;
1402         int res = 0;
1403         if (opt->flags & PARSE_IN_RANGE) {
1404                 res = opt->flags & PARSE_DEFAULT ?
1405                         ast_parse_arg(var->value, flags, field, (int) opt->args[1], (int) opt->args[2], opt->args[3]) :
1406                         ast_parse_arg(var->value, flags, field, (int) opt->args[1], (int) opt->args[2]);
1407                 if (res) {
1408                         if (opt->flags & PARSE_RANGE_DEFAULTS) {
1409                                 ast_log(LOG_WARNING, "Failed to set %s=%s. Set to %d instead due to range limit (%d, %d)\n", var->name, var->value, *field, (int) opt->args[1], (int) opt->args[2]);
1410                                 res = 0;
1411                         } else if (opt->flags & PARSE_DEFAULT) {
1412                                 ast_log(LOG_WARNING, "Failed to set %s=%s, Set to default value %d instead.\n", var->name, var->value, *field);
1413                                 res = 0;
1414                         }
1415                 }
1416         } else if ((opt->flags & PARSE_DEFAULT) && ast_parse_arg(var->value, flags, field, (int) opt->args[1])) {
1417                 ast_log(LOG_WARNING, "Attempted to set %s=%s, but set it to %d instead due to default)\n", var->name, var->value, *field);
1418         } else {
1419                 res = ast_parse_arg(var->value, flags, field);
1420         }
1421
1422         return res;
1423 }
1424
1425 /*! \brief Default option handler for unsigned integers
1426  * \note For a description of the opt->flags and opt->args values, see the documentation for
1427  * enum aco_option_type in config_options.h
1428  */
1429 static int uint_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj) {
1430         unsigned int *field = (unsigned int *)(obj + opt->args[0]);
1431         unsigned int flags = PARSE_UINT32 | opt->flags;
1432         int res = 0;
1433         if (opt->flags & PARSE_IN_RANGE) {
1434                 res = opt->flags & PARSE_DEFAULT ?
1435                         ast_parse_arg(var->value, flags, field, (unsigned int) opt->args[1], (unsigned int) opt->args[2], opt->args[3]) :
1436                         ast_parse_arg(var->value, flags, field, (unsigned int) opt->args[1], (unsigned int) opt->args[2]);
1437                 if (res) {
1438                         if (opt->flags & PARSE_RANGE_DEFAULTS) {
1439                                 ast_log(LOG_WARNING, "Failed to set %s=%s. Set to %u instead due to range limit (%d, %d)\n", var->name, var->value, *field, (int) opt->args[1], (int) opt->args[2]);
1440                                 res = 0;
1441                         } else if (opt->flags & PARSE_DEFAULT) {
1442                                 ast_log(LOG_WARNING, "Failed to set %s=%s, Set to default value %u instead.\n", var->name, var->value, *field);
1443                                 res = 0;
1444                         }
1445                 }
1446         } else if ((opt->flags & PARSE_DEFAULT) && ast_parse_arg(var->value, flags, field, (unsigned int) opt->args[1])) {
1447                 ast_log(LOG_WARNING, "Attempted to set %s=%s, but set it to %u instead due to default)\n", var->name, var->value, *field);
1448         } else {
1449                 res = ast_parse_arg(var->value, flags, field);
1450         }
1451
1452         return res;
1453 }
1454
1455 /*! \brief Default option handler for timelen signed integers
1456  * \note For a description of the opt->flags and opt->args values, see the documentation for
1457  * enum aco_option_type in config_options.h
1458  */
1459 static int timelen_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj)
1460 {
1461         int *field = (int *)(obj + opt->args[0]);
1462         unsigned int flags = PARSE_TIMELEN | opt->flags;
1463         int res = 0;
1464         if (opt->flags & PARSE_IN_RANGE) {
1465                 if (opt->flags & PARSE_DEFAULT) {
1466                         res = ast_parse_arg(var->value, flags, field, (enum ast_timelen) opt->args[1], (int) opt->args[2], (int) opt->args[3], opt->args[4]);
1467                 } else {
1468                         res = ast_parse_arg(var->value, flags, field, (enum ast_timelen) opt->args[1], (int) opt->args[2], (int) opt->args[3]);
1469                 }
1470                 if (res) {
1471                         if (opt->flags & PARSE_RANGE_DEFAULTS) {
1472                                 ast_log(LOG_WARNING, "Failed to set %s=%s. Set to %d instead due to range limit (%d, %d)\n", var->name, var->value, *field, (int) opt->args[2], (int) opt->args[3]);
1473                                 res = 0;
1474                         } else if (opt->flags & PARSE_DEFAULT) {
1475                                 ast_log(LOG_WARNING, "Failed to set %s=%s, Set to default value %d instead.\n", var->name, var->value, *field);
1476                                 res = 0;
1477                         }
1478                 }
1479         } else if ((opt->flags & PARSE_DEFAULT) && ast_parse_arg(var->value, flags, field, (enum ast_timelen) opt->args[1], (int) opt->args[2])) {
1480                 ast_log(LOG_WARNING, "Attempted to set %s=%s, but set it to %d instead due to default)\n", var->name, var->value, *field);
1481         } else {
1482                 res = ast_parse_arg(var->value, flags, field, (enum ast_timelen) opt->args[1]);
1483         }
1484
1485         return res;
1486 }
1487
1488 /*! \brief Default option handler for doubles
1489  * \note For a description of the opt->flags and opt->args values, see the documentation for
1490  * enum aco_option_type in config_options.h
1491  */
1492 static int double_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj) {
1493         double *field = (double *)(obj + opt->args[0]);
1494         return ast_parse_arg(var->value, PARSE_DOUBLE | opt->flags, field);
1495 }
1496
1497 /*! \brief Default handler for ACLs
1498  * \note For a description of the opt->flags and opt->args values, see the documentation for
1499  * enum aco_option_type in config_options.h
1500  */
1501 static int acl_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj) {
1502         struct ast_ha **ha = (struct ast_ha **)(obj + opt->args[0]);
1503         int error = 0;
1504         *ha = ast_append_ha(opt->flags ? "permit" : "deny", var->value, *ha, &error);
1505         return error;
1506 }
1507
1508 /*! \brief Default option handler for codec preferences/capabilities
1509  * \note For a description of the opt->flags and opt->args values, see the documentation for
1510  * enum aco_option_type in config_options.h
1511  */
1512 static int codec_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj) {
1513         struct ast_format_cap **cap = (struct ast_format_cap **)(obj + opt->args[0]);
1514         return ast_format_cap_update_by_allow_disallow(*cap, var->value, opt->flags);
1515 }
1516
1517 /*! \brief Default option handler for stringfields
1518  * \note For a description of the opt->flags and opt->args values, see the documentation for
1519  * enum aco_option_type in config_options.h
1520  */
1521 static int stringfield_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj)
1522 {
1523         ast_string_field *field = (const char **)(obj + opt->args[0]);
1524         struct ast_string_field_pool **pool = (struct ast_string_field_pool **)(obj + opt->args[1]);
1525         struct ast_string_field_mgr *mgr = (struct ast_string_field_mgr *)(obj + opt->args[2]);
1526
1527         if (opt->flags && ast_strlen_zero(var->value)) {
1528                 return -1;
1529         }
1530         ast_string_field_ptr_set_by_fields(*pool, *mgr, field, var->value);
1531         return 0;
1532 }
1533
1534 /*! \brief Default option handler for bools (ast_true/ast_false)
1535  * \note For a description of the opt->flags and opt->args values, see the documentation for
1536  * enum aco_option_type in config_options.h
1537  */
1538 static int bool_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj)
1539 {
1540         unsigned int *field = (unsigned int *)(obj + opt->args[0]);
1541         *field = opt->flags ? ast_true(var->value) : ast_false(var->value);
1542         return 0;
1543 }
1544
1545 /*! \brief Default option handler for bools (ast_true/ast_false) that are stored as flags
1546  * \note For a description of the opt->flags and opt->args values, see the documentation for
1547  * enum aco_option_type in config_options.h
1548  */
1549 static int boolflag_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj)
1550 {
1551         unsigned int *flags_field = (unsigned int *)(obj + opt->args[0]);
1552         unsigned int val = opt->flags ? ast_true(var->value) : ast_false(var->value);
1553         unsigned int flag = opt->args[1];
1554         if (val) {
1555                 *flags_field |= flag;
1556         } else {
1557                 *flags_field &= ~flag;
1558         }
1559         return 0;
1560 }
1561
1562 /*! \brief Default handler for ast_sockaddrs
1563  * \note For a description of the opt->flags and opt->args values, see the documentation for
1564  * enum aco_option_type in config_options.h
1565  */
1566 static int sockaddr_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj)
1567 {
1568         struct ast_sockaddr *field = (struct ast_sockaddr *)(obj + opt->args[0]);
1569         return ast_parse_arg(var->value, PARSE_ADDR | opt->flags, field);
1570 }
1571
1572 /*! \brief Default handler for doing nothing
1573  */
1574 static int noop_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj)
1575 {
1576         return 0;
1577 }
1578
1579 /*! \brief Default handler for character arrays
1580  * \note For a description of the opt->flags and opt->args values, see the documentation for
1581  * enum aco_option_type in config_options.h
1582  */
1583 static int chararray_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj)
1584 {
1585         char *field = (char *)(obj + opt->args[0]);
1586         size_t len = opt->args[1];
1587
1588         if (opt->flags && ast_strlen_zero(var->value)) {
1589                 return -1;
1590         }
1591         ast_copy_string(field, var->value, len);
1592         return 0;
1593 }