Fri Nov 12 12:02:02 2010

Asterisk developer's documentation


func_curl.c File Reference

Curl - Load a URL. More...

#include "asterisk.h"
#include <curl/curl.h>
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/cli.h"
#include "asterisk/module.h"
#include "asterisk/app.h"
#include "asterisk/utils.h"
#include "asterisk/threadstorage.h"
Include dependency graph for func_curl.c:

Go to the source code of this file.

Data Structures

struct  curl_settings
struct  global_curl_info

Defines

#define CURLOPT_SPECIAL_HASHCOMPAT   -500
#define CURLVERSION_ATLEAST(a, b, c)   ((LIBCURL_VERSION_MAJOR > (a)) || ((LIBCURL_VERSION_MAJOR == (a)) && (LIBCURL_VERSION_MINOR > (b))) || ((LIBCURL_VERSION_MAJOR == (a)) && (LIBCURL_VERSION_MINOR == (b)) && (LIBCURL_VERSION_PATCH >= (c))))

Enumerations

enum  optiontype {
  OT_BOOLEAN, OT_INTEGER, OT_INTEGER_MS, OT_STRING,
  OT_ENUM
}

Functions

static void __init_curl_instance (void)
static void __reg_module (void)
static void __unreg_module (void)
static int acf_curl_exec (struct ast_channel *chan, const char *cmd, char *info, char *buf, size_t len)
static int acf_curlopt_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
static int acf_curlopt_write (struct ast_channel *chan, const char *cmd, char *name, const char *value)
static void curl_instance_cleanup (void *data)
static int curl_instance_init (void *data)
static void curlds_free (void *data)
static int load_module (void)
static int parse_curlopt_key (const char *name, CURLoption *key, enum optiontype *ot)
static int unload_module (void)
static size_t WriteMemoryCallback (void *ptr, size_t size, size_t nmemb, void *data)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Load external URL" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "0901e4e500243c855563a2d78b0c03e4" , .load = load_module, .unload = unload_module, }
struct ast_custom_function acf_curl
struct ast_custom_function acf_curlopt
static struct ast_module_infoast_module_info = &__mod_info
static struct ast_datastore_info curl_info
static struct ast_threadstorage curl_instance = { .once = PTHREAD_ONCE_INIT , .key_init = __init_curl_instance , .custom_init = curl_instance_init , }
static const char * global_useragent = "asterisk-libcurl-agent/1.0"

Detailed Description

Curl - Load a URL.

Author:
Tilghman Lesher <curl-20050919@the-tilghman.com>
Note:
Brian Wilkins <bwilkins@cfl.rr.com> (Added POST option)
ExtRef:
Depends on the CURL library - http://curl.haxx.se/

Definition in file func_curl.c.


Define Documentation

#define CURLOPT_SPECIAL_HASHCOMPAT   -500

Definition at line 56 of file func_curl.c.

Referenced by acf_curl_exec(), and parse_curlopt_key().

#define CURLVERSION_ATLEAST ( a,
b,
 )     ((LIBCURL_VERSION_MAJOR > (a)) || ((LIBCURL_VERSION_MAJOR == (a)) && (LIBCURL_VERSION_MINOR > (b))) || ((LIBCURL_VERSION_MAJOR == (a)) && (LIBCURL_VERSION_MINOR == (b)) && (LIBCURL_VERSION_PATCH >= (c))))

Definition at line 53 of file func_curl.c.


Enumeration Type Documentation

enum optiontype
Enumerator:
OT_BOOLEAN 
OT_INTEGER 
OT_INTEGER_MS 
OT_STRING 
OT_ENUM 

Definition at line 86 of file func_curl.c.

00086                 {
00087    OT_BOOLEAN,
00088    OT_INTEGER,
00089    OT_INTEGER_MS,
00090    OT_STRING,
00091    OT_ENUM,
00092 };


Function Documentation

static void __init_curl_instance ( void   )  [static]

Definition at line 395 of file func_curl.c.

00398 {

static void __reg_module ( void   )  [static]

Definition at line 569 of file func_curl.c.

static void __unreg_module ( void   )  [static]

Definition at line 569 of file func_curl.c.

static int acf_curl_exec ( struct ast_channel chan,
const char *  cmd,
char *  info,
char *  buf,
size_t  len 
) [static]

Definition at line 397 of file func_curl.c.

References AST_APP_ARG, ast_autoservice_start(), ast_autoservice_stop(), ast_channel_datastore_find(), ast_copy_string(), ast_debug, AST_DECLARE_APP_ARGS, ast_free, AST_LIST_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), AST_STANDARD_APP_ARGS, ast_str_append(), ast_str_buffer(), ast_str_create(), ast_str_strlen(), ast_str_trim_blanks(), ast_strlen_zero(), ast_threadstorage_get(), ast_uri_decode(), curl_instance, CURLOPT_SPECIAL_HASHCOMPAT, ast_datastore::data, curl_settings::key, curl_settings::list, LOG_ERROR, LOG_WARNING, name, pbx_builtin_setvar_helper(), str, url, and curl_settings::value.

00398 {
00399    struct ast_str *str = ast_str_create(16);
00400    int ret = -1;
00401    AST_DECLARE_APP_ARGS(args,
00402       AST_APP_ARG(url);
00403       AST_APP_ARG(postdata);
00404    );
00405    CURL **curl;
00406    struct curl_settings *cur;
00407    struct ast_datastore *store = NULL;
00408    int hashcompat = 0;
00409    AST_LIST_HEAD(global_curl_info, curl_settings) *list = NULL;
00410 
00411    *buf = '\0';
00412    
00413    if (ast_strlen_zero(info)) {
00414       ast_log(LOG_WARNING, "CURL requires an argument (URL)\n");
00415       ast_free(str);
00416       return -1;
00417    }
00418 
00419    AST_STANDARD_APP_ARGS(args, info);  
00420 
00421    if (chan) {
00422       ast_autoservice_start(chan);
00423    }
00424 
00425    if (!(curl = ast_threadstorage_get(&curl_instance, sizeof(*curl)))) {
00426       ast_log(LOG_ERROR, "Cannot allocate curl structure\n");
00427       return -1;
00428    }
00429 
00430    AST_LIST_LOCK(&global_curl_info);
00431    AST_LIST_TRAVERSE(&global_curl_info, cur, list) {
00432       if (cur->key == CURLOPT_SPECIAL_HASHCOMPAT) {
00433          hashcompat = (cur->value != NULL) ? 1 : 0;
00434       } else {
00435          curl_easy_setopt(*curl, cur->key, cur->value);
00436       }
00437    }
00438 
00439    if (chan && (store = ast_channel_datastore_find(chan, &curl_info, NULL))) {
00440       list = store->data;
00441       AST_LIST_LOCK(list);
00442       AST_LIST_TRAVERSE(list, cur, list) {
00443          if (cur->key == CURLOPT_SPECIAL_HASHCOMPAT) {
00444             hashcompat = (cur->value != NULL) ? 1 : 0;
00445          } else {
00446             curl_easy_setopt(*curl, cur->key, cur->value);
00447          }
00448       }
00449    }
00450 
00451    curl_easy_setopt(*curl, CURLOPT_URL, args.url);
00452    curl_easy_setopt(*curl, CURLOPT_FILE, (void *) &str);
00453 
00454    if (args.postdata) {
00455       curl_easy_setopt(*curl, CURLOPT_POST, 1);
00456       curl_easy_setopt(*curl, CURLOPT_POSTFIELDS, args.postdata);
00457    }
00458 
00459    curl_easy_perform(*curl);
00460 
00461    if (store) {
00462       AST_LIST_UNLOCK(list);
00463    }
00464    AST_LIST_UNLOCK(&global_curl_info);
00465 
00466    if (args.postdata) {
00467       curl_easy_setopt(*curl, CURLOPT_POST, 0);
00468    }
00469 
00470    if (ast_str_strlen(str)) {
00471       ast_str_trim_blanks(str);
00472 
00473       ast_debug(3, "str='%s'\n", ast_str_buffer(str));
00474       if (hashcompat) {
00475          char *remainder = ast_str_buffer(str);
00476          char *piece;
00477          struct ast_str *fields = ast_str_create(ast_str_strlen(str) / 2);
00478          struct ast_str *values = ast_str_create(ast_str_strlen(str) / 2);
00479          int rowcount = 0;
00480          while ((piece = strsep(&remainder, "&"))) {
00481             char *name = strsep(&piece, "=");
00482             ast_uri_decode(piece);
00483             ast_uri_decode(name);
00484             ast_str_append(&fields, 0, "%s%s", rowcount ? "," : "", name);
00485             ast_str_append(&values, 0, "%s%s", rowcount ? "," : "", piece);
00486             rowcount++;
00487          }
00488          pbx_builtin_setvar_helper(chan, "~ODBCFIELDS~", ast_str_buffer(fields));
00489          ast_copy_string(buf, ast_str_buffer(values), len);
00490          ast_free(fields);
00491          ast_free(values);
00492       } else {
00493          ast_copy_string(buf, ast_str_buffer(str), len);
00494       }
00495       ret = 0;
00496    }
00497    ast_free(str);
00498 
00499    if (chan)
00500       ast_autoservice_stop(chan);
00501    
00502    return ret;
00503 }

static int acf_curlopt_read ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  len 
) [static]

Definition at line 282 of file func_curl.c.

References ast_channel_datastore_find(), ast_copy_string(), ast_debug, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_datastore::data, curl_settings::key, curl_settings::list, LOG_ERROR, OT_BOOLEAN, OT_INTEGER, OT_INTEGER_MS, OT_STRING, parse_curlopt_key(), and curl_settings::value.

00283 {
00284    struct ast_datastore *store;
00285    struct global_curl_info *list[2] = { &global_curl_info, NULL };
00286    struct curl_settings *cur = NULL;
00287    CURLoption key;
00288    enum optiontype ot;
00289    int i;
00290 
00291    if (parse_curlopt_key(data, &key, &ot)) {
00292       ast_log(LOG_ERROR, "Unrecognized option: '%s'\n", data);
00293       return -1;
00294    }
00295 
00296    if (chan && (store = ast_channel_datastore_find(chan, &curl_info, NULL))) {
00297       list[0] = store->data;
00298       list[1] = &global_curl_info;
00299    }
00300 
00301    for (i = 0; i < 2; i++) {
00302       if (!list[i]) {
00303          break;
00304       }
00305       AST_LIST_LOCK(list[i]);
00306       AST_LIST_TRAVERSE(list[i], cur, list) {
00307          if (cur->key == key) {
00308             if (ot == OT_BOOLEAN || ot == OT_INTEGER) {
00309                snprintf(buf, len, "%ld", (long)cur->value);
00310             } else if (ot == OT_INTEGER_MS) {
00311                if ((long)cur->value % 1000 == 0) {
00312                   snprintf(buf, len, "%ld", (long)cur->value / 1000);
00313                } else {
00314                   snprintf(buf, len, "%.3f", (double)((long)cur->value) / 1000.0);
00315                }
00316             } else if (ot == OT_STRING) {
00317                ast_debug(1, "Found entry %p, with key %d and value %p\n", cur, cur->key, cur->value);
00318                ast_copy_string(buf, cur->value, len);
00319             } else if (key == CURLOPT_PROXYTYPE) {
00320                if (0) {
00321 #if CURLVERSION_ATLEAST(7,15,2)
00322                } else if ((long)cur->value == CURLPROXY_SOCKS4) {
00323                   ast_copy_string(buf, "socks4", len);
00324 #endif
00325 #if CURLVERSION_ATLEAST(7,18,0)
00326                } else if ((long)cur->value == CURLPROXY_SOCKS4A) {
00327                   ast_copy_string(buf, "socks4a", len);
00328 #endif
00329                } else if ((long)cur->value == CURLPROXY_SOCKS5) {
00330                   ast_copy_string(buf, "socks5", len);
00331 #if CURLVERSION_ATLEAST(7,18,0)
00332                } else if ((long)cur->value == CURLPROXY_SOCKS5_HOSTNAME) {
00333                   ast_copy_string(buf, "socks5hostname", len);
00334 #endif
00335 #if CURLVERSION_ATLEAST(7,10,0)
00336                } else if ((long)cur->value == CURLPROXY_HTTP) {
00337                   ast_copy_string(buf, "http", len);
00338 #endif
00339                } else {
00340                   ast_copy_string(buf, "unknown", len);
00341                }
00342             }
00343             break;
00344          }
00345       }
00346       AST_LIST_UNLOCK(list[i]);
00347       if (cur) {
00348          break;
00349       }
00350    }
00351 
00352    return cur ? 0 : -1;
00353 }

static int acf_curlopt_write ( struct ast_channel chan,
const char *  cmd,
char *  name,
const char *  value 
) [static]

Definition at line 163 of file func_curl.c.

References ast_calloc, ast_channel_datastore_add(), ast_channel_datastore_find(), ast_datastore_alloc, ast_datastore_free(), ast_debug, AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_true(), ast_datastore::data, free, curl_settings::key, curl_settings::list, LOG_ERROR, OT_BOOLEAN, OT_ENUM, OT_INTEGER, OT_INTEGER_MS, OT_STRING, and parse_curlopt_key().

00164 {
00165    struct ast_datastore *store;
00166    struct global_curl_info *list;
00167    struct curl_settings *cur, *new = NULL;
00168    CURLoption key;
00169    enum optiontype ot;
00170 
00171    if (chan) {
00172       if (!(store = ast_channel_datastore_find(chan, &curl_info, NULL))) {
00173          /* Create a new datastore */
00174          if (!(store = ast_datastore_alloc(&curl_info, NULL))) {
00175             ast_log(LOG_ERROR, "Unable to allocate new datastore.  Cannot set any CURL options\n");
00176             return -1;
00177          }
00178 
00179          if (!(list = ast_calloc(1, sizeof(*list)))) {
00180             ast_log(LOG_ERROR, "Unable to allocate list head.  Cannot set any CURL options\n");
00181             ast_datastore_free(store);
00182          }
00183 
00184          store->data = list;
00185          AST_LIST_HEAD_INIT(list);
00186          ast_channel_datastore_add(chan, store);
00187       } else {
00188          list = store->data;
00189       }
00190    } else {
00191       /* Populate the global structure */
00192       list = &global_curl_info;
00193    }
00194 
00195    if (!parse_curlopt_key(name, &key, &ot)) {
00196       if (ot == OT_BOOLEAN) {
00197          if ((new = ast_calloc(1, sizeof(*new)))) {
00198             new->value = (void *)((long) ast_true(value));
00199          }
00200       } else if (ot == OT_INTEGER) {
00201          long tmp = atol(value);
00202          if ((new = ast_calloc(1, sizeof(*new)))) {
00203             new->value = (void *)tmp;
00204          }
00205       } else if (ot == OT_INTEGER_MS) {
00206          long tmp = atof(value) * 1000.0;
00207          if ((new = ast_calloc(1, sizeof(*new)))) {
00208             new->value = (void *)tmp;
00209          }
00210       } else if (ot == OT_STRING) {
00211          if ((new = ast_calloc(1, sizeof(*new) + strlen(value) + 1))) {
00212             new->value = (char *)new + sizeof(*new);
00213             strcpy(new->value, value);
00214          }
00215       } else if (ot == OT_ENUM) {
00216          if (key == CURLOPT_PROXYTYPE) {
00217             long ptype =
00218 #if CURLVERSION_ATLEAST(7,10,0)
00219                CURLPROXY_HTTP;
00220 #else
00221                CURLPROXY_SOCKS5;
00222 #endif
00223             if (0) {
00224 #if CURLVERSION_ATLEAST(7,15,2)
00225             } else if (!strcasecmp(value, "socks4")) {
00226                ptype = CURLPROXY_SOCKS4;
00227 #endif
00228 #if CURLVERSION_ATLEAST(7,18,0)
00229             } else if (!strcasecmp(value, "socks4a")) {
00230                ptype = CURLPROXY_SOCKS4A;
00231 #endif
00232 #if CURLVERSION_ATLEAST(7,18,0)
00233             } else if (!strcasecmp(value, "socks5")) {
00234                ptype = CURLPROXY_SOCKS5;
00235 #endif
00236 #if CURLVERSION_ATLEAST(7,18,0)
00237             } else if (!strncasecmp(value, "socks5", 6)) {
00238                ptype = CURLPROXY_SOCKS5_HOSTNAME;
00239 #endif
00240             }
00241 
00242             if ((new = ast_calloc(1, sizeof(*new)))) {
00243                new->value = (void *)ptype;
00244             }
00245          } else {
00246             /* Highly unlikely */
00247             goto yuck;
00248          }
00249       }
00250 
00251       /* Memory allocation error */
00252       if (!new) {
00253          return -1;
00254       }
00255 
00256       new->key = key;
00257    } else {
00258 yuck:
00259       ast_log(LOG_ERROR, "Unrecognized option: %s\n", name);
00260       return -1;
00261    }
00262 
00263    /* Remove any existing entry */
00264    AST_LIST_LOCK(list);
00265    AST_LIST_TRAVERSE_SAFE_BEGIN(list, cur, list) {
00266       if (cur->key == new->key) {
00267          AST_LIST_REMOVE_CURRENT(list);
00268          free(cur);
00269          break;
00270       }
00271    }
00272    AST_LIST_TRAVERSE_SAFE_END
00273 
00274    /* Insert new entry */
00275    ast_debug(1, "Inserting entry %p with key %d and value %p\n", new, new->key, new->value);
00276    AST_LIST_INSERT_TAIL(list, new, list);
00277    AST_LIST_UNLOCK(list);
00278 
00279    return 0;
00280 }

static void curl_instance_cleanup ( void *  data  )  [static]

Definition at line 386 of file func_curl.c.

References ast_free.

00387 {
00388    CURL **curl = data;
00389 
00390    curl_easy_cleanup(*curl);
00391 
00392    ast_free(data);
00393 }

static int curl_instance_init ( void *  data  )  [static]

Definition at line 371 of file func_curl.c.

References global_useragent, and WriteMemoryCallback().

00372 {
00373    CURL **curl = data;
00374 
00375    if (!(*curl = curl_easy_init()))
00376       return -1;
00377 
00378    curl_easy_setopt(*curl, CURLOPT_NOSIGNAL, 1);
00379    curl_easy_setopt(*curl, CURLOPT_TIMEOUT, 180);
00380    curl_easy_setopt(*curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
00381    curl_easy_setopt(*curl, CURLOPT_USERAGENT, global_useragent);
00382 
00383    return 0;
00384 }

static void curlds_free ( void *  data  )  [static]

Definition at line 73 of file func_curl.c.

References AST_LIST_HEAD, AST_LIST_HEAD_DESTROY, AST_LIST_REMOVE_HEAD, and free.

00074 {
00075    AST_LIST_HEAD(global_curl_info, curl_settings) *list = data;
00076    struct curl_settings *setting;
00077    if (!list) {
00078       return;
00079    }
00080    while ((setting = AST_LIST_REMOVE_HEAD(list, list))) {
00081       free(setting);
00082    }
00083    AST_LIST_HEAD_DESTROY(list);
00084 }

static int load_module ( void   )  [static]

Definition at line 552 of file func_curl.c.

References acf_curl, acf_curlopt, ast_custom_function_register, ast_load_resource(), ast_log(), ast_module_check(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, and LOG_ERROR.

00553 {
00554    int res;
00555 
00556    if (!ast_module_check("res_curl.so")) {
00557       if (ast_load_resource("res_curl.so") != AST_MODULE_LOAD_SUCCESS) {
00558          ast_log(LOG_ERROR, "Cannot load res_curl, so func_curl cannot be loaded\n");
00559          return AST_MODULE_LOAD_DECLINE;
00560       }
00561    }
00562 
00563    res = ast_custom_function_register(&acf_curl);
00564    res |= ast_custom_function_register(&acf_curlopt);
00565 
00566    return res;
00567 }

static int parse_curlopt_key ( const char *  name,
CURLoption *  key,
enum optiontype ot 
) [static]

Definition at line 94 of file func_curl.c.

References CURLOPT_SPECIAL_HASHCOMPAT, OT_BOOLEAN, OT_ENUM, OT_INTEGER, OT_INTEGER_MS, and OT_STRING.

Referenced by acf_curlopt_read(), and acf_curlopt_write().

00095 {
00096    if (!strcasecmp(name, "header")) {
00097       *key = CURLOPT_HEADER;
00098       *ot = OT_BOOLEAN;
00099    } else if (!strcasecmp(name, "proxy")) {
00100       *key = CURLOPT_PROXY;
00101       *ot = OT_STRING;
00102    } else if (!strcasecmp(name, "proxyport")) {
00103       *key = CURLOPT_PROXYPORT;
00104       *ot = OT_INTEGER;
00105    } else if (!strcasecmp(name, "proxytype")) {
00106       *key = CURLOPT_PROXYTYPE;
00107       *ot = OT_ENUM;
00108    } else if (!strcasecmp(name, "dnstimeout")) {
00109       *key = CURLOPT_DNS_CACHE_TIMEOUT;
00110       *ot = OT_INTEGER;
00111    } else if (!strcasecmp(name, "userpwd")) {
00112       *key = CURLOPT_USERPWD;
00113       *ot = OT_STRING;
00114    } else if (!strcasecmp(name, "proxyuserpwd")) {
00115       *key = CURLOPT_PROXYUSERPWD;
00116       *ot = OT_STRING;
00117    } else if (!strcasecmp(name, "maxredirs")) {
00118       *key = CURLOPT_MAXREDIRS;
00119       *ot = OT_INTEGER;
00120    } else if (!strcasecmp(name, "referer")) {
00121       *key = CURLOPT_REFERER;
00122       *ot = OT_STRING;
00123    } else if (!strcasecmp(name, "useragent")) {
00124       *key = CURLOPT_USERAGENT;
00125       *ot = OT_STRING;
00126    } else if (!strcasecmp(name, "cookie")) {
00127       *key = CURLOPT_COOKIE;
00128       *ot = OT_STRING;
00129    } else if (!strcasecmp(name, "ftptimeout")) {
00130       *key = CURLOPT_FTP_RESPONSE_TIMEOUT;
00131       *ot = OT_INTEGER;
00132    } else if (!strcasecmp(name, "httptimeout")) {
00133 #if CURLVERSION_ATLEAST(7,16,2)
00134       *key = CURLOPT_TIMEOUT_MS;
00135       *ot = OT_INTEGER_MS;
00136 #else
00137       *key = CURLOPT_TIMEOUT;
00138       *ot = OT_INTEGER;
00139 #endif
00140    } else if (!strcasecmp(name, "conntimeout")) {
00141 #if CURLVERSION_ATLEAST(7,16,2)
00142       *key = CURLOPT_CONNECTTIMEOUT_MS;
00143       *ot = OT_INTEGER_MS;
00144 #else
00145       *key = CURLOPT_CONNECTTIMEOUT;
00146       *ot = OT_INTEGER;
00147 #endif
00148    } else if (!strcasecmp(name, "ftptext")) {
00149       *key = CURLOPT_TRANSFERTEXT;
00150       *ot = OT_BOOLEAN;
00151    } else if (!strcasecmp(name, "ssl_verifypeer")) {
00152       *key = CURLOPT_SSL_VERIFYPEER;
00153       *ot = OT_BOOLEAN;
00154    } else if (!strcasecmp(name, "hashcompat")) {
00155       *key = CURLOPT_SPECIAL_HASHCOMPAT;
00156       *ot = OT_BOOLEAN;
00157    } else {
00158       return -1;
00159    }
00160    return 0;
00161 }

static int unload_module ( void   )  [static]

Definition at line 542 of file func_curl.c.

References acf_curl, acf_curlopt, and ast_custom_function_unregister().

00543 {
00544    int res;
00545 
00546    res = ast_custom_function_unregister(&acf_curl);
00547    res |= ast_custom_function_unregister(&acf_curlopt);
00548 
00549    return res;
00550 }

static size_t WriteMemoryCallback ( void *  ptr,
size_t  size,
size_t  nmemb,
void *  data 
) [static]

Definition at line 355 of file func_curl.c.

References ast_debug, ast_str_append_substr(), ast_str_size(), and ast_str_strlen().

Referenced by curl_instance_init().

00356 {
00357    register int realsize = size * nmemb;
00358    struct ast_str **pstr = (struct ast_str **)data;
00359 
00360    ast_debug(3, "Called with data=%p, str=%p, realsize=%d, len=%zu, used=%zu\n", data, *pstr, realsize, ast_str_size(*pstr), ast_str_strlen(*pstr));
00361 
00362    ast_str_append_substr(pstr, 0, ptr, realsize);
00363 
00364    ast_debug(3, "Now, len=%zu, used=%zu\n", ast_str_size(*pstr), ast_str_strlen(*pstr));
00365 
00366    return realsize;
00367 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Load external URL" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "0901e4e500243c855563a2d78b0c03e4" , .load = load_module, .unload = unload_module, } [static]

Definition at line 569 of file func_curl.c.

Definition at line 505 of file func_curl.c.

Referenced by load_module(), and unload_module().

Definition at line 515 of file func_curl.c.

Referenced by load_module(), and unload_module().

Definition at line 569 of file func_curl.c.

struct ast_datastore_info curl_info [static]
Initial value:
 {
   .type = "CURL",
   .destroy = curlds_free,
}

Definition at line 60 of file func_curl.c.

struct ast_threadstorage curl_instance = { .once = PTHREAD_ONCE_INIT , .key_init = __init_curl_instance , .custom_init = curl_instance_init , } [static]

Definition at line 395 of file func_curl.c.

Referenced by acf_curl_exec().

const char* global_useragent = "asterisk-libcurl-agent/1.0" [static]

Definition at line 369 of file func_curl.c.

Referenced by curl_instance_init().


Generated by  doxygen 1.6.2