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"
11 605c0ea1 2006-02-08 devnull static CFid* showfd;
12 605c0ea1 2006-02-08 devnull static CFid* seefd;
14 b330c942 2005-10-31 devnull char **maildirs;
15 b330c942 2005-10-31 devnull int nmaildirs;
18 b330c942 2005-10-31 devnull initplumb(void)
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");
27 b330c942 2005-10-31 devnull addmaildir(char *dir)
29 b330c942 2005-10-31 devnull maildirs = erealloc(maildirs, (nmaildirs+1)*sizeof(char*));
30 b330c942 2005-10-31 devnull maildirs[nmaildirs++] = dir;
34 b330c942 2005-10-31 devnull attr(Face *f)
36 b330c942 2005-10-31 devnull static char buf[128];
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;
42 b330c942 2005-10-31 devnull return nil;
46 b330c942 2005-10-31 devnull showmail(Face *f)
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;
52 b330c942 2005-10-31 devnull if(showfd<0 || f->str[Sshow]==nil || f->str[Sshow][0]=='\0')
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);
69 b330c942 2005-10-31 devnull value(Plumbattr *attr, char *key, char *def)
73 b330c942 2005-10-31 devnull v = plumblookup(attr, key);
75 b330c942 2005-10-31 devnull return v;
76 b330c942 2005-10-31 devnull return def;
80 b330c942 2005-10-31 devnull setname(Face *f, char *sender)
82 b330c942 2005-10-31 devnull char *at, *bang;
84 2eef1fa3 2006-02-14 devnull char *fld[3];
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]);
92 2eef1fa3 2006-02-14 devnull sender = estrdup(fld[1]);
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, '@');
101 b330c942 2005-10-31 devnull *at++ = '\0';
102 b330c942 2005-10-31 devnull f->str[Sdomain] = estrdup(at);
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;
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"
120 b330c942 2005-10-31 devnull static int
121 b330c942 2005-10-31 devnull getmon(char *s)
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;
131 b330c942 2005-10-31 devnull /* Fri Jul 23 14:05:14 EDT 1999 */
133 b330c942 2005-10-31 devnull parsedatev(char **a)
135 b330c942 2005-10-31 devnull char *p;
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);
164 b330c942 2005-10-31 devnull return time(0);
168 b330c942 2005-10-31 devnull parsedate(char *s)
170 b330c942 2005-10-31 devnull char *f[10];
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);
181 b330c942 2005-10-31 devnull tweakdate(char *d)
183 b330c942 2005-10-31 devnull char e[8];
185 b330c942 2005-10-31 devnull /* d, date = "Mon Aug 2 23:46:55 EDT 1999" */
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 */
192 b330c942 2005-10-31 devnull snprint(e, sizeof e, "%.6s", d+4); /* Aug 2 */
193 b330c942 2005-10-31 devnull return estrdup(e);
197 b330c942 2005-10-31 devnull nextface(void)
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;
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;
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;
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;
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;
245 b330c942 2005-10-31 devnull return nil;
249 b330c942 2005-10-31 devnull iline(char *data, char **pp)
251 b330c942 2005-10-31 devnull char *p;
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++)
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;
264 b330c942 2005-10-31 devnull dirface(char *dir, char *num)
266 b330c942 2005-10-31 devnull Face *f;
267 2eef1fa3 2006-02-14 devnull char buf[1024], *info, *p, *t, *s;
269 b330c942 2005-10-31 devnull ulong len;
270 b330c942 2005-10-31 devnull CFid *fid;
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;
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);
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);
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;