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
|
// This file is part of the adequate Debian-native package, and is available
// under the Expat license. For the full terms please see debian/copyright.
package main
import (
"errors"
"log"
"os"
"path/filepath"
)
// pathExists returns true if p exists.
//
// It does not assert that p is a file and returns true on permission error.
func pathExists(p string) bool {
_, err := os.Stat(p)
return err == nil || !errors.Is(err, os.ErrNotExist)
}
func sameFile(a, b string) bool {
if a == b {
return true
}
afi := fileInfo(a)
bfi := fileInfo(b)
return os.SameFile(afi, bfi)
}
// realPath returns where p points to if a symlink, or p as-is otherwise.
func realPath(p string) string {
pInfo, err := os.Stat(p)
if err != nil {
log.Fatalf("Failed to stat %q: %v\n", p, err)
}
dst := p
if isSymlink(pInfo) {
dst, err = os.Readlink(p)
if err != nil {
log.Fatalf("Failed to read %q: %v\n", p, err)
}
}
var dstAbs string
if filepath.IsAbs(dst) {
dstAbs = dst
} else {
// Symlink targets are relative to the directory containing the link.
dstAbs = filepath.Join(filepath.Dir(p), dst)
}
return dstAbs
}
// fileInfo returns p's FileInfo, or p's target if it's a symlink.
func fileInfo(p string) os.FileInfo {
dstAbs := realPath(p)
dstInfo, err := os.Stat(dstAbs)
if err != nil {
log.Fatalf("Failed to stat %q: %v\n", dstAbs, err)
}
return dstInfo
}
// isPathSymlink returns true if path is a symlink or it cannot be statted.
func isPathSymlink(p string) bool {
fi, err := os.Stat(p)
return err != nil || isSymlink(fi)
}
func isSymlink(fi os.FileInfo) bool {
return fi.Mode()&os.ModeSymlink != 0
}
// isExecutable returns false if path cannot be stat'ed.
func isExecutable(p string) (bool, error) {
fi, err := os.Stat(p)
return (fi != nil && fi.Mode().Perm()&0111 != 0), err
}
func isDir(p string) (bool, error) {
fi, err := os.Stat(p)
return fi != nil && fi.Mode().IsDir(), err
}
|