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