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

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

unix.superglobalmegacorp.com

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