constify arguments in more places where strings should not be modified (issue #6286)
[asterisk/asterisk.git] / res / res_clioriginate.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2005, Digium, Inc.
5  *
6  * Russell Bryant <russell@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 /*! 
20  * \file
21  *
22  * \brief Originate calls via the CLI
23  * 
24  */
25
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <string.h>
29
30 #include "asterisk.h"
31
32 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 1.1 $");
33
34 #include "asterisk/channel.h"
35 #include "asterisk/pbx.h"
36 #include "asterisk/logger.h"
37 #include "asterisk/module.h"
38 #include "asterisk/cli.h"
39 #include "asterisk/utils.h"
40 #include "asterisk/frame.h"
41
42 /*! The timeout for originated calls, in seconds */
43 #define TIMEOUT 30
44
45 STANDARD_USECOUNT_DECL;
46
47 static char *tdesc = "Call origination from the CLI";
48
49 static char orig_help[] = 
50 "  There are two ways to use this command. A call can be originated between a\n"
51 "channel and a specific application, or between a channel and an extension in\n"
52 "the dialplan. This is similar to call files or the manager originate action.\n"
53 "Calls originated with this command are given a timeout of 30 seconds.\n\n"
54
55 "Usage1: originate <tech/data> application <appname> [appdata]\n"
56 "  This will originate a call between the specified channel tech/data and the\n"
57 "given application. Arguments to the application are optional. If the given\n"
58 "arguments to the application include spaces, all of the arguments to the\n"
59 "application need to be placed in quotation marks.\n\n"
60
61 "Usage2: originate <tech/data> extension [exten@][context]\n"
62 "  This will originate a call between the specified channel tech/data and the\n"
63 "given extension. If no context is specified, the 'default' context will be\n"
64 "used. If no extension is given, the 's' extension will be used.\n";
65
66 static int handle_orig(int fd, int argc, char *argv[]);
67 static char *complete_orig(const char *line, const char *word, int pos, int state);
68
69 struct ast_cli_entry cli_orig = { { "originate", NULL }, handle_orig, "Originate a call", orig_help, complete_orig };
70
71 static int orig_app(const char *chan, const char *app, const char *appdata)
72 {
73         char *chantech;
74         char *chandata;
75         int reason = 0;
76         
77         if (ast_strlen_zero(app))
78                 return RESULT_SHOWUSAGE;
79
80         chandata = ast_strdupa(chan);
81         if (!chandata) {
82                 ast_log(LOG_ERROR, "Out of Memory!\n");
83                 return RESULT_FAILURE;
84         }
85         chantech = strsep(&chandata, "/");
86
87         ast_pbx_outgoing_app(chantech, AST_FORMAT_SLINEAR, chandata, TIMEOUT * 1000, app, appdata, &reason, 1, NULL, NULL, NULL, NULL);
88
89         return RESULT_SUCCESS;
90 }
91
92 static int orig_exten(const char *chan, const char *data)
93 {
94         char *chantech;
95         char *chandata;
96         char *exten = NULL;
97         char *context = NULL;
98         int reason = 0;
99
100         chandata = ast_strdupa(chan);
101         if (!chandata) {
102                 ast_log(LOG_ERROR, "Out of Memory!\n");
103                 return RESULT_FAILURE;
104         }
105         chantech = strsep(&chandata, "/");
106
107         if (!ast_strlen_zero(data)) {
108                 context = ast_strdupa(data);
109                 if (!context) {
110                         ast_log(LOG_ERROR, "Out of Memory!\n");
111                         return RESULT_FAILURE;
112                 }
113                 exten = strsep(&context, "@");
114         }
115
116         if (ast_strlen_zero(exten))
117                 exten = "s";
118         if (ast_strlen_zero(context))
119                 context = "default";
120         
121         ast_pbx_outgoing_exten(chantech, AST_FORMAT_SLINEAR, chandata, TIMEOUT * 1000, context, exten, 1, &reason, 1, NULL, NULL, NULL, NULL);
122
123         return RESULT_SUCCESS;
124 }
125
126 static int handle_orig(int fd, int argc, char *argv[])
127 {
128         int res;
129
130         if (ast_strlen_zero(argv[1]) || ast_strlen_zero(argv[2]))
131                 return RESULT_SHOWUSAGE;
132
133         STANDARD_INCREMENT_USECOUNT;
134
135         if (!strcasecmp("application", argv[2])) {
136                 res = orig_app(argv[1], argv[3], argv[4]);      
137         } else if (!strcasecmp("extension", argv[2])) {
138                 res = orig_exten(argv[1], argv[3]);
139         } else
140                 res = RESULT_SHOWUSAGE;
141
142         STANDARD_DECREMENT_USECOUNT;
143
144         return res;
145 }
146
147 static char *complete_orig(const char *line, const char *word, int pos, int state)
148 {
149         int wordlen;
150         char *app = "application";
151         char *exten = "extension";
152         char *ret = NULL;
153
154         if (pos != 2 || state)
155                 return NULL;
156
157         STANDARD_INCREMENT_USECOUNT;
158
159         wordlen = strlen(word);
160
161         if (ast_strlen_zero(word)) {
162                 /* show the options in alphabetical order */
163                 if (!state)
164                         ret = strdup(app);
165                 else
166                         ret = strdup(exten);
167         } else if (!strncasecmp(word, app, wordlen)) {
168                 ret = strdup(app);
169         } else if (!strncasecmp(word, exten, wordlen)) {
170                 ret = strdup(exten);
171         }
172
173         STANDARD_DECREMENT_USECOUNT;
174
175         return ret;
176 }
177
178 int unload_module(void)
179 {
180         return ast_cli_unregister(&cli_orig);
181 }
182
183 int load_module(void)
184 {
185         return ast_cli_register(&cli_orig);
186 }
187
188 char *description(void)
189 {
190         return tdesc;
191 }
192
193 int usecount(void)
194 {
195         return 0;
196 }
197
198 char *key()
199 {
200         return ASTERISK_GPL_KEY;
201 }
202