f748ba93906e0677ebd9b836dad1483b5d2b8b06
[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  */
23
24 #include <stdlib.h>
25 #include <string.h>
26 #include <sys/types.h>
27
28 #include "asterisk.h"
29
30 /* ASTERISK_FILE_VERSION(__FILE__, "$Revision$") */
31
32 #include "asterisk/channel.h"
33 #include "asterisk/pbx.h"
34 #include "asterisk/logger.h"
35 #include "asterisk/utils.h"
36 #include "asterisk/app.h"
37 #include "asterisk/config.h"            /* for ast_true */
38
39 static char *builtin_function_isnull(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
40 {
41         return data && *data ? "0" : "1";
42 }
43
44 static char *builtin_function_exists(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
45 {
46         return data && *data ? "1" : "0";
47 }
48
49 static char *builtin_function_iftime(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
50 {
51         struct ast_timing timing;
52         char *ret;
53         char *expr;
54         char *iftrue;
55         char *iffalse;
56
57         if (!(data = ast_strdupa(data))) {
58                 ast_log(LOG_WARNING, "Memory Error!\n");
59                 return NULL;
60         }
61
62         data = ast_strip_quoted(data, "\"", "\"");
63         expr = strsep(&data, "?");
64         iftrue = strsep(&data, ":");
65         iffalse = data;
66
67         if (ast_strlen_zero(expr) || !(iftrue || iffalse)) {
68                 ast_log(LOG_WARNING, "Syntax IFTIME(<timespec>?[<true>][:<false>])\n");
69                 return NULL;
70         }
71
72         if (!ast_build_timing(&timing, expr)) {
73                 ast_log(LOG_WARNING, "Invalid Time Spec.\n");
74                 return NULL;
75         }
76
77         if (iftrue)
78                 iftrue = ast_strip_quoted(iftrue, "\"", "\"");
79         if (iffalse)
80                 iffalse = ast_strip_quoted(iffalse, "\"", "\"");
81
82         if ((ret = ast_check_timing(&timing) ? iftrue : iffalse)) {
83                 ast_copy_string(buf, ret, len);
84                 ret = buf;
85         } 
86         
87         return ret;
88 }
89
90 static char *builtin_function_if(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
91 {
92         char *ret;
93         char *expr;
94         char *iftrue;
95         char *iffalse;
96
97         if (!(data = ast_strdupa(data))) {
98                 ast_log(LOG_WARNING, "Memory Error!\n");
99                 return NULL;
100         }
101
102         data = ast_strip_quoted(data, "\"", "\"");
103         expr = strsep(&data, "?");
104         iftrue = strsep(&data, ":");
105         iffalse = data;
106
107         if (ast_strlen_zero(expr) || !(iftrue || iffalse)) {
108                 ast_log(LOG_WARNING, "Syntax IF(<expr>?[<true>][:<false>])\n");
109                 return NULL;
110         }
111
112         expr = ast_strip(expr);
113         if (iftrue)
114                 iftrue = ast_strip_quoted(iftrue, "\"", "\"");
115         if (iffalse)
116                 iffalse = ast_strip_quoted(iffalse, "\"", "\"");
117
118         if ((ret = ast_true(expr) ? iftrue : iffalse)) {
119                 ast_copy_string(buf, ret, len);
120                 ret = buf;
121         } 
122         
123         return ret;
124 }
125
126 static char *builtin_function_set(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
127 {
128         char *varname;
129         char *val;
130
131         if (!(data = ast_strdupa(data))) {
132                 ast_log(LOG_WARNING, "Memory Error!\n");
133                 return NULL;
134         }
135
136         varname = strsep(&data, "=");
137         val = data;
138
139         if (ast_strlen_zero(varname) || !val) {
140                 ast_log(LOG_WARNING, "Syntax SET(<varname>=[<value>])\n");
141                 return NULL;
142         }
143
144         varname = ast_strip(varname);
145         val = ast_strip(val);
146         pbx_builtin_setvar_helper(chan, varname, val);
147         ast_copy_string(buf, val, len);
148
149         return buf;
150 }
151
152 #ifndef BUILTIN_FUNC
153 static
154 #endif
155 struct ast_custom_function isnull_function = {
156         .name = "ISNULL",
157         .synopsis = "NULL Test: Returns 1 if NULL or 0 otherwise",
158         .syntax = "ISNULL(<data>)",
159         .read = builtin_function_isnull,
160 };
161
162 #ifndef BUILTIN_FUNC
163 static
164 #endif
165 struct ast_custom_function set_function = {
166         .name = "SET",
167         .synopsis = "SET assigns a value to a channel variable",
168         .syntax = "SET(<varname>=[<value>])",
169         .read = builtin_function_set,
170 };
171
172 #ifndef BUILTIN_FUNC
173 static
174 #endif
175 struct ast_custom_function exists_function = {
176         .name = "EXISTS",
177         .synopsis = "Existence Test: Returns 1 if exists, 0 otherwise",
178         .syntax = "EXISTS(<data>)",
179         .read = builtin_function_exists,
180 };
181
182 #ifndef BUILTIN_FUNC
183 static
184 #endif
185 struct ast_custom_function if_function = {
186         .name = "IF",
187         .synopsis = "Conditional: Returns the data following '?' if true else the data following ':'",
188         .syntax = "IF(<expr>?[<true>][:<false>])",
189         .read = builtin_function_if,
190 };
191
192
193 #ifndef BUILTIN_FUNC
194 static
195 #endif
196 struct ast_custom_function if_time_function = {
197         .name = "IFTIME",
198         .synopsis = "Temporal Conditional: Returns the data following '?' if true else the data following ':'",
199         .syntax = "IFTIME(<timespec>?[<true>][:<false>])",
200         .read = builtin_function_iftime,
201 };