utils.c revision 50476
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 50476 1999-08-28 00:22:10Z peter $"; 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 821592SrgrimesDispPkt(rconn, direct) 831592Srgrimes RMPCONN *rconn; 841592Srgrimes int direct; 851592Srgrimes{ 861592Srgrimes static char BootFmt[] = "\t\tRetCode:%u SeqNo:%lx SessID:%x Vers:%u"; 871592Srgrimes static char ReadFmt[] = "\t\tRetCode:%u Offset:%lx SessID:%x\n"; 881592Srgrimes 891592Srgrimes struct tm *tmp; 9027079Ssteve struct rmp_packet *rmp; 911592Srgrimes int i, omask; 9227074Ssteve u_int32_t t; 931592Srgrimes 941592Srgrimes /* 951592Srgrimes * Since we will be working with RmpConns as well as DbgFp, we 961592Srgrimes * must block signals that can affect either. 971592Srgrimes */ 981592Srgrimes omask = sigblock(sigmask(SIGHUP)|sigmask(SIGUSR1)|sigmask(SIGUSR2)); 991592Srgrimes 1001592Srgrimes if (DbgFp == NULL) { /* sanity */ 1011592Srgrimes (void) sigsetmask(omask); 1021592Srgrimes return; 1031592Srgrimes } 1041592Srgrimes 1051592Srgrimes /* display direction packet is going using '>>>' or '<<<' */ 1061592Srgrimes fputs((direct==DIR_RCVD)?"<<< ":(direct==DIR_SENT)?">>> ":"", DbgFp); 1071592Srgrimes 1081592Srgrimes /* display packet timestamp */ 1091592Srgrimes tmp = localtime((time_t *)&rconn->tstamp.tv_sec); 1101592Srgrimes fprintf(DbgFp, "%02d:%02d:%02d.%06ld ", tmp->tm_hour, tmp->tm_min, 1111592Srgrimes tmp->tm_sec, rconn->tstamp.tv_usec); 1121592Srgrimes 1131592Srgrimes /* display src or dst addr and information about network interface */ 1141592Srgrimes fprintf(DbgFp, "Addr: %s Intf: %s\n", EnetStr(rconn), IntfName); 1151592Srgrimes 1161592Srgrimes rmp = &rconn->rmp; 1171592Srgrimes 1181592Srgrimes /* display IEEE 802.2 Logical Link Control header */ 1191592Srgrimes (void) fprintf(DbgFp, "\t802.2 LLC: DSAP:%x SSAP:%x CTRL:%x\n", 12027074Ssteve rmp->hp_llc.dsap, rmp->hp_llc.ssap, ntohs(rmp->hp_llc.cntrl)); 1211592Srgrimes 1221592Srgrimes /* display HP extensions to 802.2 Logical Link Control header */ 1231592Srgrimes (void) fprintf(DbgFp, "\tHP Ext: DXSAP:%x SXSAP:%x\n", 12427074Ssteve ntohs(rmp->hp_llc.dxsap), ntohs(rmp->hp_llc.sxsap)); 1251592Srgrimes 1261592Srgrimes /* 1271592Srgrimes * Display information about RMP packet using type field to 1281592Srgrimes * determine what kind of packet this is. 1291592Srgrimes */ 1301592Srgrimes switch(rmp->r_type) { 1311592Srgrimes case RMP_BOOT_REQ: /* boot request */ 1321592Srgrimes (void) fprintf(DbgFp, "\tBoot Request:"); 1331592Srgrimes GETWORD(rmp->r_brq.rmp_seqno, t); 13427074Ssteve if (ntohs(rmp->r_brq.rmp_session) == RMP_PROBESID) { 1351592Srgrimes if (WORDZE(rmp->r_brq.rmp_seqno)) 1361592Srgrimes fputs(" (Send Server ID)", DbgFp); 1371592Srgrimes else 1381592Srgrimes fprintf(DbgFp," (Send Filename #%u)",t); 1391592Srgrimes } 1401592Srgrimes (void) fputc('\n', DbgFp); 1411592Srgrimes (void) fprintf(DbgFp, BootFmt, rmp->r_brq.rmp_retcode, 14227074Ssteve t, ntohs(rmp->r_brq.rmp_session), 14327074Ssteve ntohs(rmp->r_brq.rmp_version)); 1441592Srgrimes (void) fprintf(DbgFp, "\n\t\tMachine Type: "); 1451592Srgrimes for (i = 0; i < RMP_MACHLEN; i++) 1461592Srgrimes (void) fputc(rmp->r_brq.rmp_machtype[i], DbgFp); 1471592Srgrimes DspFlnm(rmp->r_brq.rmp_flnmsize, &rmp->r_brq.rmp_flnm); 1481592Srgrimes break; 1491592Srgrimes case RMP_BOOT_REPL: /* boot reply */ 1501592Srgrimes fprintf(DbgFp, "\tBoot Reply:\n"); 1511592Srgrimes GETWORD(rmp->r_brpl.rmp_seqno, t); 1521592Srgrimes (void) fprintf(DbgFp, BootFmt, rmp->r_brpl.rmp_retcode, 15327074Ssteve t, ntohs(rmp->r_brpl.rmp_session), 15427074Ssteve ntohs(rmp->r_brpl.rmp_version)); 1551592Srgrimes DspFlnm(rmp->r_brpl.rmp_flnmsize,&rmp->r_brpl.rmp_flnm); 1561592Srgrimes break; 1571592Srgrimes case RMP_READ_REQ: /* read request */ 1581592Srgrimes (void) fprintf(DbgFp, "\tRead Request:\n"); 1591592Srgrimes GETWORD(rmp->r_rrq.rmp_offset, t); 1601592Srgrimes (void) fprintf(DbgFp, ReadFmt, rmp->r_rrq.rmp_retcode, 16127074Ssteve t, ntohs(rmp->r_rrq.rmp_session)); 1621592Srgrimes (void) fprintf(DbgFp, "\t\tNoOfBytes: %u\n", 16327074Ssteve ntohs(rmp->r_rrq.rmp_size)); 1641592Srgrimes break; 1651592Srgrimes case RMP_READ_REPL: /* read reply */ 1661592Srgrimes (void) fprintf(DbgFp, "\tRead Reply:\n"); 1671592Srgrimes GETWORD(rmp->r_rrpl.rmp_offset, t); 1681592Srgrimes (void) fprintf(DbgFp, ReadFmt, rmp->r_rrpl.rmp_retcode, 16927074Ssteve t, ntohs(rmp->r_rrpl.rmp_session)); 1701592Srgrimes (void) fprintf(DbgFp, "\t\tNoOfBytesSent: %d\n", 1711592Srgrimes rconn->rmplen - RMPREADSIZE(0)); 1721592Srgrimes break; 1731592Srgrimes case RMP_BOOT_DONE: /* boot complete */ 1741592Srgrimes (void) fprintf(DbgFp, "\tBoot Complete:\n"); 1751592Srgrimes (void) fprintf(DbgFp, "\t\tRetCode:%u SessID:%x\n", 1761592Srgrimes rmp->r_done.rmp_retcode, 17727074Ssteve ntohs(rmp->r_done.rmp_session)); 1781592Srgrimes break; 1791592Srgrimes default: /* ??? */ 1801592Srgrimes (void) fprintf(DbgFp, "\tUnknown Type:(%d)\n", 1811592Srgrimes rmp->r_type); 1821592Srgrimes } 1831592Srgrimes (void) fputc('\n', DbgFp); 1841592Srgrimes (void) fflush(DbgFp); 1851592Srgrimes 1861592Srgrimes (void) sigsetmask(omask); /* reset old signal mask */ 1871592Srgrimes} 1881592Srgrimes 1891592Srgrimes 1901592Srgrimes/* 1911592Srgrimes** GetEtherAddr -- convert an RMP (Ethernet) address into a string. 1921592Srgrimes** 1931592Srgrimes** An RMP BOOT packet has been received. Look at the type field 1941592Srgrimes** and process Boot Requests, Read Requests, and Boot Complete 1951592Srgrimes** packets. Any other type will be dropped with a warning msg. 1961592Srgrimes** 1971592Srgrimes** Parameters: 1981592Srgrimes** addr - array of RMP_ADDRLEN bytes. 1991592Srgrimes** 2001592Srgrimes** Returns: 2011592Srgrimes** Pointer to static string representation of `addr'. 2021592Srgrimes** 2031592Srgrimes** Side Effects: 2041592Srgrimes** None. 2051592Srgrimes** 2061592Srgrimes** Warnings: 2071592Srgrimes** - The return value points to a static buffer; it must 2081592Srgrimes** be copied if it's to be saved. 2091592Srgrimes*/ 2101592Srgrimeschar * 2111592SrgrimesGetEtherAddr(addr) 21227074Ssteve u_int8_t *addr; 2131592Srgrimes{ 2141592Srgrimes static char Hex[] = "0123456789abcdef"; 2151592Srgrimes static char etherstr[RMP_ADDRLEN*3]; 21627079Ssteve int i; 21727079Ssteve char *cp; 2181592Srgrimes 2191592Srgrimes /* 2201592Srgrimes * For each byte in `addr', convert it to "<hexchar><hexchar>:". 2211592Srgrimes * The last byte does not get a trailing `:' appended. 2221592Srgrimes */ 2231592Srgrimes i = 0; 22427074Ssteve cp = etherstr; 2251592Srgrimes for(;;) { 22627074Ssteve *cp++ = Hex[*addr >> 4 & 0xf]; 22727074Ssteve *cp++ = Hex[*addr++ & 0xf]; 2281592Srgrimes if (++i == RMP_ADDRLEN) 2291592Srgrimes break; 23027074Ssteve *cp++ = ':'; 2311592Srgrimes } 23227074Ssteve *cp = '\0'; 2331592Srgrimes 2341592Srgrimes return(etherstr); 2351592Srgrimes} 2361592Srgrimes 2371592Srgrimes 2381592Srgrimes/* 2391592Srgrimes** DispFlnm -- Print a string of bytes to DbgFp (often, a file name). 2401592Srgrimes** 2411592Srgrimes** Parameters: 2421592Srgrimes** size - number of bytes to print. 2431592Srgrimes** flnm - address of first byte. 2441592Srgrimes** 2451592Srgrimes** Returns: 2461592Srgrimes** Nothing. 2471592Srgrimes** 2481592Srgrimes** Side Effects: 2491592Srgrimes** - Characters are sent to `DbgFp'. 2501592Srgrimes*/ 2511592Srgrimesvoid 2521592SrgrimesDspFlnm(size, flnm) 25327079Ssteve u_int size; 25427079Ssteve char *flnm; 2551592Srgrimes{ 25627079Ssteve int i; 2571592Srgrimes 25827074Ssteve (void) fprintf(DbgFp, "\n\t\tFile Name (%u): <", size); 2591592Srgrimes for (i = 0; i < size; i++) 2601592Srgrimes (void) fputc(*flnm++, DbgFp); 2611592Srgrimes (void) fputs(">\n", DbgFp); 2621592Srgrimes} 2631592Srgrimes 2641592Srgrimes 2651592Srgrimes/* 2661592Srgrimes** NewClient -- allocate memory for a new CLIENT. 2671592Srgrimes** 2681592Srgrimes** Parameters: 2691592Srgrimes** addr - RMP (Ethernet) address of new client. 2701592Srgrimes** 2711592Srgrimes** Returns: 2721592Srgrimes** Ptr to new CLIENT or NULL if we ran out of memory. 2731592Srgrimes** 2741592Srgrimes** Side Effects: 2751592Srgrimes** - Memory will be malloc'd for the new CLIENT. 2761592Srgrimes** - If malloc() fails, a log message will be generated. 2771592Srgrimes*/ 2781592SrgrimesCLIENT * 2791592SrgrimesNewClient(addr) 28027074Ssteve u_int8_t *addr; 2811592Srgrimes{ 2821592Srgrimes CLIENT *ctmp; 2831592Srgrimes 2841592Srgrimes if ((ctmp = (CLIENT *) malloc(sizeof(CLIENT))) == NULL) { 2851592Srgrimes syslog(LOG_ERR, "NewClient: out of memory (%s)", 2861592Srgrimes GetEtherAddr(addr)); 2871592Srgrimes return(NULL); 2881592Srgrimes } 2891592Srgrimes 29027079Ssteve memset(ctmp, 0, sizeof(CLIENT)); 29127079Ssteve memmove(&ctmp->addr[0], addr, RMP_ADDRLEN); 2921592Srgrimes return(ctmp); 2931592Srgrimes} 2941592Srgrimes 2951592Srgrimes/* 2961592Srgrimes** FreeClient -- free linked list of Clients. 2971592Srgrimes** 2981592Srgrimes** Parameters: 2991592Srgrimes** None. 3001592Srgrimes** 3011592Srgrimes** Returns: 3021592Srgrimes** Nothing. 3031592Srgrimes** 3041592Srgrimes** Side Effects: 3051592Srgrimes** - All malloc'd memory associated with the linked list of 3061592Srgrimes** CLIENTS will be free'd; `Clients' will be set to NULL. 3071592Srgrimes** 3081592Srgrimes** Warnings: 3091592Srgrimes** - This routine must be called with SIGHUP blocked. 3101592Srgrimes*/ 3111592Srgrimesvoid 3121592SrgrimesFreeClients() 3131592Srgrimes{ 31427079Ssteve CLIENT *ctmp; 3151592Srgrimes 3161592Srgrimes while (Clients != NULL) { 3171592Srgrimes ctmp = Clients; 3181592Srgrimes Clients = Clients->next; 3191592Srgrimes FreeClient(ctmp); 3201592Srgrimes } 3211592Srgrimes} 3221592Srgrimes 3231592Srgrimes/* 3241592Srgrimes** NewStr -- allocate memory for a character array. 3251592Srgrimes** 3261592Srgrimes** Parameters: 3271592Srgrimes** str - null terminated character array. 3281592Srgrimes** 3291592Srgrimes** Returns: 3301592Srgrimes** Ptr to new character array or NULL if we ran out of memory. 3311592Srgrimes** 3321592Srgrimes** Side Effects: 3331592Srgrimes** - Memory will be malloc'd for the new character array. 3341592Srgrimes** - If malloc() fails, a log message will be generated. 3351592Srgrimes*/ 3361592Srgrimeschar * 3371592SrgrimesNewStr(str) 3381592Srgrimes char *str; 3391592Srgrimes{ 3401592Srgrimes char *stmp; 3411592Srgrimes 3421592Srgrimes if ((stmp = (char *)malloc((unsigned) (strlen(str)+1))) == NULL) { 3431592Srgrimes syslog(LOG_ERR, "NewStr: out of memory (%s)", str); 3441592Srgrimes return(NULL); 3451592Srgrimes } 3461592Srgrimes 3471592Srgrimes (void) strcpy(stmp, str); 3481592Srgrimes return(stmp); 3491592Srgrimes} 3501592Srgrimes 3511592Srgrimes/* 3521592Srgrimes** To save time, NewConn and FreeConn maintain a cache of one RMPCONN 3531592Srgrimes** in `LastFree' (defined below). 3541592Srgrimes*/ 3551592Srgrimes 3561592Srgrimesstatic RMPCONN *LastFree = NULL; 3571592Srgrimes 3581592Srgrimes/* 3591592Srgrimes** NewConn -- allocate memory for a new RMPCONN connection. 3601592Srgrimes** 3611592Srgrimes** Parameters: 3621592Srgrimes** rconn - initialization template for new connection. 3631592Srgrimes** 3641592Srgrimes** Returns: 3651592Srgrimes** Ptr to new RMPCONN or NULL if we ran out of memory. 3661592Srgrimes** 3671592Srgrimes** Side Effects: 3681592Srgrimes** - Memory may be malloc'd for the new RMPCONN (if not cached). 3691592Srgrimes** - If malloc() fails, a log message will be generated. 3701592Srgrimes*/ 3711592SrgrimesRMPCONN * 3721592SrgrimesNewConn(rconn) 3731592Srgrimes RMPCONN *rconn; 3741592Srgrimes{ 3751592Srgrimes RMPCONN *rtmp; 3761592Srgrimes 3771592Srgrimes if (LastFree == NULL) { /* nothing cached; make a new one */ 3781592Srgrimes if ((rtmp = (RMPCONN *) malloc(sizeof(RMPCONN))) == NULL) { 3791592Srgrimes syslog(LOG_ERR, "NewConn: out of memory (%s)", 3801592Srgrimes EnetStr(rconn)); 3811592Srgrimes return(NULL); 3821592Srgrimes } 3831592Srgrimes } else { /* use the cached RMPCONN */ 3841592Srgrimes rtmp = LastFree; 3851592Srgrimes LastFree = NULL; 3861592Srgrimes } 3871592Srgrimes 3881592Srgrimes /* 3891592Srgrimes * Copy template into `rtmp', init file descriptor to `-1' and 3901592Srgrimes * set ptr to next elem NULL. 3911592Srgrimes */ 39227079Ssteve memmove((char *)rtmp, (char *)rconn, sizeof(RMPCONN)); 3931592Srgrimes rtmp->bootfd = -1; 3941592Srgrimes rtmp->next = NULL; 3951592Srgrimes 3961592Srgrimes return(rtmp); 3971592Srgrimes} 3981592Srgrimes 3991592Srgrimes/* 4001592Srgrimes** FreeConn -- Free memory associated with an RMPCONN connection. 4011592Srgrimes** 4021592Srgrimes** Parameters: 4031592Srgrimes** rtmp - ptr to RMPCONN to be free'd. 4041592Srgrimes** 4051592Srgrimes** Returns: 4061592Srgrimes** Nothing. 4071592Srgrimes** 4081592Srgrimes** Side Effects: 4091592Srgrimes** - Memory associated with `rtmp' may be free'd (or cached). 4101592Srgrimes** - File desc associated with `rtmp->bootfd' will be closed. 4111592Srgrimes*/ 4121592Srgrimesvoid 4131592SrgrimesFreeConn(rtmp) 41427079Ssteve RMPCONN *rtmp; 4151592Srgrimes{ 4161592Srgrimes /* 4171592Srgrimes * If the file descriptor is in use, close the file. 4181592Srgrimes */ 4191592Srgrimes if (rtmp->bootfd >= 0) { 4201592Srgrimes (void) close(rtmp->bootfd); 4211592Srgrimes rtmp->bootfd = -1; 4221592Srgrimes } 4231592Srgrimes 4241592Srgrimes if (LastFree == NULL) /* cache for next time */ 4251592Srgrimes rtmp = LastFree; 4261592Srgrimes else /* already one cached; free this one */ 4271592Srgrimes free((char *)rtmp); 4281592Srgrimes} 4291592Srgrimes 4301592Srgrimes/* 4311592Srgrimes** FreeConns -- free linked list of RMPCONN connections. 4321592Srgrimes** 4331592Srgrimes** Parameters: 4341592Srgrimes** None. 4351592Srgrimes** 4361592Srgrimes** Returns: 4371592Srgrimes** Nothing. 4381592Srgrimes** 4391592Srgrimes** Side Effects: 4401592Srgrimes** - All malloc'd memory associated with the linked list of 4411592Srgrimes** connections will be free'd; `RmpConns' will be set to NULL. 4421592Srgrimes** - If LastFree is != NULL, it too will be free'd & NULL'd. 4431592Srgrimes** 4441592Srgrimes** Warnings: 4451592Srgrimes** - This routine must be called with SIGHUP blocked. 4461592Srgrimes*/ 4471592Srgrimesvoid 4481592SrgrimesFreeConns() 4491592Srgrimes{ 45027079Ssteve RMPCONN *rtmp; 4511592Srgrimes 4521592Srgrimes while (RmpConns != NULL) { 4531592Srgrimes rtmp = RmpConns; 4541592Srgrimes RmpConns = RmpConns->next; 4551592Srgrimes FreeConn(rtmp); 4561592Srgrimes } 4571592Srgrimes 4581592Srgrimes if (LastFree != NULL) { 4591592Srgrimes free((char *)LastFree); 4601592Srgrimes LastFree = NULL; 4611592Srgrimes } 4621592Srgrimes} 4631592Srgrimes 4641592Srgrimes/* 4651592Srgrimes** AddConn -- Add a connection to the linked list of connections. 4661592Srgrimes** 4671592Srgrimes** Parameters: 4681592Srgrimes** rconn - connection to be added. 4691592Srgrimes** 4701592Srgrimes** Returns: 4711592Srgrimes** Nothing. 4721592Srgrimes** 4731592Srgrimes** Side Effects: 4741592Srgrimes** - RmpConn will point to new connection. 4751592Srgrimes** 4761592Srgrimes** Warnings: 4771592Srgrimes** - This routine must be called with SIGHUP blocked. 4781592Srgrimes*/ 4791592Srgrimesvoid 4801592SrgrimesAddConn(rconn) 48127079Ssteve RMPCONN *rconn; 4821592Srgrimes{ 4831592Srgrimes if (RmpConns != NULL) 4841592Srgrimes rconn->next = RmpConns; 4851592Srgrimes RmpConns = rconn; 4861592Srgrimes} 4871592Srgrimes 4881592Srgrimes/* 4891592Srgrimes** FindConn -- Find a connection in the linked list of connections. 4901592Srgrimes** 4911592Srgrimes** We use the RMP (Ethernet) address as the basis for determining 4921592Srgrimes** if this is the same connection. According to the Remote Maint 4931592Srgrimes** Protocol, we can only have one connection with any machine. 4941592Srgrimes** 4951592Srgrimes** Parameters: 4961592Srgrimes** rconn - connection to be found. 4971592Srgrimes** 4981592Srgrimes** Returns: 4991592Srgrimes** Matching connection from linked list or NULL if not found. 5001592Srgrimes** 5011592Srgrimes** Side Effects: 5021592Srgrimes** None. 5031592Srgrimes** 5041592Srgrimes** Warnings: 5051592Srgrimes** - This routine must be called with SIGHUP blocked. 5061592Srgrimes*/ 5071592SrgrimesRMPCONN * 5081592SrgrimesFindConn(rconn) 50927079Ssteve RMPCONN *rconn; 5101592Srgrimes{ 51127079Ssteve RMPCONN *rtmp; 5121592Srgrimes 5131592Srgrimes for (rtmp = RmpConns; rtmp != NULL; rtmp = rtmp->next) 5141592Srgrimes if (bcmp((char *)&rconn->rmp.hp_hdr.saddr[0], 5151592Srgrimes (char *)&rtmp->rmp.hp_hdr.saddr[0], RMP_ADDRLEN) == 0) 5161592Srgrimes break; 5171592Srgrimes 5181592Srgrimes return(rtmp); 5191592Srgrimes} 5201592Srgrimes 5211592Srgrimes/* 5221592Srgrimes** RemoveConn -- Remove a connection from the linked list of connections. 5231592Srgrimes** 5241592Srgrimes** Parameters: 5251592Srgrimes** rconn - connection to be removed. 5261592Srgrimes** 5271592Srgrimes** Returns: 5281592Srgrimes** Nothing. 5291592Srgrimes** 5301592Srgrimes** Side Effects: 5311592Srgrimes** - If found, an RMPCONN will cease to exist and it will 5321592Srgrimes** be removed from the linked list. 5331592Srgrimes** 5341592Srgrimes** Warnings: 5351592Srgrimes** - This routine must be called with SIGHUP blocked. 5361592Srgrimes*/ 5371592Srgrimesvoid 5381592SrgrimesRemoveConn(rconn) 53927079Ssteve RMPCONN *rconn; 5401592Srgrimes{ 54127079Ssteve RMPCONN *thisrconn, *lastrconn; 5421592Srgrimes 5431592Srgrimes if (RmpConns == rconn) { /* easy case */ 5441592Srgrimes RmpConns = RmpConns->next; 5451592Srgrimes FreeConn(rconn); 5461592Srgrimes } else { /* must traverse linked list */ 5471592Srgrimes lastrconn = RmpConns; /* set back ptr */ 5481592Srgrimes thisrconn = lastrconn->next; /* set current ptr */ 5491592Srgrimes while (thisrconn != NULL) { 5501592Srgrimes if (rconn == thisrconn) { /* found it */ 5511592Srgrimes lastrconn->next = thisrconn->next; 5521592Srgrimes FreeConn(thisrconn); 5531592Srgrimes break; 5541592Srgrimes } 5551592Srgrimes lastrconn = thisrconn; 5561592Srgrimes thisrconn = thisrconn->next; 5571592Srgrimes } 5581592Srgrimes } 5591592Srgrimes} 560