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