xref: /original-bsd/usr.bin/uucp/uucico/pk0.c (revision 22631af3)
105c9bca4Sbostic /*-
2*22631af3Sbostic  * Copyright (c) 1985, 1993
3*22631af3Sbostic  *	The Regents of the University of California.  All rights reserved.
405c9bca4Sbostic  *
505c9bca4Sbostic  * %sccs.include.proprietary.c%
605c9bca4Sbostic  */
705c9bca4Sbostic 
896b55349Ssam #ifndef lint
9*22631af3Sbostic static char sccsid[] = "@(#)pk0.c	8.1 (Berkeley) 06/06/93";
1005c9bca4Sbostic #endif /* not lint */
1196b55349Ssam 
12e90e093fSralph #include "uucp.h"
1396b55349Ssam #include "pk.h"
1496b55349Ssam 
1596b55349Ssam /*
1696b55349Ssam  * packet driver
1796b55349Ssam  */
1896b55349Ssam 
1996b55349Ssam char next[8] = { 1, 2, 3, 4, 5, 6, 7, 0};	/* packet sequence numbers */
2096b55349Ssam char mask[8] = { 1, 2, 4, 010, 020, 040, 0100, 0200 };
2196b55349Ssam 
2296b55349Ssam struct pack *pklines[NPLINES];
23adca94fdSbloom 
240c7b3a87Sbloom int Reacks;
250c7b3a87Sbloom 
260c7b3a87Sbloom #define PKRTIME 4
270c7b3a87Sbloom #define PKWTIME 4
280c7b3a87Sbloom #define PKRSKEW 3
290c7b3a87Sbloom #define PKWSKEW 2
300c7b3a87Sbloom extern int pktimeout, pktimeskew, Ntimeout;
3196b55349Ssam 
3296b55349Ssam /*
3396b55349Ssam  * receive control messages
3496b55349Ssam  */
pkcntl(c,pk)3596b55349Ssam pkcntl(c, pk)
3696b55349Ssam register struct pack *pk;
3796b55349Ssam {
3896b55349Ssam 	register cntl, val;
3996b55349Ssam 
4096b55349Ssam 	val = c & MOD8;
4196b55349Ssam 	cntl = (c>>3) & MOD8;
4296b55349Ssam 
4396b55349Ssam 	if (!ISCNTL(c)) {
44893f18ccSralph 		logent("PK0", "not cntl");
4596b55349Ssam 		return;
4696b55349Ssam 	}
4796b55349Ssam 
4896b55349Ssam 	switch(cntl) {
4996b55349Ssam 	case INITB:
5096b55349Ssam 		val++;
5196b55349Ssam 		pk->p_xsize = pksizes[val];
5296b55349Ssam 		pk->p_lpsize = val;
53893f18ccSralph 		pk->p_bits = 1;
5496b55349Ssam 		if (pk->p_state & LIVE) {
5596b55349Ssam 			pk->p_msg |= M_INITC;
5696b55349Ssam 			break;
5796b55349Ssam 		}
5896b55349Ssam 		pk->p_state |= INITb;
5996b55349Ssam 		if ((pk->p_state & INITa)==0) {
6096b55349Ssam 			break;
6196b55349Ssam 		}
6296b55349Ssam 		pk->p_rmsg &= ~M_INITA;
6396b55349Ssam 		pk->p_msg |= M_INITC;
6496b55349Ssam 		break;
6596b55349Ssam 
6696b55349Ssam 	case INITC:
6796b55349Ssam 		if ((pk->p_state&INITab)==INITab) {
6896b55349Ssam 			pk->p_state = LIVE;
6996b55349Ssam 			pk->p_rmsg &= ~M_INITB;
7096b55349Ssam 		} else
7196b55349Ssam 			pk->p_msg |= M_INITB;
7296b55349Ssam 		if (val)
7396b55349Ssam 			pk->p_swindow = val;
7496b55349Ssam 		break;
7596b55349Ssam 	case INITA:
7696b55349Ssam 		if (val == 0 && pk->p_state&LIVE) {
77893f18ccSralph 			logent("PK0", "alloc change not implemented");
7896b55349Ssam 			break;
7996b55349Ssam 		}
8096b55349Ssam 		if (val) {
8196b55349Ssam 			pk->p_state |= INITa;
8296b55349Ssam 			pk->p_msg |= M_INITB;
8396b55349Ssam 			pk->p_rmsg |= M_INITB;
8496b55349Ssam 			pk->p_swindow = val;
8596b55349Ssam 		}
8696b55349Ssam 		break;
8796b55349Ssam 	case RJ:
8896b55349Ssam 		pk->p_state |= RXMIT;
8996b55349Ssam 		pk->p_msg |= M_RR;
9096b55349Ssam 		pk->p_rpr = val;
91893f18ccSralph 		(void) pksack(pk);
9296b55349Ssam 		break;
930c7b3a87Sbloom 	case RR:
940c7b3a87Sbloom 		pk->p_rpr = val;
950c7b3a87Sbloom 		if (pk->p_rpr == pk->p_ps) {
960c7b3a87Sbloom 			DEBUG(9, "Reack count is %d\n", ++Reacks);
970c7b3a87Sbloom 			if (Reacks >= 4) {
980c7b3a87Sbloom 				DEBUG(6, "Reack overflow on %d\n", val);
990c7b3a87Sbloom 				pk->p_state |= RXMIT;
1000c7b3a87Sbloom 				pk->p_msg |= M_RR;
1010c7b3a87Sbloom 				Reacks = 0;
1020c7b3a87Sbloom 			}
1030c7b3a87Sbloom 		} else {
1040c7b3a87Sbloom 			Reacks = 0;
1050c7b3a87Sbloom 			(void) pksack(pk);
1060c7b3a87Sbloom 		}
1070c7b3a87Sbloom 		break;
10896b55349Ssam 	case SRJ:
109893f18ccSralph 		logent("PK0", "srj not implemented");
11096b55349Ssam 		break;
11196b55349Ssam 	case CLOSE:
11296b55349Ssam 		pk->p_state = DOWN+RCLOSE;
11396b55349Ssam 		return;
11496b55349Ssam 	}
11596b55349Ssam 	if (pk->p_msg)
11696b55349Ssam 		pkoutput(pk);
11796b55349Ssam }
11896b55349Ssam 
pkaccept(pk)11996b55349Ssam pkaccept(pk)
12096b55349Ssam register struct pack *pk;
12196b55349Ssam {
12296b55349Ssam 	register x, seq;
12396b55349Ssam 	char m, cntl, *p, imask, **bp;
124893f18ccSralph 	int bad, accept, skip, t,  cc;
12596b55349Ssam 	unsigned short sum;
12696b55349Ssam 
12796b55349Ssam 	bad = accept = skip = 0;
12896b55349Ssam 	/*
12996b55349Ssam 	 * wait for input
13096b55349Ssam 	 */
13196b55349Ssam 	x = next[pk->p_pr];
13296b55349Ssam 	while ((imask=pk->p_imap) == 0 && pk->p_rcount == 0) {
133893f18ccSralph 		pkgetpack(pk);
13496b55349Ssam 	}
13596b55349Ssam 	pk->p_imap = 0;
13696b55349Ssam 
13796b55349Ssam 	/*
13896b55349Ssam 	 * determine input window in m.
13996b55349Ssam 	 */
14096b55349Ssam 	t = (~(-1<<(int)(pk->p_rwindow))) <<x;
14196b55349Ssam 	m = t;
14296b55349Ssam 	m |= t>>8;
14396b55349Ssam 
14496b55349Ssam 	/*
14596b55349Ssam 	 * mark newly accepted input buffers
14696b55349Ssam 	 */
14796b55349Ssam 	for(x=0; x<8; x++) {
14896b55349Ssam 		if ((imask & mask[x]) == 0)
14996b55349Ssam 			continue;
15096b55349Ssam 
15196b55349Ssam 		if (((cntl=pk->p_is[x])&0200) == 0) {
15296b55349Ssam 			bad++;
15396b55349Ssam free:
15496b55349Ssam 			bp = (char **)pk->p_ib[x];
15596b55349Ssam 			*bp = (char *)pk->p_ipool;
15696b55349Ssam 			pk->p_ipool = bp;
15796b55349Ssam 			pk->p_is[x] = 0;
15896b55349Ssam 			continue;
15996b55349Ssam 		}
16096b55349Ssam 
16196b55349Ssam 		pk->p_is[x] = ~(B_COPY+B_MARK);
16296b55349Ssam 		sum = (unsigned)chksum(pk->p_ib[x], pk->p_rsize) ^ (unsigned)(cntl&0377);
16396b55349Ssam 		sum += pk->p_isum[x];
16496b55349Ssam 		if (sum == CHECK) {
16596b55349Ssam 			seq = (cntl>>3) & MOD8;
16696b55349Ssam 			if (m & mask[seq]) {
16796b55349Ssam 				if (pk->p_is[seq] & (B_COPY | B_MARK)) {
16896b55349Ssam 				dup:
16996b55349Ssam 					pk->p_msg |= M_RR;
17096b55349Ssam 					skip++;
17196b55349Ssam 					goto free;
17296b55349Ssam 				}
17396b55349Ssam 				if (x != seq) {
17496b55349Ssam 					p = pk->p_ib[x];
17596b55349Ssam 					pk->p_ib[x] = pk->p_ib[seq];
17696b55349Ssam 					pk->p_is[x] = pk->p_is[seq];
17796b55349Ssam 					pk->p_ib[seq] = p;
17896b55349Ssam 				}
17996b55349Ssam 				pk->p_is[seq] = B_MARK;
18096b55349Ssam 				accept++;
18196b55349Ssam 				cc = 0;
18296b55349Ssam 				if (cntl&B_SHORT) {
18396b55349Ssam 					pk->p_is[seq] = B_MARK+B_SHORT;
18496b55349Ssam 					p = pk->p_ib[seq];
18596b55349Ssam 					cc = (unsigned)*p++ & 0377;
18696b55349Ssam 					if (cc & 0200) {
18796b55349Ssam 						cc &= 0177;
18896b55349Ssam 						cc |= *p << 7;
18996b55349Ssam 					}
19096b55349Ssam 				}
19196b55349Ssam 				pk->p_isum[seq] = pk->p_rsize - cc;
19296b55349Ssam 			} else {
19396b55349Ssam 				goto dup;
19496b55349Ssam 			}
19596b55349Ssam 		} else {
19696b55349Ssam 			bad++;
19796b55349Ssam 			goto free;
19896b55349Ssam 		}
19996b55349Ssam 	}
20096b55349Ssam 
20196b55349Ssam 	/*
20296b55349Ssam 	 * scan window again turning marked buffers into
20396b55349Ssam 	 * COPY buffers and looking for missing sequence
20496b55349Ssam 	 * numbers.
20596b55349Ssam 	 */
20696b55349Ssam 	accept = 0;
207893f18ccSralph 	t = -1;
208893f18ccSralph 	for(x=next[pk->p_pr]; m & mask[x]; x = next[x]) {
20996b55349Ssam 		if (pk->p_is[x] & B_MARK)
21096b55349Ssam 			pk->p_is[x] |= B_COPY;
211893f18ccSralph 
21296b55349Ssam 		if (pk->p_is[x] & B_COPY) {
21396b55349Ssam 			if (t >= 0) {
21496b55349Ssam 				bp = (char **)pk->p_ib[x];
21596b55349Ssam 				*bp = (char *)pk->p_ipool;
21696b55349Ssam 				pk->p_ipool = bp;
21796b55349Ssam 				pk->p_is[x] = 0;
21896b55349Ssam 				skip++;
21996b55349Ssam 			} else
22096b55349Ssam 				accept++;
22196b55349Ssam 		} else {
22296b55349Ssam 			if (t<0)
22396b55349Ssam 				t = x;
22496b55349Ssam 		}
22596b55349Ssam 	}
22696b55349Ssam 
22796b55349Ssam 	if (bad) {
22896b55349Ssam 		pk->p_msg |= M_RJ;
22996b55349Ssam 	}
23096b55349Ssam 
23196b55349Ssam 	if (skip) {
23296b55349Ssam 		pk->p_msg |= M_RR;
23396b55349Ssam 	}
23496b55349Ssam 
23596b55349Ssam 	pk->p_rcount = accept;
236893f18ccSralph 	return accept;
23796b55349Ssam }
23896b55349Ssam 
239893f18ccSralph /*ARGSUSED*/
pkread(pk,ibuf,icount)240e072a0e3Sbloom pkread(pk, ibuf, icount)
24196b55349Ssam register struct pack *pk;
242e072a0e3Sbloom char *ibuf;
243e072a0e3Sbloom int icount;
244e072a0e3Sbloom {
245893f18ccSralph 	register x;
24696b55349Ssam 	int is, cc, xfr, count;
24796b55349Ssam 	char *cp, **bp;
24896b55349Ssam 
24996b55349Ssam 	xfr = 0;
25096b55349Ssam 	count = 0;
2510c7b3a87Sbloom 	pktimeout = PKRTIME;
2520c7b3a87Sbloom 	pktimeskew = PKRSKEW;
253adca94fdSbloom 	Ntimeout = 0;
254893f18ccSralph 	while (pkaccept(pk) == 0)
255893f18ccSralph 		;
25696b55349Ssam 
257893f18ccSralph 	while (icount) {
25896b55349Ssam 		x = next[pk->p_pr];
25996b55349Ssam 		is = pk->p_is[x];
26096b55349Ssam 
26196b55349Ssam 		if (is & B_COPY) {
262893f18ccSralph 			cc = MIN(pk->p_isum[x], icount);
26396b55349Ssam 			if (cc==0 && xfr) {
26496b55349Ssam 				break;
26596b55349Ssam 			}
26696b55349Ssam 			if (is & B_RESID)
26796b55349Ssam 				cp = pk->p_rptr;
26896b55349Ssam 			else {
26996b55349Ssam 				cp = pk->p_ib[x];
27096b55349Ssam 				if (is & B_SHORT) {
27196b55349Ssam 					if (*cp++ & 0200)
27296b55349Ssam 						cp++;
27396b55349Ssam 				}
27496b55349Ssam 			}
275fb456bffSrick 			bcopy(cp, ibuf, cc);
276893f18ccSralph 			ibuf += cc;
277893f18ccSralph 			icount -= cc;
27896b55349Ssam 			count += cc;
27996b55349Ssam 			xfr++;
28096b55349Ssam 			pk->p_isum[x] -= cc;
28196b55349Ssam 			if (pk->p_isum[x] == 0) {
28296b55349Ssam 				pk->p_pr = x;
28396b55349Ssam 				bp = (char **)pk->p_ib[x];
28496b55349Ssam 				*bp = (char *)pk->p_ipool;
28596b55349Ssam 				pk->p_ipool = bp;
28696b55349Ssam 				pk->p_is[x] = 0;
28796b55349Ssam 				pk->p_rcount--;
28896b55349Ssam 				pk->p_msg |= M_RR;
28996b55349Ssam 			} else {
29096b55349Ssam 				pk->p_rptr = cp+cc;
29196b55349Ssam 				pk->p_is[x] |= B_RESID;
29296b55349Ssam 			}
29396b55349Ssam 			if (cc==0)
29496b55349Ssam 				break;
29596b55349Ssam 		} else
29696b55349Ssam 			break;
29796b55349Ssam 	}
29896b55349Ssam 	pkoutput(pk);
299893f18ccSralph 	return count;
30096b55349Ssam }
30196b55349Ssam 
302893f18ccSralph /*ARGSUSED*/
pkwrite(pk,ibuf,icount)303e072a0e3Sbloom pkwrite(pk, ibuf, icount)
304e072a0e3Sbloom register struct pack *pk;
305893f18ccSralph char *ibuf;
306893f18ccSralph int icount;
30796b55349Ssam {
30896b55349Ssam 	register x;
30996b55349Ssam 	int partial;
31096b55349Ssam 	caddr_t cp;
311893f18ccSralph 	int cc, fc, count;
31296b55349Ssam 
31396b55349Ssam 	if (pk->p_state&DOWN || !pk->p_state&LIVE) {
314893f18ccSralph 		return -1;
31596b55349Ssam 	}
31696b55349Ssam 
3170c7b3a87Sbloom 	pktimeout = PKWTIME;
3180c7b3a87Sbloom 	pktimeskew = PKWSKEW;
319adca94fdSbloom 	Ntimeout = 0;
320893f18ccSralph 	count = icount;
32196b55349Ssam 	do {
32296b55349Ssam 		while (pk->p_xcount>=pk->p_swindow)  {
32396b55349Ssam 			pkoutput(pk);
324893f18ccSralph 			pkgetpack(pk);
32596b55349Ssam 		}
32696b55349Ssam 		x = next[pk->p_pscopy];
32796b55349Ssam 		while (pk->p_os[x]!=B_NULL)  {
328893f18ccSralph 			pkgetpack(pk);
32996b55349Ssam 		}
33096b55349Ssam 		pk->p_os[x] = B_MARK;
33196b55349Ssam 		pk->p_pscopy = x;
33296b55349Ssam 		pk->p_xcount++;
33396b55349Ssam 
334893f18ccSralph 		cp = pk->p_ob[x] = malloc((unsigned)pk->p_xsize);
33596b55349Ssam 		partial = 0;
336893f18ccSralph 		if ((int)icount < pk->p_xsize) {
337893f18ccSralph 			cc = icount;
33896b55349Ssam 			fc = pk->p_xsize - cc;
33996b55349Ssam 			*cp = fc&0177;
34096b55349Ssam 			if (fc > 127) {
34196b55349Ssam 				*cp++ |= 0200;
34296b55349Ssam 				*cp++ = fc>>7;
34396b55349Ssam 			} else
34496b55349Ssam 				cp++;
34596b55349Ssam 			partial = B_SHORT;
34696b55349Ssam 		} else
34796b55349Ssam 			cc = pk->p_xsize;
348fb456bffSrick 		bcopy(ibuf, cp, cc);
349893f18ccSralph 		ibuf += cc;
350893f18ccSralph 		icount -= cc;
35196b55349Ssam 		pk->p_osum[x] = chksum(pk->p_ob[x], pk->p_xsize);
35296b55349Ssam 		pk->p_os[x] = B_READY+partial;
35396b55349Ssam 		pkoutput(pk);
354893f18ccSralph 	} while (icount);
35596b55349Ssam 
356893f18ccSralph 	return count;
35796b55349Ssam }
35896b55349Ssam 
pksack(pk)35996b55349Ssam pksack(pk)
36096b55349Ssam register struct pack *pk;
36196b55349Ssam {
36296b55349Ssam 	register x, i;
36396b55349Ssam 
36496b55349Ssam 	i = 0;
36596b55349Ssam 	for(x=pk->p_ps; x!=pk->p_rpr; ) {
36696b55349Ssam 		x = next[x];
36796b55349Ssam 		if (pk->p_os[x]&B_SENT) {
36896b55349Ssam 			i++;
36996b55349Ssam 			pk->p_os[x] = B_NULL;
37096b55349Ssam 			pk->p_state &= ~WAITO;
37196b55349Ssam 			pk->p_xcount--;
372893f18ccSralph 			free((char *)pk->p_ob[x]);
37396b55349Ssam 			pk->p_ps = x;
37496b55349Ssam 		}
37596b55349Ssam 	}
376893f18ccSralph 	return i;
37796b55349Ssam }
37896b55349Ssam 
pkoutput(pk)37996b55349Ssam pkoutput(pk)
38096b55349Ssam register struct pack *pk;
38196b55349Ssam {
382893f18ccSralph 	register x;
38396b55349Ssam 	int i;
384893f18ccSralph 	char bstate;
38596b55349Ssam 
386893f18ccSralph 	if (pk->p_obusy++) {
38796b55349Ssam 		pk->p_obusy--;
38896b55349Ssam 		return;
38996b55349Ssam 	}
39096b55349Ssam 
39196b55349Ssam 	/*
39296b55349Ssam 	 * find seq number and buffer state
39396b55349Ssam 	 * of next output packet
39496b55349Ssam 	 */
39596b55349Ssam 	if (pk->p_state&RXMIT)  {
39696b55349Ssam 		pk->p_nxtps = next[pk->p_rpr];
39796b55349Ssam 	}
39896b55349Ssam 	x = pk->p_nxtps;
39996b55349Ssam 	bstate = pk->p_os[x];
40096b55349Ssam 
40196b55349Ssam 	/*
40296b55349Ssam 	 * Send control packet if indicated
40396b55349Ssam 	 */
40496b55349Ssam 	if (pk->p_msg) {
40596b55349Ssam 		if (pk->p_msg & ~M_RR || !(bstate&B_READY) ) {
40696b55349Ssam 			x = pk->p_msg;
40796b55349Ssam 			for(i=0; i<8; i++)
40896b55349Ssam 				if (x&1)
409893f18ccSralph 					break;
410893f18ccSralph 				else
41196b55349Ssam 					x >>= 1;
41296b55349Ssam 			x = i;
41396b55349Ssam 			x <<= 3;
41496b55349Ssam 			switch(i) {
41596b55349Ssam 			case CLOSE:
41696b55349Ssam 				break;
41796b55349Ssam 			case RJ:
41896b55349Ssam 			case RR:
41996b55349Ssam 				x += pk->p_pr;
42096b55349Ssam 				break;
42196b55349Ssam 			case SRJ:
42296b55349Ssam 				break;
42396b55349Ssam 			case INITB:
42496b55349Ssam 				x += pksize(pk->p_rsize);
42596b55349Ssam 				break;
42696b55349Ssam 			case INITC:
42796b55349Ssam 				x += pk->p_rwindow;
42896b55349Ssam 				break;
42996b55349Ssam 			case INITA:
43096b55349Ssam 				x += pk->p_rwindow;
43196b55349Ssam 				break;
43296b55349Ssam 			}
43396b55349Ssam 
43496b55349Ssam 			pk->p_msg &= ~mask[i];
43596b55349Ssam 			pkxstart(pk, x, -1);
43696b55349Ssam 			goto out;
43796b55349Ssam 		}
43896b55349Ssam 	}
43996b55349Ssam 
44096b55349Ssam 
44196b55349Ssam 	/*
44296b55349Ssam 	 * Don't send data packets if line is marked dead.
44396b55349Ssam 	 */
44496b55349Ssam 	if (pk->p_state&DOWN) {
44596b55349Ssam 		goto out;
44696b55349Ssam 	}
44796b55349Ssam 	/*
44896b55349Ssam 	 * Start transmission (or retransmission) of data packets.
44996b55349Ssam 	 */
45096b55349Ssam 	if (bstate & (B_READY|B_SENT)) {
45196b55349Ssam 		char seq;
45296b55349Ssam 
45396b55349Ssam 		bstate |= B_SENT;
45496b55349Ssam 		seq = x;
45596b55349Ssam 		pk->p_nxtps = next[x];
45696b55349Ssam 
45796b55349Ssam 		x = 0200+pk->p_pr+(seq<<3);
45896b55349Ssam 		if (bstate & B_SHORT)
45996b55349Ssam 			x |= 0100;
46096b55349Ssam 		pkxstart(pk, x, seq);
46196b55349Ssam 		pk->p_os[seq] = bstate;
46296b55349Ssam 		pk->p_state &= ~RXMIT;
46396b55349Ssam 		goto out;
46496b55349Ssam 	}
46596b55349Ssam 	/*
46696b55349Ssam 	 * enable timeout if there's nothing to send
46796b55349Ssam 	 * and transmission buffers are languishing
46896b55349Ssam 	 */
46996b55349Ssam 	if (pk->p_xcount) {
47096b55349Ssam 		pk->p_state |= WAITO;
47196b55349Ssam 	} else
47296b55349Ssam 		pk->p_state &= ~WAITO;
47396b55349Ssam out:
47496b55349Ssam 	pk->p_obusy = 0;
47596b55349Ssam }
47696b55349Ssam 
47796b55349Ssam /*
47896b55349Ssam  * shut down line by
47996b55349Ssam  *	ignoring new input
48096b55349Ssam  *	letting output drain
48196b55349Ssam  *	releasing space and turning off line discipline
48296b55349Ssam  */
483893f18ccSralph /*ARGSUSED*/
pkclose(pk)484e072a0e3Sbloom pkclose(pk)
48596b55349Ssam register struct pack *pk;
486e072a0e3Sbloom {
487e90e093fSralph 	register i;
48896b55349Ssam 	char **bp;
489e90e093fSralph 	int rcheck = 0;
49096b55349Ssam 
49196b55349Ssam 	pk->p_state |= DRAINO;
49296b55349Ssam 
49396b55349Ssam 	/*
49496b55349Ssam 	 * try to flush output
49596b55349Ssam 	 */
49696b55349Ssam 	i = 0;
49796b55349Ssam 	while (pk->p_xcount && pk->p_state&LIVE) {
49896b55349Ssam 		if (pk->p_state&(RCLOSE+DOWN) || ++i > 2)
49996b55349Ssam 			break;
50096b55349Ssam 		pkoutput(pk);
50196b55349Ssam 	}
50296b55349Ssam 	pk->p_state |= DOWN;
50396b55349Ssam 
50496b55349Ssam 	/*
50596b55349Ssam 	 * try to exchange CLOSE messages
50696b55349Ssam 	 */
50796b55349Ssam 	i = 0;
50896b55349Ssam 	while ((pk->p_state&RCLOSE)==0 && i<2) {
50996b55349Ssam 		pk->p_msg = M_CLOSE;
51096b55349Ssam 		pkoutput(pk);
51196b55349Ssam 		i++;
51296b55349Ssam 	}
51396b55349Ssam 
51496b55349Ssam 	for(i=0;i<NPLINES;i++)
51596b55349Ssam 		if (pklines[i]==pk)  {
51696b55349Ssam 			pklines[i] = NULL;
51796b55349Ssam 		}
51896b55349Ssam 
51996b55349Ssam 	/*
52096b55349Ssam 	 * free space
52196b55349Ssam 	 */
52296b55349Ssam 	rcheck = 0;
52396b55349Ssam 	for (i=0;i<8;i++) {
52496b55349Ssam 		if (pk->p_os[i] != B_NULL) {
525893f18ccSralph 			free((char *)pk->p_ob[i]);
52696b55349Ssam 			pk->p_xcount--;
52796b55349Ssam 		}
52896b55349Ssam 		if (pk->p_is[i] != B_NULL)  {
529893f18ccSralph 			free((char *)pk->p_ib[i]);
53096b55349Ssam 			rcheck++;
53196b55349Ssam 		}
53296b55349Ssam 	}
53396b55349Ssam 	while (pk->p_ipool != NULL) {
53496b55349Ssam 		bp = pk->p_ipool;
53596b55349Ssam 		pk->p_ipool = (char **)*bp;
53696b55349Ssam 		rcheck++;
537893f18ccSralph 		free((char *)bp);
53896b55349Ssam 	}
53996b55349Ssam 	if (rcheck != pk->p_rwindow) {
540fb456bffSrick 		syslog(LOG_WARNING, "%s: pk0: rc %d rw %d", Rmtname, rcheck,
541fb456bffSrick 			pk->p_rwindow);
54296b55349Ssam 	}
543893f18ccSralph 	free((char *)pk);
54496b55349Ssam }
54596b55349Ssam 
pkreset(pk)54696b55349Ssam pkreset(pk)
54796b55349Ssam register struct pack *pk;
54896b55349Ssam {
54996b55349Ssam 
55096b55349Ssam 	pk->p_ps = pk->p_pr =  pk->p_rpr = 0;
55196b55349Ssam 	pk->p_nxtps = 1;
55296b55349Ssam }
55396b55349Ssam 
554893f18ccSralph #ifndef BSD4_2
bzero(s,n)555893f18ccSralph bzero(s,n)
55696b55349Ssam register char *s;
55796b55349Ssam register n;
55896b55349Ssam {
55996b55349Ssam 	while (n--)
56096b55349Ssam 		*s++ = 0;
56196b55349Ssam }
562893f18ccSralph #endif !BSD4_2
56396b55349Ssam 
pksize(n)56496b55349Ssam pksize(n)
56596b55349Ssam register n;
56696b55349Ssam {
56796b55349Ssam 	register k;
56896b55349Ssam 
56996b55349Ssam 	n >>= 5;
570893f18ccSralph 	for(k=0; n >>= 1; k++)
571893f18ccSralph 		;
572893f18ccSralph 	return k;
57396b55349Ssam }
574