Merge pull request #452 from pkg/patch/fix-filezilla
[bugfix] FileZilla parses the directory listing in longname
diff --git a/server_unix.go b/server_unix.go
index abceca4..a7b7617 100644
--- a/server_unix.go
+++ b/server_unix.go
@@ -6,21 +6,35 @@
import (
"fmt"
"os"
- "path"
"syscall"
"time"
)
-func runLsStatt(dirent os.FileInfo, statt *syscall.Stat_t) string {
+// ls -l style output for a file, which is in the 'long output' section of a readdir response packet
+// this is a very simple (lazy) implementation, just enough to look almost like openssh in a few basic cases
+func runLs(dirname string, dirent os.FileInfo) string {
// example from openssh sftp server:
// crw-rw-rw- 1 root wheel 0 Jul 31 20:52 ttyvd
// format:
// {directory / char device / etc}{rwxrwxrwx} {number of links} owner group size month day [time (this year) | year (otherwise)] name
typeword := runLsTypeWord(dirent)
- numLinks := statt.Nlink
- uid := statt.Uid
- gid := statt.Gid
+
+ var numLinks uint64 = 1
+ if dirent.IsDir() {
+ numLinks = 0
+ }
+
+ var uid, gid uint32
+
+ if statt, ok := dirent.Sys().(*syscall.Stat_t); ok {
+ // The type of Nlink varies form int16 (aix-ppc64) to uint64 (linux-amd64),
+ // we cast up to uint64 to make all OS/ARCH combos source compatible.
+ numLinks = uint64(statt.Nlink)
+ uid = statt.Uid
+ gid = statt.Gid
+ }
+
username := fmt.Sprintf("%d", uid)
groupname := fmt.Sprintf("%d", gid)
// TODO FIXME: uid -> username, gid -> groupname lookup for ls -l format output
@@ -39,16 +53,3 @@
return fmt.Sprintf("%s %4d %-8s %-8s %8d %s %2d %5s %s", typeword, numLinks, username, groupname, dirent.Size(), monthStr, day, yearOrTime, dirent.Name())
}
-
-// ls -l style output for a file, which is in the 'long output' section of a readdir response packet
-// this is a very simple (lazy) implementation, just enough to look almost like openssh in a few basic cases
-func runLs(dirname string, dirent os.FileInfo) string {
- dsys := dirent.Sys()
- if dsys == nil {
- } else if statt, ok := dsys.(*syscall.Stat_t); !ok {
- } else {
- return runLsStatt(dirent, statt)
- }
-
- return path.Join(dirname, dirent.Name())
-}