Index: apps/app_voicemail.c
===================================================================
--- apps/app_voicemail.c	(revision 96691)
+++ apps/app_voicemail.c	(working copy)
@@ -167,6 +167,10 @@
 #define MAXMSGLIMIT 255
 #endif
 
+/* for send message to multiple receivers.
+See the comments on the leave_voicemail() below, it internally allocates a string array that is 1024 chars long.so our max string length of the generated recipients must be less than this*/
+#define MAX_FORWARD_MESSAGE_RECEIVER_STRING 1024
+
 #define BASEMAXINLINE 256
 #define BASELINELEN 72
 #define BASEMAXINLINE 256
@@ -191,6 +195,7 @@
 #define VM_ALLOCED       (1 << 13)
 #define VM_SEARCH        (1 << 14)
 #define VM_TEMPGREETWARN (1 << 15)  /*!< Remind user tempgreeting is set */
+#define VM_MOVEHEARD     (1 << 16)  /*!< Move a "heard" message to Old after listening to it */
 #define ERROR_LOCK_PATH  -100
 
 
@@ -605,6 +610,9 @@
 		ast_set2_flag(vmu, ast_true(value), VM_OPERATOR);	
 	} else if (!strcasecmp(var, "envelope")){
 		ast_set2_flag(vmu, ast_true(value), VM_ENVELOPE);	
+	} else if (!strcasecmp(var, "moveheard")){
+		ast_log(LOG_DEBUG, "applying moveheard=%s\n", value);
+		ast_set2_flag(vmu, ast_true(value), VM_MOVEHEARD);
 	} else if (!strcasecmp(var, "sayduration")){
 		ast_set2_flag(vmu, ast_true(value), VM_SAYDURATION);	
 	} else if (!strcasecmp(var, "saydurationm")){
@@ -2800,7 +2808,9 @@
 	char fmt[80];
 	char *context;
 	char ecodes[16] = "#";
-	char tmp[1024] = "", *tmpptr;
+	/*char tmp[1024] = "", *tmpptr;*/
+	char tmp[MAX_FORWARD_MESSAGE_RECEIVER_STRING] = "";
+	char *tmpptr;
 	struct ast_vm_user *vmu;
 	struct ast_vm_user svm;
 	const char *category = NULL;
@@ -3973,14 +3983,20 @@
 	const char *s;
 	int saved_messages = 0, found = 0;
 	int valid_extensions = 0;
+	int add_recipient = 0;
 	char *dir;
 	int curmsg;
+  int num_receivers = 0;
+	char recipients[MAX_FORWARD_MESSAGE_RECEIVER_STRING];
 
+	bzero(recipients,MAX_FORWARD_MESSAGE_RECEIVER_STRING);
+
 	if (vms == NULL) return -1;
 	dir = vms->curdir;
 	curmsg = vms->curmsg;
 	
 	while (!res && !valid_extensions) {
+		add_recipient = 0;
 		int use_directory = 0;
 		if (ast_test_flag((&globalflags), VM_DIRECFORWARD)) {
 			int done = 0;
@@ -4056,15 +4072,18 @@
 		} else {
 			/* Ask for an extension */
 			res = ast_streamfile(chan, "vm-extension", chan->language);	/* "extension" */
-			if (res)
+			if (res) {
 				break;
-			if ((res = ast_readstring(chan, username, sizeof(username) - 1, 2000, 10000, "#") < 0))
+			}
+			if ((res = ast_readstring(chan, username, sizeof(username) - 1, 2000, 10000, "#") < 0)) {
 				break;
+			}
 		}
 		
 		/* start all over if no username */
-		if (ast_strlen_zero(username))
+		if (ast_strlen_zero(username)) {
 			continue;
+		}
 		stringp = username;
 		s = strsep(&stringp, "*");
 		/* start optimistic */
@@ -4081,23 +4100,133 @@
 			s = strsep(&stringp, "*");
 		}
 		/* break from the loop of reading the extensions */
-		if (valid_extensions)
+		if (valid_extensions) {
+			/* break; */
+			/* for send message to multiple receivers*/
+			if (flag == 1) {
+				/* we are interested in multiple recipients only for 3->5 option */
+
+				int done = 0;
+				int retries = 0;
+
+				while ((cmd >= 0) && !done) {
+					cmd = 0;
+					while ((cmd >= 0) && !done ) {
+						if (cmd) {
+							retries = 0;
+						}
+	
+						switch (cmd) {
+							case '1':
+							add_recipient = 0;
+							done = 1;
+							break;
+		
+							case '2':
+							add_recipient = 1;
+							done=1;
+							break;
+		
+							case '*':
+							cmd = 't';
+							done = 1;
+							break;
+		
+							default:
+							/* Press 1 to enter an send message, press 2 add another recipient */
+							cmd = ast_play_and_wait(chan,"vm-forward-multiple");
+							if (!cmd) {
+								cmd = ast_waitfordigit(chan,3000);
+							}
+		
+							if (!cmd) {
+								retries++;
+							}
+		
+							if (retries > 3) {
+								cmd = 't';
+								done = 1;
+							}
+						} /* switch	*/
+		
+					} /* while reading multiple receiver prompt */
+				
+					if (cmd == 't') {
+						valid_extensions = 1;
+						break;
+					}
+
+					/* make sure we can actually add another recipient, play an error message if adding this recipient would be too large */
+					if (strlen(recipients) + 40  >= MAX_FORWARD_MESSAGE_RECEIVER_STRING && add_recipient == 1) {
+						res = ast_play_and_wait(chan, "vm-forward-multiple-too-many");
+
+						//valid_extensions = 0;
+						done = 0;
+
+						ast_log(LOG_DEBUG, "adding another recipient would exceed max length of recipient buffer of %d (current size is %d)\n", MAX_FORWARD_MESSAGE_RECEIVER_STRING, strlen(recipients));
+					}
+					else {
+						/* append the user to the recipients string. */
+						char mailbox[AST_MAX_EXTENSION * 2 + 2];
+
+						if ( strlen(recipients) > 0) {
+							strcat(recipients, "&");
+						}
+
+						snprintf(mailbox, sizeof(mailbox), "%s@%s", username, context);
+						strcat(recipients, mailbox);
+	
+						num_receivers++;
+						if (add_recipient == 1) {
+							valid_extensions = 0;
+	
+							ast_log(LOG_DEBUG, "adding recipient %s and returing to add another. num_receivers=%d\n", username, num_receivers);
+						}
+						else {
+							valid_extensions = 1;
+							ast_log(LOG_DEBUG, "adding recipient %s and continuing to record message. num_receivers=%d\n", username, num_receivers);
+			
+						}
+						done = 1; 
+					}
+				} /* while !done reading multiple recipients. */
+				
+			}
+			else {
+				/* this is to forward the message (option 8). */
+				/* currently we do not need the multiple-recipients functionality */
+				/* so we just do the what this block used to do */
+				valid_extensions = 1;
+				ast_log(LOG_DEBUG, "option 8, not processing multiple recipients.\n");
+			}
+		}
+		if (valid_extensions) {
 			break;
-		/* "I am sorry, that's not a valid extension.  Please try again." */
-		res = ast_play_and_wait(chan, "pbx-invalid");
+		}
+		if (!add_recipient) {
+			/* "I am sorry, that's not a valid extension.  Please try again." */
+			res = ast_play_and_wait(chan, "pbx-invalid");
+		}
 	}
 	/* check if we're clear to proceed */
-	if (AST_LIST_EMPTY(&extensions) || !valid_extensions)
+	if (AST_LIST_EMPTY(&extensions) || !valid_extensions) {
 		return res;
+	}
 	if (flag==1) {
 		struct leave_vm_options leave_options;
+		/*
 		char mailbox[AST_MAX_EXTENSION * 2 + 2];
 		snprintf(mailbox, sizeof(mailbox), "%s@%s", username, context);
-
+		*/
+		ast_log(LOG_DEBUG, "sending voicemail to %d recipients\n", num_receivers);
+		ast_log(LOG_DEBUG, "using recipient string: %s\n", recipients);
 		/* Send VoiceMail */
 		memset(&leave_options, 0, sizeof(leave_options));
 		leave_options.record_gain = record_gain;
-		cmd = leave_voicemail(chan, mailbox, &leave_options);
+		/* cmd = leave_voicemail(chan, mailbox, &leave_options); */
+		ast_log(LOG_DEBUG, "calling leave_voicemail()");
+		cmd = leave_voicemail(chan, recipients, &leave_options);
+		ast_log(LOG_DEBUG, "after leave_voicemail(), finished delivering voicemail to %d recipients.\n", num_receivers);
 	} else {
 
 		/* Forward VoiceMail */
@@ -4852,7 +4981,7 @@
 		return ERROR_LOCK_PATH;
 	 
 	for (x = 0; x < vmu->maxmsg; x++) { 
-		if (!vms->deleted[x] && (strcasecmp(vms->curbox, "INBOX") || !vms->heard[x])) { 
+		if (!vms->deleted[x] && (strcasecmp(vms->curbox, "INBOX") || !vms->heard[x] || (vms->heard[x] && !ast_test_flag(vmu, VM_MOVEHEARD)))) { 
 			/* Save this message.  It's not in INBOX or hasn't been heard */ 
 			make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 
 			if (!EXISTS(vms->curdir, x, vms->fn, NULL)) 
@@ -4862,7 +4991,7 @@
 			if (strcmp(vms->fn, vms->fn2)) { 
 				RENAME(vms->curdir, x, vmu->mailbox,vmu->context, vms->curdir, vms->curmsg, vms->fn, vms->fn2);
 			} 
-		} else if (!strcasecmp(vms->curbox, "INBOX") && vms->heard[x] && !vms->deleted[x]) { 
+			} else if (!strcasecmp(vms->curbox, "INBOX") && vms->heard[x] && ast_test_flag(vmu, VM_MOVEHEARD) && !vms->deleted[x]) {
 			/* Move to old folder before deleting */ 
 			res = save_to_folder(vmu, vms, x, 1);
 			if (res == ERROR_LOCK_PATH) {
@@ -7334,6 +7463,7 @@
 	const char *exitcxt = NULL;	
 	const char *extpc;
 	const char *emaildateformatstr;
+	const char *val;
 	const char *volgainstr;
 	int x;
 	int tmpadsi[4];
@@ -7618,6 +7748,12 @@
 		}
 		ast_set2_flag((&globalflags), ast_true(asthearenv), VM_ENVELOPE);	
 
+		if (!(val = ast_variable_retrieve(cfg, "general", "moveheard"))) {
+			ast_log(LOG_DEBUG,"Move Heard enabled globally\n");
+			val = "yes";
+		}
+		ast_set2_flag((&globalflags), ast_true(val), VM_MOVEHEARD);	
+
 		if (!(astsaydurationinfo = ast_variable_retrieve(cfg, "general", "sayduration"))) {
 			if (option_debug)
 				ast_log(LOG_DEBUG,"Duration info before msg enabled globally\n");
