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 |
16c61828 | 25 | static char sccsid[] = "@(#)finger.c 5.19 (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 { | |
a141c001 | 96 | userlist(argc, argv); |
6b8910b8 KB |
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 | 116 | register PERSON *pn; |
6b8910b8 | 117 | struct passwd *pw; |
7619ff47 EW |
118 | struct utmp user; |
119 | char name[UT_NAMESIZE + 1]; | |
f5ebcf9e | 120 | |
d65ceee1 | 121 | if (!freopen(_PATH_UTMP, "r", stdin)) { |
6b8910b8 | 122 | (void)fprintf(stderr, "finger: can't read %s.\n", _PATH_UTMP); |
f5ebcf9e EW |
123 | exit(2); |
124 | } | |
6b8910b8 | 125 | name[UT_NAMESIZE] = NULL; |
d65ceee1 | 126 | while (fread((char *)&user, sizeof(user), 1, stdin) == 1) { |
6b8910b8 KB |
127 | if (!user.ut_name[0]) |
128 | continue; | |
7619ff47 EW |
129 | if ((pn = find_person(user.ut_name)) == NULL) { |
130 | bcopy(user.ut_name, name, UT_NAMESIZE); | |
131 | if ((pw = getpwnam(name)) == NULL) | |
132 | continue; | |
133 | pn = enter_person(pw); | |
2e61617d | 134 | } |
7619ff47 | 135 | enter_where(&user, pn); |
f5ebcf9e | 136 | } |
7619ff47 EW |
137 | for (pn = phead; lflag && pn != NULL; pn = pn->next) |
138 | enter_lastlog(pn); | |
f5ebcf9e EW |
139 | } |
140 | ||
a141c001 EW |
141 | userlist(argc, argv) |
142 | register argc; | |
143 | register char **argv; | |
f5ebcf9e | 144 | { |
a141c001 | 145 | register i; |
7619ff47 EW |
146 | register PERSON *pn; |
147 | PERSON *nethead; | |
148 | struct utmp user; | |
149 | struct passwd *pw; | |
a141c001 | 150 | int dolocal, *used; |
a141c001 EW |
151 | char *index(); |
152 | ||
153 | if (!(used = (int *)calloc((u_int)argc, (u_int)sizeof(int)))) { | |
154 | (void)fprintf(stderr, "finger: out of space.\n"); | |
155 | exit(1); | |
156 | } | |
f5ebcf9e | 157 | |
6b8910b8 | 158 | /* pull out all network requests */ |
a141c001 EW |
159 | for (i = 0, dolocal = 0, nethead = NULL; i < argc; i++) { |
160 | if (!index(argv[i], '@')) { | |
6b8910b8 | 161 | dolocal = 1; |
f5ebcf9e | 162 | continue; |
b474790b | 163 | } |
7619ff47 | 164 | pn = palloc(); |
6b8910b8 KB |
165 | pn->next = nethead; |
166 | nethead = pn; | |
a141c001 EW |
167 | pn->name = argv[i]; |
168 | used[i] = -1; | |
f5ebcf9e | 169 | } |
6b8910b8 KB |
170 | |
171 | if (!dolocal) | |
172 | goto net; | |
173 | ||
f5ebcf9e | 174 | /* |
6b8910b8 | 175 | * traverse the list of possible login names and check the login name |
7619ff47 | 176 | * and real name against the name specified by the user. |
f5ebcf9e | 177 | */ |
d223fc79 | 178 | if (mflag) { |
a141c001 EW |
179 | for (i = 0; i < argc; i++) |
180 | if (used[i] >= 0 && (pw = getpwnam(argv[i]))) { | |
d223fc79 | 181 | enter_person(pw); |
a141c001 | 182 | used[i] = 1; |
d223fc79 KB |
183 | } |
184 | } else while (pw = getpwent()) | |
a141c001 EW |
185 | for (i = 0; i < argc; i++) |
186 | if (used[i] >= 0 && | |
187 | (!strcasecmp(pw->pw_name, argv[i]) || | |
188 | match(pw, argv[i]))) { | |
d223fc79 | 189 | enter_person(pw); |
a141c001 | 190 | used[i] = 1; |
d223fc79 | 191 | } |
6b8910b8 KB |
192 | |
193 | /* list errors */ | |
a141c001 EW |
194 | for (i = 0; i < argc; i++) |
195 | if (!used[i]) | |
6b8910b8 | 196 | (void)fprintf(stderr, |
a141c001 | 197 | "finger: %s: no such user.\n", argv[i]); |
6b8910b8 KB |
198 | |
199 | /* handle network requests */ | |
200 | net: for (pn = nethead; pn; pn = pn->next) { | |
201 | netfinger(pn->name); | |
202 | if (pn->next || entries) | |
203 | putchar('\n'); | |
2e61617d BJ |
204 | } |
205 | ||
7619ff47 | 206 | if (entries == 0) |
6b8910b8 | 207 | return; |
f5ebcf9e EW |
208 | |
209 | /* | |
6b8910b8 KB |
210 | * Scan thru the list of users currently logged in, saving |
211 | * appropriate data whenever a match occurs. | |
f5ebcf9e | 212 | */ |
d65ceee1 | 213 | if (!freopen(_PATH_UTMP, "r", stdin)) { |
6b8910b8 KB |
214 | (void)fprintf( stderr, "finger: can't read %s.\n", _PATH_UTMP); |
215 | exit(1); | |
2e61617d | 216 | } |
d65ceee1 | 217 | while (fread((char *)&user, sizeof(user), 1, stdin) == 1) { |
6b8910b8 | 218 | if (!user.ut_name[0]) |
f5ebcf9e | 219 | continue; |
7619ff47 EW |
220 | if ((pn = find_person(user.ut_name)) == NULL) |
221 | continue; | |
222 | enter_where(&user, pn); | |
b474790b | 223 | } |
7619ff47 EW |
224 | for (pn = phead; pn != NULL; pn = pn->next) |
225 | enter_lastlog(pn); | |
b474790b | 226 | } |