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