[asterisk-commits] branch group/asterisk-imap r37204 - /team/group/asterisk-imap/apps/

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Thu Jul 6 09:33:49 MST 2006


Author: mogorman
Date: Thu Jul  6 11:33:48 2006
New Revision: 37204

URL: http://svn.digium.com/view/asterisk?rev=37204&view=rev
Log:
adds imap storage to voicemail with no easy way
to turn it on in make system 

Modified:
    team/group/asterisk-imap/apps/app_voicemail.c

Modified: team/group/asterisk-imap/apps/app_voicemail.c
URL: http://svn.digium.com/view/asterisk/team/group/asterisk-imap/apps/app_voicemail.c?rev=37204&r1=37203&r2=37204&view=diff
==============================================================================
--- team/group/asterisk-imap/apps/app_voicemail.c (original)
+++ team/group/asterisk-imap/apps/app_voicemail.c Thu Jul  6 11:33:48 2006
@@ -40,10 +40,17 @@
  *
  * 12-04-2006 : Support for Polish added by DIR (www.dir.pl)
  *				 Bartosz Supczinski <Bartosz.Supczinski at dir.pl>
+ * 03-01-2006 : Support for IMAP storage integration added by OneBizTone LLC
+ *               Work funded by University of Pennsylvania
+ *               James Rothenberger <jar at onebiztone.com>
  */
 
 /*** MAKEOPTS
 <category name="MENUSELECT_app_voicemail" displayname="Voicemail Build Options" positive_output="yes" remove_on_change="apps/app_voicemail.o">
+	<member name="IMAP_STORAGE" displayname="Storage of Voicemail using IMAP">
+		<depend>imap</depend>
+		<defaultenabled>no</defaultenabled>
+	</member>
 	<member name="ODBC_STORAGE" displayname="Storage of Voicemail using ODBC">
 		<depend>unixodbc</depend>
 		<defaultenabled>no</defaultenabled>
@@ -75,7 +82,14 @@
 #include <sys/mman.h>
 #include <time.h>
 #include <dirent.h>
-
+#ifdef USE_IMAP_STORAGE
+#include <ctype.h>
+#include <signal.h>
+#include <pwd.h>
+#include "c-client/c-client.h"
+#include "c-client/imap4r1.h"
+#include "c-client/linkage.h"
+#endif
 #include "asterisk/lock.h"
 #include "asterisk/file.h"
 #include "asterisk/logger.h"
@@ -94,10 +108,56 @@
 #include "asterisk/utils.h"
 #include "asterisk/stringfields.h"
 #include "asterisk/smdi.h"
-#define SMDI_MWI_WAIT_TIMEOUT 1000 /* 1 second */
-#ifdef ODBC_STORAGE
+#ifdef USE_ODBC_STORAGE
 #include "asterisk/res_odbc.h"
 #endif
+
+#ifdef USE_IMAP_STORAGE
+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 vm_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;
+};
+AST_MUTEX_DEFINE_STATIC(vmstate_lock);
+static struct vmstate *vmstates = NULL;
+#endif
+
+#define SMDI_MWI_WAIT_TIMEOUT 1000 /* 1 second */
 
 #define COMMAND_TIMEOUT 5000
 #define	VOICEMAIL_DIR_MODE	0770
@@ -140,6 +200,7 @@
 #define VM_SEARCH		(1 << 14)
 #define VM_TEMPGREETWARN	(1 << 15)	/*!< Remind user tempgreeting is set */
 #define ERROR_LOCK_PATH		-100
+
 
 enum {
 	OPT_SILENT =           (1 << 0),
@@ -270,6 +331,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
 	AST_LIST_ENTRY(ast_vm_user) list;
 };
 
@@ -295,6 +359,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);
@@ -304,7 +379,8 @@
 			      signed char record_gain);
 static int vm_tempgreeting(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain);
 static int vm_play_folder_name(struct ast_channel *chan, char *mbox);
-
+static int notify_new_message(struct ast_channel *chan, struct ast_vm_user *vmu, int msgnum, long duration, char *fmt, char *cidnum, char *cidname);
+static int __has_voicemail(const char *context, const char *mailbox, const char *folder, int shortcircuit);
 static void apply_options(struct ast_vm_user *vmu, const char *options);
 
 #ifdef ODBC_STORAGE
@@ -318,6 +394,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) (vm_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)
@@ -325,6 +411,7 @@
 #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 DELETE(a,b,c) (vm_delete(c))
+#endif
 #endif
 
 static char VM_SPOOL_DIR[PATH_MAX];
@@ -358,7 +445,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";
 
@@ -487,6 +574,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")){
@@ -793,10 +884,8 @@
 {
 	char buf[255];
 	snprintf(buf,255,"%s %s %s %s",ext_pass_cmd,vmu->context,vmu->mailbox,newpassword);
-	if (!ast_safe_system(buf)) {
-		reset_user_pw(vmu->context, vmu->mailbox, newpassword);
+	if (!ast_safe_system(buf))
 		ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
-	}
 }
 
 static int make_dir(char *dest, int len, const char *context, const char *ext, const char *folder)
@@ -804,6 +893,40 @@
 	return snprintf(dest, len, "%s%s/%s/%s", VM_SPOOL_DIR, context, ext, folder);
 }
 
+#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 vm_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);
@@ -844,6 +967,7 @@
 	return 1;
 }
 
+#ifndef USE_IMAP_STORAGE
 /* only return failure if ast_lock_path returns 'timeout',
    not if the path does not exist or any other reason
 */
@@ -856,6 +980,7 @@
 		return 0;
 	}
 }
+#endif
 
 
 #ifdef ODBC_STORAGE
@@ -1441,6 +1566,7 @@
 
 #else
 
+#ifndef USE_IMAP_STORAGE
 static int count_messages(struct ast_vm_user *vmu, char *dir)
 {
 	/* Find all .txt files - even if they are not in sequence from 0000 */
@@ -1553,6 +1679,7 @@
 
 	return x - 1;
 }
+#endif
 
 static int vm_delete(char *file)
 {
@@ -1749,7 +1876,7 @@
 	return p;
 }
 
-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, const char *category)
+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, const char *category)
 {
 	FILE *p=NULL;
 	char date[256];
@@ -1831,6 +1958,23 @@
 		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)ast_random(), 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
 		if (!ast_strlen_zero(cidnum))
 			fprintf(p, "X-Asterisk-CallerID: %s\n", cidnum);
 		if (!ast_strlen_zero(cidname))
@@ -1879,6 +2023,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);
@@ -1972,6 +2130,7 @@
 	return 0;
 }
 
+#ifndef USE_IMAP_STORAGE
 static int get_date(char *s, int len)
 {
 	struct tm tm;
@@ -1980,6 +2139,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)
 {
@@ -2224,7 +2384,205 @@
 }
 
 #else
-
+#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 *context, const char *mailbox, const char *folder)
+{
+	return __has_voicemail(context, mailbox, folder, 0);
+}
+
+/* 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];
+	const char *frombox = mbox(imbox);
+	int recipmsgnum;
+
+	ast_log(LOG_NOTICE, "Copying message from %s@%s to %s@%s\n", vmu->mailbox, vmu->context, recip->mailbox, recip->context);
+
+	create_dirpath(todir, sizeof(todir), recip->context, recip->mailbox, "INBOX");
+  
+	make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox);
+	make_file(frompath, sizeof(frompath), fromdir, msgnum);
+
+	if (vm_lock_path(todir))
+		return ERROR_LOCK_PATH;
+
+	recipmsgnum = 0;
+	do {
+		make_file(topath, sizeof(topath), todir, recipmsgnum);
+		if (!EXISTS(todir, recipmsgnum, topath, chan->language))
+			break;
+		recipmsgnum++;
+	} while (recipmsgnum < recip->maxmsg);
+	if (recipmsgnum < recip->maxmsg) {
+		COPY(fromdir, msgnum, todir, recipmsgnum, recip->mailbox, recip->context, frompath, topath);
+	} else {
+		ast_log(LOG_ERROR, "Recipient mailbox %s@%s is full\n", recip->mailbox, recip->context);
+	}
+	ast_unlock_path(todir);
+	notify_new_message(chan, recip, recipmsgnum, duration, fmt, chan->cid.cid_num, chan->cid.cid_name);
+	
+	return 0;
+}
+#endif
+#endif
+
+#ifndef ODBC_STORAGE
 static int __has_voicemail(const char *context, const char *mailbox, const char *folder, int shortcircuit)
 {
 	DIR *dir;
@@ -2255,6 +2613,7 @@
 	return ret;
 }
 
+
 static int has_voicemail(const char *mailbox, const char *folder)
 {
 	char tmp[256], *tmp2 = tmp, *mbox, *context;
@@ -2270,10 +2629,6 @@
 	return 0;
 }
 
-static int messagecount(const char *context, const char *mailbox, const char *folder)
-{
-	return __has_voicemail(context, mailbox, folder, 0);
-}
 
 static int inboxcount(const char *mailbox, int *newmsgs, int *oldmsgs)
 {
@@ -2323,42 +2678,6 @@
 
 #endif
 
-static int notify_new_message(struct ast_channel *chan, struct ast_vm_user *vmu, int msgnum, long duration, char *fmt, char *cidnum, char *cidname);
-
-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];
-	const char *frombox = mbox(imbox);
-	int recipmsgnum;
-
-	ast_log(LOG_NOTICE, "Copying message from %s@%s to %s@%s\n", vmu->mailbox, vmu->context, recip->mailbox, recip->context);
-
-	create_dirpath(todir, sizeof(todir), recip->context, recip->mailbox, "INBOX");
-  
-	make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox);
-	make_file(frompath, sizeof(frompath), fromdir, msgnum);
-
-	if (vm_lock_path(todir))
-		return ERROR_LOCK_PATH;
-
-	recipmsgnum = 0;
-	do {
-		make_file(topath, sizeof(topath), todir, recipmsgnum);
-		if (!EXISTS(todir, recipmsgnum, topath, chan->language))
-			break;
-		recipmsgnum++;
-	} while (recipmsgnum < recip->maxmsg);
-	if (recipmsgnum < recip->maxmsg) {
-		COPY(fromdir, msgnum, todir, recipmsgnum, recip->mailbox, recip->context, frompath, topath);
-	} else {
-		ast_log(LOG_ERROR, "Recipient mailbox %s@%s is full\n", recip->mailbox, recip->context);
-	}
-	ast_unlock_path(todir);
-	notify_new_message(chan, recip, recipmsgnum, duration, fmt, chan->cid.cid_num, chan->cid.cid_name);
-	
-	return 0;
-}
-
 static void run_externnotify(char *context, char *extension)
 {
 	char arguments[255];
@@ -2406,16 +2725,22 @@
 
 static int leave_voicemail(struct ast_channel *chan, char *ext, struct leave_vm_options *options)
 {
-	char txtfile[256], tmptxtfile[256];
+#ifdef USE_IMAP_STORAGE
+	int newmsgs, oldmsgs;
+	struct vm_state *vms;
+#else
+	char tmptxtfile[256], txtfile[256];
 	char callerid[256];
 	FILE *txt;
-	int res = 0, txtdes;
+	char date[256];
+	int  txtdes;
+#endif
+	int res = 0;
 	int msgnum;
 	int duration = 0;
 	int ausemacro = 0;
 	int ousemacro = 0;
 	int ouseexten = 0;
-	char date[256];
 	char dir[256], tmpdir[260];
 	char fn[256];
 	char prefile[256]="";
@@ -2444,6 +2769,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) || ast_opt_priority_jumping)
@@ -2482,8 +2808,8 @@
 			ouseexten = 1;
 		}
 		else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "o", 1, chan->cid.cid_num)) {
-			strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
-			ousemacro = 1;
+		strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
+		ousemacro = 1;
 		}
 	}
 
@@ -2573,6 +2899,51 @@
 	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;
+		}
+		notify_new_message(chan, vmu, msgnum, duration, fmt, chan->cid.cid_num, chan->cid.cid_name);
+#else
 		if (count_messages(vmu, dir) >= vmu->maxmsg) {
 			res = ast_streamfile(chan, "vm-mailboxfull", chan->language);
 			if (!res)
@@ -2598,7 +2969,7 @@
 			/* Unless we're *really* silent, try to send the beep */
 			res = ast_stream_and_wait(chan, "beep", chan->language, "");
 		}
-
+				
 		/* Store information */
 		txt = fdopen(txtdes, "w+");
 		if (txt) {
@@ -2630,12 +3001,11 @@
 		} else
 			ast_log(LOG_WARNING, "Error opening text file for output\n");
 		res = play_record_review(chan, NULL, tmptxtfile, vmmaxmessage, fmt, 1, vmu, &duration, NULL, options->record_gain);
-
+				
 		if (txt) {
 			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);
-				fclose(txt);
 				ast_filedelete(tmptxtfile, NULL);
 				unlink(tmptxtfile);
 			} else {
@@ -2646,10 +3016,6 @@
 					/* Delete files */
 					ast_filedelete(tmptxtfile, NULL);
 					unlink(tmptxtfile);
-				} else if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) {
-					if (option_debug) 
-						ast_log(LOG_DEBUG, "The recorded media file is gone, so we should remove the .txt file too!\n");
-					unlink(tmptxtfile);	
 				} else {
 					for (;;) {
 						make_file(fn, sizeof(fn), dir, msgnum);
@@ -2666,12 +3032,11 @@
 					rename(tmptxtfile, txtfile);
 
 					ast_unlock_path(dir);
-
 					/* Are there to be more recipients of this message? */
 					while (tmpptr) {
 						struct ast_vm_user recipu, *recip;
 						char *exten, *context;
-
+					
 						exten = strsep(&tmpptr, "&");
 						context = strchr(exten, '@');
 						if (context) {
@@ -2683,7 +3048,7 @@
 							free_user(recip);
 						}
 					}
-					if (ast_fileexists(fn, NULL, NULL) > 0) {
+					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);
@@ -2691,7 +3056,7 @@
 				}
 			}
 		}
-
+#endif
 		if (res == '0') {
 			goto transfer;
 		} else if (res > 0)
@@ -2710,6 +3075,7 @@
 	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 */
@@ -2737,7 +3103,7 @@
 
 	return 0;
 }
-
+#endif
 
 static int say_and_wait(struct ast_channel *chan, int num, const char *language)
 {
@@ -2746,8 +3112,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];
@@ -2772,7 +3157,7 @@
 		COPY(dir, msg, ddir, x, username, context, sfn, dfn);
 	}
 	ast_unlock_path(ddir);
-	
+#endif
 	return 0;
 }
 
@@ -3363,8 +3748,15 @@
 	int newmsgs = 0, oldmsgs = 0;
 	const char *category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY");
 
+	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);
 
 	if (!ast_strlen_zero(vmu->attachfmt)) {
@@ -3386,7 +3778,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, category);
+		/*XXX possible imap issue, should category be NULL XXX*/
+		sendmail(myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, cidnum, cidname, fn, fmt, duration, attach_user_voicemail, chan, category);
 	}
 
 	if (!ast_strlen_zero(vmu->pager)) {
@@ -3409,26 +3802,38 @@
 	return 0;
 }
 
-static int forward_message(struct ast_channel *chan, char *context, char *dir, int curmsg, struct ast_vm_user *sender,
+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, *vmtmp;
 	AST_LIST_HEAD_NOLOCK_STATIC(extensions, ast_vm_user);
-	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;
@@ -3553,6 +3958,65 @@
 		cmd = vm_forwardoptions(chan, sender, dir, curmsg, vmfmts, context, record_gain);
 		if (!cmd) {
 			AST_LIST_TRAVERSE_SAFE_BEGIN(&extensions, vmtmp, list) {
+#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);
+#else
+
 				/* if (ast_play_and_wait(chan, "vm-savedto"))
 					break;
 				*/
@@ -3607,7 +4071,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, category);
+						/*XXX POSSIBLE ISSUE FOR IMAP STORAGE but no idea how its an else statement XXX*/
+						sendmail(myserveremail, vmtmp, todircount, vmtmp->context, vmtmp->mailbox, chan->cid.cid_num, chan->cid.cid_name, fn, tmp, duration, attach_user_voicemail, chan, category);
 					}
 
 					if (!ast_strlen_zero(vmtmp->pager)) {
@@ -3622,7 +4087,7 @@
 				/* Leave voicemail for someone */
 				manager_event(EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext_context, has_voicemail(ext_context, NULL));
 				run_externnotify(vmtmp->context, vmtmp->mailbox);
-	
+#endif
 				saved_messages++;
 				AST_LIST_REMOVE_CURRENT(&extensions, list);
 				free_user(vmtmp);
@@ -3850,6 +4315,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;
@@ -3910,7 +4485,7 @@
 		ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename);
 		return 0;
 	}
-																									
+
 	if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) {
 		ast_log(LOG_WARNING, "No origtime?!\n");
 		DISPOSE(vms->curdir, vms->curmsg);
@@ -3925,7 +4500,6 @@
 	context = ast_variable_retrieve(msg_cfg, "message", "context");
 	if (!strncasecmp("macro",context,5)) /* Macro names in contexts are useless for our needs */
 		context = ast_variable_retrieve(msg_cfg, "message","macrocontext");
-
 	if (!res)
 		res = play_message_category(chan, category);
 	if ((!res) && (ast_test_flag(vmu, VM_ENVELOPE)))
@@ -3947,7 +4521,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;
+	}

[... 1133 lines stripped ...]


More information about the asterisk-commits mailing list