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