exp/dir/filesystem: use packer to generate DirBlocks

The code here wasn't setting the DirEntry.Packdata field
because at one point that wasn't necessary for plain placking.
Then it became necessary, but everywhere else was using the packer
itself to set the field, so it got overlooked here.

Change-Id: I7c1550a994d07370047181ce53834cc4e6f252b5
Reviewed-on: https://upspin-review.googlesource.com/9560
Reviewed-by: Rob Pike <r@golang.org>
diff --git a/dir/filesystem/dir.go b/dir/filesystem/dir.go
index c27c2ab..f6a01e4 100644
--- a/dir/filesystem/dir.go
+++ b/dir/filesystem/dir.go
@@ -9,6 +9,7 @@
 package filesystem
 
 import (
+	"io/ioutil"
 	"os"
 	"path/filepath"
 	"strings"
@@ -16,10 +17,14 @@
 	"upspin.io/access"
 	"upspin.io/errors"
 	"upspin.io/log"
+	"upspin.io/pack"
 	"upspin.io/path"
 	"upspin.io/upspin"
 )
 
+// TODO: use EEIntegrityPack
+const packing = upspin.PlainPack
+
 type server struct {
 	// Set by New.
 	root          string
@@ -81,7 +86,14 @@
 
 // entry returns the DirEntry for the named local file or directory.
 func (s *server) entry(file string) (*upspin.DirEntry, error) {
-	info, err := os.Stat(file)
+	// TODO: cache DirEntries and expire them based on the file's
+	// modification time.
+	f, err := os.Open(file)
+	if err != nil {
+		return nil, err
+	}
+	defer f.Close()
+	info, err := f.Stat()
 	if err != nil {
 		return nil, err
 	}
@@ -93,24 +105,39 @@
 	if !strings.HasPrefix(file, s.root) {
 		return nil, errors.Str("internal error: not in root")
 	}
+	name := s.upspinPathFromLocal(file)
 	entry := upspin.DirEntry{
-		Name:     s.upspinPathFromLocal(file),
-		Packing:  upspin.PlainPack,
-		Time:     upspin.TimeFromGo(info.ModTime()),
-		Attr:     attr,
-		Sequence: 0,
-		Writer:   s.server.UserName(), // TODO: Is there a better answer?
+		Name:       name,
+		SignedName: name,
+		Packing:    packing,
+		Time:       upspin.TimeFromGo(info.ModTime()),
+		Attr:       attr,
+		Sequence:   0,
+		Writer:     s.server.UserName(), // TODO: Is there a better answer?
 	}
 	if !info.IsDir() {
-		block := upspin.DirBlock{
-			Location: upspin.Location{
-				Endpoint:  s.server.StoreEndpoint(),
-				Reference: upspin.Reference(file[len(s.root):]),
-			},
-			Offset: 0,
-			Size:   info.Size(),
+		p := pack.Lookup(packing)
+		bp, err := p.Pack(s.server, &entry)
+		if err != nil {
+			return nil, err
 		}
-		entry.Blocks = []upspin.DirBlock{block}
+		contents, err := ioutil.ReadAll(f)
+		if err != nil {
+			return nil, err
+		}
+		// Ignore the returned "ciphertext", as using the plain packer
+		// it is equivalent to the cleartext.
+		_, err = bp.Pack(contents)
+		if err != nil {
+			return nil, err
+		}
+		bp.SetLocation(upspin.Location{
+			Endpoint:  s.server.StoreEndpoint(),
+			Reference: upspin.Reference(file[len(s.root):]),
+		})
+		if err := bp.Close(); err != nil {
+			return nil, err
+		}
 	}
 	return &entry, nil
 }