36 #define AST_MODULE "extconfig" 62 #define MAX_NESTED_COMMENTS 128 63 #define COMMENT_START ";--" 64 #define COMMENT_END "--;" 65 #define COMMENT_META ';' 66 #define COMMENT_TAG '-' 73 #define MIN_VARIABLE_FNAME_SPACE 40 81 const char *
match,
char sep);
121 return *str ? 0 : -1;
178 for (total = 0; *
str; str++) {
185 total += ((
unsigned int) (*str));
217 #define MAX_INCLUDE_LEVEL 10 291 int name_len = strlen(name) + 1;
292 int val_len = strlen(value) + 1;
293 int fn_len = strlen(filename) + 1;
300 variable =
__ast_calloc(1, fn_len + name_len + val_len +
sizeof(*variable),
303 char *dst = variable->
stuff;
306 variable->
file = strcpy(dst, filename);
308 variable->
name = strcpy(dst, name);
310 variable->
value = strcpy(dst, value);
349 inc->inclusion_count++;
350 snprintf(real_included_file_name, real_included_file_name_size,
"%s~~%d", included_file, inc->inclusion_count);
351 }
while (stat(real_included_file_name, &statbuf) == 0);
352 ast_log(
LOG_WARNING,
"'%s', line %d: Same File included more than once! This data will be saved in %s if saved back to disk.\n", from_file, from_lineno, real_included_file_name);
354 *real_included_file_name = 0;
360 inc->include_location_file =
ast_strdup(from_file);
361 inc->include_location_lineno = from_lineno;
363 inc->included_file =
ast_strdup(real_included_file_name);
365 inc->included_file =
ast_strdup(included_file);
371 if (!inc->include_location_file
372 || !inc->included_file
373 || (is_exec && !inc->exec_file)) {
391 int from_len = strlen(from_file);
392 int to_len = strlen(to_file);
394 if (strcmp(from_file, to_file) == 0)
408 if (from_len >= to_len)
420 for (cat = conf->
root; cat; cat = cat->
next) {
425 if (strcmp(cat->
file,from_file) == 0) {
426 if (from_len >= to_len)
427 strcpy(cat->
file, to_file);
438 if (strcmp(v->
file, from_file)) {
449 str = (
char *) v->
file;
450 strcpy(str, to_file);
465 if (cat->
last == v) {
495 category->
root = variable;
496 category->
last = variable;
507 if (!variable || sscanf(line,
"%30d", &insertline) != 1) {
512 category->
root = variable;
514 for (lineno = 1; lineno < insertline; lineno++) {
521 cur->
next = variable;
529 for (p = *comment; p; p = n) {
556 while ((var = var->
next)) {
573 if (!var1 || !var1->
next) {
627 memset(&top, 0,
sizeof(top));
656 if (search_hint ==
NULL) {
659 for (curr = search_hint; curr->
next; curr = curr->
next);
663 for (curr = newvar; curr->
next; curr = curr->
next);
672 for (v = *head; v; prev = &v->
next, v = v->
next) {
673 if (!strcmp(v->
name, replacement->
name)) {
700 if (!strcasecmp(variable, v->
name)) {
707 for (cat = config->
root; cat; cat = cat->
next) {
708 for (v = cat->
root; v; v = v->
next) {
709 if (!strcasecmp(variable, v->
name)) {
720 const char *category,
const char *variable,
const char *
filter)
744 for (v = list; v; v = v->
next) {
745 if (!strcasecmp(variable_name, v->
name)) {
760 if (!(left && right)) {
764 op = strrchr(right->
name,
' ');
782 if (!(left && right)) {
786 for (field = right; field; field = field->
next) {
787 char *space = strrchr(field->
name,
' ');
796 name[space - field->
name] =
'\0';
800 if (name != field->
name) {
805 if (!old || strcmp(old->
value, field->
value)) {
818 for (field = left; field; field = field->
next) {
822 if (right_count != left_count) {
834 for (v = list; v; v = v->
next) {
835 if (!strcasecmp(variable, v->
name)) {
845 const char *found =
NULL;
847 for (v = list; v; v = v->
next) {
848 if (!strcasecmp(variable, v->
name)) {
860 new->lineno = old->
lineno;
861 new->object = old->
object;
882 const char *
match,
char sep)
886 int match_found = 0, match_expressions = 0;
904 char *match_value =
NULL;
907 regex_t r_name, r_value;
915 if (match_value ==
NULL) {
919 if (!strcmp(
"TEMPLATES", match_name)) {
920 if (!strcasecmp(
"include", match_value)) {
925 }
else if (!strcasecmp(
"restrict", match_value)) {
936 if ((rc = regcomp(&r_name, match_name, REG_EXTENDED | REG_NOSUB))) {
938 regerror(rc, &r_name, regerr, 128);
944 if ((rc = regcomp(&r_value, match_value, REG_EXTENDED | REG_NOSUB))) {
946 regerror(rc, &r_value, regerr, 128);
948 match_value, regerr);
954 for (v = cat->
root; v; v = v->
next) {
955 if (!regexec(&r_name, v->
name, 0,
NULL, 0)
956 && !regexec(&r_value, v->
value, 0,
NULL, 0)) {
964 if (match_found == match_expressions && (!cat->
ignored || template_ok)) {
980 if (!category->
file) {
1001 const char *category_name,
const char *
filter,
char sep,
char pointer_match_possible)
1005 if (pointer_match_possible) {
1006 for (cat = config->
root; cat; cat = cat->
next) {
1013 for (cat = config->
root; cat; cat = cat->
next) {
1023 const char *category_name,
const char *
filter)
1030 return category->
name;
1054 ast_str_append(&str, 0,
"%s%s", first ?
"" :
",", template->name);
1073 config->
root = category;
1079 config->
last = category;
1087 if (!config || !config->
root || !cat || !match) {
1091 if (!strcasecmp(config->
root->
name, match)) {
1099 for (cur_category = config->
root->
next; cur_category; cur_category = cur_category->
next) {
1100 if (!strcasecmp(cur_category->
name, match)) {
1104 cat->
next = cur_category;
1105 cur_category->
prev = cat;
1139 for (incl=incls; incl; incl = inclnext) {
1140 inclnext = incl->
next;
1167 return category->
root;
1203 int nmerges, psize, qsize, i;
1212 if (!config->
root) {
1229 for (i = 0; i < insize; i++) {
1241 while (psize > 0 || (qsize > 0 && q)) {
1248 }
else if (qsize == 0 || !q) {
1250 e = p; p = p->
next; psize--;
1251 }
else if ((comparator(p,q) * descending) <= 0) {
1306 for (cat = config->
root; cat; cat = cat->
next) {
1307 if (cat->
name == prev) {
1318 for (cat = config->
root; cat; cat = cat->
next) {
1319 if (!strcasecmp(cat->
name, prev)) {
1341 prev = config->
root;
1379 for (var = base->
root; var; var = var->
next) {
1394 if ((config =
ast_calloc(1,
sizeof(*config))))
1409 if (sscanf(line,
"%30d", &req_item) != 1
1417 cur = category->
root;
1421 if ((0 <= req_item && num_item == req_item)
1422 || (req_item < 0 && !strcasecmp(cur->
name, variable)
1426 if (cur == category->
last)
1430 if (cur == category->
last)
1445 const char *
value,
const char *
match,
unsigned int object)
1449 for (cur = category->
root; cur; prev = cur, cur = cur->
next) {
1450 if (strcasecmp(cur->
name, variable) ||
1458 newer->object = newer->object || object;
1461 newer->next = cur->
next;
1465 category->
root = newer;
1466 if (category->
last == cur)
1467 category->
last = newer;
1483 if (!config || !category) {
1487 if (category->
prev) {
1493 if (category->
next) {
1499 prev = category->
prev;
1568 sizeof(*cfmtime) + strlen(filename) + 1 + strlen(who_asked) + 1);
1573 strcpy(dst, filename);
1574 dst += strlen(dst) + 1;
1575 cfmtime->
who_asked = strcpy(dst, who_asked);
1597 #if defined(HAVE_STRUCT_STAT_ST_MTIM) 1599 #elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC) 1601 #elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC) 1679 if (!strcmp(cfmtime->
filename, filename)
1680 && !strcmp(cfmtime->
who_asked, who_asked)) {
1698 if (!strcmp(cfmtime->
filename, configfile) && !strcmp(cfmtime->
who_asked, who_asked))
1714 if (!strcmp(cfinclude->
include, filename)) {
1719 cfinclude =
ast_calloc(1,
sizeof(*cfinclude) + strlen(filename) + 1);
1724 strcpy(cfinclude->
include, filename);
1745 const char *suggested_include_file,
1751 char exec_file[512];
1754 if (cur[0] ==
'[') {
1766 c = strchr(cur,
']');
1768 ast_log(
LOG_WARNING,
"parse error: no closing ']', line %d of %s\n", lineno, configfile);
1790 CB_RESET(comment_buffer, lline_buffer);
1794 if (!(cur = strchr(c,
')'))) {
1796 ast_log(
LOG_WARNING,
"parse error: no closing ')', line %d of %s\n", lineno, configfile);
1800 while ((cur =
strsep(&c,
","))) {
1801 if (!strcasecmp(cur,
"!")) {
1802 (*cat)->ignored = 1;
1803 }
else if (cur[0] ==
'+') {
1806 if (cur[1] !=
',') {
1814 ast_log(
LOG_WARNING,
"Category addition requested, but category '%s' does not exist, line %d of %s\n", catname, lineno, configfile);
1819 (*cat)->ignored |= newcat->
ignored;
1832 ast_log(
LOG_WARNING,
"Inheritance requested, but category '%s' does not exist, line %d of %s\n", cur, lineno, configfile);
1858 }
else if (cur[0] ==
'#') {
1860 char real_inclusion_name[256];
1866 while (*c && (*c > 32)) {
1880 if (!strcasecmp(cur,
"include")) {
1882 }
else if (!strcasecmp(cur,
"tryinclude")) {
1885 }
else if (!strcasecmp(cur,
"exec")) {
1887 ast_log(
LOG_WARNING,
"Cannot perform #exec unless execincludes option is enabled in asterisk.conf (options section)!\n");
1891 ast_log(
LOG_WARNING,
"Unknown directive '#%s' at line %d of %s\n", cur, lineno, configfile);
1897 do_include ?
"include / tryinclude" :
"exec",
1898 do_include ?
"filename" :
"/path/to/executable",
1907 if ((*c ==
'"') || (*c ==
'<')) {
1908 char quote_char = *
c;
1909 if (quote_char ==
'<') {
1913 if (*(c + strlen(c) - 1) == quote_char) {
1915 *(c + strlen(c) - 1) =
'\0';
1928 snprintf(exec_file,
sizeof(exec_file),
"/var/tmp/exec.%d%d.%ld", (
int)now.tv_sec, (
int)now.tv_usec, (
long)pthread_self());
1929 if (snprintf(cmd,
sizeof(cmd),
"%s > %s 2>&1", cur, exec_file) >=
sizeof(cmd)) {
1930 ast_log(
LOG_ERROR,
"Failed to construct command string to execute %s.\n", cur);
1939 exec_file[0] =
'\0';
1943 ast_include_new(cfg, cfg->
include_level == 1 ?
"" : configfile, cur, !do_include, cur2, lineno, real_inclusion_name,
sizeof(real_inclusion_name));
1948 if (!do_include && !try_include) {
1949 ast_log(
LOG_ERROR,
"The file '%s' was listed as a #include but it does not exist.\n", cur);
1961 "parse error: No category context for line %d of %s\n", lineno, configfile);
1965 is_escaped = cur[0] ==
'\\';
1970 ast_log(
LOG_ERROR,
"Invalid escape in line %d of %s\n", lineno, configfile);
1974 c = strchr(cur + is_escaped,
'=');
1976 if (c && c > cur + is_escaped && (*(c - 1) ==
'+')) {
1980 if (!str || !*str) {
1990 if (!strcmp(var->
name, cur)) {
1997 goto set_new_variable;
2030 CB_RESET(comment_buffer, lline_buffer);
2045 #if defined(LOW_MEMORY) 2050 char *new_buf, *comment_p, *process_buf;
2056 struct stat statbuf;
2071 if (filename[0] ==
'/') {
2079 if (comment_buffer) {
2082 if (!lline_buffer) {
2089 globbuf.gl_offs = 0;
2091 if (glob_ret == GLOB_NOSPACE) {
2093 "Glob Expansion of pattern '%s' failed: Not enough memory\n", fn);
2096 "Glob Expansion of pattern '%s' failed: Read error\n", fn);
2101 if (!cfg && (globbuf.gl_pathc != 1 || strcmp(fn, globbuf.gl_pathv[0]))) {
2114 for (i=0; i<globbuf.gl_pathc; i++) {
2123 if (stat(fn, &statbuf)) {
2130 if (!S_ISREG(statbuf.st_mode)) {
2166 NULL, flags,
"", who_asked)) {
2199 if (!(f = fopen(fn,
"r"))) {
2200 ast_debug(1,
"No file to parse: %s\n", fn);
2201 ast_verb(2,
"Parsing '%s': Not found (%s)\n", fn, strerror(
errno));
2210 if (fgets(buf,
sizeof(buf), f)) {
2212 if (strlen(buf) ==
sizeof(buf) - 1 && buf[
sizeof(buf) - 2] !=
'\n') {
2213 ast_log(
LOG_WARNING,
"Line %d too long, skipping. It begins with: %.32s...\n", lineno, buf);
2214 while (fgets(buf,
sizeof(buf), f)) {
2215 if (strlen(buf) !=
sizeof(buf) - 1 || buf[
sizeof(buf) - 2] ==
'\n') {
2224 #define UTF8_BOM "\xEF\xBB\xBF" 2225 size_t line_bytes = strlen(buf);
2226 size_t bom_bytes =
sizeof(
UTF8_BOM) - 1;
2227 if (line_bytes >= bom_bytes
2228 && !memcmp(buf,
UTF8_BOM, bom_bytes)) {
2229 memmove(buf, &buf[bom_bytes], line_bytes - bom_bytes + 1);
2253 CB_ADD(&comment_buffer,
"\n");
2258 if ((comment_p > new_buf) && (*(comment_p - 1) ==
'\\')) {
2260 new_buf = comment_p;
2262 memmove(comment_p - 1, comment_p, strlen(comment_p) + 1);
2267 new_buf = comment_p + 3;
2269 nest[comment-1] =
lineno;
2273 }
else if ((comment_p >= new_buf + 2) &&
2278 new_buf = comment_p + 1;
2285 oldptr = process_buf + strlen(process_buf);
2287 CB_ADD(&comment_buffer,
";");
2288 CB_ADD_LEN(&comment_buffer, oldptr+1, new_buf-oldptr-1);
2291 memmove(oldptr, new_buf, strlen(new_buf) + 1);
2294 process_buf = new_buf;
2302 CB_ADD(&lline_buffer, comment_p);
2305 new_buf = comment_p;
2307 new_buf = comment_p + 1;
2312 CB_ADD(&comment_buffer, buf);
2320 flags, comment_buffer, lline_buffer,
2321 suggested_include_file, &last_cat, &last_var,
2339 }
else if (last_var) {
2353 CB_RESET(comment_buffer, lline_buffer);
2359 ast_log(
LOG_WARNING,
"Unterminated comment detected beginning on line %d\n", nest[comment - 1]);
2407 fprintf(f1,
";!\n");
2408 fprintf(f1,
";! Automatically generated configuration file\n");
2409 if (strcmp(configfile, fn))
2410 fprintf(f1,
";! Filename: %s (%s)\n", configfile, fn);
2412 fprintf(f1,
";! Filename: %s\n", configfile);
2413 fprintf(f1,
";! Generator: %s\n", generator);
2414 fprintf(f1,
";! Creation Date: %s", date);
2415 fprintf(f1,
";!\n");
2425 static void make_fn(
char *fn,
size_t fn_size,
const char *
file,
const char *configfile)
2428 if (configfile[0] ==
'/') {
2433 }
else if (file[0] ==
'/') {
2445 make_fn(fn, fn_size, file, configfile);
2497 int precomment_lines;
2511 if (lineno - precomment_lines - fi->
lineno < 0) {
2513 }
else if (lineno == 0) {
2516 }
else if (lineno - precomment_lines - fi->
lineno < 5) {
2519 for (i = fi->
lineno; i < lineno - precomment_lines; i++) {
2538 if (access(fn, F_OK)) {
2541 if (access(dn, R_OK | W_OK)) {
2546 if (access(fn, R_OK | W_OK)) {
2590 make_fn(fn,
sizeof(fn), 0, configfile);
2617 fi =
set_fn(fn,
sizeof(fn), 0, configfile, fileset);
2620 (f = fopen(fn,
"w+"))
2622 (f = fopen(fn,
"w"))
2638 fi =
set_fn(fn,
sizeof(fn), cat->
file, configfile, fileset);
2654 fprintf(f,
"#exec \"%s\"\n", incl->
exec_file);
2665 char *cmtp = cmt->
cmt;
2666 while (cmtp && *cmtp ==
';' && *(cmtp+1) ==
'!') {
2667 char *cmtp2 = strchr(cmtp+1,
'\n');
2673 fprintf(f,
"%s", cmtp);
2675 fprintf(f,
"[%s]", cat->
name);
2687 fprintf(f,
"%s",x->
name);
2696 fprintf(f,
"%s", cmt->
cmt);
2701 if (cmt->
cmt[0] !=
';' || cmt->
cmt[1] !=
'!')
2702 fprintf(f,
"%s", cmt->
cmt);
2743 fi =
set_fn(fn,
sizeof(fn), var->
file, configfile, fileset);
2746 ast_debug(1,
"Unable to open for writing: %s\n", fn);
2747 ast_verb(2,
"Unable to write %s (%s)\n", fn, strerror(
errno));
2760 fprintf(f,
"#exec \"%s\"\n", incl->
exec_file);
2770 if (cmt->
cmt[0] !=
';' || cmt->
cmt[1] !=
'!')
2771 fprintf(f,
"%s", cmt->
cmt);
2775 int escaped_len = 2 * strlen(var->
value) + 1;
2776 char escaped[escaped_len];
2781 fprintf(f,
"%s %s %s %s", var->
name, (var->
object ?
"=>" :
"="),
2784 fprintf(f,
"%s %s %s\n", var->
name, (var->
object ?
"=>" :
"="),
2790 if (cmt->
cmt[0] !=
';' || cmt->
cmt[1] !=
'!')
2791 fprintf(f,
"%s", cmt->
cmt);
2795 while (blanklines--)
2808 ast_verb(2,
"Saving '%s': saved\n", fn);
2810 ast_debug(1,
"Unable to open for writing: %s\n", fn);
2811 ast_verb(2,
"Unable to write '%s' (%s)\n", fn, strerror(
errno));
2827 ast_debug(1,
"Unable to open for writing: %s\n", fn);
2828 ast_verb(2,
"Unable to write %s (%s)\n", fn, strerror(
errno));
2838 fprintf(f,
"#exec \"%s\"\n", incl->
exec_file);
2867 #ifdef TEST_FRAMEWORK 2870 static int ast_realtime_append_mapping(
const char *name,
const char *driver,
const char *database,
const char *table,
int priority)
2877 length =
sizeof(*map);
2878 length += strlen(name) + 1;
2879 length += strlen(driver) + 1;
2880 length += strlen(database) + 1;
2882 length += strlen(table) + 1;
2888 map->
name = strcpy(dst, name);
2889 dst += strlen(dst) + 1;
2890 map->
driver = strcpy(dst, driver);
2891 dst += strlen(dst) + 1;
2892 map->
database = strcpy(dst, database);
2894 dst += strlen(dst) + 1;
2895 map->
table = strcpy(dst, table);
2910 char *driver, *
table, *database, *textpri, *stringp, *
tmp;
2925 }
else if (!config) {
2934 driver =
strsep(&stringp,
",");
2939 if ((tmp = strchr(stringp,
'\"')))
2943 if (*stringp ==
'"') {
2945 database =
strsep(&stringp,
"\"");
2949 database =
strsep(&stringp,
",");
2952 table =
strsep(&stringp,
",");
2953 textpri =
strsep(&stringp,
",");
2954 if (!textpri || !(pri = atoi(textpri))) {
2963 if (!strcmp(v->
name,
"asterisk.conf")) {
2968 if (!strcmp(v->
name,
"logger.conf")) {
2973 if (!driver || !database)
2975 if (!strcasecmp(v->
name,
"sipfriends")) {
2976 ast_log(
LOG_WARNING,
"The 'sipfriends' table is obsolete, update your config to use sippeers instead.\n");
2978 }
else if (!strcasecmp(v->
name,
"iaxfriends")) {
2979 ast_log(
LOG_WARNING,
"The 'iaxfriends' table is obsolete, update your config to use iaxusers and iaxpeers, though they can point to the same table.\n");
2996 if (!config_engine_list) {
2997 config_engine_list =
new;
2999 for (ptr = config_engine_list; ptr->
next; ptr=ptr->
next);
3012 for (ptr = config_engine_list; ptr; ptr=ptr->
next) {
3017 config_engine_list = ptr->
next;
3032 if (!strcasecmp(family, map->
name)) {
3036 ast_debug(5,
"Failed to find a realtime mapping for %s\n", family);
3050 if (!strcasecmp(family, map->
name) && (priority == map->
priority)) {
3061 for (eng = config_engine_list; !ret && eng; eng = eng->
next) {
3062 if (!strcasecmp(eng->name, map->
driver))
3088 for (cat_iter = old->
root; cat_iter; cat_iter = cat_iter->
next) {
3095 if (cat_iter->
root) {
3097 if (!new_cat->
root) {
3130 eng =
find_engine(filename, 1, db,
sizeof(db), table,
sizeof(table));
3136 eng =
find_engine(
"global", 1, db,
sizeof(db), table,
sizeof(table));
3142 result = loader->
load_func(db, table, filename, cfg, flags, suggested_include_file, who_asked);
3170 #define realtime_arguments_to_fields(ap, result) realtime_arguments_to_fields2(ap, 0, result) 3188 const char *newparam;
3224 newparam = va_arg(ap,
const char *);
3225 newval = va_arg(ap,
const char *);
3226 while ((newparam = va_arg(ap,
const char *))) {
3227 newval = va_arg(ap,
const char *);
3232 newparam = va_arg(ap,
const char *);
3237 newval = va_arg(ap,
const char *);
3244 while ((newparam = va_arg(ap,
const char *))) {
3247 newval = va_arg(ap,
const char *);
3255 field->
next = fields;
3259 first->
next = fields;
3274 for (i = 1; ; i++) {
3275 if ((eng =
find_engine(family, i, db,
sizeof(db), table,
sizeof(table)))) {
3293 va_start(ap, family);
3326 if (cur->
value[0] ==
' ' && cur->
value[1] ==
'\0') {
3327 char *vptr = (
char *) cur->
value;
3345 va_start(ap, family);
3390 va_start(ap, family);
3391 for (i = 1; ; i++) {
3392 if ((eng =
find_engine(family, i, db,
sizeof(db), table,
sizeof(table)))) {
3413 for (i = 1; ; i++) {
3414 if ((eng =
find_engine(family, i, db,
sizeof(db), table,
sizeof(table)))) {
3434 for (i = 1; ; i++) {
3435 if ((eng =
find_engine(family, i, db,
sizeof(db), table,
sizeof(table)))) {
3457 va_start(ap, family);
3475 for (i = 1; ; i++) {
3476 if ((eng =
find_engine(family, i, db,
sizeof(db), table,
sizeof(table)))) {
3494 va_start(ap, lookup);
3512 for (i = 1; ; i++) {
3513 if ((eng =
find_engine(family, i, db,
sizeof(db), table,
sizeof(table)))) {
3531 va_start(ap, family);
3538 va_start(ap, family);
3542 if (!lookup_fields || !update_fields) {
3556 for (i = 1; ; i++) {
3557 if ((eng =
find_engine(family, i, db,
sizeof(db), table,
sizeof(table)))) {
3575 va_start(ap, family);
3593 for (i = 1; ; i++) {
3594 if ((eng =
find_engine(family, i, db,
sizeof(db), table,
sizeof(table)))) {
3612 va_start(ap, lookup);
3628 for (; *chunk; chunk++) {
3629 if (*chunk ==
'^' && strchr(
"0123456789ABCDEFabcdef", chunk[1]) && strchr(
"0123456789ABCDEFabcdef", chunk[2])) {
3630 sscanf(chunk + 1,
"%02hhX", (
unsigned char *)chunk);
3631 memmove(chunk + 1, chunk + 3, strlen(chunk + 3) + 1);
3639 if (!strchr(chunk,
';') && !strchr(chunk,
'^')) {
3643 for (; *chunk; chunk++) {
3644 if (strchr(
";^", *chunk)) {
3658 void *p_result, ...)
3663 va_start(ap, p_result);
3670 char *endptr =
NULL;
3685 x = strtol(arg, &endptr, 0);
3691 error = (x < low) || (x > high);
3695 }
else if (x > high) {
3704 *result = error ? def : x;
3707 ast_debug(3,
"extract int from [%s] in [%d, %d] gives [%ld](%d)\n",
3708 arg, low, high, result ? *result : x, error);
3714 unsigned long int x = 0;
3715 uint32_t *
result = p_result;
3717 char *endptr =
NULL;
3721 def = va_arg(ap, uint32_t);
3725 low = va_arg(ap, uint32_t);
3726 high = va_arg(ap, uint32_t);
3740 x = strtoul(arg, &endptr, 0);
3745 error = (x < low) || (x > high);
3749 }
else if (x > high) {
3758 *result = error ? def : x;
3760 ast_debug(3,
"extract uint from [%s] in [%u, %u] gives [%lu](%d)\n",
3761 arg, low, high, result ? *result : x, error);
3769 int def = result ? *
result : 0;
3777 def = va_arg(ap,
int);
3780 low = va_arg(ap,
int);
3781 high = va_arg(ap,
int);
3788 if (error || x < INT_MIN || x > INT_MAX) {
3793 error = (x < low) || (x > high);
3797 }
else if (x > high) {
3806 *result = error ? def : x;
3809 ast_debug(3,
"extract timelen from [%s] in [%d, %d] gives [%d](%d)\n",
3810 arg, low, high, result ? *result : x, error);
3816 double *
result = p_result;
3817 double x = 0, def = result ? *
result : 0, low = -HUGE_VAL, high = HUGE_VAL;
3818 char *endptr =
NULL;
3822 def = va_arg(ap,
double);
3826 low = va_arg(ap,
double);
3827 high = va_arg(ap,
double);
3834 x = strtod(arg, &endptr);
3835 if (*endptr ||
errno == ERANGE) {
3839 error = (x < low) || (x > high);
3845 *result = error ? def : x;
3847 ast_debug(3,
"extract double from [%s] in [%f, %f] gives [%f](%d)\n",
3848 arg, low, high, result ? *result : x, error);
3859 ast_debug(3,
"extract addr from %s gives %s(%d)\n",
3867 struct sockaddr_in _sa_buf;
3868 struct sockaddr_in *sa = p_result ?
3869 (
struct sockaddr_in *)p_result : &_sa_buf;
3872 va_arg(ap,
struct sockaddr_in *) : sa;
3876 memset(&_sa_buf,
'\0',
sizeof(_sa_buf));
3879 buf =
strsep(&port,
":");
3880 sa->sin_family = AF_INET;
3889 sa->sin_port = def->sin_port;
3891 sa->sin_port = def->sin_port;
3893 sa->sin_port = htons(strtol(port,
NULL, 0));
3895 sa->sin_port = def->sin_port;
3902 memcpy(&sa->sin_addr, hp->h_addr,
sizeof(sa->sin_addr));
3905 sa->sin_addr = def->sin_addr;
3908 "extract inaddr from [%s] gives [%s:%d](%d)\n",
3910 ntohs(sa->sin_port), error);
3925 e->
command =
"core show config mappings";
3927 "Usage: core show config mappings\n" 3928 " Shows the filenames to config engines.\n";
3937 if (!config_engine_list) {
3938 ast_cli(a->
fd,
"No config mappings found.\n");
3940 for (eng = config_engine_list; eng; eng = eng->
next) {
3965 "Usage: config reload <filename.conf>\n" 3966 " Reloads all modules that reference <filename.conf>\n";
3973 wordlen = strlen(a->
word);
3983 if (!strcmp(cfmtime->
filename, prev)) {
4009 sprintf(buf,
"module reload %s", cfmtime->
who_asked);
4026 "Usage: config list\n" 4027 " Show all modules that have loaded a configuration file\n";
4122 if (!strcasecmp(hook->
filename, filename) &&
4123 !strcasecmp(hook->
module, module)) {
4133 const char *filename,
4169 ast_verb(0,
"[ Initializing Custom Configuration Options ]\n");
static void cfmstat_save(struct cache_file_mtime *cfmtime, struct stat *statbuf)
struct ast_variable * next
struct ast_category * next
static struct ast_config_engine text_file_engine
struct ast_comment * sameline
void * __ast_calloc(size_t nmemb, size_t size, const char *file, int lineno, const char *func) attribute_malloc
static void ast_variable_destroy(struct ast_variable *doomed)
#define AST_CLI_DEFINE(fn, txt,...)
static int init_appendbuf(void *data)
#define AST_LIST_LOCK(head)
Locks a list.
Asterisk locking-related definitions:
Asterisk main include file. File version handling, generic pbx functions.
struct ast_config_map * next
realtime_destroy * destroy_func
char * ast_realtime_decode_chunk(char *chunk)
Remove standard encoding from realtime values, which ensures that a semicolon embedded within a singl...
static void ast_destroy_template_list(struct ast_category *cat)
void ast_variable_insert(struct ast_category *category, struct ast_variable *variable, const char *line)
struct ast_variable * ast_variables_reverse(struct ast_variable *var)
Reverse a variable list.
char * file
The file name from whence this declaration was read.
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.
static char * handle_cli_core_show_config_mappings(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int hook_hash(const void *obj, const int flags)
String manipulation functions.
static void CB_ADD_LEN(struct ast_str **cb, const char *str, int len)
int ast_config_engine_register(struct ast_config_engine *new)
Register config engine.
int register_config_cli(void)
Exposed initialization method for core process.
static int unload_module(void)
void ast_variable_append(struct ast_category *category, struct ast_variable *variable)
static void CB_ADD(struct ast_str **cb, const char *str)
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
static void clear_config_maps(void)
struct ast_variable * ast_category_root(struct ast_config *config, char *cat)
returns the root ast_variable of a config
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
char * ast_category_browse(struct ast_config *config, const char *prev)
Browse categories.
struct ast_variable * ast_load_realtime_all(const char *family,...)
#define ast_test_flag(p, flag)
void ast_category_append(struct ast_config *config, struct ast_category *category)
Appends a category to a config.
char * include_location_file
file name in which the include occurs
Time-related functions and macros.
void ast_config_hook_unregister(const char *name)
Unregister a config hook.
int ast_category_inherit(struct ast_category *new, const struct ast_category *base)
Applies base (template) to category.
static int cfmstat_cmp(struct cache_file_mtime *cfmtime, struct stat *statbuf)
char * ast_realtime_encode_chunk(struct ast_str **dest, ssize_t maxlen, const char *chunk)
Encodes a chunk of data for realtime.
int ast_destroy_realtime_fields(const char *family, const char *keyfield, const char *lookup, const struct ast_variable *fields)
Destroy realtime configuration.
void ast_category_rename(struct ast_category *cat, const char *name)
int ast_update2_realtime_fields(const char *family, const struct ast_variable *lookup_fields, const struct ast_variable *update_fields)
Update realtime configuration.
struct ast_config * ast_config_internal_load(const char *filename, struct ast_config *cfg, struct ast_flags flags, const char *suggested_include_file, const char *who_asked)
struct ast_config_include * includes
descriptor for a cli entry.
int ast_realtime_enabled(void)
Check if there's any realtime engines loaded.
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
static struct ast_comment * ALLOC_COMMENT(struct ast_str *buffer)
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
void ast_include_rename(struct ast_config *conf, const char *from_file, const char *to_file)
#define CONFIG_STATUS_FILEINVALID
int ast_category_exist(const struct ast_config *config, const char *category_name, const char *filter)
Check for category duplicates.
struct ast_variable * ast_variable_list_append_hint(struct ast_variable **head, struct ast_variable *search_hint, struct ast_variable *newvar)
Appends a variable list to the end of another list.
static int reload_module(void)
realtime_store * store_func
struct ast_variable * ast_variable_list_sort(struct ast_variable *start)
Performs an in-place sort on the variable list by ascending name.
Structure for variables, used for configurations and for channel variables.
int ast_config_hook_register(const char *name, const char *filename, const char *module, enum config_hook_flags flags, config_hook_cb hook_cb)
Register a config hook for a particular file and module.
struct ast_comment * sameline
int ast_config_engine_deregister(struct ast_config_engine *del)
Deregister config engine.
int ast_realtime_append_mapping(const char *name, const char *driver, const char *database, const char *table, int priority)
Add an explicit mapping for a family.
struct ast_variable * ast_load_realtime_all_fields(const char *family, const struct ast_variable *fields)
const struct ast_category * inst
realtime_multi_get * realtime_multi_func
int ast_update_realtime_fields(const char *family, const char *keyfield, const char *lookup, const struct ast_variable *fields)
Update realtime configuration.
static struct ast_config_map * config_maps
struct ast_category * prev
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
int(* config_hook_cb)(struct ast_config *cfg)
#define ast_cli_register_multiple(e, len)
Register multiple commands.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
static int copy(char *infile, char *outfile)
Utility function to copy a file.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
char * ast_escape_semicolons(const char *string, char *outbuf, int buflen)
Escape semicolons found in a string.
struct ast_category * ast_category_delete(struct ast_config *config, struct ast_category *category)
Delete a category.
static int match(struct ast_sockaddr *addr, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
#define ast_strdup(str)
A wrapper for strdup()
int ast_parse_arg(const char *arg, enum ast_parse_flags flags, void *p_result,...)
Helper function to parse arguments See documentation in config.h.
static struct ast_category * next_available_category(struct ast_category *cat, const char *name, const char *filter)
realtime_unload * unload_func
realtime_update * update_func
static void config_shutdown(void)
int ast_update_realtime(const char *family, const char *keyfield, const char *lookup,...)
Update realtime configuration.
static void inclfile_destroy(void *obj)
struct ast_category * ast_config_get_current_category(const struct ast_config *cfg)
Retrieve the current category name being built.
void ast_cli(int fd, const char *fmt,...)
realtime_var_get * realtime_func
char * exec_file
if it's an exec, you'll have both the /var/tmp to read, and the original script
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
void ast_free_ptr(void *ptr)
free() wrapper
Socket address structure.
static void gen_header(FILE *f1, const char *configfile, const char *fn, const char *generator)
#define ast_verb(level,...)
#define realtime_arguments_to_fields(ap, result)
static void make_fn(char *fn, size_t fn_size, const char *file, const char *configfile)
static int count_linefeeds_in_comments(struct ast_comment *x)
int ast_variable_delete(struct ast_category *category, const char *variable, const char *match, const char *line)
Hold the mtime for config files, so if we don't need to reread our config, don't. ...
Configuration engine structure, used to define realtime drivers.
struct ast_config_engine * next
#define ast_strlen_zero(foo)
static struct ast_category * new_category(const char *name, const char *in_file, int lineno, int template)
All configuration options for statsd client.
struct ast_category * last
static void ast_includes_destroy(struct ast_config_include *incls)
struct ast_config * ast_load_realtime_multientry(const char *family,...)
Retrieve realtime configuration.
struct ast_category * current
#define AST_LIST_INSERT_SORTALPHA(head, elm, field, sortfield)
Inserts a list entry into a alphabetically sorted list.
static char * lline_buffer
struct ast_comment * trailing
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
static int is_writable(const char *fn)
Configuration File Parser.
#define MAX_NESTED_COMMENTS
#define ast_opt_exec_includes
#define ast_debug(level,...)
Log a DEBUG message.
static int process_text_line(struct ast_config *cfg, struct ast_category **cat, char *buf, int lineno, const char *configfile, struct ast_flags flags, struct ast_str *comment_buffer, struct ast_str *lline_buffer, const char *suggested_include_file, struct ast_category **last_cat, struct ast_variable **last_var, const char *who_asked)
parse one line in the configuration.
void ast_category_destroy(struct ast_category *cat)
struct ast_category::template_instance_list template_instances
struct ast_comment * trailing
static char * extconfig_conf
General Asterisk PBX channel definitions.
#define SCOPED_MUTEX(varname, lock)
scoped lock specialization for mutexes
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
struct ast_variable * ast_variables_dup(struct ast_variable *var)
Duplicate variable list.
Asterisk file paths, configured in asterisk.conf.
static int realtime_arguments_to_fields2(va_list ap, int skip, struct ast_variable **result)
struct ast_variable * _ast_variable_new(const char *name, const char *value, const char *filename, const char *file, const char *func, int lineno)
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
static void config_cache_flush_includes(struct cache_file_mtime *cfmtime)
struct sla_ringing_trunk * last
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
char * included_file
file name included
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
#define ao2_ref(o, delta)
static ast_mutex_t config_lock
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
#define ast_strdupa(s)
duplicate a string in memory from the stack
static struct ast_threadstorage appendbuf
char * ast_strsep(char **s, const char sep, uint32_t flags)
Act like strsep but ignore separators inside quotes.
ast_cli_command
calling arguments for new-style handlers.
realtime_require * require_func
#define ast_variable_new(name, value, filename)
static int hook_cmp(void *obj, void *arg, int flags)
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
struct ast_variable * root
char stuff[0]
Contents of file, name, and value in that order stuffed here.
int ast_variable_lists_match(const struct ast_variable *left, const struct ast_variable *right, int exact_match)
Tests 2 variable lists to see if they match.
AST_LIST_HEAD_NOLOCK(contactliststruct, contact)
struct ast_variable * ast_category_detach_variables(struct ast_category *cat)
#define CONFIG_STATUS_FILEUNCHANGED
struct ast_variable * ast_load_realtime_fields(const char *family, const struct ast_variable *fields)
Retrieve realtime configuration.
const char * ast_variable_retrieve_filtered(struct ast_config *config, const char *category, const char *variable, const char *filter)
Gets a variable by context and variable names.
struct ast_comment * precomments
Wrapper for network related headers, masking differences between various operating systems...
#define AST_LIST_HEAD_STATIC(name, type)
Defines a structure to be used to hold a list of specified type, statically initialized.
static int load_module(void)
static char * comment_buffer
static struct ast_hostent ahp
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
struct ast_category * last_browse
static struct ao2_container * cfg_hooks
struct ast_category_template_instance * next
int ast_realtime_require_field(const char *family,...)
Inform realtime what fields that may be stored.
struct cache_file_mtime::includes includes
static struct ast_variable * variable_clone(const struct ast_variable *old)
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
int ast_config_text_file_save(const char *configfile, const struct ast_config *cfg, const char *generator)
Save a config text file preserving the pre 13.2 behavior.
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
static struct ast_generator generator
int ast_safe_system(const char *s)
Safely spawn an OS shell command while closing file descriptors.
static struct inclfile * set_fn(char *fn, size_t fn_size, const char *file, const char *configfile, struct ao2_container *fileset)
const char * ast_config_option(struct ast_config *cfg, const char *cat, const char *var)
Retrieve a configuration variable within the configuration set.
const char * ast_config_AST_CONFIG_DIR
static void hook_destroy(void *obj)
struct ast_config_include * ast_include_find(struct ast_config *conf, const char *included_file)
int ast_category_is_template(const struct ast_category *category)
Check if category is a template.
int ast_variables_match(const struct ast_variable *left, const struct ast_variable *right)
Tests 2 variable values to see if they match.
const char * ast_variable_find_in_list(const struct ast_variable *list, const char *variable)
Gets the value of a variable from a variable list by name.
#define MAX_INCLUDE_LEVEL
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
struct ast_comment * precomments
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
const char * ast_variable_find_last_in_list(const struct ast_variable *list, const char *variable)
Gets the value of the LAST occurrence of a variable from a variable list.
int ast_realtime_is_mapping_defined(const char *family)
Determine if a mapping exists for a given family.
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
struct sla_ringing_trunk * first
#define ao2_iterator_next(iter)
#define ao2_alloc(data_size, destructor_fn)
#define AST_LIST_LAST(head)
Returns the last entry contained in a list.
int ast_update2_realtime(const char *family,...)
Update realtime configuration.
static char * handle_cli_config_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
int include_location_lineno
static int hash_string(const void *obj, const int flags)
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
static void config_cache_destroy_entry(struct cache_file_mtime *cfmtime)
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category)
static void ast_comment_destroy(struct ast_comment **comment)
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
const char * ast_inet_ntoa(struct in_addr ia)
thread-safe replacement for inet_ntoa().
int ast_variable_list_replace(struct ast_variable **head, struct ast_variable *replacement)
Replace a variable in the given list with a new value.
int ast_destroy_realtime(const char *family, const char *keyfield, const char *lookup,...)
Destroy realtime configuration.
#define ast_calloc(num, len)
A wrapper for calloc()
struct ast_config * ast_config_new(void)
Create a new base configuration structure.
Module could not be loaded properly.
int ast_store_realtime(const char *family,...)
Create realtime configuration.
void ast_config_set_current_category(struct ast_config *cfg, const struct ast_category *cat)
Set the category within the configuration as being current.
#define ao2_find(container, arg, flags)
static struct ast_config * config_text_file_load(const char *database, const char *table, const char *filename, struct ast_config *cfg, struct ast_flags flags, const char *suggested_include_file, const char *who_asked)
Structure used to handle boolean flags.
void ast_variables_destroy(struct ast_variable *v)
Free variable list.
static struct ast_config_engine * config_engine_list
#define ast_clear_flag(p, flag)
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS|AST_MODFLAG_LOAD_ORDER, "HTTP Phone Provisioning",.support_level=AST_MODULE_SUPPORT_EXTENDED,.load=load_module,.unload=unload_module,.reload=reload,.load_pri=AST_MODPRI_CHANNEL_DEPEND,.requires="http",)
config_hook_flags
Flags that affect the behaviour of config hooks.
void ast_config_sort_categories(struct ast_config *config, int descending, int(*comparator)(struct ast_category *p, struct ast_category *q))
Sorts categories in a config in the order of a numerical value contained within them.
static int replace(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)
#define AST_THREADSTORAGE_CUSTOM(a, b, c)
Define a thread storage variable, with custom initialization and cleanup.
int ast_check_realtime(const char *family)
Check if realtime engine is configured for family.
const char * ast_variable_find(const struct ast_category *category, const char *variable)
Gets a variable value from a specific category structure by name.
struct ast_str * ast_category_get_templates(const struct ast_category *category)
Return the template names this category inherits from.
int ast_store_realtime_fields(const char *family, const struct ast_variable *fields)
Create realtime configuration.
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
const char * ast_category_get_name(const struct ast_category *category)
Return the name of the category.
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
struct hostent * ast_gethostbyname(const char *host, struct ast_hostent *hp)
Thread-safe gethostbyname function to use in Asterisk.
char * strsep(char **str, const char *delims)
int ast_category_empty(struct ast_category *category)
Removes and destroys all variables in a category.
realtime_update2 * update2_func
struct ast_variable * last
struct ast_category * ast_category_new(const char *name, const char *in_file, int lineno)
Create a category.
#define MIN_VARIABLE_FNAME_SPACE
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Standard Command Line Interface.
struct ast_config_include * next
static struct ast_category * category_get_sep(const struct ast_config *config, const char *category_name, const char *filter, char sep, char pointer_match_possible)
struct ast_config * ast_config_copy(const struct ast_config *old)
Copies the contents of one ast_config into another.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
unsigned long stat_mtime_nsec
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
static struct ast_config_engine * find_engine(const char *family, int priority, char *database, int dbsiz, char *table, int tabsiz)
Find realtime engine for realtime family.
config_load_func * load_func
static void config_hook_exec(const char *filename, const char *module, const struct ast_config *cfg)
struct ast_config * ast_load_realtime_multientry_fields(const char *family, const struct ast_variable *fields)
Retrieve realtime configuration.
struct ast_category * ast_category_get(const struct ast_config *config, const char *category_name, const char *filter)
Retrieve a category if it exists.
config_cache_attribute_enum
struct ast_variable * ast_category_first(struct ast_category *cat)
given a pointer to a category, return the root variable.
int error(const char *format,...)
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
struct ast_config_include * ast_include_new(struct ast_config *conf, const char *from_file, const char *included_file, int is_exec, const char *exec_file, int from_lineno, char *real_included_file_name, int real_included_file_name_size)
static int hashtab_compare_strings(void *a, void *b, int flags)
struct ast_category * root
void ast_str_trim_blanks(struct ast_str *buf)
Trims trailing whitespace characters from an ast_str string.
ast_parse_flags
Support code to parse config file arguments.
static void ast_variable_move(struct ast_variable *dst_var, struct ast_variable *src_var)
static int filter(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
int ast_app_parse_timelen(const char *timestr, int *result, enum ast_timelen defunit)
Common routine to parse time lengths, with optional time unit specifier.
int ast_cli_completion_add(char *value)
Add a result to a request for completion options.
static struct ast_variable * variable_list_switch(struct ast_variable *l1, struct ast_variable *l2)
struct ast_variable * ast_load_realtime(const char *family,...)
#define ASTERISK_GPL_KEY
The text the key() function should return.
static void insert_leading_blank_lines(FILE *fp, struct inclfile *fi, struct ast_comment *precomments, int lineno)
static int hook_cb(struct ast_config *cfg)
Asterisk module definitions.
static struct hostent * hp
static int count_linefeeds(char *str)
static void config_cache_attribute(const char *configfile, enum config_cache_attribute_enum attrtype, const char *filename, const char *who_asked)
static char * handle_cli_config_list(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
int ast_category_insert(struct ast_config *config, struct ast_category *cat, const char *match)
Inserts new category.
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
const struct ast_variable * ast_variable_find_variable_in_list(const struct ast_variable *list, const char *variable_name)
Gets a variable from a variable list by name.
static void config_cache_remove(const char *filename, const char *who_asked)
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
int ast_unload_realtime(const char *family)
Release any resources cached for a realtime family.
struct ast_category * ast_category_browse_filtered(struct ast_config *config, const char *category_name, struct ast_category *prev, const char *filter)
Browse categories with filters.
static void CB_RESET(struct ast_str *cb, struct ast_str *llb)
int ast_config_text_file_save2(const char *configfile, const struct ast_config *cfg, const char *generator, uint32_t flags)
Save a config text file.
int ast_variable_update(struct ast_category *category, const char *variable, const char *value, const char *match, unsigned int object)
Update variable value within a config.
#define AST_MUTEX_DEFINE_STATIC(mutex)
static void move_variables(struct ast_category *old, struct ast_category *new)
int ast_strings_match(const char *left, const char *op, const char *right)
Compares 2 strings using realtime-style operators.
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
static struct ast_cli_entry cli_config[]
static struct cache_file_mtime * cfmtime_new(const char *filename, const char *who_asked)
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
static int does_category_match(struct ast_category *cat, const char *category_name, const char *match, char sep)
Returns true if ALL of the regex expressions and category name match. Both can be NULL (I...
struct ast_category * ast_category_new_template(const char *name, const char *in_file, int lineno)
Create a category making it a template.
#define ao2_link(container, obj)