]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
pop3c: Fixed assert-crash when prefetching a mail failed.
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Wed, 27 Jan 2016 00:04:00 +0000 (02:04 +0200)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Wed, 27 Jan 2016 00:04:00 +0000 (02:04 +0200)
src/lib-storage/index/pop3c/pop3c-mail.c
src/lib-storage/index/pop3c/pop3c-storage.h

index 5bd81bf43185538fe06b90742bd115852b3c982d..8fc7f0ae631aacb608d8092cad99590f97681626 100644 (file)
@@ -33,6 +33,8 @@ static void pop3c_mail_close(struct mail *_mail)
        /* wait for any prefetch to finish before closing the mail */
        while (pmail->prefetching)
                pop3c_client_wait_one(mbox->client);
+       if (pmail->prefetch_stream != NULL)
+               i_stream_unref(&pmail->prefetch_stream);
        index_mail_close(_mail);
 }
 
@@ -131,16 +133,20 @@ static void pop3c_mail_prefetch_done(enum pop3c_command_state state,
                                     const char *reply, void *context)
 {
        struct pop3c_mail *pmail = context;
+       struct mail *_mail = &pmail->imail.mail.mail;
+       const char *cmd;
 
        switch (state) {
        case POP3C_COMMAND_STATE_OK:
                break;
        case POP3C_COMMAND_STATE_ERR:
        case POP3C_COMMAND_STATE_DISCONNECTED:
-               i_stream_unref(&pmail->imail.data.stream);
-               pmail->imail.data.stream =
-                       i_stream_create_error_str(EIO, "%s failed: %s",
-                               pmail->prefetching_body ? "RETR" : "TOP", reply);
+               cmd = pmail->prefetching_body ? "RETR" : "TOP";
+               i_stream_unref(&pmail->prefetch_stream);
+               pmail->prefetch_stream =
+                       i_stream_create_error_str(EIO, "%s %u failed: %s",
+                               cmd, _mail->seq, reply);
+               i_stream_set_name(pmail->prefetch_stream, cmd);
                break;
        }
        pmail->prefetching = FALSE;
@@ -164,10 +170,10 @@ static bool pop3c_mail_prefetch(struct mail *_mail)
                        cmd = t_strdup_printf("TOP %u 0\r\n", _mail->seq);
 
                pmail->prefetching = TRUE;
-               pmail->imail.data.stream =
+               pmail->prefetch_stream =
                        pop3c_client_cmd_stream_async(mbox->client, cmd,
                                pop3c_mail_prefetch_done, pmail);
-               i_stream_set_name(pmail->imail.data.stream, t_strcut(cmd, '\r'));
+               i_stream_set_name(pmail->prefetch_stream, t_strcut(cmd, '\r'));
                return !pmail->prefetching;
        }
        return index_mail_prefetch(_mail);
@@ -193,6 +199,11 @@ pop3c_mail_get_stream(struct mail *_mail, bool get_body,
                pop3c_client_wait_one(mbox->client);
        }
 
+       if (pmail->prefetch_stream != NULL && mail->data.stream == NULL) {
+               mail->data.stream = pmail->prefetch_stream;
+               pmail->prefetch_stream = NULL;
+       }
+
        if (get_body && mail->data.stream != NULL) {
                name = i_stream_get_name(mail->data.stream);
                if (strncmp(name, "RETR", 4) == 0) {
index 8365d08099e6eeda5c0bdefce10da737ae7da1a2..8f0cbdd737cb93bf286ace69217e665d83375511 100644 (file)
@@ -31,6 +31,7 @@ struct pop3c_mailbox {
 
 struct pop3c_mail {
        struct index_mail imail;
+       struct istream *prefetch_stream;
 
        unsigned int prefetching:1;
        unsigned int prefetching_body:1;