Bug Summary

File:src/usr.sbin/rbootd/utils.c
Warning:line 394, column 3
Value stored to 'rtmp' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name utils.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/usr.sbin/rbootd/obj -resource-dir /usr/local/lib/clang/13.0.0 -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.sbin/rbootd/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/usr.sbin/rbootd/utils.c
1/* $OpenBSD: utils.c,v 1.17 2017/01/20 03:47:31 krw Exp $ */
2/* $NetBSD: utils.c,v 1.5.2.1 1995/11/14 08:45:46 thorpej Exp $ */
3
4/*
5 * Copyright (c) 1988, 1992 The University of Utah and the Center
6 * for Software Science (CSS).
7 * Copyright (c) 1992, 1993
8 * The Regents of the University of California. All rights reserved.
9 *
10 * This code is derived from software contributed to Berkeley by
11 * the Center for Software Science of the University of Utah Computer
12 * Science Department. CSS requests users of this software to return
13 * to css-dist@cs.utah.edu any improvements that they make and grant
14 * CSS redistribution rights.
15 *
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
18 * are met:
19 * 1. Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution.
24 * 3. Neither the name of the University nor the names of its contributors
25 * may be used to endorse or promote products derived from this software
26 * without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 * SUCH DAMAGE.
39 *
40 * from: @(#)utils.c 8.1 (Berkeley) 6/4/93
41 *
42 * From: Utah Hdr: utils.c 3.1 92/07/06
43 * Author: Jeff Forys, University of Utah CSS
44 */
45
46#include <sys/time.h>
47#include <stdio.h>
48#include <stdlib.h>
49#include <string.h>
50#include <syslog.h>
51#include <time.h>
52#include <unistd.h>
53#include "defs.h"
54
55/*
56** DispPkt -- Display the contents of an RMPCONN packet.
57**
58** Parameters:
59** rconn - packet to be displayed.
60** direct - direction packet is going (DIR_*).
61**
62** Returns:
63** Nothing.
64**
65** Side Effects:
66** None.
67*/
68void
69DispPkt(RMPCONN *rconn, int direct)
70{
71 static const char BootFmt[] =
72 "\t\tRetCode:%u SeqNo:%x SessID:%x Vers:%u";
73 static const char ReadFmt[] =
74 "\t\tRetCode:%u Offset:%x SessID:%x\n";
75 struct tm *tmp;
76 struct rmp_packet *rmp;
77 int i;
78 u_int32_t t;
79 time_t tim;
80
81 /* display direction packet is going using '>>>' or '<<<' */
82 fputs((direct==DIR_RCVD0)?"<<< ":(direct==DIR_SENT1)?">>> ":"", DbgFp);
83
84 /* display packet timestamp */
85
86 tim = rconn->tstamp.tv_sec;
87 tmp = localtime(&tim);
88 fprintf(DbgFp, "%02d:%02d:%02d.%06ld ", tmp->tm_hour, tmp->tm_min,
89 tmp->tm_sec, rconn->tstamp.tv_usec);
90
91 /* display src or dst addr and information about network interface */
92 fprintf(DbgFp, "Addr: %s Intf: %s\n", EnetStr(rconn)GetEtherAddr(&(rconn)->rmp.hp_hdr.saddr[0]), IntfName);
93
94 rmp = &rconn->rmp;
95
96 /* display IEEE 802.2 Logical Link Control header */
97 (void) fprintf(DbgFp, "\t802.2 LLC: DSAP:%x SSAP:%x CTRL:%x\n",
98 rmp->hp_llc.dsap, rmp->hp_llc.ssap, ntohs(rmp->hp_llc.cntrl)(__uint16_t)(__builtin_constant_p(rmp->hp_llc.cntrl) ? (__uint16_t
)(((__uint16_t)(rmp->hp_llc.cntrl) & 0xffU) << 8
| ((__uint16_t)(rmp->hp_llc.cntrl) & 0xff00U) >>
8) : __swap16md(rmp->hp_llc.cntrl))
);
99
100 /* display HP extensions to 802.2 Logical Link Control header */
101 (void) fprintf(DbgFp, "\tHP Ext: DXSAP:%x SXSAP:%x\n",
102 ntohs(rmp->hp_llc.dxsap)(__uint16_t)(__builtin_constant_p(rmp->hp_llc.dxsap) ? (__uint16_t
)(((__uint16_t)(rmp->hp_llc.dxsap) & 0xffU) << 8
| ((__uint16_t)(rmp->hp_llc.dxsap) & 0xff00U) >>
8) : __swap16md(rmp->hp_llc.dxsap))
, ntohs(rmp->hp_llc.sxsap)(__uint16_t)(__builtin_constant_p(rmp->hp_llc.sxsap) ? (__uint16_t
)(((__uint16_t)(rmp->hp_llc.sxsap) & 0xffU) << 8
| ((__uint16_t)(rmp->hp_llc.sxsap) & 0xff00U) >>
8) : __swap16md(rmp->hp_llc.sxsap))
);
103
104 /*
105 * Display information about RMP packet using type field to
106 * determine what kind of packet this is.
107 */
108 switch (rmp->r_typermp_proto.rmp_raw.rmp_type) {
109 case RMP_BOOT_REQ1: /* boot request */
110 (void) fprintf(DbgFp, "\tBoot Request:");
111 GETWORD(rmp->r_brq.rmp_seqno, t)(t) = (((u_int32_t)(__uint16_t)(__builtin_constant_p((rmp->
rmp_proto.rmp_brq.rmp_seqno).val[0]) ? (__uint16_t)(((__uint16_t
)((rmp->rmp_proto.rmp_brq.rmp_seqno).val[0]) & 0xffU) <<
8 | ((__uint16_t)((rmp->rmp_proto.rmp_brq.rmp_seqno).val[
0]) & 0xff00U) >> 8) : __swap16md((rmp->rmp_proto
.rmp_brq.rmp_seqno).val[0]))) << 16) | (__uint16_t)(__builtin_constant_p
((rmp->rmp_proto.rmp_brq.rmp_seqno).val[1]) ? (__uint16_t)
(((__uint16_t)((rmp->rmp_proto.rmp_brq.rmp_seqno).val[1]) &
0xffU) << 8 | ((__uint16_t)((rmp->rmp_proto.rmp_brq
.rmp_seqno).val[1]) & 0xff00U) >> 8) : __swap16md((
rmp->rmp_proto.rmp_brq.rmp_seqno).val[1]))
;
112 if (ntohs(rmp->r_brq.rmp_session)(__uint16_t)(__builtin_constant_p(rmp->rmp_proto.rmp_brq.rmp_session
) ? (__uint16_t)(((__uint16_t)(rmp->rmp_proto.rmp_brq.rmp_session
) & 0xffU) << 8 | ((__uint16_t)(rmp->rmp_proto.rmp_brq
.rmp_session) & 0xff00U) >> 8) : __swap16md(rmp->
rmp_proto.rmp_brq.rmp_session))
== RMP_PROBESID0xffff) {
113 if (WORDZE(rmp->r_brq.rmp_seqno)((rmp->rmp_proto.rmp_brq.rmp_seqno.val[0] == 0) &&
(rmp->rmp_proto.rmp_brq.rmp_seqno.val[1] == 0))
)
114 fputs(" (Send Server ID)", DbgFp);
115 else
116 fprintf(DbgFp," (Send Filename #%u)",t);
117 }
118 (void) fputc('\n', DbgFp);
119 (void) fprintf(DbgFp, BootFmt, rmp->r_brqrmp_proto.rmp_brq.rmp_retcode,
120 t, ntohs(rmp->r_brq.rmp_session)(__uint16_t)(__builtin_constant_p(rmp->rmp_proto.rmp_brq.rmp_session
) ? (__uint16_t)(((__uint16_t)(rmp->rmp_proto.rmp_brq.rmp_session
) & 0xffU) << 8 | ((__uint16_t)(rmp->rmp_proto.rmp_brq
.rmp_session) & 0xff00U) >> 8) : __swap16md(rmp->
rmp_proto.rmp_brq.rmp_session))
,
121 ntohs(rmp->r_brq.rmp_version)(__uint16_t)(__builtin_constant_p(rmp->rmp_proto.rmp_brq.rmp_version
) ? (__uint16_t)(((__uint16_t)(rmp->rmp_proto.rmp_brq.rmp_version
) & 0xffU) << 8 | ((__uint16_t)(rmp->rmp_proto.rmp_brq
.rmp_version) & 0xff00U) >> 8) : __swap16md(rmp->
rmp_proto.rmp_brq.rmp_version))
);
122 (void) fprintf(DbgFp, "\n\t\tMachine Type: ");
123 for (i = 0; i < RMP_MACHLEN20; i++)
124 (void) fputc(rmp->r_brqrmp_proto.rmp_brq.rmp_machtype[i], DbgFp);
125 DspFlnm(rmp->r_brqrmp_proto.rmp_brq.rmp_flnmsize, &rmp->r_brqrmp_proto.rmp_brq.rmp_flnm);
126 break;
127 case RMP_BOOT_REPL129: /* boot reply */
128 fprintf(DbgFp, "\tBoot Reply:\n");
129 GETWORD(rmp->r_brpl.rmp_seqno, t)(t) = (((u_int32_t)(__uint16_t)(__builtin_constant_p((rmp->
rmp_proto.rmp_brpl.rmp_seqno).val[0]) ? (__uint16_t)(((__uint16_t
)((rmp->rmp_proto.rmp_brpl.rmp_seqno).val[0]) & 0xffU)
<< 8 | ((__uint16_t)((rmp->rmp_proto.rmp_brpl.rmp_seqno
).val[0]) & 0xff00U) >> 8) : __swap16md((rmp->rmp_proto
.rmp_brpl.rmp_seqno).val[0]))) << 16) | (__uint16_t)(__builtin_constant_p
((rmp->rmp_proto.rmp_brpl.rmp_seqno).val[1]) ? (__uint16_t
)(((__uint16_t)((rmp->rmp_proto.rmp_brpl.rmp_seqno).val[1]
) & 0xffU) << 8 | ((__uint16_t)((rmp->rmp_proto.
rmp_brpl.rmp_seqno).val[1]) & 0xff00U) >> 8) : __swap16md
((rmp->rmp_proto.rmp_brpl.rmp_seqno).val[1]))
;
130 (void) fprintf(DbgFp, BootFmt, rmp->r_brplrmp_proto.rmp_brpl.rmp_retcode,
131 t, ntohs(rmp->r_brpl.rmp_session)(__uint16_t)(__builtin_constant_p(rmp->rmp_proto.rmp_brpl.
rmp_session) ? (__uint16_t)(((__uint16_t)(rmp->rmp_proto.rmp_brpl
.rmp_session) & 0xffU) << 8 | ((__uint16_t)(rmp->
rmp_proto.rmp_brpl.rmp_session) & 0xff00U) >> 8) : __swap16md
(rmp->rmp_proto.rmp_brpl.rmp_session))
,
132 ntohs(rmp->r_brpl.rmp_version)(__uint16_t)(__builtin_constant_p(rmp->rmp_proto.rmp_brpl.
rmp_version) ? (__uint16_t)(((__uint16_t)(rmp->rmp_proto.rmp_brpl
.rmp_version) & 0xffU) << 8 | ((__uint16_t)(rmp->
rmp_proto.rmp_brpl.rmp_version) & 0xff00U) >> 8) : __swap16md
(rmp->rmp_proto.rmp_brpl.rmp_version))
);
133 DspFlnm(rmp->r_brplrmp_proto.rmp_brpl.rmp_flnmsize,&rmp->r_brplrmp_proto.rmp_brpl.rmp_flnm);
134 break;
135 case RMP_READ_REQ2: /* read request */
136 (void) fprintf(DbgFp, "\tRead Request:\n");
137 GETWORD(rmp->r_rrq.rmp_offset, t)(t) = (((u_int32_t)(__uint16_t)(__builtin_constant_p((rmp->
rmp_proto.rmp_rrq.rmp_offset).val[0]) ? (__uint16_t)(((__uint16_t
)((rmp->rmp_proto.rmp_rrq.rmp_offset).val[0]) & 0xffU)
<< 8 | ((__uint16_t)((rmp->rmp_proto.rmp_rrq.rmp_offset
).val[0]) & 0xff00U) >> 8) : __swap16md((rmp->rmp_proto
.rmp_rrq.rmp_offset).val[0]))) << 16) | (__uint16_t)(__builtin_constant_p
((rmp->rmp_proto.rmp_rrq.rmp_offset).val[1]) ? (__uint16_t
)(((__uint16_t)((rmp->rmp_proto.rmp_rrq.rmp_offset).val[1]
) & 0xffU) << 8 | ((__uint16_t)((rmp->rmp_proto.
rmp_rrq.rmp_offset).val[1]) & 0xff00U) >> 8) : __swap16md
((rmp->rmp_proto.rmp_rrq.rmp_offset).val[1]))
;
138 (void) fprintf(DbgFp, ReadFmt, rmp->r_rrqrmp_proto.rmp_rrq.rmp_retcode,
139 t, ntohs(rmp->r_rrq.rmp_session)(__uint16_t)(__builtin_constant_p(rmp->rmp_proto.rmp_rrq.rmp_session
) ? (__uint16_t)(((__uint16_t)(rmp->rmp_proto.rmp_rrq.rmp_session
) & 0xffU) << 8 | ((__uint16_t)(rmp->rmp_proto.rmp_rrq
.rmp_session) & 0xff00U) >> 8) : __swap16md(rmp->
rmp_proto.rmp_rrq.rmp_session))
);
140 (void) fprintf(DbgFp, "\t\tNoOfBytes: %u\n",
141 ntohs(rmp->r_rrq.rmp_size)(__uint16_t)(__builtin_constant_p(rmp->rmp_proto.rmp_rrq.rmp_size
) ? (__uint16_t)(((__uint16_t)(rmp->rmp_proto.rmp_rrq.rmp_size
) & 0xffU) << 8 | ((__uint16_t)(rmp->rmp_proto.rmp_rrq
.rmp_size) & 0xff00U) >> 8) : __swap16md(rmp->rmp_proto
.rmp_rrq.rmp_size))
);
142 break;
143 case RMP_READ_REPL130: /* read reply */
144 (void) fprintf(DbgFp, "\tRead Reply:\n");
145 GETWORD(rmp->r_rrpl.rmp_offset, t)(t) = (((u_int32_t)(__uint16_t)(__builtin_constant_p((rmp->
rmp_proto.rmp_rrpl.rmp_offset).val[0]) ? (__uint16_t)(((__uint16_t
)((rmp->rmp_proto.rmp_rrpl.rmp_offset).val[0]) & 0xffU
) << 8 | ((__uint16_t)((rmp->rmp_proto.rmp_rrpl.rmp_offset
).val[0]) & 0xff00U) >> 8) : __swap16md((rmp->rmp_proto
.rmp_rrpl.rmp_offset).val[0]))) << 16) | (__uint16_t)(__builtin_constant_p
((rmp->rmp_proto.rmp_rrpl.rmp_offset).val[1]) ? (__uint16_t
)(((__uint16_t)((rmp->rmp_proto.rmp_rrpl.rmp_offset).val[1
]) & 0xffU) << 8 | ((__uint16_t)((rmp->rmp_proto
.rmp_rrpl.rmp_offset).val[1]) & 0xff00U) >> 8) : __swap16md
((rmp->rmp_proto.rmp_rrpl.rmp_offset).val[1]))
;
146 (void) fprintf(DbgFp, ReadFmt, rmp->r_rrplrmp_proto.rmp_rrpl.rmp_retcode,
147 t, ntohs(rmp->r_rrpl.rmp_session)(__uint16_t)(__builtin_constant_p(rmp->rmp_proto.rmp_rrpl.
rmp_session) ? (__uint16_t)(((__uint16_t)(rmp->rmp_proto.rmp_rrpl
.rmp_session) & 0xffU) << 8 | ((__uint16_t)(rmp->
rmp_proto.rmp_rrpl.rmp_session) & 0xff00U) >> 8) : __swap16md
(rmp->rmp_proto.rmp_rrpl.rmp_session))
);
148 (void) fprintf(DbgFp, "\t\tNoOfBytesSent: %ld\n",
149 (long)(rconn->rmplen - RMPREADSIZE(0)(sizeof(struct hp_hdr) + sizeof(struct hp_llc) + sizeof(struct
rmp_read_repl) + 0 - sizeof(restofpkt) - sizeof(u_int8_t))
));
150 break;
151 case RMP_BOOT_DONE3: /* boot complete */
152 (void) fprintf(DbgFp, "\tBoot Complete:\n");
153 (void) fprintf(DbgFp, "\t\tRetCode:%u SessID:%x\n",
154 rmp->r_donermp_proto.rmp_done.rmp_retcode,
155 ntohs(rmp->r_done.rmp_session)(__uint16_t)(__builtin_constant_p(rmp->rmp_proto.rmp_done.
rmp_session) ? (__uint16_t)(((__uint16_t)(rmp->rmp_proto.rmp_done
.rmp_session) & 0xffU) << 8 | ((__uint16_t)(rmp->
rmp_proto.rmp_done.rmp_session) & 0xff00U) >> 8) : __swap16md
(rmp->rmp_proto.rmp_done.rmp_session))
);
156 break;
157 default: /* ??? */
158 (void) fprintf(DbgFp, "\tUnknown Type:(%d)\n",
159 rmp->r_typermp_proto.rmp_raw.rmp_type);
160 break;
161 }
162 (void) fputc('\n', DbgFp);
163 (void) fflush(DbgFp);
164}
165
166
167/*
168** GetEtherAddr -- convert an RMP (Ethernet) address into a string.
169**
170** An RMP BOOT packet has been received. Look at the type field
171** and process Boot Requests, Read Requests, and Boot Complete
172** packets. Any other type will be dropped with a warning msg.
173**
174** Parameters:
175** addr - array of RMP_ADDRLEN bytes.
176**
177** Returns:
178** Pointer to static string representation of `addr'.
179**
180** Side Effects:
181** None.
182**
183** Warnings:
184** - The return value points to a static buffer; it must
185** be copied if it's to be saved.
186*/
187char *
188GetEtherAddr(u_int8_t *addr)
189{
190 static char Hex[] = "0123456789abcdef";
191 static char etherstr[RMP_ADDRLEN6*3];
192 int i;
193 char *cp;
194
195 /*
196 * For each byte in `addr', convert it to "<hexchar><hexchar>:".
197 * The last byte does not get a trailing `:' appended.
198 */
199 i = 0;
200 cp = etherstr;
201 for(;;) {
202 *cp++ = Hex[*addr >> 4 & 0xf];
203 *cp++ = Hex[*addr++ & 0xf];
204 if (++i == RMP_ADDRLEN6)
205 break;
206 *cp++ = ':';
207 }
208 *cp = '\0';
209
210 return(etherstr);
211}
212
213
214/*
215** DispFlnm -- Print a string of bytes to DbgFp (often, a file name).
216**
217** Parameters:
218** size - number of bytes to print.
219** flnm - address of first byte.
220**
221** Returns:
222** Nothing.
223**
224** Side Effects:
225** - Characters are sent to `DbgFp'.
226*/
227void
228DspFlnm(u_int size, char *flnm)
229{
230 u_int i;
231
232 (void) fprintf(DbgFp, "\n\t\tFile Name (%u): <", size);
233 for (i = 0; i < size; i++)
234 (void) fputc(*flnm++, DbgFp);
235 (void) fputs(">\n", DbgFp);
236}
237
238
239/*
240** NewClient -- allocate memory for a new CLIENT.
241**
242** Parameters:
243** addr - RMP (Ethernet) address of new client.
244**
245** Returns:
246** Ptr to new CLIENT or NULL if we ran out of memory.
247**
248** Side Effects:
249** - Memory will be malloc'd for the new CLIENT.
250** - If malloc() fails, a log message will be generated.
251*/
252CLIENT *
253NewClient(u_int8_t *addr)
254{
255 CLIENT *ctmp;
256
257 if ((ctmp = malloc(sizeof(CLIENT))) == NULL((void *)0)) {
258 syslog(LOG_ERR3, "NewClient: out of memory (%s)",
259 GetEtherAddr(addr));
260 return(NULL((void *)0));
261 }
262
263 bzero(ctmp, sizeof(CLIENT));
264 bcopy(addr, &ctmp->addr[0], RMP_ADDRLEN6);
265 return(ctmp);
266}
267
268/*
269** FreeClient -- free linked list of Clients.
270**
271** Parameters:
272** None.
273**
274** Returns:
275** Nothing.
276**
277** Side Effects:
278** - All malloc'd memory associated with the linked list of
279** CLIENTS will be free'd; `Clients' will be set to NULL.
280**
281** Warnings:
282** - This routine must be called with SIGHUP blocked.
283*/
284void
285FreeClients(void)
286{
287 CLIENT *ctmp;
288
289 while (Clients != NULL((void *)0)) {
290 ctmp = Clients;
291 Clients = Clients->next;
292 FreeClient(ctmp)free(ctmp);
293 }
294}
295
296/*
297** NewStr -- allocate memory for a character array.
298**
299** Parameters:
300** str - null terminated character array.
301**
302** Returns:
303** Ptr to new character array or NULL if we ran out of memory.
304**
305** Side Effects:
306** - Memory will be malloc'd for the new character array.
307** - If malloc() fails, a log message will be generated.
308*/
309char *
310NewStr(char *str)
311{
312 char *stmp;
313
314 stmp = strdup(str);
315 if (stmp == NULL((void *)0)) {
316 syslog(LOG_ERR3, "NewStr: out of memory (%s)", str);
317 return(NULL((void *)0));
318 }
319 return(stmp);
320}
321
322/*
323** To save time, NewConn and FreeConn maintain a cache of one RMPCONN
324** in `LastFree' (defined below).
325*/
326
327static RMPCONN *LastFree = NULL((void *)0);
328
329/*
330** NewConn -- allocate memory for a new RMPCONN connection.
331**
332** Parameters:
333** rconn - initialization template for new connection.
334**
335** Returns:
336** Ptr to new RMPCONN or NULL if we ran out of memory.
337**
338** Side Effects:
339** - Memory may be malloc'd for the new RMPCONN (if not cached).
340** - If malloc() fails, a log message will be generated.
341*/
342RMPCONN *
343NewConn(RMPCONN *rconn)
344{
345 RMPCONN *rtmp;
346
347 if (LastFree == NULL((void *)0)) { /* nothing cached; make a new one */
348 if ((rtmp = malloc(sizeof(RMPCONN))) == NULL((void *)0)) {
349 syslog(LOG_ERR3, "NewConn: out of memory (%s)",
350 EnetStr(rconn)GetEtherAddr(&(rconn)->rmp.hp_hdr.saddr[0]));
351 return(NULL((void *)0));
352 }
353 } else { /* use the cached RMPCONN */
354 rtmp = LastFree;
355 LastFree = NULL((void *)0);
356 }
357
358 /*
359 * Copy template into `rtmp', init file descriptor to `-1' and
360 * set ptr to next elem NULL.
361 */
362 bcopy((char *)rconn, (char *)rtmp, sizeof(RMPCONN));
363 rtmp->bootfd = -1;
364 rtmp->next = NULL((void *)0);
365
366 return(rtmp);
367}
368
369/*
370** FreeConn -- Free memory associated with an RMPCONN connection.
371**
372** Parameters:
373** rtmp - ptr to RMPCONN to be free'd.
374**
375** Returns:
376** Nothing.
377**
378** Side Effects:
379** - Memory associated with `rtmp' may be free'd (or cached).
380** - File desc associated with `rtmp->bootfd' will be closed.
381*/
382void
383FreeConn(RMPCONN *rtmp)
384{
385 /*
386 * If the file descriptor is in use, close the file.
387 */
388 if (rtmp->bootfd >= 0) {
389 (void) close(rtmp->bootfd);
390 rtmp->bootfd = -1;
391 }
392
393 if (LastFree == NULL((void *)0)) /* cache for next time */
394 rtmp = LastFree;
Value stored to 'rtmp' is never read
395 else /* already one cached; free this one */
396 free((char *)rtmp);
397}
398
399/*
400** FreeConns -- free linked list of RMPCONN connections.
401**
402** Parameters:
403** None.
404**
405** Returns:
406** Nothing.
407**
408** Side Effects:
409** - All malloc'd memory associated with the linked list of
410** connections will be free'd; `RmpConns' will be set to NULL.
411** - If LastFree is != NULL, it too will be free'd & NULL'd.
412**
413** Warnings:
414** - This routine must be called with SIGHUP blocked.
415*/
416void
417FreeConns(void)
418{
419 RMPCONN *rtmp;
420
421 while (RmpConns != NULL((void *)0)) {
422 rtmp = RmpConns;
423 RmpConns = RmpConns->next;
424 FreeConn(rtmp);
425 }
426
427 if (LastFree != NULL((void *)0)) {
428 free((char *)LastFree);
429 LastFree = NULL((void *)0);
430 }
431}
432
433/*
434** AddConn -- Add a connection to the linked list of connections.
435**
436** Parameters:
437** rconn - connection to be added.
438**
439** Returns:
440** Nothing.
441**
442** Side Effects:
443** - RmpConn will point to new connection.
444**
445** Warnings:
446** - This routine must be called with SIGHUP blocked.
447*/
448void
449AddConn(RMPCONN *rconn)
450{
451 if (RmpConns != NULL((void *)0))
452 rconn->next = RmpConns;
453 RmpConns = rconn;
454}
455
456/*
457** FindConn -- Find a connection in the linked list of connections.
458**
459** We use the RMP (Ethernet) address as the basis for determining
460** if this is the same connection. According to the Remote Maint
461** Protocol, we can only have one connection with any machine.
462**
463** Parameters:
464** rconn - connection to be found.
465**
466** Returns:
467** Matching connection from linked list or NULL if not found.
468**
469** Side Effects:
470** None.
471**
472** Warnings:
473** - This routine must be called with SIGHUP blocked.
474*/
475RMPCONN *
476FindConn(RMPCONN *rconn)
477{
478 RMPCONN *rtmp;
479
480 for (rtmp = RmpConns; rtmp != NULL((void *)0); rtmp = rtmp->next)
481 if (bcmp((char *)&rconn->rmp.hp_hdr.saddr[0],
482 (char *)&rtmp->rmp.hp_hdr.saddr[0], RMP_ADDRLEN6) == 0)
483 break;
484
485 return(rtmp);
486}
487
488/*
489** RemoveConn -- Remove a connection from the linked list of connections.
490**
491** Parameters:
492** rconn - connection to be removed.
493**
494** Returns:
495** Nothing.
496**
497** Side Effects:
498** - If found, an RMPCONN will cease to exist and it will
499** be removed from the linked list.
500**
501** Warnings:
502** - This routine must be called with SIGHUP blocked.
503*/
504void
505RemoveConn(RMPCONN *rconn)
506{
507 RMPCONN *thisrconn, *lastrconn;
508
509 if (RmpConns == rconn) { /* easy case */
510 RmpConns = RmpConns->next;
511 FreeConn(rconn);
512 } else { /* must traverse linked list */
513 lastrconn = RmpConns; /* set back ptr */
514 thisrconn = lastrconn->next; /* set current ptr */
515 while (thisrconn != NULL((void *)0)) {
516 if (rconn == thisrconn) { /* found it */
517 lastrconn->next = thisrconn->next;
518 FreeConn(thisrconn);
519 break;
520 }
521 lastrconn = thisrconn;
522 thisrconn = thisrconn->next;
523 }
524 }
525}