static void deinitialize_sorcery(struct ast_sorcery *sorcery)
{
	ast_config_destroy(realtime_objects);
	realtime_objects = NULL;
	ast_sorcery_unref(sorcery);
}
/*
 * Load module stuff
 */
static int ind_load_module(void)
{
	struct ast_config *cfg;
	struct ast_variable *v;
	char *cxt;
	char *c;
	struct tone_zone *tones;
	const char *country = NULL;

	/* that the following cast is needed, is yuk! */
	/* yup, checked it out. It is NOT written to. */
	cfg = ast_config_load((char *)config);
	if (!cfg)
		return 0;

	/* Use existing config to populate the Indication table */
	cxt = ast_category_browse(cfg, NULL);
	while(cxt) {
		/* All categories but "general" are considered countries */
		if (!strcasecmp(cxt, "general")) {
			cxt = ast_category_browse(cfg, cxt);
			continue;
		}
		tones = malloc(sizeof(struct tone_zone));
		if (!tones) {
			ast_log(LOG_WARNING,"Out of memory\n");
			ast_config_destroy(cfg);
			return -1;
		}
		memset(tones,0,sizeof(struct tone_zone));
		ast_copy_string(tones->country,cxt,sizeof(tones->country));

		v = ast_variable_browse(cfg, cxt);
		while(v) {
			if (!strcasecmp(v->name, "description")) {
				ast_copy_string(tones->description, v->value, sizeof(tones->description));
			} else if ((!strcasecmp(v->name,"ringcadence"))||(!strcasecmp(v->name,"ringcadance"))) {
				char *ring,*rings = ast_strdupa(v->value);
				c = rings;
				ring = strsep(&c,",");
				while (ring) {
					int *tmp, val;
					if (!isdigit(ring[0]) || (val=atoi(ring))==-1) {
						ast_log(LOG_WARNING,"Invalid ringcadence given '%s' at line %d.\n",ring,v->lineno);
						ring = strsep(&c,",");
						continue;
					}
					tmp = realloc(tones->ringcadence,(tones->nrringcadence+1)*sizeof(int));
					if (!tmp) {
						ast_log(LOG_WARNING, "Out of memory\n");
						ast_config_destroy(cfg);
						return -1;
					}
					tones->ringcadence = tmp;
					tmp[tones->nrringcadence] = val;
					tones->nrringcadence++;
					/* next item */
					ring = strsep(&c,",");
				}
			} else if (!strcasecmp(v->name,"alias")) {
				char *countries = ast_strdupa(v->value);
				c = countries;
				country = strsep(&c,",");
				while (country) {
					struct tone_zone* azone = malloc(sizeof(struct tone_zone));
					if (!azone) {
						ast_log(LOG_WARNING,"Out of memory\n");
						ast_config_destroy(cfg);
						return -1;
					}
					memset(azone,0,sizeof(struct tone_zone));
					ast_copy_string(azone->country, country, sizeof(azone->country));
					ast_copy_string(azone->alias, cxt, sizeof(azone->alias));
					if (ast_register_indication_country(azone)) {
						ast_log(LOG_WARNING, "Unable to register indication alias at line %d.\n",v->lineno);
						free(tones);
					}
					/* next item */
					country = strsep(&c,",");
				}
			} else {
				/* add tone to country */
				struct tone_zone_sound *ps,*ts;
				for (ps=NULL,ts=tones->tones; ts; ps=ts, ts=ts->next) {
					if (strcasecmp(v->name,ts->name)==0) {
						/* already there */
						ast_log(LOG_NOTICE,"Duplicate entry '%s', skipped.\n",v->name);
						goto out;
					}
				}
				/* not there, add it to the back */
				ts = malloc(sizeof(struct tone_zone_sound));
				if (!ts) {
					ast_log(LOG_WARNING, "Out of memory\n");
					ast_config_destroy(cfg);
					return -1;
				}
				ts->next = NULL;
				ts->name = strdup(v->name);
				ts->data = strdup(v->value);
				if (ps)
					ps->next = ts;
				else
					tones->tones = ts;
			}
out:			v = v->next;
		}
		if (tones->description[0] || tones->alias[0] || tones->tones) {
			if (ast_register_indication_country(tones)) {
				ast_log(LOG_WARNING, "Unable to register indication at line %d.\n",v->lineno);
				free(tones);
			}
		} else free(tones);

		cxt = ast_category_browse(cfg, cxt);
	}

	/* determine which country is the default */
	country = ast_variable_retrieve(cfg,"general","country");
	if (!country || !*country || ast_set_indication_country(country))
		ast_log(LOG_WARNING,"Unable to set the default country (for indication tones)\n");

	ast_config_destroy(cfg);
	return 0;
}
static int mcd_load_config(void) {

	// initialize the timeout that we wait for a memcached pool operation to complete
	to.tv_sec = 0; to.tv_nsec = 500000;

	struct ast_config *cfg;
	struct ast_flags config_flags = { 0 };

	if (!(cfg = ast_config_load(CONFIG_FILE_NAME, config_flags))) {
		ast_log(LOG_ERROR, "missing memcached resource config file '%s'\n", CONFIG_FILE_NAME);
		return 1;
	} else if (cfg == CONFIG_STATUS_FILEINVALID) {
		ast_log(LOG_ERROR, "memcached resource config file '" CONFIG_FILE_NAME "' invalid format.\n");
		return 1;
	}

    // parse server names for memcached from the [general] section of the config file
    char mcd_config[2048]; mcd_config[0] = 0;
	struct ast_variable *serverentry = ast_variable_browse(cfg, "general");
	for ( ; serverentry; serverentry = serverentry->next) {
		if (strcasecmp(serverentry->name, "server") == 0) {
	    	strcat(mcd_config, "--SERVER=");
    		strcat(mcd_config, serverentry->value);
    		strcat(mcd_config, " ");
		}
	}
    if (strstr(mcd_config, "--SERVER=") == 0) {
        ast_log(LOG_DEBUG, "Expecting memcache server on 127.0.0.1\n");
        strcpy(mcd_config, "--SERVER=127.0.0.1 ");
    }
    ast_log(LOG_DEBUG, "res_memcached configured servers: '%s'\n", mcd_config);
//	strcat(mcd_config, "--SORT-HOSTS ");  not a good idea: turns out that the documentation says:
//                                        "Enabling this will cause hosts that are added to be placed 
//                                         in the host list in sorted order. This will defeat 
//                                         consisten hashing."

	mcdttl = 0;
	const char *ttlvalue;
	if ((ttlvalue = ast_variable_retrieve(cfg, "general", "ttl")))
		mcdttl = atoi(ttlvalue);
	ast_log(LOG_DEBUG, "default time to live for key-value entries set to %d seconds\n", mcdttl);

	use_binary_proto = 1;
	const char *proto_mode;
	if ((proto_mode = ast_variable_retrieve(cfg, "general", "binary_proto")))
		use_binary_proto = ast_true(proto_mode);
//	if (use_binary_proto)
//		strcat(mcd_config, "--BINARY-PROTOCOL ");
//	else
//		ast_log(LOG_WARNING, "not using memcached binary protocol; MCDCOUNTER() function will be unavailable\n");
/*
	const char *hashmode;
	if ((hashmode = ast_variable_retrieve(cfg, "general", "hash"))) {
		strcat(mcd_config, "--HASH=");
		strcat(mcd_config, hashmode);
		strcat(mcd_config, " ");
	}
*/
	const char *kp;
	if ((kp = ast_variable_retrieve(cfg, "general", "keyprefix"))) {
		strcat(mcd_config, "--NAMESPACE=");
		strcat(mcd_config, kp);
		strcat(mcd_config, " ");
	}

    // launch memcached client (pool of)
    mcd_config[strlen(mcd_config) - 1] = 0;
    if ((mcdpool = memcached_pool(mcd_config, strlen(mcd_config))))
	    ast_log(LOG_DEBUG, "res_memcached starting with config: '%s'\n", mcd_config);
	else
	    ast_log(LOG_ERROR, "res_memcached failed to start with config: '%s'\n", mcd_config);

	ast_config_destroy(cfg);
	return 0;

}
int load_mrcp_config(const char *filename, const char *who_asked)
{
	const char *cat = NULL;
	struct ast_variable *var;
	const char *value = NULL;

#if AST_VERSION_AT_LEAST(1,6,0)
	struct ast_flags config_flags = { 0 };
	struct ast_config *cfg = ast_config_load2(filename, who_asked, config_flags);
#else
	struct ast_config *cfg = ast_config_load(filename);
#endif
	if (!cfg) {
		ast_log(LOG_WARNING, "No such configuration file %s\n", filename);
		return -1;
	}
#if AST_VERSION_AT_LEAST(1,6,2)
	if (cfg == CONFIG_STATUS_FILEINVALID) {
		ast_log(LOG_ERROR, "Config file %s is in an invalid format\n", filename);
		return -1;
	}
#endif

	globals_clear();
	globals_default();

	if ((value = ast_variable_retrieve(cfg, "general", "default-tts-profile")) != NULL) {
		ast_log(LOG_DEBUG, "general.default-tts-profile=%s\n",  value);
		globals.unimrcp_default_synth_profile = apr_pstrdup(globals.pool, value);
	} else {
		ast_log(LOG_ERROR, "Unable to load genreal.default-tts-profile from config file, aborting\n");
		ast_config_destroy(cfg);
		return -1;
	}
	if ((value = ast_variable_retrieve(cfg, "general", "default-asr-profile")) != NULL) {
		ast_log(LOG_DEBUG, "general.default-asr-profile=%s\n",  value);
		globals.unimrcp_default_recog_profile = apr_pstrdup(globals.pool, value);
	} else {
		ast_log(LOG_ERROR, "Unable to load genreal.default-asr-profile from config file, aborting\n");
		ast_config_destroy(cfg);
		return -1;
	}
	if ((value = ast_variable_retrieve(cfg, "general", "log-level")) != NULL) {
		ast_log(LOG_DEBUG, "general.log-level=%s\n",  value);
		globals.unimrcp_log_level = apr_pstrdup(globals.pool, value);
	}
	if ((value = ast_variable_retrieve(cfg, "general", "max-connection-count")) != NULL) {
		ast_log(LOG_DEBUG, "general.max-connection-count=%s\n",  value);
		globals.unimrcp_max_connection_count = apr_pstrdup(globals.pool, value);
	}
	if ((value = ast_variable_retrieve(cfg, "general", "offer-new-connection")) != NULL) {
		ast_log(LOG_DEBUG, "general.offer-new-connection=%s\n",  value);
		globals.unimrcp_offer_new_connection = apr_pstrdup(globals.pool, value);
	}
	if ((value = ast_variable_retrieve(cfg, "general", "rx-buffer-size")) != NULL) {
		ast_log(LOG_DEBUG, "general.rx-buffer-size=%s\n",  value);
		globals.unimrcp_rx_buffer_size = apr_pstrdup(globals.pool, value);
	}
	if ((value = ast_variable_retrieve(cfg, "general", "tx-buffer-size")) != NULL) {
		ast_log(LOG_DEBUG, "general.tx-buffer-size=%s\n",  value);
		globals.unimrcp_tx_buffer_size = apr_pstrdup(globals.pool, value);
	}
	if ((value = ast_variable_retrieve(cfg, "general", "request-timeout")) != NULL) {
		ast_log(LOG_DEBUG, "general.request-timeout=%s\n",  value);
		globals.unimrcp_request_timeout = apr_pstrdup(globals.pool, value);
	}

	while ((cat = ast_category_browse(cfg, cat)) != NULL) {
		if (strcasecmp(cat, "general") != 0) {
			if ((value = ast_variable_retrieve(cfg, cat, "version")) != NULL) {
				ast_mrcp_profile_t *mod_profile = NULL;

				if (profile_create(&mod_profile, cat, value, globals.pool) == 0) {
					apr_hash_set(globals.profiles, apr_pstrdup(globals.pool, mod_profile->name), APR_HASH_KEY_STRING, mod_profile);

					for (var = ast_variable_browse(cfg, cat); var; var = var->next) {
						ast_log(LOG_DEBUG, "%s.%s=%s\n", cat, var->name, var->value);
						apr_hash_set(mod_profile->cfg, apr_pstrdup(globals.pool, var->name), APR_HASH_KEY_STRING, apr_pstrdup(globals.pool, var->value));
					}
				} else
					ast_log(LOG_WARNING, "Unable to create a profile for %s\n", cat);
			} else
				ast_log(LOG_WARNING, "Category %s does not have a version variable defined\n", cat);
		}
	}

	ast_config_destroy(cfg);

	return 0;
}
static int load_config(void)
{
	struct ast_config *cfg;
	char *p;

	/* Read in the config file */

	cfg = ast_config_load(ALMRCV_CONFIG);
                                                                                                                                  
	if(!cfg){
	
		if(option_verbose >= 4)
			ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: No config file\n");
	}
	else{

		
		p = ast_variable_retrieve(cfg, "general", "eventcmd");
		
		if(p){
			ast_copy_string(event_app, p, sizeof(event_app));
			event_app[sizeof(event_app) - 1] = '\0';
		}
		
		p = ast_variable_retrieve(cfg, "general", "loudness");
		if(p){
			toneloudness = atoi(p);
			if(toneloudness < 100)
				toneloudness = 100;
			if(toneloudness > 8192)
				toneloudness = 8192;
		}
		p = ast_variable_retrieve(cfg, "general", "fdtimeout");
		if(p){
			fdtimeout = atoi(p);
			if(fdtimeout < 1000)
				fdtimeout = 1000;
			if(fdtimeout > 10000)
				fdtimeout = 10000;	
		}
		
		p = ast_variable_retrieve(cfg, "general", "sdtimeout");
		if(p){
			sdtimeout = atoi(p);
			if(sdtimeout < 110)
				sdtimeout = 110;
			if(sdtimeout > 4000)
				sdtimeout = 4000;			

		}
		
		p = ast_variable_retrieve(cfg, "general", "logindividualevents");
		if(p){
			log_individual_events = ast_true(p);

		}
		
		p = ast_variable_retrieve(cfg, "general", "eventspooldir");
			
		if(p){
			ast_copy_string(event_spool_dir, p, sizeof(event_spool_dir));
			event_spool_dir[sizeof(event_spool_dir) - 1] = '\0';
		}
		
		p = ast_variable_retrieve(cfg, "general", "timestampformat");
			
		if(p){
			ast_copy_string(time_stamp_format, p, sizeof(time_stamp_format));
			time_stamp_format[sizeof(time_stamp_format) - 1] = '\0';
		}

		p = ast_variable_retrieve(cfg, "general", "db-family");
                                                                                                                                            
		if(p){
			ast_copy_string(db_family, p, sizeof(db_family));
			db_family[sizeof(db_family) - 1] = '\0';
		}
		ast_config_destroy(cfg);
	}
	return 0;

}
Beispiel #6
0
static int load_config(int reload) {
	char *cat = NULL;
	struct ast_config *cfg;
	struct ast_variable *v;
	struct ast_flags config_flags = {reload ? CONFIG_FLAG_FILEUNCHANGED : 0};
	int newenablecdr = 0;

	cfg = ast_config_load(CONF_FILE, config_flags);
	if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
		return 0;
	}

	if (cfg == CONFIG_STATUS_FILEINVALID) {
		ast_log(LOG_ERROR, "Config file '%s' could not be parsed\n", CONF_FILE);
		return -1;
	}

	if (!cfg) {
		/* Standard configuration */
		ast_log(LOG_WARNING, "Failed to load configuration file. Module not activated.\n");
		if (enablecdr) {
			ast_cdr_backend_suspend(name);
		}
		enablecdr = 0;
		return -1;
	}

	if (reload) {
		ast_rwlock_wrlock(&config_lock);
		ast_free(bs_host);
		ast_free(bs_tube);
	}

	/* Bootstrap the default configuration */
	bs_host = ast_strdup(DEFAULT_BEANSTALK_HOST);
	bs_port = DEFAULT_BEANSTALK_PORT;
	bs_tube = ast_strdup(DEFAULT_BEANSTALK_TUBE);
	priority = BEANSTALK_JOB_PRIORITY;

	while ((cat = ast_category_browse(cfg, cat))) {
		if (!strcasecmp(cat, "general")) {
			v = ast_variable_browse(cfg, cat);
			while (v) {

				if (!strcasecmp(v->name, "enabled")) {
					newenablecdr = ast_true(v->value);
				} else if (!strcasecmp(v->name, "host")) {
					ast_free(bs_host);
					bs_host = ast_strdup(v->value);
				} else if (!strcasecmp(v->name, "port")) {
					bs_port = atoi(v->value);
				} else if (!strcasecmp(v->name, "tube")) {
					ast_free(bs_tube);
					bs_tube = ast_strdup(v->value);
				} else if (!strcasecmp(v->name, "priority")) {
					priority = atoi(v->value);
				}
				v = v->next;

			}
		}
	}

	if (reload) {
		ast_rwlock_unlock(&config_lock);
	}

	ast_config_destroy(cfg);

	if (!newenablecdr) {
		ast_cdr_backend_suspend(name);
	} else if (newenablecdr) {
		ast_cdr_backend_unsuspend(name);
		ast_log(LOG_NOTICE, "Added beanstalkd server %s at port %d with tube %s", bs_host, bs_port, bs_tube);
	}
	enablecdr = newenablecdr;

	return 0;
}
static int directory_exec(struct ast_channel *chan, void *data)
{
	int res = 0;
	struct localuser *u;
	struct ast_config *cfg;
	int last = 1;
	int fromappvm = 0;
	char *context, *dialcontext, *dirintro, *options;

	if (ast_strlen_zero(data)) {
		ast_log(LOG_WARNING, "Directory requires an argument (context[,dialcontext])\n");
		return -1;
	}

	LOCAL_USER_ADD(u);

	context = ast_strdupa(data);
	dialcontext = strchr(context, '|');
	if (dialcontext) {
		*dialcontext = '\0';
		dialcontext++;
		options = strchr(dialcontext, '|');
		if (options) {
			*options = '\0';
			options++; 
			if (strchr(options, 'f'))
				last = 0;
			if (strchr(options, 'v'))
				fromappvm = 1;
		}
	} else	
		dialcontext = context;

	cfg = realtime_directory(context);
	if (!cfg) {
		LOCAL_USER_REMOVE(u);
		return -1;
	}

	dirintro = ast_variable_retrieve(cfg, context, "directoryintro");
	if (ast_strlen_zero(dirintro))
		dirintro = ast_variable_retrieve(cfg, "general", "directoryintro");
	if (ast_strlen_zero(dirintro)) {
		if (last)
			dirintro = "dir-intro";	
		else
			dirintro = "dir-intro-fn";
	}

	if (chan->_state != AST_STATE_UP) 
		res = ast_answer(chan);

	for (;;) {
		if (!res)
			res = ast_streamfile(chan, dirintro, chan->language);
		if (!res)
			res = ast_waitstream(chan, AST_DIGIT_ANY);
		ast_stopstream(chan);
		if (!res)
			res = ast_waitfordigit(chan, 5000);
		if (res > 0) {
			res = do_directory(chan, cfg, context, dialcontext, res, last, fromappvm);
			if (res > 0) {
				res = ast_waitstream(chan, AST_DIGIT_ANY);
				ast_stopstream(chan);
				if (res >= 0) {
					continue;
				}
			}
		}
		break;
	}
	ast_config_destroy(cfg);
	LOCAL_USER_REMOVE(u);
	return res;
}
Beispiel #8
0
static int odbc_load_module(int reload)
{
	int res = 0;
	struct ast_config *cfg;
	struct ast_variable *var;
	const char *tmp;
	struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };

	do {
		cfg = ast_config_load(config_file, config_flags);
		if (!cfg || cfg == CONFIG_STATUS_FILEINVALID) {
			ast_log(LOG_WARNING, "cdr_odbc: Unable to load config for ODBC CDR's: %s\n", config_file);
			res = AST_MODULE_LOAD_DECLINE;
			break;
		} else if (cfg == CONFIG_STATUS_FILEUNCHANGED)
			break;

		var = ast_variable_browse(cfg, "global");
		if (!var) {
			/* nothing configured */
			break;
		}

		if ((tmp = ast_variable_retrieve(cfg, "global", "dsn")) == NULL) {
			ast_log(LOG_WARNING, "cdr_odbc: dsn not specified.  Assuming asteriskdb\n");
			tmp = "asteriskdb";
		}
		if (dsn)
			ast_free(dsn);
		dsn = ast_strdup(tmp);
		if (dsn == NULL) {
			res = -1;
			break;
		}

		if (((tmp = ast_variable_retrieve(cfg, "global", "dispositionstring"))) && ast_true(tmp))
			ast_set_flag(&config, CONFIG_DISPOSITIONSTRING);
		else
			ast_clear_flag(&config, CONFIG_DISPOSITIONSTRING);

		if (((tmp = ast_variable_retrieve(cfg, "global", "loguniqueid"))) && ast_true(tmp)) {
			ast_set_flag(&config, CONFIG_LOGUNIQUEID);
			ast_debug(1, "cdr_odbc: Logging uniqueid\n");
		} else {
			ast_clear_flag(&config, CONFIG_LOGUNIQUEID);
			ast_debug(1, "cdr_odbc: Not logging uniqueid\n");
		}

		if (((tmp = ast_variable_retrieve(cfg, "global", "usegmtime"))) && ast_true(tmp)) {
			ast_set_flag(&config, CONFIG_USEGMTIME);
			ast_debug(1, "cdr_odbc: Logging in GMT\n");
		} else {
			ast_clear_flag(&config, CONFIG_USEGMTIME);
			ast_debug(1, "cdr_odbc: Logging in local time\n");
		}

		if (((tmp = ast_variable_retrieve(cfg, "global", "hrtime"))) && ast_true(tmp)) {
			ast_set_flag(&config, CONFIG_HRTIME);
			ast_debug(1, "cdr_odbc: Logging billsec and duration fields as floats\n");
		} else {
			ast_clear_flag(&config, CONFIG_HRTIME);
			ast_debug(1, "cdr_odbc: Logging billsec and duration fields as integers\n");
		}

		if ((tmp = ast_variable_retrieve(cfg, "global", "table")) == NULL) {
			ast_log(LOG_WARNING, "cdr_odbc: table not specified.  Assuming cdr\n");
			tmp = "cdr";
		}
		if (table)
			ast_free(table);
		table = ast_strdup(tmp);
		if (table == NULL) {
			res = -1;
			break;
		}

		ast_verb(3, "cdr_odbc: dsn is %s\n", dsn);
		ast_verb(3, "cdr_odbc: table is %s\n", table);

		if (!ast_test_flag(&config, CONFIG_REGISTERED)) {
			res = ast_cdr_register(name, ast_module_info->description, odbc_log);
			if (res) {
				ast_log(LOG_ERROR, "cdr_odbc: Unable to register ODBC CDR handling\n");
			} else {
				ast_set_flag(&config, CONFIG_REGISTERED);
			}
		}
	} while (0);

	if (ast_test_flag(&config, CONFIG_REGISTERED) && (!cfg || dsn == NULL || table == NULL)) {
		ast_cdr_unregister(name);
		ast_clear_flag(&config, CONFIG_REGISTERED);
	}

	if (cfg && cfg != CONFIG_STATUS_FILEUNCHANGED && cfg != CONFIG_STATUS_FILEINVALID) {
		ast_config_destroy(cfg);
	}
	return res;
}
Beispiel #9
0
int misdn_cfg_init(int this_max_ports, int reload)
{
	char config[] = "misdn.conf";
	char *cat, *p;
	int i;
	struct ast_config *cfg;
	struct ast_variable *v;
	struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };

	if (!(cfg = ast_config_load2(config, "chan_misdn", config_flags)) || cfg == CONFIG_STATUS_FILEINVALID) {
		ast_log(LOG_WARNING, "missing or invalid file: misdn.conf\n");
		return -1;
	} else if (cfg == CONFIG_STATUS_FILEUNCHANGED)
		return 0;

	ast_mutex_init(&config_mutex);

	/* Copy the default jb config over global_jbconf */
	memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));

	misdn_cfg_lock();

	if (this_max_ports) {
		/* this is the first run */
		max_ports = this_max_ports;
		map = ast_calloc(MISDN_GEN_LAST + 1, sizeof(int));
		if (_enum_array_map())
			return -1;
		p = ast_calloc(1, (max_ports + 1) * sizeof(union misdn_cfg_pt *)
						   + (max_ports + 1) * NUM_PORT_ELEMENTS * sizeof(union misdn_cfg_pt));
		port_cfg = (union misdn_cfg_pt **)p;
		p += (max_ports + 1) * sizeof(union misdn_cfg_pt *);
		for (i = 0; i <= max_ports; ++i) {
			port_cfg[i] = (union misdn_cfg_pt *)p;
			p += NUM_PORT_ELEMENTS * sizeof(union misdn_cfg_pt);
		}
		general_cfg = ast_calloc(1, sizeof(union misdn_cfg_pt *) * NUM_GEN_ELEMENTS);
		ptp = ast_calloc(max_ports + 1, sizeof(int));
	}
	else {
		/* misdn reload */
		_free_port_cfg();
		_free_general_cfg();
		memset(port_cfg[0], 0, NUM_PORT_ELEMENTS * sizeof(union misdn_cfg_pt) * (max_ports + 1));
		memset(general_cfg, 0, sizeof(union misdn_cfg_pt *) * NUM_GEN_ELEMENTS);
		memset(ptp, 0, sizeof(int) * (max_ports + 1));
	}

	cat = ast_category_browse(cfg, NULL);

	while(cat) {
		v = ast_variable_browse(cfg, cat);
		if (!strcasecmp(cat, "general")) {
			_build_general_config(v);
		} else {
			_build_port_config(v, cat);
		}
		cat = ast_category_browse(cfg, cat);
	}

	_fill_defaults();

	misdn_cfg_unlock();
	ast_config_destroy(cfg);

	return 0;
}
static int parse_config(int reload) 
{
	struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
	struct ast_config *cfg = ast_config_load("codecs.conf", config_flags);
	struct ast_variable *var;
	int res;
	float res_f;

	if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID)
		return 0;

	for (var = ast_variable_browse(cfg, "speex"); var; var = var->next) {
		if (!strcasecmp(var->name, "quality")) {
			res = abs(atoi(var->value));
			if (res > -1 && res < 11) {
				ast_verb(3, "CODEC SPEEX: Setting Quality to %d\n",res);
				quality = res;
			} else 
				ast_log(LOG_ERROR,"Error Quality must be 0-10\n");
		} else if (!strcasecmp(var->name, "complexity")) {
			res = abs(atoi(var->value));
			if (res > -1 && res < 11) {
				ast_verb(3, "CODEC SPEEX: Setting Complexity to %d\n",res);
				complexity = res;
			} else 
				ast_log(LOG_ERROR,"Error! Complexity must be 0-10\n");
		} else if (!strcasecmp(var->name, "vbr_quality")) {
			if (sscanf(var->value, "%30f", &res_f) == 1 && res_f >= 0 && res_f <= 10) {
				ast_verb(3, "CODEC SPEEX: Setting VBR Quality to %f\n",res_f);
				vbr_quality = res_f;
			} else
				ast_log(LOG_ERROR,"Error! VBR Quality must be 0-10\n");
		} else if (!strcasecmp(var->name, "abr_quality")) {
			ast_log(LOG_ERROR,"Error! ABR Quality setting obsolete, set ABR to desired bitrate\n");
		} else if (!strcasecmp(var->name, "enhancement")) {
			enhancement = ast_true(var->value) ? 1 : 0;
			ast_verb(3, "CODEC SPEEX: Perceptual Enhancement Mode. [%s]\n",enhancement ? "on" : "off");
		} else if (!strcasecmp(var->name, "vbr")) {
			vbr = ast_true(var->value) ? 1 : 0;
			ast_verb(3, "CODEC SPEEX: VBR Mode. [%s]\n",vbr ? "on" : "off");
		} else if (!strcasecmp(var->name, "abr")) {
			res = abs(atoi(var->value));
			if (res >= 0) {
					if (res > 0)
					ast_verb(3, "CODEC SPEEX: Setting ABR target bitrate to %d\n",res);
					else
					ast_verb(3, "CODEC SPEEX: Disabling ABR\n");
				abr = res;
			} else 
				ast_log(LOG_ERROR,"Error! ABR target bitrate must be >= 0\n");
		} else if (!strcasecmp(var->name, "vad")) {
			vad = ast_true(var->value) ? 1 : 0;
			ast_verb(3, "CODEC SPEEX: VAD Mode. [%s]\n",vad ? "on" : "off");
		} else if (!strcasecmp(var->name, "dtx")) {
			dtx = ast_true(var->value) ? 1 : 0;
			ast_verb(3, "CODEC SPEEX: DTX Mode. [%s]\n",dtx ? "on" : "off");
		} else if (!strcasecmp(var->name, "preprocess")) {
			preproc = ast_true(var->value) ? 1 : 0;
			ast_verb(3, "CODEC SPEEX: Preprocessing. [%s]\n",preproc ? "on" : "off");
		} else if (!strcasecmp(var->name, "pp_vad")) {
			pp_vad = ast_true(var->value) ? 1 : 0;
			ast_verb(3, "CODEC SPEEX: Preprocessor VAD. [%s]\n",pp_vad ? "on" : "off");
		} else if (!strcasecmp(var->name, "pp_agc")) {
			pp_agc = ast_true(var->value) ? 1 : 0;
			ast_verb(3, "CODEC SPEEX: Preprocessor AGC. [%s]\n",pp_agc ? "on" : "off");
		} else if (!strcasecmp(var->name, "pp_agc_level")) {
			if (sscanf(var->value, "%30f", &res_f) == 1 && res_f >= 0) {
				ast_verb(3, "CODEC SPEEX: Setting preprocessor AGC Level to %f\n",res_f);
				pp_agc_level = res_f;
			} else
				ast_log(LOG_ERROR,"Error! Preprocessor AGC Level must be >= 0\n");
		} else if (!strcasecmp(var->name, "pp_denoise")) {
			pp_denoise = ast_true(var->value) ? 1 : 0;
			ast_verb(3, "CODEC SPEEX: Preprocessor Denoise. [%s]\n",pp_denoise ? "on" : "off");
		} else if (!strcasecmp(var->name, "pp_dereverb")) {
			pp_dereverb = ast_true(var->value) ? 1 : 0;
			ast_verb(3, "CODEC SPEEX: Preprocessor Dereverb. [%s]\n",pp_dereverb ? "on" : "off");
		} else if (!strcasecmp(var->name, "pp_dereverb_decay")) {
			if (sscanf(var->value, "%30f", &res_f) == 1 && res_f >= 0) {
				ast_verb(3, "CODEC SPEEX: Setting preprocessor Dereverb Decay to %f\n",res_f);
				pp_dereverb_decay = res_f;
			} else
				ast_log(LOG_ERROR,"Error! Preprocessor Dereverb Decay must be >= 0\n");
		} else if (!strcasecmp(var->name, "pp_dereverb_level")) {
			if (sscanf(var->value, "%30f", &res_f) == 1 && res_f >= 0) {
				ast_verb(3, "CODEC SPEEX: Setting preprocessor Dereverb Level to %f\n",res_f);
				pp_dereverb_level = res_f;
			} else
				ast_log(LOG_ERROR,"Error! Preprocessor Dereverb Level must be >= 0\n");
		}
	}
	ast_config_destroy(cfg);
	return 0;
}
Beispiel #11
0
/*! \brief Function which passes through an aliased CLI command to the real one */
static char *cli_alias_passthrough(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
	struct cli_alias *alias;
	struct cli_alias tmp = {
		.cli_entry.command = e->command,
	};
	char *generator;
	const char *line;

	/* Try to find the alias based on the CLI entry */
	if (!(alias = ao2_find(cli_aliases, &tmp, OBJ_POINTER))) {
		return 0;
	}

	switch (cmd) {
	case CLI_INIT:
		ao2_ref(alias, -1);
		return NULL;
	case CLI_GENERATE:
		line = a->line;
		line += (strlen(alias->alias));
		if (!strncasecmp(alias->alias, alias->real_cmd, strlen(alias->alias))) {
			generator = NULL;
		} else if (!ast_strlen_zero(a->word)) {
			struct ast_str *real_cmd = ast_str_alloca(strlen(alias->real_cmd) + strlen(line) + 1);
			ast_str_append(&real_cmd, 0, "%s%s", alias->real_cmd, line);
			generator = ast_cli_generator(ast_str_buffer(real_cmd), a->word, a->n);
		} else {
			generator = ast_cli_generator(alias->real_cmd, a->word, a->n);
		}
		ao2_ref(alias, -1);
		return generator;
	}

	/* If they gave us extra arguments we need to construct a string to pass in */
	if (a->argc != e->args) {
		struct ast_str *real_cmd = ast_str_alloca(2048);
		int i;

		ast_str_append(&real_cmd, 0, "%s", alias->real_cmd);

		/* Add the additional arguments that have been passed in */
		for (i = e->args + 1; i <= a->argc; i++) {
			ast_str_append(&real_cmd, 0, " %s", a->argv[i - 1]);
		}

		ast_cli_command(a->fd, ast_str_buffer(real_cmd));
	} else {
		ast_cli_command(a->fd, alias->real_cmd);
	}

	ao2_ref(alias, -1);

	return CLI_SUCCESS;
}

/*! \brief CLI Command to display CLI Aliases */
static char *alias_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
#define FORMAT "%-50.50s %-50.50s\n"
	struct cli_alias *alias;
	struct ao2_iterator i;

	switch (cmd) {
	case CLI_INIT:
		e->command = "cli show aliases";
		e->usage =
			"Usage: cli show aliases\n"
			"       Displays a list of aliased CLI commands.\n";
		return NULL;
	case CLI_GENERATE:
		return NULL;
	}

	ast_cli(a->fd, FORMAT, "Alias Command", "Real Command");

	i = ao2_iterator_init(cli_aliases, 0);
	for (; (alias = ao2_iterator_next(&i)); ao2_ref(alias, -1)) {
		ast_cli(a->fd, FORMAT, alias->alias, alias->real_cmd);
	}
	ao2_iterator_destroy(&i);

	return CLI_SUCCESS;
#undef FORMAT
}

/*! \brief CLI commands to interact with things */
static struct ast_cli_entry cli_alias[] = {
	AST_CLI_DEFINE(alias_show, "Show CLI command aliases"),
};

/*! \brief Function called to load or reload the configuration file */
static void load_config(int reload)
{
	struct ast_config *cfg = NULL;
	struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
	struct cli_alias *alias;
	struct ast_variable *v, *v1;

	if (!(cfg = ast_config_load(config_file, config_flags)) || cfg == CONFIG_STATUS_FILEINVALID) {
		ast_log(LOG_ERROR, "res_clialiases configuration file '%s' not found\n", config_file);
		return;
	} else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
		return;
	}

	/* Destroy any existing CLI aliases */
	if (reload) {
		ao2_callback(cli_aliases, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, alias_unregister_cb, NULL);
	}

	for (v = ast_variable_browse(cfg, "general"); v; v = v->next) {
		if (strcmp(v->name, "template")) {
			ast_log(LOG_WARNING, "%s is not a correct option in [%s]\n", v->name, "general");
			continue;
		}
		/* Read in those there CLI aliases */
		for (v1 = ast_variable_browse(cfg, v->value); v1; v1 = v1->next) {
			struct cli_alias *existing = ao2_callback(cli_aliases, 0, alias_name_cb, (char*)v1->name);

			if (existing) {
				ast_log(LOG_WARNING, "Alias '%s' could not be unregistered and has been retained\n",
					existing->alias);
				ao2_ref(existing, -1);
				continue;
			}

			if (!(alias = ao2_alloc((sizeof(*alias) + strlen(v1->name) + strlen(v1->value) + 2), NULL))) {
				continue;
			}
			alias->alias = ((char *) alias) + sizeof(*alias);
			alias->real_cmd = ((char *) alias->alias) + strlen(v1->name) + 1;
			strcpy(alias->alias, v1->name);
			strcpy(alias->real_cmd, v1->value);
			alias->cli_entry.handler = cli_alias_passthrough;
			alias->cli_entry.command = alias->alias;
			alias->cli_entry.usage = "Aliased CLI Command\n";

			if (ast_cli_register(&alias->cli_entry)) {
				ao2_ref(alias, -1);
				continue;
			}
			ao2_link(cli_aliases, alias);
			ast_verb(2, "Aliased CLI command '%s' to '%s'\n", v1->name, v1->value);
			ao2_ref(alias, -1);
		}
	}

	ast_config_destroy(cfg);

	return;
}

/*! \brief Function called to reload the module */
static int reload_module(void)
{
	load_config(1);
	return 0;
}
Beispiel #12
0
static int mongodb_load_module(int reload)
{
	int res = -1;
	struct ast_config *cfg = NULL;
   	mongoc_uri_t *uri = NULL;

	do {
		const char *tmp;
		struct ast_variable *var;
		struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };

		cfg = ast_config_load(CONFIG_FILE, config_flags);
		if (!cfg || cfg == CONFIG_STATUS_FILEINVALID) {
			ast_log(LOG_WARNING, "unable to load config file=%s\n", CONFIG_FILE);
			res = AST_MODULE_LOAD_DECLINE;
			break;
		} 
		else if (cfg == CONFIG_STATUS_FILEUNCHANGED)
			break;

		var = ast_variable_browse(cfg, CATEGORY);
		if (!var) {
			ast_log(LOG_WARNING, "no category specified.\n");
			break;
		}

		if ((tmp = ast_variable_retrieve(cfg, CATEGORY, URI)) == NULL) {
			ast_log(LOG_WARNING, "no uri specified.\n");
			break;
		}
	   	uri = mongoc_uri_new(tmp);
	   	if (uri == NULL) {
			ast_log(LOG_ERROR, "parsing uri error, %s\n", tmp);
			break;
	   	}

		if ((tmp = ast_variable_retrieve(cfg, CATEGORY, DATABSE)) == NULL) {
			ast_log(LOG_WARNING, "no database specified.\n");
			break;
		}
		if (dbname)
			ast_free(dbname);
		dbname = ast_strdup(tmp);
		if (dbname == NULL) {
			ast_log(LOG_ERROR, "not enough memory for dbname\n");
			break;
		}

		if ((tmp = ast_variable_retrieve(cfg, CATEGORY, COLLECTION)) == NULL) {
			ast_log(LOG_WARNING, "no collection specified.\n");
			break;
		}
		if (dbcollection)
			ast_free(dbcollection);
		dbcollection = ast_strdup(tmp);
		if (dbcollection == NULL) {
			ast_log(LOG_ERROR, "not enough memory for dbcollection\n");
			break;
		}

		if (!ast_test_flag(&config, CONFIG_REGISTERED)) {
			res = ast_cdr_register(NAME, ast_module_info->description, mongodb_log);
			if (res) {
				ast_log(LOG_ERROR, "unable to register CDR handling\n");
				break;
			}
			ast_set_flag(&config, CONFIG_REGISTERED);
		}

		if ((tmp = ast_variable_retrieve(cfg, CATEGORY, SERVERID)) != NULL) {
			if (!bson_oid_is_valid (tmp, strlen(tmp))) {
				ast_log(LOG_ERROR, "invalid server id specified.\n");
				break;
			}
			serverid = ast_malloc(sizeof(bson_oid_t));
		   	if (serverid == NULL) {
				ast_log(LOG_ERROR, "not enough memory\n");
				break;
	   		}
			bson_oid_init_from_string(serverid, tmp);
		}

		if (dbpool)
			mongoc_client_pool_destroy(dbpool);
	   	dbpool = mongoc_client_pool_new(uri);
	   	if (dbpool == NULL) {
			ast_log(LOG_ERROR, "cannot make a connection pool for MongoDB\n");
			break;
	   	}

	   	res = 0; // suceess
	} while (0);

	if (uri)
	   mongoc_uri_destroy(uri);
	if (ast_test_flag(&config, CONFIG_REGISTERED) && (!cfg || dbname == NULL || dbcollection == NULL)) {
		ast_cdr_backend_suspend(NAME);
		ast_clear_flag(&config, CONFIG_REGISTERED);
	} 
	else
		ast_cdr_backend_unsuspend(NAME);
	if (cfg && cfg != CONFIG_STATUS_FILEUNCHANGED && cfg != CONFIG_STATUS_FILEINVALID)
		ast_config_destroy(cfg);
	return res;
}
Beispiel #13
0
static int odbc_load_module(void)
{
	int res = 0;
	struct ast_config *cfg;
	struct ast_variable *var;
	const char *tmp;

	ast_mutex_lock(&odbc_lock);

	cfg = ast_config_load(config);
	if (!cfg) {
		ast_log(LOG_WARNING, "cdr_odbc: Unable to load config for ODBC CDR's: %s\n", config);
		res = AST_MODULE_LOAD_DECLINE;
		goto out;
	}
	
	var = ast_variable_browse(cfg, "global");
	if (!var) {
		/* nothing configured */
		goto out;
	}

	tmp = ast_variable_retrieve(cfg,"global","dsn");
	if (tmp == NULL) {
		ast_log(LOG_WARNING,"cdr_odbc: dsn not specified.  Assuming asteriskdb\n");
		tmp = "asteriskdb";
	}
	dsn = strdup(tmp);
	if (dsn == NULL) {
		ast_log(LOG_ERROR,"cdr_odbc: Out of memory error.\n");
		res = -1;
		goto out;
	}

	tmp = ast_variable_retrieve(cfg,"global","dispositionstring");
	if (tmp) {
		dispositionstring = ast_true(tmp);
	} else {
		dispositionstring = 0;
	}
		
	tmp = ast_variable_retrieve(cfg,"global","username");
	if (tmp) {
		username = strdup(tmp);
		if (username == NULL) {
			ast_log(LOG_ERROR,"cdr_odbc: Out of memory error.\n");
			res = -1;
			goto out;
		}
	}

	tmp = ast_variable_retrieve(cfg,"global","password");
	if (tmp) {
		password = strdup(tmp);
		if (password == NULL) {
			ast_log(LOG_ERROR,"cdr_odbc: Out of memory error.\n");
			res = -1;
			goto out;
		}
	}

	tmp = ast_variable_retrieve(cfg,"global","loguniqueid");
	if (tmp) {
		loguniqueid = ast_true(tmp);
		if (loguniqueid) {
			ast_log(LOG_DEBUG,"cdr_odbc: Logging uniqueid\n");
		} else {
			ast_log(LOG_DEBUG,"cdr_odbc: Not logging uniqueid\n");
		}
	} else {
		ast_log(LOG_DEBUG,"cdr_odbc: Not logging uniqueid\n");
		loguniqueid = 0;
	}

	tmp = ast_variable_retrieve(cfg,"global","usegmtime");
	if (tmp) {
		usegmtime = ast_true(tmp);
		if (usegmtime) {
			ast_log(LOG_DEBUG,"cdr_odbc: Logging in GMT\n");
		} else {
			ast_log(LOG_DEBUG,"cdr_odbc: Not logging in GMT\n");
		}
	} else {
		ast_log(LOG_DEBUG,"cdr_odbc: Not logging in GMT\n");
		usegmtime = 0;
	}

	tmp = ast_variable_retrieve(cfg,"global","table");
	if (tmp == NULL) {
		ast_log(LOG_WARNING,"cdr_odbc: table not specified.  Assuming cdr\n");
		tmp = "cdr";
	}
	table = strdup(tmp);
	if (table == NULL) {
		ast_log(LOG_ERROR,"cdr_odbc: Out of memory error.\n");
		res = -1;
		goto out;
	}

	if (option_verbose > 2) {
		ast_verbose( VERBOSE_PREFIX_3 "cdr_odbc: dsn is %s\n",dsn);
		if (username)
		{
			ast_verbose( VERBOSE_PREFIX_3 "cdr_odbc: username is %s\n",username);
			ast_verbose( VERBOSE_PREFIX_3 "cdr_odbc: password is [secret]\n");
		}
		else
			ast_verbose( VERBOSE_PREFIX_3 "cdr_odbc: retreiving username and password from odbc config\n");
		ast_verbose( VERBOSE_PREFIX_3 "cdr_odbc: table is %s\n",table);
	}
	
	res = odbc_init();
	if (res < 0) {
		ast_log(LOG_ERROR, "cdr_odbc: Unable to connect to datasource: %s\n", dsn);
		if (option_verbose > 2) {
			ast_verbose( VERBOSE_PREFIX_3 "cdr_odbc: Unable to connect to datasource: %s\n", dsn);
		}
	}
	res = ast_cdr_register(name, ast_module_info->description, odbc_log);
	if (res) {
		ast_log(LOG_ERROR, "cdr_odbc: Unable to register ODBC CDR handling\n");
	}
out:
	if (cfg)
		ast_config_destroy(cfg);
	ast_mutex_unlock(&odbc_lock);
	return res;
}
static int festival_exec(struct ast_channel *chan, void *vdata)
{
	int usecache;
	int res=0;
	struct localuser *u;
 	struct sockaddr_in serv_addr;
	struct hostent *serverhost;
	struct ast_hostent ahp;
	int fd;
	FILE *fs;
	char *host;
	char *cachedir;
	char *temp;
	char *festivalcommand;
	int port=1314;
	int n;
	char ack[4];
	char *waveform;
	int filesize;
	int wave;
	char bigstring[MAXFESTLEN];
	int i;
	struct MD5Context md5ctx;
	unsigned char MD5Res[16];
	char MD5Hex[33] = "";
	char koko[4] = "";
	char cachefile[MAXFESTLEN]="";
	int readcache=0;
	int writecache=0;
	int strln;
	int fdesc = -1;
	char buffer[16384];
	int seekpos = 0;	
	char *data;	
	char *intstr;
	struct ast_config *cfg;

	if (ast_strlen_zero(vdata)) {
		ast_log(LOG_WARNING, "festival requires an argument (text)\n");
		return -1;
	}

	LOCAL_USER_ADD(u);

	cfg = ast_config_load(FESTIVAL_CONFIG);
	if (!cfg) {
		ast_log(LOG_WARNING, "No such configuration file %s\n", FESTIVAL_CONFIG);
		LOCAL_USER_REMOVE(u);
		return -1;
	}
	if (!(host = ast_variable_retrieve(cfg, "general", "host"))) {
		host = "localhost";
	}
	if (!(temp = ast_variable_retrieve(cfg, "general", "port"))) {
		port = 1314;
	} else {
		port = atoi(temp);
	}
	if (!(temp = ast_variable_retrieve(cfg, "general", "usecache"))) {
		usecache=0;
	} else {
		usecache = ast_true(temp);
	}
	if (!(cachedir = ast_variable_retrieve(cfg, "general", "cachedir"))) {
		cachedir = "/tmp/";
	}
	if (!(festivalcommand = ast_variable_retrieve(cfg, "general", "festivalcommand"))) {
		festivalcommand = "(tts_textasterisk \"%s\" 'file)(quit)\n";
	}
	
	data = ast_strdupa(vdata);
	if (!data) {
		ast_log(LOG_ERROR, "Out of memery\n");
		ast_config_destroy(cfg);
		LOCAL_USER_REMOVE(u);
		return -1;
	}

	intstr = strchr(data, '|');
	if (intstr) {	
		*intstr = '\0';
		intstr++;
		if (!strcasecmp(intstr, "any"))
			intstr = AST_DIGIT_ANY;
	}
	
	ast_log(LOG_DEBUG, "Text passed to festival server : %s\n",(char *)data);
	/* Connect to local festival server */
	
    	fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    	if (fd < 0) {
		ast_log(LOG_WARNING,"festival_client: can't get socket\n");
		ast_config_destroy(cfg);
		LOCAL_USER_REMOVE(u);
        	return -1;
	}
        memset(&serv_addr, 0, sizeof(serv_addr));
        if ((serv_addr.sin_addr.s_addr = inet_addr(host)) == -1) {
	        /* its a name rather than an ipnum */
	        serverhost = ast_gethostbyname(host, &ahp);
	        if (serverhost == (struct hostent *)0) {
        	    	ast_log(LOG_WARNING,"festival_client: gethostbyname failed\n");
			ast_config_destroy(cfg);
			LOCAL_USER_REMOVE(u);
	            	return -1;
        	}
	        memmove(&serv_addr.sin_addr,serverhost->h_addr, serverhost->h_length);
    	}
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_port = htons(port);

	if (connect(fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) != 0) {
		ast_log(LOG_WARNING,"festival_client: connect to server failed\n");
		ast_config_destroy(cfg);
		LOCAL_USER_REMOVE(u);
        	return -1;
    	}
    	
    	/* Compute MD5 sum of string */
    	MD5Init(&md5ctx);
    	MD5Update(&md5ctx,(unsigned char const *)data,strlen(data));
    	MD5Final(MD5Res,&md5ctx);
		MD5Hex[0] = '\0';
    	
    	/* Convert to HEX and look if there is any matching file in the cache 
    		directory */
    	for (i=0;i<16;i++) {
    		snprintf(koko, sizeof(koko), "%X",MD5Res[i]);
    		strncat(MD5Hex, koko, sizeof(MD5Hex) - strlen(MD5Hex) - 1);
    	}
    	readcache=0;
    	writecache=0;
    	if (strlen(cachedir)+strlen(MD5Hex)+1<=MAXFESTLEN && (usecache==-1)) {
    		snprintf(cachefile, sizeof(cachefile), "%s/%s", cachedir, MD5Hex);
    		fdesc=open(cachefile,O_RDWR);
    		if (fdesc==-1) {
    			fdesc=open(cachefile,O_CREAT|O_RDWR,0777);
    			if (fdesc!=-1) {
    				writecache=1;
    				strln=strlen((char *)data);
    				ast_log(LOG_DEBUG,"line length : %d\n",strln);
    				write(fdesc,&strln,sizeof(int));
    				write(fdesc,data,strln);
				seekpos=lseek(fdesc,0,SEEK_CUR);
				ast_log(LOG_DEBUG,"Seek position : %d\n",seekpos);
    			}
    		} else {
    			read(fdesc,&strln,sizeof(int));
    			ast_log(LOG_DEBUG,"Cache file exists, strln=%d, strlen=%d\n",strln,(int)strlen((char *)data));
    			if (strlen((char *)data)==strln) {
    				ast_log(LOG_DEBUG,"Size OK\n");
    				read(fdesc,&bigstring,strln);
	    			bigstring[strln] = 0;
				if (strcmp(bigstring,data)==0) { 
	    				readcache=1;
	    			} else {
	    				ast_log(LOG_WARNING,"Strings do not match\n");
	    			}
	    		} else {
	    			ast_log(LOG_WARNING,"Size mismatch\n");
	    		}
	    	}
	}
    			
	if (readcache==1) {
		close(fd);
		fd=fdesc;
		ast_log(LOG_DEBUG,"Reading from cache...\n");
	} else {
		ast_log(LOG_DEBUG,"Passing text to festival...\n");
    		fs=fdopen(dup(fd),"wb");
		fprintf(fs,festivalcommand,(char *)data);
		fflush(fs);
		fclose(fs);
	}
	
	/* Write to cache and then pass it down */
	if (writecache==1) {
		ast_log(LOG_DEBUG,"Writing result to cache...\n");
		while ((strln=read(fd,buffer,16384))!=0) {
			write(fdesc,buffer,strln);
		}
		close(fd);
		close(fdesc);
		fd=open(cachefile,O_RDWR);
		lseek(fd,seekpos,SEEK_SET);
	}
	
	ast_log(LOG_DEBUG,"Passing data to channel...\n");
	
	/* Read back info from server */
	/* This assumes only one waveform will come back, also LP is unlikely */
	wave = 0;
	do {
               int read_data;
		for (n=0; n < 3; )
               {
                       read_data = read(fd,ack+n,3-n);
                       /* this avoids falling in infinite loop
                        * in case that festival server goes down
                        * */
                       if ( read_data == -1 )
                       {
                               ast_log(LOG_WARNING,"Unable to read from cache/festival fd\n");
			       close(fd);
			       ast_config_destroy(cfg);
			       LOCAL_USER_REMOVE(u);
                               return -1;
                       }
                       n += read_data;
               }
		ack[3] = '\0';
		if (strcmp(ack,"WV\n") == 0) {         /* receive a waveform */
			ast_log(LOG_DEBUG,"Festival WV command\n");
			waveform = socket_receive_file_to_buff(fd,&filesize);
			res = send_waveform_to_channel(chan,waveform,filesize, intstr);
			free(waveform);
			break;
		}
		else if (strcmp(ack,"LP\n") == 0) {   /* receive an s-expr */
			ast_log(LOG_DEBUG,"Festival LP command\n");
			waveform = socket_receive_file_to_buff(fd,&filesize);
			waveform[filesize]='\0';
			ast_log(LOG_WARNING,"Festival returned LP : %s\n",waveform);
			free(waveform);
		} else if (strcmp(ack,"ER\n") == 0) {    /* server got an error */
			ast_log(LOG_WARNING,"Festival returned ER\n");
			res=-1;
			break;
    		}
	} while (strcmp(ack,"OK\n") != 0);
	close(fd);
	ast_config_destroy(cfg);
	LOCAL_USER_REMOVE(u);
	return res;

}
static int parse_config(void)
{
	struct ast_config *config;
	const char *s;

	config = ast_config_load(RES_CONFIG_PGSQL_CONF);

	if (!config) {
		ast_log(LOG_WARNING, "Unable to load config %s\n",RES_CONFIG_PGSQL_CONF);
		return 0;
	}
	if (!(s = ast_variable_retrieve(config, "general", "dbuser"))) {
		ast_log(LOG_WARNING,
				"Postgresql RealTime: No database user found, using 'asterisk' as default.\n");
		strcpy(dbuser, "asterisk");
	} else {
		ast_copy_string(dbuser, s, sizeof(dbuser));
	}

	if (!(s = ast_variable_retrieve(config, "general", "dbpass"))) {
		ast_log(LOG_WARNING,
				"Postgresql RealTime: No database password found, using 'asterisk' as default.\n");
		strcpy(dbpass, "asterisk");
	} else {
		ast_copy_string(dbpass, s, sizeof(dbpass));
	}

	if (!(s = ast_variable_retrieve(config, "general", "dbhost"))) {
		ast_log(LOG_WARNING,
				"Postgresql RealTime: No database host found, using localhost via socket.\n");
		dbhost[0] = '\0';
	} else {
		ast_copy_string(dbhost, s, sizeof(dbhost));
	}

	if (!(s = ast_variable_retrieve(config, "general", "dbname"))) {
		ast_log(LOG_WARNING,
				"Postgresql RealTime: No database name found, using 'asterisk' as default.\n");
		strcpy(dbname, "asterisk");
	} else {
		ast_copy_string(dbname, s, sizeof(dbname));
	}

	if (!(s = ast_variable_retrieve(config, "general", "dbport"))) {
		ast_log(LOG_WARNING,
				"Postgresql RealTime: No database port found, using 5432 as default.\n");
		dbport = 5432;
	} else {
		dbport = atoi(s);
	}

	if (!ast_strlen_zero(dbhost)) {
		/* No socket needed */
	} else if (!(s = ast_variable_retrieve(config, "general", "dbsock"))) {
		ast_log(LOG_WARNING,
				"Postgresql RealTime: No database socket found, using '/tmp/pgsql.sock' as default.\n");
		strcpy(dbsock, "/tmp/pgsql.sock");
	} else {
		ast_copy_string(dbsock, s, sizeof(dbsock));
	}
	ast_config_destroy(config);

	if (!ast_strlen_zero(dbhost)) {
		ast_log(LOG_DEBUG, "Postgresql RealTime Host: %s\n", dbhost);
		ast_log(LOG_DEBUG, "Postgresql RealTime Port: %i\n", dbport);
	} else {
		ast_log(LOG_DEBUG, "Postgresql RealTime Socket: %s\n", dbsock);
	}
	ast_log(LOG_DEBUG, "Postgresql RealTime User: %s\n", dbuser);
	ast_log(LOG_DEBUG, "Postgresql RealTime Password: %s\n", dbpass);
	ast_log(LOG_DEBUG, "Postgresql RealTime DBName: %s\n", dbname);

	return 1;
}