Merged revisions 303678 via svnmerge from
authorJeff Peeler <jpeeler@digium.com>
Tue, 25 Jan 2011 17:05:56 +0000 (17:05 +0000)
committerJeff Peeler <jpeeler@digium.com>
Tue, 25 Jan 2011 17:05:56 +0000 (17:05 +0000)
https://origsvn.digium.com/svn/asterisk/branches/1.8

................
  r303678 | jpeeler | 2011-01-25 11:02:38 -0600 (Tue, 25 Jan 2011) | 33 lines

  Merged revisions 303677 via svnmerge from
  https://origsvn.digium.com/svn/asterisk/branches/1.6.2

  ................
    r303677 | jpeeler | 2011-01-25 10:59:28 -0600 (Tue, 25 Jan 2011) | 26 lines

    Merged revisions 303676 via svnmerge from
    https://origsvn.digium.com/svn/asterisk/branches/1.4

    ........
      r303676 | jpeeler | 2011-01-25 10:58:29 -0600 (Tue, 25 Jan 2011) | 20 lines

      Fix voicemail sequencing for file based storage.

      A previous change was made to account for when the number of voicemail messages
      exceeds the max limit to be handled properly, but it caused gaps in the messages
      to not be properly handled. This has now been resolved.

      In later non 1.4 branches, it appears that resequencing wasn't even occurring
      due from what appears and accidental code removal.

      (closes issue #18498)
      Reported by: JJCinAZ
      Patches:
            bug18498v2.patch uploaded by jpeeler (license 325)

      (closes issue #18486)
      Reported by: bluefox
      Patches:
            bug18486.patch uploaded by jpeeler (license 325)
    ........
  ................
................

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@303679 65c4cc65-6c06-0410-ace0-fbb531ad65f3

apps/app_voicemail.c

index ca47368..6d3de28 100644 (file)
@@ -3923,6 +3923,8 @@ static int last_message_index(struct ast_vm_user *vmu, char *dir)
        DIR *msgdir;
        struct dirent *msgdirent;
        int msgdirint;
        DIR *msgdir;
        struct dirent *msgdirent;
        int msgdirint;
+       char extension[3];
+       int stopcount = 0;
 
        /* Reading the entire directory into a file map scales better than
         * doing a stat repeatedly on a predicted sequence.  I suspect this
 
        /* Reading the entire directory into a file map scales better than
         * doing a stat repeatedly on a predicted sequence.  I suspect this
@@ -3933,14 +3935,20 @@ static int last_message_index(struct ast_vm_user *vmu, char *dir)
        }
 
        while ((msgdirent = readdir(msgdir))) {
        }
 
        while ((msgdirent = readdir(msgdir))) {
-               if (sscanf(msgdirent->d_name, "msg%30d", &msgdirint) == 1 && msgdirint < MAXMSGLIMIT)
+               if (sscanf(msgdirent->d_name, "msg%30d.%3s", &msgdirint, extension) == 2 && msgdirint < MAXMSGLIMIT && !strcmp(extension, "txt")) {
                        map[msgdirint] = 1;
                        map[msgdirint] = 1;
+                       stopcount++;
+                       ast_debug(4, "%s map[%d] = %d, count = %d\n", dir, msgdirint, map[msgdirint], stopcount);
+               }
        }
        closedir(msgdir);
 
        for (x = 0; x < vmu->maxmsg; x++) {
        }
        closedir(msgdir);
 
        for (x = 0; x < vmu->maxmsg; x++) {
-               if (map[x] == 0)
+               if (map[x] == 1) {
+                       stopcount--;
+               } else if (map[x] == 0 && !stopcount) {
                        break;
                        break;
+               }
        }
 
        return x - 1;
        }
 
        return x - 1;
@@ -6021,6 +6029,36 @@ leave_vm_out:
        return res;
 }
 
        return res;
 }
 
+#ifndef IMAP_STORAGE
+static int resequence_mailbox(struct ast_vm_user *vmu, char *dir, int stopcount)
+{
+    /* we know the actual number of messages, so stop process when number is hit */
+
+    int x, dest;
+    char sfn[PATH_MAX];
+    char dfn[PATH_MAX];
+
+    if (vm_lock_path(dir))
+        return ERROR_LOCK_PATH;
+
+    for (x = 0, dest = 0; dest != stopcount && x < vmu->maxmsg + 10; 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, vmu->mailbox, vmu->context, dir, dest, sfn, dfn);
+            }
+
+            dest++;
+        }
+    }
+    ast_unlock_path(dir);
+
+    return dest;
+}
+#endif
+
 static int say_and_wait(struct ast_channel *chan, int num, const char *language)
 {
        int d;
 static int say_and_wait(struct ast_channel *chan, int num, const char *language)
 {
        int d;
@@ -7735,8 +7773,12 @@ static int open_mailbox(struct vm_state *vms, struct ast_vm_user *vmu, int box)
 
        if (last_msg < -1) {
                return last_msg;
 
        if (last_msg < -1) {
                return last_msg;
-       } else if (vms->lastmsg != last_msg) {
-               ast_log(LOG_NOTICE, "Mailbox: %s, expected %d but found %d message(s) in box with max threshold of %d.\n", vms->curdir, last_msg + 1, vms->lastmsg + 1, vmu->maxmsg);
+       } 
+#ifndef ODBC_STORAGE
+       else if (vms->lastmsg != last_msg) {
+               ast_log(LOG_NOTICE, "Resequencing mailbox: %s, expected %d but found %d message(s) in box with max threshold of %d.\n", vms->curdir, last_msg + 1, vms->lastmsg + 1, vmu->maxmsg);
+        resequence_mailbox(vmu, vms->curdir, count_msg);
+#endif
        }
 
        return 0;
        }
 
        return 0;