|
| 1 | +/* |
| 2 | +Constants/functions for interpreting results of os.Stat() and os.Lstat(). |
| 3 | +
|
| 4 | +Suggested usage: import github.com/goimp/stat |
| 5 | +*/ |
| 6 | +package stat |
| 7 | + |
| 8 | +// Indices for stat struct members in the tuple returned by os.Stat() |
| 9 | +const ( |
| 10 | + ST_MODE = 0 |
| 11 | + ST_INO = 1 |
| 12 | + ST_DEV = 2 |
| 13 | + ST_NLINK = 3 |
| 14 | + ST_UID = 4 |
| 15 | + ST_GID = 5 |
| 16 | + ST_SIZE = 6 |
| 17 | + ST_ATIME = 7 |
| 18 | + ST_MTIME = 8 |
| 19 | + ST_CTIME = 9 |
| 20 | +) |
| 21 | + |
| 22 | +// Extract bits from the mode |
| 23 | + |
| 24 | +// Return the portion of the file's mode that can be set by os.chmod(). |
| 25 | +func S_IMODE(mode uint32) uint32 { |
| 26 | + return mode & 0o7777 |
| 27 | +} |
| 28 | + |
| 29 | +// Return the portion of the file's mode that describes the file type. |
| 30 | +func S_IFMT(mode uint32) uint32 { |
| 31 | + return mode & 0o170000 |
| 32 | +} |
| 33 | + |
| 34 | +// Constants used as S_IFMT() for various file types |
| 35 | +// (not all are implemented on all systems) |
| 36 | +const ( |
| 37 | + S_IFDIR = 0o040000 // directory |
| 38 | + S_IFCHR = 0o020000 // character device |
| 39 | + S_IFBLK = 0o060000 // block device |
| 40 | + S_IFREG = 0o100000 // regular file |
| 41 | + S_IFIFO = 0o010000 // fifo (named pipe) |
| 42 | + S_IFLNK = 0o120000 // symbolic link |
| 43 | + S_IFSOCK = 0o140000 // socket file |
| 44 | + // Fallbacks for uncommon platform-specific constants |
| 45 | + S_IFDOOR = 0 |
| 46 | + S_IFPORT = 0 |
| 47 | + S_IFWHT = 0 |
| 48 | +) |
| 49 | + |
| 50 | +// Functions to test for each file type |
| 51 | + |
| 52 | +// Return True if mode is from a directory. |
| 53 | +func S_ISDIR(mode uint32) bool { |
| 54 | + return S_IFMT(mode) == S_IFDIR |
| 55 | +} |
| 56 | + |
| 57 | +// Return True if mode is from a character special device file. |
| 58 | +func S_ISCHR(mode uint32) bool { |
| 59 | + return S_IFMT(mode) == S_IFCHR |
| 60 | +} |
| 61 | + |
| 62 | +// Return True if mode is from a block special device file. |
| 63 | +func S_ISBLK(mode uint32) bool { |
| 64 | + return S_IFMT(mode) == S_IFBLK |
| 65 | +} |
| 66 | + |
| 67 | +// Return True if mode is from a regular file. |
| 68 | +func S_ISREG(mode uint32) bool { |
| 69 | + return S_IFMT(mode) == S_IFREG |
| 70 | +} |
| 71 | + |
| 72 | +// Return True if mode is from a FIFO (named pipe). |
| 73 | +func S_ISFIFO(mode uint32) bool { |
| 74 | + return S_IFMT(mode) == S_IFIFO |
| 75 | +} |
| 76 | + |
| 77 | +// Return True if mode is from a symbolic link. |
| 78 | +func S_ISLNK(mode uint32) bool { |
| 79 | + return S_IFMT(mode) == S_IFLNK |
| 80 | +} |
| 81 | + |
| 82 | +// Return True if mode is from a socket. |
| 83 | +func S_ISSOCK(mode uint32) bool { |
| 84 | + return S_IFMT(mode) == S_IFSOCK |
| 85 | +} |
| 86 | + |
| 87 | +// Return True if mode is from a door. |
| 88 | +func S_ISDOOR(mode uint32) bool { |
| 89 | + return false |
| 90 | +} |
| 91 | + |
| 92 | +// Return True if mode is from an event port. |
| 93 | +func S_ISPORT(mode uint32) bool { |
| 94 | + return false |
| 95 | +} |
| 96 | + |
| 97 | +// Return True if mode is from a whiteout. |
| 98 | +func S_ISWHT(mode uint32) bool { |
| 99 | + return false |
| 100 | +} |
| 101 | + |
| 102 | +// Names for permission bits |
| 103 | +const ( |
| 104 | + S_ISUID = 0o4000 // set UID bit |
| 105 | + S_ISGID = 0o2000 // set GID bit |
| 106 | + S_ENFMT = S_ISGID // file locking enforcement |
| 107 | + S_ISVTX = 0o1000 // sticky bit |
| 108 | + S_IREAD = 0o0400 // Unix V7 synonym for S_IRUSR |
| 109 | + S_IWRITE = 0o0200 // Unix V7 synonym for S_IWUSR |
| 110 | + S_IEXEC = 0o0100 // Unix V7 synonym for S_IXUSR |
| 111 | + S_IRWXU = 0o0700 // mask for owner permissions |
| 112 | + S_IRUSR = 0o0400 // read by owner |
| 113 | + S_IWUSR = 0o0200 // write by owner |
| 114 | + S_IXUSR = 0o0100 // execute by owner |
| 115 | + S_IRWXG = 0o0070 // mask for group permissions |
| 116 | + S_IRGRP = 0o0040 // read by group |
| 117 | + S_IWGRP = 0o0020 // write by group |
| 118 | + S_IXGRP = 0o0010 // execute by group |
| 119 | + S_IRWXO = 0o0007 // mask for others (not in group) permissions |
| 120 | + S_IROTH = 0o0004 // read by others |
| 121 | + S_IWOTH = 0o0002 // write by others |
| 122 | + S_IXOTH = 0o0001 // execute by others |
| 123 | +) |
| 124 | + |
| 125 | +// Names for file flags |
| 126 | +const ( |
| 127 | + UF_SETTABLE = 0x0000ffff // owner settable flags |
| 128 | + UF_NODUMP = 0x00000001 // do not dump file |
| 129 | + UF_IMMUTABLE = 0x00000002 // file may not be changed |
| 130 | + UF_APPEND = 0x00000004 // file may only be appended to |
| 131 | + UF_OPAQUE = 0x00000008 // directory is opaque when viewed through a union stack |
| 132 | + UF_NOUNLINK = 0x00000010 // file may not be renamed or deleted |
| 133 | + UF_COMPRESSED = 0x00000020 // macOS: file is compressed |
| 134 | + UF_TRACKED = 0x00000040 // macOS: used for handling document IDs |
| 135 | + UF_DATAVAULT = 0x00000080 // macOS: entitlement needed for I/O |
| 136 | + UF_HIDDEN = 0x00008000 // macOS: file should not be displayed |
| 137 | + SF_SETTABLE = 0xffff0000 // superuser settable flags |
| 138 | + SF_ARCHIVED = 0x00010000 // file may be archived |
| 139 | + SF_IMMUTABLE = 0x00020000 // file may not be changed |
| 140 | + SF_APPEND = 0x00040000 // file may only be appended to |
| 141 | + SF_RESTRICTED = 0x00080000 // macOS: entitlement needed for writing |
| 142 | + SF_NOUNLINK = 0x00100000 // file may not be renamed or deleted |
| 143 | + SF_SNAPSHOT = 0x00200000 // file is a snapshot file |
| 144 | + SF_FIRMLINK = 0x00800000 // macOS: file is a firmlink |
| 145 | + SF_DATALESS = 0x40000000 // macOS: file is a dataless object |
| 146 | +) |
| 147 | + |
| 148 | +// File type chars according to: |
| 149 | +// http://en.wikibooks.org/wiki/C_Programming/POSIX_Reference/sys/stat.h |
| 150 | +var fileModeTable = [][]struct { |
| 151 | + Mask uint32 |
| 152 | + Symbol string |
| 153 | +}{ |
| 154 | + { |
| 155 | + {S_IFLNK, "l"}, |
| 156 | + {S_IFSOCK, "s"}, |
| 157 | + {S_IFREG, "-"}, |
| 158 | + {S_IFBLK, "b"}, |
| 159 | + {S_IFDIR, "d"}, |
| 160 | + {S_IFCHR, "c"}, |
| 161 | + {S_IFIFO, "p"}, |
| 162 | + }, |
| 163 | + {{S_IRUSR, "r"}}, |
| 164 | + {{S_IWUSR, "w"}}, |
| 165 | + { |
| 166 | + {S_IXUSR | S_ISUID, "s"}, |
| 167 | + {S_ISUID, "S"}, |
| 168 | + {S_IXUSR, "x"}, |
| 169 | + }, |
| 170 | + {{S_IRGRP, "r"}}, |
| 171 | + {{S_IWGRP, "w"}}, |
| 172 | + { |
| 173 | + {S_IXGRP | S_ISGID, "s"}, |
| 174 | + {S_ISGID, "S"}, |
| 175 | + {S_IXGRP, "x"}, |
| 176 | + }, |
| 177 | + {{S_IROTH, "r"}}, |
| 178 | + {{S_IWOTH, "w"}}, |
| 179 | + { |
| 180 | + {S_IXOTH | S_ISVTX, "t"}, |
| 181 | + {S_ISVTX, "T"}, |
| 182 | + {S_IXOTH, "x"}, |
| 183 | + }, |
| 184 | +} |
| 185 | + |
| 186 | +// Convert a file's mode to a string of the form '-rwxrwxrwx'. |
| 187 | +func FileMode(mode uint32) string { |
| 188 | + var perm []rune |
| 189 | + |
| 190 | + for index, table := range fileModeTable { |
| 191 | + found := false |
| 192 | + for _, entry := range table { |
| 193 | + if mode&entry.Mask == entry.Mask { |
| 194 | + perm = append(perm, rune(entry.Symbol[0])) |
| 195 | + found = true |
| 196 | + break |
| 197 | + } |
| 198 | + } |
| 199 | + if !found { |
| 200 | + if index == 0 { |
| 201 | + // Unknown file type |
| 202 | + perm = append(perm, '?') |
| 203 | + } else { |
| 204 | + perm = append(perm, '-') |
| 205 | + } |
| 206 | + } |
| 207 | + } |
| 208 | + |
| 209 | + return string(perm) |
| 210 | +} |
| 211 | + |
| 212 | +// Windows FILE_ATTRIBUTE constants for interpreting os.Stat()'s |
| 213 | +// "st_file_attributes" member |
| 214 | + |
| 215 | +const ( |
| 216 | + FILE_ATTRIBUTE_ARCHIVE = 32 |
| 217 | + FILE_ATTRIBUTE_COMPRESSED = 2048 |
| 218 | + FILE_ATTRIBUTE_DEVICE = 64 |
| 219 | + FILE_ATTRIBUTE_DIRECTORY = 16 |
| 220 | + FILE_ATTRIBUTE_ENCRYPTED = 16384 |
| 221 | + FILE_ATTRIBUTE_HIDDEN = 2 |
| 222 | + FILE_ATTRIBUTE_INTEGRITY_STREAM = 32768 |
| 223 | + FILE_ATTRIBUTE_NORMAL = 128 |
| 224 | + FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 8192 |
| 225 | + FILE_ATTRIBUTE_NO_SCRUB_DATA = 131072 |
| 226 | + FILE_ATTRIBUTE_OFFLINE = 4096 |
| 227 | + FILE_ATTRIBUTE_READONLY = 1 |
| 228 | + FILE_ATTRIBUTE_REPARSE_POINT = 1024 |
| 229 | + FILE_ATTRIBUTE_SPARSE_FILE = 512 |
| 230 | + FILE_ATTRIBUTE_SYSTEM = 4 |
| 231 | + FILE_ATTRIBUTE_TEMPORARY = 256 |
| 232 | + FILE_ATTRIBUTE_VIRTUAL = 65536 |
| 233 | +) |
0 commit comments