static void mail_log_update_wanted_fields(struct mail *mail, enum mail_log_field fields) { enum mail_fetch_field wanted_fields = 0; struct mailbox_header_lookup_ctx *wanted_headers = NULL; const char *headers[4]; unsigned int hdr_idx = 0; if ((fields & MAIL_LOG_FIELD_MSGID) != 0) headers[hdr_idx++] = "Message-ID"; if ((fields & MAIL_LOG_FIELD_FROM) != 0) headers[hdr_idx++] = "From"; if ((fields & MAIL_LOG_FIELD_SUBJECT) != 0) headers[hdr_idx++] = "Subject"; if (hdr_idx > 0) { i_assert(hdr_idx < N_ELEMENTS(headers)); headers[hdr_idx] = NULL; wanted_headers = mailbox_header_lookup_init(mail->box, headers); } if ((fields & MAIL_LOG_FIELD_PSIZE) != 0) wanted_fields |= MAIL_FETCH_PHYSICAL_SIZE; if ((fields & MAIL_LOG_FIELD_VSIZE) != 0) wanted_fields |= MAIL_FETCH_VIRTUAL_SIZE; mail_add_temp_wanted_fields(mail, wanted_fields, wanted_headers); if (wanted_headers != NULL) mailbox_header_lookup_unref(&wanted_headers); }
static void index_mail_update_access_parts(struct index_mail *mail) { struct mail *_mail = &mail->mail.mail; struct imapc_mailbox *mbox = (struct imapc_mailbox *)_mail->box; struct index_mail_data *data = &mail->data; struct mailbox_header_lookup_ctx *header_ctx; time_t date; uoff_t size; if ((data->wanted_fields & MAIL_FETCH_RECEIVED_DATE) != 0) (void)index_mail_get_received_date(_mail, &date); if ((data->wanted_fields & MAIL_FETCH_PHYSICAL_SIZE) != 0) { if (index_mail_get_physical_size(_mail, &size) < 0 && !IMAPC_BOX_HAS_FEATURE(mbox, IMAPC_FEATURE_RFC822_SIZE)) data->access_part |= READ_HDR | READ_BODY; } if (data->access_part == 0 && data->wanted_headers != NULL) { /* see if all wanted headers exist in cache */ if (!imapc_mail_has_headers_in_cache(mail, data->wanted_headers)) data->access_part |= PARSE_HDR; } if (data->access_part == 0 && (data->wanted_fields & MAIL_FETCH_IMAP_ENVELOPE) != 0) { /* the common code already checked this partially, but we need a guaranteed correct answer */ header_ctx = mailbox_header_lookup_init(_mail->box, imap_envelope_headers); if (!imapc_mail_has_headers_in_cache(mail, header_ctx)) data->access_part |= PARSE_HDR; mailbox_header_lookup_unref(&header_ctx); } }
int dsync_mail_get_hdr_hash(struct mail *mail, const char **hdr_hash_r) { struct istream *hdr_input, *input; struct mailbox_header_lookup_ctx *hdr_ctx; struct md5_context md5_ctx; unsigned char md5_result[MD5_RESULTLEN]; const unsigned char *data; size_t size; int ret = 0; hdr_ctx = mailbox_header_lookup_init(mail->box, hashed_headers); ret = mail_get_header_stream(mail, hdr_ctx, &hdr_input); mailbox_header_lookup_unref(&hdr_ctx); if (ret < 0) return -1; input = i_stream_create_lf(hdr_input); md5_init(&md5_ctx); while (!i_stream_is_eof(input)) { if (i_stream_read_data(input, &data, &size, 0) == -1) break; if (size == 0) break; md5_update(&md5_ctx, data, size); i_stream_skip(input, size); } if (input->stream_errno != 0) ret = -1; i_stream_unref(&input); md5_final(&md5_ctx, md5_result); *hdr_hash_r = binary_to_hex(md5_result, sizeof(md5_result)); return ret; }
static int imapc_mail_get_headers(struct mail *_mail, const char *field, bool decode_to_utf8, const char *const **value_r) { struct mailbox_header_lookup_ctx *headers; const char *header_names[2]; struct istream *input; int ret; header_names[0] = field; header_names[1] = NULL; headers = mailbox_header_lookup_init(_mail->box, header_names); ret = mail_get_header_stream(_mail, headers, &input); mailbox_header_lookup_unref(&headers); if (ret < 0) return -1; /* the header should cached now. */ return index_mail_get_headers(_mail, field, decode_to_utf8, value_r); }
struct mail * virtual_mail_set_backend_mail(struct mail *mail, struct virtual_backend_box *bbox) { struct virtual_mail *vmail = (struct virtual_mail *)mail; struct mailbox_transaction_context *backend_trans; struct mailbox_header_lookup_ctx *backend_headers; backend_trans = virtual_transaction_get(mail->transaction, bbox->box); backend_headers = vmail->wanted_headers == NULL ? NULL : mailbox_header_lookup_init(bbox->box, vmail->wanted_headers->headers); vmail->backend_mail = mail_alloc(backend_trans, vmail->wanted_fields, backend_headers); if (backend_headers != NULL) mailbox_header_lookup_unref(&backend_headers); array_append(&vmail->backend_mails, &vmail->backend_mail, 1); return vmail->backend_mail; }
static struct mail_raw *mail_raw_create (struct mail_user *ruser, struct istream *input, const char *mailfile, const char *sender, time_t mtime) { struct mail_raw *mailr; struct mailbox_header_lookup_ctx *headers_ctx; const char *envelope_sender; int ret; if ( mailfile != NULL && *mailfile != '/' ) mailfile = t_abspath(mailfile); mailr = i_new(struct mail_raw, 1); envelope_sender = sender != NULL ? sender : DEFAULT_ENVELOPE_SENDER; if ( mailfile == NULL ) { ret = raw_mailbox_alloc_stream(ruser, input, mtime, envelope_sender, &mailr->box); } else { ret = raw_mailbox_alloc_path(ruser, mailfile, (time_t)-1, envelope_sender, &mailr->box); } if ( ret < 0 ) { if ( mailfile == NULL ) { i_fatal("Can't open delivery mail as raw: %s", mailbox_get_last_error(mailr->box, NULL)); } else { i_fatal("Can't open delivery mail as raw (file=%s): %s", mailfile, mailbox_get_last_error(mailr->box, NULL)); } } mailr->trans = mailbox_transaction_begin(mailr->box, 0); headers_ctx = mailbox_header_lookup_init(mailr->box, wanted_headers); mailr->mail = mail_alloc(mailr->trans, 0, headers_ctx); mailbox_header_lookup_unref(&headers_ctx); mail_set_seq(mailr->mail, 1); return mailr; }
static int virtual_mail_get_header_stream(struct mail *mail, struct mailbox_header_lookup_ctx *headers, struct istream **stream_r) { struct virtual_mail *vmail = (struct virtual_mail *)mail; struct mailbox_header_lookup_ctx *backend_headers; int ret; if (virtual_mail_handle_lost(vmail) < 0) return -1; backend_headers = mailbox_header_lookup_init(vmail->backend_mail->box, headers->headers); ret = mail_get_header_stream(vmail->backend_mail, backend_headers, stream_r); mailbox_header_lookup_unref(&backend_headers); if (ret < 0) { virtual_box_copy_error(mail->box, vmail->backend_mail->box); return -1; } return 0; }
static int imapc_mail_get_headers(struct mail *_mail, const char *field, bool decode_to_utf8, const char *const **value_r) { struct mailbox_header_lookup_ctx *headers; const char *header_names[2]; const unsigned char *data; size_t size; struct istream *input; int ret; header_names[0] = field; header_names[1] = NULL; headers = mailbox_header_lookup_init(_mail->box, header_names); ret = mail_get_header_stream(_mail, headers, &input); mailbox_header_lookup_unref(&headers); if (ret < 0) return -1; while (i_stream_read_data(input, &data, &size, 0) > 0) i_stream_skip(input, size); /* the header should cached now. */ return index_mail_get_headers(_mail, field, decode_to_utf8, value_r); }
struct mailbox_header_lookup_ctx * dsync_mail_get_hash_headers(struct mailbox *box) { return mailbox_header_lookup_init(box, hashed_headers); }