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
00028
00029
00030
00031 #include "asterisk.h"
00032
00033 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 328209 $")
00034
00035 #include "asterisk/module.h"
00036 #include "asterisk/channel.h"
00037 #include "asterisk/pbx.h"
00038 #include "asterisk/utils.h"
00039 #include "asterisk/app.h"
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118 static int isnull(struct ast_channel *chan, const char *cmd, char *data,
00119 char *buf, size_t len)
00120 {
00121 strcpy(buf, data && *data ? "0" : "1");
00122
00123 return 0;
00124 }
00125
00126 static int exists(struct ast_channel *chan, const char *cmd, char *data, char *buf,
00127 size_t len)
00128 {
00129 strcpy(buf, data && *data ? "1" : "0");
00130
00131 return 0;
00132 }
00133
00134 static int iftime(struct ast_channel *chan, const char *cmd, char *data, char *buf,
00135 size_t len)
00136 {
00137 struct ast_timing timing;
00138 char *expr;
00139 char *iftrue;
00140 char *iffalse;
00141
00142 data = ast_strip_quoted(data, "\"", "\"");
00143 expr = strsep(&data, "?");
00144 iftrue = strsep(&data, ":");
00145 iffalse = data;
00146
00147 if (ast_strlen_zero(expr) || !(iftrue || iffalse)) {
00148 ast_log(LOG_WARNING,
00149 "Syntax IFTIME(<timespec>?[<true>][:<false>])\n");
00150 return -1;
00151 }
00152
00153 if (!ast_build_timing(&timing, expr)) {
00154 ast_log(LOG_WARNING, "Invalid Time Spec.\n");
00155 ast_destroy_timing(&timing);
00156 return -1;
00157 }
00158
00159 if (iftrue)
00160 iftrue = ast_strip_quoted(iftrue, "\"", "\"");
00161 if (iffalse)
00162 iffalse = ast_strip_quoted(iffalse, "\"", "\"");
00163
00164 ast_copy_string(buf, ast_check_timing(&timing) ? S_OR(iftrue, "") : S_OR(iffalse, ""), len);
00165 ast_destroy_timing(&timing);
00166
00167 return 0;
00168 }
00169
00170 static int acf_if(struct ast_channel *chan, const char *cmd, char *data, char *buf,
00171 size_t len)
00172 {
00173 AST_DECLARE_APP_ARGS(args1,
00174 AST_APP_ARG(expr);
00175 AST_APP_ARG(remainder);
00176 );
00177 AST_DECLARE_APP_ARGS(args2,
00178 AST_APP_ARG(iftrue);
00179 AST_APP_ARG(iffalse);
00180 );
00181 args2.iftrue = args2.iffalse = NULL;
00182
00183
00184
00185
00186
00187
00188 AST_NONSTANDARD_APP_ARGS(args1, data, '?');
00189 AST_NONSTANDARD_APP_ARGS(args2, args1.remainder, ':');
00190
00191 if (ast_strlen_zero(args1.expr) || !(args2.iftrue || args2.iffalse)) {
00192 ast_log(LOG_WARNING, "Syntax IF(<expr>?[<true>][:<false>]) (expr must be non-null, and either <true> or <false> must be non-null)\n");
00193 ast_log(LOG_WARNING, " In this case, <expr>='%s', <true>='%s', and <false>='%s'\n", args1.expr, args2.iftrue, args2.iffalse);
00194 return -1;
00195 }
00196
00197 args1.expr = ast_strip(args1.expr);
00198 if (args2.iftrue)
00199 args2.iftrue = ast_strip(args2.iftrue);
00200 if (args2.iffalse)
00201 args2.iffalse = ast_strip(args2.iffalse);
00202
00203 ast_copy_string(buf, pbx_checkcondition(args1.expr) ? (S_OR(args2.iftrue, "")) : (S_OR(args2.iffalse, "")), len);
00204
00205 return 0;
00206 }
00207
00208 static int set(struct ast_channel *chan, const char *cmd, char *data, char *buf,
00209 size_t len)
00210 {
00211 char *varname;
00212 char *val;
00213
00214 varname = strsep(&data, "=");
00215 val = data;
00216
00217 if (ast_strlen_zero(varname) || !val) {
00218 ast_log(LOG_WARNING, "Syntax SET(<varname>=[<value>])\n");
00219 return -1;
00220 }
00221
00222 varname = ast_strip(varname);
00223 val = ast_strip(val);
00224 pbx_builtin_setvar_helper(chan, varname, val);
00225 ast_copy_string(buf, val, len);
00226
00227 return 0;
00228 }
00229
00230 static int set2(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **str, ssize_t len)
00231 {
00232 if (len > -1) {
00233 ast_str_make_space(str, len == 0 ? strlen(data) : len);
00234 }
00235 return set(chan, cmd, data, ast_str_buffer(*str), ast_str_size(*str));
00236 }
00237
00238 static int import_helper(struct ast_channel *chan, const char *cmd, char *data, char *buf, struct ast_str **str, ssize_t len)
00239 {
00240 AST_DECLARE_APP_ARGS(args,
00241 AST_APP_ARG(channel);
00242 AST_APP_ARG(varname);
00243 );
00244 AST_STANDARD_APP_ARGS(args, data);
00245 if (buf) {
00246 *buf = '\0';
00247 }
00248
00249 if (!ast_strlen_zero(args.varname)) {
00250 struct ast_channel *chan2;
00251
00252 if ((chan2 = ast_channel_get_by_name(args.channel))) {
00253 char *s = alloca(strlen(args.varname) + 4);
00254 if (s) {
00255 sprintf(s, "${%s}", args.varname);
00256 ast_channel_lock(chan2);
00257 if (buf) {
00258 pbx_substitute_variables_helper(chan2, s, buf, len);
00259 } else {
00260 ast_str_substitute_variables(str, len, chan2, s);
00261 }
00262 ast_channel_unlock(chan2);
00263 }
00264 chan2 = ast_channel_unref(chan2);
00265 }
00266 }
00267
00268 return 0;
00269 }
00270
00271 static int import_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
00272 {
00273 return import_helper(chan, cmd, data, buf, NULL, len);
00274 }
00275
00276 static int import_read2(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **str, ssize_t len)
00277 {
00278 return import_helper(chan, cmd, data, NULL, str, len);
00279 }
00280
00281 static struct ast_custom_function isnull_function = {
00282 .name = "ISNULL",
00283 .read = isnull,
00284 .read_max = 2,
00285 };
00286
00287 static struct ast_custom_function set_function = {
00288 .name = "SET",
00289 .read = set,
00290 .read2 = set2,
00291 };
00292
00293 static struct ast_custom_function exists_function = {
00294 .name = "EXISTS",
00295 .read = exists,
00296 .read_max = 2,
00297 };
00298
00299 static struct ast_custom_function if_function = {
00300 .name = "IF",
00301 .read = acf_if,
00302 };
00303
00304 static struct ast_custom_function if_time_function = {
00305 .name = "IFTIME",
00306 .read = iftime,
00307 };
00308
00309 static struct ast_custom_function import_function = {
00310 .name = "IMPORT",
00311 .read = import_read,
00312 .read2 = import_read2,
00313 };
00314
00315 static int unload_module(void)
00316 {
00317 int res = 0;
00318
00319 res |= ast_custom_function_unregister(&isnull_function);
00320 res |= ast_custom_function_unregister(&set_function);
00321 res |= ast_custom_function_unregister(&exists_function);
00322 res |= ast_custom_function_unregister(&if_function);
00323 res |= ast_custom_function_unregister(&if_time_function);
00324 res |= ast_custom_function_unregister(&import_function);
00325
00326 return res;
00327 }
00328
00329 static int load_module(void)
00330 {
00331 int res = 0;
00332
00333 res |= ast_custom_function_register(&isnull_function);
00334 res |= ast_custom_function_register(&set_function);
00335 res |= ast_custom_function_register(&exists_function);
00336 res |= ast_custom_function_register(&if_function);
00337 res |= ast_custom_function_register(&if_time_function);
00338 res |= ast_custom_function_register(&import_function);
00339
00340 return res;
00341 }
00342
00343 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Logical dialplan functions");