daemon.go 2.9 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
}

Siraj Ravel's avatar
Siraj Ravel committed
24 25 26 27 28 29 30
type Command struct {
	Command string
	Args    []string
	Opts    map[string]interface{}
}

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 77
	u.DOut("Got command: %v\n", command)
	ExecuteCommand(&command, dl.node, conn)
78
}
79

Siraj Ravel's avatar
Siraj Ravel committed
80
func ExecuteCommand(com *Command, Ipfsnode *core.IpfsNode, out io.Writer) {
81 82 83 84 85 86
	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
		for _, path := range com.Args {
Siraj Ravel's avatar
Siraj Ravel committed
89
			_, err := commands.AddPath(Ipfsnode, path, depth)
90 91 92 93 94 95 96
			if err != nil {
				fmt.Fprintf(out, "addFile error: %v\n", err)
				continue
			}
		}
	case "cat":
		for _, fn := range com.Args {
Siraj Ravel's avatar
Siraj Ravel committed
97
			DAGnode, err := Ipfsnode.Resolver.ResolvePath(fn)
98 99 100 101
			if err != nil {
				fmt.Fprintf(out, "catFile error: %v\n", err)
				return
			}
102

Siraj Ravel's avatar
Siraj Ravel committed
103
			read, err := dag.NewDagReader(nd, Ipfsnode.DAG)
104 105 106 107
			if err != nil {
				fmt.Fprintln(out, err)
				continue
			}
108

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

123 124 125 126
			for _, link := range nd.Links {
				fmt.Fprintf(out, "%s %d %s\n", link.Hash.B58String(), link.Size, link.Name)
			}
		}
Jeromy's avatar
Jeromy committed
127 128
	case "pin":
		for _, fn := range com.Args {
Siraj Ravel's avatar
Siraj Ravel committed
129
			DAGnode, err := Ipfsnode.Resolver.ResolvePath(fn)
Jeromy's avatar
Jeromy committed
130
			if err != nil {
Siraj Ravel's avatar
Siraj Ravel committed
131
				fmt.Fprintf(out, "pin error: %v\n", err)
Jeromy's avatar
Jeromy committed
132 133 134
				return
			}

Siraj Ravel's avatar
Siraj Ravel committed
135
			err = Ipfsnode.PinDagNode(nd)
Jeromy's avatar
Jeromy committed
136 137 138 139 140
			if err != nil {
				fmt.Fprintf(out, "pin: %v\n", err)
				return
			}
		}
141 142
	default:
		fmt.Fprintf(out, "Invalid Command: '%s'\n", com.Command)
143 144 145 146 147 148 149
	}
}

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