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
00029 #include "asterisk.h"
00030
00031 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 120905 $")
00032
00033 #include "asterisk/file.h"
00034 #include "asterisk/channel.h"
00035 #include "asterisk/pbx.h"
00036 #include "asterisk/module.h"
00037 #include "asterisk/app.h"
00038
00039
00040 #define MAXRESULT 1024
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 static char *app_exec = "Exec";
00055 static char *exec_synopsis = "Executes dialplan application";
00056 static char *exec_descrip =
00057 " Exec(appname(arguments)):\n"
00058 "Allows an arbitrary application to be invoked even when not\n"
00059 "hardcoded into the dialplan. If the underlying application\n"
00060 "terminates the dialplan, or if the application cannot be found,\n"
00061 "Exec will terminate the dialplan.\n"
00062 " To invoke external applications, see the application System.\n"
00063 " If you would like to catch any error instead, see TryExec.\n";
00064
00065 static char *app_tryexec = "TryExec";
00066 static char *tryexec_synopsis = "Executes dialplan application, always returning";
00067 static char *tryexec_descrip =
00068 " TryExec(appname(arguments)):\n"
00069 "Allows an arbitrary application to be invoked even when not\n"
00070 "hardcoded into the dialplan. To invoke external applications\n"
00071 "see the application System. Always returns to the dialplan.\n"
00072 "The channel variable TRYSTATUS will be set to one of:\n"
00073 " SUCCESS if the application returned zero\n"
00074 " FAILED if the application returned non-zero\n"
00075 " NOAPP if the application was not found or was not specified\n";
00076
00077 static char *app_execif = "ExecIf";
00078 static char *execif_synopsis = "Executes dialplan application, conditionally";
00079 static char *execif_descrip =
00080 " ExecIF (<expr>?<appiftrue>(<args>)[:<appiffalse>(<args>)])\n"
00081 "If <expr> is true, execute and return the result of <appiftrue>(<args>).\n"
00082 "If <expr> is true, but <appiftrue> is not found, then the application\n"
00083 "will return a non-zero value.\n";
00084
00085 static int exec_exec(struct ast_channel *chan, void *data)
00086 {
00087 int res = 0;
00088 char *s, *appname, *endargs, args[MAXRESULT];
00089 struct ast_app *app;
00090
00091 if (ast_strlen_zero(data))
00092 return 0;
00093
00094 s = ast_strdupa(data);
00095 args[0] = 0;
00096 appname = strsep(&s, "(");
00097 if (s) {
00098 endargs = strrchr(s, ')');
00099 if (endargs)
00100 *endargs = '\0';
00101 pbx_substitute_variables_helper(chan, s, args, MAXRESULT - 1);
00102 }
00103 if (appname) {
00104 app = pbx_findapp(appname);
00105 if (app) {
00106 res = pbx_exec(chan, app, args);
00107 } else {
00108 ast_log(LOG_WARNING, "Could not find application (%s)\n", appname);
00109 res = -1;
00110 }
00111 }
00112
00113 return res;
00114 }
00115
00116 static int tryexec_exec(struct ast_channel *chan, void *data)
00117 {
00118 int res = 0;
00119 char *s, *appname, *endargs, args[MAXRESULT];
00120 struct ast_app *app;
00121
00122 if (ast_strlen_zero(data))
00123 return 0;
00124
00125 s = ast_strdupa(data);
00126 args[0] = 0;
00127 appname = strsep(&s, "(");
00128 if (s) {
00129 endargs = strrchr(s, ')');
00130 if (endargs)
00131 *endargs = '\0';
00132 pbx_substitute_variables_helper(chan, s, args, MAXRESULT - 1);
00133 }
00134 if (appname) {
00135 app = pbx_findapp(appname);
00136 if (app) {
00137 res = pbx_exec(chan, app, args);
00138 pbx_builtin_setvar_helper(chan, "TRYSTATUS", res ? "FAILED" : "SUCCESS");
00139 } else {
00140 ast_log(LOG_WARNING, "Could not find application (%s)\n", appname);
00141 pbx_builtin_setvar_helper(chan, "TRYSTATUS", "NOAPP");
00142 }
00143 }
00144
00145 return 0;
00146 }
00147
00148 static int execif_exec(struct ast_channel *chan, void *data)
00149 {
00150 int res = 0;
00151 char *truedata = NULL, *falsedata = NULL, *end, *firstcomma, *firstquestion;
00152 struct ast_app *app = NULL;
00153 AST_DECLARE_APP_ARGS(expr,
00154 AST_APP_ARG(expr);
00155 AST_APP_ARG(remainder);
00156 );
00157 AST_DECLARE_APP_ARGS(apps,
00158 AST_APP_ARG(t);
00159 AST_APP_ARG(f);
00160 );
00161 char *parse = ast_strdupa(data);
00162
00163 firstcomma = strchr(parse, ',');
00164 firstquestion = strchr(parse, '?');
00165
00166 if ((firstcomma != NULL && firstquestion != NULL && firstcomma < firstquestion) || (firstquestion == NULL)) {
00167
00168 AST_DECLARE_APP_ARGS(depr,
00169 AST_APP_ARG(expr);
00170 AST_APP_ARG(appname);
00171 AST_APP_ARG(appargs);
00172 );
00173 AST_STANDARD_APP_ARGS(depr, parse);
00174
00175 ast_log(LOG_WARNING, "Deprecated syntax found. Please upgrade to using ExecIf(<expr>?%s(%s))\n", depr.appname, depr.appargs);
00176
00177
00178 expr.expr = depr.expr;
00179 apps.t = depr.appname;
00180 apps.f = NULL;
00181 truedata = depr.appargs;
00182 } else {
00183
00184
00185 AST_NONSTANDARD_APP_ARGS(expr, parse, '?');
00186 if (ast_strlen_zero(expr.remainder)) {
00187 ast_log(LOG_ERROR, "Usage: ExecIf(<expr>?<appiftrue>(<args>)[:<appiffalse>(<args)])\n");
00188 return -1;
00189 }
00190
00191 AST_NONSTANDARD_APP_ARGS(apps, expr.remainder, ':');
00192
00193 if (apps.t && (truedata = strchr(apps.t, '('))) {
00194 *truedata++ = '\0';
00195 if ((end = strrchr(truedata, ')'))) {
00196 *end = '\0';
00197 }
00198 }
00199
00200 if (apps.f && (falsedata = strchr(apps.f, '('))) {
00201 *falsedata++ = '\0';
00202 if ((end = strrchr(falsedata, ')'))) {
00203 *end = '\0';
00204 }
00205 }
00206 }
00207
00208 if (pbx_checkcondition(expr.expr)) {
00209 if (!ast_strlen_zero(apps.t) && (app = pbx_findapp(apps.t))) {
00210 res = pbx_exec(chan, app, S_OR(truedata, ""));
00211 } else {
00212 ast_log(LOG_WARNING, "Could not find application! (%s)\n", apps.t);
00213 res = -1;
00214 }
00215 } else if (!ast_strlen_zero(apps.f)) {
00216 if ((app = pbx_findapp(apps.f))) {
00217 res = pbx_exec(chan, app, S_OR(falsedata, ""));
00218 } else {
00219 ast_log(LOG_WARNING, "Could not find application! (%s)\n", apps.f);
00220 res = -1;
00221 }
00222 }
00223
00224 return res;
00225 }
00226
00227 static int unload_module(void)
00228 {
00229 int res;
00230
00231 res = ast_unregister_application(app_exec);
00232 res |= ast_unregister_application(app_tryexec);
00233 res |= ast_unregister_application(app_execif);
00234
00235 return res;
00236 }
00237
00238 static int load_module(void)
00239 {
00240 int res = ast_register_application(app_exec, exec_exec, exec_synopsis, exec_descrip);
00241 res |= ast_register_application(app_tryexec, tryexec_exec, tryexec_synopsis, tryexec_descrip);
00242 res |= ast_register_application(app_execif, execif_exec, execif_synopsis, execif_descrip);
00243 return res;
00244 }
00245
00246 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Executes dialplan applications");