wht@tridom.uucp (Warren Tucker) (10/28/89)
This ditty displays XENIX V/386 process status in "real time" on a Wyse 60 in native mode. Login shells (**argv == '-') are omitted. It works with SCO XENIX V/386 2.3.1 and beyond and compiles ok with development system 2.3.1. Just unshar and make. The README talks about necessary permissions. #!/bin/sh # shar: Shell Archiver (v1.22) # # Run the following text with /bin/sh to create: # README # Makefile # w6.c # w6.h # w6ps.c # if test -f README; then echo "File README exists"; else echo "x - extracting README (Text)" sed 's/^X//' << 'SHAR_EOF' > README && Xw6ps - XENIX V/386 Wyse 60 process status display in 43-line, 132-col mode X XThis ditty displays XENIX V/386 process status in "real time" on a Wyse X60 in native mode. Login shells (**argv == '-') are omitted. It works Xwith SCO XENIX V/386 2.3.1 and beyond and compiles ok with development Xsystem 2.3.1. X XIt is offered to the public domain with no warranty as-is: a reasonable X"ps" that doesn't blow up with seek errors (so far :-)) and a decent Xtoolkit for Wyse 60 manipulation and kmem/mem munging. X XNOTES: X1. w6ps must be able to access /dev/{*mem,swap}. This means: X a. chmod +r /dev/{*mem,swap} BAD IDEA X b. chown sysinfo w6ps;chmod u+s w6ps X X2. I use a Wyse 60 as a non-enabled terminal on "/dev/tty2h" and the Xprogram has that name hard-coded; you'll probably need to change X'w6tty_default' in w6.c. X X3. The program misbehaves if there are more than about 40 "non-login" Xprocesses. X X4. The terminal is expected to be set for 9600 baud. X X5. w6test tests the w6.c driver. SHAR_EOF chmod 0644 README || echo "restore of README fails" fi if test -f Makefile; then echo "File Makefile exists"; else echo "x - extracting Makefile (Text)" sed 's/^X//' << 'SHAR_EOF' > Makefile && X# CHK=0xD8E4 X# X# Makefile for w6test and w6ps X# X# NOTE: w6ps needs chown sysinfo,chmod u+s for access to /dev/{*mem,swap} X# X#+:EDITS: X#:01-07-1989-12:21-wht-creation X XC_EXTRA = -i -M3 XCFLAGS = -LARGE -DLINT_ARGS -Ox -K $(C_EXTRA) XLDFLAGS = $(C_EXTRA) -lx X X.c.o:; cc -c $(CFLAGS) $*.c X XW6PS_OFILES = \ X w6ps.o\ X w6.o X Xall: w6ps w6test X Xw6test: w6test.o X cc $(LDFLAGS) w6test.o -o w6test X Xw6ps: $(W6PS_OFILES) X cc $(LDFLAGS) $(W6PS_OFILES) -o w6ps X Xw6test.o: w6.c X cc -DTEST -Fow6test.o -c $(CFLAGS) w6.c SHAR_EOF chmod 0644 Makefile || echo "restore of Makefile fails" fi if test -f w6.c; then echo "File w6.c exists"; else echo "x - extracting w6.c (Text)" sed 's/^X//' << 'SHAR_EOF' > w6.c && X/* CHK=0xF46E */ X Xchar *w6tty_default = "/dev/tty2h"; X X/*+------------------------------------------------------------------------- X w6.c - Wyse 60 (native mode) display driver X ...!gatech!emory!tridom!wht - Public Domain X X Defined functions: X _w6_delta_attr(bit,state) X _w6_lgetc(char_rtnd) X main() X w6_132cols() X w6_24lines() X w6_25lines() X w6_42lines() X w6_43lines() X w6_80cols() X w6attr(attr) X w6blink(on) X w6close() X w6clr() X w6clrline() X w6clrtobot() X w6clrtoeol() X w6ctrl(ctrl_cmd) X w6dim(on) X w6eolwrap(on) X w6home() X w6ins_line() X w6mon_mode(on) X w6move(y,x) X w6norm() X w6oneseg() X w6open(line) X w6prog_fkey_label(keynum,str) X w6prog_fkey_str(keynum,str) X w6putc(ch) X w6reverse(on) X w6scroll(onflag) X w6set_time() X w6topline(msg) X w6underline(on) X w6xonxoff(on) X X--------------------------------------------------------------------------*/ X/*+:EDITS:*/ X/*:01-04-1989-18:03-wht-creation */ X X#include <stdio.h> X#include <signal.h> X#include <ctype.h> X#include <sys/types.h> X#include <sys/errno.h> X X#if defined(M_XENIX) X#include <sys/stat.h> X#include <sys/ioctl.h> X#include <string.h> X#include <fcntl.h> X#include <termio.h> X#endif X X#if defined(pyr) X#include <sys/stat.h> X#include <sys/file.h> X#include <sys/termio.h> X#include <strings.h> X#endif X X#include <time.h> X#include <sys/timeb.h> X X#include "w6.h" Xextern int errno; X Xint w6fd = -1; /* file descriptor for line */ Xchar w6_ttyname[64]; /* /dev/ttyname for line */ Xstruct termio w6_termio; /* attributes for the line to remote */ X X Xvoid w6putc(ch) Xchar ch; X{ write(w6fd,&ch,1); } X Xvoid w6putcs(str,count) char *str; int count; X{ write(w6fd,str,count);} X Xvoid w6puts(str) char *str; X{ write(w6fd,str,strlen(str));} X Xvoid w6xonxoff(on) X{ w6putcs("\033c2",3); w6putc(on ? '1' : '0'); } X Xvoid w6clr() /* clear screen */ X{ w6putc(26);} X Xchar w6_home[]={ ESC,'{'}; Xvoid w6home() /* home screen */ X{ w6putcs(w6_home,2); } X Xvoid w6scroll(onflag) /* scroll on/off */ X{ w6putc(ESC); w6putc((onflag) ? 'O' : 'N'); } X Xvoid w6oneseg() /* whole screen one segment */ X{ Xstatic char w6_oneseg[]={ ESC,'x','0',}; X w6putcs(w6_oneseg,3); X} X Xvoid w6topline(msg) Xchar *msg; X{ Xstatic char w6_topline[]={ESC,'F'}; X w6putcs(w6_topline,2); X w6putcs(msg,strlen(msg)); X w6putc(0x0D); X} X Xvoid w6ctrl(ctrl_cmd) /* display control */ Xint ctrl_cmd; X{ Xstatic char w6_ctrl[]={ ESC,'`' }; X w6putcs(w6_ctrl,2); X w6putc(ctrl_cmd); X} Xstatic int _w6_cols = -1; X Xvoid w6_132cols() X{ w6ctrl(W6_132);_w6_cols = 132;} Xvoid w6_80cols() X{ w6ctrl(W6_80); _w6_cols = 80;} X Xvoid _w6lines(spec) char spec; X{ static char cmd[] = {ESC,'e'}; X w6putcs(cmd,2); w6putc(spec); X} Xvoid w6_24lines() X{ _w6lines('('); } Xvoid w6_25lines() X{ _w6lines(')'); } Xvoid w6_42lines() X{ _w6lines('*'); } Xvoid w6_43lines() X{ _w6lines('+'); } X Xvoid w6ins_line() X{ w6putc(ESC);w6putc('E');} X Xvoid w6move(y,x) Xunsigned char y,x; X{ Xchar buf[16]; X if(_w6_cols == 80) X sprintf(buf,"\033=%c%c",y+20,x+20); X else X sprintf(buf,"\033a%dR%dC",y + 1,x + 1); X w6puts(buf); X} X Xvoid w6clrtoeol() X{ static char cmd[]={ESC,'c','O'}; X w6putcs(cmd,3); X} X Xvoid w6clrtobot() X{ static char cmd[]={ESC,'Y'}; X w6putcs(cmd,2); X} X Xvoid w6clrline() X{ static char cmd[]={0x0D,ESC,'c','O'}; X w6putcs(cmd,4); X} X Xvoid w6set_time() X{ Xchar buf[10]; Xlong time(); Xlong now = time((long *)0); Xstruct tm *localtime(); Xstruct tm *lt = localtime(&now); X sprintf(buf,"\033c8%02d%02d",lt->tm_hour,lt->tm_min); X w6puts(buf); X} X X Xstatic char w6_attrcmd[]={ ESC,'G'}; Xstatic char w6_attr = '0'; X Xvoid w6norm() /* normal attribute */ X{ X w6_attr = '0'; X w6putcs(w6_attrcmd,2); X w6putc(w6_attr); X} X Xvoid w6attr(attr) /* absolute */ X{ X w6_attr = '0' | attr; X w6putcs(w6_attrcmd,2); X w6putc(w6_attr); X} X Xvoid _w6_delta_attr(bit,state) /* delta */ Xunsigned char bit,state; X{ X if(state) X w6_attr |= bit; X else X w6_attr &= ~bit; X w6putcs(w6_attrcmd,2); X w6putc(w6_attr); X} X Xvoid w6blink(on) /* blink */ X{ _w6_delta_attr(W6BLINK,on); } X Xvoid w6reverse(on) /* reverse */ X{ _w6_delta_attr(W6REVERSE,on); } X Xvoid w6underline(on) /* reverse */ X{ _w6_delta_attr(W6UNDERLINE,on); } X Xvoid w6dim(on) /* dim */ X{ _w6_delta_attr(W6DIM,on); } X X Xvoid w6eolwrap(on) X{ w6putcs("\033d",2); w6putc(on ? '/' : '.'); } X Xvoid w6mon_mode(on) X{ w6eolwrap(on); w6putc(ESC); w6putc(on ? 'U' : 'u'); } X Xvoid w6prog_fkey_str(keynum,str) Xint keynum; Xchar *str; X{ Xchar wstr[128]; X sprintf(wstr,"\033z%c%s\177",keynum - 1 + '@',str); X w6puts(wstr); X X} /* end of w6prog_fkey_str */ X Xvoid w6prog_fkey_label(keynum,str) Xint keynum; Xchar *str; X{ Xchar wstr[128]; X X sprintf(wstr,"\033z%c%s\177",keynum - 1 + '0',str); X write(w6fd,wstr,strlen(wstr)); X X} /* end of w6prog_fkey_label */ X X/*+------------------------------------------------------------------------- X _w6_lgetc(char_rtnd) -- get char from line X--------------------------------------------------------------------------*/ Xvoid X_w6_lgetc(char_rtnd) Xchar *char_rtnd; X{ Xextern int errno; X XREAD_AGAIN: X errno = 0; X if(read(w6fd,char_rtnd,1) < 1) X { X if(errno == EINTR) /* if signal interrupted, ... */ X goto READ_AGAIN; X exit(250); X } X} /* end of _w6_lgetc */ X X/*+---------------------------------------------------------------------- X w6open(line) Xreturns negative W6_OPEN_ codes if failure else positive pid using line Xelse 0 if successful open X------------------------------------------------------------------------*/ Xint Xw6open(line) Xchar *line; X{ Xregister int itmp; X X strcpy(w6_ttyname,line); X if(!strcmp(w6_ttyname,"/dev/tty")) X return(W6_OPEN_INVALID); X if(w6fd >= 0) X return(W6_OPEN_ALREADY); X X w6fd = open(w6_ttyname,O_RDWR | O_NDELAY,0777); X if(w6fd < 0) X { X perror(w6_ttyname); X return(W6_OPEN_OPNFAIL); X } X else X { X fcntl(w6fd,F_SETFL,O_RDWR); X ioctl(w6fd,(int)TCGETA,(char *) &w6_termio); X w6_termio.c_iflag = IGNPAR | IGNBRK | IXON; X w6_termio.c_oflag = OPOST | ONLCR | ONOCR; X w6_termio.c_cflag = CREAD | CLOCAL | CS8 | CSTOPB | B9600; X#if defined(USE_XCLUDE) X w6_termio.c_lflag = XCLUDE; X#else X w6_termio.c_lflag = 0; X#endif X w6_termio.c_cc[VMIN] = 1; X w6_termio.c_cc[VTIME] = 1; X ioctl(w6fd,(int)TCSETA,(char *) &w6_termio); X } X X w6mon_mode(0); X w6xonxoff(1); X w6set_time(); X return(0); X X} /* end of w6open */ X X/*+----------------------------------------------------------------------- X w6close() X------------------------------------------------------------------------*/ Xvoid w6close() X{ X if(w6fd < 0) X return; X close(w6fd); X w6fd = -1; X X} /* end of w6close */ X X#if defined(TEST) Xmain() X{ Xregister int offset; Xregister int itmp; X X if(itmp = w6open(w6tty_default)) X { X printf("w6open error %d\n",itmp); X exit(1); X } X X w6set_time(); X w6ctrl(W6SCROFF); X w6clr(); X w6topline(""); X w6ctrl(W6SCRON); X w6ctrl(W6CUROFF); X w6eolwrap(1); X w6topline("Wyse 60 test"); X w6_132cols(); X w6_43lines(); X X for(offset = 0; offset < 100; offset += 10) X { X for(itmp = 1; itmp < 10; itmp++) X { X w6move(itmp,itmp + offset); X w6putc('\\'); X } X X for(itmp = 9; itmp > 0; itmp--) X { X w6move(itmp,offset + 20 - itmp); X w6putc('/'); X } X } X X w6move(16,0); X X w6norm(); X w6puts("normal"); X w6putc('\n'); X X w6reverse(1); X w6puts("reverse"); X w6putc('\n'); X X w6dim(1); X w6puts("dim reverse"); X w6norm(); X w6putc('\n'); X X w6blink(1); X w6puts("blinking\n"); X X w6attr(W6DIM); X w6puts("dim\n"); X X w6blink(1); X w6puts("dim blinking"); X w6norm(); X w6putc('\n'); X X w6move(23,0,stdout); X w6ctrl(W6SCRON); X X w6ctrl(W6CURLIN); X w6ctrl(W6CURON); X w6move(0,0); X w6puts("*"); X w6move(42,0); X w6puts("*"); X w6close(); X exit(1); X} X X#endif X X/* vi: set tabstop=4 shiftwidth=4: */ SHAR_EOF chmod 0644 w6.c || echo "restore of w6.c fails" fi if test -f w6.h; then echo "File w6.h exists"; else echo "x - extracting w6.h (Text)" sed 's/^X//' << 'SHAR_EOF' > w6.h && X/* CHK=0xE557 */ X/*+------------------------------------------------------------------------- X w6.h X ...!gatech!emory!tridom!wht - Public Domain X--------------------------------------------------------------------------*/ X/*+:EDITS:*/ X/*:01-05-1989-18:35-wht-creation */ X X#ifdef ESC X#undef ESC X#endif X#define ESC 0x1B X X/* w6open() and related routines error codes */ X#define W6_OPEN_INVALID -1 /* for invalid tty name */ X#define W6_OPEN_UNKPID -2 /* unknown pid using line */ X#define W6_OPEN_LCKERR -3 /* lock file open error */ X#define W6_OPEN_NODEV -4 /* device does not exist */ X#define W6_OPEN_OPNFAIL -5 /* could not open line */ X#define W6_OPEN_ALREADY -6 /* line already open */ X X/* w6ctrl() parameters */ X#define W6CUROFF '0' /* cursor off */ X#define W6CURON '1' /* cursor on */ X#define W6CURBLK '2' /* cursor steady block */ X#define W6CURLINBLINK '3' /* cursor blinking block */ X#define W6CURLIN '4' /* cursor steady line */ X#define W6CURBLKBLINK '5' /* cursor blinking block */ X#define W6SCROFF '8' /* turn off screen */ X#define W6SCRON '9' /* turn on screen */ X#define W6_132 ';' /* 132 column */ X#define W6_80 ':' /* 80 column */ X#define W6SCRLJUMP '@' /* jump scroll */ X#define W6SCRLSMOOTH1 '<' /* smooth scroll 1 line per second */ X#define W6SCRLSMOOTH2 '=' /* smooth scroll 2 line per second */ X#define W6SCRLSMOOTH4 '>' /* smooth scroll 4 line per second */ X#define W6SCRLSMOOTH8 '?' /* smooth scroll 8 line per second */ X X/* w6attr() parameters */ X#define W6BLINK 0x02 X#define W6REVERSE 0x04 X#define W6UNDERLINE 0x08 X#define W6DIM 0x40 X SHAR_EOF chmod 0644 w6.h || echo "restore of w6.h fails" fi if test -f w6ps.c; then echo "File w6ps.c exists"; else echo "x - extracting w6ps.c (Text)" sed 's/^X//' << 'SHAR_EOF' > w6ps.c && X/* CHK=0xC5D1 */ X/*+------------------------------------------------------------------------- X w6ps.c - XENIX V/386 Wyse 60 process status display X ...!gatech!emory!tridom!wht - Public Domain X X Defined functions: X display_line0() X display_proc(iproc,initial) X display_procs(initial) X error_term(text) X find_utmp_for_pgrp(pgrp) X get_cpu_time_str(timeval) X get_procs() X get_user(proc,slot,user) X getpwent_and_enter(uid) X init_uid_name_hash() X main(argc,argv,envp) X perror_term(text,code) X pgrp_to_ttyname(pgrp) X proc_pid_compare(p1,p2) X read_utmp() X uid_name_enter(uid,name) X uid_to_name(uid) X X--------------------------------------------------------------------------*/ X/*+:EDITS:*/ X/*:01-05-1989-13:27-wht-creation */ X X#include <stdio.h> X#include <fcntl.h> X#include <pwd.h> X#include <sys/param.h> X#include <sys/sysmacros.h> X#include <sys/types.h> X#include <sys/page.h> X#include <sys/seg.h> X#include <sys/proc.h> X#include <sys/signal.h> X#include <sys/dir.h> X#include <sys/user.h> X#include <sys/var.h> X#include <sys/utsname.h> X#include <utmp.h> X#include "w6.h" X Xchar *malloc(int); Xchar *calloc(int,int); X Xextern int errno; X Xint memfd; Xint kmemfd; Xint swapfd; X Xint w6ps_pid; Xint noldprocs; Xint nprocs; Xint mpid; Xint hz; Xunsigned short avenrun[3]; Xstruct var v; Xstruct file *files; Xstruct inode *inodes; Xstruct text *texts; Xstruct proc *procs; Xstruct proc *oldprocs; Xstruct mount *mounts; Xstruct buf *bufs; Xstruct buf *bufstart; Xstruct user user; Xdaddr_t swplo; Xstruct utsname utsname; Xtime_t ktime; Xtime_t klbolt; X#define MAX_UTMP 32 Xint nutmps = 0; Xstruct utmp utmps[MAX_UTMP]; X X#define XL_V 0 X#define XL_FILE 1 X#define XL_INODE 2 X#define XL_PROC 3 X#define XL_TEXT 4 X#define XL_MOUNT 5 X#define XL_BUFFER 6 X#define XL_SWPLO 7 X#define XL_TIME 8 X#define XL_LBOLT 9 X#define XL_UTSNAME 10 X#define XL_USER 11 X#define XL_AVENRUN 12 X#define XL_MPID 13 X#define XL_HZ 14 X Xstruct xlist namelist[] = X{ X { 0,0,0,"_v" }, X { 0,0,0,"_file" }, X { 0,0,0,"_inode" }, X { 0,0,0,"_proc" }, X { 0,0,0,"_text" }, X { 0,0,0,"_mount" }, X { 0,0,0,"_bufstrt" }, X { 0,0,0,"_swplo" }, X { 0,0,0,"_time" }, X { 0,0,0,"_lbolt" }, X { 0,0,0,"_utsname" }, X { 0,0,0,"_u" }, X { 0,0,0,"_avenrun" }, X { 0,0,0,"_mpid" }, X { 0,0,0,"_hz" }, X { 0,0,0,(char *) 0 } X}; X Xperror_term(text,code) Xchar *text; Xint code; X{ X fputs(text,stdout); X printf(" code=%d ",code); X perror(""); X exit(1); X} X Xerror_term(text) Xchar *text; X{ X fputs(text,stdout); X exit(1); X} X X/*+------------------------------------------------------------------------- X read_utmp() X--------------------------------------------------------------------------*/ Xvoid Xread_utmp() X{ Xint utmpfd; Xstruct utmp *tutmp = utmps; X X nutmps = 0; X if((utmpfd = open("/etc/utmp",O_RDONLY,755)) < 0) X { X perror_term("/etc/utmp",errno); X exit(1); X } X X while(read(utmpfd,(char *)(tutmp++),sizeof(struct utmp)) > 0) X { X if(++nutmps == MAX_UTMP) X error_term("too many utmp entries for me to handle"); X } X 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{ 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 return(tutmp->ut_id); X} /* end of pgrp_to_ttyname */ X X/*+------------------------------------------------------------------------- X get_user(proc,slot,user) X--------------------------------------------------------------------------*/ Xget_user(proc,slot,user) Xstruct proc *proc; Xint slot; /* not used */ Xstruct user *user; X{ X struct proc *first_proc = (struct proc *) namelist[XL_PROC].xl_value; X long swapaddr; X int i; X X if((proc->p_flag & (SSWAP|SPARTOUT)) || ! (proc->p_flag & SLOAD)) X { X swapaddr = proc->p_addr[0].te_frameno * NBPC; X lseek(swapfd,swapaddr,0); X read(swapfd,user,sizeof *user); X } else X { X lseek(memfd,proc->p_addr[0].te_frameno * NBPC,0); X read(memfd,user,sizeof *user); X } X if((user->u_procp - first_proc) == proc->p_dummy0) X return(1); X else X return(0); X 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 -1 X#define HASHIT(i) ((i) % UID_NAME_HASH_SIZE) X Xstruct uid_name_hash_entry { X int 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 int uid; Xregister char *name; X{ Xregister int table_uid; Xregister int hashval; X X if(++uid_count >= UID_NAME_HASH_SIZE) X error_term("too many user names"); 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 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 int 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 sprintf(errant,"%d",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 int uid; X{ Xregister int uid_hash; Xregister int table_uid; Xregister char *name; 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 char *uid_to_name */ X X/*+----------------------------------------------------------------------- X char *get_cpu_time_str(timeval) X 6-char static string address is returned X------------------------------------------------------------------------*/ Xchar *get_cpu_time_str(timeval) Xlong timeval; X{ Xstatic char timestr[10]; Xlong mm,ss; X X/* timeval /= hz; */ X timeval /= 50; X mm = timeval / 60L; X timeval -= mm * 60L; X ss = timeval; X X if(mm > 999) X sprintf(timestr,"%5ldu",mm); X else X sprintf(timestr,"%3lu:%02lu",mm,ss); X return(timestr); X} /* end of get_cpu_time_str */ X X#define AVENRUN_Y 0 X#define AVENRUN_X 0 X/*+------------------------------------------------------------------------- X display_line0() X--------------------------------------------------------------------------*/ Xvoid Xdisplay_line0() X{ Xregister int count; Xregister int itmp; Xchar s64[64]; X X w6move(AVENRUN_Y,AVENRUN_X); X X lseek(kmemfd,namelist[XL_AVENRUN].xl_value,0); X read(kmemfd,avenrun,sizeof(avenrun)); X X lseek(kmemfd,namelist[XL_MPID].xl_value,0); X read(kmemfd,&mpid,sizeof(mpid)); X X sprintf(s64,"last pid: %5d load averages:", X mpid,avenrun[0],avenrun[1],0); X w6puts(s64); X X for(count = 0; count < 3; count++) X { X itmp = avenrun[count]; X sprintf(s64," %d.%02d",itmp / 100, itmp % 100); X w6puts(s64); X } X X} /* end of display_line0 */ X X#define PROC_Y 2 X#define PROC_X 0 X#define UID_X 2 X#define PID_X 12 X#define PPID_X 18 X#define PGRP_X 24 X#define CPU_X 30 X#define TIM_X 34 X#define PRI_X 38 X#define NICE_X 42 X#define WSIZE_X 45 X#define TSIZE_X 50 X#define SSIZE_X 55 X#define UTIME_X 60 X#define STIME_X 67 X#define TTY_X 74 X#define CMD_X 78 X X/*+------------------------------------------------------------------------- X display_proc(iproc,initial) X00000000001111111111222222222233333333334444444444555555555566666666667777777777 X01234567890123456789012345678901234567890123456789012345678901234567890123456789 XS USER PID PPID PGRP CPU TIM PRI NI WSIZ TSIZ SSIZ UCPU SCPU TTY CM X# ########X ##### ##### ##### ### ### ### ## #### #### #### ###### ###### ### ## X--------------------------------------------------------------------------*/ Xvoid Xdisplay_proc(iproc,initial) Xregister int iproc; Xregister int initial; X{ Xregister int positioned = 0; Xregister int itmp; Xregister int got_user; Xstruct proc *tproc = procs + iproc; Xstruct proc *oproc = oldprocs + iproc; Xstatic char *p_stat_str = " S?RIZTXXX"; Xchar buf[20]; X X if((itmp = (tproc->p_stat == SRUN)) || X ((tproc->p_stat != SRUN) && (oproc->p_stat == SRUN))) X { X initial = 1; X if(itmp && (tproc->p_pid != w6ps_pid)) X { X w6reverse(1); X w6dim(1); X } X } X X if(initial || (tproc->p_stat != oproc->p_stat)) X { X w6move(PROC_Y + 2 + iproc,PROC_X); X w6putc(p_stat_str[tproc->p_stat]); X w6putc(' '); X positioned = 1; X } X X if(initial || (tproc->p_uid != oproc->p_uid)) X { X if(!positioned) X w6move(PROC_Y + 2 + iproc,PROC_X + UID_X); X sprintf(buf,"%8s",uid_to_name(tproc->p_uid)); X w6puts(buf); X w6putc((tproc->p_uid != tproc->p_suid) ? '#' : ' '); X w6putc(' '); X positioned = 1; X } X else X positioned = 0; X X if(initial || (tproc->p_pid != oproc->p_pid)) X { X if(!positioned) X w6move(PROC_Y + 2 + iproc,PROC_X + PID_X); X sprintf(buf,"%5d ",tproc->p_pid); X w6puts(buf); X positioned = 1; X } X else X positioned = 0; X X if(initial || (tproc->p_ppid != oproc->p_ppid)) X { X if(!positioned) X w6move(PROC_Y + 2 + iproc,PROC_X + PPID_X); X sprintf(buf,"%5d ",tproc->p_ppid); X w6puts(buf); X positioned = 1; X } X else X positioned = 0; X X if(initial || (tproc->p_pgrp != oproc->p_pgrp)) X { X if(!positioned) X w6move(PROC_Y + 2 + iproc,PROC_X + PGRP_X); X sprintf(buf,"%5d ",tproc->p_pgrp); X w6puts(buf); X positioned = 1; X } X else X positioned = 0; X X if(initial || (tproc->p_cpu != oproc->p_cpu)) X { X if(!positioned) X w6move(PROC_Y + 2 + iproc,PROC_X + CPU_X); X sprintf(buf,"%3u ",tproc->p_cpu); X w6puts(buf); X positioned = 1; X } X else X positioned = 0; X X if(initial || (tproc->p_time != oproc->p_time)) X { X if(!positioned) X w6move(PROC_Y + 2 + iproc,PROC_X + TIM_X); X sprintf(buf,"%3u ",tproc->p_time); X w6puts(buf); X positioned = 1; X } X else X positioned = 0; X X if(initial || (tproc->p_pri != oproc->p_pri)) X { X if(!positioned) X w6move(PROC_Y + 2 + iproc,PROC_X + PRI_X); X sprintf(buf,"%3u ",tproc->p_pri); X w6puts(buf); X positioned = 1; X } X else X positioned = 0; X X if(initial || (tproc->p_nice != oproc->p_nice)) X { X if(!positioned) X w6move(PROC_Y + 2 + iproc,PROC_X + NICE_X); X sprintf(buf,"%2d ",tproc->p_nice); X w6puts(buf); X positioned = 1; X } X else X positioned = 0; X X if(initial || (tproc->p_wsize != oproc->p_wsize)) X { X if(!positioned) X w6move(PROC_Y + 2 + iproc,PROC_X + WSIZE_X); X sprintf(buf,"%4d ",tproc->p_wsize); X w6puts(buf); X positioned = 1; X } X else X positioned = 0; X X if(initial || (tproc->p_tsize != oproc->p_tsize)) X { X if(!positioned) X w6move(PROC_Y + 2 + iproc,PROC_X + TSIZE_X); X sprintf(buf,"%4d ",tproc->p_tsize); X w6puts(buf); X positioned = 1; X } X else X positioned = 0; X X if(initial || (tproc->p_ssize != oproc->p_ssize)) X { X if(!positioned) X w6move(PROC_Y + 2 + iproc,PROC_X + SSIZE_X); X sprintf(buf,"%4d ",tproc->p_ssize); X w6puts(buf); X positioned = 1; X } X else X positioned = 0; X X/* since not saving user area, always update fields from it */ X if(!positioned) X w6move(PROC_Y + 2 + iproc,PROC_X + UTIME_X); X if(got_user = get_user(tproc,iproc,&user)) X { X w6puts(get_cpu_time_str(user.u_utime)); X w6putc(' '); X w6puts(get_cpu_time_str(user.u_stime)); X w6putc(' '); X } X else X w6puts("------ ------ "); X positioned = 1; X X if(!positioned) X w6move(PROC_Y + 2 + iproc,PROC_X + TTY_X); X sprintf(buf,"%3.3s ",pgrp_to_ttyname(tproc->p_pgrp)); X w6puts(buf); X positioned = 1; X X if(!positioned) X w6move(PROC_Y + 2 + iproc,PROC_X + CMD_X); X if(got_user) X { X register char *cptr = user.u_psargs; X while(*cptr) X { X *cptr &= 0x7F; X if(*cptr < 0x20) X *cptr = 0x20; X cptr++; X } X w6puts(user.u_psargs); X } X else X { X switch(tproc->p_stat) X { X case SIDL: X w6puts("------ in creation ------"); X break; X case SZOMB: X w6puts("----- in termination -----"); X break; X case SXBRK: X case SXSTK: X case SXTXT: X w6puts("-------- swapping --------"); X default: X w6puts("???"); X } X } X X w6clrtoeol(); X w6norm(); X X} /* end of display_proc */ X X/*+------------------------------------------------------------------------- X display_procs(initial) X--------------------------------------------------------------------------*/ Xvoid Xdisplay_procs(initial) Xint initial; X{ Xregister int iproc; X for(iproc = 0; iproc < nprocs; iproc++) X display_proc(iproc,(iproc >= noldprocs) ? 1 : initial); X w6clrtobot(); X} /* end of display_procs */ X X/*+------------------------------------------------------------------------- X proc_pid_compare(p1,p2) X--------------------------------------------------------------------------*/ Xproc_pid_compare(p1,p2) Xstruct proc *p1; Xstruct proc *p2; X{ X return(p1->p_pid - p2->p_pid); X} /* end of proc_pid_compare */ X X/*+------------------------------------------------------------------------- X get_procs() X--------------------------------------------------------------------------*/ Xvoid Xget_procs() X{ Xregister int iproc; Xregister int proc_size = v.v_proc * sizeof(struct proc); Xstruct proc *tproc; X X/* save old proc structure */ X memcpy((char *)oldprocs,(char *)procs,proc_size); X noldprocs = nprocs; X X/* read current procs - steal iproc register int temporarily */ X lseek(kmemfd,namelist[XL_PROC].xl_value,0); X if((iproc = read(kmemfd,procs,proc_size)) != proc_size) X perror_term("get_procs: cannot read kmem",iproc); 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 = procs + iproc; X tproc->p_dummy0 = iproc; /* save slot number */ X if((tproc->p_stat == 0) || (tproc->p_pgrp == tproc->p_pid) || X (tproc->p_pgrp == 0)) X tproc->p_pid = 32767; X else X nprocs++; X } X X/* sort new procs array */ X qsort((char *)procs,v.v_proc,sizeof(struct proc),proc_pid_compare); X X} /* end of get_procs */ X X/*+------------------------------------------------------------------------- X main(argc,argv,envp) X--------------------------------------------------------------------------*/ Xmain(argc,argv,envp) Xint argc; Xchar **argv; Xchar **envp; X{ Xregister int itmp; Xchar s80[80]; Xextern char *w6tty_default; X X setbuf(stdout,NULL); X setbuf(stderr,NULL); X X w6ps_pid = getpid(); X X if(itmp = w6open(w6tty_default)) X { X printf("w6open error %d\n",itmp); X exit(1); X } X X w6ctrl(W6SCROFF); X w6clr(); X w6topline(""); X w6ctrl(W6SCRON); X w6ctrl(W6CUROFF); X w6eolwrap(1); X w6_132cols(); X w6_43lines(); X X if(access("/xenix",4)) X { X fprintf(stderr,"must have read access to /xenix\n"); X exit(1); X } X if(xlist("/xenix",namelist) != 0) X { X perror("w6ps: namelist"); X exit(1); X } X X if(access("/dev/mem",4) || access("/dev/kmem",4) || X access("/dev/swap",4)) X { X fprintf(stderr,"w6ps: must be owned by root or sysinfo + setuid\n"); X exit(1); X } X X if((memfd = open("/dev/mem",O_RDONLY)) < 0) X { X perror("w6ps: /dev/mem"); X exit(1); X } X if((kmemfd = open("/dev/kmem",O_RDONLY)) < 0) X { X perror("w6ps: /dev/kmem"); X exit(1); X } X if((swapfd = open("/dev/swap",O_RDONLY)) < 0) X { X perror("w6ps: /dev/swap"); X exit(1); X } X X lseek(kmemfd,namelist[XL_V].xl_value,0); X read(kmemfd,&v,sizeof v); X X lseek(kmemfd,namelist[XL_SWPLO].xl_value,0); X read(kmemfd,&swplo,sizeof swplo); X X lseek(kmemfd,namelist[XL_UTSNAME].xl_value,0); X read(kmemfd,&utsname,sizeof utsname); X X lseek(kmemfd,namelist[XL_HZ].xl_value,0); X read(kmemfd,&hz,sizeof hz); X X sprintf(s80,"%s - %s %s %s",utsname.nodename, X utsname.sysname,utsname.version,utsname.release); X w6topline(s80); X X if(!(procs = (struct proc *)calloc(1,v.v_proc * sizeof(struct proc)))) X { X fprintf(stderr,"no memory\n"); X exit(1); X } X X if(!(oldprocs = (struct proc *)malloc(v.v_proc * sizeof(struct proc)))) X { X fprintf(stderr,"no memory\n"); X exit(1); X } X noldprocs = nprocs = 0; X X init_uid_name_hash(); X X w6move(PROC_Y,PROC_X); X w6puts("S USER PID PPID PGRP CPU TIM PRI NI WSIZ TSIZ SSIZ UCPU SCPU TTY CMD"); X w6move(PROC_Y + 1,PROC_X); X w6puts("- --------- ----- ----- ----- --- --- --- -- ---- ---- ---- ------ ------ --- --"); X get_procs(); X display_line0(); X display_procs(1); X X while(1) X { X sleep(2); X get_procs(); X display_line0(); X display_procs(0); X } X X exit(0); X} /* end of main */ X X SHAR_EOF chmod 0644 w6ps.c || echo "restore of w6ps.c fails" fi exit 0 -- ------------------------------------------------------------------- Warren Tucker, Tridom Corporation ...!gatech!emory!tridom!wht Ker-au'-lo-phon. An 8-foot partial flue-stop, having metal pipes surmounted by adjustable rings, and with a hole bored near the top of each pipe, producing a soft and "reedy" tone.