utils.c revision 27079
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 4227079Ssteve * $Id: utils.c,v 1.2 1997/06/29 19:00:29 steve Exp $ 431592Srgrimes * 4427074Ssteve * From: Utah Hdr: utils.c 3.1 92/07/06 451592Srgrimes * Author: Jeff Forys, University of Utah CSS 461592Srgrimes */ 471592Srgrimes 481592Srgrimes#ifndef lint 4927077Sstevestatic const char sccsid[] = "@(#)utils.c 8.1 (Berkeley) 6/4/93"; 501592Srgrimes#endif /* not lint */ 511592Srgrimes 521592Srgrimes#include <sys/param.h> 5327077Ssteve#include <sys/time.h> 541592Srgrimes 551592Srgrimes#include <fcntl.h> 561592Srgrimes#include <signal.h> 571592Srgrimes#include <stdio.h> 581592Srgrimes#include <stdlib.h> 591592Srgrimes#include <string.h> 601592Srgrimes#include <syslog.h> 611592Srgrimes#include <time.h> 621592Srgrimes#include <unistd.h> 631592Srgrimes#include "defs.h" 641592Srgrimes 651592Srgrimes/* 661592Srgrimes** DispPkt -- Display the contents of an RMPCONN packet. 671592Srgrimes** 681592Srgrimes** Parameters: 691592Srgrimes** rconn - packet to be displayed. 701592Srgrimes** direct - direction packet is going (DIR_*). 711592Srgrimes** 721592Srgrimes** Returns: 731592Srgrimes** Nothing. 741592Srgrimes** 751592Srgrimes** Side Effects: 761592Srgrimes** None. 771592Srgrimes*/ 781592Srgrimesvoid 791592SrgrimesDispPkt(rconn, direct) 801592Srgrimes RMPCONN *rconn; 811592Srgrimes int direct; 821592Srgrimes{ 831592Srgrimes static char BootFmt[] = "\t\tRetCode:%u SeqNo:%lx SessID:%x Vers:%u"; 841592Srgrimes static char ReadFmt[] = "\t\tRetCode:%u Offset:%lx SessID:%x\n"; 851592Srgrimes 861592Srgrimes struct tm *tmp; 8727079Ssteve struct rmp_packet *rmp; 881592Srgrimes int i, omask; 8927074Ssteve u_int32_t t; 901592Srgrimes 911592Srgrimes /* 921592Srgrimes * Since we will be working with RmpConns as well as DbgFp, we 931592Srgrimes * must block signals that can affect either. 941592Srgrimes */ 951592Srgrimes omask = sigblock(sigmask(SIGHUP)|sigmask(SIGUSR1)|sigmask(SIGUSR2)); 961592Srgrimes 971592Srgrimes if (DbgFp == NULL) { /* sanity */ 981592Srgrimes (void) sigsetmask(omask); 991592Srgrimes return; 1001592Srgrimes } 1011592Srgrimes 1021592Srgrimes /* display direction packet is going using '>>>' or '<<<' */ 1031592Srgrimes fputs((direct==DIR_RCVD)?"<<< ":(direct==DIR_SENT)?">>> ":"", DbgFp); 1041592Srgrimes 1051592Srgrimes /* display packet timestamp */ 1061592Srgrimes tmp = localtime((time_t *)&rconn->tstamp.tv_sec); 1071592Srgrimes fprintf(DbgFp, "%02d:%02d:%02d.%06ld ", tmp->tm_hour, tmp->tm_min, 1081592Srgrimes tmp->tm_sec, rconn->tstamp.tv_usec); 1091592Srgrimes 1101592Srgrimes /* display src or dst addr and information about network interface */ 1111592Srgrimes fprintf(DbgFp, "Addr: %s Intf: %s\n", EnetStr(rconn), IntfName); 1121592Srgrimes 1131592Srgrimes rmp = &rconn->rmp; 1141592Srgrimes 1151592Srgrimes /* display IEEE 802.2 Logical Link Control header */ 1161592Srgrimes (void) fprintf(DbgFp, "\t802.2 LLC: DSAP:%x SSAP:%x CTRL:%x\n", 11727074Ssteve rmp->hp_llc.dsap, rmp->hp_llc.ssap, ntohs(rmp->hp_llc.cntrl)); 1181592Srgrimes 1191592Srgrimes /* display HP extensions to 802.2 Logical Link Control header */ 1201592Srgrimes (void) fprintf(DbgFp, "\tHP Ext: DXSAP:%x SXSAP:%x\n", 12127074Ssteve ntohs(rmp->hp_llc.dxsap), ntohs(rmp->hp_llc.sxsap)); 1221592Srgrimes 1231592Srgrimes /* 1241592Srgrimes * Display information about RMP packet using type field to 1251592Srgrimes * determine what kind of packet this is. 1261592Srgrimes */ 1271592Srgrimes switch(rmp->r_type) { 1281592Srgrimes case RMP_BOOT_REQ: /* boot request */ 1291592Srgrimes (void) fprintf(DbgFp, "\tBoot Request:"); 1301592Srgrimes GETWORD(rmp->r_brq.rmp_seqno, t); 13127074Ssteve if (ntohs(rmp->r_brq.rmp_session) == RMP_PROBESID) { 1321592Srgrimes if (WORDZE(rmp->r_brq.rmp_seqno)) 1331592Srgrimes fputs(" (Send Server ID)", DbgFp); 1341592Srgrimes else 1351592Srgrimes fprintf(DbgFp," (Send Filename #%u)",t); 1361592Srgrimes } 1371592Srgrimes (void) fputc('\n', DbgFp); 1381592Srgrimes (void) fprintf(DbgFp, BootFmt, rmp->r_brq.rmp_retcode, 13927074Ssteve t, ntohs(rmp->r_brq.rmp_session), 14027074Ssteve ntohs(rmp->r_brq.rmp_version)); 1411592Srgrimes (void) fprintf(DbgFp, "\n\t\tMachine Type: "); 1421592Srgrimes for (i = 0; i < RMP_MACHLEN; i++) 1431592Srgrimes (void) fputc(rmp->r_brq.rmp_machtype[i], DbgFp); 1441592Srgrimes DspFlnm(rmp->r_brq.rmp_flnmsize, &rmp->r_brq.rmp_flnm); 1451592Srgrimes break; 1461592Srgrimes case RMP_BOOT_REPL: /* boot reply */ 1471592Srgrimes fprintf(DbgFp, "\tBoot Reply:\n"); 1481592Srgrimes GETWORD(rmp->r_brpl.rmp_seqno, t); 1491592Srgrimes (void) fprintf(DbgFp, BootFmt, rmp->r_brpl.rmp_retcode, 15027074Ssteve t, ntohs(rmp->r_brpl.rmp_session), 15127074Ssteve ntohs(rmp->r_brpl.rmp_version)); 1521592Srgrimes DspFlnm(rmp->r_brpl.rmp_flnmsize,&rmp->r_brpl.rmp_flnm); 1531592Srgrimes break; 1541592Srgrimes case RMP_READ_REQ: /* read request */ 1551592Srgrimes (void) fprintf(DbgFp, "\tRead Request:\n"); 1561592Srgrimes GETWORD(rmp->r_rrq.rmp_offset, t); 1571592Srgrimes (void) fprintf(DbgFp, ReadFmt, rmp->r_rrq.rmp_retcode, 15827074Ssteve t, ntohs(rmp->r_rrq.rmp_session)); 1591592Srgrimes (void) fprintf(DbgFp, "\t\tNoOfBytes: %u\n", 16027074Ssteve ntohs(rmp->r_rrq.rmp_size)); 1611592Srgrimes break; 1621592Srgrimes case RMP_READ_REPL: /* read reply */ 1631592Srgrimes (void) fprintf(DbgFp, "\tRead Reply:\n"); 1641592Srgrimes GETWORD(rmp->r_rrpl.rmp_offset, t); 1651592Srgrimes (void) fprintf(DbgFp, ReadFmt, rmp->r_rrpl.rmp_retcode, 16627074Ssteve t, ntohs(rmp->r_rrpl.rmp_session)); 1671592Srgrimes (void) fprintf(DbgFp, "\t\tNoOfBytesSent: %d\n", 1681592Srgrimes rconn->rmplen - RMPREADSIZE(0)); 1691592Srgrimes break; 1701592Srgrimes case RMP_BOOT_DONE: /* boot complete */ 1711592Srgrimes (void) fprintf(DbgFp, "\tBoot Complete:\n"); 1721592Srgrimes (void) fprintf(DbgFp, "\t\tRetCode:%u SessID:%x\n", 1731592Srgrimes rmp->r_done.rmp_retcode, 17427074Ssteve ntohs(rmp->r_done.rmp_session)); 1751592Srgrimes break; 1761592Srgrimes default: /* ??? */ 1771592Srgrimes (void) fprintf(DbgFp, "\tUnknown Type:(%d)\n", 1781592Srgrimes rmp->r_type); 1791592Srgrimes } 1801592Srgrimes (void) fputc('\n', DbgFp); 1811592Srgrimes (void) fflush(DbgFp); 1821592Srgrimes 1831592Srgrimes (void) sigsetmask(omask); /* reset old signal mask */ 1841592Srgrimes} 1851592Srgrimes 1861592Srgrimes 1871592Srgrimes/* 1881592Srgrimes** GetEtherAddr -- convert an RMP (Ethernet) address into a string. 1891592Srgrimes** 1901592Srgrimes** An RMP BOOT packet has been received. Look at the type field 1911592Srgrimes** and process Boot Requests, Read Requests, and Boot Complete 1921592Srgrimes** packets. Any other type will be dropped with a warning msg. 1931592Srgrimes** 1941592Srgrimes** Parameters: 1951592Srgrimes** addr - array of RMP_ADDRLEN bytes. 1961592Srgrimes** 1971592Srgrimes** Returns: 1981592Srgrimes** Pointer to static string representation of `addr'. 1991592Srgrimes** 2001592Srgrimes** Side Effects: 2011592Srgrimes** None. 2021592Srgrimes** 2031592Srgrimes** Warnings: 2041592Srgrimes** - The return value points to a static buffer; it must 2051592Srgrimes** be copied if it's to be saved. 2061592Srgrimes*/ 2071592Srgrimeschar * 2081592SrgrimesGetEtherAddr(addr) 20927074Ssteve 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 2491592SrgrimesDspFlnm(size, flnm) 25027079Ssteve u_int size; 25127079Ssteve char *flnm; 2521592Srgrimes{ 25327079Ssteve int i; 2541592Srgrimes 25527074Ssteve (void) fprintf(DbgFp, "\n\t\tFile Name (%u): <", size); 2561592Srgrimes for (i = 0; i < size; i++) 2571592Srgrimes (void) fputc(*flnm++, DbgFp); 2581592Srgrimes (void) fputs(">\n", DbgFp); 2591592Srgrimes} 2601592Srgrimes 2611592Srgrimes 2621592Srgrimes/* 2631592Srgrimes** NewClient -- allocate memory for a new CLIENT. 2641592Srgrimes** 2651592Srgrimes** Parameters: 2661592Srgrimes** addr - RMP (Ethernet) address of new client. 2671592Srgrimes** 2681592Srgrimes** Returns: 2691592Srgrimes** Ptr to new CLIENT or NULL if we ran out of memory. 2701592Srgrimes** 2711592Srgrimes** Side Effects: 2721592Srgrimes** - Memory will be malloc'd for the new CLIENT. 2731592Srgrimes** - If malloc() fails, a log message will be generated. 2741592Srgrimes*/ 2751592SrgrimesCLIENT * 2761592SrgrimesNewClient(addr) 27727074Ssteve u_int8_t *addr; 2781592Srgrimes{ 2791592Srgrimes CLIENT *ctmp; 2801592Srgrimes 2811592Srgrimes if ((ctmp = (CLIENT *) malloc(sizeof(CLIENT))) == NULL) { 2821592Srgrimes syslog(LOG_ERR, "NewClient: out of memory (%s)", 2831592Srgrimes GetEtherAddr(addr)); 2841592Srgrimes return(NULL); 2851592Srgrimes } 2861592Srgrimes 28727079Ssteve memset(ctmp, 0, sizeof(CLIENT)); 28827079Ssteve memmove(&ctmp->addr[0], addr, RMP_ADDRLEN); 2891592Srgrimes return(ctmp); 2901592Srgrimes} 2911592Srgrimes 2921592Srgrimes/* 2931592Srgrimes** FreeClient -- free linked list of Clients. 2941592Srgrimes** 2951592Srgrimes** Parameters: 2961592Srgrimes** None. 2971592Srgrimes** 2981592Srgrimes** Returns: 2991592Srgrimes** Nothing. 3001592Srgrimes** 3011592Srgrimes** Side Effects: 3021592Srgrimes** - All malloc'd memory associated with the linked list of 3031592Srgrimes** CLIENTS will be free'd; `Clients' will be set to NULL. 3041592Srgrimes** 3051592Srgrimes** Warnings: 3061592Srgrimes** - This routine must be called with SIGHUP blocked. 3071592Srgrimes*/ 3081592Srgrimesvoid 3091592SrgrimesFreeClients() 3101592Srgrimes{ 31127079Ssteve CLIENT *ctmp; 3121592Srgrimes 3131592Srgrimes while (Clients != NULL) { 3141592Srgrimes ctmp = Clients; 3151592Srgrimes Clients = Clients->next; 3161592Srgrimes FreeClient(ctmp); 3171592Srgrimes } 3181592Srgrimes} 3191592Srgrimes 3201592Srgrimes/* 3211592Srgrimes** NewStr -- allocate memory for a character array. 3221592Srgrimes** 3231592Srgrimes** Parameters: 3241592Srgrimes** str - null terminated character array. 3251592Srgrimes** 3261592Srgrimes** Returns: 3271592Srgrimes** Ptr to new character array or NULL if we ran out of memory. 3281592Srgrimes** 3291592Srgrimes** Side Effects: 3301592Srgrimes** - Memory will be malloc'd for the new character array. 3311592Srgrimes** - If malloc() fails, a log message will be generated. 3321592Srgrimes*/ 3331592Srgrimeschar * 3341592SrgrimesNewStr(str) 3351592Srgrimes char *str; 3361592Srgrimes{ 3371592Srgrimes char *stmp; 3381592Srgrimes 3391592Srgrimes if ((stmp = (char *)malloc((unsigned) (strlen(str)+1))) == NULL) { 3401592Srgrimes syslog(LOG_ERR, "NewStr: out of memory (%s)", str); 3411592Srgrimes return(NULL); 3421592Srgrimes } 3431592Srgrimes 3441592Srgrimes (void) strcpy(stmp, str); 3451592Srgrimes return(stmp); 3461592Srgrimes} 3471592Srgrimes 3481592Srgrimes/* 3491592Srgrimes** To save time, NewConn and FreeConn maintain a cache of one RMPCONN 3501592Srgrimes** in `LastFree' (defined below). 3511592Srgrimes*/ 3521592Srgrimes 3531592Srgrimesstatic RMPCONN *LastFree = NULL; 3541592Srgrimes 3551592Srgrimes/* 3561592Srgrimes** NewConn -- allocate memory for a new RMPCONN connection. 3571592Srgrimes** 3581592Srgrimes** Parameters: 3591592Srgrimes** rconn - initialization template for new connection. 3601592Srgrimes** 3611592Srgrimes** Returns: 3621592Srgrimes** Ptr to new RMPCONN or NULL if we ran out of memory. 3631592Srgrimes** 3641592Srgrimes** Side Effects: 3651592Srgrimes** - Memory may be malloc'd for the new RMPCONN (if not cached). 3661592Srgrimes** - If malloc() fails, a log message will be generated. 3671592Srgrimes*/ 3681592SrgrimesRMPCONN * 3691592SrgrimesNewConn(rconn) 3701592Srgrimes RMPCONN *rconn; 3711592Srgrimes{ 3721592Srgrimes RMPCONN *rtmp; 3731592Srgrimes 3741592Srgrimes if (LastFree == NULL) { /* nothing cached; make a new one */ 3751592Srgrimes if ((rtmp = (RMPCONN *) malloc(sizeof(RMPCONN))) == NULL) { 3761592Srgrimes syslog(LOG_ERR, "NewConn: out of memory (%s)", 3771592Srgrimes EnetStr(rconn)); 3781592Srgrimes return(NULL); 3791592Srgrimes } 3801592Srgrimes } else { /* use the cached RMPCONN */ 3811592Srgrimes rtmp = LastFree; 3821592Srgrimes LastFree = NULL; 3831592Srgrimes } 3841592Srgrimes 3851592Srgrimes /* 3861592Srgrimes * Copy template into `rtmp', init file descriptor to `-1' and 3871592Srgrimes * set ptr to next elem NULL. 3881592Srgrimes */ 38927079Ssteve memmove((char *)rtmp, (char *)rconn, sizeof(RMPCONN)); 3901592Srgrimes rtmp->bootfd = -1; 3911592Srgrimes rtmp->next = NULL; 3921592Srgrimes 3931592Srgrimes return(rtmp); 3941592Srgrimes} 3951592Srgrimes 3961592Srgrimes/* 3971592Srgrimes** FreeConn -- Free memory associated with an RMPCONN connection. 3981592Srgrimes** 3991592Srgrimes** Parameters: 4001592Srgrimes** rtmp - ptr to RMPCONN to be free'd. 4011592Srgrimes** 4021592Srgrimes** Returns: 4031592Srgrimes** Nothing. 4041592Srgrimes** 4051592Srgrimes** Side Effects: 4061592Srgrimes** - Memory associated with `rtmp' may be free'd (or cached). 4071592Srgrimes** - File desc associated with `rtmp->bootfd' will be closed. 4081592Srgrimes*/ 4091592Srgrimesvoid 4101592SrgrimesFreeConn(rtmp) 41127079Ssteve RMPCONN *rtmp; 4121592Srgrimes{ 4131592Srgrimes /* 4141592Srgrimes * If the file descriptor is in use, close the file. 4151592Srgrimes */ 4161592Srgrimes if (rtmp->bootfd >= 0) { 4171592Srgrimes (void) close(rtmp->bootfd); 4181592Srgrimes rtmp->bootfd = -1; 4191592Srgrimes } 4201592Srgrimes 4211592Srgrimes if (LastFree == NULL) /* cache for next time */ 4221592Srgrimes rtmp = LastFree; 4231592Srgrimes else /* already one cached; free this one */ 4241592Srgrimes free((char *)rtmp); 4251592Srgrimes} 4261592Srgrimes 4271592Srgrimes/* 4281592Srgrimes** FreeConns -- free linked list of RMPCONN connections. 4291592Srgrimes** 4301592Srgrimes** Parameters: 4311592Srgrimes** None. 4321592Srgrimes** 4331592Srgrimes** Returns: 4341592Srgrimes** Nothing. 4351592Srgrimes** 4361592Srgrimes** Side Effects: 4371592Srgrimes** - All malloc'd memory associated with the linked list of 4381592Srgrimes** connections will be free'd; `RmpConns' will be set to NULL. 4391592Srgrimes** - If LastFree is != NULL, it too will be free'd & NULL'd. 4401592Srgrimes** 4411592Srgrimes** Warnings: 4421592Srgrimes** - This routine must be called with SIGHUP blocked. 4431592Srgrimes*/ 4441592Srgrimesvoid 4451592SrgrimesFreeConns() 4461592Srgrimes{ 44727079Ssteve RMPCONN *rtmp; 4481592Srgrimes 4491592Srgrimes while (RmpConns != NULL) { 4501592Srgrimes rtmp = RmpConns; 4511592Srgrimes RmpConns = RmpConns->next; 4521592Srgrimes FreeConn(rtmp); 4531592Srgrimes } 4541592Srgrimes 4551592Srgrimes if (LastFree != NULL) { 4561592Srgrimes free((char *)LastFree); 4571592Srgrimes LastFree = NULL; 4581592Srgrimes } 4591592Srgrimes} 4601592Srgrimes 4611592Srgrimes/* 4621592Srgrimes** AddConn -- Add a connection to the linked list of connections. 4631592Srgrimes** 4641592Srgrimes** Parameters: 4651592Srgrimes** rconn - connection to be added. 4661592Srgrimes** 4671592Srgrimes** Returns: 4681592Srgrimes** Nothing. 4691592Srgrimes** 4701592Srgrimes** Side Effects: 4711592Srgrimes** - RmpConn will point to new connection. 4721592Srgrimes** 4731592Srgrimes** Warnings: 4741592Srgrimes** - This routine must be called with SIGHUP blocked. 4751592Srgrimes*/ 4761592Srgrimesvoid 4771592SrgrimesAddConn(rconn) 47827079Ssteve RMPCONN *rconn; 4791592Srgrimes{ 4801592Srgrimes if (RmpConns != NULL) 4811592Srgrimes rconn->next = RmpConns; 4821592Srgrimes RmpConns = rconn; 4831592Srgrimes} 4841592Srgrimes 4851592Srgrimes/* 4861592Srgrimes** FindConn -- Find a connection in the linked list of connections. 4871592Srgrimes** 4881592Srgrimes** We use the RMP (Ethernet) address as the basis for determining 4891592Srgrimes** if this is the same connection. According to the Remote Maint 4901592Srgrimes** Protocol, we can only have one connection with any machine. 4911592Srgrimes** 4921592Srgrimes** Parameters: 4931592Srgrimes** rconn - connection to be found. 4941592Srgrimes** 4951592Srgrimes** Returns: 4961592Srgrimes** Matching connection from linked list or NULL if not found. 4971592Srgrimes** 4981592Srgrimes** Side Effects: 4991592Srgrimes** None. 5001592Srgrimes** 5011592Srgrimes** Warnings: 5021592Srgrimes** - This routine must be called with SIGHUP blocked. 5031592Srgrimes*/ 5041592SrgrimesRMPCONN * 5051592SrgrimesFindConn(rconn) 50627079Ssteve RMPCONN *rconn; 5071592Srgrimes{ 50827079Ssteve RMPCONN *rtmp; 5091592Srgrimes 5101592Srgrimes for (rtmp = RmpConns; rtmp != NULL; rtmp = rtmp->next) 5111592Srgrimes if (bcmp((char *)&rconn->rmp.hp_hdr.saddr[0], 5121592Srgrimes (char *)&rtmp->rmp.hp_hdr.saddr[0], RMP_ADDRLEN) == 0) 5131592Srgrimes break; 5141592Srgrimes 5151592Srgrimes return(rtmp); 5161592Srgrimes} 5171592Srgrimes 5181592Srgrimes/* 5191592Srgrimes** RemoveConn -- Remove a connection from the linked list of connections. 5201592Srgrimes** 5211592Srgrimes** Parameters: 5221592Srgrimes** rconn - connection to be removed. 5231592Srgrimes** 5241592Srgrimes** Returns: 5251592Srgrimes** Nothing. 5261592Srgrimes** 5271592Srgrimes** Side Effects: 5281592Srgrimes** - If found, an RMPCONN will cease to exist and it will 5291592Srgrimes** be removed from the linked list. 5301592Srgrimes** 5311592Srgrimes** Warnings: 5321592Srgrimes** - This routine must be called with SIGHUP blocked. 5331592Srgrimes*/ 5341592Srgrimesvoid 5351592SrgrimesRemoveConn(rconn) 53627079Ssteve RMPCONN *rconn; 5371592Srgrimes{ 53827079Ssteve RMPCONN *thisrconn, *lastrconn; 5391592Srgrimes 5401592Srgrimes if (RmpConns == rconn) { /* easy case */ 5411592Srgrimes RmpConns = RmpConns->next; 5421592Srgrimes FreeConn(rconn); 5431592Srgrimes } else { /* must traverse linked list */ 5441592Srgrimes lastrconn = RmpConns; /* set back ptr */ 5451592Srgrimes thisrconn = lastrconn->next; /* set current ptr */ 5461592Srgrimes while (thisrconn != NULL) { 5471592Srgrimes if (rconn == thisrconn) { /* found it */ 5481592Srgrimes lastrconn->next = thisrconn->next; 5491592Srgrimes FreeConn(thisrconn); 5501592Srgrimes break; 5511592Srgrimes } 5521592Srgrimes lastrconn = thisrconn; 5531592Srgrimes thisrconn = thisrconn->next; 5541592Srgrimes } 5551592Srgrimes } 5561592Srgrimes} 557