# HG changeset patch # User mmj # Date 1107805060 -39600 # Node ID 160dab909572dbb9c3174103c9daefe9b427d078 # Parent 9cafbe08e06e94a7242b6355b2195bb650fdeeb6 Add .filename.lock file to lock against. Only allow addresses with a @ in them. 1.2.3 diff -r 9cafbe08e06e -r 160dab909572 ChangeLog --- 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 diff -r 9cafbe08e06e -r 160dab909572 README --- 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: diff -r 9cafbe08e06e -r 160dab909572 VERSION --- 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 diff -r 9cafbe08e06e -r 160dab909572 src/mlmmj-sub.c --- 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) { diff -r 9cafbe08e06e -r 160dab909572 src/mlmmj-unsub.c --- 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();