36#define AST_MODULE "extconfig"
63#define MAX_NESTED_COMMENTS 128
64#define COMMENT_START ";--"
65#define COMMENT_END "--;"
66#define COMMENT_META ';'
67#define COMMENT_TAG '-'
74#define MIN_VARIABLE_FNAME_SPACE 40
82 const char *
match,
char sep);
122 return *
str ? 0 : -1;
218#define MAX_INCLUDE_LEVEL 10
292 int name_len = strlen(
name) + 1;
293 int val_len = strlen(
value) + 1;
294 int fn_len = strlen(filename) + 1;
301 variable =
__ast_calloc(1, fn_len + name_len + val_len +
sizeof(*variable),
304 char *dst = variable->
stuff;
307 variable->
file = strcpy(dst, filename);
349 snprintf(real_included_file_name, real_included_file_name_size,
"%s~~%d", included_file, inc->
inclusion_count);
350 }
while (stat(real_included_file_name, &statbuf) == 0);
351 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);
353 *real_included_file_name = 0;
379 conf->includes = inc;
390 int from_len = strlen(from_file);
391 int to_len = strlen(to_file);
393 if (strcmp(from_file, to_file) == 0)
405 for (incl =
conf->includes; incl; incl=incl->
next) {
407 if (from_len >= to_len)
419 for (cat =
conf->root; cat; cat = cat->
next) {
424 if (strcmp(cat->
file,from_file) == 0) {
425 if (from_len >= to_len)
426 strcpy(cat->
file, to_file);
437 if (strcmp(v->
file, from_file)) {
449 strcpy(
str, to_file);
464 if (cat->
last == v) {
479 for (x=
conf->includes;x;x=x->
next) {
494 category->
root = variable;
495 category->
last = variable;
506 if (!variable || sscanf(line,
"%30d", &insertline) != 1) {
511 category->
root = variable;
520 cur->
next = variable;
555 while ((
var =
var->next)) {
572 if (!var1 || !var1->
next) {
605 if (
config->last_browse && (
config->last_browse->name == category)) {
606 cat =
config->last_browse;
626 memset(&top, 0,
sizeof(top));
659 for (curr = sh; 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)) {
689 for (v = *head; v; prev = &v->
next, v = v->
next) {
702 const char *name_value_separator,
const char *quote_char,
struct ast_str **
str)
718 var->value,
S_OR(quote_char,
""),
var->next ? item_separator :
"");
728 const char *name_value_separator,
const char *quote_str)
745 nv_sep =
ast_strlen_zero(name_value_separator) ?
'=' : name_value_separator[0];
769 const char *name_value_separator)
798 if (!strcasecmp(variable, v->
name)) {
805 for (cat =
config->root; cat; cat = cat->
next) {
806 for (v = cat->
root; v; v = v->
next) {
807 if (!strcasecmp(variable, v->
name)) {
818 const char *category,
const char *variable,
const char *
filter)
842 for (v = list; v; v = v->
next) {
843 if (!strcasecmp(variable_name, v->
name)) {
858 if (!(left && right)) {
862 op = strrchr(right->
name,
' ');
880 if (!(left && right)) {
884 for (field = right; field; field = field->
next) {
885 char *space = strrchr(field->
name,
' ');
903 if (!old || strcmp(old->
value, field->
value)) {
916 for (field = left; field; field = field->
next) {
920 if (right_count != left_count) {
932 for (v = list; v; v = v->
next) {
933 if (!strcasecmp(variable, v->
name)) {
943 const char *found =
NULL;
945 for (v = list; v; v = v->
next) {
946 if (!strcasecmp(variable, v->
name)) {
958 new->lineno = old->
lineno;
959 new->object = old->
object;
980 const char *
match,
char sep)
984 int match_found = 0, match_expressions = 0;
1002 char *match_value =
NULL;
1005 regex_t r_name, r_value;
1007 match_expressions++;
1013 if (match_value ==
NULL) {
1017 if (!strcmp(
"TEMPLATES", match_name)) {
1018 if (!strcasecmp(
"include", match_value)) {
1023 }
else if (!strcasecmp(
"restrict", match_value)) {
1034 if ((rc = regcomp(&r_name, match_name, REG_EXTENDED | REG_NOSUB))) {
1036 regerror(rc, &r_name, regerr, 128);
1038 match_name, regerr);
1042 if ((rc = regcomp(&r_value, match_value, REG_EXTENDED | REG_NOSUB))) {
1044 regerror(rc, &r_value, regerr, 128);
1046 match_value, regerr);
1052 for (v = cat->
root; v; v = v->
next) {
1053 if (!regexec(&r_name, v->
name, 0,
NULL, 0)
1054 && !regexec(&r_value, v->
value, 0,
NULL, 0)) {
1062 if (match_found == match_expressions && (!cat->
ignored || template_ok)) {
1078 if (!category->
file) {
1099 const char *category_name,
const char *
filter,
char sep,
char pointer_match_possible)
1103 if (pointer_match_possible) {
1104 for (cat =
config->root; cat; cat = cat->
next) {
1111 for (cat =
config->root; cat; cat = cat->
next) {
1121 const char *category_name,
const char *
filter)
1128 return category->
name;
1168 config->last->next = category;
1178 config->current = category;
1192 config->root->prev = cat;
1197 for (cur_category =
config->root->next; cur_category; cur_category = cur_category->
next) {
1198 if (!strcasecmp(cur_category->
name,
match)) {
1202 cat->
next = cur_category;
1203 cur_category->
prev = cat;
1237 for (incl=incls; incl; incl = inclnext) {
1238 inclnext = incl->
next;
1265 return category->
root;
1301 int nmerges, psize, qsize, i;
1327 for (i = 0; i < insize; i++) {
1339 while (psize > 0 || (qsize > 0 && q)) {
1346 }
else if (qsize == 0 || !q) {
1348 e = p; p = p->
next; psize--;
1349 }
else if ((comparator(p,q) * descending) <= 0) {
1394 }
else if (
config->last_browse && (
config->last_browse->name == prev_name)) {
1396 cat =
config->last_browse->next;
1404 for (cat =
config->root; cat; cat = cat->
next) {
1405 if (cat->
name == prev_name) {
1416 for (cat =
config->root; cat; cat = cat->
next) {
1417 if (!strcasecmp(cat->
name, prev_name)) {
1429 config->last_browse = cat;
1507 if (sscanf(line,
"%30d", &req_item) != 1
1515 cur = category->
root;
1519 if ((0 <= req_item && num_item == req_item)
1520 || (req_item < 0 && !strcasecmp(cur->
name, variable)
1524 if (cur == category->
last)
1528 if (cur == category->
last)
1543 const char *
value,
const char *
match,
unsigned int object)
1547 for (cur = category->
root; cur;
prev = cur, cur = cur->
next) {
1548 if (strcasecmp(cur->
name, variable) ||
1554 for (cur = category->
root; cur;
prev = cur, cur = cur->
next) {
1555 if (cur != matchvar) {
1562 newer->object = newer->object || object;
1565 newer->next = cur->
next;
1569 category->
root = newer;
1570 if (category->
last == cur)
1571 category->
last = newer;
1587 if (!
config || !category) {
1591 if (category->
prev) {
1597 if (category->
next) {
1605 if (
config->last_browse == category) {
1672 sizeof(*cfmtime) + strlen(filename) + 1 + strlen(who_asked) + 1);
1677 strcpy(dst, filename);
1678 dst += strlen(dst) + 1;
1679 cfmtime->
who_asked = strcpy(dst, who_asked);
1699#if defined(HAVE_STRUCT_STAT_ST_MTIM)
1701#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC)
1703#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC)
1775 if (!strcmp(cfmtime->
filename, filename)
1776 && !strcmp(cfmtime->
who_asked, who_asked)) {
1794 if (!strcmp(cfmtime->
filename, configfile) && !strcmp(cfmtime->
who_asked, who_asked))
1810 if (!strcmp(cfinclude->
include, filename)) {
1815 cfinclude =
ast_calloc(1,
sizeof(*cfinclude) + strlen(filename) + 1);
1820 strcpy(cfinclude->
include, filename);
1849 struct stat output_file_info;
1852 if (snprintf(
buf,
sizeof(
buf),
"%s 2>&1 > %s", command, output_file) >=
sizeof(
buf)) {
1853 ast_log(
LOG_ERROR,
"Failed to construct command string to execute %s.\n", command);
1861 fp = popen(
buf,
"r");
1870 while (fgets(
buf,
sizeof(
buf), fp)) {
1872 if (strlen(
buf) ==
sizeof(
buf) - 1 &&
buf[
sizeof(
buf) - 2] !=
'\n') {
1878 while (fgets(
buf,
sizeof(
buf), fp)) {
1879 if (strlen(
buf) !=
sizeof(
buf) - 1 ||
buf[
sizeof(
buf) - 2] ==
'\n') {
1910 if (stat(output_file, &output_file_info) == -1) {
1911 ast_log(
LOG_ERROR,
"#exec <%s>: Unable to stat() temporary file `%s': %s\n",
1915 }
else if (output_file_info.st_size == 0) {
1934 const char *suggested_include_file,
1940 char exec_file[512];
1943 if (cur[0] ==
'[') {
1955 c = strchr(cur,
']');
1983 if (!(cur = strchr(
c,
')'))) {
1989 while ((cur =
strsep(&
c,
","))) {
1990 if (!strcasecmp(cur,
"!")) {
1991 (*cat)->ignored = 1;
1992 }
else if (cur[0] ==
'+') {
1995 if (cur[1] !=
',') {
2003 ast_log(
LOG_WARNING,
"Category addition requested, but category '%s' does not exist, line %d of %s\n", catname,
lineno, configfile);
2008 (*cat)->ignored |= newcat->
ignored;
2021 ast_log(
LOG_WARNING,
"Inheritance requested, but category '%s' does not exist, line %d of %s\n", cur,
lineno, configfile);
2047 }
else if (cur[0] ==
'#') {
2049 char real_inclusion_name[256];
2055 while (*
c && (*
c > 32)) {
2069 if (!strcasecmp(cur,
"include")) {
2071 }
else if (!strcasecmp(cur,
"tryinclude")) {
2074 }
else if (!strcasecmp(cur,
"exec")) {
2076 ast_log(
LOG_WARNING,
"Cannot perform #exec unless execincludes option is enabled in asterisk.conf (options section)!\n");
2086 do_include ?
"include / tryinclude" :
"exec",
2087 do_include ?
"filename" :
"/path/to/executable",
2096 if ((*
c ==
'"') || (*
c ==
'<')) {
2097 char quote_char = *
c;
2098 if (quote_char ==
'<') {
2102 if (*(
c + strlen(
c) - 1) == quote_char) {
2104 *(
c + strlen(
c) - 1) =
'\0';
2116 snprintf(exec_file,
sizeof(exec_file),
"/var/tmp/exec.%d%d.%ld", (
int)now.tv_sec, (
int)now.tv_usec, (
long)pthread_self());
2124 exec_file[0] =
'\0';
2134 ast_log(
LOG_ERROR,
"The file '%s' was listed as a #include but it does not exist.\n", cur);
2146 "parse error: No category context for line %d of %s\n",
lineno, configfile);
2150 is_escaped = cur[0] ==
'\\';
2159 c = strchr(cur + is_escaped,
'=');
2161 if (
c &&
c > cur + is_escaped && (*(
c - 1) ==
'+')) {
2175 if (!strcmp(
var->name, cur)) {
2182 goto set_new_variable;
2230#if defined(LOW_MEMORY)
2235 char *new_buf, *comment_p, *process_buf;
2241 struct stat statbuf;
2256 if (filename[0] ==
'/') {
2274 globbuf.gl_offs = 0;
2276 if (glob_ret == GLOB_NOSPACE) {
2278 "Glob Expansion of pattern '%s' failed: Not enough memory\n", fn);
2281 "Glob Expansion of pattern '%s' failed: Read error\n", fn);
2286 if (!cfg && (globbuf.gl_pathc != 1 || strcmp(fn, globbuf.gl_pathv[0]))) {
2299 for (i=0; i<globbuf.gl_pathc; i++) {
2308 if (stat(fn, &statbuf)) {
2315 if (!S_ISREG(statbuf.st_mode)) {
2351 NULL, flags,
"", who_asked)) {
2384 if (!(f = fopen(fn,
"r"))) {
2385 ast_debug(1,
"No file to parse: %s\n", fn);
2386 ast_verb(2,
"Parsing '%s': Not found (%s)\n", fn, strerror(
errno));
2395 if (fgets(
buf,
sizeof(
buf), f)) {
2397 if (strlen(
buf) ==
sizeof(
buf) - 1 &&
buf[
sizeof(
buf) - 2] !=
'\n') {
2399 while (fgets(
buf,
sizeof(
buf), f)) {
2400 if (strlen(
buf) !=
sizeof(
buf) - 1 ||
buf[
sizeof(
buf) - 2] ==
'\n') {
2409#define UTF8_BOM "\xEF\xBB\xBF"
2410 size_t line_bytes = strlen(
buf);
2411 size_t bom_bytes =
sizeof(
UTF8_BOM) - 1;
2412 if (line_bytes >= bom_bytes
2414 memmove(
buf, &
buf[bom_bytes], line_bytes - bom_bytes + 1);
2443 if ((comment_p > new_buf) && (*(comment_p - 1) ==
'\\')) {
2445 new_buf = comment_p;
2447 memmove(comment_p - 1, comment_p, strlen(comment_p) + 1);
2452 new_buf = comment_p + 3;
2458 }
else if ((comment_p >= new_buf + 2) &&
2463 new_buf = comment_p + 1;
2470 oldptr = process_buf + strlen(process_buf);
2476 memmove(oldptr, new_buf, strlen(new_buf) + 1);
2479 process_buf = new_buf;
2490 new_buf = comment_p;
2492 new_buf = comment_p + 1;
2506 suggested_include_file, &last_cat, &last_var,
2524 }
else if (last_var) {
2584static void gen_header(FILE *f1,
const char *configfile,
const char *fn,
const char *generator)
2592 fprintf(f1,
";!\n");
2593 fprintf(f1,
";! Automatically generated configuration file\n");
2594 if (strcmp(configfile, fn))
2595 fprintf(f1,
";! Filename: %s (%s)\n", configfile, fn);
2597 fprintf(f1,
";! Filename: %s\n", configfile);
2598 fprintf(f1,
";! Generator: %s\n", generator);
2599 fprintf(f1,
";! Creation Date: %s", date);
2600 fprintf(f1,
";!\n");
2610static void make_fn(
char *fn,
size_t fn_size,
const char *
file,
const char *configfile)
2613 if (configfile[0] ==
'/') {
2618 }
else if (
file[0] ==
'/') {
2682 int precomment_lines;
2698 }
else if (
lineno == 0) {
2701 }
else if (
lineno - precomment_lines - fi->
lineno < 5) {
2704 for (i = fi->
lineno; i <
lineno - precomment_lines; i++) {
2723 if (access(fn, F_OK)) {
2726 if (access(dn, R_OK | W_OK)) {
2731 if (access(fn, R_OK | W_OK)) {
2775 make_fn(fn,
sizeof(fn), 0, configfile);
2802 fi =
set_fn(fn,
sizeof(fn), 0, configfile, fileset);
2805 (f = fopen(fn,
"w+"))
2807 (f = fopen(fn,
"w"))
2823 fi =
set_fn(fn,
sizeof(fn), cat->
file, configfile, fileset);
2839 fprintf(f,
"#exec \"%s\"\n", incl->
exec_file);
2850 char *cmtp = cmt->
cmt;
2851 while (cmtp && *cmtp ==
';' && *(cmtp+1) ==
'!') {
2852 char *cmtp2 = strchr(cmtp+1,
'\n');
2858 fprintf(f,
"%s", cmtp);
2860 fprintf(f,
"[%s]", cat->
name);
2872 fprintf(f,
"%s",x->
name);
2881 fprintf(f,
"%s", cmt->
cmt);
2886 if (cmt->
cmt[0] !=
';' || cmt->
cmt[1] !=
'!')
2887 fprintf(f,
"%s", cmt->
cmt);
2904 if (!strcasecmp(
var->name, v->
name) && !strcmp(
var->value, v->
value)) {
2909 if (
var->inherited) {
2913 if (!strcasecmp(
var->name, v->
name) && !strcmp(
var->value, v->
value)) {
2928 fi =
set_fn(fn,
sizeof(fn),
var->file, configfile, fileset);
2931 ast_debug(1,
"Unable to open for writing: %s\n", fn);
2932 ast_verb(2,
"Unable to write %s (%s)\n", fn, strerror(
errno));
2945 fprintf(f,
"#exec \"%s\"\n", incl->
exec_file);
2954 for (cmt =
var->precomments; cmt; cmt=cmt->
next) {
2955 if (cmt->
cmt[0] !=
';' || cmt->
cmt[1] !=
'!')
2956 fprintf(f,
"%s", cmt->
cmt);
2960 int escaped_len = 2 * strlen(
var->value) + 1;
2961 char escaped[escaped_len];
2965 if (
var->sameline) {
2966 fprintf(f,
"%s %s %s %s",
var->name, (
var->object ?
"=>" :
"="),
2967 escaped,
var->sameline->cmt);
2969 fprintf(f,
"%s %s %s\n",
var->name, (
var->object ?
"=>" :
"="),
2974 for (cmt =
var->trailing; cmt; cmt=cmt->
next) {
2975 if (cmt->
cmt[0] !=
';' || cmt->
cmt[1] !=
'!')
2976 fprintf(f,
"%s", cmt->
cmt);
2978 if (
var->blanklines) {
2979 blanklines =
var->blanklines;
2980 while (blanklines--)
2993 ast_verb(2,
"Saving '%s': saved\n", fn);
2995 ast_debug(1,
"Unable to open for writing: %s\n", fn);
2996 ast_verb(2,
"Unable to write '%s' (%s)\n", fn, strerror(
errno));
3012 ast_debug(1,
"Unable to open for writing: %s\n", fn);
3013 ast_verb(2,
"Unable to write %s (%s)\n", fn, strerror(
errno));
3023 fprintf(f,
"#exec \"%s\"\n", incl->
exec_file);
3052#ifdef TEST_FRAMEWORK
3062 length =
sizeof(*map);
3063 length += strlen(
name) + 1;
3064 length += strlen(driver) + 1;
3065 length += strlen(database) + 1;
3067 length += strlen(
table) + 1;
3074 dst += strlen(dst) + 1;
3075 map->
driver = strcpy(dst, driver);
3076 dst += strlen(dst) + 1;
3077 map->
database = strcpy(dst, database);
3079 dst += strlen(dst) + 1;
3095 char *driver, *
table, *database, *textpri, *stringp, *
tmp;
3119 driver =
strsep(&stringp,
",");
3124 if ((
tmp = strchr(stringp,
'\"')))
3128 if (*stringp ==
'"') {
3130 database =
strsep(&stringp,
"\"");
3134 database =
strsep(&stringp,
",");
3138 textpri =
strsep(&stringp,
",");
3139 if (!textpri || !(pri = atoi(textpri))) {
3148 if (!strcmp(v->
name,
"asterisk.conf")) {
3153 if (!strcmp(v->
name,
"logger.conf")) {
3158 if (!driver || !database)
3160 if (!strcasecmp(v->
name,
"iaxfriends")) {
3161 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");
3214 if (!strcasecmp(family, map->
name)) {
3218 ast_debug(5,
"Failed to find a realtime mapping for %s\n", family);
3244 if (!strcasecmp(eng->name, map->
driver))
3270 for (cat_iter = old->
root; cat_iter; cat_iter = cat_iter->
next) {
3277 if (cat_iter->
root) {
3279 if (!new_cat->
root) {
3352#define realtime_arguments_to_fields(ap, result) realtime_arguments_to_fields2(ap, 0, result)
3370 const char *newparam;
3406 newparam = va_arg(ap,
const char *);
3407 newval = va_arg(ap,
const char *);
3408 while ((newparam = va_arg(ap,
const char *))) {
3409 newval = va_arg(ap,
const char *);
3414 newparam = va_arg(ap,
const char *);
3419 newval = va_arg(ap,
const char *);
3426 while ((newparam = va_arg(ap,
const char *))) {
3429 newval = va_arg(ap,
const char *);
3437 field->
next = fields;
3456 for (i = 1; ; i++) {
3475 va_start(ap, family);
3508 if (cur->
value[0] ==
' ' && cur->
value[1] ==
'\0') {
3509 char *vptr = (
char *) cur->
value;
3527 va_start(ap, family);
3572 va_start(ap, family);
3573 for (i = 1; ; i++) {
3598 for (i = 1; ; i++) {
3619 for (i = 1; ; i++) {
3642 va_start(ap, family);
3660 for (i = 1; ; i++) {
3679 va_start(ap, lookup);
3697 for (i = 1; ; i++) {
3716 va_start(ap, family);
3723 va_start(ap, family);
3727 if (!lookup_fields || !update_fields) {
3741 for (i = 1; ; i++) {
3760 va_start(ap, family);
3778 for (i = 1; ; i++) {
3797 va_start(ap, lookup);
3813 for (; *chunk; chunk++) {
3814 if (*chunk ==
'^' && strchr(
"0123456789ABCDEFabcdef", chunk[1]) && strchr(
"0123456789ABCDEFabcdef", chunk[2])) {
3815 sscanf(chunk + 1,
"%02hhX", (
unsigned char *)chunk);
3816 memmove(chunk + 1, chunk + 3, strlen(chunk + 3) + 1);
3824 if (!strchr(chunk,
';') && !strchr(chunk,
'^')) {
3828 for (; *chunk; chunk++) {
3829 if (strchr(
";^", *chunk)) {
3843 void *p_result, ...)
3848 va_start(ap, p_result);
3855 char *endptr =
NULL;
3870 x = strtol(arg, &endptr, 0);
3876 error = (x < low) || (x > high);
3880 }
else if (x > high) {
3892 ast_debug(3,
"extract int from [%s] in [%d, %d] gives [%ld](%d)\n",
3899 unsigned long int x = 0;
3900 uint32_t *
result = p_result;
3902 char *endptr =
NULL;
3906 def = va_arg(ap, uint32_t);
3910 low = va_arg(ap, uint32_t);
3911 high = va_arg(ap, uint32_t);
3925 x = strtoul(arg, &endptr, 0);
3930 error = (x < low) || (x > high);
3934 }
else if (x > high) {
3945 ast_debug(3,
"extract uint from [%s] in [%u, %u] gives [%lu](%d)\n",
3962 def = va_arg(ap,
int);
3965 low = va_arg(ap,
int);
3966 high = va_arg(ap,
int);
3973 if (
error || x < INT_MIN || x > INT_MAX) {
3978 error = (x < low) || (x > high);
3982 }
else if (x > high) {
3994 ast_debug(3,
"extract timelen from [%s] in [%d, %d] gives [%d](%d)\n",
4001 double *
result = p_result;
4002 double x = 0, def =
result ? *
result : 0, low = -HUGE_VAL, high = HUGE_VAL;
4003 char *endptr =
NULL;
4007 def = va_arg(ap,
double);
4011 low = va_arg(ap,
double);
4012 high = va_arg(ap,
double);
4019 x = strtod(arg, &endptr);
4020 if (*endptr ||
errno == ERANGE) {
4024 error = (x < low) || (x > high);
4032 ast_debug(3,
"extract double from [%s] in [%f, %f] gives [%f](%d)\n",
4044 ast_debug(3,
"extract addr from %s gives %s(%d)\n",
4052 struct sockaddr_in _sa_buf;
4053 struct sockaddr_in *sa = p_result ?
4054 (
struct sockaddr_in *)p_result : &_sa_buf;
4057 va_arg(ap,
struct sockaddr_in *) : sa;
4060 memset(&_sa_buf,
'\0',
sizeof(_sa_buf));
4064 sa->sin_family = AF_INET;
4073 sa->sin_port = def->sin_port;
4075 sa->sin_port = def->sin_port;
4077 sa->sin_port = htons(strtol(port,
NULL, 0));
4079 sa->sin_port = def->sin_port;
4086 sa->sin_addr = def->sin_addr;
4088 struct sockaddr_in
tmp;
4090 sa->sin_addr =
tmp.sin_addr;
4093 "extract inaddr from [%s] gives [%s:%d](%d)\n",
4095 ntohs(sa->sin_port),
error);
4110 e->
command =
"core show config mappings";
4112 "Usage: core show config mappings\n"
4113 " Shows the filenames to config engines.\n";
4123 ast_cli(
a->fd,
"No config mappings found.\n");
4150 "Usage: config reload <filename.conf>\n"
4151 " Reloads all modules that reference <filename.conf>\n";
4158 wordlen = strlen(
a->word);
4172 if (!strncmp(cfmtime->
filename,
a->word, wordlen)) {
4192 if (!strcmp(cfmtime->
filename,
a->argv[2])) {
4211 "Usage: config list\n"
4212 " Show all modules that have loaded a configuration file\n";
4307 if (!strcasecmp(hook->
filename, filename) &&
4308 !strcasecmp(hook->
module, module)) {
4318 const char *filename,
4354 ast_verb(0,
"[ Initializing Custom Configuration Options ]\n");
struct sla_ringing_trunk * first
struct sla_ringing_trunk * last
static int copy(char *infile, char *outfile)
Utility function to copy a file.
static int input(yyscan_t yyscanner)
Asterisk main include file. File version handling, generic pbx functions.
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
#define ast_strdup(str)
A wrapper for strdup()
#define ast_strdupa(s)
duplicate a string in memory from the stack
void ast_free_ptr(void *ptr)
free() wrapper
void * __ast_calloc(size_t nmemb, size_t size, const char *file, int lineno, const char *func) attribute_malloc
#define ast_calloc(num, len)
A wrapper for calloc()
#define ao2_iterator_next(iter)
#define ao2_link(container, obj)
Add an object to a container.
@ AO2_ALLOC_OPT_LOCK_MUTEX
#define ao2_find(container, arg, flags)
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ao2_alloc(data_size, destructor_fn)
#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.
static int match(struct ast_sockaddr *addr, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
static const char config[]
General Asterisk PBX channel definitions.
#define AST_MAX_USER_FIELD
Standard Command Line Interface.
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
#define AST_CLI_DEFINE(fn, txt,...)
int ast_cli_completion_add(char *value)
Add a result to a request for completion options.
void ast_cli(int fd, const char *fmt,...)
ast_cli_command
calling arguments for new-style handlers.
#define ast_cli_register_multiple(e, len)
Register multiple commands.
static char * lline_buffer
static char * comment_buffer
static int replace(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)
static int quote(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static int filter(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
Application convenience functions, designed to give consistent look and feel to Asterisk apps.
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.
void ast_replace_sigchld(void)
Replace the SIGCHLD handler.
void ast_unreplace_sigchld(void)
Restore the SIGCHLD handler.
char * strsep(char **str, const char *delims)
Configuration File Parser.
#define ast_variable_new(name, value, filename)
#define ast_variable_list_append(head, new_var)
#define CONFIG_STATUS_FILEUNCHANGED
@ CONFIG_SAVE_FLAG_PRESERVE_EFFECTIVE_CONTEXT
#define CONFIG_STATUS_FILEINVALID
ast_parse_flags
Support code to parse config file arguments.
int(* config_hook_cb)(struct ast_config *cfg)
Callback when configuration is updated.
config_hook_flags
Flags that affect the behaviour of config hooks.
@ CONFIG_FLAG_WITHCOMMENTS
@ CONFIG_FLAG_FILEUNCHANGED
#define ast_debug(level,...)
Log a DEBUG message.
#define ast_verb(level,...)
#define AST_LIST_HEAD_STATIC(name, type)
Defines a structure to be used to hold a list of specified type, statically initialized.
#define AST_LIST_HEAD_NOLOCK(name, type)
Defines a structure to be used to hold a list of specified type (with no lock).
#define AST_LIST_INSERT_SORTALPHA(head, elm, field, sortfield)
Inserts a list entry into a alphabetically sorted list.
#define AST_LIST_LAST(head)
Returns the last entry contained in a list.
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
#define AST_LIST_LOCK(head)
Locks a list.
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Asterisk locking-related definitions:
#define SCOPED_MUTEX(varname, lock)
scoped lock specialization for mutexes
#define AST_MUTEX_DEFINE_STATIC(mutex)
void ast_include_rename(struct ast_config *conf, const char *from_file, const char *to_file)
static void config_cache_flush_includes(struct cache_file_mtime *cfmtime)
struct ast_variable * ast_variable_list_from_quoted_string(const char *input, const char *item_separator, const char *name_value_separator, const char *quote_str)
Parse a string into an ast_variable list. The reverse of ast_variable_list_join.
static struct ast_cli_entry cli_config[]
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
#define MAX_NESTED_COMMENTS
const char * ast_category_get_name(const struct ast_category *category)
Return the name of the category.
void ast_variable_append(struct ast_category *category, struct ast_variable *variable)
struct ast_category * ast_category_new_template(const char *name, const char *in_file, int lineno)
Create a category making it a template.
struct ast_variable * ast_category_detach_variables(struct ast_category *cat)
static void config_shutdown(void)
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
static void ast_includes_destroy(struct ast_config_include *incls)
int ast_store_realtime(const char *family,...)
Create realtime configuration.
static int cfmstat_cmp(struct cache_file_mtime *cfmtime, struct stat *statbuf)
int ast_variables_match(const struct ast_variable *left, const struct ast_variable *right)
Tests 2 variable values to see if they match.
int ast_store_realtime_fields(const char *family, const struct ast_variable *fields)
Create realtime configuration.
#define MIN_VARIABLE_FNAME_SPACE
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.
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_category_rename(struct ast_category *cat, const char *name)
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 void config_cache_attribute(const char *configfile, enum config_cache_attribute_enum attrtype, const char *filename, const char *who_asked)
int ast_update_realtime(const char *family, const char *keyfield, const char *lookup,...)
Update realtime configuration.
int ast_destroy_realtime_fields(const char *family, const char *keyfield, const char *lookup, const struct ast_variable *fields)
Destroy realtime configuration.
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_variable_delete(struct ast_category *category, const char *variable, const char *match, const char *line)
int ast_realtime_require_field(const char *family,...)
Inform realtime what fields that may be stored.
struct ast_config * ast_config_copy(const struct ast_config *old)
Copies the contents of one ast_config into another.
void ast_config_hook_unregister(const char *name)
Unregister a config hook.
int ast_category_insert(struct ast_config *config, struct ast_category *cat, const char *match)
Inserts new category.
struct ast_category * ast_category_delete(struct ast_config *config, struct ast_category *category)
Delete a category.
char * ast_realtime_encode_chunk(struct ast_str **dest, ssize_t maxlen, const char *chunk)
Encodes a chunk of data for realtime.
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
static void config_cache_remove(const char *filename, const char *who_asked)
struct ast_variable * ast_variable_list_from_string(const char *input, const char *item_separator, const char *name_value_separator)
Parse a string into an ast_variable list. The reverse of ast_variable_list_join.
static int count_linefeeds_in_comments(struct ast_comment *x)
static ast_mutex_t config_lock
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 hook_hash(const void *obj, const int flags)
static char * handle_cli_config_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
struct ast_config * ast_config_new(void)
Create a new base configuration structure.
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)
static void ast_variable_destroy(struct ast_variable *doomed)
#define realtime_arguments_to_fields(ap, result)
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.
struct ast_variable * ast_variables_reverse(struct ast_variable *var)
Reverse a variable list.
int ast_realtime_enabled(void)
Check if there's any realtime engines loaded.
static int init_appendbuf(void *data)
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.
int ast_unload_realtime(const char *family)
Release any resources cached for a realtime family.
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)
static void insert_leading_blank_lines(FILE *fp, struct inclfile *fi, struct ast_comment *precomments, int lineno)
static int hashtab_compare_strings(void *a, void *b, int flags)
static struct ast_category * next_available_category(struct ast_category *cat, const char *name, const char *filter)
config_cache_attribute_enum
struct ast_str * ast_category_get_templates(const struct ast_category *category)
Return the template names this category inherits from.
int ast_config_engine_deregister(struct ast_config_engine *del)
Deregister config engine.
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)
static int realtime_arguments_to_fields2(va_list ap, int skip, struct ast_variable **result)
struct ast_variable * ast_load_realtime_all(const char *family,...)
void ast_config_set_current_category(struct ast_config *cfg, const struct ast_category *cat)
Set the category within the configuration as being current.
struct ast_category * ast_category_new(const char *name, const char *in_file, int lineno)
Create a category.
struct ast_variable * ast_load_realtime(const char *family,...)
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.
static int reload_module(void)
int ast_update2_realtime(const char *family,...)
Update realtime configuration.
int ast_realtime_is_mapping_defined(const char *family)
Determine if a mapping exists for a given family.
int ast_config_engine_register(struct ast_config_engine *new)
Register config engine.
struct ast_category * ast_config_get_current_category(const struct ast_config *cfg)
Retrieve the current category name being built.
static void move_variables(struct ast_category *old, struct ast_category *new)
struct ast_config * ast_load_realtime_multientry(const char *family,...)
Retrieve realtime configuration.
static int count_linefeeds(char *str)
char * ast_realtime_decode_chunk(char *chunk)
Remove standard encoding from realtime values, which ensures that a semicolon embedded within a singl...
static void gen_header(FILE *f1, const char *configfile, const char *fn, const char *generator)
static void ast_destroy_template_list(struct ast_category *cat)
void ast_category_append(struct ast_config *config, struct ast_category *category)
Appends a category to a config.
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.
int ast_check_realtime(const char *family)
Check if realtime engine is configured for family.
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.
struct ast_variable * ast_load_realtime_all_fields(const char *family, const struct ast_variable *fields)
static char * handle_cli_core_show_config_mappings(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
struct ast_variable * ast_variables_dup(struct ast_variable *var)
Duplicate variable list.
struct ast_variable * ast_category_root(struct ast_config *config, char *cat)
returns the root ast_variable of a config
static void clear_config_maps(void)
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category)
static struct ast_threadstorage appendbuf
static void ast_variable_move(struct ast_variable *dst_var, struct ast_variable *src_var)
static void CB_RESET(struct ast_str *cb, struct ast_str *llb)
static void ast_comment_destroy(struct ast_comment **comment)
int ast_category_empty(struct ast_category *category)
Removes and destroys all variables in a category.
static struct ast_variable * variable_clone(const struct ast_variable *old)
int ast_category_is_template(const struct ast_category *category)
Check if category is a template.
static void config_cache_destroy_entry(struct cache_file_mtime *cfmtime)
struct ast_str * ast_variable_list_join(const struct ast_variable *head, const char *item_separator, const char *name_value_separator, const char *quote_char, struct ast_str **str)
Join an ast_variable list with specified separators and quoted values.
static struct ast_config_map * config_maps
static int hash_string(const void *obj, const int flags)
static struct ao2_container * cfg_hooks
#define MAX_INCLUDE_LEVEL
struct ast_variable * ast_load_realtime_fields(const char *family, const struct ast_variable *fields)
Retrieve realtime configuration.
int ast_variable_list_replace(struct ast_variable **head, struct ast_variable *replacement)
Replace a variable in the given list with a new value.
static int handle_include_exec(const char *command, const char *output_file)
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
int ast_destroy_realtime(const char *family, const char *keyfield, const char *lookup,...)
Destroy 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.
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.
int ast_update_realtime_fields(const char *family, const char *keyfield, const char *lookup, const struct ast_variable *fields)
Update realtime configuration.
static void hook_destroy(void *obj)
static int hook_cmp(void *obj, void *arg, int flags)
void ast_category_destroy(struct ast_category *cat)
struct ast_variable * ast_category_first(struct ast_category *cat)
given a pointer to a category, return the root variable.
static struct inclfile * set_fn(char *fn, size_t fn_size, const char *file, const char *configfile, struct ao2_container *fileset)
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.
const char * ast_config_option(struct ast_config *cfg, const char *cat, const char *var)
Retrieve a configuration variable within the configuration set.
static void cfmstat_save(struct cache_file_mtime *cfmtime, struct stat *statbuf)
static int load_module(void)
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_sort(struct ast_variable *start)
Performs an in-place sort on the variable list by ascending name.
static void CB_ADD_LEN(struct ast_str **cb, const char *str, int len)
static int is_writable(const char *fn)
static int unload_module(void)
static void make_fn(char *fn, size_t fn_size, const char *file, const char *configfile)
void ast_variable_insert(struct ast_category *category, struct ast_variable *variable, const char *line)
int ast_variable_list_replace_variable(struct ast_variable **head, struct ast_variable *old, struct ast_variable *new)
Replace a variable in the given list with a new variable.
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.
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
static char * extconfig_conf
struct ast_config_include * ast_include_find(struct ast_config *conf, const char *included_file)
struct ast_variable * _ast_variable_new(const char *name, const char *value, const char *filename, const char *file, const char *func, int lineno)
static char * handle_cli_config_list(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static struct cache_file_mtime * cfmtime_new(const char *filename, const char *who_asked)
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_config * ast_load_realtime_multientry_fields(const char *family, const struct ast_variable *fields)
Retrieve realtime configuration.
static struct ast_category * new_category(const char *name, const char *in_file, int lineno, int template)
static struct ast_config_engine * config_engine_list
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 int ast_realtime_append_mapping(const char *name, const char *driver, const char *database, const char *table, int priority)
int ast_update2_realtime_fields(const char *family, const struct ast_variable *lookup_fields, const struct ast_variable *update_fields)
Update realtime configuration.
static void inclfile_destroy(void *obj)
int ast_category_inherit(struct ast_category *new, const struct ast_category *base)
Applies base (template) to category.
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_category * ast_category_get(const struct ast_config *config, const char *category_name, const char *filter)
Retrieve a category if it exists.
static struct ast_comment * ALLOC_COMMENT(struct ast_str *buffer)
static void config_hook_exec(const char *filename, const char *module, const struct ast_config *cfg)
static struct ast_config_engine text_file_engine
static void CB_ADD(struct ast_str **cb, const char *str)
static struct ast_variable * variable_list_switch(struct ast_variable *l1, struct ast_variable *l2)
int register_config_cli(void)
Exposed initialization method for core process.
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.
#define WEXITSTATUS(status)
#define WIFEXITED(status)
Asterisk module definitions.
@ AST_MODFLAG_GLOBAL_SYMBOLS
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
@ AST_MODULE_SUPPORT_CORE
#define ASTERISK_GPL_KEY
The text the key() function should return.
@ AST_MODULE_LOAD_FAILURE
Module could not be loaded properly.
@ AST_MODULE_LOAD_SUCCESS
int ast_sockaddr_resolve_first_af(struct ast_sockaddr *addr, const char *name, int flag, int family)
Return the first entry from ast_sockaddr_resolve filtered by address family.
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
#define ast_sockaddr_to_sin(addr, sin)
Converts a struct ast_sockaddr to a struct sockaddr_in.
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
Wrapper for network related headers, masking differences between various operating systems....
const char * ast_inet_ntoa(struct in_addr ia)
thread-safe replacement for inet_ntoa().
#define ast_opt_exec_includes
Asterisk file paths, configured in asterisk.conf.
const char * ast_config_AST_CONFIG_DIR
String manipulation functions.
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
static force_inline int attribute_pure ast_strlen_zero(const char *s)
char * ast_strsep_quoted(char **s, const char sep, const char quote, uint32_t flags)
Like ast_strsep() except you can specify a specific quote character.
void ast_str_trim_blanks(struct ast_str *buf)
Trims trailing whitespace characters from an ast_str string.
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
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.
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
char * ast_strsep(char **s, const char sep, uint32_t flags)
Act like strsep but ignore separators inside quotes.
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
struct ast_category_template_instance * next
const struct ast_category * inst
struct ast_comment * precomments
struct ast_category::template_instance_list template_instances
struct ast_category * next
struct ast_variable * last
struct ast_comment * trailing
struct ast_variable * root
struct ast_comment * sameline
struct ast_category * prev
char * file
The file name from whence this declaration was read.
descriptor for a cli entry.
Configuration engine structure, used to define realtime drivers.
realtime_var_get * realtime_func
struct ast_config_engine * next
realtime_destroy * destroy_func
realtime_unload * unload_func
realtime_store * store_func
realtime_multi_get * realtime_multi_func
config_load_func * load_func
realtime_update * update_func
realtime_update2 * update2_func
realtime_require * require_func
char * include_location_file
file name in which the include occurs
char * exec_file
if it's an exec, you'll have both the /var/tmp to read, and the original script
char * included_file
file name included
struct ast_config_include * next
int include_location_lineno
struct ast_config_map * next
struct ast_category * current
struct ast_category * last
struct ast_category * root
struct ast_config_include * includes
struct ast_category * last_browse
Structure used to handle boolean flags.
Socket address structure.
Support for dynamic strings.
Structure for variables, used for configurations and for channel variables.
char stuff[0]
Contents of file, name, and value in that order stuffed here.
struct ast_comment * precomments
struct ast_comment * trailing
struct ast_comment * sameline
struct ast_variable * next
Hold the mtime for config files, so if we don't need to reread our config, don't.
struct cache_file_include::@335 list
struct cache_file_mtime::includes includes
struct cache_file_mtime::@336 list
unsigned long stat_mtime_nsec
All configuration options for http media cache.
struct sla_ringing_trunk * next
static int hook_cb(struct ast_config *cfg)
static struct aco_type item
#define AST_THREADSTORAGE_CUSTOM(a, b, c)
Define a thread storage variable, with custom initialization and cleanup.
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.
Time-related functions and macros.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
int error(const char *format,...)
#define ast_test_flag(p, flag)
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
#define ast_clear_flag(p, flag)
char * ast_escape_semicolons(const char *string, char *outbuf, int buflen)
Escape semicolons found in a string.