123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
- #include <u.h>
- #include <libc.h>
- #include <auth.h>
- #include <fcall.h>
- #include "9p1.h"
- #define MAXFDATA (8*1024)
- #define MAXRPC (MAXFDATA+160)
- /*
- * 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
- */
- uchar msglen[256] =
- {
- [Tnop9p1] 3,
- [Rnop9p1] 3,
- [Tsession9p1] 3+CHALLEN,
- [Rsession9p1] 3+NAMEREC+DOMLEN+CHALLEN,
- [Terror9p1] 0,
- [Rerror9p1] 67,
- [Tflush9p1] 5,
- [Rflush9p1] 3,
- [Tattach9p1] 5+2*NAMEREC+TICKETLEN+AUTHENTLEN,
- [Rattach9p1] 13+AUTHENTLEN,
- [Tclone9p1] 7,
- [Rclone9p1] 5,
- [Twalk9p1] 33,
- [Rwalk9p1] 13,
- [Topen9p1] 6,
- [Ropen9p1] 13,
- [Tcreate9p1] 38,
- [Rcreate9p1] 13,
- [Tread9p1] 15,
- [Rread9p1] 8,
- [Twrite9p1] 16,
- [Rwrite9p1] 7,
- [Tclunk9p1] 5,
- [Rclunk9p1] 5,
- [Tremove9p1] 5,
- [Rremove9p1] 5,
- [Tstat9p1] 5,
- [Rstat9p1] 121,
- [Twstat9p1] 121,
- [Rwstat9p1] 5,
- [Tclwalk9p1] 35,
- [Rclwalk9p1] 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 */
- };
- 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 Twrite9p1: /* Fmt: TGGFFOOOOOOOOCC */
- len = Twritehdr; /* T = type, G = tag, F = fid */
- off = Twritecnt; /* O = offset, C = count */
- break;
- case Rread9p1: /* 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
- fcall(int fd)
- {
- int i, r, n, l;
- uchar *p, *buf;
- int pipefd[2];
- if(pipe(pipefd) < 0)
- fatal("fcall pipe: %r");
- buf = malloc(MAXRPC);
- if(buf == nil)
- fatal("fcall malloc");
- switch(rfork(RFPROC|RFMEM|RFFDG|RFCNAMEG)){
- default:
- return pipefd[0]; /* parent returns fd */
- case 0:
- break; /* child builds buffers */
- case -1:
- fatal("fcall fork: %r");
- }
- /* close file descriptors */
- for(i=0; i<20; i++)
- if(i!=fd && i!=pipefd[1])
- close(i);
- 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(pipefd[1], buf, r) < 0)
- break;
- n = (p - buf) - r;
- memmove(buf, buf+r, n);
- p = buf+n;
- l = MAXRPC - n;
- }
- }
- close(pipefd[1]);
- fatal(nil);
- return -1;
- }
|