Annotation of 42BSD/usr.bin/uucp/pk1.c, revision 1.1

1.1     ! root        1: #ifndef lint
        !             2: static char sccsid[] = "@(#)pk1.c      5.1 (Berkeley) 7/2/83";
        !             3: #endif
        !             4: 
        !             5: extern char    *malloc();
        !             6: 
        !             7: #define USER   1
        !             8: #include <stdio.h>
        !             9: #ifdef SYSIII
        !            10: #include <sys/types.h>
        !            11: #endif
        !            12: #include "pk.p"
        !            13: #include <sys/param.h>
        !            14: #include "pk.h"
        !            15: #include <sys/buf.h>
        !            16: #include <setjmp.h>
        !            17: #include <signal.h>
        !            18: 
        !            19: 
        !            20: #define PKMAXSTMSG 40
        !            21: #define        PKTIME  25
        !            22: extern int Errorrate;
        !            23: int Connodata = 0;
        !            24: int Ntimeout = 0;
        !            25: #define CONNODATA 10
        !            26: #define NTIMEOUT 50
        !            27: /*
        !            28:  * packet driver support routines
        !            29:  *
        !            30:  */
        !            31: 
        !            32: struct pack *pklines[NPLINES];
        !            33: 
        !            34: /*
        !            35:  * start initial synchronization.
        !            36:  */
        !            37: 
        !            38: struct pack *
        !            39: pkopen(ifn, ofn)
        !            40: int ifn, ofn;
        !            41: {
        !            42:        register struct pack *pk;
        !            43:        register char **bp;
        !            44:        register int i;
        !            45: 
        !            46:        if (++pkactive >= NPLINES)
        !            47:                return(NULL);
        !            48:        if ((pk = (struct pack *) malloc(sizeof (struct pack))) == NULL)
        !            49:                return(NULL);
        !            50:        pkzero((caddr_t) pk, sizeof (struct pack));
        !            51:        pk->p_ifn = ifn;
        !            52:        pk->p_ofn = ofn;
        !            53:        pk->p_xsize = pk->p_rsize = PACKSIZE;
        !            54:        pk->p_rwindow = pk->p_swindow = WINDOWS;
        !            55:        /*  allocate input windows */
        !            56:        for (i = 0; i < pk->p_rwindow; i++) {
        !            57:                if ((bp = (char **) GETEPACK) == NULL)
        !            58:                        break;
        !            59:                *bp = (char *) pk->p_ipool;
        !            60:                pk->p_ipool = bp;
        !            61:        }
        !            62:        if (i == 0)
        !            63:                return(NULL);
        !            64:        pk->p_rwindow = i;
        !            65: 
        !            66:        /* start synchronization */
        !            67:        pk->p_msg = pk->p_rmsg = M_INITA;
        !            68:        for (i = 0; i < NPLINES; i++) {
        !            69:                if (pklines[i] == NULL) {
        !            70:                        pklines[i] = pk;
        !            71:                        break;
        !            72:                }
        !            73:        }
        !            74:        if (i >= NPLINES)
        !            75:                return(NULL);
        !            76:        pkoutput(pk);
        !            77: 
        !            78:        for (i = 0; i < PKMAXSTMSG; i++) {
        !            79:                PKGETPKT(pk);
        !            80:                if ((pk->p_state & LIVE) != 0)
        !            81:                        break;
        !            82:        }
        !            83:        if (i >= PKMAXSTMSG)
        !            84:                return(NULL);
        !            85: 
        !            86:        pkreset(pk);
        !            87:        return(pk);
        !            88: }
        !            89: 
        !            90: 
        !            91: /*
        !            92:  * input framing and block checking.
        !            93:  * frame layout for most devices is:
        !            94:  *     
        !            95:  *     S|K|X|Y|C|Z|  ... data ... |
        !            96:  *
        !            97:  *     where   S       == initial synch byte
        !            98:  *             K       == encoded frame size (indexes pksizes[])
        !            99:  *             X, Y    == block check bytes
        !           100:  *             C       == control byte
        !           101:  *             Z       == XOR of header (K^X^Y^C)
        !           102:  *             data    == 0 or more data bytes
        !           103:  *
        !           104:  */
        !           105: 
        !           106: int pksizes[] = {
        !           107:        1, 32, 64, 128, 256, 512, 1024, 2048, 4096, 1
        !           108: };
        !           109: 
        !           110: #define GETRIES 5
        !           111: /*
        !           112:  * Pseudo-dma byte collection.
        !           113:  */
        !           114: 
        !           115: pkgetpack(ipk)
        !           116: struct pack *ipk;
        !           117: {
        !           118:        int ret, k, tries;
        !           119:        register char *p;
        !           120:        register struct pack *pk;
        !           121:        register struct header *h;
        !           122:        unsigned short sum;
        !           123:        int ifn;
        !           124:        char **bp;
        !           125:        char hdchk;
        !           126: 
        !           127:        pk = PADDR;
        !           128:        if ((pk->p_state & DOWN) ||
        !           129:          Connodata > CONNODATA /* || Ntimeout > NTIMEOUT */)
        !           130:                pkfail();
        !           131:        ifn = pk->p_ifn;
        !           132: 
        !           133:        /* find HEADER */
        !           134:        for (tries = 0; tries < GETRIES; ) {
        !           135:                p = (caddr_t) &pk->p_ihbuf;
        !           136:                if ((ret = pkcget(ifn, p, 1)) < 0) {
        !           137:                        /* set up retransmit or REJ */
        !           138:                        tries++;
        !           139:                        pk->p_msg |= pk->p_rmsg;
        !           140:                        if (pk->p_msg == 0)
        !           141:                                pk->p_msg |= M_RR;
        !           142:                        if ((pk->p_state & LIVE) == LIVE)
        !           143:                                pk->p_state |= RXMIT;
        !           144:                        pkoutput(pk);
        !           145:                        continue;
        !           146:                }
        !           147:                if (*p != SYN)
        !           148:                        continue;
        !           149:                p++;
        !           150:                ret = pkcget(ifn, p, HDRSIZ - 1);
        !           151:                if (ret == -1)
        !           152:                        continue;
        !           153:                break;
        !           154:        }
        !           155:        if (tries >= GETRIES) {
        !           156:                PKDEBUG(4, "tries = %d\n", tries);
        !           157:                pkfail();
        !           158:        }
        !           159: 
        !           160:        Connodata++;
        !           161:        h = (struct header * ) &pk->p_ihbuf;
        !           162:        p = (caddr_t) h;
        !           163:        hdchk = p[1] ^ p[2] ^ p[3] ^ p[4];
        !           164:        p += 2;
        !           165:        sum = (unsigned) *p++ & 0377;
        !           166:        sum |= (unsigned) *p << 8;
        !           167:        h->sum = sum;
        !           168:        PKDEBUG(7, "rec h->cntl %o\n", (unsigned) h->cntl);
        !           169:        k = h->ksize;
        !           170:        if (hdchk != h->ccntl) {
        !           171:                /* bad header */
        !           172:                PKDEBUG(7, "bad header %o,", hdchk);
        !           173:                PKDEBUG(7, "h->ccntl %o\n", h->ccntl);
        !           174:                return;
        !           175:        }
        !           176:        if (k == 9) {
        !           177:                if (((h->sum + h->cntl) & 0xffff) == CHECK) {
        !           178:                        pkcntl(h->cntl, pk);
        !           179:                        PKDEBUG(7, "state - %o\n", pk->p_state);
        !           180:                }
        !           181:                else {
        !           182:                        /*  bad header */
        !           183:                        PKDEBUG(7, "bad header (k==9) %o\n", h->cntl);
        !           184:                        pk->p_state |= BADFRAME;
        !           185:                }
        !           186:                return;
        !           187:        }
        !           188:        if (k && pksizes[k] == pk->p_rsize) {
        !           189:                pk->p_rpr = h->cntl & MOD8;
        !           190:                pksack(pk);
        !           191:                Connodata = 0;
        !           192:                bp = pk->p_ipool;
        !           193:                pk->p_ipool = (char **) *bp;
        !           194:                if (bp == NULL) {
        !           195:                        PKDEBUG(7, "bp NULL %s\n", "");
        !           196:                return;
        !           197:                }
        !           198:        }
        !           199:        else {
        !           200:                return;
        !           201:        }
        !           202:        ret = pkcget(pk->p_ifn, (char *) bp, pk->p_rsize);
        !           203:        if (ret == 0)
        !           204:                pkdata(h->cntl, h->sum, pk, (char **) bp);
        !           205:        return;
        !           206: }
        !           207: 
        !           208: 
        !           209: pkdata(c, sum, pk, bp)
        !           210: char c;
        !           211: unsigned short sum;
        !           212: register struct pack *pk;
        !           213: char **bp;
        !           214: {
        !           215: register x;
        !           216: int t;
        !           217: char m;
        !           218: 
        !           219:        if (pk->p_state & DRAINO || !(pk->p_state & LIVE)) {
        !           220:                pk->p_msg |= pk->p_rmsg;
        !           221:                pkoutput(pk);
        !           222:                goto drop;
        !           223:        }
        !           224:        t = next[pk->p_pr];
        !           225:        for(x=pk->p_pr; x!=t; x = (x-1)&7) {
        !           226:                if (pk->p_is[x] == 0)
        !           227:                        goto slot;
        !           228:        }
        !           229: drop:
        !           230:        *bp = (char *)pk->p_ipool;
        !           231:        pk->p_ipool = bp;
        !           232:        return;
        !           233: 
        !           234: slot:
        !           235:        m = mask[x];
        !           236:        pk->p_imap |= m;
        !           237:        pk->p_is[x] = c;
        !           238:        pk->p_isum[x] = sum;
        !           239:        pk->p_ib[x] = (char *)bp;
        !           240:        return;
        !           241: }
        !           242: 
        !           243: 
        !           244: 
        !           245: /*
        !           246:  * setup input transfers
        !           247:  */
        !           248: pkrstart(pk)
        !           249: {}
        !           250: 
        !           251: #define PKMAXBUF 128
        !           252: /*
        !           253:  * Start transmission on output device associated with pk.
        !           254:  * For asynch devices (t_line==1) framing is
        !           255:  * imposed.  For devices with framing and crc
        !           256:  * in the driver (t_line==2) the transfer is
        !           257:  * passed on to the driver.
        !           258:  */
        !           259: pkxstart(pk, cntl, x)
        !           260: register struct pack *pk;
        !           261: char cntl;
        !           262: register x;
        !           263: {
        !           264:        register char *p;
        !           265:        int ret;
        !           266:        short checkword;
        !           267:        char hdchk;
        !           268: 
        !           269:        p = (caddr_t) &pk->p_ohbuf;
        !           270:        *p++ = SYN;
        !           271:        if (x < 0) {
        !           272:                *p++ = hdchk = 9;
        !           273:                checkword = cntl;
        !           274:        }
        !           275:        else {
        !           276:                *p++ = hdchk = pk->p_lpsize;
        !           277:                checkword = pk->p_osum[x] ^ (unsigned)(cntl & 0377);
        !           278:        }
        !           279:        checkword = CHECK - checkword;
        !           280:        *p = checkword;
        !           281:        hdchk ^= *p++;
        !           282:        *p = checkword>>8;
        !           283:        hdchk ^= *p++;
        !           284:        *p = cntl;
        !           285:        hdchk ^= *p++;
        !           286:        *p = hdchk;
        !           287:  /*  writes  */
        !           288: PKDEBUG(7, "send %o\n", (unsigned) cntl);
        !           289:        p = (caddr_t) & pk->p_ohbuf;
        !           290:        if (x < 0) {
        !           291: #ifdef PROTODEBUG
        !           292:                GENERROR(p, HDRSIZ);
        !           293: #endif
        !           294:                ret = write(pk->p_ofn, p, HDRSIZ);
        !           295:                PKASSERT(ret == HDRSIZ, "PKXSTART ret", "", ret);
        !           296:        }
        !           297:        else {
        !           298:                char buf[PKMAXBUF + HDRSIZ], *b;
        !           299:                int i;
        !           300:                for (i = 0, b = buf; i < HDRSIZ; i++) 
        !           301:                        *b++ = *p++;
        !           302:                for (i = 0, p = pk->p_ob[x]; i < pk->p_xsize; i++)
        !           303:                        *b++ = *p++;
        !           304: #ifdef PROTODEBUG
        !           305:                GENERROR(buf, pk->p_xsize + HDRSIZ);
        !           306: #endif
        !           307:                ret = write(pk->p_ofn, buf, pk->p_xsize + HDRSIZ);
        !           308:                PKASSERT(ret == pk->p_xsize + HDRSIZ,
        !           309:                  "PKXSTART ret", "", ret);
        !           310:                Connodata = 0;
        !           311:        }
        !           312:        if (pk->p_msg)
        !           313:                pkoutput(pk);
        !           314:        return;
        !           315: }
        !           316: 
        !           317: 
        !           318: pkmove(p1, p2, count, flag)
        !           319: char *p1, *p2;
        !           320: int count, flag;
        !           321: {
        !           322:        register char *s, *d;
        !           323:        register int i;
        !           324: 
        !           325:        if (flag == B_WRITE) {
        !           326:                s = p2;
        !           327:                d = p1;
        !           328:        }
        !           329:        else {
        !           330:                s = p1;
        !           331:                d = p2;
        !           332:        }
        !           333:        for (i = 0; i < count; i++)
        !           334:                *d++ = *s++;
        !           335:        return;
        !           336: }
        !           337: 
        !           338: 
        !           339: /***
        !           340:  *     pkcget(fn, b, n)        get n characters from input
        !           341:  *     char *b;                - buffer for characters
        !           342:  *     int fn;                 - file descriptor
        !           343:  *     int n;                  - requested number of characters
        !           344:  *
        !           345:  *     return codes:
        !           346:  *             n - number of characters returned
        !           347:  *             0 - end of file
        !           348:  */
        !           349: 
        !           350: jmp_buf Getjbuf;
        !           351: cgalarm() { longjmp(Getjbuf, 1); }
        !           352: 
        !           353: pkcget(fn, b, n)
        !           354: int fn, n;
        !           355: register char *b;
        !           356: {
        !           357:        register int nchars, ret;
        !           358: 
        !           359:        if (setjmp(Getjbuf)) {
        !           360:                Ntimeout++;
        !           361:                PKDEBUG(4, "alarm %d\n", Ntimeout);
        !           362:                return(-1);
        !           363:        }
        !           364:        signal(SIGALRM, cgalarm);
        !           365: 
        !           366:        alarm(PKTIME);
        !           367:        for (nchars = 0; nchars < n; nchars += ret) {
        !           368:                ret = read(fn, b, n - nchars);
        !           369:                if (ret == 0) {
        !           370:                        alarm(0);
        !           371:                        return(-1);
        !           372:                }
        !           373:                PKASSERT(ret > 0, "PKCGET READ", "", ret);
        !           374:                b += ret;
        !           375:        }
        !           376:        alarm(0);
        !           377:        return(0);
        !           378: }
        !           379: 
        !           380: 
        !           381: #ifdef PROTODEBUG
        !           382: generror(p, s)
        !           383: char *p;
        !           384: int s;
        !           385: {
        !           386:        int r;
        !           387:        if (Errorrate != 0 && (rand() % Errorrate) == 0) {
        !           388:                r = rand() % s;
        !           389: fprintf(stderr, "gen err at %o, (%o), ", r, (unsigned) *(p + r));
        !           390:                *(p + r) += 1;
        !           391:        }
        !           392:        return;
        !           393: }
        !           394: 
        !           395: 
        !           396: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.