github.com/pkg/sftp@v1.13.6/stat_posix.go (about) 1 //go:build !plan9 2 // +build !plan9 3 4 package sftp 5 6 import ( 7 "os" 8 "syscall" 9 ) 10 11 const EBADF = syscall.EBADF 12 13 func wrapPathError(filepath string, err error) error { 14 if errno, ok := err.(syscall.Errno); ok { 15 return &os.PathError{Path: filepath, Err: errno} 16 } 17 return err 18 } 19 20 // translateErrno translates a syscall error number to a SFTP error code. 21 func translateErrno(errno syscall.Errno) uint32 { 22 switch errno { 23 case 0: 24 return sshFxOk 25 case syscall.ENOENT: 26 return sshFxNoSuchFile 27 case syscall.EACCES, syscall.EPERM: 28 return sshFxPermissionDenied 29 } 30 31 return sshFxFailure 32 } 33 34 func translateSyscallError(err error) (uint32, bool) { 35 switch e := err.(type) { 36 case syscall.Errno: 37 return translateErrno(e), true 38 case *os.PathError: 39 debug("statusFromError,pathError: error is %T %#v", e.Err, e.Err) 40 if errno, ok := e.Err.(syscall.Errno); ok { 41 return translateErrno(errno), true 42 } 43 } 44 return 0, false 45 } 46 47 // isRegular returns true if the mode describes a regular file. 48 func isRegular(mode uint32) bool { 49 return mode&S_IFMT == syscall.S_IFREG 50 } 51 52 // toFileMode converts sftp filemode bits to the os.FileMode specification 53 func toFileMode(mode uint32) os.FileMode { 54 var fm = os.FileMode(mode & 0777) 55 56 switch mode & S_IFMT { 57 case syscall.S_IFBLK: 58 fm |= os.ModeDevice 59 case syscall.S_IFCHR: 60 fm |= os.ModeDevice | os.ModeCharDevice 61 case syscall.S_IFDIR: 62 fm |= os.ModeDir 63 case syscall.S_IFIFO: 64 fm |= os.ModeNamedPipe 65 case syscall.S_IFLNK: 66 fm |= os.ModeSymlink 67 case syscall.S_IFREG: 68 // nothing to do 69 case syscall.S_IFSOCK: 70 fm |= os.ModeSocket 71 } 72 73 if mode&syscall.S_ISUID != 0 { 74 fm |= os.ModeSetuid 75 } 76 if mode&syscall.S_ISGID != 0 { 77 fm |= os.ModeSetgid 78 } 79 if mode&syscall.S_ISVTX != 0 { 80 fm |= os.ModeSticky 81 } 82 83 return fm 84 } 85 86 // fromFileMode converts from the os.FileMode specification to sftp filemode bits 87 func fromFileMode(mode os.FileMode) uint32 { 88 ret := uint32(mode & os.ModePerm) 89 90 switch mode & os.ModeType { 91 case os.ModeDevice | os.ModeCharDevice: 92 ret |= syscall.S_IFCHR 93 case os.ModeDevice: 94 ret |= syscall.S_IFBLK 95 case os.ModeDir: 96 ret |= syscall.S_IFDIR 97 case os.ModeNamedPipe: 98 ret |= syscall.S_IFIFO 99 case os.ModeSymlink: 100 ret |= syscall.S_IFLNK 101 case 0: 102 ret |= syscall.S_IFREG 103 case os.ModeSocket: 104 ret |= syscall.S_IFSOCK 105 } 106 107 if mode&os.ModeSetuid != 0 { 108 ret |= syscall.S_ISUID 109 } 110 if mode&os.ModeSetgid != 0 { 111 ret |= syscall.S_ISGID 112 } 113 if mode&os.ModeSticky != 0 { 114 ret |= syscall.S_ISVTX 115 } 116 117 return ret 118 } 119 120 const ( 121 s_ISUID = syscall.S_ISUID 122 s_ISGID = syscall.S_ISGID 123 s_ISVTX = syscall.S_ISVTX 124 )