Index: apps/app_voicemail.c
===================================================================
RCS file: /usr/cvsroot/asterisk/apps/app_voicemail.c,v
retrieving revision 1.215
diff -u -r1.215 app_voicemail.c
--- apps/app_voicemail.c	17 May 2005 17:19:53 -0000	1.215
+++ apps/app_voicemail.c	30 May 2005 19:29:35 -0000
@@ -210,18 +210,18 @@
 static char odbc_database[80];
 #define RETRIEVE(a,b) retrieve_file(a,b)
 #define DISPOSE(a,b) remove_file(a,b)
-#define STORE(a,b) store_file(a,b)
+#define STORE(a,b,c,d) store_file(a,b,c,d)
 #define EXISTS(a,b,c,d) (message_exists(a,b))
-#define RENAME(a,b,c,d,e,f) (rename_file(a,b,c,d))
-#define COPY(a,b,c,d,e,f) (copy_file(a,b,c,d))
+#define RENAME(a,b,c,d,e,f,g,h) (rename_file(a,b,c,d,e,f))
+#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
 #define RETRIEVE(a,b)
 #define DISPOSE(a,b)
-#define STORE(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) (rename_file(e,f));
-#define COPY(a,b,c,d,e,f) (copy_file(e,f));
+#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
 
@@ -796,7 +796,8 @@
 						fprintf(f, "%s=%s\n", coltitle, rowdata);
 				}
 			}
-		}
+		} else if (msgnum > -1) /* msgnum will be -1 if the message hasn't yet been saved */
+			ast_log(LOG_WARNING, "Failed to retrieve rows for msgnum=%s and dir=%s\n", msgnums, dir);
 		SQLFreeHandle (SQL_HANDLE_STMT, stmt);
 	} else
 		ast_log(LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);
@@ -996,7 +997,7 @@
 	return;	
 }
 
-static void copy_file(char *sdir, int smsg, char *ddir, int dmsg)
+static void copy_file(char *sdir, int smsg, char *ddir, int dmsg, char *dmailboxuser, char *dmailboxcontext)
 {
 	int res;
 	SQLLEN rowcount=0;
@@ -1016,7 +1017,7 @@
 			ast_log(LOG_WARNING, "SQL Alloc Handle failed!\n");
 			goto yuck;
 		}
-		snprintf(sql, sizeof(sql), "INSERT INTO voicemessages (dir, msgnum, context, macrocontext, callerid, origtime, duration, recording) SELECT ?,?,context,macrocontext,callerid,origtime,duration,recording FROM voicemessages WHERE dir=? AND msgnum=?");
+		snprintf(sql, sizeof(sql), "INSERT INTO voicemessages (dir, msgnum, context, macrocontext, callerid, origtime, duration, recording, mailboxuser, mailboxcontext) SELECT ?,?,context,macrocontext,callerid,origtime,duration,recording,?,? FROM voicemessages WHERE dir=? AND msgnum=?");
 		res = SQLPrepare(stmt, sql, SQL_NTS);
 		if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
 			ast_log(LOG_WARNING, "SQL Prepare failed![%s]\n", sql);
@@ -1025,8 +1026,10 @@
 		}
 		SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(ddir), 0, (void *)ddir, 0, NULL);
 		SQLBindParameter(stmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(msgnumd), 0, (void *)msgnumd, 0, NULL);
-		SQLBindParameter(stmt, 3, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(sdir), 0, (void *)sdir, 0, NULL);
-		SQLBindParameter(stmt, 4, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(msgnums), 0, (void *)msgnums, 0, NULL);
+		SQLBindParameter(stmt, 3, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(dmailboxuser), 0, (void *)dmailboxuser, 0, NULL);
+		SQLBindParameter(stmt, 4, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(dmailboxcontext), 0, (void *)dmailboxcontext, 0, NULL);
+		SQLBindParameter(stmt, 5, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(sdir), 0, (void *)sdir, 0, NULL);
+		SQLBindParameter(stmt, 6, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(msgnums), 0, (void *)msgnums, 0, NULL);
 		res = odbc_smart_execute(obj, stmt);
 		if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
 			ast_log(LOG_WARNING, "SQL Execute error!\n[%s] (You probably don't have MySQL 4.1 or later installed)\n\n", sql);
@@ -1046,7 +1049,7 @@
 	return;	
 }
 
-static int store_file(char *dir, int msgnum)
+static int store_file(char *dir, char *mailboxuser, char *mailboxcontext, int msgnum)
 {
 	int x = 0;
 	int res;
@@ -1117,9 +1120,9 @@
 			goto yuck;
 		}
 		if (!ast_strlen_zero(category)) 
-			snprintf(sql, sizeof(sql), "INSERT INTO voicemessages (dir,msgnum,recording,context,macrocontext,callerid,origtime,duration,category) VALUES (?,?,?,?,?,?,?,?,?)");
+			snprintf(sql, sizeof(sql), "INSERT INTO voicemessages (dir,msgnum,recording,context,macrocontext,callerid,origtime,duration,mailboxuser,mailboxcontext,category) VALUES (?,?,?,?,?,?,?,?,?,?,?)");
 		else
-			snprintf(sql, sizeof(sql), "INSERT INTO voicemessages (dir,msgnum,recording,context,macrocontext,callerid,origtime,duration) VALUES (?,?,?,?,?,?,?,?)");
+			snprintf(sql, sizeof(sql), "INSERT INTO voicemessages (dir,msgnum,recording,context,macrocontext,callerid,origtime,duration,mailboxuser,mailboxcontext) VALUES (?,?,?,?,?,?,?,?,?,?)");
 		res = SQLPrepare(stmt, sql, SQL_NTS);
 		if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
 			ast_log(LOG_WARNING, "SQL Prepare failed![%s]\n", sql);
@@ -1135,8 +1138,10 @@
 		SQLBindParameter(stmt, 6, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(callerid), 0, (void *)callerid, 0, NULL);
 		SQLBindParameter(stmt, 7, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(origtime), 0, (void *)origtime, 0, NULL);
 		SQLBindParameter(stmt, 8, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(duration), 0, (void *)duration, 0, NULL);
+		SQLBindParameter(stmt, 9, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(mailboxuser), 0, (void *)mailboxuser, 0, NULL);
+		SQLBindParameter(stmt, 10, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(mailboxcontext), 0, (void *)mailboxcontext, 0, NULL);
 		if (!ast_strlen_zero(category))
-			SQLBindParameter(stmt, 9, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(category), 0, (void *)category, 0, NULL);
+			SQLBindParameter(stmt, 11, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(category), 0, (void *)category, 0, NULL);
 		res = odbc_smart_execute(obj, stmt);
 		if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
 			ast_log(LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);
@@ -1162,7 +1167,7 @@
 	return x;
 }
 
-static void rename_file(char *sdir, int smsg, char *ddir, int dmsg)
+static void rename_file(char *sdir, int smsg, char *mailboxuser, char *mailboxcontext, char *ddir, int dmsg)
 {
 	int res;
 	SQLLEN rowcount=0;
@@ -1182,7 +1187,7 @@
 			ast_log(LOG_WARNING, "SQL Alloc Handle failed!\n");
 			goto yuck;
 		}
-		snprintf(sql, sizeof(sql), "UPDATE voicemessages SET dir=?, msgnum=? WHERE dir=? AND msgnum=?");
+		snprintf(sql, sizeof(sql), "UPDATE voicemessages SET dir=?, msgnum=?, mailboxuser=?, mailboxcontext=? WHERE dir=? AND msgnum=?");
 		res = SQLPrepare(stmt, sql, SQL_NTS);
 		if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
 			ast_log(LOG_WARNING, "SQL Prepare failed![%s]\n", sql);
@@ -1191,8 +1196,10 @@
 		}
 		SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(ddir), 0, (void *)ddir, 0, NULL);
 		SQLBindParameter(stmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(msgnumd), 0, (void *)msgnumd, 0, NULL);
-		SQLBindParameter(stmt, 3, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(sdir), 0, (void *)sdir, 0, NULL);
-		SQLBindParameter(stmt, 4, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(msgnums), 0, (void *)msgnums, 0, NULL);
+		SQLBindParameter(stmt, 3, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(mailboxuser), 0, (void *)mailboxuser, 0, NULL);
+		SQLBindParameter(stmt, 4, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(mailboxcontext), 0, (void *)mailboxcontext, 0, NULL);
+		SQLBindParameter(stmt, 5, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(sdir), 0, (void *)sdir, 0, NULL);
+		SQLBindParameter(stmt, 6, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(msgnums), 0, (void *)msgnums, 0, NULL);
 		res = odbc_smart_execute(obj, stmt);
 		if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
 			ast_log(LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);
@@ -1956,7 +1963,7 @@
 		recipmsgnum++;
 	} while (recipmsgnum < MAXMSG);
 	if (recipmsgnum < MAXMSG) {
-		COPY(fromdir, msgnum, todir, recipmsgnum, frompath, topath);
+		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);
 	}
@@ -2232,7 +2239,7 @@
 				}
 				if (ast_fileexists(fn, NULL, NULL)) {
 					notify_new_message(chan, vmu, msgnum, duration, fmt, chan->cid.cid_num, chan->cid.cid_name);
-					STORE(dir, msgnum);
+					STORE(dir, vmu->mailbox, vmu->context, msgnum);
 					DISPOSE(dir, msgnum);
 				}
 			} else {
@@ -2257,7 +2264,7 @@
 }
 
 
-static void resequence_mailbox(char * dir)
+static void resequence_mailbox(char * dir, struct ast_vm_user *vmu)
 {
 	/* we know max messages, so stop process when number is hit */
 
@@ -2272,7 +2279,7 @@
 
 			if(x != dest) {
 				make_file(dfn, sizeof(dfn), dir, dest);
-				RENAME(dir, x, dir, dest, sfn, dfn);
+				RENAME(dir, x, vmu->mailbox, vmu->context, dir, dest, sfn, dfn);
 			}
 
 			dest++;
@@ -2310,7 +2317,7 @@
 		return -1;
 	}
 	if (strcmp(sfn, dfn)) {
-		COPY(dir, msg, ddir, x, sfn, dfn);
+		COPY(dir, msg, ddir, x, username, context, sfn, dfn);
 	}
 	ast_unlock_path(ddir);
 	return 0;
@@ -3415,7 +3422,7 @@
 	if(vms->lastmsg != last_message_index(vms->curdir))
 	{
 		ast_log(LOG_NOTICE, "Resequencing Mailbox: %s\n", vms->curdir);
-		resequence_mailbox(vms->curdir);
+		resequence_mailbox(vms->curdir, vmu);
 	}
 
 	snprintf(vms->vmbox, sizeof(vms->vmbox), "vm-%s", vms->curbox);
@@ -3437,7 +3444,7 @@
 				vms->curmsg++; 
 				make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg); 
 				if (strcmp(vms->fn, vms->fn2)) { 
-					RENAME(vms->curdir, x, vms->curdir, vms->curmsg, vms->fn, vms->fn2);
+					RENAME(vms->curdir, x, vmu->mailbox, vmu->context, vms->curdir, vms->curmsg, vms->fn, vms->fn2);
 				} 
 			} else if (!strcasecmp(vms->curbox, "INBOX") && vms->heard[x] && !vms->deleted[x]) { 
 				/* Move to old folder before deleting */ 
@@ -5936,7 +5943,7 @@
  				ast_verbose(VERBOSE_PREFIX_3 "Saving message as is\n");
  				ast_streamfile(chan, "vm-msgsaved", chan->language);
  				ast_waitstream(chan, "");
-				STORE(recordfile, -1);
+				STORE(recordfile, vmu->mailbox, vmu->context, -1);
 				DISPOSE(recordfile, -1);
  				cmd = 't';
  				return res;
Index: doc/README.odbcstorage
===================================================================
RCS file: /usr/cvsroot/asterisk/doc/README.odbcstorage,v
retrieving revision 1.1
diff -u -r1.1 README.odbcstorage
--- doc/README.odbcstorage	7 Jan 2005 06:19:37 -0000	1.1
+++ doc/README.odbcstorage	30 May 2005 19:29:36 -0000
@@ -6,18 +6,20 @@
 *only* supports ODBC.  The table description for the "voicemessages" 
 table is as follows:
 
-+--------------+-------------+------+-----+---------+-------+
-| Field        | Type        | Null | Key | Default | Extra |
-+--------------+-------------+------+-----+---------+-------+
-| msgnum       | int(11)     | YES  |     | NULL    |       |
-| dir          | varchar(80) | YES  | MUL | NULL    |       |
-| context      | varchar(80) | YES  |     | NULL    |       |
-| macrocontext | varchar(80) | YES  |     | NULL    |       |
-| callerid     | varchar(40) | YES  |     | NULL    |       |
-| origtime     | varchar(40) | YES  |     | NULL    |       |
-| duration     | varchar(20) | YES  |     | NULL    |       |
-| recording    | longblob    | YES  |     | NULL    |       |
-+--------------+-------------+------+-----+---------+-------+
++----------------+-------------+------+-----+---------+-------+
+| Field          | Type        | Null | Key | Default | Extra |
++----------------+-------------+------+-----+---------+-------+
+| msgnum         | int(11)     | YES  |     | NULL    |       |
+| dir            | varchar(80) | YES  | MUL | NULL    |       |
+| context        | varchar(80) | YES  |     | NULL    |       |
+| macrocontext   | varchar(80) | YES  |     | NULL    |       |
+| callerid       | varchar(40) | YES  |     | NULL    |       |
+| origtime       | varchar(40) | YES  |     | NULL    |       |
+| duration       | varchar(20) | YES  |     | NULL    |       |
+| mailboxuser    | varchar(80) | YES  |     | NULL    |       |
+| mailboxcontext | varchar(80) | YES  |     | NULL    |       |
+| recording      | longblob    | YES  |     | NULL    |       |
++----------------+-------------+------+-----+---------+-------+
 
 The database name (from /etc/asterisk/res_odbc.conf) is in the 
 "odbcstorage" variable in the general section.
