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

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

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

Siraj Ravel's avatar
Siraj Ravel committed
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{}
}

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

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

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

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

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

Siraj Ravel's avatar
Siraj Ravel committed
67
	dec := json.NewDecoder(conn)
68

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

Siraj Ravel's avatar
Siraj Ravel committed
76
	u.DOut("Got command: %v\n", command)
77 78 79 80
	err := ExecuteCommand(&command, dl.node, conn)
	if err != nil {
		fmt.Fprintln(conn, "%v\n", err)
	}
81
}
82

83
func ExecuteCommand(com *Command, ipfsnode *core.IpfsNode, out io.Writer) error {
84 85 86 87 88 89
	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
90
		}
91
		for _, path := range com.Args {
92 93 94 95 96 97
			nd, err := commands.AddPath(ipfsnode, path, depth)
			if err != nil {
				return fmt.Errorf("addFile error: %v", err)
			}

			k, err := nd.Key()
98
			if err != nil {
99
				return fmt.Errorf("addFile error: %v", err)
100
			}
101 102

			fmt.Fprintf(out, "Added node: %s = %s\n", path, k.Pretty())
103 104 105
		}
	case "cat":
		for _, fn := range com.Args {
Siraj Ravel's avatar
Siraj Ravel committed
106
			dagnode, err := ipfsnode.Resolver.ResolvePath(fn)
107
			if err != nil {
108
				return fmt.Errorf("catFile error: %v", err)
109
			}
110

Siraj Ravel's avatar
Siraj Ravel committed
111
			read, err := dag.NewDagReader(dagnode, ipfsnode.DAG)
112
			if err != nil {
113
				return fmt.Errorf("cat error: %v", err)
114
			}
115

116 117
			_, err = io.Copy(out, read)
			if err != nil {
118
				return fmt.Errorf("cat error: %v", err)
119 120 121 122
			}
		}
	case "ls":
		for _, fn := range com.Args {
Siraj Ravel's avatar
Siraj Ravel committed
123
			dagnode, err := ipfsnode.Resolver.ResolvePath(fn)
124
			if err != nil {
125
				return fmt.Errorf("ls error: %v", err)
126
			}
127

Siraj Ravel's avatar
Siraj Ravel committed
128
			for _, link := range dagnode.Links {
129 130 131
				fmt.Fprintf(out, "%s %d %s\n", link.Hash.B58String(), link.Size, link.Name)
			}
		}
Jeromy's avatar
Jeromy committed
132 133
	case "pin":
		for _, fn := range com.Args {
Siraj Ravel's avatar
Siraj Ravel committed
134
			dagnode, err := ipfsnode.Resolver.ResolvePath(fn)
Jeromy's avatar
Jeromy committed
135
			if err != nil {
136
				return fmt.Errorf("pin error: %v", err)
Jeromy's avatar
Jeromy committed
137 138
			}

Siraj Ravel's avatar
Siraj Ravel committed
139
			err = ipfsnode.PinDagNode(dagnode)
Jeromy's avatar
Jeromy committed
140
			if err != nil {
141
				return fmt.Errorf("pin: %v", err)
Jeromy's avatar
Jeromy committed
142 143
			}
		}
144
	default:
145
		return fmt.Errord("Invalid Command: '%s'", com.Command)
146 147 148 149 150 151 152
	}
}

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