changeset 456:160dab909572

Add .filename.lock file to lock against. Only allow addresses with a @ in them. 1.2.3
author mmj
date Tue, 08 Feb 2005 06:37:40 +1100
parents 9cafbe08e06e
children da6291416e50
files ChangeLog README VERSION src/mlmmj-sub.c src/mlmmj-unsub.c
diffstat 5 files changed, 86 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Fri Feb 04 03:20:32 2005 +1100
+++ b/ChangeLog	Tue Feb 08 06:37:40 2005 +1100
@@ -1,4 +1,7 @@
- o In case of listname+bounces-INDEX use the DSN (RFC1891) to extract
+1.2.3
+ o Only allow subscription of addresses with '@' in them
+ o Add extra lock layer (.filename.lock) when accessing subscribers files
+ o In case of listname+bounces-INDEX use the DSN (RFC1891) report to extract
    the bouncing address
  o Fix usage of a zero sized control/verp string
  o Make the Date: header RFC2822 conformant
--- a/README	Fri Feb 04 03:20:32 2005 +1100
+++ b/README	Tue Feb 08 06:37:40 2005 +1100
@@ -1,4 +1,4 @@
-README mlmmj-1.2.2					February 1st 2005
+README mlmmj-1.2.3					February 7th 2005
 
 This is an attempt at implementing a mailing list manager with the same
 functionality as the brilliant ezmlm, but with a decent license and mail server
@@ -19,6 +19,7 @@
  · Digests
  · No mail delivery subscription
  · VERP support
+ · Delivery Status Notification (RFC1891) support
 
 To use mlmmj, do the following:
 
--- a/VERSION	Fri Feb 04 03:20:32 2005 +1100
+++ b/VERSION	Tue Feb 08 06:37:40 2005 +1100
@@ -1,1 +1,1 @@
-1.2.2
+1.2.3
--- a/src/mlmmj-sub.c	Fri Feb 04 03:20:32 2005 +1100
+++ b/src/mlmmj-sub.c	Tue Feb 08 06:37:40 2005 +1100
@@ -244,9 +244,10 @@
 {
 	char *listaddr, *listdir = NULL, *address = NULL, *subfilename = NULL;
 	char *mlmmjsend, *bindir, chstr[2], *subdir, *subddirname = NULL;
+	char *sublockname;
 	int subconfirm = 0, confirmsub = 0, opt, subfilefd, lock, notifysub;
 	int changeuid = 1, status, digest = 0, nomail = 0;
-	int groupwritable = 0;
+	int groupwritable = 0, sublock, sublockfd;
 	size_t len;
 	off_t suboff;
 	struct stat st;
@@ -300,6 +301,12 @@
 		exit(EXIT_FAILURE);
 	}
 
+	if(strchr(address, '@') == NULL) {
+		log_error(LOG_ARGS, "No '@' sign in '%s', not subscribing",
+				address);
+		exit(EXIT_SUCCESS);
+	}
+
 	if(digest && nomail) {
 		fprintf(stderr, "Specify either -d or -n, not both\n");
 		fprintf(stderr, "%s -h for help\n", argv[0]);
@@ -365,6 +372,24 @@
 	subfilename = concatstr(3, listdir, subdir, chstr);
 	myfree(subdir);
 
+	sublockname = concatstr(5, listdir, subdir, ".", chstr, ".lock");
+	sublockfd = open(sublockname, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
+	if(sublockfd < 0) {
+		log_error(LOG_ARGS, "Error opening lock file %s",
+				sublockname);
+		myfree(sublockname);
+		exit(EXIT_FAILURE);
+	}
+
+	sublock = myexcllock(sublockfd);
+	if(sublock < 0) {
+		log_error(LOG_ARGS, "Error locking '%s' file",
+				sublockname);
+		myfree(sublockname);
+		close(sublockfd);
+		exit(EXIT_FAILURE);
+	}
+
 	subfilefd = open(subfilename, O_RDWR|O_CREAT,
 				S_IRUSR|S_IWUSR|groupwritable);
 	if(subfilefd == -1) {
--- a/src/mlmmj-unsub.c	Fri Feb 04 03:20:32 2005 +1100
+++ b/src/mlmmj-unsub.c	Tue Feb 08 06:37:40 2005 +1100
@@ -231,29 +231,34 @@
 	struct stat st;
 	char *inmap;
 	size_t len = strlen(address) + 1; /* + 1 for the '\n' */
-	ssize_t writeres, written = 0;
+	ssize_t writeres = 0, written = 0;
 	
 	if(suboff == -1)
-		return 1; /* Did not find subscriber */
+		return -1; /* Did not find subscriber */
 
 	if(fstat(subreadfd, &st) < 0) {
-		log_error(LOG_ARGS, "Could not stat fd");
-		return 1;
+		log_error(LOG_ARGS, "Could not stat subreadfd");
+		return -1;
 	}
 
 	if((inmap = mmap(0, st.st_size, PROT_READ, MAP_SHARED,
 		       subreadfd, 0)) == MAP_FAILED) {
-		log_error(LOG_ARGS, "Could not mmap fd");
-		return 1;
+		log_error(LOG_ARGS, "Could not mmap subreadfd");
+		return -1;
 	}
 
-	if((writeres = writen(subwritefd, inmap, suboff)) < 0)
+	if(suboff > 0) {
+		writeres = writen(subwritefd, inmap, suboff);
+		if(writeres < 0)
 		return -1;
+	}
 	written += writeres;
 	
-	if((writeres = writen(subwritefd, inmap + suboff + len,
-					st.st_size - len - suboff) < 0))
+	writeres = writen(subwritefd, inmap + len + suboff,
+				st.st_size - len - suboff);
+	if(writeres < 0)
 		return -1;
+
 	written += writeres;
 
 	munmap(inmap, st.st_size);
@@ -283,10 +288,10 @@
 {
 	int subread, subwrite, rlock, wlock, opt, unsubres, status, nomail = 0;
 	int confirmunsub = 0, unsubconfirm = 0, notifysub = 0, digest = 0;
-	int changeuid = 1, groupwritable = 0;
+	int changeuid = 1, groupwritable = 0, sublock, sublockfd;
 	char *listaddr, *listdir = NULL, *address = NULL, *subreadname = NULL;
 	char *subwritename, *mlmmjsend, *bindir, *subdir;
-	char *subddirname;
+	char *subddirname, *sublockname;
 	off_t suboff;
 	DIR *subddir;
 	struct dirent *dp;
@@ -439,25 +444,50 @@
 			continue;
 		}
 
+		/* create a .name.lock file and aquire the lock */
+		sublockname = concatstr(5, listdir, subdir, ".", dp->d_name,
+					".lock");
+		sublockfd = open(sublockname, O_RDWR | O_CREAT,
+						S_IRUSR | S_IWUSR);
+		if(sublockfd < 0) {
+			log_error(LOG_ARGS, "Error opening lock file %s",
+					sublockname);
+			myfree(sublockname);
+			continue;
+		}
+
+		sublock = myexcllock(sublockfd);
+		if(sublock < 0) {
+			log_error(LOG_ARGS, "Error locking '%s' file",
+					sublockname);
+			myfree(sublockname);
+			close(sublockfd);
+			continue;
+		}
+		
 		rlock = myexcllock(subread);
 		if(rlock < 0) {
 			log_error(LOG_ARGS, "Error locking '%s' file",
 					subreadname);
 			close(subread);
+			close(sublockfd);
 			myfree(subreadname);
+			myfree(sublockname);
 			continue;
 		}
 
 		subwritename = concatstr(2, subreadname, ".new");
 
-		subwrite = open(subwritename, O_RDWR | O_CREAT | O_EXCL,
+		subwrite = open(subwritename, O_RDWR | O_CREAT | O_TRUNC,
 				S_IRUSR | S_IWUSR | groupwritable);
 		if(subwrite == -1){
 			log_error(LOG_ARGS, "Could not open '%s'",
 					subwritename);
 			close(subread);
+			close(sublockfd);
 			myfree(subreadname);
 			myfree(subwritename);
+			myfree(sublockname);
 			continue;
 		}
 
@@ -467,8 +497,10 @@
 					subwritename);
 			close(subread);
 			close(subwrite);
+			close(sublockfd);
 			myfree(subreadname);
 			myfree(subwritename);
+			myfree(sublockname);
 			continue;
 		}
 
@@ -476,14 +508,14 @@
 		if(unsubres < 0) {
 			close(subread);
 			close(subwrite);
+			close(sublockfd);
 			unlink(subwritename);
 			myfree(subreadname);
 			myfree(subwritename);
+			myfree(sublockname);
 			continue;
 		}
 
-		unlink(subreadname);
-
 		if(unsubres > 0) {
 			if(rename(subwritename, subreadname) < 0) {
 				log_error(LOG_ARGS,
@@ -495,13 +527,18 @@
 				myfree(subwritename);
 				continue;
 			}
-		} else /* unsubres == 0, no subscribers left */
+		} else { /* unsubres == 0, no subscribers left */
 			unlink(subwritename);
+			unlink(subreadname);
+		}
 
 		close(subread);
 		close(subwrite);
+		close(sublockfd);
 		myfree(subreadname);
 		myfree(subwritename);
+		unlink(sublockname);
+		myfree(sublockname);
 
 		if(confirmunsub) {
 			childpid = fork();