diff options
Diffstat (limited to 'usr.sbin/smtpd/envelope.c')
-rw-r--r-- | usr.sbin/smtpd/envelope.c | 175 |
1 files changed, 174 insertions, 1 deletions
diff --git a/usr.sbin/smtpd/envelope.c b/usr.sbin/smtpd/envelope.c index 6264f1bfd6d..5a2014b3f13 100644 --- a/usr.sbin/smtpd/envelope.c +++ b/usr.sbin/smtpd/envelope.c @@ -1,4 +1,4 @@ -/* $OpenBSD: envelope.c,v 1.4 2012/01/15 16:47:49 chl Exp $ */ +/* $OpenBSD: envelope.c,v 1.5 2012/06/01 09:24:58 eric Exp $ */ /* * Copyright (c) 2011 Gilles Chehade <gilles@openbsd.org> @@ -87,6 +87,179 @@ envelope_set_errormsg(struct envelope *e, char *fmt, ...) strlcpy(e->errorline + (sizeof(e->errorline) - 4), "...", 4); } +int +envelope_load_file(struct envelope *ep, FILE *fp) +{ + char *buf, *lbuf; + char *field; + size_t len; + enum envelope_field fields[] = { + EVP_VERSION, + EVP_ID, + EVP_HOSTNAME, + EVP_SOCKADDR, + EVP_HELO, + EVP_SENDER, + EVP_RCPT, + EVP_DEST, + EVP_TYPE, + EVP_CTIME, + EVP_EXPIRE, + EVP_RETRY, + EVP_LASTTRY, + EVP_FLAGS, + EVP_ERRORLINE, + EVP_MDA_METHOD, + EVP_MDA_BUFFER, + EVP_MDA_USER, + EVP_MTA_RELAY_HOST, + EVP_MTA_RELAY_PORT, + EVP_MTA_RELAY_CERT, + EVP_MTA_RELAY_FLAGS, + EVP_MTA_RELAY_AUTHMAP + }; + int i; + int n; + int ret; + + n = sizeof(fields) / sizeof(enum envelope_field); + bzero(ep, sizeof (*ep)); + lbuf = NULL; + while ((buf = fgetln(fp, &len))) { + if (buf[len - 1] == '\n') + buf[len - 1] = '\0'; + else { + if ((lbuf = malloc(len + 1)) == NULL) + err(1, NULL); + memcpy(lbuf, buf, len); + lbuf[len] = '\0'; + buf = lbuf; + } + + for (i = 0; i < n; ++i) { + field = envelope_ascii_field_name(fields[i]); + len = strlen(field); + if (! strncasecmp(field, buf, len)) { + /* skip kw and tailing whitespaces */ + buf += len; + while (*buf && isspace(*buf)) + buf++; + + /* we *want* ':' */ + if (*buf != ':') + continue; + buf++; + + /* skip whitespaces after separator */ + while (*buf && isspace(*buf)) + buf++; + + ret = envelope_ascii_load(fields[i], ep, buf); + if (ret == 0) + goto err; + break; + } + } + + /* unknown keyword */ + if (i == n) + goto err; + } + free(lbuf); + return 1; + +err: + free(lbuf); + return 0; +} + +int +envelope_dump_file(struct envelope *ep, FILE *fp) +{ + char buf[8192]; + + enum envelope_field fields[] = { + EVP_VERSION, + EVP_ID, + EVP_TYPE, + EVP_HELO, + EVP_HOSTNAME, + EVP_ERRORLINE, + EVP_SOCKADDR, + EVP_SENDER, + EVP_RCPT, + EVP_DEST, + EVP_CTIME, + EVP_LASTTRY, + EVP_EXPIRE, + EVP_RETRY, + EVP_FLAGS + }; + enum envelope_field mda_fields[] = { + EVP_MDA_METHOD, + EVP_MDA_BUFFER, + EVP_MDA_USER + }; + enum envelope_field mta_fields[] = { + EVP_MTA_RELAY_HOST, + EVP_MTA_RELAY_PORT, + EVP_MTA_RELAY_CERT, + EVP_MTA_RELAY_AUTHMAP, + EVP_MTA_RELAY_FLAGS + }; + enum envelope_field *pfields = NULL; + int i; + int n; + + n = sizeof(fields) / sizeof(enum envelope_field); + for (i = 0; i < n; ++i) { + bzero(buf, sizeof buf); + if (! envelope_ascii_dump(fields[i], ep, buf, sizeof buf)) + goto err; + if (buf[0] == '\0') + continue; + fprintf(fp, "%s: %s\n", + envelope_ascii_field_name(fields[i]), buf); + } + + switch (ep->type) { + case D_MDA: + pfields = mda_fields; + n = sizeof(mda_fields) / sizeof(enum envelope_field); + break; + case D_MTA: + pfields = mta_fields; + n = sizeof(mta_fields) / sizeof(enum envelope_field); + break; + case D_BOUNCE: + /* nothing ! */ + break; + default: + goto err; + } + + if (pfields) { + for (i = 0; i < n; ++i) { + bzero(buf, sizeof buf); + if (! envelope_ascii_dump(pfields[i], ep, buf, + sizeof buf)) + goto err; + if (buf[0] == '\0') + continue; + fprintf(fp, "%s: %s\n", + envelope_ascii_field_name(pfields[i]), buf); + } + } + + if (fflush(fp) != 0) + goto err; + + return 1; + +err: + return 0; +} + char * envelope_ascii_field_name(enum envelope_field field) { |