static enum ast_test_result_state test_2way_function(struct ast_test *test, struct ast_channel *c, const char *encode1, const char *encode2, const char *decode1, const char *decode2) { struct ast_str *str = ast_str_create(16), *expression = ast_str_alloca(120); int okay; ast_str_set(&expression, 0, "%s%s%s", encode1, "foobarbaz", encode2); ast_str_substitute_variables(&str, 0, c, ast_str_buffer(expression)); ast_str_set(&expression, 0, "%s%s%s", decode1, ast_str_buffer(str), decode2); ast_str_substitute_variables(&str, 0, c, ast_str_buffer(expression)); okay = !strcmp(ast_str_buffer(str), "foobarbaz"); ast_test_status_update(test, "Testing '%s%s' and '%s%s' . . . . . %s\n", encode1, encode2, decode1, decode2, okay ? "passed" : "FAILED"); if (!okay) { ast_test_status_update(test, " '%s' != 'foobarbaz'\n", ast_str_buffer(str)); } ast_free(str); return okay ? AST_TEST_PASS : AST_TEST_FAIL; }
char *__netsock_stringify_fmt(const struct sockaddr_storage *sockAddrStorage, int format) { const struct sockaddr_storage *sockAddrStorage_tmp; char host[NI_MAXHOST] = ""; char port[NI_MAXSERV] = ""; struct ast_str *str; int e; static const size_t size = sizeof(host) - 1 + sizeof(port) - 1 + 4; if (!sockAddrStorage) { return "(null)"; } if (!(str = ast_str_thread_get(&sccp_netsock_stringify_buf, size))) { return ""; } //if (sccp_netsock_ipv4_mapped(sockAddrStorage, &sockAddrStorage_tmp_ipv4)) { // struct sockaddr_storage sockAddrStorage_tmp_ipv4; // sockAddrStorage_tmp = &sockAddrStorage_tmp_ipv4; //#if DEBUG // sccp_log(0)("SCCP: ipv4 mapped in ipv6 address\n"); //#endif //} else { sockAddrStorage_tmp = sockAddrStorage; //} if ((e = getnameinfo((struct sockaddr *) sockAddrStorage_tmp, sccp_netsock_sizeof(sockAddrStorage_tmp), format & SCCP_SOCKADDR_STR_ADDR ? host : NULL, format & SCCP_SOCKADDR_STR_ADDR ? sizeof(host) : 0, format & SCCP_SOCKADDR_STR_PORT ? port : 0, format & SCCP_SOCKADDR_STR_PORT ? sizeof(port) : 0, NI_NUMERICHOST | NI_NUMERICSERV))) { sccp_log(DEBUGCAT_SOCKET) (VERBOSE_PREFIX_3 "SCCP: getnameinfo(): %s \n", gai_strerror(e)); return ""; } if ((format & SCCP_SOCKADDR_STR_REMOTE) == SCCP_SOCKADDR_STR_REMOTE) { char *p; if (sccp_netsock_is_ipv6_link_local(sockAddrStorage_tmp) && (p = strchr(host, '%'))) { *p = '\0'; } } switch ((format & SCCP_SOCKADDR_STR_FORMAT_MASK)) { case SCCP_SOCKADDR_STR_DEFAULT: ast_str_set(&str, 0, sockAddrStorage_tmp->ss_family == AF_INET6 ? "[%s]:%s" : "%s:%s", host, port); break; case SCCP_SOCKADDR_STR_ADDR: ast_str_set(&str, 0, "%s", host); break; case SCCP_SOCKADDR_STR_HOST: ast_str_set(&str, 0, sockAddrStorage_tmp->ss_family == AF_INET6 ? "[%s]" : "%s", host); break; case SCCP_SOCKADDR_STR_PORT: ast_str_set(&str, 0, "%s", port); break; default: pbx_log(LOG_ERROR, "Invalid format\n"); return ""; } return ast_str_buffer(str); }
static void security_event_cb(const struct ast_event *event, void *data) { struct ast_str *str; enum ast_security_event_type event_type; if (!(str = ast_str_thread_get(&security_event_buf, SECURITY_EVENT_BUF_INIT_LEN))) { return; } /* Note that the event type is guaranteed to be valid here. */ event_type = ast_event_get_ie_uint(event, AST_EVENT_IE_SECURITY_EVENT); ast_assert(event_type >= 0 && event_type < AST_SECURITY_EVENT_NUM_TYPES); ast_str_set(&str, 0, "%s=\"%s\"", ast_event_get_ie_type_name(AST_EVENT_IE_SECURITY_EVENT), ast_security_event_get_name(event_type)); append_ies(&str, event, ast_security_event_get_required_ies(event_type), REQUIRED); append_ies(&str, event, ast_security_event_get_optional_ies(event_type), NOT_REQUIRED); ast_log_dynamic_level(LOG_SECURITY, "%s\n", ast_str_buffer(str)); }
/*! * \internal * \brief Build the NOTIFY request adding content or header info. */ static void build_notify(pjsip_tx_data *tdata, const char *name, const char *value, struct ast_str **content_type, struct ast_str **content) { if (not_allowed(name)) { ast_log(LOG_WARNING, "Cannot specify %s header, " "ignoring\n", name); return; } if (!strcasecmp(name, "Content-type")) { if (!(*content_type)) { *content_type = ast_str_create(CONTENT_TYPE_SIZE); } ast_str_set(content_type, 0,"%s", value); } else if (!strcasecmp(name, "Content")) { if (!(*content)) { *content = ast_str_create(CONTENT_SIZE); } if (ast_str_strlen(*content)) { ast_str_append(content, 0, "\r\n"); } ast_str_append(content, 0, "%s", value); } else { ast_sip_add_header(tdata, name, value); } }
static struct ast_manager_event_blob *varset_to_ami(struct stasis_message *msg) { RAII_VAR(struct ast_str *, channel_event_string, NULL, ast_free); struct ast_channel_blob *obj = stasis_message_data(msg); const char *variable = ast_json_string_get(ast_json_object_get(obj->blob, "variable")); const char *value = ast_json_string_get(ast_json_object_get(obj->blob, "value")); if (obj->snapshot) { channel_event_string = ast_manager_build_channel_state_string(obj->snapshot); } else { channel_event_string = ast_str_create(35); ast_str_set(&channel_event_string, 0, "Channel: none\r\n" "Uniqueid: none\r\n"); } if (!channel_event_string) { return NULL; } return ast_manager_event_blob_create(EVENT_FLAG_DIALPLAN, "VarSet", "%s" "Variable: %s\r\n" "Value: %s\r\n", ast_str_buffer(channel_event_string), variable, value); }
static int add_ipv4_ie(struct ast_event **event, enum ast_event_ie_type ie_type, const struct ast_security_event_ipv4_addr *addr) { struct ast_str *str = ast_str_alloca(64); ast_str_set(&str, 0, "IPV4/"); switch (addr->transport) { case AST_SECURITY_EVENT_TRANSPORT_UDP: ast_str_append(&str, 0, "UDP/"); break; case AST_SECURITY_EVENT_TRANSPORT_TCP: ast_str_append(&str, 0, "TCP/"); break; case AST_SECURITY_EVENT_TRANSPORT_TLS: ast_str_append(&str, 0, "TLS/"); break; } ast_str_append(&str, 0, "%s/%hu", ast_inet_ntoa(addr->sin->sin_addr), ntohs(addr->sin->sin_port)); return ast_event_append_ie_str(event, ie_type, ast_str_buffer(str)); }
static struct ast_manager_event_blob *system_registry_to_ami(struct stasis_message *message) { struct ast_json_payload *payload = stasis_message_data(message); const char *channeltype; const char *username; const char *domain; const char *status; const char *cause; RAII_VAR(struct ast_str *, cause_string, ast_str_create(32), ast_free); if (!cause_string) { return NULL; } channeltype = ast_json_string_get(ast_json_object_get(payload->json, "channeltype")); username = ast_json_string_get(ast_json_object_get(payload->json, "username")); domain = ast_json_string_get(ast_json_object_get(payload->json, "domain")); status = ast_json_string_get(ast_json_object_get(payload->json, "status")); cause = ast_json_string_get(ast_json_object_get(payload->json, "cause")); if (!ast_strlen_zero(cause)) { ast_str_set(&cause_string, 0, "Cause: %s\r\n", cause); } return ast_manager_event_blob_create(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: %s\r\n" "Username: %s\r\n" "Domain: %s\r\n" "Status: %s\r\n" "%s", channeltype, username, domain, status, ast_str_buffer(cause_string)); }
static void security_event_stasis_cb(struct ast_json *json) { struct ast_str *str; struct ast_json *event_type_json; enum ast_security_event_type event_type; event_type_json = ast_json_object_get(json, "SecurityEvent"); event_type = ast_json_integer_get(event_type_json); ast_assert(event_type >= 0 && event_type < AST_SECURITY_EVENT_NUM_TYPES); if (!(str = ast_str_thread_get(&security_event_buf, SECURITY_EVENT_BUF_INIT_LEN))) { return; } ast_str_set(&str, 0, "SecurityEvent=\"%s\"", ast_security_event_get_name(event_type)); append_json(&str, json, ast_security_event_get_required_ies(event_type), REQUIRED); append_json(&str, json, ast_security_event_get_optional_ies(event_type), NOT_REQUIRED); ast_log_dynamic_level(LOG_SECURITY, "%s\n", ast_str_buffer(str)); }
static int load_config_string(struct ast_config *cfg, const char *category, const char *variable, struct ast_str **field, const char *def) { struct unload_string *us; const char *tmp; if (!(us = ast_calloc(1, sizeof(*us)))) { return -1; } if (!(*field = ast_str_create(16))) { ast_free(us); return -1; } tmp = ast_variable_retrieve(cfg, category, variable); ast_str_set(field, 0, "%s", tmp ? tmp : def); us->str = *field; AST_LIST_LOCK(&unload_strings); AST_LIST_INSERT_HEAD(&unload_strings, us, entry); AST_LIST_UNLOCK(&unload_strings); return 0; }
struct ast_str *ast_manager_build_bridge_state_string_prefix( const struct ast_bridge_snapshot *snapshot, const char *prefix) { struct ast_str *out = ast_str_create(128); int res; if (!out) { return NULL; } res = ast_str_set(&out, 0, "%sBridgeUniqueid: %s\r\n" "%sBridgeType: %s\r\n" "%sBridgeTechnology: %s\r\n" "%sBridgeCreator: %s\r\n" "%sBridgeName: %s\r\n" "%sBridgeNumChannels: %u\r\n", prefix, snapshot->uniqueid, prefix, snapshot->subclass, prefix, snapshot->technology, prefix, ast_strlen_zero(snapshot->creator) ? "<unknown>": snapshot->creator, prefix, ast_strlen_zero(snapshot->name) ? "<unknown>": snapshot->name, prefix, snapshot->num_channels); if (!res) { ast_free(out); return NULL; } return out; }
static enum ast_test_result_state test_chan_variable(struct ast_test *test, struct ast_channel *c, const char *varname) { const char *values[] = { "one", "three", "reallylongdinosaursoundingthingwithwordsinit" }; int i, okay = 1; char workspace[4096]; struct ast_str *str = ast_str_create(16); struct ast_str *var = ast_str_create(16); ast_str_set(&var, 0, "${%s}", varname); for (i = 0; i < ARRAY_LEN(values); i++) { pbx_builtin_setvar_helper(c, varname, values[i]); ast_str_substitute_variables(&str, 0, c, ast_str_buffer(var)); pbx_substitute_variables_helper(c, ast_str_buffer(var), workspace, sizeof(workspace)); ast_test_status_update(test, "Testing '%s' . . . . . %s\n", ast_str_buffer(var), okay ? "passed" : "FAILED"); if (strcmp(values[i], ast_str_buffer(str)) != 0 || strcmp(values[i], workspace) != 0) { ast_test_status_update(test, "%s != %s != %s\n", values[i], ast_str_buffer(str), workspace); okay = 0; } } ast_free(str); ast_free(var); return okay ? AST_TEST_PASS : AST_TEST_FAIL; }
static int update2_curl(const char *url, const char *unused, const struct ast_variable *lookup_fields, const struct ast_variable *update_fields) { struct ast_str *query, *buffer; char buf1[200], buf2[200]; const struct ast_variable *field; char *stringp; unsigned int start = 1; int rowcount = -1; if (!ast_custom_function_find("CURL")) { ast_log(LOG_ERROR, "func_curl.so must be loaded in order to use res_config_curl.so!!\n"); return -1; } if (!(query = ast_str_thread_get(&query_buf, 1000))) return -1; if (!(buffer = ast_str_thread_get(&result_buf, 16))) { return -1; } ast_str_set(&query, 0, "${CURL(%s/update?", url); for (field = lookup_fields; field; field = field->next) { ast_uri_encode(field->name, buf1, sizeof(buf1), ast_uri_http); ast_uri_encode(field->value, buf2, sizeof(buf2), ast_uri_http); ast_str_append(&query, 0, "%s%s=%s", !start ? "" : "&", buf1, buf2); start = 0; } ast_str_append(&query, 0, ","); start = 1; for (field = update_fields; field; field = field->next) { ast_uri_encode(field->name, buf1, sizeof(buf1), ast_uri_http); ast_uri_encode(field->value, buf2, sizeof(buf2), ast_uri_http); ast_str_append(&query, 0, "%s%s=%s", !start ? "" : "&", buf1, buf2); start = 0; } ast_str_append(&query, 0, ")}"); /* Proxies work, by setting CURLOPT options in the [globals] section of * extensions.conf. Unfortunately, this means preloading pbx_config.so * so that they have an opportunity to be set prior to startup realtime * queries. */ ast_str_substitute_variables(&buffer, 0, NULL, ast_str_buffer(query)); /* Line oriented output */ stringp = ast_str_buffer(buffer); while (*stringp <= ' ') { stringp++; } sscanf(stringp, "%30d", &rowcount); if (rowcount >= 0) { return (int)rowcount; } return -1; }
/*! \brief Function which adds ICE attributes to a media stream */ static void add_ice_to_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media, pj_pool_t *pool, pjmedia_sdp_media *media) { struct ast_rtp_engine_ice *ice; struct ao2_container *candidates; const char *username, *password; pj_str_t stmp; pjmedia_sdp_attr *attr; struct ao2_iterator it_candidates; struct ast_rtp_engine_ice_candidate *candidate; if (!session->endpoint->media.rtp.ice_support || !(ice = ast_rtp_instance_get_ice(session_media->rtp)) || !(candidates = ice->get_local_candidates(session_media->rtp))) { return; } if ((username = ice->get_ufrag(session_media->rtp))) { attr = pjmedia_sdp_attr_create(pool, "ice-ufrag", pj_cstr(&stmp, username)); media->attr[media->attr_count++] = attr; } if ((password = ice->get_password(session_media->rtp))) { attr = pjmedia_sdp_attr_create(pool, "ice-pwd", pj_cstr(&stmp, password)); media->attr[media->attr_count++] = attr; } it_candidates = ao2_iterator_init(candidates, 0); for (; (candidate = ao2_iterator_next(&it_candidates)); ao2_ref(candidate, -1)) { struct ast_str *attr_candidate = ast_str_create(128); ast_str_set(&attr_candidate, -1, "%s %u %s %d %s ", candidate->foundation, candidate->id, candidate->transport, candidate->priority, ast_sockaddr_stringify_addr_remote(&candidate->address)); ast_str_append(&attr_candidate, -1, "%s typ ", ast_sockaddr_stringify_port(&candidate->address)); switch (candidate->type) { case AST_RTP_ICE_CANDIDATE_TYPE_HOST: ast_str_append(&attr_candidate, -1, "host"); break; case AST_RTP_ICE_CANDIDATE_TYPE_SRFLX: ast_str_append(&attr_candidate, -1, "srflx"); break; case AST_RTP_ICE_CANDIDATE_TYPE_RELAYED: ast_str_append(&attr_candidate, -1, "relay"); break; } if (!ast_sockaddr_isnull(&candidate->relay_address)) { ast_str_append(&attr_candidate, -1, " raddr %s rport", ast_sockaddr_stringify_addr_remote(&candidate->relay_address)); ast_str_append(&attr_candidate, -1, " %s", ast_sockaddr_stringify_port(&candidate->relay_address)); } attr = pjmedia_sdp_attr_create(pool, "candidate", pj_cstr(&stmp, ast_str_buffer(attr_candidate))); media->attr[media->attr_count++] = attr; ast_free(attr_candidate); } ao2_iterator_destroy(&it_candidates); ao2_ref(candidates, -1); }
static int __ast_http_post_load(int reload) { struct ast_config *cfg; struct ast_variable *v; struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; cfg = ast_config_load2("http.conf", "http", config_flags); if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) { return 0; } if (reload) { ast_http_uri_unlink_all_with_key(__FILE__); } if (cfg) { for (v = ast_variable_browse(cfg, "general"); v; v = v->next) { if (!strcasecmp(v->name, "prefix")) { ast_copy_string(prefix, v->value, sizeof(prefix)); if (prefix[strlen(prefix)] == '/') { prefix[strlen(prefix)] = '\0'; } } } for (v = ast_variable_browse(cfg, "post_mappings"); v; v = v->next) { struct ast_http_uri *urih; struct ast_str *ds; if (!(urih = ast_calloc(sizeof(*urih), 1))) { ast_config_destroy(cfg); return -1; } if (!(ds = ast_str_create(32))) { ast_free(urih); ast_config_destroy(cfg); return -1; } urih->description = ast_strdup("HTTP POST mapping"); urih->uri = ast_strdup(v->name); ast_str_set(&ds, 0, "%s", v->value); urih->data = ds; urih->has_subtree = 0; urih->supports_get = 0; urih->supports_post = 1; urih->callback = http_post_callback; urih->key = __FILE__; urih->mallocd = urih->dmallocd = 1; ast_http_uri_link(urih); } ast_config_destroy(cfg); } return 0; }
/*! * \brief Execute an DELETE query * \param url * \param unused * \param keyfield where clause field * \param lookup value of field for where clause * \param ap list containing one or more field/value set(s) * * Delete a row from a database table, prepare the sql statement using keyfield and lookup * control the number of records to change. Additional params to match rows are stored in ap list. * Sub-in the values to the prepared statement and execute it. * * \retval number of rows affected * \retval -1 on failure */ static int destroy_curl(const char *url, const char *unused, const char *keyfield, const char *lookup, va_list ap) { struct ast_str *query; char buf1[200], buf2[200]; const char *newparam, *newval; char *stringp; int i, rowcount = -1; const int EncodeSpecialChars = 1, bufsize = 100; char *buffer; if (!ast_custom_function_find("CURL")) { ast_log(LOG_ERROR, "func_curl.so must be loaded in order to use res_config_curl.so!!\n"); return -1; } if (!(query = ast_str_create(1000))) return -1; if (!(buffer = ast_malloc(bufsize))) { ast_free(query); return -1; } ast_uri_encode(keyfield, buf1, sizeof(buf1), EncodeSpecialChars); ast_uri_encode(lookup, buf2, sizeof(buf2), EncodeSpecialChars); ast_str_set(&query, 0, "${CURL(%s/destroy,%s=%s&", url, buf1, buf2); for (i = 0; (newparam = va_arg(ap, const char *)); i++) { newval = va_arg(ap, const char *); ast_uri_encode(newparam, buf1, sizeof(buf1), EncodeSpecialChars); ast_uri_encode(newval, buf2, sizeof(buf2), EncodeSpecialChars); ast_str_append(&query, 0, "%s%s=%s", i > 0 ? "&" : "", buf1, buf2); } va_end(ap); ast_str_append(&query, 0, ")}"); pbx_substitute_variables_helper(NULL, query->str, buffer, bufsize); /* Line oriented output */ stringp = buffer; while (*stringp <= ' ') stringp++; sscanf(stringp, "%d", &rowcount); ast_free(buffer); ast_free(query); if (rowcount >= 0) return (int)rowcount; return -1; }
static int manager_bridge_info(struct mansession *s, const struct message *m) { const char *id = astman_get_header(m, "ActionID"); const char *bridge_uniqueid = astman_get_header(m, "BridgeUniqueid"); RAII_VAR(struct ast_str *, id_text, ast_str_create(128), ast_free); RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup); RAII_VAR(struct ast_str *, bridge_info, NULL, ast_free); struct ast_bridge_snapshot *snapshot; struct bridge_list_data list_data; if (!id_text) { astman_send_error(s, m, "Internal error"); return -1; } if (ast_strlen_zero(bridge_uniqueid)) { astman_send_error(s, m, "BridgeUniqueid must be provided"); return 0; } if (!ast_strlen_zero(id)) { ast_str_set(&id_text, 0, "ActionID: %s\r\n", id); } msg = stasis_cache_get(ast_bridge_cache(), ast_bridge_snapshot_type(), bridge_uniqueid); if (!msg) { astman_send_error(s, m, "Specified BridgeUniqueid not found"); return 0; } snapshot = stasis_message_data(msg); bridge_info = ast_manager_build_bridge_state_string(snapshot); if (!bridge_info) { astman_send_error(s, m, "Internal error"); return -1; } astman_send_listack(s, m, "Bridge channel listing will follow", "start"); list_data.id_text = ast_str_buffer(id_text); list_data.count = 0; ao2_callback_data(snapshot->channels, OBJ_NODATA, send_bridge_info_item_cb, s, &list_data); astman_send_list_complete_start(s, m, "BridgeInfoComplete", list_data.count); if (!ast_strlen_zero(ast_str_buffer(bridge_info))) { astman_append(s, "%s", ast_str_buffer(bridge_info)); } astman_send_list_complete_end(s); return 0; }
static void *transport_websocket_init(const struct ast_socket_io_session *session) { struct ast_websocket *ws; struct ast_str *uri = ast_str_create(128); enum ast_websocket_result result; struct ast_uri *session_uri = ast_socket_io_uri(session); struct ast_tls_config *tls_cfg = NULL; if (!uri) { ast_log(LOG_ERROR, "Unable to allocate websocket uri\n"); return NULL; } ast_str_set(&uri, 0, "%s://%s:%s/socket.io/%s/websocket/%s", ast_uri_is_secure(session_uri) ? "wss" : "ws", ast_uri_host(session_uri), ast_uri_port(session_uri), SOCKET_IO_VERSION, ast_socket_io_id(session)); if (!ast_strlen_zero(ast_uri_query(session_uri))) { ast_str_append(&uri, 0, "?%s", ast_uri_query(session_uri)); } if (ast_uri_is_secure(session_uri)) { /* The websocket client expects a copy of the TLS configuration so provide it */ tls_cfg = ast_calloc(1, sizeof(*tls_cfg)); ast_set_flag(&tls_cfg->flags, AST_SSL_DONT_VERIFY_SERVER); } ws = ast_websocket_client_create( ast_str_buffer(uri), "socket.io", tls_cfg, &result); ast_free(uri); if (ws) { struct protoent *p; p = getprotobyname("tcp"); if (p) { int arg = 1; if (setsockopt(ast_websocket_fd(ws), p->p_proto, TCP_NODELAY, (char *) &arg, sizeof(arg) ) < 0) { ast_log(LOG_WARNING, "Failed to set TCP_NODELAY on HTTP connection: %s\n", strerror(errno)); ast_log(LOG_WARNING, "Some HTTP requests may be slow to respond.\n"); } } ast_websocket_set_nonblock(ws); } return ws; }
static int require_curl(const char *url, const char *unused, va_list ap) { struct ast_str *query, *buffer; char *elm, field[256]; int type, size, i = 0; if (!ast_custom_function_find("CURL")) { ast_log(LOG_ERROR, "func_curl.so must be loaded in order to use res_config_curl.so!!\n"); return -1; } if (!(query = ast_str_thread_get(&query_buf, 100))) { return -1; } if (!(buffer = ast_str_thread_get(&result_buf, 16))) { return -1; } ast_str_set(&query, 0, "${CURL(%s/require,", url); while ((elm = va_arg(ap, char *))) { type = va_arg(ap, require_type); size = va_arg(ap, int); ast_uri_encode(elm, field, sizeof(field), ast_uri_http); ast_str_append(&query, 0, "%s%s=%s%%3A%d", i > 0 ? "&" : "", field, type == RQ_CHAR ? "char" : type == RQ_INTEGER1 ? "integer1" : type == RQ_UINTEGER1 ? "uinteger1" : type == RQ_INTEGER2 ? "integer2" : type == RQ_UINTEGER2 ? "uinteger2" : type == RQ_INTEGER3 ? "integer3" : type == RQ_UINTEGER3 ? "uinteger3" : type == RQ_INTEGER4 ? "integer4" : type == RQ_UINTEGER4 ? "uinteger4" : type == RQ_INTEGER8 ? "integer8" : type == RQ_UINTEGER8 ? "uinteger8" : type == RQ_DATE ? "date" : type == RQ_DATETIME ? "datetime" : type == RQ_FLOAT ? "float" : "unknown", size); i++; } ast_str_append(&query, 0, ")}"); ast_str_substitute_variables(&buffer, 0, NULL, ast_str_buffer(query)); return atoi(ast_str_buffer(buffer)); }
static struct ast_sip_aor *find_aor(struct ast_sip_endpoint *endpoint, pjsip_uri *uri) { char *configured_aors, *aor_name; pjsip_sip_uri *sip_uri; char *domain_name; RAII_VAR(struct ast_str *, id, NULL, ast_free); if (ast_strlen_zero(endpoint->aors)) { return NULL; } sip_uri = pjsip_uri_get_uri(uri); domain_name = ast_alloca(sip_uri->host.slen + 1); ast_copy_pj_str(domain_name, &sip_uri->host, sip_uri->host.slen + 1); configured_aors = ast_strdupa(endpoint->aors); /* Iterate the configured AORs to see if the user or the user+domain match */ while ((aor_name = strsep(&configured_aors, ","))) { struct ast_sip_domain_alias *alias = NULL; if (!pj_strcmp2(&sip_uri->user, aor_name)) { break; } if (!id && !(id = ast_str_create(sip_uri->user.slen + sip_uri->host.slen + 2))) { return NULL; } ast_str_set(&id, 0, "%.*s@", (int)sip_uri->user.slen, sip_uri->user.ptr); if ((alias = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "domain_alias", domain_name))) { ast_str_append(&id, 0, "%s", alias->domain); ao2_cleanup(alias); } else { ast_str_append(&id, 0, "%s", domain_name); } if (!strcmp(aor_name, ast_str_buffer(id))) { ast_free(id); break; } } if (ast_strlen_zero(aor_name)) { return NULL; } return ast_sip_location_retrieve_aor(aor_name); }
/*! * \brief Execute an DELETE query * \param url * \param unused * \param keyfield where clause field * \param lookup value of field for where clause * \param fields list containing one or more field/value set(s) * * Delete a row from a database table, prepare the sql statement using keyfield and lookup * control the number of records to change. Additional params to match rows are stored in ap list. * Sub-in the values to the prepared statement and execute it. * * \retval number of rows affected * \retval -1 on failure */ static int destroy_curl(const char *url, const char *unused, const char *keyfield, const char *lookup, const struct ast_variable *fields) { struct ast_str *query, *buffer; char buf1[200], buf2[200]; const struct ast_variable *field; char *stringp; int start = 1, rowcount = -1; if (!ast_custom_function_find("CURL")) { ast_log(LOG_ERROR, "func_curl.so must be loaded in order to use res_config_curl.so!!\n"); return -1; } if (!(query = ast_str_thread_get(&query_buf, 1000))) { return -1; } if (!(buffer = ast_str_thread_get(&result_buf, 16))) { return -1; } ast_uri_encode(keyfield, buf1, sizeof(buf1), ast_uri_http); ast_uri_encode(lookup, buf2, sizeof(buf2), ast_uri_http); ast_str_set(&query, 0, "${CURL(%s/destroy,%s=%s&", url, buf1, buf2); for (field = fields; field; field = field->next) { ast_uri_encode(field->name, buf1, sizeof(buf1), ast_uri_http); ast_uri_encode(field->value, buf2, sizeof(buf2), ast_uri_http); ast_str_append(&query, 0, "%s%s=%s", !start ? "&" : "", buf1, buf2); start = 0; } ast_str_append(&query, 0, ")}"); ast_str_substitute_variables(&buffer, 0, NULL, ast_str_buffer(query)); /* Line oriented output */ stringp = ast_str_buffer(buffer); while (*stringp <= ' ') { stringp++; } sscanf(stringp, "%30d", &rowcount); if (rowcount >= 0) { return (int)rowcount; } return -1; }
static int pgsql_reconnect(const char *database) { char my_database[50]; ast_copy_string(my_database, S_OR(database, dbname), sizeof(my_database)); /* mutex lock should have been locked before calling this function. */ if (pgsqlConn && PQstatus(pgsqlConn) != CONNECTION_OK) { PQfinish(pgsqlConn); pgsqlConn = NULL; } /* DB password can legitimately be 0-length */ if ((!pgsqlConn) && (!ast_strlen_zero(dbhost) || !ast_strlen_zero(dbsock)) && !ast_strlen_zero(dbuser) && !ast_strlen_zero(my_database)) { struct ast_str *connInfo = ast_str_create(32); ast_str_set(&connInfo, 0, "host=%s port=%d dbname=%s user=%s", dbhost, dbport, my_database, dbuser); if (!ast_strlen_zero(dbpass)) ast_str_append(&connInfo, 0, " password=%s", dbpass); ast_debug(1, "%u connInfo=%s\n", (unsigned int)connInfo->len, connInfo->str); pgsqlConn = PQconnectdb(connInfo->str); ast_debug(1, "%u connInfo=%s\n", (unsigned int)connInfo->len, connInfo->str); ast_free(connInfo); connInfo = NULL; ast_debug(1, "pgsqlConn=%p\n", pgsqlConn); if (pgsqlConn && PQstatus(pgsqlConn) == CONNECTION_OK) { ast_debug(1, "PostgreSQL RealTime: Successfully connected to database.\n"); connect_time = time(NULL); return 1; } else { ast_log(LOG_ERROR, "PostgreSQL RealTime: Failed to connect database %s on %s: %s\n", dbname, dbhost, PQresultErrorMessage(NULL)); return 0; } } else { ast_debug(1, "PostgreSQL RealTime: One or more of the parameters in the config does not pass our validity checks.\n"); return 1; } }
/*! \brief Builds a manager string based on the contents of a parked call payload */ static struct ast_str *manager_build_parked_call_string(const struct ast_parked_call_payload *payload) { struct ast_str *out = ast_str_create(1024); RAII_VAR(struct ast_str *, parkee_string, NULL, ast_free); RAII_VAR(struct ast_str *, retriever_string, NULL, ast_free); if (!out) { return NULL; } parkee_string = ast_manager_build_channel_state_string_prefix(payload->parkee, "Parkee"); if (!parkee_string) { ast_free(out); return NULL; } if (payload->retriever) { retriever_string = ast_manager_build_channel_state_string_prefix(payload->retriever, "Retriever"); if (!retriever_string) { ast_free(out); return NULL; } } ast_str_set(&out, 0, "%s" /* parkee channel state */ "%s" /* retriever channel state (when available) */ "ParkerDialString: %s\r\n" "Parkinglot: %s\r\n" "ParkingSpace: %u\r\n" "ParkingTimeout: %lu\r\n" "ParkingDuration: %lu\r\n", ast_str_buffer(parkee_string), retriever_string ? ast_str_buffer(retriever_string) : "", payload->parker_dial_string, payload->parkinglot, payload->parkingspace, payload->timeout, payload->duration); return out; }
struct ast_str *ast_manager_build_bridge_state_string_prefix( const struct ast_bridge_snapshot *snapshot, const char *prefix) { struct ast_str *out = ast_str_create(128); int res; if (!out) { return NULL; } res = ast_str_set(&out, 0, "%sBridgeUniqueid: %s\r\n" "%sBridgeType: %s\r\n" "%sBridgeTechnology: %s\r\n" "%sBridgeCreator: %s\r\n" "%sBridgeName: %s\r\n" "%sBridgeNumChannels: %u\r\n" "%sBridgeVideoSourceMode: %s\r\n", prefix, snapshot->uniqueid, prefix, snapshot->subclass, prefix, snapshot->technology, prefix, ast_strlen_zero(snapshot->creator) ? "<unknown>": snapshot->creator, prefix, ast_strlen_zero(snapshot->name) ? "<unknown>": snapshot->name, prefix, snapshot->num_channels, prefix, ast_bridge_video_mode_to_string(snapshot->video_mode)); if (!res) { ast_free(out); return NULL; } if (snapshot->video_mode != AST_BRIDGE_VIDEO_MODE_NONE && !ast_strlen_zero(snapshot->video_source_id)) { res = ast_str_append(&out, 0, "%sBridgeVideoSource: %s\r\n", prefix, snapshot->video_source_id); if (!res) { ast_free(out); return NULL; } } return out; }
struct ast_json *ast_json_ipaddr(const struct ast_sockaddr *addr, enum ast_transport transport_type) { struct ast_str *string = ast_str_alloca(64); if (!string) { return NULL; } ast_str_set(&string, 0, (ast_sockaddr_is_ipv4(addr) || ast_sockaddr_is_ipv4_mapped(addr)) ? "IPV4/" : "IPV6/"); if (transport_type) { char *transport_string = NULL; /* NOTE: None will be applied if multiple transport types are specified in transport_type */ switch(transport_type) { case AST_TRANSPORT_UDP: transport_string = "UDP"; break; case AST_TRANSPORT_TCP: transport_string = "TCP"; break; case AST_TRANSPORT_TLS: transport_string = "TLS"; break; case AST_TRANSPORT_WS: transport_string = "WS"; break; case AST_TRANSPORT_WSS: transport_string = "WSS"; break; } if (transport_string) { ast_str_append(&string, 0, "%s/", transport_string); } } ast_str_append(&string, 0, "%s", ast_sockaddr_stringify_addr(addr)); ast_str_append(&string, 0, "/%s", ast_sockaddr_stringify_port(addr)); return ast_json_string_create(ast_str_buffer(string)); }
static int manager_bridges_list(struct mansession *s, const struct message *m) { const char *id = astman_get_header(m, "ActionID"); const char *type_filter = astman_get_header(m, "BridgeType"); RAII_VAR(struct ast_str *, id_text, ast_str_create(128), ast_free); RAII_VAR(struct ao2_container *, bridges, NULL, ao2_cleanup); struct bridge_list_data list_data; if (!id_text) { astman_send_error(s, m, "Internal error"); return -1; } if (!ast_strlen_zero(id)) { ast_str_set(&id_text, 0, "ActionID: %s\r\n", id); } bridges = stasis_cache_dump(ast_bridge_cache(), ast_bridge_snapshot_type()); if (!bridges) { astman_send_error(s, m, "Internal error"); return -1; } astman_send_listack(s, m, "Bridge listing will follow", "start"); if (!ast_strlen_zero(type_filter)) { char *type_filter_dup = ast_strdupa(type_filter); ao2_callback(bridges, OBJ_MULTIPLE | OBJ_NODATA | OBJ_UNLINK, filter_bridge_type_cb, type_filter_dup); } list_data.id_text = ast_str_buffer(id_text); list_data.count = 0; ao2_callback_data(bridges, OBJ_NODATA, send_bridge_list_item_cb, s, &list_data); astman_send_list_complete_start(s, m, "BridgeListComplete", list_data.count); astman_send_list_complete_end(s); return 0; }
static int build_path_data(pjsip_rx_data *rdata, struct ast_str **path_str) { pjsip_generic_string_hdr *path_hdr = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &path_hdr_name, NULL); if (!path_hdr) { return 0; } *path_str = ast_str_create(64); if (!path_str) { return -1; } ast_str_set(path_str, 0, "%.*s", (int)path_hdr->hvalue.slen, path_hdr->hvalue.ptr); while ((path_hdr = (pjsip_generic_string_hdr *) pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &path_hdr_name, path_hdr->next))) { ast_str_append(path_str, 0, ",%.*s", (int)path_hdr->hvalue.slen, path_hdr->hvalue.ptr); } return 0; }
/*! * \brief Subscription callback for all channel messages. * \param data Data pointer given when creating the subscription. * \param sub This subscription. * \param topic The topic the message was posted to. This is not necessarily the * topic you subscribed to, since messages may be forwarded between * topics. * \param message The message itself. */ static void statsmaker(void *data, struct stasis_subscription *sub, struct stasis_message *message) { RAII_VAR(struct ast_str *, metric, NULL, ast_free); if (stasis_subscription_final_message(sub, message)) { /* Normally, data points to an object that must be cleaned up. * The final message is an unsubscribe notification that's * guaranteed to be the last message this subscription receives. * This would be a safe place to kick off any needed cleanup. */ return; } /* For no good reason, count message types */ metric = ast_str_create(80); if (metric) { ast_str_set(&metric, 0, "stasis.message.%s", stasis_message_type_name(stasis_message_type(message))); ast_statsd_log(ast_str_buffer(metric), AST_STATSD_METER, 1); } }
/* * \brief Allocate a threadpool * * This is implemented as a taskprocessor listener's alloc callback. This * is because the threadpool exists as the private data on a taskprocessor * listener. * * \param name The name of the threadpool. * \param options The options the threadpool uses. * \retval NULL Could not initialize threadpool properly * \retval non-NULL The newly-allocated threadpool */ static struct ast_threadpool *threadpool_alloc(const char *name, const struct ast_threadpool_options *options) { RAII_VAR(struct ast_threadpool *, pool, NULL, ao2_cleanup); struct ast_str *control_tps_name; pool = ao2_alloc(sizeof(*pool), threadpool_destructor); control_tps_name = ast_str_create(64); if (!pool || !control_tps_name) { ast_free(control_tps_name); return NULL; } ast_str_set(&control_tps_name, 0, "%s-control", name); pool->control_tps = ast_taskprocessor_get(ast_str_buffer(control_tps_name), TPS_REF_DEFAULT); ast_free(control_tps_name); if (!pool->control_tps) { return NULL; } pool->active_threads = ao2_container_alloc(THREAD_BUCKETS, worker_thread_hash, worker_thread_cmp); if (!pool->active_threads) { return NULL; } pool->idle_threads = ao2_container_alloc(THREAD_BUCKETS, worker_thread_hash, worker_thread_cmp); if (!pool->idle_threads) { return NULL; } pool->zombie_threads = ao2_container_alloc(THREAD_BUCKETS, worker_thread_hash, worker_thread_cmp); if (!pool->zombie_threads) { return NULL; } pool->options = *options; ao2_ref(pool, +1); return pool; }
static int add_crypto_to_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media, pj_pool_t *pool, pjmedia_sdp_media *media) { pj_str_t stmp; pjmedia_sdp_attr *attr; enum ast_rtp_dtls_hash hash; const char *crypto_attribute; struct ast_rtp_engine_dtls *dtls; static const pj_str_t STR_NEW = { "new", 3 }; static const pj_str_t STR_EXISTING = { "existing", 8 }; static const pj_str_t STR_ACTIVE = { "active", 6 }; static const pj_str_t STR_PASSIVE = { "passive", 7 }; static const pj_str_t STR_ACTPASS = { "actpass", 7 }; static const pj_str_t STR_HOLDCONN = { "holdconn", 8 }; switch (session_media->encryption) { case AST_SIP_MEDIA_ENCRYPT_NONE: case AST_SIP_MEDIA_TRANSPORT_INVALID: break; case AST_SIP_MEDIA_ENCRYPT_SDES: if (!session_media->srtp) { session_media->srtp = ast_sdp_srtp_alloc(); if (!session_media->srtp) { return -1; } } crypto_attribute = ast_sdp_srtp_get_attrib(session_media->srtp, 0 /* DTLS running? No */, session->endpoint->media.rtp.srtp_tag_32 /* 32 byte tag length? */); if (!crypto_attribute) { /* No crypto attribute to add, bad news */ return -1; } attr = pjmedia_sdp_attr_create(pool, "crypto", pj_cstr(&stmp, crypto_attribute)); media->attr[media->attr_count++] = attr; break; case AST_SIP_MEDIA_ENCRYPT_DTLS: if (setup_dtls_srtp(session, session_media)) { return -1; } dtls = ast_rtp_instance_get_dtls(session_media->rtp); if (!dtls) { return -1; } switch (dtls->get_connection(session_media->rtp)) { case AST_RTP_DTLS_CONNECTION_NEW: attr = pjmedia_sdp_attr_create(pool, "connection", &STR_NEW); media->attr[media->attr_count++] = attr; break; case AST_RTP_DTLS_CONNECTION_EXISTING: attr = pjmedia_sdp_attr_create(pool, "connection", &STR_EXISTING); media->attr[media->attr_count++] = attr; break; default: break; } switch (dtls->get_setup(session_media->rtp)) { case AST_RTP_DTLS_SETUP_ACTIVE: attr = pjmedia_sdp_attr_create(pool, "setup", &STR_ACTIVE); media->attr[media->attr_count++] = attr; break; case AST_RTP_DTLS_SETUP_PASSIVE: attr = pjmedia_sdp_attr_create(pool, "setup", &STR_PASSIVE); media->attr[media->attr_count++] = attr; break; case AST_RTP_DTLS_SETUP_ACTPASS: attr = pjmedia_sdp_attr_create(pool, "setup", &STR_ACTPASS); media->attr[media->attr_count++] = attr; break; case AST_RTP_DTLS_SETUP_HOLDCONN: attr = pjmedia_sdp_attr_create(pool, "setup", &STR_HOLDCONN); media->attr[media->attr_count++] = attr; break; default: break; } hash = dtls->get_fingerprint_hash(session_media->rtp); crypto_attribute = dtls->get_fingerprint(session_media->rtp); if (crypto_attribute && (hash == AST_RTP_DTLS_HASH_SHA1 || hash == AST_RTP_DTLS_HASH_SHA256)) { RAII_VAR(struct ast_str *, fingerprint, ast_str_create(64), ast_free); if (!fingerprint) { return -1; } if (hash == AST_RTP_DTLS_HASH_SHA1) { ast_str_set(&fingerprint, 0, "SHA-1 %s", crypto_attribute); } else { ast_str_set(&fingerprint, 0, "SHA-256 %s", crypto_attribute); } attr = pjmedia_sdp_attr_create(pool, "fingerprint", pj_cstr(&stmp, ast_str_buffer(fingerprint))); media->attr[media->attr_count++] = attr; } break; }
/*! * \brief Execute a curl query and return ast_variable list * \param url The base URL from which to retrieve data * \param unused Not currently used * \param fields list containing one or more field/operator/value set. * * \retval var on success * \retval NULL on failure */ static struct ast_variable *realtime_curl(const char *url, const char *unused, const struct ast_variable *fields) { struct ast_str *query, *buffer; char buf1[256], buf2[256]; const struct ast_variable *field; char *stringp, *pair, *key; unsigned int start = 1; struct ast_variable *var = NULL, *prev = NULL; if (!ast_custom_function_find("CURL")) { ast_log(LOG_ERROR, "func_curl.so must be loaded in order to use res_config_curl.so!!\n"); return NULL; } if (!(query = ast_str_thread_get(&query_buf, 16))) { return NULL; } if (!(buffer = ast_str_thread_get(&result_buf, 16))) { return NULL; } ast_str_set(&query, 0, "${CURL(%s/single,", url); for (field = fields; field; field = field->next) { ast_uri_encode(field->name, buf1, sizeof(buf1), ast_uri_http); ast_uri_encode(field->value, buf2, sizeof(buf2), ast_uri_http); ast_str_append(&query, 0, "%s%s=%s", !start ? "&" : "", buf1, buf2); start = 0; } ast_str_append(&query, 0, ")}"); ast_str_substitute_variables(&buffer, 0, NULL, ast_str_buffer(query)); /* Remove any trailing newline characters */ if ((stringp = strchr(ast_str_buffer(buffer), '\r')) || (stringp = strchr(ast_str_buffer(buffer), '\n'))) { *stringp = '\0'; } stringp = ast_str_buffer(buffer); while ((pair = strsep(&stringp, "&"))) { key = strsep(&pair, "="); ast_uri_decode(key, ast_uri_http); if (pair) { ast_uri_decode(pair, ast_uri_http); } if (!ast_strlen_zero(key)) { if (prev) { prev->next = ast_variable_new(key, S_OR(pair, ""), ""); if (prev->next) { prev = prev->next; } } else { prev = var = ast_variable_new(key, S_OR(pair, ""), ""); } } } return var; }