1 #include "common.h" 2 #include "dat.h" 3 4 String* 5 getaddr(Node *p) 6 { 7 for(; p; p = p->next){ 8 if(p->s && p->addr) 9 return p->s; 10 } 11 return nil; 12 } 13 14 /* send messae adding our own reply-to and precedence */ 15 void 16 getaddrs(void) 17 { 18 Field *f; 19 20 for(f = firstfield; f; f = f->next){ 21 if(f->node->c == FROM && from == nil) 22 from = getaddr(f->node); 23 if(f->node->c == SENDER && sender == nil) 24 sender = getaddr(f->node); 25 } 26 } 27 28 /* write address file, should be append only */ 29 void 30 writeaddr(char *file, char *addr, int rem, char *listname) 31 { 32 int fd; 33 Dir *d; 34 35 fd = open(file, OWRITE); 36 if(fd < 0){ 37 fd = create(file, OWRITE, DMAPPEND|0666); 38 if(fd < 0) 39 sysfatal("creating address list %s: %r", file); 40 d = dirstat(file); 41 d->mode = DMAPPEND|0666; 42 dirwstat(file, d); 43 free(d); 44 } else 45 seek(fd, 0, 2); 46 if(rem) 47 fprint(fd, "!%s\n", addr); 48 else 49 fprint(fd, "%s\n", addr); 50 close(fd); 51 52 if(*addr != '#') 53 sendnotification(addr, listname, rem); 54 } 55 56 void 57 remaddr(char *addr) 58 { 59 Addr **l; 60 Addr *a; 61 62 for(l = &al; *l; l = &(*l)->next){ 63 a = *l; 64 if(strcmp(addr, a->addr) == 0){ 65 (*l) = a->next; 66 free(a); 67 na--; 68 break; 69 } 70 } 71 } 72 73 int 74 addaddr(char *addr) 75 { 76 Addr **l; 77 Addr *a; 78 79 for(l = &al; *l; l = &(*l)->next){ 80 if(strcmp(addr, (*l)->addr) == 0) 81 return 0; 82 } 83 na++; 84 *l = a = malloc(sizeof(*a)+strlen(addr)+1); 85 if(a == nil) 86 sysfatal("allocating: %r"); 87 a->addr = (char*)&a[1]; 88 strcpy(a->addr, addr); 89 a->next = nil; 90 *l = a; 91 return 1; 92 } 93 94 /* read address file */ 95 void 96 readaddrs(char *file) 97 { 98 Biobuf *b; 99 char *p; 100 101 b = Bopen(file, OREAD); 102 if(b == nil) 103 return; 104 105 while((p = Brdline(b, '\n')) != nil){ 106 p[Blinelen(b)-1] = 0; 107 if(*p == '#') 108 continue; 109 if(*p == '!') 110 remaddr(p+1); 111 else 112 addaddr(p); 113 } 114 Bterm(b); 115 } 116 117 /* start a mailer sending to all the receivers */ 118 int 119 startmailer(char *name) 120 { 121 int pfd[2]; 122 char **av; 123 int ac; 124 Addr *a; 125 126 putenv("upasname", "/dev/null"); 127 if(pipe(pfd) < 0) 128 sysfatal("creating pipe: %r"); 129 switch(fork()){ 130 case -1: 131 sysfatal("starting mailer: %r"); 132 case 0: 133 close(pfd[1]); 134 break; 135 default: 136 close(pfd[0]); 137 return pfd[1]; 138 } 139 140 dup(pfd[0], 0); 141 close(pfd[0]); 142 143 av = malloc(sizeof(char*)*(na+2)); 144 if(av == nil) 145 sysfatal("starting mailer: %r"); 146 ac = 0; 147 av[ac++] = name; 148 for(a = al; a != nil; a = a->next) 149 av[ac++] = a->addr; 150 av[ac] = 0; 151 exec("/bin/upas/send", av); 152 sysfatal("execing mailer: %r"); 153 154 /* not reached */ 155 return -1; 156 } 157 158 void 159 sendnotification(char *addr, char *listname, int rem) 160 { 161 int pfd[2]; 162 Waitmsg *w; 163 164 putenv("upasname", "/dev/null"); 165 if(pipe(pfd) < 0) 166 sysfatal("creating pipe: %r"); 167 switch(fork()){ 168 case -1: 169 sysfatal("starting mailer: %r"); 170 case 0: 171 close(pfd[1]); 172 dup(pfd[0], 0); 173 close(pfd[0]); 174 execl("/bin/upas/send", "mlnotify", addr, 0); 175 sysfatal("execing mailer: %r"); 176 break; 177 default: 178 close(pfd[0]); 179 fprint(pfd[1], "From: %s-owner\n\n", listname); 180 if(rem) 181 fprint(pfd[1], "You have removed from the %s mailing list\n", listname); 182 else{ 183 fprint(pfd[1], "You have been added to the %s mailing list\n", listname); 184 fprint(pfd[1], "To be removed, send an email to %s-owner containing\n", 185 listname); 186 fprint(pfd[1], "the word 'remove' in the subject or body.\n"); 187 } 188 close(pfd[1]); 189 190 /* wait for mailer to end */ 191 while(w = wait()){ 192 if(w->msg != nil && w->msg[0]) 193 sysfatal("%s", w->msg); 194 free(w); 195 } 196 break; 197 } 198 } 199