Mercurial > hg > mlmmj
view src/mlmmj-unsub.c @ 45:01815cd7df4c
Debugging printf removed
author | mmj |
---|---|
date | Sun, 25 Apr 2004 20:20:35 +1000 |
parents | 74cf6cb8362f |
children | 4e9e7f2d2e09 |
line wrap: on
line source
/* Copyright (C) 2002, 2003 Mads Martin Joergensen <mmj at mmj.dk> * * $Id$ * * This file is redistributable under version 2 of the GNU General * Public License as described at http://www.gnu.org/licenses/gpl.txt */ #include <stdlib.h> #include <stdio.h> #include <string.h> #include <errno.h> #include <syslog.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/mman.h> #include <unistd.h> #include <fcntl.h> #include <libgen.h> #include "mlmmj.h" #include "mlmmj-unsub.h" #include "mylocking.h" #include "wrappers.h" #include "mygetline.h" #include "getlistaddr.h" #include "subscriberfuncs.h" #include "strgen.h" #include "log_error.h" void confirm_unsub(const char *listdir, const char *listaddr, const char *subaddr, const char *mlmmjsend) { FILE *subtextfile, *queuefile; char buf[READ_BUFSIZE]; char *bufres, *subtextfilename, *randomstr, *queuefilename; char *fromstr, *tostr, *subjectstr, *fromaddr, *helpaddr; char *listname, *listfqdn; size_t len; subtextfilename = concatstr(2, listdir, "/text/unsub-ok"); if((subtextfile = fopen(subtextfilename, "r")) == NULL) { log_error(LOG_ARGS, "Could not open '%s'", subtextfilename); free(subtextfilename); exit(EXIT_FAILURE); } free(subtextfilename); listname = genlistname(listaddr); listfqdn = genlistfqdn(listaddr); randomstr = random_str(); queuefilename = concatstr(3, listdir, "/queue/", randomstr); printf("%s\n", queuefilename); if((queuefile = fopen(queuefilename, "w")) == NULL) { log_error(LOG_ARGS, "Could not open '%s'", queuefilename); free(queuefilename); free(randomstr); exit(EXIT_FAILURE); } free(randomstr); len = strlen(listname) + strlen(listfqdn) + strlen("+help@") + 1; helpaddr = malloc(len); snprintf(helpaddr, len, "%s+help@%s", listname, listfqdn); len += strlen("-bounces"); fromaddr = malloc(len); snprintf(fromaddr, len, "%s-bounces+help@%s", listname, listfqdn); fromstr = headerstr("From: ", helpaddr); fputs(fromstr, queuefile); free(helpaddr); tostr = headerstr("To: ", subaddr); fputs(tostr, queuefile); subjectstr = headerstr("Subject: Goodbye from ", listaddr); fputs(subjectstr, queuefile); fputc('\n', queuefile); while((bufres = fgets(buf, sizeof(buf), subtextfile))) if(strncmp(buf, "*LSTADDR*", 9) == 0) fputs(listaddr, queuefile); else fputs(buf, queuefile); free(tostr); free(subjectstr); free(listname); free(listfqdn); fclose(subtextfile); fclose(queuefile); execlp(mlmmjsend, mlmmjsend, "-L", "1", "-T", subaddr, "-F", fromaddr, "-m", queuefilename, 0); log_error(LOG_ARGS, "execlp() of '%s' failed", mlmmjsend); exit(EXIT_FAILURE); } void generate_unsubconfirm(const char *listdir, const char *listaddr, const char *subaddr, const char *mlmmjsend) { size_t len; char buf[READ_BUFSIZE]; char *confirmaddr, *bufres, *listname, *listfqdn, *confirmfilename; char *subtextfilename, *queuefilename, *fromaddr, *randomstr; char *tostr, *fromstr, *helpaddr, *subjectstr; FILE *subconffile, *subtextfile, *queuefile; listname = genlistname(listaddr); listfqdn = genlistfqdn(listaddr); randomstr = random_plus_addr(subaddr); confirmfilename = concatstr(3, listdir, "/unsubconf/", randomstr); if((subconffile = fopen(confirmfilename, "w")) == NULL) { log_error(LOG_ARGS, "Could not open '%s'", confirmfilename); free(confirmfilename); free(randomstr); exit(EXIT_FAILURE); } fputs(subaddr, subconffile); fclose(subconffile); free(confirmfilename); len = strlen(listname) + strlen(listfqdn) + strlen("+help@") + 1; helpaddr = malloc(len); snprintf(helpaddr, len, "%s+help@%s", listname, listfqdn); len = strlen(listname) + strlen(listfqdn) + strlen("+confunsub") + strlen(subaddr) + 20; confirmaddr = malloc(len); snprintf(confirmaddr, len, "%s+confunsub-%s@%s", listname, randomstr, listfqdn); len += strlen("-bounces"); fromaddr = malloc(len); snprintf(fromaddr, len, "%s-bounces+confunsub-%s@%s", listname, randomstr, listfqdn); subtextfilename = concatstr(2, listdir, "/text/unsub-confirm"); if((subtextfile = fopen(subtextfilename, "r")) == NULL) { log_error(LOG_ARGS, "Could not open '%s'", subtextfilename); free(randomstr); free(subtextfilename); exit(EXIT_FAILURE); } free(subtextfilename); queuefilename = concatstr(3, listdir, "/queue/", randomstr); printf("%s\n", queuefilename); if((queuefile = fopen(queuefilename, "w")) == NULL) { log_error(LOG_ARGS, "Could not open '%s'", queuefilename); free(queuefilename); free(randomstr); exit(EXIT_FAILURE); } free(randomstr); fromstr = headerstr("From: ", helpaddr); fputs(fromstr, queuefile); free(fromstr); tostr = headerstr("To: ", subaddr); fputs(tostr, queuefile); free(tostr); subjectstr = headerstr("Subject: Confirm unsubscribe from ", listaddr); fputs(subjectstr, queuefile); fputc('\n', queuefile); free(subjectstr); while((bufres = fgets(buf, READ_BUFSIZE, subtextfile))) if(strncmp(buf, "*LSTADDR*", 9) == 0) fputs(listaddr, queuefile); else if(strncmp(buf, "*SUBADDR*", 9) == 0) fputs(subaddr, queuefile); else if(strncmp(buf, "*CNFADDR*", 9) == 0) fputs(confirmaddr, queuefile); else fputs(buf, queuefile); free(listname); free(listfqdn); fclose(subtextfile); fclose(queuefile); execlp(mlmmjsend, mlmmjsend, "-L", "1", "-T", subaddr, "-F", fromaddr, "-R", confirmaddr, "-m", queuefilename, 0); log_error(LOG_ARGS, "execlp() of '%s' failed", mlmmjsend); exit(EXIT_FAILURE); } int unsubscribe(int subreadfd, int subwritefd, const char *address) { off_t suboff = find_subscriber(subreadfd, address); struct stat st; char *inmap; size_t len = strlen(address) + 1; /* + 1 for the '\n' */ if(suboff == -1) return 0; /* Did not find subscriber */ if(fstat(subreadfd, &st) < 0) { log_error(LOG_ARGS, "Could not stat fd"); return 1; } if((inmap = mmap(0, st.st_size, PROT_READ, MAP_SHARED, subreadfd, 0)) == (void *)-1) { log_error(LOG_ARGS, "Could not mmap fd"); return 1; } writen(subwritefd, inmap, suboff); writen(subwritefd, inmap + suboff + len, st.st_size - len - suboff); munmap(inmap, st.st_size); return 0; } static void print_help(const char *prg) { printf("Usage: %s -L /path/to/chat-list\n" " -a someguy@somewhere.ltd\n" " -C request mail confirmation\n" " -c send goodbye mail\n" " -h this help\n" " -V print version\n", prg); exit(EXIT_SUCCESS); } int main(int argc, char **argv) { int subread, subwrite, rlock, wlock, opt; int confirmunsub = 0, unsubconfirm = 0; char listaddr[READ_BUFSIZE]; char *listdir = NULL, *address = NULL, *subreadname = NULL; char *subwritename, *mlmmjsend, *argv0 = strdup(argv[0]); off_t suboff; mlmmjsend = concatstr(2, dirname(argv0), "/mlmmj-send"); free(argv0); log_set_name(argv[0]); while ((opt = getopt(argc, argv, "hcCVL:a:")) != -1) { switch(opt) { case 'L': listdir = optarg; break; case 'a': address = optarg; break; case 'c': confirmunsub = 1; break; case 'C': unsubconfirm = 1; break; case 'h': print_help(argv[0]); break; case 'V': print_version(argv[0]); exit(0); } } if(listdir == 0 || address == 0) { fprintf(stderr, "You have to specify -L and -a\n"); fprintf(stderr, "%s -h for help\n", argv[0]); exit(EXIT_FAILURE); } if(confirmunsub && unsubconfirm) { fprintf(stderr, "Cannot specify both -C and -c\n"); fprintf(stderr, "%s -h for help\n", argv[0]); exit(EXIT_FAILURE); } /* get the list address */ getlistaddr(listaddr, listdir); subreadname = concatstr(2, listdir, "/subscribers"); subwritename = concatstr(2, listdir, "/subscribers.new"); subread = open(subreadname, O_RDWR); if(subread == -1) { free(subreadname); free(subwritename); log_error(LOG_ARGS, "Could not open '%s'", subreadname); exit(EXIT_FAILURE); } rlock = myexcllock(subread); if(rlock < 0) { perror("rlock"); log_error(LOG_ARGS, "Error locking '%s' file", subreadname); close(subread); free(subreadname); free(subwritename); exit(EXIT_FAILURE); } suboff = find_subscriber(subread, address); if(suboff == -1) { myunlock(subread); free(subreadname); free(subwritename); close(subread); exit(EXIT_SUCCESS); } subwrite = open(subwritename, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if(subwrite == -1){ log_error(LOG_ARGS, "Could not open '%s'", subwritename); close(subread); free(subreadname); free(subwritename); exit(EXIT_FAILURE); } wlock = myexcllock(subwrite); if(wlock < 0) { perror("wlock"); log_error(LOG_ARGS, "Error locking '%s' file", subwritename); close(subread); close(subwrite); free(subreadname); free(subwritename); exit(EXIT_FAILURE); } if(unsubconfirm) generate_unsubconfirm(listdir, listaddr, address, mlmmjsend); else unsubscribe(subread, subwrite, address); if(rename(subwritename, subreadname) < 0) { log_error(LOG_ARGS, "Could not rename '%s' to '%s'", subwritename, subreadname); myunlock(subread); myunlock(subwrite); close(subread); close(subwrite); free(subreadname); free(subwritename); exit(EXIT_FAILURE); } myunlock(subread); myunlock(subwrite); free(subreadname); free(subwritename); close(subread); close(subwrite); if(confirmunsub) confirm_unsub(listdir, listaddr, address, mlmmjsend); return EXIT_SUCCESS; }