diff options
Diffstat (limited to 'usr.bin/rwho/rwho.c')
-rw-r--r-- | usr.bin/rwho/rwho.c | 131 |
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))); } |