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