summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--maildrop.c90
-rw-r--r--pop3d.c6
-rw-r--r--pop3d.h4
-rw-r--r--session.c12
4 files changed, 68 insertions, 44 deletions
diff --git a/maildrop.c b/maildrop.c
index 12861f7..97c9b9b 100644
--- a/maildrop.c
+++ b/maildrop.c
@@ -33,6 +33,7 @@
#include "pop3d.h"
static void session_imsgev(struct imsgev *, int, struct imsg *);
+static void maildrop_init(struct imsgev *, struct imsg *, struct m_backend *);
static void update(struct imsgev *, struct imsg *, struct m_backend *);
static void retr(struct imsgev *, struct imsg *, struct m_backend *);
static void dele(struct imsgev *, struct imsg *, struct m_backend *);
@@ -48,17 +49,13 @@ static size_t expand(char *, const char *, size_t, struct passwd *);
static struct mdrop m;
pid_t
-maildrop_init(uint32_t session_id, int pair[2], struct passwd *pw,
- int type, const char *path)
+maildrop_setup(uint32_t session_id, int pair[2], struct passwd *pw)
{
struct imsgev iev_session;
struct event ev_sigint, ev_sigterm;
- struct stats stats;
struct m_backend *mb;
- char buf[MAXPATHLEN];
pid_t pid;
- mode_t old_mask;
- int fd, flags, res = -1;
+ extern int mtype;
if ((pid = fork()) != 0)
return (pid);
@@ -70,45 +67,15 @@ maildrop_init(uint32_t session_id, int pair[2], struct passwd *pw,
close(pair[0]);
setproctitle("maildrop");
- if ((mb = m_backend_lookup(type)) == NULL)
+ if ((mb = m_backend_lookup(mtype)) == NULL)
fatalx("maildrop: invalid backend");
- if (expand(buf, path, sizeof(buf), pw) >= sizeof(buf))
- fatalx("maildrop: path truncation");
-
- flags = O_CREAT;
- if (type == M_MBOX)
- flags |= O_RDWR;
- else
- flags |= O_RDONLY;
-
- old_mask = umask(S_IXUSR|S_IXGRP|S_IWOTH|S_IROTH|S_IXOTH);
- if ((fd = open(buf, flags)) == -1)
- logit(LOG_CRIT, "%zu: failed to open %s", session_id , buf);
-
- if (fd != -1) {
- m.fd = fd;
- res = mb->init(&m, &stats.nmsgs, &stats.sz);
- }
-
- umask(old_mask);
event_init();
signal_set(&ev_sigint, SIGINT, sig_handler, NULL);
signal_set(&ev_sigterm, SIGTERM, sig_handler, NULL);
signal_add(&ev_sigint, NULL);
signal_add(&ev_sigterm, NULL);
imsgev_init(&iev_session, pair[1], mb, session_imsgev, needfd);
-
- if (res == 0) {
- imsgev_xcompose(&iev_session, IMSG_MAILDROP_INIT, session_id,
- 0, -1, &stats, sizeof(struct stats), "maildrop_init");
- } else {
- logit(LOG_CRIT, "%zu: maildrop init failed %s",
- session_id, buf);
- imsgev_xcompose(&iev_session, IMSG_MAILDROP_INIT, session_id,
- 0, -1, NULL, 0, "maildrop_init");
- }
-
if (event_dispatch() < 0)
fatal("event_dispatch");
@@ -176,6 +143,9 @@ session_imsgev(struct imsgev *iev, int code, struct imsg *imsg)
switch (code) {
case IMSGEV_IMSG:
switch (imsg->hdr.type) {
+ case IMSG_MAILDROP_INIT:
+ maildrop_init(iev, imsg, mb);
+ break;
case IMSG_MAILDROP_UPDATE:
update(iev, imsg, mb);
break;
@@ -212,6 +182,52 @@ session_imsgev(struct imsgev *iev, int code, struct imsg *imsg)
}
static void
+maildrop_init(struct imsgev *iev, struct imsg *imsg, struct m_backend *mb)
+{
+ struct stats stats;
+ char buf[MAXPATHLEN];
+ struct passwd *pw;
+ extern const char *mpath;
+ extern int mtype;
+ mode_t old_mask;
+ int fd, flags, res = -1;
+ uint32_t session_id = imsg->hdr.peerid;
+ const char *user = imsg->data;
+
+ if ((pw = getpwnam(user)) == NULL)
+ fatalx("authenticate: getpwnam");
+
+ if (expand(buf, mpath, sizeof(buf), pw) >= sizeof(buf))
+ fatalx("maildrop: path truncation");
+
+ flags = O_CREAT;
+ if (mtype == M_MBOX)
+ flags |= O_RDWR;
+ else
+ flags |= O_RDONLY;
+
+ old_mask = umask(S_IXUSR|S_IXGRP|S_IWOTH|S_IROTH|S_IXOTH);
+ if ((fd = open(buf, flags)) == -1)
+ logit(LOG_CRIT, "%zu: failed to open %s", session_id , buf);
+
+ if (fd != -1) {
+ m.fd = fd;
+ res = mb->init(&m, &stats.nmsgs, &stats.sz);
+ }
+
+ umask(old_mask);
+ if (res == 0) {
+ imsgev_xcompose(iev, IMSG_MAILDROP_INIT, session_id,
+ 0, -1, &stats, sizeof(struct stats), "maildrop_init");
+ } else {
+ logit(LOG_CRIT, "%zu: maildrop init failed %s",
+ session_id, buf);
+ imsgev_xcompose(iev, IMSG_MAILDROP_INIT, session_id,
+ 0, -1, NULL, 0, "maildrop_init");
+ }
+}
+
+static void
update(struct imsgev *iev, struct imsg *imsg, struct m_backend *mb)
{
int res;
diff --git a/pop3d.c b/pop3d.c
index cbd3ea3..dd71cb9 100644
--- a/pop3d.c
+++ b/pop3d.c
@@ -47,8 +47,8 @@ static enum m_type m_type(const char *);
static void usage(void);
static struct imsgev iev_pop3e;
-static const char *mpath;
-static int mtype = M_MBOX;
+const char *mpath;
+int mtype = M_MBOX;
int
main(int argc, char *argv[])
@@ -172,7 +172,7 @@ authenticate(struct imsgev *iev, struct imsg *imsg)
if ((pw = getpwnam(req->user)) == NULL)
fatalx("authenticate: getpwnam");
- if (maildrop_init(imsg->hdr.peerid, pair, pw, mtype, mpath) == -1) {
+ if (maildrop_setup(imsg->hdr.peerid, pair, pw) == -1) {
logit(LOG_INFO, "%u: unable to fork maildrop process",
imsg->hdr.peerid);
pair[0] = -1;
diff --git a/pop3d.h b/pop3d.h
index fa7de0b..72f50e5 100644
--- a/pop3d.h
+++ b/pop3d.h
@@ -66,7 +66,7 @@ struct mdrop {
} e;
size_t nmsgs;
size_t sz;
- struct msg **msgs_index; /* random access to msgs */
+ struct msg **msgs_index; /* random access msgs */
int fd;
};
@@ -156,7 +156,7 @@ int session_cmp(struct session *, struct session *);
SPLAY_PROTOTYPE(session_tree, session, entry, session_cmp);
/* maildrop.c */
-pid_t maildrop_init(uint32_t, int [2], struct passwd *, int, const char *);
+pid_t maildrop_setup(uint32_t, int [2], struct passwd *);
/* util.c */
void set_nonblocking(int);
diff --git a/session.c b/session.c
index 8f7622c..0db47de 100644
--- a/session.c
+++ b/session.c
@@ -147,8 +147,14 @@ session_close(struct session *s, int flush)
io_clear(&entry->io);
iobuf_clear(&entry->iobuf);
- imsgev_clear(entry->iev_maildrop);
- entry->iev_maildrop->terminate = 1;
+ /*
+ * If the session hadn't made it to TRANSACTION
+ * iev_maildrop is not inited.
+ */
+ if (entry->iev_maildrop) {
+ imsgev_clear(entry->iev_maildrop);
+ entry->iev_maildrop->terminate = 1;
+ }
logit(LOG_INFO, "%u: session closed", entry->id);
free(entry);
}
@@ -440,6 +446,8 @@ session_imsgev_init(struct session *s, int fd)
s->iev_maildrop = xcalloc(1, sizeof(struct imsgev),
"session_imsgev_init");
imsgev_init(s->iev_maildrop, fd, NULL, maildrop_imsgev, needfd);
+ imsgev_xcompose(s->iev_maildrop, IMSG_MAILDROP_INIT, s->id, 0,
+ -1, s->user, sizeof(s->user), "session_imsgev_init");
}
static void