aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/upas/ml/common.c
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2005-10-29 16:26:44 +0000
committerrsc <devnull@localhost>2005-10-29 16:26:44 +0000
commit5cdb17983ae6e6367ad7a940cb219eab247a9304 (patch)
tree8ca1ef49af2a96e7daebe624d91fdf679814a057 /src/cmd/upas/ml/common.c
parentcd3745196389579fb78b9b01ef1daefb5a57aa71 (diff)
downloadplan9port-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.c197
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;
+ }
+}