Annotation of 43BSD/usr.bin/uucp/pk1.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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