Blame


1 941e1713 2006-02-15 devnull #include "a.h"
2 941e1713 2006-02-15 devnull
3 941e1713 2006-02-15 devnull enum
4 941e1713 2006-02-15 devnull {
5 941e1713 2006-02-15 devnull BoxSubChunk = 16,
6 941e1713 2006-02-15 devnull BoxChunk = 64,
7 941e1713 2006-02-15 devnull MsgChunk = 256,
8 941e1713 2006-02-15 devnull PartChunk = 4,
9 cbeb0b26 2006-04-01 devnull PartSubChunk = 4
10 941e1713 2006-02-15 devnull };
11 941e1713 2006-02-15 devnull
12 941e1713 2006-02-15 devnull Box **boxes;
13 941e1713 2006-02-15 devnull uint nboxes;
14 941e1713 2006-02-15 devnull Box *rootbox;
15 941e1713 2006-02-15 devnull int boxid;
16 941e1713 2006-02-15 devnull
17 941e1713 2006-02-15 devnull Box*
18 941e1713 2006-02-15 devnull boxbyname(char *name)
19 941e1713 2006-02-15 devnull {
20 941e1713 2006-02-15 devnull int i;
21 941e1713 2006-02-15 devnull
22 941e1713 2006-02-15 devnull /* LATER: replace with hash table */
23 941e1713 2006-02-15 devnull for(i=0; i<nboxes; i++)
24 941e1713 2006-02-15 devnull if(boxes[i] && strcmp(boxes[i]->name, name) == 0)
25 941e1713 2006-02-15 devnull return boxes[i];
26 941e1713 2006-02-15 devnull return nil;
27 941e1713 2006-02-15 devnull }
28 941e1713 2006-02-15 devnull
29 941e1713 2006-02-15 devnull Box*
30 941e1713 2006-02-15 devnull subbox(Box *b, char *elem)
31 941e1713 2006-02-15 devnull {
32 941e1713 2006-02-15 devnull int i;
33 fa325e9b 2020-01-10 cross
34 941e1713 2006-02-15 devnull for(i=0; i<b->nsub; i++)
35 941e1713 2006-02-15 devnull if(b->sub[i] && strcmp(b->sub[i]->elem, elem) == 0)
36 941e1713 2006-02-15 devnull return b->sub[i];
37 941e1713 2006-02-15 devnull return nil;
38 941e1713 2006-02-15 devnull }
39 941e1713 2006-02-15 devnull
40 941e1713 2006-02-15 devnull Box*
41 941e1713 2006-02-15 devnull boxbyid(uint id)
42 941e1713 2006-02-15 devnull {
43 941e1713 2006-02-15 devnull int i;
44 fa325e9b 2020-01-10 cross
45 941e1713 2006-02-15 devnull /* LATER: replace with binary search */
46 941e1713 2006-02-15 devnull for(i=0; i<nboxes; i++)
47 941e1713 2006-02-15 devnull if(boxes[i] && boxes[i]->id == id)
48 941e1713 2006-02-15 devnull return boxes[i];
49 941e1713 2006-02-15 devnull return nil;
50 941e1713 2006-02-15 devnull }
51 941e1713 2006-02-15 devnull
52 941e1713 2006-02-15 devnull Box*
53 941e1713 2006-02-15 devnull boxcreate(char *name)
54 941e1713 2006-02-15 devnull {
55 941e1713 2006-02-15 devnull char *p;
56 941e1713 2006-02-15 devnull Box *b, *bb;
57 fa325e9b 2020-01-10 cross
58 941e1713 2006-02-15 devnull if((b = boxbyname(name)) != nil)
59 941e1713 2006-02-15 devnull return b;
60 fa325e9b 2020-01-10 cross
61 941e1713 2006-02-15 devnull b = emalloc(sizeof *b);
62 941e1713 2006-02-15 devnull b->id = ++boxid;
63 941e1713 2006-02-15 devnull b->time = time(0);
64 941e1713 2006-02-15 devnull b->name = estrdup(name);
65 941e1713 2006-02-15 devnull b->uidnext = 1;
66 941e1713 2006-02-15 devnull p = strrchr(b->name, '/');
67 941e1713 2006-02-15 devnull if(p){
68 941e1713 2006-02-15 devnull *p = 0;
69 941e1713 2006-02-15 devnull bb = boxcreate(b->name);
70 941e1713 2006-02-15 devnull *p = '/';
71 941e1713 2006-02-15 devnull b->elem = p+1;
72 941e1713 2006-02-15 devnull }else{
73 941e1713 2006-02-15 devnull bb = rootbox;
74 941e1713 2006-02-15 devnull b->elem = b->name;
75 941e1713 2006-02-15 devnull }
76 941e1713 2006-02-15 devnull if(nboxes%BoxChunk == 0)
77 941e1713 2006-02-15 devnull boxes = erealloc(boxes, (nboxes+BoxChunk)*sizeof boxes[0]);
78 941e1713 2006-02-15 devnull boxes[nboxes++] = b;
79 941e1713 2006-02-15 devnull if(bb->nsub%BoxSubChunk == 0)
80 941e1713 2006-02-15 devnull bb->sub = erealloc(bb->sub, (bb->nsub+BoxSubChunk)*sizeof bb->sub[0]);
81 941e1713 2006-02-15 devnull bb->sub[bb->nsub++] = b;
82 941e1713 2006-02-15 devnull b->parent = bb;
83 941e1713 2006-02-15 devnull return b;
84 941e1713 2006-02-15 devnull }
85 941e1713 2006-02-15 devnull
86 941e1713 2006-02-15 devnull void
87 941e1713 2006-02-15 devnull boxfree(Box *b)
88 941e1713 2006-02-15 devnull {
89 941e1713 2006-02-15 devnull int i;
90 fa325e9b 2020-01-10 cross
91 941e1713 2006-02-15 devnull if(b == nil)
92 941e1713 2006-02-15 devnull return;
93 941e1713 2006-02-15 devnull for(i=0; i<b->nmsg; i++)
94 941e1713 2006-02-15 devnull msgfree(b->msg[i]);
95 941e1713 2006-02-15 devnull free(b->msg);
96 941e1713 2006-02-15 devnull free(b);
97 941e1713 2006-02-15 devnull }
98 941e1713 2006-02-15 devnull
99 941e1713 2006-02-15 devnull Part*
100 941e1713 2006-02-15 devnull partcreate(Msg *m, Part *pp)
101 941e1713 2006-02-15 devnull {
102 941e1713 2006-02-15 devnull Part *p;
103 fa325e9b 2020-01-10 cross
104 941e1713 2006-02-15 devnull if(m->npart%PartChunk == 0)
105 941e1713 2006-02-15 devnull m->part = erealloc(m->part, (m->npart+PartChunk)*sizeof m->part[0]);
106 941e1713 2006-02-15 devnull p = emalloc(sizeof *p);
107 941e1713 2006-02-15 devnull p->msg = m;
108 fa325e9b 2020-01-10 cross p->ix = m->npart;
109 941e1713 2006-02-15 devnull m->part[m->npart++] = p;
110 941e1713 2006-02-15 devnull if(pp){
111 941e1713 2006-02-15 devnull if(pp->nsub%PartSubChunk == 0)
112 941e1713 2006-02-15 devnull pp->sub = erealloc(pp->sub, (pp->nsub+PartSubChunk)*sizeof pp->sub[0]);
113 941e1713 2006-02-15 devnull p->pix = pp->nsub;
114 941e1713 2006-02-15 devnull p->parent = pp;
115 941e1713 2006-02-15 devnull pp->sub[pp->nsub++] = p;
116 941e1713 2006-02-15 devnull }
117 941e1713 2006-02-15 devnull return p;
118 941e1713 2006-02-15 devnull }
119 941e1713 2006-02-15 devnull
120 941e1713 2006-02-15 devnull void
121 941e1713 2006-02-15 devnull partfree(Part *p)
122 941e1713 2006-02-15 devnull {
123 941e1713 2006-02-15 devnull int i;
124 fa325e9b 2020-01-10 cross
125 941e1713 2006-02-15 devnull if(p == nil)
126 941e1713 2006-02-15 devnull return;
127 941e1713 2006-02-15 devnull for(i=0; i<p->nsub; i++)
128 941e1713 2006-02-15 devnull partfree(p->sub[i]);
129 941e1713 2006-02-15 devnull free(p->sub);
130 941e1713 2006-02-15 devnull hdrfree(p->hdr);
131 941e1713 2006-02-15 devnull free(p->type);
132 941e1713 2006-02-15 devnull free(p->idstr);
133 941e1713 2006-02-15 devnull free(p->desc);
134 941e1713 2006-02-15 devnull free(p->encoding);
135 941e1713 2006-02-15 devnull free(p->charset);
136 941e1713 2006-02-15 devnull free(p->raw);
137 941e1713 2006-02-15 devnull free(p->rawheader);
138 941e1713 2006-02-15 devnull free(p->rawbody);
139 941e1713 2006-02-15 devnull free(p->mimeheader);
140 941e1713 2006-02-15 devnull free(p->body);
141 941e1713 2006-02-15 devnull free(p);
142 941e1713 2006-02-15 devnull }
143 941e1713 2006-02-15 devnull
144 941e1713 2006-02-15 devnull void
145 941e1713 2006-02-15 devnull msgfree(Msg *m)
146 941e1713 2006-02-15 devnull {
147 941e1713 2006-02-15 devnull int i;
148 fa325e9b 2020-01-10 cross
149 941e1713 2006-02-15 devnull if(m == nil)
150 941e1713 2006-02-15 devnull return;
151 941e1713 2006-02-15 devnull for(i=0; i<m->npart; i++)
152 941e1713 2006-02-15 devnull free(m->part[i]);
153 941e1713 2006-02-15 devnull free(m->part);
154 941e1713 2006-02-15 devnull free(m);
155 941e1713 2006-02-15 devnull }
156 941e1713 2006-02-15 devnull
157 941e1713 2006-02-15 devnull void
158 941e1713 2006-02-15 devnull msgplumb(Msg *m, int delete)
159 941e1713 2006-02-15 devnull {
160 941e1713 2006-02-15 devnull static int fd = -1;
161 941e1713 2006-02-15 devnull Plumbmsg p;
162 941e1713 2006-02-15 devnull Plumbattr a[10];
163 941e1713 2006-02-15 devnull char buf[256], date[40];
164 941e1713 2006-02-15 devnull int ai;
165 fa325e9b 2020-01-10 cross
166 941e1713 2006-02-15 devnull if(m == nil || m->npart < 1 || m->part[0]->hdr == nil)
167 941e1713 2006-02-15 devnull return;
168 941e1713 2006-02-15 devnull if(m->box && strcmp(m->box->name, "mbox") != 0)
169 941e1713 2006-02-15 devnull return;
170 941e1713 2006-02-15 devnull
171 941e1713 2006-02-15 devnull p.src = "mailfs";
172 941e1713 2006-02-15 devnull p.dst = "seemail";
173 941e1713 2006-02-15 devnull p.wdir = "/";
174 941e1713 2006-02-15 devnull p.type = "text";
175 941e1713 2006-02-15 devnull
176 941e1713 2006-02-15 devnull ai = 0;
177 941e1713 2006-02-15 devnull a[ai].name = "filetype";
178 941e1713 2006-02-15 devnull a[ai].value = "mail";
179 fa325e9b 2020-01-10 cross
180 941e1713 2006-02-15 devnull a[++ai].name = "mailtype";
181 941e1713 2006-02-15 devnull a[ai].value = delete?"delete":"new";
182 941e1713 2006-02-15 devnull a[ai-1].next = &a[ai];
183 941e1713 2006-02-15 devnull
184 941e1713 2006-02-15 devnull if(m->part[0]->hdr->from){
185 941e1713 2006-02-15 devnull a[++ai].name = "sender";
186 941e1713 2006-02-15 devnull a[ai].value = m->part[0]->hdr->from;
187 941e1713 2006-02-15 devnull a[ai-1].next = &a[ai];
188 941e1713 2006-02-15 devnull }
189 941e1713 2006-02-15 devnull
190 941e1713 2006-02-15 devnull if(m->part[0]->hdr->subject){
191 941e1713 2006-02-15 devnull a[++ai].name = "subject";
192 941e1713 2006-02-15 devnull a[ai].value = m->part[0]->hdr->subject;
193 941e1713 2006-02-15 devnull a[ai-1].next = &a[ai];
194 941e1713 2006-02-15 devnull }
195 941e1713 2006-02-15 devnull
196 941e1713 2006-02-15 devnull if(m->part[0]->hdr->digest){
197 941e1713 2006-02-15 devnull a[++ai].name = "digest";
198 941e1713 2006-02-15 devnull a[ai].value = m->part[0]->hdr->digest;
199 941e1713 2006-02-15 devnull a[ai-1].next = &a[ai];
200 941e1713 2006-02-15 devnull }
201 fa325e9b 2020-01-10 cross
202 941e1713 2006-02-15 devnull strcpy(date, ctime(m->date));
203 941e1713 2006-02-15 devnull date[strlen(date)-1] = 0; /* newline */
204 941e1713 2006-02-15 devnull a[++ai].name = "date";
205 941e1713 2006-02-15 devnull a[ai].value = date;
206 941e1713 2006-02-15 devnull a[ai-1].next = &a[ai];
207 fa325e9b 2020-01-10 cross
208 941e1713 2006-02-15 devnull a[ai].next = nil;
209 fa325e9b 2020-01-10 cross
210 941e1713 2006-02-15 devnull p.attr = a;
211 2fc68b6d 2011-11-22 rsc #ifdef PLAN9PORT
212 941e1713 2006-02-15 devnull snprint(buf, sizeof buf, "Mail/%s/%ud", m->box->name, m->id);
213 2fc68b6d 2011-11-22 rsc #else
214 2fc68b6d 2011-11-22 rsc snprint(buf, sizeof buf, "/mail/fs/%s/%ud", m->box->name, m->id);
215 2fc68b6d 2011-11-22 rsc #endif
216 941e1713 2006-02-15 devnull p.ndata = strlen(buf);
217 941e1713 2006-02-15 devnull p.data = buf;
218 fa325e9b 2020-01-10 cross
219 941e1713 2006-02-15 devnull if(fd < 0)
220 941e1713 2006-02-15 devnull fd = plumbopen("send", OWRITE);
221 941e1713 2006-02-15 devnull if(fd < 0)
222 941e1713 2006-02-15 devnull return;
223 941e1713 2006-02-15 devnull
224 941e1713 2006-02-15 devnull plumbsend(fd, &p);
225 941e1713 2006-02-15 devnull }
226 941e1713 2006-02-15 devnull
227 941e1713 2006-02-15 devnull
228 941e1713 2006-02-15 devnull Msg*
229 941e1713 2006-02-15 devnull msgcreate(Box *box)
230 941e1713 2006-02-15 devnull {
231 941e1713 2006-02-15 devnull Msg *m;
232 fa325e9b 2020-01-10 cross
233 941e1713 2006-02-15 devnull m = emalloc(sizeof *m);
234 941e1713 2006-02-15 devnull m->box = box;
235 941e1713 2006-02-15 devnull partcreate(m, nil);
236 941e1713 2006-02-15 devnull m->part[0]->type = estrdup("message/rfc822");
237 941e1713 2006-02-15 devnull if(box->nmsg%MsgChunk == 0)
238 941e1713 2006-02-15 devnull box->msg = erealloc(box->msg, (box->nmsg+MsgChunk)*sizeof box->msg[0]);
239 941e1713 2006-02-15 devnull m->ix = box->nmsg++;
240 941e1713 2006-02-15 devnull box->msg[m->ix] = m;
241 941e1713 2006-02-15 devnull m->id = ++box->msgid;
242 941e1713 2006-02-15 devnull return m;
243 941e1713 2006-02-15 devnull }
244 941e1713 2006-02-15 devnull
245 941e1713 2006-02-15 devnull Msg*
246 941e1713 2006-02-15 devnull msgbyimapuid(Box *box, uint uid, int docreate)
247 941e1713 2006-02-15 devnull {
248 941e1713 2006-02-15 devnull int i;
249 941e1713 2006-02-15 devnull Msg *msg;
250 941e1713 2006-02-15 devnull
251 941e1713 2006-02-15 devnull if(box == nil)
252 941e1713 2006-02-15 devnull return nil;
253 941e1713 2006-02-15 devnull /* LATER: binary search or something */
254 941e1713 2006-02-15 devnull for(i=0; i<box->nmsg; i++)
255 941e1713 2006-02-15 devnull if(box->msg[i]->imapuid == uid)
256 941e1713 2006-02-15 devnull return box->msg[i];
257 941e1713 2006-02-15 devnull if(!docreate)
258 941e1713 2006-02-15 devnull return nil;
259 941e1713 2006-02-15 devnull msg = msgcreate(box);
260 941e1713 2006-02-15 devnull msg->imapuid = uid;
261 941e1713 2006-02-15 devnull return msg;
262 941e1713 2006-02-15 devnull }
263 941e1713 2006-02-15 devnull
264 941e1713 2006-02-15 devnull Msg*
265 941e1713 2006-02-15 devnull msgbyid(Box *box, uint id)
266 941e1713 2006-02-15 devnull {
267 941e1713 2006-02-15 devnull int i;
268 941e1713 2006-02-15 devnull
269 941e1713 2006-02-15 devnull if(box == nil)
270 941e1713 2006-02-15 devnull return nil;
271 941e1713 2006-02-15 devnull /* LATER: binary search or something */
272 941e1713 2006-02-15 devnull for(i=0; i<box->nmsg; i++)
273 941e1713 2006-02-15 devnull if(box->msg[i]->id == id)
274 941e1713 2006-02-15 devnull return box->msg[i];
275 941e1713 2006-02-15 devnull return nil;
276 941e1713 2006-02-15 devnull }
277 941e1713 2006-02-15 devnull
278 941e1713 2006-02-15 devnull Part*
279 941e1713 2006-02-15 devnull partbyid(Msg *m, uint id)
280 941e1713 2006-02-15 devnull {
281 941e1713 2006-02-15 devnull if(m == nil)
282 941e1713 2006-02-15 devnull return nil;
283 941e1713 2006-02-15 devnull if(id >= m->npart)
284 941e1713 2006-02-15 devnull return nil;
285 941e1713 2006-02-15 devnull return m->part[id];
286 941e1713 2006-02-15 devnull }
287 941e1713 2006-02-15 devnull
288 941e1713 2006-02-15 devnull Part*
289 941e1713 2006-02-15 devnull subpart(Part *p, uint a)
290 941e1713 2006-02-15 devnull {
291 941e1713 2006-02-15 devnull if(p == nil || a >= p->nsub)
292 941e1713 2006-02-15 devnull return nil;
293 941e1713 2006-02-15 devnull return p->sub[a];
294 941e1713 2006-02-15 devnull }
295 941e1713 2006-02-15 devnull
296 941e1713 2006-02-15 devnull void
297 941e1713 2006-02-15 devnull hdrfree(Hdr *h)
298 941e1713 2006-02-15 devnull {
299 941e1713 2006-02-15 devnull if(h == nil)
300 941e1713 2006-02-15 devnull return;
301 941e1713 2006-02-15 devnull free(h->date);
302 941e1713 2006-02-15 devnull free(h->subject);
303 941e1713 2006-02-15 devnull free(h->from);
304 941e1713 2006-02-15 devnull free(h->sender);
305 941e1713 2006-02-15 devnull free(h->replyto);
306 941e1713 2006-02-15 devnull free(h->to);
307 941e1713 2006-02-15 devnull free(h->cc);
308 941e1713 2006-02-15 devnull free(h->bcc);
309 941e1713 2006-02-15 devnull free(h->inreplyto);
310 941e1713 2006-02-15 devnull free(h->messageid);
311 941e1713 2006-02-15 devnull free(h->digest);
312 941e1713 2006-02-15 devnull free(h);
313 941e1713 2006-02-15 devnull }
314 941e1713 2006-02-15 devnull
315 941e1713 2006-02-15 devnull void
316 941e1713 2006-02-15 devnull boxinit(void)
317 941e1713 2006-02-15 devnull {
318 941e1713 2006-02-15 devnull rootbox = emalloc(sizeof *rootbox);
319 941e1713 2006-02-15 devnull rootbox->name = estrdup("");
320 941e1713 2006-02-15 devnull rootbox->time = time(0);
321 941e1713 2006-02-15 devnull }