xref: /original-bsd/usr.bin/who/who.c (revision a9a02843)
1 /*
2  * Copyright (c) 1989 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Michael Fischbein.
7  *
8  * Redistribution and use in source and binary forms are permitted
9  * provided that the above copyright notice and this paragraph are
10  * duplicated in all such forms and that any documentation,
11  * advertising materials, and other materials related to such
12  * distribution and use acknowledge that the software was developed
13  * by the University of California, Berkeley.  The name of the
14  * University may not be used to endorse or promote products derived
15  * from this software without specific prior written permission.
16  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19  */
20 
21 #ifndef lint
22 char copyright[] =
23 "@(#) Copyright (c) 1989 The Regents of the University of California.\n\
24  All rights reserved.\n";
25 #endif /* not lint */
26 
27 #ifndef lint
28 static char sccsid[] = "@(#)who.c	5.10 (Berkeley) 06/29/89";
29 #endif /* not lint */
30 
31 #include <sys/types.h>
32 #include <sys/file.h>
33 #include <sys/time.h>
34 #include <pwd.h>
35 #include <utmp.h>
36 #include <stdio.h>
37 
38 main(argc, argv)
39 	int argc;
40 	char **argv;
41 {
42 	register char *p;
43 	struct utmp usr;
44 	struct passwd *pw;
45 	FILE *ufp, *file();
46 	char *t, *rindex(), *strcpy(), *strncpy(), *ttyname();
47 	time_t time();
48 
49 	switch (argc) {
50 	case 1:					/* who */
51 		ufp = file(_PATH_UTMP);
52 		/* only entries with both name and line fields */
53 		while (fread((char *)&usr, sizeof(usr), 1, ufp) == 1)
54 			if (*usr.ut_name && *usr.ut_line)
55 				output(&usr);
56 		break;
57 	case 2:					/* who utmp_file */
58 		ufp = file(argv[1]);
59 		/* all entries */
60 		while (fread((char *)&usr, sizeof(usr), 1, ufp) == 1)
61 			output(&usr);
62 		break;
63 	case 3:					/* who am i */
64 		ufp = file(_PATH_UTMP);
65 
66 		/* search through the utmp and find an entry for this tty */
67 		if (p = ttyname(0)) {
68 			/* strip any directory component */
69 			if (t = rindex(p, '/'))
70 				p = t + 1;
71 			while (fread((char *)&usr, sizeof(usr), 1, ufp) == 1)
72 				if (usr.ut_name && !strcmp(usr.ut_line, p)) {
73 					output(&usr);
74 					exit(0);
75 				}
76 			/* well, at least we know what the tty is */
77 			(void)strncpy(usr.ut_line, p, UT_LINESIZE);
78 		} else
79 			(void)strcpy(usr.ut_line, "tty??");
80 		pw = getpwuid(getuid());
81 		(void)strncpy(usr.ut_name, pw ? pw->pw_name : "?", UT_NAMESIZE);
82 		(void)time(&usr.ut_time);
83 		*usr.ut_host = '\0';
84 		output(&usr);
85 		break;
86 	default:
87 		(void)fprintf(stderr, "usage: who [ file ]\n       who am i\n");
88 		exit(1);
89 	}
90 	exit(0);
91 }
92 
93 output(up)
94 	struct utmp *up;
95 {
96 	char *ctime();
97 
98 	(void)printf("%-*.*s %-*.*s", UT_NAMESIZE, UT_NAMESIZE, up->ut_name,
99 	    UT_LINESIZE, UT_LINESIZE, up->ut_line);
100 	(void)printf("%.12s", ctime(&up->ut_time) + 4);
101 	if (*up->ut_host)
102 		printf("\t(%.*s)", UT_HOSTSIZE, up->ut_host);
103 	(void)putchar('\n');
104 }
105 
106 FILE *
107 file(name)
108 	char *name;
109 {
110 	extern int errno;
111 	FILE *ufp;
112 	char *strerror();
113 
114 	if (!(ufp = fopen(name, "r"))) {
115 		(void)fprintf(stderr, "who: %s: %s.\n", name, strerror(errno));
116 		exit(1);
117 	}
118 	return(ufp);
119 }
120