#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		*fontname;
char		*mysysname;
char		argchars[] = "bcCeEfiIlmnsw";
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)
{
	if(fontname)
		mediumfont = openfont(display, fontname);
	if(mediumfont == nil)
		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 [-LY] [-F font] [-O] [-S scale] [-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 'F':
		fontname = EARGF(usage());
		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;
}

