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