Wed Oct 28 11:46:10 2009

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"

Include dependency graph for func_strings.c:

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 len)
static int acf_strptime (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
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 len)
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 len)
static int len (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
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 len)
static int string_toupper (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
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 = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, }
static char * app_clearhash = "ClearHash"
static struct ast_custom_function array_function
static const struct
ast_module_info
ast_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 206 of file func_strings.c.

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

#define HASH_PREFIX   "~HASH~%s~"

Definition at line 205 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 933 of file func_strings.c.

static void __unreg_module ( void   )  [static]

Definition at line 933 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 425 of file func_strings.c.

References AST_APP_ARG, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_log(), AST_STANDARD_APP_ARGS, format, LOG_ERROR, SPRINTF_CONVERSION, SPRINTF_FLAG, SPRINTF_LENGTH, SPRINTF_PRECISION, SPRINTF_WIDTH, and var.

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

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

Definition at line 676 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.

00678 {
00679    AST_DECLARE_APP_ARGS(args,
00680               AST_APP_ARG(epoch);
00681               AST_APP_ARG(timezone);
00682               AST_APP_ARG(format);
00683    );
00684    struct timeval tv;
00685    struct ast_tm tm;
00686 
00687    buf[0] = '\0';
00688 
00689    AST_STANDARD_APP_ARGS(args, parse);
00690 
00691    ast_get_timeval(args.epoch, &tv, ast_tvnow(), NULL);
00692    ast_localtime(&tv, &tm, args.timezone);
00693 
00694    if (!args.format)
00695       args.format = "%c";
00696 
00697    if (ast_strftime(buf, len, args.format, &tm) <= 0)
00698       ast_log(LOG_WARNING, "C function strftime() output nothing?!!\n");
00699 
00700    buf[len - 1] = '\0';
00701 
00702    return 0;
00703 }

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

Definition at line 720 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.

00722 {
00723    AST_DECLARE_APP_ARGS(args,
00724               AST_APP_ARG(timestring);
00725               AST_APP_ARG(timezone);
00726               AST_APP_ARG(format);
00727    );
00728    union {
00729       struct ast_tm atm;
00730       struct tm time;
00731    } t = { { 0, }, };
00732 
00733    buf[0] = '\0';
00734 
00735    if (!data) {
00736       ast_log(LOG_ERROR,
00737             "Asterisk function STRPTIME() requires an argument.\n");
00738       return -1;
00739    }
00740 
00741    AST_STANDARD_APP_ARGS(args, data);
00742 
00743    if (ast_strlen_zero(args.format)) {
00744       ast_log(LOG_ERROR,
00745             "No format supplied to STRPTIME(<timestring>,<timezone>,<format>)");
00746       return -1;
00747    }
00748 
00749    if (!strptime(args.timestring, args.format, &t.time)) {
00750       ast_log(LOG_WARNING, "C function strptime() output nothing?!!\n");
00751    } else {
00752       struct timeval tv;
00753       /* Since strptime(3) does not check DST, force ast_mktime() to calculate it. */
00754       t.atm.tm_isdst = -1;
00755       tv = ast_mktime(&t.atm, args.timezone);
00756       snprintf(buf, len, "%d", (int) tv.tv_sec);
00757    }
00758 
00759    return 0;
00760 }

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

Definition at line 236 of file func_strings.c.

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

Referenced by hash_write().

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

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

Definition at line 215 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(), ast_var_t::entries, len(), var, and ast_channel::varshead.

Referenced by exec_clearhash().

00216 {
00217    struct ast_var_t *var;
00218    int len = strlen(prefix);
00219    AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->varshead, var, entries) {
00220       if (strncasecmp(prefix, ast_var_name(var), len) == 0) {
00221          AST_LIST_REMOVE_CURRENT(entries);
00222          ast_free(var);
00223       }
00224    }
00225    AST_LIST_TRAVERSE_SAFE_END
00226 }

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

Definition at line 621 of file func_strings.c.

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

00622 {
00623    char *bufptr = buf, *dataptr = data;
00624 
00625    if (len < 3){ /* at least two for quotes and one for binary zero */
00626       ast_log(LOG_ERROR, "Not enough buffer");
00627       return -1;
00628    }
00629 
00630    if (ast_strlen_zero(data)) {
00631       ast_log(LOG_WARNING, "No argument specified!\n");
00632       ast_copy_string(buf,"\"\"",len);
00633       return 0;
00634    }
00635 
00636    *bufptr++ = '"';
00637    for (; bufptr < buf + len - 3; dataptr++){
00638       if (*dataptr == '"') {
00639          *bufptr++ = '"';
00640          *bufptr++ = '"';
00641       } else if (*dataptr == '\0') {
00642          break;
00643       } else {
00644          *bufptr++ = *dataptr;
00645       }
00646    }
00647    *bufptr++ = '"';
00648    *bufptr='\0';
00649    return 0;
00650 }

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

Definition at line 228 of file func_strings.c.

References clearvar_prefix(), HASH_PREFIX, and prefix.

Referenced by load_module().

00229 {
00230    char prefix[80];
00231    snprintf(prefix, sizeof(prefix), HASH_PREFIX, data ? (char *)data : "null");
00232    clearvar_prefix(chan, prefix);
00233    return 0;
00234 }

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

Note:
Looks a little strange, until you realize that we can overflow the size of a char.

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_STANDARD_APP_ARGS, and LOG_ERROR.

Referenced by 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, ac;
00091    char allowed[256] = "";
00092    size_t allowedlen = 0;
00093 
00094    AST_STANDARD_APP_ARGS(args, parse);
00095 
00096    if (!args.string) {
00097       ast_log(LOG_ERROR, "Usage: FILTER(<allowed-chars>,<string>)\n");
00098       return -1;
00099    }
00100 
00101    /* Expand ranges */
00102    for (; *(args.allowed) && allowedlen < sizeof(allowed); ) {
00103       char c1 = 0, c2 = 0;
00104       size_t consumed = 0;
00105 
00106       if (ast_get_encoded_char(args.allowed, &c1, &consumed))
00107          return -1;
00108       args.allowed += consumed;
00109 
00110       if (*(args.allowed) == '-') {
00111          if (ast_get_encoded_char(args.allowed + 1, &c2, &consumed))
00112             c2 = -1;
00113          args.allowed += consumed + 1;
00114 
00115          /*!\note
00116           * Looks a little strange, until you realize that we can overflow
00117           * the size of a char.
00118           */
00119          for (ac = c1; ac != c2 && allowedlen < sizeof(allowed) - 1; ac++)
00120             allowed[allowedlen++] = ac;
00121          allowed[allowedlen++] = ac;
00122 
00123          ast_debug(4, "c1=%d, c2=%d\n", c1, c2);
00124 
00125          /* Decrement before the loop increment */
00126          (args.allowed)--;
00127       } else
00128          allowed[allowedlen++] = c1;
00129    }
00130 
00131    ast_debug(1, "Allowed: %s\n", allowed);
00132 
00133    for (; *(args.string) && (buf + len - 1 > outbuf); (args.string)++) {
00134       if (strchr(allowed, *(args.string)))
00135          *outbuf++ = *(args.string);
00136    }
00137    *outbuf = '\0';
00138 
00139    return 0;
00140 }

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

Definition at line 777 of file func_strings.c.

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

00779 {
00780    if (ast_strlen_zero(data)) {
00781       ast_log(LOG_WARNING, "EVAL requires an argument: EVAL(<string>)\n");
00782       return -1;
00783    }
00784 
00785    pbx_substitute_variables_helper(chan, data, buf, len - 1);
00786 
00787    return 0;
00788 }

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(), 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 343 of file func_strings.c.

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

00344 {
00345    char varname[256];
00346    const char *varvalue;
00347    AST_DECLARE_APP_ARGS(arg,
00348       AST_APP_ARG(hashname);
00349       AST_APP_ARG(hashkey);
00350    );
00351 
00352    AST_STANDARD_APP_ARGS(arg, data);
00353    if (arg.argc == 2) {
00354       snprintf(varname, sizeof(varname), HASH_FORMAT, arg.hashname, arg.hashkey);
00355       varvalue = pbx_builtin_getvar_helper(chan, varname);
00356       if (varvalue)
00357          ast_copy_string(buf, varvalue, len);
00358       else
00359          *buf = '\0';
00360    } else if (arg.argc == 1) {
00361       char colnames[4096];
00362       int i;
00363       AST_DECLARE_APP_ARGS(arg2,
00364          AST_APP_ARG(col)[100];
00365       );
00366 
00367       /* Get column names, in no particular order */
00368       hashkeys_read(chan, "HASHKEYS", arg.hashname, colnames, sizeof(colnames));
00369       pbx_builtin_setvar_helper(chan, "~ODBCFIELDS~", colnames);
00370 
00371       AST_STANDARD_APP_ARGS(arg2, colnames);
00372       *buf = '\0';
00373 
00374       /* Now get the corresponding column values, in exactly the same order */
00375       for (i = 0; i < arg2.argc; i++) {
00376          snprintf(varname, sizeof(varname), HASH_FORMAT, arg.hashname, arg2.col[i]);
00377          varvalue = pbx_builtin_getvar_helper(chan, varname);
00378          strncat(buf, varvalue, len - strlen(buf) - 1);
00379          strncat(buf, ",", len - strlen(buf) - 1);
00380       }
00381 
00382       /* Strip trailing comma */
00383       buf[strlen(buf) - 1] = '\0';
00384    }
00385 
00386    return 0;
00387 }

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

Definition at line 323 of file func_strings.c.

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

00324 {
00325    char varname[256];
00326    AST_DECLARE_APP_ARGS(arg,
00327       AST_APP_ARG(hashname);
00328       AST_APP_ARG(hashkey);
00329    );
00330 
00331    if (!strchr(var, ',')) {
00332       /* Single argument version */
00333       return array(chan, "HASH", var, value);
00334    }
00335 
00336    AST_STANDARD_APP_ARGS(arg, var);
00337    snprintf(varname, sizeof(varname), HASH_FORMAT, arg.hashname, arg.hashkey);
00338    pbx_builtin_setvar_helper(chan, varname, value);
00339 
00340    return 0;
00341 }

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

Definition at line 301 of file func_strings.c.

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

Referenced by hash_read().

00302 {
00303    struct ast_var_t *newvar;
00304    int plen;
00305    char prefix[80];
00306    snprintf(prefix, sizeof(prefix), HASH_PREFIX, data);
00307    plen = strlen(prefix);
00308 
00309    memset(buf, 0, len);
00310    AST_LIST_TRAVERSE(&chan->varshead, newvar, entries) {
00311       if (strncasecmp(prefix, ast_var_name(newvar), plen) == 0) {
00312          /* Copy everything after the prefix */
00313          strncat(buf, ast_var_name(newvar) + plen, len - strlen(buf) - 1);
00314          /* Trim the trailing ~ */
00315          buf[strlen(buf) - 1] = ',';
00316       }
00317    }
00318    /* Trim the trailing comma */
00319    buf[strlen(buf) - 1] = '\0';
00320    return 0;
00321 }

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

Definition at line 806 of file func_strings.c.

00807 {
00808    char *bufptr, *dataptr;
00809 
00810    for (bufptr = buf, dataptr = data; bufptr < buf + len - 1; dataptr++) {
00811       if (*dataptr == '\0') {
00812          *bufptr++ = '\0';
00813          break;
00814       } else if (*dataptr == '1') {
00815          *bufptr++ = '1';
00816       } else if (strchr("AaBbCc2", *dataptr)) {
00817          *bufptr++ = '2';
00818       } else if (strchr("DdEeFf3", *dataptr)) {
00819          *bufptr++ = '3';
00820       } else if (strchr("GgHhIi4", *dataptr)) {
00821          *bufptr++ = '4';
00822       } else if (strchr("JjKkLl5", *dataptr)) {
00823          *bufptr++ = '5';
00824       } else if (strchr("MmNnOo6", *dataptr)) {
00825          *bufptr++ = '6';
00826       } else if (strchr("PpQqRrSs7", *dataptr)) {
00827          *bufptr++ = '7';
00828       } else if (strchr("TtUuVv8", *dataptr)) {
00829          *bufptr++ = '8';
00830       } else if (strchr("WwXxYyZz9", *dataptr)) {
00831          *bufptr++ = '9';
00832       } else if (*dataptr == '0') {
00833          *bufptr++ = '0';
00834       }
00835    }
00836    buf[len - 1] = '\0';
00837 
00838    return 0;
00839 }

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

Definition at line 657 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_digitdetect(), ast_dsp_process(), ast_dsp_silence(), ast_feature_request_and_dial(), 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(), auth_exec(), 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_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(), set(), skinny_ss(), sms_messagetx(), socket_read(), ss_thread(), static_callback(), strndup(), strnlen(), term_filter_escapes(), transfer_exec(), udptl_build_packet(), unistim_sp(), unquote(), vmwi_generate(), and wav_write().

00658 {
00659    int length = 0;
00660 
00661    if (data)
00662       length = strlen(data);
00663 
00664    snprintf(buf, len, "%d", length);
00665 
00666    return 0;
00667 }

static int load_module ( void   )  [static]

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

Definition at line 580 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(), and make_email_file().

00581 {
00582    char *bufptr = buf, *dataptr = data;
00583 
00584    if (len < 3){ /* at least two for quotes and one for binary zero */
00585       ast_log(LOG_ERROR, "Not enough buffer");
00586       return -1;
00587    }
00588 
00589    if (ast_strlen_zero(data)) {
00590       ast_log(LOG_WARNING, "No argument specified!\n");
00591       ast_copy_string(buf, "\"\"", len);
00592       return 0;
00593    }
00594 
00595    *bufptr++ = '"';
00596    for (; bufptr < buf + len - 3; dataptr++) {
00597       if (*dataptr == '\\') {
00598          *bufptr++ = '\\';
00599          *bufptr++ = '\\';
00600       } else if (*dataptr == '"') {
00601          *bufptr++ = '\\';
00602          *bufptr++ = '"';
00603       } else if (*dataptr == '\0') {
00604          break;
00605       } else {
00606          *bufptr++ = *dataptr;
00607       }
00608    }
00609    *bufptr++ = '"';
00610    *bufptr = '\0';
00611    return 0;
00612 }

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

Definition at line 156 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.

00158 {
00159    AST_DECLARE_APP_ARGS(args,
00160               AST_APP_ARG(null);
00161               AST_APP_ARG(reg);
00162               AST_APP_ARG(str);
00163    );
00164    int errcode;
00165    regex_t regexbuf;
00166 
00167    buf[0] = '\0';
00168 
00169    AST_NONSTANDARD_APP_ARGS(args, parse, '"');
00170 
00171    if (args.argc != 3) {
00172       ast_log(LOG_ERROR, "Unexpected arguments: should have been in the form '\"<regex>\" <string>'\n");
00173       return -1;
00174    }
00175    if ((*args.str == ' ') || (*args.str == '\t'))
00176       args.str++;
00177 
00178    ast_debug(1, "FUNCTION REGEX (%s)(%s)\n", args.reg, args.str);
00179 
00180    if ((errcode = regcomp(&regexbuf, args.reg, REG_EXTENDED | REG_NOSUB))) {
00181       regerror(errcode, &regexbuf, buf, len);
00182       ast_log(LOG_WARNING, "Malformed input %s(%s): %s\n", cmd, parse, buf);
00183       return -1;
00184    }
00185    
00186    strcpy(buf, regexec(&regexbuf, args.str, 0, NULL, 0) ? "0" : "1");
00187 
00188    regfree(&regexbuf);
00189 
00190    return 0;
00191 }

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

Definition at line 866 of file func_strings.c.

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

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

Definition at line 849 of file func_strings.c.

00850 {
00851    char *bufptr = buf, *dataptr = data;
00852 
00853    while ((bufptr < buf + len - 1) && (*bufptr++ = toupper(*dataptr++)));
00854 
00855    return 0;
00856 }

static int unload_module ( void   )  [static]


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 = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, } [static]

Definition at line 933 of file func_strings.c.

char* app_clearhash = "ClearHash" [static]

Definition at line 208 of file func_strings.c.

Definition at line 413 of file func_strings.c.

const struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 933 of file func_strings.c.

Initial value:

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

Definition at line 652 of file func_strings.c.

char* desc_clearhash [static]

Initial value:

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

Definition at line 210 of file func_strings.c.

Definition at line 790 of file func_strings.c.

Definition at line 76 of file func_strings.c.

Definition at line 142 of file func_strings.c.

Definition at line 389 of file func_strings.c.

Definition at line 401 of file func_strings.c.

Definition at line 841 of file func_strings.c.

Definition at line 669 of file func_strings.c.

Definition at line 614 of file func_strings.c.

Definition at line 193 of file func_strings.c.

Definition at line 569 of file func_strings.c.

Definition at line 705 of file func_strings.c.

Definition at line 762 of file func_strings.c.

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

Definition at line 209 of file func_strings.c.

Definition at line 875 of file func_strings.c.

Definition at line 858 of file func_strings.c.


Generated on Wed Oct 28 11:46:10 2009 for Asterisk - the Open Source PBX by  doxygen 1.5.6