home *** CD-ROM | disk | FTP | other *** search
- From: robert@olsen.UUCP (Robert Ward)
- Newsgroups: alt.sources
- Subject: SPS for SunOS4.1 and DEC 3100's - Shar 2 of 3
- Message-ID: <200@frey.UUCP>
- Date: 19 Nov 90 15:43:16 GMT
-
-
- #!/bin/sh
- #
- # This is a shar (shell archive) file.
- # In order to extract the contents of this archive, remove everything
- # above the "#!/bin/sh" line. Then execute the remaining file with
- # /bin/sh. The following file(s) will be extracted:
- # filecount.c
- # findtty.c
- # flagdecode.c
- # flags.h
- # flagsetup.c
- # getcmd.c
- # getupage.c
- # globals1.c
- # globals2.c
- # hashuid.c
- # initialise.c
- # initsymbols.c
- # inittty.c
- # main.c
- # mktree.c
- # needed.c
- # openfiles.c
- #
- #
- # This archive was generated on Mon Aug 6 17:53:37 MET DST 1990
- #
- #
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if [ -f 'filecount.c' -a "${1}" != "-c" ] ; then
- echo shar: Won\'t overwrite existing file "filecount.c"
- exit 2
- fi
- echo x - filecount.c
- sed -e 's/^X//' > filecount.c << '---END-OF-filecount.c---'
- 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-filecount.c---
- LEN=`wc -c < filecount.c`
- if [ $LEN != 1585 ] ; then
- echo shar: File "filecount.c" was $LEN, should have been 1585 bytes
- fi
- if [ -f 'findtty.c' -a "${1}" != "-c" ] ; then
- echo shar: Won\'t overwrite existing file "findtty.c"
- exit 2
- fi
- echo x - findtty.c
- sed -e 's/^X//' > findtty.c << '---END-OF-findtty.c---'
- 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-findtty.c---
- LEN=`wc -c < findtty.c`
- if [ $LEN != 1324 ] ; then
- echo shar: File "findtty.c" was $LEN, should have been 1324 bytes
- fi
- if [ -f 'flagdecode.c' -a "${1}" != "-c" ] ; then
- echo shar: Won\'t overwrite existing file "flagdecode.c"
- exit 2
- fi
- echo x - flagdecode.c
- sed -e 's/^X//' > flagdecode.c << '---END-OF-flagdecode.c---'
- X# ifndef lint
- Xstatic char SccsId[] = "@(#)flagdecode.c 1.1\t10/1/88" ;
- X# endif
- X
- X# include "sps.h"
- X# include "flags.h"
- X
- X/* FLAGDECODE - Looks at the argument list and sets various internal switches */
- Xflagdecode ( argc, argv )
- X
- Xregister int argc ;
- Xregister char **argv ;
- X
- X{
- X register char *chp ;
- X union flaglist *plist ;
- X union flaglist *tlist ;
- X union flaglist *ulist ;
- X static char usage[] =
- X "sps - Unknown option %s\nUsage - sps [ -dcefgijkoqrsvwyABFNPSTUWZ ][ process|tty|user ] ...\n";
- X union flaglist *getflgsp() ;
- X extern struct flags Flg ;
- X
- X plist = tlist = ulist = (union flaglist*)0 ;
- X for ( argv++ ; --argc ; argv++ )
- X {
- X chp = *argv ;
- X while ( *chp )
- X switch ( *chp++ )
- X {
- X case '-' :
- X /* Separation character */
- X continue ;
- X case 'c' :
- X case 'C' :
- X /* Print stored command, not args */
- X Flg.flg_c = 1 ;
- X continue ;
- X case 'd' :
- X case 'D' :
- X /* List disc orientated information */
- X Flg.flg_d = 1 ;
- X Flg.flg_v = 0 ;
- X continue ;
- X case 'e' :
- X case 'E' :
- X /* List environment strings */
- X Flg.flg_e = 1 ;
- X continue ;
- X case 'f' :
- X /* List the father's process id */
- X Flg.flg_f = 1 ;
- X continue ;
- X case 'g' :
- X case 'G' :
- X /* List the process group id */
- X Flg.flg_g = 1 ;
- X continue ;
- X case 'i' :
- X case 'I' :
- X /* Initialise (super-user only) */
- X Flg.flg_i = 1 ;
- X continue ;
- X case 'j' :
- X case 'J' :
- X /* The next argument specifies the
- X name of the information file */
- X if ( argc <= 1 )
- X prexit(
- X "sps - Name of an information file expected after `-j' flag\n" ) ;
- X argc-- ;
- X Flg.flg_j = *++argv ;
- X continue ;
- X case 'k' :
- X case 'K' :
- X /* Use a disc file such as /vmcore
- X rather than /dev/{k}mem for
- X accessing kernel data. The next
- X argument specifies the file name. */
- X if ( argc <= 1 )
- X prexit(
- X "sps - Name of a memory dump file expected after `-k' flag\n" ) ;
- X argc-- ;
- X Flg.flg_k = *++argv ;
- X Flg.flg_o = 1 ;
- X continue ;
- X case 'l' :
- X case 'v' :
- X case 'L' :
- X case 'V' :
- X /* Verbose output */
- X Flg.flg_d = 0 ;
- X Flg.flg_v = 1 ;
- X continue ;
- X case 'o' :
- X case 'O' :
- X /* Avoid looking at the swap device */
- X Flg.flg_o = 1 ;
- X continue ;
- X case 'q' :
- X case 'Q' :
- X /* Show only the user time, not the
- X user + system times together. */
- X Flg.flg_q = 1 ;
- X continue ;
- X case 'r' :
- X case 'R' :
- X /* Repeat output every n seconds.
- X The next argument specifies n which
- X defaults to 5 if omitted. */
- X Flg.flg_r = 1 ;
- X if ( argc > 1 )
- X {
- X if ( **++argv >= '0'
- X && **argv <= '9' )
- X {
- X argc-- ;
- X Flg.flg_rdelay
- X = atoi( *argv ) ;
- X continue ;
- X }
- X argv-- ;
- X }
- X Flg.flg_rdelay = 0 ;
- X continue ;
- X case 's' :
- X /* Next argument specifies a symbol
- X file rather than the default
- X /vmunix. */
- X if ( argc <= 1 )
- X prexit(
- X "sps - Name of a symbol file expected after `-s' flag\n" ) ;
- X argc-- ;
- X Flg.flg_s = *++argv ;
- X continue ;
- X case 'w' :
- X /* Wide output, exceeding 79 columns */
- X Flg.flg_w = 1 ;
- X continue ;
- X case 'y' :
- X case 'Y' :
- X /* List current tty information */
- X Flg.flg_y = 1 ;
- X continue ;
- X case 'a' :
- X case 'A' :
- X /* List all processes */
- X Flg.flg_AZ = 1 ;
- X Flg.flg_A = 1 ;
- X continue ;
- X case 'b' :
- X case 'B' :
- X /* List only busy processes */
- X Flg.flg_AZ = 1 ;
- X Flg.flg_B = 1 ;
- X continue ;
- X case 'F' :
- X /* List only foreground processes */
- X Flg.flg_AZ = 1 ;
- X Flg.flg_F = 1 ;
- X continue ;
- X case 'n' :
- X case 'N' :
- X /* No processes, just the summary line*/
- X Flg.flg_AZ = 1 ;
- X Flg.flg_N = 1 ;
- X continue ;
- X case 'p' :
- X case 'P' :
- X /* List only the given process ids */
- X Flg.flg_AZ = 1 ;
- X Flg.flg_P = 1 ;
- X if ( !plist )
- X plist=Flg.flg_Plist=getflgsp( argc );
- X while ( argc > 1 )
- X {
- X if ( **++argv == '-' )
- X {
- X --argv ;
- X break ;
- X }
- X --argc ;
- X plist->f_chp = *argv ;
- X (++plist)->f_chp = (char*)0 ;
- X }
- X continue ;
- X case 'S' :
- X /* List only stopped processes */
- X Flg.flg_AZ = 1 ;
- X Flg.flg_S = 1 ;
- X continue ;
- X case 't' :
- X case 'T' :
- X /* List only processes attached to the
- X specified terminals */
- X Flg.flg_AZ = 1 ;
- X Flg.flg_T = 1 ;
- X if ( !tlist )
- X tlist=Flg.flg_Tlist=getflgsp( argc );
- X while ( argc > 1 )
- X {
- X if ( **++argv == '-' )
- X {
- X --argv ;
- X break ;
- X }
- X --argc ;
- X tlist->f_chp = *argv ;
- X (++tlist)->f_chp = (char*)0 ;
- X }
- X continue ;
- X case 'u' :
- X case 'U' :
- X /* List only processes belonging to the
- X specified users */
- X Flg.flg_AZ = 1 ;
- X Flg.flg_U = 1 ;
- X if ( !ulist )
- X ulist=Flg.flg_Ulist=getflgsp( argc );
- X while ( argc > 1 )
- X {
- X if ( **++argv == '-' )
- X {
- X --argv ;
- X break ;
- X }
- X --argc ;
- X ulist->f_chp = *argv ;
- X (++ulist)->f_chp = (char*)0 ;
- X }
- X continue ;
- X case 'W' :
- X /* List only waiting processes */
- X Flg.flg_AZ = 1 ;
- X Flg.flg_W = 1 ;
- X continue ;
- X case 'z' :
- X case 'Z' :
- X /* List only zombie processes */
- X Flg.flg_AZ = 1 ;
- X Flg.flg_Z = 1 ;
- X continue ;
- X default :
- X prexit( usage, *argv ) ;
- X /* NOTREACHED */
- X }
- X }
- X}
- ---END-OF-flagdecode.c---
- LEN=`wc -c < flagdecode.c`
- if [ $LEN != 5627 ] ; then
- echo shar: File "flagdecode.c" was $LEN, should have been 5627 bytes
- fi
- if [ -f 'flags.h' -a "${1}" != "-c" ] ; then
- echo shar: Won\'t overwrite existing file "flags.h"
- exit 2
- fi
- echo x - flags.h
- sed -e 's/^X//' > flags.h << '---END-OF-flags.h---'
- X# ifndef lint
- Xstatic char FlagsHId[] = "@(#)flags.h 1.1\t10/1/88" ;
- X# endif
- X
- 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_c:1 ; /* print command from upage */
- 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---
- LEN=`wc -c < flags.h`
- if [ $LEN != 2638 ] ; then
- echo shar: File "flags.h" was $LEN, should have been 2638 bytes
- fi
- if [ -f 'flagsetup.c' -a "${1}" != "-c" ] ; then
- echo shar: Won\'t overwrite existing file "flagsetup.c"
- exit 2
- fi
- echo x - flagsetup.c
- sed -e 's/^X//' > flagsetup.c << '---END-OF-flagsetup.c---'
- 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-flagsetup.c---
- LEN=`wc -c < flagsetup.c`
- if [ $LEN != 2342 ] ; then
- echo shar: File "flagsetup.c" was $LEN, should have been 2342 bytes
- fi
- if [ -f 'getcmd.c' -a "${1}" != "-c" ] ; then
- echo shar: Won\'t overwrite existing file "getcmd.c"
- exit 2
- fi
- echo x - getcmd.c
- sed -e 's/^X//' > getcmd.c << '---END-OF-getcmd.c---'
- X# ifndef lint
- Xstatic char SccsId[] = "@(#)getcmd.c 1.7\t8/6/90" ;
- X# endif
- X
- X# include "sps.h"
- X# include "flags.h"
- X# ifdef KVM
- X# include <kvm.h>
- X# include <ctype.h>
- X# else
- X# include <h/vm.h>
- X# ifdef BSD42
- X# include <machine/pte.h>
- X# else BSD42
- X# include <h/pte.h>
- X# endif BSD42
- X# endif KVM
- X
- X/*
- X** GETCMD - Returns a character string read from a process' upage.
- X** This character string should represent the arguments to the current process.
- X*/
- Xchar *getcmd ( p )
- X
- Xregister struct process *p ;
- X
- X{
- X# ifdef KVM
- X char **ap ;
- X char *cp ;
- X char *sp ;
- X char **argv ;
- X char **env ;
- X extern kvm_t *Flkvm ;
- X# else
- X register int *ip ;
- X register char *cp ;
- X register char *cp0 ;
- X struct dblock db ;
- X struct pte ptetbl[ UPAGES + CLSIZE ] ;
- X extern int Flmem, Flswap ;
- X# endif
- X unsigned nbad ;
- X union
- X {
- X char a_argc[ CLSIZE * NBPG ] ;
- X int a_argi[ CLSIZE * NBPG / sizeof( int ) ] ;
- X } argbuf ;
- X extern struct flags Flg ;
- X extern union userstate User ;
- X char *strcat(), *strncpy(), *strsave() ;
- X
- X p->pr_csaved = 0 ;
- X p->pr_upag = 0 ;
- X if ( p->pr_p.p_stat == SZOMB )
- X return ( "** Exit **" ) ;
- X if ( !(p->pr_p.p_flag & SLOAD) && Flg.flg_o )
- X return ( "** Swapped out **" ) ;
- X /* Find the process' upage */
- X# ifdef KVM
- X if ( !getupage( p ) )
- X# else
- X if ( !getupage( p, ptetbl ) )
- X# endif
- X return ( "** No upage **" ) ;
- X p->pr_upag = 1 ;
- X /* Is this a system process ? */
- X if ( p->pr_p.p_flag & SSYS )
- X switch ( p->pr_p.p_pid )
- X {
- X case 0 :
- X return ( "Unix Swapper" ) ;
- X case 2 :
- X return ( "Unix Pager" ) ;
- X# ifdef SUNOS40
- X case 3 :
- X case 4 :
- X return ( "Unix Idle" ) ;
- X# endif
- X default :
- X break ;
- X }
- X# ifdef DEC3100
- X /* Reading the command arguments doesn't work on the DEC 3100 so
- X we resort to this kludge until one day it does. */
- X if ( 1 )
- X# else DEC3100
- X if ( Flg.flg_c )
- X# endif DEC3100
- X {
- X p->pr_csaved = 1 ;
- X (void)strncpy( argbuf.a_argc, User.u_us.u_comm,
- X sizeof( User.u_us.u_comm ) ) ;
- X argbuf.a_argc[ sizeof ( User.u_us.u_comm ) ] = '\0' ;
- X return ( strsave( argbuf.a_argc ) ) ;
- X }
- X# ifdef KVM
- X if ( kvm_getcmd( Flkvm, &p->pr_p, &User.u_us, &argv,
- X Flg.flg_e ? &env : (char ***)NULL ) < 0 || argv == NULL )
- X goto getsysargs ;
- X p->pr_csaved = 1 ;
- X sp = argbuf.a_argc ;
- X nbad = 0 ;
- X ap = argv ;
- X do {
- X /* Copy one string from argv or env */
- X for ( cp = *ap++; *cp; )
- X if ( isprint( *cp ) )
- X *sp++ = *cp++ ;
- X else
- X {
- X /* Replace control characters with ?'s */
- X if ( ++nbad > 5 )
- X {
- X *sp++ = ' ' ;
- X break ;
- X }
- X *sp++ = '?' ;
- X cp++ ;
- X }
- X *sp++ = ' ' ;
- X /* Check if at end of argv and user wants to see env */
- X if ( *ap == 0 && Flg.flg_e && argv != 0 )
- X {
- X free( (char *) argv ) ;
- X argv = NULL ;
- X ap = env ;
- X if ( ap == NULL )
- X break ;
- X }
- X } while ( *ap ) ;
- X if ( Flg.flg_e )
- X free( (char*)env ) ;
- X while ( *--sp == ' ' )
- X *sp = '\0' ;
- X return ( strsave( argbuf.a_argc ) ) ;
- X# else
- X /* Fix by Alexander Dupuy <dupuy@amsterdam.columbia.edu> */
- X /* Check for lack of stack, jack! (Sun 3.0 biod's) */
- X if (User.u_us.u_ssize == 0)
- X goto getsysargs ;
- X /* Look at the top of the upage to locate the command arguments.
- X The page is loaded if the process itself is loaded and the pte
- X contains is marked as valid. */
- X if ( (p->pr_p.p_flag & SLOAD)
- X && !ptetbl[0].pg_fod && ptetbl[0].pg_pfnum )
- X { /* If the page is loaded, read the arguments from
- X physical memory. */
- X memseek( Flmem, (long)ctob( ptetbl[0].pg_pfnum ) ) ;
- X if ( read( Flmem, argbuf.a_argc, CLSIZE*NBPG ) != CLSIZE*NBPG )
- X return ( "** Memory read error **" ) ;
- X }
- X else
- X { /* Otherwise the page is on the swap device */
- X vstodb( 0, ctod( CLSIZE ), &User.u_us.u_smap, &db, 1 ) ;
- X# ifdef BSD42
- X swseek( (long)dtob( db.db_base ) ) ;
- X# else
- X swseek( (long)ctob( db.db_base ) ) ;
- X# endif
- X if ( Flg.flg_o )
- X return ( "** Swapped page **" ) ;
- X if ( read( Flswap, argbuf.a_argc, CLSIZE*NBPG ) != CLSIZE*NBPG )
- X return ( "** Swap device read error **" ) ;
- X }
- X /* Look down until the end of command arguments is found. */
- X ip = &argbuf.a_argi[ CLSIZE*NBPG / sizeof( int ) ] ;
- X ip -= 2 ;
- X while ( *--ip )
- X if ( ip == &argbuf.a_argi[0] )
- X goto getsysargs ;
- X p->pr_csaved = 1 ;
- X /* Process the command arguments, looking for nulls and unprintable
- X characters. */
- X cp0 = (char*)(ip + 1) ;
- X if ( !*cp0 )
- X cp0++ ;
- X if ( *cp0 )
- X {
- X nbad = 0 ;
- X for ( cp = cp0 ; cp < &argbuf.a_argc[ CLSIZE*NBPG ] ; cp++ )
- X {
- X *cp &= 0177 ;
- X if ( !*cp )
- X { /* Replace nulls with spaces */
- X *cp = ' ' ;
- X continue ;
- X }
- X if ( *cp < ' ' || *cp == 0177 )
- X { /* Replace control characters with ?'s */
- X if ( ++nbad > 5 )
- X {
- X *cp++ = ' ' ;
- X break ;
- X }
- X *cp = '?' ;
- X continue ;
- X }
- X if ( !Flg.flg_e && *cp == '=' )
- X { /* Break on an `=' if we are not interested
- X in the environment strings. */
- X *cp = '\0' ;
- X while ( cp > cp0 && *--cp != ' ' )
- X *cp = '\0' ;
- X break ;
- X }
- X }
- X while ( *--cp == ' ' )
- X *cp = '\0' ;
- X return ( strsave( cp0 ) ) ;
- X }
- X# endif KVM
- Xgetsysargs :
- X /* If the command arguments cannot be accessed from the user's memory
- X space, get the command name from the system's idea of what the
- X name should be. */
- X p->pr_csaved = 1 ;
- X argbuf.a_argc[0] = '(' ;
- X (void)strncpy( &argbuf.a_argc[1], User.u_us.u_comm,
- X sizeof( User.u_us.u_comm ) ) ;
- X argbuf.a_argc[ sizeof ( User.u_us.u_comm ) + 1 ] = '\0' ;
- X (void)strcat( &argbuf.a_argc[0], ")" ) ;
- X return ( strsave( argbuf.a_argc ) ) ;
- X}
- X
- X# ifndef KVM
- X/*
- X** VSTODB - Given a base/size pair in virtual swap area,
- X** return a physical base/size pair which is the
- X** (largest) initial, physically contiguous block.
- X/* This code is stolen from the kernel file /sys/sys/vm_drum.c.
- X*/
- Xvstodb ( vsbase, vssize, dmp, dbp, rev )
- X
- Xregister int vsbase ;
- Xregister int vssize;
- Xstruct dmap *dmp ;
- Xregister struct dblock *dbp ;
- Xint rev ;
- X
- X{
- X register int blk ;
- X register swblk_t *ip ;
- X# ifdef BSD42
- X extern struct info Info ;
- X# endif
- X
- X# ifdef BSD42
- X blk = Info.i_dmmin ;
- X# else
- X blk = DMMIN ;
- X# endif
- X ip = dmp->dm_map ;
- X while ( vsbase >= blk )
- X {
- X vsbase -= blk ;
- X# ifdef BSD42
- X if ( blk < Info.i_dmmax )
- X# else
- X if ( blk < DMMAX )
- X# endif
- X blk *= 2 ;
- X ip++ ;
- X }
- X dbp->db_size = vssize < blk - vsbase ? vssize : blk - vsbase ;
- X dbp->db_base = *ip + (rev ? blk - (vsbase + dbp->db_size) : vsbase);
- X}
- X# endif
- ---END-OF-getcmd.c---
- LEN=`wc -c < getcmd.c`
- if [ $LEN != 6872 ] ; then
- echo shar: File "getcmd.c" was $LEN, should have been 6872 bytes
- fi
- if [ -f 'getupage.c' -a "${1}" != "-c" ] ; then
- echo shar: Won\'t overwrite existing file "getupage.c"
- exit 2
- fi
- echo x - getupage.c
- sed -e 's/^X//' > getupage.c << '---END-OF-getupage.c---'
- X# ifndef lint
- Xstatic char SccsId[] = "@(#)getupage.c 1.3\t8/2/90" ;
- X# endif
- X
- X# include "sps.h"
- X# ifdef KVM
- X# include <kvm.h>
- X# else
- X# include <h/vm.h>
- X# ifdef BSD42
- X# include <machine/pte.h>
- X# else
- X# include <h/pte.h>
- X# endif
- 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# ifndef KVM
- 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 BSD42
- X swseek( (long)ctob( p->pr_p.p_swaddr ) ) ;
- X# endif BSD42
- X# ifdef SUN
- X if ( read( Flswap, (char*)&User.u_us, sizeof( union userstate ))
- X != sizeof( union userstate ) )
- X# else SUN
- X if ( read( Flswap, (char*)&User.u_us, sizeof( struct user ) )
- X != sizeof( struct user ) )
- X# endif SUN
- 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# ifdef DEC3100
- X /* This method of accessing the upage suffices on the DEC Station
- X but only provides sufficient pte's to read the upage, leaving the
- X command arguments inaccessible. */
- X memseek( Flkmem, (long)p->pr_p.p_addr ) ;
- X if ( read( Flkmem, (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# else DEC3100
- 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# endif DEC3100
- 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# ifdef DEC3100
- X memseek( Flmem, (long)ctob( ptetbl[ i ].pg_pfnum ) ) ;
- X# else DEC3100
- X memseek( Flmem, (long)ctob( ptetbl[ CLSIZE+i ].pg_pfnum ) ) ;
- X# endif DEC3100
- 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}
- X
- X# else KVM
- X
- Xgetupage ( p )
- X
- Xregister struct process *p ;
- X
- X{
- X struct user *upage ;
- X extern union userstate User ;
- X extern kvm_t *Flkvm ;
- X
- X if (upage = kvm_getu( Flkvm, &p->pr_p ) )
- X {
- X bcopy( (char *)upage, User.u_pg[0], sizeof( struct user ) ) ;
- X return ( 1 ) ;
- X }
- X fprintf( stderr, "sps - Can't read upage of process %d\n",
- X p->pr_p.p_pid ) ;
- X return ( 0 ) ;
- X}
- X
- X# endif KVM
- ---END-OF-getupage.c---
- LEN=`wc -c < getupage.c`
- if [ $LEN != 4161 ] ; then
- echo shar: File "getupage.c" was $LEN, should have been 4161 bytes
- fi
- if [ -f 'globals1.c' -a "${1}" != "-c" ] ; then
- echo shar: Won\'t overwrite existing file "globals1.c"
- exit 2
- fi
- echo x - globals1.c
- sed -e 's/^X//' > globals1.c << '---END-OF-globals1.c---'
- 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-globals1.c---
- LEN=`wc -c < globals1.c`
- if [ $LEN != 945 ] ; then
- echo shar: File "globals1.c" was $LEN, should have been 945 bytes
- fi
- if [ -f 'globals2.c' -a "${1}" != "-c" ] ; then
- echo shar: Won\'t overwrite existing file "globals2.c"
- exit 2
- fi
- echo x - globals2.c
- sed -e 's/^X//' > globals2.c << '---END-OF-globals2.c---'
- X# ifndef lint
- Xstatic char SccsId[] = "@(#)globals2.c 1.2\t7/4/90" ;
- X# endif
- X
- X# include "sps.h"
- X
- X/* Read Only variables, global to the code of sps ... */
- X
- X/* Null ttyline device ... */
- Xstruct ttyline Notty = { " " } ;
- X
- X/*
- X** The symbol table. For each address read from the kernel during
- X** initialisation, this table shows the following:
- X** i. the name of that symbol within the kernel ;
- X** ii. whether an extra indirection is needed through the kernel,
- X** i.e. whether the value of that symbol should be obtained
- X** rather than its address.
- X** iii. where the obtained value/address is placed in the Info structure ;
- X** iv. whether the obtained value is associated with a reason for
- X** a process wait state.
- X*/
- X/* The order of entries in this table is unimportant. */
- X
- Xextern struct info Info ;
- X
- Xstruct symbol Symbollist[] =
- X{
- X /* Kernel addresses required in order to access process,
- X tty and upage information. All these addresses should be
- X located in the symbol file during initialisation. */
- X { "_proc", 1, (caddr_t*)&Info.i_proc0, (char*)0 },
- X { "_nproc", 1, (caddr_t*)&Info.i_nproc, (char*)0 },
- X# ifdef ULTRIX20
- X { "_gnode", 1, (caddr_t*)&Info.i_inode0, (char*)0 },
- X { "_ngnode", 1, (caddr_t*)&Info.i_ninode, (char*)0 },
- X# else
- X# ifndef SUNOS41
- X { "_inode", 1, (caddr_t*)&Info.i_inode0, (char*)0 },
- X# endif SUNOS41
- X { "_ninode", 1, (caddr_t*)&Info.i_ninode, (char*)0 },
- X# endif ULTRIX20
- X
- X# ifndef SUNOS40
- X { "_text", 1, (caddr_t*)&Info.i_text0, (char*)0 },
- X { "_ntext", 1, (caddr_t*)&Info.i_ntext, (char*)0 },
- X { "_swbuf", 1, (caddr_t*)&Info.i_swbuf0, (char*)0 },
- X { "_nswbuf", 1, (caddr_t*)&Info.i_nswbuf, (char*)0 },
- X { "_buf", 1, (caddr_t*)&Info.i_buf0, (char*)0 },
- X { "_nbuf", 1, (caddr_t*)&Info.i_nbuf, (char*)0 },
- X { "_ecmx", 1, (caddr_t*)&Info.i_ecmx, (char*)0 },
- X { "_Usrptmap", 0, (caddr_t*)&Info.i_usrptmap, (char*)0 },
- X { "_usrpt", 0, (caddr_t*)&Info.i_usrpt, (char*)0 },
- X { "_dmmin", 1, (caddr_t*)&Info.i_dmmin, (char*)0 },
- X { "_dmmax", 1, (caddr_t*)&Info.i_dmmax, (char*)0 },
- X# endif SUNOS40
- X
- X { "_cdevsw", 0, (caddr_t*)&Info.i_cdevsw, (char*)0 },
- X# ifdef BSD42
- X# ifdef NFS
- X# ifndef NOQUOTA
- X { "_dquot", 1, (caddr_t*)&Info.i_quota0, (char*)0 },
- X { "_ndquot", 1, (caddr_t*)&Info.i_nquota, (char*)0 },
- X# endif NOQUOTA
- X# else NFS
- X { "_quota", 1, (caddr_t*)&Info.i_quota0, (char*)0 },
- X { "_nquota", 1, (caddr_t*)&Info.i_nquota, (char*)0 },
- X# endif NFS
- X { "_mbutl", 0, (caddr_t*)&Info.i_mbutl, (char*)0 },
- X# else BSD42
- X { "_hz", 1, (caddr_t*)&Info.i_hz, (char*)0 },
- X# endif BSD42
- X
- X# ifdef CHAOS
- X { "_Chconntab", 0, &Info.i_Chconntab, (char*)0 },
- X# endif CHAOS
- X
- X# ifdef SUNOS40
- X { "_maxmem", 1, (caddr_t*)&Info.i_ecmx, (char*)0 },
- X { "_segvn_ops", 0, (caddr_t*)&Info.i_segvn_ops,(char*)0 },
- X { "_pty_softc", 0, (caddr_t*)&Info.i_ptybase, (char*)0 },
- X { "_npty", 1, (caddr_t*)&Info.i_npty, (char*)0 },
- X# ifdef SUNOS41
- X { "_strst", 0, (caddr_t*)&Info.i_strst, (char*)0 },
- X { "_allstream", 1, (caddr_t*)&Info.i_allstream, (char*)0 },
- X# else SUNOS41
- X { "_streams", 0, (caddr_t*)&Info.i_streams, (char*)0 },
- X { "_streamsNSTREAMS", 1, (caddr_t*)&Info.i_streamsNSTREAMS ,(char*)0 },
- X# endif SUNOS41
- X { "_Sysbase", 1, (caddr_t*)&Info.i_sysbase, (char*)0 },
- X# endif SUNOS40
- X
- X /* Kernel addresses associated with process wait states.
- X It is not important if some of these addresses are unresolved
- X at initialisation. */
- X# ifndef SUN
- X { "_fltab", 0, &Info.i_waitstate[0], "floppy" },
- X { "_tu", 0, &Info.i_waitstate[1], "tu58" },
- X { "_lp_softc", 0, &Info.i_waitstate[3], "printr" },
- X# endif SUN
- X { "_bfreelist", 0, &Info.i_waitstate[2], "buffer" },
- X { "_lbolt", 0, &Info.i_waitstate[4], "lbolt" },
- X { "_runin", 0, &Info.i_waitstate[5], "runin" },
- X { "_runout", 0, &Info.i_waitstate[6], "runout" },
- X { "_ipc", 0, &Info.i_waitstate[7], "ptrace" },
- X# ifdef SUNOS41
- X { "_uunix", 0, &Info.i_waitstate[8], "pause" },
- X# else SUNOS41
- X { "_u", 0, &Info.i_waitstate[8], "pause" },
- X# endif SUNOS41
- X { "_freemem", 0, &Info.i_waitstate[9], "freemm" },
- X { "_kernelmap", 0, &Info.i_waitstate[10], "kermap" },
- X { "_cwaiting", 0, &Info.i_waitstate[11], "cwait" },
- X# ifdef BSD42
- X { "_selwait", 0, &Info.i_waitstate[12], "select" },
- X# endif BSD42
- X# ifdef CHAOS
- X { "_Chrfclist", 0, &Info.i_waitstate[13], "chrfc" },
- X# endif CHAOS
- X# ifndef SUN
- X { "_rhpbuf", 0, &Info.i_waitstate[14], "rhpbuf" },
- X { "_rhtbuf", 0, &Info.i_waitstate[15], "rhtbuf" },
- X { "_ridcbuf", 0, &Info.i_waitstate[16], "ridcbf" },
- X { "_rikbuf", 0, &Info.i_waitstate[17], "rikbuf" },
- X { "_rmtbuf", 0, &Info.i_waitstate[18], "rmtbuf" },
- X { "_rrkbuf", 0, &Info.i_waitstate[19], "rrkbuf" },
- X { "_rrlbuf", 0, &Info.i_waitstate[20], "rrlbuf" },
- X { "_rrxbuf", 0, &Info.i_waitstate[21], "rrxbuf" },
- X { "_rswbuf", 0, &Info.i_waitstate[22], "rswbuf" },
- X { "_rtmbuf", 0, &Info.i_waitstate[23], "rtmbuf" },
- X { "_rtsbuf", 0, &Info.i_waitstate[24], "rtsbuf" },
- X { "_rudbuf", 0, &Info.i_waitstate[25], "rudbuf" },
- X { "_rupbuf", 0, &Info.i_waitstate[26], "rupbuf" },
- X { "_rutbuf", 0, &Info.i_waitstate[27], "rutbuf" },
- X { "_rvabuf", 0, &Info.i_waitstate[28], "rvabuf" },
- X { "_rvpbuf", 0, &Info.i_waitstate[29], "rvpbuf" },
- X { "_chtbuf", 0, &Info.i_waitstate[30], "chtbuf" },
- X { "_cmtbuf", 0, &Info.i_waitstate[31], "cmtbuf" },
- X { "_ctmbuf", 0, &Info.i_waitstate[32], "ctmbuf" },
- X { "_ctsbuf", 0, &Info.i_waitstate[33], "ctsbuf" },
- X { "_cutbuf", 0, &Info.i_waitstate[34], "cutbuf" },
- X# ifdef NFS
- X { "_async_bufhead", 0, &Info.i_waitstate[35], "async" },
- X# endif NFS
- X# else SUN
- X { "_async_bufhead", 0, &Info.i_waitstate[14], "async" },
- X { "_desktops", 0, &Info.i_waitstate[15], "dtops" },
- X# endif SUN
- X# ifdef ULTRIX20
- X { "_async_bufhead", 0, &Info.i_waitstate[35], "async" },
- X# endif ULTRIX20
- X { (char*)0, 0, (caddr_t*)0, (char*)0 }
- X} ;
- ---END-OF-globals2.c---
- LEN=`wc -c < globals2.c`
- if [ $LEN != 6807 ] ; then
- echo shar: File "globals2.c" was $LEN, should have been 6807 bytes
- fi
- if [ -f 'hashuid.c' -a "${1}" != "-c" ] ; then
- echo shar: Won\'t overwrite existing file "hashuid.c"
- exit 2
- fi
- echo x - hashuid.c
- sed -e 's/^X//' > hashuid.c << '---END-OF-hashuid.c---'
- 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-hashuid.c---
- LEN=`wc -c < hashuid.c`
- if [ $LEN != 1515 ] ; then
- echo shar: File "hashuid.c" was $LEN, should have been 1515 bytes
- fi
- if [ -f 'initialise.c' -a "${1}" != "-c" ] ; then
- echo shar: Won\'t overwrite existing file "initialise.c"
- exit 2
- fi
- echo x - initialise.c
- sed -e 's/^X//' > initialise.c << '---END-OF-initialise.c---'
- 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-initialise.c---
- LEN=`wc -c < initialise.c`
- if [ $LEN != 1986 ] ; then
- echo shar: File "initialise.c" was $LEN, should have been 1986 bytes
- fi
- if [ -f 'initsymbols.c' -a "${1}" != "-c" ] ; then
- echo shar: Won\'t overwrite existing file "initsymbols.c"
- exit 2
- fi
- echo x - initsymbols.c
- sed -e 's/^X//' > initsymbols.c << '---END-OF-initsymbols.c---'
- 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@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-initsymbols.c---
- LEN=`wc -c < initsymbols.c`
- if [ $LEN != 3515 ] ; then
- echo shar: File "initsymbols.c" was $LEN, should have been 3515 bytes
- fi
- if [ -f 'inittty.c' -a "${1}" != "-c" ] ; then
- echo shar: Won\'t overwrite existing file "inittty.c"
- exit 2
- fi
- echo x - inittty.c
- sed -e 's/^X//' > inittty.c << '---END-OF-inittty.c---'
- X# ifndef lint
- Xstatic char SccsId[] = "@(#)inittty.c 1.1\t10/1/88" ;
- X# endif
- X
- X# include "sps.h"
- X# include <h/conf.h>
- X# include <h/ioctl.h>
- X# ifdef SUNOS40
- X# include <h/stream.h>
- X# else
- X# include <h/tty.h>
- X# endif
- X# include <sys/stat.h>
- X# include <stdio.h>
- X
- X/* INITTTY - Initialise the tty part of the info structure */
- Xinittty ()
- X{
- X register struct ttyline *lp ;
- X# ifdef BSD42
- X register struct direct *dp ;
- X DIR *dfd ;
- X# else
- X struct direct dir ;
- X FILE *dfd ;
- X# endif
- X struct stat statbuf ;
- X static char filedev[] = FILE_DEV ;
- X extern struct info Info ;
- X# ifdef BSD42
- X DIR *opendir() ;
- X struct direct *readdir() ;
- X# else
- X FILE *fopen() ;
- X# endif
- X
- X lp = Info.i_ttyline ;
- X# ifdef BSD42
- X if ( !(dfd = opendir( filedev )) )
- X# else
- X if ( !(dfd = fopen( filedev, "r" )) )
- X# endif
- X prexit( "Can't open %s\n", filedev ) ;
- X if ( chdir( filedev ) < 0 )
- X prexit( "sps - Can't chdir to %s\n", filedev ) ;
- X# ifdef BSD42
- X /* Read all entries in the device directory, looking for ttys */
- X while ( dp = readdir( dfd ) )
- X { /* Skip entries that do not match "tty" or "console" */
- X if ( strncmp( "tty", dp->d_name, 3 )
- X && strcmp( "console", dp->d_name ) )
- X continue ;
- X /* Skip "tty" itself */
- X if ( dp->d_namlen == 3 )
- X continue ;
- X# ifdef CHAOS
- X /* Skip chaos ttys ; they are accessed during ttystatus() */
- X if ( dp->d_namelen > 3 &&
- X dp->d_name[ sizeof( "tty" ) - 1 ] == 'C' )
- X continue ;
- X# endif
- X if ( lp >= &Info.i_ttyline[ MAXTTYS ] )
- X prexit( "sps - Too many ttys in %s\n", filedev ) ;
- X /* Copy the tty name into the information entry */
- X if ( !strcmp( dp->d_name, "console" ) )
- X {
- X lp->l_name[0] = 'c' ;
- X lp->l_name[1] = 'o' ;
- X }
- X else
- X {
- X lp->l_name[0] = dp->d_name[3] ;
- X lp->l_name[1] = dp->d_name[4] ;
- X }
- X /* Ensure that this tty is actually a valid character device */
- X if ( stat( dp->d_name, &statbuf ) < 0 )
- X continue ;
- X# else
- X /* Read all entries in the device directory, looking for ttys */
- X while ( fread( (char*)&dir, sizeof( struct direct ), 1, dfd ) == 1 )
- X { /* Skip entries that do not match "tty" or "console" */
- X if ( strncmp( "tty", dir.d_name, 3 )
- X && strcmp( "console", dir.d_name ) )
- X continue ;
- X /* Skip "tty" itself */
- X if ( dir.d_name[3] == '\0' )
- X continue ;
- X# ifdef CHAOS
- X /* Skip chaos ttys ; they are accessed during ttystatus() */
- X if ( dir.d_name[ sizeof( "tty" ) - 1 ] == 'C' )
- X continue ;
- X# endif
- X if ( lp >= &Info.i_ttyline[ MAXTTYS ] )
- X prexit( "sps - Too many ttys in %s\n", filedev ) ;
- X /* Copy the tty name into the information entry */
- X if ( !strcmp( dir.d_name, "console" ) )
- X {
- X lp->l_name[0] = 'c' ;
- X lp->l_name[1] = 'o' ;
- X }
- X else
- X {
- X lp->l_name[0] = dir.d_name[3] ;
- X lp->l_name[1] = dir.d_name[4] ;
- X }
- X /* Ensure that this tty is actually a valid character device */
- X if ( stat( dir.d_name, &statbuf ) < 0 )
- X continue ;
- X# endif
- X if ( (statbuf.st_mode & S_IFMT) != S_IFCHR )
- X continue ;
- X /* Find the device # of the tty and the address of its
- X associated struct tty in /dev/kmem. */
- X lp->l_dev = statbuf.st_rdev ;
- X if ( getkmem ( (long)&Info.i_cdevsw[ major( statbuf.st_rdev ) ]
- X# ifdef SUNOS40
- X .d_str,
- X# else
- X .d_ttys,
- X# endif
- X (char*)&lp->l_addr, sizeof( lp->l_addr ) )
- X != sizeof( lp->l_addr ) )
- X {
- X fprintf( stderr, "sps - Can't read struct tty for %s\n",
- X# ifdef BSD42
- X dp->d_name ) ;
- X# else
- X dir.d_name ) ;
- X# endif
- X continue ;
- X }
- X# ifndef SUNOS40
- X lp->l_addr += (int)minor( statbuf.st_rdev ) ;
- X# endif
- X lp++ ;
- X }
- X# ifdef BSD42
- X (void)closedir( dfd ) ;
- X# else
- X (void)fclose( dfd ) ;
- X# endif
- X}
- ---END-OF-inittty.c---
- LEN=`wc -c < inittty.c`
- if [ $LEN != 3716 ] ; then
- echo shar: File "inittty.c" was $LEN, should have been 3716 bytes
- fi
- if [ -f 'main.c' -a "${1}" != "-c" ] ; then
- echo shar: Won\'t overwrite existing file "main.c"
- exit 2
- fi
- echo x - main.c
- sed -e 's/^X//' > main.c << '---END-OF-main.c---'
- X# ifndef lint
- Xstatic char SccsId[] = "@(#)main.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# include <fcntl.h>
- X# endif KVM
- X# ifndef SUNOS40
- X# include <h/text.h>
- X# endif
- X# include <sys/stat.h>
- X# include <stdio.h>
- X
- X
- X/* SPS - Show Process Status */
- X
- X/* J. R. Ward - Hasler AG, Bern, Switzerland - 24 May 1985 */
- X/* - 26 Nov 1986 */
- X/* J. R. Ward - Olsen & Associates, Zuerich, Switzerland - 1 Oct 1988 */
- X/* <robert@olsen.uucp> */
- X
- X/* NFS additions and SunOS4.0 support by Alexander Dupuy
- X <dupuy@ncs.columbia.edu> and Charlie Kim <cck@cunixc.cc.columbia.edu>.
- X Ultrix 2.x support by Rob Lehman at CUCCA. */
- X
- Xmain ( argc,argv )
- X
- Xint argc ;
- Xchar **argv ;
- X
- X{
- X register struct process *plist ;
- X register struct process *process ;
- X# ifndef SUNOS40
- X register struct text *text ;
- X# endif
- X int flinfo ;
- X char *fileinfo, *filesymbol ;
- X struct stat sinfo, ssymbol ;
- X# ifdef WARNPASSWD
- X struct stat spasswd ;
- X# endif
- X extern struct flags Flg ;
- X extern struct info Info ;
- X# ifdef KVM
- X extern kvm_t *Flkvm ;
- X# else
- X extern int Flmem ;
- X extern int Flkmem ;
- X extern int Flswap ;
- X# endif
- 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# ifdef KVM
- X Flkvm = kvm_open( Flg.flg_s, Flg.flg_k, NULL, O_RDONLY, "sps" ) ;
- X# else
- 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# endif
- 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# ifdef WARNPASSWD
- 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# endif
- 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# ifndef SUNOS40
- X text = (struct text*)getcore( Info.i_ntext * sizeof( struct text ) ) ;
- X# endif
- X do
- X { /* Read current process status */
- X# ifdef SUNOS40
- X readstatus( process ) ;
- X /* Select those processes to be listed */
- X plist = needed( process ) ;
- X# else
- X readstatus( process, text ) ;
- X /* Select those processes to be listed */
- X plist = needed( process, text ) ;
- X# endif
- 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---
- LEN=`wc -c < main.c`
- if [ $LEN != 4246 ] ; then
- echo shar: File "main.c" was $LEN, should have been 4246 bytes
- fi
- if [ -f 'mktree.c' -a "${1}" != "-c" ] ; then
- echo shar: Won\'t overwrite existing file "mktree.c"
- exit 2
- fi
- echo x - mktree.c
- sed -e 's/^X//' > mktree.c << '---END-OF-mktree.c---'
- 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-mktree.c---
- LEN=`wc -c < mktree.c`
- if [ $LEN != 1703 ] ; then
- echo shar: File "mktree.c" was $LEN, should have been 1703 bytes
- fi
- if [ -f 'needed.c' -a "${1}" != "-c" ] ; then
- echo shar: Won\'t overwrite existing file "needed.c"
- exit 2
- fi
- echo x - needed.c
- sed -e 's/^X//' > needed.c << '---END-OF-needed.c---'
- X# ifndef lint
- Xstatic char SccsId[] = "@(#)needed.c 1.3\t7/4/90" ;
- X# endif
- X
- X# include "sps.h"
- X# include "flags.h"
- X# ifndef SUNOS40
- X# include <h/text.h>
- X# endif
- X# include <stdio.h>
- X
- X/*
- X** NEEDED - Determine which processes are needed for the printout
- X** and add these to a list of needed processes.
- X*/
- X# ifdef SUNOS40
- Xstruct process *needed ( process )
- X
- Xregister struct process *process ;
- X
- X# else
- X
- Xstruct process *needed ( process, text )
- X
- Xregister struct process *process ;
- Xstruct text *text ;
- X
- X# endif
- X{
- X register struct process *p ;
- X register struct process *plist ;
- X struct process *lastp ;
- X int uid ;
- X extern struct flags Flg ;
- X extern union userstate User ;
- X extern struct info Info ;
- X extern struct ttyline Notty ;
- X struct ttyline *findtty() ;
- X char *getcmd() ;
- X
- X plist = (struct process*)0 ;
- X lastp = &process[ Info.i_nproc ] ;
- X /* Normalise internal pointers from kernel addresses. For each kmem
- X address in the `proc' and `text' structures, we convert that
- X address for our own internal use. */
- X for ( p = process ; p < lastp ; p++ )
- X {
- X if ( !p->pr_p.p_stat )
- X continue ;
- X# ifndef SUNOS40
- X /* Normalise internal text pointers */
- X if ( p->pr_p.p_textp )
- X p->pr_p.p_textp = &text[p->pr_p.p_textp - Info.i_text0];
- X# endif
- X /* Normalise internal linked list of processes */
- X p->pr_plink = p->pr_p.p_link ?
- X &process[ p->pr_p.p_link - Info.i_proc0 ] :
- X (struct process*)0 ;
- X /* Normalise internal parent pointers */
- X p->pr_pptr = p->pr_p.p_pptr ?
- X &process[ p->pr_p.p_pptr - Info.i_proc0 ] :
- X (struct process*)0 ;
- X /* Check for valid parent pointers */
- X if ( !p->pr_pptr )
- X {
- X p->pr_pptr = process ;
- X continue ;
- X }
- X if ( p->pr_pptr < process || p->pr_pptr >= lastp )
- X {
- X fprintf( stderr, "sps - process %d has bad pptr\n",
- X p->pr_p.p_pid ) ;
- X p->pr_pptr = process ;
- X }
- X }
- X /* For each process, see if it is a candidate for selection.
- X If so, retrieve its command arguments and upage information. */
- X uid = getuid() ;
- X for ( p = process ; p < lastp ; p++ )
- X {
- X if ( !p->pr_p.p_stat )
- X continue ;
- X /* Count processes and sizes */
- X summarise( p ) ;
- X /* Select the given processes. Bear in mind that selection
- X of processes based on the `F' and `T' flags must be
- X postponed until the upage is accessed. */
- X if ( !Flg.flg_F && !Flg.flg_T && !selectproc( p, process, uid ))
- X continue ;
- X /* Try to find the process' command arguments. Accessing the
- X arguments also involves retrieving the upage. */
- X p->pr_cmd = getcmd( p ) ;
- X /* If the upage was found successfully, use this information */
- X if ( p->pr_upag )
- X {
- X# ifdef BSD42
- X p->pr_rself = User.u_us.u_ru ;
- X p->pr_rchild = User.u_us.u_cru ;
- X# else
- X p->pr_vself = User.u_us.u_vm ;
- X p->pr_vchild = User.u_us.u_cvm ;
- X# endif
- X p->pr_tty = findtty( p ) ;
- X p->pr_files = filecount( p ) ;
- X }
- X else
- X p->pr_tty = &Notty ;
- X /* Select on the basis of the `F' and `T' flags */
- X if ( Flg.flg_F
- X && !(p->pr_p.p_pgrp && p->pr_p.p_pgrp == p->pr_tty->l_pgrp) )
- X continue ;
- X if ( Flg.flg_T && !selecttty( p ) )
- X continue ;
- X /* Arrive here with a selected process. Add this to the
- X linked list of needed processes. */
- X p->pr_plink = plist ;
- X plist = p ;
- X p->pr_child = (struct process*)0 ;
- X p->pr_sibling = (struct process*)0 ;
- X }
- X return ( plist ) ;
- X}
- X
- X/* SUMMARISE - Summarises the given process into the `Summary' structure */
- X/*
- X** SHOULD ACCOUNT HERE FOR THE SIZE OF LOADED PAGE TABLES, BUT WE DON'T REALLY
- X** KNOW THEIR RESIDENT SIZES.
- X*/
- Xsummarise ( p )
- X
- Xregister struct process *p ;
- X
- X{
- X# ifndef SUNOS40
- X register struct text *tp ;
- X# endif
- X int busy ;
- X extern struct summary Summary ;
- X
- X Summary.sm_ntotal++ ;
- X if ( p->pr_p.p_stat == SZOMB )
- X return ;
- X /* Firstly, account for processes */
- X# if defined(OLDSTATS) || !defined(SUNOS40)
- X Summary.sm_ktotal += p->pr_p.p_dsize + p->pr_p.p_ssize ;
- X# else
- X seg_count( p ) ; /* count up process pages */
- X
- X Summary.sm_ktotal += p->pr_private + p->pr_shared ;
- X# endif
- X Summary.sm_kloaded += p->pr_p.p_rssize ;
- X Summary.sm_kswapped += p->pr_p.p_swrss ;
- X if ( p->pr_p.p_flag & SLOAD )
- X Summary.sm_nloaded++ ;
- X else
- X Summary.sm_nswapped++ ;
- X busy = (p->pr_p.p_stat == SRUN) || (p->pr_p.p_stat==SSLEEP
- X && (p->pr_p.p_pri<PZERO && p->pr_p.p_pid > MSPID) ) ;
- X# ifdef SUNOS40
- X /* Ignore the idle processes */
- X if ( p->pr_p.p_pid == 3 || p->pr_p.p_pid == 4 )
- X busy = 0 ;
- X# endif SUNOS40
- X if ( busy )
- X {
- X Summary.sm_nbusy++ ;
- X# if defined(OLDSTATS) || !defined(SUNOS40)
- X Summary.sm_kbusy += p->pr_p.p_dsize + p->pr_p.p_ssize ;
- X# else
- X Summary.sm_kbusy += p->pr_private + p->pr_shared ;
- X# endif
- X }
- X# ifndef SUNOS40
- X /* Now account for their texts */
- X if ( !(tp = p->pr_p.p_textp) || !tp->x_count )
- X return ;
- X Summary.sm_ktotal += tp->x_size ;
- X Summary.sm_kloaded += tp->x_rssize ;
- X Summary.sm_kswapped += tp->x_swrss ;
- X if ( busy )
- X Summary.sm_kbusy += tp->x_size ;
- X tp->x_count = 0 ;
- X# endif
- X}
- ---END-OF-needed.c---
- LEN=`wc -c < needed.c`
- if [ $LEN != 5151 ] ; then
- echo shar: File "needed.c" was $LEN, should have been 5151 bytes
- fi
- if [ -f 'openfiles.c' -a "${1}" != "-c" ] ; then
- echo shar: Won\'t overwrite existing file "openfiles.c"
- exit 2
- fi
- echo x - openfiles.c
- sed -e 's/^X//' > openfiles.c << '---END-OF-openfiles.c---'
- X# ifndef lint
- Xstatic char SccsId[] = "@(#)openfiles.c 1.1\t10/1/88" ;
- X# endif
- X
- X# include <stdio.h>
- X# include "sps.h"
- X# include "flags.h"
- X# include <varargs.h>
- X# ifdef KVM
- X# include <kvm.h>
- X# endif
- 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# ifdef KVM
- X
- Xgetkmem ( addr, buf, bufsize )
- X
- Xlong addr ;
- Xchar *buf ;
- Xint bufsize ;
- X{
- X extern kvm_t *Flkvm ;
- X
- X return( kvm_read( Flkvm, (long)addr, buf, bufsize ) ) ;
- X}
- X
- X# else
- X
- Xgetkmem ( addr, buf, bufsize )
- X
- Xlong addr ;
- Xchar *buf ;
- Xint bufsize ;
- X{
- X extern int Flkmem ;
- X
- X memseek( Flkmem, (long)addr ) ;
- X return( read( Flkmem, buf, bufsize ) ) ;
- 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# ifdef SUN
- X pos &= KERNELBASE - 1 ;
- X# else
- X pos &= 0x7fffffff ;
- X# endif
- 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# endif
- 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/* VARARGS */
- X/* ARGSUSED */
- Xprexit ( va_alist )
- X
- Xva_dcl
- X
- X{
- X char *fmt ;
- X va_list args ;
- X
- X va_start( args ) ;
- X fmt = va_arg( args, char * ) ;
- X
- X vfprintf( stderr, fmt, args ) ;
- X exit( 1 ) ;
- X}
- X
- X# ifndef VPRINTF
- X
- Xint vfprintf ( filep, fmt, args )
- X
- XFILE *filep ;
- Xchar *fmt ;
- Xva_list args ;
- X
- X{
- X _doprnt( fmt, args, filep ) ;
- X return( ferror( filep ) ? EOF : 0 ) ;
- X}
- X
- X# endif
- ---END-OF-openfiles.c---
- LEN=`wc -c < openfiles.c`
- if [ $LEN != 3718 ] ; then
- echo shar: File "openfiles.c" was $LEN, should have been 3718 bytes
- fi
- exit 0
-