biff-0.17.pre20000412/0040700000175000017500000000000007075260024012057 5ustar memmembiff-0.17.pre20000412/biff/0040700000175000017500000000000007075260024012765 5ustar memmembiff-0.17.pre20000412/biff/.cvsignore0100644000175000017500000000000506767430261015000 0ustar memmembiff biff-0.17.pre20000412/biff/Makefile0100644000175000017500000000043606335777024014452 0ustar memmemall: biff include ../MCONFIG %.o: %.c $(CC) $(CFLAGS) $< -c biff.o: ../version.h biff: biff.o $(CC) $(LDFLAGS) $^ $(LIBS) -o $@ install: biff install -s -m$(BINMODE) biff $(INSTALLROOT)$(BINDIR) install -m$(MANMODE) biff.1 $(INSTALLROOT)$(MANDIR)/man1 clean: rm -f *.o biff biff-0.17.pre20000412/biff/biff.10100644000175000017500000000651207075224454013777 0ustar memmem.\" Copyright (c) 1980, 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: @(#)biff.1 6.5 (Berkeley) 3/14/91 .\" $Id: biff.1,v 1.14 2000/04/13 01:55:56 dholland Exp $ .\" .Dd July 31, 1999 .Dt BIFF 1 .Os "Linux NetKit (0.17-pre-20000412)" .Sh NAME .Nm biff .Nd "be notified if mail arrives and who it is from" .Sh SYNOPSIS .Nm biff .Op Cm ny .Sh DESCRIPTION .Nm Biff informs the system whether you want to be notified when mail arrives during the current terminal session. .Pp Options supported by .Nm biff : .Bl -tag -width 4n .It Cm n Disables notification. .It Cm y Enables notification. .El .Pp When mail notification is enabled, the header and first few lines of the message will be printed on your screen whenever mail arrives. A .Dq Li biff y command is often included in the file .Pa \&.login or .Pa \&.profile to be executed at each login. .Pp .Nm Biff operates asynchronously via the .Xr comsat 8 service. If that service is not enabled, .Nm biff will not do anything. In that case, or for synchronous notification, use the .Ar MAIL variable of .Xr sh 1 or the .Ar mail variable of .Xr csh 1 . .Sh SEE ALSO .Xr csh 1 , .Xr mail 1 , .Xr sh 1 , .Xr comsat 8 .Sh HISTORY The .Nm command appeared in .Bx 4.0 . .Sh BUGS .Xr su 1 , and biff don't seem to get on too well. This is probably due to the tty still being owned by the person using su. This can result in .Dq Li Permission denied messages when attempting to change the biff status of your session. .Pp Please report bugs to netbug@ftp.uk.linux.org including diffs/patches, compiler error logs or as complete a bug report as is possible. biff-0.17.pre20000412/biff/biff.c0100644000175000017500000000666007024720337014060 0ustar memmem/* * Copyright (c) 1980 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) 1980 The Regents of the University of California.\n" "All rights reserved.\n"; /* * From: @(#)biff.c 5.3 (Berkeley) 6/1/90 */ char rcsid[] = "$Id: biff.c,v 1.11 1999/12/12 13:19:27 dholland Exp $"; /* * biff */ #include #include #include #include #include "../version.h" int main(int argc, char *argv[]) { char *tty; /* name of tty */ struct stat stb; /* storage for return of stat on tty */ /* * ttyname() returns a pointer to the pathname of the * terminal device that is open on the specified file * descriptor. If this fails tell the user. */ tty = ttyname(STDERR_FILENO); if (tty == NULL) { fprintf(stderr, "stderr is not a tty - where are you?\n"); exit(1); } /* stat() the tty */ if (stat(tty, &stb)==-1) { perror(tty); exit(1); } /* * If no command line arguments are specified then simply return * the current status to the user. */ if (argc == 1) { /* if user execute bit is on (ie biff y) */ if(stb.st_mode&0100) { printf("is y\n"); } else { printf("is n\n"); } } else { /* If there's a command line argument... */ /* switch based on argument */ switch (argv[1][0]) { case 'y': /* user entered biff y */ if (chmod(tty, stb.st_mode|0100) == -1) perror(tty); break; case 'n': /* user entered biff n */ if (chmod(tty, stb.st_mode&~0100) == -1) perror(tty); break; default: /* They used neither of the correct arguments -Doh! */ fprintf(stderr, "usage: biff [y|n]\n"); } } return (stb.st_mode&0100) ? 0 : 1; /* Return 0 if on or 1 if off */ } biff-0.17.pre20000412/.cvsignore0100644000175000017500000000001006775427243014073 0ustar memmemMCONFIG biff-0.17.pre20000412/ChangeLog0100644000175000017500000000353707026450132013645 0ustar memmem14-Dec-99: biff+comsat-0.16 is released. 17-Oct-1999: Comsat now allows ttys in /dev/pts. Also, it now skips utmp entries that aren't marked USER_PROCESS. 14-Sep-1999: Fixed signal blocking in comsat to be POSIX. Fixed (or at least patched) comsat DoS attack by sleeping 0.1 seconds in the parent process after every fork. (Otherwise you can flood the system with comsat processes, bypassing any process quotas.) 1-Aug-1999: Complete y2k and y2038 audit. 31-Jul-1999: Redid makefiles/config stuff for new confgen version. 12-Jun-1997: biff+comsat-0.10 released. 08-Jun-1997: More adjustments for glibc. 19-May-1997: Fix a year-2038 bug in comsat: a time variable was int, not time_t. 05-Apr-1997: Added configure script to generate MCONFIG. Better utmp handling in comsat. 08-Mar-1997: Split from full NetKit package. Generated this change log from NetKit's. 29-Dec-1996 NetKit-0.09 released. Hardened programs against DNS h_length spoofing attacks. Use inet_aton() everywhere instead of inet_addr(). 22-Aug-1996 NetKit-B-0.08 released. (almost) everything now compiles with lots of warnings turned on. 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. 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. date not known NetKit-B-0.05 released. date not known NetKit-B-0.04 released. Changes to comsat and biff from newer NetBSD versions. date not known NetKit-B-0.03 released. biff-0.17.pre20000412/MCONFIG.in0100644000175000017500000000026006774770341013513 0ustar memmem# Dirs INSTALLROOT BINDIR SBINDIR MANDIR # Modes BINMODE DAEMONMODE MANMODE # Compiling ALLWARNINGS CC CFLAGS LDFLAGS LIBS # Features BSDSIGNAL FN(snprintf) TYPE(socklen_t) biff-0.17.pre20000412/Makefile0100644000175000017500000000074607024720301013526 0ustar memmem# 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 = biff comsat %.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 biff-0.17.pre20000412/README0100644000175000017500000000661107075253344012761 0ustar memmemThis is biff+comsat-0.17-pre-20000412 for Linux. This package updates biff+comsat-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: comsat Daemon for asynchronous new mail notification biff Control program for comsat Requires: Working compiler, libc, and kernel. Security: This release contains no security fixes relative to biff+comsat 0.16. However, versions prior to NetKit-0.09 should not be used. 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. After this release is finalized, if there are no immediate problems, I plan to hand over the source tree to Red Hat for subsequent maintenance, unless some alternative arrangements can be made. David A. Holland 12 April 2000 biff-0.17.pre20000412/configure0100755000175000017500000002043207024765410014001 0ustar memmem#!/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 < __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 BSD signal semantics... ' cat <__conftest.c #include #include int count=0; void handle(int foo) { count++; } int main() { int pid=getpid(); signal(SIGINT, handle); kill(pid,SIGINT); kill(pid,SIGINT); kill(pid,SIGINT); if (count!=3) return 1; return 0; } EOF if ( $CC $CFLAGS __conftest.c -o __conftest || exit 1 ./__conftest || exit 1 ) >/dev/null 2>&1; then echo 'yes' else if ( $CC $CFLAGS -D__USE_BSD_SIGNAL __conftest.c -o __conftest || exit 1 ./__conftest || exit 1 ) >/dev/null 2>&1; then echo '-D__USE_BSD_SIGNAL' CFLAGS="$CFLAGS -D__USE_BSD_SIGNAL" else echo 'no' echo 'This package needs BSD signal semantics to run.' rm -f __conftest* exit fi fi rm -f __conftest* ################################################## echo -n 'Checking for socklen_t... ' cat <__conftest.c #include #include #include 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 <__conftest.c #include 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 <__conftest.c #include #include #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 biff-0.17.pre20000412/version.h0100644000175000017500000000016207075224453013731 0ustar memmem/* * String to embed in binaries to identify package */ char pkg[]="$NetKit: biff+comsat-0.17-pre-20000412 $"; biff-0.17.pre20000412/comsat/0040700000175000017500000000000007075260024013345 5ustar memmembiff-0.17.pre20000412/comsat/.cvsignore0100644000175000017500000000000706767430261015362 0ustar memmemcomsat biff-0.17.pre20000412/comsat/Makefile0100644000175000017500000000056406750663032015026 0ustar memmemall: comsat include ../MCONFIG %.o: %.c $(CC) $(CFLAGS) $< -c comsat.o: ../version.h comsat: comsat.o $(CC) $(LDFLAGS) $^ $(LIBS) -o $@ install: comsat install -s -m$(DAEMONMODE) comsat $(INSTALLROOT)$(SBINDIR)/in.comsat install -m$(MANMODE) comsat.8 $(INSTALLROOT)$(MANDIR)/man8/in.comsat.8 ln -sf in.comsat.8 $(MANDIR)/man8/comsat.8 clean: rm -f *.o comsat biff-0.17.pre20000412/comsat/comsat.80100644000175000017500000000700607075224454014745 0ustar memmem.\" Copyright (c) 1983, 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: @(#)comsat.8 6.5 (Berkeley) 3/16/91 .\" $Id: comsat.8,v 1.12 2000/04/13 01:55:56 dholland Exp $ .\" .Dd July 31, 1999" .Dt COMSAT 8 .Os "Linux NetKit (0.17-pre-20000412)" .Sh NAME .Nm comsat .Nd biff server .Sh SYNOPSIS .Nm comsat .Sh DESCRIPTION .Nm Comsat is the server process which receives reports of incoming mail and notifies users if they have requested this service. .Nm Comsat receives messages on a datagram port associated with the .Dq biff service specification (see .Xr services 5 and .Xr inetd 8 ) . The one line messages are of the form: .Pp .Dl user@mailbox-offset .Pp If the .Em user specified is logged in to the system and the associated terminal has the owner execute bit turned on (by a .Dq Li biff y ) , the .Em offset is used as a seek offset into the appropriate mailbox file and the first 7 lines or 560 characters of the message are printed on the user's terminal. Lines which appear to be part of the message header other than the .Dq From or .Dq Subject lines are not included in the output. .Sh FILES .Bl -tag -width /var/run/utmp -compact .It Pa /var/run/utmp to find out who's logged on and on what terminals .El .Sh SEE ALSO .Xr biff 1 , .Xr inetd 8 .Sh BUGS The message header filtering is prone to error. The density of the information presented is near the theoretical minimum. .Pp Users should be notified of mail which arrives on other machines than the one to which they are currently logged in. .Pp The notification should appear in a separate window so it does not mess up the screen. .Pp Please report bugs to netbug@ftp.uk.linux.org and include diffs/patches, compiler error logs or as complete a bug report as you are able. .Sh HISTORY The .Nm daemon appeared in .Bx 4.2 . biff-0.17.pre20000412/comsat/comsat.c0100644000175000017500000003220207002454527015010 0ustar memmem/* * Copyright (c) 1980 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) 1980 Regents of the University of California.\n" "All rights reserved.\n"; /* * From: @(#)comsat.c 5.24 (Berkeley) 2/25/91 */ char rcsid[] = "$Id: comsat.c,v 1.17 1999/10/17 23:18:47 dholland Exp $"; #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* used for _PATH_MAILDIR, _PATH_UTMP, etc. */ #include #include #include "../version.h" static int debug = 0; #define dsyslog if (debug) syslog #define MAXIDLE 120 static char hostname[MAXHOSTNAMELEN]; static struct utmp *utmp = NULL; static time_t lastmsgtime; static int nutmp; static void mailfor(char *name); static void notify(struct utmp *utp, off_t offset); static void jkfprintf(FILE *, const char *name, off_t offset, const char *cr); static void onalrm(int); int main(void) { char msgbuf[100]; /* network input buffer */ struct sockaddr_in from; /* name of socket */ socklen_t fromlen; /* holds sizeof(from) */ /* * Verify proper invocation: get the address of the local socket * that's supposed to be our stdin. If it's not a socket (the only * likely error) assume we were inadvertently run from someone's * shell and quit out. */ fromlen = sizeof(from); if (getsockname(0, (struct sockaddr *)&from, &fromlen) < 0) { fprintf(stderr, "comsat: getsockname: %s.\n", strerror(errno)); exit(1); } /* * openlog() opens a connection to the system logger for comsat. * We log as "comsat", with the process id, to the "LOG_DAEMON" * log channel. */ openlog("comsat", LOG_PID, LOG_DAEMON); /* * Schlep over to the system mail spool. */ if (chdir(_PATH_MAILDIR)) { syslog(LOG_ERR, "chdir: %s: %m", _PATH_MAILDIR); exit(1); } /* * Record the time of the last message received (the one that * caused us to be run) so we can idle out later. */ time(&lastmsgtime); /* * Grab our hostname for spewing to the user's screen. */ gethostname(hostname, sizeof(hostname)); /* * Make sure we won't get stopped by scribbling on the user's screen. */ signal(SIGTTOU, SIG_IGN); /* * This declares that we're not interested in child processes' * exit codes, so they will go away on their own without needing * to be wait()'d for. */ signal(SIGCHLD, SIG_IGN); /* * Periodically reread the utmp, starting now. */ signal(SIGALRM, onalrm); onalrm(SIGALRM); /* * Loop forever handling biff packets. */ for (;;) { sigset_t sigset; int cc; errno = 0; cc = recv(0, msgbuf, sizeof(msgbuf) - 1, 0); if (cc <= 0) { if (errno != EINTR) sleep(1); continue; } if (!nutmp) { /* utmp is empty: no one is logged in */ continue; } /* Make sure we don't get SIGALRM while doing mailfor() */ sigemptyset(&sigset); sigaddset(&sigset, SIGALRM); sigprocmask(SIG_BLOCK, &sigset, NULL); /* null-terminate input */ msgbuf[cc] = 0; /* update time stamp */ time(&lastmsgtime); /* biff the user */ mailfor(msgbuf); /* allow SIGALRM again */ sigprocmask(SIG_UNBLOCK, &sigset, NULL); } } /* * This function is called at startup and every fifteen seconds while * we're running, via timer signals. */ static void onalrm(int signum) { static int utmpsize; /* last malloced size for utmp */ static time_t utmpmtime; /* last modification time for utmp */ struct stat statbuf; /* scratch storage for stat() */ struct utmp *uptr; int maxutmp; /* * Defensive programming (this should not happen) */ if (signum!=SIGALRM) { dsyslog(LOG_DEBUG, "wild signal %d\n", signum); return; } /* * If we've been sitting around doing nothing, go away. */ if (time(NULL) - lastmsgtime >= MAXIDLE) { exit(0); } /* * Come back here in another fifteen seconds. */ alarm(15); /* * Check the modification time of the utmp file. */ if (stat(_PATH_UTMP, &statbuf) < 0) { dsyslog(LOG_DEBUG, "fstat of utmp failed: %m\n"); return; } if (statbuf.st_mtime > utmpmtime) { /* * utmp has changed since we last came here; reread it and * save the modification time. */ utmpmtime = statbuf.st_mtime; /* * If it's now bigger than the space we have for it, * get more space. */ if (statbuf.st_size > utmpsize) { utmpsize = statbuf.st_size + 10 * sizeof(struct utmp); if (utmp) { utmp = realloc(utmp, utmpsize); } else { utmp = malloc(utmpsize); } if (!utmp) { syslog(LOG_ERR, "malloc failed: %m"); exit(1); } } /* This is how many utmp entries we can possibly get */ maxutmp = utmpsize / sizeof(struct utmp); /* Rewind the utmp file */ setutent(); /* * Read the utmp file, via libc, copying each entry and * counting how many we get. */ nutmp = 0; while ((uptr = getutent())!=NULL && nutmp < maxutmp) { utmp[nutmp] = *uptr; nutmp++; } /* Now done; close the utmp file. */ endutent(); } } /* * We get here when we have mail to announce for the specified user. * "name" holds a biff packet, which comes in the form * username@fileoffset */ static void mailfor(char *name) { struct utmp *utp; char *cp; off_t offset; /* Break off the file offset part and convert it to an integer. */ cp = strchr(name, '@'); if (!cp) return; *cp = 0; offset = atol(cp + 1); /* Look through the utmp and call notify() for each matching login. */ utp = &utmp[nutmp]; while (--utp >= utmp) { if (!strncmp(utp->ut_name, name, sizeof(utmp[0].ut_name))) notify(utp, offset); } } /* * Check if a given tty name found in utmp is actually a legitimate tty. */ static int valid_tty(const char *line) { const char *testline = line; /* * As of Linux 2.2 we can now sometimes have ttys in subdirs, * but only /dev/pts. So if the name begins with pts/, skip that * part. If there's a slash in anything else, complain loudly. */ if (!strncmp(testline, "pts/", 4)) testline += 4; if (strchr(testline, '/')) { /* A slash is an attempt to break security... */ return 0; } return 1; } /* * This actually writes to the user's terminal. */ static void notify(struct utmp *utp, off_t offset) { FILE *tp; /* file open on tty */ struct stat stb; struct termios tbuf; char tty[sizeof(utp->ut_line)+sizeof(_PATH_DEV)+1]; /* full tty path */ char name[sizeof(utp->ut_name) + 1]; /* user name */ char line[sizeof(utp->ut_line) + 1]; /* tty name */ const char *cr; /* line delimiter */ sigset_t sigset; /* scratch signal mask */ #ifdef USER_PROCESS if (utp->ut_type != USER_PROCESS) { return; } #endif /* * Be careful in case we have a hostile utmp. (Remember sunos4 * where it was mode 666?) Note that ut_line normally includes * enough space for the null-terminator, but ut_name doesn't. */ strncpy(line, utp->ut_line, sizeof(utp->ut_line)); line[sizeof(utp->ut_line)] = 0; strncpy(name, utp->ut_name, sizeof(utp->ut_name)); name[sizeof(name) - 1] = '\0'; /* Get the full path to the tty. */ snprintf(tty, sizeof(tty), "%s%s", _PATH_DEV, line); /* * Again, in case we have a hostile utmp, try to make sure we've * got valid data and we're not being asked to write to, say, * /etc/passwd. */ if (!valid_tty(line)) { syslog(LOG_AUTH | LOG_NOTICE, "invalid tty \"%s\" in utmp", tty); return; } /* * If the user's tty isn't mode u+x, they don't want biffage; * skip them. */ if (stat(tty, &stb) || !(stb.st_mode & S_IEXEC)) { dsyslog(LOG_DEBUG, "%s: wrong mode on %s", name, tty); return; } dsyslog(LOG_DEBUG, "notify %s on %s\n", name, tty); /* * Fork a child process to do the tty I/O. There are, traditionally, * various ways for tty I/O to block indefinitely or otherwise hang. * Also later down we're going to setuid to make sure we can't be * used to read any file on the system. * * This of course makes a denial of service attack possible. So, * in the parent process, wait a tenth of a second before continuing. * This causes a primitive form of rate-limiting. It might be too * much delay for a busy system. But a busy system probably shouldn't * be using comsat. If someone would like to make this smarter, feel * free. * * Note: sleep with select() and NOT sleep() because on some systems * at least sleep uses alarm(), which would interfere with our * reload/timeout logic. */ if (fork()) { /* parent process */ struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 100000; select(0, NULL, NULL, NULL, &tv); return; } /* child process */ /* * Turn off the alarm handler and instead exit in thirty seconds. * Make sure SIGALRM isn't blocked. */ signal(SIGALRM, SIG_DFL); sigemptyset(&sigset); sigprocmask(SIG_SETMASK, &sigset, NULL); alarm(30); /* * Open the tty. */ if ((tp = fopen(tty, "w")) == NULL) { dsyslog(LOG_ERR, "fopen of tty %s failed", tty); _exit(-1); } /* * Get the tty mode. Try to determine whether to use \n or \r\n * for linebreaks. */ tcgetattr(fileno(tp), &tbuf); if ((tbuf.c_oflag & OPOST) && (tbuf.c_oflag & ONLCR)) cr = "\n"; else cr = "\r\n"; /* * Announce the mail. */ fprintf(tp, "%s\aNew mail for %s@%.*s\a has arrived:%s----%s", cr, name, (int)sizeof(hostname), hostname, cr, cr); /* * Print the first few lines of the message. */ jkfprintf(tp, name, offset, cr); /* * Close up and quit the child process. */ fclose(tp); _exit(0); } /* * This prints a few lines from the mailbox of the user "name" at offset * "offset", using "cr" as the line break string, to the file "tp". */ static void jkfprintf(FILE *tp, const char *name, off_t offset, const char *cr) { char *cp, ch; FILE *fi; int linecnt, charcnt, inheader; struct passwd *p; char line[BUFSIZ]; /* * Set uid to user in case mail drop is on nfs * ...and also to prevent cute symlink to /etc/shadow games */ if ((p = getpwnam(name)) == NULL) { /* * If user is not in passwd file, assume that it's * an attempt to break security... */ syslog(LOG_AUTH | LOG_NOTICE, "%s not in passwd file", name); return; } /* * This sets both real and effective uids and clears the saved uid * too (see posix) so it's a one-way trip. */ setuid(p->pw_uid); /* * Open the user's mailbox (recall we're already in the mail spool dir) */ fi = fopen(name, "r"); if (fi == NULL) return; /* Move to requested offset */ fseek(fi, offset, L_SET); /* * Print the first 7 lines or 560 characters of the new mail * (whichever comes first). Skip header crap other than * From and Subject. */ linecnt = 7; charcnt = 560; inheader = 1; while (fgets(line, sizeof(line), fi) != NULL) { if (inheader) { if (line[0] == '\n') { inheader = 0; continue; } if (line[0] == ' ' || line[0] == '\t' || (strncasecmp(line, "From:", 5) && strncasecmp(line, "Subject:", 8))) continue; } if (linecnt <= 0 || charcnt <= 0) { fprintf(tp, "...more...%s", cr); fclose(fi); return; } /* strip weird stuff so can't trojan horse stupid terminals */ for (cp = line; (ch = *cp) && ch != '\n'; ++cp, --charcnt) { ch = toascii(ch); if (!isprint(ch) && !isspace(ch)) ch |= 0x40; fputc(ch, tp); } fputs(cr, tp); --linecnt; } fprintf(tp, "----%s", cr); fclose(fi); }