Merged revisions 51057 via svnmerge from
[asterisk/asterisk.git] / main / config.c
index c52d032..4a986bd 100644 (file)
@@ -86,6 +86,8 @@ static void CB_INIT(void)
                comment_buffer[0] = 0;
                comment_buffer_size = CB_INCR;
                lline_buffer = ast_malloc(CB_INCR);
+               if (!lline_buffer)
+                       return;
                lline_buffer[0] = 0;
                lline_buffer_size = CB_INCR;
        } else {
@@ -127,7 +129,7 @@ static void  LLB_ADD(char *str)
        int siz = strlen(str);
        if (rem < siz+1) {
                lline_buffer = ast_realloc(lline_buffer, lline_buffer_size + CB_INCR + siz + 1);
-               if (!lline_buffer)
+               if (!lline_buffer) 
                        return;
                lline_buffer_size += CB_INCR + siz + 1;
        }
@@ -167,6 +169,7 @@ static struct ast_config_engine *config_engine_list;
 struct ast_category {
        char name[80];
        int ignored;                    /*!< do not let user of the config see this category */
+       int include_level;      
        struct ast_comment *precomments;
        struct ast_comment *sameline;
        struct ast_variable *root;
@@ -207,6 +210,8 @@ void ast_variable_append(struct ast_category *category, struct ast_variable *var
        else
                category->root = variable;
        category->last = variable;
+       while (category->last->next)
+               category->last = category->last->next;
 }
 
 void ast_variables_destroy(struct ast_variable *v)
@@ -337,6 +342,7 @@ void ast_category_append(struct ast_config *config, struct ast_category *categor
                config->last->next = category;
        else
                config->root = category;
+       category->include_level = config->include_level;
        config->last = category;
        config->current = category;
 }
@@ -392,6 +398,7 @@ struct ast_variable *ast_category_detach_variables(struct ast_category *cat)
 
        v = cat->root;
        cat->root = NULL;
+       cat->last = NULL;
 
        return v;
 }
@@ -418,7 +425,7 @@ struct ast_config *ast_config_new(void)
        return config;
 }
 
-int ast_variable_delete(struct ast_category *category, char *variable, char *match)
+int ast_variable_delete(struct ast_category *category, const char *variable, const char *match)
 {
        struct ast_variable *cur, *prev=NULL, *curn;
        int res = -1;
@@ -467,7 +474,7 @@ int ast_variable_delete(struct ast_category *category, char *variable, char *mat
        return res;
 }
 
-int ast_variable_update(struct ast_category *category, char *variable, char *value, char *match)
+int ast_variable_update(struct ast_category *category, const char *variable, const char *value, const char *match)
 {
        struct ast_variable *cur, *prev=NULL, *newer;
        newer = ast_variable_new(variable, value);
@@ -518,7 +525,7 @@ int ast_variable_update(struct ast_category *category, char *variable, char *val
        return 0;
 }
 
-int ast_category_delete(struct ast_config *cfg, char *category)
+int ast_category_delete(struct ast_config *cfg, const char *category)
 {
        struct ast_category *prev=NULL, *cat;
        cat = cfg->root;
@@ -793,8 +800,11 @@ static struct ast_config *config_text_file_load(const char *database, const char
 
        if (withcomments) {
                CB_INIT();
+               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;
@@ -844,7 +854,7 @@ static struct ast_config *config_text_file_load(const char *database, const char
                while(!feof(f)) {
                        lineno++;
                        if (fgets(buf, sizeof(buf), f)) {
-                               if ( withcomments ) {    
+                               if ( withcomments ) {
                                        CB_ADD(lline_buffer);       /* add the current lline buffer to the comment buffer */
                                        lline_buffer[0] = 0;        /* erase the lline buffer */
                                }
@@ -905,7 +915,7 @@ static struct ast_config *config_text_file_load(const char *database, const char
                                                        new_buf = comment_p + 1;
                                        }
                                }
-                               if( comment && !process_buf )
+                               if( withcomments && comment && !process_buf )
                                {
                                        CB_ADD(buf);  /* the whole line is a comment, store it */
                                }
@@ -934,16 +944,16 @@ static struct ast_config *config_text_file_load(const char *database, const char
                        }
                }
 #endif
-       if (withcomments) {
-               if (comment_buffer) { 
-                       free(comment_buffer);
-                       free(lline_buffer);
-                       comment_buffer=0; 
-                       lline_buffer=0; 
-                       comment_buffer_size=0; 
-                       lline_buffer_size=0;
-               }
+
+       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;
 
@@ -974,10 +984,13 @@ int config_text_file_save(const char *configfile, const struct ast_config *cfg,
        if ((f = fopen(fn, "w"))) {
 #endif     
                if (option_verbose > 1)
-                       ast_verbose(  VERBOSE_PREFIX_2 "Saving '%s': ", fn);
+                       ast_verbose(VERBOSE_PREFIX_2 "Saving '%s': ", fn);
                fprintf(f, ";!\n");
                fprintf(f, ";! Automatically generated configuration file\n");
-               fprintf(f, ";! Filename: %s (%s)\n", configfile, fn);
+               if (strcmp(configfile, fn))
+                       fprintf(f, ";! Filename: %s (%s)\n", configfile, fn);
+               else
+                       fprintf(f, ";! Filename: %s\n", configfile);
                fprintf(f, ";! Generator: %s\n", generator);
                fprintf(f, ";! Creation Date: %s", date);
                fprintf(f, ";!\n");
@@ -1027,9 +1040,9 @@ int config_text_file_save(const char *configfile, const struct ast_config *cfg,
                        ast_verbose("Saved\n");
        } else {
                if (option_debug)
-                       printf("Unable to open for writing: %s\n", fn);
+                       ast_log(LOG_DEBUG, "Unable to open for writing: %s\n", fn);
                if (option_verbose > 1)
-                       printf( "Unable to write (%s)", strerror(errno));
+                       ast_verbose(VERBOSE_PREFIX_2 "Unable to write (%s)", strerror(errno));
                return -1;
        }
        fclose(f);
@@ -1090,7 +1103,7 @@ int read_config_maps(void)
 {
        struct ast_config *config, *configtmp;
        struct ast_variable *v;
-       char *driver, *table, *database, *stringp;
+       char *driver, *table, *database, *stringp, *tmp;
 
        clear_config_maps();
 
@@ -1106,6 +1119,9 @@ int read_config_maps(void)
                stringp = v->value;
                driver = strsep(&stringp, ",");
 
+               if ((tmp = strchr(stringp, '\"')))
+                       stringp = tmp;
+
                /* check if the database text starts with a double quote */
                if (*stringp == '"') {
                        stringp++;
@@ -1301,20 +1317,58 @@ struct ast_config *ast_config_load_with_comments(const char *filename)
        return result;
 }
 
-struct ast_variable *ast_load_realtime(const char *family, ...)
+static struct ast_variable *ast_load_realtime_helper(const char *family, va_list ap)
 {
        struct ast_config_engine *eng;
        char db[256]="";
        char table[256]="";
        struct ast_variable *res=NULL;
-       va_list ap;
 
-       va_start(ap, family);
        eng = find_engine(family, db, sizeof(db), table, sizeof(table));
        if (eng && eng->realtime_func) 
                res = eng->realtime_func(db, table, ap);
+
+       return res;
+}
+
+struct ast_variable *ast_load_realtime_all(const char *family, ...)
+{
+       struct ast_variable *res;
+       va_list ap;
+
+       va_start(ap, family);
+       res = ast_load_realtime_helper(family, ap);
+       va_end(ap);
+
+       return res;
+}
+
+struct ast_variable *ast_load_realtime(const char *family, ...)
+{
+       struct ast_variable *res, *cur, *prev = NULL, *freeme = NULL;
+       va_list ap;
+
+       va_start(ap, family);
+       res = ast_load_realtime_helper(family, ap);
        va_end(ap);
 
+       /* Eliminate blank entries */
+       for (cur = res; cur; cur = cur->next) {
+               if (freeme) {
+                       free(freeme);
+                       freeme = NULL;
+               }
+
+               if (ast_strlen_zero(cur->value)) {
+                       if (prev)
+                               prev->next = cur->next;
+                       else
+                               res = cur->next;
+                       freeme = cur;
+               } else {
+                       prev = cur;
+               }
+       }
        return res;
 }
 
@@ -1388,11 +1442,11 @@ static int config_command(int fd, int argc, char **argv)
 }
 
 static char show_config_help[] =
-       "Usage: core list config mappings\n"
+       "Usage: core show config mappings\n"
        "       Shows the filenames to config engines.\n";
 
 static struct ast_cli_entry cli_config[] = {
-       { { "core", "list", "config", "mappings", NULL },
+       { { "core", "show", "config", "mappings", NULL },
        config_command, "Display config mappings (file names to config engines)",
        show_config_help },
 };