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)
790 if (!strcasecmp(variable, v->
name)) {
797 for (cat =
config->root; cat; cat = cat->
next) {
798 for (v = cat->
root; v; v = v->
next) {
799 if (!strcasecmp(variable, v->
name)) {
810 const char *category,
const char *variable,
const char *
filter)
834 for (v = list; v; v = v->
next) {
835 if (!strcasecmp(variable_name, v->
name)) {
850 if (!(left && right)) {
854 op = strrchr(right->
name,
' ');
872 if (!(left && right)) {
876 for (field = right; field; field = field->
next) {
877 char *space = strrchr(field->
name,
' ');
895 if (!old || strcmp(old->
value, field->
value)) {
908 for (field = left; field; field = field->
next) {
912 if (right_count != left_count) {
924 for (v = list; v; v = v->
next) {
925 if (!strcasecmp(variable, v->
name)) {
935 const char *found =
NULL;
937 for (v = list; v; v = v->
next) {
938 if (!strcasecmp(variable, v->
name)) {
950 new->lineno = old->
lineno;
951 new->object = old->
object;
972 const char *
match,
char sep)
976 int match_found = 0, match_expressions = 0;
994 char *match_value =
NULL;
997 regex_t r_name, r_value;
1005 if (match_value ==
NULL) {
1009 if (!strcmp(
"TEMPLATES", match_name)) {
1010 if (!strcasecmp(
"include", match_value)) {
1015 }
else if (!strcasecmp(
"restrict", match_value)) {
1026 if ((rc = regcomp(&r_name, match_name, REG_EXTENDED | REG_NOSUB))) {
1028 regerror(rc, &r_name, regerr, 128);
1030 match_name, regerr);
1034 if ((rc = regcomp(&r_value, match_value, REG_EXTENDED | REG_NOSUB))) {
1036 regerror(rc, &r_value, regerr, 128);
1038 match_value, regerr);
1044 for (v = cat->
root; v; v = v->
next) {
1045 if (!regexec(&r_name, v->
name, 0,
NULL, 0)
1046 && !regexec(&r_value, v->
value, 0,
NULL, 0)) {
1054 if (match_found == match_expressions && (!cat->
ignored || template_ok)) {
1070 if (!category->
file) {
1091 const char *category_name,
const char *
filter,
char sep,
char pointer_match_possible)
1095 if (pointer_match_possible) {
1096 for (cat =
config->root; cat; cat = cat->
next) {
1103 for (cat =
config->root; cat; cat = cat->
next) {
1113 const char *category_name,
const char *
filter)
1120 return category->
name;
1160 config->last->next = category;
1170 config->current = category;
1184 config->root->prev = cat;
1189 for (cur_category =
config->root->next; cur_category; cur_category = cur_category->
next) {
1190 if (!strcasecmp(cur_category->
name,
match)) {
1194 cat->
next = cur_category;
1195 cur_category->
prev = cat;
1229 for (incl=incls; incl; incl = inclnext) {
1230 inclnext = incl->
next;
1257 return category->
root;
1293 int nmerges, psize, qsize, i;
1319 for (i = 0; i < insize; i++) {
1331 while (psize > 0 || (qsize > 0 && q)) {
1338 }
else if (qsize == 0 || !q) {
1340 e = p; p = p->
next; psize--;
1341 }
else if ((comparator(p,q) * descending) <= 0) {
1386 }
else if (
config->last_browse && (
config->last_browse->name == prev_name)) {
1388 cat =
config->last_browse->next;
1396 for (cat =
config->root; cat; cat = cat->
next) {
1397 if (cat->
name == prev_name) {
1408 for (cat =
config->root; cat; cat = cat->
next) {
1409 if (!strcasecmp(cat->
name, prev_name)) {
1421 config->last_browse = cat;
1499 if (sscanf(line,
"%30d", &req_item) != 1
1507 cur = category->
root;
1511 if ((0 <= req_item && num_item == req_item)
1512 || (req_item < 0 && !strcasecmp(cur->
name, variable)
1516 if (cur == category->
last)
1520 if (cur == category->
last)
1535 const char *
value,
const char *
match,
unsigned int object)
1539 for (cur = category->
root; cur;
prev = cur, cur = cur->
next) {
1540 if (strcasecmp(cur->
name, variable) ||
1548 newer->object = newer->object || object;
1551 newer->next = cur->
next;
1555 category->
root = newer;
1556 if (category->
last == cur)
1557 category->
last = newer;
1573 if (!
config || !category) {
1577 if (category->
prev) {
1583 if (category->
next) {
1591 if (
config->last_browse == category) {
1658 sizeof(*cfmtime) + strlen(filename) + 1 + strlen(who_asked) + 1);
1663 strcpy(dst, filename);
1664 dst += strlen(dst) + 1;
1665 cfmtime->
who_asked = strcpy(dst, who_asked);
1685#if defined(HAVE_STRUCT_STAT_ST_MTIM)
1687#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC)
1689#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC)
1761 if (!strcmp(cfmtime->
filename, filename)
1762 && !strcmp(cfmtime->
who_asked, who_asked)) {
1780 if (!strcmp(cfmtime->
filename, configfile) && !strcmp(cfmtime->
who_asked, who_asked))
1796 if (!strcmp(cfinclude->
include, filename)) {
1801 cfinclude =
ast_calloc(1,
sizeof(*cfinclude) + strlen(filename) + 1);
1806 strcpy(cfinclude->
include, filename);
1835 struct stat output_file_info;
1838 if (snprintf(
buf,
sizeof(
buf),
"%s 2>&1 > %s", command, output_file) >=
sizeof(
buf)) {
1839 ast_log(
LOG_ERROR,
"Failed to construct command string to execute %s.\n", command);
1847 fp = popen(
buf,
"r");
1856 while (fgets(
buf,
sizeof(
buf), fp)) {
1858 if (strlen(
buf) ==
sizeof(
buf) - 1 &&
buf[
sizeof(
buf) - 2] !=
'\n') {
1864 while (fgets(
buf,
sizeof(
buf), fp)) {
1865 if (strlen(
buf) !=
sizeof(
buf) - 1 ||
buf[
sizeof(
buf) - 2] ==
'\n') {
1896 if (stat(output_file, &output_file_info) == -1) {
1897 ast_log(
LOG_ERROR,
"#exec <%s>: Unable to stat() temporary file `%s': %s\n",
1901 }
else if (output_file_info.st_size == 0) {
1920 const char *suggested_include_file,
1926 char exec_file[512];
1929 if (cur[0] ==
'[') {
1941 c = strchr(cur,
']');
1969 if (!(cur = strchr(
c,
')'))) {
1975 while ((cur =
strsep(&
c,
","))) {
1976 if (!strcasecmp(cur,
"!")) {
1977 (*cat)->ignored = 1;
1978 }
else if (cur[0] ==
'+') {
1981 if (cur[1] !=
',') {
1989 ast_log(
LOG_WARNING,
"Category addition requested, but category '%s' does not exist, line %d of %s\n", catname,
lineno, configfile);
1994 (*cat)->ignored |= newcat->
ignored;
2007 ast_log(
LOG_WARNING,
"Inheritance requested, but category '%s' does not exist, line %d of %s\n", cur,
lineno, configfile);
2033 }
else if (cur[0] ==
'#') {
2035 char real_inclusion_name[256];
2041 while (*
c && (*
c > 32)) {
2055 if (!strcasecmp(cur,
"include")) {
2057 }
else if (!strcasecmp(cur,
"tryinclude")) {
2060 }
else if (!strcasecmp(cur,
"exec")) {
2062 ast_log(
LOG_WARNING,
"Cannot perform #exec unless execincludes option is enabled in asterisk.conf (options section)!\n");
2072 do_include ?
"include / tryinclude" :
"exec",
2073 do_include ?
"filename" :
"/path/to/executable",
2082 if ((*
c ==
'"') || (*
c ==
'<')) {
2083 char quote_char = *
c;
2084 if (quote_char ==
'<') {
2088 if (*(
c + strlen(
c) - 1) == quote_char) {
2090 *(
c + strlen(
c) - 1) =
'\0';
2102 snprintf(exec_file,
sizeof(exec_file),
"/var/tmp/exec.%d%d.%ld", (
int)now.tv_sec, (
int)now.tv_usec, (
long)pthread_self());
2110 exec_file[0] =
'\0';
2120 ast_log(
LOG_ERROR,
"The file '%s' was listed as a #include but it does not exist.\n", cur);
2132 "parse error: No category context for line %d of %s\n",
lineno, configfile);
2136 is_escaped = cur[0] ==
'\\';
2145 c = strchr(cur + is_escaped,
'=');
2147 if (
c &&
c > cur + is_escaped && (*(
c - 1) ==
'+')) {
2161 if (!strcmp(
var->name, cur)) {
2168 goto set_new_variable;
2216#if defined(LOW_MEMORY)
2221 char *new_buf, *comment_p, *process_buf;
2227 struct stat statbuf;
2242 if (filename[0] ==
'/') {
2260 globbuf.gl_offs = 0;
2262 if (glob_ret == GLOB_NOSPACE) {
2264 "Glob Expansion of pattern '%s' failed: Not enough memory\n", fn);
2267 "Glob Expansion of pattern '%s' failed: Read error\n", fn);
2272 if (!cfg && (globbuf.gl_pathc != 1 || strcmp(fn, globbuf.gl_pathv[0]))) {
2285 for (i=0; i<globbuf.gl_pathc; i++) {
2294 if (stat(fn, &statbuf)) {
2301 if (!S_ISREG(statbuf.st_mode)) {
2337 NULL, flags,
"", who_asked)) {
2370 if (!(f = fopen(fn,
"r"))) {
2371 ast_debug(1,
"No file to parse: %s\n", fn);
2372 ast_verb(2,
"Parsing '%s': Not found (%s)\n", fn, strerror(
errno));
2381 if (fgets(
buf,
sizeof(
buf), f)) {
2383 if (strlen(
buf) ==
sizeof(
buf) - 1 &&
buf[
sizeof(
buf) - 2] !=
'\n') {
2385 while (fgets(
buf,
sizeof(
buf), f)) {
2386 if (strlen(
buf) !=
sizeof(
buf) - 1 ||
buf[
sizeof(
buf) - 2] ==
'\n') {
2395#define UTF8_BOM "\xEF\xBB\xBF"
2396 size_t line_bytes = strlen(
buf);
2397 size_t bom_bytes =
sizeof(
UTF8_BOM) - 1;
2398 if (line_bytes >= bom_bytes
2400 memmove(
buf, &
buf[bom_bytes], line_bytes - bom_bytes + 1);
2429 if ((comment_p > new_buf) && (*(comment_p - 1) ==
'\\')) {
2431 new_buf = comment_p;
2433 memmove(comment_p - 1, comment_p, strlen(comment_p) + 1);
2438 new_buf = comment_p + 3;
2444 }
else if ((comment_p >= new_buf + 2) &&
2449 new_buf = comment_p + 1;
2456 oldptr = process_buf + strlen(process_buf);
2462 memmove(oldptr, new_buf, strlen(new_buf) + 1);
2465 process_buf = new_buf;
2476 new_buf = comment_p;
2478 new_buf = comment_p + 1;
2492 suggested_include_file, &last_cat, &last_var,
2510 }
else if (last_var) {
2570static void gen_header(FILE *f1,
const char *configfile,
const char *fn,
const char *generator)
2578 fprintf(f1,
";!\n");
2579 fprintf(f1,
";! Automatically generated configuration file\n");
2580 if (strcmp(configfile, fn))
2581 fprintf(f1,
";! Filename: %s (%s)\n", configfile, fn);
2583 fprintf(f1,
";! Filename: %s\n", configfile);
2584 fprintf(f1,
";! Generator: %s\n", generator);
2585 fprintf(f1,
";! Creation Date: %s", date);
2586 fprintf(f1,
";!\n");
2596static void make_fn(
char *fn,
size_t fn_size,
const char *
file,
const char *configfile)
2599 if (configfile[0] ==
'/') {
2604 }
else if (
file[0] ==
'/') {
2668 int precomment_lines;
2684 }
else if (
lineno == 0) {
2687 }
else if (
lineno - precomment_lines - fi->
lineno < 5) {
2690 for (i = fi->
lineno; i <
lineno - precomment_lines; i++) {
2709 if (access(fn, F_OK)) {
2712 if (access(dn, R_OK | W_OK)) {
2717 if (access(fn, R_OK | W_OK)) {
2761 make_fn(fn,
sizeof(fn), 0, configfile);
2788 fi =
set_fn(fn,
sizeof(fn), 0, configfile, fileset);
2791 (f = fopen(fn,
"w+"))
2793 (f = fopen(fn,
"w"))
2809 fi =
set_fn(fn,
sizeof(fn), cat->
file, configfile, fileset);
2825 fprintf(f,
"#exec \"%s\"\n", incl->
exec_file);
2836 char *cmtp = cmt->
cmt;
2837 while (cmtp && *cmtp ==
';' && *(cmtp+1) ==
'!') {
2838 char *cmtp2 = strchr(cmtp+1,
'\n');
2844 fprintf(f,
"%s", cmtp);
2846 fprintf(f,
"[%s]", cat->
name);
2858 fprintf(f,
"%s",x->
name);
2867 fprintf(f,
"%s", cmt->
cmt);
2872 if (cmt->
cmt[0] !=
';' || cmt->
cmt[1] !=
'!')
2873 fprintf(f,
"%s", cmt->
cmt);
2890 if (!strcasecmp(
var->name, v->
name) && !strcmp(
var->value, v->
value)) {
2895 if (
var->inherited) {
2899 if (!strcasecmp(
var->name, v->
name) && !strcmp(
var->value, v->
value)) {
2914 fi =
set_fn(fn,
sizeof(fn),
var->file, configfile, fileset);
2917 ast_debug(1,
"Unable to open for writing: %s\n", fn);
2918 ast_verb(2,
"Unable to write %s (%s)\n", fn, strerror(
errno));
2931 fprintf(f,
"#exec \"%s\"\n", incl->
exec_file);
2940 for (cmt =
var->precomments; cmt; cmt=cmt->
next) {
2941 if (cmt->
cmt[0] !=
';' || cmt->
cmt[1] !=
'!')
2942 fprintf(f,
"%s", cmt->
cmt);
2946 int escaped_len = 2 * strlen(
var->value) + 1;
2947 char escaped[escaped_len];
2951 if (
var->sameline) {
2952 fprintf(f,
"%s %s %s %s",
var->name, (
var->object ?
"=>" :
"="),
2953 escaped,
var->sameline->cmt);
2955 fprintf(f,
"%s %s %s\n",
var->name, (
var->object ?
"=>" :
"="),
2960 for (cmt =
var->trailing; cmt; cmt=cmt->
next) {
2961 if (cmt->
cmt[0] !=
';' || cmt->
cmt[1] !=
'!')
2962 fprintf(f,
"%s", cmt->
cmt);
2964 if (
var->blanklines) {
2965 blanklines =
var->blanklines;
2966 while (blanklines--)
2979 ast_verb(2,
"Saving '%s': saved\n", fn);
2981 ast_debug(1,
"Unable to open for writing: %s\n", fn);
2982 ast_verb(2,
"Unable to write '%s' (%s)\n", fn, strerror(
errno));
2998 ast_debug(1,
"Unable to open for writing: %s\n", fn);
2999 ast_verb(2,
"Unable to write %s (%s)\n", fn, strerror(
errno));
3009 fprintf(f,
"#exec \"%s\"\n", incl->
exec_file);
3038#ifdef TEST_FRAMEWORK
3048 length =
sizeof(*map);
3049 length += strlen(
name) + 1;
3050 length += strlen(driver) + 1;
3051 length += strlen(database) + 1;
3053 length += strlen(
table) + 1;
3060 dst += strlen(dst) + 1;
3061 map->
driver = strcpy(dst, driver);
3062 dst += strlen(dst) + 1;
3063 map->
database = strcpy(dst, database);
3065 dst += strlen(dst) + 1;
3081 char *driver, *
table, *database, *textpri, *stringp, *
tmp;
3105 driver =
strsep(&stringp,
",");
3110 if ((
tmp = strchr(stringp,
'\"')))
3114 if (*stringp ==
'"') {
3116 database =
strsep(&stringp,
"\"");
3120 database =
strsep(&stringp,
",");
3124 textpri =
strsep(&stringp,
",");
3125 if (!textpri || !(pri = atoi(textpri))) {
3134 if (!strcmp(v->
name,
"asterisk.conf")) {
3139 if (!strcmp(v->
name,
"logger.conf")) {
3144 if (!driver || !database)
3146 if (!strcasecmp(v->
name,
"iaxfriends")) {
3147 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");
3200 if (!strcasecmp(family, map->
name)) {
3204 ast_debug(5,
"Failed to find a realtime mapping for %s\n", family);
3230 if (!strcasecmp(eng->name, map->
driver))
3256 for (cat_iter = old->
root; cat_iter; cat_iter = cat_iter->
next) {
3263 if (cat_iter->
root) {
3265 if (!new_cat->
root) {
3338#define realtime_arguments_to_fields(ap, result) realtime_arguments_to_fields2(ap, 0, result)
3356 const char *newparam;
3392 newparam = va_arg(ap,
const char *);
3393 newval = va_arg(ap,
const char *);
3394 while ((newparam = va_arg(ap,
const char *))) {
3395 newval = va_arg(ap,
const char *);
3400 newparam = va_arg(ap,
const char *);
3405 newval = va_arg(ap,
const char *);
3412 while ((newparam = va_arg(ap,
const char *))) {
3415 newval = va_arg(ap,
const char *);
3423 field->
next = fields;
3442 for (i = 1; ; i++) {
3461 va_start(ap, family);
3494 if (cur->
value[0] ==
' ' && cur->
value[1] ==
'\0') {
3495 char *vptr = (
char *) cur->
value;
3513 va_start(ap, family);
3558 va_start(ap, family);
3559 for (i = 1; ; i++) {
3584 for (i = 1; ; i++) {
3605 for (i = 1; ; i++) {
3628 va_start(ap, family);
3646 for (i = 1; ; i++) {
3665 va_start(ap, lookup);
3683 for (i = 1; ; i++) {
3702 va_start(ap, family);
3709 va_start(ap, family);
3713 if (!lookup_fields || !update_fields) {
3727 for (i = 1; ; i++) {
3746 va_start(ap, family);
3764 for (i = 1; ; i++) {
3783 va_start(ap, lookup);
3799 for (; *chunk; chunk++) {
3800 if (*chunk ==
'^' && strchr(
"0123456789ABCDEFabcdef", chunk[1]) && strchr(
"0123456789ABCDEFabcdef", chunk[2])) {
3801 sscanf(chunk + 1,
"%02hhX", (
unsigned char *)chunk);
3802 memmove(chunk + 1, chunk + 3, strlen(chunk + 3) + 1);
3810 if (!strchr(chunk,
';') && !strchr(chunk,
'^')) {
3814 for (; *chunk; chunk++) {
3815 if (strchr(
";^", *chunk)) {
3829 void *p_result, ...)
3834 va_start(ap, p_result);
3841 char *endptr =
NULL;
3856 x = strtol(arg, &endptr, 0);
3862 error = (x < low) || (x > high);
3866 }
else if (x > high) {
3878 ast_debug(3,
"extract int from [%s] in [%d, %d] gives [%ld](%d)\n",
3885 unsigned long int x = 0;
3886 uint32_t *
result = p_result;
3888 char *endptr =
NULL;
3892 def = va_arg(ap, uint32_t);
3896 low = va_arg(ap, uint32_t);
3897 high = va_arg(ap, uint32_t);
3911 x = strtoul(arg, &endptr, 0);
3916 error = (x < low) || (x > high);
3920 }
else if (x > high) {
3931 ast_debug(3,
"extract uint from [%s] in [%u, %u] gives [%lu](%d)\n",
3948 def = va_arg(ap,
int);
3951 low = va_arg(ap,
int);
3952 high = va_arg(ap,
int);
3959 if (
error || x < INT_MIN || x > INT_MAX) {
3964 error = (x < low) || (x > high);
3968 }
else if (x > high) {
3980 ast_debug(3,
"extract timelen from [%s] in [%d, %d] gives [%d](%d)\n",
3987 double *
result = p_result;
3988 double x = 0, def =
result ? *
result : 0, low = -HUGE_VAL, high = HUGE_VAL;
3989 char *endptr =
NULL;
3993 def = va_arg(ap,
double);
3997 low = va_arg(ap,
double);
3998 high = va_arg(ap,
double);
4005 x = strtod(arg, &endptr);
4006 if (*endptr ||
errno == ERANGE) {
4010 error = (x < low) || (x > high);
4018 ast_debug(3,
"extract double from [%s] in [%f, %f] gives [%f](%d)\n",
4030 ast_debug(3,
"extract addr from %s gives %s(%d)\n",
4038 struct sockaddr_in _sa_buf;
4039 struct sockaddr_in *sa = p_result ?
4040 (
struct sockaddr_in *)p_result : &_sa_buf;
4043 va_arg(ap,
struct sockaddr_in *) : sa;
4046 memset(&_sa_buf,
'\0',
sizeof(_sa_buf));
4050 sa->sin_family = AF_INET;
4059 sa->sin_port = def->sin_port;
4061 sa->sin_port = def->sin_port;
4063 sa->sin_port = htons(strtol(port,
NULL, 0));
4065 sa->sin_port = def->sin_port;
4072 sa->sin_addr = def->sin_addr;
4074 struct sockaddr_in
tmp;
4076 sa->sin_addr =
tmp.sin_addr;
4079 "extract inaddr from [%s] gives [%s:%d](%d)\n",
4081 ntohs(sa->sin_port),
error);
4096 e->
command =
"core show config mappings";
4098 "Usage: core show config mappings\n"
4099 " Shows the filenames to config engines.\n";
4109 ast_cli(
a->fd,
"No config mappings found.\n");
4136 "Usage: config reload <filename.conf>\n"
4137 " Reloads all modules that reference <filename.conf>\n";
4144 wordlen = strlen(
a->word);
4158 if (!strncmp(cfmtime->
filename,
a->word, wordlen)) {
4178 if (!strcmp(cfmtime->
filename,
a->argv[2])) {
4197 "Usage: config list\n"
4198 " Show all modules that have loaded a configuration file\n";
4293 if (!strcasecmp(hook->
filename, filename) &&
4294 !strcasecmp(hook->
module, module)) {
4304 const char *filename,
4340 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.