1*9a747e4fSDavid du Colombier #include "all.h" 2*9a747e4fSDavid du Colombier #include "/sys/include/fcall.h" 3*9a747e4fSDavid du Colombier 4*9a747e4fSDavid du Colombier static int 5*9a747e4fSDavid du Colombier readmsg(Chan *c, void *abuf, int n, int *ninep) 6*9a747e4fSDavid du Colombier { 7*9a747e4fSDavid du Colombier int fd, len; 8*9a747e4fSDavid du Colombier uchar *buf; 9*9a747e4fSDavid du Colombier 10*9a747e4fSDavid du Colombier buf = abuf; 11*9a747e4fSDavid du Colombier fd = c->chan; 12*9a747e4fSDavid du Colombier qlock(&c->rlock); 13*9a747e4fSDavid du Colombier if(readn(fd, buf, 3) != 3){ 14*9a747e4fSDavid du Colombier qunlock(&c->rlock); 15*9a747e4fSDavid du Colombier print("readn(3) fails: %r\n"); 16*9a747e4fSDavid du Colombier return -1; 17*9a747e4fSDavid du Colombier } 18*9a747e4fSDavid du Colombier if((50 <= buf[0] && buf[0] <= 87 && (buf[0]&1)==0 && GBIT16(buf+1) == 0xFFFF) 19*9a747e4fSDavid du Colombier || buf[0] == 86 /* Tattach */){ 20*9a747e4fSDavid du Colombier *ninep = 1; 21*9a747e4fSDavid du Colombier /* assume message boundaries */ 22*9a747e4fSDavid du Colombier n = read(fd, buf+3, n-3); 23*9a747e4fSDavid du Colombier if(n < 0){ 24*9a747e4fSDavid du Colombier qunlock(&c->rlock); 25*9a747e4fSDavid du Colombier return -1; 26*9a747e4fSDavid du Colombier } 27*9a747e4fSDavid du Colombier return n+3; 28*9a747e4fSDavid du Colombier } 29*9a747e4fSDavid du Colombier 30*9a747e4fSDavid du Colombier *ninep = 2; 31*9a747e4fSDavid du Colombier if(read(fd, buf+3, 1) != 1){ 32*9a747e4fSDavid du Colombier qunlock(&c->rlock); 33*9a747e4fSDavid du Colombier print("read(1) fails: %r\n"); 34*9a747e4fSDavid du Colombier return -1; 35*9a747e4fSDavid du Colombier } 36*9a747e4fSDavid du Colombier len = GBIT32(buf); 37*9a747e4fSDavid du Colombier if(len > n){ 38*9a747e4fSDavid du Colombier print("msg too large\n"); 39*9a747e4fSDavid du Colombier qunlock(&c->rlock); 40*9a747e4fSDavid du Colombier return -1; 41*9a747e4fSDavid du Colombier } 42*9a747e4fSDavid du Colombier if(readn(fd, buf+4, len-4) != len-4){ 43*9a747e4fSDavid du Colombier print("readn(%d) fails: %r\n", len-4); 44*9a747e4fSDavid du Colombier qunlock(&c->rlock); 45*9a747e4fSDavid du Colombier return -1; 46*9a747e4fSDavid du Colombier } 47*9a747e4fSDavid du Colombier qunlock(&c->rlock); 48*9a747e4fSDavid du Colombier return len; 49*9a747e4fSDavid du Colombier } 50*9a747e4fSDavid du Colombier 51*9a747e4fSDavid du Colombier void 52*9a747e4fSDavid du Colombier startserveproc(void (*f)(Chan*, uchar*, int), char *name, Chan *c, uchar *b, int nb) 53*9a747e4fSDavid du Colombier { 54*9a747e4fSDavid du Colombier switch(rfork(RFMEM|RFFDG|RFPROC)){ 55*9a747e4fSDavid du Colombier case -1: 56*9a747e4fSDavid du Colombier panic("can't fork"); 57*9a747e4fSDavid du Colombier case 0: 58*9a747e4fSDavid du Colombier break; 59*9a747e4fSDavid du Colombier default: 60*9a747e4fSDavid du Colombier return; 61*9a747e4fSDavid du Colombier } 62*9a747e4fSDavid du Colombier procname = name; 63*9a747e4fSDavid du Colombier f(c, b, nb); 64*9a747e4fSDavid du Colombier _exits(nil); 65*9a747e4fSDavid du Colombier } 66*9a747e4fSDavid du Colombier 67*9a747e4fSDavid du Colombier void 68*9a747e4fSDavid du Colombier serve(Chan *chan) 69*9a747e4fSDavid du Colombier { 70*9a747e4fSDavid du Colombier int i, nin, p9; 71*9a747e4fSDavid du Colombier uchar inbuf[1024]; 72*9a747e4fSDavid du Colombier void (*s)(Chan*, uchar*, int); 73*9a747e4fSDavid du Colombier 74*9a747e4fSDavid du Colombier p9 = 0; 75*9a747e4fSDavid du Colombier if((nin = readmsg(chan, inbuf, sizeof inbuf, &p9)) < 0) 76*9a747e4fSDavid du Colombier return; 77*9a747e4fSDavid du Colombier 78*9a747e4fSDavid du Colombier switch(p9){ 79*9a747e4fSDavid du Colombier default: 80*9a747e4fSDavid du Colombier print("unknown 9P type\n"); 81*9a747e4fSDavid du Colombier return; 82*9a747e4fSDavid du Colombier case 1: 83*9a747e4fSDavid du Colombier s = serve9p1; 84*9a747e4fSDavid du Colombier break; 85*9a747e4fSDavid du Colombier case 2: 86*9a747e4fSDavid du Colombier s = serve9p2; 87*9a747e4fSDavid du Colombier break; 88*9a747e4fSDavid du Colombier } 89*9a747e4fSDavid du Colombier 90*9a747e4fSDavid du Colombier for(i=1; i<conf.nserve; i++) 91*9a747e4fSDavid du Colombier startserveproc(s, "srv", chan, nil, 0); 92*9a747e4fSDavid du Colombier (*s)(chan, inbuf, nin); 93*9a747e4fSDavid du Colombier } 94*9a747e4fSDavid du Colombier 95