static switch_status_t opus_load_config(switch_bool_t reload) { char *cf = "opus.conf"; switch_xml_t cfg, xml = NULL, param, settings; switch_status_t status = SWITCH_STATUS_SUCCESS; if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Opening of %s failed\n", cf); return status; } if ((settings = switch_xml_child(cfg, "settings"))) { for (param = switch_xml_child(settings, "param"); param; param = param->next) { char *key = (char *) switch_xml_attr_soft(param, "name"); char *val = (char *) switch_xml_attr_soft(param, "value"); if (!strcasecmp(key, "use-vbr") && !zstr(val)) { opus_prefs.use_vbr = atoi(val); } else if (!strcasecmp(key, "complexity")) { opus_prefs.complexity = atoi(val); } else if (!strcasecmp(key, "maxaveragebitrate")) { opus_prefs.maxaveragebitrate = atoi(val); if ( opus_prefs.maxaveragebitrate < 6000 || opus_prefs.maxaveragebitrate > 510000 ) { opus_prefs.maxaveragebitrate = 0; /* values outside the range between 6000 and 510000 SHOULD be ignored */ } } else if (!strcasecmp(key, "maxplaybackrate")) { opus_prefs.maxplaybackrate = atoi(val); if ( opus_prefs.maxplaybackrate != 8000 && opus_prefs.maxplaybackrate != 12000 && opus_prefs.maxplaybackrate != 16000 && opus_prefs.maxplaybackrate != 24000 && opus_prefs.maxplaybackrate != 48000) { opus_prefs.maxplaybackrate = 0; /* value not supported */ } } } } if (xml) { switch_xml_free(xml); } return status; }
switch_status_t initialise_ei(struct ei_cnode_s *ec) { char thisnodename[MAXNODELEN + 1]; char thisalivename[MAXNODELEN + 1]; char *atsign; if (zstr(listen_list.hostname) || !strncasecmp(prefs.ip, "0.0.0.0", 7) || !strncasecmp(prefs.ip, "::", 2)) { listen_list.hostname=(char *) switch_core_get_hostname(); } if (strlen(listen_list.hostname) > EI_MAXHOSTNAMELEN) { *(listen_list.hostname+EI_MAXHOSTNAMELEN) = '\0'; } /* copy the prefs.nodename into something we can modify */ strncpy(thisalivename, prefs.nodename, MAXNODELEN); if ((atsign = strchr(thisalivename, '@'))) { /* we got a qualified node name, don't guess the host/domain */ snprintf(thisnodename, MAXNODELEN + 1, "%s", prefs.nodename); /* truncate the alivename at the @ */ *atsign = '\0'; } else { if (prefs.shortname) { char *off; if ((off = strchr(listen_list.hostname, '.'))) { *off = '\0'; } } snprintf(thisnodename, MAXNODELEN + 1, "%s@%s", prefs.nodename, listen_list.hostname); } /* init the ei stuff */ if (ei_connect_xinit(ec, listen_list.hostname, thisalivename, thisnodename, (Erl_IpAddr) listen_list.addr, prefs.cookie, 0) < 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to init ei connection\n"); return SWITCH_STATUS_FALSE; } return SWITCH_STATUS_SUCCESS; }
static switch_status_t config_callback_dsn(switch_xml_config_item_t *data, const char *newvalue, switch_config_callback_type_t callback_type, switch_bool_t changed) { switch_status_t status = SWITCH_STATUS_SUCCESS; switch_cache_db_handle_t *dbh = NULL; if (!switch_odbc_available()) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ODBC is not compiled in. Do not configure odbc-dsn parameter!\n"); return SWITCH_STATUS_FALSE; } if ((callback_type == CONFIG_LOAD || callback_type == CONFIG_RELOAD) && changed) { if (zstr(newvalue)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "No local database defined.\n"); } else { switch_safe_free(globals.odbc_dsn); globals.odbc_dsn = strdup(newvalue); if ((globals.odbc_user = strchr(globals.odbc_dsn, ':'))) { *globals.odbc_user++ = '\0'; if ((globals.odbc_pass = strchr(globals.odbc_user, ':'))) { *globals.odbc_pass++ = '\0'; } } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connecting to dsn: %s\n", globals.odbc_dsn); if (!(dbh = cidlookup_get_db_handle())) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot Open ODBC Database!\n"); switch_goto_status(SWITCH_STATUS_FALSE, done); } } } switch_goto_status(SWITCH_STATUS_SUCCESS, done); done: switch_cache_db_release_db_handle(&dbh); return status; }
SWITCH_DECLARE_CONSTRUCTOR Event::Event(const char *type, const char *subclass_name) { switch_event_types_t event_id; if (switch_name_event(type, &event_id) != SWITCH_STATUS_SUCCESS) { event_id = SWITCH_EVENT_MESSAGE; } if (!zstr(subclass_name) && event_id != SWITCH_EVENT_CUSTOM) { switch_log_printf(SWITCH_CHANNEL_LOG,SWITCH_LOG_WARNING, "Changing event type to custom because you specified a subclass name!\n"); event_id = SWITCH_EVENT_CUSTOM; } if (switch_event_create_subclass(&event, event_id, subclass_name) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG,SWITCH_LOG_ERROR, "Failed to create event!\n"); event = NULL; } serialized_string = NULL; mine = 1; }
static switch_status_t say_telephone_number(switch_say_file_handle_t *sh, char *tosay, switch_say_args_t *say_args) { int silence = 0; char *p; for (p = tosay; !zstr(p); p++) { int a = tolower((int) *p); if (a >= '0' && a <= '9') { switch_say_file(sh, "digits/%c", a); silence = 0; } else if (a == '+' || (a >= 'a' && a <= 'z')) { switch_say_file(sh, "ascii/%d", a); silence = 0; } else if (!silence) { switch_say_file(sh, "silence_stream://100"); silence = 1; } } return SWITCH_STATUS_SUCCESS; }
/** * Add a definition for a tag * @param tag the name * @param attribs_fn the function to handle the tag attributes * @param cdata_fn the function to handler the tag CDATA * @param children_tags comma-separated list of valid child tag names * @return the definition */ static struct tag_def *add_tag_def(const char *tag, tag_attribs_fn attribs_fn, tag_cdata_fn cdata_fn, const char *children_tags) { struct tag_def *def = switch_core_alloc(globals.pool, sizeof(*def)); switch_core_hash_init(&def->children_tags, globals.pool); if (!zstr(children_tags)) { char *children_tags_dup = switch_core_strdup(globals.pool, children_tags); char *tags[32] = { 0 }; int tag_count = switch_separate_string(children_tags_dup, ',', tags, sizeof(tags) / sizeof(tags[0])); if (tag_count) { int i; for (i = 0; i < tag_count; i++) { switch_core_hash_insert(def->children_tags, tags[i], tags[i]); } } } def->attribs_fn = attribs_fn; def->cdata_fn = cdata_fn; def->is_root = SWITCH_FALSE; switch_core_hash_insert(globals.tag_defs, tag, def); return def; }
static switch_status_t process_node(const switch_log_node_t *node, switch_log_level_t level) { switch_hash_index_t *hi; void *val; const void *var; logfile_profile_t *profile; for (hi = switch_hash_first(NULL, profile_hash); hi; hi = switch_hash_next(hi)) { size_t mask = 0; size_t ok = 0; switch_hash_this(hi, &var, NULL, &val); profile = val; ok = switch_log_check_mask(profile->all_level, level); if (!ok) { mask = (size_t) switch_core_hash_find(profile->log_hash, node->file); ok = switch_log_check_mask(mask, level); } if (!ok) { mask = (size_t) switch_core_hash_find(profile->log_hash, node->func); ok = switch_log_check_mask(mask, level); } if (ok) { if (profile->log_uuid && !zstr(node->userdata)) { char buf[2048]; switch_snprintf(buf, sizeof(buf), "%s %s", node->userdata, node->data); mod_logfile_raw_write(profile, buf); } else { mod_logfile_raw_write(profile, node->data); } } } return SWITCH_STATUS_SUCCESS; }
switch_cache_db_handle_t *directory_get_db_handle(void) { switch_cache_db_connection_options_t options = { {0} }; switch_cache_db_handle_t *dbh = NULL; if (!zstr(globals.odbc_dsn)) { options.odbc_options.dsn = globals.odbc_dsn; options.odbc_options.user = globals.odbc_user; options.odbc_options.pass = globals.odbc_pass; if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_ODBC, &options) != SWITCH_STATUS_SUCCESS) { dbh = NULL; } return dbh; } else { options.core_db_options.db_path = globals.dbname; if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_CORE_DB, &options) != SWITCH_STATUS_SUCCESS) { dbh = NULL; } return dbh; } }
switch_status_t set_global_facility(const char *facility) { const struct _facility_table_entry facilities[] = { {"auth", LOG_AUTH}, #if !defined (__SVR4) && !defined (__sun) {"authpriv", LOG_AUTHPRIV}, {"ftp", LOG_FTP}, #endif {"cron", LOG_CRON}, {"daemon", LOG_DAEMON}, {"kern", LOG_KERN}, {"local0", LOG_LOCAL0}, {"local1", LOG_LOCAL1}, {"local2", LOG_LOCAL2}, {"local3", LOG_LOCAL3}, {"local4", LOG_LOCAL4}, {"local5", LOG_LOCAL5}, {"local6", LOG_LOCAL6}, {"local7", LOG_LOCAL7}, {"lpr", LOG_LPR}, {"mail", LOG_MAIL}, {"news", LOG_NEWS}, {"syslog", LOG_SYSLOG}, {"user", LOG_USER}, {"uucp", LOG_UUCP}, {NULL, 0} }; const struct _facility_table_entry *entry = facilities; while (!zstr(entry->description)) { if (!strcasecmp(entry->description, facility)) { globals.facility = entry->facility; return SWITCH_STATUS_SUCCESS; } entry++; } return SWITCH_STATUS_FALSE; }
static char *do_db_lookup(switch_memory_pool_t *pool, switch_event_t *event, const char *num, const char *sql) { char *name = NULL; char *newsql = NULL; char *err = NULL; callback_t cbt = { 0 }; cbt.pool = pool; if (!zstr(globals.odbc_dsn)) { newsql = switch_event_expand_headers(event, sql); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "SQL: %s\n", newsql); if (cidlookup_execute_sql_callback(newsql, cidlookup_callback, &cbt, &err)) { name = cbt.name; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to lookup cid: %s\n", err ? err : "(null)"); } } if (newsql != globals.sql) { switch_safe_free(newsql); } return name; }
static switch_call_cause_t sip_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event, switch_caller_profile_t *outbound_profile, switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause) { const char *profile; if (session) { profile = switch_channel_get_variable(switch_core_session_get_channel(session), "sip_profile"); } else { profile = switch_core_get_variable("sip_profile"); } if (zstr(profile)) { profile = "default"; } outbound_profile->destination_number = switch_core_sprintf(outbound_profile->pool, "%s/%s", profile, outbound_profile->destination_number); UNPROTECT_INTERFACE(sip_endpoint_interface); return switch_core_session_outgoing_channel(session, var_event, "sofia", outbound_profile, new_session, pool, SOF_NONE, cancel_cause); }
/** * Process module XML configuration * @param pool memory pool to allocate from * @param config_file to use * @return SWITCH_STATUS_SUCCESS on successful configuration */ static switch_status_t do_config(switch_memory_pool_t *pool, const char *config_file) { switch_xml_t cfg, xml; /* set defaults */ globals.file_prefix = switch_core_sprintf(pool, "%s%s", SWITCH_GLOBAL_dirs.recordings_dir, SWITCH_PATH_SEPARATOR); if (!(xml = switch_xml_open_cfg(config_file, &cfg, NULL))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", config_file); return SWITCH_STATUS_TERM; } /* get params */ { switch_xml_t settings = switch_xml_child(cfg, "fax"); if (settings) { switch_xml_t param; for (param = switch_xml_child(settings, "param"); param; param = param->next) { const char *var = switch_xml_attr_soft(param, "name"); const char *val = switch_xml_attr_soft(param, "value"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "param: %s = %s\n", var, val); if (!strcasecmp(var, "receivefax-file-prefix")) { if (!zstr(val)) { globals.file_prefix = switch_core_strdup(pool, val); } } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unsupported param: %s\n", var); } } } } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "receivefax-file-prefix = %s\n", globals.file_prefix); switch_xml_free(xml); return SWITCH_STATUS_SUCCESS; }
SWITCH_DECLARE(char *) switch_core_perform_strdup(switch_memory_pool_t *pool, const char *todup, const char *file, const char *func, int line) { char *duped = NULL; switch_size_t len; switch_assert(pool != NULL); if (!todup) { return NULL; } if (zstr(todup)) { return SWITCH_BLANK_STRING; } #ifdef LOCK_MORE #ifdef USE_MEM_LOCK switch_mutex_lock(memory_manager.mem_lock); #endif #endif len = strlen(todup) + 1; #ifdef DEBUG_ALLOC if (len > 500) switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "%p Core Strdup Allocate %s %d\n", (void *) pool, apr_pool_tag(pool, NULL), (int)len); #endif duped = apr_pstrmemdup(pool, todup, len); switch_assert(duped != NULL); #ifdef LOCK_MORE #ifdef USE_MEM_LOCK switch_mutex_unlock(memory_manager.mem_lock); #endif #endif return duped; }
static void api_hook(switch_core_session_t *session, const char *hook_var, int use_session) { if (!zstr(hook_var)) { switch_stream_handle_t stream = { 0 }; char *cmd = strdup(hook_var); char *arg = NULL; char *expanded = NULL; if ((arg = strchr(cmd, ':')) && *(arg + 1) == ':') { *arg++ = '\0'; *arg++ = '\0'; } else { if ((arg = strchr(cmd, ' '))) { *arg++ = '\0'; } } SWITCH_STANDARD_STREAM(stream); switch_channel_get_variables(session->channel, &stream.param_event); switch_channel_event_set_data(session->channel, stream.param_event); expanded = switch_event_expand_headers(stream.param_event, arg); switch_api_execute(cmd, expanded, use_session ? session : NULL, &stream); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Hangup Command %s %s(%s):\n%s\n", use_session ? "with Session" : "with no Session", cmd, switch_str_nil(expanded), switch_str_nil((char *) stream.data) ); if (expanded != arg) { switch_safe_free(expanded); } switch_safe_free(cmd); switch_safe_free(stream.data); } }
void conference_data_event_handler(switch_event_t *event) { switch_event_t *revent; char *name = switch_event_get_header(event, "conference-name"); char *domain = switch_event_get_header(event, "conference-domain"); conference_obj_t *conference = NULL; char *body = NULL; if (!zstr(name) && (conference = conference_find(name, domain))) { if (conference_utils_test_flag(conference, CFLAG_RFC4579)) { switch_event_dup(&revent, event); revent->event_id = SWITCH_EVENT_CONFERENCE_DATA; revent->flags |= EF_UNIQ_HEADERS; switch_event_add_header(revent, SWITCH_STACK_TOP, "Event-Name", "CONFERENCE_DATA"); body = conference_cdr_rfc4579_render(conference, event, revent); switch_event_add_body(revent, "%s", body); switch_event_fire(&revent); switch_safe_free(body); } switch_thread_rwlock_unlock(conference->rwlock); } }
switch_status_t utils_recover(char *profile_name) { char arg[128]; switch_stream_handle_t mystream = { 0 }; if (!zstr(profile_name)) { switch_snprintf(arg, sizeof(arg),"profile %s recover",profile_name); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"sofia %s\n", arg); SWITCH_STANDARD_STREAM(mystream); if (switch_api_execute("sofia", arg, NULL, &mystream) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,"cannot recover profile %s\n", profile_name); return SWITCH_STATUS_FALSE; } switch_safe_free(mystream.data); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE,"profile %s recovered\n", profile_name); return SWITCH_STATUS_SUCCESS; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,"Invalid profile name\n"); return SWITCH_STATUS_FALSE; } return SWITCH_STATUS_FALSE; }
static switch_cache_db_handle_t *cidlookup_get_db_handle(void) { switch_cache_db_connection_options_t options = { {0} }; switch_cache_db_handle_t *dbh = NULL; if (!zstr(globals.odbc_dsn)) { char *dsn; if ((dsn = strstr(globals.odbc_dsn, "pgsql;")) != NULL) { options.pgsql_options.dsn = (char*)(dsn + 6); if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_PGSQL, &options) != SWITCH_STATUS_SUCCESS) dbh = NULL; } else { options.odbc_options.dsn = globals.odbc_dsn; options.odbc_options.user = globals.odbc_user; options.odbc_options.pass = globals.odbc_pass; if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_ODBC, &options) != SWITCH_STATUS_SUCCESS) dbh = NULL; } } return dbh; }
SWITCH_DECLARE(int) EventConsumer::bind(const char *event_name, const char *subclass_name) { switch_event_types_t event_id = SWITCH_EVENT_CUSTOM; switch_name_event(event_name, &event_id); if (!ready) { return 0; } if (zstr(subclass_name)) { subclass_name = NULL; } if (node_index <= SWITCH_EVENT_ALL && switch_event_bind_removable(__FILE__, event_id, subclass_name, event_handler, this, &enodes[node_index]) == SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "bound to %s %s\n", event_name, switch_str_nil(subclass_name)); node_index++; return 1; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot bind to %s %s\n", event_name, switch_str_nil(subclass_name)); return 0; } }
static char *parse_template(nproxy_connection_t * conn, const char *file) { apr_file_t *f; char b[4096]; apr_size_t blen; apr_status_t status; /**/ char *in_p = NULL; nn_buffer_t *bufferin; size_t out_size; char *out_p = NULL; nn_buffer_t *bufferout; bufferin = nn_buffer_init(conn->pool, 0, 4096); if (!bufferin) { return NULL; } bufferout = nn_buffer_init(conn->pool, 0, 4096); if (bufferout == NULL) { return NULL; } if (APR_STATUS_SUCCESS != apr_file_open(&f, file, APR_READ, 0, conn->pool)) { nn_log(NN_LOG_ERROR, "Cannot open template file %s", file); return NULL; } do { blen = sizeof(b); status = apr_file_read(f, b, &blen); if (blen > 0) { if (nn_buffer_append(bufferin, b, blen) != APR_STATUS_SUCCESS) { return NULL; } } } while (blen > 0); apr_file_close(f); if (status != APR_EOF) { /* An error occurred reading the file */ nn_log(NN_LOG_ERROR, "Error reading template file %s", file); return NULL; } /* Now we have the full content of the file. We must start evaluating our substitutions. */ nn_buffer_get_char(bufferin, &in_p); if (in_p == NULL) { return NULL; } if (conn->var_hash) { apr_hash_index_t *hi; for (hi = apr_hash_first(conn->pool, conn->var_hash); hi; hi = apr_hash_next(hi)) { apr_ssize_t vlen; const char *var = NULL; char *val = NULL; apr_hash_this(hi, (const void **) &var, &vlen, (void *) &val); if (!zstr(var) && !zstr(val)) { char *s1 = NULL; s1 = apr_psprintf(conn->pool, "{%s}", var); nn_buffer_get_char(bufferin, &in_p); if (in_p) { nn_buffer_reset(bufferout); do_subst(in_p, bufferout, s1, val); out_size = nn_buffer_get_char(bufferout, &out_p); if (out_size && out_p) { nn_buffer_reset(bufferin); nn_buffer_append(bufferin, out_p, out_size); } } } } } /* We won't destroy the buffer, it will be deleted with the pool */ nn_buffer_get_char(bufferin, &in_p); return in_p; }
/** * open next file for reading * @param handle the file handle */ static switch_status_t next_file(switch_file_handle_t *handle) { int loops = 0; struct rayo_file_context *context = handle->private_info; struct output_component *output = context->component ? OUTPUT_COMPONENT(context->component) : NULL; top: if (switch_test_flag((&context->fh), SWITCH_FILE_OPEN)) { switch_core_file_close(&context->fh); } if (switch_test_flag(handle, SWITCH_FILE_FLAG_WRITE)) { /* unsupported */ return SWITCH_STATUS_FALSE; } if (!context->cur_doc) { context->cur_doc = iks_find(output->document, "document"); if (!context->cur_doc) { iks_delete(output->document); output->document = NULL; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Missing <document>\n"); return SWITCH_STATUS_FALSE; } } else { context->cur_doc = iks_next_tag(context->cur_doc); } /* done? */ if (!context->cur_doc) { if (context->could_open && ++loops < 2 && (output->repeat_times == 0 || ++context->play_count < output->repeat_times)) { /* repeat all document(s) */ if (!output->repeat_interval_ms) { goto top; } } else { /* no more files to play */ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Done playing\n"); return SWITCH_STATUS_FALSE; } } if (!context->cur_doc) { /* play silence between repeats */ switch_safe_free(context->ssml); context->ssml = switch_mprintf("silence_stream://%i", output->repeat_interval_ms); } else { /* play next document */ iks *speak = NULL; switch_safe_free(context->ssml); context->ssml = NULL; speak = iks_find(context->cur_doc, "speak"); if (speak) { /* <speak> is child node */ char *ssml_str = iks_string(NULL, speak); if (zstr(output->renderer)) { /* FS must parse the SSML */ context->ssml = switch_mprintf("ssml://%s", ssml_str); } else { /* renderer will parse the SSML */ if (!zstr(output->headers) && !strncmp("unimrcp", output->renderer, 7)) { /* pass MRCP headers */ context->ssml = switch_mprintf("tts://%s||%s%s", output->renderer, output->headers, ssml_str); } else { context->ssml = switch_mprintf("tts://%s||%s", output->renderer, ssml_str); } } iks_free(ssml_str); } else if (iks_has_children(context->cur_doc)) { /* check if <speak> is in CDATA */ const char *ssml_str = NULL; iks *ssml = iks_child(context->cur_doc); if (ssml && iks_type(ssml) == IKS_CDATA) { ssml_str = iks_cdata(ssml); } if (zstr(ssml_str)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Missing <document> CDATA\n"); return SWITCH_STATUS_FALSE; } if (zstr(output->renderer)) { /* FS must parse the SSML */ context->ssml = switch_mprintf("ssml://%s", ssml_str); } else { /* renderer will parse the SSML */ if (!zstr(output->headers) && !strncmp("unimrcp", output->renderer, 7)) { /* pass MRCP headers */ context->ssml = switch_mprintf("tts://%s||%s%s", output->renderer, output->headers, ssml_str); } else { context->ssml = switch_mprintf("tts://%s||%s", output->renderer, ssml_str); } } } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Missing <speak>\n"); return SWITCH_STATUS_FALSE; } } if (switch_core_file_open(&context->fh, context->ssml, handle->channels, handle->samplerate, handle->flags, NULL) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Failed to open %s\n", context->ssml); goto top; } else { context->could_open = 1; } handle->samples = context->fh.samples; handle->format = context->fh.format; handle->sections = context->fh.sections; handle->seekable = context->fh.seekable; handle->speed = context->fh.speed; handle->vol = context->fh.vol; handle->offset_pos = context->fh.offset_pos; handle->interval = context->fh.interval; if (switch_test_flag((&context->fh), SWITCH_FILE_NATIVE)) { switch_set_flag(handle, SWITCH_FILE_NATIVE); } else { switch_clear_flag(handle, SWITCH_FILE_NATIVE); } return SWITCH_STATUS_SUCCESS; }
/** * Wraps file with interface that can be controlled by fileman flags * @param handle * @param path the file to play * @return SWITCH_STATUS_SUCCESS if opened */ static switch_status_t fileman_file_open(switch_file_handle_t *handle, const char *path) { int start_offset_ms = 0; switch_status_t status = SWITCH_STATUS_FALSE; struct fileman_file_context *context = switch_core_alloc(handle->memory_pool, sizeof(*context)); handle->private_info = context; if (handle->params) { const char *id = switch_event_get_header(handle->params, "id"); const char *uuid = switch_event_get_header(handle->params, "session"); const char *start_offset_ms_str = switch_event_get_header(handle->params, "start_offset_ms"); if (!zstr(id)) { context->id = switch_core_strdup(handle->memory_pool, id); } if (!zstr(uuid)) { context->uuid = switch_core_strdup(handle->memory_pool, uuid); } if (!zstr(start_offset_ms_str) && switch_is_number(start_offset_ms_str)) { start_offset_ms = atoi(start_offset_ms_str); if (start_offset_ms < 0) { start_offset_ms = 0; } } } switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->uuid), SWITCH_LOG_DEBUG, "Got path %s\n", path); if ((status = switch_core_file_open(&context->fh, path, handle->channels, handle->samplerate, handle->flags, NULL)) != SWITCH_STATUS_SUCCESS) { return status; } /* set up handle for external control */ if (!context->id) { /* use filename as ID */ context->id = switch_core_strdup(handle->memory_pool, path); } switch_mutex_lock(fileman_globals.mutex); if (!switch_core_hash_find(fileman_globals.hash, context->id)) { switch_core_hash_insert(fileman_globals.hash, context->id, handle); } else { switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->uuid), SWITCH_LOG_WARNING, "Duplicate fileman ID: %s\n", context->id); return SWITCH_STATUS_FALSE; } switch_mutex_unlock(fileman_globals.mutex); context->max_frame_len = (handle->samplerate / 1000 * SWITCH_MAX_INTERVAL); switch_zmalloc(context->abuf, FILE_STARTBYTES * sizeof(*context->abuf)); if (!context->fh.audio_buffer) { switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->uuid), SWITCH_LOG_DEBUG, "Create audio buffer\n"); switch_buffer_create_dynamic(&context->fh.audio_buffer, FILE_BLOCKSIZE, FILE_BUFSIZE, 0); switch_assert(context->fh.audio_buffer); } handle->samples = context->fh.samples; handle->format = context->fh.format; handle->sections = context->fh.sections; handle->seekable = context->fh.seekable; handle->speed = context->fh.speed; handle->vol = context->fh.vol; handle->offset_pos = context->fh.offset_pos; handle->interval = context->fh.interval; if (switch_test_flag((&context->fh), SWITCH_FILE_NATIVE)) { switch_set_flag(handle, SWITCH_FILE_NATIVE); } else { switch_clear_flag(handle, SWITCH_FILE_NATIVE); } if (handle->params && switch_true(switch_event_get_header(handle->params, "pause"))) { switch_set_flag(handle, SWITCH_FILE_PAUSE); } if (handle->seekable && start_offset_ms) { unsigned int pos = 0; int32_t target = start_offset_ms * (handle->samplerate / 1000); switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->uuid), SWITCH_LOG_DEBUG, "seek to position %d\n", target); switch_core_file_seek(&context->fh, &pos, target, SEEK_SET); } return status; }
/** * Process fileman command */ static switch_status_t fileman_process_cmd(const char *cmd, switch_file_handle_t *fhp) { if (zstr(cmd)) { return SWITCH_STATUS_SUCCESS; } if (fhp) { struct fileman_file_context *context = (struct fileman_file_context *)fhp->private_info; if (!switch_test_flag(fhp, SWITCH_FILE_OPEN)) { return SWITCH_STATUS_FALSE; } if (!strncasecmp(cmd, "speed", 5)) { char *p; if ((p = strchr(cmd, ':'))) { p++; if (*p == '+' || *p == '-') { int step; if (!(step = atoi(p))) { if (*p == '+') { step = 1; } else { step = -1; } } fhp->speed += step; } else { int speed = atoi(p); fhp->speed = speed; } return SWITCH_STATUS_SUCCESS; } return SWITCH_STATUS_FALSE; } else if (!strncasecmp(cmd, "volume", 6)) { char *p; if ((p = strchr(cmd, ':'))) { p++; if (*p == '+' || *p == '-') { int step; if (!(step = atoi(p))) { if (*p == '+') { step = 1; } else { step = -1; } } fhp->vol += step; } else { int vol = atoi(p); fhp->vol = vol; } return SWITCH_STATUS_SUCCESS; } if (fhp->vol) { switch_normalize_volume(fhp->vol); } return SWITCH_STATUS_FALSE; } else if (!strcasecmp(cmd, "pause")) { switch_set_flag(fhp, SWITCH_FILE_PAUSE); return SWITCH_STATUS_SUCCESS; } else if (!strcasecmp(cmd, "resume")) { switch_clear_flag(fhp, SWITCH_FILE_PAUSE); return SWITCH_STATUS_SUCCESS; } else if (!strcasecmp(cmd, "stop")) { switch_set_flag(fhp, SWITCH_FILE_DONE); return SWITCH_STATUS_FALSE; } else if (!strcasecmp(cmd, "truncate")) { switch_core_file_truncate(fhp, 0); } else if (!strcasecmp(cmd, "restart")) { unsigned int pos = 0; fhp->speed = 0; switch_core_file_seek(fhp, &pos, 0, SEEK_SET); return SWITCH_STATUS_SUCCESS; } else if (!strncasecmp(cmd, "seek", 4)) { unsigned int samps = 0; unsigned int pos = 0; char *p; if ((p = strchr(cmd, ':'))) { p++; if (*p == '+' || *p == '-') { int step; int32_t target; if (!(step = atoi(p))) { if (*p == '+') { step = 1000; } else { step = -1000; } } samps = step * (fhp->samplerate / 1000); target = (int32_t)fhp->pos + samps; if (target < 0) { target = 0; } switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->uuid), SWITCH_LOG_DEBUG, "seek to position %d\n", target); switch_core_file_seek(fhp, &pos, target, SEEK_SET); } else { samps = switch_atoui(p) * (fhp->samplerate / 1000); switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->uuid), SWITCH_LOG_DEBUG, "seek to position %d\n", samps); switch_core_file_seek(fhp, &pos, samps, SEEK_SET); } } return SWITCH_STATUS_SUCCESS; } } if (!strcmp(cmd, "true") || !strcmp(cmd, "undefined")) { return SWITCH_STATUS_SUCCESS; } return SWITCH_STATUS_FALSE; }
static switch_status_t switch_console_logger(const switch_log_node_t *node, switch_log_level_t level) { FILE *handle; if (!RUNNING) { return SWITCH_STATUS_SUCCESS; } #if 0 if (failed_write) { if ((handle = switch_core_data_channel(SWITCH_CHANNEL_ID_LOG))) { int aok = can_write(handle, 100); if (aok) { const char *msg = "Failed to write to the console! Logging disabled! RE-enable with the 'console loglevel' command\n"; #ifdef WIN32 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s", msg); #else if (COLORIZE) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s%s%s", COLORS[1], msg, SWITCH_SEQ_DEFAULT_COLOR); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s", msg); } #endif failed_write = 0; } } } #endif if (level > hard_log_level && (node->slevel == SWITCH_LOG_UNINIT || level > node->slevel)) { return SWITCH_STATUS_SUCCESS; } if ((handle = switch_core_data_channel(SWITCH_CHANNEL_ID_LOG))) { size_t mask = 0; size_t ok = 0; ok = switch_log_check_mask(all_level, level); if (log_hash) { if (!ok) { mask = (size_t) switch_core_hash_find(log_hash, node->file); ok = switch_log_check_mask(mask, level); } if (!ok) { mask = (size_t) switch_core_hash_find(log_hash, node->func); ok = switch_log_check_mask(mask, level); } } if (ok) { #ifndef WIN32 int aok = can_write(handle, 10000); if (!aok) { //hard_log_level = 0; //failed_write++; return SWITCH_STATUS_SUCCESS; } #endif if (COLORIZE) { #ifdef WIN32 DWORD len = (DWORD) strlen(node->data); DWORD outbytes = 0; SetConsoleTextAttribute(hStdout, COLORS[node->level]); if (log_uuid && !zstr(node->userdata)) { WriteFile(hStdout, node->userdata, (DWORD)strlen(node->userdata), &outbytes, NULL); WriteFile(hStdout, " ", 1, &outbytes, NULL); } WriteFile(hStdout, node->data, len, &outbytes, NULL); SetConsoleTextAttribute(hStdout, wOldColorAttrs); #else if (log_uuid && !zstr(node->userdata)) { fprintf(handle, "%s%s %s%s", COLORS[node->level], node->userdata, node->data, SWITCH_SEQ_DEFAULT_COLOR); } else { fprintf(handle, "%s%s%s", COLORS[node->level], node->data, SWITCH_SEQ_DEFAULT_COLOR); } #endif } else if (log_uuid && !zstr(node->userdata)) { fprintf(handle, "%s %s", node->userdata, node->data); } else { fprintf(handle, "%s", node->data); } } } return SWITCH_STATUS_SUCCESS; }
static switch_status_t do_config(void) { char *cf = "xml_scgi.conf"; switch_xml_t cfg, xml, bindings_tag, binding_tag, param; xml_binding_t *binding = NULL; int x = 0; int need_vars_map = 0; switch_hash_t *vars_map = 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 SWITCH_STATUS_TERM; } if (!(bindings_tag = switch_xml_child(cfg, "bindings"))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing <bindings> tag!\n"); goto done; } for (binding_tag = switch_xml_child(bindings_tag, "binding"); binding_tag; binding_tag = binding_tag->next) { char *bname = (char *) switch_xml_attr_soft(binding_tag, "name"); char *host = "127.0.0.1"; char *port = "8080"; char *bind_mask = NULL; int timeout = 0; char *server = NULL; hash_node_t *hash_node; need_vars_map = 0; vars_map = NULL; for (param = switch_xml_child(binding_tag, "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, "host")) { bind_mask = (char *) switch_xml_attr_soft(param, "bindings"); if (val) { host = val; } } else if (!strcasecmp(var, "port")) { port = val; } else if (!strcasecmp(var, "timeout")) { int tmp = atoi(val); if (tmp >= 0) { timeout = tmp; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't set a negative timeout!\n"); } } else if (!strcasecmp(var, "enable-post-var")) { if (!vars_map && need_vars_map == 0) { if (switch_core_hash_init(&vars_map, globals.pool) != SWITCH_STATUS_SUCCESS) { need_vars_map = -1; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Can't init params hash!\n"); continue; } need_vars_map = 1; } if (vars_map && val) { if (switch_core_hash_insert(vars_map, val, ENABLE_PARAM_VALUE) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Can't add %s to params hash!\n", val); } } } else if (!strcasecmp(var, "server")) { server = val; } } if (!host) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Binding has no host!\n"); if (vars_map) { switch_core_hash_destroy(&vars_map); } continue; } if (!(binding = switch_core_alloc(globals.pool, sizeof(*binding)))) { if (vars_map) { switch_core_hash_destroy(&vars_map); } goto done; } memset(binding, 0, sizeof(*binding)); binding->timeout = timeout; binding->host = switch_core_strdup(globals.pool, host); binding->port = atoi(port); binding->vars_map = vars_map; binding->uri = switch_mprintf("/%s", bname); binding->url = switch_mprintf("scgi://%s:%s/%s", host, port, bname); if (server) { binding->server = switch_core_strdup(globals.pool, server); } if (bind_mask) { binding->bindings = switch_core_strdup(globals.pool, bind_mask); } if (vars_map) { switch_zmalloc(hash_node, sizeof(hash_node_t)); hash_node->hash = vars_map; hash_node->next = NULL; if (!globals.hash_root) { globals.hash_root = hash_node; globals.hash_tail = globals.hash_root; } else { globals.hash_tail->next = hash_node; globals.hash_tail = globals.hash_tail->next; } } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Binding [%s] XML Fetch Function [%s] [%s]\n", zstr(bname) ? "N/A" : bname, binding->url, binding->bindings ? binding->bindings : "all"); switch_xml_bind_search_function(xml_url_fetch, switch_xml_parse_section_string(binding->bindings), binding); if (binding->server) { launch_monitor_thread(binding); } binding->next = globals.bindings; globals.bindings = binding; x++; binding = NULL; } done: switch_xml_free(xml); return x ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE; }
apr_status_t http_send_custom_response(nproxy_connection_t * conn, http_resp_codes_t error_code) { size_t t; int clen; int e_code; char *tpl = NULL; char *e_msg = NULL; char *e_text = NULL; char *e_detail = NULL; char *payload = NULL; char found = 0; char timebuf[APR_RFC822_DATE_LEN]; char *additional_headers = ""; const char *tmp = NULL; nproxy_connection_side_t *side; apr_status_t rv; apr_size_t len; const char *fallback_error = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" " "\"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n" "<html>\n" "<head><title>%d %s</title></head>\n" "<body>\n" "<h1>%d %s</h1>\n" "<p>%s</p>\n" "<hr />\n" "<p><em>Generated by NProxy</em></p>\n" "</body>\n" "</html>\n"; side = conn->browser; apr_rfc822_date(timebuf, apr_time_now()); for (t = 0; t < sizeof(ec) / sizeof(ec[0]); t++) { if (error_code == ec[t].code) { e_code = ec[t].number; e_msg = ec[t].string; found = 1; break; } } if (!found) { e_msg = "Error code string not found."; e_code = error_code; } e_detail = "No details, sorry."; if ((tmp = nproxy_connection_get_variable(conn, "additional_headers"))) { if (!zstr(tmp)) { additional_headers = (char *) tmp; } } if ((tmp = nproxy_connection_get_variable(conn, "custom_cause"))) { if (!zstr(tmp)) { e_msg = (char *) tmp; } } if ((tmp = nproxy_connection_get_variable(conn, "custom_detail"))) { if (!zstr(tmp)) { e_detail = (char *) tmp; } } tmp = nproxy_connection_get_variable(conn, "custom_template"); tpl = find_template(conn, e_code, tmp); if (tpl != NULL) { if (conn->requests != NULL) { nproxy_connection_set_variable(conn, "req_method", conn->requests->method); nproxy_connection_set_variable(conn, "req_host", conn->requests->host); nproxy_connection_set_variable(conn, "req_port", apr_psprintf(conn->pool, "%d", conn->requests->port)); nproxy_connection_set_variable(conn, "req_url", conn->requests->url); } nproxy_connection_set_variable(conn, "resp_errno", apr_psprintf(conn->pool, "%d", e_code)); nproxy_connection_set_variable(conn, "resp_cause", e_msg); nproxy_connection_set_variable(conn, "resp_detail", e_detail); nproxy_connection_set_variable(conn, "package", "NProxy"); e_text = parse_template(conn, tpl); } if (zstr(e_text)) { e_text = apr_psprintf(conn->pool, fallback_error, e_code, e_msg, e_code, e_msg, e_detail); } clen = strlen(e_text); payload = apr_psprintf(conn->pool, "%s %d %s\r\n" "Content-Type: text/html\r\n" "Connection: close\r\n" "Proxy-Connection: close\r\n" "Content-Length: %d\r\n" "Date: %s\r\n" "%s" "\r\n" "%s", "HTTP/1.0", e_code, e_msg, clen, timebuf, additional_headers, e_text); len = strlen(payload); rv = apr_socket_send(side->sock, payload, &len); if (rv == APR_STATUS_SUCCESS) { if (conn->requests != NULL) { conn->requests->bytes_in += len; conn->requests->response_headers.resp_code = error_code; } } else { rv = APR_STATUS_ERROR; } return rv; }
static switch_status_t enum_lookup(char *root, char *in, enum_record_t **results, switch_channel_t *channel, switch_core_session_t *session) { switch_status_t sstatus = SWITCH_STATUS_SUCCESS; char *mnum = NULL, *mroot = NULL, *p; char *server[ENUM_MAXNAMESERVERS]; int inameserver = 0; char *argv[ ENUM_MAXNAMESERVERS ] = { 0 }; int argc; int x = 0; char *enum_nameserver_dup; const char *enum_nameserver = NULL; *results = NULL; mnum = switch_mprintf("%s%s", *in == '+' ? "" : "+", in); if ((p = strchr(mnum, '*'))) { *p++ = '\0'; mroot = switch_mprintf("%s.%s", p, root ? root : globals.isn_root); root = mroot; } if (zstr(root)) { root = globals.root; } /* Empty the server array */ for(inameserver=0; inameserver<ENUM_MAXNAMESERVERS; inameserver++) { server[inameserver] = NULL; } inameserver = 0; /* check for enum_nameserver channel var */ if (channel) { enum_nameserver = switch_channel_get_variable(channel, "enum_nameserver"); } if (zstr(enum_nameserver)) { enum_nameserver = switch_core_get_variable("enum-server"); } if (!zstr(enum_nameserver)) { /* Blank the server array */ for(inameserver=0; inameserver<ENUM_MAXNAMESERVERS; inameserver++) { server[inameserver] = NULL; } enum_nameserver_dup = switch_core_session_strdup(session, enum_nameserver); argc = switch_separate_string(enum_nameserver_dup, ',', argv, (sizeof(argv) / sizeof(argv[0]))); inameserver = 0; for (x = 0; x < argc; x++) { server[inameserver] = argv[x]; inameserver++; } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Enum nameserver override : %s\n", enum_nameserver); } if (!inameserver) { /* use config param "nameserver" ( can be up to ENUM_MAXNAMESERVERS ) */ for(inameserver = 0; inameserver<ENUM_MAXNAMESERVERS; inameserver++) { server[inameserver] = NULL; if ( globals.nameserver[inameserver] != NULL ) { server[inameserver] = globals.nameserver[inameserver]; } } } ldns_lookup(mnum, root, server, results); switch_safe_free(mnum); switch_safe_free(mroot); return sstatus; }
static void parse_naptr(const ldns_rr *naptr, const char *number, enum_record_t **results) { char *str = ldns_rr2str(naptr); char *argv[11] = { 0 }; int i, argc; char *pack[4] = { 0 }; int packc; char *p; int order = 10; int preference = 100; char *service = NULL; char *packstr; char *regex, *replace; if (zstr(str)) { if (str != NULL) { /* In this case ldns_rr2str returned a malloc'd null terminated string */ switch_safe_free(str); } return; } for (p = str; p && *p; p++) { if (*p == '\t') *p = ' '; if (*p == ' ' && *(p+1) == '.') *p = '\0'; } argc = switch_split(str, ' ', argv); for (i = 0; i < argc; i++) { if (i > 0) { strip_quotes(argv[i]); } } service = argv[7]; packstr = argv[8]; if (zstr(service) || zstr(packstr)) { goto end; } if (!zstr(argv[4])) { order = atoi(argv[4]); } if (!zstr(argv[5])) { preference = atoi(argv[5]); } if ((packc = switch_split(packstr, '!', pack))) { regex = pack[1]; replace = pack[2]; } else { goto end; } for (p = replace; p && *p; p++) { if (*p == '\\') { *p = '$'; } } if (service && regex && replace) { switch_regex_t *re = NULL, *re2 = NULL; int proceed = 0, ovector[30]; char *substituted = NULL; char *substituted_2 = NULL; char *orig_uri; char *uri_expanded = NULL; enum_route_t *route; int supported = 0; uint32_t len = 0; if ((proceed = switch_regex_perform(number, regex, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) { if (strchr(regex, '(')) { len = (uint32_t) (strlen(number) + strlen(replace) + 10) * proceed; if (!(substituted = malloc(len))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n"); switch_regex_safe_free(re); goto end; } memset(substituted, 0, len); switch_perform_substitution(re, proceed, replace, number, substituted, len, ovector); orig_uri = substituted; } else { orig_uri = replace; } switch_mutex_lock(MUTEX); for (route = globals.route_order; route; route = route->next) { char *uri = orig_uri; if (strcasecmp(service, route->service)) { continue; } if ((proceed = switch_regex_perform(uri, route->regex, &re2, ovector, sizeof(ovector) / sizeof(ovector[0])))) { switch_event_t *event = NULL; if (strchr(route->regex, '(')) { len = (uint32_t) (strlen(uri) + strlen(route->replace) + 10) * proceed; if (!(substituted_2 = malloc(len))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n"); switch_safe_free(substituted); switch_regex_safe_free(re); switch_regex_safe_free(re2); switch_mutex_unlock(MUTEX); goto end; } memset(substituted_2, 0, len); switch_perform_substitution(re2, proceed, route->replace, uri, substituted_2, len, ovector); uri = substituted_2; } else { uri = route->replace; } switch_event_create(&event, SWITCH_EVENT_REQUEST_PARAMS); uri_expanded = switch_event_expand_headers(event, uri); switch_event_destroy(&event); if (uri_expanded == uri) { uri_expanded = NULL; } else { uri = uri_expanded; } supported++; add_result(results, order, preference, service, uri, supported); } switch_safe_free(uri_expanded); switch_safe_free(substituted_2); switch_regex_safe_free(re2); } switch_mutex_unlock(MUTEX); if (!supported) { add_result(results, order, preference, service, orig_uri, 0); } switch_safe_free(substituted); switch_regex_safe_free(re); } } end: switch_safe_free(str); return; }
/** * Get a URL from the cache, add it if it does not exist * @param cache The cache * @param session the (optional) session requesting the URL * @param url The URL * @param download If true, the file will be downloaded if it does not exist in the cache. * @param pool The pool to use for allocating the filename * @return The filename or NULL if there is an error */ static char *url_cache_get(url_cache_t *cache, switch_core_session_t *session, const char *url, int download, switch_memory_pool_t *pool) { char *filename = NULL; cached_url_t *u = NULL; if (zstr(url)) { return NULL; } url_cache_lock(cache, session); u = switch_core_hash_find(cache->map, url); if (u && u->status == CACHED_URL_AVAILABLE) { if (switch_time_now() >= (u->download_time + u->max_age)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Cached URL has expired.\n"); url_cache_remove_soft(cache, session, u); /* will get permanently deleted upon replacement */ u = NULL; } else if (switch_file_exists(u->filename, pool) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Cached URL file is missing.\n"); url_cache_remove_soft(cache, session, u); /* will get permanently deleted upon replacement */ u = NULL; } } if (!u && download) { /* URL is not cached, let's add it.*/ /* Set up URL entry and add to map to prevent simultaneous downloads */ cache->misses++; switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Cache MISS: size = %zu (%zu MB), hit ratio = %d/%d\n", cache->queue.size, cache->size / 1000000, cache->hits, cache->hits + cache->misses); u = cached_url_create(cache, url); if (url_cache_add(cache, session, u) != SWITCH_STATUS_SUCCESS) { /* This error should never happen */ url_cache_unlock(cache, session); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Failed to add URL to cache!\n"); cached_url_destroy(u, cache->pool); return NULL; } /* download the file */ url_cache_unlock(cache, session); if (http_get(cache, u, session) == SWITCH_STATUS_SUCCESS) { /* Got the file, let the waiters know it is available */ url_cache_lock(cache, session); u->status = CACHED_URL_AVAILABLE; filename = switch_core_strdup(pool, u->filename); cache->size += u->size; } else { /* Did not get the file, flag for replacement */ url_cache_lock(cache, session); url_cache_remove_soft(cache, session, u); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Failed to download URL %s\n", url); cache->errors++; } } else if (!u) { filename = DOWNLOAD_NEEDED; } else { /* Wait until file is downloaded */ if (u->status == CACHED_URL_RX_IN_PROGRESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Waiting for URL %s to be available\n", url); u->waiters++; url_cache_unlock(cache, session); while(u->status == CACHED_URL_RX_IN_PROGRESS) { switch_sleep(10 * 1000); /* 10 ms */ } url_cache_lock(cache, session); u->waiters--; } /* grab filename if everything is OK */ if (u->status == CACHED_URL_AVAILABLE) { filename = switch_core_strdup(pool, u->filename); cache->hits++; u->used = 1; switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Cache HIT: size = %zu (%zu MB), hit ratio = %d/%d\n", cache->queue.size, cache->size / 1000000, cache->hits, cache->hits + cache->misses); } } url_cache_unlock(cache, session); return filename; }
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 isUrl(const char *filename) { return !zstr(filename) && (!strncmp("http://", filename, strlen("http://")) || !strncmp("https://", filename, strlen("https://"))); }