diff options
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/ruptime/ruptime.1 | 8 | ||||
-rw-r--r-- | usr.bin/ruptime/ruptime.c | 160 |
2 files changed, 101 insertions, 67 deletions
diff --git a/usr.bin/ruptime/ruptime.1 b/usr.bin/ruptime/ruptime.1 index f15153a..1ef1eb9 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 58c8789..32f85aa 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,15 +112,87 @@ 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); + ruptime(*argv, aflg, cmp); + while (*argv++ != NULL) { + if (*argv == NULL) + break; + ruptime(*argv, aflg, cmp); + } + exit(0); +} + +char * +interval(time_t tval, const char *updown) +{ + static char resbuf[32]; + int days, hours, minutes; + + if (tval < 0) { + (void)snprintf(resbuf, sizeof(resbuf), " %s ??:??", updown); + return (resbuf); + } + /* round to minutes. */ + minutes = (tval + (60 - 1)) / 60; + hours = minutes / 60; + minutes %= 60; + days = hours / 24; + hours %= 24; + if (days) + (void)snprintf(resbuf, sizeof(resbuf), + "%s %3d+%02d:%02d", updown, days, hours, minutes); + else + (void)snprintf(resbuf, sizeof(resbuf), + "%s %2d:%02d", updown, hours, minutes); + return (resbuf); +} + +#define HS(a) ((const struct hs *)(a)) + +/* Alphabetical comparison. */ +int +hscmp(const void *a1, const void *a2) +{ + return (rflg * + strcmp(HS(a1)->hs_wd->wd_hostname, HS(a2)->hs_wd->wd_hostname)); +} + +/* Load average comparison. */ +int +lcmp(const void *a1, const void *a2) +{ + if (ISDOWN(HS(a1))) + if (ISDOWN(HS(a2))) + return (tcmp(a1, a2)); + else + return (rflg); + else if (ISDOWN(HS(a2))) + return (-rflg); + else + return (rflg * + (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)) + 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); @@ -134,6 +200,11 @@ main(int argc, char *argv[]) } 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; @@ -159,8 +230,12 @@ main(int argc, char *argv[]) ++hsp; ++nhosts; } - if (nhosts == 0) - errx(1, "no hosts in %s", _PATH_RWHODIR); + 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); @@ -186,59 +261,10 @@ main(int argc, char *argv[]) hsp->hs_wd->wd_loadav[1] / 100.0, maxloadav >= 1000 ? 5 : 4, hsp->hs_wd->wd_loadav[2] / 100.0); + free(hsp->hs_wd); } - exit(0); -} - -char * -interval(time_t tval, const char *updown) -{ - static char resbuf[32]; - int days, hours, minutes; - - if (tval < 0) { - (void)snprintf(resbuf, sizeof(resbuf), " %s ??:??", updown); - return (resbuf); - } - /* round to minutes. */ - minutes = (tval + (60 - 1)) / 60; - hours = minutes / 60; - minutes %= 60; - days = hours / 24; - hours %= 24; - if (days) - (void)snprintf(resbuf, sizeof(resbuf), - "%s %3d+%02d:%02d", updown, days, hours, minutes); - else - (void)snprintf(resbuf, sizeof(resbuf), - "%s %2d:%02d", updown, hours, minutes); - return (resbuf); -} - -#define HS(a) ((const struct hs *)(a)) - -/* Alphabetical comparison. */ -int -hscmp(const void *a1, const void *a2) -{ - return (rflg * - strcmp(HS(a1)->hs_wd->wd_hostname, HS(a2)->hs_wd->wd_hostname)); -} - -/* Load average comparison. */ -int -lcmp(const void *a1, const void *a2) -{ - if (ISDOWN(HS(a1))) - if (ISDOWN(HS(a2))) - return (tcmp(a1, a2)); - else - return (rflg); - else if (ISDOWN(HS(a2))) - return (-rflg); - else - return (rflg * - (HS(a2)->hs_wd->wd_loadav[0] - HS(a1)->hs_wd->wd_loadav[0])); + free(hs); + hs = NULL; } /* Number of users comparison. */ |