daemon.go 2.52 KB
Newer Older
1 2 3 4 5
package daemon

import (
	"encoding/json"
	"errors"
6 7
	"fmt"
	"io"
8 9
	"net"

10 11 12
	core "github.com/jbenet/go-ipfs/core"
	commands "github.com/jbenet/go-ipfs/core/commands"
	dag "github.com/jbenet/go-ipfs/merkledag"
13 14 15 16 17 18
	u "github.com/jbenet/go-ipfs/util"
)

var ErrInvalidCommand = errors.New("invalid command")

type DaemonListener struct {
19 20 21
	node   *core.IpfsNode
	list   net.Listener
	closed bool
22 23
}

24
func NewDaemonListener(node *core.IpfsNode, addr string) (*DaemonListener, error) {
25 26 27 28
	list, err := net.Listen("tcp", addr)
	if err != nil {
		return nil, err
	}
29
	fmt.Println("new daemon listener.")
30 31

	return &DaemonListener{
32 33
		node: node,
		list: list,
34 35 36 37
	}, nil
}

type Command struct {
38 39 40 41 42 43 44 45 46
	Command string
	Args    []string
	Opts    map[string]interface{}
}

func NewCommand() *Command {
	return &Command{
		Opts: make(map[string]interface{}),
	}
47 48 49
}

func (dl *DaemonListener) Listen() {
50
	fmt.Println("listen.")
51 52
	for {
		c, err := dl.list.Accept()
53
		fmt.Println("Loop!")
54 55 56 57 58 59 60 61 62 63 64
		if err != nil {
			if !dl.closed {
				u.PErr("DaemonListener Accept: %v\n", err)
			}
			return
		}
		go dl.handleConnection(c)
	}
}

func (dl *DaemonListener) handleConnection(c net.Conn) {
65 66
	defer c.Close()

67
	dec := json.NewDecoder(c)
68 69

	var com Command
70 71
	err := dec.Decode(&com)
	if err != nil {
72
		fmt.Fprintln(c, err)
73 74
		return
	}
75

76
	u.DOut("Got command: %v\n", com)
77 78
	ExecuteCommand(&com, dl.node, c)
}
79

80 81 82 83 84 85 86
func ExecuteCommand(com *Command, n *core.IpfsNode, out io.Writer) {
	u.DOut("executing command: %s\n", com.Command)
	switch com.Command {
	case "add":
		depth := 1
		if r, ok := com.Opts["r"].(bool); r && ok {
			depth = -1
87
		}
88 89 90 91 92 93 94 95 96 97 98 99 100 101
		for _, path := range com.Args {
			_, err := commands.AddPath(n, path, depth)
			if err != nil {
				fmt.Fprintf(out, "addFile error: %v\n", err)
				continue
			}
		}
	case "cat":
		for _, fn := range com.Args {
			nd, err := n.Resolver.ResolvePath(fn)
			if err != nil {
				fmt.Fprintf(out, "catFile error: %v\n", err)
				return
			}
102

103 104 105 106 107
			read, err := dag.NewDagReader(nd, n.DAG)
			if err != nil {
				fmt.Fprintln(out, err)
				continue
			}
108

109 110 111 112 113 114 115 116 117 118 119 120 121
			_, err = io.Copy(out, read)
			if err != nil {
				fmt.Fprintln(out, err)
				continue
			}
		}
	case "ls":
		for _, fn := range com.Args {
			nd, err := n.Resolver.ResolvePath(fn)
			if err != nil {
				fmt.Fprintf(out, "ls: %v\n", err)
				return
			}
122

123 124 125 126 127 128
			for _, link := range nd.Links {
				fmt.Fprintf(out, "%s %d %s\n", link.Hash.B58String(), link.Size, link.Name)
			}
		}
	default:
		fmt.Fprintf(out, "Invalid Command: '%s'\n", com.Command)
129 130 131 132 133 134 135
	}
}

func (dl *DaemonListener) Close() error {
	dl.closed = true
	return dl.list.Close()
}