istream-raw-mbox.c revision 64a67c0296b120b6e15169ac9d84dec964e55969
/* Copyright (c) 2003-2008 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "buffer.h"
#include "istream-internal.h"
#include "istream-raw-mbox.h"
#include "mbox-from.h"
struct raw_mbox_istream {
struct istream_private istream;
char *sender, *next_sender;
unsigned int crlf_ending:1;
unsigned int corrupted:1;
unsigned int eof:1;
};
{
}
static void
{
}
{
const unsigned char *buf, *p;
char *sender;
int skip;
/* from_offset points to "\nFrom ", so unless we're at the beginning
of the file, skip the initial \n */
skip++;
/* EOF - shouldn't happen */
return -1;
}
}
if (rstream->from_offset != 0) {
}
/* beginning of mbox */
/* broken From - should happen only at beginning of
file if this isn't a mbox.. */
return -1;
}
} else {
}
/* we'll skip over From-line */
return 0;
}
{
/* a) Header didn't have ending \n
b) "headers\n\nFrom ..", the second \n belongs to next
message which we didn't know at the time yet.
The +2 check is for CR+LF linefeeds */
}
}
{
static const char *mbox_from = "\nFrom ";
const unsigned char *buf;
const char *fromp;
char *sender;
int eoh_char;
bool crlf_ending = FALSE;
return -1;
ret = 0;
do {
/* fake our read count. needed because if in the end
we have only one character in buffer and we skip it
(as potential CR), we want to get back to this
i_stream_raw_mbox_read() to read more data. */
break;
}
} while (ret > 0);
if (ret < 0) {
if (ret == -2) {
return -2;
}
/* we've read the whole file, final byte should be
the \n trailer */
pos--;
crlf_ending = TRUE;
pos--;
}
}
/* haven't seen From-line yet, so this mbox
stream is now at EOF */
}
}
}
/* beginning of message, we haven't yet read our From-line */
/* we're at the end of file with CR+LF linefeeds?
need more data to verify it. */
return i_stream_raw_mbox_read(stream);
}
if (mbox_read_from_line(rstream) < 0) {
return -1;
}
/* got it. we don't want to return it however,
so start again from headers */
if (pos == 0)
return i_stream_raw_mbox_read(stream);
}
/* See if we have From-line here - note that it works right only
because all characters are different in mbox_from. */
eoh_char = -1;
}
if (*++fromp == '\0') {
/* potential From-line, see if we have the
rest of the line buffered.
FIXME: if From-line is longer than input
buffer, we break. probably irrelevant.. */
i++;
from_after_pos = i;
from_start_pos = i - 6;
if (from_start_pos > 0 &&
/* CR also belongs to it. */
crlf_ending = TRUE;
} else {
crlf_ending = FALSE;
}
}
/* we have the whole From-line here now.
See if it's a valid one. */
&sender) == 0) {
/* yep, we stop here. */
break;
}
}
} else {
fromp++;
}
}
/* we want to go at least one byte further next time */
/* we're waiting for the \n at the end of From-line */
} else {
/* leave out the beginnings of potential From-line + CR */
if (new_pos > 0)
new_pos--;
}
/* istream_raw_mbox_set_next_offset() used invalid
cached next_offset? */
return -1;
}
return i_stream_raw_mbox_read(stream);
ret = -2;
} else {
}
return ret;
}
{
rstream->input_peak_offset = 0;
}
{
}
static const struct stat *
{
return NULL;
}
{
struct raw_mbox_istream *rstream;
}
{
const unsigned char *data;
char *sender;
/* minimal: "From x Thu Nov 29 22:33:52 2001" = 31 chars */
/* EOF */
return 1;
}
data += 6;
size -= 6;
data += 7;
size -= 7;
} else {
return 0;
}
break;
}
return 0;
return 1;
}
{
struct raw_mbox_istream *rstream =
return rstream->from_offset;
}
{
struct raw_mbox_istream *rstream =
i_error("Unexpectedly lost From-line at "
return (uoff_t)-1;
}
return rstream->hdr_offset;
}
{
struct raw_mbox_istream *rstream =
return rstream->body_offset;
i_error("Unexpectedly lost From-line at "
} else {
}
break;
}
}
return rstream->body_offset;
}
{
struct raw_mbox_istream *rstream =
const unsigned char *data;
/* if we already have the existing body size, use it as long as
it's >= expected body_size. otherwise the previous parsing
may have stopped at a From_-line that belongs to the body. */
return body_size;
if (istream_raw_mbox_is_valid_from(rstream) > 0) {
return expected_body_size;
}
/* invalid expected_body_size */
}
return body_size;
/* have to read through the message body */
}
{
struct raw_mbox_istream *rstream =
return rstream->received_time;
}
{
struct raw_mbox_istream *rstream =
}
{
struct raw_mbox_istream *rstream =
return rstream->crlf_ending;
}
{
struct raw_mbox_istream *rstream =
}
{
struct raw_mbox_istream *rstream =
bool check;
return 0;
}
/* back to beginning of current message */
} else {
}
if (check)
}
{
struct raw_mbox_istream *rstream =
}
{
struct raw_mbox_istream *rstream =
}