[Asterisk-code-review] app voicemail: fix bugs, imap mm status log change to debug (asterisk[master])

Matthew Fredrickson asteriskteam at digium.com
Thu May 26 16:13:34 CDT 2016


Matthew Fredrickson has uploaded a new change for review.

  https://gerrit.asterisk.org/2911

Change subject: app_voicemail: fix bugs, imap mm_status log change to debug
......................................................................

app_voicemail: fix bugs, imap mm_status log change to debug

Fixed some bugs:
- create dirpath when save downloading message from IMAP storage.
- create IMAP folder if not exists when saving to IMAP storage
- check if file successfully opened before write to it
- some IMAP checks
- remove non-standard flag 'Unseen'
etc

Change to debug IMAP mm_status log instead of verbose.

Remove unused X-Asterisk-VM-Caller-channel message header
for security reason. The clients should not know name of peer/endpoint.

ASTERISK-26045 #close

Change-Id: I7f83d88b69b36934e2539c114b9fb612deed971b
---
M apps/app_voicemail.c
1 file changed, 160 insertions(+), 66 deletions(-)


  git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/11/2911/1

diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c
index e7de8a2..1d5b2dc 100644
--- a/apps/app_voicemail.c
+++ b/apps/app_voicemail.c
@@ -1088,7 +1088,7 @@
 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,
 			char *fmt, int outsidecaller, struct ast_vm_user *vmu, int *duration, int *sound_duration, const char *unlockdir,
-			signed char record_gain, struct vm_state *vms, char *flag, const char *msg_id);
+			signed char record_gain, struct vm_state *vms, char *flag, const char *msg_id, int forwardintro);
 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, struct vm_state *vms, int msgnum, long duration, char *fmt, char *cidnum, char *cidname, const char *flag);
@@ -2174,6 +2174,7 @@
 {
 	struct vm_state *vms_p;
 	char *file, *filename;
+	char dest[PATH_MAX];
 	char *attachment;
 	int i;
 	BODY *body;
@@ -2237,6 +2238,7 @@
 		if (!strcmp(filename, file)) {
 			ast_copy_string(vms_p->fn, dir, sizeof(vms_p->fn));
 			vms_p->msgArray[vms_p->curmsg] = i + 1;
+			create_dirpath(dest, sizeof(dest), vmu->context, vms_p->username, "");
 			save_body(body, vms_p, "2", attachment, 0);
 			ret = 0;
 			break;
@@ -2369,7 +2371,8 @@
 	snprintf(text_file, sizeof(text_file), "%s.%s", vms->fn, "txt");
 
 	if (!(text_file_ptr = fopen(text_file, "w"))) {
-		ast_log(LOG_WARNING, "Unable to open/create file %s: %s\n", text_file, strerror(errno));
+		ast_log(LOG_ERROR, "Unable to open/create file %s: %s\n", text_file, strerror(errno));
+		goto exit;
 	}
 
 	fprintf(text_file_ptr, "%s\n", "[message]");
@@ -2709,8 +2712,8 @@
 	}
 
 	make_email_file(p, myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, "INBOX",
-		S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL),
-		S_COR(ast_channel_caller(chan)->id.name.valid, ast_channel_caller(chan)->id.name.str, NULL),
+		chan ? S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL) : NULL,
+		chan ? S_COR(ast_channel_caller(chan)->id.name.valid, ast_channel_caller(chan)->id.name.str, NULL) : NULL,
 		fn, introfn, fmt, duration, 1, chan, NULL, 1, flag, msg_id);
 	/* read mail file to memory */
 	len = ftell(p);
@@ -3018,6 +3021,10 @@
 	ast_mutex_lock(&vms->lock);
 	ast_mutex_lock(&mail_open_lock);
 	vms->mailstream = mail_open (stream, tmp, debug ? OP_DEBUG : NIL);
+	/* Create the folder if it dosn't exist */
+	if (vms->mailstream && !mail_status(vms->mailstream, tmp, SA_UIDNEXT)) {
+		mail_create(vms->mailstream, tmp);
+	}
 	ast_mutex_unlock(&mail_open_lock);
 	ast_mutex_unlock(&vms->lock);
 	if (vms->mailstream == NIL) {
@@ -3112,7 +3119,15 @@
 {
 	FILE *output;
 
-	output = fopen (filename, "w");
+	if (!filename || !buffer) {
+		return;
+	}
+
+	if (!(output = fopen(filename, "w"))) {
+		ast_log(LOG_ERROR, "Unable to open/create file %s: %s\n", filename, strerror(errno));
+		return;
+	}
+
 	if (fwrite(buffer, len, 1, output) != 1) {
 		if (ferror(output)) {
 			ast_log(LOG_ERROR, "Short write while writing e-mail body: %s.\n", strerror(errno));
@@ -3247,18 +3262,30 @@
 
 void mm_status(MAILSTREAM * stream, char *mailbox, MAILSTATUS * status)
 {
-	ast_log(AST_LOG_NOTICE, " Mailbox %s", mailbox);
-	if (status->flags & SA_MESSAGES)
-		ast_log(AST_LOG_NOTICE, ", %lu messages", status->messages);
-	if (status->flags & SA_RECENT)
-		ast_log(AST_LOG_NOTICE, ", %lu recent", status->recent);
-	if (status->flags & SA_UNSEEN)
-		ast_log(AST_LOG_NOTICE, ", %lu unseen", status->unseen);
-	if (status->flags & SA_UIDVALIDITY)
-		ast_log(AST_LOG_NOTICE, ", %lu UID validity", status->uidvalidity);
-	if (status->flags & SA_UIDNEXT)
-		ast_log(AST_LOG_NOTICE, ", %lu next UID", status->uidnext);
-	ast_log(AST_LOG_NOTICE, "\n");
+	struct ast_str *str;
+	if (!DEBUG_ATLEAST(5) || !(str = ast_str_create(MAX_OBJECT_FIELD))) {
+	    return;
+	}
+
+	ast_str_append(&str, 0, " Mailbox %s", mailbox);
+	if (status->flags & SA_MESSAGES) {
+		ast_str_append(&str, 0, ", %lu messages", status->messages);
+	}
+	if (status->flags & SA_RECENT) {
+		ast_str_append(&str, 0, ", %lu recent", status->recent);
+	}
+	if (status->flags & SA_UNSEEN) {
+		ast_str_append(&str, 0, ", %lu unseen", status->unseen);
+	}
+	if (status->flags & SA_UIDVALIDITY) {
+		ast_str_append(&str, 0, ", %lu UID validity", status->uidvalidity);
+	}
+	if (status->flags & SA_UIDNEXT) {
+		ast_str_append(&str, 0, ", %lu next UID", status->uidnext);
+	}
+	ast_log(LOG_DEBUG, "%s\n", ast_str_buffer(str));
+
+	ast_free(str);
 }
 
 
@@ -3446,8 +3473,9 @@
 	if (interactive) {
 		struct vm_state *vms;
 		pthread_once(&ts_vmstate.once, ts_vmstate.key_init);
-		vms = pthread_getspecific(ts_vmstate.key);
-		return vms;
+		if ((vms = pthread_getspecific(ts_vmstate.key)) && vms->imapuser && !strcmp(vms->imapuser, user)) {
+			return vms;
+		}
 	}
 
 	AST_LIST_LOCK(&vmstates);
@@ -3485,8 +3513,10 @@
 	if (interactive) {
 		struct vm_state *vms;
 		pthread_once(&ts_vmstate.once, ts_vmstate.key_init);
-		vms = pthread_getspecific(ts_vmstate.key);
-		return vms;
+		if ((vms = pthread_getspecific(ts_vmstate.key)) && vms->username && vms->context &&
+		    !strcmp(vms->username,mailbox) && !strcmp(vms->context, local_context)) {
+			return vms;
+		}
 	}
 
 	AST_LIST_LOCK(&vmstates);
@@ -5133,7 +5163,9 @@
 		first_line = 0;
 	}
 
-	if (!ast_strlen_zero(emailsubject) || !ast_strlen_zero(vmu->emailsubject)) {
+	if (msgnum <= -1) {
+		fprintf(p, "Subject: New greeting '%s' on %s." ENDL, greeting_attachment, date);
+	} else if (!ast_strlen_zero(emailsubject) || !ast_strlen_zero(vmu->emailsubject)) {
 		char *e_subj = !ast_strlen_zero(vmu->emailsubject) ? vmu->emailsubject : emailsubject;
 		struct ast_channel *ast;
 		if ((ast = ast_dummy_channel_alloc())) {
@@ -5186,9 +5218,8 @@
 		fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, mailbox);
 #endif
 		/* flag added for Urgent */
-		fprintf(p, "X-Asterisk-VM-Flag: %s" ENDL, flag);
+		fprintf(p, "X-Asterisk-VM-Flag: %s" ENDL, S_OR(flag, ""));
 		fprintf(p, "X-Asterisk-VM-Priority: %d" ENDL, chan ? ast_channel_priority(chan) : 0);
-		fprintf(p, "X-Asterisk-VM-Caller-channel: %s" ENDL, chan ? ast_channel_name(chan) : "");
 		fprintf(p, "X-Asterisk-VM-Caller-ID-Num: %s" ENDL, enc_cidnum);
 		fprintf(p, "X-Asterisk-VM-Caller-ID-Name: %s" ENDL, enc_cidname);
 		fprintf(p, "X-Asterisk-VM-Duration: %d" ENDL, duration);
@@ -5219,7 +5250,11 @@
 		fprintf(p, "--%s" ENDL, bound);
 	}
 	fprintf(p, "Content-Type: text/plain; charset=%s" ENDL "Content-Transfer-Encoding: 8bit" ENDL ENDL, charset);
-	if (emailbody || vmu->emailbody) {
+	if (msgnum <= -1) {
+		fprintf(p, "This message is to let you know that your greeting '%s' was changed on %s." ENDL
+				"Please do not delete this message, lest your greeting vanish with it." ENDL ENDL,
+				greeting_attachment, date);
+	} else if (emailbody || vmu->emailbody) {
 		char* e_body = vmu->emailbody ? vmu->emailbody : emailbody;
 		struct ast_channel *ast;
 		if ((ast = ast_dummy_channel_alloc())) {
@@ -5245,7 +5280,7 @@
 		} else {
 			ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
 		}
-	} else if (msgnum > -1) {
+	} else {
 		if (strcmp(vmu->mailbox, mailbox)) {
 			/* Forwarded type */
 			struct ast_config *msg_cfg;
@@ -5290,9 +5325,6 @@
 				ENDL ENDL, vmu->fullname, dur, msgnum + 1, mailbox,
 				(cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), date);
 		}
-	} else {
-		fprintf(p, "This message is to let you know that your greeting was changed on %s." ENDL
-				"Please do not delete this message, lest your greeting vanish with it." ENDL ENDL, date);
 	}
 
 	if (imap || attach_user_voicemail) {
@@ -6851,7 +6883,7 @@
 			res = ast_streamfile(chan, "vm-mailboxfull", ast_channel_language(chan));
 			goto leave_vm_out;
 		}
-		res = play_record_review(chan, NULL, tmptxtfile, vmu->maxsecs, fmt, 1, vmu, &duration, &sound_duration, NULL, options->record_gain, vms, flag, msg_id);
+		res = play_record_review(chan, NULL, tmptxtfile, vmu->maxsecs, fmt, 1, vmu, &duration, &sound_duration, NULL, options->record_gain, vms, flag, msg_id, 0);
 
 		if (txt) {
 			fprintf(txt, "flag=%s\n", flag);
@@ -7055,6 +7087,7 @@
 	char sequence[10];
 	char mailbox[256];
 	int res;
+	int curr_mbox;
 
 	/* get the real IMAP message number for this message */
 	snprintf(sequence, sizeof(sequence), "%ld", vms->msgArray[msg]);
@@ -7064,26 +7097,35 @@
 	/* if save to Old folder, put in INBOX as read */
 	if (box == OLD_FOLDER) {
 		mail_setflag(vms->mailstream, sequence, "\\Seen");
-		mail_clearflag(vms->mailstream, sequence, "\\Unseen");
 	} else if (box == NEW_FOLDER) {
-		mail_setflag(vms->mailstream, sequence, "\\Unseen");
 		mail_clearflag(vms->mailstream, sequence, "\\Seen");
 	}
 	if (!strcasecmp(mbox(vmu, NEW_FOLDER), vms->curbox) && (box == NEW_FOLDER || box == OLD_FOLDER)) {
 		ast_mutex_unlock(&vms->lock);
 		return 0;
 	}
-	/* Create the folder if it don't exist */
+
+	/* get the current mailbox so that we can point the mailstream back to it later */
+	curr_mbox = get_folder_by_name(vms->curbox);
+
+	/* Create the folder if it dosn't exist */
 	imap_mailbox_name(mailbox, sizeof(mailbox), vms, box, 1); /* Get the full mailbox name */
-	ast_debug(5, "Checking if folder exists: %s\n", mailbox);
-	if (mail_create(vms->mailstream, mailbox) == NIL)
-		ast_debug(5, "Folder exists.\n");
-	else
-		ast_log(AST_LOG_NOTICE, "Folder %s created!\n", mbox(vmu, box));
-	if (move) {
-		res = !mail_move(vms->mailstream, sequence, (char *) mbox(vmu, box));
+	if (vms->mailstream && !mail_status(vms->mailstream, mailbox, SA_UIDNEXT)) {
+    		if (mail_create(vms->mailstream, mailbox) != NIL) {
+			ast_log(AST_LOG_NOTICE, "Folder %s created!\n", mbox(vmu, box));
+		}
+	}
+
+	/* restore previous mbox stream */
+	if (init_mailstream(vms, curr_mbox) || !vms->mailstream) {
+		ast_log(AST_LOG_ERROR, "IMAP mailstream is NULL or can't init_mailstream\n");
+		res = -1;
 	} else {
-		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;
@@ -7814,9 +7856,9 @@
 			}
 			make_file(vms->introfn, sizeof(vms->introfn), curdir, curmsg);
 			strncat(vms->introfn, "intro", sizeof(vms->introfn));
-			ast_play_and_wait(chan, INTRO);
+			ast_play_and_wait(chan, "vm-record-prepend");
 			ast_play_and_wait(chan, "beep");
-			cmd = play_record_review(chan, NULL, vms->introfn, vmu->maxsecs, vm_fmts, 1, vmu, (int *) duration, NULL, NULL, record_gain, vms, flag, msg_id);
+			cmd = play_record_review(chan, NULL, vms->introfn, vmu->maxsecs, vm_fmts, 1, vmu, (int *) duration, NULL, NULL, record_gain, vms, flag, msg_id, 1);
 			if (cmd == -1) {
 				break;
 			}
@@ -8085,6 +8127,7 @@
 	AST_LIST_HEAD_NOLOCK_STATIC(extensions, ast_vm_user);
 	char *stringp;
 	const char *s;
+	const char mailbox_context[256];
 	int saved_messages = 0;
 	int valid_extensions = 0;
 	char *dir;
@@ -8193,20 +8236,44 @@
 		/* start optimistic */
 		valid_extensions = 1;
 		while (s) {
+			snprintf((char*)mailbox_context, sizeof(mailbox_context), "%s@%s", s, context ? context : "default");
 			if ((is_new_message == 1 || strcmp(s, sender->mailbox)) && (receiver = find_user(NULL, context, s))) {
 				int oldmsgs;
 				int newmsgs;
 				int capacity;
-				if (inboxcount(s, &newmsgs, &oldmsgs)) {
-					ast_log(LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", s);
+
+				if (inboxcount(mailbox_context, &newmsgs, &oldmsgs)) {
+					ast_log(LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", mailbox_context);
 					/* Shouldn't happen, but allow trying another extension if it does */
 					res = ast_play_and_wait(chan, "pbx-invalid");
 					valid_extensions = 0;
 					break;
 				}
+#ifdef IMAP_STORAGE
+				if (!(dstvms = get_vm_state_by_mailbox(s, context, 0))) {
+					if (!(dstvms = create_vm_state_from_user(receiver))) {
+						ast_log(AST_LOG_ERROR, "Couldn't allocate necessary space\n");
+						/* Shouldn't happen, but allow trying another extension if it does */
+						res = ast_play_and_wait(chan, "pbx-invalid");
+						valid_extensions = 0;
+						break;
+					}
+				}
+				check_quota(dstvms, imapfolder);
+				if (dstvms->quota_limit && dstvms->quota_usage >= dstvms->quota_limit) {
+					ast_log(LOG_NOTICE, "Mailbox '%s' is exceeded quota %u >= %u\n", mailbox_context, dstvms->quota_usage, dstvms->quota_limit);
+					res = ast_play_and_wait(chan, "vm-mailboxfull");
+					valid_extensions = 0;
+					while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list))) {
+						inprocess_count(vmtmp->mailbox, vmtmp->context, -1);
+						free_user(vmtmp);
+					}
+					break;
+				}
+#endif
 				capacity = receiver->maxmsg - inprocess_count(receiver->mailbox, receiver->context, +1);
 				if ((newmsgs + oldmsgs) >= capacity) {
-					ast_log(LOG_NOTICE, "Mailbox '%s' is full with capacity of %d, prompting for another extension.\n", s, capacity);
+					ast_log(LOG_NOTICE, "Mailbox '%s' is full with capacity of %d, prompting for another extension.\n", mailbox_context, capacity);
 					res = ast_play_and_wait(chan, "vm-mailboxfull");
 					valid_extensions = 0;
 					while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list))) {
@@ -8226,7 +8293,7 @@
 				while ((receiver = AST_LIST_REMOVE_HEAD(&extensions, list))) {
 					free_user(receiver);
 				}
-				ast_log(LOG_NOTICE, "'%s' is not a valid mailbox\n", s);
+				ast_log(LOG_NOTICE, "'%s' is not a valid mailbox\n", mailbox_context);
 				/* "I am sorry, that's not a valid extension.  Please try again." */
 				res = ast_play_and_wait(chan, "pbx-invalid");
 				valid_extensions = 0;
@@ -8306,7 +8373,7 @@
 					if (!dstvms->mailstream) {
 						ast_log(AST_LOG_ERROR, "IMAP mailstream for %s is NULL\n", vmtmp->mailbox);
 					} else {
-						copy_msg_result = STORE(vmstmp.curdir, vmtmp->mailbox, vmtmp->context, dstvms->curmsg, chan, vmtmp, fmt, duration, dstvms, urgent_str, msg_id);
+						copy_msg_result = STORE(vmstmp.curdir, vmtmp->mailbox, vmtmp->context, curmsg, chan, vmtmp, fmt, duration, dstvms, urgent_str, msg_id);
 						run_externnotify(vmtmp->context, vmtmp->mailbox, urgent_str); 
 					}
 				} else {
@@ -8342,10 +8409,6 @@
 					res = ast_play_and_wait(chan, "vm-messages");
 				if (!res)
 					res = ast_play_and_wait(chan, "vm-saved"); */
-#ifdef IMAP_STORAGE
-				/* If forwarded with intro, DON'T PLAY THIS MESSAGE AGAIN! */
-				if (ast_strlen_zero(vmstmp.introfn))
-#endif
 				res = ast_play_and_wait(chan, "vm-msgforwarded");
 			}
 #ifndef IMAP_STORAGE
@@ -8814,6 +8877,7 @@
 	char arg[10];
 	int i;
 	BODY* body;
+	int curr_mbox;
 
 	file = strrchr(ast_strdupa(dir), '/');
 	if (file) {
@@ -8824,6 +8888,16 @@
 	}
 
 	ast_mutex_lock(&vms->lock);
+
+	/* get the current mailbox so that we can point the mailstream back to it later */
+	curr_mbox = get_folder_by_name(vms->curbox);
+
+	if (init_mailstream(vms, GREETINGS_FOLDER) || !vms->mailstream) {
+		ast_log(AST_LOG_ERROR, "IMAP mailstream is NULL or can't init_mailstream\n");
+		ast_mutex_unlock(&vms->lock);
+		return -1;
+	}
+
 	for (i = 0; i < vms->mailstream->nmsgs; i++) {
 		mail_fetchstructure(vms->mailstream, i + 1, &body);
 		/* We have the body, now we extract the file name of the first attachment. */
@@ -8841,6 +8915,14 @@
 		}
 	}
 	mail_expunge(vms->mailstream);
+
+	if (curr_mbox != -1) {
+		/* restore previous mbox stream */
+		if (init_mailstream(vms, curr_mbox) || !vms->mailstream) {
+			ast_log(AST_LOG_ERROR, "IMAP mailstream is NULL or can't init_mailstream\n");
+		}
+	}
+
 	ast_mutex_unlock(&vms->lock);
 	return 0;
 }
@@ -10348,7 +10430,7 @@
 	if (ast_test_flag(vmu, VM_FORCENAME)) {
 		snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username);
 		if (ast_fileexists(prefile, NULL, NULL) < 1) {
-			cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL, NULL);
+			cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL, NULL, 0);
 			if (cmd < 0 || cmd == 't' || cmd == '#')
 				return cmd;
 		}
@@ -10358,14 +10440,14 @@
 	if (ast_test_flag(vmu, VM_FORCEGREET)) {
 		snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username);
 		if (ast_fileexists(prefile, NULL, NULL) < 1) {
-			cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL, NULL);
+			cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL, NULL, 0);
 			if (cmd < 0 || cmd == 't' || cmd == '#')
 				return cmd;
 		}
 
 		snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username);
 		if (ast_fileexists(prefile, NULL, NULL) < 1) {
-			cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL, NULL);
+			cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL, NULL, 0);
 			if (cmd < 0 || cmd == 't' || cmd == '#')
 				return cmd;
 		}
@@ -10447,15 +10529,15 @@
 		switch (cmd) {
 		case '1': /* Record your unavailable message */
 			snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username);
-			cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL, NULL);
+			cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL, NULL, 0);
 			break;
 		case '2':  /* Record your busy message */
 			snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username);
-			cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL, NULL);
+			cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL, NULL, 0);
 			break;
 		case '3': /* Record greeting */
 			snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username);
-			cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL, NULL);
+			cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL, NULL, 0);
 			break;
 		case '4':  /* manage the temporary greeting */
 			cmd = vm_tempgreeting(chan, vmu, vms, fmtc, record_gain);
@@ -10589,7 +10671,7 @@
 			retries = 0;
 		RETRIEVE(prefile, -1, vmu->mailbox, vmu->context);
 		if (ast_fileexists(prefile, NULL, NULL) <= 0) {
-			cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL, NULL);
+			cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL, NULL, 0);
 			if (cmd == -1) {
 				break;
 			}
@@ -10597,7 +10679,7 @@
 		} else {
 			switch (cmd) {
 			case '1':
-				cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL, NULL);
+				cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL, NULL, 0);
 				break;
 			case '2':
 				DELETE(prefile, -1, prefile, vmu);
@@ -11876,7 +11958,13 @@
 			cmd = vm_options(chan, vmu, &vms, vmfmts, record_gain);
 			if (useadsi)
 				adsi_status(chan, &vms);
-			break;
+			/* Reopen play_folder */
+			res = open_mailbox(&vms, vmu, play_folder);
+			if (res < 0) {
+				goto out;
+			}
+			vms.starting = 1;
+ 			break;
 		default:	/* Nothing */
 			ast_test_suite_event_notify("PLAYBACK", "Message: instructions");
 			cmd = vm_instructions(chan, vmu, &vms, 0, in_urgent);
@@ -15109,7 +15197,7 @@
 
 static int play_record_review(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt,
 			int outsidecaller, struct ast_vm_user *vmu, int *duration, int *sound_duration, const char *unlockdir,
-			signed char record_gain, struct vm_state *vms, char *flag, const char *msg_id)
+			signed char record_gain, struct vm_state *vms, char *flag, const char *msg_id, int forwardintro)
 {
 	/* Record message & let caller review or re-record it, or set options if applicable */
 	int res = 0;
@@ -15151,7 +15239,9 @@
 				ast_verb(3, "Saving message as is\n");
 				if (!outsidecaller) 
 					ast_filerename(tempfile, recordfile, NULL);
-				ast_stream_and_wait(chan, "vm-msgsaved", "");
+				if (!forwardintro) {
+					ast_stream_and_wait(chan, "vm-msgsaved", "");
+				}
 				if (!outsidecaller) {
 					/* Saves to IMAP server only if imapgreeting=yes */
 					STORE(recordfile, vmu->mailbox, vmu->context, -1, chan, vmu, fmt, *duration, vms, flag, msg_id);
@@ -15174,7 +15264,11 @@
 				ast_verb(3, "Recording the message\n");
 			
 			if (recorded && outsidecaller) {
-				cmd = ast_play_and_wait(chan, INTRO);
+				if (forwardintro) {
+					cmd = ast_play_and_wait(chan, "vm-record-prepend");
+				} else {
+					cmd = ast_play_and_wait(chan, INTRO);
+				}
 				cmd = ast_play_and_wait(chan, "beep");
 			}
 			recorded = 1;
@@ -15295,10 +15389,10 @@
 			}
 			return cmd;
 		default:
-			/* If the caller is an ouside caller, and the review option is enabled,
+			/* If the caller is an ouside caller and the review option is enabled or it's forward intro
 			   allow them to review the message, but let the owner of the box review
 			   their OGM's */
-			if (outsidecaller && !ast_test_flag(vmu, VM_REVIEW))
+			if (outsidecaller && !ast_test_flag(vmu, VM_REVIEW) && !forwardintro)
 				return cmd;
 			if (msg_exists) {
 				cmd = ast_play_and_wait(chan, "vm-review");

-- 
To view, visit https://gerrit.asterisk.org/2911
To unsubscribe, visit https://gerrit.asterisk.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I7f83d88b69b36934e2539c114b9fb612deed971b
Gerrit-PatchSet: 1
Gerrit-Project: asterisk
Gerrit-Branch: master
Gerrit-Owner: Matthew Fredrickson <creslin at digium.com>
Gerrit-Reviewer: Alexei Gradinari <alex2grad at gmail.com>



More information about the asterisk-code-review mailing list