|
|
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.