artful finger package: http://archive.ubuntu.com/ubuntu/pool/universe/b/bsd-finger/bsd-finger_0.17.orig.tar.bz2
This commit is contained in:
commit
37c4557418
1
.cvsignore
Normal file
1
.cvsignore
Normal file
@ -0,0 +1 @@
|
|||||||
|
MCONFIG
|
7
BUGS
Normal file
7
BUGS
Normal 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
133
ChangeLog
Normal 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
22
MCONFIG.in
Normal 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
8
MRULES
Normal 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
20
Makefile
Normal 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
118
README
Normal 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
305
configure
vendored
Normal 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
1
finger/.cvsignore
Normal file
@ -0,0 +1 @@
|
|||||||
|
finger
|
18
finger/Makefile
Normal file
18
finger/Makefile
Normal 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
179
finger/display.c
Normal 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
194
finger/finger.1
Normal 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
334
finger/finger.c
Normal 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
119
finger/finger.h
Normal 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
361
finger/lprint.c
Normal 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
155
finger/net.c
Normal 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
172
finger/sprint.c
Normal 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
418
finger/util.c
Normal 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
1
fingerd/.cvsignore
Normal file
@ -0,0 +1 @@
|
|||||||
|
fingerd
|
18
fingerd/Makefile
Normal file
18
fingerd/Makefile
Normal 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
157
fingerd/fingerd.8
Normal 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
295
fingerd/fingerd.c
Normal 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
41
fingerd/pathnames.h
Normal 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"
|
Loading…
Reference in New Issue
Block a user