commit - a287838f380d0bec3fca2f273a88d5e466dde790
commit + a211223d04eb8add0ba4b89c31473196903d7296
blob - 4b27868ec32fcc96ec3ffd47220c27aebe999789
blob + 511fe85a8f5024c97cd39a4467cb95e31180c0b4
--- smtp_proc.c
+++ smtp_proc.c
uint64_t, uint64_t, char *);
static void smtp_in_link_disconnect(struct smtp_callback *, int, struct timespec *,
uint64_t, char *);
+static void smtp_printf(const char *, ...)
+ __attribute__((__format__ (printf, 1, 2)));
+static void smtp_vprintf(const char *, va_list);
+static void smtp_write(int, short, void *);
+struct smtp_writebuf {
+ char *buf;
+ size_t bufsize;
+ size_t buflen;
+};
+
struct smtp_callback {
char *type;
char *phase;
{
struct event stdinev;
- printf("register|ready\n");
- fflush(stdout);
+ smtp_printf("register|ready\n");
ready = 1;
log_init(debug, LOG_MAIL);
void
smtp_filter_proceed(uint64_t reqid, uint64_t token)
{
- printf("filter-result|%016"PRIx64"|%016"PRIx64"|proceed\n", token,
+ smtp_printf("filter-result|%016"PRIx64"|%016"PRIx64"|proceed\n", token,
reqid);
- fflush(stdout);
}
+static void
+smtp_printf(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ smtp_vprintf(fmt, ap);
+ va_end(ap);
+}
+
+static void
+smtp_vprintf(const char *fmt, va_list ap)
+{
+ va_list cap;
+ static struct smtp_writebuf buf = {NULL, 0, 0};
+ int fmtlen;
+
+ va_copy(cap, ap);
+ fmtlen = vsnprintf(buf.buf + buf.buflen, buf.bufsize - buf.buflen, fmt,
+ ap);
+ if (fmtlen == -1)
+ fatal("vsnprintf");
+ if (fmtlen >= buf.bufsize - buf.buflen) {
+ buf.bufsize = buf.buflen + fmtlen + 1;
+ buf.buf = reallocarray(buf.buf, buf.bufsize,
+ sizeof(*(buf.buf)));
+ if (buf.buf == NULL)
+ fatalx(NULL);
+ fmtlen = vsnprintf(buf.buf + buf.buflen,
+ buf.bufsize - buf.buflen, fmt, cap);
+ if (fmtlen == -1)
+ fatal("vsnprintf");
+ }
+ buf.buflen += fmtlen;
+
+ if (strchr(buf.buf, '\n') != NULL)
+ smtp_write(STDOUT_FILENO, EV_WRITE, &buf);
+}
+
+static void
+smtp_write(int fd, short event, void *arg)
+{
+ struct smtp_writebuf *buf = arg;
+ static struct event ev;
+ static int evset = 0;
+ ssize_t wlen;
+
+ if (buf->buflen == 0)
+ return;
+ if (!evset) {
+ event_set(&ev, fd, EV_WRITE, smtp_write, buf);
+ evset = 1;
+ }
+ wlen = write(fd, buf->buf, buf->buflen);
+ if (wlen == -1) {
+ if (errno != EAGAIN || errno != EINTR)
+ fatal("Failed to write to smtpd");
+ event_add(&ev, NULL);
+ return;
+ }
+ if (wlen < buf->buflen) {
+ memmove(buf->buf, buf->buf + wlen, buf->buflen - wlen);
+ event_add(&ev, NULL);
+ }
+ buf->buflen -= wlen;
+}
+
void
smtp_filter_reject(uint64_t reqid, uint64_t token, int code,
const char *reason, ...)
if (code < 200 || code > 599)
fatalx("Invalid reject code");
- printf("filter-result|%016"PRIx64"|%016"PRIx64"|reject|%d ", token,
+ smtp_printf("filter-result|%016"PRIx64"|%016"PRIx64"|reject|%d ", token,
reqid, code);
va_start(ap, reason);
- vprintf(reason, ap);
+ smtp_vprintf(reason, ap);
va_end(ap);
- putchar('\n');
- fflush(stdout);
+ smtp_printf("\n");
}
void
{
va_list ap;
- printf("filter-result|%016"PRIx64"|%016"PRIx64"|disconnect|421 ",
+ smtp_printf("filter-result|%016"PRIx64"|%016"PRIx64"|disconnect|421 ",
token, reqid);
va_start(ap, reason);
- vprintf(reason, ap);
+ smtp_vprintf(reason, ap);
va_end(ap);
- putchar('\n');
- fflush(stdout);
+ smtp_printf("\n");
}
void
{
va_list ap;
- printf("filter-dataline|%016"PRIx64"|%016"PRIx64"|", token, reqid);
+ smtp_printf("filter-dataline|%016"PRIx64"|%016"PRIx64"|", token, reqid);
va_start(ap, line);
- vprintf(line, ap);
+ smtp_vprintf(line, ap);
va_end(ap);
- putchar('\n');
- fflush(stdout);
+ smtp_printf("\n");
}
static int
return -1;
}
smtp_callbacks[i].cb = cb;
- printf("register|%s|%s|%s\n", type, direction, phase);
+ smtp_printf("register|%s|%s|%s\n", type, direction,
+ phase);
return 0;
}
}