<p>Friendly Automation <strong>submitted</strong> this change.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/18661">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Joshua Colp: Looks good to me, but someone else must approve
  Kevin Harwell: Looks good to me, approved
  Friendly Automation: Approved for Submit

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">app_voicemail: Add option to prevent message deletion.<br><br>Adds an option to VoiceMailMain that prevents the user<br>from deleting messages during that application invocation.<br>This can be useful for public or shared mailboxes, where<br>some users should be able to listen to messages but not<br>delete them.<br><br>ASTERISK-30063 #close<br><br>Change-Id: Icdfb8423ae8d1fce65a056b603eb84a672e80a26<br>---<br>M apps/app_voicemail.c<br>A doc/CHANGES-staging/app_voicemail_nodelete.txt<br>2 files changed, 34 insertions(+), 17 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c</span><br><span>index 49d30e0..5436c87 100644</span><br><span>--- a/apps/app_voicemail.c</span><br><span>+++ b/apps/app_voicemail.c</span><br><span>@@ -219,6 +219,10 @@</span><br><span>                                               <para>Use the specified amount of gain when recording a voicemail message.</span><br><span>                                             The units are whole-number decibels (dB).</para></span><br><span>                                       </option></span><br><span style="color: hsl(120, 100%, 40%);">+                                       <option name="r"></span><br><span style="color: hsl(120, 100%, 40%);">+                                             <para>"Read only". Prevent user from deleting any messages.</para></span><br><span style="color: hsl(120, 100%, 40%);">+                                              <para>This applies only to specific executions of VoiceMailMain, NOT the mailbox itself.</para></span><br><span style="color: hsl(120, 100%, 40%);">+                                   </option></span><br><span>                                      <option name="s"></span><br><span>                                            <para>Skip checking the passcode for the mailbox.</para></span><br><span>                                         </option></span><br><span>@@ -592,6 +596,7 @@</span><br><span>        OPT_EARLYM_GREETING =  (1 << 10),</span><br><span>      OPT_BEEP =             (1 << 11),</span><br><span>      OPT_SILENT_IF_GREET =  (1 << 12),</span><br><span style="color: hsl(120, 100%, 40%);">+       OPT_READONLY =         (1 << 13),</span><br><span> };</span><br><span> </span><br><span> enum vm_option_args {</span><br><span>@@ -621,7 +626,8 @@</span><br><span>     AST_APP_OPTION('U', OPT_MESSAGE_Urgent),</span><br><span>     AST_APP_OPTION('P', OPT_MESSAGE_PRIORITY),</span><br><span>   AST_APP_OPTION('e', OPT_EARLYM_GREETING),</span><br><span style="color: hsl(0, 100%, 40%);">-       AST_APP_OPTION_ARG('t', OPT_BEEP, OPT_ARG_BEEP_TONE)</span><br><span style="color: hsl(120, 100%, 40%);">+  AST_APP_OPTION_ARG('t', OPT_BEEP, OPT_ARG_BEEP_TONE),</span><br><span style="color: hsl(120, 100%, 40%);">+ AST_APP_OPTION('r', OPT_READONLY),</span><br><span> });</span><br><span> </span><br><span> static const char * const mailbox_folders[] = {</span><br><span>@@ -10328,7 +10334,7 @@</span><br><span>   }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static int vm_instructions_en(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent)</span><br><span style="color: hsl(120, 100%, 40%);">+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)</span><br><span> {</span><br><span>        int res = 0;</span><br><span>         /* Play instructions and wait for new command */</span><br><span>@@ -10388,10 +10394,12 @@</span><br><span> #ifdef IMAP_STORAGE</span><br><span>                          ast_mutex_unlock(&vms->lock);</span><br><span> #endif</span><br><span style="color: hsl(0, 100%, 40%);">-                          if (!curmsg_deleted) {</span><br><span style="color: hsl(0, 100%, 40%);">-                                  res = ast_play_and_wait(chan, "vm-delete");</span><br><span style="color: hsl(0, 100%, 40%);">-                           } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                                        res = ast_play_and_wait(chan, "vm-undelete");</span><br><span style="color: hsl(120, 100%, 40%);">+                               if (!nodelete) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                      if (!curmsg_deleted) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                                res = ast_play_and_wait(chan, "vm-delete");</span><br><span style="color: hsl(120, 100%, 40%);">+                                 } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                                              res = ast_play_and_wait(chan, "vm-undelete");</span><br><span style="color: hsl(120, 100%, 40%);">+                                       }</span><br><span>                            }</span><br><span>                            if (!res) {</span><br><span>                                  res = ast_play_and_wait(chan, "vm-toforward");</span><br><span>@@ -10416,7 +10424,7 @@</span><br><span>   return res;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static int vm_instructions_ja(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms,  int skipadvanced, int in_urgent)</span><br><span style="color: hsl(120, 100%, 40%);">+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)</span><br><span> {</span><br><span>    int res = 0;</span><br><span>         /* Play instructions and wait for new command */</span><br><span>@@ -10512,7 +10520,7 @@</span><br><span>   return res;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static int vm_instructions_zh(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms,  int skipadvanced, int in_urgent)</span><br><span style="color: hsl(120, 100%, 40%);">+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)</span><br><span> {</span><br><span>    int res = 0;</span><br><span>         /* Play instructions and wait for new command */</span><br><span>@@ -10530,20 +10538,20 @@</span><br><span>                         res = ast_play_and_wait(chan, "vm-opts");</span><br><span>          if (!res) {</span><br><span>                  vms->starting = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-                   return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent);</span><br><span style="color: hsl(120, 100%, 40%);">+                   return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent, nodelete);</span><br><span>                }</span><br><span>    }</span><br><span>    return res;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static int vm_instructions(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent)</span><br><span style="color: hsl(120, 100%, 40%);">+static int vm_instructions(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent, int nodelete)</span><br><span> {</span><br><span>    if (!strncasecmp(ast_channel_language(chan), "ja", 2)) { /* Japanese syntax */</span><br><span style="color: hsl(0, 100%, 40%);">-                return vm_instructions_ja(chan, vmu, vms, skipadvanced, in_urgent);</span><br><span style="color: hsl(120, 100%, 40%);">+           return vm_instructions_ja(chan, vmu, vms, skipadvanced, in_urgent, nodelete);</span><br><span>        } else if (vms->starting && !strncasecmp(ast_channel_language(chan), "zh", 2)) { /* CHINESE (Taiwan) syntax */</span><br><span style="color: hsl(0, 100%, 40%);">-             return vm_instructions_zh(chan, vmu, vms, skipadvanced, in_urgent);</span><br><span style="color: hsl(120, 100%, 40%);">+           return vm_instructions_zh(chan, vmu, vms, skipadvanced, in_urgent, nodelete);</span><br><span>        } else {                                        /* Default to ENGLISH */</span><br><span style="color: hsl(0, 100%, 40%);">-                return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent);</span><br><span style="color: hsl(120, 100%, 40%);">+           return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent, nodelete);</span><br><span>        }</span><br><span> }</span><br><span> </span><br><span>@@ -11426,6 +11434,7 @@</span><br><span>         int play_auto = 0;</span><br><span>   int play_folder = 0;</span><br><span>         int in_urgent = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+    int nodelete = 0;</span><br><span> #ifdef IMAP_STORAGE</span><br><span>     int deleted = 0;</span><br><span> #endif</span><br><span>@@ -11488,6 +11497,9 @@</span><br><span>                                         play_folder = 0;</span><br><span>                             }</span><br><span>                    }</span><br><span style="color: hsl(120, 100%, 40%);">+                     if (ast_test_flag(&flags, OPT_READONLY)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                nodelete = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+                 }</span><br><span>            } else {</span><br><span>                     /* old style options parsing */</span><br><span>                      while (*(args.argv0)) {</span><br><span>@@ -11901,7 +11913,7 @@</span><br><span>                    }</span><br><span>                    break;</span><br><span>               case '7': /* Delete the current message */</span><br><span style="color: hsl(0, 100%, 40%);">-                      if (vms.curmsg >= 0 && vms.curmsg <= vms.lastmsg) {</span><br><span style="color: hsl(120, 100%, 40%);">+                     if (!nodelete && vms.curmsg >= 0 && vms.curmsg <= vms.lastmsg) {</span><br><span>                               vms.deleted[vms.curmsg] = !vms.deleted[vms.curmsg];</span><br><span>                          if (useadsi)</span><br><span>                                         adsi_delete(chan, &vms);</span><br><span>@@ -12090,7 +12102,7 @@</span><br><span>                                       if (!cmd)</span><br><span>                                            cmd = ast_play_and_wait(chan, "vm-opts");</span><br><span>                                  if (!cmd)</span><br><span style="color: hsl(0, 100%, 40%);">-                                               cmd = vm_instructions(chan, vmu, &vms, 1, in_urgent);</span><br><span style="color: hsl(120, 100%, 40%);">+                                             cmd = vm_instructions(chan, vmu, &vms, 1, in_urgent, nodelete);</span><br><span>                                  break;</span><br><span>                               }</span><br><span>                            cmd = ast_play_and_wait(chan, "vm-onefor");</span><br><span>@@ -12102,7 +12114,7 @@</span><br><span>                              if (!cmd)</span><br><span>                                    cmd = ast_play_and_wait(chan, "vm-opts");</span><br><span>                          if (!cmd)</span><br><span style="color: hsl(0, 100%, 40%);">-                                       cmd = vm_instructions(chan, vmu, &vms, 1, in_urgent);</span><br><span style="color: hsl(120, 100%, 40%);">+                                     cmd = vm_instructions(chan, vmu, &vms, 1, in_urgent, nodelete);</span><br><span>                  } else</span><br><span>                               cmd = 0;</span><br><span>                     break;</span><br><span>@@ -12119,7 +12131,7 @@</span><br><span>                     break;</span><br><span>               default:        /* Nothing */</span><br><span>                        ast_test_suite_event_notify("PLAYBACK", "Message: instructions");</span><br><span style="color: hsl(0, 100%, 40%);">-                   cmd = vm_instructions(chan, vmu, &vms, 0, in_urgent);</span><br><span style="color: hsl(120, 100%, 40%);">+                     cmd = vm_instructions(chan, vmu, &vms, 0, in_urgent, nodelete);</span><br><span>                  break;</span><br><span>               }</span><br><span>    }</span><br><span>diff --git a/doc/CHANGES-staging/app_voicemail_nodelete.txt b/doc/CHANGES-staging/app_voicemail_nodelete.txt</span><br><span>new file mode 100644</span><br><span>index 0000000..ef95896</span><br><span>--- /dev/null</span><br><span>+++ b/doc/CHANGES-staging/app_voicemail_nodelete.txt</span><br><span>@@ -0,0 +1,5 @@</span><br><span style="color: hsl(120, 100%, 40%);">+Subject: app_voicemail</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+The r option has been added, which prevents deletion</span><br><span style="color: hsl(120, 100%, 40%);">+of messages from VoiceMailMain, which can be</span><br><span style="color: hsl(120, 100%, 40%);">+useful for shared mailboxes.</span><br><span></span><br></pre><div style="white-space:pre-wrap"></div><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/18661">change 18661</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/c/asterisk/+/18661"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 19 </div>
<div style="display:none"> Gerrit-Change-Id: Icdfb8423ae8d1fce65a056b603eb84a672e80a26 </div>
<div style="display:none"> Gerrit-Change-Number: 18661 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: N A <mail@interlinked.x10host.com> </div>
<div style="display:none"> Gerrit-Reviewer: Friendly Automation </div>
<div style="display:none"> Gerrit-Reviewer: Joshua Colp <jcolp@sangoma.com> </div>
<div style="display:none"> Gerrit-Reviewer: Kevin Harwell <kharwell@digium.com> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>