[asterisk-commits] mmichelson: branch mmichelson/trunk-digiumphones r367415 - /team/mmichelson/t...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed May 23 15:18:49 CDT 2012


Author: mmichelson
Date: Wed May 23 15:18:45 2012
New Revision: 367415

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=367415
Log:
Add new message-ID-having message to proper IMAP folder.

IMAP has the drawback, at the moment anyway, that new
messages are created and automatically saved in the INBOX instead
of using the directory name to try to determine the folder. So what
has to be done instead is to save the message, then move it to
the appropriate folder.

I adjusted save_to_folder() to have a new parameter that indicates
whether the message should be copied or moved. I also added
documentation to indicate that this final parameter is only
observed when using IMAP voicemail.


Modified:
    team/mmichelson/trunk-digiumphones/apps/app_voicemail.c

Modified: team/mmichelson/trunk-digiumphones/apps/app_voicemail.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/trunk-digiumphones/apps/app_voicemail.c?view=diff&rev=367415&r1=367414&r2=367415
==============================================================================
--- team/mmichelson/trunk-digiumphones/apps/app_voicemail.c (original)
+++ team/mmichelson/trunk-digiumphones/apps/app_voicemail.c Wed May 23 15:18:45 2012
@@ -496,7 +496,7 @@
 static void mm_parsequota (MAILSTREAM *stream, unsigned char *msg, QUOTALIST *pquota);
 static void imap_mailbox_name(char *spec, size_t len, struct vm_state *vms, int box, int target);
 static int imap_store_file(const char *dir, const char *mailboxuser, const char *mailboxcontext, int msgnum, struct ast_channel *chan, struct ast_vm_user *vmu, char *fmt, int duration, struct vm_state *vms, const char *flag, const char *msg_id);
-static void vm_imap_update_msg_id(char *dir, int msgnum, const char *msg_id, struct ast_vm_user *vmu, struct ast_config *msg_cfg);
+static void vm_imap_update_msg_id(char *dir, int msgnum, const char *msg_id, struct ast_vm_user *vmu, struct ast_config *msg_cfg, int folder);
 static void update_messages_by_imapuser(const char *user, unsigned long number);
 static int vm_delete(char *file);
 
@@ -843,7 +843,7 @@
 #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,d) (delete_file(a,b))
-#define UPDATE_MSG_ID(a, b, c, d, e) (odbc_update_msg_id((a), (b), (c)))
+#define UPDATE_MSG_ID(a, b, c, d, e, f) (odbc_update_msg_id((a), (b), (c)))
 #else
 #ifdef IMAP_STORAGE
 #define DISPOSE(a,b) (imap_remove_file(a,b))
@@ -853,7 +853,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,d) (vm_imap_delete(a,b,d))
-#define UPDATE_MSG_ID(a, b, c, d, e) (vm_imap_update_msg_id((a), (b), (c), (d), (e)))
+#define UPDATE_MSG_ID(a, b, c, d, e, f) (vm_imap_update_msg_id((a), (b), (c), (d), (e), (f)))
 #else
 #define RETRIEVE(a,b,c,d)
 #define DISPOSE(a,b)
@@ -862,7 +862,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_plain_file(g,h)); 
 #define DELETE(a,b,c,d) (vm_delete(c))
-#define UPDATE_MSG_ID(a, b, c, d, e)
+#define UPDATE_MSG_ID(a, b, c, d, e, f)
 #endif
 #endif
 
@@ -1026,6 +1026,7 @@
 
 /* Forward declarations - generic */
 static int open_mailbox(struct vm_state *vms, struct ast_vm_user *vmu, int box);
+static int close_mailbox(struct vm_state *vms, struct ast_vm_user *vmu);
 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);
 static int dialout(struct ast_channel *chan, struct ast_vm_user *vmu, char *num, char *outgoing_context);
 static int play_record_review(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime,
@@ -1043,6 +1044,21 @@
 struct ast_str *vm_mailbox_snapshot_str(const char *mailbox, const char *context);
 static const char *substitute_escapes(const char *value);
 static int message_range_and_existence_check(struct vm_state *vms, const char *msg_ids [], size_t num_msgs, int *msg_nums, struct ast_vm_user *vmu);
+/*!
+ * Place a message in the indicated folder
+ *
+ * \param vmu Voicemail user
+ * \param vms Current voicemail state for the user
+ * \param msg The message number to save
+ * \param box The folder into which the message should be saved
+ * \param[out] newmsg The new message number of the saved message
+ * \param move Tells whether to copy or to move the message
+ *
+ * \note the "move" parameter is only honored for IMAP voicemail presently
+ * \retval 0 Success
+ * \revval other Failure
+ */
+static int save_to_folder(struct ast_vm_user *vmu, struct vm_state *vms, int msg, int box, int *newmsg, int move);
 
 struct ao2_container *inprocess_container;
 
@@ -1942,7 +1958,7 @@
 	ast_mutex_unlock(&vms->lock);
 }
 
-static void vm_imap_update_msg_id(char *dir, int msgnum, const char *msg_id, struct ast_vm_user *vmu, struct ast_config *msg_cfg)
+static void vm_imap_update_msg_id(char *dir, int msgnum, const char *msg_id, struct ast_vm_user *vmu, struct ast_config *msg_cfg, int folder)
 {
 	struct ast_channel *chan;
 	char *cid;
@@ -1952,17 +1968,29 @@
 	const char *duration_str;
 	int duration = 0;
 
+	/*
+	 * First, get things initially set up. If any of this fails, then
+	 * back out before doing anything substantial
+	 */
+	vms = get_vm_state_by_mailbox(vmu->mailbox, vmu->context, 0);
+	if (!vms) {
+		return;
+	}
+
+	if (open_mailbox(vms, vmu, folder)) {
+		return;
+	}
+
 	chan = ast_dummy_channel_alloc();
 	if (!chan) {
+		close_mailbox(vms, vmu);
 		return;
 	}
 
-	vms = get_vm_state_by_mailbox(vmu->mailbox, vmu->context, 0);
-	if (!vms) {
-		chan = ast_channel_unref(chan);
-		return;
-	}
-
+	/*
+	 * We need to make sure the new message we save has the same
+	 * callerid, flag, and duration as the original message
+	 */
 	cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid"));
 
 	if (!ast_strlen_zero(cid)) {
@@ -1984,10 +2012,20 @@
 		sscanf(duration_str, "%30d", &duration);
 	}
 
+	/*
+	 * IMAP messages cannot be altered once delivered. So we have to delete the
+	 * current message and then re-add it with the updated message ID.
+	 *
+	 * Furthermore, there currently is no atomic way to create a new message and to
+	 * store it in an arbitrary folder. So we have to save it to the INBOX and then
+	 * move to the appropriate folder.
+	 */
 	vm_imap_delete(dir, msgnum, vmu);
 	imap_store_file(dir, vmu->mailbox, vmu->context, msgnum, chan, vmu, vmfmts,
 			duration, vms, ast_variable_retrieve(msg_cfg, "message", "flag"), msg_id);
-
+	save_to_folder(vmu, vms, msgnum, folder, NULL, 1);
+
+	close_mailbox(vms, vmu);
 	ast_channel_unref(chan);
 }
 
@@ -6739,7 +6777,7 @@
 	return d;
 }
 
-static int save_to_folder(struct ast_vm_user *vmu, struct vm_state *vms, int msg, int box, int *newmsg)
+static int save_to_folder(struct ast_vm_user *vmu, struct vm_state *vms, int msg, int box, int *newmsg, int move)
 {
 #ifdef IMAP_STORAGE
 	/* we must use mbox(x) folder names, and copy the message there */
@@ -6772,7 +6810,11 @@
 		ast_debug(5, "Folder exists.\n");
 	else
 		ast_log(AST_LOG_NOTICE, "Folder %s created!\n", mbox(vmu, box));
-	res = !mail_copy(vms->mailstream, sequence, (char *) mbox(vmu, box));
+	if (move) {
+		res = !mail_move(vms->mailstream, sequence, (char *) mbox(vmu, box));
+	} else {
+		res = !mail_copy(vms->mailstream, sequence, (char *) mbox(vmu, box));
+	}
 	ast_mutex_unlock(&vms->lock);
 	return res;
 #else
@@ -8590,7 +8632,7 @@
 			}
 		} else if ((!strcasecmp(vms->curbox, "INBOX") || !strcasecmp(vms->curbox, "Urgent")) && vms->heard[x] && ast_test_flag(vmu, VM_MOVEHEARD) && !vms->deleted[x]) {
 			/* Move to old folder before deleting */
-			res = save_to_folder(vmu, vms, x, 1, NULL);
+			res = save_to_folder(vmu, vms, x, 1, NULL, 0);
 			if (res == ERROR_LOCK_PATH) {
 				/* If save failed do not delete the message */
 				ast_log(AST_LOG_WARNING, "Save failed.  Not moving message: %s.\n", res == ERROR_LOCK_PATH ? "unable to lock path" : "destination folder full");
@@ -8600,7 +8642,7 @@
 			}
 		} else if (vms->deleted[x] && vmu->maxdeletedmsg) {
 			/* Move to deleted folder */
-			res = save_to_folder(vmu, vms, x, 10, NULL);
+			res = save_to_folder(vmu, vms, x, 10, NULL, 0);
 			if (res == ERROR_LOCK_PATH) {
 				/* If save failed do not delete the message */
 				vms->deleted[x] = 0;
@@ -11212,7 +11254,7 @@
 				break;
 			} else if (cmd > 0) {
 				box = cmd = cmd - '0';
-				cmd = save_to_folder(vmu, &vms, vms.curmsg, cmd, NULL);
+				cmd = save_to_folder(vmu, &vms, vms.curmsg, cmd, NULL, 0);
 				if (cmd == ERROR_LOCK_PATH) {
 					res = cmd;
 					goto out;
@@ -11439,7 +11481,7 @@
 	snprintf(buf, size, "%08lx%08lx%08lx%08lx", val[0], val[1], val[2], val[3]);
 }
 
-static int add_message_id(struct ast_config *msg_cfg, char *dir, int msg, char *filename, char *id, size_t id_size, struct ast_vm_user *vmu)
+static int add_message_id(struct ast_config *msg_cfg, char *dir, int msg, char *filename, char *id, size_t id_size, struct ast_vm_user *vmu, int folder)
 {
 	struct ast_variable *var;
 	struct ast_category *cat;
@@ -11464,7 +11506,7 @@
 		return -1;
 	}
 
-	UPDATE_MSG_ID(dir, msg, id, vmu, msg_cfg);
+	UPDATE_MSG_ID(dir, msg, id, vmu, msg_cfg, folder);
 	return 0;
 }
 
@@ -14722,7 +14764,7 @@
 			 */
 			char id[33];
 			if (!(add_message_id(msg_cfg, vms->curdir, vms->curmsg,
-							filename, id, sizeof(id), vmu))) {
+							filename, id, sizeof(id), vmu, mailbox_index))) {
 				ast_string_field_set(msg_snapshot, msg_id, id);
 			} else {
 				ast_log(LOG_WARNING, "Unable to create a message ID for message %s/%d\n", vms->curdir, vms->curmsg);
@@ -15246,7 +15288,7 @@
 
 	/* Now actually move the message */
 	for (i = 0; i < num_msgs; ++i) {
-		if (save_to_folder(vmu, &vms, old_msg_nums[i], new_folder_index, NULL)) {
+		if (save_to_folder(vmu, &vms, old_msg_nums[i], new_folder_index, NULL, 0)) {
 			res = -1;
 			goto vm_move_cleanup;
 		}




More information about the asterisk-commits mailing list