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