diff --git a/server_unix.go b/server_unix.go index abceca49..a7b7617c 100644 --- a/server_unix.go +++ b/server_unix.go @@ -6,21 +6,35 @@ package sftp 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 @@ func runLsStatt(dirent os.FileInfo, statt *syscall.Stat_t) string { 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()) -}