00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "asterisk.h"
00028
00029 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
00030
00031 #include <stdio.h>
00032 #include <stdlib.h>
00033 #include <string.h>
00034 #include <sys/types.h>
00035
00036 #include "asterisk/module.h"
00037 #include "asterisk/channel.h"
00038 #include "asterisk/pbx.h"
00039 #include "asterisk/logger.h"
00040 #include "asterisk/utils.h"
00041 #include "asterisk/app.h"
00042
00043 static int isnull(struct ast_channel *chan, char *cmd, char *data,
00044 char *buf, size_t len)
00045 {
00046 strcpy(buf, data && *data ? "0" : "1");
00047
00048 return 0;
00049 }
00050
00051 static int exists(struct ast_channel *chan, char *cmd, char *data, char *buf,
00052 size_t len)
00053 {
00054 strcpy(buf, data && *data ? "1" : "0");
00055
00056 return 0;
00057 }
00058
00059 static int iftime(struct ast_channel *chan, char *cmd, char *data, char *buf,
00060 size_t len)
00061 {
00062 struct ast_timing timing;
00063 char *expr;
00064 char *iftrue;
00065 char *iffalse;
00066
00067 data = ast_strip_quoted(data, "\"", "\"");
00068 expr = strsep(&data, "?");
00069 iftrue = strsep(&data, ":");
00070 iffalse = data;
00071
00072 if (ast_strlen_zero(expr) || !(iftrue || iffalse)) {
00073 ast_log(LOG_WARNING,
00074 "Syntax IFTIME(<timespec>?[<true>][:<false>])\n");
00075 return -1;
00076 }
00077
00078 if (!ast_build_timing(&timing, expr)) {
00079 ast_log(LOG_WARNING, "Invalid Time Spec.\n");
00080 return -1;
00081 }
00082
00083 if (iftrue)
00084 iftrue = ast_strip_quoted(iftrue, "\"", "\"");
00085 if (iffalse)
00086 iffalse = ast_strip_quoted(iffalse, "\"", "\"");
00087
00088 ast_copy_string(buf, ast_check_timing(&timing) ? iftrue : iffalse, len);
00089
00090 return 0;
00091 }
00092
00093 static int acf_if(struct ast_channel *chan, char *cmd, char *data, char *buf,
00094 size_t len)
00095 {
00096 char *expr;
00097 char *iftrue;
00098 char *iffalse;
00099
00100 data = ast_strip_quoted(data, "\"", "\"");
00101 expr = strsep(&data, "?");
00102 iftrue = strsep(&data, ":");
00103 iffalse = data;
00104
00105 if (ast_strlen_zero(expr) || !(iftrue || iffalse)) {
00106 ast_log(LOG_WARNING, "Syntax IF(<expr>?[<true>][:<false>])\n");
00107 return -1;
00108 }
00109
00110 expr = ast_strip(expr);
00111 if (iftrue)
00112 iftrue = ast_strip_quoted(iftrue, "\"", "\"");
00113 if (iffalse)
00114 iffalse = ast_strip_quoted(iffalse, "\"", "\"");
00115
00116 ast_copy_string(buf, pbx_checkcondition(expr) ? (S_OR(iftrue, "")) : (S_OR(iffalse, "")), len);
00117
00118 return 0;
00119 }
00120
00121 static int set(struct ast_channel *chan, char *cmd, char *data, char *buf,
00122 size_t len)
00123 {
00124 char *varname;
00125 char *val;
00126
00127 varname = strsep(&data, "=");
00128 val = data;
00129
00130 if (ast_strlen_zero(varname) || !val) {
00131 ast_log(LOG_WARNING, "Syntax SET(<varname>=[<value>])\n");
00132 return -1;
00133 }
00134
00135 varname = ast_strip(varname);
00136 val = ast_strip(val);
00137 pbx_builtin_setvar_helper(chan, varname, val);
00138 ast_copy_string(buf, val, len);
00139
00140 return 0;
00141 }
00142
00143 static struct ast_custom_function isnull_function = {
00144 .name = "ISNULL",
00145 .synopsis = "NULL Test: Returns 1 if NULL or 0 otherwise",
00146 .syntax = "ISNULL(<data>)",
00147 .read = isnull,
00148 };
00149
00150 static struct ast_custom_function set_function = {
00151 .name = "SET",
00152 .synopsis = "SET assigns a value to a channel variable",
00153 .syntax = "SET(<varname>=[<value>])",
00154 .read = set,
00155 };
00156
00157 static struct ast_custom_function exists_function = {
00158 .name = "EXISTS",
00159 .synopsis = "Existence Test: Returns 1 if exists, 0 otherwise",
00160 .syntax = "EXISTS(<data>)",
00161 .read = exists,
00162 };
00163
00164 static struct ast_custom_function if_function = {
00165 .name = "IF",
00166 .synopsis =
00167 "Conditional: Returns the data following '?' if true else the data following ':'",
00168 .syntax = "IF(<expr>?[<true>][:<false>])",
00169 .read = acf_if,
00170 };
00171
00172 static struct ast_custom_function if_time_function = {
00173 .name = "IFTIME",
00174 .synopsis =
00175 "Temporal Conditional: Returns the data following '?' if true else the data following ':'",
00176 .syntax = "IFTIME(<timespec>?[<true>][:<false>])",
00177 .read = iftime,
00178 };
00179
00180 static int unload_module(void)
00181 {
00182 int res = 0;
00183
00184 res |= ast_custom_function_unregister(&isnull_function);
00185 res |= ast_custom_function_unregister(&set_function);
00186 res |= ast_custom_function_unregister(&exists_function);
00187 res |= ast_custom_function_unregister(&if_function);
00188 res |= ast_custom_function_unregister(&if_time_function);
00189
00190 return res;
00191 }
00192
00193 static int load_module(void)
00194 {
00195 int res = 0;
00196
00197 res |= ast_custom_function_register(&isnull_function);
00198 res |= ast_custom_function_register(&set_function);
00199 res |= ast_custom_function_register(&exists_function);
00200 res |= ast_custom_function_register(&if_function);
00201 res |= ast_custom_function_register(&if_time_function);
00202
00203 return res;
00204 }
00205
00206 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Logical dialplan functions");