Blame


1 5cdb1798 2005-10-29 devnull #include "common.h"
2 5cdb1798 2005-10-29 devnull #include <auth.h>
3 5cdb1798 2005-10-29 devnull #include <fcall.h>
4 5cdb1798 2005-10-29 devnull #include <libsec.h>
5 5cdb1798 2005-10-29 devnull #include <9pclient.h> /* jpc */
6 5cdb1798 2005-10-29 devnull #include <thread.h> /* jpc */
7 5cdb1798 2005-10-29 devnull #include "dat.h"
8 5cdb1798 2005-10-29 devnull
9 5cdb1798 2005-10-29 devnull enum
10 5cdb1798 2005-10-29 devnull {
11 cbeb0b26 2006-04-01 devnull OPERM = 0x3, /* mask of all permission types in open mode */
12 5cdb1798 2005-10-29 devnull };
13 5cdb1798 2005-10-29 devnull
14 5cdb1798 2005-10-29 devnull typedef struct Fid Fid;
15 5cdb1798 2005-10-29 devnull
16 5cdb1798 2005-10-29 devnull struct Fid
17 5cdb1798 2005-10-29 devnull {
18 5cdb1798 2005-10-29 devnull Qid qid;
19 5cdb1798 2005-10-29 devnull short busy;
20 5cdb1798 2005-10-29 devnull short open;
21 5cdb1798 2005-10-29 devnull int fid;
22 5cdb1798 2005-10-29 devnull Fid *next;
23 5cdb1798 2005-10-29 devnull Mailbox *mb;
24 5cdb1798 2005-10-29 devnull Message *m;
25 cbeb0b26 2006-04-01 devnull Message *mtop; /* top level message */
26 5cdb1798 2005-10-29 devnull
27 cbeb0b26 2006-04-01 devnull /*finger pointers to speed up reads of large directories */
28 cbeb0b26 2006-04-01 devnull long foff; /* offset/DIRLEN of finger */
29 cbeb0b26 2006-04-01 devnull Message *fptr; /* pointer to message at off */
30 cbeb0b26 2006-04-01 devnull int fvers; /* mailbox version when finger was saved */
31 5cdb1798 2005-10-29 devnull };
32 5cdb1798 2005-10-29 devnull
33 cbeb0b26 2006-04-01 devnull ulong path; /* incremented for each new file */
34 5cdb1798 2005-10-29 devnull Fid *fids;
35 5cdb1798 2005-10-29 devnull int mfd[2];
36 5cdb1798 2005-10-29 devnull char user[Elemlen];
37 5cdb1798 2005-10-29 devnull int messagesize = 4*1024*IOHDRSZ;
38 5cdb1798 2005-10-29 devnull uchar mdata[8*1024*IOHDRSZ];
39 5cdb1798 2005-10-29 devnull uchar mbuf[8*1024*IOHDRSZ];
40 5cdb1798 2005-10-29 devnull Fcall thdr;
41 5cdb1798 2005-10-29 devnull Fcall rhdr;
42 5cdb1798 2005-10-29 devnull int fflg;
43 5cdb1798 2005-10-29 devnull char *mntpt;
44 5cdb1798 2005-10-29 devnull int biffing;
45 5cdb1798 2005-10-29 devnull int plumbing = 1;
46 5cdb1798 2005-10-29 devnull
47 5cdb1798 2005-10-29 devnull QLock mbllock;
48 5cdb1798 2005-10-29 devnull Mailbox *mbl;
49 5cdb1798 2005-10-29 devnull
50 5cdb1798 2005-10-29 devnull Fid *newfid(int);
51 5cdb1798 2005-10-29 devnull void error(char*);
52 5cdb1798 2005-10-29 devnull void io(void);
53 5cdb1798 2005-10-29 devnull void *erealloc(void*, ulong);
54 5cdb1798 2005-10-29 devnull void *emalloc(ulong);
55 5cdb1798 2005-10-29 devnull void usage(void);
56 5cdb1798 2005-10-29 devnull void run_io(void*);
57 5cdb1798 2005-10-29 devnull void reader(void*);
58 5cdb1798 2005-10-29 devnull int readheader(Message*, char*, int, int);
59 5cdb1798 2005-10-29 devnull int cistrncmp(char*, char*, int);
60 5cdb1798 2005-10-29 devnull int tokenconvert(String*, char*, int);
61 5cdb1798 2005-10-29 devnull String* stringconvert(String*, char*, int);
62 5cdb1798 2005-10-29 devnull void post(char*, char*, int);
63 5cdb1798 2005-10-29 devnull
64 5cdb1798 2005-10-29 devnull char *rflush(Fid*), *rauth(Fid*),
65 5cdb1798 2005-10-29 devnull *rattach(Fid*), *rwalk(Fid*),
66 5cdb1798 2005-10-29 devnull *ropen(Fid*), *rcreate(Fid*),
67 5cdb1798 2005-10-29 devnull *rread(Fid*), *rwrite(Fid*), *rclunk(Fid*),
68 5cdb1798 2005-10-29 devnull *rremove(Fid*), *rstat(Fid*), *rwstat(Fid*),
69 5cdb1798 2005-10-29 devnull *rversion(Fid*);
70 5cdb1798 2005-10-29 devnull
71 5cdb1798 2005-10-29 devnull char *(*fcalls[])(Fid*) = {
72 5cdb1798 2005-10-29 devnull [Tflush] rflush,
73 5cdb1798 2005-10-29 devnull [Tversion] rversion,
74 5cdb1798 2005-10-29 devnull [Tauth] rauth,
75 5cdb1798 2005-10-29 devnull [Tattach] rattach,
76 5cdb1798 2005-10-29 devnull [Twalk] rwalk,
77 5cdb1798 2005-10-29 devnull [Topen] ropen,
78 5cdb1798 2005-10-29 devnull [Tcreate] rcreate,
79 5cdb1798 2005-10-29 devnull [Tread] rread,
80 5cdb1798 2005-10-29 devnull [Twrite] rwrite,
81 5cdb1798 2005-10-29 devnull [Tclunk] rclunk,
82 5cdb1798 2005-10-29 devnull [Tremove] rremove,
83 5cdb1798 2005-10-29 devnull [Tstat] rstat,
84 cbeb0b26 2006-04-01 devnull [Twstat] rwstat
85 5cdb1798 2005-10-29 devnull };
86 5cdb1798 2005-10-29 devnull
87 5cdb1798 2005-10-29 devnull char Eperm[] = "permission denied";
88 5cdb1798 2005-10-29 devnull char Enotdir[] = "not a directory";
89 5cdb1798 2005-10-29 devnull char Enoauth[] = "upas/fs: authentication not required";
90 5cdb1798 2005-10-29 devnull char Enotexist[] = "file does not exist";
91 5cdb1798 2005-10-29 devnull char Einuse[] = "file in use";
92 5cdb1798 2005-10-29 devnull char Eexist[] = "file exists";
93 5cdb1798 2005-10-29 devnull char Enotowner[] = "not owner";
94 5cdb1798 2005-10-29 devnull char Eisopen[] = "file already open for I/O";
95 5cdb1798 2005-10-29 devnull char Excl[] = "exclusive use file already open";
96 5cdb1798 2005-10-29 devnull char Ename[] = "illegal name";
97 5cdb1798 2005-10-29 devnull char Ebadctl[] = "unknown control message";
98 5cdb1798 2005-10-29 devnull
99 5cdb1798 2005-10-29 devnull char *dirtab[] =
100 5cdb1798 2005-10-29 devnull {
101 5cdb1798 2005-10-29 devnull [Qdir] ".",
102 5cdb1798 2005-10-29 devnull [Qbody] "body",
103 5cdb1798 2005-10-29 devnull [Qbcc] "bcc",
104 5cdb1798 2005-10-29 devnull [Qcc] "cc",
105 5cdb1798 2005-10-29 devnull [Qdate] "date",
106 5cdb1798 2005-10-29 devnull [Qdigest] "digest",
107 5cdb1798 2005-10-29 devnull [Qdisposition] "disposition",
108 5cdb1798 2005-10-29 devnull [Qfilename] "filename",
109 5cdb1798 2005-10-29 devnull [Qfrom] "from",
110 5cdb1798 2005-10-29 devnull [Qheader] "header",
111 5cdb1798 2005-10-29 devnull [Qinfo] "info",
112 5cdb1798 2005-10-29 devnull [Qinreplyto] "inreplyto",
113 5cdb1798 2005-10-29 devnull [Qlines] "lines",
114 5cdb1798 2005-10-29 devnull [Qmimeheader] "mimeheader",
115 5cdb1798 2005-10-29 devnull [Qmessageid] "messageid",
116 5cdb1798 2005-10-29 devnull [Qraw] "raw",
117 5cdb1798 2005-10-29 devnull [Qrawunix] "rawunix",
118 5cdb1798 2005-10-29 devnull [Qrawbody] "rawbody",
119 5cdb1798 2005-10-29 devnull [Qrawheader] "rawheader",
120 5cdb1798 2005-10-29 devnull [Qreplyto] "replyto",
121 5cdb1798 2005-10-29 devnull [Qsender] "sender",
122 5cdb1798 2005-10-29 devnull [Qsubject] "subject",
123 5cdb1798 2005-10-29 devnull [Qto] "to",
124 5cdb1798 2005-10-29 devnull [Qtype] "type",
125 5cdb1798 2005-10-29 devnull [Qunixdate] "unixdate",
126 5cdb1798 2005-10-29 devnull [Qunixheader] "unixheader",
127 5cdb1798 2005-10-29 devnull [Qctl] "ctl",
128 cbeb0b26 2006-04-01 devnull [Qmboxctl] "ctl"
129 5cdb1798 2005-10-29 devnull };
130 5cdb1798 2005-10-29 devnull
131 5cdb1798 2005-10-29 devnull enum
132 5cdb1798 2005-10-29 devnull {
133 cbeb0b26 2006-04-01 devnull Hsize= 1277
134 5cdb1798 2005-10-29 devnull };
135 5cdb1798 2005-10-29 devnull
136 5cdb1798 2005-10-29 devnull Hash *htab[Hsize];
137 5cdb1798 2005-10-29 devnull
138 5cdb1798 2005-10-29 devnull int debug;
139 5cdb1798 2005-10-29 devnull int fflag;
140 5cdb1798 2005-10-29 devnull int logging;
141 5cdb1798 2005-10-29 devnull
142 5cdb1798 2005-10-29 devnull void
143 5cdb1798 2005-10-29 devnull usage(void)
144 5cdb1798 2005-10-29 devnull {
145 5cdb1798 2005-10-29 devnull fprint(2, "usage: %s [-b -m mountpoint]\n", argv0);
146 5cdb1798 2005-10-29 devnull threadexits("usage");
147 5cdb1798 2005-10-29 devnull }
148 5cdb1798 2005-10-29 devnull
149 5cdb1798 2005-10-29 devnull void
150 5cdb1798 2005-10-29 devnull notifyf(void *a, char *s)
151 5cdb1798 2005-10-29 devnull {
152 5cdb1798 2005-10-29 devnull USED(a);
153 5cdb1798 2005-10-29 devnull if(strncmp(s, "interrupt", 9) == 0)
154 5cdb1798 2005-10-29 devnull noted(NCONT);
155 5cdb1798 2005-10-29 devnull noted(NDFLT);
156 5cdb1798 2005-10-29 devnull }
157 5cdb1798 2005-10-29 devnull
158 5cdb1798 2005-10-29 devnull void
159 5cdb1798 2005-10-29 devnull threadmain(int argc, char *argv[])
160 5cdb1798 2005-10-29 devnull {
161 5cdb1798 2005-10-29 devnull int p[2], std, nodflt;
162 5cdb1798 2005-10-29 devnull char maildir[128];
163 5cdb1798 2005-10-29 devnull char mbox[128];
164 5cdb1798 2005-10-29 devnull char *mboxfile, *err;
165 5cdb1798 2005-10-29 devnull char srvfile[64];
166 5cdb1798 2005-10-29 devnull int srvpost;
167 5cdb1798 2005-10-29 devnull
168 5cdb1798 2005-10-29 devnull rfork(RFNOTEG);
169 5cdb1798 2005-10-29 devnull mntpt = nil;
170 5cdb1798 2005-10-29 devnull fflag = 0;
171 5cdb1798 2005-10-29 devnull mboxfile = nil;
172 5cdb1798 2005-10-29 devnull std = 0;
173 5cdb1798 2005-10-29 devnull nodflt = 0;
174 5cdb1798 2005-10-29 devnull srvpost = 0;
175 5cdb1798 2005-10-29 devnull
176 5cdb1798 2005-10-29 devnull ARGBEGIN{
177 5cdb1798 2005-10-29 devnull case 'b':
178 5cdb1798 2005-10-29 devnull biffing = 1;
179 5cdb1798 2005-10-29 devnull break;
180 5cdb1798 2005-10-29 devnull case 'f':
181 5cdb1798 2005-10-29 devnull fflag = 1;
182 5cdb1798 2005-10-29 devnull mboxfile = ARGF();
183 5cdb1798 2005-10-29 devnull break;
184 5cdb1798 2005-10-29 devnull case 'm':
185 5cdb1798 2005-10-29 devnull mntpt = ARGF();
186 5cdb1798 2005-10-29 devnull break;
187 5cdb1798 2005-10-29 devnull case 'd':
188 5cdb1798 2005-10-29 devnull debug = 1;
189 5cdb1798 2005-10-29 devnull break;
190 5cdb1798 2005-10-29 devnull case 'p':
191 5cdb1798 2005-10-29 devnull plumbing = 0;
192 5cdb1798 2005-10-29 devnull break;
193 5cdb1798 2005-10-29 devnull case 's':
194 5cdb1798 2005-10-29 devnull srvpost = 1;
195 5cdb1798 2005-10-29 devnull break;
196 5cdb1798 2005-10-29 devnull case 'l':
197 5cdb1798 2005-10-29 devnull logging = 1;
198 5cdb1798 2005-10-29 devnull break;
199 5cdb1798 2005-10-29 devnull case 'n':
200 5cdb1798 2005-10-29 devnull nodflt = 1;
201 5cdb1798 2005-10-29 devnull break;
202 5cdb1798 2005-10-29 devnull default:
203 5cdb1798 2005-10-29 devnull usage();
204 5cdb1798 2005-10-29 devnull }ARGEND
205 5cdb1798 2005-10-29 devnull
206 5cdb1798 2005-10-29 devnull if(pipe(p) < 0)
207 5cdb1798 2005-10-29 devnull error("pipe failed");
208 5cdb1798 2005-10-29 devnull mfd[0] = p[0];
209 5cdb1798 2005-10-29 devnull mfd[1] = p[0];
210 5cdb1798 2005-10-29 devnull
211 5cdb1798 2005-10-29 devnull notify(notifyf);
212 5cdb1798 2005-10-29 devnull strcpy(user, getuser());
213 5cdb1798 2005-10-29 devnull if(mntpt == nil){
214 5cdb1798 2005-10-29 devnull snprint(maildir, sizeof(maildir), "/mail/fs");
215 5cdb1798 2005-10-29 devnull mntpt = maildir;
216 5cdb1798 2005-10-29 devnull }
217 5cdb1798 2005-10-29 devnull if(mboxfile == nil && !nodflt){
218 5cdb1798 2005-10-29 devnull snprint(mbox, sizeof(mbox), "/mail/box/%s/mbox", user);
219 5cdb1798 2005-10-29 devnull mboxfile = mbox;
220 5cdb1798 2005-10-29 devnull std = 1;
221 5cdb1798 2005-10-29 devnull }
222 5cdb1798 2005-10-29 devnull
223 5cdb1798 2005-10-29 devnull if(debug)
224 5cdb1798 2005-10-29 devnull fmtinstall('F', fcallfmt);
225 5cdb1798 2005-10-29 devnull
226 5cdb1798 2005-10-29 devnull if(mboxfile != nil){
227 5cdb1798 2005-10-29 devnull err = newmbox(mboxfile, "mbox", std);
228 5cdb1798 2005-10-29 devnull if(err != nil)
229 5cdb1798 2005-10-29 devnull sysfatal("opening mailbox: %s", err);
230 5cdb1798 2005-10-29 devnull }
231 5cdb1798 2005-10-29 devnull
232 5cdb1798 2005-10-29 devnull switch(rfork(RFFDG|RFPROC|RFNAMEG|RFNOTEG)){ /* jpc removed RFEND */
233 5cdb1798 2005-10-29 devnull case -1:
234 5cdb1798 2005-10-29 devnull error("fork");
235 5cdb1798 2005-10-29 devnull case 0:
236 5cdb1798 2005-10-29 devnull henter(PATH(0, Qtop), dirtab[Qctl],
237 5cdb1798 2005-10-29 devnull (Qid){PATH(0, Qctl), 0, QTFILE}, nil, nil);
238 5cdb1798 2005-10-29 devnull close(p[1]);
239 5cdb1798 2005-10-29 devnull io();
240 5cdb1798 2005-10-29 devnull postnote(PNGROUP, getpid(), "die yankee pig dog");
241 5cdb1798 2005-10-29 devnull break;
242 5cdb1798 2005-10-29 devnull default:
243 5cdb1798 2005-10-29 devnull close(p[0]); /* don't deadlock if child fails */
244 5cdb1798 2005-10-29 devnull if(srvpost){
245 5cdb1798 2005-10-29 devnull sprint(srvfile, "/srv/upasfs.%s", user);
246 5cdb1798 2005-10-29 devnull /* post(srvfile, "upasfs", p[1]); jpc */
247 5cdb1798 2005-10-29 devnull post9pservice(p[1], "upasfs"); /* jpc */
248 5cdb1798 2005-10-29 devnull } else {
249 5cdb1798 2005-10-29 devnull error("tried to mount, fixme"); /* jpc */
250 5cdb1798 2005-10-29 devnull /* if(mount(p[1], -1, mntpt, MREPL, "") < 0)
251 5cdb1798 2005-10-29 devnull error("mount failed"); jpc */
252 5cdb1798 2005-10-29 devnull }
253 5cdb1798 2005-10-29 devnull }
254 5cdb1798 2005-10-29 devnull threadexits(0);
255 5cdb1798 2005-10-29 devnull }
256 5cdb1798 2005-10-29 devnull
257 5cdb1798 2005-10-29 devnull void run_io(void *v) {
258 5cdb1798 2005-10-29 devnull int *p;
259 5cdb1798 2005-10-29 devnull
260 5cdb1798 2005-10-29 devnull p = v;
261 5cdb1798 2005-10-29 devnull henter(PATH(0, Qtop), dirtab[Qctl],
262 5cdb1798 2005-10-29 devnull (Qid){PATH(0, Qctl), 0, QTFILE}, nil, nil);
263 5cdb1798 2005-10-29 devnull close(p[1]);
264 5cdb1798 2005-10-29 devnull io();
265 5cdb1798 2005-10-29 devnull postnote(PNGROUP, getpid(), "die yankee pig dog");
266 5cdb1798 2005-10-29 devnull }
267 5cdb1798 2005-10-29 devnull
268 5cdb1798 2005-10-29 devnull static int
269 5cdb1798 2005-10-29 devnull fileinfo(Message *m, int t, char **pp)
270 5cdb1798 2005-10-29 devnull {
271 5cdb1798 2005-10-29 devnull char *p;
272 5cdb1798 2005-10-29 devnull int len;
273 5cdb1798 2005-10-29 devnull
274 5cdb1798 2005-10-29 devnull p = "";
275 5cdb1798 2005-10-29 devnull len = 0;
276 5cdb1798 2005-10-29 devnull switch(t){
277 5cdb1798 2005-10-29 devnull case Qbody:
278 5cdb1798 2005-10-29 devnull p = m->body;
279 5cdb1798 2005-10-29 devnull len = m->bend - m->body;
280 5cdb1798 2005-10-29 devnull break;
281 5cdb1798 2005-10-29 devnull case Qbcc:
282 5cdb1798 2005-10-29 devnull if(m->bcc822){
283 5cdb1798 2005-10-29 devnull p = s_to_c(m->bcc822);
284 5cdb1798 2005-10-29 devnull len = strlen(p);
285 5cdb1798 2005-10-29 devnull }
286 5cdb1798 2005-10-29 devnull break;
287 5cdb1798 2005-10-29 devnull case Qcc:
288 5cdb1798 2005-10-29 devnull if(m->cc822){
289 5cdb1798 2005-10-29 devnull p = s_to_c(m->cc822);
290 5cdb1798 2005-10-29 devnull len = strlen(p);
291 5cdb1798 2005-10-29 devnull }
292 5cdb1798 2005-10-29 devnull break;
293 5cdb1798 2005-10-29 devnull case Qdisposition:
294 5cdb1798 2005-10-29 devnull switch(m->disposition){
295 5cdb1798 2005-10-29 devnull case Dinline:
296 5cdb1798 2005-10-29 devnull p = "inline";
297 5cdb1798 2005-10-29 devnull break;
298 5cdb1798 2005-10-29 devnull case Dfile:
299 5cdb1798 2005-10-29 devnull p = "file";
300 5cdb1798 2005-10-29 devnull break;
301 5cdb1798 2005-10-29 devnull }
302 5cdb1798 2005-10-29 devnull len = strlen(p);
303 5cdb1798 2005-10-29 devnull break;
304 5cdb1798 2005-10-29 devnull case Qdate:
305 5cdb1798 2005-10-29 devnull if(m->date822){
306 5cdb1798 2005-10-29 devnull p = s_to_c(m->date822);
307 5cdb1798 2005-10-29 devnull len = strlen(p);
308 5cdb1798 2005-10-29 devnull } else if(m->unixdate != nil){
309 5cdb1798 2005-10-29 devnull p = s_to_c(m->unixdate);
310 5cdb1798 2005-10-29 devnull len = strlen(p);
311 5cdb1798 2005-10-29 devnull }
312 5cdb1798 2005-10-29 devnull break;
313 5cdb1798 2005-10-29 devnull case Qfilename:
314 5cdb1798 2005-10-29 devnull if(m->filename){
315 5cdb1798 2005-10-29 devnull p = s_to_c(m->filename);
316 5cdb1798 2005-10-29 devnull len = strlen(p);
317 5cdb1798 2005-10-29 devnull }
318 5cdb1798 2005-10-29 devnull break;
319 5cdb1798 2005-10-29 devnull case Qinreplyto:
320 5cdb1798 2005-10-29 devnull if(m->inreplyto822){
321 5cdb1798 2005-10-29 devnull p = s_to_c(m->inreplyto822);
322 5cdb1798 2005-10-29 devnull len = strlen(p);
323 5cdb1798 2005-10-29 devnull }
324 5cdb1798 2005-10-29 devnull break;
325 5cdb1798 2005-10-29 devnull case Qmessageid:
326 5cdb1798 2005-10-29 devnull if(m->messageid822){
327 5cdb1798 2005-10-29 devnull p = s_to_c(m->messageid822);
328 5cdb1798 2005-10-29 devnull len = strlen(p);
329 5cdb1798 2005-10-29 devnull }
330 5cdb1798 2005-10-29 devnull break;
331 5cdb1798 2005-10-29 devnull case Qfrom:
332 5cdb1798 2005-10-29 devnull if(m->from822){
333 5cdb1798 2005-10-29 devnull p = s_to_c(m->from822);
334 5cdb1798 2005-10-29 devnull len = strlen(p);
335 5cdb1798 2005-10-29 devnull } else if(m->unixfrom != nil){
336 5cdb1798 2005-10-29 devnull p = s_to_c(m->unixfrom);
337 5cdb1798 2005-10-29 devnull len = strlen(p);
338 5cdb1798 2005-10-29 devnull }
339 5cdb1798 2005-10-29 devnull break;
340 5cdb1798 2005-10-29 devnull case Qheader:
341 5cdb1798 2005-10-29 devnull p = m->header;
342 5cdb1798 2005-10-29 devnull len = headerlen(m);
343 5cdb1798 2005-10-29 devnull break;
344 5cdb1798 2005-10-29 devnull case Qlines:
345 5cdb1798 2005-10-29 devnull p = m->lines;
346 5cdb1798 2005-10-29 devnull if(*p == 0)
347 5cdb1798 2005-10-29 devnull countlines(m);
348 5cdb1798 2005-10-29 devnull len = strlen(m->lines);
349 5cdb1798 2005-10-29 devnull break;
350 5cdb1798 2005-10-29 devnull case Qraw:
351 5cdb1798 2005-10-29 devnull p = m->start;
352 5cdb1798 2005-10-29 devnull if(strncmp(m->start, "From ", 5) == 0){
353 5cdb1798 2005-10-29 devnull p = strchr(p, '\n');
354 5cdb1798 2005-10-29 devnull if(p == nil)
355 5cdb1798 2005-10-29 devnull p = m->start;
356 5cdb1798 2005-10-29 devnull else
357 5cdb1798 2005-10-29 devnull p++;
358 5cdb1798 2005-10-29 devnull }
359 5cdb1798 2005-10-29 devnull len = m->end - p;
360 5cdb1798 2005-10-29 devnull break;
361 5cdb1798 2005-10-29 devnull case Qrawunix:
362 5cdb1798 2005-10-29 devnull p = m->start;
363 5cdb1798 2005-10-29 devnull len = m->end - p;
364 5cdb1798 2005-10-29 devnull break;
365 5cdb1798 2005-10-29 devnull case Qrawbody:
366 5cdb1798 2005-10-29 devnull p = m->rbody;
367 5cdb1798 2005-10-29 devnull len = m->rbend - p;
368 5cdb1798 2005-10-29 devnull break;
369 5cdb1798 2005-10-29 devnull case Qrawheader:
370 5cdb1798 2005-10-29 devnull p = m->header;
371 5cdb1798 2005-10-29 devnull len = m->hend - p;
372 5cdb1798 2005-10-29 devnull break;
373 5cdb1798 2005-10-29 devnull case Qmimeheader:
374 5cdb1798 2005-10-29 devnull p = m->mheader;
375 5cdb1798 2005-10-29 devnull len = m->mhend - p;
376 5cdb1798 2005-10-29 devnull break;
377 5cdb1798 2005-10-29 devnull case Qreplyto:
378 5cdb1798 2005-10-29 devnull p = nil;
379 5cdb1798 2005-10-29 devnull if(m->replyto822 != nil){
380 5cdb1798 2005-10-29 devnull p = s_to_c(m->replyto822);
381 5cdb1798 2005-10-29 devnull len = strlen(p);
382 5cdb1798 2005-10-29 devnull } else if(m->from822 != nil){
383 5cdb1798 2005-10-29 devnull p = s_to_c(m->from822);
384 5cdb1798 2005-10-29 devnull len = strlen(p);
385 5cdb1798 2005-10-29 devnull } else if(m->sender822 != nil){
386 5cdb1798 2005-10-29 devnull p = s_to_c(m->sender822);
387 5cdb1798 2005-10-29 devnull len = strlen(p);
388 5cdb1798 2005-10-29 devnull } else if(m->unixfrom != nil){
389 5cdb1798 2005-10-29 devnull p = s_to_c(m->unixfrom);
390 5cdb1798 2005-10-29 devnull len = strlen(p);
391 5cdb1798 2005-10-29 devnull }
392 5cdb1798 2005-10-29 devnull break;
393 5cdb1798 2005-10-29 devnull case Qsender:
394 5cdb1798 2005-10-29 devnull if(m->sender822){
395 5cdb1798 2005-10-29 devnull p = s_to_c(m->sender822);
396 5cdb1798 2005-10-29 devnull len = strlen(p);
397 5cdb1798 2005-10-29 devnull }
398 5cdb1798 2005-10-29 devnull break;
399 5cdb1798 2005-10-29 devnull case Qsubject:
400 5cdb1798 2005-10-29 devnull p = nil;
401 5cdb1798 2005-10-29 devnull if(m->subject822){
402 5cdb1798 2005-10-29 devnull p = s_to_c(m->subject822);
403 5cdb1798 2005-10-29 devnull len = strlen(p);
404 5cdb1798 2005-10-29 devnull }
405 5cdb1798 2005-10-29 devnull break;
406 5cdb1798 2005-10-29 devnull case Qto:
407 5cdb1798 2005-10-29 devnull if(m->to822){
408 5cdb1798 2005-10-29 devnull p = s_to_c(m->to822);
409 5cdb1798 2005-10-29 devnull len = strlen(p);
410 5cdb1798 2005-10-29 devnull }
411 5cdb1798 2005-10-29 devnull break;
412 5cdb1798 2005-10-29 devnull case Qtype:
413 5cdb1798 2005-10-29 devnull if(m->type){
414 5cdb1798 2005-10-29 devnull p = s_to_c(m->type);
415 5cdb1798 2005-10-29 devnull len = strlen(p);
416 5cdb1798 2005-10-29 devnull }
417 5cdb1798 2005-10-29 devnull break;
418 5cdb1798 2005-10-29 devnull case Qunixdate:
419 5cdb1798 2005-10-29 devnull if(m->unixdate){
420 5cdb1798 2005-10-29 devnull p = s_to_c(m->unixdate);
421 5cdb1798 2005-10-29 devnull len = strlen(p);
422 5cdb1798 2005-10-29 devnull }
423 5cdb1798 2005-10-29 devnull break;
424 5cdb1798 2005-10-29 devnull case Qunixheader:
425 5cdb1798 2005-10-29 devnull if(m->unixheader){
426 5cdb1798 2005-10-29 devnull p = s_to_c(m->unixheader);
427 5cdb1798 2005-10-29 devnull len = s_len(m->unixheader);
428 5cdb1798 2005-10-29 devnull }
429 5cdb1798 2005-10-29 devnull break;
430 5cdb1798 2005-10-29 devnull case Qdigest:
431 5cdb1798 2005-10-29 devnull if(m->sdigest){
432 5cdb1798 2005-10-29 devnull p = s_to_c(m->sdigest);
433 5cdb1798 2005-10-29 devnull len = strlen(p);
434 5cdb1798 2005-10-29 devnull }
435 5cdb1798 2005-10-29 devnull break;
436 5cdb1798 2005-10-29 devnull }
437 5cdb1798 2005-10-29 devnull *pp = p;
438 5cdb1798 2005-10-29 devnull return len;
439 5cdb1798 2005-10-29 devnull }
440 5cdb1798 2005-10-29 devnull
441 5cdb1798 2005-10-29 devnull int infofields[] = {
442 5cdb1798 2005-10-29 devnull Qfrom,
443 5cdb1798 2005-10-29 devnull Qto,
444 5cdb1798 2005-10-29 devnull Qcc,
445 5cdb1798 2005-10-29 devnull Qreplyto,
446 5cdb1798 2005-10-29 devnull Qunixdate,
447 5cdb1798 2005-10-29 devnull Qsubject,
448 5cdb1798 2005-10-29 devnull Qtype,
449 5cdb1798 2005-10-29 devnull Qdisposition,
450 5cdb1798 2005-10-29 devnull Qfilename,
451 5cdb1798 2005-10-29 devnull Qdigest,
452 5cdb1798 2005-10-29 devnull Qbcc,
453 5cdb1798 2005-10-29 devnull Qinreplyto,
454 5cdb1798 2005-10-29 devnull Qdate,
455 5cdb1798 2005-10-29 devnull Qsender,
456 5cdb1798 2005-10-29 devnull Qmessageid,
457 5cdb1798 2005-10-29 devnull Qlines,
458 cbeb0b26 2006-04-01 devnull -1
459 5cdb1798 2005-10-29 devnull };
460 5cdb1798 2005-10-29 devnull
461 5cdb1798 2005-10-29 devnull static int
462 5cdb1798 2005-10-29 devnull readinfo(Message *m, char *buf, long off, int count)
463 5cdb1798 2005-10-29 devnull {
464 5cdb1798 2005-10-29 devnull char *p;
465 5cdb1798 2005-10-29 devnull int len, i, n;
466 5cdb1798 2005-10-29 devnull String *s;
467 5cdb1798 2005-10-29 devnull
468 5cdb1798 2005-10-29 devnull s = s_new();
469 5cdb1798 2005-10-29 devnull len = 0;
470 5cdb1798 2005-10-29 devnull for(i = 0; len < count && infofields[i] >= 0; i++){
471 5cdb1798 2005-10-29 devnull n = fileinfo(m, infofields[i], &p);
472 5cdb1798 2005-10-29 devnull s = stringconvert(s, p, n);
473 5cdb1798 2005-10-29 devnull s_append(s, "\n");
474 5cdb1798 2005-10-29 devnull p = s_to_c(s);
475 5cdb1798 2005-10-29 devnull n = strlen(p);
476 5cdb1798 2005-10-29 devnull if(off > 0){
477 5cdb1798 2005-10-29 devnull if(off >= n){
478 5cdb1798 2005-10-29 devnull off -= n;
479 5cdb1798 2005-10-29 devnull continue;
480 5cdb1798 2005-10-29 devnull }
481 5cdb1798 2005-10-29 devnull p += off;
482 5cdb1798 2005-10-29 devnull n -= off;
483 5cdb1798 2005-10-29 devnull off = 0;
484 5cdb1798 2005-10-29 devnull }
485 5cdb1798 2005-10-29 devnull if(n > count - len)
486 5cdb1798 2005-10-29 devnull n = count - len;
487 5cdb1798 2005-10-29 devnull if(buf)
488 5cdb1798 2005-10-29 devnull memmove(buf+len, p, n);
489 5cdb1798 2005-10-29 devnull len += n;
490 5cdb1798 2005-10-29 devnull }
491 5cdb1798 2005-10-29 devnull s_free(s);
492 5cdb1798 2005-10-29 devnull return len;
493 5cdb1798 2005-10-29 devnull }
494 5cdb1798 2005-10-29 devnull
495 5cdb1798 2005-10-29 devnull static void
496 5cdb1798 2005-10-29 devnull mkstat(Dir *d, Mailbox *mb, Message *m, int t)
497 5cdb1798 2005-10-29 devnull {
498 5cdb1798 2005-10-29 devnull char *p;
499 5cdb1798 2005-10-29 devnull
500 5cdb1798 2005-10-29 devnull d->uid = user;
501 5cdb1798 2005-10-29 devnull d->gid = user;
502 5cdb1798 2005-10-29 devnull d->muid = user;
503 5cdb1798 2005-10-29 devnull d->mode = 0444;
504 5cdb1798 2005-10-29 devnull d->qid.vers = 0;
505 5cdb1798 2005-10-29 devnull d->qid.type = QTFILE;
506 5cdb1798 2005-10-29 devnull d->type = 0;
507 5cdb1798 2005-10-29 devnull d->dev = 0;
508 5cdb1798 2005-10-29 devnull if(mb != nil && mb->d != nil){
509 5cdb1798 2005-10-29 devnull d->atime = mb->d->atime;
510 5cdb1798 2005-10-29 devnull d->mtime = mb->d->mtime;
511 5cdb1798 2005-10-29 devnull } else {
512 5cdb1798 2005-10-29 devnull d->atime = time(0);
513 5cdb1798 2005-10-29 devnull d->mtime = d->atime;
514 5cdb1798 2005-10-29 devnull }
515 5cdb1798 2005-10-29 devnull
516 5cdb1798 2005-10-29 devnull switch(t){
517 5cdb1798 2005-10-29 devnull case Qtop:
518 5cdb1798 2005-10-29 devnull d->name = ".";
519 5cdb1798 2005-10-29 devnull d->mode = DMDIR|0555;
520 5cdb1798 2005-10-29 devnull d->atime = d->mtime = time(0);
521 5cdb1798 2005-10-29 devnull d->length = 0;
522 5cdb1798 2005-10-29 devnull d->qid.path = PATH(0, Qtop);
523 5cdb1798 2005-10-29 devnull d->qid.type = QTDIR;
524 5cdb1798 2005-10-29 devnull break;
525 5cdb1798 2005-10-29 devnull case Qmbox:
526 5cdb1798 2005-10-29 devnull d->name = mb->name;
527 5cdb1798 2005-10-29 devnull d->mode = DMDIR|0555;
528 5cdb1798 2005-10-29 devnull d->length = 0;
529 5cdb1798 2005-10-29 devnull d->qid.path = PATH(mb->id, Qmbox);
530 5cdb1798 2005-10-29 devnull d->qid.type = QTDIR;
531 5cdb1798 2005-10-29 devnull d->qid.vers = mb->vers;
532 5cdb1798 2005-10-29 devnull break;
533 5cdb1798 2005-10-29 devnull case Qdir:
534 5cdb1798 2005-10-29 devnull d->name = m->name;
535 5cdb1798 2005-10-29 devnull d->mode = DMDIR|0555;
536 5cdb1798 2005-10-29 devnull d->length = 0;
537 5cdb1798 2005-10-29 devnull d->qid.path = PATH(m->id, Qdir);
538 5cdb1798 2005-10-29 devnull d->qid.type = QTDIR;
539 5cdb1798 2005-10-29 devnull break;
540 5cdb1798 2005-10-29 devnull case Qctl:
541 5cdb1798 2005-10-29 devnull d->name = dirtab[t];
542 5cdb1798 2005-10-29 devnull d->mode = 0666;
543 5cdb1798 2005-10-29 devnull d->atime = d->mtime = time(0);
544 5cdb1798 2005-10-29 devnull d->length = 0;
545 5cdb1798 2005-10-29 devnull d->qid.path = PATH(0, Qctl);
546 5cdb1798 2005-10-29 devnull break;
547 5cdb1798 2005-10-29 devnull case Qmboxctl:
548 5cdb1798 2005-10-29 devnull d->name = dirtab[t];
549 5cdb1798 2005-10-29 devnull d->mode = 0222;
550 5cdb1798 2005-10-29 devnull d->atime = d->mtime = time(0);
551 5cdb1798 2005-10-29 devnull d->length = 0;
552 5cdb1798 2005-10-29 devnull d->qid.path = PATH(mb->id, Qmboxctl);
553 5cdb1798 2005-10-29 devnull break;
554 5cdb1798 2005-10-29 devnull case Qinfo:
555 5cdb1798 2005-10-29 devnull d->name = dirtab[t];
556 5cdb1798 2005-10-29 devnull d->length = readinfo(m, nil, 0, 1<<30);
557 5cdb1798 2005-10-29 devnull d->qid.path = PATH(m->id, t);
558 5cdb1798 2005-10-29 devnull break;
559 5cdb1798 2005-10-29 devnull default:
560 5cdb1798 2005-10-29 devnull d->name = dirtab[t];
561 5cdb1798 2005-10-29 devnull d->length = fileinfo(m, t, &p);
562 5cdb1798 2005-10-29 devnull d->qid.path = PATH(m->id, t);
563 5cdb1798 2005-10-29 devnull break;
564 5cdb1798 2005-10-29 devnull }
565 5cdb1798 2005-10-29 devnull }
566 5cdb1798 2005-10-29 devnull
567 5cdb1798 2005-10-29 devnull char*
568 5cdb1798 2005-10-29 devnull rversion(Fid* dummy)
569 5cdb1798 2005-10-29 devnull {
570 5cdb1798 2005-10-29 devnull Fid *f;
571 5cdb1798 2005-10-29 devnull
572 5cdb1798 2005-10-29 devnull if(thdr.msize < 256)
573 5cdb1798 2005-10-29 devnull return "max messagesize too small";
574 5cdb1798 2005-10-29 devnull if(thdr.msize < messagesize)
575 5cdb1798 2005-10-29 devnull messagesize = thdr.msize;
576 5cdb1798 2005-10-29 devnull rhdr.msize = messagesize;
577 5cdb1798 2005-10-29 devnull if(strncmp(thdr.version, "9P2000", 6) != 0)
578 5cdb1798 2005-10-29 devnull return "unknown 9P version";
579 5cdb1798 2005-10-29 devnull else
580 5cdb1798 2005-10-29 devnull rhdr.version = "9P2000";
581 5cdb1798 2005-10-29 devnull for(f = fids; f; f = f->next)
582 5cdb1798 2005-10-29 devnull if(f->busy)
583 5cdb1798 2005-10-29 devnull rclunk(f);
584 5cdb1798 2005-10-29 devnull return nil;
585 5cdb1798 2005-10-29 devnull }
586 5cdb1798 2005-10-29 devnull
587 5cdb1798 2005-10-29 devnull char*
588 5cdb1798 2005-10-29 devnull rauth(Fid* dummy)
589 5cdb1798 2005-10-29 devnull {
590 5cdb1798 2005-10-29 devnull return Enoauth;
591 5cdb1798 2005-10-29 devnull }
592 5cdb1798 2005-10-29 devnull
593 5cdb1798 2005-10-29 devnull char*
594 5cdb1798 2005-10-29 devnull rflush(Fid *f)
595 5cdb1798 2005-10-29 devnull {
596 5cdb1798 2005-10-29 devnull USED(f);
597 5cdb1798 2005-10-29 devnull return 0;
598 5cdb1798 2005-10-29 devnull }
599 5cdb1798 2005-10-29 devnull
600 5cdb1798 2005-10-29 devnull char*
601 5cdb1798 2005-10-29 devnull rattach(Fid *f)
602 5cdb1798 2005-10-29 devnull {
603 5cdb1798 2005-10-29 devnull f->busy = 1;
604 5cdb1798 2005-10-29 devnull f->m = nil;
605 5cdb1798 2005-10-29 devnull f->mb = nil;
606 5cdb1798 2005-10-29 devnull f->qid.path = PATH(0, Qtop);
607 5cdb1798 2005-10-29 devnull f->qid.type = QTDIR;
608 5cdb1798 2005-10-29 devnull f->qid.vers = 0;
609 5cdb1798 2005-10-29 devnull rhdr.qid = f->qid;
610 5cdb1798 2005-10-29 devnull if(strcmp(thdr.uname, user) != 0)
611 5cdb1798 2005-10-29 devnull return Eperm;
612 5cdb1798 2005-10-29 devnull return 0;
613 5cdb1798 2005-10-29 devnull }
614 5cdb1798 2005-10-29 devnull
615 5cdb1798 2005-10-29 devnull static Fid*
616 5cdb1798 2005-10-29 devnull doclone(Fid *f, int nfid)
617 5cdb1798 2005-10-29 devnull {
618 5cdb1798 2005-10-29 devnull Fid *nf;
619 5cdb1798 2005-10-29 devnull
620 5cdb1798 2005-10-29 devnull nf = newfid(nfid);
621 5cdb1798 2005-10-29 devnull if(nf->busy)
622 5cdb1798 2005-10-29 devnull return nil;
623 5cdb1798 2005-10-29 devnull nf->busy = 1;
624 5cdb1798 2005-10-29 devnull nf->open = 0;
625 5cdb1798 2005-10-29 devnull nf->m = f->m;
626 5cdb1798 2005-10-29 devnull nf->mtop = f->mtop;
627 5cdb1798 2005-10-29 devnull nf->mb = f->mb;
628 5cdb1798 2005-10-29 devnull if(f->mb != nil)
629 5cdb1798 2005-10-29 devnull mboxincref(f->mb);
630 5cdb1798 2005-10-29 devnull if(f->mtop != nil){
631 5cdb1798 2005-10-29 devnull qlock(&f->mb->ql);
632 5cdb1798 2005-10-29 devnull msgincref(f->mtop);
633 5cdb1798 2005-10-29 devnull qunlock(&f->mb->ql);
634 5cdb1798 2005-10-29 devnull }
635 5cdb1798 2005-10-29 devnull nf->qid = f->qid;
636 5cdb1798 2005-10-29 devnull return nf;
637 5cdb1798 2005-10-29 devnull }
638 5cdb1798 2005-10-29 devnull
639 5cdb1798 2005-10-29 devnull char*
640 5cdb1798 2005-10-29 devnull dowalk(Fid *f, char *name)
641 5cdb1798 2005-10-29 devnull {
642 5cdb1798 2005-10-29 devnull int t;
643 5cdb1798 2005-10-29 devnull Mailbox *omb, *mb;
644 5cdb1798 2005-10-29 devnull char *rv, *p;
645 5cdb1798 2005-10-29 devnull Hash *h;
646 5cdb1798 2005-10-29 devnull
647 5cdb1798 2005-10-29 devnull t = FILE(f->qid.path);
648 5cdb1798 2005-10-29 devnull
649 5cdb1798 2005-10-29 devnull rv = Enotexist;
650 5cdb1798 2005-10-29 devnull
651 5cdb1798 2005-10-29 devnull omb = f->mb;
652 5cdb1798 2005-10-29 devnull if(omb)
653 5cdb1798 2005-10-29 devnull qlock(&omb->ql);
654 5cdb1798 2005-10-29 devnull else
655 5cdb1798 2005-10-29 devnull qlock(&mbllock);
656 5cdb1798 2005-10-29 devnull
657 cbeb0b26 2006-04-01 devnull /* this must catch everything except . and .. */
658 5cdb1798 2005-10-29 devnull retry:
659 5cdb1798 2005-10-29 devnull h = hlook(f->qid.path, name);
660 5cdb1798 2005-10-29 devnull if(h != nil){
661 5cdb1798 2005-10-29 devnull f->mb = h->mb;
662 5cdb1798 2005-10-29 devnull f->m = h->m;
663 5cdb1798 2005-10-29 devnull switch(t){
664 5cdb1798 2005-10-29 devnull case Qtop:
665 5cdb1798 2005-10-29 devnull if(f->mb != nil)
666 5cdb1798 2005-10-29 devnull mboxincref(f->mb);
667 5cdb1798 2005-10-29 devnull break;
668 5cdb1798 2005-10-29 devnull case Qmbox:
669 5cdb1798 2005-10-29 devnull if(f->m){
670 5cdb1798 2005-10-29 devnull msgincref(f->m);
671 5cdb1798 2005-10-29 devnull f->mtop = f->m;
672 5cdb1798 2005-10-29 devnull }
673 5cdb1798 2005-10-29 devnull break;
674 5cdb1798 2005-10-29 devnull }
675 5cdb1798 2005-10-29 devnull f->qid = h->qid;
676 5cdb1798 2005-10-29 devnull rv = nil;
677 5cdb1798 2005-10-29 devnull } else if((p = strchr(name, '.')) != nil && *name != '.'){
678 5cdb1798 2005-10-29 devnull *p = 0;
679 5cdb1798 2005-10-29 devnull goto retry;
680 5cdb1798 2005-10-29 devnull }
681 5cdb1798 2005-10-29 devnull
682 5cdb1798 2005-10-29 devnull if(omb)
683 5cdb1798 2005-10-29 devnull qunlock(&omb->ql);
684 5cdb1798 2005-10-29 devnull else
685 5cdb1798 2005-10-29 devnull qunlock(&mbllock);
686 5cdb1798 2005-10-29 devnull if(rv == nil)
687 5cdb1798 2005-10-29 devnull return rv;
688 5cdb1798 2005-10-29 devnull
689 5cdb1798 2005-10-29 devnull if(strcmp(name, ".") == 0)
690 5cdb1798 2005-10-29 devnull return nil;
691 5cdb1798 2005-10-29 devnull
692 5cdb1798 2005-10-29 devnull if(f->qid.type != QTDIR)
693 5cdb1798 2005-10-29 devnull return Enotdir;
694 5cdb1798 2005-10-29 devnull
695 5cdb1798 2005-10-29 devnull if(strcmp(name, "..") == 0){
696 5cdb1798 2005-10-29 devnull switch(t){
697 5cdb1798 2005-10-29 devnull case Qtop:
698 5cdb1798 2005-10-29 devnull f->qid.path = PATH(0, Qtop);
699 5cdb1798 2005-10-29 devnull f->qid.type = QTDIR;
700 5cdb1798 2005-10-29 devnull f->qid.vers = 0;
701 5cdb1798 2005-10-29 devnull break;
702 5cdb1798 2005-10-29 devnull case Qmbox:
703 5cdb1798 2005-10-29 devnull f->qid.path = PATH(0, Qtop);
704 5cdb1798 2005-10-29 devnull f->qid.type = QTDIR;
705 5cdb1798 2005-10-29 devnull f->qid.vers = 0;
706 5cdb1798 2005-10-29 devnull qlock(&mbllock);
707 5cdb1798 2005-10-29 devnull mb = f->mb;
708 5cdb1798 2005-10-29 devnull f->mb = nil;
709 5cdb1798 2005-10-29 devnull mboxdecref(mb);
710 5cdb1798 2005-10-29 devnull qunlock(&mbllock);
711 5cdb1798 2005-10-29 devnull break;
712 5cdb1798 2005-10-29 devnull case Qdir:
713 5cdb1798 2005-10-29 devnull qlock(&f->mb->ql);
714 5cdb1798 2005-10-29 devnull if(f->m->whole == f->mb->root){
715 5cdb1798 2005-10-29 devnull f->qid.path = PATH(f->mb->id, Qmbox);
716 5cdb1798 2005-10-29 devnull f->qid.type = QTDIR;
717 5cdb1798 2005-10-29 devnull f->qid.vers = f->mb->d->qid.vers;
718 5cdb1798 2005-10-29 devnull msgdecref(f->mb, f->mtop);
719 5cdb1798 2005-10-29 devnull f->m = f->mtop = nil;
720 5cdb1798 2005-10-29 devnull } else {
721 5cdb1798 2005-10-29 devnull f->m = f->m->whole;
722 5cdb1798 2005-10-29 devnull f->qid.path = PATH(f->m->id, Qdir);
723 5cdb1798 2005-10-29 devnull f->qid.type = QTDIR;
724 5cdb1798 2005-10-29 devnull }
725 5cdb1798 2005-10-29 devnull qunlock(&f->mb->ql);
726 5cdb1798 2005-10-29 devnull break;
727 5cdb1798 2005-10-29 devnull }
728 5cdb1798 2005-10-29 devnull rv = nil;
729 5cdb1798 2005-10-29 devnull }
730 5cdb1798 2005-10-29 devnull return rv;
731 5cdb1798 2005-10-29 devnull }
732 5cdb1798 2005-10-29 devnull
733 5cdb1798 2005-10-29 devnull char*
734 5cdb1798 2005-10-29 devnull rwalk(Fid *f)
735 5cdb1798 2005-10-29 devnull {
736 5cdb1798 2005-10-29 devnull Fid *nf;
737 5cdb1798 2005-10-29 devnull char *rv;
738 5cdb1798 2005-10-29 devnull int i;
739 5cdb1798 2005-10-29 devnull
740 5cdb1798 2005-10-29 devnull if(f->open)
741 5cdb1798 2005-10-29 devnull return Eisopen;
742 5cdb1798 2005-10-29 devnull
743 5cdb1798 2005-10-29 devnull rhdr.nwqid = 0;
744 5cdb1798 2005-10-29 devnull nf = nil;
745 5cdb1798 2005-10-29 devnull
746 5cdb1798 2005-10-29 devnull /* clone if requested */
747 5cdb1798 2005-10-29 devnull if(thdr.newfid != thdr.fid){
748 5cdb1798 2005-10-29 devnull nf = doclone(f, thdr.newfid);
749 5cdb1798 2005-10-29 devnull if(nf == nil)
750 5cdb1798 2005-10-29 devnull return "new fid in use";
751 5cdb1798 2005-10-29 devnull f = nf;
752 5cdb1798 2005-10-29 devnull }
753 5cdb1798 2005-10-29 devnull
754 5cdb1798 2005-10-29 devnull /* if it's just a clone, return */
755 5cdb1798 2005-10-29 devnull if(thdr.nwname == 0 && nf != nil)
756 5cdb1798 2005-10-29 devnull return nil;
757 5cdb1798 2005-10-29 devnull
758 5cdb1798 2005-10-29 devnull /* walk each element */
759 5cdb1798 2005-10-29 devnull rv = nil;
760 5cdb1798 2005-10-29 devnull for(i = 0; i < thdr.nwname; i++){
761 5cdb1798 2005-10-29 devnull rv = dowalk(f, thdr.wname[i]);
762 5cdb1798 2005-10-29 devnull if(rv != nil){
763 5cdb1798 2005-10-29 devnull if(nf != nil)
764 5cdb1798 2005-10-29 devnull rclunk(nf);
765 5cdb1798 2005-10-29 devnull break;
766 5cdb1798 2005-10-29 devnull }
767 5cdb1798 2005-10-29 devnull rhdr.wqid[i] = f->qid;
768 5cdb1798 2005-10-29 devnull }
769 5cdb1798 2005-10-29 devnull rhdr.nwqid = i;
770 5cdb1798 2005-10-29 devnull
771 5cdb1798 2005-10-29 devnull /* we only error out if no walk */
772 5cdb1798 2005-10-29 devnull if(i > 0)
773 5cdb1798 2005-10-29 devnull rv = nil;
774 5cdb1798 2005-10-29 devnull
775 5cdb1798 2005-10-29 devnull return rv;
776 5cdb1798 2005-10-29 devnull }
777 5cdb1798 2005-10-29 devnull
778 5cdb1798 2005-10-29 devnull char *
779 5cdb1798 2005-10-29 devnull ropen(Fid *f)
780 5cdb1798 2005-10-29 devnull {
781 5cdb1798 2005-10-29 devnull int file;
782 5cdb1798 2005-10-29 devnull
783 5cdb1798 2005-10-29 devnull if(f->open)
784 5cdb1798 2005-10-29 devnull return Eisopen;
785 5cdb1798 2005-10-29 devnull
786 5cdb1798 2005-10-29 devnull file = FILE(f->qid.path);
787 5cdb1798 2005-10-29 devnull if(thdr.mode != OREAD)
788 5cdb1798 2005-10-29 devnull if(file != Qctl && file != Qmboxctl)
789 5cdb1798 2005-10-29 devnull return Eperm;
790 5cdb1798 2005-10-29 devnull
791 cbeb0b26 2006-04-01 devnull /* make sure we've decoded */
792 5cdb1798 2005-10-29 devnull if(file == Qbody){
793 5cdb1798 2005-10-29 devnull if(f->m->decoded == 0)
794 5cdb1798 2005-10-29 devnull decode(f->m);
795 5cdb1798 2005-10-29 devnull if(f->m->converted == 0)
796 5cdb1798 2005-10-29 devnull convert(f->m);
797 5cdb1798 2005-10-29 devnull }
798 5cdb1798 2005-10-29 devnull
799 5cdb1798 2005-10-29 devnull rhdr.iounit = 0;
800 5cdb1798 2005-10-29 devnull rhdr.qid = f->qid;
801 5cdb1798 2005-10-29 devnull f->open = 1;
802 5cdb1798 2005-10-29 devnull return 0;
803 5cdb1798 2005-10-29 devnull }
804 5cdb1798 2005-10-29 devnull
805 5cdb1798 2005-10-29 devnull char *
806 5cdb1798 2005-10-29 devnull rcreate(Fid* dummy)
807 5cdb1798 2005-10-29 devnull {
808 5cdb1798 2005-10-29 devnull return Eperm;
809 5cdb1798 2005-10-29 devnull }
810 5cdb1798 2005-10-29 devnull
811 5cdb1798 2005-10-29 devnull int
812 5cdb1798 2005-10-29 devnull readtopdir(Fid* dummy, uchar *buf, long off, int cnt, int blen)
813 5cdb1798 2005-10-29 devnull {
814 5cdb1798 2005-10-29 devnull Dir d;
815 5cdb1798 2005-10-29 devnull int m, n;
816 5cdb1798 2005-10-29 devnull long pos;
817 5cdb1798 2005-10-29 devnull Mailbox *mb;
818 5cdb1798 2005-10-29 devnull
819 5cdb1798 2005-10-29 devnull n = 0;
820 5cdb1798 2005-10-29 devnull pos = 0;
821 5cdb1798 2005-10-29 devnull mkstat(&d, nil, nil, Qctl);
822 5cdb1798 2005-10-29 devnull m = convD2M(&d, &buf[n], blen);
823 5cdb1798 2005-10-29 devnull if(off <= pos){
824 5cdb1798 2005-10-29 devnull if(m <= BIT16SZ || m > cnt)
825 5cdb1798 2005-10-29 devnull return 0;
826 5cdb1798 2005-10-29 devnull n += m;
827 5cdb1798 2005-10-29 devnull cnt -= m;
828 5cdb1798 2005-10-29 devnull }
829 5cdb1798 2005-10-29 devnull pos += m;
830 5cdb1798 2005-10-29 devnull
831 5cdb1798 2005-10-29 devnull for(mb = mbl; mb != nil; mb = mb->next){
832 5cdb1798 2005-10-29 devnull mkstat(&d, mb, nil, Qmbox);
833 5cdb1798 2005-10-29 devnull m = convD2M(&d, &buf[n], blen-n);
834 5cdb1798 2005-10-29 devnull if(off <= pos){
835 5cdb1798 2005-10-29 devnull if(m <= BIT16SZ || m > cnt)
836 5cdb1798 2005-10-29 devnull break;
837 5cdb1798 2005-10-29 devnull n += m;
838 5cdb1798 2005-10-29 devnull cnt -= m;
839 5cdb1798 2005-10-29 devnull }
840 5cdb1798 2005-10-29 devnull pos += m;
841 5cdb1798 2005-10-29 devnull }
842 5cdb1798 2005-10-29 devnull return n;
843 5cdb1798 2005-10-29 devnull }
844 5cdb1798 2005-10-29 devnull
845 5cdb1798 2005-10-29 devnull int
846 5cdb1798 2005-10-29 devnull readmboxdir(Fid *f, uchar *buf, long off, int cnt, int blen)
847 5cdb1798 2005-10-29 devnull {
848 5cdb1798 2005-10-29 devnull Dir d;
849 5cdb1798 2005-10-29 devnull int n, m;
850 5cdb1798 2005-10-29 devnull long pos;
851 5cdb1798 2005-10-29 devnull Message *msg;
852 5cdb1798 2005-10-29 devnull
853 5cdb1798 2005-10-29 devnull n = 0;
854 5cdb1798 2005-10-29 devnull if(f->mb->ctl){
855 5cdb1798 2005-10-29 devnull mkstat(&d, f->mb, nil, Qmboxctl);
856 5cdb1798 2005-10-29 devnull m = convD2M(&d, &buf[n], blen);
857 5cdb1798 2005-10-29 devnull if(off == 0){
858 5cdb1798 2005-10-29 devnull if(m <= BIT16SZ || m > cnt){
859 5cdb1798 2005-10-29 devnull f->fptr = nil;
860 5cdb1798 2005-10-29 devnull return 0;
861 5cdb1798 2005-10-29 devnull }
862 5cdb1798 2005-10-29 devnull n += m;
863 5cdb1798 2005-10-29 devnull cnt -= m;
864 5cdb1798 2005-10-29 devnull } else
865 5cdb1798 2005-10-29 devnull off -= m;
866 5cdb1798 2005-10-29 devnull }
867 5cdb1798 2005-10-29 devnull
868 cbeb0b26 2006-04-01 devnull /* to avoid n**2 reads of the directory, use a saved finger pointer */
869 5cdb1798 2005-10-29 devnull if(f->mb->vers == f->fvers && off >= f->foff && f->fptr != nil){
870 5cdb1798 2005-10-29 devnull msg = f->fptr;
871 5cdb1798 2005-10-29 devnull pos = f->foff;
872 5cdb1798 2005-10-29 devnull } else {
873 5cdb1798 2005-10-29 devnull msg = f->mb->root->part;
874 5cdb1798 2005-10-29 devnull pos = 0;
875 5cdb1798 2005-10-29 devnull }
876 5cdb1798 2005-10-29 devnull
877 5cdb1798 2005-10-29 devnull for(; cnt > 0 && msg != nil; msg = msg->next){
878 cbeb0b26 2006-04-01 devnull /* act like deleted files aren't there */
879 5cdb1798 2005-10-29 devnull if(msg->deleted)
880 5cdb1798 2005-10-29 devnull continue;
881 5cdb1798 2005-10-29 devnull
882 5cdb1798 2005-10-29 devnull mkstat(&d, f->mb, msg, Qdir);
883 5cdb1798 2005-10-29 devnull m = convD2M(&d, &buf[n], blen-n);
884 5cdb1798 2005-10-29 devnull if(off <= pos){
885 5cdb1798 2005-10-29 devnull if(m <= BIT16SZ || m > cnt)
886 5cdb1798 2005-10-29 devnull break;
887 5cdb1798 2005-10-29 devnull n += m;
888 5cdb1798 2005-10-29 devnull cnt -= m;
889 5cdb1798 2005-10-29 devnull }
890 5cdb1798 2005-10-29 devnull pos += m;
891 5cdb1798 2005-10-29 devnull }
892 5cdb1798 2005-10-29 devnull
893 cbeb0b26 2006-04-01 devnull /* save a finger pointer for next read of the mbox directory */
894 5cdb1798 2005-10-29 devnull f->foff = pos;
895 5cdb1798 2005-10-29 devnull f->fptr = msg;
896 5cdb1798 2005-10-29 devnull f->fvers = f->mb->vers;
897 5cdb1798 2005-10-29 devnull
898 5cdb1798 2005-10-29 devnull return n;
899 5cdb1798 2005-10-29 devnull }
900 5cdb1798 2005-10-29 devnull
901 5cdb1798 2005-10-29 devnull int
902 5cdb1798 2005-10-29 devnull readmsgdir(Fid *f, uchar *buf, long off, int cnt, int blen)
903 5cdb1798 2005-10-29 devnull {
904 5cdb1798 2005-10-29 devnull Dir d;
905 5cdb1798 2005-10-29 devnull int i, n, m;
906 5cdb1798 2005-10-29 devnull long pos;
907 5cdb1798 2005-10-29 devnull Message *msg;
908 5cdb1798 2005-10-29 devnull
909 5cdb1798 2005-10-29 devnull n = 0;
910 5cdb1798 2005-10-29 devnull pos = 0;
911 5cdb1798 2005-10-29 devnull for(i = 0; i < Qmax; i++){
912 5cdb1798 2005-10-29 devnull mkstat(&d, f->mb, f->m, i);
913 5cdb1798 2005-10-29 devnull m = convD2M(&d, &buf[n], blen-n);
914 5cdb1798 2005-10-29 devnull if(off <= pos){
915 5cdb1798 2005-10-29 devnull if(m <= BIT16SZ || m > cnt)
916 5cdb1798 2005-10-29 devnull return n;
917 5cdb1798 2005-10-29 devnull n += m;
918 5cdb1798 2005-10-29 devnull cnt -= m;
919 5cdb1798 2005-10-29 devnull }
920 5cdb1798 2005-10-29 devnull pos += m;
921 5cdb1798 2005-10-29 devnull }
922 5cdb1798 2005-10-29 devnull for(msg = f->m->part; msg != nil; msg = msg->next){
923 5cdb1798 2005-10-29 devnull mkstat(&d, f->mb, msg, Qdir);
924 5cdb1798 2005-10-29 devnull m = convD2M(&d, &buf[n], blen-n);
925 5cdb1798 2005-10-29 devnull if(off <= pos){
926 5cdb1798 2005-10-29 devnull if(m <= BIT16SZ || m > cnt)
927 5cdb1798 2005-10-29 devnull break;
928 5cdb1798 2005-10-29 devnull n += m;
929 5cdb1798 2005-10-29 devnull cnt -= m;
930 5cdb1798 2005-10-29 devnull }
931 5cdb1798 2005-10-29 devnull pos += m;
932 5cdb1798 2005-10-29 devnull }
933 5cdb1798 2005-10-29 devnull
934 5cdb1798 2005-10-29 devnull return n;
935 5cdb1798 2005-10-29 devnull }
936 5cdb1798 2005-10-29 devnull
937 5cdb1798 2005-10-29 devnull char*
938 5cdb1798 2005-10-29 devnull rread(Fid *f)
939 5cdb1798 2005-10-29 devnull {
940 5cdb1798 2005-10-29 devnull long off;
941 5cdb1798 2005-10-29 devnull int t, i, n, cnt;
942 5cdb1798 2005-10-29 devnull char *p;
943 5cdb1798 2005-10-29 devnull
944 5cdb1798 2005-10-29 devnull rhdr.count = 0;
945 5cdb1798 2005-10-29 devnull off = thdr.offset;
946 5cdb1798 2005-10-29 devnull cnt = thdr.count;
947 5cdb1798 2005-10-29 devnull
948 5cdb1798 2005-10-29 devnull if(cnt > messagesize - IOHDRSZ)
949 5cdb1798 2005-10-29 devnull cnt = messagesize - IOHDRSZ;
950 5cdb1798 2005-10-29 devnull
951 5cdb1798 2005-10-29 devnull rhdr.data = (char*)mbuf;
952 5cdb1798 2005-10-29 devnull
953 5cdb1798 2005-10-29 devnull t = FILE(f->qid.path);
954 5cdb1798 2005-10-29 devnull if(f->qid.type & QTDIR){
955 5cdb1798 2005-10-29 devnull if(t == Qtop) {
956 5cdb1798 2005-10-29 devnull qlock(&mbllock);
957 5cdb1798 2005-10-29 devnull n = readtopdir(f, mbuf, off, cnt, messagesize - IOHDRSZ);
958 5cdb1798 2005-10-29 devnull qunlock(&mbllock);
959 5cdb1798 2005-10-29 devnull } else if(t == Qmbox) {
960 5cdb1798 2005-10-29 devnull qlock(&f->mb->ql);
961 5cdb1798 2005-10-29 devnull if(off == 0)
962 5cdb1798 2005-10-29 devnull syncmbox(f->mb, 1);
963 5cdb1798 2005-10-29 devnull n = readmboxdir(f, mbuf, off, cnt, messagesize - IOHDRSZ);
964 5cdb1798 2005-10-29 devnull qunlock(&f->mb->ql);
965 5cdb1798 2005-10-29 devnull } else if(t == Qmboxctl) {
966 5cdb1798 2005-10-29 devnull n = 0;
967 5cdb1798 2005-10-29 devnull } else {
968 5cdb1798 2005-10-29 devnull n = readmsgdir(f, mbuf, off, cnt, messagesize - IOHDRSZ);
969 5cdb1798 2005-10-29 devnull }
970 5cdb1798 2005-10-29 devnull
971 5cdb1798 2005-10-29 devnull rhdr.count = n;
972 5cdb1798 2005-10-29 devnull return nil;
973 5cdb1798 2005-10-29 devnull }
974 5cdb1798 2005-10-29 devnull
975 5cdb1798 2005-10-29 devnull if(FILE(f->qid.path) == Qheader){
976 5cdb1798 2005-10-29 devnull rhdr.count = readheader(f->m, (char*)mbuf, off, cnt);
977 5cdb1798 2005-10-29 devnull return nil;
978 5cdb1798 2005-10-29 devnull }
979 5cdb1798 2005-10-29 devnull
980 5cdb1798 2005-10-29 devnull if(FILE(f->qid.path) == Qinfo){
981 5cdb1798 2005-10-29 devnull rhdr.count = readinfo(f->m, (char*)mbuf, off, cnt);
982 5cdb1798 2005-10-29 devnull return nil;
983 5cdb1798 2005-10-29 devnull }
984 5cdb1798 2005-10-29 devnull
985 5cdb1798 2005-10-29 devnull i = fileinfo(f->m, FILE(f->qid.path), &p);
986 5cdb1798 2005-10-29 devnull if(off < i){
987 5cdb1798 2005-10-29 devnull if((off + cnt) > i)
988 5cdb1798 2005-10-29 devnull cnt = i - off;
989 5cdb1798 2005-10-29 devnull memmove(mbuf, p + off, cnt);
990 5cdb1798 2005-10-29 devnull rhdr.count = cnt;
991 5cdb1798 2005-10-29 devnull }
992 5cdb1798 2005-10-29 devnull return nil;
993 5cdb1798 2005-10-29 devnull }
994 5cdb1798 2005-10-29 devnull
995 5cdb1798 2005-10-29 devnull char*
996 5cdb1798 2005-10-29 devnull rwrite(Fid *f)
997 5cdb1798 2005-10-29 devnull {
998 5cdb1798 2005-10-29 devnull char *err;
999 5cdb1798 2005-10-29 devnull char *token[1024];
1000 5cdb1798 2005-10-29 devnull int t, n;
1001 5cdb1798 2005-10-29 devnull String *file;
1002 5cdb1798 2005-10-29 devnull
1003 5cdb1798 2005-10-29 devnull t = FILE(f->qid.path);
1004 5cdb1798 2005-10-29 devnull rhdr.count = thdr.count;
1005 5cdb1798 2005-10-29 devnull switch(t){
1006 5cdb1798 2005-10-29 devnull case Qctl:
1007 5cdb1798 2005-10-29 devnull if(thdr.count == 0)
1008 5cdb1798 2005-10-29 devnull return Ebadctl;
1009 5cdb1798 2005-10-29 devnull if(thdr.data[thdr.count-1] == '\n')
1010 5cdb1798 2005-10-29 devnull thdr.data[thdr.count-1] = 0;
1011 5cdb1798 2005-10-29 devnull else
1012 5cdb1798 2005-10-29 devnull thdr.data[thdr.count] = 0;
1013 5cdb1798 2005-10-29 devnull n = tokenize(thdr.data, token, nelem(token));
1014 5cdb1798 2005-10-29 devnull if(n == 0)
1015 5cdb1798 2005-10-29 devnull return Ebadctl;
1016 5cdb1798 2005-10-29 devnull if(strcmp(token[0], "open") == 0){
1017 5cdb1798 2005-10-29 devnull file = s_new();
1018 5cdb1798 2005-10-29 devnull switch(n){
1019 5cdb1798 2005-10-29 devnull case 1:
1020 5cdb1798 2005-10-29 devnull err = Ebadctl;
1021 5cdb1798 2005-10-29 devnull break;
1022 5cdb1798 2005-10-29 devnull case 2:
1023 5cdb1798 2005-10-29 devnull mboxpath(token[1], getlog(), file, 0);
1024 5cdb1798 2005-10-29 devnull err = newmbox(s_to_c(file), nil, 0);
1025 5cdb1798 2005-10-29 devnull break;
1026 5cdb1798 2005-10-29 devnull default:
1027 5cdb1798 2005-10-29 devnull mboxpath(token[1], getlog(), file, 0);
1028 5cdb1798 2005-10-29 devnull if(strchr(token[2], '/') != nil)
1029 5cdb1798 2005-10-29 devnull err = "/ not allowed in mailbox name";
1030 5cdb1798 2005-10-29 devnull else
1031 5cdb1798 2005-10-29 devnull err = newmbox(s_to_c(file), token[2], 0);
1032 5cdb1798 2005-10-29 devnull break;
1033 5cdb1798 2005-10-29 devnull }
1034 5cdb1798 2005-10-29 devnull s_free(file);
1035 5cdb1798 2005-10-29 devnull return err;
1036 5cdb1798 2005-10-29 devnull }
1037 5cdb1798 2005-10-29 devnull if(strcmp(token[0], "close") == 0){
1038 5cdb1798 2005-10-29 devnull if(n < 2)
1039 5cdb1798 2005-10-29 devnull return nil;
1040 5cdb1798 2005-10-29 devnull freembox(token[1]);
1041 5cdb1798 2005-10-29 devnull return nil;
1042 5cdb1798 2005-10-29 devnull }
1043 5cdb1798 2005-10-29 devnull if(strcmp(token[0], "delete") == 0){
1044 5cdb1798 2005-10-29 devnull if(n < 3)
1045 5cdb1798 2005-10-29 devnull return nil;
1046 5cdb1798 2005-10-29 devnull delmessages(n-1, &token[1]);
1047 5cdb1798 2005-10-29 devnull return nil;
1048 5cdb1798 2005-10-29 devnull }
1049 5cdb1798 2005-10-29 devnull return Ebadctl;
1050 5cdb1798 2005-10-29 devnull case Qmboxctl:
1051 5cdb1798 2005-10-29 devnull if(f->mb && f->mb->ctl){
1052 5cdb1798 2005-10-29 devnull if(thdr.count == 0)
1053 5cdb1798 2005-10-29 devnull return Ebadctl;
1054 5cdb1798 2005-10-29 devnull if(thdr.data[thdr.count-1] == '\n')
1055 5cdb1798 2005-10-29 devnull thdr.data[thdr.count-1] = 0;
1056 5cdb1798 2005-10-29 devnull else
1057 5cdb1798 2005-10-29 devnull thdr.data[thdr.count] = 0;
1058 5cdb1798 2005-10-29 devnull n = tokenize(thdr.data, token, nelem(token));
1059 5cdb1798 2005-10-29 devnull if(n == 0)
1060 5cdb1798 2005-10-29 devnull return Ebadctl;
1061 5cdb1798 2005-10-29 devnull return (*f->mb->ctl)(f->mb, n, token);
1062 5cdb1798 2005-10-29 devnull }
1063 5cdb1798 2005-10-29 devnull }
1064 5cdb1798 2005-10-29 devnull return Eperm;
1065 5cdb1798 2005-10-29 devnull }
1066 5cdb1798 2005-10-29 devnull
1067 5cdb1798 2005-10-29 devnull char *
1068 5cdb1798 2005-10-29 devnull rclunk(Fid *f)
1069 5cdb1798 2005-10-29 devnull {
1070 5cdb1798 2005-10-29 devnull Mailbox *mb;
1071 5cdb1798 2005-10-29 devnull
1072 5cdb1798 2005-10-29 devnull f->busy = 0;
1073 5cdb1798 2005-10-29 devnull f->open = 0;
1074 5cdb1798 2005-10-29 devnull if(f->mtop != nil){
1075 5cdb1798 2005-10-29 devnull qlock(&f->mb->ql);
1076 5cdb1798 2005-10-29 devnull msgdecref(f->mb, f->mtop);
1077 5cdb1798 2005-10-29 devnull qunlock(&f->mb->ql);
1078 5cdb1798 2005-10-29 devnull }
1079 5cdb1798 2005-10-29 devnull f->m = f->mtop = nil;
1080 5cdb1798 2005-10-29 devnull mb = f->mb;
1081 5cdb1798 2005-10-29 devnull if(mb != nil){
1082 5cdb1798 2005-10-29 devnull f->mb = nil;
1083 5cdb1798 2005-10-29 devnull assert(mb->refs > 0);
1084 5cdb1798 2005-10-29 devnull qlock(&mbllock);
1085 5cdb1798 2005-10-29 devnull mboxdecref(mb);
1086 5cdb1798 2005-10-29 devnull qunlock(&mbllock);
1087 5cdb1798 2005-10-29 devnull }
1088 5cdb1798 2005-10-29 devnull f->fid = -1;
1089 5cdb1798 2005-10-29 devnull return 0;
1090 5cdb1798 2005-10-29 devnull }
1091 5cdb1798 2005-10-29 devnull
1092 5cdb1798 2005-10-29 devnull char *
1093 5cdb1798 2005-10-29 devnull rremove(Fid *f)
1094 5cdb1798 2005-10-29 devnull {
1095 5cdb1798 2005-10-29 devnull if(f->m != nil){
1096 5cdb1798 2005-10-29 devnull if(f->m->deleted == 0)
1097 5cdb1798 2005-10-29 devnull mailplumb(f->mb, f->m, 1);
1098 5cdb1798 2005-10-29 devnull f->m->deleted = 1;
1099 5cdb1798 2005-10-29 devnull }
1100 5cdb1798 2005-10-29 devnull return rclunk(f);
1101 5cdb1798 2005-10-29 devnull }
1102 5cdb1798 2005-10-29 devnull
1103 5cdb1798 2005-10-29 devnull char *
1104 5cdb1798 2005-10-29 devnull rstat(Fid *f)
1105 5cdb1798 2005-10-29 devnull {
1106 5cdb1798 2005-10-29 devnull Dir d;
1107 5cdb1798 2005-10-29 devnull
1108 5cdb1798 2005-10-29 devnull if(FILE(f->qid.path) == Qmbox){
1109 5cdb1798 2005-10-29 devnull qlock(&f->mb->ql);
1110 5cdb1798 2005-10-29 devnull syncmbox(f->mb, 1);
1111 5cdb1798 2005-10-29 devnull qunlock(&f->mb->ql);
1112 5cdb1798 2005-10-29 devnull }
1113 5cdb1798 2005-10-29 devnull mkstat(&d, f->mb, f->m, FILE(f->qid.path));
1114 5cdb1798 2005-10-29 devnull rhdr.nstat = convD2M(&d, mbuf, messagesize - IOHDRSZ);
1115 5cdb1798 2005-10-29 devnull rhdr.stat = mbuf;
1116 5cdb1798 2005-10-29 devnull return 0;
1117 5cdb1798 2005-10-29 devnull }
1118 5cdb1798 2005-10-29 devnull
1119 5cdb1798 2005-10-29 devnull char *
1120 5cdb1798 2005-10-29 devnull rwstat(Fid* dummy)
1121 5cdb1798 2005-10-29 devnull {
1122 5cdb1798 2005-10-29 devnull return Eperm;
1123 5cdb1798 2005-10-29 devnull }
1124 5cdb1798 2005-10-29 devnull
1125 5cdb1798 2005-10-29 devnull Fid *
1126 5cdb1798 2005-10-29 devnull newfid(int fid)
1127 5cdb1798 2005-10-29 devnull {
1128 5cdb1798 2005-10-29 devnull Fid *f, *ff;
1129 5cdb1798 2005-10-29 devnull
1130 5cdb1798 2005-10-29 devnull ff = 0;
1131 5cdb1798 2005-10-29 devnull for(f = fids; f; f = f->next)
1132 5cdb1798 2005-10-29 devnull if(f->fid == fid)
1133 5cdb1798 2005-10-29 devnull return f;
1134 5cdb1798 2005-10-29 devnull else if(!ff && !f->busy)
1135 5cdb1798 2005-10-29 devnull ff = f;
1136 5cdb1798 2005-10-29 devnull if(ff){
1137 5cdb1798 2005-10-29 devnull ff->fid = fid;
1138 5cdb1798 2005-10-29 devnull ff->fptr = nil;
1139 5cdb1798 2005-10-29 devnull return ff;
1140 5cdb1798 2005-10-29 devnull }
1141 5cdb1798 2005-10-29 devnull f = emalloc(sizeof *f);
1142 5cdb1798 2005-10-29 devnull f->fid = fid;
1143 5cdb1798 2005-10-29 devnull f->fptr = nil;
1144 5cdb1798 2005-10-29 devnull f->next = fids;
1145 5cdb1798 2005-10-29 devnull fids = f;
1146 5cdb1798 2005-10-29 devnull return f;
1147 5cdb1798 2005-10-29 devnull }
1148 5cdb1798 2005-10-29 devnull
1149 5cdb1798 2005-10-29 devnull int
1150 5cdb1798 2005-10-29 devnull fidmboxrefs(Mailbox *mb)
1151 5cdb1798 2005-10-29 devnull {
1152 5cdb1798 2005-10-29 devnull Fid *f;
1153 5cdb1798 2005-10-29 devnull int refs = 0;
1154 5cdb1798 2005-10-29 devnull
1155 5cdb1798 2005-10-29 devnull for(f = fids; f; f = f->next){
1156 5cdb1798 2005-10-29 devnull if(f->mb == mb)
1157 5cdb1798 2005-10-29 devnull refs++;
1158 5cdb1798 2005-10-29 devnull }
1159 5cdb1798 2005-10-29 devnull return refs;
1160 5cdb1798 2005-10-29 devnull }
1161 5cdb1798 2005-10-29 devnull
1162 5cdb1798 2005-10-29 devnull void
1163 5cdb1798 2005-10-29 devnull io(void)
1164 5cdb1798 2005-10-29 devnull {
1165 5cdb1798 2005-10-29 devnull char *err;
1166 5cdb1798 2005-10-29 devnull int n, nw;
1167 5cdb1798 2005-10-29 devnull
1168 5cdb1798 2005-10-29 devnull /* start a process to watch the mailboxes*/
1169 5cdb1798 2005-10-29 devnull if(plumbing){
1170 5cdb1798 2005-10-29 devnull proccreate(reader, nil, 16000);
1171 5cdb1798 2005-10-29 devnull #if 0 /* jpc */
1172 5cdb1798 2005-10-29 devnull switch(rfork(RFPROC|RFMEM)){
1173 5cdb1798 2005-10-29 devnull case -1:
1174 5cdb1798 2005-10-29 devnull /* oh well */
1175 5cdb1798 2005-10-29 devnull break;
1176 5cdb1798 2005-10-29 devnull case 0:
1177 5cdb1798 2005-10-29 devnull reader();
1178 5cdb1798 2005-10-29 devnull threadexits(nil);
1179 5cdb1798 2005-10-29 devnull default:
1180 5cdb1798 2005-10-29 devnull break;
1181 5cdb1798 2005-10-29 devnull }
1182 5cdb1798 2005-10-29 devnull #endif /* jpc */
1183 5cdb1798 2005-10-29 devnull }
1184 5cdb1798 2005-10-29 devnull
1185 5cdb1798 2005-10-29 devnull for(;;){
1186 5cdb1798 2005-10-29 devnull /*
1187 5cdb1798 2005-10-29 devnull * reading from a pipe or a network device
1188 5cdb1798 2005-10-29 devnull * will give an error after a few eof reads
1189 5cdb1798 2005-10-29 devnull * however, we cannot tell the difference
1190 5cdb1798 2005-10-29 devnull * between a zero-length read and an interrupt
1191 5cdb1798 2005-10-29 devnull * on the processes writing to us,
1192 5cdb1798 2005-10-29 devnull * so we wait for the error
1193 5cdb1798 2005-10-29 devnull */
1194 5cdb1798 2005-10-29 devnull checkmboxrefs();
1195 5cdb1798 2005-10-29 devnull n = read9pmsg(mfd[0], mdata, messagesize);
1196 5cdb1798 2005-10-29 devnull if(n == 0)
1197 5cdb1798 2005-10-29 devnull continue;
1198 5cdb1798 2005-10-29 devnull if(n < 0)
1199 5cdb1798 2005-10-29 devnull return;
1200 5cdb1798 2005-10-29 devnull if(convM2S(mdata, n, &thdr) == 0)
1201 5cdb1798 2005-10-29 devnull continue;
1202 5cdb1798 2005-10-29 devnull
1203 5cdb1798 2005-10-29 devnull if(debug)
1204 5cdb1798 2005-10-29 devnull fprint(2, "%s:<-%F\n", argv0, &thdr);
1205 5cdb1798 2005-10-29 devnull
1206 5cdb1798 2005-10-29 devnull rhdr.data = (char*)mdata + messagesize;
1207 5cdb1798 2005-10-29 devnull if(!fcalls[thdr.type])
1208 5cdb1798 2005-10-29 devnull err = "bad fcall type";
1209 5cdb1798 2005-10-29 devnull else
1210 5cdb1798 2005-10-29 devnull err = (*fcalls[thdr.type])(newfid(thdr.fid));
1211 5cdb1798 2005-10-29 devnull if(err){
1212 5cdb1798 2005-10-29 devnull rhdr.type = Rerror;
1213 5cdb1798 2005-10-29 devnull rhdr.ename = err;
1214 5cdb1798 2005-10-29 devnull }else{
1215 5cdb1798 2005-10-29 devnull rhdr.type = thdr.type + 1;
1216 5cdb1798 2005-10-29 devnull rhdr.fid = thdr.fid;
1217 5cdb1798 2005-10-29 devnull }
1218 5cdb1798 2005-10-29 devnull rhdr.tag = thdr.tag;
1219 5cdb1798 2005-10-29 devnull if(debug)
1220 5cdb1798 2005-10-29 devnull fprint(2, "%s:->%F\n", argv0, &rhdr);/**/
1221 5cdb1798 2005-10-29 devnull n = convS2M(&rhdr, mdata, messagesize);
1222 5cdb1798 2005-10-29 devnull if((nw = write(mfd[1], mdata, n)) != n) {
1223 5cdb1798 2005-10-29 devnull fprint(2,"wrote %d bytes\n",nw);
1224 5cdb1798 2005-10-29 devnull error("mount write");
1225 5cdb1798 2005-10-29 devnull }
1226 5cdb1798 2005-10-29 devnull }
1227 5cdb1798 2005-10-29 devnull }
1228 5cdb1798 2005-10-29 devnull
1229 5cdb1798 2005-10-29 devnull void
1230 5cdb1798 2005-10-29 devnull reader(void *dummy)
1231 5cdb1798 2005-10-29 devnull {
1232 5cdb1798 2005-10-29 devnull ulong t;
1233 5cdb1798 2005-10-29 devnull Dir *d;
1234 5cdb1798 2005-10-29 devnull Mailbox *mb;
1235 5cdb1798 2005-10-29 devnull
1236 5cdb1798 2005-10-29 devnull sleep(15*1000);
1237 5cdb1798 2005-10-29 devnull for(;;){
1238 5cdb1798 2005-10-29 devnull t = time(0);
1239 5cdb1798 2005-10-29 devnull qlock(&mbllock);
1240 5cdb1798 2005-10-29 devnull for(mb = mbl; mb != nil; mb = mb->next){
1241 5cdb1798 2005-10-29 devnull assert(mb->refs > 0);
1242 5cdb1798 2005-10-29 devnull if(mb->waketime != 0 && t > mb->waketime){
1243 5cdb1798 2005-10-29 devnull qlock(&mb->ql);
1244 5cdb1798 2005-10-29 devnull mb->waketime = 0;
1245 5cdb1798 2005-10-29 devnull break;
1246 5cdb1798 2005-10-29 devnull }
1247 5cdb1798 2005-10-29 devnull
1248 5cdb1798 2005-10-29 devnull d = dirstat(mb->path);
1249 5cdb1798 2005-10-29 devnull if(d == nil)
1250 5cdb1798 2005-10-29 devnull continue;
1251 5cdb1798 2005-10-29 devnull
1252 5cdb1798 2005-10-29 devnull qlock(&mb->ql);
1253 5cdb1798 2005-10-29 devnull if(mb->d)
1254 5cdb1798 2005-10-29 devnull if(d->qid.path != mb->d->qid.path
1255 5cdb1798 2005-10-29 devnull || d->qid.vers != mb->d->qid.vers){
1256 5cdb1798 2005-10-29 devnull free(d);
1257 5cdb1798 2005-10-29 devnull break;
1258 5cdb1798 2005-10-29 devnull }
1259 5cdb1798 2005-10-29 devnull qunlock(&mb->ql);
1260 5cdb1798 2005-10-29 devnull free(d);
1261 5cdb1798 2005-10-29 devnull }
1262 5cdb1798 2005-10-29 devnull qunlock(&mbllock);
1263 5cdb1798 2005-10-29 devnull if(mb != nil){
1264 5cdb1798 2005-10-29 devnull syncmbox(mb, 1);
1265 5cdb1798 2005-10-29 devnull qunlock(&mb->ql);
1266 5cdb1798 2005-10-29 devnull } else
1267 5cdb1798 2005-10-29 devnull sleep(15*1000);
1268 5cdb1798 2005-10-29 devnull }
1269 5cdb1798 2005-10-29 devnull }
1270 5cdb1798 2005-10-29 devnull
1271 5cdb1798 2005-10-29 devnull int
1272 5cdb1798 2005-10-29 devnull newid(void)
1273 5cdb1798 2005-10-29 devnull {
1274 5cdb1798 2005-10-29 devnull int rv;
1275 5cdb1798 2005-10-29 devnull static int id;
1276 5cdb1798 2005-10-29 devnull static Lock idlock;
1277 5cdb1798 2005-10-29 devnull
1278 5cdb1798 2005-10-29 devnull lock(&idlock);
1279 5cdb1798 2005-10-29 devnull rv = ++id;
1280 5cdb1798 2005-10-29 devnull unlock(&idlock);
1281 5cdb1798 2005-10-29 devnull
1282 5cdb1798 2005-10-29 devnull return rv;
1283 5cdb1798 2005-10-29 devnull }
1284 5cdb1798 2005-10-29 devnull
1285 5cdb1798 2005-10-29 devnull void
1286 5cdb1798 2005-10-29 devnull error(char *s)
1287 5cdb1798 2005-10-29 devnull {
1288 5cdb1798 2005-10-29 devnull postnote(PNGROUP, getpid(), "die yankee pig dog");
1289 5cdb1798 2005-10-29 devnull fprint(2, "%s: %s: %r\n", argv0, s);
1290 5cdb1798 2005-10-29 devnull threadexits(s);
1291 5cdb1798 2005-10-29 devnull }
1292 5cdb1798 2005-10-29 devnull
1293 5cdb1798 2005-10-29 devnull
1294 5cdb1798 2005-10-29 devnull typedef struct Ignorance Ignorance;
1295 5cdb1798 2005-10-29 devnull struct Ignorance
1296 5cdb1798 2005-10-29 devnull {
1297 5cdb1798 2005-10-29 devnull Ignorance *next;
1298 5cdb1798 2005-10-29 devnull char *str; /* string */
1299 5cdb1798 2005-10-29 devnull int partial; /* true if not exact match */
1300 5cdb1798 2005-10-29 devnull };
1301 5cdb1798 2005-10-29 devnull Ignorance *ignorance;
1302 5cdb1798 2005-10-29 devnull
1303 5cdb1798 2005-10-29 devnull /*
1304 5cdb1798 2005-10-29 devnull * read the file of headers to ignore
1305 5cdb1798 2005-10-29 devnull */
1306 5cdb1798 2005-10-29 devnull void
1307 5cdb1798 2005-10-29 devnull readignore(void)
1308 5cdb1798 2005-10-29 devnull {
1309 5cdb1798 2005-10-29 devnull char *p;
1310 5cdb1798 2005-10-29 devnull Ignorance *i;
1311 5cdb1798 2005-10-29 devnull Biobuf *b;
1312 5cdb1798 2005-10-29 devnull
1313 5cdb1798 2005-10-29 devnull if(ignorance != nil)
1314 5cdb1798 2005-10-29 devnull return;
1315 5cdb1798 2005-10-29 devnull
1316 5cdb1798 2005-10-29 devnull b = Bopen("/mail/lib/ignore", OREAD);
1317 5cdb1798 2005-10-29 devnull if(b == 0)
1318 5cdb1798 2005-10-29 devnull return;
1319 5cdb1798 2005-10-29 devnull while(p = Brdline(b, '\n')){
1320 5cdb1798 2005-10-29 devnull p[Blinelen(b)-1] = 0;
1321 5cdb1798 2005-10-29 devnull while(*p && (*p == ' ' || *p == '\t'))
1322 5cdb1798 2005-10-29 devnull p++;
1323 5cdb1798 2005-10-29 devnull if(*p == '#')
1324 5cdb1798 2005-10-29 devnull continue;
1325 5cdb1798 2005-10-29 devnull i = malloc(sizeof(Ignorance));
1326 5cdb1798 2005-10-29 devnull if(i == 0)
1327 5cdb1798 2005-10-29 devnull break;
1328 5cdb1798 2005-10-29 devnull i->partial = strlen(p);
1329 5cdb1798 2005-10-29 devnull i->str = strdup(p);
1330 5cdb1798 2005-10-29 devnull if(i->str == 0){
1331 5cdb1798 2005-10-29 devnull free(i);
1332 5cdb1798 2005-10-29 devnull break;
1333 5cdb1798 2005-10-29 devnull }
1334 5cdb1798 2005-10-29 devnull i->next = ignorance;
1335 5cdb1798 2005-10-29 devnull ignorance = i;
1336 5cdb1798 2005-10-29 devnull }
1337 5cdb1798 2005-10-29 devnull Bterm(b);
1338 5cdb1798 2005-10-29 devnull }
1339 5cdb1798 2005-10-29 devnull
1340 5cdb1798 2005-10-29 devnull int
1341 5cdb1798 2005-10-29 devnull ignore(char *p)
1342 5cdb1798 2005-10-29 devnull {
1343 5cdb1798 2005-10-29 devnull Ignorance *i;
1344 5cdb1798 2005-10-29 devnull
1345 5cdb1798 2005-10-29 devnull readignore();
1346 5cdb1798 2005-10-29 devnull for(i = ignorance; i != nil; i = i->next)
1347 5cdb1798 2005-10-29 devnull if(cistrncmp(i->str, p, i->partial) == 0)
1348 5cdb1798 2005-10-29 devnull return 1;
1349 5cdb1798 2005-10-29 devnull return 0;
1350 5cdb1798 2005-10-29 devnull }
1351 5cdb1798 2005-10-29 devnull
1352 5cdb1798 2005-10-29 devnull int
1353 5cdb1798 2005-10-29 devnull hdrlen(char *p, char *e)
1354 5cdb1798 2005-10-29 devnull {
1355 5cdb1798 2005-10-29 devnull char *ep;
1356 5cdb1798 2005-10-29 devnull
1357 5cdb1798 2005-10-29 devnull ep = p;
1358 5cdb1798 2005-10-29 devnull do {
1359 5cdb1798 2005-10-29 devnull ep = strchr(ep, '\n');
1360 5cdb1798 2005-10-29 devnull if(ep == nil){
1361 5cdb1798 2005-10-29 devnull ep = e;
1362 5cdb1798 2005-10-29 devnull break;
1363 5cdb1798 2005-10-29 devnull }
1364 5cdb1798 2005-10-29 devnull ep++;
1365 5cdb1798 2005-10-29 devnull if(ep >= e){
1366 5cdb1798 2005-10-29 devnull ep = e;
1367 5cdb1798 2005-10-29 devnull break;
1368 5cdb1798 2005-10-29 devnull }
1369 5cdb1798 2005-10-29 devnull } while(*ep == ' ' || *ep == '\t');
1370 5cdb1798 2005-10-29 devnull return ep - p;
1371 5cdb1798 2005-10-29 devnull }
1372 5cdb1798 2005-10-29 devnull
1373 cbeb0b26 2006-04-01 devnull /* rfc2047 non-ascii */
1374 5cdb1798 2005-10-29 devnull typedef struct Charset Charset;
1375 5cdb1798 2005-10-29 devnull struct Charset {
1376 5cdb1798 2005-10-29 devnull char *name;
1377 5cdb1798 2005-10-29 devnull int len;
1378 5cdb1798 2005-10-29 devnull int convert;
1379 5cdb1798 2005-10-29 devnull char *tcsname;
1380 5cdb1798 2005-10-29 devnull } charsets[] =
1381 5cdb1798 2005-10-29 devnull {
1382 5cdb1798 2005-10-29 devnull { "us-ascii", 8, 1, nil, },
1383 5cdb1798 2005-10-29 devnull { "utf-8", 5, 0, nil, },
1384 5cdb1798 2005-10-29 devnull { "iso-8859-1", 10, 1, nil, },
1385 5cdb1798 2005-10-29 devnull { "iso-8859-2", 10, 2, "8859-2", },
1386 5cdb1798 2005-10-29 devnull { "big5", 4, 2, "big5", },
1387 5cdb1798 2005-10-29 devnull { "iso-2022-jp", 11, 2, "jis", },
1388 5cdb1798 2005-10-29 devnull { "windows-1251", 12, 2, "cp1251"},
1389 cbeb0b26 2006-04-01 devnull { "koi8-r", 6, 2, "koi8"}
1390 5cdb1798 2005-10-29 devnull };
1391 5cdb1798 2005-10-29 devnull
1392 5cdb1798 2005-10-29 devnull int
1393 5cdb1798 2005-10-29 devnull rfc2047convert(String *s, char *token, int len)
1394 5cdb1798 2005-10-29 devnull {
1395 5cdb1798 2005-10-29 devnull char decoded[1024];
1396 5cdb1798 2005-10-29 devnull char utfbuf[2*1024];
1397 5cdb1798 2005-10-29 devnull int i;
1398 5cdb1798 2005-10-29 devnull char *e, *x;
1399 5cdb1798 2005-10-29 devnull
1400 5cdb1798 2005-10-29 devnull if(len == 0)
1401 5cdb1798 2005-10-29 devnull return -1;
1402 5cdb1798 2005-10-29 devnull
1403 5cdb1798 2005-10-29 devnull e = token+len-2;
1404 5cdb1798 2005-10-29 devnull token += 2;
1405 5cdb1798 2005-10-29 devnull
1406 cbeb0b26 2006-04-01 devnull /* bail if we don't understand the character set */
1407 5cdb1798 2005-10-29 devnull for(i = 0; i < nelem(charsets); i++)
1408 5cdb1798 2005-10-29 devnull if(cistrncmp(charsets[i].name, token, charsets[i].len) == 0)
1409 5cdb1798 2005-10-29 devnull if(token[charsets[i].len] == '?'){
1410 5cdb1798 2005-10-29 devnull token += charsets[i].len + 1;
1411 5cdb1798 2005-10-29 devnull break;
1412 5cdb1798 2005-10-29 devnull }
1413 5cdb1798 2005-10-29 devnull if(i >= nelem(charsets))
1414 5cdb1798 2005-10-29 devnull return -1;
1415 5cdb1798 2005-10-29 devnull
1416 cbeb0b26 2006-04-01 devnull /* bail if it doesn't fit */
1417 5cdb1798 2005-10-29 devnull if(e-token > sizeof(decoded)-1)
1418 5cdb1798 2005-10-29 devnull return -1;
1419 5cdb1798 2005-10-29 devnull
1420 cbeb0b26 2006-04-01 devnull /* bail if we don't understand the encoding */
1421 5cdb1798 2005-10-29 devnull if(cistrncmp(token, "b?", 2) == 0){
1422 5cdb1798 2005-10-29 devnull token += 2;
1423 5cdb1798 2005-10-29 devnull len = dec64((uchar*)decoded, sizeof(decoded), token, e-token);
1424 5cdb1798 2005-10-29 devnull decoded[len] = 0;
1425 5cdb1798 2005-10-29 devnull } else if(cistrncmp(token, "q?", 2) == 0){
1426 5cdb1798 2005-10-29 devnull token += 2;
1427 5cdb1798 2005-10-29 devnull len = decquoted(decoded, token, e);
1428 5cdb1798 2005-10-29 devnull if(len > 0 && decoded[len-1] == '\n')
1429 5cdb1798 2005-10-29 devnull len--;
1430 5cdb1798 2005-10-29 devnull decoded[len] = 0;
1431 5cdb1798 2005-10-29 devnull } else
1432 5cdb1798 2005-10-29 devnull return -1;
1433 5cdb1798 2005-10-29 devnull
1434 5cdb1798 2005-10-29 devnull switch(charsets[i].convert){
1435 5cdb1798 2005-10-29 devnull case 0:
1436 5cdb1798 2005-10-29 devnull s_append(s, decoded);
1437 5cdb1798 2005-10-29 devnull break;
1438 5cdb1798 2005-10-29 devnull case 1:
1439 5cdb1798 2005-10-29 devnull latin1toutf(utfbuf, decoded, decoded+len);
1440 5cdb1798 2005-10-29 devnull s_append(s, utfbuf);
1441 5cdb1798 2005-10-29 devnull break;
1442 5cdb1798 2005-10-29 devnull case 2:
1443 5cdb1798 2005-10-29 devnull if(xtoutf(charsets[i].tcsname, &x, decoded, decoded+len) <= 0){
1444 5cdb1798 2005-10-29 devnull s_append(s, decoded);
1445 5cdb1798 2005-10-29 devnull } else {
1446 5cdb1798 2005-10-29 devnull s_append(s, x);
1447 5cdb1798 2005-10-29 devnull free(x);
1448 5cdb1798 2005-10-29 devnull }
1449 5cdb1798 2005-10-29 devnull break;
1450 5cdb1798 2005-10-29 devnull }
1451 5cdb1798 2005-10-29 devnull
1452 5cdb1798 2005-10-29 devnull return 0;
1453 5cdb1798 2005-10-29 devnull }
1454 5cdb1798 2005-10-29 devnull
1455 5cdb1798 2005-10-29 devnull char*
1456 5cdb1798 2005-10-29 devnull rfc2047start(char *start, char *end)
1457 5cdb1798 2005-10-29 devnull {
1458 5cdb1798 2005-10-29 devnull int quests;
1459 5cdb1798 2005-10-29 devnull
1460 5cdb1798 2005-10-29 devnull if(*--end != '=')
1461 5cdb1798 2005-10-29 devnull return nil;
1462 5cdb1798 2005-10-29 devnull if(*--end != '?')
1463 5cdb1798 2005-10-29 devnull return nil;
1464 5cdb1798 2005-10-29 devnull
1465 5cdb1798 2005-10-29 devnull quests = 0;
1466 5cdb1798 2005-10-29 devnull for(end--; end >= start; end--){
1467 5cdb1798 2005-10-29 devnull switch(*end){
1468 5cdb1798 2005-10-29 devnull case '=':
1469 5cdb1798 2005-10-29 devnull if(quests == 3 && *(end+1) == '?')
1470 5cdb1798 2005-10-29 devnull return end;
1471 5cdb1798 2005-10-29 devnull break;
1472 5cdb1798 2005-10-29 devnull case '?':
1473 5cdb1798 2005-10-29 devnull ++quests;
1474 5cdb1798 2005-10-29 devnull break;
1475 5cdb1798 2005-10-29 devnull case ' ':
1476 5cdb1798 2005-10-29 devnull case '\t':
1477 5cdb1798 2005-10-29 devnull case '\n':
1478 5cdb1798 2005-10-29 devnull case '\r':
1479 5cdb1798 2005-10-29 devnull /* can't have white space in a token */
1480 5cdb1798 2005-10-29 devnull return nil;
1481 5cdb1798 2005-10-29 devnull }
1482 5cdb1798 2005-10-29 devnull }
1483 5cdb1798 2005-10-29 devnull return nil;
1484 5cdb1798 2005-10-29 devnull }
1485 5cdb1798 2005-10-29 devnull
1486 cbeb0b26 2006-04-01 devnull /* convert a header line */
1487 5cdb1798 2005-10-29 devnull String*
1488 5cdb1798 2005-10-29 devnull stringconvert(String *s, char *uneaten, int len)
1489 5cdb1798 2005-10-29 devnull {
1490 5cdb1798 2005-10-29 devnull char *token;
1491 5cdb1798 2005-10-29 devnull char *p;
1492 5cdb1798 2005-10-29 devnull int i;
1493 5cdb1798 2005-10-29 devnull
1494 5cdb1798 2005-10-29 devnull s = s_reset(s);
1495 5cdb1798 2005-10-29 devnull p = uneaten;
1496 5cdb1798 2005-10-29 devnull for(i = 0; i < len; i++){
1497 5cdb1798 2005-10-29 devnull if(*p++ == '='){
1498 5cdb1798 2005-10-29 devnull token = rfc2047start(uneaten, p);
1499 5cdb1798 2005-10-29 devnull if(token != nil){
1500 5cdb1798 2005-10-29 devnull s_nappend(s, uneaten, token-uneaten);
1501 5cdb1798 2005-10-29 devnull if(rfc2047convert(s, token, p - token) < 0)
1502 5cdb1798 2005-10-29 devnull s_nappend(s, token, p - token);
1503 5cdb1798 2005-10-29 devnull uneaten = p;
1504 5cdb1798 2005-10-29 devnull }
1505 5cdb1798 2005-10-29 devnull }
1506 5cdb1798 2005-10-29 devnull }
1507 5cdb1798 2005-10-29 devnull if(p > uneaten)
1508 5cdb1798 2005-10-29 devnull s_nappend(s, uneaten, p-uneaten);
1509 5cdb1798 2005-10-29 devnull return s;
1510 5cdb1798 2005-10-29 devnull }
1511 5cdb1798 2005-10-29 devnull
1512 5cdb1798 2005-10-29 devnull int
1513 5cdb1798 2005-10-29 devnull readheader(Message *m, char *buf, int off, int cnt)
1514 5cdb1798 2005-10-29 devnull {
1515 5cdb1798 2005-10-29 devnull char *p, *e;
1516 5cdb1798 2005-10-29 devnull int n, ns;
1517 5cdb1798 2005-10-29 devnull char *to = buf;
1518 5cdb1798 2005-10-29 devnull String *s;
1519 5cdb1798 2005-10-29 devnull
1520 5cdb1798 2005-10-29 devnull p = m->header;
1521 5cdb1798 2005-10-29 devnull e = m->hend;
1522 5cdb1798 2005-10-29 devnull s = nil;
1523 5cdb1798 2005-10-29 devnull
1524 cbeb0b26 2006-04-01 devnull /* copy in good headers */
1525 5cdb1798 2005-10-29 devnull while(cnt > 0 && p < e){
1526 5cdb1798 2005-10-29 devnull n = hdrlen(p, e);
1527 5cdb1798 2005-10-29 devnull if(ignore(p)){
1528 5cdb1798 2005-10-29 devnull p += n;
1529 5cdb1798 2005-10-29 devnull continue;
1530 5cdb1798 2005-10-29 devnull }
1531 5cdb1798 2005-10-29 devnull
1532 cbeb0b26 2006-04-01 devnull /* rfc2047 processing */
1533 5cdb1798 2005-10-29 devnull s = stringconvert(s, p, n);
1534 5cdb1798 2005-10-29 devnull ns = s_len(s);
1535 5cdb1798 2005-10-29 devnull if(off > 0){
1536 5cdb1798 2005-10-29 devnull if(ns <= off){
1537 5cdb1798 2005-10-29 devnull off -= ns;
1538 5cdb1798 2005-10-29 devnull p += n;
1539 5cdb1798 2005-10-29 devnull continue;
1540 5cdb1798 2005-10-29 devnull }
1541 5cdb1798 2005-10-29 devnull ns -= off;
1542 5cdb1798 2005-10-29 devnull }
1543 5cdb1798 2005-10-29 devnull if(ns > cnt)
1544 5cdb1798 2005-10-29 devnull ns = cnt;
1545 5cdb1798 2005-10-29 devnull memmove(to, s_to_c(s)+off, ns);
1546 5cdb1798 2005-10-29 devnull to += ns;
1547 5cdb1798 2005-10-29 devnull p += n;
1548 5cdb1798 2005-10-29 devnull cnt -= ns;
1549 5cdb1798 2005-10-29 devnull off = 0;
1550 5cdb1798 2005-10-29 devnull }
1551 5cdb1798 2005-10-29 devnull
1552 5cdb1798 2005-10-29 devnull s_free(s);
1553 5cdb1798 2005-10-29 devnull return to - buf;
1554 5cdb1798 2005-10-29 devnull }
1555 5cdb1798 2005-10-29 devnull
1556 5cdb1798 2005-10-29 devnull int
1557 5cdb1798 2005-10-29 devnull headerlen(Message *m)
1558 5cdb1798 2005-10-29 devnull {
1559 5cdb1798 2005-10-29 devnull char buf[1024];
1560 5cdb1798 2005-10-29 devnull int i, n;
1561 5cdb1798 2005-10-29 devnull
1562 5cdb1798 2005-10-29 devnull if(m->hlen >= 0)
1563 5cdb1798 2005-10-29 devnull return m->hlen;
1564 5cdb1798 2005-10-29 devnull for(n = 0; ; n += i){
1565 5cdb1798 2005-10-29 devnull i = readheader(m, buf, n, sizeof(buf));
1566 5cdb1798 2005-10-29 devnull if(i <= 0)
1567 5cdb1798 2005-10-29 devnull break;
1568 5cdb1798 2005-10-29 devnull }
1569 5cdb1798 2005-10-29 devnull m->hlen = n;
1570 5cdb1798 2005-10-29 devnull return n;
1571 5cdb1798 2005-10-29 devnull }
1572 5cdb1798 2005-10-29 devnull
1573 5cdb1798 2005-10-29 devnull QLock hashlock;
1574 5cdb1798 2005-10-29 devnull
1575 5cdb1798 2005-10-29 devnull uint
1576 5cdb1798 2005-10-29 devnull hash(ulong ppath, char *name)
1577 5cdb1798 2005-10-29 devnull {
1578 5cdb1798 2005-10-29 devnull uchar *p;
1579 5cdb1798 2005-10-29 devnull uint h;
1580 5cdb1798 2005-10-29 devnull
1581 5cdb1798 2005-10-29 devnull h = 0;
1582 5cdb1798 2005-10-29 devnull for(p = (uchar*)name; *p; p++)
1583 5cdb1798 2005-10-29 devnull h = h*7 + *p;
1584 5cdb1798 2005-10-29 devnull h += ppath;
1585 5cdb1798 2005-10-29 devnull
1586 5cdb1798 2005-10-29 devnull return h % Hsize;
1587 5cdb1798 2005-10-29 devnull }
1588 5cdb1798 2005-10-29 devnull
1589 5cdb1798 2005-10-29 devnull Hash*
1590 5cdb1798 2005-10-29 devnull hlook(ulong ppath, char *name)
1591 5cdb1798 2005-10-29 devnull {
1592 5cdb1798 2005-10-29 devnull int h;
1593 5cdb1798 2005-10-29 devnull Hash *hp;
1594 5cdb1798 2005-10-29 devnull
1595 5cdb1798 2005-10-29 devnull qlock(&hashlock);
1596 5cdb1798 2005-10-29 devnull h = hash(ppath, name);
1597 5cdb1798 2005-10-29 devnull for(hp = htab[h]; hp != nil; hp = hp->next)
1598 5cdb1798 2005-10-29 devnull if(ppath == hp->ppath && strcmp(name, hp->name) == 0){
1599 5cdb1798 2005-10-29 devnull qunlock(&hashlock);
1600 5cdb1798 2005-10-29 devnull return hp;
1601 5cdb1798 2005-10-29 devnull }
1602 5cdb1798 2005-10-29 devnull qunlock(&hashlock);
1603 5cdb1798 2005-10-29 devnull return nil;
1604 5cdb1798 2005-10-29 devnull }
1605 5cdb1798 2005-10-29 devnull
1606 5cdb1798 2005-10-29 devnull void
1607 5cdb1798 2005-10-29 devnull henter(ulong ppath, char *name, Qid qid, Message *m, Mailbox *mb)
1608 5cdb1798 2005-10-29 devnull {
1609 5cdb1798 2005-10-29 devnull int h;
1610 5cdb1798 2005-10-29 devnull Hash *hp, **l;
1611 5cdb1798 2005-10-29 devnull
1612 5cdb1798 2005-10-29 devnull qlock(&hashlock);
1613 5cdb1798 2005-10-29 devnull h = hash(ppath, name);
1614 5cdb1798 2005-10-29 devnull for(l = &htab[h]; *l != nil; l = &(*l)->next){
1615 5cdb1798 2005-10-29 devnull hp = *l;
1616 5cdb1798 2005-10-29 devnull if(ppath == hp->ppath && strcmp(name, hp->name) == 0){
1617 5cdb1798 2005-10-29 devnull hp->m = m;
1618 5cdb1798 2005-10-29 devnull hp->mb = mb;
1619 5cdb1798 2005-10-29 devnull hp->qid = qid;
1620 5cdb1798 2005-10-29 devnull qunlock(&hashlock);
1621 5cdb1798 2005-10-29 devnull return;
1622 5cdb1798 2005-10-29 devnull }
1623 5cdb1798 2005-10-29 devnull }
1624 5cdb1798 2005-10-29 devnull
1625 5cdb1798 2005-10-29 devnull *l = hp = emalloc(sizeof(*hp));
1626 5cdb1798 2005-10-29 devnull hp->m = m;
1627 5cdb1798 2005-10-29 devnull hp->mb = mb;
1628 5cdb1798 2005-10-29 devnull hp->qid = qid;
1629 5cdb1798 2005-10-29 devnull hp->name = name;
1630 5cdb1798 2005-10-29 devnull hp->ppath = ppath;
1631 5cdb1798 2005-10-29 devnull qunlock(&hashlock);
1632 5cdb1798 2005-10-29 devnull }
1633 5cdb1798 2005-10-29 devnull
1634 5cdb1798 2005-10-29 devnull void
1635 5cdb1798 2005-10-29 devnull hfree(ulong ppath, char *name)
1636 5cdb1798 2005-10-29 devnull {
1637 5cdb1798 2005-10-29 devnull int h;
1638 5cdb1798 2005-10-29 devnull Hash *hp, **l;
1639 5cdb1798 2005-10-29 devnull
1640 5cdb1798 2005-10-29 devnull qlock(&hashlock);
1641 5cdb1798 2005-10-29 devnull h = hash(ppath, name);
1642 5cdb1798 2005-10-29 devnull for(l = &htab[h]; *l != nil; l = &(*l)->next){
1643 5cdb1798 2005-10-29 devnull hp = *l;
1644 5cdb1798 2005-10-29 devnull if(ppath == hp->ppath && strcmp(name, hp->name) == 0){
1645 5cdb1798 2005-10-29 devnull hp->mb = nil;
1646 5cdb1798 2005-10-29 devnull *l = hp->next;
1647 5cdb1798 2005-10-29 devnull free(hp);
1648 5cdb1798 2005-10-29 devnull break;
1649 5cdb1798 2005-10-29 devnull }
1650 5cdb1798 2005-10-29 devnull }
1651 5cdb1798 2005-10-29 devnull qunlock(&hashlock);
1652 5cdb1798 2005-10-29 devnull }
1653 5cdb1798 2005-10-29 devnull
1654 5cdb1798 2005-10-29 devnull int
1655 5cdb1798 2005-10-29 devnull hashmboxrefs(Mailbox *mb)
1656 5cdb1798 2005-10-29 devnull {
1657 5cdb1798 2005-10-29 devnull int h;
1658 5cdb1798 2005-10-29 devnull Hash *hp;
1659 5cdb1798 2005-10-29 devnull int refs = 0;
1660 5cdb1798 2005-10-29 devnull
1661 5cdb1798 2005-10-29 devnull qlock(&hashlock);
1662 5cdb1798 2005-10-29 devnull for(h = 0; h < Hsize; h++){
1663 5cdb1798 2005-10-29 devnull for(hp = htab[h]; hp != nil; hp = hp->next)
1664 5cdb1798 2005-10-29 devnull if(hp->mb == mb)
1665 5cdb1798 2005-10-29 devnull refs++;
1666 5cdb1798 2005-10-29 devnull }
1667 5cdb1798 2005-10-29 devnull qunlock(&hashlock);
1668 5cdb1798 2005-10-29 devnull return refs;
1669 5cdb1798 2005-10-29 devnull }
1670 5cdb1798 2005-10-29 devnull
1671 5cdb1798 2005-10-29 devnull void
1672 5cdb1798 2005-10-29 devnull checkmboxrefs(void)
1673 5cdb1798 2005-10-29 devnull {
1674 5cdb1798 2005-10-29 devnull int f, refs;
1675 5cdb1798 2005-10-29 devnull Mailbox *mb;
1676 5cdb1798 2005-10-29 devnull
1677 5cdb1798 2005-10-29 devnull qlock(&mbllock);
1678 5cdb1798 2005-10-29 devnull for(mb=mbl; mb; mb=mb->next){
1679 5cdb1798 2005-10-29 devnull qlock(&mb->ql);
1680 5cdb1798 2005-10-29 devnull refs = (f=fidmboxrefs(mb))+1;
1681 5cdb1798 2005-10-29 devnull if(refs != mb->refs){
1682 5cdb1798 2005-10-29 devnull fprint(2, "mbox %s %s ref mismatch actual %d (%d+1) expected %d\n", mb->name, mb->path, refs, f, mb->refs);
1683 5cdb1798 2005-10-29 devnull abort();
1684 5cdb1798 2005-10-29 devnull }
1685 5cdb1798 2005-10-29 devnull qunlock(&mb->ql);
1686 5cdb1798 2005-10-29 devnull }
1687 5cdb1798 2005-10-29 devnull qunlock(&mbllock);
1688 5cdb1798 2005-10-29 devnull }
1689 5cdb1798 2005-10-29 devnull
1690 5cdb1798 2005-10-29 devnull void
1691 5cdb1798 2005-10-29 devnull post(char *name, char *envname, int srvfd)
1692 5cdb1798 2005-10-29 devnull {
1693 5cdb1798 2005-10-29 devnull int fd;
1694 5cdb1798 2005-10-29 devnull char buf[32];
1695 5cdb1798 2005-10-29 devnull
1696 5cdb1798 2005-10-29 devnull fd = create(name, OWRITE, 0600);
1697 5cdb1798 2005-10-29 devnull if(fd < 0)
1698 5cdb1798 2005-10-29 devnull error("post failed");
1699 5cdb1798 2005-10-29 devnull sprint(buf, "%d",srvfd);
1700 5cdb1798 2005-10-29 devnull if(write(fd, buf, strlen(buf)) != strlen(buf))
1701 5cdb1798 2005-10-29 devnull error("srv write");
1702 5cdb1798 2005-10-29 devnull close(fd);
1703 5cdb1798 2005-10-29 devnull putenv(envname, name);
1704 5cdb1798 2005-10-29 devnull }