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