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 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 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; }
/*! * \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; }
/*! * \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 ap 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, va_list ap) { struct ast_str *query; char buf1[200], buf2[200]; const char *newparam, *newval; char *stringp, *pair, *key; int i; struct ast_variable *var=NULL, *prev=NULL; const int EncodeSpecialChars = 1, bufsize = 64000; 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 NULL; } if (!(query = ast_str_create(1000))) return NULL; if (!(buffer = ast_malloc(bufsize))) { ast_free(query); return NULL; } ast_str_set(&query, 0, "${CURL(%s/single,", url); 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); /* Remove any trailing newline characters */ if ((stringp = strchr(buffer, '\r')) || (stringp = strchr(buffer, '\n'))) *stringp = '\0'; stringp = buffer; while ((pair = strsep(&stringp, "&"))) { key = strsep(&pair, "="); ast_uri_decode(key); if (pair) ast_uri_decode(pair); 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, ""), ""); } } ast_free(buffer); ast_free(query); return var; }
/*! * \brief Excute an Select query and return ast_config list * \param url * \param unused * \param ap 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, va_list ap) { struct ast_str *query; char buf1[200], buf2[200]; const char *newparam, *newval; char *stringp, *line, *pair, *key, *initfield = NULL; int i; const int EncodeSpecialChars = 1, bufsize = 256000; struct ast_variable *var=NULL; struct ast_config *cfg=NULL; struct ast_category *cat=NULL; 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 NULL; } if (!(query = ast_str_create(1000))) return NULL; if (!(buffer = ast_malloc(bufsize))) { ast_free(query); return NULL; } ast_str_set(&query, 0, "${CURL(%s/multi,", url); for (i = 0; (newparam = va_arg(ap, const char *)); i++) { newval = va_arg(ap, const char *); if (i == 0) { char *op; initfield = ast_strdupa(newparam); if ((op = strchr(initfield, ' '))) *op = '\0'; } 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, ")}"); /* Do the CURL query */ pbx_substitute_variables_helper(NULL, query->str, buffer, bufsize); if (!(cfg = ast_config_new())) goto exit_multi; /* Line oriented output */ stringp = 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); if (pair) ast_uri_decode(pair); 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); } exit_multi: ast_free(buffer); ast_free(query); return cfg; }