37 #include "asterisk/paths.h"
44 #define AST_INCLUDE_GLOB 1
56 #define MAX_NESTED_COMMENTS 128
57 #define COMMENT_START ";--"
58 #define COMMENT_END "--;"
59 #define COMMENT_META ';'
60 #define COMMENT_TAG '-'
67 #define MIN_VARIABLE_FNAME_SPACE 40
89 unsigned int has_exec:1;
91 unsigned long stat_size;
93 unsigned long stat_mtime_nsec;
98 const
char *who_asked;
110 return *str ? 0 : -1;
167 for (total = 0; *
str; str++) {
168 unsigned int tmp =
total;
174 total += ((
unsigned int) (*str));
184 const struct inclfile *ae = a, *be = b;
206 #define MAX_INCLUDE_LEVEL 10
233 struct ast_category *next;
276 struct ast_variable *_ast_variable_new(
const char *name,
const char *
value,
const char *filename,
const char *file,
const char *func,
int lineno)
282 int name_len = strlen(name) + 1;
283 int val_len = strlen(value) + 1;
284 int fn_len = strlen(filename) + 1;
293 (variable =
__ast_calloc(1, fn_len + name_len + val_len +
sizeof(*variable), file, lineno, func))
295 (variable =
ast_calloc(1, fn_len + name_len + val_len +
sizeof(*variable)))
298 char *dst = variable->
stuff;
301 variable->
file = strcpy(dst, filename);
303 variable->
name = strcpy(dst, name);
305 variable->
value = strcpy(dst, value);
344 inc->inclusion_count++;
345 snprintf(real_included_file_name, real_included_file_name_size,
"%s~~%d", included_file, inc->inclusion_count);
346 }
while (stat(real_included_file_name, &statbuf) == 0);
347 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);
349 *real_included_file_name = 0;
355 inc->include_location_file =
ast_strdup(from_file);
356 inc->include_location_lineno = from_lineno;
358 inc->included_file =
ast_strdup(real_included_file_name);
360 inc->included_file =
ast_strdup(included_file);
366 if (!inc->include_location_file
367 || !inc->included_file
368 || (is_exec && !inc->exec_file)) {
383 struct ast_category *cat;
386 int from_len = strlen(from_file);
387 int to_len = strlen(to_file);
389 if (strcmp(from_file, to_file) == 0)
403 if (from_len >= to_len)
415 for (cat = conf->
root; cat; cat = cat->
next) {
420 if (strcmp(cat->
file,from_file) == 0) {
421 if (from_len >= to_len)
422 strcpy(cat->
file, to_file);
433 if (strcmp(v->
file, from_file)) {
442 if (to_len < v->name - v->
file) {
444 str = (
char *) v->
file;
445 strcpy(str, to_file);
460 if (cat->
last == v) {
490 category->
root = variable;
491 category->
last = variable;
502 if (!variable || sscanf(line,
"%30d", &insertline) != 1) {
507 category->
root = variable;
509 for (lineno = 1; lineno < insertline; lineno++) {
516 cur->
next = variable;
524 for (p = *comment; p; p = n) {
551 while ((var = var->
next)) {
568 if (!var1 || !var1->
next) {
599 struct ast_category *cat = NULL;
611 return (cat) ? cat->
root : NULL;
631 if (!strcasecmp(variable, v->
name)) {
636 struct ast_category *cat;
638 for (cat = config->
root; cat; cat = cat->
next) {
639 for (v = cat->
root; v; v = v->
next) {
640 if (!strcasecmp(variable, v->
name)) {
655 new->lineno = old->
lineno;
656 new->object = old->
object;
675 struct ast_category *category;
682 if (!category->
file) {
693 struct ast_category *cat;
696 for (cat = config->
root; cat; cat = cat->
next) {
697 if (cat->
name == category_name && (ignored || !cat->
ignored))
701 for (cat = config->
root; cat; cat = cat->
next) {
702 if (!strcasecmp(cat->
name, category_name) && (ignored || !cat->
ignored))
724 config->
root = category;
726 config->
last = category;
732 struct ast_category *cur_category;
734 if (!config || !cat || !match) {
737 if (!strcasecmp(config->
root->
name, match)) {
742 for (cur_category = config->
root; cur_category && cur_category->
next;
743 cur_category = cur_category->
next) {
744 if (!strcasecmp(cur_category->
next->
name, match)) {
746 cur_category->
next = cat;
779 for (incl=incls; incl; incl = inclnext) {
780 inclnext = incl->
next;
798 return (cat) ? cat->
root : NULL;
806 return category->
root;
812 struct ast_category *cat;
827 for (cat = config->
root; cat; cat = cat->
next) {
828 if (cat->
name == prev) {
839 for (cat = config->
root; cat; cat = cat->
next) {
840 if (!strcasecmp(cat->
name, prev)) {
853 return (cat) ? cat->
name : NULL;
884 for (var = base->
root; var; var = var->
next)
892 if ((config =
ast_calloc(1,
sizeof(*config))))
907 if (sscanf(line,
"%30d", &req_item) != 1
915 cur = category->
root;
919 if ((0 <= req_item && num_item == req_item)
920 || (req_item < 0 && !strcasecmp(cur->
name, variable)
924 if (cur == category->
last)
925 category->
last = prev;
928 if (cur == category->
last)
929 category->
last = NULL;
943 const char *value,
const char *
match,
unsigned int object)
947 for (cur = category->
root; cur; prev = cur, cur = cur->
next) {
948 if (strcasecmp(cur->
name, variable) ||
956 newer->object = newer->object ||
object;
959 newer->next = cur->
next;
963 category->
root = newer;
964 if (category->
last == cur)
965 category->
last = newer;
978 struct ast_category *prev=NULL, *cat;
982 if (cat->name == category) {
985 if (cat == cfg->
last)
989 if (cat == cfg->
last)
1002 if (!strcasecmp(cat->name, category)) {
1005 if (cat == cfg->
last)
1009 if (cat == cfg->
last)
1023 struct ast_category *cat;
1025 for (cat = cfg->
root; cat; cat = cat->
next) {
1026 if (strcasecmp(cat->
name, category))
1039 struct ast_category *cat, *catn;
1063 cfg->
current = (
struct ast_category *) cat;
1078 struct cache_file_mtime *cfmtime;
1082 sizeof(*cfmtime) + strlen(filename) + 1 + strlen(who_asked) + 1);
1087 strcpy(dst, filename);
1088 dst += strlen(dst) + 1;
1089 cfmtime->
who_asked = strcpy(dst, who_asked);
1108 static void cfmstat_save(
struct cache_file_mtime *cfmtime,
struct stat *statbuf)
1111 #if defined(HAVE_STRUCT_STAT_ST_MTIM)
1113 #elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC)
1115 #elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC)
1132 static int cfmstat_cmp(
struct cache_file_mtime *cfmtime,
struct stat *statbuf)
1134 struct cache_file_mtime cfm_buf;
1189 struct cache_file_mtime *cfmtime;
1193 if (!strcmp(cfmtime->
filename, filename)
1194 && !strcmp(cfmtime->
who_asked, who_asked)) {
1206 struct cache_file_mtime *cfmtime;
1212 if (!strcmp(cfmtime->
filename, configfile) && !strcmp(cfmtime->
who_asked, who_asked))
1228 if (!strcmp(cfinclude->
include, filename)) {
1233 cfinclude =
ast_calloc(1,
sizeof(*cfinclude) + strlen(filename) + 1);
1238 strcpy(cfinclude->
include, filename);
1256 char *buf,
int lineno,
const char *configfile,
struct ast_flags flags,
1257 struct ast_str *comment_buffer,
1259 const char *suggested_include_file,
1260 struct ast_category **last_cat,
struct ast_variable **last_var,
const char *who_asked)
1265 char cmd[512], exec_file[512];
1268 if (cur[0] ==
'[') {
1277 struct ast_category *newcat = NULL;
1280 c = strchr(cur,
']');
1282 ast_log(
LOG_WARNING,
"parse error: no closing ']', line %d of %s\n", lineno, configfile);
1305 CB_RESET(comment_buffer, lline_buffer);
1309 if (!(cur = strchr(c,
')'))) {
1310 ast_log(
LOG_WARNING,
"parse error: no closing ')', line %d of %s\n", lineno, configfile);
1314 while ((cur =
strsep(&c,
","))) {
1315 if (!strcasecmp(cur,
"!")) {
1316 (*cat)->ignored = 1;
1317 }
else if (!strcasecmp(cur,
"+")) {
1322 ast_log(
LOG_WARNING,
"Category addition requested, but category '%s' does not exist, line %d of %s\n", catname, lineno, configfile);
1331 struct ast_category *base;
1335 ast_log(
LOG_WARNING,
"Inheritance requested, but category '%s' does not exist, line %d of %s\n", cur, lineno, configfile);
1344 }
else if (cur[0] ==
'#') {
1346 char real_inclusion_name[256];
1351 while (*c && (*c > 32)) {
1365 if (!strcasecmp(cur,
"include")) {
1367 }
else if (!strcasecmp(cur,
"exec")) {
1369 ast_log(
LOG_WARNING,
"Cannot perform #exec unless execincludes option is enabled in asterisk.conf (options section)!\n");
1373 ast_log(
LOG_WARNING,
"Unknown directive '#%s' at line %d of %s\n", cur, lineno, configfile);
1379 do_include ?
"include" :
"exec",
1380 do_include ?
"filename" :
"/path/to/executable",
1389 if ((*c ==
'"') || (*c ==
'<')) {
1390 char quote_char = *c;
1391 if (quote_char ==
'<') {
1395 if (*(c + strlen(c) - 1) == quote_char) {
1397 *(c + strlen(c) - 1) =
'\0';
1408 snprintf(exec_file,
sizeof(exec_file),
"/var/tmp/exec.%d%d.%ld", (
int)now.tv_sec, (
int)now.tv_usec, (
long)pthread_self());
1409 snprintf(cmd,
sizeof(cmd),
"%s > %s 2>&1", cur, exec_file);
1415 exec_file[0] =
'\0';
1419 ast_include_new(cfg, cfg->
include_level == 1 ?
"" : configfile, cur, !do_include, cur2, lineno, real_inclusion_name,
sizeof(real_inclusion_name));
1425 ast_log(
LOG_ERROR,
"The file '%s' was listed as a #include but it does not exist.\n", cur);
1435 "parse error: No category context for line %d of %s\n", lineno, configfile);
1438 c = strchr(cur,
'=');
1440 if (c && c > cur && (*(c - 1) ==
'+')) {
1444 if (!str || !*str) {
1454 if (!strcmp(var->
name, cur)) {
1461 goto set_new_variable;
1491 CB_RESET(comment_buffer, lline_buffer);
1506 #if defined(LOW_MEMORY)
1511 char *new_buf, *comment_p, *process_buf;
1515 struct ast_category *cat = NULL;
1517 struct stat statbuf;
1518 struct cache_file_mtime *cfmtime = NULL;
1521 struct ast_category *last_cat = 0;
1523 struct ast_str *comment_buffer = NULL;
1524 struct ast_str *lline_buffer = NULL;
1529 if (filename[0] ==
'/') {
1539 if (!lline_buffer) {
1545 #ifdef AST_INCLUDE_GLOB
1550 globbuf.gl_offs = 0;
1552 if (glob_ret == GLOB_NOSPACE) {
1554 "Glob Expansion of pattern '%s' failed: Not enough memory\n", fn);
1557 "Glob Expansion of pattern '%s' failed: Read error\n", fn);
1562 if (!cfg && (globbuf.gl_pathc != 1 || strcmp(fn, globbuf.gl_pathv[0]))) {
1575 for (i=0; i<globbuf.gl_pathc; i++) {
1584 if (stat(fn, &statbuf)) {
1591 if (!S_ISREG(statbuf.st_mode)) {
1626 NULL, flags,
"", who_asked)) {
1635 #ifdef AST_INCLUDE_GLOB
1663 if (!(f = fopen(fn,
"r"))) {
1664 ast_debug(1,
"No file to parse: %s\n", fn);
1675 if (fgets(buf,
sizeof(buf), f)) {
1677 if (strlen(buf) ==
sizeof(buf) - 1 && buf[
sizeof(buf) - 1] !=
'\n') {
1678 ast_log(
LOG_WARNING,
"Line %d too long, skipping. It begins with: %.32s...\n", lineno, buf);
1679 while (fgets(buf,
sizeof(buf), f)) {
1680 if (strlen(buf) !=
sizeof(buf) - 1 || buf[
sizeof(buf) - 1] ==
'\n') {
1700 CB_ADD(&comment_buffer,
"\n");
1705 if ((comment_p > new_buf) && (*(comment_p - 1) ==
'\\')) {
1707 new_buf = comment_p;
1709 memmove(comment_p - 1, comment_p, strlen(comment_p) + 1);
1714 new_buf = comment_p + 3;
1716 nest[comment-1] = lineno;
1720 }
else if ((comment_p >= new_buf + 2) &&
1725 new_buf = comment_p + 1;
1731 oldptr = process_buf + strlen(process_buf);
1733 CB_ADD(&comment_buffer,
";");
1734 CB_ADD_LEN(&comment_buffer, oldptr+1, new_buf-oldptr-1);
1737 memmove(oldptr, new_buf, strlen(new_buf) + 1);
1740 process_buf = new_buf;
1747 CB_ADD(&lline_buffer, comment_p);
1750 new_buf = comment_p;
1752 new_buf = comment_p + 1;
1756 CB_ADD(&comment_buffer, buf);
1762 if (
process_text_line(cfg, &cat, buffer, lineno, fn, flags, comment_buffer, lline_buffer, suggested_include_file, &last_cat, &last_var, who_asked)) {
1779 }
else if (last_var) {
1793 CB_RESET(comment_buffer, lline_buffer);
1798 ast_log(
LOG_WARNING,
"Unterminated comment detected beginning on line %d\n", nest[comment - 1]);
1800 #ifdef AST_INCLUDE_GLOB
1848 fprintf(f1,
";!\n");
1849 fprintf(f1,
";! Automatically generated configuration file\n");
1850 if (strcmp(configfile, fn))
1851 fprintf(f1,
";! Filename: %s (%s)\n", configfile, fn);
1853 fprintf(f1,
";! Filename: %s\n", configfile);
1854 fprintf(f1,
";! Generator: %s\n", generator);
1855 fprintf(f1,
";! Creation Date: %s", date);
1856 fprintf(f1,
";!\n");
1866 static void make_fn(
char *fn,
size_t fn_size,
const char *file,
const char *configfile)
1869 if (configfile[0] ==
'/') {
1874 }
else if (file[0] ==
'/') {
1886 make_fn(fn, fn_size, file, configfile);
1938 int precomment_lines;
1952 if (lineno - precomment_lines - fi->
lineno < 0) {
1954 }
else if (lineno == 0) {
1957 }
else if (lineno - precomment_lines - fi->
lineno < 5) {
1960 for (i = fi->
lineno; i < lineno - precomment_lines; i++) {
1982 struct ast_category *cat;
2002 if (access(fn, R_OK | W_OK)) {
2010 make_fn(fn,
sizeof(fn), 0, configfile);
2011 if (access(fn, R_OK | W_OK)) {
2038 fi =
set_fn(fn,
sizeof(fn), 0, configfile, fileset);
2041 (f = fopen(fn,
"w+"))
2043 (f = fopen(fn,
"w"))
2059 fi =
set_fn(fn,
sizeof(fn), cat->
file, configfile, fileset);
2075 fprintf(f,
"#exec \"%s\"\n", incl->
exec_file);
2086 char *cmtp = cmt->
cmt;
2087 while (cmtp && *cmtp ==
';' && *(cmtp+1) ==
'!') {
2088 char *cmtp2 = strchr(cmtp+1,
'\n');
2094 fprintf(f,
"%s", cmtp);
2096 fprintf(f,
"[%s]", cat->
name);
2108 fprintf(f,
"%s",x->
name);
2117 fprintf(f,
"%s", cmt->
cmt);
2122 if (cmt->
cmt[0] !=
';' || cmt->
cmt[1] !=
'!')
2123 fprintf(f,
"%s", cmt->
cmt);
2149 fi =
set_fn(fn,
sizeof(fn), var->
file, configfile, fileset);
2152 ast_debug(1,
"Unable to open for writing: %s\n", fn);
2153 ast_verb(2,
"Unable to write %s (%s)", fn, strerror(
errno));
2166 fprintf(f,
"#exec \"%s\"\n", incl->
exec_file);
2176 if (cmt->
cmt[0] !=
';' || cmt->
cmt[1] !=
'!')
2177 fprintf(f,
"%s", cmt->
cmt);
2182 fprintf(f,
"%s %s %s\n", var->
name, (var->
object ?
"=>" :
"="), var->
value);
2184 if (cmt->
cmt[0] !=
';' || cmt->
cmt[1] !=
'!')
2185 fprintf(f,
"%s", cmt->
cmt);
2189 while (blanklines--)
2205 ast_debug(1,
"Unable to open for writing: %s\n", fn);
2222 ast_debug(1,
"Unable to open for writing: %s\n", fn);
2223 ast_verb(2,
"Unable to write %s (%s)", fn, strerror(
errno));
2233 fprintf(f,
"#exec \"%s\"\n", incl->
exec_file);
2269 length =
sizeof(*map);
2270 length += strlen(name) + 1;
2271 length += strlen(driver) + 1;
2272 length += strlen(database) + 1;
2274 length += strlen(table) + 1;
2280 map->
name = strcpy(dst, name);
2281 dst += strlen(dst) + 1;
2282 map->
driver = strcpy(dst, driver);
2283 dst += strlen(dst) + 1;
2284 map->
database = strcpy(dst, database);
2286 dst += strlen(dst) + 1;
2287 map->
table = strcpy(dst, table);
2302 char *driver, *
table, *database, *textpri, *stringp, *tmp;
2316 }
else if (!config) {
2325 driver =
strsep(&stringp,
",");
2327 if ((tmp = strchr(stringp,
'\"')))
2331 if (*stringp ==
'"') {
2333 database =
strsep(&stringp,
"\"");
2337 database =
strsep(&stringp,
",");
2340 table =
strsep(&stringp,
",");
2341 textpri =
strsep(&stringp,
",");
2342 if (!textpri || !(pri = atoi(textpri))) {
2346 if (!strcmp(v->
name, extconfig_conf)) {
2351 if (!strcmp(v->
name,
"asterisk.conf")) {
2356 if (!strcmp(v->
name,
"logger.conf")) {
2361 if (!driver || !database)
2363 if (!strcasecmp(v->
name,
"sipfriends")) {
2364 ast_log(
LOG_WARNING,
"The 'sipfriends' table is obsolete, update your config to use sippeers instead.\n");
2365 append_mapping(
"sippeers", driver, database, table ? table :
"sipfriends", pri);
2366 }
else if (!strcasecmp(v->
name,
"iaxfriends")) {
2367 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");
2368 append_mapping(
"iaxusers", driver, database, table ? table :
"iaxfriends", pri);
2369 append_mapping(
"iaxpeers", driver, database, table ? table :
"iaxfriends", pri);
2384 if (!config_engine_list) {
2385 config_engine_list =
new;
2387 for (ptr = config_engine_list; ptr->
next; ptr=ptr->
next);
2403 for (ptr = config_engine_list; ptr; ptr=ptr->
next) {
2408 config_engine_list = ptr->
next;
2428 if (!strcasecmp(family, map->
name) && (priority == map->
priority)) {
2439 for (eng = config_engine_list; !ret && eng; eng = eng->
next) {
2440 if (!strcasecmp(eng->name, map->
driver))
2477 eng =
find_engine(filename, 1, db,
sizeof(db), table,
sizeof(table));
2483 eng =
find_engine(
"global", 1, db,
sizeof(db), table,
sizeof(table));
2489 result = loader->
load_func(db, table, filename, cfg, flags, suggested_include_file, who_asked);
2523 for (i = 1; ; i++) {
2524 if ((eng =
find_engine(family, i, db,
sizeof(db), table,
sizeof(table)))) {
2541 va_start(ap, family);
2555 va_start(ap, family);
2573 if (cur->
value[0] ==
' ' && cur->
value[1] ==
'\0') {
2574 char *vptr = (
char *) cur->
value;
2614 va_start(ap, family);
2615 for (i = 1; ; i++) {
2616 if ((eng =
find_engine(family, i, db,
sizeof(db), table,
sizeof(table)))) {
2637 for (i = 1; ; i++) {
2638 if ((eng =
find_engine(family, i, db,
sizeof(db), table,
sizeof(table)))) {
2659 va_start(ap, family);
2660 for (i = 1; ; i++) {
2661 if ((eng =
find_engine(family, i, db,
sizeof(db), table,
sizeof(table)))) {
2687 va_start(ap, lookup);
2688 for (i = 1; ; i++) {
2689 if ((eng =
find_engine(family, i, db,
sizeof(db), table,
sizeof(table)))) {
2711 va_start(ap, family);
2712 for (i = 1; ; i++) {
2713 if ((eng =
find_engine(family, i, db,
sizeof(db), table,
sizeof(table)))) {
2734 va_start(ap, family);
2735 for (i = 1; ; i++) {
2736 if ((eng =
find_engine(family, i, db,
sizeof(db), table,
sizeof(table)))) {
2758 va_start(ap, lookup);
2759 for (i = 1; ; i++) {
2760 if ((eng =
find_engine(family, i, db,
sizeof(db), table,
sizeof(table)))) {
2776 for (; *chunk; chunk++) {
2777 if (*chunk ==
'^' && strchr(
"0123456789ABCDEFabcdef", chunk[1]) && strchr(
"0123456789ABCDEFabcdef", chunk[2])) {
2778 sscanf(chunk + 1,
"%02hhX", (
unsigned char *)chunk);
2779 memmove(chunk + 1, chunk + 3, strlen(chunk + 3) + 1);
2787 if (!strchr(chunk,
';') && !strchr(chunk,
'^')) {
2791 for (; *chunk; chunk++) {
2792 if (strchr(
";^", *chunk)) {
2806 void *p_result, ...)
2811 va_start(ap, p_result);
2816 int32_t *result = p_result;
2818 char *endptr = NULL;
2822 def = va_arg(ap, int32_t);
2825 low = va_arg(ap, int32_t);
2826 high = va_arg(ap, int32_t);
2833 x = strtol(arg, &endptr, 0);
2839 error = (x < low) || (x > high);
2845 *result = error ? def : x;
2848 ast_debug(3,
"extract int from [%s] in [%d, %d] gives [%ld](%d)\n",
2849 arg, low, high, result ? *result : x, error);
2855 unsigned long int x = 0;
2856 uint32_t *result = p_result;
2857 uint32_t def = result ? *result : 0, low = 0, high =
UINT32_MAX;
2858 char *endptr = NULL;
2862 def = va_arg(ap, uint32_t);
2866 low = va_arg(ap, uint32_t);
2867 high = va_arg(ap, uint32_t);
2881 x = strtoul(arg, &endptr, 0);
2886 error = (x < low) || (x > high);
2892 *result = error ? def : x;
2894 ast_debug(3,
"extract uint from [%s] in [%u, %u] gives [%lu](%d)\n",
2895 arg, low, high, result ? *result : x, error);
2901 double *result = p_result;
2902 double x = 0, def = result ? *result : 0, low = -HUGE_VAL, high = HUGE_VAL;
2903 char *endptr = NULL;
2907 def = va_arg(ap,
double);
2911 low = va_arg(ap,
double);
2912 high = va_arg(ap,
double);
2919 x = strtod(arg, &endptr);
2920 if (*endptr ||
errno == ERANGE) {
2924 error = (x < low) || (x > high);
2930 *result = error ? def : x;
2932 ast_debug(3,
"extract double from [%s] in [%f, %f] gives [%f](%d)\n",
2933 arg, low, high, result ? *result : x, error);
2944 ast_debug(3,
"extract addr from %s gives %s(%d)\n",
2952 struct sockaddr_in _sa_buf;
2953 struct sockaddr_in *sa = p_result ?
2954 (
struct sockaddr_in *)p_result : &_sa_buf;
2957 va_arg(ap,
struct sockaddr_in *) : sa;
2961 memset(&_sa_buf,
'\0',
sizeof(_sa_buf));
2964 buf =
strsep(&port,
":");
2965 sa->sin_family = AF_INET;
2974 sa->sin_port = def->sin_port;
2976 sa->sin_port = def->sin_port;
2978 sa->sin_port = htons(strtol(port, NULL, 0));
2980 sa->sin_port = def->sin_port;
2987 memcpy(&sa->sin_addr, hp->h_addr,
sizeof(sa->sin_addr));
2990 sa->sin_addr = def->sin_addr;
2993 "extract inaddr from [%s] gives [%s:%d](%d)\n",
2995 ntohs(sa->sin_port), error);
3010 e->
command =
"core show config mappings";
3012 "Usage: core show config mappings\n"
3013 " Shows the filenames to config engines.\n";
3021 if (!config_engine_list) {
3022 ast_cli(a->
fd,
"No config mappings found.\n");
3024 for (eng = config_engine_list; eng; eng = eng->
next) {
3042 struct cache_file_mtime *cfmtime;
3043 char *prev =
"", *completion_value = NULL;
3044 int wordlen, which = 0;
3050 "Usage: config reload <filename.conf>\n"
3051 " Reloads all modules that reference <filename.conf>\n";
3058 wordlen = strlen(a->
word);
3063 if (strcmp(cfmtime->
filename, prev) == 0) {
3072 if (++which > a->
n && strncmp(cfmtime->
filename, a->
word, wordlen) == 0) {
3082 return completion_value;
3093 sprintf(buf,
"module reload %s", cfmtime->
who_asked);
3104 struct cache_file_mtime *cfmtime;
3110 "Usage: config list\n"
3111 " Show all modules that have loaded a configuration file\n";
3134 struct cache_file_mtime *cfmtime;
static void config_shutdown(void)
int ast_variable_delete(struct ast_category *category, const char *variable, const char *match, const char *line)
struct ast_config_engine * next
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.
static struct ast_cli_entry cli_config[]
struct ast_comment * precomments
#define AST_CLI_DEFINE(fn, txt,...)
char * exec_file
if it's an exec, you'll have both the /var/tmp to read, and the original script
int ast_store_realtime(const char *family,...) attribute_sentinel
Create realtime configuration.
#define AST_LIST_LOCK(head)
Locks a list.
int ast_category_delete(struct ast_config *cfg, const char *category)
int ast_safe_system(const char *s)
Safely spawn an external program while closing file descriptors.
Asterisk locking-related definitions:
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)
Asterisk main include file. File version handling, generic pbx functions.
realtime_destroy * destroy_func
#define ao2_link(arg1, arg2)
static void ast_comment_destroy(struct ast_comment **comment)
const char * ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable)
Gets a variable.
static const char config[]
static char * handle_cli_config_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static void config_cache_attribute(const char *configfile, enum config_cache_attribute_enum attrtype, const char *filename, const char *who_asked)
int ast_realtime_enabled(void)
Check if there's any realtime engines loaded.
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.
char * strsep(char **str, const char *delims)
static ast_mutex_t config_lock
static int count_linefeeds_in_comments(struct ast_comment *x)
static struct cache_file_mtime * cfmtime_new(const char *filename, const char *who_asked)
realtime_update * update_func
struct ast_config_include * ast_include_find(struct ast_config *conf, const char *included_file)
String manipulation functions.
struct ast_variable * ast_category_detach_variables(struct ast_category *cat)
struct ast_variable * ast_category_first(struct ast_category *cat)
given a pointer to a category, return the root variable.
struct ast_category * current
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
#define ast_test_flag(p, flag)
static void CB_ADD_LEN(struct ast_str **cb, const char *str, int len)
int ast_unload_realtime(const char *family)
Release any resources cached for a realtime family.
Time-related functions and macros.
static void ast_variable_move(struct ast_variable *dst_var, struct ast_variable *src_var)
static struct ast_category * category_get(const struct ast_config *config, const char *category_name, int ignored)
descriptor for a cli entry.
int ast_update2_realtime(const char *family,...) attribute_sentinel
Update realtime configuration.
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category)
Goes through variables.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
realtime_store * store_func
static int hash_string(const void *obj, const int flags)
int ast_category_insert(struct ast_config *config, struct ast_category *cat, const char *match)
Inserts new category.
struct ast_category * ast_config_get_current_category(const struct ast_config *cfg)
Retrieve the current category name being built.
struct ast_variable * ast_load_realtime_all(const char *family,...) attribute_sentinel
Structure for variables, used for configurations and for channel variables.
void ast_include_rename(struct ast_config *conf, const char *from_file, const char *to_file)
Configuration File Parser.
static void config_cache_flush_includes(struct cache_file_mtime *cfmtime)
static void gen_header(FILE *f1, const char *configfile, const char *fn, const char *generator)
static char * extconfig_conf
int ast_config_text_file_save(const char *filename, const struct ast_config *cfg, const char *generator)
struct ast_variable * ast_load_realtime(const char *family,...) attribute_sentinel
Retrieve realtime configuration.
static struct ast_variable * variable_clone(const struct ast_variable *old)
struct ast_variable * last
void * __ast_calloc(size_t nmemb, size_t size, const char *file, int lineno, const char *func)
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
static int hashtab_compare_strings(void *a, void *b, int flags)
struct ast_category * next
static void clear_config_maps(void)
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
struct ast_str * ast_str_create(size_t init_len)
Create a malloc'ed dynamic length string.
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
#define ast_mutex_lock(a)
ast_parse_flags
Support code to parse config file arguments.
const char * ast_config_option(struct ast_config *cfg, const char *cat, const char *var)
Retrieve a configuration variable within the configuration set.
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
realtime_unload * unload_func
char stuff[0]
Contents of file, name, and value in that order stuffed here.
void ast_cli(int fd, const char *fmt,...)
struct ast_category * last_browse
static struct ast_variable * ast_load_realtime_helper(const char *family, va_list ap)
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
void ast_free_ptr(void *ptr)
Socket address structure.
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
char * included_file
file name included
#define MAX_INCLUDE_LEVEL
#define ast_verb(level,...)
void ast_config_destroy(struct ast_config *config)
Destroys a config.
static void ast_includes_destroy(struct ast_config_include *incls)
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_category * ast_category_new(const char *name, const char *in_file, int lineno)
Create a category structure.
static void config_cache_destroy_entry(struct cache_file_mtime *cfmtime)
#define AST_LIST_INSERT_SORTALPHA(head, elm, field, sortfield)
Inserts a list entry into a alphabetically sorted list.
struct ast_comment * trailing
static struct ast_config_map * config_maps
static void make_fn(char *fn, size_t fn_size, const char *file, const char *configfile)
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
struct ast_category * ast_category_get(const struct ast_config *config, const char *category_name)
Retrieve a category if it exists.
int ast_update_realtime(const char *family, const char *keyfield, const char *lookup,...) attribute_sentinel
Update realtime configuration.
static int append_mapping(const char *name, const char *driver, const char *database, const char *table, int priority)
static struct inclfile * set_fn(char *fn, size_t fn_size, const char *file, const char *configfile, struct ao2_container *fileset)
#define ast_opt_exec_includes
#define ast_debug(level,...)
Log a DEBUG message.
static char * handle_cli_core_show_config_mappings(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
int ast_category_exist(const struct ast_config *config, const char *category_name)
Check for category duplicates.
struct ast_variable * ast_variables_reverse(struct ast_variable *var)
Reverse a variable list.
void ast_category_destroy(struct ast_category *cat)
struct ast_category::template_instance_list template_instances
struct ast_comment * trailing
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.
struct ast_variable * root
static void inherit_category(struct ast_category *new, const struct ast_category *base)
General Asterisk PBX channel definitions.
int ast_destroy_realtime(const char *family, const char *keyfield, const char *lookup,...) attribute_sentinel
Destroy realtime configuration.
int ast_parse_arg(const char *arg, enum ast_parse_flags flags, void *result,...)
The argument parsing routine.
char * ast_realtime_encode_chunk(struct ast_str **dest, ssize_t maxlen, const char *chunk)
Encodes a chunk of data for realtime.
static void insert_leading_blank_lines(FILE *fp, struct inclfile *fi, struct ast_comment *precomments, int lineno)
static force_inline int attribute_pure ast_strlen_zero(const char *s)
#define MAX_NESTED_COMMENTS
struct sla_ringing_trunk * last
config_load_func * load_func
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
#define ao2_ref(o, delta)
char * ast_category_browse(struct ast_config *config, const char *prev)
Goes through categories.
int ast_register_atexit(void(*func)(void))
Register a function to be executed before Asterisk exits.
static void CB_RESET(struct ast_str *cb, struct ast_str *llb)
char * ast_realtime_decode_chunk(char *chunk)
Remove standard encoding from realtime values, which ensures that a semicolon embedded within a singl...
ast_cli_command
calling arguments for new-style handlers.
realtime_require * require_func
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
int config_text_file_save(const char *filename, const struct ast_config *cfg, const char *generator)
int register_config_cli(void)
Exposed initialization method for core process.
static void config_cache_remove(const char *filename, const char *who_asked)
static int init_appendbuf(void *data)
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 void cfmstat_save(struct cache_file_mtime *cfmtime, struct stat *statbuf)
struct cache_file_mtime::includes includes
#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_strdupa(s)
duplicate a string in memory from the stack
static void ast_destroy_template_list(struct ast_category *cat)
struct ast_variable * ast_category_root(struct ast_config *config, char *cat)
returns the root ast_variable of a config
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
static void inclfile_destroy(void *obj)
static struct ast_category * next_available_category(struct ast_category *cat)
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)
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
static struct ast_generator generator
static struct ast_config_engine * config_engine_list
static void CB_ADD(struct ast_str **cb, const char *str)
const char * ast_config_AST_CONFIG_DIR
static struct ast_config_engine text_file_engine
static int cfmstat_cmp(struct cache_file_mtime *cfmtime, struct stat *statbuf)
void ast_variable_append(struct ast_category *category, struct ast_variable *variable)
struct ast_comment * sameline
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
#define ao2_alloc(data_size, destructor_fn)
#define AST_LIST_LAST(head)
Returns the last entry contained in a list.
int ast_config_engine_register(struct ast_config_engine *newconfig)
Register config engine.
int include_location_lineno
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
#define ao2_find(arg1, arg2, arg3)
const char * ast_inet_ntoa(struct in_addr ia)
thread-safe replacement for inet_ntoa().
static struct ast_comment * ALLOC_COMMENT(struct ast_str *buffer)
struct ast_config * ast_config_new(void)
Create a new base configuration structure.
static void ast_variable_destroy(struct ast_variable *doomed)
struct ast_variable * ast_variables_dup(struct ast_variable *var)
Duplicate variable list.
static char * handle_cli_config_list(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
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_category * last
Structure used to handle boolean flags.
int ast_realtime_require_field(const char *family,...) attribute_sentinel
Inform realtime what fields that may be stored.
#define ast_clear_flag(p, flag)
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.
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
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.
#define MIN_VARIABLE_FNAME_SPACE
struct ast_comment * precomments
char * include_location_file
file name in which the include occurs
realtime_update2 * update2_func
Standard Command Line Interface.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
unsigned long stat_mtime_nsec
#define ao2_container_alloc(arg1, arg2, arg3)
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
int ast_cli_register_multiple(struct ast_cli_entry *e, int len)
Register multiple commands.
realtime_multi_get * realtime_multi_func
struct ast_category * root
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
struct ast_comment * sameline
struct ast_config_map * next
struct ast_config_include * next
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
struct ast_variable * next
void ast_str_trim_blanks(struct ast_str *buf)
Trims trailing whitespace characters from an ast_str string.
void ast_category_append(struct ast_config *config, struct ast_category *cat)
#define CONFIG_STATUS_FILEINVALID
void ast_variable_insert(struct ast_category *category, struct ast_variable *variable, const char *line)
struct ast_config * ast_config_internal_load(const char *configfile, struct ast_config *cfg, struct ast_flags flags, const char *suggested_incl_file, const char *who_asked)
void ast_category_rename(struct ast_category *cat, const char *name)
struct ast_config_include * includes
static struct hostent * hp
struct cache_file_include::@241 list
void ast_config_set_current_category(struct ast_config *cfg, const struct ast_category *cat)
Set the category within the configuration as being current.
static int match(struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
static int count_linefeeds(char *str)
int ast_category_empty(struct ast_config *cfg, const char *category)
Removes and destroys all variables within a category.
static void move_variables(struct ast_category *old, struct ast_category *new)
#define AST_MUTEX_DEFINE_STATIC(mutex)
struct cache_file_include * next
config_cache_attribute_enum
struct ast_variable * ast_variable_new(const char *name, const char *value, const char *filename)
struct ast_category * inst
char * file
The file name from whence this declaration was read.
#define ASTERISK_FILE_VERSION(file, version)
Register/unregister a source code file with the core.
struct ast_config * ast_load_realtime_multientry(const char *family,...) attribute_sentinel
Retrieve realtime configuration.
#define CONFIG_STATUS_FILEUNCHANGED
int ast_config_engine_deregister(struct ast_config_engine *del)
Deregister config engine.
#define ast_mutex_unlock(a)
static struct ast_threadstorage appendbuf
realtime_var_get * realtime_func
int ast_check_realtime(const char *family)
Check if realtime engine is configured for family.
int read_config_maps(void)
Exposed re-initialization method for core process.