00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <stdlib.h>
00025 #include <stdio.h>
00026 #include <string.h>
00027 #include <sys/types.h>
00028 #include <sched.h>
00029
00030 #include "asterisk.h"
00031
00032 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 20003 $")
00033
00034 #include "asterisk/module.h"
00035 #include "asterisk/channel.h"
00036 #include "asterisk/pbx.h"
00037 #include "asterisk/logger.h"
00038 #include "asterisk/utils.h"
00039 #include "asterisk/app.h"
00040 #include "asterisk/localtime.h"
00041
00042 AST_MUTEX_DEFINE_STATIC(local_lock);
00043 static int use_count = 0;
00044
00045 static unsigned int trunk_app_separate_args(char *buf, char delim, char **array, int arraylen)
00046 {
00047 int argc;
00048 char *scan;
00049 int paren = 0, quote = 0;
00050
00051 if (!buf || !array || !arraylen)
00052 return 0;
00053
00054 memset(array, 0, arraylen * sizeof(*array));
00055
00056 scan = buf;
00057
00058 for (argc = 0; *scan && (argc < arraylen - 1); argc++) {
00059 array[argc] = scan;
00060 for (; *scan; scan++) {
00061 if (*scan == '(')
00062 paren++;
00063 else if (*scan == ')') {
00064 if (paren)
00065 paren--;
00066 } else if (*scan == '"') {
00067 quote = quote ? 0 : 1;
00068
00069 memmove(scan, scan + 1, strlen(scan));
00070 scan--;
00071 } else if (*scan == '\\') {
00072
00073 memmove(scan, scan + 1, strlen(scan));
00074 } else if ((*scan == delim) && !paren && !quote) {
00075 *scan++ = '\0';
00076 break;
00077 }
00078 }
00079 }
00080
00081 if (*scan)
00082 array[argc++] = scan;
00083
00084 return argc;
00085 }
00086
00087 static void array(struct ast_channel *chan, char *cmd, char *var, const char *value)
00088 {
00089 AST_DECLARE_APP_ARGS(arg1,
00090 AST_APP_ARG(var)[100];
00091 );
00092 AST_DECLARE_APP_ARGS(arg2,
00093 AST_APP_ARG(val)[100];
00094 );
00095 char *value2;
00096 int i;
00097
00098 value2 = ast_strdupa(value);
00099 if (!var || !value2)
00100 return;
00101
00102 ast_mutex_lock(&local_lock);
00103 use_count++;
00104 ast_mutex_unlock(&local_lock);
00105
00106
00107
00108
00109
00110
00111
00112 ast_log(LOG_DEBUG, "array (%s=%s)\n", var, value2);
00113 if (strchr(var, ','))
00114 arg1.argc = trunk_app_separate_args(var, ',', arg1.argv, (sizeof(arg1) - sizeof(arg1.argc)) / sizeof(arg1.argv[0]));
00115 else
00116 arg1.argc = trunk_app_separate_args(var, '|', arg1.argv, (sizeof(arg1) - sizeof(arg1.argc)) / sizeof(arg1.argv[0]));
00117
00118 if (strchr(value2, ','))
00119 arg2.argc = trunk_app_separate_args(value2, ',', arg2.argv, (sizeof(arg2) - sizeof(arg2.argc)) / sizeof(arg2.argv[0]));
00120 else
00121 arg2.argc = trunk_app_separate_args(value2, '|', arg2.argv, (sizeof(arg2) - sizeof(arg2.argc)) / sizeof(arg2.argv[0]));
00122
00123 for (i = 0; i < arg1.argc; i++) {
00124 ast_log(LOG_DEBUG, "array set value (%s=%s)\n", arg1.var[i],
00125 arg2.val[i]);
00126 if (i < arg2.argc) {
00127 pbx_builtin_setvar_helper(chan, arg1.var[i], arg2.val[i]);
00128 } else {
00129
00130
00131 pbx_builtin_setvar_helper(chan, arg1.var[i], "");
00132 }
00133 }
00134
00135 ast_mutex_lock(&local_lock);
00136 use_count--;
00137 ast_mutex_unlock(&local_lock);
00138
00139 return;
00140 }
00141
00142 static struct ast_custom_function array_function = {
00143 .name = "ARRAY",
00144 .synopsis = "Allows setting multiple variables at once",
00145 .syntax = "ARRAY(var1[,var2[...][,varN]])",
00146 .write = array,
00147 .desc =
00148 "The comma-separated list passed as a value to which the function is set will\n"
00149 "be interpreted as a set of values to which the comma-separated list of\n"
00150 "variable names in the argument should be set.\n"
00151 "Hence, Set(ARRAY(var1,var2)=1,2) will set var1 to 1 and var2 to 2\n"
00152 "Note: remember to either backslash your commas in extensions.conf or quote the\n"
00153 "entire argument, since Set can take multiple arguments itself.\n",
00154 };
00155
00156 static char *tdesc = "String handling dialplan functions";
00157
00158 int unload_module(void)
00159 {
00160 int res = 0;
00161
00162 res |= ast_custom_function_unregister(&array_function);
00163 sched_yield();
00164
00165 return res;
00166 }
00167
00168 int load_module(void)
00169 {
00170 int res = 0;
00171
00172 res |= ast_custom_function_register(&array_function);
00173
00174 return res;
00175 }
00176
00177 char *description(void)
00178 {
00179 return tdesc;
00180 }
00181
00182 int usecount(void)
00183 {
00184 return use_count;
00185 }
00186
00187 char *key(void)
00188 {
00189 return ASTERISK_GPL_KEY;
00190 }
00191