Browse Source

Use MLST if supported

closes #46
Julian Kornberger 9 years ago
parent
commit
04544dbe82
1 changed files with 23 additions and 8 deletions
  1. 23 8
      ftp.go

+ 23 - 8
ftp.go

@@ -24,11 +24,12 @@ const (
 
 
 // ServerConn represents the connection to a remote FTP server.
 // ServerConn represents the connection to a remote FTP server.
 type ServerConn struct {
 type ServerConn struct {
-	conn        *textproto.Conn
-	host        string
-	timeout     time.Duration
-	features    map[string]string
-	disableEPSV bool
+	conn          *textproto.Conn
+	host          string
+	timeout       time.Duration
+	features      map[string]string
+	disableEPSV   bool
+	mlstSupported bool
 }
 }
 
 
 // Entry describes a file and is returned by List().
 // Entry describes a file and is returned by List().
@@ -100,6 +101,10 @@ func DialTimeout(addr string, timeout time.Duration) (*ServerConn, error) {
 		return nil, err
 		return nil, err
 	}
 	}
 
 
+	if _, mlstSupported := c.features["MLST"]; mlstSupported {
+		c.mlstSupported = true
+	}
+
 	return c, nil
 	return c, nil
 }
 }
 
 
@@ -337,7 +342,18 @@ func (c *ServerConn) NameList(path string) (entries []string, err error) {
 
 
 // List issues a LIST FTP command.
 // List issues a LIST FTP command.
 func (c *ServerConn) List(path string) (entries []*Entry, err error) {
 func (c *ServerConn) List(path string) (entries []*Entry, err error) {
-	conn, err := c.cmdDataConnFrom(0, "LIST %s", path)
+	var cmd string
+	var parseFunc func(string) (*Entry, error)
+
+	if c.mlstSupported {
+		cmd = "MLSD"
+		parseFunc = parseRFC3659ListLine
+	} else {
+		cmd = "LIST"
+		parseFunc = parseListLine
+	}
+
+	conn, err := c.cmdDataConnFrom(0, "%s %s", cmd, path)
 	if err != nil {
 	if err != nil {
 		return
 		return
 	}
 	}
@@ -347,8 +363,7 @@ func (c *ServerConn) List(path string) (entries []*Entry, err error) {
 
 
 	scanner := bufio.NewScanner(r)
 	scanner := bufio.NewScanner(r)
 	for scanner.Scan() {
 	for scanner.Scan() {
-		line := scanner.Text()
-		entry, err := parseListLine(line)
+		entry, err := parseFunc(scanner.Text())
 		if err == nil {
 		if err == nil {
 			entries = append(entries, entry)
 			entries = append(entries, entry)
 		}
 		}