Michał Krzysztof Feiler 2018-10-12 09:45:57 +02:00
commit 37c4557418
24 changed files with 3082 additions and 0 deletions

1
.cvsignore Normal file
View File

@ -0,0 +1 @@
MCONFIG

7
BUGS Normal file
View File

@ -0,0 +1,7 @@
finger:
- add option to issue CRs so fingerd doesn't need to fork
- Some nameservers hose on "", patch finger to work around it
fingerd:
- rejection of finger forwarding should be optional

133
ChangeLog Normal file
View File

@ -0,0 +1,133 @@
22-Jul-2000:
Document ~/.pgpkey. (Herbert Xu, herbert@gondor.apana.org.au)
18-Dec-1999:
Add support for ~/.nofinger files.
14-Dec-1999:
bsd-finger-0.16 is released.
12-Dec-1999:
Withdrew -R option; finger can figure out on its own if it needs
to emit CRs.
Also, make printing of pts/* ttys work right.
14-Sep-1999:
Rewrote output handling of finger to deal with 8-bit characters
correctly. Also fixed what I think was some uninitialized data
displaying ":0" utmp entries.
Backed out patch 1.15 of finger/util.c because it was completely
wrong. Fixed gecos processing _again_.
Added -R option to finger that causes it to emit CR before every
LF. Changed fingerd to use it. This means fingerd no longer
needs to fork.
1-Aug-1999:
Complete y2k and y2038 audit.
31-Jul-1999:
Redid makefiles/config stuff for new confgen version.
23-Sep-1997:
fingerd should now refuse to run as root and bail if it can't find
"nobody".
22-Sep-1997:
Fix finger to not destroy gethostbyname() results with
getservbyname().
02-Aug-1997:
Fix fingerd to complain if it can't switch from root.
12-Jun-1997:
bsd-finger-0.10 released.
08-Jun-1997:
More adjustments for glibc.
13-May-1997:
Do dynamic column width formatting in short format printout. (HJ Lu)
05-Apr-1997:
Added configure script to generate MCONFIG.
glibc fixes from HJ Lu.
Display .pgpkey file in finger (Edward S. Marshall,
emarshal@common.net)
Better utmp handling.
08-Mar-1997:
Split from full NetKit package.
Generated this change log from NetKit's.
07-Mar-1997:
Fixed finger to reject .plans that aren't regular files. (Thomas
Roessler, roessler@sobolev.rhein.de)
01-Feb-1997:
Fixed finger's timezone handling. Now gets daylight time right.
29-Dec-1996
NetKit-0.09 released.
Fix doc bugs in fingerd.
Fingerd accepts -p as equivalent to -L for compatibility with
"fingerd-extlog.tar.gz".
Assorted alpha/glibc patches. (Erik Troan, ewt@redhat.com)
Assorted bug fixes from Debian. (Peter Tobias,
tobias@et-inf.fho-emden.de)
Hardened programs against DNS h_length spoofing attacks.
Use inet_aton() everywhere instead of inet_addr().
Fixed bug in finger's processing of &'s in full names that probably has
security implications.
Finger doesn't follow symlinks now.
22-Aug-1996
NetKit-B-0.08 released.
fingerd uses fork instead of system for running uptime (with -w flag).
fingerd supports -L flag to run alternate finger client.
(almost) everything now compiles with lots of warnings turned on.
fingerd now accepts a new -u flag to reject "finger @host" queries.
fix bug in finger that prevented matching full names
(fix from James Jones <james@richland.cc.il.us>.)
25-Jul-1996
NetKit-B-0.07A released.
23-Jul-1996
NetKit-B-0.07 released.
Integrated a collection of patches that had been lurking on the net,
including the 256-ptys support for telnetd and passive mode ftp.
Major security fixes, including to fingerd, lpr, rlogin, rsh, talkd,
and telnetd. Do *not* use the sliplogin from earlier versions of this
package, either.
Several of the daemons support better logging.
Much of the code builds without libbsd.a or bsd includes.
Massive code cleanup. Almost everything compiles clean with gcc
-Wall now. rusers and rusersd do not; patches to rpcgen to fix
this would be appreciated if anyone feels like it.
New maintainer: David A. Holland, dholland@hcs.harvard.edu
date not known
NetKit-B-0.06 released.
Added a missing argument in a printf to the finger source
code. Phil Edge
"finger -l" prints the standard timezone when it should print the
daylight savings timezone. tzname[0] is standard timezone and
tzname[1] is daylight savings timezone. This patch is from Phil
Edge. He wasn't too sure about this patch, and I haven't looked
into it. Anyone who really knows about this stuff? Look into
lprint.c in the finger source. I changed all "1 - daylight" into
"daylight"... You could also verify all Linux-specific changes
to timezone things. Other parts look also like duplicate work.
(Maybe even wrong...)
date not known
NetKit-B-0.05 released.
Fixed finger/util.c to cope with XDM login entry in utmp (Leonard
Zubkoff)
date not known
NetKit-B-0.04 released.
date not known
NetKit-B-0.03 released.
Fixed fingerd to not use 'getdomainname' to get the FQDN.

22
MCONFIG.in Normal file
View File

@ -0,0 +1,22 @@
# Dirs
INSTALLROOT
BINDIR
SBINDIR
MANDIR
# Modes
BINMODE
DAEMONMODE
MANMODE
# Compiling
ALLWARNINGS
CC
CFLAGS
LDFLAGS
LIBS
# Features
FN(snprintf)
TYPE(socklen_t)

8
MRULES Normal file
View File

@ -0,0 +1,8 @@
# Standard compilation rules (don't use make builtins)
%.o: %.c
$(CC) $(CFLAGS) $< -c
%.o: %.cc
$(CC) $(CFLAGS) $< -c

20
Makefile Normal file
View File

@ -0,0 +1,20 @@
# You can do "make SUB=blah" to make only a few, or edit here, or both
# You can also run make directly in the subdirs you want.
SUB = finger fingerd
%.build:
(cd $(patsubst %.build, %, $@) && $(MAKE))
%.install:
(cd $(patsubst %.install, %, $@) && $(MAKE) install)
%.clean:
(cd $(patsubst %.clean, %, $@) && $(MAKE) clean)
all: $(patsubst %, %.build, $(SUB))
install: $(patsubst %, %.install, $(SUB))
clean: $(patsubst %, %.clean, $(SUB))
distclean: clean
rm -f MCONFIG

118
README Normal file
View File

@ -0,0 +1,118 @@
This is bsd-finger-0.17 for Linux.
This package updates bsd-finger-0.16.
If you're reading this off a CD, go right away and check the net
archives for later versions and security fixes. As of this writing the
home site for NetKit is
ftp://ftp.uk.linux.org/pub/linux/Networking/netkit
Contents:
finger Program for printing user information
fingerd Daemon for remote finger access
Requires:
Working compiler, libc, and kernel.
Security:
bsd-finger-0.17 contains no new security fixes.
bsd-finger-0.16 fixes some possible denial of service attacks
against fingerd.
bsd-finger-0.10 fixed a denial of service situation where
users' .plan or .project files are named pipes.
The NetKit-0.09 and earlier versions of this code fixed a
number of now well-known security problems. Please don't use
older versions.
Note:
If you are using the finger daemon from this package with a
custom finger client, rather than the finger client in this
package, you will need to update your client to send carriage
returns (CR, or '\r' in C) before line feeds (LF, or '\n' in
C) if the finger client's standard output is a socket.
This is because as of bsd-finger-0.15, finger probes this
condition and sends CRs itself instead of expecting fingerd
to make an extra copy of all the data through a pipe just to
add CRs in.
Ignoring this circumstance and always sending LF instead of
CR/LF will in most cases work, but is not RFC-compliant.
Installation:
Do "./configure --help" and decide what options you want. The
defaults should be suitable for most Linux systems. Then run
the configure script.
Do "make" to compile.
Then (as root) do "make install".
Save a backup copy of any mission-critical program in case the
new one doesn't work, and so forth. We warned you.
If you get gcc warnings from files in /usr/include, they are
due to problems in your libc, not netkit. (You may only see
them when compiling netkit because netkit turns on a lot of
compiler warnings.)
DEC CC:
The DEC compiler for the Alpha is now freely available. This
is a much better compiler with gcc, that is, it generates much
better code. If you have the DEC compiler, you can explicitly
use the DEC compiler instead of gcc by configuring like this:
./configure --with-c-compiler=ccc
It is known to generate spurious warnings on some files. Also,
some headers from some versions of glibc confuse it; that may
prevent netkit from working. Other problems should be reported
as bugs.
Bugs:
Please make sure the header files in /usr/include match the
libc version installed in /lib and /usr/lib. If you have weird
problems this is the most likely culprit.
Also, before reporting a bug, be sure you're working with the
latest version.
If something doesn't compile for you, fix it and send diffs.
If you can't, send the compiler's error output.
If it compiles but doesn't work, send as complete a bug report as
you can. Patches and fixes are welcome, as long as you describe
adequately what they're supposed to fix. Please, one patch per
distinct fix. Please do NOT send the whole archive back or
reindent the source.
Be sure to send all correspondence in e-mail to the netkit address.
Postings to netnews or mailing lists will not be seen due to the
enormous volume. Also, anything that doesn't get filed in the bug
database is quite likely to end up forgotten.
Please don't report known bugs (see the BUGS file(s)) unless you
are including fixes. :-)
Mail should be sent to: netbug@ftp.uk.linux.org
Early in April 2000, a hacker broke into the machine that was hosting
the netkit bug database for me and trashed it. Unfortunately, it seems
backups hadn't gotten done for a while, so three months of mail (since
mid-January) was lost. So, if you sent something and didn't hear back,
or you sent something, heard back, but the changes failed to appear in
this release (unlikely but possible) - please resend.
Please see http://www.hcs.harvard.edu/~dholland/computers/netkit.html
if you are curious why it was so long between the 0.10 and 0.16 releases.
Future plans for netkit maintenance are still up in the air, but in the
meantime new releases will still appear from time to time. I don't have
a whole lot of cycles to spare to work on netkit, so things are likely
to continue to be fairly slow.
David A. Holland
23 July 2000

305
configure vendored Normal file
View File

@ -0,0 +1,305 @@
#!/bin/sh
#
# This file was generated by confgen version 2.
# Do not edit.
#
PREFIX='/usr'
#EXECPREFIX='$PREFIX'
INSTALLROOT=''
BINMODE='755'
#DAEMONMODE='$BINMODE'
MANMODE='644'
while [ x$1 != x ]; do case $1 in
--help)
cat <<EOF
Usage: configure [options]
--help Show this message
--with-debug Enable debugging
--prefix=path Prefix for location of files [/usr]
--exec-prefix=path Location for arch-depedent files [prefix]
--installroot=root Top of filesystem tree to install in [/]
--binmode=mode Mode for binaries [755]
--daemonmode=mode Mode for daemon binaries [same as binmode]
--manmode=mode Mode for manual pages [644]
--with-c-compiler=cc Program for compiling C source [guessed]
EOF
exit 0;;
--verbose) ;;
--quiet) ;;
--subdir) . ../configure.defs;;
--with-debug|--debug) DEBUG=1;;
--prefix=*) PREFIX=`echo $1 | sed 's/^[^=]*=//'` ;;
--exec-prefix=*) EXECPREFIX=`echo $1 | sed 's/^[^=]*=//'` ;;
--installroot=*) INSTALLROOT=`echo $1 | sed 's/^[^=]*=//'` ;;
--binmode=*) BINMODE=`echo $1 | sed 's/^[^=]*=//'` ;;
--daemonmode=*) DAEMONMODE=`echo $1 | sed 's/^[^=]*=//'` ;;
--manmode=*) MANMODE=`echo $1 | sed 's/^[^=]*=//'` ;;
--with-c-compiler=*) CC=`echo $1 | sed 's/^[^=]*=//'` ;;
*) echo "Unrecognized option: $1"; exit 1;;
esac
shift
done
if [ x$EXECPREFIX = x ]; then
EXECPREFIX="$PREFIX"
fi
if [ x$DAEMONMODE = x ]; then
DAEMONMODE="$BINMODE"
fi
BINDIR="$EXECPREFIX/bin"
SBINDIR="$EXECPREFIX/sbin"
MANDIR="$PREFIX/man"
echo "Directories: $BINDIR $SBINDIR $MANDIR "
if [ x$INSTALLROOT != x ]; then
echo "Installing in chroot tree rooted at $INSTALLROOT"
fi
##################################################
WARNINGS='-Wall -W -Wpointer-arith -Wbad-function-cast -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wnested-externs -Winline '
cat << EOF > __conftest.c
int main() { int class=0; return class; }
EOF
if [ x"$CC" = x ]; then
echo -n 'Looking for a C compiler... '
for TRY in egcs gcc g++ CC c++ cc; do
(
$TRY __conftest.c -o __conftest || exit 1;
./__conftest || exit 1;
) >/dev/null 2>&1 || continue;
CC=$TRY
break;
done
if [ x"$CC" = x ]; then
echo 'failed.'
echo 'Cannot find a C compiler. Run configure with --with-c-compiler.'
rm -f __conftest*
exit
fi
echo "$CC"
else
echo -n 'Checking if C compiler works... '
if (
$CC __conftest.c -o __conftest || exit 1
./__conftest || exit 1
) >/dev/null 2>&1; then
echo 'yes'
else
echo 'no'
echo 'Compiler '"$CC"' does not exist or cannot compile C; try another.'
rm -f __conftest*
exit
fi
fi
echo -n "Checking if $CC accepts gcc warnings... "
if (
$CC $WARNINGS __conftest.c -o __conftest || exit 1
) >/dev/null 2>&1; then
echo 'yes'
CC_WARNINGS=1
else
echo 'no'
fi
if [ x$DEBUG = x ]; then
echo -n "Checking if $CC accepts -O2... "
if (
$CC -O2 __conftest.c -o __conftest
) >/dev/null 2>&1; then
echo 'yes'
CFLAGS="$CFLAGS -O2"
else
echo 'no'
echo -n "Checking if $CC accepts -O... "
if (
$CC -O __conftest.c -o __conftest
) >/dev/null 2>&1; then
echo 'yes'
CFLAGS="$CFLAGS -O"
else
echo 'no'
fi
fi
else
echo -n "Checking if $CC accepts -g... "
if (
$CC -g __conftest.c -o __conftest
) >/dev/null 2>&1; then
echo 'yes'
CFLAGS="$CFLAGS -g"
else
echo 'no'
fi
fi
LDFLAGS=
LIBS=
rm -f __conftest*
##################################################
echo -n 'Checking for socklen_t... '
cat <<EOF >__conftest.c
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main() {
struct sockaddr_in sn;
socklen_t len = sizeof(sn);
getpeername(0, (struct sockaddr *)&sn, &len);
return 0;
}
EOF
if (
$CC $CFLAGS __conftest.c -o __conftest || exit 1
) >/dev/null 2>&1; then
echo 'yes'
else
if (
$CC $CFLAGS -Dsocklen_t=int __conftest.c -o __conftest || exit 1
) >/dev/null 2>&1; then
echo 'int'
CFLAGS="$CFLAGS -Dsocklen_t=int"
else
if (
$CC $CFLAGS -Dsocklen_t=size_t __conftest.c -o __conftest || exit 1
) >/dev/null 2>&1; then
echo 'size_t'
CFLAGS="$CFLAGS -Dsocklen_t=size_t"
else
echo 'no'
echo 'Cannot work out what to use for socklen_t. Help...'
rm -f __conftest*
exit
fi
fi
fi
rm -f __conftest*
##################################################
echo -n 'Checking for snprintf declaration... '
cat <<EOF >__conftest.c
#include <stdio.h>
int main() {
void *x = (void *)snprintf;
printf("%lx", (long)x);
return 0;
}
EOF
if (
$CC $CFLAGS __conftest.c -o __conftest || exit 1
) >/dev/null 2>&1; then
echo 'ok'
else
if (
$CC $CFLAGS -D_GNU_SOURCE __conftest.c -o __conftest || exit 1
./__conftest || exit 1
) >/dev/null 2>&1; then
echo '-D_GNU_SOURCE'
CFLAGS="$CFLAGS -D_GNU_SOURCE"
else
echo 'manual'
CFLAGS="$CFLAGS -DDECLARE_SNPRINTF"
fi
fi
rm -f __conftest*
echo -n 'Checking for snprintf implementation... '
cat <<EOF >__conftest.c
#include <stdio.h>
#include <string.h>
#ifdef DECLARE_SNPRINTF
#ifdef __cplusplus
extern "C"
#endif /*__cplusplus*/
int snprintf(char *, int, const char *, ...);
#endif /*DECLARE_SNPRINTF*/
int main() {
char buf[32];
snprintf(buf, 8, "%s", "1234567890");
if (strlen(buf)!=7) return 1;
return 0;
}
EOF
if (
$CC $CFLAGS __conftest.c $LIBBSD -o __conftest || exit 1
./__conftest || exit 1
) >/dev/null 2>&1; then
echo 'ok'
else
if (
$CC $CFLAGS __conftest.c -lsnprintf $LIBBSD -o __conftest || exit 1
./__conftest || exit 1
) >/dev/null 2>&1; then
echo '-lsnprintf'
LIBS="$LIBS -lsnprintf"
else
if (
$CC $CFLAGS __conftest.c -ldb $LIBBSD -o __conftest || exit 1
./__conftest || exit 1
) >/dev/null 2>&1; then
echo '-ldb'
LIBS="$LIBS -ldb"
else
echo 'missing'
echo 'This package requires snprintf.'
rm -f __conftest*
exit
fi
fi
fi
rm -f __conftest*
##################################################
## libbsd should go last in case it's broken
if [ "x$LIBBSD" != x ]; then
LIBS="$LIBS $LIBBSD"
fi
echo 'Generating MCONFIG...'
(
echo -n '# Generated by configure (confgen version 2) on '
date
echo '#'
echo
echo "BINDIR=$BINDIR"
echo "SBINDIR=$SBINDIR"
echo "MANDIR=$MANDIR"
echo "BINMODE=$BINMODE"
echo "DAEMONMODE=$DAEMONMODE"
echo "MANMODE=$MANMODE"
echo "PREFIX=$PREFIX"
echo "EXECPREFIX=$EXECPREFIX"
echo "INSTALLROOT=$INSTALLROOT"
echo "CC=$CC"
if [ x$CC_WARNINGS != x ]; then
CFLAGS="$CFLAGS $WARNINGS"
fi
echo "CFLAGS=$CFLAGS" | sed 's/= */=/'
echo "LDFLAGS=$LDFLAGS" | sed 's/= */=/'
echo "LIBS=$LIBS" | sed 's/= */=/'
) > MCONFIG

1
finger/.cvsignore Normal file
View File

@ -0,0 +1 @@
finger

18
finger/Makefile Normal file
View File

@ -0,0 +1,18 @@
all: finger
include ../MCONFIG
include ../MRULES
finger: finger.o lprint.o net.o sprint.o util.o display.o
$(CC) $(LDFLAGS) $^ $(LIBS) -o $@
finger.o lprint.o net.o sprint.o util.o display.o: finger.h
finger.o: ../version.h
install: finger
install -s -m$(BINMODE) finger $(INSTALLROOT)$(BINDIR)
install -m$(MANMODE) finger.1 $(INSTALLROOT)$(MANDIR)/man1
clean:
rm -f *.o finger

179
finger/display.c Normal file
View File

@ -0,0 +1,179 @@
/*
* Copyright (c) 1989 The Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Tony Nardo of the Johns Hopkins University/Applied Physics Lab.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <termios.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include "finger.h"
int
getscreenwidth(void)
{
#if defined(TIOCGWINSZ)
struct winsize ws;
if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) < 0 || ws.ws_col==0) {
return 80;
}
return ws.ws_col;
#elif defined(TIOCGSIZE)
struct ttysize ts;
if (ioctl(STDIN_FILENO, TIOCGSIZE, &ts) < 0 || ts.ts_cols==0) {
return 80;
}
return ts.ts_cols;
#else
const char *e = getenv("COLUMNS");
int col = e ? atoi(e) : 0;
if (col==0) col = 80;
return col;
#endif
}
int
is8bit(void)
{
static int cache=-1;
struct termios tios;
if (cache>=0) return cache;
if (tcgetattr(STDIN_FILENO, &tios)<0) {
/* assume 8-bit; it's 1999 now, not 1972 */
cache = 1;
}
else {
cache = (tios.c_cflag & CSIZE)==CS8;
}
return cache;
}
/************/
static int send_crs=0;
void
set_crmode(void)
{
send_crs = 1;
}
static
void
fxputc(FILE *f, int ch)
{
/* drop any sign */
ch = ch&0xff;
/* on 7-bit terminals, strip high bit */
if (!is8bit()) ch &= 0x7f;
/*
* Assume anything that isn't a control character is printable.
* We can't count on locale stuff to tell us what's printable
* because we might be looking at someone who uses different
* locale settings or is on the other side of the planet. So,
* strip 0-31, 127, 128-159, and 255. Note that not stripping
* 128-159 is asking for trouble, as 155 (M-esc) is interpreted
* as esc-[ by most terminals. Hopefully this won't break anyone's
* charset.
*
* It would be nice if we could set the terminal to display in the
* right charset, but we have no way to know what it is. feh.
*/
if (((ch&0x7f) >= 32 && (ch&0x7f) != 0x7f) || ch=='\t') {
putc(ch, f);
return;
}
if (ch=='\n') {
if (send_crs) putc('\r', f);
putc('\n', f);
return;
}
if (ch&0x80) {
putc('M', f);
putc('-', f);
ch &= 0x7f;
}
putc('^', f);
if (ch==0x7f) putc('?', f);
else putc(ch+'@', f);
}
void
xputc(int ch)
{
fxputc(stdout, ch);
}
static void fxputs(FILE *f, const char *buf) {
int i;
for (i=0; buf[i]; i++) fxputc(f, buf[i]);
}
int xprintf(const char *fmt, ...) {
char buf[1024];
va_list ap;
va_start(ap, fmt);
vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
fxputs(stdout, buf);
return strlen(buf);
}
int eprintf(const char *fmt, ...) {
char buf[1024];
va_list ap;
va_start(ap, fmt);
vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
fxputs(stderr, buf);
return strlen(buf);
}

194
finger/finger.1 Normal file
View File

@ -0,0 +1,194 @@
.\" Copyright (c) 1989, 1990 The Regents of the University of California.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by the University of
.\" California, Berkeley and its contributors.
.\" 4. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" from: @(#)finger.1 6.14 (Berkeley) 7/27/91
.\" $Id: finger.1,v 1.18 2000/07/30 23:56:57 dholland Exp $
.\"
.Dd August 15, 1999
.Dt FINGER 1
.Os "Linux NetKit (0.17)"
.Sh NAME
.Nm finger
.Nd user information lookup program
.Sh SYNOPSIS
.Nm finger
.Op Fl lmsp
.Op Ar user ...
.Op Ar user@host ...
.Sh DESCRIPTION
The
.Nm finger
displays information about the system users.
.Pp
Options are:
.Bl -tag -width flag
.It Fl s
.Nm Finger
displays the user's login name, real name, terminal name and write
status (as a ``*'' after the terminal name if write permission is
denied), idle time, login time, office location and office phone
number.
.Pp
Login time is displayed as month, day, hours and minutes, unless
more than six months ago, in which case the year is displayed rather
than the hours and minutes.
.Pp
Unknown devices as well as nonexistent idle and login times are
displayed as single asterisks.
.Pp
.It Fl l
Produces a multi-line format displaying all of the information
described for the
.Fl s
option as well as the user's home directory, home phone number, login
shell, mail status, and the contents of the files
.Dq Pa .plan ,
.Dq Pa .project ,
.Dq Pa .pgpkey
and
.Dq Pa .forward
from the user's home directory.
.Pp
Phone numbers specified as eleven digits are printed as ``+N-NNN-NNN-NNNN''.
Numbers specified as ten or seven digits are printed as the appropriate
subset of that string.
Numbers specified as five digits are printed as ``xN-NNNN''.
Numbers specified as four digits are printed as ``xNNNN''.
.Pp
If write permission is denied to the device, the phrase ``(messages off)''
is appended to the line containing the device name.
One entry per user is displayed with the
.Fl l
option; if a user is logged on multiple times, terminal information
is repeated once per login.
.Pp
Mail status is shown as ``No Mail.'' if there is no mail at all,
``Mail last read DDD MMM ## HH:MM YYYY (TZ)'' if the person has looked
at their mailbox since new mail arriving, or ``New mail received ...'',
`` Unread since ...'' if they have new mail.
.Pp
.It Fl p
Prevents
the
.Fl l
option of
.Nm finger
from displaying the contents of the
.Dq Pa .plan ,
.Dq Pa .project
and
.Dq Pa .pgpkey
files.
.It Fl m
Prevent matching of
.Ar user
names.
.Ar User
is usually a login name; however, matching will also be done on the
users' real names, unless the
.Fl m
option is supplied.
All name matching performed by
.Nm finger
is case insensitive.
.El
.Pp
If no options are specified,
.Nm finger
defaults to the
.Fl l
style output if operands are provided, otherwise to the
.Fl s
style.
Note that some fields may be missing, in either format, if information
is not available for them.
.Pp
If no arguments are specified,
.Nm finger
will print an entry for each user currently logged into the system.
.Pp
.Nm Finger
may be used to look up users on a remote machine.
The format is to specify a
.Ar user
as
.Dq Li user@host ,
or
.Dq Li @host ,
where the default output
format for the former is the
.Fl l
style, and the default output format for the latter is the
.Fl s
style.
The
.Fl l
option is the only option that may be passed to a remote machine.
.Pp
If standard output is a socket,
.Nm finger
will emit a carriage return (^M) before every linefeed (^J). This is
for processing remote finger requests when invoked by
.Xr fingerd 8 .
.Sh FILES
.Bl -tag -width mmmmmmmmmmmmmmm
.It Pa ~/.nofinger
If finger finds this file in a user's home directory, it will, for
finger requests originating outside the local host, firmly deny the
existence of that user. For this to work, the finger program, as
started by
.Xr fingerd 8 ,
must be able to see the
.Pa .nofinger
file. This generally means that the home directory containing the file
must have the other-users-execute bit set (o+w). See
.Xr chmod 1 .
If you use this feature for privacy, please test it with ``finger
@localhost'' before relying on it, just in case.
.It ~/.plan
.It ~/.project
.It ~/.pgp
These files are printed as part of a long-format request. The
.Pa .project
file is limited to one line; the
.Pa .plan
file may be arbitrarily long.
.El
.Sh SEE ALSO
.Xr chfn 1 ,
.Xr passwd 1 ,
.Xr w 1 ,
.Xr who 1
.Sh HISTORY
The
.Nm finger
command appeared in
.Bx 3.0 .

334
finger/finger.c Normal file
View File

@ -0,0 +1,334 @@
/*
* Copyright (c) 1989 The Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Tony Nardo of the Johns Hopkins University/Applied Physics Lab.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Mail status reporting added 931007 by Luke Mewburn, <zak@rmit.edu.au>.
*/
char copyright[] =
"@(#) Copyright (c) 1989 The Regents of the University of California.\n"
"All rights reserved.\n";
/*
* from: @(#)finger.c 5.22 (Berkeley) 6/29/90
*/
char finger_rcsid[] = \
"$Id: finger.c,v 1.15 1999/12/18 16:41:51 dholland Exp $";
/*
* Finger prints out information about users. It is not portable since
* certain fields (e.g. the full user name, office, and phone numbers) are
* extracted from the gecos field of the passwd file which other UNIXes
* may not have or may use for other things. (This is not really true any
* more, btw.)
*
* There are currently two output formats; the short format is one line
* per user and displays login name, tty, login time, real name, idle time,
* and office location/phone number. The long format gives the same
* information (in a more legible format) as well as home directory, shell,
* mail info, and .plan/.project files.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <limits.h>
#include <time.h>
#include <getopt.h>
#include "finger.h"
#include "../version.h"
static void loginlist(void);
static void userlist(int argc, char *argv[]);
int lflag, pplan;
static int sflag, mflag;
static int enable_nofinger;
time_t now;
char tbuf[TBUFLEN];
PERSON *phead, *ptail; /* the linked list of all people */
int entries; /* number of people */
int main(int argc, char *argv[]) {
int ch;
struct sockaddr_in sin;
socklen_t slen = sizeof(sin);
while ((ch = getopt(argc, argv, "lmps")) != EOF) {
switch(ch) {
case 'l':
lflag = 1; /* long format */
break;
case 'm':
mflag = 1; /* do exact match of names */
break;
case 'p':
pplan = 1; /* don't show .plan/.project */
break;
case 's':
sflag = 1; /* short format */
break;
case '?':
case 'h':
default:
eprintf("usage: finger [-lmps] [login ...]\n");
return 1;
}
}
argc -= optind;
argv += optind;
if (getsockname(STDOUT_FILENO, (struct sockaddr *)&sin, &slen)==0) {
/*
* stdout is a socket. must be a network finger request,
* so emit CRs with our LFs at the ends of lines.
*/
set_crmode();
/*
* Also, enable .nofinger processing.
*/
enable_nofinger = 1;
}
/*
* Also check stdin for nofinger processing, because of older
* fingerds that make stdout a pipe for CRLF handling.
*/
if (getsockname(STDIN_FILENO, (struct sockaddr *)&sin, &slen)==0) {
enable_nofinger = 1;
}
time(&now);
setpwent();
if (!*argv) {
/*
* Assign explicit "small" format if no names given and -l
* not selected. Force the -s BEFORE we get names so proper
* screening will be done.
*/
if (!lflag) {
sflag = 1; /* if -l not explicit, force -s */
}
loginlist();
if (entries == 0) {
xprintf("No one logged on.\n");
}
}
else {
userlist(argc, argv);
/*
* Assign explicit "large" format if names given and -s not
* explicitly stated. Force the -l AFTER we get names so any
* remote finger attempts specified won't be mishandled.
*/
if (!sflag)
lflag = 1; /* if -s not explicit, force -l */
}
if (entries != 0) {
if (lflag) lflag_print();
else sflag_print();
}
return 0;
}
/* Returns 1 if .nofinger is found and enable_nofinger is set. */
static
int
check_nofinger(struct passwd *pw)
{
if (enable_nofinger) {
char path[PATH_MAX];
struct stat tripe;
snprintf(path, sizeof(path), "%s/.nofinger", pw->pw_dir);
if (stat(path, &tripe)==0) {
return 1;
}
}
return 0;
}
static void
loginlist(void)
{
PERSON *pn;
struct passwd *pw;
struct utmp *uptr;
char name[UT_NAMESIZE + 1];
name[UT_NAMESIZE] = '\0';
/*
* if (!freopen(_PATH_UTMP, "r", stdin)) {
* fprintf(stderr, "finger: can't read %s.\n", _PATH_UTMP);
* exit(2);
* }
*/
setutent();
while ((uptr = getutent())!=NULL) {
if (!uptr->ut_name[0])
continue;
#ifdef USER_PROCESS
if (uptr->ut_type != USER_PROCESS) continue;
#endif
if ((pn = find_person(uptr->ut_name)) == NULL) {
memcpy(name, uptr->ut_name, UT_NAMESIZE);
if ((pw = getpwnam(name)) == NULL)
continue;
if (check_nofinger(pw))
continue;
pn = enter_person(pw);
}
enter_where(uptr, pn);
}
for (pn = phead; lflag && pn != NULL; pn = pn->next)
enter_lastlog(pn);
endutent();
}
static void do_local(int argc, char *argv[], int *used) {
int i;
struct passwd *pw;
/*
* traverse the list of possible login names and check the login name
* and real name against the name specified by the user.
*/
if (mflag) {
for (i = 0; i < argc; i++)
if (used[i] >= 0 && (pw = getpwnam(argv[i]))) {
if (!check_nofinger(pw)) {
enter_person(pw);
used[i] = 1;
}
}
} else for (pw = getpwent(); pw; pw = getpwent())
for (i = 0; i < argc; i++)
if (used[i] >= 0 &&
(!strcasecmp(pw->pw_name, argv[i]) ||
match(pw, argv[i]))) {
if (!check_nofinger(pw)) {
enter_person(pw);
used[i] = 1;
}
}
/* list errors */
for (i = 0; i < argc; i++)
if (!used[i])
(void)eprintf("finger: %s: no such user.\n", argv[i]);
}
static void
userlist(int argc, char *argv[])
{
int i;
PERSON *pn;
PERSON *nethead, **nettail;
struct utmp *uptr;
int dolocal, *used;
used = calloc(argc, sizeof(int));
if (!used) {
eprintf("finger: out of space.\n");
exit(1);
}
/* pull out all network requests */
for (i = 0, dolocal = 0, nettail = &nethead; i < argc; i++) {
if (!strchr(argv[i], '@')) {
dolocal = 1;
continue;
}
pn = palloc();
*nettail = pn;
nettail = &pn->next;
pn->name = argv[i];
used[i] = -1;
}
*nettail = NULL;
if (dolocal) do_local(argc, argv, used);
/* handle network requests */
for (pn = nethead; pn; pn = pn->next) {
netfinger(pn->name);
if (pn->next || entries)
xputc('\n');
}
if (entries == 0)
return;
/*
* Scan thru the list of users currently logged in, saving
* appropriate data whenever a match occurs.
*/
/*
* if (!freopen(_PATH_UTMP, "r", stdin)) {
* (void)fprintf( stderr, "finger: can't read %s.\n", _PATH_UTMP);
* exit(1);
* }
*/
setutent();
while ((uptr = getutent())!=NULL) {
if (!uptr->ut_name[0])
continue;
#ifdef USER_PROCESS
if (uptr->ut_type != USER_PROCESS) continue;
#endif
if ((pn = find_person(uptr->ut_name)) == NULL) {
continue;
}
enter_where(uptr, pn);
}
for (pn = phead; pn != NULL; pn = pn->next) {
enter_lastlog(pn);
}
endutent();
}

119
finger/finger.h Normal file
View File

@ -0,0 +1,119 @@
/*
* Copyright (c) 1989 The Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Tony Nardo of the Johns Hopkins University/Applied Physics Lab.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)finger.h 5.5 (Berkeley) 6/1/90
* $Id: finger.h,v 1.7 1999/09/14 10:51:11 dholland Exp $
*/
#include <pwd.h>
#include <utmp.h>
/*
* All unique persons are linked in a list headed by "head" and linkd
* by the "next" field, as well as kept in a hash table.
*/
typedef struct person {
struct person *next; /* link to next person */
struct person *hlink; /* link to next person in hash bucket */
uid_t uid; /* user id */
char *dir; /* user's home directory */
char *homephone; /* pointer to home phone no. */
char *name; /* login name */
char *office; /* pointer to office name */
char *officephone; /* pointer to office phone no. */
char *realname; /* pointer to full name */
char *shell; /* user's shell */
time_t mailread; /* last time mail was read */
time_t mailrecv; /* last time mail was read */
struct where *whead, *wtail; /* list of where he is or has been */
} PERSON;
enum status { LASTLOG, LOGGEDIN };
typedef struct where {
struct where *next; /* next place he is or has been */
enum status info; /* type/status of request */
short writable; /* tty is writable */
time_t loginat; /* time of (last) login */
time_t idletime; /* how long idle (if logged in) */
char tty[UT_LINESIZE+1]; /* null terminated tty line */
char host[UT_HOSTSIZE+1]; /* null terminated remote host name */
} WHERE;
extern PERSON *phead, *ptail; /* the linked list of all people */
extern int entries; /* number of people */
#define TBUFLEN 1024
extern char tbuf[TBUFLEN]; /* temp buffer for anybody */
extern time_t now;
extern int lflag, pplan;
PERSON *enter_person(struct passwd *);
PERSON *find_person(const char *name);
PERSON *palloc(void);
WHERE *walloc(PERSON *);
void lflag_print(void);
void sflag_print(void);
void enter_where(struct utmp *ut, PERSON *pn);
void enter_lastlog(PERSON *pn);
int match(struct passwd *pw, const char *user);
void netfinger(const char *name);
const char *prphone(const char *num);
#ifndef DAYSPERNYEAR
#define DAYSPERNYEAR 365
#endif
#ifndef SECSPERDAY
#define SECSPERDAY (60 * 60 * 24)
#endif
/* turn on crnl translation on output */
void set_crmode(void);
/* Display, masking control characters and possibly doing crnl translation */
void xputc(int ch);
void xputs(const char *buf);
int xprintf(const char *fmt, ...);
/* Send to stderr, possibly doing crnl translation */
int eprintf(const char *fmt, ...);
/* terminal inquiries */
int is8bit(void);
int getscreenwidth(void);

361
finger/lprint.c Normal file
View File

@ -0,0 +1,361 @@
/*
* Copyright (c) 1989 The Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Tony Nardo of the Johns Hopkins University/Applied Physics Lab.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* from: @(#)lprint.c 5.13 (Berkeley) 10/31/90
*/
char lprint_rcsid[] =
"$Id: lprint.c,v 1.11 1999/09/14 10:51:11 dholland Exp $";
#include <stdio.h>
#include <ctype.h>
#include <paths.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <sys/time.h>
#include "finger.h"
static void lprint(PERSON *pn);
static int demi_print(char *str, int oddfield);
static int show_text(const char *directory, const char *file_name,
const char *header);
#define LINE_LEN 80
#define TAB_LEN 8 /* 8 spaces between tabs */
#define _PATH_FORWARD ".forward"
#define _PATH_PLAN ".plan"
#define _PATH_PROJECT ".project"
#define _PATH_PGPKEY ".pgpkey"
void
lflag_print(void)
{
register PERSON *pn = phead;
while (1) {
lprint(pn);
if (!pplan) {
show_text(pn->dir, _PATH_PGPKEY, "PGP key:\n");
show_text(pn->dir, _PATH_PROJECT, "Project:\n");
if (!show_text(pn->dir, _PATH_PLAN, "Plan:\n")) {
xprintf("No Plan.\n");
}
}
if (!(pn = pn->next))
break;
xputc('\n');
}
}
static void
lprint(PERSON *pn)
{
struct tm *delta, *tp;
WHERE *w;
int cpr, len, maxlen;
int oddfield;
char timebuf[128];
/*
* long format --
* login name
* real name
* home directory
* shell
* office, office phone, home phone if available
*/
xprintf("Login: %-15s\t\t\tName: %s\nDirectory: %-25s",
pn->name, pn->realname, pn->dir);
xprintf("\tShell: %-s\n", *pn->shell ? pn->shell : _PATH_BSHELL);
/*
* try and print office, office phone, and home phone on one line;
* if that fails, do line filling so it looks nice.
*/
#define OFFICE_TAG "Office"
#define OFFICE_PHONE_TAG "Office Phone"
oddfield = 0;
if (pn->office && pn->officephone &&
strlen(pn->office) + strlen(pn->officephone) +
sizeof(OFFICE_TAG) + 2 <= 5 * TAB_LEN)
{
snprintf(tbuf, TBUFLEN, "%s: %s, %s", OFFICE_TAG, pn->office,
prphone(pn->officephone));
oddfield = demi_print(tbuf, oddfield);
}
else {
if (pn->office) {
snprintf(tbuf, TBUFLEN, "%s: %s", OFFICE_TAG,
pn->office);
oddfield = demi_print(tbuf, oddfield);
}
if (pn->officephone) {
snprintf(tbuf, TBUFLEN, "%s: %s", OFFICE_PHONE_TAG,
prphone(pn->officephone));
oddfield = demi_print(tbuf, oddfield);
}
}
if (pn->homephone) {
snprintf(tbuf, TBUFLEN, "%s: %s", "Home Phone",
prphone(pn->homephone));
oddfield = demi_print(tbuf, oddfield);
}
if (oddfield) xputc('\n');
/*
* long format con't: * if logged in
* terminal
* idle time
* if messages allowed
* where logged in from
* if not logged in
* when last logged in
*/
/* find out longest device name for this user for formatting */
for (w = pn->whead, maxlen = -1; w != NULL; w = w->next)
if ((len = strlen(w->tty)) > maxlen)
maxlen = len;
/* find rest of entries for user */
for (w = pn->whead; w != NULL; w = w->next) {
switch (w->info) {
case LOGGEDIN:
tp = localtime(&w->loginat);
/*
* t = asctime(tp);
* tzset();
* tzn = tzname[daylight];
* cpr = printf("On since %.16s (%s) on %s",
* t, tzn, w->tty);
*/
strftime(timebuf, sizeof(timebuf),
"%a %b %e %R (%Z)", tp);
cpr = xprintf("On since %s on %s", timebuf, w->tty);
if (*w->host) {
cpr += xprintf(" from %s", w->host);
}
/*
* idle time is tough; if have one, print a comma,
* then spaces to pad out the device name, then the
* idle time. Follow with a comma if a remote login.
*/
delta = gmtime(&w->idletime);
if (delta->tm_yday || delta->tm_hour
|| delta->tm_min || delta->tm_sec) {
if (*w->host)
xputc('\n');
cpr += xprintf("%-*s",
(int) (maxlen - strlen(w->tty) + 3), "");
if (delta->tm_yday > 0) {
cpr += xprintf("%d day%s ",
delta->tm_yday,
delta->tm_yday == 1 ? "" : "s");
}
if (delta->tm_hour > 0) {
cpr += xprintf("%d hour%s ",
delta->tm_hour,
delta->tm_hour == 1 ? "" : "s");
}
if ((delta->tm_min > 0) && !delta->tm_yday) {
cpr += xprintf("%d minute%s ",
delta->tm_min,
delta->tm_min == 1 ? "" : "s");
}
if ((delta->tm_sec > 0) && !delta->tm_yday
&& !delta->tm_hour) {
cpr += xprintf("%d second%s ",
delta->tm_sec,
delta->tm_sec == 1 ? "" : "s");
}
cpr += xprintf("idle");
}
if (!w->writable) {
if (delta->tm_yday || delta->tm_hour
|| delta->tm_min || delta->tm_sec)
cpr += xprintf("\n ");
cpr += xprintf(" (messages off)");
}
break;
case LASTLOG:
if (w->loginat == 0) {
(void)xprintf("Never logged in.");
break;
}
tp = localtime(&w->loginat);
/*
* t = asctime(tp);
* tzset();
* tzn = tzname[daylight];
* if(now - w->loginat > SECSPERDAY * DAYSPERNYEAR / 2)
* cpr =
* printf("Last login %.16s %.4s (%s) on %s",
* t, t + 20, tzn, w->tty);
* else
* cpr = printf("Last login %.16s (%s) on %s",
* t, tzn, w->tty);
*/
if (now - w->loginat < SECSPERDAY * DAYSPERNYEAR / 2) {
strftime(timebuf, sizeof(timebuf),
"%a %b %e %R (%Z)", tp);
}
else {
strftime(timebuf, sizeof(timebuf),
"%a %b %e %R %Y (%Z)", tp);
}
cpr = xprintf("Last login %s on %s", timebuf, w->tty);
if (*w->host) {
cpr += xprintf(" from %s", w->host);
}
break;
}
xputc('\n');
}
/* If the user forwards mail elsewhere, tell us about it */
show_text(pn->dir, _PATH_FORWARD, "Mail forwarded to ");
/* Print the standard mailbox information. */
if (pn->mailrecv == -1)
xprintf("No mail.\n");
else if (pn->mailrecv > pn->mailread) {
tp = localtime(&pn->mailrecv);
/*
* t = asctime(tp);
* tzset();
* tzn = tzname[daylight];
* printf("New mail received %.16s %.4s (%s)\n", t,
* t + 20, tzn);
*/
strftime(timebuf, sizeof(timebuf),
"%a %b %e %R %Y (%Z)", tp);
xprintf("New mail received %s\n", timebuf);
tp = localtime(&pn->mailread);
/*
* t = asctime(tp);
* tzset();
* tzn = tzname[daylight];
* printf(" Unread since %.16s %.4s (%s)\n", t,
* t + 20, tzn);
*/
strftime(timebuf, sizeof(timebuf),
"%a %b %e %R %Y (%Z)", tp);
xprintf(" Unread since %s\n", timebuf);
} else {
tp = localtime(&pn->mailread);
/*
* t = asctime(tp);
* tzset();
* tzn = tzname[daylight];
* printf("Mail last read %.16s %.4s (%s)\n", t,
* t + 20, tzn);
*/
strftime(timebuf, sizeof(timebuf),
"%a %b %e %R %Y (%Z)", tp);
xprintf("Mail last read %s\n", timebuf);
}
}
static int
demi_print(char *str, int oddfield)
{
static int lenlast;
int lenthis, maxlen;
lenthis = strlen(str);
if (oddfield) {
/*
* We left off on an odd number of fields. If we haven't
* crossed the midpoint of the screen, and we have room for
* the next field, print it on the same line; otherwise,
* print it on a new line.
*
* Note: we insist on having the right hand fields start
* no less than 5 tabs out.
*/
maxlen = 5 * TAB_LEN;
if (maxlen < lenlast)
maxlen = lenlast;
if (((((maxlen / TAB_LEN) + 1) * TAB_LEN) +
lenthis) <= LINE_LEN) {
while(lenlast < (4 * TAB_LEN)) {
xputc('\t');
lenlast += TAB_LEN;
}
(void)xprintf("\t%s\n", str); /* force one tab */
} else {
(void)xprintf("\n%s", str); /* go to next line */
oddfield = !oddfield; /* this'll be undone below */
}
} else
(void)xprintf("%s", str);
oddfield = !oddfield; /* toggle odd/even marker */
lenlast = lenthis;
return(oddfield);
}
static int
show_text(const char *directory, const char *file_name, const char *header)
{
int ch, lastc = 0, fd;
FILE *fp;
struct stat sbuf1, sbuf2;
snprintf(tbuf, TBUFLEN, "%s/%s", directory, file_name);
if (lstat(tbuf, &sbuf1) || !S_ISREG(sbuf1.st_mode)) return 0;
fd = open(tbuf, O_RDONLY);
if (fd<0) return 0;
if (fstat(fd, &sbuf2)) { close(fd); return 0; }
/* if we didn't get the same file both times, bail */
if (sbuf1.st_dev!=sbuf2.st_dev || sbuf1.st_ino!=sbuf2.st_ino) {
close(fd);
return 0;
}
fp = fdopen(fd, "r");
if (fp == NULL) { close(fd); return 0; }
xprintf("%s", header);
while ((ch = getc(fp)) != EOF) {
xputc(ch);
lastc = ch;
}
if (lastc != '\n') xputc('\n');
fclose(fp);
return 1;
}

155
finger/net.c Normal file
View File

@ -0,0 +1,155 @@
/*
* Copyright (c) 1989 The Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Tony Nardo of the Johns Hopkins University/Applied Physics Lab.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef lint
/*static char sccsid[] = "from: @(#)net.c 5.5 (Berkeley) 6/1/90";*/
char net_rcsid[] = "$Id: net.c,v 1.9 1999/09/14 10:51:11 dholland Exp $";
#endif /* not lint */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include "finger.h"
void netfinger(const char *name) {
register FILE *fp;
struct in_addr defaddr;
register int c, sawret, ateol;
struct hostent *hp, def;
struct servent *sp;
struct sockaddr_in sn;
int s;
char *alist[1], *host;
host = strrchr(name, '@');
if (!host) return;
*host++ = '\0';
memset(&sn, 0, sizeof(sn));
sp = getservbyname("finger", "tcp");
if (!sp) {
eprintf("finger: tcp/finger: unknown service\n");
return;
}
sn.sin_port = sp->s_port;
hp = gethostbyname(host);
if (!hp) {
if (!inet_aton(host, &defaddr)) {
eprintf("finger: unknown host: %s\n", host);
return;
}
def.h_name = host;
def.h_addr_list = alist;
def.h_addr = (char *)&defaddr;
def.h_length = sizeof(struct in_addr);
def.h_addrtype = AF_INET;
def.h_aliases = 0;
hp = &def;
}
sn.sin_family = hp->h_addrtype;
if (hp->h_length > (int)sizeof(sn.sin_addr)) {
hp->h_length = sizeof(sn.sin_addr);
}
memcpy(&sn.sin_addr, hp->h_addr, hp->h_length);
if ((s = socket(hp->h_addrtype, SOCK_STREAM, 0)) < 0) {
eprintf("finger: socket: %s\n", strerror(errno));
return;
}
/* print hostname before connecting, in case it takes a while */
xprintf("[%s]\n", hp->h_name);
if (connect(s, (struct sockaddr *)&sn, sizeof(sn)) < 0) {
eprintf("finger: connect: %s\n", strerror(errno));
close(s);
return;
}
/* -l flag for remote fingerd */
if (lflag) write(s, "/W ", 3);
/* send the name followed by <CR><LF> */
write(s, name, strlen(name));
write(s, "\r\n", 2);
/*
* Read from the remote system; once we're connected, we assume some
* data. If none arrives, we hang until the user interrupts.
*
* If we see a <CR> or a <CR> with the high bit set, treat it as
* a newline; if followed by a newline character, only output one
* newline.
*
* Text is sent to xputc() for printability analysis.
*/
fp = fdopen(s, "r");
if (!fp) {
eprintf("finger: fdopen: %s\n", strerror(errno));
close(s);
return;
}
sawret = 0;
ateol = 1;
while ((c = getc(fp)) != EOF) {
c &= 0xff;
if (c == ('\r'|0x80) || c == ('\n'|0x80)) c &= 0x7f;
if (c == '\r') {
sawret = ateol = 1;
xputc('\n');
}
else if (sawret && c == '\n') {
sawret = 0;
/* don't print */
}
else {
if (c == '\n') ateol = 1;
sawret = 0;
xputc(c);
}
}
if (!ateol) xputc('\n');
fclose(fp);
}

172
finger/sprint.c Normal file
View File

@ -0,0 +1,172 @@
/*
* Copyright (c) 1989 The Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Tony Nardo of the Johns Hopkins University/Applied Physics Lab.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef lint
/*static char sccsid[] = "from: @(#)sprint.c 5.8 (Berkeley) 12/4/90";*/
char sprint_rcsid[] = "$Id: sprint.c,v 1.10 1999/12/12 18:59:33 dholland Exp $";
#endif /* not lint */
#include <sys/types.h>
#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "finger.h"
static void stimeprint(WHERE *w);
static int psort(const void *a, const void *b);
static PERSON **sort(void);
void sflag_print(void) {
register PERSON *pn;
register WHERE *w;
register char *p;
PERSON **list;
int maxlname, maxrname, space, cnt;
list = sort();
/*
* short format --
* login name
* real name
* terminal name
* if terminal writeable (add an '*' to the terminal name
* if not)
* if logged in show idle time and day logged in, else
* show last login date and time. If > 6 moths,
* show year instead of time.
* office location
* office phone
*/
maxlname = maxrname = sizeof("Login ");
for (cnt = 0; cnt < entries; ++cnt) {
int l;
pn = list[cnt];
l = pn->name ? strlen(pn->name) : 1;
if (l > maxlname) maxlname = l;
l = pn->realname ? strlen(pn->realname) : 1;
if (l > maxrname) maxrname = l;
}
/* prevent screen overflow */
space = getscreenwidth() - 50;
if (maxlname + maxrname > space) maxrname = space - maxlname;
/* add a space if there's room */
if (maxlname + maxrname < space-2) { maxlname++; maxrname++; }
(void)xprintf("%-*s %-*s %s\n", maxlname, "Login", maxrname,
"Name", " Tty Idle Login Time Office Office Phone");
for (cnt = 0; cnt < entries; ++cnt) {
pn = list[cnt];
for (w = pn->whead; w != NULL; w = w->next) {
(void)xprintf("%-*.*s %-*.*s ", maxlname, maxlname,
pn->name, maxrname, maxrname,
pn->realname ? pn->realname : "");
if (!w->loginat) {
(void)xprintf(" * * No logins ");
goto office;
}
(void)xputc(w->info == LOGGEDIN && !w->writable ?
'*' : ' ');
if (*w->tty)
(void)xprintf("%-7.7s ", w->tty);
else
(void)xprintf(" ");
if (w->info == LOGGEDIN) {
stimeprint(w);
(void)xprintf(" ");
} else
(void)xprintf(" * ");
p = ctime(&w->loginat);
(void)xprintf("%.6s", p + 4);
if (now - w->loginat >= SECSPERDAY * DAYSPERNYEAR / 2)
(void)xprintf(" %.4s", p + 20);
else
(void)xprintf(" %.5s", p + 11);
office:
if (w->host[0] != '\0') {
xprintf(" (%s)", w->host);
} else {
if (pn->office)
(void)xprintf(" %-10.10s", pn->office);
else if (pn->officephone)
(void)xprintf(" %-10.10s", " ");
if (pn->officephone)
(void)xprintf(" %-.14s",
prphone(pn->officephone));
}
xputc('\n');
}
}
}
static PERSON **sort(void) {
register PERSON *pn, **lp;
PERSON **list;
if (!(list = (PERSON **)malloc((u_int)(entries * sizeof(PERSON *))))) {
eprintf("finger: Out of space.\n");
exit(1);
}
for (lp = list, pn = phead; pn != NULL; pn = pn->next)
*lp++ = pn;
(void)qsort(list, entries, sizeof(PERSON *), psort);
return(list);
}
static int psort(const void *a, const void *b) {
const PERSON *const *p = (const PERSON *const *)a;
const PERSON *const *t = (const PERSON *const *)b;
return(strcmp((*p)->name, (*t)->name));
}
static void stimeprint(WHERE *w) {
register struct tm *delta;
delta = gmtime(&w->idletime);
if (!delta->tm_yday)
if (!delta->tm_hour)
if (!delta->tm_min)
(void)xprintf(" ");
else
(void)xprintf("%5d", delta->tm_min);
else
(void)xprintf("%2d:%02d",
delta->tm_hour, delta->tm_min);
else
(void)xprintf("%4dd", delta->tm_yday);
}

418
finger/util.c Normal file
View File

@ -0,0 +1,418 @@
/*
* Copyright (c) 1989 The Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Tony Nardo of the Johns Hopkins University/Applied Physics Lab.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef lint
/*static char sccsid[] = "from: @(#)util.c 5.14 (Berkeley) 1/17/91";*/
char util_rcsid[] = "$Id: util.c,v 1.18 1999/09/28 22:53:58 netbug Exp $";
#endif /* not lint */
#include <sys/types.h>
/* #include <sys/param.h> <--- unused? */
#include <sys/stat.h>
#include <sys/file.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <paths.h>
#include <errno.h>
#include <lastlog.h>
#include <unistd.h>
#include <stdlib.h>
#include "finger.h"
#define HBITS 8 /* number of bits in hash code */
#define HSIZE (1 << 8) /* hash table size */
#define HMASK (HSIZE - 1) /* hash code mask */
static PERSON *htab[HSIZE]; /* the buckets */
static int hash(const char *name);
static void find_idle_and_ttywrite(register WHERE *w) {
struct stat sb;
/* No device for X console. Utmp entry by XDM login (":0"). */
if (w->tty[0] == ':') {
w->idletime = 0; /* would be nice to have it emit ??? */
w->writable = 0;
return;
}
snprintf(tbuf, TBUFLEN, "%s/%s", _PATH_DEV, w->tty);
if (stat(tbuf, &sb) < 0) {
eprintf("finger: %s: %s\n", tbuf, strerror(errno));
return;
}
w->idletime = now < sb.st_atime ? 0 : now - sb.st_atime;
#define TALKABLE 0220 /* tty is writable if 220 mode */
w->writable = ((sb.st_mode & TALKABLE) == TALKABLE);
}
static void userinfo(PERSON *pn, struct passwd *pw) {
char *p;
struct stat sb;
char *bp;
char *rname;
int i, j, ct;
char *fields[4];
int nfields;
pn->uid = pw->pw_uid;
pn->name = strdup(pw->pw_name);
pn->dir = strdup(pw->pw_dir);
pn->shell = strdup(pw->pw_shell);
/* make a private copy of gecos to munge */
strncpy(tbuf, pw->pw_gecos, TBUFLEN);
tbuf[TBUFLEN-1] = 0; /* ensure null termination */
bp = tbuf;
/* why do we skip asterisks!?!? */
if (*bp == '*') ++bp;
/*
* fields[0] -> real name
* fields[1] -> office
* fields[2] -> officephone
* fields[3] -> homephone
*/
nfields = 0;
for (p = strtok(bp, ","); p; p = strtok(NULL, ",")) {
if (*p==0) p = NULL; // skip empties
if (nfields < 4) fields[nfields++] = p;
}
while (nfields<4) fields[nfields++] = NULL;
if (fields[0]) {
/*
* Ampersands in gecos get replaced by the capitalized login
* name. This is a major nuisance and whoever thought it up
* should be shot.
*/
p = fields[0];
/* First, count the number of ampersands. */
for (ct=i=0; p[i]; i++) if (p[i]=='&') ct++;
/* This tells us how much space we need to copy the name. */
rname = malloc(strlen(p) + ct*strlen(pw->pw_name) + 1);
if (!rname) {
eprintf("finger: Out of space.\n");
exit(1);
}
/* Now, do it */
for (i=j=0; p[i]; i++) {
if (p[i]=='&') {
strcpy(rname + j, pw->pw_name);
if (islower(rname[j])) {
rname[j] = toupper(rname[j]);
}
j += strlen(pw->pw_name);
}
else {
rname[j++] = p[i];
}
}
rname[j] = 0;
pn->realname = rname;
}
pn->office = fields[1] ? strdup(fields[1]) : NULL;
pn->officephone = fields[2] ? strdup(fields[2]) : NULL;
pn->homephone = fields[3] ? strdup(fields[3]) : NULL;
pn->mailrecv = -1; /* -1 == not_valid */
pn->mailread = -1; /* -1 == not_valid */
snprintf(tbuf, TBUFLEN, "%s/%s", _PATH_MAILDIR, pw->pw_name);
if (stat(tbuf, &sb) < 0) {
if (errno != ENOENT) {
eprintf("finger: %s: %s\n", tbuf, strerror(errno));
return;
}
}
else if (sb.st_size != 0) {
pn->mailrecv = sb.st_mtime;
pn->mailread = sb.st_atime;
}
}
int
match(struct passwd *pw, const char *user)
{
char *p;
int i, j, ct, rv=0;
char *rname;
strncpy(tbuf, pw->pw_gecos, TBUFLEN);
tbuf[TBUFLEN-1] = 0; /* guarantee null termination */
p = tbuf;
/* why do we skip asterisks!?!? */
if (*p == '*') ++p;
/* truncate the uninteresting stuff off the end of gecos */
p = strtok(p, ",");
if (!p) return 0;
/*
* Ampersands get replaced by the login name.
*/
/* First, count the number of ampersands. */
for (ct=i=0; p[i]; i++) if (p[i]=='&') ct++;
/* This tells us how much space we need to copy the name. */
rname = malloc(strlen(p) + ct*strlen(pw->pw_name) + 1);
if (!rname) {
eprintf("finger: Out of space.\n");
exit(1);
}
/* Now, do it */
for (i=j=0; p[i]; i++) {
if (p[i]=='&') {
strcpy(rname + j, pw->pw_name);
if (islower(rname[j])) rname[j] = toupper(rname[j]);
j += strlen(pw->pw_name);
}
else {
rname[j++] = p[i];
}
}
rname[j] = 0;
for (p = strtok(rname, "\t "); p && !rv; p = strtok(NULL, "\t ")) {
if (!strcasecmp(p, user))
rv = 1;
}
free(rname);
return rv;
}
static int get_lastlog(int fd, uid_t uid, struct lastlog *ll) {
loff_t pos;
if (fd == -1) return -1;
pos = (long)uid * sizeof(*ll);
if (lseek(fd, pos, L_SET) != pos) return -1;
if (read(fd, ll, sizeof(*ll)) != sizeof(*ll)) return -1;
return 0;
}
void enter_lastlog(PERSON *pn) {
static int opened = 0, fd = -1;
WHERE *w;
struct lastlog ll;
int doit = 0;
/* some systems may not maintain lastlog, don't report errors. */
if (!opened) {
fd = open(_PATH_LASTLOG, O_RDONLY, 0);
opened = 1;
}
if (get_lastlog(fd, pn->uid, &ll)) {
/* as if never logged in */
ll.ll_line[0] = ll.ll_host[0] = '\0';
ll.ll_time = 0;
}
if ((w = pn->whead) == NULL)
doit = 1;
else if (ll.ll_time != 0) {
/* if last login is earlier than some current login */
for (; !doit && w != NULL; w = w->next)
if (w->info == LOGGEDIN && w->loginat < ll.ll_time)
doit = 1;
/*
* and if it's not any of the current logins
* can't use time comparison because there may be a small
* discrepency since login calls time() twice
*/
for (w = pn->whead; doit && w != NULL; w = w->next)
if (w->info == LOGGEDIN &&
strncmp(w->tty, ll.ll_line, UT_LINESIZE) == 0)
doit = 0;
}
if (doit) {
w = walloc(pn);
w->info = LASTLOG;
bcopy(ll.ll_line, w->tty, UT_LINESIZE);
w->tty[UT_LINESIZE] = 0;
bcopy(ll.ll_host, w->host, UT_HOSTSIZE);
w->host[UT_HOSTSIZE] = 0;
w->loginat = ll.ll_time;
}
}
void enter_where(struct utmp *ut, PERSON *pn) {
register WHERE *w = walloc(pn);
w->info = LOGGEDIN;
bcopy(ut->ut_line, w->tty, UT_LINESIZE);
w->tty[UT_LINESIZE] = 0;
bcopy(ut->ut_host, w->host, UT_HOSTSIZE);
w->host[UT_HOSTSIZE] = 0;
w->loginat = ut->ut_time;
find_idle_and_ttywrite(w);
}
PERSON * enter_person(struct passwd *pw) {
register PERSON *pn, **pp;
for (pp = htab + hash(pw->pw_name);
*pp != NULL && strcmp((*pp)->name, pw->pw_name) != 0;
pp = &(*pp)->hlink)
;
if ((pn = *pp) == NULL) {
pn = palloc();
entries++;
if (phead == NULL)
phead = ptail = pn;
else {
ptail->next = pn;
ptail = pn;
}
pn->next = NULL;
pn->hlink = NULL;
*pp = pn;
userinfo(pn, pw);
pn->whead = NULL;
}
return(pn);
}
PERSON *find_person(const char *name) {
register PERSON *pn;
/* name may be only UT_NAMESIZE long and not terminated */
for (pn = htab[hash(name)];
pn != NULL && strncmp(pn->name, name, UT_NAMESIZE) != 0;
pn = pn->hlink)
;
return(pn);
}
static int hash(const char *name) {
register int h, i;
h = 0;
/* name may be only UT_NAMESIZE long and not terminated */
for (i = UT_NAMESIZE; --i >= 0 && *name;)
h = ((h << 2 | h >> (HBITS - 2)) ^ *name++) & HMASK;
return(h);
}
PERSON *palloc(void) {
PERSON *p;
if ((p = (PERSON *)malloc((u_int) sizeof(PERSON))) == NULL) {
eprintf("finger: Out of space.\n");
exit(1);
}
return(p);
}
WHERE *
walloc(PERSON *pn)
{
register WHERE *w;
if ((w = (WHERE *)malloc((u_int) sizeof(WHERE))) == NULL) {
eprintf("finger: Out of space.\n");
exit(1);
}
if (pn->whead == NULL)
pn->whead = pn->wtail = w;
else {
pn->wtail->next = w;
pn->wtail = w;
}
w->next = NULL;
return(w);
}
const char *
prphone(const char *num)
{
char *p;
const char *q;
int len;
static char pbuf[15];
/* don't touch anything if the user has their own formatting */
for (q = num; *q; ++q)
if (!isdigit(*q))
return(num);
len = q - num;
p = pbuf;
switch(len) {
case 11: /* +0-123-456-7890 */
*p++ = '+';
*p++ = *num++;
*p++ = '-';
/* FALLTHROUGH */
case 10: /* 012-345-6789 */
*p++ = *num++;
*p++ = *num++;
*p++ = *num++;
*p++ = '-';
/* FALLTHROUGH */
case 7: /* 012-3456 */
*p++ = *num++;
*p++ = *num++;
*p++ = *num++;
break;
case 5: /* x0-1234 */
case 4: /* x1234 */
*p++ = 'x';
*p++ = *num++;
break;
default:
return num;
}
if (len != 4) {
*p++ = '-';
*p++ = *num++;
}
*p++ = *num++;
*p++ = *num++;
*p++ = *num++;
*p = '\0';
return(pbuf);
}

1
fingerd/.cvsignore Normal file
View File

@ -0,0 +1 @@
fingerd

18
fingerd/Makefile Normal file
View File

@ -0,0 +1,18 @@
all: fingerd
include ../MCONFIG
include ../MRULES
fingerd: fingerd.o
$(CC) $(LDFLAGS) $^ $(LIBS) -o $@
fingerd.o: pathnames.h ../version.h
install: fingerd
install -s -m$(DAEMONMODE) fingerd $(INSTALLROOT)$(SBINDIR)/in.fingerd
install -m$(MANMODE) fingerd.8 $(INSTALLROOT)$(MANDIR)/man8/in.fingerd.8
ln -sf in.fingerd.8 $(INSTALLROOT)$(MANDIR)/man8/fingerd.8
clean:
rm -f *.o fingerd

157
fingerd/fingerd.8 Normal file
View File

@ -0,0 +1,157 @@
.\" Copyright (c) 1980, 1991 The Regents of the University of California.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by the University of
.\" California, Berkeley and its contributors.
.\" 4. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" from: @(#)fingerd.8 6.4 (Berkeley) 3/16/91
.\" $Id: fingerd.8,v 1.18 2000/07/30 23:56:57 dholland Exp $
.\"
.Dd August 29, 1996
.Dt FINGERD 8
.Os "Linux NetKit (0.17)"
.Sh NAME
.Nm fingerd
.Nd remote user information server
.Sh SYNOPSIS
.Nm fingerd
.Op Fl wulf
.Op Fl pL Ar path
.Op Fl t Ar timeout
.Sh DESCRIPTION
.Nm Fingerd
is a simple daemon based on
.%T RFC1196
that provides an interface to the
.Dq finger
program at most network sites.
The program is supposed to return a friendly,
human-oriented status report on either the system at the moment
or a particular person in depth.
.Pp
If the
.Fl w
option is given, remote users will get an additional
.Dq Welcome to ...
banner
which also shows some informations (e.g. uptime, operating system name and
release) about the system the
.Nm fingerd
is running on. Some sites may consider this a security risk as it
gives out information that may be useful to crackers.
.Pp
If the
.Fl u
option is given, requests of the form
.Dq finger @host
are rejected.
.Pp
If the
.Fl l
option is given, information about requests made is logged. This
option probably violates users' privacy and should not be used on
multiuser boxes.
.Pp
If the
.Fl f
option is given, finger forwarding (user@host1@host2) is allowed.
Useful behind firewalls, but probably not wise for security and
resource reasons.
.Pp
The
.Fl p
option allows specification of an alternate location for fingerd to find
the
.Dq finger
program. The
.Fl L
option is equivalent.
.Pp
The
.Fl t
option specifies the time to wait for a request before closing the
connection. A value of 0 waits forever. The default is 60 seconds.
.Pp
Options to fingerd should be specified in
.Pa /etc/inetd.conf .
.Pp
The finger protocol consists mostly of specifying command arguments.
The
.Xr inetd 8
.Dq super-server
runs
.Nm fingerd
for
.Tn TCP
requests received on port 79.
Once connected
.Nm fingerd
reads a single command line
terminated by a
.Aq Tn CRLF
which is passed to
.Xr finger 1 .
It closes its connections as soon as all output is finished.
.Pp
If the line is empty (i.e. just a
.Aq Tn CRLF
is sent) then
.Xr finger
returns a
.Dq default
report that lists all people logged into
the system at that moment. This feature is blocked by the
.Fl u
option.
.Pp
If a user name is specified (e.g.
.Pf eric Aq Tn CRLF )
then the
response lists more extended information for only that particular user,
whether logged in or not.
Allowable
.Dq names
in the command line include both
.Dq login names
and
.Dq user names .
If a name is ambiguous, all possible derivations are returned.
.Sh SEE ALSO
.Xr finger 1 ,
.Xr inetd 8
.Sh RESTRICTIONS
Connecting directly to the server from a
.Tn TIP
or an equally narrow-minded
.Tn TELNET Ns \-protocol
user program can result
in meaningless attempts at option negotiation being sent to the
server, which will foul up the command line interpretation.
.Sh HISTORY
The finger daemon appeared in
.Bx 4.3 .

295
fingerd/fingerd.c Normal file
View File

@ -0,0 +1,295 @@
/*
* Copyright (c) 1983 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
char copyright[] =
"@(#) Copyright (c) 1983 The Regents of the University of California.\n"
"All rights reserved.\n";
/*
* from: @(#)fingerd.c 5.6 (Berkeley) 6/1/90"
*/
char rcsid[] =
"$Id: fingerd.c,v 1.23 1999/12/12 18:46:28 dholland Exp $";
#include <pwd.h>
#include <grp.h>
#include <netdb.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <syslog.h>
#include <getopt.h>
#include <netinet/in.h>
#include <sys/utsname.h>
#include <sys/wait.h>
#include "pathnames.h"
#include "../version.h"
#define ENTRIES 50
#define WS " \t\r\n"
/* These are used in this order if the finger path compiled in doesn't work. */
#define _ALT_PATH_FINGER_1 "/usr/local/bin/finger"
#define _ALT_PATH_FINGER_2 "/usr/ucb/finger"
#define _ALT_PATH_FINGER_3 "/usr/bin/finger"
static
void
fatal(const char *msg, int use_errno, int tolog, int toclient)
{
const char *err = "";
const char *sep = "";
if (use_errno) {
err = strerror(errno);
sep = ": ";
}
if (tolog) syslog(LOG_ERR, "%s%s%s\n", msg, sep, err);
if (toclient) fprintf(stderr, "fingerd: %s%s%s\r\n", msg, sep, err);
else fprintf(stderr, "fingerd: Internal error\r\n");
exit(1);
}
static
void
timeout(int sig)
{
(void)sig;
errno = ETIMEDOUT;
fatal("Input timeout", 0, 1, 1);
}
int
main(int argc, char *argv[])
{
#if 0
FILE *fp;
int p[2], ch;
pid_t pid;
#endif
int ca;
const char *av[ENTRIES + 1];
const char **avy;
char *const *avx;
char line[1024];
int welcome = 0, heavylogging = 0, nouserlist = 0;
int patience = 60, forwarding = 0;
int k, nusers;
char *s, *t;
const char *fingerpath = NULL;
struct sockaddr_in sn;
socklen_t sval = sizeof(sn);
if (getpeername(0, (struct sockaddr *) &sn, &sval) < 0) {
fatal("getpeername", 1, 0, 1);
}
openlog("fingerd", LOG_PID, LOG_DAEMON);
if (!getuid() || !geteuid()) {
struct passwd *pwd = getpwnam("nobody");
if (pwd) {
initgroups(pwd->pw_name, pwd->pw_gid);
setgid(pwd->pw_gid);
setuid(pwd->pw_uid);
}
seteuid(0); /* this should fail */
if (!getuid() || !geteuid()) {
fatal("setuid: couldn't drop root", 0, 1, 0);
}
}
/*endpwent(); -- is it safe to put this here? */
opterr = 0;
while ((ca = getopt(argc, argv, "wlL:p:uft:h?")) != EOF) {
switch(ca) {
case 'w':
welcome = 1;
break;
case 'l':
heavylogging = 1;
break;
case 'L':
case 'p':
fingerpath = optarg;
break;
case 'u':
nouserlist = 1;
break;
case 'f':
forwarding = 1;
break;
case 't':
patience = atoi(optarg);
break;
case '?':
case 'h':
default:
syslog(LOG_ERR, "usage: fingerd [-wulf]"
"[-pL /path/finger] [-t timeout]");
exit(1);
}
}
argc -= optind;
argv += optind;
/*
* Hang up after a while so people can't DoS by leaving lots of
* open sockets about.
*/
if (patience != 0) {
signal(SIGALRM, timeout);
alarm(patience);
}
if (!fgets(line, sizeof(line), stdin)) {
fatal("Client hung up - probable port-scan", 0, 1, 0);
}
if (welcome) {
char buf[256];
struct hostent *hp;
struct utsname utsname;
uname(&utsname);
gethostname(buf, sizeof(buf));
if ((hp = gethostbyname(buf))) {
/* paranoia: dns spoofing? */
strncpy(buf, hp->h_name, sizeof(buf));
buf[sizeof(buf)-1] = 0;
}
printf("\r\nWelcome to %s version %s at %s !\r\n\n",
utsname.sysname, utsname.release, buf);
fflush(stdout);
switch (fork()) {
case -1: /* fork failed, oh well */
break;
case 0: /* child */
execl(_PATH_UPTIME, _PATH_UPTIME, NULL);
_exit(1);
default: /* parent */
wait(NULL);
break;
}
fflush(stdout);
printf("\r\n");
fflush(stdout);
}
k = nusers = 0;
av[k++] = "finger";
for (s = strtok(line, WS); s && k<ENTRIES; s = strtok(NULL, WS)) {
/* RFC742: "/[Ww]" == "-l" */
if (!strncasecmp(s, "/w", 2)) memcpy(s, "-l", 2);
if (!forwarding) {
t = strchr(s, '@');
if (t) {
fprintf(stderr,
"fingerd: forwarding not allowed\r\n");
syslog(LOG_WARNING, "rejected %s\n", s);
exit(1);
}
}
if (heavylogging) {
if (*s=='-') syslog(LOG_INFO, "option %s\n", s);
else syslog(LOG_INFO, "fingered %s\n", s);
}
av[k++] = s;
if (*s!='-') nusers++;
}
av[k] = NULL;
if (nusers==0) {
/* finger @host */
if (nouserlist) {
syslog(LOG_WARNING, "rejected finger @host\n");
printf("Please supply a username\r\n");
return 0;
}
if (heavylogging) syslog(LOG_INFO, "fingered @host\n");
}
/* Yay! we don't need to do this any more - finger does it for us */
#if 0
if (pipe(p) < 0) {
fatal("pipe", 1, 1, 0);
}
pid = fork();
if (pid<0) {
fatal("fork", 1, 1, 0);
}
if (pid==0) {
/* child */
close(p[0]);
dup2(p[1], 1);
if (p[1]!=1) close(p[1]);
#endif
/*
* execv() takes (char *const *), because (char const *const *)
* doesn't work right in C (only in C++). C9x might fix this
* if we're lucky. In the meantime we need to defeat the type
* system to avoid warnings.
*/
avy = av;
/*avx = avy;*/
memcpy(&avx, &avy, sizeof(avx));
if (fingerpath) execv(fingerpath, avx);
execv(_PATH_FINGER, avx);
execv(_ALT_PATH_FINGER_1, avx);
execv(_ALT_PATH_FINGER_2, avx);
execv(_ALT_PATH_FINGER_3, avx);
syslog(LOG_ERR, "Finger program not found\n");
exit(1);
#if 0
}
/* parent */
close(p[1]);
/* convert \n to \r\n. This should be an option to finger... */
fp = fdopen(p[0], "r");
if (!fp) {
fatal("fdopen", 1, 1, 0);
}
while ((ch = getc(fp)) != EOF) {
if (ch == '\n') putchar('\r');
putchar(ch);
}
return 0;
#endif
}

41
fingerd/pathnames.h Normal file
View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 1989 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)pathnames.h 5.3 (Berkeley) 6/1/90
* $Id: pathnames.h,v 1.3 1996/07/13 23:21:42 dholland Exp $
*/
/*
* These should maybe be determined at configure/install time.
*/
#define _PATH_FINGER "/usr/bin/finger"
#define _PATH_UPTIME "/usr/bin/uptime"

5
version.h Normal file
View File

@ -0,0 +1,5 @@
/*
* String to embed in binaries to identify package
*/
char pkg[]="$NetKit: bsd-finger-0.17 $";