[asterisk-commits] mmichelson: branch mmichelson/imap_consistency_trunk r134249 - /team/mmichels...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Jul 29 15:16:38 CDT 2008


Author: mmichelson
Date: Tue Jul 29 15:16:37 2008
New Revision: 134249

URL: http://svn.digium.com/view/asterisk?view=rev&rev=134249
Log:
Resolve a bunch of conflicts.

The main conflicts left to resolve revolve around the
play_message and imap_retrieve_file functions.


Modified:
    team/mmichelson/imap_consistency_trunk/apps/app_voicemail.c

Modified: team/mmichelson/imap_consistency_trunk/apps/app_voicemail.c
URL: http://svn.digium.com/view/asterisk/team/mmichelson/imap_consistency_trunk/apps/app_voicemail.c?view=diff&rev=134249&r1=134248&r2=134249
==============================================================================
--- team/mmichelson/imap_consistency_trunk/apps/app_voicemail.c (original)
+++ team/mmichelson/imap_consistency_trunk/apps/app_voicemail.c Tue Jul 29 15:16:37 2008
@@ -1258,39 +1258,24 @@
 	return snprintf(dest, len, "%s%s/%s/%s", VM_SPOOL_DIR, context, ext, folder);
 }
 
-<<<<<<< .working
-#ifdef IMAP_STORAGE
-static int make_gsm_file(char *dest, size_t len, char *imapuser, char *dir, int num, char *prefix)
-=======
+/*! 
+ * \brief Creates a file system path expression for a folder within the voicemail data folder and the appropriate context.
+ * \param dest The variable to hold the output generated path expression. This buffer should be of size PATH_MAX.
+ * \param len The length of the path string that was written out.
+ * 
+ * The path is constructed as 
+ * 	VM_SPOOL_DIRcontext/ext/folder
+ *
+ * \return zero on success, -1 on error.
+ */
 static int make_file(char *dest, const int len, const char *dir, const int num)
->>>>>>> .merge-right.r134223
-{
-<<<<<<< .working
-	int res;
-	if ((res = ast_mkdir(dir, 01777))) {
-		ast_log(AST_LOG_WARNING, "ast_mkdir '%s' failed: %s\n", dir, strerror(res));
-		return snprintf(dest, len, "%s/%s%04d", dir, prefix, num);
-	}
-=======
->>>>>>> .merge-right.r134223
+{
 	return snprintf(dest, len, "%s/%s%04d", dir, prefix, num);
 }
 
 /* same as mkstemp, but return a FILE * */
 static FILE *vm_mkftemp(char *template)
 {
-<<<<<<< .working
-	unsigned long messageNum = 0;
-	char arg[10];
-
-	/* find real message number based on msgnum */
-	/* this may be an index into vms->msgArray based on the msgnum. */
-
-	messageNum = vms->msgArray[msgnum];
-	if (messageNum == 0) {
-		ast_log(AST_LOG_WARNING, "msgnum %d, mailbox message %lu is zero.\n", msgnum, messageNum);
-		return;
-=======
 	FILE *p = NULL;
 	int pfd = mkstemp(template);
 	chmod(template, VOICEMAIL_FILE_MODE & ~my_umask);
@@ -1300,16 +1285,8 @@
 			close(pfd);
 			pfd = -1;
 		}
->>>>>>> .merge-right.r134223
-	}
-<<<<<<< .working
-	ast_debug(3, "deleting msgnum %d, which is mailbox message %lu\n",msgnum,messageNum);
-	/* delete message */
-	snprintf (arg, sizeof(arg), "%lu",messageNum);
-	mail_setflag (vms->mailstream,arg,"\\DELETED");
-=======
+	}
 	return p;
->>>>>>> .merge-right.r134223
 }
 
 /*! \brief basically mkdir -p $dest/$context/$ext/$folder
@@ -1333,14 +1310,14 @@
 	return 0;
 }
 
-<<<<<<< .working
-/*! \brief Lock file path
-    only return failure if ast_lock_path returns 'timeout',
-=======
 static const char *mbox(int id)
 {
 	static const char *msgs[] = {
+#ifdef IMAP_STORAGE
+		imapfolder,
+#else
 		"INBOX",
+#endif
 		"Old",
 		"Work",
 		"Family",
@@ -1350,14 +1327,16 @@
 		"Cust3",
 		"Cust4",
 		"Cust5",
+		"Deleted",
+		"Urgent"
 	};
-	return (id >= 0 && id < (sizeof(msgs)/sizeof(msgs[0]))) ? msgs[id] : "tmp";
+	return (id >= 0 && id < (sizeof(msgs)/sizeof(msgs[0]))) ? msgs[id] : "Unknown";
 }
 
 static void free_user(struct ast_vm_user *vmu)
 {
 	if (ast_test_flag(vmu, VM_ALLOCED))
-		free(vmu);
+		ast_free(vmu);
 }
 
 /* All IMAP-specific functions should go in this block. This
@@ -1393,6 +1372,7 @@
 	mail_setflag (vms->mailstream,arg,"\\DELETED");
 }
 
+/* XXX BIG inconsistency between trunk and 1.4 be incredibly careful here */
 static int imap_retrieve_file(const char *dir, const int msgnum, const struct ast_vm_user *vmu)
 {
 	BODY *body;
@@ -1501,7 +1481,11 @@
 	/*assume a NULL folder means INBOX*/
 	if (!folder)
 		return 0;
+#ifdef IMAP_STORAGE
+	if (!strcasecmp(folder, imapfolder))
+#else
 	if (!strcasecmp(folder, "INBOX"))
+#endif
 		return 0;
 	else if (!strcasecmp(folder, "Old"))
 		return 1;
@@ -1525,6 +1509,15 @@
 		return 0;
 }
 
+/*!
+ * \brief Gets the number of messages that exist in a mailbox folder.
+ * \param context
+ * \param mailbox
+ * \param folder
+ * 
+ * This method is used when IMAP backend is used.
+ * \return The number of messages in this mailbox folder (zero or more).
+ */
 static int messagecount(const char *context, const char *mailbox, const char *folder)
 {
 	SEARCHPGM *pgm;
@@ -1534,22 +1527,29 @@
 	struct vm_state *vms_p;
 	int ret = 0;
 	int fold = folder_int(folder);
+	int urgent = 0;
 	
 	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(&vmus, context, mailbox);
 	if (!vmu) {
-		ast_log (LOG_ERROR,"Couldn't find mailbox %s in context %s\n",mailbox,context);
+		ast_log(AST_LOG_ERROR, "Couldn't find mailbox %s in context %s\n", mailbox, context);
 		return -1;
 	} else {
 		/* No IMAP account available */
 		if (vmu->imapuser[0] == '\0') {
-			ast_log (LOG_WARNING,"IMAP user not set for mailbox %s\n",vmu->mailbox);
+			ast_log(AST_LOG_WARNING, "IMAP user not set for mailbox %s\n", vmu->mailbox);
 			return -1;
 		}
+	}
+	
+	/* No IMAP account available */
+	if (vmu->imapuser[0] == '\0') {
+		ast_log(AST_LOG_WARNING, "IMAP user not set for mailbox %s\n", vmu->mailbox);
+		free_user(vmu);
+		return -1;
 	}
 
 	/* check if someone is accessing this box right now... */
@@ -1558,13 +1558,15 @@
 		vms_p = get_vm_state_by_mailbox(mailbox,1);
 	}
 	if (vms_p) {
-		if (option_debug > 2)
-			ast_log (LOG_DEBUG,"Returning before search - user is logged in\n");
-		if (fold == 0) {/*INBOX*/
+		ast_debug(3, "Returning before search - user is logged in\n");
+		if (fold == 0) { /* INBOX */
 			return vms_p->newmessages;
 		}
-		if (fold == 1) {/*Old messages*/
-		 	return vms_p->oldmessages;
+		if (fold == 1) { /* Old messages */
+			return vms_p->oldmessages;
+		}
+		if (fold == 11) {/*Urgent messages*/
+		 	return vms_p->urgentmessages;
 		}
 	}
 
@@ -1574,15 +1576,29 @@
 		vms_p = get_vm_state_by_mailbox(mailbox,0);
 	}
 
+	/* If URGENT, then look at INBOX */
+	if (fold == 11) {
+		fold = NEW_FOLDER;
+		urgent = 1;
+	}
+
 	if (!vms_p) {
-		if (!(vms_p = create_vm_state_from_user(vmu))) {
-			ast_log(LOG_WARNING, "Unable to allocate space for new vm_state!\n");
+		ast_debug(3,"Adding new vmstate for %s\n",vmu->imapuser);
+		if (!(vms_p = ast_calloc(1, sizeof(*vms_p)))) {
 			return -1;
 		}
+		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;
+		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,"IMAP mailstream is NULL\n");
+		ast_log(AST_LOG_ERROR, "Houston we have a problem - IMAP mailstream is NULL\n");
 		return -1;
 	}
 	if (ret == 0) {
@@ -1600,15 +1616,22 @@
 			pgm->unseen = 0;
 			pgm->seen = 1;
 		}
+		/* look for urgent messages */
+		if (urgent) {
+			pgm->flagged = 1;
+			pgm->unflagged = 0;
+		}
 		pgm->undeleted = 1;
 		pgm->deleted = 0;
 
 		vms_p->vmArrayIndex = 0;
 		mail_search_full (vms_p->mailstream, NULL, pgm, NIL);
-		if (fold == 0)
+		if (fold == 0 && urgent == 0)
 			vms_p->newmessages = vms_p->vmArrayIndex;
 		if (fold == 1)
 			vms_p->oldmessages = vms_p->vmArrayIndex;
+		if (fold == 0 && urgent == 1)
+			vms_p->urgentmessages = vms_p->vmArrayIndex;
 		/*Freeing the searchpgm also frees the searchhdr*/
 		mail_free_searchpgm(&pgm);
 		vms_p->updated = 0;
@@ -1619,10 +1642,11 @@
 	return 0;
 }
 
-static int imap_store_file(char *dir, char *mailboxuser, char *mailboxcontext, int msgnum, struct ast_channel *chan, struct ast_vm_user *vmu, char *fmt, int duration, struct vm_state *vms)
+static int imap_store_file(char *dir, char *mailboxuser, char *mailboxcontext, int msgnum, struct ast_channel *chan, struct ast_vm_user *vmu, char *fmt, int duration, struct vm_state *vms, char *introfile, const char *flag)
 {
 	char *myserveremail = serveremail;
 	char fn[PATH_MAX];
+	char intro[PATH_MAX];
 	char mailbox[256];
 	char *stringp;
 	FILE *p=NULL;
@@ -1631,11 +1655,15 @@
 	void *buf;
 	int tempcopy = 0;
 	STRING str;
-
-	/*Greetings are not retrieved from IMAP, so there is no reason to attempt storing them there either*/
-	if (msgnum < 0)
-		return 0;
-
+	int ret; /* for better error checking */
+	char *imapflags = NIL;
+
+	/* Set urgent flag for IMAP message */
+	if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) {
+		ast_debug(3, "Setting message flag \\\\FLAGGED.\n");
+		imapflags="\\FLAGGED";
+	}
+	
 	/* Attach only the first format */
 	fmt = ast_strdupa(fmt);
 	stringp = fmt;
@@ -1644,65 +1672,103 @@
 	if (!ast_strlen_zero(vmu->serveremail))
 		myserveremail = vmu->serveremail;
 
-	make_file(fn, sizeof(fn), dir, msgnum);
-
+	if (msgnum > -1)
+		make_file(fn, sizeof(fn), dir, msgnum);
+	else
+		ast_copy_string (fn, dir, sizeof(fn));
+	
 	if (ast_strlen_zero(vmu->email)) {
-		/*we need the vmu->email to be set when we call make_email_file, but if we keep it set,
-		 * a duplicate e-mail will be created. So at the end of this function, we will revert back to an empty
-		 * string if tempcopy is 1
+		/* We need the vmu->email to be set when we call make_email_file, but
+		 * if we keep it set, a duplicate e-mail will be created. So at the end
+		 * of this function, we will revert back to an empty string if tempcopy
+		 * is 1.
 		 */
 		ast_copy_string(vmu->email, vmu->imapuser, sizeof(vmu->email));
 		tempcopy = 1;
 	}
 
+	if (!ast_strlen_zero(introfile)) {
+		snprintf(intro, sizeof(intro), "%s/msgintro%04d", dir, msgnum);
+	} else {
+		intro[0] = '\0';
+	}
+
 	if (!strcmp(fmt, "wav49"))
 		fmt = "WAV";
-	if (option_debug > 2)
-		ast_log(LOG_DEBUG, "Storing file '%s', format '%s'\n", fn, fmt);
+	ast_debug(3, "Storing file '%s', format '%s'\n", fn, fmt);
+
 	/* Make a temporary file instead of piping directly to sendmail, in case the mail
-	   command hangs */
-	if ((p = vm_mkftemp(tmp)) == NULL) {
-		ast_log(LOG_WARNING, "Unable to store '%s' (can't create temporary file)\n", fn);
+	   command hangs. */
+	if (!(p = vm_mkftemp(tmp))) {
+		ast_log(AST_LOG_WARNING, "Unable to store '%s' (can't create temporary file)\n", fn);
 		if (tempcopy)
 			*(vmu->email) = '\0';
 		return -1;
-	} else {
-		make_email_file(p, myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL), fn, fmt, duration, 1, chan, NULL, 1);
-		/* read mail file to memory */
-		len = ftell(p);
-		rewind(p);
-		if ((buf = ast_malloc(len+1)) == NIL) {
-			ast_log(LOG_ERROR, "Can't allocate %ld bytes to read message\n", len+1);
-			fclose(p);
+	}
+
+	if (msgnum < 0 && imapgreetings) {
+		if ((ret = init_mailstream(vms, GREETINGS_FOLDER))) {
+			ast_log(AST_LOG_WARNING, "Unable to open mailstream.\n");
 			return -1;
 		}
-		fread(buf, len, 1, p);
-		((char *)buf)[len] = '\0';
-		INIT(&str, mail_string, buf, len);
-		init_mailstream(vms, 0);
-		imap_mailbox_name(mailbox, sizeof(mailbox), vms, 0, 1);
-		if (!mail_append(vms->mailstream, mailbox, &str))
+		imap_delete_old_greeting(fn, vms);
+	}
+	
+	make_email_file(p, myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL), fn, intro, fmt, duration, 1, chan, NULL, 1, flag);
+	/* read mail file to memory */		
+	len = ftell(p);
+	rewind(p);
+	if (!(buf = ast_malloc(len + 1))) {
+		ast_log(AST_LOG_ERROR, "Can't allocate %ld bytes to read message\n", len + 1);
+		fclose(p);
+		if (tempcopy)
+			*(vmu->email) = '\0';
+		return -1;
+	}
+	fread(buf, len, 1, p);
+	((char *)buf)[len] = '\0';
+	INIT(&str, mail_string, buf, len);
+	ret = init_mailstream(vms, NEW_FOLDER);
+	if (ret == 0) {
+		imap_mailbox_name(mailbox, sizeof(mailbox), vms, NEW_FOLDER, 1);
+		if(!mail_append_full(vms->mailstream, mailbox, imapflags, NIL, &str))
 			ast_log(LOG_ERROR, "Error while sending the message to %s\n", mailbox);
 		fclose(p);
 		unlink(tmp);
 		ast_free(buf);
-		if (option_debug > 2)
-			ast_log(LOG_DEBUG, "%s stored\n", fn);
-		/* Using messagecount to populate the last place in the msgArray
-		 * is less than optimal, but it's the only way given the current setup
-		 */
-		messagecount(vmu->context, vmu->mailbox, "INBOX");
-	}
+	} else {
+		ast_log(LOG_ERROR, "Could not initialize mailstream for %s\n",mailbox);
+		fclose(p);
+		unlink(tmp);
+		ast_free(buf);
+		return -1;
+	}
+	ast_debug(3, "%s stored\n", fn);
+	
 	if (tempcopy)
 		*(vmu->email) = '\0';
+	
 	return 0;
 
 }
 
-static int inboxcount(const char *mailbox_context, int *newmsgs, int *oldmsgs)
+/*!
+ * \brief Gets the number of messages that exist in the inbox folder.
+ * \param mailbox_context
+ * \param newmsgs The variable that is updated with the count of new messages within this inbox.
+ * \param oldmsgs The variable that is updated with the count of old messages within this inbox.
+ * \param urgentmsgs The variable that is updated with the count of urgent messages within this inbox.
+ * 
+ * This method is used when IMAP backend is used.
+ * Simultaneously determines the count of new,old, and urgent messages. The total messages would then be the sum of these three.
+ *
+ * \return zero on success, -1 on error.
+ */
+
+static int inboxcount2(const char *mailbox_context, int *urgentmsgs, int *newmsgs, int *oldmsgs)
 {
 	char tmp[PATH_MAX] = "";
-	char *mailboxnc; 	
+	char *mailboxnc;
 	char *context;
 	char *mb;
 	char *cur;
@@ -1710,9 +1776,10 @@
 		*newmsgs = 0;
 	if (oldmsgs)
 		*oldmsgs = 0;
-
-	if (option_debug > 2)
-	 	ast_log (LOG_DEBUG,"Mailbox is set to %s\n",mailbox_context);
+	if (urgentmsgs)
+		*urgentmsgs = 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;
@@ -1720,18 +1787,20 @@
 	ast_copy_string(tmp, mailbox_context, sizeof(tmp));
 	context = strchr(tmp, '@');
 	if (strchr(mailbox_context, ',')) {
-		int tmpnew, tmpold;
+		int tmpnew, tmpold, tmpurgent;
 		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))
+				if (inboxcount2(cur, urgentmsgs ? &tmpurgent : NULL, newmsgs ? &tmpnew : NULL, oldmsgs ? &tmpold : NULL))
 					return -1;
 				else {
 					if (newmsgs)
 						*newmsgs += tmpnew; 
 					if (oldmsgs)
 						*oldmsgs += tmpold;
+					if (urgentmsgs)
+						*urgentmsgs += tmpurgent;
 				}
 			}
 		}
@@ -1746,16 +1815,34 @@
 		mailboxnc = (char *)mailbox_context;
 	}
 	if (newmsgs) {
-		if ((*newmsgs = messagecount(context, mailboxnc, "INBOX")) < 0)
+		if ((*newmsgs = messagecount(context, mailboxnc, imapfolder)) < 0)
 			return -1;
 	}
 	if (oldmsgs) {
 		if ((*oldmsgs = messagecount(context, mailboxnc, "Old")) < 0)
 			return -1;
 	}
+	if (urgentmsgs) {
+		if((*urgentmsgs = messagecount(context, mailboxnc, "Urgent")) < 0)
+			return -1;
+	}
 	return 0;
 }
-	
+
+static int inboxcount(const char *mailbox_context, int *newmsgs, int *oldmsgs)
+{
+	return inboxcount2(mailbox_context, NULL, newmsgs, oldmsgs);
+}
+
+/** 
+ * \brief Determines if the given folder has messages.
+ * \param mailbox The @ delimited string for user at context. If no context is found, uses 'default' for the context.
+ * \param folder the folder to look in
+ *
+ * This function is used when the mailbox is stored in an IMAP back end.
+ * This invokes the messagecount(). Here we are interested in the presence of messages (> 0) only, not the actual count.
+ * \return 1 if the folder has one or more messages. zero otherwise.
+ */
 
 static int has_voicemail(const char *mailbox, const char *folder)
 {
@@ -1777,6 +1864,21 @@
 	return messagecount(context, tmp, folder) ? 1 : 0;
 }
 
+/*!
+ * \brief Copies a message from one mailbox to another.
+ * \param chan
+ * \param vmu
+ * \param imbox
+ * \param msgnum
+ * \param duration
+ * \param recip
+ * \param fmt
+ * \param dir
+ *
+ * This works with IMAP storage based mailboxes.
+ *
+ * \return zero on success, -1 on error.
+ */
 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)
 {
 	struct vm_state *sendvms = NULL, *destvms = NULL;
@@ -1804,13 +1906,17 @@
 {
 	char tmp[256], *t = tmp;
 	size_t left = sizeof(tmp);
-
-	if (box == 1) {
-		ast_copy_string(vms->curbox, mbox(0), sizeof(vms->curbox));
-		snprintf(vms->vmbox, sizeof(vms->vmbox), "vm-%s", mbox(1));
+	
+	if (box == OLD_FOLDER) {
+		ast_copy_string(vms->curbox, mbox(NEW_FOLDER), sizeof(vms->curbox));
 	} else {
 		ast_copy_string(vms->curbox, mbox(box), sizeof(vms->curbox));
-		snprintf(vms->vmbox, sizeof(vms->vmbox), "vm-%s", vms->curbox);
+	}
+
+	if (box == NEW_FOLDER) {
+		ast_copy_string(vms->vmbox, "vm-INBOX", sizeof(vms->vmbox));
+	} else {
+		snprintf(vms->vmbox, sizeof(vms->vmbox), "vm-%s", mbox(box));
 	}
 
 	/* Build up server information */
@@ -1826,9 +1932,11 @@
 
 	/* End with username */
 	ast_build_string(&t, &left, "/user=%s}", vms->imapuser);
-
-	if (box == 0 || box == 1)
+	
+	if (box == NEW_FOLDER || box == OLD_FOLDER)
 		snprintf(spec, len, "%s%s", tmp, use_folder? imapfolder: "INBOX");
+	else if (box == GREETINGS_FOLDER)
+		snprintf(spec, len, "%s%s", tmp, greetingfolder);
 	else
 		snprintf(spec, len, "%s%s%c%s", tmp, imapfolder, delimiter, mbox(box));
 }
@@ -1896,51 +2004,59 @@
 {
 	SEARCHPGM *pgm;
 	SEARCHHEADER *hdr;
-	int ret;
+	int ret, urgent = 0;
+
+	/* If Urgent, then look at INBOX */
+	if (box == 11) {
+		box = NEW_FOLDER;
+		urgent = 1;
+	}
 
 	ast_copy_string(vms->imapuser,vmu->imapuser, sizeof(vms->imapuser));
-	if (option_debug > 2)
-		ast_log(LOG_DEBUG,"Before init_mailstream, user is %s\n",vmu->imapuser);
-	ret = init_mailstream(vms, box);
-	if (ret != 0 || !vms->mailstream) {
-		ast_log (LOG_ERROR,"Could not initialize mailstream\n");
+	ast_debug(3,"Before init_mailstream, user is %s\n",vmu->imapuser);
+
+	if ((ret = init_mailstream(vms, box)) || !vms->mailstream) {
+		ast_log(AST_LOG_ERROR, "Could not initialize mailstream\n");
 		return -1;
 	}
 	
-	create_dirpath(vms->curdir, sizeof(vms->curdir), vmu->context, vms->username, vms->curbox);
-
 	/* Check Quota */
 	if  (box == 0)  {
-		if (option_debug > 2)
-			ast_log(LOG_DEBUG, "Mailbox name set to: %s, about to check quotas\n", mbox(box));
+		ast_debug(3, "Mailbox name set to: %s, about to check quotas\n", mbox(box));
 		check_quota(vms,(char *)mbox(box));
 	}
 
 	pgm = mail_newsearchpgm();
 
 	/* Check IMAP folder for Asterisk messages only... */
-	hdr = mail_newsearchheader ("X-Asterisk-VM-Extension", vmu->mailbox);
+	hdr = mail_newsearchheader("X-Asterisk-VM-Extension", vmu->mailbox);
 	pgm->header = hdr;
 	pgm->deleted = 0;
 	pgm->undeleted = 1;
 
-	/* if box = 0, check for new, if box = 1, check for read */
-	if (box == 0) {
+	/* if box = NEW_FOLDER, check for new, if box = OLD_FOLDER, check for read */
+	if (box == NEW_FOLDER && urgent == 1) {
 		pgm->unseen = 1;
 		pgm->seen = 0;
-	} else if (box == 1) {
+		pgm->flagged = 1;
+		pgm->unflagged = 0;
+	} else if (box == NEW_FOLDER && urgent == 0) {
+		pgm->unseen = 1;
+		pgm->seen = 0;
+		pgm->flagged = 0;
+		pgm->unflagged = 1;
+	} else if (box == OLD_FOLDER) {
 		pgm->seen = 1;
 		pgm->unseen = 0;
 	}
 
+	ast_debug(3,"Before mail_search_full, user is %s\n",vmu->imapuser);
+
 	vms->vmArrayIndex = 0;
-	if (option_debug > 2)
-		ast_log(LOG_DEBUG,"Before mail_search_full, user is %s\n",vmu->imapuser);
 	mail_search_full (vms->mailstream, NULL, pgm, NIL);
-
 	vms->lastmsg = vms->vmArrayIndex - 1;
-
 	mail_free_searchpgm(&pgm);
+
 	return 0;
 }
 
@@ -1953,21 +2069,34 @@
 	fclose (output);
 }
 
+static void update_messages_by_imapuser(const char *user, unsigned long number)
+{
+	struct vmstate *vlist = NULL;
+
+	AST_LIST_LOCK(&vmstates);
+	AST_LIST_TRAVERSE(&vmstates, vlist, list) {
+		if (!vlist->vms) {
+			ast_debug(3, "error: vms is NULL for %s\n", user);
+			continue;
+		}
+		if (!vlist->vms->imapuser) {
+			ast_debug(3, "error: imapuser is NULL for %s\n", user);
+			continue;
+		}
+		ast_debug(3, "saving mailbox message number %lu as message %d. Interactive set to %d\n", number, vlist->vms->vmArrayIndex, vlist->vms->interactive);
+		vlist->vms->msgArray[vlist->vms->vmArrayIndex++] = number;
+	}
+	AST_LIST_UNLOCK(&vmstates);
+}
+
 void mm_searched(MAILSTREAM *stream, unsigned long number)
 {
-	struct vm_state *vms;
-	char *mailbox;
-	char *user;
-	mailbox = stream->mailbox;
-	user = get_user_by_mailbox(mailbox);
-	vms = get_vm_state_by_imapuser(user,2);
-	if (vms) {
-		if (option_debug > 2)
-			ast_log (LOG_DEBUG, "saving mailbox message number %lu as message %d. Interactive set to %d\n",number,vms->vmArrayIndex,vms->interactive);
-		vms->msgArray[vms->vmArrayIndex++] = number;
-	} else {
-		ast_log (LOG_ERROR, "No state found.\n");
-	}
+	char *mailbox = stream->mailbox, buf[1024] = "", *user;
+
+	if (!(user = get_user_by_mailbox(mailbox, buf, sizeof(buf))))
+		return;
+
+	update_messages_by_imapuser(user, number);
 }
 
 static struct ast_vm_user *find_user_realtime_imapuser(const char *imapuser)
@@ -1997,8 +2126,7 @@
 void mm_exists(MAILSTREAM * stream, unsigned long number)
 {
 	/* mail_ping will callback here if new mail! */
-	if (option_debug > 3)
-		ast_log (LOG_DEBUG, "Entering EXISTS callback for message %ld\n", number);
+	ast_debug(4, "Entering EXISTS callback for message %ld\n", number);
 	if (number == 0) return;
 	set_update(stream);
 }
@@ -2007,8 +2135,7 @@
 void mm_expunged(MAILSTREAM * stream, unsigned long number)
 {
 	/* mail_ping will callback here if expunged mail! */
-	if (option_debug > 3)
-		ast_log (LOG_DEBUG, "Entering EXPUNGE callback for message %ld\n", number);
+	ast_debug(4, "Entering EXPUNGE callback for message %ld\n", number);
 	if (number == 0) return;
 	set_update(stream);
 }
@@ -2017,8 +2144,7 @@
 void mm_flags(MAILSTREAM * stream, unsigned long number)
 {
 	/* mail_ping will callback here if read mail! */
-	if (option_debug > 3)
-		ast_log (LOG_DEBUG, "Entering FLAGS callback for message %ld\n", number);
+	ast_debug(4, "Entering FLAGS callback for message %ld\n", number);
 	if (number == 0) return;
 	set_update(stream);
 }
@@ -2026,6 +2152,7 @@
 
 void mm_notify(MAILSTREAM * stream, char *string, long errflg)
 {
+	ast_debug(5, "Entering NOTIFY callback, errflag is %ld, string is %s\n", errflg, string);
 	mm_log (string, errflg);
 }
 
@@ -2035,50 +2162,47 @@
 	if (delimiter == '\0') {
 		delimiter = delim;
 	}
-	if (option_debug > 4) {
-		ast_log(LOG_DEBUG, "Delimiter set to %c and mailbox %s\n",delim, mailbox);
-		if (attributes & LATT_NOINFERIORS)
-			ast_log(LOG_DEBUG, "no inferiors\n");
-		if (attributes & LATT_NOSELECT)
-			ast_log(LOG_DEBUG, "no select\n");
-		if (attributes & LATT_MARKED)
-			ast_log(LOG_DEBUG, "marked\n");
-		if (attributes & LATT_UNMARKED)
-			ast_log(LOG_DEBUG, "unmarked\n");
-	}
+
+	ast_debug(5, "Delimiter set to %c and mailbox %s\n",delim, mailbox);
+	if (attributes & LATT_NOINFERIORS)
+		ast_debug(5, "no inferiors\n");
+	if (attributes & LATT_NOSELECT)
+		ast_debug(5, "no select\n");
+	if (attributes & LATT_MARKED)
+		ast_debug(5, "marked\n");
+	if (attributes & LATT_UNMARKED)
+		ast_debug(5, "unmarked\n");
 }
 
 
 void mm_lsub(MAILSTREAM * stream, int delimiter, char *mailbox, long attributes)
 {
-	if (option_debug > 4) {
-		ast_log(LOG_DEBUG, "Delimiter set to %c and mailbox %s\n",delimiter, mailbox);
-		if (attributes & LATT_NOINFERIORS)
-			ast_log(LOG_DEBUG, "no inferiors\n");
-		if (attributes & LATT_NOSELECT)
-			ast_log(LOG_DEBUG, "no select\n");
-		if (attributes & LATT_MARKED)
-			ast_log(LOG_DEBUG, "marked\n");
-		if (attributes & LATT_UNMARKED)
-			ast_log(LOG_DEBUG, "unmarked\n");
-	}
+	ast_debug(5, "Delimiter set to %c and mailbox %s\n",delimiter, mailbox);
+	if (attributes & LATT_NOINFERIORS)
+		ast_debug(5, "no inferiors\n");
+	if (attributes & LATT_NOSELECT)
+		ast_debug(5, "no select\n");
+	if (attributes & LATT_MARKED)
+		ast_debug(5, "marked\n");
+	if (attributes & LATT_UNMARKED)
+		ast_debug(5, "unmarked\n");
 }
 
 
 void mm_status(MAILSTREAM * stream, char *mailbox, MAILSTATUS * status)
 {
-	ast_log (LOG_NOTICE," Mailbox %s", mailbox);
+	ast_log(AST_LOG_NOTICE, " Mailbox %s", mailbox);
 	if (status->flags & SA_MESSAGES)
-		ast_log (LOG_NOTICE,", %lu messages", status->messages);
+		ast_log(AST_LOG_NOTICE, ", %lu messages", status->messages);
 	if (status->flags & SA_RECENT)
-		ast_log (LOG_NOTICE,", %lu recent", status->recent);
+		ast_log(AST_LOG_NOTICE, ", %lu recent", status->recent);
 	if (status->flags & SA_UNSEEN)
-		ast_log (LOG_NOTICE,", %lu unseen", status->unseen);
+		ast_log(AST_LOG_NOTICE, ", %lu unseen", status->unseen);
 	if (status->flags & SA_UIDVALIDITY)
-		ast_log (LOG_NOTICE,", %lu UID validity", status->uidvalidity);
+		ast_log(AST_LOG_NOTICE, ", %lu UID validity", status->uidvalidity);
 	if (status->flags & SA_UIDNEXT)
-		ast_log (LOG_NOTICE,", %lu next UID", status->uidnext);
-	ast_log (LOG_NOTICE,"\n");
+		ast_log(AST_LOG_NOTICE, ", %lu next UID", status->uidnext);
+	ast_log(AST_LOG_NOTICE, "\n");
 }
 
 
@@ -2086,15 +2210,14 @@
 {
 	switch ((short) errflg) {
 		case NIL:
-			if (option_debug)
-				ast_log(LOG_DEBUG,"IMAP Info: %s\n", string);
+			ast_debug(1,"IMAP Info: %s\n", string);
 			break;
 		case PARSE:
 		case WARN:
-			ast_log (LOG_WARNING,"IMAP Warning: %s\n", string);
+			ast_log(AST_LOG_WARNING, "IMAP Warning: %s\n", string);
 			break;
 		case ERROR:
-			ast_log (LOG_ERROR,"IMAP Error: %s\n", string);
+			ast_log(AST_LOG_ERROR, "IMAP Error: %s\n", string);
 			break;
 	}
 }
@@ -2102,7 +2225,7 @@
 
 void mm_dlog(char *string)
 {
-	ast_log (LOG_NOTICE, "%s\n", string);
+	ast_log(AST_LOG_NOTICE, "%s\n", string);
 }
 
 
@@ -2110,8 +2233,7 @@
 {
 	struct ast_vm_user *vmu;
 
-	if (option_debug > 3)
-		ast_log(LOG_DEBUG, "Entering callback mm_login\n");
+	ast_debug(4, "Entering callback mm_login\n");
 
 	ast_copy_string(user, mb->user, MAILTMPLEN);
 
@@ -2154,17 +2276,16 @@
 
 void mm_fatal(char *string)
 {
-	ast_log(LOG_ERROR,"IMAP access FATAL error: %s\n", string);
+	ast_log(AST_LOG_ERROR, "IMAP access FATAL error: %s\n", string);
 }
 
 /* C-client callback to handle quota */
 static void mm_parsequota(MAILSTREAM *stream, unsigned char *msg, QUOTALIST *pquota)
 {
 	struct vm_state *vms;
-	char *mailbox;
-	char *user;
-	unsigned long usage = 0;
-	unsigned long limit = 0;
+	char *mailbox = stream->mailbox, *user;
+	char buf[1024] = "";
+	unsigned long usage = 0, limit = 0;
 	
 	while (pquota) {
 		usage = pquota->usage;
@@ -2172,88 +2293,78 @@
 		pquota = pquota->next;
 	}
 	
-	mailbox = stream->mailbox;
-	user = get_user_by_mailbox(mailbox);
-	vms = get_vm_state_by_imapuser(user,2);
-	if (vms) {
-		if (option_debug > 2)
-			ast_log (LOG_DEBUG, "User %s usage is %lu, limit is %lu\n",user,usage,limit);
-		vms->quota_usage = usage;
-		vms->quota_limit = limit;
-	} else {
-		ast_log (LOG_ERROR, "No state found.\n");
-	}
-}
-
-static char *get_header_by_tag(char *header, char *tag)
-{
-	char *start;
+	if (!(user = get_user_by_mailbox(mailbox, buf, sizeof(buf))) || !(vms = get_vm_state_by_imapuser(user, 2))) {
+		ast_log(AST_LOG_ERROR, "No state found.\n");
+		return;
+	}
+
+	ast_debug(3, "User %s usage is %lu, limit is %lu\n", user, usage, limit);
+
+	vms->quota_usage = usage;
+	vms->quota_limit = limit;
+}
+
+static char *get_header_by_tag(char *header, char *tag, char *buf, size_t len)
+{
+	char *start, *eol_pnt;
 	int taglen;
-	char *eol_pnt;
-
-	if (!header || !tag)
+
+	if (ast_strlen_zero(header) || ast_strlen_zero(tag))
 		return NULL;
 
 	taglen = strlen(tag) + 1;
 	if (taglen < 1)
 		return NULL;
 
-	start = strstr(header, tag);
-	if (!start)
+	if (!(start = strstr(header, tag)))
 		return NULL;
 
-	ast_mutex_lock(&imaptemp_lock);
-	ast_copy_string(imaptemp, start+taglen, sizeof(imaptemp));
-	ast_mutex_unlock(&imaptemp_lock);
-	if ((eol_pnt = strchr(imaptemp,'\r')) || (eol_pnt = strchr(imaptemp,'\n')))
+	/* Since we can be called multiple times we should clear our buffer */
+	memset(buf, 0, len);
+
+	ast_copy_string(buf, start+taglen, len);
+	if ((eol_pnt = strchr(buf,'\r')) || (eol_pnt = strchr(buf,'\n')))
 		*eol_pnt = '\0';
-	return imaptemp;
-}
-
-static char *get_user_by_mailbox(char *mailbox)
-{
-	char *start, *quote;
-	char *eol_pnt;
-
-	if (!mailbox)
+	return buf;
+}
+
+static char *get_user_by_mailbox(char *mailbox, char *buf, size_t len)
+{
+	char *start, *quote, *eol_pnt;
+
+	if (ast_strlen_zero(mailbox))
 		return NULL;
 
-	start = strstr(mailbox,"/user=");
-	if (!start)
+	if (!(start = strstr(mailbox, "/user=")))
 		return NULL;
 
-	ast_mutex_lock(&imaptemp_lock);
-	ast_copy_string(imaptemp, start+6, sizeof(imaptemp));
-	ast_mutex_unlock(&imaptemp_lock);
-
-	quote = strchr(imaptemp,'\"');
-	if (!quote) {  /* if username is not in quotes */
-		eol_pnt = strchr(imaptemp,'/');
-		if (!eol_pnt) {
-			eol_pnt = strchr(imaptemp,'}');
-		}
+	ast_copy_string(buf, start+6, len);
+
+	if (!(quote = strchr(buf, '\"'))) {
+		if (!(eol_pnt = strchr(buf, '/')))
+			eol_pnt = strchr(buf,'}');
 		*eol_pnt = '\0';
-		return imaptemp;
+		return buf;
 	} else {
-		eol_pnt = strchr(imaptemp+1,'\"');
+		eol_pnt = strchr(buf+1,'\"');
 		*eol_pnt = '\0';
-		return imaptemp+1;
-	}
-}
-
-static struct vm_state *create_vm_state_from_user(struct ast_vm_user *vmu)
+		return buf+1;
+	}
+}
+
+static struct vm_state *create_vm_state_from_user(struct ast_vm_user *vmu, char *mailbox)
 {
 	struct vm_state *vms_p;
 
 	if (option_debug > 4)
-		ast_log(LOG_DEBUG,"Adding new vmstate for %s\n",vmu->imapuser);
+		ast_log(AST_LOG_DEBUG,"Adding new vmstate for %s\n",vmu->imapuser);
 	if (!(vms_p = ast_calloc(1, sizeof(*vms_p))))
 		return NULL;
 	ast_copy_string(vms_p->imapuser,vmu->imapuser, sizeof(vms_p->imapuser));
-	ast_copy_string(vms_p->username, vmu->mailbox, sizeof(vms_p->username)); /* save for access from interactive entry point */
+	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 */
 	if (option_debug > 4)
-		ast_log(LOG_DEBUG,"Copied %s to %s\n",vmu->imapuser,vms_p->imapuser);
+		ast_log(AST_LOG_DEBUG,"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(0), sizeof(vms_p->curbox));
@@ -2266,68 +2377,57 @@
 {
 	struct vmstate *vlist = NULL;
 
-	ast_mutex_lock(&vmstate_lock);
-	vlist = vmstates;
-	while (vlist) {
-		if (vlist->vms) {
-			if (vlist->vms->imapuser) {
-				if (!strcmp(vlist->vms->imapuser,user)) {
-					if (interactive == 2) {
-						ast_mutex_unlock(&vmstate_lock);
-						return vlist->vms;
-					} else if (vlist->vms->interactive == interactive) {
-						ast_mutex_unlock(&vmstate_lock);
-						return vlist->vms;
-					}
-				}
-			} else {
-				if (option_debug > 2)
-					ast_log(LOG_DEBUG, "	error: imapuser is NULL for %s\n",user);
-			}
-		} else {
-			if (option_debug > 2)
-				ast_log(LOG_DEBUG, "	error: vms is NULL for %s\n",user);
-		}
-		vlist = vlist->next;
-	}
-	ast_mutex_unlock(&vmstate_lock);
-	if (option_debug > 2)
-		ast_log(LOG_DEBUG, "%s not found in vmstates\n",user);
+	AST_LIST_LOCK(&vmstates);
+	AST_LIST_TRAVERSE(&vmstates, vlist, list) {
+		if (!vlist->vms) {
+			ast_debug(3, "error: vms is NULL for %s\n", user);
+			continue;
+		}
+		if (!vlist->vms->imapuser) {
+			ast_debug(3, "error: imapuser is NULL for %s\n", user);
+			continue;
+		}
+
+		if (!strcmp(vlist->vms->imapuser, user) && (interactive == 2 || vlist->vms->interactive == interactive)) {
+			AST_LIST_UNLOCK(&vmstates);
+			return vlist->vms;
+		}
+	}
+	AST_LIST_UNLOCK(&vmstates);
+
+	ast_debug(3, "%s not found in vmstates\n", user);
+
 	return NULL;
 }
 
 static struct vm_state *get_vm_state_by_mailbox(const char *mailbox, int interactive)
-{ 
+{
+
 	struct vmstate *vlist = NULL;
 
-	ast_mutex_lock(&vmstate_lock);
-	vlist = vmstates;
-	if (option_debug > 2) 
-		ast_log(LOG_DEBUG, "Mailbox set to %s\n",mailbox);
-	while (vlist) {
-		if (vlist->vms) {
-			if (vlist->vms->username) {
-				if (option_debug > 2)
-					ast_log(LOG_DEBUG, "	comparing mailbox %s (i=%d) to vmstate mailbox %s (i=%d)\n",mailbox,interactive,vlist->vms->username,vlist->vms->interactive);
-				if (!strcmp(vlist->vms->username,mailbox) && vlist->vms->interactive == interactive) {
-					if (option_debug > 2)
-						ast_log(LOG_DEBUG, "	Found it!\n");
-					ast_mutex_unlock(&vmstate_lock);
-					return vlist->vms;
-				}
-			} else {
-				if (option_debug > 2)
-					ast_log(LOG_DEBUG, "	error: username is NULL for %s\n",mailbox);
-			}
-		} else {
-			if (option_debug > 2)
-				ast_log(LOG_DEBUG, "	error: vms is NULL for %s\n",mailbox);
-		}
-		vlist = vlist->next;
-	}
-	ast_mutex_unlock(&vmstate_lock);
-	if (option_debug > 2)
-		ast_log(LOG_DEBUG, "%s not found in vmstates\n",mailbox);
+	AST_LIST_LOCK(&vmstates);
+	AST_LIST_TRAVERSE(&vmstates, vlist, list) {
+		if (!vlist->vms) {
+			ast_debug(3, "error: vms is NULL for %s\n", mailbox);
+			continue;
+		}
+		if (!vlist->vms->username) {
+			ast_debug(3, "error: username is NULL for %s\n", mailbox);
+			continue;
+		}
+
+		ast_debug(3, "comparing mailbox %s (i=%d) to vmstate mailbox %s (i=%d)\n", mailbox, interactive, vlist->vms->username, vlist->vms->interactive);
+		
+		if (!strcmp(vlist->vms->username,mailbox) && vlist->vms->interactive == interactive) {
+			ast_debug(3, "Found it!\n");
+			AST_LIST_UNLOCK(&vmstates);
+			return vlist->vms;
+		}
+	}
+	AST_LIST_UNLOCK(&vmstates);
+
+	ast_debug(3, "%s not found in vmstates\n", mailbox);
+
 	return NULL;
 }
 
@@ -2341,13 +2441,16 @@
 	   We can compare the username to find the duplicate */
 	if (vms->interactive == 1) {
 		altvms = get_vm_state_by_mailbox(vms->username,0);
-		if (altvms) {
-			if (option_debug > 2)
-				ast_log(LOG_DEBUG, "Duplicate mailbox %s, copying message info...\n",vms->username);
+		if (altvms) {	
+			ast_debug(3, "Duplicate mailbox %s, copying message info...\n",vms->username);
 			vms->newmessages = altvms->newmessages;
 			vms->oldmessages = altvms->oldmessages;
+			ast_debug(3, "check_msgArray before memcpy\n");
+			check_msgArray(vms);
 			/* memcpy(vms->msgArray, altvms->msgArray, sizeof(long)*256); */
 			copy_msgArray(vms, altvms);
+			ast_debug(3, "check_msgArray after memcpy\n");
+			check_msgArray(vms);
 			vms->vmArrayIndex = altvms->vmArrayIndex;
 			vms->lastmsg = altvms->lastmsg;
 			vms->curmsg = altvms->curmsg;
@@ -2359,141 +2462,166 @@
 		}
 	}
 
-	v = (struct vmstate *)malloc(sizeof(struct vmstate));
-	if (!v) {
-		ast_log(LOG_ERROR, "Out of memory\n");
-	}
-	if (option_debug > 2)
-		ast_log(LOG_DEBUG, "Inserting vm_state for user:%s, mailbox %s\n",vms->imapuser,vms->username);
-	ast_mutex_lock(&vmstate_lock);
+	if (!(v = ast_calloc(1, sizeof(*v))))
+		return;
+	
 	v->vms = vms;
-	v->next = vmstates;
-	vmstates = v;
-	ast_mutex_unlock(&vmstate_lock);
+
+	ast_debug(3, "Inserting vm_state for user:%s, mailbox %s\n",vms->imapuser,vms->username);
+
+	AST_LIST_LOCK(&vmstates);
+	AST_LIST_INSERT_TAIL(&vmstates, v, list);
+	AST_LIST_UNLOCK(&vmstates);
 }
 
 static void vmstate_delete(struct vm_state *vms) 
 {
-	struct vmstate *vc, *vf = NULL, *vl = NULL;
-	struct vm_state *altvms;
-
-	/* If interactive, we should copy pertainent info
+	struct vmstate *vc = NULL;
+	struct vm_state *altvms = NULL;
+
+	/* If interactive, we should copy pertinent info
 	   back to the persistent state (to make update immediate) */
-	if (vms->interactive == 1) {
-		altvms = vms->persist_vms;
-		if (altvms) {
-			if (option_debug > 2)
-				ast_log(LOG_DEBUG, "Duplicate mailbox %s, copying message info...\n",vms->username);
-			altvms->newmessages = vms->newmessages;
-			altvms->oldmessages = vms->oldmessages;
-			altvms->updated = 1;
-		}
-	}
-
-	ast_mutex_lock(&vmstate_lock);
-	vc = vmstates;
-	if (option_debug > 2)
-		ast_log(LOG_DEBUG, "Removing vm_state for user:%s, mailbox %s\n",vms->imapuser,vms->username);
-	while (vc) {
+	if (vms->interactive == 1 && (altvms = vms->persist_vms)) {
+		ast_debug(3, "Duplicate mailbox %s, copying message info...\n", vms->username);
+		altvms->newmessages = vms->newmessages;
+		altvms->oldmessages = vms->oldmessages;
+		altvms->updated = 1;
+	}
+	
+	ast_debug(3, "Removing vm_state for user:%s, mailbox %s\n", vms->imapuser, vms->username);
+	
+	AST_LIST_LOCK(&vmstates);
+	AST_LIST_TRAVERSE_SAFE_BEGIN(&vmstates, vc, list) {
 		if (vc->vms == vms) {
-			vf = vc;
-			if (vl)
-				vl->next = vc->next;
-			else
-				vmstates = vc->next;
+			AST_LIST_REMOVE_CURRENT(list);
 			break;
 		}
-		vl = vc;
-		vc = vc->next;
-	}
-	if (!vf) {
-		ast_log(LOG_ERROR, "No vmstate found for user:%s, mailbox %s\n",vms->imapuser,vms->username);
-	} else {
-		ast_mutex_destroy(&vf->vms->lock);
-		free(vf);
-	}
-	ast_mutex_unlock(&vmstate_lock);
+	}
+	AST_LIST_TRAVERSE_SAFE_END
+	AST_LIST_UNLOCK(&vmstates);
+	
+	if (vc) {
+		ast_mutex_destroy(&vc->vms->lock);
+		ast_free(vc);
+	}
+	else
+		ast_log(AST_LOG_ERROR, "No vmstate found for user:%s, mailbox %s\n", vms->imapuser, vms->username);
 }
 
 static void set_update(MAILSTREAM * stream) 
 {
 	struct vm_state *vms;
-	char *mailbox;
-	char *user;
-
-	mailbox = stream->mailbox;
-	user = get_user_by_mailbox(mailbox);
-	vms = get_vm_state_by_imapuser(user, 0);
-	if (vms) {
-		if (option_debug > 2)
-			ast_log (LOG_DEBUG, "User %s mailbox set for update.\n",user);
-		vms->updated = 1; /* set updated flag since mailbox changed */
-	} else {
-		if (option_debug > 2)
-			ast_log (LOG_WARNING, "User %s mailbox not found for update.\n",user);
-	}
+	char *mailbox = stream->mailbox, *user;
+	char buf[1024] = "";
+
+	if (!(user = get_user_by_mailbox(mailbox, buf, sizeof(buf))) || !(vms = get_vm_state_by_imapuser(user, 0))) {
+		if (user && option_debug > 2)
+			ast_log(AST_LOG_WARNING, "User %s mailbox not found for update.\n", user);
+		return;
+	}
+
+	ast_debug(3, "User %s mailbox set for update.\n", user);
+
+	vms->updated = 1; /* Set updated flag since mailbox changed */
 }
 
 static void init_vm_state(struct vm_state *vms) 
 {
 	int x;
 	vms->vmArrayIndex = 0;
-	for (x = 0; x < 256; x++) {
+	for (x = 0; x < VMSTATE_MAX_MSG_ARRAY; x++) {
 		vms->msgArray[x] = 0;
 	}
 	ast_mutex_init(&vms->lock);
 }
 
+static void check_msgArray(struct vm_state *vms) 
+{
+	int x;
+	for (x = 0; x < VMSTATE_MAX_MSG_ARRAY; x++) {
+		if (vms->msgArray[x] != 0) {
+			ast_debug(1, "Item %d set to %ld\n", x, vms->msgArray[x]);
+		}
+	}
+}
+
+/*!
+ * \brief Copies the msgArray property from one vm_state to another.
+ * \param dst
+ * \param src
+ *
+ * Goes over each element in the msgArray array property and copies the value from the source to the destination vm_state.
+ */
 static void copy_msgArray(struct vm_state *dst, struct vm_state *src)
 {
 	int x;
-	for (x = 0; x<256; x++) {
+	for (x = 0; x < VMSTATE_MAX_MSG_ARRAY; x++) {
 		dst->msgArray[x] = src->msgArray[x];
 	}
 }
 
-static int save_body(BODY *body, struct vm_state *vms, char *section, char *format) 
+static int save_body(BODY *body, struct vm_state *vms, char *section, char *format, char *altfile) 
 {
 	char *body_content;
 	char *body_decoded;
+	char *fn = S_OR(altfile, vms->fn);
 	unsigned long len;

[... 1432 lines stripped ...]



More information about the asterisk-commits mailing list