Give session a chance to init its imsgev. Let session initiate the
authorSunil Nimmagadda <sunil@nimmagadda.net>
Wed, 27 Aug 2014 14:25:26 +0500
changeset 33 252e70a700c0
parent 32 efb124b66dbd
child 35 dcf7a837ec0b
Give session a chance to init its imsgev. Let session initiate the process of MAILDROP_INIT. Maildrop now sets up itself and waits for MAILDROP_INIT from session. This would now eliminate the doubt in the earlier setup when priv process forks and the child gets cpu slice first before parent which sends MAILDROP_INIT to an uninitialized imsgev.
maildrop.c
session.c
--- a/maildrop.c	Wed Aug 27 12:47:09 2014 +0500
+++ b/maildrop.c	Wed Aug 27 14:25:26 2014 +0500
@@ -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 *);
@@ -52,14 +53,9 @@
 {
 	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;
-	extern const char	*mpath;
 
 	if ((pid = fork()) != 0)
 		return (pid);
@@ -74,42 +70,12 @@
 	if ((mb = m_backend_lookup(mtype)) == NULL)
 		fatalx("maildrop: invalid backend");
 
-	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);
 	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");
 
@@ -178,6 +144,7 @@
 	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);
@@ -215,6 +182,52 @@
 }
 
 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;
--- a/session.c	Wed Aug 27 12:47:09 2014 +0500
+++ b/session.c	Wed Aug 27 14:25:26 2014 +0500
@@ -436,7 +436,9 @@
 void
 session_imsgev_init(struct session *s, int fd)
 {
-	imsgev_init(&s->iev_maildrop, fd, s, maildrop_imsgev, needfd);
+	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