[comp.sources.unix] v10i060: SPS for BSD, Ultrix1.2, Sun3.x, NFS, Part01/03

rs@uunet.UU.NET (Rich Salz) (07/23/87)

Submitted-by: robert@hslrswi.UUCP (Robert Ward)
Posting-Number: Volume 10, Issue 60
Archive-name: sps/Part01

[  This is a fast, public, version of "ps" for BSD-derived Unices..  --r$  ]

Hello Net,

This is another posting of SPS, hopefully the last for quite a while now.
This version is the same as the one last posted to comp.sources.unix
except that it includes fixes for those 4.3 systems with NFS. These
additions were incorporated by Alexander Dupuy <dupuy@amsterdam.columbia.edu>
who writes:

> Sun-specific changes
> 
> 	A minor bugfix to "getcmd.c" to deal with processes which have no stack
> (this is the case for nfs async block i/o daemons on some VMEbus Suns).
> 
> 
> 4.3+NFS changes
> 
> 	Changes to conditionalization to support NFS on non-Sun systems.
> Several things like disc quotas are reimplemented with NFS, and should be
> ignored on any NFS system, not just Suns.  The files "globals2.c" and
> "waitingfor.c" were changed to support non-Sun NFS systems.  The file
> "Makefile.sun" was changed to add the -DNFS option, and a new Makefile for
> 4.3+NFS systems was added.
> 
> 					Alexander Dupuy



As usual, please mail all comments and fixes to myself (Robert) at:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    J. Robert Ward,						   ___________
    Hasler AG, Belpstrasse 23, CH-3000 Berne 14, Switzerland	   |    _    |
								   |  _| |_  |
Tel.:	    +41 31 632319					   | |_   _| |
X.400:	    robert@hslrswi.hasler				   |   |_|   |
Bitnet:	    robert%hslrswi.UUCP@cernvax.BITNET	   		   |_________|
Uucp:	    ... {seismo,ukc, ... }!mcvax!cernvax!hslrswi!robert
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 1 (of 3)."
# Contents:  MANIFEST Makefile.4.1 Makefile.4.2 Makefile.4.3
#   Makefile.4.3+NFS Makefile.sun README README2 filecount.c findtty.c
#   flags.h flagsetup.c getupage.c globals1.c hashuid.c initialise.c
#   initsymbols.c main.c mktree.c openfiles.c percentmem.c prcmd.c
#   prcpu.c prheader.c printall.c prsummary.c readstatus.c
#   selectproc.c selecttty.c termwidth.c ttystatus.c
# Wrapped by rs@uunet on Wed Jul 22 20:09:05 1987
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f MANIFEST -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"MANIFEST\"
else
echo shar: Extracting \"MANIFEST\" \(1344 characters\)
sed "s/^X//" >MANIFEST <<'END_OF_MANIFEST'
X   File Name		Archive #	Description
X-----------------------------------------------------------
X MANIFEST                  1	This shipping list
X Makefile.4.1              1	
X Makefile.4.2              1	
X Makefile.4.3              1	
X Makefile.4.3+NFS          1	
X Makefile.sun              1	
X README                    1	
X README2                   1	
X filecount.c               1	
X findtty.c                 1	
X flagdecode.c              2	
X flags.h                   1	
X flagsetup.c               1	
X getcmd.c                  2	
X getupage.c                1	
X globals1.c                1	
X globals2.c                2	
X hashuid.c                 1	
X initialise.c              1	
X initsymbols.c             1	
X inittty.c                 2	
X main.c                    1	
X mktree.c                  1	
X needed.c                  2	
X openfiles.c               1	
X patches                   3	
X percentmem.c              1	
X prcmd.c                   1	
X prcpu.c                   1	
X prheader.c                1	
X printall.c                1	
X printproc.c               2	
X prsummary.c               1	
X readstatus.c              1	
X selectproc.c              1	
X selecttty.c               1	
X sps.h                     2	
X sps.man                   3	
X termwidth.c               1	
X ttystatus.c               1	
X waitingfor.c              2	
END_OF_MANIFEST
if test 1344 -ne `wc -c <MANIFEST`; then
    echo shar: \"MANIFEST\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f Makefile.4.1 -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"Makefile.4.1\"
else
echo shar: Extracting \"Makefile.4.1\" \(882 characters\)
sed "s/^X//" >Makefile.4.1 <<'END_OF_Makefile.4.1'
X# Makefile for SPS (4.1BSD UNIX Version)
X
XPROG    =       sps
XOBJS    =       filecount.o findtty.o flagdecode.o flagsetup.o \
X		getcmd.o getupage.o globals1.o globals2.o hashuid.o \
X		initialise.o initsymbols.o inittty.o main.o mktree.o \
X		needed.o openfiles.o percentmem.o prcmd.o prcpu.o \
X		prheader.o printall.o printproc.o prsummary.o readstatus.o \
X		selectproc.o selecttty.o termwidth.o ttystatus.o waitingfor.o
X
XINCS    =       sps.h
XLIBS    =       -ltermlib
XCFLAGS  =       -I/usr/src/sys -DCHAOS
X
Xall:            $(PROG)
X.c.o:
X		cc $(CFLAGS) -c -O -R $<
Xglobals1.o waitingfor.o:
X		cc $(CFLAGS) -c -O $<
X
X$(OBJS):        $(INCS)
X
X$(PROG):        $(OBJS)
X		cc -o $@ $(OBJS) $(LIBS)
X
Xinstall:        $(PROG)
X		strip $(PROG)
X		mv $(PROG) /bin/$(PROG)
X		/etc/chown root /bin/$(PROG)
X		chmod 4711 /bin/$(PROG)
X
Xlint:
X		lint -x -b $(CFLAGS) *.c
Xclean:
X		rm -f $(OBJS) $(PROG)
END_OF_Makefile.4.1
if test 882 -ne `wc -c <Makefile.4.1`; then
    echo shar: \"Makefile.4.1\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f Makefile.4.2 -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"Makefile.4.2\"
else
echo shar: Extracting \"Makefile.4.2\" \(977 characters\)
sed "s/^X//" >Makefile.4.2 <<'END_OF_Makefile.4.2'
X# Makefile for SPS (Vax 4.2BSD and Ultrix1.2 UNIX Version)
X
XPROG    =       sps
XOBJS    =       filecount.o findtty.o flagdecode.o flagsetup.o \
X		getcmd.o getupage.o globals1.o globals2.o hashuid.o \
X		initialise.o initsymbols.o inittty.o main.o mktree.o \
X		needed.o openfiles.o percentmem.o prcmd.o prcpu.o \
X		prheader.o printall.o printproc.o prsummary.o readstatus.o \
X		selectproc.o selecttty.o termwidth.o ttystatus.o waitingfor.o
XINCS    =       sps.h
XCC      =       cc
XCFLAGS  =       -DBSD42 -I/sys
XLIBS    =       -ltermlib
XDIRINSTALL =	/bin
X
Xall:		    $(PROG)
X.c.o:
X		$(CC) $(CFLAGS) -c -O -R $<
X	
Xglobals1.o waitingfor.o:
X		$(CC) $(CFLAGS) -c -O $<
X
X$(OBJS):		$(INCS)
X
X$(PROG):		$(OBJS)
X		$(CC) -o $@ $(OBJS) $(LIBS)
X
Xinstall:		$(PROG)
X		strip $(PROG)
X		mv $(PROG) $(DIRINSTALL)/$(PROG)
X		/etc/chown root $(DIRINSTALL)/$(PROG)
X		chgrp kmem $(DIRINSTALL)/$(PROG)
X		chmod 2755 $(DIRINSTALL)/$(PROG)
X
Xlint:
X		lint -x -b $(CFLAGS) *.c
Xclean:
X		rm -f $(OBJS) $(PROG)
END_OF_Makefile.4.2
if test 977 -ne `wc -c <Makefile.4.2`; then
    echo shar: \"Makefile.4.2\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f Makefile.4.3 -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"Makefile.4.3\"
else
echo shar: Extracting \"Makefile.4.3\" \(966 characters\)
sed "s/^X//" >Makefile.4.3 <<'END_OF_Makefile.4.3'
X# Makefile for SPS (Vax 4.3BSD Version)
X
XPROG    =       sps
XOBJS    =       filecount.o findtty.o flagdecode.o flagsetup.o \
X		getcmd.o getupage.o globals1.o globals2.o hashuid.o \
X		initialise.o initsymbols.o inittty.o main.o mktree.o \
X		needed.o openfiles.o percentmem.o prcmd.o prcpu.o \
X		prheader.o printall.o printproc.o prsummary.o readstatus.o \
X		selectproc.o selecttty.o termwidth.o ttystatus.o waitingfor.o
XINCS    =       sps.h
XCC      =       cc
XCFLAGS  =       -DBSD42 -DBSD43 -I/sys
XLIBS    =       -ltermlib
XDIRINSTALL =	/bin
X
Xall:		    $(PROG)
X.c.o:
X		$(CC) $(CFLAGS) -c -O -R $<
X	
Xglobals1.o waitingfor.o:
X		$(CC) $(CFLAGS) -c -O $<
X
X$(OBJS):		$(INCS)
X
X$(PROG):		$(OBJS)
X		$(CC) -o $@ $(OBJS) $(LIBS)
X
Xinstall:		$(PROG)
X		strip $(PROG)
X		mv $(PROG) $(DIRINSTALL)/$(PROG)
X		/etc/chown root $(DIRINSTALL)/$(PROG)
X		chgrp kmem $(DIRINSTALL)/$(PROG)
X		chmod 2755 $(DIRINSTALL)/$(PROG)
X
Xlint:
X		lint -x -b $(CFLAGS) *.c
Xclean:
X		rm -f $(OBJS) $(PROG)
END_OF_Makefile.4.3
if test 966 -ne `wc -c <Makefile.4.3`; then
    echo shar: \"Makefile.4.3\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f Makefile.4.3+NFS -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"Makefile.4.3+NFS\"
else
echo shar: Extracting \"Makefile.4.3+NFS\" \(1089 characters\)
sed "s/^X//" >Makefile.4.3+NFS <<'END_OF_Makefile.4.3+NFS'
X# Makefile for SPS (Vax 4.3BSD Version)
XPROG    =       sps
XOBJS    =       filecount.o findtty.o flagdecode.o flagsetup.o \
X        getcmd.o getupage.o globals1.o globals2.o hashuid.o \
X        initialise.o initsymbols.o inittty.o main.o mktree.o \
X        needed.o openfiles.o percentmem.o prcmd.o prcpu.o \
X        prheader.o printall.o printproc.o prsummary.o readstatus.o \
X        selectproc.o selecttty.o termwidth.o ttystatus.o waitingfor.o
XINCS    =       sps.h
XCC      =       cc
XCFLAGS  =       -DBSD42 -DBSD43 -DQUOTA -DNFS -I/sys
XLIBS    =       -ltermlib
XDIRINSTALL =    /bin
Xall:            $(PROG)
X.c.o:
X        $(CC) $(CFLAGS) -c -O -R $<
Xglobals1.o waitingfor.o:
X        $(CC) $(CFLAGS) -c -O $<
X$(OBJS):        $(INCS)
X$(PROG):        $(OBJS)
X        $(CC) -o $@ $(OBJS) $(LIBS)
Xinstall:        $(PROG)
X        strip $(PROG)
X        mv $(PROG) $(DIRINSTALL)/$(PROG)
X        /etc/chown root $(DIRINSTALL)/$(PROG)
X        chgrp kmem $(DIRINSTALL)/$(PROG)
X        chmod 2755 $(DIRINSTALL)/$(PROG)
Xlint:
X        lint -x -b $(CFLAGS) *.c
Xclean:
X        rm -f $(OBJS) $(PROG)
END_OF_Makefile.4.3+NFS
if test 1089 -ne `wc -c <Makefile.4.3+NFS`; then
    echo shar: \"Makefile.4.3+NFS\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f Makefile.sun -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"Makefile.sun\"
else
echo shar: Extracting \"Makefile.sun\" \(988 characters\)
sed "s/^X//" >Makefile.sun <<'END_OF_Makefile.sun'
X# Makefile for SPS (Sun-2 and Sun-3, 4.2BSD UNIX Version)
X
XPROG    =       sps
XOBJS    =       filecount.o findtty.o flagdecode.o flagsetup.o \
X		getcmd.o getupage.o globals1.o globals2.o hashuid.o \
X		initialise.o initsymbols.o inittty.o main.o mktree.o \
X		needed.o openfiles.o percentmem.o prcmd.o prcpu.o \
X		prheader.o printall.o printproc.o prsummary.o readstatus.o \
X		selectproc.o selecttty.o termwidth.o ttystatus.o waitingfor.o
XINCS    =       sps.h
XCC      =       cc
XCFLAGS  =       -DSUN -DBSD42 -DNFS -I/sys
XLIBS    =       -ltermlib
XDIRINSTALL	= /bin
X
Xall:		    $(PROG)
X.c.o:
X		$(CC) $(CFLAGS) -c -O -R $<
X	
Xglobals1.o waitingfor.o:
X		$(CC) $(CFLAGS) -c -O $<
X
X$(OBJS):		$(INCS)
X
X$(PROG):		$(OBJS)
X		$(CC) -o $@ $(OBJS) $(LIBS)
X
Xinstall:		$(PROG)
X		strip $(PROG)
X		mv $(PROG) $(DIRINSTALL)/$(PROG)
X		/etc/chown root $(DIRINSTALL)/$(PROG)
X		chgrp kmem $(DIRINSTALL)/$(PROG)
X		chmod 2755 $(DIRINSTALL)/$(PROG)
X
Xlint:
X		lint -x -b $(CFLAGS) *.c
Xclean:
X		rm -f $(OBJS) $(PROG)
END_OF_Makefile.sun
if test 988 -ne `wc -c <Makefile.sun`; then
    echo shar: \"Makefile.sun\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f README -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"README\"
else
echo shar: Extracting \"README\" \(1226 characters\)
sed "s/^X//" >README <<'END_OF_README'
X		SPS - Show Process Status
X		=========================
XTo compile, install and test, type the following commands (as super-user):
X	% make                  # Compile SPS
X	% make install          # Install SPS into /bin/sps
X	% sps i                 # Initialise SPS
X	% sps va                # Run SPS
X********************************************************************************
XThe files in this directory are for the 4.[12]BSD / VAX-11 version of SPS.
XCompiler options are as follows -
X	-DCHAOS         if the Chaos network is incorporated into 4.xbsd
X	-DTRACE         for testing/debugging purposes
X	-DBSD42         compile SPS for 4.2bsd.
X			Otherwise, SPS is compiled for 4.1bsd.
X********************************************************************************
XIf you want to tell SPS about a new type of device, then add a new line to
Xthe symbol table (see globals2.c),after ensuring that there is sufficient
Xroom in the `info' structure. (NWAITSTATE may need to be increased in sps.h).
X********************************************************************************
XSPS understands if the size of internal kernel tables are changed under VMUNIX,
Xbut must be recompiled if major modifications are made to the kernel.
END_OF_README
if test 1226 -ne `wc -c <README`; then
    echo shar: \"README\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f README2 -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"README2\"
else
echo shar: Extracting \"README2\" \(3050 characters\)
sed "s/^X//" >README2 <<'END_OF_README2'
X		SPS  -  Show Process Status
X		===========================
X
XSPS is a intended to be used as a replacement for the standard ps(1)
Xprogram. Its advantages over ps(1) are that it shows more useful
Xinformation and that it is faster.
X
XSPS is currently implemented for 4.1 and 4.2bsd Unix on Vaxen and for
XSun's 4.2bsd/Release 2. (I also have a somewhat older implementation
Xfor V7 on a PDP-11 as well as Unisoft Version 1.3 on a MC68000 if you
Xare interested).
X
XSPS displays wait channels symbolically, rather than as hexadecimal
Xaddresses. If you wish to teach sps about a new sort of device, you
Xmust add an entry in the symbol table (globals2.c) as well as
Xincreasing the size of that table (NWAITSTATE in sps.h).
X
XSPS sorts processes before listing them. The order reflects the
Xrelationship of the processes. A child process is listed underneath its
Xcorresponding parent and is indented to depict the exact relationship.
XSPS also indicates setuid processes.
X
XSPS displays such values as the resident and virtual sizes of system
Xprocesses.  It accepts a whole range of options to control the output.
XBy default, SPS lists information about one's own processes. Other
Xoptions instruct it to be verbose (the "v" option), to list all the
Xcommand arguments of a process (the "w" option) or to list the
Xenvironment strings of that process (the "e" option). Similarly, there
Xare options to control which processes are to be displayed. The "a"
Xoption tells it to describe all processes and the "b" option tells it
Xto describe "busy" processes, which is useful if you wish to find out
Xwhat is loading your system. There are also options to select the
Xoutput according to user, controlling tty or process number.
X
XSPS keeps its information in an information file. By default, this is
X/etc/spsinfo. This means that it can avoid having to do an expensive
Xnlist() operation each time it is run. It must be reinitialised (with
Xthe "i" option) if new users are added to /etc/passwd or if a new
Xversion of /vmunix is installed.
X
XTo compile SPS, unbundle the four shell archive files.  Check that the
Xdefine statements in sps.h are large enough for your system (You may
Xneed to alter MAXTTYS).  Then compile it using the appropriate
XMakefile. Initialise it by typing "sps i" (ignore any error messages at
Xthis stage) and then test it out by typing "sps va". That should make
XSPS list verbose information about every process currently active. If
Xthat works, use the appropriate Makefile to install it.
X
XSend all bug reports, fixes, comments and suggestions to Robert Ward at -
X
X******************************************************************************
X    Robert Ward,
X    Hasler AG, Murtenstrasse 137a, CH-3008 Bern, Switzerland
X
XTel.:	    (031) - 65 23 19
XUucp:	    ... {seismo,decvax,ukc, ... }!mcvax!cernvax!hslrswi!robert
XBitnet:	    hslrswi!robert@cernvax.bitnet
XArpa:	    hslrswi!robert%cernvax.bitnet@WISCVM.ARPA
XEdunet:	    hslrswi!robert%cernvax.bitnet@UCBJADE.Berkeley.EDU
X******************************************************************************
END_OF_README2
if test 3050 -ne `wc -c <README2`; then
    echo shar: \"README2\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f filecount.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"filecount.c\"
else
echo shar: Extracting \"filecount.c\" \(351 characters\)
sed "s/^X//" >filecount.c <<'END_OF_filecount.c'
X# include       "sps.h"
X
X/* FILECOUNT - Counts the # open files for the current process */
Xfilecount ()
X{
X	register int            i ;
X	register struct file    **f ;
X	register int            count ;
X	extern union userstate  User ;
X
X	count = 0 ;
X	for ( i = 0, f = User.u_us.u_ofile ; i < NOFILE ; i++ )
X		if ( *f++ )
X			count++ ;
X	return ( count ) ;
X}
END_OF_filecount.c
if test 351 -ne `wc -c <filecount.c`; then
    echo shar: \"filecount.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f findtty.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"findtty.c\"
else
echo shar: Extracting \"findtty.c\" \(533 characters\)
sed "s/^X//" >findtty.c <<'END_OF_findtty.c'
X# include       "sps.h"
X# include       <h/ioctl.h>
X# include       <h/tty.h>
X
X/* FINDTTY - Attempts to determine to which tty a process is connected */
Xstruct ttyline  *findtty ( p )
X
Xregister struct process         *p ;
X
X{
X	register struct ttyline *lp ;
X	extern struct info      Info ;
X	extern struct ttyline   Notty ;
X	extern union userstate  User ;
X
X	if ( !p->pr_p.p_pgrp )
X		return ( &Notty ) ;
X	for ( lp = Info.i_ttyline ; lp->l_name[0] ; lp++ )
X		if ( lp->l_dev == User.u_us.u_ttyd )
X			return ( lp ) ;
X	return ( &Notty ) ;
X}
END_OF_findtty.c
if test 533 -ne `wc -c <findtty.c`; then
    echo shar: \"findtty.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f flags.h -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"flags.h\"
else
echo shar: Extracting \"flags.h\" \(2488 characters\)
sed "s/^X//" >flags.h <<'END_OF_flags.h'
X/* Structure holding information specified in the option list ... */
Xunion flaglist
X{
X	char                    *f_chp ;        /* Option specified as string */
X	int                     f_uid ;         /* Numerical user id */
X	int                     f_pid ;         /* Numerical process id */
X	struct ttyline          *f_ttyline ;    /* Specified tty */
X} ;
X
X/* Structure holding global information specifed by arg list options ... */
Xstruct flags
X{
X	int                     flg_d:1 ;       /* disc orientated output */
X	int                     flg_e:1 ;       /* print environment string */
X	int                     flg_f:1 ;       /* print process father # */
X	int                     flg_g:1 ;       /* print process group # */
X	int                     flg_i:1 ;       /* initialise sps */
X	char                    *flg_j ;        /* Use this as the info file */
X	char                    *flg_k ;        /* Use this as the {k}mem file*/
X	int                     flg_o:1 ;       /* avoid the swap device */
X	int                     flg_q:1 ;       /* show user time only */
X	int                     flg_r:1 ;       /* repeat output */
X	unsigned                flg_rdelay ;    /* ... with this much delay */
X	char                    *flg_s ;        /* Use this as the symbol file*/
X	int                     flg_v:1 ;       /* print verbose listing */
X	int                     flg_w:1 ;       /* print wide output */
X	int                     flg_y:1 ;       /* print tty information */
X	int                     flg_A:1 ;       /* print all processes */
X	int                     flg_B:1 ;       /* print busy processes */
X	int                     flg_F:1 ;       /* print foreground processes */
X	int                     flg_N:1 ;       /* print no processes */
X	int                     flg_P:1 ;       /* print specified process #'s*/
X	int                     flg_S:1 ;       /* print stopped processes */
X	int                     flg_T:1 ;       /* print procs for given ttys */
X	int                     flg_U:1 ;       /* print procs for given users*/
X	int                     flg_W:1 ;       /* print waiting processes */
X	int                     flg_Z:1 ;       /* print zombie processes */
X	int                     flg_AZ:1 ;      /* One of A to Z was specified*/
X	union flaglist          *flg_Plist ;    /* List of specified processes*/
X	union flaglist          *flg_Tlist ;    /* List of specified ttys */
X	union flaglist          *flg_Ulist ;    /* List of specified users */
X} ;
END_OF_flags.h
if test 2488 -ne `wc -c <flags.h`; then
    echo shar: \"flags.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f flagsetup.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"flagsetup.c\"
else
echo shar: Extracting \"flagsetup.c\" \(2210 characters\)
sed "s/^X//" >flagsetup.c <<'END_OF_flagsetup.c'
X# include       "sps.h"
X# include       "flags.h"
X# include       <h/ioctl.h>
X# include       <h/tty.h>
X
X/*
X** FLAGSETUP - Replaces any users or processes specified by flagdecode()
X** with numerical equivalents. The lists are terminated by negative values.
X** or null pointers. Ttystatus() must have been previously called to
X** initialise the Info structure with chaos tty values.
X*/
Xflagsetup ()
X{
X	register union flaglist *fp ;
X	register char           *chp ;
X	register int            i ;
X	register struct ttyline *lp ;
X	int                     found ;
X	extern struct flags     Flg ;
X	extern struct info      Info ;
X
X	/* Look for specified users */
X	if ( Flg.flg_U )                
X	{
X		if ( !Flg.flg_Ulist->f_chp )
X			prexit( "sps - User name was expected after -u flag\n");
X		for ( fp = Flg.flg_Ulist ; chp = fp->f_chp ; fp++ )
X		{
X			found = 0 ;
X			for ( i = 0 ; i < MAXUSERID ; i++ )
X				if ( !strncmp( chp, Info.i_hnames[i].h_uname,
X					UNAMELEN ) )
X				{
X					fp->f_uid = Info.i_hnames[i].h_uid ;
X					found = 1 ;
X					break ;
X				}
X			if ( !found )
X				prexit( "sps - Unknown user: %s\n", chp ) ;
X		}
X		fp->f_uid = -1 ;
X	}
X	/* Look for specified process ids */
X	if ( Flg.flg_P )                
X	{
X		if ( !Flg.flg_Plist->f_chp )
X			prexit(
X			     "sps - Process id was expected after -p flag\n" ) ;
X		for ( fp = Flg.flg_Plist ; chp = fp->f_chp ; fp++ )
X		{
X			if ( chp[0] < '0' || chp[0] > '9' )
X				prexit( "sps - Bad process id: %s\n", chp ) ;
X			fp->f_pid = atoi( chp ) ;
X		}
X		fp->f_pid = -1 ;
X	}
X	/* Look for specified ttys */
X	if ( !Flg.flg_T )               
X		return ;
X	if ( !Flg.flg_Tlist->f_chp )
X		prexit( "sps - Tty name was expected after -t flag\n" ) ;
X	for ( fp = Flg.flg_Tlist ; chp = fp->f_chp ; fp++ )
X	{       /* Under VMUNIX, all ttys have two character names.
X		   Thus, a flag of the form `t 8' should be expanded to
X		   become `t 08'. */
X		if ( !chp[1] )
X			chp[1] = chp[0], chp[0] = '0' ;
X		found = 0 ;
X		for ( lp = Info.i_ttyline ; lp->l_name[0] ; lp++ )
X			if ( !strncmp( chp, lp->l_name, 2 ) )
X			{
X				fp->f_ttyline = lp ;
X				found = 1 ;
X				break ;
X			}
X		if ( !found )
X			prexit( "sps - Unknown tty name: %.2s\n", chp ) ;
X	}
X	fp->f_ttyline = (struct ttyline*)0 ;
X}
END_OF_flagsetup.c
if test 2210 -ne `wc -c <flagsetup.c`; then
    echo shar: \"flagsetup.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f getupage.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"getupage.c\"
else
echo shar: Extracting \"getupage.c\" \(2971 characters\)
sed "s/^X//" >getupage.c <<'END_OF_getupage.c'
X# include       "sps.h"
X# include       <h/vm.h>
X# ifdef BSD42
X# include	<machine/pte.h>
X# else
X# include       <h/pte.h>
X# endif
X# include       <stdio.h>
X
X/*
X** GETUPAGE - Reads the upage for the specified process as well as sufficient
X** page tables entries for reading the command arguments. The pte's are read
X** into the argument `ptetbl'. The upage is read into the external variable
X** `User'. This procedure returns 1 if the upage was successfully read.
X*/
X
X# define        usrpt           (Info.i_usrpt)
X
Xgetupage ( p, ptetbl )
X
Xregister struct process         *p ;
Xregister struct pte             *ptetbl ;
X
X{
X	register int            i ;
X	register int            ncl ;
X	struct pte              pte ;
X	extern struct info      Info ;
X	extern union userstate  User ;
X	extern int              Flmem, Flkmem, Flswap ;
X
X	/* If the process is not loaded, look for the upage on the swap device*/
X	if ( !(p->pr_p.p_flag & SLOAD) )
X	{                               
X# ifdef BSD42
X		swseek( (long)dtob( p->pr_p.p_swaddr ) ) ;
X# else
X		swseek( (long)ctob( p->pr_p.p_swaddr ) ) ;
X# endif
X# ifdef SUN
X		if ( read( Flswap, (char*)&User.u_us, sizeof( union userstate ))
X		!= sizeof( union userstate ) )
X# else
X		if ( read( Flswap, (char*)&User.u_us, sizeof( struct user ) )
X		!= sizeof( struct user ) )
X# endif
X		{
X			fprintf( stderr,
X				"sps - Can't read upage of process %d\n",
X			    p->pr_p.p_pid ) ;
X			return ( 0 ) ;
X		}
X		return ( 1 ) ;          
X	}                               
X	/* The process is loaded. Locate the process pte's by reading
X	   the pte of their base address from system virtual address space. */
X	memseek( Flkmem, (long)&Info.i_usrptmap[ btokmx(p->pr_p.p_p0br)
X		+ p->pr_p.p_szpt-1 ] ) ;
X	if ( read( Flkmem, (char*)&pte, sizeof( struct pte ) )
X	!= sizeof( struct pte ) )
X	{
X		fprintf( stderr,
X		      "sps - Can't read indir pte for upage of process %d\n",
X		    p->pr_p.p_pid ) ;
X		return ( 0 ) ;
X	}                               
X	/* Now read the process' pte's from physical memory. We need to access
X	   sufficient pte's for the upage and for the command arguments. */
X	memseek( Flmem, (long)ctob( pte.pg_pfnum+1 )
X		- (UPAGES+CLSIZE)*sizeof( struct pte ) ) ;
X	if ( read( Flmem, (char*)ptetbl, (UPAGES+CLSIZE)*sizeof( struct pte ) )
X	!= (UPAGES+CLSIZE)*sizeof( struct pte ) )
X	{
X		fprintf( stderr, "sps - Can't read page table of process %d\n",
X			p->pr_p.p_pid ) ;
X		return ( 0 ) ;
X	}
X	/* Now we can read the pages belonging to the upage.
X	   Here we read in an entire click at one go. */
X	ncl = (sizeof( struct user ) + NBPG*CLSIZE - 1) / (NBPG*CLSIZE) ;
X	while ( --ncl >= 0 )            
X	{                               
X		i = ncl * CLSIZE ;
X		memseek( Flmem, (long)ctob( ptetbl[ CLSIZE+i ].pg_pfnum ) ) ;
X		if ( read( Flmem, User.u_pg[i], CLSIZE*NBPG ) != CLSIZE*NBPG )
X		{
X			fprintf( stderr,
X				"sps - Can't read page 0x%x of process %d\n",
X				ptetbl[ CLSIZE+i ].pg_pfnum, p->pr_p.p_pid ) ;
X			return ( 0 ) ;
X		}
X	}
X	return ( 1 ) ;
X}
END_OF_getupage.c
if test 2971 -ne `wc -c <getupage.c`; then
    echo shar: \"getupage.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f globals1.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"globals1.c\"
else
echo shar: Extracting \"globals1.c\" \(720 characters\)
sed "s/^X//" >globals1.c <<'END_OF_globals1.c'
X# include       "sps.h"
X# include       "flags.h"
X
X/* Read/Write Variables global to the code of sps */
X
Xstruct info                     Info ;          /* Information structure */
X
Xstruct flags                    Flg ;           /* Flag options */
X
Xstruct summary                  Summary ;       /* Summary of processes */
X
Xunion  userstate                User ;          /* Upage of one process */
X
Xint                             Flmem, Flkmem, Flswap ; /* File descriptors */
X
Xunsigned                        Termwidth ;     /* Width of output device */
X
Xshort                           Lastpgrp ;      /* Last process pgrp printed */
X
Xshort                           Lastuid ;       /* Last process uid printed */
END_OF_globals1.c
if test 720 -ne `wc -c <globals1.c`; then
    echo shar: \"globals1.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f hashuid.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"hashuid.c\"
else
echo shar: Extracting \"hashuid.c\" \(1441 characters\)
sed "s/^X//" >hashuid.c <<'END_OF_hashuid.c'
X# include       "sps.h"
X
X/* The hashing functions themselves ... */
X# define        HASHFN1( a )            (((unsigned)(a)*91 + 17) % MAXUSERID)
X# define        HASHFN2( a )            (((unsigned)(a) + 47) % MAXUSERID)
X
X/*
X** HASHUID - Returns a pointer to a slot in the hash table that corresponds
X** to the hash table entry for `uid'. It returns a null pointer if there is
X** no such slot.
X*/
Xstruct hashtab  *hashuid ( uid )
X
Xint                             uid ;
X
X{
X	register struct hashtab *hp ;
X	register int            i ;
X	register int            j ;
X	extern struct info      Info ;
X
X	j = HASHFN1( uid ) ;
X	for ( i = 0 ; i < MAXUSERID ; i++ )
X	{
X		hp = &Info.i_hnames[ j ] ;
X		if ( !hp->h_uname[0] )
X			return ( (struct hashtab*)0 ) ;
X		if ( hp->h_uid == uid )
X			return ( hp ) ;
X		j = HASHFN2( j ) ;
X	}
X	return ( (struct hashtab*)0 ) ;
X}
X
X/*
X** HASHNEXT - Returns a pointer to the next slot in the hash table that
X** may be use for storing information for `uid'. It returns a null pointer
X** if there are no more free slots available.
X*/
Xstruct hashtab  *hashnext ( uid )
X
Xint                             uid ;
X
X{
X	register struct hashtab *hp ;
X	register int            i ;
X	register int            j ;
X	extern struct info      Info ;
X
X	j = HASHFN1( uid ) ;
X	for ( i = 0 ; i < MAXUSERID ; i++ )
X	{
X		hp = &Info.i_hnames[ j ] ;
X		if ( !hp->h_uname[0] )
X			return ( hp ) ;
X		j = HASHFN2( j ) ;
X	}
X	return ( (struct hashtab*)0 ) ;
X}
END_OF_hashuid.c
if test 1441 -ne `wc -c <hashuid.c`; then
    echo shar: \"hashuid.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f initialise.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"initialise.c\"
else
echo shar: Extracting \"initialise.c\" \(1905 characters\)
sed "s/^X//" >initialise.c <<'END_OF_initialise.c'
X# include       "sps.h"
X# include       "flags.h"
X# include       <pwd.h>
X# include       <stdio.h>
X
X/*
X** INITIALISE - Called to reset the `Info' structure with new kernel
X** addresses and user and tty information.
X*/
Xinitialise ()
X{
X	register FILE           *fd ;
X	char                    *fileinfo ;
X	extern struct flags     Flg ;
X	extern struct info      Info ;
X	FILE                    *fopen() ;
X
X	fileinfo = Flg.flg_j ? Flg.flg_j : FILE_INFO ;
X	/* Read kernel addresses */
X	initsymbols() ;                 
X	/* Read user names */
X	initusers() ;                   
X	(void)umask( ~0644 ) ;          
X	if ( !(fd = fopen( fileinfo, "w" )) )
X	{
X		fprintf( stderr, "sps - Can't create info file %s", fileinfo ) ;
X		sysperror() ;
X	}
X	/* Find tty addresses */
X	inittty() ;                     
X	if ( fwrite( (char*)&Info, sizeof( struct info ), 1, fd ) != 1 )
X	{
X		fprintf( stderr, "sps - Can't write info file %s", fileinfo ) ;
X		sysperror() ;
X		exit( 1 ) ;
X	}
X	(void)fclose( fd ) ;
X	printf( "sps is initialised\n" ) ;
X}
X
X/* INITUSERS - Read the passwd file and fill in the user name arrays */
Xinitusers ()
X{
X	register struct passwd  *pw ;
X	register struct hashtab *hp ;
X	struct passwd           *getpwent() ;
X	char                    *strncpy() ;
X	struct hashtab          *hashuid(), *hashnext() ;
X
X	while ( pw = getpwent() )
X	{       /* For each user in the passwd file, first see if that uid
X		   has been already allocated in the hash table. */
X		if ( hp = hashuid( pw->pw_uid ) )
X		{
X			fprintf( stderr,
X		   "sps - Names %s and %s conflict in passwd file for uid %d\n",
X				hp->h_uname, pw->pw_name, pw->pw_uid ) ;
X			continue ;
X		}
X		/* Try to find a free slot in the hash table and fill it. */
X		if ( !(hp = hashnext( pw->pw_uid )) )
X			prexit( "sps - Too many users in passwd file\n" ) ;
X		hp->h_uid = pw->pw_uid ;
X		(void)strncpy( hp->h_uname, pw->pw_name, UNAMELEN ) ;
X	}
X	(void)endpwent() ;
X}
END_OF_initialise.c
if test 1905 -ne `wc -c <initialise.c`; then
    echo shar: \"initialise.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f initsymbols.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"initsymbols.c\"
else
echo shar: Extracting \"initsymbols.c\" \(3000 characters\)
sed "s/^X//" >initsymbols.c <<'END_OF_initsymbols.c'
X# include       "sps.h"
X# include       "flags.h"
X# ifdef BSD42
X# include       <sys/file.h>
X# endif
X# include       <nlist.h>
X# include       <stdio.h>
X
X/* INITSYMBOLS - Reads kmem values into the Info structure */
X/*
X** THIS CODE COPIES KMEM VALUES INTO THE INFO STRUCTURE ASSUMING THAT
X** VALUES READ FROM THE KERNEL HAVE TYPE CADDR_T. THEREFORE, WE ARE
X** MAKING THE DUBIOUS ASSUMPTION THAT INTS, POINTERS AND CADDR_T's
X** HAVE IDENTICAL SIZES.
X*/
Xinitsymbols ()
X{
X	register struct nlist   *np ;
X	register struct symbol  *s ;
X	register struct nlist   *np0 ;
X	char                    *filesymbol ;
X	extern int              Flkmem ;
X	extern struct flags     Flg ;
X	extern struct symbol    Symbollist[] ;
X	extern struct info      Info ;
X	char                    *getcore() ;
X	char                    *strncpy() ;
X
X	filesymbol = Flg.flg_s ? Flg.flg_s : FILE_SYMBOL ;
X	/* Find the length of the symbol table */
X	for ( s = Symbollist ; s->s_kname ; s++ )
X		;
X	/* Construct an nlist structure by copying names from the symbol table*/
X	np0 = (struct nlist*)getcore( (s-Symbollist+1)*sizeof( struct nlist ) );
X	for ( s = Symbollist, np = np0 ; s->s_kname ; s++, np++ )
X	{                                       
X		np->n_name = s->s_kname ;       
X		np[1].n_name = (char*)0 ;       
X		np->n_value = 0 ;
X	}
X# ifdef BSD42
X	if ( access( filesymbol, R_OK ) < 0 )
X# else
X	if ( access( filesymbol, 4 ) < 0 )
X# endif
X	{
X		fprintf( stderr, "sps - Can't open symbol file %s", filesymbol);
X		sysperror() ;
X	}
X	/* Get kernel addresses */
X	(void)nlist( filesymbol, np0 ) ;              
X	if ( np0[0].n_value == -1 )
X	{
X		fprintf( stderr, "sps - Can't read symbol file %s", filesymbol);
X		sysperror() ;
X	}
X	for ( s = Symbollist, np = np0 ; s->s_kname ; s++, np++ )
X	{                                       
X		if ( !np->n_value )             
X		{
X			fprintf( stderr, "sps - Can't find symbol %s in %s",
X				np->n_name, filesymbol ) ;
X			/* Assume this error to be unimportant if the address
X			   is only associated with a process wait state.
X			   This may happen if the system has been configured
X			   without a particular device. */
X			fprintf( stderr, &Info.i_waitstate[ 0 ] <= s->s_info
X				&& s->s_info < &Info.i_waitstate[ NWAITSTATE ]
X				? " (error is not serious)\n"
X				: " (ERROR MAY BE SERIOUS)\n" ) ;
X			*s->s_info = (caddr_t)0 ;
X			continue ;
X		}
X		/* If no indirection is required, just copy the obtained value
X		   into the `Info' structure. */
X		if ( !s->s_indirect )           
X		{                               
X		/* DUBIOUS ASSUMPTION THAT KMEM VALUE HAS SIZE OF A CADDR_T */
X			*s->s_info = (caddr_t)np->n_value ;
X			continue ;              
X		}                               
X		/* Otherwise one level of indirection is required. Using the
X		   obtained address, look again in the kernel for the value */
X		memseek( Flkmem, (long)np->n_value ) ;
X		/* DUBIOUS ASSUMPTION THAT KMEM VALUE HAS SIZE OF A CADDR_T */
X		(void)read( Flkmem, (char*)s->s_info, sizeof(caddr_t) ) ;
X	}
X	free( (char*)np0 ) ;
X}
END_OF_initsymbols.c
if test 3000 -ne `wc -c <initsymbols.c`; then
    echo shar: \"initsymbols.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f main.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"main.c\"
else
echo shar: Extracting \"main.c\" \(3406 characters\)
sed "s/^X//" >main.c <<'END_OF_main.c'
X# include       "sps.h"
X# include       "flags.h"
X# include       <h/text.h>
X# include       <sys/stat.h>
X# include       <stdio.h>
X
X
X/* SPS - Show Process Status */
X/* J. R. Ward - Hasler AG Bern, CH - 24 May 1985 */
X/*				     26 Nov 1986 */
X
X/* <robert@hslrswi.uucp> */
X
Xmain ( argc,argv )
X
Xint                             argc ;
Xchar                            **argv ;
X
X{
X	register struct process *plist ;
X	register struct process *process ;
X	register struct text    *text ;
X	int                     flinfo ;
X	char			*fileinfo, *filesymbol ;
X	struct stat		sinfo, ssymbol, spasswd ;
X	extern struct flags     Flg ;
X	extern struct info      Info ;
X	extern int              Flmem ;
X	extern int              Flkmem ;
X	extern int              Flswap ;
X	char                    *getcore() ;
X	struct process          *needed(), *mktree() ;
X
X	/* Renice as fast as possible for root only (Suggested by Jeff Mogul,
X	   gregorio!mogul) */
X	if ( !getuid() )
X		(void)nice( -40 ) ;
X	/* Decode the flag arguments */
X	flagdecode( argc, argv ) ;      
X	/* Determine the terminal width */
X	if ( !Flg.flg_w && !Flg.flg_N && !Flg.flg_i )
X		termwidth() ;
X	/* Open the cpu physical memory, kernel virtual memory and swap device*/
X	if ( Flg.flg_k )
X	{
X		Flmem = openfile( Flg.flg_k ) ;
X		Flkmem = Flmem ;
X	}
X	else
X	{
X		Flmem = openfile( FILE_MEM ) ;
X		Flkmem = openfile( FILE_KMEM ) ;
X		if ( !Flg.flg_o )
X			Flswap = openfile( FILE_SWAP ) ;
X	}
X	if ( Flg.flg_i )
X	{       /* -i flag for info file initialisation */
X		initialise() ;          
X		exit( 0 ) ;
X	}
X	/* Check that the information file is newer than the symbol and
X	   password files, suggested by gregorio!mogul */
X	fileinfo = Flg.flg_j ? Flg.flg_j : FILE_INFO ;
X	filesymbol = Flg.flg_s ? Flg.flg_s : FILE_SYMBOL ;
X	flinfo = openfile( fileinfo ) ;
X	(void)fstat( flinfo, &sinfo ) ;
X	if ( !stat( filesymbol, &ssymbol ) &&
X		sinfo.st_mtime < ssymbol.st_mtime )
X		fprintf( stderr,
X	       "sps - WARNING: Info file `%s' is older than symbol file `%s'\n",
X			fileinfo, filesymbol ) ;
X	if ( !stat( FILE_PASSWD, &spasswd ) &&
X		sinfo.st_mtime < spasswd.st_mtime )
X		fprintf( stderr,
X	       "sps - WARNING: Info file `%s' is older than passwd file `%s'\n",
X			fileinfo, FILE_PASSWD ) ;
X	/* Read the information file */
X	if ( read( flinfo, (char*)&Info, sizeof( struct info ) )
X	!= sizeof( struct info ) )
X	{
X		fprintf( stderr, "sps - Can't read info file `%s'", fileinfo ) ;
X		sysperror() ;
X	}
X	(void)close( flinfo ) ;
X	/* Find current tty status */
X	ttystatus() ;                   
X	/* Now that we know the available ttys, decode the flags */
X	flagsetup() ;                   
X	process = (struct process*)getcore(Info.i_nproc*sizeof(struct process));
X	text = (struct text*)getcore( Info.i_ntext * sizeof( struct text ) ) ;
X	do
X	{       /* Read current process and text status */
X		readstatus( process, text ) ;
X		/* Select those processes to be listed */
X		plist = needed( process, text ) ;
X		/* Form a tree of listed processes */
X		plist = mktree( process, plist ) ;
X		if ( !Flg.flg_N )
X		{       /* Print the processes */
X			prheader() ;
X			printall( plist, 0 ) ;
X		}
X		prsummary() ;
X		(void)fflush( stdout ) ;
X		if ( Flg.flg_r )        
X		{       /* If repeating, again get tty status */
X			ttystatus() ;
X			if ( Flg.flg_rdelay )
X# ifdef BSD42
X				sleep( Flg.flg_rdelay ) ;
X# else
X				sleep( (int)Flg.flg_rdelay ) ;
X# endif
X		}
X	} while ( Flg.flg_r ) ;
X	exit( 0 ) ;
X}
END_OF_main.c
if test 3406 -ne `wc -c <main.c`; then
    echo shar: \"main.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f mktree.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"mktree.c\"
else
echo shar: Extracting \"mktree.c\" \(1626 characters\)
sed "s/^X//" >mktree.c <<'END_OF_mktree.c'
X# include       "sps.h"
X
X/*
X** MKTREE - Sort the needed processes by subtree and at the top by user.
X** This procedure takes a list of processes (as returned by needed())
X** and returnes a pointer to a sorted list.
X*/
Xstruct process  *mktree ( process, plist )
X
Xstruct process                  *process ;
Xstruct process                  *plist ;
X
X{
X	register struct process *p ;
X	register struct process *pp ;
X	register struct process *lp ;
X	struct process          *op ;
X	struct process          proot ;
X
X	proot.pr_sibling = (struct process*)0 ;
X	for ( p = plist ; p ; p = p->pr_plink )
X	{
X		if ( p->pr_pptr > &process[1] )
X		{
X			for ( pp = plist ; pp ; pp = pp->pr_plink )
X			{
X				if ( pp != p->pr_pptr )
X					continue ;
X				if ( lp = pp->pr_child )
X				{       /* Does process have children ? */
X					op = (struct process*)0 ;
X					while (lp &&
X					lp->pr_p.p_pid < p->pr_p.p_pid )
X					{
X						op = lp ;
X						lp=lp->pr_sibling ;
X					}
X					if ( op )
X					{
X						p->pr_sibling = lp ;
X						op->pr_sibling = p ;
X						break ;
X					}
X				}       
X				p->pr_sibling = lp ;
X				pp->pr_child = p ;
X				break ;
X			}
X			if ( pp )
X				continue ;
X		}
X		/* We have a top level process, sort into top level list.
X		   The top level is sorted firstly by user-id and then
X		   by process-id. */
X		lp = &proot ;
X		pp = lp->pr_sibling ;
X		while ( pp )
X		{
X			if ( p->pr_p.p_uid < pp->pr_p.p_uid )
X				break ;
X			if ( p->pr_p.p_uid == pp->pr_p.p_uid
X			&& p->pr_p.p_pid < pp->pr_p.p_pid )
X				break ;
X			lp = pp, pp = pp->pr_sibling ;
X		}
X		p->pr_sibling = lp->pr_sibling ;
X		lp->pr_sibling = p ;
X	}
X	return ( proot.pr_sibling ) ;
X}
END_OF_mktree.c
if test 1626 -ne `wc -c <mktree.c`; then
    echo shar: \"mktree.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f openfiles.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"openfiles.c\"
else
echo shar: Extracting \"openfiles.c\" \(2626 characters\)
sed "s/^X//" >openfiles.c <<'END_OF_openfiles.c'
X# include       <stdio.h>
X# include       "sps.h"
X# include       "flags.h"
X
X/* Miscellaneous procedures */
X
X/* OPENFILE - Opens the named file */
Xopenfile ( name )
X
Xchar                            *name ;
X
X{
X	register int            fd ;
X
X	if ( (fd = open( name, 0 )) >= 0 )
X		return ( fd ) ;
X	fprintf( stderr, "sps - Can't open %s", name ) ;
X	sysperror() ;
X	/* NOTREACHED */
X}
X
X/* MEMSEEK - Seek on a special file */
Xmemseek ( fd, pos )
X
Xint                             fd ;
Xlong                            pos ;
X
X{
X	extern int              errno ;
X	extern struct flags     Flg ;
X	long                    lseek() ;
X
X	errno = 0 ;
X	if ( Flg.flg_k )
X		pos &= 0x7fffffff ;
X	(void)lseek( fd, pos, 0 ) ;
X	if ( errno )
X	{
X		fprintf( stderr, "sps - Seek failed" ) ;
X		sysperror() ;
X	}
X}
X
X/* SWSEEK - Seek on the swap device */
Xswseek ( pos )
X
Xlong                            pos ;
X
X{
X	extern int              Flswap ;
X	extern int              errno ;
X	long                    lseek() ;
X
X	errno = 0 ;
X	(void)lseek( Flswap, pos, 0 ) ;
X	if ( errno )
X	{
X		fprintf( stderr, "sps - Seek failed" ) ;
X		sysperror() ;
X	}
X}
X
X# ifdef lint
Xint                             errno ;
Xint                             sys_nerr ;
Xchar                            *sys_errlist[] ;
X# endif
X
X/* SYSPERROR - Reports a system defined error msg and then exits gracefully */
Xsysperror ()
X{
X	extern int              errno ;
X	extern int              sys_nerr ;
X	extern char             *sys_errlist[] ;
X
X	if ( 0 < errno && errno < sys_nerr )
X		fprintf( stderr, " : %s", sys_errlist[errno] ) ;
X	(void)fputc( '\n', stderr ) ;
X	exit( 1 ) ;
X}
X
X/* STRSAVE - Store a string in core for later use. */
Xchar    *strsave ( cp )
X
Xregister char                   *cp ;
X
X{
X	register char           *chp ;
X	char                    *getcore(), *strcpy() ;
X
X	chp = getcore( strlen( cp ) + 1 ) ;
X	(void)strcpy( chp, cp ) ;
X	return ( chp ) ;
X}
X
X/* GETCORE - Allocate and return a pointer to the asked for amount of core */
Xchar    *getcore ( size )
X
Xregister int                    size ;
X
X{
X	register char           *chp ;
X	char                    *malloc() ;
X
X	if ( chp = malloc( (unsigned)size ) )
X		return ( chp ) ;
X	fprintf( stderr, "sps - Out of core" ) ;
X	sysperror() ;
X	/* NOTREACHED */
X}
X
Xunion flaglist  *getflgsp ( argc )
X
Xregister int                    argc ;
X
X{
X	char                    *getcore() ;
X
X	return ( (union flaglist*)getcore( sizeof( union flaglist )*argc ) ) ;
X}
X
X/* PREXIT - Print an error message and exit */
X/* VARARGS1 */
X/* ARGSUSED */
Xprexit ( fmt, args )
X
Xchar                            *fmt ;
X
X{
X	_doprnt( fmt, &args, stderr ) ;
X	exit( 1 ) ;
X}
END_OF_openfiles.c
if test 2626 -ne `wc -c <openfiles.c`; then
    echo shar: \"openfiles.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f percentmem.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"percentmem.c\"
else
echo shar: Extracting \"percentmem.c\" \(823 characters\)
sed "s/^X//" >percentmem.c <<'END_OF_percentmem.c'
X# include       "sps.h"
X# include       <h/text.h>
X# ifdef BSD42
X# include	<machine/pte.h>
X# else
X# include       <h/pte.h>
X# include       <h/vmparam.h>
X# endif
X# include       <h/vmmac.h>
X
X/* PERCENTMEM - Returns the percentage of real memory used by this process */
Xdouble  percentmem ( p )
X
Xregister struct process         *p ;
X
X{
X	register struct text    *tp ;
X	int                     szptudot ;
X	double                  fracmem ;
X	extern struct info      Info ;
X
X	tp = p->pr_p.p_textp ;
X	if ( !(p->pr_p.p_flag & SLOAD) || !tp )
X		return ( 0.0 ) ;
X	szptudot = UPAGES + clrnd( ctopt( p->pr_p.p_dsize + p->pr_p.p_ssize ) );
X	fracmem = ( (double)p->pr_p.p_rssize + szptudot ) / CLSIZE ;
X	if ( tp->x_ccount )
X		fracmem += ((double)tp->x_rssize)/CLSIZE/tp->x_ccount ;
X	return ( 100.0 * fracmem / (double)Info.i_ecmx ) ;
X}
END_OF_percentmem.c
if test 823 -ne `wc -c <percentmem.c`; then
    echo shar: \"percentmem.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f prcmd.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"prcmd.c\"
else
echo shar: Extracting \"prcmd.c\" \(709 characters\)
sed "s/^X//" >prcmd.c <<'END_OF_prcmd.c'
X# include       "sps.h"
X# include       "flags.h"
X
X/* PRCMD - Prints the command arguments according to the switches */
Xprcmd ( p, lpad, width )
X
Xregister struct process         *p ;
Xint                             lpad ;
Xint                             width ;
X
X{
X	extern struct flags     Flg ;
X	extern unsigned         Termwidth ;
X
X	printf( "%*d ", lpad, p->pr_p.p_pid ) ;
X	if ( Flg.flg_f )
X	{
X		printf( "%5d ", p->pr_p.p_ppid ) ;
X		width -= 6 ;
X	}
X	if ( Flg.flg_g )
X	{
X		printf( "%5d ", p->pr_p.p_pgrp ) ;
X		width -= 6 ;
X	}
X	width += Termwidth ;
X	if ( Flg.flg_w )
X		printf( "%s\n", p->pr_cmd ) ;
X	else if ( width > 0 )
X		printf( "%-.*s\n", width, p->pr_cmd ) ;
X	if ( p->pr_csaved )
X		free( p->pr_cmd ) ;
X}
END_OF_prcmd.c
if test 709 -ne `wc -c <prcmd.c`; then
    echo shar: \"prcmd.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f prcpu.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"prcpu.c\"
else
echo shar: Extracting \"prcpu.c\" \(1538 characters\)
sed "s/^X//" >prcpu.c <<'END_OF_prcpu.c'
X# include       "sps.h"
X
X# ifdef BSD42
X
X/* PRCPU - Print cpu time */
Xprcpu ( time, utime )
X
Xregister time_t                 time ;
Xtime_t                          utime ;
X
X{
X	time += utime / 1000000 ;
X	utime %= 1000000 ;
X	if ( time < 0L )
X	{       /* Ignore negative times */
X		printf( "     " ) ;     
X		return ;
X	}
X	if ( time < 60L*10L )
X	{       /* Print as seconds if less than 1000 seconds */
X		printf( "%3d.%1d", (int)time, (int)utime/100000 ) ;
X		return ;
X	}
X	/* Print as minutes if less than 10 hours ; print as hours if less than
X	   10 days, else print as days. */
X	if ( time < 60L*60L*10L )               
X		printf( "%3D M", time/60L ) ;
X	else if ( time < 24L*60L*60L*10L )
X		printf( "%3D H", time/60L/60L ) ;
X	else
X		printf( "%3D D", time/60L/60L/24L ) ;
X}
X
X# else
X
X/* PRCPU - Print cpu time */
Xprcpu ( time )
X
Xregister time_t                 time ;
X
X{
X	extern struct info      Info ;
X
X	if ( time < 0L )
X	{       /* Ignore negative times */
X		printf( "     " ) ;     
X		return ;
X	}
X	if ( time < Info.i_hz*60L*10L )
X	{       /* Less than 10 minutes */
X		printf( "%3D.%1D", time/Info.i_hz,
X			(time % Info.i_hz / (Info.i_hz/10L)) ) ;
X		return ;
X	}
X	/* If less than 10 hours, print as minutes */
X	time /= Info.i_hz ;
X	/* Print as minutes if less than 10 hours ; print as hours if less than
X	   10 days, else print as days. */
X	if ( time < 60L*60L*10L )               
X		printf( "%3D M", time/60L ) ;
X	else if ( time < 24L*60L*60L*10L )
X		printf( "%3D H", time/60L/60L ) ;
X	else
X		printf( "%3D D", time/60L/60L/24L ) ;
X}
X
X# endif
END_OF_prcpu.c
if test 1538 -ne `wc -c <prcpu.c`; then
    echo shar: \"prcpu.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f prheader.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"prheader.c\"
else
echo shar: Extracting \"prheader.c\" \(438 characters\)
sed "s/^X//" >prheader.c <<'END_OF_prheader.c'
X# include       "sps.h"
X# include       "flags.h"
X
X/* PRHEADER - Print a header according to the switches */
Xprheader ()
X{
X	extern struct flags     Flg ;
X
X	printf( "Ty User    %s Proc#", Flg.flg_v ?
X		" Status Fl Nice Virtual Resident %M  Time Child %C" :
X		Flg.flg_d ?
X		"  Files    PageFaults Swap BlockI/O Kbytsecs" : "" ) ;
X	if ( Flg.flg_f )
X		printf( " Ppid#" ) ;
X	if ( Flg.flg_g )
X		printf( " Pgrp#" ) ;
X	printf( " Command\n" ) ;
X}
END_OF_prheader.c
if test 438 -ne `wc -c <prheader.c`; then
    echo shar: \"prheader.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f printall.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"printall.c\"
else
echo shar: Extracting \"printall.c\" \(430 characters\)
sed "s/^X//" >printall.c <<'END_OF_printall.c'
X# include       <stdio.h>
X# include       "sps.h"
X
X/* PRINTALL - Recursively print the process tree. */
Xprintall ( p, md )
X
Xregister struct process         *p ;
Xregister int                    md ;
X
X{
X	while ( p )
X	{       /* Print this process */
X		printproc( p, md ) ;    
X		(void)fflush( stdout ) ;
X		/* Print child processes */
X		printall( p->pr_child, md+1 ) ;
X		/* Print brother processes */
X		p = p->pr_sibling ;     
X	}
X}
END_OF_printall.c
if test 430 -ne `wc -c <printall.c`; then
    echo shar: \"printall.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f prsummary.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"prsummary.c\"
else
echo shar: Extracting \"prsummary.c\" \(632 characters\)
sed "s/^X//" >prsummary.c <<'END_OF_prsummary.c'
X# include       "sps.h"
X
X/* PRSUMMARY - Print the summarising information */
Xprsummary ()
X{
X	extern struct summary   Summary ;
X
X	printf(
X"%D (%Dk) processes, %D (%Dk) busy, %D (%Dk) loaded, %D (%Dk) swapped\n",
X		Summary.sm_ntotal, KBYTES( Summary.sm_ktotal ),
X		Summary.sm_nbusy, KBYTES( Summary.sm_kbusy ),
X		Summary.sm_nloaded, KBYTES( Summary.sm_kloaded ),
X		Summary.sm_nswapped, KBYTES( Summary.sm_kswapped ) ) ;
X	Summary.sm_ntotal = 0L ;
X	Summary.sm_ktotal = 0L ;
X	Summary.sm_nbusy = 0L ;
X	Summary.sm_kbusy = 0L ;
X	Summary.sm_nloaded = 0L ;
X	Summary.sm_kloaded = 0L ;
X	Summary.sm_nswapped = 0L ;
X	Summary.sm_kswapped = 0L ;
X}
END_OF_prsummary.c
if test 632 -ne `wc -c <prsummary.c`; then
    echo shar: \"prsummary.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f readstatus.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"readstatus.c\"
else
echo shar: Extracting \"readstatus.c\" \(1170 characters\)
sed "s/^X//" >readstatus.c <<'END_OF_readstatus.c'
X# include       "sps.h"
X# include       <h/text.h>
X
X/* READSTATUS - Reads the kernel memory for current processes and texts */
Xreadstatus ( process, text )
X
Xregister struct process         *process ;
Xstruct text                     *text ;
X
X{
X	register struct proc    *p ;
X	register struct proc    *p0 ;
X	register struct process *pr ;
X	extern struct info      Info ;
X	extern int              Flkmem ;
X	char                    *getcore() ;
X
X	/* Read current text information */
X	memseek( Flkmem, (long)Info.i_text0 ) ;
X	if ( read( Flkmem, (char*)text, Info.i_ntext * sizeof( struct text ) )
X	!= Info.i_ntext * sizeof( struct text ) )
X		prexit( "sps - Can't read system text table\n" ) ;
X	/* Read current process information */
X	p0 = (struct proc*)getcore( sizeof( struct proc )*Info.i_nproc ) ;
X	memseek( Flkmem, (long)Info.i_proc0 ) ;
X	if ( read( Flkmem, (char*)p0, Info.i_nproc * sizeof( struct proc ) )
X	!= Info.i_nproc * sizeof( struct proc ) )
X		prexit( "sps - Can't read system process table\n" ) ;
X	/* Copy process information into our own array */
X	for ( p = p0, pr = process ; pr < &process[ Info.i_nproc ] ; p++, pr++ )
X		pr->pr_p = *p ;
X	free( (char*)p0 ) ;
X}
END_OF_readstatus.c
if test 1170 -ne `wc -c <readstatus.c`; then
    echo shar: \"readstatus.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f selectproc.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"selectproc.c\"
else
echo shar: Extracting \"selectproc.c\" \(1885 characters\)
sed "s/^X//" >selectproc.c <<'END_OF_selectproc.c'
X# include       "sps.h"
X# include       "flags.h"
X# ifdef USELOGINUID
X# include	<pwd.h>
X# endif USELOGINUID
X
X/*
X** SELECTPROC - Given a process structure, this procedure decides whether
X** the process is a candidate for printing.
X*/
Xselectproc ( p, process, thisuid )
X
Xregister struct process         *p ;            
Xregister struct process         *process ;      
Xint				thisuid ;
X
X{
X	register union flaglist *fp ;
X	register struct process *pp ;
X#ifdef USELOGINUID
X	char			*username ;
X	struct passwd		*pw ;
X	char			*getlogin() ;
X	struct passwd		*getpwnam() ;
X#endif USELOGINUID
X	extern struct flags     Flg ;
X
X	/* Flg.flg_AZ is an internal flag set if one of flags `A' to `Z'
X	   was specified. If this is not set, a process is listed only
X	   if it or one of its ancestors belongs to the invoking user. */
X	if ( !Flg.flg_AZ )
X	{
X#ifdef USELOGINUID
X		thisuid = (username = getlogin())
X			&& (pw = getpwnam( username )) ? pw->pw_uid : getuid() ;
X#endif USELOGINUID
X		for ( pp = p ; pp > &process[1] ; pp = pp->pr_pptr )
X			if ( thisuid == pp->pr_p.p_uid )
X				return ( 1 ) ;
X	}
X	if ( Flg.flg_A )
X		return ( 1 ) ;
X	if ( Flg.flg_P )
X		for ( fp = Flg.flg_Plist ; fp->f_pid >= 0 ; fp++ )
X			if ( fp->f_pid == p->pr_p.p_pid )
X				return ( 1 ) ;
X	if ( Flg.flg_U )
X		for ( pp = p ; pp > &process[1] ; pp = pp->pr_pptr )
X			for ( fp = Flg.flg_Ulist ; fp->f_uid >= 0 ; fp++ )
X				if ( fp->f_uid == pp->pr_p.p_uid )
X					return ( 1 ) ;
X	switch ( p->pr_p.p_stat )
X	{
X		case SRUN :
X			if ( Flg.flg_B )
X				return ( 1 ) ;
X			break ;
X		case SSLEEP :
X			if ( Flg.flg_B
X			&&   p->pr_p.p_pri < PZERO && p->pr_p.p_pid > MSPID )
X				return ( 1 ) ;
X		case SWAIT :
X		case SIDL :
X			if ( Flg.flg_W )
X				return ( 1 ) ;
X			break ;
X		case SSTOP :
X			if ( Flg.flg_S )
X				return ( 1 ) ;
X			break ;
X		case SZOMB :
X			if ( Flg.flg_Z )
X				return ( 1 ) ;
X			break ;
X		default :
X			break ;
X	}
X	return ( 0 ) ;
X}
END_OF_selectproc.c
if test 1885 -ne `wc -c <selectproc.c`; then
    echo shar: \"selectproc.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f selecttty.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"selecttty.c\"
else
echo shar: Extracting \"selecttty.c\" \(368 characters\)
sed "s/^X//" >selecttty.c <<'END_OF_selecttty.c'
X# include       "sps.h"
X# include       "flags.h"
X
X/* SELECTTTY - Decides whether this process is interesting for its tty */
Xselecttty ( p )
X
Xregister struct process         *p ;
X
X{
X	register union flaglist *fp ;
X	extern struct flags     Flg ;
X
X	for ( fp = Flg.flg_Tlist ; fp->f_ttyline ; fp++ )
X		if ( fp->f_ttyline == p->pr_tty )
X			return ( 1 ) ;
X	return ( 0 ) ;
X}
END_OF_selecttty.c
if test 368 -ne `wc -c <selecttty.c`; then
    echo shar: \"selecttty.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f termwidth.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"termwidth.c\"
else
echo shar: Extracting \"termwidth.c\" \(691 characters\)
sed "s/^X//" >termwidth.c <<'END_OF_termwidth.c'
X#include	<sys/ioctl.h>
X
X/*
X** TERMWIDTH - Sets the external variable `Termwidth' to the # of columns
X** on the terminal.
X*/
Xtermwidth ()
X{
X	register char           *termtype ;
X	register int            twidth ;
X#ifdef TIOCGWINSZ
X	struct winsize		w ;
X#endif
X	char                    buf[ 1025 ] ;
X	extern unsigned         Termwidth ;
X	char                    *getenv() ;
X
X#ifdef TIOCGWINSZ
X	w.ws_col = 0 ;
X	if ( !ioctl( 0, TIOCGWINSZ, &w ) && w.ws_col )
X	{
X		Termwidth = w.ws_col ;
X		return ;
X	}
X#endif
X	Termwidth = 80 ;
X	if ( !(termtype = getenv( "TERM" )) )
X		return ;
X	if ( tgetent( buf, termtype ) != 1 )
X		return ;
X	twidth = tgetnum( "co" ) ;
X	if ( twidth > 40 )
X		Termwidth = twidth ;
X}
END_OF_termwidth.c
if test 691 -ne `wc -c <termwidth.c`; then
    echo shar: \"termwidth.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f ttystatus.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"ttystatus.c\"
else
echo shar: Extracting \"ttystatus.c\" \(2911 characters\)
sed "s/^X//" >ttystatus.c <<'END_OF_ttystatus.c'
X# include       "sps.h"
X# include       "flags.h"
X# include       <stdio.h>
X# include       <h/ioctl.h>
X# include       <h/tty.h>
X# ifdef CHAOS
X# include       <chunix/chsys.h>
X# include       <chaos/chaos.h>
X# endif
X
X/*
X** TTYSTATUS - Reads the kernel memory for tty structures of active processes.
X** The addresses of the associated struct ttys of /dev/kmem are kept in the
X** info structure. Here we use those addresses to access the structures.
X** Actually, we are mostly interested just in the process group of each tty.
X*/
Xttystatus ()
X{
X	register struct ttyline *lp ;
X	struct tty              tty ;
X	extern struct flags     Flg ;
X	extern struct info      Info ;
X	extern int              Flkmem ;
X
X	if ( Flg.flg_y )
X		printf( "Ty   Dev       Addr Rawq Canq Outq  Pgrp\n" ) ;
X	lp = Info.i_ttyline ;
X# ifdef CHAOS
X	while ( lp->l_name[0] && lp->l_name[0] != 'C' )
X# else
X	while ( lp->l_name[0] )
X# endif
X	{
X		memseek( Flkmem, (long)lp->l_addr ) ;
X		if ( read( Flkmem, (char*)&tty, sizeof( struct tty ) )
X		!= sizeof( struct tty ) )
X		{
X			fprintf( stderr,
X				"sps - Can't read struct tty for tty%.2s\n",
X				lp->l_name ) ;
X			lp->l_pgrp = 0 ;
X			lp++ ;
X			continue ;
X		}
X		lp->l_pgrp = tty.t_pgrp ;
X		prtty( lp, &tty ) ;
X		lp++ ;
X	}
X# ifdef CHAOS
X	chaosttys( lp ) ;               
X# endif
X}
X
X/* PRTTY - Print out the tty structure */
Xprtty ( lp, tty )
X
Xregister struct ttyline         *lp ;
Xregister struct tty             *tty ;
X
X{
X	extern struct flags     Flg ;
X
X	if ( !Flg.flg_y )
X		return ;
X	printf( "%-2.2s %2d,%2d 0x%08x %4d %4d %4d %5d\n",
X		lp->l_name,
X		major( lp->l_dev ),
X		minor( lp->l_dev ),
X		lp->l_addr,
X		tty->t_rawq.c_cc,
X		tty->t_canq.c_cc,
X		tty->t_outq.c_cc,
X		tty->t_pgrp ) ;
X}
X
X# ifdef CHAOS
X
X/* CHAOSTTYS - Finds ttys attached to the Chaos net */
Xchaosttys ( lp )
X
Xregister struct ttyline         *lp ;
X
X{
X	register struct connection      **cnp ;
X	register int                    i ;
X	struct tty                      tty ;
X	struct connection               *conntab[CHNCONNS] ;
X	struct connection               conn ;
X	extern struct info              Info ;
X	extern int                      Flkmem ;
X
X	memseek( Flkmem, (long)Info.i_Chconntab ) ;
X	(void)read( Flkmem, (char*)conntab, sizeof( conntab ) ) ;
X	for ( i = 0, cnp = conntab ; cnp < &conntab[CHNCONNS] ; i++, cnp++ )
X	{
X		if ( !*cnp )
X			continue ;
X		memseek( Flkmem, (long)*cnp ) ;
X		(void)read( Flkmem, (char*)&conn, sizeof( struct connection ) );
X		if ( !(conn.cn_flags & CHTTY) )
X			continue ;
X		memseek( Flkmem, (long)conn.cn_ttyp ) ;
X		(void)read( Flkmem, (char*)&tty, sizeof( struct tty ) ) ;
X		if ( lp >= &Info.i_ttyline[MAXTTYS] )
X			prexit( "sps - Too many chaos ttys\n" ) ;
X		lp->l_addr = conn.cn_ttyp ;
X		lp->l_pgrp = tty.t_pgrp ;
X		lp->l_dev = tty.t_dev ;
X		lp->l_name[0] = 'C' ;
X		lp->l_name[1] = i < 10 ? '0'+i : i-10 <= 'z'-'a' ? i-10+'a' :
X				i-10-('z'-'a')+'A' ;
X		prtty( lp, &tty ) ;
X		lp++ ;
X	}
X}
X
X# endif
END_OF_ttystatus.c
if test 2911 -ne `wc -c <ttystatus.c`; then
    echo shar: \"ttystatus.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of archive 1 \(of 3\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 3 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 3 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 

Rich $alz			"Anger is an energy"
Cronus Project, BBN Labs	rsalz@bbn.com
Moderator, comp.sources.unix	sources@uunVar ;
X		}