Index: apps/app_read.c
===================================================================
RCS file: /usr/cvsroot/asterisk/apps/app_read.c,v
retrieving revision 1.9
diff -u -r1.9 app_read.c
--- apps/app_read.c	2 Sep 2004 13:52:58 -0000	1.9
+++ apps/app_read.c	10 Dec 2004 04:00:10 -0000
@@ -31,9 +31,9 @@
 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"
@@ -41,40 +41,69 @@
 "                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;
 
+#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];
-	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 tries = 1;
+	int to = 0;
 	if (!data || ast_strlen_zero((char *)data)) {
 		ast_log(LOG_WARNING, "Read requires an argument (variable)\n");
 		return -1;
 	}
-	strncpy(argdata, (char *)data, sizeof(argdata)-1);
-	stringp=argdata;
-	varname = strsep(&stringp, "|");
-	filename = strsep(&stringp, "|");
-	maxdigitstr = strsep(&stringp,"|");
-	options = strsep(&stringp, "|");
+	if((varname = ast_strdupa((char *)data))) {
+		ast_next_data(varname,filename,'|');
+		if(filename) {
+			ast_next_data(filename,maxdigitstr,'|');
+			if(maxdigitstr) {
+				ast_next_data(maxdigitstr,options,'|');
+				if(options) {
+					ast_next_data(options,loops,'|');
+					if(loops)
+						ast_next_data(loops,timeout,'|');
+				}
+			}
+		}
+		
+	}
+
 	if (options && !strcasecmp(options, "skip"))
 		option_skip = 1;
 	if (options && !strcasecmp(options, "noanswer"))
 		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) {
@@ -82,8 +111,8 @@
 	    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;
@@ -101,13 +130,17 @@
 		}
 	}
 	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);
-		} else {
-			ast_verbose(VERBOSE_PREFIX_3 "User entered nothing\n");
+		while(tries) {
+			ast_stopstream(chan);
+			res = ast_app_getdata(chan, filename, tmp, maxdigits, to ? to * 1000 : 0);
+			if (tmp && !ast_strlen_zero(tmp)) {
+				pbx_builtin_setvar_helper(chan, varname, tmp);
+				ast_verbose(VERBOSE_PREFIX_3 "User entered '%s'\n", tmp);
+				tries = 0;
+			} else {
+				tries--;
+				ast_verbose(VERBOSE_PREFIX_3 "User entered nothing %d tries left\n",tries);
+			}
 		}
 	}
 	LOCAL_USER_REMOVE(u);
