int main(int argc, char *argv[]) { int ch; struct dirent *dp; int width; ssize_t cc; register struct whod *w = &wd; register struct whoent *we; register struct myutmp *mp; int f, n, i; int d_first; (void) setlocale(LC_TIME, ""); d_first = (*nl_langinfo(D_MD_ORDER) == 'd'); while ((ch = getopt(argc, argv, "a")) != -1) switch((char)ch) { case 'a': aflg = 1; break; case '?': default: usage(); } argc -= optind; argv += optind; if (argc != 0) usage(); if (chdir(_PATH_RWHODIR) || (dirp = opendir(".")) == NULL) err(1, "%s", _PATH_RWHODIR); mp = myutmp; (void)time(&now); while ((dp = readdir(dirp))) { if (dp->d_ino == 0 || strncmp(dp->d_name, "whod.", 5)) continue; f = open(dp->d_name, O_RDONLY); if (f < 0) continue; cc = read(f, (char *)&wd, sizeof (struct whod)); if (cc < WHDRSIZE) { (void) close(f); continue; } if (down(w,now)) { (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) { we++; continue; } if (nusers >= NUSERS) errx(1, "too many users"); mp->myutmp = we->we_utmp; mp->myidle = we->we_idle; (void) strcpy(mp->myhost, w->wd_hostname); nusers++; we++; mp++; } (void) close(f); } 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); if (j > width) width = j; mp++; } mp = myutmp; for (i = 0; i < nusers; i++) { char buf[BUFSIZ], cbuf[80]; time_t 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); mp->myidle /= 60; if (mp->myidle) { if (aflg) { if (mp->myidle >= 100*60) mp->myidle = 100*60 - 1; if (mp->myidle >= 60) printf(" %2d", mp->myidle / 60); else printf(" "); } else printf(" "); printf(":%02d", mp->myidle % 60); } printf("\n"); mp++; } exit(0); }
int main(int argc, char *argv[]) { int ch; struct dirent *dp; int width; ssize_t cc; struct whod *w; struct whoent *we; struct myutmp *mp; cap_rights_t rights; 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) { case 'a': aflg = 1; break; case '?': default: usage(); } } argc -= optind; argv += optind; if (argc != 0) usage(); 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; cap_rights_init(&rights, CAP_READ, CAP_LOOKUP); if (cap_rights_limit(dfd, &rights) < 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); cap_rights_init(&rights, CAP_READ); while ((dp = readdir(dirp)) != NULL) { if (dp->d_ino == 0 || strncmp(dp->d_name, "whod.", 5) != 0) continue; f = openat(dfd, dp->d_name, O_RDONLY); if (f < 0) continue; if (cap_rights_limit(f, &rights) < 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) != 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) { we++; continue; } if (nusers >= NUSERS) errx(1, "too many users"); mp->myutmp = we->we_utmp; mp->myidle = we->we_idle; (void) strcpy(mp->myhost, w->wd_hostname); nusers++; we++; mp++; } (void) close(f); } 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; j = strlen(mp->myhost) + 1 + sizeof(mp->myutmp.out_line); if (j > width) width = j; mp++; } mp = myutmp; for (i = 0; i < nusers; i++) { char buf[BUFSIZ], cbuf[80]; time_t t; 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); mp->myidle /= 60; 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 { printf(" "); } printf(":%02d", mp->myidle % 60); } printf("\n"); mp++; } exit(0); }
static int rusers_reply(caddr_t replyp, struct sockaddr_in *raddrp) { u_int x; int idle; char date[32], idle_time[64], remote[64]; struct hostent *hp; utmpidlearr *up, u; char *host; int days, hours, minutes, seconds; up = &u; memcpy(up, replyp, sizeof(*up)); if (search_host(raddrp->sin_addr)) return (0); if (!allopt && up->utmpidlearr_len == 0) return (0); hp = gethostbyaddr((char *)&raddrp->sin_addr.s_addr, sizeof(struct in_addr), AF_INET); if (hp != NULL) host = hp->h_name; else host = inet_ntoa(raddrp->sin_addr); if (!longopt) printf("%-*s ", HOST_WIDTH, host); for (x = 0; x < up->utmpidlearr_len; x++) { time_t t = _int_to_time(up->utmpidlearr_val[x].ui_utmp.ut_time); strncpy(date, &(ctime(&t)[4]), sizeof(date) - 1); idle = up->utmpidlearr_val[x].ui_idle; sprintf(idle_time, " :%02d", idle); if (idle == MAX_INT) strcpy(idle_time, "??"); else if (idle == 0) strcpy(idle_time, ""); else { seconds = idle; days = seconds / (60 * 60 * 24); seconds %= (60 * 60 * 24); hours = seconds / (60 * 60); seconds %= (60 * 60); minutes = seconds / 60; seconds %= 60; if (idle > 60) sprintf(idle_time, "%d:%02d", minutes, seconds); if (idle >= (60 * 60)) sprintf(idle_time, "%d:%02d:%02d", hours, minutes, seconds); if (idle >= (24 * 60 * 60)) sprintf(idle_time, "%d days, %d:%02d:%02d", days, hours, minutes, seconds); } strncpy(remote, up->utmpidlearr_val[x].ui_utmp.ut_host, sizeof(remote) - 1); if (strlen(remote) != 0) sprintf(remote, "(%.16s)", up->utmpidlearr_val[x].ui_utmp.ut_host); if (longopt) printf("%-8.8s %*s:%-*.*s %-12.12s %6s %.18s\n", up->utmpidlearr_val[x].ui_utmp.ut_name, HOST_WIDTH, host, LINE_WIDTH, LINE_WIDTH, up->utmpidlearr_val[x].ui_utmp.ut_line, date, idle_time, remote ); else printf("%s ", up->utmpidlearr_val[x].ui_utmp.ut_name); } if (!longopt) putchar('\n'); remember_host(raddrp->sin_addr); return (0); }