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