Commit | Line | Data |
---|---|---|
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 | |
19 | char 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 | 25 | static 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 | 47 | time_t now; |
7619ff47 | 48 | int lflag, sflag, mflag, pplan; |
6b8910b8 | 49 | char tbuf[1024]; |
f5ebcf9e EW |
50 | |
51 | main(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 | 114 | loginlist() |
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 |
144 | userlist(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 */ | |
201 | net: 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 | } |