From b0a00d8e31da3aaf575c36d14a22d29023f96471 Mon Sep 17 00:00:00 2001 From: mengqi <5b5f7426@gmail.com> Date: Thu, 5 Feb 2015 11:09:57 +0800 Subject: [PATCH 1/2] If a entry is link, split the entry.Name by '->', save the first part to entry.Name and the second part to entry.PointTo --- ftp.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ftp.go b/ftp.go index 5fe19fe..0042425 100644 --- a/ftp.go +++ b/ftp.go @@ -32,6 +32,7 @@ type ServerConn struct { // Entry describes a file and is returned by List(). type Entry struct { Name string + PointTo string Type EntryType Size uint64 Time time.Time @@ -305,6 +306,13 @@ func parseListLine(line string) (*Entry, error) { e.Time = t e.Name = strings.Join(fields[8:], " ") + if e.Type == EntryTypeLink { + name := strings.SplitN(e.Name, " -> ", 2) + e.Name = name[0] + if len(name) > 1 { + e.PointTo = name[1] + } + } return e, nil } From 71cbbe03bdd303541f54c621c45e9c1f61d54bc7 Mon Sep 17 00:00:00 2001 From: mengqi <5b5f7426@gmail.com> Date: Thu, 5 Feb 2015 13:07:23 +0800 Subject: [PATCH 2/2] Add method for walking directory. --- ftp.go | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) diff --git a/ftp.go b/ftp.go index 0042425..53c4165 100644 --- a/ftp.go +++ b/ftp.go @@ -32,10 +32,11 @@ type ServerConn struct { // Entry describes a file and is returned by List(). type Entry struct { Name string - PointTo string Type EntryType Size uint64 Time time.Time + PointTo string + PointToDir bool } // response represent a data-connection @@ -497,3 +498,75 @@ func (r *response) Close() error { } return err } + +// Make a test to check if a path (usually a link) is a directory. +func (c *ServerConn) IsDir(path string) (bool, error) { + curdir, err := c.CurrentDir() + if err != nil { + return false, err + } + + err = c.ChangeDir(path) + if err != nil { + return false, nil + } + + err = c.ChangeDir(curdir) + if err != nil { + return true, err + } + + return true, nil +} + +// Function for walking directory. +type WalkFunc func(path string, entry *Entry) error + +// Walking a directory, and call walkfunc for each file or subdirectory. +func (c *ServerConn) Walk(path string, followlink bool, walkfunc WalkFunc) error { + entries, err := c.List(path) + if err != nil { + return err + } + + ok, err := c.IsDir(path) + if err != nil { + return err + } + if !ok && len(entries) > 0 { + return walkfunc(path, entries[0]) + } + + for _, e := range entries { + p := strings.Join([]string{path, e.Name}, "/") + + if e.Type == EntryTypeLink { + ok, err := c.IsDir(p) + if err != nil { + return err + } + if ok { + e.PointToDir = true + + if followlink { + err = c.Walk(p, followlink, walkfunc) + if err != nil { + return err + } + } + } + } else if e.Type == EntryTypeFolder { + err = c.Walk(p, followlink, walkfunc) + if err != nil { + return err + } + } + + err = walkfunc(p, e) + if err != nil { + return err + } + } + + return nil +}