38 #include <curl/curl.h>
64 char buf1[256], buf2[256];
66 char *stringp, *
pair, *key;
67 unsigned int start = 1;
70 if (!ast_custom_function_find(
"CURL")) {
71 ast_log(LOG_ERROR,
"func_curl.so must be loaded in order to use res_config_curl.so!!\n");
85 for (field = fields; field; field = field->
next) {
88 ast_str_append(&query, 0,
"%s%s=%s", !start ?
"&" :
"", buf1, buf2);
101 while ((pair = strsep(&stringp,
"&"))) {
102 key = strsep(&pair,
"=");
108 if (!ast_strlen_zero(key)) {
110 prev->next = ast_variable_new(key,
S_OR(pair,
""),
"");
115 prev = var = ast_variable_new(key,
S_OR(pair,
""),
"");
134 struct ast_str *query, *buffer;
135 char buf1[256], buf2[256];
137 char *stringp, *line, *
pair, *key, *initfield = NULL;
143 if (!ast_custom_function_find(
"CURL")) {
144 ast_log(LOG_ERROR,
"func_curl.so must be loaded in order to use res_config_curl.so!!\n");
158 for (field = fields; field; field = field->
next) {
162 if ((op = strchr(initfield,
' ')))
167 ast_str_append(&query, 0,
"%s%s=%s", !start ?
"&" :
"", buf1, buf2);
183 while ((line = strsep(&stringp,
"\r\n"))) {
184 if (ast_strlen_zero(line)) {
193 while ((pair = strsep(&line,
"&"))) {
194 key = strsep(&pair,
"=");
200 if (!strcasecmp(key, initfield) && pair) {
201 ast_category_rename(cat, pair);
204 if (!ast_strlen_zero(key)) {
205 var = ast_variable_new(key,
S_OR(pair,
""),
"");
206 ast_variable_append(cat, var);
232 static int update_curl(
const char *url,
const char *unused,
const char *keyfield,
const char *lookup,
const struct ast_variable *fields)
234 struct ast_str *query, *buffer;
235 char buf1[256], buf2[256];
238 int start = 1, rowcount = -1;
240 if (!ast_custom_function_find(
"CURL")) {
241 ast_log(LOG_ERROR,
"func_curl.so must be loaded in order to use res_config_curl.so!!\n");
255 ast_str_set(&query, 0,
"${CURL(%s/update?%s=%s,", url, buf1, buf2);
257 for (field = fields; field; field = field->
next) {
260 ast_str_append(&query, 0,
"%s%s=%s", !start ?
"&" :
"", buf1, buf2);
269 while (*stringp <=
' ') {
272 sscanf(stringp,
"%30d", &rowcount);
275 return (
int)rowcount;
281 static int update2_curl(
const char *url,
const char *unused,
const struct ast_variable *lookup_fields,
const struct ast_variable *update_fields)
283 struct ast_str *query, *buffer;
284 char buf1[200], buf2[200];
287 unsigned int start = 1;
290 if (!ast_custom_function_find(
"CURL")) {
291 ast_log(LOG_ERROR,
"func_curl.so must be loaded in order to use res_config_curl.so!!\n");
304 for (field = lookup_fields; field; field = field->
next) {
307 ast_str_append(&query, 0,
"%s%s=%s", !start ?
"" :
"&", buf1, buf2);
313 for (field = update_fields; field; field = field->
next) {
316 ast_str_append(&query, 0,
"%s%s=%s", !start ?
"" :
"&", buf1, buf2);
329 while (*stringp <=
' ') {
332 sscanf(stringp,
"%30d", &rowcount);
335 return (
int)rowcount;
356 struct ast_str *query, *buffer;
357 char buf1[256], buf2[256];
360 int start = 1, rowcount = -1;
362 if (!ast_custom_function_find(
"CURL")) {
363 ast_log(LOG_ERROR,
"func_curl.so must be loaded in order to use res_config_curl.so!!\n");
377 for (field = fields; field; field = field->
next) {
380 ast_str_append(&query, 0,
"%s%s=%s", !start ?
"&" :
"", buf1, buf2);
388 while (*stringp <=
' ') {
391 sscanf(stringp,
"%30d", &rowcount);
415 static int destroy_curl(
const char *url,
const char *unused,
const char *keyfield,
const char *lookup,
const struct ast_variable *fields)
417 struct ast_str *query, *buffer;
418 char buf1[200], buf2[200];
421 int start = 1, rowcount = -1;
423 if (!ast_custom_function_find(
"CURL")) {
424 ast_log(LOG_ERROR,
"func_curl.so must be loaded in order to use res_config_curl.so!!\n");
438 ast_str_set(&query, 0,
"${CURL(%s/destroy,%s=%s&", url, buf1, buf2);
440 for (field = fields; field; field = field->
next) {
443 ast_str_append(&query, 0,
"%s%s=%s", !start ?
"&" :
"", buf1, buf2);
452 while (*stringp <=
' ') {
455 sscanf(stringp,
"%30d", &rowcount);
458 return (
int)rowcount;
464 static int require_curl(
const char *url,
const char *unused, va_list ap)
466 struct ast_str *query, *buffer;
467 char *elm, field[256];
468 int type, size, i = 0;
470 if (!ast_custom_function_find(
"CURL")) {
471 ast_log(LOG_ERROR,
"func_curl.so must be loaded in order to use res_config_curl.so!!\n");
485 while ((elm = va_arg(ap,
char *))) {
487 size = va_arg(ap,
int);
492 type == RQ_CHAR ?
"char" :
493 type == RQ_INTEGER1 ?
"integer1" :
494 type == RQ_UINTEGER1 ?
"uinteger1" :
495 type == RQ_INTEGER2 ?
"integer2" :
496 type == RQ_UINTEGER2 ?
"uinteger2" :
497 type == RQ_INTEGER3 ?
"integer3" :
498 type == RQ_UINTEGER3 ?
"uinteger3" :
499 type == RQ_INTEGER4 ?
"integer4" :
500 type == RQ_UINTEGER4 ?
"uinteger4" :
501 type == RQ_INTEGER8 ?
"integer8" :
502 type == RQ_UINTEGER8 ?
"uinteger8" :
503 type == RQ_DATE ?
"date" :
504 type == RQ_DATETIME ?
"datetime" :
505 type == RQ_FLOAT ?
"float" :
515 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)
517 struct ast_str *query, *buffer;
519 char *stringp, *line, *
pair, *key;
520 int last_cat_metric = -1, cat_metric = -1;
523 char *category =
"", *var_name =
"", *var_val =
"";
526 if (!ast_custom_function_find(
"CURL")) {
527 ast_log(LOG_ERROR,
"func_curl.so must be loaded in order to use res_config_curl.so!!\n");
540 ast_str_set(&query, 0,
"${CURL(%s/static?file=%s)}", url, buf1);
549 while ((line = strsep(&stringp,
"\r\n"))) {
550 if (ast_strlen_zero(line)) {
554 while ((pair = strsep(&line,
"&"))) {
555 key = strsep(&pair,
"=");
561 if (!strcasecmp(key,
"category")) {
562 category =
S_OR(pair,
"");
563 }
else if (!strcasecmp(key,
"var_name")) {
564 var_name =
S_OR(pair,
"");
565 }
else if (!strcasecmp(key,
"var_val")) {
566 var_val =
S_OR(pair,
"");
567 }
else if (!strcasecmp(key,
"cat_metric")) {
568 cat_metric = pair ? atoi(pair) : 0;
572 if (!strcmp(var_name,
"#include")) {
573 if (!ast_config_internal_load(var_val, cfg, loader_flags,
"", who_asked))
577 if (!cat || strcmp(category, cur_cat) || last_cat_metric != cat_metric) {
583 last_cat_metric = cat_metric;
586 ast_variable_append(cat, ast_variable_new(var_name, var_val,
""));
594 .load_func = config_curl,
600 .update2_func = update2_curl,
601 .require_func = require_curl,
604 static int reload_module(
void)
612 }
else if (cfg == CONFIG_STATUS_FILEINVALID) {
613 ast_log(LOG_WARNING,
"res_curl.conf could not be parsed!\n");
617 if (!(var = ast_variable_browse(cfg,
"globals")) && !(var = ast_variable_browse(cfg,
"global")) && !(var = ast_variable_browse(cfg,
"general"))) {
618 ast_log(LOG_WARNING,
"[globals] not found in res_curl.conf\n");
623 for (; var; var = var->
next) {
624 if (strncmp(var->
name,
"CURLOPT(", 8)) {
626 snprintf(name,
sizeof(name),
"CURLOPT(%s)", var->
name);
636 static int unload_module(
void)
643 static int load_module(
void)
652 AST_MODULE_INFO(
ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER,
"Realtime Curl configuration",
653 .support_level = AST_MODULE_SUPPORT_CORE,
655 .unload = unload_module,
656 .reload = reload_module,
658 .requires =
"extconfig,res_curl,func_curl",
void ast_uri_decode(char *s, struct ast_flags spec)
Decode URI, URN, URL (overwrite string)
struct ast_variable * next
#define AST_THREADSTORAGE(name)
Define a thread storage variable.
require_type
Types used in ast_realtime_require_field.
Asterisk locking-related definitions:
Asterisk main include file. File version handling, generic pbx functions.
static int destroy_curl(const char *url, const char *unused, const char *keyfield, const char *lookup, const struct ast_variable *fields)
Execute an DELETE query.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
static struct ast_config * realtime_multi_curl(const char *url, const char *unused, const struct ast_variable *fields)
Execute an Select query and return ast_config list.
Structure for variables, used for configurations and for channel variables.
char * ast_uri_encode(const char *string, char *outbuf, int buflen, struct ast_flags spec)
Turn text string to URI-encoded XX version.
void ast_str_substitute_variables(struct ast_str **buf, ssize_t maxlen, struct ast_channel *chan, const char *templ)
int ast_config_engine_deregister(struct ast_config_engine *del)
Deregister config engine.
struct ast_category * ast_config_get_current_category(const struct ast_config *cfg)
Retrieve the current category name being built.
int ast_config_engine_register(struct ast_config_engine *newconfig)
Register config engine.
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
#define ast_strdup(str)
A wrapper for strdup()
Generic File Format Support. Should be included by clients of the file handling routines. File service providers should instead include mod_format.h.
Definitions to aid in the use of thread local storage.
Configuration engine structure, used to define realtime drivers.
static struct ast_variable * realtime_curl(const char *url, const char *unused, const struct ast_variable *fields)
Execute a curl query and return ast_variable list.
void ast_category_append(struct ast_config *config, struct ast_category *category)
Appends a category to a config.
#define ast_category_new_anonymous()
Create a nameless category that is not backed by a file.
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Configuration File Parser.
#define ast_config_load(filename, flags)
Load a config file.
General Asterisk PBX channel definitions.
struct ast_config * ast_config_new(void)
Create a new base configuration structure.
Core PBX routines and definitions.
Support for dynamic strings.
static int store_curl(const char *url, const char *unused, const struct ast_variable *fields)
Execute an INSERT query.
#define ast_category_new_dynamic(name)
Create a category that is not backed by a file.
Structure used to handle boolean flags.
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
static int update_curl(const char *url, const char *unused, const char *keyfield, const char *lookup, const struct ast_variable *fields)
Execute an UPDATE query.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
struct ast_str * ast_str_thread_get(struct ast_threadstorage *ts, size_t init_len)
Retrieve a thread locally stored dynamic string.
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
#define ASTERISK_GPL_KEY
The text the key() function should return.
Asterisk module definitions.