uoff_t from_offset, hdr_offset, body_offset, mail_size;
uoff_t input_peak_offset;
+ unsigned int locked:1;
+ unsigned int seeked:1;
unsigned int crlf_ending:1;
unsigned int corrupted:1;
+ unsigned int mail_size_forced:1;
unsigned int eof:1;
unsigned int header_missing_eoh:1;
};
int eoh_char, tz;
bool crlf_ending = FALSE;
+ i_assert(rstream->seeked);
i_assert(stream->istream.v_offset >= rstream->from_offset);
if (stream->istream.eof)
/* istream_raw_mbox_set_next_offset() used invalid
cached next_offset? */
i_error("Next message unexpectedly lost from mbox file "
- "%s at %"PRIuUOFF_T, rstream->path,
- rstream->hdr_offset + rstream->mail_size);
+ "%s at %"PRIuUOFF_T" (%s)", rstream->path,
+ rstream->hdr_offset + rstream->mail_size,
+ rstream->mail_size_forced ? "cached" : "noncached");
rstream->eof = TRUE;
rstream->corrupted = TRUE;
rstream->istream.istream.stream_errno = EINVAL;
struct raw_mbox_istream *rstream =
(struct raw_mbox_istream *)stream->real_stream;
+ i_assert(rstream->seeked);
+
return rstream->from_offset;
}
struct raw_mbox_istream *rstream =
(struct raw_mbox_istream *)stream->real_stream;
+ i_assert(rstream->seeked);
+
if (rstream->hdr_offset == rstream->from_offset)
(void)i_stream_raw_mbox_read(&rstream->istream);
uoff_t offset;
size_t pos;
+ i_assert(rstream->seeked);
+
if (rstream->body_offset != (uoff_t)-1)
return rstream->body_offset;
size_t size;
uoff_t old_offset, body_size, next_body_offset;
+ i_assert(rstream->seeked);
i_assert(rstream->hdr_offset != (uoff_t)-1);
i_assert(rstream->body_offset != (uoff_t)-1);
struct raw_mbox_istream *rstream =
(struct raw_mbox_istream *)stream->real_stream;
+ i_assert(rstream->seeked);
+
if (rstream->received_time == (time_t)-1)
(void)i_stream_raw_mbox_read(&rstream->istream);
return rstream->received_time;
struct raw_mbox_istream *rstream =
(struct raw_mbox_istream *)stream->real_stream;
+ i_assert(rstream->seeked);
+
if (rstream->sender == NULL)
(void)i_stream_raw_mbox_read(&rstream->istream);
return rstream->sender == NULL ? "" : rstream->sender;
struct raw_mbox_istream *rstream =
(struct raw_mbox_istream *)stream->real_stream;
+ i_assert(rstream->seeked);
+
return rstream->crlf_ending;
}
(struct raw_mbox_istream *)stream->real_stream;
bool check;
+ i_assert(rstream->locked);
+
rstream->corrupted = FALSE;
rstream->eof = FALSE;
rstream->istream.istream.eof = FALSE;
- if (rstream->mail_size != (uoff_t)-1 &&
+ /* if seeked is FALSE, we unlocked in the middle. don't try to use
+ any cached state then. */
+ if (rstream->mail_size != (uoff_t)-1 && rstream->seeked &&
rstream->hdr_offset + rstream->mail_size == offset) {
istream_raw_mbox_next(stream, (uoff_t)-1);
return 0;
}
- if (offset == rstream->from_offset) {
+ if (offset == rstream->from_offset && rstream->seeked) {
/* back to beginning of current message */
offset = rstream->hdr_offset;
check = offset == 0;
rstream->hdr_offset = offset;
check = TRUE;
}
+ rstream->seeked = TRUE;
i_stream_seek_mark(stream, offset);
i_stream_seek_mark(rstream->istream.parent, offset);
i_assert(rstream->hdr_offset != (uoff_t)-1);
+ rstream->mail_size_forced = TRUE;
rstream->mail_size = offset - rstream->hdr_offset;
}
return rstream->corrupted;
}
+
+void istream_raw_mbox_set_locked(struct istream *stream)
+{
+ struct raw_mbox_istream *rstream =
+ (struct raw_mbox_istream *)stream->real_stream;
+
+ rstream->locked = TRUE;
+}
+
+void istream_raw_mbox_set_unlocked(struct istream *stream)
+{
+ struct raw_mbox_istream *rstream =
+ (struct raw_mbox_istream *)stream->real_stream;
+
+ rstream->locked = FALSE;
+ rstream->seeked = FALSE;
+}
if (mbox->mbox_file_stream != NULL) {
/* read-only mbox stream */
i_assert(mbox->mbox_fd == -1 && mbox->mbox_readonly);
+ } else {
+ if (mbox->mbox_fd == -1) {
+ if (mbox_file_open(mbox) < 0)
+ return -1;
+ }
- mbox->mbox_stream =
- i_stream_create_raw_mbox(mbox->mbox_file_stream,
- mbox->path);
- return 0;
- }
-
- if (mbox->mbox_fd == -1) {
- if (mbox_file_open(mbox) < 0)
- return -1;
- }
-
- if (mbox->mbox_writeonly)
- mbox->mbox_file_stream = i_stream_create_from_data(NULL, 0);
- else {
- mbox->mbox_file_stream =
- i_stream_create_fd(mbox->mbox_fd,
- MAIL_READ_BLOCK_SIZE, FALSE);
+ if (mbox->mbox_writeonly) {
+ mbox->mbox_file_stream =
+ i_stream_create_from_data(NULL, 0);
+ } else {
+ mbox->mbox_file_stream =
+ i_stream_create_fd(mbox->mbox_fd,
+ MAIL_READ_BLOCK_SIZE, FALSE);
+ }
}
mbox->mbox_stream = i_stream_create_raw_mbox(mbox->mbox_file_stream,
mbox->path);
+ if (mbox->mbox_lock_type != F_UNLCK)
+ istream_raw_mbox_set_locked(mbox->mbox_stream);
return 0;
}