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; }
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)); }
/*! * \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 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)); }
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)); }
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 int system_exec_helper(struct ast_channel *chan, const char *data, int failmode) { int res = 0; struct ast_str *buf = ast_str_thread_get(&buf_buf, 16); char *cbuf; if (ast_strlen_zero(data)) { ast_log(LOG_WARNING, "System requires an argument(command)\n"); pbx_builtin_setvar_helper(chan, chanvar, "FAILURE"); return failmode; } ast_autoservice_start(chan); /* Do our thing here */ ast_str_get_encoded_str(&buf, 0, (char *) data); cbuf = ast_str_buffer(buf); if (strchr("\"'", cbuf[0]) && cbuf[ast_str_strlen(buf) - 1] == cbuf[0]) { cbuf[ast_str_strlen(buf) - 1] = '\0'; cbuf++; ast_log(LOG_NOTICE, "It is not necessary to quote the argument to the System application.\n"); } res = ast_safe_system(cbuf); if ((res < 0) && (errno != ECHILD)) { ast_log(LOG_WARNING, "Unable to execute '%s'\n", (char *)data); pbx_builtin_setvar_helper(chan, chanvar, "FAILURE"); res = failmode; } else if (res == 127) { ast_log(LOG_WARNING, "Unable to execute '%s'\n", (char *)data); pbx_builtin_setvar_helper(chan, chanvar, "FAILURE"); res = failmode; } else { if (res < 0) res = 0; if (res != 0) pbx_builtin_setvar_helper(chan, chanvar, "APPERROR"); else pbx_builtin_setvar_helper(chan, chanvar, "SUCCESS"); res = 0; } ast_autoservice_stop(chan); return res; }
static int system_exec_helper(struct ast_channel *chan, void *data, int failmode) { int res = 0; struct ast_str *buf = ast_str_thread_get(&buf_buf, 16); if (ast_strlen_zero(data)) { ast_log(LOG_WARNING, "System requires an argument(command)\n"); pbx_builtin_setvar_helper(chan, chanvar, "FAILURE"); return failmode; } ast_autoservice_start(chan); /* Do our thing here */ ast_str_get_encoded_str(&buf, 0, (char *) data); res = ast_safe_system(ast_str_buffer(buf)); if ((res < 0) && (errno != ECHILD)) { ast_log(LOG_WARNING, "Unable to execute '%s'\n", (char *)data); pbx_builtin_setvar_helper(chan, chanvar, "FAILURE"); res = failmode; } else if (res == 127) { ast_log(LOG_WARNING, "Unable to execute '%s'\n", (char *)data); pbx_builtin_setvar_helper(chan, chanvar, "FAILURE"); res = failmode; } else { if (res < 0) res = 0; if (res != 0) pbx_builtin_setvar_helper(chan, chanvar, "APPERROR"); else pbx_builtin_setvar_helper(chan, chanvar, "SUCCESS"); res = 0; } ast_autoservice_stop(chan); return res; }
static int dumpchan_exec(struct ast_channel *chan, const char *data) { struct ast_str *vars = ast_str_thread_get(&ast_str_thread_global_buf, 16); char info[2048]; int level = 0; static char *line = "================================================================================"; if (!ast_strlen_zero(data)) level = atoi(data); serialize_showchan(chan, info, sizeof(info)); pbx_builtin_serialize_variables(chan, &vars); ast_verb(level, "\n" "Dumping Info For Channel: %s:\n" "%s\n" "Info:\n" "%s\n" "Variables:\n" "%s%s\n", ast_channel_name(chan), line, info, ast_str_buffer(vars), line); return 0; }
/*! * \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; }
static struct ast_config *config_curl(const char *url, const char *unused, const char *file, struct ast_config *cfg, struct ast_flags flags, const char *sugg_incl, const char *who_asked) { struct ast_str *query, *buffer; char buf1[200]; char *stringp, *line, *pair, *key; int last_cat_metric = -1, cat_metric = -1; struct ast_category *cat = NULL; char *cur_cat = ""; char *category = "", *var_name = "", *var_val = ""; struct ast_flags loader_flags = { 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 NULL; } if (!(query = ast_str_thread_get(&query_buf, 100))) { return NULL; } if (!(buffer = ast_str_thread_get(&result_buf, 16))) { return NULL; } ast_uri_encode(file, buf1, sizeof(buf1), ast_uri_http); ast_str_set(&query, 0, "${CURL(%s/static?file=%s)}", url, buf1); /* Do the CURL query */ ast_str_substitute_variables(&buffer, 0, NULL, ast_str_buffer(query)); /* Line oriented output */ stringp = ast_str_buffer(buffer); cat = ast_config_get_current_category(cfg); while ((line = strsep(&stringp, "\r\n"))) { if (ast_strlen_zero(line)) { continue; } while ((pair = strsep(&line, "&"))) { key = strsep(&pair, "="); ast_uri_decode(key, ast_uri_http); if (pair) { ast_uri_decode(pair, ast_uri_http); } if (!strcasecmp(key, "category")) { category = S_OR(pair, ""); } else if (!strcasecmp(key, "var_name")) { var_name = S_OR(pair, ""); } else if (!strcasecmp(key, "var_val")) { var_val = S_OR(pair, ""); } else if (!strcasecmp(key, "cat_metric")) { cat_metric = pair ? atoi(pair) : 0; } } if (!strcmp(var_name, "#include")) { if (!ast_config_internal_load(var_val, cfg, loader_flags, "", who_asked)) return NULL; } if (!cat || strcmp(category, cur_cat) || last_cat_metric != cat_metric) { if (!(cat = ast_category_new(category, "", 99999))) break; cur_cat = category; last_cat_metric = cat_metric; ast_category_append(cfg, cat); } ast_variable_append(cat, ast_variable_new(var_name, var_val, "")); } return cfg; }
/*! * \brief Excute an Select query and return ast_config list * \param url * \param unused * \param fields list containing one or more field/operator/value set. * * \retval struct ast_config pointer on success * \retval NULL on failure */ static struct ast_config *realtime_multi_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, *line, *pair, *key, *initfield = NULL; int start = 1; struct ast_variable *var = NULL; struct ast_config *cfg = NULL; struct ast_category *cat = 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/multi,", url); for (field = fields; field; field = field->next) { if (start) { char *op; initfield = ast_strdupa(field->name); if ((op = strchr(initfield, ' '))) *op = '\0'; } 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, ")}"); /* Do the CURL query */ ast_str_substitute_variables(&buffer, 0, NULL, ast_str_buffer(query)); if (!(cfg = ast_config_new())) { return NULL; } /* Line oriented output */ stringp = ast_str_buffer(buffer); while ((line = strsep(&stringp, "\r\n"))) { if (ast_strlen_zero(line)) { continue; } if (!(cat = ast_category_new("", "", 99999))) { continue; } while ((pair = strsep(&line, "&"))) { key = strsep(&pair, "="); ast_uri_decode(key, ast_uri_http); if (pair) { ast_uri_decode(pair, ast_uri_http); } if (!strcasecmp(key, initfield) && pair) { ast_category_rename(cat, pair); } if (!ast_strlen_zero(key)) { var = ast_variable_new(key, S_OR(pair, ""), ""); ast_variable_append(cat, var); } } ast_category_append(cfg, cat); } return cfg; }
char *ast_sockaddr_stringify_fmt(const struct ast_sockaddr *sa, int format) { struct ast_sockaddr sa_ipv4; const struct ast_sockaddr *sa_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 (ast_sockaddr_isnull(sa)) { return "(null)"; } if (!(str = ast_str_thread_get(&ast_sockaddr_stringify_buf, size))) { return ""; } if (ast_sockaddr_ipv4_mapped(sa, &sa_ipv4)) { sa_tmp = &sa_ipv4; } else { sa_tmp = sa; } if ((e = getnameinfo((struct sockaddr *)&sa_tmp->ss, sa_tmp->len, format & AST_SOCKADDR_STR_ADDR ? host : NULL, format & AST_SOCKADDR_STR_ADDR ? sizeof(host) : 0, format & AST_SOCKADDR_STR_PORT ? port : 0, format & AST_SOCKADDR_STR_PORT ? sizeof(port): 0, NI_NUMERICHOST | NI_NUMERICSERV))) { ast_log(LOG_ERROR, "getnameinfo(): %s\n", gai_strerror(e)); return ""; } if ((format & AST_SOCKADDR_STR_REMOTE) == AST_SOCKADDR_STR_REMOTE) { char *p; if (ast_sockaddr_is_ipv6_link_local(sa) && (p = strchr(host, '%'))) { *p = '\0'; } } switch ((format & AST_SOCKADDR_STR_FORMAT_MASK)) { case AST_SOCKADDR_STR_DEFAULT: ast_str_set(&str, 0, sa_tmp->ss.ss_family == AF_INET6 ? "[%s]:%s" : "%s:%s", host, port); break; case AST_SOCKADDR_STR_ADDR: ast_str_set(&str, 0, "%s", host); break; case AST_SOCKADDR_STR_HOST: ast_str_set(&str, 0, sa_tmp->ss.ss_family == AF_INET6 ? "[%s]" : "%s", host); break; case AST_SOCKADDR_STR_PORT: ast_str_set(&str, 0, "%s", port); break; default: ast_log(LOG_ERROR, "Invalid format\n"); return ""; } return ast_str_buffer(str); }