Blame


1 b330c942 2005-10-31 devnull #include <u.h>
2 b330c942 2005-10-31 devnull #include <libc.h>
3 605c0ea1 2006-02-08 devnull #include <thread.h>
4 b330c942 2005-10-31 devnull #include <draw.h>
5 b330c942 2005-10-31 devnull #include <regexp.h>
6 b330c942 2005-10-31 devnull #include <bio.h>
7 b330c942 2005-10-31 devnull #include <9pclient.h>
8 605c0ea1 2006-02-08 devnull #include <plumb.h>
9 b330c942 2005-10-31 devnull #include "faces.h"
10 b330c942 2005-10-31 devnull
11 605c0ea1 2006-02-08 devnull static CFid* showfd;
12 605c0ea1 2006-02-08 devnull static CFid* seefd;
13 b330c942 2005-10-31 devnull
14 b330c942 2005-10-31 devnull char **maildirs;
15 b330c942 2005-10-31 devnull int nmaildirs;
16 b330c942 2005-10-31 devnull
17 b330c942 2005-10-31 devnull void
18 b330c942 2005-10-31 devnull initplumb(void)
19 b330c942 2005-10-31 devnull {
20 605c0ea1 2006-02-08 devnull showfd = plumbopenfid("send", OWRITE);
21 605c0ea1 2006-02-08 devnull seefd = plumbopenfid("seemail", OREAD);
22 605c0ea1 2006-02-08 devnull if(showfd == nil || seefd == nil)
23 605c0ea1 2006-02-08 devnull sysfatal("plumbopen: %r");
24 b330c942 2005-10-31 devnull }
25 b330c942 2005-10-31 devnull
26 b330c942 2005-10-31 devnull void
27 b330c942 2005-10-31 devnull addmaildir(char *dir)
28 b330c942 2005-10-31 devnull {
29 b330c942 2005-10-31 devnull maildirs = erealloc(maildirs, (nmaildirs+1)*sizeof(char*));
30 b330c942 2005-10-31 devnull maildirs[nmaildirs++] = dir;
31 b330c942 2005-10-31 devnull }
32 b330c942 2005-10-31 devnull
33 b330c942 2005-10-31 devnull char*
34 b330c942 2005-10-31 devnull attr(Face *f)
35 b330c942 2005-10-31 devnull {
36 b330c942 2005-10-31 devnull static char buf[128];
37 b330c942 2005-10-31 devnull
38 b330c942 2005-10-31 devnull if(f->str[Sdigest]){
39 b330c942 2005-10-31 devnull snprint(buf, sizeof buf, "digest=%s", f->str[Sdigest]);
40 b330c942 2005-10-31 devnull return buf;
41 b330c942 2005-10-31 devnull }
42 b330c942 2005-10-31 devnull return nil;
43 b330c942 2005-10-31 devnull }
44 b330c942 2005-10-31 devnull
45 b330c942 2005-10-31 devnull void
46 b330c942 2005-10-31 devnull showmail(Face *f)
47 b330c942 2005-10-31 devnull {
48 00d75e0e 2006-02-11 devnull char buf[256];
49 b330c942 2005-10-31 devnull Plumbmsg pm;
50 b330c942 2005-10-31 devnull Plumbattr a;
51 b330c942 2005-10-31 devnull
52 b330c942 2005-10-31 devnull if(showfd<0 || f->str[Sshow]==nil || f->str[Sshow][0]=='\0')
53 b330c942 2005-10-31 devnull return;
54 00d75e0e 2006-02-11 devnull snprint(buf, sizeof buf, "Mail/%s", f->str[Sshow]);
55 b330c942 2005-10-31 devnull pm.src = "faces";
56 b330c942 2005-10-31 devnull pm.dst = "showmail";
57 00d75e0e 2006-02-11 devnull pm.wdir = "/";
58 b330c942 2005-10-31 devnull pm.type = "text";
59 b330c942 2005-10-31 devnull a.name = "digest";
60 b330c942 2005-10-31 devnull a.value = f->str[Sdigest];
61 b330c942 2005-10-31 devnull a.next = nil;
62 b330c942 2005-10-31 devnull pm.attr = &a;
63 00d75e0e 2006-02-11 devnull pm.ndata = strlen(buf);
64 00d75e0e 2006-02-11 devnull pm.data = buf;
65 605c0ea1 2006-02-08 devnull plumbsendtofid(showfd, &pm);
66 b330c942 2005-10-31 devnull }
67 b330c942 2005-10-31 devnull
68 b330c942 2005-10-31 devnull char*
69 b330c942 2005-10-31 devnull value(Plumbattr *attr, char *key, char *def)
70 b330c942 2005-10-31 devnull {
71 b330c942 2005-10-31 devnull char *v;
72 b330c942 2005-10-31 devnull
73 b330c942 2005-10-31 devnull v = plumblookup(attr, key);
74 b330c942 2005-10-31 devnull if(v)
75 b330c942 2005-10-31 devnull return v;
76 b330c942 2005-10-31 devnull return def;
77 b330c942 2005-10-31 devnull }
78 b330c942 2005-10-31 devnull
79 b330c942 2005-10-31 devnull void
80 b330c942 2005-10-31 devnull setname(Face *f, char *sender)
81 b330c942 2005-10-31 devnull {
82 b330c942 2005-10-31 devnull char *at, *bang;
83 b330c942 2005-10-31 devnull char *p;
84 2eef1fa3 2006-02-14 devnull char *fld[3];
85 2eef1fa3 2006-02-14 devnull int nf;
86 b330c942 2005-10-31 devnull
87 2eef1fa3 2006-02-14 devnull p = estrdup(sender);
88 2eef1fa3 2006-02-14 devnull nf = tokenize(p, fld, 3);
89 2eef1fa3 2006-02-14 devnull if(nf <= 1)
90 2eef1fa3 2006-02-14 devnull sender = estrdup(fld[0]);
91 2eef1fa3 2006-02-14 devnull else
92 2eef1fa3 2006-02-14 devnull sender = estrdup(fld[1]);
93 2eef1fa3 2006-02-14 devnull free(p);
94 2eef1fa3 2006-02-14 devnull
95 b330c942 2005-10-31 devnull /* works with UTF-8, although it's written as ASCII */
96 b330c942 2005-10-31 devnull for(p=sender; *p!='\0'; p++)
97 b330c942 2005-10-31 devnull *p = tolower(*p);
98 b330c942 2005-10-31 devnull f->str[Suser] = sender;
99 b330c942 2005-10-31 devnull at = strchr(sender, '@');
100 b330c942 2005-10-31 devnull if(at){
101 b330c942 2005-10-31 devnull *at++ = '\0';
102 b330c942 2005-10-31 devnull f->str[Sdomain] = estrdup(at);
103 b330c942 2005-10-31 devnull return;
104 b330c942 2005-10-31 devnull }
105 b330c942 2005-10-31 devnull bang = strchr(sender, '!');
106 b330c942 2005-10-31 devnull if(bang){
107 b330c942 2005-10-31 devnull *bang++ = '\0';
108 b330c942 2005-10-31 devnull f->str[Suser] = estrdup(bang);
109 b330c942 2005-10-31 devnull f->str[Sdomain] = sender;
110 b330c942 2005-10-31 devnull return;
111 b330c942 2005-10-31 devnull }
112 b330c942 2005-10-31 devnull }
113 b330c942 2005-10-31 devnull
114 b330c942 2005-10-31 devnull static char* months[] = {
115 b330c942 2005-10-31 devnull "jan", "feb", "mar", "apr",
116 b330c942 2005-10-31 devnull "may", "jun", "jul", "aug",
117 b330c942 2005-10-31 devnull "sep", "oct", "nov", "dec"
118 b330c942 2005-10-31 devnull };
119 b330c942 2005-10-31 devnull
120 b330c942 2005-10-31 devnull static int
121 b330c942 2005-10-31 devnull getmon(char *s)
122 b330c942 2005-10-31 devnull {
123 b330c942 2005-10-31 devnull int i;
124 b330c942 2005-10-31 devnull
125 b330c942 2005-10-31 devnull for(i=0; i<nelem(months); i++)
126 b330c942 2005-10-31 devnull if(cistrcmp(months[i], s) == 0)
127 b330c942 2005-10-31 devnull return i;
128 b330c942 2005-10-31 devnull return -1;
129 b330c942 2005-10-31 devnull }
130 b330c942 2005-10-31 devnull
131 b330c942 2005-10-31 devnull /* Fri Jul 23 14:05:14 EDT 1999 */
132 b330c942 2005-10-31 devnull ulong
133 b330c942 2005-10-31 devnull parsedatev(char **a)
134 b330c942 2005-10-31 devnull {
135 b330c942 2005-10-31 devnull char *p;
136 b330c942 2005-10-31 devnull Tm tm;
137 b330c942 2005-10-31 devnull
138 b330c942 2005-10-31 devnull memset(&tm, 0, sizeof tm);
139 b330c942 2005-10-31 devnull if((tm.mon=getmon(a[1])) == -1)
140 b330c942 2005-10-31 devnull goto Err;
141 b330c942 2005-10-31 devnull tm.mday = strtol(a[2], &p, 10);
142 b330c942 2005-10-31 devnull if(*p != '\0')
143 b330c942 2005-10-31 devnull goto Err;
144 b330c942 2005-10-31 devnull tm.hour = strtol(a[3], &p, 10);
145 b330c942 2005-10-31 devnull if(*p != ':')
146 b330c942 2005-10-31 devnull goto Err;
147 b330c942 2005-10-31 devnull tm.min = strtol(p+1, &p, 10);
148 b330c942 2005-10-31 devnull if(*p != ':')
149 b330c942 2005-10-31 devnull goto Err;
150 b330c942 2005-10-31 devnull tm.sec = strtol(p+1, &p, 10);
151 b330c942 2005-10-31 devnull if(*p != '\0')
152 b330c942 2005-10-31 devnull goto Err;
153 b330c942 2005-10-31 devnull if(strlen(a[4]) != 3)
154 b330c942 2005-10-31 devnull goto Err;
155 b330c942 2005-10-31 devnull strcpy(tm.zone, a[4]);
156 b330c942 2005-10-31 devnull if(strlen(a[5]) != 4)
157 b330c942 2005-10-31 devnull goto Err;
158 b330c942 2005-10-31 devnull tm.year = strtol(a[5], &p, 10);
159 b330c942 2005-10-31 devnull if(*p != '\0')
160 b330c942 2005-10-31 devnull goto Err;
161 b330c942 2005-10-31 devnull tm.year -= 1900;
162 b330c942 2005-10-31 devnull return tm2sec(&tm);
163 b330c942 2005-10-31 devnull Err:
164 b330c942 2005-10-31 devnull return time(0);
165 b330c942 2005-10-31 devnull }
166 b330c942 2005-10-31 devnull
167 b330c942 2005-10-31 devnull ulong
168 b330c942 2005-10-31 devnull parsedate(char *s)
169 b330c942 2005-10-31 devnull {
170 b330c942 2005-10-31 devnull char *f[10];
171 b330c942 2005-10-31 devnull int nf;
172 b330c942 2005-10-31 devnull
173 b330c942 2005-10-31 devnull nf = getfields(s, f, nelem(f), 1, " ");
174 b330c942 2005-10-31 devnull if(nf < 6)
175 b330c942 2005-10-31 devnull return time(0);
176 b330c942 2005-10-31 devnull return parsedatev(f);
177 b330c942 2005-10-31 devnull }
178 b330c942 2005-10-31 devnull
179 b330c942 2005-10-31 devnull
180 b330c942 2005-10-31 devnull char*
181 b330c942 2005-10-31 devnull tweakdate(char *d)
182 b330c942 2005-10-31 devnull {
183 b330c942 2005-10-31 devnull char e[8];
184 b330c942 2005-10-31 devnull
185 b330c942 2005-10-31 devnull /* d, date = "Mon Aug 2 23:46:55 EDT 1999" */
186 b330c942 2005-10-31 devnull
187 b330c942 2005-10-31 devnull if(strlen(d) < strlen("Mon Aug 2 23:46:55 EDT 1999"))
188 b330c942 2005-10-31 devnull return estrdup("");
189 b330c942 2005-10-31 devnull if(strncmp(date, d, 4+4+3) == 0)
190 b330c942 2005-10-31 devnull snprint(e, sizeof e, "%.5s", d+4+4+3); /* 23:46 */
191 b330c942 2005-10-31 devnull else
192 b330c942 2005-10-31 devnull snprint(e, sizeof e, "%.6s", d+4); /* Aug 2 */
193 b330c942 2005-10-31 devnull return estrdup(e);
194 b330c942 2005-10-31 devnull }
195 b330c942 2005-10-31 devnull
196 b330c942 2005-10-31 devnull Face*
197 b330c942 2005-10-31 devnull nextface(void)
198 b330c942 2005-10-31 devnull {
199 b330c942 2005-10-31 devnull int i;
200 b330c942 2005-10-31 devnull Face *f;
201 b330c942 2005-10-31 devnull Plumbmsg *m;
202 2eef1fa3 2006-02-14 devnull char *t, *data, *showmailp, *digestp;
203 b330c942 2005-10-31 devnull ulong xtime;
204 b330c942 2005-10-31 devnull
205 b330c942 2005-10-31 devnull f = emalloc(sizeof(Face));
206 b330c942 2005-10-31 devnull for(;;){
207 605c0ea1 2006-02-08 devnull m = plumbrecvfid(seefd);
208 605c0ea1 2006-02-08 devnull if(m == nil)
209 605c0ea1 2006-02-08 devnull killall("error on seemail plumb port");
210 2eef1fa3 2006-02-14 devnull if(strncmp(m->data, "Mail/", 5) != 0){
211 2eef1fa3 2006-02-14 devnull plumbfree(m);
212 2eef1fa3 2006-02-14 devnull continue;
213 2eef1fa3 2006-02-14 devnull }
214 2eef1fa3 2006-02-14 devnull data = m->data+5;
215 605c0ea1 2006-02-08 devnull t = value(m->attr, "mailtype", "");
216 605c0ea1 2006-02-08 devnull if(strcmp(t, "delete") == 0)
217 2eef1fa3 2006-02-14 devnull delete(data, value(m->attr, "digest", nil));
218 605c0ea1 2006-02-08 devnull else if(strcmp(t, "new") != 0)
219 605c0ea1 2006-02-08 devnull fprint(2, "faces: unknown plumb message type %s\n", t);
220 00d75e0e 2006-02-11 devnull else for(i=0; i<nmaildirs; i++)
221 2eef1fa3 2006-02-14 devnull if(strncmp(data, maildirs[i], strlen(maildirs[i])) == 0)
222 605c0ea1 2006-02-08 devnull goto Found;
223 605c0ea1 2006-02-08 devnull plumbfree(m);
224 605c0ea1 2006-02-08 devnull continue;
225 b330c942 2005-10-31 devnull
226 605c0ea1 2006-02-08 devnull Found:
227 605c0ea1 2006-02-08 devnull xtime = parsedate(value(m->attr, "date", date));
228 605c0ea1 2006-02-08 devnull digestp = value(m->attr, "digest", nil);
229 605c0ea1 2006-02-08 devnull if(alreadyseen(digestp)){
230 605c0ea1 2006-02-08 devnull /* duplicate upas/fs can send duplicate messages */
231 b330c942 2005-10-31 devnull plumbfree(m);
232 605c0ea1 2006-02-08 devnull continue;
233 b330c942 2005-10-31 devnull }
234 2eef1fa3 2006-02-14 devnull showmailp = estrdup(data);
235 605c0ea1 2006-02-08 devnull if(digestp)
236 605c0ea1 2006-02-08 devnull digestp = estrdup(digestp);
237 2eef1fa3 2006-02-14 devnull setname(f, value(m->attr, "sender", "???"));
238 605c0ea1 2006-02-08 devnull plumbfree(m);
239 2eef1fa3 2006-02-14 devnull f->time = xtime;
240 2eef1fa3 2006-02-14 devnull f->tm = *localtime(xtime);
241 2eef1fa3 2006-02-14 devnull f->str[Sshow] = showmailp;
242 2eef1fa3 2006-02-14 devnull f->str[Sdigest] = digestp;
243 2eef1fa3 2006-02-14 devnull return f;
244 b330c942 2005-10-31 devnull }
245 b330c942 2005-10-31 devnull return nil;
246 b330c942 2005-10-31 devnull }
247 b330c942 2005-10-31 devnull
248 b330c942 2005-10-31 devnull char*
249 b330c942 2005-10-31 devnull iline(char *data, char **pp)
250 b330c942 2005-10-31 devnull {
251 b330c942 2005-10-31 devnull char *p;
252 b330c942 2005-10-31 devnull
253 605c0ea1 2006-02-08 devnull if(*data == 0)
254 605c0ea1 2006-02-08 devnull return nil;
255 b330c942 2005-10-31 devnull for(p=data; *p!='\0' && *p!='\n'; p++)
256 b330c942 2005-10-31 devnull ;
257 b330c942 2005-10-31 devnull if(*p == '\n')
258 b330c942 2005-10-31 devnull *p++ = '\0';
259 b330c942 2005-10-31 devnull *pp = p;
260 b330c942 2005-10-31 devnull return data;
261 b330c942 2005-10-31 devnull }
262 b330c942 2005-10-31 devnull
263 b330c942 2005-10-31 devnull Face*
264 b330c942 2005-10-31 devnull dirface(char *dir, char *num)
265 b330c942 2005-10-31 devnull {
266 b330c942 2005-10-31 devnull Face *f;
267 2eef1fa3 2006-02-14 devnull char buf[1024], *info, *p, *t, *s;
268 b330c942 2005-10-31 devnull int n;
269 b330c942 2005-10-31 devnull ulong len;
270 b330c942 2005-10-31 devnull CFid *fid;
271 b330c942 2005-10-31 devnull
272 b330c942 2005-10-31 devnull sprint(buf, "%s/%s/info", dir, num);
273 605c0ea1 2006-02-08 devnull len = fsdirlen(mailfs, buf);
274 b330c942 2005-10-31 devnull if(len <= 0)
275 b330c942 2005-10-31 devnull return nil;
276 605c0ea1 2006-02-08 devnull fid = fsopen(mailfs, buf, OREAD);
277 b330c942 2005-10-31 devnull if(fid == nil)
278 b330c942 2005-10-31 devnull return nil;
279 b330c942 2005-10-31 devnull info = emalloc(len+1);
280 b330c942 2005-10-31 devnull n = fsreadn(fid, info, len);
281 b330c942 2005-10-31 devnull fsclose(fid);
282 b330c942 2005-10-31 devnull if(n < 0){
283 b330c942 2005-10-31 devnull free(info);
284 b330c942 2005-10-31 devnull return nil;
285 b330c942 2005-10-31 devnull }
286 b330c942 2005-10-31 devnull info[n] = '\0';
287 b330c942 2005-10-31 devnull f = emalloc(sizeof(Face));
288 605c0ea1 2006-02-08 devnull for(p=info; (s=iline(p, &p)) != nil; ){
289 605c0ea1 2006-02-08 devnull t = strchr(s, ' ');
290 605c0ea1 2006-02-08 devnull if(t == nil)
291 605c0ea1 2006-02-08 devnull continue;
292 605c0ea1 2006-02-08 devnull *t++ = 0;
293 605c0ea1 2006-02-08 devnull if(strcmp(s, "unixdate") == 0){
294 605c0ea1 2006-02-08 devnull f->time = atoi(t);
295 605c0ea1 2006-02-08 devnull f->tm = *localtime(f->time);
296 605c0ea1 2006-02-08 devnull }
297 2eef1fa3 2006-02-14 devnull else if(strcmp(s, "from") == 0)
298 2eef1fa3 2006-02-14 devnull setname(f, t);
299 605c0ea1 2006-02-08 devnull else if(strcmp(s, "digest") == 0)
300 605c0ea1 2006-02-08 devnull f->str[Sdigest] = estrdup(t);
301 605c0ea1 2006-02-08 devnull }
302 b330c942 2005-10-31 devnull sprint(buf, "%s/%s", dir, num);
303 b330c942 2005-10-31 devnull f->str[Sshow] = estrdup(buf);
304 b330c942 2005-10-31 devnull free(info);
305 b330c942 2005-10-31 devnull return f;
306 b330c942 2005-10-31 devnull }