1package filexfer 2 3// FileMode represents a file’s mode and permission bits. 4// The bits are defined according to POSIX standards, 5// and may not apply to the OS being built for. 6type FileMode uint32 7 8// Permission flags, defined here to avoid potential inconsistencies in individual OS implementations. 9const ( 10 ModePerm FileMode = 0o0777 // S_IRWXU | S_IRWXG | S_IRWXO 11 ModeUserRead FileMode = 0o0400 // S_IRUSR 12 ModeUserWrite FileMode = 0o0200 // S_IWUSR 13 ModeUserExec FileMode = 0o0100 // S_IXUSR 14 ModeGroupRead FileMode = 0o0040 // S_IRGRP 15 ModeGroupWrite FileMode = 0o0020 // S_IWGRP 16 ModeGroupExec FileMode = 0o0010 // S_IXGRP 17 ModeOtherRead FileMode = 0o0004 // S_IROTH 18 ModeOtherWrite FileMode = 0o0002 // S_IWOTH 19 ModeOtherExec FileMode = 0o0001 // S_IXOTH 20 21 ModeSetUID FileMode = 0o4000 // S_ISUID 22 ModeSetGID FileMode = 0o2000 // S_ISGID 23 ModeSticky FileMode = 0o1000 // S_ISVTX 24 25 ModeType FileMode = 0xF000 // S_IFMT 26 ModeNamedPipe FileMode = 0x1000 // S_IFIFO 27 ModeCharDevice FileMode = 0x2000 // S_IFCHR 28 ModeDir FileMode = 0x4000 // S_IFDIR 29 ModeDevice FileMode = 0x6000 // S_IFBLK 30 ModeRegular FileMode = 0x8000 // S_IFREG 31 ModeSymlink FileMode = 0xA000 // S_IFLNK 32 ModeSocket FileMode = 0xC000 // S_IFSOCK 33) 34 35// IsDir reports whether m describes a directory. 36// That is, it tests for m.Type() == ModeDir. 37func (m FileMode) IsDir() bool { 38 return (m & ModeType) == ModeDir 39} 40 41// IsRegular reports whether m describes a regular file. 42// That is, it tests for m.Type() == ModeRegular 43func (m FileMode) IsRegular() bool { 44 return (m & ModeType) == ModeRegular 45} 46 47// Perm returns the POSIX permission bits in m (m & ModePerm). 48func (m FileMode) Perm() FileMode { 49 return (m & ModePerm) 50} 51 52// Type returns the type bits in m (m & ModeType). 53func (m FileMode) Type() FileMode { 54 return (m & ModeType) 55} 56 57// String returns a `-rwxrwxrwx` style string representing the `ls -l` POSIX permissions string. 58func (m FileMode) String() string { 59 var buf [10]byte 60 61 switch m.Type() { 62 case ModeRegular: 63 buf[0] = '-' 64 case ModeDir: 65 buf[0] = 'd' 66 case ModeSymlink: 67 buf[0] = 'l' 68 case ModeDevice: 69 buf[0] = 'b' 70 case ModeCharDevice: 71 buf[0] = 'c' 72 case ModeNamedPipe: 73 buf[0] = 'p' 74 case ModeSocket: 75 buf[0] = 's' 76 default: 77 buf[0] = '?' 78 } 79 80 const rwx = "rwxrwxrwx" 81 for i, c := range rwx { 82 if m&(1<<uint(9-1-i)) != 0 { 83 buf[i+1] = byte(c) 84 } else { 85 buf[i+1] = '-' 86 } 87 } 88 89 if m&ModeSetUID != 0 { 90 if buf[3] == 'x' { 91 buf[3] = 's' 92 } else { 93 buf[3] = 'S' 94 } 95 } 96 97 if m&ModeSetGID != 0 { 98 if buf[6] == 'x' { 99 buf[6] = 's' 100 } else { 101 buf[6] = 'S' 102 } 103 } 104 105 if m&ModeSticky != 0 { 106 if buf[9] == 'x' { 107 buf[9] = 't' 108 } else { 109 buf[9] = 'T' 110 } 111 } 112 113 return string(buf[:]) 114} 115