sprint.c revision 156282
155714Skris/*
255714Skris * Copyright (c) 1989, 1993
355714Skris *	The Regents of the University of California.  All rights reserved.
455714Skris *
555714Skris * This code is derived from software contributed to Berkeley by
655714Skris * Tony Nardo of the Johns Hopkins University/Applied Physics Lab.
755714Skris *
855714Skris * Redistribution and use in source and binary forms, with or without
955714Skris * modification, are permitted provided that the following conditions
1055714Skris * are met:
1155714Skris * 1. Redistributions of source code must retain the above copyright
1255714Skris *    notice, this list of conditions and the following disclaimer.
1355714Skris * 2. Redistributions in binary form must reproduce the above copyright
1455714Skris *    notice, this list of conditions and the following disclaimer in the
1555714Skris *    documentation and/or other materials provided with the distribution.
1655714Skris * 3. All advertising materials mentioning features or use of this software
1755714Skris *    must display the following acknowledgement:
1855714Skris *	This product includes software developed by the University of
1955714Skris *	California, Berkeley and its contributors.
2055714Skris * 4. Neither the name of the University nor the names of its contributors
2155714Skris *    may be used to endorse or promote products derived from this software
2255714Skris *    without specific prior written permission.
2355714Skris *
2455714Skris * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2555714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2655714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2755714Skris * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2855714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2955714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3055714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3155714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3255714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3355714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3455714Skris * SUCH DAMAGE.
3555714Skris */
3655714Skris
3755714Skris#if 0
3855714Skris#ifndef lint
3955714Skrisstatic char sccsid[] = "@(#)sprint.c	8.3 (Berkeley) 4/28/95";
4055714Skris#endif
4155714Skris#endif
4255714Skris
4355714Skris#include <sys/cdefs.h>
4455714Skris__FBSDID("$FreeBSD: head/usr.bin/finger/sprint.c 156282 2006-03-04 16:13:16Z rwatson $");
4555714Skris
4655714Skris#include <sys/types.h>
4755714Skris#include <sys/socket.h>
4855714Skris#include <db.h>
4955714Skris#include <err.h>
5055714Skris#include <langinfo.h>
5155714Skris#include <pwd.h>
5255714Skris#include <stdio.h>
5355714Skris#include <string.h>
5455714Skris#include <time.h>
5555714Skris#include <utmp.h>
5655714Skris#include "finger.h"
5755714Skris
58100928Snectarstatic void	  stimeprint(WHERE *);
59160814Ssimon
60100928Snectarvoid
61100928Snectarsflag_print(void)
62100928Snectar{
63100928Snectar	PERSON *pn;
64100928Snectar	WHERE *w;
65100928Snectar	int sflag, r, namelen;
66100928Snectar	char p[80];
67100928Snectar	PERSON *tmp;
68100928Snectar	DBT data, key;
69100928Snectar	struct tm *lc;
70100928Snectar
71100928Snectar	if (d_first < 0)
72100928Snectar		d_first = (*nl_langinfo(D_MD_ORDER) == 'd');
73100928Snectar	/*
74100928Snectar	 * short format --
75100928Snectar	 *	login name
76100928Snectar	 *	real name
77100928Snectar	 *	terminal name (the XX of ttyXX)
78100928Snectar	 *	if terminal writeable (add an '*' to the terminal name
79100928Snectar	 *		if not)
80100928Snectar	 *	if logged in show idle time and day logged in, else
81100928Snectar	 *		show last login date and time.
82100928Snectar	 *		If > 6 months, show year instead of time.
83100928Snectar	 *	if (-o)
84100928Snectar	 *		office location
85100928Snectar	 *		office phone
86100928Snectar	 *	else
87100928Snectar	 *		remote host
88100928Snectar	 */
89100928Snectar#define	MAXREALNAME	16
90100928Snectar#define MAXHOSTNAME     17      /* in reality, hosts are never longer than 16 */
91100928Snectar	(void)printf("%-*s %-*s%s %s\n", UT_NAMESIZE, "Login", MAXREALNAME,
92100928Snectar	    "Name", " TTY      Idle  Login  Time  ", (gflag) ? "" :
93100928Snectar	    oflag ? "Office  Phone" : "Where");
94100928Snectar
95100928Snectar	for (sflag = R_FIRST;; sflag = R_NEXT) {
96100928Snectar		r = (*db->seq)(db, &key, &data, sflag);
97100928Snectar		if (r == -1)
98100928Snectar			err(1, "db seq");
99100928Snectar		if (r == 1)
100100928Snectar			break;
101100928Snectar		memmove(&tmp, data.data, sizeof tmp);
102100928Snectar		pn = tmp;
103100928Snectar
104100928Snectar		for (w = pn->whead; w != NULL; w = w->next) {
105100928Snectar			namelen = MAXREALNAME;
106100928Snectar			if (w->info == LOGGEDIN && !w->writable)
107100928Snectar				--namelen;	/* leave space before `*' */
108100928Snectar			(void)printf("%-*.*s %-*.*s", UT_NAMESIZE, UT_NAMESIZE,
109100928Snectar				pn->name, MAXREALNAME, namelen,
110100928Snectar				pn->realname ? pn->realname : "");
111160814Ssimon			if (!w->loginat) {
112160814Ssimon				(void)printf("  *     *   No logins   ");
113160814Ssimon				goto office;
114160814Ssimon			}
115160814Ssimon			(void)putchar(w->info == LOGGEDIN && !w->writable ?
116160814Ssimon			    '*' : ' ');
117160814Ssimon			if (*w->tty)
118160814Ssimon				(void)printf("%-7.7s ",
119160814Ssimon					     (strncmp(w->tty, "tty", 3)
120160814Ssimon					      && strncmp(w->tty, "cua", 3))
121160814Ssimon					     ? w->tty : w->tty + 3);
122160814Ssimon			else
123160814Ssimon				(void)printf("        ");
12455714Skris			if (w->info == LOGGEDIN) {
12555714Skris				stimeprint(w);
126109998Smarkm				(void)printf("  ");
127109998Smarkm			} else
12855714Skris				(void)printf("    *  ");
12955714Skris			lc = localtime(&w->loginat);
13055714Skris#define SECSPERDAY 86400
131109998Smarkm#define DAYSPERWEEK 7
13255714Skris#define DAYSPERNYEAR 365
133160814Ssimon			if (now - w->loginat < SECSPERDAY * (DAYSPERWEEK - 1)) {
134160814Ssimon				(void)strftime(p, sizeof(p), "%a", lc);
135160814Ssimon			} else {
136160814Ssimon				(void)strftime(p, sizeof(p),
13755714Skris					     d_first ? "%e %b" : "%b %e", lc);
13855714Skris			}
13968651Skris			(void)printf("%-6.6s", p);
140160814Ssimon			if (now - w->loginat >= SECSPERDAY * DAYSPERNYEAR / 2) {
141160814Ssimon				(void)strftime(p, sizeof(p), "%Y", lc);
142160814Ssimon			} else {
143160814Ssimon				(void)strftime(p, sizeof(p), "%R", lc);
144160814Ssimon			}
145160814Ssimon			(void)printf(" %-5.5s", p);
14655714Skrisoffice:
14755714Skris			if (gflag)
14855714Skris				goto no_gecos;
14955714Skris			if (oflag) {
15055714Skris				if (pn->office)
15155714Skris					(void)printf(" %-7.7s", pn->office);
15255714Skris				else if (pn->officephone)
15355714Skris					(void)printf(" %-7.7s", " ");
154160814Ssimon				if (pn->officephone)
155160814Ssimon					(void)printf(" %-.9s",
156160814Ssimon					    prphone(pn->officephone));
157160814Ssimon			} else
15855714Skris				(void)printf(" %.*s", MAXHOSTNAME, w->host);
15955714Skrisno_gecos:
16055714Skris			putchar('\n');
161109998Smarkm		}
162160814Ssimon	}
16355714Skris}
164109998Smarkm
16555714Skrisstatic void
16655714Skrisstimeprint(WHERE *w)
16755714Skris{
16859191Skris	struct tm *delta;
16955714Skris
17055714Skris	if (w->idletime == -1) {
17155714Skris		(void)printf("     ");
17255714Skris		return;
17355714Skris	}
17455714Skris
17555714Skris	delta = gmtime(&w->idletime);
17655714Skris	if (!delta->tm_yday)
17789837Skris		if (!delta->tm_hour)
17855714Skris			if (!delta->tm_min)
17955714Skris				(void)printf("     ");
18055714Skris			else
18155714Skris				(void)printf("%5d", delta->tm_min);
18255714Skris		else
18355714Skris			(void)printf("%2d:%02d",
18455714Skris			    delta->tm_hour, delta->tm_min);
18555714Skris	else
18655714Skris		(void)printf("%4dd", delta->tm_yday);
18755714Skris}
18855714Skris