Merge anthm's app_read addition, somewhat modified (bug #3013)
authorMark Spencer <markster@digium.com>
Wed, 29 Dec 2004 13:06:53 +0000 (13:06 +0000)
committerMark Spencer <markster@digium.com>
Wed, 29 Dec 2004 13:06:53 +0000 (13:06 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@4587 65c4cc65-6c06-0410-ace0-fbb531ad65f3

app.c
apps/app_read.c

diff --git a/app.c b/app.c
index dc078ce..c910605 100755 (executable)
--- a/app.c
+++ b/app.c
@@ -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;
+}
index e915138..e8bd662 100755 (executable)
@@ -31,9 +31,9 @@ static char *app = "Read";
 static char *synopsis = "Read a variable";
 
 static char *descrip = 
 static char *synopsis = "Read a variable";
 
 static char *descrip = 
-"  Read(variable[|filename][|maxdigits][|option])\n\n"
-"Reads a #-terminated string of digits from the user in to the given variable,\n"
-"optionally playing a given filename first.\n"
+"  Read(variable[|filename][|maxdigits][|option][|attempts][|timeout])\n\n"
+"Reads a #-terminated string of digits a certian number of times from the\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 have been entered (without requiring the user to\n"
 "                press the '#' key).\n"
 "  maxdigits  -- maximum acceptable number of digits. Stops reading after\n"
 "                maxdigits have been entered (without requiring the user to\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"
 "  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"
 "                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"
 "                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";
 
 STANDARD_LOCAL_USER;
 
 LOCAL_USER_DECL;
 
 "Returns -1 on hangup or error and 0 otherwise.\n";
 
 STANDARD_LOCAL_USER;
 
 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)
 {
        int res = 0;
        struct localuser *u;
        char tmp[256];
 static int read_exec(struct ast_channel *chan, void *data)
 {
        int res = 0;
        struct localuser *u;
        char tmp[256];
-       char argdata[256] = "";
-       char *varname;
-       char *filename;
-       char *stringp;
-       char *maxdigitstr;
-       char *options;
+       char *timeout = NULL;
+       char *varname = NULL;
+       char *filename = NULL;
+       char *loops;
+       char *maxdigitstr=NULL;
+       char *options=NULL;
        int option_skip = 0;
        int option_noanswer = 0;
        int maxdigits=255;
        int option_skip = 0;
        int option_noanswer = 0;
        int maxdigits=255;
-       if (!data || ast_strlen_zero((char *)data)) {
-               ast_log(LOG_WARNING, "Read requires an argument (variable)\n");
+       int tries = 1;
+       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 = strsep(&stringp, "|");
-       filename = strsep(&stringp, "|");
-       maxdigitstr = strsep(&stringp,"|");
-       options = strsep(&stringp, "|");
-       if (options && !strcasecmp(options, "skip"))
-               option_skip = 1;
-       if (options && !strcasecmp(options, "noanswer"))
-               option_noanswer = 1;
+
+       varname = args[x++];
+       filename = args[x++];
+       maxdigitstr = args[x++];
+       options = args[x++];
+       loops = args[x++];
+       
+       if (options) { 
+               if (!strcasecmp(options, "skip"))
+                       option_skip = 1;
+               else if (!strcasecmp(options, "noanswer"))
+                       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)) 
                filename = NULL;
        if (maxdigitstr) {
        if (!(filename) || ast_strlen_zero(filename)) 
                filename = NULL;
        if (maxdigitstr) {
@@ -82,8 +117,8 @@ static int read_exec(struct ast_channel *chan, void *data)
            if ((maxdigits<1) || (maxdigits>255)) {
                maxdigits = 255;
            } else
            if ((maxdigits<1) || (maxdigits>255)) {
                maxdigits = 255;
            } else
-               ast_verbose(VERBOSE_PREFIX_3 "Accepting a maximum of %i digits.\n", maxdigits);
-       }       
+                       ast_verbose(VERBOSE_PREFIX_3 "Accepting a maximum of %i digits.\n", maxdigits);
+       }
        if (!(varname) || ast_strlen_zero(varname)) {
                ast_log(LOG_WARNING, "Read requires an variable name\n");
                return -1;
        if (!(varname) || ast_strlen_zero(varname)) {
                ast_log(LOG_WARNING, "Read requires an variable name\n");
                return -1;
@@ -101,14 +136,25 @@ static int read_exec(struct ast_channel *chan, void *data)
                }
        }
        if (!res) {
                }
        }
        if (!res) {
-               ast_stopstream(chan);
-               res = ast_app_getdata(chan, filename, tmp, maxdigits, 0);
-               if (res > -1) {
-                       pbx_builtin_setvar_helper(chan, varname, tmp);
-                       ast_verbose(VERBOSE_PREFIX_3 "User entered '%s'\n", tmp);
-                       res = 0;
-               } else {
-                       ast_verbose(VERBOSE_PREFIX_3 "User disconnected\n");
+               while(tries && !res) {
+                       ast_stopstream(chan);
+                       res = ast_app_getdata(chan, filename, tmp, maxdigits, 0);
+                       if (res > -1) {
+                               pbx_builtin_setvar_helper(chan, varname, tmp);
+                               if (!ast_strlen_zero(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;
+                       } else {
+                               ast_verbose(VERBOSE_PREFIX_3 "User disconnected\n");
+                       }
                }
        }
        LOCAL_USER_REMOVE(u);
                }
        }
        LOCAL_USER_REMOVE(u);