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;
 
 
  180        unsigned int tmp = 
total;
 
 
  218#define MAX_INCLUDE_LEVEL 10 
  318    int name_len = strlen(
name) + 1;
 
  319    int val_len = strlen(
value) + 1;
 
  320    int fn_len = strlen(filename) + 1;
 
  327    variable = 
__ast_calloc(1, fn_len + name_len + val_len + 
sizeof(*variable),
 
  330        char *dst = variable->
stuff;    
 
  333        variable->
file = strcpy(dst, filename);
 
 
  362static void make_fn(
char *fn, 
size_t fn_size, 
const char *
file, 
const char *configfile);
 
  379            snprintf(real_included_file_name, real_included_file_name_size, 
"%s~~%d", included_file, inc->
inclusion_count);
 
  380        } 
while (stat(real_included_file_name, &statbuf) == 0);
 
  381        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);
 
  383        *real_included_file_name = 0;
 
  410        inc_file = 
ast_calloc(1, 
sizeof(*inc_file) + strlen(fn) + 1);
 
  415        strcpy(inc_file->
path, fn); 
 
  429            for (i = 0; i < globbuf.gl_pathc; i++) {
 
  430                char *matched_path = globbuf.gl_pathv[i];
 
  432                if (access(matched_path, 
F_OK) != 0) {
 
  437                inc_file = 
ast_calloc(1, 
sizeof(*inc_file) + strlen(matched_path) + 1);
 
  443                strcpy(inc_file->
path, matched_path);   
 
  460    if (
conf->includes_root && 
conf->includes_last) {
 
  461        conf->includes_last->next = inc;
 
  463        conf->includes_root = inc;
 
  465    conf->includes_last = inc;
 
 
  476    int from_len = strlen(from_file);
 
  477    int to_len = strlen(to_file);
 
  479    if (strcmp(from_file, to_file) == 0) 
 
  491    for (incl = 
conf->includes_root; incl; incl = incl->
next) {
 
  493            if (from_len >= to_len)
 
  505    for (cat = 
conf->root; cat; cat = cat->
next) {
 
  510        if (strcmp(cat->
file, from_file) == 0) {
 
  511            if (from_len >= to_len)
 
  512                strcpy(cat->
file, to_file);
 
  523            if (strcmp(v->
file, from_file)) {
 
  535                strcpy(
str, to_file);
 
  550            if (cat->
last == v) {
 
 
  565    for (x = 
conf->includes_root; x; x = x->
next) {
 
 
  580        category->
root = variable;
 
  581    category->
last = variable;
 
 
  592    if (!variable || sscanf(line, 
"%30d", &insertline) != 1) {
 
  597        category->
root = variable;
 
  606        cur->
next = variable;
 
 
  641    while ((
var = 
var->next)) {
 
 
  658    if (!var1 || !var1->
next) {
 
 
  691    if (
config->last_browse && (
config->last_browse->name == category)) {
 
  692        cat = 
config->last_browse;
 
 
  712    memset(&top, 0, 
sizeof(top));
 
 
  745        for (curr = sh; curr->
next; curr = curr->
next);
 
  749    for (curr = newvar; curr->
next; curr = curr->
next);
 
 
  758    for (v = *head; v; prev = &v->
next, v = v->
next) {
 
  759        if (!strcmp(v->
name, replacement->
name)) {
 
 
  775    for (v = *head; v; prev = &v->
next, v = v->
next) {
 
 
  788    const char *name_value_separator, 
const char *quote_char, 
struct ast_str **
str)
 
  804            var->value, 
S_OR(quote_char, 
""), 
var->next ? item_separator : 
"");
 
 
  814    const char *name_value_separator, 
const char *quote_str)
 
  831    nv_sep = 
ast_strlen_zero(name_value_separator) ? 
'=' : name_value_separator[0];
 
 
  855    const char *name_value_separator)
 
 
  884            if (!strcasecmp(variable, v->
name)) {
 
  892            for (v = cat->
root; v; v = v->
next) {
 
  893                if (!strcasecmp(variable, v->
name)) {
 
 
  904    const char *category, 
const char *variable, 
const char *
filter)
 
 
  928    for (v = list; v; v = v->
next) {
 
  929        if (!strcasecmp(variable_name, v->
name)) {
 
 
  944    if (!(left && right)) {
 
  948    op = strrchr(right->
name, 
' ');
 
 
  966    if (!(left && right)) {
 
  970    for (field = right; field; field = field->
next) {
 
  971        char *space = strrchr(field->
name, 
' ');
 
  989            if (!old || strcmp(old->
value, field->
value)) {
 
 1002        for (field = left; field; field = field->
next) {
 
 1006        if (right_count != left_count) {
 
 
 1018    for (v = list; v; v = v->
next) {
 
 1019        if (!strcasecmp(variable, v->
name)) {
 
 
 1029    const char *found = 
NULL;
 
 1031    for (v = list; v; v = v->
next) {
 
 1032        if (!strcasecmp(variable, v->
name)) {
 
 
 1044        new->lineno = old->
lineno;
 
 1045        new->object = old->
object;
 
 
 1066    const char *
match, 
char sep)
 
 1070    int match_found = 0, match_expressions = 0;
 
 1071    int template_ok = 0;
 
 1088        char *match_value = 
NULL;
 
 1091        regex_t r_name, r_value;
 
 1093        match_expressions++;
 
 1099        if (match_value == 
NULL) {
 
 1103        if (!strcmp(
"TEMPLATES", match_name)) {
 
 1104            if (!strcasecmp(
"include", match_value)) {
 
 1109            } 
else if (!strcasecmp(
"restrict", match_value)) {
 
 1120        if ((rc = regcomp(&r_name, match_name, REG_EXTENDED | REG_NOSUB))) {
 
 1122            regerror(rc, &r_name, regerr, 128);
 
 1124                match_name, regerr);
 
 1128        if ((rc = regcomp(&r_value, match_value, REG_EXTENDED | REG_NOSUB))) {
 
 1130            regerror(rc, &r_value, regerr, 128);
 
 1132                match_value, regerr);
 
 1138        for (v = cat->
root; v; v = v->
next) {
 
 1139            if (!regexec(&r_name, v->
name, 0, 
NULL, 0)
 
 1140                && !regexec(&r_value, v->
value, 0, 
NULL, 0)) {
 
 1148    if (match_found == match_expressions && (!cat->
ignored || template_ok)) {
 
 
 1164    if (!category->
file) {
 
 
 1185    const char *category_name, 
const char *
filter, 
char sep, 
char pointer_match_possible)
 
 1189    if (pointer_match_possible) {
 
 
 1207    const char *category_name, 
const char *
filter)
 
 
 1214    return category->
name;
 
 
 1254        config->last->next = category;
 
 1264    config->current = category;
 
 
 1283    for (cur_category = 
config->
root->
next; cur_category; cur_category = cur_category->
next) {
 
 1284        if (!strcasecmp(cur_category->
name, 
match)) {
 
 1288            cat->
next = cur_category;
 
 1289            cur_category->
prev = cat;
 
 
 1344    for (incl = incls; incl; incl = inclnext) {
 
 1345        inclnext = incl->
next;
 
 
 1369        return category->
root;
 
 
 1405    int nmerges, psize, qsize, i;
 
 1431            for (i = 0; i < insize; i++) {
 
 1443            while (psize > 0 || (qsize > 0 && q)) {
 
 1450                } 
else if (qsize == 0 || !q) {
 
 1452                    e = p; p = p->
next; psize--;
 
 1453                } 
else if ((comparator(p, q) * descending) <= 0) {
 
 
 1498    } 
else if (
config->last_browse && (
config->last_browse->name == prev_name)) {
 
 1509            if (cat->
name == prev_name) {
 
 1521                if (!strcasecmp(cat->
name, prev_name)) {
 
 1533    config->last_browse = cat;
 
 
 1611        if (sscanf(line, 
"%30d", &req_item) != 1
 
 1619    cur = category->
root;
 
 1623        if ((0 <= req_item && num_item == req_item)
 
 1624            || (req_item < 0 && !strcasecmp(cur->
name, variable)
 
 1628                if (cur == category->
last)
 
 1632                if (cur == category->
last)
 
 
 1647                        const char *
value, 
const char *
match, 
unsigned int object)
 
 1655    for (cur = category->
root; cur; 
prev = cur, cur = cur->
next) {
 
 1679    newer->object = newer->object || object;
 
 1682    newer->next = cur->
next;
 
 1686        category->
root = newer;
 
 1688    if (category->
last == cur) {
 
 1689        category->
last = newer;
 
 
 1701    if (!
config || !category) {
 
 1705    if (category->
prev) {
 
 1711    if (category->
next) {
 
 1719    if (
config->last_browse == category) {
 
 
 1786        sizeof(*cfmtime) + strlen(filename) + 1 + strlen(who_asked) + 1);
 
 1791    strcpy(dst, filename); 
 
 1792    dst += strlen(dst) + 1;
 
 1793    cfmtime->
who_asked = strcpy(dst, who_asked); 
 
 
 1813#if defined(HAVE_STRUCT_STAT_ST_MTIM) 
 1815#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC) 
 1817#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC) 
 
 1889        if (!strcmp(cfmtime->
filename, filename)
 
 1890            && !strcmp(cfmtime->
who_asked, who_asked)) {
 
 
 1908        if (!strcmp(cfmtime->
filename, configfile) && !strcmp(cfmtime->
who_asked, who_asked))
 
 1924            if (!strcmp(cfinclude->
include, filename)) {
 
 1929        cfinclude = 
ast_calloc(1, 
sizeof(*cfinclude) + strlen(filename) + 1);
 
 1934        strcpy(cfinclude->
include, filename); 
 
 
 1963    struct stat output_file_info;
 
 1966    if (snprintf(
buf, 
sizeof(
buf), 
"%s 2>&1 > %s", command, output_file) >= 
sizeof(
buf)) {
 
 1967        ast_log(
LOG_ERROR, 
"Failed to construct command string to execute %s.\n", command);
 
 1975    fp = popen(
buf, 
"r");
 
 1984    while (fgets(
buf, 
sizeof(
buf), fp)) {
 
 1986        if (strlen(
buf) == 
sizeof(
buf) - 1 && 
buf[
sizeof(
buf) - 2] != 
'\n') {
 
 1992            while (fgets(
buf, 
sizeof(
buf), fp)) {
 
 1993                if (strlen(
buf) != 
sizeof(
buf) - 1 || 
buf[
sizeof(
buf) - 2] == 
'\n') {
 
 2024    if (stat(output_file, &output_file_info) == -1) {
 
 2025        ast_log(
LOG_ERROR, 
"#exec <%s>: Unable to stat() temporary file `%s': %s\n",
 
 2029    } 
else if (output_file_info.st_size == 0) {
 
 
 2048    const char *suggested_include_file,
 
 2052    const char *who_asked)
 
 2057    char exec_file[512];
 
 2060    if (cur[0] == 
'[') { 
 
 2072        c = strchr(cur, 
']');
 
 2100            if (!(cur = strchr(
c, 
')'))) {
 
 2106            while ((cur = 
strsep(&
c, 
","))) {
 
 2107                if (!strcasecmp(cur, 
"!")) {
 
 2108                    (*cat)->ignored = 1;
 
 2109                } 
else if (cur[0] == 
'+') {
 
 2112                    if (cur[1] != 
',') {
 
 2120                        ast_log(
LOG_WARNING, 
"Category addition requested, but category '%s' does not exist, line %d of %s\n", catname, 
lineno, configfile);
 
 2125                        (*cat)->ignored |= newcat->
ignored;
 
 2138                        ast_log(
LOG_WARNING, 
"Inheritance requested, but category '%s' does not exist, line %d of %s\n", cur, 
lineno, configfile);
 
 2165    } 
else if (cur[0] == 
'#') { 
 
 2167        char real_inclusion_name[256];
 
 2174        while (*
c && (*
c > 32)) {
 
 2188        if (!strcasecmp(cur, 
"include")) {
 
 2190        } 
else if (!strcasecmp(cur, 
"tryinclude")) {
 
 2192        } 
else if (!strcasecmp(cur, 
"exec")) {
 
 2194                ast_log(
LOG_WARNING, 
"Cannot perform #exec unless execincludes option is enabled in asterisk.conf (options section)!\n");
 
 2215        if ((*
c == 
'"') || (*
c == 
'<')) {
 
 2216            char quote_char = *
c;
 
 2217            if (quote_char == 
'<') {
 
 2221            if (*(
c + strlen(
c) - 1) == quote_char) {
 
 2223                *(
c + strlen(
c) - 1) = 
'\0';
 
 2235            snprintf(exec_file, 
sizeof(exec_file), 
"/var/tmp/exec.%d%d.%ld", (
int)now.tv_sec, (
int)now.tv_usec, (
long)pthread_self());
 
 2243            exec_file[0] = 
'\0';
 
 2260            ast_log(
LOG_ERROR, 
"The file '%s' was listed as a #include but it does not exist.\n", cur);
 
 2274        *last_inc = newinclude;
 
 2282                "parse error: No category context for line %d of %s\n", 
lineno, configfile);
 
 2286        is_escaped = cur[0] == 
'\\';
 
 2295        c = strchr(cur + is_escaped, 
'=');
 
 2297        if (
c && 
c > cur + is_escaped && (*(
c - 1) == 
'+')) {
 
 2311                if (!strcmp(
var->name, cur)) {
 
 2318                goto set_new_variable;
 
 
 2365#if defined(LOW_MEMORY) 
 2370    char *new_buf, *comment_p, *process_buf;
 
 2376    struct stat statbuf;
 
 2392    if (filename[0] == 
'/') {
 
 2410    globbuf.gl_offs = 0;    
 
 2412    if (glob_ret == GLOB_NOSPACE) {
 
 2414            "Glob Expansion of pattern '%s' failed: Not enough memory\n", fn);
 
 2417            "Glob Expansion of pattern '%s' failed: Read error\n", fn);
 
 2422        if (!cfg && (globbuf.gl_pathc != 1 || strcmp(fn, globbuf.gl_pathv[0]))) {
 
 2435        for (i = 0; i < globbuf.gl_pathc; i++) {
 
 2444                if (stat(fn, &statbuf)) {
 
 2451                if (!S_ISREG(statbuf.st_mode)) {
 
 2487                            NULL, flags, 
"", who_asked)) {
 
 2520                if (!(f = fopen(fn, 
"r"))) {
 
 2521                    ast_debug(1, 
"No file to parse: %s\n", fn);
 
 2522                    ast_verb(2, 
"Parsing '%s': Not found (%s)\n", fn, strerror(
errno));
 
 2531                    if (fgets(
buf, 
sizeof(
buf), f)) {
 
 2533                        if (strlen(
buf) == 
sizeof(
buf) - 1 && 
buf[
sizeof(
buf) - 2] != 
'\n') {
 
 2535                            while (fgets(
buf, 
sizeof(
buf), f)) {
 
 2536                                if (strlen(
buf) != 
sizeof(
buf) - 1 || 
buf[
sizeof(
buf) - 2] == 
'\n') {
 
 2545#define UTF8_BOM "\xEF\xBB\xBF" 
 2546                            size_t line_bytes = strlen(
buf);
 
 2547                            size_t bom_bytes = 
sizeof(
UTF8_BOM) - 1;
 
 2548                            if (line_bytes >= bom_bytes
 
 2550                                memmove(
buf, &
buf[bom_bytes], line_bytes - bom_bytes + 1);
 
 2577                            if ((comment_p > new_buf) && (*(comment_p - 1) == 
'\\')) {
 
 2579                                new_buf = comment_p;
 
 2581                                memmove(comment_p - 1, comment_p, strlen(comment_p) + 1);
 
 2586                                    new_buf = comment_p + 3;
 
 2592                            } 
else if ((comment_p >= new_buf + 2) &&
 
 2597                                new_buf = comment_p + 1;
 
 2604                                        oldptr = process_buf + strlen(process_buf);
 
 2610                                        memmove(oldptr, new_buf, strlen(new_buf) + 1);
 
 2613                                        process_buf = new_buf;
 
 2620                                    while ((comment_p > new_buf) && isspace(*(comment_p - 1))) {
 
 2625                                    if ((comment_p != new_buf) && (*comment_p == 
' ') && (*(comment_p + 1) == 
' ')) {
 
 2636                                    new_buf = comment_p;
 
 2638                                    new_buf = comment_p + 1;
 
 2652                                    suggested_include_file, &last_cat, &last_var, &last_inc,
 
 2670                } 
else if (last_var) {
 
 2678                } 
else if (last_inc) {
 
 
 2738static void gen_header(FILE *f1, 
const char *configfile, 
const char *fn, 
const char *generator)
 
 2746    fprintf(f1, 
";!\n");
 
 2747    fprintf(f1, 
";! Automatically generated configuration file\n");
 
 2748    if (strcmp(configfile, fn))
 
 2749        fprintf(f1, 
";! Filename: %s (%s)\n", configfile, fn);
 
 2751        fprintf(f1, 
";! Filename: %s\n", configfile);
 
 2752    fprintf(f1, 
";! Generator: %s\n", generator);
 
 2753    fprintf(f1, 
";! Creation Date: %s", date);
 
 2754    fprintf(f1, 
";!\n");
 
 
 2764static void make_fn(
char *fn, 
size_t fn_size, 
const char *
file, 
const char *configfile)
 
 2767        if (configfile[0] == 
'/') {
 
 2772    } 
else if (
file[0] == 
'/') {
 
 
 2836    int precomment_lines;
 
 2852    } 
else if (
lineno == 0) {
 
 2855    } 
else if (
lineno - precomment_lines - fi->
lineno < 5) {
 
 2858        for (i = fi->
lineno; i < 
lineno - precomment_lines; i++) {
 
 
 2877    if (access(fn, 
F_OK)) {
 
 2880        if (access(dn, 
R_OK | W_OK)) {
 
 2885        if (access(fn, 
R_OK | W_OK)) {
 
 
 2899        const char *line = cmt->
cmt;
 
 2902        while ((nl = strchr(line, 
'\n')) != 
NULL) {
 
 2904            if (line[0] != 
';' || line[1] != 
'!') {
 
 2906                fprintf(f, 
"%s\n", line);
 
 
 2924        fprintf(f, 
"#exec \"%s\"\n", incl->
exec_file);
 
 
 2972    make_fn(fn, 
sizeof(fn), 0, configfile);
 
 2994                fi = 
set_fn(fn, 
sizeof(fn), included_file->
path, configfile, fileset);
 
 2997                    ast_verb(2, 
"Saving tryinclude '%s'\n", fn);
 
 3011    fi = 
set_fn(fn, 
sizeof(fn), 0, configfile, fileset);
 
 3014        (f = fopen(fn, 
"w+"))
 
 3016        (f = fopen(fn, 
"w"))
 
 3032            fi = 
set_fn(fn, 
sizeof(fn), cat->
file, configfile, fileset);
 
 3062            fprintf(f, 
"[%s]", cat->
name);
 
 3074                        fprintf(f, 
"%s",x->
name);
 
 3083                fprintf(f, 
"%s", cmt->
cmt);
 
 3111                    if (
var->inherited) {
 
 3116                            if (!strcasecmp(
var->name, v->
name)) {
 
 3139                        if (!strcasecmp(
var->name, v->
name)) {
 
 3152                    if (!
var->inherited && parent && !strcmp(
var->value, parent->
value)) {
 
 3158                    if (
var->inherited || (parent && !strcmp(
var->value, parent->
value))) {
 
 3164                fi = 
set_fn(fn, 
sizeof(fn), 
var->file, configfile, fileset);
 
 3167                    ast_debug(1, 
"Unable to open for writing: %s\n", fn);
 
 3168                    ast_verb(2, 
"Unable to write %s (%s)\n", fn, strerror(
errno));
 
 3195                    int escaped_len = 2 * strlen(
var->value) + 1;
 
 3196                    char escaped[escaped_len];
 
 3200                    if (
var->sameline) {
 
 3201                        fprintf(f, 
"%s %s %s  %s", 
var->name, (
var->object ? 
"=>" : 
"="),
 
 3202                            escaped, 
var->sameline->cmt);
 
 3204                        fprintf(f, 
"%s %s %s\n", 
var->name, (
var->object ? 
"=>" : 
"="),
 
 3211                if (
var->blanklines) {
 
 3212                    blanklines = 
var->blanklines;
 
 3213                    while (blanklines--)
 
 3236                    ast_debug(1, 
"Unable to open for writing: %s\n", fn);
 
 3237                    ast_verb(2, 
"Unable to write %s (%s)\n", fn, strerror(
errno));
 
 3262        ast_verb(2, 
"Saving '%s': saved\n", fn);
 
 3264        ast_debug(1, 
"Unable to open for writing: %s\n", fn);
 
 3265        ast_verb(2, 
"Unable to write '%s' (%s)\n", fn, strerror(
errno));
 
 
 3292#ifdef TEST_FRAMEWORK 
 3302    length = 
sizeof(*map);
 
 3303    length += strlen(
name) + 1;
 
 3304    length += strlen(driver) + 1;
 
 3305    length += strlen(database) + 1;
 
 3307        length += strlen(table) + 1;
 
 3314    dst += strlen(dst) + 1;
 
 3315    map->
driver = strcpy(dst, driver);
 
 3316    dst += strlen(dst) + 1;
 
 3317    map->
database = strcpy(dst, database);
 
 3319        dst += strlen(dst) + 1;
 
 3320        map->
table = strcpy(dst, table);
 
 
 3335    char *driver, *table, *database, *textpri, *stringp, *tmp;
 
 3359        driver = 
strsep(&stringp, 
",");
 
 3364        if ((tmp = strchr(stringp, 
'\"')))
 
 3368        if (*stringp == 
'"') {
 
 3370            database = 
strsep(&stringp, 
"\"");
 
 3374            database = 
strsep(&stringp, 
",");
 
 3377        table = 
strsep(&stringp, 
",");
 
 3378        textpri = 
strsep(&stringp, 
",");
 
 3379        if (!textpri || !(pri = atoi(textpri))) {
 
 3388        if (!strcmp(v->
name, 
"asterisk.conf")) {
 
 3393        if (!strcmp(v->
name, 
"logger.conf")) {
 
 3398        if (!driver || !database)
 
 3400        if (!strcasecmp(v->
name, 
"iaxfriends")) {
 
 3401            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");
 
 
 3454        if (!strcasecmp(family, map->
name)) {
 
 3458    ast_debug(5, 
"Failed to find a realtime mapping for %s\n", family);
 
 
 3484            if (!strcasecmp(eng->name, map->
driver))
 
 
 3510    for (cat_iter = old->
root; cat_iter; cat_iter = cat_iter->
next) {
 
 3517        if (cat_iter->
root) {
 
 3519            if (!new_cat->
root) {
 
 
 3564    result = loader->
load_func(
db, table, filename, cfg, flags, suggested_include_file, who_asked);
 
 
 3592#define realtime_arguments_to_fields(ap, result) realtime_arguments_to_fields2(ap, 0, result) 
 3610    const char *newparam;
 
 3646        newparam = va_arg(ap, 
const char *);
 
 3647        newval = va_arg(ap, 
const char *);
 
 3648        while ((newparam = va_arg(ap, 
const char *))) {
 
 3649            newval = va_arg(ap, 
const char *);
 
 3654    newparam = va_arg(ap, 
const char *);
 
 3659    newval = va_arg(ap, 
const char *);
 
 3666    while ((newparam = va_arg(ap, 
const char *))) {
 
 3669        newval = va_arg(ap, 
const char *);
 
 3677        field->
next = fields;
 
 
 3696    for (i = 1; ; i++) {
 
 3697        if ((eng = 
find_engine(family, i, 
db, 
sizeof(
db), table, 
sizeof(table)))) {
 
 
 3727    va_start(ap, family);
 
 
 3760            if (cur->
value[0] == 
' ' && cur->
value[1] == 
'\0') {
 
 3761                char *vptr = (
char *) cur->
value;
 
 
 3779    va_start(ap, family);
 
 
 3824    va_start(ap, family);
 
 3825    for (i = 1; ; i++) {
 
 3826        if ((eng = 
find_engine(family, i, 
db, 
sizeof(
db), table, 
sizeof(table)))) {
 
 
 3850    for (i = 1; ; i++) {
 
 3851        if ((eng = 
find_engine(family, i, 
db, 
sizeof(
db), table, 
sizeof(table)))) {
 
 
 3871    for (i = 1; ; i++) {
 
 3872        if ((eng = 
find_engine(family, i, 
db, 
sizeof(
db), table, 
sizeof(table)))) {
 
 
 3894    va_start(ap, family);
 
 
 3912    for (i = 1; ; i++) {
 
 3913        if ((eng = 
find_engine(family, i, 
db, 
sizeof(
db), table, 
sizeof(table)))) {
 
 
 3931    va_start(ap, lookup);
 
 
 3949    for (i = 1; ; i++) {
 
 3950        if ((eng = 
find_engine(family, i, 
db, 
sizeof(
db), table, 
sizeof(table)))) {
 
 
 3968    va_start(ap, family);
 
 3975    va_start(ap, family);
 
 3979    if (!lookup_fields || !update_fields) {
 
 
 3993    for (i = 1; ; i++) {
 
 3994        if ((eng = 
find_engine(family, i, 
db, 
sizeof(
db), table, 
sizeof(table)))) {
 
 
 4012    va_start(ap, family);
 
 
 4030    for (i = 1; ; i++) {
 
 4031        if ((eng = 
find_engine(family, i, 
db, 
sizeof(
db), table, 
sizeof(table)))) {
 
 
 4049    va_start(ap, lookup);
 
 
 4065    for (; *chunk; chunk++) {
 
 4066        if (*chunk == 
'^' && strchr(
"0123456789ABCDEFabcdef", chunk[1]) && strchr(
"0123456789ABCDEFabcdef", chunk[2])) {
 
 4067            sscanf(chunk + 1, 
"%02hhX", (
unsigned char *)chunk);
 
 4068            memmove(chunk + 1, chunk + 3, strlen(chunk + 3) + 1);
 
 
 4076    if (!strchr(chunk, 
';') && !strchr(chunk, 
'^')) {
 
 4080        for (; *chunk; chunk++) {
 
 4081            if (strchr(
";^", *chunk)) {
 
 
 4095    void *p_result, ...)
 
 4100    va_start(ap, p_result);
 
 4105        int32_t *
result = p_result;
 
 4107        char *endptr = 
NULL;
 
 4111            def = va_arg(ap, int32_t);
 
 4114            low = va_arg(ap, int32_t);
 
 4115            high = va_arg(ap, int32_t);
 
 4122        x = strtol(arg, &endptr, 0);
 
 4128        error = (x < low) || (x > high);
 
 4132            } 
else if (x > high) {
 
 4144        ast_debug(3, 
"extract int from [%s] in [%d, %d] gives [%ld](%d)\n",
 
 4151        unsigned long int x = 0;
 
 4152        uint32_t *
result = p_result;
 
 4154        char *endptr = 
NULL;
 
 4158            def = va_arg(ap, uint32_t);
 
 4162            low = va_arg(ap, uint32_t);
 
 4163            high = va_arg(ap, uint32_t);
 
 4177        x = strtoul(arg, &endptr, 0);
 
 4182        error = (x < low) || (x > high);
 
 4186            } 
else if (x > high) {
 
 4197        ast_debug(3, 
"extract uint from [%s] in [%u, %u] gives [%lu](%d)\n",
 
 4214            def = va_arg(ap, 
int);
 
 4217            low = va_arg(ap, 
int);
 
 4218            high = va_arg(ap, 
int);
 
 4225        if (
error || x < INT_MIN || x > INT_MAX) {
 
 4230        error = (x < low) || (x > high);
 
 4234            } 
else if (x > high) {
 
 4246        ast_debug(3, 
"extract timelen from [%s] in [%d, %d] gives [%d](%d)\n",
 
 4253        double *
result = p_result;
 
 4254        double x = 0, def = 
result ? *
result : 0, low = -HUGE_VAL, high = HUGE_VAL;
 
 4255        char *endptr = 
NULL;
 
 4259            def = va_arg(ap, 
double);
 
 4263            low = va_arg(ap, 
double);
 
 4264            high = va_arg(ap, 
double);
 
 4271        x = strtod(arg, &endptr);
 
 4272        if (*endptr || 
errno == ERANGE) {
 
 4276        error = (x < low) || (x > high);
 
 4284        ast_debug(3, 
"extract double from [%s] in [%f, %f] gives [%f](%d)\n",
 
 4296        ast_debug(3, 
"extract addr from %s gives %s(%d)\n",
 
 4304        struct sockaddr_in _sa_buf; 
 
 4305        struct sockaddr_in *sa = p_result ?
 
 4306            (
struct sockaddr_in *)p_result : &_sa_buf;
 
 4309            va_arg(ap, 
struct sockaddr_in *) : sa;
 
 4312        memset(&_sa_buf, 
'\0', 
sizeof(_sa_buf)); 
 
 4316        sa->sin_family = AF_INET;   
 
 4325                sa->sin_port = def->sin_port;
 
 4327                sa->sin_port = def->sin_port;
 
 4329                sa->sin_port = htons(strtol(port, 
NULL, 0));
 
 4331            sa->sin_port = def->sin_port;
 
 4338            sa->sin_addr = def->sin_addr;
 
 4340            struct sockaddr_in tmp;
 
 4342            sa->sin_addr = tmp.sin_addr;
 
 4345            "extract inaddr from [%s] gives [%s:%d](%d)\n",
 
 4347            ntohs(sa->sin_port), 
error);
 
 
 4362        e->
command = 
"core show config mappings";
 
 4364            "Usage: core show config mappings\n" 
 4365            "   Shows the filenames to config engines.\n";
 
 4375            ast_cli(
a->fd, 
"No config mappings found.\n");
 
 
 4402            "Usage: config reload <filename.conf>\n" 
 4403            "   Reloads all modules that reference <filename.conf>\n";
 
 4410        wordlen = strlen(
a->word);
 
 4424            if (!strncmp(cfmtime->
filename, 
a->word, wordlen)) {
 
 4444        if (!strcmp(cfmtime->
filename, 
a->argv[2])) {
 
 
 4463            "Usage: config list\n" 
 4464            "   Show all modules that have loaded a configuration file\n";
 
 
 4559        if (!strcasecmp(hook->
filename, filename) &&
 
 4560                !strcasecmp(hook->module, module)) {
 
 
 4570        const char *filename,
 
 
 4606        ast_verb(0, 
"[ Initializing Custom Configuration Options ]\n");
 
 
void ast_cli_unregister_multiple(void)
struct sla_ringing_trunk * first
struct sla_ringing_trunk * last
static int copy(char *infile, char *outfile)
Utility function to copy a file.
char * strsep(char **str, const char *delims)
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.
#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,...)
#define ast_cli_command(fd, s)
#define ast_cli_register_multiple(e, len)
Register multiple commands.
static void CB_RESET(void)
static char * lline_buffer
#define AST_LIST_HEAD_NOLOCK(name, type)
Defines a structure to be used to hold a list of specified type (with no lock).
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.
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
@ CONFIG_FLAG_WITHCOMMENTS
@ CONFIG_FLAG_FILEUNCHANGED
ast_parse_flags
Support code to parse config file arguments.
#define CONFIG_RT_NOT_FOUND
int(* config_hook_cb)(struct ast_config *cfg)
Callback when configuration is updated.
config_hook_flags
Flags that affect the behaviour of config hooks.
#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.
static void config_included_files_destroy(struct ast_config_include *incl)
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)
include_statement_type
Types used for ast_include_new() include_type.
@ CONFIG_STATEMENT_TRYINCLUDE
@ CONFIG_STATEMENT_INCLUDE
static ast_mutex_t config_lock
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 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, struct ast_config_include **last_inc, const char *who_asked)
parse one line in the configuration.
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,...)
struct ast_config_include * ast_include_new(struct ast_config *conf, const char *from_file, const char *included_file, int include_type, const char *exec_file, int from_lineno, char *real_included_file_name, int real_included_file_name_size)
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 void print_include(FILE *f, struct ast_config_include *incl)
static void ast_variable_move(struct ast_variable *dst_var, struct ast_variable *src_var)
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.
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)
static void ast_include_destroy(struct ast_config_include *incl)
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 void print_comment(FILE *f, struct ast_comment *comment)
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.
size_t attribute_pure ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within 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.
char *attribute_pure ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str 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 *attribute_pure 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::included_files_list included_files
struct ast_comment * sameline
struct ast_config_include * next
struct ast_comment * precomments
enum include_statement_type include_type
struct ast_comment * trailing
int include_location_lineno
struct ast_config_map * next
struct ast_config_include * includes_root
struct ast_config_include * includes_last
struct ast_category * current
struct ast_category * last
struct ast_category * root
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::@359 list
struct cache_file_mtime::includes includes
struct cache_file_mtime::@360 list
unsigned long stat_mtime_nsec
const char *config_hook_cb hook_cb
All configuration options for http media cache.
struct config_included_file * next
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.