@@ -6,21 +6,35 @@ package sftp
6
6
import (
7
7
"fmt"
8
8
"os"
9
- "path"
10
9
"syscall"
11
10
"time"
12
11
)
13
12
14
- func runLsStatt (dirent os.FileInfo , statt * syscall.Stat_t ) string {
13
+ // ls -l style output for a file, which is in the 'long output' section of a readdir response packet
14
+ // this is a very simple (lazy) implementation, just enough to look almost like openssh in a few basic cases
15
+ func runLs (dirname string , dirent os.FileInfo ) string {
15
16
// example from openssh sftp server:
16
17
// crw-rw-rw- 1 root wheel 0 Jul 31 20:52 ttyvd
17
18
// format:
18
19
// {directory / char device / etc}{rwxrwxrwx} {number of links} owner group size month day [time (this year) | year (otherwise)] name
19
20
20
21
typeword := runLsTypeWord (dirent )
21
- numLinks := statt .Nlink
22
- uid := statt .Uid
23
- gid := statt .Gid
22
+
23
+ var numLinks uint64 = 1
24
+ if dirent .IsDir () {
25
+ numLinks = 0
26
+ }
27
+
28
+ var uid , gid uint32
29
+
30
+ if statt , ok := dirent .Sys ().(* syscall.Stat_t ); ok {
31
+ // The type of Nlink varies form int16 (aix-ppc64) to uint64 (linux-amd64),
32
+ // we cast up to uint64 to make all OS/ARCH combos source compatible.
33
+ numLinks = uint64 (statt .Nlink )
34
+ uid = statt .Uid
35
+ gid = statt .Gid
36
+ }
37
+
24
38
username := fmt .Sprintf ("%d" , uid )
25
39
groupname := fmt .Sprintf ("%d" , gid )
26
40
// 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 {
39
53
40
54
return fmt .Sprintf ("%s %4d %-8s %-8s %8d %s %2d %5s %s" , typeword , numLinks , username , groupname , dirent .Size (), monthStr , day , yearOrTime , dirent .Name ())
41
55
}
42
-
43
- // ls -l style output for a file, which is in the 'long output' section of a readdir response packet
44
- // this is a very simple (lazy) implementation, just enough to look almost like openssh in a few basic cases
45
- func runLs (dirname string , dirent os.FileInfo ) string {
46
- dsys := dirent .Sys ()
47
- if dsys == nil {
48
- } else if statt , ok := dsys .(* syscall.Stat_t ); ! ok {
49
- } else {
50
- return runLsStatt (dirent , statt )
51
- }
52
-
53
- return path .Join (dirname , dirent .Name ())
54
- }
0 commit comments