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