summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Michelson <mmichelson@digium.com>2008-04-25 18:18:30 +0000
committerMark Michelson <mmichelson@digium.com>2008-04-25 18:18:30 +0000
commit8ce5a0a50089757c2ee04ba2d0d0ff65fdbb6dcd (patch)
tree56d6fb9dea91c16919520853d2400c0e9e156c9a
parent34451e7c4342acca070d63d0206e67faf0df76cf (diff)
This patch allows for forwarding a message with a "comment" attachment
if using IMAP storage for voicemail. The comment will be recorded and attached as a second attachment in addition to the original message. This will be invoked if you choose to prepend a message the way you would with file or ODBC storage (closes issue #12028) Reported by: jaroth Patches: forward_with_comment_v2.patch uploaded by jaroth (license 50) Tested by: jaroth git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@114656 65c4cc65-6c06-0410-ace0-fbb531ad65f3
-rw-r--r--apps/app_voicemail.c258
1 files changed, 177 insertions, 81 deletions
diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c
index 04b0ca4ce..0e96a6d9d 100644
--- a/apps/app_voicemail.c
+++ b/apps/app_voicemail.c
@@ -149,12 +149,12 @@ static void set_update(MAILSTREAM * stream);
static void init_vm_state(struct vm_state *vms);
static void check_msgArray(struct vm_state *vms);
static void copy_msgArray(struct vm_state *dst, struct vm_state *src);
-static int save_body(BODY *body, struct vm_state *vms, char *section, char *format);
-static int make_gsm_file(char *dest, size_t len, char *imapuser, char *dir, int num);
+static int save_body(BODY *body, struct vm_state *vms, char *section, char *format, char *altfile);
+static int make_gsm_file(char *dest, size_t len, char *imapuser, char *dir, int num, char *prefix);
static void get_mailbox_delimiter(MAILSTREAM *stream);
static void mm_parsequota (MAILSTREAM *stream, unsigned char *msg, QUOTALIST *pquota);
static void imap_mailbox_name(char *spec, size_t len, struct vm_state *vms, int box, int target);
-static int imap_store_file(char *dir, char *mailboxuser, char *mailboxcontext, int msgnum, struct ast_channel *chan, struct ast_vm_user *vmu, char *fmt, int duration, struct vm_state *vms);
+static int imap_store_file(char *dir, char *mailboxuser, char *mailboxcontext, int msgnum, struct ast_channel *chan, struct ast_vm_user *vmu, char *fmt, int duration, struct vm_state *vms, char *introfile);
static void update_messages_by_imapuser(const char *user, unsigned long number);
static int imap_remove_file (char *dir, int msgnum);
@@ -414,6 +414,7 @@ struct vm_state {
char vmbox[PATH_MAX];
char fn[PATH_MAX];
char fn2[PATH_MAX];
+ char intro[PATH_MAX];
int *deleted;
int *heard;
int curmsg;
@@ -450,7 +451,7 @@ static char odbc_table[80];
#ifdef IMAP_STORAGE
#define RETRIEVE(a,b,c,d) (imap_retrieve_file(a,b,c,d ))
#define DISPOSE(a,b) (imap_remove_file(a,b))
-#define STORE(a,b,c,d,e,f,g,h,i) (imap_store_file(a,b,c,d,e,f,g,h,i))
+#define STORE(a,b,c,d,e,f,g,h,i,j) (imap_store_file(a,b,c,d,e,f,g,h,i,j))
#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));
@@ -459,7 +460,7 @@ static char odbc_table[80];
#else
#define RETRIEVE(a,b,c,d)
#define DISPOSE(a,b)
-#define STORE(a,b,c,d,e,f,g,h,i)
+#define STORE(a,b,c,d,e,f,g,h,i,j)
#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_plain_file(g,h));
@@ -670,8 +671,9 @@ 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);
-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 *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category, int imap);
+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);
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);
#if !(defined(ODBC_STORAGE) || defined(IMAP_STORAGE))
@@ -1121,14 +1123,14 @@ static int make_dir(char *dest, int len, const char *context, const char *ext, c
}
#ifdef IMAP_STORAGE
-static int make_gsm_file(char *dest, size_t len, char *imapuser, char *dir, int num)
+static int make_gsm_file(char *dest, size_t len, char *imapuser, char *dir, int num, char *prefix)
{
int res;
if ((res = ast_mkdir(dir, 01777))) {
ast_log(AST_LOG_WARNING, "ast_mkdir '%s' failed: %s\n", dir, strerror(res));
- return snprintf(dest, len, "%s/msg%04d", dir, num);
+ return snprintf(dest, len, "%s/%smsg%04d", dir, prefix, num);
}
- return snprintf(dest, len, "%s/msg%04d", dir, num);
+ return snprintf(dest, len, "%s/%smsg%04d", dir, prefix, num);
}
static void vm_imap_delete(int msgnum, struct vm_state *vms)
@@ -2252,19 +2254,18 @@ static FILE *vm_mkftemp(char *template)
*
* 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 *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category, int imap)
+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)
{
char date[256];
char host[MAXHOSTNAMELEN] = "";
char who[256];
char bound[256];
- char fname[256];
char dur[256];
- char tmpcmd[256];
struct ast_tm tm;
char *passdata2;
size_t len_passdata;
- char *greeting_attachment;
+ char *greeting_attachment;
+ char filename[256];
#ifdef IMAP_STORAGE
#define ENDL "\r\n"
@@ -2383,49 +2384,71 @@ static void make_email_file(FILE *p, char *srcemail, struct ast_vm_user *vmu, in
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);
}
+
if (attach_user_voicemail) {
- /* Eww. We want formats to tell us their own MIME type */
- char *ctype = (!strcasecmp(format, "ogg")) ? "application/" : "audio/x-";
- char tmpdir[256], newtmp[256];
- int tmpfd = -1;
-
- if (vmu->volgain < -.001 || vmu->volgain > .001) {
- create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, vmu->mailbox, "tmp");
- snprintf(newtmp, sizeof(newtmp), "%s/XXXXXX", tmpdir);
- tmpfd = mkstemp(newtmp);
- chmod(newtmp, VOICEMAIL_FILE_MODE & ~my_umask);
- ast_debug(3, "newtmp: %s\n", newtmp);
- if (tmpfd > -1) {
- snprintf(tmpcmd, sizeof(tmpcmd), "sox -v %.4f %s.%s %s.%s", vmu->volgain, attach, format, newtmp, format);
- ast_safe_system(tmpcmd);
- attach = newtmp;
- ast_debug(3, "VOLGAIN: Stored at: %s.%s - Level: %.4f - Mailbox: %s\n", attach, format, vmu->volgain, mailbox);
- }
+ if (!ast_strlen_zero(attach2)) {
+ snprintf(filename, sizeof(filename), "msgintro%04d.%s", msgnum, format);
+ ast_debug(5, "creating attachment filename %s\n", filename);
+ add_email_attachment(p, vmu, format, attach2, greeting_attachment, mailbox, bound, filename, 0, msgnum);
+ snprintf(filename, sizeof(filename), "msg%04d.%s", msgnum, format);
+ ast_debug(5, "creating second attachment filename %s\n", filename);
+ add_email_attachment(p, vmu, format, attach, greeting_attachment, mailbox, bound, filename, 1, msgnum);
+ } else {
+ snprintf(filename, sizeof(filename), "msg%04d.%s", msgnum, format);
+ ast_debug(5, "creating attachment filename %s, no second attachment.\n", filename);
+ add_email_attachment(p, vmu, format, attach, greeting_attachment, mailbox, bound, filename, 1, msgnum);
}
- fprintf(p, "--%s" ENDL, bound);
- if (msgnum > -1)
- fprintf(p, "Content-Type: %s%s; name=\"msg%04d.%s\"" ENDL, ctype, format, msgnum + 1, format);
- else
- fprintf(p, "Content-Type: %s%s; name=\"%s.%s\"" ENDL, ctype, format, greeting_attachment, format);
- fprintf(p, "Content-Transfer-Encoding: base64" ENDL);
- fprintf(p, "Content-Description: Voicemail sound attachment." ENDL);
- if (msgnum > -1)
- fprintf(p, "Content-Disposition: attachment; filename=\"msg%04d.%s\"" ENDL ENDL, msgnum + 1, format);
- else
- fprintf(p, "Content-Disposition: attachment; filename=\"%s.%s\"" ENDL ENDL, greeting_attachment, format);
- snprintf(fname, sizeof(fname), "%s.%s", attach, format);
- base_encode(fname, p);
- fprintf(p, ENDL "--%s--" ENDL "." ENDL, bound);
+ }
+}
+
+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)
+{
+ char tmpdir[256], newtmp[256];
+ char fname[256];
+ char tmpcmd[256];
+ int tmpfd = -1;
+
+ /* Eww. We want formats to tell us their own MIME type */
+ char *ctype = (!strcasecmp(format, "ogg")) ? "application/" : "audio/x-";
+
+ if (vmu->volgain < -.001 || vmu->volgain > .001) {
+ create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, vmu->mailbox, "tmp");
+ snprintf(newtmp, sizeof(newtmp), "%s/XXXXXX", tmpdir);
+ tmpfd = mkstemp(newtmp);
+ chmod(newtmp, VOICEMAIL_FILE_MODE & ~my_umask);
+ ast_debug(3, "newtmp: %s\n", newtmp);
if (tmpfd > -1) {
- unlink(fname);
- close(tmpfd);
- unlink(newtmp);
+ snprintf(tmpcmd, sizeof(tmpcmd), "sox -v %.4f %s.%s %s.%s", vmu->volgain, attach, format, newtmp, format);
+ ast_safe_system(tmpcmd);
+ attach = newtmp;
+ ast_debug(3, "VOLGAIN: Stored at: %s.%s - Level: %.4f - Mailbox: %s\n", attach, format, vmu->volgain, mailbox);
}
}
-#undef ENDL
+ fprintf(p, "--%s" ENDL, bound);
+ if (msgnum > -1)
+ fprintf(p, "Content-Type: %s%s; name=\"%s\"" ENDL, ctype, format, filename);
+ else
+ fprintf(p, "Content-Type: %s%s; name=\"%s.%s\"" ENDL, ctype, format, attach, format);
+ fprintf(p, "Content-Transfer-Encoding: base64" ENDL);
+ fprintf(p, "Content-Description: Voicemail sound attachment." ENDL);
+ if (msgnum > -1)
+ fprintf(p, "Content-Disposition: attachment; filename=\"%s\"" ENDL ENDL, filename);
+ else
+ fprintf(p, "Content-Disposition: attachment; filename=\"%s.%s\"" ENDL ENDL, attach, format);
+ snprintf(fname, sizeof(fname), "%s.%s", attach, format);
+ base_encode(fname, p);
+ if (last)
+ fprintf(p, ENDL ENDL "--%s--" ENDL "." ENDL, bound);
+ if (tmpfd > -1) {
+ unlink(fname);
+ close(tmpfd);
+ unlink(newtmp);
+ }
+ return 0;
}
+#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 *format, int duration, int attach_user_voicemail, struct ast_channel *chan, 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 *attach2, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category)
{
FILE *p = NULL;
char tmp[80] = "/tmp/astmail-XXXXXX";
@@ -2444,7 +2467,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, format, duration, attach_user_voicemail, chan, category, 0);
+ make_email_file(p, srcemail, vmu, msgnum, context, mailbox, cidnum, cidname, attach, attach2, format, duration, attach_user_voicemail, chan, category, 0);
fclose(p);
snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp);
ast_safe_system(tmp2);
@@ -2862,10 +2885,11 @@ static int has_voicemail(const char *mailbox, const char *folder)
#elif defined(IMAP_STORAGE)
-static int imap_store_file(char *dir, char *mailboxuser, char *mailboxcontext, int msgnum, struct ast_channel *chan, struct ast_vm_user *vmu, char *fmt, int duration, struct vm_state *vms)
+static int imap_store_file(char *dir, char *mailboxuser, char *mailboxcontext, int msgnum, struct ast_channel *chan, struct ast_vm_user *vmu, char *fmt, int duration, struct vm_state *vms, char *introfile)
{
char *myserveremail = serveremail;
char fn[PATH_MAX];
+ char intro[PATH_MAX];
char mailbox[256];
char *stringp;
FILE *p = NULL;
@@ -2873,6 +2897,7 @@ static int imap_store_file(char *dir, char *mailboxuser, char *mailboxcontext, i
long len;
void *buf;
int tempcopy = 0;
+ int ret;
STRING str;
/* Attach only the first format */
@@ -2898,6 +2923,12 @@ static int imap_store_file(char *dir, char *mailboxuser, char *mailboxcontext, i
tempcopy = 1;
}
+ if (!ast_strlen_zero(introfile)) {
+ snprintf(intro, sizeof(intro), "%s/msgintro%04d", dir, msgnum);
+ } else {
+ intro[0] = '\0';
+ }
+
if (!strcmp(fmt, "wav49"))
fmt = "WAV";
ast_debug(3, "Storing file '%s', format '%s'\n", fn, fmt);
@@ -2912,11 +2943,14 @@ static int imap_store_file(char *dir, char *mailboxuser, char *mailboxcontext, i
}
if (msgnum < 0 && imapgreetings) {
- init_mailstream(vms, GREETINGS_FOLDER);
+ if ((ret = init_mailstream(vms, GREETINGS_FOLDER))) {
+ ast_log(AST_LOG_WARNING, "Unable to open mailstream.\n");
+ return -1;
+ }
imap_delete_old_greeting(fn, vms);
}
- make_email_file(p, myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL), fn, fmt, duration, 1, chan, NULL, 1);
+ make_email_file(p, myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL), fn, intro, fmt, duration, 1, chan, NULL, 1);
/* read mail file to memory */
len = ftell(p);
rewind(p);
@@ -2930,7 +2964,11 @@ static int imap_store_file(char *dir, char *mailboxuser, char *mailboxcontext, i
fread(buf, len, 1, p);
((char *)buf)[len] = '\0';
INIT(&str, mail_string, buf, len);
- init_mailstream(vms, NEW_FOLDER);
+ if ((ret = init_mailstream(vms, NEW_FOLDER))) {
+ ast_log(AST_LOG_WARNING, "Unable to open mailstream.\n");
+ return -1;
+ }
+
imap_mailbox_name(mailbox, sizeof(mailbox), vms, NEW_FOLDER, 1);
if (!mail_append(vms->mailstream, mailbox, &str))
ast_log(AST_LOG_ERROR, "Error while sending the message to %s\n", mailbox);
@@ -3827,7 +3865,7 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, struct leave_vm_
* ODBC storage does the entire copy with SQL.
*/
if (ast_fileexists(fn, NULL, NULL) > 0) {
- STORE(dir, vmu->mailbox, vmu->context, msgnum, chan, vmu, fmt, duration, vms);
+ STORE(dir, vmu->mailbox, vmu->context, msgnum, chan, vmu, fmt, duration, vms, NULL);
}
/* Are there to be more recipients of this message? */
@@ -4543,16 +4581,21 @@ static int get_folder2(struct ast_channel *chan, char *fn, int start)
* \return zero on success, -1 on error.
*/
static int vm_forwardoptions(struct ast_channel *chan, struct ast_vm_user *vmu, char *curdir, int curmsg, char *vmfmts,
- char *context, signed char record_gain, long *duration, struct vm_state *vms)
+ char *context, signed char record_gain, long *duration, struct vm_state *vms, char *introfile)
{
+#ifdef IMAP_STORAGE
+ int res;
+#endif
int cmd = 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];
+ struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE };
+#ifndef IMAP_STORAGE
+ signed char zero_gain = 0;
+#endif
+ const char *duration_str;
/* Must always populate duration correctly */
make_file(msgfile, sizeof(msgfile), curdir, curmsg);
@@ -4572,6 +4615,15 @@ static int vm_forwardoptions(struct ast_channel *chan, struct ast_vm_user *vmu,
retries = 0;
switch (cmd) {
case '1':
+
+#ifdef IMAP_STORAGE
+ /* Record new intro file */
+ res = ast_play_and_wait(chan, INTRO);
+ res = ast_play_and_wait(chan, "beep");
+ res = play_record_review(chan, NULL, introfile, vmu->maxsecs, vmfmts, 1, vmu, (int *)duration, NULL, record_gain, vms);
+ cmd = 't';
+#else
+
/* prepend a message to the current message, update the metadata and return */
prepend_duration = 0;
@@ -4605,12 +4657,15 @@ static int vm_forwardoptions(struct ast_channel *chan, struct ast_vm_user *vmu,
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, prepend_duration, vms);
+ STORE(curdir, vmu->mailbox, context, curmsg, chan, vmu, vmfmts, prepend_duration, vms, NULL);
}
}
+#endif
break;
case '2':
+ /* NULL out introfile so we know there is no intro! */
+ introfile[0] = '\0';
cmd = 't';
break;
case '*':
@@ -4717,7 +4772,7 @@ 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, fmt, duration, attach_user_voicemail, chan, category);
+ sendmail(myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, cidnum, cidname, fn, NULL, fmt, duration, attach_user_voicemail, chan, category);
if (attach_user_voicemail)
DISPOSE(todir, msgnum);
@@ -4780,9 +4835,11 @@ static int forward_message(struct ast_channel *chan, char *context, struct vm_st
BODY *body;
char *header_content;
char *temp;
- char todir[256];
- int todircount = 0;
+ char todir[256], introtmp[256];
+ char tmpcmd[512];
+ int todircount = 0, two_part = -1;
struct vm_state *dstvms;
+ char tmpdir[PATH_MAX];
#endif
char username[70] = "";
char fn[PATH_MAX]; /* for playback of name greeting */
@@ -4796,6 +4853,7 @@ static int forward_message(struct ast_channel *chan, char *context, struct vm_st
int valid_extensions = 0;
char *dir;
int curmsg;
+ char tmptxtfile[PATH_MAX];
if (vms == NULL) return -1;
dir = vms->curdir;
@@ -4943,6 +5001,14 @@ static int forward_message(struct ast_channel *chan, char *context, struct vm_st
long duration = 0;
char origmsgfile[PATH_MAX], msgfile[PATH_MAX];
struct vm_state vmstmp;
+#ifdef IMAP_STORAGE
+ char *myserveremail = serveremail;
+ char buf[1024] = "";
+ /* create tempfile for forwarding intro */
+ create_dirpath(tmpdir, sizeof(tmpdir), receiver->context, receiver->mailbox, "tmp");
+ snprintf(tmptxtfile, sizeof(tmptxtfile), "%s/msgintro%04d", tmpdir, curmsg);
+ ast_debug(5, "Creating temp file name %s...\n",tmptxtfile);
+#endif
memcpy(&vmstmp, vms, sizeof(vmstmp));
make_file(origmsgfile, sizeof(origmsgfile), dir, curmsg);
@@ -4954,13 +5020,11 @@ static int forward_message(struct ast_channel *chan, char *context, struct vm_st
/* 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);
+ cmd = vm_forwardoptions(chan, sender, vmstmp.curdir, curmsg, vmfmts, S_OR(context, "default"), record_gain, &duration, &vmstmp, tmptxtfile);
if (!cmd) {
AST_LIST_TRAVERSE_SAFE_BEGIN(&extensions, vmtmp, list) {
#ifdef IMAP_STORAGE
- char *myserveremail = serveremail;
int attach_user_voicemail;
- char buf[1024] = "";
/* 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]);
@@ -4994,22 +5058,35 @@ static int forward_message(struct ast_channel *chan, char *context, struct vm_st
fmt = "WAV";
ast_debug(3, "**** format set to %s, vmfmts set to %s\n", fmt, vmfmts);
snprintf(todir, sizeof(todir), "%s%s/%s/tmp", VM_SPOOL_DIR, vmtmp->context, vmtmp->mailbox);
- make_gsm_file(vms->fn, sizeof(vms->fn), vms->imapuser, todir, vms->curmsg);
+ make_gsm_file(vms->fn, sizeof(vms->fn), vms->imapuser, todir, vms->curmsg, "msg");
ast_debug(3, "Before mail_fetchstructure, message number is %ld, filename is:%s\n", vms->msgArray[vms->curmsg], vms->fn);
mail_fetchstructure(vms->mailstream, vms->msgArray[vms->curmsg], &body);
- save_body(body, vms, "3", "gsm");
+
/* should not assume "fmt" here! */
- save_body(body, vms, "2", fmt);
+ save_body(body, vms, "2", fmt, vms->fn);
+ save_body(body, vms, "2", fmt, vms->fn);
+
+ /* second attachment would be body if intro, otherwise null
+ * two_part will be set to 0 if there are two parts, otherwise -1 */
+ snprintf(introtmp, sizeof(introtmp), "%stmp",vms->intro);
+ two_part = save_body(body,vms,"3",fmt, introtmp);
+
+ /* If there are two parts to the existing
+ * message, merge them together into one message before sending */
+ if (two_part == 0) {
+ snprintf(tmpcmd, sizeof(tmpcmd), "sox %s.%s %s.%s %smerge.%s ; mv -f %smerge.%s %s/msg%04d.%s", vms->fn, fmt, introtmp, fmt, vms->fn, fmt, vms->fn, fmt, tmpdir, curmsg, fmt);
+ ast_debug(5,"about to execute system command %s\n",tmpcmd);
+ ast_safe_system(tmpcmd);
+ } /* by now vms->fn should have merged audio */
/* get destination mailbox */
- dstvms = get_vm_state_by_mailbox(vmtmp->mailbox, 0);
- if (dstvms) {
+ if ((dstvms = get_vm_state_by_mailbox(vmtmp->mailbox, 0))) {
init_mailstream(dstvms, 0);
if (!dstvms->mailstream) {
ast_log(AST_LOG_ERROR, "IMAP mailstream for %s is NULL\n", vmtmp->mailbox);
} else {
- STORE(todir, vmtmp->mailbox, vmtmp->context, dstvms->curmsg, chan, vmtmp, fmt, duration, dstvms);
+ STORE(todir, vmtmp->mailbox, vmtmp->context, dstvms->curmsg, chan, vmtmp, fmt, duration, dstvms, tmptxtfile);
run_externnotify(vmtmp->context, vmtmp->mailbox);
}
} else {
@@ -5020,7 +5097,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), vms->fn, fmt, duration, attach_user_voicemail, chan, NULL);
+ sendmail(myserveremail, vmtmp, todircount, vmtmp->context, vmtmp->mailbox, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL), vms->fn, tmptxtfile, fmt, duration, attach_user_voicemail, chan, NULL);
#else
copy_message(chan, sender, -1, curmsg, duration, vmtmp, fmt, vmstmp.curdir);
@@ -5279,7 +5356,7 @@ static int play_message(struct ast_channel *chan, struct ast_vm_user *vmu, struc
char duration[16];
char category[32];
char todir[PATH_MAX];
- int res = 0;
+ int res = 0, two_part = -1;
char *attachedfilefmt;
char *temp;
char buf[1024];
@@ -5300,7 +5377,8 @@ static int play_message(struct ast_channel *chan, struct ast_vm_user *vmu, struc
return -1;
}
snprintf(todir, sizeof(todir), "%s%s/%s/tmp", VM_SPOOL_DIR, vmu->context, vmu->mailbox);
- make_gsm_file(vms->fn, sizeof(vms->fn), vms->imapuser, todir, vms->curmsg);
+ make_gsm_file(vms->fn, sizeof(vms->fn), vms->imapuser, todir, vms->curmsg, "msg");
+ make_gsm_file(vms->intro, sizeof(vms->intro), vms->imapuser, todir, vms->curmsg, "msgintro");
mail_fetchstructure (vms->mailstream, vms->msgArray[vms->curmsg], &body);
@@ -5320,7 +5398,8 @@ static int play_message(struct ast_channel *chan, struct ast_vm_user *vmu, struc
ast_log(AST_LOG_ERROR, "File format could not be obtained from IMAP message attachment\n");
return -1;
}
- save_body(body, vms, "2", attachedfilefmt);
+ save_body(body, vms, "2", attachedfilefmt, vms->fn); /* save first attachment */
+ two_part = save_body(body, vms, "3", attachedfilefmt, vms->intro); /* save forwarded intro if present */
adsi_message(chan, vms);
if (!vms->curmsg)
@@ -5386,7 +5465,12 @@ static int play_message(struct ast_channel *chan, struct ast_vm_user *vmu, struc
if (!res) {
vms->heard[vms->curmsg] = 1;
- res = wait_file(chan, vms, vms->fn);
+ if (two_part == 0) { /* If there are two parts */
+ wait_file(chan, vms, vms->fn);
+ res = wait_file(chan, vms, vms->intro);
+ } else {
+ res = wait_file(chan, vms, vms->fn);
+ }
}
DISPOSE(vms->curdir, vms->curmsg);
DELETE(0, 0, vms->fn);
@@ -5720,7 +5804,7 @@ static int imap_retrieve_file (char *dir, int msgnum, const char *mailbox, char
if (!strcmp(filename, file)) {
ast_copy_string(vms_p->fn, dir, sizeof(vms_p->fn));
vms_p->msgArray[vms_p->curmsg] = i + 1;
- save_body(body, vms_p, "2", attachment);
+ save_body(body, vms_p, "2", attachment, vms_p->fn);
free_user(vmu);
return 0;
}
@@ -9848,8 +9932,11 @@ static int play_record_review(struct ast_channel *chan, char *playfile, char *re
ast_filerename(tempfile, recordfile, NULL);
ast_stream_and_wait(chan, "vm-msgsaved", "");
if (!outsidecaller) {
- STORE(recordfile, vmu->mailbox, vmu->context, -1, chan, vmu, fmt, *duration, vms);
+ /* Saves to IMAP server - but SHOULD save to filesystem ONLY if recording greetings! */
+#ifndef IMAP_STORAGE
+ STORE(recordfile, vmu->mailbox, vmu->context, -1, chan, vmu, fmt, *duration, vms, NULL);
DISPOSE(recordfile, -1);
+#endif
}
cmd = 't';
return res;
@@ -10478,22 +10565,31 @@ static void copy_msgArray(struct vm_state *dst, struct vm_state *src)
}
}
-static int save_body(BODY *body, struct vm_state *vms, char *section, char *format)
+static int save_body(BODY *body, struct vm_state *vms, char *section, char *format, char *altfile)
{
char *body_content;
char *body_decoded;
+ char *fn = S_OR(altfile, vms->fn);
unsigned long len;
unsigned long newlen;
char filename[256];
if (!body || body == NIL)
return -1;
+
body_content = mail_fetchbody(vms->mailstream, vms->msgArray[vms->curmsg], section, &len);
if (body_content != NIL) {
- snprintf(filename, sizeof(filename), "%s.%s", vms->fn, format);
+ snprintf(filename, sizeof(filename), "%s.%s", fn, format);
/* ast_debug(1, body_content); */
body_decoded = rfc822_base64((unsigned char *)body_content, len, &newlen);
+ /* If the body of the file is empty, return an error */
+ if (!newlen) {
+ return -1;
+ }
write_file(filename, (char *) body_decoded, newlen);
+ } else {
+ ast_debug(5, "Body of message is NULL.\n");
+ return -1;
}
return 0;
}