Blame


1 9f1fdc12 2005-10-29 devnull #include <u.h>
2 9f1fdc12 2005-10-29 devnull #include <libc.h>
3 9f1fdc12 2005-10-29 devnull #include <bio.h>
4 9f1fdc12 2005-10-29 devnull #include <thread.h>
5 9f1fdc12 2005-10-29 devnull #include <plumb.h>
6 9f1fdc12 2005-10-29 devnull #include <ctype.h>
7 9f1fdc12 2005-10-29 devnull #include <9pclient.h> /* jpc */
8 9f1fdc12 2005-10-29 devnull #include "dat.h"
9 9f1fdc12 2005-10-29 devnull
10 9f1fdc12 2005-10-29 devnull char *maildir = "/mail/fs/"; /* mountpoint of mail file system */
11 9f1fdc12 2005-10-29 devnull char *mailtermdir = "/mnt/term/mail/fs/"; /* alternate mountpoint */
12 9f1fdc12 2005-10-29 devnull char *mboxname = "mbox"; /* mailboxdir/mboxname is mail spool file */
13 9f1fdc12 2005-10-29 devnull char *mailboxdir = nil; /* nil == /mail/box/$user */
14 9f1fdc12 2005-10-29 devnull char *fsname; /* filesystem for mailboxdir/mboxname is at maildir/fsname */
15 9f1fdc12 2005-10-29 devnull char *user;
16 9f1fdc12 2005-10-29 devnull char *outgoing;
17 9f1fdc12 2005-10-29 devnull
18 9f1fdc12 2005-10-29 devnull Window *wbox;
19 9f1fdc12 2005-10-29 devnull Message mbox;
20 9f1fdc12 2005-10-29 devnull Message replies;
21 9f1fdc12 2005-10-29 devnull char *home;
22 9f1fdc12 2005-10-29 devnull int plumbsendfd;
23 9f1fdc12 2005-10-29 devnull int plumbseemailfd;
24 9f1fdc12 2005-10-29 devnull int plumbshowmailfd;
25 9f1fdc12 2005-10-29 devnull int plumbsendmailfd;
26 9f1fdc12 2005-10-29 devnull Channel *cplumb;
27 9f1fdc12 2005-10-29 devnull Channel *cplumbshow;
28 9f1fdc12 2005-10-29 devnull Channel *cplumbsend;
29 9f1fdc12 2005-10-29 devnull int wctlfd;
30 9f1fdc12 2005-10-29 devnull void mainctl(void*);
31 9f1fdc12 2005-10-29 devnull void plumbproc(void*);
32 9f1fdc12 2005-10-29 devnull void plumbshowproc(void*);
33 9f1fdc12 2005-10-29 devnull void plumbsendproc(void*);
34 9f1fdc12 2005-10-29 devnull void plumbthread(void);
35 9f1fdc12 2005-10-29 devnull void plumbshowthread(void*);
36 9f1fdc12 2005-10-29 devnull void plumbsendthread(void*);
37 9f1fdc12 2005-10-29 devnull
38 9f1fdc12 2005-10-29 devnull int shortmenu;
39 9f1fdc12 2005-10-29 devnull
40 9f1fdc12 2005-10-29 devnull CFsys *upasfs; /*jpc */
41 9f1fdc12 2005-10-29 devnull CFsys *acmefs; /*jpc */
42 9f1fdc12 2005-10-29 devnull
43 9f1fdc12 2005-10-29 devnull void
44 9f1fdc12 2005-10-29 devnull usage(void)
45 9f1fdc12 2005-10-29 devnull {
46 9f1fdc12 2005-10-29 devnull fprint(2, "usage: Mail [-sS] [-o outgoing] [mailboxname [directoryname]]\n");
47 9f1fdc12 2005-10-29 devnull threadexitsall("usage");
48 9f1fdc12 2005-10-29 devnull }
49 9f1fdc12 2005-10-29 devnull
50 9f1fdc12 2005-10-29 devnull void
51 9f1fdc12 2005-10-29 devnull removeupasfs(void)
52 9f1fdc12 2005-10-29 devnull {
53 9f1fdc12 2005-10-29 devnull char buf[256];
54 9f1fdc12 2005-10-29 devnull
55 9f1fdc12 2005-10-29 devnull if(strcmp(mboxname, "mbox") == 0)
56 9f1fdc12 2005-10-29 devnull return;
57 9f1fdc12 2005-10-29 devnull snprint(buf, sizeof buf, "close %s", mboxname);
58 9f1fdc12 2005-10-29 devnull write(mbox.ctlfd, buf, strlen(buf));
59 9f1fdc12 2005-10-29 devnull }
60 9f1fdc12 2005-10-29 devnull
61 9f1fdc12 2005-10-29 devnull int
62 9f1fdc12 2005-10-29 devnull ismaildir(char *s)
63 9f1fdc12 2005-10-29 devnull {
64 9f1fdc12 2005-10-29 devnull char buf[256];
65 9f1fdc12 2005-10-29 devnull Dir *d;
66 9f1fdc12 2005-10-29 devnull int ret;
67 9f1fdc12 2005-10-29 devnull
68 9f1fdc12 2005-10-29 devnull snprint(buf, sizeof buf, "%s%s", maildir, s);
69 9f1fdc12 2005-10-29 devnull d = dirstat(buf);
70 9f1fdc12 2005-10-29 devnull if(d == nil)
71 9f1fdc12 2005-10-29 devnull return 0;
72 9f1fdc12 2005-10-29 devnull ret = d->qid.type & QTDIR;
73 9f1fdc12 2005-10-29 devnull free(d);
74 9f1fdc12 2005-10-29 devnull return ret;
75 9f1fdc12 2005-10-29 devnull }
76 9f1fdc12 2005-10-29 devnull
77 9f1fdc12 2005-10-29 devnull void
78 9f1fdc12 2005-10-29 devnull threadmain(int argc, char *argv[])
79 9f1fdc12 2005-10-29 devnull {
80 9f1fdc12 2005-10-29 devnull char *s, *name;
81 9f1fdc12 2005-10-29 devnull char err[ERRMAX], *cmd;
82 9f1fdc12 2005-10-29 devnull int i, newdir;
83 9f1fdc12 2005-10-29 devnull Fmt fmt;
84 9f1fdc12 2005-10-29 devnull
85 9f1fdc12 2005-10-29 devnull doquote = needsrcquote;
86 9f1fdc12 2005-10-29 devnull quotefmtinstall();
87 9f1fdc12 2005-10-29 devnull
88 9f1fdc12 2005-10-29 devnull /* open these early so we won't miss notification of new mail messages while we read mbox */
89 9f1fdc12 2005-10-29 devnull plumbsendfd = plumbopen("send", OWRITE|OCEXEC);
90 9f1fdc12 2005-10-29 devnull plumbseemailfd = plumbopen("seemail", OREAD|OCEXEC);
91 9f1fdc12 2005-10-29 devnull plumbshowmailfd = plumbopen("showmail", OREAD|OCEXEC);
92 9f1fdc12 2005-10-29 devnull
93 9f1fdc12 2005-10-29 devnull /* jpc */
94 9f1fdc12 2005-10-29 devnull acmefs = nsmount("acme",nil);
95 9f1fdc12 2005-10-29 devnull upasfs = nsmount("upasfs", nil);
96 9f1fdc12 2005-10-29 devnull /* jpc end */
97 9f1fdc12 2005-10-29 devnull
98 9f1fdc12 2005-10-29 devnull shortmenu = 0;
99 9f1fdc12 2005-10-29 devnull ARGBEGIN{
100 9f1fdc12 2005-10-29 devnull case 's':
101 9f1fdc12 2005-10-29 devnull shortmenu = 1;
102 9f1fdc12 2005-10-29 devnull break;
103 9f1fdc12 2005-10-29 devnull case 'S':
104 9f1fdc12 2005-10-29 devnull shortmenu = 2;
105 9f1fdc12 2005-10-29 devnull break;
106 9f1fdc12 2005-10-29 devnull case 'o':
107 9f1fdc12 2005-10-29 devnull outgoing = EARGF(usage());
108 9f1fdc12 2005-10-29 devnull break;
109 9f1fdc12 2005-10-29 devnull case 'm':
110 9f1fdc12 2005-10-29 devnull smprint(maildir, "%s/", EARGF(usage()));
111 9f1fdc12 2005-10-29 devnull break;
112 9f1fdc12 2005-10-29 devnull default:
113 9f1fdc12 2005-10-29 devnull usage();
114 9f1fdc12 2005-10-29 devnull }ARGEND
115 9f1fdc12 2005-10-29 devnull
116 9f1fdc12 2005-10-29 devnull name = "mbox";
117 9f1fdc12 2005-10-29 devnull
118 9f1fdc12 2005-10-29 devnull /* bind the terminal /mail/fs directory over the local one */
119 9f1fdc12 2005-10-29 devnull if(access(maildir, 0)<0 && access(mailtermdir, 0)==0) {
120 9f1fdc12 2005-10-29 devnull /* jpc - bind(mailtermdir, maildir, MAFTER); */
121 9f1fdc12 2005-10-29 devnull fprint(2,"jpc: trying to bind(mailtermdir, maildir, MAFTER)\n");
122 9f1fdc12 2005-10-29 devnull }
123 9f1fdc12 2005-10-29 devnull
124 9f1fdc12 2005-10-29 devnull newdir = 1;
125 9f1fdc12 2005-10-29 devnull if(argc > 0){
126 9f1fdc12 2005-10-29 devnull i = strlen(argv[0]);
127 9f1fdc12 2005-10-29 devnull if(argc>2 || i==0)
128 9f1fdc12 2005-10-29 devnull usage();
129 9f1fdc12 2005-10-29 devnull /* see if the name is that of an existing /mail/fs directory */
130 9f1fdc12 2005-10-29 devnull if(argc==1 && strchr(argv[0], '/')==0 && ismaildir(argv[0])){
131 9f1fdc12 2005-10-29 devnull name = argv[0];
132 9f1fdc12 2005-10-29 devnull mboxname = eappend(estrdup(maildir), "", name);
133 9f1fdc12 2005-10-29 devnull newdir = 0;
134 9f1fdc12 2005-10-29 devnull }else{
135 9f1fdc12 2005-10-29 devnull if(argv[0][i-1] == '/')
136 9f1fdc12 2005-10-29 devnull argv[0][i-1] = '\0';
137 9f1fdc12 2005-10-29 devnull s = strrchr(argv[0], '/');
138 9f1fdc12 2005-10-29 devnull if(s == nil)
139 9f1fdc12 2005-10-29 devnull mboxname = estrdup(argv[0]);
140 9f1fdc12 2005-10-29 devnull else{
141 9f1fdc12 2005-10-29 devnull *s++ = '\0';
142 9f1fdc12 2005-10-29 devnull if(*s == '\0')
143 9f1fdc12 2005-10-29 devnull usage();
144 9f1fdc12 2005-10-29 devnull mailboxdir = argv[0];
145 9f1fdc12 2005-10-29 devnull mboxname = estrdup(s);
146 9f1fdc12 2005-10-29 devnull }
147 9f1fdc12 2005-10-29 devnull if(argc > 1)
148 9f1fdc12 2005-10-29 devnull name = argv[1];
149 9f1fdc12 2005-10-29 devnull else
150 9f1fdc12 2005-10-29 devnull name = mboxname;
151 9f1fdc12 2005-10-29 devnull }
152 9f1fdc12 2005-10-29 devnull }
153 9f1fdc12 2005-10-29 devnull
154 9f1fdc12 2005-10-29 devnull user = getenv("user");
155 9f1fdc12 2005-10-29 devnull if(user == nil)
156 9f1fdc12 2005-10-29 devnull user = "none";
157 9f1fdc12 2005-10-29 devnull if(mailboxdir == nil)
158 9f1fdc12 2005-10-29 devnull mailboxdir = estrstrdup(unsharp("#9/mail/box/"), user);
159 9f1fdc12 2005-10-29 devnull if(outgoing == nil)
160 9f1fdc12 2005-10-29 devnull outgoing = estrstrdup(mailboxdir, "/outgoing");
161 9f1fdc12 2005-10-29 devnull
162 9f1fdc12 2005-10-29 devnull // s = estrstrdup(maildir, "ctl");
163 9f1fdc12 2005-10-29 devnull mbox.ctlfd = fsopenfd(upasfs,"ctl", ORDWR|OCEXEC);
164 9f1fdc12 2005-10-29 devnull if(mbox.ctlfd < 0)
165 9f1fdc12 2005-10-29 devnull error("can't open %s: %r\n", s);
166 9f1fdc12 2005-10-29 devnull
167 9f1fdc12 2005-10-29 devnull fsname = estrdup(name);
168 9f1fdc12 2005-10-29 devnull if(newdir && argc > 0){
169 9f1fdc12 2005-10-29 devnull s = emalloc(5+strlen(mailboxdir)+strlen(mboxname)+strlen(name)+10+1);
170 9f1fdc12 2005-10-29 devnull for(i=0; i<10; i++){
171 9f1fdc12 2005-10-29 devnull sprint(s, "open %s/%s %s", mailboxdir, mboxname, fsname);
172 9f1fdc12 2005-10-29 devnull if(write(mbox.ctlfd, s, strlen(s)) >= 0)
173 9f1fdc12 2005-10-29 devnull break;
174 9f1fdc12 2005-10-29 devnull err[0] = '\0';
175 9f1fdc12 2005-10-29 devnull errstr(err, sizeof err);
176 9f1fdc12 2005-10-29 devnull if(strstr(err, "mbox name in use") == nil)
177 9f1fdc12 2005-10-29 devnull error("can't create directory %s for mail: %s\n", name, err);
178 9f1fdc12 2005-10-29 devnull free(fsname);
179 9f1fdc12 2005-10-29 devnull fsname = emalloc(strlen(name)+10);
180 9f1fdc12 2005-10-29 devnull sprint(fsname, "%s-%d", name, i);
181 9f1fdc12 2005-10-29 devnull }
182 9f1fdc12 2005-10-29 devnull if(i == 10)
183 9f1fdc12 2005-10-29 devnull error("can't open %s/%s: %r", mailboxdir, mboxname);
184 9f1fdc12 2005-10-29 devnull free(s);
185 9f1fdc12 2005-10-29 devnull }
186 9f1fdc12 2005-10-29 devnull
187 9f1fdc12 2005-10-29 devnull s = estrstrdup(fsname, "/");
188 9f1fdc12 2005-10-29 devnull mbox.name = estrstrdup(maildir, s);
189 9f1fdc12 2005-10-29 devnull // mbox.name = "/mail/fs/mbox/";
190 9f1fdc12 2005-10-29 devnull mbox.level= 0;
191 9f1fdc12 2005-10-29 devnull readmbox(&mbox, maildir, s);
192 9f1fdc12 2005-10-29 devnull home = getenv("home");
193 9f1fdc12 2005-10-29 devnull if(home == nil)
194 9f1fdc12 2005-10-29 devnull home = "/";
195 9f1fdc12 2005-10-29 devnull
196 9f1fdc12 2005-10-29 devnull wbox = newwindow();
197 9f1fdc12 2005-10-29 devnull winname(wbox, mbox.name);
198 9f1fdc12 2005-10-29 devnull wintagwrite(wbox, "Put Mail Delmesg ", 3+1+4+1+7+1);
199 9f1fdc12 2005-10-29 devnull threadcreate(mainctl, wbox, STACK);
200 9f1fdc12 2005-10-29 devnull
201 9f1fdc12 2005-10-29 devnull fmtstrinit(&fmt);
202 9f1fdc12 2005-10-29 devnull fmtprint(&fmt, "Mail");
203 9f1fdc12 2005-10-29 devnull if(shortmenu)
204 9f1fdc12 2005-10-29 devnull fmtprint(&fmt, " -%c", "sS"[shortmenu-1]);
205 9f1fdc12 2005-10-29 devnull if(outgoing)
206 9f1fdc12 2005-10-29 devnull fmtprint(&fmt, " -o %s", outgoing);
207 9f1fdc12 2005-10-29 devnull fmtprint(&fmt, " %s", name);
208 9f1fdc12 2005-10-29 devnull cmd = fmtstrflush(&fmt);
209 9f1fdc12 2005-10-29 devnull if(cmd == nil)
210 9f1fdc12 2005-10-29 devnull sysfatal("out of memory");
211 9f1fdc12 2005-10-29 devnull winsetdump(wbox, "/acme/mail", cmd);
212 9f1fdc12 2005-10-29 devnull mbox.w = wbox;
213 9f1fdc12 2005-10-29 devnull
214 9f1fdc12 2005-10-29 devnull mesgmenu(wbox, &mbox);
215 9f1fdc12 2005-10-29 devnull // sleep(100);
216 9f1fdc12 2005-10-29 devnull winclean(wbox);
217 9f1fdc12 2005-10-29 devnull
218 9f1fdc12 2005-10-29 devnull wctlfd = open("/dev/wctl", OWRITE|OCEXEC); /* for acme window */
219 9f1fdc12 2005-10-29 devnull cplumb = chancreate(sizeof(Plumbmsg*), 0);
220 9f1fdc12 2005-10-29 devnull cplumbshow = chancreate(sizeof(Plumbmsg*), 0);
221 9f1fdc12 2005-10-29 devnull if(strcmp(name, "mbox") == 0){
222 9f1fdc12 2005-10-29 devnull /*
223 9f1fdc12 2005-10-29 devnull * Avoid creating multiple windows to send mail by only accepting
224 9f1fdc12 2005-10-29 devnull * sendmail plumb messages if we're reading the main mailbox.
225 9f1fdc12 2005-10-29 devnull */
226 9f1fdc12 2005-10-29 devnull plumbsendmailfd = plumbopen("sendmail", OREAD|OCEXEC);
227 9f1fdc12 2005-10-29 devnull cplumbsend = chancreate(sizeof(Plumbmsg*), 0);
228 9f1fdc12 2005-10-29 devnull proccreate(plumbsendproc, nil, STACK);
229 9f1fdc12 2005-10-29 devnull threadcreate(plumbsendthread, nil, STACK);
230 9f1fdc12 2005-10-29 devnull }
231 9f1fdc12 2005-10-29 devnull /* start plumb reader as separate proc ... */
232 9f1fdc12 2005-10-29 devnull proccreate(plumbproc, nil, STACK);
233 9f1fdc12 2005-10-29 devnull proccreate(plumbshowproc, nil, STACK);
234 9f1fdc12 2005-10-29 devnull threadcreate(plumbshowthread, nil, STACK);
235 9f1fdc12 2005-10-29 devnull /* ... and use this thread to read the messages */
236 9f1fdc12 2005-10-29 devnull plumbthread();
237 9f1fdc12 2005-10-29 devnull }
238 9f1fdc12 2005-10-29 devnull
239 9f1fdc12 2005-10-29 devnull void
240 9f1fdc12 2005-10-29 devnull plumbproc(void* v)
241 9f1fdc12 2005-10-29 devnull {
242 9f1fdc12 2005-10-29 devnull Plumbmsg *m;
243 9f1fdc12 2005-10-29 devnull
244 9f1fdc12 2005-10-29 devnull threadsetname("plumbproc");
245 9f1fdc12 2005-10-29 devnull for(;;){
246 9f1fdc12 2005-10-29 devnull m = plumbrecv(plumbseemailfd);
247 9f1fdc12 2005-10-29 devnull sendp(cplumb, m);
248 9f1fdc12 2005-10-29 devnull if(m == nil)
249 9f1fdc12 2005-10-29 devnull threadexits(nil);
250 9f1fdc12 2005-10-29 devnull }
251 9f1fdc12 2005-10-29 devnull }
252 9f1fdc12 2005-10-29 devnull
253 9f1fdc12 2005-10-29 devnull void
254 9f1fdc12 2005-10-29 devnull plumbshowproc(void* v)
255 9f1fdc12 2005-10-29 devnull {
256 9f1fdc12 2005-10-29 devnull Plumbmsg *m;
257 9f1fdc12 2005-10-29 devnull
258 9f1fdc12 2005-10-29 devnull threadsetname("plumbshowproc");
259 9f1fdc12 2005-10-29 devnull for(;;){
260 9f1fdc12 2005-10-29 devnull m = plumbrecv(plumbshowmailfd);
261 9f1fdc12 2005-10-29 devnull sendp(cplumbshow, m);
262 9f1fdc12 2005-10-29 devnull if(m == nil)
263 9f1fdc12 2005-10-29 devnull threadexits(nil);
264 9f1fdc12 2005-10-29 devnull }
265 9f1fdc12 2005-10-29 devnull }
266 9f1fdc12 2005-10-29 devnull
267 9f1fdc12 2005-10-29 devnull void
268 9f1fdc12 2005-10-29 devnull plumbsendproc(void* v)
269 9f1fdc12 2005-10-29 devnull {
270 9f1fdc12 2005-10-29 devnull Plumbmsg *m;
271 9f1fdc12 2005-10-29 devnull
272 9f1fdc12 2005-10-29 devnull threadsetname("plumbsendproc");
273 9f1fdc12 2005-10-29 devnull for(;;){
274 9f1fdc12 2005-10-29 devnull m = plumbrecv(plumbsendmailfd);
275 9f1fdc12 2005-10-29 devnull sendp(cplumbsend, m);
276 9f1fdc12 2005-10-29 devnull if(m == nil)
277 9f1fdc12 2005-10-29 devnull threadexits(nil);
278 9f1fdc12 2005-10-29 devnull }
279 9f1fdc12 2005-10-29 devnull }
280 9f1fdc12 2005-10-29 devnull
281 9f1fdc12 2005-10-29 devnull void
282 9f1fdc12 2005-10-29 devnull newmesg(char *name, char *digest)
283 9f1fdc12 2005-10-29 devnull {
284 9f1fdc12 2005-10-29 devnull Dir *d;
285 9f1fdc12 2005-10-29 devnull char* tmp;
286 9f1fdc12 2005-10-29 devnull
287 9f1fdc12 2005-10-29 devnull if(strncmp(name, mbox.name, strlen(mbox.name)) != 0) {
288 9f1fdc12 2005-10-29 devnull return; /* message is about another mailbox */
289 9f1fdc12 2005-10-29 devnull }
290 9f1fdc12 2005-10-29 devnull if(mesglookupfile(&mbox, name, digest) != nil) {
291 9f1fdc12 2005-10-29 devnull return;
292 9f1fdc12 2005-10-29 devnull }
293 9f1fdc12 2005-10-29 devnull if (strncmp(name,"/mail/fs/",strlen("/mail/fs/"))==0) {
294 9f1fdc12 2005-10-29 devnull tmp = name+strlen("/mail/fs/");
295 9f1fdc12 2005-10-29 devnull }
296 9f1fdc12 2005-10-29 devnull d = fsdirstat(upasfs,tmp);
297 9f1fdc12 2005-10-29 devnull if(d == nil) {
298 9f1fdc12 2005-10-29 devnull return;
299 9f1fdc12 2005-10-29 devnull }
300 9f1fdc12 2005-10-29 devnull if(mesgadd(&mbox, mbox.name, d, digest)) {
301 9f1fdc12 2005-10-29 devnull mesgmenunew(wbox, &mbox);
302 9f1fdc12 2005-10-29 devnull }
303 9f1fdc12 2005-10-29 devnull free(d);
304 9f1fdc12 2005-10-29 devnull }
305 9f1fdc12 2005-10-29 devnull
306 9f1fdc12 2005-10-29 devnull void
307 9f1fdc12 2005-10-29 devnull showmesg(char *name, char *digest)
308 9f1fdc12 2005-10-29 devnull {
309 9f1fdc12 2005-10-29 devnull char *n;
310 9f1fdc12 2005-10-29 devnull
311 9f1fdc12 2005-10-29 devnull if(strncmp(name, mbox.name, strlen(mbox.name)) != 0)
312 9f1fdc12 2005-10-29 devnull return; /* message is about another mailbox */
313 9f1fdc12 2005-10-29 devnull n = estrdup(name+strlen(mbox.name));
314 9f1fdc12 2005-10-29 devnull if(n[strlen(n)-1] != '/')
315 9f1fdc12 2005-10-29 devnull n = egrow(n, "/", nil);
316 9f1fdc12 2005-10-29 devnull mesgopen(&mbox, mbox.name, name+strlen(mbox.name), nil, 1, digest);
317 9f1fdc12 2005-10-29 devnull free(n);
318 9f1fdc12 2005-10-29 devnull }
319 9f1fdc12 2005-10-29 devnull
320 9f1fdc12 2005-10-29 devnull void
321 9f1fdc12 2005-10-29 devnull delmesg(char *name, char *digest, int dodel)
322 9f1fdc12 2005-10-29 devnull {
323 9f1fdc12 2005-10-29 devnull Message *m;
324 9f1fdc12 2005-10-29 devnull
325 9f1fdc12 2005-10-29 devnull m = mesglookupfile(&mbox, name, digest);
326 9f1fdc12 2005-10-29 devnull if(m != nil){
327 9f1fdc12 2005-10-29 devnull mesgmenumarkdel(wbox, &mbox, m, 0);
328 9f1fdc12 2005-10-29 devnull if(dodel)
329 9f1fdc12 2005-10-29 devnull m->writebackdel = 1;
330 9f1fdc12 2005-10-29 devnull }
331 9f1fdc12 2005-10-29 devnull }
332 9f1fdc12 2005-10-29 devnull
333 9f1fdc12 2005-10-29 devnull void
334 9f1fdc12 2005-10-29 devnull plumbthread(void)
335 9f1fdc12 2005-10-29 devnull {
336 9f1fdc12 2005-10-29 devnull Plumbmsg *m;
337 9f1fdc12 2005-10-29 devnull Plumbattr *a;
338 9f1fdc12 2005-10-29 devnull char *type, *digest;
339 9f1fdc12 2005-10-29 devnull
340 9f1fdc12 2005-10-29 devnull threadsetname("plumbthread");
341 9f1fdc12 2005-10-29 devnull while((m = recvp(cplumb)) != nil){
342 9f1fdc12 2005-10-29 devnull a = m->attr;
343 9f1fdc12 2005-10-29 devnull digest = plumblookup(a, "digest");
344 9f1fdc12 2005-10-29 devnull type = plumblookup(a, "mailtype");
345 9f1fdc12 2005-10-29 devnull if(type == nil)
346 9f1fdc12 2005-10-29 devnull fprint(2, "Mail: plumb message with no mailtype attribute\n");
347 9f1fdc12 2005-10-29 devnull else if(strcmp(type, "new") == 0)
348 9f1fdc12 2005-10-29 devnull newmesg(m->data, digest);
349 9f1fdc12 2005-10-29 devnull else if(strcmp(type, "delete") == 0)
350 9f1fdc12 2005-10-29 devnull delmesg(m->data, digest, 0);
351 9f1fdc12 2005-10-29 devnull else
352 9f1fdc12 2005-10-29 devnull fprint(2, "Mail: unknown plumb attribute %s\n", type);
353 9f1fdc12 2005-10-29 devnull plumbfree(m);
354 9f1fdc12 2005-10-29 devnull }
355 9f1fdc12 2005-10-29 devnull threadexits(nil);
356 9f1fdc12 2005-10-29 devnull }
357 9f1fdc12 2005-10-29 devnull
358 9f1fdc12 2005-10-29 devnull void
359 9f1fdc12 2005-10-29 devnull plumbshowthread(void* v)
360 9f1fdc12 2005-10-29 devnull {
361 9f1fdc12 2005-10-29 devnull Plumbmsg *m;
362 9f1fdc12 2005-10-29 devnull
363 9f1fdc12 2005-10-29 devnull threadsetname("plumbshowthread");
364 9f1fdc12 2005-10-29 devnull while((m = recvp(cplumbshow)) != nil){
365 9f1fdc12 2005-10-29 devnull showmesg(m->data, plumblookup(m->attr, "digest"));
366 9f1fdc12 2005-10-29 devnull plumbfree(m);
367 9f1fdc12 2005-10-29 devnull }
368 9f1fdc12 2005-10-29 devnull threadexits(nil);
369 9f1fdc12 2005-10-29 devnull }
370 9f1fdc12 2005-10-29 devnull
371 9f1fdc12 2005-10-29 devnull void
372 9f1fdc12 2005-10-29 devnull plumbsendthread(void* v)
373 9f1fdc12 2005-10-29 devnull {
374 9f1fdc12 2005-10-29 devnull Plumbmsg *m;
375 9f1fdc12 2005-10-29 devnull
376 9f1fdc12 2005-10-29 devnull threadsetname("plumbsendthread");
377 9f1fdc12 2005-10-29 devnull while((m = recvp(cplumbsend)) != nil){
378 9f1fdc12 2005-10-29 devnull mkreply(nil, "Mail", m->data, m->attr, nil);
379 9f1fdc12 2005-10-29 devnull plumbfree(m);
380 9f1fdc12 2005-10-29 devnull }
381 9f1fdc12 2005-10-29 devnull threadexits(nil);
382 9f1fdc12 2005-10-29 devnull }
383 9f1fdc12 2005-10-29 devnull
384 9f1fdc12 2005-10-29 devnull int
385 9f1fdc12 2005-10-29 devnull mboxcommand(Window *w, char *s)
386 9f1fdc12 2005-10-29 devnull {
387 9f1fdc12 2005-10-29 devnull char *args[10], **targs;
388 9f1fdc12 2005-10-29 devnull Message *m, *next;
389 9f1fdc12 2005-10-29 devnull int ok, nargs, i, j;
390 9f1fdc12 2005-10-29 devnull char buf[128];
391 9f1fdc12 2005-10-29 devnull
392 9f1fdc12 2005-10-29 devnull nargs = tokenize(s, args, nelem(args));
393 9f1fdc12 2005-10-29 devnull if(nargs == 0)
394 9f1fdc12 2005-10-29 devnull return 0;
395 9f1fdc12 2005-10-29 devnull if(strcmp(args[0], "Mail") == 0){
396 9f1fdc12 2005-10-29 devnull if(nargs == 1)
397 9f1fdc12 2005-10-29 devnull mkreply(nil, "Mail", "", nil, nil);
398 9f1fdc12 2005-10-29 devnull else
399 9f1fdc12 2005-10-29 devnull mkreply(nil, "Mail", args[1], nil, nil);
400 9f1fdc12 2005-10-29 devnull return 1;
401 9f1fdc12 2005-10-29 devnull }
402 9f1fdc12 2005-10-29 devnull if(strcmp(s, "Del") == 0){
403 9f1fdc12 2005-10-29 devnull if(mbox.dirty){
404 9f1fdc12 2005-10-29 devnull mbox.dirty = 0;
405 9f1fdc12 2005-10-29 devnull fprint(2, "mail: mailbox not written\n");
406 9f1fdc12 2005-10-29 devnull return 1;
407 9f1fdc12 2005-10-29 devnull }
408 9f1fdc12 2005-10-29 devnull ok = 1;
409 9f1fdc12 2005-10-29 devnull for(m=mbox.head; m!=nil; m=next){
410 9f1fdc12 2005-10-29 devnull next = m->next;
411 9f1fdc12 2005-10-29 devnull if(m->w){
412 9f1fdc12 2005-10-29 devnull if(windel(m->w, 0))
413 9f1fdc12 2005-10-29 devnull m->w = nil;
414 9f1fdc12 2005-10-29 devnull else
415 9f1fdc12 2005-10-29 devnull ok = 0;
416 9f1fdc12 2005-10-29 devnull }
417 9f1fdc12 2005-10-29 devnull }
418 9f1fdc12 2005-10-29 devnull for(m=replies.head; m!=nil; m=next){
419 9f1fdc12 2005-10-29 devnull next = m->next;
420 9f1fdc12 2005-10-29 devnull if(m->w){
421 9f1fdc12 2005-10-29 devnull if(windel(m->w, 0))
422 9f1fdc12 2005-10-29 devnull m->w = nil;
423 9f1fdc12 2005-10-29 devnull else
424 9f1fdc12 2005-10-29 devnull ok = 0;
425 9f1fdc12 2005-10-29 devnull }
426 9f1fdc12 2005-10-29 devnull }
427 9f1fdc12 2005-10-29 devnull if(ok){
428 9f1fdc12 2005-10-29 devnull windel(w, 1);
429 9f1fdc12 2005-10-29 devnull removeupasfs();
430 9f1fdc12 2005-10-29 devnull threadexitsall(nil);
431 9f1fdc12 2005-10-29 devnull }
432 9f1fdc12 2005-10-29 devnull return 1;
433 9f1fdc12 2005-10-29 devnull }
434 9f1fdc12 2005-10-29 devnull if(strcmp(s, "Put") == 0){
435 9f1fdc12 2005-10-29 devnull rewritembox(wbox, &mbox);
436 9f1fdc12 2005-10-29 devnull return 1;
437 9f1fdc12 2005-10-29 devnull }
438 9f1fdc12 2005-10-29 devnull if(strcmp(s, "Delmesg") == 0){
439 9f1fdc12 2005-10-29 devnull if(nargs > 1){
440 9f1fdc12 2005-10-29 devnull for(i=1; i<nargs; i++){
441 9f1fdc12 2005-10-29 devnull snprint(buf, sizeof buf, "%s%s", mbox.name, args[i]);
442 9f1fdc12 2005-10-29 devnull delmesg(buf, nil, 1);
443 9f1fdc12 2005-10-29 devnull }
444 9f1fdc12 2005-10-29 devnull }
445 9f1fdc12 2005-10-29 devnull s = winselection(w);
446 9f1fdc12 2005-10-29 devnull if(s == nil)
447 9f1fdc12 2005-10-29 devnull return 1;
448 9f1fdc12 2005-10-29 devnull nargs = 1;
449 9f1fdc12 2005-10-29 devnull for(i=0; s[i]; i++)
450 9f1fdc12 2005-10-29 devnull if(s[i] == '\n')
451 9f1fdc12 2005-10-29 devnull nargs++;
452 9f1fdc12 2005-10-29 devnull targs = emalloc(nargs*sizeof(char*)); /* could be too many for a local array */
453 9f1fdc12 2005-10-29 devnull nargs = getfields(s, targs, nargs, 1, "\n");
454 9f1fdc12 2005-10-29 devnull for(i=0; i<nargs; i++){
455 9f1fdc12 2005-10-29 devnull if(!isdigit(targs[i][0]))
456 9f1fdc12 2005-10-29 devnull continue;
457 9f1fdc12 2005-10-29 devnull j = atoi(targs[i]); /* easy way to parse the number! */
458 9f1fdc12 2005-10-29 devnull if(j == 0)
459 9f1fdc12 2005-10-29 devnull continue;
460 9f1fdc12 2005-10-29 devnull snprint(buf, sizeof buf, "%s%d", mbox.name, j);
461 9f1fdc12 2005-10-29 devnull delmesg(buf, nil, 1);
462 9f1fdc12 2005-10-29 devnull }
463 9f1fdc12 2005-10-29 devnull free(s);
464 9f1fdc12 2005-10-29 devnull free(targs);
465 9f1fdc12 2005-10-29 devnull return 1;
466 9f1fdc12 2005-10-29 devnull }
467 9f1fdc12 2005-10-29 devnull return 0;
468 9f1fdc12 2005-10-29 devnull }
469 9f1fdc12 2005-10-29 devnull
470 9f1fdc12 2005-10-29 devnull void
471 9f1fdc12 2005-10-29 devnull mainctl(void *v)
472 9f1fdc12 2005-10-29 devnull {
473 9f1fdc12 2005-10-29 devnull Window *w;
474 9f1fdc12 2005-10-29 devnull Event *e, *e2, *eq, *ea;
475 9f1fdc12 2005-10-29 devnull int na, nopen;
476 9f1fdc12 2005-10-29 devnull char *s, *t, *buf;
477 9f1fdc12 2005-10-29 devnull
478 9f1fdc12 2005-10-29 devnull w = v;
479 9f1fdc12 2005-10-29 devnull proccreate(wineventproc, w, STACK);
480 9f1fdc12 2005-10-29 devnull
481 9f1fdc12 2005-10-29 devnull for(;;){
482 9f1fdc12 2005-10-29 devnull e = recvp(w->cevent);
483 9f1fdc12 2005-10-29 devnull switch(e->c1){
484 9f1fdc12 2005-10-29 devnull default:
485 9f1fdc12 2005-10-29 devnull Unknown:
486 9f1fdc12 2005-10-29 devnull print("unknown message %c%c\n", e->c1, e->c2);
487 9f1fdc12 2005-10-29 devnull break;
488 9f1fdc12 2005-10-29 devnull
489 9f1fdc12 2005-10-29 devnull case 'E': /* write to body; can't affect us */
490 9f1fdc12 2005-10-29 devnull break;
491 9f1fdc12 2005-10-29 devnull
492 9f1fdc12 2005-10-29 devnull case 'F': /* generated by our actions; ignore */
493 9f1fdc12 2005-10-29 devnull break;
494 9f1fdc12 2005-10-29 devnull
495 9f1fdc12 2005-10-29 devnull case 'K': /* type away; we don't care */
496 9f1fdc12 2005-10-29 devnull break;
497 9f1fdc12 2005-10-29 devnull
498 9f1fdc12 2005-10-29 devnull case 'M':
499 9f1fdc12 2005-10-29 devnull switch(e->c2){
500 9f1fdc12 2005-10-29 devnull case 'x':
501 9f1fdc12 2005-10-29 devnull case 'X':
502 9f1fdc12 2005-10-29 devnull ea = nil;
503 9f1fdc12 2005-10-29 devnull e2 = nil;
504 9f1fdc12 2005-10-29 devnull if(e->flag & 2)
505 9f1fdc12 2005-10-29 devnull e2 = recvp(w->cevent);
506 9f1fdc12 2005-10-29 devnull if(e->flag & 8){
507 9f1fdc12 2005-10-29 devnull ea = recvp(w->cevent);
508 9f1fdc12 2005-10-29 devnull na = ea->nb;
509 9f1fdc12 2005-10-29 devnull recvp(w->cevent);
510 9f1fdc12 2005-10-29 devnull }else
511 9f1fdc12 2005-10-29 devnull na = 0;
512 9f1fdc12 2005-10-29 devnull s = e->b;
513 9f1fdc12 2005-10-29 devnull /* if it's a known command, do it */
514 9f1fdc12 2005-10-29 devnull if((e->flag&2) && e->nb==0)
515 9f1fdc12 2005-10-29 devnull s = e2->b;
516 9f1fdc12 2005-10-29 devnull if(na){
517 9f1fdc12 2005-10-29 devnull t = emalloc(strlen(s)+1+na+1);
518 9f1fdc12 2005-10-29 devnull sprint(t, "%s %s", s, ea->b);
519 9f1fdc12 2005-10-29 devnull s = t;
520 9f1fdc12 2005-10-29 devnull }
521 9f1fdc12 2005-10-29 devnull /* if it's a long message, it can't be for us anyway */
522 9f1fdc12 2005-10-29 devnull if(!mboxcommand(w, s)) /* send it back */
523 9f1fdc12 2005-10-29 devnull winwriteevent(w, e);
524 9f1fdc12 2005-10-29 devnull if(na)
525 9f1fdc12 2005-10-29 devnull free(s);
526 9f1fdc12 2005-10-29 devnull break;
527 9f1fdc12 2005-10-29 devnull
528 9f1fdc12 2005-10-29 devnull case 'l':
529 9f1fdc12 2005-10-29 devnull case 'L':
530 9f1fdc12 2005-10-29 devnull buf = nil;
531 9f1fdc12 2005-10-29 devnull eq = e;
532 9f1fdc12 2005-10-29 devnull if(e->flag & 2){
533 9f1fdc12 2005-10-29 devnull e2 = recvp(w->cevent);
534 9f1fdc12 2005-10-29 devnull eq = e2;
535 9f1fdc12 2005-10-29 devnull }
536 9f1fdc12 2005-10-29 devnull s = eq->b;
537 9f1fdc12 2005-10-29 devnull if(eq->q1>eq->q0 && eq->nb==0){
538 9f1fdc12 2005-10-29 devnull buf = emalloc((eq->q1-eq->q0)*UTFmax+1);
539 9f1fdc12 2005-10-29 devnull winread(w, eq->q0, eq->q1, buf);
540 9f1fdc12 2005-10-29 devnull s = buf;
541 9f1fdc12 2005-10-29 devnull }
542 9f1fdc12 2005-10-29 devnull nopen = 0;
543 9f1fdc12 2005-10-29 devnull do{
544 9f1fdc12 2005-10-29 devnull /* skip 'deleted' string if present' */
545 9f1fdc12 2005-10-29 devnull if(strncmp(s, deleted, strlen(deleted)) == 0)
546 9f1fdc12 2005-10-29 devnull s += strlen(deleted);
547 9f1fdc12 2005-10-29 devnull /* skip mail box name if present */
548 9f1fdc12 2005-10-29 devnull if(strncmp(s, mbox.name, strlen(mbox.name)) == 0)
549 9f1fdc12 2005-10-29 devnull s += strlen(mbox.name);
550 9f1fdc12 2005-10-29 devnull nopen += mesgopen(&mbox, mbox.name, s, nil, 0, nil);
551 9f1fdc12 2005-10-29 devnull while(*s!='\0' && *s++!='\n')
552 9f1fdc12 2005-10-29 devnull ;
553 9f1fdc12 2005-10-29 devnull }while(*s);
554 9f1fdc12 2005-10-29 devnull if(nopen == 0) /* send it back */
555 9f1fdc12 2005-10-29 devnull winwriteevent(w, e);
556 9f1fdc12 2005-10-29 devnull free(buf);
557 9f1fdc12 2005-10-29 devnull break;
558 9f1fdc12 2005-10-29 devnull
559 9f1fdc12 2005-10-29 devnull case 'I': /* modify away; we don't care */
560 9f1fdc12 2005-10-29 devnull case 'D':
561 9f1fdc12 2005-10-29 devnull case 'd':
562 9f1fdc12 2005-10-29 devnull case 'i':
563 9f1fdc12 2005-10-29 devnull break;
564 9f1fdc12 2005-10-29 devnull
565 9f1fdc12 2005-10-29 devnull default:
566 9f1fdc12 2005-10-29 devnull goto Unknown;
567 9f1fdc12 2005-10-29 devnull }
568 9f1fdc12 2005-10-29 devnull }
569 9f1fdc12 2005-10-29 devnull }
570 9f1fdc12 2005-10-29 devnull }
571 9f1fdc12 2005-10-29 devnull