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