changeset 450:b57be6e2a98d

Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
author mmj
date Fri, 04 Feb 2005 01:53:15 +1100
parents e9fadd2c7a37
children d146092aefd5
files ChangeLog src/Makefile.am src/listcontrol.c src/mlmmj-bounce.c
diffstat 4 files changed, 79 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Fri Feb 04 01:34:31 2005 +1100
+++ b/ChangeLog	Fri Feb 04 01:53:15 2005 +1100
@@ -1,3 +1,5 @@
+ o In case of listname+bounces-INDEX use the DSN (RFC1891) to extract
+   the bouncing address
  o Fix usage of a zero sized control/verp string
  o Make the Date: header RFC2822 conformant
 1.2.2
--- a/src/Makefile.am	Fri Feb 04 01:34:31 2005 +1100
+++ b/src/Makefile.am	Fri Feb 04 01:53:15 2005 +1100
@@ -44,7 +44,7 @@
 mlmmj_bounce_SOURCES = mlmmj-bounce.c print-version.c log_error.c \
 		       subscriberfuncs.c strgen.c random-int.c writen.c \
 		       prepstdreply.c mygetline.c chomp.c getlistaddr.c \
-		       memory.c
+		       memory.c find_email_adr.c gethdrline.c
 
 mlmmj_maintd_SOURCES = mlmmj-maintd.c print-version.c log_error.c mygetline.c \
 		       strgen.c random-int.c chomp.c writen.c memory.c \
--- a/src/listcontrol.c	Fri Feb 04 01:34:31 2005 +1100
+++ b/src/listcontrol.c	Fri Feb 04 01:53:15 2005 +1100
@@ -453,9 +453,15 @@
 	case CTRL_BOUNCES:
 		bouncenr = param;
 		c = strchr(param, '-');
-		if (!c) { /* malformed bounce, ignore and clean up */
-	 		unlink(mailname);
-			exit(EXIT_SUCCESS);
+		if (!c) { /* Exec with dsn parsing, since the addr is missing */
+			execlp(mlmmjbounce, mlmmjbounce,
+					"-L", listdir,
+					"-m", mailname,
+					"-n", bouncenr,
+					"-d", (char *)NULL);
+			log_error(LOG_ARGS, "execlp() of '%s' failed",
+					mlmmjbounce);
+			exit(EXIT_FAILURE);
 		}
 		*c++ = '\0';
 		execlp(mlmmjbounce, mlmmjbounce,
--- a/src/mlmmj-bounce.c	Fri Feb 04 01:34:31 2005 +1100
+++ b/src/mlmmj-bounce.c	Fri Feb 04 01:53:15 2005 +1100
@@ -32,6 +32,8 @@
 #include <time.h>
 #include <dirent.h>
 #include <sys/mman.h>
+#include <string.h>
+#include <ctype.h>
 
 #include "getlistaddr.h"
 #include "mlmmj.h"
@@ -43,6 +45,8 @@
 #include "chomp.h"
 #include "prepstdreply.h"
 #include "memory.h"
+#include "find_email_adr.h"
+#include "gethdrline.h"
 
 char *fetchindexes(const char *bouncefile)
 {
@@ -164,6 +168,49 @@
 	exit(EXIT_FAILURE);
 }
 
+char *dsnparseaddr(const char *mailname)
+{
+	int fd, indsn = 0, i;
+	char *line, *linedup, *search, *addr = NULL;
+	struct email_container emails;
+
+	fd = open(mailname, O_RDONLY);
+	if(fd < 0) {
+		log_error(LOG_ARGS, "Could not open bounceindexfile %s",
+				mailname);
+		return NULL;
+	}
+
+	while((line = gethdrline(fd))) {
+		linedup = mystrdup(line);
+		for(i = 0; line[i]; i++)
+			linedup[i] = tolower(line[i]);
+		search = strstr(linedup, "message/delivery-status");
+		myfree(linedup);
+		if(search)
+			indsn = 1;
+		if(indsn) {
+			i = strncasecmp(line, "Final-Recipient:", 16);
+			if(i == 0) {
+				find_email_adr(line, &emails);
+				if(emails.emailcount > 0) {
+					addr = mystrdup(emails.emaillist[0]);
+					for(i = 0; i < emails.emailcount; i++)
+						myfree(emails.emaillist[i]);
+					myfree(emails.emaillist);	
+				} else {
+					addr = NULL;
+				}
+				myfree(line);
+				return addr;
+			}
+		}
+		myfree(line);
+	}
+	
+	return NULL;
+}
+
 static void print_help(const char *prg)
 {
 	printf("Usage: %s -L /path/to/list -a john=doe.org [-n num | -p]\n"
@@ -179,7 +226,7 @@
 
 int main(int argc, char **argv)
 {
-	int opt, fd;
+	int opt, fd, dsnbounce = 0;
 	char *listdir = NULL, *address = NULL, *number = NULL;
 	char *bindir, *mlmmjsend, *savename;
 	char *mailname = NULL, *bfilename, *a, *buf;
@@ -197,7 +244,7 @@
 	mlmmjsend = concatstr(2, bindir, "/mlmmj-send");
 	myfree(bindir);
 
-	while ((opt = getopt(argc, argv, "hVL:a:n:m:p")) != -1) {
+	while ((opt = getopt(argc, argv, "hdVL:a:n:m:p")) != -1) {
 		switch(opt) {
 		case 'L':
 			listdir = optarg;
@@ -205,6 +252,9 @@
 		case 'a':
 			address = optarg;
 			break;
+		case 'd':
+			dsnbounce = 1;
+			break;
 		case 'm':
 			mailname = optarg;
 			break;
@@ -223,8 +273,10 @@
 		}
 	}
 
-	if(listdir == NULL || address == NULL || (number == NULL && probe == 0)) {
-		fprintf(stderr, "You have to specify -L, -a and -n or -p\n");
+	if(listdir == NULL || (address == NULL && dsnbounce == 0)
+				|| (number == NULL && probe == 0)) {
+		fprintf(stderr,
+			"You have to specify -L, -a or -d and -n or -p\n");
 		fprintf(stderr, "%s -h for help\n", argv[0]);
 		exit(EXIT_FAILURE);
 	}
@@ -248,6 +300,16 @@
 		}
 	}
 	
+	if(dsnbounce) {
+		address = dsnparseaddr(mailname);
+		if(address == NULL) {
+			/* not parseable, so unlink and clean up */
+			if(mailname)
+				unlink(mailname);
+			exit(EXIT_SUCCESS);
+		}
+	}
+			
 	if(number != NULL && probe != 0) {
 		fprintf(stderr, "You can only specify one of -n or -p\n");
 		fprintf(stderr, "%s -h for help\n", argv[0]);