12402637b0284329864f83204a51355ffd0536ce
[asterisk/asterisk.git] / funcs / func_logic.c
1 /*
2  * Asterisk -- A telephony toolkit for Linux.
3  *
4  * Conditional logic dialplan functions
5  * 
6  * Copyright (C) 2005, Digium, Inc.
7  * Portions Copyright (C) 2005, Anthony Minessale II
8  *
9  * This program is free software, distributed under the terms of
10  * the GNU General Public License
11  */
12
13 #include <stdlib.h>
14 #include <string.h>
15 #include <sys/types.h>
16
17 #include "asterisk/channel.h"
18 #include "asterisk/pbx.h"
19 #include "asterisk/logger.h"
20 #include "asterisk/utils.h"
21 #include "asterisk/app.h"
22 #include "asterisk/config.h"            /* for ast_true */
23
24 static char *builtin_function_isnull(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
25 {
26         return data && *data ? "0" : "1";
27 }
28
29 static char *builtin_function_exists(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
30 {
31         return data && *data ? "1" : "0";
32 }
33
34 static char *builtin_function_iftime(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
35 {
36         struct ast_timing timing;
37         char *ret;
38         char *expr;
39         char *iftrue;
40         char *iffalse;
41
42         if (!(data = ast_strdupa(data))) {
43                 ast_log(LOG_WARNING, "Memory Error!\n");
44                 return NULL;
45         }
46
47         data = ast_strip_quoted(data, "\"", "\"");
48         expr = strsep(&data, "?");
49         iftrue = strsep(&data, ":");
50         iffalse = data;
51
52         if (!expr || ast_strlen_zero(expr) || !(iftrue || iffalse)) {
53                 ast_log(LOG_WARNING, "Syntax IFTIME(<timespec>?[<true>][:<false>])\n");
54                 return NULL;
55         }
56
57         if (!ast_build_timing(&timing, expr)) {
58                 ast_log(LOG_WARNING, "Invalid Time Spec.\n");
59                 return NULL;
60         }
61
62         if (iftrue)
63                 iftrue = ast_strip_quoted(iftrue, "\"", "\"");
64         if (iffalse)
65                 iffalse = ast_strip_quoted(iffalse, "\"", "\"");
66
67         if ((ret = ast_check_timing(&timing) ? iftrue : iffalse)) {
68                 ast_copy_string(buf, ret, len);
69                 ret = buf;
70         } 
71         
72         return ret;
73 }
74
75 static char *builtin_function_if(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
76 {
77         char *ret;
78         char *expr;
79         char *iftrue;
80         char *iffalse;
81
82         if (!(data = ast_strdupa(data))) {
83                 ast_log(LOG_WARNING, "Memory Error!\n");
84                 return NULL;
85         }
86
87         data = ast_strip_quoted(data, "\"", "\"");
88         expr = strsep(&data, "?");
89         iftrue = strsep(&data, ":");
90         iffalse = data;
91
92         if (!expr || ast_strlen_zero(expr) || !(iftrue || iffalse)) {
93                 ast_log(LOG_WARNING, "Syntax IF(<timespec>?[<true>][:<false>])\n");
94                 return NULL;
95         }
96
97         if (iftrue)
98                 iftrue = ast_strip_quoted(iftrue, "\"", "\"");
99         if (iffalse)
100                 iffalse = ast_strip_quoted(iffalse, "\"", "\"");
101
102         if ((ret = ast_true(expr) ? iftrue : iffalse)) {
103                 ast_copy_string(buf, ret, len);
104                 ret = buf;
105         } 
106         
107         return ret;
108 }
109
110 static char *builtin_function_set(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
111 {
112         char *varname;
113         char *val;
114
115         if (!(data = ast_strdupa(data))) {
116                 ast_log(LOG_WARNING, "Memory Error!\n");
117                 return NULL;
118         }
119
120         varname = strsep(&data, "=");
121         val = data;
122
123         if (!varname || ast_strlen_zero(varname) || !val) {
124                 ast_log(LOG_WARNING, "Syntax SET(<varname>=[<value>])\n");
125                 return NULL;
126         }
127
128         varname = ast_strip(varname);
129         val = ast_strip(val);
130         pbx_builtin_setvar_helper(chan, varname, val);
131         ast_copy_string(buf, val, len);
132
133         return buf;
134 }
135
136 #ifndef BUILTIN_FUNC
137 static
138 #endif
139 struct ast_custom_function isnull_function = {
140         .name = "ISNULL",
141         .synopsis = "NULL Test: Returns 1 if NULL or 0 otherwise",
142         .syntax = "ISNULL(<data>)",
143         .read = builtin_function_isnull,
144 };
145
146 #ifndef BUILTIN_FUNC
147 static
148 #endif
149 struct ast_custom_function set_function = {
150         .name = "SET",
151         .synopsis = "SET assigns a value to a channel variable",
152         .syntax = "SET(<varname>=[<value>])",
153         .read = builtin_function_set,
154 };
155
156 #ifndef BUILTIN_FUNC
157 static
158 #endif
159 struct ast_custom_function exists_function = {
160         .name = "EXISTS",
161         .synopsis = "Existence Test: Returns 1 if exists, 0 otherwise",
162         .syntax = "EXISTS(<data>)",
163         .read = builtin_function_exists,
164 };
165
166 #ifndef BUILTIN_FUNC
167 static
168 #endif
169 struct ast_custom_function if_function = {
170         .name = "IF",
171         .synopsis = "Conditional: Returns the data following '?' if true else the data following ':'",
172         .syntax = "IF(<expr>?[<true>][:<false>])",
173         .read = builtin_function_if,
174 };
175
176
177 #ifndef BUILTIN_FUNC
178 static
179 #endif
180 struct ast_custom_function if_time_function = {
181         .name = "IFTIME",
182         .synopsis = "Temporal Conditional: Returns the data following '?' if true else the data following ':'",
183         .syntax = "IFTIME(<timespec>?[<true>][:<false>])",
184         .read = builtin_function_iftime,
185 };