From 99dae57b4fc3fdc587f00f5409c8e78032352c10 Mon Sep 17 00:00:00 2001
From: Alexander Neumann <alexander@bumpern.de>
Date: Tue, 21 Jul 2015 21:23:40 +0200
Subject: [PATCH 1/4] fuse: use node.Type instead of node.Mode

---
 cmd/restic/fuse/dir.go | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/cmd/restic/fuse/dir.go b/cmd/restic/fuse/dir.go
index c8114bbca..43ea71e2b 100644
--- a/cmd/restic/fuse/dir.go
+++ b/cmd/restic/fuse/dir.go
@@ -66,10 +66,10 @@ func (d *dir) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) {
 
 	for _, node := range d.children {
 		var typ fuse.DirentType
-		switch {
-		case node.Mode.IsDir():
+		switch node.Type {
+		case "dir":
 			typ = fuse.DT_Dir
-		case node.Mode.IsRegular():
+		case "file":
 			typ = fuse.DT_File
 		}
 
@@ -88,10 +88,10 @@ func (d *dir) Lookup(ctx context.Context, name string) (fs.Node, error) {
 	if !ok {
 		return nil, fuse.ENOENT
 	}
-	switch {
-	case child.Mode.IsDir():
+	switch child.Type {
+	case "dir":
 		return newDir(d.repo, child)
-	case child.Mode.IsRegular():
+	case "file":
 		return newFile(d.repo, child)
 	default:
 		return nil, fuse.ENOENT

From 1ac72b8813bba58fec803070c920d1c2222a3192 Mon Sep 17 00:00:00 2001
From: Alexander Neumann <alexander@bumpern.de>
Date: Tue, 21 Jul 2015 21:24:06 +0200
Subject: [PATCH 2/4] Fix style issue

---
 cmd/restic/fuse/file.go | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/cmd/restic/fuse/file.go b/cmd/restic/fuse/file.go
index b207d939c..61b2ba170 100644
--- a/cmd/restic/fuse/file.go
+++ b/cmd/restic/fuse/file.go
@@ -23,8 +23,8 @@ type file struct {
 
 func newFile(repo *repository.Repository, node *restic.Node) (*file, error) {
 	sizes := make([]uint32, len(node.Content))
-	for i, blobId := range node.Content {
-		length, err := repo.Index().LookupSize(blobId)
+	for i, blobID := range node.Content {
+		length, err := repo.Index().LookupSize(blobID)
 		if err != nil {
 			return nil, err
 		}

From 3f4b5b8d482e47d73fdafb4b90a4a727dde6626a Mon Sep 17 00:00:00 2001
From: Alexander Neumann <alexander@bumpern.de>
Date: Tue, 21 Jul 2015 21:25:05 +0200
Subject: [PATCH 3/4] fuse/mount: display symlinks properly

---
 cmd/restic/fuse/dir.go  |  4 ++++
 cmd/restic/fuse/link.go | 30 ++++++++++++++++++++++++++++++
 2 files changed, 34 insertions(+)
 create mode 100644 cmd/restic/fuse/link.go

diff --git a/cmd/restic/fuse/dir.go b/cmd/restic/fuse/dir.go
index 43ea71e2b..ef7013977 100644
--- a/cmd/restic/fuse/dir.go
+++ b/cmd/restic/fuse/dir.go
@@ -71,6 +71,8 @@ func (d *dir) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) {
 			typ = fuse.DT_Dir
 		case "file":
 			typ = fuse.DT_File
+		case "symlink":
+			typ = fuse.DT_Link
 		}
 
 		ret = append(ret, fuse.Dirent{
@@ -93,6 +95,8 @@ func (d *dir) Lookup(ctx context.Context, name string) (fs.Node, error) {
 		return newDir(d.repo, child)
 	case "file":
 		return newFile(d.repo, child)
+	case "symlink":
+		return newLink(d.repo, child)
 	default:
 		return nil, fuse.ENOENT
 	}
diff --git a/cmd/restic/fuse/link.go b/cmd/restic/fuse/link.go
new file mode 100644
index 000000000..c5a17811b
--- /dev/null
+++ b/cmd/restic/fuse/link.go
@@ -0,0 +1,30 @@
+package fuse
+
+import (
+	"bazil.org/fuse"
+	"bazil.org/fuse/fs"
+	"github.com/restic/restic"
+	"github.com/restic/restic/repository"
+	"golang.org/x/net/context"
+)
+
+// Statically ensure that *file implements the given interface
+var _ = fs.NodeReadlinker(&link{})
+
+type link struct {
+	node *restic.Node
+}
+
+func newLink(repo *repository.Repository, node *restic.Node) (*link, error) {
+	return &link{node: node}, nil
+}
+
+func (l *link) Readlink(ctx context.Context, req *fuse.ReadlinkRequest) (string, error) {
+	return l.node.LinkTarget, nil
+}
+
+func (l *link) Attr(ctx context.Context, a *fuse.Attr) error {
+	a.Inode = l.node.Inode
+	a.Mode = l.node.Mode
+	return nil
+}

From 9911d46996807f411e7473f63b3bc256f22c2aef Mon Sep 17 00:00:00 2001
From: Alexander Neumann <alexander@bumpern.de>
Date: Tue, 21 Jul 2015 21:34:59 +0200
Subject: [PATCH 4/4] fuse: rename child/children -> node/items

---
 cmd/restic/fuse/dir.go | 42 +++++++++++++++++++++---------------------
 1 file changed, 21 insertions(+), 21 deletions(-)

diff --git a/cmd/restic/fuse/dir.go b/cmd/restic/fuse/dir.go
index ef7013977..ff4fa2e95 100644
--- a/cmd/restic/fuse/dir.go
+++ b/cmd/restic/fuse/dir.go
@@ -16,9 +16,9 @@ var _ = fs.HandleReadDirAller(&dir{})
 var _ = fs.NodeStringLookuper(&dir{})
 
 type dir struct {
-	repo     *repository.Repository
-	children map[string]*restic.Node
-	inode    uint64
+	repo  *repository.Repository
+	items map[string]*restic.Node
+	inode uint64
 }
 
 func newDir(repo *repository.Repository, node *restic.Node) (*dir, error) {
@@ -26,15 +26,15 @@ func newDir(repo *repository.Repository, node *restic.Node) (*dir, error) {
 	if err != nil {
 		return nil, err
 	}
-	children := make(map[string]*restic.Node)
-	for _, child := range tree.Nodes {
-		children[child.Name] = child
+	items := make(map[string]*restic.Node)
+	for _, node := range tree.Nodes {
+		items[node.Name] = node
 	}
 
 	return &dir{
-		repo:     repo,
-		children: children,
-		inode:    node.Inode,
+		repo:  repo,
+		items: items,
+		inode: node.Inode,
 	}, nil
 }
 
@@ -43,15 +43,15 @@ func newDirFromSnapshot(repo *repository.Repository, snapshot SnapshotWithId) (*
 	if err != nil {
 		return nil, err
 	}
-	children := make(map[string]*restic.Node)
+	items := make(map[string]*restic.Node)
 	for _, node := range tree.Nodes {
-		children[node.Name] = node
+		items[node.Name] = node
 	}
 
 	return &dir{
-		repo:     repo,
-		children: children,
-		inode:    inodeFromBackendId(snapshot.ID),
+		repo:  repo,
+		items: items,
+		inode: inodeFromBackendId(snapshot.ID),
 	}, nil
 }
 
@@ -62,9 +62,9 @@ func (d *dir) Attr(ctx context.Context, a *fuse.Attr) error {
 }
 
 func (d *dir) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) {
-	ret := make([]fuse.Dirent, 0, len(d.children))
+	ret := make([]fuse.Dirent, 0, len(d.items))
 
-	for _, node := range d.children {
+	for _, node := range d.items {
 		var typ fuse.DirentType
 		switch node.Type {
 		case "dir":
@@ -86,17 +86,17 @@ func (d *dir) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) {
 }
 
 func (d *dir) Lookup(ctx context.Context, name string) (fs.Node, error) {
-	child, ok := d.children[name]
+	node, ok := d.items[name]
 	if !ok {
 		return nil, fuse.ENOENT
 	}
-	switch child.Type {
+	switch node.Type {
 	case "dir":
-		return newDir(d.repo, child)
+		return newDir(d.repo, node)
 	case "file":
-		return newFile(d.repo, child)
+		return newFile(d.repo, node)
 	case "symlink":
-		return newLink(d.repo, child)
+		return newLink(d.repo, node)
 	default:
 		return nil, fuse.ENOENT
 	}