Asterisk - The Open Source Telephony Project GIT-master-a358458
app_system.c
Go to the documentation of this file.
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 Execute arbitrary system commands
22 *
23 * \author Mark Spencer <markster@digium.com>
24 *
25 * \ingroup applications
26 */
27
28/*** MODULEINFO
29 <support_level>core</support_level>
30 ***/
31
32#include "asterisk.h"
33
34#include "asterisk/pbx.h"
35#include "asterisk/module.h"
36#include "asterisk/app.h"
37#include "asterisk/channel.h" /* autoservice */
38#include "asterisk/strings.h"
40
41/*** DOCUMENTATION
42 <application name="System" language="en_US">
43 <synopsis>
44 Execute a system command.
45 </synopsis>
46 <syntax>
47 <parameter name="command" required="true">
48 <para>Command to execute</para>
49 <warning><para>Do not use untrusted strings such as <variable>CALLERID(num)</variable>
50 or <variable>CALLERID(name)</variable> as part of the command parameters. You
51 risk a command injection attack executing arbitrary commands if the untrusted
52 strings aren't filtered to remove dangerous characters. See function
53 <variable>FILTER()</variable>.</para></warning>
54 </parameter>
55 </syntax>
56 <description>
57 <para>Executes a command by using system(). If the command
58 fails, the console should report a fallthrough.</para>
59 <para>Result of execution is returned in the <variable>SYSTEMSTATUS</variable> channel variable:</para>
60 <variablelist>
61 <variable name="SYSTEMSTATUS">
62 <value name="FAILURE">
63 Could not execute the specified command.
64 </value>
65 <value name="SUCCESS">
66 Specified command successfully executed.
67 </value>
68 </variable>
69 </variablelist>
70 </description>
71 </application>
72 <application name="TrySystem" language="en_US">
73 <synopsis>
74 Try executing a system command.
75 </synopsis>
76 <syntax>
77 <parameter name="command" required="true">
78 <para>Command to execute</para>
79 <warning><para>Do not use untrusted strings such as <variable>CALLERID(num)</variable>
80 or <variable>CALLERID(name)</variable> as part of the command parameters. You
81 risk a command injection attack executing arbitrary commands if the untrusted
82 strings aren't filtered to remove dangerous characters. See function
83 <variable>FILTER()</variable>.</para></warning>
84 </parameter>
85 </syntax>
86 <description>
87 <para>Executes a command by using system().</para>
88 <para>Result of execution is returned in the <variable>SYSTEMSTATUS</variable> channel variable:</para>
89 <variablelist>
90 <variable name="SYSTEMSTATUS">
91 <value name="FAILURE">
92 Could not execute the specified command.
93 </value>
94 <value name="SUCCESS">
95 Specified command successfully executed.
96 </value>
97 <value name="APPERROR">
98 Specified command successfully executed, but returned error code.
99 </value>
100 </variable>
101 </variablelist>
102 </description>
103 </application>
104
105 ***/
106
108
109static char *app = "System";
110
111static char *app2 = "TrySystem";
112
113static char *chanvar = "SYSTEMSTATUS";
114
115static int system_exec_helper(struct ast_channel *chan, const char *data, int failmode)
116{
117 int res = 0;
118 struct ast_str *buf = ast_str_thread_get(&buf_buf, 16);
119 char *cbuf;
120
121 if (ast_strlen_zero(data)) {
122 ast_log(LOG_WARNING, "System requires an argument(command)\n");
123 pbx_builtin_setvar_helper(chan, chanvar, "FAILURE");
124 return failmode;
125 }
126
128
129 /* Do our thing here */
130 ast_str_get_encoded_str(&buf, 0, (char *) data);
131 cbuf = ast_str_buffer(buf);
132
133 if (strchr("\"'", cbuf[0]) && cbuf[ast_str_strlen(buf) - 1] == cbuf[0]) {
134 cbuf[ast_str_strlen(buf) - 1] = '\0';
135 cbuf++;
136 ast_log(LOG_NOTICE, "It is not necessary to quote the argument to the System application.\n");
137 }
138
139 res = ast_safe_system(cbuf);
140
141 if ((res < 0) && (errno != ECHILD)) {
142 ast_log(LOG_WARNING, "Unable to execute '%s'\n", (char *)data);
143 pbx_builtin_setvar_helper(chan, chanvar, "FAILURE");
144 res = failmode;
145 } else if (res == 127) {
146 ast_log(LOG_WARNING, "Unable to execute '%s'\n", (char *)data);
147 pbx_builtin_setvar_helper(chan, chanvar, "FAILURE");
148 res = failmode;
149 } else {
150 if (res < 0)
151 res = 0;
152 if (res != 0)
153 pbx_builtin_setvar_helper(chan, chanvar, "APPERROR");
154 else
155 pbx_builtin_setvar_helper(chan, chanvar, "SUCCESS");
156 res = 0;
157 }
158
160
161 return res;
162}
163
164static int system_exec(struct ast_channel *chan, const char *data)
165{
166 return system_exec_helper(chan, data, -1);
167}
168
169static int trysystem_exec(struct ast_channel *chan, const char *data)
170{
171 return system_exec_helper(chan, data, 0);
172}
173
174static int unload_module(void)
175{
176 int res;
177
180
181 return res;
182}
183
184static int load_module(void)
185{
186 int res;
187
190
191 return res;
192}
193
194AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Generic System() application");
static int system_exec(struct ast_channel *chan, const char *data)
Definition: app_system.c:164
static char * app2
Definition: app_system.c:111
static struct ast_threadstorage buf_buf
Definition: app_system.c:107
static char * app
Definition: app_system.c:109
static int load_module(void)
Definition: app_system.c:184
static int trysystem_exec(struct ast_channel *chan, const char *data)
Definition: app_system.c:169
static int unload_module(void)
Definition: app_system.c:174
static int system_exec_helper(struct ast_channel *chan, const char *data, int failmode)
Definition: app_system.c:115
Asterisk main include file. File version handling, generic pbx functions.
#define ast_log
Definition: astobj2.c:42
General Asterisk PBX channel definitions.
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
Definition: autoservice.c:266
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
Definition: autoservice.c:200
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
Application convenience functions, designed to give consistent look and feel to Asterisk apps.
int ast_str_get_encoded_str(struct ast_str **str, int maxlen, const char *stream)
Decode a stream of encoded control or extended ASCII characters.
Definition: main/app.c:3165
int ast_safe_system(const char *s)
Safely spawn an OS shell command while closing file descriptors.
Definition: extconf.c:829
#define LOG_NOTICE
#define LOG_WARNING
int errno
Asterisk module definitions.
#define AST_MODULE_INFO_STANDARD(keystr, desc)
Definition: module.h:567
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:626
Core PBX routines and definitions.
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name.
String manipulation functions.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:730
struct ast_str * ast_str_thread_get(struct ast_threadstorage *ts, size_t init_len)
Retrieve a thread locally stored dynamic string.
Definition: strings.h:909
Main Channel structure associated with a channel.
Support for dynamic strings.
Definition: strings.h:623
structure for queuing ARI channel variable setting
Definition: control.c:705
Definitions to aid in the use of thread local storage.
#define AST_THREADSTORAGE(name)
Define a thread storage variable.
Definition: threadstorage.h:86