diff options
author | rsc <devnull@localhost> | 2005-10-29 16:26:44 +0000 |
---|---|---|
committer | rsc <devnull@localhost> | 2005-10-29 16:26:44 +0000 |
commit | 5cdb17983ae6e6367ad7a940cb219eab247a9304 (patch) | |
tree | 8ca1ef49af2a96e7daebe624d91fdf679814a057 /src/cmd/upas/ml/common.c | |
parent | cd3745196389579fb78b9b01ef1daefb5a57aa71 (diff) | |
download | plan9port-5cdb17983ae6e6367ad7a940cb219eab247a9304.tar.gz plan9port-5cdb17983ae6e6367ad7a940cb219eab247a9304.tar.bz2 plan9port-5cdb17983ae6e6367ad7a940cb219eab247a9304.zip |
Thanks to John Cummings.
Diffstat (limited to 'src/cmd/upas/ml/common.c')
-rw-r--r-- | src/cmd/upas/ml/common.c | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/src/cmd/upas/ml/common.c b/src/cmd/upas/ml/common.c new file mode 100644 index 00000000..307a4925 --- /dev/null +++ b/src/cmd/upas/ml/common.c @@ -0,0 +1,197 @@ +#include "common.h" +#include "dat.h" + +String* +getaddr(Node *p) +{ + for(; p; p = p->next){ + if(p->s && p->addr) + return p->s; + } + return nil; +} + +/* send messae adding our own reply-to and precedence */ +void +getaddrs(void) +{ + Field *f; + + for(f = firstfield; f; f = f->next){ + if(f->node->c == FROM && from == nil) + from = getaddr(f->node); + if(f->node->c == SENDER && sender == nil) + sender = getaddr(f->node); + } +} + +/* write address file, should be append only */ +void +writeaddr(char *file, char *addr, int rem, char *listname) +{ + int fd; + Dir nd; + + fd = open(file, OWRITE); + if(fd < 0){ + fd = create(file, OWRITE, DMAPPEND|0666); + if(fd < 0) + sysfatal("creating address list %s: %r", file); + nulldir(&nd); + nd.mode = DMAPPEND|0666; + dirwstat(file, &nd); + } else + seek(fd, 0, 2); + if(rem) + fprint(fd, "!%s\n", addr); + else + fprint(fd, "%s\n", addr); + close(fd); + + if(*addr != '#') + sendnotification(addr, listname, rem); +} + +void +remaddr(char *addr) +{ + Addr **l; + Addr *a; + + for(l = &al; *l; l = &(*l)->next){ + a = *l; + if(strcmp(addr, a->addr) == 0){ + (*l) = a->next; + free(a); + na--; + break; + } + } +} + +int +addaddr(char *addr) +{ + Addr **l; + Addr *a; + + for(l = &al; *l; l = &(*l)->next){ + if(strcmp(addr, (*l)->addr) == 0) + return 0; + } + na++; + *l = a = malloc(sizeof(*a)+strlen(addr)+1); + if(a == nil) + sysfatal("allocating: %r"); + a->addr = (char*)&a[1]; + strcpy(a->addr, addr); + a->next = nil; + *l = a; + return 1; +} + +/* read address file */ +void +readaddrs(char *file) +{ + Biobuf *b; + char *p; + + b = Bopen(file, OREAD); + if(b == nil) + return; + + while((p = Brdline(b, '\n')) != nil){ + p[Blinelen(b)-1] = 0; + if(*p == '#') + continue; + if(*p == '!') + remaddr(p+1); + else + addaddr(p); + } + Bterm(b); +} + +/* start a mailer sending to all the receivers */ +int +startmailer(char *name) +{ + int pfd[2]; + char **av; + int ac; + Addr *a; + + putenv("upasname", "/dev/null"); + if(pipe(pfd) < 0) + sysfatal("creating pipe: %r"); + switch(fork()){ + case -1: + sysfatal("starting mailer: %r"); + case 0: + close(pfd[1]); + break; + default: + close(pfd[0]); + return pfd[1]; + } + + dup(pfd[0], 0); + close(pfd[0]); + + av = malloc(sizeof(char*)*(na+2)); + if(av == nil) + sysfatal("starting mailer: %r"); + ac = 0; + av[ac++] = name; + for(a = al; a != nil; a = a->next) + av[ac++] = a->addr; + av[ac] = 0; + exec("/bin/upas/send", av); + sysfatal("execing mailer: %r"); + + /* not reached */ + return -1; +} + +void +sendnotification(char *addr, char *listname, int rem) +{ + int pfd[2]; + Waitmsg *w; + + putenv("upasname", "/dev/null"); + if(pipe(pfd) < 0) + sysfatal("creating pipe: %r"); + switch(fork()){ + case -1: + sysfatal("starting mailer: %r"); + case 0: + close(pfd[1]); + dup(pfd[0], 0); + close(pfd[0]); + execl("/bin/upas/send", "mlnotify", addr, nil); + sysfatal("execing mailer: %r"); + break; + default: + close(pfd[0]); + fprint(pfd[1], "From: %s-owner\n\n", listname); + if(rem) + fprint(pfd[1], "You have removed from the %s mailing list\n", listname); + else{ + fprint(pfd[1], "You have been added to the %s mailing list\n", listname); + fprint(pfd[1], "To be removed, send an email to %s-owner containing\n", + listname); + fprint(pfd[1], "the word 'remove' in the subject or body.\n"); + } + close(pfd[1]); + + /* wait for mailer to end */ + while(w = wait()){ + if(w->msg != nil && w->msg[0]) + sysfatal("%s", w->msg); + free(w); + } + break; + } +} |