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