Wed Aug 18 22:34:24 2010

Asterisk developer's documentation


func_strings.c File Reference

String manipulation dialplan functions. More...

#include "asterisk.h"
#include <regex.h>
#include <ctype.h>
#include "asterisk/module.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/utils.h"
#include "asterisk/app.h"
#include "asterisk/localtime.h"

Go to the source code of this file.

Defines

#define HASH_FORMAT   HASH_PREFIX "%s~"
#define HASH_PREFIX   "~HASH~%s~"
#define SPRINTF_CONVERSION   4
#define SPRINTF_FLAG   0
#define SPRINTF_LENGTH   3
#define SPRINTF_PRECISION   2
#define SPRINTF_WIDTH   1

Functions

static void __reg_module (void)
static void __unreg_module (void)
static int acf_sprintf (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
static int acf_strftime (struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t buflen)
static int acf_strptime (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static int array (struct ast_channel *chan, const char *cmd, char *var, const char *value)
static void clearvar_prefix (struct ast_channel *chan, const char *prefix)
static int csv_quote (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
static int exec_clearhash (struct ast_channel *chan, void *data)
static int filter (struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
static int function_eval (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static int function_fieldqty (struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
static int hash_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
static int hash_write (struct ast_channel *chan, const char *cmd, char *var, const char *value)
static int hashkeys_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
static int keypadhash (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static int len (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static int load_module (void)
static int quote (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
static int regex (struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
static int string_tolower (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static int string_toupper (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static int unload_module (void)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "String handling dialplan functions" , .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 = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, }
static char * app_clearhash = "ClearHash"
static struct ast_custom_function array_function
static struct ast_module_infoast_module_info = &__mod_info
static struct ast_custom_function csv_quote_function
static char * desc_clearhash
static struct ast_custom_function eval_function
static struct ast_custom_function fieldqty_function
static struct ast_custom_function filter_function
static struct ast_custom_function hash_function
static struct ast_custom_function hashkeys_function
static struct ast_custom_function keypadhash_function
static struct ast_custom_function len_function
static struct ast_custom_function quote_function
static struct ast_custom_function regex_function
static struct ast_custom_function sprintf_function
static struct ast_custom_function strftime_function
static struct ast_custom_function strptime_function
static char * syn_clearhash = "Clear the keys from a specified hashname"
static struct ast_custom_function tolower_function
static struct ast_custom_function toupper_function


Detailed Description

String manipulation dialplan functions.

Author:
Tilghman Lesher

Anothony Minessale II

Definition in file func_strings.c.


Define Documentation

#define HASH_FORMAT   HASH_PREFIX "%s~"

Definition at line 223 of file func_strings.c.

Referenced by array(), hash_read(), and hash_write().

#define HASH_PREFIX   "~HASH~%s~"

Definition at line 222 of file func_strings.c.

Referenced by exec_clearhash(), and hashkeys_read().

#define SPRINTF_CONVERSION   4

Referenced by acf_sprintf().

#define SPRINTF_FLAG   0

Referenced by acf_sprintf().

#define SPRINTF_LENGTH   3

Referenced by acf_sprintf().

#define SPRINTF_PRECISION   2

Referenced by acf_sprintf().

#define SPRINTF_WIDTH   1

Referenced by acf_sprintf().


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 950 of file func_strings.c.

static void __unreg_module ( void   )  [static]

Definition at line 950 of file func_strings.c.

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

Definition at line 442 of file func_strings.c.

References AST_APP_ARG, AST_DECLARE_APP_ARGS, AST_STANDARD_APP_ARGS, format, SPRINTF_CONVERSION, SPRINTF_FLAG, SPRINTF_LENGTH, SPRINTF_PRECISION, SPRINTF_WIDTH, and var.

00443 {
00444 #define SPRINTF_FLAG 0
00445 #define SPRINTF_WIDTH   1
00446 #define SPRINTF_PRECISION  2
00447 #define SPRINTF_LENGTH  3
00448 #define SPRINTF_CONVERSION 4
00449    int i, state = -1, argcount = 0;
00450    char *formatstart = NULL, *bufptr = buf;
00451    char formatbuf[256] = "";
00452    int tmpi;
00453    double tmpd;
00454    AST_DECLARE_APP_ARGS(arg,
00455             AST_APP_ARG(format);
00456             AST_APP_ARG(var)[100];
00457    );
00458 
00459    AST_STANDARD_APP_ARGS(arg, data);
00460 
00461    /* Scan the format, converting each argument into the requisite format type. */
00462    for (i = 0; arg.format[i]; i++) {
00463       switch (state) {
00464       case SPRINTF_FLAG:
00465          if (strchr("#0- +'I", arg.format[i]))
00466             break;
00467          state = SPRINTF_WIDTH;
00468       case SPRINTF_WIDTH:
00469          if (arg.format[i] >= '0' && arg.format[i] <= '9')
00470             break;
00471 
00472          /* Next character must be a period to go into a precision */
00473          if (arg.format[i] == '.') {
00474             state = SPRINTF_PRECISION;
00475          } else {
00476             state = SPRINTF_LENGTH;
00477             i--;
00478          }
00479          break;
00480       case SPRINTF_PRECISION:
00481          if (arg.format[i] >= '0' && arg.format[i] <= '9')
00482             break;
00483          state = SPRINTF_LENGTH;
00484       case SPRINTF_LENGTH:
00485          if (strchr("hl", arg.format[i])) {
00486             if (arg.format[i + 1] == arg.format[i])
00487                i++;
00488             state = SPRINTF_CONVERSION;
00489             break;
00490          } else if (strchr("Lqjzt", arg.format[i])) {
00491             state = SPRINTF_CONVERSION;
00492             break;
00493          }
00494          state = SPRINTF_CONVERSION;
00495       case SPRINTF_CONVERSION:
00496          if (strchr("diouxXc", arg.format[i])) {
00497             /* Integer */
00498 
00499             /* Isolate this format alone */
00500             ast_copy_string(formatbuf, formatstart, sizeof(formatbuf));
00501             formatbuf[&arg.format[i] - formatstart + 1] = '\0';
00502 
00503             /* Convert the argument into the required type */
00504             if (arg.var[argcount]) {
00505                if (sscanf(arg.var[argcount++], "%30d", &tmpi) != 1) {
00506                   ast_log(LOG_ERROR, "Argument '%s' is not an integer number for format '%s'\n", arg.var[argcount - 1], formatbuf);
00507                   goto sprintf_fail;
00508                }
00509             } else {
00510                ast_log(LOG_ERROR, "SPRINTF() has more format specifiers than arguments!\n");
00511                goto sprintf_fail;
00512             }
00513 
00514             /* Format the argument */
00515             snprintf(bufptr, buf + len - bufptr, formatbuf, tmpi);
00516 
00517             /* Update the position of the next parameter to print */
00518             bufptr = strchr(buf, '\0');
00519          } else if (strchr("eEfFgGaA", arg.format[i])) {
00520             /* Double */
00521 
00522             /* Isolate this format alone */
00523             ast_copy_string(formatbuf, formatstart, sizeof(formatbuf));
00524             formatbuf[&arg.format[i] - formatstart + 1] = '\0';
00525 
00526             /* Convert the argument into the required type */
00527             if (arg.var[argcount]) {
00528                if (sscanf(arg.var[argcount++], "%30lf", &tmpd) != 1) {
00529                   ast_log(LOG_ERROR, "Argument '%s' is not a floating point number for format '%s'\n", arg.var[argcount - 1], formatbuf);
00530                   goto sprintf_fail;
00531                }
00532             } else {
00533                ast_log(LOG_ERROR, "SPRINTF() has more format specifiers than arguments!\n");
00534                goto sprintf_fail;
00535             }
00536 
00537             /* Format the argument */
00538             snprintf(bufptr, buf + len - bufptr, formatbuf, tmpd);
00539 
00540             /* Update the position of the next parameter to print */
00541             bufptr = strchr(buf, '\0');
00542          } else if (arg.format[i] == 's') {
00543             /* String */
00544 
00545             /* Isolate this format alone */
00546             ast_copy_string(formatbuf, formatstart, sizeof(formatbuf));
00547             formatbuf[&arg.format[i] - formatstart + 1] = '\0';
00548 
00549             /* Format the argument */
00550             snprintf(bufptr, buf + len - bufptr, formatbuf, arg.var[argcount++]);
00551 
00552             /* Update the position of the next parameter to print */
00553             bufptr = strchr(buf, '\0');
00554          } else if (arg.format[i] == '%') {
00555             /* Literal data to copy */
00556             *bufptr++ = arg.format[i];
00557          } else {
00558             /* Not supported */
00559 
00560             /* Isolate this format alone */
00561             ast_copy_string(formatbuf, formatstart, sizeof(formatbuf));
00562             formatbuf[&arg.format[i] - formatstart + 1] = '\0';
00563 
00564             ast_log(LOG_ERROR, "Format type not supported: '%s' with argument '%s'\n", formatbuf, arg.var[argcount++]);
00565             goto sprintf_fail;
00566          }
00567          state = -1;
00568          break;
00569       default:
00570          if (arg.format[i] == '%') {
00571             state = SPRINTF_FLAG;
00572             formatstart = &arg.format[i];
00573             break;
00574          } else {
00575             /* Literal data to copy */
00576             *bufptr++ = arg.format[i];
00577          }
00578       }
00579    }
00580    *bufptr = '\0';
00581    return 0;
00582 sprintf_fail:
00583    return -1;
00584 }

static int acf_strftime ( struct ast_channel chan,
const char *  cmd,
char *  parse,
char *  buf,
size_t  buflen 
) [static]

Definition at line 693 of file func_strings.c.

References AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_get_timeval(), ast_localtime(), ast_log(), AST_STANDARD_APP_ARGS, ast_strftime(), ast_tvnow(), format, and LOG_WARNING.

00695 {
00696    AST_DECLARE_APP_ARGS(args,
00697               AST_APP_ARG(epoch);
00698               AST_APP_ARG(timezone);
00699               AST_APP_ARG(format);
00700    );
00701    struct timeval when;
00702    struct ast_tm tm;
00703 
00704    buf[0] = '\0';
00705 
00706    AST_STANDARD_APP_ARGS(args, parse);
00707 
00708    ast_get_timeval(args.epoch, &when, ast_tvnow(), NULL);
00709    ast_localtime(&when, &tm, args.timezone);
00710 
00711    if (!args.format)
00712       args.format = "%c";
00713 
00714    if (ast_strftime(buf, buflen, args.format, &tm) <= 0)
00715       ast_log(LOG_WARNING, "C function strftime() output nothing?!!\n");
00716 
00717    buf[buflen - 1] = '\0';
00718 
00719    return 0;
00720 }

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

Definition at line 737 of file func_strings.c.

References AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), ast_mktime(), AST_STANDARD_APP_ARGS, ast_strlen_zero(), format, LOG_ERROR, and LOG_WARNING.

00739 {
00740    AST_DECLARE_APP_ARGS(args,
00741               AST_APP_ARG(timestring);
00742               AST_APP_ARG(timezone);
00743               AST_APP_ARG(format);
00744    );
00745    union {
00746       struct ast_tm atm;
00747       struct tm time;
00748    } t = { { 0, }, };
00749 
00750    buf[0] = '\0';
00751 
00752    if (!data) {
00753       ast_log(LOG_ERROR,
00754             "Asterisk function STRPTIME() requires an argument.\n");
00755       return -1;
00756    }
00757 
00758    AST_STANDARD_APP_ARGS(args, data);
00759 
00760    if (ast_strlen_zero(args.format)) {
00761       ast_log(LOG_ERROR,
00762             "No format supplied to STRPTIME(<timestring>,<timezone>,<format>)");
00763       return -1;
00764    }
00765 
00766    if (!strptime(args.timestring, args.format, &t.time)) {
00767       ast_log(LOG_WARNING, "C function strptime() output nothing?!!\n");
00768    } else {
00769       struct timeval when;
00770       /* Since strptime(3) does not check DST, force ast_mktime() to calculate it. */
00771       t.atm.tm_isdst = -1;
00772       when = ast_mktime(&t.atm, args.timezone);
00773       snprintf(buf, buflen, "%d", (int) when.tv_sec);
00774    }
00775 
00776    return 0;
00777 }

static int array ( struct ast_channel chan,
const char *  cmd,
char *  var,
const char *  value 
) [static]

Definition at line 253 of file func_strings.c.

References AST_APP_ARG, ast_autoservice_stop(), ast_debug, AST_DECLARE_APP_ARGS, AST_STANDARD_APP_ARGS, ast_strdupa, chan, HASH_FORMAT, pbx_builtin_getvar_helper(), and pbx_builtin_setvar_helper().

Referenced by hash_write().

00255 {
00256    AST_DECLARE_APP_ARGS(arg1,
00257               AST_APP_ARG(var)[100];
00258    );
00259    AST_DECLARE_APP_ARGS(arg2,
00260               AST_APP_ARG(val)[100];
00261    );
00262    char *origvar = "", *value2, varname[256];
00263    int i, ishash = 0;
00264 
00265    value2 = ast_strdupa(value);
00266    if (!var || !value2)
00267       return -1;
00268 
00269    if (!strcmp(cmd, "HASH")) {
00270       const char *var2 = pbx_builtin_getvar_helper(chan, "~ODBCFIELDS~");
00271       origvar = var;
00272       if (var2)
00273          var = ast_strdupa(var2);
00274       else {
00275          if (chan)
00276             ast_autoservice_stop(chan);
00277          return -1;
00278       }
00279       ishash = 1;
00280    }
00281 
00282    /* The functions this will generally be used with are SORT and ODBC_*, which
00283     * both return comma-delimited lists.  However, if somebody uses literal lists,
00284     * their commas will be translated to vertical bars by the load, and I don't
00285     * want them to be surprised by the result.  Hence, we prefer commas as the
00286     * delimiter, but we'll fall back to vertical bars if commas aren't found.
00287     */
00288    ast_debug(1, "array (%s=%s)\n", var, value2);
00289    AST_STANDARD_APP_ARGS(arg1, var);
00290 
00291    AST_STANDARD_APP_ARGS(arg2, value2);
00292 
00293    for (i = 0; i < arg1.argc; i++) {
00294       ast_debug(1, "array set value (%s=%s)\n", arg1.var[i],
00295             arg2.val[i]);
00296       if (i < arg2.argc) {
00297          if (ishash) {
00298             snprintf(varname, sizeof(varname), HASH_FORMAT, origvar, arg1.var[i]);
00299             pbx_builtin_setvar_helper(chan, varname, arg2.val[i]);
00300          } else {
00301             pbx_builtin_setvar_helper(chan, arg1.var[i], arg2.val[i]);
00302          }
00303       } else {
00304          /* We could unset the variable, by passing a NULL, but due to
00305           * pushvar semantics, that could create some undesired behavior. */
00306          if (ishash) {
00307             snprintf(varname, sizeof(varname), HASH_FORMAT, origvar, arg1.var[i]);
00308             pbx_builtin_setvar_helper(chan, varname, "");
00309          } else {
00310             pbx_builtin_setvar_helper(chan, arg1.var[i], "");
00311          }
00312       }
00313    }
00314 
00315    return 0;
00316 }

static void clearvar_prefix ( struct ast_channel chan,
const char *  prefix 
) [static]

Definition at line 232 of file func_strings.c.

References ast_free, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_var_name(), chan, ast_var_t::entries, len(), var, and ast_channel::varshead.

Referenced by exec_clearhash().

00233 {
00234    struct ast_var_t *var;
00235    int len = strlen(prefix);
00236    AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->varshead, var, entries) {
00237       if (strncasecmp(prefix, ast_var_name(var), len) == 0) {
00238          AST_LIST_REMOVE_CURRENT(entries);
00239          ast_free(var);
00240       }
00241    }
00242    AST_LIST_TRAVERSE_SAFE_END
00243 }

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

Definition at line 638 of file func_strings.c.

References ast_copy_string(), ast_log(), ast_strlen_zero(), LOG_ERROR, and LOG_WARNING.

00639 {
00640    char *bufptr = buf, *dataptr = data;
00641 
00642    if (len < 3){ /* at least two for quotes and one for binary zero */
00643       ast_log(LOG_ERROR, "Not enough buffer");
00644       return -1;
00645    }
00646 
00647    if (ast_strlen_zero(data)) {
00648       ast_log(LOG_WARNING, "No argument specified!\n");
00649       ast_copy_string(buf,"\"\"",len);
00650       return 0;
00651    }
00652 
00653    *bufptr++ = '"';
00654    for (; bufptr < buf + len - 3; dataptr++){
00655       if (*dataptr == '"') {
00656          *bufptr++ = '"';
00657          *bufptr++ = '"';
00658       } else if (*dataptr == '\0') {
00659          break;
00660       } else {
00661          *bufptr++ = *dataptr;
00662       }
00663    }
00664    *bufptr++ = '"';
00665    *bufptr='\0';
00666    return 0;
00667 }

static int exec_clearhash ( struct ast_channel chan,
void *  data 
) [static]

Definition at line 245 of file func_strings.c.

References chan, clearvar_prefix(), HASH_PREFIX, and prefix.

Referenced by load_module().

00246 {
00247    char prefix[80];
00248    snprintf(prefix, sizeof(prefix), HASH_PREFIX, data ? (char *)data : "null");
00249    clearvar_prefix(chan, prefix);
00250    return 0;
00251 }

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

Definition at line 83 of file func_strings.c.

References AST_APP_ARG, ast_debug, AST_DECLARE_APP_ARGS, ast_get_encoded_char(), ast_log(), ast_opt_dont_warn, AST_STANDARD_RAW_ARGS, LOG_ERROR, and LOG_WARNING.

Referenced by append_var_and_value_to_filter(), realtime_ldap_base_ap(), and update_ldap().

00085 {
00086    AST_DECLARE_APP_ARGS(args,
00087               AST_APP_ARG(allowed);
00088               AST_APP_ARG(string);
00089    );
00090    char *outbuf = buf;
00091    unsigned char ac;
00092    char allowed[256] = "";
00093    size_t allowedlen = 0;
00094    int32_t bitfield[8] = { 0, }; /* 256 bits */
00095 
00096    AST_STANDARD_RAW_ARGS(args, parse);
00097 
00098    if (!args.string) {
00099       ast_log(LOG_ERROR, "Usage: FILTER(<allowed-chars>,<string>)\n");
00100       return -1;
00101    }
00102 
00103    if (args.allowed[0] == '"' && !ast_opt_dont_warn) {
00104       ast_log(LOG_WARNING, "FILTER allowed characters includes the quote (\") character.  This may not be what you want.\n");
00105    }
00106 
00107    /* Expand ranges */
00108    for (; *(args.allowed);) {
00109       char c1 = 0, c2 = 0;
00110       size_t consumed = 0;
00111 
00112       if (ast_get_encoded_char(args.allowed, &c1, &consumed))
00113          return -1;
00114       args.allowed += consumed;
00115 
00116       if (*(args.allowed) == '-') {
00117          if (ast_get_encoded_char(args.allowed + 1, &c2, &consumed))
00118             c2 = -1;
00119          args.allowed += consumed + 1;
00120 
00121          if ((c2 < c1 || c2 == -1) && !ast_opt_dont_warn) {
00122             ast_log(LOG_WARNING, "Range wrapping in FILTER(%s,%s).  This may not be what you want.\n", parse, args.string);
00123          }
00124 
00125          /*!\note
00126           * Looks a little strange, until you realize that we can overflow
00127           * the size of a char.
00128           */
00129          for (ac = c1; ac != c2; ac++) {
00130             bitfield[ac / 32] |= 1 << (ac % 32);
00131          }
00132          bitfield[ac / 32] |= 1 << (ac % 32);
00133 
00134          ast_debug(4, "c1=%d, c2=%d\n", c1, c2);
00135       } else {
00136          ac = (unsigned char) c1;
00137          ast_debug(4, "c1=%d, consumed=%d, args.allowed=%s\n", c1, (int) consumed, args.allowed - consumed);
00138          bitfield[ac / 32] |= 1 << (ac % 32);
00139       }
00140    }
00141 
00142    for (ac = 1; ac != 0; ac++) {
00143       if (bitfield[ac / 32] & (1 << (ac % 32))) {
00144          allowed[allowedlen++] = ac;
00145       }
00146    }
00147 
00148    ast_debug(1, "Allowed: %s\n", allowed);
00149 
00150    for (; *(args.string) && (buf + len - 1 > outbuf); (args.string)++) {
00151       if (strchr(allowed, *(args.string)))
00152          *outbuf++ = *(args.string);
00153    }
00154    *outbuf = '\0';
00155 
00156    return 0;
00157 }

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

Definition at line 794 of file func_strings.c.

References ast_log(), ast_strlen_zero(), chan, LOG_WARNING, and pbx_substitute_variables_helper().

00796 {
00797    if (ast_strlen_zero(data)) {
00798       ast_log(LOG_WARNING, "EVAL requires an argument: EVAL(<string>)\n");
00799       return -1;
00800    }
00801 
00802    pbx_substitute_variables_helper(chan, data, buf, buflen - 1);
00803 
00804    return 0;
00805 }

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

Definition at line 42 of file func_strings.c.

References AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_get_encoded_char(), AST_STANDARD_APP_ARGS, ast_strlen_zero(), chan, pbx_substitute_variables_helper(), and strsep().

00044 {
00045    char *varsubst, varval[8192], *varval2 = varval;
00046    int fieldcount = 0;
00047    AST_DECLARE_APP_ARGS(args,
00048               AST_APP_ARG(varname);
00049               AST_APP_ARG(delim);
00050       );
00051    char delim[2] = "";
00052    size_t delim_used;
00053 
00054    AST_STANDARD_APP_ARGS(args, parse);
00055    if (args.delim) {
00056       ast_get_encoded_char(args.delim, delim, &delim_used);
00057 
00058       varsubst = alloca(strlen(args.varname) + 4);
00059 
00060       sprintf(varsubst, "${%s}", args.varname);
00061       pbx_substitute_variables_helper(chan, varsubst, varval, sizeof(varval) - 1);
00062       if (ast_strlen_zero(varval2))
00063          fieldcount = 0;
00064       else {
00065          while (strsep(&varval2, delim))
00066             fieldcount++;
00067       }
00068    } else {
00069       fieldcount = 1;
00070    }
00071    snprintf(buf, len, "%d", fieldcount);
00072 
00073    return 0;
00074 }

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

Definition at line 360 of file func_strings.c.

References AST_APP_ARG, ast_copy_string(), AST_DECLARE_APP_ARGS, AST_STANDARD_APP_ARGS, chan, HASH_FORMAT, hashkeys_read(), pbx_builtin_getvar_helper(), and pbx_builtin_setvar_helper().

00361 {
00362    char varname[256];
00363    const char *varvalue;
00364    AST_DECLARE_APP_ARGS(arg,
00365       AST_APP_ARG(hashname);
00366       AST_APP_ARG(hashkey);
00367    );
00368 
00369    AST_STANDARD_APP_ARGS(arg, data);
00370    if (arg.argc == 2) {
00371       snprintf(varname, sizeof(varname), HASH_FORMAT, arg.hashname, arg.hashkey);
00372       varvalue = pbx_builtin_getvar_helper(chan, varname);
00373       if (varvalue)
00374          ast_copy_string(buf, varvalue, len);
00375       else
00376          *buf = '\0';
00377    } else if (arg.argc == 1) {
00378       char colnames[4096];
00379       int i;
00380       AST_DECLARE_APP_ARGS(arg2,
00381          AST_APP_ARG(col)[100];
00382       );
00383 
00384       /* Get column names, in no particular order */
00385       hashkeys_read(chan, "HASHKEYS", arg.hashname, colnames, sizeof(colnames));
00386       pbx_builtin_setvar_helper(chan, "~ODBCFIELDS~", colnames);
00387 
00388       AST_STANDARD_APP_ARGS(arg2, colnames);
00389       *buf = '\0';
00390 
00391       /* Now get the corresponding column values, in exactly the same order */
00392       for (i = 0; i < arg2.argc; i++) {
00393          snprintf(varname, sizeof(varname), HASH_FORMAT, arg.hashname, arg2.col[i]);
00394          varvalue = pbx_builtin_getvar_helper(chan, varname);
00395          strncat(buf, varvalue, len - strlen(buf) - 1);
00396          strncat(buf, ",", len - strlen(buf) - 1);
00397       }
00398 
00399       /* Strip trailing comma */
00400       buf[strlen(buf) - 1] = '\0';
00401    }
00402 
00403    return 0;
00404 }

static int hash_write ( struct ast_channel chan,
const char *  cmd,
char *  var,
const char *  value 
) [static]

Definition at line 340 of file func_strings.c.

References array(), AST_APP_ARG, AST_DECLARE_APP_ARGS, AST_STANDARD_APP_ARGS, chan, HASH_FORMAT, and pbx_builtin_setvar_helper().

00341 {
00342    char varname[256];
00343    AST_DECLARE_APP_ARGS(arg,
00344       AST_APP_ARG(hashname);
00345       AST_APP_ARG(hashkey);
00346    );
00347 
00348    if (!strchr(var, ',')) {
00349       /* Single argument version */
00350       return array(chan, "HASH", var, value);
00351    }
00352 
00353    AST_STANDARD_APP_ARGS(arg, var);
00354    snprintf(varname, sizeof(varname), HASH_FORMAT, arg.hashname, arg.hashkey);
00355    pbx_builtin_setvar_helper(chan, varname, value);
00356 
00357    return 0;
00358 }

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

Definition at line 318 of file func_strings.c.

References AST_LIST_TRAVERSE, ast_var_name(), chan, ast_var_t::entries, HASH_PREFIX, prefix, and ast_channel::varshead.

Referenced by hash_read().

00319 {
00320    struct ast_var_t *newvar;
00321    int plen;
00322    char prefix[80];
00323    snprintf(prefix, sizeof(prefix), HASH_PREFIX, data);
00324    plen = strlen(prefix);
00325 
00326    memset(buf, 0, len);
00327    AST_LIST_TRAVERSE(&chan->varshead, newvar, entries) {
00328       if (strncasecmp(prefix, ast_var_name(newvar), plen) == 0) {
00329          /* Copy everything after the prefix */
00330          strncat(buf, ast_var_name(newvar) + plen, len - strlen(buf) - 1);
00331          /* Trim the trailing ~ */
00332          buf[strlen(buf) - 1] = ',';
00333       }
00334    }
00335    /* Trim the trailing comma */
00336    buf[strlen(buf) - 1] = '\0';
00337    return 0;
00338 }

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

Definition at line 823 of file func_strings.c.

00824 {
00825    char *bufptr, *dataptr;
00826 
00827    for (bufptr = buf, dataptr = data; bufptr < buf + buflen - 1; dataptr++) {
00828       if (*dataptr == '\0') {
00829          *bufptr++ = '\0';
00830          break;
00831       } else if (*dataptr == '1') {
00832          *bufptr++ = '1';
00833       } else if (strchr("AaBbCc2", *dataptr)) {
00834          *bufptr++ = '2';
00835       } else if (strchr("DdEeFf3", *dataptr)) {
00836          *bufptr++ = '3';
00837       } else if (strchr("GgHhIi4", *dataptr)) {
00838          *bufptr++ = '4';
00839       } else if (strchr("JjKkLl5", *dataptr)) {
00840          *bufptr++ = '5';
00841       } else if (strchr("MmNnOo6", *dataptr)) {
00842          *bufptr++ = '6';
00843       } else if (strchr("PpQqRrSs7", *dataptr)) {
00844          *bufptr++ = '7';
00845       } else if (strchr("TtUuVv8", *dataptr)) {
00846          *bufptr++ = '8';
00847       } else if (strchr("WwXxYyZz9", *dataptr)) {
00848          *bufptr++ = '9';
00849       } else if (*dataptr == '0') {
00850          *bufptr++ = '0';
00851       }
00852    }
00853    buf[buflen - 1] = '\0';
00854 
00855    return 0;
00856 }

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

Definition at line 674 of file func_strings.c.

Referenced by __ast_cli_register(), __get_header(), _parse(), add_sdp(), aji_io_recv(), aji_recv(), aji_send_header(), aji_send_raw(), aji_start_sasl(), alsa_write(), append_interface(), append_var_and_value_to_filter(), ast_app_group_set_channel(), ast_cdr_appenduserfield(), ast_cli_complete(), ast_codec_get_len(), ast_dsp_noise(), ast_dsp_process(), ast_dsp_silence(), ast_feature_request_and_dial(), ast_format_str_reduce(), ast_frdup(), ast_getformatname_multiple(), ast_http_uri_link(), ast_mkdir(), ast_read_image(), ast_rtcp_read(), ast_rtcp_write_rr(), ast_rtcp_write_sr(), ast_rtp_lookup_mime_multiple(), ast_rtp_read(), ast_say_number_full_ka(), ast_smoother_read(), ast_translate(), ast_udptl_read(), ast_udptl_write(), authenticate(), build_device(), build_facility(), builtin_automixmonitor(), builtin_automonitor(), callerid_generate(), cleaned_basedn(), clearvar_prefix(), cli_complete(), cli_console_sendtext(), complete_agent_logoff_cmd(), complete_dialplan_add_extension(), complete_dialplan_add_ignorepat(), complete_dialplan_add_include(), complete_dialplan_remove_extension(), complete_dialplan_remove_ignorepat(), complete_dialplan_remove_include(), complete_meetmecmd(), complete_peer_helper(), conf_play(), config_jitterbuffer(), copy(), create_video_frame(), dahdi_sendtext(), dahdi_setoption(), devstate_write(), dialgroup_refreshdb(), dictate_exec(), dundi_encrypt(), dundi_parse_ies(), dundi_send(), expr2_token_subst(), ffmpeg_decode(), get_sdp(), get_sdp_iterate(), get_to_address(), gsm_write(), gsmtolin_framein(), h261_encap(), h263_encap(), h263_read(), h263_write(), h263p_encap(), h264_read(), h264_write(), handle_cli_devstate_change(), handle_commandmatchesarray(), handle_output(), handle_response(), help1(), iax_parse_ies(), iax_str2flags(), launch_monitor_thread(), listener(), load_file(), local_call(), lpc10tolin_framein(), message_template_parse_emailbody(), mgcp_ss(), mgcpsock_read(), misdn_read(), monmp3thread(), mpeg4_encap(), newpvt(), ogg_vorbis_read(), parse_ie(), ParseBookmark(), pbx_load_users(), pbx_substitute_variables_helper_full(), phoneprov_callback(), process_sdp(), readfile_exec(), reschedule_precache(), run_agi(), skinny_ss(), sms_messagetx(), socket_read(), ss_thread(), static_callback(), term_filter_escapes(), transfer_exec(), udptl_build_packet(), unistim_sp(), unquote(), vmwi_generate(), and wav_write().

00675 {
00676    int length = 0;
00677 
00678    if (data)
00679       length = strlen(data);
00680 
00681    snprintf(buf, buflen, "%d", length);
00682 
00683    return 0;
00684 }

static int load_module ( void   )  [static]

Definition at line 925 of file func_strings.c.

References app_clearhash, array_function, ast_custom_function_register, ast_register_application, csv_quote_function, desc_clearhash, eval_function, exec_clearhash(), fieldqty_function, filter_function, hash_function, hashkeys_function, keypadhash_function, len_function, quote_function, regex_function, sprintf_function, strftime_function, strptime_function, syn_clearhash, tolower_function, and toupper_function.

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

Definition at line 597 of file func_strings.c.

References ast_copy_string(), ast_log(), ast_strlen_zero(), LOG_ERROR, and LOG_WARNING.

Referenced by __ast_app_separate_args(), make_email_file(), and parse_options().

00598 {
00599    char *bufptr = buf, *dataptr = data;
00600 
00601    if (len < 3){ /* at least two for quotes and one for binary zero */
00602       ast_log(LOG_ERROR, "Not enough buffer");
00603       return -1;
00604    }
00605 
00606    if (ast_strlen_zero(data)) {
00607       ast_log(LOG_WARNING, "No argument specified!\n");
00608       ast_copy_string(buf, "\"\"", len);
00609       return 0;
00610    }
00611 
00612    *bufptr++ = '"';
00613    for (; bufptr < buf + len - 3; dataptr++) {
00614       if (*dataptr == '\\') {
00615          *bufptr++ = '\\';
00616          *bufptr++ = '\\';
00617       } else if (*dataptr == '"') {
00618          *bufptr++ = '\\';
00619          *bufptr++ = '"';
00620       } else if (*dataptr == '\0') {
00621          break;
00622       } else {
00623          *bufptr++ = *dataptr;
00624       }
00625    }
00626    *bufptr++ = '"';
00627    *bufptr = '\0';
00628    return 0;
00629 }

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

Definition at line 173 of file func_strings.c.

References AST_APP_ARG, ast_debug, AST_DECLARE_APP_ARGS, ast_log(), AST_NONSTANDARD_APP_ARGS, LOG_ERROR, LOG_WARNING, and str.

00175 {
00176    AST_DECLARE_APP_ARGS(args,
00177               AST_APP_ARG(null);
00178               AST_APP_ARG(reg);
00179               AST_APP_ARG(str);
00180    );
00181    int errcode;
00182    regex_t regexbuf;
00183 
00184    buf[0] = '\0';
00185 
00186    AST_NONSTANDARD_APP_ARGS(args, parse, '"');
00187 
00188    if (args.argc != 3) {
00189       ast_log(LOG_ERROR, "Unexpected arguments: should have been in the form '\"<regex>\" <string>'\n");
00190       return -1;
00191    }
00192    if ((*args.str == ' ') || (*args.str == '\t'))
00193       args.str++;
00194 
00195    ast_debug(1, "FUNCTION REGEX (%s)(%s)\n", args.reg, args.str);
00196 
00197    if ((errcode = regcomp(&regexbuf, args.reg, REG_EXTENDED | REG_NOSUB))) {
00198       regerror(errcode, &regexbuf, buf, len);
00199       ast_log(LOG_WARNING, "Malformed input %s(%s): %s\n", cmd, parse, buf);
00200       return -1;
00201    }
00202    
00203    strcpy(buf, regexec(&regexbuf, args.str, 0, NULL, 0) ? "0" : "1");
00204 
00205    regfree(&regexbuf);
00206 
00207    return 0;
00208 }

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

Definition at line 883 of file func_strings.c.

00884 {
00885    char *bufptr = buf, *dataptr = data;
00886 
00887    while ((bufptr < buf + buflen - 1) && (*bufptr++ = tolower(*dataptr++)));
00888 
00889    return 0;
00890 }

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

Definition at line 866 of file func_strings.c.

00867 {
00868    char *bufptr = buf, *dataptr = data;
00869 
00870    while ((bufptr < buf + buflen - 1) && (*bufptr++ = toupper(*dataptr++)));
00871 
00872    return 0;
00873 }

static int unload_module ( void   )  [static]

Definition at line 900 of file func_strings.c.

References app_clearhash, array_function, ast_custom_function_unregister(), ast_unregister_application(), csv_quote_function, eval_function, fieldqty_function, filter_function, hash_function, hashkeys_function, keypadhash_function, len_function, quote_function, regex_function, sprintf_function, strftime_function, strptime_function, tolower_function, and toupper_function.


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "String handling dialplan functions" , .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 = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, } [static]

Definition at line 950 of file func_strings.c.

char* app_clearhash = "ClearHash" [static]

Definition at line 225 of file func_strings.c.

Referenced by load_module(), and unload_module().

struct ast_custom_function array_function [static]

Definition at line 430 of file func_strings.c.

Referenced by load_module(), and unload_module().

struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 950 of file func_strings.c.

struct ast_custom_function csv_quote_function [static]

Initial value:

 {
   .name = "CSV_QUOTE",
   .read = csv_quote,
}

Definition at line 669 of file func_strings.c.

Referenced by load_module(), and unload_module().

char* desc_clearhash [static]

Initial value:

"ClearHash(<hashname>)\n"
"  Clears all keys out of the specified hashname\n"

Definition at line 227 of file func_strings.c.

Referenced by load_module().

struct ast_custom_function eval_function [static]

Definition at line 807 of file func_strings.c.

Referenced by load_module(), and unload_module().

struct ast_custom_function fieldqty_function [static]

Definition at line 76 of file func_strings.c.

Referenced by load_module(), and unload_module().

struct ast_custom_function filter_function [static]

Definition at line 159 of file func_strings.c.

Referenced by load_module(), and unload_module().

struct ast_custom_function hash_function [static]

Definition at line 406 of file func_strings.c.

Referenced by load_module(), and unload_module().

struct ast_custom_function hashkeys_function [static]

Definition at line 418 of file func_strings.c.

Referenced by load_module(), and unload_module().

struct ast_custom_function keypadhash_function [static]

Definition at line 858 of file func_strings.c.

Referenced by load_module(), and unload_module().

struct ast_custom_function len_function [static]

Definition at line 686 of file func_strings.c.

Referenced by load_module(), and unload_module().

struct ast_custom_function quote_function [static]

Definition at line 631 of file func_strings.c.

Referenced by load_module(), and unload_module().

struct ast_custom_function regex_function [static]

Definition at line 210 of file func_strings.c.

Referenced by load_module(), and unload_module().

struct ast_custom_function sprintf_function [static]

Definition at line 586 of file func_strings.c.

Referenced by load_module(), and unload_module().

struct ast_custom_function strftime_function [static]

Definition at line 722 of file func_strings.c.

Referenced by load_module(), and unload_module().

struct ast_custom_function strptime_function [static]

Definition at line 779 of file func_strings.c.

Referenced by load_module(), and unload_module().

char* syn_clearhash = "Clear the keys from a specified hashname" [static]

Definition at line 226 of file func_strings.c.

Referenced by load_module().

struct ast_custom_function tolower_function [static]

Definition at line 892 of file func_strings.c.

Referenced by load_module(), and unload_module().

struct ast_custom_function toupper_function [static]

Definition at line 875 of file func_strings.c.

Referenced by load_module(), and unload_module().


Generated on Wed Aug 18 22:34:24 2010 for Asterisk - the Open Source PBX by  doxygen 1.4.7