Un-revert in preparation for actual fix

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@4880 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Mark Spencer
2005-01-22 22:13:11 +00:00
parent 28efa96e0d
commit 17c311c9b9
4 changed files with 217 additions and 230 deletions

128
config.c
View File

@@ -41,7 +41,7 @@
#define COMMENT_TAG '-' #define COMMENT_TAG '-'
static int ast_cust_config=0; static int ast_cust_config=0;
struct ast_config *(*global_load_func)(const char *dbname, const char *table, const char *, struct ast_config *,struct ast_category **,struct ast_variable **,int); static config_static_func *global_load_func;
static struct ast_config_map { static struct ast_config_map {
struct ast_config_map *next; struct ast_config_map *next;
@@ -169,19 +169,22 @@ char *ast_variable_retrieve(const struct ast_config *config, const char *categor
return NULL; return NULL;
} }
int ast_category_exist(struct ast_config *config, char *category_name) struct ast_category *ast_category_get(const struct ast_config *config, const char *category_name)
{ {
struct ast_category *category = NULL; struct ast_category *category = config->root;
category = config->root;
while(category) { while(category) {
if (!strcasecmp(category->name, category_name)) if (!strcasecmp(category->name, category_name))
return 1; return category;
category = category->next; category = category->next;
} }
return 0; return NULL;
}
int ast_category_exist(struct ast_config *config, char *category_name)
{
return !!ast_category_get(config, category_name);
} }
@@ -229,45 +232,54 @@ static struct ast_config_reg *get_config_registrations(void)
return ast_cust_config_list; return ast_cust_config_list;
} }
void ast_category_append(struct ast_config *config, struct ast_category *category)
{
if (config->last)
config->last->next = category;
else
config->root = category;
config->last = category;
}
static void variable_append(struct ast_category *category, struct ast_variable *variable)
{
if (category->last)
category->last->next = variable;
else
category->root = variable;
category->last = variable;
}
static int cfg_process(struct ast_config *tmp, struct ast_category **cat, char *buf, int lineno, const char *configfile, int includelevel)
static int cfg_process(struct ast_config *tmp, struct ast_category **_tmpc, struct ast_variable **_last, char *buf, int lineno, const char *configfile, int includelevel )
{ {
char *c; char *c;
char *cur; char *cur;
char *arg=NULL; char *arg=NULL;
struct ast_variable *v; struct ast_variable *v;
int object; int object;
cur = ast_strip(buf); cur = ast_strip(buf);
if (!ast_strlen_zero(cur)) { if (ast_strlen_zero(cur))
return 0;
/* Actually parse the entry */ /* Actually parse the entry */
if (cur[0] == '[') { if (cur[0] == '[') {
/* A category header */ /* A category header */
c = strchr(cur, ']'); c = strchr(cur, ']');
if (c) { if (!c) {
*c = 0;
*_tmpc = malloc(sizeof(struct ast_category));
if (!*_tmpc) {
ast_destroy(tmp); ast_destroy(tmp);
ast_log(LOG_WARNING, ast_log(LOG_WARNING, "parse error: no closing ']', line %d of %s\n", lineno, configfile);
"Out of memory, line %d\n", lineno);
return -1; return -1;
} }
memset(*_tmpc, 0, sizeof(struct ast_category)); *c = '\0';
strncpy((*_tmpc)->name, cur+1, sizeof((*_tmpc)->name) - 1); cur++;
(*_tmpc)->root = NULL; *cat = ast_new_category(cur);
if (!tmp->prev) if (!*cat) {
tmp->root = *_tmpc; ast_destroy(tmp);
else ast_log(LOG_WARNING, "Out of memory, line %d of %s\n", lineno, configfile);
tmp->prev->next = *_tmpc; return -1;
tmp->prev = *_tmpc;
*_last = NULL;
} else {
ast_log(LOG_WARNING,
"parse error: no closing ']', line %d of %s\n", lineno, configfile);
} }
ast_category_append(tmp, *cat);
} else if (cur[0] == '#') { } else if (cur[0] == '#') {
/* A directive */ /* A directive */
cur++; cur++;
@@ -285,6 +297,7 @@ static int cfg_process(struct ast_config *tmp, struct ast_category **_tmpc, stru
if (!strcasecmp(cur, "include")) { if (!strcasecmp(cur, "include")) {
/* A #include */ /* A #include */
if (c) { if (c) {
/* Strip off leading and trailing "'s and <>'s */
while((*c == '<') || (*c == '>') || (*c == '\"')) c++; while((*c == '<') || (*c == '>') || (*c == '\"')) c++;
/* Get rid of leading mess */ /* Get rid of leading mess */
cur = c; cur = c;
@@ -306,20 +319,19 @@ static int cfg_process(struct ast_config *tmp, struct ast_category **_tmpc, stru
if(arg && cur) { if(arg && cur) {
ast_log(LOG_WARNING, "Including files with explicit config engine no longer permitted. Please use extconfig.conf to specify all mappings\n"); ast_log(LOG_WARNING, "Including files with explicit config engine no longer permitted. Please use extconfig.conf to specify all mappings\n");
} else { } else {
if (!ast_internal_load(cur, tmp, _tmpc, _last, includelevel + 1)) if (!ast_internal_load(cur, tmp, cat, includelevel + 1))
return -1; return -1;
} }
} else } else
ast_log(LOG_WARNING, "Maximum Include level (%d) exceeded\n", includelevel); ast_log(LOG_WARNING, "Maximum Include level (%d) exceeded\n", includelevel);
} else } else
ast_log(LOG_WARNING, "Directive '#include' needs an argument (filename) at line %d of %s\n", lineno, configfile); ast_log(LOG_WARNING, "Directive '#include' needs an argument (filename) at line %d of %s\n", lineno, configfile);
/* Strip off leading and trailing "'s and <>'s */
} }
else else
ast_log(LOG_WARNING, "Unknown directive '%s' at line %d of %s\n", cur, lineno, configfile); ast_log(LOG_WARNING, "Unknown directive '%s' at line %d of %s\n", cur, lineno, configfile);
} else { } else {
/* Just a line (variable = value) */ /* Just a line (variable = value) */
if (!*_tmpc) { if (!*cat) {
ast_log(LOG_WARNING, ast_log(LOG_WARNING,
"parse error: No category context for line %d of %s\n", lineno, configfile); "parse error: No category context for line %d of %s\n", lineno, configfile);
ast_destroy(tmp); ast_destroy(tmp);
@@ -337,16 +349,11 @@ static int cfg_process(struct ast_config *tmp, struct ast_category **_tmpc, stru
object = 0; object = 0;
v = ast_new_variable(ast_strip(cur), ast_strip(c)); v = ast_new_variable(ast_strip(cur), ast_strip(c));
if (v) { if (v) {
v->next = NULL;
v->lineno = lineno; v->lineno = lineno;
v->object = object; v->object = object;
/* Put and reset comments */ /* Put and reset comments */
v->blanklines = 0; v->blanklines = 0;
if (*_last) variable_append(*cat, v);
(*_last)->next = v;
else
(*_tmpc)->root = v;
*_last = v;
} else { } else {
ast_destroy(tmp); ast_destroy(tmp);
ast_log(LOG_WARNING, "Out of memory, line %d\n", lineno); ast_log(LOG_WARNING, "Out of memory, line %d\n", lineno);
@@ -357,7 +364,6 @@ static int cfg_process(struct ast_config *tmp, struct ast_category **_tmpc, stru
} }
} }
}
return 0; return 0;
} }
@@ -423,7 +429,6 @@ int ast_save(char *configfile, struct ast_config *cfg, char *generator)
return 0; return 0;
} }
struct ast_variable *ast_load_realtime(const char *family, ...) struct ast_variable *ast_load_realtime(const char *family, ...)
{ {
struct ast_config_reg *reg; struct ast_config_reg *reg;
@@ -469,7 +474,7 @@ int ast_update_realtime(const char *family, const char *keyfield, const char *lo
return res; return res;
} }
struct ast_config *ast_internal_load(const char *configfile, struct ast_config *tmp, struct ast_category **_tmpc, struct ast_variable **_last, int includelevel) struct ast_config *ast_internal_load(const char *configfile, struct ast_config *tmp, struct ast_category **cat, int includelevel)
{ {
char fn[256]; char fn[256];
char buf[8192]; char buf[8192];
@@ -477,11 +482,10 @@ struct ast_config *ast_internal_load(const char *configfile, struct ast_config *
char table[256]; char table[256];
FILE *f; FILE *f;
int lineno=0; int lineno=0;
int master=0;
int comment = 0, nest[MAX_NESTED_COMMENTS]; int comment = 0, nest[MAX_NESTED_COMMENTS];
struct ast_config_reg *reg=NULL; struct ast_config_reg *reg=NULL;
struct ast_config *(*load_func)(const char *database, const char *table, const char *, struct ast_config *,struct ast_category **,struct ast_variable **,int); config_static_func *load_func;
char *comment_p, *process_buf, *new_buf=NULL; char *comment_p, *process_buf, *new_buf=NULL;
load_func=NULL; load_func=NULL;
@@ -501,7 +505,7 @@ struct ast_config *ast_internal_load(const char *configfile, struct ast_config *
if (load_func) { if (load_func) {
ast_log(LOG_NOTICE,"Loading Config %s via %s engine\n",configfile,reg && reg->name ? reg->name : "global"); ast_log(LOG_NOTICE,"Loading Config %s via %s engine\n",configfile,reg && reg->name ? reg->name : "global");
if((tmp = load_func(db, table, configfile,tmp, _tmpc, _last, includelevel))) if((tmp = load_func(db, table, configfile, tmp, cat, includelevel)))
return tmp; return tmp;
} }
} }
@@ -542,13 +546,13 @@ struct ast_config *ast_internal_load(const char *configfile, struct ast_config *
ast_log(LOG_DEBUG, "Parsing %s\n", fn); ast_log(LOG_DEBUG, "Parsing %s\n", fn);
else if (option_verbose > 2) else if (option_verbose > 2)
ast_verbose("Found\n"); ast_verbose("Found\n");
if (!tmp)
tmp = ast_new_config();
if (!tmp) { if (!tmp) {
if((tmp = malloc(sizeof(struct ast_config)))) { ast_log(LOG_WARNING, "Out of memory\n");
memset(tmp, 0, sizeof(struct ast_config)); fclose(f);
master = 1; return tmp;
} }
}
if (tmp) {
while(!feof(f)) { while(!feof(f)) {
lineno++; lineno++;
if (fgets(buf, sizeof(buf), f)) { if (fgets(buf, sizeof(buf), f)) {
@@ -599,15 +603,12 @@ struct ast_config *ast_internal_load(const char *configfile, struct ast_config *
new_buf = comment_p + 1; new_buf = comment_p + 1;
} }
} }
if (process_buf && cfg_process(tmp, _tmpc, _last, process_buf, lineno, fn, includelevel)) { if (process_buf && cfg_process(tmp, cat, process_buf, lineno, configfile, includelevel)) {
tmp = NULL; tmp = NULL;
break; break;
} }
} }
} }
} else
ast_log(LOG_WARNING, "Out of memory\n");
fclose(f); fclose(f);
} else { /* can't open file */ } else { /* can't open file */
if (option_debug) if (option_debug)
@@ -673,22 +674,9 @@ int ast_cust_config_active(void) {
struct ast_config *ast_load(char *configfile) struct ast_config *ast_load(char *configfile)
{ {
struct ast_category *tmpc=NULL; struct ast_category *category = NULL;
struct ast_variable *last = NULL;
return ast_internal_load(configfile, NULL, &tmpc, &last, 0); return ast_internal_load(configfile, NULL, &category, 0);
}
void ast_category_append(struct ast_config *config, struct ast_category *cat)
{
struct ast_category *prev = NULL;
cat->next = NULL;
if (config->root) {
prev = config->root;
while(prev->next) prev = prev->next;
prev->next = cat;
} else
config->root = cat;
} }
char *ast_category_browse(struct ast_config *config, char *prev) char *ast_category_browse(struct ast_config *config, char *prev)
@@ -732,8 +720,6 @@ struct ast_config *ast_new_config(void)
return config; return config;
} }
struct ast_category *ast_new_category(char *name) struct ast_category *ast_new_category(char *name)
{ {
struct ast_category *category; struct ast_category *category;
@@ -745,7 +731,6 @@ struct ast_category *ast_new_category(char *name)
return category; return category;
} }
struct ast_variable *ast_new_variable(char *name, char *value) struct ast_variable *ast_new_variable(char *name, char *value)
{ {
struct ast_variable *variable; struct ast_variable *variable;
@@ -755,7 +740,6 @@ struct ast_variable *ast_new_variable(char *name, char *value)
memset(variable, 0, length); memset(variable, 0, length);
variable->name = variable->stuff; variable->name = variable->stuff;
variable->value = variable->stuff + strlen(name) + 1; variable->value = variable->stuff + strlen(name) + 1;
variable->object=0;
strcpy(variable->name,name); strcpy(variable->name,name);
strcpy(variable->value,value); strcpy(variable->value,value);
} }

View File

@@ -96,6 +96,13 @@ int ast_true(const char *val);
*/ */
int ast_false(const char *val); int ast_false(const char *val);
/*! Retrieve a category if it exists
* \param config which config to use
* \param category_name name of the category you're looking for
* This will search through the categories within a given config file and search for a match. The passed category_name can be a regular string.
* Returns pointer to category if found, NULL if not. */
struct ast_category *ast_category_get(const struct ast_config *config, const char *category_name);
/*! Check for category duplicates */ /*! Check for category duplicates */
/*! /*!
* \param config which config to use * \param config which config to use

View File

@@ -14,53 +14,49 @@ extern "C" {
struct ast_category { struct ast_category {
char name[80]; char name[80];
struct ast_variable *root; struct ast_variable *root;
struct ast_variable *last;
struct ast_category *next; struct ast_category *next;
}; };
struct ast_config { struct ast_config {
/* Maybe this structure isn't necessary but we'll keep it
for now */
struct ast_category *root; struct ast_category *root;
struct ast_category *prev; struct ast_category *last;
}; };
typedef struct ast_config *config_static_func(const char *database, const char *table, const char *configfile, struct ast_config *config, struct ast_category **cat, int includelevel);
struct ast_category;
struct ast_config_reg { struct ast_config_reg {
char name[CONFIG_KEYWORD_STRLEN]; char name[CONFIG_KEYWORD_STRLEN];
struct ast_config *(*static_func)(const char *database, const char *table, const char *, struct ast_config *,struct ast_category **,struct ast_variable **,int); config_static_func *static_func;
struct ast_variable *(*realtime_func)(const char *database, const char *table, va_list ap); struct ast_variable *(*realtime_func)(const char *database, const char *table, va_list ap);
struct ast_config *(*realtime_multi_func)(const char *database, const char *table, va_list ap); struct ast_config *(*realtime_multi_func)(const char *database, const char *table, va_list ap);
int (*update_func)(const char *database, const char *table, const char *keyfield, const char *entity, va_list ap); int (*update_func)(const char *database, const char *table, const char *keyfield, const char *entity, va_list ap);
struct ast_config_reg *next; struct ast_config_reg *next;
}; };
int ast_config_register(struct ast_config_reg *new); int ast_config_register(struct ast_config_reg *new);
int ast_config_deregister(struct ast_config_reg *del); int ast_config_deregister(struct ast_config_reg *del);
void ast_cust_config_on(void); void ast_cust_config_on(void);
void ast_cust_config_off(void); void ast_cust_config_off(void);
int ast_cust_config_active(void); int ast_cust_config_active(void);
void ast_config_destroy_all(void); void ast_config_destroy_all(void);
int ast_category_delete(struct ast_config *cfg, char *category);
int ast_variable_delete(struct ast_config *cfg, char *category, char *variable, char *value);
int ast_save(char *filename, struct ast_config *cfg, char *generator);
struct ast_config *ast_new_config(void);
struct ast_category *ast_new_category(char *name);
struct ast_variable *ast_new_variable(char *name,char *value);
void ast_category_append(struct ast_config *config, struct ast_category *cat);
void ast_category_destroy(struct ast_category *cat);
int ast_cust_config_register(struct ast_config_reg *new); int ast_cust_config_register(struct ast_config_reg *new);
int ast_cust_config_deregister(struct ast_config_reg *new); int ast_cust_config_deregister(struct ast_config_reg *new);
int register_config_cli(void); int register_config_cli(void);
int read_ast_cust_config(void); int read_ast_cust_config(void);
struct ast_config *ast_internal_load(const char *configfile, struct ast_config *tmp, struct ast_category **_tmpc, struct ast_variable **_last, int includelevel);
struct ast_config *ast_new_config(void);
struct ast_category *ast_new_category(char *name);
void ast_category_append(struct ast_config *config, struct ast_category *cat);
int ast_category_delete(struct ast_config *cfg, char *category);
void ast_category_destroy(struct ast_category *cat);
struct ast_variable *ast_new_variable(char *name,char *value);
int ast_variable_delete(struct ast_config *cfg, char *category, char *variable, char *value);
int ast_save(char *filename, struct ast_config *cfg, char *generator);
struct ast_config *ast_internal_load(const char *configfile, struct ast_config *tmp, struct ast_category **cat, int includelevel);
#if defined(__cplusplus) || defined(c_plusplus) #if defined(__cplusplus) || defined(c_plusplus)
} }

View File

@@ -410,7 +410,7 @@ static int update_odbc(const char *database, const char *table, const char *keyf
return -1; return -1;
} }
static struct ast_config *config_odbc (const char *database, const char *table, const char *file, struct ast_config *new_config_s, struct ast_category **new_cat_p, struct ast_variable **new_v_p, int recur) static struct ast_config *config_odbc(const char *database, const char *table, const char *file, struct ast_config *new_config_s, struct ast_category **new_cat_p, int recur)
{ {
struct ast_config *new; struct ast_config *new;
struct ast_variable *cur_v, *new_v; struct ast_variable *cur_v, *new_v;
@@ -480,7 +480,7 @@ static struct ast_config *config_odbc (const char *database, const char *table,
cat_started = 0; cat_started = 0;
cur_cat = *new_cat_p; cur_cat = *new_cat_p;
cur_v = *new_v_p; cur_v = NULL;
if (cur_cat) if (cur_cat)
cat_started = 1; cat_started = 1;
@@ -490,7 +490,7 @@ static struct ast_config *config_odbc (const char *database, const char *table,
while (res != SQL_NO_DATA) { while (res != SQL_NO_DATA) {
if (!strcmp (var_name, "#include") && recur < MAX_INCLUDE_LEVEL) { if (!strcmp (var_name, "#include") && recur < MAX_INCLUDE_LEVEL) {
config_odbc(database, table, var_val, new, &cur_cat, &cur_v, recur + 1); config_odbc(database, table, var_val, new, &cur_cat, recur + 1);
} else { } else {
if (strcmp (last, category) || last_cat_metric != cat_metric) { if (strcmp (last, category) || last_cat_metric != cat_metric) {
strncpy(last, category, sizeof(last) - 1); strncpy(last, category, sizeof(last) - 1);