miscellaneous +/- (commands, dht, net)

a shared branch of innocuous miscellaneous fixes. Feel free to push. ~~Will be rebased after Dec 1, 01:00 UTC and merged.~~
Bindings to control remote daemons

``` go
type Client interface {
	Add(io.Reader) (Key, error)
	Cat(Key) (io.Reader, error)

	http.FileSystem
}


func (c *client) Add(r io.Reader) (Key, error) {

	f := &cmds.SliceFile{"TODO",
		[]cmds.File{
			&cmds.ReaderFile{Filename: "TODO", Reader: r},
		},
	}
	req, err := cmds.NewRequest([]string{"add"}, nil, nil, f, core_cmds.AddCmd, nil)
	if err != nil {
		return nil, err
	}
	res, err := c.httpClient.Send(req)
	if err != nil {
		return nil, err
	}
	switch v := res.Output().(type) {
	case *core_cmds.AddOutput:
		if len(v.Objects) < 1 {
			return nil, errors.New("malformed response")
		}
		k, err := parseKey(v.Objects[0].Hash)
		if err != nil {
			return nil, err
		}
		return k, nil
	default:
		return nil, errors.New("unrecognized output format")
	}
}

func (c *client) Cat(k Key) (io.Reader, error) {
	// FIXME workaround for panic in http.Send
	f := &cmds.SliceFile{"TODO",
		[]cmds.File{
			&cmds.ReaderFile{Filename: "TODO", Reader: bytes.NewReader([]byte(""))},
		},
	}
	req, err := cmds.NewRequest([]string{"cat"}, nil, []string{k.String()}, f, core_cmds.CatCmd, nil)
	if err != nil {
		return nil, err
	}
	res, err := c.httpClient.Send(req)
	if err != nil {
		return nil, err
	}
	return res.Reader()
}
```