Commit | Line | Data |
---|---|---|
22e155fc | 1 | /* |
6b8910b8 | 2 | * Copyright (c) 1989 The Regents of the University of California. |
a46f6f3d KB |
3 | * All rights reserved. |
4 | * | |
1c15e888 C |
5 | * This code is derived from software contributed to Berkeley by |
6 | * Tony Nardo of the Johns Hopkins University/Applied Physics Lab. | |
7 | * | |
af359dea C |
8 | * Redistribution and use in source and binary forms, with or without |
9 | * modification, are permitted provided that the following conditions | |
10 | * are met: | |
11 | * 1. Redistributions of source code must retain the above copyright | |
12 | * notice, this list of conditions and the following disclaimer. | |
13 | * 2. Redistributions in binary form must reproduce the above copyright | |
14 | * notice, this list of conditions and the following disclaimer in the | |
15 | * documentation and/or other materials provided with the distribution. | |
16 | * 3. All advertising materials mentioning features or use of this software | |
17 | * must display the following acknowledgement: | |
18 | * This product includes software developed by the University of | |
19 | * California, Berkeley and its contributors. | |
20 | * 4. Neither the name of the University nor the names of its contributors | |
21 | * may be used to endorse or promote products derived from this software | |
22 | * without specific prior written permission. | |
23 | * | |
24 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
25 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
26 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
27 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
28 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
29 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
30 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
31 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
32 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
33 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
34 | * SUCH DAMAGE. | |
22e155fc DF |
35 | */ |
36 | ||
37 | #ifndef lint | |
38 | char copyright[] = | |
6b8910b8 | 39 | "@(#) Copyright (c) 1989 The Regents of the University of California.\n\ |
22e155fc | 40 | All rights reserved.\n"; |
a46f6f3d | 41 | #endif /* not lint */ |
22e155fc | 42 | |
840fc587 | 43 | #ifndef lint |
af359dea | 44 | static char sccsid[] = "@(#)finger.c 5.22 (Berkeley) 6/29/90"; |
a46f6f3d | 45 | #endif /* not lint */ |
2e61617d | 46 | |
f5ebcf9e | 47 | /* |
6b8910b8 KB |
48 | * Finger prints out information about users. It is not portable since |
49 | * certain fields (e.g. the full user name, office, and phone numbers) are | |
50 | * extracted from the gecos field of the passwd file which other UNIXes | |
51 | * may not have or may use for other things. | |
2e61617d | 52 | * |
6b8910b8 KB |
53 | * There are currently two output formats; the short format is one line |
54 | * per user and displays login name, tty, login time, real name, idle time, | |
55 | * and office location/phone number. The long format gives the same | |
56 | * information (in a more legible format) as well as home directory, shell, | |
57 | * mail info, and .plan/.project files. | |
2e61617d BJ |
58 | */ |
59 | ||
6b8910b8 KB |
60 | #include <sys/param.h> |
61 | #include <sys/file.h> | |
c630b816 | 62 | #include <stdio.h> |
6b8910b8 | 63 | #include "finger.h" |
f5ebcf9e | 64 | |
6b8910b8 | 65 | time_t now; |
7619ff47 | 66 | int lflag, sflag, mflag, pplan; |
6b8910b8 | 67 | char tbuf[1024]; |
f5ebcf9e EW |
68 | |
69 | main(argc, argv) | |
70 | int argc; | |
6b8910b8 | 71 | char **argv; |
2e61617d | 72 | { |
6b8910b8 KB |
73 | extern int optind; |
74 | int ch; | |
75 | time_t time(); | |
76 | ||
77 | while ((ch = getopt(argc, argv, "lmps")) != EOF) | |
78 | switch(ch) { | |
79 | case 'l': | |
80 | lflag = 1; /* long format */ | |
81 | break; | |
82 | case 'm': | |
83 | mflag = 1; /* force exact match of names */ | |
84 | break; | |
85 | case 'p': | |
86 | pplan = 1; /* don't show .plan/.project */ | |
87 | break; | |
88 | case 's': | |
89 | sflag = 1; /* short format */ | |
90 | break; | |
91 | case '?': | |
92 | default: | |
93 | (void)fprintf(stderr, | |
94 | "usage: finger [-lmps] [login ...]\n"); | |
95 | exit(1); | |
96 | } | |
97 | argc -= optind; | |
98 | argv += optind; | |
99 | ||
100 | (void)time(&now); | |
101 | setpassent(1); | |
102 | if (!*argv) { | |
103 | /* | |
104 | * Assign explicit "small" format if no names given and -l | |
105 | * not selected. Force the -s BEFORE we get names so proper | |
106 | * screening will be done. | |
107 | */ | |
108 | if (!lflag) | |
109 | sflag = 1; /* if -l not explicit, force -s */ | |
110 | loginlist(); | |
7619ff47 | 111 | if (entries == 0) |
6b8910b8 KB |
112 | (void)printf("No one logged on.\n"); |
113 | } else { | |
a141c001 | 114 | userlist(argc, argv); |
6b8910b8 KB |
115 | /* |
116 | * Assign explicit "large" format if names given and -s not | |
117 | * explicitly stated. Force the -l AFTER we get names so any | |
118 | * remote finger attempts specified won't be mishandled. | |
119 | */ | |
120 | if (!sflag) | |
121 | lflag = 1; /* if -s not explicit, force -l */ | |
122 | } | |
7619ff47 | 123 | if (entries != 0) { |
6b8910b8 KB |
124 | if (lflag) |
125 | lflag_print(); | |
126 | else | |
127 | sflag_print(); | |
128 | } | |
f5ebcf9e EW |
129 | exit(0); |
130 | } | |
2e61617d | 131 | |
6b8910b8 | 132 | loginlist() |
f5ebcf9e | 133 | { |
6b8910b8 | 134 | register PERSON *pn; |
6b8910b8 | 135 | struct passwd *pw; |
7619ff47 EW |
136 | struct utmp user; |
137 | char name[UT_NAMESIZE + 1]; | |
f5ebcf9e | 138 | |
d65ceee1 | 139 | if (!freopen(_PATH_UTMP, "r", stdin)) { |
6b8910b8 | 140 | (void)fprintf(stderr, "finger: can't read %s.\n", _PATH_UTMP); |
f5ebcf9e EW |
141 | exit(2); |
142 | } | |
6b8910b8 | 143 | name[UT_NAMESIZE] = NULL; |
d65ceee1 | 144 | while (fread((char *)&user, sizeof(user), 1, stdin) == 1) { |
6b8910b8 KB |
145 | if (!user.ut_name[0]) |
146 | continue; | |
7619ff47 EW |
147 | if ((pn = find_person(user.ut_name)) == NULL) { |
148 | bcopy(user.ut_name, name, UT_NAMESIZE); | |
149 | if ((pw = getpwnam(name)) == NULL) | |
150 | continue; | |
151 | pn = enter_person(pw); | |
2e61617d | 152 | } |
7619ff47 | 153 | enter_where(&user, pn); |
f5ebcf9e | 154 | } |
7619ff47 EW |
155 | for (pn = phead; lflag && pn != NULL; pn = pn->next) |
156 | enter_lastlog(pn); | |
f5ebcf9e EW |
157 | } |
158 | ||
a141c001 EW |
159 | userlist(argc, argv) |
160 | register argc; | |
161 | register char **argv; | |
f5ebcf9e | 162 | { |
a141c001 | 163 | register i; |
7619ff47 | 164 | register PERSON *pn; |
a8adf1f5 | 165 | PERSON *nethead, **nettail; |
7619ff47 EW |
166 | struct utmp user; |
167 | struct passwd *pw; | |
a141c001 | 168 | int dolocal, *used; |
a141c001 EW |
169 | char *index(); |
170 | ||
171 | if (!(used = (int *)calloc((u_int)argc, (u_int)sizeof(int)))) { | |
172 | (void)fprintf(stderr, "finger: out of space.\n"); | |
173 | exit(1); | |
174 | } | |
f5ebcf9e | 175 | |
6b8910b8 | 176 | /* pull out all network requests */ |
a8adf1f5 | 177 | for (i = 0, dolocal = 0, nettail = &nethead; i < argc; i++) { |
a141c001 | 178 | if (!index(argv[i], '@')) { |
6b8910b8 | 179 | dolocal = 1; |
f5ebcf9e | 180 | continue; |
b474790b | 181 | } |
7619ff47 | 182 | pn = palloc(); |
a8adf1f5 EW |
183 | *nettail = pn; |
184 | nettail = &pn->next; | |
a141c001 EW |
185 | pn->name = argv[i]; |
186 | used[i] = -1; | |
f5ebcf9e | 187 | } |
a8adf1f5 | 188 | *nettail = NULL; |
6b8910b8 KB |
189 | |
190 | if (!dolocal) | |
191 | goto net; | |
192 | ||
f5ebcf9e | 193 | /* |
6b8910b8 | 194 | * traverse the list of possible login names and check the login name |
7619ff47 | 195 | * and real name against the name specified by the user. |
f5ebcf9e | 196 | */ |
d223fc79 | 197 | if (mflag) { |
a141c001 EW |
198 | for (i = 0; i < argc; i++) |
199 | if (used[i] >= 0 && (pw = getpwnam(argv[i]))) { | |
d223fc79 | 200 | enter_person(pw); |
a141c001 | 201 | used[i] = 1; |
d223fc79 KB |
202 | } |
203 | } else while (pw = getpwent()) | |
a141c001 EW |
204 | for (i = 0; i < argc; i++) |
205 | if (used[i] >= 0 && | |
206 | (!strcasecmp(pw->pw_name, argv[i]) || | |
207 | match(pw, argv[i]))) { | |
d223fc79 | 208 | enter_person(pw); |
a141c001 | 209 | used[i] = 1; |
d223fc79 | 210 | } |
6b8910b8 KB |
211 | |
212 | /* list errors */ | |
a141c001 EW |
213 | for (i = 0; i < argc; i++) |
214 | if (!used[i]) | |
6b8910b8 | 215 | (void)fprintf(stderr, |
a141c001 | 216 | "finger: %s: no such user.\n", argv[i]); |
6b8910b8 KB |
217 | |
218 | /* handle network requests */ | |
219 | net: for (pn = nethead; pn; pn = pn->next) { | |
220 | netfinger(pn->name); | |
221 | if (pn->next || entries) | |
222 | putchar('\n'); | |
2e61617d BJ |
223 | } |
224 | ||
7619ff47 | 225 | if (entries == 0) |
6b8910b8 | 226 | return; |
f5ebcf9e EW |
227 | |
228 | /* | |
6b8910b8 KB |
229 | * Scan thru the list of users currently logged in, saving |
230 | * appropriate data whenever a match occurs. | |
f5ebcf9e | 231 | */ |
d65ceee1 | 232 | if (!freopen(_PATH_UTMP, "r", stdin)) { |
6b8910b8 KB |
233 | (void)fprintf( stderr, "finger: can't read %s.\n", _PATH_UTMP); |
234 | exit(1); | |
2e61617d | 235 | } |
d65ceee1 | 236 | while (fread((char *)&user, sizeof(user), 1, stdin) == 1) { |
6b8910b8 | 237 | if (!user.ut_name[0]) |
f5ebcf9e | 238 | continue; |
7619ff47 EW |
239 | if ((pn = find_person(user.ut_name)) == NULL) |
240 | continue; | |
241 | enter_where(&user, pn); | |
b474790b | 242 | } |
7619ff47 EW |
243 | for (pn = phead; pn != NULL; pn = pn->next) |
244 | enter_lastlog(pn); | |
b474790b | 245 | } |