[asterisk-commits] jpeeler: branch 1.6.2 r293118 - in /branches/1.6.2: ./ apps/app_voicemail.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Oct 26 13:33:27 CDT 2010


Author: jpeeler
Date: Tue Oct 26 13:33:24 2010
New Revision: 293118

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=293118
Log:
Merged revisions 293004 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
  r293004 | jpeeler | 2010-10-25 17:55:28 -0500 (Mon, 25 Oct 2010) | 29 lines
  
  Fix inprocess_container in voicemail to correctly restrict max messages.
  
  The comparison function logic was off, so the number of sessions for a given
  mailbox were not being incremented properly. This problem caused the maximum
  number of messages per folder to not be respected when simultaneously leaving
  multiple voicemails just below the threshold. 
  
  These problems should be fixed by the above, but just in case:
  Fixed resequence_mailbox to rely on the actual number of detected number of
  files in a directory rather than just assuming only 10 messages more than the
  maximum had been left. Also if more messages than the maximum are deleted they
  are actually removed now.
  
  
  The second purpose of this commit should have been separated out probably, but
  is related to the above. Again, if the number of messages in a given voicemail
  folder exceeds the maximum set limit make sure to allocate enough space for the
  deleted and heard index tracking array.
  
  A few random fixes:
  There was a forgotten decrement of the inprocess count in imap_store_file.
  
  When using IMAP storage, do not look in the directory where file based storage
  messages may still reside and influence the message count.
  
  Ensure to use only the first format in sendmail.
  
  ABE-2516
........

Modified:
    branches/1.6.2/   (props changed)
    branches/1.6.2/apps/app_voicemail.c

Propchange: branches/1.6.2/
------------------------------------------------------------------------------
Binary property 'branch-1.4-merged' - no diff available.

Modified: branches/1.6.2/apps/app_voicemail.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.6.2/apps/app_voicemail.c?view=diff&rev=293118&r1=293117&r2=293118
==============================================================================
--- branches/1.6.2/apps/app_voicemail.c (original)
+++ branches/1.6.2/apps/app_voicemail.c Tue Oct 26 13:33:24 2010
@@ -627,6 +627,7 @@
 	char intro[PATH_MAX];
 	int *deleted;
 	int *heard;
+	int dh_arraysize; /* used for deleted / heard allocation */
 	int curmsg;
 	int lastmsg;
 	int newmessages;
@@ -851,7 +852,7 @@
 static int inprocess_cmp_fn(void *obj, void *arg, int flags)
 {
 	struct inprocess *i = obj, *j = arg;
-	if (!strcmp(i->mailbox, j->mailbox)) {
+	if (strcmp(i->mailbox, j->mailbox)) {
 		return 0;
 	}
 	return !strcmp(i->context, j->context) ? CMP_MATCH : 0;
@@ -869,6 +870,9 @@
 		ao2_unlock(inprocess_container);
 		ao2_ref(i, -1);
 		return ret;
+	}
+	if (delta < 0) {
+		ast_log(LOG_WARNING, "BUG: ref count decrement on non-existing object???\n");
 	}
 	if (!(i = ao2_alloc(sizeof(*i) + strlen(context) + strlen(mailbox) + 2, NULL))) {
 		ao2_unlock(inprocess_container);
@@ -1546,6 +1550,33 @@
 	}
 }
 
+static int vm_allocate_dh(struct vm_state *vms, struct ast_vm_user *vmu, int count_msg) {
+
+	int arraysize = (vmu->maxmsg > count_msg ? vmu->maxmsg : count_msg);
+	if (!vms->dh_arraysize) {
+		/* initial allocation */
+		if (!(vms->deleted = ast_calloc(arraysize, sizeof(int)))) {
+			return -1;
+		}
+		if (!(vms->heard = ast_calloc(arraysize, sizeof(int)))) {
+			return -1;
+		}
+		vms->dh_arraysize = arraysize;
+	} else if (vms->dh_arraysize < arraysize) {
+		if (!(vms->deleted = ast_realloc(vms->deleted, arraysize * sizeof(int)))) {
+			return -1;
+		}
+		if (!(vms->heard = ast_realloc(vms->heard, arraysize * sizeof(int)))) {
+			return -1;
+		}
+		memset(vms->deleted, 0, arraysize * sizeof(int));
+		memset(vms->heard, 0, arraysize * sizeof(int));
+		vms->dh_arraysize = arraysize;
+	}
+
+	return 0;
+}
+
 /* All IMAP-specific functions should go in this block. This
  * keeps them from being spread out all over the code */
 #ifdef IMAP_STORAGE
@@ -1947,9 +1978,11 @@
 	}
 	
 	/* Check if we have exceeded maxmsg */
-	if (msgnum >= vmu->maxmsg  - inprocess_count(vmu->mailbox, vmu->context, 0)) {
-		ast_log(AST_LOG_WARNING, "Unable to leave message since we will exceed the maximum number of messages allowed (%u > %u)\n", msgnum, vmu->maxmsg);
+	ast_debug(3, "Checking message number quota: mailbox has %d messages, maximum is set to %d, current messages %d\n", msgnum, vmu->maxmsg, inprocess_count(vmu->mailbox, vmu->context, 0));
+	if (msgnum >= vmu->maxmsg - inprocess_count(vmu->mailbox, vmu->context, +1)) {
+		ast_log(LOG_WARNING, "Unable to leave message since we will exceed the maximum number of messages allowed (%u >= %u)\n", msgnum, vmu->maxmsg);
 		ast_play_and_wait(chan, "vm-mailboxfull");
+		pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
 		return -1;
 	}
 
@@ -2095,7 +2128,7 @@
 	
 	if (tempcopy)
 		*(vmu->email) = '\0';
-	
+	inprocess_count(vmu->mailbox, vmu->context, -1);
 	return 0;
 
 }
@@ -2422,6 +2455,16 @@
 	mail_search_full (vms->mailstream, NULL, pgm, NIL);
 	vms->lastmsg = vms->vmArrayIndex - 1;
 	mail_free_searchpgm(&pgm);
+	/* Since IMAP storage actually stores both old and new messages in the same IMAP folder,
+	 * ensure to allocate enough space to account for all of them. Warn if old messages
+	 * have not been checked first as that is required.
+	 */
+	if (box == 0 && !vms->dh_arraysize) {
+		ast_log(LOG_WARNING, "The code expects the old messages to be checked first, fix the code.\n");
+	}
+	if (vm_allocate_dh(vms, vmu, box == 0 ? vms->vmArrayIndex + vms->oldmessages : vms->lastmsg)) {
+		return -1;
+	}
 
 	ast_mutex_unlock(&vms->lock);
 	return 0;
@@ -4533,11 +4576,18 @@
 	FILE *p=NULL;
 	char tmp[80] = "/tmp/astmail-XXXXXX";
 	char tmp2[256];
+	char *stringp;
 
 	if (vmu && ast_strlen_zero(vmu->email)) {
 		ast_log(AST_LOG_WARNING, "E-mail address missing for mailbox [%s].  E-mail will not be sent.\n", vmu->mailbox);
 		return(0);
 	}
+
+	/* Mail only the first format */
+	format = ast_strdupa(format);
+	stringp = format;
+	strsep(&stringp, "|");
+
 	if (!strcmp(format, "wav49"))
 		format = "WAV";
 	ast_debug(3, "Attaching file '%s', format '%s', uservm is '%d', global is %d\n", attach, format, attach_user_voicemail, ast_test_flag((&globalflags), VM_ATTACH));
@@ -5286,7 +5336,14 @@
 
 	DISPOSE(tempfile, -1);
 	/* It's easier just to try to make it than to check for its existence */
+#ifndef IMAP_STORAGE
 	create_dirpath(dir, sizeof(dir), vmu->context, ext, "INBOX");
+#else
+	snprintf(dir, sizeof(dir), "%simap", VM_SPOOL_DIR);
+	if (mkdir(dir, VOICEMAIL_DIR_MODE) && errno != EEXIST) {
+		ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dir, strerror(errno));
+	}
+#endif
 
 	/* Check current or macro-calling context for special extensions */
 	if (ast_test_flag(vmu, VM_OPERATOR)) {
@@ -5449,7 +5506,7 @@
 		/* here is a big difference! We add one to it later */
 		msgnum = newmsgs + oldmsgs;
 		ast_debug(3, "Messagecount set to %d\n",msgnum);
-		snprintf(fn, sizeof(fn), "%s/imap/msg%s%04d", VM_SPOOL_DIR, vmu->mailbox, msgnum);
+		snprintf(fn, sizeof(fn), "%simap/msg%s%04d", VM_SPOOL_DIR, vmu->mailbox, msgnum);
 		/* set variable for compatibility */
 		pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE");
 
@@ -6527,7 +6584,11 @@
 	}
 	ast_channel_unlock(chan);
 
+#ifndef IMAP_STORAGE
 	make_dir(todir, sizeof(todir), vmu->context, vmu->mailbox, !ast_strlen_zero(flag) && !strcmp(flag, "Urgent") ? "Urgent" : "INBOX");
+#else
+	snprintf(todir, sizeof(todir), "%simap", VM_SPOOL_DIR);
+#endif
 	make_file(fn, sizeof(fn), todir, msgnum);
 	snprintf(ext_context, sizeof(ext_context), "%s@%s", vmu->mailbox, vmu->context);
 
@@ -7326,11 +7387,16 @@
 	/* Faster to make the directory than to check if it exists. */
 	create_dirpath(vms->curdir, sizeof(vms->curdir), vmu->context, vms->username, vms->curbox);
 
+	/* traverses directory using readdir (or select query for ODBC) */
 	count_msg = count_messages(vmu, vms->curdir);
 	if (count_msg < 0) {
 		return count_msg;
 	} else {
 		vms->lastmsg = count_msg - 1;
+	}
+
+	if (vm_allocate_dh(vms, vmu, count_msg)) {
+		return -1;
 	}
 
 	/*
@@ -7345,11 +7411,14 @@
 		return -1;
 	}
 
+	/* for local storage, checks directory for messages up to maxmsg limit */
 	last_msg = last_message_index(vmu, vms->curdir);
 	ast_unlock_path(vms->curdir);
 
 	if (last_msg < 0) {
 		return last_msg;
+	} else if (vms->lastmsg != last_msg) {
+		ast_log(LOG_NOTICE, "Mailbox: %s, expected %d but found %d message(s) in box with max threshold of %d.\n", vms->curdir, last_msg + 1, vms->lastmsg + 1, vmu->maxmsg);
 	}
 
 	return 0;
@@ -7375,7 +7444,8 @@
 		return ERROR_LOCK_PATH;
 	}
 
-	for (x = 0; x < vmu->maxmsg; x++) {
+	/* must check up to last detected message, just in case it is erroneously greater than maxmsg */
+	for (x = 0; x < vms->lastmsg + 1; x++) {
 		if (!vms->deleted[x] && ((strcasecmp(vms->curbox, "INBOX") && strcasecmp(vms->curbox, "Urgent")) || !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);
@@ -7429,7 +7499,7 @@
 	if (vms->deleted) {
 		/* Since we now expunge after each delete, deleting in reverse order
 		 * ensures that no reordering occurs between each step. */
-		for (x = vmu->maxmsg - 1; x >= 0; x--) {
+		for (x = vms->dh_arraysize - 1; x >= 0; x--) {
 			if (vms->deleted[x]) {
 				ast_debug(3, "IMAP delete of %d\n", x);
 				DELETE(vms->curdir, x, vms->fn, vmu);
@@ -7440,10 +7510,10 @@
 
 done:
 	if (vms->deleted) {
-		memset(vms->deleted, 0, vmu->maxmsg * sizeof(int));
+		memset(vms->deleted, 0, vms->dh_arraysize * sizeof(int));
 	}
 	if (vms->heard) {
-		memset(vms->heard, 0, vmu->maxmsg * sizeof(int));
+		memset(vms->heard, 0, vms->dh_arraysize * sizeof(int));
 	}
 
 	return 0;
@@ -9327,20 +9397,20 @@
 	/* Retrieve urgent, old and new message counts */
 	ast_debug(1, "Before open_mailbox\n");
 	res = open_mailbox(&vms, vmu, OLD_FOLDER); /* Count all messages, even Urgent */
-	if (res == ERROR_LOCK_PATH)
+	if (res < 0)
 		goto out;
 	vms.oldmessages = vms.lastmsg + 1;
 	ast_debug(1, "Number of old messages: %d\n",vms.oldmessages);
 	/* check INBOX */
 	res = open_mailbox(&vms, vmu, NEW_FOLDER);
-	if (res == ERROR_LOCK_PATH)
+	if (res < 0)
 		goto out;
 	vms.newmessages = vms.lastmsg + 1;
 	ast_debug(1, "Number of new messages: %d\n",vms.newmessages);
 	/* Start in Urgent */
 	in_urgent = 1;
 	res = open_mailbox(&vms, vmu, 11); /*11 is the Urgent folder */
-	if (res == ERROR_LOCK_PATH)
+	if (res < 0)
 		goto out;
 	vms.urgentmessages = vms.lastmsg + 1;
 	ast_debug(1, "Number of urgent messages: %d\n",vms.urgentmessages);
@@ -9354,7 +9424,7 @@
 			in_urgent = 0;
 			res = open_mailbox(&vms, vmu, play_folder);
 		}
-		if (res == ERROR_LOCK_PATH)
+		if (res < 0)
 			goto out;
 
 		/* If there are no new messages, inform the user and hangup */
@@ -9370,13 +9440,13 @@
 			res = open_mailbox(&vms, vmu, OLD_FOLDER); /* Count all messages, even Urgent */
 			in_urgent = 0;
 			play_folder = 1;
-			if (res == ERROR_LOCK_PATH)
+			if (res < 0)
 				goto out;
 		} else if (!vms.urgentmessages && vms.newmessages) {
 			/* If we have new messages but none are urgent */
 			in_urgent = 0;
 			res = open_mailbox(&vms, vmu, NEW_FOLDER);
-			if (res == ERROR_LOCK_PATH)
+			if (res < 0)
 				goto out;
 		}
 	}
@@ -9444,7 +9514,7 @@
 				/* If folder is not urgent, set in_urgent to zero! */
 				if (cmd != 11) in_urgent = 0;
 				res = open_mailbox(&vms, vmu, cmd);
-				if (res == ERROR_LOCK_PATH)
+				if (res < 0)
 					goto out;
 				play_folder = cmd;
 				cmd = 0;
@@ -9575,7 +9645,7 @@
 					if (res == ERROR_LOCK_PATH)
 						goto out;
 					res = open_mailbox(&vms, vmu, 11);  /* Open Urgent folder */
-					if (res == ERROR_LOCK_PATH)
+					if (res < 0)
 						goto out;
 					ast_debug(1, "No more new messages, opened INBOX and got %d Urgent messages\n",vms.lastmsg + 1);
 					vms.curmsg = vms.lastmsg;
@@ -9604,7 +9674,7 @@
 					if (res == ERROR_LOCK_PATH)
 						goto out;
 					res = open_mailbox(&vms, vmu, NEW_FOLDER);
-					if (res == ERROR_LOCK_PATH)
+					if (res < 0)
 						goto out;
 					ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n",vms.lastmsg + 1);
 					vms.curmsg = -1;
@@ -9666,7 +9736,7 @@
 							if (res == ERROR_LOCK_PATH)
 								goto out;
 							res = open_mailbox(&vms, vmu, NEW_FOLDER);
-							if (res == ERROR_LOCK_PATH)
+							if (res < 0)
 								goto out;
 							ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n",vms.lastmsg + 1);
 							vms.curmsg = -1;
@@ -9703,7 +9773,7 @@
 					if (res == ERROR_LOCK_PATH)
 						goto out;
 					res = open_mailbox(&vms, vmu, NEW_FOLDER);
-					if (res == ERROR_LOCK_PATH)
+					if (res < 0)
 						goto out;
 					ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n",vms.lastmsg + 1);
 					vms.curmsg = -1;
@@ -9776,7 +9846,7 @@
 						if (res == ERROR_LOCK_PATH)
 							goto out;
 						res = open_mailbox(&vms, vmu, NEW_FOLDER);
-						if (res == ERROR_LOCK_PATH)
+						if (res < 0)
 							goto out;
 						ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n",vms.lastmsg + 1);
 						vms.curmsg = -1;




More information about the asterisk-commits mailing list