/* Copyright (c) 2003-2018 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "buffer.h"
#include "istream-private.h"
#include "istream-raw-mbox.h"
#include "mbox-from.h"
struct raw_mbox_istream {
};
{
}
{
const unsigned char *buf, *p;
char *sender;
unsigned int skip;
int tz;
/* from_offset points to "\nFrom ", so unless we're at the beginning
of the file, skip the initial \n */
if (rstream->from_offset == 0)
skip = 0;
else {
skip = 1;
if (*buf == '\r')
skip++;
}
if (ret < 0) {
if (ret == -2) {
/* From_-line is too long, but we should be
able to parse what we have so far. */
break;
}
/* EOF shouldn't happen */
return -1;
}
}
/* beginning of mbox */
/* broken From - should happen only at beginning of
file if this isn't a mbox.. */
"mbox file doesn't begin with 'From ' line");
return -1;
}
} else {
}
/* skip over From-line */
if (line_pos == 0) {
/* line was too long. skip the input until we find LF. */
if (p != NULL)
break;
}
if (ret <= 0) {
/* EOF shouldn't happen */
return -1;
}
}
return 0;
}
{
/* Header didn't have ending \n */
} else {
/* "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 */
}
}
{
const unsigned char *buf;
const char *fromp;
char *sender;
return -1;
return -1;
}
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) {
/* From_-line is longer than our input buffer.
finish the check without seeing the LF. */
/* we've read everything our parent stream
has to offer. */
return -2;
}
/* parent stream is full, but we haven't returned
all its bytes to our caller yet. */
/* 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) {
"Next message unexpectedly corrupted in mbox file "
"%s at %"PRIuUOFF_T,
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. */
i++;
/* CR also belongs to it. */
crlf_ending = TRUE;
from_start_pos = i - 7;
} else {
crlf_ending = FALSE;
from_start_pos = i - 6;
}
from_after_pos = i;
if (ret == -2) {
/* even if we don't have the
whole line, we need to
finish this check now. */
goto mbox_verify;
}
}
/* we have the whole From-line here now.
See if it's a valid one. */
&received_time, &tz,
&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? */
"Next message unexpectedly lost from mbox file "
return -1;
}
return i_stream_raw_mbox_read(stream);
ret = -2;
} else {
}
return ret;
}
{
rstream->input_peak_offset = 0;
}
{
rstream->input_peak_offset = 0;
}
static int
{
return -1;
}
return 0;
}
{
}
{
const unsigned char *data;
char *sender;
int tz;
/* minimal: "From x Thu Nov 29 22:33:52 2001" = 31 chars */
do {
if (size >= 31)
break;
/* EOF */
return 1;
}
data += 6;
size -= 6;
data += 7;
size -= 7;
} else {
return 0;
}
break;
}
return 0;
return 1;
}
{
return rstream->from_offset;
}
{
(void)i_stream_read(stream);
i_error("Unexpectedly lost From-line from mbox file %s at "
return -1;
}
if (stream->stream_errno != 0)
return -1;
return 0;
}
{
return 0;
}
if (i_stream_read(stream) < 0) {
i_error("Unexpectedly lost From-line from mbox file "
"%s at %"PRIuUOFF_T,
} else {
}
return -1;
}
}
return 0;
}
{
const unsigned char *data;
return -1;
/* 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. */
*body_size_r = body_size;
return 0;
}
/* If header_missing_eoh is set, the message body begins with
a From_-line and the body_offset is pointing to the line
*before* the first line of the body, i.e. the empty line
separating the headers from the body. If that is the case,
we'll have to skip over the empty line to get the correct
next_body_offset. */
if (rstream->header_missing_eoh) {
}
if (istream_raw_mbox_is_valid_from(rstream) > 0) {
return 0;
}
/* invalid expected_body_size */
}
*body_size_r = body_size;
return 0;
}
/* have to read through the message body */
if (stream->stream_errno != 0)
return -1;
return 0;
}
{
(void)i_stream_read(stream);
return rstream->received_time;
}
{
(void)i_stream_read(stream);
}
{
return rstream->crlf_ending;
}
{
&body_size) < 0)
return -1;
return 0;
}
{
bool check;
/* reset any (corruption) errors */
stream->stream_errno = 0;
/* if seeked is FALSE, we unlocked in the middle. don't try to use
any cached state then. */
/* back to beginning of current message */
} else {
}
if (check)
(void)i_stream_read(stream);
}
{
}
{
}
{
}
{
}
{
}