clean up copyright notice
[unix-history] / usr / src / usr.bin / finger / finger.c
CommitLineData
22e155fc 1/*
6b8910b8 2 * Copyright (c) 1989 The Regents of the University of California.
a46f6f3d
KB
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms are permitted
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * advertising materials, and other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley. The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
6b8910b8 15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22e155fc
DF
16 */
17
18#ifndef lint
19char copyright[] =
6b8910b8 20"@(#) Copyright (c) 1989 The Regents of the University of California.\n\
22e155fc 21 All rights reserved.\n";
a46f6f3d 22#endif /* not lint */
22e155fc 23
840fc587 24#ifndef lint
6f3f7e2c 25static char sccsid[] = "@(#)finger.c 5.15 (Berkeley) %G%";
a46f6f3d 26#endif /* not lint */
2e61617d 27
f5ebcf9e 28/*
6b8910b8
KB
29 * Finger prints out information about users. It is not portable since
30 * certain fields (e.g. the full user name, office, and phone numbers) are
31 * extracted from the gecos field of the passwd file which other UNIXes
32 * may not have or may use for other things.
2e61617d 33 *
6b8910b8
KB
34 * There are currently two output formats; the short format is one line
35 * per user and displays login name, tty, login time, real name, idle time,
36 * and office location/phone number. The long format gives the same
37 * information (in a more legible format) as well as home directory, shell,
38 * mail info, and .plan/.project files.
2e61617d
BJ
39 */
40
6b8910b8
KB
41#include <sys/param.h>
42#include <sys/file.h>
c630b816 43#include <stdio.h>
6b8910b8 44#include "finger.h"
c630b816 45#include "pathnames.h"
f5ebcf9e 46
6b8910b8 47time_t now;
7619ff47 48int lflag, sflag, mflag, pplan;
6b8910b8 49char tbuf[1024];
f5ebcf9e
EW
50
51main(argc, argv)
52 int argc;
6b8910b8 53 char **argv;
2e61617d 54{
6b8910b8
KB
55 extern int optind;
56 int ch;
57 time_t time();
58
59 while ((ch = getopt(argc, argv, "lmps")) != EOF)
60 switch(ch) {
61 case 'l':
62 lflag = 1; /* long format */
63 break;
64 case 'm':
65 mflag = 1; /* force exact match of names */
66 break;
67 case 'p':
68 pplan = 1; /* don't show .plan/.project */
69 break;
70 case 's':
71 sflag = 1; /* short format */
72 break;
73 case '?':
74 default:
75 (void)fprintf(stderr,
76 "usage: finger [-lmps] [login ...]\n");
77 exit(1);
78 }
79 argc -= optind;
80 argv += optind;
81
82 (void)time(&now);
83 setpassent(1);
84 if (!*argv) {
85 /*
86 * Assign explicit "small" format if no names given and -l
87 * not selected. Force the -s BEFORE we get names so proper
88 * screening will be done.
89 */
90 if (!lflag)
91 sflag = 1; /* if -l not explicit, force -s */
92 loginlist();
7619ff47 93 if (entries == 0)
6b8910b8
KB
94 (void)printf("No one logged on.\n");
95 } else {
96 userlist(argv);
97 /*
98 * Assign explicit "large" format if names given and -s not
99 * explicitly stated. Force the -l AFTER we get names so any
100 * remote finger attempts specified won't be mishandled.
101 */
102 if (!sflag)
103 lflag = 1; /* if -s not explicit, force -l */
104 }
7619ff47 105 if (entries != 0) {
6b8910b8
KB
106 if (lflag)
107 lflag_print();
108 else
109 sflag_print();
110 }
f5ebcf9e
EW
111 exit(0);
112}
2e61617d 113
6b8910b8 114loginlist()
f5ebcf9e 115{
6b8910b8
KB
116 register PERSON *pn;
117 register int fd;
118 struct passwd *pw;
7619ff47
EW
119 struct utmp user;
120 char name[UT_NAMESIZE + 1];
f5ebcf9e 121
6b8910b8
KB
122 if ((fd = open(_PATH_UTMP, O_RDONLY, 0)) < 0) {
123 (void)fprintf(stderr, "finger: can't read %s.\n", _PATH_UTMP);
f5ebcf9e
EW
124 exit(2);
125 }
6b8910b8 126 name[UT_NAMESIZE] = NULL;
7619ff47 127 while (read(fd, (char *)&user, sizeof(user)) == sizeof(user)) {
6b8910b8
KB
128 if (!user.ut_name[0])
129 continue;
7619ff47
EW
130 if ((pn = find_person(user.ut_name)) == NULL) {
131 bcopy(user.ut_name, name, UT_NAMESIZE);
132 if ((pw = getpwnam(name)) == NULL)
133 continue;
134 pn = enter_person(pw);
2e61617d 135 }
7619ff47 136 enter_where(&user, pn);
f5ebcf9e 137 }
6b8910b8 138 (void)close(fd);
7619ff47
EW
139 for (pn = phead; lflag && pn != NULL; pn = pn->next)
140 enter_lastlog(pn);
f5ebcf9e
EW
141}
142
6b8910b8
KB
143#define ARGIGNORE (char *)0x01
144userlist(argv)
f5ebcf9e
EW
145 char **argv;
146{
7619ff47
EW
147 register char **ap;
148 register PERSON *pn;
149 PERSON *nethead;
150 struct utmp user;
151 struct passwd *pw;
152 int fd, dolocal, *index();
f5ebcf9e 153
6b8910b8 154 /* pull out all network requests */
7619ff47
EW
155 for (ap = argv, dolocal = 0, nethead = NULL; *ap != NULL; ap++) {
156 if (!index(*ap, '@')) {
6b8910b8 157 dolocal = 1;
f5ebcf9e 158 continue;
b474790b 159 }
7619ff47 160 pn = palloc();
6b8910b8
KB
161 pn->next = nethead;
162 nethead = pn;
7619ff47
EW
163 pn->name = *ap;
164 *ap = ARGIGNORE;
f5ebcf9e 165 }
6b8910b8
KB
166
167 if (!dolocal)
168 goto net;
169
f5ebcf9e 170 /*
6b8910b8 171 * traverse the list of possible login names and check the login name
7619ff47 172 * and real name against the name specified by the user.
f5ebcf9e 173 */
7619ff47
EW
174 if (mflag)
175 for (ap = argv; *ap != NULL; ap++) {
176 if (*ap == ARGIGNORE)
177 continue;
178 if ((pw = getpwnam(*ap)) == NULL)
179 continue;
180 enter_person(pw);
181 *ap = ARGIGNORE;
182 }
183 else while (pw = getpwent())
184 for (ap = argv; *ap != NULL; ap++) {
185 if (*ap == ARGIGNORE)
f5ebcf9e 186 continue;
7619ff47 187 if (strcasecmp(pw->pw_name, *ap) && !match(pw, *ap))
f5ebcf9e 188 continue;
7619ff47
EW
189 enter_person(pw);
190 *ap = ARGIGNORE;
6b8910b8 191 /* don't break, may be listed multiple times */
2e61617d 192 }
6b8910b8
KB
193
194 /* list errors */
7619ff47
EW
195 for (ap = argv; *ap != NULL; ap++)
196 if (*ap != ARGIGNORE)
6b8910b8 197 (void)fprintf(stderr,
7619ff47 198 "finger: %s: no such user.\n", *ap);
6b8910b8
KB
199
200 /* handle network requests */
201net: for (pn = nethead; pn; pn = pn->next) {
202 netfinger(pn->name);
203 if (pn->next || entries)
204 putchar('\n');
2e61617d
BJ
205 }
206
7619ff47 207 if (entries == 0)
6b8910b8 208 return;
f5ebcf9e
EW
209
210 /*
6b8910b8
KB
211 * Scan thru the list of users currently logged in, saving
212 * appropriate data whenever a match occurs.
f5ebcf9e 213 */
6b8910b8
KB
214 if ((fd = open(_PATH_UTMP, O_RDONLY, 0)) < 0) {
215 (void)fprintf( stderr, "finger: can't read %s.\n", _PATH_UTMP);
216 exit(1);
2e61617d 217 }
6b8910b8
KB
218 while (read(fd, (char *)&user, sizeof(user)) == sizeof(user)) {
219 if (!user.ut_name[0])
f5ebcf9e 220 continue;
7619ff47
EW
221 if ((pn = find_person(user.ut_name)) == NULL)
222 continue;
223 enter_where(&user, pn);
b474790b 224 }
6b8910b8 225 (void)close(fd);
7619ff47
EW
226 for (pn = phead; pn != NULL; pn = pn->next)
227 enter_lastlog(pn);
b474790b 228}