Index: asterisk/apps/app_queue.c
===================================================================
RCS file: /usr/cvsroot/asterisk/apps/app_queue.c,v
retrieving revision 1.13
diff -u -r1.13 app_queue.c
--- asterisk/apps/app_queue.c	2 Jul 2003 14:06:12 -0000	1.13
+++ asterisk/apps/app_queue.c	2 Jul 2003 23:12:56 -0000
@@ -115,11 +115,18 @@
 };
 
 struct member {
+	time_t last_used;
 	char tech[80];				/* Technology */
 	char loc[256];				/* Location */
 	struct member *next;		/* Next member */
 };
 
+struct myagent {
+        char *loc;
+	time_t *last_used;
+	char *tech;
+};
+                                                        
 struct ast_call_queue {
 	pthread_mutex_t	lock;	
 	char name[80];			/* Name of the queue */
@@ -438,6 +445,15 @@
 	}
 	return res;
 }
+       
+int compare_last_used (const struct myagent *c1, const struct myagent *c2)
+{
+	char str1[15];
+	char str2[15];
+        sprintf(str1, "%d", c1->last_used);
+        sprintf(str2, "%d", c2->last_used);
+	return strncmp (str1, str2,15);
+}                         
 
 static int try_calling(struct queue_ent *qe, char *options, char *announceoverride, char *url)
 {
@@ -453,14 +469,42 @@
 	struct ast_channel *peer;
 	int res = 0, bridge = 0;
 	char *announce = NULL;
+	time_t now;
+	int n = 0;
+	int i = 0;	
 	/* Hold the lock while we setup the outgoing calls */
 	ast_pthread_mutex_lock(&qe->parent->lock);
 	cur = qe->parent->members;
+	while(cur) {
+		cur = cur->next;
+		n++;
+	}
+	
+	struct myagent myagents[n];
+        
+        cur = qe->parent->members;
+        while(cur) {
+        	myagents[i].loc = cur->loc;
+        	myagents[i].last_used = cur->last_used;
+        	myagents[i].tech = cur->tech;
+	        ast_verbose( VERBOSE_PREFIX_3 "loading agent array: %s last_used: %d tech: %s\n", myagents[i].loc, myagents[i].last_used, myagents[i].tech);
+                cur = cur->next;
+        	i++;
+       	}
+	
+	qsort (myagents, n, sizeof (struct myagent), compare_last_used);
+
+	for(i = 0; i < n; i++) {
+        	ast_verbose( VERBOSE_PREFIX_3 "sorted agent array: %s last_used: %d\n", myagents[i].loc, myagents[i].last_used );
+	}        
+
 	if (strlen(qe->announce))
 		announce = qe->announce;
 	if (announceoverride && strlen(announceoverride))
 		announce = announceoverride;
-	while(cur) {
+//	while(cur) {
+	for(i=0; i < n; i++) {
+                ast_verbose(VERBOSE_PREFIX_2 "try_calling: agent: %s (queue: %s)\n", myagents[i].loc, qe->parent->name);
 		/* Get a technology/[device:]number pair */
 		tmp = malloc(sizeof(struct localuser));
 		if (!tmp) {
@@ -486,8 +530,8 @@
 			ast_log(LOG_DEBUG, "Queue with URL=%s_\n", url);
 		} else 
 			ast_log(LOG_DEBUG, "Simple queue (no URL)\n");
-
-		strncpy(numsubst, cur->loc, sizeof(numsubst)-1);
+		strncpy(numsubst, myagents[i].loc, sizeof(numsubst)-1);
+//		strncpy(numsubst, cur->loc, sizeof(numsubst)-1);
 		/* If we're dialing by extension, look at the extension to know what to dial */
 		if ((newnum = strstr(numsubst, "BYEXTENSION"))) {
 			strncpy(restofit, newnum + strlen("BYEXTENSION"), sizeof(restofit)-1);
@@ -496,7 +540,9 @@
 				ast_log(LOG_DEBUG, "Dialing by extension %s\n", numsubst);
 		}
 		/* Request the peer */
-		tmp->chan = ast_request(cur->tech, qe->chan->nativeformats, numsubst);
+//		tmp->chan = ast_request(cur->tech, qe->chan->nativeformats, numsubst);
+                tmp->chan = ast_request(myagents[i].tech, qe->chan->nativeformats, numsubst);
+              
 		if (!tmp->chan) {
 			/* If we can't, just go on to the next call */
 #if 0
@@ -524,6 +570,15 @@
 			break;
 		}
 #endif		
+                cur = qe->parent->members;
+                while(cur) {
+                        if (cur->loc == myagents[i].loc) {
+                                cur->last_used = time(&now);
+				break;
+                        }
+                        cur = cur->next;
+                }
+                                
 		tmp->chan->appl = "AppQueue";
 		tmp->chan->data = "(Outgoing Line)";
 		tmp->chan->whentohangup = 0;
@@ -566,7 +621,7 @@
 		if (outgoing->chan->_state == AST_STATE_UP)
 			break;
 
-		cur = cur->next;
+//		cur = cur->next;
 	}
 	if (qe->parent->timeout)
 		to = qe->parent->timeout * 1000;
@@ -665,10 +720,13 @@
 		return 0;
 	tmp[0] = digit;
 	tmp[1] = '\0';
+        ast_verbose(VERBOSE_PREFIX_3 "qe->chan: %s qe->context: %s tmp: %s\n", qe->chan, qe->context, tmp);
+	ast_verbose(VERBOSE_PREFIX_3 "OLD qe->chan: %s qe->chan->context: %s qe->chan->exten: %s\n", qe->chan, qe->chan->context, qe->chan->exten);
 	if (ast_exists_extension(qe->chan, qe->context, tmp, 1, qe->chan->callerid)) {
 		strncpy(qe->chan->context, qe->context, sizeof(qe->chan->context) - 1);
 		strncpy(qe->chan->exten, tmp, sizeof(qe->chan->exten) - 1);
 		qe->chan->priority = 0;
+                ast_verbose(VERBOSE_PREFIX_3 "NEW qe->chan: %s qe->chan->context: %s qe->chan->exten: %s\n", qe->chan, qe->chan->context, qe->chan->exten);
 		return 1;
 	}
 	return 0;
@@ -894,6 +952,10 @@
 	char *options = NULL;
 	char *url = NULL;
 	char *announceoverride = NULL;
+	char  *holdtimeout = NULL;
+	time_t now;
+	time_t beg_time;
+	time_t now_time;
 	
 	/* Our queue entry */
 	struct queue_ent qe;
@@ -921,16 +983,23 @@
 				if (announceoverride) {
 					*announceoverride = '\0';
 					announceoverride++;
+			
+	                                holdtimeout = strchr(announceoverride, '|');
+        	                        if (holdtimeout) {
+                	                        *holdtimeout = '\0';
+                        	                holdtimeout++;
+                                	}
 				}
 			}
 		}
 	}
-	printf("queue: %s, options: %s, url: %s, announce: %s\n",
-		queuename, options, url, announceoverride);
+	printf("queue: %s, options: %s, url: %s, announce: %s holdtimeout: %s\n",
+		queuename, options, url, announceoverride, holdtimeout);
 	/* Setup our queue entry */
 	memset(&qe, 0, sizeof(qe));
 	qe.chan = chan;
 	qe.start = time(NULL);
+	beg_time = time(&now);
 	if (!join_queue(queuename, &qe)) {
 		/* Start music on hold */
 		ast_moh_start(chan, qe.moh);
@@ -962,8 +1031,22 @@
 					}
 					break;
 				}
+
 				if (res && valid_exit(&qe, res))
 					break;
+
+			        now_time = time(&now);
+				if (!res && (now_time - beg_time) > atoi(holdtimeout)) {
+		                        if (valid_exit(&qe, 115)) { /* 115 = "s" just for testing */
+						ast_verbose(VERBOSE_PREFIX_3 "holdtimeout exceeded, valid exten avail\n");
+						res = AST_PBX_KEEPALIVE;
+						break;
+					} else {
+                                      		ast_verbose(VERBOSE_PREFIX_3 "holdtimeout exceeded, no valid exten.\n");
+                                        	res = -1;
+						break;
+                                	}
+				}
 			}
 		}
 		/* Don't allow return code > 0 */
