daemon.go 2.11 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
	u "github.com/jbenet/go-ipfs/util"
11 12

	ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
13 14
)

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

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

30 31 32 33 34 35 36
func NewDaemonListener(ipfsnode *core.IpfsNode, addr *ma.Multiaddr) (*DaemonListener, error) {
	network, host, err := addr.DialArgs()
	if err != nil {
		return nil, err
	}

	list, err := net.Listen(network, host)
37 38 39
	if err != nil {
		return nil, err
	}
Siraj Ravel's avatar
Siraj Ravel committed
40
	fmt.Println("New daemon listener initialized.")
41 42

	return &DaemonListener{
Siraj Ravel's avatar
Siraj Ravel committed
43
		node: ipfsnode,
44
		list: list,
45 46 47
	}, nil
}

48 49 50 51
func NewCommand() *Command {
	return &Command{
		Opts: make(map[string]interface{}),
	}
52 53 54
}

func (dl *DaemonListener) Listen() {
55
	fmt.Println("listen.")
56
	for {
Siraj Ravel's avatar
Siraj Ravel committed
57
		conn, err := dl.list.Accept()
58
		fmt.Println("Loop!")
59 60 61 62 63 64
		if err != nil {
			if !dl.closed {
				u.PErr("DaemonListener Accept: %v\n", err)
			}
			return
		}
Siraj Ravel's avatar
Siraj Ravel committed
65
		go dl.handleConnection(conn)
66 67 68
	}
}

Siraj Ravel's avatar
Siraj Ravel committed
69 70
func (dl *DaemonListener) handleConnection(conn net.Conn) {
	defer conn.Close()
71

Siraj Ravel's avatar
Siraj Ravel committed
72
	dec := json.NewDecoder(conn)
73

Siraj Ravel's avatar
Siraj Ravel committed
74 75
	var command Command
	err := dec.Decode(&command)
76
	if err != nil {
Siraj Ravel's avatar
Siraj Ravel committed
77
		fmt.Fprintln(conn, err)
78 79
		return
	}
80

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

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