|
|
1.1 ! root 1: #include "u.h" ! 2: #include "../port/lib.h" ! 3: #include "mem.h" ! 4: #include "dat.h" ! 5: #include "fns.h" ! 6: #include "../port/error.h" ! 7: ! 8: enum ! 9: { ! 10: Twritehdr = 16, /* Min bytes for Twrite */ ! 11: Rreadhdr = 8, /* Min bytes for Rread */ ! 12: Twritecnt = 13, /* Offset in byte stream of write count */ ! 13: Rreadcnt = 5, /* Offset for Readcnt */ ! 14: }; ! 15: ! 16: static void fcalliput(Queue*, Block*); ! 17: static void fcalloput(Queue*, Block*); ! 18: static void fcallopen(Queue*, Stream*); ! 19: static void fcallclose(Queue*); ! 20: static void fcallreset(void); ! 21: Qinfo fcallinfo = { fcalliput, fcalloput, fcallopen, fcallclose, "fcall", fcallreset }; ! 22: ! 23: static uchar msglen[256] = ! 24: { ! 25: [Tnop] 3, ! 26: [Rnop] 3, ! 27: [Tsession] 3+CHALLEN, ! 28: [Rsession] 3+NAMELEN+DOMLEN+CHALLEN, ! 29: [Terror] 0, ! 30: [Rerror] 67, ! 31: [Tflush] 5, ! 32: [Rflush] 3, ! 33: [Tattach] 5+2*NAMELEN+TICKETLEN+AUTHENTLEN, ! 34: [Rattach] 13+AUTHENTLEN, ! 35: [Tclone] 7, ! 36: [Rclone] 5, ! 37: [Twalk] 33, ! 38: [Rwalk] 13, ! 39: [Topen] 6, ! 40: [Ropen] 13, ! 41: [Tcreate] 38, ! 42: [Rcreate] 13, ! 43: [Tread] 15, ! 44: [Rread] 8, ! 45: [Twrite] 16, ! 46: [Rwrite] 7, ! 47: [Tclunk] 5, ! 48: [Rclunk] 5, ! 49: [Tremove] 5, ! 50: [Rremove] 5, ! 51: [Tstat] 5, ! 52: [Rstat] 121, ! 53: [Twstat] 121, ! 54: [Rwstat] 5, ! 55: [Tclwalk] 35, ! 56: [Rclwalk] 13, ! 57: }; ! 58: ! 59: void ! 60: stfcalllink(void) ! 61: { ! 62: newqinfo(&fcallinfo); ! 63: } ! 64: ! 65: static void ! 66: fcallreset(void) ! 67: { ! 68: } ! 69: ! 70: static void ! 71: fcallopen(Queue *q, Stream *s) ! 72: { ! 73: USED(q, s); ! 74: } ! 75: ! 76: static void ! 77: fcallclose(Queue * q) ! 78: { ! 79: USED(q); ! 80: } ! 81: ! 82: void ! 83: fcalloput(Queue *q, Block *bp) ! 84: { ! 85: PUTNEXT(q, bp); ! 86: } ! 87: ! 88: void ! 89: upstream(Queue *q, ulong len) ! 90: { ! 91: Block *bl, **tail, *bp; ! 92: ulong l; ! 93: ! 94: tail = &bl; ! 95: while(len) { ! 96: l = BLEN(q->first); ! 97: if(l > len) ! 98: break; ! 99: bp = getq(q); /* Consume all of block */ ! 100: *tail = bp; ! 101: tail = &bp->next; ! 102: len -= l; ! 103: } ! 104: if(len) { /* Consume partial block */ ! 105: lock(q); ! 106: *tail = copyb(q->first, len); ! 107: q->first->rptr += len; ! 108: q->len -= len; ! 109: unlock(q); ! 110: } ! 111: for(bp = bl; bp->next; bp = bp->next) ! 112: ; ! 113: bp->flags |= S_DELIM; ! 114: PUTNEXT(q, bl); ! 115: } ! 116: ! 117: static void ! 118: fcalliput(Queue *q, Block *bp) ! 119: { ! 120: ulong len, need, off; ! 121: ! 122: if(bp->type != M_DATA) { ! 123: PUTNEXT(q, bp); ! 124: return; ! 125: } ! 126: if(BLEN(bp) == 0) { ! 127: freeb(bp); ! 128: return; ! 129: } ! 130: ! 131: /* Stash the data */ ! 132: bp->flags &= ~S_DELIM; ! 133: putq(q, bp); ! 134: ! 135: for(;;) { ! 136: bp = q->first; ! 137: if(bp == 0) ! 138: return; ! 139: switch(bp->rptr[0]) { /* This is the type */ ! 140: default: ! 141: len = msglen[bp->rptr[0]]; ! 142: if(len == 0){ ! 143: bp = allocb(0); ! 144: bp->type = M_HANGUP; ! 145: PUTNEXT(q, bp); ! 146: return; ! 147: } ! 148: if(q->len < len) ! 149: return; ! 150: ! 151: upstream(q, len); ! 152: continue; ! 153: ! 154: case Twrite: /* Fmt: TGGFFOOOOOOOOCC */ ! 155: len = Twritehdr; /* T = type, G = tag, F = fid */ ! 156: off = Twritecnt; /* O = offset, C = count */ ! 157: break; ! 158: ! 159: case Rread: /* Fmt: TGGFFCC */ ! 160: len = Rreadhdr; ! 161: off = Rreadcnt; ! 162: break; ! 163: } ! 164: ! 165: if(q->len < len) ! 166: return; ! 167: ! 168: /* ! 169: * the lock here is wrong. it should be a qlock since ! 170: * the pullup may block. not worth fixing. ! 171: */ ! 172: lock(q); ! 173: bp = q->first = pullup(q->first, len); ! 174: if(bp == 0) ! 175: q->len = 0; ! 176: unlock(q); ! 177: need = len+bp->rptr[off]+(bp->rptr[off+1]<<8); ! 178: if(q->len < need) ! 179: return; ! 180: ! 181: upstream(q, need); ! 182: } ! 183: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.