* Copyright (c) 1980, 1991, 1993, 1994
* The Regents of the University of California. All rights reserved.
* %sccs.include.redist.c%
static char copyright
[] =
"@(#) Copyright (c) 1980, 1991, 1993, 1994\n\
The Regents of the University of California. All rights reserved.\n";
static char sccsid
[] = "@(#)w.c 8.2 (Berkeley) %G%";
* w - print system status (who and what)
* This program is similar to the systat command on Tenex/Tops 10/20
time_t now
; /* the current time of day */
time_t uptime
; /* time of last reboot & elapsed time since */
int ttywidth
; /* width of tty */
int argwidth
; /* width of tty */
int header
= 1; /* true if -h flag: don't print heading */
int nflag
; /* true if -n flag: don't convert addrs */
int sortidle
; /* sort bu idle time */
char *sel_user
; /* login of particular user selected */
char domain
[MAXHOSTNAMELEN
];
* One of these per active utmp entry.
dev_t tdev
; /* dev_t of terminal */
time_t idle
; /* idle time of terminal in seconds */
struct kinfo_proc
*kp
; /* `most interesting' proc */
char *args
; /* arg list of interesting process */
} *ep
, *ehead
= NULL
, **nextp
= &ehead
;
static void pr_header
__P((time_t *, int));
static void usage
__P((int));
char *fmt_argv
__P((char **, char *, int)); /* ../../bin/ps/fmt.c */
int ch
, i
, nentries
, nusers
, wcmd
;
char *memf
, *nlistf
, *p
, *x
;
char buf
[MAXHOSTNAMELEN
], errbuf
[256];
/* Are we w(1) or uptime(1)? */
while ((ch
= getopt(argc
, argv
, p
)) != EOF
)
case 'f': case 'l': case 's': case 'u': case 'w':
warnx("[-flsuw] no longer supported");
if ((kd
= kvm_openfiles(nlistf
, memf
, NULL
, O_RDONLY
, errbuf
)) == NULL
)
if ((ut
= fopen(_PATH_UTMP
, "r")) == NULL
)
err(1, "%s", _PATH_UTMP
);
for (nusers
= 0; fread(&utmp
, sizeof(utmp
), 1, ut
);) {
if (utmp
.ut_name
[0] == '\0')
if (wcmd
== 0 || (sel_user
&&
strncmp(utmp
.ut_name
, sel_user
, UT_NAMESIZE
) != 0))
if ((ep
= calloc(1, sizeof(struct entry
))) == NULL
)
memmove(&(ep
->utmp
), &utmp
, sizeof(struct utmp
));
stp
= ttystat(ep
->utmp
.ut_line
);
* If this is the console device, attempt to ascertain
* the true console device dev_t.
(void) sysctl(mib
, 2, &ep
->tdev
, &size
, NULL
, 0);
if ((ep
->idle
= now
- stp
->st_atime
) < 0)
if (header
|| wcmd
== 0) {
#define HEADER "USER TTY FROM LOGIN@ IDLE WHAT\n"
#define WUSED (sizeof (HEADER) - sizeof ("WHAT\n"))
if ((kp
= kvm_getprocs(kd
, KERN_PROC_ALL
, 0, &nentries
)) == NULL
)
err(1, "%s", kvm_geterr(kd
));
for (i
= 0; i
< nentries
; i
++, kp
++) {
struct proc
*p
= &kp
->kp_proc
;
if (p
->p_stat
== SIDL
|| p
->p_stat
== SZOMB
)
for (ep
= ehead
; ep
!= NULL
; ep
= ep
->next
) {
if (ep
->tdev
== e
->e_tdev
&& e
->e_pgid
== e
->e_tpgid
) {
* Proc is in foreground of this terminal
if (proc_compare(&ep
->kp
->kp_proc
, p
))
if ((ioctl(STDOUT_FILENO
, TIOCGWINSZ
, &ws
) == -1 &&
ioctl(STDERR_FILENO
, TIOCGWINSZ
, &ws
) == -1 &&
ioctl(STDIN_FILENO
, TIOCGWINSZ
, &ws
) == -1) || ws
.ws_col
== 0)
ttywidth
= ws
.ws_col
- 1;
argwidth
= ttywidth
- WUSED
;
for (ep
= ehead
; ep
!= NULL
; ep
= ep
->next
) {
ep
->args
= fmt_argv(kvm_getargv(kd
, ep
->kp
, argwidth
),
ep
->kp
->kp_proc
.p_comm
, MAXCOMLEN
);
if (sortidle
&& ehead
!= NULL
) {
struct entry
*from
= ehead
, *save
;
(*nextp
) && from
->idle
>= (*nextp
)->idle
;
if (gethostname(domain
, sizeof(domain
) - 1) < 0 ||
(p
= strchr(domain
, '.')) == 0)
domain
[sizeof(domain
) - 1] = '\0';
memmove(domain
, p
, strlen(p
) + 1);
for (ep
= ehead
; ep
!= NULL
; ep
= ep
->next
) {
p
= *ep
->utmp
.ut_host
? ep
->utmp
.ut_host
: "-";
if (!nflag
&& isdigit(*p
) &&
(long)(l
= inet_addr(p
)) != -1 &&
(hp
= gethostbyaddr((char *)&l
, sizeof(l
), AF_INET
))) {
if (p
> hp
->h_name
&& strcmp(p
, domain
) == 0)
(void)snprintf(buf
, sizeof(buf
), "%s:%s", p
, x
);
(void)printf("%-*.*s %-2.2s %-*.*s ",
UT_NAMESIZE
, UT_NAMESIZE
, ep
->utmp
.ut_name
,
strncmp(ep
->utmp
.ut_line
, "tty", 3) ?
ep
->utmp
.ut_line
: ep
->utmp
.ut_line
+ 3,
UT_HOSTSIZE
, UT_HOSTSIZE
, *p
? p
: "-");
pr_attime(&ep
->utmp
.ut_time
, &now
);
(void)printf("%.*s\n", argwidth
, ep
->args
);
* Note, SCCS forces the string manipulation below, as it
* replaces w.c with file information.
(void)strftime(buf
,sizeof(buf
),__CONCAT("%l:%","M%p"),localtime(nowp
));
(void)printf("%s ", buf
);
* Print how long system has been up.
* (Found by looking getting "boottime" from the kernel)
if (sysctl(mib
, 2, &boottime
, &size
, NULL
, 0) != -1 &&
uptime
= now
- boottime
.tv_sec
;
days
= uptime
/ SECSPERDAY
;
hrs
= uptime
/ SECSPERHOUR
;
mins
= uptime
/ SECSPERMIN
;
(void)printf(" %d day%s,", days
, days
> 1 ? "s" : "");
(void)printf(" %2d:%02d,", hrs
, mins
);
(void)printf(" %d hr%s,",
hrs
, hrs
> 1 ? "s" : "");
(void)printf(" %d min%s,",
mins
, mins
> 1 ? "s" : "");
/* Print number of users logged in to system */
(void)printf(" %d user%s", nusers
, nusers
> 1 ? "s" : "");
* Print 1, 5, and 15 minute load averages.
if (getloadavg(avenrun
, sizeof(avenrun
) / sizeof(avenrun
[0])) == -1)
(void)printf(", no load average information available\n");
(void)printf(", load averages:");
for (i
= 0; i
< (sizeof(avenrun
) / sizeof(avenrun
[0])); i
++) {
(void)printf(" %.2f", avenrun
[i
]);
(void)snprintf(ttybuf
, sizeof(ttybuf
), "%s/%s", _PATH_DEV
, line
);
"usage: w: [-hin] [-M core] [-N system] [user]\n");
(void)fprintf(stderr
, "uptime\n");