Don't reload a configuration file if nothing has changed.
authorTilghman Lesher <tilghman@meg.abyt.es>
Thu, 16 Aug 2007 21:09:46 +0000 (21:09 +0000)
committerTilghman Lesher <tilghman@meg.abyt.es>
Thu, 16 Aug 2007 21:09:46 +0000 (21:09 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@79747 65c4cc65-6c06-0410-ace0-fbb531ad65f3

75 files changed:
apps/app_alarmreceiver.c
apps/app_amd.c
apps/app_directory.c
apps/app_festival.c
apps/app_followme.c
apps/app_meetme.c
apps/app_minivm.c
apps/app_osplookup.c
apps/app_playback.c
apps/app_privacy.c
apps/app_queue.c
apps/app_rpt.c
apps/app_voicemail.c
cdr/cdr_adaptive_odbc.c
cdr/cdr_csv.c
cdr/cdr_custom.c
cdr/cdr_manager.c
cdr/cdr_odbc.c
cdr/cdr_pgsql.c
cdr/cdr_radius.c
cdr/cdr_sqlite3_custom.c
cdr/cdr_tds.c
channels/chan_agent.c
channels/chan_alsa.c
channels/chan_gtalk.c
channels/chan_h323.c
channels/chan_iax2.c
channels/chan_jingle.c
channels/chan_mgcp.c
channels/chan_misdn.c
channels/chan_oss.c
channels/chan_phone.c
channels/chan_sip.c
channels/chan_skinny.c
channels/chan_vpb.cc
channels/chan_zap.c
channels/iax2-provision.c
channels/iax2-provision.h
channels/misdn/chan_misdn_config.h
channels/misdn_config.c
codecs/codec_adpcm.c
codecs/codec_alaw.c
codecs/codec_g722.c
codecs/codec_g726.c
codecs/codec_gsm.c
codecs/codec_lpc10.c
codecs/codec_speex.c
codecs/codec_ulaw.c
codecs/codec_zap.c
funcs/func_odbc.c
include/asterisk/config.h
main/asterisk.c
main/cdr.c
main/config.c
main/dnsmgr.c
main/enum.c
main/http.c
main/loader.c
main/logger.c
main/manager.c
main/rtp.c
main/udptl.c
pbx/pbx_config.c
pbx/pbx_dundi.c
res/res_adsi.c
res/res_config_odbc.c
res/res_config_pgsql.c
res/res_config_sqlite.c
res/res_features.c
res/res_indications.c
res/res_jabber.c
res/res_musiconhold.c
res/res_odbc.c
res/res_smdi.c
res/res_snmp.c

index b48c8db..194a332 100644 (file)
@@ -714,10 +714,11 @@ static int load_config(void)
 {
        struct ast_config *cfg;
        const char *p;
+       struct ast_flags config_flags = { 0 };
 
        /* Read in the config file */
 
-       cfg = ast_config_load(ALMRCV_CONFIG);
+       cfg = ast_config_load(ALMRCV_CONFIG, config_flags);
                                                                                                                                   
        if(!cfg){
        
index 2d88dd8..dea61ff 100644 (file)
@@ -317,16 +317,18 @@ static int amd_exec(struct ast_channel *chan, void *data)
        return 0;
 }
 
-static void load_config(void)
+static void load_config(int reload)
 {
        struct ast_config *cfg = NULL;
        char *cat = NULL;
        struct ast_variable *var = NULL;
+       struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
 
-       if (!(cfg = ast_config_load("amd.conf"))) {
+       if (!(cfg = ast_config_load("amd.conf", config_flags))) {
                ast_log(LOG_ERROR, "Configuration file amd.conf missing.\n");
                return;
-       }
+       } else if (cfg == CONFIG_STATUS_FILEUNCHANGED)
+               return;
 
        cat = ast_category_browse(cfg, NULL);
 
@@ -377,13 +379,13 @@ static int unload_module(void)
 
 static int load_module(void)
 {
-       load_config();
+       load_config(0);
        return ast_register_application(app, amd_exec, synopsis, descrip);
 }
 
 static int reload(void)
 {
-       load_config();
+       load_config(1);
        return 0;
 }
 
index 4564014..896f9cb 100644 (file)
@@ -364,9 +364,10 @@ static struct ast_config *realtime_directory(char *context)
        const char *fullname;
        const char *hidefromdir;
        char tmp[100];
+       struct ast_flags config_flags = { 0 };
 
        /* Load flat file config. */
-       cfg = ast_config_load(VOICEMAIL_CONFIG);
+       cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags);
 
        if (!cfg) {
                /* Loading config failed. */
@@ -597,6 +598,7 @@ static int directory_exec(struct ast_channel *chan, void *data)
        int fromappvm = 0;
        const char *dirintro;
        char *parse;
+       struct ast_flags config_flags = { 0 };
        AST_DECLARE_APP_ARGS(args,
                AST_APP_ARG(vmcontext);
                AST_APP_ARG(dialcontext);
@@ -630,7 +632,7 @@ static int directory_exec(struct ast_channel *chan, void *data)
                return -1;
        }
        
-       ucfg = ast_config_load("users.conf");
+       ucfg = ast_config_load("users.conf", config_flags);
 
        dirintro = ast_variable_retrieve(cfg, args.vmcontext, "directoryintro");
        if (ast_strlen_zero(dirintro))
@@ -674,7 +676,8 @@ static int unload_module(void)
 static int load_module(void)
 {
 #ifdef ODBC_STORAGE
-       struct ast_config *cfg = ast_config_load(VOICEMAIL_CONFIG);
+       struct ast_flags config_flags = { 0 };
+       struct ast_config *cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags);
        const char *tmp;
 
        if (cfg) {
index 60950ad..b6097be 100644 (file)
@@ -306,6 +306,7 @@ static int festival_exec(struct ast_channel *chan, void *vdata)
        char *data;     
        struct ast_config *cfg;
        char *newfestivalcommand;
+       struct ast_flags config_flags = { 0 };
        AST_DECLARE_APP_ARGS(args,
                AST_APP_ARG(text);
                AST_APP_ARG(interrupt);
@@ -316,7 +317,7 @@ static int festival_exec(struct ast_channel *chan, void *vdata)
                return -1;
        }
 
-       cfg = ast_config_load(FESTIVAL_CONFIG);
+       cfg = ast_config_load(FESTIVAL_CONFIG, config_flags);
        if (!cfg) {
                ast_log(LOG_WARNING, "No such configuration file %s\n", FESTIVAL_CONFIG);
                return -1;
@@ -520,7 +521,8 @@ static int unload_module(void)
 
 static int load_module(void)
 {
-       struct ast_config *cfg = ast_config_load(FESTIVAL_CONFIG);
+       struct ast_flags config_flags = { 0 };
+       struct ast_config *cfg = ast_config_load(FESTIVAL_CONFIG, config_flags);
        if (!cfg) {
                ast_log(LOG_WARNING, "No such configuration file %s\n", FESTIVAL_CONFIG);
                return AST_MODULE_LOAD_DECLINE;
index f81472e..1a697e5 100644 (file)
@@ -275,7 +275,7 @@ static struct number *create_followme_number(char *number, int timeout, int numo
 }
 
 /*! \brief Reload followme application module */
-static int reload_followme(void)
+static int reload_followme(int reload)
 {
        struct call_followme *f;
        struct ast_config *cfg;
@@ -289,11 +289,13 @@ static int reload_followme(void)
        const char *takecallstr;
        const char *declinecallstr;
        const char *tmpstr;
+       struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
 
-       if (!(cfg = ast_config_load("followme.conf"))) {
+       if (!(cfg = ast_config_load("followme.conf", config_flags))) {
                ast_log(LOG_WARNING, "No follow me config file (followme.conf), so no follow me\n");
                return 0;
-       }
+       } else if (cfg == CONFIG_STATUS_FILEUNCHANGED)
+               return 0;
 
        AST_RWLIST_WRLOCK(&followmes);
 
@@ -1051,7 +1053,7 @@ static int unload_module(void)
 
 static int load_module(void)
 {
-       if(!reload_followme())
+       if(!reload_followme(0))
                return AST_MODULE_LOAD_DECLINE;
 
        return ast_register_application(app, app_exec, synopsis, descrip);
@@ -1059,7 +1061,7 @@ static int load_module(void)
 
 static int reload(void)
 {
-       reload_followme();
+       reload_followme(1);
 
        return 0;       
 }
index 5a07453..e4f487a 100644 (file)
@@ -2407,6 +2407,7 @@ static struct ast_conference *find_conf(struct ast_channel *chan, char *confno,
 {
        struct ast_config *cfg;
        struct ast_variable *var;
+       struct ast_flags config_flags = { 0 };
        struct ast_conference *cnf;
        char *parse;
        AST_DECLARE_APP_ARGS(args,
@@ -2444,7 +2445,7 @@ static struct ast_conference *find_conf(struct ast_channel *chan, char *confno,
                        }
                } else {
                        /* Check the config */
-                       cfg = ast_config_load(CONFIG_FILE_NAME);
+                       cfg = ast_config_load(CONFIG_FILE_NAME, config_flags);
                        if (!cfg) {
                                ast_log(LOG_WARNING, "No %s file :(\n", CONFIG_FILE_NAME);
                                return NULL;
@@ -2551,7 +2552,7 @@ static int conf_exec(struct ast_channel *chan, void *data)
        int allowretry = 0;
        int retrycnt = 0;
        struct ast_conference *cnf = NULL;
-       struct ast_flags confflags = {0};
+       struct ast_flags confflags = {0}, config_flags = { 0 };
        int dynamic = 0;
        int empty = 0, empty_no_pin = 0;
        int always_prompt = 0;
@@ -2609,7 +2610,7 @@ static int conf_exec(struct ast_channel *chan, void *data)
 
                        /* We only need to load the config file for static and empty_no_pin (otherwise we don't care) */
                        if ((empty_no_pin) || (!dynamic)) {
-                               cfg = ast_config_load(CONFIG_FILE_NAME);
+                               cfg = ast_config_load(CONFIG_FILE_NAME, config_flags);
                                if (cfg) {
                                        var = ast_variable_browse(cfg, "rooms");
                                        while (var) {
@@ -3174,11 +3175,12 @@ static enum ast_device_state meetmestate(const char *data)
 static void load_config_meetme(void)
 {
        struct ast_config *cfg;
+       struct ast_flags config_flags = { 0 };
        const char *val;
 
        audio_buffers = DEFAULT_AUDIO_BUFFERS;
 
-       if (!(cfg = ast_config_load(CONFIG_FILE_NAME)))
+       if (!(cfg = ast_config_load(CONFIG_FILE_NAME, config_flags)))
                return;
 
        if ((val = ast_variable_retrieve(cfg, "general", "audiobuffers"))) {
@@ -4894,6 +4896,7 @@ static int sla_build_station(struct ast_config *cfg, const char *cat)
 static int sla_load_config(int reload)
 {
        struct ast_config *cfg;
+       struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
        const char *cat = NULL;
        int res = 0;
        const char *val;
@@ -4903,8 +4906,10 @@ static int sla_load_config(int reload)
                ast_cond_init(&sla.cond, NULL);
        }
 
-       if (!(cfg = ast_config_load(SLA_CONFIG_FILE)))
+       if (!(cfg = ast_config_load(SLA_CONFIG_FILE, config_flags)))
                return 0; /* Treat no config as normal */
+       else if (cfg == CONFIG_STATUS_FILEUNCHANGED)
+               return 0;
 
        if ((val = ast_variable_retrieve(cfg, "general", "attemptcallerid")))
                sla.attempt_callerid = ast_true(val);
index a868bac..1841e52 100644 (file)
@@ -2349,7 +2349,7 @@ static int apply_general_options(struct ast_variable *var)
 }
 
 /*! \brief Load minivoicemail configuration */
-static int load_config(void)
+static int load_config(int reload)
 {
        struct ast_config *cfg;
        struct ast_variable *var;
@@ -2357,8 +2357,12 @@ static int load_config(void)
        const char *chanvar;
        int error = 0;
        struct minivm_template *template;
+       struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
+
+       cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags);
+       if (cfg == CONFIG_STATUS_FILEUNCHANGED)
+               return 0;
 
-       cfg = ast_config_load(VOICEMAIL_CONFIG);
        ast_mutex_lock(&minivmlock);
 
        /* Destroy lists to reconfigure */
@@ -3039,7 +3043,7 @@ static int load_module(void)
        if (res)
                return(res);
 
-       if ((res = load_config()))
+       if ((res = load_config(0)))
                return(res);
 
        ast_cli_register_multiple(cli_minivm, sizeof(cli_minivm)/sizeof(cli_minivm[0]));
@@ -3053,7 +3057,7 @@ static int load_module(void)
 /*! \brief Reload mini voicemail module */
 static int reload(void)
 {
-       return(load_config());
+       return(load_config(1));
 }
 
 /*! \brief Reload cofiguration */
index 3e7f9b2..25b3fb5 100644 (file)
@@ -1773,15 +1773,22 @@ static int ospfinished_exec(
 
 /* OSP Module APIs */
 
-static int osp_load(void)
+static int osp_unload(void);
+static int osp_load(int reload)
 {
        const char* t;
        unsigned int v;
        struct ast_config* cfg;
+       struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
        int error = OSPC_ERR_NO_ERROR;
 
-       cfg = ast_config_load(OSP_CONFIG_FILE);
+       if ((cfg = ast_config_load(OSP_CONFIG_FILE, config_flags)) == CONFIG_STATUS_FILEUNCHANGED)
+               return 0;
+
        if (cfg) {
+               if (reload)
+                       osp_unload();
+
                t = ast_variable_retrieve(cfg, OSP_GENERAL_CAT, "accelerate");
                if (t && ast_true(t)) {
                        if ((error = OSPPInit(1)) != OSPC_ERR_NO_ERROR) {
@@ -2000,7 +2007,7 @@ static int load_module(void)
 {
        int res;
 
-       if(!osp_load())
+       if (!osp_load(0))
                return AST_MODULE_LOAD_DECLINE;
 
        ast_cli_register_multiple(cli_osp, sizeof(cli_osp) / sizeof(struct ast_cli_entry));
@@ -2028,8 +2035,7 @@ static int unload_module(void)
 
 static int reload(void)
 {
-       osp_unload();
-       osp_load();
+       osp_load(1);
 
        return 0;
 }
index d39d25c..db9e0e1 100644 (file)
@@ -470,12 +470,17 @@ done:
 static int reload(void)
 {
        struct ast_variable *v;
+       struct ast_flags config_flags = { CONFIG_FLAG_FILEUNCHANGED };
+       struct ast_config *newcfg;
+
+       if ((newcfg = ast_config_load("say.conf", config_flags)) == CONFIG_STATUS_FILEUNCHANGED)
+               return 0;
 
        if (say_cfg) {
                ast_config_destroy(say_cfg);
                ast_log(LOG_NOTICE, "Reloading say.conf\n");
+               say_cfg = newcfg;
        }
-       say_cfg = ast_config_load("say.conf");
 
        if (say_cfg) {
                for (v = ast_variable_browse(say_cfg, "general"); v ; v = v->next) {
@@ -510,8 +515,9 @@ static int unload_module(void)
 static int load_module(void)
 {
        struct ast_variable *v;
+       struct ast_flags config_flags = { 0 };
 
-       say_cfg = ast_config_load("say.conf");
+       say_cfg = ast_config_load("say.conf", config_flags);
        if (say_cfg) {
                for (v = ast_variable_browse(say_cfg, "general"); v ; v = v->next) {
                        if (ast_extension_match(v->name, "mode")) {
index cf3d637..e470b9e 100644 (file)
@@ -83,6 +83,7 @@ static int privacy_exec (struct ast_channel *chan, void *data)
        char phone[30];
        struct ast_config *cfg = NULL;
        char *parse = NULL;
+       struct ast_flags config_flags = { 0 };
        AST_DECLARE_APP_ARGS(args,
                AST_APP_ARG(maxretries);
                AST_APP_ARG(minlength);
@@ -122,7 +123,7 @@ static int privacy_exec (struct ast_channel *chan, void *data)
                if (!x)
                {
                        /*Read in the config file*/
-                       cfg = ast_config_load(PRIV_CONFIG);
+                       cfg = ast_config_load(PRIV_CONFIG, config_flags);
                
                        if (cfg && (s = ast_variable_retrieve(cfg, "general", "maxretries"))) {
                                if (sscanf(s, "%d", &x) == 1) 
index d571dc3..1908454 100644 (file)
@@ -3947,7 +3947,7 @@ static struct ast_custom_function queuememberlist_function = {
        .read = queue_function_queuememberlist,
 };
 
-static int reload_queues(void)
+static int reload_queues(int reload)
 {
        struct call_queue *q;
        struct ast_config *cfg;
@@ -3960,16 +3960,18 @@ static int reload_queues(void)
        char *interface;
        char *membername;
        int penalty;
+       struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
        AST_DECLARE_APP_ARGS(args,
                AST_APP_ARG(interface);
                AST_APP_ARG(penalty);
                AST_APP_ARG(membername);
        );
        
-       if (!(cfg = ast_config_load("queues.conf"))) {
+       if (!(cfg = ast_config_load("queues.conf", config_flags))) {
                ast_log(LOG_NOTICE, "No call queueing config file (queues.conf), so no call queues\n");
                return 0;
-       }
+       } else if (cfg == CONFIG_STATUS_FILEUNCHANGED)
+               return 0;
        AST_LIST_LOCK(&queues);
        use_weight=0;
        /* Mark all queues as dead for the moment */
@@ -4766,7 +4768,7 @@ static int load_module(void)
        int res;
        struct ast_context *con;
 
-       if (!reload_queues())
+       if (!reload_queues(0))
                return AST_MODULE_LOAD_DECLINE;
 
        con = ast_context_find("app_queue_gosub_virtual_context");
@@ -4810,7 +4812,7 @@ static int load_module(void)
 
 static int reload(void)
 {
-       reload_queues();
+       reload_queues(1);
        return 0;
 }
 
index ad38de1..77e4ee4 100644 (file)
@@ -918,6 +918,7 @@ static void load_rpt_vars(int n, int init)
        int     j;
        struct ast_variable *vp, *var;
        struct ast_config *cfg;
+       struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE };
 #ifdef __RPT_NOTCH
        AST_DECLARE_APP_ARGS(strs,
                AST_APP_ARG(str)[100];
@@ -929,7 +930,7 @@ static void load_rpt_vars(int n, int init)
        ast_mutex_lock(&rpt_vars[n].lock);
        if (rpt_vars[n].cfg)
                ast_config_destroy(rpt_vars[n].cfg);
-       cfg = ast_config_load("rpt.conf");
+       cfg = ast_config_load("rpt.conf", config_flags);
        if (!cfg) {
                ast_mutex_unlock(&rpt_vars[n].lock);
                ast_log(LOG_NOTICE, "Unable to open radio repeater configuration rpt.conf.  Radio Repeater disabled.\n");
@@ -7437,7 +7438,8 @@ static int unload_module(void)
 
 static int load_module(void)
 {
-       struct ast_config *cfg = ast_config_load("rpt.conf");
+       struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE };
+       struct ast_config *cfg = ast_config_load("rpt.conf", config_flags);
        if (!cfg) {
                ast_log(LOG_WARNING, "No such configuration file rpt.conf\n");
                return AST_MODULE_LOAD_DECLINE;
index c2e8afd..752d2a8 100644 (file)
@@ -260,7 +260,7 @@ AST_APP_OPTIONS(vm_app_options, {
        AST_APP_OPTION_ARG('a', OPT_AUTOPLAY, OPT_ARG_PLAYFOLDER),
 });
 
-static int load_config(void);
+static int load_config(int reload);
 
 /*! \page vmlang Voicemail Language Syntaxes Supported
 
@@ -911,12 +911,13 @@ static void vm_change_password(struct ast_vm_user *vmu, const char *newpassword)
        struct ast_category *cat=NULL;
        char *category=NULL, *value=NULL, *new=NULL;
        const char *tmp=NULL;
+       struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS };
                                        
        if (!change_password_realtime(vmu, newpassword))
                return;
 
        /* check voicemail.conf */
-       if ((cfg = ast_config_load_with_comments(VOICEMAIL_CONFIG))) {
+       if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags))) {
                while ((category = ast_category_browse(cfg, category))) {
                        if (!strcasecmp(category, vmu->context)) {
                                if (!(tmp = ast_variable_retrieve(cfg, category, vmu->mailbox))) {
@@ -946,7 +947,7 @@ static void vm_change_password(struct ast_vm_user *vmu, const char *newpassword)
        var = NULL;
        /* check users.conf and update the password stored for the mailbox*/
        /* if no vmsecret entry exists create one. */
-       if ((cfg = ast_config_load_with_comments("users.conf"))) {
+       if ((cfg = ast_config_load("users.conf", config_flags))) {
                ast_debug(4, "we are looking for %s\n", vmu->mailbox);
                while ((category = ast_category_browse(cfg, category))) {
                        ast_debug(4, "users.conf: %s\n", category);
@@ -1427,6 +1428,7 @@ static int store_file(char *dir, char *mailboxuser, char *mailboxcontext, int ms
        const char *category = "";
        struct ast_config *cfg=NULL;
        struct odbc_obj *obj;
+       struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE };
 
        delete_file(dir, msgnum);
        obj = ast_odbc_request_obj(odbc_database, 0);
@@ -1443,7 +1445,7 @@ static int store_file(char *dir, char *mailboxuser, char *mailboxcontext, int ms
                else
                        ast_copy_string(fn, dir, sizeof(fn));
                snprintf(full_fn, sizeof(full_fn), "%s.txt", fn);
-               cfg = ast_config_load(full_fn);
+               cfg = ast_config_load(full_fn, config_flags);
                snprintf(full_fn, sizeof(full_fn), "%s.%s", fn, fmt);
                fd = open(full_fn, O_RDWR);
                if (fd < 0) {
@@ -3975,6 +3977,7 @@ static int vm_forwardoptions(struct ast_channel *chan, struct ast_vm_user *vmu,
        int cmd = 0;
        int retries = 0;
        signed char zero_gain = 0;
+       struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE };
 
        while ((cmd >= 0) && (cmd != 't') && (cmd != '*')) {
                if (cmd)
@@ -3995,7 +3998,7 @@ static int vm_forwardoptions(struct ast_channel *chan, struct ast_vm_user *vmu,
                        *duration = 0;
 
                        /* if we can't read the message metadata, stop now */
-                       if (!(msg_cfg = ast_config_load(textfile))) {
+                       if (!(msg_cfg = ast_config_load(textfile, config_flags))) {
                                cmd = 0;
                                break;
                        }
@@ -4733,6 +4736,7 @@ static int play_message(struct ast_channel *chan, struct ast_vm_user *vmu, struc
        char filename[256], *cid;
        const char *origtime, *context, *category, *duration;
        struct ast_config *msg_cfg;
+       struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE };
 
        vms->starting = 0; 
        make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg);
@@ -4782,7 +4786,7 @@ static int play_message(struct ast_channel *chan, struct ast_vm_user *vmu, struc
        make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg);
        snprintf(filename, sizeof(filename), "%s.txt", vms->fn2);
        RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context);
-       msg_cfg = ast_config_load(filename);
+       msg_cfg = ast_config_load(filename, config_flags);
        if (!msg_cfg) {
                ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename);
                return 0;
@@ -7850,7 +7854,7 @@ static int manager_list_voicemail_users(struct mansession *s, const struct messa
        return RESULT_SUCCESS;
 }
 
-static int load_config(void)
+static int load_config(int reload)
 {
        struct ast_vm_user *cur;
        struct vm_zone *zcur;
@@ -7863,6 +7867,17 @@ static int load_config(void)
        char *q, *stringp;
        int x;
        int tmpadsi[4];
+       struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
+
+       if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) == CONFIG_STATUS_FILEUNCHANGED) {
+               if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEUNCHANGED)
+                       return 0;
+               ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
+               cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags);
+       } else {
+               ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
+               ucfg = ast_config_load("users.conf", config_flags);
+       }
 
        /* set audio control prompts */
        strcpy(listen_control_forward_key,DEFAULT_LISTEN_CONTROL_FORWARD_KEY);
@@ -7871,8 +7886,6 @@ static int load_config(void)
        strcpy(listen_control_restart_key,DEFAULT_LISTEN_CONTROL_RESTART_KEY);
        strcpy(listen_control_stop_key,DEFAULT_LISTEN_CONTROL_STOP_KEY);
        
-       cfg = ast_config_load(VOICEMAIL_CONFIG);
-
        AST_LIST_LOCK(&users);
        while ((cur = AST_LIST_REMOVE_HEAD(&users, list))) {
                ast_set_flag(cur, VM_ALLOCED);
@@ -8259,7 +8272,7 @@ static int load_config(void)
                if ((val = ast_variable_retrieve(cfg, "general", "pollmailboxes")))
                        poll_mailboxes = ast_true(val);
 
-               if ((ucfg = ast_config_load("users.conf"))) {   
+               if (ucfg) {     
                        for (cat = ast_category_browse(ucfg, NULL); cat ; cat = ast_category_browse(ucfg, cat)) {
                                if (!ast_true(ast_config_option(ucfg, cat, "hasvoicemail")))
                                        continue;
@@ -8427,13 +8440,15 @@ static int load_config(void)
        } else {
                AST_LIST_UNLOCK(&users);
                ast_log(LOG_WARNING, "Failed to load configuration file.\n");
+               if (ucfg)
+                       ast_config_destroy(ucfg);
                return 0;
        }
 }
 
 static int reload(void)
 {
-       return load_config();
+       return load_config(1);
 }
 
 static int unload_module(void)
@@ -8464,7 +8479,7 @@ static int load_module(void)
        /* compute the location of the voicemail spool directory */
        snprintf(VM_SPOOL_DIR, sizeof(VM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR);
 
-       if ((res = load_config()))
+       if ((res = load_config(0)))
                return res;
 
        res = ast_register_application(app, vm_exec, synopsis_vm, descrip_vm);
@@ -8555,6 +8570,7 @@ static int advanced_options(struct ast_channel *chan, struct ast_vm_user *vmu, s
        const char *origtime, *context;
        char *cid, *name, *num;
        int retries = 0;
+       struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE };
 
        vms->starting = 0; 
 #ifdef IMAP_STORAGE
@@ -8605,7 +8621,7 @@ static int advanced_options(struct ast_channel *chan, struct ast_vm_user *vmu, s
        make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg);
        snprintf(filename,sizeof(filename), "%s.txt", vms->fn2);
        RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context);
-       msg_cfg = ast_config_load(filename);
+       msg_cfg = ast_config_load(filename, config_flags);
        DISPOSE(vms->curdir, vms->curmsg);
        if (!msg_cfg) {
                ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename);
index f97f5ed..66f704d 100644 (file)
@@ -95,8 +95,9 @@ static int load_config(void)
        SQLLEN sqlptr;
        int res = 0;
        SQLHSTMT stmt = NULL;
+       struct ast_flags config_flags = { 0 }; /* Part of our config comes from the database */
 
-       cfg = ast_config_load(CONFIG);
+       cfg = ast_config_load(CONFIG, config_flags);
        if (!cfg) {
                ast_log(LOG_WARNING, "Unable to load " CONFIG ".  No adaptive ODBC CDRs.\n");
                return -1;
index bfc5098..8ae8b3c 100644 (file)
@@ -95,22 +95,24 @@ static char *name = "csv";
 static FILE *mf = NULL;
 
 
-static int load_config(void)
+static int load_config(int reload)
 {
        struct ast_config *cfg;
        struct ast_variable *var;
        const char *tmp;
+       struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
 
        usegmtime = 0;
        loguniqueid = 0;
        loguserfield = 0;
        
-       cfg = ast_config_load(config);
+       cfg = ast_config_load(config, config_flags);
        
        if (!cfg) {
                ast_log(LOG_WARNING, "unable to load config: %s\n", config);
                return 0;
-       } 
+       } else if (cfg == CONFIG_STATUS_FILEUNCHANGED)
+               return 0;
        
        var = ast_variable_browse(cfg, "csv");
        if (!var) {
@@ -316,7 +318,7 @@ static int load_module(void)
 {
        int res;
        
-       if(!load_config())
+       if(!load_config(0))
                return AST_MODULE_LOAD_DECLINE;
 
        res = ast_cdr_register(name, ast_module_info->description, csv_log);
@@ -330,7 +332,7 @@ static int load_module(void)
 
 static int reload(void)
 {
-       load_config();
+       load_config(1);
 
        return 0;
 }
index 80cd47e..fa4eb11 100644 (file)
@@ -68,12 +68,16 @@ static int load_config(int reload)
 {
        struct ast_config *cfg;
        struct ast_variable *var;
+       struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
        int res = -1;
 
+       if ((cfg = ast_config_load("cdr_custom.conf", config_flags)) == CONFIG_STATUS_FILEUNCHANGED)
+               return 0;
+
        strcpy(format, "");
        strcpy(master, "");
        ast_mutex_lock(&lock);
-       if((cfg = ast_config_load("cdr_custom.conf"))) {
+       if (cfg) {
                var = ast_variable_browse(cfg, "mappings");
                while(var) {
                        if (!ast_strlen_zero(var->name) && !ast_strlen_zero(var->value)) {
index 5dc4da6..028b4a8 100644 (file)
@@ -52,15 +52,22 @@ static char *name = "cdr_manager";
 static int enablecdr = 0;
 struct ast_str *customfields;
 
-static int load_config(void)
+static int load_config(int reload)
 {
        char *cat = NULL;
        struct ast_config *cfg;
        struct ast_variable *v;
-       
+       struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
+
+       cfg = ast_config_load(CONF_FILE, config_flags);
+       if (cfg == CONFIG_STATUS_FILEUNCHANGED)
+               return 0;
+
+       if (reload && customfields) {
+               ast_free(customfields);
+       }
        customfields = NULL;
 
-       cfg = ast_config_load(CONF_FILE);
        if (!cfg) {
                /* Standard configuration */
                ast_log(LOG_WARNING, "Failed to load configuration file. Module not activated.\n");
@@ -174,7 +181,7 @@ static int load_module(void)
        int res;
 
        /* Configuration file */
-       if (!load_config())
+       if (!load_config(0))
                return AST_MODULE_LOAD_DECLINE;
        
        res = ast_cdr_register(name, "Asterisk Manager Interface CDR Backend", manager_log);
@@ -187,12 +194,7 @@ static int load_module(void)
 
 static int reload(void)
 {
-       if (customfields) {
-               ast_free(customfields);
-       }
-       
-       load_config();
-       return 0;
+       return load_config(1);
 }
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Asterisk Manager Interface CDR Backend",
index 1ba24f5..19acbe3 100644 (file)
@@ -226,124 +226,124 @@ static int odbc_unload_module(void)
        return 0;
 }
 
-static int odbc_load_module(void)
+static int odbc_load_module(int reload)
 {
        int res = 0;
        struct ast_config *cfg;
        struct ast_variable *var;
        const char *tmp;
+       struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
 
        ast_mutex_lock(&odbc_lock);
 
-       cfg = ast_config_load(config);
-       if (!cfg) {
-               ast_log(LOG_WARNING, "cdr_odbc: Unable to load config for ODBC CDR's: %s\n", config);
-               res = AST_MODULE_LOAD_DECLINE;
-               goto out;
-       }
+       do {
+               cfg = ast_config_load(config, config_flags);
+               if (!cfg) {
+                       ast_log(LOG_WARNING, "cdr_odbc: Unable to load config for ODBC CDR's: %s\n", config);
+                       res = AST_MODULE_LOAD_DECLINE;
+                       break;
+               } else if (cfg == CONFIG_STATUS_FILEUNCHANGED)
+                       break;
        
-       var = ast_variable_browse(cfg, "global");
-       if (!var) {
-               /* nothing configured */
-               goto out;
-       }
-
-       tmp = ast_variable_retrieve(cfg,"global","dsn");
-       if (tmp == NULL) {
-               ast_log(LOG_WARNING,"cdr_odbc: dsn not specified.  Assuming asteriskdb\n");
-               tmp = "asteriskdb";
-       }
-       dsn = strdup(tmp);
-       if (dsn == NULL) {
-               ast_log(LOG_ERROR,"cdr_odbc: Out of memory error.\n");
-               res = -1;
-               goto out;
-       }
+               var = ast_variable_browse(cfg, "global");
+               if (!var) {
+                       /* nothing configured */
+                       break;
+               }
 
-       tmp = ast_variable_retrieve(cfg,"global","dispositionstring");
-       if (tmp) {
-               dispositionstring = ast_true(tmp);
-       } else {
-               dispositionstring = 0;
-       }
-               
-       tmp = ast_variable_retrieve(cfg,"global","username");
-       if (tmp) {
-               username = strdup(tmp);
-               if (username == NULL) {
-                       ast_log(LOG_ERROR,"cdr_odbc: Out of memory error.\n");
+               if ((tmp = ast_variable_retrieve(cfg, "global", "dsn")) == NULL) {
+                       ast_log(LOG_WARNING, "cdr_odbc: dsn not specified.  Assuming asteriskdb\n");
+                       tmp = "asteriskdb";
+               }
+               if (dsn)
+                       ast_free(dsn);
+               dsn = ast_strdup(tmp);
+               if (dsn == NULL) {
                        res = -1;
-                       goto out;
+                       break;
                }
-       }
 
-       tmp = ast_variable_retrieve(cfg,"global","password");
-       if (tmp) {
-               password = strdup(tmp);
-               if (password == NULL) {
-                       ast_log(LOG_ERROR,"cdr_odbc: Out of memory error.\n");
-                       res = -1;
-                       goto out;
+               if ((tmp = ast_variable_retrieve(cfg, "global", "dispositionstring")))
+                       dispositionstring = ast_true(tmp);
+               else
+                       dispositionstring = 0;
+
+               if ((tmp = ast_variable_retrieve(cfg, "global", "username"))) {
+                       if (username)
+                               ast_free(username);
+                       username = ast_strdup(tmp);
+                       if (username == NULL) {
+                               res = -1;
+                               break;
+                       }
                }
-       }
 
-       tmp = ast_variable_retrieve(cfg,"global","loguniqueid");
-       if (tmp) {
-               loguniqueid = ast_true(tmp);
-               if (loguniqueid) {
-                       ast_debug(1,"cdr_odbc: Logging uniqueid\n");
+               if ((tmp = ast_variable_retrieve(cfg, "global", "password"))) {
+                       if (password)
+                               ast_free(password);
+                       password = ast_strdup(tmp);
+                       if (password == NULL) {
+                               res = -1;
+                               break;
+                       }
+               }
+
+               if ((tmp = ast_variable_retrieve(cfg, "global", "loguniqueid"))) {
+                       loguniqueid = ast_true(tmp);
+                       if (loguniqueid) {
+                               ast_debug(1, "cdr_odbc: Logging uniqueid\n");
+                       } else {
+                               ast_debug(1, "cdr_odbc: Not logging uniqueid\n");
+                       }
                } else {
-                       ast_debug(1,"cdr_odbc: Not logging uniqueid\n");
+                       ast_debug(1, "cdr_odbc: Not logging uniqueid\n");
+                       loguniqueid = 0;
                }
-       } else {
-               ast_debug(1,"cdr_odbc: Not logging uniqueid\n");
-               loguniqueid = 0;
-       }
 
-       tmp = ast_variable_retrieve(cfg,"global","usegmtime");
-       if (tmp) {
-               usegmtime = ast_true(tmp);
-               if (usegmtime) {
-                       ast_debug(1,"cdr_odbc: Logging in GMT\n");
+               if ((tmp = ast_variable_retrieve(cfg, "global", "usegmtime"))) {
+                       usegmtime = ast_true(tmp);
+                       if (usegmtime) {
+                               ast_debug(1, "cdr_odbc: Logging in GMT\n");
+                       } else {
+                               ast_debug(1, "cdr_odbc: Not logging in GMT\n");
+                       }
                } else {
-                       ast_debug(1,"cdr_odbc: Not logging in GMT\n");
+                       ast_debug(1, "cdr_odbc: Not logging in GMT\n");
+                       usegmtime = 0;
                }
-       } else {
-               ast_debug(1,"cdr_odbc: Not logging in GMT\n");
-               usegmtime = 0;
-       }
 
-       tmp = ast_variable_retrieve(cfg,"global","table");
-       if (tmp == NULL) {
-               ast_log(LOG_WARNING,"cdr_odbc: table not specified.  Assuming cdr\n");
-               tmp = "cdr";
-       }
-       table = strdup(tmp);
-       if (table == NULL) {
-               ast_log(LOG_ERROR,"cdr_odbc: Out of memory error.\n");
-               res = -1;
-               goto out;
-       }
+               if ((tmp = ast_variable_retrieve(cfg, "global", "table")) == NULL) {
+                       ast_log(LOG_WARNING, "cdr_odbc: table not specified.  Assuming cdr\n");
+                       tmp = "cdr";
+               }
+               if (table)
+                       ast_free(table);
+               table = ast_strdup(tmp);
+               if (table == NULL) {
+                       res = -1;
+                       break;
+               }
 
-       ast_verb(3, "cdr_odbc: dsn is %s\n",dsn);
-       if (username) {
-               ast_verb(3, "cdr_odbc: username is %s\n",username);
-               ast_verb(3, "cdr_odbc: password is [secret]\n");
-       } else
-               ast_verb(3, "cdr_odbc: retreiving username and password from odbc config\n");
-       ast_verb(3, "cdr_odbc: table is %s\n",table);
-       
-       res = odbc_init();
-       if (res < 0) {
-               ast_log(LOG_ERROR, "cdr_odbc: Unable to connect to datasource: %s\n", dsn);
-               ast_verb(3, "cdr_odbc: Unable to connect to datasource: %s\n", dsn);
+               ast_verb(3, "cdr_odbc: dsn is %s\n", dsn);
+               if (username) {
+                       ast_verb(3, "cdr_odbc: username is %s\n", username);
+                       ast_verb(3, "cdr_odbc: password is [secret]\n");
+               } else
+                       ast_verb(3, "cdr_odbc: retrieving username and password from odbc config\n");
+               ast_verb(3, "cdr_odbc: table is %s\n", table);
+
+               res = odbc_init();
+               if (res < 0) {
+                       ast_log(LOG_ERROR, "cdr_odbc: Unable to connect to datasource: %s\n", dsn);
+                       ast_verb(3, "cdr_odbc: Unable to connect to datasource: %s\n", dsn);
+                       }
+               res = ast_cdr_register(name, ast_module_info->description, odbc_log);
+               if (res) {
+                       ast_log(LOG_ERROR, "cdr_odbc: Unable to register ODBC CDR handling\n");
                }
-       res = ast_cdr_register(name, ast_module_info->description, odbc_log);
-       if (res) {
-               ast_log(LOG_ERROR, "cdr_odbc: Unable to register ODBC CDR handling\n");
-       }
-out:
-       if (cfg)
+       } while (0);
+
+       if (cfg && cfg != CONFIG_STATUS_FILEUNCHANGED)
                ast_config_destroy(cfg);
        ast_mutex_unlock(&odbc_lock);
        return res;
@@ -418,7 +418,7 @@ static int odbc_init(void)
 
 static int load_module(void)
 {
-       return odbc_load_module();
+       return odbc_load_module(0);
 }
 
 static int unload_module(void)
@@ -428,8 +428,7 @@ static int unload_module(void)
 
 static int reload(void)
 {
-       odbc_unload_module();
-       return odbc_load_module();
+       return odbc_load_module(1);
 }
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "ODBC CDR Backend",
index 4ccd4aa..d3813c6 100644 (file)
@@ -183,7 +183,7 @@ static int pgsql_log(struct ast_cdr *cdr)
        return 0;
 }
 
-static int my_unload_module(void)
+static int unload_module(void)
 { 
        PQfinish(conn);
        if (pghostname)
@@ -202,20 +202,30 @@ static int my_unload_module(void)
        return 0;
 }
 
-static int process_my_load_module(struct ast_config *cfg)
+static int config_module(int reload)
 {
        struct ast_variable *var;
-        char *pgerror;
+       char *pgerror;
        const char *tmp;
+       struct ast_config *cfg;
+       struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
+
+       if ((cfg = ast_config_load(config, config_flags)) == NULL) {
+               ast_log(LOG_WARNING, "Unable to load config for PostgreSQL CDR's: %s\n", config);
+               return -1;
+       } else if (cfg == CONFIG_STATUS_FILEUNCHANGED)
+               return 0;
 
        if (!(var = ast_variable_browse(cfg, "global")))
                return 0;
 
-       if (!(tmp = ast_variable_retrieve(cfg,"global","hostname"))) {
-               ast_log(LOG_WARNING,"PostgreSQL server hostname not specified.  Assuming unix socket connection\n");
+       if (!(tmp = ast_variable_retrieve(cfg, "global", "hostname"))) {
+               ast_log(LOG_WARNING, "PostgreSQL server hostname not specified.  Assuming unix socket connection\n");
                tmp = "";       /* connect via UNIX-socket by default */
        }
-       
+
+       if (pghostname)
+               ast_free(pghostname);
        if (!(pghostname = ast_strdup(tmp)))
                return -1;
 
@@ -224,6 +234,8 @@ static int process_my_load_module(struct ast_config *cfg)
                tmp = "asteriskcdrdb";
        }
 
+       if (pgdbname)
+               ast_free(pgdbname);
        if (!(pgdbname = ast_strdup(tmp)))
                return -1;
 
@@ -232,6 +244,8 @@ static int process_my_load_module(struct ast_config *cfg)
                tmp = "asterisk";
        }
 
+       if (pgdbuser)
+               ast_free(pgdbuser);
        if (!(pgdbuser = ast_strdup(tmp)))
                return -1;
 
@@ -240,6 +254,8 @@ static int process_my_load_module(struct ast_config *cfg)
                tmp = "";
        }
 
+       if (pgpassword)
+               ast_free(pgpassword);
        if (!(pgpassword = ast_strdup(tmp)))
                return -1;
 
@@ -248,6 +264,8 @@ static int process_my_load_module(struct ast_config *cfg)
                tmp = "5432";
        }
 
+       if (pgdbport)
+               ast_free(pgdbport);
        if (!(pgdbport = ast_strdup(tmp)))
                return -1;
 
@@ -256,6 +274,8 @@ static int process_my_load_module(struct ast_config *cfg)
                tmp = "cdr";
        }
 
+       if (table)
+               ast_free(table);
        if (!(table = ast_strdup(tmp)))
                return -1;
 
@@ -276,49 +296,23 @@ static int process_my_load_module(struct ast_config *cfg)
                ast_debug(1, "Successfully connected to PostgreSQL database.\n");
                connected = 1;
        } else {
-                pgerror = PQerrorMessage(conn);
+               pgerror = PQerrorMessage(conn);
                ast_log(LOG_ERROR, "cdr_pgsql: Unable to connect to database server %s.  CALLS WILL NOT BE LOGGED!!\n", pghostname);
-                ast_log(LOG_ERROR, "cdr_pgsql: Reason: %s\n", pgerror);
+               ast_log(LOG_ERROR, "cdr_pgsql: Reason: %s\n", pgerror);
                connected = 0;
        }
 
        return ast_cdr_register(name, ast_module_info->description, pgsql_log);
 }
 
-static int my_load_module(void)
-{
-       struct ast_config *cfg;
-       int res;
-
-       if (!(cfg = ast_config_load(config))) {
-               ast_log(LOG_WARNING, "Unable to load config for PostgreSQL CDR's: %s\n", config);
-               return AST_MODULE_LOAD_DECLINE;
-       }
-
-       res = process_my_load_module(cfg);
-       ast_config_destroy(cfg);
-
-       return res;
-}
-
 static int load_module(void)
 {
-       return my_load_module();
-}
-
-static int unload_module(void)
-{
-       return my_unload_module();
+       return config_module(0) ? AST_MODULE_LOAD_DECLINE : 0;
 }
 
 static int reload(void)
 {
-       int res;
-       ast_mutex_lock(&pgsql_lock);
-       my_unload_module();
-       res = my_load_module();
-       ast_mutex_unlock(&pgsql_lock);
-       return res;
+       return config_module(1);
 }
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "PostgreSQL CDR Backend",
index b344c0b..207e247 100644 (file)
@@ -232,10 +232,11 @@ static int unload_module(void)
 static int load_module(void)
 {
        struct ast_config *cfg;
+       struct ast_flags config_flags = { 0 };
        int res;
        const char *tmp;
 
-       if ((cfg = ast_config_load(cdr_config))) {
+       if ((cfg = ast_config_load(cdr_config, config_flags))) {
                ast_set2_flag(&global_flags, ast_true(ast_variable_retrieve(cfg, "radius", "usegmtime")), RADIUS_FLAG_USEGMTIME);
                ast_set2_flag(&global_flags, ast_true(ast_variable_retrieve(cfg, "radius", "loguniqueid")), RADIUS_FLAG_LOGUNIQUEID);
                ast_set2_flag(&global_flags, ast_true(ast_variable_retrieve(cfg, "radius", "loguserfield")), RADIUS_FLAG_LOGUSERFIELD);
index c3dcbd2..1c66336 100644 (file)
@@ -74,10 +74,11 @@ static char values[1024];
 static int load_config(int reload)
 {
        struct ast_config *cfg;
+       struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
        struct ast_variable *mappingvar;
        const char *tmp;
 
-       if (!(cfg = ast_config_load(config_file))) {
+       if (!(cfg = ast_config_load(config_file, config_flags))) {
                if (reload)
                        ast_log(LOG_WARNING, "%s: Failed to reload configuration file.\n", name);
                else {
@@ -86,10 +87,10 @@ static int load_config(int reload)
                                        name);
                }
                return -1;
-       }
+       } else if (cfg == CONFIG_STATUS_FILEUNCHANGED)
+               return 0;
 
-       if (!reload)
-               ast_mutex_lock(&lock);
+       ast_mutex_lock(&lock);
 
        if (!(mappingvar = ast_variable_browse(cfg, "master"))) {
                /* nothing configured */
@@ -125,8 +126,7 @@ static int load_config(int reload)
                return -1;
        }
 
-       if (!reload)
-               ast_mutex_unlock(&lock);
+       ast_mutex_unlock(&lock);
 
        ast_config_destroy(cfg);
 
@@ -248,13 +248,7 @@ static int load_module(void)
 
 static int reload(void)
 {
-       int res;
-
-       ast_mutex_lock(&lock);
-       res = load_config(1);
-       ast_mutex_unlock(&lock);
-
-       return res;
+       return load_config(1);
 }
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "SQLite3 Custom CDR Module",
index 2707a4b..af58b86 100644 (file)
@@ -422,95 +422,106 @@ static int tds_unload_module(void)
        return 0;
 }
 
-static int tds_load_module(void)
+static int tds_load_module(int reload)
 {
        int res = 0;
        struct ast_config *cfg;
        struct ast_variable *var;
        const char *ptr = NULL;
+       struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
 #ifdef FREETDS_PRE_0_62
        TDS_INT result_type;
 #endif
 
-       cfg = ast_config_load(config);
+       cfg = ast_config_load(config, config_flags);
        if (!cfg) {
                ast_log(LOG_NOTICE, "Unable to load config for MSSQL CDR's: %s\n", config);
                return 0;
-       }
+       } else if (cfg == CONFIG_STATUS_FILEUNCHANGED)
+               return 0;
 
        var = ast_variable_browse(cfg, "global");
        if (!var) /* nothing configured */
                return 0;
 
        ptr = ast_variable_retrieve(cfg, "global", "hostname");
-       if (ptr)
-               hostname = strdup(ptr);
-       else
-               ast_log(LOG_ERROR,"Database server hostname not specified.\n");
+       if (ptr) {
+               if (hostname)
+                       ast_free(hostname);
+               hostname = ast_strdup(ptr);
+       } else
+               ast_log(LOG_ERROR, "Database server hostname not specified.\n");
 
        ptr = ast_variable_retrieve(cfg, "global", "dbname");
-       if (ptr)
-               dbname = strdup(ptr);
-       else
-               ast_log(LOG_ERROR,"Database dbname not specified.\n");
+       if (ptr) {
+               if (dbname)
+                       ast_free(dbname);
+               dbname = ast_strdup(ptr);
+       } else
+               ast_log(LOG_ERROR, "Database dbname not specified.\n");
 
        ptr = ast_variable_retrieve(cfg, "global", "user");
-       if (ptr)
-               dbuser = strdup(ptr);
-       else
-               ast_log(LOG_ERROR,"Database dbuser not specified.\n");
+       if (ptr) {
+               if (dbuser)
+                       ast_free(dbuser);
+               dbuser = ast_strdup(ptr);
+       } else
+               ast_log(LOG_ERROR, "Database dbuser not specified.\n");
 
        ptr = ast_variable_retrieve(cfg, "global", "password");
-       if (ptr)
-               password = strdup(ptr);
-       else
+       if (ptr) {
+               if (password)
+                       ast_free(password);
+               password = ast_strdup(ptr);
+       } else
                ast_log(LOG_ERROR,"Database password not specified.\n");
 
        ptr = ast_variable_retrieve(cfg, "global", "charset");
+       if (charset)
+               ast_free(charset);
        if (ptr)
-               charset = strdup(ptr);
+               charset = ast_strdup(ptr);
        else
-               charset = strdup("iso_1");
+               charset = ast_strdup("iso_1");
 
+       if (language)
+               ast_free(language);
        ptr = ast_variable_retrieve(cfg, "global", "language");
        if (ptr)
-               language = strdup(ptr);
+               language = ast_strdup(ptr);
        else
-               language = strdup("us_english");
+               language = ast_strdup("us_english");
 
-       ptr = ast_variable_retrieve(cfg,"global","table");
+       ptr = ast_variable_retrieve(cfg, "global", "table");
        if (ptr == NULL) {
-               ast_debug(1,"cdr_tds: table not specified.  Assuming cdr\n");
+               ast_debug(1, "cdr_tds: table not specified.  Assuming cdr\n");
                ptr = "cdr";
        }
-       table = strdup(ptr);
+       if (table)
+               ast_free(table);
+       table = ast_strdup(ptr);
 
        ast_config_destroy(cfg);
 
+       ast_mutex_lock(&tds_lock);
+       mssql_disconnect();
        mssql_connect();
-
-       /* Register MSSQL CDR handler */
-       res = ast_cdr_register(name, ast_module_info->description, tds_log);
-       if (res)
-       {
-               ast_log(LOG_ERROR, "Unable to register MSSQL CDR handling\n");
-       }
+       ast_mutex_unlock(&tds_lock);
 
        return res;
 }
 
 static int reload(void)
 {
-       tds_unload_module();
-       return tds_load_module();
+       return tds_load_module(1);
 }
 
 static int load_module(void)
 {
-       if(!tds_load_module())
+       if (!tds_load_module(0))
                return AST_MODULE_LOAD_DECLINE;
-       else 
-               return AST_MODULE_LOAD_SUCCESS;
+       ast_cdr_register(name, ast_module_info->description, tds_log);
+       return AST_MODULE_LOAD_SUCCESS;
 }
 
 static int unload_module(void)
index 880501a..c4e0ecb 100644 (file)
@@ -976,7 +976,7 @@ static struct ast_channel *agent_new(struct agent_pvt *p, int state)
  *
  * \returns Always 0, or so it seems.
  */
-static int read_agent_config(void)
+static int read_agent_config(int reload)
 {
        struct ast_config *cfg;
        struct ast_config *ucfg;
@@ -986,17 +986,19 @@ static int read_agent_config(void)
        const char *catname;
        const char *hasagent;
        int genhasagent;
+       struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
 
        group = 0;
        autologoff = 0;
        wrapuptime = 0;
        ackcall = 0;
        endcall = 1;
-       cfg = ast_config_load(config);
+       cfg = ast_config_load(config, config_flags);
        if (!cfg) {
                ast_log(LOG_NOTICE, "No agent configuration found -- agent support disabled\n");
                return 0;
-       }
+       } else if (cfg == CONFIG_STATUS_FILEUNCHANGED)
+               return -1;
        AST_LIST_LOCK(&agents);
        AST_LIST_TRAVERSE(&agents, p, list) {
                p->dead = 1;
@@ -1081,7 +1083,7 @@ static int read_agent_config(void)
                }
                v = v->next;
        }
-       if ((ucfg = ast_config_load("users.conf"))) {
+       if ((ucfg = ast_config_load("users.conf", config_flags)) && ucfg != CONFIG_STATUS_FILEUNCHANGED) {
                genhasagent = ast_true(ast_variable_retrieve(ucfg, "general", "hasagent"));
                catname = ast_category_browse(ucfg, NULL);
                while(catname) {
@@ -2276,7 +2278,7 @@ static int load_module(void)
                return -1;
        }
        /* Read in the config */
-       if (!read_agent_config())
+       if (!read_agent_config(0))
                return AST_MODULE_LOAD_DECLINE;
        if (persistent_agents)
                reload_agents();
@@ -2299,9 +2301,10 @@ static int load_module(void)
 
 static int reload(void)
 {
-       read_agent_config();
-       if (persistent_agents)
-               reload_agents();
+       if (!read_agent_config(1)) {
+               if (persistent_agents)
+                       reload_agents();
+       }
        return 0;
 }
 
index a2a10e8..f043cbd 100644 (file)
@@ -1082,13 +1082,14 @@ static int load_module(void)
 {
        struct ast_config *cfg;
        struct ast_variable *v;
+       struct ast_flags config_flags = { 0 };
 
        /* Copy the default jb config over global_jbconf */
        memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
 
        strcpy(mohinterpret, "default");
 
-       if (!(cfg = ast_config_load(config)))
+       if (!(cfg = ast_config_load(config, config_flags)))
                return AST_MODULE_LOAD_DECLINE;
 
        v = ast_variable_browse(cfg, "general");
index b4306fe..22d8a29 100644 (file)
@@ -1702,8 +1702,9 @@ static int gtalk_load_config(void)
        struct gtalk_candidate *global_candidates = NULL;
        struct hostent *hp;
        struct ast_hostent ahp;
+       struct ast_flags config_flags = { 0 };
 
-       cfg = ast_config_load(GOOGLE_CONFIG);
+       cfg = ast_config_load(GOOGLE_CONFIG, config_flags);
        if (!cfg)
                return 0;
 
index 36f42e8..6da113d 100644 (file)
@@ -2812,13 +2812,23 @@ static int reload_config(int is_reload)
        int is_user, is_peer, is_alias;
        char _gatekeeper[100];
        int gk_discover, gk_disable, gk_changed;
+       struct ast_flags config_flags = { is_reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
 
-       cfg = ast_config_load(config);
+       cfg = ast_config_load(config, config_flags);
 
        /* We *must* have a config file otherwise stop immediately */
        if (!cfg) {
                ast_log(LOG_NOTICE, "Unable to load config %s, H.323 disabled\n", config);
                return 1;
+       } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
+               ucfg = ast_config_load("users.conf", config_flags);
+               if (ucfg == CONFIG_STATUS_FILEUNCHANGED)
+                       return 0;
+               ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
+               cfg = ast_config_load(config, config_flags);
+       } else {
+               ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
+               ucfg = ast_config_load("users.conf", config_flags);
        }
 
        /* fire up the H.323 Endpoint */
@@ -2851,8 +2861,6 @@ static int reload_config(int is_reload)
        /* Copy the default jb config over global_jbconf */
        memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
 
-       /* Load configuration from users.conf */
-       ucfg = ast_config_load("users.conf");
        if (ucfg) {
                struct ast_variable *gen;
                int genhas_h323;
index 6f41fdb..333ccb2 100644 (file)
@@ -9776,15 +9776,26 @@ static int set_config(char *config_file, int reload)
        struct iax2_user *user;
        struct iax2_peer *peer;
        struct ast_netsock *ns;
+       struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
 #if 0
        static unsigned short int last_port=0;
 #endif
 
-       cfg = ast_config_load(config_file);
-       
+       cfg = ast_config_load(config_file, config_flags);
+
        if (!cfg) {
                ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
                return -1;
+       } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
+               ucfg = ast_config_load("users.conf", config_flags);
+               if (ucfg == CONFIG_STATUS_FILEUNCHANGED)
+                       return 0;
+               /* Otherwise we need to reread both files */
+               ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
+               cfg = ast_config_load(config_file, config_flags);
+       } else { /* iax.conf changed, gotta reread users.conf, too */
+               ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
+               ucfg = ast_config_load("users.conf", config_flags);
        }
 
        /* Reset global codec prefs */  
@@ -10048,7 +10059,6 @@ static int set_config(char *config_file, int reload)
        }
        iax2_capability = capability;
        
-       ucfg = ast_config_load("users.conf");
        if (ucfg) {
                struct ast_variable *gen;
                int genhasiax;
@@ -10176,7 +10186,7 @@ static int reload_config(void)
                iax2_poke_peer(peer, 0);
        AST_LIST_UNLOCK(&peers);
        reload_firmware();
-       iax_provision_reload();
+       iax_provision_reload(1);
 
        return 0;
 }
@@ -11097,7 +11107,7 @@ static int load_module(void)
        AST_LIST_UNLOCK(&peers);
 
        reload_firmware();
-       iax_provision_reload();
+       iax_provision_reload(0);
 
        return AST_MODULE_LOAD_SUCCESS;
 }
index 8a3321c..9848b96 100644 (file)
@@ -1567,8 +1567,9 @@ static int jingle_load_config(void)
        struct ast_codec_pref prefs;
        struct aji_client_container *clients;
        struct jingle_candidate *global_candidates = NULL;
+       struct ast_flags config_flags = { 0 };
 
-       cfg = ast_config_load(JINGLE_CONFIG);
+       cfg = ast_config_load(JINGLE_CONFIG, config_flags);
        if (!cfg)
                return 0;
 
index 64d300f..c4229e0 100644 (file)
@@ -422,8 +422,8 @@ static void start_rtp(struct mgcp_subchannel *sub);
 static void handle_response(struct mgcp_endpoint *p, struct mgcp_subchannel *sub,  
                             int result, unsigned int ident, struct mgcp_request *resp);
 static void dump_cmd_queues(struct mgcp_endpoint *p, struct mgcp_subchannel *sub);
-static int mgcp_do_reload(void);
 static int mgcp_reload(int fd, int argc, char *argv[]);
+static int reload_config(int reload);
 
 static struct ast_channel *mgcp_request(const char *type, int format, void *data, int *cause);
 static int mgcp_call(struct ast_channel *ast, char *dest, int timeout);
@@ -3379,7 +3379,7 @@ static void *do_monitor(void *data)
                ast_mutex_unlock(&mgcp_reload_lock);
                if (reloading) {
                        ast_verb(1, "Reloading MGCP\n");
-                       mgcp_do_reload();
+                       reload_config(1);
                        /* Add an I/O event to our UDP socket */
                        if (mgcpsock > -1) 
                                mgcpsock_read_id = ast_io_add(io, mgcpsock, mgcpsock_read, AST_IO_IN, NULL);
@@ -4042,7 +4042,7 @@ static void prune_gateways(void)
        ast_mutex_unlock(&gatelock);
 }
 
-static int reload_config(void)
+static int reload_config(int reload)
 {
        struct ast_config *cfg;
        struct ast_variable *v;
@@ -4052,18 +4052,21 @@ static int reload_config(void)
        struct ast_hostent ahp;
        struct hostent *hp;
        int format;
+       struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
        
        if (gethostname(ourhost, sizeof(ourhost)-1)) {
                ast_log(LOG_WARNING, "Unable to get hostname, MGCP disabled\n");
                return 0;
        }
-       cfg = ast_config_load(config);
+       cfg = ast_config_load(config, config_flags);
 
        /* We *must* have a config file otherwise stop immediately */
        if (!cfg) {
                ast_log(LOG_NOTICE, "Unable to load config %s, MGCP disabled\n", config);
                return 0;
-       }
+       } else if (cfg == CONFIG_STATUS_FILEUNCHANGED)
+               return 0;
+
        memset(&bindaddr, 0, sizeof(bindaddr));
        dtmfmode = 0;
 
@@ -4222,7 +4225,7 @@ static int load_module(void)
                return AST_MODULE_LOAD_FAILURE;
        }
 
-       if (reload_config())
+       if (reload_config(0))
                return AST_MODULE_LOAD_DECLINE;
 
        /* Make sure we can register our mgcp channel type */
@@ -4242,13 +4245,6 @@ static int load_module(void)
        return AST_MODULE_LOAD_SUCCESS;
 }
 
-/*! \brief  mgcp_do_reload: Reload module */
-static int mgcp_do_reload(void)
-{
-       reload_config();
-       return 0;
-}
-
 static int mgcp_reload(int fd, int argc, char *argv[])
 {
        static int deprecated = 0;
index eb19e03..96c55da 100644 (file)
@@ -4753,7 +4753,7 @@ static int load_module(void)
                return AST_MODULE_LOAD_DECLINE;
        }
        
-       if (misdn_cfg_init(max_ports)) {
+       if (misdn_cfg_init(max_ports, 0)) {
                ast_log(LOG_ERROR, "Unable to initialize misdn_config.\n");
                return AST_MODULE_LOAD_DECLINE;
        }
index 6256deb..42e0546 100644 (file)
@@ -1577,12 +1577,13 @@ static int load_module(void)
 {
        struct ast_config *cfg = NULL;
        char *ctg = NULL;
+       struct ast_flags config_flags = { 0 };
 
        /* Copy the default jb config over global_jbconf */
        memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
 
        /* load config file */
-       if (!(cfg = ast_config_load(config))) {
+       if (!(cfg = ast_config_load(config, config_flags))) {
                ast_log(LOG_NOTICE, "Unable to load config %s\n", config);
                return AST_MODULE_LOAD_DECLINE;
        }
index e99b74e..49b9cf7 100644 (file)
@@ -1347,7 +1347,9 @@ static int load_module(void)
        struct phone_pvt *tmp;
        int mode = MODE_IMMEDIATE;
        int txgain = DEFAULT_GAIN, rxgain = DEFAULT_GAIN; /* default gain 1.0 */
-       cfg = ast_config_load(config);
+       struct ast_flags config_flags = { 0 };
+
+       cfg = ast_config_load(config, config_flags);
 
        /* We *must* have a config file otherwise stop immediately */
        if (!cfg) {
index f096ffa..4df005d 100644 (file)
@@ -17629,16 +17629,27 @@ static int reload_config(enum channelreloadreason reason)
        char *cat, *stringp, *context, *oldregcontext;
        char newcontexts[AST_MAX_CONTEXT], oldcontexts[AST_MAX_CONTEXT];
        struct ast_flags dummy[2];
+       struct ast_flags config_flags = { CONFIG_FLAG_FILEUNCHANGED };
        int auto_sip_domains = FALSE;
        struct sockaddr_in old_bindaddr = bindaddr;
        int registry_count = 0, peer_count = 0, user_count = 0;
 
-       cfg = ast_config_load(config);
+       cfg = ast_config_load(config, config_flags);
 
        /* We *must* have a config file otherwise stop immediately */
        if (!cfg) {
                ast_log(LOG_NOTICE, "Unable to load config %s\n", config);
                return -1;
+       } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
+               ucfg = ast_config_load("users.conf", config_flags);
+               if (ucfg == CONFIG_STATUS_FILEUNCHANGED)
+                       return 0;
+               /* Must reread both files, because one changed */
+               ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
+               cfg = ast_config_load(config, config_flags);
+       } else {
+               ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
+               ucfg = ast_config_load("users.conf", config_flags);
        }
        
        /* Initialize copy of current global_regcontext for later use in removing stale contexts */
@@ -18007,7 +18018,6 @@ static int reload_config(enum channelreloadreason reason)
                        authl = add_realm_authentication(authl, v->value, v->lineno);
        }
        
-       ucfg = ast_config_load("users.conf");
        if (ucfg) {
                struct ast_variable *gen;
                int genhassip, genregistersip;
@@ -18181,7 +18191,7 @@ static int reload_config(enum channelreloadreason reason)
        /* Load the list of manual NOTIFY types to support */
        if (notify_types)
                ast_config_destroy(notify_types);
-       notify_types = ast_config_load(notify_config);
+       notify_types = ast_config_load(notify_config, config_flags);
 
        /* Done, tell the manager */
        manager_event(EVENT_FLAG_SYSTEM, "ChannelReload", "ChannelType: SIP\r\nReloadReason: %s\r\nRegistry_Count: %d\r\nPeer_Count: %d\r\nUser_Count: %d\r\n\r\n", channelreloadreason2txt(reason), registry_count, peer_count, user_count);
index d9629ed..f8e22d9 100644 (file)
@@ -5142,12 +5142,13 @@ static int reload_config(void)
        int oldport = ntohs(bindaddr.sin_port);
        char *stringp, *context, *oldregcontext;
        char newcontexts[AST_MAX_CONTEXT], oldcontexts[AST_MAX_CONTEXT];
+       struct ast_flags config_flags = { 0 };
 
        if (gethostname(ourhost, sizeof(ourhost))) {
                ast_log(LOG_WARNING, "Unable to get hostname, Skinny disabled\n");
                return 0;
        }
-       cfg = ast_config_load(config);
+       cfg = ast_config_load(config, config_flags);
 
        /* We *must* have a config file otherwise stop immediately */
        if (!cfg) {
index bcc3f68..8528727 100644 (file)
@@ -2636,7 +2636,7 @@ static float parse_gain_value(char *gain_type, char *value)
 }
 
 
-int unload_module()
+static int unload_module()
 {
        struct vpb_pvt *p;
        /* First, take us out of the channel loop */
@@ -2701,10 +2701,11 @@ int unload_module()
        return 0;
 }
 
-int load_module()
+static int load_module()
 {
        struct ast_config *cfg;
        struct ast_variable *v;
+       struct ast_flags config_flags = { 0 };
        struct vpb_pvt *tmp;
        int board = 0, group = 0;
        ast_group_t     callgroup = 0;
@@ -2721,7 +2722,7 @@ int load_module()
        int bal3 = -1;
        char * callerid = NULL;
 
-       cfg = ast_config_load(config);
+       cfg = ast_config_load(config, config_flags);
 
        /* We *must* have a config file otherwise stop immediately */
        if (!cfg) {
@@ -2897,29 +2898,10 @@ int load_module()
        return error;
 }
 
-int usecount()
-{
-       return usecnt;
-}
-
-const char *description()
-{
-       return (char *) desc;
-}
-
-const char *key()
-{
-       return ASTERISK_GPL_KEY;
-}
-
 /**/
 #if defined(__cplusplus) || defined(c_plusplus)
  }
 #endif
 /**/
 
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "VoiceTronix API driver",
-               .load = load_module,
-               .unload = unload_module,
-               .reload = reload,
-              );
+AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "VoiceTronix API driver");
index 35be3ec..d4feae8 100644 (file)
@@ -12623,27 +12623,37 @@ static int process_zap(struct zt_chan_conf *confp, struct ast_variable *v, int r
                
 static int setup_zap(int reload)
 {
-       struct ast_config *cfg;
+       struct ast_config *cfg, *ucfg;
        struct ast_variable *v;
        struct zt_chan_conf base_conf = zt_chan_conf_default();
        struct zt_chan_conf conf;
-       int res;
+       struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
+       int res, x;
 
 #ifdef HAVE_PRI
        char *c;
        int spanno;
-       int i, x;
+       int i;
        int logicalspan;
        int trunkgroup;
        int dchannels[NUM_DCHANS];
 #endif
 
-       cfg = ast_config_load(config);
+       cfg = ast_config_load(config, config_flags);
 
        /* Error if we have no config file */
        if (!cfg) {
                ast_log(LOG_ERROR, "Unable to load config %s\n", config);
                return 0;
+       } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
+               ucfg = ast_config_load("users.conf", config_flags);
+               if (ucfg == CONFIG_STATUS_FILEUNCHANGED)
+                       return 0;
+               ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
+               cfg = ast_config_load(config, config_flags);
+       } else {
+               ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
+               ucfg = ast_config_load("users.conf", config_flags);
        }
 
        /* It's a little silly to lock it, but we mind as well just to be sure */
@@ -12718,25 +12728,24 @@ static int setup_zap(int reload)
        ast_config_destroy(cfg);
        if (res)
                return res;
-       cfg = ast_config_load("users.conf");
-       if (cfg) {
+       if (ucfg) {
                char *cat;
                const char *chans;
                process_zap(&base_conf, ast_variable_browse(cfg, "general"), 1, 1);
-               for (cat = ast_category_browse(cfg, NULL); cat ; cat = ast_category_browse(cfg, cat)) {
+               for (cat = ast_category_browse(ucfg, NULL); cat ; cat = ast_category_browse(ucfg, cat)) {
                        if (!strcasecmp(cat, "general"))
                                continue;
-                       chans = ast_variable_retrieve(cfg, cat, "zapchan");
+                       chans = ast_variable_retrieve(ucfg, cat, "zapchan");
                        if (!ast_strlen_zero(chans)) {
                                if (memcpy(&conf, &base_conf, sizeof(conf)) == NULL) {
                                        ast_log(LOG_ERROR, "Not enough memory for conf copy\n");
-                                       ast_config_destroy(cfg);
+                                       ast_config_destroy(ucfg);
                                        return -1;
                                }
-                               process_zap(&conf, ast_variable_browse(cfg, cat), reload, 0);
+                               process_zap(&conf, ast_variable_browse(ucfg, cat), reload, 0);
                        }
                }
-               ast_config_destroy(cfg);
+               ast_config_destroy(ucfg);
        }
 #ifdef HAVE_PRI
        if (!reload) {
index dd3419a..031897f 100644 (file)
@@ -485,12 +485,13 @@ int iax_provision_unload(void)
        return 0;
 }
 
-int iax_provision_reload(void)
+int iax_provision_reload(int reload)
 {
        struct ast_config *cfg;
        struct iax_template *cur, *prev, *next;
        char *cat;
        int found = 0;
+       struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
        if (!provinit)
                iax_provision_init();
        /* Mark all as dead.  No need for locking */
@@ -499,8 +500,8 @@ int iax_provision_reload(void)
                cur->dead = 1;
                cur = cur->next;
        }
-       cfg = ast_config_load("iaxprov.conf");
-       if (cfg) {
+       cfg = ast_config_load("iaxprov.conf", config_flags);
+       if (cfg != NULL && cfg != CONFIG_STATUS_FILEUNCHANGED) {
                /* Load as appropriate */
                cat = ast_category_browse(cfg, NULL);
                while(cat) {
@@ -512,7 +513,9 @@ int iax_provision_reload(void)
                        cat = ast_category_browse(cfg, cat);
                }
                ast_config_destroy(cfg);
-       } else
+       } else if (cfg == CONFIG_STATUS_FILEUNCHANGED)
+               return 0;
+       else
                ast_log(LOG_NOTICE, "No IAX provisioning configuration found, IAX provisioning disabled.\n");
        ast_mutex_lock(&provlock);
        /* Drop dead entries while locked */
index d951502..b1dfd06 100644 (file)
@@ -46,7 +46,7 @@
 #define PROV_FLAG_DIS_THREEWAY (1 << 7)        /* Three-way calling, transfer disabled */
 
 char *iax_provflags2str(char *buf, int buflen, unsigned int flags);
-int iax_provision_reload(void);
+int iax_provision_reload(int reload);
 int iax_provision_unload(void);
 int iax_provision_build(struct iax_ie_data *provdata, unsigned int *signature, const char *template, int force);
 int iax_provision_version(unsigned int *signature, const char *template, int force);
index 2708da4..87481de 100644 (file)
@@ -108,7 +108,7 @@ enum misdn_cfg_method {
 };
 
 /* you must call misdn_cfg_init before any other function of this header file */
-int misdn_cfg_init(int max_ports); 
+int misdn_cfg_init(int max_ports, int reload); 
 void misdn_cfg_reload(void);
 void misdn_cfg_destroy(void);
 
index bdd1437..008f0f6 100644 (file)
@@ -1063,7 +1063,7 @@ static void _fill_defaults (void)
 
 void misdn_cfg_reload (void)
 {
-       misdn_cfg_init (0);
+       misdn_cfg_init(0, 1);
 }
 
 void misdn_cfg_destroy (void)
@@ -1082,18 +1082,20 @@ void misdn_cfg_destroy (void)
        ast_mutex_destroy(&config_mutex);
 }
 
-int misdn_cfg_init (int this_max_ports)
+int misdn_cfg_init(int this_max_ports, int reload)
 {
        char config[] = "misdn.conf";
        char *cat, *p;
        int i;
        struct ast_config *cfg;
        struct ast_variable *v;
+       struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
 
-       if (!(cfg = AST_LOAD_CFG(config))) {
+       if (!(cfg = AST_LOAD_CFG(config, config_flags))) {
                ast_log(LOG_WARNING, "missing file: misdn.conf\n");
                return -1;
-       }
+       } else if (cfg == CONFIG_STATUS_FILEUNCHANGED)
+               return 0;
 
        ast_mutex_init(&config_mutex);
 
index fb4bb8b..e76470b 100644 (file)
@@ -350,11 +350,12 @@ static struct ast_translator lintoadpcm = {
        .buf_size = BUFFER_SAMPLES/ 2,  /* 2 samples per byte */
 };
 
-static void parse_config(void)
+static void parse_config(int reload)
 {
-       struct ast_config *cfg = ast_config_load("codecs.conf");
+       struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
+       struct ast_config *cfg = ast_config_load("codecs.conf", config_flags);
        struct ast_variable *var;
-       if (cfg == NULL)
+       if (cfg == NULL || cfg == CONFIG_STATUS_FILEUNCHANGED)
                return;
        for (var = ast_variable_browse(cfg, "plc"); var ; var = var->next) {
                if (!strcasecmp(var->name, "genericplc")) {
@@ -368,7 +369,7 @@ static void parse_config(void)
 /*! \brief standard module glue */
 static int reload(void)
 {
-       parse_config();
+       parse_config(1);
        return 0;
 }
 
@@ -386,7 +387,7 @@ static int load_module(void)
 {
        int res;
 
-       parse_config();
+       parse_config(0);
        res = ast_register_translator(&adpcmtolin);
        if (!res)
                res = ast_register_translator(&lintoadpcm);
index 9edae51..1c28055 100644 (file)
@@ -134,11 +134,12 @@ static struct ast_translator lintoalaw = {
        .buf_size = BUFFER_SAMPLES,
 };
 
-static void parse_config(void)
+static void parse_config(int reload)
 {
        struct ast_variable *var;
-       struct ast_config *cfg = ast_config_load("codecs.conf");
-       if (!cfg)
+       struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
+       struct ast_config *cfg = ast_config_load("codecs.conf", config_flags);
+       if (cfg == NULL || cfg == CONFIG_STATUS_FILEUNCHANGED)
                return;
        for (var = ast_variable_browse(cfg, "plc"); var; var = var->next) {
                if (!strcasecmp(var->name, "genericplc")) {
@@ -153,7 +154,7 @@ static void parse_config(void)
 
 static int reload(void)
 {
-       parse_config();
+       parse_config(1);
        return 0;
 }
 
@@ -171,7 +172,7 @@ static int load_module(void)
 {
        int res;
 
-       parse_config();
+       parse_config(0);
        res = ast_register_translator(&alawtolin);
        if (!res)
                res = ast_register_translator(&lintoalaw);
index 46d34f1..b2b7609 100644 (file)
@@ -164,12 +164,13 @@ static struct ast_translator lintog722 = {
        .buf_size = BUFFER_SAMPLES,
 };
 
-static void parse_config(void)
+static void parse_config(int reload)
 {
        struct ast_variable *var;
-       struct ast_config *cfg = ast_config_load("codecs.conf");
+       struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
+       struct ast_config *cfg = ast_config_load("codecs.conf", config_flags);
 
-       if (!cfg)
+       if (cfg == NULL || cfg == CONFIG_STATUS_FILEUNCHANGED)
                return;
        for (var = ast_variable_browse(cfg, "plc"); var; var = var->next) {
                if (!strcasecmp(var->name, "genericplc")) {
@@ -183,7 +184,7 @@ static void parse_config(void)
 
 static int reload(void)
 {
-       parse_config();
+       parse_config(1);
 
        return 0;
 }
@@ -203,7 +204,7 @@ static int load_module(void)
        int res = 0;
 
 
-       parse_config();
+       parse_config(0);
 
        res |= ast_register_translator(&g722tolin);
        res |= ast_register_translator(&lintog722);
index 425ba9b..ba80588 100644 (file)
@@ -894,12 +894,13 @@ static struct ast_translator g726aal2tog726 = {
        .buf_size = BUFFER_SAMPLES,
 };
 
-static void parse_config(void)
+static void parse_config(int reload)
 {
        struct ast_variable *var;
-       struct ast_config *cfg = ast_config_load("codecs.conf");
+       struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
+       struct ast_config *cfg = ast_config_load("codecs.conf", config_flags);
 
-       if (!cfg)
+       if (cfg == NULL || cfg == CONFIG_STATUS_FILEUNCHANGED)
                return;
        for (var = ast_variable_browse(cfg, "plc"); var; var = var->next) {
                if (!strcasecmp(var->name, "genericplc")) {
@@ -913,7 +914,7 @@ static void parse_config(void)
 
 static int reload(void)
 {
-       parse_config();
+       parse_config(1);
 
        return 0;
 }
@@ -939,7 +940,7 @@ static int load_module(void)
        int res = 0;
 
 
-       parse_config();
+       parse_config(0);
 
        res |= ast_register_translator(&g726tolin);
        res |= ast_register_translator(&lintog726);
index c346f24..b19abfe 100644 (file)
@@ -235,11 +235,12 @@ static struct ast_translator lintogsm = {
 };
 
 
-static void parse_config(void)
+static void parse_config(int reload)
 {
        struct ast_variable *var;
-       struct ast_config *cfg = ast_config_load("codecs.conf");
-       if (!cfg)
+       struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
+       struct ast_config *cfg = ast_config_load("codecs.conf", config_flags);
+       if (!cfg || cfg == CONFIG_STATUS_FILEUNCHANGED)
                return;
        for (var = ast_variable_browse(cfg, "plc"); var; var = var->next) {
               if (!strcasecmp(var->name, "genericplc")) {
@@ -253,7 +254,7 @@ static void parse_config(void)
 /*! \brief standard module glue */
 static int reload(void)
 {
-       parse_config();
+       parse_config(1);
        return 0;
 }
 
@@ -272,7 +273,7 @@ static int load_module(void)
 {
        int res;
 
-       parse_config();
+       parse_config(0);
        res = ast_register_translator(&gsmtolin);
        if (!res) 
                res=ast_register_translator(&lintogsm);
index d4688cd..3ed528b 100644 (file)
@@ -261,27 +261,28 @@ static struct ast_translator lintolpc10 = {
        .buf_size = LPC10_BYTES_IN_COMPRESSED_FRAME * (1 + BUFFER_SAMPLES / LPC10_SAMPLES_PER_FRAME),
 };
 
-static void parse_config(void)
+static void parse_config(int reload)
 {
-        struct ast_variable *var;
-        struct ast_config *cfg = ast_config_load("codecs.conf");
-       if (!cfg)
+       struct ast_variable *var;
+       struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
+       struct ast_config *cfg = ast_config_load("codecs.conf", config_flags);
+       if (cfg == NULL || cfg == CONFIG_STATUS_FILEUNCHANGED)
                return;
        for (var = ast_variable_browse(cfg, "plc"); var; var = var->next) {
-              if (!strcasecmp(var->name, "genericplc")) {
+               if (!strcasecmp(var->name, "genericplc")) {
                        lpc10tolin.useplc = ast_true(var->value) ? 1 : 0;
                        ast_verb(3, "codec_lpc10: %susing generic PLC\n",
                                        lpc10tolin.useplc ? "" : "not ");
                }
-        }
+       }
        ast_config_destroy(cfg);
 }
 
 static int reload(void)
 {
-        parse_config();
+       parse_config(1);
 
-        return 0;
+       return 0;
 }
 
 
@@ -299,10 +300,10 @@ static int load_module(void)
 {
        int res;
 
-       parse_config();
-       res=ast_register_translator(&lpc10tolin);
+       parse_config(0);
+       res = ast_register_translator(&lpc10tolin);
        if (!res) 
-               res=ast_register_translator(&lintolpc10);
+               res = ast_register_translator(&lintolpc10);
        else
                ast_unregister_translator(&lpc10tolin);
 
index 1cbd5d9..c4e24f9 100644 (file)
@@ -375,14 +375,15 @@ static struct ast_translator lintospeex = {
        .buf_size = BUFFER_SAMPLES * 2, /* XXX maybe a lot less ? */
 };
 
-static void parse_config(void) 
+static void parse_config(int reload) 
 {
-       struct ast_config *cfg = ast_config_load("codecs.conf");
+       struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
+       struct ast_config *cfg = ast_config_load("codecs.conf", config_flags);
        struct ast_variable *var;
        int res;
        float res_f;
 
-       if (cfg == NULL)
+       if (cfg == NULL || cfg == CONFIG_STATUS_FILEUNCHANGED)
                return;
 
        for (var = ast_variable_browse(cfg, "speex"); var; var = var->next) {
@@ -470,7 +471,7 @@ static void parse_config(void)
 
 static int reload(void) 
 {
-       parse_config();
+       parse_config(1);
 
        return 0;
 }
@@ -489,7 +490,7 @@ static int load_module(void)
 {
        int res;
 
-       parse_config();
+       parse_config(0);
        res=ast_register_translator(&speextolin);
        if (!res) 
                res=ast_register_translator(&lintospeex);
index ce248f1..4ffbe83 100644 (file)
@@ -147,11 +147,12 @@ static struct ast_translator lintoulaw = {
        .buffer_samples = BUFFER_SAMPLES,
 };
 
-static void parse_config(void)
+static void parse_config(int reload)
 {
        struct ast_variable *var;
-       struct ast_config *cfg = ast_config_load("codecs.conf");
-       if (!cfg)
+       struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
+       struct ast_config *cfg = ast_config_load("codecs.conf", config_flags);
+       if (cfg == NULL || cfg == CONFIG_STATUS_FILEUNCHANGED)
                return;
        for (var = ast_variable_browse(cfg, "plc"); var; var = var->next) {
                if (!strcasecmp(var->name, "genericplc")) {
@@ -164,7 +165,7 @@ static void parse_config(void)
 
 static int reload(void)
 {
-       parse_config();
+       parse_config(1);
 
        return 0;
 }
@@ -183,7 +184,7 @@ static int load_module(void)
 {
        int res;
 
-       parse_config();
+       parse_config(0);
        res = ast_register_translator(&ulawtolin);
        if (!res)
                res = ast_register_translator(&lintoulaw);
index 9204baa..b3226ff 100644 (file)
@@ -312,12 +312,13 @@ static void unregister_translators(void)
        AST_LIST_UNLOCK(&translators);
 }
 
-static void parse_config(void)
+static void parse_config(int reload)
 {
        struct ast_variable *var;
-       struct ast_config *cfg = ast_config_load("codecs.conf");
+       struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
+       struct ast_config *cfg = ast_config_load("codecs.conf", config_flags);
 
-       if (!cfg)
+       if (!cfg || cfg == CONFIG_STATUS_FILEUNCHANGED)
                return;
 
        for (var = ast_variable_browse(cfg, "plc"); var; var = var->next) {
@@ -387,7 +388,7 @@ static int reload(void)
 {
        struct translator *cur;
 
-       parse_config();
+       parse_config(1);
 
        AST_LIST_LOCK(&translators);
        AST_LIST_TRAVERSE(&translators, cur, entry)
@@ -406,7 +407,7 @@ static int unload_module(void)
 
 static int load_module(void)
 {
-       parse_config();
+       parse_config(0);
        find_transcoders();
 
        return 0;
index 856c5c2..ee80fcc 100644 (file)
@@ -746,12 +746,13 @@ static int load_module(void)
        int res = 0;
        struct ast_config *cfg;
        char *catg;
+       struct ast_flags config_flags = { 0 };
 
        res |= ast_custom_function_register(&fetch_function);
        res |= ast_register_application(app_odbcfinish, exec_odbcfinish, syn_odbcfinish, desc_odbcfinish);
        AST_LIST_LOCK(&queries);
 
-       cfg = ast_config_load(config);
+       cfg = ast_config_load(config, config_flags);
        if (!cfg) {
                ast_log(LOG_NOTICE, "Unable to load config for func_odbc: %s\n", config);
                AST_LIST_UNLOCK(&queries);
@@ -815,6 +816,11 @@ static int reload(void)
        struct ast_config *cfg;
        struct acf_odbc_query *oldquery;
        char *catg;
+       struct ast_flags config_flags = { CONFIG_FLAG_FILEUNCHANGED };
+
+       cfg = ast_config_load(config, config_flags);
+       if (cfg == CONFIG_STATUS_FILEUNCHANGED)
+               return 0;
 
        AST_LIST_LOCK(&queries);
 
@@ -824,7 +830,6 @@ static int reload(void)
                free_acf_query(oldquery);
        }
 
-       cfg = ast_config_load(config);
        if (!cfg) {
                ast_log(LOG_WARNING, "Unable to load config for func_odbc: %s\n", config);
                goto reload_out;
index 2df0a43..bbea0c4 100644 (file)
 extern "C" {
 #endif
 
+#include "asterisk/utils.h"
 #include <stdarg.h>
 
 struct ast_config;
 
 struct ast_category;
 
+/*! Options for ast_config_load()
+ */
+enum {
+       /*! Load the configuration, including comments */
+       CONFIG_FLAG_WITHCOMMENTS  = (1 << 0),
+       /*! On a reload, give us a -1 if the file hasn't changed. */
+       CONFIG_FLAG_FILEUNCHANGED = (1 << 1),
+       /*! Don't attempt to cache mtime on this config file. */
+       CONFIG_FLAG_NOCACHE       = (1 << 2),
+};
+
+#define        CONFIG_STATUS_FILEUNCHANGED     (void *)-1
+
 /*! \brief Structure for variables, used for configurations and for channel variables 
 */
 struct ast_variable {
@@ -47,7 +61,7 @@ struct ast_variable {
        char stuff[0];
 };
 
-typedef struct ast_config *config_load_func(const char *database, const char *table, const char *configfile, struct ast_config *config, int withcomments);
+typedef struct ast_config *config_load_func(const char *database, const char *table, const char *configfile, struct ast_config *config, struct ast_flags flags);
 typedef struct ast_variable *realtime_var_get(const char *database, const char *table, va_list ap);
 typedef struct ast_config *realtime_multi_get(const char *database, const char *table, va_list ap);
 typedef int realtime_update(const char *database, const char *table, const char *keyfield, const char *entity, va_list ap);
@@ -69,12 +83,15 @@ struct ast_config_engine {
 /*! \brief Load a config file 
  * \param filename path of file to open.  If no preceding '/' character, path is considered relative to AST_CONFIG_DIR
  * Create a config structure from a given configuration file.
+ * \param flags Optional flags:
+ * CONFIG_FLAG_WITHCOMMENTS - load the file with comments intact;
+ * CONFIG_FLAG_FILEUNCHANGED - check the file mtime and return CONFIG_STATUS_FILEUNCHANGED if the mtime is the same; or
+ * CONFIG_FLAG_NOCACHE - don't cache file mtime (main purpose of this option is to save memory on temporary files).
  *
  * \retval an ast_config data structure on success
  * \retval NULL on error
  */
-struct ast_config *ast_config_load(const char *filename);
-struct ast_config *ast_config_load_with_comments(const char *filename);
+struct ast_config *ast_config_load(const char *filename, struct ast_flags flags);
 
 /*! \brief Destroys a config 
  * \param config pointer to config data structure
@@ -240,7 +257,7 @@ int ast_variable_update(struct ast_category *category, const char *variable,
 
 int config_text_file_save(const char *filename, const struct ast_config *cfg, const char *generator);
 
-struct ast_config *ast_config_internal_load(const char *configfile, struct ast_config *cfg, int withcomments);
+struct ast_config *ast_config_internal_load(const char *configfile, struct ast_config *cfg, struct ast_flags flags);
 
 /*! \brief Support code to parse config file arguments
  *
index 118dd29..052bf62 100644 (file)
@@ -2290,13 +2290,14 @@ static void ast_readconfig(void)
        struct ast_variable *v;
        char *config = AST_CONFIG_FILE;
        char hostname[MAXHOSTNAMELEN] = "";
+       struct ast_flags config_flags = { 0 };
 
        if (ast_opt_override_config) {
-               cfg = ast_config_load(ast_config_AST_CONFIG_FILE);
+               cfg = ast_config_load(ast_config_AST_CONFIG_FILE, config_flags);
                if (!cfg)
                        ast_log(LOG_WARNING, "Unable to open specified master config file '%s', using built-in defaults\n", ast_config_AST_CONFIG_FILE);
        } else 
-               cfg = ast_config_load(config);
+               cfg = ast_config_load(config, config_flags);
 
        /* init with buildtime config */
        ast_copy_string(ast_config_AST_CONFIG_DIR, AST_CONFIG_DIR, sizeof(ast_config_AST_CONFIG_DIR));
index 6f0d75a..6cbb52f 100644 (file)
@@ -1281,7 +1281,7 @@ static struct ast_cli_entry cli_status = {
        "       Displays the Call Detail Record engine system status.\n"
 };
 
-static int do_reload(void)
+static int do_reload(int reload)
 {
        struct ast_config *config;
        const char *enabled_value;
@@ -1296,6 +1296,10 @@ static int do_reload(void)
        int was_enabled;
        int was_batchmode;
        int res=0;
+       struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
+
+       if ((config = ast_config_load("cdr.conf", config_flags)) == CONFIG_STATUS_FILEUNCHANGED)
+               return 0;
 
        ast_mutex_lock(&cdr_batch_lock);
 
@@ -1312,7 +1316,7 @@ static int do_reload(void)
        if (cdr_sched > -1)
                ast_sched_del(sched, cdr_sched);
 
-       if ((config = ast_config_load("cdr.conf"))) {
+       if (config) {
                if ((enabled_value = ast_variable_retrieve(config, "general", "enable"))) {
                        enabled = ast_true(enabled_value);
                }
@@ -1405,7 +1409,7 @@ int ast_cdr_engine_init(void)
 
        ast_cli_register(&cli_status);
 
-       res = do_reload();
+       res = do_reload(0);
        if (res) {
                ast_mutex_lock(&cdr_batch_lock);
                res = init_batch();
@@ -1424,6 +1428,6 @@ void ast_cdr_engine_term(void)
 
 int ast_cdr_engine_reload(void)
 {
-       return do_reload();
+       return do_reload(1);
 }
 
index 01c9c9a..1405423 100644 (file)
@@ -65,12 +65,27 @@ static char *extconfig_conf = "extconfig.conf";
 
 
 /*! \brief Structure to keep comments for rewriting configuration files */
-/*! \brief Structure to keep comments for rewriting configuration files */
 struct ast_comment {
        struct ast_comment *next;
        char cmt[0];
 };
 
+/*! \brief Hold the mtime for config files, so if we don't need to reread our config, don't. */
+struct cache_file_include {
+       AST_LIST_ENTRY(cache_file_include) list;
+       char include[0];
+};
+
+struct cache_file_mtime {
+       AST_LIST_ENTRY(cache_file_mtime) list;
+       AST_LIST_HEAD(includes, cache_file_include) includes;
+       unsigned int has_exec:1;
+       time_t mtime;
+       char filename[0];
+};
+
+static AST_LIST_HEAD_STATIC(cfmtime_head, cache_file_mtime);
+
 #define CB_INCR 250
 
 static void CB_INIT(char **comment_buffer, int *comment_buffer_size, char **lline_buffer, int *lline_buffer_size)
@@ -590,7 +605,58 @@ void ast_config_set_current_category(struct ast_config *cfg, const struct ast_ca
        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,
+enum config_cache_attribute_enum {
+       ATTRIBUTE_INCLUDE = 0,
+       ATTRIBUTE_EXEC = 1,
+};
+
+static void config_cache_attribute(const char *configfile, enum config_cache_attribute_enum attrtype, const char *filename)
+{
+       struct cache_file_mtime *cfmtime;
+       struct cache_file_include *cfinclude;
+       struct stat statbuf = { 0, };
+
+       /* Find our cached entry for this configuration file */
+       AST_LIST_LOCK(&cfmtime_head);
+       AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) {
+               if (!strcmp(cfmtime->filename, configfile))
+                       break;
+       }
+       if (!cfmtime) {
+               cfmtime = ast_calloc(1, sizeof(*cfmtime) + strlen(configfile) + 1);
+               if (!cfmtime) {
+                       AST_LIST_UNLOCK(&cfmtime_head);
+                       return;
+               }
+               AST_LIST_HEAD_INIT(&cfmtime->includes);
+               strcpy(cfmtime->filename, configfile);
+               /* Note that the file mtime is initialized to 0, i.e. 1970 */
+               AST_LIST_INSERT_TAIL(&cfmtime_head, cfmtime, list);
+       }
+
+       if (!stat(configfile, &statbuf))
+               cfmtime->mtime = 0;
+       else
+               cfmtime->mtime = statbuf.st_mtime;
+
+       switch (attrtype) {
+       case ATTRIBUTE_INCLUDE:
+               cfinclude = ast_calloc(1, sizeof(*cfinclude) + strlen(filename) + 1);
+               if (!cfinclude) {
+                       AST_LIST_UNLOCK(&cfmtime_head);
+                       return;
+               }
+               strcpy(cfinclude->include, filename);
+               AST_LIST_INSERT_TAIL(&cfmtime->includes, cfinclude, list);
+               break;
+       case ATTRIBUTE_EXEC:
+               cfmtime->has_exec = 1;
+               break;
+       }
+       AST_LIST_UNLOCK(&cfmtime_head);
+}
+
+static int process_text_line(struct ast_config *cfg, struct ast_category **cat, char *buf, int lineno, const char *configfile, struct ast_flags flags,
                                char **comment_buffer, int *comment_buffer_size, char **lline_buffer, int *lline_buffer_size)
 {
        char *c;
@@ -619,13 +685,13 @@ static int process_text_line(struct ast_config *cfg, struct ast_category **cat,
                        return -1;
                }
                /* add comments */
-               if (withcomments && *comment_buffer && (*comment_buffer)[0] ) {
+               if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && *comment_buffer && (*comment_buffer)[0] ) {
                        newcat->precomments = ALLOC_COMMENT(*comment_buffer);
                }
-               if (withcomments && *lline_buffer && (*lline_buffer)[0] ) {
+               if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && *lline_buffer && (*lline_buffer)[0] ) {
                        newcat->sameline = ALLOC_COMMENT(*lline_buffer);
                }
-               if ( withcomments )
+               if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS))
                        CB_RESET(comment_buffer, lline_buffer);
                
                /* If there are options or categories to inherit from, process them now */
@@ -702,15 +768,20 @@ static int process_text_line(struct ast_config *cfg, struct ast_category **cat,
                                }
                                /* #exec </path/to/executable>
                                   We create a tmp file, then we #include it, then we delete it. */
-                               if (do_exec) { 
+                               if (do_exec) {
+                                       if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE))
+                                               config_cache_attribute(configfile, ATTRIBUTE_EXEC, NULL);
                                        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
+                               } else {
+                                       if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE))
+                                               config_cache_attribute(configfile, ATTRIBUTE_INCLUDE, cur);
                                        exec_file[0] = '\0';
+                               }
                                /* A #include */
-                               do_include = ast_config_internal_load(cur, cfg, withcomments) ? 1 : 0;
+                               do_include = ast_config_internal_load(cur, cfg, flags) ? 1 : 0;
                                if (!ast_strlen_zero(exec_file))
                                        unlink(exec_file);
                                if (!do_include)
@@ -750,13 +821,13 @@ static int process_text_line(struct ast_config *cfg, struct ast_category **cat,
                                v->blanklines = 0;
                                ast_variable_append(*cat, v);
                                /* add comments */
-                               if (withcomments && *comment_buffer && (*comment_buffer)[0] ) {
+                               if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && *comment_buffer && (*comment_buffer)[0] ) {
                                        v->precomments = ALLOC_COMMENT(*comment_buffer);
                                }
-                               if (withcomments && *lline_buffer && (*lline_buffer)[0] ) {
+                               if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && *lline_buffer && (*lline_buffer)[0] ) {
                                        v->sameline = ALLOC_COMMENT(*lline_buffer);
                                }
-                               if ( withcomments )
+                               if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS))
                                        CB_RESET(comment_buffer, lline_buffer);
                                
                        } else {
@@ -769,7 +840,7 @@ static int process_text_line(struct ast_config *cfg, struct ast_category **cat,
        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)
+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)
 {
        char fn[256];
        char buf[8192];
@@ -780,6 +851,8 @@ static struct ast_config *config_text_file_load(const char *database, const char
        struct ast_category *cat = NULL;
        int count = 0;
        struct stat statbuf;
+       struct cache_file_mtime *cfmtime = NULL;
+       struct cache_file_include *cfinclude;
        /*! 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 */
@@ -787,8 +860,8 @@ static struct ast_config *config_text_file_load(const char *database, const char
        char *lline_buffer=0;    /*!< A buffer for stuff behind the ; */
        int  lline_buffer_size=0;
 
-       
-       cat = ast_config_get_current_category(cfg);
+       if (cfg)
+               cat = ast_config_get_current_category(cfg);
 
        if (filename[0] == '/') {
                ast_copy_string(fn, filename, sizeof(fn));
@@ -796,7 +869,7 @@ static struct ast_config *config_text_file_load(const char *database, const char
                snprintf(fn, sizeof(fn), "%s/%s", (char *)ast_config_AST_CONFIG_DIR, filename);
        }
 
-       if (withcomments) {
+       if (ast_test_flag(&flags, CONFIG_FLAG_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");
@@ -833,6 +906,77 @@ static struct ast_config *config_text_file_load(const char *database, const char
                        ast_log(LOG_WARNING, "'%s' is not a regular file, ignoring\n", fn);
                        continue;
                }
+
+               if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE)) {
+                       /* Find our cached entry for this configuration file */
+                       AST_LIST_LOCK(&cfmtime_head);
+                       AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) {
+                               if (!strcmp(cfmtime->filename, fn))
+                                       break;
+                       }
+                       if (!cfmtime) {
+                               cfmtime = ast_calloc(1, sizeof(*cfmtime) + strlen(fn) + 1);
+                               if (!cfmtime)
+                                       continue;
+                               AST_LIST_HEAD_INIT(&cfmtime->includes);
+                               strcpy(cfmtime->filename, fn);
+                               /* Note that the file mtime is initialized to 0, i.e. 1970 */
+                               AST_LIST_INSERT_TAIL(&cfmtime_head, cfmtime, list);
+                       }
+               }
+
+               if (cfmtime && (!cfmtime->has_exec) && (cfmtime->mtime == statbuf.st_mtime) && ast_test_flag(&flags, CONFIG_FLAG_FILEUNCHANGED)) {
+                       /* File is unchanged, what about the (cached) includes (if any)? */
+                       int unchanged = 1;
+                       AST_LIST_TRAVERSE(&cfmtime->includes, cfinclude, list) {
+                               /* We must glob here, because if we did not, then adding a file to globbed directory would
+                                * incorrectly cause no reload to be necessary. */
+                               char fn2[256];
+#ifdef AST_INCLUDE_GLOB
+                               int glob_ret;
+                               glob_t globbuf = { .gl_offs = 0 };
+#ifdef SOLARIS
+                               glob_ret = glob(cfinclude->include, GLOB_NOCHECK, NULL, &globbuf);
+#else
+                               glob_ret = glob(cfinclude->include, GLOB_NOMAGIC|GLOB_BRACE, NULL, &globbuf);
+#endif
+                               /* On error, we reparse */
+                               if (glob_ret == GLOB_NOSPACE || glob_ret  == GLOB_ABORTED)
+                                       unchanged = 0;
+                               else  {
+                                       /* loop over expanded files */
+                                       int j;
+                                       for (j = 0; j < globbuf.gl_pathc; j++) {
+                                               ast_copy_string(fn2, globbuf.gl_pathv[j], sizeof(fn2));
+#else
+                                               ast_copy_string(fn2, cfinclude->include);
+#endif
+                                               if (config_text_file_load(NULL, NULL, fn2, NULL, flags) == NULL) {
+                                                       unchanged = 0;
+                                                       /* One change is enough to short-circuit and reload the whole shebang */
+                                                       break;
+                                               }
+#ifdef AST_INCLUDE_GLOB
+                                       }
+                               }
+#endif
+                       }
+
+                       if (unchanged) {
+                               AST_LIST_UNLOCK(&cfmtime_head);
+                               return CONFIG_STATUS_FILEUNCHANGED;
+                       }
+               }
+               if (cfmtime)
+                       AST_LIST_UNLOCK(&cfmtime_head);
+
+               /* If cfg is NULL, then we just want an answer */
+               if (cfg == NULL)
+                       return NULL;
+
+               if (cfmtime)
+                       cfmtime->mtime = statbuf.st_mtime;
+
                ast_verb(2, "Parsing '%s': ", fn);
                        fflush(stdout);
                if (!(f = fopen(fn, "r"))) {
@@ -846,7 +990,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 (ast_test_flag(&flags, CONFIG_FLAG_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 */
                                }
@@ -883,7 +1027,7 @@ static struct ast_config *config_text_file_load(const char *database, const char
                                                                /* Actually have to move what's left over the top, then continue */
                                                                char *oldptr;
                                                                oldptr = process_buf + strlen(process_buf);
-                                                               if ( withcomments ) {
+                                                               if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) {
                                                                        CB_ADD(&comment_buffer, &comment_buffer_size, ";");
                                                                        CB_ADD_LEN(&comment_buffer, &comment_buffer_size, oldptr+1, new_buf-oldptr-1);
                                                                }
@@ -897,7 +1041,7 @@ static struct ast_config *config_text_file_load(const char *database, const char
                                                if (!comment) {
                                                        /* If ; is found, and we are not nested in a comment, 
                                                           we immediately stop all comment processing */
-                                                       if ( withcomments ) {
+                                                       if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) {
                                                                LLB_ADD(&lline_buffer, &lline_buffer_size, comment_p);
                                                        }
                                                        *comment_p = '\0'; 
@@ -906,7 +1050,7 @@ static struct ast_config *config_text_file_load(const char *database, const char
                                                        new_buf = comment_p + 1;
                                        }
                                }
-                               if ( withcomments && comment && !process_buf )
+                               if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment && !process_buf )
                                {
                                        CB_ADD(&comment_buffer, &comment_buffer_size, buf);  /* the whole line is a comment, store it */
                                }
@@ -914,7 +1058,7 @@ static struct ast_config *config_text_file_load(const char *database, const char
                                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)) {
+                                               if (process_text_line(cfg, &cat, buf, lineno, fn, flags, &comment_buffer, &comment_buffer_size, &lline_buffer, &lline_buffer_size)) {
                                                        cfg = NULL;
                                                        break;
                                                }
@@ -928,7 +1072,7 @@ static struct ast_config *config_text_file_load(const char *database, const char
                ast_log(LOG_WARNING,"Unterminated comment detected beginning on line %d\n", nest[comment - 1]);
        }
 #ifdef AST_INCLUDE_GLOB
-                                       if (!cfg)
+                                       if (cfg == NULL || cfg == CONFIG_STATUS_FILEUNCHANGED)
                                                break;
                                }
                                globfree(&globbuf);
@@ -936,7 +1080,7 @@ static struct ast_config *config_text_file_load(const char *database, const char
                }
 #endif
 
-       if (cfg && cfg->include_level == 1 && withcomments && comment_buffer) {
+       if (cfg && cfg != CONFIG_STATUS_FILEUNCHANGED && cfg->include_level == 1 && ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment_buffer) {
                ast_free(comment_buffer);
                ast_free(lline_buffer);
                comment_buffer = NULL;
@@ -1090,12 +1234,13 @@ int read_config_maps(void)
        struct ast_config *config, *configtmp;
        struct ast_variable *v;
        char *driver, *table, *database, *stringp, *tmp;
+       struct ast_flags flags = { 0 };
 
        clear_config_maps();
 
        configtmp = ast_config_new();
        configtmp->max_include_level = 1;
-       config = ast_config_internal_load(extconfig_conf, configtmp, 0);
+       config = ast_config_internal_load(extconfig_conf, configtmp, flags);
        if (!config) {
                ast_config_destroy(configtmp);
                return 0;
@@ -1234,7 +1379,7 @@ static struct ast_config_engine text_file_engine = {
        .load_func = config_text_file_load,
 };
 
-struct ast_config *ast_config_internal_load(const char *filename, struct ast_config *cfg, int withcomments)
+struct ast_config *ast_config_internal_load(const char *filename, struct ast_config *cfg, struct ast_flags flags)
 {
        char db[256];
        char table[256];
@@ -1263,9 +1408,9 @@ struct ast_config *ast_config_internal_load(const char *filename, struct ast_con
                }
        }
 
-       result = loader->load_func(db, table, filename, cfg, withcomments);
+       result = loader->load_func(db, table, filename, cfg, flags);
 
-       if (result)
+       if (result && result != CONFIG_STATUS_FILEUNCHANGED)
                result->include_level--;
        else
                cfg->include_level--;
@@ -1273,23 +1418,7 @@ struct ast_config *ast_config_internal_load(const char *filename, struct ast_con
        return result;
 }
 
-struct ast_config *ast_config_load(const char *filename)
-{
-       struct ast_config *cfg;
-       struct ast_config *result;
-
-       cfg = ast_config_new();
-       if (!cfg)
-               return NULL;
-
-       result = ast_config_internal_load(filename, cfg, 0);
-       if (!result)
-               ast_config_destroy(cfg);
-
-       return result;
-}
-
-struct ast_config *ast_config_load_with_comments(const char *filename)
+struct ast_config *ast_config_load(const char *filename, struct ast_flags flags)
 {
        struct ast_config *cfg;
        struct ast_config *result;
@@ -1298,8 +1427,8 @@ struct ast_config *ast_config_load_with_comments(const char *filename)
        if (!cfg)
                return NULL;
 
-       result = ast_config_internal_load(filename, cfg, 1);
-       if (!result)
+       result = ast_config_internal_load(filename, cfg, flags);
+       if (!result || result == CONFIG_STATUS_FILEUNCHANGED)
                ast_config_destroy(cfg);
 
        return result;
index d3eb9a5..d1e5dd3 100644 (file)
@@ -349,12 +349,16 @@ int dnsmgr_reload(void)
 static int do_reload(int loading)
 {
        struct ast_config *config;
+       struct ast_flags config_flags = { loading ? 0 : CONFIG_FLAG_FILEUNCHANGED };
        const char *interval_value;
        const char *enabled_value;
        int interval;
        int was_enabled;
        int res = -1;
 
+       if ((config = ast_config_load("dnsmgr.conf", config_flags)) == CONFIG_STATUS_FILEUNCHANGED)
+               return 0;
+
        /* ensure that no refresh cycles run while the reload is in progress */
        ast_mutex_lock(&refresh_lock);
 
@@ -366,7 +370,7 @@ static int do_reload(int loading)
        if (refresh_sched > -1)
                ast_sched_del(sched, refresh_sched);
 
-       if ((config = ast_config_load("dnsmgr.conf"))) {
+       if (config) {
                if ((enabled_value = ast_variable_retrieve(config, "general", "enable"))) {
                        enabled = ast_true(enabled_value);
                }
index cf298a6..9e771b9 100644 (file)
@@ -605,11 +605,15 @@ static struct enum_search *enum_newtoplev(char *s)
 }
 
 /*! \brief Initialize the ENUM support subsystem */
-int ast_enum_init(void)
+static int private_enum_init(int reload)
 {
        struct ast_config *cfg;
        struct enum_search *s, *sl;
        struct ast_variable *v;
+       struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
+
+       if ((cfg = ast_config_load("enum.conf", config_flags)) == CONFIG_STATUS_FILEUNCHANGED)
+               return 0;
 
        /* Destroy existing list */
        ast_mutex_lock(&enumlock);
@@ -620,7 +624,6 @@ int ast_enum_init(void)
                ast_free(sl);
        }
        toplevs = NULL;
-       cfg = ast_config_load("enum.conf");
        if (cfg) {
                sl = NULL;
                v = ast_variable_browse(cfg, "general");
@@ -646,7 +649,12 @@ int ast_enum_init(void)
        return 0;
 }
 
+int ast_enum_init(void)
+{
+       return private_enum_init(0);
+}
+
 int ast_enum_reload(void)
 {
-       return ast_enum_init();
+       return private_enum_init(1);
 }
index b61858c..b4aac26 100644 (file)
@@ -1134,6 +1134,10 @@ static int __ast_http_load(int reload)
        char newprefix[MAX_PREFIX];
        int have_sslbindaddr = 0;
        struct http_uri_redirect *redirect;
+       struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
+
+       if ((cfg = ast_config_load("http.conf", config_flags)) == CONFIG_STATUS_FILEUNCHANGED)
+               return 0;
 
        /* default values */
        memset(&http_desc.sin, 0, sizeof(http_desc.sin));
@@ -1159,7 +1163,6 @@ static int __ast_http_load(int reload)
 
        destroy_post_mappings();
 
-       cfg = ast_config_load("http.conf");
        if (cfg) {
                v = ast_variable_browse(cfg, "general");
                for (; v; v = v->next) {
index f3db684..359d732 100644 (file)
@@ -731,6 +731,7 @@ int load_modules(unsigned int preload_only)
        unsigned int load_count;
        struct load_order load_order;
        int res = 0;
+       struct ast_flags config_flags = { 0 };
 #if LOADABLE_MODULES
        struct dirent *dirent;
        DIR *dir;
@@ -745,7 +746,7 @@ int load_modules(unsigned int preload_only)
 
        AST_LIST_LOCK(&module_list);
 
-       if (!(cfg = ast_config_load(AST_MODULE_CONFIG))) {
+       if (!(cfg = ast_config_load(AST_MODULE_CONFIG, config_flags))) {
                ast_log(LOG_WARNING, "No '%s' found, no modules will be loaded.\n", AST_MODULE_CONFIG);
                goto done;
        }
index 209da21..fff798a 100644 (file)
@@ -305,12 +305,16 @@ static struct logchannel *make_logchannel(char *channel, char *components, int l
        return chan;
 }
 
-static void init_logger_chain(void)
+static void init_logger_chain(int reload)
 {
        struct logchannel *chan;
        struct ast_config *cfg;
        struct ast_variable *var;
        const char *s;
+       struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
+
+       if ((cfg = ast_config_load("logger.conf", config_flags)) == CONFIG_STATUS_FILEUNCHANGED)
+               return;
 
        /* delete our list of log channels */
        AST_RWLIST_WRLOCK(&logchannels);
@@ -323,8 +327,6 @@ static void init_logger_chain(void)
        /* close syslog */
        closelog();
        
-       cfg = ast_config_load("logger.conf");
-       
        /* If no config file, we're fine, set default options. */
        if (!cfg) {
                if (errno)
@@ -454,7 +456,7 @@ int reload_logger(int rotate)
 
        filesize_reload_needed = 0;
        
-       init_logger_chain();
+       init_logger_chain(1);
 
        if (logfiles.event_log) {
                snprintf(old, sizeof(old), "%s/%s", ast_config_AST_LOG_DIR, EVENTLOG);
@@ -802,7 +804,7 @@ int init_logger(void)
        ast_mkdir(ast_config_AST_LOG_DIR, 0777);
   
        /* create log channels */
-       init_logger_chain();
+       init_logger_chain(0);
 
        /* create the eventlog */
        if (logfiles.event_log) {
index 69c8092..9abb6c5 100644 (file)
@@ -954,6 +954,7 @@ static int authenticate(struct mansession *s, const struct message *m)
        struct ast_ha *ha = NULL;
        char *password = NULL;
        int readperm = 0, writeperm = 0;
+       struct ast_flags config_flags = { 0 };
 
        if (ast_strlen_zero(user))      /* missing username */
                return -1;
@@ -964,7 +965,7 @@ static int authenticate(struct mansession *s, const struct message *m)
         * suffices to call get_manager_by_name_locked() to fetch
         * the user's entry.
         */
-       struct ast_config *cfg = ast_config_load("manager.conf");
+       struct ast_config *cfg = ast_config_load("manager.conf", config_flags);
        char *cat = NULL;
        struct ast_variable *v;
 
@@ -1001,7 +1002,7 @@ static int authenticate(struct mansession *s, const struct message *m)
        if (!cat) {
                /* Didn't find the user in manager.conf, check users.conf */
                int hasmanager = 0;
-               cfg = ast_config_load("users.conf");
+               cfg = ast_config_load("users.conf", config_flags);
                if (!cfg)
                        return -1;
                while ( (cat = ast_category_browse(cfg, cat)) ) {
@@ -1117,12 +1118,13 @@ static int action_getconfig(struct mansession *s, const struct message *m)
        int lineno = 0;
        char *category=NULL;
        struct ast_variable *v;
+       struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
 
        if (ast_strlen_zero(fn)) {
                astman_send_error(s, m, "Filename not specified");
                return 0;
        }
-       if (!(cfg = ast_config_load_with_comments(fn))) {
+       if (!(cfg = ast_config_load(fn, config_flags))) {
                astman_send_error(s, m, "Config file not found");
                return 0;
        }
@@ -1167,13 +1169,14 @@ static int action_getconfigjson(struct mansession *s, const struct message *m)
        int comma1 = 0;
        char *buf = NULL;
        unsigned int buf_len = 0;
+       struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
 
        if (ast_strlen_zero(fn)) {
                astman_send_error(s, m, "Filename not specified");
                return 0;
        }
 
-       if (!(cfg = ast_config_load_with_comments(fn))) {
+       if (!(cfg = ast_config_load(fn, config_flags))) {
                astman_send_error(s, m, "Config file not found");
                return 0;
        }
@@ -1302,12 +1305,13 @@ static int action_updateconfig(struct mansession *s, const struct message *m)
        const char *dfn = astman_get_header(m, "DstFilename");
        int res;
        const char *rld = astman_get_header(m, "Reload");
+       struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
 
        if (ast_strlen_zero(sfn) || ast_strlen_zero(dfn)) {
                astman_send_error(s, m, "Filename not specified");
                return 0;
        }
-       if (!(cfg = ast_config_load_with_comments(sfn))) {
+       if (!(cfg = ast_config_load(sfn, config_flags))) {
                astman_send_error(s, m, "Config file not found");
                return 0;
        }
@@ -3246,7 +3250,7 @@ static struct server_args amis_desc = {
         .worker_fn = session_do,       /* thread handling the session */
 };
 
-int init_manager(void)
+static int __init_manager(int reload)
 {
        struct ast_config *cfg = NULL;
        const char *val;
@@ -3257,6 +3261,7 @@ int init_manager(void)
        struct ast_hostent ahp;
        struct ast_manager_user *user = NULL;
        struct ast_variable *var;
+       struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
 
        if (!registered) {
                /* Register default actions */
@@ -3292,8 +3297,10 @@ int init_manager(void)
                /* Append placeholder event so master_eventq never runs dry */
                append_event("Event: Placeholder\r\n\r\n", 0);
        }
+       if ((cfg = ast_config_load("manager.conf", config_flags)) == CONFIG_STATUS_FILEUNCHANGED)
+               return 0;
+
        displayconnects = 1;
-       cfg = ast_config_load("manager.conf");
        if (!cfg) {
                ast_log(LOG_NOTICE, "Unable to open management configuration manager.conf.  Call management disabled.\n");
                return 0;
@@ -3474,8 +3481,13 @@ int init_manager(void)
        return 0;
 }
 
+int init_manager(void)
+{
+       return __init_manager(0);
+}
+
 int reload_manager(void)
 {
        manager_event(EVENT_FLAG_SYSTEM, "Reload", "Message: Reload Requested\r\n");
-       return init_manager();
+       return __init_manager(1);
 }
index 7f81ed7..2ff4440 100644 (file)
@@ -3997,15 +3997,18 @@ static struct ast_cli_entry cli_rtp[] = {
        stun_no_debug_usage },
 };
 
-int ast_rtp_reload(void)
+static int __ast_rtp_reload(int reload)
 {
        struct ast_config *cfg;
        const char *s;
+       struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
+
+       if ((cfg = ast_config_load("rtp.conf", config_flags)) == CONFIG_STATUS_FILEUNCHANGED)
+               return 0;
 
        rtpstart = 5000;
        rtpend = 31000;
        dtmftimeout = DEFAULT_DTMF_TIMEOUT;
-       cfg = ast_config_load("rtp.conf");
        if (cfg) {
                if ((s = ast_variable_retrieve(cfg, "general", "rtpstart"))) {
                        rtpstart = atoi(s);
@@ -4060,10 +4063,15 @@ int ast_rtp_reload(void)
        return 0;
 }
 
+int ast_rtp_reload(void)
+{
+       return __ast_rtp_reload(1);
+}
+
 /*! \brief Initialize the RTP system in Asterisk */
 void ast_rtp_init(void)
 {
        ast_cli_register_multiple(cli_rtp, sizeof(cli_rtp) / sizeof(struct ast_cli_entry));
-       ast_rtp_reload();
+       __ast_rtp_reload(0);
 }
 
index 2385679..d3c6163 100644 (file)
@@ -1183,10 +1183,14 @@ static struct ast_cli_entry cli_udptl[] = {
        nodebug_usage },
 };
 
-void ast_udptl_reload(void)
+static void __ast_udptl_reload(int reload)
 {
        struct ast_config *cfg;
        const char *s;
+       struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
+
+       if ((cfg = ast_config_load("udptl.conf", config_flags)) == CONFIG_STATUS_FILEUNCHANGED)
+               return;
 
        udptlstart = 4500;
        udptlend = 4999;
@@ -1195,7 +1199,7 @@ void ast_udptl_reload(void)
        udptlfecspan = 0;
        udptlmaxdatagram = 0;
 
-       if ((cfg = ast_config_load("udptl.conf"))) {
+       if (cfg) {
                if ((s = ast_variable_retrieve(cfg, "general", "udptlstart"))) {
                        udptlstart = atoi(s);
                        if (udptlstart < 1024)
@@ -1258,8 +1262,13 @@ void ast_udptl_reload(void)
        ast_verb(2, "UDPTL allocating from port range %d -> %d\n", udptlstart, udptlend);
 }
 
+void ast_udptl_reload(void)
+{
+       __ast_udptl_reload(1);
+}
+
 void ast_udptl_init(void)
 {
        ast_cli_register_multiple(cli_udptl, sizeof(cli_udptl) / sizeof(struct ast_cli_entry));
-       ast_udptl_reload();
+       __ast_udptl_reload(0);
 }
index a6b4e01..77862d0 100644 (file)
@@ -722,6 +722,7 @@ static int handle_save_dialplan(int fd, int argc, char *argv[])
        struct ast_variable *v;
        int incomplete = 0; /* incomplete config write? */
        FILE *output;
+       struct ast_flags config_flags = { 0 };
 
        const char *base, *slash, *file;
 
@@ -761,7 +762,7 @@ static int handle_save_dialplan(int fd, int argc, char *argv[])
        }
        snprintf(filename, sizeof(filename), "%s%s%s", base, slash, config);
 
-       cfg = ast_config_load("extensions.conf");
+       cfg = ast_config_load("extensions.conf", config_flags);
 
        /* try to lock contexts list */
        if (ast_rdlock_contexts()) {
@@ -1329,8 +1330,9 @@ static int pbx_load_config(const char *config_file)
        struct ast_variable *v;
        const char *cxt;
        const char *aft;
+       struct ast_flags config_flags = { 0 };
 
-       cfg = ast_config_load(config_file);
+       cfg = ast_config_load(config_file, config_flags);
        if (!cfg)
                return 0;
 
@@ -1501,8 +1503,9 @@ static void pbx_load_users(void)
        int hasvoicemail;
        int start, finish, x;
        struct ast_context *con;
+       struct ast_flags config_flags = { 0 };
        
-       cfg = ast_config_load("users.conf");
+       cfg = ast_config_load("users.conf", config_flags);
        if (!cfg)
                return;
        con = ast_context_find_or_create(&local_contexts, userscontext, registrar);
index c077f4d..7d3fd82 100644 (file)
@@ -4555,13 +4555,14 @@ static struct ast_switch dundi_switch =
         matchmore:              dundi_matchmore,
 };
 
-static int set_config(char *config_file, struct sockaddr_in* sin)
+static int set_config(char *config_file, struct sockaddr_in* sin, int reload)
 {
        struct ast_config *cfg;
        struct ast_variable *v;
        char *cat;
        int format;
        int x;
+       struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
        char hn[MAXHOSTNAMELEN] = "";
        struct ast_hostent he;
        struct hostent *hp;
@@ -4570,11 +4571,12 @@ static int set_config(char *config_file, struct sockaddr_in* sin)
        int globalpcmodel = 0;
        dundi_eid testeid;
 
+       if ((cfg = ast_config_load(config_file, config_flags)) == CONFIG_STATUS_FILEUNCHANGED)
+               return 0;
+
        dundi_ttl = DUNDI_DEFAULT_TTL;
        dundi_cache_time = DUNDI_DEFAULT_CACHE_TIME;
-       cfg = ast_config_load(config_file);
-       
-       
+
        if (!cfg) {
                ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
                return -1;
@@ -4741,7 +4743,7 @@ static int reload(void)
 {
        struct sockaddr_in sin;
 
-       if (set_config("dundi.conf", &sin))
+       if (set_config("dundi.conf", &sin, 1))
                return -1;
 
        return 0;
@@ -4765,7 +4767,7 @@ static int load_module(void)
        if (!io || !sched)
                return AST_MODULE_LOAD_FAILURE;
 
-       if (set_config("dundi.conf", &sin))
+       if (set_config("dundi.conf", &sin, 0))
                return AST_MODULE_LOAD_DECLINE;
 
        netsocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
index 28ff200..21f1d89 100644 (file)
@@ -1067,9 +1067,10 @@ static void adsi_load(void)
        int x;
        struct ast_config *conf;
        struct ast_variable *v;
+       struct ast_flags config_flags = { 0 };
        char *name, *sname;
        init_state();
-       conf = ast_config_load("adsi.conf");
+       conf = ast_config_load("adsi.conf", config_flags);
        if (conf) {
                x=0;
                for (v = ast_variable_browse(conf, "intro"); v; v = v->next) {
index 5a9ad5c..6388ab7 100644 (file)
@@ -486,7 +486,7 @@ static SQLHSTMT config_odbc_prepare(struct odbc_obj *obj, void *data)
        return sth;
 }
 
-static struct ast_config *config_odbc(const char *database, const char *table, const char *file, struct ast_config *cfg, int withcomments)
+static struct ast_config *config_odbc(const char *database, const char *table, const char *file, struct ast_config *cfg, struct ast_flags flags)
 {
        struct ast_variable *new_v;
        struct ast_category *cur_cat;
@@ -500,6 +500,7 @@ static struct ast_config *config_odbc(const char *database, const char *table, c
        SQLHSTMT stmt;
        char last[128] = "";
        struct config_odbc_obj q;
+       struct ast_flags loader_flags = { 0 };
 
        memset(&q, 0, sizeof(q));
 
@@ -542,7 +543,7 @@ static struct ast_config *config_odbc(const char *database, const char *table, c
 
        while ((res = SQLFetch(stmt)) != SQL_NO_DATA) {
                if (!strcmp (q.var_name, "#include")) {
-                       if (!ast_config_internal_load(q.var_val, cfg, 0)) {
+                       if (!ast_config_internal_load(q.var_val, cfg, loader_flags)) {
                                SQLFreeHandle(SQL_HANDLE_STMT, stmt);
                                ast_odbc_release_obj(obj);
                                return NULL;
index 2fb0a0e..c3e9777 100644 (file)
@@ -62,7 +62,7 @@ static char dbsock[MAX_DB_OPTION_SIZE] = "";
 static int dbport = 5432;
 static time_t connect_time = 0;
 
-static int parse_config(void);
+static int parse_config(int reload);
 static int pgsql_reconnect(const char *database);
 static int realtime_pgsql_status(int fd, int argc, char **argv);
 
@@ -431,7 +431,7 @@ static int update_pgsql(const char *database, const char *table, const char *key
 
 static struct ast_config *config_pgsql(const char *database, const char *table,
                                           const char *file, struct ast_config *cfg,
-                                          int withcomments)
+                                          struct ast_flags flags)
 {
        PGresult *result = NULL;
        long num_rows;
@@ -496,7 +496,7 @@ static struct ast_config *config_pgsql(const char *database, const char *table,
                        char *field_var_val = PQgetvalue(result, rowIndex, 2);
                        char *field_cat_metric = PQgetvalue(result, rowIndex, 3);
                        if (!strcmp(field_var_name, "#include")) {
-                               if (!ast_config_internal_load(field_var_val, cfg, 0)) {
+                               if (!ast_config_internal_load(field_var_val, cfg, flags)) {
                                        PQclear(result);
                                        ast_mutex_unlock(&pgsql_lock);
                                        return NULL;
@@ -536,35 +536,25 @@ static struct ast_config_engine pgsql_engine = {
 
 static int load_module(void)
 {
-       if(!parse_config())
+       if(!parse_config(0))
                return AST_MODULE_LOAD_DECLINE;
 
-       ast_mutex_lock(&pgsql_lock);
-
-       if (!pgsql_reconnect(NULL)) {
-               ast_log(LOG_WARNING,
-                               "Postgresql RealTime: Couldn't establish connection. Check debug.\n");
-               ast_debug(1, "Postgresql RealTime: Cannot Connect: %s\n", PQerrorMessage(pgsqlConn));
-       }
-
        ast_config_engine_register(&pgsql_engine);
        ast_verb(1, "Postgresql RealTime driver loaded.\n");
        ast_cli_register_multiple(cli_realtime, sizeof(cli_realtime) / sizeof(struct ast_cli_entry));
 
-       ast_mutex_unlock(&pgsql_lock);
-
        return 0;
 }
 
 static int unload_module(void)
 {
-       /* Aquire control before doing anything to the module itself. */
+       /* Acquire control before doing anything to the module itself. */
        ast_mutex_lock(&pgsql_lock);
 
        if (pgsqlConn) {
                PQfinish(pgsqlConn);
                pgsqlConn = NULL;
-       };
+       }
        ast_cli_unregister_multiple(cli_realtime, sizeof(cli_realtime) / sizeof(struct ast_cli_entry));
        ast_config_engine_deregister(&pgsql_engine);
        ast_verb(1, "Postgresql RealTime unloaded.\n");
@@ -577,40 +567,32 @@ static int unload_module(void)
 
 static int reload(void)
 {
-       /* Aquire control before doing anything to the module itself. */
-       ast_mutex_lock(&pgsql_lock);
-
-       if (pgsqlConn) {
-               PQfinish(pgsqlConn);
-               pgsqlConn = NULL;
-       };
-       parse_config();
-
-       if (!pgsql_reconnect(NULL)) {
-               ast_log(LOG_WARNING,
-                               "Postgresql RealTime: Couldn't establish connection. Check debug.\n");
-               ast_debug(1, "Postgresql RealTime: Cannot Connect: %s\n", PQerrorMessage(pgsqlConn));
-       }
-
-       ast_verb(2, "Postgresql RealTime reloaded.\n");
-
-       /* Done reloading. Release lock so others can now use driver. */
-       ast_mutex_unlock(&pgsql_lock);
+       parse_config(1);
 
        return 0;
 }
 
-static int parse_config(void)
+static int parse_config(int reload)
 {
        struct ast_config *config;
        const char *s;
+       struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
 
-       config = ast_config_load(RES_CONFIG_PGSQL_CONF);
+       if ((config = ast_config_load(RES_CONFIG_PGSQL_CONF, config_flags)) == CONFIG_STATUS_FILEUNCHANGED)
+               return 0;
 
        if (!config) {
-               ast_log(LOG_WARNING, "Unable to load config %s\n",RES_CONFIG_PGSQL_CONF);
+               ast_log(LOG_WARNING, "Unable to load config %s\n", RES_CONFIG_PGSQL_CONF);
                return 0;
        }
+
+       ast_mutex_lock(&pgsql_lock);
+
+       if (pgsqlConn) {
+               PQfinish(pgsqlConn);
+               pgsqlConn = NULL;
+       }
+
        if (!(s = ast_variable_retrieve(config, "general", "dbuser"))) {
                ast_log(LOG_WARNING,
                                "Postgresql RealTime: No database user found, using 'asterisk' as default.\n");
@@ -672,6 +654,17 @@ static int parse_config(void)
                ast_debug(1, "Postgresql RealTime DBName: %s\n", dbname);
        }
 
+       if (!pgsql_reconnect(NULL)) {
+               ast_log(LOG_WARNING,
+                               "Postgresql RealTime: Couldn't establish connection. Check debug.\n");
+               ast_debug(1, "Postgresql RealTime: Cannot Connect: %s\n", PQerrorMessage(pgsqlConn));
+       }
+
+       ast_verb(2, "Postgresql RealTime reloaded.\n");
+
+       /* Done reloading. Release lock so others can now use driver. */
+       ast_mutex_unlock(&pgsql_lock);
+
        return 1;
 }
 
index c9c65f8..fd28ef6 100644 (file)
@@ -300,14 +300,14 @@ static int add_cfg_entry(void *arg, int argc, char **argv, char **columnNames);
  * \param table the table to use
  * \param file the file to load from the database
  * \param cfg the struct ast_config object to use when storing variables
- * \param withcomments Integer. Flag
+ * \param flags Optional flags.  Not used.
  * \retval cfg object
  * \retval NULL if an error occurred
  * \see add_cfg_entry()
  */
 static struct ast_config * config_handler(const char *database,
        const char *table, const char *file,
-       struct ast_config *cfg, int withcomments);
+       struct ast_config *cfg, struct ast_flags flags);
 
 /*!
  * \brief Helper function to parse a va_list object into 2 dynamic arrays of
@@ -611,8 +611,9 @@ static int load_config(void)
        struct ast_config *config;
        struct ast_variable *var;
        int error;
+       struct ast_flags config_flags = { 0 };
 
-       config = ast_config_load(RES_SQLITE_CONF_FILE);
+       config = ast_config_load(RES_SQLITE_CONF_FILE, config_flags);
 
        if (!config) {
                ast_log(LOG_ERROR, "Unable to load " RES_SQLITE_CONF_FILE "\n");
@@ -725,7 +726,7 @@ static int add_cfg_entry(void *arg, int argc, char **argv, char **columnNames)
 }
 
 static struct ast_config *config_handler(const char *database, 
-       const char *table, const char *file, struct ast_config *cfg, int withcomments)
+       const char *table, const char *file, struct ast_config *cfg, struct ast_flags flags)
 {
        struct cfg_entry_args args;
        char *errormsg;
index 70cf1ec..08cedc0 100644 (file)
@@ -2768,6 +2768,7 @@ static int load_config(void)
        struct ast_config *cfg = NULL;
        struct ast_variable *var = NULL;
        struct feature_group *fg = NULL;
+       struct ast_flags config_flags = { 0 };
        char old_parking_ext[AST_MAX_EXTENSION];
        char old_parking_con[AST_MAX_EXTENSION] = "";
        char *ctg; 
@@ -2810,7 +2811,7 @@ static int load_config(void)
        atxferdropcall = DEFAULT_ATXFER_DROP_CALL;
        atxfercallbackretries = DEFAULT_ATXFER_CALLBACK_RETRIES;
 
-       cfg = ast_config_load("features.conf");
+       cfg = ast_config_load("features.conf", config_flags);
        if (!cfg) {
                ast_log(LOG_WARNING,"Could not load features.conf\n");
                return AST_MODULE_LOAD_DECLINE;
index 2a4f38a..e12b6f9 100644 (file)
@@ -236,7 +236,7 @@ static int handle_stopplaytones(struct ast_channel *chan, void *data)
 }
 
 /*! \brief load indications module */
-static int ind_load_module(void)
+static int ind_load_module(int reload)
 {
        struct ast_config *cfg;
        struct ast_variable *v;
@@ -244,12 +244,18 @@ static int ind_load_module(void)
        char *c;
        struct ind_tone_zone *tones;
        const char *country = NULL;
+       struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
 
        /* that the following cast is needed, is yuk! */
        /* yup, checked it out. It is NOT written to. */
-       cfg = ast_config_load((char *)config);
+       cfg = ast_config_load((char *)config, config_flags);
        if (!cfg)
                return -1;
+       else if (cfg == CONFIG_STATUS_FILEUNCHANGED)
+               return 0;
+
+       if (reload)
+               ast_unregister_indication_country(NULL);
 
        /* Use existing config to populate the Indication table */
        cxt = ast_category_browse(cfg, NULL);
@@ -385,7 +391,7 @@ static int unload_module(void)
 /*! \brief Load indications module */
 static int load_module(void)
 {
-       if (ind_load_module())
+       if (ind_load_module(0))
                return AST_MODULE_LOAD_DECLINE; 
        ast_cli_register_multiple(cli_indications, sizeof(cli_indications) / sizeof(struct ast_cli_entry));
        ast_register_application("PlayTones", handle_playtones, "Play a tone list", playtones_desc);
@@ -397,10 +403,7 @@ static int load_module(void)
 /*! \brief Reload indications module */
 static int reload(void)
 {
-       /* remove the registed indications... */
-       ast_unregister_indication_country(NULL);
-
-       return ind_load_module();
+       return ind_load_module(1);
 }
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS, "Region-specific tones",
index 6653efe..8410bf2 100644 (file)
@@ -94,8 +94,8 @@ static int aji_test(int fd, int argc, char *argv[]);
 static int aji_show_clients(int fd, int argc, char *argv[]);
 static int aji_create_client(char *label, struct ast_variable *var, int debug);
 static int aji_create_buddy(char *label, struct aji_client *client);
-static int aji_reload(void);
-static int aji_load_config(void);
+static int aji_reload(int reload);
+static int aji_load_config(int reload);
 static void aji_pruneregister(struct aji_client *client);
 static int aji_filter_roster(void *data, ikspak *pak);
 static int aji_get_roster(struct aji_client *client);
@@ -2062,7 +2062,7 @@ static int aji_do_debug(int fd, int argc, char *argv[])
  */
 static int aji_do_reload(int fd, int argc, char *argv[])
 {
-       aji_reload();
+       aji_reload(1);
        ast_cli(fd, "Jabber Reloaded.\n");
        return RESULT_SUCCESS;
 }
@@ -2398,17 +2398,20 @@ static int aji_create_buddy(char *label, struct aji_client *client)
 }
 
 /*!< load config file. \return 1. */
-static int aji_load_config(void)
+static int aji_load_config(int reload)
 {
        char *cat = NULL;
        int debug = 1;
        struct ast_config *cfg = NULL;
        struct ast_variable *var = NULL;
+       struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
+
+       if ((cfg = ast_config_load(JABBER_CONFIG, config_flags)) == CONFIG_STATUS_FILEUNCHANGED)
+               return -1;
 
        /* Reset flags to default value */
        ast_set_flag(&globalflags, AJI_AUTOPRUNE | AJI_AUTOREGISTER);
 
-       cfg = ast_config_load(JABBER_CONFIG);
        if (!cfg) {
                ast_log(LOG_WARNING, "No such configuration file %s\n", JABBER_CONFIG);
                return 0;
@@ -2508,13 +2511,17 @@ static int manager_jabber_send(struct mansession *s, const struct message *m)
 }
 
 /*! \brief Reload the jabber module */
-static int aji_reload()
+static int aji_reload(int reload)
 {
+       int res;
+
        ASTOBJ_CONTAINER_MARKALL(&clients);
-       if (!aji_load_config()) {
+       if (!(res = aji_load_config(reload))) {
                ast_log(LOG_ERROR, "JABBER: Failed to load config.\n");
                return 0;
-       }
+       } else if (res == -1)
+               return 1;
+
        ASTOBJ_CONTAINER_PRUNE_MARKED(&clients, aji_client_destroy);
        ASTOBJ_CONTAINER_TRAVERSE(&clients, 1, {
                ASTOBJ_RDLOCK(iterator);
@@ -2566,7 +2573,7 @@ static int unload_module(void)
 static int load_module(void)
 {
        ASTOBJ_CONTAINER_INIT(&clients);
-       if(!aji_reload())
+       if(!aji_reload(0))
                return AST_MODULE_LOAD_DECLINE;
        ast_manager_register2("JabberSend", EVENT_FLAG_SYSTEM, manager_jabber_send,
                        "Sends a message to a Jabber Client", mandescr_jabber_send);
@@ -2580,7 +2587,7 @@ static int load_module(void)
 /*! \brief Wrapper for aji_reload */
 static int reload(void)
 {
-       aji_reload();
+       aji_reload(1);
        return 0;
 }
 
index 0aa3cc5..9a66b75 100644 (file)
@@ -1013,10 +1013,11 @@ static int load_moh_classes(int reload)
        struct mohclass *class; 
        char *cat;
        int numclasses = 0;
+       struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
 
-       cfg = ast_config_load("musiconhold.conf");
+       cfg = ast_config_load("musiconhold.conf", config_flags);
 
-       if (!cfg)
+       if (cfg == NULL || cfg == CONFIG_STATUS_FILEUNCHANGED)
                return 0;
 
        cat = ast_category_browse(cfg, NULL);
index 6b70f16..c9d3ee7 100644 (file)
@@ -213,10 +213,11 @@ static int load_odbc_config(void)
        char *cat, *dsn, *username, *password, *sanitysql;
        int enabled, pooling, limit;
        int connect = 0, res = 0;
+       struct ast_flags config_flags = { 0 };
 
        struct odbc_class *new;
 
-       config = ast_config_load(cfg);
+       config = ast_config_load(cfg, config_flags);
        if (!config) {
                ast_log(LOG_WARNING, "Unable to load config file res_odbc.conf\n");
                return -1;
@@ -538,6 +539,7 @@ static int reload(void)
        char *cat, *dsn, *username, *password, *sanitysql;
        int enabled, pooling, limit;
        int connect = 0, res = 0;
+       struct ast_flags config_flags = { CONFIG_FLAG_FILEUNCHANGED };
 
        struct odbc_class *new, *class;
        struct odbc_obj *current;
@@ -548,8 +550,8 @@ static int reload(void)
                class->delme = 1;
        }
 
-       config = ast_config_load(cfg);
-       if (config) {
+       config = ast_config_load(cfg, config_flags);
+       if (config != NULL && config != CONFIG_STATUS_FILEUNCHANGED) {
                for (cat = ast_category_browse(config, NULL); cat; cat=ast_category_browse(config, cat)) {
                        if (!strcasecmp(cat, "ENV")) {
                                for (v = ast_variable_browse(config, cat); v; v = v->next) {
index f1f1b19..01a6404 100644 (file)
@@ -513,6 +513,7 @@ static int smdi_load(int reload)
        struct ast_config *conf;
        struct ast_variable *v;
        struct ast_smdi_interface *iface = NULL;
+       struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
        int res = 0;
 
        /* Config options */
@@ -524,13 +525,14 @@ static int smdi_load(int reload)
        int msdstrip = 0;              /* strip zero digits */
        long msg_expiry = SMDI_MSG_EXPIRY_TIME;
 
-       if (!(conf = ast_config_load(config_file))) {
+       if (!(conf = ast_config_load(config_file, config_flags))) {
                if (reload)
                        ast_log(LOG_NOTICE, "Unable to reload config %s: SMDI untouched\n", config_file);
                else
                        ast_log(LOG_NOTICE, "Unable to load config %s: SMDI disabled\n", config_file);
                return 1;
-       }
+       } else if (conf == CONFIG_STATUS_FILEUNCHANGED)
+               return 0;
 
        /* Mark all interfaces that we are listening on.  We will unmark them
         * as we find them in the config file, this way we know any interfaces
index 05c483e..1fac2c3 100644 (file)
@@ -48,11 +48,12 @@ static int load_config(void)
 {
        struct ast_variable *var;
        struct ast_config *cfg;
+       struct ast_flags config_flags = { 0 };
        char *cat;
 
        res_snmp_enabled = 0;
        res_snmp_agentx_subagent = 1;
-       cfg = ast_config_load("res_snmp.conf");
+       cfg = ast_config_load("res_snmp.conf", config_flags);
        if (!cfg) {
                ast_log(LOG_WARNING, "Could not load res_snmp.conf\n");
                return 0;