#include "asterisk.h"
#include <sys/types.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <math.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <sys/time.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/wait.h>
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/astdb.h"
#include "asterisk/callerid.h"
#include "asterisk/cli.h"
#include "asterisk/options.h"
#include "asterisk/image.h"
#include "asterisk/say.h"
#include "asterisk/app.h"
#include "asterisk/dsp.h"
#include "asterisk/musiconhold.h"
#include "asterisk/utils.h"
#include "asterisk/lock.h"
#include "asterisk/strings.h"
#include "asterisk/agi.h"
Go to the source code of this file.
Defines | |
#define | AGI_PORT 4573 |
#define | fdprintf agi_debug_cli |
#define | MAX_AGI_CONNECT 2000 |
#define | MAX_ARGS 128 |
#define | MAX_COMMANDS 128 |
#define | RETRY 3 |
#define | TONE_BLOCK_SIZE 200 |
Enumerations | |
enum | agi_result { AGI_RESULT_SUCCESS, AGI_RESULT_FAILURE, AGI_RESULT_HANGUP } |
Functions | |
static int | agi_debug_cli (int fd, char *fmt,...) |
static int | agi_do_debug (int fd, int argc, char *argv[]) |
static int | agi_exec (struct ast_channel *chan, void *data) |
static int | agi_exec_full (struct ast_channel *chan, void *data, int enhanced, int dead) |
static int | agi_handle_command (struct ast_channel *chan, AGI *agi, char *buf) |
static int | agi_no_debug (int fd, int argc, char *argv[]) |
static int | agi_no_debug_deprecated (int fd, int argc, char *argv[]) |
int | ast_agi_register (agi_command *agi) |
void | ast_agi_unregister (agi_command *agi) |
AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS,"Asterisk Gateway Interface (AGI)",.load=load_module,.unload=unload_module,) | |
static int | deadagi_exec (struct ast_channel *chan, void *data) |
static int | eagi_exec (struct ast_channel *chan, void *data) |
static agi_command * | find_command (char *cmds[], int exact) |
static int | handle_agidumphtml (int fd, int argc, char *argv[]) |
static int | handle_answer (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
static int | handle_autohangup (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
static int | handle_channelstatus (struct ast_channel *chan, AGI *agi, int argc, char **argv) |
static int | handle_controlstreamfile (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
static int | handle_dbdel (struct ast_channel *chan, AGI *agi, int argc, char **argv) |
static int | handle_dbdeltree (struct ast_channel *chan, AGI *agi, int argc, char **argv) |
static int | handle_dbget (struct ast_channel *chan, AGI *agi, int argc, char **argv) |
static int | handle_dbput (struct ast_channel *chan, AGI *agi, int argc, char **argv) |
static int | handle_exec (struct ast_channel *chan, AGI *agi, int argc, char **argv) |
static int | handle_getdata (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
static int | handle_getoption (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
static int | handle_getvariable (struct ast_channel *chan, AGI *agi, int argc, char **argv) |
static int | handle_getvariablefull (struct ast_channel *chan, AGI *agi, int argc, char **argv) |
static int | handle_hangup (struct ast_channel *chan, AGI *agi, int argc, char **argv) |
static int | handle_noop (struct ast_channel *chan, AGI *agi, int arg, char *argv[]) |
static int | handle_recordfile (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
static int | handle_recvchar (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
static int | handle_recvtext (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
static int | handle_sayalpha (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
static int | handle_saydate (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
static int | handle_saydatetime (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
static int | handle_saydigits (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
static int | handle_saynumber (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
static int | handle_sayphonetic (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
static int | handle_saytime (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
static int | handle_sendimage (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
static int | handle_sendtext (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
static int | handle_setcallerid (struct ast_channel *chan, AGI *agi, int argc, char **argv) |
static int | handle_setcontext (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
static int | handle_setextension (struct ast_channel *chan, AGI *agi, int argc, char **argv) |
static int | handle_setmusic (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
static int | handle_setpriority (struct ast_channel *chan, AGI *agi, int argc, char **argv) |
static int | handle_setvariable (struct ast_channel *chan, AGI *agi, int argc, char **argv) |
static int | handle_showagi (int fd, int argc, char *argv[]) |
static int | handle_streamfile (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
static int | handle_tddmode (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
static int | handle_verbose (struct ast_channel *chan, AGI *agi, int argc, char **argv) |
static int | handle_waitfordigit (struct ast_channel *chan, AGI *agi, int argc, char *argv[]) |
static int | help_workhorse (int fd, char *match[]) |
static enum agi_result | launch_netscript (char *agiurl, char *argv[], int *fds, int *efd, int *opid) |
static enum agi_result | launch_script (char *script, char *argv[], int *fds, int *efd, int *opid) |
static int | load_module (void) |
static int | parse_args (char *s, int *max, char *argv[]) |
static enum agi_result | run_agi (struct ast_channel *chan, char *request, AGI *agi, int pid, int *status, int dead) |
static void | setup_env (struct ast_channel *chan, char *request, int fd, int enhanced) |
static int | unload_module (void) |
Variables | |
static int | agidebug = 0 |
static char * | app = "AGI" |
static struct ast_cli_entry | cli_agi [] |
static struct ast_cli_entry | cli_agi_no_debug_deprecated |
static struct ast_cli_entry | cli_dump_agihtml_deprecated |
static struct ast_cli_entry | cli_show_agi_deprecated |
static agi_command | commands [MAX_COMMANDS] |
static char * | deadapp = "DeadAGI" |
static char * | deadsynopsis = "Executes AGI on a hungup channel" |
static char | debug_usage [] |
static char * | descrip |
static char | dumpagihtml_help [] |
static char * | eapp = "EAGI" |
static char * | esynopsis = "Executes an EAGI compliant application" |
static char | no_debug_usage [] |
static char | showagi_help [] |
static char * | synopsis = "Executes an AGI compliant application" |
static char | usage_answer [] |
static char | usage_autohangup [] |
static char | usage_channelstatus [] |
static char | usage_controlstreamfile [] |
static char | usage_dbdel [] |
static char | usage_dbdeltree [] |
static char | usage_dbget [] |
static char | usage_dbput [] |
static char | usage_exec [] |
static char | usage_getdata [] |
static char | usage_getoption [] |
static char | usage_getvariable [] |
static char | usage_getvariablefull [] |
static char | usage_hangup [] |
static char | usage_noop [] |
static char | usage_recordfile [] |
static char | usage_recvchar [] |
static char | usage_recvtext [] |
static char | usage_sayalpha [] |
static char | usage_saydate [] |
static char | usage_saydatetime [] |
static char | usage_saydigits [] |
static char | usage_saynumber [] |
static char | usage_sayphonetic [] |
static char | usage_saytime [] |
static char | usage_sendimage [] |
static char | usage_sendtext [] |
static char | usage_setcallerid [] |
static char | usage_setcontext [] |
static char | usage_setextension [] |
static char | usage_setmusic [] |
static char | usage_setpriority [] |
static char | usage_setvariable [] |
static char | usage_streamfile [] |
static char | usage_tddmode [] |
static char | usage_verbose [] |
static char | usage_waitfordigit [] |
Definition in file res_agi.c.
#define AGI_PORT 4573 |
#define fdprintf agi_debug_cli |
Definition at line 72 of file res_agi.c.
Referenced by agi_handle_command(), handle_answer(), handle_autohangup(), handle_channelstatus(), handle_controlstreamfile(), handle_dbdel(), handle_dbdeltree(), handle_dbget(), handle_dbput(), handle_exec(), handle_getdata(), handle_getoption(), handle_getvariable(), handle_getvariablefull(), handle_hangup(), handle_noop(), handle_recordfile(), handle_recvchar(), handle_recvtext(), handle_sayalpha(), handle_saydate(), handle_saydatetime(), handle_saydigits(), handle_saynumber(), handle_sayphonetic(), handle_saytime(), handle_sendimage(), handle_sendtext(), handle_setcallerid(), handle_setcontext(), handle_setextension(), handle_setmusic(), handle_setpriority(), handle_setvariable(), handle_streamfile(), handle_tddmode(), handle_verbose(), handle_waitfordigit(), launch_netscript(), and setup_env().
#define MAX_AGI_CONNECT 2000 |
#define MAX_COMMANDS 128 |
Definition at line 69 of file res_agi.c.
Referenced by ast_agi_register(), and ast_agi_unregister().
enum agi_result |
Definition at line 112 of file res_agi.c.
00112 { 00113 AGI_RESULT_SUCCESS, 00114 AGI_RESULT_FAILURE, 00115 AGI_RESULT_HANGUP 00116 };
static int agi_debug_cli | ( | int | fd, | |
char * | fmt, | |||
... | ||||
) | [static] |
Definition at line 118 of file res_agi.c.
References ast_carefulwrite(), ast_log(), ast_verbose(), free, LOG_ERROR, ast_variable::stuff, and vasprintf.
00119 { 00120 char *stuff; 00121 int res = 0; 00122 00123 va_list ap; 00124 va_start(ap, fmt); 00125 res = vasprintf(&stuff, fmt, ap); 00126 va_end(ap); 00127 if (res == -1) { 00128 ast_log(LOG_ERROR, "Out of memory\n"); 00129 } else { 00130 if (agidebug) 00131 ast_verbose("AGI Tx >> %s", stuff); /* \n provided by caller */ 00132 res = ast_carefulwrite(fd, stuff, strlen(stuff), 100); 00133 free(stuff); 00134 } 00135 00136 return res; 00137 }
static int agi_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1313 of file res_agi.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01314 { 01315 if (argc != 2) 01316 return RESULT_SHOWUSAGE; 01317 agidebug = 1; 01318 ast_cli(fd, "AGI Debugging Enabled\n"); 01319 return RESULT_SUCCESS; 01320 }
static int agi_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 2058 of file res_agi.c.
References ast_channel::_softhangup, agi_exec_full(), ast_log(), and LOG_WARNING.
Referenced by load_module().
02059 { 02060 if (chan->_softhangup) 02061 ast_log(LOG_WARNING, "If you want to run AGI on hungup channels you should use DeadAGI!\n"); 02062 return agi_exec_full(chan, data, 0, 0); 02063 }
static int agi_exec_full | ( | struct ast_channel * | chan, | |
void * | data, | |||
int | enhanced, | |||
int | dead | |||
) | [static] |
Definition at line 1990 of file res_agi.c.
References ast_channel::_state, AGI_RESULT_FAILURE, AGI_RESULT_HANGUP, AGI_RESULT_SUCCESS, ast_answer(), ast_log(), ast_module_user_add, ast_module_user_remove, AST_STATE_UP, ast_strlen_zero(), ast_unreplace_sigchld(), AGI::audio, AGI::ctrl, AGI::fd, launch_script(), LOG_WARNING, MAX_ARGS, pbx_builtin_setvar_helper(), run_agi(), and strsep().
Referenced by agi_exec(), deadagi_exec(), and eagi_exec().
01991 { 01992 enum agi_result res; 01993 struct ast_module_user *u; 01994 char *argv[MAX_ARGS]; 01995 char buf[2048]=""; 01996 char *tmp = (char *)buf; 01997 int argc = 0; 01998 int fds[2]; 01999 int efd = -1; 02000 int pid; 02001 char *stringp; 02002 AGI agi; 02003 02004 if (ast_strlen_zero(data)) { 02005 ast_log(LOG_WARNING, "AGI requires an argument (script)\n"); 02006 return -1; 02007 } 02008 ast_copy_string(buf, data, sizeof(buf)); 02009 02010 memset(&agi, 0, sizeof(agi)); 02011 while ((stringp = strsep(&tmp, "|")) && argc < MAX_ARGS-1) 02012 argv[argc++] = stringp; 02013 argv[argc] = NULL; 02014 02015 u = ast_module_user_add(chan); 02016 #if 0 02017 /* Answer if need be */ 02018 if (chan->_state != AST_STATE_UP) { 02019 if (ast_answer(chan)) { 02020 LOCAL_USER_REMOVE(u); 02021 return -1; 02022 } 02023 } 02024 #endif 02025 res = launch_script(argv[0], argv, fds, enhanced ? &efd : NULL, &pid); 02026 if (res == AGI_RESULT_SUCCESS) { 02027 int status = 0; 02028 agi.fd = fds[1]; 02029 agi.ctrl = fds[0]; 02030 agi.audio = efd; 02031 res = run_agi(chan, argv[0], &agi, pid, &status, dead); 02032 /* If the fork'd process returns non-zero, set AGISTATUS to FAILURE */ 02033 if (res == AGI_RESULT_SUCCESS && status) 02034 res = AGI_RESULT_FAILURE; 02035 if (fds[1] != fds[0]) 02036 close(fds[1]); 02037 if (efd > -1) 02038 close(efd); 02039 ast_unreplace_sigchld(); 02040 } 02041 ast_module_user_remove(u); 02042 02043 switch (res) { 02044 case AGI_RESULT_SUCCESS: 02045 pbx_builtin_setvar_helper(chan, "AGISTATUS", "SUCCESS"); 02046 break; 02047 case AGI_RESULT_FAILURE: 02048 pbx_builtin_setvar_helper(chan, "AGISTATUS", "FAILURE"); 02049 break; 02050 case AGI_RESULT_HANGUP: 02051 pbx_builtin_setvar_helper(chan, "AGISTATUS", "HANGUP"); 02052 return -1; 02053 } 02054 02055 return 0; 02056 }
static int agi_handle_command | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
char * | buf | |||
) | [static] |
Definition at line 1795 of file res_agi.c.
References AST_PBX_KEEPALIVE, AGI::fd, fdprintf, find_command(), agi_command::handler, MAX_ARGS, parse_args(), RESULT_FAILURE, RESULT_SHOWUSAGE, and agi_command::usage.
Referenced by run_agi().
01796 { 01797 char *argv[MAX_ARGS]; 01798 int argc = MAX_ARGS; 01799 int res; 01800 agi_command *c; 01801 01802 parse_args(buf, &argc, argv); 01803 c = find_command(argv, 0); 01804 if (c) { 01805 res = c->handler(chan, agi, argc, argv); 01806 switch(res) { 01807 case RESULT_SHOWUSAGE: 01808 fdprintf(agi->fd, "520-Invalid command syntax. Proper usage follows:\n"); 01809 fdprintf(agi->fd, c->usage); 01810 fdprintf(agi->fd, "520 End of proper usage.\n"); 01811 break; 01812 case AST_PBX_KEEPALIVE: 01813 /* We've been asked to keep alive, so do so */ 01814 return AST_PBX_KEEPALIVE; 01815 break; 01816 case RESULT_FAILURE: 01817 /* They've already given the failure. We've been hung up on so handle this 01818 appropriately */ 01819 return -1; 01820 } 01821 } else { 01822 fdprintf(agi->fd, "510 Invalid or unknown command\n"); 01823 } 01824 return 0; 01825 }
static int agi_no_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1331 of file res_agi.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01332 { 01333 if (argc != 3) 01334 return RESULT_SHOWUSAGE; 01335 agidebug = 0; 01336 ast_cli(fd, "AGI Debugging Disabled\n"); 01337 return RESULT_SUCCESS; 01338 }
static int agi_no_debug_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1322 of file res_agi.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01323 { 01324 if (argc != 3) 01325 return RESULT_SHOWUSAGE; 01326 agidebug = 0; 01327 ast_cli(fd, "AGI Debugging Disabled\n"); 01328 return RESULT_SUCCESS; 01329 }
int ast_agi_register | ( | agi_command * | agi | ) |
Definition at line 1666 of file res_agi.c.
References ast_log(), agi_command::cmda, LOG_WARNING, and MAX_COMMANDS.
01667 { 01668 int x; 01669 for (x=0; x<MAX_COMMANDS - 1; x++) { 01670 if (commands[x].cmda[0] == agi->cmda[0]) { 01671 ast_log(LOG_WARNING, "Command already registered!\n"); 01672 return -1; 01673 } 01674 } 01675 for (x=0; x<MAX_COMMANDS - 1; x++) { 01676 if (!commands[x].cmda[0]) { 01677 commands[x] = *agi; 01678 return 0; 01679 } 01680 } 01681 ast_log(LOG_WARNING, "No more room for new commands!\n"); 01682 return -1; 01683 }
void ast_agi_unregister | ( | agi_command * | agi | ) |
Definition at line 1685 of file res_agi.c.
References agi_command::cmda, and MAX_COMMANDS.
01686 { 01687 int x; 01688 for (x=0; x<MAX_COMMANDS - 1; x++) { 01689 if (commands[x].cmda[0] == agi->cmda[0]) { 01690 memset(&commands[x], 0, sizeof(agi_command)); 01691 } 01692 } 01693 }
AST_MODULE_INFO | ( | ASTERISK_GPL_KEY | , | |
AST_MODFLAG_GLOBAL_SYMBOLS | , | |||
"Asterisk Gateway Interface (AGI)" | , | |||
. | load = load_module , |
|||
. | unload = unload_module | |||
) |
static int deadagi_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 2086 of file res_agi.c.
References agi_exec_full(), ast_check_hangup(), ast_log(), and LOG_WARNING.
Referenced by load_module().
02087 { 02088 if (!ast_check_hangup(chan)) 02089 ast_log(LOG_WARNING,"Running DeadAGI on a live channel will cause problems, please use AGI\n"); 02090 return agi_exec_full(chan, data, 0, 1); 02091 }
static int eagi_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 2065 of file res_agi.c.
References ast_channel::_softhangup, agi_exec_full(), AST_FORMAT_SLINEAR, ast_getformatname(), ast_log(), ast_set_read_format(), LOG_WARNING, and ast_channel::readformat.
Referenced by load_module().
02066 { 02067 int readformat; 02068 int res; 02069 02070 if (chan->_softhangup) 02071 ast_log(LOG_WARNING, "If you want to run AGI on hungup channels you should use DeadAGI!\n"); 02072 readformat = chan->readformat; 02073 if (ast_set_read_format(chan, AST_FORMAT_SLINEAR)) { 02074 ast_log(LOG_WARNING, "Unable to set channel '%s' to linear mode\n", chan->name); 02075 return -1; 02076 } 02077 res = agi_exec_full(chan, data, 1, 0); 02078 if (!res) { 02079 if (ast_set_read_format(chan, readformat)) { 02080 ast_log(LOG_WARNING, "Unable to restore channel '%s' to format %s\n", chan->name, ast_getformatname(readformat)); 02081 } 02082 } 02083 return res; 02084 }
static agi_command* find_command | ( | char * | cmds[], | |
int | exact | |||
) | [static] |
Definition at line 1695 of file res_agi.c.
References agi_command::cmda, and match().
01696 { 01697 int x; 01698 int y; 01699 int match; 01700 01701 for (x=0; x < sizeof(commands) / sizeof(commands[0]); x++) { 01702 if (!commands[x].cmda[0]) 01703 break; 01704 /* start optimistic */ 01705 match = 1; 01706 for (y=0; match && cmds[y]; y++) { 01707 /* If there are no more words in the command (and we're looking for 01708 an exact match) or there is a difference between the two words, 01709 then this is not a match */ 01710 if (!commands[x].cmda[y] && !exact) 01711 break; 01712 /* don't segfault if the next part of a command doesn't exist */ 01713 if (!commands[x].cmda[y]) 01714 return NULL; 01715 if (strcasecmp(commands[x].cmda[y], cmds[y])) 01716 match = 0; 01717 } 01718 /* If more words are needed to complete the command then this is not 01719 a candidate (unless we're looking for a really inexact answer */ 01720 if ((exact > -1) && commands[x].cmda[y]) 01721 match = 0; 01722 if (match) 01723 return &commands[x]; 01724 } 01725 return NULL; 01726 }
static int handle_agidumphtml | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1936 of file res_agi.c.
References ast_cli(), ast_join(), agi_command::cmda, RESULT_SHOWUSAGE, RESULT_SUCCESS, strsep(), agi_command::summary, and agi_command::usage.
01937 { 01938 struct agi_command *e; 01939 char fullcmd[80]; 01940 int x; 01941 FILE *htmlfile; 01942 01943 if ((argc < 3)) 01944 return RESULT_SHOWUSAGE; 01945 01946 if (!(htmlfile = fopen(argv[2], "wt"))) { 01947 ast_cli(fd, "Could not create file '%s'\n", argv[2]); 01948 return RESULT_SHOWUSAGE; 01949 } 01950 01951 fprintf(htmlfile, "<HTML>\n<HEAD>\n<TITLE>AGI Commands</TITLE>\n</HEAD>\n"); 01952 fprintf(htmlfile, "<BODY>\n<CENTER><B><H1>AGI Commands</H1></B></CENTER>\n\n"); 01953 01954 01955 fprintf(htmlfile, "<TABLE BORDER=\"0\" CELLSPACING=\"10\">\n"); 01956 01957 for (x=0;x<sizeof(commands)/sizeof(commands[0]);x++) { 01958 char *stringp, *tempstr; 01959 01960 e = &commands[x]; 01961 if (!e->cmda[0]) /* end ? */ 01962 break; 01963 /* Hide commands that start with '_' */ 01964 if ((e->cmda[0])[0] == '_') 01965 continue; 01966 ast_join(fullcmd, sizeof(fullcmd), e->cmda); 01967 01968 fprintf(htmlfile, "<TR><TD><TABLE BORDER=\"1\" CELLPADDING=\"5\" WIDTH=\"100%%\">\n"); 01969 fprintf(htmlfile, "<TR><TH ALIGN=\"CENTER\"><B>%s - %s</B></TH></TR>\n", fullcmd,e->summary); 01970 01971 stringp=e->usage; 01972 tempstr = strsep(&stringp, "\n"); 01973 01974 fprintf(htmlfile, "<TR><TD ALIGN=\"CENTER\">%s</TD></TR>\n", tempstr); 01975 01976 fprintf(htmlfile, "<TR><TD ALIGN=\"CENTER\">\n"); 01977 while ((tempstr = strsep(&stringp, "\n")) != NULL) 01978 fprintf(htmlfile, "%s<BR>\n",tempstr); 01979 fprintf(htmlfile, "</TD></TR>\n"); 01980 fprintf(htmlfile, "</TABLE></TD></TR>\n\n"); 01981 01982 } 01983 01984 fprintf(htmlfile, "</TABLE>\n</BODY>\n</HTML>\n"); 01985 fclose(htmlfile); 01986 ast_cli(fd, "AGI HTML Commands Dumped to: %s\n", argv[2]); 01987 return RESULT_SUCCESS; 01988 }
static int handle_answer | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 401 of file res_agi.c.
References ast_channel::_state, ast_answer(), AST_STATE_UP, AGI::fd, fdprintf, RESULT_FAILURE, and RESULT_SUCCESS.
00402 { 00403 int res; 00404 res = 0; 00405 if (chan->_state != AST_STATE_UP) { 00406 /* Answer the chan */ 00407 res = ast_answer(chan); 00408 } 00409 fdprintf(agi->fd, "200 result=%d\n", res); 00410 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00411 }
static int handle_autohangup | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1050 of file res_agi.c.
References AGI::fd, fdprintf, RESULT_SHOWUSAGE, RESULT_SUCCESS, and ast_channel::whentohangup.
01051 { 01052 int timeout; 01053 01054 if (argc != 3) 01055 return RESULT_SHOWUSAGE; 01056 if (sscanf(argv[2], "%d", &timeout) != 1) 01057 return RESULT_SHOWUSAGE; 01058 if (timeout < 0) 01059 timeout = 0; 01060 if (timeout) 01061 chan->whentohangup = time(NULL) + timeout; 01062 else 01063 chan->whentohangup = 0; 01064 fdprintf(agi->fd, "200 result=0\n"); 01065 return RESULT_SUCCESS; 01066 }
static int handle_channelstatus | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 1140 of file res_agi.c.
References ast_channel::_state, ast_channel_unlock, ast_get_channel_by_name_locked(), AGI::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01141 { 01142 struct ast_channel *c; 01143 if (argc == 2) { 01144 /* no argument: supply info on the current channel */ 01145 fdprintf(agi->fd, "200 result=%d\n", chan->_state); 01146 return RESULT_SUCCESS; 01147 } else if (argc == 3) { 01148 /* one argument: look for info on the specified channel */ 01149 c = ast_get_channel_by_name_locked(argv[2]); 01150 if (c) { 01151 fdprintf(agi->fd, "200 result=%d\n", c->_state); 01152 ast_channel_unlock(c); 01153 return RESULT_SUCCESS; 01154 } 01155 /* if we get this far no channel name matched the argument given */ 01156 fdprintf(agi->fd, "200 result=-1\n"); 01157 return RESULT_SUCCESS; 01158 } else { 01159 return RESULT_SHOWUSAGE; 01160 } 01161 }
static int handle_controlstreamfile | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 512 of file res_agi.c.
References ast_control_streamfile(), ast_strlen_zero(), AGI::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and skipms.
00513 { 00514 int res = 0; 00515 int skipms = 3000; 00516 char *fwd = NULL; 00517 char *rev = NULL; 00518 char *pause = NULL; 00519 char *stop = NULL; 00520 00521 if (argc < 5 || argc > 9) 00522 return RESULT_SHOWUSAGE; 00523 00524 if (!ast_strlen_zero(argv[4])) 00525 stop = argv[4]; 00526 else 00527 stop = NULL; 00528 00529 if ((argc > 5) && (sscanf(argv[5], "%d", &skipms) != 1)) 00530 return RESULT_SHOWUSAGE; 00531 00532 if (argc > 6 && !ast_strlen_zero(argv[6])) 00533 fwd = argv[6]; 00534 else 00535 fwd = "#"; 00536 00537 if (argc > 7 && !ast_strlen_zero(argv[7])) 00538 rev = argv[7]; 00539 else 00540 rev = "*"; 00541 00542 if (argc > 8 && !ast_strlen_zero(argv[8])) 00543 pause = argv[8]; 00544 else 00545 pause = NULL; 00546 00547 res = ast_control_streamfile(chan, argv[3], fwd, rev, stop, pause, NULL, skipms); 00548 00549 fdprintf(agi->fd, "200 result=%d\n", res); 00550 00551 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00552 }
static int handle_dbdel | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 1280 of file res_agi.c.
References ast_db_del(), AGI::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01281 { 01282 int res; 01283 01284 if (argc != 4) 01285 return RESULT_SHOWUSAGE; 01286 res = ast_db_del(argv[2], argv[3]); 01287 fdprintf(agi->fd, "200 result=%c\n", res ? '0' : '1'); 01288 return RESULT_SUCCESS; 01289 }
static int handle_dbdeltree | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 1291 of file res_agi.c.
References ast_db_deltree(), AGI::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01292 { 01293 int res; 01294 if ((argc < 3) || (argc > 4)) 01295 return RESULT_SHOWUSAGE; 01296 if (argc == 4) 01297 res = ast_db_deltree(argv[2], argv[3]); 01298 else 01299 res = ast_db_deltree(argv[2], NULL); 01300 01301 fdprintf(agi->fd, "200 result=%c\n", res ? '0' : '1'); 01302 return RESULT_SUCCESS; 01303 }
static int handle_dbget | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 1253 of file res_agi.c.
References ast_db_get(), AGI::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01254 { 01255 int res; 01256 char tmp[256]; 01257 01258 if (argc != 4) 01259 return RESULT_SHOWUSAGE; 01260 res = ast_db_get(argv[2], argv[3], tmp, sizeof(tmp)); 01261 if (res) 01262 fdprintf(agi->fd, "200 result=0\n"); 01263 else 01264 fdprintf(agi->fd, "200 result=1 (%s)\n", tmp); 01265 01266 return RESULT_SUCCESS; 01267 }
static int handle_dbput | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 1269 of file res_agi.c.
References ast_db_put(), AGI::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01270 { 01271 int res; 01272 01273 if (argc != 5) 01274 return RESULT_SHOWUSAGE; 01275 res = ast_db_put(argv[2], argv[3], argv[4]); 01276 fdprintf(agi->fd, "200 result=%c\n", res ? '0' : '1'); 01277 return RESULT_SUCCESS; 01278 }
static int handle_exec | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 1094 of file res_agi.c.
References ast_log(), ast_verbose(), AGI::fd, fdprintf, LOG_WARNING, option_verbose, pbx_exec(), pbx_findapp(), RESULT_SHOWUSAGE, and VERBOSE_PREFIX_3.
01095 { 01096 int res; 01097 struct ast_app *app; 01098 01099 if (argc < 2) 01100 return RESULT_SHOWUSAGE; 01101 01102 if (option_verbose > 2) 01103 ast_verbose(VERBOSE_PREFIX_3 "AGI Script Executing Application: (%s) Options: (%s)\n", argv[1], argv[2]); 01104 01105 app = pbx_findapp(argv[1]); 01106 01107 if (app) { 01108 res = pbx_exec(chan, app, argv[2]); 01109 } else { 01110 ast_log(LOG_WARNING, "Could not find application (%s)\n", argv[1]); 01111 res = -2; 01112 } 01113 fdprintf(agi->fd, "200 result=%d\n", res); 01114 01115 /* Even though this is wrong, users are depending upon this result. */ 01116 return res; 01117 }
static int handle_getdata | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 809 of file res_agi.c.
References ast_app_getdata_full(), AGI::audio, AGI::ctrl, AGI::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
00810 { 00811 int res; 00812 char data[1024]; 00813 int max; 00814 int timeout; 00815 00816 if (argc < 3) 00817 return RESULT_SHOWUSAGE; 00818 if (argc >= 4) 00819 timeout = atoi(argv[3]); 00820 else 00821 timeout = 0; 00822 if (argc >= 5) 00823 max = atoi(argv[4]); 00824 else 00825 max = 1024; 00826 res = ast_app_getdata_full(chan, argv[2], data, max, timeout, agi->audio, agi->ctrl); 00827 if (res == 2) /* New command */ 00828 return RESULT_SUCCESS; 00829 else if (res == 1) 00830 fdprintf(agi->fd, "200 result=%s (timeout)\n", data); 00831 else if (res < 0 ) 00832 fdprintf(agi->fd, "200 result=-1\n"); 00833 else 00834 fdprintf(agi->fd, "200 result=%s\n", data); 00835 return RESULT_SUCCESS; 00836 }
static int handle_getoption | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 610 of file res_agi.c.
References ast_applystream(), ast_log(), ast_openstream(), ast_openvstream(), ast_playstream(), ast_seekstream(), ast_stopstream(), ast_tellstream(), ast_verbose(), ast_waitfordigit_full(), ast_waitstream_full(), AGI::audio, AGI::ctrl, ast_pbx::dtimeout, AGI::fd, fdprintf, LOG_DEBUG, LOG_WARNING, option_verbose, ast_channel::pbx, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, ast_channel::stream, VERBOSE_PREFIX_3, and ast_filestream::vfs.
00611 { 00612 int res; 00613 int vres; 00614 struct ast_filestream *fs; 00615 struct ast_filestream *vfs; 00616 long sample_offset = 0; 00617 long max_length; 00618 int timeout = 0; 00619 char *edigits = ""; 00620 00621 if ( argc < 4 || argc > 5 ) 00622 return RESULT_SHOWUSAGE; 00623 00624 if ( argv[3] ) 00625 edigits = argv[3]; 00626 00627 if ( argc == 5 ) 00628 timeout = atoi(argv[4]); 00629 else if (chan->pbx->dtimeout) { 00630 /* by default dtimeout is set to 5sec */ 00631 timeout = chan->pbx->dtimeout * 1000; /* in msec */ 00632 } 00633 00634 fs = ast_openstream(chan, argv[2], chan->language); 00635 if (!fs) { 00636 fdprintf(agi->fd, "200 result=%d endpos=%ld\n", 0, sample_offset); 00637 ast_log(LOG_WARNING, "Unable to open %s\n", argv[2]); 00638 return RESULT_SUCCESS; 00639 } 00640 vfs = ast_openvstream(chan, argv[2], chan->language); 00641 if (vfs) 00642 ast_log(LOG_DEBUG, "Ooh, found a video stream, too\n"); 00643 00644 if (option_verbose > 2) 00645 ast_verbose(VERBOSE_PREFIX_3 "Playing '%s' (escape_digits=%s) (timeout %d)\n", argv[2], edigits, timeout); 00646 00647 ast_seekstream(fs, 0, SEEK_END); 00648 max_length = ast_tellstream(fs); 00649 ast_seekstream(fs, sample_offset, SEEK_SET); 00650 res = ast_applystream(chan, fs); 00651 if (vfs) 00652 vres = ast_applystream(chan, vfs); 00653 ast_playstream(fs); 00654 if (vfs) 00655 ast_playstream(vfs); 00656 00657 res = ast_waitstream_full(chan, argv[3], agi->audio, agi->ctrl); 00658 /* this is to check for if ast_waitstream closed the stream, we probably are at 00659 * the end of the stream, return that amount, else check for the amount */ 00660 sample_offset = (chan->stream)?ast_tellstream(fs):max_length; 00661 ast_stopstream(chan); 00662 if (res == 1) { 00663 /* Stop this command, don't print a result line, as there is a new command */ 00664 return RESULT_SUCCESS; 00665 } 00666 00667 /* If the user didnt press a key, wait for digitTimeout*/ 00668 if (res == 0 ) { 00669 res = ast_waitfordigit_full(chan, timeout, agi->audio, agi->ctrl); 00670 /* Make sure the new result is in the escape digits of the GET OPTION */ 00671 if ( !strchr(edigits,res) ) 00672 res=0; 00673 } 00674 00675 fdprintf(agi->fd, "200 result=%d endpos=%ld\n", res, sample_offset); 00676 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00677 }
static int handle_getvariable | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 1172 of file res_agi.c.
References ast_func_read(), ast_strlen_zero(), AGI::fd, fdprintf, pbx_retrieve_variable(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01173 { 01174 char *ret; 01175 char tempstr[1024]; 01176 01177 if (argc != 3) 01178 return RESULT_SHOWUSAGE; 01179 01180 /* check if we want to execute an ast_custom_function */ 01181 if (!ast_strlen_zero(argv[2]) && (argv[2][strlen(argv[2]) - 1] == ')')) { 01182 ret = ast_func_read(chan, argv[2], tempstr, sizeof(tempstr)) ? NULL : tempstr; 01183 } else { 01184 pbx_retrieve_variable(chan, argv[2], &ret, tempstr, sizeof(tempstr), NULL); 01185 } 01186 01187 if (ret) 01188 fdprintf(agi->fd, "200 result=1 (%s)\n", ret); 01189 else 01190 fdprintf(agi->fd, "200 result=0\n"); 01191 01192 return RESULT_SUCCESS; 01193 }
static int handle_getvariablefull | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 1195 of file res_agi.c.
References ast_channel_unlock, ast_get_channel_by_name_locked(), AGI::fd, fdprintf, pbx_substitute_variables_helper(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01196 { 01197 char tmp[4096] = ""; 01198 struct ast_channel *chan2=NULL; 01199 01200 if ((argc != 4) && (argc != 5)) 01201 return RESULT_SHOWUSAGE; 01202 if (argc == 5) { 01203 chan2 = ast_get_channel_by_name_locked(argv[4]); 01204 } else { 01205 chan2 = chan; 01206 } 01207 if (chan) { /* XXX isn't this chan2 ? */ 01208 pbx_substitute_variables_helper(chan2, argv[3], tmp, sizeof(tmp) - 1); 01209 fdprintf(agi->fd, "200 result=1 (%s)\n", tmp); 01210 } else { 01211 fdprintf(agi->fd, "200 result=0\n"); 01212 } 01213 if (chan2 && (chan2 != chan)) 01214 ast_channel_unlock(chan2); 01215 return RESULT_SUCCESS; 01216 }
static int handle_hangup | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 1068 of file res_agi.c.
References ast_channel_unlock, ast_get_channel_by_name_locked(), ast_softhangup(), AST_SOFTHANGUP_EXPLICIT, AGI::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01069 { 01070 struct ast_channel *c; 01071 if (argc == 1) { 01072 /* no argument: hangup the current channel */ 01073 ast_softhangup(chan,AST_SOFTHANGUP_EXPLICIT); 01074 fdprintf(agi->fd, "200 result=1\n"); 01075 return RESULT_SUCCESS; 01076 } else if (argc == 2) { 01077 /* one argument: look for info on the specified channel */ 01078 c = ast_get_channel_by_name_locked(argv[1]); 01079 if (c) { 01080 /* we have a matching channel */ 01081 ast_softhangup(c,AST_SOFTHANGUP_EXPLICIT); 01082 fdprintf(agi->fd, "200 result=1\n"); 01083 ast_channel_unlock(c); 01084 return RESULT_SUCCESS; 01085 } 01086 /* if we get this far no channel name matched the argument given */ 01087 fdprintf(agi->fd, "200 result=-1\n"); 01088 return RESULT_SUCCESS; 01089 } else { 01090 return RESULT_SHOWUSAGE; 01091 } 01092 }
static int handle_noop | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | arg, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1340 of file res_agi.c.
References AGI::fd, fdprintf, and RESULT_SUCCESS.
01341 { 01342 fdprintf(agi->fd, "200 result=0\n"); 01343 return RESULT_SUCCESS; 01344 }
static int handle_recordfile | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 873 of file res_agi.c.
References ast_applystream(), ast_closestream(), AST_CONTROL_VIDUPDATE, ast_dsp_free(), ast_dsp_new(), ast_dsp_set_threshold(), ast_dsp_silence(), AST_FORMAT_SLINEAR, AST_FRAME_DTMF, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree(), ast_indicate(), ast_log(), ast_read(), ast_seekstream(), ast_set_read_format(), ast_stream_rewind(), ast_streamfile(), ast_tellstream(), ast_truncstream(), ast_waitfor(), ast_waitstream(), ast_writefile(), ast_writestream(), f, AGI::fd, fdprintf, ast_frame::frametype, LOG_WARNING, ast_channel::readformat, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, silence, ast_channel::stream, ast_frame::subclass, and ast_dsp::totalsilence.
00874 { 00875 struct ast_filestream *fs; 00876 struct ast_frame *f; 00877 struct timeval start; 00878 long sample_offset = 0; 00879 int res = 0; 00880 int ms; 00881 00882 struct ast_dsp *sildet=NULL; /* silence detector dsp */ 00883 int totalsilence = 0; 00884 int dspsilence = 0; 00885 int silence = 0; /* amount of silence to allow */ 00886 int gotsilence = 0; /* did we timeout for silence? */ 00887 char *silencestr=NULL; 00888 int rfmt=0; 00889 00890 00891 /* XXX EAGI FIXME XXX */ 00892 00893 if (argc < 6) 00894 return RESULT_SHOWUSAGE; 00895 if (sscanf(argv[5], "%d", &ms) != 1) 00896 return RESULT_SHOWUSAGE; 00897 00898 if (argc > 6) 00899 silencestr = strchr(argv[6],'s'); 00900 if ((argc > 7) && (!silencestr)) 00901 silencestr = strchr(argv[7],'s'); 00902 if ((argc > 8) && (!silencestr)) 00903 silencestr = strchr(argv[8],'s'); 00904 00905 if (silencestr) { 00906 if (strlen(silencestr) > 2) { 00907 if ((silencestr[0] == 's') && (silencestr[1] == '=')) { 00908 silencestr++; 00909 silencestr++; 00910 if (silencestr) 00911 silence = atoi(silencestr); 00912 if (silence > 0) 00913 silence *= 1000; 00914 } 00915 } 00916 } 00917 00918 if (silence > 0) { 00919 rfmt = chan->readformat; 00920 res = ast_set_read_format(chan, AST_FORMAT_SLINEAR); 00921 if (res < 0) { 00922 ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n"); 00923 return -1; 00924 } 00925 sildet = ast_dsp_new(); 00926 if (!sildet) { 00927 ast_log(LOG_WARNING, "Unable to create silence detector :(\n"); 00928 return -1; 00929 } 00930 ast_dsp_set_threshold(sildet, 256); 00931 } 00932 00933 /* backward compatibility, if no offset given, arg[6] would have been 00934 * caught below and taken to be a beep, else if it is a digit then it is a 00935 * offset */ 00936 if ((argc >6) && (sscanf(argv[6], "%ld", &sample_offset) != 1) && (!strchr(argv[6], '='))) 00937 res = ast_streamfile(chan, "beep", chan->language); 00938 00939 if ((argc > 7) && (!strchr(argv[7], '='))) 00940 res = ast_streamfile(chan, "beep", chan->language); 00941 00942 if (!res) 00943 res = ast_waitstream(chan, argv[4]); 00944 if (res) { 00945 fdprintf(agi->fd, "200 result=%d (randomerror) endpos=%ld\n", res, sample_offset); 00946 } else { 00947 fs = ast_writefile(argv[2], argv[3], NULL, O_CREAT | O_WRONLY | (sample_offset ? O_APPEND : 0), 0, 0644); 00948 if (!fs) { 00949 res = -1; 00950 fdprintf(agi->fd, "200 result=%d (writefile)\n", res); 00951 if (sildet) 00952 ast_dsp_free(sildet); 00953 return RESULT_FAILURE; 00954 } 00955 00956 /* Request a video update */ 00957 ast_indicate(chan, AST_CONTROL_VIDUPDATE); 00958 00959 chan->stream = fs; 00960 ast_applystream(chan,fs); 00961 /* really should have checks */ 00962 ast_seekstream(fs, sample_offset, SEEK_SET); 00963 ast_truncstream(fs); 00964 00965 start = ast_tvnow(); 00966 while ((ms < 0) || ast_tvdiff_ms(ast_tvnow(), start) < ms) { 00967 res = ast_waitfor(chan, -1); 00968 if (res < 0) { 00969 ast_closestream(fs); 00970 fdprintf(agi->fd, "200 result=%d (waitfor) endpos=%ld\n", res,sample_offset); 00971 if (sildet) 00972 ast_dsp_free(sildet); 00973 return RESULT_FAILURE; 00974 } 00975 f = ast_read(chan); 00976 if (!f) { 00977 fdprintf(agi->fd, "200 result=%d (hangup) endpos=%ld\n", 0, sample_offset); 00978 ast_closestream(fs); 00979 if (sildet) 00980 ast_dsp_free(sildet); 00981 return RESULT_FAILURE; 00982 } 00983 switch(f->frametype) { 00984 case AST_FRAME_DTMF: 00985 if (strchr(argv[4], f->subclass)) { 00986 /* This is an interrupting chracter, so rewind to chop off any small 00987 amount of DTMF that may have been recorded 00988 */ 00989 ast_stream_rewind(fs, 200); 00990 ast_truncstream(fs); 00991 sample_offset = ast_tellstream(fs); 00992 fdprintf(agi->fd, "200 result=%d (dtmf) endpos=%ld\n", f->subclass, sample_offset); 00993 ast_closestream(fs); 00994 ast_frfree(f); 00995 if (sildet) 00996 ast_dsp_free(sildet); 00997 return RESULT_SUCCESS; 00998 } 00999 break; 01000 case AST_FRAME_VOICE: 01001 ast_writestream(fs, f); 01002 /* this is a safe place to check progress since we know that fs 01003 * is valid after a write, and it will then have our current 01004 * location */ 01005 sample_offset = ast_tellstream(fs); 01006 if (silence > 0) { 01007 dspsilence = 0; 01008 ast_dsp_silence(sildet, f, &dspsilence); 01009 if (dspsilence) { 01010 totalsilence = dspsilence; 01011 } else { 01012 totalsilence = 0; 01013 } 01014 if (totalsilence > silence) { 01015 /* Ended happily with silence */ 01016 gotsilence = 1; 01017 break; 01018 } 01019 } 01020 break; 01021 case AST_FRAME_VIDEO: 01022 ast_writestream(fs, f); 01023 default: 01024 /* Ignore all other frames */ 01025 break; 01026 } 01027 ast_frfree(f); 01028 if (gotsilence) 01029 break; 01030 } 01031 01032 if (gotsilence) { 01033 ast_stream_rewind(fs, silence-1000); 01034 ast_truncstream(fs); 01035 sample_offset = ast_tellstream(fs); 01036 } 01037 fdprintf(agi->fd, "200 result=%d (timeout) endpos=%ld\n", res, sample_offset); 01038 ast_closestream(fs); 01039 } 01040 01041 if (silence > 0) { 01042 res = ast_set_read_format(chan, rfmt); 01043 if (res) 01044 ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", chan->name); 01045 ast_dsp_free(sildet); 01046 } 01047 return RESULT_SUCCESS; 01048 }
static int handle_recvchar | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 443 of file res_agi.c.
References ast_recvchar(), AGI::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
00444 { 00445 int res; 00446 if (argc != 3) 00447 return RESULT_SHOWUSAGE; 00448 res = ast_recvchar(chan,atoi(argv[2])); 00449 if (res == 0) { 00450 fdprintf(agi->fd, "200 result=%d (timeout)\n", res); 00451 return RESULT_SUCCESS; 00452 } 00453 if (res > 0) { 00454 fdprintf(agi->fd, "200 result=%d\n", res); 00455 return RESULT_SUCCESS; 00456 } 00457 else { 00458 fdprintf(agi->fd, "200 result=%d (hangup)\n", res); 00459 return RESULT_FAILURE; 00460 } 00461 }
static int handle_recvtext | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 463 of file res_agi.c.
References ast_recvtext(), ast_hostent::buf, AGI::fd, fdprintf, free, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
00464 { 00465 char *buf; 00466 00467 if (argc != 3) 00468 return RESULT_SHOWUSAGE; 00469 buf = ast_recvtext(chan,atoi(argv[2])); 00470 if (buf) { 00471 fdprintf(agi->fd, "200 result=1 (%s)\n", buf); 00472 free(buf); 00473 } else { 00474 fdprintf(agi->fd, "200 result=-1\n"); 00475 } 00476 return RESULT_SUCCESS; 00477 }
static int handle_sayalpha | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 717 of file res_agi.c.
References ast_say_character_str_full, AGI::audio, AGI::ctrl, AGI::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
00718 { 00719 int res; 00720 00721 if (argc != 4) 00722 return RESULT_SHOWUSAGE; 00723 00724 res = ast_say_character_str_full(chan, argv[2], argv[3], chan->language, agi->audio, agi->ctrl); 00725 if (res == 1) /* New command */ 00726 return RESULT_SUCCESS; 00727 fdprintf(agi->fd, "200 result=%d\n", res); 00728 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00729 }
static int handle_saydate | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 731 of file res_agi.c.
References ast_say_date, AGI::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
00732 { 00733 int res; 00734 int num; 00735 if (argc != 4) 00736 return RESULT_SHOWUSAGE; 00737 if (sscanf(argv[2], "%d", &num) != 1) 00738 return RESULT_SHOWUSAGE; 00739 res = ast_say_date(chan, num, argv[3], chan->language); 00740 if (res == 1) 00741 return RESULT_SUCCESS; 00742 fdprintf(agi->fd, "200 result=%d\n", res); 00743 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00744 }
static int handle_saydatetime | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 761 of file res_agi.c.
References ast_get_time_t(), ast_say_date_with_format, ast_strlen_zero(), AGI::fd, fdprintf, format, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
00762 { 00763 int res=0; 00764 time_t unixtime; 00765 char *format, *zone=NULL; 00766 00767 if (argc < 4) 00768 return RESULT_SHOWUSAGE; 00769 00770 if (argc > 4) { 00771 format = argv[4]; 00772 } else { 00773 /* XXX this doesn't belong here, but in the 'say' module */ 00774 if (!strcasecmp(chan->language, "de")) { 00775 format = "A dBY HMS"; 00776 } else { 00777 format = "ABdY 'digits/at' IMp"; 00778 } 00779 } 00780 00781 if (argc > 5 && !ast_strlen_zero(argv[5])) 00782 zone = argv[5]; 00783 00784 if (ast_get_time_t(argv[2], &unixtime, 0, NULL)) 00785 return RESULT_SHOWUSAGE; 00786 00787 res = ast_say_date_with_format(chan, unixtime, argv[3], chan->language, format, zone); 00788 if (res == 1) 00789 return RESULT_SUCCESS; 00790 00791 fdprintf(agi->fd, "200 result=%d\n", res); 00792 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00793 }
static int handle_saydigits | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 700 of file res_agi.c.
References ast_say_digit_str_full, AGI::audio, AGI::ctrl, AGI::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
00701 { 00702 int res; 00703 int num; 00704 00705 if (argc != 4) 00706 return RESULT_SHOWUSAGE; 00707 if (sscanf(argv[2], "%d", &num) != 1) 00708 return RESULT_SHOWUSAGE; 00709 00710 res = ast_say_digit_str_full(chan, argv[2], argv[3], chan->language, agi->audio, agi->ctrl); 00711 if (res == 1) /* New command */ 00712 return RESULT_SUCCESS; 00713 fdprintf(agi->fd, "200 result=%d\n", res); 00714 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00715 }
static int handle_saynumber | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 685 of file res_agi.c.
References ast_say_number_full, AGI::audio, AGI::ctrl, AGI::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
00686 { 00687 int res; 00688 int num; 00689 if (argc != 4) 00690 return RESULT_SHOWUSAGE; 00691 if (sscanf(argv[2], "%d", &num) != 1) 00692 return RESULT_SHOWUSAGE; 00693 res = ast_say_number_full(chan, num, argv[3], chan->language, (char *) NULL, agi->audio, agi->ctrl); 00694 if (res == 1) 00695 return RESULT_SUCCESS; 00696 fdprintf(agi->fd, "200 result=%d\n", res); 00697 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00698 }
static int handle_sayphonetic | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 795 of file res_agi.c.
References ast_say_phonetic_str_full, AGI::audio, AGI::ctrl, AGI::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
00796 { 00797 int res; 00798 00799 if (argc != 4) 00800 return RESULT_SHOWUSAGE; 00801 00802 res = ast_say_phonetic_str_full(chan, argv[2], argv[3], chan->language, agi->audio, agi->ctrl); 00803 if (res == 1) /* New command */ 00804 return RESULT_SUCCESS; 00805 fdprintf(agi->fd, "200 result=%d\n", res); 00806 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00807 }
static int handle_saytime | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 746 of file res_agi.c.
References ast_say_time, AGI::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
00747 { 00748 int res; 00749 int num; 00750 if (argc != 4) 00751 return RESULT_SHOWUSAGE; 00752 if (sscanf(argv[2], "%d", &num) != 1) 00753 return RESULT_SHOWUSAGE; 00754 res = ast_say_time(chan, num, argv[3], chan->language); 00755 if (res == 1) 00756 return RESULT_SUCCESS; 00757 fdprintf(agi->fd, "200 result=%d\n", res); 00758 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00759 }
static int handle_sendimage | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 500 of file res_agi.c.
References ast_check_hangup(), ast_send_image(), AGI::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
00501 { 00502 int res; 00503 if (argc != 3) 00504 return RESULT_SHOWUSAGE; 00505 res = ast_send_image(chan, argv[2]); 00506 if (!ast_check_hangup(chan)) 00507 res = 0; 00508 fdprintf(agi->fd, "200 result=%d\n", res); 00509 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00510 }
static int handle_sendtext | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 426 of file res_agi.c.
References ast_sendtext(), AGI::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
00427 { 00428 int res; 00429 if (argc != 3) 00430 return RESULT_SHOWUSAGE; 00431 /* At the moment, the parser (perhaps broken) returns with 00432 the last argument PLUS the newline at the end of the input 00433 buffer. This probably needs to be fixed, but I wont do that 00434 because other stuff may break as a result. The right way 00435 would probably be to strip off the trailing newline before 00436 parsing, then here, add a newline at the end of the string 00437 before sending it to ast_sendtext --DUDE */ 00438 res = ast_sendtext(chan, argv[2]); 00439 fdprintf(agi->fd, "200 result=%d\n", res); 00440 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00441 }
static int handle_setcallerid | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 1119 of file res_agi.c.
References ast_callerid_parse(), ast_set_callerid(), ast_shrink_phone_number(), AGI::fd, fdprintf, and RESULT_SUCCESS.
01120 { 01121 char tmp[256]=""; 01122 char *l = NULL, *n = NULL; 01123 01124 if (argv[2]) { 01125 ast_copy_string(tmp, argv[2], sizeof(tmp)); 01126 ast_callerid_parse(tmp, &n, &l); 01127 if (l) 01128 ast_shrink_phone_number(l); 01129 else 01130 l = ""; 01131 if (!n) 01132 n = ""; 01133 ast_set_callerid(chan, l, n, NULL); 01134 } 01135 01136 fdprintf(agi->fd, "200 result=1\n"); 01137 return RESULT_SUCCESS; 01138 }
static int handle_setcontext | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 838 of file res_agi.c.
References ast_channel::context, AGI::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
00839 { 00840 00841 if (argc != 3) 00842 return RESULT_SHOWUSAGE; 00843 ast_copy_string(chan->context, argv[2], sizeof(chan->context)); 00844 fdprintf(agi->fd, "200 result=0\n"); 00845 return RESULT_SUCCESS; 00846 }
static int handle_setextension | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 848 of file res_agi.c.
References ast_channel::exten, AGI::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
00849 { 00850 if (argc != 3) 00851 return RESULT_SHOWUSAGE; 00852 ast_copy_string(chan->exten, argv[2], sizeof(chan->exten)); 00853 fdprintf(agi->fd, "200 result=0\n"); 00854 return RESULT_SUCCESS; 00855 }
static int handle_setmusic | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1346 of file res_agi.c.
References ast_moh_start(), ast_moh_stop(), AGI::fd, fdprintf, and RESULT_SUCCESS.
01347 { 01348 if (!strncasecmp(argv[2], "on", 2)) 01349 ast_moh_start(chan, argc > 3 ? argv[3] : NULL, NULL); 01350 else if (!strncasecmp(argv[2], "off", 3)) 01351 ast_moh_stop(chan); 01352 fdprintf(agi->fd, "200 result=0\n"); 01353 return RESULT_SUCCESS; 01354 }
static int handle_setpriority | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 857 of file res_agi.c.
References ast_explicit_goto(), ast_findlabel_extension(), ast_channel::cid, ast_callerid::cid_num, ast_channel::context, ast_channel::exten, AGI::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
00858 { 00859 int pri; 00860 if (argc != 3) 00861 return RESULT_SHOWUSAGE; 00862 00863 if (sscanf(argv[2], "%d", &pri) != 1) { 00864 if ((pri = ast_findlabel_extension(chan, chan->context, chan->exten, argv[2], chan->cid.cid_num)) < 1) 00865 return RESULT_SHOWUSAGE; 00866 } 00867 00868 ast_explicit_goto(chan, NULL, NULL, pri); 00869 fdprintf(agi->fd, "200 result=0\n"); 00870 return RESULT_SUCCESS; 00871 }
static int handle_setvariable | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 1163 of file res_agi.c.
References AGI::fd, fdprintf, pbx_builtin_setvar_helper(), and RESULT_SUCCESS.
01164 { 01165 if (argv[3]) 01166 pbx_builtin_setvar_helper(chan, argv[2], argv[3]); 01167 01168 fdprintf(agi->fd, "200 result=1\n"); 01169 return RESULT_SUCCESS; 01170 }
static int handle_showagi | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1912 of file res_agi.c.
References ast_cli(), ast_join(), find_command(), help_workhorse(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and agi_command::usage.
01913 { 01914 struct agi_command *e; 01915 char fullcmd[80]; 01916 if ((argc < 2)) 01917 return RESULT_SHOWUSAGE; 01918 if (argc > 2) { 01919 e = find_command(argv + 2, 1); 01920 if (e) 01921 ast_cli(fd, e->usage); 01922 else { 01923 if (find_command(argv + 2, -1)) { 01924 return help_workhorse(fd, argv + 1); 01925 } else { 01926 ast_join(fullcmd, sizeof(fullcmd), argv+1); 01927 ast_cli(fd, "No such command '%s'.\n", fullcmd); 01928 } 01929 } 01930 } else { 01931 return help_workhorse(fd, NULL); 01932 } 01933 return RESULT_SUCCESS; 01934 }
static int handle_streamfile | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 554 of file res_agi.c.
References ast_applystream(), ast_log(), ast_openstream(), ast_openvstream(), ast_playstream(), ast_seekstream(), ast_stopstream(), ast_tellstream(), ast_verbose(), ast_waitstream_full(), AGI::audio, AGI::ctrl, AGI::fd, fdprintf, LOG_DEBUG, option_verbose, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, ast_channel::stream, VERBOSE_PREFIX_3, and ast_filestream::vfs.
00555 { 00556 int res; 00557 int vres; 00558 struct ast_filestream *fs; 00559 struct ast_filestream *vfs; 00560 long sample_offset = 0; 00561 long max_length; 00562 char *edigits = ""; 00563 00564 if (argc < 4 || argc > 5) 00565 return RESULT_SHOWUSAGE; 00566 00567 if (argv[3]) 00568 edigits = argv[3]; 00569 00570 if ((argc > 4) && (sscanf(argv[4], "%ld", &sample_offset) != 1)) 00571 return RESULT_SHOWUSAGE; 00572 00573 fs = ast_openstream(chan, argv[2], chan->language); 00574 00575 if (!fs) { 00576 fdprintf(agi->fd, "200 result=%d endpos=%ld\n", 0, sample_offset); 00577 return RESULT_SUCCESS; 00578 } 00579 vfs = ast_openvstream(chan, argv[2], chan->language); 00580 if (vfs) 00581 ast_log(LOG_DEBUG, "Ooh, found a video stream, too\n"); 00582 00583 if (option_verbose > 2) 00584 ast_verbose(VERBOSE_PREFIX_3 "Playing '%s' (escape_digits=%s) (sample_offset %ld)\n", argv[2], edigits, sample_offset); 00585 00586 ast_seekstream(fs, 0, SEEK_END); 00587 max_length = ast_tellstream(fs); 00588 ast_seekstream(fs, sample_offset, SEEK_SET); 00589 res = ast_applystream(chan, fs); 00590 if (vfs) 00591 vres = ast_applystream(chan, vfs); 00592 ast_playstream(fs); 00593 if (vfs) 00594 ast_playstream(vfs); 00595 00596 res = ast_waitstream_full(chan, argv[3], agi->audio, agi->ctrl); 00597 /* this is to check for if ast_waitstream closed the stream, we probably are at 00598 * the end of the stream, return that amount, else check for the amount */ 00599 sample_offset = (chan->stream) ? ast_tellstream(fs) : max_length; 00600 ast_stopstream(chan); 00601 if (res == 1) { 00602 /* Stop this command, don't print a result line, as there is a new command */ 00603 return RESULT_SUCCESS; 00604 } 00605 fdprintf(agi->fd, "200 result=%d endpos=%ld\n", res, sample_offset); 00606 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00607 }
static int handle_tddmode | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 479 of file res_agi.c.
References ast_channel_setoption(), AST_OPTION_TDD, AGI::fd, fdprintf, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
00480 { 00481 int res,x; 00482 if (argc != 3) 00483 return RESULT_SHOWUSAGE; 00484 if (!strncasecmp(argv[2],"on",2)) 00485 x = 1; 00486 else 00487 x = 0; 00488 if (!strncasecmp(argv[2],"mate",4)) 00489 x = 2; 00490 if (!strncasecmp(argv[2],"tdd",3)) 00491 x = 1; 00492 res = ast_channel_setoption(chan, AST_OPTION_TDD, &x, sizeof(char), 0); 00493 if (res != RESULT_SUCCESS) 00494 fdprintf(agi->fd, "200 result=0\n"); 00495 else 00496 fdprintf(agi->fd, "200 result=1\n"); 00497 return RESULT_SUCCESS; 00498 }
static int handle_verbose | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 1218 of file res_agi.c.
References ast_verbose(), ast_channel::data, AGI::fd, fdprintf, option_verbose, prefix, RESULT_SHOWUSAGE, RESULT_SUCCESS, VERBOSE_PREFIX_1, VERBOSE_PREFIX_2, VERBOSE_PREFIX_3, and VERBOSE_PREFIX_4.
01219 { 01220 int level = 0; 01221 char *prefix; 01222 01223 if (argc < 2) 01224 return RESULT_SHOWUSAGE; 01225 01226 if (argv[2]) 01227 sscanf(argv[2], "%d", &level); 01228 01229 switch (level) { 01230 case 4: 01231 prefix = VERBOSE_PREFIX_4; 01232 break; 01233 case 3: 01234 prefix = VERBOSE_PREFIX_3; 01235 break; 01236 case 2: 01237 prefix = VERBOSE_PREFIX_2; 01238 break; 01239 case 1: 01240 default: 01241 prefix = VERBOSE_PREFIX_1; 01242 break; 01243 } 01244 01245 if (level <= option_verbose) 01246 ast_verbose("%s %s: %s\n", prefix, chan->data, argv[1]); 01247 01248 fdprintf(agi->fd, "200 result=1\n"); 01249 01250 return RESULT_SUCCESS; 01251 }
static int handle_waitfordigit | ( | struct ast_channel * | chan, | |
AGI * | agi, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 413 of file res_agi.c.
References ast_waitfordigit_full(), AGI::audio, AGI::ctrl, AGI::fd, fdprintf, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
00414 { 00415 int res; 00416 int to; 00417 if (argc != 4) 00418 return RESULT_SHOWUSAGE; 00419 if (sscanf(argv[3], "%d", &to) != 1) 00420 return RESULT_SHOWUSAGE; 00421 res = ast_waitfordigit_full(chan, to, agi->audio, agi->ctrl); 00422 fdprintf(agi->fd, "200 result=%d\n", res); 00423 return (res >= 0) ? RESULT_SUCCESS : RESULT_FAILURE; 00424 }
static int help_workhorse | ( | int | fd, | |
char * | match[] | |||
) | [static] |
Definition at line 1643 of file res_agi.c.
References ast_cli(), ast_join(), agi_command::cmda, and agi_command::summary.
01644 { 01645 char fullcmd[80]; 01646 char matchstr[80]; 01647 int x; 01648 struct agi_command *e; 01649 if (match) 01650 ast_join(matchstr, sizeof(matchstr), match); 01651 for (x=0;x<sizeof(commands)/sizeof(commands[0]);x++) { 01652 e = &commands[x]; 01653 if (!e->cmda[0]) 01654 break; 01655 /* Hide commands that start with '_' */ 01656 if ((e->cmda[0])[0] == '_') 01657 continue; 01658 ast_join(fullcmd, sizeof(fullcmd), e->cmda); 01659 if (match && strncasecmp(matchstr, fullcmd, strlen(matchstr))) 01660 continue; 01661 ast_cli(fd, "%20.20s %s\n", fullcmd, e->summary); 01662 } 01663 return 0; 01664 }
static enum agi_result launch_netscript | ( | char * | agiurl, | |
char * | argv[], | |||
int * | fds, | |||
int * | efd, | |||
int * | opid | |||
) | [static] |
Definition at line 141 of file res_agi.c.
References AGI_PORT, AGI_RESULT_FAILURE, AGI_RESULT_SUCCESS, ast_gethostbyname(), ast_log(), ast_strdupa, ast_strlen_zero(), pollfd::events, pollfd::fd, fdprintf, hp, LOG_DEBUG, LOG_WARNING, MAX_AGI_CONNECT, option_debug, poll(), POLLOUT, and s.
Referenced by launch_script().
00142 { 00143 int s; 00144 int flags; 00145 struct pollfd pfds[1]; 00146 char *host; 00147 char *c; int port = AGI_PORT; 00148 char *script=""; 00149 struct sockaddr_in sin; 00150 struct hostent *hp; 00151 struct ast_hostent ahp; 00152 int res; 00153 00154 /* agiusl is "agi://host.domain[:port][/script/name]" */ 00155 host = ast_strdupa(agiurl + 6); /* Remove agi:// */ 00156 /* Strip off any script name */ 00157 if ((c = strchr(host, '/'))) { 00158 *c = '\0'; 00159 c++; 00160 script = c; 00161 } 00162 if ((c = strchr(host, ':'))) { 00163 *c = '\0'; 00164 c++; 00165 port = atoi(c); 00166 } 00167 if (efd) { 00168 ast_log(LOG_WARNING, "AGI URI's don't support Enhanced AGI yet\n"); 00169 return -1; 00170 } 00171 hp = ast_gethostbyname(host, &ahp); 00172 if (!hp) { 00173 ast_log(LOG_WARNING, "Unable to locate host '%s'\n", host); 00174 return -1; 00175 } 00176 s = socket(AF_INET, SOCK_STREAM, 0); 00177 if (s < 0) { 00178 ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno)); 00179 return -1; 00180 } 00181 flags = fcntl(s, F_GETFL); 00182 if (flags < 0) { 00183 ast_log(LOG_WARNING, "Fcntl(F_GETFL) failed: %s\n", strerror(errno)); 00184 close(s); 00185 return -1; 00186 } 00187 if (fcntl(s, F_SETFL, flags | O_NONBLOCK) < 0) { 00188 ast_log(LOG_WARNING, "Fnctl(F_SETFL) failed: %s\n", strerror(errno)); 00189 close(s); 00190 return -1; 00191 } 00192 memset(&sin, 0, sizeof(sin)); 00193 sin.sin_family = AF_INET; 00194 sin.sin_port = htons(port); 00195 memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr)); 00196 if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) && (errno != EINPROGRESS)) { 00197 ast_log(LOG_WARNING, "Connect failed with unexpected error: %s\n", strerror(errno)); 00198 close(s); 00199 return AGI_RESULT_FAILURE; 00200 } 00201 00202 pfds[0].fd = s; 00203 pfds[0].events = POLLOUT; 00204 while ((res = poll(pfds, 1, MAX_AGI_CONNECT)) != 1) { 00205 if (errno != EINTR) { 00206 if (!res) { 00207 ast_log(LOG_WARNING, "FastAGI connection to '%s' timed out after MAX_AGI_CONNECT (%d) milliseconds.\n", 00208 agiurl, MAX_AGI_CONNECT); 00209 } else 00210 ast_log(LOG_WARNING, "Connect to '%s' failed: %s\n", agiurl, strerror(errno)); 00211 close(s); 00212 return AGI_RESULT_FAILURE; 00213 } 00214 } 00215 00216 if (fdprintf(s, "agi_network: yes\n") < 0) { 00217 if (errno != EINTR) { 00218 ast_log(LOG_WARNING, "Connect to '%s' failed: %s\n", agiurl, strerror(errno)); 00219 close(s); 00220 return AGI_RESULT_FAILURE; 00221 } 00222 } 00223 00224 /* If we have a script parameter, relay it to the fastagi server */ 00225 if (!ast_strlen_zero(script)) 00226 fdprintf(s, "agi_network_script: %s\n", script); 00227 00228 if (option_debug > 3) 00229 ast_log(LOG_DEBUG, "Wow, connected!\n"); 00230 fds[0] = s; 00231 fds[1] = s; 00232 *opid = -1; 00233 return AGI_RESULT_SUCCESS; 00234 }
static enum agi_result launch_script | ( | char * | script, | |
char * | argv[], | |||
int * | fds, | |||
int * | efd, | |||
int * | opid | |||
) | [static] |
Definition at line 236 of file res_agi.c.
References AGI_RESULT_FAILURE, AGI_RESULT_SUCCESS, ast_config_AST_AGI_DIR, ast_config_AST_CONFIG_DIR, ast_config_AST_CONFIG_FILE, ast_config_AST_DATA_DIR, ast_config_AST_KEY_DIR, ast_config_AST_LOG_DIR, ast_config_AST_MODULE_DIR, ast_config_AST_MONITOR_DIR, ast_config_AST_RUN_DIR, ast_config_AST_SPOOL_DIR, ast_config_AST_VAR_DIR, ast_log(), ast_set_priority(), ast_verbose(), launch_netscript(), LOG_WARNING, option_verbose, setenv(), and VERBOSE_PREFIX_3.
Referenced by agi_exec_full().
00237 { 00238 char tmp[256]; 00239 int pid; 00240 int toast[2]; 00241 int fromast[2]; 00242 int audio[2]; 00243 int x; 00244 int res; 00245 sigset_t signal_set, old_set; 00246 00247 if (!strncasecmp(script, "agi://", 6)) 00248 return launch_netscript(script, argv, fds, efd, opid); 00249 00250 if (script[0] != '/') { 00251 snprintf(tmp, sizeof(tmp), "%s/%s", (char *)ast_config_AST_AGI_DIR, script); 00252 script = tmp; 00253 } 00254 if (pipe(toast)) { 00255 ast_log(LOG_WARNING, "Unable to create toast pipe: %s\n",strerror(errno)); 00256 return AGI_RESULT_FAILURE; 00257 } 00258 if (pipe(fromast)) { 00259 ast_log(LOG_WARNING, "unable to create fromast pipe: %s\n", strerror(errno)); 00260 close(toast[0]); 00261 close(toast[1]); 00262 return AGI_RESULT_FAILURE; 00263 } 00264 if (efd) { 00265 if (pipe(audio)) { 00266 ast_log(LOG_WARNING, "unable to create audio pipe: %s\n", strerror(errno)); 00267 close(fromast[0]); 00268 close(fromast[1]); 00269 close(toast[0]); 00270 close(toast[1]); 00271 return AGI_RESULT_FAILURE; 00272 } 00273 res = fcntl(audio[1], F_GETFL); 00274 if (res > -1) 00275 res = fcntl(audio[1], F_SETFL, res | O_NONBLOCK); 00276 if (res < 0) { 00277 ast_log(LOG_WARNING, "unable to set audio pipe parameters: %s\n", strerror(errno)); 00278 close(fromast[0]); 00279 close(fromast[1]); 00280 close(toast[0]); 00281 close(toast[1]); 00282 close(audio[0]); 00283 close(audio[1]); 00284 return AGI_RESULT_FAILURE; 00285 } 00286 } 00287 00288 /* Block SIGHUP during the fork - prevents a race */ 00289 sigfillset(&signal_set); 00290 pthread_sigmask(SIG_BLOCK, &signal_set, &old_set); 00291 pid = fork(); 00292 if (pid < 0) { 00293 ast_log(LOG_WARNING, "Failed to fork(): %s\n", strerror(errno)); 00294 pthread_sigmask(SIG_SETMASK, &old_set, NULL); 00295 return AGI_RESULT_FAILURE; 00296 } 00297 if (!pid) { 00298 /* Pass paths to AGI via environmental variables */ 00299 setenv("AST_CONFIG_DIR", ast_config_AST_CONFIG_DIR, 1); 00300 setenv("AST_CONFIG_FILE", ast_config_AST_CONFIG_FILE, 1); 00301 setenv("AST_MODULE_DIR", ast_config_AST_MODULE_DIR, 1); 00302 setenv("AST_SPOOL_DIR", ast_config_AST_SPOOL_DIR, 1); 00303 setenv("AST_MONITOR_DIR", ast_config_AST_MONITOR_DIR, 1); 00304 setenv("AST_VAR_DIR", ast_config_AST_VAR_DIR, 1); 00305 setenv("AST_DATA_DIR", ast_config_AST_DATA_DIR, 1); 00306 setenv("AST_LOG_DIR", ast_config_AST_LOG_DIR, 1); 00307 setenv("AST_AGI_DIR", ast_config_AST_AGI_DIR, 1); 00308 setenv("AST_KEY_DIR", ast_config_AST_KEY_DIR, 1); 00309 setenv("AST_RUN_DIR", ast_config_AST_RUN_DIR, 1); 00310 00311 /* Don't run AGI scripts with realtime priority -- it causes audio stutter */ 00312 ast_set_priority(0); 00313 00314 /* Redirect stdin and out, provide enhanced audio channel if desired */ 00315 dup2(fromast[0], STDIN_FILENO); 00316 dup2(toast[1], STDOUT_FILENO); 00317 if (efd) { 00318 dup2(audio[0], STDERR_FILENO + 1); 00319 } else { 00320 close(STDERR_FILENO + 1); 00321 } 00322 00323 /* Before we unblock our signals, return our trapped signals back to the defaults */ 00324 signal(SIGHUP, SIG_DFL); 00325 signal(SIGCHLD, SIG_DFL); 00326 signal(SIGINT, SIG_DFL); 00327 signal(SIGURG, SIG_DFL); 00328 signal(SIGTERM, SIG_DFL); 00329 signal(SIGPIPE, SIG_DFL); 00330 signal(SIGXFSZ, SIG_DFL); 00331 00332 /* unblock important signal handlers */ 00333 if (pthread_sigmask(SIG_UNBLOCK, &signal_set, NULL)) { 00334 ast_log(LOG_WARNING, "unable to unblock signals for AGI script: %s\n", strerror(errno)); 00335 _exit(1); 00336 } 00337 00338 /* Close everything but stdin/out/error */ 00339 for (x=STDERR_FILENO + 2;x<1024;x++) 00340 close(x); 00341 00342 /* Execute script */ 00343 execv(script, argv); 00344 /* Can't use ast_log since FD's are closed */ 00345 fprintf(stdout, "verbose \"Failed to execute '%s': %s\" 2\n", script, strerror(errno)); 00346 fflush(stdout); 00347 _exit(1); 00348 } 00349 pthread_sigmask(SIG_SETMASK, &old_set, NULL); 00350 if (option_verbose > 2) 00351 ast_verbose(VERBOSE_PREFIX_3 "Launched AGI Script %s\n", script); 00352 fds[0] = toast[0]; 00353 fds[1] = fromast[1]; 00354 if (efd) { 00355 *efd = audio[1]; 00356 } 00357 /* close what we're not using in the parent */ 00358 close(toast[1]); 00359 close(fromast[0]); 00360 00361 if (efd) 00362 close(audio[0]); 00363 00364 *opid = pid; 00365 return AGI_RESULT_SUCCESS; 00366 }
static int load_module | ( | void | ) | [static] |
Definition at line 2146 of file res_agi.c.
References agi_exec(), ast_cli_register_multiple(), ast_register_application(), deadagi_exec(), and eagi_exec().
02147 { 02148 ast_cli_register_multiple(cli_agi, sizeof(cli_agi) / sizeof(struct ast_cli_entry)); 02149 ast_register_application(deadapp, deadagi_exec, deadsynopsis, descrip); 02150 ast_register_application(eapp, eagi_exec, esynopsis, descrip); 02151 return ast_register_application(app, agi_exec, synopsis, descrip); 02152 }
static int parse_args | ( | char * | s, | |
int * | max, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1729 of file res_agi.c.
References ast_log(), LOG_WARNING, and MAX_ARGS.
01730 { 01731 int x=0; 01732 int quoted=0; 01733 int escaped=0; 01734 int whitespace=1; 01735 char *cur; 01736 01737 cur = s; 01738 while(*s) { 01739 switch(*s) { 01740 case '"': 01741 /* If it's escaped, put a literal quote */ 01742 if (escaped) 01743 goto normal; 01744 else 01745 quoted = !quoted; 01746 if (quoted && whitespace) { 01747 /* If we're starting a quote, coming off white space start a new word, too */ 01748 argv[x++] = cur; 01749 whitespace=0; 01750 } 01751 escaped = 0; 01752 break; 01753 case ' ': 01754 case '\t': 01755 if (!quoted && !escaped) { 01756 /* If we're not quoted, mark this as whitespace, and 01757 end the previous argument */ 01758 whitespace = 1; 01759 *(cur++) = '\0'; 01760 } else 01761 /* Otherwise, just treat it as anything else */ 01762 goto normal; 01763 break; 01764 case '\\': 01765 /* If we're escaped, print a literal, otherwise enable escaping */ 01766 if (escaped) { 01767 goto normal; 01768 } else { 01769 escaped=1; 01770 } 01771 break; 01772 default: 01773 normal: 01774 if (whitespace) { 01775 if (x >= MAX_ARGS -1) { 01776 ast_log(LOG_WARNING, "Too many arguments, truncating\n"); 01777 break; 01778 } 01779 /* Coming off of whitespace, start the next argument */ 01780 argv[x++] = cur; 01781 whitespace=0; 01782 } 01783 *(cur++) = *s; 01784 escaped=0; 01785 } 01786 s++; 01787 } 01788 /* Null terminate */ 01789 *(cur++) = '\0'; 01790 argv[x] = NULL; 01791 *max = x; 01792 return 0; 01793 }
static enum agi_result run_agi | ( | struct ast_channel * | chan, | |
char * | request, | |||
AGI * | agi, | |||
int | pid, | |||
int * | status, | |||
int | dead | |||
) | [static] |
Definition at line 1827 of file res_agi.c.
References agi_handle_command(), AGI_RESULT_FAILURE, AGI_RESULT_HANGUP, AGI_RESULT_SUCCESS, ast_false(), AST_FRAME_VOICE, ast_frfree(), ast_log(), AST_PBX_KEEPALIVE, ast_read(), ast_strlen_zero(), ast_verbose(), ast_waitfor_nandfds(), AGI::audio, AGI::ctrl, ast_frame::data, ast_frame::datalen, f, AGI::fd, ast_frame::frametype, LOG_DEBUG, LOG_WARNING, option_verbose, pbx_builtin_getvar_helper(), RETRY, setup_env(), and VERBOSE_PREFIX_3.
Referenced by agi_exec_full().
01828 { 01829 struct ast_channel *c; 01830 int outfd; 01831 int ms; 01832 enum agi_result returnstatus = AGI_RESULT_SUCCESS; 01833 struct ast_frame *f; 01834 char buf[2048]; 01835 FILE *readf; 01836 /* how many times we'll retry if ast_waitfor_nandfs will return without either 01837 channel or file descriptor in case select is interrupted by a system call (EINTR) */ 01838 int retry = RETRY; 01839 01840 if (!(readf = fdopen(agi->ctrl, "r"))) { 01841 ast_log(LOG_WARNING, "Unable to fdopen file descriptor\n"); 01842 if (pid > -1) 01843 kill(pid, SIGHUP); 01844 close(agi->ctrl); 01845 return AGI_RESULT_FAILURE; 01846 } 01847 setlinebuf(readf); 01848 setup_env(chan, request, agi->fd, (agi->audio > -1)); 01849 for (;;) { 01850 ms = -1; 01851 c = ast_waitfor_nandfds(&chan, dead ? 0 : 1, &agi->ctrl, 1, NULL, &outfd, &ms); 01852 if (c) { 01853 retry = RETRY; 01854 /* Idle the channel until we get a command */ 01855 f = ast_read(c); 01856 if (!f) { 01857 ast_log(LOG_DEBUG, "%s hungup\n", chan->name); 01858 returnstatus = AGI_RESULT_HANGUP; 01859 break; 01860 } else { 01861 /* If it's voice, write it to the audio pipe */ 01862 if ((agi->audio > -1) && (f->frametype == AST_FRAME_VOICE)) { 01863 /* Write, ignoring errors */ 01864 write(agi->audio, f->data, f->datalen); 01865 } 01866 ast_frfree(f); 01867 } 01868 } else if (outfd > -1) { 01869 retry = RETRY; 01870 if (!fgets(buf, sizeof(buf), readf)) { 01871 /* Program terminated */ 01872 if (returnstatus) 01873 returnstatus = -1; 01874 if (option_verbose > 2) 01875 ast_verbose(VERBOSE_PREFIX_3 "AGI Script %s completed, returning %d\n", request, returnstatus); 01876 if (pid > 0) 01877 waitpid(pid, status, 0); 01878 /* No need to kill the pid anymore, since they closed us */ 01879 pid = -1; 01880 break; 01881 } 01882 /* get rid of trailing newline, if any */ 01883 if (*buf && buf[strlen(buf) - 1] == '\n') 01884 buf[strlen(buf) - 1] = 0; 01885 if (agidebug) 01886 ast_verbose("AGI Rx << %s\n", buf); 01887 returnstatus |= agi_handle_command(chan, agi, buf); 01888 /* If the handle_command returns -1, we need to stop */ 01889 if ((returnstatus < 0) || (returnstatus == AST_PBX_KEEPALIVE)) { 01890 break; 01891 } 01892 } else { 01893 if (--retry <= 0) { 01894 ast_log(LOG_WARNING, "No channel, no fd?\n"); 01895 returnstatus = AGI_RESULT_FAILURE; 01896 break; 01897 } 01898 } 01899 } 01900 /* Notify process */ 01901 if (pid > -1) { 01902 const char *sighup = pbx_builtin_getvar_helper(chan, "AGISIGHUP"); 01903 if (ast_strlen_zero(sighup) || !ast_false(sighup)) { 01904 if (kill(pid, SIGHUP)) 01905 ast_log(LOG_WARNING, "unable to send SIGHUP to AGI process %d: %s\n", pid, strerror(errno)); 01906 } 01907 } 01908 fclose(readf); 01909 return returnstatus; 01910 }
static void setup_env | ( | struct ast_channel * | chan, | |
char * | request, | |||
int | fd, | |||
int | enhanced | |||
) | [static] |
Definition at line 368 of file res_agi.c.
References ast_channel::cid, ast_callerid::cid_ani2, ast_callerid::cid_dnid, ast_callerid::cid_name, ast_callerid::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, ast_callerid::cid_tns, ast_callerid::cid_ton, ast_channel::context, ast_channel::exten, fdprintf, ast_channel::priority, S_OR, ast_channel::tech, and ast_channel_tech::type.
Referenced by run_agi().
00369 { 00370 /* Print initial environment, with agi_request always being the first 00371 thing */ 00372 fdprintf(fd, "agi_request: %s\n", request); 00373 fdprintf(fd, "agi_channel: %s\n", chan->name); 00374 fdprintf(fd, "agi_language: %s\n", chan->language); 00375 fdprintf(fd, "agi_type: %s\n", chan->tech->type); 00376 fdprintf(fd, "agi_uniqueid: %s\n", chan->uniqueid); 00377 00378 /* ANI/DNIS */ 00379 fdprintf(fd, "agi_callerid: %s\n", S_OR(chan->cid.cid_num, "unknown")); 00380 fdprintf(fd, "agi_calleridname: %s\n", S_OR(chan->cid.cid_name, "unknown")); 00381 fdprintf(fd, "agi_callingpres: %d\n", chan->cid.cid_pres); 00382 fdprintf(fd, "agi_callingani2: %d\n", chan->cid.cid_ani2); 00383 fdprintf(fd, "agi_callington: %d\n", chan->cid.cid_ton); 00384 fdprintf(fd, "agi_callingtns: %d\n", chan->cid.cid_tns); 00385 fdprintf(fd, "agi_dnid: %s\n", S_OR(chan->cid.cid_dnid, "unknown")); 00386 fdprintf(fd, "agi_rdnis: %s\n", S_OR(chan->cid.cid_rdnis, "unknown")); 00387 00388 /* Context information */ 00389 fdprintf(fd, "agi_context: %s\n", chan->context); 00390 fdprintf(fd, "agi_extension: %s\n", chan->exten); 00391 fdprintf(fd, "agi_priority: %d\n", chan->priority); 00392 fdprintf(fd, "agi_enhanced: %s\n", enhanced ? "1.0" : "0.0"); 00393 00394 /* User information */ 00395 fdprintf(fd, "agi_accountcode: %s\n", chan->accountcode ? chan->accountcode : ""); 00396 00397 /* End with empty return */ 00398 fdprintf(fd, "\n"); 00399 }
static int unload_module | ( | void | ) | [static] |
Definition at line 2137 of file res_agi.c.
References ast_cli_unregister_multiple(), ast_module_user_hangup_all, and ast_unregister_application().
02138 { 02139 ast_module_user_hangup_all(); 02140 ast_cli_unregister_multiple(cli_agi, sizeof(cli_agi) / sizeof(struct ast_cli_entry)); 02141 ast_unregister_application(eapp); 02142 ast_unregister_application(deadapp); 02143 return ast_unregister_application(app); 02144 }
struct ast_cli_entry cli_agi[] [static] |
struct ast_cli_entry cli_agi_no_debug_deprecated [static] |
Initial value:
{ { "agi", "no", "debug", NULL }, agi_no_debug_deprecated, NULL, NULL }
struct ast_cli_entry cli_dump_agihtml_deprecated [static] |
Initial value:
{ { "dump", "agihtml", NULL }, handle_agidumphtml, NULL, NULL }
struct ast_cli_entry cli_show_agi_deprecated [static] |
Initial value:
{ { "show", "agi", NULL }, handle_showagi, NULL, NULL }
agi_command commands[MAX_COMMANDS] [static] |
Definition at line 1603 of file res_agi.c.
Referenced by aji_dinfo_handler(), and dundi_showframe().
char* deadsynopsis = "Executes AGI on a hungup channel" [static] |
char debug_usage[] [static] |
char dumpagihtml_help[] [static] |
char* esynopsis = "Executes an EAGI compliant application" [static] |
char no_debug_usage[] [static] |
char showagi_help[] [static] |
char usage_answer[] [static] |
char usage_autohangup[] [static] |
Initial value:
" Usage: SET AUTOHANGUP <time>\n" " Cause the channel to automatically hangup at <time> seconds in the\n" " future. Of course it can be hungup before then as well. Setting to 0 will\n" " cause the autohangup feature to be disabled on this channel.\n"
char usage_channelstatus[] [static] |
char usage_controlstreamfile[] [static] |
char usage_dbdel[] [static] |
char usage_dbdeltree[] [static] |
char usage_dbget[] [static] |
char usage_dbput[] [static] |
char usage_exec[] [static] |
char usage_getdata[] [static] |
char usage_getoption[] [static] |
char usage_getvariable[] [static] |
char usage_getvariablefull[] [static] |
char usage_hangup[] [static] |
char usage_noop[] [static] |
char usage_recordfile[] [static] |
char usage_recvchar[] [static] |
char usage_recvtext[] [static] |
Initial value:
" Usage: RECEIVE TEXT <timeout>\n" " Receives a string of text on a channel. Specify timeout to be the\n" " maximum time to wait for input in milliseconds, or 0 for infinite. Most channels\n" " do not support the reception of text. Returns -1 for failure or 1 for success, and the string in parentheses.\n"
char usage_sayalpha[] [static] |
char usage_saydate[] [static] |
char usage_saydatetime[] [static] |
char usage_saydigits[] [static] |
char usage_saynumber[] [static] |
char usage_sayphonetic[] [static] |
char usage_saytime[] [static] |
char usage_sendimage[] [static] |
char usage_sendtext[] [static] |
char usage_setcallerid[] [static] |
char usage_setcontext[] [static] |
char usage_setextension[] [static] |
char usage_setmusic[] [static] |
char usage_setpriority[] [static] |
char usage_setvariable[] [static] |
char usage_streamfile[] [static] |
char usage_tddmode[] [static] |
char usage_verbose[] [static] |
char usage_waitfordigit[] [static] |