代码拉取完成,页面将自动刷新
package files
import (
"crypto/md5"
"errors"
"fmt"
"io"
"os"
"path"
"path/filepath"
"syscall"
)
// FileInfo 描述一个配置文,由fileStat返回.
type FileInfo struct {
Uid uint32
Gid uint32
Mode os.FileMode
Md5 string
}
func AppendPrefix(prefix string, keys []string) []string {
s := make([]string, len(keys))
for i, k := range keys {
s[i] = path.Join(prefix, k)
}
return s
}
// isFileExist 报告路径是否退出.
func IsFileExist(fpath string) bool {
if _, err := os.Stat(fpath); os.IsNotExist(err) {
return false
}
return true
}
// filestat 返回描述命名文件的FileInfo.
func FileStat(name string) (fi FileInfo, err error) {
if IsFileExist(name) {
f, err := os.Open(name)
if err != nil {
return fi, err
}
defer f.Close()
stats, _ := f.Stat()
fi.Uid = stats.Sys().(*syscall.Stat_t).Uid
fi.Gid = stats.Sys().(*syscall.Stat_t).Gid
fi.Mode = stats.Mode()
h := md5.New()
_, _ = io.Copy(h, f)
fi.Md5 = fmt.Sprintf("%x", h.Sum(nil))
return fi, nil
}
return fi, errors.New("file not found")
}
// IsConfigChanged 报告src和dest配置文件是否相等.
// 当两个配置文件具有相同的文件内容和Unix权限时,它们是相等的. 所有者,组和方式必须匹配.在其他情况下返回false.
func IsConfigChanged(src, dest string) (bool, error) {
if !IsFileExist(dest) {
return true, nil
}
d, err := FileStat(dest)
if err != nil {
return true, err
}
s, err := FileStat(src)
if err != nil {
return true, err
}
if d.Uid != s.Uid {
fmt.Printf("%s has UID %d should be %d\n", dest, d.Uid, s.Uid)
}
if d.Gid != s.Gid {
fmt.Printf("%s has GID %d should be %d\n", dest, d.Gid, s.Gid)
}
if d.Mode != s.Mode {
fmt.Printf("%s has mode %s should be %s\n", dest, d.Mode, s.Mode)
}
if d.Md5 != s.Md5 {
fmt.Printf("%s has md5sum %s should be %s\n", dest, d.Md5, s.Md5)
}
if d.Uid != s.Uid || d.Gid != s.Gid || d.Mode != s.Mode || d.Md5 != s.Md5 {
return true, nil
}
return false, nil
}
func IsDirectory(path string) (bool, error) {
f, err := os.Stat(path)
if err != nil {
return false, err
}
switch mode := f.Mode(); {
case mode.IsDir():
return true, nil
case mode.IsRegular():
return false, nil
}
return false, nil
}
func RecursiveFilesLookup(root string, pattern string) ([]string, error) {
return recursiveLookup(root, pattern, false)
}
func RecursiveDirsLookup(root string, pattern string) ([]string, error) {
return recursiveLookup(root, pattern, true)
}
func recursiveLookup(root string, pattern string, dirsLookup bool) ([]string, error) {
var result []string
isDir, err := IsDirectory(root)
if err != nil {
return nil, err
}
if isDir {
err := filepath.Walk(root, func(root string, f os.FileInfo, err error) error {
match, err := filepath.Match(pattern, f.Name())
if err != nil {
return err
}
if match {
isDir, err := IsDirectory(root)
if err != nil {
return err
}
if isDir && dirsLookup {
result = append(result, root)
} else if !isDir && !dirsLookup {
result = append(result, root)
}
}
return nil
})
if err != nil {
return nil, err
}
} else {
if !dirsLookup {
result = append(result, root)
}
}
return result, nil
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。