00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "asterisk.h"
00029
00030 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 83179 $")
00031
00032 #include <stdlib.h>
00033 #include <stdio.h>
00034 #include <unistd.h>
00035 #include <string.h>
00036 #include <errno.h>
00037
00038 #include "asterisk/lock.h"
00039 #include "asterisk/file.h"
00040 #include "asterisk/logger.h"
00041 #include "asterisk/channel.h"
00042 #include "asterisk/pbx.h"
00043 #include "asterisk/module.h"
00044 #include "asterisk/app.h"
00045 #include "asterisk/options.h"
00046
00047 static char *app = "System";
00048
00049 static char *app2 = "TrySystem";
00050
00051 static char *synopsis = "Execute a system command";
00052
00053 static char *synopsis2 = "Try executing a system command";
00054
00055 static char *chanvar = "SYSTEMSTATUS";
00056
00057 static char *descrip =
00058 " System(command): Executes a command by using system(). If the command\n"
00059 "fails, the console should report a fallthrough. \n"
00060 "Result of execution is returned in the SYSTEMSTATUS channel variable:\n"
00061 " FAILURE Could not execute the specified command\n"
00062 " SUCCESS Specified command successfully executed\n"
00063 "\n"
00064 "Old behaviour:\n"
00065 "If the command itself executes but is in error, and if there exists\n"
00066 "a priority n + 101, where 'n' is the priority of the current instance,\n"
00067 "then the channel will be setup to continue at that priority level.\n"
00068 "Note that this jump functionality has been deprecated and will only occur\n"
00069 "if the global priority jumping option is enabled in extensions.conf.\n";
00070
00071 static char *descrip2 =
00072 " TrySystem(command): Executes a command by using system().\n"
00073 "on any situation.\n"
00074 "Result of execution is returned in the SYSTEMSTATUS channel variable:\n"
00075 " FAILURE Could not execute the specified command\n"
00076 " SUCCESS Specified command successfully executed\n"
00077 " APPERROR Specified command successfully executed, but returned error code\n"
00078 "\n"
00079 "Old behaviour:\nIf the command itself executes but is in error, and if\n"
00080 "there exists a priority n + 101, where 'n' is the priority of the current\n"
00081 "instance, then the channel will be setup to continue at that\n"
00082 "priority level. Otherwise, System will terminate.\n";
00083
00084
00085 static int system_exec_helper(struct ast_channel *chan, void *data, int failmode)
00086 {
00087 int res=0;
00088 struct ast_module_user *u;
00089
00090 if (ast_strlen_zero(data)) {
00091 ast_log(LOG_WARNING, "System requires an argument(command)\n");
00092 pbx_builtin_setvar_helper(chan, chanvar, "FAILURE");
00093 return failmode;
00094 }
00095
00096 u = ast_module_user_add(chan);
00097
00098 ast_autoservice_start(chan);
00099
00100
00101 res = ast_safe_system((char *)data);
00102 if ((res < 0) && (errno != ECHILD)) {
00103 ast_log(LOG_WARNING, "Unable to execute '%s'\n", (char *)data);
00104 pbx_builtin_setvar_helper(chan, chanvar, "FAILURE");
00105 res = failmode;
00106 } else if (res == 127) {
00107 ast_log(LOG_WARNING, "Unable to execute '%s'\n", (char *)data);
00108 pbx_builtin_setvar_helper(chan, chanvar, "FAILURE");
00109 res = failmode;
00110 } else {
00111 if (res < 0)
00112 res = 0;
00113 if (ast_opt_priority_jumping && res)
00114 ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
00115
00116 if (res != 0)
00117 pbx_builtin_setvar_helper(chan, chanvar, "APPERROR");
00118 else
00119 pbx_builtin_setvar_helper(chan, chanvar, "SUCCESS");
00120 res = 0;
00121 }
00122
00123 ast_autoservice_stop(chan);
00124
00125 ast_module_user_remove(u);
00126
00127 return res;
00128 }
00129
00130 static int system_exec(struct ast_channel *chan, void *data)
00131 {
00132 return system_exec_helper(chan, data, -1);
00133 }
00134
00135 static int trysystem_exec(struct ast_channel *chan, void *data)
00136 {
00137 return system_exec_helper(chan, data, 0);
00138 }
00139
00140 static int unload_module(void)
00141 {
00142 int res;
00143
00144 res = ast_unregister_application(app);
00145 res |= ast_unregister_application(app2);
00146
00147 ast_module_user_hangup_all();
00148
00149 return res;
00150 }
00151
00152 static int load_module(void)
00153 {
00154 int res;
00155
00156 res = ast_register_application(app2, trysystem_exec, synopsis2, descrip2);
00157 res |= ast_register_application(app, system_exec, synopsis, descrip);
00158
00159 return res;
00160 }
00161
00162 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Generic System() application");