1/*
2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
--- 26 unchanged lines hidden (view full) ---
35
36#if 0
37#ifndef lint
38static char sccsid[] = "@(#)rwhod.c 8.1 (Berkeley) 6/6/93";
39#endif /* not lint */
40#endif
41
42#include <sys/cdefs.h>
43__FBSDID("$FreeBSD: head/usr.sbin/rwhod/rwhod.c 146940 2005-06-03 17:38:33Z ssouhlal $");
44
45#include <sys/param.h>
46#include <sys/socket.h>
47#include <sys/stat.h>
48#include <sys/signal.h>
49#include <sys/ioctl.h>
50#include <sys/sysctl.h>
51
--- 10 unchanged lines hidden (view full) ---
62#include <fcntl.h>
63#include <netdb.h>
64#include <paths.h>
65#include <stdio.h>
66#include <stdlib.h>
67#include <string.h>
68#include <syslog.h>
69#include <timeconv.h>
70#include <unistd.h>
71#include <utmp.h>
72#include <pwd.h>
73#include <grp.h>
74
75/*
76 * This version of Berkeley's rwhod has been modified to use IP multicast
77 * datagrams, under control of a new command-line option:
78 *
79 * rwhod -m causes rwhod to use IP multicast (instead of
--- 61 unchanged lines hidden (view full) ---
141 struct sockaddr *n_addr; /* who to send to */
142 int n_addrlen; /* size of address */
143 int n_flags; /* should forward?, interface flags */
144};
145
146struct neighbor *neighbors;
147struct whod mywd;
148struct servent *sp;
149int s, utmpf;
150
151#define WHDRSIZE (int)(sizeof(mywd) - sizeof(mywd.wd_we))
152
153void run_as(uid_t *, gid_t *);
154int configure(int);
155void getboottime(int);
156void onalrm(int);
157void quit(const char *);
--- 68 unchanged lines hidden (view full) ---
226 if (gethostname(myname, sizeof(myname) - 1) < 0) {
227 syslog(LOG_ERR, "gethostname: %m");
228 exit(1);
229 }
230 if ((cp = index(myname, '.')) != NULL)
231 *cp = '\0';
232 strncpy(mywd.wd_hostname, myname, sizeof(mywd.wd_hostname) - 1);
233 mywd.wd_hostname[sizeof(mywd.wd_hostname) - 1] = '\0';
234 utmpf = open(_PATH_UTMP, O_RDONLY|O_CREAT, 0644);
235 if (utmpf < 0) {
236 syslog(LOG_ERR, "%s: %m", _PATH_UTMP);
237 exit(1);
238 }
239 getboottime(0);
240 if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
241 syslog(LOG_ERR, "socket: %m");
242 exit(1);
243 }
244 if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0) {
245 syslog(LOG_ERR, "setsockopt SO_BROADCAST: %m");
246 exit(1);
--- 131 unchanged lines hidden (view full) ---
378 if (!isascii(*name) || !(isalnum(*name) || ispunct(*name)))
379 return (0);
380 name++, size++;
381 }
382 *name = '\0';
383 return (size > 0);
384}
385
386int utmptime;
387int utmpent;
388int utmpsize = 0;
389struct utmp *utmp;
390int alarmcount;
391
392void
393onalrm(signo)
394 int signo __unused;
395{
396 register struct neighbor *np;
397 register struct whoent *we = mywd.wd_we, *wlast;
398 register int i;
399 struct stat stb;
400 double avenrun[3];
401 time_t now;
402 int cc;
403
404 now = time(NULL);
405 if (alarmcount % 10 == 0)
406 getboottime(0);
407 alarmcount++;
408 (void) fstat(utmpf, &stb);
409 if ((stb.st_mtime != utmptime) || (stb.st_size > utmpsize)) {
410 utmptime = stb.st_mtime;
411 if (stb.st_size > utmpsize) {
412 utmpsize = stb.st_size + 10 * sizeof(struct utmp);
413 utmp = (struct utmp *)reallocf(utmp, utmpsize);
414 if (utmp == NULL) {
415 syslog(LOG_WARNING, "malloc failed");
416 utmpsize = 0;
417 goto done;
418 }
419 }
420 (void) lseek(utmpf, (off_t)0, L_SET);
421 cc = read(utmpf, (char *)utmp, stb.st_size);
422 if (cc < 0) {
423 syslog(LOG_ERR, "read(%s): %m", _PATH_UTMP);
424 goto done;
425 }
426 wlast = &mywd.wd_we[1024 / sizeof(struct whoent) - 1];
427 utmpent = cc / sizeof(struct utmp);
428 for (i = 0; i < utmpent; i++)
429 if (utmp[i].ut_name[0]) {
430 memcpy(we->we_utmp.out_line, utmp[i].ut_line,
431 sizeof(utmp[i].ut_line));
432 memcpy(we->we_utmp.out_name, utmp[i].ut_name,
433 sizeof(utmp[i].ut_name));
434 we->we_utmp.out_time = htonl(utmp[i].ut_time);
435 if (we >= wlast)
436 break;
437 we++;
438 }
439 utmpent = we - mywd.wd_we;
440 }
441
442 /*
443 * The test on utmpent looks silly---after all, if no one is
444 * logged on, why worry about efficiency?---but is useful on
445 * (e.g.) compute servers.
446 */
447 if (utmpent && chdir(_PATH_DEV)) {
448 syslog(LOG_ERR, "chdir(%s): %m", _PATH_DEV);
449 exit(1);
450 }
451 we = mywd.wd_we;
452 for (i = 0; i < utmpent; i++) {
453 if (stat(we->we_utmp.out_line, &stb) >= 0)
454 we->we_idle = htonl(now - stb.st_atime);
455 we++;
456 }
457 (void)getloadavg(avenrun, sizeof(avenrun)/sizeof(avenrun[0]));
458 for (i = 0; i < 3; i++)
459 mywd.wd_loadav[i] = htonl((u_long)(avenrun[i] * 100));
460 cc = (char *)we - (char *)&mywd;
461 mywd.wd_sendtime = htonl(_time_to_time32(time(NULL)));
462 mywd.wd_vers = WHODVERSION;
463 mywd.wd_type = WHODTYPE_STATUS;
464 if (multicast_mode == SCOPED_MULTICAST) {
465 (void) sendto(s, (char *)&mywd, cc, 0,
466 (struct sockaddr *)&multicast_addr,
467 sizeof(multicast_addr));
468 }
--- 11 unchanged lines hidden (view full) ---
480 exit(1);
481 }
482 (void) sendto(s, (char *)&mywd, cc, 0,
483 (struct sockaddr *)&multicast_addr,
484 sizeof(multicast_addr));
485 } else (void) sendto(s, (char *)&mywd, cc, 0,
486 np->n_addr, np->n_addrlen);
487 }
488 if (utmpent && chdir(_PATH_RWHODIR)) {
489 syslog(LOG_ERR, "chdir(%s): %m", _PATH_RWHODIR);
490 exit(1);
491 }
492done:
493 (void) alarm(AL_INTERVAL);
494}
495
496void
497getboottime(signo)
498 int signo __unused;
499{
500 int mib[2];
--- 237 unchanged lines hidden ---
2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
--- 26 unchanged lines hidden (view full) ---
35
36#if 0
37#ifndef lint
38static char sccsid[] = "@(#)rwhod.c 8.1 (Berkeley) 6/6/93";
39#endif /* not lint */
40#endif
41
42#include <sys/cdefs.h>
43__FBSDID("$FreeBSD: head/usr.sbin/rwhod/rwhod.c 146940 2005-06-03 17:38:33Z ssouhlal $");
44
45#include <sys/param.h>
46#include <sys/socket.h>
47#include <sys/stat.h>
48#include <sys/signal.h>
49#include <sys/ioctl.h>
50#include <sys/sysctl.h>
51
--- 10 unchanged lines hidden (view full) ---
62#include <fcntl.h>
63#include <netdb.h>
64#include <paths.h>
65#include <stdio.h>
66#include <stdlib.h>
67#include <string.h>
68#include <syslog.h>
69#include <timeconv.h>
70#include <unistd.h>
71#include <utmp.h>
72#include <pwd.h>
73#include <grp.h>
74
75/*
76 * This version of Berkeley's rwhod has been modified to use IP multicast
77 * datagrams, under control of a new command-line option:
78 *
79 * rwhod -m causes rwhod to use IP multicast (instead of
--- 61 unchanged lines hidden (view full) ---
141 struct sockaddr *n_addr; /* who to send to */
142 int n_addrlen; /* size of address */
143 int n_flags; /* should forward?, interface flags */
144};
145
146struct neighbor *neighbors;
147struct whod mywd;
148struct servent *sp;
149int s, utmpf;
150
151#define WHDRSIZE (int)(sizeof(mywd) - sizeof(mywd.wd_we))
152
153void run_as(uid_t *, gid_t *);
154int configure(int);
155void getboottime(int);
156void onalrm(int);
157void quit(const char *);
--- 68 unchanged lines hidden (view full) ---
226 if (gethostname(myname, sizeof(myname) - 1) < 0) {
227 syslog(LOG_ERR, "gethostname: %m");
228 exit(1);
229 }
230 if ((cp = index(myname, '.')) != NULL)
231 *cp = '\0';
232 strncpy(mywd.wd_hostname, myname, sizeof(mywd.wd_hostname) - 1);
233 mywd.wd_hostname[sizeof(mywd.wd_hostname) - 1] = '\0';
234 utmpf = open(_PATH_UTMP, O_RDONLY|O_CREAT, 0644);
235 if (utmpf < 0) {
236 syslog(LOG_ERR, "%s: %m", _PATH_UTMP);
237 exit(1);
238 }
239 getboottime(0);
240 if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
241 syslog(LOG_ERR, "socket: %m");
242 exit(1);
243 }
244 if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0) {
245 syslog(LOG_ERR, "setsockopt SO_BROADCAST: %m");
246 exit(1);
--- 131 unchanged lines hidden (view full) ---
378 if (!isascii(*name) || !(isalnum(*name) || ispunct(*name)))
379 return (0);
380 name++, size++;
381 }
382 *name = '\0';
383 return (size > 0);
384}
385
386int utmptime;
387int utmpent;
388int utmpsize = 0;
389struct utmp *utmp;
390int alarmcount;
391
392void
393onalrm(signo)
394 int signo __unused;
395{
396 register struct neighbor *np;
397 register struct whoent *we = mywd.wd_we, *wlast;
398 register int i;
399 struct stat stb;
400 double avenrun[3];
401 time_t now;
402 int cc;
403
404 now = time(NULL);
405 if (alarmcount % 10 == 0)
406 getboottime(0);
407 alarmcount++;
408 (void) fstat(utmpf, &stb);
409 if ((stb.st_mtime != utmptime) || (stb.st_size > utmpsize)) {
410 utmptime = stb.st_mtime;
411 if (stb.st_size > utmpsize) {
412 utmpsize = stb.st_size + 10 * sizeof(struct utmp);
413 utmp = (struct utmp *)reallocf(utmp, utmpsize);
414 if (utmp == NULL) {
415 syslog(LOG_WARNING, "malloc failed");
416 utmpsize = 0;
417 goto done;
418 }
419 }
420 (void) lseek(utmpf, (off_t)0, L_SET);
421 cc = read(utmpf, (char *)utmp, stb.st_size);
422 if (cc < 0) {
423 syslog(LOG_ERR, "read(%s): %m", _PATH_UTMP);
424 goto done;
425 }
426 wlast = &mywd.wd_we[1024 / sizeof(struct whoent) - 1];
427 utmpent = cc / sizeof(struct utmp);
428 for (i = 0; i < utmpent; i++)
429 if (utmp[i].ut_name[0]) {
430 memcpy(we->we_utmp.out_line, utmp[i].ut_line,
431 sizeof(utmp[i].ut_line));
432 memcpy(we->we_utmp.out_name, utmp[i].ut_name,
433 sizeof(utmp[i].ut_name));
434 we->we_utmp.out_time = htonl(utmp[i].ut_time);
435 if (we >= wlast)
436 break;
437 we++;
438 }
439 utmpent = we - mywd.wd_we;
440 }
441
442 /*
443 * The test on utmpent looks silly---after all, if no one is
444 * logged on, why worry about efficiency?---but is useful on
445 * (e.g.) compute servers.
446 */
447 if (utmpent && chdir(_PATH_DEV)) {
448 syslog(LOG_ERR, "chdir(%s): %m", _PATH_DEV);
449 exit(1);
450 }
451 we = mywd.wd_we;
452 for (i = 0; i < utmpent; i++) {
453 if (stat(we->we_utmp.out_line, &stb) >= 0)
454 we->we_idle = htonl(now - stb.st_atime);
455 we++;
456 }
457 (void)getloadavg(avenrun, sizeof(avenrun)/sizeof(avenrun[0]));
458 for (i = 0; i < 3; i++)
459 mywd.wd_loadav[i] = htonl((u_long)(avenrun[i] * 100));
460 cc = (char *)we - (char *)&mywd;
461 mywd.wd_sendtime = htonl(_time_to_time32(time(NULL)));
462 mywd.wd_vers = WHODVERSION;
463 mywd.wd_type = WHODTYPE_STATUS;
464 if (multicast_mode == SCOPED_MULTICAST) {
465 (void) sendto(s, (char *)&mywd, cc, 0,
466 (struct sockaddr *)&multicast_addr,
467 sizeof(multicast_addr));
468 }
--- 11 unchanged lines hidden (view full) ---
480 exit(1);
481 }
482 (void) sendto(s, (char *)&mywd, cc, 0,
483 (struct sockaddr *)&multicast_addr,
484 sizeof(multicast_addr));
485 } else (void) sendto(s, (char *)&mywd, cc, 0,
486 np->n_addr, np->n_addrlen);
487 }
488 if (utmpent && chdir(_PATH_RWHODIR)) {
489 syslog(LOG_ERR, "chdir(%s): %m", _PATH_RWHODIR);
490 exit(1);
491 }
492done:
493 (void) alarm(AL_INTERVAL);
494}
495
496void
497getboottime(signo)
498 int signo __unused;
499{
500 int mib[2];
--- 237 unchanged lines hidden ---