common.c (3372B)
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 nd; 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 nulldir(&nd); 41 nd.mode = DMAPPEND|0666; 42 dirwstat(file, &nd); 43 } else 44 seek(fd, 0, 2); 45 if(rem) 46 fprint(fd, "!%s\n", addr); 47 else 48 fprint(fd, "%s\n", addr); 49 close(fd); 50 51 if(*addr != '#') 52 sendnotification(addr, listname, rem); 53 } 54 55 void 56 remaddr(char *addr) 57 { 58 Addr **l; 59 Addr *a; 60 61 for(l = &al; *l; l = &(*l)->next){ 62 a = *l; 63 if(strcmp(addr, a->addr) == 0){ 64 (*l) = a->next; 65 free(a); 66 na--; 67 break; 68 } 69 } 70 } 71 72 int 73 addaddr(char *addr) 74 { 75 Addr **l; 76 Addr *a; 77 78 for(l = &al; *l; l = &(*l)->next){ 79 if(strcmp(addr, (*l)->addr) == 0) 80 return 0; 81 } 82 na++; 83 *l = a = malloc(sizeof(*a)+strlen(addr)+1); 84 if(a == nil) 85 sysfatal("allocating: %r"); 86 a->addr = (char*)&a[1]; 87 strcpy(a->addr, addr); 88 a->next = nil; 89 *l = a; 90 return 1; 91 } 92 93 /* read address file */ 94 void 95 readaddrs(char *file) 96 { 97 Biobuf *b; 98 char *p; 99 100 b = Bopen(file, OREAD); 101 if(b == nil) 102 return; 103 104 while((p = Brdline(b, '\n')) != nil){ 105 p[Blinelen(b)-1] = 0; 106 if(*p == '#') 107 continue; 108 if(*p == '!') 109 remaddr(p+1); 110 else 111 addaddr(p); 112 } 113 Bterm(b); 114 } 115 116 /* start a mailer sending to all the receivers */ 117 int 118 startmailer(char *name) 119 { 120 int pfd[2]; 121 char **av; 122 int ac; 123 Addr *a; 124 125 putenv("upasname", "/dev/null"); 126 if(pipe(pfd) < 0) 127 sysfatal("creating pipe: %r"); 128 switch(fork()){ 129 case -1: 130 sysfatal("starting mailer: %r"); 131 case 0: 132 close(pfd[1]); 133 break; 134 default: 135 close(pfd[0]); 136 return pfd[1]; 137 } 138 139 dup(pfd[0], 0); 140 close(pfd[0]); 141 142 av = malloc(sizeof(char*)*(na+2)); 143 if(av == nil) 144 sysfatal("starting mailer: %r"); 145 ac = 0; 146 av[ac++] = name; 147 for(a = al; a != nil; a = a->next) 148 av[ac++] = a->addr; 149 av[ac] = 0; 150 exec("/bin/upas/send", av); 151 sysfatal("execing mailer: %r"); 152 153 /* not reached */ 154 return -1; 155 } 156 157 void 158 sendnotification(char *addr, char *listname, int rem) 159 { 160 int pfd[2]; 161 Waitmsg *w; 162 163 putenv("upasname", "/dev/null"); 164 if(pipe(pfd) < 0) 165 sysfatal("creating pipe: %r"); 166 switch(fork()){ 167 case -1: 168 sysfatal("starting mailer: %r"); 169 case 0: 170 close(pfd[1]); 171 dup(pfd[0], 0); 172 close(pfd[0]); 173 execl("/bin/upas/send", "mlnotify", addr, nil); 174 sysfatal("execing mailer: %r"); 175 break; 176 default: 177 close(pfd[0]); 178 fprint(pfd[1], "From: %s-owner\n\n", listname); 179 if(rem) 180 fprint(pfd[1], "You have removed from the %s mailing list\n", listname); 181 else{ 182 fprint(pfd[1], "You have been added to the %s mailing list\n", listname); 183 fprint(pfd[1], "To be removed, send an email to %s-owner containing\n", 184 listname); 185 fprint(pfd[1], "the word 'remove' in the subject or body.\n"); 186 } 187 close(pfd[1]); 188 189 /* wait for mailer to end */ 190 while(w = wait()){ 191 if(w->msg != nil && w->msg[0]) 192 sysfatal("%s", w->msg); 193 free(w); 194 } 195 break; 196 } 197 }