Annotation of 42BSD/usr.bin/uucp/pk1.c, revision 1.1.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.