xref: /csrg-svn/libexec/rbootd/utils.c (revision 66233)
155579Sbostic /*
255579Sbostic  * Copyright (c) 1988, 1992 The University of Utah and the Center
355579Sbostic  *	for Software Science (CSS).
461443Sbostic  * Copyright (c) 1992, 1993
561443Sbostic  *	The Regents of the University of California.  All rights reserved.
655579Sbostic  *
755579Sbostic  * This code is derived from software contributed to Berkeley by
855579Sbostic  * the Center for Software Science of the University of Utah Computer
955579Sbostic  * Science Department.  CSS requests users of this software to return
1055579Sbostic  * to css-dist@cs.utah.edu any improvements that they make and grant
1155579Sbostic  * CSS redistribution rights.
1255579Sbostic  *
1355579Sbostic  * %sccs.include.redist.c%
1455579Sbostic  *
15*66233Sbostic  *	@(#)utils.c	8.2 (Berkeley) 02/22/94
1655579Sbostic  *
1755579Sbostic  * Utah $Hdr: utils.c 3.1 92/07/06$
1855579Sbostic  * Author: Jeff Forys, University of Utah CSS
1955579Sbostic  */
2055579Sbostic 
2155579Sbostic #ifndef lint
22*66233Sbostic static char sccsid[] = "@(#)utils.c	8.2 (Berkeley) 02/22/94";
2355579Sbostic #endif /* not lint */
2455579Sbostic 
2555600Sbostic #include <sys/param.h>
26*66233Sbostic #include <sys/time.h>
2755579Sbostic 
2855600Sbostic #include <fcntl.h>
2955600Sbostic #include <signal.h>
3055600Sbostic #include <stdio.h>
3155600Sbostic #include <stdlib.h>
3255600Sbostic #include <string.h>
3355579Sbostic #include <syslog.h>
3455600Sbostic #include <time.h>
3555600Sbostic #include <unistd.h>
3655600Sbostic #include "defs.h"
3755579Sbostic 
3855579Sbostic /*
3955579Sbostic **  DispPkt -- Display the contents of an RMPCONN packet.
4055579Sbostic **
4155579Sbostic **	Parameters:
4255579Sbostic **		rconn - packet to be displayed.
4355579Sbostic **		direct - direction packet is going (DIR_*).
4455579Sbostic **
4555579Sbostic **	Returns:
4655579Sbostic **		Nothing.
4755579Sbostic **
4855579Sbostic **	Side Effects:
4955579Sbostic **		None.
5055579Sbostic */
5155600Sbostic void
DispPkt(rconn,direct)5255579Sbostic DispPkt(rconn, direct)
5355600Sbostic 	RMPCONN *rconn;
5455600Sbostic 	int direct;
5555579Sbostic {
5655579Sbostic 	static char BootFmt[] = "\t\tRetCode:%u SeqNo:%lx SessID:%x Vers:%u";
5755579Sbostic 	static char ReadFmt[] = "\t\tRetCode:%u Offset:%lx SessID:%x\n";
5855579Sbostic 
5955579Sbostic 	struct tm *tmp;
6055579Sbostic 	register struct rmp_packet *rmp;
6155579Sbostic 	int i, omask;
6255579Sbostic 	u_int t;
6355579Sbostic 
6455579Sbostic 	/*
6555579Sbostic 	 *  Since we will be working with RmpConns as well as DbgFp, we
6655579Sbostic 	 *  must block signals that can affect either.
6755579Sbostic 	 */
6855579Sbostic 	omask = sigblock(sigmask(SIGHUP)|sigmask(SIGUSR1)|sigmask(SIGUSR2));
6955579Sbostic 
7055579Sbostic 	if (DbgFp == NULL) {			/* sanity */
7155579Sbostic 		(void) sigsetmask(omask);
7255579Sbostic 		return;
7355579Sbostic 	}
7455579Sbostic 
7555579Sbostic 	/* display direction packet is going using '>>>' or '<<<' */
7655579Sbostic 	fputs((direct==DIR_RCVD)?"<<< ":(direct==DIR_SENT)?">>> ":"", DbgFp);
7755579Sbostic 
7855579Sbostic 	/* display packet timestamp */
7955579Sbostic 	tmp = localtime((time_t *)&rconn->tstamp.tv_sec);
8055579Sbostic 	fprintf(DbgFp, "%02d:%02d:%02d.%06ld   ", tmp->tm_hour, tmp->tm_min,
8155579Sbostic 	        tmp->tm_sec, rconn->tstamp.tv_usec);
8255579Sbostic 
8355579Sbostic 	/* display src or dst addr and information about network interface */
8455579Sbostic 	fprintf(DbgFp, "Addr: %s   Intf: %s\n", EnetStr(rconn), IntfName);
8555579Sbostic 
8655579Sbostic 	rmp = &rconn->rmp;
8755579Sbostic 
8855579Sbostic 	/* display IEEE 802.2 Logical Link Control header */
8955579Sbostic 	(void) fprintf(DbgFp, "\t802.2 LLC: DSAP:%x SSAP:%x CTRL:%x\n",
9055579Sbostic 	               rmp->hp_llc.dsap, rmp->hp_llc.ssap, rmp->hp_llc.cntrl);
9155579Sbostic 
9255579Sbostic 	/* display HP extensions to 802.2 Logical Link Control header */
9355579Sbostic 	(void) fprintf(DbgFp, "\tHP Ext:    DXSAP:%x SXSAP:%x\n",
9455579Sbostic 	               rmp->hp_llc.dxsap, rmp->hp_llc.sxsap);
9555579Sbostic 
9655579Sbostic 	/*
9755579Sbostic 	 *  Display information about RMP packet using type field to
9855579Sbostic 	 *  determine what kind of packet this is.
9955579Sbostic 	 */
10055579Sbostic 	switch(rmp->r_type) {
10155579Sbostic 		case RMP_BOOT_REQ:		/* boot request */
10255579Sbostic 			(void) fprintf(DbgFp, "\tBoot Request:");
10355579Sbostic 			GETWORD(rmp->r_brq.rmp_seqno, t);
10455579Sbostic 			if (rmp->r_brq.rmp_session == RMP_PROBESID) {
10555579Sbostic 				if (WORDZE(rmp->r_brq.rmp_seqno))
10655579Sbostic 					fputs(" (Send Server ID)", DbgFp);
10755579Sbostic 				else
10855579Sbostic 					fprintf(DbgFp," (Send Filename #%u)",t);
10955579Sbostic 			}
11055579Sbostic 			(void) fputc('\n', DbgFp);
11155579Sbostic 			(void) fprintf(DbgFp, BootFmt, rmp->r_brq.rmp_retcode,
11255579Sbostic 			        t, rmp->r_brq.rmp_session,
11355579Sbostic 			        rmp->r_brq.rmp_version);
11455579Sbostic 			(void) fprintf(DbgFp, "\n\t\tMachine Type: ");
11555579Sbostic 			for (i = 0; i < RMP_MACHLEN; i++)
11655579Sbostic 				(void) fputc(rmp->r_brq.rmp_machtype[i], DbgFp);
11755579Sbostic 			DspFlnm(rmp->r_brq.rmp_flnmsize, &rmp->r_brq.rmp_flnm);
11855579Sbostic 			break;
11955579Sbostic 		case RMP_BOOT_REPL:		/* boot reply */
12055579Sbostic 			fprintf(DbgFp, "\tBoot Reply:\n");
12155579Sbostic 			GETWORD(rmp->r_brpl.rmp_seqno, t);
12255579Sbostic 			(void) fprintf(DbgFp, BootFmt, rmp->r_brpl.rmp_retcode,
12355579Sbostic 			        t, rmp->r_brpl.rmp_session,
12455579Sbostic 			        rmp->r_brpl.rmp_version);
12555579Sbostic 			DspFlnm(rmp->r_brpl.rmp_flnmsize,&rmp->r_brpl.rmp_flnm);
12655579Sbostic 			break;
12755579Sbostic 		case RMP_READ_REQ:		/* read request */
12855579Sbostic 			(void) fprintf(DbgFp, "\tRead Request:\n");
12955579Sbostic 			GETWORD(rmp->r_rrq.rmp_offset, t);
13055579Sbostic 			(void) fprintf(DbgFp, ReadFmt, rmp->r_rrq.rmp_retcode,
13155579Sbostic 			        t, rmp->r_rrq.rmp_session);
13255579Sbostic 			(void) fprintf(DbgFp, "\t\tNoOfBytes: %u\n",
13355579Sbostic 			        rmp->r_rrq.rmp_size);
13455579Sbostic 			break;
13555579Sbostic 		case RMP_READ_REPL:		/* read reply */
13655579Sbostic 			(void) fprintf(DbgFp, "\tRead Reply:\n");
13755579Sbostic 			GETWORD(rmp->r_rrpl.rmp_offset, t);
13855579Sbostic 			(void) fprintf(DbgFp, ReadFmt, rmp->r_rrpl.rmp_retcode,
13955579Sbostic 			        t, rmp->r_rrpl.rmp_session);
14055579Sbostic 			(void) fprintf(DbgFp, "\t\tNoOfBytesSent: %d\n",
14155579Sbostic 			        rconn->rmplen - RMPREADSIZE(0));
14255579Sbostic 			break;
14355579Sbostic 		case RMP_BOOT_DONE:		/* boot complete */
14455579Sbostic 			(void) fprintf(DbgFp, "\tBoot Complete:\n");
14555579Sbostic 			(void) fprintf(DbgFp, "\t\tRetCode:%u SessID:%x\n",
14655579Sbostic 			        rmp->r_done.rmp_retcode,
14755579Sbostic 			        rmp->r_done.rmp_session);
14855579Sbostic 			break;
14955579Sbostic 		default:			/* ??? */
15055579Sbostic 			(void) fprintf(DbgFp, "\tUnknown Type:(%d)\n",
15155579Sbostic 				rmp->r_type);
15255579Sbostic 	}
15355579Sbostic 	(void) fputc('\n', DbgFp);
15455579Sbostic 	(void) fflush(DbgFp);
15555579Sbostic 
15655579Sbostic 	(void) sigsetmask(omask);		/* reset old signal mask */
15755579Sbostic }
15855579Sbostic 
15955579Sbostic 
16055579Sbostic /*
16155579Sbostic **  GetEtherAddr -- convert an RMP (Ethernet) address into a string.
16255579Sbostic **
16355579Sbostic **	An RMP BOOT packet has been received.  Look at the type field
16455579Sbostic **	and process Boot Requests, Read Requests, and Boot Complete
16555579Sbostic **	packets.  Any other type will be dropped with a warning msg.
16655579Sbostic **
16755579Sbostic **	Parameters:
16855579Sbostic **		addr - array of RMP_ADDRLEN bytes.
16955579Sbostic **
17055579Sbostic **	Returns:
17155579Sbostic **		Pointer to static string representation of `addr'.
17255579Sbostic **
17355579Sbostic **	Side Effects:
17455579Sbostic **		None.
17555579Sbostic **
17655579Sbostic **	Warnings:
17755579Sbostic **		- The return value points to a static buffer; it must
17855579Sbostic **		  be copied if it's to be saved.
17955579Sbostic **		- For speed, we assume a u_char consists of 8 bits.
18055579Sbostic */
18155579Sbostic char *
GetEtherAddr(addr)18255579Sbostic GetEtherAddr(addr)
18355600Sbostic 	u_char *addr;
18455579Sbostic {
18555579Sbostic 	static char Hex[] = "0123456789abcdef";
18655579Sbostic 	static char etherstr[RMP_ADDRLEN*3];
18755579Sbostic 	register int i;
18855579Sbostic 	register char *cp1, *cp2;
18955579Sbostic 
19055579Sbostic 	/*
19155579Sbostic 	 *  For each byte in `addr', convert it to "<hexchar><hexchar>:".
19255579Sbostic 	 *  The last byte does not get a trailing `:' appended.
19355579Sbostic 	 */
19455579Sbostic 	i = 0;
19555579Sbostic 	cp1 = (char *)addr;
19655579Sbostic 	cp2 = etherstr;
19755579Sbostic 	for(;;) {
19855579Sbostic 		*cp2++ = Hex[*cp1 >> 4 & 0xf];
19955579Sbostic 		*cp2++ = Hex[*cp1++ & 0xf];
20055579Sbostic 		if (++i == RMP_ADDRLEN)
20155579Sbostic 			break;
20255579Sbostic 		*cp2++ = ':';
20355579Sbostic 	}
20455579Sbostic 	*cp2 = '\0';
20555579Sbostic 
20655579Sbostic 	return(etherstr);
20755579Sbostic }
20855579Sbostic 
20955579Sbostic 
21055579Sbostic /*
21155579Sbostic **  DispFlnm -- Print a string of bytes to DbgFp (often, a file name).
21255579Sbostic **
21355579Sbostic **	Parameters:
21455579Sbostic **		size - number of bytes to print.
21555579Sbostic **		flnm - address of first byte.
21655579Sbostic **
21755579Sbostic **	Returns:
21855579Sbostic **		Nothing.
21955579Sbostic **
22055579Sbostic **	Side Effects:
22155579Sbostic **		- Characters are sent to `DbgFp'.
22255579Sbostic */
22355600Sbostic void
DspFlnm(size,flnm)22455579Sbostic DspFlnm(size, flnm)
22555600Sbostic 	register u_int size;
22655600Sbostic 	register char *flnm;
22755579Sbostic {
22855579Sbostic 	register int i;
22955579Sbostic 
23055579Sbostic 	(void) fprintf(DbgFp, "\n\t\tFile Name (%d): <", size);
23155579Sbostic 	for (i = 0; i < size; i++)
23255579Sbostic 		(void) fputc(*flnm++, DbgFp);
23355579Sbostic 	(void) fputs(">\n", DbgFp);
23455579Sbostic }
23555579Sbostic 
23655579Sbostic 
23755579Sbostic /*
23855579Sbostic **  NewClient -- allocate memory for a new CLIENT.
23955579Sbostic **
24055579Sbostic **	Parameters:
24155579Sbostic **		addr - RMP (Ethernet) address of new client.
24255579Sbostic **
24355579Sbostic **	Returns:
24455579Sbostic **		Ptr to new CLIENT or NULL if we ran out of memory.
24555579Sbostic **
24655579Sbostic **	Side Effects:
24755579Sbostic **		- Memory will be malloc'd for the new CLIENT.
24855579Sbostic **		- If malloc() fails, a log message will be generated.
24955579Sbostic */
25055579Sbostic CLIENT *
NewClient(addr)25155579Sbostic NewClient(addr)
25255600Sbostic 	u_char *addr;
25355579Sbostic {
25455579Sbostic 	CLIENT *ctmp;
25555579Sbostic 
25655579Sbostic 	if ((ctmp = (CLIENT *) malloc(sizeof(CLIENT))) == NULL) {
25755579Sbostic 		syslog(LOG_ERR, "NewClient: out of memory (%s)",
25855579Sbostic 		       GetEtherAddr(addr));
25955579Sbostic 		return(NULL);
26055579Sbostic 	}
26155579Sbostic 
26255600Sbostic 	bzero(ctmp, sizeof(CLIENT));
26355600Sbostic 	bcopy(addr, &ctmp->addr[0], RMP_ADDRLEN);
26455579Sbostic 	return(ctmp);
26555579Sbostic }
26655579Sbostic 
26755579Sbostic /*
26855579Sbostic **  FreeClient -- free linked list of Clients.
26955579Sbostic **
27055579Sbostic **	Parameters:
27155579Sbostic **		None.
27255579Sbostic **
27355579Sbostic **	Returns:
27455579Sbostic **		Nothing.
27555579Sbostic **
27655579Sbostic **	Side Effects:
27755579Sbostic **		- All malloc'd memory associated with the linked list of
27855579Sbostic **		  CLIENTS will be free'd; `Clients' will be set to NULL.
27955579Sbostic **
28055579Sbostic **	Warnings:
28155579Sbostic **		- This routine must be called with SIGHUP blocked.
28255579Sbostic */
28355600Sbostic void
FreeClients()28455579Sbostic FreeClients()
28555579Sbostic {
28655579Sbostic 	register CLIENT *ctmp;
28755579Sbostic 
28855579Sbostic 	while (Clients != NULL) {
28955579Sbostic 		ctmp = Clients;
29055579Sbostic 		Clients = Clients->next;
29155579Sbostic 		FreeClient(ctmp);
29255579Sbostic 	}
29355579Sbostic }
29455579Sbostic 
29555579Sbostic /*
29655579Sbostic **  NewStr -- allocate memory for a character array.
29755579Sbostic **
29855579Sbostic **	Parameters:
29955579Sbostic **		str - null terminated character array.
30055579Sbostic **
30155579Sbostic **	Returns:
30255579Sbostic **		Ptr to new character array or NULL if we ran out of memory.
30355579Sbostic **
30455579Sbostic **	Side Effects:
30555579Sbostic **		- Memory will be malloc'd for the new character array.
30655579Sbostic **		- If malloc() fails, a log message will be generated.
30755579Sbostic */
30855579Sbostic char *
NewStr(str)30955579Sbostic NewStr(str)
31055600Sbostic 	char *str;
31155579Sbostic {
31255579Sbostic 	char *stmp;
31355579Sbostic 
31455579Sbostic 	if ((stmp = (char *)malloc((unsigned) (strlen(str)+1))) == NULL) {
31555579Sbostic 		syslog(LOG_ERR, "NewStr: out of memory (%s)", str);
31655579Sbostic 		return(NULL);
31755579Sbostic 	}
31855579Sbostic 
31955579Sbostic 	(void) strcpy(stmp, str);
32055579Sbostic 	return(stmp);
32155579Sbostic }
32255579Sbostic 
32355579Sbostic /*
32455579Sbostic **  To save time, NewConn and FreeConn maintain a cache of one RMPCONN
32555579Sbostic **  in `LastFree' (defined below).
32655579Sbostic */
32755579Sbostic 
32855579Sbostic static RMPCONN *LastFree = NULL;
32955579Sbostic 
33055579Sbostic /*
33155579Sbostic **  NewConn -- allocate memory for a new RMPCONN connection.
33255579Sbostic **
33355579Sbostic **	Parameters:
33455579Sbostic **		rconn - initialization template for new connection.
33555579Sbostic **
33655579Sbostic **	Returns:
33755579Sbostic **		Ptr to new RMPCONN or NULL if we ran out of memory.
33855579Sbostic **
33955579Sbostic **	Side Effects:
34055579Sbostic **		- Memory may be malloc'd for the new RMPCONN (if not cached).
34155579Sbostic **		- If malloc() fails, a log message will be generated.
34255579Sbostic */
34355579Sbostic RMPCONN *
NewConn(rconn)34455579Sbostic NewConn(rconn)
34555600Sbostic 	RMPCONN *rconn;
34655579Sbostic {
34755579Sbostic 	RMPCONN *rtmp;
34855579Sbostic 
34955579Sbostic 	if (LastFree == NULL) {		/* nothing cached; make a new one */
35055579Sbostic 		if ((rtmp = (RMPCONN *) malloc(sizeof(RMPCONN))) == NULL) {
35155579Sbostic 			syslog(LOG_ERR, "NewConn: out of memory (%s)",
35255579Sbostic 			       EnetStr(rconn));
35355579Sbostic 			return(NULL);
35455579Sbostic 		}
35555579Sbostic 	} else {			/* use the cached RMPCONN */
35655579Sbostic 		rtmp = LastFree;
35755579Sbostic 		LastFree = NULL;
35855579Sbostic 	}
35955579Sbostic 
36055579Sbostic 	/*
36155579Sbostic 	 *  Copy template into `rtmp', init file descriptor to `-1' and
36255579Sbostic 	 *  set ptr to next elem NULL.
36355579Sbostic 	 */
36455579Sbostic 	bcopy((char *)rconn, (char *)rtmp, sizeof(RMPCONN));
36555579Sbostic 	rtmp->bootfd = -1;
36655579Sbostic 	rtmp->next = NULL;
36755579Sbostic 
36855579Sbostic 	return(rtmp);
36955579Sbostic }
37055579Sbostic 
37155579Sbostic /*
37255579Sbostic **  FreeConn -- Free memory associated with an RMPCONN connection.
37355579Sbostic **
37455579Sbostic **	Parameters:
37555579Sbostic **		rtmp - ptr to RMPCONN to be free'd.
37655579Sbostic **
37755579Sbostic **	Returns:
37855579Sbostic **		Nothing.
37955579Sbostic **
38055579Sbostic **	Side Effects:
38155579Sbostic **		- Memory associated with `rtmp' may be free'd (or cached).
38255579Sbostic **		- File desc associated with `rtmp->bootfd' will be closed.
38355579Sbostic */
38455600Sbostic void
FreeConn(rtmp)38555579Sbostic FreeConn(rtmp)
38655600Sbostic 	register RMPCONN *rtmp;
38755579Sbostic {
38855579Sbostic 	/*
38955579Sbostic 	 *  If the file descriptor is in use, close the file.
39055579Sbostic 	 */
39155579Sbostic 	if (rtmp->bootfd >= 0) {
39255579Sbostic 		(void) close(rtmp->bootfd);
39355579Sbostic 		rtmp->bootfd = -1;
39455579Sbostic 	}
39555579Sbostic 
39655579Sbostic 	if (LastFree == NULL)		/* cache for next time */
39755579Sbostic 		rtmp = LastFree;
39855579Sbostic 	else				/* already one cached; free this one */
39955579Sbostic 		free((char *)rtmp);
40055579Sbostic }
40155579Sbostic 
40255579Sbostic /*
40355579Sbostic **  FreeConns -- free linked list of RMPCONN connections.
40455579Sbostic **
40555579Sbostic **	Parameters:
40655579Sbostic **		None.
40755579Sbostic **
40855579Sbostic **	Returns:
40955579Sbostic **		Nothing.
41055579Sbostic **
41155579Sbostic **	Side Effects:
41255579Sbostic **		- All malloc'd memory associated with the linked list of
41355579Sbostic **		  connections will be free'd; `RmpConns' will be set to NULL.
41455579Sbostic **		- If LastFree is != NULL, it too will be free'd & NULL'd.
41555579Sbostic **
41655579Sbostic **	Warnings:
41755579Sbostic **		- This routine must be called with SIGHUP blocked.
41855579Sbostic */
41955600Sbostic void
FreeConns()42055579Sbostic FreeConns()
42155579Sbostic {
42255579Sbostic 	register RMPCONN *rtmp;
42355579Sbostic 
42455579Sbostic 	while (RmpConns != NULL) {
42555579Sbostic 		rtmp = RmpConns;
42655579Sbostic 		RmpConns = RmpConns->next;
42755579Sbostic 		FreeConn(rtmp);
42855579Sbostic 	}
42955579Sbostic 
43055579Sbostic 	if (LastFree != NULL) {
43155579Sbostic 		free((char *)LastFree);
43255579Sbostic 		LastFree = NULL;
43355579Sbostic 	}
43455579Sbostic }
43555579Sbostic 
43655579Sbostic /*
43755579Sbostic **  AddConn -- Add a connection to the linked list of connections.
43855579Sbostic **
43955579Sbostic **	Parameters:
44055579Sbostic **		rconn - connection to be added.
44155579Sbostic **
44255579Sbostic **	Returns:
44355579Sbostic **		Nothing.
44455579Sbostic **
44555579Sbostic **	Side Effects:
44655579Sbostic **		- RmpConn will point to new connection.
44755579Sbostic **
44855579Sbostic **	Warnings:
44955579Sbostic **		- This routine must be called with SIGHUP blocked.
45055579Sbostic */
45155600Sbostic void
AddConn(rconn)45255579Sbostic AddConn(rconn)
45355600Sbostic 	register RMPCONN *rconn;
45455579Sbostic {
45555579Sbostic 	if (RmpConns != NULL)
45655579Sbostic 		rconn->next = RmpConns;
45755579Sbostic 	RmpConns = rconn;
45855579Sbostic }
45955579Sbostic 
46055579Sbostic /*
46155579Sbostic **  FindConn -- Find a connection in the linked list of connections.
46255579Sbostic **
46355579Sbostic **	We use the RMP (Ethernet) address as the basis for determining
46455579Sbostic **	if this is the same connection.  According to the Remote Maint
46555579Sbostic **	Protocol, we can only have one connection with any machine.
46655579Sbostic **
46755579Sbostic **	Parameters:
46855579Sbostic **		rconn - connection to be found.
46955579Sbostic **
47055579Sbostic **	Returns:
47155579Sbostic **		Matching connection from linked list or NULL if not found.
47255579Sbostic **
47355579Sbostic **	Side Effects:
47455579Sbostic **		None.
47555579Sbostic **
47655579Sbostic **	Warnings:
47755579Sbostic **		- This routine must be called with SIGHUP blocked.
47855579Sbostic */
47955579Sbostic RMPCONN *
FindConn(rconn)48055579Sbostic FindConn(rconn)
48155600Sbostic 	register RMPCONN *rconn;
48255579Sbostic {
48355579Sbostic 	register RMPCONN *rtmp;
48455579Sbostic 
48555579Sbostic 	for (rtmp = RmpConns; rtmp != NULL; rtmp = rtmp->next)
48655579Sbostic 		if (bcmp((char *)&rconn->rmp.hp_hdr.saddr[0],
48755579Sbostic 		         (char *)&rtmp->rmp.hp_hdr.saddr[0], RMP_ADDRLEN) == 0)
48855579Sbostic 			break;
48955579Sbostic 
49055579Sbostic 	return(rtmp);
49155579Sbostic }
49255579Sbostic 
49355579Sbostic /*
49455579Sbostic **  RemoveConn -- Remove a connection from the linked list of connections.
49555579Sbostic **
49655579Sbostic **	Parameters:
49755579Sbostic **		rconn - connection to be removed.
49855579Sbostic **
49955579Sbostic **	Returns:
50055579Sbostic **		Nothing.
50155579Sbostic **
50255579Sbostic **	Side Effects:
50355579Sbostic **		- If found, an RMPCONN will cease to exist and it will
50455579Sbostic **		  be removed from the linked list.
50555579Sbostic **
50655579Sbostic **	Warnings:
50755579Sbostic **		- This routine must be called with SIGHUP blocked.
50855579Sbostic */
50955600Sbostic void
RemoveConn(rconn)51055579Sbostic RemoveConn(rconn)
51155600Sbostic 	register RMPCONN *rconn;
51255579Sbostic {
51355579Sbostic 	register RMPCONN *thisrconn, *lastrconn;
51455579Sbostic 
51555579Sbostic 	if (RmpConns == rconn) {		/* easy case */
51655579Sbostic 		RmpConns = RmpConns->next;
51755579Sbostic 		FreeConn(rconn);
51855579Sbostic 	} else {				/* must traverse linked list */
51955579Sbostic 		lastrconn = RmpConns;			/* set back ptr */
52055579Sbostic 		thisrconn = lastrconn->next;		/* set current ptr */
52155579Sbostic 		while (thisrconn != NULL) {
52255579Sbostic 			if (rconn == thisrconn) {		/* found it */
52355579Sbostic 				lastrconn->next = thisrconn->next;
52455579Sbostic 				FreeConn(thisrconn);
52555579Sbostic 				break;
52655579Sbostic 			}
52755579Sbostic 			lastrconn = thisrconn;
52855579Sbostic 			thisrconn = thisrconn->next;
52955579Sbostic 		}
53055579Sbostic 	}
53155579Sbostic }
532