istream-raw-mbox.c revision 7f773564b94e6054a40d3785cb63c29f1e4d4dee
5e0ce63bb65db34d7f48b34bbb5545fa791781c4Timo Sirainen/* Copyright (C) 2003 Timo Sirainen */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen uoff_t from_offset, hdr_offset, body_offset, mail_size;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainenstatic void _close(struct _iostream *stream __attr_unused__)
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen struct raw_mbox_istream *rstream = (struct raw_mbox_istream *)stream;
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen i_stream_seek(rstream->input, rstream->istream.istream.v_offset);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainenstatic void _set_max_buffer_size(struct _iostream *stream, size_t max_size)
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen struct raw_mbox_istream *rstream = (struct raw_mbox_istream *)stream;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen i_stream_set_max_buffer_size(rstream->input, max_size);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainenstatic void _set_blocking(struct _iostream *stream, int timeout_msecs,
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen struct raw_mbox_istream *rstream = (struct raw_mbox_istream *)stream;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen i_stream_set_blocking(rstream->input, timeout_msecs,
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainenstatic int mbox_read_from_line(struct raw_mbox_istream *rstream)
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen const unsigned char *buf, *p;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen buf = i_stream_get_data(rstream->input, &pos);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen /* from_offset points to "\nFrom ", so unless we're at the beginning
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen of the file, skip the initial \n */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen while ((p = memchr(buf+skip, '\n', pos-skip)) == NULL) {
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen /* EOF - shouldn't happen */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen buf = i_stream_get_data(rstream->input, &pos);
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen /* beginning of mbox */
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainen mbox_from_parse(buf+5, pos-5, &received_time, &sender) < 0) {
1060afdc2fcdf647dbb3bc11647401f1b44a3a8aTimo Sirainen /* broken From - should happen only at beginning of
1060afdc2fcdf647dbb3bc11647401f1b44a3a8aTimo Sirainen file if this isn't a mbox.. */
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainen if (rstream->istream.istream.v_offset == rstream->from_offset) {
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen /* we'll skip over From-line */
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainen rstream->istream.istream.v_offset += line_pos+1;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen rstream->hdr_offset = rstream->istream.istream.v_offset;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen struct raw_mbox_istream *rstream = (struct raw_mbox_istream *)stream;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen const unsigned char *buf;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen /* missing \n from headers */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen i_stream_seek(rstream->input, stream->istream.v_offset);
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen buf = i_stream_get_data(rstream->input, &pos);
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen } while (ret > 0 &&
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen stream->istream.v_offset + pos <= rstream->input_peak_offset);
143cb2e0744e647f8fc637bbdea1106c1587a4bfTimo Sirainen /* we've read the whole file, final byte should be
143cb2e0744e647f8fc637bbdea1106c1587a4bfTimo Sirainen the \n trailer */
7d207b1e77a7b5e3fda640e353acfc86d261fedfTimo Sirainen rstream->mail_size = stream->istream.v_offset + pos -
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen if (stream->istream.v_offset == rstream->from_offset) {
cd1eef2109b4476842b7757f1d69b104196d5941Timo Sirainen /* beginning of message, we haven't yet read our From-line */
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen /* got it. we don't want to return it however,
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen so start again from headers */
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen buf = i_stream_get_data(rstream->input, &pos);
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen /* See if we have From-line here - note that it works right only
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen because all characters are different in mbox_from. */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen eoh_char = rstream->body_offset == (uoff_t)-1 ? '\n' : '\0';
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen for (i = 0; i < pos; i++) {
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen if (buf[i] == eoh_char && i > 0 && buf[i-1] == '\n') {
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen rstream->body_offset = stream->istream.v_offset + i + 1;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen /* potential From-line, see if we have the
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainen rest of the line buffered.
411d6baa37f31d90730e90c4a28c43e1974bbe58Timo Sirainen FIXME: if From-line is longer than input
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen buffer, we break. probably irrelevant.. */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen } else if (from_start_pos != 0) {
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen /* we have the whole From-line here now.
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen See if it's a valid one. */
&sender) == 0) {
from_start_pos = 0;
fromp++;
if (from_start_pos != 0) {
return ret;
const unsigned char *data;
char *sender;
return TRUE;
return FALSE;
return FALSE;
return TRUE;
const unsigned char *data;
return body_size;
int check;
if (check)