Asterisk.org: Developer Documentation (28 Oct 2009)

Wed Oct 28 15:47:49 2009

## Asterisk developer's documentation

# app_system.c

Go to the documentation of this file.

    00001 /*
    00002  * Asterisk -- An open source telephony toolkit.
    00003  *
    00004  * Copyright (C) 1999 - 2005, Digium, Inc.
    00005  *
    00006  * Mark Spencer <markster@digium.com>
    00007  *
    00008  * See http://www.asterisk.org for more information about
    00009  * the Asterisk project. Please do not directly contact
    00010  * any of the maintainers of this project for assistance;
    00011  * the project provides a web site, mailing lists and IRC
    00012  * channels for your use.
    00013  *
    00014  * This program is free software, distributed under the terms of
    00015  * the GNU General Public License Version 2. See the LICENSE file
    00016  * at the top of the source tree.
    00017  */
    00018
    00019 /*! \file
    00020  *
    00021  * \brief Execute arbitrary system commands
    00022  *
    00023  * \ingroup applications
    00024  */
    00025
    00026 #include <stdlib.h>
    00027 #include <stdio.h>
    00028 #include <unistd.h>
    00029 #include <string.h>
    00030 #include <errno.h>
    00031
    00032 #include "asterisk.h"
    00033
    00034 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 7221 $")
    00035
    00036 #include "asterisk/lock.h"
    00037 #include "asterisk/file.h"
    00038 #include "asterisk/logger.h"
    00039 #include "asterisk/channel.h"
    00040 #include "asterisk/pbx.h"
    00041 #include "asterisk/module.h"
    00042 #include "asterisk/app.h"
    00043 #include "asterisk/options.h"
    00044
    00045 static char *tdesc = "Generic System() application";
    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 STANDARD_LOCAL_USER;
    00085
    00086 LOCAL_USER_DECL;
    00087
    00088 static int system_exec_helper(struct ast_channel *chan, void *data, int failmode)
    00089 {
    00090    int res=0;
    00091    struct localuser *u;
    00092
    00093    if (ast_strlen_zero(data)) {
    00094       ast_log(LOG_WARNING, "System requires an argument(command)\n");
    00095       pbx_builtin_setvar_helper(chan, chanvar, "FAILURE");
    00096       return failmode;
    00097    }
    00098
    00099    LOCAL_USER_ADD(u);
    00100
    00101    /* Do our thing here */
    00102    res = ast_safe_system((char *)data);
    00103    if ((res < 0) && (errno != ECHILD)) {
    00104       ast_log(LOG_WARNING, "Unable to execute '%s'\n", (char *)data);
    00105       pbx_builtin_setvar_helper(chan, chanvar, "FAILURE");
    00106       res = failmode;
    00107    } else if (res == 127) {
    00108       ast_log(LOG_WARNING, "Unable to execute '%s'\n", (char *)data);
    00109       pbx_builtin_setvar_helper(chan, chanvar, "FAILURE");
    00110       res = failmode;
    00111    } else {
    00112       if (res < 0)
    00113          res = 0;
    00114       if (option_priority_jumping && res)
    00115          ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
    00116
    00117       if (res != 0)
    00118          pbx_builtin_setvar_helper(chan, chanvar, "APPERROR");
    00119       else
    00120          pbx_builtin_setvar_helper(chan, chanvar, "SUCCESS");
    00121       res = 0;
    00122    }
    00123
    00124    LOCAL_USER_REMOVE(u);
    00125
    00126    return res;
    00127 }
    00128
    00129 static int system_exec(struct ast_channel *chan, void *data)
    00130 {
    00131    return system_exec_helper(chan, data, -1);
    00132 }
    00133
    00134 static int trysystem_exec(struct ast_channel *chan, void *data)
    00135 {
    00136    return system_exec_helper(chan, data, 0);
    00137 }
    00138
    00139 int unload_module(void)
    00140 {
    00141    int res;
    00142
    00143    res = ast_unregister_application(app);
    00144    res |= ast_unregister_application(app2);
    00145
    00146    STANDARD_HANGUP_LOCALUSERS;
    00147
    00148    return res;
    00149 }
    00150
    00151 int load_module(void)
    00152 {
    00153    int res;
    00154
    00155    res = ast_register_application(app2, trysystem_exec, synopsis2, descrip2);
    00156    res |= ast_register_application(app, system_exec, synopsis, descrip);
    00157
    00158    return res;
    00159 }
    00160
    00161 char *description(void)
    00162 {
    00163    return tdesc;
    00164 }
    00165
    00166 int usecount(void)
    00167 {
    00168    int res;
    00169    STANDARD_USECOUNT(res);
    00170    return res;
    00171 }
    00172
    00173 char *key()
    00174 {
    00175    return ASTERISK_GPL_KEY;
    00176 }