v23i049: SPS, a PS replacement, Part03/04

Rich Salz rsalz at bbn.com
Tue Nov 27 06:06:03 AEST 1990


Submitted-by: Robert Ward <olsen!robert at uunet.uu.net>
Posting-number: Volume 23, Issue 49
Archive-name: sps2/part03

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then feed it
# into a shell via "sh file" or similar.  To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sources-unix at uunet.uu.net if you want that tool.
# Contents:  BUG-libkvm Make.4.3+NFS Make.dec3100 Make.sun.2.0
#   Make.sun.3.0 Make.sun.3.2 Make.sun.4.0 Make.sun.4.0+386i
#   Make.sun.4.1 Make.sun4.3.2 Make.ultrix2 Make.ultrix3 RELEASENOTES
#   filecount.c findtty.c flagsetup.c globals1.c hashuid.c
#   initialise.c initsymbols.c mktree.c percentmem.c prcpu.c
#   readstatus.c selectproc.c termwidth.c vmstat.c
# Wrapped by rsalz at papaya.bbn.com on Mon Nov 26 14:03:23 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo If this archive is complete, you will see the following message:
echo '          "shar: End of archive 3 (of 4)."'
if test -f 'BUG-libkvm' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'BUG-libkvm'\"
else
  echo shar: Extracting \"'BUG-libkvm'\" \(1656 characters\)
  sed "s/^X//" >'BUG-libkvm' <<'END_OF_FILE'
XThere is a bug in kvm_getcmd(3) which occurs when the arguments for a command
Xcontain an '=', or if an '=' in the environment is removed.  In user space,
Xcommand arguments are laid out like this:
X
Xa r g 0 '\0' a r g 1 '\0' ... e n v 1 = e n v '\0' e n v 2 = e n v ...
X
XThe only way to tell where the arguments end and the environment begins is to
Xlook for arguments which contain '=', or environment strings which don't.  Most
Xprograms used to use the first approach.  The libkvm library uses the latter,
Xand gets it wrong if it sees a '=' in any strings before the last string
Xwhich doesn't have one.  The korn shell nulls out some '=' in it's environment,
Xand if you have it, it's the most noticable tickler of this bug.  But even if
Xyou don't, you can tickle it with "vi a=b c".
X
XHere's the fix.  You could probably patch the binary to ignore the
X"&& (argd.cnt == 0)" test, which will cause slightly incorrect results,
Xbut ones a bit closer to the truth.  Just search for "\0=" in the
Xlibrary, and look past it a bit.
X
X*** /tmp/,RCSt1a01687	Wed Sep 28 01:50:36 1988
X--- kvmgetcmd.c	Mon Aug 29 23:23:43 1988
X***************
X*** 141,150 ****
X  			if (*cp == '=')
X  				eqseen++;
X  			if (*cp-- == '\0') {
X! 				if (eqseen && (argd.cnt == 0)) {
X  					envd.cnt++;
X  					envd.sp = Uvaddr(cp+2);
X  					eqseen = 0;
X  				} else {
X  					argd.cnt++;
X  				}
X--- 141,154 ----
X  			if (*cp == '=')
X  				eqseen++;
X  			if (*cp-- == '\0') {
X! 				if (eqseen) {
X  					envd.cnt++;
X  					envd.sp = Uvaddr(cp+2);
X  					eqseen = 0;
X+ 					if (argd.cnt != 0) {
X+ 						envd.cnt += argd.cnt;
X+ 						argd.cnt = 0;
X+ 					}
X  				} else {
X  					argd.cnt++;
X  				}
END_OF_FILE
  if test 1656 -ne `wc -c <'BUG-libkvm'`; then
    echo shar: \"'BUG-libkvm'\" unpacked with wrong size!
  fi
  # end of 'BUG-libkvm'
fi
if test -f 'Make.4.3+NFS' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Make.4.3+NFS'\"
else
  echo shar: Extracting \"'Make.4.3+NFS'\" \(976 characters\)
  sed "s/^X//" >'Make.4.3+NFS' <<'END_OF_FILE'
X# Makefile for SPS (Vax 4.3BSD+NFS 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 -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_FILE
  if test 976 -ne `wc -c <'Make.4.3+NFS'`; then
    echo shar: \"'Make.4.3+NFS'\" unpacked with wrong size!
  fi
  # end of 'Make.4.3+NFS'
fi
if test -f 'Make.dec3100' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Make.dec3100'\"
else
  echo shar: Extracting \"'Make.dec3100'\" \(1005 characters\)
  sed "s/^X//" >'Make.dec3100' <<'END_OF_FILE'
X# Makefile for SPS (Ultrix 2.0 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 -DULTRIX20 -DULTRIX30 -DVPRINTF -DDEC3100 -I/sys
XLIBS    =       -ltermlib
XDIRINSTALL =	/bin
X
Xall:		    $(PROG)
X.c.o:
X		$(CC) $(CFLAGS) -c -g -R $<
X	
Xglobals1.o waitingfor.o:
X		$(CC) $(CFLAGS) -c -g $<
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_FILE
  if test 1005 -ne `wc -c <'Make.dec3100'`; then
    echo shar: \"'Make.dec3100'\" unpacked with wrong size!
  fi
  # end of 'Make.dec3100'
fi
if test -f 'Make.sun.2.0' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Make.sun.2.0'\"
else
  echo shar: Extracting \"'Make.sun.2.0'\" \(1009 characters\)
  sed "s/^X//" >'Make.sun.2.0' <<'END_OF_FILE'
X# Makefile for SPS (Sun-2, Sun UNIX 4.2 Release 2.x 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 -DNOQUOTA -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 $(LIBS)
Xclean:
X		rm -f $(OBJS) $(PROG)
END_OF_FILE
  if test 1009 -ne `wc -c <'Make.sun.2.0'`; then
    echo shar: \"'Make.sun.2.0'\" unpacked with wrong size!
  fi
  # end of 'Make.sun.2.0'
fi
if test -f 'Make.sun.3.0' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Make.sun.3.0'\"
else
  echo shar: Extracting \"'Make.sun.3.0'\" \(1009 characters\)
  sed "s/^X//" >'Make.sun.3.0' <<'END_OF_FILE'
X# Makefile for SPS (Sun-2 and Sun-3, Sun UNIX 4.2 Release 3.0 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 $(LIBS)
Xclean:
X		rm -f $(OBJS) $(PROG)
END_OF_FILE
  if test 1009 -ne `wc -c <'Make.sun.3.0'`; then
    echo shar: \"'Make.sun.3.0'\" unpacked with wrong size!
  fi
  # end of 'Make.sun.3.0'
fi
if test -f 'Make.sun.3.2' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Make.sun.3.2'\"
else
  echo shar: Extracting \"'Make.sun.3.2'\" \(1019 characters\)
  sed "s/^X//" >'Make.sun.3.2' <<'END_OF_FILE'
X# Makefile for SPS (Sun-2 and Sun-3, Sun UNIX 4.2 Release 3.x 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 -DVPRINTF -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 $(LIBS)
Xclean:
X		rm -f $(OBJS) $(PROG)
END_OF_FILE
  if test 1019 -ne `wc -c <'Make.sun.3.2'`; then
    echo shar: \"'Make.sun.3.2'\" unpacked with wrong size!
  fi
  # end of 'Make.sun.3.2'
fi
if test -f 'Make.sun.4.0' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Make.sun.4.0'\"
else
  echo shar: Extracting \"'Make.sun.4.0'\" \(1134 characters\)
  sed "s/^X//" >'Make.sun.4.0' <<'END_OF_FILE'
X# Makefile for SPS (Sun-2, Sun-3 and Sun-4, SunOS 4.0 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 stream.o termwidth.o ttystatus.o \
X		vmstat.o waitingfor.o
XINCS    =       sps.h
XCC      =       cc
XCFLAGS  =       -DSUN -DBSD42 -DNFS -DVPRINTF -DKVM -DSUNOS40 -Isys
XLIBS    =       -ltermlib -lkvm
XDIRINSTALL	= /usr/kvm
X
Xall:		    $(PROG)
X.c.o:
X		$(CC) $(CFLAGS) -c -O -R $<
X	
Xglobals1.o stream.o waitingfor.o:
X		$(CC) $(CFLAGS) -c -O $<
X
X$(OBJS):		sys $(INCS)
X
Xsys:
X		-mkdir sys
X		-ln -s /sys/* sys
X		-ln -s /sys/sys sys/h
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 $(LIBS)
Xclean:
X		rm -f $(OBJS) $(PROG)
END_OF_FILE
  if test 1134 -ne `wc -c <'Make.sun.4.0'`; then
    echo shar: \"'Make.sun.4.0'\" unpacked with wrong size!
  fi
  # end of 'Make.sun.4.0'
fi
if test -f 'Make.sun.4.0+386i' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Make.sun.4.0+386i'\"
else
  echo shar: Extracting \"'Make.sun.4.0+386i'\" \(1144 characters\)
  sed "s/^X//" >'Make.sun.4.0+386i' <<'END_OF_FILE'
X# Makefile for SPS (Sun-2, Sun-3 and Sun-4, SunOS 4.0 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 stream.o termwidth.o ttystatus.o \
X		vmstat.o waitingfor.o
XINCS    =       sps.h
XCC      =       cc
XCFLAGS  =       -DSUN -DBSD42 -DNFS -DVPRINTF -DKVM -DSUNOS40 -DSUN386I -Isys
XLIBS    =       -ltermlib -lkvm
XDIRINSTALL	= /usr/kvm
X
Xall:		    $(PROG)
X.c.o:
X		$(CC) $(CFLAGS) -c -O -R $<
X	
Xglobals1.o stream.o waitingfor.o:
X		$(CC) $(CFLAGS) -c -O $<
X
X$(OBJS):		sys $(INCS)
X
Xsys:
X		-mkdir sys
X		-ln -s /sys/* sys
X		-ln -s /sys/sys sys/h
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 $(LIBS)
Xclean:
X		rm -f $(OBJS) $(PROG)
END_OF_FILE
  if test 1144 -ne `wc -c <'Make.sun.4.0+386i'`; then
    echo shar: \"'Make.sun.4.0+386i'\" unpacked with wrong size!
  fi
  # end of 'Make.sun.4.0+386i'
fi
if test -f 'Make.sun.4.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Make.sun.4.1'\"
else
  echo shar: Extracting \"'Make.sun.4.1'\" \(1201 characters\)
  sed "s/^X//" >'Make.sun.4.1' <<'END_OF_FILE'
X# Makefile for SPS (Sun-2, Sun-3 and Sun-4, SunOS 4.1 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 stream.o termwidth.o ttystatus.o \
X		waitingfor.o
XINCS    =       sps.h
XCC      =       cc
X# You'll need both "-DSUNOS40" and "-DSUNOS41" for SunOS 4.1
XCFLAGS  =	-DSUN -DBSD42 -DNFS -DVPRINTF -DKVM -DSUNOS40 -DSUNOS41 -Isys
XLIBS    =       -ltermlib -lkvm
XDIRINSTALL	= /usr/kvm
X
Xall:		    $(PROG)
X.c.o:
X		$(CC) $(CFLAGS) -c -O -R $<
X
Xglobals1.o stream.o waitingfor.o filecount.o:
X		$(CC) $(CFLAGS) -c -O $<
X
X$(OBJS):		sys $(INCS)
X
Xsys:
X		-mkdir sys
X		-ln -s /sys/* sys
X		-ln -s /sys/sys sys/h
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 $(LIBS)
Xclean:
X		rm -f $(OBJS) $(PROG)
END_OF_FILE
  if test 1201 -ne `wc -c <'Make.sun.4.1'`; then
    echo shar: \"'Make.sun.4.1'\" unpacked with wrong size!
  fi
  # end of 'Make.sun.4.1'
fi
if test -f 'Make.sun4.3.2' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Make.sun4.3.2'\"
else
  echo shar: Extracting \"'Make.sun4.3.2'\" \(1066 characters\)
  sed "s/^X//" >'Make.sun4.3.2' <<'END_OF_FILE'
X# Makefile for SPS (Sun-4, SunOS Sys 4-3.2 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 -DVPRINTF -Isys
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):		sys $(INCS)
X
Xsys:
X		-mkdir sys
X		-ln -s /sys/* sys
X		-ln -s /sys/sys sys/h
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 $(LIBS)
Xclean:
X		rm -f $(OBJS) $(PROG)
END_OF_FILE
  if test 1066 -ne `wc -c <'Make.sun4.3.2'`; then
    echo shar: \"'Make.sun4.3.2'\" unpacked with wrong size!
  fi
  # end of 'Make.sun4.3.2'
fi
if test -f 'Make.ultrix2' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Make.ultrix2'\"
else
  echo shar: Extracting \"'Make.ultrix2'\" \(984 characters\)
  sed "s/^X//" >'Make.ultrix2' <<'END_OF_FILE'
X# Makefile for SPS (Ultrix 2.0 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 -DULTRIX20 -DVPRINTF -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_FILE
  if test 984 -ne `wc -c <'Make.ultrix2'`; then
    echo shar: \"'Make.ultrix2'\" unpacked with wrong size!
  fi
  # end of 'Make.ultrix2'
fi
if test -f 'Make.ultrix3' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Make.ultrix3'\"
else
  echo shar: Extracting \"'Make.ultrix3'\" \(995 characters\)
  sed "s/^X//" >'Make.ultrix3' <<'END_OF_FILE'
X# Makefile for SPS (Ultrix 2.0 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 -DULTRIX20 -DULTRIX30 -DVPRINTF -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_FILE
  if test 995 -ne `wc -c <'Make.ultrix3'`; then
    echo shar: \"'Make.ultrix3'\" unpacked with wrong size!
  fi
  # end of 'Make.ultrix3'
fi
if test -f 'RELEASENOTES' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'RELEASENOTES'\"
else
  echo shar: Extracting \"'RELEASENOTES'\" \(3510 characters\)
  sed "s/^X//" >'RELEASENOTES' <<'END_OF_FILE'
X		NEW  RELEASE  OF  SPS
X		=====================
X
X
XThe files in this directory represent a major new release of the SPS
Xprogram.  One or two minor bugs have been corrected but, more
Ximportantly, SPS has now been ported to run under the SunOS 4.0, 4.1 and
XUltrix 2.x and 3.x operating systems.
X
X
XGratitude and heart-felt thanks for these achievments should be
Xdirected to Rob Lehman (and others?) at CUCCA, Charlie Kim
X<cck at cunixc.cc.columbia.edu> at CUCCA and, in particular, to Alexander
XDupuy <dupuy at ncs.columbia.edu> at the Columbia C.S. Dept.  Rob Lehman
Xadded the Ultrix 2.x support. Charlie Kim and Alexander Dupuy
Ximplemented the SunOS 4.0 support and Alexander added support for the
XNFS additions as well as incorporating general improvements to the code.
XSakari Jalovaara <sja at sirius.hut.fi> at the Helsinki University of Technology
XComputing Centre added the support for SunOS4.1.
X
X
XThis release of SPS includes support for all(?) systems previously
Xsupported, although it has not been tested under 4.1 or 4.2bsd, or Sun 4.2
XUNIX Release 2.x.  New systems supported include Ultrix 2.x and SunOS 4.0
Xand SunOS 4.1.  The support for Sun 2.x and 3.x releases has been
Ximproved.  Support for the DEC 3100 has been included, as yet incomplete.
X
XMinor fixes include:
X    One additional option [-c], identical to the ps(1) -c option,
X	has been added.
X    The code to warn if the passwd file is older than the info file
X	has been ifdef'ed out since this caused more grief than
X	benefit.  The old code may be reactivated by a -DWARNPASSWD
X	compiler flag.
X    Under SunOS, a status of itty?? indicates a process that is waiting
X	to read or write to an iconified window.
X
X
XFor SunOS 4.x users:
X    One additional file is included in this distribution, BUG-libkvm,
X    containing a (source-only, sorry) patch to fix a bug in the libkvm
X    library where the command arguments for the ksh (or "vi a=b c", for
X    that matter) are returned incorrectly buy kvm_getcmd(3).
X
XFor DecStation 3100 users:
X    The code that mimics the virtual to physical address translation is
X    incomplete.  Upage information is accessed correctly but not the
X    command line arguments.  If anyone knows how to make this code work,
X    please contact me.
X
X
XBuilding and installing SPS works much like it did before, only now there are
Xeven more Makefiles to choose from:
X	Makefile.4.1		Standard 4.1bsd for Vax
X	Makefile.4.2		Standard 4.2bsd, Ultrix 1.x for Vax
X	Makefile.4.3		Standard 4.3bsd (or 4.3-tahoe) for Vax
X	Makefile.4.3+NFS	4.3bsd+NFS from Wisconsin (Mt. Xinu?, others?)
X	Makefile.dec3100	DECStation 3100 + Ultrix 3.0 (incomplete)
X	Makefile.sun.2.0	Sun 4.2 UNIX Release 2.0 - 2.2 for Sun-2
X	Makefile.sun.3.0	Sun 4.2 UNIX Release 3.0 for Sun-2, Sun-3
X	Makefile.sun.3.2	Sun 4.2 UNIX Release 3.2 for Sun-2, Sun-3
X	Makefile.sun.4.0	SunOS 4.0 for Sun-2, Sun-3, Sun-4
X	Makefile.sun.4.0+386i	SunOS 4.0 for Sun 386i
X	Makefile.sun.4.1	SunOS 4.1 for Sun-2, Sun-3, Sun-4
X	Makefile.sun4.3.2	SunOS Sys 4-3.2 for Sun-4
X	Makefile.ultrix.2.0	DEC Ultrix 2.0 - 2.2
X	Makefile.ultrix.3.0	DEC Ultrix 3.0
X
X
X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
X    J. Robert Ward,
X    Olsen & Associates, Seefeldstrasse 233, CH-8008 Zuerich, Switzerland
X
XTel.:   +41 1 552224     Fax: +41 1 552282    Telex: 816656
XEmail:  robert at olsen.uu.ch              Uucp:  uunet!chx400!olsen!robert
XX.400:  s=robert/ou=olsen/o=uucp/p=switch/a=arcom/c=ch
X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
END_OF_FILE
  if test 3510 -ne `wc -c <'RELEASENOTES'`; then
    echo shar: \"'RELEASENOTES'\" unpacked with wrong size!
  fi
  # end of 'RELEASENOTES'
fi
if test -f 'filecount.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'filecount.c'\"
else
  echo shar: Extracting \"'filecount.c'\" \(1585 characters\)
  sed "s/^X//" >'filecount.c' <<'END_OF_FILE'
X# ifndef lint
Xstatic char SccsId[] =  "@(#)filecount.c	1.2\t7/4/90" ;
X# endif
X
X# include       "sps.h"
X
X/* FILECOUNT - Counts the # open files for the current process */
Xfilecount ( p )
X
Xstruct process         *p ;
X
X{
X	register int            i ;
X	register struct file    **f ;
X	register int            count ;
X	extern union userstate  User ;
X# ifdef SUNOS41
X	/*
X	 * The open file list is in User.u_us.u_ofile_arr
X	 * if User.u_us.u_ofile points to it; otherwise we'll have
X	 * do it the hard way by reading the list from kmem.
X	 *
X	 * Read the comment to u_ofile in /usr/include/sys/user.h.
X	 */
X
X	int			len ;
X	static char		*files = 0 ;
X	static int		 files_len = 0 ;
X	extern char		*getcore () ;
X# endif SUNOS41
X
X
X# ifdef SUNOS41
X
X#  ifndef offsetof
X#   define offsetof(type,member)	((long) &(((type *) 0)->member))
X#  endif offsetof
X
X	if ( (long) User.u_us.u_ofile ==
X	    (long) p->pr_p.p_uarea + offsetof(struct user, u_ofile_arr[0]) )
X		f = &User.u_us.u_ofile_arr[ 0 ] ;
X	else
X	{
X		len = User.u_us.u_lastfile * sizeof (struct file *) ;
X		if (len <= 0)
X			return 0;
X		if (files == 0 || len < files_len)
X		{
X			if (files != 0)
X				free (files) ;
X			files = (char *) getcore(len) ;
X			files_len = len ;
X		}
X		if ( getkmem( (long)User.u_us.u_ofile, (char *)files, len)
X		!= len )
X			return 0 ;
X		f = (struct file **)files ;
X	}
X	count = 0 ;
X	for ( i = 0 ; i < User.u_us.u_lastfile ; i++ )
X		if ( *f++ )
X			count++ ;
X	return ( count ) ;
X# else SUNOS41
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# endif SUNOS41
X}
END_OF_FILE
  if test 1585 -ne `wc -c <'filecount.c'`; then
    echo shar: \"'filecount.c'\" unpacked with wrong size!
  fi
  # end of 'filecount.c'
fi
if test -f 'findtty.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'findtty.c'\"
else
  echo shar: Extracting \"'findtty.c'\" \(1324 characters\)
  sed "s/^X//" >'findtty.c' <<'END_OF_FILE'
X# ifndef lint
Xstatic char SccsId[] =  "@(#)findtty.c	1.4\t8/6/90" ;
X# endif
X
X# include       "sps.h"
X# include       <h/ioctl.h>
X# ifdef SUNOS40
X# include       <h/stream.h>
X# else
X# include       <h/tty.h>
X# endif
X# ifdef SUNOS41
X# include	<h/session.h>
X# endif
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# ifdef SUNOS41
X	struct sess		*s ;
X	extern struct sess	*find_session () ;
X# else
X	extern union userstate  User ;
X# endif SUNOS41
X
X
X# ifdef SUNOS41
X	if ( !p->pr_p.p_pgrp || !p->pr_p.p_sessp )
X		return ( &Notty ) ;
X	s = find_session( p->pr_p.p_sessp ) ;
X	if ( s == 0 || s->s_ttyp == 0 )
X		return &Notty;
X	for ( lp = Info.i_ttyline ; lp->l_name[0] ; lp++ )
X		if ( lp->l_dev == s->s_ttyd )
X			return ( lp ) ;
X	/* Kludge from outer space	++sja */
X	if ( s->s_ttyd == 256 )
X		return &Info.i_ttyline[0] ;
X	return ( &Notty ) ;
X# else
X#  ifdef ULTRIX30
X	if ( !p->pr_p.p_pgrp || !p->pr_p.p_ttyp )
X#  else
X	if ( !p->pr_p.p_pgrp || !User.u_us.u_ttyp )
X#  endif
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#endif SUNOS41
X}
END_OF_FILE
  if test 1324 -ne `wc -c <'findtty.c'`; then
    echo shar: \"'findtty.c'\" unpacked with wrong size!
  fi
  # end of 'findtty.c'
fi
if test -f 'flagsetup.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'flagsetup.c'\"
else
  echo shar: Extracting \"'flagsetup.c'\" \(2342 characters\)
  sed "s/^X//" >'flagsetup.c' <<'END_OF_FILE'
X# ifndef lint
Xstatic char SccsId[] =  "@(#)flagsetup.c	1.1\t10/1/88" ;
X# endif
X
X# include       "sps.h"
X# include       "flags.h"
X# include       <h/ioctl.h>
X# ifdef SUNOS40
X# include       <h/stream.h>
X# endif
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 < MAXUSERS ; 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_FILE
  if test 2342 -ne `wc -c <'flagsetup.c'`; then
    echo shar: \"'flagsetup.c'\" unpacked with wrong size!
  fi
  # end of 'flagsetup.c'
fi
if test -f 'globals1.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'globals1.c'\"
else
  echo shar: Extracting \"'globals1.c'\" \(945 characters\)
  sed "s/^X//" >'globals1.c' <<'END_OF_FILE'
X# ifndef lint
Xstatic char SccsId[] =  "@(#)globals1.c	1.1\t10/1/88" ;
X# endif
X
X# include       "sps.h"
X# include       "flags.h"
X# ifdef KVM
X# include       <kvm.h>
X# endif
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
X# ifdef KVM
Xkvm_t                          *Flkvm ;         /* Kernel VM descriptor */
X# else
Xint                             Flmem, Flkmem, Flswap ; /* File descriptors */
X# endif
X
Xunsigned                        Termwidth ;     /* Width of output device */
X
Xshort                           Lastpgrp ;      /* Last process pgrp printed */
X
Xshort                           Lastuid ;       /* Last process uid printed */
END_OF_FILE
  if test 945 -ne `wc -c <'globals1.c'`; then
    echo shar: \"'globals1.c'\" unpacked with wrong size!
  fi
  # end of 'globals1.c'
fi
if test -f 'hashuid.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'hashuid.c'\"
else
  echo shar: Extracting \"'hashuid.c'\" \(1515 characters\)
  sed "s/^X//" >'hashuid.c' <<'END_OF_FILE'
X# ifndef lint
Xstatic char SccsId[] =  "@(#)hashuid.c	1.1\t10/1/88" ;
X# endif
X
X# include       "sps.h"
X
X/* The hashing functions themselves ... */
X# define        HASHFN1( a )            (((unsigned)(a)*91 + 17) % MAXUSERS)
X# define        HASHFN2( a )            (((unsigned)(a) + 47) % MAXUSERS)
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 < MAXUSERS ; 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 < MAXUSERS ; 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_FILE
  if test 1515 -ne `wc -c <'hashuid.c'`; then
    echo shar: \"'hashuid.c'\" unpacked with wrong size!
  fi
  # end of 'hashuid.c'
fi
if test -f 'initialise.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'initialise.c'\"
else
  echo shar: Extracting \"'initialise.c'\" \(1986 characters\)
  sed "s/^X//" >'initialise.c' <<'END_OF_FILE'
X# ifndef lint
Xstatic char SccsId[] =  "@(#)initialise.c	1.1\t10/1/88" ;
X# endif
X
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_FILE
  if test 1986 -ne `wc -c <'initialise.c'`; then
    echo shar: \"'initialise.c'\" unpacked with wrong size!
  fi
  # end of 'initialise.c'
fi
if test -f 'initsymbols.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'initsymbols.c'\"
else
  echo shar: Extracting \"'initsymbols.c'\" \(3515 characters\)
  sed "s/^X//" >'initsymbols.c' <<'END_OF_FILE'
X# ifndef lint
Xstatic char SccsId[] =	"@(#)initsymbols.c	1.4\t8/6/90" ;
X# endif lint
X
X# include       "sps.h"
X# include       "flags.h"
X# ifdef BSD42
X#  include       <sys/file.h>
X# endif BSD42
X# ifdef KVM
X#  include       <kvm.h>
X# endif KVM
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# ifdef KVM
X	extern kvm_t           *Flkvm ;
X# endif
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# ifdef SUN386I
X		/* Remove '_' prefix because 386i uses COFF format -
X		   Provided by Martin Reed <mr at ritd.co.uk> */
X		np->n_name = &s->s_kname[1] ;       
X# else SUN386I
X                                     
X		np->n_name = s->s_kname ; 
X# endif SUN386I     
X		np[1].n_name = (char*)0 ;       
X		np->n_value = 0 ;
X	}
X# ifdef KVM
X	if ( kvm_nlist( Flkvm, np0 ) == -1 )
X	{
X		fprintf( stderr, "sps - Can't read symbol file %s", filesymbol);
X		sysperror() ;
X	}
X              
X# else KVM
X#  ifdef BSD42
X	if ( access( filesymbol, R_OK ) < 0 )
X#  else BSD42
X	if ( access( filesymbol, 4 ) < 0 )
X#  endif BSD42
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# endif KVM
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		/* DUBIOUS ASSUMPTION THAT KMEM VALUE HAS SIZE OF A CADDR_T */
X		(void)getkmem( (long)np->n_value, (char*)s->s_info,
X			sizeof(caddr_t) ) ;
X	}
X	free( (char*)np0 ) ;
X}
END_OF_FILE
  if test 3515 -ne `wc -c <'initsymbols.c'`; then
    echo shar: \"'initsymbols.c'\" unpacked with wrong size!
  fi
  # end of 'initsymbols.c'
fi
if test -f 'mktree.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'mktree.c'\"
else
  echo shar: Extracting \"'mktree.c'\" \(1703 characters\)
  sed "s/^X//" >'mktree.c' <<'END_OF_FILE'
X# ifndef lint
Xstatic char SccsId[] =  "@(#)mktree.c	1.1\t10/1/88" ;
X# endif
X
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_FILE
  if test 1703 -ne `wc -c <'mktree.c'`; then
    echo shar: \"'mktree.c'\" unpacked with wrong size!
  fi
  # end of 'mktree.c'
fi
if test -f 'percentmem.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'percentmem.c'\"
else
  echo shar: Extracting \"'percentmem.c'\" \(1112 characters\)
  sed "s/^X//" >'percentmem.c' <<'END_OF_FILE'
X# ifndef lint
Xstatic char SccsId[] =  "@(#)percentmem.c	1.1\t10/1/88" ;
X# endif
X
X# include       "sps.h"
X# ifndef SUNOS40
X# include       <h/text.h>
X# endif
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# ifndef SUNOS40
X	register struct text    *tp ;
X# endif
X	int                     szptudot ;
X	double                  fracmem ;
X	extern struct info      Info ;
X
X# ifdef SUNOS40
X	if ( !(p->pr_p.p_flag & SLOAD) )
X		return ( 0.0 ) ;
X	szptudot = UPAGES ;
X	fracmem = ( (double)p->pr_p.p_rssize + szptudot ) ;
X# else
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# endif
X	return ( 100.0 * fracmem / (double)Info.i_ecmx ) ;
X}
END_OF_FILE
  if test 1112 -ne `wc -c <'percentmem.c'`; then
    echo shar: \"'percentmem.c'\" unpacked with wrong size!
  fi
  # end of 'percentmem.c'
fi
if test -f 'prcpu.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'prcpu.c'\"
else
  echo shar: Extracting \"'prcpu.c'\" \(1614 characters\)
  sed "s/^X//" >'prcpu.c' <<'END_OF_FILE'
X# ifndef lint
Xstatic char SccsId[] =  "@(#)prcpu.c	1.1\t10/1/88" ;
X# endif
X
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_FILE
  if test 1614 -ne `wc -c <'prcpu.c'`; then
    echo shar: \"'prcpu.c'\" unpacked with wrong size!
  fi
  # end of 'prcpu.c'
fi
if test -f 'readstatus.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'readstatus.c'\"
else
  echo shar: Extracting \"'readstatus.c'\" \(1281 characters\)
  sed "s/^X//" >'readstatus.c' <<'END_OF_FILE'
X# ifndef lint
Xstatic char SccsId[] =  "@(#)readstatus.c	1.1\t10/1/88" ;
X# endif
X
X# include       "sps.h"
X# ifndef SUNOS40
X# include       <h/text.h>
X# endif
X
X/* READSTATUS - Reads the kernel memory for current processes and texts */
X# ifdef SUNOS40
Xreadstatus ( process )
X
Xregister struct process         *process ;
X
X# else
X
Xreadstatus ( process, text )
X
Xregister struct process         *process ;
Xstruct text                     *text ;
X
X# endif
X{
X	register struct proc    *p ;
X	register struct proc    *p0 ;
X	register struct process *pr ;
X	int                     size ;
X	extern struct info      Info ;
X	char                    *getcore() ;
X
X# ifndef SUNOS40
X	/* Read current text information */
X	size = Info.i_ntext * sizeof( struct text ) ;
X	if ( getkmem( (long)Info.i_text0, (char*)text, size ) != size )
X		prexit( "sps - Can't read system text table\n" ) ;
X# endif
X	/* Read current process information */
X	size = Info.i_nproc * sizeof( struct proc ) ;
X	p0 = (struct proc*)getcore( size ) ;
X	if ( getkmem( (long)Info.i_proc0, (char*)p0, size ) != size )
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_FILE
  if test 1281 -ne `wc -c <'readstatus.c'`; then
    echo shar: \"'readstatus.c'\" unpacked with wrong size!
  fi
  # end of 'readstatus.c'
fi
if test -f 'selectproc.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'selectproc.c'\"
else
  echo shar: Extracting \"'selectproc.c'\" \(2248 characters\)
  sed "s/^X//" >'selectproc.c' <<'END_OF_FILE'
X# ifndef lint
Xstatic char SccsId[] =  "@(#)selectproc.c	1.2\t6/15/90" ;
X# endif
X
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# ifdef SUNOS40
X				/* Ignore the idle processes */
X				return ( p->pr_p.p_pid != 3
X				    && p->pr_p.p_pid != 4 ) ;
X# else
X				return ( 1 ) ;
X# endif SUNOS40
X			break ;
X		case SSLEEP :
X			if ( Flg.flg_B
X			&&   p->pr_p.p_pri < PZERO && p->pr_p.p_pid > MSPID )
X# ifdef SUNOS40
X				/* Ignore the idle processes */
X				return ( p->pr_p.p_pid != 3
X				    && p->pr_p.p_pid != 4 ) ;
X# else
X				return ( 1 ) ;
X# endif SUNOS40
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_FILE
  if test 2248 -ne `wc -c <'selectproc.c'`; then
    echo shar: \"'selectproc.c'\" unpacked with wrong size!
  fi
  # end of 'selectproc.c'
fi
if test -f 'termwidth.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'termwidth.c'\"
else
  echo shar: Extracting \"'termwidth.c'\" \(978 characters\)
  sed "s/^X//" >'termwidth.c' <<'END_OF_FILE'
X# ifndef lint
Xstatic char SccsId[] =  "@(#)termwidth.c	1.3\t8/6/90" ;
X# endif
X
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# else
X# ifdef TIOCGSIZE
X	struct ttysize          w ;
X# endif
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# else
X# ifdef TIOCGSIZE
X	w.ts_cols = 0 ;
X	if ( !ioctl( 0, TIOCGSIZE, &w ) && w.ts_cols )
X	{
X		Termwidth = w.ts_cols ;
X		return ;
X	}
X# endif
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_FILE
  if test 978 -ne `wc -c <'termwidth.c'`; then
    echo shar: \"'termwidth.c'\" unpacked with wrong size!
  fi
  # end of 'termwidth.c'
fi
if test -f 'vmstat.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'vmstat.c'\"
else
  echo shar: Extracting \"'vmstat.c'\" \(1902 characters\)
  sed "s/^X//" >'vmstat.c' <<'END_OF_FILE'
X# ifndef lint
Xstatic char SccsId[] =  "@(#)vmstat.c	1.1\t10/1/88" ;
X# endif
X
X# ifdef SUNOS40
X# ifndef OLDSTATS
X# include "sps.h"
X# include <h/mman.h>
X# include <vm/hat.h>
X# include <vm/as.h>
X# include <vm/seg.h>
X# include <vm/seg_vn.h>
X
Xseg_count ( p )
X
Xstruct process                  *p ;
X
X{
X	extern struct info      Info ;
X	struct as               as ;		/* address space */
X	struct seg              seg ;		/* segment in addr space */
X	struct segvn_data       vn_data ;
X	unsigned                private = 0 ;
X	unsigned                shared = 0 ;
X
X	p->pr_private = 0 ;
X	p->pr_shared = 0 ;
X
X	if ( getkmem( (long)p->pr_p.p_as, &as, sizeof( as ) ) != sizeof( as ) )
X		return( -1 ) ;
X	seg.s_next = as.a_segs ;	/* setup for loop */
X	do
X	{
X		if ( ( getkmem( seg.s_next, &seg, sizeof( seg ) ) )
X		!= sizeof( seg ) )
X			break ;
X		if ( seg.s_as != p->pr_p.p_as )
X			continue ;	/* invalid segment */
X		if ( seg.s_ops != Info.i_segvn_ops )
X		{			/* mapped device is "shared" */
X			shared += seg.s_size ;
X			continue ;
X		}
X		if ( getkmem( (long)seg.s_data, &vn_data, sizeof( vn_data ) )
X		!= sizeof( vn_data ) )
X			continue ;
X		/*
X		 * If a segment has an anonymous mapping, it is in the swap
X		 * area.  If it is also MAP_PRIVATE, we consider it "private"
X		 * (even though it may be shared between parent and child after
X		 * a fork() call).  Segments without an anonymous mapping are
X		 * considered to be "shared".  [Should we worry about swap
X		 * space reserved for copy-on-write shared segments?]
X		 */
X
X		if ( vn_data.amp && (vn_data.type & MAP_TYPE) == MAP_PRIVATE )
X			private += seg.s_size ;
X		else
X			shared += seg.s_size ;
X	}
X	while ( seg.s_next != as.a_segs ) ;
X
X# define BYTETOPAGE(x) (((x)+(PAGESIZE-1))>>PGSHIFT)
X
X	p->pr_private = BYTETOPAGE( private ) ;
X	p->pr_shared = BYTETOPAGE( shared ) ;
X	p->pr_p.p_rssize = as.a_rss ;	/* update count of resident pages */
X	return( 0 ) ;
X}
X# endif
X# endif
END_OF_FILE
  if test 1902 -ne `wc -c <'vmstat.c'`; then
    echo shar: \"'vmstat.c'\" unpacked with wrong size!
  fi
  # end of 'vmstat.c'
fi
echo shar: End of archive 3 \(of 4\).
cp /dev/null ark3isdone
MISSING=""
for I in 1 2 3 4 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 4 archives.
    rm -f ark[1-9]isdone
else
    echo You still must unpack the following archives:
    echo "        " ${MISSING}
fi
exit 0
exit 0 # Just in case...
-- 
Please send comp.sources.unix-related mail to rsalz at uunet.uu.net.
Use a domain-based address or give alternate paths, or you may lose out.



More information about the Comp.sources.unix mailing list