Blame


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