Annotation of src/usr.bin/finger/finger.c, Revision 1.3
1.3 ! deraadt 1: /* $OpenBSD: finger.c,v 1.2 1996/06/26 05:33:16 deraadt Exp $ */
1.2 deraadt 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.3 ! deraadt 51: static char rcsid[] = "$OpenBSD: finger.c,v 1.2 1996/06/26 05:33:16 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:
1.3 ! deraadt 77: int loginlist __P((void));
! 78: void userlist __P((int, char **));
! 79:
! 80: int
1.1 deraadt 81: main(argc, argv)
82: int argc;
83: char **argv;
84: {
85: extern int optind;
86: int ch;
87: time_t time();
88:
89: while ((ch = getopt(argc, argv, "lmps")) != EOF)
90: switch(ch) {
91: case 'l':
92: lflag = 1; /* long format */
93: break;
94: case 'm':
95: mflag = 1; /* force exact match of names */
96: break;
97: case 'p':
98: pplan = 1; /* don't show .plan/.project */
99: break;
100: case 's':
101: sflag = 1; /* short format */
102: break;
103: case '?':
104: default:
105: (void)fprintf(stderr,
106: "usage: finger [-lmps] [login ...]\n");
107: exit(1);
108: }
109: argc -= optind;
110: argv += optind;
111:
112: (void)time(&now);
113: setpassent(1);
114: if (!*argv) {
115: /*
116: * Assign explicit "small" format if no names given and -l
117: * not selected. Force the -s BEFORE we get names so proper
118: * screening will be done.
119: */
120: if (!lflag)
121: sflag = 1; /* if -l not explicit, force -s */
122: loginlist();
123: if (entries == 0)
124: (void)printf("No one logged on.\n");
125: } else {
126: userlist(argc, argv);
127: /*
128: * Assign explicit "large" format if names given and -s not
129: * explicitly stated. Force the -l AFTER we get names so any
130: * remote finger attempts specified won't be mishandled.
131: */
132: if (!sflag)
133: lflag = 1; /* if -s not explicit, force -l */
134: }
135: if (entries != 0) {
136: if (lflag)
137: lflag_print();
138: else
139: sflag_print();
140: }
141: exit(0);
142: }
143:
1.3 ! deraadt 144: int
1.1 deraadt 145: loginlist()
146: {
147: register PERSON *pn;
148: struct passwd *pw;
149: struct utmp user;
150: char name[UT_NAMESIZE + 1];
151:
152: if (!freopen(_PATH_UTMP, "r", stdin)) {
153: (void)fprintf(stderr, "finger: can't read %s.\n", _PATH_UTMP);
154: exit(2);
155: }
156: name[UT_NAMESIZE] = NULL;
157: while (fread((char *)&user, sizeof(user), 1, stdin) == 1) {
158: if (!user.ut_name[0])
159: continue;
160: if ((pn = find_person(user.ut_name)) == NULL) {
161: bcopy(user.ut_name, name, UT_NAMESIZE);
162: if ((pw = getpwnam(name)) == NULL)
163: continue;
164: pn = enter_person(pw);
165: }
166: enter_where(&user, pn);
167: }
168: for (pn = phead; lflag && pn != NULL; pn = pn->next)
169: enter_lastlog(pn);
170: }
171:
1.3 ! deraadt 172: void
1.1 deraadt 173: userlist(argc, argv)
174: register argc;
175: register char **argv;
176: {
177: register i;
178: register PERSON *pn;
179: PERSON *nethead, **nettail;
180: struct utmp user;
181: struct passwd *pw;
182: int dolocal, *used;
183: char *index();
184:
185: if (!(used = (int *)calloc((u_int)argc, (u_int)sizeof(int)))) {
186: (void)fprintf(stderr, "finger: out of space.\n");
187: exit(1);
188: }
189:
190: /* pull out all network requests */
191: for (i = 0, dolocal = 0, nettail = &nethead; i < argc; i++) {
192: if (!index(argv[i], '@')) {
193: dolocal = 1;
194: continue;
195: }
196: pn = palloc();
197: *nettail = pn;
198: nettail = &pn->next;
199: pn->name = argv[i];
200: used[i] = -1;
201: }
202: *nettail = NULL;
203:
204: if (!dolocal)
205: goto net;
206:
207: /*
208: * traverse the list of possible login names and check the login name
209: * and real name against the name specified by the user.
210: */
211: if (mflag) {
212: for (i = 0; i < argc; i++)
213: if (used[i] >= 0 && (pw = getpwnam(argv[i]))) {
214: enter_person(pw);
215: used[i] = 1;
216: }
217: } else while (pw = getpwent())
218: for (i = 0; i < argc; i++)
219: if (used[i] >= 0 &&
220: (!strcasecmp(pw->pw_name, argv[i]) ||
221: match(pw, argv[i]))) {
222: enter_person(pw);
223: used[i] = 1;
224: }
225:
226: /* list errors */
227: for (i = 0; i < argc; i++)
228: if (!used[i])
229: (void)fprintf(stderr,
230: "finger: %s: no such user.\n", argv[i]);
231:
232: /* handle network requests */
233: net: for (pn = nethead; pn; pn = pn->next) {
234: netfinger(pn->name);
235: if (pn->next || entries)
236: putchar('\n');
237: }
238:
239: if (entries == 0)
240: return;
241:
242: /*
243: * Scan thru the list of users currently logged in, saving
244: * appropriate data whenever a match occurs.
245: */
246: if (!freopen(_PATH_UTMP, "r", stdin)) {
247: (void)fprintf( stderr, "finger: can't read %s.\n", _PATH_UTMP);
248: exit(1);
249: }
250: while (fread((char *)&user, sizeof(user), 1, stdin) == 1) {
251: if (!user.ut_name[0])
252: continue;
253: if ((pn = find_person(user.ut_name)) == NULL)
254: continue;
255: enter_where(&user, pn);
256: }
257: for (pn = phead; pn != NULL; pn = pn->next)
258: enter_lastlog(pn);
259: }