Sat Aug 6 00:39:20 2011

Asterisk developer's documentation


app_exec.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (c) 2004 - 2005, Tilghman Lesher.  All rights reserved.
00005  * Portions copyright (c) 2006, Philipp Dunkel.
00006  *
00007  * Tilghman Lesher <app_exec__v002@the-tilghman.com>
00008  *
00009  * This code is released by the author with no restrictions on usage.
00010  *
00011  * See http://www.asterisk.org for more information about
00012  * the Asterisk project. Please do not directly contact
00013  * any of the maintainers of this project for assistance;
00014  * the project provides a web site, mailing lists and IRC
00015  * channels for your use.
00016  *
00017  */
00018 
00019 /*! \file
00020  *
00021  * \brief Exec application
00022  *
00023  * \author Tilghman Lesher <app_exec__v002@the-tilghman.com>
00024  * \author Philipp Dunkel <philipp.dunkel@ebox.at>
00025  *
00026  * \ingroup applications
00027  */
00028 
00029 #include "asterisk.h"
00030 
00031 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 107582 $")
00032 
00033 #include <stdio.h>
00034 #include <stdlib.h>
00035 #include <unistd.h>
00036 #include <string.h>
00037 
00038 #include "asterisk/file.h"
00039 #include "asterisk/logger.h"
00040 #include "asterisk/options.h"
00041 #include "asterisk/channel.h"
00042 #include "asterisk/pbx.h"
00043 #include "asterisk/module.h"
00044 
00045 /* Maximum length of any variable */
00046 #define MAXRESULT 1024
00047 
00048 /*! Note
00049  *
00050  * The key difference between these two apps is exit status.  In a
00051  * nutshell, Exec tries to be transparent as possible, behaving
00052  * in exactly the same way as if the application it calls was
00053  * directly invoked from the dialplan.
00054  *
00055  * TryExec, on the other hand, provides a way to execute applications
00056  * and catch any possible fatal error without actually fatally
00057  * affecting the dialplan.
00058  */
00059 
00060 static char *app_exec = "Exec";
00061 static char *exec_synopsis = "Executes dialplan application";
00062 static char *exec_descrip =
00063 "Usage: Exec(appname(arguments))\n"
00064 "  Allows an arbitrary application to be invoked even when not\n"
00065 "hardcoded into the dialplan.  If the underlying application\n"
00066 "terminates the dialplan, or if the application cannot be found,\n"
00067 "Exec will terminate the dialplan.\n"
00068 "  To invoke external applications, see the application System.\n"
00069 "  If you would like to catch any error instead, see TryExec.\n";
00070 
00071 static char *app_tryexec = "TryExec";
00072 static char *tryexec_synopsis = "Executes dialplan application, always returning";
00073 static char *tryexec_descrip =
00074 "Usage: TryExec(appname(arguments))\n"
00075 "  Allows an arbitrary application to be invoked even when not\n"
00076 "hardcoded into the dialplan. To invoke external applications\n"
00077 "see the application System.  Always returns to the dialplan.\n"
00078 "The channel variable TRYSTATUS will be set to:\n"
00079 "    SUCCESS   if the application returned zero\n"
00080 "    FAILED    if the application returned non-zero\n"
00081 "    NOAPP     if the application was not found or was not specified\n";
00082 
00083 static char *app_execif = "ExecIf";
00084 static char *execif_synopsis = "Executes dialplan application, conditionally";
00085 static char *execif_descrip = 
00086 "Usage:  ExecIF (<expr>|<app>|<data>)\n"
00087 "If <expr> is true, execute and return the result of <app>(<data>).\n"
00088 "If <expr> is true, but <app> is not found, then the application\n"
00089 "will return a non-zero value.\n";
00090 
00091 static int exec_exec(struct ast_channel *chan, void *data)
00092 {
00093    int res=0;
00094    struct ast_module_user *u;
00095    char *s, *appname, *endargs, args[MAXRESULT] = "";
00096    struct ast_app *app;
00097 
00098    u = ast_module_user_add(chan);
00099 
00100    /* Check and parse arguments */
00101    if (data) {
00102       s = ast_strdupa(data);
00103       appname = strsep(&s, "(");
00104       if (s) {
00105          endargs = strrchr(s, ')');
00106          if (endargs)
00107             *endargs = '\0';
00108          pbx_substitute_variables_helper(chan, s, args, MAXRESULT - 1);
00109       }
00110       if (appname) {
00111          app = pbx_findapp(appname);
00112          if (app) {
00113             res = pbx_exec(chan, app, args);
00114          } else {
00115             ast_log(LOG_WARNING, "Could not find application (%s)\n", appname);
00116             res = -1;
00117          }
00118       }
00119    }
00120 
00121    ast_module_user_remove(u);
00122    return res;
00123 }
00124 
00125 static int tryexec_exec(struct ast_channel *chan, void *data)
00126 {
00127    int res=0;
00128    struct ast_module_user *u;
00129    char *s, *appname, *endargs, args[MAXRESULT] = "";
00130    struct ast_app *app;
00131 
00132    u = ast_module_user_add(chan);
00133 
00134    /* Check and parse arguments */
00135    if (data) {
00136       s = ast_strdupa(data);
00137       appname = strsep(&s, "(");
00138       if (s) {
00139          endargs = strrchr(s, ')');
00140          if (endargs)
00141             *endargs = '\0';
00142          pbx_substitute_variables_helper(chan, s, args, MAXRESULT - 1);
00143       }
00144       if (appname) {
00145          app = pbx_findapp(appname);
00146          if (app) {
00147             res = pbx_exec(chan, app, args);
00148             pbx_builtin_setvar_helper(chan, "TRYSTATUS", res ? "FAILED" : "SUCCESS");
00149          } else {
00150             ast_log(LOG_WARNING, "Could not find application (%s)\n", appname);
00151             pbx_builtin_setvar_helper(chan, "TRYSTATUS", "NOAPP");
00152          }
00153       }
00154    }
00155 
00156    ast_module_user_remove(u);
00157    return 0;
00158 }
00159 
00160 static int execif_exec(struct ast_channel *chan, void *data)
00161 {
00162    int res = 0;
00163    struct ast_module_user *u;
00164    char *myapp = NULL;
00165    char *mydata = NULL;
00166    char *expr = NULL;
00167    struct ast_app *app = NULL;
00168 
00169    u = ast_module_user_add(chan);
00170 
00171    expr = ast_strdupa(data);
00172 
00173    if ((myapp = strchr(expr,'|'))) {
00174       *myapp = '\0';
00175       myapp++;
00176       if ((mydata = strchr(myapp,'|'))) {
00177          *mydata = '\0';
00178          mydata++;
00179       } else
00180          mydata = "";
00181 
00182       if (pbx_checkcondition(expr)) { 
00183          if ((app = pbx_findapp(myapp))) {
00184             res = pbx_exec(chan, app, mydata);
00185          } else {
00186             ast_log(LOG_WARNING, "Could not find application! (%s)\n", myapp);
00187             res = -1;
00188          }
00189       }
00190    } else {
00191       ast_log(LOG_ERROR,"Invalid Syntax.\n");
00192       res = -1;
00193    }
00194       
00195    ast_module_user_remove(u);
00196 
00197    return res;
00198 }
00199 
00200 static int unload_module(void)
00201 {
00202    int res;
00203 
00204    res = ast_unregister_application(app_exec);
00205    res |= ast_unregister_application(app_tryexec);
00206    res |= ast_unregister_application(app_execif);
00207 
00208    ast_module_user_hangup_all();
00209 
00210    return res;
00211 }
00212 
00213 static int load_module(void)
00214 {
00215    int res = ast_register_application(app_exec, exec_exec, exec_synopsis, exec_descrip);
00216    res |= ast_register_application(app_tryexec, tryexec_exec, tryexec_synopsis, tryexec_descrip);
00217    res |= ast_register_application(app_execif, execif_exec, execif_synopsis, execif_descrip);
00218    return res;
00219 }
00220 
00221 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Executes dialplan applications");

Generated on Sat Aug 6 00:39:20 2011 for Asterisk - the Open Source PBX by  doxygen 1.4.7