return;
}
mail_storage_set_critical(_mail->box->storage,
- "read(%s) failed: %s (uid=%u, box=%s)",
+ "read(%s) failed: %s (uid=%u, box=%s, read reason=%s)",
i_stream_get_name(input), i_stream_get_error(input),
- _mail->uid, mailbox_get_vname(_mail->box));
+ _mail->uid, mailbox_get_vname(_mail->box),
+ mail->mail.get_stream_reason == NULL ? "" :
+ mail->mail.get_stream_reason);
}
static int index_mail_parse_body(struct index_mail *mail,
bool has_nuls;
int ret;
+ if (_mail->box->storage->user->mail_debug &&
+ mail->mail.get_stream_reason != NULL &&
+ mail->mail.get_stream_reason[0] != '\0') {
+ i_debug("Mailbox %s: Opened mail UID=%u because: %s",
+ _mail->box->vname, _mail->uid,
+ mail->mail.get_stream_reason);
+ }
+
if (!data->initialized_wrapper_stream &&
_mail->transaction->stats_track) {
input = i_stream_create_mail(_mail, data->stream,
pool_t pool, data_pool;
ARRAY(union mail_module_context *) module_contexts;
+
+ const char *get_stream_reason;
};
struct mailbox_list_context {
int mail_get_stream(struct mail *mail, struct message_size *hdr_size,
struct message_size *body_size, struct istream **stream_r)
ATTR_NULL(2, 3);
+/* Same as mail_get_stream(), but specify a reason why the mail is being read.
+ This can be useful for debugging purposes. */
+int mail_get_stream_because(struct mail *mail, struct message_size *hdr_size,
+ struct message_size *body_size,
+ const char *reason, struct istream **stream_r)
+ ATTR_NULL(2, 3);
/* Similar to mail_get_stream(), but the stream may or may not contain the
message body. */
int mail_get_hdr_stream(struct mail *mail, struct message_size *hdr_size,
struct istream **stream_r) ATTR_NULL(2);
+/* Same as mail_get_hdr_stream(), but specify a reason why the header is being
+ read. This can be useful for debugging purposes. */
+int mail_get_hdr_stream_because(struct mail *mail,
+ struct message_size *hdr_size,
+ const char *reason, struct istream **stream_r);
/* Returns the message part's body decoded to 8bit binary. If the
Content-Transfer-Encoding isn't supported, returns -1 and sets error to
MAIL_ERROR_CONVERSION. If the part refers to a multipart, all of its
int mail_get_stream(struct mail *mail, struct message_size *hdr_size,
struct message_size *body_size, struct istream **stream_r)
+{
+ return mail_get_stream_because(mail, hdr_size, body_size,
+ "mail stream", stream_r);
+}
+
+int mail_get_stream_because(struct mail *mail, struct message_size *hdr_size,
+ struct message_size *body_size,
+ const char *reason, struct istream **stream_r)
{
struct mail_private *p = (struct mail_private *)mail;
int ret;
return -1;
}
T_BEGIN {
+ p->get_stream_reason = reason;
ret = p->v.get_stream(mail, TRUE, hdr_size, body_size, stream_r);
+ p->get_stream_reason = "";
} T_END;
return ret;
}
int mail_get_hdr_stream(struct mail *mail, struct message_size *hdr_size,
struct istream **stream_r)
+{
+ return mail_get_hdr_stream_because(mail, hdr_size, "header stream", stream_r);
+}
+
+int mail_get_hdr_stream_because(struct mail *mail,
+ struct message_size *hdr_size,
+ const char *reason, struct istream **stream_r)
{
struct mail_private *p = (struct mail_private *)mail;
int ret;
return -1;
}
T_BEGIN {
+ p->get_stream_reason = reason;
ret = p->v.get_stream(mail, FALSE, hdr_size, NULL, stream_r);
+ p->get_stream_reason = "";
} T_END;
return ret;
}