13 void (*fn)(Comp *, char **, int);
41 assert(na < nelem(av));
42 procexec(c->sync, "/bin/upas/marshal", av);
46 postmesg(Comp *c, char **, int nf)
48 char *buf, wpath[64], *path;
52 snprint(wpath, sizeof(wpath), "/mnt/acme/%d/body", c->id);
54 fprint(2, "Post: too many args\n");
57 if((fd = open(wpath, OREAD)) == -1){
58 fprint(2, "open body: %r\n");
62 sysfatal("pipe: %r\n");
64 c->sync = chancreate(sizeof(ulong), 0);
65 procrfork(execmarshal, c, Stack, RFNOTEG);
71 while((n = read(fd, buf, Bufsz)) > 0)
72 if(write(c->fd[1], buf, n) != n)
74 write(c->fd[1], "\n", 1);
80 if(fprint(c->ctl, "name %s:Sent\n", c->path) == -1)
81 sysfatal("write ctl: %r");
82 if(c->replyto != nil){
83 if((m = mesglookup(c->rname, c->rdigest)) == nil)
86 path = estrjoin(mbox.path, "/", m->name, "/flags", nil);
87 if((fd = open(path, OWRITE)) != -1){
94 fprint(c->ctl, "clean\n");
98 compquit(Comp *c, char **, int)
103 static Fn compfn[] = {
120 c->qnext = mbox.opencomp;
122 fprint(c->ctl, "clean\n");
125 if(winevent(c, &ev) != 'M')
127 if(strcmp(ev.text, "Del") == 0)
132 if(matchmesg(&mbox, ev.text))
133 mesgopen(ev.text, nil);
139 if((nf = tokenize(ev.text, f, nelem(f))) == 0)
141 for(p = compfn; p->fn != nil; p++)
142 if(strcmp(p->name, f[0]) == 0){
143 p->fn(c, &f[1], nf - 1);
152 for(pc = &mbox.opencomp; *pc != nil; pc = &(*pc)->qnext)
174 assert(r->state & Sopen);
176 wingetsel(r, &q0, &q1);
178 s = smprint("/mnt/acme/%d/xdata", r->id);
187 strpcmp(void *a, void *b)
189 return strcmp(*(char**)a, *(char**)b);
193 show(Biobuf *fd, char *type, char **addrs, int naddrs)
202 qsort(addrs, naddrs, sizeof(char*), strpcmp);
203 Bprint(fd, "%s: ", type);
204 for(i = 0; i < naddrs; i++){
205 if(i > 0 && strcmp(addrs[i-1], addrs[i]) == 0)
207 w += Bprint(fd, "%s%s", sep, addrs[i]);
212 Bprint(fd, "\n%s: ", type);
219 respondto(Biobuf *fd, char *to, Mesg *r, int all)
226 rpto = (strlen(r->replyto) > 0) ? r->replyto : r->from;
227 if(r == nil || !all){
228 Bprint(fd, "To: %s\n", rpto);
233 addrs = emalloc(64*sizeof(char*));
234 n += tokenize(to, addrs+n, 64-n);
235 n += tokenize(rpto, addrs+n, 64-n);
236 n += tokenize(r->to, addrs+n, 64-n);
237 show(fd, "To", addrs, n);
238 n = tokenize(r->cc, addrs+n, 64-n);
239 show(fd, "CC", addrs, n);
244 compose(char *to, Mesg *r, int all)
251 c = emalloc(sizeof(Comp));
253 c->path = esmprint("%s%s%s.%d", mbox.path, r->name, "Reply", ncompose++);
255 c->path = esmprint("%sCompose.%d", mbox.path, ncompose++);
258 wintagwrite(c, "Post |fmt ");
259 wfd = bwinopen(c, "body", OWRITE);
260 respondto(wfd, to, r, all);
262 Bprint(wfd, "Subject: ");
264 if(r->messageid != nil)
265 c->replyto = estrdup(r->messageid);
266 c->rpath = estrjoin(mbox.path, r->name, nil);
267 c->rname = estrdup(r->name);
268 c->rdigest = estrdup(r->digest);
269 Bprint(wfd, "Subject: ");
270 if(r->subject != nil && cistrncmp(r->subject, "Re", 2) != 0)
272 Bprint(wfd, "%s\n\n", r->subject);
273 Bprint(wfd, "Quoth %s:\n", r->fromcolon);
276 while((ln = Brdstr(rfd, '\n', 0)) != nil)
277 if(Bprint(wfd, "> %s", ln) == -1)
284 fprint(c->addr, "$");
285 fprint(c->ctl, "dot=addr");
286 threadcreate(compmain, c, Stack);