daemon.go 1.94 KB
Newer Older
1 2 3 4
package daemon

import (
	"encoding/json"
5
	"fmt"
6 7
	"net"

8
	core "github.com/jbenet/go-ipfs/core"
9
	"github.com/jbenet/go-ipfs/core/commands"
10 11 12
	u "github.com/jbenet/go-ipfs/util"
)

Siraj Ravel's avatar
Siraj Ravel committed
13 14
//DaemonListener listens to an initialized IPFS node and can send it commands instead of
//starting up a new set of connections
15
type DaemonListener struct {
16 17 18
	node   *core.IpfsNode
	list   net.Listener
	closed bool
19 20
}

Siraj Ravel's avatar
Siraj Ravel committed
21
//Command accepts user input and can be sent to the running IPFS node
Siraj Ravel's avatar
Siraj Ravel committed
22 23 24 25 26 27
type Command struct {
	Command string
	Args    []string
	Opts    map[string]interface{}
}

Siraj Ravel's avatar
Siraj Ravel committed
28
func NewDaemonListener(ipfsnode *core.IpfsNode, addr string) (*DaemonListener, error) {
29 30 31 32
	list, err := net.Listen("tcp", addr)
	if err != nil {
		return nil, err
	}
Siraj Ravel's avatar
Siraj Ravel committed
33
	fmt.Println("New daemon listener initialized.")
34 35

	return &DaemonListener{
Siraj Ravel's avatar
Siraj Ravel committed
36
		node: ipfsnode,
37
		list: list,
38 39 40
	}, nil
}

41 42 43 44
func NewCommand() *Command {
	return &Command{
		Opts: make(map[string]interface{}),
	}
45 46 47
}

func (dl *DaemonListener) Listen() {
48
	fmt.Println("listen.")
49
	for {
Siraj Ravel's avatar
Siraj Ravel committed
50
		conn, err := dl.list.Accept()
51
		fmt.Println("Loop!")
52 53 54 55 56 57
		if err != nil {
			if !dl.closed {
				u.PErr("DaemonListener Accept: %v\n", err)
			}
			return
		}
Siraj Ravel's avatar
Siraj Ravel committed
58
		go dl.handleConnection(conn)
59 60 61
	}
}

Siraj Ravel's avatar
Siraj Ravel committed
62 63
func (dl *DaemonListener) handleConnection(conn net.Conn) {
	defer conn.Close()
64

Siraj Ravel's avatar
Siraj Ravel committed
65
	dec := json.NewDecoder(conn)
66

Siraj Ravel's avatar
Siraj Ravel committed
67 68
	var command Command
	err := dec.Decode(&command)
69
	if err != nil {
Siraj Ravel's avatar
Siraj Ravel committed
70
		fmt.Fprintln(conn, err)
71 72
		return
	}
73

Siraj Ravel's avatar
Siraj Ravel committed
74
	u.DOut("Got command: %v\n", command)
75
	switch command.Command {
76
	case "add":
77
		err = commands.Add(dl.node, command.Args, command.Opts, conn)
78
	case "cat":
79
		err = commands.Cat(dl.node, command.Args, command.Opts, conn)
80
	case "ls":
81
		err = commands.Ls(dl.node, command.Args, command.Opts, conn)
Jeromy's avatar
Jeromy committed
82
	case "pin":
83
		err = commands.Pin(dl.node, command.Args, command.Opts, conn)
84
	default:
85 86 87 88
		err = fmt.Errorf("Invalid Command: '%s'", command.Command)
	}
	if err != nil {
		fmt.Fprintln(conn, err)
89 90 91 92 93 94 95
	}
}

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