|
|
|
@ -1088,7 +1088,7 @@ static int advanced_options(struct ast_channel *chan, struct ast_vm_user *vmu, s
|
|
|
|
|
static int dialout(struct ast_channel *chan, struct ast_vm_user *vmu, char *num, char *outgoing_context);
|
|
|
|
|
static int play_record_review(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime,
|
|
|
|
|
char *fmt, int outsidecaller, struct ast_vm_user *vmu, int *duration, int *sound_duration, const char *unlockdir,
|
|
|
|
|
signed char record_gain, struct vm_state *vms, char *flag, const char *msg_id);
|
|
|
|
|
signed char record_gain, struct vm_state *vms, char *flag, const char *msg_id, int forwardintro);
|
|
|
|
|
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);
|
|
|
|
@ -2174,6 +2174,7 @@ static int imap_retrieve_greeting(const char *dir, const int msgnum, struct ast_
|
|
|
|
|
{
|
|
|
|
|
struct vm_state *vms_p;
|
|
|
|
|
char *file, *filename;
|
|
|
|
|
char dest[PATH_MAX];
|
|
|
|
|
char *attachment;
|
|
|
|
|
int i;
|
|
|
|
|
BODY *body;
|
|
|
|
@ -2237,6 +2238,7 @@ static int imap_retrieve_greeting(const char *dir, const int msgnum, struct ast_
|
|
|
|
|
if (!strcmp(filename, file)) {
|
|
|
|
|
ast_copy_string(vms_p->fn, dir, sizeof(vms_p->fn));
|
|
|
|
|
vms_p->msgArray[vms_p->curmsg] = i + 1;
|
|
|
|
|
create_dirpath(dest, sizeof(dest), vmu->context, vms_p->username, "");
|
|
|
|
|
save_body(body, vms_p, "2", attachment, 0);
|
|
|
|
|
ret = 0;
|
|
|
|
|
break;
|
|
|
|
@ -2369,7 +2371,8 @@ static int imap_retrieve_file(const char *dir, const int msgnum, const char *mai
|
|
|
|
|
snprintf(text_file, sizeof(text_file), "%s.%s", vms->fn, "txt");
|
|
|
|
|
|
|
|
|
|
if (!(text_file_ptr = fopen(text_file, "w"))) {
|
|
|
|
|
ast_log(LOG_WARNING, "Unable to open/create file %s: %s\n", text_file, strerror(errno));
|
|
|
|
|
ast_log(LOG_ERROR, "Unable to open/create file %s: %s\n", text_file, strerror(errno));
|
|
|
|
|
goto exit;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fprintf(text_file_ptr, "%s\n", "[message]");
|
|
|
|
@ -2709,8 +2712,8 @@ static int imap_store_file(const char *dir, const char *mailboxuser, const char
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
make_email_file(p, myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, "INBOX",
|
|
|
|
|
S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL),
|
|
|
|
|
S_COR(ast_channel_caller(chan)->id.name.valid, ast_channel_caller(chan)->id.name.str, NULL),
|
|
|
|
|
chan ? S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL) : NULL,
|
|
|
|
|
chan ? S_COR(ast_channel_caller(chan)->id.name.valid, ast_channel_caller(chan)->id.name.str, NULL) : NULL,
|
|
|
|
|
fn, introfn, fmt, duration, 1, chan, NULL, 1, flag, msg_id);
|
|
|
|
|
/* read mail file to memory */
|
|
|
|
|
len = ftell(p);
|
|
|
|
@ -3018,6 +3021,10 @@ static int init_mailstream(struct vm_state *vms, int box)
|
|
|
|
|
ast_mutex_lock(&vms->lock);
|
|
|
|
|
ast_mutex_lock(&mail_open_lock);
|
|
|
|
|
vms->mailstream = mail_open (stream, tmp, debug ? OP_DEBUG : NIL);
|
|
|
|
|
/* Create the folder if it dosn't exist */
|
|
|
|
|
if (vms->mailstream && !mail_status(vms->mailstream, tmp, SA_UIDNEXT)) {
|
|
|
|
|
mail_create(vms->mailstream, tmp);
|
|
|
|
|
}
|
|
|
|
|
ast_mutex_unlock(&mail_open_lock);
|
|
|
|
|
ast_mutex_unlock(&vms->lock);
|
|
|
|
|
if (vms->mailstream == NIL) {
|
|
|
|
@ -3112,7 +3119,15 @@ static void write_file(char *filename, char *buffer, unsigned long len)
|
|
|
|
|
{
|
|
|
|
|
FILE *output;
|
|
|
|
|
|
|
|
|
|
output = fopen (filename, "w");
|
|
|
|
|
if (!filename || !buffer) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!(output = fopen(filename, "w"))) {
|
|
|
|
|
ast_log(LOG_ERROR, "Unable to open/create file %s: %s\n", filename, strerror(errno));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (fwrite(buffer, len, 1, output) != 1) {
|
|
|
|
|
if (ferror(output)) {
|
|
|
|
|
ast_log(LOG_ERROR, "Short write while writing e-mail body: %s.\n", strerror(errno));
|
|
|
|
@ -3247,18 +3262,30 @@ void mm_lsub(MAILSTREAM * stream, int delim, char *mailbox, long attributes)
|
|
|
|
|
|
|
|
|
|
void mm_status(MAILSTREAM * stream, char *mailbox, MAILSTATUS * status)
|
|
|
|
|
{
|
|
|
|
|
ast_log(AST_LOG_NOTICE, " Mailbox %s", mailbox);
|
|
|
|
|
if (status->flags & SA_MESSAGES)
|
|
|
|
|
ast_log(AST_LOG_NOTICE, ", %lu messages", status->messages);
|
|
|
|
|
if (status->flags & SA_RECENT)
|
|
|
|
|
ast_log(AST_LOG_NOTICE, ", %lu recent", status->recent);
|
|
|
|
|
if (status->flags & SA_UNSEEN)
|
|
|
|
|
ast_log(AST_LOG_NOTICE, ", %lu unseen", status->unseen);
|
|
|
|
|
if (status->flags & SA_UIDVALIDITY)
|
|
|
|
|
ast_log(AST_LOG_NOTICE, ", %lu UID validity", status->uidvalidity);
|
|
|
|
|
if (status->flags & SA_UIDNEXT)
|
|
|
|
|
ast_log(AST_LOG_NOTICE, ", %lu next UID", status->uidnext);
|
|
|
|
|
ast_log(AST_LOG_NOTICE, "\n");
|
|
|
|
|
struct ast_str *str;
|
|
|
|
|
if (!DEBUG_ATLEAST(5) || !(str = ast_str_create(MAX_OBJECT_FIELD))) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ast_str_append(&str, 0, " Mailbox %s", mailbox);
|
|
|
|
|
if (status->flags & SA_MESSAGES) {
|
|
|
|
|
ast_str_append(&str, 0, ", %lu messages", status->messages);
|
|
|
|
|
}
|
|
|
|
|
if (status->flags & SA_RECENT) {
|
|
|
|
|
ast_str_append(&str, 0, ", %lu recent", status->recent);
|
|
|
|
|
}
|
|
|
|
|
if (status->flags & SA_UNSEEN) {
|
|
|
|
|
ast_str_append(&str, 0, ", %lu unseen", status->unseen);
|
|
|
|
|
}
|
|
|
|
|
if (status->flags & SA_UIDVALIDITY) {
|
|
|
|
|
ast_str_append(&str, 0, ", %lu UID validity", status->uidvalidity);
|
|
|
|
|
}
|
|
|
|
|
if (status->flags & SA_UIDNEXT) {
|
|
|
|
|
ast_str_append(&str, 0, ", %lu next UID", status->uidnext);
|
|
|
|
|
}
|
|
|
|
|
ast_log(LOG_DEBUG, "%s\n", ast_str_buffer(str));
|
|
|
|
|
|
|
|
|
|
ast_free(str);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -3446,8 +3473,9 @@ static struct vm_state *get_vm_state_by_imapuser(const char *user, int interacti
|
|
|
|
|
if (interactive) {
|
|
|
|
|
struct vm_state *vms;
|
|
|
|
|
pthread_once(&ts_vmstate.once, ts_vmstate.key_init);
|
|
|
|
|
vms = pthread_getspecific(ts_vmstate.key);
|
|
|
|
|
return vms;
|
|
|
|
|
if ((vms = pthread_getspecific(ts_vmstate.key)) && vms->imapuser && !strcmp(vms->imapuser, user)) {
|
|
|
|
|
return vms;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
AST_LIST_LOCK(&vmstates);
|
|
|
|
@ -3485,8 +3513,10 @@ static struct vm_state *get_vm_state_by_mailbox(const char *mailbox, const char
|
|
|
|
|
if (interactive) {
|
|
|
|
|
struct vm_state *vms;
|
|
|
|
|
pthread_once(&ts_vmstate.once, ts_vmstate.key_init);
|
|
|
|
|
vms = pthread_getspecific(ts_vmstate.key);
|
|
|
|
|
return vms;
|
|
|
|
|
if ((vms = pthread_getspecific(ts_vmstate.key)) && vms->username && vms->context &&
|
|
|
|
|
!strcmp(vms->username,mailbox) && !strcmp(vms->context, local_context)) {
|
|
|
|
|
return vms;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
AST_LIST_LOCK(&vmstates);
|
|
|
|
@ -5133,7 +5163,9 @@ static void make_email_file(FILE *p,
|
|
|
|
|
first_line = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!ast_strlen_zero(emailsubject) || !ast_strlen_zero(vmu->emailsubject)) {
|
|
|
|
|
if (msgnum <= -1) {
|
|
|
|
|
fprintf(p, "Subject: New greeting '%s' on %s." ENDL, greeting_attachment, date);
|
|
|
|
|
} else if (!ast_strlen_zero(emailsubject) || !ast_strlen_zero(vmu->emailsubject)) {
|
|
|
|
|
char *e_subj = !ast_strlen_zero(vmu->emailsubject) ? vmu->emailsubject : emailsubject;
|
|
|
|
|
struct ast_channel *ast;
|
|
|
|
|
if ((ast = ast_dummy_channel_alloc())) {
|
|
|
|
@ -5186,9 +5218,8 @@ static void make_email_file(FILE *p,
|
|
|
|
|
fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, mailbox);
|
|
|
|
|
#endif
|
|
|
|
|
/* flag added for Urgent */
|
|
|
|
|
fprintf(p, "X-Asterisk-VM-Flag: %s" ENDL, flag);
|
|
|
|
|
fprintf(p, "X-Asterisk-VM-Flag: %s" ENDL, S_OR(flag, ""));
|
|
|
|
|
fprintf(p, "X-Asterisk-VM-Priority: %d" ENDL, chan ? ast_channel_priority(chan) : 0);
|
|
|
|
|
fprintf(p, "X-Asterisk-VM-Caller-channel: %s" ENDL, chan ? ast_channel_name(chan) : "");
|
|
|
|
|
fprintf(p, "X-Asterisk-VM-Caller-ID-Num: %s" ENDL, enc_cidnum);
|
|
|
|
|
fprintf(p, "X-Asterisk-VM-Caller-ID-Name: %s" ENDL, enc_cidname);
|
|
|
|
|
fprintf(p, "X-Asterisk-VM-Duration: %d" ENDL, duration);
|
|
|
|
@ -5219,7 +5250,11 @@ static void make_email_file(FILE *p,
|
|
|
|
|
fprintf(p, "--%s" ENDL, bound);
|
|
|
|
|
}
|
|
|
|
|
fprintf(p, "Content-Type: text/plain; charset=%s" ENDL "Content-Transfer-Encoding: 8bit" ENDL ENDL, charset);
|
|
|
|
|
if (emailbody || vmu->emailbody) {
|
|
|
|
|
if (msgnum <= -1) {
|
|
|
|
|
fprintf(p, "This message is to let you know that your greeting '%s' was changed on %s." ENDL
|
|
|
|
|
"Please do not delete this message, lest your greeting vanish with it." ENDL ENDL,
|
|
|
|
|
greeting_attachment, date);
|
|
|
|
|
} else if (emailbody || vmu->emailbody) {
|
|
|
|
|
char* e_body = vmu->emailbody ? vmu->emailbody : emailbody;
|
|
|
|
|
struct ast_channel *ast;
|
|
|
|
|
if ((ast = ast_dummy_channel_alloc())) {
|
|
|
|
@ -5245,7 +5280,7 @@ static void make_email_file(FILE *p,
|
|
|
|
|
} else {
|
|
|
|
|
ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
|
|
|
|
|
}
|
|
|
|
|
} else if (msgnum > -1) {
|
|
|
|
|
} else {
|
|
|
|
|
if (strcmp(vmu->mailbox, mailbox)) {
|
|
|
|
|
/* Forwarded type */
|
|
|
|
|
struct ast_config *msg_cfg;
|
|
|
|
@ -5290,9 +5325,6 @@ plain_message:
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (imap || attach_user_voicemail) {
|
|
|
|
@ -6851,7 +6883,7 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, struct leave_vm_
|
|
|
|
|
res = ast_streamfile(chan, "vm-mailboxfull", ast_channel_language(chan));
|
|
|
|
|
goto leave_vm_out;
|
|
|
|
|
}
|
|
|
|
|
res = play_record_review(chan, NULL, tmptxtfile, vmu->maxsecs, fmt, 1, vmu, &duration, &sound_duration, NULL, options->record_gain, vms, flag, msg_id);
|
|
|
|
|
res = play_record_review(chan, NULL, tmptxtfile, vmu->maxsecs, fmt, 1, vmu, &duration, &sound_duration, NULL, options->record_gain, vms, flag, msg_id, 0);
|
|
|
|
|
|
|
|
|
|
if (txt) {
|
|
|
|
|
fprintf(txt, "flag=%s\n", flag);
|
|
|
|
@ -7055,6 +7087,7 @@ static int save_to_folder(struct ast_vm_user *vmu, struct vm_state *vms, int msg
|
|
|
|
|
char sequence[10];
|
|
|
|
|
char mailbox[256];
|
|
|
|
|
int res;
|
|
|
|
|
int curr_mbox;
|
|
|
|
|
|
|
|
|
|
/* get the real IMAP message number for this message */
|
|
|
|
|
snprintf(sequence, sizeof(sequence), "%ld", vms->msgArray[msg]);
|
|
|
|
@ -7064,26 +7097,35 @@ static int save_to_folder(struct ast_vm_user *vmu, struct vm_state *vms, int msg
|
|
|
|
|
/* if save to Old folder, put in INBOX as read */
|
|
|
|
|
if (box == OLD_FOLDER) {
|
|
|
|
|
mail_setflag(vms->mailstream, sequence, "\\Seen");
|
|
|
|
|
mail_clearflag(vms->mailstream, sequence, "\\Unseen");
|
|
|
|
|
} else if (box == NEW_FOLDER) {
|
|
|
|
|
mail_setflag(vms->mailstream, sequence, "\\Unseen");
|
|
|
|
|
mail_clearflag(vms->mailstream, sequence, "\\Seen");
|
|
|
|
|
}
|
|
|
|
|
if (!strcasecmp(mbox(vmu, NEW_FOLDER), vms->curbox) && (box == NEW_FOLDER || box == OLD_FOLDER)) {
|
|
|
|
|
ast_mutex_unlock(&vms->lock);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
/* Create the folder if it don't exist */
|
|
|
|
|
|
|
|
|
|
/* get the current mailbox so that we can point the mailstream back to it later */
|
|
|
|
|
curr_mbox = get_folder_by_name(vms->curbox);
|
|
|
|
|
|
|
|
|
|
/* Create the folder if it dosn't exist */
|
|
|
|
|
imap_mailbox_name(mailbox, sizeof(mailbox), vms, box, 1); /* Get the full mailbox name */
|
|
|
|
|
ast_debug(5, "Checking if folder exists: %s\n", mailbox);
|
|
|
|
|
if (mail_create(vms->mailstream, mailbox) == NIL)
|
|
|
|
|
ast_debug(5, "Folder exists.\n");
|
|
|
|
|
else
|
|
|
|
|
ast_log(AST_LOG_NOTICE, "Folder %s created!\n", mbox(vmu, box));
|
|
|
|
|
if (move) {
|
|
|
|
|
res = !mail_move(vms->mailstream, sequence, (char *) mbox(vmu, box));
|
|
|
|
|
if (vms->mailstream && !mail_status(vms->mailstream, mailbox, SA_UIDNEXT)) {
|
|
|
|
|
if (mail_create(vms->mailstream, mailbox) != NIL) {
|
|
|
|
|
ast_log(AST_LOG_NOTICE, "Folder %s created!\n", mbox(vmu, box));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* restore previous mbox stream */
|
|
|
|
|
if (init_mailstream(vms, curr_mbox) || !vms->mailstream) {
|
|
|
|
|
ast_log(AST_LOG_ERROR, "IMAP mailstream is NULL or can't init_mailstream\n");
|
|
|
|
|
res = -1;
|
|
|
|
|
} else {
|
|
|
|
|
res = !mail_copy(vms->mailstream, sequence, (char *) mbox(vmu, box));
|
|
|
|
|
if (move) {
|
|
|
|
|
res = !mail_move(vms->mailstream, sequence, (char *) mbox(vmu, box));
|
|
|
|
|
} else {
|
|
|
|
|
res = !mail_copy(vms->mailstream, sequence, (char *) mbox(vmu, box));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
ast_mutex_unlock(&vms->lock);
|
|
|
|
|
return res;
|
|
|
|
@ -7814,9 +7856,9 @@ static int vm_forwardoptions(struct ast_channel *chan, struct ast_vm_user *vmu,
|
|
|
|
|
}
|
|
|
|
|
make_file(vms->introfn, sizeof(vms->introfn), curdir, curmsg);
|
|
|
|
|
strncat(vms->introfn, "intro", sizeof(vms->introfn));
|
|
|
|
|
ast_play_and_wait(chan, INTRO);
|
|
|
|
|
ast_play_and_wait(chan, "vm-record-prepend");
|
|
|
|
|
ast_play_and_wait(chan, "beep");
|
|
|
|
|
cmd = play_record_review(chan, NULL, vms->introfn, vmu->maxsecs, vm_fmts, 1, vmu, (int *) duration, NULL, NULL, record_gain, vms, flag, msg_id);
|
|
|
|
|
cmd = play_record_review(chan, NULL, vms->introfn, vmu->maxsecs, vm_fmts, 1, vmu, (int *) duration, NULL, NULL, record_gain, vms, flag, msg_id, 1);
|
|
|
|
|
if (cmd == -1) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
@ -8085,6 +8127,7 @@ static int forward_message(struct ast_channel *chan, char *context, struct vm_st
|
|
|
|
|
AST_LIST_HEAD_NOLOCK_STATIC(extensions, ast_vm_user);
|
|
|
|
|
char *stringp;
|
|
|
|
|
const char *s;
|
|
|
|
|
const char mailbox_context[256];
|
|
|
|
|
int saved_messages = 0;
|
|
|
|
|
int valid_extensions = 0;
|
|
|
|
|
char *dir;
|
|
|
|
@ -8193,20 +8236,44 @@ static int forward_message(struct ast_channel *chan, char *context, struct vm_st
|
|
|
|
|
/* start optimistic */
|
|
|
|
|
valid_extensions = 1;
|
|
|
|
|
while (s) {
|
|
|
|
|
snprintf((char*)mailbox_context, sizeof(mailbox_context), "%s@%s", s, context ? context : "default");
|
|
|
|
|
if ((is_new_message == 1 || strcmp(s, sender->mailbox)) && (receiver = find_user(NULL, context, s))) {
|
|
|
|
|
int oldmsgs;
|
|
|
|
|
int newmsgs;
|
|
|
|
|
int capacity;
|
|
|
|
|
if (inboxcount(s, &newmsgs, &oldmsgs)) {
|
|
|
|
|
ast_log(LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", s);
|
|
|
|
|
|
|
|
|
|
if (inboxcount(mailbox_context, &newmsgs, &oldmsgs)) {
|
|
|
|
|
ast_log(LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", mailbox_context);
|
|
|
|
|
/* Shouldn't happen, but allow trying another extension if it does */
|
|
|
|
|
res = ast_play_and_wait(chan, "pbx-invalid");
|
|
|
|
|
valid_extensions = 0;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
#ifdef IMAP_STORAGE
|
|
|
|
|
if (!(dstvms = get_vm_state_by_mailbox(s, context, 0))) {
|
|
|
|
|
if (!(dstvms = create_vm_state_from_user(receiver))) {
|
|
|
|
|
ast_log(AST_LOG_ERROR, "Couldn't allocate necessary space\n");
|
|
|
|
|
/* Shouldn't happen, but allow trying another extension if it does */
|
|
|
|
|
res = ast_play_and_wait(chan, "pbx-invalid");
|
|
|
|
|
valid_extensions = 0;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
check_quota(dstvms, imapfolder);
|
|
|
|
|
if (dstvms->quota_limit && dstvms->quota_usage >= dstvms->quota_limit) {
|
|
|
|
|
ast_log(LOG_NOTICE, "Mailbox '%s' is exceeded quota %u >= %u\n", mailbox_context, dstvms->quota_usage, dstvms->quota_limit);
|
|
|
|
|
res = ast_play_and_wait(chan, "vm-mailboxfull");
|
|
|
|
|
valid_extensions = 0;
|
|
|
|
|
while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list))) {
|
|
|
|
|
inprocess_count(vmtmp->mailbox, vmtmp->context, -1);
|
|
|
|
|
free_user(vmtmp);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
capacity = receiver->maxmsg - inprocess_count(receiver->mailbox, receiver->context, +1);
|
|
|
|
|
if ((newmsgs + oldmsgs) >= capacity) {
|
|
|
|
|
ast_log(LOG_NOTICE, "Mailbox '%s' is full with capacity of %d, prompting for another extension.\n", s, capacity);
|
|
|
|
|
ast_log(LOG_NOTICE, "Mailbox '%s' is full with capacity of %d, prompting for another extension.\n", mailbox_context, capacity);
|
|
|
|
|
res = ast_play_and_wait(chan, "vm-mailboxfull");
|
|
|
|
|
valid_extensions = 0;
|
|
|
|
|
while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list))) {
|
|
|
|
@ -8226,7 +8293,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);
|
|
|
|
|
ast_log(LOG_NOTICE, "'%s' is not a valid mailbox\n", mailbox_context);
|
|
|
|
|
/* "I am sorry, that's not a valid extension. Please try again." */
|
|
|
|
|
res = ast_play_and_wait(chan, "pbx-invalid");
|
|
|
|
|
valid_extensions = 0;
|
|
|
|
@ -8306,7 +8373,7 @@ static int forward_message(struct ast_channel *chan, char *context, struct vm_st
|
|
|
|
|
if (!dstvms->mailstream) {
|
|
|
|
|
ast_log(AST_LOG_ERROR, "IMAP mailstream for %s is NULL\n", vmtmp->mailbox);
|
|
|
|
|
} else {
|
|
|
|
|
copy_msg_result = STORE(vmstmp.curdir, vmtmp->mailbox, vmtmp->context, dstvms->curmsg, chan, vmtmp, fmt, duration, dstvms, urgent_str, msg_id);
|
|
|
|
|
copy_msg_result = STORE(vmstmp.curdir, vmtmp->mailbox, vmtmp->context, curmsg, chan, vmtmp, fmt, duration, dstvms, urgent_str, msg_id);
|
|
|
|
|
run_externnotify(vmtmp->context, vmtmp->mailbox, urgent_str);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
@ -8342,10 +8409,6 @@ static int forward_message(struct ast_channel *chan, char *context, struct vm_st
|
|
|
|
|
res = ast_play_and_wait(chan, "vm-messages");
|
|
|
|
|
if (!res)
|
|
|
|
|
res = ast_play_and_wait(chan, "vm-saved"); */
|
|
|
|
|
#ifdef IMAP_STORAGE
|
|
|
|
|
/* If forwarded with intro, DON'T PLAY THIS MESSAGE AGAIN! */
|
|
|
|
|
if (ast_strlen_zero(vmstmp.introfn))
|
|
|
|
|
#endif
|
|
|
|
|
res = ast_play_and_wait(chan, "vm-msgforwarded");
|
|
|
|
|
}
|
|
|
|
|
#ifndef IMAP_STORAGE
|
|
|
|
@ -8814,6 +8877,7 @@ static int imap_delete_old_greeting (char *dir, struct vm_state *vms)
|
|
|
|
|
char arg[10];
|
|
|
|
|
int i;
|
|
|
|
|
BODY* body;
|
|
|
|
|
int curr_mbox;
|
|
|
|
|
|
|
|
|
|
file = strrchr(ast_strdupa(dir), '/');
|
|
|
|
|
if (file) {
|
|
|
|
@ -8824,6 +8888,16 @@ static int imap_delete_old_greeting (char *dir, struct vm_state *vms)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ast_mutex_lock(&vms->lock);
|
|
|
|
|
|
|
|
|
|
/* get the current mailbox so that we can point the mailstream back to it later */
|
|
|
|
|
curr_mbox = get_folder_by_name(vms->curbox);
|
|
|
|
|
|
|
|
|
|
if (init_mailstream(vms, GREETINGS_FOLDER) || !vms->mailstream) {
|
|
|
|
|
ast_log(AST_LOG_ERROR, "IMAP mailstream is NULL or can't init_mailstream\n");
|
|
|
|
|
ast_mutex_unlock(&vms->lock);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < vms->mailstream->nmsgs; i++) {
|
|
|
|
|
mail_fetchstructure(vms->mailstream, i + 1, &body);
|
|
|
|
|
/* We have the body, now we extract the file name of the first attachment. */
|
|
|
|
@ -8841,6 +8915,14 @@ static int imap_delete_old_greeting (char *dir, struct vm_state *vms)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
mail_expunge(vms->mailstream);
|
|
|
|
|
|
|
|
|
|
if (curr_mbox != -1) {
|
|
|
|
|
/* restore previous mbox stream */
|
|
|
|
|
if (init_mailstream(vms, curr_mbox) || !vms->mailstream) {
|
|
|
|
|
ast_log(AST_LOG_ERROR, "IMAP mailstream is NULL or can't init_mailstream\n");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ast_mutex_unlock(&vms->lock);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
@ -10348,7 +10430,7 @@ static int vm_newuser(struct ast_channel *chan, struct ast_vm_user *vmu, struct
|
|
|
|
|
if (ast_test_flag(vmu, VM_FORCENAME)) {
|
|
|
|
|
snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username);
|
|
|
|
|
if (ast_fileexists(prefile, NULL, NULL) < 1) {
|
|
|
|
|
cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL, NULL);
|
|
|
|
|
cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL, NULL, 0);
|
|
|
|
|
if (cmd < 0 || cmd == 't' || cmd == '#')
|
|
|
|
|
return cmd;
|
|
|
|
|
}
|
|
|
|
@ -10358,14 +10440,14 @@ static int vm_newuser(struct ast_channel *chan, struct ast_vm_user *vmu, struct
|
|
|
|
|
if (ast_test_flag(vmu, VM_FORCEGREET)) {
|
|
|
|
|
snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username);
|
|
|
|
|
if (ast_fileexists(prefile, NULL, NULL) < 1) {
|
|
|
|
|
cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL, NULL);
|
|
|
|
|
cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL, NULL, 0);
|
|
|
|
|
if (cmd < 0 || cmd == 't' || cmd == '#')
|
|
|
|
|
return cmd;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username);
|
|
|
|
|
if (ast_fileexists(prefile, NULL, NULL) < 1) {
|
|
|
|
|
cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL, NULL);
|
|
|
|
|
cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL, NULL, 0);
|
|
|
|
|
if (cmd < 0 || cmd == 't' || cmd == '#')
|
|
|
|
|
return cmd;
|
|
|
|
|
}
|
|
|
|
@ -10447,15 +10529,15 @@ static int vm_options(struct ast_channel *chan, struct ast_vm_user *vmu, struct
|
|
|
|
|
switch (cmd) {
|
|
|
|
|
case '1': /* Record your unavailable message */
|
|
|
|
|
snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username);
|
|
|
|
|
cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL, NULL);
|
|
|
|
|
cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL, NULL, 0);
|
|
|
|
|
break;
|
|
|
|
|
case '2': /* Record your busy message */
|
|
|
|
|
snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username);
|
|
|
|
|
cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL, NULL);
|
|
|
|
|
cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL, NULL, 0);
|
|
|
|
|
break;
|
|
|
|
|
case '3': /* Record greeting */
|
|
|
|
|
snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username);
|
|
|
|
|
cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL, NULL);
|
|
|
|
|
cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL, NULL, 0);
|
|
|
|
|
break;
|
|
|
|
|
case '4': /* manage the temporary greeting */
|
|
|
|
|
cmd = vm_tempgreeting(chan, vmu, vms, fmtc, record_gain);
|
|
|
|
@ -10589,7 +10671,7 @@ static int vm_tempgreeting(struct ast_channel *chan, struct ast_vm_user *vmu, st
|
|
|
|
|
retries = 0;
|
|
|
|
|
RETRIEVE(prefile, -1, vmu->mailbox, vmu->context);
|
|
|
|
|
if (ast_fileexists(prefile, NULL, NULL) <= 0) {
|
|
|
|
|
cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL, NULL);
|
|
|
|
|
cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL, NULL, 0);
|
|
|
|
|
if (cmd == -1) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
@ -10597,7 +10679,7 @@ static int vm_tempgreeting(struct ast_channel *chan, struct ast_vm_user *vmu, st
|
|
|
|
|
} else {
|
|
|
|
|
switch (cmd) {
|
|
|
|
|
case '1':
|
|
|
|
|
cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL, NULL);
|
|
|
|
|
cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL, NULL, 0);
|
|
|
|
|
break;
|
|
|
|
|
case '2':
|
|
|
|
|
DELETE(prefile, -1, prefile, vmu);
|
|
|
|
@ -11876,7 +11958,13 @@ static int vm_execmain(struct ast_channel *chan, const char *data)
|
|
|
|
|
cmd = vm_options(chan, vmu, &vms, vmfmts, record_gain);
|
|
|
|
|
if (useadsi)
|
|
|
|
|
adsi_status(chan, &vms);
|
|
|
|
|
break;
|
|
|
|
|
/* Reopen play_folder */
|
|
|
|
|
res = open_mailbox(&vms, vmu, play_folder);
|
|
|
|
|
if (res < 0) {
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
vms.starting = 1;
|
|
|
|
|
break;
|
|
|
|
|
default: /* Nothing */
|
|
|
|
|
ast_test_suite_event_notify("PLAYBACK", "Message: instructions");
|
|
|
|
|
cmd = vm_instructions(chan, vmu, &vms, 0, in_urgent);
|
|
|
|
@ -15109,7 +15197,7 @@ static int advanced_options(struct ast_channel *chan, struct ast_vm_user *vmu, s
|
|
|
|
|
|
|
|
|
|
static int play_record_review(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt,
|
|
|
|
|
int outsidecaller, struct ast_vm_user *vmu, int *duration, int *sound_duration, const char *unlockdir,
|
|
|
|
|
signed char record_gain, struct vm_state *vms, char *flag, const char *msg_id)
|
|
|
|
|
signed char record_gain, struct vm_state *vms, char *flag, const char *msg_id, int forwardintro)
|
|
|
|
|
{
|
|
|
|
|
/* Record message & let caller review or re-record it, or set options if applicable */
|
|
|
|
|
int res = 0;
|
|
|
|
@ -15151,7 +15239,9 @@ static int play_record_review(struct ast_channel *chan, char *playfile, char *re
|
|
|
|
|
ast_verb(3, "Saving message as is\n");
|
|
|
|
|
if (!outsidecaller)
|
|
|
|
|
ast_filerename(tempfile, recordfile, NULL);
|
|
|
|
|
ast_stream_and_wait(chan, "vm-msgsaved", "");
|
|
|
|
|
if (!forwardintro) {
|
|
|
|
|
ast_stream_and_wait(chan, "vm-msgsaved", "");
|
|
|
|
|
}
|
|
|
|
|
if (!outsidecaller) {
|
|
|
|
|
/* Saves to IMAP server only if imapgreeting=yes */
|
|
|
|
|
STORE(recordfile, vmu->mailbox, vmu->context, -1, chan, vmu, fmt, *duration, vms, flag, msg_id);
|
|
|
|
@ -15174,7 +15264,11 @@ static int play_record_review(struct ast_channel *chan, char *playfile, char *re
|
|
|
|
|
ast_verb(3, "Recording the message\n");
|
|
|
|
|
|
|
|
|
|
if (recorded && outsidecaller) {
|
|
|
|
|
cmd = ast_play_and_wait(chan, INTRO);
|
|
|
|
|
if (forwardintro) {
|
|
|
|
|
cmd = ast_play_and_wait(chan, "vm-record-prepend");
|
|
|
|
|
} else {
|
|
|
|
|
cmd = ast_play_and_wait(chan, INTRO);
|
|
|
|
|
}
|
|
|
|
|
cmd = ast_play_and_wait(chan, "beep");
|
|
|
|
|
}
|
|
|
|
|
recorded = 1;
|
|
|
|
@ -15295,10 +15389,10 @@ static int play_record_review(struct ast_channel *chan, char *playfile, char *re
|
|
|
|
|
}
|
|
|
|
|
return cmd;
|
|
|
|
|
default:
|
|
|
|
|
/* If the caller is an ouside caller, and the review option is enabled,
|
|
|
|
|
/* If the caller is an ouside caller and the review option is enabled or it's forward intro
|
|
|
|
|
allow them to review the message, but let the owner of the box review
|
|
|
|
|
their OGM's */
|
|
|
|
|
if (outsidecaller && !ast_test_flag(vmu, VM_REVIEW))
|
|
|
|
|
if (outsidecaller && !ast_test_flag(vmu, VM_REVIEW) && !forwardintro)
|
|
|
|
|
return cmd;
|
|
|
|
|
if (msg_exists) {
|
|
|
|
|
cmd = ast_play_and_wait(chan, "vm-review");
|
|
|
|
|