static int launch_streams(const char *name) { switch_xml_t cfg, xml, directory; int x = 0; if (!(xml = switch_xml_open_cfg(global_cf, &cfg, NULL))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", global_cf); return 0; } if (zstr(name)) { for (directory = switch_xml_child(cfg, "directory"); directory; directory = directory->next) { char *name = (char *) switch_xml_attr(directory, "name"); char *path = (char *) switch_xml_attr(directory, "path"); launch_thread(name, path, directory); x++; } } else if ((directory = switch_xml_find_child(cfg, "directory", "name", name))) { char *path = (char *) switch_xml_attr(directory, "path"); launch_thread(name, path, directory); x++; } switch_xml_free(xml); return x; }
switch_status_t mod_xml_radius_check_conditions(switch_channel_t *channel, switch_xml_t conditions) { switch_xml_t condition, param; char *channel_var = NULL; const char *channel_val = NULL; char *regex = NULL; char *anti = NULL; int all_matched = 1; int result = 0; if ( (condition = switch_xml_child(conditions, "condition")) == NULL) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to locate a condition under the conditions section\n"); return SWITCH_STATUS_FALSE; } for (; condition; condition = condition->next) { if ( (param = switch_xml_child(condition, "param")) == NULL) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to locate a param under this condition\n"); return SWITCH_STATUS_FALSE; } all_matched = 1; for (; param && all_matched; param = param->next) { channel_var = (char *) switch_xml_attr(param, "var"); regex = (char *) switch_xml_attr(param, "regex"); anti = (char *) switch_xml_attr(param, "anti"); if ( channel_var == NULL || regex == NULL ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Improperly constructed mod_radius condition: %s %s\n", channel_var, regex); continue; } if ( ( channel_val = switch_channel_get_variable(channel, channel_var) ) == NULL ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Improperly constructed mod_radius condition, no such channel variable: %s %s\n", channel_var, regex); continue; } result = ( switch_regex_match( channel_val, regex) != SWITCH_STATUS_SUCCESS); if (( anti == NULL && result ) || ( anti != NULL && !result ) ){ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Didn't match: %s == %s \n", switch_channel_get_variable(channel, channel_var), regex); all_matched = 0; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Result of %s match: %s == %s \n", anti, switch_channel_get_variable(channel, channel_var), regex); } } if ( all_matched ) { return SWITCH_STATUS_SUCCESS; } } return SWITCH_STATUS_FALSE; }
/*login是否成功 */ bool CBaseModule::isLoginSuc(string username, string userpwd) { //临时方案:目前根据文件读取 bool bRes = false; switch_xml_t x_NEs,x_ne; const char *errmsg[1]={ 0 }; const char *name=NULL; const char *pwd=NULL; char *nefile = switch_mprintf("%s%s%s", SWITCH_GLOBAL_dirs.conf_dir, SWITCH_PATH_SEPARATOR, CARI_CCP_OPUSER_XML_FILE ); if (!cari_common_isExistedFile(nefile)){ goto end; } //将内容转换成xml的结构(注意:中文字符问题) x_NEs = cari_common_parseXmlFromFile(nefile); if (!x_NEs){ goto end; } //遍历查找 x_ne = switch_xml_child(x_NEs, "opuser"); for (; x_ne; x_ne = x_ne->next) { name = switch_xml_attr(x_ne, "name"); pwd = switch_xml_attr(x_ne, "pwd"); if (isEqualStr(username.c_str(),name) && isEqualStr(userpwd.c_str(),pwd)){ bRes = true; break; } } end: switch_safe_free(nefile); return bRes; }
void switch_load_timezones(switch_bool_t reload) { switch_xml_t xml = NULL, x_lists = NULL, x_list = NULL, cfg = NULL; unsigned total = 0; if (TIMEZONES_LIST.hash) { switch_core_hash_destroy(&TIMEZONES_LIST.hash); } if (TIMEZONES_LIST.pool) { switch_core_destroy_memory_pool(&TIMEZONES_LIST.pool); } memset(&TIMEZONES_LIST, 0, sizeof(TIMEZONES_LIST)); switch_core_new_memory_pool(&TIMEZONES_LIST.pool); switch_core_hash_init(&TIMEZONES_LIST.hash, TIMEZONES_LIST.pool); if ((xml = switch_xml_open_cfg("timezones.conf", &cfg, NULL))) { if ((x_lists = switch_xml_child(cfg, "timezones"))) { for (x_list = switch_xml_child(x_lists, "zone"); x_list; x_list = x_list->next) { const char *name = switch_xml_attr(x_list, "name"); const char *value = switch_xml_attr(x_list, "value"); if (zstr(name)) { continue; } if (zstr(value)) { continue; } switch_core_hash_insert(TIMEZONES_LIST.hash, name, switch_core_strdup(TIMEZONES_LIST.pool, value)); total++; } } switch_xml_free(xml); } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Timezone %sloaded %d definitions\n", reload ? "re" : "", total); }
switch_status_t mod_xml_radius_check_conditions(switch_channel_t *channel, switch_xml_t conditions) { switch_xml_t condition, param; char *channel_var = NULL; char *regex = NULL; int all_matched = 1; if ( (condition = switch_xml_child(conditions, "condition")) == NULL) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to locate a condition under the conditions section\n"); return SWITCH_STATUS_FALSE; } for (; condition; condition = condition->next) { if ( (param = switch_xml_child(condition, "param")) == NULL) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to locate a param under this condition\n"); return SWITCH_STATUS_FALSE; } all_matched = 1; for (; param && all_matched; param = param->next) { channel_var = (char *) switch_xml_attr(param, "var"); regex = (char *) switch_xml_attr(param, "regex"); if ( channel_var == NULL || regex == NULL ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Improperly constructed mod_radius condition: %s %s\n", channel_var, regex); } if ( switch_regex_match( switch_channel_get_variable(channel, channel_var), regex) != SWITCH_STATUS_SUCCESS) { all_matched = 0; } } if ( all_matched ) { return SWITCH_STATUS_SUCCESS; } } return SWITCH_STATUS_FALSE; }
static void do_config(switch_bool_t reload) { switch_xml_t xml = NULL, x_lists = NULL, x_list = NULL, cfg = NULL; if ((xml = switch_xml_open_cfg("hash.conf", &cfg, NULL))) { if ((x_lists = switch_xml_child(cfg, "remotes"))) { for (x_list = switch_xml_child(x_lists, "remote"); x_list; x_list = x_list->next) { const char *name = switch_xml_attr(x_list, "name"); const char *host = switch_xml_attr(x_list, "host"); const char *szport = switch_xml_attr(x_list, "port"); const char *username = switch_xml_attr(x_list, "username"); const char *password = switch_xml_attr(x_list, "password"); const char *szinterval = switch_xml_attr(x_list, "interval"); uint16_t port = 0; int interval = 0; limit_remote_t *remote; switch_threadattr_t *thd_attr = NULL; if (reload) { switch_thread_rwlock_rdlock(globals.remote_hash_rwlock); if (switch_core_hash_find(globals.remote_hash, name)) { switch_thread_rwlock_unlock(globals.remote_hash_rwlock); continue; } switch_thread_rwlock_unlock(globals.remote_hash_rwlock); } if (!zstr(szport)) { port = (uint16_t)atoi(szport); } if (!zstr(szinterval)) { interval = atoi(szinterval); } remote = limit_remote_create(name, host, port, username, password, interval); remote->state = REMOTE_DOWN; switch_threadattr_create(&thd_attr, remote->pool); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); switch_thread_create(&remote->thread, thd_attr, limit_remote_thread, remote, remote->pool); } } switch_xml_free(xml); } }
static switch_status_t load_config(switch_memory_pool_t *pool) { char *cf = "cdr_csv.conf"; switch_xml_t cfg, xml, settings, param; switch_status_t status = SWITCH_STATUS_SUCCESS; memset(&globals, 0, sizeof(globals)); switch_core_hash_init(&globals.fd_hash, pool); switch_core_hash_init(&globals.template_hash, pool); globals.pool = pool; switch_core_hash_insert(globals.template_hash, "default", default_template); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding default template.\n"); globals.legs = CDR_LEG_A; if ((xml = switch_xml_open_cfg(cf, &cfg, NULL))) { if ((settings = switch_xml_child(cfg, "settings"))) { for (param = switch_xml_child(settings, "param"); param; param = param->next) { char *var = (char *) switch_xml_attr_soft(param, "name"); char *val = (char *) switch_xml_attr_soft(param, "value"); if (!strcasecmp(var, "debug")) { globals.debug = switch_true(val); } else if (!strcasecmp(var, "legs")) { globals.legs = 0; if (strchr(val, 'a')) { globals.legs |= CDR_LEG_A; } if (strchr(val, 'b')) { globals.legs |= CDR_LEG_B; } } else if (!strcasecmp(var, "log-base")) { globals.log_dir = switch_core_sprintf(pool, "%s%scdr-csv", val, SWITCH_PATH_SEPARATOR); } else if (!strcasecmp(var, "rotate-on-hup")) { globals.rotate = switch_true(val); } else if (!strcasecmp(var, "default-template")) { globals.default_template = switch_core_strdup(pool, val); } else if (!strcasecmp(var, "master-file-only")) { globals.masterfileonly = switch_true(val); } } } if ((settings = switch_xml_child(cfg, "templates"))) { for (param = switch_xml_child(settings, "template"); param; param = param->next) { char *var = (char *) switch_xml_attr(param, "name"); if (var) { char *tpl; size_t len = strlen(param->txt) + 2; if (end_of(param->txt) != '\n') { tpl = switch_core_alloc(pool, len); switch_snprintf(tpl, len, "%s\n", param->txt); } else { tpl = switch_core_strdup(pool, param->txt); } switch_core_hash_insert(globals.template_hash, var, tpl); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding template %s.\n", var); } } } switch_xml_free(xml); } if (zstr(globals.default_template)) { globals.default_template = switch_core_strdup(pool, "default"); } if (!globals.log_dir) { globals.log_dir = switch_core_sprintf(pool, "%s%scdr-csv", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR); } return status; }
static switch_status_t load_config(switch_memory_pool_t *pool) { char *cf = "cdr_sqlite.conf"; switch_xml_t cfg, xml, settings, param; switch_cache_db_handle_t *dbh = NULL; char *select_sql = NULL, *create_sql = NULL; switch_status_t status = SWITCH_STATUS_SUCCESS; memset(&globals, 0, sizeof(globals)); switch_core_hash_init(&globals.template_hash, pool); globals.pool = pool; switch_core_hash_insert(globals.template_hash, "default", default_template); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding default template.\n"); globals.legs = CDR_LEG_A; if ((xml = switch_xml_open_cfg(cf, &cfg, NULL))) { if ((settings = switch_xml_child(cfg, "settings"))) { for (param = switch_xml_child(settings, "param"); param; param = param->next) { char *var = (char *) switch_xml_attr_soft(param, "name"); char *val = (char *) switch_xml_attr_soft(param, "value"); if (!strcasecmp(var, "debug")) { globals.debug = switch_true(val); } else if (!strcasecmp(var, "db-name")) { globals.db_name = switch_core_strdup(pool, val); } else if (!strcasecmp(var, "db-table")) { globals.db_table = switch_core_strdup(pool, val); } else if (!strcasecmp(var, "legs")) { globals.legs = 0; if (strchr(val, 'a')) { globals.legs |= CDR_LEG_A; } if (strchr(val, 'b')) { globals.legs |= CDR_LEG_B; } } else if (!strcasecmp(var, "default-template")) { globals.default_template = switch_core_strdup(pool, val); } } } if ((settings = switch_xml_child(cfg, "templates"))) { for (param = switch_xml_child(settings, "template"); param; param = param->next) { char *var = (char *) switch_xml_attr(param, "name"); if (var) { char *tpl; tpl = switch_core_strdup(pool, param->txt); switch_core_hash_insert(globals.template_hash, var, tpl); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding template %s.\n", var); } } } switch_xml_free(xml); } if (zstr(globals.db_name)) { globals.db_name = switch_core_strdup(pool, "cdr"); } if (zstr(globals.db_table)) { globals.db_table = switch_core_strdup(pool, "cdr"); } if (zstr(globals.default_template)) { globals.default_template = switch_core_strdup(pool, "default"); } dbh = cdr_get_db_handle(); if (dbh) { select_sql = switch_mprintf("SELECT * FROM %s LIMIT 1", globals.db_table); assert(select_sql); create_sql = switch_mprintf(default_create_sql, globals.db_table); assert(create_sql); /* Check if table exists (try SELECT FROM ...) and create table if query fails */ switch_cache_db_test_reactive(dbh, select_sql, NULL, create_sql); switch_safe_free(select_sql); switch_safe_free(create_sql); switch_cache_db_release_db_handle(&dbh); } return status; }
static int sangoma_parse_config(void) { switch_xml_t cfg, settings, param, vocallos, xml, vocallo; struct in_addr vocallo_base_ip; char ipbuff[50]; char netbuff[50]; int host_ipaddr = 0; int host_netmaskaddr = 0; int vidx = 0; int baseudp = 0; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Reading sangoma codec configuration\n"); if (!(xml = switch_xml_open_cfg(SANGOMA_TRANSCODE_CONFIG, &cfg, NULL))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to open sangoma codec configuration %s\n", SANGOMA_TRANSCODE_CONFIG); return -1; } memset(&g_init_cfg, 0, sizeof(g_init_cfg)); if ((settings = switch_xml_child(cfg, "settings"))) { /* nothing here yet */ for (param = switch_xml_child(settings, "param"); param; param = param->next) { char *var = (char *)switch_xml_attr_soft(param, "name"); char *val = (char *)switch_xml_attr_soft(param, "value"); /* this parameter overrides the default list of codecs to load */ if (!strcasecmp(var, "register")) { strncpy(g_codec_register_list, val, sizeof(g_codec_register_list)-1); g_codec_register_list[sizeof(g_codec_register_list)-1] = 0; } else if (!strcasecmp(var, "noregister")) { strncpy(g_codec_noregister_list, val, sizeof(g_codec_noregister_list)-1); g_codec_noregister_list[sizeof(g_codec_noregister_list)-1] = 0; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Ignored unknown Sangoma codec setting %s\n", var); } } } if ((vocallos = switch_xml_child(cfg, "vocallos"))) { for (vocallo = switch_xml_child(vocallos, "vocallo"); vocallo; vocallo = vocallo->next) { const char *name = switch_xml_attr(vocallo, "name"); if (!name) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Sangoma vocallo found with no name= attribute, ignoring!\n"); continue; } if (load_nic_network_information(name, &g_init_cfg.host_nic_vocallo_cfg[vidx])) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Ignoring vocallo %s, failed to retrieve its network configuration\n", name); continue; } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Configuring vocallo %s\n", name); g_init_cfg.host_nic_vocallo_cfg[vidx].vocallo_base_udp_port = SANGOMA_DEFAULT_UDP_PORT; g_init_cfg.host_nic_vocallo_cfg[vidx].silence_suppression = 0; for (param = switch_xml_child(vocallo, "param"); param; param = param->next) { char *var = (char *)switch_xml_attr_soft(param, "name"); char *val = (char *)switch_xml_attr_soft(param, "value"); /* starting UDP port to be used by the vocallo modules */ if (!strcasecmp(var, "baseudp")) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Found Sangoma codec base udp port %s\n", val); baseudp = atoi(val); if (baseudp < SANGOMA_MIN_UDP_PORT || baseudp > SANGOMA_MAX_UDP_PORT) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid Sangoma codec base udp port %s, using default %d\n", val, SANGOMA_DEFAULT_UDP_PORT); break; } g_init_cfg.host_nic_vocallo_cfg[vidx].vocallo_base_udp_port = baseudp; } else if (!strcasecmp(var, "vocalloaddr")) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Found Sangoma codec vocallo addr %s\n", val); if (switch_inet_pton(AF_INET, val, &vocallo_base_ip) <= 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid Sangoma codec vocallo addr %s\n", val); break; } g_init_cfg.host_nic_vocallo_cfg[vidx].vocallo_ip = ntohl(vocallo_base_ip.s_addr); } else if (!strcasecmp(var, "silence")) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Found Sangoma codec silence setting %s\n", val); g_init_cfg.host_nic_vocallo_cfg[vidx].silence_suppression = switch_true(val) ? 1 : 0; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Ignored unknown Sangoma vocallo setting %s\n", var); } } if (!g_init_cfg.host_nic_vocallo_cfg[vidx].vocallo_ip) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Ignoring vocallo %s, no valid address was configured\n", name); continue; } host_ipaddr = htonl(g_init_cfg.host_nic_vocallo_cfg[vidx].host_ip); host_netmaskaddr = htonl(g_init_cfg.host_nic_vocallo_cfg[vidx].host_ip_netmask); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Configured Sangoma transcoding interface %s, IP address %s, netmask %s\n", name, switch_inet_ntop(AF_INET, &host_ipaddr, ipbuff, sizeof(ipbuff)), switch_inet_ntop(AF_INET, &host_netmaskaddr, netbuff, sizeof(netbuff))); strncpy(g_vocallo_names[vidx], name, sizeof(g_vocallo_names[vidx])-1); g_vocallo_names[vidx][sizeof(g_vocallo_names[vidx])-1] = 0; vidx++; } } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No <vocallos> section found in configuration file %s\n", SANGOMA_TRANSCODE_CONFIG); } switch_xml_free(xml); if (!vidx) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No vocallos were configured, make sure there is at least one <vocallo> in %s.\n", SANGOMA_TRANSCODE_CONFIG); } g_init_cfg.host_nic_vocallo_sz = vidx; return 0; }
static void launch_threads(void) { char *cf = "local_stream.conf"; switch_xml_t cfg, xml, directory, param; switch_memory_pool_t *pool; local_stream_source_t *source; switch_thread_t *thread; switch_threadattr_t *thd_attr = NULL; if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", cf); return; } for (directory = switch_xml_child(cfg, "directory"); directory; directory = directory->next) { char *path = (char *) switch_xml_attr(directory, "path"); char *name = (char *) switch_xml_attr(directory, "name"); if (!(name && path)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid config!\n"); continue; } if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "OH OH no pool\n"); abort(); } source = switch_core_alloc(pool, sizeof(*source)); assert(source != NULL); source->pool = pool; source->name = switch_core_strdup(source->pool, name); source->location = switch_core_strdup(source->pool, path); source->rate = 8000; source->interval = 20; source->channels = 1; source->timer_name = "soft"; source->prebuf = DEFAULT_PREBUFFER_SIZE; source->stopped = 0; source->chime_freq = 30; for (param = switch_xml_child(directory, "param"); param; param = param->next) { char *var = (char *) switch_xml_attr_soft(param, "name"); char *val = (char *) switch_xml_attr_soft(param, "value"); if (!strcasecmp(var, "rate")) { int tmp = atoi(val); if (tmp == 8000 || tmp == 12000 || tmp == 16000 || tmp == 24000 || tmp == 32000 || tmp == 48000) { source->rate = tmp; } } else if (!strcasecmp(var, "shuffle")) { source->shuffle = switch_true(val); } else if (!strcasecmp(var, "prebuf")) { int tmp = atoi(val); if (tmp > 0) { source->prebuf = (uint32_t) tmp; } } else if (!strcasecmp(var, "channels")) { int tmp = atoi(val); if (tmp == 1 || tmp == 2) { source->channels = (uint8_t) tmp; } } else if (!strcasecmp(var, "chime-freq")) { int tmp = atoi(val); if (tmp > 1) { source->chime_freq = tmp; } } else if (!strcasecmp(var, "chime-max")) { int tmp = atoi(val); if (tmp > 1) { source->chime_max = tmp; } } else if (!strcasecmp(var, "chime-list")) { char *list_dup = switch_core_strdup(source->pool, val); source->chime_total = switch_separate_string(list_dup, ',', source->chime_list, (sizeof(source->chime_list) / sizeof(source->chime_list[0]))); } else if (!strcasecmp(var, "interval")) { int tmp = atoi(val); if (SWITCH_ACCEPTABLE_INTERVAL(tmp)) { source->interval = tmp; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Interval must be multiple of 10 and less than %d, Using default of 20\n", SWITCH_MAX_INTERVAL); } } else if (!strcasecmp(var, "timer-name")) { source->timer_name = switch_core_strdup(source->pool, val); } } if (source->chime_max) { source->chime_max *= source->rate; } if (source->chime_total) { source->chime_counter = source->rate * source->chime_freq; } source->samples = switch_samples_per_packet(source->rate, source->interval); switch_mutex_init(&source->mutex, SWITCH_MUTEX_NESTED, source->pool); switch_threadattr_create(&thd_attr, source->pool); switch_threadattr_detach_set(thd_attr, 1); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); switch_thread_create(&thread, thd_attr, read_stream_thread, source, source->pool); } switch_xml_free(xml); }
static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *caller_profile, switch_xml_t xexten, switch_caller_extension_t **extension) { switch_xml_t xcond, xaction, xexpression; switch_channel_t *channel = switch_core_session_get_channel(session); char *exten_name = (char *) switch_xml_attr(xexten, "name"); int proceed = 0; char *expression_expanded = NULL, *field_expanded = NULL; switch_regex_t *re = NULL; if (!exten_name) { exten_name = "_anon_"; } for (xcond = switch_xml_child(xexten, "condition"); xcond; xcond = xcond->next) { char *field = NULL; char *do_break_a = NULL; char *expression = NULL; const char *field_data = NULL; int ovector[30]; switch_bool_t anti_action = SWITCH_TRUE; break_t do_break_i = BREAK_ON_FALSE; int time_match = switch_xml_std_datetime_check(xcond); switch_safe_free(field_expanded); switch_safe_free(expression_expanded); if (switch_xml_child(xcond, "condition")) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Nested conditions are not allowed!\n"); proceed = 1; goto done; } field = (char *) switch_xml_attr(xcond, "field"); if ((xexpression = switch_xml_child(xcond, "expression"))) { expression = switch_str_nil(xexpression->txt); } else { expression = (char *) switch_xml_attr_soft(xcond, "expression"); } if ((expression_expanded = switch_channel_expand_variables(channel, expression)) == expression) { expression_expanded = NULL; } else { expression = expression_expanded; } if ((do_break_a = (char *) switch_xml_attr(xcond, "break"))) { if (!strcasecmp(do_break_a, "on-true")) { do_break_i = BREAK_ON_TRUE; } else if (!strcasecmp(do_break_a, "on-false")) { do_break_i = BREAK_ON_FALSE; } else if (!strcasecmp(do_break_a, "always")) { do_break_i = BREAK_ALWAYS; } else if (!strcasecmp(do_break_a, "never")) { do_break_i = BREAK_NEVER; } else { do_break_a = NULL; } } if (time_match == 1) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG, "Dialplan: %s Date/Time Match (PASS) [%s] break=%s\n", switch_channel_get_name(channel), exten_name, do_break_a ? do_break_a : "on-false"); anti_action = SWITCH_FALSE; } else if (time_match == 0) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG, "Dialplan: %s Date/Time Match (FAIL) [%s] break=%s\n", switch_channel_get_name(channel), exten_name, do_break_a ? do_break_a : "on-false"); } if (field) { if (strchr(field, '$')) { if ((field_expanded = switch_channel_expand_variables(channel, field)) == field) { field_expanded = NULL; field_data = field; } else { field_data = field_expanded; } } else { field_data = switch_caller_get_field_by_name(caller_profile, field); } if (!field_data) { field_data = ""; } if ((proceed = switch_regex_perform(field_data, expression, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG, "Dialplan: %s Regex (PASS) [%s] %s(%s) =~ /%s/ break=%s\n", switch_channel_get_name(channel), exten_name, field, field_data, expression, do_break_a ? do_break_a : "on-false"); anti_action = SWITCH_FALSE; } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG, "Dialplan: %s Regex (FAIL) [%s] %s(%s) =~ /%s/ break=%s\n", switch_channel_get_name(channel), exten_name, field, field_data, expression, do_break_a ? do_break_a : "on-false"); } } else if (time_match == -1) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG, "Dialplan: %s Absolute Condition [%s]\n", switch_channel_get_name(channel), exten_name); anti_action = SWITCH_FALSE; } if (anti_action) { for (xaction = switch_xml_child(xcond, "anti-action"); xaction; xaction = xaction->next) { const char *application = switch_xml_attr_soft(xaction, "application"); const char *loop = switch_xml_attr(xaction, "loop"); const char *data; const char *inline_ = switch_xml_attr_soft(xaction, "inline"); int xinline = switch_true(inline_); int loop_count = 1; if (!zstr(xaction->txt)) { data = xaction->txt; } else { data = (char *) switch_xml_attr_soft(xaction, "data"); } if (!*extension) { if ((*extension = switch_caller_extension_new(session, exten_name, caller_profile->destination_number)) == 0) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Memory Error!\n"); proceed = 0; goto done; } } if (loop) { loop_count = atoi(loop); } for (;loop_count > 0; loop_count--) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG, "Dialplan: %s ANTI-Action %s(%s) %s\n", switch_channel_get_name(channel), application, data, xinline ? "INLINE" : ""); if (xinline) { exec_app(session, application, data); } else { switch_caller_extension_add_application(session, *extension, application, data); } } proceed = 1; } } else { for (xaction = switch_xml_child(xcond, "action"); xaction; xaction = xaction->next) { char *application = (char *) switch_xml_attr_soft(xaction, "application"); const char *loop = switch_xml_attr(xaction, "loop"); char *data = NULL; char *substituted = NULL; uint32_t len = 0; char *app_data = NULL; const char *inline_ = switch_xml_attr_soft(xaction, "inline"); int xinline = switch_true(inline_); int loop_count = 1; if (!zstr(xaction->txt)) { data = xaction->txt; } else { data = (char *) switch_xml_attr_soft(xaction, "data"); } if (field && strchr(expression, '(')) { len = (uint32_t) (strlen(data) + strlen(field_data) + 10) * proceed; if (!(substituted = malloc(len))) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Memory Error!\n"); proceed = 0; goto done; } memset(substituted, 0, len); switch_perform_substitution(re, proceed, data, field_data, substituted, len, ovector); app_data = substituted; } else { app_data = data; } if (!*extension) { if ((*extension = switch_caller_extension_new(session, exten_name, caller_profile->destination_number)) == 0) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Memory Error!\n"); proceed = 0; goto done; } } if (loop) { loop_count = atoi(loop); } for (;loop_count > 0; loop_count--) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG, "Dialplan: %s Action %s(%s) %s\n", switch_channel_get_name(channel), application, app_data, xinline ? "INLINE" : ""); if (xinline) { exec_app(session, application, app_data); } else { switch_caller_extension_add_application(session, *extension, application, app_data); } } switch_safe_free(substituted); } } switch_regex_safe_free(re); if (((anti_action == SWITCH_FALSE && do_break_i == BREAK_ON_TRUE) || (anti_action == SWITCH_TRUE && do_break_i == BREAK_ON_FALSE)) || do_break_i == BREAK_ALWAYS) { break; } } done: switch_regex_safe_free(re); switch_safe_free(field_expanded); switch_safe_free(expression_expanded); return proceed; }
SWITCH_DECLARE(switch_status_t) switch_ivr_menu_stack_xml_build(switch_ivr_menu_xml_ctx_t *xml_menu_ctx, switch_ivr_menu_t ** menu_stack, switch_xml_t xml_menus, switch_xml_t xml_menu) { switch_status_t status = SWITCH_STATUS_FALSE; if (xml_menu_ctx != NULL && menu_stack != NULL && xml_menu != NULL) { const char *menu_name = switch_xml_attr_soft(xml_menu, "name"); /* if the attr doesn't exist, return "" */ const char *greet_long = switch_xml_attr(xml_menu, "greet-long"); /* if the attr doesn't exist, return NULL */ const char *greet_short = switch_xml_attr(xml_menu, "greet-short"); /* if the attr doesn't exist, return NULL */ const char *invalid_sound = switch_xml_attr(xml_menu, "invalid-sound"); /* if the attr doesn't exist, return NULL */ const char *exit_sound = switch_xml_attr(xml_menu, "exit-sound"); /* if the attr doesn't exist, return NULL */ const char *timeout = switch_xml_attr_soft(xml_menu, "timeout"); /* if the attr doesn't exist, return "" */ const char *max_failures = switch_xml_attr_soft(xml_menu, "max-failures"); /* if the attr doesn't exist, return "" */ const char *max_timeouts = switch_xml_attr_soft(xml_menu, "max-timeouts"); const char *confirm_macro = switch_xml_attr(xml_menu, "confirm-macro"); const char *confirm_key = switch_xml_attr(xml_menu, "confirm-key"); const char *tts_engine = switch_xml_attr(xml_menu, "tts-engine"); const char *tts_voice = switch_xml_attr(xml_menu, "tts-voice"); const char *confirm_attempts = switch_xml_attr_soft(xml_menu, "confirm-attempts"); const char *digit_len = switch_xml_attr_soft(xml_menu, "digit-len"); const char *inter_timeout = switch_xml_attr_soft(xml_menu, "inter-digit-timeout"); switch_ivr_menu_t *menu = NULL; if (zstr(max_timeouts)) { max_timeouts = max_failures; } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "building menu '%s'\n", menu_name); status = switch_ivr_menu_init(&menu, *menu_stack, menu_name, greet_long, greet_short, invalid_sound, exit_sound, confirm_macro, confirm_key, tts_engine, tts_voice, atoi(confirm_attempts), atoi(inter_timeout), atoi(digit_len), atoi(timeout), strlen(max_failures) ? atoi(max_failures) : 0, strlen(max_timeouts) ? atoi(max_timeouts) : 0, xml_menu_ctx->pool); /* set the menu_stack for the caller */ if (status == SWITCH_STATUS_SUCCESS && *menu_stack == NULL) { *menu_stack = menu; if (xml_menu_ctx->autocreated) { switch_set_flag(menu, SWITCH_IVR_MENU_FLAG_FREEPOOL); } } if (status == SWITCH_STATUS_SUCCESS && menu != NULL) { switch_xml_t xml_kvp; /* build menu entries */ for (xml_kvp = switch_xml_child(xml_menu, "entry"); xml_kvp != NULL && status == SWITCH_STATUS_SUCCESS; xml_kvp = xml_kvp->next) { const char *action = switch_xml_attr(xml_kvp, "action"); const char *digits = switch_xml_attr(xml_kvp, "digits"); const char *param = switch_xml_attr_soft(xml_kvp, "param"); if (is_valid_action(action) && !zstr(digits)) { switch_ivr_menu_xml_map_t *xml_map = xml_menu_ctx->map; int found = 0; /* find and appropriate xml handler */ while (xml_map != NULL && !found) { if (!(found = (strcasecmp(xml_map->name, action) == 0))) { xml_map = xml_map->next; } } if (found && xml_map != NULL) { /* do we need to build a new sub-menu ? */ if (xml_map->action == SWITCH_IVR_ACTION_EXECMENU && switch_ivr_menu_find(*menu_stack, param) == NULL) { if ((xml_menu = switch_xml_find_child(xml_menus, "menu", "name", param)) != NULL) { status = switch_ivr_menu_stack_xml_build(xml_menu_ctx, menu_stack, xml_menus, xml_menu); } } /* finally bind the menu entry */ if (status == SWITCH_STATUS_SUCCESS) { if (xml_map->function != NULL) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "binding menu caller control '%s'/'%s' to '%s'\n", xml_map->name, param, digits); status = switch_ivr_menu_bind_function(menu, xml_map->function, param, digits); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "binding menu action '%s' to '%s'\n", xml_map->name, digits); status = switch_ivr_menu_bind_action(menu, xml_map->action, param, digits); } } } } else { status = SWITCH_STATUS_FALSE; } } } } if (status != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to build xml menu\n"); } return status; }
static int load_config(int reloading) { struct dist_list *main_list = NULL, *new_list, *old_list = NULL, *lp = NULL; switch_status_t status = SWITCH_STATUS_FALSE; char *cf = "distributor.conf"; switch_xml_t cfg, xml, lists, list, param; if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", cf); return SWITCH_STATUS_TERM; } if (!(lists = switch_xml_child(cfg, "lists"))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't find any lists!\n"); return status; } switch_mutex_lock(globals.mod_lock); for (list = switch_xml_child(lists, "list"); list; list = list->next) { const char *name = switch_xml_attr(list, "name"); const char *tweight = switch_xml_attr(list, "total-weight"); struct dist_node *node, *np = NULL; if (zstr(name)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing NAME!\n"); continue; } if (!zstr(tweight)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "The total-weight attribute is no longer necessary.\n"); } switch_zmalloc(new_list, sizeof(*new_list)); new_list->name = strdup(name); new_list->last = -1; if (lp) { lp->next = new_list; } else { main_list = new_list; } lp = new_list; for (param = switch_xml_child(list, "node"); param; param = param->next) { char *name_attr = (char *) switch_xml_attr_soft(param, "name"); char *weight_val = (char *) switch_xml_attr_soft(param, "weight"); int tmp; if ((tmp = atoi(weight_val)) < 1) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Weight %d value incorrect, must be > 0\n", tmp); continue; } switch_zmalloc(node, sizeof(*node)); node->name = strdup(name_attr); node->wval = tmp; if (np) { np->next = node; } else { lp->nodes = node; } np = node; lp->node_count++; } calc_weight(lp); } if (main_list) { old_list = globals.list; globals.list = main_list; status = SWITCH_STATUS_SUCCESS; } switch_mutex_unlock(globals.mod_lock); if (old_list) { destroy_list(old_list); } if (xml) { switch_xml_free(xml); } return status; }
switch_status_t load_agent(const char *agent_name) { switch_xml_t x_agents, x_agent, cfg, xml; if (!(xml = switch_xml_open_cfg(global_cf, &cfg, NULL))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", global_cf); return SWITCH_STATUS_FALSE; } if (!(x_agents = switch_xml_child(cfg, "agents"))) { goto end; } if ((x_agent = switch_xml_find_child(x_agents, "agent", "name", agent_name))) { const char *type = switch_xml_attr(x_agent, "type"); const char *contact = switch_xml_attr(x_agent, "contact"); const char *status = switch_xml_attr(x_agent, "status"); const char *max_no_answer = switch_xml_attr(x_agent, "max-no-answer"); const char *wrap_up_time = switch_xml_attr(x_agent, "wrap-up-time"); const char *reject_delay_time = switch_xml_attr(x_agent, "reject-delay-time"); const char *busy_delay_time = switch_xml_attr(x_agent, "busy-delay-time"); const char *no_answer_delay_time = switch_xml_attr(x_agent, "no-answer-delay-time"); if (type) { cc_status_t res = cc_agent_add(agent_name, type); // For HA, only add new agent, DO NOT update or DELETE. if (res == CC_STATUS_AGENT_ALREADY_EXIST) { goto end; } if (res == CC_STATUS_SUCCESS) { if (contact) { cc_agent_update("contact", contact, agent_name); } if (status) { cc_agent_update("status", status, agent_name); } if (wrap_up_time) { cc_agent_update("wrap_up_time", wrap_up_time, agent_name); } if (max_no_answer) { cc_agent_update("max_no_answer", max_no_answer, agent_name); } if (reject_delay_time) { cc_agent_update("reject_delay_time", reject_delay_time, agent_name); } if (busy_delay_time) { cc_agent_update("busy_delay_time", busy_delay_time, agent_name); } if (no_answer_delay_time) { cc_agent_update("no_answer_delay_time", no_answer_delay_time, agent_name); } /* if (type && res == CC_STATUS_AGENT_ALREADY_EXIST) { cc_agent_update("type", type, agent_name); }*/ } } } end: if (xml) { switch_xml_free(xml); } return SWITCH_STATUS_SUCCESS; }
/** * read default settings from speex.conf */ static void load_configuration() { switch_xml_t xml = NULL, cfg = NULL; if ((xml = switch_xml_open_cfg("speex.conf", &cfg, NULL))) { switch_xml_t x_lists; if ((x_lists = switch_xml_child(cfg, "settings"))) { const char *settings_name = switch_xml_attr(x_lists, "name"); switch_xml_t x_list; if (zstr(settings_name)) { settings_name = ""; } for (x_list = switch_xml_child(x_lists, "param"); x_list; x_list = x_list->next) { const char *name = switch_xml_attr(x_list, "name"); const char *value = switch_xml_attr(x_list, "value"); if (zstr(name)) { continue; } if (zstr(value)) { continue; } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s %s = %s\n", settings_name, name, value); if (!strcasecmp("quality", name)) { /* compression quality, integer 0-10 */ int tmp = atoi(value); if (switch_is_number(value) && tmp >= 0 && tmp <= 10) { default_codec_settings.quality = tmp; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ignoring invalid quality value: %s\n", value); } } else if (!strcasecmp("complexity", name)) { /* compression complexity, integer 1-10 */ int tmp = atoi(value); if (switch_is_number(value) && tmp >= 1 && tmp <= 10) { default_codec_settings.complexity = tmp; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ignoring invalid complexity value: %s\n", value); } } else if (!strcasecmp("enhancement", name)) { /* enable perceptual enhancement, boolean */ default_codec_settings.enhancement = switch_true(value); } else if (!strcasecmp("vad", name)) { /* enable voice activity detection, boolean */ default_codec_settings.vad = switch_true(value); } else if (!strcasecmp("vbr", name)) { /* enable variable bit rate, boolean */ default_codec_settings.vbr = switch_true(value); } else if (!strcasecmp("vbr-quality", name)) { /* variable bit rate quality, float 0-10 */ float tmp = atof(value); if (switch_is_number(value) && tmp >= 0 && tmp <= 10) { default_codec_settings.vbr_quality = tmp; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ignoring invalid vbr-quality value: %s\n", value); } } else if (!strcasecmp("abr", name)) { /* average bit rate, integer bits per sec */ int tmp = atoi(value); if (switch_is_number(value) && tmp >= 0) { default_codec_settings.abr = tmp; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ignoring invalid abr value: %s\n", value); } } else if (!strcasecmp("dtx", name)) { /* discontinuous transmit, boolean */ default_codec_settings.dtx = switch_true(value); } else if (!strcasecmp("preproc", name)) { /* enable preprocessor, boolean */ default_codec_settings.preproc = switch_true(value); } else if (!strcasecmp("pp-vad", name)) { /* enable preprocessor VAD, boolean */ default_codec_settings.pp_vad = switch_true(value); } else if (!strcasecmp("pp-agc", name)) { /* enable preprocessor automatic gain control, boolean */ default_codec_settings.pp_agc = switch_true(value); } else if (!strcasecmp("pp-agc-level", name)) { /* agc level, float */ float tmp = atof(value); if (switch_is_number(value) && tmp >= 0.0f) { default_codec_settings.pp_agc_level = tmp; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ignoring invalid pp-agc-level value: %s\n", value); } } else if (!strcasecmp("pp-denoise", name)) { /* enable preprocessor denoiser, boolean */ default_codec_settings.pp_denoise = switch_true(value); } else if (!strcasecmp("pp-dereverb", name)) { /* enable preprocessor reverberation removal, boolean */ default_codec_settings.pp_dereverb = switch_true(value); } else if (!strcasecmp("pp-dereverb-decay", name)) { /* reverberation removal decay, float */ float tmp = atof(value); if (switch_is_number(value) && tmp >= 0.0f) { default_codec_settings.pp_dereverb_decay = tmp; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ignoring invalid pp-dereverb-decay value: %s\n", value); } } else if (!strcasecmp("pp-dereverb-level", name)) { /* reverberation removal level, float */ float tmp = atof(value); if (switch_is_number(value) && tmp >= 0.0f) { default_codec_settings.pp_dereverb_level = tmp; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ignoring invalid pp-dereverb-level value: %s\n", value); } } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ignoring invalid unknown param: %s = %s\n", name, value); } } } switch_xml_free(xml); } }
static switch_status_t load_config(switch_memory_pool_t *pool) { switch_status_t status = SWITCH_STATUS_SUCCESS; char *cf = "cdr_pg_csv.conf", *ptr; switch_xml_t cfg, xml, schema, field; const char *attr; int num_fields = 0; switch_size_t len = 0; cdr_field_t *cdr_field; if (globals.db_online) { PQfinish(globals.db_connection); switch_mutex_destroy(globals.db_mutex); globals.db_online = 0; } memset(&globals, 0, sizeof(globals)); switch_core_hash_init(&globals.fd_hash, pool); switch_mutex_init(&globals.db_mutex, SWITCH_MUTEX_NESTED, pool); globals.pool = pool; if (switch_xml_config_parse_module_settings(cf, SWITCH_FALSE, config_settings) != SWITCH_STATUS_SUCCESS) { return SWITCH_STATUS_FALSE; } if ((xml = switch_xml_open_cfg(cf, &cfg, NULL))) { if ((schema = switch_xml_child(cfg, "schema"))) { /* Count fields in schema so we can calculate required buffer size */ for (field = switch_xml_child(schema, "field"); field; field = field->next) { if (switch_xml_attr(field, "var")) { num_fields++; } } globals.db_schema = switch_core_alloc(pool, (num_fields + 1) * sizeof(cdr_field_t)); cdr_field = globals.db_schema->fields; for (field = switch_xml_child(schema, "field"); field; field = field->next) { if ((attr = switch_xml_attr(field, "var"))) { cdr_field->var_name = switch_core_strdup(pool, attr); /* Assume SQL column name is the same as FreeSWITCH channel var name, unless specified otherwise */ if ((attr = switch_xml_attr(field, "column"))) { cdr_field->col_name = switch_core_strdup(pool, attr); } else { cdr_field->col_name = switch_core_strdup(pool, cdr_field->var_name); } /* Assume all fields should be quoted (treated as strings), unless specified otherwise */ if ((attr = switch_xml_attr(field, "quote")) && !strncmp(attr, "false", 5)) { cdr_field->quote = SWITCH_FALSE; } else { cdr_field->quote = SWITCH_TRUE; } /* Assume all fields allow SQL nulls, unless specified otherwise */ if ((attr = switch_xml_attr(field, "not-null")) && !strncmp(attr, "true", 4)) { cdr_field->not_null = SWITCH_TRUE; } else { cdr_field->not_null = SWITCH_FALSE; } len += strlen(cdr_field->col_name) + 1; cdr_field++; } } cdr_field->var_name = 0; globals.db_schema->columns = switch_core_alloc(pool, len); ptr = globals.db_schema->columns; for (cdr_field = globals.db_schema->fields; cdr_field->col_name; cdr_field++) { len = strlen(cdr_field->col_name); memcpy(ptr, cdr_field->col_name, len); ptr += len; *ptr = ','; ptr++; } *--ptr = '\0'; } switch_xml_free(xml); } return status; }
switch_status_t mod_xml_radius_add_params(switch_core_session_t *session, switch_event_t *params, rc_handle *handle, VALUE_PAIR **send, switch_xml_t fields) { switch_xml_t param; void *av_value = NULL; if ( (param = switch_xml_child(fields, "param")) == NULL) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to locate a param under the fields section\n"); goto err; } for (; param; param = param->next) { DICT_ATTR *attribute = NULL; DICT_VENDOR *vendor = NULL; int attr_num = 0, vend_num = 0; char *var = (char *) switch_xml_attr(param, "name"); char *vend = (char *) switch_xml_attr(param, "vendor"); char *variable = (char *) switch_xml_attr(param, "variable"); char *variable_secondary = (char *) switch_xml_attr(param, "variable_secondary"); char *val_default = (char *) switch_xml_attr(param, "default"); char *format = (char *) switch_xml_attr(param, "format"); char *other_leg = (char *) switch_xml_attr(param, "other_leg"); attribute = rc_dict_findattr(handle, var); if ( attribute == NULL ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: Could not locate attribute '%s' in the configured dictionary\n", var); goto err; } if ( GLOBAL_DEBUG ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: dict attr '%s' value '%d' type '%d'\n", attribute->name, attribute->value, attribute->type); } attr_num = attribute->value; if ( vend ) { vendor = rc_dict_findvend(handle, vend); if ( vendor == NULL ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: Could not locate vendor '%s' in the configured dictionary %p\n", vend, vend); goto err; } if ( GLOBAL_DEBUG ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: dict vend name '%s' vendorpec '%d'\n", vendor->vendorname, vendor->vendorpec); } vend_num = vendor->vendorpec; } if ( var ) { if ( session ) { switch_channel_t *channel = switch_core_session_get_channel(session); /* Accounting only */ if ( strncmp( var, "h323-setup-time", 15) == 0 ) { switch_caller_profile_t *profile = switch_channel_get_caller_profile(channel); switch_time_t time = profile->times->created; switch_time_exp_t tm; if ( !time ) { goto end_loop; } switch_time_exp_lt(&tm, time); if ( GLOBAL_TIME_FORMAT == 1 ) { av_value = switch_mprintf("%02u:%02u:%02u.%03u %s %s %s %02u %04u", tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec/1000, GLOBAL_TIME_ZONE, radattrdays[tm.tm_wday], radattrmonths[tm.tm_mon], tm.tm_mday, tm.tm_year + 1900); } else { av_value = switch_mprintf("%04u-%02u-%02uT%02u:%02u:%02u.%06u%+03d%02d", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec, tm.tm_gmtoff / 3600, tm.tm_gmtoff % 3600); } if (rc_avpair_add(handle, send, attr_num, av_value, -1, vend_num) == NULL) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: failed to add option to handle\n"); goto err; } if ( GLOBAL_DEBUG ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: value: %s\n", (char *) av_value); } } else if ( strncmp( var, "h323-connect-time", 17) == 0 ) { switch_caller_profile_t *profile = switch_channel_get_caller_profile(channel); switch_time_t time = profile->times->answered; switch_time_exp_t tm; if ( !time ) { goto end_loop; } switch_time_exp_lt(&tm, time); if ( GLOBAL_TIME_FORMAT == 1 ) { av_value = switch_mprintf("%02u:%02u:%02u.%03u %s %s %s %02u %04u", tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec/1000, GLOBAL_TIME_ZONE, radattrdays[tm.tm_wday], radattrmonths[tm.tm_mon], tm.tm_mday, tm.tm_year + 1900); } else { av_value = switch_mprintf("%04u-%02u-%02uT%02u:%02u:%02u.%06u%+03d%02d", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec, tm.tm_gmtoff / 3600, tm.tm_gmtoff % 3600); } if (rc_avpair_add(handle, send, attr_num, av_value, -1, vend_num) == NULL) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: failed to add option to handle\n"); goto err; } if ( GLOBAL_DEBUG ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: value: %s\n", (char *) av_value); } } else if ( strncmp( var, "h323-disconnect-time", 20) == 0 ) { switch_caller_profile_t *profile = switch_channel_get_caller_profile(channel); switch_time_t time = profile->times->hungup; switch_time_exp_t tm; if ( !time ) { if ( variable_secondary != NULL && strncmp(variable_secondary, "now", 3) == 0 ) { time = switch_time_now(); } else { goto end_loop; } } switch_time_exp_lt(&tm, time); if ( GLOBAL_TIME_FORMAT == 1 ) { av_value = switch_mprintf("%02u:%02u:%02u.%03u %s %s %s %02u %04u", tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec/1000, GLOBAL_TIME_FORMAT, radattrdays[tm.tm_wday], radattrmonths[tm.tm_mon], tm.tm_mday, tm.tm_year + 1900); } else { av_value = switch_mprintf("%04u-%02u-%02uT%02u:%02u:%02u.%06u%+03d%02d", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec, tm.tm_gmtoff / 3600, tm.tm_gmtoff % 3600); } if (rc_avpair_add(handle, send, attr_num, av_value, -1, vend_num) == NULL) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: failed to add option to handle\n"); goto err; } if ( GLOBAL_DEBUG ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: value: %s\n", (char *) av_value); } } else if ( strncmp( var, "h323-disconnect-cause", 21) == 0 ) { switch_call_cause_t cause = switch_channel_get_cause(channel); av_value = switch_mprintf("h323-disconnect-cause=%x", cause); if (rc_avpair_add(handle, send, 30, av_value, -1, 9) == NULL) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: failed to add disconnect cause \n"); goto err; } } else { if ( format == NULL ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing format attribute for %s variable\n", variable); goto err; } if ( attribute->type == 0 ) { const char *val = NULL; if ( other_leg ) { val = switch_channel_get_variable_partner(channel, variable); if ( val == NULL && variable_secondary != NULL) { val = switch_channel_get_variable_partner(channel, variable_secondary); } } else { val = switch_channel_get_variable(channel, variable); if ( val == NULL && variable_secondary != NULL) { val = switch_channel_get_variable(channel, variable_secondary); } } if ( val == NULL && val_default != NULL) { av_value = switch_mprintf(format, val_default); } else { av_value = switch_mprintf(format, val); } if ( GLOBAL_DEBUG ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: value: %s\n", (char *) av_value); } if (rc_avpair_add(handle, send, attr_num, av_value, -1, vend_num) == NULL) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: failed to add option with val '%s' to handle\n", (char *) av_value); goto err; } } else if ( attribute->type == 1 ) { int number = atoi(switch_channel_get_variable(channel, variable)); if (rc_avpair_add(handle, send, attr_num, &number, -1, vend_num) == NULL) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: failed to add option with value '%d' to handle\n", number); goto err; } } } } else if ( params ) { /* Auth only */ char *tmp = switch_event_get_header(params, variable); if ( GLOBAL_DEBUG ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: param var '%s' val: %s\n", variable, tmp); } if ( tmp == NULL ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: Unable to locate '%s' on the event\n", variable); goto err; } av_value = switch_mprintf(format, tmp); if (rc_avpair_add(handle, send, attr_num, av_value, -1, vend_num) == NULL) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: failed to add option to handle\n"); goto err; } } else { goto err; } } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: all params must have a name attribute\n"); goto err; } end_loop: if ( av_value != NULL ) { free(av_value); av_value = NULL; } } return SWITCH_STATUS_SUCCESS; err: if ( av_value != NULL ) { free(av_value); av_value = NULL; } return SWITCH_STATUS_GENERR; }
static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *caller_profile, switch_xml_t xexten, switch_caller_extension_t **extension, const char *exten_name, int recur) { switch_xml_t xcond, xaction, xexpression, xregex; switch_channel_t *channel = switch_core_session_get_channel(session); int proceed = 0, save_proceed = 0; char *expression_expanded = NULL, *field_expanded = NULL; switch_regex_t *re = NULL, *save_re = NULL; int offset = 0; const char *tmp, *tzoff = NULL, *tzname = NULL, *req_nesta = NULL; char nbuf[128] = ""; int req_nest = 1; char space[MAX_RECUR_SPACE] = ""; const char *orig_exten_name = exten_name; check_tz(); if (!exten_name) { exten_name = "_anon_"; } if (!orig_exten_name) { orig_exten_name = "_anon_"; } if (recur) { int i, j = 0, k = 0; if (recur > MAX_RECUR) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Recursion LIMIT!\n"); return 0; } switch_snprintf(nbuf, sizeof(nbuf), "%s_recur_%d", exten_name, recur); exten_name = nbuf; space[j++] = '|'; for (i = 0; i < recur; i++) { for (k = 0; k < RECUR_SPACE; k++) { if (i == recur-1 && k == RECUR_SPACE-1) { space[j++] = ' '; } else { space[j++] = '-'; } } } if ((req_nesta = switch_xml_attr(xexten, "require-nested"))) { req_nest = switch_true(req_nesta); } switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG, "%sDialplan: Processing recursive conditions level:%d [%s] require-nested=%s\n", space, recur, exten_name, req_nest ? "TRUE" : "FALSE"); } else { if ((tmp = switch_xml_attr(xexten, "name"))) { exten_name = tmp; } } for (xcond = switch_xml_child(xexten, "condition"); xcond; xcond = xcond->next) { char *field = NULL; char *do_break_a = NULL; char *expression = NULL, *save_expression = NULL, *save_field_data = NULL; char *regex_rule = NULL; const char *field_data = NULL; int ovector[30]; switch_bool_t anti_action = SWITCH_TRUE; break_t do_break_i = BREAK_ON_FALSE; int time_match; check_tz(); time_match = switch_xml_std_datetime_check(xcond, tzoff ? &offset : NULL, tzname); switch_safe_free(field_expanded); switch_safe_free(expression_expanded); field = (char *) switch_xml_attr(xcond, "field"); if ((do_break_a = (char *) switch_xml_attr(xcond, "break"))) { if (!strcasecmp(do_break_a, "on-true")) { do_break_i = BREAK_ON_TRUE; } else if (!strcasecmp(do_break_a, "on-false")) { do_break_i = BREAK_ON_FALSE; } else if (!strcasecmp(do_break_a, "always")) { do_break_i = BREAK_ALWAYS; } else if (!strcasecmp(do_break_a, "never")) { do_break_i = BREAK_NEVER; } else { do_break_a = NULL; } } if (switch_xml_child(xcond, "condition")) { if (!(proceed = parse_exten(session, caller_profile, xcond, extension, orig_exten_name, recur + 1))) { if (do_break_i == BREAK_NEVER) { continue; } goto done; } } if (time_match == 1) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG, "%sDialplan: %s Date/Time Match (PASS) [%s] break=%s\n", space, switch_channel_get_name(channel), exten_name, do_break_a ? do_break_a : "on-false"); anti_action = SWITCH_FALSE; proceed = 1; } else if (time_match == 0) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG, "%sDialplan: %s Date/TimeMatch (FAIL) [%s] break=%s\n", space, switch_channel_get_name(channel), exten_name, do_break_a ? do_break_a : "on-false"); } if ((regex_rule = (char *) switch_xml_attr(xcond, "regex"))) { int all = !strcasecmp(regex_rule, "all"); int xor = !strcasecmp(regex_rule, "xor"); int pass = 0; int fail = 0; int total = 0; switch_channel_del_variable_prefix(channel, "DP_REGEX_MATCH"); for (xregex = switch_xml_child(xcond, "regex"); xregex; xregex = xregex->next) { check_tz(); time_match = switch_xml_std_datetime_check(xregex, tzoff ? &offset : NULL, tzname); if (time_match == 1) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG, "%sDialplan: %s Date/Time Match (PASS) [%s]\n", space, switch_channel_get_name(channel), exten_name); anti_action = SWITCH_FALSE; } else if (time_match == 0) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG, "%sDialplan: %s Date/TimeMatch (FAIL) [%s]\n", space, switch_channel_get_name(channel), exten_name); } if ((xexpression = switch_xml_child(xregex, "expression"))) { expression = switch_str_nil(xexpression->txt); } else { expression = (char *) switch_xml_attr_soft(xregex, "expression"); } if ((expression_expanded = switch_channel_expand_variables(channel, expression)) == expression) { expression_expanded = NULL; } else { expression = expression_expanded; } total++; field = (char *) switch_xml_attr(xregex, "field"); if (field) { if (strchr(field, '$')) { if ((field_expanded = switch_channel_expand_variables(channel, field)) == field) { field_expanded = NULL; field_data = field; } else { field_data = field_expanded; } } else { field_data = switch_caller_get_field_by_name(caller_profile, field); } if (!field_data) { field_data = ""; } if ((proceed = switch_regex_perform(field_data, expression, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG, "%sDialplan: %s Regex (PASS) [%s] %s(%s) =~ /%s/ match=%s\n", space, switch_channel_get_name(channel), exten_name, field, field_data, expression, all ? "all" : "any"); pass++; if (!all && !xor) break; } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG, "%sDialplan: %s Regex (FAIL) [%s] %s(%s) =~ /%s/ match=%s\n", space, switch_channel_get_name(channel), exten_name, field, field_data, expression, all ? "all" : "any"); fail++; if (all && !xor) break; } } else if (time_match == -1) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG, "%sDialplan: %s Absolute Condition [%s] match=%s\n", space, switch_channel_get_name(channel), exten_name, all ? "all" : "any"); pass++; proceed = 1; if (!all && !xor) break; } else if (time_match == 1) { pass++; proceed = 1; if (!all && !xor) break; } if (field && strchr(expression, '(')) { char var[256]; switch_snprintf(var, sizeof(var), "DP_REGEX_MATCH_%d", total); switch_channel_set_variable(channel, var, NULL); switch_capture_regex(re, proceed, field_data, ovector, var, switch_regex_set_var_callback, session); switch_safe_free(save_expression); switch_safe_free(save_field_data); switch_regex_safe_free(save_re); save_expression = strdup(expression); save_field_data = strdup(field_data); save_re = re; save_proceed = proceed; re = NULL; } switch_regex_safe_free(re); switch_safe_free(field_expanded); switch_safe_free(expression_expanded); } if (xor) { if (pass == 1) { anti_action = SWITCH_FALSE; } } else { if ((all && !fail) || (!all && pass)) { anti_action = SWITCH_FALSE; } } switch_safe_free(field_expanded); switch_safe_free(expression_expanded); } else { if ((xexpression = switch_xml_child(xcond, "expression"))) { expression = switch_str_nil(xexpression->txt); } else { expression = (char *) switch_xml_attr_soft(xcond, "expression"); } if ((expression_expanded = switch_channel_expand_variables(channel, expression)) == expression) { expression_expanded = NULL; } else { expression = expression_expanded; } if (field) { if (strchr(field, '$')) { if ((field_expanded = switch_channel_expand_variables(channel, field)) == field) { field_expanded = NULL; field_data = field; } else { field_data = field_expanded; } } else { field_data = switch_caller_get_field_by_name(caller_profile, field); } if (!field_data) { field_data = ""; } if ((proceed = switch_regex_perform(field_data, expression, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG, "%sDialplan: %s Regex (PASS) [%s] %s(%s) =~ /%s/ break=%s\n", space, switch_channel_get_name(channel), exten_name, field, field_data, expression, do_break_a ? do_break_a : "on-false"); anti_action = SWITCH_FALSE; } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG, "%sDialplan: %s Regex (FAIL) [%s] %s(%s) =~ /%s/ break=%s\n", space, switch_channel_get_name(channel), exten_name, field, field_data, expression, do_break_a ? do_break_a : "on-false"); } } else if (time_match == -1) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG, "%sDialplan: %s Absolute Condition [%s]\n", space, switch_channel_get_name(channel), exten_name); anti_action = SWITCH_FALSE; proceed = 1; } } if (save_re) { re = save_re; save_re = NULL; expression = expression_expanded = save_expression; save_expression = NULL; field_data = field_expanded = save_field_data; field = (char *) field_data; save_field_data = NULL; proceed = save_proceed; } if (anti_action) { for (xaction = switch_xml_child(xcond, "anti-action"); xaction; xaction = xaction->next) { const char *application = switch_xml_attr_soft(xaction, "application"); const char *loop = switch_xml_attr(xaction, "loop"); const char *data; const char *inline_ = switch_xml_attr_soft(xaction, "inline"); int xinline = switch_true(inline_); int loop_count = 1; if (!zstr(xaction->txt)) { data = xaction->txt; } else { data = (char *) switch_xml_attr_soft(xaction, "data"); } if (!*extension) { if ((*extension = switch_caller_extension_new(session, exten_name, caller_profile->destination_number)) == 0) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Memory Error!\n"); proceed = 0; goto done; } } if (loop) { loop_count = atoi(loop); } for (;loop_count > 0; loop_count--) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG, "%sDialplan: %s ANTI-Action %s(%s) %s\n", space, switch_channel_get_name(channel), application, data, xinline ? "INLINE" : ""); if (xinline) { exec_app(session, application, data); } else { switch_caller_extension_add_application(session, *extension, application, data); } } proceed = 1; } } else { if (field && strchr(expression, '(')) { switch_channel_set_variable(channel, "DP_MATCH", NULL); switch_capture_regex(re, proceed, field_data, ovector, "DP_MATCH", switch_regex_set_var_callback, session); } for (xaction = switch_xml_child(xcond, "action"); xaction; xaction = xaction->next) { char *application = (char *) switch_xml_attr_soft(xaction, "application"); const char *loop = switch_xml_attr(xaction, "loop"); char *data = NULL; char *substituted = NULL; uint32_t len = 0; char *app_data = NULL; const char *inline_ = switch_xml_attr_soft(xaction, "inline"); int xinline = switch_true(inline_); int loop_count = 1; if (!zstr(xaction->txt)) { data = xaction->txt; } else { data = (char *) switch_xml_attr_soft(xaction, "data"); } if (field && strchr(expression, '(')) { len = (uint32_t) (strlen(data) + strlen(field_data) + 10) * proceed; if (!(substituted = malloc(len))) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Memory Error!\n"); proceed = 0; goto done; } memset(substituted, 0, len); switch_perform_substitution(re, proceed, data, field_data, substituted, len, ovector); app_data = substituted; } else { app_data = data; } if (!*extension) { if ((*extension = switch_caller_extension_new(session, exten_name, caller_profile->destination_number)) == 0) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Memory Error!\n"); proceed = 0; goto done; } } if (loop) { loop_count = atoi(loop); } for (;loop_count > 0; loop_count--) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG, "%sDialplan: %s Action %s(%s) %s\n", space, switch_channel_get_name(channel), application, app_data, xinline ? "INLINE" : ""); if (xinline) { exec_app(session, application, app_data); } else { switch_caller_extension_add_application(session, *extension, application, app_data); } } switch_safe_free(substituted); } } switch_regex_safe_free(re); if (((anti_action == SWITCH_FALSE && do_break_i == BREAK_ON_TRUE) || (anti_action == SWITCH_TRUE && do_break_i == BREAK_ON_FALSE)) || do_break_i == BREAK_ALWAYS) { break; } } done: switch_regex_safe_free(re); switch_safe_free(field_expanded); switch_safe_free(expression_expanded); if (!req_nest) proceed = 1; return proceed; }
static int parse_exten(switch_event_t *event, switch_xml_t xexten, switch_event_t **extension) { switch_xml_t xcond, xaction, xexpression; char *exten_name = (char *) switch_xml_attr(xexten, "name"); int proceed = 0; char *expression_expanded = NULL, *field_expanded = NULL; switch_regex_t *re = NULL; const char *to = switch_event_get_header(event, "to"); const char *tzoff = NULL, *tzname = NULL; int offset = 0; check_tz(); if (!to) { to = "nobody"; } if (!exten_name) { exten_name = "_anon_"; } for (xcond = switch_xml_child(xexten, "condition"); xcond; xcond = xcond->next) { char *field = NULL; char *do_break_a = NULL; char *expression = NULL; const char *field_data = NULL; int ovector[30]; switch_bool_t anti_action = SWITCH_TRUE; break_t do_break_i = BREAK_ON_FALSE; int time_match; check_tz(); time_match = switch_xml_std_datetime_check(xcond, tzoff ? &offset : NULL, tzname); switch_safe_free(field_expanded); switch_safe_free(expression_expanded); if (switch_xml_child(xcond, "condition")) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Nested conditions are not allowed!\n"); proceed = 1; goto done; } field = (char *) switch_xml_attr(xcond, "field"); if ((xexpression = switch_xml_child(xcond, "expression"))) { expression = switch_str_nil(xexpression->txt); } else { expression = (char *) switch_xml_attr_soft(xcond, "expression"); } if ((expression_expanded = switch_event_expand_headers(event, expression)) == expression) { expression_expanded = NULL; } else { expression = expression_expanded; } if ((do_break_a = (char *) switch_xml_attr(xcond, "break"))) { if (!strcasecmp(do_break_a, "on-true")) { do_break_i = BREAK_ON_TRUE; } else if (!strcasecmp(do_break_a, "on-false")) { do_break_i = BREAK_ON_FALSE; } else if (!strcasecmp(do_break_a, "always")) { do_break_i = BREAK_ALWAYS; } else if (!strcasecmp(do_break_a, "never")) { do_break_i = BREAK_NEVER; } else { do_break_a = NULL; } } if (time_match == 1) { switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "Chatplan: %s Date/Time Match (PASS) [%s] break=%s\n", to, exten_name, do_break_a ? do_break_a : "on-false"); anti_action = SWITCH_FALSE; } else if (time_match == 0) { switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "Chatplan: %s Date/Time Match (FAIL) [%s] break=%s\n", to, exten_name, do_break_a ? do_break_a : "on-false"); } if (field) { if (strchr(field, '$')) { if ((field_expanded = switch_event_expand_headers(event, field)) == field) { field_expanded = NULL; field_data = field; } else { field_data = field_expanded; } } else { field_data = switch_event_get_header(event, field); } if (!field_data) { field_data = ""; } if ((proceed = switch_regex_perform(field_data, expression, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) { switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "Chatplan: %s Regex (PASS) [%s] %s(%s) =~ /%s/ break=%s\n", to, exten_name, field, field_data, expression, do_break_a ? do_break_a : "on-false"); anti_action = SWITCH_FALSE; } else { switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "Chatplan: %s Regex (FAIL) [%s] %s(%s) =~ /%s/ break=%s\n", to, exten_name, field, field_data, expression, do_break_a ? do_break_a : "on-false"); } } else if (time_match == -1) { switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "Chatplan: %s Absolute Condition [%s]\n", to, exten_name); anti_action = SWITCH_FALSE; } if (anti_action) { for (xaction = switch_xml_child(xcond, "anti-action"); xaction; xaction = xaction->next) { const char *application = switch_xml_attr_soft(xaction, "application"); const char *loop = switch_xml_attr(xaction, "loop"); const char *data; const char *inline_ = switch_xml_attr_soft(xaction, "inline"); int xinline = switch_true(inline_); int loop_count = 1; if (!zstr(xaction->txt)) { data = xaction->txt; } else { data = (char *) switch_xml_attr_soft(xaction, "data"); } if (!*extension) { if ((switch_event_create(extension, SWITCH_EVENT_CLONE)) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n"); abort(); } } if (loop) { loop_count = atoi(loop); } for (;loop_count > 0; loop_count--) { switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "Chatplan: %s ANTI-Action %s(%s) %s\n", to, application, data, xinline ? "INLINE" : ""); if (xinline) { switch_core_execute_chat_app(event, application, data); } else { switch_event_add_header_string(*extension, SWITCH_STACK_BOTTOM, application, zstr(data) ? "__undef" : data); } } proceed = 1; } } else { if (field && strchr(expression, '(')) { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "DP_MATCH", NULL); switch_capture_regex(re, proceed, field_data, ovector, "DP_MATCH", switch_regex_set_event_header_callback, event); } for (xaction = switch_xml_child(xcond, "action"); xaction; xaction = xaction->next) { char *application = (char *) switch_xml_attr_soft(xaction, "application"); const char *loop = switch_xml_attr(xaction, "loop"); char *data = NULL; char *substituted = NULL; uint32_t len = 0; char *app_data = NULL; const char *inline_ = switch_xml_attr_soft(xaction, "inline"); int xinline = switch_true(inline_); int loop_count = 1; if (!zstr(xaction->txt)) { data = xaction->txt; } else { data = (char *) switch_xml_attr_soft(xaction, "data"); } if (field && strchr(expression, '(')) { len = (uint32_t) (strlen(data) + strlen(field_data) + 10) * proceed; if (!(substituted = (char *) malloc(len))) { abort(); } memset(substituted, 0, len); switch_perform_substitution(re, proceed, data, field_data, substituted, len, ovector); app_data = substituted; } else { app_data = data; } if (!*extension) { if ((switch_event_create(extension, SWITCH_EVENT_CLONE)) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n"); abort(); } } if (loop) { loop_count = atoi(loop); } for (;loop_count > 0; loop_count--) { switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "Chatplan: %s Action %s(%s) %s\n", to, application, app_data, xinline ? "INLINE" : ""); if (xinline) { switch_core_execute_chat_app(event, application, app_data); } else { switch_event_add_header_string(*extension, SWITCH_STACK_BOTTOM, application, zstr(app_data) ? "__undef" : app_data); } } switch_safe_free(substituted); } } switch_regex_safe_free(re); if (((anti_action == SWITCH_FALSE && do_break_i == BREAK_ON_TRUE) || (anti_action == SWITCH_TRUE && do_break_i == BREAK_ON_FALSE)) || do_break_i == BREAK_ALWAYS) { break; } } done: switch_regex_safe_free(re); switch_safe_free(field_expanded); switch_safe_free(expression_expanded); return proceed; }
static switch_event_t *chatplan_hunt(switch_event_t *event) { switch_event_t *extension = NULL; switch_xml_t alt_root = NULL, cfg, xml = NULL, xcontext, xexten = NULL; const char *alt_path; const char *context; const char *from; const char *to; if (!(context = switch_event_get_header(event, "context"))) { context = "default"; } if (!(from = switch_event_get_header(event, "from_user"))) { from = switch_event_get_header(event, "from"); } if (!(to = switch_event_get_header(event, "to_user"))) { to = switch_event_get_header(event, "to"); } alt_path = switch_event_get_header(event, "alt_path"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Processing text message %s->%s in context %s\n", from, to, context); /* get our handle to the "chatplan" section of the config */ if (!zstr(alt_path)) { switch_xml_t conf = NULL, tag = NULL; if (!(alt_root = switch_xml_parse_file_simple(alt_path))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of [%s] failed\n", alt_path); goto done; } if ((conf = switch_xml_find_child(alt_root, "section", "name", "chatplan")) && (tag = switch_xml_find_child(conf, "chatplan", NULL, NULL))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Getting chatplan from alternate path: %s\n", alt_path); xml = alt_root; cfg = tag; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of chatplan failed\n"); goto done; } } else { if (switch_xml_locate("chatplan", NULL, NULL, NULL, &xml, &cfg, event, SWITCH_FALSE) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of chatplan failed\n"); goto done; } } /* get a handle to the context tag */ if (!(xcontext = switch_xml_find_child(cfg, "context", "name", context))) { if (!(xcontext = switch_xml_find_child(cfg, "context", "name", "global"))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Context %s not found\n", context); goto done; } } xexten = switch_xml_child(xcontext, "extension"); while (xexten) { int proceed = 0; const char *cont = switch_xml_attr(xexten, "continue"); const char *exten_name = switch_xml_attr(xexten, "name"); if (!exten_name) { exten_name = "UNKNOWN"; } switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "Chatplan: %s parsing [%s->%s] continue=%s\n", to, context, exten_name, cont ? cont : "false"); proceed = parse_exten(event, xexten, &extension); if (proceed && !switch_true(cont)) { break; } xexten = xexten->next; } switch_xml_free(xml); xml = NULL; done: switch_xml_free(xml); return extension; }
static abyss_bool user_attributes(const char *user, const char *domain_name, const char **ppasswd, const char **pvm_passwd, const char **palias, const char **pallowed_commands) { const char *passwd; const char *vm_passwd; const char *alias; const char *allowed_commands; switch_event_t *params; switch_xml_t x_user, x_params, x_param; passwd = NULL; vm_passwd = NULL; alias = NULL; allowed_commands = NULL; if (ppasswd) *ppasswd = NULL; if (pvm_passwd) *pvm_passwd = NULL; if (palias) *palias = NULL; if (pallowed_commands) *pallowed_commands = NULL; params = NULL; switch_event_create(¶ms, SWITCH_EVENT_REQUEST_PARAMS); switch_assert(params); switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "number_alias", "check"); if (switch_xml_locate_user_merged("id", user, domain_name, NULL, &x_user, params) != SWITCH_STATUS_SUCCESS) { switch_event_destroy(¶ms); return FALSE; } switch_event_destroy(¶ms); alias = switch_xml_attr(x_user, "number-alias"); if ((x_params = switch_xml_child(x_user, "params"))) { for (x_param = switch_xml_child(x_params, "param"); x_param; x_param = x_param->next) { const char *var = switch_xml_attr_soft(x_param, "name"); const char *val = switch_xml_attr_soft(x_param, "value"); if (!strcasecmp(var, "password")) { passwd = val; } else if (!strcasecmp(var, "vm-password")) { vm_passwd = val; } else if (!strcasecmp(var, "http-allowed-api")) { allowed_commands = val; } } } if (ppasswd && passwd) { *ppasswd = strdup(passwd); } if (pvm_passwd && vm_passwd) { *pvm_passwd = strdup(vm_passwd); } if (palias && alias) { *palias = strdup(alias); } if (pallowed_commands && allowed_commands) { *pallowed_commands = strdup(allowed_commands); } if (x_user) { switch_xml_free(x_user); } return TRUE; }