changeset 629:61e93e5c3ecf

Added support for mail size limit (Christoph Wilke)
author mortenp
date Sun, 04 Mar 2007 04:26:00 +1100
parents 3dea3499f94e
children d132d689873a
files ChangeLog TUNABLES src/mlmmj-process.c
diffstat 3 files changed, 71 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Sun Mar 04 04:24:18 2007 +1100
+++ b/ChangeLog	Sun Mar 04 04:26:00 2007 +1100
@@ -1,3 +1,4 @@
+ o Added support for mail size limit (Christoph Wilke)
  o Log the result of access rules in the operation log (Henne Vogelsang)
  o Ignore empty lines in control files
 1.2.13
--- a/TUNABLES	Sun Mar 04 04:24:18 2007 +1100
+++ b/TUNABLES	Sun Mar 04 04:26:00 2007 +1100
@@ -183,3 +183,12 @@
    If this file exists, subscription to the nomail version of the mailinglist
    will be denied. (Useful if you don't want to allow nomail and notify users
    about it).
+
+ · maxmailsize			(normal)
+
+   With this option the maximal allowed size of incoming mails can be specified.
+
+ · nomaxmailsizedenymails	(boolean)
+
+   If this is set, no reject notifications caused by violation of maxmailsize
+   will be sent.
--- a/src/mlmmj-process.c	Sun Mar 04 04:24:18 2007 +1100
+++ b/src/mlmmj-process.c	Sun Mar 04 04:26:00 2007 +1100
@@ -330,7 +330,9 @@
 	int i, j, opt, noprocess = 0, moderated = 0;
 	int hdrfd, footfd, rawmailfd, donemailfd;
 	int subonlypost = 0, addrtocc = 1, intocc = 0, modnonsubposts = 0;
+	int maxmailsize = 0;
 	int notoccdenymails = 0, noaccessdenymails = 0, nosubonlydenymails = 0;
+	int nomaxmailsizedenymails = 0;
 	char *listdir = NULL, *mailfile = NULL, *headerfilename = NULL;
 	char *footerfilename = NULL, *donemailname = NULL;
 	char *randomstr = NULL, *mqueuename;
@@ -338,7 +340,8 @@
 	char *bindir, *subjectprefix, *discardname, *listaddr, *listdelim;
 	char *listfqdn, *listname, *fromaddr;
 	char *queuefilename, *recipextra = NULL, *owner = NULL;
-	char *maildata[2] = { "posteraddr", NULL };
+	char *maxmailsizestr;
+	char *maildata[4] = { "posteraddr", NULL, "maxmailsize", NULL };
 	char *envstr, *efrom;
 	struct stat st;
 	uid_t uid;
@@ -613,6 +616,63 @@
 		return EXIT_SUCCESS;
 	}
 
+	listaddr = getlistaddr(listdir);
+	alternates = ctrlvalues(listdir, "listaddress");
+	
+	/* checking incoming mail's size */
+	maxmailsizestr = ctrlvalue(listdir, "maxmailsize");
+	if(maxmailsizestr) {
+		maxmailsize = atol(maxmailsizestr);
+		if(stat(donemailname, &st) < 0) {
+			log_error(LOG_ARGS, "stat(%s,..) failed", donemailname);
+			exit(EXIT_FAILURE);
+		}
+
+		if(st.st_size > maxmailsize) {
+
+			nomaxmailsizedenymails = statctrl(listdir, "nomaxmailsizedenymails");
+			if (nomaxmailsizedenymails) {
+				errno = 0;
+				log_error(LOG_ARGS, "Discarding %s due to"
+						" size limit (%d bytes too big)",
+						donemailname, (st.st_size - maxmailsize));
+				unlink(donemailname);
+				unlink(mailfile);
+				myfree(donemailname);
+				myfree(maxmailsizestr);
+				exit(EXIT_SUCCESS);
+			}
+
+			listdelim = getlistdelim(listdir);
+			listname = genlistname(listaddr);
+			listfqdn = genlistfqdn(listaddr);
+			fromaddr = concatstr(4, listname, listdelim,
+					"bounces-help@", listfqdn);
+			maildata[3] = maxmailsizestr;
+			queuefilename = prepstdreply(listdir,
+					"maxmailsize", "$listowner$",
+					fromemails.emaillist[0],
+					NULL, 2, maildata, NULL);
+			MY_ASSERT(queuefilename)
+			myfree(listdelim);
+			myfree(listname);
+			myfree(listfqdn);
+			unlink(donemailname);
+			unlink(mailfile);
+			myfree(donemailname);
+			myfree(maxmailsizestr);
+			execlp(mlmmjsend, mlmmjsend,
+					"-l", "1",
+					"-L", listdir,
+					"-T", fromemails.emaillist[0],
+					"-F", fromaddr,
+					"-m", queuefilename, (char *)NULL);
+		
+			log_error(LOG_ARGS, "execlp() of '%s' failed", mlmmjsend);
+			exit(EXIT_FAILURE);
+		}
+	}
+
 	/* discard malformed mail with invalid From: */
 	if(fromemails.emailcount != 1) { 
 		for(i = 0; i < fromemails.emailcount; i++)
@@ -655,9 +715,6 @@
 
 	unlink(mailfile);
 
-	listaddr = getlistaddr(listdir);
-	alternates = ctrlvalues(listdir, "listaddress");
-
 	addrtocc = !(statctrl(listdir, "tocc"));
 	if(addrtocc) {
 		for(i = 0; i < toemails.emailcount; i++) {