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