diff --git a/ftp.go b/ftp.go index cf8e2f8..5e764cc 100644 --- a/ftp.go +++ b/ftp.go @@ -290,6 +290,8 @@ func (c *ServerConn) cmdDataConnFrom(offset uint64, format string, args ...inter // parseListLine parses the various non-standard format returned by the LIST // FTP command. func parseListLine(line string) (*Entry, error) { + var err error + if strings.HasPrefix(line, "modify=") { e := &Entry{} arr := strings.Split(line, "; ") @@ -322,7 +324,36 @@ func parseListLine(line string) (*Entry, error) { } else { fields := strings.Fields(line) + if len(fields) >= 7 && fields[1] == "folder" { + e := &Entry{ + Type: EntryTypeFolder, + Name: strings.Join(fields[6:], " "), + } + if err = e.SetTime(fields[3:6]); err != nil { + return nil, err + } + + return e, nil + } + + if fields[1] == "0" { + e := &Entry{ + Type: EntryTypeFile, + Name: strings.Join(fields[7:], " "), + } + + if err = e.SetSize(fields[2]); err != nil { + return nil, err + } + if err = e.SetTime(fields[4:7]); err != nil { + return nil, err + } + + return e, nil + } + if len(fields) < 9 { + //panic(fmt.Sprintf("%d %v", len(fields), fields[6])) return nil, errors.New("Unsupported LIST line") } @@ -339,30 +370,40 @@ func parseListLine(line string) (*Entry, error) { } if e.Type == EntryTypeFile { - size, err := strconv.ParseUint(fields[4], 10, 0) - if err != nil { + if err = e.SetSize(fields[4]); err != nil { return nil, err } - e.Size = size } - var timeStr string - if strings.Contains(fields[7], ":") { // this year - thisYear, _, _ := time.Now().Date() - timeStr = fields[6] + " " + fields[5] + " " + strconv.Itoa(thisYear)[2:4] + " " + fields[7] + " GMT" - } else { // not this year - timeStr = fields[6] + " " + fields[5] + " " + fields[7][2:4] + " " + "00:00" + " GMT" - } - t, err := time.Parse("_2 Jan 06 15:04 MST", timeStr) - if err != nil { + + if err = e.SetTime(fields[5:8]); err != nil { return nil, err } - e.Time = t e.Name = strings.Join(fields[8:], " ") return e, nil } } +func (e *Entry) SetSize(str string) (err error) { + e.Size, err = strconv.ParseUint(str, 10, 0) + return +} + +func (e *Entry) SetTime(fields []string) (err error) { + var timeStr string + if strings.Contains(fields[2], ":") { // this year + thisYear, _, _ := time.Now().Date() + timeStr = fields[1] + " " + fields[0] + " " + strconv.Itoa(thisYear)[2:4] + " " + fields[2] + " GMT" + } else { // not this year + if len(fields[2]) != 4 { + return errors.New("Invalid year format in time string") + } + timeStr = fields[1] + " " + fields[0] + " " + fields[2][2:4] + " " + "00:00" + " GMT" + } + e.Time, err = time.Parse("_2 Jan 06 15:04 MST", timeStr) + return +} + // NameList issues an NLST FTP command. func (c *ServerConn) NameList(path string) (entries []string, err error) { conn, err := c.cmdDataConnFrom(0, "NLST %s", path) diff --git a/parse_test.go b/parse_test.go index 9360a90..375f1f5 100644 --- a/parse_test.go +++ b/parse_test.go @@ -21,6 +21,10 @@ var listTests = []line{ {"drwxr-xr-x 3 110 1002 3 Dec 02 2009 p u b", "p u b", 0, EntryTypeFolder, time.Date(2009, time.December, 2, 0, 0, 0, 0, time.UTC)}, {"-rwxr-xr-x 3 110 1002 1234567 Dec 02 2009 fileName", "fileName", 1234567, EntryTypeFile, time.Date(2009, time.December, 2, 0, 0, 0, 0, time.UTC)}, {"lrwxrwxrwx 1 root other 7 Jan 25 00:17 bin -> usr/bin", "bin -> usr/bin", 0, EntryTypeLink, time.Date(thisYear, time.January, 25, 0, 17, 0, 0, time.UTC)}, + // Another ls style + {"drwxr-xr-x folder 0 Aug 15 05:49 !!!-Tipp des Haus!", "!!!-Tipp des Haus!", 0, EntryTypeFolder, time.Date(thisYear, time.August, 15, 5, 49, 0, 0, time.UTC)}, + {"drwxrwxrwx folder 0 Aug 11 20:32 P0RN", "P0RN", 0, EntryTypeFolder, time.Date(thisYear, time.August, 11, 20, 32, 0, 0, time.UTC)}, + {"-rw-r--r-- 0 195291136 195291136 Nov 16 2006 VIDEO_TS.VOB", "VIDEO_TS.VOB", 195291136, EntryTypeFile, time.Date(2006, time.November, 16, 0, 0, 0, 0, time.UTC)}, // Microsoft's FTP servers for Windows {"---------- 1 owner group 1803128 Jul 10 10:18 ls-lR.Z", "ls-lR.Z", 1803128, EntryTypeFile, time.Date(thisYear, time.July, 10, 10, 18, 0, 0, time.UTC)}, {"d--------- 1 owner group 0 May 9 19:45 Softlib", "Softlib", 0, EntryTypeFolder, time.Date(thisYear, time.May, 9, 19, 45, 0, 0, time.UTC)},