//! Functions for parsing and managing permissions mod bit; mod parser; mod who; use std::fmt::{self, Write}; pub use { bit::Bit, parser::{ParseError, Parser}, who::Who, }; /// Gets the umask for the current user #[must_use] pub fn get_umask() -> u32 { let mask = unsafe { libc::umask(0) }; let _mask = unsafe { libc::umask(mask) }; mask } /// Functions for extracting information about Unix modes pub trait Mode { /// Returns a string representing permissions in symbolic format /// including file type fn mode_string_full(&self) -> Result; /// Returns a string representing permissions in symbolic format /// minus file type fn mode_string(&self) -> Result; } impl Mode for u32 { fn mode_string_full(&self) -> Result { let b = if self & 0o40000 != 0 && self & 0o20000 != 0 { 'b' } else if self & 0o40000 != 0 { 'd' } else if self & 0o20000 != 0 { 'c' } else { '-' }; let mut s = String::new(); write!(s, "{b}")?; [ Bit::URead, Bit::UWrite, Bit::UExec, Bit::GRead, Bit::GWrite, Bit::GExec, Bit::ORead, Bit::OWrite, Bit::OExec, ] .iter() .try_for_each(|b| write!(s, "{}", b.as_char(*self)))?; Ok(s) } fn mode_string(&self) -> Result { let mut s = String::new(); [ Bit::URead, Bit::UWrite, Bit::UExec, Bit::GRead, Bit::GWrite, Bit::GExec, Bit::ORead, Bit::OWrite, Bit::OExec, ] .iter() .try_for_each(|b| write!(s, "{}", b.as_char(*self)))?; Ok(s) } } #[cfg(test)] mod test { use super::*; #[test] fn getumask() { let mask = unsafe { libc::umask(0o22) }; assert_eq!(get_umask(), 0o022); unsafe { libc::umask(mask); } } #[test] fn display_bits_dir() { let m: u32 = 0o40755; let s = m.mode_string_full().unwrap(); assert_eq!(s.as_str(), "drwxr-xr-x") } #[test] fn display_bits_char() { let m: u32 = 0o20666; let s = m.mode_string_full().unwrap(); assert_eq!(s.as_str(), "crw-rw-rw-") } #[test] fn display_bits_block() { let m: u32 = 0o60660; let s = m.mode_string_full().unwrap(); assert_eq!(s.as_str(), "brw-rw----") } #[test] fn display_bits_file() { let m: u32 = 0o100644; let s = m.mode_string_full().unwrap(); assert_eq!(s.as_str(), "-rw-r--r--") } #[test] fn display_bits_suid() { let m: u32 = 0o104755; let s = m.mode_string_full().unwrap(); assert_eq!(s.as_str(), "-rwsr-xr-x") } #[test] fn display_bits_sgid() { let m: u32 = 0o102755; let s = m.mode_string_full().unwrap(); assert_eq!(s.as_str(), "-rwxr-sr-x") } #[test] fn display_bits_sticky() { let m: u32 = 0o41777; let s = m.mode_string_full().unwrap(); assert_eq!(s.as_str(), "drwxrwxrwt") } }