Merged revisions 186415 via svnmerge from
authorTilghman Lesher <tilghman@meg.abyt.es>
Fri, 3 Apr 2009 19:30:34 +0000 (19:30 +0000)
committerTilghman Lesher <tilghman@meg.abyt.es>
Fri, 3 Apr 2009 19:30:34 +0000 (19:30 +0000)
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
  r186415 | tilghman | 2009-04-03 14:06:58 -0500 (Fri, 03 Apr 2009) | 7 lines

  Distinguish in a sent email between simple sends and forwards.
  (closes issue #11678)
   Reported by: jamessan
   Patches:
         20090330__bug11678.diff.txt uploaded by tilghman (license 14)
   Tested by: tilghman, lmadsen
........

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@186444 65c4cc65-6c06-0410-ace0-fbb531ad65f3

apps/app_voicemail.c
configs/voicemail.conf.sample

index 14e0555..070b78d 100644 (file)
@@ -804,7 +804,7 @@ static int play_record_review(struct ast_channel *chan, char *playfile, char *re
 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);
-static void make_email_file(FILE *p, char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, char *cidnum, char *cidname, char *attach, char *attach2, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category, int imap, const char *flag);
+static void make_email_file(FILE *p, char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, char *attach, char *attach2, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category, int imap, const char *flag);
 static void apply_options(struct ast_vm_user *vmu, const char *options);
 static int add_email_attachment(FILE *p, struct ast_vm_user *vmu, char *format, char *attach, char *greeting_attachment, char *mailbox, char *bound, char *filename, int last, int msgnum);
 static int is_valid_dtmf(const char *key);
@@ -3843,9 +3843,16 @@ static int base_encode(char *filename, FILE *so)
        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, const char *flag)
+static void prep_email_sub_vars(struct ast_channel *ast, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, char *dur, char *date, char *passdata, size_t passdatasize, const char *category, const char *flag)
 {
        char callerid[256];
+       char fromdir[256], fromfile[256];
+       struct ast_config *msg_cfg;
+       const char *origcallerid, *origtime;
+       char origcidname[80], origcidnum[80], origdate[80];
+       int inttime;
+       struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE };
+
        /* Prepare variables for substitution in email body and subject */
        pbx_builtin_setvar_helper(ast, "VM_NAME", vmu->fullname);
        pbx_builtin_setvar_helper(ast, "VM_DUR", dur);
@@ -3860,6 +3867,35 @@ static void prep_email_sub_vars(struct ast_channel *ast, struct ast_vm_user *vmu
        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);
+
+       /* Retrieve info from VM attribute file */
+       make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder);
+       make_file(fromfile, sizeof(fromfile), fromdir, msgnum - 1);
+       if (strlen(fromfile) < sizeof(fromfile) - 5) {
+               strcat(fromfile, ".txt");
+       }
+       if (!(msg_cfg = ast_config_load(fromfile, config_flags))) {
+               if (option_debug > 0) {
+                       ast_log(LOG_DEBUG, "Config load for message text file '%s' failed\n", fromfile);
+               }
+               return;
+       }
+
+       if ((origcallerid = ast_variable_retrieve(msg_cfg, "message", "callerid"))) {
+               pbx_builtin_setvar_helper(ast, "ORIG_VM_CALLERID", origcallerid);
+               ast_callerid_split(origcallerid, origcidname, sizeof(origcidname), origcidnum, sizeof(origcidnum));
+               pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNAME", origcidname);
+               pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNUM", origcidnum);
+       }
+
+       if ((origtime = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(origtime, "%d", &inttime) == 1) {
+               struct timeval tv = { inttime, };
+               struct ast_tm tm;
+               ast_localtime(&tv, &tm, NULL);
+               ast_strftime(origdate, sizeof(origdate), emaildateformat, &tm);
+               pbx_builtin_setvar_helper(ast, "ORIG_VM_DATE", origdate);
+       }
+       ast_config_destroy(msg_cfg);
 }
 
 /*!
@@ -3993,7 +4029,7 @@ static char *encode_mime_str(const char *start, char *end, size_t endsize, size_
  *
  * The email body, and base 64 encoded attachement (if any) are stored to the file identified by *p. This method does not actually send the email.  That is done by invoking the configure 'mailcmd' and piping this generated file into it, or with the sendemail() function.
  */
-static void make_email_file(FILE *p, char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, char *cidnum, char *cidname, char *attach, char *attach2, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category, int imap, const char *flag)
+static void make_email_file(FILE *p, char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, char *attach, char *attach2, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category, int imap, const char *flag)
 {
        char date[256];
        char host[MAXHOSTNAMELEN] = "";
@@ -4053,7 +4089,7 @@ static void make_email_file(FILE *p, char *srcemail, struct ast_vm_user *vmu, in
                if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Substitution/voicemail"))) {
                        char *ptr;
                        memset(passdata2, 0, len_passdata2);
-                       prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, enc_cidnum, enc_cidname, dur, date, passdata2, len_passdata2, category, flag);
+                       prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, enc_cidnum, enc_cidname, dur, date, passdata2, len_passdata2, category, flag);
                        pbx_substitute_variables_helper(ast, fromstring, passdata2, len_passdata2);
                        len_passdata = strlen(passdata2) * 3 + 300;
                        passdata = alloca(len_passdata);
@@ -4104,7 +4140,7 @@ static void make_email_file(FILE *p, char *srcemail, struct ast_vm_user *vmu, in
                        }
 
                        memset(passdata, 0, len_passdata);
-                       prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, len_passdata, category, flag);
+                       prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, passdata, len_passdata, category, flag);
                        pbx_substitute_variables_helper(ast, e_subj, passdata, len_passdata);
                        if (check_mime(passdata)) {
                                int first_line = 1;
@@ -4190,17 +4226,57 @@ static void make_email_file(FILE *p, char *srcemail, struct ast_vm_user *vmu, in
                        int vmlen = strlen(e_body) * 3 + 200;
                        passdata = alloca(vmlen);
                        memset(passdata, 0, vmlen);
-                       prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category, flag);
+                       prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, passdata, vmlen, category, flag);
                        pbx_substitute_variables_helper(ast, e_body, passdata, vmlen);
                        fprintf(p, "%s" ENDL, passdata);
                        ast_channel_free(ast);
                } else
                        ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
-       } else if (msgnum > -1){
-               fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just left a %s long %s message (number %d)" ENDL
-               "in mailbox %s from %s, on %s so you might" ENDL
-               "want to check it when you get a chance.  Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" ENDL ENDL, vmu->fullname, 
-               dur, flag, msgnum + 1, mailbox, (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), date);
+       } else if (msgnum > -1) {
+               if (strcmp(vmu->mailbox, mailbox)) {
+                       /* Forwarded type */
+                       struct ast_config *msg_cfg;
+                       const char *v;
+                       int inttime;
+                       char fromdir[256], fromfile[256], origdate[80] = "", origcallerid[80] = "";
+                       struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE };
+                       /* Retrieve info from VM attribute file */
+                       make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder);
+                       make_file(fromfile, sizeof(fromfile), fromdir, msgnum);
+                       if (strlen(fromfile) < sizeof(fromfile) - 5) {
+                               strcat(fromfile, ".txt");
+                       }
+                       if ((msg_cfg = ast_config_load(fromfile, config_flags))) {
+                               if ((v = ast_variable_retrieve(msg_cfg, "message", "callerid"))) {
+                                       ast_copy_string(origcallerid, v, sizeof(origcallerid));
+                               }
+
+                               /* You might be tempted to do origdate, except that a) it's in the wrong
+                                * format, and b) it's missing for IMAP recordings. */
+                               if ((v = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(v, "%d", &inttime) == 1) {
+                                       struct timeval tv = { inttime, };
+                                       struct ast_tm tm;
+                                       ast_localtime(&tv, &tm, NULL);
+                                       ast_strftime(origdate, sizeof(origdate), emaildateformat, &tm);
+                               }
+                               fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just forwarded"
+                                       " a %s long message (number %d)" ENDL "in mailbox %s from %s, on %s" ENDL
+                                       "(originally sent by %s on %s)" ENDL "so you might want to check it when you get a"
+                                       " chance.  Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" ENDL ENDL, vmu->fullname, dur,
+                                       msgnum + 1, mailbox, (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")),
+                                       date, origcallerid, origdate);
+                               ast_config_destroy(msg_cfg);
+                       } else {
+                               goto plain_message;
+                       }
+               } else {
+plain_message:
+                       fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just left a "
+                               "%s long message (number %d)" ENDL "in mailbox %s from %s, on %s so you might" ENDL
+                               "want to check it when you get a chance.  Thanks!" ENDL ENDL "\t\t\t\t--Asterisk"
+                               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);
@@ -4275,7 +4351,7 @@ static int add_email_attachment(FILE *p, struct ast_vm_user *vmu, char *format,
 }
 #undef ENDL
 
-static int sendmail(char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, char *cidnum, char *cidname, char *attach, char *attach2, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category, const char *flag)
+static int sendmail(char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, char *attach, char *attach2, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category, const char *flag)
 {
        FILE *p=NULL;
        char tmp[80] = "/tmp/astmail-XXXXXX";
@@ -4294,7 +4370,7 @@ static int sendmail(char *srcemail, struct ast_vm_user *vmu, int msgnum, char *c
                ast_log(AST_LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd);
                return -1;
        } else {
-               make_email_file(p, srcemail, vmu, msgnum, context, mailbox, cidnum, cidname, attach, attach2, format, duration, attach_user_voicemail, chan, category, 0, flag);
+               make_email_file(p, srcemail, vmu, msgnum, context, mailbox, fromfolder, cidnum, cidname, attach, attach2, format, duration, attach_user_voicemail, chan, category, 0, flag);
                fclose(p);
                snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp);
                ast_safe_system(tmp2);
@@ -4303,7 +4379,7 @@ static int sendmail(char *srcemail, struct ast_vm_user *vmu, int msgnum, char *c
        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, const char *flag)
+static int sendpage(char *srcemail, char *pager, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, int duration, struct ast_vm_user *vmu, const char *category, const char *flag)
 {
        char date[256];
        char host[MAXHOSTNAMELEN] = "";
@@ -4334,7 +4410,7 @@ static int sendpage(char *srcemail, char *pager, int msgnum, char *context, char
                        int vmlen = strlen(fromstring)*3 + 200;
                        passdata = alloca(vmlen);
                        memset(passdata, 0, vmlen);
-                       prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category, flag);
+                       prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, passdata, vmlen, category, flag);
                        pbx_substitute_variables_helper(ast, pagerfromstring, passdata, vmlen);
                        fprintf(p, "From: %s <%s>\n", passdata, who);
                        ast_channel_free(ast);
@@ -4350,7 +4426,7 @@ static int sendpage(char *srcemail, char *pager, int msgnum, char *context, char
                        int vmlen = strlen(pagersubject) * 3 + 200;
                        passdata = alloca(vmlen);
                        memset(passdata, 0, vmlen);
-                       prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category, flag);
+                       prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, passdata, vmlen, category, flag);
                        pbx_substitute_variables_helper(ast, pagersubject, passdata, vmlen);
                        fprintf(p, "Subject: %s\n\n", passdata);
                        ast_channel_free(ast);
@@ -4372,7 +4448,7 @@ static int sendpage(char *srcemail, char *pager, int msgnum, char *context, char
                        int vmlen = strlen(pagerbody) * 3 + 200;
                        passdata = alloca(vmlen);
                        memset(passdata, 0, vmlen);
-                       prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category, flag);
+                       prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, passdata, vmlen, category, flag);
                        pbx_substitute_variables_helper(ast, pagerbody, passdata, vmlen);
                        fprintf(p, "%s\n", passdata);
                        ast_channel_free(ast);
@@ -6259,14 +6335,15 @@ static int notify_new_message(struct ast_channel *chan, struct ast_vm_user *vmu,
                        RETRIEVE(todir, msgnum, vmu->mailbox, vmu->context);
 
                /* XXX possible imap issue, should category be NULL XXX */
-               sendmail(myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, cidnum, cidname, fn, NULL, fmt, duration, attach_user_voicemail, chan, category, flag);
+               sendmail(myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, mbox(0), cidnum, cidname, fn, NULL, fmt, duration, attach_user_voicemail, chan, category, flag);
 
                if (attach_user_voicemail)
                        DISPOSE(todir, msgnum);
        }
 
-       if (!ast_strlen_zero(vmu->pager))
-               sendpage(myserveremail, vmu->pager, msgnum, vmu->context, vmu->mailbox, cidnum, cidname, duration, vmu, category, flag);
+       if (!ast_strlen_zero(vmu->pager)) {
+               sendpage(myserveremail, vmu->pager, msgnum, vmu->context, vmu->mailbox, mbox(0), cidnum, cidname, duration, vmu, category, flag);
+       }
 
        if (ast_test_flag(vmu, VM_DELETE))
                DELETE(todir, msgnum, fn, vmu);
@@ -6446,6 +6523,7 @@ static int forward_message(struct ast_channel *chan, char *context, struct vm_st
                                while ((receiver = AST_LIST_REMOVE_HEAD(&extensions, list))) {
                                        free_user(receiver);
                                }
+                               ast_log(LOG_NOTICE, "'%s' is not a valid mailbox\n", s);
                                valid_extensions = 0;
                                break;
                        }
@@ -6519,7 +6597,7 @@ static int forward_message(struct ast_channel *chan, char *context, struct vm_st
                                        myserveremail = vmtmp->serveremail;
                                attach_user_voicemail = ast_test_flag(vmtmp, VM_ATTACH);
                                /* NULL category for IMAP storage */
-                               sendmail(myserveremail, vmtmp, todircount, vmtmp->context, vmtmp->mailbox, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL), vmstmp.fn, vmstmp.introfn, fmt, duration, attach_user_voicemail, chan, NULL, urgent_str);
+                               sendmail(myserveremail, vmtmp, todircount, vmtmp->context, vmtmp->mailbox, dstvms->curbox, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL), vmstmp.fn, vmstmp.introfn, fmt, duration, attach_user_voicemail, chan, NULL, urgent_str);
 #else
                                copy_message(chan, sender, 0, curmsg, duration, vmtmp, fmt, dir, urgent_str);
 #endif
index e34f91d..3606b14 100644 (file)
@@ -115,6 +115,10 @@ maxlogins=3
 ; Change the from, body and/or subject, variables:
 ;     VM_NAME, VM_DUR, VM_MSGNUM, VM_MAILBOX, VM_CALLERID, VM_CIDNUM,
 ;     VM_CIDNAME, VM_DATE
+; Additionally, on forwarded messages, you have the variables:
+;     ORIG_VM_CALLERID, ORIG_VM_CIDNUM, ORIG_VM_CIDNAME, ORIG_VM_DATE
+; You can select between two variables by using dialplan functions, e.g.
+;     ${IF(${ISNULL(${ORIG_VM_DATE})}?${VM_DATE}:${ORIG_VM_DATE})}
 ;
 ; Note: The emailbody config row can only be up to 512 characters due to a
 ;       limitation in the Asterisk configuration subsystem.
@@ -124,6 +128,11 @@ maxlogins=3
 ; caller", if they are both null.
 ;emailbody=Dear ${VM_NAME}:\n\n\tjust wanted to let you know you were just left a ${VM_DUR} long message (number ${VM_MSGNUM})\nin mailbox ${VM_MAILBOX} from ${VM_CALLERID}, on ${VM_DATE}, so you might\nwant to check it when you get a chance.  Thanks!\n\n\t\t\t\t--Asterisk\n
 ;
+; Note: ${IF()} strips spacing at the beginning and end of its true and false
+; values, so a newline cannot be placed at either location.  The word 'so' is
+; therefore duplicated, in order for the newline to be interpreted correctly.
+;emailbody=Dear ${VM_NAME}:\n\n\tjust wanted to let you know you were just ${IF($["${VM_CIDNUM}" = "${ORIG_VM_CIDNUM}"]?left:forwarded)} a ${VM_DUR} long message (number ${VM_MSGNUM})\nin mailbox ${VM_MAILBOX} from ${VM_CALLERID}, on ${VM_DATE},\n${IF($["${VM_CIDNUM}" = "${ORIG_VM_CIDNUM}"]?so:(originally sent by ${ORIG_VM_CALLERID} on ${ORIG_VM_DATE})\nso)} you might want to check it when you get a chance.  Thanks!\n\n\t\t\t\t--Asterisk\n
+;
 ; You can also change the Pager From: string, the pager body and/or subject.
 ; The above defined variables also can be used here
 ;pagerfromstring=The Asterisk PBX