[asterisk-commits] tilghman: branch 1.6.0 r193871 - in /branches/1.6.0: ./ apps/app_voicemail.c
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue May 12 12:47:19 CDT 2009
Author: tilghman
Date: Tue May 12 12:47:16 2009
New Revision: 193871
URL: http://svn.asterisk.org/svn-view/asterisk?view=rev&rev=193871
Log:
Merged revisions 193870 via svnmerge from
https://origsvn.digium.com/svn/asterisk/trunk
........
r193870 | tilghman | 2009-05-12 12:29:33 -0500 (Tue, 12 May 2009) | 2 lines
Convert a THREADSTORAGE object into a simple malloc'd object (as suggested by Russell on -dev)
........
Modified:
branches/1.6.0/ (props changed)
branches/1.6.0/apps/app_voicemail.c
Propchange: branches/1.6.0/
------------------------------------------------------------------------------
Binary property 'trunk-merged' - no diff available.
Modified: branches/1.6.0/apps/app_voicemail.c
URL: http://svn.asterisk.org/svn-view/asterisk/branches/1.6.0/apps/app_voicemail.c?view=diff&rev=193871&r1=193870&r2=193871
==============================================================================
--- branches/1.6.0/apps/app_voicemail.c (original)
+++ branches/1.6.0/apps/app_voicemail.c Tue May 12 12:47:16 2009
@@ -226,8 +226,6 @@
#define ERROR_LOCK_PATH -100
#define ERROR_MAILBOX_FULL -200
-
-AST_THREADSTORAGE(voicemail_extension_list);
enum {
NEW_FOLDER,
@@ -4255,424 +4253,449 @@
}
}
- struct leave_vm_options {
- unsigned int flags;
- signed char record_gain;
- char *exitcontext;
- };
-
- static int leave_voicemail(struct ast_channel *chan, char *ext, struct leave_vm_options *options)
- {
+struct leave_vm_options {
+ unsigned int flags;
+ signed char record_gain;
+ char *exitcontext;
+};
+
+static int leave_voicemail(struct ast_channel *chan, char *ext, struct leave_vm_options *options)
+{
#ifdef IMAP_STORAGE
- int newmsgs, oldmsgs;
+ int newmsgs, oldmsgs;
#endif
- char txtfile[PATH_MAX], tmptxtfile[PATH_MAX];
- struct vm_state *vms = NULL;
- char callerid[256];
- FILE *txt;
- char date[256];
- int txtdes;
- int res = 0;
- int msgnum;
- int duration = 0;
- int ausemacro = 0;
- int ousemacro = 0;
- int ouseexten = 0;
- int rtmsgid = 0;
- char tmpid[16];
- char tmpdur[16];
- char priority[16];
- char origtime[16];
- char dir[PATH_MAX], tmpdir[PATH_MAX];
- char fn[PATH_MAX];
- char prefile[PATH_MAX] = "";
- char tempfile[PATH_MAX] = "";
- char ext_context[256] = "";
- char fmt[80];
- char *context;
- char ecodes[17] = "#";
- char *tmpptr;
- struct ast_str *tmp = ast_str_thread_get(&voicemail_extension_list, 16);
- struct ast_vm_user *vmu;
- struct ast_vm_user svm;
- const char *category = NULL, *code, *alldtmf = "0123456789ABCD*#";
-
- ast_str_set(&tmp, 0, "%s", ext);
- ext = ast_str_buffer(tmp);
- if ((context = strchr(ext, '@'))) {
- *context++ = '\0';
- tmpptr = strchr(context, '&');
- } else {
- tmpptr = strchr(ext, '&');
- }
-
- if (tmpptr)
- *tmpptr++ = '\0';
-
- category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY");
-
- ast_debug(3, "Before find_user\n");
- if (!(vmu = find_user(&svm, context, ext))) {
- ast_log(LOG_WARNING, "No entry in voicemail config file for '%s'\n", ext);
- pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
- return res;
- }
- /* Setup pre-file if appropriate */
- if (strcmp(vmu->context, "default"))
- snprintf(ext_context, sizeof(ext_context), "%s@%s", ext, vmu->context);
- else
- ast_copy_string(ext_context, vmu->mailbox, sizeof(ext_context));
- if (ast_test_flag(options, OPT_BUSY_GREETING)) {
- snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, ext);
- } else if (ast_test_flag(options, OPT_UNAVAIL_GREETING)) {
- snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, ext);
- }
- snprintf(tempfile, sizeof(tempfile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, ext);
- if ((res = create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, ext, "tmp"))) {
- ast_log(LOG_WARNING, "Failed to make directory (%s)\n", tempfile);
- return -1;
- }
- RETRIEVE(tempfile, -1, vmu->mailbox, vmu->context);
- if (ast_fileexists(tempfile, NULL, NULL) > 0)
- ast_copy_string(prefile, tempfile, sizeof(prefile));
- 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");
-
- /* Check current or macro-calling context for special extensions */
- if (ast_test_flag(vmu, VM_OPERATOR)) {
- if (!ast_strlen_zero(vmu->exit)) {
- if (ast_exists_extension(chan, vmu->exit, "o", 1, chan->cid.cid_num)) {
- strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
- ouseexten = 1;
- }
- } else if (ast_exists_extension(chan, chan->context, "o", 1, chan->cid.cid_num)) {
+ char txtfile[PATH_MAX], tmptxtfile[PATH_MAX];
+ struct vm_state *vms = NULL;
+ char callerid[256];
+ FILE *txt;
+ char date[256];
+ int txtdes;
+ int res = 0;
+ int msgnum;
+ int duration = 0;
+ int ausemacro = 0;
+ int ousemacro = 0;
+ int ouseexten = 0;
+ int rtmsgid = 0;
+ char tmpid[16];
+ char tmpdur[16];
+ char priority[16];
+ char origtime[16];
+ char dir[PATH_MAX], tmpdir[PATH_MAX];
+ char fn[PATH_MAX];
+ char prefile[PATH_MAX] = "";
+ char tempfile[PATH_MAX] = "";
+ char ext_context[256] = "";
+ char fmt[80];
+ char *context;
+ char ecodes[17] = "#";
+ char *tmpptr;
+ struct ast_str *tmp = ast_str_create(16);
+ struct ast_vm_user *vmu;
+ struct ast_vm_user svm;
+ const char *category = NULL, *code, *alldtmf = "0123456789ABCD*#";
+
+ ast_str_set(&tmp, 0, "%s", ext);
+ ext = ast_str_buffer(tmp);
+ if ((context = strchr(ext, '@'))) {
+ *context++ = '\0';
+ tmpptr = strchr(context, '&');
+ } else {
+ tmpptr = strchr(ext, '&');
+ }
+
+ if (tmpptr) {
+ *tmpptr++ = '\0';
+ }
+
+ category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY");
+
+ ast_debug(3, "Before find_user\n");
+ if (!(vmu = find_user(&svm, context, ext))) {
+ ast_log(LOG_WARNING, "No entry in voicemail config file for '%s'\n", ext);
+ pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
+ ast_free(tmp);
+ return res;
+ }
+ /* Setup pre-file if appropriate */
+ if (strcmp(vmu->context, "default")) {
+ snprintf(ext_context, sizeof(ext_context), "%s@%s", ext, vmu->context);
+ } else {
+ ast_copy_string(ext_context, vmu->mailbox, sizeof(ext_context));
+ }
+ if (ast_test_flag(options, OPT_BUSY_GREETING)) {
+ snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, ext);
+ } else if (ast_test_flag(options, OPT_UNAVAIL_GREETING)) {
+ snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, ext);
+ }
+ snprintf(tempfile, sizeof(tempfile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, ext);
+ if ((res = create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, ext, "tmp"))) {
+ ast_log(LOG_WARNING, "Failed to make directory (%s)\n", tempfile);
+ ast_free(tmp);
+ return -1;
+ }
+ RETRIEVE(tempfile, -1, vmu->mailbox, vmu->context);
+ if (ast_fileexists(tempfile, NULL, NULL) > 0) {
+ ast_copy_string(prefile, tempfile, sizeof(prefile));
+ }
+ 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");
+
+ /* Check current or macro-calling context for special extensions */
+ if (ast_test_flag(vmu, VM_OPERATOR)) {
+ if (!ast_strlen_zero(vmu->exit)) {
+ if (ast_exists_extension(chan, vmu->exit, "o", 1, chan->cid.cid_num)) {
strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
ouseexten = 1;
- } else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "o", 1, chan->cid.cid_num)) {
- strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
- ousemacro = 1;
- }
- }
-
- if (!ast_strlen_zero(vmu->exit)) {
- if (ast_exists_extension(chan, vmu->exit, "a", 1, chan->cid.cid_num))
- strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
- } else if (ast_exists_extension(chan, chan->context, "a", 1, chan->cid.cid_num))
+ }
+ } else if (ast_exists_extension(chan, chan->context, "o", 1, chan->cid.cid_num)) {
+ strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
+ ouseexten = 1;
+ } else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "o", 1, chan->cid.cid_num)) {
+ strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
+ ousemacro = 1;
+ }
+ }
+
+ if (!ast_strlen_zero(vmu->exit)) {
+ if (ast_exists_extension(chan, vmu->exit, "a", 1, chan->cid.cid_num)) {
strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
- else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "a", 1, chan->cid.cid_num)) {
- strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
- ausemacro = 1;
- }
-
- if (ast_test_flag(options, OPT_DTMFEXIT)) {
- for (code = alldtmf; *code; code++) {
- char e[2] = "";
- e[0] = *code;
- if (strchr(ecodes, e[0]) == NULL && ast_canmatch_extension(chan, chan->context, e, 1, chan->cid.cid_num))
- strncat(ecodes, e, sizeof(ecodes) - strlen(ecodes) - 1);
- }
- }
-
- /* Play the beginning intro if desired */
- if (!ast_strlen_zero(prefile)) {
- res = play_greeting(chan, vmu, prefile, ecodes);
- if (res == -2) {
- /* The file did not exist */
- ast_debug(1, "%s doesn't exist, doing what we can\n", prefile);
- res = invent_message(chan, vmu, ext, ast_test_flag(options, OPT_BUSY_GREETING), ecodes);
- }
- if (res < 0) {
- ast_debug(1, "Hang up during prefile playback\n");
- free_user(vmu);
- pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
- return -1;
- }
- }
+ }
+ } else if (ast_exists_extension(chan, chan->context, "a", 1, chan->cid.cid_num)) {
+ strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
+ } else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "a", 1, chan->cid.cid_num)) {
+ strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
+ ausemacro = 1;
+ }
+
+ if (ast_test_flag(options, OPT_DTMFEXIT)) {
+ for (code = alldtmf; *code; code++) {
+ char e[2] = "";
+ e[0] = *code;
+ if (strchr(ecodes, e[0]) == NULL && ast_canmatch_extension(chan, chan->context, e, 1, chan->cid.cid_num)) {
+ strncat(ecodes, e, sizeof(ecodes) - strlen(ecodes) - 1);
+ }
+ }
+ }
+
+ /* Play the beginning intro if desired */
+ if (!ast_strlen_zero(prefile)) {
+ res = play_greeting(chan, vmu, prefile, ecodes);
+ if (res == -2) {
+ /* The file did not exist */
+ ast_debug(1, "%s doesn't exist, doing what we can\n", prefile);
+ res = invent_message(chan, vmu, ext, ast_test_flag(options, OPT_BUSY_GREETING), ecodes);
+ }
+ if (res < 0) {
+ ast_debug(1, "Hang up during prefile playback\n");
+ free_user(vmu);
+ pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
+ ast_free(tmp);
+ return -1;
+ }
+ }
+ if (res == '#') {
+ /* On a '#' we skip the instructions */
+ ast_set_flag(options, OPT_SILENT);
+ res = 0;
+ }
+ if (!res && !ast_test_flag(options, OPT_SILENT)) {
+ res = ast_stream_and_wait(chan, INTRO, ecodes);
if (res == '#') {
- /* On a '#' we skip the instructions */
ast_set_flag(options, OPT_SILENT);
res = 0;
}
- if (!res && !ast_test_flag(options, OPT_SILENT)) {
- res = ast_stream_and_wait(chan, INTRO, ecodes);
- if (res == '#') {
- ast_set_flag(options, OPT_SILENT);
- res = 0;
- }
- }
- if (res > 0)
- ast_stopstream(chan);
- /* Check for a '*' here in case the caller wants to escape from voicemail to something
- other than the operator -- an automated attendant or mailbox login for example */
- if (res == '*') {
- chan->exten[0] = 'a';
+ }
+ if (res > 0) {
+ ast_stopstream(chan);
+ }
+ /* Check for a '*' here in case the caller wants to escape from voicemail to something
+ * other than the operator -- an automated attendant or mailbox login for example */
+ if (res == '*') {
+ chan->exten[0] = 'a';
+ chan->exten[1] = '\0';
+ if (!ast_strlen_zero(vmu->exit)) {
+ ast_copy_string(chan->context, vmu->exit, sizeof(chan->context));
+ } else if (ausemacro && !ast_strlen_zero(chan->macrocontext)) {
+ ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context));
+ }
+ chan->priority = 0;
+ free_user(vmu);
+ pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT");
+ ast_free(tmp);
+ return 0;
+ }
+
+ /* Check for a '0' here */
+ if (ast_test_flag(vmu, VM_OPERATOR) && res == '0') {
+transfer:
+ if (ouseexten || ousemacro) {
+ chan->exten[0] = 'o';
chan->exten[1] = '\0';
if (!ast_strlen_zero(vmu->exit)) {
ast_copy_string(chan->context, vmu->exit, sizeof(chan->context));
- } else if (ausemacro && !ast_strlen_zero(chan->macrocontext)) {
+ } else if (ousemacro && !ast_strlen_zero(chan->macrocontext)) {
ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context));
}
+ ast_play_and_wait(chan, "transfer");
chan->priority = 0;
free_user(vmu);
pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT");
- return 0;
- }
-
- /* Check for a '0' here */
- if (ast_test_flag(vmu, VM_OPERATOR) && res == '0') {
- transfer:
- if (ouseexten || ousemacro) {
- chan->exten[0] = 'o';
- chan->exten[1] = '\0';
- if (!ast_strlen_zero(vmu->exit)) {
- ast_copy_string(chan->context, vmu->exit, sizeof(chan->context));
- } else if (ousemacro && !ast_strlen_zero(chan->macrocontext)) {
- ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context));
+ }
+ ast_free(tmp);
+ return 0;
+ }
+
+ /* Allow all other digits to exit Voicemail and return to the dialplan */
+ if (ast_test_flag(options, OPT_DTMFEXIT) && res > 0) {
+ if (!ast_strlen_zero(options->exitcontext)) {
+ ast_copy_string(chan->context, options->exitcontext, sizeof(chan->context));
+ }
+ free_user(vmu);
+ pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT");
+ return res;
+ }
+
+ if (res < 0) {
+ free_user(vmu);
+ pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
+ ast_free(tmp);
+ return -1;
+ }
+ /* The meat of recording the message... All the announcements and beeps have been played*/
+ ast_copy_string(fmt, vmfmts, sizeof(fmt));
+ if (!ast_strlen_zero(fmt)) {
+ msgnum = 0;
+
+#ifdef IMAP_STORAGE
+ /* Is ext a mailbox? */
+ /* must open stream for this user to get info! */
+ res = inboxcount(ext_context, &newmsgs, &oldmsgs);
+ if (res < 0) {
+ ast_log(LOG_NOTICE, "Can not leave voicemail, unable to count messages\n");
+ ast_free(tmp);
+ return -1;
+ }
+ if (!(vms = get_vm_state_by_mailbox(ext, 0))) {
+ /* It is possible under certain circumstances that inboxcount did not
+ * create a vm_state when it was needed. This is a catchall which will
+ * rarely be used.
+ */
+ if (!(vms = create_vm_state_from_user(vmu))) {
+ ast_log(LOG_ERROR, "Couldn't allocate necessary space\n");
+ ast_free(tmp);
+ return -1;
+ }
+ }
+ vms->newmessages++;
+
+ /* here is a big difference! We add one to it later */
+ msgnum = newmsgs + oldmsgs;
+ ast_debug(3, "Messagecount set to %d\n", msgnum);
+ snprintf(fn, sizeof(fn), "%s/imap/msg%s%04d", VM_SPOOL_DIR, vmu->mailbox, msgnum);
+ /* set variable for compatibility */
+ pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE");
+
+ /* Check if mailbox is full */
+ check_quota(vms, imapfolder);
+ if (vms->quota_limit && vms->quota_usage >= vms->quota_limit) {
+ ast_debug(1, "*** QUOTA EXCEEDED!! %u >= %u\n", vms->quota_usage, vms->quota_limit);
+ ast_play_and_wait(chan, "vm-mailboxfull");
+ ast_free(tmp);
+ return -1;
+ }
+
+ /* Check if we have exceeded maxmsg */
+ if (msgnum >= vmu->maxmsg) {
+ ast_log(LOG_WARNING, "Unable to leave message since we will exceed the maximum number of messages allowed (%u > %u)\n", msgnum, vmu->maxmsg);
+ ast_play_and_wait(chan, "vm-mailboxfull");
+ ast_free(tmp);
+ return -1;
+ }
+#else
+ 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;
+ }
+
+#endif
+ snprintf(tmptxtfile, sizeof(tmptxtfile), "%s/XXXXXX", tmpdir);
+ txtdes = mkstemp(tmptxtfile);
+ chmod(tmptxtfile, VOICEMAIL_FILE_MODE & ~my_umask);
+ 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", "");
+ }
+
+ /* Store information in real-time storage */
+ if (ast_check_realtime("voicemail_data")) {
+ snprintf(priority, sizeof(priority), "%d", chan->priority);
+ snprintf(origtime, sizeof(origtime), "%ld", (long)time(NULL));
+ get_date(date, sizeof(date));
+ rtmsgid = ast_store_realtime("voicemail_data", "origmailbox", ext, "context", chan->context, "macrocontext", chan->macrocontext, "exten", chan->exten, "priority", priority, "callerchan", chan->name, "callerid", ast_callerid_merge(callerid, sizeof(callerid), chan->cid.cid_name, chan->cid.cid_num, "Unknown"), "origdate", date, "origtime", origtime, "category", category ? category : "", NULL);
+ }
+
+ /* 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), S_OR(chan->cid.cid_name, NULL), S_OR(chan->cid.cid_num, NULL), "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, vmu->maxsecs, fmt, 1, vmu, &duration, NULL, options->record_gain, vms);
+
+ if (txt) {
+ if (duration < vmminsecs) {
+ fclose(txt);
+ ast_verb(3, "Recording was %d seconds long but needs to be at least %d - abandoning\n", duration, vmminsecs);
+ ast_filedelete(tmptxtfile, NULL);
+ unlink(tmptxtfile);
+ if (ast_check_realtime("voicemail_data")) {
+ snprintf(tmpid, sizeof(tmpid), "%d", rtmsgid);
+ ast_destroy_realtime("voicemail_data", "id", tmpid, NULL);
}
- ast_play_and_wait(chan, "transfer");
- chan->priority = 0;
- free_user(vmu);
- pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT");
- }
- return 0;
- }
-
- /* Allow all other digits to exit Voicemail and return to the dialplan */
- if (ast_test_flag(options, OPT_DTMFEXIT) && res > 0) {
- if (!ast_strlen_zero(options->exitcontext))
- ast_copy_string(chan->context, options->exitcontext, sizeof(chan->context));
- free_user(vmu);
- pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT");
- return res;
- }
-
- if (res < 0) {
- free_user(vmu);
- pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
- return -1;
- }
- /* The meat of recording the message... All the announcements and beeps have been played*/
- ast_copy_string(fmt, vmfmts, sizeof(fmt));
- if (!ast_strlen_zero(fmt)) {
- msgnum = 0;
-
-#ifdef IMAP_STORAGE
- /* Is ext a mailbox? */
- /* must open stream for this user to get info! */
- res = inboxcount(ext_context, &newmsgs, &oldmsgs);
- if (res < 0) {
- ast_log(LOG_NOTICE, "Can not leave voicemail, unable to count messages\n");
- return -1;
- }
- if (!(vms = get_vm_state_by_mailbox(ext, 0))) {
- /* It is possible under certain circumstances that inboxcount did not
- * create a vm_state when it was needed. This is a catchall which will
- * rarely be used.
- */
- if (!(vms = create_vm_state_from_user(vmu))) {
- ast_log(LOG_ERROR, "Couldn't allocate necessary space\n");
- return -1;
- }
- }
- vms->newmessages++;
-
- /* here is a big difference! We add one to it later */
- msgnum = newmsgs + oldmsgs;
- ast_debug(3, "Messagecount set to %d\n", msgnum);
- snprintf(fn, sizeof(fn), "%s/imap/msg%s%04d", VM_SPOOL_DIR, vmu->mailbox, msgnum);
- /* set variable for compatibility */
- pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE");
-
- /* Check if mailbox is full */
- check_quota(vms, imapfolder);
- if (vms->quota_limit && vms->quota_usage >= vms->quota_limit) {
- ast_debug(1, "*** QUOTA EXCEEDED!! %u >= %u\n", vms->quota_usage, vms->quota_limit);
- ast_play_and_wait(chan, "vm-mailboxfull");
- return -1;
- }
-
- /* Check if we have exceeded maxmsg */
- if (msgnum >= vmu->maxmsg) {
- ast_log(LOG_WARNING, "Unable to leave message since we will exceed the maximum number of messages allowed (%u > %u)\n", msgnum, vmu->maxmsg);
- ast_play_and_wait(chan, "vm-mailboxfull");
- return -1;
- }
-#else
- 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;
- }
-
-#endif
- snprintf(tmptxtfile, sizeof(tmptxtfile), "%s/XXXXXX", tmpdir);
- txtdes = mkstemp(tmptxtfile);
- chmod(tmptxtfile, VOICEMAIL_FILE_MODE & ~my_umask);
- 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", "");
- }
-
- /* Store information in real-time storage */
- if (ast_check_realtime("voicemail_data")) {
- snprintf(priority, sizeof(priority), "%d", chan->priority);
- snprintf(origtime, sizeof(origtime), "%ld", (long)time(NULL));
- get_date(date, sizeof(date));
- rtmsgid = ast_store_realtime("voicemail_data", "origmailbox", ext, "context", chan->context, "macrocontext", chan->macrocontext, "exten", chan->exten, "priority", priority, "callerchan", chan->name, "callerid", ast_callerid_merge(callerid, sizeof(callerid), chan->cid.cid_name, chan->cid.cid_num, "Unknown"), "origdate", date, "origtime", origtime, "category", category ? category : "", NULL);
- }
-
- /* 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), S_OR(chan->cid.cid_name, NULL), S_OR(chan->cid.cid_num, NULL), "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, vmu->maxsecs, fmt, 1, vmu, &duration, NULL, options->record_gain, vms);
-
- if (txt) {
- if (duration < vmminsecs) {
- fclose(txt);
- ast_verb(3, "Recording was %d seconds long but needs to be at least %d - abandoning\n", duration, vmminsecs);
+ } 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 if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) {
+ ast_debug(1, "The recorded media file is gone, so we should remove the .txt file too!\n");
+ unlink(tmptxtfile);
+ ast_unlock_path(dir);
if (ast_check_realtime("voicemail_data")) {
snprintf(tmpid, sizeof(tmpid), "%d", rtmsgid);
ast_destroy_realtime("voicemail_data", "id", tmpid, NULL);
}
} 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 if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) {
- ast_debug(1, "The recorded media file is gone, so we should remove the .txt file too!\n");
- unlink(tmptxtfile);
- ast_unlock_path(dir);
- if (ast_check_realtime("voicemail_data")) {
- snprintf(tmpid, sizeof(tmpid), "%d", rtmsgid);
- ast_destroy_realtime("voicemail_data", "id", tmpid, NULL);
+#ifndef IMAP_STORAGE
+ msgnum = last_message_index(vmu, dir) + 1;
+#endif
+ make_file(fn, sizeof(fn), dir, msgnum);
+
+ /* assign a variable with the name of the voicemail file */
+#ifndef IMAP_STORAGE
+ pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", fn);
+#else
+ pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE");
+#endif
+
+ snprintf(txtfile, sizeof(txtfile), "%s.txt", fn);
+ ast_filerename(tmptxtfile, fn, NULL);
+ rename(tmptxtfile, txtfile);
+
+ /* Properly set permissions on voicemail text descriptor file.
+ Unfortunately mkstemp() makes this file 0600 on most unix systems. */
+ if (chmod(txtfile, VOICEMAIL_FILE_MODE) < 0) {
+ ast_log(LOG_ERROR, "Couldn't set permissions on voicemail text file %s: %s", txtfile, strerror(errno));
+ }
+
+ ast_unlock_path(dir);
+ if (ast_check_realtime("voicemail_data")) {
+ snprintf(tmpid, sizeof(tmpid), "%d", rtmsgid);
+ snprintf(tmpdur, sizeof(tmpdur), "%d", duration);
+ ast_update_realtime("voicemail_data", "id", tmpid, "filename", fn, "duration", tmpdur, NULL);
+ }
+ /* We must store the file first, before copying the message, because
+ * 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);
+ }
+
+ /* 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++;
}
- } else {
-#ifndef IMAP_STORAGE
- msgnum = last_message_index(vmu, dir) + 1;
-#endif
- make_file(fn, sizeof(fn), dir, msgnum);
-
- /* assign a variable with the name of the voicemail file */
-#ifndef IMAP_STORAGE
- pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", fn);
-#else
- pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE");
-#endif
-
- snprintf(txtfile, sizeof(txtfile), "%s.txt", fn);
- ast_filerename(tmptxtfile, fn, NULL);
- rename(tmptxtfile, txtfile);
-
- /* Properly set permissions on voicemail text descriptor file.
- Unfortunately mkstemp() makes this file 0600 on most unix systems. */
- if (chmod(txtfile, VOICEMAIL_FILE_MODE) < 0)
- ast_log(LOG_ERROR, "Couldn't set permissions on voicemail text file %s: %s", txtfile, strerror(errno));
-
- ast_unlock_path(dir);
- if (ast_check_realtime("voicemail_data")) {
- snprintf(tmpid, sizeof(tmpid), "%d", rtmsgid);
- snprintf(tmpdur, sizeof(tmpdur), "%d", duration);
- ast_update_realtime("voicemail_data", "id", tmpid, "filename", fn, "duration", tmpdur, NULL);
- }
- /* We must store the file first, before copying the message, because
- * 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);
- }
-
- /* 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, dir);
- free_user(recip);
- }
- }
- /* Notification and disposal needs to happen after the copy, though. */
- if (ast_fileexists(fn, NULL, NULL)) {
-#ifdef IMAP_STORAGE
- notify_new_message(chan, vmu, vms, msgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL));
-#else
- notify_new_message(chan, vmu, NULL, msgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL));
-#endif
- DISPOSE(dir, msgnum);
+ if ((recip = find_user(&recipu, context, exten))) {
+ copy_message(chan, vmu, 0, msgnum, duration, recip, fmt, dir);
+ free_user(recip);
}
}
+ /* Notification and disposal needs to happen after the copy, though. */
+ if (ast_fileexists(fn, NULL, NULL)) {
+#ifdef IMAP_STORAGE
+ notify_new_message(chan, vmu, vms, msgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL));
+#else
+ notify_new_message(chan, vmu, NULL, msgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL));
+#endif
+ DISPOSE(dir, msgnum);
+ }
}
}
- if (res == '0') {
- goto transfer;
- } else if (res > 0)
- res = 0;
-
- if (duration < vmminsecs)
- /* 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:
- free_user(vmu);
-
- return res;
- }
+ }
+ if (res == '0') {
+ goto transfer;
+ } else if (res > 0) {
+ res = 0;
+ }
+
+ if (duration < vmminsecs) {
+ /* 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:
+ free_user(vmu);
+
+ ast_free(tmp);
+ return res;
+}
#ifndef IMAP_STORAGE
static int resequence_mailbox(struct ast_vm_user *vmu, char *dir)
More information about the asterisk-commits
mailing list