|
|
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 01000
14: #define MS_DEL 02000
15: #define MS_MASK 0377
16:
17: struct block *msgcollect();
18: int msctodput(), msctodsrv(), msdtocput(), msdtocsrv(), msgopen(), rmsgopen(),
19: msgclose(), rmsgclose();
20: struct qinit msgrinit = { msctodput, msctodsrv, msgopen, msgclose, 128, 65 };
21: struct qinit msgwinit = { msdtocput, msdtocsrv, msgopen, msgclose, 128, 65 };
22: struct streamtab msginfo = { &msgrinit, &msgwinit };
23:
24: struct qinit rmsgrinit = { msdtocput, msdtocsrv, rmsgopen, rmsgclose, 128, 65 };
25: struct qinit rmsgwinit = { msctodput, msctodsrv, rmsgopen, rmsgclose, 128, 65 };
26: struct streamtab rmsginfo = { &rmsgrinit, &rmsgwinit };
27:
28: struct mesg {
29: short type;
30: short size;
31: } mesg[NMESG];
32:
33: msgopen(q, dev)
34: register struct queue *q;
35: {
36: register struct mesg *mp;
37:
38: if (WR(q)->ptr)
39: return(1);
40: for (mp = mesg; mp->type&MS_OPEN; mp++)
41: if (mp >= &mesg[NMESG-1])
42: return(0);
43: mp->type = MS_OPEN;
44: mp->size = 0;
45: q->ptr = (caddr_t)0; /* "stopped" flag */
46: WR(q)->ptr = (caddr_t)mp;
47: WR(q)->flag |= QNOENB;
48: q->flag |= QDELIM;
49: return(1);
50: }
51:
52: rmsgopen(q, dev)
53: register struct queue *q;
54: {
55: register struct mesg *mp;
56:
57: if (q->ptr)
58: return(1);
59: for (mp = mesg; mp->type&MS_OPEN; mp++)
60: if (mp >= &mesg[NMESG-1])
61: return(0);
62: mp->type = MS_OPEN;
63: mp->size = 0;
64: WR(q)->ptr = (caddr_t)0; /* "stopped" flag */
65: q->ptr = (caddr_t)mp;
66: q->flag |= QNOENB;
67: q->flag |= QDELIM;
68: return(1);
69: }
70:
71: msgclose(q)
72: register struct queue *q;
73: {
74: if (WR(q)->ptr)
75: ((struct mesg*)WR(q)->ptr)->type = 0;
76: }
77:
78: rmsgclose(q)
79: register struct queue *q;
80: {
81: if (q->ptr)
82: ((struct mesg*)q->ptr)->type = 0;
83: }
84:
85: msctodput(q, bp)
86: register struct queue *q;
87: register struct block *bp;
88: {
89: register struct mesg *mp = (struct mesg *)(OTHERQ(q)->ptr);
90: register struct queue *bq = backq(q);
91:
92: /* propagate changes in delimiter status */
93: if (mp->type&MS_DEL) {
94: if ((bq->flag&QDELIM) == 0) {
95: mp->type &= ~MS_DEL;
96: putctl(q, M_NDEL);
97: }
98: } else {
99: if (bq->flag&QDELIM) {
100: mp->type |= MS_DEL;
101: putctl(q, M_YDEL);
102: }
103: }
104: if (bp->type==M_STOP) {
105: freeb(bp);
106: q->ptr = (caddr_t)1; /* mark stopped */
107: return;
108: }
109: if (bp->type>=QPCTL) { /* including M_START */
110: if (bp->type==M_START)
111: freeb(bp);
112: else {
113: /* ioctl transparency */
114: if (q->ptr == (caddr_t)2
115: && (bp->type==M_IOCACK || bp->type==M_IOCNAK)) {
116: (*q->next->qinfo->putp)(q->next, bp);
117: q->ptr = (caddr_t)0;
118: return;
119: }
120: putq(q, bp);
121: }
122: q->ptr = (caddr_t)0; /* mark unstopped */
123: qenable(q);
124: return;
125: }
126: putq(q, bp);
127: return;
128: }
129:
130: msctodsrv(q)
131: register struct queue *q;
132: {
133: register struct block *bp, *hbp;
134: register type;
135:
136: for (;;) {
137: if (q->next->flag & QFULL || q->ptr==(caddr_t)1)
138: return;
139: if ((bp = getq(q)) == NULL)
140: return;
141: if ((hbp = allocb(sizeof(struct mesg))) == NULL) {
142: putbq(q, bp);
143: return;
144: }
145: ((struct mesg *)(hbp->wptr))->type = type = bp->type;
146: ((struct mesg *)(hbp->wptr))->size = bp->wptr - bp->rptr;
147: hbp->wptr += sizeof(struct mesg);
148: (*q->next->qinfo->putp)(q->next, hbp);
149: bp->type = M_DATA;
150: if (bp->wptr > bp->rptr)
151: (*q->next->qinfo->putp)(q->next, bp);
152: else
153: freeb(bp);
154: putctl(q->next, M_DELIM);
155: if (type == M_HANGUP)
156: putctl(q->next, M_HANGUP);
157: }
158: }
159:
160: msdtocput(q, bp)
161: register struct queue *q;
162: register struct block *bp;
163: {
164: switch (bp->type) {
165:
166: default:
167: freeb(bp);
168: return;
169:
170: case M_FLUSH:
171: flushq(OTHERQ(q), 1);
172: case M_IOCACK:
173: case M_IOCNAK:
174: case M_HANGUP:
175: (*q->next->qinfo->putp)(q->next, bp);
176: return;
177:
178: case M_DATA:
179: case M_IOCTL:
180: putq(q, bp);
181: qenable(q);
182: return;
183: }
184: }
185:
186: msdtocsrv(q)
187: register struct queue *q;
188: {
189: register struct block *bp;
190: register struct mesg *mp = (struct mesg *)q->ptr;
191:
192: for (;;) {
193: if (q->next->flag & QFULL)
194: return;
195: if (mp->size == 0) { /* Start of message */
196: bp = msgcollect(q, sizeof(struct mesg), 0);
197: if (bp == NULL)
198: return;
199: mp->size = ((struct mesg *)bp->rptr)->size;
200: mp->type &= ~MS_MASK;
201: mp->type |= ((struct mesg *)bp->rptr)->type &MS_MASK;
202: if (mp->size < 0) {
203: mp->size = 0;
204: printf("size<0 in msdtocsrv\n");
205: }
206: if (mp->size==0) {
207: bp->type = mp->type;
208: bp->rptr = bp->wptr;
209: if (bp->type==M_YDEL)
210: q->flag |= QDELIM;
211: else if (bp->type==M_NDEL)
212: q->flag &= ~QDELIM;
213: (*q->next->qinfo->putp)(q->next, bp);
214: continue;
215: }
216: freeb(bp);
217: }
218: bp = msgcollect(q, mp->size, (mp->type&MS_MASK) == M_DATA);
219: if (bp == NULL)
220: return;
221: bp->type = mp->type;
222: mp->size -= bp->wptr - bp->rptr;
223: (*q->next->qinfo->putp)(q->next, bp);
224: }
225: }
226:
227: struct block *
228: msgcollect(q, size, isdata)
229: register struct queue *q;
230: {
231: register struct block *nbp, *bp;
232: register ninb;
233:
234: if (q->first==NULL)
235: return(NULL);
236: nbp = allocb(size);
237: if (nbp == NULL)
238: return(NULL);
239: if (size > nbp->lim - nbp->wptr)
240: size = nbp->lim - nbp->wptr;
241: while (size) {
242: bp = getq(q);
243: if (bp == NULL)
244: break;
245: if (bp->type != M_DATA) {
246: /* prevent the ack from being turned to data */
247: if (bp->type==M_IOCTL)
248: OTHERQ(q)->ptr = (caddr_t)2;
249: (*q->next->qinfo->putp)(q->next, bp);
250: continue;
251: }
252: ninb = bp->wptr - bp->rptr;
253: if (ninb <= size) {
254: bcopy((caddr_t)bp->rptr, (caddr_t)nbp->wptr, ninb);
255: size -= ninb;
256: nbp->wptr += ninb;
257: freeb(bp);
258: continue;
259: }
260: bcopy((caddr_t)bp->rptr, (caddr_t)nbp->wptr, size);
261: nbp->wptr += size;
262: bp->rptr += size;
263: size = 0;
264: putbq(q, bp);
265: }
266: if (nbp->rptr >= nbp->wptr) {
267: freeb(nbp);
268: return(NULL);
269: }
270: if (size==0 || isdata)
271: return(nbp);
272: putbq(q, nbp);
273: return(NULL);
274: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.