Annotation of 40BSD/cmd/uucp/pk1.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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