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