Home | History | Annotate | Line # | Download | only in rbootd
utils.c revision 1.15.34.1
      1  1.15.34.1      jym /*	$NetBSD: utils.c,v 1.15.34.1 2009/05/13 19:20:36 jym Exp $	*/
      2       1.14      agc 
      3       1.14      agc /*
      4       1.14      agc  * Copyright (c) 1992, 1993
      5       1.14      agc  *	The Regents of the University of California.  All rights reserved.
      6       1.14      agc  *
      7       1.14      agc  * This code is derived from software contributed to Berkeley by
      8       1.14      agc  * the Center for Software Science of the University of Utah Computer
      9       1.14      agc  * Science Department.  CSS requests users of this software to return
     10       1.14      agc  * to css-dist (at) cs.utah.edu any improvements that they make and grant
     11       1.14      agc  * CSS redistribution rights.
     12       1.14      agc  *
     13       1.14      agc  * Redistribution and use in source and binary forms, with or without
     14       1.14      agc  * modification, are permitted provided that the following conditions
     15       1.14      agc  * are met:
     16       1.14      agc  * 1. Redistributions of source code must retain the above copyright
     17       1.14      agc  *    notice, this list of conditions and the following disclaimer.
     18       1.14      agc  * 2. Redistributions in binary form must reproduce the above copyright
     19       1.14      agc  *    notice, this list of conditions and the following disclaimer in the
     20       1.14      agc  *    documentation and/or other materials provided with the distribution.
     21       1.14      agc  * 3. Neither the name of the University nor the names of its contributors
     22       1.14      agc  *    may be used to endorse or promote products derived from this software
     23       1.14      agc  *    without specific prior written permission.
     24       1.14      agc  *
     25       1.14      agc  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     26       1.14      agc  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     27       1.14      agc  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     28       1.14      agc  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     29       1.14      agc  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     30       1.14      agc  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     31       1.14      agc  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     32       1.14      agc  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     33       1.14      agc  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     34       1.14      agc  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     35       1.14      agc  * SUCH DAMAGE.
     36       1.14      agc  *
     37       1.14      agc  *	from: @(#)utils.c	8.1 (Berkeley) 6/4/93
     38       1.14      agc  *
     39       1.14      agc  * From: Utah Hdr: utils.c 3.1 92/07/06
     40       1.14      agc  * Author: Jeff Forys, University of Utah CSS
     41       1.14      agc  */
     42        1.3  thorpej 
     43        1.1   brezak /*
     44        1.1   brezak  * Copyright (c) 1988, 1992 The University of Utah and the Center
     45        1.1   brezak  *	for Software Science (CSS).
     46        1.1   brezak  *
     47        1.1   brezak  * This code is derived from software contributed to Berkeley by
     48        1.1   brezak  * the Center for Software Science of the University of Utah Computer
     49        1.1   brezak  * Science Department.  CSS requests users of this software to return
     50        1.1   brezak  * to css-dist (at) cs.utah.edu any improvements that they make and grant
     51        1.1   brezak  * CSS redistribution rights.
     52        1.1   brezak  *
     53        1.1   brezak  * Redistribution and use in source and binary forms, with or without
     54        1.1   brezak  * modification, are permitted provided that the following conditions
     55        1.1   brezak  * are met:
     56        1.1   brezak  * 1. Redistributions of source code must retain the above copyright
     57        1.1   brezak  *    notice, this list of conditions and the following disclaimer.
     58        1.1   brezak  * 2. Redistributions in binary form must reproduce the above copyright
     59        1.1   brezak  *    notice, this list of conditions and the following disclaimer in the
     60        1.1   brezak  *    documentation and/or other materials provided with the distribution.
     61        1.1   brezak  * 3. All advertising materials mentioning features or use of this software
     62        1.1   brezak  *    must display the following acknowledgement:
     63        1.1   brezak  *	This product includes software developed by the University of
     64        1.1   brezak  *	California, Berkeley and its contributors.
     65        1.1   brezak  * 4. Neither the name of the University nor the names of its contributors
     66        1.1   brezak  *    may be used to endorse or promote products derived from this software
     67        1.1   brezak  *    without specific prior written permission.
     68        1.1   brezak  *
     69        1.1   brezak  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     70        1.1   brezak  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     71        1.1   brezak  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     72        1.1   brezak  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     73        1.1   brezak  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     74        1.1   brezak  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     75        1.1   brezak  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     76        1.1   brezak  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     77        1.1   brezak  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     78        1.1   brezak  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     79        1.1   brezak  * SUCH DAMAGE.
     80        1.1   brezak  *
     81        1.2   brezak  *	from: @(#)utils.c	8.1 (Berkeley) 6/4/93
     82        1.1   brezak  *
     83        1.2   brezak  * From: Utah Hdr: utils.c 3.1 92/07/06
     84        1.1   brezak  * Author: Jeff Forys, University of Utah CSS
     85        1.1   brezak  */
     86        1.1   brezak 
     87        1.7  thorpej #include <sys/cdefs.h>
     88        1.1   brezak #ifndef lint
     89        1.7  thorpej #if 0
     90        1.7  thorpej static char sccsid[] = "@(#)utils.c	8.1 (Berkeley) 6/4/93";
     91        1.7  thorpej #else
     92  1.15.34.1      jym __RCSID("$NetBSD: utils.c,v 1.15.34.1 2009/05/13 19:20:36 jym Exp $");
     93        1.7  thorpej #endif
     94        1.1   brezak #endif /* not lint */
     95        1.1   brezak 
     96        1.1   brezak #include <sys/param.h>
     97       1.15  mycroft #include <sys/time.h>
     98        1.1   brezak 
     99        1.1   brezak #include <fcntl.h>
    100        1.1   brezak #include <signal.h>
    101        1.1   brezak #include <stdio.h>
    102        1.1   brezak #include <stdlib.h>
    103        1.1   brezak #include <string.h>
    104        1.1   brezak #include <syslog.h>
    105        1.1   brezak #include <time.h>
    106        1.1   brezak #include <unistd.h>
    107        1.1   brezak #include "defs.h"
    108        1.1   brezak 
    109        1.1   brezak /*
    110        1.1   brezak **  DispPkt -- Display the contents of an RMPCONN packet.
    111        1.1   brezak **
    112        1.1   brezak **	Parameters:
    113        1.1   brezak **		rconn - packet to be displayed.
    114        1.1   brezak **		direct - direction packet is going (DIR_*).
    115        1.1   brezak **
    116        1.1   brezak **	Returns:
    117        1.1   brezak **		Nothing.
    118        1.1   brezak **
    119        1.1   brezak **	Side Effects:
    120        1.1   brezak **		None.
    121        1.1   brezak */
    122        1.1   brezak void
    123        1.1   brezak DispPkt(rconn, direct)
    124        1.1   brezak 	RMPCONN *rconn;
    125        1.1   brezak 	int direct;
    126        1.1   brezak {
    127       1.12       is 	static const char BootFmt[] = "\t\tRetCode:%u SeqNo:%lx SessID:%x Vers:%u";
    128       1.12       is 	static const char ReadFmt[] = "\t\tRetCode:%u Offset:%lx SessID:%x\n";
    129        1.1   brezak 
    130        1.1   brezak 	struct tm *tmp;
    131        1.9    lukem 	struct rmp_packet *rmp;
    132        1.1   brezak 	int i, omask;
    133        1.5  thorpej 	u_int32_t t;
    134        1.1   brezak 
    135        1.1   brezak 	/*
    136        1.1   brezak 	 *  Since we will be working with RmpConns as well as DbgFp, we
    137        1.1   brezak 	 *  must block signals that can affect either.
    138        1.1   brezak 	 */
    139        1.1   brezak 	omask = sigblock(sigmask(SIGHUP)|sigmask(SIGUSR1)|sigmask(SIGUSR2));
    140        1.1   brezak 
    141        1.1   brezak 	if (DbgFp == NULL) {			/* sanity */
    142        1.1   brezak 		(void) sigsetmask(omask);
    143        1.1   brezak 		return;
    144        1.1   brezak 	}
    145        1.1   brezak 
    146        1.1   brezak 	/* display direction packet is going using '>>>' or '<<<' */
    147        1.1   brezak 	fputs((direct==DIR_RCVD)?"<<< ":(direct==DIR_SENT)?">>> ":"", DbgFp);
    148        1.1   brezak 
    149        1.1   brezak 	/* display packet timestamp */
    150        1.1   brezak 	tmp = localtime((time_t *)&rconn->tstamp.tv_sec);
    151        1.1   brezak 	fprintf(DbgFp, "%02d:%02d:%02d.%06ld   ", tmp->tm_hour, tmp->tm_min,
    152       1.11   kleink 	        tmp->tm_sec, (long int)rconn->tstamp.tv_usec);
    153        1.1   brezak 
    154        1.1   brezak 	/* display src or dst addr and information about network interface */
    155        1.1   brezak 	fprintf(DbgFp, "Addr: %s   Intf: %s\n", EnetStr(rconn), IntfName);
    156        1.1   brezak 
    157        1.1   brezak 	rmp = &rconn->rmp;
    158        1.1   brezak 
    159        1.1   brezak 	/* display IEEE 802.2 Logical Link Control header */
    160        1.1   brezak 	(void) fprintf(DbgFp, "\t802.2 LLC: DSAP:%x SSAP:%x CTRL:%x\n",
    161        1.4  thorpej                rmp->hp_llc.dsap, rmp->hp_llc.ssap, ntohs(rmp->hp_llc.cntrl));
    162        1.1   brezak 
    163        1.1   brezak 	/* display HP extensions to 802.2 Logical Link Control header */
    164        1.1   brezak 	(void) fprintf(DbgFp, "\tHP Ext:    DXSAP:%x SXSAP:%x\n",
    165        1.4  thorpej 	               ntohs(rmp->hp_llc.dxsap), ntohs(rmp->hp_llc.sxsap));
    166        1.1   brezak 
    167        1.1   brezak 	/*
    168        1.1   brezak 	 *  Display information about RMP packet using type field to
    169        1.1   brezak 	 *  determine what kind of packet this is.
    170        1.1   brezak 	 */
    171        1.1   brezak 	switch(rmp->r_type) {
    172        1.1   brezak 		case RMP_BOOT_REQ:		/* boot request */
    173        1.1   brezak 			(void) fprintf(DbgFp, "\tBoot Request:");
    174        1.1   brezak 			GETWORD(rmp->r_brq.rmp_seqno, t);
    175        1.4  thorpej 			if (ntohs(rmp->r_brq.rmp_session) == RMP_PROBESID) {
    176        1.1   brezak 				if (WORDZE(rmp->r_brq.rmp_seqno))
    177        1.1   brezak 					fputs(" (Send Server ID)", DbgFp);
    178        1.1   brezak 				else
    179        1.1   brezak 					fprintf(DbgFp," (Send Filename #%u)",t);
    180        1.1   brezak 			}
    181        1.1   brezak 			(void) fputc('\n', DbgFp);
    182        1.1   brezak 			(void) fprintf(DbgFp, BootFmt, rmp->r_brq.rmp_retcode,
    183       1.12       is 			        (unsigned long)t, ntohs(rmp->r_brq.rmp_session),
    184        1.4  thorpej 			        ntohs(rmp->r_brq.rmp_version));
    185        1.1   brezak 			(void) fprintf(DbgFp, "\n\t\tMachine Type: ");
    186        1.1   brezak 			for (i = 0; i < RMP_MACHLEN; i++)
    187        1.1   brezak 				(void) fputc(rmp->r_brq.rmp_machtype[i], DbgFp);
    188        1.1   brezak 			DspFlnm(rmp->r_brq.rmp_flnmsize, &rmp->r_brq.rmp_flnm);
    189        1.1   brezak 			break;
    190        1.1   brezak 		case RMP_BOOT_REPL:		/* boot reply */
    191        1.1   brezak 			fprintf(DbgFp, "\tBoot Reply:\n");
    192        1.1   brezak 			GETWORD(rmp->r_brpl.rmp_seqno, t);
    193        1.1   brezak 			(void) fprintf(DbgFp, BootFmt, rmp->r_brpl.rmp_retcode,
    194       1.12       is 			        (unsigned long)t, ntohs(rmp->r_brpl.rmp_session),
    195        1.4  thorpej 			        ntohs(rmp->r_brpl.rmp_version));
    196        1.1   brezak 			DspFlnm(rmp->r_brpl.rmp_flnmsize,&rmp->r_brpl.rmp_flnm);
    197        1.1   brezak 			break;
    198        1.1   brezak 		case RMP_READ_REQ:		/* read request */
    199        1.1   brezak 			(void) fprintf(DbgFp, "\tRead Request:\n");
    200        1.1   brezak 			GETWORD(rmp->r_rrq.rmp_offset, t);
    201        1.1   brezak 			(void) fprintf(DbgFp, ReadFmt, rmp->r_rrq.rmp_retcode,
    202       1.12       is 			        (unsigned long)t, ntohs(rmp->r_rrq.rmp_session));
    203        1.1   brezak 			(void) fprintf(DbgFp, "\t\tNoOfBytes: %u\n",
    204        1.4  thorpej 			        ntohs(rmp->r_rrq.rmp_size));
    205        1.1   brezak 			break;
    206        1.1   brezak 		case RMP_READ_REPL:		/* read reply */
    207        1.1   brezak 			(void) fprintf(DbgFp, "\tRead Reply:\n");
    208        1.1   brezak 			GETWORD(rmp->r_rrpl.rmp_offset, t);
    209        1.1   brezak 			(void) fprintf(DbgFp, ReadFmt, rmp->r_rrpl.rmp_retcode,
    210       1.12       is 			        (unsigned long)t, ntohs(rmp->r_rrpl.rmp_session));
    211        1.8  thorpej 			(void) fprintf(DbgFp, "\t\tNoOfBytesSent: %ld\n",
    212        1.8  thorpej 			        (long)(rconn->rmplen - RMPREADSIZE(0)));
    213        1.1   brezak 			break;
    214        1.1   brezak 		case RMP_BOOT_DONE:		/* boot complete */
    215        1.1   brezak 			(void) fprintf(DbgFp, "\tBoot Complete:\n");
    216        1.1   brezak 			(void) fprintf(DbgFp, "\t\tRetCode:%u SessID:%x\n",
    217        1.1   brezak 			        rmp->r_done.rmp_retcode,
    218        1.4  thorpej 			        ntohs(rmp->r_done.rmp_session));
    219        1.1   brezak 			break;
    220        1.1   brezak 		default:			/* ??? */
    221        1.1   brezak 			(void) fprintf(DbgFp, "\tUnknown Type:(%d)\n",
    222        1.1   brezak 				rmp->r_type);
    223        1.1   brezak 	}
    224        1.1   brezak 	(void) fputc('\n', DbgFp);
    225        1.1   brezak 	(void) fflush(DbgFp);
    226        1.1   brezak 
    227        1.1   brezak 	(void) sigsetmask(omask);		/* reset old signal mask */
    228        1.1   brezak }
    229        1.1   brezak 
    230        1.1   brezak 
    231        1.1   brezak /*
    232        1.1   brezak **  GetEtherAddr -- convert an RMP (Ethernet) address into a string.
    233        1.1   brezak **
    234        1.1   brezak **	An RMP BOOT packet has been received.  Look at the type field
    235        1.1   brezak **	and process Boot Requests, Read Requests, and Boot Complete
    236        1.1   brezak **	packets.  Any other type will be dropped with a warning msg.
    237        1.1   brezak **
    238        1.1   brezak **	Parameters:
    239        1.1   brezak **		addr - array of RMP_ADDRLEN bytes.
    240        1.1   brezak **
    241        1.1   brezak **	Returns:
    242        1.1   brezak **		Pointer to static string representation of `addr'.
    243        1.1   brezak **
    244        1.1   brezak **	Side Effects:
    245        1.1   brezak **		None.
    246        1.1   brezak **
    247        1.1   brezak **	Warnings:
    248        1.1   brezak **		- The return value points to a static buffer; it must
    249        1.1   brezak **		  be copied if it's to be saved.
    250        1.1   brezak */
    251        1.1   brezak char *
    252        1.1   brezak GetEtherAddr(addr)
    253        1.5  thorpej 	u_int8_t *addr;
    254        1.1   brezak {
    255        1.1   brezak 	static char Hex[] = "0123456789abcdef";
    256        1.1   brezak 	static char etherstr[RMP_ADDRLEN*3];
    257        1.9    lukem 	int i;
    258        1.9    lukem 	char *cp;
    259        1.1   brezak 
    260        1.1   brezak 	/*
    261        1.1   brezak 	 *  For each byte in `addr', convert it to "<hexchar><hexchar>:".
    262        1.1   brezak 	 *  The last byte does not get a trailing `:' appended.
    263        1.1   brezak 	 */
    264        1.1   brezak 	i = 0;
    265        1.5  thorpej 	cp = etherstr;
    266        1.1   brezak 	for(;;) {
    267        1.5  thorpej 		*cp++ = Hex[*addr >> 4 & 0xf];
    268        1.5  thorpej 		*cp++ = Hex[*addr++ & 0xf];
    269        1.1   brezak 		if (++i == RMP_ADDRLEN)
    270        1.1   brezak 			break;
    271        1.5  thorpej 		*cp++ = ':';
    272        1.1   brezak 	}
    273        1.5  thorpej 	*cp = '\0';
    274        1.1   brezak 
    275        1.1   brezak 	return(etherstr);
    276        1.1   brezak }
    277        1.1   brezak 
    278        1.1   brezak 
    279        1.1   brezak /*
    280        1.1   brezak **  DispFlnm -- Print a string of bytes to DbgFp (often, a file name).
    281        1.1   brezak **
    282        1.1   brezak **	Parameters:
    283        1.1   brezak **		size - number of bytes to print.
    284        1.1   brezak **		flnm - address of first byte.
    285        1.1   brezak **
    286        1.1   brezak **	Returns:
    287        1.1   brezak **		Nothing.
    288        1.1   brezak **
    289        1.1   brezak **	Side Effects:
    290        1.1   brezak **		- Characters are sent to `DbgFp'.
    291        1.1   brezak */
    292        1.1   brezak void
    293        1.1   brezak DspFlnm(size, flnm)
    294        1.9    lukem 	u_int size;
    295        1.9    lukem 	char *flnm;
    296        1.1   brezak {
    297  1.15.34.1      jym 	size_t i;
    298        1.1   brezak 
    299        1.5  thorpej 	(void) fprintf(DbgFp, "\n\t\tFile Name (%u): <", size);
    300        1.1   brezak 	for (i = 0; i < size; i++)
    301        1.1   brezak 		(void) fputc(*flnm++, DbgFp);
    302        1.1   brezak 	(void) fputs(">\n", DbgFp);
    303        1.1   brezak }
    304        1.1   brezak 
    305        1.1   brezak 
    306        1.1   brezak /*
    307        1.1   brezak **  NewClient -- allocate memory for a new CLIENT.
    308        1.1   brezak **
    309        1.1   brezak **	Parameters:
    310        1.1   brezak **		addr - RMP (Ethernet) address of new client.
    311        1.1   brezak **
    312        1.1   brezak **	Returns:
    313        1.1   brezak **		Ptr to new CLIENT or NULL if we ran out of memory.
    314        1.1   brezak **
    315        1.1   brezak **	Side Effects:
    316        1.1   brezak **		- Memory will be malloc'd for the new CLIENT.
    317        1.1   brezak **		- If malloc() fails, a log message will be generated.
    318        1.1   brezak */
    319        1.1   brezak CLIENT *
    320        1.1   brezak NewClient(addr)
    321        1.5  thorpej 	u_int8_t *addr;
    322        1.1   brezak {
    323        1.1   brezak 	CLIENT *ctmp;
    324        1.1   brezak 
    325        1.1   brezak 	if ((ctmp = (CLIENT *) malloc(sizeof(CLIENT))) == NULL) {
    326        1.1   brezak 		syslog(LOG_ERR, "NewClient: out of memory (%s)",
    327        1.1   brezak 		       GetEtherAddr(addr));
    328        1.1   brezak 		return(NULL);
    329        1.1   brezak 	}
    330        1.1   brezak 
    331        1.9    lukem 	memset(ctmp, 0, sizeof(CLIENT));
    332        1.9    lukem 	memmove(&ctmp->addr[0], addr, RMP_ADDRLEN);
    333        1.1   brezak 	return(ctmp);
    334        1.1   brezak }
    335        1.1   brezak 
    336        1.1   brezak /*
    337       1.10      mrg **  FreeClients -- free linked list of Clients.
    338        1.1   brezak **
    339        1.1   brezak **	Parameters:
    340        1.1   brezak **		None.
    341        1.1   brezak **
    342        1.1   brezak **	Returns:
    343        1.1   brezak **		Nothing.
    344        1.1   brezak **
    345        1.1   brezak **	Side Effects:
    346        1.1   brezak **		- All malloc'd memory associated with the linked list of
    347        1.1   brezak **		  CLIENTS will be free'd; `Clients' will be set to NULL.
    348        1.1   brezak **
    349        1.1   brezak **	Warnings:
    350        1.1   brezak **		- This routine must be called with SIGHUP blocked.
    351        1.1   brezak */
    352        1.1   brezak void
    353        1.1   brezak FreeClients()
    354        1.1   brezak {
    355        1.9    lukem 	CLIENT *ctmp;
    356        1.1   brezak 
    357        1.1   brezak 	while (Clients != NULL) {
    358        1.1   brezak 		ctmp = Clients;
    359        1.1   brezak 		Clients = Clients->next;
    360        1.1   brezak 		FreeClient(ctmp);
    361        1.1   brezak 	}
    362        1.1   brezak }
    363        1.1   brezak 
    364        1.1   brezak /*
    365        1.1   brezak **  NewStr -- allocate memory for a character array.
    366        1.1   brezak **
    367        1.1   brezak **	Parameters:
    368        1.1   brezak **		str - null terminated character array.
    369        1.1   brezak **
    370        1.1   brezak **	Returns:
    371        1.1   brezak **		Ptr to new character array or NULL if we ran out of memory.
    372        1.1   brezak **
    373        1.1   brezak **	Side Effects:
    374        1.1   brezak **		- Memory will be malloc'd for the new character array.
    375        1.1   brezak **		- If malloc() fails, a log message will be generated.
    376        1.1   brezak */
    377        1.1   brezak char *
    378        1.1   brezak NewStr(str)
    379        1.1   brezak 	char *str;
    380        1.1   brezak {
    381        1.1   brezak 	char *stmp;
    382        1.1   brezak 
    383       1.13   itojun 	if ((stmp = strdup(str)) == NULL) {
    384        1.1   brezak 		syslog(LOG_ERR, "NewStr: out of memory (%s)", str);
    385        1.1   brezak 		return(NULL);
    386        1.1   brezak 	}
    387        1.1   brezak 
    388        1.1   brezak 	return(stmp);
    389        1.1   brezak }
    390        1.1   brezak 
    391        1.1   brezak /*
    392        1.1   brezak **  To save time, NewConn and FreeConn maintain a cache of one RMPCONN
    393        1.1   brezak **  in `LastFree' (defined below).
    394        1.1   brezak */
    395        1.1   brezak 
    396        1.1   brezak static RMPCONN *LastFree = NULL;
    397        1.1   brezak 
    398        1.1   brezak /*
    399        1.1   brezak **  NewConn -- allocate memory for a new RMPCONN connection.
    400        1.1   brezak **
    401        1.1   brezak **	Parameters:
    402        1.1   brezak **		rconn - initialization template for new connection.
    403        1.1   brezak **
    404        1.1   brezak **	Returns:
    405        1.1   brezak **		Ptr to new RMPCONN or NULL if we ran out of memory.
    406        1.1   brezak **
    407        1.1   brezak **	Side Effects:
    408        1.1   brezak **		- Memory may be malloc'd for the new RMPCONN (if not cached).
    409        1.1   brezak **		- If malloc() fails, a log message will be generated.
    410        1.1   brezak */
    411        1.1   brezak RMPCONN *
    412        1.1   brezak NewConn(rconn)
    413        1.1   brezak 	RMPCONN *rconn;
    414        1.1   brezak {
    415        1.1   brezak 	RMPCONN *rtmp;
    416        1.1   brezak 
    417        1.1   brezak 	if (LastFree == NULL) {		/* nothing cached; make a new one */
    418        1.1   brezak 		if ((rtmp = (RMPCONN *) malloc(sizeof(RMPCONN))) == NULL) {
    419        1.1   brezak 			syslog(LOG_ERR, "NewConn: out of memory (%s)",
    420        1.1   brezak 			       EnetStr(rconn));
    421        1.1   brezak 			return(NULL);
    422        1.1   brezak 		}
    423        1.1   brezak 	} else {			/* use the cached RMPCONN */
    424        1.1   brezak 		rtmp = LastFree;
    425        1.1   brezak 		LastFree = NULL;
    426        1.1   brezak 	}
    427        1.1   brezak 
    428        1.1   brezak 	/*
    429        1.1   brezak 	 *  Copy template into `rtmp', init file descriptor to `-1' and
    430        1.1   brezak 	 *  set ptr to next elem NULL.
    431        1.1   brezak 	 */
    432        1.9    lukem 	memmove((char *)rtmp, (char *)rconn, sizeof(RMPCONN));
    433        1.1   brezak 	rtmp->bootfd = -1;
    434        1.1   brezak 	rtmp->next = NULL;
    435        1.1   brezak 
    436        1.1   brezak 	return(rtmp);
    437        1.1   brezak }
    438        1.1   brezak 
    439        1.1   brezak /*
    440        1.1   brezak **  FreeConn -- Free memory associated with an RMPCONN connection.
    441        1.1   brezak **
    442        1.1   brezak **	Parameters:
    443        1.1   brezak **		rtmp - ptr to RMPCONN to be free'd.
    444        1.1   brezak **
    445        1.1   brezak **	Returns:
    446        1.1   brezak **		Nothing.
    447        1.1   brezak **
    448        1.1   brezak **	Side Effects:
    449        1.1   brezak **		- Memory associated with `rtmp' may be free'd (or cached).
    450        1.1   brezak **		- File desc associated with `rtmp->bootfd' will be closed.
    451        1.1   brezak */
    452        1.1   brezak void
    453        1.1   brezak FreeConn(rtmp)
    454        1.9    lukem 	RMPCONN *rtmp;
    455        1.1   brezak {
    456        1.1   brezak 	/*
    457        1.1   brezak 	 *  If the file descriptor is in use, close the file.
    458        1.1   brezak 	 */
    459        1.1   brezak 	if (rtmp->bootfd >= 0) {
    460        1.1   brezak 		(void) close(rtmp->bootfd);
    461        1.1   brezak 		rtmp->bootfd = -1;
    462        1.1   brezak 	}
    463        1.1   brezak 
    464        1.1   brezak 	if (LastFree == NULL)		/* cache for next time */
    465       1.10      mrg 		LastFree = rtmp;
    466        1.1   brezak 	else				/* already one cached; free this one */
    467        1.1   brezak 		free((char *)rtmp);
    468        1.1   brezak }
    469        1.1   brezak 
    470        1.1   brezak /*
    471        1.1   brezak **  FreeConns -- free linked list of RMPCONN connections.
    472        1.1   brezak **
    473        1.1   brezak **	Parameters:
    474        1.1   brezak **		None.
    475        1.1   brezak **
    476        1.1   brezak **	Returns:
    477        1.1   brezak **		Nothing.
    478        1.1   brezak **
    479        1.1   brezak **	Side Effects:
    480        1.1   brezak **		- All malloc'd memory associated with the linked list of
    481        1.1   brezak **		  connections will be free'd; `RmpConns' will be set to NULL.
    482        1.1   brezak **		- If LastFree is != NULL, it too will be free'd & NULL'd.
    483        1.1   brezak **
    484        1.1   brezak **	Warnings:
    485        1.1   brezak **		- This routine must be called with SIGHUP blocked.
    486        1.1   brezak */
    487        1.1   brezak void
    488        1.1   brezak FreeConns()
    489        1.1   brezak {
    490        1.9    lukem 	RMPCONN *rtmp;
    491        1.1   brezak 
    492        1.1   brezak 	while (RmpConns != NULL) {
    493        1.1   brezak 		rtmp = RmpConns;
    494        1.1   brezak 		RmpConns = RmpConns->next;
    495        1.1   brezak 		FreeConn(rtmp);
    496        1.1   brezak 	}
    497        1.1   brezak 
    498        1.1   brezak 	if (LastFree != NULL) {
    499        1.1   brezak 		free((char *)LastFree);
    500        1.1   brezak 		LastFree = NULL;
    501        1.1   brezak 	}
    502        1.1   brezak }
    503        1.1   brezak 
    504        1.1   brezak /*
    505        1.1   brezak **  AddConn -- Add a connection to the linked list of connections.
    506        1.1   brezak **
    507        1.1   brezak **	Parameters:
    508        1.1   brezak **		rconn - connection to be added.
    509        1.1   brezak **
    510        1.1   brezak **	Returns:
    511        1.1   brezak **		Nothing.
    512        1.1   brezak **
    513        1.1   brezak **	Side Effects:
    514        1.1   brezak **		- RmpConn will point to new connection.
    515        1.1   brezak **
    516        1.1   brezak **	Warnings:
    517        1.1   brezak **		- This routine must be called with SIGHUP blocked.
    518        1.1   brezak */
    519        1.1   brezak void
    520        1.1   brezak AddConn(rconn)
    521        1.9    lukem 	RMPCONN *rconn;
    522        1.1   brezak {
    523        1.1   brezak 	if (RmpConns != NULL)
    524        1.1   brezak 		rconn->next = RmpConns;
    525        1.1   brezak 	RmpConns = rconn;
    526        1.1   brezak }
    527        1.1   brezak 
    528        1.1   brezak /*
    529        1.1   brezak **  FindConn -- Find a connection in the linked list of connections.
    530        1.1   brezak **
    531        1.1   brezak **	We use the RMP (Ethernet) address as the basis for determining
    532        1.1   brezak **	if this is the same connection.  According to the Remote Maint
    533        1.1   brezak **	Protocol, we can only have one connection with any machine.
    534        1.1   brezak **
    535        1.1   brezak **	Parameters:
    536        1.1   brezak **		rconn - connection to be found.
    537        1.1   brezak **
    538        1.1   brezak **	Returns:
    539        1.1   brezak **		Matching connection from linked list or NULL if not found.
    540        1.1   brezak **
    541        1.1   brezak **	Side Effects:
    542        1.1   brezak **		None.
    543        1.1   brezak **
    544        1.1   brezak **	Warnings:
    545        1.1   brezak **		- This routine must be called with SIGHUP blocked.
    546        1.1   brezak */
    547        1.1   brezak RMPCONN *
    548        1.1   brezak FindConn(rconn)
    549        1.9    lukem 	RMPCONN *rconn;
    550        1.1   brezak {
    551        1.9    lukem 	RMPCONN *rtmp;
    552        1.1   brezak 
    553        1.1   brezak 	for (rtmp = RmpConns; rtmp != NULL; rtmp = rtmp->next)
    554        1.9    lukem 		if (memcmp((char *)&rconn->rmp.hp_hdr.saddr[0],
    555        1.1   brezak 		         (char *)&rtmp->rmp.hp_hdr.saddr[0], RMP_ADDRLEN) == 0)
    556        1.1   brezak 			break;
    557        1.1   brezak 
    558        1.1   brezak 	return(rtmp);
    559        1.1   brezak }
    560        1.1   brezak 
    561        1.1   brezak /*
    562        1.1   brezak **  RemoveConn -- Remove a connection from the linked list of connections.
    563        1.1   brezak **
    564        1.1   brezak **	Parameters:
    565        1.1   brezak **		rconn - connection to be removed.
    566        1.1   brezak **
    567        1.1   brezak **	Returns:
    568        1.1   brezak **		Nothing.
    569        1.1   brezak **
    570        1.1   brezak **	Side Effects:
    571        1.1   brezak **		- If found, an RMPCONN will cease to exist and it will
    572        1.1   brezak **		  be removed from the linked list.
    573        1.1   brezak **
    574        1.1   brezak **	Warnings:
    575        1.1   brezak **		- This routine must be called with SIGHUP blocked.
    576        1.1   brezak */
    577        1.1   brezak void
    578        1.1   brezak RemoveConn(rconn)
    579        1.9    lukem 	RMPCONN *rconn;
    580        1.1   brezak {
    581        1.9    lukem 	RMPCONN *thisrconn, *lastrconn;
    582        1.1   brezak 
    583        1.1   brezak 	if (RmpConns == rconn) {		/* easy case */
    584        1.1   brezak 		RmpConns = RmpConns->next;
    585        1.1   brezak 		FreeConn(rconn);
    586        1.1   brezak 	} else {				/* must traverse linked list */
    587        1.1   brezak 		lastrconn = RmpConns;			/* set back ptr */
    588        1.1   brezak 		thisrconn = lastrconn->next;		/* set current ptr */
    589        1.1   brezak 		while (thisrconn != NULL) {
    590        1.1   brezak 			if (rconn == thisrconn) {		/* found it */
    591        1.1   brezak 				lastrconn->next = thisrconn->next;
    592        1.1   brezak 				FreeConn(thisrconn);
    593        1.1   brezak 				break;
    594        1.1   brezak 			}
    595        1.1   brezak 			lastrconn = thisrconn;
    596        1.1   brezak 			thisrconn = thisrconn->next;
    597        1.1   brezak 		}
    598        1.1   brezak 	}
    599        1.1   brezak }
    600