diff options
author | tilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b> | 2008-12-18 21:56:27 +0000 |
---|---|---|
committer | tilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b> | 2008-12-18 21:56:27 +0000 |
commit | 11223a9b0ad03aa9ad1090660f7eed523869b2a5 (patch) | |
tree | 70dabebaf78603ba9eb4899a82408cc4ff10274d | |
parent | bdd3ac9729de515ef6558fab1e7031b139c87f24 (diff) |
Merged revisions 165797 via svnmerge from
https://origsvn.digium.com/svn/asterisk/trunk
................
r165797 | tilghman | 2008-12-18 15:41:02 -0600 (Thu, 18 Dec 2008) | 15 lines
Merged revisions 165767 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r165767 | tilghman | 2008-12-18 15:14:47 -0600 (Thu, 18 Dec 2008) | 8 lines
Add mutexes around accesses to the IMAP library interface. This prevents
certain crashes, especially when shared mailboxes are used.
(closes issue #13653)
Reported by: howardwilkinson
Patches:
asterisk-1.4.21.2-appvoicemail-sharedimap-lock.patch uploaded by howardwilkinson (license 590)
Tested by: jpeeler
........
................
git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.6.0@165806 f38db490-d61c-443f-a65b-d21fe96a405b
-rw-r--r-- | apps/app_voicemail.c | 63 |
1 files changed, 48 insertions, 15 deletions
diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c index 66ec7df53..91676937d 100644 --- a/apps/app_voicemail.c +++ b/apps/app_voicemail.c @@ -45,7 +45,7 @@ c-client (http://www.washington.edu/imap/ ***/ /*** MAKEOPTS -<category name="MENUSELECT_OPTS_app_voicemail" displayname="Voicemail Build Options" positive_output="yes" remove_on_change="apps/app_voicemail.o apps/app_directory.o"> +<category name="MENUSELECT_OPTS_app_voicemail" displayname="Voicemail Build Options" positive_output="yes" remove_on_change="apps/app_voicemail.o apps/app_voicemail.so apps/app_directory.o apps/app_directory.so"> <member name="ODBC_STORAGE" displayname="Storage of Voicemail using ODBC"> <depend>unixodbc</depend> <depend>ltdl</depend> @@ -1147,7 +1147,9 @@ static void vm_imap_delete(int msgnum, struct ast_vm_user *vmu) ast_debug(3, "deleting msgnum %d, which is mailbox message %lu\n", msgnum, messageNum); /* delete message */ snprintf(arg, sizeof(arg), "%lu", messageNum); + ast_mutex_lock(&vms->lock); mail_setflag(vms->mailstream, arg, "\\DELETED"); + ast_mutex_unlock(&vms->lock); } static int imap_retrieve_greeting (const char *dir, const int msgnum, struct ast_vm_user *vmu) @@ -1179,9 +1181,11 @@ static int imap_retrieve_greeting (const char *dir, const int msgnum, struct ast return -1; } + ast_mutex_lock(&vms_p->lock); ret = init_mailstream(vms_p, GREETINGS_FOLDER); if (!vms_p->mailstream) { ast_log(LOG_ERROR, "IMAP mailstream is NULL\n"); + ast_mutex_unlock(&vms_p->lock); return -1; } @@ -1193,6 +1197,7 @@ static int imap_retrieve_greeting (const char *dir, const int msgnum, struct ast attachment = ast_strdupa(body->nested.part->next->body.parameter->value); } else { ast_log(LOG_ERROR, "There is no file attached to this IMAP message.\n"); + ast_mutex_unlock(&vms_p->lock); return -1; } filename = strsep(&attachment, "."); @@ -1200,9 +1205,11 @@ static int imap_retrieve_greeting (const char *dir, const int msgnum, struct ast ast_copy_string(vms_p->fn, dir, sizeof(vms_p->fn)); vms_p->msgArray[vms_p->curmsg] = i + 1; save_body(body, vms_p, "2", attachment); + ast_mutex_unlock(&vms_p->lock); return 0; } } + ast_mutex_unlock(&vms_p->lock); return -1; } @@ -1267,7 +1274,9 @@ static int imap_retrieve_file(const char *dir, const int msgnum, const char *mai } /* This will only work for new messages... */ + ast_mutex_lock(&vms->lock); header_content = mail_fetchheader (vms->mailstream, vms->msgArray[msgnum]); + ast_mutex_unlock(&vms->lock); /* empty string means no valid header */ if (ast_strlen_zero(header_content)) { ast_log (LOG_ERROR,"Could not fetch header for message number %ld\n",vms->msgArray[msgnum]); @@ -1275,8 +1284,10 @@ static int imap_retrieve_file(const char *dir, const int msgnum, const char *mai goto exit; } + ast_mutex_lock(&vms->lock); mail_fetchstructure (vms->mailstream,vms->msgArray[msgnum],&body); - + ast_mutex_unlock(&vms->lock); + /* We have the body, now we extract the file name of the first attachment. */ if (body->nested.part && body->nested.part->next && body->nested.part->next->body.parameter->value) { attachedfilefmt = ast_strdupa(body->nested.part->next->body.parameter->value); @@ -1455,12 +1466,6 @@ static int messagecount(const char *context, const char *mailbox, const char *fo int ret = 0; int fold = folder_int(folder); - /* If URGENT, then look at INBOX */ - if (fold == 11) { - fold = NEW_FOLDER; - urgent = 1; - } - if (ast_strlen_zero(mailbox)) return 0; @@ -1515,6 +1520,7 @@ static int messagecount(const char *context, const char *mailbox, const char *fo return -1; } if (ret == 0) { + ast_mutex_lock(&vms_p->lock); pgm = mail_newsearchpgm (); hdr = mail_newsearchheader ("X-Asterisk-VM-Extension", (char *)mailbox); pgm->header = hdr; @@ -1540,10 +1546,13 @@ static int messagecount(const char *context, const char *mailbox, const char *fo vms_p->oldmessages = vms_p->vmArrayIndex; /* Freeing the searchpgm also frees the searchhdr */ mail_free_searchpgm(&pgm); + ast_mutex_unlock(&vms_p->lock); vms_p->updated = 0; return vms_p->vmArrayIndex; - } else { + } else { + ast_mutex_lock(&vms_p->lock); mail_ping(vms_p->mailstream); + ast_mutex_unlock(&vms_p->lock); } return 0; } @@ -1665,8 +1674,12 @@ static int copy_message(struct ast_channel *chan, struct ast_vm_user *vmu, int i return -1; } snprintf(messagestring, sizeof(messagestring), "%ld", sendvms->msgArray[msgnum]); - if ((mail_copy(sendvms->mailstream, messagestring, (char *) mbox(imbox)) == T)) + ast_mutex_lock(&sendvms->lock); + if ((mail_copy(sendvms->mailstream, messagestring, (char *) mbox(imbox)) == T)) { + ast_mutex_unlock(&sendvms->lock); return 0; + } + ast_mutex_unlock(&sendvms->lock); ast_log(LOG_WARNING, "Unable to copy message from mailbox %s to mailbox %s\n", vmu->mailbox, recip->mailbox); return -1; } @@ -1802,6 +1815,7 @@ static int open_mailbox(struct vm_state *vms, struct ast_vm_user *vmu, int box) check_quota(vms,(char *)mbox(box)); } + ast_mutex_lock(&vms->lock); pgm = mail_newsearchpgm(); /* Check IMAP folder for Asterisk messages only... */ @@ -1833,6 +1847,7 @@ static int open_mailbox(struct vm_state *vms, struct ast_vm_user *vmu, int box) vms->lastmsg = vms->vmArrayIndex - 1; mail_free_searchpgm(&pgm); + ast_mutex_unlock(&vms->lock); return 0; } @@ -1841,9 +1856,9 @@ static void write_file(char *filename, char *buffer, unsigned long len) FILE *output; output = fopen (filename, "w"); - if (fwrite(buffer, len, 1, output) < len) { + if (fwrite(buffer, len, 1, output) != 1) { if (ferror(output)) { - ast_log(LOG_ERROR, "Short write while writing e-mail body.\n"); + ast_log(LOG_ERROR, "Short write while writing e-mail body: %s.\n", strerror(errno)); } } fclose (output); @@ -2319,7 +2334,9 @@ static int save_body(BODY *body, struct vm_state *vms, char *section, char *form if (!body || body == NIL) return -1; + ast_mutex_lock(&vms->lock); body_content = mail_fetchbody (vms->mailstream, vms->msgArray[vms->curmsg], section, &len); + ast_mutex_unlock(&vms->lock); if (body_content != NIL) { snprintf(filename, sizeof(filename), "%s.%s", vms->fn, format); /* ast_log (LOG_DEBUG,body_content); */ @@ -2334,6 +2351,7 @@ static int save_body(BODY *body, struct vm_state *vms, char *section, char *form * * Determines the delimiter character that is used by the underlying IMAP based mail store. */ +/* MUTEX should already be held */ static void get_mailbox_delimiter(MAILSTREAM *stream) { char tmp[50]; snprintf(tmp, sizeof(tmp), "{%s}", imapserver); @@ -2348,6 +2366,7 @@ static void get_mailbox_delimiter(MAILSTREAM *stream) { * Calls imap_getquotaroot, which will populate its results into the vm_state vms input structure. */ static void check_quota(struct vm_state *vms, char *mailbox) { + ast_mutex_lock(&vms->lock); mail_parameters(NULL, SET_QUOTA, (void *) mm_parsequota); ast_debug(3, "Mailbox name set to: %s, about to check quotas\n", mailbox); if (vms && vms->mailstream != NULL) { @@ -2355,6 +2374,7 @@ static void check_quota(struct vm_state *vms, char *mailbox) { } else { ast_log(LOG_WARNING, "Mailstream not available for mailbox: %s\n", mailbox); } + ast_mutex_unlock(&vms->lock); } #endif /* IMAP_STORAGE */ @@ -4595,17 +4615,23 @@ static int has_voicemail(const char *mailbox, const char *folder) /* simple. huh? */ char sequence[10]; char mailbox[256]; + int res; + /* get the real IMAP message number for this message */ snprintf(sequence, sizeof(sequence), "%ld", vms->msgArray[msg]); ast_debug(3, "Copying sequence %s to mailbox %s\n", sequence, mbox(box)); + ast_mutex_lock(&vms->lock); + if (box == OLD_FOLDER) { mail_setflag(vms->mailstream, sequence, "\\Seen"); } else if (box == NEW_FOLDER) { mail_clearflag(vms->mailstream, sequence, "\\Seen"); } - if (!strcasecmp(mbox(NEW_FOLDER), vms->curbox) && (box == NEW_FOLDER || box == OLD_FOLDER)) + if (!strcasecmp(mbox(NEW_FOLDER), vms->curbox) && (box == NEW_FOLDER || box == OLD_FOLDER)) { + ast_mutex_unlock(&vms->lock); return 0; + } /* Create the folder if it don't exist */ imap_mailbox_name(mailbox, sizeof(mailbox), vms, box, 1); /* Get the full mailbox name */ ast_debug(5, "Checking if folder exists: %s\n",mailbox); @@ -4613,7 +4639,9 @@ static int has_voicemail(const char *mailbox, const char *folder) ast_debug(5, "Folder exists.\n"); else ast_log(LOG_NOTICE, "Folder %s created!\n",mbox(box)); - return !mail_copy(vms->mailstream, sequence, (char *)mbox(box)); + res = !mail_copy(vms->mailstream, sequence, (char *)mbox(box)); + ast_mutex_unlock(&vms->lock); + return res; #else char *dir = vms->curdir; char *username = vms->username; @@ -5967,7 +5995,8 @@ static int imap_delete_old_greeting (char *dir, struct vm_state *vms) ast_log(LOG_ERROR, "Failed to procure file name from directory passed. You should never see this.\n"); return -1; } - + + ast_mutex_lock(&vms->lock); for (i = 0; i < vms->mailstream->nmsgs; i++) { mail_fetchstructure(vms->mailstream, i + 1, &body); /* We have the body, now we extract the file name of the first attachment. */ @@ -5975,6 +6004,7 @@ static int imap_delete_old_greeting (char *dir, struct vm_state *vms) attachment = ast_strdupa(body->nested.part->next->body.parameter->value); } else { ast_log(LOG_ERROR, "There is no file attached to this IMAP message.\n"); + ast_mutex_unlock(&vms->lock); return -1; } filename = strsep(&attachment, "."); @@ -5984,6 +6014,7 @@ static int imap_delete_old_greeting (char *dir, struct vm_state *vms) } } mail_expunge(vms->mailstream); + ast_mutex_unlock(&vms->lock); return 0; } @@ -8186,12 +8217,14 @@ out: /* expunge message - use UID Expunge if supported on IMAP server*/ ast_debug(3, "*** Checking if we can expunge, deleted set to %d, expungeonhangup set to %d\n", deleted, expungeonhangup); if (vmu && deleted == 1 && expungeonhangup == 1) { + ast_mutex_lock(&vms.lock); #ifdef HAVE_IMAP_TK2006 if (LEVELUIDPLUS (vms.mailstream)) { mail_expunge_full(vms.mailstream, NIL, EX_UID); } else #endif mail_expunge(vms.mailstream); + ast_mutex_unlock(&vms.lock); } /* before we delete the state, we should copy pertinent info * back to the persistent model */ |