~rbn/neinp

ref: b441da6dea2e963387a86b9d1d57802b77f21b83 neinp/stat/fileinfo.go -rw-r--r-- 1.3 KiB
b441da6dRuben Schuller initial commit 2 years ago
                                                                                
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
package stat

import (
	"github.com/rbns/neinp/qid"
	"os"
	"os/user"
	"strconv"
	"syscall"
	"time"
)

// FileInfo creates Stat using os.FileInfo.Sys(). If using the information
// returned by Sys() fails, it returns a stat like returned by GenericStat.
func FileInfo(fi os.FileInfo) Stat {
	s, ok := fi.Sys().(*syscall.Stat_t)
	if !ok {
		return Generic(fi)
	}

	size := fi.Size()
	if fi.IsDir() {
		size = 0
	}

	var uid, gid string

	x, err := user.LookupId(strconv.Itoa(int(s.Uid)))
	if err != nil {
		return Generic(fi)
	}
	uid = x.Name

	y, err := user.LookupGroupId(strconv.Itoa(int(s.Gid)))
	if err != nil {
		return Generic(fi)
	}
	gid = y.Name

	stat := Stat{
		Qid:    qid.FileInfo(fi),
		Mode:   Mode(fi.Mode()),
		Atime:  time.Unix(s.Atim.Sec, s.Atim.Nsec),
		Mtime:  time.Unix(s.Mtim.Sec, s.Mtim.Nsec),
		Length: uint64(size),
		Name:   fi.Name(),
		Uid:    uid,
		Gid:    gid,
		Muid:   uid,
	}

	return stat
}

// Generic creates a neinp.Stat not using FileInfo.Sys().
func Generic(fi os.FileInfo) Stat {
	size := fi.Size()
	if fi.IsDir() {
		size = 0
	}

	uid := "nobody"
	gid := "nogroup"

	stat := Stat{
		Qid:    qid.FileInfo(fi),
		Mode:   NeinMode(fi.Mode()),
		Atime:  fi.ModTime(),
		Mtime:  fi.ModTime(),
		Length: uint64(size),
		Name:   fi.Name(),
		Uid:    uid,
		Gid:    gid,
		Muid:   uid,
	}

	return stat
}