Mercurial > dovecot > original-hg > dovecot-1.2
view src/lib-index/mbox/mbox-append.c @ 1276:3607a2b4f011 HEAD
Added index->append_abort() to abort append cleanly.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Wed, 05 Mar 2003 03:41:36 +0200 |
parents | 411006be3c66 |
children | 2ea9661542ee |
line wrap: on
line source
/* Copyright (C) 2002 Timo Sirainen */ #include "lib.h" #include "ioloop.h" #include "istream.h" #include "hex-binary.h" #include "md5.h" #include "mbox-index.h" #include "mail-index-util.h" static int mbox_index_append_next(struct mail_index *index, struct istream *input) { struct mail_index_record *rec; struct mail_index_update *update; struct mbox_header_context ctx; time_t internal_date; uoff_t abs_start_offset, eoh_offset; const unsigned char *data; unsigned char md5_digest[16]; size_t size, pos; int failed; /* get the From-line */ pos = 0; while (i_stream_read_data(input, &data, &size, pos) > 0) { for (; pos < size; pos++) { if (data[pos] == '\n') break; } if (pos < size) break; } if (pos == size || size <= 5 || strncmp((const char *) data, "From ", 5) != 0) { /* a) no \n found, or line too long b) not a From-line */ index_set_error(index, "Error indexing mbox file %s: " "From-line not found where expected", index->mailbox_path); index->set_flags |= MAIL_INDEX_FLAG_FSCK; return FALSE; } /* parse the From-line */ internal_date = mbox_from_parse_date(data + 5, size - 5); if (internal_date == (time_t)-1) internal_date = ioloop_time; i_stream_skip(input, pos+1); abs_start_offset = input->start_offset + input->v_offset; /* now, find the end of header. also stops at "\nFrom " if it's found (broken messages) */ mbox_skip_header(input); eoh_offset = input->v_offset; /* add message to index */ rec = index->append_begin(index); if (rec == NULL) return FALSE; update = index->update_begin(index, rec); index->update_field_raw(update, DATA_HDR_INTERNAL_DATE, &internal_date, sizeof(internal_date)); /* location = offset to beginning of headers in message */ index->update_field_raw(update, DATA_FIELD_LOCATION, &abs_start_offset, sizeof(uoff_t)); /* parse the header and cache wanted fields. get the message flags from Status and X-Status fields. temporarily limit the stream length so the message body is parsed properly. the stream length limit is raised again by mbox_header_cb after reading the headers. it uses Content-Length if available or finds the next From-line. */ mbox_header_init_context(&ctx, index, input); ctx.set_read_limit = TRUE; i_stream_seek(input, abs_start_offset - input->start_offset); i_stream_set_read_limit(input, eoh_offset); mail_index_update_headers(update, input, 0, mbox_header_cb, &ctx); i_stream_seek(input, input->v_limit); i_stream_set_read_limit(input, 0); /* save MD5 */ md5_final(&ctx.md5, md5_digest); index->update_field_raw(update, DATA_FIELD_MD5, md5_digest, sizeof(md5_digest)); if (!index->update_end(update)) { index->append_abort(index, rec); failed = TRUE; } else { /* save message flags */ rec->msg_flags = ctx.flags; mail_index_mark_flag_changes(index, rec, 0, rec->msg_flags); failed = FALSE; if (!index->append_end(index, rec)) failed = TRUE; } mbox_header_free_context(&ctx); return !failed; } int mbox_index_append(struct mail_index *index, struct istream *input) { int ret; if (input->v_offset == input->v_size) { /* no new data */ return TRUE; } if (!index->set_lock(index, MAIL_LOCK_EXCLUSIVE)) return FALSE; for (;;) { if (input->start_offset + input->v_offset != 0) { /* we're at the [\r]\n before the From-line, skip it */ if (!mbox_skip_crlf(input)) { index_set_error(index, "Error indexing mbox file %s: " "LF not found where expected", index->mailbox_path); index->set_flags |= MAIL_INDEX_FLAG_FSCK; return FALSE; } } if (input->v_offset == input->v_size) break; t_push(); ret = mbox_index_append_next(index, input); t_pop(); if (!ret) return FALSE; } return TRUE; }