static int pop3c_mail_get_stream(struct mail *_mail, bool get_body, struct message_size *hdr_size, struct message_size *body_size, struct istream **stream_r) { struct index_mail *mail = (struct index_mail *)_mail; struct pop3c_mailbox *mbox = (struct pop3c_mailbox *)_mail->box; enum pop3c_capability capa; const char *name, *cmd, *error; struct istream *input; if (get_body && mail->data.stream != NULL) { name = i_stream_get_name(mail->data.stream); if (strncmp(name, "RETR", 4) == 0) { /* we've fetched the body */ } else if (strncmp(name, "TOP", 3) == 0) { /* we've fetched the header, but we need the body now too */ index_mail_close_streams(mail); } else { i_panic("Unexpected POP3 stream name: %s", name); } } if (mail->data.stream == NULL) { capa = pop3c_client_get_capabilities(mbox->client); if (get_body || (capa & POP3C_CAPABILITY_TOP) == 0) { cmd = t_strdup_printf("RETR %u\r\n", _mail->seq); get_body = TRUE; } else { cmd = t_strdup_printf("TOP %u 0\r\n", _mail->seq); } if (pop3c_client_cmd_stream(mbox->client, cmd, &input, &error) < 0) { mail_storage_set_error(mbox->box.storage, !pop3c_client_is_connected(mbox->client) ? MAIL_ERROR_TEMP : MAIL_ERROR_EXPUNGED, error); return -1; } mail->data.stream = input; if (mail->mail.v.istream_opened != NULL) { if (mail->mail.v.istream_opened(_mail, &mail->data.stream) < 0) { index_mail_close_streams(mail); return -1; } } i_stream_set_name(mail->data.stream, t_strcut(cmd, '\r')); if (get_body) pop3c_mail_cache_size(mail); } return index_mail_init_stream(mail, hdr_size, body_size, stream_r); }
static int imapc_mail_get_stream(struct mail *_mail, bool get_body, struct message_size *hdr_size, struct message_size *body_size, struct istream **stream_r) { struct imapc_mail *mail = (struct imapc_mail *)_mail; struct index_mail_data *data = &mail->imail.data; enum mail_fetch_field fetch_field; if (get_body && !mail->body_fetched && mail->imail.data.stream != NULL) { /* we've fetched the header, but we need the body now too */ index_mail_close_streams(&mail->imail); } if (data->stream == NULL) { if (!data->initialized) { /* coming here from mail_set_seq() */ mail_set_aborted(_mail); return -1; } fetch_field = get_body || (data->access_part & READ_BODY) != 0 ? MAIL_FETCH_STREAM_BODY : MAIL_FETCH_STREAM_HEADER; if (imapc_mail_fetch(_mail, fetch_field) < 0) return -1; if (data->stream == NULL) { if (imapc_mail_failed(_mail, "BODY[]") < 0) return -1; i_assert(data->stream == NULL); /* this could be either a temporary server bug, or the server may permanently just not return anything for this mail. the latter happens at least with Exchange when trying to fetch calendar "mails", so we'll just return them as empty mails instead of disconnecting the client. */ mail->body_fetched = TRUE; data->stream = i_stream_create_from_data(&uchar_nul, 0); imapc_mail_init_stream(mail, TRUE); } } return index_mail_init_stream(&mail->imail, hdr_size, body_size, stream_r); }
static int imapc_mail_get_stream(struct mail *_mail, bool get_body, struct message_size *hdr_size, struct message_size *body_size, struct istream **stream_r) { struct imapc_mail *mail = (struct imapc_mail *)_mail; struct index_mail_data *data = &mail->imail.data; enum mail_fetch_field fetch_field; if (get_body && !mail->body_fetched && mail->imail.data.stream != NULL) { /* we've fetched the header, but we need the body now too */ index_mail_close_streams(&mail->imail); } if (data->stream == NULL) { if (!data->initialized) { /* coming here from mail_set_seq() */ mail_set_aborted(_mail); return -1; } fetch_field = get_body || (data->access_part & READ_BODY) != 0 ? MAIL_FETCH_STREAM_BODY : MAIL_FETCH_STREAM_HEADER; if (imapc_mail_fetch(_mail, fetch_field, NULL) < 0) return -1; if (data->stream == NULL) { if (imapc_mail_failed(_mail, "BODY[]")) return -1; i_assert(data->stream == NULL); /* return the broken email as empty */ mail->body_fetched = TRUE; data->stream = i_stream_create_from_data(NULL, 0); imapc_mail_init_stream(mail); } } return index_mail_init_stream(&mail->imail, hdr_size, body_size, stream_r); }