aboutsummaryrefslogtreecommitdiffstats
path: root/1.2-netsec/funcs/func_strings.c
diff options
context:
space:
mode:
Diffstat (limited to '1.2-netsec/funcs/func_strings.c')
-rw-r--r--1.2-netsec/funcs/func_strings.c229
1 files changed, 229 insertions, 0 deletions
diff --git a/1.2-netsec/funcs/func_strings.c b/1.2-netsec/funcs/func_strings.c
new file mode 100644
index 000000000..503611bbe
--- /dev/null
+++ b/1.2-netsec/funcs/func_strings.c
@@ -0,0 +1,229 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2005, Digium, Inc.
+ * Portions Copyright (C) 2005, Tilghman Lesher. All rights reserved.
+ * Portions Copyright (C) 2005, Anthony Minessale II
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ *
+ * \brief String manipulation dialplan functions
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <regex.h>
+
+#include "asterisk.h"
+
+/* ASTERISK_FILE_VERSION(__FILE__, "$Revision$") */
+
+#include "asterisk/channel.h"
+#include "asterisk/pbx.h"
+#include "asterisk/logger.h"
+#include "asterisk/utils.h"
+#include "asterisk/app.h"
+#include "asterisk/localtime.h"
+
+static char *function_fieldqty(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
+{
+ char *varname, *varval, workspace[256];
+ char *delim = ast_strdupa(data);
+ int fieldcount = 0;
+
+ if (delim) {
+ varname = strsep(&delim, "|");
+ pbx_retrieve_variable(chan, varname, &varval, workspace, sizeof(workspace), NULL);
+ if (delim) {
+ while (strsep(&varval, delim))
+ fieldcount++;
+ } else if (!ast_strlen_zero(varval)) {
+ fieldcount = 1;
+ }
+ snprintf(buf, len, "%d", fieldcount);
+ } else {
+ ast_log(LOG_ERROR, "Out of memory\n");
+ strncpy(buf, "1", len);
+ }
+ return buf;
+}
+
+#ifndef BUILTIN_FUNC
+static
+#endif
+struct ast_custom_function fieldqty_function = {
+ .name = "FIELDQTY",
+ .synopsis = "Count the fields, with an arbitrary delimiter",
+ .syntax = "FIELDQTY(<varname>,<delim>)",
+ .read = function_fieldqty,
+};
+
+static char *builtin_function_regex(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
+{
+ char *arg, *earg = NULL, *tmp, errstr[256] = "";
+ int errcode;
+ regex_t regexbuf;
+
+ ast_copy_string(buf, "0", len);
+
+ tmp = ast_strdupa(data);
+ if (!tmp) {
+ ast_log(LOG_ERROR, "Out of memory in %s(%s)\n", cmd, data);
+ return buf;
+ }
+
+ /* Regex in quotes */
+ arg = strchr(tmp, '"');
+ if (arg) {
+ arg++;
+ earg = strrchr(arg, '"');
+ if (earg) {
+ *earg++ = '\0';
+ /* Skip over any spaces before the data we are checking */
+ while (*earg == ' ')
+ earg++;
+ }
+ } else {
+ arg = tmp;
+ }
+
+ if ((errcode = regcomp(&regexbuf, arg, REG_EXTENDED | REG_NOSUB))) {
+ regerror(errcode, &regexbuf, errstr, sizeof(errstr));
+ ast_log(LOG_WARNING, "Malformed input %s(%s): %s\n", cmd, data, errstr);
+ } else {
+ if (!regexec(&regexbuf, earg ? earg : "", 0, NULL, 0))
+ ast_copy_string(buf, "1", len);
+ }
+ regfree(&regexbuf);
+
+ return buf;
+}
+
+#ifndef BUILTIN_FUNC
+static
+#endif
+struct ast_custom_function regex_function = {
+ .name = "REGEX",
+ .synopsis = "Regular Expression: Returns 1 if data matches regular expression.",
+ .syntax = "REGEX(\"<regular expression>\" <data>)",
+ .read = builtin_function_regex,
+};
+
+static char *builtin_function_len(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
+{
+ int length = 0;
+ if (data) {
+ length = strlen(data);
+ }
+ snprintf(buf, len, "%d", length);
+ return buf;
+}
+
+#ifndef BUILTIN_FUNC
+static
+#endif
+struct ast_custom_function len_function = {
+ .name = "LEN",
+ .synopsis = "Returns the length of the argument given",
+ .syntax = "LEN(<string>)",
+ .read = builtin_function_len,
+};
+
+static char *acf_strftime(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
+{
+ char *format, *epoch, *timezone = NULL;
+ long epochi;
+ struct tm time;
+
+ buf[0] = '\0';
+
+ if (!data) {
+ ast_log(LOG_ERROR, "Asterisk function STRFTIME() requires an argument.\n");
+ return buf;
+ }
+
+ format = ast_strdupa(data);
+ if (!format) {
+ ast_log(LOG_ERROR, "Out of memory\n");
+ return buf;
+ }
+
+ epoch = strsep(&format, "|");
+ timezone = strsep(&format, "|");
+
+ if (ast_strlen_zero(epoch) || !sscanf(epoch, "%ld", &epochi)) {
+ struct timeval tv = ast_tvnow();
+ epochi = tv.tv_sec;
+ }
+
+ ast_localtime(&epochi, &time, timezone);
+
+ if (!format) {
+ format = "%c";
+ }
+
+ if (!strftime(buf, len, format, &time)) {
+ ast_log(LOG_WARNING, "C function strftime() output nothing?!!\n");
+ }
+ buf[len - 1] = '\0';
+
+ return buf;
+}
+
+#ifndef BUILTIN_FUNC
+static
+#endif
+struct ast_custom_function strftime_function = {
+ .name = "STRFTIME",
+ .synopsis = "Returns the current date/time in a specified format.",
+ .syntax = "STRFTIME([<epoch>][,[timezone][,format]])",
+ .read = acf_strftime,
+};
+
+static char *function_eval(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
+{
+ memset(buf, 0, len);
+
+ if (ast_strlen_zero(data)) {
+ ast_log(LOG_WARNING, "EVAL requires an argument: EVAL(<string>)\n");
+ return buf;
+ }
+
+ pbx_substitute_variables_helper(chan, data, buf, len - 1);
+
+ return buf;
+}
+
+#ifndef BUILTIN_FUNC
+static
+#endif
+struct ast_custom_function eval_function = {
+ .name = "EVAL",
+ .synopsis = "Evaluate stored variables.",
+ .syntax = "EVAL(<variable>)",
+ .desc = "Using EVAL basically causes a string to be evaluated twice.\n"
+ "When a variable or expression is in the dialplan, it will be\n"
+ "evaluated at runtime. However, if the result of the evaluation\n"
+ "is in fact a variable or expression, using EVAL will have it\n"
+ "evaluated a second time. For example, if the variable ${MYVAR}\n"
+ "contains \"${OTHERVAR}\", then the result of putting ${EVAL(${MYVAR})}\n"
+ "in the dialplan will be the contents of the variable, OTHERVAR.\n"
+ "Normally, by just putting ${MYVAR} in the dialplan, you would be\n"
+ "left with \"${OTHERVAR}\".\n",
+ .read = function_eval,
+};
+