17c478bdstevel@tonic-gate/* 27c478bdstevel@tonic-gate * CDDL HEADER START 37c478bdstevel@tonic-gate * 47c478bdstevel@tonic-gate * The contents of this file are subject to the terms of the 57c478bdstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bdstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bdstevel@tonic-gate * with the License. 87c478bdstevel@tonic-gate * 97c478bdstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bdstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bdstevel@tonic-gate * See the License for the specific language governing permissions 127c478bdstevel@tonic-gate * and limitations under the License. 137c478bdstevel@tonic-gate * 147c478bdstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bdstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bdstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bdstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bdstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bdstevel@tonic-gate * 207c478bdstevel@tonic-gate * CDDL HEADER END 217c478bdstevel@tonic-gate */ 227c478bdstevel@tonic-gate/* 23ace1a5fdp * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 247c478bdstevel@tonic-gate * Use is subject to license terms. 257c478bdstevel@tonic-gate */ 267c478bdstevel@tonic-gate 277c478bdstevel@tonic-gate/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 287c478bdstevel@tonic-gate/* All Rights Reserved */ 297c478bdstevel@tonic-gate 307c478bdstevel@tonic-gate 317c478bdstevel@tonic-gate#pragma ident "%Z%%M% %I% %E% SMI" 327c478bdstevel@tonic-gate 337c478bdstevel@tonic-gate#include "uucp.h" 347c478bdstevel@tonic-gate 357c478bdstevel@tonic-gate#include "pk.h" 367c478bdstevel@tonic-gate#include <sys/buf.h> 377c478bdstevel@tonic-gate 387c478bdstevel@tonic-gateextern void pkfail(), pkzero(), pkoutput(), pkreset(), pkcntl(), pkgetpack(); 397c478bdstevel@tonic-gateextern int pksack(); 407c478bdstevel@tonic-gatestatic void pkdata(); 417c478bdstevel@tonic-gatestatic int pkcget(); 42462be47ceasthastatic void xlatestate(struct pack *, int); 43462be47ceasthavoid xlatecntl(int, int); 447c478bdstevel@tonic-gate 457c478bdstevel@tonic-gate/* 467c478bdstevel@tonic-gate * Code added to allow translation of states from numbers to 477c478bdstevel@tonic-gate * letters, to be done in such a way as to be meaningful to 487c478bdstevel@tonic-gate * John Q. Public 497c478bdstevel@tonic-gate */ 507c478bdstevel@tonic-gatestruct { 517c478bdstevel@tonic-gate int state; 527c478bdstevel@tonic-gate char *msg; 537c478bdstevel@tonic-gate} st_trans[] = { 547c478bdstevel@tonic-gate DEAD, "Dead!", 557c478bdstevel@tonic-gate INITa, "INIT code a", 567c478bdstevel@tonic-gate INITb, "INIT code b", 577c478bdstevel@tonic-gate LIVE, "O.K.", 587c478bdstevel@tonic-gate RXMIT, "Rcv/Xmit", 597c478bdstevel@tonic-gate RREJ, "RREJ?", 607c478bdstevel@tonic-gate PDEBUG, "PDEBUG?", 617c478bdstevel@tonic-gate DRAINO, "Draino...", 627c478bdstevel@tonic-gate WAITO, "Waiting", 637c478bdstevel@tonic-gate DOWN, "Link down", 647c478bdstevel@tonic-gate RCLOSE, "RCLOSE?", 657c478bdstevel@tonic-gate BADFRAME, "Bad frame", 667c478bdstevel@tonic-gate -1, "End of the line", 677c478bdstevel@tonic-gate}; 687c478bdstevel@tonic-gate 697c478bdstevel@tonic-gateextern char _Protocol[]; /* Protocol string with (options) */ 707c478bdstevel@tonic-gate 717c478bdstevel@tonic-gate#define PKMAXSTMSG 40 727c478bdstevel@tonic-gateint Connodata = 0; /* Continuous Non Valid Data Count */ 737c478bdstevel@tonic-gateint Ntimeout = 0; 747c478bdstevel@tonic-gate#define CONNODATA 20 /* Max Continuous Non Valid Data Count */ 757c478bdstevel@tonic-gate#define NTIMEOUT 50 /* This is not currently used, but maybe future */ 767c478bdstevel@tonic-gate 777c478bdstevel@tonic-gateextern jmp_buf Getjbuf; 787c478bdstevel@tonic-gate 797c478bdstevel@tonic-gate/* 807c478bdstevel@tonic-gate * start initial synchronization. 817c478bdstevel@tonic-gate */ 827c478bdstevel@tonic-gatestruct pack * 837c478bdstevel@tonic-gatepkopen(ifn, ofn) 847c478bdstevel@tonic-gateint ifn, ofn; 857c478bdstevel@tonic-gate{ 86462be47ceastha struct pack *pk; 87462be47ceastha char **bp; 88462be47ceastha int i; 897c478bdstevel@tonic-gate int windows = WINDOWS; 907c478bdstevel@tonic-gate extern int xpacksize, packsize; 917c478bdstevel@tonic-gate 927c478bdstevel@tonic-gate if ((pk = (struct pack *) calloc(1, sizeof (struct pack))) == NULL) 937c478bdstevel@tonic-gate return(NULL); 947c478bdstevel@tonic-gate pk->p_ifn = ifn; 957c478bdstevel@tonic-gate pk->p_ofn = ofn; 967c478bdstevel@tonic-gate DEBUG(7, "Setting up protocol parameters '%s'\n", _Protocol); 977c478bdstevel@tonic-gate if ( _Protocol[1] == '(' ) { 987c478bdstevel@tonic-gate if (sscanf(_Protocol, "%*c(%d,%d)", &windows, &packsize) == 0) 997c478bdstevel@tonic-gate sscanf(_Protocol, "%*c(,%d)", &packsize); 1007c478bdstevel@tonic-gate windows = ( windows < MINWINDOWS ? WINDOWS : 1017c478bdstevel@tonic-gate ( windows > MAXWINDOWS ? WINDOWS : windows ) ); 1027c478bdstevel@tonic-gate packsize = ( packsize < MINPACKSIZE ? PACKSIZE : 1037c478bdstevel@tonic-gate ( packsize > MAXPACKSIZE ? PACKSIZE : packsize ) ); 1047c478bdstevel@tonic-gate } 1057c478bdstevel@tonic-gate if ( (_Protocol[0] == 'g') && (packsize > OLDPACKSIZE) ) { 1067c478bdstevel@tonic-gate /* 1077c478bdstevel@tonic-gate * We reset to OLDPACKSIZE to maintain compatibility 1087c478bdstevel@tonic-gate * with old limited implementations. Maybe we should 1097c478bdstevel@tonic-gate * just warn the administrator and continue? 1107c478bdstevel@tonic-gate */ 1117c478bdstevel@tonic-gate packsize = OLDPACKSIZE; 1127c478bdstevel@tonic-gate } 1137c478bdstevel@tonic-gate pk->p_xsize = pk->p_rsize = xpacksize = packsize; 1147c478bdstevel@tonic-gate pk->p_rwindow = pk->p_swindow = windows; 1157c478bdstevel@tonic-gate 1167c478bdstevel@tonic-gate /* 1177c478bdstevel@tonic-gate * allocate input window 1187c478bdstevel@tonic-gate */ 1197c478bdstevel@tonic-gate for (i = 0; i < pk->p_rwindow; i++) { 1207c478bdstevel@tonic-gate if ((bp = (char **) malloc((unsigned) pk->p_xsize)) == NULL) 1217c478bdstevel@tonic-gate break; 1227c478bdstevel@tonic-gate *bp = (char *) pk->p_ipool; 1237c478bdstevel@tonic-gate pk->p_ipool = bp; 1247c478bdstevel@tonic-gate } 1257c478bdstevel@tonic-gate if (i == 0) 1267c478bdstevel@tonic-gate return(NULL); 1277c478bdstevel@tonic-gate pk->p_rwindow = i; 1287c478bdstevel@tonic-gate 1297c478bdstevel@tonic-gate /* 1307c478bdstevel@tonic-gate * start synchronization 1317c478bdstevel@tonic-gate */ 1327c478bdstevel@tonic-gate pk->p_msg = pk->p_rmsg = M_INITA; 1337c478bdstevel@tonic-gate pkoutput(pk); 1347c478bdstevel@tonic-gate 1357c478bdstevel@tonic-gate for (i = 0; i < PKMAXSTMSG; i++) { 1367c478bdstevel@tonic-gate pkgetpack(pk); 1377c478bdstevel@tonic-gate if ((pk->p_state & LIVE) != 0) 1387c478bdstevel@tonic-gate break; 1397c478bdstevel@tonic-gate } 1407c478bdstevel@tonic-gate if (i >= PKMAXSTMSG) 1417c478bdstevel@tonic-gate return(NULL); 1427c478bdstevel@tonic-gate 1437c478bdstevel@tonic-gate pkreset(pk); 1447c478bdstevel@tonic-gate return(pk); 1457c478bdstevel@tonic-gate} 1467c478bdstevel@tonic-gate 1477c478bdstevel@tonic-gate/* 1487c478bdstevel@tonic-gate * input framing and block checking. 1497c478bdstevel@tonic-gate * frame layout for most devices is: 1507c478bdstevel@tonic-gate * 1517c478bdstevel@tonic-gate * S|K|X|Y|C|Z| ... data ... | 1527c478bdstevel@tonic-gate * 1537c478bdstevel@tonic-gate * where S == initial synch byte 1547c478bdstevel@tonic-gate * K == encoded frame size (indexes pksizes[]) 1557c478bdstevel@tonic-gate * X, Y == block check bytes 1567c478bdstevel@tonic-gate * C == control byte 1577c478bdstevel@tonic-gate * Z == XOR of header (K^X^Y^C) 1587c478bdstevel@tonic-gate * data == 0 or more data bytes 1597c478bdstevel@tonic-gate * 1607c478bdstevel@tonic-gate */ 1617c478bdstevel@tonic-gate#define GETRIES 10 1627c478bdstevel@tonic-gate 1637c478bdstevel@tonic-gate/* 1647c478bdstevel@tonic-gate * Byte collection. 1657c478bdstevel@tonic-gate */ 1667c478bdstevel@tonic-gatevoid 1677c478bdstevel@tonic-gatepkgetpack(ipk) 168462be47ceasthastruct pack *ipk; 1697c478bdstevel@tonic-gate{ 170462be47ceastha char *p; 171462be47ceastha struct pack *pk; 172462be47ceastha struct header *h; 1737c478bdstevel@tonic-gate unsigned short sum; 1747c478bdstevel@tonic-gate int k, tries, ifn, noise; 1757c478bdstevel@tonic-gate char **bp, hdchk; 1767c478bdstevel@tonic-gate 1777c478bdstevel@tonic-gate pk = ipk; 1787c478bdstevel@tonic-gate /* 1797c478bdstevel@tonic-gate * If we are known to be DOWN, or if we've received too many garbage 1807c478bdstevel@tonic-gate * packets or timeouts, give up without a fight. 1817c478bdstevel@tonic-gate */ 1827c478bdstevel@tonic-gate if ((pk->p_state & DOWN) || Connodata > CONNODATA || Ntimeout > NTIMEOUT) 1837c478bdstevel@tonic-gate pkfail(); 1847c478bdstevel@tonic-gate ifn = pk->p_ifn; 1857c478bdstevel@tonic-gate h = &pk->p_ihbuf; 1867c478bdstevel@tonic-gate 1877c478bdstevel@tonic-gate /* 1887c478bdstevel@tonic-gate * Attempt no more than GETRIES times to read a packet. The only valid 1897c478bdstevel@tonic-gate * exit from this loop is a return. Break forces a failure. 1907c478bdstevel@tonic-gate */ 1917c478bdstevel@tonic-gate for (tries = 0; tries < GETRIES; tries++) { 1927c478bdstevel@tonic-gate /* 1937c478bdstevel@tonic-gate * Read header. 1947c478bdstevel@tonic-gate * First look for SYN. If more than 3 * packetsize characters 1957c478bdstevel@tonic-gate * go by w/o a SYN, request a retransmit. 1967c478bdstevel@tonic-gate */ 1977c478bdstevel@tonic-gate p = (caddr_t) h; 1987c478bdstevel@tonic-gate noise = 0; 1997c478bdstevel@tonic-gate for ( ; ; ) { 2007c478bdstevel@tonic-gate if (pkcget(ifn, p, HDRSIZ) != SUCCESS) { 2017c478bdstevel@tonic-gate DEBUG(7, 2027c478bdstevel@tonic-gate "Alarm while looking for SYN -- request RXMIT\n%s", ""); 2037c478bdstevel@tonic-gate goto retransmit; 2047c478bdstevel@tonic-gate } 2057c478bdstevel@tonic-gate if (*p == SYN) 2067c478bdstevel@tonic-gate break; /* got it */ 2077c478bdstevel@tonic-gate else { 2087c478bdstevel@tonic-gate char *pp, *pend; 2097c478bdstevel@tonic-gate 2107c478bdstevel@tonic-gate DEBUG(7, "first char not SYN (%x)\n", *p&0xff); 2117c478bdstevel@tonic-gate if ((pp = memchr(p, SYN, HDRSIZ)) != NULL) { 2127c478bdstevel@tonic-gate pend = p + HDRSIZ; 2137c478bdstevel@tonic-gate while (pp < pend) 2147c478bdstevel@tonic-gate *p++ = *pp++; 2157c478bdstevel@tonic-gate /* Now look for remainder of header */ 2167c478bdstevel@tonic-gate if (pkcget(ifn, p, pend - p) != 2177c478bdstevel@tonic-gate SUCCESS) { 2187c478bdstevel@tonic-gate DEBUG(7, 2197c478bdstevel@tonic-gate "Alarm while looking for header -- request RXMIT\n%s", ""); 2207c478bdstevel@tonic-gate goto retransmit; 2217c478bdstevel@tonic-gate } 2227c478bdstevel@tonic-gate p = (caddr_t) h; 2237c478bdstevel@tonic-gate break; /* got entire header */ 2247c478bdstevel@tonic-gate } 2257c478bdstevel@tonic-gate } 2267c478bdstevel@tonic-gate if ((noise += HDRSIZ) > 3 * pk->p_rsize) { 2277c478bdstevel@tonic-gate DEBUG(7, 2287c478bdstevel@tonic-gate "No SYN in %d characters -- request RXMIT\n", noise); 2297c478bdstevel@tonic-gate goto retransmit; 2307c478bdstevel@tonic-gate } 2317c478bdstevel@tonic-gate } 2327c478bdstevel@tonic-gate /* Validate the header */ 2337c478bdstevel@tonic-gate Connodata++; 2347c478bdstevel@tonic-gate hdchk = p[1] ^ p[2] ^ p[3] ^ p[4]; 2357c478bdstevel@tonic-gate sum = ((unsigned) p[2] & 0377) | ((unsigned) p[3] << 8); 2367c478bdstevel@tonic-gate h->sum = sum; 2377c478bdstevel@tonic-gate k = h->ksize; 2387c478bdstevel@tonic-gate if (hdchk != h->ccntl) { 2397c478bdstevel@tonic-gate /* bad header */ 2407c478bdstevel@tonic-gate DEBUG(7, "bad header checksum\n%s", ""); 2417c478bdstevel@tonic-gate return; 2427c478bdstevel@tonic-gate } 2437c478bdstevel@tonic-gate 2447c478bdstevel@tonic-gate if (k == 9) { /* control packet */ 2457c478bdstevel@tonic-gate if (((h->sum + h->cntl) & 0xffff) == CHECK) { 2467c478bdstevel@tonic-gate pkcntl(h->cntl, pk); 2477c478bdstevel@tonic-gate xlatestate(pk, 7); 2487c478bdstevel@tonic-gate } else { 2497c478bdstevel@tonic-gate /* bad header */ 2507c478bdstevel@tonic-gate DEBUG(7, "bad header (k == 9) 0%o\n", h->cntl&0xff); 2517c478bdstevel@tonic-gate pk->p_state |= BADFRAME; 2527c478bdstevel@tonic-gate } 2537c478bdstevel@tonic-gate return; 2547c478bdstevel@tonic-gate } 2557c478bdstevel@tonic-gate /* data packet */ 2567c478bdstevel@tonic-gate if (k && pksizes[k] != pk->p_rsize) 2577c478bdstevel@tonic-gate return; 2587c478bdstevel@tonic-gate pk->p_rpr = h->cntl & MOD8; 2597c478bdstevel@tonic-gate pksack(pk); 2607c478bdstevel@tonic-gate if ((bp = pk->p_ipool) == NULL) { 2617c478bdstevel@tonic-gate DEBUG(7, "bp NULL\n%s", ""); 2627c478bdstevel@tonic-gate return; 2637c478bdstevel@tonic-gate } 2647c478bdstevel@tonic-gate pk->p_ipool = (char **) *bp; 2657c478bdstevel@tonic-gate /* Header checks out, go for data */ 2667c478bdstevel@tonic-gate if (pkcget(pk->p_ifn, (char *) bp, pk->p_rsize) == SUCCESS) { 2677c478bdstevel@tonic-gate pkdata(h->cntl, h->sum, pk, bp); 2687c478bdstevel@tonic-gate Ntimeout = 0; 2697c478bdstevel@tonic-gate return; 2707c478bdstevel@tonic-gate } 2717c478bdstevel@tonic-gate DEBUG(7, "Alarm while reading data -- request RXMIT\n%s", ""); 2727c478bdstevel@tonic-gateretransmit: 2737c478bdstevel@tonic-gate /* 2747c478bdstevel@tonic-gate * Transmission error or excessive noise. Send a RXMIT 2757c478bdstevel@tonic-gate * and try again. 2767c478bdstevel@tonic-gate */ 2777c478bdstevel@tonic-gate/* 2787c478bdstevel@tonic-gate Retries++; 2797c478bdstevel@tonic-gate*/ 2807c478bdstevel@tonic-gate pk->p_msg |= pk->p_rmsg; 2817c478bdstevel@tonic-gate if (pk->p_msg == 0) 2827c478bdstevel@tonic-gate pk->p_msg |= M_RR; 2837c478bdstevel@tonic-gate if ((pk->p_state & LIVE) == LIVE) 2847c478bdstevel@tonic-gate pk->p_state |= RXMIT; 2857c478bdstevel@tonic-gate pkoutput(pk); 2867c478bdstevel@tonic-gate } 2877c478bdstevel@tonic-gate DEBUG(7, "pkgetpack failed after %d tries\n", tries); 2887c478bdstevel@tonic-gate pkfail(); 2897c478bdstevel@tonic-gate} 2907c478bdstevel@tonic-gate 2917c478bdstevel@tonic-gate/* 2927c478bdstevel@tonic-gate * Translate pk->p_state into something printable. 2937c478bdstevel@tonic-gate */ 294462be47ceasthastatic void 2957c478bdstevel@tonic-gatexlatestate(pk, dbglvl) 296462be47ceasthastruct pack *pk; 297462be47ceasthaint dbglvl; 2987c478bdstevel@tonic-gate{ 299462be47ceastha int i; 3007c478bdstevel@tonic-gate char delimc = ' ', msgline[80], *buf = msgline; 3017c478bdstevel@tonic-gate 3027c478bdstevel@tonic-gate if (Debug < dbglvl) 3037c478bdstevel@tonic-gate return; 3047c478bdstevel@tonic-gate sprintf(buf, "state -"); 3057c478bdstevel@tonic-gate buf += strlen(buf); 3067c478bdstevel@tonic-gate for(i = 0; st_trans[i].state != -1; i++) { 3077c478bdstevel@tonic-gate if (pk->p_state&st_trans[i].state){ 3087c478bdstevel@tonic-gate sprintf(buf, "%c[%s]", delimc, st_trans[i].msg); 3097c478bdstevel@tonic-gate buf += strlen(buf); 3107c478bdstevel@tonic-gate delimc = '&'; 3117c478bdstevel@tonic-gate } 3127c478bdstevel@tonic-gate } 3137c478bdstevel@tonic-gate sprintf(buf, " (0%o)\n", pk->p_state); 3147c478bdstevel@tonic-gate DEBUG(dbglvl, "%s", msgline); 315462be47ceastha return; 3167c478bdstevel@tonic-gate} 3177c478bdstevel@tonic-gate 3187c478bdstevel@tonic-gatestatic void 3197c478bdstevel@tonic-gatepkdata(c, sum, pk, bp) 320462be47ceasthastruct pack *pk; 3217c478bdstevel@tonic-gateunsigned short sum; 3227c478bdstevel@tonic-gatechar c; 3237c478bdstevel@tonic-gatechar **bp; 3247c478bdstevel@tonic-gate{ 325462be47ceastha int x; 3267c478bdstevel@tonic-gate int t; 3277c478bdstevel@tonic-gate char m; 3287c478bdstevel@tonic-gate 3297c478bdstevel@tonic-gate if (pk->p_state & DRAINO || !(pk->p_state & LIVE)) { 3307c478bdstevel@tonic-gate pk->p_msg |= pk->p_rmsg; 3317c478bdstevel@tonic-gate pkoutput(pk); 3327c478bdstevel@tonic-gate goto drop; 3337c478bdstevel@tonic-gate } 3347c478bdstevel@tonic-gate t = next[pk->p_pr]; 3357c478bdstevel@tonic-gate for(x=pk->p_pr; x!=t; x = (x-1)&7) { 3367c478bdstevel@tonic-gate if (pk->p_is[x] == 0) 3377c478bdstevel@tonic-gate goto slot; 3387c478bdstevel@tonic-gate } 3397c478bdstevel@tonic-gatedrop: 3407c478bdstevel@tonic-gate *bp = (char *)pk->p_ipool; 3417c478bdstevel@tonic-gate pk->p_ipool = bp; 3427c478bdstevel@tonic-gate return; 3437c478bdstevel@tonic-gate 3447c478bdstevel@tonic-gateslot: 3457c478bdstevel@tonic-gate m = mask[x]; 3467c478bdstevel@tonic-gate pk->p_imap |= m; 3477c478bdstevel@tonic-gate pk->p_is[x] = c; 3487c478bdstevel@tonic-gate pk->p_isum[x] = sum; 3497c478bdstevel@tonic-gate pk->p_ib[x] = (char *)bp; 3507c478bdstevel@tonic-gate} 3517c478bdstevel@tonic-gate 3527c478bdstevel@tonic-gate/* 3537c478bdstevel@tonic-gate * Start transmission on output device associated with pk. 3547c478bdstevel@tonic-gate * For asynch devices (t_line==1) framing is 3557c478bdstevel@tonic-gate * imposed. For devices with framing and crc 3567c478bdstevel@tonic-gate * in the driver (t_line==2) the transfer is 3577c478bdstevel@tonic-gate * passed on to the driver. 3587c478bdstevel@tonic-gate */ 3597c478bdstevel@tonic-gatevoid 3607c478bdstevel@tonic-gatepkxstart(pk, cntl, x) 361462be47ceasthastruct pack *pk; 3627c478bdstevel@tonic-gateint x; 3637c478bdstevel@tonic-gatechar cntl; 3647c478bdstevel@tonic-gate{ 365462be47ceastha char *p; 366462be47ceastha short checkword; 367462be47ceastha char hdchk; 3687c478bdstevel@tonic-gate 3697c478bdstevel@tonic-gate p = (caddr_t) &pk->p_ohbuf; 3707c478bdstevel@tonic-gate *p++ = SYN; 3717c478bdstevel@tonic-gate if (x < 0) { 3727c478bdstevel@tonic-gate *p++ = hdchk = 9; 3737c478bdstevel@tonic-gate checkword = cntl; 3747c478bdstevel@tonic-gate } else { 3757c478bdstevel@tonic-gate *p++ = hdchk = pk->p_lpsize; 3767c478bdstevel@tonic-gate checkword = pk->p_osum[x] ^ (unsigned)(cntl & 0377); 3777c478bdstevel@tonic-gate } 3787c478bdstevel@tonic-gate checkword = CHECK - checkword; 3797c478bdstevel@tonic-gate *p = checkword; 3807c478bdstevel@tonic-gate hdchk ^= *p++; 3817c478bdstevel@tonic-gate *p = checkword>>8; 3827c478bdstevel@tonic-gate hdchk ^= *p++; 3837c478bdstevel@tonic-gate *p = cntl; 3847c478bdstevel@tonic-gate hdchk ^= *p++; 3857c478bdstevel@tonic-gate *p = hdchk; 3867c478bdstevel@tonic-gate 3877c478bdstevel@tonic-gate /* 3887c478bdstevel@tonic-gate * writes 3897c478bdstevel@tonic-gate */ 3907c478bdstevel@tonic-gate if (Debug >= 9) 3917c478bdstevel@tonic-gate xlatecntl(1, cntl); 3927c478bdstevel@tonic-gate 3937c478bdstevel@tonic-gate p = (caddr_t) & pk->p_ohbuf; 3947c478bdstevel@tonic-gate if (x < 0) { 3957c478bdstevel@tonic-gate if ((*Write)(pk->p_ofn, p, HDRSIZ) != HDRSIZ) { 3967c478bdstevel@tonic-gate DEBUG(4, "pkxstart, write failed, %s\n", 397ace1a5fdp strerror(errno)); 398ace1a5fdp logent(strerror(errno), "PKXSTART WRITE"); 3997c478bdstevel@tonic-gate pkfail(); 4007c478bdstevel@tonic-gate /* NOT REACHED */ 4017c478bdstevel@tonic-gate } 4027c478bdstevel@tonic-gate } else { 4037c478bdstevel@tonic-gate char buf[MAXPACKSIZE + HDRSIZ]; 4047c478bdstevel@tonic-gate 4057c478bdstevel@tonic-gate memcpy(buf, p, HDRSIZ); 4067c478bdstevel@tonic-gate memcpy(buf+HDRSIZ, pk->p_ob[x], pk->p_xsize); 4077c478bdstevel@tonic-gate if ((*Write)(pk->p_ofn, buf, pk->p_xsize + HDRSIZ) != 4087c478bdstevel@tonic-gate pk->p_xsize + HDRSIZ) { 4097c478bdstevel@tonic-gate DEBUG(4, "pkxstart, write failed, %s\n", 410ace1a5fdp strerror(errno)); 411ace1a5fdp logent(strerror(errno), "PKXSTART WRITE"); 4127c478bdstevel@tonic-gate pkfail(); 4137c478bdstevel@tonic-gate /* NOT REACHED */ 4147c478bdstevel@tonic-gate } 4157c478bdstevel@tonic-gate Connodata = 0; 4167c478bdstevel@tonic-gate } 4177c478bdstevel@tonic-gate if (pk->p_msg) 4187c478bdstevel@tonic-gate pkoutput(pk); 4197c478bdstevel@tonic-gate} 4207c478bdstevel@tonic-gate 4217c478bdstevel@tonic-gate/* 4227c478bdstevel@tonic-gate * get n characters from input 4237c478bdstevel@tonic-gate * b -> buffer for characters 4247c478bdstevel@tonic-gate * fn -> file descriptor 4257c478bdstevel@tonic-gate * n -> requested number of characters 4267c478bdstevel@tonic-gate * return: 4277c478bdstevel@tonic-gate * SUCCESS -> n chars successfully read 4287c478bdstevel@tonic-gate * FAIL -> o.w. 4297c478bdstevel@tonic-gate */ 4307c478bdstevel@tonic-gate 4317c478bdstevel@tonic-gatestatic int 4327c478bdstevel@tonic-gatepkcget(fn, b, n) 433462be47ceasthaint n; 434462be47ceasthachar *b; 435462be47ceasthaint fn; 4367c478bdstevel@tonic-gate{ 437462be47ceastha int ret; 4387c478bdstevel@tonic-gate#ifdef PKSPEEDUP 4397c478bdstevel@tonic-gate extern int linebaudrate; 440462be47ceastha int donap = (linebaudrate > 0 && linebaudrate < 4800); 4417c478bdstevel@tonic-gate#endif /* PKSPEEDUP */ 4427c478bdstevel@tonic-gate 4437c478bdstevel@tonic-gate if (n == 0) 4447c478bdstevel@tonic-gate return(SUCCESS); 4457c478bdstevel@tonic-gate if (setjmp(Getjbuf)) { 4467c478bdstevel@tonic-gate Ntimeout++; 4477c478bdstevel@tonic-gate DEBUG(4, "pkcget: alarm %d\n", Ntimeout); 4487c478bdstevel@tonic-gate return(FAIL); 4497c478bdstevel@tonic-gate } 4507c478bdstevel@tonic-gate 4517c478bdstevel@tonic-gate (void) alarm( (unsigned) ( 10 + (n >> 7)) ); 4527c478bdstevel@tonic-gate 4537c478bdstevel@tonic-gate for (;;) { 4547c478bdstevel@tonic-gate ret = (*Read)(fn, b, n); 4557c478bdstevel@tonic-gate (void) alarm(0); 4567c478bdstevel@tonic-gate if (ret == 0) { 4577c478bdstevel@tonic-gate DEBUG(4, "pkcget, read failed, EOF\n", 0); 4587c478bdstevel@tonic-gate /* 4597c478bdstevel@tonic-gate * Device has decided that the connection has no 4607c478bdstevel@tonic-gate * more data to send. Any further tries are futile... 4617c478bdstevel@tonic-gate * (The only other way to get a zero return value 4627c478bdstevel@tonic-gate * is to read a zero length message from a STREAM. 4637c478bdstevel@tonic-gate * However, uucp *never* sends zero length messages 4647c478bdstevel@tonic-gate * over any sort of channel...) 4657c478bdstevel@tonic-gate */ 4667c478bdstevel@tonic-gate pkfail(); 4677c478bdstevel@tonic-gate /* NOT REACHED */ 4687c478bdstevel@tonic-gate } 4697c478bdstevel@tonic-gate if (ret < 0) { 4707c478bdstevel@tonic-gate DEBUG(4, "pkcget, read failed, %s\n", 471ace1a5fdp strerror(errno)); 472ace1a5fdp logent(strerror(errno), "PKCGET READ"); 4737c478bdstevel@tonic-gate pkfail(); 4747c478bdstevel@tonic-gate /* NOT REACHED */ 4757c478bdstevel@tonic-gate } 4767c478bdstevel@tonic-gate if ((n -= ret) <= 0) 4777c478bdstevel@tonic-gate break; 4787c478bdstevel@tonic-gate#ifdef PKSPEEDUP 4797c478bdstevel@tonic-gate if (donap) { 4807c478bdstevel@tonic-gate#if defined(BSD4_2) || defined(ATTSVR4) 4817c478bdstevel@tonic-gate /* wait for more chars to come in */ 4827c478bdstevel@tonic-gate nap((n * HZ * 10) / linebaudrate); /* n char times */ 4837c478bdstevel@tonic-gate#else 4847c478bdstevel@tonic-gate sleep(1); 4857c478bdstevel@tonic-gate#endif 4867c478bdstevel@tonic-gate } 4877c478bdstevel@tonic-gate#endif /* PKSPEEDUP */ 4887c478bdstevel@tonic-gate b += ret; 4897c478bdstevel@tonic-gate (void) alarm( (unsigned) ( 10 + (n >> 7)) ); 4907c478bdstevel@tonic-gate } 4917c478bdstevel@tonic-gate (void) alarm(0); 4927c478bdstevel@tonic-gate return(SUCCESS); 4937c478bdstevel@tonic-gate} 4947c478bdstevel@tonic-gate 4957c478bdstevel@tonic-gate/* 4967c478bdstevel@tonic-gate * role == 0: receive 4977c478bdstevel@tonic-gate * role == 1: send 4987c478bdstevel@tonic-gate */ 499462be47ceasthavoid 5007c478bdstevel@tonic-gatexlatecntl(role, cntl) 501462be47ceasthaint role; 502462be47ceasthaint cntl; 5037c478bdstevel@tonic-gate{ 5047c478bdstevel@tonic-gate static char *cntltype[4] = {"CNTL, ", "ALT, ", "DATA, ", "SHORT, "}; 5057c478bdstevel@tonic-gate static char *cntlxxx[8] = {"ZERO, ", "CLOSE, ", "RJ, ", "SRJ, ", 5067c478bdstevel@tonic-gate "RR, ", "INITC, ", "INITB, ", "INITA, "}; 5077c478bdstevel@tonic-gate char dbgbuf[128]; 508462be47ceastha char *ptr; 5097c478bdstevel@tonic-gate 5107c478bdstevel@tonic-gate ptr = dbgbuf; 5117c478bdstevel@tonic-gate strcpy(ptr, role ? "send " : "recv "); 5127c478bdstevel@tonic-gate ptr += strlen(ptr); 5137c478bdstevel@tonic-gate 5147c478bdstevel@tonic-gate strcpy(ptr, cntltype[(cntl&0300)>>6]); 5157c478bdstevel@tonic-gate ptr += strlen(ptr); 5167c478bdstevel@tonic-gate 5177c478bdstevel@tonic-gate if (cntl&0300) { 5187c478bdstevel@tonic-gate /* data packet */ 5197c478bdstevel@tonic-gate if (role) 5207c478bdstevel@tonic-gate sprintf(ptr, "loc %o, rem %o\n", (cntl & 070) >> 3, cntl & 7); 5217c478bdstevel@tonic-gate else 5227c478bdstevel@tonic-gate sprintf(ptr, "loc %o, rem %o\n", cntl & 7, (cntl & 070) >> 3); 5237c478bdstevel@tonic-gate } else { 5247c478bdstevel@tonic-gate /* control packet */ 5257c478bdstevel@tonic-gate strcpy(ptr, cntlxxx[(cntl&070)>>3]); 5267c478bdstevel@tonic-gate ptr += strlen(ptr); 5277c478bdstevel@tonic-gate sprintf(ptr, "val %o\n", cntl & 7); 5287c478bdstevel@tonic-gate } 5297c478bdstevel@tonic-gate 5307c478bdstevel@tonic-gate DEBUG(1, dbgbuf, 0); 5317c478bdstevel@tonic-gate} 532