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
|
//! Functions for parsing and managing permissions
|
||||||
mod parser;
|
mod parser;
|
||||||
use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign};
|
use std::{
|
||||||
|
fmt::{self, Write},
|
||||||
|
ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign},
|
||||||
|
};
|
||||||
|
|
||||||
pub use parser::{ParseError, Parser};
|
pub use parser::{ParseError, Parser};
|
||||||
|
|
||||||
|
/// Gets the umask for the current user
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn get_umask() -> u32 {
|
pub fn get_umask() -> u32 {
|
||||||
let mask = unsafe { libc::umask(0) };
|
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)]
|
#[derive(Clone, Copy, PartialEq)]
|
||||||
pub enum Bit {
|
pub enum Bit {
|
||||||
Suid = 0o4000,
|
Suid = 0o4000,
|
||||||
@ -26,6 +32,61 @@ pub enum Bit {
|
|||||||
OExec = 0o1,
|
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 {
|
impl BitAnd<u32> for Bit {
|
||||||
type Output = u32;
|
type Output = u32;
|
||||||
|
|
||||||
@ -69,3 +130,66 @@ impl BitOrAssign<Bit> for u32 {
|
|||||||
*self = *self | rhs;
|
*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},
|
ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Errors which might occur when parsing Unix permissions from a string
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub enum ParseError {
|
pub enum ParseError {
|
||||||
/// the given `Bit` cannot be set for the given `Who`
|
/// the given `Bit` cannot be set for the given `Who`
|
||||||
|
Loading…
Reference in New Issue
Block a user