Blob


1 #include "common.h"
2 #include "dat.h"
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 }
14 /* send messae adding our own reply-to and precedence */
15 void
16 getaddrs(void)
17 {
18 Field *f;
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 }
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;
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);
51 if(*addr != '#')
52 sendnotification(addr, listname, rem);
53 }
55 void
56 remaddr(char *addr)
57 {
58 Addr **l;
59 Addr *a;
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 }
72 int
73 addaddr(char *addr)
74 {
75 Addr **l;
76 Addr *a;
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 }
93 /* read address file */
94 void
95 readaddrs(char *file)
96 {
97 Biobuf *b;
98 char *p;
100 b = Bopen(file, OREAD);
101 if(b == nil)
102 return;
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);
113 Bterm(b);
116 /* start a mailer sending to all the receivers */
117 int
118 startmailer(char *name)
120 int pfd[2];
121 char **av;
122 int ac;
123 Addr *a;
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];
139 dup(pfd[0], 0);
140 close(pfd[0]);
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");
153 /* not reached */
154 return -1;
157 void
158 sendnotification(char *addr, char *listname, int rem)
160 int pfd[2];
161 Waitmsg *w;
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");
187 close(pfd[1]);
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);
195 break;