revert my pass through the tree to remove checks of the result of ast_strdupa
[asterisk/asterisk.git] / apps / app_url.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2005, Digium, Inc.
5  *
6  * Mark Spencer <markster@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*! \file
20  *
21  * \brief App to transmit a URL
22  *
23  * \author Mark Spencer <markster@digium.com>
24  * 
25  * \ingroup applications
26  */
27  
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <string.h>
31
32 #include "asterisk.h"
33
34 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
35
36 #include "asterisk/lock.h"
37 #include "asterisk/file.h"
38 #include "asterisk/logger.h"
39 #include "asterisk/channel.h"
40 #include "asterisk/pbx.h"
41 #include "asterisk/module.h"
42 #include "asterisk/translate.h"
43 #include "asterisk/image.h"
44 #include "asterisk/options.h"
45
46 static char *tdesc = "Send URL Applications";
47
48 static char *app = "SendURL";
49
50 static char *synopsis = "Send a URL";
51
52 static char *descrip = 
53 "  SendURL(URL[|option]): Requests client go to URL (IAX2) or sends the \n"
54 "URL to the client (other channels).\n"
55 "Result is returned in the SENDURLSTATUS channel variable:\n"
56 "    SUCCESS       URL successfully sent to client\n"
57 "    FAILURE       Failed to send URL\n"
58 "    NOLOAD        Clien failed to load URL (wait enabled)\n"
59 "    UNSUPPORTED   Channel does not support URL transport\n"
60 "\n"
61 "If the option 'wait' is specified, execution will wait for an\n"
62 "acknowledgement that the URL has been loaded before continuing\n"
63 "and will return -1 if the peer is unable to load the URL\n"
64 "\n"
65 "Old behaviour (deprecated): \n"
66 " If the client does not support Asterisk \"html\" transport, \n"
67 " and there exists a step with priority n + 101, then execution will\n"
68 " continue at that step.\n"
69 " Otherwise, execution will continue at the next priority level.\n"
70 " SendURL only returns 0 if the URL was sent correctly  or if\n"
71 " the channel does not support HTML transport, and -1 otherwise.\n";
72
73 STANDARD_LOCAL_USER;
74
75 LOCAL_USER_DECL;
76
77 static int sendurl_exec(struct ast_channel *chan, void *data)
78 {
79         int res = 0;
80         struct localuser *u;
81         char *tmp;
82         char *options;
83         int local_option_wait=0;
84         int local_option_jump = 0;
85         struct ast_frame *f;
86         char *stringp=NULL;
87         char *status = "FAILURE";
88         
89         if (ast_strlen_zero(data)) {
90                 ast_log(LOG_WARNING, "SendURL requires an argument (URL)\n");
91                 pbx_builtin_setvar_helper(chan, "SENDURLSTATUS", status);
92                 return -1;
93         }
94
95         LOCAL_USER_ADD(u);
96
97         tmp = ast_strdupa(data);
98         if (!tmp) {
99                 ast_log(LOG_ERROR, "Out of memory\n");
100                 LOCAL_USER_REMOVE(u);
101                 return -1;
102         }
103
104         stringp=tmp;
105         strsep(&stringp, "|");
106         options = strsep(&stringp, "|");
107         if (options && !strcasecmp(options, "wait"))
108                 local_option_wait = 1;
109         if (options && !strcasecmp(options, "j"))
110                 local_option_jump = 1;
111         
112         if (!ast_channel_supports_html(chan)) {
113                 /* Does not support transport */
114                 if (local_option_jump || ast_opt_priority_jumping)
115                          ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
116                 pbx_builtin_setvar_helper(chan, "SENDURLSTATUS", "UNSUPPORTED");
117                 LOCAL_USER_REMOVE(u);
118                 return 0;
119         }
120         res = ast_channel_sendurl(chan, tmp);
121         if (res == -1) {
122                 pbx_builtin_setvar_helper(chan, "SENDURLSTATUS", "FAILURE");
123                 LOCAL_USER_REMOVE(u);
124                 return res;
125         }
126         status = "SUCCESS";
127         if (local_option_wait) {
128                 for(;;) {
129                         /* Wait for an event */
130                         res = ast_waitfor(chan, -1);
131                         if (res < 0) 
132                                 break;
133                         f = ast_read(chan);
134                         if (!f) {
135                                 res = -1;
136                                 status = "FAILURE";
137                                 break;
138                         }
139                         if (f->frametype == AST_FRAME_HTML) {
140                                 switch(f->subclass) {
141                                 case AST_HTML_LDCOMPLETE:
142                                         res = 0;
143                                         ast_frfree(f);
144                                         status = "NOLOAD";
145                                         goto out;
146                                         break;
147                                 case AST_HTML_NOSUPPORT:
148                                         /* Does not support transport */
149                                         status ="UNSUPPORTED";
150                                         if (local_option_jump || ast_opt_priority_jumping)
151                                                 ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
152                                         res = 0;
153                                         goto out;
154                                         break;
155                                 default:
156                                         ast_log(LOG_WARNING, "Don't know what to do with HTML subclass %d\n", f->subclass);
157                                 };
158                         }
159                         ast_frfree(f);
160                 }
161         } 
162 out:    
163         pbx_builtin_setvar_helper(chan, "SENDURLSTATUS", status);
164         LOCAL_USER_REMOVE(u);
165         return res;
166 }
167
168 int unload_module(void)
169 {
170         int res;
171
172         res = ast_unregister_application(app);
173         
174         STANDARD_HANGUP_LOCALUSERS;
175
176         return res;     
177 }
178
179 int load_module(void)
180 {
181         return ast_register_application(app, sendurl_exec, synopsis, descrip);
182 }
183
184 char *description(void)
185 {
186         return tdesc;
187 }
188
189 int usecount(void)
190 {
191         int res;
192         STANDARD_USECOUNT(res);
193         return res;
194 }
195
196 char *key()
197 {
198         return ASTERISK_GPL_KEY;
199 }