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, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37 #ifndef lint
38 static char sccsid[] = "@(#)lprint.c 5.13 (Berkeley) 10/31/90";
39 #endif /* not lint */
40
41 #include <sys/types.h>
42 #include <sys/file.h>
43 #include <sys/stat.h>
44 #include <sys/time.h>
45 #include <tzfile.h>
46 #include <stdio.h>
47 #include <ctype.h>
48 #include <paths.h>
49 #include "finger.h"
50
51 #define LINE_LEN 80
52 #define TAB_LEN 8 /* 8 spaces between tabs */
53 #define _PATH_PLAN ".plan"
54 #define _PATH_PROJECT ".project"
55
lflag_print()56 lflag_print()
57 {
58 extern int pplan;
59 register PERSON *pn;
60
61 for (pn = phead;;) {
62 lprint(pn);
63 if (!pplan) {
64 (void)show_text(pn->dir, _PATH_PROJECT, "Project:");
65 if (!show_text(pn->dir, _PATH_PLAN, "Plan:"))
66 (void)printf("No Plan.\n");
67 }
68 if (!(pn = pn->next))
69 break;
70 putchar('\n');
71 }
72 }
73
lprint(pn)74 lprint(pn)
75 register PERSON *pn;
76 {
77 extern time_t now;
78 register struct tm *delta;
79 register WHERE *w;
80 register int cpr, len, maxlen;
81 struct tm *tp;
82 int oddfield;
83 time_t time();
84 char *t, *tzn, *prphone();
85
86 /*
87 * long format --
88 * login name
89 * real name
90 * home directory
91 * shell
92 * office, office phone, home phone if available
93 */
94 (void)printf("Login: %-15s\t\t\tName: %s\nDirectory: %-25s",
95 pn->name, pn->realname, pn->dir);
96 (void)printf("\tShell: %-s\n", *pn->shell ? pn->shell : _PATH_BSHELL);
97
98 /*
99 * try and print office, office phone, and home phone on one line;
100 * if that fails, do line filling so it looks nice.
101 */
102 #define OFFICE_TAG "Office"
103 #define OFFICE_PHONE_TAG "Office Phone"
104 oddfield = 0;
105 if (pn->office && pn->officephone &&
106 strlen(pn->office) + strlen(pn->officephone) +
107 sizeof(OFFICE_TAG) + 2 <= 5 * TAB_LEN) {
108 (void)sprintf(tbuf, "%s: %s, %s", OFFICE_TAG, pn->office,
109 prphone(pn->officephone));
110 oddfield = demi_print(tbuf, oddfield);
111 } else {
112 if (pn->office) {
113 (void)sprintf(tbuf, "%s: %s", OFFICE_TAG, pn->office);
114 oddfield = demi_print(tbuf, oddfield);
115 }
116 if (pn->officephone) {
117 (void)sprintf(tbuf, "%s: %s", OFFICE_PHONE_TAG,
118 prphone(pn->officephone));
119 oddfield = demi_print(tbuf, oddfield);
120 }
121 }
122 if (pn->homephone) {
123 (void)sprintf(tbuf, "%s: %s", "Home Phone",
124 prphone(pn->homephone));
125 oddfield = demi_print(tbuf, oddfield);
126 }
127 if (oddfield)
128 putchar('\n');
129
130 /*
131 * long format con't: * if logged in
132 * terminal
133 * idle time
134 * if messages allowed
135 * where logged in from
136 * if not logged in
137 * when last logged in
138 */
139 /* find out longest device name for this user for formatting */
140 for (w = pn->whead, maxlen = -1; w != NULL; w = w->next)
141 if ((len = strlen(w->tty)) > maxlen)
142 maxlen = len;
143 /* find rest of entries for user */
144 for (w = pn->whead; w != NULL; w = w->next) {
145 switch (w->info) {
146 case LOGGEDIN:
147 tp = localtime(&w->loginat);
148 t = asctime(tp);
149 tzn = tp->tm_zone;
150 cpr = printf("On since %.16s (%s) on %s",
151 t, tzn, w->tty);
152 /*
153 * idle time is tough; if have one, print a comma,
154 * then spaces to pad out the device name, then the
155 * idle time. Follow with a comma if a remote login.
156 */
157 delta = gmtime(&w->idletime);
158 if (delta->tm_yday || delta->tm_hour || delta->tm_min) {
159 cpr += printf("%-*s idle ",
160 maxlen - strlen(w->tty) + 1, ",");
161 if (delta->tm_yday > 0) {
162 cpr += printf("%d day%s ",
163 delta->tm_yday,
164 delta->tm_yday == 1 ? "" : "s");
165 }
166 cpr += printf("%d:%02d",
167 delta->tm_hour, delta->tm_min);
168 if (*w->host) {
169 putchar(',');
170 ++cpr;
171 }
172 }
173 if (!w->writable)
174 cpr += printf(" (messages off)");
175 break;
176 case LASTLOG:
177 if (w->loginat == 0) {
178 (void)printf("Never logged in.");
179 break;
180 }
181 tp = localtime(&w->loginat);
182 t = asctime(tp);
183 tzn = tp->tm_zone;
184 if (now - w->loginat > SECSPERDAY * DAYSPERNYEAR / 2)
185 cpr =
186 printf("Last login %.16s %.4s (%s) on %s",
187 t, t + 20, tzn, w->tty);
188 else
189 cpr = printf("Last login %.16s (%s) on %s",
190 t, tzn, w->tty);
191 break;
192 }
193 if (*w->host) {
194 if (LINE_LEN < (cpr + 6 + strlen(w->host)))
195 (void)printf("\n ");
196 (void)printf(" from %s", w->host);
197 }
198 putchar('\n');
199 }
200 }
201
demi_print(str,oddfield)202 demi_print(str, oddfield)
203 char *str;
204 int oddfield;
205 {
206 static int lenlast;
207 int lenthis, maxlen;
208
209 lenthis = strlen(str);
210 if (oddfield) {
211 /*
212 * We left off on an odd number of fields. If we haven't
213 * crossed the midpoint of the screen, and we have room for
214 * the next field, print it on the same line; otherwise,
215 * print it on a new line.
216 *
217 * Note: we insist on having the right hand fields start
218 * no less than 5 tabs out.
219 */
220 maxlen = 5 * TAB_LEN;
221 if (maxlen < lenlast)
222 maxlen = lenlast;
223 if (((((maxlen / TAB_LEN) + 1) * TAB_LEN) +
224 lenthis) <= LINE_LEN) {
225 while(lenlast < (4 * TAB_LEN)) {
226 putchar('\t');
227 lenlast += TAB_LEN;
228 }
229 (void)printf("\t%s\n", str); /* force one tab */
230 } else {
231 (void)printf("\n%s", str); /* go to next line */
232 oddfield = !oddfield; /* this'll be undone below */
233 }
234 } else
235 (void)printf("%s", str);
236 oddfield = !oddfield; /* toggle odd/even marker */
237 lenlast = lenthis;
238 return(oddfield);
239 }
240
show_text(directory,file_name,header)241 show_text(directory, file_name, header)
242 char *directory, *file_name, *header;
243 {
244 register int ch, lastc;
245 register FILE *fp;
246
247 (void)sprintf(tbuf, "%s/%s", directory, file_name);
248 if ((fp = fopen(tbuf, "r")) == NULL)
249 return(0);
250 (void)printf("%s\n", header);
251 while ((ch = getc(fp)) != EOF)
252 vputc(lastc = ch);
253 if (lastc != '\n')
254 (void)putchar('\n');
255 (void)fclose(fp);
256 return(1);
257 }
258
vputc(ch)259 vputc(ch)
260 register int ch;
261 {
262 int meta;
263
264 if (!isascii(ch)) {
265 (void)putchar('M');
266 (void)putchar('-');
267 ch = toascii(ch);
268 meta = 1;
269 } else
270 meta = 0;
271 if (isprint(ch) || !meta && (ch == ' ' || ch == '\t' || ch == '\n'))
272 (void)putchar(ch);
273 else {
274 (void)putchar('^');
275 (void)putchar(ch == '\177' ? '?' : ch | 0100);
276 }
277 }
278