| // +build !plan9 |
| |
| package sftp |
| |
| import ( |
| "os" |
| "syscall" |
| ) |
| |
| const EBADF = syscall.EBADF |
| |
| func wrapPathError(filepath string, err error) error { |
| if errno, ok := err.(syscall.Errno); ok { |
| return &os.PathError{Path: filepath, Err: errno} |
| } |
| return err |
| } |
| |
| // translateErrno translates a syscall error number to a SFTP error code. |
| func translateErrno(errno syscall.Errno) uint32 { |
| switch errno { |
| case 0: |
| return sshFxOk |
| case syscall.ENOENT: |
| return sshFxNoSuchFile |
| case syscall.EPERM: |
| return sshFxPermissionDenied |
| } |
| |
| return sshFxFailure |
| } |
| |
| func translateSyscallError(err error) (uint32, bool) { |
| switch e := err.(type) { |
| case syscall.Errno: |
| return translateErrno(e), true |
| case *os.PathError: |
| debug("statusFromError,pathError: error is %T %#v", e.Err, e.Err) |
| if errno, ok := e.Err.(syscall.Errno); ok { |
| return translateErrno(errno), true |
| } |
| } |
| return 0, false |
| } |
| |
| // toFileMode converts sftp filemode bits to the os.FileMode specification |
| func toFileMode(mode uint32) os.FileMode { |
| var fm = os.FileMode(mode & 0777) |
| switch mode & S_IFMT { |
| case syscall.S_IFBLK: |
| fm |= os.ModeDevice |
| case syscall.S_IFCHR: |
| fm |= os.ModeDevice | os.ModeCharDevice |
| case syscall.S_IFDIR: |
| fm |= os.ModeDir |
| case syscall.S_IFIFO: |
| fm |= os.ModeNamedPipe |
| case syscall.S_IFLNK: |
| fm |= os.ModeSymlink |
| case syscall.S_IFREG: |
| // nothing to do |
| case syscall.S_IFSOCK: |
| fm |= os.ModeSocket |
| } |
| if mode&syscall.S_ISGID != 0 { |
| fm |= os.ModeSetgid |
| } |
| if mode&syscall.S_ISUID != 0 { |
| fm |= os.ModeSetuid |
| } |
| if mode&syscall.S_ISVTX != 0 { |
| fm |= os.ModeSticky |
| } |
| return fm |
| } |
| |
| // fromFileMode converts from the os.FileMode specification to sftp filemode bits |
| func fromFileMode(mode os.FileMode) uint32 { |
| ret := uint32(0) |
| |
| if mode&os.ModeDevice != 0 { |
| if mode&os.ModeCharDevice != 0 { |
| ret |= syscall.S_IFCHR |
| } else { |
| ret |= syscall.S_IFBLK |
| } |
| } |
| if mode&os.ModeDir != 0 { |
| ret |= syscall.S_IFDIR |
| } |
| if mode&os.ModeSymlink != 0 { |
| ret |= syscall.S_IFLNK |
| } |
| if mode&os.ModeNamedPipe != 0 { |
| ret |= syscall.S_IFIFO |
| } |
| if mode&os.ModeSetgid != 0 { |
| ret |= syscall.S_ISGID |
| } |
| if mode&os.ModeSetuid != 0 { |
| ret |= syscall.S_ISUID |
| } |
| if mode&os.ModeSticky != 0 { |
| ret |= syscall.S_ISVTX |
| } |
| if mode&os.ModeSocket != 0 { |
| ret |= syscall.S_IFSOCK |
| } |
| |
| if mode&os.ModeType == 0 { |
| ret |= syscall.S_IFREG |
| } |
| ret |= uint32(mode & os.ModePerm) |
| |
| return ret |
| } |