Bug Summary

File:src/usr.bin/rusers/rusers.c
Warning:line 604, column 12
2nd function call argument is an uninitialized value

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 rusers.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.bin/rusers/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.bin/rusers/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.bin/rusers/rusers.c
1/* $OpenBSD: rusers.c,v 1.43 2020/12/29 19:52:16 benno Exp $ */
2
3/*
4 * Copyright (c) 2001, 2003 Todd C. Miller <millert@openbsd.org>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 * Sponsored in part by the Defense Advanced Research Projects
18 * Agency (DARPA) and Air Force Research Laboratory, Air Force
19 * Materiel Command, USAF, under agreement number F39502-99-1-0512.
20 */
21/*-
22 * Copyright (c) 1993 John Brezak
23 * All rights reserved.
24 *
25 * Redistribution and use in source and binary forms, with or without
26 * modification, are permitted provided that the following conditions
27 * are met:
28 * 1. Redistributions of source code must retain the above copyright
29 * notice, this list of conditions and the following disclaimer.
30 * 2. Redistributions in binary form must reproduce the above copyright
31 * notice, this list of conditions and the following disclaimer in the
32 * documentation and/or other materials provided with the distribution.
33 * 3. The name of the author may not be used to endorse or promote products
34 * derived from this software without specific prior written permission.
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
37 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
38 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
40 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
41 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
42 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
45 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46 * POSSIBILITY OF SUCH DAMAGE.
47 */
48
49#include <sys/ioctl.h>
50#include <sys/socket.h>
51#include <sys/signal.h>
52#include <rpc/rpc.h>
53#include <rpc/pmap_prot.h>
54#include <rpc/pmap_rmt.h>
55#include <rpcsvc/rusers.h>
56#include <rpcsvc/rnusers.h> /* Old protocol version */
57#include <arpa/inet.h>
58#include <net/if.h>
59#include <err.h>
60#include <errno(*__errno()).h>
61#include <ifaddrs.h>
62#include <netdb.h>
63#include <stdio.h>
64#include <stdlib.h>
65#include <string.h>
66#include <termios.h>
67#include <unistd.h>
68#include <limits.h>
69#include <poll.h>
70
71#define MINIMUM(a, b)(((a) < (b)) ? (a) : (b)) (((a) < (b)) ? (a) : (b))
72#define MAXIMUM(a, b)(((a) > (b)) ? (a) : (b)) (((a) > (b)) ? (a) : (b))
73
74/* Preferred formatting */
75#define HOST_WIDTH17 17
76#define LINE_WIDTH8 8
77#define NAME_WIDTH8 8
78
79#define MAX_BROADCAST_SIZE1400 1400
80
81struct host_info {
82 u_int count;
83 u_int idle;
84 char *host;
85 rusers_utmp *users;
86} *hostinfo;
87
88void print_entry(struct host_info *, int);
89void fmt_idle(int, char *, size_t);
90void onehost(char *);
91void allhosts(void);
92void sorthosts(void);
93void expandhosts(void);
94void alarmclock(int);
95char *estrndup(const char *, size_t);
96struct host_info *add_host(char *);
97int hcompare(const void *, const void *);
98int icompare(const void *, const void *);
99int ucompare(const void *, const void *);
100bool_tint32_t rusers_reply(char *, struct sockaddr_in *);
101bool_tint32_t rusers_reply_3(char *, struct sockaddr_in *);
102enum clnt_stat get_reply(int, in_port_t, u_long, struct rpc_msg *,
103 struct rmtcallres *, bool_tint32_t (*)(char *, struct sockaddr_in *));
104enum clnt_stat rpc_setup(int *, XDR *, struct rpc_msg *,
105 struct rmtcallargs *, AUTH *, char *);
106__dead__attribute__((__noreturn__)) void usage(void);
107
108int aflag, hflag, iflag, lflag, uflag;
109u_int nentries, maxentries;
110long termwidth;
111extern char *__progname;
112
113int
114main(int argc, char **argv)
115{
116 struct winsize win;
117 char *cp;
118 int ch;
119
120 while ((ch = getopt(argc, argv, "ahilu")) != -1)
1
Assuming the condition is false
2
Loop condition is false. Execution continues on line 142
121 switch (ch) {
122 case 'a':
123 aflag = 1;
124 break;
125 case 'h':
126 hflag = 1;
127 break;
128 case 'i':
129 iflag = 1;
130 break;
131 case 'l':
132 lflag = 1;
133 break;
134 case 'u':
135 uflag = 1;
136 break;
137 default:
138 usage();
139 /*NOTREACHED*/
140 }
141
142 if (hflag + iflag + uflag > 1)
3
Assuming the condition is false
4
Taking false branch
143 usage();
144
145 termwidth = 0;
146 if ((cp = getenv("COLUMNS")) != NULL((void *)0))
5
Assuming the condition is true
6
Taking true branch
147 termwidth = strtonum(cp, 1, LONG_MAX9223372036854775807L, NULL((void *)0));
148 if (termwidth == 0 && ioctl(STDOUT_FILENO1, TIOCGWINSZ((unsigned long)0x40000000 | ((sizeof(struct winsize) & 0x1fff
) << 16) | ((('t')) << 8) | ((104)))
, &win) == 0 &&
7
Assuming 'termwidth' is not equal to 0
149 win.ws_col > 0)
150 termwidth = win.ws_col;
151 if (termwidth
7.1
'termwidth' is not equal to 0
== 0)
8
Taking false branch
152 termwidth = 80;
153
154 setvbuf(stdout(&__sF[1]), NULL((void *)0), _IOLBF1, 0);
155
156 if (argc == optind) {
9
Assuming 'argc' is equal to 'optind'
10
Taking true branch
157 if (hflag || iflag || uflag) {
11
Assuming 'hflag' is 0
12
Assuming 'iflag' is 0
13
Assuming 'uflag' is 0
14
Taking false branch
158 puts("Collecting responses...");
159 allhosts();
160 sorthosts();
161 } else
162 allhosts();
15
Calling 'allhosts'
163 } else {
164 aflag = 1;
165 for (; optind < argc; optind++)
166 (void) onehost(argv[optind]);
167 if (hflag || iflag || uflag)
168 sorthosts();
169 }
170
171 exit(0);
172}
173
174struct host_info *
175add_host(char *host)
176{
177 int i;
178
179 for (i = 0; i < nentries; i++) {
180 /* Existing entry. */
181 if (strcmp(host, hostinfo[i].host) == 0)
182 return(NULL((void *)0));
183 }
184
185 /* New entry, allocate space if needed and store. */
186 if (nentries == maxentries) {
187 maxentries += 128;
188 hostinfo = reallocarray(hostinfo, maxentries,
189 sizeof(*hostinfo));
190 if (hostinfo == NULL((void *)0))
191 err(1, NULL((void *)0));
192 }
193 if ((hostinfo[nentries].host = strdup(host)) == NULL((void *)0))
194 err(1, NULL((void *)0));
195 return(&hostinfo[nentries++]);
196}
197
198void
199fmt_idle(int idle, char *idle_time, size_t idle_time_len)
200{
201 int days, hours, minutes, seconds;
202
203 switch (idle) {
204 case 0:
205 *idle_time = '\0';
206 break;
207 case INT_MAX2147483647:
208 strlcpy(idle_time, "??", idle_time_len);
209 break;
210 default:
211 seconds = idle;
212 days = seconds / (60*60*24);
213 seconds %= (60*60*24);
214 hours = seconds / (60*60);
215 seconds %= (60*60);
216 minutes = seconds / 60;
217 seconds %= 60;
218 if (idle >= (24*60*60))
219 snprintf(idle_time, idle_time_len,
220 "%d day%s, %d:%02d:%02d", days,
221 days > 1 ? "s" : "", hours, minutes, seconds);
222 else if (idle >= (60*60))
223 snprintf(idle_time, idle_time_len, "%2d:%02d:%02d",
224 hours, minutes, seconds);
225 else if (idle > 60)
226 snprintf(idle_time, idle_time_len, "%2d:%02d",
227 minutes, seconds);
228 else
229 snprintf(idle_time, idle_time_len, " :%02d", idle);
230 break;
231 }
232}
233
234bool_tint32_t
235rusers_reply(char *replyp, struct sockaddr_in *raddrp)
236{
237 utmpidlearr *up = (utmpidlearr *)replyp;
238 struct host_info *entry;
239 struct hostent *hp;
240 rusers_utmp *ut;
241 char *host;
242 int i;
243
244 if (!aflag && up->uia_cnt == 0)
245 return(0);
246
247 hp = gethostbyaddr((char *)&raddrp->sin_addr,
248 sizeof(struct in_addr), AF_INET2);
249 if (hp)
250 host = hp->h_name;
251 else
252 host = inet_ntoa(raddrp->sin_addr);
253 if ((entry = add_host(host)) == NULL((void *)0))
254 return(0);
255
256 if (up->uia_cnt == 0)
257 ut = NULL((void *)0);
258 else if ((ut = calloc(up->uia_cnt, sizeof(*ut))) == NULL((void *)0))
259 err(1, NULL((void *)0));
260 entry->users = ut;
261 entry->count = up->uia_cnt;
262 entry->idle = UINT_MAX(2147483647 *2U +1U);
263 for (i = 0; i < up->uia_cnt; i++, ut++) {
264 ut->ut_user = estrndup(up->uia_arr[i]->ui_utmp.ut_name,
265 RNUSERS_MAXUSERLEN8);
266 ut->ut_line = estrndup(up->uia_arr[i]->ui_utmp.ut_line,
267 RNUSERS_MAXLINELEN8);
268 ut->ut_host = estrndup(up->uia_arr[i]->ui_utmp.ut_host,
269 RNUSERS_MAXHOSTLEN16);
270 ut->ut_time = up->uia_arr[i]->ui_utmp.ut_time;
271 ut->ut_idle = up->uia_arr[i]->ui_idle;
272 if (ut->ut_idle < entry->idle)
273 entry->idle = ut->ut_idle;
274 }
275
276 if (!hflag && !iflag && !uflag) {
277 print_entry(entry, lflag && entry->count);
278 for (i = 0, ut = entry->users; i < entry->count; i++, ut++) {
279 free(ut->ut_user);
280 free(ut->ut_line);
281 free(ut->ut_host);
282 }
283 free(entry->users);
284 }
285
286 return(0);
287}
288
289bool_tint32_t
290rusers_reply_3(char *replyp, struct sockaddr_in *raddrp)
291{
292 utmp_array *up3 = (utmp_array *)replyp;
293 struct host_info *entry;
294 struct hostent *hp;
295 rusers_utmp *ut;
296 char *host;
297 int i;
298
299 if (!aflag && up3->utmp_array_len == 0)
300 return(0);
301
302 hp = gethostbyaddr((char *)&raddrp->sin_addr,
303 sizeof(struct in_addr), AF_INET2);
304 if (hp)
305 host = hp->h_name;
306 else
307 host = inet_ntoa(raddrp->sin_addr);
308 if ((entry = add_host(host)) == NULL((void *)0))
309 return(0);
310
311 if (up3->utmp_array_len == 0)
312 ut = NULL((void *)0);
313 else if ((ut = calloc(up3->utmp_array_len, sizeof(*ut))) == NULL((void *)0))
314 err(1, NULL((void *)0));
315 entry->users = ut;
316 entry->count = up3->utmp_array_len;
317 entry->idle = UINT_MAX(2147483647 *2U +1U);
318 for (i = 0; i < up3->utmp_array_len; i++, ut++) {
319 ut->ut_user = estrndup(up3->utmp_array_val[i].ut_user,
320 RUSERS_MAXUSERLEN32);
321 ut->ut_line = estrndup(up3->utmp_array_val[i].ut_line,
322 RUSERS_MAXLINELEN32);
323 ut->ut_host = estrndup(up3->utmp_array_val[i].ut_host,
324 RUSERS_MAXHOSTLEN257);
325 ut->ut_time = up3->utmp_array_val[i].ut_time;
326 ut->ut_idle = up3->utmp_array_val[i].ut_idle;
327 if (ut->ut_idle < entry->idle)
328 entry->idle = ut->ut_idle;
329 }
330
331 if (!hflag && !iflag && !uflag) {
332 print_entry(entry, lflag && entry->count);
333 for (i = 0, ut = entry->users; i < entry->count; i++, ut++) {
334 free(ut->ut_user);
335 free(ut->ut_line);
336 free(ut->ut_host);
337 }
338 free(entry->users);
339 }
340
341 return(0);
342}
343
344void
345onehost(char *host)
346{
347 utmpidlearr up;
348 utmp_array up3;
349 CLIENT *rusers_clnt;
350 struct sockaddr_in sin;
351 struct hostent *hp;
352 struct timeval tv = { 25, 0 };
353 int error;
354
355 memset(&sin, 0, sizeof sin);
356
357 hp = gethostbyname(host);
358 if (hp == NULL((void *)0))
359 errx(1, "unknown host \"%s\"", host);
360
361 /* Try version 3 first. */
362 rusers_clnt = clnt_create(host, RUSERSPROG((u_long)100002), RUSERSVERS_3((u_long)3), "udp");
363 if (rusers_clnt == NULL((void *)0)) {
364 clnt_pcreateerror(__progname);
365 exit(1);
366 }
367
368 memset(&up3, 0, sizeof(up3));
369 error = clnt_call(rusers_clnt, RUSERSPROC_NAMES, xdr_void, NULL,((*(rusers_clnt)->cl_ops->cl_call)(rusers_clnt, ((u_long
)2), xdr_void, (caddr_t)((void *)0), xdr_utmp_array, (caddr_t
)&up3, tv))
370 xdr_utmp_array, &up3, tv)((*(rusers_clnt)->cl_ops->cl_call)(rusers_clnt, ((u_long
)2), xdr_void, (caddr_t)((void *)0), xdr_utmp_array, (caddr_t
)&up3, tv))
;
371 switch (error) {
372 case RPC_SUCCESS:
373 sin.sin_addr.s_addr = *(int *)hp->h_addrh_addr_list[0];
374 rusers_reply_3((char *)&up3, &sin);
375 clnt_destroy(rusers_clnt)((*(rusers_clnt)->cl_ops->cl_destroy)(rusers_clnt));
376 return;
377 case RPC_PROGVERSMISMATCH:
378 clnt_destroy(rusers_clnt)((*(rusers_clnt)->cl_ops->cl_destroy)(rusers_clnt));
379 break;
380 default:
381 clnt_perror(rusers_clnt, __progname);
382 clnt_destroy(rusers_clnt)((*(rusers_clnt)->cl_ops->cl_destroy)(rusers_clnt));
383 exit(1);
384 }
385
386 /* Fall back to version 2. */
387 rusers_clnt = clnt_create(host, RUSERSPROG((u_long)100002), RUSERSVERS_IDLE2, "udp");
388 if (rusers_clnt == NULL((void *)0)) {
389 clnt_pcreateerror(__progname);
390 exit(1);
391 }
392
393 memset(&up, 0, sizeof(up));
394 error = clnt_call(rusers_clnt, RUSERSPROC_NAMES, xdr_void, NULL,((*(rusers_clnt)->cl_ops->cl_call)(rusers_clnt, ((u_long
)2), xdr_void, (caddr_t)((void *)0), xdr_utmpidlearr, (caddr_t
)&up, tv))
395 xdr_utmpidlearr, &up, tv)((*(rusers_clnt)->cl_ops->cl_call)(rusers_clnt, ((u_long
)2), xdr_void, (caddr_t)((void *)0), xdr_utmpidlearr, (caddr_t
)&up, tv))
;
396 if (error != RPC_SUCCESS) {
397 clnt_perror(rusers_clnt, __progname);
398 clnt_destroy(rusers_clnt)((*(rusers_clnt)->cl_ops->cl_destroy)(rusers_clnt));
399 exit(1);
400 }
401 sin.sin_addr.s_addr = *(int *)hp->h_addrh_addr_list[0];
402 rusers_reply((char *)&up, &sin);
403 clnt_destroy(rusers_clnt)((*(rusers_clnt)->cl_ops->cl_destroy)(rusers_clnt));
404}
405
406enum clnt_stat
407get_reply(int sock, in_port_t port, u_long xid, struct rpc_msg *msgp,
408 struct rmtcallres *resp, bool_tint32_t (*callback)(char *, struct sockaddr_in *))
409{
410 ssize_t inlen;
411 socklen_t fromlen;
412 struct sockaddr_in raddr;
413 char inbuf[UDPMSGSIZE8800];
414 XDR xdr;
415
416retry:
417 msgp->acpted_rplyru.RM_rmb.ru.RP_ar.ar_verf = _null_auth;
418 msgp->acpted_rplyru.RM_rmb.ru.RP_ar.ar_resultsru.AR_results.where = (caddr_t)resp;
419 msgp->acpted_rplyru.RM_rmb.ru.RP_ar.ar_resultsru.AR_results.proc = xdr_rmtcallres;
420
421 fromlen = sizeof(raddr);
422 inlen = recvfrom(sock, inbuf, sizeof(inbuf), 0,
423 (struct sockaddr *)&raddr, &fromlen);
424 if (inlen == -1) {
425 if (errno(*__errno()) == EINTR4)
426 goto retry;
427 return (RPC_CANTRECV);
428 }
429 if (inlen < sizeof(u_int32_t))
430 goto retry;
431
432 /*
433 * If the reply we got matches our request, decode the
434 * replay and pass it to the callback function.
435 */
436 xdrmem_create(&xdr, inbuf, (u_int)inlen, XDR_DECODE);
437 if (xdr_replymsg(&xdr, msgp)) {
438 if ((msgp->rm_xid == xid) &&
439 (msgp->rm_replyru.RM_rmb.rp_stat == MSG_ACCEPTED) &&
440 (msgp->acpted_rplyru.RM_rmb.ru.RP_ar.ar_stat == SUCCESS)) {
441 raddr.sin_port = htons(port)(__uint16_t)(__builtin_constant_p(port) ? (__uint16_t)(((__uint16_t
)(port) & 0xffU) << 8 | ((__uint16_t)(port) & 0xff00U
) >> 8) : __swap16md(port))
;
442 (void)(*callback)(resp->results_ptr, &raddr);
443 }
444 }
445 xdr.x_op = XDR_FREE;
446 msgp->acpted_rplyru.RM_rmb.ru.RP_ar.ar_resultsru.AR_results.proc = xdr_void;
447 (void)xdr_replymsg(&xdr, msgp);
448 (void)(*resp->xdr_results)(&xdr, resp->results_ptr);
449 xdr_destroy(&xdr)if ((&xdr)->x_ops->x_destroy) (*(&xdr)->x_ops
->x_destroy)(&xdr)
;
450
451 return(RPC_SUCCESS);
452}
453
454enum clnt_stat
455rpc_setup(int *fdp, XDR *xdr, struct rpc_msg *msg, struct rmtcallargs *args,
456 AUTH *unix_auth, char *buf)
457{
458 int on = 1;
459
460 if ((*fdp = socket(AF_INET2, SOCK_DGRAM2, IPPROTO_UDP17)) == -1)
461 return(RPC_CANTSEND);
462
463 if (setsockopt(*fdp, SOL_SOCKET0xffff, SO_BROADCAST0x0020, &on, sizeof(on)) == -1)
464 return(RPC_CANTSEND);
465
466 msg->rm_xid = arc4random();
467 msg->rm_direction = CALL;
468 msg->rm_callru.RM_cmb.cb_rpcvers = RPC_MSG_VERSION((unsigned long) 2);
469 msg->rm_callru.RM_cmb.cb_prog = PMAPPROG((unsigned long)100000);
470 msg->rm_callru.RM_cmb.cb_vers = PMAPVERS((unsigned long)2);
471 msg->rm_callru.RM_cmb.cb_proc = PMAPPROC_CALLIT((unsigned long)5);
472 msg->rm_callru.RM_cmb.cb_cred = unix_auth->ah_cred;
473 msg->rm_callru.RM_cmb.cb_verf = unix_auth->ah_verf;
474
475 xdrmem_create(xdr, buf, MAX_BROADCAST_SIZE1400, XDR_ENCODE);
476 if (!xdr_callmsg(xdr, msg) || !xdr_rmtcall_args(xdr, args))
477 return(RPC_CANTENCODEARGS);
478
479 return(RPC_SUCCESS);
480}
481
482void
483allhosts(void)
484{
485 enum clnt_stat stat;
486 struct itimerval timeout;
487 AUTH *unix_auth;
488 size_t outlen[2];
489 int sock[2] = { -1, -1 };
490 int i, rval;
491 u_long xid[2], port[2];
492 struct pollfd pfd[2];
493 struct sockaddr_in *sin, baddr;
494 struct rmtcallargs args;
495 struct rmtcallres res[2];
496 struct rpc_msg msg[2];
497 struct ifaddrs *ifa, *ifap = NULL((void *)0);
498 char buf[2][MAX_BROADCAST_SIZE1400];
499 utmpidlearr up;
500 utmp_array up3;
501 XDR xdr;
502
503 if ((unix_auth = authunix_create_default()) == NULL((void *)0))
16
Assuming the condition is false
17
Taking false branch
504 err(1, "can't create auth handle");
505
506 if (getifaddrs(&ifap) != 0)
18
Assuming the condition is false
19
Taking false branch
507 err(1, "can't get list of interface addresses");
508
509 memset(&up, 0, sizeof(up));
510 memset(&up3, 0, sizeof(up3));
511 memset(&baddr, 0, sizeof(baddr));
512 memset(&res, 0, sizeof(res));
513 memset(&msg, 0, sizeof(msg));
514 memset(&timeout, 0, sizeof(timeout));
515
516 args.prog = RUSERSPROG((u_long)100002);
517 args.vers = RUSERSVERS_IDLE2;
518 args.proc = RUSERSPROC_NAMES((u_long)2);
519 args.xdr_args = xdr_void;
520 args.args_ptr = NULL((void *)0);
521
522 stat = rpc_setup(&sock[0], &xdr, &msg[0], &args, unix_auth, buf[0]);
523 if (stat
19.1
'stat' is equal to RPC_SUCCESS
!= RPC_SUCCESS)
20
Taking false branch
524 goto cleanup;
525 xid[0] = msg[0].rm_xid;
526 outlen[0] = xdr_getpos(&xdr)(*(&xdr)->x_ops->x_getpostn)(&xdr);
527 xdr_destroy(&xdr)if ((&xdr)->x_ops->x_destroy) (*(&xdr)->x_ops
->x_destroy)(&xdr)
;
21
Assuming field 'x_destroy' is null
22
Taking false branch
528
529 args.vers = RUSERSVERS_3((u_long)3);
530 stat = rpc_setup(&sock[1], &xdr, &msg[1], &args, unix_auth, buf[1]);
531 if (stat
22.1
'stat' is equal to RPC_SUCCESS
!= RPC_SUCCESS)
23
Taking false branch
532 goto cleanup;
533 xid[1] = msg[1].rm_xid;
534 outlen[1] = xdr_getpos(&xdr)(*(&xdr)->x_ops->x_getpostn)(&xdr);
535 xdr_destroy(&xdr)if ((&xdr)->x_ops->x_destroy) (*(&xdr)->x_ops
->x_destroy)(&xdr)
;
24
Assuming field 'x_destroy' is null
25
Taking false branch
536
537 baddr.sin_family = AF_INET2;
538 baddr.sin_port = htons(PMAPPORT)(__uint16_t)(__builtin_constant_p(((unsigned short)111)) ? (__uint16_t
)(((__uint16_t)(((unsigned short)111)) & 0xffU) << 8
| ((__uint16_t)(((unsigned short)111)) & 0xff00U) >>
8) : __swap16md(((unsigned short)111)))
;
26
'?' condition is true
539 baddr.sin_addr.s_addr = htonl(INADDR_ANY)(__uint32_t)(__builtin_constant_p(((u_int32_t)(0x00000000))) ?
(__uint32_t)(((__uint32_t)(((u_int32_t)(0x00000000))) & 0xff
) << 24 | ((__uint32_t)(((u_int32_t)(0x00000000))) &
0xff00) << 8 | ((__uint32_t)(((u_int32_t)(0x00000000))
) & 0xff0000) >> 8 | ((__uint32_t)(((u_int32_t)(0x00000000
))) & 0xff000000) >> 24) : __swap32md(((u_int32_t)(
0x00000000))))
;
27
'?' condition is true
540
541 res[0].port_ptr = &port[0];
542 res[0].xdr_results = xdr_utmpidlearr;
543 res[0].results_ptr = (caddr_t)&up;
544
545 res[1].port_ptr = &port[1];
546 res[1].xdr_results = xdr_utmp_array;
547 res[1].results_ptr = (caddr_t)&up3;
548
549 (void)signal(SIGALRM14, alarmclock);
550
551 /*
552 * We do 6 runs through the loop. On even runs we send
553 * a version 3 broadcast. On odd ones we send a version 2
554 * broadcast. This should give version 3 replies enough
555 * of an 'edge' over the old version 2 ones in most cases.
556 * We poll() waiting for replies for 5 seconds in between
557 * each broadcast.
558 */
559 for (i = 0; i < 6; i++) {
28
Loop condition is true. Entering loop body
560 for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
29
Loop condition is false. Execution continues on line 588
561 if (ifa->ifa_addr == NULL((void *)0) ||
562 ifa->ifa_addr->sa_family != AF_INET2 ||
563 !(ifa->ifa_flags & IFF_BROADCAST0x2) ||
564 !(ifa->ifa_flags & IFF_UP0x1) ||
565 ifa->ifa_broadaddrifa_dstaddr == NULL((void *)0) ||
566 ifa->ifa_broadaddrifa_dstaddr->sa_family != AF_INET2)
567 continue;
568 sin = (struct sockaddr_in *)ifa->ifa_broadaddrifa_dstaddr;
569 baddr.sin_addr = sin->sin_addr;
570
571 /* use protocol 2 or 3 depending on i (odd or even) */
572 if (i & 1) {
573 if (sendto(sock[0], buf[0], outlen[0], 0,
574 (struct sockaddr *)&baddr,
575 sizeof(baddr)) != outlen[0])
576 err(1, "can't send broadcast packet");
577 } else {
578 if (sendto(sock[1], buf[1], outlen[1], 0,
579 (struct sockaddr *)&baddr,
580 sizeof(baddr)) != outlen[1])
581 err(1, "can't send broadcast packet");
582 }
583 }
584
585 /*
586 * We stay in the poll loop for ~5 seconds
587 */
588 timeout.it_value.tv_sec = 5;
589 timeout.it_value.tv_usec = 0;
590 while (timerisset(&timeout.it_value)((&timeout.it_value)->tv_sec || (&timeout.it_value
)->tv_usec)
) {
591 pfd[0].fd = sock[0];
592 pfd[0].events = POLLIN0x0001;
593 pfd[1].fd = sock[1];
594 pfd[1].events = POLLIN0x0001;
595 setitimer(ITIMER_REAL0, &timeout, NULL((void *)0));
596 rval = poll(pfd, 2, 0);
597 setitimer(ITIMER_REAL0, NULL((void *)0), &timeout);
598 if (rval == -1) {
30
Assuming the condition is false
31
Taking false branch
599 if (errno(*__errno()) == EINTR4)
600 break;
601 err(1, "poll"); /* shouldn't happen */
602 }
603 if (pfd[1].revents & POLLIN0x0001) {
32
Assuming the condition is true
33
Taking true branch
604 stat = get_reply(sock[1], (in_port_t)port[1],
34
2nd function call argument is an uninitialized value
605 xid[1], &msg[1], &res[1], rusers_reply_3);
606 if (stat != RPC_SUCCESS)
607 goto cleanup;
608 }
609 if (pfd[0].revents & POLLIN0x0001) {
610 stat = get_reply(sock[0], (in_port_t)port[0],
611 xid[0], &msg[0], &res[0], rusers_reply);
612 if (stat != RPC_SUCCESS)
613 goto cleanup;
614 }
615 }
616 }
617cleanup:
618 if (ifap != NULL((void *)0))
619 freeifaddrs(ifap);
620 if (sock[0] >= 0)
621 (void)close(sock[0]);
622 if (sock[1] >= 0)
623 (void)close(sock[1]);
624 AUTH_DESTROY(unix_auth)((*((unix_auth)->ah_ops->ah_destroy))(unix_auth));
625 if (stat != RPC_SUCCESS) {
626 clnt_perrno(stat);
627 exit(1);
628 }
629}
630
631void
632print_entry(struct host_info *entry, int longfmt)
633{
634 char date[32], idle_time[64];
635 char remote[RUSERS_MAXHOSTLEN257 + 3];
636 struct rusers_utmp *ut;
637 int i, len;
638
639 if (!longfmt)
640 printf("%-*.*s ", HOST_WIDTH17, HOST_WIDTH17, entry->host);
641
642 for (i = 0, ut = entry->users; i < entry->count; i++, ut++) {
643 if (longfmt) {
644 time_t tim = ut->ut_time;
645 strftime(date, sizeof(date), "%h %d %R",
646 localtime(&tim));
647 date[sizeof(date) - 1] = '\0';
648 fmt_idle(ut->ut_idle, idle_time, sizeof(idle_time));
649 len = termwidth -
650 (MAXIMUM(strlen(ut->ut_user), NAME_WIDTH)(((strlen(ut->ut_user)) > (8)) ? (strlen(ut->ut_user
)) : (8))
+ 1 +
651 HOST_WIDTH17 + 1 + LINE_WIDTH8 + 1 + strlen(date) +
652 1 + MAXIMUM(8, strlen(idle_time))(((8) > (strlen(idle_time))) ? (8) : (strlen(idle_time))) + 1 + 2);
653 if (len > 0 && ut->ut_host[0] != '\0')
654 snprintf(remote, sizeof(remote), "(%.*s)",
655 MINIMUM(len, RUSERS_MAXHOSTLEN)(((len) < (257)) ? (len) : (257)), ut->ut_host);
656 else
657 remote[0] = '\0';
658 len = HOST_WIDTH17 - MINIMUM(HOST_WIDTH, strlen(entry->host))(((17) < (strlen(entry->host))) ? (17) : (strlen(entry->
host)))
+
659 LINE_WIDTH8 - MINIMUM(LINE_WIDTH, strlen(ut->ut_line))(((8) < (strlen(ut->ut_line))) ? (8) : (strlen(ut->ut_line
)))
;
660 printf("%-*s %.*s:%.*s%-*s %-12s %8s %s\n",
661 NAME_WIDTH8, ut->ut_user, HOST_WIDTH17, entry->host,
662 LINE_WIDTH8, ut->ut_line, len, "", date,
663 idle_time, remote);
664 } else {
665 fputs(ut->ut_user, stdout(&__sF[1]));
666 putchar(' ')(!__isthreaded ? __sputc(' ', (&__sF[1])) : (putc)(' ', (
&__sF[1])))
;
667 }
668 }
669 if (!longfmt)
670 putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n',
(&__sF[1])))
;
671}
672
673void
674expandhosts(void)
675{
676 struct host_info *new_hostinfo, *entry;
677 u_int count;
678 int i, j;
679
680 for (i = 0, count = 0; i < nentries; i++)
681 count += hostinfo[i].count;
682
683 new_hostinfo = calloc(sizeof(*entry), count);
684 if (new_hostinfo == NULL((void *)0))
685 err(1, NULL((void *)0));
686 for (i = 0, entry = new_hostinfo; i < nentries; i++) {
687 for (j = 0; j < hostinfo[i].count; j++) {
688 memcpy(entry, &hostinfo[i], sizeof(*entry));
689 entry->users = &hostinfo[i].users[j];
690 entry->idle = entry->users->ut_idle;
691 entry->count = 1;
692 entry++;
693 }
694 }
695 free(hostinfo);
696 hostinfo = new_hostinfo;
697 nentries = maxentries = count;
698}
699
700void
701sorthosts(void)
702{
703 int i;
704 int (*compar)(const void *, const void *);
705
706 if (iflag && lflag)
707 expandhosts();
708
709 if (hflag)
710 compar = hcompare;
711 else if (iflag)
712 compar = icompare;
713 else
714 compar = ucompare;
715 qsort(hostinfo, nentries, sizeof(*hostinfo), compar);
716
717 for (i = 0; i < nentries; i++)
718 print_entry(&hostinfo[i], lflag && hostinfo[i].count);
719}
720
721int
722hcompare(const void *aa, const void *bb)
723{
724 const struct host_info *a = (struct host_info *)aa;
725 const struct host_info *b = (struct host_info *)bb;
726 int rval;
727
728 if ((rval = strcasecmp(a->host, b->host)) != 0)
729 return(rval);
730
731 if (a->idle < b->idle)
732 return(-1);
733 else if (a->idle > b->idle)
734 return(1);
735
736 if (a->count > b->count)
737 return(-1);
738 else if (a->count < b->count)
739 return(1);
740
741 return(0);
742}
743
744int
745icompare(const void *aa, const void *bb)
746{
747 const struct host_info *a = (struct host_info *)aa;
748 const struct host_info *b = (struct host_info *)bb;
749
750 if (a->idle < b->idle)
751 return(-1);
752 else if (a->idle > b->idle)
753 return(1);
754
755 if (a->count > b->count)
756 return(-1);
757 else if (a->count < b->count)
758 return(1);
759
760 return(strcasecmp(a->host, b->host));
761}
762
763int
764ucompare(const void *aa, const void *bb)
765{
766 const struct host_info *a = (struct host_info *)aa;
767 const struct host_info *b = (struct host_info *)bb;
768
769 if (a->count > b->count)
770 return(-1);
771 else if (a->count < b->count)
772 return(1);
773
774 if (a->idle < b->idle)
775 return(-1);
776 else if (a->idle > b->idle)
777 return(1);
778
779 return(strcasecmp(a->host, b->host));
780}
781
782void
783alarmclock(int signo)
784{
785
786 ; /* just interrupt */
787}
788
789char *
790estrndup(const char *src, size_t len)
791{
792 char *dst, *end;
793
794 if ((end = memchr(src, '\0', len)) != NULL((void *)0))
795 len = end - src;
796
797 if ((dst = malloc(len + 1)) == NULL((void *)0))
798 err(1, NULL((void *)0));
799 memcpy(dst, src, len);
800 dst[len] = '\0';
801
802 return(dst);
803}
804
805void
806usage(void)
807{
808
809 fprintf(stderr(&__sF[2]), "usage: %s [-al] [-h | -i | -u] [hosts ...]\n",
810 __progname);
811 exit(1);
812}