Merged revisions 101942 via svnmerge from
authorTilghman Lesher <tilghman@meg.abyt.es>
Fri, 1 Feb 2008 22:12:55 +0000 (22:12 +0000)
committerTilghman Lesher <tilghman@meg.abyt.es>
Fri, 1 Feb 2008 22:12:55 +0000 (22:12 +0000)
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r101942 | tilghman | 2008-02-01 15:54:28 -0600 (Fri, 01 Feb 2008) | 8 lines

Fix the VM_DUR variable for forwarded voicemail, and fixed several other bugs
while I'm in the area.
(closes issue #11615)
 Reported by: jamessan
 Patches:
       20071226__bug11615__2.diff.txt uploaded by Corydon76 (license 14)
 Tested by: Corydon76, jamessan

........

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

apps/app_voicemail.c

index 27146ee..0e716b4 100644 (file)
@@ -454,7 +454,7 @@ static char odbc_table[80];
 #define STORE(a,b,c,d,e,f,g,h,i)
 #define EXISTS(a,b,c,d) (ast_fileexists(c, NULL, d) > 0)
 #define RENAME(a,b,c,d,e,f,g,h) (rename_file(g,h));
-#define COPY(a,b,c,d,e,f,g,h) (copy_file(g,h));
+#define COPY(a,b,c,d,e,f,g,h) (copy_plain_file(g,h));
 #define DELETE(a,b,c) (vm_delete(c))
 #endif
 #endif
@@ -1624,6 +1624,7 @@ static void rename_file(char *sfn, char *dfn)
        }
        rename(stxt, dtxt);
 }
+#endif
 
 static int copy(char *infile, char *outfile)
 {
@@ -1675,7 +1676,7 @@ static int copy(char *infile, char *outfile)
 #endif
 }
 
-static void copy_file(char *frompath, char *topath)
+static void copy_plain_file(char *frompath, char *topath)
 {
        char frompath2[PATH_MAX], topath2[PATH_MAX];
        struct ast_variable *tmp, *var = NULL;
@@ -1716,6 +1717,8 @@ static void copy_file(char *frompath, char *topath)
        copy(frompath2, topath2);
        ast_variables_destroy(var);
 }
+
+#ifndef IMAP_STORAGE
 /*! \brief
  * A negative return value indicates an error.
  * \note Should always be called with a lock already set on dir.
@@ -2329,7 +2332,7 @@ static const char *mbox(int id)
                "Cust5",
                "Deleted",
        };
-       return (id >= 0 && id < (sizeof(msgs) / sizeof(msgs[0]))) ? msgs[id] : "Unknown";
+       return (id >= 0 && id < (sizeof(msgs) / sizeof(msgs[0]))) ? msgs[id] : "tmp";
 }
 #ifdef IMAP_STORAGE
 static int folder_int(const char *folder)
@@ -4058,9 +4061,26 @@ static int vm_forwardoptions(struct ast_channel *chan, struct ast_vm_user *vmu,
                             char *context, signed char record_gain, long *duration, struct vm_state *vms)
 {
        int cmd = 0;
-       int retries = 0;
+       int retries = 0, prepend_duration = 0, already_recorded = 0;
        signed char zero_gain = 0;
        struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE };
+       struct ast_config *msg_cfg;
+       const char *duration_str;
+       char msgfile[PATH_MAX], backup[PATH_MAX];
+       char textfile[PATH_MAX];
+
+       /* Must always populate duration correctly */
+       make_file(msgfile, sizeof(msgfile), curdir, curmsg);
+       strcpy(textfile, msgfile);
+       strcpy(backup, msgfile);
+       strncat(textfile, ".txt", sizeof(textfile) - 1);
+       strncat(backup, "-bak", sizeof(backup) - 1);
+
+       msg_cfg = ast_config_load(textfile, config_flags);
+
+       *duration = 0;
+       if ((duration_str = ast_variable_retrieve(msg_cfg, "message", "duration")))
+               *duration = atoi(duration_str);
 
        while ((cmd >= 0) && (cmd != 't') && (cmd != '*')) {
                if (cmd)
@@ -4069,16 +4089,7 @@ static int vm_forwardoptions(struct ast_channel *chan, struct ast_vm_user *vmu,
                case '1': 
                        /* prepend a message to the current message, update the metadata and return */
                {
-                       char msgfile[PATH_MAX];
-                       char textfile[PATH_MAX];
-                       int prepend_duration = 0;
-                       struct ast_config *msg_cfg;
-                       const char *duration_str;
-
-                       make_file(msgfile, sizeof(msgfile), curdir, curmsg);
-                       strcpy(textfile, msgfile);
-                       strncat(textfile, ".txt", sizeof(textfile) - 1);
-                       *duration = 0;
+                       prepend_duration = 0;
 
                        /* if we can't read the message metadata, stop now */
                        if (!(msg_cfg = ast_config_load(textfile, config_flags))) {
@@ -4086,6 +4097,13 @@ static int vm_forwardoptions(struct ast_channel *chan, struct ast_vm_user *vmu,
                                break;
                        }
 
+                       /* Back up the original file, so we can retry the prepend */
+                       if (already_recorded)
+                               ast_filecopy(backup, msgfile, NULL);
+                       else
+                               ast_filecopy(msgfile, backup, NULL);
+                       already_recorded = 1;
+
                        if (record_gain)
                                ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0);
 
@@ -4093,26 +4111,20 @@ static int vm_forwardoptions(struct ast_channel *chan, struct ast_vm_user *vmu,
                        if (record_gain)
                                ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0);
 
-                       
-                       if ((duration_str = ast_variable_retrieve(msg_cfg, "message", "duration")))
-                               *duration = atoi(duration_str);
-
                        if (prepend_duration) {
                                struct ast_category *msg_cat;
                                /* need enough space for a maximum-length message duration */
                                char duration_str[12];
 
-                               *duration += prepend_duration;
+                               prepend_duration += *duration;
                                msg_cat = ast_category_get(msg_cfg, "message");
-                               snprintf(duration_str, sizeof(duration_str), "%ld", *duration);
+                               snprintf(duration_str, sizeof(duration_str), "%d", prepend_duration);
                                if (!ast_variable_update(msg_cat, "duration", duration_str, NULL, 0)) {
                                        config_text_file_save(textfile, msg_cfg, "app_voicemail");
-                                       STORE(curdir, vmu->mailbox, context, curmsg, chan, vmu, vmfmts, *duration, vms);
+                                       STORE(curdir, vmu->mailbox, context, curmsg, chan, vmu, vmfmts, prepend_duration, vms);
                                }
                        }
 
-                       ast_config_destroy(msg_cfg);
-
                        break;
                }
                case '2': 
@@ -4135,6 +4147,13 @@ static int vm_forwardoptions(struct ast_channel *chan, struct ast_vm_user *vmu,
                                cmd = 't';
                }
        }
+
+       ast_config_destroy(msg_cfg);
+       if (already_recorded)
+               ast_filedelete(backup, NULL);
+       if (prepend_duration)
+               *duration = prepend_duration;
+
        if (cmd == 't' || cmd == 'S')
                cmd = 0;
        return cmd;
@@ -4389,19 +4408,34 @@ static int forward_message(struct ast_channel *chan, char *context, struct vm_st
                leave_options.record_gain = record_gain;
                cmd = leave_voicemail(chan, mailbox, &leave_options);
        } else {
-
                /* Forward VoiceMail */
                long duration = 0;
+               char origmsgfile[PATH_MAX], msgfile[PATH_MAX];
+               struct vm_state vmstmp;
 #ifdef IMAP_STORAGE
                char *myserveremail = serveremail;
                char buf[1024] = "";
                int attach_user_voicemail = ast_test_flag((&globalflags), VM_ATTACH);
 #endif
+
+               memcpy(&vmstmp, vms, sizeof(vmstmp));
+
+               make_file(origmsgfile, sizeof(origmsgfile), dir, curmsg);
+               create_dirpath(vmstmp.curdir, sizeof(vmstmp.curdir), sender->context, vmstmp.username, "tmp");
+               make_file(msgfile, sizeof(msgfile), vmstmp.curdir, curmsg);
+
                RETRIEVE(dir, curmsg, sender->mailbox, context);
-               cmd = vm_forwardoptions(chan, sender, dir, curmsg, vmfmts, S_OR(context, "default"), record_gain, &duration, vms);
+
+               /* Alter a surrogate file, only */
+               copy_plain_file(origmsgfile, msgfile);
+
+               cmd = vm_forwardoptions(chan, sender, vmstmp.curdir, curmsg, vmfmts, S_OR(context, "default"), record_gain, &duration, &vmstmp);
                if (!cmd) {
                        AST_LIST_TRAVERSE_SAFE_BEGIN(&extensions, vmtmp, list) {
 #ifdef IMAP_STORAGE
+                               char *myserveremail;
+                               int attach_user_voicemail;
+
                                /* Need to get message content */
                                ast_debug(3, "Before mail_fetchheaders, curmsg is: %d, imap messages is %lu\n", vms->curmsg, vms->msgArray[vms->curmsg]);
                                if (!vms->msgArray[vms->curmsg]) {
@@ -4465,7 +4499,7 @@ static int forward_message(struct ast_channel *chan, char *context, struct vm_st
                                sendmail(myserveremail, vmtmp, todircount, vmtmp->context, vmtmp->mailbox, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL), vms->fn, fmt, duration, attach_user_voicemail, chan, NULL);
 
 #else
-                               copy_message(chan, sender, 0, curmsg, duration, vmtmp, fmt, dir);
+                               copy_message(chan, sender, -1, curmsg, duration, vmtmp, fmt, vmstmp.curdir);
 #endif
                                saved_messages++;
                                AST_LIST_REMOVE_CURRENT(list);
@@ -4486,6 +4520,9 @@ static int forward_message(struct ast_channel *chan, char *context, struct vm_st
                                res = ast_play_and_wait(chan, "vm-msgsaved");
                        }       
                }
+
+               /* Remove surrogate file */
+               DELETE(tmpdir, curmsg, msgfile);
        }
 
        /* If anything failed above, we still have this list to free */