[asterisk-commits] murf: branch murf/bug_7638 r79012 - in /team/murf/bug_7638: ./ apps/ channels...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Aug 10 10:32:29 CDT 2007


Author: murf
Date: Fri Aug 10 10:32:29 2007
New Revision: 79012

URL: http://svn.digium.com/view/asterisk?view=rev&rev=79012
Log:
Merged revisions 78750,78779,78807,78824,78828-78829,78861-78862,78906,78908,78952,78956 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/trunk

................
r78750 | russell | 2007-08-09 11:25:09 -0600 (Thu, 09 Aug 2007) | 17 lines

Merged revisions 78749 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r78749 | russell | 2007-08-09 12:24:40 -0500 (Thu, 09 Aug 2007) | 9 lines

Fix subscriptions to multiple mailboxes for ODBC_STORAGE.  Also, leave a
comment for this to be fixed for IMAP_STORAGE, as well.  I left IMAP alone
since I know MarkM was working on this code right now for another reason.

This is broken even worse in trunk, but for a different reason.  The fact
that the mailbox option supported multiple mailboxes is completely not obvious
from the code in the channel drivers.  Anyway, I will fix that in another
commit ...

........

................
r78779 | russell | 2007-08-09 11:59:06 -0600 (Thu, 09 Aug 2007) | 9 lines

Merged revisions 78778 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r78778 | russell | 2007-08-09 12:58:31 -0500 (Thu, 09 Aug 2007) | 1 line

add a comment to indicate that inboxcount for ODBC_STORAGE needs to be fixed to support multiple mailboxes
........

................
r78807 | russell | 2007-08-09 13:11:53 -0600 (Thu, 09 Aug 2007) | 4 lines

Restore the ability to have multiple mailboxes listed for the mailbox option
in sip.conf.  chan_sip now maintains separate internal MWI subscriptions for
each one.

................
r78824 | russell | 2007-08-09 13:35:07 -0600 (Thu, 09 Aug 2007) | 2 lines

When looking up a mailbox, use the default context if not specified as something else

................
r78828 | mmichelson | 2007-08-09 14:07:32 -0600 (Thu, 09 Aug 2007) | 10 lines

Blocked revisions 78826 via svnmerge

........
r78826 | mmichelson | 2007-08-09 14:52:43 -0500 (Thu, 09 Aug 2007) | 3 lines

I broke canreinvite...Now I'm fixing it. I put some new code in the wrong place and so I've reverted the canreinvite section to how it was and put my new code where it should be.


........

................
r78829 | russell | 2007-08-09 14:07:59 -0600 (Thu, 09 Aug 2007) | 3 lines

Don't use strncpy for moving a chunk of memory to another that is overlapping.
This was found by running Asterisk under valgrind.

................
r78861 | mmichelson | 2007-08-09 16:18:23 -0600 (Thu, 09 Aug 2007) | 17 lines

Merged revisions 78859 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r78859 | mmichelson | 2007-08-09 16:51:17 -0500 (Thu, 09 Aug 2007) | 9 lines

Quite a few changes regarding IMAP storage.

1. instead of using inboxcount as the core message counting function, we use messagecount instead. This makes it possible to count messages in folders besides just INBOX and Old.
2. inboxcount and hasvoicemail now use messagecount as their means of determining return values.
3. Added a copy_message function for IMAP storage. Unfortunately I don't have the means to test it, but it seems like a pretty straightforward function.
4. Removed a #ifndef IMAP_STORAGE and matching #endif from leave_voicemail for a couple of reasons. One, we want to support copying mail to multiple IMAP boxes, and two, IMAP was
   broken because a STORE macro had been moved into this section of code.


........

................
r78862 | mmichelson | 2007-08-09 16:19:45 -0600 (Thu, 09 Aug 2007) | 10 lines

Blocked revisions 78860 via svnmerge

........
r78860 | mmichelson | 2007-08-09 17:03:48 -0500 (Thu, 09 Aug 2007) | 3 lines

Removing some extra debug code I left in my last commit


........

................
r78906 | murf | 2007-08-09 17:32:23 -0600 (Thu, 09 Aug 2007) | 9 lines

Merged revisions 78891 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r78891 | murf | 2007-08-09 17:10:46 -0600 (Thu, 09 Aug 2007) | 1 line

This fixes bug 10416; thanks to mvanbaak for the pretty output
........

................
r78908 | mmichelson | 2007-08-09 17:49:05 -0600 (Thu, 09 Aug 2007) | 12 lines

Merged revisions 78907 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r78907 | mmichelson | 2007-08-09 18:47:00 -0500 (Thu, 09 Aug 2007) | 4 lines

Improved a bit of logic regarding comma-separated mailboxes in has_voicemail. Also added some braces to some compound if statements
since unbraced if statements scare me in general.


........

................
r78952 | file | 2007-08-10 07:50:58 -0600 (Fri, 10 Aug 2007) | 12 lines

Merged revisions 78951 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r78951 | file | 2007-08-10 10:49:19 -0300 (Fri, 10 Aug 2007) | 4 lines

(closes issue #10422)
Reported by: bhowell
Add note to sample configuration about module load order and how it can cause perfectly good queue members to be marked as invalid.

........

................
r78956 | file | 2007-08-10 08:17:42 -0600 (Fri, 10 Aug 2007) | 10 lines

Merged revisions 78955 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r78955 | file | 2007-08-10 11:15:53 -0300 (Fri, 10 Aug 2007) | 2 lines

Don't bother having the core pass through or emulate begin DTMF frames when in an ast_waitstream. It only cares about the end of DTMF.

........

................

Modified:
    team/murf/bug_7638/   (props changed)
    team/murf/bug_7638/Makefile
    team/murf/bug_7638/apps/app_minivm.c
    team/murf/bug_7638/apps/app_voicemail.c
    team/murf/bug_7638/channels/chan_sip.c
    team/murf/bug_7638/configs/queues.conf.sample
    team/murf/bug_7638/main/file.c

Propchange: team/murf/bug_7638/
------------------------------------------------------------------------------
    automerge = yes

Propchange: team/murf/bug_7638/
------------------------------------------------------------------------------
Binary property 'branch-1.4-blocked' - no diff available.

Propchange: team/murf/bug_7638/
------------------------------------------------------------------------------
Binary property 'branch-1.4-merged' - no diff available.

Propchange: team/murf/bug_7638/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Fri Aug 10 10:32:29 2007
@@ -1,1 +1,1 @@
-/trunk:1-78748
+/trunk:1-78996

Modified: team/murf/bug_7638/Makefile
URL: http://svn.digium.com/view/asterisk/team/murf/bug_7638/Makefile?view=diff&rev=79012&r1=79011&r2=79012
==============================================================================
--- team/murf/bug_7638/Makefile (original)
+++ team/murf/bug_7638/Makefile Fri Aug 10 10:32:29 2007
@@ -281,7 +281,11 @@
 	@echo " + Asterisk has successfully been built, and +"  
 	@echo " + can be installed by running:              +"
 	@echo " +                                           +"
+ifeq ($(MAKE), gmake)
+	@echo " +               $(MAKE) install               +"  
+else
 	@echo " +               $(MAKE) install                +"  
+endif
 	@echo " +-------------------------------------------+"  
 
 _all: cleantest $(SUBDIRS)
@@ -490,14 +494,22 @@
 	@echo " + configuration files (overwriting any      +"
 	@echo " + existing config files), run:              +"  
 	@echo " +                                           +"
+ifeq ($(MAKE), gmake)
+	@echo " +               $(MAKE) samples               +"
+else
 	@echo " +               $(MAKE) samples                +"
+endif
 	@echo " +                                           +"
 	@echo " +-----------------  or ---------------------+"
 	@echo " +                                           +"
 	@echo " + You can go ahead and install the asterisk +"
 	@echo " + program documentation now or later run:   +"
 	@echo " +                                           +"
+ifeq ($(MAKE), gmake)
+	@echo " +              $(MAKE) progdocs               +"
+else
 	@echo " +              $(MAKE) progdocs                +"
+endif
 	@echo " +                                           +"
 	@echo " + **Note** This requires that you have      +"
 	@echo " + doxygen installed on your local system    +"
@@ -669,7 +681,11 @@
 	@echo " + directories, and logs, run the following  +"
 	@echo " + command:                                  +"
 	@echo " +                                           +"
+ifeq ($(MAKE), gmake)
+	@echo " +            $(MAKE) uninstall-all            +"  
+else
 	@echo " +            $(MAKE) uninstall-all             +"  
+endif
 	@echo " +-------------------------------------------+"  
 
 uninstall-all: _uninstall

Modified: team/murf/bug_7638/apps/app_minivm.c
URL: http://svn.digium.com/view/asterisk/team/murf/bug_7638/apps/app_minivm.c?view=diff&rev=79012&r1=79011&r2=79012
==============================================================================
--- team/murf/bug_7638/apps/app_minivm.c (original)
+++ team/murf/bug_7638/apps/app_minivm.c Fri Aug 10 10:32:29 2007
@@ -2275,11 +2275,11 @@
 	       int len = strlen("\n");
 	       switch (tmpwrite[1]) {
 	       case 'n':
-		      strncpy(tmpwrite+len, tmpwrite+2, strlen(tmpwrite+2)+1);
+		      memmove(tmpwrite + len, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
 		      strncpy(tmpwrite, "\n", len);
 		      break;
 	       case 't':
-		      strncpy(tmpwrite+len, tmpwrite+2, strlen(tmpwrite+2)+1);
+		      memmove(tmpwrite + len, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
 		      strncpy(tmpwrite, "\t", len);
 		      break;
 	       default:

Modified: team/murf/bug_7638/apps/app_voicemail.c
URL: http://svn.digium.com/view/asterisk/team/murf/bug_7638/apps/app_voicemail.c?view=diff&rev=79012&r1=79011&r2=79012
==============================================================================
--- team/murf/bug_7638/apps/app_voicemail.c (original)
+++ team/murf/bug_7638/apps/app_voicemail.c Fri Aug 10 10:32:29 2007
@@ -1681,8 +1681,6 @@
 	copy(frompath2, topath2);
 	ast_variables_destroy(var);
 }
-#endif
-
 /*! \brief
  * A negative return value indicates an error.
  * \note Should always be called with a lock already set on dir.
@@ -1714,8 +1712,8 @@
 	return x - 1;
 }
 
-#endif
-
+#endif /*#ifndef IMAP_STORAGE*/
+#endif /*#else of #ifdef ODBC_STORAGE*/
 #ifndef ODBC_STORAGE
 static int vm_delete(char *file)
 {
@@ -2294,8 +2292,39 @@
 	};
 	return (id >= 0 && id < (sizeof(msgs)/sizeof(msgs[0]))) ? msgs[id] : "Unknown";
 }
+#ifdef IMAP_STORAGE
+static int folder_int(const char *folder)
+{
+	/*assume a NULL folder means INBOX*/
+	if (!folder)
+		return 0;
+	if(!strcasecmp(folder, "INBOX"))
+		return 0;
+	else if (!strcasecmp(folder, "Old"))
+		return 1;
+	else if (!strcasecmp(folder, "Work"))
+		return 2;
+	else if (!strcasecmp(folder, "Family"))
+		return 3;
+	else if (!strcasecmp(folder, "Friends"))
+		return 4;
+	else if (!strcasecmp(folder, "Cust1"))
+		return 5;
+	else if (!strcasecmp(folder, "Cust2"))
+		return 6;
+	else if (!strcasecmp(folder, "Cust3"))
+		return 7;
+	else if (!strcasecmp(folder, "Cust4"))
+		return 8;
+	else if (!strcasecmp(folder, "Cust5"))
+		return 9;
+	else /*assume they meant INBOX if folder is not found otherwise*/
+		return 0;
+}
+#endif
 
 #ifdef ODBC_STORAGE
+/*! XXX \todo Fix this function to support multiple mailboxes in the intput string */
 static int inboxcount(const char *mailbox, int *newmsgs, int *oldmsgs)
 {
 	int x = -1;
@@ -2438,17 +2467,16 @@
 
 static int has_voicemail(const char *mailbox, const char *folder)
 {
-	char *context, tmp[256];
+	char tmp[256], *tmp2 = tmp, *mbox, *context;
 	ast_copy_string(tmp, mailbox, sizeof(tmp));
-	if ((context = strchr(tmp, '@')))
-		*context++ = '\0';
-	else
-		context = "default";
-
-	if (messagecount(context, tmp, folder))
-		return 1;
-	else
-		return 0;
+	while ((context = mbox = strsep(&tmp2, ","))) {
+		strsep(&context, "@");
+		if (ast_strlen_zero(context))
+			context = "default";
+		if (messagecount(context, mbox, folder))
+			return 1;
+	}
+	return 0;
 }
 
 #elif defined(IMAP_STORAGE)
@@ -2521,66 +2549,24 @@
 
 }
 
-static int inboxcount(const char *mailbox, int *newmsgs, int *oldmsgs)
+static int messagecount(const char *context, const char *mailbox, const char *folder)
 {
 	SEARCHPGM *pgm;
 	SEARCHHEADER *hdr;
  
- 	struct ast_vm_user *vmu;
- 	struct vm_state *vms_p;
- 	char tmp[256] = "";
- 	char *mb, *cur;
- 	char *mailboxnc; 
- 	char *context;
- 	int ret = 0;
-
- 	if (newmsgs)
- 		*newmsgs = 0;
-
- 	if (oldmsgs)
- 		*oldmsgs = 0;
- 
-	 ast_debug(3,"Mailbox is set to %s\n",mailbox);
-
- 	/* If no mailbox, return immediately */
- 	if (ast_strlen_zero(mailbox)) 
- 		return 0;
-
- 	if (strchr(mailbox, ',')) {
- 		int tmpnew, tmpold;
-		ast_copy_string(tmp, mailbox, sizeof(tmp));
- 		mb = tmp;
- 		ret = 0;
- 		while((cur = strsep(&mb, ", "))) {
- 			if (!ast_strlen_zero(cur)) {
- 				if (inboxcount(cur, newmsgs ? &tmpnew : NULL, oldmsgs ? &tmpold : NULL))
- 					return -1;
- 				else {
- 					if (newmsgs)
- 						*newmsgs += tmpnew; 
- 					if (oldmsgs)
- 						*oldmsgs += tmpold;
- 				}
- 			}
- 		}
- 		return 0;
- 	}
-
-	ast_copy_string(tmp, mailbox, sizeof(tmp));
-
-	if ((context = strchr(tmp, '@'))) {
- 		*context = '\0';
- 		mailboxnc = tmp;
- 		context++;
- 	} else {
- 		context = "default";
- 		mailboxnc = (char *)mailbox;
- 	}
- 
- 	/* We have to get the user before we can open the stream! */
- 	/*ast_debug(1,"Before find_user, context is %s and mailbox is %s\n",context,mailbox); */
-	if (!(vmu = find_user(NULL, context, mailboxnc))) {
-		ast_log(LOG_ERROR, "Couldn't find mailbox %s in context %s\n", mailboxnc, context);
+	struct ast_vm_user *vmu;
+	struct vm_state *vms_p;
+	int ret = 0;
+	int fold = folder_int(folder);
+	
+	if (ast_strlen_zero(mailbox))
+		return 0;
+
+	/* We have to get the user before we can open the stream! */
+	/* ast_log (LOG_DEBUG,"Before find_user, context is %s and mailbox is %s\n",context,mailbox); */
+	vmu = find_user(NULL, context, mailbox);
+	if (!vmu) {
+		ast_log (LOG_ERROR,"Couldn't find mailbox %s in context %s\n",mailbox,context);
 		return -1;
 	}
 	
@@ -2591,108 +2577,184 @@
 		return -1;
  	}
 
- 	/* check if someone is accessing this box right now... */
-	if ((vms_p = get_vm_state_by_imapuser(vmu->imapuser, 1)) || (vms_p = get_vm_state_by_mailbox(mailboxnc, 1))) {
-		ast_debug(3,"Returning before search - user is logged in\n");
- 		*newmsgs = vms_p->newmessages;
- 		*oldmsgs = vms_p->oldmessages;
-		free_user(vmu);
- 		return 0;
- 	}
-
- 	/* add one if not there... */
-	if (!(vms_p = get_vm_state_by_imapuser(vmu->imapuser, 0)) && !(vms_p = get_vm_state_by_mailbox(mailboxnc, 0))) {
+	/* check if someone is accessing this box right now... */
+	vms_p = get_vm_state_by_imapuser(vmu->imapuser,1);
+	if (!vms_p) {
+		vms_p = get_vm_state_by_mailbox(mailbox,1);
+	}
+	if (vms_p) {
+		ast_debug(3, "Returning before search - user is logged in\n");
+		if(fold == 0) {/*INBOX*/
+			free_user(vmu);
+			return vms_p->newmessages;
+		}
+		if(fold == 1) {/*Old messages*/
+			free_user(vmu);
+		 	return vms_p->oldmessages;
+		}
+	}
+
+	/* add one if not there... */
+	vms_p = get_vm_state_by_imapuser(vmu->imapuser,0);
+	if (!vms_p) {
+		vms_p = get_vm_state_by_mailbox(mailbox,0);
+	}
+
+	if (!vms_p) {
 		ast_debug(3,"Adding new vmstate for %s\n",vmu->imapuser);
 		if (!(vms_p = ast_calloc(1, sizeof(*vms_p)))) {
 			free_user(vmu);
 			return -1;
 		}
- 		ast_copy_string(vms_p->imapuser,vmu->imapuser, sizeof(vms_p->imapuser));
- 		ast_copy_string(vms_p->username, mailboxnc, sizeof(vms_p->username)); /* save for access from interactive entry point */
- 		vms_p->mailstream = NIL; /* save for access from interactive entry point */
-		ast_debug(3,"Copied %s to %s\n",vmu->imapuser,vms_p->imapuser);
+		ast_copy_string(vms_p->imapuser,vmu->imapuser, sizeof(vms_p->imapuser));
+		ast_copy_string(vms_p->username, mailbox, sizeof(vms_p->username)); /* save for access from interactive entry point */
+		vms_p->mailstream = NIL; /* save for access from interactive entry point */
+		ast_debug(3, "Copied %s to %s\n",vmu->imapuser,vms_p->imapuser);
 		vms_p->updated = 1;
 		/* set mailbox to INBOX! */
-		ast_copy_string(vms_p->curbox, mbox(NEW_FOLDER), sizeof(vms_p->curbox));
- 		init_vm_state(vms_p);
- 		vmstate_insert(vms_p);
- 	}
-
-	/* If no mailstream exists yet and even after attempting to initialize it fails, bail out */
-	ret = init_mailstream(vms_p, NEW_FOLDER);
+		ast_copy_string(vms_p->curbox, mbox(fold), sizeof(vms_p->curbox));
+		init_vm_state(vms_p);
+		vmstate_insert(vms_p);
+	}
+	ret = init_mailstream(vms_p, fold);
 	if (!vms_p->mailstream) {
 		ast_log (LOG_ERROR,"Houston we have a problem - IMAP mailstream is NULL\n");
 		free_user(vmu);
 		return -1;
 	}
-
-	if (!ret && vms_p->updated > 0) {
-		if (newmsgs) {
-			pgm = mail_newsearchpgm();
-			hdr = mail_newsearchheader("X-Asterisk-VM-Extension", (char *)mailboxnc);
-			pgm->header = hdr;
+	if (ret == 0) {
+		pgm = mail_newsearchpgm ();
+		hdr = mail_newsearchheader ("X-Asterisk-VM-Extension", (char *)mailbox);
+		pgm->header = hdr;
+		if (fold != 1) {
 			pgm->unseen = 1;
 			pgm->seen = 0;
-			pgm->undeleted = 1;
-			pgm->deleted = 0;
-			vms_p->vmArrayIndex = 0;
-			mail_search_full(vms_p->mailstream, NULL, pgm, NIL);
-			*newmsgs = vms_p->vmArrayIndex;
-			vms_p->newmessages = vms_p->vmArrayIndex;
-			mail_free_searchpgm(&pgm);
-		}
-		if (oldmsgs) {
-			pgm = mail_newsearchpgm ();
-			hdr = mail_newsearchheader ("X-Asterisk-VM-Extension", (char *)mailboxnc);
-			pgm->header = hdr;
+		}
+		/* In the special case where fold is 1 (old messages) we have to do things a bit
+		 * differently. Old messages are stored in the INBOX but are marked as "seen"
+		 */
+		else {
 			pgm->unseen = 0;
 			pgm->seen = 1;
-			pgm->undeleted = 1;
-			pgm->deleted = 0;
-			vms_p->vmArrayIndex = 0;
-			mail_search_full(vms_p->mailstream, NULL, pgm, NIL);
-			*oldmsgs = vms_p->vmArrayIndex;
+		}
+		pgm->undeleted = 1;
+		pgm->deleted = 0;
+
+		vms_p->vmArrayIndex = 0;
+		mail_search_full (vms_p->mailstream, NULL, pgm, NIL);
+		if(fold == 0)
+			vms_p->newmessages = vms_p->vmArrayIndex;
+		if(fold == 1)
 			vms_p->oldmessages = vms_p->vmArrayIndex;
-			mail_free_searchpgm(&pgm);
-		}
-	}
-
- 	if (vms_p->updated > 1) {  /* changes, so we did the searches above */
- 		vms_p->updated = 0;
- 	} else {  /* no changes, so don't search */
- 		mail_ping(vms_p->mailstream);
- 		/* Keep the old data */
- 		*newmsgs = vms_p->newmessages;
- 		*oldmsgs = vms_p->oldmessages;
- 	}
-
+		/*Freeing the searchpgm also frees the searchhdr*/
+		mail_free_searchpgm(&pgm);
+		free_user(vmu);
+		vms_p->updated = 0;
+		return vms_p->vmArrayIndex;
+	} else {  
+		mail_ping(vms_p->mailstream);
+	}
 	free_user(vmu);
- 	return 0;
- }
+	return 0;
+}
+static int inboxcount(const char *mailbox_context, int *newmsgs, int *oldmsgs)
+{
+	char tmp[PATH_MAX] = "";
+	char *mailboxnc; 	
+	char *context;
+	char *mb;
+	char *cur;
+	if (newmsgs)
+		*newmsgs = 0;
+	if (oldmsgs)
+		*oldmsgs = 0;
+
+	ast_debug(3,"Mailbox is set to %s\n",mailbox_context);
+	/* If no mailbox, return immediately */
+	if (ast_strlen_zero(mailbox_context))
+		return 0;
+	
+	ast_copy_string(tmp, mailbox_context, sizeof(tmp));
+	context = strchr(tmp, '@');
+	if (strchr(mailbox_context, ',')) {
+		int tmpnew, tmpold;
+		ast_copy_string(tmp, mailbox_context, sizeof(tmp));
+		mb = tmp;
+		while((cur = strsep(&mb, ", "))) {
+			if (!ast_strlen_zero(cur)) {
+				if (inboxcount(cur, newmsgs ? &tmpnew : NULL, oldmsgs ? &tmpold : NULL))
+					return -1;
+				else {
+					if (newmsgs)
+						*newmsgs += tmpnew; 
+					if (oldmsgs)
+						*oldmsgs += tmpold;
+				}
+			}
+		}
+		return 0;
+	}
+	if (context) {
+		*context = '\0';
+		mailboxnc = tmp;
+		context++;
+	} else {
+		context = "default";
+		mailboxnc = (char *)mailbox_context;
+	}
+	if (newmsgs) {
+		if((*newmsgs = messagecount(context, mailboxnc, "INBOX")) < 0)
+			return -1;
+	}
+	if (oldmsgs) {
+		if((*oldmsgs = messagecount(context, mailboxnc, "Old")) < 0)
+			return -1;
+	}
+	return 0;
+}
+	
 
 static int has_voicemail(const char *mailbox, const char *folder)
 {
-	int newmsgs, oldmsgs;
-	
-	if(inboxcount(mailbox, &newmsgs, &oldmsgs))
+	char tmp[256], *tmp2, *mbox, *context;
+	ast_copy_string(tmp, mailbox, sizeof(tmp));
+	tmp2 = tmp;
+	if(strchr(tmp2, ',')) {
+		while((mbox = strsep(&tmp2, ","))) {
+			if(!ast_strlen_zero(mbox)) {
+				if (has_voicemail(mbox, folder))
+					return 1;
+			}
+		}
+	}
+	if ((context= strchr(tmp, '@')))
+		*context++ = '\0';
+	else
+		context = "default";
+	return messagecount(context, tmp, folder) ? 1 : 0;
+}
+
+static int copy_message(struct ast_channel *chan, struct ast_vm_user *vmu, int imbox, int msgnum, long duration, struct ast_vm_user *recip, char *fmt, char *dir)
+{
+	char dest[256];
+	struct vm_state *sendvms = NULL, *destvms = NULL;
+	char messagestring[10]; /*I guess this could be a problem if someone has more than 999999999 messages...*/
+	if(!(sendvms = get_vm_state_by_imapuser(vmu->imapuser, 2)))
+	{
+		ast_log(LOG_ERROR, "Couldn't get vm_state for originator's mailbox!!\n");
+		return -1;
+	}
+	if(!(destvms = get_vm_state_by_imapuser(recip->imapuser, 2)))
+	{
+		ast_log(LOG_ERROR, "Couldn't get vm_state for destination mailbox!\n");
+		return -1;
+	}
+	imap_mailbox_name(dest, destvms, imbox, 1);
+	snprintf(messagestring, sizeof(messagestring), "%ld", sendvms->msgArray[msgnum]);
+	if((mail_copy(sendvms->mailstream, messagestring, dest) == T))
 		return 0;
-	else
-		return folder? oldmsgs: newmsgs;
-}
-
-static int messagecount(const char *context, const char *mailbox, const char *folder)
-{
-	int newmsgs, oldmsgs;
- 	char tmp[256] = "";
-	
- 	if (ast_strlen_zero(mailbox))
- 		return 0;
-	sprintf(tmp,"%s@%s", mailbox, ast_strlen_zero(context)? "default": context);
-
-	if(inboxcount(tmp, &newmsgs, &oldmsgs))
-		return 0;
-	else
-		return folder? oldmsgs: newmsgs;
+	ast_log(LOG_WARNING, "Unable to copy message from mailbox %s to mailbox %s\n", vmu->mailbox, recip->mailbox);
+	return -1;
 }
 
 #endif
@@ -3241,7 +3303,6 @@
 						snprintf(tmpdur, sizeof(tmpdur), "%d", duration);
 						ast_update_realtime("voicemail_data", "id", tmpid, "filename", fn, "duration", tmpdur, NULL);
 					}
-#ifndef IMAP_STORAGE
 					/* We must store the file first, before copying the message, because
 					 * ODBC storage does the entire copy with SQL.
 					 */
@@ -3265,7 +3326,6 @@
 							free_user(recip);
 						}
 					}
-#endif
 					/* Notification and disposal needs to happen after the copy, though. */
 					if (ast_fileexists(fn, NULL, NULL)) {
 						notify_new_message(chan, vmu, msgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL));

Modified: team/murf/bug_7638/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/murf/bug_7638/channels/chan_sip.c?view=diff&rev=79012&r1=79011&r2=79012
==============================================================================
--- team/murf/bug_7638/channels/chan_sip.c (original)
+++ team/murf/bug_7638/channels/chan_sip.c Fri Aug 10 10:32:29 2007
@@ -1226,6 +1226,20 @@
 	int autoframing;
 };
 
+/*!
+ * \brief A peer's mailbox
+ *
+ * We could use STRINGFIELDS here, but for only two strings, it seems like
+ * too much effort ...
+ */
+struct sip_mailbox {
+	char *mailbox;
+	char *context;
+	/*! Associated MWI subscription */
+	struct ast_event_sub *event_sub;
+	AST_LIST_ENTRY(sip_mailbox) entry;
+};
+
 /*! \brief Structure for SIP peer data, we place calls to peers if registered  or fixed IP address (host) */
 /* XXX field 'name' must be first otherwise sip_addrcmp() will fail */
 struct sip_peer {
@@ -1254,7 +1268,6 @@
 	int busy_level;			/*!< Level of active channels where we signal busy */
 	enum transfermodes allowtransfer;	/*! SIP Refer restriction scheme */
 	char vmexten[AST_MAX_EXTENSION]; /*!< Dialplan extension for MWI notify message*/
-	char mailbox[AST_MAX_EXTENSION]; /*!< Mailbox setting for MWI checks */
 	char language[MAX_LANGUAGE];	/*!<  Default language for prompts */
 	char mohinterpret[MAX_MUSICCLASS];/*!<  Music on Hold class */
 	char mohsuggest[MAX_MUSICCLASS];/*!<  Music on Hold class */
@@ -1263,6 +1276,9 @@
 	int lastmsgssent;
 	unsigned int sipoptions;	/*!<  Supported SIP options */
 	struct ast_flags flags[2];	/*!<  SIP_ flags */
+	
+	/*! Mailboxes that this peer cares about */
+	AST_LIST_HEAD_NOLOCK(, sip_mailbox) mailboxes;
 
 	/* things that don't belong in flags */
 	char is_realtime;		/*!< this is a 'realtime' peer */
@@ -1293,7 +1309,6 @@
 	struct ast_variable *chanvars;	/*!<  Variables to set for channel created by user */
 	struct sip_pvt *mwipvt;		/*!<  Subscription for MWI */
 	int autoframing;
-	struct ast_event_sub *mwi_event_sub; /*!< The MWI event subscription */
 };
 
 
@@ -2880,6 +2895,25 @@
 	}
 }
 
+static void destroy_mailbox(struct sip_mailbox *mailbox)
+{
+	if (mailbox->mailbox)
+		ast_free(mailbox->mailbox);
+	if (mailbox->context)
+		ast_free(mailbox->context);
+	if (mailbox->event_sub)
+		ast_event_unsubscribe(mailbox->event_sub);
+	ast_free(mailbox);
+}
+
+static void clear_peer_mailboxes(struct sip_peer *peer)
+{
+	struct sip_mailbox *mailbox;
+
+	while ((mailbox = AST_LIST_REMOVE_HEAD(&peer->mailboxes, entry)))
+		destroy_mailbox(mailbox);
+}
+
 /*! \brief Destroy peer object from memory */
 static void sip_destroy_peer(struct sip_peer *peer)
 {
@@ -2895,11 +2929,6 @@
 
 	if (peer->mwipvt) 	/* We have an active subscription, delete it */
 		peer->mwipvt = sip_destroy(peer->mwipvt);
-
-	if (peer->mwi_event_sub) {
-		ast_event_unsubscribe(peer->mwi_event_sub);
-		peer->mwi_event_sub = NULL;
-	}
 
 	if (peer->chanvars) {
 		ast_variables_destroy(peer->chanvars);
@@ -2923,6 +2952,7 @@
 	peer->auth = NULL;
 	if (peer->dnsmgr)
 		ast_dnsmgr_release(peer->dnsmgr);
+	clear_peer_mailboxes(peer);
 	ast_free(peer);
 }
 
@@ -11098,6 +11128,19 @@
 	return _sip_show_peer(0, fd, NULL, NULL, argc, (const char **) argv);
 }
 
+static void peer_mailboxes_to_str(struct ast_str **mailbox_str, struct sip_peer *peer)
+{
+	struct sip_mailbox *mailbox;
+
+	AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) {
+		ast_str_append(mailbox_str, 0, "%s%s%s%s",
+			mailbox->mailbox,
+			ast_strlen_zero(mailbox->context) ? "" : "@",
+			S_OR(mailbox->context, ""),
+			AST_LIST_NEXT(mailbox, entry) ? "," : "");
+	}
+}
+
 /*! \brief Show one peer in detail (main function) */
 static int _sip_show_peer(int type, int fd, struct mansession *s, const struct message *m, int argc, const char *argv[])
 {
@@ -11132,6 +11175,7 @@
 		}
 	}
 	if (peer && type==0 ) { /* Normal listing */
+		struct ast_str *mailbox_str = ast_str_alloca(512);
 		ast_cli(fd,"\n\n");
 		ast_cli(fd, "  * Name       : %s\n", peer->name);
 		if (realtimepeers) {	/* Realtime is enabled */
@@ -11159,7 +11203,8 @@
 		print_group(fd, peer->callgroup, 0);
 		ast_cli(fd, "  Pickupgroup  : ");
 		print_group(fd, peer->pickupgroup, 0);
-		ast_cli(fd, "  Mailbox      : %s\n", peer->mailbox);
+		peer_mailboxes_to_str(&mailbox_str, peer);
+		ast_cli(fd, "  Mailbox      : %s\n", mailbox_str->str);
 		ast_cli(fd, "  VM Extension : %s\n", peer->vmexten);
 		ast_cli(fd, "  LastMsgsSent : %d/%d\n", (peer->lastmsgssent & 0x7fff0000) >> 16, peer->lastmsgssent & 0xffff);
 		ast_cli(fd, "  Call limit   : %d\n", peer->call_limit);
@@ -11234,6 +11279,7 @@
 		unref_peer(peer);
 	} else  if (peer && type == 1) { /* manager listing */
 		char buf[256];
+		struct ast_str *mailbox_str = ast_str_alloca(512);
 		astman_append(s, "Channeltype: SIP\r\n");
 		astman_append(s, "ObjectName: %s\r\n", peer->name);
 		astman_append(s, "ChanObjectType: peer\r\n");
@@ -11253,7 +11299,8 @@
 		astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->callgroup));
 		astman_append(s, "Pickupgroup: ");
 		astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->pickupgroup));
-		astman_append(s, "VoiceMailbox: %s\r\n", peer->mailbox);
+		peer_mailboxes_to_str(&mailbox_str, peer);
+		astman_append(s, "VoiceMailbox: %s\r\n", mailbox_str->str);
 		astman_append(s, "TransferMode: %s\r\n", transfermode2str(peer->allowtransfer));
 		astman_append(s, "LastMsgsSent: %d\r\n", peer->lastmsgssent);
 		astman_append(s, "Call-limit: %d\r\n", peer->call_limit);
@@ -11656,6 +11703,9 @@
 			arg->numchans++;
 		}
 		if (cur->subscribed != NONE && arg->subscriptions) {
+			struct ast_str *mailbox_str = ast_str_alloca(512);
+			if (cur->subscribed == MWI_NOTIFICATION && cur->relatedpeer)
+				peer_mailboxes_to_str(&mailbox_str, cur->relatedpeer);
 			ast_cli(arg->fd, FORMAT3, ast_inet_ntoa(dst->sin_addr),
 				S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 
 			   	cur->callid,
@@ -11663,7 +11713,7 @@
 				cur->subscribed == MWI_NOTIFICATION ? "--" : cur->subscribeuri,
 				cur->subscribed == MWI_NOTIFICATION ? "<none>" : ast_extension_state2str(cur->laststate), 
 				subscription_type2str(cur->subscribed),
-				cur->subscribed == MWI_NOTIFICATION ? (cur->relatedpeer ? cur->relatedpeer->mailbox : "<none>") : "<none>"
+				cur->subscribed == MWI_NOTIFICATION ? S_OR(mailbox_str->str, "<none>") : "<none>"
 );
 			arg->numchans++;
 		}
@@ -12700,7 +12750,9 @@
 	} else  if (!strcasecmp(colname, "useragent")) {
 		ast_copy_string(buf, peer->useragent, len);
 	} else  if (!strcasecmp(colname, "mailbox")) {
-		ast_copy_string(buf, peer->mailbox, len);
+		struct ast_str *mailbox_str = ast_str_alloca(512);
+		peer_mailboxes_to_str(&mailbox_str, peer);
+		ast_copy_string(buf, mailbox_str->str, len);
 	} else  if (!strcasecmp(colname, "context")) {
 		ast_copy_string(buf, peer->context, len);
 	} else  if (!strcasecmp(colname, "expire")) {
@@ -15563,6 +15615,18 @@
 	return 1;
 }
 
+static void add_peer_mwi_subs(struct sip_peer *peer)
+{
+	struct sip_mailbox *mailbox;
+
+	AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) {
+		mailbox->event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, peer,
+			AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox->mailbox,
+			AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, S_OR(mailbox->context, "default"),
+			AST_EVENT_IE_END);
+	}
+}
+
 /*! \brief  Handle incoming SUBSCRIBE request */
 static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int seqno, char *e)
 {
@@ -15745,7 +15809,7 @@
 		  The subscribed URI needs to exist in the dial plan
 		  In most devices, this is configurable to the voicemailmain extension you use
 		*/
-		if (!authpeer || ast_strlen_zero(authpeer->mailbox)) {
+		if (!authpeer || AST_LIST_EMPTY(&authpeer->mailboxes)) {
 			transmit_response(p, "404 Not found (no mailbox)", req);
 			p->needdestroy = 1;
 			ast_log(LOG_NOTICE, "Received SIP subscribe for peer without mailbox: %s\n", authpeer->name);
@@ -15756,15 +15820,7 @@
 
 		p->subscribed = MWI_NOTIFICATION;
 		if (ast_test_flag(&authpeer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY)) {
-			char *mailbox, *context;
-			context = mailbox = ast_strdupa(authpeer->mailbox);
-			strsep(&context, "@");
-			if (ast_strlen_zero(context))
-				context = "default";
-			authpeer->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, authpeer,
-				AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
-				AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
-				AST_EVENT_IE_END);
+			add_peer_mwi_subs(authpeer);
 		}
 		if (authpeer->mwipvt && authpeer->mwipvt != p)	/* Destroy old PVT if this is a new one */
 			/* We only allow one subscription per peer */
@@ -15801,7 +15857,7 @@
 
 		if (sipdebug) {
 			if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer)
-				ast_debug(2, "Adding subscription for mailbox notification - peer %s Mailbox %s\n", p->relatedpeer->name, p->relatedpeer->mailbox);
+				ast_debug(2, "Adding subscription for mailbox notification - peer %s\n", p->relatedpeer->name);
 			else
 				ast_debug(2, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username);
 		}
@@ -16234,13 +16290,39 @@
 	return 1;
 }
 
+/*!
+ * \brief Get cached MWI info
+ * \retval 0 At least one message is waiting
+ * \retval 1 no messages waiting
+ */
+static int get_cached_mwi(struct sip_peer *peer, int *new, int *old)
+{
+	struct sip_mailbox *mailbox;
+
+	AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) {
+		struct ast_event *event;
+		event = ast_event_get_cached(AST_EVENT_MWI,
+			AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox->mailbox,
+			AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, S_OR(mailbox->context, "default"),
+			AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_EXISTS,
+			AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_EXISTS,
+			AST_EVENT_IE_END);
+		if (!event)
+			continue;
+		*new += ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
+		*old += ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS);
+		ast_event_destroy(event);
+	}
+
+	return (*new || *old) ? 0 : 1;
+}
+
 /*! \brief Send message waiting indication to alert peer that they've got voicemail */
 static int sip_send_mwi_to_peer(struct sip_peer *peer, const struct ast_event *event, int cache_only)
 {
 	/* Called with peerl lock, but releases it */
 	struct sip_pvt *p;
 	int newmsgs = 0, oldmsgs = 0;
-	struct ast_event *cache_event = NULL;
 
 	if (ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY) && !peer->mwipvt)
 		return 0;
@@ -16249,30 +16331,18 @@
 	if (!peer->addr.sin_addr.s_addr && !peer->defaddr.sin_addr.s_addr) 
 		return 0;
 
-	if (!event) {
-		char *mailbox, *context = NULL;
-		/* Check the event cache for the mailbox info */
-		context = mailbox = ast_strdupa(peer->mailbox);
-		strsep(&context, "@");
-		if (ast_strlen_zero(context))
-			context = "default";
-		event = cache_event = ast_event_get_cached(AST_EVENT_MWI,
-			AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
-			AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
-			AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_EXISTS,
-			AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_EXISTS,
-			AST_EVENT_IE_END);
-	}
-
 	if (event) {
 		newmsgs = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
 		oldmsgs = ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS);
-		if (cache_event)
-			ast_event_destroy(cache_event);
+	} else if (!get_cached_mwi(peer, &newmsgs, &oldmsgs)) {
+		/* got it!  Don't keep looking. */
 	} else if (cache_only) {
 		return 0;
-	} else /* Fall back to manually checking the mailbox */
-		ast_app_inboxcount(peer->mailbox, &newmsgs, &oldmsgs);
+	} else { /* Fall back to manually checking the mailbox */
+		struct ast_str *mailbox_str = ast_str_alloca(512);
+		peer_mailboxes_to_str(&mailbox_str, peer);
+		ast_app_inboxcount(mailbox_str->str, &newmsgs, &oldmsgs);
+	}
 	
 	if (peer->mwipvt) {
 		/* Base message on subscription */
@@ -17212,11 +17282,11 @@
 	peer->fromdomain[0] = '\0';
 	peer->fromuser[0] = '\0';
 	peer->regexten[0] = '\0';
-	peer->mailbox[0] = '\0';
 	peer->callgroup = 0;
 	peer->pickupgroup = 0;
 	peer->maxms = default_qualify;
 	peer->prefs = default_prefs;
+	clear_peer_mailboxes(peer);
 }
 
 /*! \brief Create temporary peer (used in autocreatepeer mode) */
@@ -17239,6 +17309,30 @@
 	reg_source_db(peer);
 
 	return peer;
+}
+
+static void add_peer_mailboxes(struct sip_peer *peer, const char *value)
+{
+	char *next, *mbox, *context;
+
+	next = ast_strdupa(value);
+
+	while ((mbox = context = strsep(&next, ","))) {
+		struct sip_mailbox *mailbox;
+
+		if (!(mailbox = ast_calloc(1, sizeof(*mailbox))))
+			continue;
+
+		strsep(&context, "@");
+		if (ast_strlen_zero(mbox)) {
+			free(mailbox);
+			continue;
+		}
+		mailbox->mailbox = ast_strdup(mbox);
+		mailbox->context = ast_strdup(context);
+
+		AST_LIST_INSERT_TAIL(&peer->mailboxes, mailbox, entry);
+	}
 }
 
 /*! \brief Build peer from configuration (file or realtime static/dynamic) */
@@ -17427,7 +17521,7 @@
 		} else if (!strcasecmp(v->name, "mohsuggest")) {
 			ast_copy_string(peer->mohsuggest, v->value, sizeof(peer->mohsuggest));
 		} else if (!strcasecmp(v->name, "mailbox")) {
-			ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox));
+			add_peer_mailboxes(peer, v->value);
 		} else if (!strcasecmp(v->name, "subscribemwi")) {
 			ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_SUBSCRIBEMWIONLY);
 		} else if (!strcasecmp(v->name, "vmexten")) {
@@ -17499,16 +17593,8 @@
 	/* If they didn't request that MWI is sent *only* on subscribe, go ahead and
 	 * subscribe to it now. */
 	if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY) && 
-		!ast_strlen_zero(peer->mailbox)) {
-		char *mailbox, *context;
-		context = mailbox = ast_strdupa(peer->mailbox);
-		strsep(&context, "@");
-		if (ast_strlen_zero(context))
-			context = "default";
-		peer->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, peer,
-			AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
-			AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
-			AST_EVENT_IE_END);
+		!AST_LIST_EMPTY(&peer->mailboxes)) {
+		add_peer_mwi_subs(peer);
 		/* Send MWI from the event cache only.  This is so we can send initial
 		 * MWI if app_voicemail got loaded before chan_sip.  If it is the other
 		 * way, then we will get events when app_voicemail gets loaded. */

Modified: team/murf/bug_7638/configs/queues.conf.sample
URL: http://svn.digium.com/view/asterisk/team/murf/bug_7638/configs/queues.conf.sample?view=diff&rev=79012&r1=79011&r2=79012
==============================================================================
--- team/murf/bug_7638/configs/queues.conf.sample (original)
+++ team/murf/bug_7638/configs/queues.conf.sample Fri Aug 10 10:32:29 2007
@@ -344,6 +344,10 @@
 ; messages as a "friendly name".  Multiple interfaces may share a single
 ; member name.
 ;
+; It is important to ensure that channel drivers used for members are loaded
+; before app_queue.so itself or they may be marked invalid until reload. This
+; can be accomplished by explicitly listing them in modules.conf before app_queue.so
+;
 ;member => Zap/1
 ;member => Zap/2,10
 ;member => Zap/3,10,Bob Johnson

Modified: team/murf/bug_7638/main/file.c
URL: http://svn.digium.com/view/asterisk/team/murf/bug_7638/main/file.c?view=diff&rev=79012&r1=79011&r2=79012
==============================================================================
--- team/murf/bug_7638/main/file.c (original)
+++ team/murf/bug_7638/main/file.c Fri Aug 10 10:32:29 2007
@@ -986,6 +986,9 @@
 		forward = "";
 	if (!rewind)
 		rewind = "";
+
+	/* Switch the channel to end DTMF frame only. waitstream_core doesn't care about the start of DTMF. */
+	ast_set_flag(c, AST_FLAG_END_DTMF_ONLY);
 	
 	while (c->stream) {
 		int res;
@@ -1000,6 +1003,7 @@
 			res = ast_waitfor(c, ms);
 			if (res < 0) {
 				ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno));
+				ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
 				return res;
 			}
 		} else {
@@ -1010,9 +1014,11 @@
 				if (errno == EINTR)
 					continue;
 				ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
+				ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
 				return -1;
 			} else if (outfd > -1) { /* this requires cmdfd set */
 				/* The FD we were watching has something waiting */
+				ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
 				return 1;
 			}
 			/* if rchan is set, it is 'c' */
@@ -1020,8 +1026,10 @@
 		}
 		if (res > 0) {
 			struct ast_frame *fr = ast_read(c);
-			if (!fr)
+			if (!fr) {
+				ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
 				return -1;
+			}
 			switch (fr->frametype) {
 			case AST_FRAME_DTMF_END:
 				if (context) {
@@ -1029,6 +1037,7 @@
 					if (ast_exists_extension(c, context, exten, 1, c->cid.cid_num)) {
 						res = fr->subclass;
 						ast_frfree(fr);
+						ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
 						return res;
 					}
 				} else {
@@ -1039,6 +1048,7 @@
 						ast_stream_rewind(c->stream, skip_ms);
 					} else if (strchr(breakon, res)) {
 						ast_frfree(fr);
+						ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
 						return res;
 					}					
 				}

[... 19 lines stripped ...]



More information about the asterisk-commits mailing list