summaryrefslogtreecommitdiff
path: root/usr.sbin/smtpd/queue_fsqueue.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/smtpd/queue_fsqueue.c')
-rw-r--r--usr.sbin/smtpd/queue_fsqueue.c186
1 files changed, 71 insertions, 115 deletions
diff --git a/usr.sbin/smtpd/queue_fsqueue.c b/usr.sbin/smtpd/queue_fsqueue.c
index 1488b356ff2..f498fbf71aa 100644
--- a/usr.sbin/smtpd/queue_fsqueue.c
+++ b/usr.sbin/smtpd/queue_fsqueue.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: queue_fsqueue.c,v 1.43 2012/07/02 13:22:14 eric Exp $ */
+/* $OpenBSD: queue_fsqueue.c,v 1.44 2012/07/08 18:13:08 chl Exp $ */
/*
* Copyright (c) 2011 Gilles Chehade <gilles@openbsd.org>
@@ -42,25 +42,18 @@
#include "smtpd.h"
#include "log.h"
-enum queue_kind {
- Q_INCOMING,
- Q_QUEUE,
- Q_CORRUPT
-};
-
-static int fsqueue_envelope_load(enum queue_kind, struct envelope *);
-static int fsqueue_envelope_update(enum queue_kind, struct envelope *);
-static int fsqueue_envelope_delete(enum queue_kind, struct envelope *);
+static int fsqueue_envelope_load(struct envelope *);
+static int fsqueue_envelope_update(struct envelope *);
+static int fsqueue_envelope_delete(struct envelope *);
-static int fsqueue_message_create(enum queue_kind, u_int32_t *);
-static int fsqueue_message_commit(enum queue_kind, u_int32_t);
-static int fsqueue_message_fd_r(enum queue_kind, u_int32_t);
-static int fsqueue_message_fd_rw(enum queue_kind, u_int32_t);
-static int fsqueue_message_delete(enum queue_kind, u_int32_t);
-static int fsqueue_message_corrupt(enum queue_kind, u_int32_t);
+static int fsqueue_message_create(u_int32_t *);
+static int fsqueue_message_commit(u_int32_t);
+static int fsqueue_message_fd_r(u_int32_t);
+static int fsqueue_message_delete(u_int32_t);
+static int fsqueue_message_corrupt(u_int32_t);
-static int fsqueue_message_path(enum queue_kind, uint32_t, char *, size_t);
-static int fsqueue_envelope_path(enum queue_kind, u_int64_t, char *, size_t);
+static int fsqueue_message_path(uint32_t, char *, size_t);
+static int fsqueue_envelope_path(u_int64_t, char *, size_t);
static int fsqueue_envelope_dump_atomic(char *, struct envelope *);
static int fsqueue_init(int);
@@ -71,13 +64,9 @@ static void *fsqueue_qwalk_new(u_int32_t);
static int fsqueue_qwalk(void *, u_int64_t *);
static void fsqueue_qwalk_close(void *);
-#define PATH_INCOMING "/incoming"
#define PATH_QUEUE "/queue"
#define PATH_CORRUPT "/corrupt"
-#define PATH_MESSAGE "/message"
-#define PATH_ENVELOPES "/envelopes"
-
#define PATH_EVPTMP PATH_INCOMING "/envelope.tmp"
struct queue_backend queue_backend_fs = {
@@ -90,46 +79,30 @@ struct queue_backend queue_backend_fs = {
};
static int
-fsqueue_message_path(enum queue_kind qkind, uint32_t msgid, char *buf, size_t len)
+fsqueue_message_path(uint32_t msgid, char *buf, size_t len)
{
- switch (qkind) {
- case Q_QUEUE:
- return bsnprintf(buf, len, "%s/%03x/%08x",
- PATH_QUEUE,
- msgid & 0xfff,
- msgid);
- case Q_INCOMING:
- case Q_CORRUPT:
- return bsnprintf(buf, len, "%s/%08x",
- qkind == Q_INCOMING ? PATH_INCOMING : PATH_CORRUPT,
- msgid);
- default:
- fatalx("fsqueue_message_path: unsupported queue kind.");
- }
- return (0);
+ return bsnprintf(buf, len, "%s/%03x/%08x",
+ PATH_QUEUE,
+ msgid & 0xfff,
+ msgid);
}
static int
-fsqueue_envelope_path(enum queue_kind qkind, uint64_t evpid, char *buf, size_t len)
+fsqueue_message_corrupt_path(uint32_t msgid, char *buf, size_t len)
{
- switch (qkind) {
- case Q_QUEUE:
- return bsnprintf(buf, len, "%s/%03x/%08x%s/%016" PRIx64,
- PATH_QUEUE,
- evpid_to_msgid(evpid) & 0xfff,
- evpid_to_msgid(evpid),
- PATH_ENVELOPES, evpid);
- case Q_INCOMING:
- case Q_CORRUPT:
- return bsnprintf(buf, len, "%s/%08x%s/%016" PRIx64,
- qkind == Q_INCOMING ? PATH_INCOMING : PATH_CORRUPT,
- evpid_to_msgid(evpid),
- PATH_ENVELOPES, evpid);
- default:
- fatalx("fsqueue_envelope_path: unsupported queue kind.");
- }
+ return bsnprintf(buf, len, "%s/%08x",
+ PATH_CORRUPT,
+ msgid);
+}
- return (0);
+static int
+fsqueue_envelope_path(uint64_t evpid, char *buf, size_t len)
+{
+ return bsnprintf(buf, len, "%s/%03x/%08x%s/%016" PRIx64,
+ PATH_QUEUE,
+ evpid_to_msgid(evpid) & 0xfff,
+ evpid_to_msgid(evpid),
+ PATH_ENVELOPES, evpid);
}
static int
@@ -178,7 +151,7 @@ tempfail:
}
static int
-fsqueue_envelope_create(enum queue_kind qkind, struct envelope *ep)
+fsqueue_envelope_create(struct envelope *ep)
{
char evpname[MAXPATHLEN];
u_int64_t evpid;
@@ -186,7 +159,11 @@ fsqueue_envelope_create(enum queue_kind qkind, struct envelope *ep)
again:
evpid = queue_generate_evpid(evpid_to_msgid(ep->id));
- fsqueue_envelope_path(qkind, evpid, evpname, sizeof(evpname));
+ if (ep->type == D_BOUNCE)
+ fsqueue_envelope_path(evpid, evpname, sizeof(evpname));
+ else
+ queue_envelope_incoming_path(evpid, evpname, sizeof(evpname));
+
if (stat(evpname, &sb) != -1 || errno != ENOENT)
goto again;
ep->id = evpid;
@@ -195,13 +172,13 @@ again:
}
static int
-fsqueue_envelope_load(enum queue_kind qkind, struct envelope *ep)
+fsqueue_envelope_load(struct envelope *ep)
{
char pathname[MAXPATHLEN];
FILE *fp;
int ret;
- fsqueue_envelope_path(qkind, ep->id, pathname, sizeof(pathname));
+ fsqueue_envelope_path(ep->id, pathname, sizeof(pathname));
fp = fopen(pathname, "r");
if (fp == NULL) {
@@ -217,23 +194,23 @@ fsqueue_envelope_load(enum queue_kind qkind, struct envelope *ep)
}
static int
-fsqueue_envelope_update(enum queue_kind qkind, struct envelope *ep)
+fsqueue_envelope_update(struct envelope *ep)
{
char dest[MAXPATHLEN];
- fsqueue_envelope_path(qkind, ep->id, dest, sizeof(dest));
+ fsqueue_envelope_path(ep->id, dest, sizeof(dest));
return (fsqueue_envelope_dump_atomic(dest, ep));
}
static int
-fsqueue_envelope_delete(enum queue_kind qkind, struct envelope *ep)
+fsqueue_envelope_delete(struct envelope *ep)
{
char pathname[MAXPATHLEN];
log_debug("#### %s: queue_envelope_delete: %016" PRIx64,
__func__, ep->id);
- fsqueue_envelope_path(qkind, ep->id, pathname, sizeof(pathname));
+ fsqueue_envelope_path(ep->id, pathname, sizeof(pathname));
if (unlink(pathname) == -1) {
log_debug("######: %s [errno: %d]", pathname, errno);
@@ -243,13 +220,13 @@ fsqueue_envelope_delete(enum queue_kind qkind, struct envelope *ep)
*strrchr(pathname, '/') = '\0';
if (rmdir(pathname) != -1)
- fsqueue_message_delete(qkind, evpid_to_msgid(ep->id));
+ fsqueue_message_delete(evpid_to_msgid(ep->id));
return 1;
}
static int
-fsqueue_message_create(enum queue_kind qkind, u_int32_t *msgid)
+fsqueue_message_create(u_int32_t *msgid)
{
char rootdir[MAXPATHLEN];
char evpdir[MAXPATHLEN];
@@ -259,11 +236,11 @@ again:
*msgid = queue_generate_msgid();
/* prevent possible collision later when moving to Q_QUEUE */
- fsqueue_message_path(Q_QUEUE, *msgid, rootdir, sizeof(rootdir));
+ fsqueue_message_path(*msgid, rootdir, sizeof(rootdir));
if (stat(rootdir, &sb) != -1 || errno != ENOENT)
goto again;
- fsqueue_message_path(qkind, *msgid, rootdir, sizeof(rootdir));
+ queue_message_incoming_path(*msgid, rootdir, sizeof(rootdir));
if (mkdir(rootdir, 0700) == -1) {
if (errno == EEXIST)
goto again;
@@ -291,14 +268,14 @@ again:
}
static int
-fsqueue_message_commit(enum queue_kind qkind, u_int32_t msgid)
+fsqueue_message_commit(u_int32_t msgid)
{
- char rootdir[MAXPATHLEN];
+ char incomingdir[MAXPATHLEN];
char queuedir[MAXPATHLEN];
char msgdir[MAXPATHLEN];
- fsqueue_message_path(qkind, msgid, rootdir, sizeof(rootdir));
- fsqueue_message_path(Q_QUEUE, msgid, msgdir, sizeof(msgdir));
+ queue_message_incoming_path(msgid, incomingdir, sizeof(incomingdir));
+ fsqueue_message_path(msgid, msgdir, sizeof(msgdir));
strlcpy(queuedir, msgdir, sizeof(queuedir));
*strrchr(queuedir, '/') = '\0';
@@ -309,7 +286,7 @@ fsqueue_message_commit(enum queue_kind qkind, u_int32_t msgid)
fatal("fsqueue_message_commit: mkdir");
}
- if (rename(rootdir, msgdir) == -1) {
+ if (rename(incomingdir, msgdir) == -1) {
if (errno == ENOSPC)
return 0;
fatal("fsqueue_message_commit: rename");
@@ -319,12 +296,12 @@ fsqueue_message_commit(enum queue_kind qkind, u_int32_t msgid)
}
static int
-fsqueue_message_fd_r(enum queue_kind qkind, u_int32_t msgid)
+fsqueue_message_fd_r(u_int32_t msgid)
{
int fd;
char path[MAXPATHLEN];
- fsqueue_message_path(qkind, msgid, path, sizeof(path));
+ fsqueue_message_path(msgid, path, sizeof(path));
strlcat(path, PATH_MESSAGE, sizeof(path));
if ((fd = open(path, O_RDONLY)) == -1)
@@ -334,22 +311,12 @@ fsqueue_message_fd_r(enum queue_kind qkind, u_int32_t msgid)
}
static int
-fsqueue_message_fd_rw(enum queue_kind qkind, u_int32_t msgid)
-{
- char path[MAXPATHLEN];
-
- fsqueue_message_path(qkind, msgid, path, sizeof(path));
- strlcat(path, PATH_MESSAGE, sizeof(path));
-
- return open(path, O_CREAT|O_EXCL|O_RDWR, 0600);
-}
-
-static int
-fsqueue_message_delete(enum queue_kind qkind, u_int32_t msgid)
+fsqueue_message_delete(u_int32_t msgid)
{
char rootdir[MAXPATHLEN];
- fsqueue_message_path(qkind, msgid, rootdir, sizeof(rootdir));
+ if (! fsqueue_message_path(msgid, rootdir, sizeof(rootdir)))
+ fatal("fsqueue_message_delete: snprintf");
if (rmtree(rootdir, 0) == -1)
fatal("fsqueue_message_delete: rmtree");
@@ -358,7 +325,7 @@ fsqueue_message_delete(enum queue_kind qkind, u_int32_t msgid)
}
static int
-fsqueue_message_corrupt(enum queue_kind qkind, u_int32_t msgid)
+fsqueue_message_corrupt(u_int32_t msgid)
{
struct stat sb;
char rootdir[MAXPATHLEN];
@@ -366,11 +333,12 @@ fsqueue_message_corrupt(enum queue_kind qkind, u_int32_t msgid)
char buf[64];
int retry = 0;
- fsqueue_message_path(qkind, msgid, rootdir, sizeof(rootdir));
- fsqueue_message_path(Q_CORRUPT, msgid, corruptdir, sizeof(corruptdir));
+ fsqueue_message_path(msgid, rootdir, sizeof(rootdir));
+ fsqueue_message_corrupt_path(msgid, corruptdir, sizeof(corruptdir));
+
again:
if (stat(corruptdir, &sb) != -1 || errno != ENOENT) {
- fsqueue_message_path(Q_CORRUPT, msgid, corruptdir, sizeof(corruptdir));
+ fsqueue_message_corrupt_path(msgid, corruptdir, sizeof(corruptdir));
snprintf(buf, sizeof(buf), ".%i", retry++);
strlcat(corruptdir, buf, sizeof(corruptdir));
goto again;
@@ -386,17 +354,12 @@ static int
fsqueue_init(int server)
{
unsigned int n;
- char *paths[] = { PATH_INCOMING, PATH_QUEUE, PATH_CORRUPT };
+ char *paths[] = { PATH_QUEUE, PATH_CORRUPT };
char path[MAXPATHLEN];
int ret;
- if (!fsqueue_envelope_path(Q_QUEUE, 0, path, sizeof(path)))
+ if (!fsqueue_envelope_path(0, path, sizeof(path)))
errx(1, "cannot store envelope path in %s", PATH_QUEUE);
- if (!fsqueue_envelope_path(Q_INCOMING, 0, path, sizeof(path)))
- errx(1, "cannot store envelope path in %s", PATH_INCOMING);
-
- if (server)
- mvpurge(PATH_SPOOL PATH_INCOMING, PATH_SPOOL PATH_PURGE);
ret = 1;
for (n = 0; n < nitems(paths); n++) {
@@ -416,22 +379,19 @@ fsqueue_message(enum queue_op qop, u_int32_t *msgid)
{
switch (qop) {
case QOP_CREATE:
- return fsqueue_message_create(Q_INCOMING, msgid);
+ return fsqueue_message_create(msgid);
case QOP_DELETE:
- return fsqueue_message_delete(Q_INCOMING, *msgid);
+ return fsqueue_message_delete(*msgid);
case QOP_COMMIT:
- return fsqueue_message_commit(Q_INCOMING, *msgid);
+ return fsqueue_message_commit(*msgid);
case QOP_FD_R:
- return fsqueue_message_fd_r(Q_QUEUE, *msgid);
-
- case QOP_FD_RW:
- return fsqueue_message_fd_rw(Q_INCOMING, *msgid);
+ return fsqueue_message_fd_r(*msgid);
case QOP_CORRUPT:
- return fsqueue_message_corrupt(Q_QUEUE, *msgid);
+ return fsqueue_message_corrupt(*msgid);
default:
fatalx("queue_fsqueue_message: unsupported operation.");
@@ -445,20 +405,16 @@ fsqueue_envelope(enum queue_op qop, struct envelope *m)
{
switch (qop) {
case QOP_CREATE:
- /* currently, only bounce envelopes are created in queued
- * messages
- */
- return fsqueue_envelope_create(
- m->type == D_BOUNCE ? Q_QUEUE : Q_INCOMING, m);
+ return fsqueue_envelope_create(m);
case QOP_DELETE:
- return fsqueue_envelope_delete(Q_QUEUE, m);
+ return fsqueue_envelope_delete(m);
case QOP_LOAD:
- return fsqueue_envelope_load(Q_QUEUE, m);
+ return fsqueue_envelope_load(m);
case QOP_UPDATE:
- return fsqueue_envelope_update(Q_QUEUE, m);
+ return fsqueue_envelope_update(m);
default:
fatalx("queue_fsqueue_envelope: unsupported operation.");