Wed Jan 8 2020 09:49:40

Asterisk developer's documentation


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 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 340863 $")
35 
36 #include "asterisk/pbx.h"
37 #include "asterisk/module.h"
38 #include "asterisk/app.h"
39 #include "asterisk/channel.h" /* autoservice */
40 #include "asterisk/strings.h"
41 #include "asterisk/threadstorage.h"
42 
43 /*** DOCUMENTATION
44  <application name="System" language="en_US">
45  <synopsis>
46  Execute a system command.
47  </synopsis>
48  <syntax>
49  <parameter name="command" required="true">
50  <para>Command to execute</para>
51  </parameter>
52  </syntax>
53  <description>
54  <para>Executes a command by using system(). If the command
55  fails, the console should report a fallthrough.</para>
56  <para>Result of execution is returned in the <variable>SYSTEMSTATUS</variable> channel variable:</para>
57  <variablelist>
58  <variable name="SYSTEMSTATUS">
59  <value name="FAILURE">
60  Could not execute the specified command.
61  </value>
62  <value name="SUCCESS">
63  Specified command successfully executed.
64  </value>
65  </variable>
66  </variablelist>
67  </description>
68  </application>
69  <application name="TrySystem" language="en_US">
70  <synopsis>
71  Try executing a system command.
72  </synopsis>
73  <syntax>
74  <parameter name="command" required="true">
75  <para>Command to execute</para>
76  </parameter>
77  </syntax>
78  <description>
79  <para>Executes a command by using system().</para>
80  <para>Result of execution is returned in the <variable>SYSTEMSTATUS</variable> channel variable:</para>
81  <variablelist>
82  <variable name="SYSTEMSTATUS">
83  <value name="FAILURE">
84  Could not execute the specified command.
85  </value>
86  <value name="SUCCESS">
87  Specified command successfully executed.
88  </value>
89  <value name="APPERROR">
90  Specified command successfully executed, but returned error code.
91  </value>
92  </variable>
93  </variablelist>
94  </description>
95  </application>
96 
97  ***/
98 
100 
101 static char *app = "System";
102 
103 static char *app2 = "TrySystem";
104 
105 static char *chanvar = "SYSTEMSTATUS";
106 
107 static int system_exec_helper(struct ast_channel *chan, const char *data, int failmode)
108 {
109  int res = 0;
110  struct ast_str *buf = ast_str_thread_get(&buf_buf, 16);
111  char *cbuf;
112 
113  if (ast_strlen_zero(data)) {
114  ast_log(LOG_WARNING, "System requires an argument(command)\n");
115  pbx_builtin_setvar_helper(chan, chanvar, "FAILURE");
116  return failmode;
117  }
118 
119  ast_autoservice_start(chan);
120 
121  /* Do our thing here */
122  ast_str_get_encoded_str(&buf, 0, (char *) data);
123  cbuf = ast_str_buffer(buf);
124 
125  if (strchr("\"'", cbuf[0]) && cbuf[ast_str_strlen(buf) - 1] == cbuf[0]) {
126  cbuf[ast_str_strlen(buf) - 1] = '\0';
127  cbuf++;
128  ast_log(LOG_NOTICE, "It is not necessary to quote the argument to the System application.\n");
129  }
130 
131  res = ast_safe_system(cbuf);
132 
133  if ((res < 0) && (errno != ECHILD)) {
134  ast_log(LOG_WARNING, "Unable to execute '%s'\n", (char *)data);
135  pbx_builtin_setvar_helper(chan, chanvar, "FAILURE");
136  res = failmode;
137  } else if (res == 127) {
138  ast_log(LOG_WARNING, "Unable to execute '%s'\n", (char *)data);
139  pbx_builtin_setvar_helper(chan, chanvar, "FAILURE");
140  res = failmode;
141  } else {
142  if (res < 0)
143  res = 0;
144  if (res != 0)
145  pbx_builtin_setvar_helper(chan, chanvar, "APPERROR");
146  else
147  pbx_builtin_setvar_helper(chan, chanvar, "SUCCESS");
148  res = 0;
149  }
150 
151  ast_autoservice_stop(chan);
152 
153  return res;
154 }
155 
156 static int system_exec(struct ast_channel *chan, const char *data)
157 {
158  return system_exec_helper(chan, data, -1);
159 }
160 
161 static int trysystem_exec(struct ast_channel *chan, const char *data)
162 {
163  return system_exec_helper(chan, data, 0);
164 }
165 
166 static int unload_module(void)
167 {
168  int res;
169 
170  res = ast_unregister_application(app);
171  res |= ast_unregister_application(app2);
172 
173  return res;
174 }
175 
176 static int load_module(void)
177 {
178  int res;
179 
182 
183  return res;
184 }
185 
186 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Generic System() application");
#define AST_THREADSTORAGE(name)
Define a thread storage variable.
Definition: threadstorage.h:81
Main Channel structure associated with a channel.
Definition: channel.h:742
#define AST_MODULE_INFO_STANDARD(keystr, desc)
Definition: module.h:396
int ast_safe_system(const char *s)
Safely spawn an external program while closing file descriptors.
Definition: asterisk.c:1077
Asterisk main include file. File version handling, generic pbx functions.
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
Definition: autoservice.c:179
String manipulation functions.
#define LOG_WARNING
Definition: logger.h:144
static int load_module(void)
Definition: app_system.c:176
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
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: app.c:2210
static int unload_module(void)
Definition: app_system.c:166
static int system_exec_helper(struct ast_channel *chan, const char *data, int failmode)
Definition: app_system.c:107
Definitions to aid in the use of thread local storage.
static char * chanvar
Definition: app_system.c:105
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx.c:7705
General Asterisk PBX channel definitions.
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
Definition: autoservice.c:238
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
static int system_exec(struct ast_channel *chan, const char *data)
Definition: app_system.c:156
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
int errno
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...
Definition: pbx.c:10546
static char * app
Definition: app_system.c:101
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:471
static int trysystem_exec(struct ast_channel *chan, const char *data)
Definition: app_system.c:161
static struct ast_threadstorage buf_buf
Definition: app_system.c:99
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
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:669
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:38
Asterisk module definitions.
static char * app2
Definition: app_system.c:103
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:437
#define ASTERISK_FILE_VERSION(file, version)
Register/unregister a source code file with the core.
Definition: asterisk.h:180