ostream-dot.c revision 83773f7eb5e12e68f5efee7278bdab35d2ee84c0
/* Copyright (c) 2013-2015 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "array.h"
#include "ostream-private.h"
#include "ostream-dot.h"
enum dot_ostream_state {
STREAM_STATE_INIT = 0,
};
struct dot_ostream {
struct ostream_private ostream;
enum dot_ostream_state state;
bool force_extra_crlf;
};
static int
{
int ret;
/* make space for the dot line */
if (ret < 0)
return ret;
}
}
;
!dstream->force_extra_crlf) {
} else {
}
return ret;
}
static void
{
if (close_parent)
}
static ssize_t
{
const struct const_iovec *iov_new;
unsigned int count, i;
/* error / we still couldn't flush existing data to
parent stream. */
return ret;
}
/* check for dots */
struct const_iovec iovn;
p = data;
char add = 0;
/* none */
case STREAM_STATE_NONE:
switch (*p) {
case '\n':
/* add missing CR */
add = '\r';
break;
case '\r':
break;
}
break;
/* got CR */
case STREAM_STATE_CR:
switch (*p) {
case '\r':
break;
case '\n':
break;
default:
break;
}
break;
/* got CRLF, or the first line */
case STREAM_STATE_INIT:
case STREAM_STATE_CRLF:
switch (*p) {
case '\r':
break;
case '\n':
/* add missing CR */
add = '\r';
break;
case '.':
/* add dot */
add = '.';
default:
break;
}
break;
case STREAM_STATE_DONE:
i_unreached();
}
if (add != 0) {
if (chunk > 0) {
/* forward chunk to new iovec */
data = p;
}
/* insert byte (substitute one with pair) */
data++;
max_bytes -= 2;
added++;
sent++;
}
}
if (max_bytes == 0)
break;
if (chunk > 0) {
}
}
/* send */
if (count == 0) {
ret = 0;
return -1;
}
/* all must be sent */
return sent;
}
struct ostream *
{
struct dot_ostream *dstream;
}