New trait Mode
, currently just prints the symbolic representation of a
Unix mode, as extracted from u32
This commit is contained in:
parent
97d4fe1947
commit
1ff61def39
128
src/mode/mod.rs
128
src/mode/mod.rs
@ -1,15 +1,21 @@
|
||||
//! Functions for parsing and managing permissions
|
||||
mod parser;
|
||||
use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign};
|
||||
use std::{
|
||||
fmt::{self, Write},
|
||||
ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign},
|
||||
};
|
||||
|
||||
pub use parser::{ParseError, Parser};
|
||||
|
||||
/// Gets the umask for the current user
|
||||
#[must_use]
|
||||
pub fn get_umask() -> u32 {
|
||||
let mask = unsafe { libc::umask(0) };
|
||||
unsafe { libc::umask(mask) }
|
||||
let _mask = unsafe { libc::umask(mask) };
|
||||
mask
|
||||
}
|
||||
|
||||
/// Unix permission bit flags
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub enum Bit {
|
||||
Suid = 0o4000,
|
||||
@ -26,6 +32,61 @@ pub enum Bit {
|
||||
OExec = 0o1,
|
||||
}
|
||||
|
||||
impl Bit {
|
||||
fn as_char(&self, mode: u32) -> char {
|
||||
if mode & *self != 0 {
|
||||
match self {
|
||||
Self::Suid | Self::Sgid => 's',
|
||||
Self::Sticky => 't',
|
||||
Self::URead | Self::GRead | Self::ORead => 'r',
|
||||
Self::UWrite | Self::GWrite | Self::OWrite => 'w',
|
||||
Self::UExec if mode & Self::Suid != 0 => 's',
|
||||
Self::GExec if mode & Self::Sgid != 0 => 's',
|
||||
Self::OExec if mode & Self::Sticky != 0 => 't',
|
||||
Self::UExec | Self::GExec | Self::OExec => 'x',
|
||||
}
|
||||
} else {
|
||||
'-'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Functions for extracting information about Unix modes
|
||||
pub trait Mode {
|
||||
/// Returns a string representing permissions in symbolic format
|
||||
fn mode_string(&self) -> Result<String, fmt::Error>;
|
||||
}
|
||||
|
||||
impl Mode for u32 {
|
||||
fn mode_string(&self) -> Result<String, fmt::Error> {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
impl BitAnd<u32> for Bit {
|
||||
type Output = u32;
|
||||
|
||||
@ -69,3 +130,66 @@ impl BitOrAssign<Bit> for u32 {
|
||||
*self = *self | rhs;
|
||||
}
|
||||
}
|
||||
|
||||
#[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().unwrap();
|
||||
assert_eq!(s.as_str(), "drwxr-xr-x")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn display_bits_char() {
|
||||
let m: u32 = 0o20666;
|
||||
let s = m.mode_string().unwrap();
|
||||
assert_eq!(s.as_str(), "crw-rw-rw-")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn display_bits_block() {
|
||||
let m: u32 = 0o60660;
|
||||
let s = m.mode_string().unwrap();
|
||||
assert_eq!(s.as_str(), "brw-rw----")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn display_bits_file() {
|
||||
let m: u32 = 0o100644;
|
||||
let s = m.mode_string().unwrap();
|
||||
assert_eq!(s.as_str(), "-rw-r--r--")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn display_bits_suid() {
|
||||
let m: u32 = 0o104755;
|
||||
let s = m.mode_string().unwrap();
|
||||
assert_eq!(s.as_str(), "-rwsr-xr-x")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn display_bits_sgid() {
|
||||
let m: u32 = 0o102755;
|
||||
let s = m.mode_string().unwrap();
|
||||
assert_eq!(s.as_str(), "-rwxr-sr-x")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn display_bits_sticky() {
|
||||
let m: u32 = 0o41777;
|
||||
let s = m.mode_string().unwrap();
|
||||
assert_eq!(s.as_str(), "drwxrwxrwt")
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ use std::{
|
||||
ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign},
|
||||
};
|
||||
|
||||
/// Errors which might occur when parsing Unix permissions from a string
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum ParseError {
|
||||
/// the given `Bit` cannot be set for the given `Who`
|
||||
|
Loading…
Reference in New Issue
Block a user