diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c
index 49d30e0999..5436c87e23 100644
--- a/apps/app_voicemail.c
+++ b/apps/app_voicemail.c
@@ -219,6 +219,10 @@
Use the specified amount of gain when recording a voicemail message.
The units are whole-number decibels (dB).
+
@@ -592,6 +596,7 @@ enum vm_option_flags {
OPT_EARLYM_GREETING = (1 << 10),
OPT_BEEP = (1 << 11),
OPT_SILENT_IF_GREET = (1 << 12),
+ OPT_READONLY = (1 << 13),
};
enum vm_option_args {
@@ -621,7 +626,8 @@ AST_APP_OPTIONS(vm_app_options, {
AST_APP_OPTION('U', OPT_MESSAGE_Urgent),
AST_APP_OPTION('P', OPT_MESSAGE_PRIORITY),
AST_APP_OPTION('e', OPT_EARLYM_GREETING),
- AST_APP_OPTION_ARG('t', OPT_BEEP, OPT_ARG_BEEP_TONE)
+ AST_APP_OPTION_ARG('t', OPT_BEEP, OPT_ARG_BEEP_TONE),
+ AST_APP_OPTION('r', OPT_READONLY),
});
static const char * const mailbox_folders[] = {
@@ -10328,7 +10334,7 @@ static int vm_intro(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm
}
}
-static int vm_instructions_en(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent)
+static int vm_instructions_en(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent, int nodelete)
{
int res = 0;
/* Play instructions and wait for new command */
@@ -10388,10 +10394,12 @@ static int vm_instructions_en(struct ast_channel *chan, struct ast_vm_user *vmu,
#ifdef IMAP_STORAGE
ast_mutex_unlock(&vms->lock);
#endif
- if (!curmsg_deleted) {
- res = ast_play_and_wait(chan, "vm-delete");
- } else {
- res = ast_play_and_wait(chan, "vm-undelete");
+ if (!nodelete) {
+ if (!curmsg_deleted) {
+ res = ast_play_and_wait(chan, "vm-delete");
+ } else {
+ res = ast_play_and_wait(chan, "vm-undelete");
+ }
}
if (!res) {
res = ast_play_and_wait(chan, "vm-toforward");
@@ -10416,7 +10424,7 @@ static int vm_instructions_en(struct ast_channel *chan, struct ast_vm_user *vmu,
return res;
}
-static int vm_instructions_ja(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent)
+static int vm_instructions_ja(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent, int nodelete)
{
int res = 0;
/* Play instructions and wait for new command */
@@ -10512,7 +10520,7 @@ static int vm_instructions_ja(struct ast_channel *chan, struct ast_vm_user *vmu,
return res;
}
-static int vm_instructions_zh(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent)
+static int vm_instructions_zh(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent, int nodelete)
{
int res = 0;
/* Play instructions and wait for new command */
@@ -10530,20 +10538,20 @@ static int vm_instructions_zh(struct ast_channel *chan, struct ast_vm_user *vmu,
res = ast_play_and_wait(chan, "vm-opts");
if (!res) {
vms->starting = 0;
- return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent);
+ return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent, nodelete);
}
}
return res;
}
-static int vm_instructions(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent)
+static int vm_instructions(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent, int nodelete)
{
if (!strncasecmp(ast_channel_language(chan), "ja", 2)) { /* Japanese syntax */
- return vm_instructions_ja(chan, vmu, vms, skipadvanced, in_urgent);
+ return vm_instructions_ja(chan, vmu, vms, skipadvanced, in_urgent, nodelete);
} else if (vms->starting && !strncasecmp(ast_channel_language(chan), "zh", 2)) { /* CHINESE (Taiwan) syntax */
- return vm_instructions_zh(chan, vmu, vms, skipadvanced, in_urgent);
+ return vm_instructions_zh(chan, vmu, vms, skipadvanced, in_urgent, nodelete);
} else { /* Default to ENGLISH */
- return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent);
+ return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent, nodelete);
}
}
@@ -11426,6 +11434,7 @@ static int vm_execmain(struct ast_channel *chan, const char *data)
int play_auto = 0;
int play_folder = 0;
int in_urgent = 0;
+ int nodelete = 0;
#ifdef IMAP_STORAGE
int deleted = 0;
#endif
@@ -11488,6 +11497,9 @@ static int vm_execmain(struct ast_channel *chan, const char *data)
play_folder = 0;
}
}
+ if (ast_test_flag(&flags, OPT_READONLY)) {
+ nodelete = 1;
+ }
} else {
/* old style options parsing */
while (*(args.argv0)) {
@@ -11901,7 +11913,7 @@ static int vm_execmain(struct ast_channel *chan, const char *data)
}
break;
case '7': /* Delete the current message */
- if (vms.curmsg >= 0 && vms.curmsg <= vms.lastmsg) {
+ if (!nodelete && vms.curmsg >= 0 && vms.curmsg <= vms.lastmsg) {
vms.deleted[vms.curmsg] = !vms.deleted[vms.curmsg];
if (useadsi)
adsi_delete(chan, &vms);
@@ -12090,7 +12102,7 @@ static int vm_execmain(struct ast_channel *chan, const char *data)
if (!cmd)
cmd = ast_play_and_wait(chan, "vm-opts");
if (!cmd)
- cmd = vm_instructions(chan, vmu, &vms, 1, in_urgent);
+ cmd = vm_instructions(chan, vmu, &vms, 1, in_urgent, nodelete);
break;
}
cmd = ast_play_and_wait(chan, "vm-onefor");
@@ -12102,7 +12114,7 @@ static int vm_execmain(struct ast_channel *chan, const char *data)
if (!cmd)
cmd = ast_play_and_wait(chan, "vm-opts");
if (!cmd)
- cmd = vm_instructions(chan, vmu, &vms, 1, in_urgent);
+ cmd = vm_instructions(chan, vmu, &vms, 1, in_urgent, nodelete);
} else
cmd = 0;
break;
@@ -12119,7 +12131,7 @@ static int vm_execmain(struct ast_channel *chan, const char *data)
break;
default: /* Nothing */
ast_test_suite_event_notify("PLAYBACK", "Message: instructions");
- cmd = vm_instructions(chan, vmu, &vms, 0, in_urgent);
+ cmd = vm_instructions(chan, vmu, &vms, 0, in_urgent, nodelete);
break;
}
}
diff --git a/doc/CHANGES-staging/app_voicemail_nodelete.txt b/doc/CHANGES-staging/app_voicemail_nodelete.txt
new file mode 100644
index 0000000000..ef9589652d
--- /dev/null
+++ b/doc/CHANGES-staging/app_voicemail_nodelete.txt
@@ -0,0 +1,5 @@
+Subject: app_voicemail
+
+The r option has been added, which prevents deletion
+of messages from VoiceMailMain, which can be
+useful for shared mailboxes.