From e7cb5ef7740301536aea956197d15a496a575135 Mon Sep 17 00:00:00 2001 From: Juli Mallett Date: Sat, 1 Mar 2003 23:09:26 +0000 Subject: [PATCH] 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 MFC after: 3 weeks --- usr.bin/ruptime/ruptime.1 | 8 ++ usr.bin/ruptime/ruptime.c | 174 ++++++++++++++++++++++---------------- 2 files changed, 108 insertions(+), 74 deletions(-) diff --git a/usr.bin/ruptime/ruptime.1 b/usr.bin/ruptime/ruptime.1 index f15153aaeedd..1ef1eb99ef5e 100644 --- a/usr.bin/ruptime/ruptime.1 +++ b/usr.bin/ruptime/ruptime.1 @@ -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. diff --git a/usr.bin/ruptime/ruptime.c b/usr.bin/ruptime/ruptime.c index 58c87896c479..32f85aacfe63 100644 --- a/usr.bin/ruptime/ruptime.c +++ b/usr.bin/ruptime/ruptime.c @@ -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)