Asterisk - The Open Source Telephony Project  GIT-master-a24979a
Macros | Functions | Variables
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 "asterisk/test.h"
Include dependency graph for func_strings.c:

Go to the source code of this file.

Macros

#define beginning   (cmd[0] == 'S') /* SHIFT */
 
#define beginning   (cmd[0] == 'U') /* UNSHIFT */
 
#define HASH_FORMAT   HASH_PREFIX "%s~"
 
#define HASH_PREFIX   "~HASH~%s~"
 

Functions

static void __init_result_buf (void)
 
static void __init_tmp_buf (void)
 
static void __reg_module (void)
 
static void __unreg_module (void)
 
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)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
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, const char *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_eval2 (struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t buflen)
 
static int function_fieldnum (struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
 
static int function_fieldnum_helper (struct ast_channel *chan, const char *cmd, char *parse, char *buf, struct ast_str **sbuf, ssize_t len)
 
static int function_fieldnum_str (struct ast_channel *chan, const char *cmd, char *parse, struct ast_str **buf, ssize_t len)
 
static int function_fieldqty (struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
 
static int function_fieldqty_helper (struct ast_channel *chan, const char *cmd, char *parse, char *buf, struct ast_str **sbuf, ssize_t len)
 
static int function_fieldqty_str (struct ast_channel *chan, const char *cmd, char *parse, struct ast_str **buf, ssize_t len)
 
static const char * get_key (const struct ast_str *prefix, const struct ast_var_t *var)
 
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 hashkeys_read2 (struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_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 listfilter (struct ast_channel *chan, const char *cmd, char *parse, char *buf, struct ast_str **bufstr, ssize_t len)
 
static int listfilter_read (struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
 
static int listfilter_read2 (struct ast_channel *chan, const char *cmd, char *parse, struct ast_str **buf, ssize_t len)
 
static int load_module (void)
 
static int passthru (struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)
 
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 replace (struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)
 
static int shift_pop (struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)
 
static int strbetween (struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)
 
static int string_tolower (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
 
static int string_tolower2 (struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t buflen)
 
static int string_toupper (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
 
static int string_toupper2 (struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t buflen)
 
static int strreplace (struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)
 
static int unload_module (void)
 
static int unshift_push (struct ast_channel *chan, const char *cmd, char *data, const char *new_value)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .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, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
 
static char * app_clearhash = "ClearHash"
 
static struct ast_custom_function array_function
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_custom_function csv_quote_function
 
static struct ast_custom_function eval_function
 
static struct ast_custom_function fieldnum_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 listfilter_function
 
static struct ast_custom_function passthru_function
 
static struct ast_custom_function pop_function
 
static struct ast_custom_function push_function
 
static struct ast_custom_function quote_function
 
static struct ast_custom_function regex_function
 
static struct ast_custom_function replace_function
 
static struct ast_threadstorage result_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_result_buf , .custom_init = NULL , }
 
static struct ast_custom_function shift_function
 
static struct ast_custom_function strbetween_function
 
static struct ast_custom_function strftime_function
 
static struct ast_custom_function strptime_function
 
static struct ast_custom_function strreplace_function
 
static struct ast_threadstorage tmp_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_tmp_buf , .custom_init = NULL , }
 
static struct ast_custom_function tolower_function
 
static struct ast_custom_function toupper_function
 
static struct ast_custom_function unshift_function
 

Detailed Description

String manipulation dialplan functions.

Author
Tilghman Lesher
Anthony Minessale II
Naveen Albert

Definition in file func_strings.c.

Macro Definition Documentation

◆ beginning [1/2]

#define beginning   (cmd[0] == 'S') /* SHIFT */

◆ beginning [2/2]

#define beginning   (cmd[0] == 'U') /* UNSHIFT */

◆ HASH_FORMAT

#define HASH_FORMAT   HASH_PREFIX "%s~"

Definition at line 1063 of file func_strings.c.

◆ HASH_PREFIX

#define HASH_PREFIX   "~HASH~%s~"

Definition at line 1062 of file func_strings.c.

Function Documentation

◆ __init_result_buf()

static void __init_result_buf ( void  )
static

Definition at line 47 of file func_strings.c.

467 {

◆ __init_tmp_buf()

static void __init_tmp_buf ( void  )
static

Definition at line 48 of file func_strings.c.

467 {

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 2181 of file func_strings.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 2181 of file func_strings.c.

◆ acf_strftime()

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

Definition at line 1434 of file func_strings.c.

1436 {
1438  AST_APP_ARG(epoch);
1439  AST_APP_ARG(timezone);
1441  );
1442  struct timeval when;
1443  struct ast_tm tm;
1444 
1445  buf[0] = '\0';
1446 
1448 
1449  ast_get_timeval(args.epoch, &when, ast_tvnow(), NULL);
1450  ast_localtime(&when, &tm, args.timezone);
1451 
1452  if (!args.format)
1453  args.format = "%c";
1454 
1455  if (ast_strftime(buf, buflen, args.format, &tm) <= 0)
1456  ast_log(LOG_WARNING, "C function strftime() output nothing?!!\n");
1457 
1458  buf[buflen - 1] = '\0';
1459 
1460  return 0;
1461 }
#define ast_log
Definition: astobj2.c:42
static snd_pcm_format_t format
Definition: chan_alsa.c:106
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1844
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define AST_APP_ARG(name)
Define an application argument.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
#define LOG_WARNING
int ast_strftime(char *buf, size_t len, const char *format, const struct ast_tm *tm)
Special version of strftime(3) that handles fractions of a second. Takes the same arguments as strfti...
Definition: localtime.c:2524
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
#define NULL
Definition: resample.c:96
int ast_get_timeval(const char *src, struct timeval *tv, struct timeval _default, int *consumed)
Parse a time (float) string.
Definition: main/utils.c:2317
const char * args
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:157

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

◆ acf_strptime()

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

Definition at line 1468 of file func_strings.c.

1470 {
1472  AST_APP_ARG(timestring);
1473  AST_APP_ARG(timezone);
1475  );
1476  struct ast_tm tm;
1477 
1478  buf[0] = '\0';
1479 
1480  if (!data) {
1482  "Asterisk function STRPTIME() requires an argument.\n");
1483  return -1;
1484  }
1485 
1486  AST_STANDARD_APP_ARGS(args, data);
1487 
1488  if (ast_strlen_zero(args.format)) {
1490  "No format supplied to STRPTIME(<timestring>,<timezone>,<format>)");
1491  return -1;
1492  }
1493 
1494  if (!ast_strptime(args.timestring, args.format, &tm)) {
1495  ast_log(LOG_WARNING, "STRPTIME() found no time specified within the string\n");
1496  } else {
1497  struct timeval when;
1498  when = ast_mktime(&tm, args.timezone);
1499  snprintf(buf, buflen, "%d", (int) when.tv_sec);
1500  }
1501 
1502  return 0;
1503 }
#define LOG_ERROR
char * ast_strptime(const char *s, const char *format, struct ast_tm *tm)
Special version of strptime(3) which places the answer in the common structure ast_tm....
Definition: localtime.c:2550
struct timeval ast_mktime(struct ast_tm *const tmp, const char *zone)
Timezone-independent version of mktime(3).
Definition: localtime.c:2357
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65

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

◆ array()

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

Definition at line 1089 of file func_strings.c.

1091 {
1092  AST_DECLARE_APP_ARGS(arg1,
1093  AST_APP_ARG(var)[100];
1094  );
1095  AST_DECLARE_APP_ARGS(arg2,
1096  AST_APP_ARG(val)[100];
1097  );
1098  char *origvar = "", *value2, varname[256];
1099  int i, ishash = 0;
1100 
1101  if (!var) {
1102  return -1;
1103  }
1104  value2 = ast_strdupa(value);
1105 
1106  if (!strcmp(cmd, "HASH")) {
1107  const char *var2 = pbx_builtin_getvar_helper(chan, "~ODBCFIELDS~");
1108  origvar = var;
1109  if (var2)
1110  var = ast_strdupa(var2);
1111  else {
1112  if (chan)
1113  ast_autoservice_stop(chan);
1114  return -1;
1115  }
1116  ishash = 1;
1117  }
1118 
1119  /* The functions this will generally be used with are SORT and ODBC_*, which
1120  * both return comma-delimited lists. However, if somebody uses literal lists,
1121  * their commas will be translated to vertical bars by the load, and I don't
1122  * want them to be surprised by the result. Hence, we prefer commas as the
1123  * delimiter, but we'll fall back to vertical bars if commas aren't found.
1124  */
1125  ast_debug(1, "array (%s=%s)\n", var, S_OR(value2, ""));
1126  AST_STANDARD_APP_ARGS(arg1, var);
1127 
1128  AST_STANDARD_APP_ARGS(arg2, value2);
1129 
1130  for (i = 0; i < arg1.argc; i++) {
1131  ast_debug(1, "array set value (%s=%s)\n", arg1.var[i],
1132  S_OR(arg2.val[i], ""));
1133  if (i < arg2.argc) {
1134  if (ishash) {
1135  if (origvar[0] == '_') {
1136  if (origvar[1] == '_') {
1137  snprintf(varname, sizeof(varname), "__" HASH_FORMAT, origvar + 2, arg1.var[i]);
1138  } else {
1139  snprintf(varname, sizeof(varname), "_" HASH_FORMAT, origvar + 1, arg1.var[i]);
1140  }
1141  } else {
1142  snprintf(varname, sizeof(varname), HASH_FORMAT, origvar, arg1.var[i]);
1143  }
1144 
1145  pbx_builtin_setvar_helper(chan, varname, arg2.val[i]);
1146  } else {
1147  pbx_builtin_setvar_helper(chan, arg1.var[i], arg2.val[i]);
1148  }
1149  } else {
1150  /* We could unset the variable, by passing a NULL, but due to
1151  * pushvar semantics, that could create some undesired behavior. */
1152  if (ishash) {
1153  snprintf(varname, sizeof(varname), HASH_FORMAT, origvar, arg1.var[i]);
1154  pbx_builtin_setvar_helper(chan, varname, "");
1155  } else {
1156  pbx_builtin_setvar_helper(chan, arg1.var[i], "");
1157  }
1158  }
1159  }
1160 
1161  return 0;
1162 }
#define var
Definition: ast_expr2f.c:614
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
Definition: autoservice.c:266
#define HASH_FORMAT
#define ast_debug(level,...)
Log a DEBUG message.
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name.
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition: strings.h:80
Definition: ast_expr2.c:325
int value
Definition: syslog.c:37

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(), pbx_builtin_setvar_helper(), S_OR, value, and var.

Referenced by __ast_app_separate_args(), app_event_filter_matched(), app_to_json(), append_json(), ast_app_separate_args(), ast_json_array_append(), ast_json_array_clear(), ast_json_array_extend(), ast_json_array_get(), ast_json_array_insert(), ast_json_array_remove(), ast_json_array_set(), ast_json_array_size(), device_to_json_cb(), hash_write(), json_array_from_list(), NearestNeighbor(), stasis_app_device_states_to_json(), and stasis_app_mailboxes_to_json().

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 2181 of file func_strings.c.

◆ clearvar_prefix()

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

Definition at line 1068 of file func_strings.c.

1069 {
1070  struct ast_var_t *var;
1071  int len = strlen(prefix);
1073  if (strncmp(prefix, ast_var_name(var), len) == 0) {
1075  ast_free(var);
1076  }
1077  }
1079 }
#define ast_free(a)
Definition: astmm.h:180
struct varshead * ast_channel_varshead(struct ast_channel *chan)
const char * ast_var_name(const struct ast_var_t *var)
Definition: chanvars.c:60
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static char prefix[MAX_PREFIX]
Definition: http.c:144
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:615
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:529
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:557
struct ast_var_t::@239 entries

References ast_channel_varshead(), ast_free, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_var_name(), ast_var_t::entries, len(), prefix, and var.

Referenced by exec_clearhash().

◆ csv_quote()

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

Definition at line 1381 of file func_strings.c.

1382 {
1383  char *bufptr = buf, *dataptr = data;
1384 
1385  if (len < 3) { /* at least two for quotes and one for binary zero */
1386  ast_log(LOG_ERROR, "Not enough buffer\n");
1387  return -1;
1388  }
1389 
1390  if (ast_strlen_zero(data)) {
1391  ast_copy_string(buf, "\"\"", len);
1392  return 0;
1393  }
1394 
1395  *bufptr++ = '"';
1396  for (; bufptr < buf + len - 3; dataptr++){
1397  if (*dataptr == '"') {
1398  *bufptr++ = '"';
1399  *bufptr++ = '"';
1400  } else if (*dataptr == '\0') {
1401  break;
1402  } else {
1403  *bufptr++ = *dataptr;
1404  }
1405  }
1406  *bufptr++ = '"';
1407  *bufptr='\0';
1408  return 0;
1409 }
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:406

References ast_copy_string(), ast_log, ast_strlen_zero(), buf, len(), and LOG_ERROR.

◆ exec_clearhash()

static int exec_clearhash ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 1081 of file func_strings.c.

1082 {
1083  char prefix[80];
1084  snprintf(prefix, sizeof(prefix), HASH_PREFIX, data ? (char *)data : "null");
1085  clearvar_prefix(chan, prefix);
1086  return 0;
1087 }
static void clearvar_prefix(struct ast_channel *chan, const char *prefix)
#define HASH_PREFIX

References clearvar_prefix(), HASH_PREFIX, and prefix.

◆ filter()

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 734 of file func_strings.c.

736 {
738  AST_APP_ARG(allowed);
739  AST_APP_ARG(string);
740  );
741  char *outbuf = buf;
742  unsigned char ac;
743  char allowed[256] = "";
744  size_t allowedlen = 0;
745  int32_t bitfield[8] = { 0, }; /* 256 bits */
746 
748 
749  if (!args.string) {
750  ast_log(LOG_ERROR, "Usage: FILTER(<allowed-chars>,<string>)\n");
751  return -1;
752  }
753 
754  if (args.allowed[0] == '"' && !ast_opt_dont_warn) {
755  ast_log(LOG_WARNING, "FILTER allowed characters includes the quote (\") character. This may not be what you want.\n");
756  }
757 
758  /* Expand ranges */
759  for (; *(args.allowed);) {
760  char c1 = 0, c2 = 0;
761  size_t consumed = 0;
762 
763  if (ast_get_encoded_char(args.allowed, &c1, &consumed))
764  return -1;
765  args.allowed += consumed;
766 
767  if (*(args.allowed) == '-') {
768  if (ast_get_encoded_char(args.allowed + 1, &c2, &consumed))
769  c2 = c1;
770  args.allowed += consumed + 1;
771 
772  if ((unsigned char) c2 < (unsigned char) c1 && !ast_opt_dont_warn) {
773  ast_log(LOG_WARNING, "Range wrapping in FILTER(%s,%s). This may not be what you want.\n", parse, args.string);
774  }
775 
776  /*!\note
777  * Looks a little strange, until you realize that we can overflow
778  * the size of a char.
779  */
780  for (ac = (unsigned char) c1; ac != (unsigned char) c2; ac++) {
781  bitfield[ac / 32] |= 1 << (ac % 32);
782  }
783  bitfield[ac / 32] |= 1 << (ac % 32);
784 
785  ast_debug(4, "c1=%d, c2=%d\n", c1, c2);
786  } else {
787  ac = (unsigned char) c1;
788  ast_debug(4, "c1=%d, consumed=%d, args.allowed=%s\n", c1, (int) consumed, args.allowed - consumed);
789  bitfield[ac / 32] |= 1 << (ac % 32);
790  }
791  }
792 
793  for (ac = 1; ac != 0; ac++) {
794  if (bitfield[ac / 32] & (1 << (ac % 32))) {
795  allowed[allowedlen++] = ac;
796  }
797  }
798 
799  ast_debug(1, "Allowed: %s\n", allowed);
800 
801  for (; *(args.string) && (buf + len - 1 > outbuf); (args.string)++) {
802  if (strchr(allowed, *(args.string)))
803  *outbuf++ = *(args.string);
804  }
805  *outbuf = '\0';
806 
807  return 0;
808 }
int int32_t
Definition: db.h:60
int ast_get_encoded_char(const char *stream, char *result, size_t *consumed)
Decode an encoded control or extended ASCII character.
Definition: main/app.c:3147
#define AST_STANDARD_RAW_ARGS(args, parse)
#define ast_opt_dont_warn
Definition: options.h:125

References args, AST_APP_ARG, ast_debug, AST_DECLARE_APP_ARGS, ast_get_encoded_char(), ast_log, ast_opt_dont_warn, AST_STANDARD_RAW_ARGS, buf, len(), LOG_ERROR, LOG_WARNING, and parse().

Referenced by action_filter(), action_getconfig(), action_getconfigjson(), app_event_filter_set(), app_events_allowed_set(), app_events_disallowed_set(), append_var_and_value_to_filter(), ast_category_browse_filtered(), ast_category_exist(), ast_category_get(), ast_variable_retrieve_filtered(), category_get_sep(), create_lookup_filter(), iax_firmware_traverse(), kqueue_timer_ack(), next_available_category(), process_text_line(), realtime_ldap_base_ap(), stasis_app_event_filter_set(), stasis_caching_set_filter(), stasis_cp_single_set_filter(), stasis_subscription_set_filter(), and update2_ldap().

◆ function_eval()

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

Definition at line 1510 of file func_strings.c.

1512 {
1513  if (ast_strlen_zero(data)) {
1514  ast_log(LOG_WARNING, "EVAL requires an argument: EVAL(<string>)\n");
1515  return -1;
1516  }
1517 
1518  pbx_substitute_variables_helper(chan, data, buf, buflen - 1);
1519 
1520  return 0;
1521 }
void pbx_substitute_variables_helper(struct ast_channel *c, const char *cp1, char *cp2, int count)
Definition: ael_main.c:211

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

◆ function_eval2()

static int function_eval2 ( struct ast_channel chan,
const char *  cmd,
char *  data,
struct ast_str **  buf,
ssize_t  buflen 
)
static

Definition at line 1523 of file func_strings.c.

1525 {
1526  if (ast_strlen_zero(data)) {
1527  ast_log(LOG_WARNING, "EVAL requires an argument: EVAL(<string>)\n");
1528  return -1;
1529  }
1530 
1531  ast_str_substitute_variables(buf, buflen, chan, data);
1532 
1533  return 0;
1534 }
void ast_str_substitute_variables(struct ast_str **buf, ssize_t maxlen, struct ast_channel *chan, const char *templ)

◆ function_fieldnum()

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

Definition at line 589 of file func_strings.c.

591 {
592  return function_fieldnum_helper(chan, cmd, parse, buf, NULL, len);
593 }
static int function_fieldnum_helper(struct ast_channel *chan, const char *cmd, char *parse, char *buf, struct ast_str **sbuf, ssize_t len)
Definition: func_strings.c:528

References buf, function_fieldnum_helper(), len(), NULL, and parse().

◆ function_fieldnum_helper()

static int function_fieldnum_helper ( struct ast_channel chan,
const char *  cmd,
char *  parse,
char *  buf,
struct ast_str **  sbuf,
ssize_t  len 
)
static

Definition at line 528 of file func_strings.c.

530 {
531  char *varsubst, *field;
532  struct ast_str *str = ast_str_thread_get(&result_buf, 16);
533  int fieldindex = 0, res = 0;
535  AST_APP_ARG(varname);
536  AST_APP_ARG(delim);
537  AST_APP_ARG(field);
538  );
539  char delim[2] = "";
540  size_t delim_used;
541 
542  if (!str) {
543  return -1;
544  }
545 
547 
548  if (args.argc < 3) {
549  ast_log(LOG_ERROR, "Usage: FIELDNUM(<listname>,<delimiter>,<fieldvalue>)\n");
550  res = -1;
551  } else {
552  varsubst = ast_alloca(strlen(args.varname) + 4);
553  sprintf(varsubst, "${%s}", args.varname);
554 
555  ast_str_substitute_variables(&str, 0, chan, varsubst);
556 
557  if (ast_str_strlen(str) == 0 || ast_strlen_zero(args.delim)) {
558  fieldindex = 0;
559  } else if (ast_get_encoded_char(args.delim, delim, &delim_used) == -1) {
560  res = -1;
561  } else {
562  char *varval = ast_str_buffer(str);
563 
564  while ((field = strsep(&varval, delim)) != NULL) {
565  fieldindex++;
566 
567  if (!strcasecmp(field, args.field)) {
568  break;
569  }
570  }
571 
572  if (!field) {
573  fieldindex = 0;
574  }
575 
576  res = 0;
577  }
578  }
579 
580  if (sbuf) {
581  ast_str_set(sbuf, len, "%d", fieldindex);
582  } else {
583  snprintf(buf, len, "%d", fieldindex);
584  }
585 
586  return res;
587 }
const char * str
Definition: app_jack.c:147
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:288
static struct ast_threadstorage result_buf
Definition: func_strings.c:47
char * strsep(char **str, const char *delims)
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:739
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1091
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:711
struct ast_str * ast_str_thread_get(struct ast_threadstorage *ts, size_t init_len)
Retrieve a thread locally stored dynamic string.
Definition: strings.h:887
Support for dynamic strings.
Definition: strings.h:604

References args, ast_alloca, AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_get_encoded_char(), ast_log, AST_STANDARD_APP_ARGS, ast_str_buffer(), ast_str_set(), ast_str_strlen(), ast_str_substitute_variables(), ast_str_thread_get(), ast_strlen_zero(), buf, len(), LOG_ERROR, NULL, parse(), result_buf, str, and strsep().

Referenced by function_fieldnum().

◆ function_fieldnum_str()

static int function_fieldnum_str ( struct ast_channel chan,
const char *  cmd,
char *  parse,
struct ast_str **  buf,
ssize_t  len 
)
static

Definition at line 595 of file func_strings.c.

597 {
598  return function_fieldnum_helper(chan, cmd, parse, NULL, buf, len);
599 }

◆ function_fieldqty()

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

Definition at line 510 of file func_strings.c.

512 {
513  return function_fieldqty_helper(chan, cmd, parse, buf, NULL, len);
514 }
static int function_fieldqty_helper(struct ast_channel *chan, const char *cmd, char *parse, char *buf, struct ast_str **sbuf, ssize_t len)
Definition: func_strings.c:465

References buf, function_fieldqty_helper(), len(), NULL, and parse().

◆ function_fieldqty_helper()

static int function_fieldqty_helper ( struct ast_channel chan,
const char *  cmd,
char *  parse,
char *  buf,
struct ast_str **  sbuf,
ssize_t  len 
)
static

Definition at line 465 of file func_strings.c.

467 {
468  char *varsubst;
469  struct ast_str *str = ast_str_thread_get(&result_buf, 16);
470  int fieldcount = 0;
472  AST_APP_ARG(varname);
473  AST_APP_ARG(delim);
474  );
475  char delim[2] = "";
476  size_t delim_used;
477 
478  if (!str) {
479  return -1;
480  }
481 
483  if (args.delim) {
484  ast_get_encoded_char(args.delim, delim, &delim_used);
485 
486  varsubst = ast_alloca(strlen(args.varname) + 4);
487 
488  sprintf(varsubst, "${%s}", args.varname);
489  ast_str_substitute_variables(&str, 0, chan, varsubst);
490  if (ast_str_strlen(str) == 0) {
491  fieldcount = 0;
492  } else {
493  char *varval = ast_str_buffer(str);
494  while (strsep(&varval, delim)) {
495  fieldcount++;
496  }
497  }
498  } else {
499  fieldcount = 1;
500  }
501  if (sbuf) {
502  ast_str_set(sbuf, len, "%d", fieldcount);
503  } else {
504  snprintf(buf, len, "%d", fieldcount);
505  }
506 
507  return 0;
508 }

References args, ast_alloca, AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_get_encoded_char(), AST_STANDARD_APP_ARGS, ast_str_buffer(), ast_str_set(), ast_str_strlen(), ast_str_substitute_variables(), ast_str_thread_get(), buf, len(), parse(), result_buf, str, and strsep().

Referenced by function_fieldqty().

◆ function_fieldqty_str()

static int function_fieldqty_str ( struct ast_channel chan,
const char *  cmd,
char *  parse,
struct ast_str **  buf,
ssize_t  len 
)
static

Definition at line 516 of file func_strings.c.

518 {
519  return function_fieldqty_helper(chan, cmd, parse, NULL, buf, len);
520 }

◆ get_key()

static const char* get_key ( const struct ast_str prefix,
const struct ast_var_t var 
)
static

Definition at line 1164 of file func_strings.c.

1165 {
1166  const char *prefix_name = ast_str_buffer(prefix);
1167  const char *var_name = ast_var_name(var);
1168  int prefix_len;
1169  int var_len;
1170 
1171  if (ast_strlen_zero(var_name)) {
1172  return NULL;
1173  }
1174 
1175  prefix_len = ast_str_strlen(prefix);
1176  var_len = strlen(var_name);
1177 
1178  /*
1179  * Make sure we only match on non-empty, hash function created keys. If valid
1180  * then return a pointer to the variable that's just after the prefix.
1181  */
1182  return var_len > (prefix_len + 1) && var_name[var_len - 1] == '~' &&
1183  strncmp(prefix_name, var_name, prefix_len) == 0 ? var_name + prefix_len : NULL;
1184 }

References ast_str_buffer(), ast_str_strlen(), ast_strlen_zero(), ast_var_name(), NULL, prefix, and var.

Referenced by hashkeys_read(), and hashkeys_read2().

◆ hash_read()

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

Definition at line 1274 of file func_strings.c.

1275 {
1276  char varname[256];
1277  const char *varvalue;
1279  AST_APP_ARG(hashname);
1280  AST_APP_ARG(hashkey);
1281  );
1282 
1283  AST_STANDARD_APP_ARGS(arg, data);
1284  if (arg.argc == 2) {
1285  snprintf(varname, sizeof(varname), HASH_FORMAT, arg.hashname, arg.hashkey);
1286  varvalue = pbx_builtin_getvar_helper(chan, varname);
1287  if (varvalue)
1288  ast_copy_string(buf, varvalue, len);
1289  else
1290  *buf = '\0';
1291  } else if (arg.argc == 1) {
1292  char colnames[4096];
1293  int i;
1294  AST_DECLARE_APP_ARGS(arg2,
1295  AST_APP_ARG(col)[100];
1296  );
1297 
1298  if (!chan) {
1299  ast_log(LOG_WARNING, "No channel and only 1 parameter was provided to %s function.\n", cmd);
1300  return -1;
1301  }
1302 
1303  /* Get column names, in no particular order */
1304  hashkeys_read(chan, "HASHKEYS", arg.hashname, colnames, sizeof(colnames));
1305  pbx_builtin_setvar_helper(chan, "~ODBCFIELDS~", colnames);
1306 
1307  AST_STANDARD_APP_ARGS(arg2, colnames);
1308  *buf = '\0';
1309 
1310  /* Now get the corresponding column values, in exactly the same order */
1311  for (i = 0; i < arg2.argc; i++) {
1312  snprintf(varname, sizeof(varname), HASH_FORMAT, arg.hashname, arg2.col[i]);
1313  varvalue = pbx_builtin_getvar_helper(chan, varname);
1314  strncat(buf, varvalue, len - strlen(buf) - 1);
1315  strncat(buf, ",", len - strlen(buf) - 1);
1316  }
1317 
1318  /* Strip trailing comma */
1319  buf[strlen(buf) - 1] = '\0';
1320  }
1321 
1322  return 0;
1323 }
static int hashkeys_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)

◆ hash_write()

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

Definition at line 1246 of file func_strings.c.

1247 {
1248  char varname[256];
1250  AST_APP_ARG(hashname);
1251  AST_APP_ARG(hashkey);
1252  );
1253 
1254  if (!strchr(var, ',')) {
1255  /* Single argument version */
1256  return array(chan, "HASH", var, value);
1257  }
1258 
1259  AST_STANDARD_APP_ARGS(arg, var);
1260  if (arg.hashname[0] == '_') {
1261  if (arg.hashname[1] == '_') {
1262  snprintf(varname, sizeof(varname), "__" HASH_FORMAT, arg.hashname + 2, arg.hashkey);
1263  } else {
1264  snprintf(varname, sizeof(varname), "_" HASH_FORMAT, arg.hashname + 1, arg.hashkey);
1265  }
1266  } else {
1267  snprintf(varname, sizeof(varname), HASH_FORMAT, arg.hashname, arg.hashkey);
1268  }
1269  pbx_builtin_setvar_helper(chan, varname, value);
1270 
1271  return 0;
1272 }
static int array(struct ast_channel *chan, const char *cmd, char *var, const char *value)

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

◆ hashkeys_read()

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

Definition at line 1186 of file func_strings.c.

1187 {
1188  struct ast_var_t *newvar;
1189  struct ast_str *prefix = ast_str_alloca(80);
1190  size_t buf_len;
1191 
1192  if (!chan) {
1193  ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
1194  return -1;
1195  }
1196 
1197  ast_str_set(&prefix, -1, HASH_PREFIX, data);
1198  memset(buf, 0, len);
1199 
1200  AST_LIST_TRAVERSE(ast_channel_varshead(chan), newvar, entries) {
1201  const char *key = get_key(prefix, newvar);
1202 
1203  if (key) {
1204  strncat(buf, key, len - strlen(buf) - 1);
1205  /* Replace the trailing ~ */
1206  buf[strlen(buf) - 1] = ',';
1207  }
1208  }
1209  /* Trim the trailing comma */
1210  buf_len = strlen(buf);
1211  if (buf_len) {
1212  buf[buf_len - 1] = '\0';
1213  }
1214  return 0;
1215 }
static const char * get_key(const struct ast_str *prefix, const struct ast_var_t *var)
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491
#define ast_str_alloca(init_len)
Definition: strings.h:826

References ast_channel_varshead(), AST_LIST_TRAVERSE, ast_log, ast_str_alloca, ast_str_set(), buf, get_key(), HASH_PREFIX, len(), LOG_WARNING, and prefix.

◆ hashkeys_read2()

static int hashkeys_read2 ( struct ast_channel chan,
const char *  cmd,
char *  data,
struct ast_str **  buf,
ssize_t  len 
)
static

Definition at line 1217 of file func_strings.c.

1218 {
1219  struct ast_var_t *newvar;
1220  struct ast_str *prefix = ast_str_alloca(80);
1221 
1222  if (!chan) {
1223  ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
1224  return -1;
1225  }
1226 
1227  ast_str_set(&prefix, -1, HASH_PREFIX, data);
1228 
1229  AST_LIST_TRAVERSE(ast_channel_varshead(chan), newvar, entries) {
1230  const char *key = get_key(prefix, newvar);
1231 
1232  if (key) {
1233  char *tmp;
1234 
1235  ast_str_append(buf, len, "%s", key);
1236  /* Replace the trailing ~ */
1237  tmp = ast_str_buffer(*buf);
1238  tmp[ast_str_strlen(*buf) - 1] = ',';
1239  }
1240  }
1241 
1242  ast_str_truncate(*buf, -1);
1243  return 0;
1244 }
static int tmp()
Definition: bt_open.c:389
char * ast_str_truncate(struct ast_str *buf, ssize_t len)
Truncates the enclosed string to the given length.
Definition: strings.h:764
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1117

References ast_channel_varshead(), AST_LIST_TRAVERSE, ast_log, ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_set(), ast_str_strlen(), ast_str_truncate(), buf, get_key(), HASH_PREFIX, len(), LOG_WARNING, prefix, and tmp().

◆ keypadhash()

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

Definition at line 1542 of file func_strings.c.

1543 {
1544  char *bufptr, *dataptr;
1545 
1546  for (bufptr = buf, dataptr = data; bufptr < buf + buflen - 1; dataptr++) {
1547  if (*dataptr == '\0') {
1548  *bufptr++ = '\0';
1549  break;
1550  } else if (*dataptr == '1') {
1551  *bufptr++ = '1';
1552  } else if (strchr("AaBbCc2", *dataptr)) {
1553  *bufptr++ = '2';
1554  } else if (strchr("DdEeFf3", *dataptr)) {
1555  *bufptr++ = '3';
1556  } else if (strchr("GgHhIi4", *dataptr)) {
1557  *bufptr++ = '4';
1558  } else if (strchr("JjKkLl5", *dataptr)) {
1559  *bufptr++ = '5';
1560  } else if (strchr("MmNnOo6", *dataptr)) {
1561  *bufptr++ = '6';
1562  } else if (strchr("PpQqRrSs7", *dataptr)) {
1563  *bufptr++ = '7';
1564  } else if (strchr("TtUuVv8", *dataptr)) {
1565  *bufptr++ = '8';
1566  } else if (strchr("WwXxYyZz9", *dataptr)) {
1567  *bufptr++ = '9';
1568  } else if (*dataptr == '0') {
1569  *bufptr++ = '0';
1570  }
1571  }
1572  buf[buflen - 1] = '\0';
1573 
1574  return 0;
1575 }

References buf.

◆ len()

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

Definition at line 1416 of file func_strings.c.

1417 {
1418  int length = 0;
1419 
1420  if (data)
1421  length = strlen(data);
1422 
1423  snprintf(buf, buflen, "%d", length);
1424 
1425  return 0;
1426 }

References buf.

Referenced by __analog_ss_thread(), __ast_cli_register(), __ast_cli_register_multiple(), __ast_dsp_call_progress(), __ast_dsp_silence_noise(), __ast_frdup(), __big_return(), __bt_defcmp(), __bt_defpfx(), __call_hash(), OrderedDict::__eq__(), __get_header(), OrderedDict::__init__(), __mgcp_xmit(), __rec_fmap(), __rec_fpipe(), __rec_vpipe(), __rtp_recvfrom(), __rtp_sendto(), MultiOrderedDict::__setitem__(), AbsQuantW(), acf_curl_exec(), acf_curlopt_helper(), acf_curlopt_read(), acf_curlopt_read2(), acf_cut_exec(), acf_escape(), acf_escape_backslashes(), acf_escape_ticks(), acf_faxopt_read(), acf_fetch(), acf_iaxvar_read(), acf_if(), acf_meetme_info(), acf_odbc_read(), acf_sort_exec(), acf_sprintf(), acf_transaction_read(), acf_vm_info(), action_command(), FaxPcap::add(), add_sdp(), adsi_careful_send(), ael_token_subst(), alsa_write(), amdf_pitch(), anaFilter(), analog_ss_thread(), anti_injection(), aoc_parse_ie(), append_attr_address(), append_attr_string(), append_interface(), append_var_and_value_to_filter(), apply_outgoing(), ast_agi_register_multiple(), ast_agi_unregister_multiple(), ast_app_group_set_channel(), ast_app_options2str64(), ast_audiosocket_receive_frame(), ast_beep_start(), ast_bucket_alloc(), ast_bucket_file_alloc(), ast_callerid_vmwi_generate(), ast_carefulwrite(), ast_channel_get_cc_agent_type(), ast_channel_get_device_name(), ast_cli_complete(), ast_cli_unregister_multiple(), ast_dsp_process(), ast_dsp_silence_noise_with_energy(), ast_format_str_reduce(), ast_frame_type2str(), ast_func_read(), ast_gen_cas(), ast_get_builtin_feature(), ast_get_feature(), ast_get_namedgroups(), ast_http_prefix(), ast_http_send(), ast_http_uri_link(), ast_iostream_gets(), ast_iostream_printf(), ast_join_delim(), ast_json_utf8_check_len(), ast_media_cache_retrieve(), ast_media_cache_retrieve_metadata(), ast_mkdir(), ast_msg_data_alloc(), ast_read_image(), ast_readstring(), ast_readstring_full(), ast_recvfrom(), ast_rtcp_generate_report(), ast_rtcp_generate_sdes(), ast_rtcp_interpret(), ast_rtp_interpret(), ast_say_number_full_ka(), ast_sendto(), ast_sip_sanitize_xml(), ast_smoother_read(), ast_sockaddr_copy_sockaddr(), ast_speech_get_setting(), ast_speech_write(), ast_srtp_get_random(), ast_srtp_protect(), ast_srtp_unprotect(), ast_statsd_log_string(), ast_str_buffer(), ast_str_substitute_variables_full(), ast_strftime(), ast_strftime_locale(), ast_stun_handle_packet(), ast_tdd_gen_ecdisa(), AST_TEST_DEFINE(), ast_translate(), ast_udptl_write(), ast_websocket_write_string(), ast_xml_escape(), ast_xmldoc_printable(), auth_exec(), authenticate(), base64_buf_helper(), base64_helper(), blacklist_read(), bridge_p2p_rtp_write(), bucket_copy(), bucket_file_wizard_retrieve(), bucket_wizard_retrieve(), buf_hash(), buf_hash_add(), build_device(), build_ha(), build_rand_pad(), build_regex(), build_route(), builtin_feature_get_exten(), calc_energy(), calendar_join_attendees(), calendar_query_exec(), calendar_query_result_exec(), callerid_feed(), callerid_feed_jp(), callerid_generate(), callerid_read(), careful_write(), category_set_sublevels(), CB_ADD_LEN(), cdata(), cdr_read(), channel_do_masquerade(), chararray_handler_fn(), check_dirpath(), check_sip_domain(), chunked_atoh(), cleaned_basedn(), clearvar_prefix(), cli_complete(), cli_console_sendtext(), sip_to_pjsip::cli_options(), sip_to_pjsql::cli_options(), collect_data(), collect_key(), complete_confno(), complete_dialplan_add_extension(), complete_dialplan_add_ignorepat(), complete_dialplan_add_include(), complete_dialplan_remove_context(), complete_dialplan_remove_extension(), complete_dialplan_remove_ignorepat(), complete_dialplan_remove_include(), complete_meetmecmd_list(), complete_meetmecmd_mute_kick(), complete_peer_helper(), complete_userno(), conf_get_pin(), conf_play(), connectedline_read(), cops_getmsg(), copy(), create_dirpath(), create_video_frame(), crement_function_read(), csv_quote(), custom_devstate_callback(), custom_level_still_exists(), custom_presence_callback(), dahdi_func_read(), dahdi_sendtext(), dahdi_setoption(), dbl_list_expect_reverse(), dbm_open(), dcbias_(), decode_length(), decode_open_type(), decrypt_memcpy(), DEFINE_SQL_STATEMENT(), devstate_read(), devstate_write(), dialgroup_read(), dialgroup_refreshdb(), dictate_exec(), dns_parse_answer(), do_pktccops(), dtmf_store_framehook(), dump_addr(), dump_answer(), dump_byte(), dump_cause(), dump_datetime(), dump_eid(), dump_encrypted(), dump_hint(), dump_ies(), dump_int(), dump_ipaddr(), dump_prefs(), dump_prov(), dump_prov_flags(), dump_prov_ies(), dump_raw(), dump_samprate(), dump_short(), dump_string(), dump_string_hex(), dump_versioned_codec(), dundi_encrypt(), dundi_parse_ies(), dundi_send(), ebl_callback(), encode_length(), encode_open_type(), encrypt_memcpy(), energy_(), enum_callback(), enum_query_read(), env_read(), expand_gosub_args(), expr2_token_subst(), ext_cmp_exten_strlen(), ext_strncpy(), fbuf_append(), feature_read(), featuremap_get(), featuremap_read(), fetch_response_reader(), ffmpeg_decode(), file2display(), file2format(), file_basename(), file_dirname(), file_format(), file_read(), filename_parse(), filter(), frame_set_var(), fsk_serial(), func_channel_read(), func_confbridge_info(), func_get_parkingslot_channel(), func_header_read(), func_mchan_read(), func_read_header(), func_read_headers(), function_amiclient(), function_db_delete(), function_db_read(), function_enum(), function_fieldnum(), function_fieldnum_helper(), function_fieldqty(), function_fieldqty_helper(), function_iaxpeer(), function_ooh323_read(), function_realtime_read(), function_realtime_readdestroy(), function_sippeer(), function_txtcidname(), g722_decode(), g722_encode(), gen_tone(), gen_tones(), general_get(), PathSegment::get_child(), get_csv(), get_date(), get_domain(), get_name_from_resource(), get_sdp(), get_sdp_iterate(), global_read(), group_function_read(), gsm_write(), gsmtolin_framein(), h261_encap(), h263_encap(), h263_read(), h263_write(), h263p_decap(), h263p_encap(), h264_read(), h264_write(), handle_characters(), handle_cli_mobile_search(), handle_cli_moh_unregister_class(), handle_commandmatchesarray(), handle_incoming(), handle_keypad_button_message(), handle_output(), handle_response(), handle_show_sysinfo(), handle_soft_key_event_message(), hangupcause_keys_read(), hangupcause_read(), Model::has_properties(), Model::has_subtypes(), hashfunc(), hashkeys_read(), hashkeys_read2(), header_identify_match_check(), help1(), hepv3_create_capture_info(), hook_read(), hpInput(), hpOutput(), http_request_headers_get(), httpd_process_request(), iax2_getpeername(), iax_frame_subclass2str(), iax_parse_ies(), iax_str2flags(), iftime(), import_helper(), import_read(), init_stmt(), inner_product_single(), internal_feature_read(), internal_featuremap_read(), interpolate_product_single(), ip_identify_apply(), isodate(), ivfilt_(), json_utf8_check_full(), linear_generator(), listener(), listfilter(), listfilter_read(), load_file(), lock_read(), lpc10_decode(), lpc10tolin_framein(), lpfilt_(), lws2sws(), make_ari_stubs::main(), refcounter::main(), main(), spandspflow2pcap::main(), make_dir(), make_file(), make_filename(), manager_login(), math(), MD5Update(), media_offer_read_av(), memcpy_decrypt(), memcpy_encrypt(), message_template_parse_emailbody(), method_match(), mgcp_postrequest(), mgcp_ss(), mgcpsock_read(), milliwatt_generate(), minivm_account_func_read(), minivm_counter_func_read(), moh_generate(), monmp3thread(), mpeg4_decap(), mpeg4_encap(), msg_data_func_read(), msg_func_read(), msg_to_endpoint(), my_dahdi_write(), newpvt(), PathSegment::num_children(), parse_bookmark(), parse_cdata(), parse_ie(), refcounter::parse_line(), get_documentation::parse_manager_event_instance(), parse_naptr(), parse_srv(), partial_match(), passthru(), pbx_substitute_variables_helper_full(), pbx_substitute_variables_helper_full_location(), phoneprov_callback(), pickup_get(), pjsip_acf_channel_read(), pjsip_acf_dial_contacts_read(), pjsip_acf_dtmf_mode_read(), pjsip_acf_media_offer_read(), pjsip_acf_moh_passthrough_read(), playtone(), plc_fillin(), plc_rx(), pp_each_extension_helper(), pp_each_extension_read(), pp_each_user_helper(), pp_each_user_read(), presence_read(), print_body(), process_cn_rfc3389(), process_dtmf_cisco(), process_dtmf_rfc2833(), reflocks::process_file(), refstats::process_file(), process_sdp(), queue_function_exists(), queue_function_mem_read(), queue_function_memberpenalty_read(), queue_function_qac_dep(), queue_function_queuegetchannel(), queue_function_queuememberlist(), queue_function_queuewaitingcount(), queue_function_var(), quote(), read_credentials(), read_header(), read_headers(), realtimefield_read(), receive_message(), red_t140_to_red(), redirecting_read(), refer_blind_callback(), regex(), remove_header(), replace(), reschedule_precache(), resource_name_baselen(), rtp_instance_parse_extmap_extensions(), save_history(), sayfile_exec(), scan_thread(), schedule_delivery(), sco_accept(), sco_write(), send_string(), set(), set2(), set_bridge_peer_vars_multiparty(), sha1(), shared_read(), sip_addheader(), sip_route_add(), sip_route_process_header(), sip_show_channel(), sip_show_history(), sip_tcptls_write(), skip_name(), smdi_msg_retrieve_read(), sms_generate(), sms_messagetx(), socket_process_meta(), speech_aeap_engine_get_setting(), speech_aeap_engine_write(), speech_grammar(), speech_score(), speech_text(), speex_get_wb_sz_at(), speex_samples(), sprint_list_entry(), srv_callback(), start_automixmonitor(), start_automonitor(), stat_read(), StateConstructW(), StateSearchW(), static_callback(), strbetween(), strreplace(), syntFilter(), t38_tx_packet_handler(), tdd_feed(), term_filter_escapes(), timeout_read(), transfer_exec(), transmit_response_bysession(), try_firmware(), trylock_read(), txt_callback(), udptl_build_packet(), udptl_rx_packet(), unistim_sp(), unlock_read(), unquote(), OrderedDict::update(), uri_parse_and_default(), uridecode(), uriencode(), vm_check_password_shell(), wav_write(), ws_safe_read(), ws_send_msg(), xfer_get(), xmldoc_get_syntax_fun(), xmldoc_reverse_helper(), xmldoc_setpostbr(), xmpp_client_authenticate_sasl(), xmpp_client_receive(), xmpp_client_send_raw_message(), and xmpp_io_recv().

◆ listfilter()

static int listfilter ( struct ast_channel chan,
const char *  cmd,
char *  parse,
char *  buf,
struct ast_str **  bufstr,
ssize_t  len 
)
static

Definition at line 607 of file func_strings.c.

608 {
610  AST_APP_ARG(listname);
611  AST_APP_ARG(delimiter);
612  AST_APP_ARG(fieldvalue);
613  );
614  struct ast_str *orig_list = ast_str_thread_get(&tmp_buf, 16);
615  const char *begin, *cur, *next;
616  int dlen, flen, first = 1;
617  struct ast_str *result, **result_ptr = &result;
618  char *delim, *varsubst;
619 
621 
622  if (buf) {
623  if (!(result = ast_str_thread_get(&result_buf, 16))) {
624  return -1;
625  }
626  } else {
627  /* Place the result directly into the output buffer */
628  result_ptr = bufstr;
629  }
630 
631  if (args.argc < 3) {
632  ast_log(LOG_ERROR, "Usage: LISTFILTER(<listname>,<delimiter>,<fieldvalue>)\n");
633  return -1;
634  }
635 
636  varsubst = ast_alloca(strlen(args.listname) + 4);
637  sprintf(varsubst, "${%s}", args.listname);
638 
639  /* If we don't lock the channel, the variable could disappear out from underneath us. */
640  if (chan) {
641  ast_channel_lock(chan);
642  }
643  ast_str_substitute_variables(&orig_list, 0, chan, varsubst);
644  if (!ast_str_strlen(orig_list)) {
645  if (chan) {
646  ast_channel_unlock(chan);
647  }
648  return -1;
649  }
650 
651  /* If the string isn't there, just copy out the string and be done with it. */
652  if (!strstr(ast_str_buffer(orig_list), args.fieldvalue)) {
653  if (buf) {
654  ast_copy_string(buf, ast_str_buffer(orig_list), len);
655  } else {
656  ast_str_set(result_ptr, len, "%s", ast_str_buffer(orig_list));
657  }
658  if (chan) {
659  ast_channel_unlock(chan);
660  }
661  return 0;
662  }
663 
664  dlen = strlen(args.delimiter);
665  delim = ast_alloca(dlen + 1);
666  ast_get_encoded_str(args.delimiter, delim, dlen + 1);
667 
668  if ((dlen = strlen(delim)) == 0) {
669  delim = ",";
670  dlen = 1;
671  }
672 
673  flen = strlen(args.fieldvalue);
674 
675  ast_str_reset(*result_ptr);
676  /* Enough space for any result */
677  if (len > -1) {
678  ast_str_make_space(result_ptr, len ? len : ast_str_strlen(orig_list) + 1);
679  }
680 
681  begin = ast_str_buffer(orig_list);
682  next = strstr(begin, delim);
683 
684  do {
685  /* Find next boundary */
686  if (next) {
687  cur = next;
688  next = strstr(cur + dlen, delim);
689  } else {
690  cur = strchr(begin + dlen, '\0');
691  }
692 
693  if (flen == cur - begin && !strncmp(begin, args.fieldvalue, flen)) {
694  /* Skip field */
695  begin += flen + dlen;
696  } else {
697  /* Copy field to output */
698  if (!first) {
699  ast_str_append(result_ptr, len, "%s", delim);
700  }
701 
702  ast_str_append_substr(result_ptr, len, begin, cur - begin);
703  first = 0;
704  begin = cur + dlen;
705  }
706  } while (*cur != '\0');
707  if (chan) {
708  ast_channel_unlock(chan);
709  }
710 
711  if (buf) {
713  }
714 
715  return 0;
716 }
struct sla_ringing_trunk * first
Definition: app_meetme.c:1094
static PGresult * result
Definition: cel_pgsql.c:84
#define ast_channel_lock(chan)
Definition: channel.h:2922
#define ast_channel_unlock(chan)
Definition: channel.h:2923
static struct ast_threadstorage tmp_buf
Definition: func_strings.c:48
char * ast_get_encoded_str(const char *stream, char *result, size_t result_len)
Decode a stream of encoded control or extended ASCII characters.
Definition: main/app.c:3222
char * ast_str_append_substr(struct ast_str **buf, ssize_t maxlen, const char *src, size_t maxsrc)
Append a non-NULL terminated substring to the end of a dynamic string.
Definition: strings.h:1040
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition: strings.h:674
#define ast_str_make_space(buf, new_len)
Definition: strings.h:806

References args, ast_alloca, AST_APP_ARG, ast_channel_lock, ast_channel_unlock, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_get_encoded_str(), ast_log, AST_STANDARD_APP_ARGS, ast_str_append(), ast_str_append_substr(), ast_str_buffer(), ast_str_make_space, ast_str_reset(), ast_str_set(), ast_str_strlen(), ast_str_substitute_variables(), ast_str_thread_get(), buf, first, len(), LOG_ERROR, parse(), result, result_buf, and tmp_buf.

Referenced by listfilter_read().

◆ listfilter_read()

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

Definition at line 718 of file func_strings.c.

719 {
720  return listfilter(chan, cmd, parse, buf, NULL, len);
721 }
static int listfilter(struct ast_channel *chan, const char *cmd, char *parse, char *buf, struct ast_str **bufstr, ssize_t len)
Definition: func_strings.c:607

References buf, len(), listfilter(), NULL, and parse().

◆ listfilter_read2()

static int listfilter_read2 ( struct ast_channel chan,
const char *  cmd,
char *  parse,
struct ast_str **  buf,
ssize_t  len 
)
static

Definition at line 723 of file func_strings.c.

724 {
725  return listfilter(chan, cmd, parse, NULL, buf, len);
726 }

◆ load_module()

static int load_module ( void  )
static

Definition at line 2142 of file func_strings.c.

2143 {
2144  int res = 0;
2145 
2146  AST_TEST_REGISTER(test_FIELDNUM);
2147  AST_TEST_REGISTER(test_REPLACE);
2148  AST_TEST_REGISTER(test_FILTER);
2149  AST_TEST_REGISTER(test_STRREPLACE);
2150  AST_TEST_REGISTER(test_STRBETWEEN);
2177 
2178  return res;
2179 }
static struct ast_custom_function fieldqty_function
Definition: func_strings.c:522
static struct ast_custom_function eval_function
static struct ast_custom_function shift_function
static struct ast_custom_function hashkeys_function
static struct ast_custom_function fieldnum_function
Definition: func_strings.c:601
static struct ast_custom_function filter_function
Definition: func_strings.c:810
static struct ast_custom_function hash_function
static struct ast_custom_function strptime_function
static struct ast_custom_function strbetween_function
static struct ast_custom_function regex_function
static struct ast_custom_function replace_function
Definition: func_strings.c:879
static char * app_clearhash
static struct ast_custom_function strreplace_function
Definition: func_strings.c:968
static struct ast_custom_function passthru_function
static struct ast_custom_function listfilter_function
Definition: func_strings.c:728
static struct ast_custom_function pop_function
static struct ast_custom_function unshift_function
static struct ast_custom_function keypadhash_function
static struct ast_custom_function strftime_function
static struct ast_custom_function toupper_function
static struct ast_custom_function quote_function
static struct ast_custom_function csv_quote_function
static struct ast_custom_function tolower_function
static struct ast_custom_function array_function
static struct ast_custom_function push_function
static int exec_clearhash(struct ast_channel *chan, const char *data)
static struct ast_custom_function len_function
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:626
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1543
#define AST_TEST_REGISTER(cb)
Definition: test.h:127

◆ passthru()

static int passthru ( struct ast_channel chan,
const char *  cmd,
char *  data,
struct ast_str **  buf,
ssize_t  len 
)
static

Definition at line 1764 of file func_strings.c.

1765 {
1766  ast_str_set(buf, len, "%s", data);
1767  return 0;
1768 }

References ast_str_set(), buf, and len().

◆ quote()

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

Definition at line 1342 of file func_strings.c.

1343 {
1344  char *bufptr = buf, *dataptr = data;
1345 
1346  if (len < 3){ /* at least two for quotes and one for binary zero */
1347  ast_log(LOG_ERROR, "Not enough buffer\n");
1348  return -1;
1349  }
1350 
1351  if (ast_strlen_zero(data)) {
1352  ast_log(LOG_WARNING, "No argument specified!\n");
1353  ast_copy_string(buf, "\"\"", len);
1354  return 0;
1355  }
1356 
1357  *bufptr++ = '"';
1358  for (; bufptr < buf + len - 3; dataptr++) {
1359  if (*dataptr == '\\') {
1360  *bufptr++ = '\\';
1361  *bufptr++ = '\\';
1362  } else if (*dataptr == '"') {
1363  *bufptr++ = '\\';
1364  *bufptr++ = '"';
1365  } else if (*dataptr == '\0') {
1366  break;
1367  } else {
1368  *bufptr++ = *dataptr;
1369  }
1370  }
1371  *bufptr++ = '"';
1372  *bufptr = '\0';
1373  return 0;
1374 }

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

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

◆ regex()

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

Definition at line 1020 of file func_strings.c.

1022 {
1024  AST_APP_ARG(null);
1025  AST_APP_ARG(reg);
1026  AST_APP_ARG(str);
1027  );
1028  int errcode;
1029  regex_t regexbuf;
1030 
1031  buf[0] = '\0';
1032 
1034 
1035  if (args.argc != 3) {
1036  ast_log(LOG_ERROR, "Unexpected arguments: should have been in the form '\"<regex>\" <string>'\n");
1037  return -1;
1038  }
1039  if ((*args.str == ' ') || (*args.str == '\t'))
1040  args.str++;
1041 
1042  ast_debug(1, "FUNCTION REGEX (%s)(%s)\n", args.reg, args.str);
1043 
1044  if ((errcode = regcomp(&regexbuf, args.reg, REG_EXTENDED | REG_NOSUB))) {
1045  regerror(errcode, &regexbuf, buf, len);
1046  ast_log(LOG_WARNING, "Malformed input %s(%s): %s\n", cmd, parse, buf);
1047  return -1;
1048  }
1049 
1050  strcpy(buf, regexec(&regexbuf, args.str, 0, NULL, 0) ? "0" : "1");
1051 
1052  regfree(&regexbuf);
1053 
1054  return 0;
1055 }
#define AST_NONSTANDARD_APP_ARGS(args, parse, sep)
Performs the 'nonstandard' argument separation process for an application.

References args, AST_APP_ARG, ast_debug, AST_DECLARE_APP_ARGS, ast_log, AST_NONSTANDARD_APP_ARGS, buf, len(), LOG_ERROR, LOG_WARNING, NULL, parse(), and str.

Referenced by ast_mwi_mailbox_delete_by_regex(), ast_mwi_mailbox_get_by_regex(), ast_sip_cli_traverse_objects(), ast_sorcery_object_fields_register(), ast_sorcery_retrieve_by_regex(), ast_strings_match(), build_regex(), cli_aor_get_container(), cli_channel_get_container(), cli_channelstats_get_container(), cli_contact_get_container(), cli_endpoint_get_container(), cli_get_container(), cli_show_subscriptions_inout(), get_container(), make_astdb_prefix_pattern(), sorcery_astdb_retrieve_regex(), sorcery_config_retrieve_regex(), sorcery_memory_cache_retrieve_regex(), sorcery_memory_retrieve_regex(), sorcery_realtime_retrieve_regex(), xmldoc_get_syntax_config_option(), and xmldoc_update_config_option().

◆ replace()

static int replace ( struct ast_channel chan,
const char *  cmd,
char *  data,
struct ast_str **  buf,
ssize_t  len 
)
static

Definition at line 815 of file func_strings.c.

816 {
818  AST_APP_ARG(varname);
819  AST_APP_ARG(find);
821  );
822  char *strptr, *varsubst;
823  RAII_VAR(struct ast_str *, str, ast_str_create(16), ast_free);
824  char find[256]; /* Only 256 characters possible */
825  char replace[2] = "";
826  size_t unused;
827 
829 
830  if (!str) {
831  return -1;
832  }
833 
834  if (args.argc < 2) {
835  ast_log(LOG_ERROR, "Usage: %s(<varname>,<search-chars>[,<replace-char>])\n", cmd);
836  return -1;
837  }
838 
839  /* Decode escapes */
840  ast_get_encoded_str(args.find, find, sizeof(find));
841  ast_get_encoded_char(args.replace, replace, &unused);
842 
843  if (ast_strlen_zero(find) || ast_strlen_zero(args.varname)) {
844  ast_log(LOG_ERROR, "The characters to search for and the variable name must not be empty.\n");
845  return -1;
846  }
847 
848  varsubst = ast_alloca(strlen(args.varname) + 4);
849  sprintf(varsubst, "${%s}", args.varname);
850  ast_str_substitute_variables(&str, 0, chan, varsubst);
851 
852  if (!ast_str_strlen(str)) {
853  /* Blank, nothing to replace */
854  return -1;
855  }
856 
857  ast_debug(3, "String to search: (%s)\n", ast_str_buffer(str));
858  ast_debug(3, "Characters to find: (%s)\n", find);
859  ast_debug(3, "Character to replace with: (%s)\n", replace);
860 
861  for (strptr = ast_str_buffer(str); *strptr; strptr++) {
862  /* buf is already a mutable buffer, so we construct the result
863  * directly there */
864  if (strchr(find, *strptr)) {
865  if (ast_strlen_zero(replace)) {
866  memmove(strptr, strptr + 1, strlen(strptr + 1) + 1);
867  strptr--;
868  } else {
869  /* Replace character */
870  *strptr = *replace;
871  }
872  }
873  }
874 
876  return 0;
877 }
static int replace(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)
Definition: func_strings.c:815
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:640
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:936

References args, ast_alloca, AST_APP_ARG, ast_debug, AST_DECLARE_APP_ARGS, ast_free, ast_get_encoded_char(), ast_get_encoded_str(), ast_log, AST_STANDARD_APP_ARGS, ast_str_buffer(), ast_str_create, ast_str_set(), ast_str_strlen(), ast_str_substitute_variables(), ast_strlen_zero(), buf, len(), LOG_ERROR, RAII_VAR, and str.

Referenced by FaxPcap::add(), add_header(), add_pri(), app_get_replace_channel_app(), app_set_replace_channel_app(), app_set_replace_channel_snapshot(), ast_add_extension2(), ast_sip_add_global_request_header(), ast_sip_add_global_response_header(), bridge_features_ds_set_full(), channel_feature_hooks_set_full(), get_replace_channel_snapshot(), ResourceApi::load(), ApiDeclaration::load_file(), localized_add_extension2(), manager_dialplan_extension_add(), spandspflow2pcap::n2b(), parking_add_extension(), get_documentation::parse_manager_event_instance(), process_text_line(), replace_channel_destroy(), and astconfigparser::try_section().

◆ shift_pop()

static int shift_pop ( struct ast_channel chan,
const char *  cmd,
char *  data,
struct ast_str **  buf,
ssize_t  len 
)
static

Definition at line 1640 of file func_strings.c.

1641 {
1642 #define beginning (cmd[0] == 'S') /* SHIFT */
1643  char *after, delimiter[2] = ",", *varsubst;
1644  size_t unused;
1645  struct ast_str *before = ast_str_thread_get(&result_buf, 16);
1646  char *(*search_func)(const char *s, int c) = (beginning ? strchr : strrchr);
1648  AST_APP_ARG(var);
1649  AST_APP_ARG(delimiter);
1650  );
1651 
1652  if (!before) {
1653  return -1;
1654  }
1655 
1656  AST_STANDARD_APP_ARGS(args, data);
1657 
1658  if (ast_strlen_zero(args.var)) {
1659  ast_log(LOG_WARNING, "%s requires a variable name\n", cmd);
1660  return -1;
1661  }
1662 
1663  varsubst = ast_alloca(strlen(args.var) + 4);
1664  sprintf(varsubst, "${%s}", args.var);
1665  ast_str_substitute_variables(&before, 0, chan, varsubst);
1666 
1667  if (args.argc > 1 && !ast_strlen_zero(args.delimiter)) {
1668  ast_get_encoded_char(args.delimiter, delimiter, &unused);
1669  }
1670 
1671  if (!ast_str_strlen(before)) {
1672  /* Nothing to pop */
1673  return -1;
1674  }
1675 
1676  if (!(after = search_func(ast_str_buffer(before), delimiter[0]))) {
1677  /* Only one entry in array */
1678  ast_str_set(buf, len, "%s", ast_str_buffer(before));
1679  pbx_builtin_setvar_helper(chan, args.var, "");
1680  } else {
1681  *after++ = '\0';
1682  ast_str_set(buf, len, "%s", beginning ? ast_str_buffer(before) : after);
1683  pbx_builtin_setvar_helper(chan, args.var, beginning ? after : ast_str_buffer(before));
1684  }
1685 
1686  return 0;
1687 #undef beginning
1688 }
#define beginning
static struct test_val c

◆ strbetween()

static int strbetween ( struct ast_channel chan,
const char *  cmd,
char *  data,
struct ast_str **  buf,
ssize_t  len 
)
static

Definition at line 973 of file func_strings.c.

974 {
975  int c, origsize;
976  char *varsubstr, *origstr;
977  struct ast_str *str = ast_str_thread_get(&result_buf, 16); /* Holds the data obtained from varname */
978 
980  AST_APP_ARG(varname);
981  AST_APP_ARG(insert_string);
982  AST_APP_ARG(other); /* Any remining unused arguments */
983  );
984 
985  ast_str_reset(*buf);
986 
987  if (!str) {
988  ast_log(LOG_ERROR, "Couldn't obtain string\n");
989  return -1;
990  }
991 
993 
994  if (args.argc != 2 || ast_strlen_zero(args.varname)) {
995  ast_log(LOG_ERROR, "Usage: %s(<varname>,<insert-string>)\n", cmd);
996  return -1;
997  }
998 
999  varsubstr = ast_alloca(strlen(args.varname) + 4);
1000  sprintf(varsubstr, "${%s}", args.varname);
1001  ast_str_substitute_variables(&str, 0, chan, varsubstr);
1002  origstr = ast_str_buffer(str);
1003  origsize = strlen(origstr);
1004  for (c = 0; c < origsize; c++) {
1005  ast_str_append(buf, len, "%c", origstr[c]);
1006  /* no insert after the last character */
1007  if (c < (origsize - 1)) {
1008  ast_str_append(buf, len, "%s", args.insert_string);
1009  }
1010  }
1011 
1012  return 0;
1013 }

References args, ast_alloca, AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log, AST_STANDARD_APP_ARGS, ast_str_append(), ast_str_buffer(), ast_str_reset(), ast_str_substitute_variables(), ast_str_thread_get(), ast_strlen_zero(), buf, c, len(), LOG_ERROR, result_buf, and str.

◆ string_tolower()

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

Definition at line 1611 of file func_strings.c.

1612 {
1613  char *bufptr = buf, *dataptr = data;
1614 
1615  while ((bufptr < buf + buflen - 1) && (*bufptr++ = tolower(*dataptr++)));
1616 
1617  return 0;
1618 }

References buf.

◆ string_tolower2()

static int string_tolower2 ( struct ast_channel chan,
const char *  cmd,
char *  data,
struct ast_str **  buf,
ssize_t  buflen 
)
static

Definition at line 1620 of file func_strings.c.

1621 {
1622  char *bufptr, *dataptr = data;
1623 
1624  if (buflen > -1) {
1625  ast_str_make_space(buf, buflen > 0 ? buflen : strlen(data) + 1);
1626  }
1627  bufptr = ast_str_buffer(*buf);
1628  while ((bufptr < ast_str_buffer(*buf) + ast_str_size(*buf) - 1) && (*bufptr++ = tolower(*dataptr++)));
1629  ast_str_update(*buf);
1630 
1631  return 0;
1632 }
void ast_str_update(struct ast_str *buf)
Update the length of the buffer, after using ast_str merely as a buffer.
Definition: strings.h:684
size_t ast_str_size(const struct ast_str *buf)
Returns the current maximum length (without reallocation) of the current buffer.
Definition: strings.h:723

References ast_str_buffer(), ast_str_make_space, ast_str_size(), ast_str_update(), and buf.

◆ string_toupper()

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

Definition at line 1582 of file func_strings.c.

1583 {
1584  char *bufptr = buf, *dataptr = data;
1585 
1586  while ((bufptr < buf + buflen - 1) && (*bufptr++ = toupper(*dataptr++)));
1587 
1588  return 0;
1589 }

References buf.

◆ string_toupper2()

static int string_toupper2 ( struct ast_channel chan,
const char *  cmd,
char *  data,
struct ast_str **  buf,
ssize_t  buflen 
)
static

Definition at line 1591 of file func_strings.c.

1592 {
1593  char *bufptr, *dataptr = data;
1594 
1595  if (buflen > -1) {
1596  ast_str_make_space(buf, buflen > 0 ? buflen : strlen(data) + 1);
1597  }
1598  bufptr = ast_str_buffer(*buf);
1599  while ((bufptr < ast_str_buffer(*buf) + ast_str_size(*buf) - 1) && (*bufptr++ = toupper(*dataptr++)));
1600  ast_str_update(*buf);
1601 
1602  return 0;
1603 }

References ast_str_buffer(), ast_str_make_space, ast_str_size(), ast_str_update(), and buf.

◆ strreplace()

static int strreplace ( struct ast_channel chan,
const char *  cmd,
char *  data,
struct ast_str **  buf,
ssize_t  len 
)
static

Definition at line 884 of file func_strings.c.

885 {
886  char *varsubstr; /* substring for input var */
887  char *start; /* Starting pos of substring search. */
888  char *end; /* Ending pos of substring search. */
889  int find_size; /* length of given find-string */
890  unsigned max_matches; /* number of matches we find before terminating search */
891  unsigned count; /* loop counter */
892  struct ast_str *str = ast_str_thread_get(&result_buf, 16); /* Holds the data obtained from varname */
893 
895  AST_APP_ARG(varname);
896  AST_APP_ARG(find_string);
897  AST_APP_ARG(replace_string);
898  AST_APP_ARG(max_replacements);
899  AST_APP_ARG(other); /* Any remining unused arguments */
900  );
901 
902  /* Guarantee output string is empty to start with. */
903  ast_str_reset(*buf);
904 
905  if (!str) {
906  /* We failed to allocate str, forget it. We failed. */
907  return -1;
908  }
909 
910  /* Parse the arguments. */
912 
913  if (args.argc < 2) {
914  /* Didn't receive enough arguments to do anything */
916  "Usage: %s(<varname>,<find-string>[,<replace-string>,[<max-replacements>]])\n",
917  cmd);
918  return -1;
919  }
920 
921  /* No var name specified. Return failure, string is already empty. */
922  if (ast_strlen_zero(args.varname)) {
923  return -1;
924  }
925 
926  /* Zero length find strings are a no-no. Kill the function if we run into one. */
927  if (ast_strlen_zero(args.find_string)) {
928  ast_log(LOG_ERROR, "No <find-string> specified\n");
929  return -1;
930  }
931  find_size = strlen(args.find_string);
932 
933  /* set varsubstr to the matching variable */
934  varsubstr = ast_alloca(strlen(args.varname) + 4);
935  sprintf(varsubstr, "${%s}", args.varname);
936  ast_str_substitute_variables(&str, 0, chan, varsubstr);
937 
938  /* Determine how many replacements are allowed. */
939  if (!args.max_replacements
940  || (max_matches = atoi(args.max_replacements)) <= 0) {
941  /* Unlimited replacements are allowed. */
942  max_matches = -1;
943  }
944 
945  /* Generate the search and replaced string. */
946  start = ast_str_buffer(str);
947  for (count = 0; count < max_matches; ++count) {
948  end = strstr(start, args.find_string);
949  if (!end) {
950  /* Did not find a matching substring in the remainder. */
951  break;
952  }
953 
954  /* Replace the found substring. */
955  *end = '\0';
956  ast_str_append(buf, len, "%s", start);
957  if (args.replace_string) {
958  /* Append the replacement string */
959  ast_str_append(buf, len, "%s", args.replace_string);
960  }
961  start = end + find_size;
962  }
963  ast_str_append(buf, len, "%s", start);
964 
965  return 0;
966 }
char * end
Definition: eagi_proxy.c:73

References args, ast_alloca, AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log, AST_STANDARD_APP_ARGS, ast_str_append(), ast_str_buffer(), ast_str_reset(), ast_str_substitute_variables(), ast_str_thread_get(), ast_strlen_zero(), buf, end, len(), LOG_ERROR, result_buf, and str.

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 2103 of file func_strings.c.

2104 {
2105  int res = 0;
2106 
2107  AST_TEST_UNREGISTER(test_FIELDNUM);
2108  AST_TEST_UNREGISTER(test_REPLACE);
2109  AST_TEST_UNREGISTER(test_FILTER);
2110  AST_TEST_UNREGISTER(test_STRREPLACE);
2111  AST_TEST_UNREGISTER(test_STRBETWEEN);
2138 
2139  return res;
2140 }
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
#define AST_TEST_UNREGISTER(cb)
Definition: test.h:128

References app_clearhash, array_function, ast_custom_function_unregister(), AST_TEST_UNREGISTER, ast_unregister_application(), csv_quote_function, eval_function, fieldnum_function, fieldqty_function, filter_function, hash_function, hashkeys_function, keypadhash_function, len_function, listfilter_function, passthru_function, pop_function, push_function, quote_function, regex_function, replace_function, shift_function, strbetween_function, strftime_function, strptime_function, strreplace_function, tolower_function, toupper_function, and unshift_function.

◆ unshift_push()

static int unshift_push ( struct ast_channel chan,
const char *  cmd,
char *  data,
const char *  new_value 
)
static

Definition at line 1700 of file func_strings.c.

1701 {
1702 #define beginning (cmd[0] == 'U') /* UNSHIFT */
1703  char delimiter[2] = ",", *varsubst;
1704  size_t unused;
1705  struct ast_str *buf, *previous_value;
1707  AST_APP_ARG(var);
1708  AST_APP_ARG(delimiter);
1709  );
1710  const char *stripped_var;
1711 
1712  if (!(buf = ast_str_thread_get(&result_buf, 16)) ||
1713  !(previous_value = ast_str_thread_get(&tmp_buf, 16))) {
1714  return -1;
1715  }
1716 
1717  AST_STANDARD_APP_ARGS(args, data);
1718 
1719  if (ast_strlen_zero(args.var)) {
1720  ast_log(LOG_WARNING, "%s requires a variable name\n", cmd);
1721  return -1;
1722  }
1723 
1724  if (args.argc > 1 && !ast_strlen_zero(args.delimiter)) {
1725  ast_get_encoded_char(args.delimiter, delimiter, &unused);
1726  }
1727 
1728  /* UNSHIFT and PUSH act as ways of setting a variable, so we need to be
1729  * sure to skip leading underscores if they appear. However, we only want
1730  * to skip up to two since that is the maximum number that can be used to
1731  * indicate variable inheritance. Any further underscores are part of the
1732  * variable name.
1733  */
1734  stripped_var = args.var + MIN(strspn(args.var, "_"), 2);
1735  varsubst = ast_alloca(strlen(stripped_var) + 4);
1736  sprintf(varsubst, "${%s}", stripped_var);
1737  ast_str_substitute_variables(&previous_value, 0, chan, varsubst);
1738 
1739  if (!ast_str_strlen(previous_value)) {
1740  ast_str_set(&buf, 0, "%s", new_value);
1741  } else {
1742  ast_str_set(&buf, 0, "%s%c%s",
1743  beginning ? new_value : ast_str_buffer(previous_value),
1744  delimiter[0],
1745  beginning ? ast_str_buffer(previous_value) : new_value);
1746  }
1747 
1749 
1750  return 0;
1751 #undef beginning
1752 }
#define MIN(a, b)
Definition: utils.h:226

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .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, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
static

Definition at line 2142 of file func_strings.c.

◆ app_clearhash

char* app_clearhash = "ClearHash"
static

Definition at line 1065 of file func_strings.c.

Referenced by unload_module().

◆ array_function

struct ast_custom_function array_function
static
Initial value:
= {
.name = "ARRAY",
.write = array,
}

Definition at line 1274 of file func_strings.c.

Referenced by unload_module().

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 2181 of file func_strings.c.

◆ csv_quote_function

struct ast_custom_function csv_quote_function
static
Initial value:
= {
.name = "CSV_QUOTE",
.read = csv_quote,
}
static int csv_quote(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)

Definition at line 1381 of file func_strings.c.

Referenced by unload_module().

◆ eval_function

struct ast_custom_function eval_function
static
Initial value:
= {
.name = "EVAL",
.read = function_eval,
.read2 = function_eval2,
}
static int function_eval2(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t buflen)
static int function_eval(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)

Definition at line 1523 of file func_strings.c.

Referenced by unload_module().

◆ fieldnum_function

struct ast_custom_function fieldnum_function
static
Initial value:
= {
.name = "FIELDNUM",
}
static int function_fieldnum_str(struct ast_channel *chan, const char *cmd, char *parse, struct ast_str **buf, ssize_t len)
Definition: func_strings.c:595
static int function_fieldnum(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
Definition: func_strings.c:589

Definition at line 595 of file func_strings.c.

Referenced by unload_module().

◆ fieldqty_function

struct ast_custom_function fieldqty_function
static
Initial value:
= {
.name = "FIELDQTY",
}
static int function_fieldqty_str(struct ast_channel *chan, const char *cmd, char *parse, struct ast_str **buf, ssize_t len)
Definition: func_strings.c:516
static int function_fieldqty(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
Definition: func_strings.c:510

Definition at line 516 of file func_strings.c.

Referenced by unload_module().

◆ filter_function

struct ast_custom_function filter_function
static
Initial value:
= {
.name = "FILTER",
.read = filter,
}
static int filter(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
Definition: func_strings.c:734

Definition at line 734 of file func_strings.c.

Referenced by unload_module().

◆ hash_function

struct ast_custom_function hash_function
static
Initial value:
= {
.name = "HASH",
.write = hash_write,
.read = hash_read,
}
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)

Definition at line 1274 of file func_strings.c.

Referenced by unload_module().

◆ hashkeys_function

struct ast_custom_function hashkeys_function
static
Initial value:
= {
.name = "HASHKEYS",
.read = hashkeys_read,
.read2 = hashkeys_read2,
}
static int hashkeys_read2(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)

Definition at line 1274 of file func_strings.c.

Referenced by unload_module().

◆ keypadhash_function

struct ast_custom_function keypadhash_function
static
Initial value:
= {
.name = "KEYPADHASH",
.read = keypadhash,
}
static int keypadhash(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)

Definition at line 1542 of file func_strings.c.

Referenced by unload_module().

◆ len_function

struct ast_custom_function len_function
static
Initial value:
= {
.name = "LEN",
.read = len,
.read_max = 12,
}

Definition at line 1416 of file func_strings.c.

Referenced by unload_module().

◆ listfilter_function

struct ast_custom_function listfilter_function
static
Initial value:
= {
.name = "LISTFILTER",
.read = listfilter_read,
.read2 = listfilter_read2,
}
static int listfilter_read2(struct ast_channel *chan, const char *cmd, char *parse, struct ast_str **buf, ssize_t len)
Definition: func_strings.c:723
static int listfilter_read(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
Definition: func_strings.c:718

Definition at line 723 of file func_strings.c.

Referenced by unload_module().

◆ passthru_function

struct ast_custom_function passthru_function
static
Initial value:
= {
.name = "PASSTHRU",
.read2 = passthru,
}
static int passthru(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)

Definition at line 1764 of file func_strings.c.

Referenced by unload_module().

◆ pop_function

struct ast_custom_function pop_function
static
Initial value:
= {
.name = "POP",
.read2 = shift_pop,
}
static int shift_pop(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)

Definition at line 1640 of file func_strings.c.

Referenced by unload_module().

◆ push_function

struct ast_custom_function push_function
static
Initial value:
= {
.name = "PUSH",
.write = unshift_push,
}
static int unshift_push(struct ast_channel *chan, const char *cmd, char *data, const char *new_value)

Definition at line 1700 of file func_strings.c.

Referenced by unload_module().

◆ quote_function

struct ast_custom_function quote_function
static
Initial value:
= {
.name = "QUOTE",
.read = quote,
}
static int quote(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)

Definition at line 1342 of file func_strings.c.

Referenced by unload_module().

◆ regex_function

struct ast_custom_function regex_function
static
Initial value:
= {
.name = "REGEX",
.read = regex,
}
static int regex(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)

Definition at line 1020 of file func_strings.c.

Referenced by unload_module().

◆ replace_function

struct ast_custom_function replace_function
static
Initial value:
= {
.name = "REPLACE",
.read2 = replace,
}

Definition at line 815 of file func_strings.c.

Referenced by unload_module().

◆ result_buf

struct ast_threadstorage result_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_result_buf , .custom_init = NULL , }
static

◆ shift_function

struct ast_custom_function shift_function
static
Initial value:
= {
.name = "SHIFT",
.read2 = shift_pop,
}

Definition at line 1640 of file func_strings.c.

Referenced by unload_module().

◆ strbetween_function

struct ast_custom_function strbetween_function
static
Initial value:
= {
.name = "STRBETWEEN",
.read2 = strbetween,
}
static int strbetween(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)
Definition: func_strings.c:973

Definition at line 973 of file func_strings.c.

Referenced by unload_module().

◆ strftime_function

struct ast_custom_function strftime_function
static
Initial value:
= {
.name = "STRFTIME",
.read = acf_strftime,
}
static int acf_strftime(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t buflen)

Definition at line 1434 of file func_strings.c.

Referenced by unload_module().

◆ strptime_function

struct ast_custom_function strptime_function
static
Initial value:
= {
.name = "STRPTIME",
.read = acf_strptime,
}
static int acf_strptime(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)

Definition at line 1468 of file func_strings.c.

Referenced by unload_module().

◆ strreplace_function

struct ast_custom_function strreplace_function
static
Initial value:
= {
.name = "STRREPLACE",
.read2 = strreplace,
}
static int strreplace(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)
Definition: func_strings.c:884

Definition at line 884 of file func_strings.c.

Referenced by unload_module().

◆ tmp_buf

struct ast_threadstorage tmp_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_tmp_buf , .custom_init = NULL , }
static

Definition at line 48 of file func_strings.c.

Referenced by listfilter().

◆ tolower_function

struct ast_custom_function tolower_function
static
Initial value:
= {
.name = "TOLOWER",
.read = string_tolower,
.read2 = string_tolower2,
}
static int string_tolower(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static int string_tolower2(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t buflen)

Definition at line 1620 of file func_strings.c.

Referenced by unload_module().

◆ toupper_function

struct ast_custom_function toupper_function
static
Initial value:
= {
.name = "TOUPPER",
.read = string_toupper,
.read2 = string_toupper2,
}
static int string_toupper(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static int string_toupper2(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t buflen)

Definition at line 1591 of file func_strings.c.

Referenced by unload_module().

◆ unshift_function

struct ast_custom_function unshift_function
static
Initial value:
= {
.name = "UNSHIFT",
.write = unshift_push,
}

Definition at line 1700 of file func_strings.c.

Referenced by unload_module().