mode: move Parser into separate module
This commit is contained in:
parent
b52787280b
commit
962a9c53b6
312
src/mode/mod.rs
312
src/mode/mod.rs
@ -1,6 +1,6 @@
|
|||||||
//! Functions for parsing and managing permissions
|
//! Functions for parsing and managing permissions
|
||||||
|
mod parser;
|
||||||
use std::{error, fmt::Display, num::ParseIntError};
|
pub use parser::{Parser, ParseError};
|
||||||
|
|
||||||
pub fn get_umask() -> u32 {
|
pub fn get_umask() -> u32 {
|
||||||
let mask = unsafe { libc::umask(0) };
|
let mask = unsafe { libc::umask(0) };
|
||||||
@ -23,311 +23,3 @@ pub enum Bit {
|
|||||||
OWrite = 0o2,
|
OWrite = 0o2,
|
||||||
OExec = 0o1,
|
OExec = 0o1,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
|
||||||
pub enum ParseError {
|
|
||||||
InvalidBit,
|
|
||||||
InvalidDigit,
|
|
||||||
OutsideRange,
|
|
||||||
ParseIntError(ParseIntError),
|
|
||||||
NoOpSet,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Display for ParseError {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
write!(f, "{self:?}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl error::Error for ParseError {}
|
|
||||||
|
|
||||||
impl From<ParseIntError> for ParseError {
|
|
||||||
fn from(value: ParseIntError) -> Self {
|
|
||||||
Self::ParseIntError(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
|
||||||
enum Op {
|
|
||||||
Add,
|
|
||||||
Remove,
|
|
||||||
Equals,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
|
||||||
enum Who {
|
|
||||||
User,
|
|
||||||
Group,
|
|
||||||
Other,
|
|
||||||
All,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Parser {
|
|
||||||
mode: u32,
|
|
||||||
op: Option<Op>,
|
|
||||||
who: Vec<Who>,
|
|
||||||
bits: Vec<char>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for Parser {
|
|
||||||
fn default() -> Self {
|
|
||||||
let umask = get_umask();
|
|
||||||
let mut mode = 0o0777;
|
|
||||||
mode &= umask;
|
|
||||||
Self {
|
|
||||||
mode,
|
|
||||||
op: None,
|
|
||||||
who: vec![],
|
|
||||||
bits: vec![],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Parser {
|
|
||||||
pub fn new(mode: u32) -> Self {
|
|
||||||
Self {
|
|
||||||
mode,
|
|
||||||
op: None,
|
|
||||||
who: vec![],
|
|
||||||
bits: vec![],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_octal(&mut self, value: &str) -> Result<u32, ParseError> {
|
|
||||||
let m = u32::from_str_radix(value, 8)?;
|
|
||||||
if m <= 0o7777 {
|
|
||||||
Ok(m)
|
|
||||||
} else {
|
|
||||||
Err(ParseError::OutsideRange)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn add_who(&mut self, who: Who) -> Result<(), ParseError> {
|
|
||||||
if self.op.is_some() || self.who.contains(&who) || !self.bits.is_empty() {
|
|
||||||
Err(ParseError::InvalidDigit)
|
|
||||||
} else {
|
|
||||||
self.who.push(who);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_op(&mut self, op: Op) -> Result<(), ParseError> {
|
|
||||||
if self.op.is_some() || !self.bits.is_empty() {
|
|
||||||
Err(ParseError::InvalidDigit)
|
|
||||||
} else {
|
|
||||||
self.op = Some(op);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn push_bit(&mut self, bit: char) -> Result<(), ParseError> {
|
|
||||||
match self.op {
|
|
||||||
Some(_) => if self.bits.contains(&bit) {
|
|
||||||
return Err(ParseError::InvalidDigit);
|
|
||||||
} else {
|
|
||||||
self.bits.push(bit);
|
|
||||||
},
|
|
||||||
None => return Err(ParseError::NoOpSet),
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn push_suid(&mut self) -> Result<(), ParseError> {
|
|
||||||
for w in &self.who {
|
|
||||||
if w == &Who::All || w == &Who::Other {
|
|
||||||
return Err(ParseError::InvalidBit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if self.who.is_empty() {
|
|
||||||
return Err(ParseError::InvalidBit);
|
|
||||||
}
|
|
||||||
self.push_bit('s')
|
|
||||||
}
|
|
||||||
|
|
||||||
fn push_sticky(&mut self) -> Result<(), ParseError> {
|
|
||||||
for w in &self.who {
|
|
||||||
if w == &Who::All || w == &Who::User || w == &Who::Group {
|
|
||||||
return Err(ParseError::InvalidBit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if self.who.is_empty() {
|
|
||||||
return Err(ParseError::InvalidBit);
|
|
||||||
}
|
|
||||||
self.push_bit('t')
|
|
||||||
}
|
|
||||||
|
|
||||||
fn add_user_bits(&mut self) {
|
|
||||||
for b in &self.bits {
|
|
||||||
match b {
|
|
||||||
'r' => self.mode |= Bit::URead as u32,
|
|
||||||
'w' => self.mode |= Bit::UWrite as u32,
|
|
||||||
'x' => self.mode |= Bit::UExec as u32,
|
|
||||||
's' => self.mode |= Bit::Suid as u32,
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remove_user_bits(&mut self) {
|
|
||||||
for b in &self.bits {
|
|
||||||
match b {
|
|
||||||
'r' => self.mode &= Bit::URead as u32,
|
|
||||||
'w' => self.mode &= Bit::UWrite as u32,
|
|
||||||
'x' => self.mode &= Bit::UExec as u32,
|
|
||||||
's' => self.mode &= Bit::Suid as u32,
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn zero_user_bits(&mut self) {
|
|
||||||
self.mode &= 0o4444;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_user_bits(&mut self) {
|
|
||||||
match self.op {
|
|
||||||
Some(Op::Add) => self.add_user_bits(),
|
|
||||||
Some(Op::Remove) => self.remove_user_bits(),
|
|
||||||
Some(Op::Equals) => {
|
|
||||||
self.zero_user_bits();
|
|
||||||
self.add_user_bits();
|
|
||||||
},
|
|
||||||
None => {},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn add_group_bits(&mut self) {
|
|
||||||
for b in &self.bits {
|
|
||||||
match b {
|
|
||||||
'r' => self.mode |= Bit::GRead as u32,
|
|
||||||
'w' => self.mode |= Bit::GWrite as u32,
|
|
||||||
'x' => self.mode |= Bit::GExec as u32,
|
|
||||||
's' => self.mode |= Bit::Sgid as u32,
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remove_group_bits(&mut self) {
|
|
||||||
for b in &self.bits {
|
|
||||||
match b {
|
|
||||||
'r' => self.mode &= Bit::GRead as u32,
|
|
||||||
'w' => self.mode &= Bit::GWrite as u32,
|
|
||||||
'x' => self.mode &= Bit::GExec as u32,
|
|
||||||
's' => self.mode &= Bit::Sgid as u32,
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn zero_group_bits(&mut self) {
|
|
||||||
self.mode &= 0o2222;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_group_bits(&mut self) {
|
|
||||||
match self.op {
|
|
||||||
Some(Op::Add) => self.add_group_bits(),
|
|
||||||
Some(Op::Remove) => self.remove_group_bits(),
|
|
||||||
Some(Op::Equals) => {
|
|
||||||
self.zero_group_bits();
|
|
||||||
self.add_group_bits();
|
|
||||||
},
|
|
||||||
None => {},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn add_other_bits(&mut self) {
|
|
||||||
for b in &self.bits {
|
|
||||||
match b {
|
|
||||||
'r' => self.mode |= Bit::ORead as u32,
|
|
||||||
'w' => self.mode |= Bit::OWrite as u32,
|
|
||||||
'x' => self.mode |= Bit::OExec as u32,
|
|
||||||
't' => self.mode |= Bit::Sticky as u32,
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remove_other_bits(&mut self) {
|
|
||||||
for b in &self.bits {
|
|
||||||
match b {
|
|
||||||
'r' => self.mode &= Bit::ORead as u32,
|
|
||||||
'w' => self.mode &= Bit::OWrite as u32,
|
|
||||||
'x' => self.mode &= Bit::OExec as u32,
|
|
||||||
's' => self.mode &= Bit::Sticky as u32,
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn zero_other_bits(&mut self) {
|
|
||||||
self.mode &= 0o1111;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_other_bits(&mut self) {
|
|
||||||
match self.op {
|
|
||||||
Some(Op::Add) => self.add_other_bits(),
|
|
||||||
Some(Op::Remove) => self.remove_other_bits(),
|
|
||||||
Some(Op::Equals) => {
|
|
||||||
self.zero_other_bits();
|
|
||||||
self.add_other_bits();
|
|
||||||
},
|
|
||||||
None => {},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_bits(&mut self) {
|
|
||||||
for w in self.who.clone() {
|
|
||||||
match w {
|
|
||||||
Who::User => self.set_user_bits(),
|
|
||||||
Who::Group => self.set_group_bits(),
|
|
||||||
Who::Other => self.set_other_bits(),
|
|
||||||
Who::All => {
|
|
||||||
self.set_user_bits();
|
|
||||||
self.set_group_bits();
|
|
||||||
self.set_other_bits();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn reset(&mut self) {
|
|
||||||
self.who.clear();
|
|
||||||
self.op = None;
|
|
||||||
self.bits.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn mode(&self) -> u32 {
|
|
||||||
self.mode
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn parse(&mut self, value: &str) -> Result<u32, ParseError> {
|
|
||||||
match self.parse_octal(value) {
|
|
||||||
Ok(mode) => {
|
|
||||||
self.mode = mode;
|
|
||||||
return Ok(mode)
|
|
||||||
},
|
|
||||||
Err(e) => if e == ParseError::OutsideRange {
|
|
||||||
return Err(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for c in value.chars() {
|
|
||||||
match c {
|
|
||||||
'u' => self.add_who(Who::User)?,
|
|
||||||
'g' => self.add_who(Who::Group)?,
|
|
||||||
'o' => self.add_who(Who::Other)?,
|
|
||||||
'a' => self.add_who(Who::All)?,
|
|
||||||
'-' => self.set_op(Op::Remove)?,
|
|
||||||
'+' => self.set_op(Op::Add)?,
|
|
||||||
'=' => self.set_op(Op::Equals)?,
|
|
||||||
'r' | 'w' | 'x' => self.push_bit(c)?,
|
|
||||||
's' => self.push_suid()?,
|
|
||||||
't' => self.push_sticky()?,
|
|
||||||
_ => return Err(ParseError::InvalidDigit),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.set_bits();
|
|
||||||
self.reset();
|
|
||||||
Ok(self.mode)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
310
src/mode/parser.rs
Normal file
310
src/mode/parser.rs
Normal file
@ -0,0 +1,310 @@
|
|||||||
|
use std::{error, fmt::Display, num::ParseIntError};
|
||||||
|
use super::{Bit, get_umask};
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
|
pub enum ParseError {
|
||||||
|
InvalidBit,
|
||||||
|
InvalidDigit,
|
||||||
|
OutsideRange,
|
||||||
|
ParseIntError(ParseIntError),
|
||||||
|
NoOpSet,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for ParseError {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(f, "{self:?}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl error::Error for ParseError {}
|
||||||
|
|
||||||
|
impl From<ParseIntError> for ParseError {
|
||||||
|
fn from(value: ParseIntError) -> Self {
|
||||||
|
Self::ParseIntError(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
|
enum Op {
|
||||||
|
Add,
|
||||||
|
Remove,
|
||||||
|
Equals,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
enum Who {
|
||||||
|
User,
|
||||||
|
Group,
|
||||||
|
Other,
|
||||||
|
All,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Parser {
|
||||||
|
mode: u32,
|
||||||
|
op: Option<Op>,
|
||||||
|
who: Vec<Who>,
|
||||||
|
bits: Vec<char>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Parser {
|
||||||
|
fn default() -> Self {
|
||||||
|
let umask = get_umask();
|
||||||
|
let mut mode = 0o0777;
|
||||||
|
mode &= umask;
|
||||||
|
Self {
|
||||||
|
mode,
|
||||||
|
op: None,
|
||||||
|
who: vec![],
|
||||||
|
bits: vec![],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Parser {
|
||||||
|
pub fn new(mode: u32) -> Self {
|
||||||
|
Self {
|
||||||
|
mode,
|
||||||
|
op: None,
|
||||||
|
who: vec![],
|
||||||
|
bits: vec![],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_octal(&mut self, value: &str) -> Result<u32, ParseError> {
|
||||||
|
let m = u32::from_str_radix(value, 8)?;
|
||||||
|
if m <= 0o7777 {
|
||||||
|
Ok(m)
|
||||||
|
} else {
|
||||||
|
Err(ParseError::OutsideRange)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_who(&mut self, who: Who) -> Result<(), ParseError> {
|
||||||
|
if self.op.is_some() || self.who.contains(&who) || !self.bits.is_empty() {
|
||||||
|
Err(ParseError::InvalidDigit)
|
||||||
|
} else {
|
||||||
|
self.who.push(who);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_op(&mut self, op: Op) -> Result<(), ParseError> {
|
||||||
|
if self.op.is_some() || !self.bits.is_empty() {
|
||||||
|
Err(ParseError::InvalidDigit)
|
||||||
|
} else {
|
||||||
|
self.op = Some(op);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn push_bit(&mut self, bit: char) -> Result<(), ParseError> {
|
||||||
|
match self.op {
|
||||||
|
Some(_) => if self.bits.contains(&bit) {
|
||||||
|
return Err(ParseError::InvalidDigit);
|
||||||
|
} else {
|
||||||
|
self.bits.push(bit);
|
||||||
|
},
|
||||||
|
None => return Err(ParseError::NoOpSet),
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn push_suid(&mut self) -> Result<(), ParseError> {
|
||||||
|
for w in &self.who {
|
||||||
|
if w == &Who::All || w == &Who::Other {
|
||||||
|
return Err(ParseError::InvalidBit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if self.who.is_empty() {
|
||||||
|
return Err(ParseError::InvalidBit);
|
||||||
|
}
|
||||||
|
self.push_bit('s')
|
||||||
|
}
|
||||||
|
|
||||||
|
fn push_sticky(&mut self) -> Result<(), ParseError> {
|
||||||
|
for w in &self.who {
|
||||||
|
if w == &Who::All || w == &Who::User || w == &Who::Group {
|
||||||
|
return Err(ParseError::InvalidBit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if self.who.is_empty() {
|
||||||
|
return Err(ParseError::InvalidBit);
|
||||||
|
}
|
||||||
|
self.push_bit('t')
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_user_bits(&mut self) {
|
||||||
|
for b in &self.bits {
|
||||||
|
match b {
|
||||||
|
'r' => self.mode |= Bit::URead as u32,
|
||||||
|
'w' => self.mode |= Bit::UWrite as u32,
|
||||||
|
'x' => self.mode |= Bit::UExec as u32,
|
||||||
|
's' => self.mode |= Bit::Suid as u32,
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_user_bits(&mut self) {
|
||||||
|
for b in &self.bits {
|
||||||
|
match b {
|
||||||
|
'r' => self.mode &= Bit::URead as u32,
|
||||||
|
'w' => self.mode &= Bit::UWrite as u32,
|
||||||
|
'x' => self.mode &= Bit::UExec as u32,
|
||||||
|
's' => self.mode &= Bit::Suid as u32,
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn zero_user_bits(&mut self) {
|
||||||
|
self.mode &= 0o4444;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_user_bits(&mut self) {
|
||||||
|
match self.op {
|
||||||
|
Some(Op::Add) => self.add_user_bits(),
|
||||||
|
Some(Op::Remove) => self.remove_user_bits(),
|
||||||
|
Some(Op::Equals) => {
|
||||||
|
self.zero_user_bits();
|
||||||
|
self.add_user_bits();
|
||||||
|
},
|
||||||
|
None => {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_group_bits(&mut self) {
|
||||||
|
for b in &self.bits {
|
||||||
|
match b {
|
||||||
|
'r' => self.mode |= Bit::GRead as u32,
|
||||||
|
'w' => self.mode |= Bit::GWrite as u32,
|
||||||
|
'x' => self.mode |= Bit::GExec as u32,
|
||||||
|
's' => self.mode |= Bit::Sgid as u32,
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_group_bits(&mut self) {
|
||||||
|
for b in &self.bits {
|
||||||
|
match b {
|
||||||
|
'r' => self.mode &= Bit::GRead as u32,
|
||||||
|
'w' => self.mode &= Bit::GWrite as u32,
|
||||||
|
'x' => self.mode &= Bit::GExec as u32,
|
||||||
|
's' => self.mode &= Bit::Sgid as u32,
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn zero_group_bits(&mut self) {
|
||||||
|
self.mode &= 0o2222;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_group_bits(&mut self) {
|
||||||
|
match self.op {
|
||||||
|
Some(Op::Add) => self.add_group_bits(),
|
||||||
|
Some(Op::Remove) => self.remove_group_bits(),
|
||||||
|
Some(Op::Equals) => {
|
||||||
|
self.zero_group_bits();
|
||||||
|
self.add_group_bits();
|
||||||
|
},
|
||||||
|
None => {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_other_bits(&mut self) {
|
||||||
|
for b in &self.bits {
|
||||||
|
match b {
|
||||||
|
'r' => self.mode |= Bit::ORead as u32,
|
||||||
|
'w' => self.mode |= Bit::OWrite as u32,
|
||||||
|
'x' => self.mode |= Bit::OExec as u32,
|
||||||
|
't' => self.mode |= Bit::Sticky as u32,
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_other_bits(&mut self) {
|
||||||
|
for b in &self.bits {
|
||||||
|
match b {
|
||||||
|
'r' => self.mode &= Bit::ORead as u32,
|
||||||
|
'w' => self.mode &= Bit::OWrite as u32,
|
||||||
|
'x' => self.mode &= Bit::OExec as u32,
|
||||||
|
's' => self.mode &= Bit::Sticky as u32,
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn zero_other_bits(&mut self) {
|
||||||
|
self.mode &= 0o1111;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_other_bits(&mut self) {
|
||||||
|
match self.op {
|
||||||
|
Some(Op::Add) => self.add_other_bits(),
|
||||||
|
Some(Op::Remove) => self.remove_other_bits(),
|
||||||
|
Some(Op::Equals) => {
|
||||||
|
self.zero_other_bits();
|
||||||
|
self.add_other_bits();
|
||||||
|
},
|
||||||
|
None => {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_bits(&mut self) {
|
||||||
|
for w in self.who.clone() {
|
||||||
|
match w {
|
||||||
|
Who::User => self.set_user_bits(),
|
||||||
|
Who::Group => self.set_group_bits(),
|
||||||
|
Who::Other => self.set_other_bits(),
|
||||||
|
Who::All => {
|
||||||
|
self.set_user_bits();
|
||||||
|
self.set_group_bits();
|
||||||
|
self.set_other_bits();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reset(&mut self) {
|
||||||
|
self.who.clear();
|
||||||
|
self.op = None;
|
||||||
|
self.bits.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mode(&self) -> u32 {
|
||||||
|
self.mode
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse(&mut self, value: &str) -> Result<u32, ParseError> {
|
||||||
|
match self.parse_octal(value) {
|
||||||
|
Ok(mode) => {
|
||||||
|
self.mode = mode;
|
||||||
|
return Ok(mode)
|
||||||
|
},
|
||||||
|
Err(e) => if e == ParseError::OutsideRange {
|
||||||
|
return Err(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for c in value.chars() {
|
||||||
|
match c {
|
||||||
|
'u' => self.add_who(Who::User)?,
|
||||||
|
'g' => self.add_who(Who::Group)?,
|
||||||
|
'o' => self.add_who(Who::Other)?,
|
||||||
|
'a' => self.add_who(Who::All)?,
|
||||||
|
'-' => self.set_op(Op::Remove)?,
|
||||||
|
'+' => self.set_op(Op::Add)?,
|
||||||
|
'=' => self.set_op(Op::Equals)?,
|
||||||
|
'r' | 'w' | 'x' => self.push_bit(c)?,
|
||||||
|
's' => self.push_suid()?,
|
||||||
|
't' => self.push_sticky()?,
|
||||||
|
_ => return Err(ParseError::InvalidDigit),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.set_bits();
|
||||||
|
self.reset();
|
||||||
|
Ok(self.mode)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user