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