Index: apps/app_voicemail.c =================================================================== --- apps/app_voicemail.c (revision 30272) +++ apps/app_voicemail.c (working copy) @@ -133,6 +133,8 @@ OPT_PREPEND_MAILBOX = (1 << 4), OPT_PRIORITY_JUMP = (1 << 5), OPT_AUTOPLAY = (1 << 6), + OPT_MESSAGE_URGENT = (1 << 7), + OPT_MESSAGE_PRIORITY = (1 << 8) } vm_option_flags; enum { @@ -150,6 +152,8 @@ AST_APP_OPTION('p', OPT_PREPEND_MAILBOX), AST_APP_OPTION('j', OPT_PRIORITY_JUMP), AST_APP_OPTION_ARG('a', OPT_AUTOPLAY, OPT_ARG_PLAYFOLDER), + AST_APP_OPTION('U', OPT_MESSAGE_URGENT), + AST_APP_OPTION('P', OPT_MESSAGE_PRIORITY) }); static int load_config(void); @@ -344,7 +348,9 @@ " calling party.\n" " u - Play the 'unavailable greeting.\n" " j - Jump to priority n+101 if the mailbox is not found or some other\n" -" error occurs.\n"; +" error occurs.\n" +" U - Mark message as URGENT.\n" +" P - Mark message as PRIORITY.\n"; static char *synopsis_vmain = "Check Voicemail messages"; @@ -1678,7 +1684,7 @@ return 1; } -static void prep_email_sub_vars(struct ast_channel *ast, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, char *cidnum, char *cidname, char *dur, char *date, char *passdata, size_t passdatasize, const char *category) +static void prep_email_sub_vars(struct ast_channel *ast, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, char *cidnum, char *cidname, char *dur, char *date, char *passdata, size_t passdatasize, const char *category,char *flag) { char callerid[256]; /* Prepare variables for substition in email body and subject */ @@ -1693,6 +1699,7 @@ pbx_builtin_setvar_helper(ast, "VM_CIDNUM", (cidnum ? cidnum : "an unknown caller")); pbx_builtin_setvar_helper(ast, "VM_DATE", date); pbx_builtin_setvar_helper(ast, "VM_CATEGORY", category ? ast_strdupa(category) : "no category"); + pbx_builtin_setvar_helper(ast, "VM_FLAG", flag); } /* @@ -1733,7 +1740,7 @@ return p; } -static int sendmail(char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, char *cidnum, char *cidname, char *attach, char *format, int duration, int attach_user_voicemail, const char *category) +static int sendmail(char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, char *cidnum, char *cidname, char *attach, char *format, int duration, int attach_user_voicemail, const char *category, char *flag) { FILE *p=NULL; char date[256]; @@ -1779,7 +1786,7 @@ int vmlen = strlen(fromstring)*3 + 200; if ((passdata = alloca(vmlen))) { memset(passdata, 0, vmlen); - prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category); + prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category, flag); pbx_substitute_variables_helper(ast,fromstring,passdata,vmlen); fprintf(p, "From: %s <%s>\n",passdata,who); } else ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n"); @@ -1796,7 +1803,7 @@ int vmlen = strlen(emailsubject)*3 + 200; if ((passdata = alloca(vmlen))) { memset(passdata, 0, vmlen); - prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category); + prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category, flag); pbx_substitute_variables_helper(ast,emailsubject,passdata,vmlen); fprintf(p, "Subject: %s\n",passdata); } else ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n"); @@ -1807,9 +1814,9 @@ fprintf(p, emailtitle, msgnum + 1, mailbox) ; fprintf(p,"\n") ; } else if (ast_test_flag((&globalflags), VM_PBXSKIP)) - fprintf(p, "Subject: New message %d in mailbox %s\n", msgnum + 1, mailbox); + fprintf(p, "Subject: New %s message %d in mailbox %s\n",flag, msgnum + 1, mailbox); else - fprintf(p, "Subject: [PBX]: New message %d in mailbox %s\n", msgnum + 1, mailbox); + fprintf(p, "Subject: [PBX]: New %s message %d in mailbox %s\n", flag, msgnum + 1, mailbox); fprintf(p, "Message-ID: \n", msgnum, (unsigned int)ast_random(), mailbox, getpid(), host); fprintf(p, "MIME-Version: 1.0\n"); if (attach_user_voicemail) { @@ -1828,18 +1835,18 @@ int vmlen = strlen(emailbody)*3 + 200; if ((passdata = alloca(vmlen))) { memset(passdata, 0, vmlen); - prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category); + prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category, flag); pbx_substitute_variables_helper(ast,emailbody,passdata,vmlen); fprintf(p, "%s\n",passdata); } else ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n"); ast_channel_free(ast); } else ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); } else { - fprintf(p, "Dear %s:\n\n\tJust wanted to let you know you were just left a %s long message (number %d)\n" + fprintf(p, "Dear %s:\n\n\tJust wanted to let you know you were just left a %s long %s message (number %d)\n" "in mailbox %s from %s, on %s so you might\n" "want to check it when you get a chance. Thanks!\n\n\t\t\t\t--Asterisk\n\n", vmu->fullname, - dur, msgnum + 1, mailbox, (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), date); + dur, flag, msgnum + 1, mailbox, (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), date); } if (attach_user_voicemail) { /* Eww. We want formats to tell us their own MIME type */ @@ -1865,7 +1872,7 @@ return 0; } -static int sendpage(char *srcemail, char *pager, int msgnum, char *context, char *mailbox, char *cidnum, char *cidname, int duration, struct ast_vm_user *vmu, const char *category) +static int sendpage(char *srcemail, char *pager, int msgnum, char *context, char *mailbox, char *cidnum, char *cidname, int duration, struct ast_vm_user *vmu, const char *category, char *flag) { char date[256]; char host[MAXHOSTNAMELEN]=""; @@ -1897,7 +1904,7 @@ int vmlen = strlen(fromstring)*3 + 200; if ((passdata = alloca(vmlen))) { memset(passdata, 0, vmlen); - prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category); + prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category, flag); pbx_substitute_variables_helper(ast,pagerfromstring,passdata,vmlen); fprintf(p, "From: %s <%s>\n",passdata,who); } else @@ -1914,14 +1921,14 @@ int vmlen = strlen(pagersubject)*3 + 200; if ((passdata = alloca(vmlen))) { memset(passdata, 0, vmlen); - prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category); + prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category, flag); pbx_substitute_variables_helper(ast,pagersubject,passdata,vmlen); fprintf(p, "Subject: %s\n\n",passdata); } else ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n"); ast_channel_free(ast); } else ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); } else - fprintf(p, "Subject: New VM\n\n"); + fprintf(p, "Subject: New %s VM\n\n", flag); strftime(date, sizeof(date), "%A, %B %d, %Y at %r", &tm); if (pagerbody) { struct ast_channel *ast; @@ -1930,15 +1937,15 @@ int vmlen = strlen(pagerbody)*3 + 200; if ((passdata = alloca(vmlen))) { memset(passdata, 0, vmlen); - prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category); + prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category, flag); pbx_substitute_variables_helper(ast,pagerbody,passdata,vmlen); fprintf(p, "%s\n",passdata); } else ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n"); ast_channel_free(ast); } else ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); } else { - fprintf(p, "New %s long msg in box %s\n" - "from %s, on %s", dur, mailbox, (cidname ? cidname : (cidnum ? cidnum : "unknown")), date); + fprintf(p, "New %s long %s msg in box %s\n" + "from %s, on %s", dur, flag, mailbox, (cidname ? cidname : (cidnum ? cidnum : "unknown")), date); } fclose(p); snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp); @@ -2299,9 +2306,9 @@ #endif -static int notify_new_message(struct ast_channel *chan, struct ast_vm_user *vmu, int msgnum, long duration, char *fmt, char *cidnum, char *cidname); +static int notify_new_message(struct ast_channel *chan, struct ast_vm_user *vmu, int msgnum, long duration, char *fmt, char *cidnum, char *cidname, char *flag); -static int copy_message(struct ast_channel *chan, struct ast_vm_user *vmu, int imbox, int msgnum, long duration, struct ast_vm_user *recip, char *fmt) +static int copy_message(struct ast_channel *chan, struct ast_vm_user *vmu, int imbox, int msgnum, long duration, struct ast_vm_user *recip, char *fmt, char *flag) { char fromdir[256], todir[256], frompath[256], topath[256]; const char *frombox = mbox(imbox); @@ -2330,12 +2337,12 @@ ast_log(LOG_ERROR, "Recipient mailbox %s@%s is full\n", recip->mailbox, recip->context); } ast_unlock_path(todir); - notify_new_message(chan, recip, recipmsgnum, duration, fmt, chan->cid.cid_num, chan->cid.cid_name); + notify_new_message(chan, recip, recipmsgnum, duration, fmt, chan->cid.cid_num, chan->cid.cid_name, flag); return 0; } -static void run_externnotify(char *context, char *extension) +static void run_externnotify(char *context, char *extension, char *flag) { char arguments[255]; char ext_context[256] = ""; @@ -2374,7 +2381,7 @@ if (inboxcount(ext_context, &newvoicemails, &oldvoicemails)) { ast_log(LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", extension); } else { - snprintf(arguments, sizeof(arguments), "%s %s %s %d&", externnotify, context, extension, newvoicemails); + snprintf(arguments, sizeof(arguments), "%s %s %s %d %s&", externnotify, context, extension, newvoicemails, flag ? flag : ""); ast_log(LOG_DEBUG, "Executing %s\n", arguments); ast_safe_system(arguments); } @@ -2410,6 +2417,7 @@ struct ast_vm_user *vmu; struct ast_vm_user svm; const char *category = NULL; + char *flag = ""; ast_copy_string(tmp, ext, sizeof(tmp)); ext = tmp; @@ -2425,7 +2433,16 @@ *tmpptr++ = '\0'; category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"); + if (ast_test_flag(options, OPT_MESSAGE_URGENT)) + flag = "URGENT"; + else if (ast_test_flag(options, OPT_MESSAGE_PRIORITY)) + flag = "PRIORITY"; + else + flag = pbx_builtin_getvar_helper(chan, "VM_FLAG"); + if (!flag) + flag = ""; + if (!(vmu = find_user(&svm, context, ext))) { ast_log(LOG_WARNING, "No entry in voicemail config file for '%s'\n", ext); if (ast_test_flag(options, OPT_PRIORITY_JUMP) || ast_opt_priority_jumping) @@ -2599,7 +2616,8 @@ "callerid=%s\n" "origdate=%s\n" "origtime=%ld\n" - "category=%s\n", + "category=%s\n" + "flag=%s\n", ext, chan->context, chan->macrocontext, @@ -2608,7 +2626,8 @@ chan->name, ast_callerid_merge(callerid, sizeof(callerid), chan->cid.cid_name, chan->cid.cid_num, "Unknown"), date, (long)time(NULL), - category ? category : ""); + category ? category : "", + flag ? flag : ""); } else ast_log(LOG_WARNING, "Error opening text file for output\n"); res = play_record_review(chan, NULL, tmptxtfile, vmmaxmessage, fmt, 1, vmu, &duration, NULL, options->record_gain); @@ -2655,13 +2674,13 @@ context++; } if ((recip = find_user(&recipu, context, exten))) { - copy_message(chan, vmu, 0, msgnum, duration, recip, fmt); + copy_message(chan, vmu, 0, msgnum, duration, recip, fmt, flag); free_user(recip); } } if (ast_fileexists(fn, NULL, NULL)) { STORE(dir, vmu->mailbox, vmu->context, msgnum); - notify_new_message(chan, vmu, msgnum, duration, fmt, chan->cid.cid_num, chan->cid.cid_name); + notify_new_message(chan, vmu, msgnum, duration, fmt, chan->cid.cid_num, chan->cid.cid_name, flag); DISPOSE(dir, msgnum); } } @@ -3333,7 +3352,7 @@ return cmd; } -static int notify_new_message(struct ast_channel *chan, struct ast_vm_user *vmu, int msgnum, long duration, char *fmt, char *cidnum, char *cidname) +static int notify_new_message(struct ast_channel *chan, struct ast_vm_user *vmu, int msgnum, long duration, char *fmt, char *cidnum, char *cidname, char *flag) { char todir[256], fn[256], ext_context[256], *stringp; int newmsgs = 0, oldmsgs = 0; @@ -3362,14 +3381,14 @@ attach_user_voicemail = ast_test_flag(vmu, VM_ATTACH); if (!ast_strlen_zero(vmu->serveremail)) myserveremail = vmu->serveremail; - sendmail(myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, cidnum, cidname, fn, fmt, duration, attach_user_voicemail, category); + sendmail(myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, cidnum, cidname, fn, fmt, duration, attach_user_voicemail, category, flag); } if (!ast_strlen_zero(vmu->pager)) { char *myserveremail = serveremail; if (!ast_strlen_zero(vmu->serveremail)) myserveremail = vmu->serveremail; - sendpage(myserveremail, vmu->pager, msgnum, vmu->context, vmu->mailbox, cidnum, cidname, duration, vmu, category); + sendpage(myserveremail, vmu->pager, msgnum, vmu->context, vmu->mailbox, cidnum, cidname, duration, vmu, category, flag); } if (ast_test_flag(vmu, VM_DELETE)) { @@ -3381,12 +3400,12 @@ ast_app_inboxcount(ext_context, &newmsgs, &oldmsgs); } manager_event(EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s@%s\r\nWaiting: %d\r\nNew: %d\r\nOld: %d\r\n", vmu->mailbox, vmu->context, ast_app_has_voicemail(ext_context, NULL), newmsgs, oldmsgs); - run_externnotify(vmu->context, vmu->mailbox); + run_externnotify(vmu->context, vmu->mailbox, flag); return 0; } static int forward_message(struct ast_channel *chan, char *context, char *dir, int curmsg, struct ast_vm_user *sender, - char *fmt, int flag, signed char record_gain) + char *fmt, int flag, signed char record_gain, char *flag2) { char username[70]=""; char sys[256]; @@ -3583,21 +3602,21 @@ attach_user_voicemail = ast_test_flag(vmtmp, VM_ATTACH); if (!ast_strlen_zero(vmtmp->serveremail)) myserveremail = vmtmp->serveremail; - sendmail(myserveremail, vmtmp, todircount, vmtmp->context, vmtmp->mailbox, chan->cid.cid_num, chan->cid.cid_name, fn, tmp, duration, attach_user_voicemail, category); + sendmail(myserveremail, vmtmp, todircount, vmtmp->context, vmtmp->mailbox, chan->cid.cid_num, chan->cid.cid_name, fn, tmp, duration, attach_user_voicemail, category, flag2); } if (!ast_strlen_zero(vmtmp->pager)) { char *myserveremail = serveremail; if (!ast_strlen_zero(vmtmp->serveremail)) myserveremail = vmtmp->serveremail; - sendpage(myserveremail, vmtmp->pager, todircount, vmtmp->context, vmtmp->mailbox, chan->cid.cid_num, chan->cid.cid_name, duration, vmtmp, category); + sendpage(myserveremail, vmtmp->pager, todircount, vmtmp->context, vmtmp->mailbox, chan->cid.cid_num, chan->cid.cid_name, duration, vmtmp, category, flag2); } ast_config_destroy(mif); /* or here */ } /* Leave voicemail for someone */ manager_event(EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext_context, has_voicemail(ext_context, NULL)); - run_externnotify(vmtmp->context, vmtmp->mailbox); + run_externnotify(vmtmp->context, vmtmp->mailbox, flag2); saved_messages++; AST_LIST_REMOVE_CURRENT(&extensions, list); @@ -3829,7 +3848,7 @@ static int play_message(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms) { int res = 0; - char filename[256],*origtime, *cid, *context, *duration; + char filename[256],*origtime, *cid, *context, *duration, *flag; char *category; struct ast_config *msg_cfg; @@ -3897,6 +3916,7 @@ cid = ast_variable_retrieve(msg_cfg, "message", "callerid"); duration = ast_variable_retrieve(msg_cfg, "message", "duration"); category = ast_variable_retrieve(msg_cfg, "message", "category"); + flag = ast_variable_retrieve(msg_cfg, "message", "flag"); context = ast_variable_retrieve(msg_cfg, "message", "context"); if (!strncasecmp("macro",context,5)) /* Macro names in contexts are useless for our needs */ @@ -3904,6 +3924,10 @@ if (!res) res = play_message_category(chan, category); + /* To Be Implimented + if ((!res) && (flag)) + res = play_message_flag(chan, flag); + */ if ((!res) && (ast_test_flag(vmu, VM_ENVELOPE))) res = play_message_datetime(chan, vmu, origtime, filename); if ((!res) && (ast_test_flag(vmu, VM_SAYCID))) @@ -5587,7 +5611,7 @@ case '5': /* Leave VoiceMail */ if (ast_test_flag(vmu, VM_SVMAIL)) { - cmd = forward_message(chan, vmu->context, vms.curdir, vms.curmsg, vmu, vmfmts, 1, record_gain); + cmd = forward_message(chan, vmu->context, vms.curdir, vms.curmsg, vmu, vmfmts, 1, record_gain, NULL); if (cmd == ERROR_LOCK_PATH) { res = cmd; goto out; @@ -5668,7 +5692,7 @@ case '8': if (vms.lastmsg > -1) { - cmd = forward_message(chan, vmu->context, vms.curdir, vms.curmsg, vmu, vmfmts, 0, record_gain); + cmd = forward_message(chan, vmu->context, vms.curdir, vms.curmsg, vmu, vmfmts, 0, record_gain, NULL); if (cmd == ERROR_LOCK_PATH) { res = cmd; goto out; @@ -5771,7 +5795,7 @@ if (valid) { snprintf(ext_context, sizeof(ext_context), "%s@%s", vms.username, vmu->context); manager_event(EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext_context, has_voicemail(ext_context, NULL)); - run_externnotify(vmu->context, vmu->mailbox); + run_externnotify(vmu->context, vmu->mailbox, NULL); } if (vmu) free_user(vmu); @@ -5813,7 +5837,7 @@ LOCAL_USER_REMOVE(u); return -1; } - ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING | OPT_PRIORITY_JUMP); + ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING | OPT_PRIORITY_JUMP | OPT_MESSAGE_URGENT | OPT_MESSAGE_PRIORITY); if (ast_test_flag(&flags, OPT_RECORDGAIN)) { int gain;