📄 astconfig.c
字号:
{ struct ast_variable *cur, *prev=NULL, *newer; if (!(newer = ast_variable_new(variable, value))) return -1; newer->object = object; for (cur = category->root; cur; prev = cur, cur = cur->next) { if (strcasecmp(cur->name, variable) || (!ast_strlen_zero(match) && strcasecmp(cur->value, match))) continue; newer->next = cur->next; newer->object = cur->object || object; if (prev) prev->next = newer; else category->root = newer; if (category->last == cur) category->last = newer; cur->next = NULL; ast_variables_destroy(cur); return 0; } if (prev) prev->next = newer; else category->root = newer; return 0;}int ast_category_delete(struct ast_config *cfg, char *category){ struct ast_category *prev=NULL, *cat; cat = cfg->root; while(cat) { if (cat->name == category) { ast_variables_destroy(cat->root); if (prev) { prev->next = cat->next; if (cat == cfg->last) cfg->last = prev; } else { cfg->root = cat->next; if (cat == cfg->last) cfg->last = NULL; } free(cat); return 0; } prev = cat; cat = cat->next; } prev = NULL; cat = cfg->root; while(cat) { if (!strcasecmp(cat->name, category)) { ast_variables_destroy(cat->root); if (prev) { prev->next = cat->next; if (cat == cfg->last) cfg->last = prev; } else { cfg->root = cat->next; if (cat == cfg->last) cfg->last = NULL; } free(cat); return 0; } prev = cat; cat = cat->next; } return -1;}void ast_config_destroy(struct ast_config *cfg){ struct ast_category *cat, *catn; if (!cfg) return; cat = cfg->root; while(cat) { ast_variables_destroy(cat->root); catn = cat; cat = cat->next; free(catn); } free(cfg);}struct ast_category *ast_config_get_current_category(const struct ast_config *cfg){ return cfg->current;}void ast_config_set_current_category(struct ast_config *cfg, const struct ast_category *cat){ /* cast below is just to silence compiler warning about dropping "const" */ cfg->current = (struct ast_category *) cat;}static int process_text_line(struct ast_config *cfg, struct ast_category **cat, char *buf, int lineno, const char *configfile, int withcomments, char **comment_buffer, int *comment_buffer_size, char **lline_buffer, int *lline_buffer_size){ char *c; char *cur = buf; struct ast_variable *v; char cmd[512], exec_file[512]; int object, do_exec, do_include; /* Actually parse the entry */ if (cur[0] == '[') { struct ast_category *newcat = NULL; char *catname; /* A category header */ c = strchr(cur, ']'); if (!c) { ast_log(LOG_WARNING, "parse error: no closing ']', line %d of %s\n", lineno, configfile); return -1; } *c++ = '\0'; cur++; if (*c++ != '(') c = NULL; catname = cur; if (!(*cat = newcat = ast_category_new(catname))) { return -1; } /* add comments */ if (withcomments && *comment_buffer && (*comment_buffer)[0] ) { newcat->precomments = ALLOC_COMMENT(*comment_buffer); } if (withcomments && *lline_buffer && (*lline_buffer)[0] ) { newcat->sameline = ALLOC_COMMENT(*lline_buffer); } if( withcomments ) CB_RESET(comment_buffer, lline_buffer); /* If there are options or categories to inherit from, process them now */ if (c) { if (!(cur = strchr(c, ')'))) { ast_log(LOG_WARNING, "parse error: no closing ')', line %d of %s\n", lineno, configfile); return -1; } *cur = '\0'; while ((cur = strsep(&c, ","))) { if (!strcasecmp(cur, "!")) { (*cat)->ignored = 1; } else if (!strcasecmp(cur, "+")) { *cat = category_get(cfg, catname, 1); if (!(*cat)) { if (newcat) ast_category_destroy(newcat); ast_log(LOG_WARNING, "Category addition requested, but category '%s' does not exist, line %d of %s\n", catname, lineno, configfile); return -1; } if (newcat) { move_variables(newcat, *cat); ast_category_destroy(newcat); newcat = NULL; } } else { struct ast_category *base; base = category_get(cfg, cur, 1); if (!base) { ast_log(LOG_WARNING, "Inheritance requested, but category '%s' does not exist, line %d of %s\n", cur, lineno, configfile); return -1; } inherit_category(*cat, base); } } } if (newcat) ast_category_append(cfg, *cat); } else if (cur[0] == '#') { /* A directive */ cur++; c = cur; while(*c && (*c > 32)) c++; if (*c) { *c = '\0'; /* Find real argument */ c = ast_skip_blanks(c + 1); if (!(*c)) c = NULL; } else c = NULL; do_include = !strcasecmp(cur, "include"); if(!do_include) do_exec = !strcasecmp(cur, "exec"); else do_exec = 0; if (do_exec && !ast_opt_exec_includes) { ast_log(LOG_WARNING, "Cannot perform #exec unless execincludes option is enabled in asterisk.conf (options section)!\n"); do_exec = 0; } if (do_include || do_exec) { if (c) { /* Strip off leading and trailing "'s and <>'s */ while((*c == '<') || (*c == '>') || (*c == '\"')) c++; /* Get rid of leading mess */ cur = c; while (!ast_strlen_zero(cur)) { c = cur + strlen(cur) - 1; if ((*c == '>') || (*c == '<') || (*c == '\"')) *c = '\0'; else break; } /* #exec </path/to/executable> We create a tmp file, then we #include it, then we delete it. */ if (do_exec) { snprintf(exec_file, sizeof(exec_file), "/var/tmp/exec.%d.%ld", (int)time(NULL), (long)pthread_self()); snprintf(cmd, sizeof(cmd), "%s > %s 2>&1", cur, exec_file); ast_safe_system(cmd); cur = exec_file; } else exec_file[0] = '\0'; /* A #include */#ifdef USE_ASTERISK_1_4 do_include = ast_config_internal_load(cur, cfg, withcomments) ? 1 : 0;#else do_include = ast_config_internal_load(cur, cfg) ? 1 : 0;#endif if(!ast_strlen_zero(exec_file)) unlink(exec_file); if(!do_include) return 0; } else { ast_log(LOG_WARNING, "Directive '#%s' needs an argument (%s) at line %d of %s\n", do_exec ? "exec" : "include", do_exec ? "/path/to/executable" : "filename", lineno, configfile); } } else ast_log(LOG_WARNING, "Unknown directive '%s' at line %d of %s\n", cur, lineno, configfile); } else { /* Just a line (variable = value) */ if (!(*cat)) { ast_log(LOG_WARNING, "parse error: No category context for line %d of %s\n", lineno, configfile); return -1; } c = strchr(cur, '='); if (c) { *c = 0; c++; /* Ignore > in => */ if (*c== '>') { object = 1; c++; } else object = 0; if ((v = ast_variable_new(ast_strip(cur), ast_strip(c)))) { v->lineno = lineno; v->object = object; /* Put and reset comments */ v->blanklines = 0; ast_variable_append(*cat, v); /* add comments */ if (withcomments && *comment_buffer && (*comment_buffer)[0] ) { v->precomments = ALLOC_COMMENT(*comment_buffer); } if (withcomments && *lline_buffer && (*lline_buffer)[0] ) { v->sameline = ALLOC_COMMENT(*lline_buffer); } if( withcomments ) CB_RESET(comment_buffer, lline_buffer); } else { return -1; } } else { ast_log(LOG_WARNING, "No '=' (equal sign) in line %d of %s\n", lineno, configfile); } } return 0;}static struct ast_config *config_text_file_load(const char *database, const char *table, const char *filename, struct ast_config *cfg, int withcomments){ char fn[256]; char buf[8192]; char *new_buf, *comment_p, *process_buf; FILE *f; int lineno=0; int comment = 0, nest[MAX_NESTED_COMMENTS]; struct ast_category *cat = NULL; int count = 0; struct stat statbuf; /*! Growable string buffer */ char *comment_buffer=0; /*!< this will be a comment collector.*/ int comment_buffer_size=0; /*!< the amount of storage so far alloc'd for the comment_buffer */ char *lline_buffer=0; /*!< A buffer for stuff behind the ; */ int lline_buffer_size=0; cat = ast_config_get_current_category(cfg); if (filename[0] == '/') { ast_copy_string(fn, filename, sizeof(fn)); } else { snprintf(fn, sizeof(fn), "%s/%s", (char *)ast_config_AST_CONFIG_DIR, filename); } if (withcomments) { CB_INIT(&comment_buffer, &comment_buffer_size, &lline_buffer, &lline_buffer_size); if (!lline_buffer || !comment_buffer) { ast_log(LOG_ERROR, "Failed to initialize the comment buffer!\n"); return NULL; } }#ifdef AST_INCLUDE_GLOB { int glob_ret; glob_t globbuf; globbuf.gl_offs = 0; /* initialize it to silence gcc */#ifdef SOLARIS glob_ret = glob(fn, GLOB_NOCHECK, NULL, &globbuf);#else glob_ret = glob(fn, GLOB_NOMAGIC|GLOB_BRACE, NULL, &globbuf);#endif if (glob_ret == GLOB_NOSPACE) ast_log(LOG_WARNING, "Glob Expansion of pattern '%s' failed: Not enough memory\n", fn); else if (glob_ret == GLOB_ABORTED) ast_log(LOG_WARNING, "Glob Expansion of pattern '%s' failed: Read error\n", fn); else { /* loop over expanded files */ int i; for (i=0; i<globbuf.gl_pathc; i++) { ast_copy_string(fn, globbuf.gl_pathv[i], sizeof(fn));#endif do { if (stat(fn, &statbuf)) continue; if (!S_ISREG(statbuf.st_mode)) { ast_log(LOG_WARNING, "'%s' is not a regular file, ignoring\n", fn); continue; } if (option_verbose > 1) { ast_verbose(VERBOSE_PREFIX_2 "Parsing '%s': ", fn); fflush(stdout); } if (!(f = fopen(fn, "r"))) { if (option_debug) ast_log(LOG_DEBUG, "No file to parse: %s\n", fn); if (option_verbose > 1) ast_verbose( "Not found (%s)\n", strerror(errno)); continue; } count++; if (option_debug) ast_log(LOG_DEBUG, "Parsing %s\n", fn); if (option_verbose > 1) ast_verbose("Found\n"); while(!feof(f)) { lineno++; if (fgets(buf, sizeof(buf), f)) { if ( withcomments ) { CB_ADD(&comment_buffer, &comment_buffer_size, lline_buffer); /* add the current lline buffer to the comment buffer */ lline_buffer[0] = 0; /* erase the lline buffer */ } new_buf = buf; if (comment) process_buf = NULL; else process_buf = buf; while ((comment_p = strchr(new_buf, COMMENT_META))) { if ((comment_p > new_buf) && (*(comment_p-1) == '\\')) { /* Yuck, gotta memmove */ memmove(comment_p - 1, comment_p, strlen(comment_p) + 1); new_buf = comment_p; } else if(comment_p[1] == COMMENT_TAG && comment_p[2] == COMMENT_TAG && (comment_p[3] != '-')) { /* Meta-Comment start detected ";--" */ if (comment < MAX_NESTED_COMMENTS) { *comment_p = '\0'; new_buf = comment_p + 3; comment++; nest[comment-1] = lineno; } else { ast_log(LOG_ERROR, "Maximum nest limit of %d reached.\n", MAX_NESTED_COMMENTS); } } else if ((comment_p >= new_buf + 2) && (*(comment_p - 1) == COMMENT_TAG) && (*(comment_p - 2) == COMMENT_TAG)) { /* Meta-Comment end detected */ comment--; new_buf = comment_p + 1; if (!comment) { /* Back to non-comment now */ if (process_buf) { /* Actually have to move what's left over the top, then continue */ char *oldptr; oldptr = process_buf + strlen(process_buf); if ( withcomments ) { CB_ADD(&comment_buffer, &comment_buffer_size, ";"); CB_ADD_LEN(&comment_buffer, &comment_buffer_size, oldptr+1, new_buf-oldptr-1); } memmove(oldptr, new_buf, strlen(new_buf) + 1); new_buf = oldptr; } else process_buf = new_buf; } } else { if (!comment) { /* If ; is found, and we are not nested in a comment, we immediately stop all comment processing */ if ( withcomments ) { LLB_ADD(&lline_buffer, &lline_buffer_size, comment_p); } *comment_p = '\0'; new_buf = comment_p; } else new_buf = comment_p + 1; } } if( withcomments && comment && !process_buf ) { CB_ADD(&comment_buffer, &comment_buffer_size, buf); /* the whole line is a comment, store it */ } if (process_buf) { char *buf = ast_strip(process_buf); if (!ast_strlen_zero(buf)) { if (process_text_line(cfg, &cat, buf, lineno, fn, withcomments, &comment_buffer, &comment_buffer_size, &lline_buffer, &lline_buffer_size)) { cfg = NULL; break; } } } } } fclose(f); } while(0); if (comment) { ast_log(LOG_WARNING,"Unterminated comment detected beginning on line %d\n", nest[comment - 1]); }#ifdef AST_INCLUDE_GLOB if (!cfg) break; } globfree(&globbuf); } }#endif if (cfg && cfg->include_level == 1 && withcomments && comment_buffer) { free(comment_buffer); free(lline_buffer); comment_buffer = NULL; lline_buffer = NULL; comment_buffer_size = 0; lline_buffer_size = 0; } if (count == 0) return NULL; return cfg;}int config_text_file_save(const char *configfile, const struct ast_config *cfg, const char *generator){ FILE *f; char fn[256]; char date[256]=""; time_t t;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -