/* Copyright (c) 2007-2018 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "istream-private.h"
#include "istream-dot.h"
struct dot_istream {
/* how far in string "\r\n.\r" are we */
unsigned int state;
/* state didn't actually start with \r */
/* state didn't contain \n either (only at the beginnign of stream) */
/* we've seen the "." line, keep returning EOF */
};
{
if (size == 0) {
if (ret <= 0) {
/* we didn't see "." line */
"dot-input stream ends without '.' line");
}
return ret;
}
}
return -2;
return 1;
}
{
unsigned int i = 0;
}
{
unsigned int i = 0;
if (!dstream->state_no_cr)
if (dstream->state_no_lf)
else {
/* \r\n.\r seen, go back to \r state */
}
}
{
if (dstream->send_last_lf) {
}
}
static ssize_t
{
}
return ret;
}
{
/* @UNSAFE */
const unsigned char *data;
return -2;
} else {
}
}
/* we have to update stream->pos before reading more data */
return -1;
if (ret1 != 0)
return ret1;
}
case 0:
break;
case 1:
/* CR seen */
if (data[i] == '\n')
else {
goto end;
}
break;
case 2:
/* [CR]LF seen */
if (data[i] == '.')
else {
goto end;
}
break;
case 3:
/* [CR]LF. seen */
if (data[i] == '\r')
else if (data[i] == '\n') {
/* EOF */
i++;
goto end;
} else {
/* drop the initial dot */
goto end;
}
break;
case 4:
/* [CR]LF.CR seen */
if (data[i] == '\n') {
/* EOF */
i++;
goto end;
} else {
/* drop the initial dot */
goto end;
}
}
if (data[i] == '\r') {
} else if (data[i] == '\n') {
} else {
}
}
}
end:
if (ret == 0)
return i_stream_dot_read(stream);
return ret;
}
{
i_stream_get_fd(input), 0);
}