robert@hslrswi.UUCP (Robert Ward) (07/11/85)
Send comments, suggestions, bug fixes, bug reports to - Robert Ward, Hasler AG, Abt. 34, Belpstrasse 23, CH-3000 Bern 14, Switzerland. (... mcvax!cernvax!hslrswi!robert) ******************************************************************************* This is a sh(1) archive. In order to extract the contents of this shar, use an editor to place the contents of this file from the dotted line onwards into a second, temporary file. Then run sh on that second file. --------------------------------- C U T --- H E R E --------------------------- #! /bin/sh echo Extracting filecount.c cat > filecount.c << '---END-OF-filecount.c---' # include "sps.h" /* FILECOUNT - Counts the # open files for the current process */ filecount () { register int i ; register struct file **f ; register int count ; extern union userstate User ; count = 0 ; for ( i = 0, f = User.u_us.u_ofile ; i < NOFILE ; i++ ) if ( *f++ ) count++ ; return ( count ) ; } ---END-OF-filecount.c--- echo Extracting findtty.c cat > findtty.c << '---END-OF-findtty.c---' # include "sps.h" # include <h/tty.h> /* FINDTTY - Attempts to determine to which tty a process is connected */ struct ttyline *findtty ( p ) register struct process *p ; { register struct ttyline *lp ; extern struct info Info ; extern struct ttyline Notty ; extern union userstate User ; if ( !p->pr_p.p_pgrp ) return ( &Notty ) ; for ( lp = Info.i_ttyline ; lp->l_name[0] ; lp++ ) if ( lp->l_dev == User.u_us.u_ttyd ) return ( lp ) ; return ( &Notty ) ; } ---END-OF-findtty.c--- echo Extracting flagdecode.c cat > flagdecode.c << '---END-OF-flagdecode.c---' # include "sps.h" # include "flags.h" /* FLAGDECODE - Looks at the argument list and sets various internal switches */ flagdecode ( argc, argv ) register int argc ; register char **argv ; { register char *chp ; union flaglist *plist ; union flaglist *tlist ; union flaglist *ulist ; static char usage[] = "sps - Unknown option %s\nUsage - sps [ -defgijkoqrsvwyABFNPSTUWZ ][ process|tty|user ] ...\n"; union flaglist *getflgsp() ; extern struct flags Flg ; plist = tlist = ulist = (union flaglist*)0 ; for ( argv++ ; --argc ; argv++ ) { chp = *argv ; while ( *chp ) switch ( *chp++ ) { case '-' : /* Separation character */ continue ; case 'd' : case 'D' : /* List disc orientated information */ Flg.flg_d = 1 ; Flg.flg_v = 0 ; continue ; case 'e' : case 'E' : /* List environment strings */ Flg.flg_e = 1 ; continue ; case 'f' : /* List the father's process id */ Flg.flg_f = 1 ; continue ; case 'g' : case 'G' : /* List the process group id */ Flg.flg_g = 1 ; continue ; case 'i' : case 'I' : /* Initialise (super-user only) */ Flg.flg_i = 1 ; continue ; case 'j' : case 'J' : /* The next argument specifies the name of the information file */ if ( argc <= 1 ) prexit( "sps - Name of an information file expected after `-j' flag\n" ) ; argc-- ; Flg.flg_j = *++argv ; continue ; case 'k' : case 'K' : /* Use a disc file such as /vmcore rather than /dev/{k}mem for accessing kernel data. The next argument specifies the file name. */ if ( argc <= 1 ) prexit( "sps - Name of a memory dump file expected after `-k' flag\n" ) ; argc-- ; Flg.flg_k = *++argv ; Flg.flg_o = 1 ; continue ; case 'l' : case 'v' : case 'L' : case 'V' : /* Verbose output */ Flg.flg_d = 0 ; Flg.flg_v = 1 ; continue ; case 'o' : case 'O' : /* Avoid looking at the swap device */ Flg.flg_o = 1 ; continue ; case 'q' : case 'Q' : /* Show only the user time, not the user + system times together. */ Flg.flg_q = 1 ; continue ; case 'r' : case 'R' : /* Repeat output every n seconds. The next argument specifies n which defaults to 5 if omitted. */ Flg.flg_r = 1 ; if ( argc > 1 ) { if ( **++argv >= '0' && **argv <= '9' ) { argc-- ; Flg.flg_rdelay = atoi( *argv ) ; continue ; } argv-- ; } Flg.flg_rdelay = 0 ; continue ; case 's' : /* Next argument specifies a symbol file rather than the default /vmunix. */ if ( argc <= 1 ) prexit( "sps - Name of a symbol file expected after `-s' flag\n" ) ; argc-- ; Flg.flg_s = *++argv ; continue ; case 'w' : /* Wide output, exceeding 79 columns */ Flg.flg_w = 1 ; continue ; case 'y' : case 'Y' : /* List current tty information */ Flg.flg_y = 1 ; continue ; case 'a' : case 'A' : /* List all processes */ Flg.flg_AZ = 1 ; Flg.flg_A = 1 ; continue ; case 'b' : case 'B' : /* List only busy processes */ Flg.flg_AZ = 1 ; Flg.flg_B = 1 ; continue ; case 'F' : /* List only foreground processes */ Flg.flg_AZ = 1 ; Flg.flg_F = 1 ; continue ; case 'n' : case 'N' : /* No processes, just the summary line*/ Flg.flg_AZ = 1 ; Flg.flg_N = 1 ; continue ; case 'p' : case 'P' : /* List only the given process ids */ Flg.flg_AZ = 1 ; Flg.flg_P = 1 ; if ( !plist ) plist=Flg.flg_Plist=getflgsp( argc ); while ( argc > 1 ) { if ( **++argv == '-' ) { --argv ; break ; } --argc ; plist->f_chp = *argv ; (++plist)->f_chp = (char*)0 ; } continue ; case 'S' : /* List only stopped processes */ Flg.flg_AZ = 1 ; Flg.flg_S = 1 ; continue ; case 't' : case 'T' : /* List only processes attached to the specified terminals */ Flg.flg_AZ = 1 ; Flg.flg_T = 1 ; if ( !tlist ) tlist=Flg.flg_Tlist=getflgsp( argc ); while ( argc > 1 ) { if ( **++argv == '-' ) { --argv ; break ; } --argc ; tlist->f_chp = *argv ; (++tlist)->f_chp = (char*)0 ; } continue ; case 'u' : case 'U' : /* List only processes belonging to the specified users */ Flg.flg_AZ = 1 ; Flg.flg_U = 1 ; if ( !ulist ) ulist=Flg.flg_Ulist=getflgsp( argc ); while ( argc > 1 ) { if ( **++argv == '-' ) { --argv ; break ; } --argc ; ulist->f_chp = *argv ; (++ulist)->f_chp = (char*)0 ; } continue ; case 'W' : /* List only waiting processes */ Flg.flg_AZ = 1 ; Flg.flg_W = 1 ; continue ; case 'z' : case 'Z' : /* List only zombie processes */ Flg.flg_AZ = 1 ; Flg.flg_Z = 1 ; continue ; default : prexit( usage, *argv ) ; /* NOTREACHED */ } } } ---END-OF-flagdecode.c--- echo Extracting flags.h cat > flags.h << '---END-OF-flags.h---' /* Structure holding information specified in the option list ... */ union flaglist { char *f_chp ; /* Option specified as string */ int f_uid ; /* Numerical user id */ int f_pid ; /* Numerical process id */ struct ttyline *f_ttyline ; /* Specified tty */ } ; /* Structure holding global information specifed by arg list options ... */ struct flags { int flg_d:1 ; /* disc orientated output */ int flg_e:1 ; /* print environment string */ int flg_f:1 ; /* print process father # */ int flg_g:1 ; /* print process group # */ int flg_i:1 ; /* initialise sps */ char *flg_j ; /* Use this as the info file */ char *flg_k ; /* Use this as the {k}mem file*/ int flg_o:1 ; /* avoid the swap device */ int flg_q:1 ; /* show user time only */ int flg_r:1 ; /* repeat output */ unsigned flg_rdelay ; /* ... with this much delay */ char *flg_s ; /* Use this as the symbol file*/ int flg_v:1 ; /* print verbose listing */ int flg_w:1 ; /* print wide output */ int flg_y:1 ; /* print tty information */ int flg_A:1 ; /* print all processes */ int flg_B:1 ; /* print busy processes */ int flg_F:1 ; /* print foreground processes */ int flg_N:1 ; /* print no processes */ int flg_P:1 ; /* print specified process #'s*/ int flg_S:1 ; /* print stopped processes */ int flg_T:1 ; /* print procs for given ttys */ int flg_U:1 ; /* print procs for given users*/ int flg_W:1 ; /* print waiting processes */ int flg_Z:1 ; /* print zombie processes */ int flg_AZ:1 ; /* One of A to Z was specified*/ union flaglist *flg_Plist ; /* List of specified processes*/ union flaglist *flg_Tlist ; /* List of specified ttys */ union flaglist *flg_Ulist ; /* List of specified users */ } ; ---END-OF-flags.h--- echo Extracting flagsetup.c cat > flagsetup.c << '---END-OF-flagsetup.c---' # include "sps.h" # include "flags.h" # include <h/tty.h> /* ** FLAGSETUP - Replaces any users or processes specified by flagdecode() ** with numerical equivalents. The lists are terminated by negative values. ** or null pointers. Ttystatus() must have been previously called to ** initialise the Info structure with chaos tty values. */ flagsetup () { register union flaglist *fp ; register char *chp ; register int i ; register struct ttyline *lp ; int found ; extern struct flags Flg ; extern struct info Info ; /* Look for specified users */ if ( Flg.flg_U ) { if ( !Flg.flg_Ulist->f_chp ) prexit( "sps - User name was expected after -u flag\n"); for ( fp = Flg.flg_Ulist ; chp = fp->f_chp ; fp++ ) { found = 0 ; for ( i = 0 ; i < MAXUSERID ; i++ ) if ( !strncmp( chp, Info.i_hnames[i].h_uname, UNAMELEN ) ) { fp->f_uid = Info.i_hnames[i].h_uid ; found = 1 ; break ; } if ( !found ) prexit( "sps - Unknown user: %s\n", chp ) ; } fp->f_uid = -1 ; } /* Look for specified process ids */ if ( Flg.flg_P ) { if ( !Flg.flg_Plist->f_chp ) prexit( "sps - Process id was expected after -p flag\n" ) ; for ( fp = Flg.flg_Plist ; chp = fp->f_chp ; fp++ ) { if ( chp[0] < '0' || chp[0] > '9' ) prexit( "sps - Bad process id: %s\n", chp ) ; fp->f_pid = atoi( chp ) ; } fp->f_pid = -1 ; } /* Look for specified ttys */ if ( !Flg.flg_T ) return ; if ( !Flg.flg_Tlist->f_chp ) prexit( "sps - Tty name was expected after -t flag\n" ) ; for ( fp = Flg.flg_Tlist ; chp = fp->f_chp ; fp++ ) { /* Under VMUNIX, all ttys have two character names. Thus, a flag of the form `t 8' should be expanded to become `t 08'. */ if ( !chp[1] ) chp[1] = chp[0], chp[0] = '0' ; found = 0 ; for ( lp = Info.i_ttyline ; lp->l_name[0] ; lp++ ) if ( !strncmp( chp, lp->l_name, 2 ) ) { fp->f_ttyline = lp ; found = 1 ; break ; } if ( !found ) prexit( "sps - Unknown tty name: %.2s\n", chp ) ; } fp->f_ttyline = (struct ttyline*)0 ; } ---END-OF-flagsetup.c--- echo Extracting getcmd.c cat > getcmd.c << '---END-OF-getcmd.c---' # include "sps.h" # include "flags.h" # include <h/vm.h> # ifdef BSD42 # include <vax/pte.h> # else # include <h/pte.h> # endif /* ** GETCMD - Returns a character string read from a process' upage. ** This character string should represent the arguments to the current process. */ char *getcmd ( p ) register struct process *p ; { register int *ip ; register char *cp ; register char *cp0 ; unsigned nbad ; struct dblock db ; struct pte ptetbl[ UPAGES + CLSIZE ] ; union { char a_argc[ CLSIZE * NBPG ] ; int a_argi[ CLSIZE * NBPG / sizeof( int ) ] ; } argbuf ; extern struct flags Flg ; extern union userstate User ; extern int Flmem, Flswap ; char *strcat(), *strncpy(), *strsave() ; p->pr_csaved = 0 ; p->pr_upag = 0 ; if ( p->pr_p.p_stat == SZOMB ) return ( "** Exit **" ) ; if ( !(p->pr_p.p_flag & SLOAD) && Flg.flg_o ) return ( "** Swapped out **" ) ; /* Find the process' upage */ if ( !getupage( p, ptetbl ) ) return ( "** No upage **" ) ; /* Is this a system process ? */ if ( p->pr_p.p_flag & SSYS ) switch ( p->pr_p.p_pid ) { case 0 : p->pr_upag = 1 ; return ( "Unix Swapper" ) ; case 2 : p->pr_upag = 1 ; return ( "Unix Pager" ) ; default : break ; } /* Look at the top of the upage to locate the command arguments. The page is loaded if the process itself is loaded and the pte contains is marked as valid. */ if ( (p->pr_p.p_flag & SLOAD) && !ptetbl[0].pg_fod && ptetbl[0].pg_pfnum ) { /* If the page is loaded, read the arguments from physical memory. */ memseek( Flmem, (long)ctob( ptetbl[0].pg_pfnum ) ) ; if ( read( Flmem, argbuf.a_argc, CLSIZE*NBPG ) != CLSIZE*NBPG ) return ( "** Memory read error **" ) ; } else { /* Otherwise the page is on the swap device */ vstodb( 0, CLSIZE, &User.u_us.u_smap, &db, 1 ) ; # ifdef BSD42 swseek( (long)dtob( db.db_base ) ) ; # else swseek( (long)ctob( db.db_base ) ) ; # endif if ( Flg.flg_o ) return ( "** Swapped page **" ) ; if ( read( Flswap, argbuf.a_argc, CLSIZE*NBPG ) != CLSIZE*NBPG ) return ( "** Swap device read error **" ) ; } /* Look down until the end of command arguments is found. */ p->pr_upag = 1 ; p->pr_csaved = 1 ; ip = &argbuf.a_argi[ CLSIZE*NBPG / sizeof( int ) ] ; ip -= 2 ; while ( *--ip ) if ( ip == &argbuf.a_argi[0] ) { /* If the command arguments cannot be accessed from the user's memory space, get the command name from the system's idea of what the name should be. */ argbuf.a_argc[0] = '(' ; (void)strncpy( &argbuf.a_argc[1], User.u_us.u_comm, sizeof( User.u_us.u_comm ) ) ; (void)strcat( &argbuf.a_argc[0], ")" ) ; return ( strsave( argbuf.a_argc ) ) ; } /* Process the command arguments, looking for nulls and unprintable characters. */ cp0 = (char*)(ip + 1) ; if ( !*cp0 ) cp0++ ; nbad = 0 ; for ( cp = cp0 ; cp < &argbuf.a_argc[ CLSIZE*NBPG ] ; cp++ ) { *cp &= 0177 ; if ( !*cp ) { /* Replace nulls with spaces */ *cp = ' ' ; continue ; } if ( *cp < ' ' || *cp == 0177 ) { /* Replace control characters with ?'s */ if ( ++nbad > 5 ) { *cp++ = ' ' ; break ; } *cp = '?' ; continue ; } if ( !Flg.flg_e && *cp == '=' ) { /* Break on an `=' if we are not interested in the environment strings. */ *cp = '\0' ; while ( cp > cp0 && *--cp != ' ' ) *cp = '\0' ; break ; } } while ( *--cp == ' ' ) *cp = '\0' ; return ( strsave( cp0 ) ) ; } /* ** VSTODB - Given a base/size pair in virtual swap area, ** return a physical base/size pair which is the ** (largest) initial, physically contiguous block. /* This code is stolen from the kernel file /sys/sys/vm_drum.c. */ vstodb ( vsbase, vssize, dmp, dbp, rev ) register int vsbase ; register int vssize; struct dmap *dmp ; register struct dblock *dbp ; int rev ; { register int blk ; register swblk_t *ip ; # ifdef BSD42 extern struct info Info ; # endif # ifdef BSD42 blk = Info.i_dmmin ; # else blk = DMMIN ; # endif ip = dmp->dm_map ; while ( vsbase >= blk ) { vsbase -= blk ; # ifdef BSD42 if ( blk < Info.i_dmmax ) # else if ( blk < DMMAX ) # endif blk *= 2 ; ip++ ; } dbp->db_size = vssize < blk - vsbase ? vssize : blk - vsbase ; dbp->db_base = *ip + (rev ? blk - (vsbase + dbp->db_size) : vsbase); } ---END-OF-getcmd.c--- echo Extracting getupage.c cat > getupage.c << '---END-OF-getupage.c---' # include "sps.h" # include <h/vm.h> # ifdef BSD42 # include <vax/pte.h> # else # include <h/pte.h> # endif # include <stdio.h> /* ** GETUPAGE - Reads the upage for the specified process as well as sufficient ** page tables entries for reading the command arguments. The pte's are read ** into the argument `ptetbl'. The upage is read into the external variable ** `User'. This procedure returns 1 if the upage was successfully read. */ # define usrpt (Info.i_usrpt) getupage ( p, ptetbl ) register struct process *p ; register struct pte *ptetbl ; { register int i ; register int ncl ; struct pte pte ; extern struct info Info ; extern union userstate User ; extern int Flmem, Flkmem, Flswap ; /* If the process is not loaded, look for the upage on the swap device*/ if ( !(p->pr_p.p_flag & SLOAD) ) { # ifdef BSD42 swseek( (long)dtob( p->pr_p.p_swaddr ) ) ; # else swseek( (long)ctob( p->pr_p.p_swaddr ) ) ; # endif if ( read( Flswap, (char*)&User.u_us, sizeof( struct user ) ) != sizeof( struct user ) ) { fprintf( stderr, "sps - Can't read upage of process %d\n", p->pr_p.p_pid ) ; return ( 0 ) ; } return ( 1 ) ; } /* The process is loaded. Locate the process pte's by reading the pte of their base address from system virtual address space. */ memseek( Flkmem, (long)&Info.i_usrptmap[ btokmx(p->pr_p.p_p0br) + p->pr_p.p_szpt-1 ] ) ; if ( read( Flkmem, (char*)&pte, sizeof( struct pte ) ) != sizeof( struct pte ) ) { fprintf( stderr, "sps - Can't read indir pte for upage of process %d\n", p->pr_p.p_pid ) ; return ( 0 ) ; } /* Now read the process' pte's from physical memory. We need to access sufficient pte's for the upage and for the command arguments. */ memseek( Flmem, (long)ctob( pte.pg_pfnum+1 ) - (UPAGES+CLSIZE)*sizeof( struct pte ) ) ; if ( read( Flmem, (char*)ptetbl, (UPAGES+CLSIZE)*sizeof( struct pte ) ) != (UPAGES+CLSIZE)*sizeof( struct pte ) ) { fprintf( stderr, "sps - Can't read page table of process %d\n", p->pr_p.p_pid ) ; return ( 0 ) ; } /* Now we can read the pages belonging to the upage. Here we read in an entire click at one go. */ ncl = (sizeof( struct user ) + NBPG*CLSIZE - 1) / (NBPG*CLSIZE) ; while ( --ncl >= 0 ) { i = ncl * CLSIZE ; memseek( Flmem, (long)ctob( ptetbl[ CLSIZE+i ].pg_pfnum ) ) ; if ( read( Flmem, User.u_pg[i], CLSIZE*NBPG ) != CLSIZE*NBPG ) { fprintf( stderr, "sps - Can't read page 0x%x of process %d\n", ptetbl[ CLSIZE+i ].pg_pfnum, p->pr_p.p_pid ) ; return ( 0 ) ; } } return ( 1 ) ; } ---END-OF-getupage.c--- echo Extracting globals1.c cat > globals1.c << '---END-OF-globals1.c---' # include "sps.h" # include "flags.h" /* Read/Write Variables global to the code of sps */ struct info Info ; /* Information structure */ struct flags Flg ; /* Flag options */ struct summary Summary ; /* Summary of processes */ union userstate User ; /* Upage of one process */ int Flmem, Flkmem, Flswap ; /* File descriptors */ unsigned Termwidth ; /* Width of output device */ short Lastpgrp ; /* Last process pgrp printed */ short Lastuid ; /* Last process uid printed */ ---END-OF-globals1.c--- echo Extracting globals2.c cat > globals2.c << '---END-OF-globals2.c---' # include "sps.h" /* Read Only variables, global to the code of sps ... */ /* Null ttyline device ... */ struct ttyline Notty = { 0, 0, " ", 0 } ; /* ** The symbol table. For each address read from the kernel during ** initialisation, this table shows the following: ** i. the name of that symbol within the kernel ; ** ii. whether an extra indirection is needed through the kernel, ** i.e. whether the value of that symbol should be obtained ** rather than its address. ** iii. where the obtained value/address is placed in the Info structure ; ** iv. whether the obtained value is associated with a reason for ** a process wait state. */ /* The order of entries in this table is unimportant. */ extern struct info Info ; struct symbol Symbollist[] = { /* Kernel addresses required in order to access process, tty and upage information. All these addresses should be located in the symbol file during initialisation. */ { "_proc", 1, (caddr_t*)&Info.i_proc0, (char*)0 }, { "_nproc", 1, (caddr_t*)&Info.i_nproc, (char*)0 }, { "_text", 1, (caddr_t*)&Info.i_text0, (char*)0 }, { "_ntext", 1, (caddr_t*)&Info.i_ntext, (char*)0 }, { "_inode", 1, (caddr_t*)&Info.i_inode0, (char*)0 }, { "_ninode", 1, (caddr_t*)&Info.i_ninode, (char*)0 }, { "_swbuf", 1, (caddr_t*)&Info.i_swbuf0, (char*)0 }, { "_nswbuf", 1, (caddr_t*)&Info.i_nswbuf, (char*)0 }, { "_buf", 1, (caddr_t*)&Info.i_buf0, (char*)0 }, { "_nbuf", 1, (caddr_t*)&Info.i_nbuf, (char*)0 }, { "_ecmx", 1, (caddr_t*)&Info.i_ecmx, (char*)0 }, { "_Usrptmap", 0, (caddr_t*)&Info.i_usrptmap, (char*)0 }, { "_usrpt", 0, (caddr_t*)&Info.i_usrpt, (char*)0 }, { "_cdevsw", 0, (caddr_t*)&Info.i_cdevsw, (char*)0 }, # ifdef BSD42 { "_quota", 1, (caddr_t*)&Info.i_quota0, (char*)0 }, { "_nquota", 1, (caddr_t*)&Info.i_nquota, (char*)0 }, { "_dmmin", 1, (caddr_t*)&Info.i_dmmin, (char*)0 }, { "_dmmax", 1, (caddr_t*)&Info.i_dmmax, (char*)0 }, { "_mbutl", 0, (caddr_t*)&Info.i_mbutl, (char*)0 }, # else { "_hz", 1, (caddr_t*)&Info.i_hz, (char*)0 }, # endif # ifdef CHAOS { "_Chconntab", 0, &Info.i_Chconntab, (char*)0 }, # endif /* Kernel addresses associated with process wait states. It is not important if some of these addresses are unresolved at initialisation. */ { "_fltab", 0, &Info.i_waitstate[0], "floppy" }, { "_tu", 0, &Info.i_waitstate[1], "tu58" }, { "_bfreelist", 0, &Info.i_waitstate[2], "buffer" }, { "_lp_softc", 0, &Info.i_waitstate[3], "printr" }, { "_lbolt", 0, &Info.i_waitstate[4], "lbolt" }, { "_runin", 0, &Info.i_waitstate[5], "runin" }, { "_runout", 0, &Info.i_waitstate[6], "runout" }, { "_ipc", 0, &Info.i_waitstate[7], "ptrace" }, { "_u", 0, &Info.i_waitstate[8], "pause" }, { "_freemem", 0, &Info.i_waitstate[9], "freemm" }, { "_kernelmap", 0, &Info.i_waitstate[10], "kermap" }, { "_cwaiting", 0, &Info.i_waitstate[11], "cwait" }, { "_rhpbuf", 0, &Info.i_waitstate[12], "rhpbuf" }, { "_rhtbuf", 0, &Info.i_waitstate[13], "rhtbuf" }, { "_ridcbuf", 0, &Info.i_waitstate[14], "ridcbf" }, { "_rikbuf", 0, &Info.i_waitstate[15], "rikbuf" }, { "_rmtbuf", 0, &Info.i_waitstate[16], "rmtbuf" }, { "_rrkbuf", 0, &Info.i_waitstate[17], "rrkbuf" }, { "_rrlbuf", 0, &Info.i_waitstate[18], "rrlbuf" }, { "_rrxbuf", 0, &Info.i_waitstate[19], "rrxbuf" }, { "_rswbuf", 0, &Info.i_waitstate[20], "rswbuf" }, { "_rtmbuf", 0, &Info.i_waitstate[21], "rtmbuf" }, { "_rtsbuf", 0, &Info.i_waitstate[22], "rtsbuf" }, { "_rudbuf", 0, &Info.i_waitstate[23], "rudbuf" }, { "_rupbuf", 0, &Info.i_waitstate[24], "rupbuf" }, { "_rutbuf", 0, &Info.i_waitstate[25], "rutbuf" }, { "_rvabuf", 0, &Info.i_waitstate[26], "rvabuf" }, { "_rvpbuf", 0, &Info.i_waitstate[27], "rvpbuf" }, { "_chtbuf", 0, &Info.i_waitstate[28], "chtbuf" }, { "_cmtbuf", 0, &Info.i_waitstate[29], "cmtbuf" }, { "_ctmbuf", 0, &Info.i_waitstate[30], "ctmbuf" }, { "_ctsbuf", 0, &Info.i_waitstate[31], "ctsbuf" }, { "_cutbuf", 0, &Info.i_waitstate[32], "cutbuf" }, # ifdef BSD42 { "_selwait", 0, &Info.i_waitstate[33], "select" }, # endif # ifdef CHAOS { "_Chrfclist", 0, &Info.i_waitstate[34], "chrfc" }, # endif { (char*)0, 0, (caddr_t*)0, (char*)0 } } ; ---END-OF-globals2.c--- echo Extracting hashuid.c cat > hashuid.c << '---END-OF-hashuid.c---' # include "sps.h" /* The hashing functions themselves ... */ # define HASHFN1( a ) (((a)*91 + 17) % MAXUSERID) # define HASHFN2( a ) (((a) + 47) % MAXUSERID) /* ** HASHUID - Returns a pointer to a slot in the hash table that corresponds ** to the hash table entry for `uid'. It returns a null pointer if there is ** no such slot. */ struct hashtab *hashuid ( uid ) int uid ; { register struct hashtab *hp ; register int i ; register int j ; extern struct info Info ; j = HASHFN1( uid ) ; for ( i = 0 ; i < MAXUSERID ; i++ ) { hp = &Info.i_hnames[ j ] ; if ( !hp->h_uname[0] ) return ( (struct hashtab*)0 ) ; if ( hp->h_uid == uid ) return ( hp ) ; j = HASHFN2( j ) ; } return ( (struct hashtab*)0 ) ; } /* ** HASHNEXT - Returns a pointer to the next slot in the hash table that ** may be use for storing information for `uid'. It returns a null pointer ** if there are no more free slots available. */ struct hashtab *hashnext ( uid ) int uid ; { register struct hashtab *hp ; register int i ; register int j ; extern struct info Info ; j = HASHFN1( uid ) ; for ( i = 0 ; i < MAXUSERID ; i++ ) { hp = &Info.i_hnames[ j ] ; if ( !hp->h_uname[0] ) return ( hp ) ; j = HASHFN2( j ) ; } return ( (struct hashtab*)0 ) ; } ---END-OF-hashuid.c---