Blame


1 941e1713 2006-02-15 devnull /*
2 941e1713 2006-02-15 devnull * Mail file system.
3 fa325e9b 2020-01-10 cross *
4 941e1713 2006-02-15 devnull * Serve the bulk of requests out of memory, so they can
5 fa325e9b 2020-01-10 cross * be in the main loop (will never see their flushes).
6 941e1713 2006-02-15 devnull * Some requests do block and they get handled in
7 941e1713 2006-02-15 devnull * separate threads. They're all okay to give up on
8 941e1713 2006-02-15 devnull * early, though, so we just respond saying interrupted
9 941e1713 2006-02-15 devnull * and then when they finish, silently discard the request.
10 941e1713 2006-02-15 devnull
11 941e1713 2006-02-15 devnull TO DO:
12 941e1713 2006-02-15 devnull
13 941e1713 2006-02-15 devnull decode subject, etc.
14 941e1713 2006-02-15 devnull decode body
15 941e1713 2006-02-15 devnull
16 941e1713 2006-02-15 devnull digest
17 941e1713 2006-02-15 devnull disposition
18 941e1713 2006-02-15 devnull filename
19 fa325e9b 2020-01-10 cross
20 941e1713 2006-02-15 devnull ctl messages
21 941e1713 2006-02-15 devnull
22 941e1713 2006-02-15 devnull fetch mail on demand
23 941e1713 2006-02-15 devnull
24 941e1713 2006-02-15 devnull */
25 941e1713 2006-02-15 devnull
26 941e1713 2006-02-15 devnull #include "a.h"
27 941e1713 2006-02-15 devnull
28 941e1713 2006-02-15 devnull enum
29 941e1713 2006-02-15 devnull {
30 941e1713 2006-02-15 devnull /* directories */
31 941e1713 2006-02-15 devnull Qroot,
32 941e1713 2006-02-15 devnull Qbox,
33 941e1713 2006-02-15 devnull Qmsg,
34 941e1713 2006-02-15 devnull
35 941e1713 2006-02-15 devnull /* control files */
36 941e1713 2006-02-15 devnull Qctl,
37 941e1713 2006-02-15 devnull Qboxctl,
38 941e1713 2006-02-15 devnull Qsearch,
39 941e1713 2006-02-15 devnull
40 941e1713 2006-02-15 devnull /* message header - same order as struct Hdr */
41 941e1713 2006-02-15 devnull Qdate,
42 941e1713 2006-02-15 devnull Qsubject,
43 941e1713 2006-02-15 devnull Qfrom,
44 941e1713 2006-02-15 devnull Qsender,
45 941e1713 2006-02-15 devnull Qreplyto,
46 941e1713 2006-02-15 devnull Qto,
47 941e1713 2006-02-15 devnull Qcc,
48 941e1713 2006-02-15 devnull Qbcc,
49 941e1713 2006-02-15 devnull Qinreplyto,
50 941e1713 2006-02-15 devnull Qmessageid,
51 fa325e9b 2020-01-10 cross
52 941e1713 2006-02-15 devnull /* part data - same order as stuct Part */
53 941e1713 2006-02-15 devnull Qtype,
54 941e1713 2006-02-15 devnull Qidstr,
55 941e1713 2006-02-15 devnull Qdesc,
56 941e1713 2006-02-15 devnull Qencoding, /* only here temporarily! */
57 941e1713 2006-02-15 devnull Qcharset,
58 bb70a84b 2007-06-23 devnull Qfilename,
59 941e1713 2006-02-15 devnull Qraw,
60 941e1713 2006-02-15 devnull Qrawheader,
61 941e1713 2006-02-15 devnull Qrawbody,
62 941e1713 2006-02-15 devnull Qmimeheader,
63 fa325e9b 2020-01-10 cross
64 941e1713 2006-02-15 devnull /* part numbers - same order as struct Part */
65 941e1713 2006-02-15 devnull Qsize,
66 941e1713 2006-02-15 devnull Qlines,
67 941e1713 2006-02-15 devnull
68 941e1713 2006-02-15 devnull /* other message files */
69 941e1713 2006-02-15 devnull Qbody,
70 941e1713 2006-02-15 devnull Qheader,
71 941e1713 2006-02-15 devnull Qdigest,
72 941e1713 2006-02-15 devnull Qdisposition,
73 941e1713 2006-02-15 devnull Qflags,
74 941e1713 2006-02-15 devnull Qinfo,
75 941e1713 2006-02-15 devnull Qrawunix,
76 941e1713 2006-02-15 devnull Qunixdate,
77 941e1713 2006-02-15 devnull Qunixheader,
78 fa325e9b 2020-01-10 cross
79 941e1713 2006-02-15 devnull Qfile0 = Qbody,
80 cbeb0b26 2006-04-01 devnull Qnfile = Qunixheader+1-Qfile0
81 941e1713 2006-02-15 devnull };
82 941e1713 2006-02-15 devnull
83 941e1713 2006-02-15 devnull static char Egreg[] = "gone postal";
84 941e1713 2006-02-15 devnull static char Enobox[] = "no such mailbox";
85 941e1713 2006-02-15 devnull static char Enomsg[] = "no such message";
86 941e1713 2006-02-15 devnull static char Eboxgone[] = "mailbox not available";
87 941e1713 2006-02-15 devnull static char Emsggone[] = "message not available";
88 941e1713 2006-02-15 devnull static char Eperm[] = "permission denied";
89 941e1713 2006-02-15 devnull static char Ebadctl[] = "bad control message";
90 941e1713 2006-02-15 devnull
91 941e1713 2006-02-15 devnull Channel *fsreqchan;
92 941e1713 2006-02-15 devnull Srv fs;
93 941e1713 2006-02-15 devnull Qid rootqid;
94 941e1713 2006-02-15 devnull ulong t0;
95 941e1713 2006-02-15 devnull
96 2fc68b6d 2011-11-22 rsc #ifdef PLAN9PORT
97 941e1713 2006-02-15 devnull void
98 941e1713 2006-02-15 devnull responderror(Req *r)
99 941e1713 2006-02-15 devnull {
100 941e1713 2006-02-15 devnull char e[ERRMAX];
101 fa325e9b 2020-01-10 cross
102 941e1713 2006-02-15 devnull rerrstr(e, sizeof e);
103 941e1713 2006-02-15 devnull respond(r, e);
104 941e1713 2006-02-15 devnull }
105 2fc68b6d 2011-11-22 rsc #endif
106 941e1713 2006-02-15 devnull
107 941e1713 2006-02-15 devnull int
108 941e1713 2006-02-15 devnull qtype(Qid q)
109 941e1713 2006-02-15 devnull {
110 941e1713 2006-02-15 devnull return q.path&0x3F;
111 941e1713 2006-02-15 devnull }
112 941e1713 2006-02-15 devnull
113 941e1713 2006-02-15 devnull int
114 941e1713 2006-02-15 devnull qboxid(Qid q)
115 941e1713 2006-02-15 devnull {
116 941e1713 2006-02-15 devnull return (q.path>>40)&0xFFFF;
117 941e1713 2006-02-15 devnull }
118 941e1713 2006-02-15 devnull
119 941e1713 2006-02-15 devnull int
120 941e1713 2006-02-15 devnull qmsgid(Qid q)
121 941e1713 2006-02-15 devnull {
122 941e1713 2006-02-15 devnull return ((q.path>>32)&0xFF000000) | ((q.path>>16)&0xFFFFFF);
123 941e1713 2006-02-15 devnull }
124 941e1713 2006-02-15 devnull
125 941e1713 2006-02-15 devnull int
126 941e1713 2006-02-15 devnull qpartid(Qid q)
127 941e1713 2006-02-15 devnull {
128 941e1713 2006-02-15 devnull return ((q.path>>6)&0x3FF);
129 941e1713 2006-02-15 devnull }
130 941e1713 2006-02-15 devnull
131 941e1713 2006-02-15 devnull Qid
132 941e1713 2006-02-15 devnull qid(int ctl, Box *box, Msg *msg, Part *part)
133 941e1713 2006-02-15 devnull {
134 941e1713 2006-02-15 devnull Qid q;
135 fa325e9b 2020-01-10 cross
136 941e1713 2006-02-15 devnull q.type = 0;
137 941e1713 2006-02-15 devnull if(ctl == Qroot || ctl == Qbox || ctl == Qmsg)
138 941e1713 2006-02-15 devnull q.type = QTDIR;
139 941e1713 2006-02-15 devnull q.path = (vlong)((msg ? msg->id : 0)&0xFF000000)<<32;
140 941e1713 2006-02-15 devnull q.path |= (vlong)((msg ? msg->id : 0)&0xFFFFFF)<<16;
141 941e1713 2006-02-15 devnull q.path |= (vlong)((box ? box->id : 0)&0xFFFF)<<40;
142 941e1713 2006-02-15 devnull q.path |= ((part ? part->ix : 0)&0x3FF)<<6;
143 941e1713 2006-02-15 devnull q.path |= ctl&0x3F;
144 941e1713 2006-02-15 devnull q.vers = box ? box->validity : 0;
145 941e1713 2006-02-15 devnull return q;
146 941e1713 2006-02-15 devnull }
147 941e1713 2006-02-15 devnull
148 941e1713 2006-02-15 devnull int
149 941e1713 2006-02-15 devnull parseqid(Qid q, Box **box, Msg **msg, Part **part)
150 941e1713 2006-02-15 devnull {
151 941e1713 2006-02-15 devnull *msg = nil;
152 941e1713 2006-02-15 devnull *part = nil;
153 fa325e9b 2020-01-10 cross
154 941e1713 2006-02-15 devnull *box = boxbyid(qboxid(q));
155 941e1713 2006-02-15 devnull if(*box){
156 941e1713 2006-02-15 devnull *msg = msgbyid(*box, qmsgid(q));
157 941e1713 2006-02-15 devnull }
158 941e1713 2006-02-15 devnull if(*msg)
159 941e1713 2006-02-15 devnull *part = partbyid(*msg, qpartid(q));
160 941e1713 2006-02-15 devnull return qtype(q);
161 941e1713 2006-02-15 devnull }
162 941e1713 2006-02-15 devnull
163 941e1713 2006-02-15 devnull static struct {
164 941e1713 2006-02-15 devnull int type;
165 941e1713 2006-02-15 devnull char *name;
166 941e1713 2006-02-15 devnull } typenames[] = {
167 941e1713 2006-02-15 devnull Qbody, "body",
168 941e1713 2006-02-15 devnull Qbcc, "bcc",
169 941e1713 2006-02-15 devnull Qcc, "cc",
170 941e1713 2006-02-15 devnull Qdate, "date",
171 941e1713 2006-02-15 devnull Qfilename, "filename",
172 941e1713 2006-02-15 devnull Qflags, "flags",
173 941e1713 2006-02-15 devnull Qfrom, "from",
174 941e1713 2006-02-15 devnull Qheader, "header",
175 941e1713 2006-02-15 devnull Qinfo, "info",
176 941e1713 2006-02-15 devnull Qinreplyto, "inreplyto",
177 941e1713 2006-02-15 devnull Qlines, "lines",
178 941e1713 2006-02-15 devnull Qmimeheader, "mimeheader",
179 941e1713 2006-02-15 devnull Qmessageid, "messageid",
180 941e1713 2006-02-15 devnull Qraw, "raw",
181 941e1713 2006-02-15 devnull Qrawunix, "rawunix",
182 941e1713 2006-02-15 devnull Qrawbody, "rawbody",
183 941e1713 2006-02-15 devnull Qrawheader, "rawheader",
184 941e1713 2006-02-15 devnull Qreplyto, "replyto",
185 941e1713 2006-02-15 devnull Qsender, "sender",
186 941e1713 2006-02-15 devnull Qsubject, "subject",
187 941e1713 2006-02-15 devnull Qto, "to",
188 941e1713 2006-02-15 devnull Qtype, "type",
189 941e1713 2006-02-15 devnull Qunixdate, "unixdate",
190 941e1713 2006-02-15 devnull Qunixheader, "unixheader",
191 941e1713 2006-02-15 devnull Qidstr, "idstr",
192 941e1713 2006-02-15 devnull Qdesc, "desc",
193 941e1713 2006-02-15 devnull Qencoding, "encoding",
194 cbeb0b26 2006-04-01 devnull Qcharset, "charset"
195 941e1713 2006-02-15 devnull };
196 941e1713 2006-02-15 devnull
197 941e1713 2006-02-15 devnull char*
198 941e1713 2006-02-15 devnull nameoftype(int t)
199 941e1713 2006-02-15 devnull {
200 941e1713 2006-02-15 devnull int i;
201 fa325e9b 2020-01-10 cross
202 941e1713 2006-02-15 devnull for(i=0; i<nelem(typenames); i++)
203 941e1713 2006-02-15 devnull if(typenames[i].type == t)
204 941e1713 2006-02-15 devnull return typenames[i].name;
205 941e1713 2006-02-15 devnull return "???";
206 941e1713 2006-02-15 devnull }
207 941e1713 2006-02-15 devnull
208 941e1713 2006-02-15 devnull int
209 941e1713 2006-02-15 devnull typeofname(char *name)
210 941e1713 2006-02-15 devnull {
211 941e1713 2006-02-15 devnull int i;
212 fa325e9b 2020-01-10 cross
213 941e1713 2006-02-15 devnull for(i=0; i<nelem(typenames); i++)
214 941e1713 2006-02-15 devnull if(strcmp(typenames[i].name, name) == 0)
215 941e1713 2006-02-15 devnull return typenames[i].type;
216 941e1713 2006-02-15 devnull return 0;
217 941e1713 2006-02-15 devnull }
218 941e1713 2006-02-15 devnull
219 941e1713 2006-02-15 devnull static void
220 941e1713 2006-02-15 devnull fsattach(Req *r)
221 941e1713 2006-02-15 devnull {
222 941e1713 2006-02-15 devnull r->fid->qid = rootqid;
223 941e1713 2006-02-15 devnull r->ofcall.qid = rootqid;
224 941e1713 2006-02-15 devnull respond(r, nil);
225 941e1713 2006-02-15 devnull }
226 941e1713 2006-02-15 devnull
227 c7722328 2006-02-28 devnull static int
228 941e1713 2006-02-15 devnull isnumber(char *s)
229 941e1713 2006-02-15 devnull {
230 941e1713 2006-02-15 devnull int n;
231 941e1713 2006-02-15 devnull
232 941e1713 2006-02-15 devnull if(*s < '1' || *s > '9')
233 941e1713 2006-02-15 devnull return 0;
234 941e1713 2006-02-15 devnull n = strtol(s, &s, 10);
235 941e1713 2006-02-15 devnull if(*s != 0)
236 941e1713 2006-02-15 devnull return 0;
237 941e1713 2006-02-15 devnull return n;
238 941e1713 2006-02-15 devnull }
239 941e1713 2006-02-15 devnull
240 941e1713 2006-02-15 devnull static char*
241 941e1713 2006-02-15 devnull fswalk1(Fid *fid, char *name, void *arg)
242 941e1713 2006-02-15 devnull {
243 941e1713 2006-02-15 devnull int a, type;
244 941e1713 2006-02-15 devnull Box *b, *box;
245 941e1713 2006-02-15 devnull Msg *msg;
246 941e1713 2006-02-15 devnull Part *p, *part;
247 941e1713 2006-02-15 devnull
248 941e1713 2006-02-15 devnull USED(arg);
249 fa325e9b 2020-01-10 cross
250 941e1713 2006-02-15 devnull switch(type = parseqid(fid->qid, &box, &msg, &part)){
251 941e1713 2006-02-15 devnull case Qroot:
252 941e1713 2006-02-15 devnull if(strcmp(name, "..") == 0)
253 941e1713 2006-02-15 devnull return nil;
254 941e1713 2006-02-15 devnull if(strcmp(name, "ctl") == 0){
255 941e1713 2006-02-15 devnull fid->qid = qid(Qctl, nil, nil, nil);
256 941e1713 2006-02-15 devnull return nil;
257 941e1713 2006-02-15 devnull }
258 941e1713 2006-02-15 devnull if((box = boxbyname(name)) != nil){
259 941e1713 2006-02-15 devnull fid->qid = qid(Qbox, box, nil, nil);
260 941e1713 2006-02-15 devnull return nil;
261 941e1713 2006-02-15 devnull }
262 941e1713 2006-02-15 devnull break;
263 941e1713 2006-02-15 devnull
264 941e1713 2006-02-15 devnull case Qbox:
265 941e1713 2006-02-15 devnull /*
266 941e1713 2006-02-15 devnull * Would be nice if .. could work even if the box is gone,
267 941e1713 2006-02-15 devnull * but we don't know how deep the directory was.
268 941e1713 2006-02-15 devnull */
269 941e1713 2006-02-15 devnull if(box == nil)
270 941e1713 2006-02-15 devnull return Eboxgone;
271 941e1713 2006-02-15 devnull if(strcmp(name, "..") == 0){
272 941e1713 2006-02-15 devnull if((box = box->parent) == nil){
273 941e1713 2006-02-15 devnull fid->qid = rootqid;
274 941e1713 2006-02-15 devnull return nil;
275 941e1713 2006-02-15 devnull }
276 941e1713 2006-02-15 devnull fid->qid = qid(Qbox, box, nil, nil);
277 941e1713 2006-02-15 devnull return nil;
278 941e1713 2006-02-15 devnull }
279 941e1713 2006-02-15 devnull if(strcmp(name, "ctl") == 0){
280 941e1713 2006-02-15 devnull fid->qid = qid(Qboxctl, box, nil, nil);
281 941e1713 2006-02-15 devnull return nil;
282 941e1713 2006-02-15 devnull }
283 941e1713 2006-02-15 devnull if(strcmp(name, "search") == 0){
284 941e1713 2006-02-15 devnull fid->qid = qid(Qsearch, box, nil, nil);
285 941e1713 2006-02-15 devnull return nil;
286 941e1713 2006-02-15 devnull }
287 941e1713 2006-02-15 devnull if((b = subbox(box, name)) != nil){
288 941e1713 2006-02-15 devnull fid->qid = qid(Qbox, b, nil, nil);
289 941e1713 2006-02-15 devnull return nil;
290 941e1713 2006-02-15 devnull }
291 941e1713 2006-02-15 devnull if((a = isnumber(name)) != 0){
292 941e1713 2006-02-15 devnull if((msg = msgbyid(box, a)) == nil){
293 941e1713 2006-02-15 devnull return Enomsg;
294 941e1713 2006-02-15 devnull }
295 941e1713 2006-02-15 devnull fid->qid = qid(Qmsg, box, msg, nil);
296 941e1713 2006-02-15 devnull return nil;
297 941e1713 2006-02-15 devnull }
298 941e1713 2006-02-15 devnull break;
299 941e1713 2006-02-15 devnull
300 941e1713 2006-02-15 devnull case Qmsg:
301 941e1713 2006-02-15 devnull if(strcmp(name, "..") == 0){
302 941e1713 2006-02-15 devnull if(part == msg->part[0]){
303 941e1713 2006-02-15 devnull fid->qid = qid(Qbox, box, nil, nil);
304 941e1713 2006-02-15 devnull return nil;
305 941e1713 2006-02-15 devnull }
306 941e1713 2006-02-15 devnull fid->qid = qid(Qmsg, box, msg, part->parent);
307 941e1713 2006-02-15 devnull return nil;
308 941e1713 2006-02-15 devnull }
309 941e1713 2006-02-15 devnull if((type = typeofname(name)) > 0){
310 941e1713 2006-02-15 devnull /* XXX - should check that type makes sense (see msggen) */
311 941e1713 2006-02-15 devnull fid->qid = qid(type, box, msg, part);
312 941e1713 2006-02-15 devnull return nil;
313 941e1713 2006-02-15 devnull }
314 941e1713 2006-02-15 devnull if((a = isnumber(name)) != 0){
315 941e1713 2006-02-15 devnull if((p = subpart(part, a-1)) != nil){
316 941e1713 2006-02-15 devnull fid->qid = qid(Qmsg, box, msg, p);
317 941e1713 2006-02-15 devnull return nil;
318 941e1713 2006-02-15 devnull }
319 941e1713 2006-02-15 devnull }
320 941e1713 2006-02-15 devnull break;
321 941e1713 2006-02-15 devnull }
322 941e1713 2006-02-15 devnull return "not found";
323 941e1713 2006-02-15 devnull }
324 941e1713 2006-02-15 devnull
325 941e1713 2006-02-15 devnull static void
326 941e1713 2006-02-15 devnull fswalk(Req *r)
327 941e1713 2006-02-15 devnull {
328 941e1713 2006-02-15 devnull walkandclone(r, fswalk1, nil, nil);
329 941e1713 2006-02-15 devnull }
330 941e1713 2006-02-15 devnull
331 941e1713 2006-02-15 devnull static struct {
332 941e1713 2006-02-15 devnull int flag;
333 941e1713 2006-02-15 devnull char *name;
334 941e1713 2006-02-15 devnull } flagtab[] = {
335 941e1713 2006-02-15 devnull FlagJunk, "junk",
336 941e1713 2006-02-15 devnull FlagNonJunk, "notjunk",
337 941e1713 2006-02-15 devnull FlagReplied, "replied",
338 941e1713 2006-02-15 devnull FlagFlagged, "flagged",
339 cbeb0b26 2006-04-01 devnull /* FlagDeleted, "deleted", */
340 941e1713 2006-02-15 devnull FlagDraft, "draft",
341 cbeb0b26 2006-04-01 devnull FlagSeen, "seen"
342 941e1713 2006-02-15 devnull };
343 941e1713 2006-02-15 devnull
344 941e1713 2006-02-15 devnull static void
345 941e1713 2006-02-15 devnull addaddrs(Fmt *fmt, char *prefix, char *addrs)
346 941e1713 2006-02-15 devnull {
347 941e1713 2006-02-15 devnull char **f;
348 941e1713 2006-02-15 devnull int i, nf, inquote;
349 941e1713 2006-02-15 devnull char *p, *sep;
350 fa325e9b 2020-01-10 cross
351 941e1713 2006-02-15 devnull if(addrs == nil)
352 941e1713 2006-02-15 devnull return;
353 941e1713 2006-02-15 devnull addrs = estrdup(addrs);
354 941e1713 2006-02-15 devnull nf = 0;
355 941e1713 2006-02-15 devnull inquote = 0;
356 941e1713 2006-02-15 devnull for(p=addrs; *p; p++){
357 941e1713 2006-02-15 devnull if(*p == ' ' && !inquote)
358 941e1713 2006-02-15 devnull nf++;
359 941e1713 2006-02-15 devnull if(*p == '\'')
360 941e1713 2006-02-15 devnull inquote = !inquote;
361 941e1713 2006-02-15 devnull }
362 941e1713 2006-02-15 devnull nf += 10;
363 941e1713 2006-02-15 devnull f = emalloc(nf*sizeof f[0]);
364 941e1713 2006-02-15 devnull nf = tokenize(addrs, f, nf);
365 941e1713 2006-02-15 devnull fmtprint(fmt, "%s:", prefix);
366 941e1713 2006-02-15 devnull sep = " ";
367 941e1713 2006-02-15 devnull for(i=0; i+1<nf; i+=2){
368 941e1713 2006-02-15 devnull if(f[i][0])
369 941e1713 2006-02-15 devnull fmtprint(fmt, "%s%s <%s>", sep, f[i], f[i+1]);
370 941e1713 2006-02-15 devnull else
371 941e1713 2006-02-15 devnull fmtprint(fmt, "%s%s", sep, f[i+1]);
372 941e1713 2006-02-15 devnull sep = ", ";
373 941e1713 2006-02-15 devnull }
374 941e1713 2006-02-15 devnull fmtprint(fmt, "\n");
375 941e1713 2006-02-15 devnull free(addrs);
376 941e1713 2006-02-15 devnull }
377 941e1713 2006-02-15 devnull
378 941e1713 2006-02-15 devnull static void
379 941e1713 2006-02-15 devnull mkbody(Part *p, Qid q)
380 941e1713 2006-02-15 devnull {
381 941e1713 2006-02-15 devnull char *t;
382 941e1713 2006-02-15 devnull int len;
383 2fc68b6d 2011-11-22 rsc
384 2fc68b6d 2011-11-22 rsc USED(q);
385 941e1713 2006-02-15 devnull if(p->msg->part[0] == p)
386 941e1713 2006-02-15 devnull t = p->rawbody;
387 941e1713 2006-02-15 devnull else
388 941e1713 2006-02-15 devnull t = p->raw;
389 941e1713 2006-02-15 devnull if(t == nil)
390 941e1713 2006-02-15 devnull return;
391 941e1713 2006-02-15 devnull
392 941e1713 2006-02-15 devnull len = -1;
393 941e1713 2006-02-15 devnull if(p->encoding && cistrcmp(p->encoding, "quoted-printable") == 0)
394 941e1713 2006-02-15 devnull t = decode(QuotedPrintable, t, &len);
395 941e1713 2006-02-15 devnull else if(p->encoding && cistrcmp(p->encoding, "base64") == 0)
396 941e1713 2006-02-15 devnull t = decode(Base64, t, &len);
397 941e1713 2006-02-15 devnull else
398 941e1713 2006-02-15 devnull t = estrdup(t);
399 941e1713 2006-02-15 devnull
400 941e1713 2006-02-15 devnull if(p->charset){
401 941e1713 2006-02-15 devnull t = tcs(p->charset, t);
402 941e1713 2006-02-15 devnull len = -1;
403 941e1713 2006-02-15 devnull }
404 941e1713 2006-02-15 devnull p->body = t;
405 941e1713 2006-02-15 devnull if(len == -1)
406 941e1713 2006-02-15 devnull p->nbody = strlen(t);
407 941e1713 2006-02-15 devnull else
408 941e1713 2006-02-15 devnull p->nbody = len;
409 941e1713 2006-02-15 devnull }
410 941e1713 2006-02-15 devnull
411 941e1713 2006-02-15 devnull static Qid ZQ;
412 fa325e9b 2020-01-10 cross
413 941e1713 2006-02-15 devnull static int
414 941e1713 2006-02-15 devnull filedata(int type, Box *box, Msg *msg, Part *part, char **pp, int *len, int *freeme, int force, Qid q)
415 941e1713 2006-02-15 devnull {
416 941e1713 2006-02-15 devnull int i, inquote, n, t;
417 941e1713 2006-02-15 devnull char *from, *s;
418 941e1713 2006-02-15 devnull static char buf[256];
419 941e1713 2006-02-15 devnull Fmt fmt;
420 941e1713 2006-02-15 devnull
421 941e1713 2006-02-15 devnull *pp = nil;
422 941e1713 2006-02-15 devnull *freeme = 0;
423 941e1713 2006-02-15 devnull if(len)
424 941e1713 2006-02-15 devnull *len = -1;
425 941e1713 2006-02-15 devnull
426 941e1713 2006-02-15 devnull if(msg == nil || part == nil){
427 941e1713 2006-02-15 devnull werrstr(Emsggone);
428 941e1713 2006-02-15 devnull return -1;
429 941e1713 2006-02-15 devnull }
430 941e1713 2006-02-15 devnull switch(type){
431 941e1713 2006-02-15 devnull case Qdate:
432 941e1713 2006-02-15 devnull case Qsubject:
433 941e1713 2006-02-15 devnull case Qfrom:
434 941e1713 2006-02-15 devnull case Qsender:
435 941e1713 2006-02-15 devnull case Qreplyto:
436 941e1713 2006-02-15 devnull case Qto:
437 941e1713 2006-02-15 devnull case Qcc:
438 941e1713 2006-02-15 devnull case Qbcc:
439 941e1713 2006-02-15 devnull case Qinreplyto:
440 941e1713 2006-02-15 devnull case Qmessageid:
441 941e1713 2006-02-15 devnull if(part->hdr == nil){
442 941e1713 2006-02-15 devnull werrstr(Emsggone);
443 941e1713 2006-02-15 devnull return -1;
444 941e1713 2006-02-15 devnull }
445 941e1713 2006-02-15 devnull *pp = ((char**)&part->hdr->date)[type-Qdate];
446 941e1713 2006-02-15 devnull return 0;
447 fa325e9b 2020-01-10 cross
448 941e1713 2006-02-15 devnull case Qunixdate:
449 941e1713 2006-02-15 devnull strcpy(buf, ctime(msg->date));
450 941e1713 2006-02-15 devnull *pp = buf;
451 941e1713 2006-02-15 devnull return 0;
452 941e1713 2006-02-15 devnull
453 941e1713 2006-02-15 devnull case Qunixheader:
454 941e1713 2006-02-15 devnull if(part->hdr == nil){
455 941e1713 2006-02-15 devnull werrstr(Emsggone);
456 941e1713 2006-02-15 devnull return -1;
457 941e1713 2006-02-15 devnull }
458 941e1713 2006-02-15 devnull from = part->hdr->from;
459 941e1713 2006-02-15 devnull if(from == nil)
460 941e1713 2006-02-15 devnull from = "???";
461 941e1713 2006-02-15 devnull else{
462 941e1713 2006-02-15 devnull inquote = 0;
463 941e1713 2006-02-15 devnull for(; *from; from++){
464 941e1713 2006-02-15 devnull if(*from == '\'')
465 941e1713 2006-02-15 devnull inquote = !inquote;
466 941e1713 2006-02-15 devnull if(!inquote && *from == ' '){
467 941e1713 2006-02-15 devnull from++;
468 941e1713 2006-02-15 devnull break;
469 941e1713 2006-02-15 devnull }
470 941e1713 2006-02-15 devnull }
471 941e1713 2006-02-15 devnull if(*from == 0)
472 941e1713 2006-02-15 devnull from = part->hdr->from;
473 941e1713 2006-02-15 devnull }
474 941e1713 2006-02-15 devnull n = snprint(buf, sizeof buf, "From %s %s", from, ctime(msg->date));
475 941e1713 2006-02-15 devnull if(n+1 < sizeof buf){
476 941e1713 2006-02-15 devnull *pp = buf;
477 941e1713 2006-02-15 devnull return 0;
478 941e1713 2006-02-15 devnull }
479 941e1713 2006-02-15 devnull fmtstrinit(&fmt);
480 941e1713 2006-02-15 devnull fmtprint(&fmt, "From %s %s", from, ctime(msg->date));
481 941e1713 2006-02-15 devnull s = fmtstrflush(&fmt);
482 941e1713 2006-02-15 devnull if(s){
483 941e1713 2006-02-15 devnull *pp = s;
484 941e1713 2006-02-15 devnull *freeme = 1;
485 941e1713 2006-02-15 devnull }else
486 941e1713 2006-02-15 devnull *pp = buf;
487 941e1713 2006-02-15 devnull return 0;
488 941e1713 2006-02-15 devnull
489 941e1713 2006-02-15 devnull case Qtype:
490 941e1713 2006-02-15 devnull case Qidstr:
491 941e1713 2006-02-15 devnull case Qdesc:
492 941e1713 2006-02-15 devnull case Qencoding:
493 941e1713 2006-02-15 devnull case Qcharset:
494 bb70a84b 2007-06-23 devnull case Qfilename:
495 941e1713 2006-02-15 devnull case Qraw:
496 941e1713 2006-02-15 devnull case Qrawheader:
497 941e1713 2006-02-15 devnull case Qrawbody:
498 941e1713 2006-02-15 devnull case Qmimeheader:
499 941e1713 2006-02-15 devnull *pp = ((char**)&part->type)[type-Qtype];
500 941e1713 2006-02-15 devnull if(*pp == nil && force){
501 941e1713 2006-02-15 devnull switch(type){
502 941e1713 2006-02-15 devnull case Qraw:
503 941e1713 2006-02-15 devnull imapfetchraw(imap, part);
504 941e1713 2006-02-15 devnull break;
505 941e1713 2006-02-15 devnull case Qrawheader:
506 941e1713 2006-02-15 devnull imapfetchrawheader(imap, part);
507 941e1713 2006-02-15 devnull break;
508 941e1713 2006-02-15 devnull case Qrawbody:
509 941e1713 2006-02-15 devnull imapfetchrawbody(imap, part);
510 941e1713 2006-02-15 devnull break;
511 941e1713 2006-02-15 devnull case Qmimeheader:
512 941e1713 2006-02-15 devnull imapfetchrawmime(imap, part);
513 941e1713 2006-02-15 devnull break;
514 941e1713 2006-02-15 devnull default:
515 941e1713 2006-02-15 devnull return 0;
516 941e1713 2006-02-15 devnull }
517 941e1713 2006-02-15 devnull /*
518 941e1713 2006-02-15 devnull * We ran fetchsomething, which might have changed
519 941e1713 2006-02-15 devnull * the mailbox contents. Msg might even be gone.
520 941e1713 2006-02-15 devnull */
521 941e1713 2006-02-15 devnull t = parseqid(q, &box, &msg, &part);
522 941e1713 2006-02-15 devnull if(t != type || msg == nil || part == nil)
523 941e1713 2006-02-15 devnull return 0;
524 941e1713 2006-02-15 devnull *pp = ((char**)&part->type)[type-Qtype];
525 941e1713 2006-02-15 devnull }
526 941e1713 2006-02-15 devnull return 0;
527 941e1713 2006-02-15 devnull
528 941e1713 2006-02-15 devnull case Qbody:
529 941e1713 2006-02-15 devnull if(part->body){
530 941e1713 2006-02-15 devnull *pp = part->body;
531 941e1713 2006-02-15 devnull if(len)
532 941e1713 2006-02-15 devnull *len = part->nbody;
533 941e1713 2006-02-15 devnull return 0;
534 941e1713 2006-02-15 devnull }
535 941e1713 2006-02-15 devnull if(!force)
536 941e1713 2006-02-15 devnull return 0;
537 941e1713 2006-02-15 devnull if(part->rawbody == nil){
538 941e1713 2006-02-15 devnull if(part->msg->part[0] == part)
539 941e1713 2006-02-15 devnull imapfetchrawbody(imap, part);
540 941e1713 2006-02-15 devnull else
541 941e1713 2006-02-15 devnull imapfetchraw(imap, part);
542 941e1713 2006-02-15 devnull t = parseqid(q, &box, &msg, &part);
543 941e1713 2006-02-15 devnull if(t != type || msg == nil || part == nil)
544 941e1713 2006-02-15 devnull return 0;
545 941e1713 2006-02-15 devnull }
546 941e1713 2006-02-15 devnull mkbody(part, q);
547 941e1713 2006-02-15 devnull *pp = part->body;
548 941e1713 2006-02-15 devnull if(len)
549 941e1713 2006-02-15 devnull *len = part->nbody;
550 941e1713 2006-02-15 devnull return 0;
551 941e1713 2006-02-15 devnull
552 941e1713 2006-02-15 devnull case Qsize:
553 941e1713 2006-02-15 devnull case Qlines:
554 941e1713 2006-02-15 devnull n = ((uint*)&part->size)[type-Qsize];
555 941e1713 2006-02-15 devnull snprint(buf, sizeof buf, "%d", n);
556 941e1713 2006-02-15 devnull *pp = buf;
557 941e1713 2006-02-15 devnull return 0;
558 941e1713 2006-02-15 devnull
559 941e1713 2006-02-15 devnull case Qflags:
560 941e1713 2006-02-15 devnull s = buf;
561 941e1713 2006-02-15 devnull *s = 0;
562 941e1713 2006-02-15 devnull for(i=0; i<nelem(flagtab); i++){
563 941e1713 2006-02-15 devnull if(msg->flags&flagtab[i].flag){
564 941e1713 2006-02-15 devnull if(s > buf)
565 941e1713 2006-02-15 devnull *s++ = ' ';
566 941e1713 2006-02-15 devnull strcpy(s, flagtab[i].name);
567 941e1713 2006-02-15 devnull s += strlen(s);
568 941e1713 2006-02-15 devnull }
569 941e1713 2006-02-15 devnull }
570 941e1713 2006-02-15 devnull *pp = buf;
571 941e1713 2006-02-15 devnull return 0;
572 941e1713 2006-02-15 devnull
573 941e1713 2006-02-15 devnull case Qinfo:
574 941e1713 2006-02-15 devnull fmtstrinit(&fmt);
575 941e1713 2006-02-15 devnull if(part == msg->part[0]){
576 941e1713 2006-02-15 devnull if(msg->date)
577 2fc68b6d 2011-11-22 rsc fmtprint(&fmt, "unixdate %ud %s", msg->date, ctime(msg->date));
578 941e1713 2006-02-15 devnull if(msg->flags){
579 941e1713 2006-02-15 devnull filedata(Qflags, box, msg, part, pp, nil, freeme, 0, ZQ);
580 941e1713 2006-02-15 devnull fmtprint(&fmt, "flags %s\n", buf);
581 941e1713 2006-02-15 devnull }
582 941e1713 2006-02-15 devnull }
583 941e1713 2006-02-15 devnull if(part->hdr){
584 941e1713 2006-02-15 devnull if(part->hdr->digest)
585 941e1713 2006-02-15 devnull fmtprint(&fmt, "digest %s\n", part->hdr->digest);
586 941e1713 2006-02-15 devnull if(part->hdr->from)
587 941e1713 2006-02-15 devnull fmtprint(&fmt, "from %s\n", part->hdr->from);
588 941e1713 2006-02-15 devnull if(part->hdr->to)
589 941e1713 2006-02-15 devnull fmtprint(&fmt, "to %s\n", part->hdr->to);
590 941e1713 2006-02-15 devnull if(part->hdr->cc)
591 941e1713 2006-02-15 devnull fmtprint(&fmt, "cc %s\n", part->hdr->cc);
592 941e1713 2006-02-15 devnull if(part->hdr->replyto)
593 941e1713 2006-02-15 devnull fmtprint(&fmt, "replyto %s\n", part->hdr->replyto);
594 941e1713 2006-02-15 devnull if(part->hdr->bcc)
595 941e1713 2006-02-15 devnull fmtprint(&fmt, "bcc %s\n", part->hdr->bcc);
596 941e1713 2006-02-15 devnull if(part->hdr->inreplyto)
597 941e1713 2006-02-15 devnull fmtprint(&fmt, "inreplyto %s\n", part->hdr->inreplyto);
598 941e1713 2006-02-15 devnull if(part->hdr->date)
599 941e1713 2006-02-15 devnull fmtprint(&fmt, "date %s\n", part->hdr->date);
600 941e1713 2006-02-15 devnull if(part->hdr->sender)
601 941e1713 2006-02-15 devnull fmtprint(&fmt, "sender %s\n", part->hdr->sender);
602 941e1713 2006-02-15 devnull if(part->hdr->messageid)
603 941e1713 2006-02-15 devnull fmtprint(&fmt, "messageid %s\n", part->hdr->messageid);
604 941e1713 2006-02-15 devnull if(part->hdr->subject)
605 941e1713 2006-02-15 devnull fmtprint(&fmt, "subject %s\n", part->hdr->subject);
606 941e1713 2006-02-15 devnull }
607 941e1713 2006-02-15 devnull if(part->type)
608 941e1713 2006-02-15 devnull fmtprint(&fmt, "type %s\n", part->type);
609 941e1713 2006-02-15 devnull if(part->lines)
610 941e1713 2006-02-15 devnull fmtprint(&fmt, "lines %d\n", part->lines);
611 141d6009 2006-06-30 devnull if(part->filename)
612 141d6009 2006-06-30 devnull fmtprint(&fmt, "filename %s\n", part->filename);
613 941e1713 2006-02-15 devnull s = fmtstrflush(&fmt);
614 941e1713 2006-02-15 devnull if(s == nil)
615 941e1713 2006-02-15 devnull s = estrdup("");
616 941e1713 2006-02-15 devnull *freeme = 1;
617 941e1713 2006-02-15 devnull *pp = s;
618 941e1713 2006-02-15 devnull return 0;
619 941e1713 2006-02-15 devnull
620 941e1713 2006-02-15 devnull case Qheader:
621 941e1713 2006-02-15 devnull if(part->hdr == nil)
622 941e1713 2006-02-15 devnull return 0;
623 941e1713 2006-02-15 devnull fmtstrinit(&fmt);
624 941e1713 2006-02-15 devnull if(part == msg->part[0])
625 941e1713 2006-02-15 devnull fmtprint(&fmt, "Date: %s", ctime(msg->date));
626 941e1713 2006-02-15 devnull else
627 941e1713 2006-02-15 devnull fmtprint(&fmt, "Date: %s\n", part->hdr->date);
628 941e1713 2006-02-15 devnull addaddrs(&fmt, "To", part->hdr->to);
629 941e1713 2006-02-15 devnull addaddrs(&fmt, "From", part->hdr->from);
630 941e1713 2006-02-15 devnull if(part->hdr->from==nil
631 941e1713 2006-02-15 devnull || (part->hdr->sender && strcmp(part->hdr->sender, part->hdr->from) != 0))
632 941e1713 2006-02-15 devnull addaddrs(&fmt, "Sender", part->hdr->sender);
633 fa325e9b 2020-01-10 cross if(part->hdr->from==nil
634 941e1713 2006-02-15 devnull || (part->hdr->replyto && strcmp(part->hdr->replyto, part->hdr->from) != 0))
635 941e1713 2006-02-15 devnull addaddrs(&fmt, "Reply-To", part->hdr->replyto);
636 eb44dca2 2007-06-25 devnull fmtprint(&fmt, "Subject: %s\n", part->hdr->subject);
637 941e1713 2006-02-15 devnull s = fmtstrflush(&fmt);
638 941e1713 2006-02-15 devnull if(s == nil)
639 941e1713 2006-02-15 devnull s = estrdup("");
640 941e1713 2006-02-15 devnull *freeme = 1;
641 941e1713 2006-02-15 devnull *pp = s;
642 941e1713 2006-02-15 devnull return 0;
643 941e1713 2006-02-15 devnull
644 941e1713 2006-02-15 devnull default:
645 941e1713 2006-02-15 devnull werrstr(Egreg);
646 941e1713 2006-02-15 devnull return -1;
647 941e1713 2006-02-15 devnull }
648 941e1713 2006-02-15 devnull }
649 941e1713 2006-02-15 devnull
650 941e1713 2006-02-15 devnull int
651 941e1713 2006-02-15 devnull filldir(Dir *d, int type, Box *box, Msg *msg, Part *part)
652 941e1713 2006-02-15 devnull {
653 941e1713 2006-02-15 devnull int freeme, len;
654 941e1713 2006-02-15 devnull char *s;
655 941e1713 2006-02-15 devnull
656 941e1713 2006-02-15 devnull memset(d, 0, sizeof *d);
657 941e1713 2006-02-15 devnull if(box){
658 941e1713 2006-02-15 devnull d->atime = box->time;
659 941e1713 2006-02-15 devnull d->mtime = box->time;
660 941e1713 2006-02-15 devnull }else{
661 941e1713 2006-02-15 devnull d->atime = t0;
662 941e1713 2006-02-15 devnull d->mtime = t0;
663 941e1713 2006-02-15 devnull }
664 941e1713 2006-02-15 devnull d->uid = estrdup9p("upas");
665 941e1713 2006-02-15 devnull d->gid = estrdup9p("upas");
666 941e1713 2006-02-15 devnull d->muid = estrdup9p("upas");
667 941e1713 2006-02-15 devnull d->qid = qid(type, box, msg, part);
668 941e1713 2006-02-15 devnull
669 941e1713 2006-02-15 devnull switch(type){
670 941e1713 2006-02-15 devnull case Qroot:
671 941e1713 2006-02-15 devnull case Qbox:
672 941e1713 2006-02-15 devnull case Qmsg:
673 941e1713 2006-02-15 devnull d->mode = 0555|DMDIR;
674 941e1713 2006-02-15 devnull if(box && !(box->flags&FlagNoInferiors))
675 941e1713 2006-02-15 devnull d->mode = 0775|DMDIR;
676 941e1713 2006-02-15 devnull break;
677 941e1713 2006-02-15 devnull case Qctl:
678 941e1713 2006-02-15 devnull case Qboxctl:
679 941e1713 2006-02-15 devnull d->mode = 0222;
680 941e1713 2006-02-15 devnull break;
681 941e1713 2006-02-15 devnull case Qsearch:
682 941e1713 2006-02-15 devnull d->mode = 0666;
683 941e1713 2006-02-15 devnull break;
684 fa325e9b 2020-01-10 cross
685 941e1713 2006-02-15 devnull case Qflags:
686 941e1713 2006-02-15 devnull d->mode = 0666;
687 941e1713 2006-02-15 devnull goto msgfile;
688 941e1713 2006-02-15 devnull default:
689 941e1713 2006-02-15 devnull d->mode = 0444;
690 941e1713 2006-02-15 devnull msgfile:
691 941e1713 2006-02-15 devnull if(filedata(type, box, msg, part, &s, &len, &freeme, 0, ZQ) >= 0){
692 941e1713 2006-02-15 devnull if(s){
693 941e1713 2006-02-15 devnull if(len == -1)
694 941e1713 2006-02-15 devnull d->length = strlen(s);
695 941e1713 2006-02-15 devnull else
696 941e1713 2006-02-15 devnull d->length = len;
697 941e1713 2006-02-15 devnull if(freeme)
698 941e1713 2006-02-15 devnull free(s);
699 941e1713 2006-02-15 devnull }
700 941e1713 2006-02-15 devnull }else if(type == Qraw && msg && part == msg->part[0])
701 941e1713 2006-02-15 devnull d->length = msg->size;
702 941e1713 2006-02-15 devnull break;
703 941e1713 2006-02-15 devnull }
704 941e1713 2006-02-15 devnull
705 941e1713 2006-02-15 devnull switch(type){
706 941e1713 2006-02-15 devnull case Qroot:
707 941e1713 2006-02-15 devnull d->name = estrdup9p("/");
708 941e1713 2006-02-15 devnull break;
709 941e1713 2006-02-15 devnull case Qbox:
710 941e1713 2006-02-15 devnull if(box == nil){
711 941e1713 2006-02-15 devnull werrstr(Enobox);
712 941e1713 2006-02-15 devnull return -1;
713 941e1713 2006-02-15 devnull }
714 941e1713 2006-02-15 devnull d->name = estrdup9p(box->elem);
715 941e1713 2006-02-15 devnull break;
716 941e1713 2006-02-15 devnull case Qmsg:
717 941e1713 2006-02-15 devnull if(msg == nil){
718 941e1713 2006-02-15 devnull werrstr(Enomsg);
719 941e1713 2006-02-15 devnull return -1;
720 941e1713 2006-02-15 devnull }
721 941e1713 2006-02-15 devnull if(part == nil || part == msg->part[0])
722 941e1713 2006-02-15 devnull d->name = esmprint("%d", msg->id);
723 941e1713 2006-02-15 devnull else
724 941e1713 2006-02-15 devnull d->name = esmprint("%d", part->pix+1);
725 941e1713 2006-02-15 devnull break;
726 941e1713 2006-02-15 devnull case Qctl:
727 941e1713 2006-02-15 devnull case Qboxctl:
728 941e1713 2006-02-15 devnull d->name = estrdup9p("ctl");
729 941e1713 2006-02-15 devnull break;
730 941e1713 2006-02-15 devnull case Qsearch:
731 941e1713 2006-02-15 devnull d->name = estrdup9p("search");
732 941e1713 2006-02-15 devnull break;
733 941e1713 2006-02-15 devnull default:
734 941e1713 2006-02-15 devnull d->name = estrdup9p(nameoftype(type));
735 941e1713 2006-02-15 devnull break;
736 941e1713 2006-02-15 devnull }
737 941e1713 2006-02-15 devnull return 0;
738 941e1713 2006-02-15 devnull }
739 fa325e9b 2020-01-10 cross
740 941e1713 2006-02-15 devnull static void
741 941e1713 2006-02-15 devnull fsstat(Req *r)
742 941e1713 2006-02-15 devnull {
743 941e1713 2006-02-15 devnull int type;
744 941e1713 2006-02-15 devnull Box *box;
745 941e1713 2006-02-15 devnull Msg *msg;
746 941e1713 2006-02-15 devnull Part *part;
747 fa325e9b 2020-01-10 cross
748 941e1713 2006-02-15 devnull type = parseqid(r->fid->qid, &box, &msg, &part);
749 941e1713 2006-02-15 devnull if(filldir(&r->d, type, box, msg, part) < 0)
750 941e1713 2006-02-15 devnull responderror(r);
751 941e1713 2006-02-15 devnull else
752 941e1713 2006-02-15 devnull respond(r, nil);
753 941e1713 2006-02-15 devnull }
754 941e1713 2006-02-15 devnull
755 941e1713 2006-02-15 devnull int
756 941e1713 2006-02-15 devnull rootgen(int i, Dir *d, void *aux)
757 941e1713 2006-02-15 devnull {
758 941e1713 2006-02-15 devnull USED(aux);
759 fa325e9b 2020-01-10 cross
760 941e1713 2006-02-15 devnull if(i == 0)
761 941e1713 2006-02-15 devnull return filldir(d, Qctl, nil, nil, nil);
762 941e1713 2006-02-15 devnull i--;
763 941e1713 2006-02-15 devnull if(i < rootbox->nsub)
764 941e1713 2006-02-15 devnull return filldir(d, Qbox, rootbox->sub[i], nil, nil);
765 941e1713 2006-02-15 devnull return -1;
766 941e1713 2006-02-15 devnull }
767 941e1713 2006-02-15 devnull
768 941e1713 2006-02-15 devnull int
769 941e1713 2006-02-15 devnull boxgen(int i, Dir *d, void *aux)
770 941e1713 2006-02-15 devnull {
771 941e1713 2006-02-15 devnull Box *box;
772 941e1713 2006-02-15 devnull
773 941e1713 2006-02-15 devnull box = aux;
774 941e1713 2006-02-15 devnull if(i == 0)
775 941e1713 2006-02-15 devnull return filldir(d, Qboxctl, box, nil, nil);
776 941e1713 2006-02-15 devnull i--;
777 941e1713 2006-02-15 devnull if(i == 0)
778 941e1713 2006-02-15 devnull return filldir(d, Qsearch, box, nil, nil);
779 bb70a84b 2007-06-23 devnull i--;
780 941e1713 2006-02-15 devnull if(i < box->nsub)
781 941e1713 2006-02-15 devnull return filldir(d, Qbox, box->sub[i], nil, nil);
782 941e1713 2006-02-15 devnull i -= box->nsub;
783 941e1713 2006-02-15 devnull if(i < box->nmsg)
784 941e1713 2006-02-15 devnull return filldir(d, Qmsg, box, box->msg[i], nil);
785 941e1713 2006-02-15 devnull return -1;
786 941e1713 2006-02-15 devnull }
787 941e1713 2006-02-15 devnull
788 941e1713 2006-02-15 devnull static int msgdir[] = {
789 fa325e9b 2020-01-10 cross Qtype,
790 fa325e9b 2020-01-10 cross Qbody, Qbcc, Qcc, Qdate, Qflags, Qfrom, Qheader, Qinfo,
791 fa325e9b 2020-01-10 cross Qinreplyto, Qlines, Qmimeheader, Qmessageid,
792 941e1713 2006-02-15 devnull Qraw, Qrawunix, Qrawbody, Qrawheader,
793 941e1713 2006-02-15 devnull Qreplyto, Qsender, Qsubject, Qto,
794 941e1713 2006-02-15 devnull Qunixdate, Qunixheader
795 941e1713 2006-02-15 devnull };
796 941e1713 2006-02-15 devnull static int mimemsgdir[] = {
797 fa325e9b 2020-01-10 cross Qtype,
798 fa325e9b 2020-01-10 cross Qbody, Qbcc, Qcc, Qdate, Qfrom, Qheader, Qinfo,
799 fa325e9b 2020-01-10 cross Qinreplyto, Qlines, Qmimeheader, Qmessageid,
800 941e1713 2006-02-15 devnull Qraw, Qrawunix, Qrawbody, Qrawheader,
801 cbeb0b26 2006-04-01 devnull Qreplyto, Qsender, Qsubject, Qto
802 941e1713 2006-02-15 devnull };
803 941e1713 2006-02-15 devnull static int mimedir[] = {
804 941e1713 2006-02-15 devnull Qtype,
805 941e1713 2006-02-15 devnull Qbody,
806 bb70a84b 2007-06-23 devnull Qfilename,
807 bb70a84b 2007-06-23 devnull Qcharset,
808 941e1713 2006-02-15 devnull Qmimeheader,
809 cbeb0b26 2006-04-01 devnull Qraw
810 941e1713 2006-02-15 devnull };
811 fa325e9b 2020-01-10 cross
812 941e1713 2006-02-15 devnull int
813 941e1713 2006-02-15 devnull msggen(int i, Dir *d, void *aux)
814 941e1713 2006-02-15 devnull {
815 941e1713 2006-02-15 devnull Box *box;
816 941e1713 2006-02-15 devnull Msg *msg;
817 941e1713 2006-02-15 devnull Part *part;
818 fa325e9b 2020-01-10 cross
819 941e1713 2006-02-15 devnull part = aux;
820 941e1713 2006-02-15 devnull msg = part->msg;
821 941e1713 2006-02-15 devnull box = msg->box;
822 941e1713 2006-02-15 devnull if(part->ix == 0){
823 941e1713 2006-02-15 devnull if(i < nelem(msgdir))
824 941e1713 2006-02-15 devnull return filldir(d, msgdir[i], box, msg, part);
825 941e1713 2006-02-15 devnull i -= nelem(msgdir);
826 941e1713 2006-02-15 devnull }else if(part->type && strcmp(part->type, "message/rfc822") == 0){
827 941e1713 2006-02-15 devnull if(i < nelem(mimemsgdir))
828 941e1713 2006-02-15 devnull return filldir(d, mimemsgdir[i], box, msg, part);
829 941e1713 2006-02-15 devnull i -= nelem(mimemsgdir);
830 941e1713 2006-02-15 devnull }else{
831 941e1713 2006-02-15 devnull if(i < nelem(mimedir))
832 941e1713 2006-02-15 devnull return filldir(d, mimedir[i], box, msg, part);
833 941e1713 2006-02-15 devnull i -= nelem(mimedir);
834 941e1713 2006-02-15 devnull }
835 941e1713 2006-02-15 devnull if(i < part->nsub)
836 941e1713 2006-02-15 devnull return filldir(d, Qmsg, box, msg, part->sub[i]);
837 941e1713 2006-02-15 devnull return -1;
838 941e1713 2006-02-15 devnull }
839 941e1713 2006-02-15 devnull
840 941e1713 2006-02-15 devnull enum
841 941e1713 2006-02-15 devnull {
842 cbeb0b26 2006-04-01 devnull CMhangup
843 941e1713 2006-02-15 devnull };
844 941e1713 2006-02-15 devnull static Cmdtab ctltab[] =
845 941e1713 2006-02-15 devnull {
846 cbeb0b26 2006-04-01 devnull CMhangup, "hangup", 2
847 941e1713 2006-02-15 devnull };
848 941e1713 2006-02-15 devnull
849 941e1713 2006-02-15 devnull enum
850 941e1713 2006-02-15 devnull {
851 941e1713 2006-02-15 devnull CMdelete,
852 941e1713 2006-02-15 devnull CMrefresh,
853 941e1713 2006-02-15 devnull CMreplied,
854 941e1713 2006-02-15 devnull CMread,
855 941e1713 2006-02-15 devnull CMsave,
856 941e1713 2006-02-15 devnull CMjunk,
857 cbeb0b26 2006-04-01 devnull CMnonjunk
858 941e1713 2006-02-15 devnull };
859 941e1713 2006-02-15 devnull static Cmdtab boxctltab[] =
860 941e1713 2006-02-15 devnull {
861 941e1713 2006-02-15 devnull CMdelete, "delete", 0,
862 941e1713 2006-02-15 devnull CMrefresh, "refresh", 1,
863 941e1713 2006-02-15 devnull CMreplied, "replied", 0,
864 941e1713 2006-02-15 devnull CMread, "read", 0,
865 941e1713 2006-02-15 devnull CMsave, "save", 0,
866 941e1713 2006-02-15 devnull CMjunk, "junk", 0,
867 cbeb0b26 2006-04-01 devnull CMnonjunk, "nonjunk", 0
868 941e1713 2006-02-15 devnull };
869 941e1713 2006-02-15 devnull
870 941e1713 2006-02-15 devnull static void
871 941e1713 2006-02-15 devnull fsread(Req *r)
872 941e1713 2006-02-15 devnull {
873 941e1713 2006-02-15 devnull char *s;
874 941e1713 2006-02-15 devnull int type, len, freeme;
875 941e1713 2006-02-15 devnull Box *box;
876 941e1713 2006-02-15 devnull Msg *msg;
877 941e1713 2006-02-15 devnull Part *part;
878 fa325e9b 2020-01-10 cross
879 941e1713 2006-02-15 devnull switch(type = parseqid(r->fid->qid, &box, &msg, &part)){
880 941e1713 2006-02-15 devnull case Qroot:
881 941e1713 2006-02-15 devnull dirread9p(r, rootgen, nil);
882 941e1713 2006-02-15 devnull respond(r, nil);
883 941e1713 2006-02-15 devnull return;
884 941e1713 2006-02-15 devnull
885 941e1713 2006-02-15 devnull case Qbox:
886 941e1713 2006-02-15 devnull if(box == nil){
887 941e1713 2006-02-15 devnull respond(r, Eboxgone);
888 941e1713 2006-02-15 devnull return;
889 941e1713 2006-02-15 devnull }
890 941e1713 2006-02-15 devnull if(box->nmsg == 0)
891 941e1713 2006-02-15 devnull imapcheckbox(imap, box);
892 941e1713 2006-02-15 devnull parseqid(r->fid->qid, &box, &msg, &part);
893 941e1713 2006-02-15 devnull if(box == nil){
894 941e1713 2006-02-15 devnull respond(r, Eboxgone);
895 941e1713 2006-02-15 devnull return;
896 941e1713 2006-02-15 devnull }
897 941e1713 2006-02-15 devnull dirread9p(r, boxgen, box);
898 941e1713 2006-02-15 devnull respond(r, nil);
899 941e1713 2006-02-15 devnull return;
900 941e1713 2006-02-15 devnull
901 941e1713 2006-02-15 devnull case Qmsg:
902 941e1713 2006-02-15 devnull if(msg == nil || part == nil){
903 941e1713 2006-02-15 devnull respond(r, Emsggone);
904 941e1713 2006-02-15 devnull return;
905 941e1713 2006-02-15 devnull }
906 941e1713 2006-02-15 devnull dirread9p(r, msggen, part);
907 941e1713 2006-02-15 devnull respond(r, nil);
908 941e1713 2006-02-15 devnull return;
909 fa325e9b 2020-01-10 cross
910 941e1713 2006-02-15 devnull case Qctl:
911 941e1713 2006-02-15 devnull case Qboxctl:
912 941e1713 2006-02-15 devnull respond(r, Egreg);
913 941e1713 2006-02-15 devnull return;
914 941e1713 2006-02-15 devnull
915 941e1713 2006-02-15 devnull case Qsearch:
916 941e1713 2006-02-15 devnull readstr(r, r->fid->aux);
917 941e1713 2006-02-15 devnull respond(r, nil);
918 941e1713 2006-02-15 devnull return;
919 941e1713 2006-02-15 devnull
920 941e1713 2006-02-15 devnull default:
921 941e1713 2006-02-15 devnull if(filedata(type, box, msg, part, &s, &len, &freeme, 1, r->fid->qid) < 0){
922 941e1713 2006-02-15 devnull responderror(r);
923 941e1713 2006-02-15 devnull return;
924 941e1713 2006-02-15 devnull }
925 941e1713 2006-02-15 devnull if(s && len == -1)
926 941e1713 2006-02-15 devnull len = strlen(s);
927 941e1713 2006-02-15 devnull readbuf(r, s, len);
928 941e1713 2006-02-15 devnull if(freeme)
929 941e1713 2006-02-15 devnull free(s);
930 941e1713 2006-02-15 devnull respond(r, nil);
931 941e1713 2006-02-15 devnull return;
932 941e1713 2006-02-15 devnull }
933 941e1713 2006-02-15 devnull }
934 941e1713 2006-02-15 devnull
935 941e1713 2006-02-15 devnull int
936 941e1713 2006-02-15 devnull mkmsglist(Box *box, char **f, int nf, Msg ***mm)
937 941e1713 2006-02-15 devnull {
938 941e1713 2006-02-15 devnull int i, nm;
939 941e1713 2006-02-15 devnull Msg **m;
940 fa325e9b 2020-01-10 cross
941 941e1713 2006-02-15 devnull m = emalloc(nf*sizeof m[0]);
942 941e1713 2006-02-15 devnull nm = 0;
943 941e1713 2006-02-15 devnull for(i=0; i<nf; i++)
944 941e1713 2006-02-15 devnull if((m[nm] = msgbyid(box, atoi(f[i]))) != nil)
945 941e1713 2006-02-15 devnull nm++;
946 941e1713 2006-02-15 devnull *mm = m;
947 941e1713 2006-02-15 devnull return nm;
948 941e1713 2006-02-15 devnull }
949 941e1713 2006-02-15 devnull
950 941e1713 2006-02-15 devnull static void
951 941e1713 2006-02-15 devnull fswrite(Req *r)
952 941e1713 2006-02-15 devnull {
953 a6a35288 2017-10-13 0intro int i, j, c, type, flag, unflag, flagset, f;
954 941e1713 2006-02-15 devnull Box *box;
955 941e1713 2006-02-15 devnull Msg *msg;
956 941e1713 2006-02-15 devnull Part *part;
957 941e1713 2006-02-15 devnull Cmdbuf *cb;
958 941e1713 2006-02-15 devnull Cmdtab *ct;
959 941e1713 2006-02-15 devnull Msg **m;
960 941e1713 2006-02-15 devnull int nm;
961 941e1713 2006-02-15 devnull Fmt fmt;
962 941e1713 2006-02-15 devnull
963 941e1713 2006-02-15 devnull r->ofcall.count = r->ifcall.count;
964 941e1713 2006-02-15 devnull switch(type = parseqid(r->fid->qid, &box, &msg, &part)){
965 941e1713 2006-02-15 devnull default:
966 941e1713 2006-02-15 devnull respond(r, Egreg);
967 941e1713 2006-02-15 devnull break;
968 941e1713 2006-02-15 devnull
969 941e1713 2006-02-15 devnull case Qctl:
970 941e1713 2006-02-15 devnull cb = parsecmd(r->ifcall.data, r->ifcall.count);
971 941e1713 2006-02-15 devnull if((ct = lookupcmd(cb, ctltab, nelem(ctltab))) == nil){
972 941e1713 2006-02-15 devnull respondcmderror(r, cb, "unknown message");
973 941e1713 2006-02-15 devnull free(cb);
974 941e1713 2006-02-15 devnull return;
975 941e1713 2006-02-15 devnull }
976 941e1713 2006-02-15 devnull r->ofcall.count = r->ifcall.count;
977 941e1713 2006-02-15 devnull switch(ct->index){
978 941e1713 2006-02-15 devnull case CMhangup:
979 941e1713 2006-02-15 devnull imaphangup(imap, atoi(cb->f[1]));
980 941e1713 2006-02-15 devnull respond(r, nil);
981 941e1713 2006-02-15 devnull break;
982 941e1713 2006-02-15 devnull default:
983 941e1713 2006-02-15 devnull respond(r, Egreg);
984 941e1713 2006-02-15 devnull break;
985 941e1713 2006-02-15 devnull }
986 941e1713 2006-02-15 devnull free(cb);
987 941e1713 2006-02-15 devnull return;
988 941e1713 2006-02-15 devnull
989 941e1713 2006-02-15 devnull case Qboxctl:
990 941e1713 2006-02-15 devnull cb = parsecmd(r->ifcall.data, r->ifcall.count);
991 941e1713 2006-02-15 devnull if((ct = lookupcmd(cb, boxctltab, nelem(boxctltab))) == nil){
992 941e1713 2006-02-15 devnull respondcmderror(r, cb, "bad message");
993 941e1713 2006-02-15 devnull free(cb);
994 941e1713 2006-02-15 devnull return;
995 941e1713 2006-02-15 devnull }
996 941e1713 2006-02-15 devnull r->ofcall.count = r->ifcall.count;
997 941e1713 2006-02-15 devnull switch(ct->index){
998 941e1713 2006-02-15 devnull case CMsave:
999 941e1713 2006-02-15 devnull if(cb->nf <= 2){
1000 941e1713 2006-02-15 devnull respondcmderror(r, cb, Ebadctl);
1001 941e1713 2006-02-15 devnull break;
1002 941e1713 2006-02-15 devnull }
1003 941e1713 2006-02-15 devnull nm = mkmsglist(box, cb->f+2, cb->nf-2, &m);
1004 941e1713 2006-02-15 devnull if(nm != cb->nf-2){
1005 cbeb0b26 2006-04-01 devnull /* free(m); */
1006 941e1713 2006-02-15 devnull respond(r, Enomsg);
1007 941e1713 2006-02-15 devnull break;
1008 941e1713 2006-02-15 devnull }
1009 941e1713 2006-02-15 devnull if(nm > 0 && imapcopylist(imap, cb->f[1], m, nm) < 0)
1010 941e1713 2006-02-15 devnull responderror(r);
1011 941e1713 2006-02-15 devnull else
1012 941e1713 2006-02-15 devnull respond(r, nil);
1013 941e1713 2006-02-15 devnull free(m);
1014 941e1713 2006-02-15 devnull break;
1015 fa325e9b 2020-01-10 cross
1016 941e1713 2006-02-15 devnull case CMjunk:
1017 941e1713 2006-02-15 devnull flag = FlagJunk;
1018 941e1713 2006-02-15 devnull goto flagit;
1019 941e1713 2006-02-15 devnull case CMnonjunk:
1020 941e1713 2006-02-15 devnull flag = FlagNonJunk;
1021 941e1713 2006-02-15 devnull goto flagit;
1022 941e1713 2006-02-15 devnull case CMreplied:
1023 941e1713 2006-02-15 devnull flag = FlagReplied;
1024 941e1713 2006-02-15 devnull goto flagit;
1025 941e1713 2006-02-15 devnull case CMread:
1026 941e1713 2006-02-15 devnull flag = FlagSeen;
1027 941e1713 2006-02-15 devnull flagit:
1028 941e1713 2006-02-15 devnull if(cb->nf <= 1){
1029 941e1713 2006-02-15 devnull respondcmderror(r, cb, Ebadctl);
1030 941e1713 2006-02-15 devnull break;
1031 941e1713 2006-02-15 devnull }
1032 941e1713 2006-02-15 devnull nm = mkmsglist(box, cb->f+1, cb->nf-1, &m);
1033 941e1713 2006-02-15 devnull if(nm != cb->nf-1){
1034 941e1713 2006-02-15 devnull free(m);
1035 941e1713 2006-02-15 devnull respond(r, Enomsg);
1036 941e1713 2006-02-15 devnull break;
1037 941e1713 2006-02-15 devnull }
1038 941e1713 2006-02-15 devnull if(nm > 0 && imapflaglist(imap, +1, flag, m, nm) < 0)
1039 941e1713 2006-02-15 devnull responderror(r);
1040 941e1713 2006-02-15 devnull else
1041 941e1713 2006-02-15 devnull respond(r, nil);
1042 941e1713 2006-02-15 devnull free(m);
1043 941e1713 2006-02-15 devnull break;
1044 941e1713 2006-02-15 devnull
1045 941e1713 2006-02-15 devnull case CMrefresh:
1046 941e1713 2006-02-15 devnull imapcheckbox(imap, box);
1047 941e1713 2006-02-15 devnull respond(r, nil);
1048 941e1713 2006-02-15 devnull break;
1049 941e1713 2006-02-15 devnull
1050 941e1713 2006-02-15 devnull case CMdelete:
1051 941e1713 2006-02-15 devnull if(cb->nf <= 1){
1052 941e1713 2006-02-15 devnull respondcmderror(r, cb, Ebadctl);
1053 941e1713 2006-02-15 devnull break;
1054 941e1713 2006-02-15 devnull }
1055 941e1713 2006-02-15 devnull nm = mkmsglist(box, cb->f+1, cb->nf-1, &m);
1056 941e1713 2006-02-15 devnull if(nm > 0 && imapremovelist(imap, m, nm) < 0)
1057 941e1713 2006-02-15 devnull responderror(r);
1058 941e1713 2006-02-15 devnull else
1059 941e1713 2006-02-15 devnull respond(r, nil);
1060 941e1713 2006-02-15 devnull free(m);
1061 941e1713 2006-02-15 devnull break;
1062 941e1713 2006-02-15 devnull
1063 941e1713 2006-02-15 devnull default:
1064 941e1713 2006-02-15 devnull respond(r, Egreg);
1065 941e1713 2006-02-15 devnull break;
1066 941e1713 2006-02-15 devnull }
1067 941e1713 2006-02-15 devnull free(cb);
1068 941e1713 2006-02-15 devnull return;
1069 941e1713 2006-02-15 devnull
1070 941e1713 2006-02-15 devnull case Qflags:
1071 941e1713 2006-02-15 devnull if(msg == nil){
1072 941e1713 2006-02-15 devnull respond(r, Enomsg);
1073 941e1713 2006-02-15 devnull return;
1074 941e1713 2006-02-15 devnull }
1075 941e1713 2006-02-15 devnull cb = parsecmd(r->ifcall.data, r->ifcall.count);
1076 941e1713 2006-02-15 devnull flag = 0;
1077 941e1713 2006-02-15 devnull unflag = 0;
1078 941e1713 2006-02-15 devnull flagset = 0;
1079 941e1713 2006-02-15 devnull for(i=0; i<cb->nf; i++){
1080 941e1713 2006-02-15 devnull f = 0;
1081 941e1713 2006-02-15 devnull c = cb->f[i][0];
1082 941e1713 2006-02-15 devnull if(c == '+' || c == '-')
1083 941e1713 2006-02-15 devnull cb->f[i]++;
1084 941e1713 2006-02-15 devnull for(j=0; j<nelem(flagtab); j++){
1085 941e1713 2006-02-15 devnull if(strcmp(flagtab[j].name, cb->f[i]) == 0){
1086 941e1713 2006-02-15 devnull f = flagtab[j].flag;
1087 941e1713 2006-02-15 devnull break;
1088 941e1713 2006-02-15 devnull }
1089 941e1713 2006-02-15 devnull }
1090 941e1713 2006-02-15 devnull if(f == 0){
1091 941e1713 2006-02-15 devnull respondcmderror(r, cb, "unknown flag %s", cb->f[i]);
1092 941e1713 2006-02-15 devnull free(cb);
1093 941e1713 2006-02-15 devnull return;
1094 941e1713 2006-02-15 devnull }
1095 941e1713 2006-02-15 devnull if(c == '+')
1096 941e1713 2006-02-15 devnull flag |= f;
1097 941e1713 2006-02-15 devnull else if(c == '-')
1098 941e1713 2006-02-15 devnull unflag |= f;
1099 941e1713 2006-02-15 devnull else
1100 941e1713 2006-02-15 devnull flagset |= f;
1101 941e1713 2006-02-15 devnull }
1102 941e1713 2006-02-15 devnull free(cb);
1103 941e1713 2006-02-15 devnull if((flagset!=0)+(unflag!=0)+(flag!=0) != 1){
1104 941e1713 2006-02-15 devnull respondcmderror(r, cb, Ebadctl);
1105 941e1713 2006-02-15 devnull return;
1106 941e1713 2006-02-15 devnull }
1107 941e1713 2006-02-15 devnull if(flag)
1108 941e1713 2006-02-15 devnull i = 1;
1109 941e1713 2006-02-15 devnull else if(unflag){
1110 941e1713 2006-02-15 devnull i = -1;
1111 941e1713 2006-02-15 devnull flag = unflag;
1112 941e1713 2006-02-15 devnull }else{
1113 941e1713 2006-02-15 devnull i = 0;
1114 941e1713 2006-02-15 devnull flag = flagset;
1115 941e1713 2006-02-15 devnull }
1116 941e1713 2006-02-15 devnull if(imapflaglist(imap, i, flag, &msg, 1) < 0)
1117 941e1713 2006-02-15 devnull responderror(r);
1118 941e1713 2006-02-15 devnull else
1119 941e1713 2006-02-15 devnull respond(r, nil);
1120 941e1713 2006-02-15 devnull return;
1121 941e1713 2006-02-15 devnull
1122 941e1713 2006-02-15 devnull case Qsearch:
1123 941e1713 2006-02-15 devnull if(box == nil){
1124 941e1713 2006-02-15 devnull respond(r, Eboxgone);
1125 941e1713 2006-02-15 devnull return;
1126 941e1713 2006-02-15 devnull }
1127 941e1713 2006-02-15 devnull fmtstrinit(&fmt);
1128 941e1713 2006-02-15 devnull nm = imapsearchbox(imap, box, r->ifcall.data, &m);
1129 941e1713 2006-02-15 devnull for(i=0; i<nm; i++){
1130 941e1713 2006-02-15 devnull if(i>0)
1131 941e1713 2006-02-15 devnull fmtrune(&fmt, ' ');
1132 941e1713 2006-02-15 devnull fmtprint(&fmt, "%d", m[i]->id);
1133 941e1713 2006-02-15 devnull }
1134 941e1713 2006-02-15 devnull free(r->fid->aux);
1135 941e1713 2006-02-15 devnull r->fid->aux = fmtstrflush(&fmt);
1136 941e1713 2006-02-15 devnull respond(r, nil);
1137 941e1713 2006-02-15 devnull return;
1138 941e1713 2006-02-15 devnull }
1139 941e1713 2006-02-15 devnull }
1140 941e1713 2006-02-15 devnull
1141 941e1713 2006-02-15 devnull static void
1142 941e1713 2006-02-15 devnull fsopen(Req *r)
1143 941e1713 2006-02-15 devnull {
1144 941e1713 2006-02-15 devnull switch(qtype(r->fid->qid)){
1145 941e1713 2006-02-15 devnull case Qctl:
1146 941e1713 2006-02-15 devnull case Qboxctl:
1147 941e1713 2006-02-15 devnull if((r->ifcall.mode&~OTRUNC) != OWRITE){
1148 941e1713 2006-02-15 devnull respond(r, Eperm);
1149 941e1713 2006-02-15 devnull return;
1150 941e1713 2006-02-15 devnull }
1151 941e1713 2006-02-15 devnull respond(r, nil);
1152 941e1713 2006-02-15 devnull return;
1153 941e1713 2006-02-15 devnull
1154 941e1713 2006-02-15 devnull case Qflags:
1155 941e1713 2006-02-15 devnull case Qsearch:
1156 941e1713 2006-02-15 devnull if((r->ifcall.mode&~OTRUNC) > ORDWR){
1157 941e1713 2006-02-15 devnull respond(r, Eperm);
1158 941e1713 2006-02-15 devnull return;
1159 941e1713 2006-02-15 devnull }
1160 941e1713 2006-02-15 devnull respond(r, nil);
1161 941e1713 2006-02-15 devnull return;
1162 941e1713 2006-02-15 devnull
1163 941e1713 2006-02-15 devnull default:
1164 941e1713 2006-02-15 devnull if(r->ifcall.mode != OREAD){
1165 941e1713 2006-02-15 devnull respond(r, Eperm);
1166 941e1713 2006-02-15 devnull return;
1167 941e1713 2006-02-15 devnull }
1168 941e1713 2006-02-15 devnull respond(r, nil);
1169 941e1713 2006-02-15 devnull return;
1170 941e1713 2006-02-15 devnull }
1171 941e1713 2006-02-15 devnull }
1172 941e1713 2006-02-15 devnull
1173 941e1713 2006-02-15 devnull static void
1174 941e1713 2006-02-15 devnull fsflush(Req *r)
1175 941e1713 2006-02-15 devnull {
1176 941e1713 2006-02-15 devnull /*
1177 941e1713 2006-02-15 devnull * We only handle reads and writes outside the main loop,
1178 941e1713 2006-02-15 devnull * so we must be flushing one of those. In both cases it's
1179 941e1713 2006-02-15 devnull * okay to just ignore the results of the request, whenever
1180 941e1713 2006-02-15 devnull * they're ready.
1181 941e1713 2006-02-15 devnull */
1182 941e1713 2006-02-15 devnull incref(&r->oldreq->ref);
1183 941e1713 2006-02-15 devnull respond(r->oldreq, "interrupted");
1184 941e1713 2006-02-15 devnull respond(r, nil);
1185 941e1713 2006-02-15 devnull }
1186 941e1713 2006-02-15 devnull
1187 941e1713 2006-02-15 devnull static void
1188 941e1713 2006-02-15 devnull fsthread(void *v)
1189 941e1713 2006-02-15 devnull {
1190 941e1713 2006-02-15 devnull Req *r;
1191 fa325e9b 2020-01-10 cross
1192 941e1713 2006-02-15 devnull r = v;
1193 941e1713 2006-02-15 devnull switch(r->ifcall.type){
1194 941e1713 2006-02-15 devnull case Tread:
1195 941e1713 2006-02-15 devnull fsread(r);
1196 941e1713 2006-02-15 devnull break;
1197 941e1713 2006-02-15 devnull case Twrite:
1198 941e1713 2006-02-15 devnull fswrite(r);
1199 941e1713 2006-02-15 devnull break;
1200 941e1713 2006-02-15 devnull }
1201 941e1713 2006-02-15 devnull }
1202 941e1713 2006-02-15 devnull
1203 941e1713 2006-02-15 devnull static void
1204 941e1713 2006-02-15 devnull fsrecv(void *v)
1205 941e1713 2006-02-15 devnull {
1206 941e1713 2006-02-15 devnull Req *r;
1207 2fc68b6d 2011-11-22 rsc
1208 2fc68b6d 2011-11-22 rsc USED(v);
1209 941e1713 2006-02-15 devnull while((r = recvp(fsreqchan)) != nil){
1210 941e1713 2006-02-15 devnull switch(r->ifcall.type){
1211 941e1713 2006-02-15 devnull case Tattach:
1212 941e1713 2006-02-15 devnull fsattach(r);
1213 941e1713 2006-02-15 devnull break;
1214 941e1713 2006-02-15 devnull case Tflush:
1215 941e1713 2006-02-15 devnull fsflush(r);
1216 941e1713 2006-02-15 devnull break;
1217 941e1713 2006-02-15 devnull case Topen:
1218 941e1713 2006-02-15 devnull fsopen(r);
1219 941e1713 2006-02-15 devnull break;
1220 941e1713 2006-02-15 devnull case Twalk:
1221 941e1713 2006-02-15 devnull fswalk(r);
1222 941e1713 2006-02-15 devnull break;
1223 941e1713 2006-02-15 devnull case Tstat:
1224 941e1713 2006-02-15 devnull fsstat(r);
1225 941e1713 2006-02-15 devnull break;
1226 941e1713 2006-02-15 devnull default:
1227 941e1713 2006-02-15 devnull threadcreate(fsthread, r, STACK);
1228 941e1713 2006-02-15 devnull break;
1229 941e1713 2006-02-15 devnull }
1230 941e1713 2006-02-15 devnull }
1231 941e1713 2006-02-15 devnull }
1232 941e1713 2006-02-15 devnull
1233 941e1713 2006-02-15 devnull static void
1234 941e1713 2006-02-15 devnull fssend(Req *r)
1235 941e1713 2006-02-15 devnull {
1236 941e1713 2006-02-15 devnull sendp(fsreqchan, r);
1237 941e1713 2006-02-15 devnull }
1238 941e1713 2006-02-15 devnull
1239 941e1713 2006-02-15 devnull static void
1240 941e1713 2006-02-15 devnull fsdestroyfid(Fid *f)
1241 941e1713 2006-02-15 devnull {
1242 941e1713 2006-02-15 devnull free(f->aux);
1243 941e1713 2006-02-15 devnull }
1244 941e1713 2006-02-15 devnull
1245 941e1713 2006-02-15 devnull void
1246 941e1713 2006-02-15 devnull fsinit0(void) /* bad planning - clash with lib9pclient */
1247 941e1713 2006-02-15 devnull {
1248 941e1713 2006-02-15 devnull t0 = time(0);
1249 941e1713 2006-02-15 devnull
1250 941e1713 2006-02-15 devnull fs.attach = fssend;
1251 941e1713 2006-02-15 devnull fs.flush = fssend;
1252 941e1713 2006-02-15 devnull fs.open = fssend;
1253 941e1713 2006-02-15 devnull fs.walk = fssend;
1254 941e1713 2006-02-15 devnull fs.read = fssend;
1255 941e1713 2006-02-15 devnull fs.write = fssend;
1256 941e1713 2006-02-15 devnull fs.stat = fssend;
1257 941e1713 2006-02-15 devnull fs.destroyfid = fsdestroyfid;
1258 fa325e9b 2020-01-10 cross
1259 941e1713 2006-02-15 devnull rootqid = qid(Qroot, nil, nil, nil);
1260 fa325e9b 2020-01-10 cross
1261 941e1713 2006-02-15 devnull fsreqchan = chancreate(sizeof(void*), 0);
1262 941e1713 2006-02-15 devnull mailthread(fsrecv, nil);
1263 941e1713 2006-02-15 devnull }