henesyinit from p9f0ed2a895 years agoHistory
1210 lines · 24.0 KB · C
RawDownload
#include <u.h>#include <libc.h>#include <ctype.h>#include <auth.h>#include <fcall.h>#include <draw.h>#include <event.h> #define	MAXNUM	8	/* maximum number of numbers on data line */ typedef struct Graph		Graph;typedef struct Machine	Machine; struct Graph{	int		colindex;	Rectangle	r;	int		*data;	int		ndata;	char		*label;	void		(*newvalue)(Machine*, long*, long*, int);	void		(*update)(Graph*, long, long);	Machine	*mach;	int		overflow;	Image	*overtmp;}; enum{	/* /dev/swap */	Mem		= 0,	Maxmem,	Swap,	Maxswap,	/* /dev/sysstats */	Procno	= 0,	Context,	Interrupt,	Syscall,	Fault,	TLBfault,	TLBpurge,	Load,	/* /net/ether0/0/stats */	In		= 0,	Out,	Err0,	/* /mnt/apm/battery */	Battery,}; struct Machine{	char		*name;	int		remote;	int		statsfd;	int		swapfd;	int		etherfd;	int		batteryfd;	int		disable; 	long		devswap[4];	long		devsysstat[8];	long		prevsysstat[8];	int		nproc;	long		netetherstats[8];	long		prevetherstats[8];	long		batterystats[2]; 	char		buf[1024];	char		*bufp;	char		*ebufp;}; enum{	Mainproc,	Mouseproc,	NPROC,}; enum{	Ncolor	= 6,	Ysqueeze	= 2,	/* vertical squeezing of label text */	Labspace	= 2,	/* room around label */	Dot		= 2,	/* height of dot */	Opwid	= 5,	/* strlen("add  ") or strlen("drop ") */	Nlab		= 3,	/* max number of labels on y axis */	Lablen	= 16,	/* max length of label */	Lx		= 4,	/* label tick length */}; enum Menu2{	Mcontext,	Mether,	Methererr,	Metherin,	Metherout,	Mfault,	Mintr,	Mload,	Mmem,	Mswap,	Msyscall,	Mtlbmiss,	Mtlbpurge,	Mbattery,	Nmenu2,}; char	*menu2str[Nmenu2+1] = {	"add  context ",	"add  ether   ",	"add  ethererr",	"add  etherin ",	"add  etherout",	"add  fault   ",	"add  intr    ",	"add  load    ",	"add  mem     ",	"add  swap    ",	"add  syscall ",	"add  tlbmiss ",	"add  tlbpurge",	"add  battery ",	nil,};  void	contextval(Machine*, long*, long*, int),	etherval(Machine*, long*, long*, int),	ethererrval(Machine*, long*, long*, int),	etherinval(Machine*, long*, long*, int),	etheroutval(Machine*, long*, long*, int),	faultval(Machine*, long*, long*, int),	intrval(Machine*, long*, long*, int),	loadval(Machine*, long*, long*, int),	memval(Machine*, long*, long*, int),	swapval(Machine*, long*, long*, int),	syscallval(Machine*, long*, long*, int),	tlbmissval(Machine*, long*, long*, int),	tlbpurgeval(Machine*, long*, long*, int),	batteryval(Machine*, long*, long*, int); Menu	menu2 = {menu2str, nil};int		present[Nmenu2];void		(*newvaluefn[Nmenu2])(Machine*, long*, long*, int init) = {	contextval,	etherval,	ethererrval,	etherinval,	etheroutval,	faultval,	intrval,	loadval,	memval,	swapval,	syscallval,	tlbmissval,	tlbpurgeval,	batteryval,}; Image	*cols[Ncolor][3];Graph	*graph;Machine	*mach;Font		*mediumfont;char		*mysysname;char		argchars[] = "bceEfimlnpstw";int		pids[NPROC];int 		parity;	/* toggled to avoid patterns in textured background */int		nmach;int		ngraph;	/* totaly number is ngraph*nmach */double	scale = 1.0;int		logscale = 0;int		ylabels = 0; char		*procnames[NPROC] = {"main", "mouse"}; voidkillall(char *s){	int i, pid; 	pid = getpid();	for(i=0; i<NPROC; i++)		if(pids[i] && pids[i]!=pid)			postnote(PNPROC, pids[i], "kill");	exits(s);} void*emalloc(ulong sz){	void *v;	v = malloc(sz);	if(v == nil) {		fprint(2, "stats: out of memory allocating %ld: %r\n", sz);		killall("mem");	}	memset(v, 0, sz);	return v;} void*erealloc(void *v, ulong sz){	v = realloc(v, sz);	if(v == nil) {		fprint(2, "stats: out of memory reallocating %ld: %r\n", sz);		killall("mem");	}	return v;} char*estrdup(char *s){	char *t;	if((t = strdup(s)) == nil) {		fprint(2, "stats: out of memory in strdup(%.10s): %r\n", s);		killall("mem");	}	return t;} voidmkcol(int i, int c0, int c1, int c2){	cols[i][0] = allocimagemix(display, c0, DWhite);	cols[i][1] = allocimage(display, Rect(0,0,1,1), CMAP8, 1, c1);	cols[i][2] = allocimage(display, Rect(0,0,1,1), CMAP8, 1, c2);} voidcolinit(void){	mediumfont = openfont(display, "/lib/font/bit/pelm/latin1.8.font");	if(mediumfont == nil)		mediumfont = font; 	/* Peach */	mkcol(0, 0xFFAAAAFF, 0xFFAAAAFF, 0xBB5D5DFF);	/* Aqua */	mkcol(1, DPalebluegreen, DPalegreygreen, DPurpleblue);	/* Yellow */	mkcol(2, DPaleyellow, DDarkyellow, DYellowgreen);	/* Green */	mkcol(3, DPalegreen, DMedgreen, DDarkgreen);	/* Blue */	mkcol(4, 0x00AAFFFF, 0x00AAFFFF, 0x0088CCFF);	/* Grey */	cols[5][0] = allocimage(display, Rect(0,0,1,1), CMAP8, 1, 0xEEEEEEFF);	cols[5][1] = allocimage(display, Rect(0,0,1,1), CMAP8, 1, 0xCCCCCCFF);	cols[5][2] = allocimage(display, Rect(0,0,1,1), CMAP8, 1, 0x888888FF);} intloadbuf(Machine *m, int *fd){	int n;  	if(*fd < 0)		return 0;	seek(*fd, 0, 0);	n = read(*fd, m->buf, sizeof m->buf);	if(n <= 0){		close(*fd);		*fd = -1;		return 0;	}	m->bufp = m->buf;	m->ebufp = m->buf+n;	return 1;} voidlabel(Point p, int dy, char *text){	char *s;	Rune r[2];	int w, maxw, maxy; 	p.x += Labspace;	maxy = p.y+dy;	maxw = 0;	r[1] = '\0';	for(s=text; *s; ){		if(p.y+mediumfont->height-Ysqueeze > maxy)			break;		w = chartorune(r, s);		s += w;		w = runestringwidth(mediumfont, r);		if(w > maxw)			maxw = w;		runestring(screen, p, display->black, ZP, mediumfont, r);		p.y += mediumfont->height-Ysqueeze;	}} Pointparitypt(int x){	return Pt(x+parity, 0);} Pointdatapoint(Graph *g, int x, long v, long vmax){	Point p;	double y; 	p.x = x;	y = ((double)v)/(vmax*scale);	if(logscale){		/*		 * Arrange scale to cover a factor of 1000.		 * vmax corresponds to the 100 mark.		 * 10*vmax is the top of the scale.		 */		if(y <= 0.)			y = 0;		else{			y = log10(y);			/* 1 now corresponds to the top; -2 to the bottom; rescale */			y = (y+2.)/3.;		}	}	p.y = g->r.max.y - Dy(g->r)*y - Dot;	if(p.y < g->r.min.y)		p.y = g->r.min.y;	if(p.y > g->r.max.y-Dot)		p.y = g->r.max.y-Dot;	return p;} voiddrawdatum(Graph *g, int x, long prev, long v, long vmax){	int c;	Point p, q; 	c = g->colindex;	p = datapoint(g, x, v, vmax);	q = datapoint(g, x, prev, vmax);	if(p.y < q.y){		draw(screen, Rect(p.x, g->r.min.y, p.x+1, p.y), cols[c][0], nil, paritypt(p.x));		draw(screen, Rect(p.x, p.y, p.x+1, q.y+Dot), cols[c][2], nil, ZP);		draw(screen, Rect(p.x, q.y+Dot, p.x+1, g->r.max.y), cols[c][1], nil, ZP);	}else{		draw(screen, Rect(p.x, g->r.min.y, p.x+1, q.y), cols[c][0], nil, paritypt(p.x));		draw(screen, Rect(p.x, q.y, p.x+1, p.y+Dot), cols[c][2], nil, ZP);		draw(screen, Rect(p.x, p.y+Dot, p.x+1, g->r.max.y), cols[c][1], nil, ZP);	} } voidredraw(Graph *g, int vmax){	int i, c; 	c = g->colindex;	draw(screen, g->r, cols[c][0], nil, paritypt(g->r.min.x));	for(i=1; i<Dx(g->r); i++)		drawdatum(g, g->r.max.x-i, g->data[i-1], g->data[i], vmax);	drawdatum(g, g->r.min.x, g->data[i], g->data[i], vmax);	g->overflow = 0;} voidupdate1(Graph *g, long v, long vmax){	char buf[32];	int overflow; 	if(g->overflow && g->overtmp!=nil)		draw(screen, g->overtmp->r, g->overtmp, nil, g->overtmp->r.min);	draw(screen, g->r, screen, nil, Pt(g->r.min.x+1, g->r.min.y));	drawdatum(g, g->r.max.x-1, g->data[0], v, vmax);	memmove(g->data+1, g->data, (g->ndata-1)*sizeof(g->data[0]));	g->data[0] = v;	g->overflow = 0;	if(logscale)		overflow = (v>10*vmax*scale);	else		overflow = (v>vmax*scale);	if(overflow && g->overtmp!=nil){		g->overflow = 1;		draw(g->overtmp, g->overtmp->r, screen, nil, g->overtmp->r.min);		sprint(buf, "%ld", v);		string(screen, g->overtmp->r.min, display->black, ZP, mediumfont, buf);	}} /* read one line of text from buffer and process integers */intreadnums(Machine *m, int n, long *a, int spanlines){	int i;	char *p, *ep; 	if(spanlines)		ep = m->ebufp;	else		for(ep=m->bufp; ep<m->ebufp; ep++)			if(*ep == '\n')				break;	p = m->bufp;	for(i=0; i<n && p<ep; i++){		while(p<ep && !isdigit(*p))			p++;		if(p == ep)			break;		a[i] = strtol(p, &p, 10);	}	if(ep < m->ebufp)		ep++;	m->bufp = ep;	return i == n;} /* Network on fd1, mount driver on fd0 */static intfilter(int fd){	int p[2]; 	if(pipe(p) < 0){		fprint(2, "stats: can't pipe: %r\n");		killall("pipe");	} 	switch(rfork(RFNOWAIT|RFPROC|RFFDG)) {	case -1:		sysfatal("rfork record module");	case 0:		dup(fd, 1);		close(fd);		dup(p[0], 0);		close(p[0]);		close(p[1]);		execl("/bin/aux/fcall", "fcall", 0);		fprint(2, "stats: can't exec fcall: %r\n");		killall("fcall");	default:		close(fd);		close(p[0]);	}	return p[1];	} /* * 9fs */intconnect9fs(char *addr){	char dir[4*NAMELEN], *na;	int fd; 	fprint(2, "connect9fs...");	na = netmkaddr(addr, 0, "9fs"); 	fprint(2, "dial %s...", na);	if((fd = dial(na, 0, dir, 0)) < 0)		return -1; 	fprint(2, "dir %s...", dir);	if(strstr(dir, "tcp"))		fd = filter(fd);	return fd;} /* * exportfs */int connectexportfs(char *addr){	char buf[ERRLEN], dir[4*NAMELEN], *na;	int fd, n;	char *tree; 	tree = "/";	na = netmkaddr(addr, 0, "exportfs");	if((fd = dial(na, 0, dir, 0)) < 0)		return -1; 	if(auth(fd) < 0){		close(fd);		return -1;	} 	n = write(fd, tree, strlen(tree));	if(n < 0){		close(fd);

Lines 1–500 of 1210.