|
|
1.1 root 1: /*
2: * message processor-- written data turns into control, read control
3: * turns into data
4: * rmesg is just the opposite
5: */
6:
7: #include "../h/param.h"
8: #include "../h/systm.h"
9: #include "../h/stream.h"
10: #include "../h/conf.h"
11: #include "mesg.h"
12:
13: #define MS_OPEN 01
14: #define MS_DEL 02
15:
16: #define MS_STOP 010
17: #define MS_IOCTL 020
18:
19: struct block *msgcollect();
20: int msctodput(), msctodsrv(), msdtocput(), msdtocsrv(), msgopen(), rmsgopen(),
21: msgclose(), rmsgclose();
22: struct qinit msgrinit = { msctodput, msctodsrv, msgopen, msgclose, 128, 65 };
23: struct qinit msgwinit = { msdtocput, msdtocsrv, msgopen, msgclose, 128, 65 };
24: struct streamtab msginfo = { &msgrinit, &msgwinit };
25:
26: struct qinit rmsgrinit = { msdtocput, msdtocsrv, rmsgopen, rmsgclose, 128, 65 };
27: struct qinit rmsgwinit = { msctodput, msctodsrv, rmsgopen, rmsgclose, 128, 65 };
28: struct streamtab rmsginfo = { &rmsgrinit, &rmsgwinit };
29:
30: struct imesg {
31: char type;
32: char msflag;
33: short size;
34: } mesg[NMESG];
35:
36: msgopen(q, dev)
37: register struct queue *q;
38: {
39: register struct imesg *mp;
40:
41: if (WR(q)->ptr)
42: return(1);
43: for (mp = mesg; mp->msflag&MS_OPEN; mp++)
44: if (mp >= &mesg[NMESG-1])
45: return(0);
46: mp->msflag = MS_OPEN;
47: mp->size = 0;
48: WR(q)->ptr = (caddr_t)mp;
49: WR(q)->flag |= QNOENB;
50: q->flag |= QDELIM;
51: return(1);
52: }
53:
54: rmsgopen(q, dev)
55: register struct queue *q;
56: {
57: register struct imesg *mp;
58:
59: if (q->ptr)
60: return(1);
61: for (mp = mesg; mp->msflag&MS_OPEN; mp++)
62: if (mp >= &mesg[NMESG-1])
63: return(0);
64: mp->msflag = MS_OPEN;
65: mp->size = 0;
66: q->ptr = (caddr_t)mp;
67: q->flag |= QNOENB;
68: q->flag |= QDELIM;
69: return(1);
70: }
71:
72: msgclose(q)
73: register struct queue *q;
74: {
75: if (WR(q)->ptr)
76: ((struct imesg *)WR(q)->ptr)->msflag = 0;
77: }
78:
79: rmsgclose(q)
80: register struct queue *q;
81: {
82: if (q->ptr)
83: ((struct imesg *)q->ptr)->msflag = 0;
84: }
85:
86: msctodput(q, bp)
87: register struct queue *q;
88: register struct block *bp;
89: {
90: register struct imesg *mp = (struct imesg *)(OTHERQ(q)->ptr);
91: register struct queue *bq = backq(q);
92:
93: /* propagate changes in delimiter status */
94: if (mp->msflag&MS_DEL) {
95: if ((bq->flag&QDELIM) == 0) {
96: mp->msflag &= ~MS_DEL;
97: putctl(q, M_NDEL);
98: }
99: } else {
100: if (bq->flag&QDELIM) {
101: mp->msflag |= MS_DEL;
102: putctl(q, M_YDEL);
103: }
104: }
105: if (bp->type==M_STOP) {
106: freeb(bp);
107: mp->msflag |= MS_STOP;
108: return;
109: }
110: if (bp->type>=QPCTL) { /* including M_START */
111: if (bp->type==M_START)
112: freeb(bp);
113: else {
114: /* ioctl transparency */
115: if (mp->msflag & MS_IOCTL
116: && (bp->type==M_IOCACK || bp->type==M_IOCNAK)) {
117: (*q->next->qinfo->putp)(q->next, bp);
118: mp->msflag &=~ MS_IOCTL;
119: return;
120: }
121: putq(q, bp);
122: }
123: mp->msflag &=~ MS_STOP;
124: qenable(q);
125: return;
126: }
127: putq(q, bp);
128: /* enable if we don't have delimiters */
129: if ((bq->flag&QDELIM) == 0)
130: qenable(q);
131: return;
132: }
133:
134: msctodsrv(q)
135: register struct queue *q;
136: {
137: register struct block *bp, *hbp;
138: register struct imesg *mp = (struct imesg *)OTHERQ(q)->ptr;
139: register type;
140: register size;
141:
142: for (;;) {
143: if (q->next->flag & QFULL || mp->msflag & MS_STOP)
144: return;
145: if ((bp = getq(q)) == NULL)
146: return;
147: if ((hbp = allocb(MSGHLEN)) == NULL) {
148: putbq(q, bp);
149: return;
150: }
151: ((struct mesg *)(hbp->wptr))->magic = MSGMAGIC;
152: ((struct mesg *)(hbp->wptr))->type = type = bp->type;
153: size = bp->wptr - bp->rptr;
154: ((struct mesg *)(hbp->wptr))->losize = size;
155: ((struct mesg *)(hbp->wptr))->hisize = size>>8;
156: hbp->wptr += MSGHLEN;
157: (*q->next->qinfo->putp)(q->next, hbp);
158: bp->type = M_DATA;
159: if (bp->wptr > bp->rptr)
160: (*q->next->qinfo->putp)(q->next, bp);
161: else
162: freeb(bp);
163: putctl(q->next, M_DELIM);
164: if (type == M_HANGUP)
165: putctl(q->next, M_HANGUP);
166: }
167: }
168:
169: msdtocput(q, bp)
170: register struct queue *q;
171: register struct block *bp;
172: {
173: switch (bp->type) {
174:
175: default:
176: freeb(bp);
177: return;
178:
179: case M_FLUSH:
180: flushq(OTHERQ(q), 1);
181: case M_IOCACK:
182: case M_IOCNAK:
183: case M_HANGUP:
184: (*q->next->qinfo->putp)(q->next, bp);
185: return;
186:
187: case M_DATA:
188: case M_IOCTL:
189: putq(q, bp);
190: qenable(q);
191: return;
192: }
193: }
194:
195: msdtocsrv(q)
196: register struct queue *q;
197: {
198: register struct block *bp;
199: register struct imesg *mp = (struct imesg *)q->ptr;
200:
201: for (;;) {
202: if (q->next->flag & QFULL)
203: return;
204: if (mp->size == 0) { /* Start of message */
205: bp = msgcollect(q, MSGHLEN, 0, 1);
206: if (bp == NULL)
207: return;
208: mp->size = ((struct mesg *)bp->rptr)->losize;
209: mp->size += ((struct mesg *)bp->rptr)->hisize<<8;
210: mp->type = ((struct mesg *)bp->rptr)->type;
211: /* magic ok; was checked in msgcollect */
212: if (mp->size < 0)
213: mp->size = 0;
214: if (mp->size==0) {
215: bp->type = mp->type;
216: bp->rptr = bp->wptr;
217: if (bp->type==M_YDEL)
218: q->flag |= QDELIM;
219: else if (bp->type==M_NDEL)
220: q->flag &= ~QDELIM;
221: (*q->next->qinfo->putp)(q->next, bp);
222: continue;
223: }
224: freeb(bp);
225: }
226: bp = msgcollect(q, mp->size, mp->type == M_DATA, 0);
227: if (bp == NULL)
228: return;
229: bp->type = mp->type;
230: mp->size -= bp->wptr - bp->rptr;
231: (*q->next->qinfo->putp)(q->next, bp);
232: }
233: }
234:
235: long ms_badmag;
236:
237: struct block *
238: msgcollect(q, size, isdata, findmag)
239: register struct queue *q;
240: {
241: register struct block *nbp, *bp;
242: register ninb;
243: register struct imesg *mp = (struct imesg *)q->ptr;
244:
245: if (findmag == 0) {
246: if ((bp = getq(q)) == NULL)
247: return (NULL);
248: }
249: else {
250: while ((bp = getq(q)) != NULL) {
251: if (bp->type != M_DATA) {
252: /* prevent the ack from being turned to data */
253: if (bp->type==M_IOCTL)
254: mp->msflag |= MS_IOCTL;
255: (*q->next->qinfo->putp)(q->next, bp);
256: continue;
257: }
258: while (bp->rptr < bp->wptr-1) {
259: if (bp->rptr[1] == MSGMAGIC)
260: goto gotmagic;
261: bp->rptr++;
262: ms_badmag++;
263: }
264: freeb(bp);
265: }
266: if (bp == NULL)
267: return (NULL);
268: }
269: gotmagic:
270: nbp = allocb(size);
271: if (nbp == NULL) {
272: putbq(q, bp);
273: return(NULL);
274: }
275: if (size > nbp->lim - nbp->wptr)
276: size = nbp->lim - nbp->wptr;
277: while (size) {
278: if (bp->type != M_DATA) {
279: /* prevent the ack from being turned to data */
280: if (bp->type==M_IOCTL)
281: mp->msflag |= MS_IOCTL;
282: (*q->next->qinfo->putp)(q->next, bp);
283: if ((bp = getq(q)) == NULL)
284: break;
285: continue;
286: }
287: ninb = bp->wptr - bp->rptr;
288: if (ninb > size) {
289: bcopy((caddr_t)bp->rptr, (caddr_t)nbp->wptr, size);
290: nbp->wptr += size;
291: bp->rptr += size;
292: size = 0;
293: putbq(q, bp);
294: break;
295: }
296: bcopy((caddr_t)bp->rptr, (caddr_t)nbp->wptr, ninb);
297: size -= ninb;
298: nbp->wptr += ninb;
299: freeb(bp);
300: if (size == 0)
301: break;
302: if ((bp = getq(q)) == NULL)
303: break;
304: }
305: if (nbp->rptr >= nbp->wptr) {
306: freeb(nbp);
307: return(NULL);
308: }
309: if (size==0 || isdata)
310: return(nbp);
311: putbq(q, nbp);
312: return(NULL);
313: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.