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