-
Notifications
You must be signed in to change notification settings - Fork 2
/
readdir_linux.go
90 lines (79 loc) · 2.1 KB
/
readdir_linux.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
// +build linux
package sftpd
import (
"bytes"
"fmt"
"os/exec"
"time"
)
const shellToUse = "sh"
var users map[uint32]string
var groups map[uint32]string
func init() {
// 所有 sftp 连接共用变量
users = make(map[uint32]string)
groups = make(map[uint32]string)
}
func shellout(command string) (string, string, error) {
var stdout bytes.Buffer
var stderr bytes.Buffer
cmd := exec.Command(shellToUse, "-c", command)
cmd.Stdout = &stdout
cmd.Stderr = &stderr
err := cmd.Run()
return stdout.String(), stderr.String(), err
}
// 另外格式化方案可以参考 github.com/pkg/sftp 中的 runLsTypeWord, runLs 函数
func readdirLongName(fi *NamedAttr, sysType int) string {
// 执行命令很耗时,把前面的结果存 map,有则不用再去执行命令了
// 缺点就是如果某个 uid 或者 gid 对应的用户或者组的名称变了,不能感知,问题不大
var user, group string
if sysType == 2 {
user = fmt.Sprintf("%d", fi.Uid)
group = fmt.Sprintf("%d", fi.Gid)
} else {
if u, ok := users[fi.Uid]; ok {
user = u
} else {
user = string(fi.Uid)
stdout, _, e := shellout(fmt.Sprintf("/usr/bin/getent passwd %d 2>/dev/null|awk -F : '{print $1}'", fi.Uid))
if e == nil {
if stdout != "" {
user = stdout
}
}
users[fi.Uid] = user
}
if g, ok := groups[fi.Gid]; ok {
group = g
} else {
group = string(fi.Gid)
stdout, _, e := shellout(fmt.Sprintf("/usr/bin/getent group %d 2>/dev/null|awk -F : '{print $1}'", fi.Gid))
if e == nil {
if stdout != "" {
group = stdout
}
}
groups[fi.Gid] = group
}
user = fmt.Sprintf("%s(%d)", user, fi.Uid)
group = fmt.Sprintf("%s(%d)", group, fi.Gid)
}
return fmt.Sprintf("%s %4d %-8s %-8s %8d %12s %s",
//fi.Mode.String(),
fi.ModeString,
1, // links
user, group,
//fi.User, fi.Group,
fi.Size,
readdirTimeFormat(fi.MTime),
fi.Name,
)
}
func readdirTimeFormat(t time.Time) string {
// We return timestamps in UTC, should we offer a customisation point for users?
if t.Year() == time.Now().Year() {
return t.Format("Jan _2 15:04")
}
return t.Format("Jan _2 2006")
}