## diffname boot/fcall.c 2001/0214 ## diff -e /dev/null /n/emeliedump/2001/0214/sys/src/9/boot/fcall.c 0a #include #include #include #include #include #include "boot.h" /* * reassemble 9P messages for stream based protocols * interposed between devmnt and the network by srv for tcp connections * fcall expects devmnt on fd0, network fd1 */ static uchar msglen[256] = { [Tnop] 3, [Rnop] 3, [Tsession] 3+CHALLEN, [Rsession] 3+NAMELEN+DOMLEN+CHALLEN, [Terror] 0, [Rerror] 67, [Tflush] 5, [Rflush] 3, [Tattach] 5+2*NAMELEN+TICKETLEN+AUTHENTLEN, [Rattach] 13+AUTHENTLEN, [Tclone] 7, [Rclone] 5, [Twalk] 33, [Rwalk] 13, [Topen] 6, [Ropen] 13, [Tcreate] 38, [Rcreate] 13, [Tread] 15, [Rread] 8, [Twrite] 16, [Rwrite] 7, [Tclunk] 5, [Rclunk] 5, [Tremove] 5, [Rremove] 5, [Tstat] 5, [Rstat] 121, [Twstat] 121, [Rwstat] 5, [Tclwalk] 35, [Rclwalk] 13, }; enum { Twritehdr = 16, /* Min bytes for Twrite */ Rreadhdr = 8, /* Min bytes for Rread */ Twritecnt = 13, /* Offset in byte stream of write count */ Rreadcnt = 5, /* Offset for Readcnt */ }; void echo(int f, int t) { int n; char buf[MAXRPC]; for(;;) { n = read9p(f, buf, MAXRPC); if(n <= 0) break; if(write(t, buf, n) < n) break; } } int mntrpclen(uchar *d, int n) { uchar t; int len, off; if(n < 1) return 0; t = d[0]; switch(t) { /* This is the type */ default: len = msglen[t]; if(len == 0) /* Illegal type so consume */ return n; if(n < len) return 0; return len; case Twrite: /* Fmt: TGGFFOOOOOOOOCC */ len = Twritehdr; /* T = type, G = tag, F = fid */ off = Twritecnt; /* O = offset, C = count */ break; case Rread: /* Fmt: TGGFFCC */ len = Rreadhdr; off = Rreadcnt; break; } if(n < off+2) return 0; len += d[off]|(d[off+1]<<8); if(n < len) return 0; return len; } int pushfcall(int fd) { int r, n, l, pfd[2]; uchar *p, buf[MAXRPC]; if(pipe(pfd) < 0){ fprint(2, "pipe: %r\n"); exits("pipe"); } /* Downstream is just a copy process */ switch(rfork(RFPROC|RFFDG|RFMEM)){ case 0: close(pfd[1]); echo(pfd[0], fd); fprint(2, "echo finished\n"); exits("echo done"); case -1: fprint(2, "fcall fork failed: %r\n"); exits("fork"); } switch(rfork(RFPROC|RFFDG|RFMEM)){ default: close(pfd[0]); return pfd[1]; case 0: close(pfd[1]); break; case -1: fprint(2, "fcall fork failed: %r\n"); exits("fork"); } /* Dispatch only full RPC's to the mount driver */ l = MAXRPC; p = buf; for(;;) { n = read(fd, p, l); if(n < 0) break; p += n; l -= n; for(;;) { r = mntrpclen(buf, p - buf); if(r == 0) break; if(write(pfd[0], buf, r) < 0) break; n = (p - buf) - r; memmove(buf, buf+r, n); p = buf+n; l = MAXRPC - n; } } abort(); return 0; } . ## diffname boot/fcall.c 2001/0527 # deleted ## diff -e /n/emeliedump/2001/0214/sys/src/9/boot/fcall.c /n/emeliedump/2001/0527/sys/src/9/boot/fcall.c 1,171d