Merged revisions 27636 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.2 ........ r27636 | tilghman | 2006-05-16 21:19:50 -0500 (Tue, 16 May 2006) | 2 lines Bug 7125 - Fix race condition between resequencing and leaving a message ........ git-svn-id: http://svn.digium.com/svn/asterisk/trunk@27637 f38db490-d61c-443f-a65b-d21fe96a405b
This commit is contained in:
parent
080ef129f8
commit
4cce0ae9f2
|
@ -2413,17 +2413,17 @@ struct leave_vm_options {
|
|||
|
||||
static int leave_voicemail(struct ast_channel *chan, char *ext, struct leave_vm_options *options)
|
||||
{
|
||||
char tmptxtfile[256], txtfile[256];
|
||||
char txtfile[256], tmptxtfile[256];
|
||||
char callerid[256];
|
||||
FILE *txt;
|
||||
int res = 0;
|
||||
int res = 0, txtdes;
|
||||
int msgnum;
|
||||
int duration = 0;
|
||||
int ausemacro = 0;
|
||||
int ousemacro = 0;
|
||||
int ouseexten = 0;
|
||||
char date[256];
|
||||
char dir[256];
|
||||
char dir[256], tmpdir[260];
|
||||
char fn[256];
|
||||
char prefile[256]="";
|
||||
char tempfile[256]="";
|
||||
|
@ -2475,6 +2475,7 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, struct leave_vm_
|
|||
DISPOSE(tempfile, -1);
|
||||
/* It's easier just to try to make it than to check for its existence */
|
||||
create_dirpath(dir, sizeof(dir), vmu->context, ext, "INBOX");
|
||||
create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, ext, "tmp");
|
||||
|
||||
/* Check current or macro-calling context for special extensions */
|
||||
if (ast_test_flag(vmu, VM_OPERATOR)) {
|
||||
|
@ -2579,121 +2580,129 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, struct leave_vm_
|
|||
if (!ast_strlen_zero(fmt)) {
|
||||
msgnum = 0;
|
||||
|
||||
if (vm_lock_path(dir)) {
|
||||
free_user(vmu);
|
||||
return ERROR_LOCK_PATH;
|
||||
if (count_messages(vmu, dir) >= vmu->maxmsg) {
|
||||
res = ast_streamfile(chan, "vm-mailboxfull", chan->language);
|
||||
if (!res)
|
||||
res = ast_waitstream(chan, "");
|
||||
ast_log(LOG_WARNING, "No more messages possible\n");
|
||||
pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
|
||||
goto leave_vm_out;
|
||||
}
|
||||
|
||||
/*
|
||||
* This operation can be very expensive if done say over NFS or if the mailbox has 100+ messages
|
||||
* in the folder. So we should get this first so we don't cut off the first few seconds of the
|
||||
* message.
|
||||
*/
|
||||
do {
|
||||
make_file(fn, sizeof(fn), dir, msgnum);
|
||||
if (!EXISTS(dir,msgnum,fn,chan->language))
|
||||
break;
|
||||
msgnum++;
|
||||
} while (msgnum < vmu->maxmsg);
|
||||
snprintf(tmptxtfile, sizeof(tmptxtfile), "%s/XXXXXX", tmpdir);
|
||||
txtdes = mkstemp(tmptxtfile);
|
||||
if (txtdes < 0) {
|
||||
res = ast_streamfile(chan, "vm-mailboxfull", chan->language);
|
||||
if (!res)
|
||||
res = ast_waitstream(chan, "");
|
||||
ast_log(LOG_ERROR, "Unable to create message file: %s\n", strerror(errno));
|
||||
pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
|
||||
goto leave_vm_out;
|
||||
}
|
||||
|
||||
/* Now play the beep once we have the message number for our next message. */
|
||||
if (res >= 0) {
|
||||
/* Unless we're *really* silent, try to send the beep */
|
||||
res = ast_stream_and_wait(chan, "beep", chan->language, "");
|
||||
}
|
||||
if (msgnum < vmu->maxmsg) {
|
||||
/* assign a variable with the name of the voicemail file */
|
||||
pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", fn);
|
||||
|
||||
/* Store information */
|
||||
snprintf(txtfile, sizeof(txtfile), "%s.txt", fn);
|
||||
snprintf(tmptxtfile, sizeof(tmptxtfile), "%s.txt.tmp", fn);
|
||||
txt = fopen(tmptxtfile, "w+");
|
||||
if (txt) {
|
||||
get_date(date, sizeof(date));
|
||||
fprintf(txt,
|
||||
";\n"
|
||||
"; Message Information file\n"
|
||||
";\n"
|
||||
"[message]\n"
|
||||
"origmailbox=%s\n"
|
||||
"context=%s\n"
|
||||
"macrocontext=%s\n"
|
||||
"exten=%s\n"
|
||||
"priority=%d\n"
|
||||
"callerchan=%s\n"
|
||||
"callerid=%s\n"
|
||||
"origdate=%s\n"
|
||||
"origtime=%ld\n"
|
||||
"category=%s\n",
|
||||
ext,
|
||||
chan->context,
|
||||
chan->macrocontext,
|
||||
chan->exten,
|
||||
chan->priority,
|
||||
chan->name,
|
||||
ast_callerid_merge(callerid, sizeof(callerid), chan->cid.cid_name, chan->cid.cid_num, "Unknown"),
|
||||
date, (long)time(NULL),
|
||||
category ? category : "");
|
||||
} else
|
||||
ast_log(LOG_WARNING, "Error opening text file for output\n");
|
||||
res = play_record_review(chan, NULL, fn, vmmaxmessage, fmt, 1, vmu, &duration, dir, options->record_gain);
|
||||
if (res == '0') {
|
||||
if (txt && EXISTS(dir,msgnum,fn,chan->language)) {
|
||||
fclose(txt);
|
||||
rename(tmptxtfile, txtfile);
|
||||
} else if (txt && !EXISTS(dir,msgnum,fn,chan->language)) {
|
||||
if (option_debug)
|
||||
ast_log(LOG_DEBUG, "The recorded media file is gone, so we should remove the .txt file too!\n");
|
||||
fclose(txt);
|
||||
unlink(tmptxtfile);
|
||||
}
|
||||
goto transfer;
|
||||
}
|
||||
if (res > 0)
|
||||
res = 0;
|
||||
if (txt) {
|
||||
fprintf(txt, "duration=%d\n", duration);
|
||||
fclose(txt);
|
||||
rename(tmptxtfile, txtfile);
|
||||
}
|
||||
|
||||
|
||||
/* Store information */
|
||||
txt = fdopen(txtdes, "w+");
|
||||
if (txt) {
|
||||
get_date(date, sizeof(date));
|
||||
fprintf(txt,
|
||||
";\n"
|
||||
"; Message Information file\n"
|
||||
";\n"
|
||||
"[message]\n"
|
||||
"origmailbox=%s\n"
|
||||
"context=%s\n"
|
||||
"macrocontext=%s\n"
|
||||
"exten=%s\n"
|
||||
"priority=%d\n"
|
||||
"callerchan=%s\n"
|
||||
"callerid=%s\n"
|
||||
"origdate=%s\n"
|
||||
"origtime=%ld\n"
|
||||
"category=%s\n",
|
||||
ext,
|
||||
chan->context,
|
||||
chan->macrocontext,
|
||||
chan->exten,
|
||||
chan->priority,
|
||||
chan->name,
|
||||
ast_callerid_merge(callerid, sizeof(callerid), chan->cid.cid_name, chan->cid.cid_num, "Unknown"),
|
||||
date, (long)time(NULL),
|
||||
category ? category : "");
|
||||
} 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);
|
||||
|
||||
if (txt) {
|
||||
if (duration < vmminmessage) {
|
||||
if (option_verbose > 2)
|
||||
ast_verbose( VERBOSE_PREFIX_3 "Recording was %d seconds long but needs to be at least %d - abandoning\n", duration, vmminmessage);
|
||||
DELETE(dir,msgnum,fn);
|
||||
/* XXX We should really give a prompt too short/option start again, with leave_vm_out called only after a timeout XXX */
|
||||
pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
|
||||
goto leave_vm_out;
|
||||
}
|
||||
/* Are there to be more recipients of this message? */
|
||||
while (tmpptr) {
|
||||
struct ast_vm_user recipu, *recip;
|
||||
char *exten, *context;
|
||||
|
||||
exten = strsep(&tmpptr, "&");
|
||||
context = strchr(exten, '@');
|
||||
if (context) {
|
||||
*context = '\0';
|
||||
context++;
|
||||
}
|
||||
if ((recip = find_user(&recipu, context, exten))) {
|
||||
copy_message(chan, vmu, 0, msgnum, duration, recip, fmt);
|
||||
free_user(recip);
|
||||
} else {
|
||||
fprintf(txt, "duration=%d\n", duration);
|
||||
fclose(txt);
|
||||
if (vm_lock_path(dir)) {
|
||||
ast_log(LOG_ERROR, "Couldn't lock directory %s. Voicemail will be lost.\n", dir);
|
||||
/* Delete files */
|
||||
ast_filedelete(tmptxtfile, NULL);
|
||||
unlink(tmptxtfile);
|
||||
} else {
|
||||
for (;;) {
|
||||
make_file(fn, sizeof(fn), dir, msgnum);
|
||||
if (!EXISTS(dir, msgnum, fn, NULL))
|
||||
break;
|
||||
msgnum++;
|
||||
}
|
||||
|
||||
/* assign a variable with the name of the voicemail file */
|
||||
pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", fn);
|
||||
|
||||
snprintf(txtfile, sizeof(txtfile), "%s.txt", fn);
|
||||
ast_filerename(tmptxtfile, fn, NULL);
|
||||
rename(tmptxtfile, txtfile);
|
||||
|
||||
ast_unlock_path(dir);
|
||||
|
||||
/* Are there to be more recipients of this message? */
|
||||
while (tmpptr) {
|
||||
struct ast_vm_user recipu, *recip;
|
||||
char *exten, *context;
|
||||
|
||||
exten = strsep(&tmpptr, "&");
|
||||
context = strchr(exten, '@');
|
||||
if (context) {
|
||||
*context = '\0';
|
||||
context++;
|
||||
}
|
||||
if ((recip = find_user(&recipu, context, exten))) {
|
||||
copy_message(chan, vmu, 0, msgnum, duration, recip, fmt);
|
||||
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);
|
||||
DISPOSE(dir, msgnum);
|
||||
}
|
||||
}
|
||||
}
|
||||
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);
|
||||
DISPOSE(dir, msgnum);
|
||||
}
|
||||
pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS");
|
||||
} else {
|
||||
ast_unlock_path(dir);
|
||||
res = ast_stream_and_wait(chan, "vm-mailboxfull", chan->language, "");
|
||||
ast_log(LOG_WARNING, "No more messages possible\n");
|
||||
pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
|
||||
}
|
||||
|
||||
if (res == '0') {
|
||||
goto transfer;
|
||||
} else if (res > 0)
|
||||
res = 0;
|
||||
|
||||
if (duration < vmminmessage)
|
||||
/* XXX We should really give a prompt too short/option start again, with leave_vm_out called only after a timeout XXX */
|
||||
pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
|
||||
else
|
||||
pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS");
|
||||
} else
|
||||
ast_log(LOG_WARNING, "No format for saving voicemail?\n");
|
||||
leave_vm_out:
|
||||
|
|
Reference in New Issue