I have tried:
for file in walkFiles("*"):
echo(file.getFilePermissions, file)
but what I get looks like the following:
{fpUserWrite, fpUserRead, fpGroupWrite, fpGroupRead, fpOthersRead}testfile1
Does anyone know a way to get the standard Unix/Linux permissions string using Nim?Just check that set for each permission and add the corresponding character, it should map 1-1.
proc posixRepr(file: string): string =
let info = getFileInfo(file, followSymlink = false)
result.add([pcFile: '-', 'l', pcDir: 'd', 'l'][info.kind])
for i, fp in [fpUserRead, fpUserWrite, fpUserExec, fpGroupRead, fpGroupWrite,
fpGroupExec, fpOthersRead, fpOthersWrite, fpOthersExec]:
result.add(if fp in info.permissions: "rwx"[i mod 3] else: '-')
It may also depend on how "standard" the desired string is whether @jasper's solution is enough for @cnuzzi. Usually, the setuid, setgid, sticky bits have some 's' or 't' substitutions for the 'x', and capitialized [ST] if one of those bits is set but the corresponding execute permission is missing. I think Unix standardization efforts were disintegrating by the time they were getting around to this level of the userspace utilities.
So, @jasper may need to use something like this (from https://github.com/c-blake/lc/blob/master/lc.nim search for proc fmtPerm):
import posix
proc fmtPerm*(m: Mode, s=""): string =
## Call with ``.st_mode`` of some ``Stat`` to get rwxr-x..; ``s`` is optional
## separator string such as a space or a comma to enhance readabilty.
let m = m.uint and 4095
const rwx = ["---", "--x", "-w-", "-wx", "r--", "r-x", "rw-", "rwx" ]
result = rwx[(m shr 6) and 7] & s & rwx[(m shr 3) and 7] & s & rwx[m and 7]
let o = s.len
if (m and 0o4000) != 0 and (m and 0o100) != 0: result[2] = 's' #setuid,+x
if (m and 0o4000) != 0 and (m and 0o100) == 0: result[2] = 'S' #setuid,noX
if (m and 0o2000) != 0 and (m and 0o010) != 0: result[5+o] = 's' #setgid,+x
if (m and 0o2000) != 0 and (m and 0o010) == 0: result[5+o] = 'S' #setgid,noX
if (m and 0o1000) != 0 and (m and 0o001) != 0: result[8+o] = 't' #sticky,+x
if (m and 0o1000) != 0 and (m and 0o001) == 0: result[8+o] = 'T' #sticky,noX
I didn't see any direct code to do this formatting in posix, but you surely would import posix to get Mode. That code just uses the raw low 12 bits, but those are actually pretty standard.go does the translation too, https://golang.org/src/os/types.go?s=2790:2823#L55
65 func (m FileMode) String() string {
66 const str = "dalTLDpSugct?"
67 var buf [32]byte // Mode is uint32.
68 w := 0
69 for i, c := range str {
70 if m&(1<<uint(32-1-i)) != 0 {
71 buf[w] = byte(c)
72 w++
73 }
74 }
75 if w == 0 {
76 buf[w] = '-'
77 w++
78 }
79 const rwx = "rwxrwxrwx"
80 for i, c := range rwx {
81 if m&(1<<uint(9-1-i)) != 0 {
82 buf[w] = byte(c)
83 } else {
84 buf[w] = '-'
85 }
86 w++
87 }
88 return string(buf[:w])
89 }