date and time created 90/05/15 14:27:54 by marc
[unix-history] / usr / src / usr.bin / finger / finger.c
CommitLineData
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
19char 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 25static 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 47time_t now;
7619ff47 48int lflag, sflag, mflag, pplan;
6b8910b8 49char tbuf[1024];
f5ebcf9e
EW
50
51main(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 114loginlist()
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
141userlist(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 */
200net: 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}