Merge anthm's app_read addition, somewhat modified (bug #3013)

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@4587 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Mark Spencer
2004-12-29 13:06:53 +00:00
parent ed18567073
commit 118b47674f
2 changed files with 92 additions and 31 deletions

15
app.c
View File

@@ -1070,3 +1070,18 @@ int ast_app_group_match_get_count(char *groupmatch, char *category)
return count; return count;
} }
int ast_seperate_app_args(char *buf, char delim, char **array, int arraylen)
{
int x = 0;
memset(array, 0, arraylen * sizeof(char *));
if (!buf)
return 0;
for (array[x] = buf ; x < arraylen && array[x]; x++) {
if ((array[x+1] = strchr(array[x], delim))) {
*array[x+1] = '\0';
array[x+1]++;
}
}
return x;
}

View File

@@ -31,9 +31,9 @@ static char *app = "Read";
static char *synopsis = "Read a variable"; static char *synopsis = "Read a variable";
static char *descrip = static char *descrip =
" Read(variable[|filename][|maxdigits][|option])\n\n" " Read(variable[|filename][|maxdigits][|option][|attempts][|timeout])\n\n"
"Reads a #-terminated string of digits from the user in to the given variable,\n" "Reads a #-terminated string of digits a certian number of times from the\n"
"optionally playing a given filename first.\n" "user in to the given variable, optionally playing a given filename first.\n"
" maxdigits -- maximum acceptable number of digits. Stops reading after\n" " maxdigits -- maximum acceptable number of digits. Stops reading after\n"
" maxdigits have been entered (without requiring the user to\n" " maxdigits have been entered (without requiring the user to\n"
" press the '#' key).\n" " press the '#' key).\n"
@@ -41,40 +41,75 @@ static char *descrip =
" Any value below 0 means the same. Max accepted value is 255.\n" " Any value below 0 means the same. Max accepted value is 255.\n"
" option -- may be 'skip' to return immediately if the line is not up,\n" " option -- may be 'skip' to return immediately if the line is not up,\n"
" or 'noanswer' to read digits even if the line is not up.\n\n" " or 'noanswer' to read digits even if the line is not up.\n\n"
"If attempts is greater than 1, that many attempts will be made in the event no data is entered.\n"
"If timeout is greater than 0, that value will override the default timeout.\n\n"
"Returns -1 on hangup or error and 0 otherwise.\n"; "Returns -1 on hangup or error and 0 otherwise.\n";
STANDARD_LOCAL_USER; STANDARD_LOCAL_USER;
LOCAL_USER_DECL; LOCAL_USER_DECL;
#define ast_next_data(instr,ptr,delim) if((ptr=strchr(instr,delim))) { *(ptr) = '\0' ; ptr++;}
static int read_exec(struct ast_channel *chan, void *data) static int read_exec(struct ast_channel *chan, void *data)
{ {
int res = 0; int res = 0;
struct localuser *u; struct localuser *u;
char tmp[256]; char tmp[256];
char argdata[256] = ""; char *timeout = NULL;
char *varname; char *varname = NULL;
char *filename; char *filename = NULL;
char *stringp; char *loops;
char *maxdigitstr; char *maxdigitstr=NULL;
char *options; char *options=NULL;
int option_skip = 0; int option_skip = 0;
int option_noanswer = 0; int option_noanswer = 0;
int maxdigits=255; int maxdigits=255;
if (!data || ast_strlen_zero((char *)data)) { int tries = 1;
ast_log(LOG_WARNING, "Read requires an argument (variable)\n"); int to = 0;
int defined = 0, x = 0;
char *argcopy;
char *args[8];
if (data)
argcopy = ast_strdupa((char *)data);
if (ast_seperate_app_args(argcopy, '|', args, sizeof(args) / sizeof(args[0])) < 1) {
ast_log(LOG_WARNING, "Cannot Parse Arguements.\n");
return -1; return -1;
} }
strncpy(argdata, (char *)data, sizeof(argdata)-1);
stringp=argdata; varname = args[x++];
varname = strsep(&stringp, "|"); filename = args[x++];
filename = strsep(&stringp, "|"); maxdigitstr = args[x++];
maxdigitstr = strsep(&stringp,"|"); options = args[x++];
options = strsep(&stringp, "|"); loops = args[x++];
if (options && !strcasecmp(options, "skip"))
if (options) {
if (!strcasecmp(options, "skip"))
option_skip = 1; option_skip = 1;
if (options && !strcasecmp(options, "noanswer")) else if (!strcasecmp(options, "noanswer"))
option_noanswer = 1; option_noanswer = 1;
else {
if (strchr(options, 's'))
option_skip = 1;
if (strchr(options, 'n'))
option_noanswer = 1;
}
}
if(loops) {
tries = atoi(loops);
if(tries <= 0)
tries = 1;
}
if(timeout) {
to = atoi(timeout);
if(to <= 0)
to = 0;
}
if (!(filename) || ast_strlen_zero(filename)) if (!(filename) || ast_strlen_zero(filename))
filename = NULL; filename = NULL;
if (maxdigitstr) { if (maxdigitstr) {
@@ -101,16 +136,27 @@ static int read_exec(struct ast_channel *chan, void *data)
} }
} }
if (!res) { if (!res) {
while(tries && !res) {
ast_stopstream(chan); ast_stopstream(chan);
res = ast_app_getdata(chan, filename, tmp, maxdigits, 0); res = ast_app_getdata(chan, filename, tmp, maxdigits, 0);
if (res > -1) { if (res > -1) {
pbx_builtin_setvar_helper(chan, varname, tmp); pbx_builtin_setvar_helper(chan, varname, tmp);
if (!ast_strlen_zero(tmp)) {
ast_verbose(VERBOSE_PREFIX_3 "User entered '%s'\n", tmp); ast_verbose(VERBOSE_PREFIX_3 "User entered '%s'\n", tmp);
tries = 0;
} else {
tries--;
if (tries)
ast_verbose(VERBOSE_PREFIX_3 "User entered nothing, %d chance(s) left\n", tries);
else
ast_verbose(VERBOSE_PREFIX_3 "User entered nothing.\n");
}
res = 0; res = 0;
} else { } else {
ast_verbose(VERBOSE_PREFIX_3 "User disconnected\n"); ast_verbose(VERBOSE_PREFIX_3 "User disconnected\n");
} }
} }
}
LOCAL_USER_REMOVE(u); LOCAL_USER_REMOVE(u);
return res; return res;
} }