home *** CD-ROM | disk | FTP | other *** search
- /*
- * readpr.c -- read process table
- *
- * Copyright (C) 1986, 1990 Philip L. Budne
- *
- * This file is part of "Phil's Finger Program".
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 1, or (at your option)
- * any later version.
- *
- */
-
- # ifndef lint
- static char *rcsid = "$Id: readpr.c,v 3.0 90/07/06 13:11:38 budd Rel $";
- # endif /* lint not defined */
-
- # include "finger.h"
- # include "waitstate.h"
- # ifndef Umax
-
- # include <stdio.h>
- # include "ustruct.h"
-
- # ifdef USG
- # include <sys/var.h>
- # endif /* USG defined */
-
- # ifndef SIGHUP
- # include <signal.h>
- # endif /* SIGHUP not defined */
-
- # include "pr.h"
- # include "kmem.h"
- # include "info.h" /* after finger.h */
- # include "args.h" /* for debugsw */
-
- /* # define DEBUG_READPR /* dump all pr's */
-
- # ifndef UTMP_NO_HOST
- # define MUST_HAVE_TTY /* run a bit faster */
- # endif /* UTMP_NO_HOST not defined */
-
- extern struct info I; /* namelist values from names.c */
- extern struct user *ustruct(); /* from ustruct.c */
- extern void u_cleanup(); /* from ustruct.c */
-
- extern FTYPE kmem; /* fd for /dev/kmem */
- /* (more under SunOS 4.0) */
- # if SunOS < 400
- extern FTYPE mem; /* fd for /dev/mem */
- extern FTYPE swap; /* fd for /dev/drum */
- /* from kmem.c */
- # endif /* SunOS < 400 */
-
- FORWARD LOCAL enum sig istate();
-
- LOCAL int nproc; /* kernel nproc */
- LOCAL struct proc *aproc; /* kernel virt addr of process table */
-
- /*
- * readpr finds and reads in the array pr, containing the interesting
- * parts of the proc and user tables for each live process.
- */
-
- # ifdef AIX3
- # define MAXPROC 512
-
- GLOBAL struct pr *readpr() {
- int i, n;
- struct pr *prvec;
- struct procinfo pivec[MAXPROC];
- register struct pr *prp;
- register struct procinfo *pip;
-
- n = getproc( pivec, MAXPROC, sizeof( struct procinfo ) );
- if( n < 1 ) {
- /* Check errno, report of MAXPROC too small!!! */
- return( NULL );
- }
-
- prvec = (struct pr *) calloc( n+1, sizeof( struct pr ) );
- if( prvec == NULL )
- return( NULL );
-
- prp = prvec;
- for( i = 0, pip = pivec; i < n; i++, pip++ ) {
- struct userinfo ui;
-
- if( pip->pi_stat == 0 )
- continue;
-
- if( getuser( pip, sizeof( struct procinfo ),
- &ui, sizeof( struct userinfo ) ) < 0 )
- continue;
-
- prp->pr_uid = pip->pi_uid;
- prp->pr_pid = pip->pi_pid;
- prp->pr_ppid = pip->pi_ppid;
- prp->pr_pgrp = pip->pi_pgrp;
- prp->pr_stat = pip->pi_stat;
- prp->pr_flag = pip->pi_flag;
- prp->pr_wchan = pip->pi_wchan;
-
- prp->pr_ttyp = ui.ui_ttyp;
- prp->pr_ttyd = ui.ui_ttyd + ui.ui_ttympx;
-
- strzcpy(prp->pr_cmd, ui.ui_comm, sizeof( ui.ui_comm ) );
- # ifdef DEBUG_READPR
- dumppr( prp );
- # endif /* DEBUG_READPR defined */
- prp++;
- }
- prp->pr_stat = 0; /* mark end */
-
- # ifdef DEBUGSW
- if( sw_debug )
- printf("read %d processes\n", prp - prvec );
- # endif /* DEBUGSW defined */
-
- /* realloc prvec to size? */
- return( prvec );
- }
-
- # else /* AIX3 not defined */
-
- GLOBAL struct pr *readpr() {
- register struct pr *prp; /* current pr entry */
- register int i; /* loop index */
- struct user *upp; /* pointer to upage(s) */
- struct proc *mpp; /* ptr to current process */
- struct pr *prvec;
- struct proc *allproc; /* whole process table */
- # ifdef USG
- struct var v;
- # endif /* USG defined */
- # if SunOS >= 410
- struct sess sess;
- # endif /* SunOS >= 410 */
-
- if( !ini_kmem() ) /* initialize /dev/kmem etc. */
- return( NULL );
-
- # ifdef USG
- KMEMREAD(I.info_v, &v, sizeof( v ) ); /* var struct */
- nproc = v.v_proc; /* size of proc table */
- aproc = (struct proc *) I.info_proc; /* addr of proc table */
- # else /* USG not defined */
- KMEMREAD(I.info_nproc, &nproc, sizeof( nproc )); /* size of proc tbl */
- KMEMREAD(I.info_proc, &aproc, sizeof( aproc )); /* addr of proc tbl */
- # endif /* USG not defined */
-
- # ifdef DEBUG_READPR
- printf("nproc %d aproc %#x\n", nproc, aproc );
- # endif /* DEBUG_READPR defined */
-
- prvec = (struct pr *)calloc(nproc+1, sizeof(struct pr));/* allocate tbl */
- if( prvec == NULL )
- return( NULL );
-
- allproc = (struct proc *) calloc(nproc, sizeof( struct proc ) );
- KMEMREAD(aproc, allproc, nproc * sizeof( struct proc ) );
- mpp = allproc;
-
- prp = prvec; /* pointer to dest block */
- for( i = 0; i < nproc; i++, mpp++ ) { /* for all processes */
- if( mpp->p_stat == 0 || mpp->p_stat == SZOMB ) /* a zombie or worse? */
- continue; /* forget it */
-
- # ifdef SSYS
- if( mpp->p_flag & SSYS ) /* swapper or pager? */
- continue; /* flush */
- # endif /* SSYS defined */
-
- # ifdef SWEXIT
- if( mpp->p_flag & SWEXIT ) /* exiting? */
- continue; /* nevermind. */
- # endif /* SWEXIT defined */
-
- # if defined(MUST_HAVE_TTY) && defined(P_TTYP)
- /* avoid fetching ustruct needlessly */
- if( mpp->p_ttyp == NULL ) /* no terminal pointer? */
- continue;
- # endif /* defined(MUST_HAVE_TTY) && defined(P_TTYP) */
-
- # if SunOS >= 410
- if( mpp->p_sessp == NULL ||
- !KMEMREAD( (long)mpp->p_sessp, (char *)&sess, sizeof(sess) ) ) {
- # ifdef MUST_HAVE_TTY
- continue;
- # else /* MUST_HAVE_TTY not defined */
- sess.s_ttyp = NULL;
- # endif /* MUST_HAVE_TTY not defined */
- } /* no session or kmem read failed */
- # endif /* SunOS >= 410 */
-
- if( (upp = ustruct( mpp )) == NULL ) /* get ustruct? */
- continue; /* no point. */
-
- # ifdef DEBUGSW
- if( sw_debug && ((unsigned)upp->u_procp) != ((unsigned)(aproc + i)) )
- printf("%%Funny u struct for pid %d u_procp %#x != %#x\n",
- mpp->p_pid, upp->u_procp, (aproc + i) );
- # endif /* DEBUGSW defined */
-
- /*
- * WISH:
- * check for master /etc/inetd /etc/rlogind etc??? (as a way to
- * establish root of a process tree and avoid stray background
- * processes on that tty) and keep only descendants thereof.
- */
-
- # if 0 /* since we already have ustruct, just keep it! */
- # if defined(MUST_HAVE_TTY) && !defined(P_TTYP) && SunOS < 410
- if( upp->u_ttyp == NULL ) /* no terminal pointer? */
- continue;
- # endif /* defined(MUST_HAVE_TTY) && !defined(P_TTYP) && SunOS < 410 */
- # endif /* 0 */
-
- /* save the interesting parts */
- prp->pr_uid = mpp->p_uid; /* user id */
- prp->pr_pid = mpp->p_pid; /* pid */
- prp->pr_ppid = mpp->p_ppid; /* parent pid */
- prp->pr_pgrp = mpp->p_pgrp; /* process group leader pid */
- prp->pr_stat = mpp->p_stat; /* state (1..6) */
- prp->pr_flag = mpp->p_flag; /* flags (esp swap) */
- prp->pr_wchan = mpp->p_wchan; /* wait address */
-
- # if SunOS >= 410
- prp->pr_ttyp = sess.s_ttyp;
- prp->pr_ttyd = sess.s_ttyd;
- # else /* not SunOS >= 410 */
- # ifdef P_TTYP
- prp->pr_ttyp = mpp->p_ttyp; /* pointer to tty structure */
- # else /* P_TTYP not defined */
- prp->pr_ttyp = upp->u_ttyp; /* pointer to tty structure or tpg */
- # endif /* P_TTYP not defined */
- prp->pr_ttyd = upp->u_ttyd; /* device number */
- # endif /* not SunOS >= 410 */
- prp->pr_hup = istate( upp->u_signal[SIGHUP] );
- prp->pr_intr = istate( upp->u_signal[SIGINT] );
- prp->pr_quit = istate( upp->u_signal[SIGQUIT]);
- /* what you've all been waiting for... */
- strzcpy(prp->pr_cmd, upp->u_comm, sizeof( upp->u_comm ) );
-
- # ifdef DEBUG_READPR
- dumppr( prp );
- # endif /* DEBUG_READPR defined */
- prp++;
- } /* for i */
- prp->pr_stat = 0; /* mark end */
-
- /* WISH: realloc to shorten prvec? */
-
- free( allproc ); /* free copy of process table */
- u_cleanup(); /* cleanup ustruct reader */
-
- # ifdef DEBUGSW
- if( sw_debug )
- printf("read %d processes\n", prp - prvec );
- # endif /* DEBUGSW defined */
-
- return( prvec );
- } /* readpr */
-
- LOCAL enum sig istate( x ) /* return signal handler state */
- # ifdef VOIDSIG
- void (*x)();
- # else /* VOIDSIG not defined */
- int (*x)();
- # endif /* VOIDSIG not defined */
- {
- if( x == SIG_DFL )
- return( S_DEFAULT ); /* no handler */
- else if( x == SIG_IGN )
- return( S_IGNORE ); /* ignores interrupts */
- # ifdef SIG_HOLD
- else if( x == SIG_HOLD )
- return( S_HOLD ); /* interrupt held? */
- # endif /* SIG_HOLD defined */
- else
- return( S_CATCH ); /* has handler */
- } /* istate */
-
- # endif /* AIX3 not defined */
-
- GLOBAL waitstate_t waitstate( prp ) /* look at process wait states */
- struct pr *prp;
- {
- # ifndef SHORT_TTYP /* non-streams tty drivers... */
- register struct tty *t;
- # endif /* SHORT_TTYP not defined */
- register caddr_t w;
-
- w = prp->pr_wchan; /* get wait addr */
- if( w == (caddr_t) 0 ) /* no wait? */
- return( WS_RU ); /* runable */
-
- # ifndef SHORT_TTYP /* non-streams tty drivers... */
- t = prp->pr_ttyp; /* get tty pointer */
-
- if( w == (caddr_t) &t->t_rawq ) /* input wait */
- return( WS_TI );
- if( w == (caddr_t) &t->t_outq ) /* output wait */
- return( WS_TO );
- if( w >= (caddr_t) t && w < (caddr_t) (t+1) ) /* other terminal wait */
- return( WS_TW );
- # endif /* SHORT_TTYP not defined */
-
- # ifdef USG
- # ifdef STREAMS
- if( w == (caddr_t) I.info_pollwait ) /* poll(2) */
- return( WS_SE );
- # endif /* STREAMS defined */
- # else /* USG not defined */
- if( w == (caddr_t) I.info_selwait ) /* select(2) */
- return( WS_SE );
- # endif /* USG not defined */
- # if SunOS < 410
- if( w == (caddr_t) I.info_u ) /* pause(2) */
- return( WS_PA );
- # endif /* SunOS < 410 */
- if( w >= (caddr_t) aproc && w <= (caddr_t) (aproc+nproc) ) /* wait(2)*/
- return( WS_WA );
-
- return( WS_SL ); /* something else */
- } /* waitstate */
- # endif /* Umax not defined */
-
-
- /*
- * Local variables:
- * comment-column: 40
- * End:
- */
-