Commit Diff


commit - 09816288b5a67c9634654778c4daa4eaba330116
commit + 912d0ff20d56b6da86f0228bc197c0f57317a11f
blob - 987c4fa26dde288291979cc7eab9f7fc4ab53f63
blob + 76638062dd505151f97d71686613490890b4b100
--- opensmtpd.c
+++ opensmtpd.c
@@ -93,8 +93,10 @@ static void osmtpd_tx_rollback(struct osmtpd_callback 
 static void osmtpd_addrtoss(char *, struct sockaddr_storage *, int, char *);
 static enum osmtpd_status osmtpd_strtostatus(const char *, char *);
 static int osmtpd_session_cmp(struct osmtpd_session *, struct osmtpd_session *);
-static void *(*oncreatecb)(struct osmtpd_ctx *) = NULL;
-static void (*ondeletecb)(struct osmtpd_ctx *, void *) = NULL;
+static void *(*oncreatecb_session)(struct osmtpd_ctx *) = NULL;
+static void (*ondeletecb_session)(struct osmtpd_ctx *, void *) = NULL;
+static void *(*oncreatecb_message)(struct osmtpd_ctx *) = NULL;
+static void (*ondeletecb_message)(struct osmtpd_ctx *, void *) = NULL;
 
 static struct osmtpd_callback osmtpd_callbacks[] = {
 	{
@@ -797,14 +799,22 @@ osmtpd_register_report_timeout(int incoming, void (*cb
 }
 
 void
-osmtpd_localdata(void *(*oncreate)(struct osmtpd_ctx *),
+osmtpd_local_session(void *(*oncreate)(struct osmtpd_ctx *),
     void (*ondelete)(struct osmtpd_ctx *, void *))
 {
-	oncreatecb = oncreate;
-	ondeletecb = ondelete;
+	oncreatecb_session = oncreate;
+	ondeletecb_session = ondelete;
 }
 
 void
+osmtpd_local_message(void *(*oncreate)(struct osmtpd_ctx *),
+    void (*ondelete)(struct osmtpd_ctx *, void *))
+{
+	oncreatecb_message = oncreate;
+	ondeletecb_message = ondelete;
+}
+
+void
 osmtpd_need(int lneeds)
 {
 	needs |= lneeds;
@@ -883,8 +893,21 @@ osmtpd_run(void)
 	io_set_write(io_stdout);
 
 	for (i = 0; i < NITEMS(osmtpd_callbacks); i++) {
-		if (osmtpd_callbacks[i].doregister)
+		if (osmtpd_callbacks[i].doregister) {
 			osmtpd_register_need(osmtpd_callbacks[i].incoming);
+			if (oncreatecb_message != NULL) {
+				osmtpd_register(OSMTPD_TYPE_REPORT,
+				    OSMTPD_PHASE_TX_BEGIN,
+				    osmtpd_callbacks[i].incoming, 0, NULL);
+				osmtpd_register(OSMTPD_TYPE_REPORT,
+				    OSMTPD_PHASE_TX_ROLLBACK,
+				    osmtpd_callbacks[i].incoming, 0, NULL);
+				osmtpd_register(OSMTPD_TYPE_REPORT,
+				    OSMTPD_PHASE_TX_COMMIT,
+				    osmtpd_callbacks[i].incoming, 0, NULL);
+			}
+			
+		}
 	}
 	for (i = 0; i < NITEMS(osmtpd_callbacks); i++) {
 		if (osmtpd_callbacks[i].doregister) {
@@ -1028,9 +1051,11 @@ osmtpd_newline(struct io *io, int ev, void *arg)
 			ctx->ctx.dst.ss_family = AF_UNSPEC;
 			RB_INSERT(osmtpd_sessions, &osmtpd_sessions, ctx);
 			ctx->ctx.evpid = 0;
-			ctx->ctx.local = NULL;
-			if (oncreatecb != NULL)
-				ctx->ctx.local = oncreatecb(&ctx->ctx);
+			ctx->ctx.local_session = NULL;
+			ctx->ctx.local_message = NULL;
+			if (oncreatecb_session != NULL)
+				ctx->ctx.local_session =
+				    oncreatecb_session(&ctx->ctx);
 		}
 		ctx->ctx.type = type;
 		ctx->ctx.phase = phase;
@@ -1168,8 +1193,8 @@ osmtpd_link_disconnect(struct osmtpd_callback *cb, str
 	session = RB_FIND(osmtpd_sessions, &osmtpd_sessions, &search);
 	if (session != NULL) {
 		RB_REMOVE(osmtpd_sessions, &osmtpd_sessions, session);
-		if (ondeletecb != NULL)
-			ondeletecb(ctx, session->ctx.local);
+		if (ondeletecb_session != NULL)
+			ondeletecb_session(ctx, session->ctx.local_session);
 		free(session->ctx.rdns);
 		free(session->ctx.fcrdns);
 		free(session->ctx.identity);
@@ -1232,6 +1257,9 @@ osmtpd_tx_begin(struct osmtpd_callback *cb, struct osm
 	if (!cb->storereport)
 		ctx->msgid = 0;
 
+	if (oncreatecb_message != NULL)
+		ctx->local_message = oncreatecb_message(ctx);
+
 	if ((f = cb->cb) != NULL)
 		f(ctx, imsgid);
 }
@@ -1400,17 +1428,22 @@ osmtpd_tx_commit(struct osmtpd_callback *cb, struct os
 	if (errstr != NULL)
 		errx(1, "Invalid line received: invalid msg size: %s", linedup);
 
-	free(ctx->mailfrom);
-	ctx->mailfrom = NULL;
-
-	for (i = 0; ctx->rcptto[i] != NULL; i++)
-		free(ctx->rcptto[i]);
-	ctx->rcptto[0] = NULL;
-	ctx->evpid = 0;
-	ctx->msgid = 0;
-
 	if ((f = cb->cb) != NULL)
 		f(ctx, msgid, msgsz);
+
+	if (ondeletecb_message != NULL) {
+		ondeletecb_message(ctx, ctx->local_message);
+		ctx->local_message = NULL;
+	}
+
+	free(ctx->mailfrom);
+	ctx->mailfrom = NULL;
+
+	for (i = 0; ctx->rcptto[i] != NULL; i++)
+		free(ctx->rcptto[i]);
+	ctx->rcptto[0] = NULL;
+	ctx->evpid = 0;
+	ctx->msgid = 0;
 }
 
 static void
@@ -1436,6 +1469,11 @@ osmtpd_tx_rollback(struct osmtpd_callback *cb, struct 
 	if ((f = cb->cb) != NULL)
 		f(ctx, msgid);
 
+	if (ondeletecb_message != NULL) {
+		ondeletecb_message(ctx, ctx->local_message);
+		ctx->local_message = NULL;
+	}
+
 	free(ctx->mailfrom);
 	ctx->mailfrom = NULL;
 
@@ -1523,7 +1561,8 @@ osmtpd_register(enum osmtpd_type type, enum osmtpd_pha
 		    incoming == osmtpd_callbacks[i].incoming) {
 			if (osmtpd_callbacks[i].cb != NULL && cb != NULL)
 				errx(1, "Event already registered");
-			osmtpd_callbacks[i].cb = cb;
+			if (cb != NULL)
+				osmtpd_callbacks[i].cb = cb;
 			osmtpd_callbacks[i].doregister = 1;
 			if (storereport)
 				osmtpd_callbacks[i].storereport = 1;
blob - c8a65bc02bddd5c5a622a14548d60f190ab90df0
blob + d0d91a3b8391364e181b701c212b03bd1421f936
--- opensmtpd.h
+++ opensmtpd.h
@@ -89,7 +89,8 @@ struct osmtpd_ctx {
 	char			*mailfrom;
 	char			**rcptto;
 	uint64_t		 evpid;
-	void			*local;
+	void			*local_session;
+	void			*local_message;
 };
 
 void osmtpd_register_filter_connect(void (*)(struct osmtpd_ctx *, const char *,
@@ -138,8 +139,10 @@ void osmtpd_register_report_server(int, void (*)(struc
 void osmtpd_register_report_response(int, void (*)(struct osmtpd_ctx *,
     const char *));
 void osmtpd_register_report_timeout(int, void (*)(struct osmtpd_ctx *));
-void osmtpd_localdata(void *(*)(struct osmtpd_ctx *),
+void osmtpd_local_session(void *(*)(struct osmtpd_ctx *),
     void (*)(struct osmtpd_ctx *, void *));
+void osmtpd_local_message(void *(*)(struct osmtpd_ctx *),
+    void (*)(struct osmtpd_ctx *, void *));
 void osmtpd_need(int);
 
 void osmtpd_filter_proceed(struct osmtpd_ctx *);