45 #define CONFIG_OPT_BUCKETS 5
47 #define CONFIG_OPT_BUCKETS 53
64 const char *aliased_to;
65 const char *default_val;
72 unsigned int no_doc:1;
74 unsigned int doc_unavailable:1;
76 unsigned char deprecated:1;
105 if (!(info && info->internal)) {
106 ast_log(LOG_ERROR,
"This may not be called without an initialized aco_info!\n");
109 return info->internal->
pending;
112 static void config_option_destroy(
void *obj)
115 if (opt->match_type == ACO_REGEX && opt->name_regex) {
116 regfree(opt->name_regex);
117 ast_free(opt->name_regex);
135 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);
136 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);
165 static regex_t *build_regex(
const char *text)
174 if ((res = regcomp(regex, text, REG_EXTENDED | REG_ICASE | REG_NOSUB))) {
175 size_t len = regerror(res, regex, NULL, 0);
177 regerror(res, regex, buf, len);
178 ast_log(LOG_ERROR,
"Could not compile regex '%s': %s\n", text, buf);
191 while ((type = types[idx++])) {
192 if (!type->internal) {
193 ast_log(LOG_ERROR,
"Attempting to register option using uninitialized type\n");
198 ao2_unlink(types[idx - 1]->internal->opts, opt);
203 if (!info->
hidden && !opt->no_doc &&
204 xmldoc_update_config_option(types, info->
module, opt->name, type->
name, opt->default_val, opt->match_type == ACO_REGEX, opt->type)) {
206 opt->doc_unavailable = 1;
221 if (!info || ast_strlen_zero(name) || ast_strlen_zero(aliased_to)) {
231 opt->aliased_to = aliased_to;
233 opt->match_type = ACO_EXACT;
235 if (link_option_to_types(info, types, opt)) {
245 return option->flags;
250 return option->args[position];
267 if (strcasecmp(iter->
name, name)) {
270 for (x = 0; types[x]; x++) {
272 if (!strcasecmp(types[x]->name, iter->
ref)) {
291 if (!strcasecmp(iter->
type,
"configObject") && !strcasecmp(iter->
name, name)) {
302 unsigned int no_doc,
size_t argc, ...)
313 if (!(types && types[0])) {
317 opt = ao2_alloc_options(
sizeof(*opt) + argc *
sizeof(opt->args[0]),
323 if (matchtype == ACO_REGEX && !(opt->name_regex = build_regex(name))) {
329 for (tmp = 0; tmp < argc; tmp++) {
330 opt->args[tmp] = va_arg(ap,
size_t);
335 opt->match_type = matchtype;
336 opt->default_val = default_val;
338 opt->handler = handler;
341 opt->no_doc = no_doc;
343 if (!opt->handler && !(opt->handler = ast_config_option_default_handler(opt->type))) {
345 ast_log(LOG_ERROR,
"No handler provided, and no default handler exists for type %u\n", opt->type);
350 if (link_option_to_types(info, types, opt)) {
358 static int config_opt_hash(
const void *obj,
const int flags)
361 const char *name = (flags &
OBJ_KEY) ? obj : opt->name;
365 static int config_opt_cmp(
void *obj,
void *arg,
int flags)
368 const char *name = (flags &
OBJ_KEY) ? arg : opt2->name;
372 static int find_option_cb(
void *obj,
void *arg,
int flags)
375 const char *name = arg;
377 switch (match->match_type) {
381 return strncasecmp(name, match->name, strlen(match->name)) ? 0 :
CMP_MATCH |
CMP_STOP;
385 ast_log(LOG_ERROR,
"Unknown match type. This should not be possible.\n");
393 if (!type || !type->internal || !type->internal->
opts) {
394 ast_log(LOG_NOTICE,
"Attempting to use NULL or unitialized config type\n");
409 config_opt_hash, NULL, config_opt_cmp);
412 static int internal_aco_type_category_check(
struct aco_type *match,
const char *category)
414 const char **categories = (
const char **)match->
category;
418 return regexec(match->internal->regex, category, 0, NULL, 0);
421 return !regexec(match->internal->regex, category, 0, NULL, 0);
424 return strcasecmp(match->
category, category);
427 return !strcasecmp(match->
category, category);
430 while (*categories) {
431 if (!strcasecmp(*categories, category)) {
439 while (*categories) {
440 if (!strcasecmp(*categories, category)) {
457 for (x = 0, match = file->
types[x]; match; match = file->
types[++x]) {
459 if (internal_aco_type_category_check(match, category)) {
465 if (!(val = ast_variable_retrieve(cfg, category, match->
matchfield))) {
466 ast_log(LOG_ERROR,
"Required match field '%s' not found\n", match->
matchfield);
473 }
else if (strcasecmp(val, match->
matchvalue)) {
484 static int is_preload(
struct aco_file *file,
const char *cat)
492 for (i = 0; !ast_strlen_zero(file->
preload[i]); i++) {
493 if (!strcasecmp(cat, file->
preload[i])) {
500 static int process_category(
struct ast_config *cfg,
struct aco_info *info,
struct aco_file *file,
const char *cat,
int preload) {
501 RAII_VAR(
void *, new_item, NULL, ao2_cleanup);
510 if (!preload && is_preload(file, cat)) {
517 if (!regexec(regex_skip, cat, 0, NULL, 0)) {
519 ast_free(regex_skip);
523 ast_free(regex_skip);
527 if (!(type = internal_aco_type_find(file, cfg, cat))) {
528 ast_log(LOG_ERROR,
"Could not find config type for category '%s' in '%s'\n", cat, file->
filename);
532 if (type->
type == ACO_IGNORE) {
538 ast_log(LOG_ERROR,
"In %s: %s - No object to update!\n", file->
filename, cat);
542 if (type->
type == ACO_GLOBAL && *field) {
544 ast_log(LOG_ERROR,
"In %s: Processing options for %s failed\n", file->
filename, cat);
547 }
else if (type->
type == ACO_ITEM) {
553 if (!(new_item = type->
item_find(*field, cat))) {
555 ast_log(LOG_ERROR,
"In %s: Could not create item for %s\n", file->
filename, cat);
559 ast_log(LOG_ERROR,
"In %s: Setting defaults for %s failed\n", file->
filename, cat);
567 ast_log(LOG_ERROR,
"In %s: Preprocess callback for %s failed\n", file->
filename, cat);
572 ast_log(LOG_ERROR,
"In %s: Processing options for %s failed\n", file->
filename, cat);
577 ast_log(LOG_ERROR,
"In %s: Pre-link callback for %s failed\n", file->
filename, cat);
581 if (
new && !
ao2_link(*field, new_item)) {
582 ast_log(LOG_ERROR,
"In %s: Linking config for %s failed\n", file->
filename, cat);
589 static int apply_config(
struct aco_info *info)
598 const char *cat = NULL;
602 for (i = 0; !ast_strlen_zero(file->
preload[i]); i++) {
603 if (process_category(cfg, info, file, file->
preload[i], 1)) {
610 if (process_category(cfg, info, file, cat, 0)) {
619 if (!info->internal) {
620 ast_log(LOG_ERROR,
"Attempt to process %s with uninitialized aco_info\n", file->
filename);
625 ast_log(LOG_ERROR,
"In %s: Could not allocate temporary objects\n", file->
filename);
629 if (internal_process_ast_config(info, file, cfg)) {
637 if (apply_config(info)) {
641 ao2_cleanup(info->internal->
pending);
642 info->internal->
pending = NULL;
646 ao2_cleanup(info->internal->
pending);
647 info->internal->
pending = NULL;
660 if (!info->internal) {
661 ast_log(LOG_ERROR,
"Attempting to process uninitialized aco_info\n");
665 if (!(info->
files[0])) {
666 ast_log(LOG_ERROR,
"No filename given, cannot proceed!\n");
671 ast_log(LOG_ERROR,
"In %s: Could not allocate temporary objects\n", info->
module);
681 for (i = 0, match = file->
types[i]; match; match = file->
types[++i]) {
684 if (match->
type == ACO_IGNORE) {
688 if (match->
type != ACO_GLOBAL || !*field) {
693 ast_log(LOG_ERROR,
"In %s: Setting defaults for %s failed\n", file->
filename, match->
category);
705 if (!cfg || cfg == CONFIG_STATUS_FILEMISSING) {
706 if (file->
alias && strcmp(file->
alias, filename)) {
707 filename = file->
alias;
710 ast_log(LOG_ERROR,
"Unable to load config file '%s'\n", file->
filename);
713 }
else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
717 }
else if (cfg == CONFIG_STATUS_FILEINVALID) {
718 ast_log(LOG_ERROR,
"Contents of %s are invalid and cannot be parsed\n",
730 if (file_count != 1) {
737 res = internal_process_ast_config(info, file, cfg);
740 res = internal_process_ast_config(info, file, cfg);
754 if (apply_config(info)) {
764 ao2_cleanup(info->internal->
pending);
765 info->internal->
pending = NULL;
772 if (opt && opt->deprecated && !ast_strlen_zero(opt->aliased_to)) {
774 ast_log(LOG_WARNING,
"At line %d of %s option '%s' is deprecated. Use '%s' instead\n", var->lineno, var->
file, var->
name, alias);
776 opt = aco_option_find(type, alias);
780 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);
786 ast_log(LOG_ERROR,
"BUG! Somehow a config option for %s/%s was created with no handler!\n", cat, var->
name);
791 if (opt->doc_unavailable) {
792 ast_log(LOG_ERROR,
"Config option '%s' of type '%s' is not completely documented and can not be set\n", var->
name, type->
name);
797 if (opt->handler(opt, var, obj)) {
798 ast_log(LOG_ERROR,
"Error parsing %s=%s at line %d of %s\n", var->
name, var->
value, var->lineno, var->
file);
809 for (var = ast_variable_browse(cfg, cat); var; var = var->
next) {
818 static void internal_type_destroy(
struct aco_type *type)
823 if (!type->internal) {
827 if (type->internal->regex) {
828 regfree(type->internal->regex);
829 ast_free(type->internal->regex);
831 ao2_cleanup(type->internal->
opts);
832 type->internal->
opts = NULL;
833 ast_free(type->internal);
834 type->internal = NULL;
837 static void internal_file_types_destroy(
struct aco_file *file)
842 for (x = 0, t = file->
types[x]; t; t = file->
types[++x]) {
843 internal_type_destroy(t);
848 static int internal_type_init(
struct aco_type *type)
850 if (!(type->internal =
ast_calloc(1,
sizeof(*type->internal)))) {
857 if (!(type->internal->regex = build_regex(type->
category))) {
858 internal_type_destroy(type);
870 internal_type_destroy(type);
883 if (!(info->internal =
ast_calloc(1,
sizeof(*info->internal)))) {
887 while ((file = info->
files[x++])) {
888 while ((type = file->
types[y++])) {
889 if (internal_type_init(type)) {
895 type->
type != ACO_IGNORE &&
916 ast_free(info->internal);
917 info->internal = NULL;
919 for (x = 0; info->
files[x]; x++) {
920 internal_file_types_destroy(info->
files[x]);
929 if (!type->internal) {
935 while ((opt = ao2_iterator_next(&iter))) {
938 if (ast_strlen_zero(opt->default_val)) {
942 if (!(var = ast_variable_new(opt->name, opt->default_val,
""))) {
947 if (opt->handler(opt, var, obj)) {
948 ast_log(LOG_ERROR,
"Unable to set default for %s, %s=%s\n", category, var->name, var->value);
965 static char *complete_config_module(
const char *word)
967 size_t wordlen = strlen(word);
972 while ((cur = ao2_iterator_next(&i))) {
973 if (!strncasecmp(word, cur->
name, wordlen)) {
989 static char *complete_config_type(
const char *module,
const char *word)
991 size_t wordlen = strlen(word);
995 info = ao2_find(xmldocs, module,
OBJ_KEY);
1002 if (!strcasecmp(cur->
type,
"configObject") && !strncasecmp(word, cur->
name, wordlen)) {
1016 static char *complete_config_option(
const char *module,
const char *option,
const char *word)
1018 size_t wordlen = strlen(word);
1022 info = ao2_find(xmldocs, module,
OBJ_KEY);
1029 if (!strcasecmp(cur->
type,
"configOption") && !strcasecmp(cur->
ref, option) && !strncasecmp(word, cur->
name, wordlen)) {
1051 switch (category_match) {
1055 const char **matches = (
const char **) category;
1057 for (i = 0; matches[i]; i++) {
1082 #define XMLDOC_STRICT 1
1087 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)
1092 struct ast_xml_node *type, *syntax, *matchinfo, *tmp;
1093 struct ast_str *derived_category = NULL;
1097 if ((results =
ast_xmldoc_query(
"/docs/configInfo[@name='%s']/configFile/configObject[@name='%s']/syntax", module, name))) {
1101 if (!(results =
ast_xmldoc_query(
"/docs/configInfo[@name='%s']/configFile/configObject[@name='%s']", module, name))) {
1102 ast_log(LOG_WARNING,
"Cannot update type '%s' in module '%s' because it has no existing documentation!"
1103 " If this module was recently built, run 'xmldoc reload' to refresh documentation, then load the module again\n",
1105 return XMLDOC_STRICT ? -1 : 0;
1109 ast_log(LOG_WARNING,
"Could not retrieve documentation for type '%s' in module '%s'\n", name, module);
1110 return XMLDOC_STRICT ? -1 : 0;
1114 ast_log(LOG_WARNING,
"Could not create syntax node for type '%s' in module '%s'\n", name, module);
1115 return XMLDOC_STRICT ? -1 : 0;
1119 ast_log(LOG_WARNING,
"Could not create matchInfo node for type '%s' in module '%s'\n", name, module);
1120 return XMLDOC_STRICT ? -1 : 0;
1124 ast_log(LOG_WARNING,
"Could not create category node for type '%s' in module '%s'\n", name, module);
1125 return XMLDOC_STRICT ? -1 : 0;
1128 derived_category = derive_category_text(category_match, category);
1129 if (derived_category) {
1131 ast_free(derived_category);
1134 switch (category_match) {
1147 if (!ast_strlen_zero(matchfield)) {
1149 ast_log(LOG_WARNING,
"Could not add %s attribute for type '%s' in module '%s'\n", matchfield, name, module);
1150 return XMLDOC_STRICT ? -1 : 0;
1156 if (!config_info || !(config_type = find_xmldoc_type(config_info, name))) {
1157 ast_log(LOG_WARNING,
"Could not obtain XML documentation item for config type %s\n", name);
1158 return XMLDOC_STRICT ? -1 : 0;
1162 ast_log(LOG_WARNING,
"Could not update type '%s' with values from config type registration\n", name);
1163 return XMLDOC_STRICT ? -1 : 0;
1172 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)
1177 struct ast_xml_node *option;
1181 if (!config_info || !(config_option = find_xmldoc_option(config_info, types, name))) {
1182 ast_log(LOG_ERROR,
"XML Documentation for option '%s' in modules '%s' not found!\n", name, module);
1183 return XMLDOC_STRICT ? -1 : 0;
1186 if (!(results =
ast_xmldoc_query(
"/docs/configInfo[@name='%s']/configFile/configObject[@name='%s']/configOption[@name='%s']", module, object_name, name))) {
1187 ast_log(LOG_WARNING,
"Could not find option '%s' with type '%s' in module '%s'\n", name, object_name, module);
1188 return XMLDOC_STRICT ? -1 : 0;
1192 ast_log(LOG_WARNING,
"Could not obtain results for option '%s' with type '%s' in module '%s'\n", name, object_name, module);
1193 return XMLDOC_STRICT ? -1 : 0;
1200 ast_log(LOG_WARNING,
"Could not update option '%s' with values from config option registration\n", name);
1201 return XMLDOC_STRICT ? -1 : 0;
1215 ast_assert(a->argc == 3);
1218 ast_cli(a->fd,
"No modules found.\n");
1223 ast_cli(a->fd,
"The following modules have configuration information:\n");
1224 while ((item = ao2_iterator_next(&it_items))) {
1225 ast_cli(a->fd,
"\t%s\n", item->
name);
1234 static void cli_show_module_types(
struct ast_cli_args *a)
1239 ast_assert(a->argc == 4);
1241 if (!(item = ao2_find(xmldocs, a->argv[3],
OBJ_KEY))) {
1242 ast_cli(a->fd,
"Module %s not found.\n", a->argv[3]);
1254 ast_cli(a->fd,
"Configuration option types for %s:\n", tmp->
name);
1256 if (!strcasecmp(tmp->
type,
"configObject")) {
1257 ast_cli(a->fd,
"%-25s -- %-65.65s\n", tmp->
name,
1266 static void cli_show_module_type(
struct ast_cli_args *a)
1270 char option_type[64];
1273 ast_assert(a->argc == 5);
1275 if (!(item = ao2_find(xmldocs, a->argv[3],
OBJ_KEY))) {
1276 ast_cli(a->fd,
"Unknown module %s\n", a->argv[3]);
1282 if (!strcasecmp(tmp->
type,
"configObject") && !strcasecmp(tmp->
name, a->argv[4])) {
1284 term_color(option_type, tmp->
name, COLOR_MAGENTA, COLOR_BLACK,
sizeof(option_type));
1285 ast_cli(a->fd,
"%s", option_type);
1289 ast_cli(a->fd,
"\n\n");
1301 ast_cli(a->fd,
"Unknown configuration type %s\n", a->argv[4]);
1308 if (!strcasecmp(tmp->
type,
"configOption") && !strcasecmp(tmp->
ref, a->argv[4])) {
1309 ast_cli(a->fd,
"%-25s -- %-120.120s\n", tmp->
name,
1318 static void cli_show_module_options(
struct ast_cli_args *a)
1322 char option_name[64];
1325 ast_assert(a->argc == 6);
1327 if (!(item = ao2_find(xmldocs, a->argv[3],
OBJ_KEY))) {
1328 ast_cli(a->fd,
"Unknown module %s\n", a->argv[3]);
1333 if (!strcasecmp(tmp->
type,
"configOption") && !strcasecmp(tmp->
ref, a->argv[4]) && !strcasecmp(tmp->
name, a->argv[5])) {
1335 ast_cli(a->fd,
"\n");
1337 term_color(option_name, tmp->
ref, COLOR_MAGENTA, COLOR_BLACK,
sizeof(option_name));
1348 ast_cli(a->fd,
"See Also:\n");
1357 ast_cli(a->fd,
"No option %s found for %s:%s\n", a->argv[5], a->argv[3], a->argv[4]);
1365 e->
command =
"config show help";
1367 "Usage: config show help [<module> [<type> [<option>]]]\n"
1368 " Display detailed information about module configuration.\n"
1369 " * If nothing is specified, the modules that have\n"
1370 " configuration information are listed.\n"
1371 " * If <module> is specified, the configuration types\n"
1372 " for that module will be listed, along with brief\n"
1373 " information about that type.\n"
1374 " * If <module> and <type> are specified, detailed\n"
1375 " information about the type is displayed, as well\n"
1376 " as the available options.\n"
1377 " * If <module>, <type>, and <option> are specified,\n"
1378 " detailed information will be displayed about that\n"
1380 " NOTE: the help documentation is partially generated at run\n"
1381 " time when a module is loaded. If a module is not loaded,\n"
1382 " configuration help for that module may be incomplete.\n";
1387 return complete_config_module(a->word);
1389 return complete_config_type(a->argv[3], a->word);
1391 return complete_config_option(a->argv[3], a->argv[4], a->word);
1399 cli_show_modules(a);
1402 cli_show_module_types(a);
1405 cli_show_module_type(a);
1408 cli_show_module_options(a);
1411 return CLI_SHOWUSAGE;
1418 AST_CLI_DEFINE(cli_show_help,
"Show configuration help for a module"),
1421 static void aco_deinit(
void)
1424 ao2_cleanup(xmldocs);
1433 ast_log(LOG_ERROR,
"Couldn't build config documentation\n");
1448 int *field = (
int *)(obj + opt->args[0]);
1449 unsigned int flags = PARSE_INT32 | opt->flags;
1451 if (opt->flags & PARSE_IN_RANGE) {
1452 res = opt->flags & PARSE_DEFAULT ?
1453 ast_parse_arg(var->
value, flags, field, (
int) opt->args[1], (
int) opt->args[2], opt->args[3]) :
1456 if (opt->flags & PARSE_RANGE_DEFAULTS) {
1457 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]);
1459 }
else if (opt->flags & PARSE_DEFAULT) {
1460 ast_log(LOG_WARNING,
"Failed to set %s=%s, Set to default value %d instead.\n", var->
name, var->
value, *field);
1464 }
else if ((opt->flags & PARSE_DEFAULT) &&
ast_parse_arg(var->
value, flags, field, (
int) opt->args[1])) {
1465 ast_log(LOG_WARNING,
"Attempted to set %s=%s, but set it to %d instead due to default)\n", var->
name, var->
value, *field);
1478 unsigned int *field = (
unsigned int *)(obj + opt->args[0]);
1479 unsigned int flags = PARSE_UINT32 | opt->flags;
1481 if (opt->flags & PARSE_IN_RANGE) {
1482 res = opt->flags & PARSE_DEFAULT ?
1483 ast_parse_arg(var->
value, flags, field, (
unsigned int) opt->args[1], (
unsigned int) opt->args[2], opt->args[3]) :
1484 ast_parse_arg(var->
value, flags, field, (
unsigned int) opt->args[1], (
unsigned int) opt->args[2]);
1486 if (opt->flags & PARSE_RANGE_DEFAULTS) {
1487 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]);
1489 }
else if (opt->flags & PARSE_DEFAULT) {
1490 ast_log(LOG_WARNING,
"Failed to set %s=%s, Set to default value %u instead.\n", var->
name, var->
value, *field);
1494 }
else if ((opt->flags & PARSE_DEFAULT) &&
ast_parse_arg(var->
value, flags, field, (
unsigned int) opt->args[1])) {
1495 ast_log(LOG_WARNING,
"Attempted to set %s=%s, but set it to %u instead due to default)\n", var->
name, var->
value, *field);
1509 int *field = (
int *)(obj + opt->args[0]);
1510 unsigned int flags = PARSE_TIMELEN | opt->flags;
1512 if (opt->flags & PARSE_IN_RANGE) {
1513 if (opt->flags & PARSE_DEFAULT) {
1514 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]);
1516 res =
ast_parse_arg(var->
value, flags, field, (
enum ast_timelen) opt->args[1], (
int) opt->args[2], (
int) opt->args[3]);
1519 if (opt->flags & PARSE_RANGE_DEFAULTS) {
1520 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]);
1522 }
else if (opt->flags & PARSE_DEFAULT) {
1523 ast_log(LOG_WARNING,
"Failed to set %s=%s, Set to default value %d instead.\n", var->
name, var->
value, *field);
1527 }
else if ((opt->flags & PARSE_DEFAULT) &&
ast_parse_arg(var->
value, flags, field, (
enum ast_timelen) opt->args[1], (
int) opt->args[2])) {
1528 ast_log(LOG_WARNING,
"Attempted to set %s=%s, but set it to %d instead due to default)\n", var->
name, var->
value, *field);
1541 double *field = (
double *)(obj + opt->args[0]);
1550 struct ast_ha **ha = (
struct ast_ha **)(obj + opt->args[0]);
1571 ast_string_field *field = (
const char **)(obj + opt->args[0]);
1575 if (opt->flags && ast_strlen_zero(var->
value)) {
1578 ast_string_field_ptr_set_by_fields(*pool, *mgr, field, var->
value);
1588 unsigned int *field = (
unsigned int *)(obj + opt->args[0]);
1599 unsigned int *flags_field = (
unsigned int *)(obj + opt->args[0]);
1601 unsigned int flag = opt->args[1];
1603 *flags_field |= flag;
1605 *flags_field &= ~flag;
1633 char *field = (
char *)(obj + opt->args[0]);
1634 size_t len = opt->args[1];
1636 if (opt->flags && ast_strlen_zero(var->
value)) {
aco_type_item_pre_process item_pre_process
Type for default handler for ast_sockaddrs.
struct ast_variable * next
Type for default option handler for format capabilities.
int(* aco_option_handler)(const struct aco_option *opt, struct ast_variable *var, void *obj)
A callback function for handling a particular option.
aco_pre_apply_config pre_apply_config
int aco_info_init(struct aco_info *info)
Initialize an aco_info structure.
static int sockaddr_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj)
Default handler for ast_sockaddrs.
aco_type_item_find item_find
struct ao2_global_obj * global_obj
Asterisk main include file. File version handling, generic pbx functions.
static int chararray_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj)
Default handler for character arrays.
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
int ast_parse_arg(const char *arg, enum ast_parse_flags flags, void *p_result,...)
The argument parsing routine.
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
const ast_string_field ref
unsigned int aco_option_get_flags(const struct aco_option *option)
Read the flags of a config option - useful when using a custom callback for a config option...
int ast_cli_unregister(struct ast_cli_entry *e)
Unregisters a command or an array of commands.
descriptor for a cli entry.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container, as described below.
Structure for variables, used for configurations and for channel variables.
static pj_pool_t * pool
Global memory pool for configuration and timers.
aco_type_prelink item_prelink
static int boolflag_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj)
Default option handler for bools (ast_true/ast_false) that are stored as flags.
struct ao2_container * ast_xmldoc_build_documentation(const char *type)
Build the documentation for a particular source type.
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
static int uint_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj)
Default option handler for unsigned integers.
Type for a default handler that should do nothing.
intptr_t aco_option_get_argument(const struct aco_option *option, unsigned int position)
Get the offset position for an argument within a config option.
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
#define ast_cli_register_multiple(e, len)
Register multiple commands.
struct ast_xml_xpath_results * ast_xmldoc_query(const char *fmt,...)
Execute an XPath query on the loaded XML documentation.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
static int codec_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj)
Default option handler for codec preferences/capabilities.
Type for default option handler for bools (ast_true/ast_false) that are stored in a flag...
#define ast_strdup(str)
A wrapper for strdup()
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
enum aco_process_status aco_process_config(struct aco_info *info, int reload)
Process a config info via the options registered with an aco_info.
The representation of a single configuration file to be processed.
Bits of aco_info that shouldn't be assigned outside this file.
aco_matchtype
What kind of matching should be done on an option name.
Socket address structure.
struct ast_xml_node * ast_xml_new_child(struct ast_xml_node *parent, const char *child_name)
Add a child node inside a passed parent node.
Type for a custom (user-defined) option handler.
Type for default option handler for character array strings.
internal representation of ACL entries In principle user applications would have no need for this...
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Type for default option handler for bools (ast_true/ast_false)
Configuration File Parser.
struct ao2_container * opts
static int bool_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj)
Default option handler for bools (ast_true/ast_false)
#define ast_config_load(filename, flags)
Load a config file.
static int noop_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj)
Default handler for doing nothing.
const ast_string_field type
static int int_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj)
Default option handler for signed integers.
static int stringfield_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj)
Default option handler for stringfields.
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
Type for default option handler for unsigned integers.
int aco_process_category_options(struct aco_type *type, struct ast_config *cfg, const char *cat, void *obj)
Parse each option defined in a config category.
#define ast_strdupa(s)
duplicate a string in memory from the stack
Access Control of various sorts.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
int aco_option_register_deprecated(struct aco_info *info, const char *name, struct aco_type **types, const char *aliased_to)
Register a deprecated (and aliased) config option.
Asterisk internal frame definitions.
aco_process_status
Return values for the aco_process functions.
#define ast_malloc(len)
A wrapper for malloc()
aco_type_item_alloc item_alloc
#define ast_debug(level,...)
Log a DEBUG message.
enum aco_category_op category_match
aco_option_type
The option types.
The config had not been edited and no changes applied.
Their was an error and no changes were applied.
struct ast_str * description
char * term_color(char *outbuf, const char *inbuf, int fgcolor, int bgcolor, int maxout)
Colorize a specified string by adding terminal color codes.
static char * aco_option_type_string[]
Value of the aco_option_type enum as strings.
Configuration option-handling.
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Allocate and initialize a hash container with the desired number of buckets.
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
Support for dynamic strings.
struct aco_file * files[]
#define ao2_unlink(container, obj)
Remove an object from a container.
aco_post_apply_config post_apply_config
Type for default option handler for bools (ast_true/ast_false)
void ast_xml_set_text(struct ast_xml_node *node, const char *content)
Set an element content string.
const ast_string_field name
#define ast_calloc(num, len)
A wrapper for calloc()
Type for default option handler for ACLs.
const char * ast_term_reset(void)
Returns the terminal reset code.
Type for default option handler for doubles.
static int timelen_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj)
Default option handler for timelen signed integers.
The config was processed and applied.
Asterisk XML Documentation API.
Prototypes for public functions only of internal interest,.
void ast_xml_xpath_results_free(struct ast_xml_xpath_results *results)
Free the XPath results.
char * ast_xmldoc_printable(const char *bwinput, int withcolors)
Colorize and put delimiters (instead of tags) to the xmldoc output.
int ast_xmldoc_regenerate_doc_item(struct ast_xml_doc_item *item)
Regenerate the documentation for a particular item.
Structure used to handle boolean flags.
void aco_info_destroy(struct aco_info *info)
Destroy an initialized aco_info struct.
const char * skip_category
#define ao2_global_obj_replace_unref(holder, obj)
Replace an ao2 object in the global holder, throwing away any old object.
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
int ast_xml_set_attribute(struct ast_xml_node *node, const char *name, const char *value)
Set an attribute to a node.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Type for default option handler for time length signed integers.
Standard Command Line Interface.
Type information about a category-level configurable object.
aco_snapshot_alloc snapshot_alloc
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
int attribute_pure ast_false(const char *val)
Make sure something is false. Determine if a string containing a boolean value is "false"...
enum aco_process_status aco_process_ast_config(struct aco_info *info, struct aco_file *file, struct ast_config *cfg)
Process config info from an ast_config via options registered with an aco_info.
int aco_set_defaults(struct aco_type *type, const char *category, void *obj)
Set all default options of obj.
Type for default option handler for stringfields.
void * aco_pending_config(struct aco_info *info)
Get pending config changes.
struct ast_ha * ast_append_ha(const char *sense, const char *stuff, struct ast_ha *path, int *error)
Add a new rule to a list of HAs.
Handy terminal functions for vt* terms.
Struct that contains the XML documentation for a particular item. Note that this is an ao2 ref counte...
int aco_process_var(struct aco_type *type, const char *cat, struct ast_variable *var, void *obj)
Parse a single ast_variable and apply it to an object.
static int acl_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj)
Default handler for ACLs.
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
int ast_cli_completion_add(char *value)
Add a result to a request for completion options.
struct aco_type * types[]
Type for default option handler for signed integers.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
struct ao2_container * aco_option_container_alloc(void)
Allocate a container to hold config options.
static int double_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj)
Default option handler for doubles.
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
struct ast_xml_node * ast_xml_xpath_get_first_result(struct ast_xml_xpath_results *results)
Return the first result node of an XPath query.
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
int __aco_option_register(struct aco_info *info, const char *name, enum aco_matchtype matchtype, struct aco_type **types, const char *default_val, enum aco_option_type kind, aco_option_handler handler, unsigned int flags, unsigned int no_doc, size_t argc,...)
register a config option
aco_matchvalue_func matchfunc
static force_inline int attribute_pure ast_str_case_hash(const char *str)
Compute a hash value on a case-insensitive string.
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
struct ast_str * synopsis
#define ao2_link(container, obj)
Add an object to a container.