summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--usr.bin/ruptime/ruptime.18
-rw-r--r--usr.bin/ruptime/ruptime.c160
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. */
OpenPOWER on IntegriCloud