1 d3df3087 2003-12-06 devnull #include <u.h>
2 d3df3087 2003-12-06 devnull #include <libc.h>
3 d3df3087 2003-12-06 devnull #include <fcall.h>
4 d3df3087 2003-12-06 devnull #include <thread.h>
5 32f69c36 2003-12-11 devnull #include <errno.h>
9 d3df3087 2003-12-06 devnull STACK = 32768,
10 d3df3087 2003-12-06 devnull NHASH = 31,
11 d3df3087 2003-12-06 devnull MAXMSG = 64, /* per connection */
14 d3df3087 2003-12-06 devnull typedef struct Hash Hash;
15 d3df3087 2003-12-06 devnull typedef struct Fid Fid;
16 d3df3087 2003-12-06 devnull typedef struct Msg Msg;
17 d3df3087 2003-12-06 devnull typedef struct Conn Conn;
18 d3df3087 2003-12-06 devnull typedef struct Queue Queue;
20 d3df3087 2003-12-06 devnull struct Hash
22 d3df3087 2003-12-06 devnull Hash *next;
27 d3df3087 2003-12-06 devnull struct Fid
31 d3df3087 2003-12-06 devnull int cfid;
32 21e626de 2004-12-28 devnull int openfd;
33 9777187b 2006-02-03 devnull int offset;
34 9777187b 2006-02-03 devnull int coffset;
35 215993f8 2005-09-13 devnull int isdir;
36 d3df3087 2003-12-06 devnull Fid *next;
39 d3df3087 2003-12-06 devnull struct Msg
42 d3df3087 2003-12-06 devnull int internal;
44 d3df3087 2003-12-06 devnull int ctag;
46 32f69c36 2003-12-11 devnull int isopenfd;
47 d3df3087 2003-12-06 devnull Fcall tx;
48 d3df3087 2003-12-06 devnull Fcall rx;
49 d3df3087 2003-12-06 devnull Fid *fid;
50 d3df3087 2003-12-06 devnull Fid *newfid;
51 d3df3087 2003-12-06 devnull Fid *afid;
52 d3df3087 2003-12-06 devnull Msg *oldm;
53 d3df3087 2003-12-06 devnull Msg *next;
54 d3df3087 2003-12-06 devnull uchar *tpkt;
55 d3df3087 2003-12-06 devnull uchar *rpkt;
58 d3df3087 2003-12-06 devnull struct Conn
61 32f69c36 2003-12-11 devnull int fdmode;
62 32f69c36 2003-12-11 devnull Fid *fdfid;
63 d3df3087 2003-12-06 devnull int nmsg;
64 d3df3087 2003-12-06 devnull int nfid;
65 d3df3087 2003-12-06 devnull Channel *inc;
66 d3df3087 2003-12-06 devnull Channel *internal;
67 d3df3087 2003-12-06 devnull int inputstalled;
68 d3df3087 2003-12-06 devnull char dir[40];
69 d3df3087 2003-12-06 devnull Hash *tag[NHASH];
70 d3df3087 2003-12-06 devnull Hash *fid[NHASH];
71 d3df3087 2003-12-06 devnull Queue *outq;
72 d3df3087 2003-12-06 devnull Queue *inq;
73 215993f8 2005-09-13 devnull int dotu;
76 5c84c448 2005-03-21 devnull char *xaname;
77 d3df3087 2003-12-06 devnull char *addr;
79 d3df3087 2003-12-06 devnull char adir[40];
80 d3df3087 2003-12-06 devnull int isunix;
81 d3df3087 2003-12-06 devnull Queue *outq;
82 d3df3087 2003-12-06 devnull Queue *inq;
83 05b7f431 2004-03-02 devnull int verbose = 0;
84 e2a1725d 2005-01-04 devnull int logging = 0;
85 5a8e63b2 2004-02-29 devnull int msize = 8192;
86 34e8254f 2005-07-27 devnull u32int xafid = NOFID;
87 5c84c448 2005-03-21 devnull int attached;
88 5c84c448 2005-03-21 devnull int versioned;
89 215993f8 2005-09-13 devnull int dotu;
91 d3df3087 2003-12-06 devnull void *gethash(Hash**, uint);
92 d3df3087 2003-12-06 devnull int puthash(Hash**, uint, void*);
93 d3df3087 2003-12-06 devnull int delhash(Hash**, uint, void*);
94 215993f8 2005-09-13 devnull Msg *mread9p(Ioproc*, int, int);
95 ceb04770 2003-12-09 devnull int mwrite9p(Ioproc*, int, uchar*);
96 ceb04770 2003-12-09 devnull uchar *read9ppkt(Ioproc*, int);
97 d3df3087 2003-12-06 devnull int write9ppkt(int, uchar*);
98 e2a1725d 2005-01-04 devnull Msg *msgnew(int);
99 d3df3087 2003-12-06 devnull void msgput(Msg*);
100 e2a1725d 2005-01-04 devnull void msgclear(Msg*);
101 d3df3087 2003-12-06 devnull Msg *msgget(int);
102 e2a1725d 2005-01-04 devnull void msgincref(Msg*);
103 d3df3087 2003-12-06 devnull Fid *fidnew(int);
104 d3df3087 2003-12-06 devnull void fidput(Fid*);
105 d3df3087 2003-12-06 devnull void *emalloc(int);
106 d3df3087 2003-12-06 devnull void *erealloc(void*, int);
107 ceb04770 2003-12-09 devnull Queue *qalloc(void);
108 d3df3087 2003-12-06 devnull int sendq(Queue*, void*);
109 d3df3087 2003-12-06 devnull void *recvq(Queue*);
110 d3df3087 2003-12-06 devnull void connthread(void*);
111 ceb04770 2003-12-09 devnull void connoutthread(void*);
112 d3df3087 2003-12-06 devnull void listenthread(void*);
113 ceb04770 2003-12-09 devnull void outputthread(void*);
114 ceb04770 2003-12-09 devnull void inputthread(void*);
115 d3df3087 2003-12-06 devnull void rewritehdr(Fcall*, uchar*);
116 215993f8 2005-09-13 devnull void repack(Fcall*, uchar**, int);
117 d3df3087 2003-12-06 devnull int tlisten(char*, char*);
118 d3df3087 2003-12-06 devnull int taccept(int, char*);
119 ceb04770 2003-12-09 devnull int iolisten(Ioproc*, char*, char*);
120 ceb04770 2003-12-09 devnull int ioaccept(Ioproc*, int, char*);
121 32f69c36 2003-12-11 devnull int iorecvfd(Ioproc*, int);
122 32f69c36 2003-12-11 devnull int iosendfd(Ioproc*, int, int);
123 32f69c36 2003-12-11 devnull void mainproc(void*);
124 32f69c36 2003-12-11 devnull int ignorepipe(void*, char*);
125 e2a1725d 2005-01-04 devnull int timefmt(Fmt*);
126 5c84c448 2005-03-21 devnull void dorootstat(void);
127 215993f8 2005-09-13 devnull int stripudirread(Msg*);
128 16c1defa 2005-11-12 devnull int cvtustat(Fcall*, uchar**, int);
131 d3df3087 2003-12-06 devnull usage(void)
133 5c84c448 2005-03-21 devnull fprint(2, "usage: 9pserve [-lv] [-A aname afid] [-M msize] address\n");
134 d3df3087 2003-12-06 devnull fprint(2, "\treads/writes 9P messages on stdin/stdout\n");
135 38c10d1a 2005-01-17 devnull threadexitsall("usage");
138 ceb04770 2003-12-09 devnull uchar vbuf[128];
139 32f69c36 2003-12-11 devnull extern int _threaddebuglevel;
141 d3df3087 2003-12-06 devnull threadmain(int argc, char **argv)
143 3a6f92ee 2005-03-18 devnull char *file, *x;
146 3a6f92ee 2005-03-18 devnull x = getenv("verbose9pserve");
148 3a6f92ee 2005-03-18 devnull verbose = atoi(x);
149 5c84c448 2005-03-21 devnull fprint(2, "verbose9pserve %s => %d\n", x, verbose);
151 d3df3087 2003-12-06 devnull ARGBEGIN{
152 d3df3087 2003-12-06 devnull default:
153 d3df3087 2003-12-06 devnull usage();
154 5c84c448 2005-03-21 devnull case 'A':
155 5c84c448 2005-03-21 devnull attached = 1;
156 5c84c448 2005-03-21 devnull xaname = EARGF(usage());
157 5c84c448 2005-03-21 devnull xafid = atoi(EARGF(usage()));
159 5c84c448 2005-03-21 devnull case 'M':
160 5c84c448 2005-03-21 devnull versioned = 1;
161 5c84c448 2005-03-21 devnull msize = atoi(EARGF(usage()));
163 ceb04770 2003-12-09 devnull case 'v':
164 ceb04770 2003-12-09 devnull verbose++;
166 d3df3087 2003-12-06 devnull case 'u':
167 5c84c448 2005-03-21 devnull isunix++;
169 e2a1725d 2005-01-04 devnull case 'l':
170 e2a1725d 2005-01-04 devnull logging++;
174 5c84c448 2005-03-21 devnull if(attached && !versioned){
175 5c84c448 2005-03-21 devnull fprint(2, "-A must be used with -M\n");
176 5c84c448 2005-03-21 devnull usage();
179 d3df3087 2003-12-06 devnull if(argc != 1)
180 d3df3087 2003-12-06 devnull usage();
181 ceb04770 2003-12-09 devnull addr = argv[0];
183 e2a1725d 2005-01-04 devnull fmtinstall('T', timefmt);
185 d3df3087 2003-12-06 devnull if((afd = announce(addr, adir)) < 0)
186 d3df3087 2003-12-06 devnull sysfatal("announce %s: %r", addr);
187 e2a1725d 2005-01-04 devnull if(logging){
188 e2a1725d 2005-01-04 devnull if(strncmp(addr, "unix!", 5) == 0)
189 e2a1725d 2005-01-04 devnull addr += 5;
190 e2a1725d 2005-01-04 devnull file = smprint("%s.log", addr);
191 e2a1725d 2005-01-04 devnull if(file == nil)
192 e2a1725d 2005-01-04 devnull sysfatal("smprint log: %r");
193 e2a1725d 2005-01-04 devnull if((fd = create(file, OWRITE, 0666)) < 0)
194 e2a1725d 2005-01-04 devnull sysfatal("create %s: %r", file);
195 e2a1725d 2005-01-04 devnull dup(fd, 2);
196 e2a1725d 2005-01-04 devnull if(fd > 2)
197 e2a1725d 2005-01-04 devnull close(fd);
199 e2a1725d 2005-01-04 devnull if(verbose) fprint(2, "%T 9pserve running\n");
200 e2a1725d 2005-01-04 devnull proccreate(mainproc, nil, STACK);
204 32f69c36 2003-12-11 devnull mainproc(void *v)
206 c91bd328 2004-03-05 devnull int n, nn;
207 32f69c36 2003-12-11 devnull Fcall f;
208 32f69c36 2003-12-11 devnull USED(v);
210 32f69c36 2003-12-11 devnull atnotify(ignorepipe, 1);
211 ceb04770 2003-12-09 devnull fmtinstall('D', dirfmt);
212 ceb04770 2003-12-09 devnull fmtinstall('M', dirmodefmt);
213 ceb04770 2003-12-09 devnull fmtinstall('F', fcallfmt);
214 ceb04770 2003-12-09 devnull fmtinstall('H', encodefmt);
216 ceb04770 2003-12-09 devnull outq = qalloc();
217 ceb04770 2003-12-09 devnull inq = qalloc();
219 5c84c448 2005-03-21 devnull if(!versioned){
220 5c84c448 2005-03-21 devnull f.type = Tversion;
221 215993f8 2005-09-13 devnull f.version = "9P2000.u";
222 5c84c448 2005-03-21 devnull f.msize = msize;
223 5c84c448 2005-03-21 devnull f.tag = NOTAG;
224 5c84c448 2005-03-21 devnull n = convS2M(&f, vbuf, sizeof vbuf);
225 9e2f1d9b 2005-11-21 devnull if(n <= BIT16SZ)
226 9e2f1d9b 2005-11-21 devnull sysfatal("convS2M conversion error");
227 5c84c448 2005-03-21 devnull if(verbose > 1) fprint(2, "%T * <- %F\n", &f);
228 5c84c448 2005-03-21 devnull nn = write(1, vbuf, n);
229 5c84c448 2005-03-21 devnull if(n != nn)
230 5c84c448 2005-03-21 devnull sysfatal("error writing Tversion: %r\n");
231 5c84c448 2005-03-21 devnull n = read9pmsg(0, vbuf, sizeof vbuf);
232 5c84c448 2005-03-21 devnull if(convM2S(vbuf, n, &f) != n)
233 5c84c448 2005-03-21 devnull sysfatal("convM2S failure");
234 5c84c448 2005-03-21 devnull if(f.msize < msize)
235 5c84c448 2005-03-21 devnull msize = f.msize;
236 5c84c448 2005-03-21 devnull if(verbose > 1) fprint(2, "%T * -> %F\n", &f);
237 215993f8 2005-09-13 devnull dotu = strncmp(f.version, "9P2000.u", 8) == 0;
240 32f69c36 2003-12-11 devnull threadcreate(inputthread, nil, STACK);
241 32f69c36 2003-12-11 devnull threadcreate(outputthread, nil, STACK);
243 5c84c448 2005-03-21 devnull // if(rootfid)
244 5c84c448 2005-03-21 devnull // dorootstat();
246 ceb04770 2003-12-09 devnull threadcreate(listenthread, nil, STACK);
247 32f69c36 2003-12-11 devnull threadexits(0);
251 32f69c36 2003-12-11 devnull ignorepipe(void *v, char *s)
253 32f69c36 2003-12-11 devnull USED(v);
254 32f69c36 2003-12-11 devnull if(strcmp(s, "sys: write on closed pipe") == 0)
255 32f69c36 2003-12-11 devnull return 1;
256 c042e61e 2005-03-18 devnull if(strcmp(s, "sys: tstp") == 0)
257 c042e61e 2005-03-18 devnull return 1;
258 c042e61e 2005-03-18 devnull fprint(2, "9pserve %s: %T note: %s\n", addr, s);
259 32f69c36 2003-12-11 devnull return 0;
263 d3df3087 2003-12-06 devnull listenthread(void *arg)
265 d3df3087 2003-12-06 devnull Conn *c;
266 ceb04770 2003-12-09 devnull Ioproc *io;
268 ceb04770 2003-12-09 devnull io = ioproc();
269 d3df3087 2003-12-06 devnull USED(arg);
270 7ffc5208 2004-12-28 devnull threadsetname("listen %s", adir);
271 d3df3087 2003-12-06 devnull for(;;){
272 ceb04770 2003-12-09 devnull c = emalloc(sizeof(Conn));
273 ceb04770 2003-12-09 devnull c->fd = iolisten(io, adir, c->dir);
274 d3df3087 2003-12-06 devnull if(c->fd < 0){
275 e2a1725d 2005-01-04 devnull if(verbose) fprint(2, "%T listen: %r\n");
276 d3df3087 2003-12-06 devnull close(afd);
277 d3df3087 2003-12-06 devnull free(c);
280 32f69c36 2003-12-11 devnull c->inc = chancreate(sizeof(void*), 0);
281 32f69c36 2003-12-11 devnull c->internal = chancreate(sizeof(void*), 0);
282 32f69c36 2003-12-11 devnull c->inq = qalloc();
283 32f69c36 2003-12-11 devnull c->outq = qalloc();
284 e2a1725d 2005-01-04 devnull if(verbose) fprint(2, "%T incoming call on %s\n", c->dir);
285 d3df3087 2003-12-06 devnull threadcreate(connthread, c, STACK);
290 32f69c36 2003-12-11 devnull send9pmsg(Msg *m)
292 d3df3087 2003-12-06 devnull int n, nn;
294 215993f8 2005-09-13 devnull n = sizeS2Mu(&m->rx, m->c->dotu);
295 d3df3087 2003-12-06 devnull m->rpkt = emalloc(n);
296 215993f8 2005-09-13 devnull nn = convS2Mu(&m->rx, m->rpkt, n, m->c->dotu);
297 9e2f1d9b 2005-11-21 devnull if(nn <= BIT16SZ)
298 9e2f1d9b 2005-11-21 devnull sysfatal("convS2Mu conversion error");
299 d3df3087 2003-12-06 devnull if(nn != n)
300 9e2f1d9b 2005-11-21 devnull sysfatal("sizeS2Mu and convS2Mu disagree");
301 d3df3087 2003-12-06 devnull sendq(m->c->outq, m);
305 ceb04770 2003-12-09 devnull sendomsg(Msg *m)
307 ceb04770 2003-12-09 devnull int n, nn;
309 215993f8 2005-09-13 devnull n = sizeS2Mu(&m->tx, m->c->dotu);
310 ceb04770 2003-12-09 devnull m->tpkt = emalloc(n);
311 215993f8 2005-09-13 devnull nn = convS2Mu(&m->tx, m->tpkt, n, m->c->dotu);
312 9e2f1d9b 2005-11-21 devnull if(nn <= BIT16SZ)
313 9e2f1d9b 2005-11-21 devnull sysfatal("convS2Mu conversion error");
314 ceb04770 2003-12-09 devnull if(nn != n)
315 9e2f1d9b 2005-11-21 devnull sysfatal("sizeS2Mu and convS2Mu disagree");
316 ceb04770 2003-12-09 devnull sendq(outq, m);
320 ceb04770 2003-12-09 devnull err(Msg *m, char *ename)
322 ceb04770 2003-12-09 devnull m->rx.type = Rerror;
323 ceb04770 2003-12-09 devnull m->rx.ename = ename;
324 ceb04770 2003-12-09 devnull m->rx.tag = m->tx.tag;
325 32f69c36 2003-12-11 devnull send9pmsg(m);
329 5c84c448 2005-03-21 devnull estrdup(char *s)
331 5c84c448 2005-03-21 devnull char *t;
333 5c84c448 2005-03-21 devnull t = emalloc(strlen(s)+1);
334 5c84c448 2005-03-21 devnull strcpy(t, s);
335 5c84c448 2005-03-21 devnull return t;
339 d3df3087 2003-12-06 devnull connthread(void *arg)
341 d3df3087 2003-12-06 devnull int i, fd;
342 d3df3087 2003-12-06 devnull Conn *c;
343 05b7f431 2004-03-02 devnull Hash *h, *hnext;
344 05b7f431 2004-03-02 devnull Msg *m, *om, *mm;
346 ceb04770 2003-12-09 devnull Ioproc *io;
348 d3df3087 2003-12-06 devnull c = arg;
349 7ffc5208 2004-12-28 devnull threadsetname("conn %s", c->dir);
350 ceb04770 2003-12-09 devnull io = ioproc();
351 ceb04770 2003-12-09 devnull fd = ioaccept(io, c->fd, c->dir);
352 d3df3087 2003-12-06 devnull if(fd < 0){
353 e2a1725d 2005-01-04 devnull if(verbose) fprint(2, "%T accept %s: %r\n", c->dir);
354 d3df3087 2003-12-06 devnull goto out;
356 d3df3087 2003-12-06 devnull close(c->fd);
357 d3df3087 2003-12-06 devnull c->fd = fd;
358 ceb04770 2003-12-09 devnull threadcreate(connoutthread, c, STACK);
359 215993f8 2005-09-13 devnull while((m = mread9p(io, c->fd, c->dotu)) != nil){
360 e2a1725d 2005-01-04 devnull if(verbose > 1) fprint(2, "%T fd#%d -> %F\n", c->fd, &m->tx);
361 d3df3087 2003-12-06 devnull m->c = c;
362 ceb04770 2003-12-09 devnull m->ctag = m->tx.tag;
363 d3df3087 2003-12-06 devnull c->nmsg++;
364 e2a1725d 2005-01-04 devnull if(verbose > 1) fprint(2, "%T fd#%d: new msg %p\n", c->fd, m);
365 d3df3087 2003-12-06 devnull if(puthash(c->tag, m->tx.tag, m) < 0){
366 d3df3087 2003-12-06 devnull err(m, "duplicate tag");
367 d3df3087 2003-12-06 devnull continue;
369 e2a1725d 2005-01-04 devnull msgincref(m);
370 d3df3087 2003-12-06 devnull switch(m->tx.type){
371 ceb04770 2003-12-09 devnull case Tversion:
372 ceb04770 2003-12-09 devnull m->rx.tag = m->tx.tag;
373 ceb04770 2003-12-09 devnull m->rx.msize = m->tx.msize;
374 5a8e63b2 2004-02-29 devnull if(m->rx.msize > msize)
375 5a8e63b2 2004-02-29 devnull m->rx.msize = msize;
376 ceb04770 2003-12-09 devnull m->rx.version = "9P2000";
377 215993f8 2005-09-13 devnull c->dotu = 0;
378 215993f8 2005-09-13 devnull if(dotu && strncmp(m->tx.version, "9P2000.u", 8) == 0){
379 215993f8 2005-09-13 devnull m->rx.version = "9P2000.u";
380 215993f8 2005-09-13 devnull c->dotu = 1;
382 ceb04770 2003-12-09 devnull m->rx.type = Rversion;
383 32f69c36 2003-12-11 devnull send9pmsg(m);
384 ceb04770 2003-12-09 devnull continue;
385 d3df3087 2003-12-06 devnull case Tflush:
386 d3df3087 2003-12-06 devnull if((m->oldm = gethash(c->tag, m->tx.oldtag)) == nil){
387 ceb04770 2003-12-09 devnull m->rx.tag = m->tx.tag;
388 ceb04770 2003-12-09 devnull m->rx.type = Rflush;
389 32f69c36 2003-12-11 devnull send9pmsg(m);
390 d3df3087 2003-12-06 devnull continue;
392 e2a1725d 2005-01-04 devnull msgincref(m->oldm);
394 d3df3087 2003-12-06 devnull case Tattach:
395 ceb04770 2003-12-09 devnull m->afid = nil;
396 ceb04770 2003-12-09 devnull if(m->tx.afid != NOFID
397 ceb04770 2003-12-09 devnull && (m->afid = gethash(c->fid, m->tx.afid)) == nil){
398 ceb04770 2003-12-09 devnull err(m, "unknown fid");
399 ceb04770 2003-12-09 devnull continue;
401 3a6f92ee 2005-03-18 devnull if(m->afid)
402 3a6f92ee 2005-03-18 devnull m->afid->ref++;
403 d3df3087 2003-12-06 devnull m->fid = fidnew(m->tx.fid);
404 d3df3087 2003-12-06 devnull if(puthash(c->fid, m->tx.fid, m->fid) < 0){
405 d3df3087 2003-12-06 devnull err(m, "duplicate fid");
406 d3df3087 2003-12-06 devnull continue;
408 d3df3087 2003-12-06 devnull m->fid->ref++;
409 5c84c448 2005-03-21 devnull if(attached && m->afid==nil){
410 5c84c448 2005-03-21 devnull if(m->tx.aname[0] && strcmp(xaname, m->tx.aname) != 0){
411 5c84c448 2005-03-21 devnull err(m, "invalid attach name");
412 5c84c448 2005-03-21 devnull continue;
414 5c84c448 2005-03-21 devnull m->tx.afid = xafid;
415 5c84c448 2005-03-21 devnull m->tx.aname = xaname;
416 5c84c448 2005-03-21 devnull m->tx.uname = estrdup(m->tx.uname);
417 215993f8 2005-09-13 devnull repack(&m->tx, &m->tpkt, c->dotu);
418 5c84c448 2005-03-21 devnull free(m->tx.uname);
419 5c84c448 2005-03-21 devnull m->tx.uname = "XXX";
422 d3df3087 2003-12-06 devnull case Twalk:
423 d3df3087 2003-12-06 devnull if((m->fid = gethash(c->fid, m->tx.fid)) == nil){
424 d3df3087 2003-12-06 devnull err(m, "unknown fid");
425 d3df3087 2003-12-06 devnull continue;
427 ceb04770 2003-12-09 devnull m->fid->ref++;
428 d3df3087 2003-12-06 devnull if(m->tx.newfid == m->tx.fid){
429 d3df3087 2003-12-06 devnull m->fid->ref++;
430 d3df3087 2003-12-06 devnull m->newfid = m->fid;
432 d3df3087 2003-12-06 devnull m->newfid = fidnew(m->tx.newfid);
433 d3df3087 2003-12-06 devnull if(puthash(c->fid, m->tx.newfid, m->newfid) < 0){
434 d3df3087 2003-12-06 devnull err(m, "duplicate fid");
435 d3df3087 2003-12-06 devnull continue;
437 d3df3087 2003-12-06 devnull m->newfid->ref++;
440 d3df3087 2003-12-06 devnull case Tauth:
441 5c84c448 2005-03-21 devnull if(attached){
442 5c84c448 2005-03-21 devnull err(m, "authentication not required");
443 5c84c448 2005-03-21 devnull continue;
445 ceb04770 2003-12-09 devnull m->afid = fidnew(m->tx.afid);
446 ceb04770 2003-12-09 devnull if(puthash(c->fid, m->tx.afid, m->afid) < 0){
447 d3df3087 2003-12-06 devnull err(m, "duplicate fid");
448 d3df3087 2003-12-06 devnull continue;
450 ceb04770 2003-12-09 devnull m->afid->ref++;
452 32f69c36 2003-12-11 devnull case Topenfd:
453 49588d5d 2003-12-17 devnull if(m->tx.mode&~(OTRUNC|3)){
454 49588d5d 2003-12-17 devnull err(m, "bad openfd mode");
455 32f69c36 2003-12-11 devnull continue;
457 32f69c36 2003-12-11 devnull m->isopenfd = 1;
458 32f69c36 2003-12-11 devnull m->tx.type = Topen;
459 32f69c36 2003-12-11 devnull m->tpkt[4] = Topen;
460 32f69c36 2003-12-11 devnull /* fall through */
461 ceb04770 2003-12-09 devnull case Tcreate:
462 d3df3087 2003-12-06 devnull case Topen:
463 d3df3087 2003-12-06 devnull case Tclunk:
464 d3df3087 2003-12-06 devnull case Tread:
465 d3df3087 2003-12-06 devnull case Twrite:
466 ceb04770 2003-12-09 devnull case Tremove:
467 d3df3087 2003-12-06 devnull case Tstat:
468 d3df3087 2003-12-06 devnull case Twstat:
469 d3df3087 2003-12-06 devnull if((m->fid = gethash(c->fid, m->tx.fid)) == nil){
470 d3df3087 2003-12-06 devnull err(m, "unknown fid");
471 d3df3087 2003-12-06 devnull continue;
473 d3df3087 2003-12-06 devnull m->fid->ref++;
474 215993f8 2005-09-13 devnull if(m->tx.type==Twstat && dotu && !c->dotu){
475 16c1defa 2005-11-12 devnull if(cvtustat(&m->tx, &m->tpkt, 1) < 0){
476 215993f8 2005-09-13 devnull err(m, "cannot convert stat buffer");
477 215993f8 2005-09-13 devnull continue;
480 9777187b 2006-02-03 devnull if(m->tx.type==Tread && m->fid->isdir && dotu && !c->dotu){
481 9777187b 2006-02-03 devnull if(m->tx.offset = m->fid->coffset)
482 9777187b 2006-02-03 devnull m->tx.offset = m->fid->offset;
484 9777187b 2006-02-03 devnull m->fid->offset = m->fid->coffset;
489 d3df3087 2003-12-06 devnull /* have everything - translate and send */
490 d3df3087 2003-12-06 devnull m->c = c;
491 d3df3087 2003-12-06 devnull m->ctag = m->tx.tag;
492 d3df3087 2003-12-06 devnull m->tx.tag = m->tag;
493 d3df3087 2003-12-06 devnull if(m->fid)
494 d3df3087 2003-12-06 devnull m->tx.fid = m->fid->fid;
495 d3df3087 2003-12-06 devnull if(m->newfid)
496 d3df3087 2003-12-06 devnull m->tx.newfid = m->newfid->fid;
497 d3df3087 2003-12-06 devnull if(m->afid)
498 d3df3087 2003-12-06 devnull m->tx.afid = m->afid->fid;
499 d3df3087 2003-12-06 devnull if(m->oldm)
500 d3df3087 2003-12-06 devnull m->tx.oldtag = m->oldm->tag;
501 ceb04770 2003-12-09 devnull /* reference passes to outq */
502 d3df3087 2003-12-06 devnull sendq(outq, m);
503 d3df3087 2003-12-06 devnull while(c->nmsg >= MAXMSG){
504 d3df3087 2003-12-06 devnull c->inputstalled = 1;
505 d3df3087 2003-12-06 devnull recvp(c->inc);
509 e2a1725d 2005-01-04 devnull if(verbose) fprint(2, "%T fd#%d eof; flushing conn\n", c->fd);
511 05b7f431 2004-03-02 devnull /* flush the output queue */
512 05b7f431 2004-03-02 devnull sendq(c->outq, nil);
513 05b7f431 2004-03-02 devnull while(c->outq != nil)
514 05b7f431 2004-03-02 devnull yield();
516 d3df3087 2003-12-06 devnull /* flush all outstanding messages */
517 d3df3087 2003-12-06 devnull for(i=0; i<NHASH; i++){
518 05b7f431 2004-03-02 devnull for(h=c->tag[i]; h; h=hnext){
519 d3df3087 2003-12-06 devnull om = h->v;
520 e2a1725d 2005-01-04 devnull m = msgnew(0);
521 d3df3087 2003-12-06 devnull m->internal = 1;
522 d3df3087 2003-12-06 devnull m->c = c;
523 32f69c36 2003-12-11 devnull c->nmsg++;
524 d3df3087 2003-12-06 devnull m->tx.type = Tflush;
525 d3df3087 2003-12-06 devnull m->tx.tag = m->tag;
526 d3df3087 2003-12-06 devnull m->tx.oldtag = om->tag;
527 d3df3087 2003-12-06 devnull m->oldm = om;
528 e2a1725d 2005-01-04 devnull msgincref(om);
529 e2a1725d 2005-01-04 devnull msgincref(m); /* for outq */
530 ceb04770 2003-12-09 devnull sendomsg(m);
531 05b7f431 2004-03-02 devnull mm = recvp(c->internal);
532 05b7f431 2004-03-02 devnull assert(mm == m);
533 32f69c36 2003-12-11 devnull msgput(m); /* got from recvp */
534 32f69c36 2003-12-11 devnull msgput(m); /* got from msgnew */
535 32f69c36 2003-12-11 devnull msgput(om); /* got from hash table */
536 05b7f431 2004-03-02 devnull hnext = h->next;
537 05b7f431 2004-03-02 devnull free(h);
541 d3df3087 2003-12-06 devnull /* clunk all outstanding fids */
542 d3df3087 2003-12-06 devnull for(i=0; i<NHASH; i++){
543 05b7f431 2004-03-02 devnull for(h=c->fid[i]; h; h=hnext){
544 d3df3087 2003-12-06 devnull f = h->v;
545 e2a1725d 2005-01-04 devnull m = msgnew(0);
546 d3df3087 2003-12-06 devnull m->internal = 1;
547 d3df3087 2003-12-06 devnull m->c = c;
548 32f69c36 2003-12-11 devnull c->nmsg++;
549 d3df3087 2003-12-06 devnull m->tx.type = Tclunk;
550 d3df3087 2003-12-06 devnull m->tx.tag = m->tag;
551 d3df3087 2003-12-06 devnull m->tx.fid = f->fid;
552 d3df3087 2003-12-06 devnull m->fid = f;
553 d3df3087 2003-12-06 devnull f->ref++;
554 e2a1725d 2005-01-04 devnull msgincref(m);
555 ceb04770 2003-12-09 devnull sendomsg(m);
556 05b7f431 2004-03-02 devnull mm = recvp(c->internal);
557 05b7f431 2004-03-02 devnull assert(mm == m);
558 e2a1725d 2005-01-04 devnull msgclear(m);
559 32f69c36 2003-12-11 devnull msgput(m); /* got from recvp */
560 32f69c36 2003-12-11 devnull msgput(m); /* got from msgnew */
561 32f69c36 2003-12-11 devnull fidput(f); /* got from hash table */
562 05b7f431 2004-03-02 devnull hnext = h->next;
563 05b7f431 2004-03-02 devnull free(h);
568 e2a1725d 2005-01-04 devnull closeioproc(io);
569 d3df3087 2003-12-06 devnull assert(c->nmsg == 0);
570 d3df3087 2003-12-06 devnull assert(c->nfid == 0);
571 d3df3087 2003-12-06 devnull close(c->fd);
572 32f69c36 2003-12-11 devnull chanfree(c->internal);
573 32f69c36 2003-12-11 devnull c->internal = 0;
574 32f69c36 2003-12-11 devnull chanfree(c->inc);
575 32f69c36 2003-12-11 devnull c->inc = 0;
576 32f69c36 2003-12-11 devnull free(c->inq);
577 32f69c36 2003-12-11 devnull c->inq = 0;
578 d3df3087 2003-12-06 devnull free(c);
581 32f69c36 2003-12-11 devnull static void
582 32f69c36 2003-12-11 devnull openfdthread(void *v)
584 32f69c36 2003-12-11 devnull Conn *c;
585 32f69c36 2003-12-11 devnull Fid *fid;
588 32f69c36 2003-12-11 devnull vlong tot;
589 32f69c36 2003-12-11 devnull Ioproc *io;
590 32f69c36 2003-12-11 devnull char buf[1024];
593 32f69c36 2003-12-11 devnull fid = c->fdfid;
594 32f69c36 2003-12-11 devnull io = ioproc();
595 7ffc5208 2004-12-28 devnull threadsetname("openfd %s", c->fdfid);
596 32f69c36 2003-12-11 devnull tot = 0;
597 05b7f431 2004-03-02 devnull m = nil;
598 32f69c36 2003-12-11 devnull if(c->fdmode == OREAD){
599 32f69c36 2003-12-11 devnull for(;;){
600 e2a1725d 2005-01-04 devnull if(verbose) fprint(2, "%T tread...");
601 e2a1725d 2005-01-04 devnull m = msgnew(0);
602 32f69c36 2003-12-11 devnull m->internal = 1;
603 32f69c36 2003-12-11 devnull m->c = c;
604 32f69c36 2003-12-11 devnull m->tx.type = Tread;
605 5a8e63b2 2004-02-29 devnull m->tx.count = msize - IOHDRSZ;
606 32f69c36 2003-12-11 devnull m->tx.fid = fid->fid;
607 32f69c36 2003-12-11 devnull m->tx.tag = m->tag;
608 32f69c36 2003-12-11 devnull m->tx.offset = tot;
609 32f69c36 2003-12-11 devnull m->fid = fid;
610 32f69c36 2003-12-11 devnull fid->ref++;
611 e2a1725d 2005-01-04 devnull msgincref(m);
612 32f69c36 2003-12-11 devnull sendomsg(m);
613 32f69c36 2003-12-11 devnull recvp(c->internal);
614 49588d5d 2003-12-17 devnull if(m->rx.type == Rerror){
615 e2a1725d 2005-01-04 devnull // fprint(2, "%T read error: %s\n", m->rx.ename);
618 32f69c36 2003-12-11 devnull if(m->rx.count == 0)
620 32f69c36 2003-12-11 devnull tot += m->rx.count;
621 49588d5d 2003-12-17 devnull if(iowrite(io, c->fd, m->rx.data, m->rx.count) != m->rx.count){
622 e2a1725d 2005-01-04 devnull // fprint(2, "%T pipe write error: %r\n");
625 32f69c36 2003-12-11 devnull msgput(m);
626 32f69c36 2003-12-11 devnull msgput(m);
627 05b7f431 2004-03-02 devnull m = nil;
630 32f69c36 2003-12-11 devnull for(;;){
631 e2a1725d 2005-01-04 devnull if(verbose) fprint(2, "%T twrite...");
632 5a8e63b2 2004-02-29 devnull n = sizeof buf;
633 5a8e63b2 2004-02-29 devnull if(n > msize)
634 5a8e63b2 2004-02-29 devnull n = msize;
635 5a8e63b2 2004-02-29 devnull if((n=ioread(io, c->fd, buf, n)) <= 0){
636 49588d5d 2003-12-17 devnull if(n < 0)
637 e2a1725d 2005-01-04 devnull fprint(2, "%T pipe read error: %r\n");
640 e2a1725d 2005-01-04 devnull m = msgnew(0);
641 32f69c36 2003-12-11 devnull m->internal = 1;
642 32f69c36 2003-12-11 devnull m->c = c;
643 32f69c36 2003-12-11 devnull m->tx.type = Twrite;
644 32f69c36 2003-12-11 devnull m->tx.fid = fid->fid;
645 32f69c36 2003-12-11 devnull m->tx.data = buf;
646 32f69c36 2003-12-11 devnull m->tx.count = n;
647 32f69c36 2003-12-11 devnull m->tx.tag = m->tag;
648 32f69c36 2003-12-11 devnull m->tx.offset = tot;
649 32f69c36 2003-12-11 devnull m->fid = fid;
650 32f69c36 2003-12-11 devnull fid->ref++;
651 e2a1725d 2005-01-04 devnull msgincref(m);
652 32f69c36 2003-12-11 devnull sendomsg(m);
653 32f69c36 2003-12-11 devnull recvp(c->internal);
654 49588d5d 2003-12-17 devnull if(m->rx.type == Rerror){
655 e2a1725d 2005-01-04 devnull // fprint(2, "%T write error: %s\n", m->rx.ename);
657 05b7f431 2004-03-02 devnull tot += n;
658 32f69c36 2003-12-11 devnull msgput(m);
659 32f69c36 2003-12-11 devnull msgput(m);
660 05b7f431 2004-03-02 devnull m = nil;
663 e2a1725d 2005-01-04 devnull if(verbose) fprint(2, "%T eof on %d fid %d\n", c->fd, fid->fid);
664 32f69c36 2003-12-11 devnull close(c->fd);
665 32f69c36 2003-12-11 devnull closeioproc(io);
667 32f69c36 2003-12-11 devnull msgput(m);
668 32f69c36 2003-12-11 devnull msgput(m);
670 e2a1725d 2005-01-04 devnull if(verbose) fprint(2, "%T eof on %d fid %d ref %d\n", c->fd, fid->fid, fid->ref);
671 21e626de 2004-12-28 devnull if(--fid->openfd == 0){
672 e2a1725d 2005-01-04 devnull m = msgnew(0);
673 49588d5d 2003-12-17 devnull m->internal = 1;
674 49588d5d 2003-12-17 devnull m->c = c;
675 49588d5d 2003-12-17 devnull m->tx.type = Tclunk;
676 05b7f431 2004-03-02 devnull m->tx.tag = m->tag;
677 49588d5d 2003-12-17 devnull m->tx.fid = fid->fid;
678 49588d5d 2003-12-17 devnull m->fid = fid;
679 49588d5d 2003-12-17 devnull fid->ref++;
680 e2a1725d 2005-01-04 devnull msgincref(m);
681 49588d5d 2003-12-17 devnull sendomsg(m);
682 49588d5d 2003-12-17 devnull recvp(c->internal);
683 49588d5d 2003-12-17 devnull msgput(m);
684 49588d5d 2003-12-17 devnull msgput(m);
686 32f69c36 2003-12-11 devnull fidput(fid);
687 32f69c36 2003-12-11 devnull c->fdfid = nil;
688 32f69c36 2003-12-11 devnull chanfree(c->internal);
689 32f69c36 2003-12-11 devnull c->internal = 0;
690 32f69c36 2003-12-11 devnull free(c);
694 32f69c36 2003-12-11 devnull xopenfd(Msg *m)
696 32f69c36 2003-12-11 devnull char errs[ERRMAX];
697 32f69c36 2003-12-11 devnull int n, p[2];
698 32f69c36 2003-12-11 devnull Conn *nc;
700 32f69c36 2003-12-11 devnull if(pipe(p) < 0){
701 32f69c36 2003-12-11 devnull rerrstr(errs, sizeof errs);
702 32f69c36 2003-12-11 devnull err(m, errs);
703 21e626de 2004-12-28 devnull /* XXX return here? */
705 e2a1725d 2005-01-04 devnull if(verbose) fprint(2, "%T xopen pipe %d %d...", p[0], p[1]);
707 32f69c36 2003-12-11 devnull /* now we're committed. */
709 32f69c36 2003-12-11 devnull /* a new connection for this fid */
710 32f69c36 2003-12-11 devnull nc = emalloc(sizeof(Conn));
711 32f69c36 2003-12-11 devnull nc->internal = chancreate(sizeof(void*), 0);
713 32f69c36 2003-12-11 devnull /* a ref for us */
714 32f69c36 2003-12-11 devnull nc->fdfid = m->fid;
715 32f69c36 2003-12-11 devnull m->fid->ref++;
716 21e626de 2004-12-28 devnull nc->fdfid->openfd++;
717 32f69c36 2003-12-11 devnull nc->fdmode = m->tx.mode;
718 32f69c36 2003-12-11 devnull nc->fd = p[0];
720 32f69c36 2003-12-11 devnull /* a thread to tend the pipe */
721 32f69c36 2003-12-11 devnull threadcreate(openfdthread, nc, STACK);
723 49588d5d 2003-12-17 devnull /* if mode is ORDWR, that openfdthread will write; start a reader */
724 49588d5d 2003-12-17 devnull if((m->tx.mode&3) == ORDWR){
725 49588d5d 2003-12-17 devnull nc = emalloc(sizeof(Conn));
726 49588d5d 2003-12-17 devnull nc->internal = chancreate(sizeof(void*), 0);
727 49588d5d 2003-12-17 devnull nc->fdfid = m->fid;
728 49588d5d 2003-12-17 devnull m->fid->ref++;
729 21e626de 2004-12-28 devnull nc->fdfid->openfd++;
730 49588d5d 2003-12-17 devnull nc->fdmode = OREAD;
731 49588d5d 2003-12-17 devnull nc->fd = dup(p[0], -1);
732 49588d5d 2003-12-17 devnull threadcreate(openfdthread, nc, STACK);
735 49588d5d 2003-12-17 devnull /* steal fid from other connection */
736 49588d5d 2003-12-17 devnull if(delhash(m->c->fid, m->fid->cfid, m->fid) == 0)
737 49588d5d 2003-12-17 devnull fidput(m->fid);
739 32f69c36 2003-12-11 devnull /* rewrite as Ropenfd */
740 32f69c36 2003-12-11 devnull m->rx.type = Ropenfd;
741 32f69c36 2003-12-11 devnull n = GBIT32(m->rpkt);
742 32f69c36 2003-12-11 devnull m->rpkt = erealloc(m->rpkt, n+4);
743 32f69c36 2003-12-11 devnull PBIT32(m->rpkt+n, p[1]);
745 32f69c36 2003-12-11 devnull PBIT32(m->rpkt, n);
746 32f69c36 2003-12-11 devnull m->rpkt[4] = Ropenfd;
747 32f69c36 2003-12-11 devnull m->rx.unixfd = p[1];
748 32f69c36 2003-12-11 devnull return 0;
752 d3df3087 2003-12-06 devnull connoutthread(void *arg)
754 215993f8 2005-09-13 devnull char *ename;
755 d3df3087 2003-12-06 devnull int err;
756 d3df3087 2003-12-06 devnull Conn *c;
757 05b7f431 2004-03-02 devnull Queue *outq;
758 d3df3087 2003-12-06 devnull Msg *m, *om;
759 ceb04770 2003-12-09 devnull Ioproc *io;
761 d3df3087 2003-12-06 devnull c = arg;
762 05b7f431 2004-03-02 devnull outq = c->outq;
763 ceb04770 2003-12-09 devnull io = ioproc();
764 7ffc5208 2004-12-28 devnull threadsetname("connout %s", c->dir);
765 05b7f431 2004-03-02 devnull while((m = recvq(outq)) != nil){
766 d3df3087 2003-12-06 devnull err = m->tx.type+1 != m->rx.type;
767 32f69c36 2003-12-11 devnull if(!err && m->isopenfd)
768 32f69c36 2003-12-11 devnull if(xopenfd(m) < 0)
769 32f69c36 2003-12-11 devnull continue;
770 d3df3087 2003-12-06 devnull switch(m->tx.type){
771 d3df3087 2003-12-06 devnull case Tflush:
772 d3df3087 2003-12-06 devnull om = m->oldm;
774 ceb04770 2003-12-09 devnull if(delhash(om->c->tag, om->ctag, om) == 0)
775 ceb04770 2003-12-09 devnull msgput(om);
777 d3df3087 2003-12-06 devnull case Tclunk:
778 ceb04770 2003-12-09 devnull case Tremove:
779 ceb04770 2003-12-09 devnull if(m->fid)
780 ceb04770 2003-12-09 devnull if(delhash(m->c->fid, m->fid->cfid, m->fid) == 0)
781 ceb04770 2003-12-09 devnull fidput(m->fid);
783 d3df3087 2003-12-06 devnull case Tauth:
784 ceb04770 2003-12-09 devnull if(err && m->afid){
785 80568494 2005-02-11 devnull if(verbose) fprint(2, "%T auth error\n");
786 ceb04770 2003-12-09 devnull if(delhash(m->c->fid, m->afid->cfid, m->afid) == 0)
787 80568494 2005-02-11 devnull fidput(m->afid);
790 d3df3087 2003-12-06 devnull case Tattach:
791 ceb04770 2003-12-09 devnull if(err && m->fid)
792 d3df3087 2003-12-06 devnull if(delhash(m->c->fid, m->fid->cfid, m->fid) == 0)
793 d3df3087 2003-12-06 devnull fidput(m->fid);
795 d3df3087 2003-12-06 devnull case Twalk:
796 5c84c448 2005-03-21 devnull if(err || m->rx.nwqid < m->tx.nwname)
797 5c84c448 2005-03-21 devnull if(m->tx.fid != m->tx.newfid && m->newfid)
798 d3df3087 2003-12-06 devnull if(delhash(m->c->fid, m->newfid->cfid, m->newfid) == 0)
799 d3df3087 2003-12-06 devnull fidput(m->newfid);
801 215993f8 2005-09-13 devnull case Tread:
802 9777187b 2006-02-03 devnull if(!err && m->fid->isdir && dotu && !m->c->dotu){
803 9777187b 2006-02-03 devnull m->fid->offset += m->rx.count;
804 215993f8 2005-09-13 devnull stripudirread(m);
805 9777187b 2006-02-03 devnull m->fid->coffset += m->rx.count;
808 215993f8 2005-09-13 devnull case Tstat:
809 215993f8 2005-09-13 devnull if(!err && dotu && !m->c->dotu)
810 16c1defa 2005-11-12 devnull cvtustat(&m->rx, &m->rpkt, 0);
812 215993f8 2005-09-13 devnull case Topen:
813 215993f8 2005-09-13 devnull case Tcreate:
814 215993f8 2005-09-13 devnull m->fid->isdir = (m->rx.qid.type & QTDIR);
817 215993f8 2005-09-13 devnull if(m->rx.type==Rerror && dotu && !c->dotu){
818 215993f8 2005-09-13 devnull ename = estrdup(m->rx.ename);
819 215993f8 2005-09-13 devnull m->rx.ename = ename;
820 215993f8 2005-09-13 devnull repack(&m->rx, &m->rpkt, c->dotu);
821 215993f8 2005-09-13 devnull free(ename);
822 16c1defa 2005-11-12 devnull m->rx.ename = "XXX";
824 d3df3087 2003-12-06 devnull if(delhash(m->c->tag, m->ctag, m) == 0)
825 d3df3087 2003-12-06 devnull msgput(m);
826 e2a1725d 2005-01-04 devnull if(verbose > 1) fprint(2, "%T fd#%d <- %F\n", c->fd, &m->rx);
827 ceb04770 2003-12-09 devnull rewritehdr(&m->rx, m->rpkt);
828 ceb04770 2003-12-09 devnull if(mwrite9p(io, c->fd, m->rpkt) < 0)
829 e2a1725d 2005-01-04 devnull if(verbose) fprint(2, "%T write error: %r\n");
830 d3df3087 2003-12-06 devnull msgput(m);
831 d3df3087 2003-12-06 devnull if(c->inputstalled && c->nmsg < MAXMSG)
832 d3df3087 2003-12-06 devnull nbsendp(c->inc, 0);
834 ceb04770 2003-12-09 devnull closeioproc(io);
835 05b7f431 2004-03-02 devnull free(outq);
836 05b7f431 2004-03-02 devnull c->outq = nil;
840 d3df3087 2003-12-06 devnull outputthread(void *arg)
843 ceb04770 2003-12-09 devnull Ioproc *io;
845 d3df3087 2003-12-06 devnull USED(arg);
846 ceb04770 2003-12-09 devnull io = ioproc();
847 7ffc5208 2004-12-28 devnull threadsetname("output");
848 d3df3087 2003-12-06 devnull while((m = recvq(outq)) != nil){
849 e2a1725d 2005-01-04 devnull if(verbose > 1) fprint(2, "%T * <- %F\n", &m->tx);
850 ceb04770 2003-12-09 devnull rewritehdr(&m->tx, m->tpkt);
851 ceb04770 2003-12-09 devnull if(mwrite9p(io, 1, m->tpkt) < 0)
852 d3df3087 2003-12-06 devnull sysfatal("output error: %r");
853 d3df3087 2003-12-06 devnull msgput(m);
855 ceb04770 2003-12-09 devnull closeioproc(io);
856 e2a1725d 2005-01-04 devnull fprint(2, "%T output eof\n");
857 32f69c36 2003-12-11 devnull threadexitsall(0);
861 d3df3087 2003-12-06 devnull inputthread(void *arg)
863 d3df3087 2003-12-06 devnull uchar *pkt;
864 d3df3087 2003-12-06 devnull int n, nn, tag;
866 ceb04770 2003-12-09 devnull Ioproc *io;
868 7ffc5208 2004-12-28 devnull threadsetname("input");
869 e2a1725d 2005-01-04 devnull if(verbose) fprint(2, "%T input thread\n");
870 ceb04770 2003-12-09 devnull io = ioproc();
871 ceb04770 2003-12-09 devnull USED(arg);
872 ceb04770 2003-12-09 devnull while((pkt = read9ppkt(io, 0)) != nil){
873 d3df3087 2003-12-06 devnull n = GBIT32(pkt);
874 d3df3087 2003-12-06 devnull if(n < 7){
875 e2a1725d 2005-01-04 devnull fprint(2, "%T short 9P packet from server\n");
876 d3df3087 2003-12-06 devnull free(pkt);
877 d3df3087 2003-12-06 devnull continue;
879 e2a1725d 2005-01-04 devnull if(verbose > 2) fprint(2, "%T read %.*H\n", n, pkt);
880 d3df3087 2003-12-06 devnull tag = GBIT16(pkt+5);
881 d3df3087 2003-12-06 devnull if((m = msgget(tag)) == nil){
882 e2a1725d 2005-01-04 devnull fprint(2, "%T unexpected 9P response tag %d\n", tag);
883 d3df3087 2003-12-06 devnull free(pkt);
884 d3df3087 2003-12-06 devnull continue;
886 215993f8 2005-09-13 devnull if((nn = convM2Su(pkt, n, &m->rx, dotu)) != n){
887 e2a1725d 2005-01-04 devnull fprint(2, "%T bad packet - convM2S %d but %d\n", nn, n);
888 d3df3087 2003-12-06 devnull free(pkt);
889 d3df3087 2003-12-06 devnull msgput(m);
890 d3df3087 2003-12-06 devnull continue;
892 e2a1725d 2005-01-04 devnull if(verbose > 1) fprint(2, "%T * -> %F%s\n", &m->rx,
893 05b7f431 2004-03-02 devnull m->internal ? " (internal)" : "");
894 d3df3087 2003-12-06 devnull m->rpkt = pkt;
895 d3df3087 2003-12-06 devnull m->rx.tag = m->ctag;
896 ceb04770 2003-12-09 devnull if(m->internal)
897 05b7f431 2004-03-02 devnull sendp(m->c->internal, m);
898 05b7f431 2004-03-02 devnull else if(m->c->outq)
899 ceb04770 2003-12-09 devnull sendq(m->c->outq, m);
901 05b7f431 2004-03-02 devnull msgput(m);
903 ceb04770 2003-12-09 devnull closeioproc(io);
904 e2a1725d 2005-01-04 devnull //fprint(2, "%T input eof\n");
905 32f69c36 2003-12-11 devnull threadexitsall(0);
909 d3df3087 2003-12-06 devnull gethash(Hash **ht, uint n)
911 d3df3087 2003-12-06 devnull Hash *h;
913 d3df3087 2003-12-06 devnull for(h=ht[n%NHASH]; h; h=h->next)
914 d3df3087 2003-12-06 devnull if(h->n == n)
915 d3df3087 2003-12-06 devnull return h->v;
916 d3df3087 2003-12-06 devnull return nil;
920 d3df3087 2003-12-06 devnull delhash(Hash **ht, uint n, void *v)
922 d3df3087 2003-12-06 devnull Hash *h, **l;
924 d3df3087 2003-12-06 devnull for(l=&ht[n%NHASH]; h=*l; l=&h->next)
925 d3df3087 2003-12-06 devnull if(h->n == n){
926 ceb04770 2003-12-09 devnull if(h->v != v){
927 e2a1725d 2005-01-04 devnull if(verbose) fprint(2, "%T delhash %d got %p want %p\n", n, h->v, v);
928 ceb04770 2003-12-09 devnull return -1;
930 d3df3087 2003-12-06 devnull *l = h->next;
931 d3df3087 2003-12-06 devnull free(h);
932 d3df3087 2003-12-06 devnull return 0;
934 d3df3087 2003-12-06 devnull return -1;
938 d3df3087 2003-12-06 devnull puthash(Hash **ht, uint n, void *v)
940 d3df3087 2003-12-06 devnull Hash *h;
942 d3df3087 2003-12-06 devnull if(gethash(ht, n))
943 d3df3087 2003-12-06 devnull return -1;
944 d3df3087 2003-12-06 devnull h = emalloc(sizeof(Hash));
945 d3df3087 2003-12-06 devnull h->next = ht[n%NHASH];
946 d3df3087 2003-12-06 devnull h->n = n;
947 d3df3087 2003-12-06 devnull h->v = v;
948 d3df3087 2003-12-06 devnull ht[n%NHASH] = h;
949 d3df3087 2003-12-06 devnull return 0;
952 d3df3087 2003-12-06 devnull Fid **fidtab;
953 d3df3087 2003-12-06 devnull int nfidtab;
954 d3df3087 2003-12-06 devnull Fid *freefid;
957 d3df3087 2003-12-06 devnull fidnew(int cfid)
961 d3df3087 2003-12-06 devnull if(freefid == nil){
962 ceb04770 2003-12-09 devnull fidtab = erealloc(fidtab, (nfidtab+1)*sizeof(fidtab[0]));
963 5c84c448 2005-03-21 devnull if(nfidtab == xafid){
964 5c84c448 2005-03-21 devnull fidtab[nfidtab++] = nil;
965 5c84c448 2005-03-21 devnull fidtab = erealloc(fidtab, (nfidtab+1)*sizeof(fidtab[0]));
967 d3df3087 2003-12-06 devnull fidtab[nfidtab] = emalloc(sizeof(Fid));
968 ceb04770 2003-12-09 devnull freefid = fidtab[nfidtab];
969 ceb04770 2003-12-09 devnull freefid->fid = nfidtab++;
971 d3df3087 2003-12-06 devnull f = freefid;
972 d3df3087 2003-12-06 devnull freefid = f->next;
973 ceb04770 2003-12-09 devnull f->cfid = cfid;
974 d3df3087 2003-12-06 devnull f->ref = 1;
975 9777187b 2006-02-03 devnull f->offset = 0;
976 9777187b 2006-02-03 devnull f->coffset = 0;
977 215993f8 2005-09-13 devnull f->isdir = -1;
978 d3df3087 2003-12-06 devnull return f;
982 d3df3087 2003-12-06 devnull fidput(Fid *f)
984 ceb04770 2003-12-09 devnull if(f == nil)
986 d3df3087 2003-12-06 devnull assert(f->ref > 0);
987 d3df3087 2003-12-06 devnull if(--f->ref > 0)
989 d3df3087 2003-12-06 devnull f->next = freefid;
990 d3df3087 2003-12-06 devnull f->cfid = -1;
991 d3df3087 2003-12-06 devnull freefid = f;
994 d3df3087 2003-12-06 devnull Msg **msgtab;
995 d3df3087 2003-12-06 devnull int nmsgtab;
996 16c1defa 2005-11-12 devnull int nmsg;
997 d3df3087 2003-12-06 devnull Msg *freemsg;
1000 e2a1725d 2005-01-04 devnull msgincref(Msg *m)
1002 e2a1725d 2005-01-04 devnull if(verbose > 1) fprint(2, "%T msgincref @0x%lux %p tag %d/%d ref %d=>%d\n",
1003 e2a1725d 2005-01-04 devnull getcallerpc(&m), m, m->tag, m->ctag, m->ref, m->ref+1);
1004 e2a1725d 2005-01-04 devnull m->ref++;
1008 e2a1725d 2005-01-04 devnull msgnew(int x)
1010 d3df3087 2003-12-06 devnull Msg *m;
1012 d3df3087 2003-12-06 devnull if(freemsg == nil){
1013 ceb04770 2003-12-09 devnull msgtab = erealloc(msgtab, (nmsgtab+1)*sizeof(msgtab[0]));
1014 d3df3087 2003-12-06 devnull msgtab[nmsgtab] = emalloc(sizeof(Msg));
1015 ceb04770 2003-12-09 devnull freemsg = msgtab[nmsgtab];
1016 ceb04770 2003-12-09 devnull freemsg->tag = nmsgtab++;
1018 d3df3087 2003-12-06 devnull m = freemsg;
1019 d3df3087 2003-12-06 devnull freemsg = m->next;
1020 d3df3087 2003-12-06 devnull m->ref = 1;
1021 e2a1725d 2005-01-04 devnull if(verbose > 1) fprint(2, "%T msgnew @0x%lux %p tag %d ref %d\n",
1022 e2a1725d 2005-01-04 devnull getcallerpc(&x), m, m->tag, m->ref);
1023 16c1defa 2005-11-12 devnull nmsg++;
1024 d3df3087 2003-12-06 devnull return m;
1028 e2a1725d 2005-01-04 devnull * Clear data associated with connections, so that
1029 e2a1725d 2005-01-04 devnull * if all msgs have been msgcleared, the connection
1030 e2a1725d 2005-01-04 devnull * can be freed. Note that this does *not* free the tpkt
1031 e2a1725d 2005-01-04 devnull * and rpkt; they are freed in msgput with the msg itself.
1032 e2a1725d 2005-01-04 devnull * The io write thread might still be holding a ref to msg
1033 e2a1725d 2005-01-04 devnull * even once the connection has finished with it.
1036 e2a1725d 2005-01-04 devnull msgclear(Msg *m)
1038 e2a1725d 2005-01-04 devnull if(m->c){
1039 e2a1725d 2005-01-04 devnull m->c->nmsg--;
1040 e2a1725d 2005-01-04 devnull m->c = nil;
1042 e2a1725d 2005-01-04 devnull if(m->oldm){
1043 e2a1725d 2005-01-04 devnull msgput(m->oldm);
1044 e2a1725d 2005-01-04 devnull m->oldm = nil;
1046 e2a1725d 2005-01-04 devnull if(m->fid){
1047 e2a1725d 2005-01-04 devnull fidput(m->fid);
1048 e2a1725d 2005-01-04 devnull m->fid = nil;
1050 e2a1725d 2005-01-04 devnull if(m->afid){
1051 e2a1725d 2005-01-04 devnull fidput(m->afid);
1052 e2a1725d 2005-01-04 devnull m->afid = nil;
1054 e2a1725d 2005-01-04 devnull if(m->newfid){
1055 e2a1725d 2005-01-04 devnull fidput(m->newfid);
1056 e2a1725d 2005-01-04 devnull m->newfid = nil;
1058 e2a1725d 2005-01-04 devnull if(m->rx.type == Ropenfd && m->rx.unixfd >= 0){
1059 e2a1725d 2005-01-04 devnull close(m->rx.unixfd);
1060 e2a1725d 2005-01-04 devnull m->rx.unixfd = -1;
1065 d3df3087 2003-12-06 devnull msgput(Msg *m)
1067 05b7f431 2004-03-02 devnull if(m == nil)
1068 05b7f431 2004-03-02 devnull return;
1070 e2a1725d 2005-01-04 devnull if(verbose > 1) fprint(2, "%T msgput 0x%lux %p tag %d/%d ref %d\n",
1071 e2a1725d 2005-01-04 devnull getcallerpc(&m), m, m->tag, m->ctag, m->ref);
1072 d3df3087 2003-12-06 devnull assert(m->ref > 0);
1073 d3df3087 2003-12-06 devnull if(--m->ref > 0)
1074 d3df3087 2003-12-06 devnull return;
1075 16c1defa 2005-11-12 devnull nmsg--;
1076 e2a1725d 2005-01-04 devnull msgclear(m);
1077 e2a1725d 2005-01-04 devnull if(m->tpkt){
1078 e2a1725d 2005-01-04 devnull free(m->tpkt);
1079 e2a1725d 2005-01-04 devnull m->tpkt = nil;
1081 e2a1725d 2005-01-04 devnull if(m->rpkt){
1082 e2a1725d 2005-01-04 devnull free(m->rpkt);
1083 e2a1725d 2005-01-04 devnull m->rpkt = nil;
1085 32f69c36 2003-12-11 devnull m->isopenfd = 0;
1086 32f69c36 2003-12-11 devnull m->internal = 0;
1087 d3df3087 2003-12-06 devnull m->next = freemsg;
1088 d3df3087 2003-12-06 devnull freemsg = m;
1092 ceb04770 2003-12-09 devnull msgget(int n)
1094 ceb04770 2003-12-09 devnull Msg *m;
1096 ceb04770 2003-12-09 devnull if(n < 0 || n >= nmsgtab)
1097 ceb04770 2003-12-09 devnull return nil;
1098 ceb04770 2003-12-09 devnull m = msgtab[n];
1099 ceb04770 2003-12-09 devnull if(m->ref == 0)
1100 ceb04770 2003-12-09 devnull return nil;
1101 e2a1725d 2005-01-04 devnull if(verbose) fprint(2, "%T msgget %d = %p\n", n, m);
1102 e2a1725d 2005-01-04 devnull msgincref(m);
1103 ceb04770 2003-12-09 devnull return m;
1108 d3df3087 2003-12-06 devnull emalloc(int n)
1110 d3df3087 2003-12-06 devnull void *v;
1112 d3df3087 2003-12-06 devnull v = mallocz(n, 1);
1113 ceb04770 2003-12-09 devnull if(v == nil){
1114 ceb04770 2003-12-09 devnull abort();
1115 ceb04770 2003-12-09 devnull sysfatal("out of memory allocating %d", n);
1117 d3df3087 2003-12-06 devnull return v;
1121 d3df3087 2003-12-06 devnull erealloc(void *v, int n)
1123 d3df3087 2003-12-06 devnull v = realloc(v, n);
1124 ceb04770 2003-12-09 devnull if(v == nil){
1125 ceb04770 2003-12-09 devnull abort();
1126 ceb04770 2003-12-09 devnull sysfatal("out of memory reallocating %d", n);
1128 d3df3087 2003-12-06 devnull return v;
1131 d3df3087 2003-12-06 devnull typedef struct Qel Qel;
1132 d3df3087 2003-12-06 devnull struct Qel
1134 d3df3087 2003-12-06 devnull Qel *next;
1135 d3df3087 2003-12-06 devnull void *p;
1138 d3df3087 2003-12-06 devnull struct Queue
1140 d3df3087 2003-12-06 devnull int hungup;
1141 d3df3087 2003-12-06 devnull QLock lk;
1142 d3df3087 2003-12-06 devnull Rendez r;
1143 d3df3087 2003-12-06 devnull Qel *head;
1144 d3df3087 2003-12-06 devnull Qel *tail;
1148 d3df3087 2003-12-06 devnull qalloc(void)
1150 d3df3087 2003-12-06 devnull Queue *q;
1152 d3df3087 2003-12-06 devnull q = mallocz(sizeof(Queue), 1);
1153 d3df3087 2003-12-06 devnull if(q == nil)
1154 d3df3087 2003-12-06 devnull return nil;
1155 d3df3087 2003-12-06 devnull q->r.l = &q->lk;
1156 d3df3087 2003-12-06 devnull return q;
1160 d3df3087 2003-12-06 devnull sendq(Queue *q, void *p)
1162 d3df3087 2003-12-06 devnull Qel *e;
1164 d3df3087 2003-12-06 devnull e = emalloc(sizeof(Qel));
1165 d3df3087 2003-12-06 devnull qlock(&q->lk);
1166 d3df3087 2003-12-06 devnull if(q->hungup){
1167 16c1defa 2005-11-12 devnull free(e);
1168 d3df3087 2003-12-06 devnull werrstr("hungup queue");
1169 d3df3087 2003-12-06 devnull qunlock(&q->lk);
1170 d3df3087 2003-12-06 devnull return -1;
1172 d3df3087 2003-12-06 devnull e->p = p;
1173 d3df3087 2003-12-06 devnull e->next = nil;
1174 d3df3087 2003-12-06 devnull if(q->head == nil)
1175 d3df3087 2003-12-06 devnull q->head = e;
1177 d3df3087 2003-12-06 devnull q->tail->next = e;
1178 d3df3087 2003-12-06 devnull q->tail = e;
1179 d3df3087 2003-12-06 devnull rwakeup(&q->r);
1180 d3df3087 2003-12-06 devnull qunlock(&q->lk);
1181 d3df3087 2003-12-06 devnull return 0;
1185 d3df3087 2003-12-06 devnull recvq(Queue *q)
1187 d3df3087 2003-12-06 devnull void *p;
1188 d3df3087 2003-12-06 devnull Qel *e;
1190 d3df3087 2003-12-06 devnull qlock(&q->lk);
1191 d3df3087 2003-12-06 devnull while(q->head == nil && !q->hungup)
1192 d3df3087 2003-12-06 devnull rsleep(&q->r);
1193 d3df3087 2003-12-06 devnull if(q->hungup){
1194 d3df3087 2003-12-06 devnull qunlock(&q->lk);
1195 d3df3087 2003-12-06 devnull return nil;
1197 d3df3087 2003-12-06 devnull e = q->head;
1198 d3df3087 2003-12-06 devnull q->head = e->next;
1199 d3df3087 2003-12-06 devnull qunlock(&q->lk);
1200 d3df3087 2003-12-06 devnull p = e->p;
1201 d3df3087 2003-12-06 devnull free(e);
1202 d3df3087 2003-12-06 devnull return p;
1206 ceb04770 2003-12-09 devnull read9ppkt(Ioproc *io, int fd)
1208 ceb04770 2003-12-09 devnull uchar buf[4], *pkt;
1209 ceb04770 2003-12-09 devnull int n, nn;
1211 ceb04770 2003-12-09 devnull n = ioreadn(io, fd, buf, 4);
1212 ceb04770 2003-12-09 devnull if(n != 4)
1213 ceb04770 2003-12-09 devnull return nil;
1214 ceb04770 2003-12-09 devnull n = GBIT32(buf);
1215 ceb04770 2003-12-09 devnull pkt = emalloc(n);
1216 ceb04770 2003-12-09 devnull PBIT32(pkt, n);
1217 ceb04770 2003-12-09 devnull nn = ioreadn(io, fd, pkt+4, n-4);
1218 ceb04770 2003-12-09 devnull if(nn != n-4){
1219 ceb04770 2003-12-09 devnull free(pkt);
1220 ceb04770 2003-12-09 devnull return nil;
1222 32f69c36 2003-12-11 devnull /* would do this if we ever got one of these, but we only generate them
1223 32f69c36 2003-12-11 devnull if(pkt[4] == Ropenfd){
1224 32f69c36 2003-12-11 devnull newfd = iorecvfd(io, fd);
1225 32f69c36 2003-12-11 devnull PBIT32(pkt+n-4, newfd);
1228 ceb04770 2003-12-09 devnull return pkt;
1232 215993f8 2005-09-13 devnull mread9p(Ioproc *io, int fd, int dotu)
1234 ceb04770 2003-12-09 devnull int n, nn;
1235 ceb04770 2003-12-09 devnull uchar *pkt;
1236 ceb04770 2003-12-09 devnull Msg *m;
1238 ceb04770 2003-12-09 devnull if((pkt = read9ppkt(io, fd)) == nil)
1239 ceb04770 2003-12-09 devnull return nil;
1241 e2a1725d 2005-01-04 devnull m = msgnew(0);
1242 ceb04770 2003-12-09 devnull m->tpkt = pkt;
1243 ceb04770 2003-12-09 devnull n = GBIT32(pkt);
1244 215993f8 2005-09-13 devnull nn = convM2Su(pkt, n, &m->tx, dotu);
1245 ceb04770 2003-12-09 devnull if(nn != n){
1246 e2a1725d 2005-01-04 devnull fprint(2, "%T read bad packet from %d\n", fd);
1247 ceb04770 2003-12-09 devnull return nil;
1249 ceb04770 2003-12-09 devnull return m;
1253 ceb04770 2003-12-09 devnull mwrite9p(Ioproc *io, int fd, uchar *pkt)
1255 32f69c36 2003-12-11 devnull int n, nfd;
1257 ceb04770 2003-12-09 devnull n = GBIT32(pkt);
1258 e2a1725d 2005-01-04 devnull if(verbose > 2) fprint(2, "%T write %d %d %.*H\n", fd, n, n, pkt);
1259 bb426e77 2005-01-06 devnull if(verbose > 1) fprint(2, "%T before iowrite\n");
1260 ceb04770 2003-12-09 devnull if(iowrite(io, fd, pkt, n) != n){
1261 e2a1725d 2005-01-04 devnull fprint(2, "%T write error: %r\n");
1262 ceb04770 2003-12-09 devnull return -1;
1264 bb426e77 2005-01-06 devnull if(verbose > 1) fprint(2, "%T after iowrite\n");
1265 32f69c36 2003-12-11 devnull if(pkt[4] == Ropenfd){
1266 32f69c36 2003-12-11 devnull nfd = GBIT32(pkt+n-4);
1267 32f69c36 2003-12-11 devnull if(iosendfd(io, fd, nfd) < 0){
1268 e2a1725d 2005-01-04 devnull fprint(2, "%T send fd error: %r\n");
1269 32f69c36 2003-12-11 devnull return -1;
1272 ceb04770 2003-12-09 devnull return 0;
1276 ceb04770 2003-12-09 devnull restring(uchar *pkt, int pn, char *s)
1280 ceb04770 2003-12-09 devnull if(s < (char*)pkt || s >= (char*)pkt+pn)
1281 ceb04770 2003-12-09 devnull return;
1283 ceb04770 2003-12-09 devnull n = strlen(s);
1284 ceb04770 2003-12-09 devnull memmove(s+1, s, n);
1285 ceb04770 2003-12-09 devnull PBIT16((uchar*)s-1, n);
1289 215993f8 2005-09-13 devnull repack(Fcall *f, uchar **ppkt, int dotu)
1291 5c84c448 2005-03-21 devnull uint n, nn;
1292 5c84c448 2005-03-21 devnull uchar *pkt;
1294 5c84c448 2005-03-21 devnull pkt = *ppkt;
1295 5c84c448 2005-03-21 devnull n = GBIT32(pkt);
1296 215993f8 2005-09-13 devnull nn = sizeS2Mu(f, dotu);
1297 5c84c448 2005-03-21 devnull if(nn > n){
1298 5c84c448 2005-03-21 devnull free(pkt);
1299 5c84c448 2005-03-21 devnull pkt = emalloc(nn);
1300 5c84c448 2005-03-21 devnull *ppkt = pkt;
1302 9e2f1d9b 2005-11-21 devnull n = convS2Mu(f, pkt, nn, dotu);
1303 9e2f1d9b 2005-11-21 devnull if(n <= BIT16SZ)
1304 9e2f1d9b 2005-11-21 devnull sysfatal("convS2M conversion error");
1305 9e2f1d9b 2005-11-21 devnull if(n != nn)
1306 9e2f1d9b 2005-11-21 devnull sysfatal("convS2Mu and sizeS2Mu disagree");
1310 ceb04770 2003-12-09 devnull rewritehdr(Fcall *f, uchar *pkt)
1312 ceb04770 2003-12-09 devnull int i, n;
1314 ceb04770 2003-12-09 devnull n = GBIT32(pkt);
1315 ceb04770 2003-12-09 devnull PBIT16(pkt+5, f->tag);
1316 ceb04770 2003-12-09 devnull switch(f->type){
1317 ceb04770 2003-12-09 devnull case Tversion:
1318 ceb04770 2003-12-09 devnull case Rversion:
1319 ceb04770 2003-12-09 devnull restring(pkt, n, f->version);
1321 ceb04770 2003-12-09 devnull case Tauth:
1322 ceb04770 2003-12-09 devnull PBIT32(pkt+7, f->afid);
1323 ceb04770 2003-12-09 devnull restring(pkt, n, f->uname);
1324 ceb04770 2003-12-09 devnull restring(pkt, n, f->aname);
1326 ceb04770 2003-12-09 devnull case Tflush:
1327 ceb04770 2003-12-09 devnull PBIT16(pkt+7, f->oldtag);
1329 ceb04770 2003-12-09 devnull case Tattach:
1330 ceb04770 2003-12-09 devnull restring(pkt, n, f->uname);
1331 ceb04770 2003-12-09 devnull restring(pkt, n, f->aname);
1332 ceb04770 2003-12-09 devnull PBIT32(pkt+7, f->fid);
1333 ceb04770 2003-12-09 devnull PBIT32(pkt+11, f->afid);
1335 ceb04770 2003-12-09 devnull case Twalk:
1336 ceb04770 2003-12-09 devnull PBIT32(pkt+7, f->fid);
1337 ceb04770 2003-12-09 devnull PBIT32(pkt+11, f->newfid);
1338 ceb04770 2003-12-09 devnull for(i=0; i<f->nwname; i++)
1339 ceb04770 2003-12-09 devnull restring(pkt, n, f->wname[i]);
1341 ceb04770 2003-12-09 devnull case Tcreate:
1342 ceb04770 2003-12-09 devnull restring(pkt, n, f->name);
1343 ceb04770 2003-12-09 devnull /* fall through */
1344 ceb04770 2003-12-09 devnull case Topen:
1345 ceb04770 2003-12-09 devnull case Tclunk:
1346 ceb04770 2003-12-09 devnull case Tremove:
1347 ceb04770 2003-12-09 devnull case Tstat:
1348 ceb04770 2003-12-09 devnull case Twstat:
1349 9777187b 2006-02-03 devnull case Twrite:
1350 ceb04770 2003-12-09 devnull PBIT32(pkt+7, f->fid);
1352 9777187b 2006-02-03 devnull case Tread:
1353 9777187b 2006-02-03 devnull PBIT32(pkt+7, f->fid);
1354 9777187b 2006-02-03 devnull PBIT64(pkt+11, f->offset);
1356 ceb04770 2003-12-09 devnull case Rerror:
1357 ceb04770 2003-12-09 devnull restring(pkt, n, f->ename);
1362 32f69c36 2003-12-11 devnull static long
1363 ceb04770 2003-12-09 devnull _iolisten(va_list *arg)
1365 ceb04770 2003-12-09 devnull char *a, *b;
1367 ceb04770 2003-12-09 devnull a = va_arg(*arg, char*);
1368 ceb04770 2003-12-09 devnull b = va_arg(*arg, char*);
1369 ceb04770 2003-12-09 devnull return listen(a, b);
1373 ceb04770 2003-12-09 devnull iolisten(Ioproc *io, char *a, char *b)
1375 ceb04770 2003-12-09 devnull return iocall(io, _iolisten, a, b);
1378 ceb04770 2003-12-09 devnull static long
1379 ceb04770 2003-12-09 devnull _ioaccept(va_list *arg)
1381 ceb04770 2003-12-09 devnull int fd;
1382 ceb04770 2003-12-09 devnull char *dir;
1384 ceb04770 2003-12-09 devnull fd = va_arg(*arg, int);
1385 ceb04770 2003-12-09 devnull dir = va_arg(*arg, char*);
1386 ceb04770 2003-12-09 devnull return accept(fd, dir);
1390 ceb04770 2003-12-09 devnull ioaccept(Ioproc *io, int fd, char *dir)
1392 ceb04770 2003-12-09 devnull return iocall(io, _ioaccept, fd, dir);
1396 e2a1725d 2005-01-04 devnull timefmt(Fmt *fmt)
1398 e2a1725d 2005-01-04 devnull static char *mon[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1399 e2a1725d 2005-01-04 devnull "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
1400 bb426e77 2005-01-06 devnull vlong ns;
1402 bb426e77 2005-01-06 devnull ns = nsec();
1403 e2a1725d 2005-01-04 devnull tm = *localtime(time(0));
1404 bb426e77 2005-01-06 devnull return fmtprint(fmt, "%s %2d %02d:%02d:%02d.%03d",
1405 bb426e77 2005-01-06 devnull mon[tm.mon], tm.mday, tm.hour, tm.min, tm.sec,
1406 bb426e77 2005-01-06 devnull (int)(ns%1000000000)/1000000);
1410 16c1defa 2005-11-12 devnull cvtustat(Fcall *f, uchar **fpkt, int tounix)
1413 23e7c657 2005-09-13 devnull uchar *buf;
1414 215993f8 2005-09-13 devnull char *str;
1415 215993f8 2005-09-13 devnull Dir dir;
1417 215993f8 2005-09-13 devnull str = emalloc(f->nstat);
1418 16c1defa 2005-11-12 devnull n = convM2Du(f->stat, f->nstat, &dir, str, !tounix);
1419 16c1defa 2005-11-12 devnull if(n <= BIT16SZ){
1420 16c1defa 2005-11-12 devnull free(str);
1421 215993f8 2005-09-13 devnull return -1;
1424 16c1defa 2005-11-12 devnull n = sizeD2Mu(&dir, tounix);
1425 16c1defa 2005-11-12 devnull buf = emalloc(n);
1426 9e2f1d9b 2005-11-21 devnull if(convD2Mu(&dir, buf, n, tounix) != n)
1427 9e2f1d9b 2005-11-21 devnull sysfatal("convD2Mu conversion error");
1428 215993f8 2005-09-13 devnull f->nstat = n;
1429 215993f8 2005-09-13 devnull f->stat = buf;
1431 215993f8 2005-09-13 devnull repack(f, fpkt, dotu);
1432 215993f8 2005-09-13 devnull free(buf);
1433 16c1defa 2005-11-12 devnull f->stat = nil; /* is this okay ??? */
1434 215993f8 2005-09-13 devnull free(str);
1436 215993f8 2005-09-13 devnull return 0;
1440 215993f8 2005-09-13 devnull stripudirread(Msg* msg)
1442 23e7c657 2005-09-13 devnull char *str;
1443 215993f8 2005-09-13 devnull int i, m, n, nn;
1444 23e7c657 2005-09-13 devnull uchar *buf;
1446 215993f8 2005-09-13 devnull Fcall* rx;
1448 215993f8 2005-09-13 devnull buf = nil;
1449 215993f8 2005-09-13 devnull str = nil;
1450 215993f8 2005-09-13 devnull rx = &msg->rx;
1452 215993f8 2005-09-13 devnull nn = 0;
1453 215993f8 2005-09-13 devnull for(i = 0; i < rx->count; i += m){
1454 215993f8 2005-09-13 devnull m = BIT16SZ + GBIT16(&rx->data[i]);
1455 54705b4a 2005-09-13 devnull if(statchecku((uchar*)&rx->data[i], m, 1) < 0)
1456 215993f8 2005-09-13 devnull return -1;
1457 215993f8 2005-09-13 devnull if(nn < m)
1458 215993f8 2005-09-13 devnull nn = m;
1462 215993f8 2005-09-13 devnull str = emalloc(nn);
1463 215993f8 2005-09-13 devnull buf = emalloc(rx->count);
1465 215993f8 2005-09-13 devnull nn = 0;
1466 215993f8 2005-09-13 devnull for(i = 0; i < rx->count; i += m){
1467 215993f8 2005-09-13 devnull m = BIT16SZ + GBIT16(&rx->data[i]);
1468 54705b4a 2005-09-13 devnull if(convM2Du((uchar*)&rx->data[i], m, &d, str, 1) != m){
1469 215993f8 2005-09-13 devnull free(buf);
1470 215993f8 2005-09-13 devnull free(str);
1471 215993f8 2005-09-13 devnull return -1;
1474 215993f8 2005-09-13 devnull n = convD2M(&d, &buf[nn], rx->count - nn);
1475 215993f8 2005-09-13 devnull if(n <= BIT16SZ){
1476 215993f8 2005-09-13 devnull free(buf);
1477 215993f8 2005-09-13 devnull free(str);
1478 215993f8 2005-09-13 devnull return -1;
1481 215993f8 2005-09-13 devnull nn += n;
1484 215993f8 2005-09-13 devnull rx->count = nn;
1485 54705b4a 2005-09-13 devnull rx->data = (char*)buf;
1487 215993f8 2005-09-13 devnull repack(&msg->rx, &msg->rpkt, 0);
1488 215993f8 2005-09-13 devnull free(str);
1489 215993f8 2005-09-13 devnull free(buf);
1490 16c1defa 2005-11-12 devnull rx->data = nil; /* is this okay ??? */
1492 215993f8 2005-09-13 devnull return 0;