make IF dialplan function handle quoted strings properly (bug #4322, with API mods)
[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         char *ret_true = "1", *ret_false = "0";
27
28         return data && *data ? ret_false : ret_true;
29 }
30
31 static char *builtin_function_exists(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
32 {
33         char *ret_true = "1", *ret_false = "0";
34
35         return data && *data ? ret_true : ret_false;
36 }
37
38 static char *builtin_function_if(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
39 {
40         char *ret = NULL;
41         char *mydata = NULL;
42         char *expr = NULL;
43         char *iftrue = NULL;
44         char *iffalse = NULL;
45
46         if((mydata = ast_strdupa(data))) {
47                 expr = mydata;
48                 if ((iftrue = strchr(mydata, '?'))) {
49                         *iftrue = '\0';
50                         iftrue++;
51                         if ((iffalse = strchr(iftrue, ':'))) {
52                                 *iffalse = '\0';
53                                 iffalse++;
54                         }
55                 } 
56
57                 if (expr && iftrue) {
58                         expr = ast_strip_quoted(expr, "\"", "\"");
59                         iftrue = ast_strip_quoted(iftrue, "\"", "\"");
60
61                         if (iffalse) {
62                                 iffalse = ast_strip_quoted(iffalse, "\"", "\"");
63                         }
64                         ret = ast_true(expr) ? iftrue : iffalse;
65                         if (ret) {
66                                 ast_copy_string(buf, ret, len);
67                                 ret = buf;
68                         }
69                 } else {
70                         ast_log(LOG_WARNING, "Syntax $(if <expr>?[<truecond>][:<falsecond>])\n");
71                         ret = NULL;
72                 }
73         } else {
74                 ast_log(LOG_WARNING, "Memory Error!\n");
75                 ret = NULL;
76         }
77
78         return ret;
79 }
80
81 static char *builtin_function_set(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
82 {
83         char *ret = NULL, *varname, *val;
84
85         if ((varname = ast_strdupa(data))) {
86                 if ((val = strchr(varname, '='))) {
87                         *val = '\0';
88                         val++;
89                         varname = ast_strip(varname);
90                         val = ast_strip(val);
91                         pbx_builtin_setvar_helper(chan, varname, val);
92                         ast_copy_string(buf, val, len);
93                 } else {
94                         ast_log(LOG_WARNING, "Syntax Error!\n");
95                 }
96                 
97         } else {
98         ast_log(LOG_WARNING, "Memory Error!\n");
99     }
100
101         return ret;
102 }
103
104 #ifndef BUILTIN_FUNC
105 static
106 #endif
107 struct ast_custom_function isnull_function = {
108         .name = "ISNULL",
109         .synopsis = "NULL Test: Returns 1 if NULL or 0 otherwise",
110         .syntax = "ISNULL(<data>)",
111         .read = builtin_function_isnull,
112 };
113
114 #ifndef BUILTIN_FUNC
115 static
116 #endif
117 struct ast_custom_function set_function = {
118         .name = "SET",
119         .synopsis = "SET assigns a value to a function call.",
120         .syntax = "SET(<varname>=<value>)",
121         .read = builtin_function_set,
122 };
123
124 #ifndef BUILTIN_FUNC
125 static
126 #endif
127 struct ast_custom_function exists_function = {
128         .name = "EXISTS",
129         .synopsis = "Existence Test: Returns 1 if exists, 0 otherwise",
130         .syntax = "EXISTS(<data>)",
131         .read = builtin_function_exists,
132 };
133
134 #ifndef BUILTIN_FUNC
135 static
136 #endif
137 struct ast_custom_function if_function = {
138         .name = "IF",
139         .synopsis = "Conditional: Returns the data following '?' if true else the data following ':'",
140         .syntax = "IF(<expr>?<true>:<false>)",
141         .read = builtin_function_if,
142 };