master xplshn/aruu / cmd / posix / who.c
 1/* See LICENSE file for copyright and license details. */
 2
 3
 4#include <stdio.h>
 5#include <stdlib.h>
 6#include <string.h>
 7#include <time.h>
 8#include <unistd.h>
 9#include <utmp.h>
10
11#include "config.h"
12#include "util.h"
13
14static void
15usage(void)
16{
17	eprintf("usage: %s [-ml]\n", argv0);
18}
19
20// ?man who: show logged in users
21// ?man display a list of users currently logged into the system
22int
23main(int argc, char *argv[])
24{
25	struct utmp usr;
26	FILE *ufp;
27	char timebuf[sizeof "yyyy-mm-dd hh:mm"];
28	char line_buf[sizeof(usr.ut_line) + 1];
29	char name_buf[sizeof(usr.ut_name) + 1];
30	char *tty, *ttmp;
31	int mflag = 0, lflag = 0;
32	time_t t;
33
34	ARGBEGIN {
35	// ?man -m: specify mode or limit
36	case 'm':
37		mflag = 1;
38		tty = ttyname(0);
39		if (!tty)
40			eprintf("ttyname: stdin:");
41		if ((ttmp = strrchr(tty, '/')))
42			tty = ttmp+1;
43		break;
44	// ?man -l: list in long format
45	case 'l':
46		lflag = 1;
47		break;
48	default:
49		usage();
50	} ARGEND;
51
52	if (argc > 0)
53		usage();
54
55	if (!(ufp = fopen(UTMP_PATH, "r")))
56		eprintf("fopen: %s:", UTMP_PATH);
57
58	while (fread(&usr, sizeof(usr), 1, ufp) == 1) {
59		memcpy(line_buf, usr.ut_line, sizeof(usr.ut_line));
60		line_buf[sizeof(usr.ut_line)] = '\0';
61		memcpy(name_buf, usr.ut_name, sizeof(usr.ut_name));
62		name_buf[sizeof(usr.ut_name)] = '\0';
63
64		if (!*name_buf || !*line_buf ||
65		    line_buf[0] == '~')
66			continue;
67		if (mflag != 0 && strcmp(line_buf, tty) != 0)
68			continue;
69		if (!!strcmp(name_buf, "LOGIN") == lflag)
70			continue;
71		t = usr.ut_time;
72		strftime(timebuf, sizeof timebuf, "%Y-%m-%d %H:%M", localtime(&t));
73		printf("%-8s %-12s %-16s\n", name_buf, line_buf, timebuf);
74	}
75	fclose(ufp);
76	return 0;
77}