aboutsummaryrefslogtreecommitdiffstats
path: root/smtpd/rfc5322.c
diff options
context:
space:
mode:
Diffstat (limited to 'smtpd/rfc5322.c')
-rw-r--r--smtpd/rfc5322.c266
1 files changed, 0 insertions, 266 deletions
diff --git a/smtpd/rfc5322.c b/smtpd/rfc5322.c
deleted file mode 100644
index 0af66772..00000000
--- a/smtpd/rfc5322.c
+++ /dev/null
@@ -1,266 +0,0 @@
-/* $OpenBSD: rfc5322.c,v 1.2 2018/10/24 18:59:29 gilles Exp $ */
-
-/*
- * Copyright (c) 2018 Eric Faurot <eric@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "includes.h"
-
-#include <ctype.h>
-#include <errno.h>
-#include <limits.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "rfc5322.h"
-
-struct buf {
- char *buf;
- size_t bufsz;
- size_t buflen;
- size_t bufmax;
-};
-
-static int buf_alloc(struct buf *, size_t);
-static int buf_grow(struct buf *, size_t);
-static int buf_cat(struct buf *, const char *);
-
-struct rfc5322_parser {
- const char *line;
- int state; /* last parser state */
- int next; /* parser needs data */
- int unfold;
- const char *currhdr;
- struct buf hdr;
- struct buf val;
-};
-
-struct rfc5322_parser *
-rfc5322_parser_new(void)
-{
- struct rfc5322_parser *parser;
-
- parser = calloc(1, sizeof(*parser));
- if (parser == NULL)
- return NULL;
-
- rfc5322_clear(parser);
- parser->hdr.bufmax = 1024;
- parser->val.bufmax = 65536;
-
- return parser;
-}
-
-void
-rfc5322_free(struct rfc5322_parser *parser)
-{
- free(parser->hdr.buf);
- free(parser->val.buf);
- free(parser);
-}
-
-void
-rfc5322_clear(struct rfc5322_parser *parser)
-{
- parser->line = NULL;
- parser->state = RFC5322_NONE;
- parser->next = 0;
- parser->hdr.buflen = 0;
- parser->val.buflen = 0;
-}
-
-int
-rfc5322_push(struct rfc5322_parser *parser, const char *line)
-{
- if (parser->line) {
- errno = EALREADY;
- return -1;
- }
-
- parser->line = line;
- parser->next = 0;
-
- return 0;
-}
-
-int
-rfc5322_unfold_header(struct rfc5322_parser *parser)
-{
- if (parser->unfold) {
- errno = EALREADY;
- return -1;
- }
-
- if (parser->currhdr == NULL) {
- errno = EOPNOTSUPP;
- return -1;
- }
-
- if (buf_cat(&parser->val, parser->currhdr) == -1)
- return -1;
-
- parser->currhdr = NULL;
- parser->unfold = 1;
-
- return 0;
-}
-
-static int
-_rfc5322_next(struct rfc5322_parser *parser, struct rfc5322_result *res)
-{
- size_t len;
- const char *pos, *line;
-
- line = parser->line;
-
- switch(parser->state) {
-
- case RFC5322_HEADER_START:
- case RFC5322_HEADER_CONT:
- res->hdr = parser->hdr.buf;
-
- if (line && (line[0] == ' ' || line[0] == '\t')) {
- parser->line = NULL;
- parser->next = 1;
- if (parser->unfold) {
- if (buf_cat(&parser->val, "\n") == -1 ||
- buf_cat(&parser->val, line) == -1)
- return -1;
- }
- res->value = line;
- return RFC5322_HEADER_CONT;
- }
-
- if (parser->unfold) {
- parser->val.buflen = 0;
- parser->unfold = 0;
- res->value = parser->val.buf;
- }
- return RFC5322_HEADER_END;
-
- case RFC5322_NONE:
- case RFC5322_HEADER_END:
- if (line && (pos = strchr(line, ':'))) {
- len = pos - line;
- if (buf_grow(&parser->hdr, len + 1) == -1)
- return -1;
- (void)memcpy(parser->hdr.buf, line, len);
- parser->hdr.buf[len] = '\0';
- parser->hdr.buflen = len + 1;
- parser->line = NULL;
- parser->next = 1;
- parser->currhdr = pos + 1;
- res->hdr = parser->hdr.buf;
- res->value = pos + 1;
- return RFC5322_HEADER_START;
- }
-
- return RFC5322_END_OF_HEADERS;
-
- case RFC5322_END_OF_HEADERS:
- if (line == NULL)
- return RFC5322_END_OF_MESSAGE;
-
- if (line[0] == '\0') {
- parser->line = NULL;
- parser->next = 1;
- res->value = line;
- return RFC5322_BODY_START;
- }
-
- errno = EINVAL;
- return -1;
-
- case RFC5322_BODY_START:
- case RFC5322_BODY:
- if (line == NULL)
- return RFC5322_END_OF_MESSAGE;
-
- parser->line = NULL;
- parser->next = 1;
- res->value = line;
- return RFC5322_BODY;
-
- case RFC5322_END_OF_MESSAGE:
- errno = ENOMSG;
- return -1;
-
- default:
- errno = EINVAL;
- return -1;
- }
-}
-
-int
-rfc5322_next(struct rfc5322_parser *parser, struct rfc5322_result *res)
-{
- memset(res, 0, sizeof(*res));
-
- if (parser->next)
- return RFC5322_NONE;
-
- return (parser->state = _rfc5322_next(parser, res));
-}
-
-static int
-buf_alloc(struct buf *b, size_t need)
-{
- char *buf;
- size_t alloc;
-
- if (b->buf && b->bufsz >= need)
- return 0;
-
- if (need >= b->bufmax) {
- errno = ERANGE;
- return -1;
- }
-
-#define N 256
- alloc = N * (need / N) + ((need % N) ? N : 0);
-#undef N
- buf = reallocarray(b->buf, alloc, 1);
- if (buf == NULL)
- return -1;
-
- b->buf = buf;
- b->bufsz = alloc;
-
- return 0;
-}
-
-static int
-buf_grow(struct buf *b, size_t sz)
-{
- if (SIZE_T_MAX - b->buflen <= sz) {
- errno = ERANGE;
- return -1;
- }
-
- return buf_alloc(b, b->buflen + sz);
-}
-
-static int
-buf_cat(struct buf *b, const char *s)
-{
- size_t len = strlen(s);
-
- if (buf_grow(b, len + 1) == -1)
- return -1;
-
- (void)memmove(b->buf + b->buflen, s, len + 1);
- b->buflen += len;
- return 0;
-}