Wed Jan 8 2020 09:49:49

Asterisk developer's documentation


res_config_curl.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2008, Digium, Inc.
5  *
6  * Tilghman Lesher <res_config_curl_v1@the-tilghman.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18 
19 /*! \file
20  *
21  * \brief curl plugin for portable configuration engine
22  *
23  * \author Tilghman Lesher <res_config_curl_v1@the-tilghman.com>
24  *
25  * \extref Depends on the CURL library - http://curl.haxx.se/
26  *
27  */
28 
29 /*** MODULEINFO
30  <depend>curl</depend>
31  <support_level>core</support_level>
32  ***/
33 
34 #include "asterisk.h"
35 
36 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 383667 $")
37 
38 #include <curl/curl.h>
39 
40 #include "asterisk/file.h"
41 #include "asterisk/channel.h"
42 #include "asterisk/pbx.h"
43 #include "asterisk/config.h"
44 #include "asterisk/module.h"
45 #include "asterisk/lock.h"
46 #include "asterisk/utils.h"
47 #include "asterisk/threadstorage.h"
48 
51 
52 /*!
53  * \brief Execute a curl query and return ast_variable list
54  * \param url The base URL from which to retrieve data
55  * \param unused Not currently used
56  * \param ap list containing one or more field/operator/value set.
57  *
58  * \retval var on success
59  * \retval NULL on failure
60 */
61 static struct ast_variable *realtime_curl(const char *url, const char *unused, va_list ap)
62 {
63  struct ast_str *query, *buffer;
64  char buf1[256], buf2[256];
65  const char *newparam, *newval;
66  char *stringp, *pair, *key;
67  int i;
68  struct ast_variable *var = NULL, *prev = NULL;
69  const int EncodeSpecialChars = 1;
70 
71  if (!ast_custom_function_find("CURL")) {
72  ast_log(LOG_ERROR, "func_curl.so must be loaded in order to use res_config_curl.so!!\n");
73  return NULL;
74  }
75 
76  if (!(query = ast_str_thread_get(&query_buf, 16))) {
77  return NULL;
78  }
79 
80  if (!(buffer = ast_str_thread_get(&result_buf, 16))) {
81  return NULL;
82  }
83 
84  ast_str_set(&query, 0, "${CURL(%s/single,", url);
85 
86  for (i = 0; (newparam = va_arg(ap, const char *)); i++) {
87  newval = va_arg(ap, const char *);
88  ast_uri_encode(newparam, buf1, sizeof(buf1), EncodeSpecialChars);
89  ast_uri_encode(newval, buf2, sizeof(buf2), EncodeSpecialChars);
90  ast_str_append(&query, 0, "%s%s=%s", i > 0 ? "&" : "", buf1, buf2);
91  }
92 
93  ast_str_append(&query, 0, ")}");
94  ast_str_substitute_variables(&buffer, 0, NULL, ast_str_buffer(query));
95 
96  /* Remove any trailing newline characters */
97  if ((stringp = strchr(ast_str_buffer(buffer), '\r')) || (stringp = strchr(ast_str_buffer(buffer), '\n'))) {
98  *stringp = '\0';
99  }
100 
101  stringp = ast_str_buffer(buffer);
102  while ((pair = strsep(&stringp, "&"))) {
103  key = strsep(&pair, "=");
104  ast_uri_decode(key);
105  if (pair) {
106  ast_uri_decode(pair);
107  }
108 
109  if (!ast_strlen_zero(key)) {
110  if (prev) {
111  prev->next = ast_variable_new(key, S_OR(pair, ""), "");
112  if (prev->next) {
113  prev = prev->next;
114  }
115  } else {
116  prev = var = ast_variable_new(key, S_OR(pair, ""), "");
117  }
118  }
119  }
120 
121  return var;
122 }
123 
124 /*!
125  * \brief Excute an Select query and return ast_config list
126  * \param url
127  * \param unused
128  * \param ap list containing one or more field/operator/value set.
129  *
130  * \retval struct ast_config pointer on success
131  * \retval NULL on failure
132 */
133 static struct ast_config *realtime_multi_curl(const char *url, const char *unused, va_list ap)
134 {
135  struct ast_str *query, *buffer;
136  char buf1[256], buf2[256];
137  const char *newparam, *newval;
138  char *stringp, *line, *pair, *key, *initfield = NULL;
139  int i;
140  const int EncodeSpecialChars = 1;
141  struct ast_variable *var = NULL;
142  struct ast_config *cfg = NULL;
143  struct ast_category *cat = NULL;
144 
145  if (!ast_custom_function_find("CURL")) {
146  ast_log(LOG_ERROR, "func_curl.so must be loaded in order to use res_config_curl.so!!\n");
147  return NULL;
148  }
149 
150  if (!(query = ast_str_thread_get(&query_buf, 16))) {
151  return NULL;
152  }
153 
154  if (!(buffer = ast_str_thread_get(&result_buf, 16))) {
155  return NULL;
156  }
157 
158  ast_str_set(&query, 0, "${CURL(%s/multi,", url);
159 
160  for (i = 0; (newparam = va_arg(ap, const char *)); i++) {
161  newval = va_arg(ap, const char *);
162  if (i == 0) {
163  char *op;
164  initfield = ast_strdupa(newparam);
165  if ((op = strchr(initfield, ' ')))
166  *op = '\0';
167  }
168  ast_uri_encode(newparam, buf1, sizeof(buf1), EncodeSpecialChars);
169  ast_uri_encode(newval, buf2, sizeof(buf2), EncodeSpecialChars);
170  ast_str_append(&query, 0, "%s%s=%s", i > 0 ? "&" : "", buf1, buf2);
171  }
172 
173  ast_str_append(&query, 0, ")}");
174 
175  /* Do the CURL query */
176  ast_str_substitute_variables(&buffer, 0, NULL, ast_str_buffer(query));
177 
178  if (!(cfg = ast_config_new())) {
179  return NULL;
180  }
181 
182  /* Line oriented output */
183  stringp = ast_str_buffer(buffer);
184  while ((line = strsep(&stringp, "\r\n"))) {
185  if (ast_strlen_zero(line)) {
186  continue;
187  }
188 
189  if (!(cat = ast_category_new("", "", 99999))) {
190  continue;
191  }
192 
193  while ((pair = strsep(&line, "&"))) {
194  key = strsep(&pair, "=");
195  ast_uri_decode(key);
196  if (pair) {
197  ast_uri_decode(pair);
198  }
199 
200  if (!strcasecmp(key, initfield) && pair) {
201  ast_category_rename(cat, pair);
202  }
203 
204  if (!ast_strlen_zero(key)) {
205  var = ast_variable_new(key, S_OR(pair, ""), "");
206  ast_variable_append(cat, var);
207  }
208  }
209  ast_category_append(cfg, cat);
210  }
211 
212  return cfg;
213 }
214 
215 /*!
216  * \brief Execute an UPDATE query
217  * \param url
218  * \param unused
219  * \param keyfield where clause field
220  * \param lookup value of field for where clause
221  * \param ap list containing one or more field/value set(s).
222  *
223  * Update a database table, prepare the sql statement using keyfield and lookup
224  * control the number of records to change. All values to be changed are stored in ap list.
225  * Sub-in the values to the prepared statement and execute it.
226  *
227  * \retval number of rows affected
228  * \retval -1 on failure
229 */
230 static int update_curl(const char *url, const char *unused, const char *keyfield, const char *lookup, va_list ap)
231 {
232  struct ast_str *query, *buffer;
233  char buf1[256], buf2[256];
234  const char *newparam, *newval;
235  char *stringp;
236  int i, rowcount = -1;
237  const int EncodeSpecialChars = 1;
238 
239  if (!ast_custom_function_find("CURL")) {
240  ast_log(LOG_ERROR, "func_curl.so must be loaded in order to use res_config_curl.so!!\n");
241  return -1;
242  }
243 
244  if (!(query = ast_str_thread_get(&query_buf, 16))) {
245  return -1;
246  }
247 
248  if (!(buffer = ast_str_thread_get(&result_buf, 16))) {
249  return -1;
250  }
251 
252  ast_uri_encode(keyfield, buf1, sizeof(buf1), EncodeSpecialChars);
253  ast_uri_encode(lookup, buf2, sizeof(buf2), EncodeSpecialChars);
254  ast_str_set(&query, 0, "${CURL(%s/update?%s=%s,", url, buf1, buf2);
255 
256  for (i = 0; (newparam = va_arg(ap, const char *)); i++) {
257  newval = va_arg(ap, const char *);
258  ast_uri_encode(newparam, buf1, sizeof(buf1), EncodeSpecialChars);
259  ast_uri_encode(newval, buf2, sizeof(buf2), EncodeSpecialChars);
260  ast_str_append(&query, 0, "%s%s=%s", i > 0 ? "&" : "", buf1, buf2);
261  }
262 
263  ast_str_append(&query, 0, ")}");
264  ast_str_substitute_variables(&buffer, 0, NULL, ast_str_buffer(query));
265 
266  /* Line oriented output */
267  stringp = ast_str_buffer(buffer);
268  while (*stringp <= ' ') {
269  stringp++;
270  }
271  sscanf(stringp, "%30d", &rowcount);
272 
273  if (rowcount >= 0) {
274  return (int)rowcount;
275  }
276 
277  return -1;
278 }
279 
280 static int update2_curl(const char *url, const char *unused, va_list ap)
281 {
282  struct ast_str *query, *buffer;
283  char buf1[200], buf2[200];
284  const char *newparam, *newval;
285  char *stringp;
286  int rowcount = -1, lookup = 1, first = 1;
287  const int EncodeSpecialChars = 1;
288 
289  if (!ast_custom_function_find("CURL")) {
290  ast_log(LOG_ERROR, "func_curl.so must be loaded in order to use res_config_curl.so!!\n");
291  return -1;
292  }
293 
294  if (!(query = ast_str_thread_get(&query_buf, 1000)))
295  return -1;
296 
297  if (!(buffer = ast_str_thread_get(&result_buf, 16))) {
298  return -1;
299  }
300 
301  ast_str_set(&query, 0, "${CURL(%s/update?", url);
302 
303  for (;;) {
304  if ((newparam = va_arg(ap, const char *)) == SENTINEL) {
305  if (lookup) {
306  lookup = 0;
307  ast_str_append(&query, 0, ",");
308  /* Back to the first parameter; we don't need a starting '&' */
309  first = 1;
310  continue;
311  } else {
312  break;
313  }
314  }
315  newval = va_arg(ap, const char *);
316  ast_uri_encode(newparam, buf1, sizeof(buf1), EncodeSpecialChars);
317  ast_uri_encode(newval, buf2, sizeof(buf2), EncodeSpecialChars);
318  ast_str_append(&query, 0, "%s%s=%s", first ? "" : "&", buf1, buf2);
319  first = 0;
320  }
321 
322  ast_str_append(&query, 0, ")}");
323  /* Proxies work, by setting CURLOPT options in the [globals] section of
324  * extensions.conf. Unfortunately, this means preloading pbx_config.so
325  * so that they have an opportunity to be set prior to startup realtime
326  * queries. */
327  ast_str_substitute_variables(&buffer, 0, NULL, ast_str_buffer(query));
328 
329  /* Line oriented output */
330  stringp = ast_str_buffer(buffer);
331  while (*stringp <= ' ') {
332  stringp++;
333  }
334  sscanf(stringp, "%30d", &rowcount);
335 
336  if (rowcount >= 0) {
337  return (int)rowcount;
338  }
339 
340  return -1;
341 }
342 
343 /*!
344  * \brief Execute an INSERT query
345  * \param url
346  * \param unused
347  * \param ap list containing one or more field/value set(s)
348  *
349  * Insert a new record into database table, prepare the sql statement.
350  * All values to be changed are stored in ap list.
351  * Sub-in the values to the prepared statement and execute it.
352  *
353  * \retval number of rows affected
354  * \retval -1 on failure
355 */
356 static int store_curl(const char *url, const char *unused, va_list ap)
357 {
358  struct ast_str *query, *buffer;
359  char buf1[256], buf2[256];
360  const char *newparam, *newval;
361  char *stringp;
362  int i, rowcount = -1;
363  const int EncodeSpecialChars = 1;
364 
365  if (!ast_custom_function_find("CURL")) {
366  ast_log(LOG_ERROR, "func_curl.so must be loaded in order to use res_config_curl.so!!\n");
367  return -1;
368  }
369 
370  if (!(query = ast_str_thread_get(&query_buf, 1000))) {
371  return -1;
372  }
373 
374  if (!(buffer = ast_str_thread_get(&result_buf, 16))) {
375  return -1;
376  }
377 
378  ast_str_set(&query, 0, "${CURL(%s/store,", url);
379 
380  for (i = 0; (newparam = va_arg(ap, const char *)); i++) {
381  newval = va_arg(ap, const char *);
382  ast_uri_encode(newparam, buf1, sizeof(buf1), EncodeSpecialChars);
383  ast_uri_encode(newval, buf2, sizeof(buf2), EncodeSpecialChars);
384  ast_str_append(&query, 0, "%s%s=%s", i > 0 ? "&" : "", buf1, buf2);
385  }
386 
387  ast_str_append(&query, 0, ")}");
388  ast_str_substitute_variables(&buffer, 0, NULL, ast_str_buffer(query));
389 
390  stringp = ast_str_buffer(buffer);
391  while (*stringp <= ' ') {
392  stringp++;
393  }
394  sscanf(stringp, "%30d", &rowcount);
395 
396  if (rowcount >= 0) {
397  return rowcount;
398  }
399 
400  return -1;
401 }
402 
403 /*!
404  * \brief Execute an DELETE query
405  * \param url
406  * \param unused
407  * \param keyfield where clause field
408  * \param lookup value of field for where clause
409  * \param ap list containing one or more field/value set(s)
410  *
411  * Delete a row from a database table, prepare the sql statement using keyfield and lookup
412  * control the number of records to change. Additional params to match rows are stored in ap list.
413  * Sub-in the values to the prepared statement and execute it.
414  *
415  * \retval number of rows affected
416  * \retval -1 on failure
417 */
418 static int destroy_curl(const char *url, const char *unused, const char *keyfield, const char *lookup, va_list ap)
419 {
420  struct ast_str *query, *buffer;
421  char buf1[200], buf2[200];
422  const char *newparam, *newval;
423  char *stringp;
424  int i, rowcount = -1;
425  const int EncodeSpecialChars = 1;
426 
427  if (!ast_custom_function_find("CURL")) {
428  ast_log(LOG_ERROR, "func_curl.so must be loaded in order to use res_config_curl.so!!\n");
429  return -1;
430  }
431 
432  if (!(query = ast_str_thread_get(&query_buf, 1000))) {
433  return -1;
434  }
435 
436  if (!(buffer = ast_str_thread_get(&result_buf, 16))) {
437  return -1;
438  }
439 
440  ast_uri_encode(keyfield, buf1, sizeof(buf1), EncodeSpecialChars);
441  ast_uri_encode(lookup, buf2, sizeof(buf2), EncodeSpecialChars);
442  ast_str_set(&query, 0, "${CURL(%s/destroy,%s=%s&", url, buf1, buf2);
443 
444  for (i = 0; (newparam = va_arg(ap, const char *)); i++) {
445  newval = va_arg(ap, const char *);
446  ast_uri_encode(newparam, buf1, sizeof(buf1), EncodeSpecialChars);
447  ast_uri_encode(newval, buf2, sizeof(buf2), EncodeSpecialChars);
448  ast_str_append(&query, 0, "%s%s=%s", i > 0 ? "&" : "", buf1, buf2);
449  }
450 
451  ast_str_append(&query, 0, ")}");
452  ast_str_substitute_variables(&buffer, 0, NULL, ast_str_buffer(query));
453 
454  /* Line oriented output */
455  stringp = ast_str_buffer(buffer);
456  while (*stringp <= ' ') {
457  stringp++;
458  }
459  sscanf(stringp, "%30d", &rowcount);
460 
461  if (rowcount >= 0) {
462  return (int)rowcount;
463  }
464 
465  return -1;
466 }
467 
468 static int require_curl(const char *url, const char *unused, va_list ap)
469 {
470  struct ast_str *query, *buffer;
471  char *elm, field[256];
472  int type, size, i = 0;
473  const int EncodeSpecialChars = 1;
474 
475  if (!ast_custom_function_find("CURL")) {
476  ast_log(LOG_ERROR, "func_curl.so must be loaded in order to use res_config_curl.so!!\n");
477  return -1;
478  }
479 
480  if (!(query = ast_str_thread_get(&query_buf, 100))) {
481  return -1;
482  }
483 
484  if (!(buffer = ast_str_thread_get(&result_buf, 16))) {
485  return -1;
486  }
487 
488  ast_str_set(&query, 0, "${CURL(%s/require,", url);
489 
490  while ((elm = va_arg(ap, char *))) {
491  type = va_arg(ap, require_type);
492  size = va_arg(ap, int);
493  ast_uri_encode(elm, field, sizeof(field), EncodeSpecialChars);
494  ast_str_append(&query, 0, "%s%s=%s%%3A%d",
495  i > 0 ? "&" : "",
496  field,
497  type == RQ_CHAR ? "char" :
498  type == RQ_INTEGER1 ? "integer1" :
499  type == RQ_UINTEGER1 ? "uinteger1" :
500  type == RQ_INTEGER2 ? "integer2" :
501  type == RQ_UINTEGER2 ? "uinteger2" :
502  type == RQ_INTEGER3 ? "integer3" :
503  type == RQ_UINTEGER3 ? "uinteger3" :
504  type == RQ_INTEGER4 ? "integer4" :
505  type == RQ_UINTEGER4 ? "uinteger4" :
506  type == RQ_INTEGER8 ? "integer8" :
507  type == RQ_UINTEGER8 ? "uinteger8" :
508  type == RQ_DATE ? "date" :
509  type == RQ_DATETIME ? "datetime" :
510  type == RQ_FLOAT ? "float" :
511  "unknown", size);
512  i++;
513  }
514 
515  ast_str_append(&query, 0, ")}");
516  ast_str_substitute_variables(&buffer, 0, NULL, ast_str_buffer(query));
517  return atoi(ast_str_buffer(buffer));
518 }
519 
520 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)
521 {
522  struct ast_str *query, *buffer;
523  char buf1[200];
524  char *stringp, *line, *pair, *key;
525  const int EncodeSpecialChars = 1;
526  int last_cat_metric = -1, cat_metric = -1;
527  struct ast_category *cat = NULL;
528  char *cur_cat = "";
529  char *category = "", *var_name = "", *var_val = "";
530  struct ast_flags loader_flags = { 0 };
531 
532  if (!ast_custom_function_find("CURL")) {
533  ast_log(LOG_ERROR, "func_curl.so must be loaded in order to use res_config_curl.so!!\n");
534  return NULL;
535  }
536 
537  if (!(query = ast_str_thread_get(&query_buf, 100))) {
538  return NULL;
539  }
540 
541  if (!(buffer = ast_str_thread_get(&result_buf, 16))) {
542  return NULL;
543  }
544 
545  ast_uri_encode(file, buf1, sizeof(buf1), EncodeSpecialChars);
546  ast_str_set(&query, 0, "${CURL(%s/static?file=%s)}", url, buf1);
547 
548  /* Do the CURL query */
549  ast_str_substitute_variables(&buffer, 0, NULL, ast_str_buffer(query));
550 
551  /* Line oriented output */
552  stringp = ast_str_buffer(buffer);
554 
555  while ((line = strsep(&stringp, "\r\n"))) {
556  if (ast_strlen_zero(line)) {
557  continue;
558  }
559 
560  while ((pair = strsep(&line, "&"))) {
561  key = strsep(&pair, "=");
562  ast_uri_decode(key);
563  if (pair) {
564  ast_uri_decode(pair);
565  }
566 
567  if (!strcasecmp(key, "category")) {
568  category = S_OR(pair, "");
569  } else if (!strcasecmp(key, "var_name")) {
570  var_name = S_OR(pair, "");
571  } else if (!strcasecmp(key, "var_val")) {
572  var_val = S_OR(pair, "");
573  } else if (!strcasecmp(key, "cat_metric")) {
574  cat_metric = pair ? atoi(pair) : 0;
575  }
576  }
577 
578  if (!strcmp(var_name, "#include")) {
579  if (!ast_config_internal_load(var_val, cfg, loader_flags, "", who_asked))
580  return NULL;
581  }
582 
583  if (!cat || strcmp(category, cur_cat) || last_cat_metric != cat_metric) {
584  if (!(cat = ast_category_new(category, "", 99999)))
585  break;
586  cur_cat = category;
587  last_cat_metric = cat_metric;
588  ast_category_append(cfg, cat);
589  }
590  ast_variable_append(cat, ast_variable_new(var_name, var_val, ""));
591  }
592 
593  return cfg;
594 }
595 
597  .name = "curl",
598  .load_func = config_curl,
599  .realtime_func = realtime_curl,
600  .realtime_multi_func = realtime_multi_curl,
601  .store_func = store_curl,
602  .destroy_func = destroy_curl,
603  .update_func = update_curl,
604  .update2_func = update2_curl,
605  .require_func = require_curl,
606 };
607 
608 static int reload_module(void)
609 {
610  struct ast_flags flags = { CONFIG_FLAG_NOREALTIME };
611  struct ast_config *cfg;
612  struct ast_variable *var;
613 
614  if (!(cfg = ast_config_load("res_curl.conf", flags))) {
615  return 0;
616  } else if (cfg == CONFIG_STATUS_FILEINVALID) {
617  ast_log(LOG_WARNING, "res_curl.conf could not be parsed!\n");
618  return 0;
619  }
620 
621  if (!(var = ast_variable_browse(cfg, "globals")) && !(var = ast_variable_browse(cfg, "global")) && !(var = ast_variable_browse(cfg, "general"))) {
622  ast_log(LOG_WARNING, "[globals] not found in res_curl.conf\n");
623  ast_config_destroy(cfg);
624  return 0;
625  }
626 
627  for (; var; var = var->next) {
628  if (strncmp(var->name, "CURLOPT(", 8)) {
629  char name[256];
630  snprintf(name, sizeof(name), "CURLOPT(%s)", var->name);
631  pbx_builtin_setvar_helper(NULL, name, var->value);
632  } else {
633  pbx_builtin_setvar_helper(NULL, var->name, var->value);
634  }
635  }
636  ast_config_destroy(cfg);
637  return 0;
638 }
639 
640 static int unload_module(void)
641 {
642  ast_config_engine_deregister(&curl_engine);
643  ast_verb(1, "res_config_curl unloaded.\n");
644  return 0;
645 }
646 
647 static int load_module(void)
648 {
649  if (!ast_module_check("res_curl.so")) {
650  if (ast_load_resource("res_curl.so") != AST_MODULE_LOAD_SUCCESS) {
651  ast_log(LOG_ERROR, "Cannot load res_curl, so res_config_curl cannot be loaded\n");
653  }
654  }
655 
656  if (!ast_module_check("func_curl.so")) {
657  if (ast_load_resource("func_curl.so") != AST_MODULE_LOAD_SUCCESS) {
658  ast_log(LOG_ERROR, "Cannot load func_curl, so res_config_curl cannot be loaded\n");
660  }
661  }
662 
663  reload_module();
664 
665  ast_config_engine_register(&curl_engine);
666  ast_verb(1, "res_config_curl loaded.\n");
667  return 0;
668 }
669 
670 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Realtime Curl configuration",
671  .load = load_module,
672  .unload = unload_module,
674  .load_pri = AST_MODPRI_REALTIME_DRIVER,
675  );
static int reload_module(void)
#define AST_THREADSTORAGE(name)
Define a thread storage variable.
Definition: threadstorage.h:81
Asterisk locking-related definitions:
Asterisk main include file. File version handling, generic pbx functions.
char * strsep(char **str, const char *delims)
enum ast_module_load_result ast_load_resource(const char *resource_name)
Load a module.
Definition: loader.c:947
static int store_curl(const char *url, const char *unused, va_list ap)
Execute an INSERT query.
void ast_uri_decode(char *s)
Decode URI, URN, URL (overwrite string)
Definition: utils.c:484
#define LOG_WARNING
Definition: logger.h:144
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category)
Goes through variables.
Definition: config.c:597
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
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_category * ast_config_get_current_category(const struct ast_config *cfg)
Retrieve the current category name being built.
Definition: config.c:1055
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
#define var
Definition: ast_expr2f.c:606
void ast_str_substitute_variables(struct ast_str **buf, ssize_t maxlen, struct ast_channel *chan, const char *templ)
Definition: pbx.c:4468
Configuration File Parser.
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:900
static struct ast_threadstorage buf2
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
Definition: module.h:374
char * ast_uri_encode(const char *string, char *outbuf, int buflen, int do_special_char)
Turn text string to URI-encoded XX version.
Definition: utils.c:398
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.
#define ast_verb(level,...)
Definition: logger.h:243
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: config.c:1037
Configuration engine structure, used to define realtime drivers.
Definition: config.h:121
int ast_module_check(const char *name)
Check if module with the name given is loaded.
Definition: loader.c:1255
Utility functions.
struct ast_category * ast_category_new(const char *name, const char *in_file, int lineno)
Create a category structure.
Definition: config.c:673
static struct ast_config * realtime_multi_curl(const char *url, const char *unused, va_list ap)
Excute an Select query and return ast_config list.
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:874
Definition: config.h:68
#define SENTINEL
Definition: compiler.h:75
const char * value
Definition: config.h:79
General Asterisk PBX channel definitions.
#define ast_config_load(filename, flags)
Load a config file.
Definition: config.h:170
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static struct ast_config_engine curl_engine
const char * name
Definition: config.h:77
static struct ast_threadstorage result_buf
static struct ast_variable * realtime_curl(const char *url, const char *unused, va_list ap)
Execute a curl query and return ast_variable list.
Core PBX routines and definitions.
static int require_curl(const char *url, const char *unused, va_list ap)
static int reload(void)
Definition: app_amd.c:497
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
struct ast_custom_function * ast_custom_function_find(const char *name)
Definition: pbx.c:3800
#define LOG_ERROR
Definition: logger.h:155
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
void ast_variable_append(struct ast_category *category, struct ast_variable *variable)
Definition: config.c:483
static int destroy_curl(const char *url, const char *unused, const char *keyfield, const char *lookup, va_list ap)
Execute an DELETE query.
struct sla_ringing_trunk * first
Definition: app_meetme.c:965
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int ast_config_engine_register(struct ast_config_engine *newconfig)
Register config engine.
Definition: config.c:2378
static struct ast_threadstorage buf1
static const char name[]
struct ast_config * ast_config_new(void)
Create a new base configuration structure.
Definition: config.c:888
static int update2_curl(const char *url, const char *unused, va_list ap)
static const char type[]
Definition: chan_nbs.c:57
Structure used to handle boolean flags.
Definition: utils.h:200
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...
Definition: pbx.c:10546
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
static int unload_module(void)
struct ast_variable * next
Definition: config.h:82
struct ast_str * ast_str_thread_get(struct ast_threadstorage *ts, size_t init_len)
Retrieve a thread locally stored dynamic string.
Definition: strings.h:669
void ast_category_append(struct ast_config *config, struct ast_category *cat)
Definition: config.c:719
#define CONFIG_STATUS_FILEINVALID
Definition: config.h:52
struct ast_config * ast_config_internal_load(const char *configfile, struct ast_config *cfg, struct ast_flags flags, const char *suggested_incl_file, const char *who_asked)
Definition: config.c:2459
static char url[512]
void ast_category_rename(struct ast_category *cat, const char *name)
Definition: config.c:867
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:38
Asterisk module definitions.
require_type
Types used in ast_realtime_require_field.
Definition: config.h:57
static int load_module(void)
Definition: config.h:70
static int update_curl(const char *url, const char *unused, const char *keyfield, const char *lookup, va_list ap)
Execute an UPDATE query.
struct ast_variable * ast_variable_new(const char *name, const char *value, const char *filename)
Definition: config.c:278
#define ASTERISK_FILE_VERSION(file, version)
Register/unregister a source code file with the core.
Definition: asterisk.h:180
int ast_config_engine_deregister(struct ast_config_engine *del)
Deregister config engine.
Definition: config.c:2397
static struct ast_threadstorage query_buf