lprint.c revision 1.4 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[] = "from: @(#)lprint.c 5.13 (Berkeley) 10/31/90";*/
39 static char rcsid[] = "$Id: lprint.c,v 1.4 1994/12/24 16:33:51 cgd Exp $";
40 #endif /* not lint */
41
42 #include <sys/types.h>
43 #include <sys/file.h>
44 #include <sys/stat.h>
45 #include <sys/time.h>
46 #include <tzfile.h>
47 #include <stdio.h>
48 #include <string.h>
49 #include <ctype.h>
50 #include <paths.h>
51 #include "finger.h"
52
53 #define LINE_LEN 80
54 #define TAB_LEN 8 /* 8 spaces between tabs */
55 #define _PATH_PLAN ".plan"
56 #define _PATH_PROJECT ".project"
57
58 lflag_print()
59 {
60 extern int pplan;
61 register PERSON *pn;
62
63 for (pn = phead;;) {
64 lprint(pn);
65 if (!pplan) {
66 (void)show_text(pn->dir, _PATH_PROJECT, "Project:");
67 if (!show_text(pn->dir, _PATH_PLAN, "Plan:"))
68 (void)printf("No Plan.\n");
69 }
70 if (!(pn = pn->next))
71 break;
72 putchar('\n');
73 }
74 }
75
76 lprint(pn)
77 register PERSON *pn;
78 {
79 extern time_t now;
80 register struct tm *delta;
81 register WHERE *w;
82 register int cpr, len, maxlen;
83 struct tm *tp;
84 int oddfield;
85 time_t time();
86 char *t, *tzn, *prphone();
87
88 /*
89 * long format --
90 * login name
91 * real name
92 * home directory
93 * shell
94 * office, office phone, home phone if available
95 */
96 (void)printf("Login: %-15s\t\t\tName: %s\nDirectory: %-25s",
97 pn->name, pn->realname, pn->dir);
98 (void)printf("\tShell: %-s\n", *pn->shell ? pn->shell : _PATH_BSHELL);
99
100 /*
101 * try and print office, office phone, and home phone on one line;
102 * if that fails, do line filling so it looks nice.
103 */
104 #define OFFICE_TAG "Office"
105 #define OFFICE_PHONE_TAG "Office Phone"
106 oddfield = 0;
107 if (pn->office && pn->officephone &&
108 strlen(pn->office) + strlen(pn->officephone) +
109 sizeof(OFFICE_TAG) + 2 <= 5 * TAB_LEN) {
110 (void)sprintf(tbuf, "%s: %s, %s", OFFICE_TAG, pn->office,
111 prphone(pn->officephone));
112 oddfield = demi_print(tbuf, oddfield);
113 } else {
114 if (pn->office) {
115 (void)sprintf(tbuf, "%s: %s", OFFICE_TAG, pn->office);
116 oddfield = demi_print(tbuf, oddfield);
117 }
118 if (pn->officephone) {
119 (void)sprintf(tbuf, "%s: %s", OFFICE_PHONE_TAG,
120 prphone(pn->officephone));
121 oddfield = demi_print(tbuf, oddfield);
122 }
123 }
124 if (pn->homephone) {
125 (void)sprintf(tbuf, "%s: %s", "Home Phone",
126 prphone(pn->homephone));
127 oddfield = demi_print(tbuf, oddfield);
128 }
129 if (oddfield)
130 putchar('\n');
131
132 /*
133 * long format con't: * if logged in
134 * terminal
135 * idle time
136 * if messages allowed
137 * where logged in from
138 * if not logged in
139 * when last logged in
140 */
141 /* find out longest device name for this user for formatting */
142 for (w = pn->whead, maxlen = -1; w != NULL; w = w->next)
143 if ((len = strlen(w->tty)) > maxlen)
144 maxlen = len;
145 /* find rest of entries for user */
146 for (w = pn->whead; w != NULL; w = w->next) {
147 switch (w->info) {
148 case LOGGEDIN:
149 tp = localtime(&w->loginat);
150 t = asctime(tp);
151 tzn = tp->tm_zone;
152 cpr = printf("On since %.16s (%s) on %s",
153 t, tzn, w->tty);
154 /*
155 * idle time is tough; if have one, print a comma,
156 * then spaces to pad out the device name, then the
157 * idle time. Follow with a comma if a remote login.
158 */
159 delta = gmtime(&w->idletime);
160 if (delta->tm_yday || delta->tm_hour || delta->tm_min) {
161 cpr += printf("%-*s idle ",
162 maxlen - strlen(w->tty) + 1, ",");
163 if (delta->tm_yday > 0) {
164 cpr += printf("%d day%s ",
165 delta->tm_yday,
166 delta->tm_yday == 1 ? "" : "s");
167 }
168 cpr += printf("%d:%02d",
169 delta->tm_hour, delta->tm_min);
170 if (*w->host) {
171 putchar(',');
172 ++cpr;
173 }
174 }
175 if (!w->writable)
176 cpr += printf(" (messages off)");
177 break;
178 case LASTLOG:
179 if (w->loginat == 0) {
180 (void)printf("Never logged in.");
181 break;
182 }
183 tp = localtime(&w->loginat);
184 t = asctime(tp);
185 tzn = tp->tm_zone;
186 if (now - w->loginat > SECSPERDAY * DAYSPERNYEAR / 2)
187 cpr =
188 printf("Last login %.16s %.4s (%s) on %s",
189 t, t + 20, tzn, w->tty);
190 else
191 cpr = printf("Last login %.16s (%s) on %s",
192 t, tzn, w->tty);
193 break;
194 }
195 if (*w->host) {
196 if (LINE_LEN < (cpr + 6 + strlen(w->host)))
197 (void)printf("\n ");
198 (void)printf(" from %s", w->host);
199 }
200 putchar('\n');
201 }
202 if (pn->mailrecv == -1)
203 printf("No Mail.\n");
204 else if (pn->mailrecv > pn->mailread) {
205 tp = localtime(&pn->mailrecv);
206 t = asctime(tp);
207 tzn = tp->tm_zone;
208 printf("New mail received %.16s %.4s (%s)\n", t, t + 20, tzn);
209 tp = localtime(&pn->mailread);
210 t = asctime(tp);
211 tzn = tp->tm_zone;
212 printf(" Unread since %.16s %.4s (%s)\n", t, t + 20, tzn);
213 } else {
214 tp = localtime(&pn->mailread);
215 t = asctime(tp);
216 tzn = tp->tm_zone;
217 printf("Mail last read %.16s %.4s (%s)\n", t, t + 20, tzn);
218 }
219 }
220
221 demi_print(str, oddfield)
222 char *str;
223 int oddfield;
224 {
225 static int lenlast;
226 int lenthis, maxlen;
227
228 lenthis = strlen(str);
229 if (oddfield) {
230 /*
231 * We left off on an odd number of fields. If we haven't
232 * crossed the midpoint of the screen, and we have room for
233 * the next field, print it on the same line; otherwise,
234 * print it on a new line.
235 *
236 * Note: we insist on having the right hand fields start
237 * no less than 5 tabs out.
238 */
239 maxlen = 5 * TAB_LEN;
240 if (maxlen < lenlast)
241 maxlen = lenlast;
242 if (((((maxlen / TAB_LEN) + 1) * TAB_LEN) +
243 lenthis) <= LINE_LEN) {
244 while(lenlast < (4 * TAB_LEN)) {
245 putchar('\t');
246 lenlast += TAB_LEN;
247 }
248 (void)printf("\t%s\n", str); /* force one tab */
249 } else {
250 (void)printf("\n%s", str); /* go to next line */
251 oddfield = !oddfield; /* this'll be undone below */
252 }
253 } else
254 (void)printf("%s", str);
255 oddfield = !oddfield; /* toggle odd/even marker */
256 lenlast = lenthis;
257 return(oddfield);
258 }
259
260 show_text(directory, file_name, header)
261 char *directory, *file_name, *header;
262 {
263 register int ch, lastc;
264 register FILE *fp;
265
266 (void)sprintf(tbuf, "%s/%s", directory, file_name);
267 if ((fp = fopen(tbuf, "r")) == NULL)
268 return(0);
269 (void)printf("%s\n", header);
270 while ((ch = getc(fp)) != EOF)
271 vputc(lastc = ch);
272 if (lastc != '\n')
273 (void)putchar('\n');
274 (void)fclose(fp);
275 return(1);
276 }
277
278 vputc(ch)
279 register int ch;
280 {
281 int meta;
282
283 if (!isascii(ch)) {
284 (void)putchar('M');
285 (void)putchar('-');
286 ch = toascii(ch);
287 meta = 1;
288 } else
289 meta = 0;
290 if (isprint(ch) || !meta && (ch == ' ' || ch == '\t' || ch == '\n'))
291 (void)putchar(ch);
292 else {
293 (void)putchar('^');
294 (void)putchar(ch == '\177' ? '?' : ch | 0100);
295 }
296 }
297