[asterisk-commits] branch jrothenberger/asterisk-imap r30243 - in /team/jrothenberger/asterisk-i...

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Thu May 25 08:52:10 MST 2006


Author: jrothenberger
Date: Thu May 25 10:52:09 2006
New Revision: 30243

URL: http://svn.digium.com/view/asterisk?rev=30243&view=rev
Log:

Initial commit of asterisk-imap


Added:
    team/jrothenberger/asterisk-imap/doc/README.imapstorage   (with props)
Modified:
    team/jrothenberger/asterisk-imap/apps/Makefile
    team/jrothenberger/asterisk-imap/apps/app_voicemail.c

Modified: team/jrothenberger/asterisk-imap/apps/Makefile
URL: http://svn.digium.com/view/asterisk/team/jrothenberger/asterisk-imap/apps/Makefile?rev=30243&r1=30242&r2=30243&view=diff
==============================================================================
--- team/jrothenberger/asterisk-imap/apps/Makefile (original)
+++ team/jrothenberger/asterisk-imap/apps/Makefile Thu May 25 10:52:09 2006
@@ -10,6 +10,10 @@
 # This program is free software, distributed under the terms of
 # the GNU General Public License
 #
+
+# Uncomment the lines below to use IMAP storage
+USE_IMAP_VM_INTERFACE=1
+UWCLIENT_HOME=/usr/src/imap/c-client
 
 APPS=app_dial.so app_playback.so app_voicemail.so app_directory.so app_mp3.so\
      app_system.so app_echo.so app_record.so app_image.so app_url.so app_disa.so \
@@ -83,6 +87,9 @@
 #CFLAGS+=-DEXTENDED_ODBC_STORAGE
 # See doc/README.odbcstorage for more information
 
+# If you have UW IMAP c-client you can use IMAP storage
+CFLAGS+=-DUSE_IMAP_STORAGE
+
 all: $(APPS)
 
 clean:
@@ -101,6 +108,20 @@
 
 app_curl.so: app_curl.o
 	$(CC) $(SOLINK) -o $@ ${CYGSOLINK} $< ${CYGSOLIB} $(CURLLIBS)
+
+app_voicemail.so : app_voicemail.o
+ifeq ($(USE_IMAP_VM_INTERFACE),1)
+	$(CC) $(SOLINK) -o $@ $< /usr/lib/libpam.a $(UWCLIENT_HOME)/c-client.a -lpam -ldl -L/usr/lib -lssl -lcrypto -lkrb5 -lgssapi_krb5
+else
+	$(CC) $(SOLINK) -o $@ ${CYGSOLINK} $< ${CYGSOLIB}
+endif
+
+app_voicemail.o: app_voicemail.c
+ifeq ($(USE_IMAP_VM_INTERFACE),1)
+	$(CC) $(CFLAGS) -fno-strict-aliasing -I$(UWCLIENT_HOME) -c -o $@ app_voicemail.c
+else
+	$(CC) $(CFLAGS) -c -o $@ app_voicemail.c
+endif
 
 app_sql_postgres.o: app_sql_postgres.c
 	$(CC) -pipe -I$(CROSS_COMPILE_TARGET)/usr/local/pgsql/include -I$(CROSS_COMPILE_TARGET)/usr/include/postgresql $(CFLAGS) -c -o app_sql_postgres.o app_sql_postgres.c

Modified: team/jrothenberger/asterisk-imap/apps/app_voicemail.c
URL: http://svn.digium.com/view/asterisk/team/jrothenberger/asterisk-imap/apps/app_voicemail.c?rev=30243&r1=30242&r2=30243&view=diff
==============================================================================
--- team/jrothenberger/asterisk-imap/apps/app_voicemail.c (original)
+++ team/jrothenberger/asterisk-imap/apps/app_voicemail.c Thu May 25 10:52:09 2006
@@ -35,6 +35,9 @@
  * 07-11-2005 : An issue with voicemail synchronization has been fixed by GDS Partners (www.gdspartners.com)
  *				 Stojan Sljivic <stojan.sljivic at gdspartners.com>
  *
+ * 03-01-2006 : Support for IMAP storage integration added by OneBizTone LLC
+ *              Work funded by University of Pennsylvania
+ *              James Rothenberger <jar at onebiztone.com>
  */
 
 #include <stdlib.h>
@@ -50,13 +53,72 @@
 #include <time.h>
 #include <dirent.h>
 
+#ifdef USE_ODBC_STORAGE
+#include "asterisk/res_odbc.h"
+#endif
+
+
+#ifdef USE_IMAP_STORAGE
+#include <ctype.h>
+#include <signal.h>
+#include <pwd.h>
+
+#include "c-client.h"
+#include "imap4r1.h"
+
+char *curhst = NIL;		/* currently connected host */
+char *curusr = NIL;		/* current login user */
+
+char temp[1024];
+
+static char imapserver[48]; 
+static char imapport[8]; 
+static char imapflags[128]; 
+static char authuser[32]; 
+static char authpassword[42]; 
+static int expungeonhangup = 1; 
+static char delimiter = '\0';
+
+struct vm_state;
+
+int init_mailstream (struct vm_state *vms);
+void write_file (char *filename, char *buffer, unsigned long len);
+void status (MAILSTREAM *stream);
+void display_body (BODY *body, char *pfx, long i);
+static char *get_header_by_tag(char *header, char *tag);
+static void imap_delete(int msgnum, struct vm_state *vms);
+static char *get_user_by_mailbox(char *mailbox);
+static struct vm_state *get_vm_state_by_imapuser(char *user, int interactive);
+static struct vm_state *get_vm_state_by_mailbox(const char *mailbox, int interactive);
+static void vmstate_insert(struct vm_state *vms);
+static void vmstate_delete(struct vm_state *vms);
+static void set_update(MAILSTREAM * stream);
+static void init_vm_state(struct vm_state *vms);
+static void check_msgArray(struct vm_state *vms);
+static void copy_msgArray(struct vm_state *dst, struct vm_state *src);
+static int save_body(BODY *body, struct vm_state *vms, char *section, char *format);
+static int make_gsm_file(char *dest, char *imapuser, char *dir, int num);
+static void get_mailbox_delimiter(MAILSTREAM *stream);
+void mm_parsequota (MAILSTREAM *stream, unsigned char *msg, QUOTALIST *pquota);
+/* should define TMP in config file... */
+#define TMP "/tmp"
+
+struct vmstate {
+	struct vm_state *vms;
+	struct vmstate *next;
+};
+
+#include "asterisk/lock.h"
+AST_MUTEX_DEFINE_STATIC(vmstate_lock);
+static struct vmstate *vmstates = NULL;
+
+#endif
+
 #include "asterisk.h"
 
 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 
-#include "asterisk/lock.h"
 #include "asterisk/file.h"
-#include "asterisk/logger.h"
 #include "asterisk/channel.h"
 #include "asterisk/pbx.h"
 #include "asterisk/options.h"
@@ -70,9 +132,6 @@
 #include "asterisk/localtime.h"
 #include "asterisk/cli.h"
 #include "asterisk/utils.h"
-#ifdef USE_ODBC_STORAGE
-#include "asterisk/res_odbc.h"
-#endif
 
 #define COMMAND_TIMEOUT 5000
 #define	VOICEMAIL_DIR_MODE	0700
@@ -113,6 +172,9 @@
 #define VM_DELETE		(1 << 12)
 #define VM_ALLOCED		(1 << 13)
 #define VM_SEARCH		(1 << 14)
+
+/* moved down here due to conflict with IMAP includes */
+#include "asterisk/logger.h"
 
 #define ERROR_LOCK_PATH		-100
 
@@ -229,6 +291,9 @@
 	unsigned int flags;		/*!< VM_ flags */	
 	int saydurationm;
 	int maxmsg;			/*!< Maximum number of msgs per folder for this mailbox */
+#ifdef USE_IMAP_STORAGE
+	char imapuser[80];		/* IMAP server login */
+#endif
 	struct ast_vm_user *next;
 };
 
@@ -254,6 +319,17 @@
 	int oldmessages;
 	int starting;
 	int repeats;
+#ifdef USE_IMAP_STORAGE
+	int updated; /* decremented on each mail check until 1 -allows delay */
+	long msgArray[256];
+	MAILSTREAM *mailstream;
+	int vmArrayIndex;
+	char imapuser[80]; /* IMAP server login */
+	int interactive;
+	unsigned int quota_limit;
+	unsigned int quota_usage;
+	struct vm_state *persist_vms;
+#endif
 };
 static int advanced_options(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int msg,
 			    int option, signed char record_gain);
@@ -277,6 +353,16 @@
 #define COPY(a,b,c,d,e,f,g,h) (copy_file(a,b,c,d,e,f))
 #define DELETE(a,b,c) (delete_file(a,b))
 #else
+#ifdef USE_IMAP_STORAGE
+#define RETRIEVE(a,b)
+#define DISPOSE(a,b)
+#define STORE(a,b,c,d)
+#define EXISTS(a,b,c,d) (ast_fileexists(c,NULL,d) > 0)
+#define RENAME(a,b,c,d,e,f,g,h) (rename_file(g,h));
+#define COPY(a,b,c,d,e,f,g,h) (copy_file(g,h));
+#define IMAP_DELETE(a,b,c,d) (imap_delete(b,d))
+#define DELETE(a,b,c) (vm_delete(c))
+#else
 #define RETRIEVE(a,b)
 #define DISPOSE(a,b)
 #define STORE(a,b,c,d)
@@ -285,6 +371,8 @@
 #define COPY(a,b,c,d,e,f,g,h) (copy_file(g,h));
 #define DELETE(a,b,c) (vm_delete(c))
 #endif
+#endif
+
 
 static char VM_SPOOL_DIR[AST_CONFIG_MAX_PATH];
 
@@ -317,7 +405,7 @@
 "           message. The units are whole-number decibels (dB).\n"
 "    s    - Skip the playback of instructions for leaving a message to the\n"
 "           calling party.\n"
-"    u    - Play the 'unavailable greeting.\n"
+"    u    - Play the 'unavailble greeting.\n"
 "    j    - Jump to priority n+101 if the mailbox is not found or some other\n"
 "           error occurs.\n";
 
@@ -421,6 +509,7 @@
 
 LOCAL_USER_DECL;
 
+
 static void populate_defaults(struct ast_vm_user *vmu)
 {
 	ast_copy_flags(vmu, (&globalflags), AST_FLAGS_ALL);	
@@ -447,6 +536,10 @@
 		ast_copy_string(vmu->language, value, sizeof(vmu->language));
 	} else if (!strcasecmp(var, "tz")) {
 		ast_copy_string(vmu->zonetag, value, sizeof(vmu->zonetag));
+#ifdef USE_IMAP_STORAGE
+	} else if (!strcasecmp(var, "imapuser")) {
+		strncpy(vmu->imapuser, value, sizeof(vmu->imapuser) - 1);
+#endif
 	} else if (!strcasecmp(var, "delete") || !strcasecmp(var, "deletevoicemail")) {
 		ast_set2_flag(vmu, ast_true(value), VM_DELETE);	
 	} else if (!strcasecmp(var, "saycid")){
@@ -775,7 +868,42 @@
 	return snprintf(dest, len, "%s%s/%s/%s", VM_SPOOL_DIR, context, ext, mailbox);
 }
 
+#ifdef USE_IMAP_STORAGE
+static int make_gsm_file(char *dest, char *imapuser, char *dir, int num)
+{
+	char gsmdir[256];
+
+	sprintf(gsmdir,"%s/%s",dir,imapuser);
+	if (mkdir(gsmdir, 01777) && (errno != EEXIST)) {
+		ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", gsmdir, strerror(errno));
+		return sprintf(dest, "%s/msg%04d", dir, num);
+	}
+	/* return sprintf(dest, "%s/s/msg%04d", dir, imapuser, num); */
+	return sprintf(dest, "%s/%s/msg%04d", dir, imapuser, num);
+}
+
+static void imap_delete(int msgnum, struct vm_state *vms)
+{
+	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(LOG_WARNING, "msgnum %d, mailbox message %lu is zero.\n",msgnum,messageNum);
+		return;
+	}
+	ast_log(LOG_DEBUG, "deleting msgnum %d, which is mailbox message %lu\n",msgnum,messageNum);
+	/* delete message */
+        sprintf (arg,"%lu",messageNum);
+        mail_setflag (vms->mailstream,arg,"\\DELETED");
+}
+
+#endif
 static int make_file(char *dest, int len, char *dir, int num)
+
 {
 	return snprintf(dest, len, "%s/msg%04d", dir, num);
 }
@@ -1466,6 +1594,7 @@
 /*
  * A negative return value indicates an error.
  */
+#ifndef USE_IMAP_STORAGE
 static int last_message_index(struct ast_vm_user *vmu, char *dir)
 {
 	int x;
@@ -1483,6 +1612,7 @@
 
 	return x - 1;
 }
+#endif
 
 static int vm_delete(char *file)
 {
@@ -1640,7 +1770,7 @@
 	pbx_builtin_setvar_helper(ast, "VM_DATE", date);
 }
 
-static int sendmail(char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, char *cidnum, char *cidname, char *attach, char *format, int duration, int attach_user_voicemail)
+static int sendmail(char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, char *cidnum, char *cidname, char *attach, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, char *category)
 {
 	FILE *p=NULL;
 	int pfd;
@@ -1745,6 +1875,22 @@
 		else
 			fprintf(p, "Subject: [PBX]: New message %d in mailbox %s\n", msgnum + 1, mailbox);
 		fprintf(p, "Message-ID: <Asterisk-%d-%d-%s-%d@%s>\n", msgnum, (unsigned int)rand(), mailbox, getpid(), host);
+#ifdef USE_IMAP_STORAGE
+		/* additional information needed for IMAP searching */
+		fprintf(p, "X-Asterisk-VM-Message-Num: %d\n", msgnum + 1);
+		/* fprintf(p, "X-Asterisk-VM-Orig-Mailbox: %s\n", ext); */
+		fprintf(p, "X-Asterisk-VM-Server-Name: %s\n", fromstring);
+		fprintf(p, "X-Asterisk-VM-Context: %s\n", context);
+		fprintf(p, "X-Asterisk-VM-Extension: %s\n", chan->exten);
+		fprintf(p, "X-Asterisk-VM-Priority: %d\n", chan->priority);
+		fprintf(p, "X-Asterisk-VM-Caller-channel: %s\n", chan->name);
+		fprintf(p, "X-Asterisk-VM-Caller-ID-Num: %s\n", cidnum);
+		fprintf(p, "X-Asterisk-VM-Caller-ID-Name: %s\n", cidname);
+		fprintf(p, "X-Asterisk-VM-Duration: %d\n", duration);
+		if (category != NULL) fprintf(p, "X-Asterisk-VM-Category: %s\n", category);
+		fprintf(p, "X-Asterisk-VM-Orig-date: %s\n", date);
+		fprintf(p, "X-Asterisk-VM-Orig-time: %ld\n", (long)time(NULL));
+#endif
 		fprintf(p, "MIME-Version: 1.0\n");
 		if (attach_user_voicemail) {
 			/* Something unique. */
@@ -1789,6 +1935,20 @@
 
 			snprintf(fname, sizeof(fname), "%s.%s", attach, format);
 			base_encode(fname, p);
+#ifdef USE_IMAP_STORAGE
+			/* only attach if necessary */
+			ast_log(LOG_DEBUG, "Before second attachment with format set to:%s\n",format);
+			if (strcmp(format, "gsm")) {
+			   fprintf(p, "--%s\n", bound);
+			   fprintf(p, "Content-Type: audio/x-gsm; name=\"msg%04d.%s\"\n", msgnum, format);
+			   fprintf(p, "Content-Transfer-Encoding: base64\n");
+			   fprintf(p, "Content-Description: Voicemail sound attachment.\n");
+			   fprintf(p, "Content-Disposition: attachment; filename=\"msg%04d.gsm\"\n\n", msgnum);
+
+			   snprintf(fname, sizeof(fname), "%s.gsm", attach);
+			   base_encode(fname, p);
+			}
+#endif
 			fprintf(p, "\n\n--%s--\n.\n", bound);
 		}
 		fclose(p);
@@ -1918,6 +2078,7 @@
 	return 0;
 }
 
+#ifndef USE_IMAP_STORAGE
 static int get_date(char *s, int len)
 {
 	struct tm tm;
@@ -1926,6 +2087,7 @@
 	localtime_r(&t,&tm);
 	return strftime(s, len, "%a %b %e %r %Z %Y", &tm);
 }
+#endif
 
 static int invent_message(struct ast_channel *chan, char *context, char *ext, int busy, char *ecodes)
 {
@@ -2227,8 +2389,163 @@
 		return 1;
 	return 0;
 }
-
-
+#endif
+
+#ifdef USE_IMAP_STORAGE
+static int messagecount(const char *mailbox, int *newmsgs, int *oldmsgs)
+{
+  	SEARCHPGM *pgm;
+  	SEARCHHEADER *hdr;
+
+	struct ast_vm_user *vmu;
+	struct vm_state *vms_p;
+	char tmp[256]="";
+	char *mb, *cur;
+	char *mailboxnc; // mailbox without the context
+	//char mailboxnc[256]; // mailbox without the context
+	char *context;
+	int ret = 0;
+	if (newmsgs)
+		*newmsgs = 0;
+	if (oldmsgs)
+		*oldmsgs = 0;
+
+	ast_log (LOG_DEBUG,"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;
+		strncpy(tmp, mailbox, sizeof(tmp) - 1);
+		mb = tmp;
+		ret = 0;
+		while((cur = strsep(&mb, ", "))) {
+			if (!ast_strlen_zero(cur)) {
+				if (messagecount(cur, newmsgs ? &tmpnew : NULL, oldmsgs ? &tmpold : NULL))
+					return -1;
+				else {
+					if (newmsgs)
+						*newmsgs += tmpnew; 
+					if (oldmsgs)
+						*oldmsgs += tmpold;
+				}
+			}
+		}
+		return 0;
+	}
+
+	strncpy(tmp, mailbox, sizeof(tmp) - 1);
+	context = strchr(tmp, '@');
+	if (context) {
+		*context = '\0';
+		mailboxnc = tmp;
+		context++;
+	} else {
+		context = "default";
+		mailboxnc = (char *)mailbox;
+	}
+
+	/* 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, mailboxnc);
+	if (vmu == NULL) {
+  		ast_log (LOG_ERROR,"Couldn't find mailbox %s in context %s\n",mailboxnc,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);
+			return -1;
+		}
+	}
+
+	/* check if someone is accessing this box right now... */
+	vms_p = get_vm_state_by_imapuser(vmu->imapuser,1);
+	if (vms_p == NULL) {
+		vms_p = get_vm_state_by_mailbox(mailboxnc,1);
+	}
+	if (vms_p != NULL) {
+  		ast_log (LOG_DEBUG,"Returning before search - user is logged in\n");
+		*newmsgs = vms_p->newmessages;
+		*oldmsgs = vms_p->oldmessages;
+		return 0;
+	}
+
+	/* add one if not there... */
+	vms_p = get_vm_state_by_imapuser(vmu->imapuser,0);
+	if (vms_p == NULL) {
+		vms_p = get_vm_state_by_mailbox(mailboxnc,0);
+	}
+
+	if (vms_p == NULL) {
+  		ast_log (LOG_DEBUG,"Adding new vmstate for %s\n",vmu->imapuser);
+		vms_p = (struct vm_state *)malloc(sizeof(struct vm_state));
+		strcpy(vms_p->imapuser,vmu->imapuser);
+		strcpy(vms_p->username,mailboxnc); /* save for access from interactive entry point */
+		vms_p->mailstream = NIL; /* save for access from interactive entry point */
+  		ast_log (LOG_DEBUG,"Copied %s to %s\n",vmu->imapuser,vms_p->imapuser);
+		vms_p->updated = 1;
+		vms_p->interactive = 0;
+		/* set mailbox to INBOX! */
+		strncpy(vms_p->curbox, mbox(0), sizeof(vms_p->curbox) - 1);
+		init_vm_state(vms_p);
+		vmstate_insert(vms_p);
+	}
+	if (vms_p->mailstream == NULL)
+		ret = init_mailstream(vms_p);
+	if (vms_p->mailstream == NULL) {
+  		ast_log (LOG_ERROR,"Houston we have a problem - IMAP mailstream is NULL\n");
+		return -1;
+	}
+	if (newmsgs && ret==0 && vms_p->updated==1 ) {
+  		pgm = mail_newsearchpgm ();
+  		hdr = mail_newsearchheader ("X-Asterisk-VM-Extension", (char *)mailboxnc);
+  		pgm->header = hdr;
+		pgm->unseen = 1;
+		pgm->seen = 0;
+		pgm->undeleted = 1;
+		pgm->deleted = 0;
+
+		vms_p->vmArrayIndex = 0;
+	
+  		ast_log (LOG_DEBUG,"Before search of mailbox %s for NEW messages\n",vms_p->mailstream->mailbox);
+  		mail_search_full (vms_p->mailstream, NULL, pgm, NIL);
+  		ast_log (LOG_DEBUG,"After search\n");
+		*newmsgs = vms_p->vmArrayIndex;
+		vms_p->newmessages = vms_p->vmArrayIndex;
+  		ast_log (LOG_DEBUG,"There are %d NEW messages\n",vms_p->newmessages);
+	}
+	if (oldmsgs && ret==0 && vms_p->updated==1 ) {
+  		pgm = mail_newsearchpgm ();
+  		hdr = mail_newsearchheader ("X-Asterisk-VM-Extension", (char *)mailboxnc);
+  		pgm->header = hdr;
+		pgm->unseen = 0;
+		pgm->seen = 1;
+		pgm->deleted = 0;
+		pgm->undeleted = 1;
+
+		vms_p->vmArrayIndex = 0;
+	
+  		ast_log (LOG_DEBUG,"Before search of mailbox %s for OLD messages\n",vms_p->mailstream->mailbox);
+  		mail_search_full (vms_p->mailstream, NULL, pgm, NIL);
+		*oldmsgs = vms_p->vmArrayIndex;
+		vms_p->oldmessages = vms_p->vmArrayIndex;
+  		ast_log (LOG_DEBUG,"There are %d OLD messages\n",vms_p->oldmessages);
+	}
+	if (vms_p->updated == 1) {  /* changes, so we did the searches above */
+		vms_p->updated = 0;
+	} else if (vms_p->updated > 1) {  /* decrement delay count */
+		vms_p->updated--;
+	} else {  /* no changes, so don't search */
+  		ast_log (LOG_DEBUG,"Calling mail_ping on mailbox %s\n",vms_p->mailstream->mailbox);
+		mail_ping(vms_p->mailstream);
+		/* Keep the old data */
+		*newmsgs = vms_p->newmessages;
+		*oldmsgs = vms_p->oldmessages;
+	}
+	return 0;
+}
+#else
 static int messagecount(const char *mailbox, int *newmsgs, int *oldmsgs)
 {
 	DIR *dir;
@@ -2304,6 +2621,7 @@
 
 static int notify_new_message(struct ast_channel *chan, struct ast_vm_user *vmu, int msgnum, long duration, char *fmt, char *cidnum, char *cidname);
 
+/* copy message only used by file storage */
 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 fromdir[256], todir[256], frompath[256], topath[256];
@@ -2367,15 +2685,20 @@
 
 static int leave_voicemail(struct ast_channel *chan, char *ext, struct leave_vm_options *options)
 {
+#ifdef USE_IMAP_STORAGE
+	int newmsgs, oldmsgs;
+	struct vm_state *vms;
+#else
 	char tmptxtfile[256], txtfile[256];
 	char callerid[256];
 	FILE *txt;
+	char date[256];
+#endif
 	int res = 0;
 	int msgnum;
 	int duration = 0;
 	int ausemacro = 0;
 	int ousemacro = 0;
-	char date[256];
 	char dir[256];
 	char fn[256];
 	char prefile[256]="";
@@ -2407,6 +2730,7 @@
 
 	category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY");
 
+	ast_log(LOG_DEBUG, "Before find_user\n");
 	if (!(vmu = find_user(&svm, context, ext))) {
 		ast_log(LOG_WARNING, "No entry in voicemail config file for '%s'\n", ext);
 		if (ast_test_flag(options, OPT_PRIORITY_JUMP) || option_priority_jumping)
@@ -2534,6 +2858,50 @@
 	if (!ast_strlen_zero(fmt)) {
 		msgnum = 0;
 
+#ifdef USE_IMAP_STORAGE
+			/* Is ext a mailbox? */
+			/* must open stream for this user to get info! */
+			vms = get_vm_state_by_mailbox(ext,0);
+			if (vms != NULL) {
+				ast_log(LOG_DEBUG, "Using vm_state, interactive set to %d.\n",vms->interactive);
+				newmsgs = vms->newmessages++;
+				oldmsgs = vms->oldmessages;
+			} else {
+				ast_log(LOG_DEBUG, "About to call messagecount.\n");
+				messagecount(ext, &newmsgs, &oldmsgs);
+			}
+			/* here is a big difference! We add one to it later */
+			msgnum = newmsgs + oldmsgs;
+			ast_log(LOG_NOTICE, "Messagecount set to %d\n",msgnum);
+			sprintf(fn, "%s/msg%s%04d", TMP, vmu->mailbox, msgnum);
+			/* set variable for compatability */
+			pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE");
+
+			/* Check if mailbox is full */
+			if (vms->quota_usage >= vms->quota_limit) {
+				ast_log(LOG_DEBUG, "*** QUOTA EXCEEDED!!\n");
+				ast_play_and_wait(chan, "vm-mailboxfull");
+				return -1;
+			}
+
+			/* play beep */
+			res = ast_streamfile(chan, "beep", chan->language);
+			if (!res)
+				res = ast_waitstream(chan, "");
+			/* play_record_review does recording and verify */
+			ast_log(LOG_DEBUG, "About to record message in file %s\n",fn);
+			res = play_record_review(chan, NULL, fn, vmmaxmessage, fmt, 1, vmu, &duration, dir, options->record_gain);
+			if (res == '0') {
+				goto transfer;
+			}
+			if (res > 0) res = 0;
+
+			if (duration < vmminmessage) {
+				if (option_verbose > 2) 
+					ast_verbose( VERBOSE_PREFIX_3 "Recording was %d seconds long but needs to be at least %d - abandoning\n", duration, vmminmessage);
+				goto leave_vm_out;
+			}
+#else
 		if (vm_lock_path(dir)) {
 			free_user(vmu);
 			return ERROR_LOCK_PATH;
@@ -2616,6 +2984,7 @@
 				pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
 				goto leave_vm_out;
 			}
+#endif
 			/* Are there to be more recipients of this message? */
 			while (tmpptr) {
 				struct ast_vm_user recipu, *recip;
@@ -2632,12 +3001,17 @@
 					free_user(recip);
 				}
 			}
+#ifdef USE_IMAP_STORAGE
+				notify_new_message(chan, vmu, msgnum, duration, fmt, chan->cid.cid_num, chan->cid.cid_name);
+#else
 			if (ast_fileexists(fn, NULL, NULL)) {
 				STORE(dir, vmu->mailbox, vmu->context, msgnum);
 				notify_new_message(chan, vmu, msgnum, duration, fmt, chan->cid.cid_num, chan->cid.cid_name);
 				DISPOSE(dir, msgnum);
 			}
+#endif
 			pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS");
+#ifndef USE_IMAP_STORAGE
 		} else {
 			ast_unlock_path(dir);
 			res = ast_streamfile(chan, "vm-mailboxfull", chan->language);
@@ -2646,14 +3020,18 @@
 			ast_log(LOG_WARNING, "No more messages possible\n");
 			pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
 		}
+#endif
 	} else
 		ast_log(LOG_WARNING, "No format for saving voicemail?\n");
  leave_vm_out:
 	free_user(vmu);
 	
+	ast_filedelete(fn, NULL);
 	return res;
 }
 
+
+#ifndef USE_IMAP_STORAGE
 static int resequence_mailbox(struct ast_vm_user *vmu, char *dir)
 {
 	/* we know max messages, so stop process when number is hit */
@@ -2681,7 +3059,7 @@
 
 	return 0;
 }
-
+#endif
 
 static int say_and_wait(struct ast_channel *chan, int num, char *language)
 {
@@ -2690,8 +3068,27 @@
 	return d;
 }
 
-static int save_to_folder(struct ast_vm_user *vmu, char *dir, int msg, char *context, char *username, int box)
-{
+static int save_to_folder(struct ast_vm_user *vmu, struct vm_state *vms, int msg, int box)
+{
+#ifdef USE_IMAP_STORAGE
+	/* we must use mbox(x) folder names, and copy the message there */
+	/* simple. huh? */
+	char *dbox = mbox(box);
+	long res;
+	char sequence[10];
+
+	/* if save to Old folder, just leave in INBOX */
+	if (box == 1) return 10;
+	/* get the real IMAP message number for this message */
+	sprintf(sequence,"%ld",vms->msgArray[msg]);
+	ast_log(LOG_DEBUG, "Copying sequence %s to mailbox %s\n",sequence,dbox);
+	res = mail_copy(vms->mailstream,sequence,dbox);
+	if (res == 1) return 0;
+	return 1;
+#else
+	char *dir = vms->curdir;
+	char *username = vms->username;
+	char *context = vmu->context;
 	char sfn[256];
 	char dfn[256];
 	char ddir[256];
@@ -2716,7 +3113,7 @@
 		COPY(dir, msg, ddir, x, username, context, sfn, dfn);
 	}
 	ast_unlock_path(ddir);
-	
+#endif
 	return 0;
 }
 
@@ -3306,8 +3703,15 @@
 	char todir[256], fn[256], ext_context[256], *stringp;
 	int newmsgs = 0, oldmsgs = 0;
 
+	ast_log(LOG_DEBUG, "In notify_new_message...\n");
+
+#ifdef USE_IMAP_STORAGE
+	stpcpy(todir,TMP);
+	sprintf(fn, "%s/msg%s%04d", todir, vmu->mailbox, msgnum);
+#else
 	make_dir(todir, sizeof(todir), vmu->context, vmu->mailbox, "INBOX");
 	make_file(fn, sizeof(fn), todir, msgnum);
+#endif
 	snprintf(ext_context, sizeof(ext_context), "%s@%s", vmu->mailbox, vmu->context);
 
 	/* Attach only the first format */
@@ -3322,7 +3726,8 @@
 			attach_user_voicemail = ast_test_flag(vmu, VM_ATTACH);
 			if (!ast_strlen_zero(vmu->serveremail))
 				myserveremail = vmu->serveremail;
-			sendmail(myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, cidnum, cidname, fn, fmt, duration, attach_user_voicemail);
+			/* parameter NULL used for new signature for IMAP */
+			sendmail(myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, cidnum, cidname, fn, fmt, duration, attach_user_voicemail,chan,NULL);
 		}
 
 		if (!ast_strlen_zero(vmu->pager)) {
@@ -3348,25 +3753,36 @@
 	return 0;
 }
 
-static int forward_message(struct ast_channel *chan, char *context, char *dir, int curmsg, struct ast_vm_user *sender,
-			   char *fmt, int flag, signed char record_gain)
-{
+static int forward_message(struct ast_channel *chan, char *context, struct vm_state *vms, struct ast_vm_user *sender, char *fmt, int flag, signed char record_gain)
+{
+#ifdef USE_IMAP_STORAGE
+  	BODY *body;
+	char *header_content;
+	char *temp;
+#else
+	struct ast_config *mif;
+	char sys[256];
+	char miffile[256];
+	char callerid[512];
+	char tmp[256];
+	char ext_context[256]="";
+#endif
 	char username[70]="";
-	char sys[256];
 	char todir[256];
 	int todircount=0;
 	int duration;
-	struct ast_config *mif;
-	char miffile[256];
 	char fn[256];
-	char callerid[512];
-	char ext_context[256]="";
 	int res = 0, cmd = 0;
 	struct ast_vm_user *receiver = NULL, *extensions = NULL, *vmtmp = NULL, *vmfree;
-	char tmp[256];
 	char *stringp, *s;
 	int saved_messages = 0, found = 0;
 	int valid_extensions = 0;
+	char *dir; 
+	int curmsg;
+	
+	if (vms == NULL) return -1;
+	dir = vms->curdir;
+	curmsg = vms->curmsg;
 	
 	while (!res && !valid_extensions) {
 		int use_directory = 0;
@@ -3496,6 +3912,68 @@
 		cmd = vm_forwardoptions(chan, sender, dir, curmsg, vmfmts, context, record_gain);
 		if (!cmd) {
 			while (!res && vmtmp) {
+#ifdef USE_IMAP_STORAGE
+				/* NEED TO CHANGE username to mailbox!! - JAR */
+				/* Need to get message content */
+				ast_log (LOG_DEBUG,"Before mail_fetchheaders, curmsg is: %d, imap messages is %lu\n",vms->curmsg, vms->msgArray[vms->curmsg]);
+				if (vms->msgArray[vms->curmsg] == 0) {
+					ast_log (LOG_WARNING,"Trying to access unknown message\n");
+					return -1;
+				}
+
+				/* This will only work for new messages... */
+  				header_content = mail_fetchheader (vms->mailstream, vms->msgArray[vms->curmsg]);
+				/* empty string means no valid header */
+				if (header_content == "" || header_content == NULL) {
+					ast_log (LOG_ERROR,"Could not fetch header for message number %ld\n",vms->msgArray[vms->curmsg]);
+					return -1;
+				}
+				/* Get header info needed by sendmail */
+				temp = get_header_by_tag(header_content, "X-Asterisk-VM-Duration:");
+				if (temp != NULL)
+					duration = atoi(temp);
+				else
+					duration = 0;
+
+				/* Attach only the first format */
+				fmt = ast_strdupa(fmt);
+				if (fmt) {
+					stringp = fmt;
+					strsep(&stringp, "|");
+				} else {
+					ast_log (LOG_ERROR,"audio format not set. Default to WAV\n");
+					fmt = "WAV";
+				}
+				if (!strcasecmp(fmt, "wav49"))
+					fmt = "WAV";
+				
+				ast_log (LOG_DEBUG,"**** format set to %s, vmfmts set to %s\n",fmt,vmfmts);
+	        		/* ast_copy_string(fmt, vmfmts, sizeof(fmt));*/
+				/* if (!ast_strlen_zero(fmt)) { */
+
+				make_gsm_file(vms->fn, vms->imapuser, TMP, vms->curmsg);
+
+				ast_log (LOG_DEBUG,"Before mail_fetchstructure, message number is %ld, filename is:%s\n",vms->msgArray[vms->curmsg], vms->fn);
+  				/*mail_fetchstructure (mailstream, vmArray[0], &body); */
+  				mail_fetchstructure (vms->mailstream, vms->msgArray[vms->curmsg], &body);
+  				save_body(body,vms,"3","gsm");
+				/* should not assume "fmt" here! */
+  				save_body(body,vms,"2",fmt);
+
+				char *myserveremail = serveremail;
+				if (!ast_strlen_zero(vmtmp->serveremail))
+					myserveremail = vmtmp->serveremail;
+				int attach_user_voicemail = ast_test_flag((&globalflags), VM_ATTACH);
+				attach_user_voicemail = ast_test_flag(vmtmp, VM_ATTACH);
+				stpcpy(todir,TMP);
+				sprintf(fn, "%s/%s/msg%04d", todir, vms->imapuser, vms->curmsg);
+				/* NULL category for IMAP storage */
+				sendmail(myserveremail, vmtmp, todircount, vmtmp->context, vmtmp->mailbox, chan->cid.cid_num, chan->cid.cid_name, fn, fmt, duration, attach_user_voicemail, chan, NULL);
+				saved_messages++;
+				vmfree = vmtmp;
+				vmtmp = vmtmp->next;
+				free_user(vmfree);
+#else
 				/* if (ast_play_and_wait(chan, "vm-savedto"))
 					break;
 				*/
@@ -3549,7 +4027,8 @@
 						attach_user_voicemail = ast_test_flag(vmtmp, VM_ATTACH);
 						if (!ast_strlen_zero(vmtmp->serveremail))
 							myserveremail = vmtmp->serveremail;
-						sendmail(myserveremail, vmtmp, todircount, vmtmp->context, vmtmp->mailbox, chan->cid.cid_num, chan->cid.cid_name, fn, tmp, duration, attach_user_voicemail);
+						/* NULL category for IMAP storage*/
+						sendmail(myserveremail, vmtmp, todircount, vmtmp->context, vmtmp->mailbox, chan->cid.cid_num, chan->cid.cid_name, fn, tmp, duration, attach_user_voicemail, chan, NULL);
 					}
 
 					if (!ast_strlen_zero(vmtmp->pager)) {
@@ -3569,6 +4048,7 @@
 				vmfree = vmtmp;
 				vmtmp = vmtmp->next;
 				free_user(vmfree);
+#endif
 			}
 			if (saved_messages > 0) {
 				/* give confirmation that the message was saved */
@@ -3765,6 +4245,116 @@
 	return res;
 }
 
+#ifdef USE_IMAP_STORAGE
+static int play_message(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms)
+{
+  	BODY *body;
+	char *header_content;
+	char cid[256];
+	char context[256];
+	char origtime[32];
+	char duration[16];
+	char category[32];
+
+	int res = 0;
+	char *temp;
+
+	vms->starting = 0; 
+
+	ast_log (LOG_DEBUG,"Before mail_fetchheaders, curmsg is: %d, imap messages is %lu\n",vms->curmsg, vms->msgArray[vms->curmsg]);
+	if (vms->msgArray[vms->curmsg] == 0) {
+		ast_log (LOG_WARNING,"Trying to access unknown message\n");
+		return -1;
+	}
+
+	/* This will only work for new messages... */
+  	header_content = mail_fetchheader (vms->mailstream, vms->msgArray[vms->curmsg]);
+	/* empty string means no valid header */
+	if (header_content == "" || header_content == NULL) {
+		ast_log (LOG_ERROR,"Could not fetch header for message number %ld\n",vms->msgArray[vms->curmsg]);
+		return -1;
+	}
+
+	make_gsm_file(vms->fn, vms->imapuser,TMP, vms->curmsg);
+
+	ast_log (LOG_DEBUG,"Before mail_fetchstructure, message number is %ld, filename is:%s\n",vms->msgArray[vms->curmsg], vms->fn);
+
+  	mail_fetchstructure (vms->mailstream,vms->msgArray[vms->curmsg],&body);
+  	save_body(body,vms,"3","gsm");
+
+	adsi_message(chan, vms);
+	if (!vms->curmsg)
+		res = wait_file2(chan, vms, "vm-first");	/* "First" */
+	else if (vms->curmsg == vms->lastmsg)
+		res = wait_file2(chan, vms, "vm-last");		/* "last" */
+	if (!res) {
+		res = wait_file2(chan, vms, "vm-message");	/* "message" */
+		if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
+			if (!res)
+				res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, (char *) NULL);
+		}
+	}
+
+	/* Get info from headers!!  */
+	temp = get_header_by_tag(header_content, "X-Asterisk-VM-Caller-ID-Num:");
+	if (temp != NULL) strcpy(cid,temp); else cid[0] = '\0';
+  	ast_log (LOG_DEBUG,"Caller id was set to: %s\n",cid);
+	temp = get_header_by_tag(header_content, "X-Asterisk-VM-Context:");
+	if (temp != NULL) strcpy(context,temp); else context[0] = '\0';
+  	ast_log (LOG_DEBUG,"Context was set to: %s\n",context);
+	temp = get_header_by_tag(header_content, "X-Asterisk-VM-Orig-time:");
+	if (temp != NULL) strcpy(origtime,temp); else origtime[0] = '\0';
+  	ast_log (LOG_DEBUG,"Orig time was set to: %s\n",origtime);
+	temp = get_header_by_tag(header_content, "X-Asterisk-VM-Duration:");
+	if (temp != NULL) strcpy(duration,temp); else duration[0] = '\0';
+  	ast_log (LOG_DEBUG,"Duration was set to: %s\n",duration);
+	temp = get_header_by_tag(header_content, "X-Asterisk-VM-Category:");
+	if (temp != NULL) strcpy(category,temp); else category[0] = '\0';
+  	ast_log (LOG_DEBUG,"Category was set to: %s\n",category);
+
+	/*if (!strncasecmp("macro",context,5))  Macro names in contexts are useless for our needs */
+	/*	context = ast_variable_retrieve(msg_cfg, "message","macrocontext"); */
+	if (res == '1')
+		res = 0;
+
+	ast_log (LOG_DEBUG,"Before checks, res is %d\n",res);
+
+	/* What is the category thing?  JAR */
+	if ((!res) && category[0] != '\0' && category != NULL) {
+		res = play_message_category(chan, category);
+		ast_log (LOG_DEBUG,"category, res is %d, [0] is %c\n",res,category[0]);
+	}
+
+	if ((!res) && (ast_test_flag(vmu, VM_ENVELOPE)) && origtime[0] != '\0')
+		res = play_message_datetime(chan, vmu, origtime, "IMAP_STORAGE");
+	ast_log (LOG_DEBUG,"datetime, res is %d\n",res);
+	if ((!res) && (ast_test_flag(vmu, VM_SAYCID)) && cid[0] !='\0' && context[0] !='\0')
+		res = play_message_callerid(chan, vms, cid, context, 0);
+	ast_log (LOG_DEBUG,"callerid, res is %d\n",res);
+
+        if ((!res) && (ast_test_flag(vmu, VM_SAYDURATION)) && duration[0] != '\0')
+                res = play_message_duration(chan, vms, duration, vmu->saydurationm);
+	ast_log (LOG_DEBUG,"duration, res is %d\n",res);
+
+	/* Allow pressing '1' to skip envelope / callerid */
+	/* if (res == '1')
+		res = 0;
+	*/
+	/*ast_config_destroy(msg_cfg);*/
+	res = 0;
+
+	ast_log (LOG_DEBUG,"Before play of message, res is %d\n",res);
+	if (!res) {
+		/* make_file(vms->fn, sizeof(vms->fn), TMP, vms->curmsg); */
+		ast_log (LOG_DEBUG,"About to play filename:%s\n",vms->fn);
+		vms->heard[vms->curmsg] = 1;
+		res = wait_file(chan, vms, vms->fn);
+	}
+	ast_log (LOG_DEBUG,"Before DISPOSE\n");
+	DISPOSE(vms->curdir, vms->curmsg);
+	return res;
+}
+#else
 static int play_message(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms)
 {
 	int res = 0;
@@ -3838,7 +4428,79 @@
 	DISPOSE(vms->curdir, vms->curmsg);
 	return res;
 }
-
+#endif
+
+#ifdef USE_IMAP_STORAGE
+static int open_mailbox(struct vm_state *vms, struct ast_vm_user *vmu,int box)
+{
+  	SEARCHPGM *pgm;
+  	SEARCHHEADER *hdr;
+	int ret;
+
+	strcpy(vms->imapuser,vmu->imapuser);
+	if (box == 1) {
+		strncpy(vms->curbox, mbox(0), sizeof(vms->curbox) - 1);
+		sprintf(vms->vmbox, "vm-%s", mbox(1));
+	} else {
+		strncpy(vms->curbox, mbox(box), sizeof(vms->curbox) - 1);
+		snprintf(vms->vmbox, sizeof(vms->vmbox), "vm-%s", vms->curbox);
+	}
+
+	/* No need to do another search! */
+	/*
+	if (vms->interactive == 1)  {
+		strncpy(vms->curbox, mbox(box), sizeof(vms->curbox) - 1);
+		snprintf(vms->vmbox, sizeof(vms->vmbox), "vm-%s", vms->curbox);
+		if (box == 0) {
+			vms->lastmsg = vms->newmessages - 1;
+		} else if (box == 1) {
+			vms->lastmsg = vms->oldmessages - 1;
+		}
+		return 0;
+	}
+	*/
+
+  	ast_log(LOG_DEBUG,"Before init_mailstream, user is %s\n",vmu->imapuser);
+	ret = init_mailstream(vms);
+	if (ret != 0) {
+  		ast_log (LOG_ERROR,"Could not initialize mailstream\n");
+		return -1;
+	}
+
+	/* Check Quota (here for now to test) */
+  	ast_log(LOG_DEBUG,"Checking QUOTA...\n");
+	mail_parameters(NULL, SET_QUOTA, (void *) mm_parsequota);
+	imap_getquotaroot(vms->mailstream,"INBOX");
+
+  	pgm = mail_newsearchpgm();
+
+	/* Check IMAP folder for Asterisk messages only... */
+  	ast_log(LOG_DEBUG,"setting search criteria - mailbox set to %s\n",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) {
+		pgm->unseen = 1;
+		pgm->seen = 0;
+	} else if (box == 1) {
+		pgm->seen = 1;
+		pgm->unseen = 0;
+	}
+
+	vms->vmArrayIndex = 0;
+
+  	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;
+
+	return 0;
+}
+#else
 static int open_mailbox(struct vm_state *vms, struct ast_vm_user *vmu,int box)
 {
 	int res = 0;
@@ -3878,20 +4540,24 @@
 
 	return 0;
 }
+#endif
 
 static int close_mailbox(struct vm_state *vms, struct ast_vm_user *vmu)
 {
-	int x, nummsg;
-	int res = 0;
-
+	int x = 0;
+	ast_log(LOG_DEBUG,"Entering method...\n");
 	if (vms->lastmsg <= -1)
 		goto done;
+
+	vms->curmsg = -1; 
+
+#ifndef USE_IMAP_STORAGE
+	int res = 0, nummsg;
 
 	/* Get the deleted messages fixed */ 
 	if (vm_lock_path(vms->curdir))
 		return ERROR_LOCK_PATH;
-	
-	vms->curmsg = -1; 
+	 
 	for (x = 0; x < vmu->maxmsg; x++) { 
 		if (!vms->deleted[x] && (strcasecmp(vms->curbox, "INBOX") || !vms->heard[x])) { 
 			/* Save this message.  It's not in INBOX or hasn't been heard */ 
@@ -3905,7 +4571,7 @@
 			} 
 		} else if (!strcasecmp(vms->curbox, "INBOX") && vms->heard[x] && !vms->deleted[x]) { 
 			/* Move to old folder before deleting */ 
-			res = save_to_folder(vmu, vms->curdir, x, vmu->context, vms->username, 1);
+	        res = save_to_folder(vmu, vms, x, 1);
 			if (res == ERROR_LOCK_PATH) {
 				/* If save failed do not delete the message */
 				vms->deleted[x] = 0;
@@ -3913,8 +4579,6 @@
 				--x;
 			} 
 		} 
-	} 
-
 	/* Delete ALL remaining messages */
 	nummsg = x - 1;
 	for (x = vms->curmsg + 1; x <= nummsg; x++) {
@@ -3922,7 +4586,16 @@
 		if (EXISTS(vms->curdir, x, vms->fn, NULL))
 			DELETE(vms->curdir, x, vms->fn);
 	}
+	}
 	ast_unlock_path(vms->curdir);
+#else
+	for (x=0;x < vmu->maxmsg;x++) { 
+	    if (vms->deleted[x]) { 
+	    	ast_log(LOG_DEBUG,"IMAP delete of %d\n",x);
+		IMAP_DELETE(vms->curdir, x, vms->fn, vms);
+	    }
+	}
+#endif
 
 done:
 	if (vms->deleted)
@@ -4642,7 +5315,7 @@
 		vm_change_password(vmu,newpassword);
 	else 
 		vm_change_password_shell(vmu,newpassword);
-	
+	ast_log(LOG_DEBUG,"User %s set password to %s of length %d\n",vms->username,newpassword,(int)strlen(newpassword));
 	cmd = ast_play_and_wait(chan,"vm-passchanged");
 
 	/* If forcename is set, have the user record their name */	
@@ -4991,6 +5664,7 @@
 			ast_copy_string(mailbox, fullusername, mailbox_size);
 		}
 
+		ast_log(LOG_DEBUG, "Before find user for mailbox %s\n",mailbox);
 		vmu = find_user(&vmus, context, mailbox);
 		if (vmu && (vmu->password[0] == '\0' || (vmu->password[0] == '-' && vmu->password[1] == '\0'))) {
 			/* saved password is blank, so don't bother asking */
@@ -5068,15 +5742,20 @@
 	int silentexit = 0;
 	struct ast_flags flags = { 0 };
 	signed char record_gain = 0;
+#ifdef USE_IMAP_STORAGE
+	int deleted = 0;
+#endif
 
 	LOCAL_USER_ADD(u);
 
+	/* Add the vm_state to the active list and keep it active */
 	memset(&vms, 0, sizeof(vms));
 	vms.lastmsg = -1;
 
 	memset(&vmus, 0, sizeof(vmus));
 
 	if (chan->_state != AST_STATE_UP)
+		ast_log(LOG_DEBUG, "Before ast_answer\n");
 		ast_answer(chan);
 
 	if (!ast_strlen_zero(data)) {
@@ -5137,6 +5816,7 @@
 	if (!valid)
 		res = vm_authenticate(chan, vms.username, sizeof(vms.username), &vmus, context, prefixstr, skipuser, maxlogins, 0);
 
+	ast_log(LOG_DEBUG, "After vm_authenticate\n");
 	if (!res) {
 		valid = 1;
 		if (!skipuser)
@@ -5148,6 +5828,12 @@
 	/* If ADSI is supported, setup login screen */
 	adsi_begin(chan, &useadsi);
 
+#ifdef USE_IMAP_STORAGE
+	vms.interactive = 1;
+	vms.updated = 2;
+	vmstate_insert(&vms);
+	init_vm_state(&vms);
+#endif
 	if (!valid)
 		goto out;
 
@@ -5157,17 +5843,22 @@
 	/* Set language from config to override channel language */
 	if (!ast_strlen_zero(vmu->language))
 		ast_copy_string(chan->language, vmu->language, sizeof(chan->language));
+#ifndef USE_IMAP_STORAGE
 	create_dirpath(vms.curdir, sizeof(vms.curdir), vmu->context, vms.username, "");
+#endif
 	/* Retrieve old and new message counts */
+	ast_log(LOG_DEBUG, "Before open_mailbox\n");
 	res = open_mailbox(&vms, vmu, 1);
 	if (res == ERROR_LOCK_PATH)
 		goto out;
 	vms.oldmessages = vms.lastmsg + 1;
+	ast_log(LOG_DEBUG, "Number of old messages: %d\n",vms.oldmessages);
 	/* Start in INBOX */
 	res = open_mailbox(&vms, vmu, 0);

[... 1221 lines stripped ...]


More information about the asterisk-commits mailing list