From fbe92dce2b10ceca70ca12a5b901c40f308b9393 Mon Sep 17 00:00:00 2001 From: Sean Bright Date: Mon, 27 Nov 2023 10:20:02 -0500 Subject: [PATCH] app_voicemail.c: Completely resequence mailbox folders. Resequencing is a process that occurs when we open a voicemail folder and discover that there are gaps between messages (e.g. `msg0000.txt` is missing but `msg0001.txt` exists). Resequencing involves shifting the existing messages down so we end up with a sequential list of messages. Currently, this process stops after reaching a threshold based on the message limit (`maxmsg`) configured on the current folder. However, if `maxmsg` is lowered when a voicemail folder contains more than `maxmsg + 10` messages, resequencing will not run completely leaving the mailbox in an inconsistent state. We now resequence up to the maximum number of messages permitted by `app_voicemail` (currently hard-coded at 9999 messages). Fixes #86 --- apps/app_voicemail.c | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c index f37b73e179..e4067abd06 100644 --- a/apps/app_voicemail.c +++ b/apps/app_voicemail.c @@ -4112,16 +4112,14 @@ bail: /*! * \brief Determines the highest message number in use for a given user and mailbox folder. - * \param vmu * \param dir the folder the mailbox folder to look for messages. Used to construct the SQL where clause. * * This method is used when mailboxes are stored in an ODBC back end. * Typical use to set the msgnum would be to take the value returned from this method and add one to it. * * \return the value of zero or greater to indicate the last message index in use, -1 to indicate none. - */ -static int last_message_index(struct ast_vm_user *vmu, char *dir) +static int last_message_index(char *dir) { int x = -1; int res; @@ -4684,7 +4682,6 @@ static void rename_file(char *sfn, char *dfn) /*! * \brief Determines the highest message number in use for a given user and mailbox folder. - * \param vmu * \param dir the folder the mailbox folder to look for messages. Used to construct the SQL where clause. * * This method is used when mailboxes are stored on the filesystem. (not ODBC and not IMAP). @@ -4693,7 +4690,7 @@ static void rename_file(char *sfn, char *dfn) * \note Should always be called with a lock already set on dir. * \return the value of zero or greaterto indicate the last message index in use, -1 to indicate none. */ -static int last_message_index(struct ast_vm_user *vmu, char *dir) +static int last_message_index(char *dir) { int x; unsigned char map[MAXMSGLIMIT] = ""; @@ -4720,12 +4717,8 @@ static int last_message_index(struct ast_vm_user *vmu, char *dir) } closedir(msgdir); - for (x = 0; x < vmu->maxmsg; x++) { - if (map[x] == 1) { - stopcount--; - } else if (map[x] == 0 && !stopcount) { - break; - } + for (x = 0; x < MAXMSGLIMIT && stopcount; x++) { + stopcount -= map[x]; } return x - 1; @@ -5998,7 +5991,7 @@ static int copy_message(struct ast_channel *chan, struct ast_vm_user *vmu, int i if (vm_lock_path(todir)) return ERROR_LOCK_PATH; - recipmsgnum = last_message_index(recip, todir) + 1; + recipmsgnum = last_message_index(todir) + 1; if (recipmsgnum < recip->maxmsg - (imbox ? 0 : inprocess_count(vmu->mailbox, vmu->context, 0))) { make_file(topath, sizeof(topath), todir, recipmsgnum); #ifndef ODBC_STORAGE @@ -6493,7 +6486,7 @@ static int msg_create_from_file(struct ast_vm_recording_data *recdata) return -1; } - msgnum = last_message_index(recipient, dir) + 1; + msgnum = last_message_index(dir) + 1; #endif /* Lock the directory receiving the voicemail since we want it to still exist when we attempt to copy the voicemail. @@ -7061,7 +7054,7 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, struct leave_vm_ } } else { #ifndef IMAP_STORAGE - msgnum = last_message_index(vmu, dir) + 1; + msgnum = last_message_index(dir) + 1; #endif make_file(fn, sizeof(fn), dir, msgnum); @@ -7183,7 +7176,7 @@ static int resequence_mailbox(struct ast_vm_user *vmu, char *dir, int stopcount) return ERROR_LOCK_PATH; } - for (x = 0, dest = 0; dest != stopcount && x < vmu->maxmsg + 10; x++) { + for (x = 0, dest = 0; dest != stopcount && x < MAXMSGLIMIT; x++) { make_file(sfn, sizeof(sfn), dir, x); if (EXISTS(dir, x, sfn, NULL)) { @@ -7272,7 +7265,7 @@ static int save_to_folder(struct ast_vm_user *vmu, struct vm_state *vms, int msg if (vm_lock_path(ddir)) return ERROR_LOCK_PATH; - x = last_message_index(vmu, ddir) + 1; + x = last_message_index(ddir) + 1; if (box == 10 && x >= vmu->maxdeletedmsg) { /* "Deleted" folder*/ x--; @@ -9132,8 +9125,8 @@ static int open_mailbox(struct vm_state *vms, struct ast_vm_user *vmu, int box) return ERROR_LOCK_PATH; } - /* for local storage, checks directory for messages up to maxmsg limit */ - last_msg = last_message_index(vmu, vms->curdir); + /* for local storage, checks directory for messages up to MAXMSGLIMIT */ + last_msg = last_message_index(vms->curdir); ast_unlock_path(vms->curdir); if (last_msg < -1) { @@ -9169,7 +9162,7 @@ static int close_mailbox(struct vm_state *vms, struct ast_vm_user *vmu) } /* update count as message may have arrived while we've got mailbox open */ - last_msg_idx = last_message_index(vmu, vms->curdir); + last_msg_idx = last_message_index(vms->curdir); if (last_msg_idx != vms->lastmsg) { ast_log(AST_LOG_NOTICE, "%d messages received after mailbox opened.\n", last_msg_idx - vms->lastmsg); } -- 2.47.2