X386MON part 04/06

Warren Tucker wht at n4hgf.Mt-Park.GA.US
Sun Feb 17 06:35:17 AEST 1991


Submitted-by: wht at n4hgf
Archive-name: x386monx100/part04

#!/bin/sh
# This is part 04 of x386monx100
# ============= x386mon/ps.c ==============
if test ! -d 'x386mon'; then
    echo 'x - creating directory x386mon'
    mkdir 'x386mon'
fi
if test -f 'x386mon/ps.c' -a X"$1" != X"-c"; then
	echo 'x - skipping x386mon/ps.c (File already exists)'
else
echo 'x - extracting x386mon/ps.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'x386mon/ps.c' &&
X/*+-------------------------------------------------------------------------
X	ps.c - X386MON proc status detail
X	wht at n4hgf.Mt-Park.GA.US
X
X  Defined functions:
X	display_proc_stat(x,y,iproc,initial)
X	draw_Ps(x,y,ps_procs_to_disp,initial)
X	draw_Ps_work_proc(client_data)
X	find_utmp_for_pgrp(pgrp)
X	get_cpu_time_str(ticks)
X	get_user(tproc,tuser)
X	getpwent_and_enter(uid)
X	init_uid_name_hash()
X	initialize_Ps()
X	pgrp_to_ttyname(pgrp)
X	ppproc_pid_compare(ppp1,ppp2)
X	read_and_sort_procs(initial)
X	read_utmp()
X	strcmp(cptr,)
X	strindex(s1,s2)
X	uid_name_enter(uid,name)
X	uid_to_name(uid)
X
Xprocess size: There are ways that seem right to a man, but the
Xend of them is death.  u_tsize and friends are not clicks, but in
Xbytes.  I thought this would have been:
X(ctob((u_long)user.u_tsize + user.u_dsize + user.u_ssize)) /
X1024); At least this makes numbers agree with /bin/ps, although I
Xcannot figure out why there is one extra page charged by ps (user
Xis 2 pages).  This was evidentally wrong in SCO UNIX 3.2.0 and
Xfixed in 3.2.1.  If you get lots of processes who size is
X
XFor ISC: p->p_size
XReports exactly the same value as ps.  The values in the user
Xarea seem totally bogus (u_tsize is always 0, from observation)
Xso this size, the program swap size, seems the best measure.
XWithout USIZE_FIXED, on ISC2.02/Dell UNIX 1.1 I get zeroes.
XWith USIZE_FIXED I get values, but they're way out (e.g. vpix
Xand cron shown as the same size....).
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:01-12-1991-04:35-wht at n4hgf-x1.00 (flush old edit notes) */
X
X#include <sys/types.h>
X#include <nlist.h>
X#include <pwd.h>
X#include <utmp.h>
X#include <sys/param.h>
X#include <sys/tuneable.h>
X#include <sys/sysinfo.h>
X#include <sys/sysmacros.h>
X#include <sys/immu.h>
X#include <sys/region.h>
X#if defined(mips)
X#define pg_pres pg_sv /* alias: MIPS pg_sv==page valid */
X#include <sys/sbd.h>
X#include <sys/pcb.h>
X#endif
X#include <sys/proc.h>
X#include <sys/fs/s5dir.h>
X#include <sys/user.h>
X#include <sys/var.h>
X#if defined(M_UNIX) && (defined(i386) || defined(i486)) && SYSI86_RDUBLK_WANTED
X/* maybe someday, but not now: seems buggy */
X# include <sys/sysi86.h>
X#endif
X#include "x386mon.h"
X#include "buttons.h"
X#include "utoa.h"
X#include "nlsym.h"
X#include "libkmem.h"
X#include "libmem.h"
X#include "libswap.h"
X#include "libnlsym.h"
X
X#define min(a,b) (((a) > (b)) ? (b) : (a))
X
Xextern int errno;
Xextern int nprocs;
Xextern struct var v;
Xextern struct proc *procs;
Xextern struct proc *oldprocs;
Xextern struct proc **pprocs;
Xextern struct proc **poldprocs;
Xextern XtIntervalId update_timer_ID;
X
Xint mypid;
Xint noldprocs = 0;
Xint nprocs = 0;
Xstruct user user;
X
XXtWorkProcId ps_WorkProc_ID = (XtWorkProcId)0;
X
X#define MAX_UTMP 128
Xint nutmps = 0;
Xstruct utmp utmps[MAX_UTMP];
X
Xstatic int max_procs_to_display;
Xstatic int next_proc_to_display;
Xstatic int next_proc_x;
Xstatic int next_proc_y;
Xstatic int next_proc_initial;
X
Xstatic int line_style = LineSolid;
Xstatic int cap_style = CapButt;
Xstatic int join_style = JoinMiter;
X
X/*--> to keep from having to get the user structure twice,
X *--> we copy some stuff out of it into unimportant proc areas
X *--> using these kludge redefines to keep track
X *--> (also, under SCO p_size is updated from u_{t,d,s}size;
X *--> others seem to keep this value in p_size already)
X */
X#define p_GOT_USER	p_cursig		/* true if was able to otain user struct,
X									 * thus making the remainder of this valid
X									 */
X#define p_U_PSARGS	p_sigflags		/* u_psargs copy in int[MAXSIG] array */
X#define U_PSARGS_MAX (sizeof(int) * MAXSIG)
X#define p_U_STIME	p_stime			/* u_stime copy */
X#define p_U_UTIME	p_utime			/* u_utime copy */
X#define p_PIXEL		p_sigmask		/* we need to remember the color
X									 * of the last draw
X									 */
X
X/*+-------------------------------------------------------------------------
X	strindex(s1,s2)
Xif s2 occurs in s1, return a pointer to the match in s1, else null
X--------------------------------------------------------------------------*/
X#ifdef NEED_STRINDEX
Xchar *
Xstrindex(s1,s2)
Xregister char *s1;
Xregister char *s2;
X{
X	register int l1 = strlen (s1);
X	register int l2 = strlen (s2);
X
X	for(; l1 >= l2; l1--, s1++)
X	{
X		if(!strcmp(s1,s2,l2))
X			return(s1);
X	}
X	return ((char *)0);
X}	/* end of strindex  */
X#endif /* NEED_STRINDEX */
X
X/*+-------------------------------------------------------------------------
X	ppproc_pid_compare(ppp1,ppp2)
X--------------------------------------------------------------------------*/
Xppproc_pid_compare(ppp1,ppp2)
Xregister struct proc **ppp1;
Xregister struct proc **ppp2;
X{
X	return((*ppp1)->p_pid - (*ppp2)->p_pid);
X}	/* end of ppproc_pid_compare */
X
X/*+-------------------------------------------------------------------------
X	read_and_sort_procs(initial)
X--------------------------------------------------------------------------*/
Xvoid
Xread_and_sort_procs(initial)
Xint initial;
X{
Xint iproc;
Xregister char *cptr;
Xregister struct proc *tproc;
Xint omitted_one;
Xchar omitted[80];
X
X	omitted[0] = 0;
X	if(!initial)
X	{
X		cptr = (char *)oldprocs;
X		oldprocs = procs;
X		procs = (struct proc *)cptr;
X		noldprocs = nprocs;
X		cptr = (char *)poldprocs;
X		poldprocs = pprocs;
X		pprocs = (struct proc **)cptr;
X
X#ifdef OLD
X		(void)memcpy((char *)oldprocs,(char *)procs,
X			v.v_proc * sizeof(struct proc));
X		noldprocs = nprocs;
X		(void)memcpy((char *)poldprocs,(char *)pprocs,
X			noldprocs * sizeof(struct proc *));
X#endif
X	}
X
X/* read current procs */
X	grok_proc();
X
X/* if slot not in use, force to end when sorting */
X	nprocs = 0;
X	for(iproc = 0; iproc < v.v_proc; iproc++)
X	{
X		tproc = pprocs[iproc];
X		if(	(tproc->p_stat == 0) ||		/* if slot not in use, ... */
X			(tproc->p_pid == 1)  ||		/* ... or proc is init, ... */
X			(tproc->p_flag & SSYS))		/* ... or proc is system process */
X		{							/* eliminate from consideration */
X			tproc->p_pid = 32767;	/* force below selected procs in qsort */
X			continue;
X		}
X		nprocs++;
X	}
X
X/* if too many procs, whittle zombies */
X	if(nprocs > max_procs_to_display)
X	{
X		nprocs = 0;
X		omitted_one = 0;
X		for(iproc = 0; iproc < v.v_proc; iproc++)
X		{
X			tproc = pprocs[iproc];
X			if(tproc->p_pid == 32767)	/* previously eliminated? */
X				continue;
X			else if(tproc->p_stat == SZOMB)
X			{
X				tproc->p_pid = 32767;
X				omitted_one = 1;
X				continue;
X			}
X			nprocs++;
X		}
X		if(omitted_one)
X		{
X			if(omitted[0])
X				strcat(omitted,"/");
X			strcat(omitted,"zombie");
X		}
X	}
X
X/* if still too many procs, whittle shells and gettys */
X	if(nprocs > max_procs_to_display)
X	{
X		nprocs = 0;
X		omitted_one = 0;
X		for(iproc = 0; iproc < v.v_proc; iproc++)
X		{
X			tproc = pprocs[iproc];
X			if(tproc->p_pid == 32767)	/* previously eliminated? */
X				continue;
X			else if(tproc->p_GOT_USER = get_user(tproc,&user))
X			{
X				cptr = user.u_comm;
X				if( !strcmp(cptr,"ksh")		||
X					!strcmp(cptr,"csh")		||
X					!strcmp(cptr,"sh")		||
X					!strcmp(cptr,"getty")	||
X					!strcmp(cptr,"uugetty")	||
X					!strcmp(cptr,"cron")	||
X					!strcmp(cptr,"errdemon")||
X					!strcmp(cptr,"lpsched")	||
X					!strcmp(cptr,"logger")	||
X#if defined(HAVE_NETWORKING)
X					!strcmp(cptr,"biod")	||
X					!strcmp(cptr,"nfsd")	||
X					!strcmp(cptr,"rwhod")	||
X					!strcmp(cptr,"inetd")	||
X					!strcmp(cptr,"portmap")	||
X					!strcmp(cptr,"rlogin")	||
X					!strcmp(cptr,"fingerd")	||
X					!strcmp(cptr,"configd")	||
X#endif /* HAVE_NETWORKING */
X#if defined(mips)
X					!strcmp(cptr,"midas")	||
X					!strcmp(cptr,"mirerr")	||
X					!strcmp(cptr,"errhand")	||
X					!strcmp(cptr,"syslogd")	||
X					!strcmp(cptr,"sssmd")	||
X#endif /* mips */
X					!strcmp(cptr,"bash")
X				   )
X				{
X					tproc->p_pid = 32767;
X					omitted_one = 1;
X					continue;
X				}
X				/* save stuff out of user in unimportant proc areas */
X				tproc->p_U_UTIME = user.u_utime;
X				tproc->p_U_STIME = user.u_stime;
X				strncpy((char *)tproc->p_U_PSARGS,user.u_psargs,U_PSARGS_MAX);
X				*((char *)tproc->p_U_PSARGS + U_PSARGS_MAX - 1) = 0;
X#if defined(M_UNIX) 			/* SCO */
X#if defined(SCO_USIZE_BROKEN)	/* SCO UNIX 3.2.0 */
X				tproc->p_size = 
X					(((u_long)user.u_tsize + 511) / 1024) +
X					(((u_long)user.u_dsize + 511) / 1024) +
X					(((u_long)user.u_ssize + 511) / 1024) +
X					(((u_long)((user.u_tsize)?1:0) * NBPP) / 1024);
X#else							/* SCO UNIX 3.2.1 and presumably later */
X				tproc->p_size = 
X					(ctob((u_long)user.u_tsize + user.u_dsize + user.u_ssize))
X					/ 1024;
X#endif
X#endif /* SCO */
X			}
X			nprocs++;
X		}
X		if(omitted_one)
X		{
X			if(omitted[0])
X				strcat(omitted,"/");
X			strcat(omitted,"shell/getty/daemon");
X		}
X	}
X
X/* if still too many procs, whittle swapped */
X	if(nprocs > max_procs_to_display)
X	{
X		nprocs = 0;
X		omitted_one = 0;
X		for(iproc = 0; iproc < v.v_proc; iproc++)
X		{
X			tproc = pprocs[iproc];
X			if(tproc->p_pid == 32767)	/* previously eliminated? */
X				continue;
X			else if(!(tproc->p_flag & SLOAD) && (tproc->p_stat != SRUN))
X			{
X				tproc->p_pid = 32767;
X				omitted_one = 1;
X				continue;
X			}
X			nprocs++;
X		}
X		if(omitted_one)
X		{
X			if(omitted[0])
X				strcat(omitted,"/");
X			strcat(omitted,"swapped");
X		}
X	}
X#if !defined(mips)	/************* temp mod ***************/
X
X/* if still too many procs, whittle hard */
X	if(nprocs > max_procs_to_display)
X	{
X		nprocs = 0;
X		omitted_one = 0;
X		for(iproc = 0; iproc < v.v_proc; iproc++)
X		{
X			tproc = pprocs[iproc];
X			if(tproc->p_pid == 32767)	/* previously eliminated? */
X				continue;
X			else if(tproc->p_stat == SSLEEP)
X			{
X				tproc->p_pid = 32767;
X				omitted_one = 1;
X				continue;
X			}
X			nprocs++;
X		}
X		if(omitted_one)
X		{
X			if(omitted[0])
X				strcat(omitted,"/");
X			strcat(omitted,"sleeping");
X		}
X	}
X#endif
X
X/* if still too many procs, truncate */
X	if(nprocs > max_procs_to_display)
X	{
X		nprocs = max_procs_to_display;
X		disp_msg(colorCyan.pixel,"display size too small for all processes");
X		omitted[0] = 0;
X	}
X	if(omitted[0])
X	{
X		strcat(omitted," procs omitted");
X		disp_msg(colorCyan.pixel,omitted);
X	}
X	else
X		disp_msg(background,"");
X
X/* sort new procs array */
X	(void)qsort((char *)pprocs,(unsigned)v.v_proc,
X		sizeof(struct proc *),ppproc_pid_compare);
X
X	if(initial)	/* need to memcpy here making old a copy of new */
X	{
X		(void)memcpy((char *)oldprocs,(char *)procs,
X			v.v_proc * sizeof(struct proc));
X		noldprocs = nprocs;
X		(void)memcpy((char *)poldprocs,(char *)pprocs,
X			noldprocs * sizeof(struct proc *));
X	}
X
X}	/* end of read_and_sort_procs */
X
X/*+-------------------------------------------------------------------------
X	read_utmp()
X--------------------------------------------------------------------------*/
Xvoid
Xread_utmp()
X{
Xint utmpfd;
Xregister struct utmp *tutmp = utmps;
X
X	nutmps = 0;
X	if((utmpfd = open("/etc/utmp",O_RDONLY,755)) < 0)
X		leave_text("/etc/utmp open error",255);
X
X	while(read(utmpfd,(char *)(tutmp++),sizeof(struct utmp)) > 0)
X	{
X		/* ensure null termination
X		 * (clobbers 1st byte of ut_line, but we don't use it)
X		 */
X		tutmp->ut_id[sizeof(tutmp->ut_id)] = 0;
X		if(++nutmps == MAX_UTMP)
X			leave_text("too many utmp entries for me to handle",1);
X	}
X	(void)close(utmpfd);
X}	/* end of read_utmp */
X
X/*+-------------------------------------------------------------------------
X	find_utmp_for_pgrp(pgrp)
X--------------------------------------------------------------------------*/
Xstruct utmp *
Xfind_utmp_for_pgrp(pgrp)
Xint pgrp;
X{
Xstruct utmp *tutmp = utmps;
Xregister int count = nutmps;
X
X	while(count--)
X	{
X		if(tutmp->ut_pid == pgrp)
X			return(tutmp);
X		tutmp++;
X	}
X	return((struct utmp *)0);
X}	/* end of find_utmp_for_pgrp */
X
X/*+-------------------------------------------------------------------------
X	pgrp_to_ttyname(pgrp)
X--------------------------------------------------------------------------*/
Xchar *
Xpgrp_to_ttyname(pgrp)
Xint pgrp;
X{
Xregister itmp;
Xstruct utmp *tutmp;
X
X	if(!(tutmp = find_utmp_for_pgrp(pgrp)))
X	{
X		read_utmp();
X		tutmp = find_utmp_for_pgrp(pgrp);
X	}
X	if(!tutmp)
X		return("??");
X	else
X	{
X		itmp = strlen(tutmp->ut_id);
X		return(&tutmp->ut_id[(itmp >= 2) ? (itmp - 2) : 0]);
X	}
X}	/* end of pgrp_to_ttyname */
X
X/*+-------------------------------------------------------------------------
X	get_user(tproc,tuser) - read user struct for pid
Xreturn 1 if successful, else 0 if not available
X--------------------------------------------------------------------------*/
Xint
Xget_user(tproc,tuser)
Xstruct proc *tproc;
Xstruct user *tuser;
X{
X#if defined(RDUBLK)	/* see sysi86.h #include above */
Xprintf(">>getuser p=%d ",tproc->p_pid);
X	/* this system call is not returning 0 on success ?!? */
X	int rtn = !!sysi86(RDUBLK,tproc->p_pid,(char *)tuser,sizeof(*tuser)));
Xprintf(">> rtn=%d\n,rtn);
X	return(rtn);
X#else /* RDUBLK */
X	register caddr_t uptr = (caddr_t)tuser;
X	register int ubrdcount = sizeof(struct user);
X	int ipde;
X	paddr_t mptr;
X
Xprintf(">>getuser p=%d ",tproc->p_pid);
X#if !defined(ISC_1) && !defined(mips) && defined(SULOAD)
X	if(tproc->p_flag & SULOAD)
X	{
X		for(ipde = 0;
X#if defined(SVR31)
X			ipde < USIZE;
X#else
X			ipde < tproc->p_usize;
X#endif
X			ipde++)
X		{
X			if(!tproc->p_ubptbl[ipde].pgm.pg_pres)	/* if not resident */
X			{
X				printf(">> not resident\n");
X				return(0);
X			}
X			mptr = tproc->p_ubptbl[ipde].pgm.pg_pfn * NBPP;
X			mread(uptr,(daddr_t)mptr,min(ubrdcount,NBPP));
X			uptr += NBPP;
X			if((ubrdcount -= NBPP) <= 0)
X				break;
X		}
X	}
X	else
X	{
X#if defined(SVR31)
X		mptr = tproc->p_ubdbd [0].dbd_blkno * NBPSCTR;
X#else
X		mptr = tproc->p_ubdbd.dbd_blkno * NBPSCTR;
X#endif
X		sread(uptr,mptr,ubrdcount);
X	}
X#else /* ISC_1: a compromise first-attempt */
X	for(ipde = 0; ipde < USIZE; ipde++)
X	{
X		if(!tproc->p_ubptbl[ipde].pgm.pg_pres)	/* if not resident */
X			return(0);
X		mptr = tproc->p_ubptbl[ipde].pgm.pg_pfn * NBPP;
X		mread(uptr,(daddr_t)mptr,min(ubrdcount,NBPP));
X		uptr += NBPP;
X		if((ubrdcount -= NBPP) <= 0)
X			break;
X	}
X#endif /* ISC_1 */
X
X	/*
X	 * we can get crap from swap if things change after we get
X	 * an address to read from, so validate user as best we can
X	 */
X	printf(">> u_ruid=%d p_uid=%d ruid=%d p_suid=%d\n",
X	        tuser->u_ruid,tproc->p_uid,tuser->u_ruid,tproc->p_suid,
X	        ((tuser->u_ruid == tproc->p_uid) || (tuser->u_ruid == tproc->p_suid)));
X
X	return( (tuser->u_ruid == tproc->p_uid) ||
X			(tuser->u_ruid == tproc->p_suid));
X
X#endif /* RDUBLK */
X}	/* end of get_user */
X
X/*+-------------------------------------------------------------------------
Xuid to username conversion; thanks for the idea to William LeFebvre
X--------------------------------------------------------------------------*/
X#define UID_NAME_HASH_SIZE	127	/* prime */
X#define HASH_EMPTY			32767
X#define HASHIT(i)			((i) % UID_NAME_HASH_SIZE)
X
Xstruct uid_name_hash_entry {
X	ushort uid;
X	char name[10];
X};
X
Xstruct uid_name_hash_entry uid_name_table[UID_NAME_HASH_SIZE];
Xint uid_count = 0;
X
X/*+-------------------------------------------------------------------------
X	init_uid_name_hash()
X--------------------------------------------------------------------------*/
Xvoid
Xinit_uid_name_hash()
X{
Xregister int ihash = 0;
Xregister struct uid_name_hash_entry *hashent = uid_name_table;
X
X	while(ihash++ < UID_NAME_HASH_SIZE)
X	{
X		hashent->uid = HASH_EMPTY;
X		hashent++;
X	}
X}	/* end of init_uid_name_hash */
X
X/*+-------------------------------------------------------------------------
X	uid_name_enter(uid,name)
X--------------------------------------------------------------------------*/
Xint
Xuid_name_enter(uid,name)
Xregister ushort uid;
Xregister char *name;
X{
Xregister ushort table_uid;
Xregister int hashval;
X
X	if(++uid_count >= UID_NAME_HASH_SIZE - 1)
X		leave_text("too many user names for me to handle",1);
X
X	hashval = HASHIT(uid);
X	while((table_uid = uid_name_table[hashval].uid) != HASH_EMPTY)
X	{
X		if(table_uid == uid)
X			return(hashval);
X		hashval = (hashval + 1) % UID_NAME_HASH_SIZE;
X	}
X
X	uid_name_table[hashval].uid = uid;
X	(void)strncpy(uid_name_table[hashval].name,name,
X		sizeof(uid_name_table[0].name));
X
X	return(hashval);
X
X}	/* end of uid_name_enter */
X
X/*+-------------------------------------------------------------------------
X	getpwent_and_enter(uid)
X--------------------------------------------------------------------------*/
Xgetpwent_and_enter(uid)
Xregister ushort uid;
X{
Xregister int hashval;
Xregister struct passwd *pwd;
Xchar errant[10];
Xstruct passwd *getpwuid();
X
X	pwd = getpwuid(uid);
X	endpwent();
X	if(pwd)
X	{
X		hashval = uid_name_enter(pwd->pw_uid,pwd->pw_name);
X		return(hashval);
X	}
X	(void)sprintf(errant,"%u",uid);
X	return(uid_name_enter(uid,errant));
X}	/* end of getpwent_and_enter */
X
X/*+-------------------------------------------------------------------------
X	uid_to_name(uid)
X--------------------------------------------------------------------------*/
Xchar *
Xuid_to_name(uid)
Xregister ushort uid;
X{
Xregister int uid_hash;
Xregister ushort table_uid;
X
X	uid_hash = HASHIT(uid);
X	while((table_uid = uid_name_table[uid_hash].uid) != uid)
X	{
X		if(table_uid == HASH_EMPTY)
X		{
X			/* not in hash table */
X			uid_hash = getpwent_and_enter(uid);
X			break;		/* out of while */
X		}
X		uid_hash = (uid_hash + 1) % UID_NAME_HASH_SIZE;
X	}
X	return(uid_name_table[uid_hash].name);
X}	/* end of uid_to_name */
X
X/*+-----------------------------------------------------------------------
X	char *get_cpu_time_str(ticks)
X  6-char static string address is returned
X------------------------------------------------------------------------*/
Xchar *
Xget_cpu_time_str(ticks)
Xtime_t ticks;
X{
Xstatic char timestr[10];
Xtime_t mm;
Xextern int hz;
X
X	ticks /= hz;
X	mm = ticks / 60L;
X	ticks -= mm * 60L;
X
X	if(mm < 999)
X	{
X		ultoda(timestr,3,mm);
X		timestr[3] = ':';
X		ultoda_lz(timestr + 4,2,ticks);
X	}
X	else if(mm < 9999)
X	{
X		ultoda(timestr,5,mm);
X		timestr[5] = 'm';
X		timestr[6] = 0;
X	}
X	else
X		(void)strcpy(timestr,">9999m");
X
X	return(timestr);
X
X}	/* end of get_cpu_time_str */
X
X/*
X * calculated by and dependent upon layout of string below 
X * 000000000011111111112222222222333333333344444444445555555555
X * 012345678901234567890123456789012345678901234567890123456789    */
Xchar *Ps_label = 
X    "S  USER      PID   CPU PRI NI  UCPU   SCPU  SIZE TTY CMD";
X/*   #! ########X ##### ### ### ## ###### ###### #### ### ####...
X */
X#define PROC_Y		1
X#define PROC_X		0
X#define UID_X		3
X#define PID_X		13
X#define CPU_X		19
X#define PRI_X		23
X#define NICE_X		27
X#define UTIME_X		30
X#define STIME_X		37
X#define SIZE_X		44
X#define TTY_X		49
X#define CMD_X		53
X
X/*+-------------------------------------------------------------------------
X	display_proc_stat(x,y,iproc,initial)
X--------------------------------------------------------------------------*/
Xvoid
Xdisplay_proc_stat(x,y,iproc,initial)
Xint x;
Xint y;
Xregister int iproc;
Xregister int initial;
X{
Xregister struct proc *tproc = pprocs[iproc];
Xstruct proc          *oproc = poldprocs[iproc];
Xint x2;
Xchar *p_stat_str = " sRzdipx";	/* dependent on values of SSLEEP etc */
Xchar *cptr;
Xchar s80[80];
Xint fwidth = FWIDTH;
XPixel pixel;
X
X	pixel = colorGreen.pixel;
X	if((tproc->p_stat == SRUN) && !(tproc->p_flag & SLOAD))
X		pixel = colorRed.pixel;
X	else if(tproc->p_stat == SRUN)
X		pixel = colorYellow.pixel;
X
X	if((tproc->p_pid != oproc->p_pid) || (pixel != oproc->p_PIXEL))
X		initial = 1;
X	tproc->p_PIXEL = pixel;
X
X	x2 = x;
X	s80[0] = p_stat_str[tproc->p_stat];
X	s80[1] = 0;
X	x2 += disp_info_text(x2,y,pixel,s80);
X	s80[0] = (tproc->p_flag & SLOAD) ? ' ' : 'S';
X	disp_info_text(x2,y,pixel,s80);
X
X	if(initial)
X	{
X		strcpy(s80,uid_to_name(tproc->p_uid));
X		cptr = s80 + strlen(s80);
X		*cptr++ = (tproc->p_uid != tproc->p_suid) ? '#' : ' ';
X		*cptr = 0;
X		strcat(cptr,"       ");
X		s80[11] = 0;
X		disp_info_text(x + (UID_X * fwidth),y,pixel,s80);
X
X		utoda(s80,5,tproc->p_pid);
X		s80[5] = ' ';
X		s80[6] = 0;
X		disp_info_text(x + (PID_X * fwidth),y,pixel,s80);
X	}
X
X	if(initial || (tproc->p_cpu != oproc->p_cpu))
X	{
X		utoda(s80,3,tproc->p_cpu);
X		s80[3] = ' ';
X		s80[4] = 0;
X		disp_info_text(x + (CPU_X * fwidth),y,pixel,s80);
X	}
X
X	if(initial || (tproc->p_pri != oproc->p_pri))
X	{
X		utoda(s80,3,tproc->p_pri);
X		s80[3] = ' ';
X		s80[4] = 0;
X		disp_info_text(x + (PRI_X * fwidth),y,pixel,s80);
X	}
X
X	if(initial || (tproc->p_nice != oproc->p_nice))
X	{
X		utoda(s80,2,tproc->p_nice);
X		s80[2] = ' ';
X		s80[3] = 0;
X		disp_info_text(x + (NICE_X * fwidth),y,pixel,s80);
X	}
X
X	if(tproc->p_GOT_USER)
X	{
X		int surely = initial || !oproc->p_GOT_USER;
X		if(surely || (tproc->p_U_UTIME != oproc->p_U_UTIME))
X		{
X			x2 = x + (UTIME_X * fwidth);
X			disp_info_text(x2,y,pixel,get_cpu_time_str(tproc->p_U_UTIME));
X		}
X		if(surely || (tproc->p_U_STIME != oproc->p_U_STIME))
X		{
X			x2 = x + (STIME_X * fwidth);
X			disp_info_text(x2,y,pixel,get_cpu_time_str(tproc->p_U_STIME));
X		}
X		if(surely || (tproc->p_size != oproc->p_size))
X		{
X			x2 = x + (SIZE_X * fwidth);
X			ultoda(s80,4,(u_long)tproc->p_size); /* discussed at top of file */
X			disp_info_text(x2,y,pixel,s80);
X		}
X	}
X	else
X	{
X		x2 = x + (UTIME_X * fwidth);
X		disp_info_text(x2,y,pixel,"------ ------ ---- ");
X	}
X
X	if(initial || (tproc->p_pgrp != oproc->p_pgrp))
X	{
X		strcpy(s80,pgrp_to_ttyname(tproc->p_pgrp));
X		strcat(s80,"   ");
X		s80[4] = 0;
X		x2 = x + (TTY_X * fwidth);
X		disp_info_text(x2,y,pixel,s80);
X	}
X
X	if( (initial ||
X		strcmp((char *)tproc->p_U_PSARGS,(char *)oproc->p_U_PSARGS) ||
X		(tproc->p_stat != oproc->p_stat)) && (DrawAreaXYWH.width - x2) > 0)
X	{
X		x2 = x + (CMD_X * fwidth);
X		XClearArea(display,window,x2,y,DrawAreaXYWH.width - x2,FHEIGHT,0);
X		XSetForeground(display,gc,pixel);
X		if(tproc->p_GOT_USER)
X		{
X			XDrawString(display,window,gc,x2,y + FASCENT,
X				(char *)tproc->p_U_PSARGS,
X				strlen((char *)tproc->p_U_PSARGS));
X		}
X		else
X		{
X			switch(tproc->p_stat)
X			{
X				case SZOMB:
X					cptr = "<zombie>";
X					break;
X				case SXBRK:
X					cptr = "<xbreak>";
X					break;
X				case SIDL:
X					cptr = "<in creation>";
X					break;
X				default:
X					cptr = "<swap in progress>";
X			}
X			XDrawString(display,window,gc,x2,y + FASCENT,cptr,strlen(cptr));
X		}
X	}
X
X}	/* end of display_proc_stat */
X
X/*+-------------------------------------------------------------------------
X	draw_Ps_stop_work_proc()
X--------------------------------------------------------------------------*/
Xvoid
Xdraw_Ps_stop_work_proc()
X{
X	if(ps_WorkProc_ID)
X	{
X		XtRemoveWorkProc(ps_WorkProc_ID);
X		ps_WorkProc_ID = (XtWorkProcId)0;
X	}
X}	/* end of draw_Ps_stop_work_proc */
X
X/*+-------------------------------------------------------------------------
X	draw_Ps_work_proc(client_data) - XtAppLoop driven work proc
X
Xreturns true when work done
X--------------------------------------------------------------------------*/
XBoolean
Xdraw_Ps_work_proc(client_data)
Xcaddr_t client_data;
X{
Xregister int iproc = next_proc_to_display;
X
X	switch(current_display_mode)
X	{
X		case BUTTON_ps:
X		case BUTTON_Ps:
X			break;
X		default:
X			return;
X	}
X
X	display_proc_stat(next_proc_x,next_proc_y,iproc,next_proc_initial);
X	next_proc_y += FHEIGHT;
X
X	if(++next_proc_to_display == max_procs_to_display)
X	{
X		draw_Ps_stop_work_proc();
X		if(next_proc_y < DrawAreaXYWH.height)
X		{
X			XClearArea(display,window,next_proc_x,next_proc_y,
X				DrawAreaXYWH.width - next_proc_x,
X				DrawAreaXYWH.height - next_proc_y,0);
X		}
X		if(!update_timer_ID)
X			set_update_timer();
X		return(True);		/* work done */
X	}
X
X	return(False);			/* work not done */
X
X}	/* end of draw_Ps_work_proc */
X
X/*+-------------------------------------------------------------------------
X	draw_Ps(x,y,ps_procs_to_disp,initial)
X--------------------------------------------------------------------------*/
Xvoid
Xdraw_Ps(x,y,ps_procs_to_disp,initial)
Xint x;
Xint y;
Xint ps_procs_to_disp;
Xint initial;
X{
Xregister int iproc;
Xchar *cptr;
Xint fheight = FHEIGHT;
Xint yl1 = y + (FASCENT / 2);
Xint ys  = y + FASCENT;
X
Xprintf(">> darw_Ps i=%d b=%d\n",initial,current_display_mode);
X
X	if(ps_WorkProc_ID || (DrawAreaXYWH.height < (x + (FHEIGHT * 2))))
X		return;
X
X	max_procs_to_display = ps_procs_to_disp;
X	iproc = (DrawAreaXYWH.height - y) / FHEIGHT;
X	if(max_procs_to_display > iproc)
X		max_procs_to_display = iproc;
X
X	if(initial)
X	{
X		/* the "background" bar */
X		XSetForeground(display,gc,colorSlate.pixel);
X		XSetLineAttributes(display,gc,fheight,line_style,cap_style,join_style);
X		XDrawLine(display,window,gc, x,yl1, DrawAreaXYWH.width - FGAP,yl1);
X
X		/* the label */
X		XSetForeground(display,gc,foreground);
X		XDrawString(display,window,gc, x,  ys, Ps_label,strlen(Ps_label));
X		XDrawString(display,window,gc, x+1,ys, Ps_label,strlen(Ps_label));
X	}
X
X	mypid = getpid();
X	read_and_sort_procs(initial);
X	max_procs_to_display = min(nprocs,max_procs_to_display);
X	next_proc_to_display = 0;
X	next_proc_x = x;
X	next_proc_y = y + fheight;
X	next_proc_initial = initial;
X
X	ps_WorkProc_ID = XtAppAddWorkProc(appcon,draw_Ps_work_proc,
X		(caddr_t)0);
X
X}	/* end of draw_Ps */
X
X/*+-------------------------------------------------------------------------
X	initialize_Ps()
X--------------------------------------------------------------------------*/
Xinitialize_Ps()
X{
X	init_uid_name_hash();
X}	/* end of initialize_Ps */
X
X/* vi: set tabstop=4 shiftwidth=4: */
X/* end of ps.c */
SHAR_EOF
chmod 0644 x386mon/ps.c ||
echo 'restore of x386mon/ps.c failed'
Wc_c="`wc -c < 'x386mon/ps.c'`"
test 24812 -eq "$Wc_c" ||
	echo 'x386mon/ps.c: original size 24812, current size' "$Wc_c"
fi
# ============= x386mon/scales.c ==============
if test -f 'x386mon/scales.c' -a X"$1" != X"-c"; then
	echo 'x - skipping x386mon/scales.c (File already exists)'
else
echo 'x - extracting x386mon/scales.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'x386mon/scales.c' &&
X/*+-------------------------------------------------------------------------
X	scales.c - X386MON CPU and wait percentage scale handler
X	wht at n4hgf.Mt-Park.GA.US
X
X  Defined functions:
X	draw_CpuScale_literals(x,y)
X	draw_PctScale_literals(x,y,scale_name,val1_name,val2_name,val3_name)
X	draw_WaitScale_literals(x,y)
X	update_CpuScale(x,y,per_state)
X	update_PctScale(x,y,length,label,totalC,greenC,yellowC,redC)
X	update_WaitScale(x,y,per_state,total_ticks)
X
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:01-12-1991-04:35-wht at n4hgf-x1.00 (flush old edit notes) */
X
X#include "unixincs.h"
X#define WANT_MON_EXTERNS
X#include "x386mon.h"
X#include "scales.h"
X#include "utoa.h"
X
Xint PctScale_width = 0; /* calculated width of PctScale */
Xint PctScale_xoffset = 0; /* calculated x offset of PctScale */
X
X/*+-------------------------------------------------------------------------
X	draw_PctScale_literals(x,y,scale_name,val1_name,val2_name,val3_name)
X--------------------------------------------------------------------------*/
Xvoid
Xdraw_PctScale_literals(x,y,scale_name,val1_name,val2_name,val3_name)
Xint x;
Xint y;
Xchar *scale_name;
Xchar *val1_name;
Xchar *val2_name;
Xchar *val3_name;
X{
Xint x2 = x;
Xint ys  = y + FASCENT;
Xint yl1 = y + (FASCENT / 2);
Xint yl2 = y + (FHEIGHT / 2) - 1;
Xint len;
Xchar *cptr;
Xchar s80[80];
Xint line_style = LineSolid;
Xint cap_style = CapButt;
Xint join_style = JoinMiter;
X
X	/* the "background" color */
X	XSetForeground(display,gc,colorSlate.pixel);
X	XSetLineAttributes(display,gc,FHEIGHT,line_style,cap_style,join_style);
X	XDrawLine(display,window,gc,x2,yl2,
X		DrawAreaXYWH.width - BORDER_EXTRA_WIDTH,yl2);
X
X	/* -----CPU ----tot usr ker brk-------------" */
X	XSetForeground(display,gc,foreground);
X	XSetLineAttributes(display,gc,FASCENT / 2,
X		line_style,cap_style,join_style);
X	XDrawLine(display,window,gc,
X		x2,yl1,x2 + (len = (FWIDTH * 5)) - FGAP,yl1);
X	x2 += len;
X
X	strcpy(s80,scale_name);
X	strcat(s80,"    ");
X	s80[4] = 0;
X	XDrawString(display,window,gc,x2, ys,s80,len = strlen(s80));
X	XDrawString(display,window,gc,x2+1,ys,s80,len);
X	x2 += FWIDTH * len;
X
X	XDrawLine(display,window,gc,
X		x2 + FGAP + 1,yl1,x2 + (len = (FWIDTH * 4)) - FGAP,yl1);
X	x2 += len;
X
X	if(!(DrawAreaXYWH.width <= (int)(DrawArea_MIN_WIDTH * 1.5)))
X	{
X		PctScale_xoffset = x2 - x;
X		cptr = s80;
X		strcpy(cptr,"tot ");
X		cptr += 4;
X		strcpy(cptr,val1_name);
X		cptr += 3;
X		*cptr++ = ' ';
X		strcpy(cptr,val2_name);
X		cptr += 3;
X		*cptr++ = ' ';
X		strcpy(cptr,val3_name);
X		cptr += 3;
X		*cptr++ = ' ';
X		*cptr = 0;
X		XDrawString(display,window,gc,x2, ys,s80,len = strlen(s80));
X		XDrawString(display,window,gc,x2+1,ys,s80,len);
X		x2 += FWIDTH * len;
X	}
X
X	XDrawLine(display,window,gc,
X		x2,yl1,DrawAreaXYWH.width - BORDER_EXTRA_WIDTH,yl1);
X	PctScale_width = DrawAreaXYWH.width - BORDER_EXTRA_WIDTH - x2;
X
X	XSetForeground(display,gc,colorBlue.pixel);
X
X	if(DrawAreaXYWH.width <= (int)(DrawArea_MIN_WIDTH * 1.5))
X		return;
X
X	/* per scale labels */
X	XClearArea(display,window,x,y + (FHEIGHT * 1),FWIDTH * 13,FHEIGHT,0);
X	if(StatCycle_msec == 1000L)
X		cptr = " Instant %   ";
X	else
X	{
X		ultoda(s80,2,(int)(StatCycle_msec / 1000L));
X		strcpy(s80 + 2," Sec Avg % ");
X		cptr = s80;
X	}
X	XDrawString(display,window,gc,
X		x,y + (FHEIGHT * 1) + FASCENT,cptr,strlen(cptr));
X
X	XClearArea(display,window,x,y + (FHEIGHT * 2),FWIDTH * 13,FHEIGHT,0);
X	ultoda(s80,2,(int)((StatCycle_msec * 5) / 1000L));
X	strcpy(s80 + 2," Sec Avg % ");
X	XDrawString(display,window,gc,
X		x,y + (FHEIGHT * 2) + FASCENT,s80,strlen(s80));
X
X	XClearArea(display,window,x,y + (FHEIGHT * 3),FWIDTH * 13,FHEIGHT,0);
X	ultoda(s80,2,(int)((StatCycle_msec * 10) / 1000L));
X	strcpy(s80 + 2," Sec Avg % ");
X	XDrawString(display,window,gc,
X		x,y + (FHEIGHT * 3) + FASCENT,s80,strlen(s80));
X
X}	/* end of draw_PctScale_literals */
X
X/*+-------------------------------------------------------------------------
X	draw_CpuScale_literals(x,y)
X--------------------------------------------------------------------------*/
Xvoid
Xdraw_CpuScale_literals(x,y)
Xint x;
Xint y;
X{
X	draw_PctScale_literals(x,y,"CPU","usr","ker","brk");
X}	/* end of draw_CpuScale_literals */
X
X/*+-------------------------------------------------------------------------
X	draw_WaitScale_literals(x,y)
X--------------------------------------------------------------------------*/
Xvoid
Xdraw_WaitScale_literals(x,y)
Xint x;
Xint y;
X{
X	draw_PctScale_literals(x,y,"Wait"," io","pio","swp");
X}	/* end of draw_WaitScale_literals */
X
X/*+-------------------------------------------------------------------------
X	update_PctScale(x,y,scale_length,totalC,greenC,yellowC,redC)
X--------------------------------------------------------------------------*/
Xvoid
Xupdate_PctScale(x,y,scale_length,label,totalC,greenC,yellowC,redC)
Xint x,y,scale_length;
Xchar *label;
Xunsigned long totalC;
Xunsigned long greenC;
Xunsigned long yellowC;
Xunsigned long redC;
X{
Xint yl = y + (FHEIGHT / 2) - 1;	/* y for lines */
Xint ys = y + FASCENT;		/* y for strings */
Xint line_length;
Xint used_length = 0;
Xint line_style = LineSolid;
Xint cap_style = CapButt;
Xint join_style = JoinMiter;
X
X	if(scale_length < 6)
X		return;
X
X	if(totalC < (greenC + yellowC + redC))
X		totalC = greenC + yellowC + redC;
X
X	XClearArea(display,window,x,y,scale_length,FHEIGHT,0);
X	XSetLineAttributes(display,gc,FHEIGHT,line_style,cap_style,join_style);
X
X	if(line_length = (int)(((float)greenC * scale_length) / (float)totalC))
X	{
X		XSetForeground(display,gc,colorGreen.pixel);
X		XDrawLine(display,window,gc,x,yl,x + line_length,yl);
X		if(line_length > FWIDTH)
X		{
X			XSetForeground(display,gc,colorBlack.pixel);
X			XDrawString(display,window,gc,x,    ys,label + 0,1);
X			XDrawString(display,window,gc,x + 1,ys,label + 0,1);
X		}
X		used_length += line_length;
X		x += line_length;
X	}
X
X	if(line_length = (int)(((float)yellowC * scale_length) / (float)totalC))
X	{
X		XSetForeground(display,gc,colorYellow.pixel);
X		XDrawLine(display,window,gc,x,yl,x + line_length,yl);
X		if(line_length > FWIDTH)
X		{
X			XSetForeground(display,gc,colorBlack.pixel);
X			XDrawString(display,window,gc,x,    ys,label + 1,1);
X			XDrawString(display,window,gc,x + 1,ys,label + 1,1);
X		}
X		used_length += line_length;
X		x += line_length;
X	}
X
X	if(line_length = (int)(((float)redC * scale_length) / (float)totalC))
X	{
X		XSetForeground(display,gc,colorRed.pixel);
X		XDrawLine(display,window,gc,x,yl,x + line_length,yl);
X		if(line_length > FWIDTH)
X		{
X			XSetForeground(display,gc,colorBlack.pixel);
X			XDrawString(display,window,gc,x,    ys,label + 2,1);
X			XDrawString(display,window,gc,x + 1,ys,label + 2,1);
X		}
X		used_length += line_length;
X		x += line_length;
X	}
X
X	if((scale_length - used_length) > 0)
X	{
X		XSetForeground(display,gc,background);
X		XDrawLine(display,window,gc,x + used_length,yl,x + scale_length,yl);
X	}
X
X}	/* end of update_PctScale */
X
X/*+-------------------------------------------------------------------------
X	update_CpuScale(x,y,per_state)
X
X000000000011111111112222222222333333333344444444445555555555666666
X012345678901234567890123456789012345678901234567890123456789012345
Xtot usr ker brk 
X### ### ### ### xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
X--------------------------------------------------------------------------*/
X#define _CPUSCALE_TX	(FWIDTH * 0)
X#define _CPUSCALE_UX	(FWIDTH * 4)
X#define _CPUSCALE_KX	(FWIDTH * 8)
X#define _CPUSCALE_BX	(FWIDTH * 12)
X#define _CPUSCALE_SX	(FWIDTH * 16)
X
Xtime_t
Xupdate_CpuScale(x,y,per_state)
Xint x;
Xint y;
Xtime_t *per_state;
X{
Xtime_t idle = per_state[CPU_IDLE] + per_state[CPU_WAIT];
Xtime_t cpu_ticks_total = idle + per_state[CPU_SXBRK] + 
X                         per_state[CPU_KERNEL] + per_state[CPU_USER];
Xtime_t percent_user    = (per_state[CPU_USER]   * 100) / cpu_ticks_total;
Xtime_t percent_kernel  = (per_state[CPU_KERNEL] * 100) / cpu_ticks_total;
Xtime_t percent_break   = (per_state[CPU_SXBRK]  * 100) / cpu_ticks_total;
Xtime_t percent_busy    = percent_user + percent_kernel + percent_break;
Xunsigned long pixel;
Xchar numstr[8];
X
X	x += PctScale_xoffset;
X
X	if(DrawAreaXYWH.width <= 200)
X	{
X		XClearArea(display,window,0,y,DrawAreaXYWH.width,FHEIGHT,0);
X		update_PctScale(0,y,DrawAreaXYWH.width,
X			"ukb",100,percent_user,percent_kernel,percent_break);
X	}
X	else
X	{
X		XClearArea(display,window,x,y,FWIDTH * 16,FHEIGHT,0);
X
X		if(!idle)			/* take care of integer div truncation */
X			percent_busy = 100;
X
X		if(percent_busy > res.busyAlarmThreshhold)
X			pixel = colorRed.pixel;
X		else if(percent_busy > res.busyWarningThreshhold)
X			pixel = colorYellow.pixel;
X		else
X			pixel = colorGreen.pixel;
X
X		XSetForeground(display,gc,pixel);
X		ultoda(numstr,3,percent_busy);
X		XDrawString(display,window,gc,
X			x + _CPUSCALE_TX,y + FASCENT,numstr,3);
X
X		XSetForeground(display,gc,colorGreen.pixel);
X
X		ultoda(numstr,3,percent_user);
X		XDrawString(display,window,gc,
X			x + _CPUSCALE_UX,y + FASCENT,numstr,3);
X		
X		ultoda(numstr,3,percent_kernel);
X		XDrawString(display,window,gc,
X			x + _CPUSCALE_KX,y + FASCENT,numstr,3);
X		
X		if(percent_break > res.breakAlarmThreshhold)
X			XSetForeground(display,gc,colorRed.pixel);
X		else if(percent_break > res.breakWarningThreshhold)
X			XSetForeground(display,gc,colorYellow.pixel);
X
X		ultoda(numstr,3,percent_break);
X		XDrawString(display,window,gc,
X			x + _CPUSCALE_BX,y + FASCENT,numstr,3);
X	
X		update_PctScale(x + _CPUSCALE_SX,y,PctScale_width,
X			"ukb",100,percent_user,percent_kernel,percent_break);
X	}
X
X	return(cpu_ticks_total);
X
X}	/* end of update_CpuScale */
X
X/*+-------------------------------------------------------------------------
X	update_WaitScale(x,y,per_state,total_ticks)
X
X000000000011111111112222222222333333333344444444445555555555666666
X012345678901234567890123456789012345678901234567890123456789012345
Xtot  io pio swp  
X### ### ### ### xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
X--------------------------------------------------------------------------*/
X#define _WAITSCALE_TX	(FWIDTH * 0)
X#define _WAITSCALE_IX	(FWIDTH * 4)
X#define _WAITSCALE_PX	(FWIDTH * 8)
X#define _WAITSCALE_WX	(FWIDTH * 12)
X#define _WAITSCALE_SX	(FWIDTH * 16)
X
Xtime_t
Xupdate_WaitScale(x,y,per_state,total_ticks)
Xint x;
Xint y;
Xtime_t *per_state;
Xtime_t total_ticks;
X{
Xregister itmp;
Xint accum = 0;
Xtime_t percent_io = 0L;
Xtime_t percent_swap = 0L;
Xtime_t percent_pio = 0L;
Xtime_t percent_total_wait;
Xtime_t total_wait;
Xunsigned long pixel;
Xchar numstr[8];
X
X	x += PctScale_xoffset;
X
X	/* crock: because of latency, total_ticks < all wait ticks sometimes */
X	total_wait = per_state[W_IO] + per_state[W_SWAP] + per_state[W_PIO];
X	if(total_ticks < total_wait)
X		total_ticks = total_wait;
X
X	if(total_ticks)
X	{
X		percent_io    = (per_state[W_IO]   * 100) / total_ticks;
X		percent_pio   = (per_state[W_PIO]  * 100) / total_ticks;
X		percent_swap  = (per_state[W_SWAP] * 100) / total_ticks;
X	}
X	percent_total_wait = percent_io + percent_swap + percent_pio;
X
X	if(DrawAreaXYWH.width <= 200)
X	{
X		XClearArea(display,window,0,y,DrawAreaXYWH.width,FHEIGHT,0);
X		update_PctScale(0,y,DrawAreaXYWH.width,
X			"ips",100,percent_io,percent_pio,percent_swap);
X	}
X	else
X	{
X		XClearArea(display,window,x,y,FWIDTH * 16,FHEIGHT,0);
X
X		if(percent_total_wait > res.waitAlarmThreshhold)
X			pixel = colorRed.pixel;
X		else if(percent_total_wait > res.waitWarningThreshhold)
X			pixel = colorYellow.pixel;
X		else
X			pixel = colorGreen.pixel;
X
X		XSetForeground(display,gc,pixel);
X		ultoda(numstr,3,percent_total_wait);
X		XDrawString(display,window,gc,
X			x + _WAITSCALE_TX,y + FASCENT,numstr,3);
X
X		XSetForeground(display,gc,colorGreen.pixel);
X		ultoda(numstr,3,percent_io);
X		XDrawString(display,window,gc,
X			x + _WAITSCALE_IX,y + FASCENT,numstr,3);
X		
X		ultoda(numstr,3,percent_pio);
X		XDrawString(display,window,gc,
X			x + _WAITSCALE_PX,y + FASCENT,numstr,3);
X		
X		if(percent_swap > res.swapAlarmThreshhold)
X			XSetForeground(display,gc,colorRed.pixel);
X		else if(percent_swap > res.swapWarningThreshhold)
X			XSetForeground(display,gc,colorYellow.pixel);
X
X		ultoda(numstr,3,percent_swap);
X		XDrawString(display,window,gc,
X			x + _WAITSCALE_WX,y + FASCENT,numstr,3);
X		
X		update_PctScale(x + _WAITSCALE_SX,y,PctScale_width,
X			"ips",100,percent_io,percent_pio,percent_swap);
X	}
X
X}	/* end of update_WaitScale */
X
X/* vi: set tabstop=4 shiftwidth=4: */
X/* end of scales.c */
SHAR_EOF
chmod 0644 x386mon/scales.c ||
echo 'restore of x386mon/scales.c failed'
Wc_c="`wc -c < 'x386mon/scales.c'`"
test 12204 -eq "$Wc_c" ||
	echo 'x386mon/scales.c: original size 12204, current size' "$Wc_c"
fi
# ============= x386mon/scales.h ==============
if test -f 'x386mon/scales.h' -a X"$1" != X"-c"; then
	echo 'x - skipping x386mon/scales.h (File already exists)'
else
echo 'x - extracting x386mon/scales.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'x386mon/scales.h' &&
X
X/*+-------------------------------------------------------------------------
X	scales.h
X	wht at n4hgf.Mt-Park.GA.US
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:01-12-1991-04:35-wht at n4hgf-x1.00 (flush old edit notes) */
X
Xvoid update_PctScale(int,int,int,char *,
X		unsigned long,unsigned long,unsigned long,unsigned long);
Xtime_t update_CpuScale(int,int,time_t *);
Xtime_t update_WaitScale(int,int,time_t *,time_t);
X
X/* vi: set tabstop=4 shiftwidth=4: */
X/* end of scales.h */
SHAR_EOF
chmod 0644 x386mon/scales.h ||
echo 'restore of x386mon/scales.h failed'
Wc_c="`wc -c < 'x386mon/scales.h'`"
test 520 -eq "$Wc_c" ||
	echo 'x386mon/scales.h: original size 520, current size' "$Wc_c"
fi
# ============= x386mon/sysinfo.c ==============
if test -f 'x386mon/sysinfo.c' -a X"$1" != X"-c"; then
	echo 'x - skipping x386mon/sysinfo.c (File already exists)'
else
echo 'x - extracting x386mon/sysinfo.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'x386mon/sysinfo.c' &&
X/*+-------------------------------------------------------------------------
X	sysinfo.c - X386MON sysinfo/minfo display handler
X	wht at n4hgf.Mt-Park.GA.US
X
X  Defined functions:
X	draw_Sysinfo_literals(x,y)
X	update_Sysinfo()
X
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:01-12-1991-04:35-wht at n4hgf-x1.00 (flush old edit notes) */
X
X#include "unixincs.h"
X#define WANT_MON_EXTERNS
X#include "x386mon.h"
X#include "buttons.h"
X#include "disp_info.h"
X
Xint sysinfo_tlx;
Xint sysinfo_tly;
X
X/*+-------------------------------------------------------------------------
X	update_Sysinfo()
X--------------------------------------------------------------------------*/
Xvoid
Xupdate_Sysinfo()
X{
Xregister int x,y;
Xint fheight = FHEIGHT;
Xint itmp;
Xlong ltmp;
XPixel pixel;
X
X	switch(current_display_mode)
X	{
X		case BUTTON_main:
X		case BUTTON_ps:
X			break;
X		default:
X			return;
X	}
X
X	if(DrawAreaXYWH.height < (sysinfo_tly + (fheight * 2)))
X		return;
X
X	y = sysinfo_tly + fheight;
X	x = sysinfo_tlx + Sysinfo1_TLX;
X	disp_info_long(x,y,"bread    ",7,sysidelta(bread));
X	y += fheight;
X	disp_info_long(x,y,"bwrite   ",7,sysidelta(bwrite));
X	y += fheight;
X	if((ltmp = sysidelta(lread) - myreadcnt) < 0)
X		ltmp = 0;
X	disp_info_long(x,y,"lread    ",7,ltmp);
X	y += fheight;
X	myreadcnt = 0;	/* reset /dev/{mem,kmem,swap} read count */
X	disp_info_long(x,y,"lwrite   ",7,sysidelta(lwrite));
X	y += fheight;
X	disp_info_long(x,y,"phread   ",7,sysidelta(phread));
X	y += fheight;
X	disp_info_long(x,y,"phwrite  ",7,sysidelta(phwrite));
X	y += fheight;
X	disp_info_long(x,y,"swapin   ",7,sysidelta(swapin));
X	y += fheight;
X	disp_info_long(x,y,"swapout  ",7,sysidelta(swapout));
X	y += fheight;
X	disp_info_long(x,y,"bswapin  ",7,sysidelta(bswapin));
X	y += fheight;
X	disp_info_long(x,y,"bswapout ",7,sysidelta(bswapout));
X	y += fheight;
X	disp_info_long(x,y,"iget     ",7,sysidelta(iget));
X	y += fheight;
X	disp_info_long(x,y,"namei    ",7,sysidelta(namei));
X	y += fheight;
X	disp_info_long(x,y,"dirblk   ",7,sysidelta(dirblk));
X	y += fheight;
X
X	y = sysinfo_tly + fheight;
X	x = sysinfo_tlx + Sysinfo2_TLX;
X	if((ltmp = sysidelta(readch) - myreadlen) < 0)
X		ltmp = 0;
X	disp_info_long(x,y,"readch  ",7,ltmp);
X	y += fheight;
X	myreadlen = 0;	/* reset /dev/{mem,kmem,swap} read count */
X
X	disp_info_long(x,y,"writch  ",7,sysidelta(writech));
X	y += fheight;
X
X	disp_info_long(x,y,"rawch   ",7,sysidelta(rawch));
X	y += fheight;
X	disp_info_long(x,y,"canch   ",7,sysidelta(canch));
X	y += fheight;
X	disp_info_long(x,y,"outch   ",7,sysidelta(outch));
X	y += fheight;
X
X	disp_info_long(x,y,"msg     ",7,sysidelta(msg));
X	y += fheight;
X	disp_info_long(x,y,"sema    ",7,sysidelta(sema));
X	y += fheight;
X
X	disp_static_long_units(x,y, "maxmem  ",6,"k",(long)maxmem * NBPP / 1024);
X	y += fheight;
X	disp_info_long_units(x,y,   "frmem   ",6,"k",(long)freemem * NBPP / 1024);
X	y += fheight;
X	itmp = 100 - (int)((freemem * 100) / maxmem);
X	if(itmp >= 80)
X		pixel = colorRed.pixel;
X	else if(itmp >= 50)
X		pixel = colorYellow.pixel;
X	else
X		pixel = colorGreen.pixel;
X	disp_info_units_color(x,y,"mem used",6,"%",(unsigned long)itmp,pixel);
X	y += fheight;
X
X	disp_static_int_units(x,y, "nswap   ",6,"k",nswap * NBPSCTR / 1024);
X	y += fheight;
X	disp_info_long_units(x,y,  "frswp   ",6,"k",minfo.freeswap* NBPSCTR/1024);
X	y += fheight;
X	itmp = 100 - (int)((minfo.freeswap * 100) / nswap);
X	if(itmp >= 80)
X		pixel = colorRed.pixel;
X	else if(itmp >= 50)
X		pixel = colorYellow.pixel;
X	else
X		pixel = colorGreen.pixel;
X	disp_info_units_color(x,y,"swp used",6,"%",(unsigned long)itmp,pixel);
X	y += fheight;
X
X	y = sysinfo_tly + fheight;
X	x = sysinfo_tlx + Sysinfo3_TLX;
X	disp_info_long(x,y,"pswitch ",5,sysidelta(pswitch));
X	y += fheight;
X	disp_info_long(x,y,"syscall ",5,sysidelta(syscall));
X	y += fheight;
X	disp_info_long(x,y,"sysread ",5,sysidelta(sysread));
X	y += fheight;
X	disp_info_long(x,y,"syswrit ",5,sysidelta(syswrite));
X	y += fheight;
X	disp_info_long(x,y,"sysfork ",5,sysidelta(sysfork));
X	y += fheight;
X	disp_info_long(x,y,"sysexec ",5,sysidelta(sysexec));
X	y += fheight;
X
X	y += fheight;
X	disp_info_long(x,y,"runque  ",5,sysidelta(runque));
X	y += fheight;
X	disp_info_long(x,y,"runocc  ",5,sysidelta(runocc));
X	y += fheight;
X	disp_info_long(x,y,"swpque  ",5,sysidelta(swpque));
X	y += fheight;
X	disp_info_long(x,y,"swpocc  ",5,sysidelta(swpocc));
X	y += fheight;
X
X	y = sysinfo_tly + fheight;
X	x = sysinfo_tlx + Sysinfo4_TLX;
X	disp_info_long(x,y,"vfault  ",3,midelta(vfault));
X	y += fheight;
X	disp_info_long(x,y,"demand  ",3,midelta(demand));
X	y += fheight;
X	disp_info_long(x,y,"pfault  ",3,midelta(pfault));
X	y += fheight;
X	disp_info_long(x,y,"cw      ",3,midelta(cw));
X	y += fheight;
X	disp_info_long(x,y,"steal   ",3,midelta(steal));
X	y += fheight;
X	disp_info_long(x,y,"frdpgs  ",3,midelta(freedpgs));
X	y += fheight;
X#if defined(SVR32)
X	disp_info_long(x,y,"vfpg    ",3,midelta(vfpg));
X	y += fheight;
X	disp_info_long(x,y,"sfpg    ",3,midelta(sfpg));
X	y += fheight;
X	disp_info_long(x,y,"vspg    ",3,midelta(vspg));
X	y += fheight;
X	disp_info_long(x,y,"sspg    ",3,midelta(sspg));
X	y += fheight;
X	disp_info_long(x,y,"pnpfault",3,sysidelta(pnpfault));
X	y += fheight;
X	disp_info_long(x,y,"wrtfault",3,sysidelta(wrtfault));
X	y += fheight;
X#endif
X
X	y = sysinfo_tly + fheight;
X	x = sysinfo_tlx + Sysinfo5_TLX;
X	disp_info_long(x,y,"unmodsw ",3,midelta(unmodsw));
X	y += fheight;
X	disp_info_long(x,y,"unmodfl ",3,midelta(unmodfl));
X	y += fheight;
X#if defined(SVR32)
X	disp_info_long(x,y,"psoutok ",3,midelta(psoutok));
X	y += fheight;
X	disp_info_long(x,y,"psinfai ",3,midelta(psinfail));
X	y += fheight;
X	disp_info_long(x,y,"psinok  ",3,midelta(psinok));
X	y += fheight;
X	disp_info_long(x,y,"rsout   ",3,midelta(rsout));
X	y += fheight;
X	disp_info_long(x,y,"rsin    ",3,midelta(rsin));
X	y += fheight;
X#endif
X
X	y += fheight;
X	disp_info_int(x,y,"pages on   ",0,0);
X	y += fheight;
X	disp_info_long(x,y,"swap  ",5,midelta(swap));
X	y += fheight;
X	disp_info_long(x,y,"cache ",5,midelta(cache));
X	y += fheight;
X	disp_info_long(x,y,"file  ",5,midelta(file));
X	y += fheight;
X
X}	/* end of update_Sysinfo */
X
X/*+-------------------------------------------------------------------------
X	draw_Sysinfo_literals(x,y,scale_name,val1_name,val2_name,val3_name)
X--------------------------------------------------------------------------*/
Xvoid
Xdraw_Sysinfo_literals(x,y)
Xint x;
Xint y;
X{
Xint x2 = x;
Xint ys  = y + FASCENT;
Xint yl1 = y + (FASCENT / 2) + 1;
Xint yl2 = y + (FHEIGHT / 2);
Xint len;
Xchar *cptr;
Xchar s80[80];
Xint fheight = FHEIGHT;
Xint fwidth = FWIDTH;
Xint line_style = LineSolid;
Xint cap_style = CapButt;
Xint join_style = JoinMiter;
X
X	sysinfo_tlx = x;
X	sysinfo_tly = y;
X
X	/* the "background" color */
X	XSetForeground(display,gc,colorSlate.pixel);
X	XSetLineAttributes(display,gc,fheight,
X		line_style,cap_style,join_style);
X	XDrawLine(display,window,gc, x,yl2, x + (77 * fwidth),yl2);
X
X	/* "-----Sysinfo/Minfo-----------------" */
X	XSetForeground(display,gc,foreground);
X	XSetLineAttributes(display,gc,FASCENT / 2,
X		line_style,cap_style,join_style);
X	XDrawLine(display,window,gc,
X		x2,yl1,
X		x2 + (len = (fwidth * 5)) - FGAP,yl1);
X	x2 += len;
X
X	cptr = "Sysinfo/Minfo";
X	XDrawString(display,window,gc, x2,  ys, cptr,len = strlen(cptr));
X	XDrawString(display,window,gc, x2+1,ys, cptr,len);
X	x2 += (fwidth * len) + FGAP + 1;
X
X	XDrawLine(display,window,gc, x2,yl1, x + (77 * fwidth),yl1);
X
X}	/* end of draw_Sysinfo_literals */
X
X/* vi: set tabstop=4 shiftwidth=4: */
X/* end of sysinfo.c */
SHAR_EOF
chmod 0644 x386mon/sysinfo.c ||
echo 'restore of x386mon/sysinfo.c failed'
Wc_c="`wc -c < 'x386mon/sysinfo.c'`"
test 7424 -eq "$Wc_c" ||
	echo 'x386mon/sysinfo.c: original size 7424, current size' "$Wc_c"
fi
true || echo 'restore of x386mon/tune.c failed'
echo End of part 4, continue with part 5
exit 0
 
-----------------------------------------------------------------------
Warren Tucker, TuckerWare   gatech!n4hgf!wht or wht at n4hgf.Mt-Park.GA.US
Many [Nobel physics] prizes  have been given  to people for  telling us
the universe is not as simple as we thought it was. -Stephen Hawking in
A Brief History of Time     In computing, there are no such prizes. -me



More information about the Alt.sources mailing list