utils.c revision 90377
11592Srgrimes/* 21592Srgrimes * Copyright (c) 1988, 1992 The University of Utah and the Center 31592Srgrimes * for Software Science (CSS). 41592Srgrimes * Copyright (c) 1992, 1993 51592Srgrimes * The Regents of the University of California. All rights reserved. 61592Srgrimes * 71592Srgrimes * This code is derived from software contributed to Berkeley by 81592Srgrimes * the Center for Software Science of the University of Utah Computer 91592Srgrimes * Science Department. CSS requests users of this software to return 101592Srgrimes * to css-dist@cs.utah.edu any improvements that they make and grant 111592Srgrimes * CSS redistribution rights. 121592Srgrimes * 131592Srgrimes * Redistribution and use in source and binary forms, with or without 141592Srgrimes * modification, are permitted provided that the following conditions 151592Srgrimes * are met: 161592Srgrimes * 1. Redistributions of source code must retain the above copyright 171592Srgrimes * notice, this list of conditions and the following disclaimer. 181592Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 191592Srgrimes * notice, this list of conditions and the following disclaimer in the 201592Srgrimes * documentation and/or other materials provided with the distribution. 211592Srgrimes * 3. All advertising materials mentioning features or use of this software 221592Srgrimes * must display the following acknowledgement: 231592Srgrimes * This product includes software developed by the University of 241592Srgrimes * California, Berkeley and its contributors. 251592Srgrimes * 4. Neither the name of the University nor the names of its contributors 261592Srgrimes * may be used to endorse or promote products derived from this software 271592Srgrimes * without specific prior written permission. 281592Srgrimes * 291592Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 301592Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 311592Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 321592Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 331592Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 341592Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 351592Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 361592Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 371592Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 381592Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 391592Srgrimes * SUCH DAMAGE. 401592Srgrimes * 4127074Ssteve * from: @(#)utils.c 8.1 (Berkeley) 6/4/93 421592Srgrimes * 4327074Ssteve * From: Utah Hdr: utils.c 3.1 92/07/06 441592Srgrimes * Author: Jeff Forys, University of Utah CSS 451592Srgrimes */ 461592Srgrimes 471592Srgrimes#ifndef lint 4831386Scharnier#if 0 4927077Sstevestatic const char sccsid[] = "@(#)utils.c 8.1 (Berkeley) 6/4/93"; 5031386Scharnier#endif 5131386Scharnierstatic const char rcsid[] = 5250476Speter "$FreeBSD: head/libexec/rbootd/utils.c 90377 2002-02-07 23:57:01Z imp $"; 531592Srgrimes#endif /* not lint */ 541592Srgrimes 551592Srgrimes#include <sys/param.h> 5627077Ssteve#include <sys/time.h> 571592Srgrimes 581592Srgrimes#include <fcntl.h> 591592Srgrimes#include <signal.h> 601592Srgrimes#include <stdio.h> 611592Srgrimes#include <stdlib.h> 621592Srgrimes#include <string.h> 631592Srgrimes#include <syslog.h> 641592Srgrimes#include <time.h> 651592Srgrimes#include <unistd.h> 661592Srgrimes#include "defs.h" 671592Srgrimes 681592Srgrimes/* 691592Srgrimes** DispPkt -- Display the contents of an RMPCONN packet. 701592Srgrimes** 711592Srgrimes** Parameters: 721592Srgrimes** rconn - packet to be displayed. 731592Srgrimes** direct - direction packet is going (DIR_*). 741592Srgrimes** 751592Srgrimes** Returns: 761592Srgrimes** Nothing. 771592Srgrimes** 781592Srgrimes** Side Effects: 791592Srgrimes** None. 801592Srgrimes*/ 811592Srgrimesvoid 8290377SimpDispPkt(RMPCONN *rconn, int direct) 831592Srgrimes{ 8469252Skris static const char BootFmt[] = "\t\tRetCode:%u SeqNo:%lx SessID:%x Vers:%u"; 8569252Skris static const char ReadFmt[] = "\t\tRetCode:%u Offset:%lx SessID:%x\n"; 861592Srgrimes 871592Srgrimes struct tm *tmp; 8827079Ssteve struct rmp_packet *rmp; 891592Srgrimes int i, omask; 9027074Ssteve u_int32_t t; 911592Srgrimes 921592Srgrimes /* 931592Srgrimes * Since we will be working with RmpConns as well as DbgFp, we 941592Srgrimes * must block signals that can affect either. 951592Srgrimes */ 961592Srgrimes omask = sigblock(sigmask(SIGHUP)|sigmask(SIGUSR1)|sigmask(SIGUSR2)); 971592Srgrimes 981592Srgrimes if (DbgFp == NULL) { /* sanity */ 991592Srgrimes (void) sigsetmask(omask); 1001592Srgrimes return; 1011592Srgrimes } 1021592Srgrimes 1031592Srgrimes /* display direction packet is going using '>>>' or '<<<' */ 1041592Srgrimes fputs((direct==DIR_RCVD)?"<<< ":(direct==DIR_SENT)?">>> ":"", DbgFp); 1051592Srgrimes 1061592Srgrimes /* display packet timestamp */ 1071592Srgrimes tmp = localtime((time_t *)&rconn->tstamp.tv_sec); 1081592Srgrimes fprintf(DbgFp, "%02d:%02d:%02d.%06ld ", tmp->tm_hour, tmp->tm_min, 1091592Srgrimes tmp->tm_sec, rconn->tstamp.tv_usec); 1101592Srgrimes 1111592Srgrimes /* display src or dst addr and information about network interface */ 1121592Srgrimes fprintf(DbgFp, "Addr: %s Intf: %s\n", EnetStr(rconn), IntfName); 1131592Srgrimes 1141592Srgrimes rmp = &rconn->rmp; 1151592Srgrimes 1161592Srgrimes /* display IEEE 802.2 Logical Link Control header */ 1171592Srgrimes (void) fprintf(DbgFp, "\t802.2 LLC: DSAP:%x SSAP:%x CTRL:%x\n", 11827074Ssteve rmp->hp_llc.dsap, rmp->hp_llc.ssap, ntohs(rmp->hp_llc.cntrl)); 1191592Srgrimes 1201592Srgrimes /* display HP extensions to 802.2 Logical Link Control header */ 1211592Srgrimes (void) fprintf(DbgFp, "\tHP Ext: DXSAP:%x SXSAP:%x\n", 12227074Ssteve ntohs(rmp->hp_llc.dxsap), ntohs(rmp->hp_llc.sxsap)); 1231592Srgrimes 1241592Srgrimes /* 1251592Srgrimes * Display information about RMP packet using type field to 1261592Srgrimes * determine what kind of packet this is. 1271592Srgrimes */ 1281592Srgrimes switch(rmp->r_type) { 1291592Srgrimes case RMP_BOOT_REQ: /* boot request */ 1301592Srgrimes (void) fprintf(DbgFp, "\tBoot Request:"); 1311592Srgrimes GETWORD(rmp->r_brq.rmp_seqno, t); 13227074Ssteve if (ntohs(rmp->r_brq.rmp_session) == RMP_PROBESID) { 1331592Srgrimes if (WORDZE(rmp->r_brq.rmp_seqno)) 1341592Srgrimes fputs(" (Send Server ID)", DbgFp); 1351592Srgrimes else 1361592Srgrimes fprintf(DbgFp," (Send Filename #%u)",t); 1371592Srgrimes } 1381592Srgrimes (void) fputc('\n', DbgFp); 1391592Srgrimes (void) fprintf(DbgFp, BootFmt, rmp->r_brq.rmp_retcode, 14027074Ssteve t, ntohs(rmp->r_brq.rmp_session), 14127074Ssteve ntohs(rmp->r_brq.rmp_version)); 1421592Srgrimes (void) fprintf(DbgFp, "\n\t\tMachine Type: "); 1431592Srgrimes for (i = 0; i < RMP_MACHLEN; i++) 1441592Srgrimes (void) fputc(rmp->r_brq.rmp_machtype[i], DbgFp); 1451592Srgrimes DspFlnm(rmp->r_brq.rmp_flnmsize, &rmp->r_brq.rmp_flnm); 1461592Srgrimes break; 1471592Srgrimes case RMP_BOOT_REPL: /* boot reply */ 1481592Srgrimes fprintf(DbgFp, "\tBoot Reply:\n"); 1491592Srgrimes GETWORD(rmp->r_brpl.rmp_seqno, t); 1501592Srgrimes (void) fprintf(DbgFp, BootFmt, rmp->r_brpl.rmp_retcode, 15127074Ssteve t, ntohs(rmp->r_brpl.rmp_session), 15227074Ssteve ntohs(rmp->r_brpl.rmp_version)); 1531592Srgrimes DspFlnm(rmp->r_brpl.rmp_flnmsize,&rmp->r_brpl.rmp_flnm); 1541592Srgrimes break; 1551592Srgrimes case RMP_READ_REQ: /* read request */ 1561592Srgrimes (void) fprintf(DbgFp, "\tRead Request:\n"); 1571592Srgrimes GETWORD(rmp->r_rrq.rmp_offset, t); 1581592Srgrimes (void) fprintf(DbgFp, ReadFmt, rmp->r_rrq.rmp_retcode, 15927074Ssteve t, ntohs(rmp->r_rrq.rmp_session)); 1601592Srgrimes (void) fprintf(DbgFp, "\t\tNoOfBytes: %u\n", 16127074Ssteve ntohs(rmp->r_rrq.rmp_size)); 1621592Srgrimes break; 1631592Srgrimes case RMP_READ_REPL: /* read reply */ 1641592Srgrimes (void) fprintf(DbgFp, "\tRead Reply:\n"); 1651592Srgrimes GETWORD(rmp->r_rrpl.rmp_offset, t); 1661592Srgrimes (void) fprintf(DbgFp, ReadFmt, rmp->r_rrpl.rmp_retcode, 16727074Ssteve t, ntohs(rmp->r_rrpl.rmp_session)); 1681592Srgrimes (void) fprintf(DbgFp, "\t\tNoOfBytesSent: %d\n", 1691592Srgrimes rconn->rmplen - RMPREADSIZE(0)); 1701592Srgrimes break; 1711592Srgrimes case RMP_BOOT_DONE: /* boot complete */ 1721592Srgrimes (void) fprintf(DbgFp, "\tBoot Complete:\n"); 1731592Srgrimes (void) fprintf(DbgFp, "\t\tRetCode:%u SessID:%x\n", 1741592Srgrimes rmp->r_done.rmp_retcode, 17527074Ssteve ntohs(rmp->r_done.rmp_session)); 1761592Srgrimes break; 1771592Srgrimes default: /* ??? */ 1781592Srgrimes (void) fprintf(DbgFp, "\tUnknown Type:(%d)\n", 1791592Srgrimes rmp->r_type); 1801592Srgrimes } 1811592Srgrimes (void) fputc('\n', DbgFp); 1821592Srgrimes (void) fflush(DbgFp); 1831592Srgrimes 1841592Srgrimes (void) sigsetmask(omask); /* reset old signal mask */ 1851592Srgrimes} 1861592Srgrimes 1871592Srgrimes 1881592Srgrimes/* 1891592Srgrimes** GetEtherAddr -- convert an RMP (Ethernet) address into a string. 1901592Srgrimes** 1911592Srgrimes** An RMP BOOT packet has been received. Look at the type field 1921592Srgrimes** and process Boot Requests, Read Requests, and Boot Complete 1931592Srgrimes** packets. Any other type will be dropped with a warning msg. 1941592Srgrimes** 1951592Srgrimes** Parameters: 1961592Srgrimes** addr - array of RMP_ADDRLEN bytes. 1971592Srgrimes** 1981592Srgrimes** Returns: 1991592Srgrimes** Pointer to static string representation of `addr'. 2001592Srgrimes** 2011592Srgrimes** Side Effects: 2021592Srgrimes** None. 2031592Srgrimes** 2041592Srgrimes** Warnings: 2051592Srgrimes** - The return value points to a static buffer; it must 2061592Srgrimes** be copied if it's to be saved. 2071592Srgrimes*/ 2081592Srgrimeschar * 20990377SimpGetEtherAddr(u_int8_t *addr) 2101592Srgrimes{ 2111592Srgrimes static char Hex[] = "0123456789abcdef"; 2121592Srgrimes static char etherstr[RMP_ADDRLEN*3]; 21327079Ssteve int i; 21427079Ssteve char *cp; 2151592Srgrimes 2161592Srgrimes /* 2171592Srgrimes * For each byte in `addr', convert it to "<hexchar><hexchar>:". 2181592Srgrimes * The last byte does not get a trailing `:' appended. 2191592Srgrimes */ 2201592Srgrimes i = 0; 22127074Ssteve cp = etherstr; 2221592Srgrimes for(;;) { 22327074Ssteve *cp++ = Hex[*addr >> 4 & 0xf]; 22427074Ssteve *cp++ = Hex[*addr++ & 0xf]; 2251592Srgrimes if (++i == RMP_ADDRLEN) 2261592Srgrimes break; 22727074Ssteve *cp++ = ':'; 2281592Srgrimes } 22927074Ssteve *cp = '\0'; 2301592Srgrimes 2311592Srgrimes return(etherstr); 2321592Srgrimes} 2331592Srgrimes 2341592Srgrimes 2351592Srgrimes/* 2361592Srgrimes** DispFlnm -- Print a string of bytes to DbgFp (often, a file name). 2371592Srgrimes** 2381592Srgrimes** Parameters: 2391592Srgrimes** size - number of bytes to print. 2401592Srgrimes** flnm - address of first byte. 2411592Srgrimes** 2421592Srgrimes** Returns: 2431592Srgrimes** Nothing. 2441592Srgrimes** 2451592Srgrimes** Side Effects: 2461592Srgrimes** - Characters are sent to `DbgFp'. 2471592Srgrimes*/ 2481592Srgrimesvoid 24990377SimpDspFlnm(u_int size, char *flnm) 2501592Srgrimes{ 25127079Ssteve int i; 2521592Srgrimes 25327074Ssteve (void) fprintf(DbgFp, "\n\t\tFile Name (%u): <", size); 2541592Srgrimes for (i = 0; i < size; i++) 2551592Srgrimes (void) fputc(*flnm++, DbgFp); 2561592Srgrimes (void) fputs(">\n", DbgFp); 2571592Srgrimes} 2581592Srgrimes 2591592Srgrimes 2601592Srgrimes/* 2611592Srgrimes** NewClient -- allocate memory for a new CLIENT. 2621592Srgrimes** 2631592Srgrimes** Parameters: 2641592Srgrimes** addr - RMP (Ethernet) address of new client. 2651592Srgrimes** 2661592Srgrimes** Returns: 2671592Srgrimes** Ptr to new CLIENT or NULL if we ran out of memory. 2681592Srgrimes** 2691592Srgrimes** Side Effects: 2701592Srgrimes** - Memory will be malloc'd for the new CLIENT. 2711592Srgrimes** - If malloc() fails, a log message will be generated. 2721592Srgrimes*/ 2731592SrgrimesCLIENT * 27490377SimpNewClient(u_int8_t *addr) 2751592Srgrimes{ 2761592Srgrimes CLIENT *ctmp; 2771592Srgrimes 2781592Srgrimes if ((ctmp = (CLIENT *) malloc(sizeof(CLIENT))) == NULL) { 2791592Srgrimes syslog(LOG_ERR, "NewClient: out of memory (%s)", 2801592Srgrimes GetEtherAddr(addr)); 2811592Srgrimes return(NULL); 2821592Srgrimes } 2831592Srgrimes 28427079Ssteve memset(ctmp, 0, sizeof(CLIENT)); 28527079Ssteve memmove(&ctmp->addr[0], addr, RMP_ADDRLEN); 2861592Srgrimes return(ctmp); 2871592Srgrimes} 2881592Srgrimes 2891592Srgrimes/* 2901592Srgrimes** FreeClient -- free linked list of Clients. 2911592Srgrimes** 2921592Srgrimes** Parameters: 2931592Srgrimes** None. 2941592Srgrimes** 2951592Srgrimes** Returns: 2961592Srgrimes** Nothing. 2971592Srgrimes** 2981592Srgrimes** Side Effects: 2991592Srgrimes** - All malloc'd memory associated with the linked list of 3001592Srgrimes** CLIENTS will be free'd; `Clients' will be set to NULL. 3011592Srgrimes** 3021592Srgrimes** Warnings: 3031592Srgrimes** - This routine must be called with SIGHUP blocked. 3041592Srgrimes*/ 3051592Srgrimesvoid 30690377SimpFreeClients(void) 3071592Srgrimes{ 30827079Ssteve CLIENT *ctmp; 3091592Srgrimes 3101592Srgrimes while (Clients != NULL) { 3111592Srgrimes ctmp = Clients; 3121592Srgrimes Clients = Clients->next; 3131592Srgrimes FreeClient(ctmp); 3141592Srgrimes } 3151592Srgrimes} 3161592Srgrimes 3171592Srgrimes/* 3181592Srgrimes** NewStr -- allocate memory for a character array. 3191592Srgrimes** 3201592Srgrimes** Parameters: 3211592Srgrimes** str - null terminated character array. 3221592Srgrimes** 3231592Srgrimes** Returns: 3241592Srgrimes** Ptr to new character array or NULL if we ran out of memory. 3251592Srgrimes** 3261592Srgrimes** Side Effects: 3271592Srgrimes** - Memory will be malloc'd for the new character array. 3281592Srgrimes** - If malloc() fails, a log message will be generated. 3291592Srgrimes*/ 3301592Srgrimeschar * 33190377SimpNewStr(char *str) 3321592Srgrimes{ 3331592Srgrimes char *stmp; 3341592Srgrimes 3351592Srgrimes if ((stmp = (char *)malloc((unsigned) (strlen(str)+1))) == NULL) { 3361592Srgrimes syslog(LOG_ERR, "NewStr: out of memory (%s)", str); 3371592Srgrimes return(NULL); 3381592Srgrimes } 3391592Srgrimes 3401592Srgrimes (void) strcpy(stmp, str); 3411592Srgrimes return(stmp); 3421592Srgrimes} 3431592Srgrimes 3441592Srgrimes/* 3451592Srgrimes** To save time, NewConn and FreeConn maintain a cache of one RMPCONN 3461592Srgrimes** in `LastFree' (defined below). 3471592Srgrimes*/ 3481592Srgrimes 3491592Srgrimesstatic RMPCONN *LastFree = NULL; 3501592Srgrimes 3511592Srgrimes/* 3521592Srgrimes** NewConn -- allocate memory for a new RMPCONN connection. 3531592Srgrimes** 3541592Srgrimes** Parameters: 3551592Srgrimes** rconn - initialization template for new connection. 3561592Srgrimes** 3571592Srgrimes** Returns: 3581592Srgrimes** Ptr to new RMPCONN or NULL if we ran out of memory. 3591592Srgrimes** 3601592Srgrimes** Side Effects: 3611592Srgrimes** - Memory may be malloc'd for the new RMPCONN (if not cached). 3621592Srgrimes** - If malloc() fails, a log message will be generated. 3631592Srgrimes*/ 3641592SrgrimesRMPCONN * 36590377SimpNewConn(RMPCONN *rconn) 3661592Srgrimes{ 3671592Srgrimes RMPCONN *rtmp; 3681592Srgrimes 3691592Srgrimes if (LastFree == NULL) { /* nothing cached; make a new one */ 3701592Srgrimes if ((rtmp = (RMPCONN *) malloc(sizeof(RMPCONN))) == NULL) { 3711592Srgrimes syslog(LOG_ERR, "NewConn: out of memory (%s)", 3721592Srgrimes EnetStr(rconn)); 3731592Srgrimes return(NULL); 3741592Srgrimes } 3751592Srgrimes } else { /* use the cached RMPCONN */ 3761592Srgrimes rtmp = LastFree; 3771592Srgrimes LastFree = NULL; 3781592Srgrimes } 3791592Srgrimes 3801592Srgrimes /* 3811592Srgrimes * Copy template into `rtmp', init file descriptor to `-1' and 3821592Srgrimes * set ptr to next elem NULL. 3831592Srgrimes */ 38427079Ssteve memmove((char *)rtmp, (char *)rconn, sizeof(RMPCONN)); 3851592Srgrimes rtmp->bootfd = -1; 3861592Srgrimes rtmp->next = NULL; 3871592Srgrimes 3881592Srgrimes return(rtmp); 3891592Srgrimes} 3901592Srgrimes 3911592Srgrimes/* 3921592Srgrimes** FreeConn -- Free memory associated with an RMPCONN connection. 3931592Srgrimes** 3941592Srgrimes** Parameters: 3951592Srgrimes** rtmp - ptr to RMPCONN to be free'd. 3961592Srgrimes** 3971592Srgrimes** Returns: 3981592Srgrimes** Nothing. 3991592Srgrimes** 4001592Srgrimes** Side Effects: 4011592Srgrimes** - Memory associated with `rtmp' may be free'd (or cached). 4021592Srgrimes** - File desc associated with `rtmp->bootfd' will be closed. 4031592Srgrimes*/ 4041592Srgrimesvoid 40590377SimpFreeConn(RMPCONN *rtmp) 4061592Srgrimes{ 4071592Srgrimes /* 4081592Srgrimes * If the file descriptor is in use, close the file. 4091592Srgrimes */ 4101592Srgrimes if (rtmp->bootfd >= 0) { 4111592Srgrimes (void) close(rtmp->bootfd); 4121592Srgrimes rtmp->bootfd = -1; 4131592Srgrimes } 4141592Srgrimes 4151592Srgrimes if (LastFree == NULL) /* cache for next time */ 4161592Srgrimes rtmp = LastFree; 4171592Srgrimes else /* already one cached; free this one */ 4181592Srgrimes free((char *)rtmp); 4191592Srgrimes} 4201592Srgrimes 4211592Srgrimes/* 4221592Srgrimes** FreeConns -- free linked list of RMPCONN connections. 4231592Srgrimes** 4241592Srgrimes** Parameters: 4251592Srgrimes** None. 4261592Srgrimes** 4271592Srgrimes** Returns: 4281592Srgrimes** Nothing. 4291592Srgrimes** 4301592Srgrimes** Side Effects: 4311592Srgrimes** - All malloc'd memory associated with the linked list of 4321592Srgrimes** connections will be free'd; `RmpConns' will be set to NULL. 4331592Srgrimes** - If LastFree is != NULL, it too will be free'd & NULL'd. 4341592Srgrimes** 4351592Srgrimes** Warnings: 4361592Srgrimes** - This routine must be called with SIGHUP blocked. 4371592Srgrimes*/ 4381592Srgrimesvoid 43990377SimpFreeConns(void) 4401592Srgrimes{ 44127079Ssteve RMPCONN *rtmp; 4421592Srgrimes 4431592Srgrimes while (RmpConns != NULL) { 4441592Srgrimes rtmp = RmpConns; 4451592Srgrimes RmpConns = RmpConns->next; 4461592Srgrimes FreeConn(rtmp); 4471592Srgrimes } 4481592Srgrimes 4491592Srgrimes if (LastFree != NULL) { 4501592Srgrimes free((char *)LastFree); 4511592Srgrimes LastFree = NULL; 4521592Srgrimes } 4531592Srgrimes} 4541592Srgrimes 4551592Srgrimes/* 4561592Srgrimes** AddConn -- Add a connection to the linked list of connections. 4571592Srgrimes** 4581592Srgrimes** Parameters: 4591592Srgrimes** rconn - connection to be added. 4601592Srgrimes** 4611592Srgrimes** Returns: 4621592Srgrimes** Nothing. 4631592Srgrimes** 4641592Srgrimes** Side Effects: 4651592Srgrimes** - RmpConn will point to new connection. 4661592Srgrimes** 4671592Srgrimes** Warnings: 4681592Srgrimes** - This routine must be called with SIGHUP blocked. 4691592Srgrimes*/ 4701592Srgrimesvoid 47190377SimpAddConn(RMPCONN *rconn) 4721592Srgrimes{ 4731592Srgrimes if (RmpConns != NULL) 4741592Srgrimes rconn->next = RmpConns; 4751592Srgrimes RmpConns = rconn; 4761592Srgrimes} 4771592Srgrimes 4781592Srgrimes/* 4791592Srgrimes** FindConn -- Find a connection in the linked list of connections. 4801592Srgrimes** 4811592Srgrimes** We use the RMP (Ethernet) address as the basis for determining 4821592Srgrimes** if this is the same connection. According to the Remote Maint 4831592Srgrimes** Protocol, we can only have one connection with any machine. 4841592Srgrimes** 4851592Srgrimes** Parameters: 4861592Srgrimes** rconn - connection to be found. 4871592Srgrimes** 4881592Srgrimes** Returns: 4891592Srgrimes** Matching connection from linked list or NULL if not found. 4901592Srgrimes** 4911592Srgrimes** Side Effects: 4921592Srgrimes** None. 4931592Srgrimes** 4941592Srgrimes** Warnings: 4951592Srgrimes** - This routine must be called with SIGHUP blocked. 4961592Srgrimes*/ 4971592SrgrimesRMPCONN * 49890377SimpFindConn(RMPCONN *rconn) 4991592Srgrimes{ 50027079Ssteve RMPCONN *rtmp; 5011592Srgrimes 5021592Srgrimes for (rtmp = RmpConns; rtmp != NULL; rtmp = rtmp->next) 5031592Srgrimes if (bcmp((char *)&rconn->rmp.hp_hdr.saddr[0], 5041592Srgrimes (char *)&rtmp->rmp.hp_hdr.saddr[0], RMP_ADDRLEN) == 0) 5051592Srgrimes break; 5061592Srgrimes 5071592Srgrimes return(rtmp); 5081592Srgrimes} 5091592Srgrimes 5101592Srgrimes/* 5111592Srgrimes** RemoveConn -- Remove a connection from the linked list of connections. 5121592Srgrimes** 5131592Srgrimes** Parameters: 5141592Srgrimes** rconn - connection to be removed. 5151592Srgrimes** 5161592Srgrimes** Returns: 5171592Srgrimes** Nothing. 5181592Srgrimes** 5191592Srgrimes** Side Effects: 5201592Srgrimes** - If found, an RMPCONN will cease to exist and it will 5211592Srgrimes** be removed from the linked list. 5221592Srgrimes** 5231592Srgrimes** Warnings: 5241592Srgrimes** - This routine must be called with SIGHUP blocked. 5251592Srgrimes*/ 5261592Srgrimesvoid 52790377SimpRemoveConn(RMPCONN *rconn) 5281592Srgrimes{ 52927079Ssteve RMPCONN *thisrconn, *lastrconn; 5301592Srgrimes 5311592Srgrimes if (RmpConns == rconn) { /* easy case */ 5321592Srgrimes RmpConns = RmpConns->next; 5331592Srgrimes FreeConn(rconn); 5341592Srgrimes } else { /* must traverse linked list */ 5351592Srgrimes lastrconn = RmpConns; /* set back ptr */ 5361592Srgrimes thisrconn = lastrconn->next; /* set current ptr */ 5371592Srgrimes while (thisrconn != NULL) { 5381592Srgrimes if (rconn == thisrconn) { /* found it */ 5391592Srgrimes lastrconn->next = thisrconn->next; 5401592Srgrimes FreeConn(thisrconn); 5411592Srgrimes break; 5421592Srgrimes } 5431592Srgrimes lastrconn = thisrconn; 5441592Srgrimes thisrconn = thisrconn->next; 5451592Srgrimes } 5461592Srgrimes } 5471592Srgrimes} 548