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