Skip to content

Commit c1312a7

Browse files
cornyjlaffaye
authored andcommitted
Correctly parse symlink (jlaffaye#152)
fixes jlaffaye#151
1 parent 9284a88 commit c1312a7

File tree

3 files changed

+42
-5
lines changed

3 files changed

+42
-5
lines changed

ftp.go

+5-4
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,11 @@ type dialOptions struct {
5959

6060
// Entry describes a file and is returned by List().
6161
type Entry struct {
62-
Name string
63-
Type EntryType
64-
Size uint64
65-
Time time.Time
62+
Name string
63+
Target string // target of symbolic link
64+
Type EntryType
65+
Size uint64
66+
Time time.Time
6667
}
6768

6869
// Response represents a data-connection

parse.go

+6
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,12 @@ func parseLsListLine(line string, now time.Time, loc *time.Location) (*Entry, er
135135
e.Type = EntryTypeFolder
136136
case 'l':
137137
e.Type = EntryTypeLink
138+
139+
// Split link name and target
140+
if i := strings.Index(e.Name, " -> "); i > 0 {
141+
e.Target = e.Name[i+4:]
142+
e.Name = e.Name[:i]
143+
}
138144
default:
139145
return nil, errUnknownListEntryType
140146
}

parse_test.go

+31-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ type line struct {
2323
time time.Time
2424
}
2525

26+
type symlinkLine struct {
27+
line string
28+
name string
29+
target string
30+
}
31+
2632
type unsupportedLine struct {
2733
line string
2834
err error
@@ -35,7 +41,7 @@ var listTests = []line{
3541
{"-rw-r--r-- 1 marketwired marketwired 12016 Mar 16 2016 2016031611G087802-001.newsml", "2016031611G087802-001.newsml", 12016, EntryTypeFile, newTime(2016, time.March, 16)},
3642

3743
{"-rwxr-xr-x 3 110 1002 1234567 Dec 02 2009 fileName", "fileName", 1234567, EntryTypeFile, newTime(2009, time.December, 2)},
38-
{"lrwxrwxrwx 1 root other 7 Jan 25 00:17 bin -> usr/bin", "bin -> usr/bin", 0, EntryTypeLink, newTime(thisYear, time.January, 25, 0, 17)},
44+
{"lrwxrwxrwx 1 root other 7 Jan 25 00:17 bin -> usr/bin", "bin", 0, EntryTypeLink, newTime(thisYear, time.January, 25, 0, 17)},
3945

4046
// Another ls style
4147
{"drwxr-xr-x folder 0 Aug 15 05:49 !!!-Tipp des Haus!", "!!!-Tipp des Haus!", 0, EntryTypeFolder, newTime(thisYear, time.August, 15, 5, 49)},
@@ -74,6 +80,11 @@ var listTests = []line{
7480
{"-rwxrw-r--+ 1 521 101 2080 May 21 10:53 data.csv", "data.csv", 2080, EntryTypeFile, newTime(thisYear, time.May, 21, 10, 53)},
7581
}
7682

83+
var listTestsSymlink = []symlinkLine{
84+
{"lrwxrwxrwx 1 root other 7 Jan 25 00:17 bin -> usr/bin", "bin", "usr/bin"},
85+
{"lrwxrwxrwx 1 0 1001 27 Jul 07 2017 R-3.4.0.pkg -> el-capitan/base/R-3.4.0.pkg", "R-3.4.0.pkg", "el-capitan/base/R-3.4.0.pkg"},
86+
}
87+
7788
// Not supported, we expect a specific error message
7889
var listTestsFail = []unsupportedLine{
7990
{"d [R----F--] supervisor 512 Jan 16 18:53 login", errUnsupportedListLine},
@@ -111,6 +122,25 @@ func TestParseValidListLine(t *testing.T) {
111122
}
112123
}
113124

125+
func TestParseSymlinks(t *testing.T) {
126+
for _, lt := range listTestsSymlink {
127+
entry, err := parseListLine(lt.line, now, time.UTC)
128+
if err != nil {
129+
t.Errorf("parseListLine(%v) returned err = %v", lt.line, err)
130+
continue
131+
}
132+
if entry.Name != lt.name {
133+
t.Errorf("parseListLine(%v).Name = '%v', want '%v'", lt.line, entry.Name, lt.name)
134+
}
135+
if entry.Target != lt.target {
136+
t.Errorf("parseListLine(%v).Target = '%v', want '%v'", lt.line, entry.Target, lt.target)
137+
}
138+
if entry.Type != EntryTypeLink {
139+
t.Errorf("parseListLine(%v).EntryType = %v, want EntryTypeLink", lt.line, entry.Type)
140+
}
141+
}
142+
}
143+
114144
func TestParseUnsupportedListLine(t *testing.T) {
115145
for _, lt := range listTestsFail {
116146
t.Run(fmt.Sprintf("parseListLine(%v)", lt.line), func(t *testing.T) {

0 commit comments

Comments
 (0)