? asterisk/app_runexten.diff
? asterisk/apps/app_runexten.c
Index: asterisk/pbx.c
===================================================================
RCS file: /usr/cvsroot/asterisk/pbx.c,v
retrieving revision 1.178
diff -u -3 -r1.178 pbx.c
--- asterisk/pbx.c	25 Nov 2004 02:57:34 -0000	1.178
+++ asterisk/pbx.c	26 Nov 2004 19:37:13 -0000
@@ -1875,177 +1875,179 @@
 	c->pbx->rtimeout = 10;
 	c->pbx->dtimeout = 5;
 
-	/* Start by trying whatever the channel is set to */
-	if (!ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) {
-		/* JK02: If not successfull fall back to 's' */
-		if (option_verbose > 1)
-			ast_verbose( VERBOSE_PREFIX_2 "Starting %s at %s,%s,%d failed so falling back to exten 's'\n", c->name, c->context, c->exten, c->priority);
-		strncpy(c->exten, "s", sizeof(c->exten)-1);
+	if (!ast_check_hangup(c)) {
+		/* Start by trying whatever the channel is set to */
 		if (!ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) {
-			/* JK02: And finally back to default if everything else failed */
+			/* JK02: If not successfull fall back to 's' */
 			if (option_verbose > 1)
-				ast_verbose( VERBOSE_PREFIX_2 "Starting %s at %s,%s,%d still failed so falling back to context 'default'\n", c->name, c->context, c->exten, c->priority);
-			strncpy(c->context, "default", sizeof(c->context)-1);
+				ast_verbose( VERBOSE_PREFIX_2 "Starting %s at %s,%s,%d failed so falling back to exten 's'\n", c->name, c->context, c->exten, c->priority);
+			strncpy(c->exten, "s", sizeof(c->exten)-1);
+			if (!ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) {
+				/* JK02: And finally back to default if everything else failed */
+				if (option_verbose > 1)
+					ast_verbose( VERBOSE_PREFIX_2 "Starting %s at %s,%s,%d still failed so falling back to context 'default'\n", c->name, c->context, c->exten, c->priority);
+				strncpy(c->context, "default", sizeof(c->context)-1);
+			}
+			c->priority = 1;
 		}
-		c->priority = 1;
-	}
-	if (c->cdr && !c->cdr->start.tv_sec && !c->cdr->start.tv_usec)
-		ast_cdr_start(c->cdr);
-	for(;;) {
-		pos = 0;
-		digit = 0;
-		while(ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) {
-			memset(exten, 0, sizeof(exten));
-			if ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num))) {
-				/* Something bad happened, or a hangup has been requested. */
-				if (((res >= '0') && (res <= '9')) || ((res >= 'A') && (res <= 'F')) ||
-					(res == '*') || (res == '#')) {
-					ast_log(LOG_DEBUG, "Oooh, got something to jump out with ('%c')!\n", res);
-					memset(exten, 0, sizeof(exten));
-					pos = 0;
-					exten[pos++] = digit = res;
-					break;
-				}
-				switch(res) {
-				case AST_PBX_KEEPALIVE:
-					if (option_debug)
-						ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name);
-					else if (option_verbose > 1)
-						ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name);
-					goto out;
-					break;
-				default:
-					if (option_debug)
-						ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
-					else if (option_verbose > 1)
-						ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
-					if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) {
-						c->_softhangup =0;
-						break;
-					}
-					/* atimeout */
-					if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT) {
+		if (c->cdr && !c->cdr->start.tv_sec && !c->cdr->start.tv_usec)
+			ast_cdr_start(c->cdr);
+		for(;;) {
+			pos = 0;
+			digit = 0;
+			while(ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) {
+				memset(exten, 0, sizeof(exten));
+				if ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num))) {
+					/* Something bad happened, or a hangup has been requested. */
+			    		if (((res >= '0') && (res <= '9')) || ((res >= 'A') && (res <= 'F')) ||
+					    (res == '*') || (res == '#')) {
+						ast_log(LOG_DEBUG, "Oooh, got something to jump out with ('%c')!\n", res);
+						memset(exten, 0, sizeof(exten));
+						pos = 0;
+						exten[pos++] = digit = res;
 						break;
 					}
+					switch(res) {
+					case AST_PBX_KEEPALIVE:
+						if (option_debug)
+							ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name);
+						else if (option_verbose > 1)
+							ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name);
+						goto out;
+    						break;
+					default:
+						if (option_debug)
+							ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
+						else if (option_verbose > 1)
+							ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
+						if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) {
+							c->_softhangup =0;
+							break;
+						}
+						/* atimeout */
+						if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT) {
+							break;
+						}
 
-					if (c->cdr) {
-						ast_cdr_update(c);
+						if (c->cdr) {
+							ast_cdr_update(c);
+						}
+						goto out;
 					}
+				}
+				if ((c->_softhangup == AST_SOFTHANGUP_TIMEOUT) && (ast_exists_extension(c,c->context,"T",1,c->cid.cid_num))) {
+					strncpy(c->exten,"T",sizeof(c->exten) - 1);
+			    		/* If the AbsoluteTimeout is not reset to 0, we'll get an infinite loop */
+					c->whentohangup = 0;
+					c->priority = 0;
+					c->_softhangup &= ~AST_SOFTHANGUP_TIMEOUT;
+				} else if (c->_softhangup) {
+					ast_log(LOG_DEBUG, "Extension %s, priority %d returned normally even though call was hung up\n",
+						c->exten, c->priority);
 					goto out;
 				}
+				firstpass = 0;
+				c->priority++;
 			}
-			if ((c->_softhangup == AST_SOFTHANGUP_TIMEOUT) && (ast_exists_extension(c,c->context,"T",1,c->cid.cid_num))) {
-				strncpy(c->exten,"T",sizeof(c->exten) - 1);
-				/* If the AbsoluteTimeout is not reset to 0, we'll get an infinite loop */
-				c->whentohangup = 0;
-				c->priority = 0;
-				c->_softhangup &= ~AST_SOFTHANGUP_TIMEOUT;
-			} else if (c->_softhangup) {
-				ast_log(LOG_DEBUG, "Extension %s, priority %d returned normally even though call was hung up\n",
-					c->exten, c->priority);
-				goto out;
-			}
-			firstpass = 0;
-			c->priority++;
-		}
-		if (!ast_exists_extension(c, c->context, c->exten, 1, c->cid.cid_num)) {
-			/* It's not a valid extension anymore */
-			if (ast_exists_extension(c, c->context, "i", 1, c->cid.cid_num)) {
-				if (option_verbose > 2)
-					ast_verbose(VERBOSE_PREFIX_3 "Sent into invalid extension '%s' in context '%s' on %s\n", c->exten, c->context, c->name);
-				pbx_builtin_setvar_helper(c, "INVALID_EXTEN", c->exten);
-				strncpy(c->exten, "i", sizeof(c->exten)-1);
-				c->priority = 1;
-			} else {
-				ast_log(LOG_WARNING, "Channel '%s' sent into invalid extension '%s' in context '%s', but no invalid handler\n",
-					c->name, c->exten, c->context);
-				goto out;
-			}
-		} else if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT) {
-			/* If we get this far with AST_SOFTHANGUP_TIMEOUT, then we know that the "T" extension is next. */
-			c->_softhangup = 0;
-		} else {
-			/* Done, wait for an extension */
-			waittime = 0;
-			if (digit)
-				waittime = c->pbx->dtimeout;
-			else if (!autofallthrough)
-				waittime = c->pbx->rtimeout;
-			if (waittime) {
-				while (ast_matchmore_extension(c, c->context, exten, 1, c->cid.cid_num)) {
-					/* As long as we're willing to wait, and as long as it's not defined, 
-					   keep reading digits until we can't possibly get a right answer anymore.  */
-					digit = ast_waitfordigit(c, waittime * 1000);
-					if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) {
-						c->_softhangup = 0;
-					} else {
-						if (!digit)
-							/* No entry */
-							break;
-						if (digit < 0)
-							/* Error, maybe a  hangup */
-							goto out;
-						exten[pos++] = digit;
-						waittime = c->pbx->dtimeout;
-					}
-				}
-				if (ast_exists_extension(c, c->context, exten, 1, c->cid.cid_num)) {
-					/* Prepare the next cycle */
-					strncpy(c->exten, exten, sizeof(c->exten)-1);
+			if (!ast_exists_extension(c, c->context, c->exten, 1, c->cid.cid_num)) {
+				/* It's not a valid extension anymore */
+				if (ast_exists_extension(c, c->context, "i", 1, c->cid.cid_num)) {
+					if (option_verbose > 2)
+						ast_verbose(VERBOSE_PREFIX_3 "Sent into invalid extension '%s' in context '%s' on %s\n", c->exten, c->context, c->name);
+					pbx_builtin_setvar_helper(c, "INVALID_EXTEN", c->exten);
+					strncpy(c->exten, "i", sizeof(c->exten)-1);
 					c->priority = 1;
 				} else {
-					/* No such extension */
-					if (!ast_strlen_zero(exten)) {
-						/* An invalid extension */
-						if (ast_exists_extension(c, c->context, "i", 1, c->cid.cid_num)) {
-							if (option_verbose > 2)
-								ast_verbose( VERBOSE_PREFIX_3 "Invalid extension '%s' in context '%s' on %s\n", exten, c->context, c->name);
-							pbx_builtin_setvar_helper(c, "INVALID_EXTEN", exten);
-							strncpy(c->exten, "i", sizeof(c->exten)-1);
-							c->priority = 1;
+					ast_log(LOG_WARNING, "Channel '%s' sent into invalid extension '%s' in context '%s', but no invalid handler\n",
+						c->name, c->exten, c->context);
+					goto out;
+				}
+			} else if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT) {
+				/* If we get this far with AST_SOFTHANGUP_TIMEOUT, then we know that the "T" extension is next. */
+				c->_softhangup = 0;
+			} else {
+				/* Done, wait for an extension */
+	    			waittime = 0;
+				if (digit)
+					waittime = c->pbx->dtimeout;
+				else if (!autofallthrough)
+					waittime = c->pbx->rtimeout;
+				if (waittime) {
+					while (ast_matchmore_extension(c, c->context, exten, 1, c->cid.cid_num)) {
+						/* As long as we're willing to wait, and as long as it's not defined, 
+						   keep reading digits until we can't possibly get a right answer anymore.  */
+						digit = ast_waitfordigit(c, waittime * 1000);
+						if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) {
+							c->_softhangup = 0;
 						} else {
-							ast_log(LOG_WARNING, "Invalid extension '%s', but no rule 'i' in context '%s'\n", exten, c->context);
-							goto out;
+							if (!digit)
+								/* No entry */
+								break;
+							if (digit < 0)
+								/* Error, maybe a  hangup */
+								goto out;
+							exten[pos++] = digit;
+							waittime = c->pbx->dtimeout;
 						}
+					}
+					if (ast_exists_extension(c, c->context, exten, 1, c->cid.cid_num)) {
+						/* Prepare the next cycle */
+						strncpy(c->exten, exten, sizeof(c->exten)-1);
+						c->priority = 1;
 					} else {
-						/* A simple timeout */
-						if (ast_exists_extension(c, c->context, "t", 1, c->cid.cid_num)) {
-							if (option_verbose > 2)
-								ast_verbose( VERBOSE_PREFIX_3 "Timeout on %s\n", c->name);
-							strncpy(c->exten, "t", sizeof(c->exten)-1);
-							c->priority = 1;
+						/* No such extension */
+						if (!ast_strlen_zero(exten)) {
+							/* An invalid extension */
+							if (ast_exists_extension(c, c->context, "i", 1, c->cid.cid_num)) {
+								if (option_verbose > 2)
+									ast_verbose( VERBOSE_PREFIX_3 "Invalid extension '%s' in context '%s' on %s\n", exten, c->context, c->name);
+								pbx_builtin_setvar_helper(c, "INVALID_EXTEN", exten);
+								strncpy(c->exten, "i", sizeof(c->exten)-1);
+								c->priority = 1;
+							} else {
+								ast_log(LOG_WARNING, "Invalid extension '%s', but no rule 'i' in context '%s'\n", exten, c->context);
+								goto out;
+							}
 						} else {
-							ast_log(LOG_WARNING, "Timeout, but no rule 't' in context '%s'\n", c->context);
-							goto out;
-						}
-					}	
-				}
-				if (c->cdr) {
-					if (option_verbose > 2)
-						ast_verbose(VERBOSE_PREFIX_2 "CDR updated on %s\n",c->name);	
-					ast_cdr_update(c);
-			    }
-			} else {
-				if (option_verbose > 0) {
-					char *status;
-					status = pbx_builtin_getvar_helper(c, "DIALSTATUS");
-					if (!status)
-						status = "UNKNOWN";
-					if (option_verbose > 2)
-						ast_verbose(VERBOSE_PREFIX_2 "Auto fallthrough, channel '%s' status is '%s'\n", c->name, status);
-					if (!strcasecmp(status, "CONGESTION"))
-						res = pbx_builtin_congestion(c, "10");
-					else if (!strcasecmp(status, "CHANUNAVAIL"))
-						res = pbx_builtin_congestion(c, "10");
-					else if (!strcasecmp(status, "BUSY"))
-						res = pbx_builtin_busy(c, "10");
-					goto out;
+							/* A simple timeout */
+							if (ast_exists_extension(c, c->context, "t", 1, c->cid.cid_num)) {
+								if (option_verbose > 2)
+									ast_verbose( VERBOSE_PREFIX_3 "Timeout on %s\n", c->name);
+								strncpy(c->exten, "t", sizeof(c->exten)-1);
+								c->priority = 1;
+							} else {
+								ast_log(LOG_WARNING, "Timeout, but no rule 't' in context '%s'\n", c->context);
+								goto out;
+							}
+						}	
+					}
+					if (c->cdr) {
+						if (option_verbose > 2)
+							ast_verbose(VERBOSE_PREFIX_2 "CDR updated on %s\n",c->name);	
+						ast_cdr_update(c);
+				    }
+				} else {
+					if (option_verbose > 0) {
+						char *status;
+						status = pbx_builtin_getvar_helper(c, "DIALSTATUS");
+						if (!status)
+							status = "UNKNOWN";
+						if (option_verbose > 2)
+							ast_verbose(VERBOSE_PREFIX_2 "Auto fallthrough, channel '%s' status is '%s'\n", c->name, status);
+						if (!strcasecmp(status, "CONGESTION"))
+							res = pbx_builtin_congestion(c, "10");
+						else if (!strcasecmp(status, "CHANUNAVAIL"))
+							res = pbx_builtin_congestion(c, "10");
+						else if (!strcasecmp(status, "BUSY"))
+							res = pbx_builtin_busy(c, "10");
+						goto out;
+					}
 				}
 			}
 		}
+		if (firstpass) 
+			ast_log(LOG_WARNING, "Don't know what to do with '%s'\n", c->name);
 	}
-	if (firstpass) 
-		ast_log(LOG_WARNING, "Don't know what to do with '%s'\n", c->name);
 out:
 	if ((res != AST_PBX_KEEPALIVE) && ast_exists_extension(c, c->context, "h", 1, c->cid.cid_num)) {
 		c->exten[0] = 'h';
Index: asterisk/apps/Makefile
===================================================================
RCS file: /usr/cvsroot/asterisk/apps/Makefile,v
retrieving revision 1.83
diff -u -3 -r1.83 Makefile
--- asterisk/apps/Makefile	24 Nov 2004 05:01:49 -0000	1.83
+++ asterisk/apps/Makefile	26 Nov 2004 19:37:13 -0000
@@ -30,7 +30,7 @@
      app_groupcount.so app_txtcidname.so app_controlplayback.so \
      app_talkdetect.so app_alarmreceiver.so app_userevent.so app_verbose.so \
      app_test.so app_forkcdr.so app_math.so app_realtime.so \
-     app_dumpchan.so app_waitforsilence.so
+     app_dumpchan.so app_waitforsilence.so app_runexten.so
 
 ifneq (${OSARCH},Darwin)
 APPS+=app_intercom.so
