219219 <para>Use the specified amount of gain when recording a voicemail message.
220220 The units are whole-number decibels (dB).</para>
221221 </option>
222+ <option name="r">
223+ <para>"Read only". Prevent user from deleting any messages.</para>
224+ <para>This applies only to specific executions of VoiceMailMain, NOT the mailbox itself.</para>
225+ </option>
222226 <option name="s">
223227 <para>Skip checking the passcode for the mailbox.</para>
224228 </option>
@@ -592,6 +596,7 @@ enum vm_option_flags {
592596 OPT_EARLYM_GREETING = (1 << 10),
593597 OPT_BEEP = (1 << 11),
594598 OPT_SILENT_IF_GREET = (1 << 12),
599+ OPT_READONLY = (1 << 13),
595600};
596601
597602enum vm_option_args {
@@ -621,7 +626,8 @@ AST_APP_OPTIONS(vm_app_options, {
621626 AST_APP_OPTION('U', OPT_MESSAGE_Urgent),
622627 AST_APP_OPTION('P', OPT_MESSAGE_PRIORITY),
623628 AST_APP_OPTION('e', OPT_EARLYM_GREETING),
624- AST_APP_OPTION_ARG('t', OPT_BEEP, OPT_ARG_BEEP_TONE)
629+ AST_APP_OPTION_ARG('t', OPT_BEEP, OPT_ARG_BEEP_TONE),
630+ AST_APP_OPTION('r', OPT_READONLY),
625631});
626632
627633static const char * const mailbox_folders[] = {
@@ -10328,7 +10334,7 @@ static int vm_intro(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm
1032810334 }
1032910335}
1033010336
10331- static int vm_instructions_en(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent)
10337+ 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 )
1033210338{
1033310339 int res = 0;
1033410340 /* 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,
1038810394#ifdef IMAP_STORAGE
1038910395 ast_mutex_unlock(&vms->lock);
1039010396#endif
10391- if (!curmsg_deleted) {
10392- res = ast_play_and_wait(chan, "vm-delete");
10393- } else {
10394- res = ast_play_and_wait(chan, "vm-undelete");
10397+ if (!nodelete) {
10398+ if (!curmsg_deleted) {
10399+ res = ast_play_and_wait(chan, "vm-delete");
10400+ } else {
10401+ res = ast_play_and_wait(chan, "vm-undelete");
10402+ }
1039510403 }
1039610404 if (!res) {
1039710405 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,
1041610424 return res;
1041710425}
1041810426
10419- static int vm_instructions_ja(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent)
10427+ 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 )
1042010428{
1042110429 int res = 0;
1042210430 /* 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,
1051210520 return res;
1051310521}
1051410522
10515- static int vm_instructions_zh(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent)
10523+ 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 )
1051610524{
1051710525 int res = 0;
1051810526 /* 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,
1053010538 res = ast_play_and_wait(chan, "vm-opts");
1053110539 if (!res) {
1053210540 vms->starting = 0;
10533- return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent);
10541+ return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent, nodelete );
1053410542 }
1053510543 }
1053610544 return res;
1053710545}
1053810546
10539- static int vm_instructions(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent)
10547+ static int vm_instructions(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent, int nodelete )
1054010548{
1054110549 if (!strncasecmp(ast_channel_language(chan), "ja", 2)) { /* Japanese syntax */
10542- return vm_instructions_ja(chan, vmu, vms, skipadvanced, in_urgent);
10550+ return vm_instructions_ja(chan, vmu, vms, skipadvanced, in_urgent, nodelete );
1054310551 } else if (vms->starting && !strncasecmp(ast_channel_language(chan), "zh", 2)) { /* CHINESE (Taiwan) syntax */
10544- return vm_instructions_zh(chan, vmu, vms, skipadvanced, in_urgent);
10552+ return vm_instructions_zh(chan, vmu, vms, skipadvanced, in_urgent, nodelete );
1054510553 } else { /* Default to ENGLISH */
10546- return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent);
10554+ return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent, nodelete );
1054710555 }
1054810556}
1054910557
@@ -11426,6 +11434,7 @@ static int vm_execmain(struct ast_channel *chan, const char *data)
1142611434 int play_auto = 0;
1142711435 int play_folder = 0;
1142811436 int in_urgent = 0;
11437+ int nodelete = 0;
1142911438#ifdef IMAP_STORAGE
1143011439 int deleted = 0;
1143111440#endif
@@ -11488,6 +11497,9 @@ static int vm_execmain(struct ast_channel *chan, const char *data)
1148811497 play_folder = 0;
1148911498 }
1149011499 }
11500+ if (ast_test_flag(&flags, OPT_READONLY)) {
11501+ nodelete = 1;
11502+ }
1149111503 } else {
1149211504 /* old style options parsing */
1149311505 while (*(args.argv0)) {
@@ -11901,7 +11913,7 @@ static int vm_execmain(struct ast_channel *chan, const char *data)
1190111913 }
1190211914 break;
1190311915 case '7': /* Delete the current message */
11904- if (vms.curmsg >= 0 && vms.curmsg <= vms.lastmsg) {
11916+ if (!nodelete && vms.curmsg >= 0 && vms.curmsg <= vms.lastmsg) {
1190511917 vms.deleted[vms.curmsg] = !vms.deleted[vms.curmsg];
1190611918 if (useadsi)
1190711919 adsi_delete(chan, &vms);
@@ -12090,7 +12102,7 @@ static int vm_execmain(struct ast_channel *chan, const char *data)
1209012102 if (!cmd)
1209112103 cmd = ast_play_and_wait(chan, "vm-opts");
1209212104 if (!cmd)
12093- cmd = vm_instructions(chan, vmu, &vms, 1, in_urgent);
12105+ cmd = vm_instructions(chan, vmu, &vms, 1, in_urgent, nodelete );
1209412106 break;
1209512107 }
1209612108 cmd = ast_play_and_wait(chan, "vm-onefor");
@@ -12102,7 +12114,7 @@ static int vm_execmain(struct ast_channel *chan, const char *data)
1210212114 if (!cmd)
1210312115 cmd = ast_play_and_wait(chan, "vm-opts");
1210412116 if (!cmd)
12105- cmd = vm_instructions(chan, vmu, &vms, 1, in_urgent);
12117+ cmd = vm_instructions(chan, vmu, &vms, 1, in_urgent, nodelete );
1210612118 } else
1210712119 cmd = 0;
1210812120 break;
@@ -12119,7 +12131,7 @@ static int vm_execmain(struct ast_channel *chan, const char *data)
1211912131 break;
1212012132 default: /* Nothing */
1212112133 ast_test_suite_event_notify("PLAYBACK", "Message: instructions");
12122- cmd = vm_instructions(chan, vmu, &vms, 0, in_urgent);
12134+ cmd = vm_instructions(chan, vmu, &vms, 0, in_urgent, nodelete );
1212312135 break;
1212412136 }
1212512137 }
0 commit comments