Blame


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>
6 d3df3087 2003-12-06 devnull
7 d3df3087 2003-12-06 devnull enum
8 d3df3087 2003-12-06 devnull {
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 */
12 d3df3087 2003-12-06 devnull };
13 d3df3087 2003-12-06 devnull
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;
19 d3df3087 2003-12-06 devnull
20 d3df3087 2003-12-06 devnull struct Hash
21 d3df3087 2003-12-06 devnull {
22 d3df3087 2003-12-06 devnull Hash *next;
23 d3df3087 2003-12-06 devnull uint n;
24 d3df3087 2003-12-06 devnull void *v;
25 d3df3087 2003-12-06 devnull };
26 d3df3087 2003-12-06 devnull
27 d3df3087 2003-12-06 devnull struct Fid
28 d3df3087 2003-12-06 devnull {
29 d3df3087 2003-12-06 devnull int fid;
30 d3df3087 2003-12-06 devnull int ref;
31 d3df3087 2003-12-06 devnull int cfid;
32 21e626de 2004-12-28 devnull int openfd;
33 d3df3087 2003-12-06 devnull Fid *next;
34 d3df3087 2003-12-06 devnull };
35 d3df3087 2003-12-06 devnull
36 d3df3087 2003-12-06 devnull struct Msg
37 d3df3087 2003-12-06 devnull {
38 d3df3087 2003-12-06 devnull Conn *c;
39 d3df3087 2003-12-06 devnull int internal;
40 d3df3087 2003-12-06 devnull int ref;
41 d3df3087 2003-12-06 devnull int ctag;
42 d3df3087 2003-12-06 devnull int tag;
43 32f69c36 2003-12-11 devnull int isopenfd;
44 d3df3087 2003-12-06 devnull Fcall tx;
45 d3df3087 2003-12-06 devnull Fcall rx;
46 d3df3087 2003-12-06 devnull Fid *fid;
47 d3df3087 2003-12-06 devnull Fid *newfid;
48 d3df3087 2003-12-06 devnull Fid *afid;
49 d3df3087 2003-12-06 devnull Msg *oldm;
50 d3df3087 2003-12-06 devnull Msg *next;
51 d3df3087 2003-12-06 devnull uchar *tpkt;
52 d3df3087 2003-12-06 devnull uchar *rpkt;
53 d3df3087 2003-12-06 devnull };
54 d3df3087 2003-12-06 devnull
55 d3df3087 2003-12-06 devnull struct Conn
56 d3df3087 2003-12-06 devnull {
57 d3df3087 2003-12-06 devnull int fd;
58 32f69c36 2003-12-11 devnull int fdmode;
59 32f69c36 2003-12-11 devnull Fid *fdfid;
60 d3df3087 2003-12-06 devnull int nmsg;
61 d3df3087 2003-12-06 devnull int nfid;
62 d3df3087 2003-12-06 devnull Channel *inc;
63 d3df3087 2003-12-06 devnull Channel *internal;
64 d3df3087 2003-12-06 devnull int inputstalled;
65 d3df3087 2003-12-06 devnull char dir[40];
66 d3df3087 2003-12-06 devnull Hash *tag[NHASH];
67 d3df3087 2003-12-06 devnull Hash *fid[NHASH];
68 d3df3087 2003-12-06 devnull Queue *outq;
69 d3df3087 2003-12-06 devnull Queue *inq;
70 d3df3087 2003-12-06 devnull };
71 d3df3087 2003-12-06 devnull
72 5c84c448 2005-03-21 devnull char *xaname;
73 d3df3087 2003-12-06 devnull char *addr;
74 d3df3087 2003-12-06 devnull int afd;
75 d3df3087 2003-12-06 devnull char adir[40];
76 d3df3087 2003-12-06 devnull int isunix;
77 d3df3087 2003-12-06 devnull Queue *outq;
78 d3df3087 2003-12-06 devnull Queue *inq;
79 05b7f431 2004-03-02 devnull int verbose = 0;
80 e2a1725d 2005-01-04 devnull int logging = 0;
81 5a8e63b2 2004-02-29 devnull int msize = 8192;
82 5c84c448 2005-03-21 devnull int xafid = NOFID;
83 5c84c448 2005-03-21 devnull int attached;
84 5c84c448 2005-03-21 devnull int versioned;
85 d3df3087 2003-12-06 devnull
86 d3df3087 2003-12-06 devnull void *gethash(Hash**, uint);
87 d3df3087 2003-12-06 devnull int puthash(Hash**, uint, void*);
88 d3df3087 2003-12-06 devnull int delhash(Hash**, uint, void*);
89 ceb04770 2003-12-09 devnull Msg *mread9p(Ioproc*, int);
90 ceb04770 2003-12-09 devnull int mwrite9p(Ioproc*, int, uchar*);
91 ceb04770 2003-12-09 devnull uchar *read9ppkt(Ioproc*, int);
92 d3df3087 2003-12-06 devnull int write9ppkt(int, uchar*);
93 e2a1725d 2005-01-04 devnull Msg *msgnew(int);
94 d3df3087 2003-12-06 devnull void msgput(Msg*);
95 e2a1725d 2005-01-04 devnull void msgclear(Msg*);
96 d3df3087 2003-12-06 devnull Msg *msgget(int);
97 e2a1725d 2005-01-04 devnull void msgincref(Msg*);
98 d3df3087 2003-12-06 devnull Fid *fidnew(int);
99 d3df3087 2003-12-06 devnull void fidput(Fid*);
100 d3df3087 2003-12-06 devnull void *emalloc(int);
101 d3df3087 2003-12-06 devnull void *erealloc(void*, int);
102 ceb04770 2003-12-09 devnull Queue *qalloc(void);
103 d3df3087 2003-12-06 devnull int sendq(Queue*, void*);
104 d3df3087 2003-12-06 devnull void *recvq(Queue*);
105 d3df3087 2003-12-06 devnull void connthread(void*);
106 ceb04770 2003-12-09 devnull void connoutthread(void*);
107 d3df3087 2003-12-06 devnull void listenthread(void*);
108 ceb04770 2003-12-09 devnull void outputthread(void*);
109 ceb04770 2003-12-09 devnull void inputthread(void*);
110 d3df3087 2003-12-06 devnull void rewritehdr(Fcall*, uchar*);
111 5c84c448 2005-03-21 devnull void repack(Fcall*, uchar**);
112 d3df3087 2003-12-06 devnull int tlisten(char*, char*);
113 d3df3087 2003-12-06 devnull int taccept(int, char*);
114 ceb04770 2003-12-09 devnull int iolisten(Ioproc*, char*, char*);
115 ceb04770 2003-12-09 devnull int ioaccept(Ioproc*, int, char*);
116 32f69c36 2003-12-11 devnull int iorecvfd(Ioproc*, int);
117 32f69c36 2003-12-11 devnull int iosendfd(Ioproc*, int, int);
118 32f69c36 2003-12-11 devnull void mainproc(void*);
119 32f69c36 2003-12-11 devnull int ignorepipe(void*, char*);
120 e2a1725d 2005-01-04 devnull int timefmt(Fmt*);
121 5c84c448 2005-03-21 devnull void dorootstat(void);
122 d3df3087 2003-12-06 devnull
123 d3df3087 2003-12-06 devnull void
124 d3df3087 2003-12-06 devnull usage(void)
125 d3df3087 2003-12-06 devnull {
126 5c84c448 2005-03-21 devnull fprint(2, "usage: 9pserve [-lv] [-A aname afid] [-M msize] address\n");
127 d3df3087 2003-12-06 devnull fprint(2, "\treads/writes 9P messages on stdin/stdout\n");
128 38c10d1a 2005-01-17 devnull threadexitsall("usage");
129 d3df3087 2003-12-06 devnull }
130 d3df3087 2003-12-06 devnull
131 ceb04770 2003-12-09 devnull uchar vbuf[128];
132 32f69c36 2003-12-11 devnull extern int _threaddebuglevel;
133 d3df3087 2003-12-06 devnull void
134 d3df3087 2003-12-06 devnull threadmain(int argc, char **argv)
135 d3df3087 2003-12-06 devnull {
136 3a6f92ee 2005-03-18 devnull char *file, *x;
137 e2a1725d 2005-01-04 devnull int fd;
138 ceb04770 2003-12-09 devnull
139 3a6f92ee 2005-03-18 devnull x = getenv("verbose9pserve");
140 5c84c448 2005-03-21 devnull if(x){
141 3a6f92ee 2005-03-18 devnull verbose = atoi(x);
142 5c84c448 2005-03-21 devnull fprint(2, "verbose9pserve %s => %d\n", x, verbose);
143 5c84c448 2005-03-21 devnull }
144 d3df3087 2003-12-06 devnull ARGBEGIN{
145 d3df3087 2003-12-06 devnull default:
146 d3df3087 2003-12-06 devnull usage();
147 5c84c448 2005-03-21 devnull case 'A':
148 5c84c448 2005-03-21 devnull attached = 1;
149 5c84c448 2005-03-21 devnull xaname = EARGF(usage());
150 5c84c448 2005-03-21 devnull xafid = atoi(EARGF(usage()));
151 5c84c448 2005-03-21 devnull break;
152 5c84c448 2005-03-21 devnull case 'M':
153 5c84c448 2005-03-21 devnull versioned = 1;
154 5c84c448 2005-03-21 devnull msize = atoi(EARGF(usage()));
155 5c84c448 2005-03-21 devnull break;
156 ceb04770 2003-12-09 devnull case 'v':
157 ceb04770 2003-12-09 devnull verbose++;
158 ceb04770 2003-12-09 devnull break;
159 d3df3087 2003-12-06 devnull case 'u':
160 5c84c448 2005-03-21 devnull isunix++;
161 d3df3087 2003-12-06 devnull break;
162 e2a1725d 2005-01-04 devnull case 'l':
163 e2a1725d 2005-01-04 devnull logging++;
164 e2a1725d 2005-01-04 devnull break;
165 d3df3087 2003-12-06 devnull }ARGEND
166 5c84c448 2005-03-21 devnull
167 5c84c448 2005-03-21 devnull if(attached && !versioned){
168 5c84c448 2005-03-21 devnull fprint(2, "-A must be used with -M\n");
169 5c84c448 2005-03-21 devnull usage();
170 5c84c448 2005-03-21 devnull }
171 d3df3087 2003-12-06 devnull
172 d3df3087 2003-12-06 devnull if(argc != 1)
173 d3df3087 2003-12-06 devnull usage();
174 ceb04770 2003-12-09 devnull addr = argv[0];
175 d3df3087 2003-12-06 devnull
176 e2a1725d 2005-01-04 devnull fmtinstall('T', timefmt);
177 e2a1725d 2005-01-04 devnull
178 d3df3087 2003-12-06 devnull if((afd = announce(addr, adir)) < 0)
179 d3df3087 2003-12-06 devnull sysfatal("announce %s: %r", addr);
180 e2a1725d 2005-01-04 devnull if(logging){
181 e2a1725d 2005-01-04 devnull if(strncmp(addr, "unix!", 5) == 0)
182 e2a1725d 2005-01-04 devnull addr += 5;
183 e2a1725d 2005-01-04 devnull file = smprint("%s.log", addr);
184 e2a1725d 2005-01-04 devnull if(file == nil)
185 e2a1725d 2005-01-04 devnull sysfatal("smprint log: %r");
186 e2a1725d 2005-01-04 devnull if((fd = create(file, OWRITE, 0666)) < 0)
187 e2a1725d 2005-01-04 devnull sysfatal("create %s: %r", file);
188 e2a1725d 2005-01-04 devnull dup(fd, 2);
189 e2a1725d 2005-01-04 devnull if(fd > 2)
190 e2a1725d 2005-01-04 devnull close(fd);
191 e2a1725d 2005-01-04 devnull }
192 e2a1725d 2005-01-04 devnull if(verbose) fprint(2, "%T 9pserve running\n");
193 e2a1725d 2005-01-04 devnull proccreate(mainproc, nil, STACK);
194 32f69c36 2003-12-11 devnull }
195 32f69c36 2003-12-11 devnull
196 32f69c36 2003-12-11 devnull void
197 32f69c36 2003-12-11 devnull mainproc(void *v)
198 32f69c36 2003-12-11 devnull {
199 c91bd328 2004-03-05 devnull int n, nn;
200 32f69c36 2003-12-11 devnull Fcall f;
201 32f69c36 2003-12-11 devnull USED(v);
202 32f69c36 2003-12-11 devnull
203 32f69c36 2003-12-11 devnull atnotify(ignorepipe, 1);
204 ceb04770 2003-12-09 devnull fmtinstall('D', dirfmt);
205 ceb04770 2003-12-09 devnull fmtinstall('M', dirmodefmt);
206 ceb04770 2003-12-09 devnull fmtinstall('F', fcallfmt);
207 ceb04770 2003-12-09 devnull fmtinstall('H', encodefmt);
208 ceb04770 2003-12-09 devnull
209 ceb04770 2003-12-09 devnull outq = qalloc();
210 ceb04770 2003-12-09 devnull inq = qalloc();
211 ceb04770 2003-12-09 devnull
212 5c84c448 2005-03-21 devnull if(!versioned){
213 5c84c448 2005-03-21 devnull f.type = Tversion;
214 5c84c448 2005-03-21 devnull f.version = "9P2000";
215 5c84c448 2005-03-21 devnull f.msize = msize;
216 5c84c448 2005-03-21 devnull f.tag = NOTAG;
217 5c84c448 2005-03-21 devnull n = convS2M(&f, vbuf, sizeof vbuf);
218 5c84c448 2005-03-21 devnull if(verbose > 1) fprint(2, "%T * <- %F\n", &f);
219 5c84c448 2005-03-21 devnull nn = write(1, vbuf, n);
220 5c84c448 2005-03-21 devnull if(n != nn)
221 5c84c448 2005-03-21 devnull sysfatal("error writing Tversion: %r\n");
222 5c84c448 2005-03-21 devnull n = read9pmsg(0, vbuf, sizeof vbuf);
223 5c84c448 2005-03-21 devnull if(convM2S(vbuf, n, &f) != n)
224 5c84c448 2005-03-21 devnull sysfatal("convM2S failure");
225 5c84c448 2005-03-21 devnull if(f.msize < msize)
226 5c84c448 2005-03-21 devnull msize = f.msize;
227 5c84c448 2005-03-21 devnull if(verbose > 1) fprint(2, "%T * -> %F\n", &f);
228 5c84c448 2005-03-21 devnull }
229 32f69c36 2003-12-11 devnull
230 32f69c36 2003-12-11 devnull threadcreate(inputthread, nil, STACK);
231 32f69c36 2003-12-11 devnull threadcreate(outputthread, nil, STACK);
232 5c84c448 2005-03-21 devnull
233 5c84c448 2005-03-21 devnull // if(rootfid)
234 5c84c448 2005-03-21 devnull // dorootstat();
235 5c84c448 2005-03-21 devnull
236 ceb04770 2003-12-09 devnull threadcreate(listenthread, nil, STACK);
237 32f69c36 2003-12-11 devnull threadexits(0);
238 d3df3087 2003-12-06 devnull }
239 d3df3087 2003-12-06 devnull
240 32f69c36 2003-12-11 devnull int
241 32f69c36 2003-12-11 devnull ignorepipe(void *v, char *s)
242 32f69c36 2003-12-11 devnull {
243 32f69c36 2003-12-11 devnull USED(v);
244 32f69c36 2003-12-11 devnull if(strcmp(s, "sys: write on closed pipe") == 0)
245 32f69c36 2003-12-11 devnull return 1;
246 c042e61e 2005-03-18 devnull if(strcmp(s, "sys: tstp") == 0)
247 c042e61e 2005-03-18 devnull return 1;
248 c042e61e 2005-03-18 devnull fprint(2, "9pserve %s: %T note: %s\n", addr, s);
249 32f69c36 2003-12-11 devnull return 0;
250 32f69c36 2003-12-11 devnull }
251 32f69c36 2003-12-11 devnull
252 d3df3087 2003-12-06 devnull void
253 d3df3087 2003-12-06 devnull listenthread(void *arg)
254 d3df3087 2003-12-06 devnull {
255 d3df3087 2003-12-06 devnull Conn *c;
256 ceb04770 2003-12-09 devnull Ioproc *io;
257 d3df3087 2003-12-06 devnull
258 ceb04770 2003-12-09 devnull io = ioproc();
259 d3df3087 2003-12-06 devnull USED(arg);
260 7ffc5208 2004-12-28 devnull threadsetname("listen %s", adir);
261 d3df3087 2003-12-06 devnull for(;;){
262 ceb04770 2003-12-09 devnull c = emalloc(sizeof(Conn));
263 ceb04770 2003-12-09 devnull c->fd = iolisten(io, adir, c->dir);
264 d3df3087 2003-12-06 devnull if(c->fd < 0){
265 e2a1725d 2005-01-04 devnull if(verbose) fprint(2, "%T listen: %r\n");
266 d3df3087 2003-12-06 devnull close(afd);
267 d3df3087 2003-12-06 devnull free(c);
268 d3df3087 2003-12-06 devnull return;
269 d3df3087 2003-12-06 devnull }
270 32f69c36 2003-12-11 devnull c->inc = chancreate(sizeof(void*), 0);
271 32f69c36 2003-12-11 devnull c->internal = chancreate(sizeof(void*), 0);
272 32f69c36 2003-12-11 devnull c->inq = qalloc();
273 32f69c36 2003-12-11 devnull c->outq = qalloc();
274 e2a1725d 2005-01-04 devnull if(verbose) fprint(2, "%T incoming call on %s\n", c->dir);
275 d3df3087 2003-12-06 devnull threadcreate(connthread, c, STACK);
276 d3df3087 2003-12-06 devnull }
277 d3df3087 2003-12-06 devnull }
278 d3df3087 2003-12-06 devnull
279 d3df3087 2003-12-06 devnull void
280 32f69c36 2003-12-11 devnull send9pmsg(Msg *m)
281 d3df3087 2003-12-06 devnull {
282 d3df3087 2003-12-06 devnull int n, nn;
283 d3df3087 2003-12-06 devnull
284 d3df3087 2003-12-06 devnull n = sizeS2M(&m->rx);
285 d3df3087 2003-12-06 devnull m->rpkt = emalloc(n);
286 d3df3087 2003-12-06 devnull nn = convS2M(&m->rx, m->rpkt, n);
287 d3df3087 2003-12-06 devnull if(nn != n)
288 d3df3087 2003-12-06 devnull sysfatal("sizeS2M + convS2M disagree");
289 d3df3087 2003-12-06 devnull sendq(m->c->outq, m);
290 d3df3087 2003-12-06 devnull }
291 d3df3087 2003-12-06 devnull
292 d3df3087 2003-12-06 devnull void
293 ceb04770 2003-12-09 devnull sendomsg(Msg *m)
294 ceb04770 2003-12-09 devnull {
295 ceb04770 2003-12-09 devnull int n, nn;
296 ceb04770 2003-12-09 devnull
297 ceb04770 2003-12-09 devnull n = sizeS2M(&m->tx);
298 ceb04770 2003-12-09 devnull m->tpkt = emalloc(n);
299 ceb04770 2003-12-09 devnull nn = convS2M(&m->tx, m->tpkt, n);
300 ceb04770 2003-12-09 devnull if(nn != n)
301 ceb04770 2003-12-09 devnull sysfatal("sizeS2M + convS2M disagree");
302 ceb04770 2003-12-09 devnull sendq(outq, m);
303 ceb04770 2003-12-09 devnull }
304 ceb04770 2003-12-09 devnull
305 ceb04770 2003-12-09 devnull void
306 ceb04770 2003-12-09 devnull err(Msg *m, char *ename)
307 ceb04770 2003-12-09 devnull {
308 ceb04770 2003-12-09 devnull m->rx.type = Rerror;
309 ceb04770 2003-12-09 devnull m->rx.ename = ename;
310 ceb04770 2003-12-09 devnull m->rx.tag = m->tx.tag;
311 32f69c36 2003-12-11 devnull send9pmsg(m);
312 ceb04770 2003-12-09 devnull }
313 ceb04770 2003-12-09 devnull
314 5c84c448 2005-03-21 devnull char*
315 5c84c448 2005-03-21 devnull estrdup(char *s)
316 5c84c448 2005-03-21 devnull {
317 5c84c448 2005-03-21 devnull char *t;
318 5c84c448 2005-03-21 devnull
319 5c84c448 2005-03-21 devnull t = emalloc(strlen(s)+1);
320 5c84c448 2005-03-21 devnull strcpy(t, s);
321 5c84c448 2005-03-21 devnull return t;
322 5c84c448 2005-03-21 devnull }
323 5c84c448 2005-03-21 devnull
324 ceb04770 2003-12-09 devnull void
325 d3df3087 2003-12-06 devnull connthread(void *arg)
326 d3df3087 2003-12-06 devnull {
327 d3df3087 2003-12-06 devnull int i, fd;
328 d3df3087 2003-12-06 devnull Conn *c;
329 05b7f431 2004-03-02 devnull Hash *h, *hnext;
330 05b7f431 2004-03-02 devnull Msg *m, *om, *mm;
331 d3df3087 2003-12-06 devnull Fid *f;
332 ceb04770 2003-12-09 devnull Ioproc *io;
333 d3df3087 2003-12-06 devnull
334 d3df3087 2003-12-06 devnull c = arg;
335 7ffc5208 2004-12-28 devnull threadsetname("conn %s", c->dir);
336 ceb04770 2003-12-09 devnull io = ioproc();
337 ceb04770 2003-12-09 devnull fd = ioaccept(io, c->fd, c->dir);
338 d3df3087 2003-12-06 devnull if(fd < 0){
339 e2a1725d 2005-01-04 devnull if(verbose) fprint(2, "%T accept %s: %r\n", c->dir);
340 d3df3087 2003-12-06 devnull goto out;
341 d3df3087 2003-12-06 devnull }
342 d3df3087 2003-12-06 devnull close(c->fd);
343 d3df3087 2003-12-06 devnull c->fd = fd;
344 ceb04770 2003-12-09 devnull threadcreate(connoutthread, c, STACK);
345 ceb04770 2003-12-09 devnull while((m = mread9p(io, c->fd)) != nil){
346 e2a1725d 2005-01-04 devnull if(verbose > 1) fprint(2, "%T fd#%d -> %F\n", c->fd, &m->tx);
347 d3df3087 2003-12-06 devnull m->c = c;
348 ceb04770 2003-12-09 devnull m->ctag = m->tx.tag;
349 d3df3087 2003-12-06 devnull c->nmsg++;
350 e2a1725d 2005-01-04 devnull if(verbose > 1) fprint(2, "%T fd#%d: new msg %p\n", c->fd, m);
351 d3df3087 2003-12-06 devnull if(puthash(c->tag, m->tx.tag, m) < 0){
352 d3df3087 2003-12-06 devnull err(m, "duplicate tag");
353 d3df3087 2003-12-06 devnull continue;
354 d3df3087 2003-12-06 devnull }
355 e2a1725d 2005-01-04 devnull msgincref(m);
356 d3df3087 2003-12-06 devnull switch(m->tx.type){
357 ceb04770 2003-12-09 devnull case Tversion:
358 ceb04770 2003-12-09 devnull m->rx.tag = m->tx.tag;
359 ceb04770 2003-12-09 devnull m->rx.msize = m->tx.msize;
360 5a8e63b2 2004-02-29 devnull if(m->rx.msize > msize)
361 5a8e63b2 2004-02-29 devnull m->rx.msize = msize;
362 ceb04770 2003-12-09 devnull m->rx.version = "9P2000";
363 ceb04770 2003-12-09 devnull m->rx.type = Rversion;
364 32f69c36 2003-12-11 devnull send9pmsg(m);
365 ceb04770 2003-12-09 devnull continue;
366 d3df3087 2003-12-06 devnull case Tflush:
367 d3df3087 2003-12-06 devnull if((m->oldm = gethash(c->tag, m->tx.oldtag)) == nil){
368 ceb04770 2003-12-09 devnull m->rx.tag = m->tx.tag;
369 ceb04770 2003-12-09 devnull m->rx.type = Rflush;
370 32f69c36 2003-12-11 devnull send9pmsg(m);
371 d3df3087 2003-12-06 devnull continue;
372 d3df3087 2003-12-06 devnull }
373 e2a1725d 2005-01-04 devnull msgincref(m->oldm);
374 d3df3087 2003-12-06 devnull break;
375 d3df3087 2003-12-06 devnull case Tattach:
376 ceb04770 2003-12-09 devnull m->afid = nil;
377 ceb04770 2003-12-09 devnull if(m->tx.afid != NOFID
378 ceb04770 2003-12-09 devnull && (m->afid = gethash(c->fid, m->tx.afid)) == nil){
379 ceb04770 2003-12-09 devnull err(m, "unknown fid");
380 ceb04770 2003-12-09 devnull continue;
381 ceb04770 2003-12-09 devnull }
382 3a6f92ee 2005-03-18 devnull if(m->afid)
383 3a6f92ee 2005-03-18 devnull m->afid->ref++;
384 d3df3087 2003-12-06 devnull m->fid = fidnew(m->tx.fid);
385 d3df3087 2003-12-06 devnull if(puthash(c->fid, m->tx.fid, m->fid) < 0){
386 d3df3087 2003-12-06 devnull err(m, "duplicate fid");
387 d3df3087 2003-12-06 devnull continue;
388 d3df3087 2003-12-06 devnull }
389 d3df3087 2003-12-06 devnull m->fid->ref++;
390 5c84c448 2005-03-21 devnull if(attached && m->afid==nil){
391 5c84c448 2005-03-21 devnull if(m->tx.aname[0] && strcmp(xaname, m->tx.aname) != 0){
392 5c84c448 2005-03-21 devnull err(m, "invalid attach name");
393 5c84c448 2005-03-21 devnull continue;
394 5c84c448 2005-03-21 devnull }
395 5c84c448 2005-03-21 devnull m->tx.afid = xafid;
396 5c84c448 2005-03-21 devnull m->tx.aname = xaname;
397 5c84c448 2005-03-21 devnull m->tx.uname = estrdup(m->tx.uname);
398 5c84c448 2005-03-21 devnull repack(&m->tx, &m->tpkt);
399 5c84c448 2005-03-21 devnull free(m->tx.uname);
400 5c84c448 2005-03-21 devnull m->tx.uname = "XXX";
401 5c84c448 2005-03-21 devnull }
402 d3df3087 2003-12-06 devnull break;
403 d3df3087 2003-12-06 devnull case Twalk:
404 d3df3087 2003-12-06 devnull if((m->fid = gethash(c->fid, m->tx.fid)) == nil){
405 d3df3087 2003-12-06 devnull err(m, "unknown fid");
406 d3df3087 2003-12-06 devnull continue;
407 d3df3087 2003-12-06 devnull }
408 ceb04770 2003-12-09 devnull m->fid->ref++;
409 d3df3087 2003-12-06 devnull if(m->tx.newfid == m->tx.fid){
410 d3df3087 2003-12-06 devnull m->fid->ref++;
411 d3df3087 2003-12-06 devnull m->newfid = m->fid;
412 d3df3087 2003-12-06 devnull }else{
413 d3df3087 2003-12-06 devnull m->newfid = fidnew(m->tx.newfid);
414 d3df3087 2003-12-06 devnull if(puthash(c->fid, m->tx.newfid, m->newfid) < 0){
415 d3df3087 2003-12-06 devnull err(m, "duplicate fid");
416 d3df3087 2003-12-06 devnull continue;
417 d3df3087 2003-12-06 devnull }
418 d3df3087 2003-12-06 devnull m->newfid->ref++;
419 d3df3087 2003-12-06 devnull }
420 d3df3087 2003-12-06 devnull break;
421 d3df3087 2003-12-06 devnull case Tauth:
422 5c84c448 2005-03-21 devnull if(attached){
423 5c84c448 2005-03-21 devnull err(m, "authentication not required");
424 5c84c448 2005-03-21 devnull continue;
425 5c84c448 2005-03-21 devnull }
426 ceb04770 2003-12-09 devnull m->afid = fidnew(m->tx.afid);
427 ceb04770 2003-12-09 devnull if(puthash(c->fid, m->tx.afid, m->afid) < 0){
428 d3df3087 2003-12-06 devnull err(m, "duplicate fid");
429 d3df3087 2003-12-06 devnull continue;
430 d3df3087 2003-12-06 devnull }
431 ceb04770 2003-12-09 devnull m->afid->ref++;
432 d3df3087 2003-12-06 devnull break;
433 32f69c36 2003-12-11 devnull case Topenfd:
434 49588d5d 2003-12-17 devnull if(m->tx.mode&~(OTRUNC|3)){
435 49588d5d 2003-12-17 devnull err(m, "bad openfd mode");
436 32f69c36 2003-12-11 devnull continue;
437 32f69c36 2003-12-11 devnull }
438 32f69c36 2003-12-11 devnull m->isopenfd = 1;
439 32f69c36 2003-12-11 devnull m->tx.type = Topen;
440 32f69c36 2003-12-11 devnull m->tpkt[4] = Topen;
441 32f69c36 2003-12-11 devnull /* fall through */
442 ceb04770 2003-12-09 devnull case Tcreate:
443 d3df3087 2003-12-06 devnull case Topen:
444 d3df3087 2003-12-06 devnull case Tclunk:
445 d3df3087 2003-12-06 devnull case Tread:
446 d3df3087 2003-12-06 devnull case Twrite:
447 ceb04770 2003-12-09 devnull case Tremove:
448 d3df3087 2003-12-06 devnull case Tstat:
449 d3df3087 2003-12-06 devnull case Twstat:
450 d3df3087 2003-12-06 devnull if((m->fid = gethash(c->fid, m->tx.fid)) == nil){
451 d3df3087 2003-12-06 devnull err(m, "unknown fid");
452 d3df3087 2003-12-06 devnull continue;
453 d3df3087 2003-12-06 devnull }
454 d3df3087 2003-12-06 devnull m->fid->ref++;
455 d3df3087 2003-12-06 devnull break;
456 d3df3087 2003-12-06 devnull }
457 d3df3087 2003-12-06 devnull
458 d3df3087 2003-12-06 devnull /* have everything - translate and send */
459 d3df3087 2003-12-06 devnull m->c = c;
460 d3df3087 2003-12-06 devnull m->ctag = m->tx.tag;
461 d3df3087 2003-12-06 devnull m->tx.tag = m->tag;
462 d3df3087 2003-12-06 devnull if(m->fid)
463 d3df3087 2003-12-06 devnull m->tx.fid = m->fid->fid;
464 d3df3087 2003-12-06 devnull if(m->newfid)
465 d3df3087 2003-12-06 devnull m->tx.newfid = m->newfid->fid;
466 d3df3087 2003-12-06 devnull if(m->afid)
467 d3df3087 2003-12-06 devnull m->tx.afid = m->afid->fid;
468 d3df3087 2003-12-06 devnull if(m->oldm)
469 d3df3087 2003-12-06 devnull m->tx.oldtag = m->oldm->tag;
470 ceb04770 2003-12-09 devnull /* reference passes to outq */
471 d3df3087 2003-12-06 devnull sendq(outq, m);
472 d3df3087 2003-12-06 devnull while(c->nmsg >= MAXMSG){
473 d3df3087 2003-12-06 devnull c->inputstalled = 1;
474 d3df3087 2003-12-06 devnull recvp(c->inc);
475 d3df3087 2003-12-06 devnull }
476 d3df3087 2003-12-06 devnull }
477 d3df3087 2003-12-06 devnull
478 e2a1725d 2005-01-04 devnull if(verbose) fprint(2, "%T fd#%d eof; flushing conn\n", c->fd);
479 05b7f431 2004-03-02 devnull
480 05b7f431 2004-03-02 devnull /* flush the output queue */
481 05b7f431 2004-03-02 devnull sendq(c->outq, nil);
482 05b7f431 2004-03-02 devnull while(c->outq != nil)
483 05b7f431 2004-03-02 devnull yield();
484 ceb04770 2003-12-09 devnull
485 d3df3087 2003-12-06 devnull /* flush all outstanding messages */
486 d3df3087 2003-12-06 devnull for(i=0; i<NHASH; i++){
487 05b7f431 2004-03-02 devnull for(h=c->tag[i]; h; h=hnext){
488 d3df3087 2003-12-06 devnull om = h->v;
489 e2a1725d 2005-01-04 devnull m = msgnew(0);
490 d3df3087 2003-12-06 devnull m->internal = 1;
491 d3df3087 2003-12-06 devnull m->c = c;
492 32f69c36 2003-12-11 devnull c->nmsg++;
493 d3df3087 2003-12-06 devnull m->tx.type = Tflush;
494 d3df3087 2003-12-06 devnull m->tx.tag = m->tag;
495 d3df3087 2003-12-06 devnull m->tx.oldtag = om->tag;
496 d3df3087 2003-12-06 devnull m->oldm = om;
497 e2a1725d 2005-01-04 devnull msgincref(om);
498 e2a1725d 2005-01-04 devnull msgincref(m); /* for outq */
499 ceb04770 2003-12-09 devnull sendomsg(m);
500 05b7f431 2004-03-02 devnull mm = recvp(c->internal);
501 05b7f431 2004-03-02 devnull assert(mm == m);
502 32f69c36 2003-12-11 devnull msgput(m); /* got from recvp */
503 32f69c36 2003-12-11 devnull msgput(m); /* got from msgnew */
504 32f69c36 2003-12-11 devnull msgput(om); /* got from hash table */
505 05b7f431 2004-03-02 devnull hnext = h->next;
506 05b7f431 2004-03-02 devnull free(h);
507 d3df3087 2003-12-06 devnull }
508 d3df3087 2003-12-06 devnull }
509 d3df3087 2003-12-06 devnull
510 d3df3087 2003-12-06 devnull /* clunk all outstanding fids */
511 d3df3087 2003-12-06 devnull for(i=0; i<NHASH; i++){
512 05b7f431 2004-03-02 devnull for(h=c->fid[i]; h; h=hnext){
513 d3df3087 2003-12-06 devnull f = h->v;
514 e2a1725d 2005-01-04 devnull m = msgnew(0);
515 d3df3087 2003-12-06 devnull m->internal = 1;
516 d3df3087 2003-12-06 devnull m->c = c;
517 32f69c36 2003-12-11 devnull c->nmsg++;
518 d3df3087 2003-12-06 devnull m->tx.type = Tclunk;
519 d3df3087 2003-12-06 devnull m->tx.tag = m->tag;
520 d3df3087 2003-12-06 devnull m->tx.fid = f->fid;
521 d3df3087 2003-12-06 devnull m->fid = f;
522 d3df3087 2003-12-06 devnull f->ref++;
523 e2a1725d 2005-01-04 devnull msgincref(m);
524 ceb04770 2003-12-09 devnull sendomsg(m);
525 05b7f431 2004-03-02 devnull mm = recvp(c->internal);
526 05b7f431 2004-03-02 devnull assert(mm == m);
527 e2a1725d 2005-01-04 devnull msgclear(m);
528 32f69c36 2003-12-11 devnull msgput(m); /* got from recvp */
529 32f69c36 2003-12-11 devnull msgput(m); /* got from msgnew */
530 32f69c36 2003-12-11 devnull fidput(f); /* got from hash table */
531 05b7f431 2004-03-02 devnull hnext = h->next;
532 05b7f431 2004-03-02 devnull free(h);
533 d3df3087 2003-12-06 devnull }
534 d3df3087 2003-12-06 devnull }
535 d3df3087 2003-12-06 devnull
536 d3df3087 2003-12-06 devnull out:
537 e2a1725d 2005-01-04 devnull closeioproc(io);
538 d3df3087 2003-12-06 devnull assert(c->nmsg == 0);
539 d3df3087 2003-12-06 devnull assert(c->nfid == 0);
540 d3df3087 2003-12-06 devnull close(c->fd);
541 32f69c36 2003-12-11 devnull chanfree(c->internal);
542 32f69c36 2003-12-11 devnull c->internal = 0;
543 32f69c36 2003-12-11 devnull chanfree(c->inc);
544 32f69c36 2003-12-11 devnull c->inc = 0;
545 32f69c36 2003-12-11 devnull free(c->inq);
546 32f69c36 2003-12-11 devnull c->inq = 0;
547 d3df3087 2003-12-06 devnull free(c);
548 d3df3087 2003-12-06 devnull }
549 32f69c36 2003-12-11 devnull
550 32f69c36 2003-12-11 devnull static void
551 32f69c36 2003-12-11 devnull openfdthread(void *v)
552 32f69c36 2003-12-11 devnull {
553 32f69c36 2003-12-11 devnull Conn *c;
554 32f69c36 2003-12-11 devnull Fid *fid;
555 32f69c36 2003-12-11 devnull Msg *m;
556 32f69c36 2003-12-11 devnull int n;
557 32f69c36 2003-12-11 devnull vlong tot;
558 32f69c36 2003-12-11 devnull Ioproc *io;
559 32f69c36 2003-12-11 devnull char buf[1024];
560 32f69c36 2003-12-11 devnull
561 32f69c36 2003-12-11 devnull c = v;
562 32f69c36 2003-12-11 devnull fid = c->fdfid;
563 32f69c36 2003-12-11 devnull io = ioproc();
564 7ffc5208 2004-12-28 devnull threadsetname("openfd %s", c->fdfid);
565 32f69c36 2003-12-11 devnull tot = 0;
566 05b7f431 2004-03-02 devnull m = nil;
567 32f69c36 2003-12-11 devnull if(c->fdmode == OREAD){
568 32f69c36 2003-12-11 devnull for(;;){
569 e2a1725d 2005-01-04 devnull if(verbose) fprint(2, "%T tread...");
570 e2a1725d 2005-01-04 devnull m = msgnew(0);
571 32f69c36 2003-12-11 devnull m->internal = 1;
572 32f69c36 2003-12-11 devnull m->c = c;
573 32f69c36 2003-12-11 devnull m->tx.type = Tread;
574 5a8e63b2 2004-02-29 devnull m->tx.count = msize - IOHDRSZ;
575 32f69c36 2003-12-11 devnull m->tx.fid = fid->fid;
576 32f69c36 2003-12-11 devnull m->tx.tag = m->tag;
577 32f69c36 2003-12-11 devnull m->tx.offset = tot;
578 32f69c36 2003-12-11 devnull m->fid = fid;
579 32f69c36 2003-12-11 devnull fid->ref++;
580 e2a1725d 2005-01-04 devnull msgincref(m);
581 32f69c36 2003-12-11 devnull sendomsg(m);
582 32f69c36 2003-12-11 devnull recvp(c->internal);
583 49588d5d 2003-12-17 devnull if(m->rx.type == Rerror){
584 e2a1725d 2005-01-04 devnull // fprint(2, "%T read error: %s\n", m->rx.ename);
585 32f69c36 2003-12-11 devnull break;
586 49588d5d 2003-12-17 devnull }
587 32f69c36 2003-12-11 devnull if(m->rx.count == 0)
588 32f69c36 2003-12-11 devnull break;
589 32f69c36 2003-12-11 devnull tot += m->rx.count;
590 49588d5d 2003-12-17 devnull if(iowrite(io, c->fd, m->rx.data, m->rx.count) != m->rx.count){
591 e2a1725d 2005-01-04 devnull // fprint(2, "%T pipe write error: %r\n");
592 32f69c36 2003-12-11 devnull break;
593 49588d5d 2003-12-17 devnull }
594 32f69c36 2003-12-11 devnull msgput(m);
595 32f69c36 2003-12-11 devnull msgput(m);
596 05b7f431 2004-03-02 devnull m = nil;
597 32f69c36 2003-12-11 devnull }
598 32f69c36 2003-12-11 devnull }else{
599 32f69c36 2003-12-11 devnull for(;;){
600 e2a1725d 2005-01-04 devnull if(verbose) fprint(2, "%T twrite...");
601 5a8e63b2 2004-02-29 devnull n = sizeof buf;
602 5a8e63b2 2004-02-29 devnull if(n > msize)
603 5a8e63b2 2004-02-29 devnull n = msize;
604 5a8e63b2 2004-02-29 devnull if((n=ioread(io, c->fd, buf, n)) <= 0){
605 49588d5d 2003-12-17 devnull if(n < 0)
606 e2a1725d 2005-01-04 devnull fprint(2, "%T pipe read error: %r\n");
607 32f69c36 2003-12-11 devnull break;
608 32f69c36 2003-12-11 devnull }
609 e2a1725d 2005-01-04 devnull m = msgnew(0);
610 32f69c36 2003-12-11 devnull m->internal = 1;
611 32f69c36 2003-12-11 devnull m->c = c;
612 32f69c36 2003-12-11 devnull m->tx.type = Twrite;
613 32f69c36 2003-12-11 devnull m->tx.fid = fid->fid;
614 32f69c36 2003-12-11 devnull m->tx.data = buf;
615 32f69c36 2003-12-11 devnull m->tx.count = n;
616 32f69c36 2003-12-11 devnull m->tx.tag = m->tag;
617 32f69c36 2003-12-11 devnull m->tx.offset = tot;
618 32f69c36 2003-12-11 devnull m->fid = fid;
619 32f69c36 2003-12-11 devnull fid->ref++;
620 e2a1725d 2005-01-04 devnull msgincref(m);
621 32f69c36 2003-12-11 devnull sendomsg(m);
622 32f69c36 2003-12-11 devnull recvp(c->internal);
623 49588d5d 2003-12-17 devnull if(m->rx.type == Rerror){
624 e2a1725d 2005-01-04 devnull // fprint(2, "%T write error: %s\n", m->rx.ename);
625 49588d5d 2003-12-17 devnull }
626 05b7f431 2004-03-02 devnull tot += n;
627 32f69c36 2003-12-11 devnull msgput(m);
628 32f69c36 2003-12-11 devnull msgput(m);
629 05b7f431 2004-03-02 devnull m = nil;
630 32f69c36 2003-12-11 devnull }
631 32f69c36 2003-12-11 devnull }
632 e2a1725d 2005-01-04 devnull if(verbose) fprint(2, "%T eof on %d fid %d\n", c->fd, fid->fid);
633 32f69c36 2003-12-11 devnull close(c->fd);
634 32f69c36 2003-12-11 devnull closeioproc(io);
635 32f69c36 2003-12-11 devnull if(m){
636 32f69c36 2003-12-11 devnull msgput(m);
637 32f69c36 2003-12-11 devnull msgput(m);
638 32f69c36 2003-12-11 devnull }
639 e2a1725d 2005-01-04 devnull if(verbose) fprint(2, "%T eof on %d fid %d ref %d\n", c->fd, fid->fid, fid->ref);
640 21e626de 2004-12-28 devnull if(--fid->openfd == 0){
641 e2a1725d 2005-01-04 devnull m = msgnew(0);
642 49588d5d 2003-12-17 devnull m->internal = 1;
643 49588d5d 2003-12-17 devnull m->c = c;
644 49588d5d 2003-12-17 devnull m->tx.type = Tclunk;
645 05b7f431 2004-03-02 devnull m->tx.tag = m->tag;
646 49588d5d 2003-12-17 devnull m->tx.fid = fid->fid;
647 49588d5d 2003-12-17 devnull m->fid = fid;
648 49588d5d 2003-12-17 devnull fid->ref++;
649 e2a1725d 2005-01-04 devnull msgincref(m);
650 49588d5d 2003-12-17 devnull sendomsg(m);
651 49588d5d 2003-12-17 devnull recvp(c->internal);
652 49588d5d 2003-12-17 devnull msgput(m);
653 49588d5d 2003-12-17 devnull msgput(m);
654 49588d5d 2003-12-17 devnull }
655 32f69c36 2003-12-11 devnull fidput(fid);
656 32f69c36 2003-12-11 devnull c->fdfid = nil;
657 32f69c36 2003-12-11 devnull chanfree(c->internal);
658 32f69c36 2003-12-11 devnull c->internal = 0;
659 32f69c36 2003-12-11 devnull free(c);
660 32f69c36 2003-12-11 devnull }
661 d3df3087 2003-12-06 devnull
662 32f69c36 2003-12-11 devnull int
663 32f69c36 2003-12-11 devnull xopenfd(Msg *m)
664 32f69c36 2003-12-11 devnull {
665 32f69c36 2003-12-11 devnull char errs[ERRMAX];
666 32f69c36 2003-12-11 devnull int n, p[2];
667 32f69c36 2003-12-11 devnull Conn *nc;
668 32f69c36 2003-12-11 devnull
669 32f69c36 2003-12-11 devnull if(pipe(p) < 0){
670 32f69c36 2003-12-11 devnull rerrstr(errs, sizeof errs);
671 32f69c36 2003-12-11 devnull err(m, errs);
672 21e626de 2004-12-28 devnull /* XXX return here? */
673 32f69c36 2003-12-11 devnull }
674 e2a1725d 2005-01-04 devnull if(verbose) fprint(2, "%T xopen pipe %d %d...", p[0], p[1]);
675 32f69c36 2003-12-11 devnull
676 32f69c36 2003-12-11 devnull /* now we're committed. */
677 32f69c36 2003-12-11 devnull
678 32f69c36 2003-12-11 devnull /* a new connection for this fid */
679 32f69c36 2003-12-11 devnull nc = emalloc(sizeof(Conn));
680 32f69c36 2003-12-11 devnull nc->internal = chancreate(sizeof(void*), 0);
681 32f69c36 2003-12-11 devnull
682 32f69c36 2003-12-11 devnull /* a ref for us */
683 32f69c36 2003-12-11 devnull nc->fdfid = m->fid;
684 32f69c36 2003-12-11 devnull m->fid->ref++;
685 21e626de 2004-12-28 devnull nc->fdfid->openfd++;
686 32f69c36 2003-12-11 devnull nc->fdmode = m->tx.mode;
687 32f69c36 2003-12-11 devnull nc->fd = p[0];
688 32f69c36 2003-12-11 devnull
689 32f69c36 2003-12-11 devnull /* a thread to tend the pipe */
690 32f69c36 2003-12-11 devnull threadcreate(openfdthread, nc, STACK);
691 32f69c36 2003-12-11 devnull
692 49588d5d 2003-12-17 devnull /* if mode is ORDWR, that openfdthread will write; start a reader */
693 49588d5d 2003-12-17 devnull if((m->tx.mode&3) == ORDWR){
694 49588d5d 2003-12-17 devnull nc = emalloc(sizeof(Conn));
695 49588d5d 2003-12-17 devnull nc->internal = chancreate(sizeof(void*), 0);
696 49588d5d 2003-12-17 devnull nc->fdfid = m->fid;
697 49588d5d 2003-12-17 devnull m->fid->ref++;
698 21e626de 2004-12-28 devnull nc->fdfid->openfd++;
699 49588d5d 2003-12-17 devnull nc->fdmode = OREAD;
700 49588d5d 2003-12-17 devnull nc->fd = dup(p[0], -1);
701 49588d5d 2003-12-17 devnull threadcreate(openfdthread, nc, STACK);
702 49588d5d 2003-12-17 devnull }
703 49588d5d 2003-12-17 devnull
704 49588d5d 2003-12-17 devnull /* steal fid from other connection */
705 49588d5d 2003-12-17 devnull if(delhash(m->c->fid, m->fid->cfid, m->fid) == 0)
706 49588d5d 2003-12-17 devnull fidput(m->fid);
707 49588d5d 2003-12-17 devnull
708 32f69c36 2003-12-11 devnull /* rewrite as Ropenfd */
709 32f69c36 2003-12-11 devnull m->rx.type = Ropenfd;
710 32f69c36 2003-12-11 devnull n = GBIT32(m->rpkt);
711 32f69c36 2003-12-11 devnull m->rpkt = erealloc(m->rpkt, n+4);
712 32f69c36 2003-12-11 devnull PBIT32(m->rpkt+n, p[1]);
713 32f69c36 2003-12-11 devnull n += 4;
714 32f69c36 2003-12-11 devnull PBIT32(m->rpkt, n);
715 32f69c36 2003-12-11 devnull m->rpkt[4] = Ropenfd;
716 32f69c36 2003-12-11 devnull m->rx.unixfd = p[1];
717 32f69c36 2003-12-11 devnull return 0;
718 32f69c36 2003-12-11 devnull }
719 32f69c36 2003-12-11 devnull
720 d3df3087 2003-12-06 devnull void
721 d3df3087 2003-12-06 devnull connoutthread(void *arg)
722 d3df3087 2003-12-06 devnull {
723 d3df3087 2003-12-06 devnull int err;
724 d3df3087 2003-12-06 devnull Conn *c;
725 05b7f431 2004-03-02 devnull Queue *outq;
726 d3df3087 2003-12-06 devnull Msg *m, *om;
727 ceb04770 2003-12-09 devnull Ioproc *io;
728 d3df3087 2003-12-06 devnull
729 d3df3087 2003-12-06 devnull c = arg;
730 05b7f431 2004-03-02 devnull outq = c->outq;
731 ceb04770 2003-12-09 devnull io = ioproc();
732 7ffc5208 2004-12-28 devnull threadsetname("connout %s", c->dir);
733 05b7f431 2004-03-02 devnull while((m = recvq(outq)) != nil){
734 d3df3087 2003-12-06 devnull err = m->tx.type+1 != m->rx.type;
735 32f69c36 2003-12-11 devnull if(!err && m->isopenfd)
736 32f69c36 2003-12-11 devnull if(xopenfd(m) < 0)
737 32f69c36 2003-12-11 devnull continue;
738 d3df3087 2003-12-06 devnull switch(m->tx.type){
739 d3df3087 2003-12-06 devnull case Tflush:
740 d3df3087 2003-12-06 devnull om = m->oldm;
741 ceb04770 2003-12-09 devnull if(om)
742 ceb04770 2003-12-09 devnull if(delhash(om->c->tag, om->ctag, om) == 0)
743 ceb04770 2003-12-09 devnull msgput(om);
744 d3df3087 2003-12-06 devnull break;
745 d3df3087 2003-12-06 devnull case Tclunk:
746 ceb04770 2003-12-09 devnull case Tremove:
747 ceb04770 2003-12-09 devnull if(m->fid)
748 ceb04770 2003-12-09 devnull if(delhash(m->c->fid, m->fid->cfid, m->fid) == 0)
749 ceb04770 2003-12-09 devnull fidput(m->fid);
750 d3df3087 2003-12-06 devnull break;
751 d3df3087 2003-12-06 devnull case Tauth:
752 ceb04770 2003-12-09 devnull if(err && m->afid){
753 80568494 2005-02-11 devnull if(verbose) fprint(2, "%T auth error\n");
754 ceb04770 2003-12-09 devnull if(delhash(m->c->fid, m->afid->cfid, m->afid) == 0)
755 80568494 2005-02-11 devnull fidput(m->afid);
756 ceb04770 2003-12-09 devnull }
757 ceb04770 2003-12-09 devnull break;
758 d3df3087 2003-12-06 devnull case Tattach:
759 ceb04770 2003-12-09 devnull if(err && m->fid)
760 d3df3087 2003-12-06 devnull if(delhash(m->c->fid, m->fid->cfid, m->fid) == 0)
761 d3df3087 2003-12-06 devnull fidput(m->fid);
762 d3df3087 2003-12-06 devnull break;
763 d3df3087 2003-12-06 devnull case Twalk:
764 5c84c448 2005-03-21 devnull if(err || m->rx.nwqid < m->tx.nwname)
765 5c84c448 2005-03-21 devnull if(m->tx.fid != m->tx.newfid && m->newfid)
766 d3df3087 2003-12-06 devnull if(delhash(m->c->fid, m->newfid->cfid, m->newfid) == 0)
767 d3df3087 2003-12-06 devnull fidput(m->newfid);
768 d3df3087 2003-12-06 devnull break;
769 d3df3087 2003-12-06 devnull }
770 d3df3087 2003-12-06 devnull if(delhash(m->c->tag, m->ctag, m) == 0)
771 d3df3087 2003-12-06 devnull msgput(m);
772 e2a1725d 2005-01-04 devnull if(verbose > 1) fprint(2, "%T fd#%d <- %F\n", c->fd, &m->rx);
773 ceb04770 2003-12-09 devnull rewritehdr(&m->rx, m->rpkt);
774 ceb04770 2003-12-09 devnull if(mwrite9p(io, c->fd, m->rpkt) < 0)
775 e2a1725d 2005-01-04 devnull if(verbose) fprint(2, "%T write error: %r\n");
776 d3df3087 2003-12-06 devnull msgput(m);
777 d3df3087 2003-12-06 devnull if(c->inputstalled && c->nmsg < MAXMSG)
778 d3df3087 2003-12-06 devnull nbsendp(c->inc, 0);
779 d3df3087 2003-12-06 devnull }
780 ceb04770 2003-12-09 devnull closeioproc(io);
781 05b7f431 2004-03-02 devnull free(outq);
782 05b7f431 2004-03-02 devnull c->outq = nil;
783 d3df3087 2003-12-06 devnull }
784 d3df3087 2003-12-06 devnull
785 d3df3087 2003-12-06 devnull void
786 d3df3087 2003-12-06 devnull outputthread(void *arg)
787 d3df3087 2003-12-06 devnull {
788 d3df3087 2003-12-06 devnull Msg *m;
789 ceb04770 2003-12-09 devnull Ioproc *io;
790 d3df3087 2003-12-06 devnull
791 d3df3087 2003-12-06 devnull USED(arg);
792 ceb04770 2003-12-09 devnull io = ioproc();
793 7ffc5208 2004-12-28 devnull threadsetname("output");
794 d3df3087 2003-12-06 devnull while((m = recvq(outq)) != nil){
795 e2a1725d 2005-01-04 devnull if(verbose > 1) fprint(2, "%T * <- %F\n", &m->tx);
796 ceb04770 2003-12-09 devnull rewritehdr(&m->tx, m->tpkt);
797 ceb04770 2003-12-09 devnull if(mwrite9p(io, 1, m->tpkt) < 0)
798 d3df3087 2003-12-06 devnull sysfatal("output error: %r");
799 d3df3087 2003-12-06 devnull msgput(m);
800 d3df3087 2003-12-06 devnull }
801 ceb04770 2003-12-09 devnull closeioproc(io);
802 e2a1725d 2005-01-04 devnull fprint(2, "%T output eof\n");
803 32f69c36 2003-12-11 devnull threadexitsall(0);
804 d3df3087 2003-12-06 devnull }
805 d3df3087 2003-12-06 devnull
806 d3df3087 2003-12-06 devnull void
807 d3df3087 2003-12-06 devnull inputthread(void *arg)
808 d3df3087 2003-12-06 devnull {
809 d3df3087 2003-12-06 devnull uchar *pkt;
810 d3df3087 2003-12-06 devnull int n, nn, tag;
811 d3df3087 2003-12-06 devnull Msg *m;
812 ceb04770 2003-12-09 devnull Ioproc *io;
813 d3df3087 2003-12-06 devnull
814 7ffc5208 2004-12-28 devnull threadsetname("input");
815 e2a1725d 2005-01-04 devnull if(verbose) fprint(2, "%T input thread\n");
816 ceb04770 2003-12-09 devnull io = ioproc();
817 ceb04770 2003-12-09 devnull USED(arg);
818 ceb04770 2003-12-09 devnull while((pkt = read9ppkt(io, 0)) != nil){
819 d3df3087 2003-12-06 devnull n = GBIT32(pkt);
820 d3df3087 2003-12-06 devnull if(n < 7){
821 e2a1725d 2005-01-04 devnull fprint(2, "%T short 9P packet from server\n");
822 d3df3087 2003-12-06 devnull free(pkt);
823 d3df3087 2003-12-06 devnull continue;
824 d3df3087 2003-12-06 devnull }
825 e2a1725d 2005-01-04 devnull if(verbose > 2) fprint(2, "%T read %.*H\n", n, pkt);
826 d3df3087 2003-12-06 devnull tag = GBIT16(pkt+5);
827 d3df3087 2003-12-06 devnull if((m = msgget(tag)) == nil){
828 e2a1725d 2005-01-04 devnull fprint(2, "%T unexpected 9P response tag %d\n", tag);
829 d3df3087 2003-12-06 devnull free(pkt);
830 d3df3087 2003-12-06 devnull continue;
831 d3df3087 2003-12-06 devnull }
832 d3df3087 2003-12-06 devnull if((nn = convM2S(pkt, n, &m->rx)) != n){
833 e2a1725d 2005-01-04 devnull fprint(2, "%T bad packet - convM2S %d but %d\n", nn, n);
834 d3df3087 2003-12-06 devnull free(pkt);
835 d3df3087 2003-12-06 devnull msgput(m);
836 d3df3087 2003-12-06 devnull continue;
837 d3df3087 2003-12-06 devnull }
838 e2a1725d 2005-01-04 devnull if(verbose > 1) fprint(2, "%T * -> %F%s\n", &m->rx,
839 05b7f431 2004-03-02 devnull m->internal ? " (internal)" : "");
840 d3df3087 2003-12-06 devnull m->rpkt = pkt;
841 d3df3087 2003-12-06 devnull m->rx.tag = m->ctag;
842 ceb04770 2003-12-09 devnull if(m->internal)
843 05b7f431 2004-03-02 devnull sendp(m->c->internal, m);
844 05b7f431 2004-03-02 devnull else if(m->c->outq)
845 ceb04770 2003-12-09 devnull sendq(m->c->outq, m);
846 05b7f431 2004-03-02 devnull else
847 05b7f431 2004-03-02 devnull msgput(m);
848 d3df3087 2003-12-06 devnull }
849 ceb04770 2003-12-09 devnull closeioproc(io);
850 e2a1725d 2005-01-04 devnull //fprint(2, "%T input eof\n");
851 32f69c36 2003-12-11 devnull threadexitsall(0);
852 d3df3087 2003-12-06 devnull }
853 d3df3087 2003-12-06 devnull
854 d3df3087 2003-12-06 devnull void*
855 d3df3087 2003-12-06 devnull gethash(Hash **ht, uint n)
856 d3df3087 2003-12-06 devnull {
857 d3df3087 2003-12-06 devnull Hash *h;
858 d3df3087 2003-12-06 devnull
859 d3df3087 2003-12-06 devnull for(h=ht[n%NHASH]; h; h=h->next)
860 d3df3087 2003-12-06 devnull if(h->n == n)
861 d3df3087 2003-12-06 devnull return h->v;
862 d3df3087 2003-12-06 devnull return nil;
863 d3df3087 2003-12-06 devnull }
864 d3df3087 2003-12-06 devnull
865 d3df3087 2003-12-06 devnull int
866 d3df3087 2003-12-06 devnull delhash(Hash **ht, uint n, void *v)
867 d3df3087 2003-12-06 devnull {
868 d3df3087 2003-12-06 devnull Hash *h, **l;
869 d3df3087 2003-12-06 devnull
870 d3df3087 2003-12-06 devnull for(l=&ht[n%NHASH]; h=*l; l=&h->next)
871 d3df3087 2003-12-06 devnull if(h->n == n){
872 ceb04770 2003-12-09 devnull if(h->v != v){
873 e2a1725d 2005-01-04 devnull if(verbose) fprint(2, "%T delhash %d got %p want %p\n", n, h->v, v);
874 ceb04770 2003-12-09 devnull return -1;
875 ceb04770 2003-12-09 devnull }
876 d3df3087 2003-12-06 devnull *l = h->next;
877 d3df3087 2003-12-06 devnull free(h);
878 d3df3087 2003-12-06 devnull return 0;
879 d3df3087 2003-12-06 devnull }
880 d3df3087 2003-12-06 devnull return -1;
881 d3df3087 2003-12-06 devnull }
882 d3df3087 2003-12-06 devnull
883 d3df3087 2003-12-06 devnull int
884 d3df3087 2003-12-06 devnull puthash(Hash **ht, uint n, void *v)
885 d3df3087 2003-12-06 devnull {
886 d3df3087 2003-12-06 devnull Hash *h;
887 d3df3087 2003-12-06 devnull
888 d3df3087 2003-12-06 devnull if(gethash(ht, n))
889 d3df3087 2003-12-06 devnull return -1;
890 d3df3087 2003-12-06 devnull h = emalloc(sizeof(Hash));
891 d3df3087 2003-12-06 devnull h->next = ht[n%NHASH];
892 d3df3087 2003-12-06 devnull h->n = n;
893 d3df3087 2003-12-06 devnull h->v = v;
894 d3df3087 2003-12-06 devnull ht[n%NHASH] = h;
895 d3df3087 2003-12-06 devnull return 0;
896 d3df3087 2003-12-06 devnull }
897 d3df3087 2003-12-06 devnull
898 d3df3087 2003-12-06 devnull Fid **fidtab;
899 d3df3087 2003-12-06 devnull int nfidtab;
900 d3df3087 2003-12-06 devnull Fid *freefid;
901 d3df3087 2003-12-06 devnull
902 d3df3087 2003-12-06 devnull Fid*
903 d3df3087 2003-12-06 devnull fidnew(int cfid)
904 d3df3087 2003-12-06 devnull {
905 d3df3087 2003-12-06 devnull Fid *f;
906 d3df3087 2003-12-06 devnull
907 d3df3087 2003-12-06 devnull if(freefid == nil){
908 ceb04770 2003-12-09 devnull fidtab = erealloc(fidtab, (nfidtab+1)*sizeof(fidtab[0]));
909 5c84c448 2005-03-21 devnull if(nfidtab == xafid){
910 5c84c448 2005-03-21 devnull fidtab[nfidtab++] = nil;
911 5c84c448 2005-03-21 devnull fidtab = erealloc(fidtab, (nfidtab+1)*sizeof(fidtab[0]));
912 5c84c448 2005-03-21 devnull }
913 d3df3087 2003-12-06 devnull fidtab[nfidtab] = emalloc(sizeof(Fid));
914 ceb04770 2003-12-09 devnull freefid = fidtab[nfidtab];
915 ceb04770 2003-12-09 devnull freefid->fid = nfidtab++;
916 d3df3087 2003-12-06 devnull }
917 d3df3087 2003-12-06 devnull f = freefid;
918 d3df3087 2003-12-06 devnull freefid = f->next;
919 ceb04770 2003-12-09 devnull f->cfid = cfid;
920 d3df3087 2003-12-06 devnull f->ref = 1;
921 d3df3087 2003-12-06 devnull return f;
922 d3df3087 2003-12-06 devnull }
923 d3df3087 2003-12-06 devnull
924 d3df3087 2003-12-06 devnull void
925 d3df3087 2003-12-06 devnull fidput(Fid *f)
926 d3df3087 2003-12-06 devnull {
927 ceb04770 2003-12-09 devnull if(f == nil)
928 ceb04770 2003-12-09 devnull return;
929 d3df3087 2003-12-06 devnull assert(f->ref > 0);
930 d3df3087 2003-12-06 devnull if(--f->ref > 0)
931 d3df3087 2003-12-06 devnull return;
932 d3df3087 2003-12-06 devnull f->next = freefid;
933 d3df3087 2003-12-06 devnull f->cfid = -1;
934 d3df3087 2003-12-06 devnull freefid = f;
935 d3df3087 2003-12-06 devnull }
936 d3df3087 2003-12-06 devnull
937 d3df3087 2003-12-06 devnull Msg **msgtab;
938 d3df3087 2003-12-06 devnull int nmsgtab;
939 d3df3087 2003-12-06 devnull Msg *freemsg;
940 d3df3087 2003-12-06 devnull
941 e2a1725d 2005-01-04 devnull void
942 e2a1725d 2005-01-04 devnull msgincref(Msg *m)
943 e2a1725d 2005-01-04 devnull {
944 e2a1725d 2005-01-04 devnull if(verbose > 1) fprint(2, "%T msgincref @0x%lux %p tag %d/%d ref %d=>%d\n",
945 e2a1725d 2005-01-04 devnull getcallerpc(&m), m, m->tag, m->ctag, m->ref, m->ref+1);
946 e2a1725d 2005-01-04 devnull m->ref++;
947 e2a1725d 2005-01-04 devnull }
948 e2a1725d 2005-01-04 devnull
949 d3df3087 2003-12-06 devnull Msg*
950 e2a1725d 2005-01-04 devnull msgnew(int x)
951 d3df3087 2003-12-06 devnull {
952 d3df3087 2003-12-06 devnull Msg *m;
953 d3df3087 2003-12-06 devnull
954 d3df3087 2003-12-06 devnull if(freemsg == nil){
955 ceb04770 2003-12-09 devnull msgtab = erealloc(msgtab, (nmsgtab+1)*sizeof(msgtab[0]));
956 d3df3087 2003-12-06 devnull msgtab[nmsgtab] = emalloc(sizeof(Msg));
957 ceb04770 2003-12-09 devnull freemsg = msgtab[nmsgtab];
958 ceb04770 2003-12-09 devnull freemsg->tag = nmsgtab++;
959 d3df3087 2003-12-06 devnull }
960 d3df3087 2003-12-06 devnull m = freemsg;
961 d3df3087 2003-12-06 devnull freemsg = m->next;
962 d3df3087 2003-12-06 devnull m->ref = 1;
963 e2a1725d 2005-01-04 devnull if(verbose > 1) fprint(2, "%T msgnew @0x%lux %p tag %d ref %d\n",
964 e2a1725d 2005-01-04 devnull getcallerpc(&x), m, m->tag, m->ref);
965 d3df3087 2003-12-06 devnull return m;
966 e2a1725d 2005-01-04 devnull }
967 e2a1725d 2005-01-04 devnull
968 e2a1725d 2005-01-04 devnull /*
969 e2a1725d 2005-01-04 devnull * Clear data associated with connections, so that
970 e2a1725d 2005-01-04 devnull * if all msgs have been msgcleared, the connection
971 e2a1725d 2005-01-04 devnull * can be freed. Note that this does *not* free the tpkt
972 e2a1725d 2005-01-04 devnull * and rpkt; they are freed in msgput with the msg itself.
973 e2a1725d 2005-01-04 devnull * The io write thread might still be holding a ref to msg
974 e2a1725d 2005-01-04 devnull * even once the connection has finished with it.
975 e2a1725d 2005-01-04 devnull */
976 e2a1725d 2005-01-04 devnull void
977 e2a1725d 2005-01-04 devnull msgclear(Msg *m)
978 e2a1725d 2005-01-04 devnull {
979 e2a1725d 2005-01-04 devnull if(m->c){
980 e2a1725d 2005-01-04 devnull m->c->nmsg--;
981 e2a1725d 2005-01-04 devnull m->c = nil;
982 e2a1725d 2005-01-04 devnull }
983 e2a1725d 2005-01-04 devnull if(m->oldm){
984 e2a1725d 2005-01-04 devnull msgput(m->oldm);
985 e2a1725d 2005-01-04 devnull m->oldm = nil;
986 e2a1725d 2005-01-04 devnull }
987 e2a1725d 2005-01-04 devnull if(m->fid){
988 e2a1725d 2005-01-04 devnull fidput(m->fid);
989 e2a1725d 2005-01-04 devnull m->fid = nil;
990 e2a1725d 2005-01-04 devnull }
991 e2a1725d 2005-01-04 devnull if(m->afid){
992 e2a1725d 2005-01-04 devnull fidput(m->afid);
993 e2a1725d 2005-01-04 devnull m->afid = nil;
994 e2a1725d 2005-01-04 devnull }
995 e2a1725d 2005-01-04 devnull if(m->newfid){
996 e2a1725d 2005-01-04 devnull fidput(m->newfid);
997 e2a1725d 2005-01-04 devnull m->newfid = nil;
998 e2a1725d 2005-01-04 devnull }
999 e2a1725d 2005-01-04 devnull if(m->rx.type == Ropenfd && m->rx.unixfd >= 0){
1000 e2a1725d 2005-01-04 devnull close(m->rx.unixfd);
1001 e2a1725d 2005-01-04 devnull m->rx.unixfd = -1;
1002 e2a1725d 2005-01-04 devnull }
1003 d3df3087 2003-12-06 devnull }
1004 d3df3087 2003-12-06 devnull
1005 d3df3087 2003-12-06 devnull void
1006 d3df3087 2003-12-06 devnull msgput(Msg *m)
1007 d3df3087 2003-12-06 devnull {
1008 05b7f431 2004-03-02 devnull if(m == nil)
1009 05b7f431 2004-03-02 devnull return;
1010 05b7f431 2004-03-02 devnull
1011 e2a1725d 2005-01-04 devnull if(verbose > 1) fprint(2, "%T msgput 0x%lux %p tag %d/%d ref %d\n",
1012 e2a1725d 2005-01-04 devnull getcallerpc(&m), m, m->tag, m->ctag, m->ref);
1013 d3df3087 2003-12-06 devnull assert(m->ref > 0);
1014 d3df3087 2003-12-06 devnull if(--m->ref > 0)
1015 d3df3087 2003-12-06 devnull return;
1016 e2a1725d 2005-01-04 devnull msgclear(m);
1017 e2a1725d 2005-01-04 devnull if(m->tpkt){
1018 e2a1725d 2005-01-04 devnull free(m->tpkt);
1019 e2a1725d 2005-01-04 devnull m->tpkt = nil;
1020 e2a1725d 2005-01-04 devnull }
1021 e2a1725d 2005-01-04 devnull if(m->rpkt){
1022 e2a1725d 2005-01-04 devnull free(m->rpkt);
1023 e2a1725d 2005-01-04 devnull m->rpkt = nil;
1024 e2a1725d 2005-01-04 devnull }
1025 32f69c36 2003-12-11 devnull m->isopenfd = 0;
1026 32f69c36 2003-12-11 devnull m->internal = 0;
1027 d3df3087 2003-12-06 devnull m->next = freemsg;
1028 d3df3087 2003-12-06 devnull freemsg = m;
1029 d3df3087 2003-12-06 devnull }
1030 d3df3087 2003-12-06 devnull
1031 ceb04770 2003-12-09 devnull Msg*
1032 ceb04770 2003-12-09 devnull msgget(int n)
1033 ceb04770 2003-12-09 devnull {
1034 ceb04770 2003-12-09 devnull Msg *m;
1035 ceb04770 2003-12-09 devnull
1036 ceb04770 2003-12-09 devnull if(n < 0 || n >= nmsgtab)
1037 ceb04770 2003-12-09 devnull return nil;
1038 ceb04770 2003-12-09 devnull m = msgtab[n];
1039 ceb04770 2003-12-09 devnull if(m->ref == 0)
1040 ceb04770 2003-12-09 devnull return nil;
1041 e2a1725d 2005-01-04 devnull if(verbose) fprint(2, "%T msgget %d = %p\n", n, m);
1042 e2a1725d 2005-01-04 devnull msgincref(m);
1043 ceb04770 2003-12-09 devnull return m;
1044 ceb04770 2003-12-09 devnull }
1045 ceb04770 2003-12-09 devnull
1046 ceb04770 2003-12-09 devnull
1047 d3df3087 2003-12-06 devnull void*
1048 d3df3087 2003-12-06 devnull emalloc(int n)
1049 d3df3087 2003-12-06 devnull {
1050 d3df3087 2003-12-06 devnull void *v;
1051 d3df3087 2003-12-06 devnull
1052 d3df3087 2003-12-06 devnull v = mallocz(n, 1);
1053 ceb04770 2003-12-09 devnull if(v == nil){
1054 ceb04770 2003-12-09 devnull abort();
1055 ceb04770 2003-12-09 devnull sysfatal("out of memory allocating %d", n);
1056 ceb04770 2003-12-09 devnull }
1057 d3df3087 2003-12-06 devnull return v;
1058 d3df3087 2003-12-06 devnull }
1059 d3df3087 2003-12-06 devnull
1060 d3df3087 2003-12-06 devnull void*
1061 d3df3087 2003-12-06 devnull erealloc(void *v, int n)
1062 d3df3087 2003-12-06 devnull {
1063 d3df3087 2003-12-06 devnull v = realloc(v, n);
1064 ceb04770 2003-12-09 devnull if(v == nil){
1065 ceb04770 2003-12-09 devnull abort();
1066 ceb04770 2003-12-09 devnull sysfatal("out of memory reallocating %d", n);
1067 ceb04770 2003-12-09 devnull }
1068 d3df3087 2003-12-06 devnull return v;
1069 d3df3087 2003-12-06 devnull }
1070 d3df3087 2003-12-06 devnull
1071 d3df3087 2003-12-06 devnull typedef struct Qel Qel;
1072 d3df3087 2003-12-06 devnull struct Qel
1073 d3df3087 2003-12-06 devnull {
1074 d3df3087 2003-12-06 devnull Qel *next;
1075 d3df3087 2003-12-06 devnull void *p;
1076 d3df3087 2003-12-06 devnull };
1077 d3df3087 2003-12-06 devnull
1078 d3df3087 2003-12-06 devnull struct Queue
1079 d3df3087 2003-12-06 devnull {
1080 d3df3087 2003-12-06 devnull int hungup;
1081 d3df3087 2003-12-06 devnull QLock lk;
1082 d3df3087 2003-12-06 devnull Rendez r;
1083 d3df3087 2003-12-06 devnull Qel *head;
1084 d3df3087 2003-12-06 devnull Qel *tail;
1085 d3df3087 2003-12-06 devnull };
1086 d3df3087 2003-12-06 devnull
1087 d3df3087 2003-12-06 devnull Queue*
1088 d3df3087 2003-12-06 devnull qalloc(void)
1089 d3df3087 2003-12-06 devnull {
1090 d3df3087 2003-12-06 devnull Queue *q;
1091 d3df3087 2003-12-06 devnull
1092 d3df3087 2003-12-06 devnull q = mallocz(sizeof(Queue), 1);
1093 d3df3087 2003-12-06 devnull if(q == nil)
1094 d3df3087 2003-12-06 devnull return nil;
1095 d3df3087 2003-12-06 devnull q->r.l = &q->lk;
1096 d3df3087 2003-12-06 devnull return q;
1097 d3df3087 2003-12-06 devnull }
1098 d3df3087 2003-12-06 devnull
1099 d3df3087 2003-12-06 devnull int
1100 d3df3087 2003-12-06 devnull sendq(Queue *q, void *p)
1101 d3df3087 2003-12-06 devnull {
1102 d3df3087 2003-12-06 devnull Qel *e;
1103 d3df3087 2003-12-06 devnull
1104 d3df3087 2003-12-06 devnull e = emalloc(sizeof(Qel));
1105 d3df3087 2003-12-06 devnull qlock(&q->lk);
1106 d3df3087 2003-12-06 devnull if(q->hungup){
1107 d3df3087 2003-12-06 devnull werrstr("hungup queue");
1108 d3df3087 2003-12-06 devnull qunlock(&q->lk);
1109 d3df3087 2003-12-06 devnull return -1;
1110 d3df3087 2003-12-06 devnull }
1111 d3df3087 2003-12-06 devnull e->p = p;
1112 d3df3087 2003-12-06 devnull e->next = nil;
1113 d3df3087 2003-12-06 devnull if(q->head == nil)
1114 d3df3087 2003-12-06 devnull q->head = e;
1115 d3df3087 2003-12-06 devnull else
1116 d3df3087 2003-12-06 devnull q->tail->next = e;
1117 d3df3087 2003-12-06 devnull q->tail = e;
1118 d3df3087 2003-12-06 devnull rwakeup(&q->r);
1119 d3df3087 2003-12-06 devnull qunlock(&q->lk);
1120 d3df3087 2003-12-06 devnull return 0;
1121 d3df3087 2003-12-06 devnull }
1122 d3df3087 2003-12-06 devnull
1123 d3df3087 2003-12-06 devnull void*
1124 d3df3087 2003-12-06 devnull recvq(Queue *q)
1125 d3df3087 2003-12-06 devnull {
1126 d3df3087 2003-12-06 devnull void *p;
1127 d3df3087 2003-12-06 devnull Qel *e;
1128 d3df3087 2003-12-06 devnull
1129 d3df3087 2003-12-06 devnull qlock(&q->lk);
1130 d3df3087 2003-12-06 devnull while(q->head == nil && !q->hungup)
1131 d3df3087 2003-12-06 devnull rsleep(&q->r);
1132 d3df3087 2003-12-06 devnull if(q->hungup){
1133 d3df3087 2003-12-06 devnull qunlock(&q->lk);
1134 d3df3087 2003-12-06 devnull return nil;
1135 d3df3087 2003-12-06 devnull }
1136 d3df3087 2003-12-06 devnull e = q->head;
1137 d3df3087 2003-12-06 devnull q->head = e->next;
1138 d3df3087 2003-12-06 devnull qunlock(&q->lk);
1139 d3df3087 2003-12-06 devnull p = e->p;
1140 d3df3087 2003-12-06 devnull free(e);
1141 d3df3087 2003-12-06 devnull return p;
1142 d3df3087 2003-12-06 devnull }
1143 ceb04770 2003-12-09 devnull
1144 ceb04770 2003-12-09 devnull uchar*
1145 ceb04770 2003-12-09 devnull read9ppkt(Ioproc *io, int fd)
1146 ceb04770 2003-12-09 devnull {
1147 ceb04770 2003-12-09 devnull uchar buf[4], *pkt;
1148 ceb04770 2003-12-09 devnull int n, nn;
1149 ceb04770 2003-12-09 devnull
1150 ceb04770 2003-12-09 devnull n = ioreadn(io, fd, buf, 4);
1151 ceb04770 2003-12-09 devnull if(n != 4)
1152 ceb04770 2003-12-09 devnull return nil;
1153 ceb04770 2003-12-09 devnull n = GBIT32(buf);
1154 ceb04770 2003-12-09 devnull pkt = emalloc(n);
1155 ceb04770 2003-12-09 devnull PBIT32(pkt, n);
1156 ceb04770 2003-12-09 devnull nn = ioreadn(io, fd, pkt+4, n-4);
1157 ceb04770 2003-12-09 devnull if(nn != n-4){
1158 ceb04770 2003-12-09 devnull free(pkt);
1159 ceb04770 2003-12-09 devnull return nil;
1160 ceb04770 2003-12-09 devnull }
1161 32f69c36 2003-12-11 devnull /* would do this if we ever got one of these, but we only generate them
1162 32f69c36 2003-12-11 devnull if(pkt[4] == Ropenfd){
1163 32f69c36 2003-12-11 devnull newfd = iorecvfd(io, fd);
1164 32f69c36 2003-12-11 devnull PBIT32(pkt+n-4, newfd);
1165 32f69c36 2003-12-11 devnull }
1166 32f69c36 2003-12-11 devnull */
1167 ceb04770 2003-12-09 devnull return pkt;
1168 ceb04770 2003-12-09 devnull }
1169 ceb04770 2003-12-09 devnull
1170 ceb04770 2003-12-09 devnull Msg*
1171 ceb04770 2003-12-09 devnull mread9p(Ioproc *io, int fd)
1172 ceb04770 2003-12-09 devnull {
1173 ceb04770 2003-12-09 devnull int n, nn;
1174 ceb04770 2003-12-09 devnull uchar *pkt;
1175 ceb04770 2003-12-09 devnull Msg *m;
1176 ceb04770 2003-12-09 devnull
1177 ceb04770 2003-12-09 devnull if((pkt = read9ppkt(io, fd)) == nil)
1178 ceb04770 2003-12-09 devnull return nil;
1179 ceb04770 2003-12-09 devnull
1180 e2a1725d 2005-01-04 devnull m = msgnew(0);
1181 ceb04770 2003-12-09 devnull m->tpkt = pkt;
1182 ceb04770 2003-12-09 devnull n = GBIT32(pkt);
1183 ceb04770 2003-12-09 devnull nn = convM2S(pkt, n, &m->tx);
1184 ceb04770 2003-12-09 devnull if(nn != n){
1185 e2a1725d 2005-01-04 devnull fprint(2, "%T read bad packet from %d\n", fd);
1186 ceb04770 2003-12-09 devnull return nil;
1187 ceb04770 2003-12-09 devnull }
1188 ceb04770 2003-12-09 devnull return m;
1189 ceb04770 2003-12-09 devnull }
1190 ceb04770 2003-12-09 devnull
1191 ceb04770 2003-12-09 devnull int
1192 ceb04770 2003-12-09 devnull mwrite9p(Ioproc *io, int fd, uchar *pkt)
1193 ceb04770 2003-12-09 devnull {
1194 32f69c36 2003-12-11 devnull int n, nfd;
1195 ceb04770 2003-12-09 devnull
1196 ceb04770 2003-12-09 devnull n = GBIT32(pkt);
1197 e2a1725d 2005-01-04 devnull if(verbose > 2) fprint(2, "%T write %d %d %.*H\n", fd, n, n, pkt);
1198 bb426e77 2005-01-06 devnull if(verbose > 1) fprint(2, "%T before iowrite\n");
1199 ceb04770 2003-12-09 devnull if(iowrite(io, fd, pkt, n) != n){
1200 e2a1725d 2005-01-04 devnull fprint(2, "%T write error: %r\n");
1201 ceb04770 2003-12-09 devnull return -1;
1202 ceb04770 2003-12-09 devnull }
1203 bb426e77 2005-01-06 devnull if(verbose > 1) fprint(2, "%T after iowrite\n");
1204 32f69c36 2003-12-11 devnull if(pkt[4] == Ropenfd){
1205 32f69c36 2003-12-11 devnull nfd = GBIT32(pkt+n-4);
1206 32f69c36 2003-12-11 devnull if(iosendfd(io, fd, nfd) < 0){
1207 e2a1725d 2005-01-04 devnull fprint(2, "%T send fd error: %r\n");
1208 32f69c36 2003-12-11 devnull return -1;
1209 32f69c36 2003-12-11 devnull }
1210 32f69c36 2003-12-11 devnull }
1211 ceb04770 2003-12-09 devnull return 0;
1212 ceb04770 2003-12-09 devnull }
1213 ceb04770 2003-12-09 devnull
1214 ceb04770 2003-12-09 devnull void
1215 ceb04770 2003-12-09 devnull restring(uchar *pkt, int pn, char *s)
1216 ceb04770 2003-12-09 devnull {
1217 ceb04770 2003-12-09 devnull int n;
1218 ceb04770 2003-12-09 devnull
1219 ceb04770 2003-12-09 devnull if(s < (char*)pkt || s >= (char*)pkt+pn)
1220 ceb04770 2003-12-09 devnull return;
1221 ceb04770 2003-12-09 devnull
1222 ceb04770 2003-12-09 devnull n = strlen(s);
1223 ceb04770 2003-12-09 devnull memmove(s+1, s, n);
1224 ceb04770 2003-12-09 devnull PBIT16((uchar*)s-1, n);
1225 5c84c448 2005-03-21 devnull }
1226 5c84c448 2005-03-21 devnull
1227 5c84c448 2005-03-21 devnull void
1228 5c84c448 2005-03-21 devnull repack(Fcall *f, uchar **ppkt)
1229 5c84c448 2005-03-21 devnull {
1230 5c84c448 2005-03-21 devnull uint n, nn;
1231 5c84c448 2005-03-21 devnull uchar *pkt;
1232 5c84c448 2005-03-21 devnull
1233 5c84c448 2005-03-21 devnull pkt = *ppkt;
1234 5c84c448 2005-03-21 devnull n = GBIT32(pkt);
1235 5c84c448 2005-03-21 devnull nn = sizeS2M(f);
1236 5c84c448 2005-03-21 devnull if(nn > n){
1237 5c84c448 2005-03-21 devnull free(pkt);
1238 5c84c448 2005-03-21 devnull pkt = emalloc(nn);
1239 5c84c448 2005-03-21 devnull *ppkt = pkt;
1240 5c84c448 2005-03-21 devnull }
1241 5c84c448 2005-03-21 devnull convS2M(f, pkt, nn);
1242 ceb04770 2003-12-09 devnull }
1243 ceb04770 2003-12-09 devnull
1244 ceb04770 2003-12-09 devnull void
1245 ceb04770 2003-12-09 devnull rewritehdr(Fcall *f, uchar *pkt)
1246 ceb04770 2003-12-09 devnull {
1247 ceb04770 2003-12-09 devnull int i, n;
1248 ceb04770 2003-12-09 devnull
1249 ceb04770 2003-12-09 devnull n = GBIT32(pkt);
1250 ceb04770 2003-12-09 devnull PBIT16(pkt+5, f->tag);
1251 ceb04770 2003-12-09 devnull switch(f->type){
1252 ceb04770 2003-12-09 devnull case Tversion:
1253 ceb04770 2003-12-09 devnull case Rversion:
1254 ceb04770 2003-12-09 devnull restring(pkt, n, f->version);
1255 ceb04770 2003-12-09 devnull break;
1256 ceb04770 2003-12-09 devnull case Tauth:
1257 ceb04770 2003-12-09 devnull PBIT32(pkt+7, f->afid);
1258 ceb04770 2003-12-09 devnull restring(pkt, n, f->uname);
1259 ceb04770 2003-12-09 devnull restring(pkt, n, f->aname);
1260 ceb04770 2003-12-09 devnull break;
1261 ceb04770 2003-12-09 devnull case Tflush:
1262 ceb04770 2003-12-09 devnull PBIT16(pkt+7, f->oldtag);
1263 ceb04770 2003-12-09 devnull break;
1264 ceb04770 2003-12-09 devnull case Tattach:
1265 ceb04770 2003-12-09 devnull restring(pkt, n, f->uname);
1266 ceb04770 2003-12-09 devnull restring(pkt, n, f->aname);
1267 ceb04770 2003-12-09 devnull PBIT32(pkt+7, f->fid);
1268 ceb04770 2003-12-09 devnull PBIT32(pkt+11, f->afid);
1269 ceb04770 2003-12-09 devnull break;
1270 ceb04770 2003-12-09 devnull case Twalk:
1271 ceb04770 2003-12-09 devnull PBIT32(pkt+7, f->fid);
1272 ceb04770 2003-12-09 devnull PBIT32(pkt+11, f->newfid);
1273 ceb04770 2003-12-09 devnull for(i=0; i<f->nwname; i++)
1274 ceb04770 2003-12-09 devnull restring(pkt, n, f->wname[i]);
1275 ceb04770 2003-12-09 devnull break;
1276 ceb04770 2003-12-09 devnull case Tcreate:
1277 ceb04770 2003-12-09 devnull restring(pkt, n, f->name);
1278 ceb04770 2003-12-09 devnull /* fall through */
1279 ceb04770 2003-12-09 devnull case Topen:
1280 ceb04770 2003-12-09 devnull case Tread:
1281 ceb04770 2003-12-09 devnull case Twrite:
1282 ceb04770 2003-12-09 devnull case Tclunk:
1283 ceb04770 2003-12-09 devnull case Tremove:
1284 ceb04770 2003-12-09 devnull case Tstat:
1285 ceb04770 2003-12-09 devnull case Twstat:
1286 ceb04770 2003-12-09 devnull PBIT32(pkt+7, f->fid);
1287 ceb04770 2003-12-09 devnull break;
1288 ceb04770 2003-12-09 devnull case Rerror:
1289 ceb04770 2003-12-09 devnull restring(pkt, n, f->ename);
1290 5a8e63b2 2004-02-29 devnull break;
1291 5a8e63b2 2004-02-29 devnull }
1292 32f69c36 2003-12-11 devnull }
1293 32f69c36 2003-12-11 devnull
1294 32f69c36 2003-12-11 devnull static long
1295 ceb04770 2003-12-09 devnull _iolisten(va_list *arg)
1296 ceb04770 2003-12-09 devnull {
1297 ceb04770 2003-12-09 devnull char *a, *b;
1298 ceb04770 2003-12-09 devnull
1299 ceb04770 2003-12-09 devnull a = va_arg(*arg, char*);
1300 ceb04770 2003-12-09 devnull b = va_arg(*arg, char*);
1301 ceb04770 2003-12-09 devnull return listen(a, b);
1302 ceb04770 2003-12-09 devnull }
1303 ceb04770 2003-12-09 devnull
1304 ceb04770 2003-12-09 devnull int
1305 ceb04770 2003-12-09 devnull iolisten(Ioproc *io, char *a, char *b)
1306 ceb04770 2003-12-09 devnull {
1307 ceb04770 2003-12-09 devnull return iocall(io, _iolisten, a, b);
1308 ceb04770 2003-12-09 devnull }
1309 ceb04770 2003-12-09 devnull
1310 ceb04770 2003-12-09 devnull static long
1311 ceb04770 2003-12-09 devnull _ioaccept(va_list *arg)
1312 ceb04770 2003-12-09 devnull {
1313 ceb04770 2003-12-09 devnull int fd;
1314 ceb04770 2003-12-09 devnull char *dir;
1315 ceb04770 2003-12-09 devnull
1316 ceb04770 2003-12-09 devnull fd = va_arg(*arg, int);
1317 ceb04770 2003-12-09 devnull dir = va_arg(*arg, char*);
1318 ceb04770 2003-12-09 devnull return accept(fd, dir);
1319 ceb04770 2003-12-09 devnull }
1320 ceb04770 2003-12-09 devnull
1321 ceb04770 2003-12-09 devnull int
1322 ceb04770 2003-12-09 devnull ioaccept(Ioproc *io, int fd, char *dir)
1323 ceb04770 2003-12-09 devnull {
1324 ceb04770 2003-12-09 devnull return iocall(io, _ioaccept, fd, dir);
1325 ceb04770 2003-12-09 devnull }
1326 e2a1725d 2005-01-04 devnull
1327 e2a1725d 2005-01-04 devnull int
1328 e2a1725d 2005-01-04 devnull timefmt(Fmt *fmt)
1329 e2a1725d 2005-01-04 devnull {
1330 e2a1725d 2005-01-04 devnull static char *mon[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1331 e2a1725d 2005-01-04 devnull "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
1332 bb426e77 2005-01-06 devnull vlong ns;
1333 e2a1725d 2005-01-04 devnull Tm tm;
1334 bb426e77 2005-01-06 devnull ns = nsec();
1335 e2a1725d 2005-01-04 devnull tm = *localtime(time(0));
1336 bb426e77 2005-01-06 devnull return fmtprint(fmt, "%s %2d %02d:%02d:%02d.%03d",
1337 bb426e77 2005-01-06 devnull mon[tm.mon], tm.mday, tm.hour, tm.min, tm.sec,
1338 bb426e77 2005-01-06 devnull (int)(ns%1000000000)/1000000);
1339 e2a1725d 2005-01-04 devnull }