diff --git a/.cleancount b/.cleancount index 0cfbf08886..00750edc07 100755 --- a/.cleancount +++ b/.cleancount @@ -1 +1 @@ -2 +3 diff --git a/Makefile b/Makefile index 25e2e76378..fd9628ca6b 100755 --- a/Makefile +++ b/Makefile @@ -231,7 +231,7 @@ OBJS=io.o sched.o logger.o frame.o loader.o config.o channel.o \ cdr.o tdd.o acl.o rtp.o manager.o asterisk.o ast_expr.o \ dsp.o chanvars.o indications.o autoservice.o db.o privacy.o \ astmm.o enum.o srv.o dns.o aescrypt.o aestab.o aeskey.o \ - utils.o + utils.o config_old.o ifeq (${OSARCH},Darwin) OBJS+=poll.o dlfcn.o ASTLINK=-Wl,-dynamic @@ -597,4 +597,3 @@ cleantest: if ! cmp -s .cleancount .lastclean ; then \ $(MAKE) clean; cp -f .cleancount .lastclean;\ fi - diff --git a/apps/app_alarmreceiver.c b/apps/app_alarmreceiver.c index ed10e55cbd..bb4ca3e487 100755 --- a/apps/app_alarmreceiver.c +++ b/apps/app_alarmreceiver.c @@ -747,7 +747,7 @@ static int load_config(void) /* Read in the config file */ - cfg = ast_load(ALMRCV_CONFIG); + cfg = ast_config_load(ALMRCV_CONFIG); if(!cfg){ @@ -817,7 +817,7 @@ static int load_config(void) strncpy(db_family, p, sizeof(db_family) - 1); db_family[sizeof(db_family) - 1] = '\0'; } - ast_destroy(cfg); + ast_config_destroy(cfg); } return 0; diff --git a/apps/app_directory.c b/apps/app_directory.c index eab10a3fce..8404d52691 100755 --- a/apps/app_directory.c +++ b/apps/app_directory.c @@ -351,7 +351,7 @@ static int directory_exec(struct ast_channel *chan, void *data) ast_log(LOG_WARNING, "directory requires an argument (context[,dialcontext])\n"); return -1; } - cfg = ast_load(DIRECTORY_CONFIG); + cfg = ast_config_load(DIRECTORY_CONFIG); if (!cfg) { ast_log(LOG_WARNING, "Unable to open directory configuration %s\n", DIRECTORY_CONFIG); return -1; @@ -400,7 +400,7 @@ top: } } } - ast_destroy(cfg); + ast_config_destroy(cfg); LOCAL_USER_REMOVE(u); return res; } diff --git a/apps/app_enumlookup.c b/apps/app_enumlookup.c index 16c9cf059d..4664cd68a3 100755 --- a/apps/app_enumlookup.c +++ b/apps/app_enumlookup.c @@ -145,14 +145,14 @@ static int load_config(void) struct ast_config *cfg; char *s; - cfg = ast_load(ENUM_CONFIG); + cfg = ast_config_load(ENUM_CONFIG); if (cfg) { if (!(s=ast_variable_retrieve(cfg, "general", "h323driver"))) { strncpy(h323driver, H323DRIVERDEFAULT, sizeof(h323driver) - 1); } else { strncpy(h323driver, s, sizeof(h323driver) - 1); } - ast_destroy(cfg); + ast_config_destroy(cfg); return 0; } ast_log(LOG_NOTICE, "No ENUM Config file, using defaults\n"); diff --git a/apps/app_festival.c b/apps/app_festival.c index 13eaa26b28..91a23c1fa6 100755 --- a/apps/app_festival.c +++ b/apps/app_festival.c @@ -282,7 +282,7 @@ static int festival_exec(struct ast_channel *chan, void *vdata) char *intstr; struct ast_config *cfg; - cfg = ast_load(FESTIVAL_CONFIG); + cfg = ast_config_load(FESTIVAL_CONFIG); if (!cfg) { ast_log(LOG_WARNING, "No such configuration file %s\n", FESTIVAL_CONFIG); return -1; @@ -308,7 +308,7 @@ static int festival_exec(struct ast_channel *chan, void *vdata) } if (!vdata || ast_strlen_zero(vdata)) { ast_log(LOG_WARNING, "festival requires an argument (text)\n"); - ast_destroy(cfg); + ast_config_destroy(cfg); return -1; } strncpy(data, vdata, sizeof(data) - 1); @@ -326,7 +326,7 @@ static int festival_exec(struct ast_channel *chan, void *vdata) if (fd < 0) { ast_log(LOG_WARNING,"festival_client: can't get socket\n"); - ast_destroy(cfg); + ast_config_destroy(cfg); return -1; } memset(&serv_addr, 0, sizeof(serv_addr)); @@ -335,7 +335,7 @@ static int festival_exec(struct ast_channel *chan, void *vdata) serverhost = ast_gethostbyname(host, &ahp); if (serverhost == (struct hostent *)0) { ast_log(LOG_WARNING,"festival_client: gethostbyname failed\n"); - ast_destroy(cfg); + ast_config_destroy(cfg); return -1; } memmove(&serv_addr.sin_addr,serverhost->h_addr, serverhost->h_length); @@ -345,7 +345,7 @@ static int festival_exec(struct ast_channel *chan, void *vdata) if (connect(fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) != 0) { ast_log(LOG_WARNING,"festival_client: connect to server failed\n"); - ast_destroy(cfg); + ast_config_destroy(cfg); return -1; } @@ -448,7 +448,7 @@ static int festival_exec(struct ast_channel *chan, void *vdata) } } while (strcmp(ack,"OK\n") != 0); close(fd); - ast_destroy(cfg); + ast_config_destroy(cfg); LOCAL_USER_REMOVE(u); return res; diff --git a/apps/app_meetme.c b/apps/app_meetme.c index 9385269f6c..150b36576b 100755 --- a/apps/app_meetme.c +++ b/apps/app_meetme.c @@ -1187,7 +1187,7 @@ static struct ast_conference *find_conf(struct ast_channel *chan, char *confno, } } else { /* Check the config */ - cfg = ast_load("meetme.conf"); + cfg = ast_config_load("meetme.conf"); if (!cfg) { ast_log(LOG_WARNING, "No meetme.conf file :(\n"); return NULL; @@ -1215,7 +1215,7 @@ static struct ast_conference *find_conf(struct ast_channel *chan, char *confno, if (!var) { ast_log(LOG_DEBUG, "%s isn't a valid conference\n", confno); } - ast_destroy(cfg); + ast_config_destroy(cfg); } } else if (dynamic_pin) { /* Correct for the user selecting 'D' instead of 'd' to have @@ -1373,7 +1373,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_load("meetme.conf"); + cfg = ast_config_load("meetme.conf"); if (cfg) { var = ast_variable_browse(cfg, "rooms"); while(var) { @@ -1421,7 +1421,7 @@ static int conf_exec(struct ast_channel *chan, void *data) } var = var->next; } - ast_destroy(cfg); + ast_config_destroy(cfg); } } /* Select first conference number not in use */ diff --git a/apps/app_privacy.c b/apps/app_privacy.c index 39a1c1843f..13bc38c303 100755 --- a/apps/app_privacy.c +++ b/apps/app_privacy.c @@ -82,7 +82,7 @@ privacy_exec (struct ast_channel *chan, void *data) } } /*Read in the config file*/ - cfg = ast_load(PRIV_CONFIG); + cfg = ast_config_load(PRIV_CONFIG); /*Play unidentified call*/ @@ -144,7 +144,7 @@ privacy_exec (struct ast_channel *chan, void *data) chan->priority+=100; } if (cfg) - ast_destroy(cfg); + ast_config_destroy(cfg); } LOCAL_USER_REMOVE (u); diff --git a/apps/app_queue.c b/apps/app_queue.c index 8ab4351adf..b8a0baa62b 100755 --- a/apps/app_queue.c +++ b/apps/app_queue.c @@ -2388,7 +2388,7 @@ static void reload_queues(void) int new; char *general_val = NULL; - cfg = ast_load("queues.conf"); + cfg = ast_config_load("queues.conf"); if (!cfg) { ast_log(LOG_NOTICE, "No call queueing config file (queues.conf), so no call queues\n"); return; @@ -2578,7 +2578,7 @@ static void reload_queues(void) } cat = ast_category_browse(cfg, cat); } - ast_destroy(cfg); + ast_config_destroy(cfg); q = queues; ql = NULL; while(q) { diff --git a/apps/app_realtime.c b/apps/app_realtime.c index 03236e8cb3..d0895f411a 100755 --- a/apps/app_realtime.c +++ b/apps/app_realtime.c @@ -185,7 +185,7 @@ static int realtime_exec(struct ast_channel *chan, void *data) pbx_builtin_setvar_helper(chan, vname, itt->value); } - ast_destroy_realtime(var); + ast_variables_destroy(var); } else if (option_verbose > 3) ast_verbose(VERBOSE_PREFIX_4"No Realtime Matches Found.\n"); } diff --git a/apps/app_rpt.c b/apps/app_rpt.c index 5ad267780a..fee56bbe95 100755 --- a/apps/app_rpt.c +++ b/apps/app_rpt.c @@ -3856,7 +3856,7 @@ pthread_attr_t attr; /* start with blank config */ memset(&rpt_vars,0,sizeof(rpt_vars)); - cfg = ast_load("rpt.conf"); + cfg = ast_config_load("rpt.conf"); if (!cfg) { ast_log(LOG_NOTICE, "Unable to open radio repeater configuration rpt.conf. Radio Repeater disabled.\n"); pthread_exit(NULL); diff --git a/apps/app_txtcidname.c b/apps/app_txtcidname.c index 43684c4012..5cffb271a7 100755 --- a/apps/app_txtcidname.c +++ b/apps/app_txtcidname.c @@ -87,14 +87,14 @@ static int load_config(void) struct ast_config *cfg; char *s; - cfg = ast_load(ENUM_CONFIG); + cfg = ast_config_load(ENUM_CONFIG); if (cfg) { if (!(s=ast_variable_retrieve(cfg, "general", "h323driver"))) { strncpy(h323driver, H323DRIVERDEFAULT, sizeof(h323driver) - 1); } else { strncpy(h323driver, s, sizeof(h323driver) - 1); } - ast_destroy(cfg); + ast_config_destroy(cfg); return 0; } ast_log(LOG_NOTICE, "No ENUM Config file, using defaults\n"); diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c index 70d0e2b00c..d39fbbd66c 100755 --- a/apps/app_voicemail.c +++ b/apps/app_voicemail.c @@ -1072,7 +1072,7 @@ static int store_file(char *dir, int msgnum) else strncpy(fn, dir, sizeof(fn) - 1); snprintf(full_fn, sizeof(full_fn), "%s.txt", fn); - cfg = ast_load(full_fn); + cfg = ast_config_load(full_fn); snprintf(full_fn, sizeof(full_fn), "%s.%s", fn, fmt); fd = open(full_fn, O_RDWR); if (fd < 0) { @@ -1144,7 +1144,7 @@ static int store_file(char *dir, int msgnum) ast_log(LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database); yuck: if (cfg) - ast_destroy(cfg); + ast_config_destroy(cfg); if (fdm) munmap(fdm, fdlen); if (fd > -1) @@ -3091,7 +3091,7 @@ static int forward_message(struct ast_channel *chan, char *context, char *dir, i /* load the information on the source message so we can send an e-mail like a new message */ snprintf(miffile, sizeof(miffile), "%s/msg%04d.txt", dir, curmsg); - if ((mif=ast_load(miffile))) { + if ((mif=ast_config_load(miffile))) { /* set callerid and duration variables */ snprintf(callerid, sizeof(callerid), "FWD from: %s from %s", sender->fullname, ast_variable_retrieve(mif, NULL, "callerid")); @@ -3116,7 +3116,7 @@ static int forward_message(struct ast_channel *chan, char *context, char *dir, i sendpage(myserveremail, vmtmp->pager, todircount, vmtmp->mailbox, chan->cid.cid_num, chan->cid.cid_name, duration, vmtmp); } - ast_destroy(mif); /* or here */ + ast_config_destroy(mif); /* or here */ } /* Leave voicemail for someone */ manager_event(EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext_context, has_voicemail(ext_context, NULL)); @@ -3344,7 +3344,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); - msg_cfg = ast_load(filename); + msg_cfg = ast_config_load(filename); if (!msg_cfg) { ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename); return 0; @@ -3375,7 +3375,7 @@ static int play_message(struct ast_channel *chan, struct ast_vm_user *vmu, struc /* Allow pressing '1' to skip envelope / callerid */ if (res == '1') res = 0; - ast_destroy(msg_cfg); + ast_config_destroy(msg_cfg); if (!res) { make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg); @@ -5139,7 +5139,7 @@ static int load_config(void) int x; int tmpadsi[4]; - cfg = ast_load(VOICEMAIL_CONFIG); + cfg = ast_config_load(VOICEMAIL_CONFIG); ast_mutex_lock(&vmlock); cur = users; while (cur) { @@ -5475,7 +5475,7 @@ static int load_config(void) tmpread = tmpwrite+len; } } - ast_destroy(cfg); + ast_config_destroy(cfg); ast_mutex_unlock(&vmlock); return 0; } else { @@ -5605,7 +5605,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); - msg_cfg = ast_load(filename); + msg_cfg = ast_config_load(filename); if (!msg_cfg) { ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename); return 0; @@ -5735,7 +5735,7 @@ static int advanced_options(struct ast_channel *chan, struct ast_vm_user *vmu, s } } - ast_destroy(msg_cfg); + ast_config_destroy(msg_cfg); if (!res) { make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); diff --git a/asterisk.c b/asterisk.c index 1b11bf2926..27fddf945c 100755 --- a/asterisk.c +++ b/asterisk.c @@ -48,7 +48,6 @@ #include "editline/histedit.h" #include "asterisk.h" #include -#include #include #include #include @@ -1498,11 +1497,11 @@ static void ast_readconfig(void) { char *config = ASTCONFPATH; if (option_overrideconfig == 1) { - cfg = ast_load((char *)ast_config_AST_CONFIG_FILE); + cfg = ast_config_load((char *)ast_config_AST_CONFIG_FILE); if (!cfg) ast_log(LOG_WARNING, "Unable to open specified master config file '%s', using builtin defaults\n", ast_config_AST_CONFIG_FILE); } else { - cfg = ast_load(config); + cfg = ast_config_load(config); } /* init with buildtime config */ @@ -1571,7 +1570,7 @@ static void ast_readconfig(void) { } v = v->next; } - ast_destroy(cfg); + ast_config_destroy(cfg); } int main(int argc, char *argv[]) @@ -1742,10 +1741,10 @@ int main(int argc, char *argv[]) ast_readconfig(); if (option_console && !option_verbose) - ast_verbose("[ Initializing Custom Configuration Options]"); + ast_verbose("[ Initializing Custom Configuration Options ]"); /* custom config setup */ register_config_cli(); - read_ast_cust_config(); + read_config_maps(); if (option_console) { diff --git a/cdr/cdr_manager.c b/cdr/cdr_manager.c index 1ebc58e73b..110aebadc7 100755 --- a/cdr/cdr_manager.c +++ b/cdr/cdr_manager.c @@ -36,7 +36,7 @@ static void loadconfigurationfile(void) struct ast_config *cfg; struct ast_variable *v; - cfg = ast_load(CONF_FILE); + cfg = ast_config_load(CONF_FILE); if (!cfg) { /* Standard configuration */ enablecdr = 0; @@ -60,7 +60,7 @@ static void loadconfigurationfile(void) cat = ast_category_browse(cfg, cat); } - ast_destroy(cfg); + ast_config_destroy(cfg); } static int manager_log(struct ast_cdr *cdr) diff --git a/cdr/cdr_odbc.c b/cdr/cdr_odbc.c index 9bc2a877bf..f9f0ce70f8 100755 --- a/cdr/cdr_odbc.c +++ b/cdr/cdr_odbc.c @@ -231,7 +231,7 @@ static int odbc_load_module(void) ast_mutex_lock(&odbc_lock); - cfg = ast_load(config); + cfg = ast_config_load(config); if (!cfg) { ast_log(LOG_WARNING, "cdr_odbc: Unable to load config for ODBC CDR's: %s\n", config); goto out; @@ -331,7 +331,7 @@ static int odbc_load_module(void) table = "cdr"; } - ast_destroy(cfg); + ast_config_destroy(cfg); if (option_verbose > 2) { ast_verbose( VERBOSE_PREFIX_3 "cdr_odbc: dsn is %s\n",dsn); ast_verbose( VERBOSE_PREFIX_3 "cdr_odbc: username is %s\n",username); diff --git a/cdr/cdr_pgsql.c b/cdr/cdr_pgsql.c index 65e0454029..efad07c7ba 100755 --- a/cdr/cdr_pgsql.c +++ b/cdr/cdr_pgsql.c @@ -330,13 +330,13 @@ static int my_load_module(void) { struct ast_config *cfg; int res; - cfg = ast_load(config); + cfg = ast_config_load(config); if (!cfg) { ast_log(LOG_WARNING, "Unable to load config for PostgreSQL CDR's: %s\n", config); return 0; } res = process_my_load_module(cfg); - ast_destroy(cfg); + ast_config_destroy(cfg); return res; } diff --git a/cdr/cdr_tds.c b/cdr/cdr_tds.c index 448c024955..15a7be84d3 100755 --- a/cdr/cdr_tds.c +++ b/cdr/cdr_tds.c @@ -391,7 +391,7 @@ int load_module(void) TDS_INT result_type; #endif - cfg = ast_load(config); + cfg = ast_config_load(config); if (!cfg) { ast_log(LOG_NOTICE, "Unable to load config for MSSQL CDR's: %s\n", config); @@ -462,7 +462,7 @@ int load_module(void) language = strdupa("us_english"); } - ast_destroy(cfg); + ast_config_destroy(cfg); /* Connect to M$SQL Server */ if (!(login = tds_alloc_login())) diff --git a/channels/chan_agent.c b/channels/chan_agent.c index fd85007de5..ca492cec64 100755 --- a/channels/chan_agent.c +++ b/channels/chan_agent.c @@ -876,7 +876,7 @@ static int read_agent_config(void) autologoff = 0; wrapuptime = 0; ackcall = 1; - cfg = ast_load(config); + cfg = ast_config_load(config); if (!cfg) { ast_log(LOG_NOTICE, "No agent configuration found -- agent support disabled\n"); return 0; @@ -988,7 +988,7 @@ static int read_agent_config(void) p = pn; } ast_mutex_unlock(&agentlock); - ast_destroy(cfg); + ast_config_destroy(cfg); return 0; } diff --git a/channels/chan_alsa.c b/channels/chan_alsa.c index 58de8a8f7e..f1663336b4 100755 --- a/channels/chan_alsa.c +++ b/channels/chan_alsa.c @@ -990,7 +990,7 @@ int load_module() int x; struct ast_config *cfg; struct ast_variable *v; - if ((cfg = ast_load(config))) { + if ((cfg = ast_config_load(config))) { v = ast_variable_browse(cfg, "general"); while(v) { if (!strcasecmp(v->name, "autoanswer")) @@ -1011,7 +1011,7 @@ int load_module() strncpy(outdevname, v->value, sizeof(outdevname)-1); v=v->next; } - ast_destroy(cfg); + ast_config_destroy(cfg); } res = pipe(sndcmd); if (res) { diff --git a/channels/chan_h323.c b/channels/chan_h323.c index 6309404edb..2b07ca9801 100755 --- a/channels/chan_h323.c +++ b/channels/chan_h323.c @@ -1728,7 +1728,7 @@ int reload_config(void) char *cat; char *utype; - cfg = ast_load(config); + cfg = ast_config_load(config); /* We *must* have a config file otherwise stop immediately */ if (!cfg) { @@ -1867,7 +1867,7 @@ int reload_config(void) } cat = ast_category_browse(cfg, cat); } - ast_destroy(cfg); + ast_config_destroy(cfg); /* Register our H.323 aliases if any*/ while (alias) { diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c index 5d5c0449a9..2584fe8f9b 100755 --- a/channels/chan_iax2.c +++ b/channels/chan_iax2.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -1470,7 +1469,7 @@ retry: } if (!owner) { if (pvt->vars) { - ast_destroy_realtime(pvt->vars); + ast_variables_destroy(pvt->vars); pvt->vars = NULL; } free(pvt); @@ -2170,7 +2169,7 @@ static struct iax2_peer *realtime_peer(const char *peername) } } } - ast_destroy_realtime(var); + ast_variables_destroy(var); } return peer; } @@ -2201,12 +2200,12 @@ static struct iax2_user *realtime_user(const char *username) tmp = tmp->next; } } - ast_destroy_realtime(var); + ast_variables_destroy(var); } return user; } -static void realtime_update(const char *peername, struct sockaddr_in *sin) +static void realtime_update_peer(const char *peername, struct sockaddr_in *sin) { char port[10]; char ipaddr[20]; @@ -4090,7 +4089,7 @@ static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies /* We found our match (use the first) */ /* copy vars */ for (v = user->vars ; v ; v = v->next) { - if((tmpvar = ast_new_variable(v->name, v->value))) { + if((tmpvar = ast_variable_new(v->name, v->value))) { tmpvar->next = iaxs[callno]->vars; iaxs[callno]->vars = tmpvar; } @@ -4871,7 +4870,7 @@ static int update_registry(char *name, struct sockaddr_in *sin, int callno, char p = find_peer(name); if (p) { if (ast_test_flag(p, IAX_TEMPONLY)) - realtime_update(name, sin); + realtime_update_peer(name, sin); if (inaddrcmp(&p->addr, sin)) { if (iax2_regfunk) iax2_regfunk(p->name, 1); @@ -7297,7 +7296,7 @@ static struct iax2_user *build_user(const char *name, struct ast_variable *v, in if (varname && (varval = strchr(varname,'='))) { *varval = '\0'; varval++; - if((tmpvar = ast_new_variable(varname, varval))) { + if((tmpvar = ast_variable_new(varname, varval))) { tmpvar->next = user->vars; user->vars = tmpvar; } @@ -7421,7 +7420,7 @@ static void destroy_user(struct iax2_user *user) ast_free_ha(user->ha); free_context(user->contexts); if(user->vars) { - ast_destroy_realtime(user->vars); + ast_variables_destroy(user->vars); user->vars = NULL; } free(user); @@ -7521,7 +7520,7 @@ static int set_config(char *config_file, int reload) static unsigned short int last_port=0; #endif - cfg = ast_load(config_file); + cfg = ast_config_load(config_file); if (!cfg) { ast_log(LOG_ERROR, "Unable to load config %s\n", config_file); @@ -7688,7 +7687,7 @@ static int set_config(char *config_file, int reload) } cat = ast_category_browse(cfg, cat); } - ast_destroy(cfg); + ast_config_destroy(cfg); set_timing(); return capability; } diff --git a/channels/chan_mgcp.c b/channels/chan_mgcp.c index 26ee4afd49..4e1995e7b1 100755 --- a/channels/chan_mgcp.c +++ b/channels/chan_mgcp.c @@ -4043,7 +4043,7 @@ static int reload_config(void) ast_log(LOG_WARNING, "Unable to get hostname, MGCP disabled\n"); return 0; } - cfg = ast_load(config); + cfg = ast_config_load(config); /* We *must* have a config file otherwise stop immediately */ if (!cfg) { @@ -4144,7 +4144,7 @@ static int reload_config(void) hp = ast_gethostbyname(ourhost, &ahp); if (!hp) { ast_log(LOG_WARNING, "Unable to get our IP address, MGCP disabled\n"); - ast_destroy(cfg); + ast_config_destroy(cfg); return 0; } memcpy(&__ourip, hp->h_addr, sizeof(__ourip)); @@ -4181,7 +4181,7 @@ static int reload_config(void) } } ast_mutex_unlock(&netlock); - ast_destroy(cfg); + ast_config_destroy(cfg); /* SC: send audit only to the new endpoints */ g = gateways; diff --git a/channels/chan_modem.c b/channels/chan_modem.c index 4c4b6b80f6..74f9ec7fc7 100755 --- a/channels/chan_modem.c +++ b/channels/chan_modem.c @@ -949,7 +949,7 @@ int load_module() struct ast_variable *v; struct ast_modem_pvt *tmp; char driver[80]; - cfg = ast_load(config); + cfg = ast_config_load(config); /* We *must* have a config file otherwise stop immediately */ if (!cfg) { @@ -972,7 +972,7 @@ int load_module() } else { ast_log(LOG_ERROR, "Unable to register channel '%s'\n", v->value); - ast_destroy(cfg); + ast_config_destroy(cfg); ast_mutex_unlock(&iflock); __unload_module(); return -1; @@ -984,7 +984,7 @@ int load_module() if (ast_load_resource(driver)) { ast_log(LOG_ERROR, "Failed to load driver %s\n", driver); - ast_destroy(cfg); + ast_config_destroy(cfg); ast_mutex_unlock(&iflock); __unload_module(); return -1; @@ -1055,11 +1055,11 @@ int load_module() if (ast_channel_register(type, tdesc, /* XXX Don't know our types -- maybe we should register more than one XXX */ AST_FORMAT_SLINEAR, modem_request)) { ast_log(LOG_ERROR, "Unable to register channel class %s\n", type); - ast_destroy(cfg); + ast_config_destroy(cfg); __unload_module(); return -1; } - ast_destroy(cfg); + ast_config_destroy(cfg); /* And start the monitor for the first time */ restart_monitor(); return 0; diff --git a/channels/chan_oss.c b/channels/chan_oss.c index 0219e360dd..b6dbeae22b 100755 --- a/channels/chan_oss.c +++ b/channels/chan_oss.c @@ -1026,7 +1026,7 @@ int load_module() } for (x=0;xname, "autoanswer")) @@ -1045,7 +1045,7 @@ int load_module() playbackonly = ast_true(v->value); v=v->next; } - ast_destroy(cfg); + ast_config_destroy(cfg); } ast_pthread_create(&sthread, NULL, sound_thread, NULL); return 0; diff --git a/channels/chan_phone.c b/channels/chan_phone.c index b5e8d26830..a2a0c461a5 100755 --- a/channels/chan_phone.c +++ b/channels/chan_phone.c @@ -1232,7 +1232,7 @@ int load_module() struct phone_pvt *tmp; int mode = MODE_IMMEDIATE; int txgain = DEFAULT_GAIN, rxgain = DEFAULT_GAIN; /* default gain 1.0 */ - cfg = ast_load(config); + cfg = ast_config_load(config); /* We *must* have a config file otherwise stop immediately */ if (!cfg) { @@ -1255,7 +1255,7 @@ int load_module() } else { ast_log(LOG_ERROR, "Unable to register channel '%s'\n", v->value); - ast_destroy(cfg); + ast_config_destroy(cfg); ast_mutex_unlock(&iflock); __unload_module(); return -1; @@ -1316,11 +1316,11 @@ int load_module() AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR | AST_FORMAT_ULAW : prefformat, phone_request)) { ast_log(LOG_ERROR, "Unable to register channel class %s\n", type); - ast_destroy(cfg); + ast_config_destroy(cfg); __unload_module(); return -1; } - ast_destroy(cfg); + ast_config_destroy(cfg); /* And start the monitor for the first time */ restart_monitor(); return 0; diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 232dc94976..41590e87e9 100755 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -1137,7 +1136,7 @@ static struct sip_peer *realtime_peer(const char *peername, struct sockaddr_in * while(tmp) { if (!strcasecmp(tmp->name, "type") && !strcasecmp(tmp->value, "user")) { - ast_destroy_realtime(var); + ast_variables_destroy(var); return NULL; } tmp = tmp->next; @@ -1146,7 +1145,7 @@ static struct sip_peer *realtime_peer(const char *peername, struct sockaddr_in * peer = build_peer(peername, var, 1); if (peer) ast_set_flag(peer, SIP_REALTIME); - ast_destroy_realtime(var); + ast_variables_destroy(var); return peer; } @@ -1180,7 +1179,7 @@ static void sip_destroy_user(struct sip_user *user) { ast_free_ha(user->ha); if(user->vars) { - ast_destroy_realtime(user->vars); + ast_variables_destroy(user->vars); user->vars = NULL; } if (ast_test_flag(user, SIP_REALTIME)) @@ -1206,7 +1205,7 @@ static struct sip_user *realtime_user(const char *username) while (tmp) { if (!strcasecmp(tmp->name, "type") && !strcasecmp(tmp->value, "peer")) { - ast_destroy_realtime(var); + ast_variables_destroy(var); return NULL; } tmp = tmp->next; @@ -1220,7 +1219,7 @@ static struct sip_user *realtime_user(const char *username) /* Add some finishing touches, addresses, etc */ ast_set_flag(user, SIP_REALTIME); } - ast_destroy_realtime(var); + ast_variables_destroy(var); return user; } @@ -1531,7 +1530,7 @@ static void __sip_destroy(struct sip_pvt *p, int lockowner) } ast_mutex_destroy(&p->lock); if(p->vars) { - ast_destroy_realtime(p->vars); + ast_variables_destroy(p->vars); p->vars = NULL; } free(p); @@ -2295,7 +2294,7 @@ static struct sip_pvt *sip_alloc(char *callid, struct sockaddr_in *sin, int useg ast_log(LOG_WARNING, "Unable to create RTP session: %s\n", strerror(errno)); ast_mutex_destroy(&p->lock); if(p->vars) { - ast_destroy_realtime(p->vars); + ast_variables_destroy(p->vars); p->vars = NULL; } free(p); @@ -5569,7 +5568,7 @@ static int check_user_full(struct sip_pvt *p, struct sip_request *req, char *cmd ast_copy_flags(p, user, SIP_TRUSTRPID | SIP_USECLIENTCODE | SIP_NAT | SIP_PROG_INBAND | SIP_OSPAUTH); /* copy vars */ for (v = user->vars ; v ; v = v->next) { - if((tmpvar = ast_new_variable(v->name, v->value))) { + if((tmpvar = ast_variable_new(v->name, v->value))) { tmpvar->next = p->vars; p->vars = tmpvar; } @@ -8693,7 +8692,7 @@ static struct sip_user *build_user(const char *name, struct ast_variable *v, int if (varname && (varval = strchr(varname,'='))) { *varval = '\0'; varval++; - if((tmpvar = ast_new_variable(varname, varval))) { + if((tmpvar = ast_variable_new(varname, varval))) { tmpvar->next = user->vars; user->vars = tmpvar; } @@ -9012,7 +9011,7 @@ static int reload_config(void) ast_log(LOG_WARNING, "Unable to get hostname, SIP disabled\n"); return 0; } - cfg = ast_load(config); + cfg = ast_config_load(config); /* We *must* have a config file otherwise stop immediately */ if (!cfg) { @@ -9252,7 +9251,7 @@ static int reload_config(void) if (!hp) { ast_log(LOG_WARNING, "Unable to get IP address for %s, SIP disabled\n", ourhost); if (!__ourip.s_addr) { - ast_destroy(cfg); + ast_config_destroy(cfg); return 0; } } else @@ -9297,12 +9296,12 @@ static int reload_config(void) ast_mutex_unlock(&netlock); /* Release configuration from memory */ - ast_destroy(cfg); + ast_config_destroy(cfg); /* Load the list of manual NOTIFY types to support */ if (notify_types) - ast_destroy(notify_types); - notify_types = ast_load(notify_config); + ast_config_destroy(notify_types); + notify_types = ast_config_load(notify_config); return 0; } @@ -9740,7 +9739,7 @@ int unload_module() /* Free associated memory */ ast_mutex_destroy(&pl->lock); if(pl->vars) { - ast_destroy_realtime(pl->vars); + ast_variables_destroy(pl->vars); pl->vars = NULL; } free(pl); diff --git a/channels/chan_skinny.c b/channels/chan_skinny.c index b2a07d0b6d..5cfc053f04 100755 --- a/channels/chan_skinny.c +++ b/channels/chan_skinny.c @@ -2639,7 +2639,7 @@ static int reload_config(void) return 0; } #endif - cfg = ast_load(config); + cfg = ast_config_load(config); /* We *must* have a config file otherwise stop immediately */ if (!cfg) { @@ -2690,7 +2690,7 @@ static int reload_config(void) hp = ast_gethostbyname(ourhost, &ahp); if (!hp) { ast_log(LOG_WARNING, "Unable to get our IP address, Skinny disabled\n"); - ast_destroy(cfg); + ast_config_destroy(cfg); return 0; } memcpy(&__ourip, hp->h_addr, sizeof(__ourip)); @@ -2726,7 +2726,7 @@ static int reload_config(void) skinnysock = socket(AF_INET, SOCK_STREAM, 0); if(setsockopt(skinnysock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) { ast_log(LOG_ERROR, "Set Socket Options failed: errno %d, %s", errno, strerror(errno)); - ast_destroy(cfg); + ast_config_destroy(cfg); return 0; } @@ -2739,7 +2739,7 @@ static int reload_config(void) strerror(errno)); close(skinnysock); skinnysock = -1; - ast_destroy(cfg); + ast_config_destroy(cfg); return 0; } @@ -2749,7 +2749,7 @@ static int reload_config(void) strerror(errno)); close(skinnysock); skinnysock = -1; - ast_destroy(cfg); + ast_config_destroy(cfg); return 0; } @@ -2763,7 +2763,7 @@ static int reload_config(void) ast_mutex_unlock(&netlock); /* and unload the configuration when were done */ - ast_destroy(cfg); + ast_config_destroy(cfg); return 0; } diff --git a/channels/chan_vpb.c b/channels/chan_vpb.c index a3a59f48a6..6543ac8726 100755 --- a/channels/chan_vpb.c +++ b/channels/chan_vpb.c @@ -2425,7 +2425,7 @@ int load_module() int bal3 = -1; char * callerid = NULL; - cfg = ast_load(config); + cfg = ast_config_load(config); /* We *must* have a config file otherwise stop immediately */ if (!cfg) { @@ -2530,7 +2530,7 @@ int load_module() done: (void)0; } ast_mutex_unlock(&iflock); - ast_destroy(cfg); + ast_config_destroy(cfg); if (!error && ast_channel_register(type, tdesc, prefformat, vpb_request) != 0) { ast_log(LOG_ERROR, "Unable to register channel class %s\n", type); diff --git a/channels/chan_zap.c b/channels/chan_zap.c index 33181e3f60..0129987b9a 100755 --- a/channels/chan_zap.c +++ b/channels/chan_zap.c @@ -9236,7 +9236,7 @@ static int setup_zap(int reload) struct zt_pri *pri; #endif - cfg = ast_load(config); + cfg = ast_config_load(config); /* We *must* have a config file otherwise stop immediately */ if (!cfg) { @@ -9321,7 +9321,7 @@ static int setup_zap(int reload) if (reload == 0) { if (cur_signalling < 0) { ast_log(LOG_ERROR, "Signalling must be specified before any channels are.\n"); - ast_destroy(cfg); + ast_config_destroy(cfg); ast_mutex_unlock(&iflock); return -1; } @@ -9333,13 +9333,13 @@ static int setup_zap(int reload) if (!strcasecmp(v->name, "crv")) { if (sscanf(c, "%d:%n", &trunkgroup, &y) != 1) { ast_log(LOG_WARNING, "CRV must begin with trunkgroup followed by a colon at line %d\n", v->lineno); - ast_destroy(cfg); + ast_config_destroy(cfg); ast_mutex_unlock(&iflock); return -1; } if (trunkgroup < 1) { ast_log(LOG_WARNING, "CRV trunk group must be a postive number at line %d\n", v->lineno); - ast_destroy(cfg); + ast_config_destroy(cfg); ast_mutex_unlock(&iflock); return -1; } @@ -9352,7 +9352,7 @@ static int setup_zap(int reload) } if (!pri) { ast_log(LOG_WARNING, "No such trunk group %d at CRV declaration at line %d\n", trunkgroup, v->lineno); - ast_destroy(cfg); + ast_config_destroy(cfg); ast_mutex_unlock(&iflock); return -1; } @@ -9370,7 +9370,7 @@ static int setup_zap(int reload) found_pseudo = 1; } else { ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'\n", v->value, chan); - ast_destroy(cfg); + ast_config_destroy(cfg); ast_mutex_unlock(&iflock); return -1; } @@ -9401,7 +9401,7 @@ static int setup_zap(int reload) ast_log(LOG_ERROR, "Unable to reconfigure channel '%s'\n", v->value); else ast_log(LOG_ERROR, "Unable to register channel '%s'\n", v->value); - ast_destroy(cfg); + ast_config_destroy(cfg); ast_mutex_unlock(&iflock); return -1; } @@ -9741,7 +9741,7 @@ static int setup_zap(int reload) switchtype = PRI_SWITCH_QSIG; else { ast_log(LOG_ERROR, "Unknown switchtype '%s'\n", v->value); - ast_destroy(cfg); + ast_config_destroy(cfg); ast_mutex_unlock(&iflock); return -1; } @@ -9923,7 +9923,7 @@ static int setup_zap(int reload) } } ast_mutex_unlock(&iflock); - ast_destroy(cfg); + ast_config_destroy(cfg); #ifdef ZAPATA_PRI if (!reload) { for (x=0;xdead = 1; cur = cur->next; } - cfg = ast_load("iaxprov.conf"); + cfg = ast_config_load("iaxprov.conf"); if (cfg) { /* Load as appropriate */ cat = ast_category_browse(cfg, NULL); diff --git a/codecs/codec_speex.c b/codecs/codec_speex.c index 0499bde4a8..0f7bdd6c74 100755 --- a/codecs/codec_speex.c +++ b/codecs/codec_speex.c @@ -308,7 +308,7 @@ static void parse_config(void) struct ast_variable *var; int res; - if ((cfg = ast_load("codecs.conf"))) { + if ((cfg = ast_config_load("codecs.conf"))) { if ((var = ast_variable_browse(cfg, "speex"))) { while (var) { if (!strcasecmp(var->name, "quality")) { diff --git a/config.c b/config.c index e563dd8cc4..ebb2e11857 100755 --- a/config.c +++ b/config.c @@ -25,7 +25,6 @@ # include #endif #include -#include #include #include #include @@ -40,8 +39,7 @@ #define COMMENT_META ';' #define COMMENT_TAG '-' -static int ast_cust_config=0; -static config_static_func *global_load_func; +static char *extconfig_conf = "extconfig.conf"; static struct ast_config_map { struct ast_config_map *next; @@ -50,44 +48,33 @@ static struct ast_config_map { char *database; char *table; char stuff[0]; -} *maps = NULL; +} *config_maps = NULL; -AST_MUTEX_DEFINE_STATIC(ast_cust_config_lock); -static struct ast_config_reg *ast_cust_config_list; -static char *config_conf_file = "extconfig.conf"; +AST_MUTEX_DEFINE_STATIC(config_lock); +static struct ast_config_engine *config_engine_list; -void ast_destroy_realtime(struct ast_variable *v) -{ - struct ast_variable *vn; - while(v) { - vn = v; - v = v->next; - free(vn); - } -} +#define MAX_INCLUDE_LEVEL 10 -void ast_category_destroy(struct ast_category *cat) -{ - ast_destroy_realtime(cat->root); - free(cat); -} +struct ast_comment { + struct ast_comment *next; + char cmt[0]; +}; -void ast_destroy(struct ast_config *ast) -{ - struct ast_category *cat, *catn; +struct ast_category { + char name[80]; + struct ast_variable *root; + struct ast_variable *last; + struct ast_category *next; +}; - if (!ast) - return; - - cat = ast->root; - while(cat) { - ast_destroy_realtime(cat->root); - catn = cat; - cat = cat->next; - free(catn); - } - free(ast); -} +struct ast_config { + struct ast_category *root; + struct ast_category *last; + struct ast_category *current; + struct ast_category *last_browse; /* used to cache the last category supplied via category_browse */ + int include_level; + int max_include_level; +}; int ast_true(const char *s) { @@ -96,11 +83,11 @@ int ast_true(const char *s) /* Determine if this is a true value */ if (!strcasecmp(s, "yes") || !strcasecmp(s, "true") || - !strcasecmp(s, "y") || - !strcasecmp(s, "t") || - !strcasecmp(s, "1") || - !strcasecmp(s, "on")) - return -1; + !strcasecmp(s, "y") || + !strcasecmp(s, "t") || + !strcasecmp(s, "1") || + !strcasecmp(s, "on")) + return -1; return 0; } @@ -111,127 +98,124 @@ int ast_false(const char *s) /* Determine if this is a false value */ if (!strcasecmp(s, "no") || !strcasecmp(s, "false") || - !strcasecmp(s, "n") || - !strcasecmp(s, "f") || - !strcasecmp(s, "0") || - !strcasecmp(s, "off")) - return -1; + !strcasecmp(s, "n") || + !strcasecmp(s, "f") || + !strcasecmp(s, "0") || + !strcasecmp(s, "off")) + return -1; return 0; } +struct ast_variable *ast_variable_new(const char *name, const char *value) +{ + struct ast_variable *variable; + + int length = strlen(name) + strlen(value) + 2 + sizeof(struct ast_variable); + variable = malloc(length); + if (variable) { + memset(variable, 0, length); + variable->name = variable->stuff; + variable->value = variable->stuff + strlen(name) + 1; + strcpy(variable->name,name); + strcpy(variable->value,value); + } + + return variable; +} + +void ast_variable_append(struct ast_category *category, struct ast_variable *variable) +{ + if (category->last) + category->last->next = variable; + else + category->root = variable; + category->last = variable; +} + +void ast_variables_destroy(struct ast_variable *v) +{ + struct ast_variable *vn; + + while(v) { + vn = v; + v = v->next; + free(vn); + } +} + struct ast_variable *ast_variable_browse(const struct ast_config *config, const char *category) { - struct ast_category *cat; - cat = config->root; - while(cat) { - if (cat->name == category) - return cat->root; - cat = cat->next; - } - cat = config->root; - while(cat) { - if (!strcasecmp(cat->name, category)) - return cat->root; - cat = cat->next; + struct ast_category *cat = NULL; + + if (category && config->last_browse && (config->last_browse->name == category)) + cat = config->last_browse; + else + cat = ast_category_get(config, category); + + if (cat) + return cat->root; + else + return NULL; +} + +char *ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable) +{ + struct ast_variable *v; + + if (category) { + for (v = ast_variable_browse(config, category); v; v = v->next) + if (variable == v->name) + return v->value; + for (v = ast_variable_browse(config, category); v; v = v->next) + if (!strcasecmp(variable, v->name)) + return v->value; + } else { + struct ast_category *cat; + + for (cat = config->root; cat; cat = cat->next) + for (v = cat->root; v; v = v->next) + if (!strcasecmp(variable, v->name)) + return v->value; } + return NULL; } -char *ast_variable_retrieve(const struct ast_config *config, const char *category, const char *value) +struct ast_category *ast_category_new(const char *name) { - struct ast_variable *v; + struct ast_category *category; + + category = malloc(sizeof(struct ast_category)); if (category) { - v = ast_variable_browse(config, category); - while (v) { - if (value == v->name) - return v->value; - v=v->next; - } - v = ast_variable_browse(config, category); - while (v) { - if (!strcasecmp(value, v->name)) - return v->value; - v=v->next; - } - } else { - struct ast_category *cat; - cat = config->root; - while(cat) { - v = cat->root; - while (v) { - if (!strcasecmp(value, v->name)) - return v->value; - v=v->next; - } - cat = cat->next; - } + memset(category, 0, sizeof(struct ast_category)); + strncpy(category->name, name, sizeof(category->name) - 1); } - return NULL; + + return category; } struct ast_category *ast_category_get(const struct ast_config *config, const char *category_name) { - struct ast_category *category = config->root; + struct ast_category *cat; - while(category) { - if (!strcasecmp(category->name, category_name)) - return category; - category = category->next; + for (cat = config->root; cat; cat = cat->next) { + if (cat->name == category_name) + return cat; + } + + for (cat = config->root; cat; cat = cat->next) { + if (!strcasecmp(cat->name, category_name)) + return cat; } return NULL; } -int ast_category_exist(struct ast_config *config, char *category_name) +int ast_category_exist(const struct ast_config *config, const char *category_name) { return !!ast_category_get(config, category_name); } - -static struct ast_config_reg *get_ast_cust_config_keyword(const char *name, char *database, int dbsiz, char *table, int tabsiz) -{ - struct ast_config_reg *reg,*ret=NULL; - struct ast_config_map *map; - - ast_mutex_lock(&ast_cust_config_lock); - map = maps; - while(map) { - if (!strcasecmp(name, map->name)) { - strncpy(database, map->database, dbsiz - 1); - if (map->table) - strncpy(table, map->table, tabsiz - 1); - else - strncpy(table, name, tabsiz - 1); - break; - } - map = map->next; - } - if (map) { - for (reg=ast_cust_config_list;reg && !ret;reg=reg->next) { - if (!strcmp(reg->name,map->driver)) - ret=reg; - } - } - ast_mutex_unlock(&ast_cust_config_lock); - return ret; -} - -void ast_config_destroy_all(void) -{ - struct ast_config_reg *key; - ast_mutex_lock(&ast_cust_config_lock); - for (key=ast_cust_config_list;key;key=key->next) { - ast_config_deregister(key); - } - ast_cust_config_list = NULL; - ast_mutex_unlock(&ast_cust_config_lock); -} - -static struct ast_config_reg *get_config_registrations(void) -{ - return ast_cust_config_list; -} - void ast_category_append(struct ast_config *config, struct ast_category *category) { if (config->last) @@ -239,22 +223,107 @@ void ast_category_append(struct ast_config *config, struct ast_category *categor else config->root = category; config->last = category; + config->current = category; } -static void variable_append(struct ast_category *category, struct ast_variable *variable) +void ast_category_destroy(struct ast_category *cat) { - if (category->last) - category->last->next = variable; - else - category->root = variable; - category->last = variable; + ast_variables_destroy(cat->root); + free(cat); } -static int cfg_process(struct ast_config *tmp, struct ast_category **cat, char *buf, int lineno, const char *configfile, int includelevel) +char *ast_category_browse(struct ast_config *config, const char *prev) +{ + struct ast_category *cat = NULL; + + if (prev && config->last_browse && (config->last_browse->name == prev)) + cat = config->last_browse->next; + else if (!prev && config->root) + cat = config->root; + else if (prev) { + for (cat = config->root; cat; cat = cat->next) { + if (cat->name == prev) { + cat = cat->next; + break; + } + } + if (!cat) { + for (cat = config->root; cat; cat = cat->next) { + if (!strcasecmp(cat->name, prev)) { + cat = cat->next; + break; + } + } + } + } + + config->last_browse = cat; + if (cat) + return cat->name; + else + return NULL; +} + +struct ast_variable *ast_category_detach_variables(struct ast_category *cat) +{ + struct ast_variable *v; + + v = cat->root; + cat->root = NULL; + + return v; +} + +void ast_category_rename(struct ast_category *cat, const char *name) +{ + strncpy(cat->name, name, sizeof(cat->name) - 1); +} + +struct ast_config *ast_config_new(void) +{ + struct ast_config *config; + + config = malloc(sizeof(*config)); + if (config) { + memset(config, 0, sizeof(*config)); + config->max_include_level = MAX_INCLUDE_LEVEL; + } + + return config; +} + +void ast_config_destroy(struct ast_config *cfg) +{ + struct ast_category *cat, *catn; + + if (!cfg) + return; + + cat = cfg->root; + while(cat) { + ast_variables_destroy(cat->root); + catn = cat; + cat = cat->next; + free(catn); + } + free(cfg); +} + +struct ast_category *ast_config_get_current_category(const struct ast_config *cfg) +{ + return cfg->current; +} + +void ast_config_set_current_category(struct ast_config *cfg, const struct ast_category *cat) +{ + /* cast below is just to silence compiler warning about dropping "const" */ + cfg->current = (struct ast_category *) cat; +} + +static int process_text_line(struct ast_config *cfg, struct ast_category **cat, char *buf, int lineno, const char *configfile) { char *c; char *cur; - char *arg=NULL; struct ast_variable *v; int object; @@ -267,19 +336,17 @@ static int cfg_process(struct ast_config *tmp, struct ast_category **cat, char * /* A category header */ c = strchr(cur, ']'); if (!c) { - ast_destroy(tmp); ast_log(LOG_WARNING, "parse error: no closing ']', line %d of %s\n", lineno, configfile); return -1; } *c = '\0'; cur++; - *cat = ast_new_category(cur); + *cat = ast_category_new(cur); if (!*cat) { - ast_destroy(tmp); ast_log(LOG_WARNING, "Out of memory, line %d of %s\n", lineno, configfile); return -1; } - ast_category_append(tmp, *cat); + ast_category_append(cfg, *cat); } else if (cur[0] == '#') { /* A directive */ cur++; @@ -309,21 +376,8 @@ static int cfg_process(struct ast_config *tmp, struct ast_category **cat, char * break; } - if((c = strchr(cur,':'))) { - *c = '\0'; - c++; - arg = c; - } - - if (includelevel < MAX_INCLUDE_LEVEL) { - if(arg && cur) { - ast_log(LOG_WARNING, "Including files with explicit config engine no longer permitted. Please use extconfig.conf to specify all mappings\n"); - } else { - if (!ast_internal_load(cur, tmp, cat, includelevel + 1)) - return -1; - } - } else - ast_log(LOG_WARNING, "Maximum Include level (%d) exceeded\n", includelevel); + if (!ast_config_internal_load(cur, cfg)) + return -1; } else ast_log(LOG_WARNING, "Directive '#include' needs an argument (filename) at line %d of %s\n", lineno, configfile); } @@ -334,7 +388,6 @@ static int cfg_process(struct ast_config *tmp, struct ast_category **cat, char * if (!*cat) { ast_log(LOG_WARNING, "parse error: No category context for line %d of %s\n", lineno, configfile); - ast_destroy(tmp); return -1; } c = strchr(cur, '='); @@ -347,15 +400,14 @@ static int cfg_process(struct ast_config *tmp, struct ast_category **cat, char * c++; } else object = 0; - v = ast_new_variable(ast_strip(cur), ast_strip(c)); + v = ast_variable_new(ast_strip(cur), ast_strip(c)); if (v) { v->lineno = lineno; v->object = object; /* Put and reset comments */ v->blanklines = 0; - variable_append(*cat, v); + ast_variable_append(*cat, v); } else { - ast_destroy(tmp); ast_log(LOG_WARNING, "Out of memory, line %d\n", lineno); return -1; } @@ -367,154 +419,24 @@ static int cfg_process(struct ast_config *tmp, struct ast_category **cat, char * return 0; } -int ast_save(char *configfile, struct ast_config *cfg, char *generator) -{ - FILE *f; - char fn[256]; - char date[256]=""; - time_t t; - struct ast_variable *var; - struct ast_category *cat; - int blanklines = 0; - if (configfile[0] == '/') { - strncpy(fn, configfile, sizeof(fn)-1); - } else { - snprintf(fn, sizeof(fn), "%s/%s", AST_CONFIG_DIR, configfile); - } - time(&t); - strncpy(date, ctime(&t), sizeof(date) - 1); - if ((f = fopen(fn, "w"))) { - if ((option_verbose > 1) && !option_debug) - ast_verbose( VERBOSE_PREFIX_2 "Saving '%s': ", fn); - fprintf(f, ";!\n"); - fprintf(f, ";! Automatically generated configuration file\n"); - fprintf(f, ";! Filename: %s (%s)\n", configfile, fn); - fprintf(f, ";! Generator: %s\n", generator); - fprintf(f, ";! Creation Date: %s", date); - fprintf(f, ";!\n"); - cat = cfg->root; - while(cat) { - /* Dump section with any appropriate comment */ - fprintf(f, "[%s]\n", cat->name); - var = cat->root; - while(var) { - if (var->sameline) - fprintf(f, "%s %s %s ; %s\n", var->name, (var->object ? "=>" : "="), var->value, var->sameline->cmt); - else - fprintf(f, "%s %s %s\n", var->name, (var->object ? "=>" : "="), var->value); - if (var->blanklines) { - blanklines = var->blanklines; - while (blanklines) { - fprintf(f, "\n"); - blanklines--; - } - } - - var = var->next; - } -#if 0 - /* Put an empty line */ - fprintf(f, "\n"); -#endif - cat = cat->next; - } - } else { - if (option_debug) - printf("Unable to open for writing: %s\n", fn); - else if (option_verbose > 1) - printf( "Unable to write (%s)", strerror(errno)); - return -1; - } - fclose(f); - return 0; -} - -struct ast_variable *ast_load_realtime(const char *family, ...) -{ - struct ast_config_reg *reg; - char db[256]=""; - char table[256]=""; - struct ast_variable *res=NULL; - va_list ap; - va_start(ap, family); - reg = get_ast_cust_config_keyword(family, db, sizeof(db), table, sizeof(table)); - if (reg && reg->realtime_func) - res = reg->realtime_func(db, table, ap); - va_end(ap); - return res; -} - -struct ast_config *ast_load_realtime_multientry(const char *family, ...) -{ - struct ast_config_reg *reg; - char db[256]=""; - char table[256]=""; - struct ast_config *res=NULL; - va_list ap; - va_start(ap, family); - reg = get_ast_cust_config_keyword(family, db, sizeof(db), table, sizeof(table)); - if (reg && reg->realtime_multi_func) - res = reg->realtime_multi_func(db, table, ap); - va_end(ap); - return res; -} - -int ast_update_realtime(const char *family, const char *keyfield, const char *lookup, ...) -{ - struct ast_config_reg *reg; - int res = -1; - char db[256]=""; - char table[256]=""; - va_list ap; - va_start(ap, lookup); - reg = get_ast_cust_config_keyword(family, db, sizeof(db), table, sizeof(table)); - if (reg && reg->update_func) - res = reg->update_func(db, table, keyfield, lookup, ap); - va_end(ap); - return res; -} - -struct ast_config *ast_internal_load(const char *configfile, struct ast_config *tmp, struct ast_category **cat, int includelevel) +static struct ast_config *config_text_file_load(const char *database, const char *table, const char *filename, struct ast_config *cfg) { char fn[256]; char buf[8192]; - char db[256]; - char table[256]; + char *new_buf, *comment_p, *process_buf; FILE *f; int lineno=0; int comment = 0, nest[MAX_NESTED_COMMENTS]; + struct ast_category *cat = NULL; - struct ast_config_reg *reg=NULL; - config_static_func *load_func; - char *comment_p, *process_buf, *new_buf=NULL; + cat = ast_config_get_current_category(cfg); - load_func=NULL; - if (strcmp(configfile,config_conf_file) && strcmp(configfile,"asterisk.conf") && ast_cust_config_list) { - if (global_load_func) { - load_func = global_load_func; - } else { - reg = get_ast_cust_config_keyword(configfile, db, sizeof(db), table, sizeof(table)); - if (reg && reg->static_func) { - load_func = reg->static_func; - } else { - reg = get_ast_cust_config_keyword(configfile, db, sizeof(db), table, sizeof(table)); - if (reg && reg->static_func) - global_load_func = load_func = reg->static_func; - } - } - - if (load_func) { - ast_log(LOG_NOTICE,"Loading Config %s via %s engine\n",configfile,reg && reg->name ? reg->name : "global"); - if((tmp = load_func(db, table, configfile, tmp, cat, includelevel))) - return tmp; - } - } - - if (configfile[0] == '/') { - strncpy(fn, configfile, sizeof(fn)-1); + if (filename[0] == '/') { + strncpy(fn, filename, sizeof(fn)-1); } else { - snprintf(fn, sizeof(fn), "%s/%s", (char *)ast_config_AST_CONFIG_DIR, configfile); + snprintf(fn, sizeof(fn), "%s/%s", (char *)ast_config_AST_CONFIG_DIR, filename); } + #ifdef AST_INCLUDE_GLOB { int glob_ret; @@ -546,13 +468,6 @@ struct ast_config *ast_internal_load(const char *configfile, struct ast_config * ast_log(LOG_DEBUG, "Parsing %s\n", fn); else if (option_verbose > 2) ast_verbose("Found\n"); - if (!tmp) - tmp = ast_new_config(); - if (!tmp) { - ast_log(LOG_WARNING, "Out of memory\n"); - fclose(f); - return tmp; - } while(!feof(f)) { lineno++; if (fgets(buf, sizeof(buf), f)) { @@ -603,8 +518,8 @@ struct ast_config *ast_internal_load(const char *configfile, struct ast_config * new_buf = comment_p + 1; } } - if (process_buf && cfg_process(tmp, cat, process_buf, lineno, configfile, includelevel)) { - tmp = NULL; + if (process_buf && process_text_line(cfg, &cat, process_buf, lineno, filename)) { + cfg = NULL; break; } } @@ -620,7 +535,7 @@ struct ast_config *ast_internal_load(const char *configfile, struct ast_config * ast_log(LOG_WARNING,"Unterminated comment detected beginning on line %d\n", nest[comment]); } #ifdef AST_INCLUDE_GLOB - if (!tmp) + if (!cfg) break; } globfree(&globbuf); @@ -628,233 +543,357 @@ struct ast_config *ast_internal_load(const char *configfile, struct ast_config * } #endif - return tmp; + return cfg; } -int ast_config_register(struct ast_config_reg *new) +int config_text_file_save(const char *configfile, const struct ast_config *cfg, const char *generator) { - struct ast_config_reg *ptr; - ast_mutex_lock(&ast_cust_config_lock); - if (!ast_cust_config_list) { - ast_cust_config_list = new; - } else { - for(ptr=ast_cust_config_list;ptr->next;ptr=ptr->next); - ptr->next = new; - } - ast_mutex_unlock(&ast_cust_config_lock); - ast_log(LOG_NOTICE,"Registered Config Engine %s\n",new->name); - return 1; -} - -int ast_config_deregister(struct ast_config_reg *del) -{ - struct ast_config_reg *ptr=NULL,*last=NULL; - ast_mutex_lock(&ast_cust_config_lock); - for (ptr=ast_cust_config_list;ptr;ptr=ptr->next) { - if (ptr == del) { - if (last && ptr->next) { - last->next = ptr->next; - } else if (last && ! ptr->next) { - last->next = NULL; - } else if (!last && ptr->next) { - ast_cust_config_list = ptr->next; - } else if (!last && !ptr->next) { - ast_cust_config_list = NULL; - } - } - last = ptr; - } - ast_mutex_unlock(&ast_cust_config_lock); - return 0; -} - -int ast_cust_config_active(void) { - return (ast_cust_config >0) ? 1 : 0; -} - -struct ast_config *ast_load(char *configfile) -{ - struct ast_category *category = NULL; - - return ast_internal_load(configfile, NULL, &category, 0); -} - -char *ast_category_browse(struct ast_config *config, char *prev) -{ + FILE *f; + char fn[256]; + char date[256]=""; + time_t t; + struct ast_variable *var; struct ast_category *cat; - if (!prev) { - if (config->root) - return config->root->name; - else - return NULL; + int blanklines = 0; + + if (configfile[0] == '/') { + strncpy(fn, configfile, sizeof(fn)-1); + } else { + snprintf(fn, sizeof(fn), "%s/%s", AST_CONFIG_DIR, configfile); } - cat = config->root; - while(cat) { - if (cat->name == prev) { - if (cat->next) - return cat->next->name; - else - return NULL; + time(&t); + strncpy(date, ctime(&t), sizeof(date) - 1); + if ((f = fopen(fn, "w"))) { + if ((option_verbose > 1) && !option_debug) + ast_verbose( VERBOSE_PREFIX_2 "Saving '%s': ", fn); + fprintf(f, ";!\n"); + fprintf(f, ";! Automatically generated configuration file\n"); + fprintf(f, ";! Filename: %s (%s)\n", configfile, fn); + fprintf(f, ";! Generator: %s\n", generator); + fprintf(f, ";! Creation Date: %s", date); + fprintf(f, ";!\n"); + cat = cfg->root; + while(cat) { + /* Dump section with any appropriate comment */ + fprintf(f, "[%s]\n", cat->name); + var = cat->root; + while(var) { + if (var->sameline) + fprintf(f, "%s %s %s ; %s\n", var->name, (var->object ? "=>" : "="), var->value, var->sameline->cmt); + else + fprintf(f, "%s %s %s\n", var->name, (var->object ? "=>" : "="), var->value); + if (var->blanklines) { + blanklines = var->blanklines; + while (blanklines--) + fprintf(f, "\n"); + } + + var = var->next; + } +#if 0 + /* Put an empty line */ + fprintf(f, "\n"); +#endif + cat = cat->next; } - cat = cat->next; + } else { + if (option_debug) + printf("Unable to open for writing: %s\n", fn); + else if (option_verbose > 1) + printf( "Unable to write (%s)", strerror(errno)); + return -1; } - cat = config->root; - while(cat) { - if (!strcasecmp(cat->name, prev)) { - if (cat->next) - return cat->next->name; - else - return NULL; - } - cat = cat->next; - } - return NULL; -} - - -struct ast_config *ast_new_config(void) -{ - struct ast_config *config; - config = malloc(sizeof(struct ast_config)); - memset(config,0,sizeof(struct ast_config)); - return config; -} - -struct ast_category *ast_new_category(char *name) -{ - struct ast_category *category; - category = malloc(sizeof(struct ast_category)); - if (category) { - memset(category, 0, sizeof(struct ast_category)); - strncpy(category->name, name, sizeof(category->name) - 1); - } - return category; -} - -struct ast_variable *ast_new_variable(char *name, char *value) -{ - struct ast_variable *variable; - int length = strlen(name) + strlen(value) + 2 + sizeof(struct ast_variable); - variable = malloc(length); - if (variable) { - memset(variable, 0, length); - variable->name = variable->stuff; - variable->value = variable->stuff + strlen(name) + 1; - strcpy(variable->name,name); - strcpy(variable->value,value); - } - return variable; -} - -int ast_cust_config_register(struct ast_config_reg *new) -{ - ast_config_register(new); - read_ast_cust_config(); - return 1; -} -int ast_cust_config_deregister(struct ast_config_reg *new) -{ - ast_config_deregister(new); - read_ast_cust_config(); - return 1; -} - -static void clear_cust_keywords(void) -{ - struct ast_config_map *map, *prev; - ast_mutex_lock(&ast_cust_config_lock); - map = maps; - while(map) { - prev = map; - map = map->next; - free(prev); - } - maps = NULL; - ast_mutex_unlock(&ast_cust_config_lock); -} - -static int config_command(int fd, int argc, char **argv) -{ - struct ast_config_reg *key; - struct ast_config_map *map; - - ast_cli(fd,"\n\n"); - ast_mutex_lock(&ast_cust_config_lock); - for (key=get_config_registrations();key;key=key->next) { - ast_cli(fd,"\nConfig Engine: %s\n",key->name); - map = maps; - while(map) { - if (!strcasecmp(map->driver, key->name)) - ast_cli(fd,"===> %s (db=%s, table=%s)\n",map->name, map->database, map->table ? map->table : map->name); - map = map->next; - } - } - ast_mutex_unlock(&ast_cust_config_lock); - ast_cli(fd,"\n\n"); - + fclose(f); return 0; } -static struct ast_cli_entry config_command_struct = { - { "show","config","handles", NULL }, config_command, - "Show Config Handles", NULL }; - -int register_config_cli() +static void clear_config_maps(void) { - return ast_cli_register(&config_command_struct); + struct ast_config_map *map; + + ast_mutex_lock(&config_lock); + + while (config_maps) { + map = config_maps; + config_maps = config_maps->next; + free(map); + } + + ast_mutex_unlock(&config_lock); } -int read_ast_cust_config(void) +void read_config_maps(void) { - char *cfg = config_conf_file; struct ast_config *config; struct ast_variable *v; struct ast_config_map *map; int length; char *driver, *table, *database, *stringp; - clear_cust_keywords(); - config = ast_load(cfg); - if (config) { - for (v = ast_variable_browse(config,"settings");v;v=v->next) { - stringp = v->value; - driver = strsep(&stringp, ","); - database = strsep(&stringp, ","); - table = strsep(&stringp, ","); + clear_config_maps(); + + config = ast_config_new(); + config->max_include_level = 1; + config = ast_config_internal_load(extconfig_conf, config); + if (!config) + return; + + for (v = ast_variable_browse(config, "settings"); v; v = v->next) { + stringp = v->value; + driver = strsep(&stringp, ","); + database = strsep(&stringp, ","); + table = strsep(&stringp, ","); - if (!strcmp(v->name,config_conf_file) || !strcmp(v->name,"asterisk.conf")) { - ast_log(LOG_WARNING, "Cannot bind asterisk.conf or extconfig.conf!\n"); - } else if (driver && database) { - length = sizeof(struct ast_config_map); - length += strlen(v->name) + 1; - length += strlen(driver) + 1; - length += strlen(database) + 1; - if (table) - length += strlen(table) + 1; - map = malloc(length); - if (map) { - memset(map, 0, length); - map->name = map->stuff; - strcpy(map->name, v->name); - map->driver = map->name + strlen(map->name) + 1; - strcpy(map->driver, driver); - map->database = map->driver + strlen(map->driver) + 1; - strcpy(map->database, database); - if (table) { - map->table = map->database + strlen(map->database) + 1; - strcpy(map->table, table); - } else - map->table = NULL; - map->next = maps; - if (option_verbose > 1) - ast_verbose(VERBOSE_PREFIX_2 "Binding %s to %s/%s/%s\n",map->name,map->driver, map->database, map->table ? map->table : map->name); - maps = map; - } - } + if (!strcmp(v->name, extconfig_conf) || !strcmp(v->name, "asterisk.conf")) { + ast_log(LOG_WARNING, "Cannot bind asterisk.conf or extconfig.conf!\n"); + continue; } - - ast_destroy(config); + + if (!driver || !database) + continue; + + length = sizeof(*map); + length += strlen(v->name) + 1; + length += strlen(driver) + 1; + length += strlen(database) + 1; + if (table) + length += strlen(table) + 1; + map = malloc(length); + + if (!map) + continue; + + memset(map, 0, length); + map->name = map->stuff; + strcpy(map->name, v->name); + map->driver = map->name + strlen(map->name) + 1; + strcpy(map->driver, driver); + map->database = map->driver + strlen(map->driver) + 1; + strcpy(map->database, database); + if (table) { + map->table = map->database + strlen(map->database) + 1; + strcpy(map->table, table); + } + map->next = config_maps; + + if (option_verbose > 1) + ast_verbose(VERBOSE_PREFIX_2 "Binding %s to %s/%s/%s\n", + map->name, map->driver, map->database, map->table ? map->table : map->name); + + config_maps = map; } + + ast_config_destroy(config); +} + +int ast_config_engine_register(struct ast_config_engine *new) +{ + struct ast_config_engine *ptr; + + ast_mutex_lock(&config_lock); + + if (!config_engine_list) { + config_engine_list = new; + } else { + for (ptr = config_engine_list; ptr->next; ptr=ptr->next); + ptr->next = new; + } + + ast_mutex_unlock(&config_lock); + ast_log(LOG_NOTICE,"Registered Config Engine %s\n", new->name); + + return 1; +} + +int ast_config_engine_deregister(struct ast_config_engine *del) +{ + struct ast_config_engine *ptr, *last=NULL; + + ast_mutex_lock(&config_lock); + + for (ptr = config_engine_list; ptr; ptr=ptr->next) { + if (ptr == del) { + if (last) + last->next = ptr->next; + else + config_engine_list = ptr->next; + break; + } + last = ptr; + } + + ast_mutex_unlock(&config_lock); return 0; } + +static struct ast_config_engine *find_engine(const char *filename, char *database, int dbsiz, char *table, int tabsiz) +{ + struct ast_config_engine *eng, *ret=NULL; + struct ast_config_map *map; + + ast_mutex_lock(&config_lock); + + map = config_maps; + while (map) { + if (!strcasecmp(filename, map->name)) { + strncpy(database, map->database, dbsiz-1); + if (map->table) + strncpy(table, map->table, tabsiz-1); + else + strncpy(table, filename, tabsiz-1); + break; + } + map = map->next; + } + if (map) { + for (eng = config_engine_list; eng; eng = eng->next) { + if (!strcmp(eng->name, map->driver)) { + ret = eng; + break; + } + } + } + ast_mutex_unlock(&config_lock); + + return ret; +} + +static struct ast_config_engine text_file_engine = { + .name = "text", + .load_func = config_text_file_load, +}; + +struct ast_config *ast_config_internal_load(const char *filename, struct ast_config *cfg) +{ + char db[256]; + char table[256]; + struct ast_config_engine *loader = &text_file_engine; + struct ast_config *result; + + if (cfg->include_level == cfg->max_include_level) { + ast_log(LOG_WARNING, "Maximum Include level (%d) exceeded\n", cfg->max_include_level); + return NULL; + } + + cfg->include_level++; + + if (strcmp(filename, extconfig_conf) && strcmp(filename, "asterisk.conf") && config_engine_list) { + struct ast_config_engine *eng; + + eng = find_engine(filename, db, sizeof(db), table, sizeof(table)); + if (eng && eng->load_func) { + loader = eng; + } else { + eng = find_engine("global", db, sizeof(db), table, sizeof(table)); + if (eng && eng->load_func) + loader = eng; + } + } + + result = loader->load_func(db, table, filename, cfg); + if (result) + result->include_level--; + + 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); + if (!result) + ast_config_destroy(cfg); + + return result; +} + +struct ast_variable *ast_load_realtime(const char *family, ...) +{ + struct ast_config_engine *eng; + char db[256]=""; + char table[256]=""; + struct ast_variable *res=NULL; + va_list ap; + + va_start(ap, family); + eng = find_engine(family, db, sizeof(db), table, sizeof(table)); + if (eng && eng->realtime_func) + res = eng->realtime_func(db, table, ap); + va_end(ap); + + return res; +} + +struct ast_config *ast_load_realtime_multientry(const char *family, ...) +{ + struct ast_config_engine *eng; + char db[256]=""; + char table[256]=""; + struct ast_config *res=NULL; + va_list ap; + + va_start(ap, family); + eng = find_engine(family, db, sizeof(db), table, sizeof(table)); + if (eng && eng->realtime_multi_func) + res = eng->realtime_multi_func(db, table, ap); + va_end(ap); + + return res; +} + +int ast_update_realtime(const char *family, const char *keyfield, const char *lookup, ...) +{ + struct ast_config_engine *eng; + int res = -1; + char db[256]=""; + char table[256]=""; + va_list ap; + + va_start(ap, lookup); + eng = find_engine(family, db, sizeof(db), table, sizeof(table)); + if (eng && eng->update_func) + res = eng->update_func(db, table, keyfield, lookup, ap); + va_end(ap); + + return res; +} + +static int config_command(int fd, int argc, char **argv) +{ + struct ast_config_engine *eng; + struct ast_config_map *map; + + ast_mutex_lock(&config_lock); + + ast_cli(fd, "\n\n"); + for (eng = config_engine_list; eng; eng = eng->next) { + ast_cli(fd, "\nConfig Engine: %s\n", eng->name); + for (map = config_maps; map; map = map->next) + if (!strcasecmp(map->driver, eng->name)) { + ast_cli(fd, "===> %s (db=%s, table=%s)\n", map->name, map->database, + map->table ? map->table : map->name); + break; + } + } + ast_cli(fd,"\n\n"); + + ast_mutex_unlock(&config_lock); + + return 0; +} + +static struct ast_cli_entry config_command_struct = { + { "show", "config", "mappings" }, config_command, "Show Config mappings (file names to config engines)" +}; + +int register_config_cli() +{ + return ast_cli_register(&config_command_struct); +} diff --git a/enum.c b/enum.c index 690587163a..6265f5f756 100755 --- a/enum.c +++ b/enum.c @@ -413,7 +413,7 @@ int ast_enum_init(void) free(sl); } toplevs = NULL; - cfg = ast_load("enum.conf"); + cfg = ast_config_load("enum.conf"); if (cfg) { sl = NULL; v = ast_variable_browse(cfg, "general"); @@ -430,7 +430,7 @@ int ast_enum_init(void) } v = v->next; } - ast_destroy(cfg); + ast_config_destroy(cfg); } else { toplevs = enum_newtoplev(TOPLEV); } diff --git a/include/asterisk/config.h b/include/asterisk/config.h index b8be39bf7c..a400fef51d 100755 --- a/include/asterisk/config.h +++ b/include/asterisk/config.h @@ -3,9 +3,9 @@ * * Configuration File Parser * - * Copyright (C) 1999, Mark Spencer + * Copyright (C) 1999-2005, Mark Spencer * - * Mark Spencer + * Mark Spencer * * This program is free software, distributed under the terms of * the GNU General Public License @@ -18,12 +18,11 @@ extern "C" { #endif +#include + struct ast_config; -struct ast_comment { - struct ast_comment *next; - char cmt[0]; -}; +struct ast_category; struct ast_variable { char *name; @@ -37,35 +36,54 @@ struct ast_variable { char stuff[0]; }; +#include + +typedef struct ast_config *config_load_func(const char *database, const char *table, const char *configfile, struct ast_config *config); +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); + +struct ast_config_engine { + char *name; + config_load_func *load_func; + realtime_var_get *realtime_func; + realtime_multi_get *realtime_multi_func; + realtime_update *update_func; + struct ast_config_engine *next; +}; + /*! Load a config file */ /*! * \param configfile 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. + * * Returns NULL on error, or an ast_config data structure on success */ -struct ast_config *ast_load(char *configfile); +struct ast_config *ast_config_load(const char *filename); -/*! Removes a config */ +/*! Destroys a config */ /*! - * \param config config data structure associated with the config. + * \param config pointer to config data structure * Free memory associated with a given config - * Returns nothing + * */ -void ast_destroy(struct ast_config *config); +void ast_config_destroy(struct ast_config *config); /*! Goes through categories */ /*! - * \param config Which config file you wish to "browse" + * \param config Which config structure you wish to "browse" * \param prev A pointer to a previous category. - * This funtion is kind of non-intuitive in it's use. To begin, one passes NULL as the second arguement. It will return a pointer to the string of the first category in the file. From here on after, one must then pass the previous usage's return value as the second pointer, and it will return a pointer to the category name afterwards. Note: If you manually strcpy a string into a character array and pass it thinking it will return your category, it will not; the comparisons are not done doing strcmp, they are done by checking whether the value of the string POINTER is the same. + * This funtion is kind of non-intuitive in it's use. To begin, one passes NULL as the second arguement. It will return a pointer to the string of the first category in the file. From here on after, one must then pass the previous usage's return value as the second pointer, and it will return a pointer to the category name afterwards. + * * Returns a category on success, or NULL on failure/no-more-categories */ -char *ast_category_browse(struct ast_config *config, char *prev); +char *ast_category_browse(struct ast_config *config, const char *prev); /*! Goes through variables */ /*! - * Somewhat similar in intent as the ast_category_browse. The category MUST be an actual pointer to an actual category (such as one obtained by using ast_category_browse()). - * List variables of config file + * Somewhat similar in intent as the ast_category_browse. + * List variables of config file category + * * Returns ast_variable list on success, or NULL on failure */ struct ast_variable *ast_variable_browse(const struct ast_config *config, const char *category); @@ -73,43 +91,51 @@ struct ast_variable *ast_variable_browse(const struct ast_config *config, const /*! Gets a variable */ /*! * \param config which (opened) config to use - * \param category category under which the variable lies (must be a pointer to the category, such as one given by ast_category_browse) + * \param category category under which the variable lies * \param value which variable you wish to get the data for * Goes through a given config file in the given category and searches for the given variable + * * Returns the variable value on success, or NULL if unable to find it. - * Retrieve a specific variable */ -char *ast_variable_retrieve(const struct ast_config *config, const char *category, const char *value); + */ +char *ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable); /*! Make sure something is true */ /*! - * Determine affermativeness of a boolean value. - * This function checks to see whether a string passed to it is an indication of an affirmitave value. It checks to see if the string is "yes", "true", "y", "t", and "1". - * Returns 0 if the value of s is a NULL pointer, 0 on "truth", and -1 on falsehood. + * Determine if a string containing a boolean value is "true". + * This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1". + * + * Returns 0 if val is a NULL pointer, -1 if "true", and 0 otherwise. */ int ast_true(const char *val); /*! Make sure something is false */ /*! - * Determine falseness of a boolean value. - * This function checks to see whether a string passed to it is an indication of a negatirve value. It checks to see if the string is "no", "false", "n", "f", and "0". - * Returns 0 if the value of s is a NULL pointer, 0 on "truth", and -1 on falsehood. + * Determine if a string containing a boolean value is "false". + * This function checks to see whether a string passed to it is an indication of an "false" value. It checks to see if the string is "no", "false", "n", "f", "off" or "0". + * + * Returns 0 if val is a NULL pointer, -1 if "false", and 0 otherwise. */ int ast_false(const char *val); -/*! Retrieve a category if it exists +/*! Retrieve a category if it exists */ +/*! * \param config which config to use * \param category_name name of the category you're looking for - * This will search through the categories within a given config file and search for a match. The passed category_name can be a regular string. - * Returns pointer to category if found, NULL if not. */ + * This will search through the categories within a given config file for a match. + * + * Returns pointer to category if found, NULL if not. + */ struct ast_category *ast_category_get(const struct ast_config *config, const char *category_name); /*! Check for category duplicates */ /*! * \param config which config to use * \param category_name name of the category you're looking for - * This will search through the categories within a given config file and search for a match. The passed category_name can be a regular string (as opposed to a pointer of an existent string, lol) - * Browse config structure and check for category duplicity Return non-zero if found */ -int ast_category_exist(struct ast_config *config, char *category_name); + * This will search through the categories within a given config file for a match. + * + * Return non-zero if found + */ +int ast_category_exist(const struct ast_config *config, const char *category_name); /*! Retrieve realtime configuration */ /*! @@ -148,18 +174,39 @@ struct ast_config *ast_load_realtime_multientry(const char *family, ...); */ int ast_update_realtime(const char *family, const char *keyfield, const char *lookup, ...); -/*! Free realtime configuration */ +/*! Free variable list */ /*! * \param var the linked list of variables to free - * This command free's a list of variables and should ONLY be used - * in conjunction with ast_load_realtime and not with the regular ast_load. + * This function frees a list of variables. */ -void ast_destroy_realtime(struct ast_variable *var); +void ast_variables_destroy(struct ast_variable *var); + +int ast_config_engine_register(struct ast_config_engine *new); +int ast_config_engine_deregister(struct ast_config_engine *del); +int register_config_cli(void); +void read_config_maps(void); + +struct ast_config *ast_config_new(void); +struct ast_category *ast_config_get_current_category(const struct ast_config *cfg); +void ast_config_set_current_category(struct ast_config *cfg, const struct ast_category *cat); + +struct ast_category *ast_category_new(const char *name); +void ast_category_append(struct ast_config *config, struct ast_category *cat); +int ast_category_delete(struct ast_config *cfg, char *category); +void ast_category_destroy(struct ast_category *cat); +struct ast_variable *ast_category_detach_variables(struct ast_category *cat); +void ast_category_rename(struct ast_category *cat, const char *name); + +struct ast_variable *ast_variable_new(const char *name, const char *value); +void ast_variable_append(struct ast_category *category, struct ast_variable *variable); +int ast_variable_delete(struct ast_config *cfg, char *category, char *variable, char *value); + +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); #if defined(__cplusplus) || defined(c_plusplus) } #endif - - #endif diff --git a/loader.c b/loader.c index a1f01c7bca..911fb947de 100755 --- a/loader.c +++ b/loader.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include @@ -169,9 +168,9 @@ char *ast_module_helper(char *line, char *word, int pos, int state, int rpos, in ret = strdup(m->resource); } else { ret = NULL; - if (!strncasecmp(word, "astconfig", strlen(word))) { + if (!strncasecmp(word, "extconfig", strlen(word))) { if (++which > state) - ret = strdup("astconfig"); + ret = strdup("extconfig"); } else if (!strncasecmp(word, "manager", strlen(word))) { if (++which > state) ret = strdup("manager"); @@ -200,8 +199,8 @@ int ast_module_reload(const char *name) ast_verbose("The previous reload command didn't finish yet\n"); return -1; } - if (!name || !strcasecmp(name, "astconfig")) { - read_ast_cust_config(); + if (!name || !strcasecmp(name, "extconfig")) { + read_config_maps(); reloaded = 2; } if (!name || !strcasecmp(name, "manager")) { @@ -403,11 +402,11 @@ int ast_load_resource(const char *resource_name) /* Keep the module file parsing silent */ o = option_verbose; option_verbose = 0; - cfg = ast_load(AST_MODULE_CONFIG); + cfg = ast_config_load(AST_MODULE_CONFIG); option_verbose = o; res = __load_resource(resource_name, cfg); if (cfg) - ast_destroy(cfg); + ast_config_destroy(cfg); return res; } @@ -444,7 +443,7 @@ int load_modules() char tmp[80]; if (option_verbose) ast_verbose( "Asterisk Dynamic Loader Starting:\n"); - cfg = ast_load(AST_MODULE_CONFIG); + cfg = ast_config_load(AST_MODULE_CONFIG); if (cfg) { /* Load explicitly defined modules */ v = ast_variable_browse(cfg, "modules"); @@ -459,7 +458,7 @@ int load_modules() if (__load_resource(v->value, cfg)) { ast_log(LOG_WARNING, "Loading module %s failed!\n", v->value); if (cfg) - ast_destroy(cfg); + ast_config_destroy(cfg); return -1; } } @@ -509,7 +508,7 @@ int load_modules() if (__load_resource(d->d_name, cfg)) { ast_log(LOG_WARNING, "Loading module %s failed!\n", d->d_name); if (cfg) - ast_destroy(cfg); + ast_config_destroy(cfg); return -1; } } @@ -521,7 +520,7 @@ int load_modules() } } } - ast_destroy(cfg); + ast_config_destroy(cfg); return 0; } diff --git a/logger.c b/logger.c index 607e9213a6..d9e5dfd32c 100755 --- a/logger.c +++ b/logger.c @@ -267,7 +267,7 @@ static void init_logger_chain(void) /* close syslog */ closelog(); - cfg = ast_load("logger.conf"); + cfg = ast_config_load("logger.conf"); /* If no config file, we're fine */ if (!cfg) @@ -299,7 +299,7 @@ static void init_logger_chain(void) var = var->next; } - ast_destroy(cfg); + ast_config_destroy(cfg); ast_mutex_unlock(&loglock); } diff --git a/manager.c b/manager.c index 8017da7d07..2f93090406 100755 --- a/manager.c +++ b/manager.c @@ -398,7 +398,7 @@ static int authenticate(struct mansession *s, struct message *m) char *key = astman_get_header(m, "Key"); char *events = astman_get_header(m, "Events"); - cfg = ast_load("manager.conf"); + cfg = ast_config_load("manager.conf"); if (!cfg) return -1; cat = ast_category_browse(cfg, NULL); @@ -423,7 +423,7 @@ static int authenticate(struct mansession *s, struct message *m) if (ha && !ast_apply_ha(ha, &(s->sin))) { ast_log(LOG_NOTICE, "%s failed to pass IP ACL as '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), s->sin.sin_addr), user); ast_free_ha(ha); - ast_destroy(cfg); + ast_config_destroy(cfg); return -1; } else if (ha) ast_free_ha(ha); @@ -443,7 +443,7 @@ static int authenticate(struct mansession *s, struct message *m) if (!strcmp(md5key, key)) break; else { - ast_destroy(cfg); + ast_config_destroy(cfg); return -1; } } @@ -451,7 +451,7 @@ static int authenticate(struct mansession *s, struct message *m) break; } else { ast_log(LOG_NOTICE, "%s failed to authenticate as '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), s->sin.sin_addr), user); - ast_destroy(cfg); + ast_config_destroy(cfg); return -1; } } @@ -462,13 +462,13 @@ static int authenticate(struct mansession *s, struct message *m) strncpy(s->username, cat, sizeof(s->username) - 1); s->readperm = get_perm(ast_variable_retrieve(cfg, cat, "read")); s->writeperm = get_perm(ast_variable_retrieve(cfg, cat, "write")); - ast_destroy(cfg); + ast_config_destroy(cfg); if (events) set_eventmask(s, events); return 0; } ast_log(LOG_NOTICE, "%s tried to authenticate with non-existant user '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), s->sin.sin_addr), user); - ast_destroy(cfg); + ast_config_destroy(cfg); return -1; } @@ -1455,7 +1455,7 @@ int init_manager(void) } portno = DEFAULT_MANAGER_PORT; displayconnects = 1; - cfg = ast_load("manager.conf"); + 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; @@ -1507,7 +1507,7 @@ int init_manager(void) ast_log(LOG_WARNING, "Unable to change management port / enabled\n"); #endif } - ast_destroy(cfg); + ast_config_destroy(cfg); /* If not enabled, do nothing */ if (!enabled) { diff --git a/pbx/pbx_config.c b/pbx/pbx_config.c index a840e2bd2d..74f951f622 100755 --- a/pbx/pbx_config.c +++ b/pbx/pbx_config.c @@ -972,13 +972,13 @@ static int handle_save_dialplan(int fd, int argc, char *argv[]) snprintf(filename, sizeof(filename), "%s/%s", (char *)ast_config_AST_CONFIG_DIR, config); - cfg = ast_load("extensions.conf"); + cfg = ast_config_load("extensions.conf"); /* try to lock contexts list */ if (ast_lock_contexts()) { ast_cli(fd, "Failed to lock contexts list\n"); ast_mutex_unlock(&save_dialplan_lock); - ast_destroy(cfg); + ast_config_destroy(cfg); return RESULT_FAILURE; } @@ -988,7 +988,7 @@ static int handle_save_dialplan(int fd, int argc, char *argv[]) filename); ast_unlock_contexts(); ast_mutex_unlock(&save_dialplan_lock); - ast_destroy(cfg); + ast_config_destroy(cfg); return RESULT_FAILURE; } @@ -1006,7 +1006,7 @@ static int handle_save_dialplan(int fd, int argc, char *argv[]) fprintf(output, "\n"); } - ast_destroy(cfg); + ast_config_destroy(cfg); /* walk all contexts */ c = ast_walk_contexts(NULL); @@ -1623,7 +1623,7 @@ static int pbx_load_module(void) char realvalue[256]; int lastpri = -2; - cfg = ast_load(config); + cfg = ast_config_load(config); if (cfg) { /* Use existing config to populate the PBX table */ static_config = ast_true(ast_variable_retrieve(cfg, "general", @@ -1775,7 +1775,7 @@ static int pbx_load_module(void) } cxt = ast_category_browse(cfg, cxt); } - ast_destroy(cfg); + ast_config_destroy(cfg); } ast_merge_contexts_and_delete(&local_contexts,registrar); diff --git a/pbx/pbx_dundi.c b/pbx/pbx_dundi.c index cc927080b8..dc3ee80ed8 100755 --- a/pbx/pbx_dundi.c +++ b/pbx/pbx_dundi.c @@ -4446,7 +4446,7 @@ static int set_config(char *config_file, struct sockaddr_in* sin) dundi_eid testeid; dundi_ttl = DUNDI_DEFAULT_TTL; - cfg = ast_load(config_file); + cfg = ast_config_load(config_file); if (!cfg) { @@ -4569,7 +4569,7 @@ static int set_config(char *config_file, struct sockaddr_in* sin) cat = ast_category_browse(cfg, cat); } prune_peers(); - ast_destroy(cfg); + ast_config_destroy(cfg); load_password(); if (globalpcmodel & DUNDI_MODEL_OUTBOUND) dundi_precache_full(); diff --git a/pbx/pbx_realtime.c b/pbx/pbx_realtime.c index f0e3bcf622..2d5eeacc95 100755 --- a/pbx/pbx_realtime.c +++ b/pbx/pbx_realtime.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -92,7 +91,6 @@ static struct ast_variable *realtime_switch_common(const char *table, const char { struct ast_variable *var; struct ast_config *cfg; - struct ast_category *cat; char pri[20]; char *ematch; char rexten[AST_MAX_EXTENSION + 20]=""; @@ -116,27 +114,27 @@ static struct ast_variable *realtime_switch_common(const char *table, const char if (!var) { cfg = ast_load_realtime_multientry(table, "exten LIKE", "\\_%", "context", context, "priority", pri, NULL); if (cfg) { - cat = cfg->root; + char *cat = ast_category_browse(cfg, NULL); + while(cat) { switch(mode) { case MODE_MATCHMORE: - match = ast_extension_close(cat->name, exten, 1); + match = ast_extension_close(cat, exten, 1); break; case MODE_CANMATCH: - match = ast_extension_close(cat->name, exten, 0); + match = ast_extension_close(cat, exten, 0); break; case MODE_MATCH: default: - match = ast_extension_match(cat->name, exten); + match = ast_extension_match(cat, exten); } if (match) { - var = cat->root; - cat->root = NULL; + var = ast_category_detach_variables(ast_category_get(cfg, cat)); break; } - cat = cat->next; + cat = ast_category_browse(cfg, cat); } - ast_destroy(cfg); + ast_config_destroy(cfg); } } return var; @@ -145,7 +143,7 @@ static struct ast_variable *realtime_switch_common(const char *table, const char static int realtime_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) { REALTIME_COMMON(MODE_MATCH); - if (var) ast_destroy_realtime(var); + if (var) ast_variables_destroy(var); if (var) res = 1; return res > 0 ? res : 0; @@ -154,7 +152,7 @@ static int realtime_exists(struct ast_channel *chan, const char *context, const static int realtime_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) { REALTIME_COMMON(MODE_CANMATCH); - if (var) ast_destroy_realtime(var); + if (var) ast_variables_destroy(var); if (var) res = 1; return res > 0 ? res : 0; @@ -180,7 +178,7 @@ static int realtime_exec(struct ast_channel *chan, const char *context, const ch tmp = ast_strdupa(v->value); v = v->next; } - ast_destroy_realtime(var); + ast_variables_destroy(var); if (!ast_strlen_zero(app)) { a = pbx_findapp(app); if (a) { @@ -212,7 +210,7 @@ static int realtime_exec(struct ast_channel *chan, const char *context, const ch static int realtime_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) { REALTIME_COMMON(MODE_MATCHMORE); - if (var) ast_destroy_realtime(var); + if (var) ast_variables_destroy(var); if (var) res = 1; return res > 0 ? res : 0; diff --git a/res/res_adsi.c b/res/res_adsi.c index 2ee440e6a7..de53871e44 100755 --- a/res/res_adsi.c +++ b/res/res_adsi.c @@ -1024,7 +1024,7 @@ static void adsi_load(void) struct ast_variable *v; char *name, *sname; init_state(); - conf = ast_load("adsi.conf"); + conf = ast_config_load("adsi.conf"); if (conf) { x=0; v = ast_variable_browse(conf, "intro"); @@ -1067,7 +1067,7 @@ static void adsi_load(void) } if (x) speeds = x; - ast_destroy(conf); + ast_config_destroy(conf); } } diff --git a/res/res_config_odbc.c b/res/res_config_odbc.c index 246dd80a8f..d83a4b5e20 100755 --- a/res/res_config_odbc.c +++ b/res/res_config_odbc.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include @@ -25,8 +24,6 @@ #include static char *tdesc = "ODBC Configuration"; -static struct ast_config_reg reg1; - STANDARD_LOCAL_USER; LOCAL_USER_DECL; @@ -136,14 +133,14 @@ static struct ast_variable *realtime_odbc(const char *database, const char *tabl if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { ast_log(LOG_WARNING, "SQL Describe Column error!\n[%s]\n\n", sql); if (var) - ast_destroy_realtime(var); + ast_variables_destroy(var); return NULL; } res = SQLGetData(stmt, x + 1, SQL_CHAR, rowdata, sizeof(rowdata), NULL); if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { ast_log(LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql); if (var) - ast_destroy_realtime(var); + ast_variables_destroy(var); return NULL; } stringp = rowdata; @@ -151,11 +148,11 @@ static struct ast_variable *realtime_odbc(const char *database, const char *tabl chunk = strsep(&stringp, ";"); if (chunk && !ast_strlen_zero(ast_strip(chunk))) { if (prev) { - prev->next = ast_new_variable(coltitle, chunk); + prev->next = ast_variable_new(coltitle, chunk); if (prev->next) prev = prev->next; } else - prev = var = ast_new_variable(coltitle, chunk); + prev = var = ast_variable_new(coltitle, chunk); } } @@ -174,7 +171,6 @@ static struct ast_config *realtime_multi_odbc(const char *database, const char * char sql[1024]; char coltitle[256]; char rowdata[2048]; - char *title=NULL; const char *initfield=NULL; char *op; const char *newparam, *newval; @@ -183,7 +179,7 @@ static struct ast_config *realtime_multi_odbc(const char *database, const char * SQLSMALLINT collen; int res; int x; - struct ast_variable *var=NULL, *prev=NULL; + struct ast_variable *var=NULL; struct ast_config *cfg=NULL; struct ast_category *cat=NULL; struct ast_realloca ra; @@ -268,15 +264,25 @@ static struct ast_config *realtime_multi_odbc(const char *database, const char * return NULL; } + cfg = ast_config_new(); + if (!cfg) { + ast_log(LOG_WARNING, "Out of memory!\n"); + SQLFreeHandle (SQL_HANDLE_STMT, stmt); + return NULL; + } + while (rowcount--) { var = NULL; - prev = NULL; - title = NULL; res = SQLFetch(stmt); if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { ast_log(LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql); continue; } + cat = ast_category_new(""); + if (!cat) { + ast_log(LOG_WARNING, "Out of memory!\n"); + continue; + } for (x=0;xnext = ast_new_variable(coltitle, chunk); - if (prev->next) - prev = prev->next; - } else - prev = var = ast_new_variable(coltitle, chunk); - + if (initfield && !strcmp(initfield, coltitle)) + ast_category_rename(cat, chunk); + var = ast_variable_new(coltitle, chunk); + ast_variable_append(cat, var); } } } - if (var) { - cat = ast_new_category(title ? title : ""); - if (cat) { - cat->root = var; - if (!cfg) - cfg = ast_new_config(); - if (cfg) - ast_category_append(cfg, cat); - else - ast_category_destroy(cat); - } else { - ast_log(LOG_WARNING, "Out of memory!\n"); - ast_destroy_realtime(var); - } - } + ast_category_append(cfg, cat); } SQLFreeHandle (SQL_HANDLE_STMT, stmt); @@ -410,11 +395,10 @@ static int update_odbc(const char *database, const char *table, const char *keyf return -1; } -static struct ast_config *config_odbc(const char *database, const char *table, const char *file, struct ast_config *new_config_s, struct ast_category **new_cat_p, int recur) +static struct ast_config *config_odbc(const char *database, const char *table, const char *file, struct ast_config *cfg) { - struct ast_config *new; - struct ast_variable *cur_v, *new_v; - struct ast_category *cur_cat, *new_cat; + struct ast_variable *new_v; + struct ast_category *cur_cat; int res = 0; odbc_obj *obj; SQLINTEGER err=0, commented=0, cat_metric=0, var_metric=0, last_cat_metric=0; @@ -422,10 +406,7 @@ static struct ast_config *config_odbc(const char *database, const char *table, c char sql[255] = "", filename[128], category[128], var_name[128], var_val[512]; SQLSMALLINT rowcount=0; SQLHSTMT stmt; - char last[80] = ""; - int cat_started = 0; - int var_started = 0; - + char last[128] = ""; if (!file || !strcmp (file, "res_config_odbc.conf")) return NULL; /* cant configure myself with myself ! */ @@ -434,8 +415,6 @@ static struct ast_config *config_odbc(const char *database, const char *table, c if (!obj) return NULL; - last[0] = '\0'; - res = SQLAllocHandle (SQL_HANDLE_STMT, obj->con, &stmt); SQLBindCol (stmt, 1, SQL_C_ULONG, &id, sizeof (id), &err); @@ -452,90 +431,63 @@ static struct ast_config *config_odbc(const char *database, const char *table, c if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { ast_log (LOG_WARNING, "SQL select error!\n[%s]\n\n", sql); + SQLFreeHandle (SQL_HANDLE_STMT, stmt); return NULL; } res = SQLNumResultCols (stmt, &rowcount); if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { - ast_log (LOG_WARNING, "SQL select error!\n[%s]\n\n", sql); - return NULL; - } - - if (new_config_s) { - new = new_config_s; - cat_started++; - } else { - new = ast_new_config (); - } - - if (!new) { - ast_log(LOG_WARNING, "Out of memory!\n"); + ast_log (LOG_WARNING, "SQL NumResultCols error!\n[%s]\n\n", sql); SQLFreeHandle (SQL_HANDLE_STMT, stmt); return NULL; } - if (rowcount) { - res = SQLFetch (stmt); - cat_started = 0; + if (!rowcount) { + ast_log (LOG_NOTICE, "found nothing\n"); + return cfg; + } - cur_cat = *new_cat_p; - cur_v = NULL; + cur_cat = ast_config_get_current_category(cfg); - if (cur_cat) - cat_started = 1; - if (cur_v) - var_started = 1; - - while (res != SQL_NO_DATA) { - if (!strcmp (var_name, "#include") && recur < MAX_INCLUDE_LEVEL) { - - config_odbc(database, table, var_val, new, &cur_cat, recur + 1); - } else { - if (strcmp (last, category) || last_cat_metric != cat_metric) { - strncpy(last, category, sizeof(last) - 1); - last_cat_metric = cat_metric; - new_cat = (struct ast_category *) ast_new_category (category); - - if (!cat_started) { - cat_started++; - new->root = new_cat; - cur_cat = new->root; - } else { - cur_cat->next = new_cat; - cur_cat = cur_cat->next; - } - var_started = 0; - - } - - new_v = ast_new_variable (var_name, var_val); - - if (!var_started) { - var_started++; - cur_cat->root = new_v; - cur_v = cur_cat->root; - } else { - cur_v->next = new_v; - cur_v = cur_v->next; - } + while ((res = SQLFetch(stmt)) != SQL_NO_DATA) { + if (!strcmp (var_name, "#include")) { + if (!ast_config_internal_load(var_val, cfg)) { + SQLFreeHandle (SQL_HANDLE_STMT, stmt); + return NULL; } - - /* next row */ - res = SQLFetch (stmt); + continue; + } + if (strcmp(last, category) || last_cat_metric != cat_metric) { + cur_cat = ast_category_new(category); + if (!cur_cat) { + ast_log(LOG_WARNING, "Out of memory!\n"); + break; + } + strcpy(last, category); + last_cat_metric = cat_metric; + ast_category_append(cfg, cur_cat); } - SQLFreeHandle (SQL_HANDLE_STMT, stmt); - } else { - ast_log (LOG_NOTICE, "found nothing\n"); + new_v = ast_variable_new(var_name, var_val); + ast_variable_append(cur_cat, new_v); } - return new; + SQLFreeHandle (SQL_HANDLE_STMT, stmt); + return cfg; } +static struct ast_config_engine odbc_engine = { + .name = "odbc", + .load_func = config_odbc, + .realtime_func = realtime_odbc, + .realtime_multi_func = realtime_multi_odbc, + .update_func = update_odbc +}; + int unload_module (void) { - ast_cust_config_deregister (®1); + ast_config_engine_deregister(&odbc_engine); if (option_verbose) ast_verbose("res_config_odbc unloaded.\n"); STANDARD_HANGUP_LOCALUSERS; @@ -544,13 +496,7 @@ int unload_module (void) int load_module (void) { - memset (®1, 0, sizeof (struct ast_config_reg)); - strncpy(reg1.name, "odbc", sizeof(reg1.name) - 1); - reg1.static_func = config_odbc; - reg1.realtime_func = realtime_odbc; - reg1.realtime_multi_func = realtime_multi_odbc; - reg1.update_func = update_odbc; - ast_cust_config_register (®1); + ast_config_engine_register(&odbc_engine); if (option_verbose) ast_verbose("res_config_odbc loaded.\n"); return 0; diff --git a/res/res_features.c b/res/res_features.c index 6ce3e4550b..3e4f6be300 100755 --- a/res/res_features.c +++ b/res/res_features.c @@ -1444,9 +1444,9 @@ static int load_config(void) transferdigittimeout = DEFAULT_TRANSFER_DIGIT_TIMEOUT; featuredigittimeout = DEFAULT_FEATURE_DIGIT_TIMEOUT; - cfg = ast_load("features.conf"); + cfg = ast_config_load("features.conf"); if (!cfg) { - cfg = ast_load("parking.conf"); + cfg = ast_config_load("parking.conf"); if (cfg) ast_log(LOG_NOTICE, "parking.conf is deprecated in favor of 'features.conf'. Please rename it.\n"); } @@ -1501,7 +1501,7 @@ static int load_config(void) ast_log(LOG_NOTICE, "Unknown feature '%s'\n", var->name); var = var->next; } - ast_destroy(cfg); + ast_config_destroy(cfg); } if (con) diff --git a/res/res_indications.c b/res/res_indications.c index ec2db5741b..cc744ec55a 100755 --- a/res/res_indications.c +++ b/res/res_indications.c @@ -230,7 +230,7 @@ static int ind_load_module(void) /* that the following cast is needed, is yuk! */ /* yup, checked it out. It is NOT written to. */ - cfg = ast_load((char *)config); + cfg = ast_config_load((char *)config); if (!cfg) return 0; @@ -245,7 +245,7 @@ static int ind_load_module(void) tones = malloc(sizeof(struct tone_zone)); if (!tones) { ast_log(LOG_WARNING,"Out of memory\n"); - ast_destroy(cfg); + ast_config_destroy(cfg); return -1; } memset(tones,0,sizeof(struct tone_zone)); @@ -269,7 +269,7 @@ static int ind_load_module(void) tmp = realloc(tones->ringcadance,(tones->nrringcadance+1)*sizeof(int)); if (!tmp) { ast_log(LOG_WARNING, "Out of memory\n"); - ast_destroy(cfg); + ast_config_destroy(cfg); return -1; } tones->ringcadance = tmp; @@ -286,7 +286,7 @@ static int ind_load_module(void) struct tone_zone* azone = malloc(sizeof(struct tone_zone)); if (!azone) { ast_log(LOG_WARNING,"Out of memory\n"); - ast_destroy(cfg); + ast_config_destroy(cfg); return -1; } memset(azone,0,sizeof(struct tone_zone)); @@ -313,7 +313,7 @@ static int ind_load_module(void) ts = malloc(sizeof(struct tone_zone_sound)); if (!ts) { ast_log(LOG_WARNING, "Out of memory\n"); - ast_destroy(cfg); + ast_config_destroy(cfg); return -1; } ts->next = NULL; @@ -341,7 +341,7 @@ out: v = v->next; if (!country || !*country || ast_set_indication_country(country)) ast_log(LOG_WARNING,"Unable to set the default country (for indication tones)\n"); - ast_destroy(cfg); + ast_config_destroy(cfg); return 0; } diff --git a/res/res_musiconhold.c b/res/res_musiconhold.c index 599027b899..5bebf92668 100755 --- a/res/res_musiconhold.c +++ b/res/res_musiconhold.c @@ -865,7 +865,7 @@ static int load_moh_classes(void) char *args; int x = 0; - cfg = ast_load("musiconhold.conf"); + cfg = ast_config_load("musiconhold.conf"); if (!cfg) return 0; @@ -897,7 +897,7 @@ static int load_moh_classes(void) var = var->next; } - ast_destroy(cfg); + ast_config_destroy(cfg); return x; } diff --git a/res/res_odbc.c b/res/res_odbc.c index 4e498e7b21..f843860aad 100755 --- a/res/res_odbc.c +++ b/res/res_odbc.c @@ -93,7 +93,7 @@ static int load_odbc_config(void) odbc_obj *obj; - config = ast_load(cfg); + config = ast_config_load(cfg); if (config) { for (cat = ast_category_browse(config, NULL); cat; cat=ast_category_browse(config, cat)) { if (!strcmp(cat, "ENV")) { @@ -140,7 +140,7 @@ static int load_odbc_config(void) } } - ast_destroy(config); + ast_config_destroy(config); } return 0; } diff --git a/res/res_osp.c b/res/res_osp.c index 3f95f09643..bcf7bef9c5 100755 --- a/res/res_osp.c +++ b/res/res_osp.c @@ -746,7 +746,7 @@ static int config_load(void) osp = osp->next; } ast_mutex_unlock(&osplock); - cfg = ast_load("osp.conf"); + cfg = ast_config_load("osp.conf"); if (cfg) { if (!initialized) { cat = ast_variable_retrieve(cfg, "general", "accelerate"); @@ -766,7 +766,7 @@ static int config_load(void) osp_build(cfg, cat); cat = ast_category_browse(cfg, cat); } - ast_destroy(cfg); + ast_config_destroy(cfg); } else ast_log(LOG_NOTICE, "No OSP configuration found. OSP support disabled\n"); ast_mutex_lock(&osplock); diff --git a/rtp.c b/rtp.c index 36772d6a9f..473e841b4c 100755 --- a/rtp.c +++ b/rtp.c @@ -1753,7 +1753,7 @@ void ast_rtp_reload(void) #ifdef SO_NO_CHECK checksums = 1; #endif - cfg = ast_load("rtp.conf"); + cfg = ast_config_load("rtp.conf"); if (cfg) { if ((s = ast_variable_retrieve(cfg, "general", "rtpstart"))) { rtpstart = atoi(s); @@ -1780,7 +1780,7 @@ void ast_rtp_reload(void) ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n"); #endif } - ast_destroy(cfg); + ast_config_destroy(cfg); } if (rtpstart >= rtpend) { ast_log(LOG_WARNING, "Unreasonable values for RTP start in rtp.conf/end\n");