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