Update of /usr/cvsroot/asterisk/apps
In directory mongoose.digium.com:/tmp/cvs-serv12474/apps

Modified Files:
        app_voicemail.c 
Log Message:
fix voicemail path locking problems (bug #4245)


Index: app_voicemail.c
===================================================================
RCS file: /usr/cvsroot/asterisk/apps/app_voicemail.c,v
retrieving revision 1.222
retrieving revision 1.223
diff -u -d -r1.222 -r1.223
--- app_voicemail.c     11 Jul 2005 23:13:11 -0000      1.222
+++ app_voicemail.c     12 Jul 2005 01:04:54 -0000      1.223
@@ -13,6 +13,9 @@
  * 12-16 - 2005 : Support for Greek added by InAccess Networks (work funded by 
HOL, www.hol.gr)
  *                              George Konstantoulakis <[EMAIL PROTECTED]>
  * 05-10 - 2005 : Support for Swedish and Norwegian added by Daniel Nylander, 
http://www.danielnylander.se/
+ *
+ * 07-11 - 2005 : An issue with voicemail synchronization has been fixed by 
GDS Partners (www.gdspartners.com)
+ *                              Stojan Sljivic <[EMAIL PROTECTED]>
  */
 
 #include <stdlib.h>
@@ -88,6 +91,8 @@
 #define VM_DELETE              (1 << 12)
 #define VM_ALLOCED             (1 << 13)
 
+#define ERROR_LOCK_PATH                -100
+
 static int load_config(void);
 
 /* Syntaxes supported, not really language codes.
@@ -252,6 +257,8 @@
 "extension 'a' in the current context.\n"
 "If the requested mailbox does not exist, and there exists a priority\n"
 "n + 101, then that priority will be taken next.\n"
+"If an error occur in the voicemail application resulting in that the message 
cannot be left,\n" 
+"and there exists a priority n + 101, then that priority will be taken next.\n"
 "When multiple mailboxes are specified, the unavailable or busy message\n"
 "will be taken from the first mailbox specified.\n"
 "Returns -1 on error or mailbox not found, or if the user hangs up.\n"
@@ -953,11 +960,17 @@
        return x;
 }
 
-
+/*
+ * A negative return value indicates an error.
+ */
 static int count_messages(char *dir)
 {
-       return last_message_index(dir) + 1;
+       int res = 0;
+       
+       res = last_message_index(dir);
+       return res >= 0 ? res + 1 : res;
 }
+
 static void delete_file(char *sdir, int smsg)
 {
        int res;
@@ -1229,18 +1242,23 @@
        DIR *vmdir = NULL;
        struct dirent *vment = NULL;
 
-       if ((vmdir = opendir(dir))) {
-               while ((vment = readdir(vmdir)))
-               {
-                       if (strlen(vment->d_name) > 7 && !strncmp(vment->d_name 
+ 7,".txt",4))
+       if (!ast_lock_path(dir)) {
+               if ((vmdir = opendir(dir))) {
+                       while ((vment = readdir(vmdir)))
                        {
-                               vmcount++;
+                               if (strlen(vment->d_name) > 7 && 
!strncmp(vment->d_name + 7,".txt",4))
+                               {
+                                       vmcount++;
+                               }
                        }
+                       closedir(vmdir);
                }
-               closedir(vmdir);
-       }
+               ast_unlock_path(dir);
 
-       return vmcount;
+               return vmcount;
+       } else {
+               return ERROR_LOCK_PATH;
+       }
 }
 
 static void rename_file(char *sfn, char *dfn)
@@ -1312,18 +1330,24 @@
        copy(frompath2, topath2);
 }
 
+/*
+ * A negative return value indicates an error.
+ */
 static int last_message_index(char *dir)
 {
        int x;
        char fn[256];
-       ast_lock_path(dir);
-       for (x=0;x<MAXMSG;x++) {
-               make_file(fn, sizeof(fn), dir, x);
-               if (ast_fileexists(fn, NULL, NULL) < 1)
-                       break;
+       if (!ast_lock_path(dir)) {
+               for (x=0;x<MAXMSG;x++) {
+                       make_file(fn, sizeof(fn), dir, x);
+                       if (ast_fileexists(fn, NULL, NULL) < 1)
+                               break;
+               }
+               ast_unlock_path(dir);
+               return x-1;
+       } else {
+               return ERROR_LOCK_PATH;
        }
-       ast_unlock_path(dir);
-       return x-1;
 }
 
 static int vm_delete(char *file)
@@ -1934,7 +1958,7 @@
 
 static int notify_new_message(struct ast_channel *chan, struct ast_vm_user 
*vmu, int msgnum, long duration, char *fmt, char *cidnum, char *cidname);
 
-static void copy_message(struct ast_channel *chan, struct ast_vm_user *vmu, 
int imbox, int msgnum, long duration, struct ast_vm_user *recip, char *fmt)
+static int copy_message(struct ast_channel *chan, struct ast_vm_user *vmu, int 
imbox, int msgnum, long duration, struct ast_vm_user *recip, char *fmt)
 {
        char fromdir[256], todir[256], frompath[256], topath[256];
        char *frombox = mbox(imbox);
@@ -1956,21 +1980,26 @@
 
        make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox);
        make_file(frompath, sizeof(frompath), fromdir, msgnum);
-       ast_lock_path(topath);
-       recipmsgnum = 0;
-       do {
-               make_file(topath, sizeof(topath), todir, recipmsgnum);
-               if (!EXISTS(todir, recipmsgnum, topath, chan->language))
-                       break;
-               recipmsgnum++;
-       } while (recipmsgnum < MAXMSG);
-       if (recipmsgnum < MAXMSG) {
-               COPY(fromdir, msgnum, todir, recipmsgnum, frompath, topath);
+       if (!ast_lock_path(topath)) {
+               recipmsgnum = 0;
+               do {
+                       make_file(topath, sizeof(topath), todir, recipmsgnum);
+                       if (!EXISTS(todir, recipmsgnum, topath, chan->language))
+                               break;
+                       recipmsgnum++;
+               } while (recipmsgnum < MAXMSG);
+               if (recipmsgnum < MAXMSG) {
+                       COPY(fromdir, msgnum, todir, recipmsgnum, frompath, 
topath);
+               } else {
+                       ast_log(LOG_ERROR, "Recipient mailbox [EMAIL PROTECTED] 
is full\n", recip->mailbox, recip->context);
+               }
+               ast_unlock_path(topath);
+               notify_new_message(chan, recip, recipmsgnum, duration, fmt, 
chan->cid.cid_num, chan->cid.cid_name);
        } else {
-               ast_log(LOG_ERROR, "Recipient mailbox [EMAIL PROTECTED] is 
full\n", recip->mailbox, recip->context);
+               return ERROR_LOCK_PATH;
        }
-       ast_unlock_path(topath);
-       notify_new_message(chan, recip, recipmsgnum, duration, fmt, 
chan->cid.cid_num, chan->cid.cid_name);
+       
+       return 0;
 }
 
 static void run_externnotify(char *context, char *extension)
@@ -2156,30 +2185,30 @@
                ast_copy_string(fmt, vmfmts, sizeof(fmt));
                if (!ast_strlen_zero(fmt)) {
                        msgnum = 0;
-                       if (res >= 0) {
-                               /* Unless we're *really* silent, try to send 
the beep */
-                               res = ast_streamfile(chan, "beep", 
chan->language);
-                               if (!res)
-                                       res = ast_waitstream(chan, "");
-                       }
-                       ast_lock_path(dir);
-                       do {
-                               make_file(fn, sizeof(fn), dir, msgnum);
-                               if (!EXISTS(dir,msgnum,fn,chan->language))
-                                       break;
-                               msgnum++;
-                       } while (msgnum < MAXMSG);
-                       if (msgnum < 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);
-                               txt = fopen(txtfile, "w+");
-                               if (txt) {
-                                       get_date(date, sizeof(date));
-                                       fprintf(txt, 
+                       if (!ast_lock_path(dir)) {
+                               if (res >= 0) {
+                                       /* Unless we're *really* silent, try to 
send the beep */
+                                       res = ast_streamfile(chan, "beep", 
chan->language);
+                                       if (!res)
+                                               res = ast_waitstream(chan, "");
+                               }
+                               do {
+                                       make_file(fn, sizeof(fn), dir, msgnum);
+                                       if 
(!EXISTS(dir,msgnum,fn,chan->language))
+                                               break;
+                                       msgnum++;
+                               } while (msgnum < MAXMSG);
+                               if (msgnum < 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);
+                                       txt = fopen(txtfile, "w+");
+                                       if (txt) {
+                                               get_date(date, sizeof(date));
+                                               fprintf(txt, 
 ";\n"
 "; Message Information file\n"
 ";\n"
@@ -2194,64 +2223,68 @@
 "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);
-                               if (res == '0') {
-                                       if (txt)
+               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);
+                                       if (res == '0') {
+                                               if (txt)
+                                                       fclose(txt);
+                                               goto transfer;
+                                       }
+                                       if (res > 0)
+                                               res = 0;
+                                       if (txt) {
+                                               fprintf(txt, "duration=%d\n", 
duration);
                                                fclose(txt);
-                                       goto transfer;
-                               }
-                               if (res > 0)
-                                       res = 0;
-                               if (txt) {
-                                       fprintf(txt, "duration=%d\n", duration);
-                                       fclose(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 
*/
-                                       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 (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 */
+                                               goto leave_vm_out;
                                        }
-                                       if ((recip = find_user(&recipu, 
context, exten))) {
-                                               copy_message(chan, vmu, 0, 
msgnum, duration, recip, fmt);
-                                               free_user(recip);
+                                       /* 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)) {
-                                       notify_new_message(chan, vmu, msgnum, 
duration, fmt, chan->cid.cid_num, chan->cid.cid_name);
-                                       STORE(dir, msgnum);
-                                       DISPOSE(dir, msgnum);
+                                       if (ast_fileexists(fn, NULL, NULL)) {
+                                               notify_new_message(chan, vmu, 
msgnum, duration, fmt, chan->cid.cid_num, chan->cid.cid_name);
+                                               STORE(dir, msgnum);
+                                               DISPOSE(dir, msgnum);
+                                       }
+                               } else {
+                                       ast_unlock_path(dir);
+                                       res = ast_streamfile(chan, 
"vm-mailboxfull", chan->language);
+                                       if (!res)
+                                               res = ast_waitstream(chan, "");
+                                       ast_log(LOG_WARNING, "No more messages 
possible\n");
                                }
                        } else {
-                               ast_unlock_path(dir);
-                               res = ast_streamfile(chan, "vm-mailboxfull", 
chan->language);
-                               if (!res)
-                                       res = ast_waitstream(chan, "");
-                               ast_log(LOG_WARNING, "No more messages 
possible\n");
+                               free_user(vmu);
+                               return ERROR_LOCK_PATH;
                        }
                } else
                        ast_log(LOG_WARNING, "No format for saving 
voicemail?\n");
@@ -2268,7 +2301,7 @@
 }
 
 
-static void resequence_mailbox(char * dir)
+static int resequence_mailbox(char * dir)
 {
        /* we know max messages, so stop process when number is hit */
 
@@ -2276,20 +2309,25 @@
        char sfn[256];
        char dfn[256];
 
-       ast_lock_path(dir);
-       for (x=0,dest=0;x<MAXMSG;x++) {
-               make_file(sfn, sizeof(sfn), dir, x);
-               if (EXISTS(dir, x, sfn, NULL)) {
-
-                       if(x != dest) {
-                               make_file(dfn, sizeof(dfn), dir, dest);
-                               RENAME(dir, x, dir, dest, sfn, dfn);
+       if (!ast_lock_path(dir)) {
+               for (x=0,dest=0;x<MAXMSG;x++) {
+                       make_file(sfn, sizeof(sfn), dir, x);
+                       if (EXISTS(dir, x, sfn, NULL)) {
+       
+                               if(x != dest) {
+                                       make_file(dfn, sizeof(dfn), dir, dest);
+                                       RENAME(dir, x, dir, dest, sfn, dfn);
+                               }
+       
+                               dest++;
                        }
-
-                       dest++;
                }
+               ast_unlock_path(dir);
+       } else {
+               return ERROR_LOCK_PATH;
        }
-       ast_unlock_path(dir);
+       
+       return 0;
 }
 
 
@@ -2310,20 +2348,24 @@
        make_file(sfn, sizeof(sfn), dir, msg);
        make_dir(ddir, sizeof(ddir), context, username, dbox);
        mkdir(ddir, 0700);
-       ast_lock_path(ddir);
-       for (x=0;x<MAXMSG;x++) {
-               make_file(dfn, sizeof(dfn), ddir, x);
-               if (!EXISTS(ddir, x, dfn, NULL))
-                       break;
-       }
-       if (x >= MAXMSG) {
+       if (!ast_lock_path(ddir)) {
+               for (x=0;x<MAXMSG;x++) {
+                       make_file(dfn, sizeof(dfn), ddir, x);
+                       if (!EXISTS(ddir, x, dfn, NULL))
+                               break;
+               }
+               if (x >= MAXMSG) {
+                       ast_unlock_path(ddir);
+                       return -1;
+               }
+               if (strcmp(sfn, dfn)) {
+                       COPY(dir, msg, ddir, x, sfn, dfn);
+               }
                ast_unlock_path(ddir);
-               return -1;
-       }
-       if (strcmp(sfn, dfn)) {
-               COPY(dir, msg, ddir, x, sfn, dfn);
+       } else {
+               return ERROR_LOCK_PATH;
        }
-       ast_unlock_path(ddir);
+       
        return 0;
 }
 
@@ -3096,7 +3138,10 @@
                                ast_log(LOG_DEBUG, "%s", sys);
                                ast_safe_system(sys);
                
-                               todircount = count_messages(todir);
+                               if ( (res = count_messages(todir)) )
+                                       break;
+                               else
+                                       todircount = res;
                                ast_copy_string(tmp, fmt, sizeof(tmp));
                                stringp = tmp;
                                while ((s = strsep(&stringp, "|"))) {
@@ -3419,11 +3464,18 @@
        return res;
 }
 
-static void open_mailbox(struct vm_state *vms, struct ast_vm_user *vmu,int box)
+static int open_mailbox(struct vm_state *vms, struct ast_vm_user *vmu,int box)
 {
+       int res = 0;
+       int count_msg, last_msg;
+
        ast_copy_string(vms->curbox, mbox(box), sizeof(vms->curbox));
        make_dir(vms->curdir, sizeof(vms->curdir), vmu->context, vms->username, 
vms->curbox);
-       vms->lastmsg = count_messages(vms->curdir) - 1;
+       count_msg = count_messages(vms->curdir);
+       if (count_msg < 0)
+               return count_msg;
+       else
+               vms->lastmsg = count_msg - 1;
 
        /*
        The following test is needed in case sequencing gets messed up.
@@ -3432,48 +3484,65 @@
        detected.
        */
 
-       if(vms->lastmsg != last_message_index(vms->curdir))
+       last_msg = last_message_index(vms->curdir);
+       if (last_msg < 0)
+               return last_msg;
+       else if(vms->lastmsg != last_msg)
        {
                ast_log(LOG_NOTICE, "Resequencing Mailbox: %s\n", vms->curdir);
-               resequence_mailbox(vms->curdir);
+               res = resequence_mailbox(vms->curdir);
+               if (res)
+                       return res;
        }
 
        snprintf(vms->vmbox, sizeof(vms->vmbox), "vm-%s", vms->curbox);
+       return 0;
 }
 
-static void close_mailbox(struct vm_state *vms, struct ast_vm_user *vmu)
+static int close_mailbox(struct vm_state *vms, struct ast_vm_user *vmu)
 {
        int x;
+       int res = 0;
        if (vms->lastmsg > -1) { 
                /* Get the deleted messages fixed */ 
-               ast_lock_path(vms->curdir);
-               vms->curmsg = -1; 
-               for (x=0;x < MAXMSG;x++) { 
-                       if (!vms->deleted[x] && (strcasecmp(vms->curbox, 
"INBOX") || !vms->heard[x])) { 
-                               /* Save this message.  It's not in INBOX or 
hasn't been heard */ 
+               if (!ast_lock_path(vms->curdir)) {
+                       vms->curmsg = -1; 
+                       for (x=0;x < MAXMSG;x++) { 
+                               if (!vms->deleted[x] && 
(strcasecmp(vms->curbox, "INBOX") || !vms->heard[x])) { 
+                                       /* Save this message.  It's not in 
INBOX or hasn't been heard */ 
+                                       make_file(vms->fn, sizeof(vms->fn), 
vms->curdir, x); 
+                                       if (!EXISTS(vms->curdir, x, vms->fn, 
NULL)) 
+                                               break;
+                                       vms->curmsg++; 
+                                       make_file(vms->fn2, sizeof(vms->fn2), 
vms->curdir, vms->curmsg); 
+                                       if (strcmp(vms->fn, vms->fn2)) { 
+                                               RENAME(vms->curdir, x, 
vms->curdir, vms->curmsg, vms->fn, vms->fn2);
+                                       } 
+                               } else if (!strcasecmp(vms->curbox, "INBOX") && 
vms->heard[x] && !vms->deleted[x]) { 
+                                       /* Move to old folder before deleting 
*/ 
+                                       res = save_to_folder(vms->curdir, x, 
vmu->context, vms->username, 1);
+                                       if (res == ERROR_LOCK_PATH) {
+                                               /* If save failed do not delete 
the message */
+                                               vms->deleted[x] = 0;
+                                               vms->heard[x] = 0;
+                                               --x;
+                                       } 
+                               } 
+                       } 
+                       for (x = vms->curmsg + 1; x <= MAXMSG; x++) { 
                                make_file(vms->fn, sizeof(vms->fn), 
vms->curdir, x); 
                                if (!EXISTS(vms->curdir, x, vms->fn, NULL)) 
                                        break;
-                               vms->curmsg++; 
-                               make_file(vms->fn2, sizeof(vms->fn2), 
vms->curdir, vms->curmsg); 
-                               if (strcmp(vms->fn, vms->fn2)) { 
-                                       RENAME(vms->curdir, x, vms->curdir, 
vms->curmsg, vms->fn, vms->fn2);
-                               } 
-                       } else if (!strcasecmp(vms->curbox, "INBOX") && 
vms->heard[x] && !vms->deleted[x]) { 
-                               /* Move to old folder before deleting */ 
-                               save_to_folder(vms->curdir, x, vmu->context, 
vms->username, 1); 
+                               DELETE(vms->curdir, x, vms->fn);
                        } 
-               } 
-               for (x = vms->curmsg + 1; x <= MAXMSG; x++) { 
-                       make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 
-                       if (!EXISTS(vms->curdir, x, vms->fn, NULL)) 
-                               break;
-                       DELETE(vms->curdir, x, vms->fn);
-               } 
-               ast_unlock_path(vms->curdir);
+                       ast_unlock_path(vms->curdir);
+               } else {
+                       return ERROR_LOCK_PATH;
+               }
        } 
        memset(vms->deleted, 0, sizeof(vms->deleted)); 
        memset(vms->heard, 0, sizeof(vms->heard)); 
+       return 0;
 }
 
 /* In Greek even though we CAN use a syntax like "friends messages"
@@ -4704,16 +4773,22 @@
                snprintf(vms.curdir, sizeof(vms.curdir), "%s/%s/%s", 
VM_SPOOL_DIR, vmu->context, vms.username);
                mkdir(vms.curdir, 0700);
                /* Retrieve old and new message counts */
-               open_mailbox(&vms, vmu, 1);
+               res = open_mailbox(&vms, vmu, 1);
+               if (res == ERROR_LOCK_PATH)
+                       goto out;
                vms.oldmessages = vms.lastmsg + 1;
                /* Start in INBOX */
-               open_mailbox(&vms, vmu, 0);
+               res = open_mailbox(&vms, vmu, 0);
+               if (res == ERROR_LOCK_PATH)
+                       goto out;
                vms.newmessages = vms.lastmsg + 1;
                
                /* Select proper mailbox FIRST!! */
                if (!vms.newmessages && vms.oldmessages) {
                        /* If we only have old messages start here */
-                       open_mailbox(&vms, vmu, 1);
+                       res = open_mailbox(&vms, vmu, 1);
+                       if (res == ERROR_LOCK_PATH)
+                               goto out;
                }
 
                if (useadsi)
@@ -4758,8 +4833,12 @@
                                        cmd = 0;
                                } else if (cmd > 0) {
                                        cmd = cmd - '0';
-                                       close_mailbox(&vms, vmu);
-                                       open_mailbox(&vms, vmu, cmd);
+                                       res = close_mailbox(&vms, vmu);
+                                       if (res == ERROR_LOCK_PATH)
+                                               goto out;
+                                       res = open_mailbox(&vms, vmu, cmd);
+                                       if (res == ERROR_LOCK_PATH)
+                                               goto out;
                                        cmd = 0;
                                }
                                if (useadsi)
@@ -4776,9 +4855,13 @@
                                while ((cmd > -1) && (cmd != 't') && (cmd != 
'#')) {
                                        switch(cmd) {
                                        case '1': /* Reply */
-                                               if (vms.lastmsg > -1)
+                                               if (vms.lastmsg > -1) {
                                                        cmd = 
advanced_options(chan, vmu, &vms, vms.curmsg, 1);
-                                               else
+                                                       if (cmd == 
ERROR_LOCK_PATH) {
+                                                               res = cmd;
+                                                               goto out;
+                                                       }
+                                               } else
                                                        cmd = 
ast_play_and_wait(chan, "vm-sorry");
                                                cmd = 't';
                                                break;
@@ -4789,16 +4872,23 @@
                                                        if (cmd == 9) {
                                                                silentexit = 1;
                                                                goto out;
-                                                       }
+                                                       } else if (cmd == 
ERROR_LOCK_PATH) {
+                                                               res = cmd;
+                                                               goto out;
+                                                       }
                                                }
                                                else 
                                                        cmd = 
ast_play_and_wait(chan, "vm-sorry");
                                                cmd = 't';
                                                break;
                                        case '3': /* Envelope */
-                                               if (vms.lastmsg > -1)
+                                               if (vms.lastmsg > -1) {
                                                        cmd = 
advanced_options(chan, vmu, &vms, vms.curmsg, 3);
-                                               else
+                                                       if (cmd == 
ERROR_LOCK_PATH) {
+                                                               res = cmd;
+                                                               goto out;
+                                                       }
+                                               } else
                                                        cmd = 
ast_play_and_wait(chan, "vm-sorry");
                                                cmd = 't';
                                                break;
@@ -4816,9 +4906,13 @@
                                                break;
 
                                        case '5': /* Leave VoiceMail */
-                                               if (ast_test_flag(vmu, 
VM_SVMAIL))
+                                               if (ast_test_flag(vmu, 
VM_SVMAIL)) {
                                                        cmd = 
forward_message(chan, context, vms.curdir, vms.curmsg, vmu, vmfmts,1);
-                                               else
+                                                       if (cmd == 
ERROR_LOCK_PATH) {
+                                                               res = cmd;
+                                                               goto out;
+                                                       }
+                                               } else
                                                        cmd = 
ast_play_and_wait(chan,"vm-sorry");
                                                cmd='t';
                                                break;
@@ -4899,9 +4993,13 @@
                                break;
        
                        case '8':
-                               if (vms.lastmsg > -1)
+                               if (vms.lastmsg > -1) {
                                        cmd = forward_message(chan, context, 
vms.curdir, vms.curmsg, vmu, vmfmts,0);
-                               else
+                                       if (cmd == ERROR_LOCK_PATH) {
+                                               res = cmd;
+                                               goto out;
+                                       }
+                               } else
                                        cmd = ast_play_and_wait(chan, 
"vm-nomore");
                                break;
                        case '9':
@@ -4915,6 +5013,10 @@
                                } else if (cmd > 0) {
                                        box = cmd = cmd - '0';
                                        cmd = save_to_folder(vms.curdir, 
vms.curmsg, vmu->context, vms.username, cmd);
+                                       if (cmd == ERROR_LOCK_PATH) {
+                                               res = cmd;
+                                               goto out;
+                                       }
                                        vms.deleted[vms.curmsg]=1;
                                }
                                make_file(vms.fn, sizeof(vms.fn), vms.curdir, 
vms.curmsg);
@@ -5054,6 +5156,17 @@
        }       
        res = leave_voicemail(chan, ext, silent, busy, unavail);
        LOCAL_USER_REMOVE(u);
+       
+       if (res == ERROR_LOCK_PATH) {
+               ast_log(LOG_ERROR, "Could not leave voicemail. The path is 
already locked.\n");
+               /*Send the call to n+101 priority, where n is the current 
priority*/
+               if (ast_exists_extension(chan, chan->context, chan->exten, 
chan->priority + 101, chan->cid.cid_num))
+                       chan->priority+=100;
+               else
+                       ast_log(LOG_WARNING, "Extension %s, priority %d doesn't 
exist.\n", chan->exten, chan->priority + 101);
+               res = 0;
+       }
+       
        return res;
 }
 
@@ -5900,8 +6013,9 @@
                        } else {
                                if (find_user(NULL, vmu->context, num)) {
                                        ast_verbose(VERBOSE_PREFIX_3 "Leaving 
voicemail for '%s' in context '%s'\n", num, vmu->context);
-                                       leave_voicemail(chan, num, 1, 0, 1);
-                                       res = 't';
+                                       res = leave_voicemail(chan, num, 1, 0, 
1);
+                                       if (!res)
+                                               res = 't';
                                        return res;
                                } else {
                                        /* Sender has no mailbox, can't reply */

_______________________________________________
Asterisk-Cvs mailing list
[email protected]
http://lists.digium.com/mailman/listinfo/asterisk-cvs

Reply via email to