netkit-rwho-0.17/ 40700 144 144 0 7141142024 13104 5ustar dhollandpeoplenetkit-rwho-0.17/rwho/ 40700 144 144 0 7141142024 14063 5ustar dhollandpeoplenetkit-rwho-0.17/rwho/.cvsignore100644 144 144 5 6774165557 16140 0ustar dhollandpeoplerwho netkit-rwho-0.17/rwho/Makefile100644 144 144 450 7024761721 15624 0ustar dhollandpeopleall: rwho include ../MCONFIG include ../MRULES CFLAGS += -I../include rwho: rwho.o $(CC) $(LDFLAGS) $^ $(LIBS) -o $@ rwho.o: ../version.h install: rwho install -s -m$(BINMODE) rwho $(INSTALLROOT)$(BINDIR) install -m$(MANMODE) rwho.1 $(INSTALLROOT)$(MANDIR)/man1/ clean: rm -f *.o rwho netkit-rwho-0.17/rwho/rwho.1100644 144 144 5702 7141140322 15236 0ustar dhollandpeople.\" Copyright (c) 1983, 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: @(#)rwho.1 6.7 (Berkeley) 4/23/91 .\" $Id: rwho.1,v 1.12 2000/07/30 23:57:06 dholland Exp $ .\" .Dd August 15, 1999 .Dt RWHO 1 .Os "Linux NetKit (0.17)" .Sh NAME .Nm rwho .Nd who is logged in on local machines .Sh SYNOPSIS .Nm rwho .Op Fl a .Sh DESCRIPTION The .Nm rwho command produces output similar to .Xr who , but for all machines on the local network. If no report has been received from a machine for 11 minutes then .Nm rwho assumes the machine is down, and does not report users last known to be logged into that machine. .Pp If a users hasn't typed to the system for a minute or more, then .Nm rwho reports this idle time. If a user hasn't typed to the system for an hour or more, then the user will be omitted from the output of .Nm rwho unless the .Fl a flag is given. .Sh FILES .Bl -tag -width /var/spool/rwho/rwhod.* -compact .It Pa /var/spool/rwho/whod.* information about other machines .El .Sh SEE ALSO .Xr finger 1 , .Xr rup 1 , .Xr ruptime 1 , .Xr rusers 1 , .Xr who 1 , .Xr rwhod 8 .Sh HISTORY The .Nm rwho command appeared in .Bx 4.3 . .Sh BUGS This is unwieldy when the number of machines on the local net is large. netkit-rwho-0.17/rwho/rwho.c100644 144 144 15054 6751130642 15353 0ustar dhollandpeople/* * 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: @(#)rwho.c 5.5 (Berkeley) 6/1/90 */ char rcsid[] = "$Id: rwho.c,v 1.7 1999/08/01 20:44:18 dholland Exp $"; #include #include #include #include #include #include #include #include #include #include #include "../version.h" static int utmpcmp(const void *, const void *); #define NUSERS 1000 struct myutmp { char myhost[MAXHOSTNAMELEN]; int myidle; char myline[PATH_MAX]; char myname[16]; time_t mytime; }; #define WHDRSIZE ((int)(sizeof (wd) - sizeof (wd.wd_we))) /* * this function should be shared with ruptime. */ static int down(time_t rcv, time_t now) { return (now - rcv > 11 * 60); } int main(int argc, char *argv[]) { static struct myutmp myutmp[NUSERS]; int nusers = 0; int ch; struct direct *dp; int cc, width; struct whod wd; struct whod *w = &wd; struct whoent *we; struct myutmp *mp; int f, n, i; DIR *dirp; time_t now, myrecvtime, timecorrection; int aflg = 0; size_t size; while ((ch = getopt(argc, argv, "a")) != EOF) { switch((char)ch) { case 'a': aflg = 1; break; case '?': default: fprintf(stderr, "usage: rwho [-a]\n"); exit(1); } } if (chdir(_PATH_RWHODIR) || (dirp = opendir(".")) == NULL) { perror(_PATH_RWHODIR); exit(1); } mp = myutmp; time(&now); while ((dp = readdir(dirp))!=NULL) { if (dp->d_ino == 0 || strncmp(dp->d_name, "whod.", 5)) { continue; } f = open(dp->d_name, O_RDONLY); if (f < 0) { continue; } cc = read(f, (char *)&wd, sizeof (struct whod)); if (cc < WHDRSIZE) { (void) close(f); continue; } myrecvtime = w->wd_recvtime; /* * After 2038 the rwho protocol, which sends int32s, will * start to lose. However, by then, "now" will be an int64. * So assume that if "now" is WAY bigger than myrecvtime, * the latter needs to be incremented by 2^32. 0x40000000 is * 34 years, so it's _fairly_ safe to assume we won't have * any packets that old in /var/spool/rwho. * Increment the correction by values < 2^31 so it works * if time_t is still an int32. Save the correction for * use on the login times. */ timecorrection = 0; while (now - myrecvtime + timecorrection > 0x40000000) { timecorrection += 0x70000000; timecorrection += 0x70000000; timecorrection += 0x20000000; } if (down(myrecvtime, now)) { (void) close(f); continue; } cc -= WHDRSIZE; we = w->wd_we; for (n = cc / sizeof (struct whoent); n > 0; n--) { if (aflg == 0 && we->we_idle >= 60*60) { we++; continue; } if (nusers >= NUSERS) { printf("too many users\n"); exit(1); } /* * Copy hostname. rwhod is supposed to make sure * wd_hostname is null-terminated, but be defensive. */ size = sizeof(w->wd_hostname); if (size > sizeof(mp->myhost)) { size = sizeof(mp->myhost); } strncpy(mp->myhost, w->wd_hostname, size); mp->myhost[size-1] = 0; mp->myidle = we->we_idle; /* * rwhod does not guarantee null-termination of * the strings in we_utmp. */ assert(sizeof(mp->myline) > sizeof(we->we_utmp.out_line)); assert(sizeof(mp->myname) > sizeof(we->we_utmp.out_name)); strncpy(mp->myline, we->we_utmp.out_line, sizeof(we->we_utmp.out_line)); mp->myline[sizeof(we->we_utmp.out_line)] = 0; strncpy(mp->myname, we->we_utmp.out_name, sizeof(we->we_utmp.out_name)); mp->myname[sizeof(we->we_utmp.out_name)] = 0; mp->mytime = we->we_utmp.out_time + timecorrection; nusers++; we++; mp++; } (void) close(f); } qsort(myutmp, nusers, sizeof(struct myutmp), utmpcmp); mp = myutmp; width = 0; for (i = 0; i < nusers; i++) { int j = strlen(mp->myhost) + 1 + strlen(mp->myline); if (j > width) width = j; mp++; } mp = myutmp; for (i = 0; i < nusers; i++) { char buf[BUFSIZ]; snprintf(buf, sizeof(buf), "%s:%s", mp->myhost, mp->myline); printf("%-8.8s %-*s %.12s", mp->myname, width, buf, ctime(&mp->mytime)+4); mp->myidle /= 60; if (mp->myidle) { if (aflg) { if (mp->myidle >= 100*60) mp->myidle = 100*60 - 1; if (mp->myidle >= 60) printf(" %2d", mp->myidle / 60); else printf(" "); } else printf(" "); printf(":%02d", mp->myidle % 60); } printf("\n"); mp++; } exit(0); } static int utmpcmp(const void *v1, const void *v2) { const struct myutmp *u1 = (const struct myutmp *)v1; const struct myutmp *u2 = (const struct myutmp *)v2; int rc; rc = strcmp(u1->myname, u2->myname); if (rc) return (rc); rc = strcmp(u1->myhost, u2->myhost); if (rc) return (rc); return (strcmp(u1->myline, u2->myline)); } netkit-rwho-0.17/.cvsignore100644 144 144 10 7024703557 15160 0ustar dhollandpeopleMCONFIG netkit-rwho-0.17/ChangeLog100644 144 144 4732 7136461711 15006 0ustar dhollandpeople22-Jul-2000: Add some minor additional paranoia. Changes from Olaf Kirch to run chrooted to /var/spool/rwho and then optionally drop root privileges. 3-Jun-2000: Fix sizes of types in enclosed protocols/rwhod.h. 14-Dec-1999: netkit-rwho-0.16 is released. 1-Aug-1999: Complete y2k and y2038 audit. Clean up y2038 issues. Clean up buffer problems in rwho (apparently unexploitable, fortunately.) 31-Jul-1999: Redid makefiles/config stuff for new confgen version. 23-Sep-1997: Added ruptime. Fixed a suspicious strncpy in rwhod. 12-Jun-1997: netkit-rwho-0.10 released. 08-Jun-1997: More adjustments for glibc. 19-May-1997: glibc fixes from Red Hat. 13-May-1997: Patch from Debian to support selective use of interfaces in rwhod. (via Peter Tobias, tobias@et-inf.fho-emden.de) 05-Apr-1997: Added configure script to generate MCONFIG. Ensure null termination of certain input data. (Peter Tobias, tobias@et-inf.fho-emden.de) Better utmp handling in rwhod. 08-Mar-1997: Split from full NetKit package. Generated this change log from NetKit's. 29-Dec-1996 NetKit-0.09 released. 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(). 22-Aug-1996 NetKit-B-0.08 released. (almost) everything now compiles with lots of warnings turned on. Fixed rwhod not to need -lbsd. Fixed possible buffer overrun hole in rwhod. 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. 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. date not known NetKit-B-0.03 released. Changed rusers, rpc.ruserd, rwall, rpc.rwalld, rwho, rwhod to not require to copy ./include/*.h files into /usr/include netkit-rwho-0.17/MCONFIG.in100644 144 144 240 6750761155 14622 0ustar dhollandpeople# Dirs INSTALLROOT BINDIR MANDIR SBINDIR # Modes BINMODE DAEMONMODE MANMODE # Compiling ALLWARNINGS CC CFLAGS LDFLAGS LIBS # Features BSDSIGNAL FN(snprintf) netkit-rwho-0.17/MRULES100644 144 144 173 6310307153 14131 0ustar dhollandpeople# Standard compilation rules (don't use make builtins) %.o: %.c $(CC) $(CFLAGS) $< -c %.o: %.cc $(CC) $(CFLAGS) $< -c netkit-rwho-0.17/Makefile100644 144 144 755 7024720306 14647 0ustar dhollandpeople# 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 = rwho rwhod ruptime %.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 netkit-rwho-0.17/README100644 144 144 7171 7141137776 14123 0ustar dhollandpeopleThis is netkit-rwho-0.17 for Linux. This package updates netkit-rwho-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: ruptime Program to print LAN uptimes rwho Program to print current LAN user logins rwhod Daemon to maintain data for rwho/ruptime Requires: Working compiler, libc, and kernel. Security: This release contains no known security fixes relative to netkit-rwho-0.16. However, it contains patches to enable running as a non-root user in a chroot area, so it provides a definite increment in security. Versions prior to NetKit-0.09 should not be used under any circumstances. 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 netkit-rwho-0.17/configure100755 144 144 16170 7140615675 15167 0ustar dhollandpeople#!/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 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 netkit-rwho-0.17/version.h100644 144 144 145 7141140322 15030 0ustar dhollandpeople/* * String to embed in binaries to identify package */ char pkg[]="$NetKit: netkit-rwho-0.17 $"; netkit-rwho-0.17/include/ 40700 144 144 0 7141142024 14527 5ustar dhollandpeoplenetkit-rwho-0.17/include/protocols/ 40700 144 144 0 7141142024 16553 5ustar dhollandpeoplenetkit-rwho-0.17/include/protocols/rwhod.h100644 144 144 5333 7116232632 20171 0ustar dhollandpeople/* * 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. * * from: @(#)rwhod.h 5.6 (Berkeley) 4/3/91 * $Id: rwhod.h,v 1.3 2000/06/03 16:43:06 dholland Exp $ */ #ifndef _RWHOD_H_ #define _RWHOD_H_ /* * rwho protocol packet format. */ struct outmp { char out_line[8]; /* tty name */ char out_name[8]; /* user id */ int32_t out_time; /* time on */ }; struct whod { char wd_vers; /* protocol version # */ char wd_type; /* packet type, see below */ char wd_pad[2]; int32_t wd_sendtime; /* time stamp by sender */ int32_t wd_recvtime; /* time stamp applied by receiver */ char wd_hostname[32]; /* hosts's name */ int32_t wd_loadav[3]; /* load average as in uptime */ int32_t wd_boottime; /* time system booted */ struct whoent { struct outmp we_utmp; /* active tty info */ int32_t we_idle; /* tty idle time */ } wd_we[1024 / sizeof (struct whoent)]; }; #define WHODVERSION 1 #define WHODTYPE_STATUS 1 /* host status */ #define _PATH_RWHODIR "/var/spool/rwho" #endif /* !_RWHOD_H_ */ netkit-rwho-0.17/ruptime/ 40700 144 144 0 7141142024 14571 5ustar dhollandpeoplenetkit-rwho-0.17/ruptime/.cvsignore100644 144 144 10 6774165557 16662 0ustar dhollandpeopleruptime netkit-rwho-0.17/ruptime/Makefile100644 144 144 446 6750761155 16345 0ustar dhollandpeopleall: ruptime include ../MCONFIG include ../MRULES CFLAGS += -I../include ruptime: ruptime.o $(CC) $(LDFLAGS) $^ $(LIBS) -o $@ install: ruptime install -s -m$(BINMODE) ruptime $(INSTALLROOT)$(BINDIR) install -m$(MANMODE) ruptime.1 $(INSTALLROOT)$(MANDIR)/man1/ clean: rm -f *.o ruptime netkit-rwho-0.17/ruptime/ruptime.1100644 144 144 5554 7141140322 16457 0ustar dhollandpeople.\" $OpenBSD: ruptime.1,v 1.3 1997/03/26 00:45:46 deraadt Exp $ .\" Copyright (c) 1983, 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: @(#)ruptime.1 6.9 (Berkeley) 4/23/91 .\" .Dd August 15, 1999 .Dt RUPTIME 1 .Os "Linux NetKit (0.17)" .Sh NAME .Nm ruptime .Nd show host status of local machines .Sh SYNOPSIS .Nm ruptime .Op Fl alrtu .Sh DESCRIPTION .Nm Ruptime gives a status line like .Ar uptime for each machine on the local network; these are formed from packets broadcast by each host on the network once a minute. .Pp Machines for which no status report has been received for 11 minutes are shown as being down. .Pp Options: .Bl -tag -width Ds .It Fl a Users idle an hour or more are not counted unless the .Fl a flag is given. .It Fl l Sort by load average. .It Fl r Reverses the sort order. .It Fl t Sort by uptime. .It Fl u Sort by number of users. .El .Pp The default listing is sorted by host name. .Sh FILES .Bl -tag -width /var/spool/rwho/whod.* -compact .It Pa /var/spool/rwho/whod.* data files .El .Sh SEE ALSO .Xr rup 1 , .Xr rwho 1 , .Xr uptime 1 , .Xr rwhod 8 .Sh HISTORY .Nm Ruptime appeared in .Bx 4.2 . netkit-rwho-0.17/ruptime/ruptime.c100644 144 144 17511 7024740123 16562 0ustar dhollandpeople/* * 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. * * From: @(#)ruptime.c 5.8 (Berkeley) 7/21/90 * From: OpenBSD: ruptime.c,v 1.5 1997/07/06 02:28:55 millert Exp */ char copyright[] = "@(#) Copyright (c) 1983 The Regents of the University of California.\n" "All rights reserved.\n"; char ruptime_rcsid[] = "$Id: ruptime.c,v 1.5 1999/12/12 15:33:39 dholland Exp $"; #include "../version.h" #include #include #include #include #include #include #include #include #include #include struct hs { char hs_hostname[MAXHOSTNAMELEN]; time_t hs_sendtime; time_t hs_recvtime; time_t hs_boottime; int hs_loadav[3]; int hs_nusers; }; #define ISDOWN(h) (now - (h)->hs_recvtime > 11 * 60) #define WHDRSIZE ((int)(sizeof (awhod) - sizeof (awhod.wd_we))) static size_t nhosts, hspace = 20; static struct hs *hs; static struct whod awhod; static time_t now; static int rflg = 1; static int hscmp(const void *, const void *); static int ucmp(const void *, const void *); static int lcmp(const void *, const void *); static int tcmp(const void *, const void *); static const char *interval(time_t tval, const char *updown); static void morehosts(void); int main(int argc, char **argv) { register struct hs *hsp; register struct whod *wd; register struct whoent *we; register DIR *dirp; struct dirent *dp; int aflg, cc, ch, f, maxloadav; unsigned i; char buf[sizeof(struct whod)]; int (*cmp)(const void *, const void *) = hscmp; time_t correction; aflg = 0; while ((ch = getopt(argc, argv, "alrut")) != -1) switch((char)ch) { case 'a': aflg = 1; break; case 'l': cmp = lcmp; break; case 'r': rflg = -1; break; case 't': cmp = tcmp; break; case 'u': cmp = ucmp; break; default: (void)fprintf(stderr, "usage: ruptime [-alrut]\n"); exit(1); } if (chdir(_PATH_RWHODIR) || (dirp = opendir(".")) == NULL) { (void)fprintf(stderr, "ruptime: %s: %s.\n", _PATH_RWHODIR, strerror(errno)); exit(1); } morehosts(); hsp = hs; maxloadav = -1; while ((dp = readdir(dirp))) { if (dp->d_ino == 0 || strncmp(dp->d_name, "whod.", 5)) continue; if ((f = open(dp->d_name, O_RDONLY, 0)) < 0) { (void)fprintf(stderr, "ruptime: %s: %s\n", dp->d_name, strerror(errno)); continue; } cc = read(f, buf, sizeof(struct whod)); (void)close(f); if (cc < WHDRSIZE) continue; if (nhosts == hspace) { morehosts(); hsp = hs + nhosts; } wd = (struct whod *)buf; snprintf(hsp->hs_hostname, sizeof(hsp->hs_hostname), "%s", wd->wd_hostname); /* * y2038 issue. rwhod protocol sends int32 times; * assume they're not more than a few years old, and * correct. Add in values < 0x80000000 so it works if * time_t's 32-bit. */ correction = 0; while (now - wd->wd_sendtime + correction > 0x40000000) { correction += 0x70000000; correction += 0x70000000; correction += 0x20000000; } hsp->hs_sendtime = wd->wd_sendtime + correction; hsp->hs_recvtime = wd->wd_recvtime + correction; hsp->hs_boottime = wd->wd_boottime + correction; hsp->hs_loadav[0] = wd->wd_loadav[0]; hsp->hs_loadav[1] = wd->wd_loadav[1]; hsp->hs_loadav[2] = wd->wd_loadav[2]; hsp->hs_nusers = 0; for (i = 0; i < 2; i++) if (wd->wd_loadav[i] > maxloadav) maxloadav = wd->wd_loadav[i]; we = (struct whoent *)(buf+cc); while (--we >= wd->wd_we) if (aflg || we->we_idle < 3600) hsp->hs_nusers++; nhosts++; hsp++; } if (!nhosts) { (void)printf("ruptime: no hosts in %s.\n", _PATH_RWHODIR); exit(1); } (void)time(&now); qsort(hs, nhosts, sizeof(hs[0]), cmp); for (i = 0; i < nhosts; i++) { hsp = &hs[i]; if (ISDOWN(hsp)) { (void)printf("%-12.12s%s\n", hsp->hs_hostname, interval(now - hsp->hs_recvtime, "down")); continue; } (void)printf( "%-12.12s%s, %4d user%s load %*.2f, %*.2f, %*.2f\n", hsp->hs_hostname, interval((time_t)hsp->hs_sendtime - (time_t)hsp->hs_boottime, " up"), hsp->hs_nusers, hsp->hs_nusers == 1 ? ", " : "s,", maxloadav >= 1000 ? 5 : 4, hsp->hs_loadav[0] / 100.0, maxloadav >= 1000 ? 5 : 4, hsp->hs_loadav[1] / 100.0, maxloadav >= 1000 ? 5 : 4, hsp->hs_loadav[2] / 100.0); } exit(0); } static const char * interval(time_t tval, const char *updown) { static char resbuf[32]; int days, hours, minutes; if (tval < 0 || tval > 999*24*60*60) { (void)snprintf(resbuf, sizeof(resbuf), "%s ??:??", updown); return(resbuf); } minutes = (tval + 59) / 60; /* round to minutes */ hours = minutes / 60; minutes %= 60; days = hours / 24; hours %= 24; if (days) (void)snprintf(resbuf, sizeof(resbuf), "%s %3d+%02d:%02d", updown, days, hours, minutes); else (void)snprintf(resbuf, sizeof(resbuf), "%s %2d:%02d", updown, hours, minutes); return(resbuf); } /* alphabetical comparison */ static int hscmp(const void *a1, const void *a2) { const struct hs *h1 = a1, *h2 = a2; return(rflg * strcmp(h1->hs_hostname, h2->hs_hostname)); } /* load average comparison */ static int lcmp(const void *a1, const void *a2) { const struct hs *h1 = a1, *h2 = a2; if (ISDOWN(h1)) if (ISDOWN(h2)) return(tcmp(a1, a2)); else return(rflg); else if (ISDOWN(h2)) return(-rflg); else return(rflg * (h2->hs_loadav[0] - h1->hs_loadav[0])); } /* number of users comparison */ static int ucmp(const void *a1, const void *a2) { const struct hs *h1 = a1, *h2 = a2; if (ISDOWN(h1)) if (ISDOWN(h2)) return(tcmp(a1, a2)); else return(rflg); else if (ISDOWN(h2)) return(-rflg); else return(rflg * (h2->hs_nusers - h1->hs_nusers)); } /* uptime comparison */ static int tcmp(const void *a1, const void *a2) { const struct hs *h1 = a1, *h2 = a2; return(rflg * ( (ISDOWN(h2) ? h2->hs_recvtime - now : h2->hs_sendtime - h2->hs_boottime) - (ISDOWN(h1) ? h1->hs_recvtime - now : h1->hs_sendtime - h1->hs_boottime) )); } static void morehosts(void) { hs = realloc((char *)hs, (hspace *= 2) * sizeof(*hs)); if (hs == NULL) { (void)fprintf(stderr, "ruptime: %s.\n", strerror(ENOMEM)); exit(1); } } netkit-rwho-0.17/rwhod/ 40700 144 144 0 7141142024 14227 5ustar dhollandpeoplenetkit-rwho-0.17/rwhod/.cvsignore100644 144 144 6 6774165557 16305 0ustar dhollandpeoplerwhod netkit-rwho-0.17/rwhod/Makefile100644 144 144 510 6750761155 15773 0ustar dhollandpeopleall: rwhod include ../MCONFIG include ../MRULES CFLAGS += -I../include OBJS = rwhod.o daemon.o rwhod: $(OBJS) $(CC) $(LDFLAGS) $^ $(LIBS) -o $@ $(OBJS): daemon.h install: rwhod install -s -m$(DAEMONMODE) rwhod $(INSTALLROOT)$(SBINDIR) install -m$(MANMODE) rwhod.8 $(INSTALLROOT)$(MANDIR)/man8/ clean: rm -f *.o rwhod netkit-rwho-0.17/rwhod/daemon.3100644 144 144 5461 7141140322 15672 0ustar dhollandpeople.\" From: NetBSD: daemon.3,v 1.3 1995/02/25 13:41:12 cgd Exp .\" $Id: daemon.3,v 1.12 2000/07/30 23:57:06 dholland Exp $ .\" .\" Copyright (c) 1993 .\" 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. .\" .\" @(#)daemon.3 8.1 (Berkeley) 6/9/93 .\" .Dd June 9, 1993 .Dt DAEMON 3 .Os "Linux NetKit (0.17)" .Sh NAME .Nm daemon .Nd run in the background .Sh SYNOPSIS .Fd #include .Fn daemon "int nochdir" "int noclose" .Sh DESCRIPTION .Pp The .Fn daemon function is for programs wishing to detach themselves from the controlling terminal and run in the background as system daemons. .Pp Unless the argument .Fa nochdir is non-zero, .Fn daemon changes the current working directory to the root (``/''). .Pp Unless the argument .Fa noclose is non-zero, .Fn daemon will redirect standard input, standard output and standard error to ``/dev/null''. .Sh ERRORS The function .Fn daemon may fail and set .Va errno for any of the errors specified for the library functions .Xr fork 2 and .Xr setsid 2 . .Sh SEE ALSO .Xr setsid 2 .Sh HISTORY The .Fn daemon function first appeared in .Bx 4.4 . netkit-rwho-0.17/rwhod/daemon.c100644 144 144 4714 6204550064 15761 0ustar dhollandpeople/*- * Copyright (c) 1990, 1993 * 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: @(#)daemon.c 8.1 (Berkeley) 6/4/93 * NetBSD: daemon.c,v 1.4 1995/02/25 13:41:16 cgd Exp */ char daemon_rcsid[] = "$Id: daemon.c,v 1.2 1996/08/15 07:22:28 dholland Exp $"; #include #include #include #include "daemon.h" int daemon(int nochdir, int noclose) { int fd; switch (fork()) { case -1: return -1; case 0: break; default: _exit(0); } if (setsid() == -1) return -1; if (!nochdir) chdir("/"); if (noclose) return 0; fd = open(_PATH_DEVNULL, O_RDWR, 0); if (fd != -1) { dup2(fd, STDIN_FILENO); dup2(fd, STDOUT_FILENO); dup2(fd, STDERR_FILENO); if (fd > 2) close(fd); } return 0; } netkit-rwho-0.17/rwhod/daemon.h100644 144 144 47 6204550064 15721 0ustar dhollandpeopleint daemon(int nochdir, int noclose); netkit-rwho-0.17/rwhod/rwhod.8100644 144 144 12317 7141140322 15575 0ustar dhollandpeople.\" 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: @(#)rwhod.8 6.5 (Berkeley) 3/16/91 .\" $Id: rwhod.8,v 1.16 2000/07/30 23:57:06 dholland Exp $ .\" .Dd May 13, 1997 .Dt RWHOD 8 .Os "Linux NetKit (0.17)" .Sh NAME .Nm rwhod .Nd system status server .Sh SYNOPSIS .Nm rwhod .Op Fl bpa .Op Fl u Ar user .Sh DESCRIPTION .Nm Rwhod is the server which maintains the database used by the .Xr rwho 1 and .Xr ruptime 1 programs. Its operation is predicated on the ability to .Em broadcast messages on a network. .Pp .Nm Rwhod operates as both a producer and consumer of status information. As a producer of information it periodically queries the state of the system and constructs status messages which are broadcast on a network. As a consumer of information, it listens for other .Nm rwhod servers' status messages, validating them, then recording them in a collection of files located in the directory .Pa /var/spool/rwho . .Pp The server transmits and receives messages at the port indicated in the ``rwho'' service specification; see .Xr services 5 . .Pp If the .Fl b flag is supplied, only broadcast interfaces, such as ethernets, will be used. If the .Fl p flag is supplied, only point-to-point interfaces will be used. If the .Fl a flag is supplied, or no flags are supplied, all interfaces will be used. .Pp If the .Fl u flag is supplied, rwhod will run as the specified user instead of as root. .Pp The messages sent and received, are of the form: .Bd -literal -offset indent struct outmp { char out_line[8]; /* tty name */ char out_name[8]; /* user id */ long out_time; /* time on */ }; struct whod { char wd_vers; char wd_type; char wd_fill[2]; int wd_sendtime; int wd_recvtime; char wd_hostname[32]; int wd_loadav[3]; int wd_boottime; struct whoent { struct outmp we_utmp; int we_idle; } wd_we[1024 / sizeof (struct whoent)]; }; .Ed .Pp All fields are converted to network byte order prior to transmission. The load averages are as calculated by the .Xr w 1 program, and represent load averages over the 5, 10, and 15 minute intervals prior to a server's transmission; they are multiplied by 100 for representation in an integer. The host name included is that returned by the .Xr gethostname 2 system call, with any trailing domain name omitted. The array at the end of the message contains information about the users logged in to the sending machine. This information includes the contents of the .Xr utmp 5 entry for each non-idle terminal line and a value indicating the time in seconds since a character was last received on the terminal line. .Pp Messages received by the .Xr rwho server are discarded unless they originated at an .Xr rwho server's port. In addition, if the host's name, as specified in the message, contains any unprintable .Tn ASCII characters, the message is discarded. Valid messages received by .Nm rwhod are placed in files named .Pa whod.hostname in the directory .Pa /var/spool/rwho . These files contain only the most recent message, in the format described above. .Pp Status messages are generated approximately once every 3 minutes. .Nm Rwhod recomputes the system boot time every 30 minutes because on some (non-Linux) systems it is not a totally reliable process. .Sh SEE ALSO .Xr rwho 1 , .Xr ruptime 1 .Sh BUGS There should be a way to relay status information between networks. People often interpret the server dying or network communtication failures as a machine going down. .Sh HISTORY The .Nm command appeared in .Bx 4.2 . netkit-rwho-0.17/rwhod/rwhod.c100644 144 144 44106 7136462124 15664 0ustar dhollandpeople/* * 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: @(#)rwhod.c 5.20 (Berkeley) 3/2/91 */ char rcsid[] = "$Id: rwhod.c,v 1.20 2000/07/23 03:19:48 dholland Exp $"; #include #include #include #include #include #include #include #include #include #ifndef __linux__ #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "daemon.h" #include "../version.h" #define ENDIAN LITTLE_ENDIAN /* * Alarm interval. Don't forget to change the down time check in ruptime * if this is changed. */ #define AL_INTERVAL (3 * 60) static struct sockaddr_in sine; #ifndef __linux__ struct nlist nl[] = { #define NL_BOOTTIME 0 { "_boottime" }, 0 }; #endif static void broadcaster(void); static int configure(int s); static int verify(const char *name); static int getloadavg(double ptr[3], int n); /* * We communicate with each neighbor in * a list constructed at the time we're * started up. Neighbors are currently * directly connected via a hardware interface. */ struct neighbor { struct neighbor *n_next; char *n_name; /* interface name */ char *n_addr; /* who to send to */ int n_addrlen; /* size of address */ int n_flags; /* should forward?, interface flags */ }; static struct neighbor *neighbors; static struct servent *sp; static int sk; static int use_pointopoint = 0; static int use_broadcast = 0; static int need_init = 1; static int child_pid = 0; #define WHDRSIZE (((caddr_t) &((struct whod *) 0)->wd_we) \ - ((caddr_t) 0)) static void huphandler(int); static void termhandler(int); static void sendpacket(struct whod *); static void getboottime(struct whod *); int main(int argc, char *argv[]) { struct sockaddr_in from; struct passwd *pw = 0; struct stat st; char path[64]; char *user = NULL; int on = 1; int opt; if (getuid()) { fprintf(stderr, "rwhod: not super user\n"); exit(1); } while ((opt = getopt(argc, argv, "bpau:")) != EOF) { switch (opt) { case 'b': use_broadcast = 1; break; case 'p': use_pointopoint = 1; break; case 'a': use_broadcast = 1; use_pointopoint = 1; break; case 'u': user = optarg; break; case '?': default: fprintf(stderr, "usage: rwhod [-bpa] [-u user]\n"); exit(1); break; } } if (optinds_port; if (bind(sk, (struct sockaddr *)&sine, sizeof(sine)) < 0) { syslog(LOG_ERR, "bind: %m"); exit(1); } (void) umask(022); signal(SIGTERM, termhandler); child_pid = fork(); if (child_pid < 0) { syslog(LOG_ERR, "fork: %m"); exit(1); } if (child_pid == 0) { broadcaster(); exit(0); } /* We have to drop privs in two steps--first get the * account info, then drop privs after chroot */ if (user && (pw = getpwnam(user)) == NULL) { syslog(LOG_ERR, "unknown user: %s", user); exit(1); } /* Chroot to the spool directory * (note this is already our $cwd) */ if (chroot(_PATH_RWHODIR) < 0) { syslog(LOG_ERR, "chroot(%s): %m", _PATH_RWHODIR); kill(child_pid, SIGTERM); exit(1); } /* Now drop privs */ if (pw) { if (setgroups(1, &pw->pw_gid) < 0 || setgid(pw->pw_gid) < 0 || setuid(pw->pw_uid) < 0) { syslog(LOG_ERR, "failed to drop privilege: %m"); exit(1); } } for (;;) { struct whod wd; int cc, whod; size_t len = sizeof(from); memset(&wd, 0, sizeof(wd)); cc = recvfrom(sk, (char *)&wd, sizeof(struct whod), 0, (struct sockaddr *)&from, &len); if (cc <= 0) { if (cc < 0 && errno != EINTR) syslog(LOG_WARNING, "recv: %m"); continue; } if (from.sin_port != sp->s_port) { syslog(LOG_WARNING, "%d: bad from port", ntohs(from.sin_port)); continue; } if (wd.wd_vers != WHODVERSION) continue; if (wd.wd_type != WHODTYPE_STATUS) continue; /* * Ensure null termination of the name within the packet. * Otherwise we might overflow or read past the end. */ wd.wd_hostname[sizeof(wd.wd_hostname)-1] = 0; if (!verify(wd.wd_hostname)) { syslog(LOG_WARNING, "malformed host name from %x", from.sin_addr); continue; } snprintf(path, sizeof(path), "whod.%s", wd.wd_hostname); /* * Rather than truncating and growing the file each time, * use ftruncate if size is less than previous size. */ whod = open(path, O_WRONLY | O_CREAT, 0644); if (whod < 0) { syslog(LOG_WARNING, "%s: %m", path); continue; } #if ENDIAN != BIG_ENDIAN { int i, n = (cc - WHDRSIZE)/sizeof(struct whoent); struct whoent *we; /* undo header byte swapping before writing to file */ wd.wd_sendtime = ntohl(wd.wd_sendtime); for (i = 0; i < 3; i++) wd.wd_loadav[i] = ntohl(wd.wd_loadav[i]); wd.wd_boottime = ntohl(wd.wd_boottime); we = wd.wd_we; for (i = 0; i < n; i++) { we->we_idle = ntohl(we->we_idle); we->we_utmp.out_time = ntohl(we->we_utmp.out_time); we++; } } #endif wd.wd_recvtime = time(NULL); write(whod, (char *)&wd, cc); if (fstat(whod, &st) < 0 || st.st_size > cc) ftruncate(whod, cc); (void) close(whod); } } /* * Terminate broadcaster process */ static void termhandler(int dummy) { (void) dummy; if (child_pid) kill(child_pid, SIGTERM); exit(0); } /* * Obtain boot time again */ static void huphandler(int dummy) { (void) dummy; need_init = 1; } /* * This is the part of rwhod that sends out packets */ static void broadcaster() { char myname[MAXHOSTNAMELEN], *cp; size_t mynamelen; struct whod mywd; if (!configure(sk)) exit(1); /* * Establish host name as returned by system. */ if (gethostname(myname, sizeof (myname) - 1) < 0) { syslog(LOG_ERR, "gethostname: %m"); exit(1); } if ((cp = index(myname, '.')) != NULL) *cp = '\0'; mynamelen = strlen(myname); if (mynamelen > sizeof(mywd.wd_hostname)) mynamelen = sizeof(mywd.wd_hostname); strncpy(mywd.wd_hostname, myname, mynamelen); mywd.wd_hostname[sizeof(mywd.wd_hostname)-1] = 0; getboottime(&mywd); while (1) { sendpacket(&mywd); (void) sleep(AL_INTERVAL); } } /* * Check out host name for unprintables * and other funnies before allowing a file * to be created. Sorry, but blanks aren't allowed. */ static int verify(const char *name) { register int size = 0; while (*name) { if (*name=='/' || !isascii(*name) || !(isalnum(*name) || ispunct(*name))) return (0); name++, size++; } return size > 0; } static void sendpacket(struct whod *wd) { static int nutmps = 0; static time_t utmptime = 0; static off_t utmpsize = 0; static int alarmcount = 0; struct neighbor *np; struct whoent *we = wd->wd_we, *wlast; int i, cc; struct stat stb; struct utmp *uptr; double avenrun[3]; time_t now = time(NULL); if (alarmcount % 10 == 0 || need_init) { getboottime(wd); need_init = 0; } alarmcount++; stat(_PATH_UTMP, &stb); if ((stb.st_mtime != utmptime) || (stb.st_size > utmpsize)) { utmptime = stb.st_mtime; if (stb.st_size > utmpsize) { utmpsize = stb.st_size + 10 * sizeof(struct utmp); } wlast = (struct whoent *) ((caddr_t) wd->wd_we) + sizeof(wd->wd_we); wlast = &wd->wd_we[1024 / sizeof (struct whoent) - 1]; setutent(); while ((uptr = getutent()) && we < wlast) { if (uptr->ut_name[0] && uptr->ut_type == USER_PROCESS) { bcopy(uptr->ut_line, we->we_utmp.out_line, sizeof(uptr->ut_line)); bcopy(uptr->ut_name, we->we_utmp.out_name, sizeof(uptr->ut_name)); we->we_utmp.out_time = htonl(uptr->ut_time); we++; } } nutmps = we - wd->wd_we; endutent(); } /* * The test on utmpent looks silly---after all, if no one is * logged on, why worry about efficiency?---but is useful on * (e.g.) compute servers. */ if (nutmps && chdir(_PATH_DEV)) { syslog(LOG_ERR, "chdir(%s): %m", _PATH_DEV); exit(1); } we = wd->wd_we; for (i = 0; i < nutmps; i++) { if (stat(we->we_utmp.out_line, &stb) >= 0) we->we_idle = htonl(now - stb.st_atime); we++; } getloadavg(avenrun, sizeof(avenrun)/sizeof(avenrun[0])); for (i = 0; i < 3; i++) wd->wd_loadav[i] = htonl((u_long)(avenrun[i] * 100)); cc = (char *)we - (char *)wd; wd->wd_sendtime = htonl(time(0)); wd->wd_vers = WHODVERSION; wd->wd_type = WHODTYPE_STATUS; for (np = neighbors; np != NULL; np = np->n_next) { if (sendto(sk, (char *)wd, cc, 0, (struct sockaddr *) np->n_addr, np->n_addrlen) < 0) syslog(LOG_ERR, "sendto(%s): %m", inet_ntoa(((struct sockaddr_in *)np->n_addr)->sin_addr)); } if (nutmps && chdir(_PATH_RWHODIR)) { syslog(LOG_ERR, "chdir(%s): %m", _PATH_RWHODIR); exit(1); } } /* * Taken from: * * rwhod.c * * A simple rwhod server for Linux * * Version: 0.1 * * Copyright (c) 1993 Peter Eriksson, Signum Support AB * * ----------------------------------------------------------------------- * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 1, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * ----------------------------------------------------------------------- * * Send comments/bug reports/fixes to: pen@signum.se or pen@lysator.liu.se */ int getloadavg(double ptr[3], int n) { FILE *fp; if (n!=3) return -1; fp = fopen("/proc/loadavg", "r"); if (!fp) return -1; if (fscanf(fp, "%lf %lf %lf", &ptr[0], &ptr[1], &ptr[2]) != 3) { fclose(fp); return -1; } fclose(fp); return 0; } void getboottime(struct whod *wd) { #ifdef __linux__ long uptime; time_t curtime; FILE *fp = fopen("/proc/uptime", "r"); if (!fp) return /* -1 */; fscanf(fp, "%ld", &uptime); curtime = time(NULL); curtime -= uptime; wd->wd_boottime = htonl(curtime); fclose(fp); return /* 0 */; #else static int kmemf = -1; static ino_t vmunixino; static time_t vmunixctime; struct stat sb; if (stat(_PATH_UNIX, &sb) < 0) { if (vmunixctime) return; } else { if (sb.st_ctime == vmunixctime && sb.st_ino == vmunixino) return; vmunixctime = sb.st_ctime; vmunixino= sb.st_ino; } if (kmemf >= 0) (void) close(kmemf); loop: if (nlist(_PATH_UNIX, nl)) { syslog(LOG_WARNING, "%s: namelist botch", _PATH_UNIX); sleep(300); goto loop; } kmemf = open(_PATH_KMEM, O_RDONLY, 0); if (kmemf < 0) { syslog(LOG_ERR, "%s: %m", _PATH_KMEM); exit(1); } (void) lseek(kmemf, (long)nl[NL_BOOTTIME].n_value, L_SET); (void) read(kmemf, (char *)&wd->wd_boottime, sizeof (wd->wd_boottime)); wd->wd_boottime = htonl(wd->wd_boottime); #endif } /* * Figure out device configuration and select * networks which deserve status information. */ static int configure(int s) { char buf[BUFSIZ], *cp, *cplim; struct ifconf ifc; struct ifreq ifreq, *ifr; struct sockaddr_in *sn; register struct neighbor *np; ifc.ifc_len = sizeof (buf); ifc.ifc_buf = buf; if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) { syslog(LOG_ERR, "ioctl (get interface configuration)"); return (0); } ifr = ifc.ifc_req; #ifdef AF_LINK #define max(a, b) (a > b ? a : b) #define size(p) max((p).sa_len, sizeof(p)) #else #define size(p) (sizeof (p)) #endif cplim = buf + ifc.ifc_len; /*skip over if's with big ifr_addr's */ for (cp = buf; cp < cplim; cp += sizeof (ifr->ifr_name) + size(ifr->ifr_addr)) { ifr = (struct ifreq *)cp; for (np = neighbors; np != NULL; np = np->n_next) if (np->n_name && strcmp(ifr->ifr_name, np->n_name) == 0) break; if (np != NULL) continue; ifreq = *ifr; np = (struct neighbor *)malloc(sizeof (*np)); if (np == NULL) continue; np->n_name = malloc(strlen(ifr->ifr_name) + 1); if (np->n_name == NULL) { free((char *)np); continue; } strcpy(np->n_name, ifr->ifr_name); np->n_addrlen = sizeof (ifr->ifr_addr); np->n_addr = malloc(np->n_addrlen); if (np->n_addr == NULL) { free(np->n_name); free((char *)np); continue; } bcopy((char *)&ifr->ifr_addr, np->n_addr, np->n_addrlen); if (ioctl(s, SIOCGIFFLAGS, (char *)&ifreq) < 0) { syslog(LOG_ERR, "ioctl (get interface flags)"); free((char *)np); continue; } if ((ifreq.ifr_flags & IFF_UP) == 0 || (ifreq.ifr_flags & (IFF_BROADCAST|IFF_POINTOPOINT)) == 0) { free((char *)np); continue; } np->n_flags = ifreq.ifr_flags; if (np->n_flags & IFF_POINTOPOINT) { if (ioctl(s, SIOCGIFDSTADDR, (char *)&ifreq) < 0) { syslog(LOG_ERR, "ioctl (get dstaddr)"); free(np); continue; } if (!use_pointopoint) { free(np); continue; } /* we assume addresses are all the same size */ bcopy((char *)&ifreq.ifr_dstaddr, np->n_addr, np->n_addrlen); } if (np->n_flags & IFF_BROADCAST) { if (ioctl(s, SIOCGIFBRDADDR, (char *)&ifreq) < 0) { syslog(LOG_ERR, "ioctl (get broadaddr)"); free(np); continue; } if (!use_broadcast) { free(np); continue; } /* we assume addresses are all the same size */ bcopy((char *)&ifreq.ifr_broadaddr, np->n_addr, np->n_addrlen); } /* gag, wish we could get rid of Internet dependencies */ sn = (struct sockaddr_in *)np->n_addr; sn->sin_port = sp->s_port; np->n_next = neighbors; neighbors = np; } return (1); } #ifdef DEBUG sendto(s, buf, cc, flags, to, tolen) int s; #ifdef __linux__ __const void *buf; int cc; unsigned int flags; __const struct sockaddr *to; int tolen; #else char *buf; int cc, flags; char *to; int tolen; #endif { register struct whod *w = (struct whod *)buf; register struct whoent *we; struct sockaddr_in *sn = (struct sockaddr_in *)to; char *interval(); printf("sendto %x.%d\n", ntohl(sn->sin_addr.s_addr), ntohs(sn->sin_port)); printf("hostname %s %s\n", w->wd_hostname, interval(ntohl(w->wd_sendtime) - ntohl(w->wd_boottime), " up")); printf("load %4.2f, %4.2f, %4.2f\n", ntohl(w->wd_loadav[0]) / 100.0, ntohl(w->wd_loadav[1]) / 100.0, ntohl(w->wd_loadav[2]) / 100.0); cc -= WHDRSIZE; for (we = w->wd_we, cc /= sizeof (struct whoent); cc > 0; cc--, we++) { time_t t = ntohl(we->we_utmp.out_time); printf("%-8.8s %s:%s %.12s", we->we_utmp.out_name, w->wd_hostname, we->we_utmp.out_line, ctime(&t)+4); we->we_idle = ntohl(we->we_idle) / 60; if (we->we_idle) { if (we->we_idle >= 100*60) we->we_idle = 100*60 - 1; if (we->we_idle >= 60) printf(" %2d", we->we_idle / 60); else printf(" "); printf(":%02d", we->we_idle % 60); } printf("\n"); } } char * interval(time, updown) int time; char *updown; { static char resbuf[32]; int days, hours, minutes; if (time < 0 || time > 3*30*24*60*60) { (void) snprintf(resbuf, sizeof(resbuf), " %s ??:??", updown); return (resbuf); } minutes = (time + 59) / 60; /* round to minutes */ hours = minutes / 60; minutes %= 60; days = hours / 24; hours %= 24; if (days) (void) snprintf(resbuf, sizeof(resbuf), "%s %2d+%02d:%02d", updown, days, hours, minutes); else (void) snprintf(resbuf, sizeof(resbuf), "%s %2d:%02d", updown, hours, minutes); return (resbuf); } #endif