summaryrefslogtreecommitdiffstats
path: root/usr.bin/rwho/rwho.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/rwho/rwho.c')
-rw-r--r--usr.bin/rwho/rwho.c131
1 files changed, 78 insertions, 53 deletions
diff --git a/usr.bin/rwho/rwho.c b/usr.bin/rwho/rwho.c
index 5f1334f..bcb5adb 100644
--- a/usr.bin/rwho/rwho.c
+++ b/usr.bin/rwho/rwho.c
@@ -1,6 +1,7 @@
-/*
- * Copyright (c) 1983, 1993
- * The Regents of the University of California. All rights reserved.
+/*-
+ * Copyright (c) 1983, 1993 The Regents of the University of California.
+ * Copyright (c) 2013 Mariusz Zaborski <oshogbo@FreeBSD.org>
+ * All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -42,6 +43,7 @@ static char sccsid[] = "@(#)rwho.c 8.1 (Berkeley) 6/6/93";
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include <sys/capability.h>
#include <sys/param.h>
#include <sys/file.h>
@@ -49,6 +51,7 @@ __FBSDID("$FreeBSD$");
#include <dirent.h>
#include <err.h>
+#include <errno.h>
#include <langinfo.h>
#include <locale.h>
#include <stdio.h>
@@ -58,22 +61,21 @@ __FBSDID("$FreeBSD$");
#include <timeconv.h>
#include <unistd.h>
-static DIR *dirp;
+#define NUSERS 1000
+#define WHDRSIZE (ssize_t)(sizeof(wd) - sizeof(wd.wd_we))
+/*
+ * this macro should be shared with ruptime.
+ */
+#define down(w,now) ((now) - (w)->wd_recvtime > 11 * 60)
+static DIR *dirp;
static struct whod wd;
-#define NUSERS 1000
+static int nusers;
static struct myutmp {
char myhost[sizeof(wd.wd_hostname)];
int myidle;
struct outmp myutmp;
} myutmp[NUSERS];
-static int nusers;
-
-#define WHDRSIZE (ssize_t)(sizeof (wd) - sizeof (wd.wd_we))
-/*
- * this macro should be shared with ruptime.
- */
-#define down(w,now) ((now) - (w)->wd_recvtime > 11 * 60)
static time_t now;
static int aflg;
@@ -88,17 +90,20 @@ main(int argc, char *argv[])
struct dirent *dp;
int width;
ssize_t cc;
- register struct whod *w = &wd;
- register struct whoent *we;
- register struct myutmp *mp;
+ struct whod *w;
+ struct whoent *we;
+ struct myutmp *mp;
int f, n, i;
int d_first;
+ int dfd;
+ time_t ct;
+ w = &wd;
(void) setlocale(LC_TIME, "");
d_first = (*nl_langinfo(D_MD_ORDER) == 'd');
- while ((ch = getopt(argc, argv, "a")) != -1)
- switch((char)ch) {
+ while ((ch = getopt(argc, argv, "a")) != -1) {
+ switch ((char)ch) {
case 'a':
aflg = 1;
break;
@@ -106,52 +111,73 @@ main(int argc, char *argv[])
default:
usage();
}
+ }
argc -= optind;
argv += optind;
if (argc != 0)
usage();
- if (chdir(_PATH_RWHODIR) || (dirp = opendir(".")) == NULL)
- err(1, "%s", _PATH_RWHODIR);
+ if (chdir(_PATH_RWHODIR) < 0)
+ err(1, "chdir(%s)", _PATH_RWHODIR);
+ if ((dirp = opendir(".")) == NULL)
+ err(1, "opendir(%s)", _PATH_RWHODIR);
+ dfd = dirfd(dirp);
mp = myutmp;
- (void)time(&now);
- while ((dp = readdir(dirp))) {
- if (dp->d_ino == 0 || strncmp(dp->d_name, "whod.", 5))
+ if (cap_rights_limit(dfd, CAP_READ | CAP_LOOKUP) < 0 && errno != ENOSYS)
+ err(1, "cap_rights_limit failed: %s", _PATH_RWHODIR);
+ /*
+ * Cache files required for time(3) and localtime(3) before entering
+ * capability mode.
+ */
+ (void) time(&ct);
+ (void) localtime(&ct);
+ if (cap_enter() < 0 && errno != ENOSYS)
+ err(1, "cap_enter");
+ (void) time(&now);
+ while ((dp = readdir(dirp)) != NULL) {
+ if (dp->d_ino == 0 || strncmp(dp->d_name, "whod.", 5) != 0)
continue;
- f = open(dp->d_name, O_RDONLY);
+ f = openat(dfd, dp->d_name, O_RDONLY);
if (f < 0)
continue;
- cc = read(f, (char *)&wd, sizeof (struct whod));
+ if (cap_rights_limit(f, CAP_READ) < 0 && errno != ENOSYS)
+ err(1, "cap_rights_limit failed: %s", dp->d_name);
+ cc = read(f, (char *)&wd, sizeof(struct whod));
if (cc < WHDRSIZE) {
(void) close(f);
continue;
}
- if (down(w,now)) {
+ if (down(w, now) != 0) {
(void) close(f);
continue;
}
cc -= WHDRSIZE;
we = w->wd_we;
- for (n = cc / sizeof (struct whoent); n > 0; n--) {
- if (aflg == 0 && we->we_idle >= 60*60) {
+ for (n = cc / sizeof(struct whoent); n > 0; n--) {
+ if (aflg == 0 && we->we_idle >= 60 * 60) {
we++;
continue;
}
if (nusers >= NUSERS)
errx(1, "too many users");
- mp->myutmp = we->we_utmp; mp->myidle = we->we_idle;
+ mp->myutmp = we->we_utmp;
+ mp->myidle = we->we_idle;
(void) strcpy(mp->myhost, w->wd_hostname);
- nusers++; we++; mp++;
+ nusers++;
+ we++;
+ mp++;
}
(void) close(f);
}
- qsort((char *)myutmp, nusers, sizeof (struct myutmp), utmpcmp);
+ qsort((char *)myutmp, nusers, sizeof(struct myutmp), utmpcmp);
mp = myutmp;
width = 0;
for (i = 0; i < nusers; i++) {
/* append one for the blank and use 8 for the out_line */
- int j = strlen(mp->myhost) + 1 + sizeof(mp->myutmp.out_line);
+ int j;
+
+ j = strlen(mp->myhost) + 1 + sizeof(mp->myutmp.out_line);
if (j > width)
width = j;
mp++;
@@ -159,31 +185,29 @@ main(int argc, char *argv[])
mp = myutmp;
for (i = 0; i < nusers; i++) {
char buf[BUFSIZ], cbuf[80];
- time_t t = _int_to_time(mp->myutmp.out_time);
+ time_t t;
- strftime(cbuf, sizeof(cbuf),
- d_first ? "%e %b %R" : "%b %e %R",
- localtime(&t));
- (void)sprintf(buf, "%s:%-.*s", mp->myhost,
- (int)sizeof(mp->myutmp.out_line), mp->myutmp.out_line);
+ t = _int_to_time(mp->myutmp.out_time);
+ strftime(cbuf, sizeof(cbuf), d_first ? "%e %b %R" : "%b %e %R",
+ localtime(&t));
+ (void) sprintf(buf, "%s:%-.*s", mp->myhost,
+ (int)sizeof(mp->myutmp.out_line), mp->myutmp.out_line);
printf("%-*.*s %-*s %s",
- (int)sizeof(mp->myutmp.out_name),
- (int)sizeof(mp->myutmp.out_name),
- mp->myutmp.out_name,
- width,
- buf,
- cbuf);
+ (int)sizeof(mp->myutmp.out_name),
+ (int)sizeof(mp->myutmp.out_name),
+ mp->myutmp.out_name, width, buf, cbuf);
mp->myidle /= 60;
- if (mp->myidle) {
- if (aflg) {
- if (mp->myidle >= 100*60)
- mp->myidle = 100*60 - 1;
+ if (mp->myidle != 0) {
+ if (aflg != 0) {
+ if (mp->myidle >= 100 * 60)
+ mp->myidle = 100 * 60 - 1;
if (mp->myidle >= 60)
printf(" %2d", mp->myidle / 60);
else
printf(" ");
- } else
+ } else {
printf(" ");
+ }
printf(":%02d", mp->myidle % 60);
}
printf("\n");
@@ -196,6 +220,7 @@ main(int argc, char *argv[])
static void
usage(void)
{
+
fprintf(stderr, "usage: rwho [-a]\n");
exit(1);
}
@@ -208,12 +233,12 @@ utmpcmp(const void *u1, const void *u2)
int rc;
rc = strncmp(MYUTMP(u1)->myutmp.out_name, MYUTMP(u2)->myutmp.out_name,
- sizeof(MYUTMP(u2)->myutmp.out_name));
- if (rc)
+ sizeof(MYUTMP(u2)->myutmp.out_name));
+ if (rc != 0)
return (rc);
rc = strcmp(MYUTMP(u1)->myhost, MYUTMP(u2)->myhost);
- if (rc)
+ if (rc != 0)
return (rc);
- return (strncmp(MYUTMP(u1)->myutmp.out_line, MYUTMP(u2)->myutmp.out_line,
- sizeof(MYUTMP(u2)->myutmp.out_line)));
+ return (strncmp(MYUTMP(u1)->myutmp.out_line,
+ MYUTMP(u2)->myutmp.out_line, sizeof(MYUTMP(u2)->myutmp.out_line)));
}
OpenPOWER on IntegriCloud