BBN-V6/progs/ss.c

Compare this file to the similar file:
Show the results in this format:

#include "../h/param.h"
#include "../h/proc.h"
#include "../h/user.h"
#include "../h/tty.h"

char *ss_nlist "/tmp/ss.nlist";
char *ss_names "/tmp/ss.names";
char *ss_devices "/tmp/ss.devices";
char *mem "/dev/mem";
char core;
char pcore;
char swap;

int	ndev;
char	devc[65];
int	devl[65];
char	swapfile[16];
struct ibuf {
	char	idevmin, idevmaj;
	int	inum;
	int	iflags;
	char	inl;
	char	iuid;
	char	igid;
	char	isize0;
	int	isize;
	int	iaddr[8];
	char	*ictime[2];
	char	*imtime[2];
	int	fill;
};

char cmndbuf[4096];
char *cbfree &cmndbuf[0];

#define NSYMB 22

struct NL {
	char name[8];
	int type;
	char *value;
} nl[NSYMB + 1];

char *symbol[NSYMB] {
	"_proc",
	"_dc11",
	"_kl11",
	"_dh11",
	"_pty",
	"_buf",
	"_buffers",
	"_bfreeli",
	"_fp",
	"_rkaddr",
	"_rrkbuf",
	"_runin",
	"_runout",
	"_lbolt",
	"_time",
	"_tout",
	"_callout",
	"_imp",
	"_ncprq",
	"_ncpirq",
	"_inode",
	"_swapdev"
};

char *names[256];
char namebuf[1024];
char *nbfree &namebuf[0];

struct INFO {
	struct  proc p;
	char    ttynam;
	int     cptime;
	char    *cmnd;
	char    uid, ruid;
} info[NPROC], *lastinfo;

main(argc, argv) int argc; char *argv[]; {
	register struct INFO *ip;
	register int j;
	extern icomp();


	if ( (core=open(mem,0)) < 0 || (pcore=open(mem,0)) < 0 ) {
		printf("cannot open %s\n",mem);
		exit(1);
	}

	getnl();
	getnames();

	/* --- horrendous BTL code --- */

	seek(core, nl[NSYMB-1].value, 0);
	read(core, &nl[NSYMB-1].value, 2);
	if(chdir("/dev") < 0) { printf("cannot chdir to /dev\n"); exit(1); }
	getdev();

	printf("tty owner     pid status     size cptime command\n");
	printf("-   -----     --- ------     ---- ------ -------\n");

	seek(pcore, nl[0].value, 0);
	ip = &info[0];
	for(j = 0; j < NPROC; j++) {
		read(pcore, &ip->p, sizeof ip->p);
		if(ip->p.p_stat == 0) continue;
		getusr(&ip->p, ip);
		ip++;
	}
	lastinfo = ip - 1;

	qsort(info, lastinfo - info + 1, sizeof info[0], icomp);
	output(argc, argv);

}

icomp(ii1, ii2) {
	struct INFO *i1, *i2;

	i1= ii1;  i2 = ii2;
	if (i1->ttynam != i2->ttynam)
		return(i2->ttynam - i1->ttynam);
	if(i1->p.p_pgrp != i2->p.p_pgrp)
		return(i1->p.p_pgrp - i2->p.p_pgrp);
	return(i1->p.p_pid - i2->p.p_pid);
}

getnl() {
	int file;
	register int j;
	register char *dp, *sp;

	file = open(ss_nlist, 0);
	if(file >= 0)
		read(file, nl, sizeof nl);
	else {
		for(j = 0; j < NSYMB; j++) {
			sp = symbol[j];
			dp = nl[j].name;
			while(*dp++ = *sp++);
		}
		nlist("/unix", nl);
		file = creat(ss_nlist, 0444);
		write(file, nl, sizeof nl);
	}
	close( file );
}

getusr(pp, ip) struct proc *pp; struct INFO *ip; {
	int baddr, laddr, mf;
	int baddr2, laddr2;
	register int *i;
	register char *cp, *cp1;
	int c;
	static int stbuf[257];
	int j;
	struct { long lv; };
	long ltime;

	baddr2 = baddr = laddr2 = laddr = 0;
	if(pp->p_flag & SLOAD) {
		laddr2 = laddr = pp->p_addr;
		mf = core;
	} else {
		baddr2 = baddr = pp->p_addr;
		mf = swap;
	}
	laddr =+ pp->p_size - 8;
	baddr =+ laddr >> 3;
	baddr2 =+ laddr2 >> 3;
	laddr = (laddr & 07) << 6;
	laddr2 = (laddr2 & 07) << 6;

	seek(mf, baddr2, 3);
	seek(mf, laddr2, 1);
	read(mf, &u, sizeof u);
	ip->uid = u.u_uid;
	ip->ruid = u.u_ruid;
	ltime = (u.u_utime)->lv + (u.u_stime)->lv + 30;
	ip->cptime = ldiv(ltime, 60);
	/* --- BTL code to get tty name --- */
	ip->ttynam = '!';
	if(u.u_ttyp) for(j = 0; j < ndev; j++) if(devl[j] == u.u_ttyd) {
		ip->ttynam = devc[j];
		break;
	}

	seek(mf, baddr, 3);
	seek(mf, laddr, 1);
	read(mf, stbuf, 512);
	for(i = &stbuf[256]; i > &stbuf[0];) {
		if(*--i == -1) {
			cp = i + 1;
			if(*cp == 0) cp++;
			for(cp1 = cp; cp1 < &stbuf[256]; cp1++) {
				c = *cp1;
				if(c == 0) *cp1 = ' ';
				else if(c < ' ' || c > 0176) *cp1 = 0;
			}
			cp1 = cbfree;
			while(*cp1++ = *cp++);
			ip->cmnd = cbfree;
			cbfree = cp1;
			return;
		}
	}
	ip->cmnd = cbfree;
	*cbfree++ = '?'; *cbfree++ = 0;
	return;
}

output(argc, argv) int argc; char *argv[]; {
	register int i;
	register int j;
	register struct INFO *ip;

	if(argc == 1) {
		for(ip = lastinfo; ip >= &info[0]; ip--)
		if /***(ip->ruid) && ***/
		 (ip->p.p_pgrp == ip->p.p_pid ||
		  (ip->p.p_ppid == 1 && ip->p.p_pgrp != 0)
		      ) out1(ip, 0);
	} else 
		for(i = 1; i < argc; i++)
		{	j = 0;
			for(ip = &info[0]; ip <= lastinfo; ip++)
			if((ip->p.p_pgrp == ip->p.p_pid)
				&& seq(argv[i], names[ip->ruid])) 
			{	out1(ip, 0);
				j++;
			}
			if(j == 0) printf("%s not logged in\n", argv[i]);
		}
}

out1(p, level) struct INFO *p; {
	register struct INFO *rp, *ip;
	int j;
	ip = p;

	out2(ip, level);
	for(rp = &info[0]; rp <= lastinfo; rp++)
	if(rp->p.p_pid /* kludge for process 0 */
	&& rp->p.p_ppid == ip->p.p_pid /* direct descendant */
	&& rp->p.p_pgrp == ip->p.p_pgrp /* same session */
	) out1(rp, level+1);

/***    if(level == 0)
	for(rp = &info[0]; rp <= lastinfo; rp++)
	if(rp->p.p_ppid == 1
	&& rp->p.p_pgrp == ip->p.p_pgrp
	&& rp->p.p_pid != ip->p.p_pid
	) out2(rp, 0);                          ***/
}

out2(ip, level) struct INFO *ip; int level; {
	int j;
	static lasttty;

	if(lasttty != ip->ttynam) {
		lasttty = ip->ttynam;
		printf("%c ", lasttty);
	} else printf("  ");
	if(level == 0) {
		printf("- ");
		puid(ip->p.p_uid);
	} else {
		printf("-");
		j = level;
		while(j--) putchar('>');
		j = level;
		while(j++ <= 8) putchar(' ');
	}
	printf("%5d ", ip->p.p_pid);
	pstatus(&ip->p);
	printf("%2dk ", ip->p.p_size >> 5);
	printf("%3d:", ip->cptime/60);
	ip->cptime =% 60;
	printf(ip->cptime < 10 ? "0%d " : "%d ", ip->cptime);
	printf("%-.30s ", ip->cmnd);
	printf("\n");
}

gwchan(wchan) char *wchan; {
	register struct NL *trial, *guess;

	trial = 0;
	for(guess = &nl[0]; guess <= &nl[NSYMB]; guess++)
	if(guess->value > trial->value && guess->value <= wchan)
		trial = guess;
	return(trial);
}

getnames() {
	int file;
	register char *sp, *dp;
	int j, c;

	file = open(ss_names, 0);
	if(file >= 0) {
		read(file, names, sizeof names);
		read(file, namebuf, sizeof namebuf);
	} else {
		close(0);
		open("/etc/passwd", 0);
		for(;;) {
			dp = nbfree;
			c = getchar(); if(c < 'a' || c > 'z') break;
			while(c != ':') {
				*dp++ = c;
				c = getchar();
			}
			*dp++ = 0;
			while(getchar() != ':');
			j = 0;
			while((c = getchar()) >= '0' && c <= '9')
				j = j * 10 + c - '0';
			if (names[j] == 0)
			{       names[j] = nbfree;
				nbfree = dp;
			}
			while(getchar() != '\n');
		}
		names[0] = --dp;        /* don't print user-id 0 name */
		file = creat(ss_names, 0444);
		write(file, names, sizeof names);
		write(file, namebuf, sizeof namebuf);
	}
	close(file);
}

seq(s1, s2) char *s1, *s2; {
	while(*s1) if(*s1++ != *s2++) return(0);
	return(1);
}

puid(uid) char uid; {
	if(names[uid & 0377])
		printf("%-8.8s", names[uid & 0377]);
	else
		printf("%-8d", uid & 0377);
}
pstatus(pp) struct proc *pp; {
	register struct NL *nlp;
	register char *mess;
	register i;

	switch(pp->p_stat) {
	case SSLEEP: mess = pp->p_pri > 0 ? "slp" : "SLP"; break;
	case SRUN:   mess = "run"; break;
	case SIDL:   mess = "idl"; break;
	case SZOMB:  mess = "zmb"; break;
	case SSTOP:  mess = "stp"; break;
	}
	printf("%s%c",mess,(pp->p_flag & SLOAD) ? '*' : ' ');
	mess = " ";
	if(pp->p_stat == SSLEEP) {
		nlp = gwchan(pp->p_wchan);
		switch(nlp - &nl[0]) {
		case 0:
			mess = "fork";
			break;
		case 1: case 2: case 3: case 4:
			mess = "tty";
			break;
		case 5: case 6: case 7:
			mess = "I/O";
			break;
		case 8:
			mess = "file";
			break;
		case 9: case 10:
			mess = "disk";
			break;
		case 11:
			mess = "runin";
			break;
		case 12:
			mess = "runout";
			break;
		case 13: case 14: case 15: case 16:
			mess = "clock";
			break;
		case 17: case 18: case 19: case 20:
			mess = "net";
			break;
		default:
			mess = "?";
		}
	}
	printf("%-7.7s ", mess);
}

/* --- from ps.c for V6 to get teletype names --- */


getdev()
{
	register struct { int dir_ino; char dir_n[14]; } *p;
	register i, c;
	int f;
	int k;
	char dbuf[512];
	int sbuf[20];

	/* see if we have a file containing all the neat information */
	f = open(ss_devices, 0);
	if (f >= 0)
	{	read(f, devc, sizeof devc);
		read(f, devl, sizeof devl);
		read(f, swapfile, sizeof swapfile);
		close( f );
		goto swapopen;
	}
	f = open("/dev", 0);
	if(f < 0) {
		printf("cannot open /dev\n");
		exit(0);
	}
	c = 0;

loop:
	i = read(f, dbuf, 512);
	if(i <= 0) {
		close(f);
		f = creat(ss_devices, 0444);
		write(f, devc, sizeof devc);
		write(f, devl, sizeof devl);
		write(f, swapfile, sizeof swapfile);
		close(f);
		goto swapopen;
	}
	while(i < 512)
		dbuf[i++] = 0;
	for(p = dbuf; p < dbuf+512; p++) {
		if(p->dir_ino == 0)
			continue;
		if(p->dir_n[0] == 't' &&
		   p->dir_n[1] == 't' &&
		   p->dir_n[2] == 'y' &&
		   p->dir_n[4] == 0 &&
		   p->dir_n[3] != 0) {
			if(stat(p->dir_n, sbuf) < 0)
				continue;
			devc[c] = p->dir_n[3];
			devl[c] = sbuf->iaddr[0];
			c++;
			continue;
		}
		if(swapfile[0]) continue;
		if(stat(p->dir_n, sbuf) < 0)
			continue;
		if((sbuf->iflags & 060000) != 060000)
			continue;
		if(sbuf->iaddr[0] == nl[NSYMB-1].value) {
			for(k = 0; k < 14; k++)
				swapfile[k] = p->dir_n[k];
		}
	}
	goto loop;
swapopen:
	swapfile[14] = '\000';
	swap = open(swapfile, 0);
	if (swap < 0)
	{	printf("Cannot open swap device %o\n", nl[NSYMB-1].value);
		exit(1);
	}
	c = 0;
	while( devc[c] ) c++;
	ndev = c;
	return;
}