xref: /csrg-svn/libexec/rbootd/utils.c (revision 55579)
1*55579Sbostic /*
2*55579Sbostic  * Copyright (c) 1992 Regents of the University of California.
3*55579Sbostic  * Copyright (c) 1988, 1992 The University of Utah and the Center
4*55579Sbostic  *	for Software Science (CSS).
5*55579Sbostic  * All rights reserved.
6*55579Sbostic  *
7*55579Sbostic  * This code is derived from software contributed to Berkeley by
8*55579Sbostic  * the Center for Software Science of the University of Utah Computer
9*55579Sbostic  * Science Department.  CSS requests users of this software to return
10*55579Sbostic  * to css-dist@cs.utah.edu any improvements that they make and grant
11*55579Sbostic  * CSS redistribution rights.
12*55579Sbostic  *
13*55579Sbostic  * %sccs.include.redist.c%
14*55579Sbostic  *
15*55579Sbostic  *	@(#)utils.c	5.1 (Berkeley) 07/23/92
16*55579Sbostic  *
17*55579Sbostic  * Utah $Hdr: utils.c 3.1 92/07/06$
18*55579Sbostic  * Author: Jeff Forys, University of Utah CSS
19*55579Sbostic  */
20*55579Sbostic 
21*55579Sbostic #ifndef lint
22*55579Sbostic static char sccsid[] = "@(#)utils.c	5.1 (Berkeley) 07/23/92";
23*55579Sbostic #endif /* not lint */
24*55579Sbostic 
25*55579Sbostic #include "defs.h"
26*55579Sbostic 
27*55579Sbostic #include <sys/file.h>
28*55579Sbostic 
29*55579Sbostic #include <syslog.h>
30*55579Sbostic #include <strings.h>
31*55579Sbostic 
32*55579Sbostic 
33*55579Sbostic /*
34*55579Sbostic **  DispPkt -- Display the contents of an RMPCONN packet.
35*55579Sbostic **
36*55579Sbostic **	Parameters:
37*55579Sbostic **		rconn - packet to be displayed.
38*55579Sbostic **		direct - direction packet is going (DIR_*).
39*55579Sbostic **
40*55579Sbostic **	Returns:
41*55579Sbostic **		Nothing.
42*55579Sbostic **
43*55579Sbostic **	Side Effects:
44*55579Sbostic **		None.
45*55579Sbostic */
46*55579Sbostic 
47*55579Sbostic DispPkt(rconn, direct)
48*55579Sbostic RMPCONN *rconn;
49*55579Sbostic int direct;
50*55579Sbostic {
51*55579Sbostic 	static char BootFmt[] = "\t\tRetCode:%u SeqNo:%lx SessID:%x Vers:%u";
52*55579Sbostic 	static char ReadFmt[] = "\t\tRetCode:%u Offset:%lx SessID:%x\n";
53*55579Sbostic 
54*55579Sbostic 	struct tm *tmp;
55*55579Sbostic 	register struct rmp_packet *rmp;
56*55579Sbostic 	int i, omask;
57*55579Sbostic 	u_int t;
58*55579Sbostic 
59*55579Sbostic 	/*
60*55579Sbostic 	 *  Since we will be working with RmpConns as well as DbgFp, we
61*55579Sbostic 	 *  must block signals that can affect either.
62*55579Sbostic 	 */
63*55579Sbostic 	omask = sigblock(sigmask(SIGHUP)|sigmask(SIGUSR1)|sigmask(SIGUSR2));
64*55579Sbostic 
65*55579Sbostic 	if (DbgFp == NULL) {			/* sanity */
66*55579Sbostic 		(void) sigsetmask(omask);
67*55579Sbostic 		return;
68*55579Sbostic 	}
69*55579Sbostic 
70*55579Sbostic 	/* display direction packet is going using '>>>' or '<<<' */
71*55579Sbostic 	fputs((direct==DIR_RCVD)?"<<< ":(direct==DIR_SENT)?">>> ":"", DbgFp);
72*55579Sbostic 
73*55579Sbostic 	/* display packet timestamp */
74*55579Sbostic 	tmp = localtime((time_t *)&rconn->tstamp.tv_sec);
75*55579Sbostic 	fprintf(DbgFp, "%02d:%02d:%02d.%06ld   ", tmp->tm_hour, tmp->tm_min,
76*55579Sbostic 	        tmp->tm_sec, rconn->tstamp.tv_usec);
77*55579Sbostic 
78*55579Sbostic 	/* display src or dst addr and information about network interface */
79*55579Sbostic 	fprintf(DbgFp, "Addr: %s   Intf: %s\n", EnetStr(rconn), IntfName);
80*55579Sbostic 
81*55579Sbostic 	rmp = &rconn->rmp;
82*55579Sbostic 
83*55579Sbostic 	/* display IEEE 802.2 Logical Link Control header */
84*55579Sbostic 	(void) fprintf(DbgFp, "\t802.2 LLC: DSAP:%x SSAP:%x CTRL:%x\n",
85*55579Sbostic 	               rmp->hp_llc.dsap, rmp->hp_llc.ssap, rmp->hp_llc.cntrl);
86*55579Sbostic 
87*55579Sbostic 	/* display HP extensions to 802.2 Logical Link Control header */
88*55579Sbostic 	(void) fprintf(DbgFp, "\tHP Ext:    DXSAP:%x SXSAP:%x\n",
89*55579Sbostic 	               rmp->hp_llc.dxsap, rmp->hp_llc.sxsap);
90*55579Sbostic 
91*55579Sbostic 	/*
92*55579Sbostic 	 *  Display information about RMP packet using type field to
93*55579Sbostic 	 *  determine what kind of packet this is.
94*55579Sbostic 	 */
95*55579Sbostic 	switch(rmp->r_type) {
96*55579Sbostic 		case RMP_BOOT_REQ:		/* boot request */
97*55579Sbostic 			(void) fprintf(DbgFp, "\tBoot Request:");
98*55579Sbostic 			GETWORD(rmp->r_brq.rmp_seqno, t);
99*55579Sbostic 			if (rmp->r_brq.rmp_session == RMP_PROBESID) {
100*55579Sbostic 				if (WORDZE(rmp->r_brq.rmp_seqno))
101*55579Sbostic 					fputs(" (Send Server ID)", DbgFp);
102*55579Sbostic 				else
103*55579Sbostic 					fprintf(DbgFp," (Send Filename #%u)",t);
104*55579Sbostic 			}
105*55579Sbostic 			(void) fputc('\n', DbgFp);
106*55579Sbostic 			(void) fprintf(DbgFp, BootFmt, rmp->r_brq.rmp_retcode,
107*55579Sbostic 			        t, rmp->r_brq.rmp_session,
108*55579Sbostic 			        rmp->r_brq.rmp_version);
109*55579Sbostic 			(void) fprintf(DbgFp, "\n\t\tMachine Type: ");
110*55579Sbostic 			for (i = 0; i < RMP_MACHLEN; i++)
111*55579Sbostic 				(void) fputc(rmp->r_brq.rmp_machtype[i], DbgFp);
112*55579Sbostic 			DspFlnm(rmp->r_brq.rmp_flnmsize, &rmp->r_brq.rmp_flnm);
113*55579Sbostic 			break;
114*55579Sbostic 		case RMP_BOOT_REPL:		/* boot reply */
115*55579Sbostic 			fprintf(DbgFp, "\tBoot Reply:\n");
116*55579Sbostic 			GETWORD(rmp->r_brpl.rmp_seqno, t);
117*55579Sbostic 			(void) fprintf(DbgFp, BootFmt, rmp->r_brpl.rmp_retcode,
118*55579Sbostic 			        t, rmp->r_brpl.rmp_session,
119*55579Sbostic 			        rmp->r_brpl.rmp_version);
120*55579Sbostic 			DspFlnm(rmp->r_brpl.rmp_flnmsize,&rmp->r_brpl.rmp_flnm);
121*55579Sbostic 			break;
122*55579Sbostic 		case RMP_READ_REQ:		/* read request */
123*55579Sbostic 			(void) fprintf(DbgFp, "\tRead Request:\n");
124*55579Sbostic 			GETWORD(rmp->r_rrq.rmp_offset, t);
125*55579Sbostic 			(void) fprintf(DbgFp, ReadFmt, rmp->r_rrq.rmp_retcode,
126*55579Sbostic 			        t, rmp->r_rrq.rmp_session);
127*55579Sbostic 			(void) fprintf(DbgFp, "\t\tNoOfBytes: %u\n",
128*55579Sbostic 			        rmp->r_rrq.rmp_size);
129*55579Sbostic 			break;
130*55579Sbostic 		case RMP_READ_REPL:		/* read reply */
131*55579Sbostic 			(void) fprintf(DbgFp, "\tRead Reply:\n");
132*55579Sbostic 			GETWORD(rmp->r_rrpl.rmp_offset, t);
133*55579Sbostic 			(void) fprintf(DbgFp, ReadFmt, rmp->r_rrpl.rmp_retcode,
134*55579Sbostic 			        t, rmp->r_rrpl.rmp_session);
135*55579Sbostic 			(void) fprintf(DbgFp, "\t\tNoOfBytesSent: %d\n",
136*55579Sbostic 			        rconn->rmplen - RMPREADSIZE(0));
137*55579Sbostic 			break;
138*55579Sbostic 		case RMP_BOOT_DONE:		/* boot complete */
139*55579Sbostic 			(void) fprintf(DbgFp, "\tBoot Complete:\n");
140*55579Sbostic 			(void) fprintf(DbgFp, "\t\tRetCode:%u SessID:%x\n",
141*55579Sbostic 			        rmp->r_done.rmp_retcode,
142*55579Sbostic 			        rmp->r_done.rmp_session);
143*55579Sbostic 			break;
144*55579Sbostic 		default:			/* ??? */
145*55579Sbostic 			(void) fprintf(DbgFp, "\tUnknown Type:(%d)\n",
146*55579Sbostic 				rmp->r_type);
147*55579Sbostic 	}
148*55579Sbostic 	(void) fputc('\n', DbgFp);
149*55579Sbostic 	(void) fflush(DbgFp);
150*55579Sbostic 
151*55579Sbostic 	(void) sigsetmask(omask);		/* reset old signal mask */
152*55579Sbostic }
153*55579Sbostic 
154*55579Sbostic 
155*55579Sbostic /*
156*55579Sbostic **  GetEtherAddr -- convert an RMP (Ethernet) address into a string.
157*55579Sbostic **
158*55579Sbostic **	An RMP BOOT packet has been received.  Look at the type field
159*55579Sbostic **	and process Boot Requests, Read Requests, and Boot Complete
160*55579Sbostic **	packets.  Any other type will be dropped with a warning msg.
161*55579Sbostic **
162*55579Sbostic **	Parameters:
163*55579Sbostic **		addr - array of RMP_ADDRLEN bytes.
164*55579Sbostic **
165*55579Sbostic **	Returns:
166*55579Sbostic **		Pointer to static string representation of `addr'.
167*55579Sbostic **
168*55579Sbostic **	Side Effects:
169*55579Sbostic **		None.
170*55579Sbostic **
171*55579Sbostic **	Warnings:
172*55579Sbostic **		- The return value points to a static buffer; it must
173*55579Sbostic **		  be copied if it's to be saved.
174*55579Sbostic **		- For speed, we assume a u_char consists of 8 bits.
175*55579Sbostic */
176*55579Sbostic 
177*55579Sbostic char *
178*55579Sbostic GetEtherAddr(addr)
179*55579Sbostic u_char *addr;
180*55579Sbostic {
181*55579Sbostic 	static char Hex[] = "0123456789abcdef";
182*55579Sbostic 	static char etherstr[RMP_ADDRLEN*3];
183*55579Sbostic 	register int i;
184*55579Sbostic 	register char *cp1, *cp2;
185*55579Sbostic 
186*55579Sbostic 	/*
187*55579Sbostic 	 *  For each byte in `addr', convert it to "<hexchar><hexchar>:".
188*55579Sbostic 	 *  The last byte does not get a trailing `:' appended.
189*55579Sbostic 	 */
190*55579Sbostic 	i = 0;
191*55579Sbostic 	cp1 = (char *)addr;
192*55579Sbostic 	cp2 = etherstr;
193*55579Sbostic 	for(;;) {
194*55579Sbostic 		*cp2++ = Hex[*cp1 >> 4 & 0xf];
195*55579Sbostic 		*cp2++ = Hex[*cp1++ & 0xf];
196*55579Sbostic 		if (++i == RMP_ADDRLEN)
197*55579Sbostic 			break;
198*55579Sbostic 		*cp2++ = ':';
199*55579Sbostic 	}
200*55579Sbostic 	*cp2 = '\0';
201*55579Sbostic 
202*55579Sbostic 	return(etherstr);
203*55579Sbostic }
204*55579Sbostic 
205*55579Sbostic 
206*55579Sbostic /*
207*55579Sbostic **  DispFlnm -- Print a string of bytes to DbgFp (often, a file name).
208*55579Sbostic **
209*55579Sbostic **	Parameters:
210*55579Sbostic **		size - number of bytes to print.
211*55579Sbostic **		flnm - address of first byte.
212*55579Sbostic **
213*55579Sbostic **	Returns:
214*55579Sbostic **		Nothing.
215*55579Sbostic **
216*55579Sbostic **	Side Effects:
217*55579Sbostic **		- Characters are sent to `DbgFp'.
218*55579Sbostic */
219*55579Sbostic 
220*55579Sbostic DspFlnm(size, flnm)
221*55579Sbostic register u_char size;
222*55579Sbostic register char *flnm;
223*55579Sbostic {
224*55579Sbostic 	register int i;
225*55579Sbostic 
226*55579Sbostic 	(void) fprintf(DbgFp, "\n\t\tFile Name (%d): <", size);
227*55579Sbostic 	for (i = 0; i < size; i++)
228*55579Sbostic 		(void) fputc(*flnm++, DbgFp);
229*55579Sbostic 	(void) fputs(">\n", DbgFp);
230*55579Sbostic }
231*55579Sbostic 
232*55579Sbostic 
233*55579Sbostic /*
234*55579Sbostic **  NewClient -- allocate memory for a new CLIENT.
235*55579Sbostic **
236*55579Sbostic **	Parameters:
237*55579Sbostic **		addr - RMP (Ethernet) address of new client.
238*55579Sbostic **
239*55579Sbostic **	Returns:
240*55579Sbostic **		Ptr to new CLIENT or NULL if we ran out of memory.
241*55579Sbostic **
242*55579Sbostic **	Side Effects:
243*55579Sbostic **		- Memory will be malloc'd for the new CLIENT.
244*55579Sbostic **		- If malloc() fails, a log message will be generated.
245*55579Sbostic */
246*55579Sbostic 
247*55579Sbostic CLIENT *
248*55579Sbostic NewClient(addr)
249*55579Sbostic u_char *addr;
250*55579Sbostic {
251*55579Sbostic 	CLIENT *ctmp;
252*55579Sbostic 
253*55579Sbostic 	if ((ctmp = (CLIENT *) malloc(sizeof(CLIENT))) == NULL) {
254*55579Sbostic 		syslog(LOG_ERR, "NewClient: out of memory (%s)",
255*55579Sbostic 		       GetEtherAddr(addr));
256*55579Sbostic 		return(NULL);
257*55579Sbostic 	}
258*55579Sbostic 
259*55579Sbostic 	bzero((char *)ctmp, sizeof(CLIENT));
260*55579Sbostic 	bcopy((char *)addr, (char *)&ctmp->addr[0], RMP_ADDRLEN);
261*55579Sbostic 	return(ctmp);
262*55579Sbostic }
263*55579Sbostic 
264*55579Sbostic /*
265*55579Sbostic **  FreeClient -- free linked list of Clients.
266*55579Sbostic **
267*55579Sbostic **	Parameters:
268*55579Sbostic **		None.
269*55579Sbostic **
270*55579Sbostic **	Returns:
271*55579Sbostic **		Nothing.
272*55579Sbostic **
273*55579Sbostic **	Side Effects:
274*55579Sbostic **		- All malloc'd memory associated with the linked list of
275*55579Sbostic **		  CLIENTS will be free'd; `Clients' will be set to NULL.
276*55579Sbostic **
277*55579Sbostic **	Warnings:
278*55579Sbostic **		- This routine must be called with SIGHUP blocked.
279*55579Sbostic */
280*55579Sbostic 
281*55579Sbostic FreeClients()
282*55579Sbostic {
283*55579Sbostic 	register CLIENT *ctmp;
284*55579Sbostic 
285*55579Sbostic 	while (Clients != NULL) {
286*55579Sbostic 		ctmp = Clients;
287*55579Sbostic 		Clients = Clients->next;
288*55579Sbostic 		FreeClient(ctmp);
289*55579Sbostic 	}
290*55579Sbostic }
291*55579Sbostic 
292*55579Sbostic /*
293*55579Sbostic **  NewStr -- allocate memory for a character array.
294*55579Sbostic **
295*55579Sbostic **	Parameters:
296*55579Sbostic **		str - null terminated character array.
297*55579Sbostic **
298*55579Sbostic **	Returns:
299*55579Sbostic **		Ptr to new character array or NULL if we ran out of memory.
300*55579Sbostic **
301*55579Sbostic **	Side Effects:
302*55579Sbostic **		- Memory will be malloc'd for the new character array.
303*55579Sbostic **		- If malloc() fails, a log message will be generated.
304*55579Sbostic */
305*55579Sbostic 
306*55579Sbostic char *
307*55579Sbostic NewStr(str)
308*55579Sbostic char *str;
309*55579Sbostic {
310*55579Sbostic 	char *stmp;
311*55579Sbostic 
312*55579Sbostic 	if ((stmp = (char *)malloc((unsigned) (strlen(str)+1))) == NULL) {
313*55579Sbostic 		syslog(LOG_ERR, "NewStr: out of memory (%s)", str);
314*55579Sbostic 		return(NULL);
315*55579Sbostic 	}
316*55579Sbostic 
317*55579Sbostic 	(void) strcpy(stmp, str);
318*55579Sbostic 	return(stmp);
319*55579Sbostic }
320*55579Sbostic 
321*55579Sbostic /*
322*55579Sbostic **  To save time, NewConn and FreeConn maintain a cache of one RMPCONN
323*55579Sbostic **  in `LastFree' (defined below).
324*55579Sbostic */
325*55579Sbostic 
326*55579Sbostic static RMPCONN *LastFree = NULL;
327*55579Sbostic 
328*55579Sbostic /*
329*55579Sbostic **  NewConn -- allocate memory for a new RMPCONN connection.
330*55579Sbostic **
331*55579Sbostic **	Parameters:
332*55579Sbostic **		rconn - initialization template for new connection.
333*55579Sbostic **
334*55579Sbostic **	Returns:
335*55579Sbostic **		Ptr to new RMPCONN or NULL if we ran out of memory.
336*55579Sbostic **
337*55579Sbostic **	Side Effects:
338*55579Sbostic **		- Memory may be malloc'd for the new RMPCONN (if not cached).
339*55579Sbostic **		- If malloc() fails, a log message will be generated.
340*55579Sbostic */
341*55579Sbostic 
342*55579Sbostic RMPCONN *
343*55579Sbostic NewConn(rconn)
344*55579Sbostic RMPCONN *rconn;
345*55579Sbostic {
346*55579Sbostic 	RMPCONN *rtmp;
347*55579Sbostic 
348*55579Sbostic 	if (LastFree == NULL) {		/* nothing cached; make a new one */
349*55579Sbostic 		if ((rtmp = (RMPCONN *) malloc(sizeof(RMPCONN))) == NULL) {
350*55579Sbostic 			syslog(LOG_ERR, "NewConn: out of memory (%s)",
351*55579Sbostic 			       EnetStr(rconn));
352*55579Sbostic 			return(NULL);
353*55579Sbostic 		}
354*55579Sbostic 	} else {			/* use the cached RMPCONN */
355*55579Sbostic 		rtmp = LastFree;
356*55579Sbostic 		LastFree = NULL;
357*55579Sbostic 	}
358*55579Sbostic 
359*55579Sbostic 	/*
360*55579Sbostic 	 *  Copy template into `rtmp', init file descriptor to `-1' and
361*55579Sbostic 	 *  set ptr to next elem NULL.
362*55579Sbostic 	 */
363*55579Sbostic 	bcopy((char *)rconn, (char *)rtmp, sizeof(RMPCONN));
364*55579Sbostic 	rtmp->bootfd = -1;
365*55579Sbostic 	rtmp->next = NULL;
366*55579Sbostic 
367*55579Sbostic 	return(rtmp);
368*55579Sbostic }
369*55579Sbostic 
370*55579Sbostic /*
371*55579Sbostic **  FreeConn -- Free memory associated with an RMPCONN connection.
372*55579Sbostic **
373*55579Sbostic **	Parameters:
374*55579Sbostic **		rtmp - ptr to RMPCONN to be free'd.
375*55579Sbostic **
376*55579Sbostic **	Returns:
377*55579Sbostic **		Nothing.
378*55579Sbostic **
379*55579Sbostic **	Side Effects:
380*55579Sbostic **		- Memory associated with `rtmp' may be free'd (or cached).
381*55579Sbostic **		- File desc associated with `rtmp->bootfd' will be closed.
382*55579Sbostic */
383*55579Sbostic 
384*55579Sbostic FreeConn(rtmp)
385*55579Sbostic register RMPCONN *rtmp;
386*55579Sbostic {
387*55579Sbostic 	/*
388*55579Sbostic 	 *  If the file descriptor is in use, close the file.
389*55579Sbostic 	 */
390*55579Sbostic 	if (rtmp->bootfd >= 0) {
391*55579Sbostic 		(void) close(rtmp->bootfd);
392*55579Sbostic 		rtmp->bootfd = -1;
393*55579Sbostic 	}
394*55579Sbostic 
395*55579Sbostic 	if (LastFree == NULL)		/* cache for next time */
396*55579Sbostic 		rtmp = LastFree;
397*55579Sbostic 	else				/* already one cached; free this one */
398*55579Sbostic 		free((char *)rtmp);
399*55579Sbostic }
400*55579Sbostic 
401*55579Sbostic /*
402*55579Sbostic **  FreeConns -- free linked list of RMPCONN connections.
403*55579Sbostic **
404*55579Sbostic **	Parameters:
405*55579Sbostic **		None.
406*55579Sbostic **
407*55579Sbostic **	Returns:
408*55579Sbostic **		Nothing.
409*55579Sbostic **
410*55579Sbostic **	Side Effects:
411*55579Sbostic **		- All malloc'd memory associated with the linked list of
412*55579Sbostic **		  connections will be free'd; `RmpConns' will be set to NULL.
413*55579Sbostic **		- If LastFree is != NULL, it too will be free'd & NULL'd.
414*55579Sbostic **
415*55579Sbostic **	Warnings:
416*55579Sbostic **		- This routine must be called with SIGHUP blocked.
417*55579Sbostic */
418*55579Sbostic 
419*55579Sbostic FreeConns()
420*55579Sbostic {
421*55579Sbostic 	register RMPCONN *rtmp;
422*55579Sbostic 
423*55579Sbostic 	while (RmpConns != NULL) {
424*55579Sbostic 		rtmp = RmpConns;
425*55579Sbostic 		RmpConns = RmpConns->next;
426*55579Sbostic 		FreeConn(rtmp);
427*55579Sbostic 	}
428*55579Sbostic 
429*55579Sbostic 	if (LastFree != NULL) {
430*55579Sbostic 		free((char *)LastFree);
431*55579Sbostic 		LastFree = NULL;
432*55579Sbostic 	}
433*55579Sbostic }
434*55579Sbostic 
435*55579Sbostic /*
436*55579Sbostic **  AddConn -- Add a connection to the linked list of connections.
437*55579Sbostic **
438*55579Sbostic **	Parameters:
439*55579Sbostic **		rconn - connection to be added.
440*55579Sbostic **
441*55579Sbostic **	Returns:
442*55579Sbostic **		Nothing.
443*55579Sbostic **
444*55579Sbostic **	Side Effects:
445*55579Sbostic **		- RmpConn will point to new connection.
446*55579Sbostic **
447*55579Sbostic **	Warnings:
448*55579Sbostic **		- This routine must be called with SIGHUP blocked.
449*55579Sbostic */
450*55579Sbostic 
451*55579Sbostic AddConn(rconn)
452*55579Sbostic register RMPCONN *rconn;
453*55579Sbostic {
454*55579Sbostic 	if (RmpConns != NULL)
455*55579Sbostic 		rconn->next = RmpConns;
456*55579Sbostic 	RmpConns = rconn;
457*55579Sbostic }
458*55579Sbostic 
459*55579Sbostic /*
460*55579Sbostic **  FindConn -- Find a connection in the linked list of connections.
461*55579Sbostic **
462*55579Sbostic **	We use the RMP (Ethernet) address as the basis for determining
463*55579Sbostic **	if this is the same connection.  According to the Remote Maint
464*55579Sbostic **	Protocol, we can only have one connection with any machine.
465*55579Sbostic **
466*55579Sbostic **	Parameters:
467*55579Sbostic **		rconn - connection to be found.
468*55579Sbostic **
469*55579Sbostic **	Returns:
470*55579Sbostic **		Matching connection from linked list or NULL if not found.
471*55579Sbostic **
472*55579Sbostic **	Side Effects:
473*55579Sbostic **		None.
474*55579Sbostic **
475*55579Sbostic **	Warnings:
476*55579Sbostic **		- This routine must be called with SIGHUP blocked.
477*55579Sbostic */
478*55579Sbostic 
479*55579Sbostic RMPCONN *
480*55579Sbostic FindConn(rconn)
481*55579Sbostic register RMPCONN *rconn;
482*55579Sbostic {
483*55579Sbostic 	register RMPCONN *rtmp;
484*55579Sbostic 
485*55579Sbostic 	for (rtmp = RmpConns; rtmp != NULL; rtmp = rtmp->next)
486*55579Sbostic 		if (bcmp((char *)&rconn->rmp.hp_hdr.saddr[0],
487*55579Sbostic 		         (char *)&rtmp->rmp.hp_hdr.saddr[0], RMP_ADDRLEN) == 0)
488*55579Sbostic 			break;
489*55579Sbostic 
490*55579Sbostic 	return(rtmp);
491*55579Sbostic }
492*55579Sbostic 
493*55579Sbostic /*
494*55579Sbostic **  RemoveConn -- Remove a connection from the linked list of connections.
495*55579Sbostic **
496*55579Sbostic **	Parameters:
497*55579Sbostic **		rconn - connection to be removed.
498*55579Sbostic **
499*55579Sbostic **	Returns:
500*55579Sbostic **		Nothing.
501*55579Sbostic **
502*55579Sbostic **	Side Effects:
503*55579Sbostic **		- If found, an RMPCONN will cease to exist and it will
504*55579Sbostic **		  be removed from the linked list.
505*55579Sbostic **
506*55579Sbostic **	Warnings:
507*55579Sbostic **		- This routine must be called with SIGHUP blocked.
508*55579Sbostic */
509*55579Sbostic 
510*55579Sbostic RemoveConn(rconn)
511*55579Sbostic register RMPCONN *rconn;
512*55579Sbostic {
513*55579Sbostic 	register RMPCONN *thisrconn, *lastrconn;
514*55579Sbostic 
515*55579Sbostic 	if (RmpConns == rconn) {		/* easy case */
516*55579Sbostic 		RmpConns = RmpConns->next;
517*55579Sbostic 		FreeConn(rconn);
518*55579Sbostic 	} else {				/* must traverse linked list */
519*55579Sbostic 		lastrconn = RmpConns;			/* set back ptr */
520*55579Sbostic 		thisrconn = lastrconn->next;		/* set current ptr */
521*55579Sbostic 		while (thisrconn != NULL) {
522*55579Sbostic 			if (rconn == thisrconn) {		/* found it */
523*55579Sbostic 				lastrconn->next = thisrconn->next;
524*55579Sbostic 				FreeConn(thisrconn);
525*55579Sbostic 				break;
526*55579Sbostic 			}
527*55579Sbostic 			lastrconn = thisrconn;
528*55579Sbostic 			thisrconn = thisrconn->next;
529*55579Sbostic 		}
530*55579Sbostic 	}
531*55579Sbostic }
532