_ni=0;	// network indent level

defn
_ni() {
	loop 1,_ni do {
		print("\t");
	}
}

defn
ipdev(n) {
	_ipfs(*(ipfs+4*n));
}

// the funny _foo/foo pairs exist so that if we get
// interrupted in the middle of one of these, _ni will 
// get reset to 0 next time an external call happens.

defn
_ipfs(fs) {
	complex Fs fs;
	local i;

	print("ipfs(", fs\X, ")  #I", fs.dev\D, "\n");
	i=0;
	_ni = _ni+1;
	while i < fs.np do {
		_proto(*(fs.p+i*4));
		i = i + 1;
	}
	_ni = _ni-1;
}

defn
ipfs(fs) {
	_ni = 0;
	_ipfs(fs);
}

defn
_proto(p) {
	local c;
	complex Proto p;
	_ni();
	print("proto(", p\X, ") ", *(p.name\s), "\n");
	_ni = _ni+1;
	local i;
	i = 0;
	while i < p.nc do {
		c = *(p.conv+i*4);
		complex Conv c;
		if c != 0 && c.inuse then 
			_conv(*(p.conv+i*4));
		i = i + 1;
	}
	_ni = _ni - 1;
}

defn
proto(p) {
	_ni = 0;
	_proto(p);
}

defn
_conv(c) {
	complex Conv c;
	_ni();
	local p;
	p = c.p;
	complex Proto p;
	print("conv(", c\X, ") ", *(p.name\s), "/", c.x\D, " ", 
		iptostr(*(c.laddr+12)), "!", c.lport\D, " ", iptostr(*(c.raddr+12)), 
		"!", c.rport\D, " rq ", qtostr(c.rq), " wq ", qtostr(c.wq), 
		" eq ", qtostr(c.eq), "\n");
}

defn
conv(c) {
	_ni = 0;
	_conv(c);
}

defn
iptostr(a)
{
	// BUG: little endian
	return itoa(a&0xFF)+"."+itoa((a>>8)&0xFF)+"."+itoa((a>>16)&0xFF)+"."+itoa((a>>24)&0xFF);
}

defn
qtostr(q)
{
	complex Queue q;

	return "queue("+itoa(q, "%lux")+") ["+itoa(q.len, "%d")+","+itoa(q.dlen, "%d")+","+itoa(qblocks(q), "%d")+"]";
}

defn
qblocks(q)
{
	complex Queue q;
	local b, n;

	b = q.bfirst;
	n = 0;
	while b != 0 do { 
		n = n + 1;
		complex Block b;
		b = b.next;
	}
	return n;
}

defn
_queue(q)
{
	complex Queue q;
	local b;

	print("queue(", q\X, ") len ", q.len\D, " dlen ", q.dlen\D, " limit ", q.limit\D, " nblocks ", qblocks(q)\D);
	if q.state & Qstarve then 
		print(" starve");
	if q.state & Qmsg then
		print(" msg");
	if q.state & Qclosed then
		print(" closed");
	if q.state & Qflow then
		print(" flow");
	if q.state & Qcoalesce then
		print(" coalesce");
	print("\n");

	b = q.bfirst;
	_ni = _ni+1;
	while b != 0 do {
		_block(b);
		complex Block b;
		b = b.next;
	}
	_ni = _ni - 1;
}

defn
queue(q)
{
	_ni = 0;
	_queue(q);
}

defn
_block(b)
{
	complex Block b;

	_ni();
	print("block(", b\X, ") base ", b.base\X, " rp ", b.rp\X, "/", b.rp-b.base\D, " wp ", b.wp\X, "/", b.wp-b.base\D, " lim ", b.lim\X, "/", b.lim-b.base\D, "\n");
}

defn
block(b)
{
	_ni = 0;
	block(b);
}

print(acidfile);
needacid("tcp");
needacid("qio");
