Add functionality to only list hosts specified on the command line. If none
are specified the old behaviour is old. The submitted applied a much cleaner diff to ruptime.c, however it did not cover cases like listing failures. It would probably be a good idea to move the printing from the ruptime function, and have that function just be used to build the list, as that would unbreak sorting, but this diff is intended to be clear, relative to the original code. As the sort order is the order specified on the command line, for now, such is documented in the manual page accordingly. Submitted by: Edward J. M. Blocklesby <ejb@lythe.org.uk> MFC after: 3 weeks
This commit is contained in:
parent
c38dbd95e6
commit
74f10a5358
@ -41,6 +41,7 @@
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl alrtu
|
||||
.Op Ar host ...
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
@ -49,6 +50,13 @@ utility gives a status line like
|
||||
for each machine on the local network; these are formed from packets
|
||||
broadcast by each host on the network once every three minutes.
|
||||
.Pp
|
||||
If no operands are given,
|
||||
.Nm
|
||||
displays uptime status for all machines;
|
||||
otherwise only those hosts specified on the command line are displayed.
|
||||
If hosts are specified on the command line, the sort order is equivalent
|
||||
to the order hosts were specified on the command line.
|
||||
.Pp
|
||||
Machines for which no status report has been received for 11
|
||||
minutes are shown as being down, and machines for which no status
|
||||
report has been received for 4 days are not shown in the list at all.
|
||||
|
@ -70,11 +70,13 @@ struct whod awhod;
|
||||
size_t nhosts;
|
||||
time_t now;
|
||||
int rflg = 1;
|
||||
DIR *dirp;
|
||||
|
||||
int hscmp(const void *, const void *);
|
||||
char *interval(time_t, const char *);
|
||||
int lcmp(const void *, const void *);
|
||||
void morehosts(void);
|
||||
void ruptime(const char *, int, int (*)(const void *, const void *));
|
||||
int tcmp(const void *, const void *);
|
||||
int ucmp(const void *, const void *);
|
||||
void usage(void);
|
||||
@ -82,16 +84,8 @@ void usage(void);
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
struct dirent *dp;
|
||||
struct hs *hsp;
|
||||
struct whod *wd;
|
||||
struct whoent *we;
|
||||
DIR *dirp;
|
||||
size_t hspace;
|
||||
int aflg, ch, fd, i, maxloadav;
|
||||
char buf[sizeof(struct whod)];
|
||||
int (*cmp)(const void *, const void *);
|
||||
u_int cc;
|
||||
int aflg, ch;
|
||||
|
||||
aflg = 0;
|
||||
cmp = hscmp;
|
||||
@ -118,74 +112,14 @@ main(int argc, char *argv[])
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc != 0)
|
||||
usage();
|
||||
|
||||
if (chdir(_PATH_RWHODIR) || (dirp = opendir(".")) == NULL)
|
||||
err(1, "%s", _PATH_RWHODIR);
|
||||
|
||||
maxloadav = -1;
|
||||
for (nhosts = hspace = 0; (dp = readdir(dirp)) != NULL;) {
|
||||
if (dp->d_ino == 0 || strncmp(dp->d_name, "whod.", 5))
|
||||
continue;
|
||||
if ((fd = open(dp->d_name, O_RDONLY, 0)) < 0) {
|
||||
warn("%s", dp->d_name);
|
||||
continue;
|
||||
}
|
||||
cc = read(fd, buf, sizeof(struct whod));
|
||||
(void)close(fd);
|
||||
|
||||
if (cc < WHDRSIZE)
|
||||
continue;
|
||||
if (nhosts == hspace) {
|
||||
if ((hs =
|
||||
realloc(hs, (hspace += 40) * sizeof(*hs))) == NULL)
|
||||
err(1, NULL);
|
||||
hsp = hs + nhosts;
|
||||
}
|
||||
|
||||
if ((hsp->hs_wd = malloc((size_t)WHDRSIZE)) == NULL)
|
||||
err(1, NULL);
|
||||
memmove(hsp->hs_wd, buf, (size_t)WHDRSIZE);
|
||||
|
||||
for (wd = (struct whod *)buf, i = 0; i < 2; ++i)
|
||||
if (wd->wd_loadav[i] > maxloadav)
|
||||
maxloadav = wd->wd_loadav[i];
|
||||
|
||||
for (hsp->hs_nusers = 0,
|
||||
we = (struct whoent *)(buf + cc); --we >= wd->wd_we;)
|
||||
if (aflg || we->we_idle < 3600)
|
||||
++hsp->hs_nusers;
|
||||
++hsp;
|
||||
++nhosts;
|
||||
}
|
||||
if (nhosts == 0)
|
||||
errx(1, "no hosts in %s", _PATH_RWHODIR);
|
||||
|
||||
(void)time(&now);
|
||||
qsort(hs, nhosts, sizeof(hs[0]), cmp);
|
||||
for (i = 0; i < (int)nhosts; i++) {
|
||||
hsp = &hs[i];
|
||||
if (LEFTEARTH(hsp))
|
||||
continue;
|
||||
if (ISDOWN(hsp)) {
|
||||
(void)printf("%-12.12s%s\n", hsp->hs_wd->wd_hostname,
|
||||
interval(now - hsp->hs_wd->wd_recvtime, "down"));
|
||||
continue;
|
||||
}
|
||||
(void)printf(
|
||||
"%-12.12s%s, %4d user%s load %*.2f, %*.2f, %*.2f\n",
|
||||
hsp->hs_wd->wd_hostname,
|
||||
interval((time_t)hsp->hs_wd->wd_sendtime -
|
||||
(time_t)hsp->hs_wd->wd_boottime, " up"),
|
||||
hsp->hs_nusers,
|
||||
hsp->hs_nusers == 1 ? ", " : "s,",
|
||||
maxloadav >= 1000 ? 5 : 4,
|
||||
hsp->hs_wd->wd_loadav[0] / 100.0,
|
||||
maxloadav >= 1000 ? 5 : 4,
|
||||
hsp->hs_wd->wd_loadav[1] / 100.0,
|
||||
maxloadav >= 1000 ? 5 : 4,
|
||||
hsp->hs_wd->wd_loadav[2] / 100.0);
|
||||
ruptime(*argv, aflg, cmp);
|
||||
while (*argv++ != NULL) {
|
||||
if (*argv == NULL)
|
||||
break;
|
||||
ruptime(*argv, aflg, cmp);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
@ -241,6 +175,98 @@ lcmp(const void *a1, const void *a2)
|
||||
(HS(a2)->hs_wd->wd_loadav[0] - HS(a1)->hs_wd->wd_loadav[0]));
|
||||
}
|
||||
|
||||
void
|
||||
ruptime(const char *host, int aflg, int (*cmp)(const void *, const void *))
|
||||
{
|
||||
struct hs *hsp;
|
||||
struct whod *wd;
|
||||
struct whoent *we;
|
||||
struct dirent *dp;
|
||||
const char *hostname;
|
||||
char buf[sizeof(struct whod)];
|
||||
int fd, i, maxloadav;
|
||||
size_t hspace;
|
||||
u_int cc;
|
||||
|
||||
rewinddir(dirp);
|
||||
hsp = NULL;
|
||||
maxloadav = -1;
|
||||
for (nhosts = hspace = 0; (dp = readdir(dirp)) != NULL;) {
|
||||
if (dp->d_ino == 0 || strncmp(dp->d_name, "whod.", 5) != 0)
|
||||
continue;
|
||||
if ((fd = open(dp->d_name, O_RDONLY, 0)) < 0) {
|
||||
warn("%s", dp->d_name);
|
||||
continue;
|
||||
}
|
||||
cc = read(fd, buf, sizeof(struct whod));
|
||||
(void)close(fd);
|
||||
if (host != NULL) {
|
||||
hostname = ((struct whod *)buf)->wd_hostname;
|
||||
if (strcasecmp(hostname, host) != 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cc < WHDRSIZE)
|
||||
continue;
|
||||
if (nhosts == hspace) {
|
||||
if ((hs =
|
||||
realloc(hs, (hspace += 40) * sizeof(*hs))) == NULL)
|
||||
err(1, NULL);
|
||||
hsp = hs + nhosts;
|
||||
}
|
||||
|
||||
if ((hsp->hs_wd = malloc((size_t)WHDRSIZE)) == NULL)
|
||||
err(1, NULL);
|
||||
memmove(hsp->hs_wd, buf, (size_t)WHDRSIZE);
|
||||
|
||||
for (wd = (struct whod *)buf, i = 0; i < 2; ++i)
|
||||
if (wd->wd_loadav[i] > maxloadav)
|
||||
maxloadav = wd->wd_loadav[i];
|
||||
|
||||
for (hsp->hs_nusers = 0,
|
||||
we = (struct whoent *)(buf + cc); --we >= wd->wd_we;)
|
||||
if (aflg || we->we_idle < 3600)
|
||||
++hsp->hs_nusers;
|
||||
++hsp;
|
||||
++nhosts;
|
||||
}
|
||||
if (nhosts == 0) {
|
||||
if (host == NULL)
|
||||
errx(1, "no hosts in %s", _PATH_RWHODIR);
|
||||
else
|
||||
warnx("host %s not in %s", host, _PATH_RWHODIR);
|
||||
}
|
||||
|
||||
(void)time(&now);
|
||||
qsort(hs, nhosts, sizeof(hs[0]), cmp);
|
||||
for (i = 0; i < (int)nhosts; i++) {
|
||||
hsp = &hs[i];
|
||||
if (LEFTEARTH(hsp))
|
||||
continue;
|
||||
if (ISDOWN(hsp)) {
|
||||
(void)printf("%-12.12s%s\n", hsp->hs_wd->wd_hostname,
|
||||
interval(now - hsp->hs_wd->wd_recvtime, "down"));
|
||||
continue;
|
||||
}
|
||||
(void)printf(
|
||||
"%-12.12s%s, %4d user%s load %*.2f, %*.2f, %*.2f\n",
|
||||
hsp->hs_wd->wd_hostname,
|
||||
interval((time_t)hsp->hs_wd->wd_sendtime -
|
||||
(time_t)hsp->hs_wd->wd_boottime, " up"),
|
||||
hsp->hs_nusers,
|
||||
hsp->hs_nusers == 1 ? ", " : "s,",
|
||||
maxloadav >= 1000 ? 5 : 4,
|
||||
hsp->hs_wd->wd_loadav[0] / 100.0,
|
||||
maxloadav >= 1000 ? 5 : 4,
|
||||
hsp->hs_wd->wd_loadav[1] / 100.0,
|
||||
maxloadav >= 1000 ? 5 : 4,
|
||||
hsp->hs_wd->wd_loadav[2] / 100.0);
|
||||
free(hsp->hs_wd);
|
||||
}
|
||||
free(hs);
|
||||
hs = NULL;
|
||||
}
|
||||
|
||||
/* Number of users comparison. */
|
||||
int
|
||||
ucmp(const void *a1, const void *a2)
|
||||
|
Loading…
Reference in New Issue
Block a user