#include <u.h>
#include <libc.h>
#include <ctype.h>
#include <auth.h>
#include <fcall.h>
#include <draw.h>
#include <thread.h>
#include <mouse.h>
#include <keyboard.h>

typedef struct Graph		Graph;
typedef struct Machine	Machine;

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 */

	STACK	= 8192,
	XSTACK	= 32768,
};

enum
{
	Vbattery,
	Vcontext,
	Vcpu,
	Vether,
	Vethererr,
	Vetherin,
	Vetherout,
	Vfault,
	Vfork,
	Vidle,
	Vintr,
	Vload,
	Vmem,
	Vswap,
	Vsys,
	Vsyscall,
	Vuser,
	Nvalue,
};

char*
labels[Nvalue] = 
{
	"battery",
	"context",
	"cpu",
	"ether",
	"ethererr",
	"etherin",
	"etherout",
	"fault",
	"fork",
	"idle",
	"intr",
	"load",
	"mem",
	"swap",
	"sys",
	"syscall",
	"user",
};	

struct Graph
{
	int		colindex;
	Rectangle	r;
	int		*data;
	int		ndata;
	char		*label;
	int		value;
	void		(*update)(Graph*, long, ulong);
	Machine	*mach;
	int		overflow;
	Image	*overtmp;
	ulong	vmax;
};

struct Machine
{
	char		*name;
	int		fd;
	int		pid;
	int		dead;
	int		absolute[Nvalue];
	ulong	last[Nvalue];
	ulong	val[Nvalue][2];
	ulong	load;
	ulong	nload;
};

char	*menu2str[Nvalue+1];
char xmenu2str[Nvalue+1][40];

Menu	menu2 = {menu2str, 0};
int		present[Nvalue];
Image	*cols[Ncolor][3];
Graph	*graph;
Machine	*mach;
Font		*mediumfont;
char		*mysysname;
char		argchars[] = "bceEfiIlmnsw";
int		pids[1024];
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;
int		oldsystem = 0;
int 		sleeptime = 1000;
int		changedvmax;

Mousectl *mc;
Keyboardctl *kc;

void
killall(char *s)
{
	int i;

	for(i=0; i<nmach; i++)
		if(mach[i].pid)
			postnote(PNPROC, mach[i].pid, "kill");
	threadexitsall(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;
}

void
mkcol(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);
}

void
colinit(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);
}

void
label(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;
	}
}

Point
paritypt(int x)
{
	return Pt(x+parity, 0);
}

Point
datapoint(Graph *g, int x, ulong v, ulong 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;
}

void
drawdatum(Graph *g, int x, ulong prev, ulong v, ulong 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);
	}

}

void
redraw(Graph *g, int vmax)
{
	int i, c;

	if(vmax != g->vmax){
		g->vmax = vmax;
		changedvmax = 1;
	}
	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;
}

void
update1(Graph *g, long v, ulong vmax)
{
	char buf[32];
	int overflow;

	if(v < 0)
		v = 0;
	if(vmax != g->vmax){
		g->vmax = vmax;
		changedvmax = 1;
	}
	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);
	}
}

void
usage(void)
{
	fprint(2, "usage: stats [-O] [-S scale] [-LY] [-W winsize] [-%s] [machine...]\n", argchars);
	threadexitsall("usage");
}

void
addgraph(int n)
{
	Graph *g, *ograph;
	int i, j;
	static int nadd;

	if(n > Nvalue)
		abort();
	/* avoid two adjacent graphs of same color */
	if(ngraph>0 && graph[ngraph-1].colindex==nadd%Ncolor)
		nadd++;
	ograph = graph;
	graph = emalloc(nmach*(ngraph+1)*sizeof(Graph));
	for(i=0; i<nmach; i++)
		for(j=0; j<ngraph; j++)
			graph[i*(ngraph+1)+j] = ograph[i*ngraph+j];
	free(ograph);
	ngraph++;
	for(i=0; i<nmach; i++){
		g = &graph[i*ngraph+(ngraph-1)];
		memset(g, 0, sizeof(Graph));
		g->value = n;
		g->label = menu2str[n]+Opwid;
		g->update = update1;	/* no other update functions yet */
		g->mach = &mach[i];
		g->colindex = nadd%Ncolor;
	}
	present[n] = 1;
	nadd++;
}

void
dropgraph(int which)
{
	Graph *ograph;
	int i, j, n;

	if(which > nelem(menu2str))
		abort();
	/* convert n to index in graph table */
	n = -1;
	for(i=0; i<ngraph; i++)
		if(strcmp(menu2str[which]+Opwid, graph[i].label) == 0){
			n = i;
			break;
		}
	if(n < 0){
		fprint(2, "stats: internal error can't drop graph\n");
		killall("error");
	}
	ograph = graph;
	graph = emalloc(nmach*(ngraph-1)*sizeof(Graph));
	for(i=0; i<nmach; i++){
		for(j=0; j<n; j++)
			graph[i*(ngraph-1)+j] = ograph[i*ngraph+j];
		free(ograph[i*ngraph+j].data);
		freeimage(ograph[i*ngraph+j].overtmp);
		for(j++; j<ngraph; j++)
			graph[i*(ngraph-1)+j-1] = ograph[i*ngraph+j];
	}
	free(ograph);
	ngraph--;
	present[which] = 0;
}

int initmach(Machine*, char*);

int
addmachine(char *name)
{
	if(ngraph > 0){
		fprint(2, "stats: internal error: ngraph>0 in addmachine()\n");
		usage();
	}
	if(mach == nil)
		nmach = 0;	/* a little dance to get us started with local machine by default */
	mach = erealloc(mach, (nmach+1)*sizeof(Machine));
	memset(mach+nmach, 0, sizeof(Machine));
	if (initmach(mach+nmach, name)){
		nmach++;
		return 1;
	} else
		return 0;
}

void
newvalue(Machine *m, int i, ulong *v, ulong *vmax)
{
	ulong now;

	if(m->last[i] == 0)
		m->last[i] = m->val[i][0];
		
	if(i == Vload){
		/*
		 * Invert the ewma to obtain the 5s load statistics.
		 * Ewma is load' = (1884/2048)*load + (164/2048)*last5s, so we do
		 * last5s = (load' - (1884/2048)*load) / (164/2048).
		 */
		if(++m->nload%5 == 0){
			now = m->val[i][0];
			m->load = (now - (((vlong)m->last[i]*1884)/2048)) * 2048 / 164;
			m->last[i] = now;
		}
		*v = m->load;
		*vmax = m->val[i][1];
	}else if(m->absolute[i]){
		*v = m->val[i][0];
		*vmax = m->val[i][1];
	}else{
		now = m->val[i][0];
		*v = (vlong)((now - m->last[i])*sleeptime)/1000;
		m->last[i] = now;
		*vmax = m->val[i][1];
	}
	if(*vmax == 0)
		*vmax = 1;
}

void
labelstrs(Graph *g, char strs[Nlab][Lablen], int *np)
{
	int j;
	ulong vmax;

	vmax = g->vmax;
	if(logscale){
		for(j=1; j<=2; j++)
			sprint(strs[j-1], "%g", scale*pow(10., j)*(double)vmax/100.);
		*np = 2;
	}else{
		for(j=1; j<=3; j++)
			sprint(strs[j-1], "%g", scale*(double)j*(double)vmax/4.0);
		*np = 3;
	}
}

int
labelwidth(void)
{
	int i, j, n, w, maxw;
	char strs[Nlab][Lablen];

	maxw = 0;
	for(i=0; i<ngraph; i++){
		/* choose value for rightmost graph */
		labelstrs(&graph[ngraph*(nmach-1)+i], strs, &n);
		for(j=0; j<n; j++){
			w = stringwidth(mediumfont, strs[j]);
			if(w > maxw)
				maxw = w;
		}
	}
	return maxw;
}

void
resize(void)
{
	int i, j, k, n, startx, starty, x, y, dx, dy, ly, ondata, maxx, wid, nlab;
	Graph *g;
	Rectangle machr, r;
	ulong v, vmax;
	char buf[128], labs[Nlab][Lablen];

	draw(screen, screen->r, display->white, nil, ZP);

	/* label left edge */
	x = screen->r.min.x;
	y = screen->r.min.y + Labspace+mediumfont->height+Labspace;
	dy = (screen->r.max.y - y)/ngraph;
	dx = Labspace+stringwidth(mediumfont, "0")+Labspace;
	startx = x+dx+1;
	starty = y;
	for(i=0; i<ngraph; i++,y+=dy){
		draw(screen, Rect(x, y-1, screen->r.max.x, y), display->black, nil, ZP);
		draw(screen, Rect(x, y, x+dx, screen->r.max.y), cols[graph[i].colindex][0], nil, paritypt(x));
		label(Pt(x, y), dy, graph[i].label);
		draw(screen, Rect(x+dx, y, x+dx+1, screen->r.max.y), cols[graph[i].colindex][2], nil, ZP);
	}

	/* label top edge */
	dx = (screen->r.max.x - startx)/nmach;
	for(x=startx, i=0; i<nmach; i++,x+=dx){
		draw(screen, Rect(x-1, starty-1, x, screen->r.max.y), display->black, nil, ZP);
		j = dx/stringwidth(mediumfont, "0");
	//	n = mach[i].nproc;
		n = 1;
		if(n>1 && j>=1+3+(n>10)+(n>100)){	/* first char of name + (n) */
			j -= 3+(n>10)+(n>100);
			if(j <= 0)
				j = 1;
			snprint(buf, sizeof buf, "%.*s(%d)", j, mach[i].name, n);
		}else
			snprint(buf, sizeof buf, "%.*s", j, mach[i].name);
		string(screen, Pt(x+Labspace, screen->r.min.y + Labspace), display->black, ZP, mediumfont, buf);
	}

	maxx = screen->r.max.x;

	/* label right, if requested */
	if(ylabels && dy>Nlab*(mediumfont->height+1)){
		wid = labelwidth();
		if(wid < (maxx-startx)-30){
			/* else there's not enough room */
			maxx -= 1+Lx+wid;
			draw(screen, Rect(maxx, starty, maxx+1, screen->r.max.y), display->black, nil, ZP);
			y = starty;
			for(j=0; j<ngraph; j++, y+=dy){
				/* choose value for rightmost graph */
				g = &graph[ngraph*(nmach-1)+j];
				labelstrs(g, labs, &nlab);
				r = Rect(maxx+1, y, screen->r.max.x, y+dy-1);
				if(j == ngraph-1)
					r.max.y = screen->r.max.y;
				draw(screen, r, cols[g->colindex][0], nil, paritypt(r.min.x));
				for(k=0; k<nlab; k++){
					ly = y + (dy*(nlab-k)/(nlab+1));
					draw(screen, Rect(maxx+1, ly, maxx+1+Lx, ly+1), display->black, nil, ZP);
					ly -= mediumfont->height/2;
					string(screen, Pt(maxx+1+Lx, ly), display->black, ZP, mediumfont, labs[k]);
				}
			}
		}
	}

	/* create graphs */
	for(i=0; i<nmach; i++){
		machr = Rect(startx+i*dx, starty, maxx, screen->r.max.y);
		if(i < nmach-1)
			machr.max.x = startx+(i+1)*dx - 1;
		y = starty;
		for(j=0; j<ngraph; j++, y+=dy){
			g = &graph[i*ngraph+j];
			/* allocate data */
			ondata = g->ndata;
			g->ndata = Dx(machr)+1;	/* may be too many if label will be drawn here; so what? */
			g->data = erealloc(g->data, g->ndata*sizeof(ulong));
			if(g->ndata > ondata)
				memset(g->data+ondata, 0, (g->ndata-ondata)*sizeof(ulong));
			/* set geometry */
			g->r = machr;
			g->r.min.y = y;
			g->r.max.y = y+dy - 1;
			if(j == ngraph-1)
				g->r.max.y = screen->r.max.y;
			draw(screen, g->r, cols[g->colindex][0], nil, paritypt(g->r.min.x));
			g->overflow = 0;
			r = g->r;
			r.max.y = r.min.y+mediumfont->height;
			r.max.x = r.min.x+stringwidth(mediumfont, "9999999");
			freeimage(g->overtmp);
			g->overtmp = nil;
			if(r.max.x <= g->r.max.x)
				g->overtmp = allocimage(display, r, screen->chan, 0, -1);
			newvalue(g->mach, g->value, &v, &vmax);
			redraw(g, vmax);
		}
	}

	flushimage(display, 1);
}

void
eresized(int new)
{
	lockdisplay(display);
	if(new && getwindow(display, Refnone) < 0) {
		fprint(2, "stats: can't reattach to window\n");
		killall("reattach");
	}
	resize();
	unlockdisplay(display);
}

void
mousethread(void *v)
{
	Mouse m;
	int i;

	USED(v);

	while(readmouse(mc) == 0){
		m = mc->m;
		if(m.buttons == 4){
			for(i=0; i<Nvalue; i++)
				if(present[i])
					memmove(menu2str[i], "drop ", Opwid);
				else
					memmove(menu2str[i], "add  ", Opwid);
			lockdisplay(display);
			i = menuhit(3, mc, &menu2, nil);
			if(i >= 0){
				if(!present[i])
					addgraph(i);
				else if(ngraph > 1)
					dropgraph(i);
				resize();
			}
			unlockdisplay(display);
		}
	}
}

void
resizethread(void *v)
{
	USED(v);

	while(recv(mc->resizec, 0) == 1){
		lockdisplay(display);
		if(getwindow(display, Refnone) < 0)
			sysfatal("attach to window: %r");
		resize();
		unlockdisplay(display);
	}
}

void
keyboardthread(void *v)
{
	Rune r;

	while(recv(kc->c, &r) == 1)
		if(r == 0x7F || r == 'q')
			killall("quit");
}

void machproc(void*);
void updateproc(void*);

void
threadmain(int argc, char *argv[])
{
	int i, j;
	char *s;
	ulong nargs;
	char args[100];

	nmach = 1;
	mysysname = sysname();
	if(mysysname == nil){
		fprint(2, "stats: can't find sysname: %r\n");
		threadexitsall("sysname");
	}

	nargs = 0;
	ARGBEGIN{
	case 'T':
		s = ARGF();
		if(s == nil)
			usage();
		i = atoi(s);
		if(i > 0)
			sleeptime = 1000*i;
		break;
	case 'S':
		s = ARGF();
		if(s == nil)
			usage();
		scale = atof(s);
		if(scale <= 0.)
			usage();
		break;
	case 'L':
		logscale++;
		break;
	case 'Y':
		ylabels++;
		break;
	case 'O':
		oldsystem = 1;
		break;
	case 'W':
		winsize = EARGF(usage());
		break;
	default:
		if(nargs>=sizeof args || strchr(argchars, ARGC())==nil)
			usage();
		args[nargs++] = ARGC();
	}ARGEND

	for(i=0; i<Nvalue; i++){
		menu2str[i] = xmenu2str[i];
		snprint(xmenu2str[i], sizeof xmenu2str[i], "add  %s", labels[i]);
	}

	if(argc == 0){
		mach = emalloc(nmach*sizeof(Machine));
		initmach(&mach[0], mysysname);
	}else{
		for(i=j=0; i<argc; i++)
			addmachine(argv[i]);
	}

	for(i=0; i<nmach; i++)
		proccreate(machproc, &mach[i], STACK);

	for(i=0; i<nargs; i++)
	switch(args[i]){
	default:
		fprint(2, "stats: internal error: unknown arg %c\n", args[i]);
		usage();
	case 'b':
		addgraph(Vbattery);
		break;
	case 'c':
		addgraph(Vcontext);
		break;
	case 'C':
		addgraph(Vcpu);
		break;
	case 'e':
		addgraph(Vether);
		break;
	case 'E':
		addgraph(Vetherin);
		addgraph(Vetherout);
		break;
	case 'f':
		addgraph(Vfault);
		break;
	case 'i':
		addgraph(Vintr);
		break;
	case 'I':
		addgraph(Vload);
		addgraph(Vidle);
		break;
	case 'l':
		addgraph(Vload);
		break;
	case 'm':
		addgraph(Vmem);
		break;
	case 'n':
		addgraph(Vetherin);
		addgraph(Vetherout);
		addgraph(Vethererr);
		break;
	case 's':
		addgraph(Vsyscall);
		break;
	case 'w':
		addgraph(Vswap);
		break;
	}

	if(ngraph == 0)
		addgraph(Vload);

	for(i=0; i<nmach; i++)
		for(j=0; j<ngraph; j++)
			graph[i*ngraph+j].mach = &mach[i];

	if(initdraw(0, nil, "stats") < 0)
		sysfatal("initdraw: %r");
	colinit();
	if((mc = initmouse(nil, screen)) == nil)
		sysfatal("initmouse: %r");
	if((kc = initkeyboard(nil)) == nil)
		sysfatal("initkeyboard: %r");

	display->locking = 1;
	threadcreate(keyboardthread, nil, XSTACK);
	threadcreate(mousethread, nil, XSTACK);
	threadcreate(resizethread, nil, XSTACK);
	proccreate(updateproc, nil, XSTACK);
	resize();
	unlockdisplay(display);
}

void
updateproc(void *z)
{
	int i;
	ulong v, vmax;

	USED(z);
	for(;;){
		parity = 1-parity;
		lockdisplay(display);
		for(i=0; i<nmach*ngraph; i++){
			newvalue(graph[i].mach, graph[i].value, &v, &vmax);
			graph[i].update(&graph[i], v, vmax);
		}
		if(changedvmax){
			changedvmax = 0;
			resize();
		}
		flushimage(display, 1);
		unlockdisplay(display);
		sleep(sleeptime);
	}
}

void
machproc(void *v)
{
	char buf[256], *f[4], *p;
	int i, n, t;
	Machine *m;

	m = v;
	t = 0;
	for(;;){
		n = read(m->fd, buf+t, sizeof buf-t);
		m->dead = 0;
		if(n <= 0)
			break;
		t += n;
		while((p = memchr(buf, '\n', t)) != nil){
			*p++ = 0;
			n = tokenize(buf, f, nelem(f));
			if(n >= 3){
				for(i=0; i<Nvalue; i++){
					if(strcmp(labels[i], f[0]) == 0){
						if(*f[1] == '='){
							m->absolute[i] = 1;
							f[1]++;
						}
						m->val[i][0] = strtoul(f[1], 0, 0);
						m->val[i][1] = strtoul(f[2], 0, 0);
					}
				}
			}
			t -= (p-buf);
			memmove(buf, p, t);
		}
	}
	if(m->fd){
		close(m->fd);
		m->fd = -1;
	}
	if(m->pid){
		postnote(PNPROC, m->pid, "kill");
		m->pid = 0;
	}
}

int
initmach(Machine *m, char *name)
{
	char *args[5], *q;
	int p[2], kfd[3], pid;

	m->name = name;
	if(strcmp(name, mysysname) == 0)
		name = nil;

	if(pipe(p) < 0)
		sysfatal("pipe: %r");

	memset(args, 0, sizeof args);
	args[0] = "auxstats";
	if(name){
		args[1] = name;
		if((q = strchr(name, ':')) != nil){
			*q++ = 0;
			args[2] = q;
		}
	}
	kfd[0] = open("/dev/null", OREAD);
	kfd[1] = p[1];
	kfd[2] = dup(2, -1);
	if((pid = threadspawn(kfd, "auxstats", args)) < 0){
		fprint(2, "spawn: %r\n");
		close(kfd[0]);
		close(p[0]);
		close(p[1]);
		return 0;
	}
	m->fd = p[0];
	m->pid = pid;
	if((q = strchr(m->name, '.')) != nil)
		*q = 0;
	return 1;
}

