Skip to content

Instantly share code, notes, and snippets.

@mrenouf
Created April 22, 2024 14:18
Show Gist options
  • Save mrenouf/aee88b5593d49c3dbeee10d828545a68 to your computer and use it in GitHub Desktop.
Save mrenouf/aee88b5593d49c3dbeee10d828545a68 to your computer and use it in GitHub Desktop.
Parse and format posix raw file modes (including file type and special (suid/setgid/sticky) bits)
private const val FILE_TYPES = "?pc?d?b?-?l?s???"
fun String.toPosixModeInt(): Int {
require(length == 10) { "Should have 10 characters" }
// type
val type = when(get(0)) {
'p' -> 1
'c' -> 2
'd' -> 4
'b' -> 6
'-' -> 8
'l' -> 10
's' -> 12
else -> 0
} shl 12
return type + substring(1).chunked(3).reversed().mapIndexed(::parseModeChars).sum()
}
fun parseModeChars(position: Int, mode: String): Int {
var value = when (mode[0]) {
'r' -> 4 shl position * 3
else -> 0
}
value += when (mode[1]) {
'w' -> 2 shl position * 3
else -> 0
}
return value + when (mode[2]) {
'x' -> 1 shl position * 3
'S' -> 1 shl (9 + position)
's' -> (1 shl 9 + position) + (1 shl position * 3)
'T' -> require(position == 0) {"Sticky bit in invalid position ($position)"}.let { 1 shl 9 }
't' -> require(position == 0) {"Sticky bit in invalid position ($position)"}.let { (1 shl 9) + 1 }
else -> 0
}
}
fun Int.toPosixModeString(): String {
val type = this shr 12 and 15
val special = this shr 9 and 7
return StringBuilder(10).also {
// file type
it.append(FILE_TYPES[type])
// user
it.appendModeChars(this shr 6 and 7, special and 4 != 0, 's')
it.appendModeChars(this shr 3 and 7, special and 2 != 0, 's')
it.appendModeChars(this shr 0 and 7, special and 1 != 0, 't')
}.toString()
}
private fun StringBuilder.appendModeChars(bits: Int, special: Boolean, specialX: Char) {
append(if (bits and 4 != 0) 'r' else '-')
append(if (bits and 2 != 0) 'w' else '-')
append(if (bits and 1 != 0) {
if (special) specialX else 'x'
} else {
if (special) specialX.uppercaseChar() else '-'
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment